diff --git a/src/Makefile.am b/src/Makefile.am index 083f33e2cd36de5a5ded495fade0ab0e902941f3..ebfd4868381643d699be83f5978ec8fae676a275 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,14 +10,19 @@ bin_PROGRAMS=42sh common/strmerge.c \ common/strvmerge.c \ lexer/lexer.h \ + opt/opt.h \ + opt/opt.c \ + opt/opt_init.c \ + opt/opt_parser.c \ + parser/parser.h \ + parser/parser.c \ + readline/readline.h \ + readline/readline.c \ + readline/getln.c \ shell/shell.h \ shell/shell_entry.c \ shell/shell_init.c \ shell/shell_destroy.c \ - shell/shell_prompt.c \ - opt/opt.h \ - opt/opt.c \ - opt/opt_init.c \ - opt/opt_parser.c + shell/shell_prompt.c CLEANFILES= *~ '\#*' diff --git a/src/ast/ast.h b/src/ast/ast.h index 397f82fa06593f9f8b1050fffbd381f785d9be13..6ac90f3acb24a4c7ce7327ea7ace2d7893a4b421 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:40:03 2006 Seblu -** Last update Sun Jul 30 05:35:28 2006 Seblu +** Last update Wed Aug 2 17:54:14 2006 Seblu */ #ifndef AST_H_ @@ -16,6 +16,9 @@ # include # include +struct s_ast; +typedef struct s_ast ts_ast_node; + /* ** If ast node */ @@ -87,7 +90,7 @@ typedef struct typedef struct { char **argv; - ts_redir **redirs; + ts_redir_node **redirs; char **prefix; } ts_cmd_node; @@ -114,7 +117,7 @@ typedef struct /* ** Funcdec node */ -struct +typedef struct { char *name; ts_ast_node *body; @@ -161,14 +164,14 @@ typedef union ts_while_node node_while; ts_while_node node_until; ts_cmd_node node_cmd; - ts_op_node node_and; - ts_op_node node_or; + ts_bin_node node_and; + ts_bin_node node_or; ts_subshell_node node_subshell; ts_funcdec_node node_funcdec; - ts_op_node node_bang; - ts_op_node node_pipe; - ts_op_node node_sep_semicomma; - ts_op_node node_sep_and; + ts_bin_node node_bang; + ts_bin_node node_pipe; + ts_bin_node node_sep_semicomma; + ts_bin_node node_sep_and; /* ts_case_item node_case_item; */ @@ -179,176 +182,176 @@ typedef union /* ** Generic ast node type */ -typedef struct +struct s_ast { te_node_type type; tu_node_item node; -} ts_ast_node; - - - - - -/** -** structure wordlist ex : for var in wordlist do -** word : word -** next : next word finally Sexy NULL -*/ -struct s_wordlist -{ - char *word; - struct s_wordlist *next; }; -struct s_case_item -{ - char **patterns; - int allocated; - int pos; -}; -struct s_item -{ - struct s_wordlist *pl; - struct s_ast *cmd_list; -}; -/** -** temporary structure -** which contains prefix and -** suffix command informations -** argv word or assigment words terminated by NULL -** redirs redirection pointer -** pos position in argv array -** nb_arg_alloc positions allocated -*/ -struct s_cmd_opt -{ - char **argv; - struct s_redir *redirs; - int pos; - int nb_arg_alloc; -}; -/** -** create temporary structure -** in order to get prefix and -** suffix informations -*/ -struct s_cmd_opt *tmp_create_cmdopt(struct s_cmd_opt *opt, - struct s_redir *redir, - char *arg); -/** -** add redirection to temporary -** structure s_redir -*/ -struct s_redir *tmp_add_redir(struct s_redir *base, struct s_redir *nelt); -/** -** create temporary structure s_redir -*/ -struct s_redir *tmp_create_redir(enum e_redir type, - char *filename, - int fd, - struct s_redir *redir); -/* -** PLEASE NOTE -** Every time, any argument given so this functions must be on the heap, -** they are not copied. Don't forget to dup string, for function create_cmd, -** function add_redir and function create_for -*/ - -/*! -** Create an and node -** -** @param lhs left hand side -** @param rhs right hand side -** -** @return new ast node -*/ -struct s_ast *ast_create_and(struct s_ast *lhs, struct s_ast *rhs); -/*! -** Create an or node -** -** @param lhs left hand side -** @param rhs right hand side -** -** @return new ast node -*/ -struct s_ast *ast_create_or(struct s_ast *lhs, struct s_ast *rhs); -struct s_ast *ast_create_case_clause(char *word, - struct s_ast *case_list); -struct s_ast *ast_create_if(struct s_ast *cond, - struct s_ast *positive, - struct s_ast *negative); -struct s_ast *ast_create_funcdec(char *name, struct s_ast *body); -struct s_ast *ast_create_subshell(struct s_ast *cmd); -struct s_ast *ast_create_for(char *varname, - struct s_ast *value, - struct s_ast *exec); -/** -** create cmd node -*/ -struct s_ast *ast_create_cmd(struct s_cmd_opt *prefix, - char *cmd, - struct s_cmd_opt *suffix); - -/* struct s_ast *ast_create_list(struct s_ast **item); */ -struct s_ast *ast_create_until(struct s_ast *cond, - struct s_ast *exec); -struct s_ast *ast_create_while(struct s_ast *cond, - struct s_ast *exec); -/** -** create pipe node -*/ -struct s_ast *ast_create_pipe(struct s_ast *cmd1, - struct s_ast *cmd2); -/** -** create shell structure -*/ -struct s_42sh *ast_create_ast(struct s_42sh *shell, - struct s_ast *ast); - -struct s_ast *ast_create_patterns(char *word, struct s_ast *case_item); -struct s_ast *ast_create_case_list(struct s_ast *item, - struct s_ast *case_list); -struct s_ast *ast_create_wordlist(struct s_ast *wl, - char *w); -/** -** change ast type : PIPE -> BANG_PIPE and CMD -> BANG_CMD -*/ -struct s_ast *ast_create_bang(struct s_ast *ast); -struct s_ast *ast_create_sep_op(struct s_ast *cmd1, - enum e_type sep_op, - struct s_ast *cmd2); - -/* void ast_destruct_list(struct s_ast *node); */ -void ast_destruct_cmd(struct s_ast *node); -void ast_destruct_pipe(struct s_ast *node); -void ast_destruct_redir(struct s_redir *red); - -/* void ast_print(struct s_ast *ast); */ -void ast_destruct_sep_op(struct s_ast *node); -void ast_destruct_for(struct s_ast *node); -void ast_destruct_until(struct s_ast *node); -void ast_destruct_while(struct s_ast *node); -void ast_destruct_if(struct s_ast *node); -void ast_destruct(struct s_ast *node); -void ast_destruct_bang(struct s_ast *node); -void ast_destruct_wordlist(struct s_ast *node); -void ast_destruct_case(struct s_ast *node); -/*! -** Destruct an and node -** -** @param node head of node to destruct -*/ -void ast_destruct_and(struct s_ast *node); -/*! -** Destruct an or node -** -** @param node head of node to destruct -*/ -void ast_destruct_or(struct s_ast *node); -void ast_destruct_subshell(struct s_ast *node); +/* /\** */ +/* ** structure wordlist ex : for var in wordlist do */ +/* ** word : word */ +/* ** next : next word finally Sexy NULL */ +/* *\/ */ +/* struct s_wordlist */ +/* { */ +/* char *word; */ +/* struct s_wordlist *next; */ +/* }; */ + +/* struct s_case_item */ +/* { */ +/* char **patterns; */ +/* int allocated; */ +/* int pos; */ +/* }; */ + +/* struct s_item */ +/* { */ +/* struct s_wordlist *pl; */ +/* struct s_ast *cmd_list; */ +/* }; */ + + + +/* /\** */ +/* ** temporary structure */ +/* ** which contains prefix and */ +/* ** suffix command informations */ +/* ** argv word or assigment words terminated by NULL */ +/* ** redirs redirection pointer */ +/* ** pos position in argv array */ +/* ** nb_arg_alloc positions allocated */ +/* *\/ */ +/* struct s_cmd_opt */ +/* { */ +/* char **argv; */ +/* struct s_redir *redirs; */ +/* int pos; */ +/* int nb_arg_alloc; */ +/* }; */ +/* /\** */ +/* ** create temporary structure */ +/* ** in order to get prefix and */ +/* ** suffix informations */ +/* *\/ */ +/* struct s_cmd_opt *tmp_create_cmdopt(struct s_cmd_opt *opt, */ +/* struct s_redir *redir, */ +/* char *arg); */ +/* /\** */ +/* ** add redirection to temporary */ +/* ** structure s_redir */ +/* *\/ */ +/* struct s_redir *tmp_add_redir(struct s_redir *base, struct s_redir *nelt); */ +/* /\** */ +/* ** create temporary structure s_redir */ +/* *\/ */ +/* struct s_redir *tmp_create_redir(enum e_redir type, */ +/* char *filename, */ +/* int fd, */ +/* struct s_redir *redir); */ +/* /\* */ +/* ** PLEASE NOTE */ +/* ** Every time, any argument given so this functions must be on the heap, */ +/* ** they are not copied. Don't forget to dup string, for function create_cmd, */ +/* ** function add_redir and function create_for */ +/* *\/ */ + +/* /\*! */ +/* ** Create an and node */ +/* ** */ +/* ** @param lhs left hand side */ +/* ** @param rhs right hand side */ +/* ** */ +/* ** @return new ast node */ +/* *\/ */ +/* struct s_ast *ast_create_and(struct s_ast *lhs, struct s_ast *rhs); */ +/* /\*! */ +/* ** Create an or node */ +/* ** */ +/* ** @param lhs left hand side */ +/* ** @param rhs right hand side */ +/* ** */ +/* ** @return new ast node */ +/* *\/ */ +/* struct s_ast *ast_create_or(struct s_ast *lhs, struct s_ast *rhs); */ +/* struct s_ast *ast_create_case_clause(char *word, */ +/* struct s_ast *case_list); */ +/* struct s_ast *ast_create_if(struct s_ast *cond, */ +/* struct s_ast *positive, */ +/* struct s_ast *negative); */ +/* struct s_ast *ast_create_funcdec(char *name, struct s_ast *body); */ +/* struct s_ast *ast_create_subshell(struct s_ast *cmd); */ +/* struct s_ast *ast_create_for(char *varname, */ +/* struct s_ast *value, */ +/* struct s_ast *exec); */ +/* /\** */ +/* ** create cmd node */ +/* *\/ */ +/* struct s_ast *ast_create_cmd(struct s_cmd_opt *prefix, */ +/* char *cmd, */ +/* struct s_cmd_opt *suffix); */ + +/* /\* struct s_ast *ast_create_list(struct s_ast **item); *\/ */ +/* struct s_ast *ast_create_until(struct s_ast *cond, */ +/* struct s_ast *exec); */ +/* struct s_ast *ast_create_while(struct s_ast *cond, */ +/* struct s_ast *exec); */ +/* /\** */ +/* ** create pipe node */ +/* *\/ */ +/* struct s_ast *ast_create_pipe(struct s_ast *cmd1, */ +/* struct s_ast *cmd2); */ +/* /\** */ +/* ** create shell structure */ +/* *\/ */ +/* struct s_42sh *ast_create_ast(struct s_42sh *shell, */ +/* struct s_ast *ast); */ + +/* struct s_ast *ast_create_patterns(char *word, struct s_ast *case_item); */ +/* struct s_ast *ast_create_case_list(struct s_ast *item, */ +/* struct s_ast *case_list); */ +/* struct s_ast *ast_create_wordlist(struct s_ast *wl, */ +/* char *w); */ +/* /\** */ +/* ** change ast type : PIPE -> BANG_PIPE and CMD -> BANG_CMD */ +/* *\/ */ +/* struct s_ast *ast_create_bang(struct s_ast *ast); */ +/* struct s_ast *ast_create_sep_op(struct s_ast *cmd1, */ +/* enum e_type sep_op, */ +/* struct s_ast *cmd2); */ + +/* /\* void ast_destruct_list(struct s_ast *node); *\/ */ +/* void ast_destruct_cmd(struct s_ast *node); */ +/* void ast_destruct_pipe(struct s_ast *node); */ +/* void ast_destruct_redir(struct s_redir *red); */ + +/* /\* void ast_print(struct s_ast *ast); *\/ */ +/* void ast_destruct_sep_op(struct s_ast *node); */ +/* void ast_destruct_for(struct s_ast *node); */ +/* void ast_destruct_until(struct s_ast *node); */ +/* void ast_destruct_while(struct s_ast *node); */ +/* void ast_destruct_if(struct s_ast *node); */ +/* void ast_destruct(struct s_ast *node); */ +/* void ast_destruct_bang(struct s_ast *node); */ +/* void ast_destruct_wordlist(struct s_ast *node); */ +/* void ast_destruct_case(struct s_ast *node); */ +/* /\*! */ +/* ** Destruct an and node */ +/* ** */ +/* ** @param node head of node to destruct */ +/* *\/ */ +/* void ast_destruct_and(struct s_ast *node); */ +/* /\*! */ +/* ** Destruct an or node */ +/* ** */ +/* ** @param node head of node to destruct */ +/* *\/ */ +/* void ast_destruct_or(struct s_ast *node); */ +/* void ast_destruct_subshell(struct s_ast *node); */ #endif /* !AST_H_ */ diff --git a/src/parser/parser.c b/src/parser/parser.c new file mode 100644 index 0000000000000000000000000000000000000000..536e00c005df12bead59e40f97f363bacbfeebce --- /dev/null +++ b/src/parser/parser.c @@ -0,0 +1,26 @@ +/* +** parser.c for 42sh in /home/seblu/svn/42sh/src/parser +** +** Made by Seblu +** Login +** +** Started on Wed Aug 2 00:56:07 2006 Seblu +** Last update Wed Aug 2 17:47:01 2006 Seblu +*/ + +#include "parser.h" + +/*! +** Parse a File stream, and return the ast +** +** @param fs file stream to parse +** +** @return ast from the file stream +*/ +ts_ast_node *parse(FILE* fs) +{ + int fd; + + fd = fileno(fs); + return NULL; +} diff --git a/src/parser/parser.h b/src/parser/parser.h new file mode 100644 index 0000000000000000000000000000000000000000..d4ad9a6541a95c212f3d44531368df47d952da80 --- /dev/null +++ b/src/parser/parser.h @@ -0,0 +1,19 @@ +/* +** parser.h for 42sh +** +** Made by Seblu +** Login +** +** Started on Wed Aug 2 00:49:50 2006 Seblu +** Last update Wed Aug 2 17:47:18 2006 Seblu +*/ + +#include +#include "../ast/ast.h" + +#ifndef PARSER_H_ +# define PARSER_H_ + +ts_ast_node *parse(FILE* fs); + +#endif diff --git a/src/readline/getln.c b/src/readline/getln.c new file mode 100644 index 0000000000000000000000000000000000000000..7d7b55cdde45c57c873efe23afdee5673c4327d6 --- /dev/null +++ b/src/readline/getln.c @@ -0,0 +1,99 @@ +/* +** getln.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Wed Aug 2 01:25:01 2006 Seblu +** Last update Wed Aug 2 01:38:22 2006 Seblu +*/ + +#include "readline.h" + +/*! +** Secure layer over strlen +** +** @param s the string +** +** @return lenght of the string +*/ +inline static size_t sstrlen(const char *s) +{ + if (s == NULL) + return 0; + return strlen(s); +} + +/* +** Append a string to the buffer string +*/ +inline static void buf_str(char **str, char *append, unsigned n) +{ + unsigned ln; + unsigned i; + unsigned j; + + ln = len(*str); + if ((*str = realloc(*str, (ln + n + 1) * sizeof (char))) == NULL) + exit(1); + for (i = ln, j = 0; i < ln + n; i++, j++) + (*str)[i] = append[j]; + (*str)[ln + n] = 0; +} + + +/* +** Memory allocation of getln buffer +*/ +struct s_getln *getln_open(const int fd) +{ + struct s_getln *new_buf; + + if ((new_buf = malloc(sizeof (struct s_getln))) == NULL) + exit(1); + new_buf->fd = fd; + new_buf->size = 0; + new_buf->offset = 0; + return new_buf; +} + +/* +** Free a getln struct +*/ +void getln_close(struct s_getln *buf, const int closefd) +{ + if (closefd) + close(buf->fd); + free(buf); +} + +/* +** Get next line in a file +** Return NULL when nothing to read +*/ +char *getln(struct s_getln *buf) +{ + char *string = NULL; + int i; + + do + { + for (i = buf->offset; i < buf->size; i++) + { + if (buf->data[i] == '\n') + { + buf_str(&(string), buf->data + buf->offset, i - buf->offset); + buf->offset = i + 1; + return string; + } + } + if (buf->size - buf->offset > 0) + buf_str(&(string), buf->data + buf->offset, buf->size - buf->offset); + buf->offset = 0; + buf->size = read(buf->fd, buf->data, GETLN_BUF_SIZE); + if (buf->size < 0) + buf->size = 0; + } + while (buf->size > 0); + return string; +} diff --git a/src/readline/readline.c b/src/readline/readline.c new file mode 100644 index 0000000000000000000000000000000000000000..ffc9eff0463158d1b918c17256ab78dceb3f58d8 --- /dev/null +++ b/src/readline/readline.c @@ -0,0 +1,23 @@ +/* +** readline.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Wed Aug 2 01:13:56 2006 Seblu +** Last update Wed Aug 2 17:58:03 2006 Seblu +*/ + +#include +#include +#include +#include "readline.h" + +struct s_getln getln_stdin; + +char *readline(const char *prompt) +{ + if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO)) + write(STDERR_FILENO, prompt, strlen(prompt)); + return getln(&getln_stdin); +} diff --git a/src/readline/readline.h b/src/readline/readline.h new file mode 100644 index 0000000000000000000000000000000000000000..dadb8ed393f04ed8f86389f61c5b19c73870fc7b --- /dev/null +++ b/src/readline/readline.h @@ -0,0 +1,29 @@ +/* +** readline.h for 42sh +** +** Made by Seblu +** Login +** +** Started on Wed Aug 2 01:06:25 2006 Seblu +** Last update Wed Aug 2 17:57:38 2006 Seblu +*/ + +#ifndef READLINE_H_ +# define READLINE_H_ + +# define GETLN_BUF_SIZE 1024 + +struct s_getln +{ + int fd; + char data[GETLN_BUF_SIZE]; + unsigned offset; + int size; +}; + +char *readline(const char *prompt); +char *getln(struct s_getln *buf); +void getln_close(struct s_getln *buf, const int closefd); +struct s_getln *getln_open(const int fd); + +#endif