From bf73a988e277b43e35e9ad8d3207233f2895e6f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Sun, 12 Nov 2006 15:51:08 +0000 Subject: [PATCH] --- Makefile.am | 1 + src/builtin/builtin.c | 105 +++++++++++++++ src/builtin/builtin.h | 44 ++++++ src/builtin/builtin_cd.c | 113 ++++++++++++++++ src/builtin/builtin_doubledot.c | 33 +++++ src/builtin/builtin_echo.c | 230 ++++++++++++++++++++++++++++++++ src/builtin/builtin_exec.c | 38 ++++++ src/builtin/builtin_exit.c | 54 ++++++++ src/builtin/builtin_export.c | 20 +++ src/builtin/builtin_funclist.c | 27 ++++ src/builtin/builtin_history.c | 38 ++++++ src/builtin/builtin_set.c | 20 +++ src/builtin/builtin_shopt.c | 160 ++++++++++++++++++++++ src/builtin/builtin_simpledot.c | 33 +++++ src/builtin/builtin_source.c | 57 ++++++++ src/builtin/builtin_unset.c | 42 ++++++ src/builtin/builtin_varlist.c | 23 ++++ src/exec/exec.h | 3 +- src/exec/exec_node.c | 7 +- src/exec/exec_red.c | 16 +++ src/shell/shell_entry.c | 5 +- 21 files changed, 1062 insertions(+), 7 deletions(-) create mode 100644 src/builtin/builtin.c create mode 100644 src/builtin/builtin.h create mode 100644 src/builtin/builtin_cd.c create mode 100644 src/builtin/builtin_doubledot.c create mode 100644 src/builtin/builtin_echo.c create mode 100644 src/builtin/builtin_exec.c create mode 100644 src/builtin/builtin_exit.c create mode 100644 src/builtin/builtin_export.c create mode 100644 src/builtin/builtin_funclist.c create mode 100644 src/builtin/builtin_history.c create mode 100644 src/builtin/builtin_set.c create mode 100644 src/builtin/builtin_shopt.c create mode 100644 src/builtin/builtin_simpledot.c create mode 100644 src/builtin/builtin_source.c create mode 100644 src/builtin/builtin_unset.c create mode 100644 src/builtin/builtin_varlist.c create mode 100644 src/exec/exec_red.c diff --git a/Makefile.am b/Makefile.am index 91e0332..7e9bd8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -32,6 +32,7 @@ bin_PROGRAMS=42sh src/exec/exec_node.c \ src/exec/exec_or.c \ src/exec/exec_if.c \ + src/exec/exec_red.c \ src/exec/exec_sep.c \ src/exec/exec_sepand.c \ src/exec/exec_while.c \ diff --git a/src/builtin/builtin.c b/src/builtin/builtin.c new file mode 100644 index 0000000..22f80be --- /dev/null +++ b/src/builtin/builtin.c @@ -0,0 +1,105 @@ +/* +** builtin.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Tue Apr 11 00:22:44 2006 Seblu +** Last update Sun Nov 12 16:47:59 2006 Seblu +*/ + +#include +#include +#include +#include "builtin.h" +#include "../main/42sh.h" +#include "../ast/ast.h" +#include "../opt/opt.h" + +#define BUILTIN_NUMBER 7 +#define BUILTIN_BONUS_NUMBER 7 + +static const char *builtin_name[BUILTIN_NUMBER] = + { + "cd", + "echo", + "exit", + "shopt", + "source", + "unset", + "export" + }; + +static const char *builtin_bonus_name[BUILTIN_BONUS_NUMBER] = + { + ".", + "..", + "set", + "varlist", + "funclist", + "exec", + "history" + }; + +static const t_func_builtin builtin_function[BUILTIN_NUMBER] = + { + builtin_cd, + builtin_echo, + builtin_exit, + builtin_shopt, + builtin_source, + builtin_unset, + builtin_export + }; + +static const t_func_builtin builtin_bonus_function[BUILTIN_BONUS_NUMBER] = + { + builtin_simpledot, + builtin_doubledot, + builtin_set, + builtin_varlist, + builtin_funclist, + builtin_exec, + builtin_history + }; + +/*! +** test if a command is a builtin +** +** @param name The name of the command +** @return 1 if \a name is a builtin, else 0 +*/ +int is_a_builtin(const char *name, struct s_42sh *sh) +{ + register int i; + + for (i = 0; i < BUILTIN_NUMBER; ++i) + if (!strcmp(name, builtin_name[i])) + return 1; + if (opt_isset("bonus", sh->opt)) + for (i = 0; i < BUILTIN_BONUS_NUMBER; ++i) + if (!strcmp(name, builtin_bonus_name[i])) + return 1; + return 0; +} + +/*! +** execute a shell builtin +** +** @param builtin_name The name of the builtin +** @param argv The builtin arguments, terminate by NULL, argv[0] = builtin_name +** @return The return value of the builtin +*/ +int exec_builtin(struct s_cmd *cmd, struct s_42sh *sh) +{ + register int i; + + for (i = 0; i < BUILTIN_NUMBER; ++i) + if (!strcmp(cmd->argv[0], builtin_name[i])) + return builtin_function[i](cmd->argv, sh); + if (opt_isset("bonus", sh->opt)) + for (i = 0; i < BUILTIN_BONUS_NUMBER; ++i) + if (!strcmp(cmd->argv[0], builtin_bonus_name[i])) + return builtin_bonus_function[i](cmd->argv, sh); + return 0; +} diff --git a/src/builtin/builtin.h b/src/builtin/builtin.h new file mode 100644 index 0000000..8c032f4 --- /dev/null +++ b/src/builtin/builtin.h @@ -0,0 +1,44 @@ +/* +** builtin.h for 42sh in /home/seblu/svn/42sh +** +** Made by Seblu +** Login +** +** Started on Sun Nov 12 16:46:24 2006 Seblu +** Last update Sun Nov 12 16:47:03 2006 Seblu +*/ + +#ifndef BUILTIN_H_ +# define BUILTIN_H_ + +struct s_42sh; +struct s_cmd; + +typedef int (*t_func_builtin)(char *argv[], struct s_42sh *sh); + +int is_a_builtin(const char *name, struct s_42sh *sh); +int exec_builtin(struct s_cmd *cmd, struct s_42sh *sh); + +/* +** Regular builtin +*/ +int builtin_cd(char *argv[], struct s_42sh *sh); +int builtin_echo(char *argv[], struct s_42sh *sh); +int builtin_shopt(char *argv[], struct s_42sh *sh); +int builtin_exit(char *argv[], struct s_42sh *sh); +int builtin_source(char *argv[], struct s_42sh *sh); +int builtin_unset(char *argv[], struct s_42sh *sh); +int builtin_export(char *argv[], struct s_42sh *sh); + +/* +** Bonus builtin +*/ +int builtin_simpledot(char *argv[], struct s_42sh *sh); +int builtin_doubledot(char *argv[], struct s_42sh *sh); +int builtin_set(char *argv[], struct s_42sh *sh); +int builtin_varlist(char *argv[], struct s_42sh *sh); +int builtin_funclist(char *argv[], struct s_42sh *sh); +int builtin_exec(char *argv[], struct s_42sh *sh); +int builtin_history(char *argv[], struct s_42sh *sh); + +#endif /* ! BUILTIN_H_ */ diff --git a/src/builtin/builtin_cd.c b/src/builtin/builtin_cd.c new file mode 100644 index 0000000..0ade5f6 --- /dev/null +++ b/src/builtin/builtin_cd.c @@ -0,0 +1,113 @@ +/* +** builtin_cd.c for 42sh in /home/seblu/devel/c/42sh/src/execution +** +** Made by Seblu +** Login +** +** Started on Tue Apr 11 00:23:47 2006 Seblu +** Last update Sun May 21 19:17:53 2006 Seblu +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "../main/42sh.h" +#include "builtin.h" +#include "../var/var.h" + +#include "mem.h" + +static int cd_var(struct s_42sh *sh, const char *name); +static int cd_minus(struct s_42sh *sh); +static int secure_chdir(const char *path); + +/*! +** Builtin cd. +** @param argv The tab of args: terminated by NULL, argv[0] = "cd" +** @param sh The 42sh structure +*/ +int builtin_cd(char **argv, struct s_42sh *sh) +{ + assert(sh && argv && argv[0]); + + if (!argv[1]) + return cd_var(sh, "HOME"); + if (!strcmp("-", argv[1])) + return cd_minus(sh); + return secure_chdir(argv[1]); +} + +/*! +** Change directory to home directory +** +** @param sh shell env +** @param name env var +** +** @return exit status +*/ +static int cd_var(struct s_42sh *sh, const char *name) +{ + const char *new_dir; + + if (!(new_dir = var_get(sh->vars, name))) + { + fprintf(stderr, "42sh: cd: %s not set\n", name); + return 1; + } + return secure_chdir(new_dir); +} + +/*! +** Return in previous directory +** +** @param sh shell info +** +** @return return status +*/ +static int cd_minus(struct s_42sh *sh) +{ + if (cd_var(sh, "OLDPWD")) + return 1; + return 0; +} + +/*! +** Change of directory and on error, print good error. +** +** @param path new path +** +** @return error status with error code (0 is good) +*/ +static int secure_chdir(const char *path) +{ + const char *errormsg = ""; + char *tmp; + + errno = 0; + if (chdir(path)) + { + if (errno == ENOENT) + errormsg = "No such file or directory"; + else if (errno == EACCES) + errormsg = "Permission denied"; + else if (errno == ENAMETOOLONG) + errormsg = "File name too long"; + else if (errno == ENOTDIR) + errormsg = "Not a directory"; + else if (errno == ELOOP) + errormsg = "Too many levels of symbolic links"; + else + assert(0); + fprintf(stderr, "42sh: cd %s: %s\n", path, errormsg); + return 1; + } + if ((tmp = getenv("PWD"))) + var_setenv("OLDPWD", tmp, !0); + var_setenv("PWD", (tmp = var_getcwd()), !0); + free(tmp); + return 0; +} diff --git a/src/builtin/builtin_doubledot.c b/src/builtin/builtin_doubledot.c new file mode 100644 index 0000000..b340b8f --- /dev/null +++ b/src/builtin/builtin_doubledot.c @@ -0,0 +1,33 @@ +/* +** builtin_doubledot.c for 42sh in /home/seblu/devel/c/towork/42sh +** +** Made by Seblu +** Login +** +** Started on Sat Apr 8 18:02:31 2006 Seblu +** Last update Sun Apr 9 12:38:38 2006 SIGOURE Benoit +*/ + +#include +#include "builtin.h" + +#include "mem.h" + +/*! +** Builtin double dot, allow you to cdup +** +** @param argv argv vector +** @param sh sh data +** +** @return builtin return success +*/ +int builtin_doubledot(char *argv[], struct s_42sh *sh) +{ + char *argv2[3]; + + argv2[0] = "cd"; + argv2[1] = ".."; + argv2[2] = NULL; + return builtin_cd(argv2, sh); + argv = argv; +} diff --git a/src/builtin/builtin_echo.c b/src/builtin/builtin_echo.c new file mode 100644 index 0000000..e1f705f --- /dev/null +++ b/src/builtin/builtin_echo.c @@ -0,0 +1,230 @@ +/* +** builtin_echo.c for 42sh in /goinfre/seblu/builtins +** +** Made by Seblu +** Login +** +** Started on Tue Mar 14 20:57:07 2006 Seblu +** Last update Wed Apr 12 02:02:07 2006 Seblu +*/ + +#include +#include +#include +#include +#include +#include "../main/42sh.h" +#include "../opt/opt.h" + +#include "mem.h" + +#define isoctale(x) (((x) >= '0' && (x) <= '7') ? 1 : 0) + +static int builtin_echo_ext(const char *); +static void builtin_echo_ext2(const char **, int *); +static void print_hex(const char **); +static void print_oct(const char **); +static void getoption(char *argv[], int *argp, int *line, int *ext); +static int fisdigit(const int c); +static int fisxdigit(const int c); + +/*! +** Echo show all element on her line +** +** @param argc number of argument given +** @param argv vector to argument +** @param shopt option structure of shell +** +** @return sucess status +*/ +int builtin_echo(char *argv[], struct s_42sh *sh) +{ + int argp; + int ext = 0; + int line = 1; + int first; + + assert(argv && argv[0] && sh); + ext = opt_isset("xpg_echo", sh->opt); + for (getoption(argv, &argp, &line, &ext), first = argp; argv[argp]; ++argp) + { + if (first != argp) + printf(" "); + if (ext) + { + if (!builtin_echo_ext(argv[argp])) + return fflush(stdout); + } + else + printf("%s", argv[argp]); + } + if (line) + printf("\n"); + return fflush(stdout); +} + +/*! +** Retreinve command line option +** +** @param argv argument vector +** @param argp argument position +** @param line line flag +** @param ext extended flag +*/ +static void getoption(char *argv[], int *argp, int *line, int *ext) +{ + char *carg; + + for (*argp = 1; (carg = argv[*argp]); ++*argp) + if (*carg == '-') + for (++carg; *carg; ++carg) + if (*carg == 'e') + *ext = 1; + else if (*carg == 'E') + *ext = 0; + else if (*carg == 'n') + *line = 0; + else + return; + else + return; +} + +/*! +** Interpreter for special char +** +** @param msg +*/ +static int builtin_echo_ext(const char *msg) +{ + int backed = 0; + + for (; *msg; ++msg) + if (*msg == '\\' && !backed && (backed = 1)) + continue; + else if (backed && *msg == 'a' && !(backed = 0)) + putchar('\a'); + else if (backed && *msg == 'b' && !(backed = 0)) + putchar('\b'); + else if (backed && *msg == 'c') + return 0; + else if (backed && *msg == 'e' && !(backed = 0)) + putchar(0x1b); + else if (backed && *msg == 'f' && !(backed = 0)) + putchar('\f'); + else if (backed && *msg == 'n' && !(backed = 0)) + putchar('\n'); + else if (backed && *msg == 'r' && !(backed = 0)) + putchar('\r'); + else if (backed && *msg == 't' && !(backed = 0)) + putchar('\t'); + else + builtin_echo_ext2(&msg, &backed); + return 1; +} + +/*! +** End of function builtin_echo_ext due to an stupid norme limitation. +** +** @param msg message to print +** @param backed if a backed char +*/ +static void builtin_echo_ext2(const char **msg, int *backed) +{ + if (*backed && **msg == '\\' && !(*backed = 0)) + putchar('\\'); + else if (*backed && **msg == 'v' && !(*backed = 0)) + putchar('\v'); + else if (*backed && fisdigit(**msg) && !(*backed = 0)) + print_oct(msg); + else if (*backed && **msg == 'x' && !(*backed = 0) && (++*msg)) + print_hex(msg); + else if (*backed && !(backed = 0)) + printf("\\%c", **msg); + else + putchar(**msg); +} + +/*! +** Print hexa number on stdout a number +** +** @param msg message to print +** @param base base of the number +*/ +static void print_hex(const char **msg) +{ + char buf[4]; + char *end; + long n; + unsigned char c; + int i; + + if (!fisxdigit(**msg)) + return; + for (i = 0; fisxdigit(**msg) && i < 2; ++*msg, ++i) + buf[i] = **msg; + buf[i] = 0; + --*msg; + n = strtoul(buf, &end, 16); + printf("%c", (c = n)); +} + +/*! +** Print oct number on stdout a number +** +** @param msg message to print +** @param base base of the number +*/ +static void print_oct(const char **msg) +{ + char buf[5]; + char *end; + unsigned long n; + unsigned char c; + int i; + int max; + + if (!isoctale(**msg)) + return; + max = (**msg == '0') ? 4 : 3; + for (i = 0; isoctale(**msg) && i < max; ++*msg, ++i) + buf[i] = **msg; + buf[i] = 0; + --*msg; + n = strtoul(buf, &end, 8); + printf("%c", (c = n)); +} + +/*! +** Function to say if c is a digit or not. +** It use macro isdigit, but due to epita coding style +** restriction about cast, it's impossible to call +** a macro wrote with int with char, because cast is forbidden +** and macro call, dont have the same right about parameter +** implicit cast (on netBSD) +** +** @param c character +** +** @return if \param c is a digit +*/ +static int fisdigit(const int c) +{ + return isdigit(c); +} + +/*! +** Function to say if c is a digit or not. +** It use macro isdigit, but due to epita coding style +** restriction about cast, it's impossible to call +** a macro wrote with int with char, because cast is forbidden +** and macro call, dont have the same right about parameter +** implicit cast (on netBSD) +** +** @param c character +** +** @return if \param c is a hexa digit +*/ +static int fisxdigit(const int c) +{ + return isxdigit(c); +} diff --git a/src/builtin/builtin_exec.c b/src/builtin/builtin_exec.c new file mode 100644 index 0000000..a2dd6bf --- /dev/null +++ b/src/builtin/builtin_exec.c @@ -0,0 +1,38 @@ +/* +** builtin_exec.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 10:00:36 2006 Seblu +** Last update Sun May 21 18:42:29 2006 Seblu +*/ + +#include +#include +#include +#include "builtin.h" +#include "../main/42sh.h" + +/*! +** Replace current process by which is given in arg +** +** @param argv arg vector +** @param sh shell struct +** +** @return success status +*/ +int builtin_exec(char *argv[], struct s_42sh *sh) +{ + assert(sh && argv); + if (!argv[1]) + return 0; + if (execvp(argv[1], argv + 1) == -1) + { + perror("42sh: exec"); + return 127; + } + return 0; + argv = argv; + sh = sh; +} diff --git a/src/builtin/builtin_exit.c b/src/builtin/builtin_exit.c new file mode 100644 index 0000000..2de403c --- /dev/null +++ b/src/builtin/builtin_exit.c @@ -0,0 +1,54 @@ +/* +** builtin_exit.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Sun Nov 12 16:48:50 2006 Seblu +** Last update Sun Nov 12 16:49:42 2006 Seblu +*/ + +#include +#include +#include +#include +#include "builtin.h" +#include "../main/42sh.h" + +/*! +** Terminate program +** +** @param argv vector to argument +** @param shopt option structure of shell +** +** @return +*/ +int builtin_exit(char *argv[]) +{ + long i; + char *endptr; + + assert(argv && argv[0]); + if (!argv[1]) + { +/* if (isatty(fileno(stdin))) */ +/* printf("exit\n"); */ + i = sh->last_status; + sh_destroy(sh); + exit(i); + } + if (argv[2]) + { + fprintf(stderr, "42sh : exit : too many arguments\n"); + fflush(stderr); + return 1; + } + i = strtol(argv[1], &endptr, 10); +/* if (isatty(fileno(stdin))) */ +/* printf("exit\n"); */ + if (*endptr) + fprintf(stderr, "42sh: exit: %s: numeric argument required\n", argv[1]); + sh_destroy(sh); + exit((!*endptr) ? i : 255); + return 1; +} diff --git a/src/builtin/builtin_export.c b/src/builtin/builtin_export.c new file mode 100644 index 0000000..85f9711 --- /dev/null +++ b/src/builtin/builtin_export.c @@ -0,0 +1,20 @@ +/* +** builtin_export.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 09:32:30 2006 Seblu +** Last update Thu May 11 09:41:01 2006 Seblu +*/ + +#include +#include "builtin.h" + +int builtin_export(char *argv[], struct s_42sh *sh) +{ + printf("export: not yet implemeted\n"); + sh = sh; + argv = argv; + return 1; +} diff --git a/src/builtin/builtin_funclist.c b/src/builtin/builtin_funclist.c new file mode 100644 index 0000000..b2aee84 --- /dev/null +++ b/src/builtin/builtin_funclist.c @@ -0,0 +1,27 @@ +/* +** builtin_funclist.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 10:00:36 2006 Seblu +** Last update Sun May 21 18:40:33 2006 Seblu +*/ + +#include +#include +#include "builtin.h" +#include "../func/function.h" +#include "../main/42sh.h" + +int builtin_funclist(char *argv[], struct s_42sh *sh) +{ + assert(sh); + /* FIXME + func_print(sh->funcs); + */ + printf("Not yet implemented !\n"); + return 0; + argv = argv; + sh = sh; +} diff --git a/src/builtin/builtin_history.c b/src/builtin/builtin_history.c new file mode 100644 index 0000000..1d83632 --- /dev/null +++ b/src/builtin/builtin_history.c @@ -0,0 +1,38 @@ +/* +** builtin_history.c for in /home/joel/42sh +** +** Made by joel +** Login +** +** Started on Wed May 17 12:28:30 2006 joel +** Last update Sun May 21 18:44:31 2006 Seblu +*/ + +#include +#include +#include "../main/42sh.h" +#include "../history/history.h" +#include "builtin.h" + + +/*! +** Builtin history. +** @param argv The tab of args: terminated by NULL, argv[0] = "cd" +** @param sh The 42sh structure +*/ +int builtin_history(char **argv, struct s_42sh *sh) +{ + struct s_my_dlist *list; + char *elem; + int count = 1; + + assert(sh && argv && argv[0]); + if (!sh->history->list) + return 0; + for (list = sh->history->list; list->next != NULL; list = list->next) + ; + for (; list; list = list->prev, ++count) + fprintf(stdout, " %i %s\n", count, elem = list->elem); + return 0; + argv = argv; +} diff --git a/src/builtin/builtin_set.c b/src/builtin/builtin_set.c new file mode 100644 index 0000000..464c503 --- /dev/null +++ b/src/builtin/builtin_set.c @@ -0,0 +1,20 @@ +/* +** builtin_set.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 09:32:30 2006 Seblu +** Last update Thu May 11 09:38:54 2006 Seblu +*/ + +#include +#include "builtin.h" + +int builtin_set(char *argv[], struct s_42sh *sh) +{ + printf("set: not yet implemeted\n"); + sh = sh; + argv = argv; + return 1; +} diff --git a/src/builtin/builtin_shopt.c b/src/builtin/builtin_shopt.c new file mode 100644 index 0000000..9a3998e --- /dev/null +++ b/src/builtin/builtin_shopt.c @@ -0,0 +1,160 @@ +/* +** builtin_shopt.c for 42sh in /goinfre/seblu/42sh/src +** +** Made by Seblu +** Login +** +** Started on Wed Mar 22 16:27:35 2006 Seblu +** Last update Tue Apr 11 00:24:22 2006 Seblu +*/ + +#include +#include +#include +#include "builtin.h" +#include "../main/42sh.h" +#include "../opt/opt.h" + +#include "mem.h" + +static void getoption(char *argv[], int *argp, int opts[2]); +static int mutator_opt(char *argv[], int *argp, int opts[2], struct s_42sh *sh); +static int show_opt(char *argv[], int *argp, int opts[2], struct s_42sh *sh); +static int show_all_opt(int quiet, struct s_42sh *sh); + +/*! +** This builtin change local setting of the shell +** opts[0] == set or unset +** opts[1] == quiet mode +** +** @param argv argument vector +** @param sh shell data +** +** @return success status +*/ +int builtin_shopt(char *argv[], struct s_42sh *sh) +{ + int opts[2]; + int argp = 1; + + assert(argv && argv[0] && sh); + opts[0] = -1; + opts[1] = 0; + getoption(argv, &argp, opts); + if (opts[0] == -1 && !argv[argp]) + return show_all_opt(opts[1], sh); + else if (opts[0] == -1 && argv[argp]) + return show_opt(argv, &argp, opts, sh); + else + return mutator_opt(argv, &argp, opts, sh); +} + +/*! +** Retreinve command line option +** +** @param argv argument vector +** @param argp argument position +** @param line line flag +** @param ext extended flag +*/ +static void getoption(char *argv[], int *argp, int opts[2]) +{ + for (; argv[*argp]; ++*argp) + if (!strcmp("-s", argv[*argp])) + opts[0] = 1; + else if (!strcmp("-u", argv[*argp])) + opts[0] = 0; + else if (!strcmp("-q", argv[*argp])) + opts[1] = 1; + else + break; +} + +/*! +** Sun or unset an option +** +** @param argv arg vector +** @param argp cur pos +** @param opts argline opts +** @param sh struct info +** +** @return builtin status +*/ +static int mutator_opt(char *argv[], + int *argp, + int opts[2], + struct s_42sh *sh) +{ + int ret = 0; + + for (; argv[*argp]; ++*argp) + { + if (opt_isset(argv[*argp], sh->opt) == -1) + { + fprintf(stderr, "42sh: shopt: %s: invalid shell option name\n", + argv[*argp]); + ret = 1; + continue; + } + if (opts[0]) + opt_set(argv[*argp], sh->opt); + else + opt_unset(argv[*argp], sh->opt); + } + return ret; +} + +/*! +** Show info about shell opts +** +** @param argv arg vector +** @param argp cur pos +** @param opts argline opts +** @param sh struct info +** +** @return builtin status +*/ +static int show_opt(char *argv[], + int *argp, + int opts[2], + struct s_42sh *sh) +{ + int ret = 0; + int isset = 0; + + for (; argv[*argp]; ++*argp) + { + if ((isset = opt_isset(argv[*argp], sh->opt)) == -1) + { + fprintf(stderr, "42sh: shopt: %s: invalid shell option name\n", + argv[*argp]); + ret = 1; + continue; + } + if (!opts[1]) + printf("%-15s %s\n", argv[*argp], (isset) ? "yes" : "no"); + else if (!isset) + ret = 1; + } + return ret; +} + +/*! +** Show all options +** +** @param quiet silent showing +** +** @return return status +*/ +static int show_all_opt(int quiet, struct s_42sh *sh) +{ + const char **opts; + register int i; + + if (quiet) + return 0; + opts = opt_get(); + for (i = 0; opts[i]; ++i) + printf("%-15s %s\n", opts[i], (opt_isset(opts[i], sh->opt)) ? "yes" : "no"); + return 0; +} diff --git a/src/builtin/builtin_simpledot.c b/src/builtin/builtin_simpledot.c new file mode 100644 index 0000000..418db44 --- /dev/null +++ b/src/builtin/builtin_simpledot.c @@ -0,0 +1,33 @@ +/* +** builtin_simpledot.c for 42sh in /home/seblu/devel/c/42sh +** +** Made by Seblu +** Login +** +** Started on Tue May 16 19:59:03 2006 Seblu +** Last update Tue May 16 20:10:11 2006 Seblu +*/ + +#include +#include +#include +#include +#include "builtin.h" + +#include "mem.h" + +/*! +** Builtin simple dot, equivalent to source +** +** @param argv argv vector +** @param sh sh data +** +** @return builtin return success +*/ +int builtin_simpledot(char *argv[], struct s_42sh *sh) +{ + assert(argv && sh); + free(argv[0]); + argv[0] = strdup("source"); + return builtin_source(argv, sh); +} diff --git a/src/builtin/builtin_source.c b/src/builtin/builtin_source.c new file mode 100644 index 0000000..6a430c0 --- /dev/null +++ b/src/builtin/builtin_source.c @@ -0,0 +1,57 @@ +/* +** builtin_source.c for 42sh in /goinfre/42sh/src +** +** Made by Seblu +** Login +** +** Started on Sun Apr 9 04:40:11 2006 Seblu +** Last update Sun May 21 18:35:59 2006 Seblu +*/ + +#include +#include +#include "builtin.h" +#include "../main/42sh.h" +#include "../execution/execution.h" + +#include "mem.h" + +static int builtin_source_error(int err); + +int builtin_source(char *argv[], struct s_42sh *sh) +{ + FILE *fd; + int yyparse(); + void scan_switch_buffer(FILE *fd); + int scanerr = 0; + int parseerr = 0; + struct s_42sh tempsh; + + assert(argv && sh); + if (!argv[1]) + return builtin_source_error(2); + else if (!(fd = fopen(argv[1], "r"))) + return builtin_source_error(1); + /* FIXME: call gerlic */ + scan_switch_buffer(fd); + parseerr = yyparse("source: ", &scanerr, &tempsh); + if (scanerr) + return builtin_source_error(SCAN_ERROR); + if (parseerr) + return builtin_source_error(PARSE_ERROR); + fclose(fd); + scan_switch_buffer(NULL); + exec_start(&tempsh); + /* FIXME: ast destruction */ + return tempsh.last_status; + sh = sh; +} + +static int builtin_source_error(int err) +{ + if (err == 1) + perror("42sh: source"); + else if (err == 2) + fprintf(stderr, "42sh: source: filename argument required\n"); + return 1; +} diff --git a/src/builtin/builtin_unset.c b/src/builtin/builtin_unset.c new file mode 100644 index 0000000..b1b3f32 --- /dev/null +++ b/src/builtin/builtin_unset.c @@ -0,0 +1,42 @@ +/* +** builtin_unset.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 09:36:06 2006 Seblu +** Last update Thu May 11 10:19:36 2006 Seblu +*/ + +#include +#include +#include +#include "builtin.h" +#include "../var/var.h" +#include "../func/function.h" +#include "../main/42sh.h" + +int builtin_unset(char *argv[], struct s_42sh *sh) +{ + int f = 0; + int v = 1; + int i; + + assert(argv && sh); + for (i = 0; argv[i]; ++i) + if (!strcmp(argv[i], "-v")) + v = 1; + else if (!strcmp(argv[i], "-v")) + f = 1; + for (i = 0; argv[i]; ++i) + if (argv[i][0] == '-') + continue; + else + { + if (v) + var_unset(sh->vars, argv[i]); + if (f) + func_del(argv[i], &sh->funcs); + } + return 0; +} diff --git a/src/builtin/builtin_varlist.c b/src/builtin/builtin_varlist.c new file mode 100644 index 0000000..8efe9e1 --- /dev/null +++ b/src/builtin/builtin_varlist.c @@ -0,0 +1,23 @@ +/* +** builtin_varlist.c for 42sh in /goinfre/seblu/42sh/src/builtin +** +** Made by Seblu +** Login +** +** Started on Thu May 11 10:00:36 2006 Seblu +** Last update Sun May 21 18:40:43 2006 Seblu +*/ + +#include +#include "builtin.h" +#include "../var/var.h" +#include "../main/42sh.h" + +int builtin_varlist(char *argv[], struct s_42sh *sh) +{ + assert(sh); + var_print(sh->vars); + return 0; + argv = argv; + sh = sh; +} diff --git a/src/exec/exec.h b/src/exec/exec.h index cba632b..0510e36 100644 --- a/src/exec/exec.h +++ b/src/exec/exec.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Mar 30 16:02:07 2006 Seblu -** Last update Sun Nov 12 13:29:49 2006 seblu +** Last update Sun Nov 12 16:41:42 2006 Seblu */ #ifndef EXEC_H_ @@ -21,6 +21,7 @@ void exec_and(s_bin_node *node); void exec_or(s_bin_node *node); void exec_bang(s_bin_node *node); void exec_if(s_if_node *node); +void exec_red(s_red_node *red); void exec_while(s_while_node *node); /* FIXME */ diff --git a/src/exec/exec_node.c b/src/exec/exec_node.c index 65551f1..b125007 100644 --- a/src/exec/exec_node.c +++ b/src/exec/exec_node.c @@ -5,20 +5,19 @@ ** Login ** ** Started on Sat Mar 25 14:51:09 2006 Seblu -** Last update Sun Nov 12 13:36:41 2006 seblu +** Last update Sun Nov 12 16:43:18 2006 Seblu */ #include "exec.h" void exec_node(s_ast_node *node) { - if (node == NULL) - return; + assert(node); switch (node->type) { case T_SEP: break; case T_SEPAND: break; case T_CMD: break; - case T_RED: break; + case T_RED: exec_red(&node->body.child_red); break; case T_PIPE: break; case T_AND: exec_and(&node->body.child_and); break; case T_OR: exec_or(&node->body.child_or); break; diff --git a/src/exec/exec_red.c b/src/exec/exec_red.c new file mode 100644 index 0000000..dc2716b --- /dev/null +++ b/src/exec/exec_red.c @@ -0,0 +1,16 @@ +/* +** exec_red.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Sun Nov 12 16:39:51 2006 Seblu +** Last update Sun Nov 12 16:44:02 2006 Seblu +*/ + +#include "exec.h" + +void exec_red(s_red_node *red) +{ + assert(red); +} diff --git a/src/shell/shell_entry.c b/src/shell/shell_entry.c index 43c66f5..4d44829 100644 --- a/src/shell/shell_entry.c +++ b/src/shell/shell_entry.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Mon Apr 10 23:57:28 2006 Seblu -** Last update Fri Oct 13 14:34:17 2006 seblu +** Last update Sun Nov 12 16:38:29 2006 Seblu */ #include @@ -51,7 +51,8 @@ int main(int argc, char *argv[]) return ERROR_PARSE; if (option_isset(shell->options, "ast_print")) ast_print(ast, NULL); - exec_node(ast); + if (ast) + exec_node(ast); ast_destruct(ast); } while (!parser->lexer->eof); -- GitLab