diff --git a/AUTHORS b/AUTHORS index 3c0df24c8041456e472e84520061de734e8f11f6..b226e54a2c76a7c7722dbecab102dfd88bd387f7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Sebastien Luttringer \ No newline at end of file +Sebastien LUTTRINGER diff --git a/TODO b/TODO index b8a50c5a5a2df6c6bcd2850e40aec39272924eac..b7a43dadae8df17b1af3fd45cf9b0da995ef5eee 100644 --- a/TODO +++ b/TODO @@ -1,17 +1,8 @@ ----- -Revoir les free dans le parser a cause de ast_destruct qui rentre dans les fils. -il faudrait ecrire des fonctions qui ne le fasse pas! Voir aussi au niveau de la -boucle general si ast_destruct est appele alors qu'une erreur de parse est surevenur -(le cas echeant, le supprimer) ----- -Voir probleme de syntax que j'accepte lorsque un EOF apparait avant une quote -fermante. Le token est valide alors que sous bash non ----- -ajotuer le prompt PS3 lorsque l'on parse sur plusieurs ligne ----- -parse du case ----- -parse du funcdec ----- -corriger le bug - ./42sh ** ** Started on Sun Jul 30 04:40:03 2006 Seblu -** Last update Wed Oct 11 14:58:42 2006 seblu +** Last update Tue Oct 17 17:14:49 2006 seblu */ #ifndef AST_H_ @@ -106,7 +106,7 @@ typedef struct cmd_node ** Binary ast node ** Generic node, it's a contener ! ** T_PIPE, T_SEP* , T_AND, T_OR : binary operator -** T_BANG : unary operator but ts_bin_op with right pointer is always NULL +** T_BANG : unary operator */ typedef struct bin_node { @@ -158,6 +158,7 @@ typedef union node_item s_for_node child_for; s_case_node child_case; s_while_node child_while; + s_red_node child_red; s_cmd_node child_cmd; s_bin_node child_and; s_bin_node child_or; @@ -167,7 +168,6 @@ typedef union node_item s_bin_node child_pipe; s_bin_node child_sep; s_bin_node child_sepand; - s_red_node child_red; } u_node_item; /* @@ -205,6 +205,14 @@ void ast_print_node(s_ast_node *ast, FILE *fs, unsigned int *node_id); */ void ast_destruct(s_ast_node *ast); +/*! +** Destroy node and only this node. All childs will survive. +** +** @param ast mother node to destroy +** +*/ +void ast_destruct_node(s_ast_node *ast); + /*! ** Create an if ast node ** @@ -227,7 +235,14 @@ s_ast_node *ast_if_create(s_ast_node *cond, void ast_if_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct an if ast node +** Destruct an if ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_if_destruct_node(s_ast_node *node); + +/*! +** Destruct an if ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -257,7 +272,14 @@ s_ast_node *ast_for_create(char *varname, void ast_for_print(s_ast_node *node, FILE *fs, unsigned *node_id); /*! -** Destruct a for ast node +** Destruct a for ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_for_destruct_node(s_ast_node *node); + +/*! +** Destruct a for ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -294,7 +316,14 @@ void ast_case_add_item(s_ast_node *node, void ast_case_print(s_ast_node *node, FILE *fs, unsigned *node_id); /*! -** Destruct a case ast node +** Destruct a case ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_case_destruct_node(s_ast_node *node); + +/*! +** Destruct a case ast node. Destruct child node. ** ** @param node node to destroy */ @@ -320,12 +349,62 @@ s_ast_node *ast_while_create(s_ast_node *cond, s_ast_node *exec); void ast_while_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a while ast node +** Destruct a while ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_while_destruct_node(s_ast_node *node); + +/*! +** Destruct a while ast node. Destruct all child nodes. ** ** @param node node to destroy */ void ast_while_destruct(s_ast_node *node); +/*! +** Create a redirection ast node +** +** @return the node +*/ +s_ast_node *ast_red_create(void); + +/*! +** Add a redirection to a redirection node +** +** @param node node where add +** @param type type of redirection +** @param fd fd parameter of redirection +** @param word file or word parameter of redirection +*/ +void ast_red_add(s_ast_node *node, + e_red_type type, + int fd, + char *word); + +/*! +** Print an ast red node +** +** @param ast ast node to add to file +** @param fs file stream where print ast +** @param node_id first free node id +*/ +void ast_red_print(s_ast_node *node, FILE *fs, unsigned int *node_id); + +/*! +** Destruct a red ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_red_destruct_node(s_ast_node *node); + +/*! +** Destruct a red ast node. Destruct child nodes. +** +** @param node node to destroy +*/ +void ast_red_destruct(s_ast_node *node); + /*! ** Create a cmd ast node ** @@ -359,7 +438,14 @@ void ast_cmd_add_prefix(s_ast_node *node, char *assignment_word); void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a cmd node +** Destruct a cmd ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_cmd_destruct_node(s_ast_node *node); + +/*! +** Destruct a cmd node. All child nodes will be destruct. ** ** @param node node to destroy */ @@ -385,7 +471,14 @@ s_ast_node *ast_and_create(s_ast_node *lhs, s_ast_node *rhs); void ast_and_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct an and (&&) node +** Destruct an and ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_and_destruct_node(s_ast_node *node); + +/*! +** Destruct an and (&&) node. Destruct all child nodes. ** ** @param node node to destroy */ @@ -411,7 +504,14 @@ s_ast_node *ast_or_create(s_ast_node *lhs, s_ast_node *rhs); void ast_or_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct an or (||) node +** Destruct an or ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_or_destruct_node(s_ast_node *node); + +/*! +** Destruct an or (||) ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -436,7 +536,14 @@ s_ast_node *ast_subshell_create(s_ast_node *child); void ast_subshell_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a subshell (()) node +** Destruct a subshell (()) ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_subshell_destruct_node(s_ast_node *node); + +/*! +** Destruct a subshell (()) ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -462,7 +569,14 @@ s_ast_node *ast_funcdec_create(char *name, s_ast_node *body); void ast_funcdec_print(s_ast_node *node, FILE *fs, unsigned *node_id); /*! -** Destruct a funcdec ast node +** Destruct a funcdec ast node. Don't destruct child nodes. +** +** @param node node to free +*/ +void ast_funcdec_destruct_node(s_ast_node *node); + +/*! +** Destruct a funcdec ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -487,7 +601,14 @@ s_ast_node *ast_bang_create(s_ast_node *child); void ast_bang_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a bang (!) node +** Destruct a bang (!) ast node. Don't destruct child nodes. +** +** @param node node to destroy +*/ +void ast_bang_destruct_node(s_ast_node *node); + +/*! +** Destruct a bang (!) ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -512,6 +633,12 @@ s_ast_node *ast_pipe_create(s_ast_node *lhs, s_ast_node *rhs); */ void ast_pipe_print(s_ast_node *node, FILE *fs, unsigned int *node_id); +/*! +** Destruct a pipe (|) ast node. Don't destruct child nodes. +** +** @param node node to destroy +*/ +void ast_pipe_destruct_node(s_ast_node *node); /*! ** Destruct a pipe (|) node ** @@ -539,7 +666,13 @@ s_ast_node *ast_sep_create(s_ast_node *lhs, s_ast_node *rhs); void ast_sep_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a sep (;) node +** Destruct a sep (;) ast node. Don't destruct child nodes. +** +** @param node node to destroy +*/ +void ast_sep_destruct_node(s_ast_node *node); +/*! +** Destruct a sep (;) ast node. Destruct child nodes. ** ** @param node node to destroy */ @@ -565,46 +698,17 @@ s_ast_node *ast_sepand_create(s_ast_node *lhs, s_ast_node *rhs); void ast_sepand_print(s_ast_node *node, FILE *fs, unsigned int *node_id); /*! -** Destruct a sepand (&) node +** Destruct a sepand (&) ast node. Don't destruct child nodes. ** ** @param node node to destroy */ -void ast_sepand_destruct(s_ast_node *node); - -/*! -** Create a redirection ast node -** -** @return the node -*/ -s_ast_node *ast_red_create(void); - -/*! -** Add a redirection to a redirection node -** -** @param node node where add -** @param type type of redirection -** @param fd fd parameter of redirection -** @param word file or word parameter of redirection -*/ -void ast_red_add(s_ast_node *node, - e_red_type type, - int fd, - char *word); - -/*! -** Print an ast red node -** -** @param ast ast node to add to file -** @param fs file stream where print ast -** @param node_id first free node id -*/ -void ast_red_print(s_ast_node *node, FILE *fs, unsigned int *node_id); +void ast_sepand_destruct_node(s_ast_node *node); /*! -** Destruct a red node +** Destruct a sepand (&) ast node. Destruct child nodes. ** ** @param node node to destroy */ -void ast_red_destruct(s_ast_node *node); +void ast_sepand_destruct(s_ast_node *node); #endif /* !AST_H_ */ diff --git a/src/ast/ast_and.c b/src/ast/ast_and.c index 02c5d7d994cd5c8e53cd500b0617f8c79cbd560f..b62991061b984c2450155ae2e451a5bad22b9a17 100644 --- a/src/ast/ast_and.c +++ b/src/ast/ast_and.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:45:16 2006 Seblu +** Last update Tue Oct 17 16:50:32 2006 seblu */ #include "ast.h" @@ -36,6 +36,13 @@ void ast_and_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, rhs_id); } +void ast_and_destruct_node(s_ast_node *node) +{ + if (node->type != T_AND) + return; + free(node); +} + void ast_and_destruct(s_ast_node *node) { if (node->type != T_AND) diff --git a/src/ast/ast_bang.c b/src/ast/ast_bang.c index 50df098c9325248ed1c68931e7711f500247aedd..acb8ca92f5e7b7dde41ad795d14d51726bb7fa05 100644 --- a/src/ast/ast_bang.c +++ b/src/ast/ast_bang.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:45:45 2006 Seblu +** Last update Tue Oct 17 17:12:13 2006 seblu */ #include "ast.h" @@ -33,6 +33,13 @@ void ast_bang_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, lhs_id); } +void ast_bang_destruct_node(s_ast_node *node) +{ + if (node->type != T_BANG) + return; + free(node); +} + void ast_bang_destruct(s_ast_node *node) { if (node->type != T_BANG) @@ -40,4 +47,3 @@ void ast_bang_destruct(s_ast_node *node) ast_destruct(node->body.child_bang.lhs); free(node); } - diff --git a/src/ast/ast_case.c b/src/ast/ast_case.c index 7e7cbc846beac0759d025727d97b4a7844168dde..fd5ecfece160d6bafc6563bcaa6badbe4e6c6bf5 100644 --- a/src/ast/ast_case.c +++ b/src/ast/ast_case.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Wed Oct 11 13:07:50 2006 seblu +** Last update Tue Oct 17 16:36:25 2006 seblu */ #include "ast.h" @@ -34,7 +34,7 @@ void ast_case_add_item(s_ast_node *node, item->pattern = pattern; item->exec = exec; item->next = NULL; - for (this = &node->body.child_case.items; *this; *this = (*this)->next) + for (this = &node->body.child_case.items; *this; this = &(*this)->next) ; //do nothing *this = item; } @@ -44,17 +44,19 @@ void ast_case_print(s_ast_node *node, FILE *fs, unsigned *node_id) unsigned cur_node; s_case_item *item; unsigned item_id; + unsigned item_node; if (node->type != T_CASE) return; fprintf(fs, "%u [label = \"CASE\\nword: %s\"];\n", cur_node = *node_id, node->body.child_case.word); ++*node_id; + //show items for (item = node->body.child_case.items, item_id = 0; item; item = item->next, ++item_id) { fprintf(fs, "%u -> %u\n", cur_node, *node_id); - fprintf(fs, "%u [ label = \"Item %u\\n", *node_id, item_id); + fprintf(fs, "%u [label = \"Item %u\\n", item_node = *node_id, item_id); ++*node_id; //print pattern if (item->pattern) @@ -62,11 +64,30 @@ void ast_case_print(s_ast_node *node, FILE *fs, unsigned *node_id) fprintf(fs, "%s\\n", item->pattern[i]); fprintf(fs, "\"];\n"); //print exec - if (item->exec) + if (item->exec) { + fprintf(fs, "%u -> %u\n", item_node, *node_id); ast_print_node(item->exec, fs, node_id); + } } } +void ast_case_destruct_node(s_ast_node *node) +{ + s_case_item *this, *buf; + + if (node->type != T_CASE) + return; + free(node->body.child_case.word); + for (this = node->body.child_case.items; this; this = buf) { + for (register int i = 0; this->pattern[i]; ++i) + free(this->pattern[i]); + free(this->pattern); + buf = this->next; + free(this); + } + free(node); +} + void ast_case_destruct(s_ast_node *node) { s_case_item *this, *buf; diff --git a/src/ast/ast_cmd.c b/src/ast/ast_cmd.c index 8ab60626eaae0b51713385bb6debff091a782263..97d66897b485a4340223ac8319f814f552b33aa9 100644 --- a/src/ast/ast_cmd.c +++ b/src/ast/ast_cmd.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Fri Aug 18 22:13:51 2006 Seblu -** Last update Tue Oct 10 14:27:02 2006 seblu +** Last update Tue Oct 17 17:00:22 2006 seblu */ #include "ast.h" @@ -83,6 +83,11 @@ void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "\"];\n"); } +void ast_cmd_destruct_node(s_ast_node *node) +{ + ast_cmd_destruct(node); +} + void ast_cmd_destruct(s_ast_node *node) { if (node->type != T_CMD) diff --git a/src/ast/ast_destruct.c b/src/ast/ast_destruct.c index 095126a8b900be87f4fe0fd83511ec911aefddc1..9f8c17cf9edce4b137c29359cd50fde9bf0f5983 100644 --- a/src/ast/ast_destruct.c +++ b/src/ast/ast_destruct.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sat Mar 25 23:11:01 2006 Seblu -** Last update Mon Oct 16 18:10:35 2006 seblu +** Last update Tue Oct 17 16:43:29 2006 seblu */ #include "ast.h" @@ -32,10 +32,28 @@ struct ast_destruct_switch destruction_table[NODE_TYPE_COUNT] = {T_PIPE, ast_pipe_destruct}, {T_SEPAND, ast_sepand_destruct}, {T_SEP, ast_sep_destruct}, - {T_CASE, ast_sepand_destruct}, + {T_CASE, ast_case_destruct}, {T_RED, ast_red_destruct} }; +struct ast_destruct_switch destruction_node_table[NODE_TYPE_COUNT] = + { + {T_IF, ast_if_destruct_node}, + {T_FOR, ast_for_destruct_node}, + {T_WHILE, ast_while_destruct_node}, + {T_CMD, ast_cmd_destruct_node}, + {T_AND, ast_and_destruct_node}, + {T_OR, ast_or_destruct_node}, + {T_SUBSHELL, ast_subshell_destruct_node}, + {T_FUNCDEC, ast_funcdec_destruct_node}, + {T_BANG, ast_bang_destruct_node}, + {T_PIPE, ast_pipe_destruct_node}, + {T_SEPAND, ast_sepand_destruct_node}, + {T_SEP, ast_sep_destruct_node}, + {T_CASE, ast_case_destruct_node}, + {T_RED, ast_red_destruct_node} + }; + void ast_destruct(s_ast_node *ast) { if (ast == NULL) @@ -46,3 +64,14 @@ void ast_destruct(s_ast_node *ast) return; } } + +void ast_destruct_node(s_ast_node *ast) +{ + if (ast == NULL) + return; + for (register int i = 0; i < NODE_TYPE_COUNT; ++i) + if (destruction_node_table[i].type == ast->type) { + (destruction_node_table[i].fct)(ast); + return; + } +} diff --git a/src/ast/ast_for.c b/src/ast/ast_for.c index f3c800dbbf289736f87204067dc02efe462d69ca..2c1b81b2427f362413eab95bab67402f64495ed8 100644 --- a/src/ast/ast_for.c +++ b/src/ast/ast_for.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Oct 12 16:01:04 2006 seblu +** Last update Tue Oct 17 17:15:27 2006 seblu */ #include "ast.h" @@ -49,7 +49,7 @@ void ast_for_print(s_ast_node *node, FILE *fs, unsigned *node_id) } } -void ast_for_destruct(s_ast_node *node) +void ast_for_destruct_node(s_ast_node *node) { if (node->type != T_FOR) return; @@ -57,6 +57,13 @@ void ast_for_destruct(s_ast_node *node) for (register int i = 0; node->body.child_for.values[i]; ++i) free(node->body.child_for.values[i]); free(node->body.child_for.values); - ast_destruct(node->body.child_for.exec); free(node); } + +void ast_for_destruct(s_ast_node *node) +{ + if (node->type != T_FOR) + return; + ast_destruct(node->body.child_for.exec); + ast_for_destruct_node(node); +} diff --git a/src/ast/ast_funcdec.c b/src/ast/ast_funcdec.c index 3fc38e76be547742184d9bb06d00254fa943041b..5421520399aa1720b03dca67ca3ee95e06e2312f 100644 --- a/src/ast/ast_funcdec.c +++ b/src/ast/ast_funcdec.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Oct 10 14:40:44 2006 seblu +** Last update Wed Oct 18 17:14:16 2006 seblu */ #include "ast.h" @@ -27,13 +27,21 @@ void ast_funcdec_print(s_ast_node *node, FILE *fs, unsigned *node_id) if (node->type != T_FUNCDEC) return; - fprintf(fs, "%u [label = \"FuncDec\\nName: %s\"];\n", + fprintf(fs, "%u [label = \"FuncDec\\nname: %s\"];\n", cur_id = *node_id, node->body.child_funcdec.name); lhs_id = ++*node_id; ast_print_node(node->body.child_funcdec.body, fs, node_id); fprintf(fs, "%u -> %u\n", cur_id, lhs_id); } +void ast_funcdec_destruct_node(s_ast_node *node) +{ + if (node->type != T_FUNCDEC) + return; + free(node->body.child_funcdec.name); + free(node); +} + void ast_funcdec_destruct(s_ast_node *node) { if (node->type != T_FUNCDEC) diff --git a/src/ast/ast_if.c b/src/ast/ast_if.c index a4d846e0fe1628d93abc59d59fa8c07be745691c..6d8d0dae71136df8086294f36265f945088fcf56 100644 --- a/src/ast/ast_if.c +++ b/src/ast/ast_if.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Oct 10 17:15:53 2006 seblu +** Last update Tue Oct 17 16:30:23 2006 seblu */ #include "ast.h" @@ -49,6 +49,13 @@ void ast_if_print(s_ast_node *node, FILE *fs, unsigned *node_id) } } +void ast_if_destruct_node(s_ast_node *node) +{ + if (node->type != T_IF) + return; + free(node); +} + void ast_if_destruct(s_ast_node *node) { if (node->type != T_IF) diff --git a/src/ast/ast_or.c b/src/ast/ast_or.c index 2110f69b08a772dd4f3f4f83083df1edb74c6b9e..485ba66dc0790dff73bdcbbc765430868cfa5926 100644 --- a/src/ast/ast_or.c +++ b/src/ast/ast_or.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:45:54 2006 Seblu +** Last update Tue Oct 17 17:01:20 2006 seblu */ #include "ast.h" @@ -36,6 +36,13 @@ void ast_or_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, rhs_id); } +void ast_or_destruct_node(s_ast_node *node) +{ + if (node->type != T_OR) + return; + free(node); +} + void ast_or_destruct(s_ast_node *node) { if (node->type != T_OR) diff --git a/src/ast/ast_pipe.c b/src/ast/ast_pipe.c index 826c1bf69fe028bd448628a7784662613111a190..8c880d80c7d198f0a5eb2fe3484d9c8e603a0333 100644 --- a/src/ast/ast_pipe.c +++ b/src/ast/ast_pipe.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:45:33 2006 Seblu +** Last update Tue Oct 17 17:12:46 2006 seblu */ #include "ast.h" @@ -36,6 +36,13 @@ void ast_pipe_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, rhs_id); } +void ast_pipe_destruct_node(s_ast_node *node) +{ + if (node->type != T_PIPE) + return; + free(node); +} + void ast_pipe_destruct(s_ast_node *node) { if (node->type != T_PIPE) @@ -44,4 +51,3 @@ void ast_pipe_destruct(s_ast_node *node) ast_destruct(node->body.child_pipe.rhs); free(node); } - diff --git a/src/ast/ast_red.c b/src/ast/ast_red.c index dac0bef51a7fd113691f182c42984008c6892b28..5d2f992c3cf953073e3318ab3a511f0a4eaa5b23 100644 --- a/src/ast/ast_red.c +++ b/src/ast/ast_red.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Fri Aug 18 22:13:51 2006 Seblu -** Last update Mon Oct 16 17:26:11 2006 seblu +** Last update Tue Oct 17 17:16:40 2006 seblu */ #include "ast.h" @@ -17,6 +17,9 @@ s_ast_node *ast_red_create(void) secmalloc(node, sizeof (s_ast_node)); node->type = T_RED; node->body.child_red.size = 0; + node->body.child_red.type = NULL; + node->body.child_red.fd = NULL; + node->body.child_red.word = NULL; node->body.child_red.mhs = NULL; return node; } @@ -58,7 +61,7 @@ void ast_red_print(s_ast_node *node, FILE *fs, unsigned *node_id) ast_print_node(reds->mhs, fs, node_id); } -void ast_red_destruct(s_ast_node *node) +void ast_red_destruct_node(s_ast_node *node) { s_red_node *reds; @@ -68,9 +71,17 @@ void ast_red_destruct(s_ast_node *node) if (reds->size) { free(reds->type); free(reds->fd); - for (register size_t i = 0; i < node->body.child_red.size; ++i) + for (register size_t i = 0; i < reds->size; ++i) free(reds->word[i]); free(reds->word); } free(node); } + +void ast_red_destruct(s_ast_node *node) +{ + if (node->type != T_RED) + return; + ast_destruct(node->body.child_red.mhs); + ast_red_destruct_node(node); +} diff --git a/src/ast/ast_sep.c b/src/ast/ast_sep.c index e7c520c246fdae9e754cd1779a4e6e7e49f715bf..fbd154bbb3379e422f310c839ce13835cd229a1f 100644 --- a/src/ast/ast_sep.c +++ b/src/ast/ast_sep.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Oct 12 13:11:35 2006 seblu +** Last update Tue Oct 17 17:13:30 2006 seblu */ #include "ast.h" @@ -37,6 +37,13 @@ void ast_sep_print(s_ast_node *node, FILE *fs, unsigned int *node_id) } } +void ast_sep_destruct_node(s_ast_node *node) +{ + if (node->type != T_SEP) + return; + free(node); +} + void ast_sep_destruct(s_ast_node *node) { if (node->type != T_SEP) @@ -45,4 +52,3 @@ void ast_sep_destruct(s_ast_node *node) ast_destruct(node->body.child_sep.rhs); free(node); } - diff --git a/src/ast/ast_sepand.c b/src/ast/ast_sepand.c index 964b7d158796afb77154cba4347507ba1c8c2764..4cc9886414c4cff3de7ad63f7873ae6e77f22156 100644 --- a/src/ast/ast_sepand.c +++ b/src/ast/ast_sepand.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Thu Oct 12 13:12:13 2006 seblu +** Last update Tue Oct 17 17:14:00 2006 seblu */ #include "ast.h" @@ -38,6 +38,13 @@ void ast_sepand_print(s_ast_node *node, FILE *fs, unsigned int *node_id) } } +void ast_sepand_destruct_node(s_ast_node *node) +{ + if (node->type != T_SEPAND) + return; + free(node); +} + void ast_sepand_destruct(s_ast_node *node) { if (node->type != T_SEPAND) @@ -46,4 +53,3 @@ void ast_sepand_destruct(s_ast_node *node) ast_destruct(node->body.child_sepand.rhs); free(node); } - diff --git a/src/ast/ast_subshell.c b/src/ast/ast_subshell.c index e8bfe8d36e8839cf253103f1a6ae0cf2e32b0581..587e2126e4c5c511e287883577a51f77cbd44b60 100644 --- a/src/ast/ast_subshell.c +++ b/src/ast/ast_subshell.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:43:33 2006 Seblu +** Last update Tue Oct 17 17:02:57 2006 seblu */ #include "ast.h" @@ -33,6 +33,13 @@ void ast_subshell_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, lhs_id); } +void ast_subshell_destruct_node(s_ast_node *node) +{ + if (node->type != T_SUBSHELL) + return; + free(node); +} + void ast_subshell_destruct(s_ast_node *node) { if (node->type != T_SUBSHELL) diff --git a/src/ast/ast_while.c b/src/ast/ast_while.c index a62b2081490dac4e72746b36d967fd8f1eb59802..a49ad61fc7acc05e0e455c866c90449bec5dde4a 100644 --- a/src/ast/ast_while.c +++ b/src/ast/ast_while.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Thu Aug 3 02:41:37 2006 Seblu -** Last update Tue Sep 26 17:44:08 2006 Seblu +** Last update Tue Oct 17 16:44:13 2006 seblu */ #include "ast.h" @@ -36,6 +36,13 @@ void ast_while_print(s_ast_node *node, FILE *fs, unsigned int *node_id) fprintf(fs, "%u -> %u\n", cur_id, rhs_id); } +void ast_while_destruct_node(s_ast_node *node) +{ + if (node->type != T_WHILE) + return; + free(node); +} + void ast_while_destruct(s_ast_node *node) { if (node->type != T_WHILE) diff --git a/src/common/macro.h b/src/common/macro.h index bf39c395eb1169404bff4aae3857341647d2a502..d61e09e35734ac41517b19994325a2166ff21e1d 100644 --- a/src/common/macro.h +++ b/src/common/macro.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Fri Aug 25 03:32:54 2006 Seblu -** Last update Fri Oct 13 14:33:10 2006 seblu +** Last update Tue Oct 17 10:15:20 2006 seblu */ #ifndef MACRO_H_ diff --git a/src/parser/getline.c b/src/parser/getline.c index 049dd7e60a01dbb5d0d5a1dce05cde7200495123..bb7a42c797223156c18abb38127861edbbb651b3 100644 --- a/src/parser/getline.c +++ b/src/parser/getline.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Wed Aug 2 01:25:01 2006 Seblu -** Last update Tue Aug 29 02:20:32 2006 Seblu +** Last update Tue Oct 17 09:51:30 2006 seblu */ #include @@ -33,16 +33,15 @@ static void buf_str(char **str, char *append, unsigned n) unsigned j; ln = sstrlen(*str); - if ((*str = realloc(*str, (ln + n + 1) * sizeof (char))) == NULL) - exit(1); + secrealloc(*str, *str, (ln + n + 1) * sizeof (char)); for (i = ln, j = 0; i < ln + n; i++, j++) (*str)[i] = append[j]; (*str)[ln + n] = 0; } -s_getline *getline_open(int fd) +s_getline *getline_open(int fd) { - s_getline *new_buf; + s_getline *new_buf; secmalloc(new_buf, sizeof (s_getline)); new_buf->fd = fd; diff --git a/src/parser/lexer.c b/src/parser/lexer.c index 63dc48dc6bf7921e083e157622ce9ae6c11d2094..7c6a365605f6859129e341fe2b05c544ec1a4518 100644 --- a/src/parser/lexer.c +++ b/src/parser/lexer.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 04:36:53 2006 Seblu -** Last update Thu Oct 12 15:45:20 2006 seblu +** Last update Wed Oct 18 18:27:39 2006 seblu */ #include @@ -158,6 +158,14 @@ static int lexer_cut(s_lexer *lexer); */ static void token_set(s_token *token, e_tokenid id, char *s); +/*! +** Move a token to another. Token source, will become token +** NONE. +** +** @param src source token +** @param dst destination token +*/ +static void token_move(s_token *src, s_token *dst); /* ** =========== @@ -173,14 +181,16 @@ s_lexer *lexer_init(int fd) new->stream = getline_open(fd); new->buf = NULL; new->buf_size = new->buf_pos = 0; - token_set(&new->token, TOK_NONE, NULL); + token_set(&new->previous, TOK_NONE, NULL); + token_set(&new->current, TOK_NONE, NULL); new->eof = 0; return new; } void lexer_flush(s_lexer *lexer) { - token_set(&lexer->token, TOK_NONE, NULL); + token_set(&lexer->previous, TOK_NONE, NULL); + token_set(&lexer->current, TOK_NONE, NULL); if (lexer->buf) free(lexer->buf); lexer->buf = NULL; @@ -189,20 +199,34 @@ void lexer_flush(s_lexer *lexer) s_token lexer_lookahead(s_lexer *lexer) { - if (lexer->token.id == TOK_NONE) + if (lexer->previous.id == TOK_NONE && lexer->current.id == TOK_NONE) lexer_eattoken(lexer); - return lexer->token; + return (lexer->previous.id != TOK_NONE) ? lexer->previous : lexer->current; +} + +s_token lexer_lookahead2(s_lexer *lexer) +{ + if (lexer->current.id == TOK_NONE) + lexer_eattoken(lexer); + if (lexer->previous.id == TOK_NONE) { + token_move(&lexer->current, &lexer->previous); + lexer_eattoken(lexer); + } + return lexer->current; } s_token lexer_gettoken(s_lexer *lexer) { s_token buf; + s_token *victim; - if (lexer->token.id == TOK_NONE) + if (lexer->previous.id != TOK_NONE) + victim = &lexer->previous; + else + victim = &lexer->current; + if (lexer->current.id == TOK_NONE) lexer_eattoken(lexer); - buf = lexer->token; - lexer->token.id = TOK_NONE; - lexer->token.str = NULL; + token_move(victim, &buf); return buf; } @@ -240,6 +264,14 @@ static void token_set(s_token *token, e_tokenid id, char *s) else token->len = 0; } +static void token_move(s_token *src, s_token *dst) +{ + *dst = *src; + src->id = TOK_NONE; + src->str = NULL; + src->len = 0; +} + static void lexer_eattoken(s_lexer *lexer) { //if last char was read free buffer @@ -256,7 +288,7 @@ static void lexer_eattoken(s_lexer *lexer) //if eof is read, bye bye if (!lexer->buf) { lexer->eof = 1; - token_set(&lexer->token, TOK_EOF, "EOF"); + token_set(&lexer->current, TOK_EOF, "EOF"); return; } //cut a slice of stream @@ -270,8 +302,7 @@ static int lexer_eatline(s_lexer *lexer) assert(lexer->buf); buf = lexer->buf; - if (lexer->buf_size > 0 && buf[lexer->buf_size - 1] == '\n') - buf[lexer->buf_size - 1] = 0; + //remove \n if a \ is present before him if (lexer->buf_size > 1 && buf[lexer->buf_size - 2] == '\\') buf[lexer->buf_size - 2] = 0; //show incomplet recognition prompt @@ -279,13 +310,14 @@ static int lexer_eatline(s_lexer *lexer) //retrieve a new line if (!(buf2 = getline(lexer->stream))) { lexer->eof = 1; - return 0; + token_set(&lexer->current, TOK_EOF, "EOF"); + return 1; } lexer->buf = strmerge(2, buf, buf2); lexer->buf_size = strlen(lexer->buf); free(buf); free(buf2); - return 1; + return 0; } static int lexer_cut(s_lexer *lexer) @@ -295,25 +327,25 @@ static int lexer_cut(s_lexer *lexer) size_t *buf_pos = &lexer->buf_pos, token_start, token_pos; int end_found = 0; char backed = 0, quoted = 0; - const s_quote *quote; + const s_quote *quote = NULL; // Rationale: Search begin of token - //eat separators (" ",\t, \v) + // eat separators (" ",\t, \v) while (buf[*buf_pos] && is_sep(buf[*buf_pos])) ++*buf_pos; - //eat comment + // eat comment if (buf[*buf_pos] == '#') while (buf[*buf_pos] && buf[*buf_pos] != '\n') ++*buf_pos; - //check if first chars is an operator - if (is_operator(buf + *buf_pos, buf_pos, &lexer->token)) + // check if first chars is an operator + if (is_operator(buf + *buf_pos, buf_pos, &lexer->current)) return 1; token_start = token_pos = *buf_pos; // Rationale: Search end of token for (; buf[token_pos]; ++token_pos) { // backslah newline => eatline - if ((backed || quoted) && buf[token_pos] == '\n' && lexer_eatline(lexer)) - return 0; //new line added, you can try again + if ((backed || quoted) && buf[token_pos] == '\n' && buf[token_pos + 1] == '\0') + return lexer_eatline(lexer); // backed, go to next char else if (backed) backed = 0; // check end of quoting @@ -332,7 +364,7 @@ static int lexer_cut(s_lexer *lexer) } lexer->buf_pos = token_pos; //update real lexer position buffer tokstr = strndup(buf + token_start, token_pos - token_start); - token_set(&lexer->token, ((buf[token_pos] == '>' || buf[token_pos] == '<') + token_set(&lexer->current, ((buf[token_pos] == '>' || buf[token_pos] == '<') && isdigitstr(tokstr)) ? TOK_IONUMBER : TOK_WORD, tokstr); return 1; } @@ -364,6 +396,7 @@ static int is_quote_start(const char *buf, size_t *buf_pos, const s_quote **quot static int is_quote_stop(const char *buf, size_t *buf_pos, const s_quote *quote) { + assert(quote); if (!strncmp(buf + *buf_pos, quote->stop, quote->lenstop)) { *buf_pos += quote->lenstop - 1; return 1; diff --git a/src/parser/parser.c b/src/parser/parser.c index cb9d5f188d0b833e97a5b7f635ebef34a99b4f27..eaaa493285cc2f184eaddd36963703a2cdc3d823 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -5,9 +5,10 @@ ** Login ** ** Started on Wed Aug 2 00:56:07 2006 Seblu -** Last update Mon Oct 16 16:35:13 2006 seblu +** Last update Wed Oct 18 19:21:32 2006 seblu */ + #include #include #include @@ -26,10 +27,6 @@ ** ============ */ -enum { - FD_MAX = 32765 -}; - static s_ast_node *regnode(s_parser *parser, s_ast_node *node); /*! @@ -121,7 +118,8 @@ static const s_token keyword_table[] = {TOK_WORD, "case", 4}, {TOK_WORD, "esac", 4}, {TOK_WORD, "while", 5}, - {TOK_WORD, "until", 5} + {TOK_WORD, "until", 5}, + {TOK_WORD, "function", 8} }; s_parser *parser_init(int fd) @@ -152,13 +150,16 @@ static s_ast_node *regnode(s_parser *parser, s_ast_node *node) static void parse_error(s_parser *parser, s_token t) { - fprintf(stderr, "%s: syntax error near unexpected token `%s'\n", - shell->name, t.str); + if (t.id == TOK_EOF) + fprintf(stderr, "%s: syntax error: unexpected end of file\n", shell->name); + else + fprintf(stderr, "%s: syntax error near unexpected token `%s'\n", + shell->name, t.str); parser->error = 1; shell->status = ERROR_PARSE; -/* if (parser->regnodes) */ -/* for (register int i = 0; parser->regnodes[i]; ++i) */ -/* ast_destruct(parser->regnodes[i]); */ + if (parser->regnodes) + for (register int i = 0; parser->regnodes[i]; ++i) + ast_destruct_node(parser->regnodes[i]); lexer_flush(parser->lexer); longjmp(parser->stack, 1); } @@ -168,9 +169,10 @@ s_ast_node *parse(s_parser *parser) parser->regpos = 0; parser->error = 0; // prevent of too big register ast size - if (parser->regsize >= 200) + if (parser->regsize >= REGISTER_REDUCE_SIZE) secrealloc(parser->regnodes, parser->regnodes, - (parser->regsize = 50) * sizeof (s_ast_node)); + (parser->regsize = REGISTER_DEFAULT_SIZE) * sizeof (s_ast_node)); + //return from parse_error (return !0) if (setjmp(parser->stack)) return NULL; show_prompt(PROMPT_PS1); @@ -178,10 +180,10 @@ s_ast_node *parse(s_parser *parser) //test lexer mode for (;;) { s_token tok = lexer_gettoken(parser->lexer); - if (tok.id == TOK_EOF) - exit(69); printf("Returned token: %d [%s]\n", tok.id, (*tok.str == '\n') ? "\\n" : tok.str); + if (tok.id == TOK_EOF) + exit(69); if (tok.id == TOK_NEWLINE) show_prompt(PROMPT_PS1); } @@ -290,7 +292,6 @@ static s_ast_node *parse_pipeline_command(s_parser *parser) return lhs; } -//problem of choice between simple and funcdec static s_ast_node *parse_command(s_parser *parser) { s_token token; @@ -302,13 +303,15 @@ static s_ast_node *parse_command(s_parser *parser) !strcmp(token.str, "if") || !strcmp(token.str, "until") || !strcmp(token.str, "{") || !strcmp(token.str, "case")))) return parse_shellcommand(parser); - // probleme de choix avec function pour l'instant seulement si function! - else if (token.id == TOK_WORD && !strcmp(token.str, "function")) + else if ((token.id == TOK_WORD && !strcmp(token.str, "function")) || + (token.id == TOK_WORD && + lexer_lookahead2(parser->lexer).id == TOK_LPAREN)) return parse_funcdec(parser); else if (token.id >= TOK_DLESSDASH && token.id <= TOK_WORD) return parse_simplecommand(parser); else parse_error(parser, token); + assert(0); return NULL; } @@ -341,7 +344,7 @@ static int parse_element(s_parser *parser, { s_token token; int found = 0; - int first = 1; + int first = 1; debugmsg("parse_element"); for (;;) { @@ -350,10 +353,14 @@ static int parse_element(s_parser *parser, parse_redirection(parser, red); ++found; } - else if (token.id == TOK_WORD && (!first || !is_keyword(token))) { + else if (token.id == TOK_WORD && first && !is_keyword(token)) { + first = 0; + //TODO: gestion des alias ast_cmd_add_argv(cmd, lexer_gettoken(parser->lexer).str); ++found; } + else if (token.id == TOK_WORD && !first) + ast_cmd_add_argv(cmd, lexer_gettoken(parser->lexer).str); else break; } return found; @@ -420,7 +427,6 @@ static s_ast_node *parse_shellcommand(s_parser *parser) return NULL; } -//IN PROGRESS static s_ast_node *parse_funcdec(s_parser *parser) { s_token tok; @@ -437,11 +443,9 @@ static s_ast_node *parse_funcdec(s_parser *parser) if (tok.id != TOK_WORD) parse_error(parser, tok); funcname = tok.str; - if ((tok = lexer_gettoken(parser->lexer)).id != TOK_WORD && - !strcmp(tok.str, "(")) + if (lexer_gettoken(parser->lexer).id != TOK_LPAREN) parse_error(parser, tok); - if ((tok = lexer_gettoken(parser->lexer)).id != TOK_WORD && - !strcmp(tok.str, ")")) + if (lexer_gettoken(parser->lexer).id != TOK_RPAREN) parse_error(parser, tok); eat_newline(); body = parse_shellcommand(parser); @@ -487,6 +491,7 @@ static void parse_redirection(s_parser *parser, s_ast_node **reds) case TOK_GREATAND: redtype = R_GREATAND; if (fd == -1) fd = 1; break; default: parse_error(parser, token); + redtype = 0; //to avoid warning about redtype may be unitialized } //retrieve redirection word token = lexer_gettoken(parser->lexer); @@ -510,6 +515,8 @@ static s_ast_node *parse_compound_list(s_parser *parser) tok = lexer_lookahead(parser->lexer); if (tok.id == TOK_SEP || tok.id == TOK_SEPAND || tok.id == TOK_NEWLINE) { lexer_gettoken(parser->lexer); + if (tok.id == TOK_NEWLINE) + show_prompt(PROMPT_PS2); eat_newline(); //check for and_or tok2 = lexer_lookahead(parser->lexer); @@ -572,7 +579,7 @@ static s_ast_node *parse_rulefor(s_parser *parser) while ((tok = lexer_lookahead(parser->lexer)).id == TOK_WORD); //check for ';' or '\n' if ((tok = lexer_gettoken(parser->lexer)).id != TOK_SEP && - tok.id != TOK_NEWLINE) + tok.id != TOK_NEWLINE) parse_error(parser, tok); //eat newline eat_newline(); @@ -726,8 +733,9 @@ static s_ast_node *parse_rulecase(s_parser *parser) free(tok.str); //eat newline eat_newline(); + //parse case body tok = lexer_lookahead(parser->lexer); - if ((tok.id == TOK_WORD && !strcmp(tok.str, "esac")) || + if ((tok.id == TOK_WORD && strcmp(tok.str, "esac")) || tok.id == TOK_LPAREN) { casenode = regnode(parser, ast_case_create(varname)); parse_caseclause(parser, casenode); @@ -744,13 +752,19 @@ static void parse_caseclause(s_parser *parser, s_ast_node *casenode) { s_token tok; - parse_caseitem(parser, casenode); - //check for token 'case' - tok = lexer_lookahead(parser->lexer); - if (tok.id != TOK_DSEMI) - return; - lexer_gettoken(parser->lexer); - tok = lexer_gettoken(parser->lexer); + debugmsg("parse_caseclause"); + do { + parse_caseitem(parser, casenode); + tok = lexer_lookahead(parser->lexer); + if (tok.id == TOK_DSEMI) { + lexer_gettoken(parser->lexer); + eat_newline(); + tok = lexer_lookahead(parser->lexer); + } + if (tok.id == TOK_WORD && !strcmp(tok.str, "esac")) + return; + } + while (1); } static void parse_caseitem(s_parser *parser, s_ast_node *casenode) @@ -759,6 +773,7 @@ static void parse_caseitem(s_parser *parser, s_ast_node *casenode) char **pattern = NULL; s_ast_node *exec = NULL; + debugmsg("parse_caseitem"); tok = lexer_gettoken(parser->lexer); //check for a '(' before pattern list if (tok.id == TOK_LPAREN) @@ -773,6 +788,9 @@ static void parse_caseitem(s_parser *parser, s_ast_node *casenode) parse_error(parser, tok); pattern = strvectoradd(pattern, tok.str); } + //check for ')' + if ((tok = lexer_gettoken(parser->lexer)).id != TOK_RPAREN) + parse_error(parser, tok); //eat newline eat_newline(); if ((tok = lexer_lookahead(parser->lexer)).id != TOK_DSEMI && diff --git a/src/parser/parser.h b/src/parser/parser.h index 41e2f3a1579ea0544f91130c21afc4b3040a988c..d0d747767b013af85ed4170b8825f5165b72dec8 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Wed Aug 2 00:49:50 2006 Seblu -** Last update Mon Oct 16 15:33:04 2006 seblu +** Last update Wed Oct 18 18:28:06 2006 seblu */ #ifndef PARSER_H_ @@ -20,8 +20,11 @@ # define DEBUG_LEXER 0 enum { - TOKEN_COUNT = 22, + TOKEN_COUNT = 23, KEYWORD_COUNT = 15, + FD_MAX = 32765, + REGISTER_REDUCE_SIZE = 200, + REGISTER_DEFAULT_SIZE = 50, }; typedef enum tokenid @@ -59,7 +62,8 @@ typedef struct token typedef struct lexer { - s_token token; + s_token current; //working token + s_token previous; FILE *fs; char eof; char *buf; @@ -121,6 +125,7 @@ s_lexer *lexer_init(int fd); ** Flush current information of position in the line, ** size of the line, and free line buffer. This is call ** by the parser after an error. +** Flush don't reset eof flag ! ** ** @param lexer lexer to flush */ @@ -146,6 +151,17 @@ s_token lexer_gettoken(s_lexer *lexer); */ s_token lexer_lookahead(s_lexer *lexer); +/*! +** Return the next next token without destruction of it. +** @warning The token string MUST NOT be freed ! +** This is a possibility will come from LL1 lexer. +** +** @param lexer lexer structure +** +** @return the look ahead token +*/ +s_token lexer_lookahead2(s_lexer *lexer); + /*! ** Parse input as a here-document (describe is XSI) ** diff --git a/src/shell/prompt.c b/src/shell/prompt.c index ce1926b7f3f38c02e2c4626e68f155c58804b749..34dec8b00f7eddcb197076dca38d90b9fb626c7b 100644 --- a/src/shell/prompt.c +++ b/src/shell/prompt.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 30 02:27:59 2006 Seblu -** Last update Tue Aug 29 00:47:41 2006 Seblu +** Last update Wed Oct 18 21:08:51 2006 seblu */ #include @@ -38,22 +38,20 @@ const char *get_prompt(e_prompt pty) //todo gestion des variables ! void show_prompt(e_prompt pty) { - char *prompt; - if (!isinteractive()) return; + fflush(stderr); switch (pty) { + default: case PROMPT_PS1: - prompt = "42sh "; + fprintf(stderr, "%s$ ", shell->name); break; case PROMPT_PS2: - prompt = "> "; + fprintf(stderr, "> "); break; case PROMPT_PS4: - prompt = "+"; + fprintf(stderr, "+ "); break; } fflush(stderr); - fprintf(stderr, "%s", prompt); - fflush(stderr); } diff --git a/src/shell/shell.h b/src/shell/shell.h index 9d1f4adf63120196d1a8e102f1436ae3e9c48838..079c00a45b2ff9c73248a0cc820b89b3d6b7706b 100644 --- a/src/shell/shell.h +++ b/src/shell/shell.h @@ -5,7 +5,7 @@ ** Login ** ** Started on Sun Jul 16 20:03:53 2006 Seblu -** Last update Tue Aug 29 00:51:36 2006 Seblu +** Last update Tue Oct 17 09:38:57 2006 seblu */ #ifndef SHELL_H_ diff --git a/test/parse/bad/compoundlist_1.sh b/test/parse/bad/compoundlist_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..7e217f94f45e246953c48a9f1a852c3eace0c540 --- /dev/null +++ b/test/parse/bad/compoundlist_1.sh @@ -0,0 +1 @@ +{ toto; do; } diff --git a/test/parse/bad/eof.sh b/test/parse/bad/eof.sh new file mode 100644 index 0000000000000000000000000000000000000000..a327fb31306e632182bb7c1e60faa6865e197b35 --- /dev/null +++ b/test/parse/bad/eof.sh @@ -0,0 +1,3 @@ +echo "toto +titi +tata diff --git a/test/parse/bad/freetext.sh b/test/parse/bad/freetext.sh new file mode 100644 index 0000000000000000000000000000000000000000..5e2eef5386e8c743acb0263265310cfec2abc615 --- /dev/null +++ b/test/parse/bad/freetext.sh @@ -0,0 +1,7 @@ + +coucou +c'est moi +EOF +je suis grand +OF + diff --git a/test/parse/bad/if_1.sh b/test/parse/bad/if_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..9641b4316ded2eebfbc1901e36749c25b3e276c6 --- /dev/null +++ b/test/parse/bad/if_1.sh @@ -0,0 +1,11 @@ +if { true; false; true & false; true && false; false; } then + false +elif { true; false; true & false; true && false; false; } then + true; +else + if { true; false; true & false; true && false; false; } then + true; + fi +elif { true; false; true & false; true && false; false; } then + true; +fi diff --git a/test/parse/bad/reserved_1.sh b/test/parse/bad/reserved_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..2627403b1c58fe6f2807f84a5a59956a0189b0ff --- /dev/null +++ b/test/parse/bad/reserved_1.sh @@ -0,0 +1 @@ +true; fi diff --git a/test/parse/bad/reserved_2.sh b/test/parse/bad/reserved_2.sh new file mode 100644 index 0000000000000000000000000000000000000000..8e75d0f527b4bad12137c2e2da6b50800d6d731e --- /dev/null +++ b/test/parse/bad/reserved_2.sh @@ -0,0 +1 @@ +{ function toto; } diff --git a/test/parse/good/big_1.sh b/test/parse/good/big_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..0ae86dcaa054a3e82e7972cc408ba16d6be29872 --- /dev/null +++ b/test/parse/good/big_1.sh @@ -0,0 +1,63 @@ +toto=bite tata=chate >chiche 2pipi 4>popo >>pupu +{ toto; ! titi; toto && titi; } +{ true; ! false; { false; }; } +function toto() +{ + echo "je m'appel toto" +} +cat << EOF; echo toto; cat << OF + +coucou +c'est moi +EOF +je suis grand +OF + + +if true; then + false +elif false; then + false; +else + true; +fi + +if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + false; + fi + fi + fi + fi + fi + fi + fi + fi +else + true; +fi + +if { true toto; false; true & false; true && false; false; } then + false +elif { true; false; true & false; true && false; false; } then + true; +else + if { true; false; true & false; true && false; false; } then + true; + fi +fi +if [[ -f /etc/DIR_COLORS ]] ; then + match_lhs=$(/dev/null ; then + match_lhs=$(dircolors --print-database) +else + match_lhs="" +fi#!/bin/sh +for i in toto tata titi; do echo $i; done diff --git a/test/parse/good/big_command.sh b/test/parse/good/big_command.sh new file mode 100644 index 0000000000000000000000000000000000000000..7feb8b2c0e70db63bbd05405f7eefc4f0d4bffdf --- /dev/null +++ b/test/parse/good/big_command.sh @@ -0,0 +1 @@ +toto=bite tata=chate >chiche 2pipi 4>popo >>pupu diff --git a/test/parse/good/brace_1.sh b/test/parse/good/brace_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..9008709e9d3cbcac1da1a8ec74ee46953e6272f9 --- /dev/null +++ b/test/parse/good/brace_1.sh @@ -0,0 +1 @@ +{ toto; ! titi; toto && titi; } diff --git a/test/parse/good/brace_2.sh b/test/parse/good/brace_2.sh new file mode 100644 index 0000000000000000000000000000000000000000..62cd067c8820735ec2312af5752540d2937cbce9 --- /dev/null +++ b/test/parse/good/brace_2.sh @@ -0,0 +1 @@ +{ true; ! false; { false; }; } diff --git a/test/parse/good/case_1.sh b/test/parse/good/case_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..c5a509b55ca33cc8b9f0188cbb47841027705ab8 --- /dev/null +++ b/test/parse/good/case_1.sh @@ -0,0 +1,14 @@ +case toto in + tata) + cmd >> toto | sex |bite + ;; + titi) + cmd2 &>/sex `ls -la < /sex` + ;; + toto) + cmd4 >/sex + ;; +esac diff --git a/test/parse/good/empty.sh b/test/parse/good/empty.sh new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/test/parse/good/funcdec.sh b/test/parse/good/funcdec.sh new file mode 100644 index 0000000000000000000000000000000000000000..789d975b5724f51e7fa2c0df0d037f5199fb3314 --- /dev/null +++ b/test/parse/good/funcdec.sh @@ -0,0 +1,4 @@ +function toto() +{ + echo "je m'appel toto" +} diff --git a/test/parse/good/heredocs.sh b/test/parse/good/heredocs.sh new file mode 100644 index 0000000000000000000000000000000000000000..ea904253d09f05f8ef46f8982b7f7698d9bcd1be --- /dev/null +++ b/test/parse/good/heredocs.sh @@ -0,0 +1,8 @@ +cat << EOF; echo toto; cat << OF + +coucou +c'est moi +EOF +je suis grand +OF + diff --git a/test/parse/good/if_1.sh b/test/parse/good/if_1.sh new file mode 100644 index 0000000000000000000000000000000000000000..fcddb7f9ee275c53e87c237cfae79c16db248157 --- /dev/null +++ b/test/parse/good/if_1.sh @@ -0,0 +1,7 @@ +if true; then + false +elif false; then + false; +else + true; +fi diff --git a/test/parse/good/if_2.sh b/test/parse/good/if_2.sh new file mode 100644 index 0000000000000000000000000000000000000000..76d5a0f6925b0b6756b2b87c6be18867db00eb0e --- /dev/null +++ b/test/parse/good/if_2.sh @@ -0,0 +1,21 @@ +if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + if true; then + false; + fi + fi + fi + fi + fi + fi + fi + fi +else + true; +fi diff --git a/test/parse/good/if_3.sh b/test/parse/good/if_3.sh new file mode 100644 index 0000000000000000000000000000000000000000..cb723904bf9226eb9c44ce7bfe892b02d52313fc --- /dev/null +++ b/test/parse/good/if_3.sh @@ -0,0 +1,9 @@ +if { true toto; false; true & false; true && false; false; } then + false +elif { true; false; true & false; true && false; false; } then + true; +else + if { true; false; true & false; true && false; false; } then + true; + fi +fi diff --git a/test/parse/good/if_4.sh b/test/parse/good/if_4.sh new file mode 100644 index 0000000000000000000000000000000000000000..791e19721c523ccfd59c50f3473d016fdb039fd0 --- /dev/null +++ b/test/parse/good/if_4.sh @@ -0,0 +1,7 @@ +if [[ -f /etc/DIR_COLORS ]] ; then + match_lhs=$(/dev/null ; then + match_lhs=$(dircolors --print-database) +else + match_lhs="" +fi \ No newline at end of file diff --git a/test/parse/good/sheebang.sh b/test/parse/good/sheebang.sh new file mode 100644 index 0000000000000000000000000000000000000000..66d622896ccd8bf498fc910c005393d87cc2e9b4 --- /dev/null +++ b/test/parse/good/sheebang.sh @@ -0,0 +1 @@ +#!/bin/42sh diff --git a/test/parse/good/simple_for.sh b/test/parse/good/simple_for.sh new file mode 100644 index 0000000000000000000000000000000000000000..69177932884214becde2c6ac79ffc30f757d403c --- /dev/null +++ b/test/parse/good/simple_for.sh @@ -0,0 +1 @@ +for i in toto tata titi; do echo $i; done diff --git a/test/parse/moulette.sh b/test/parse/moulette.sh new file mode 100755 index 0000000000000000000000000000000000000000..a45db755b3f25b933338d9cb199ac929b7005d77 --- /dev/null +++ b/test/parse/moulette.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +my42sh="../../src/42sh" + +# check good syntax +for file in good/*; do + $my42sh < "$file" &>/dev/null + echo ">>>>>>Return: $?" +done + +# check bad syntax +for file in bad/*; do + $my42sh < "$file" &>/dev/null + echo ">>>>>>Return: $?" +done diff --git a/tools/last-ast.sh b/tools/last-ast.sh index 849b433aad0c056bd5e5fe225e20427ddf8d4ff6..94d01ec5a7ec05b1556b895825746c531af5ea63 100755 --- a/tools/last-ast.sh +++ b/tools/last-ast.sh @@ -32,4 +32,4 @@ ln -sf ${last%*.dot}.png ast.png echo "${lyellow}Showing ${lblue}${last%*.dot}.png${lyellow}...$norm" xview=`which xview` test -x "$xview" || { echo "${lred}xview not found !$norm"; exit 2; } -"$xview" ast.png +"$xview" ast.png &