From b13062fec92f2ff581e0bedd1c9a6f0252e7c2ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Thu, 31 Aug 2006 23:02:22 +0000 Subject: [PATCH] suppression fichier shell_getopt.c (inutile) ajout d'un script qui creer un fichier ast.png a partir du dernier dot ast generer debut des ast printer parser de commande --- GRAMMAR | 14 +++--- src/Makefile.am | 3 +- src/ast/ast.h | 67 +++++++++++++++++++------ src/ast/ast_cmd.c | 86 +++++++++++++++++++++++++++++--- src/ast/ast_print.c | 95 ++++++++++++++++++++++++++++++++++++ src/ast/ast_sep.c | 2 +- src/last-ast.sh | 9 ++++ src/parser/lexer.c | 8 +-- src/parser/parser.c | 105 +++++++++++++++++++++++++++++----------- src/parser/parser.h | 4 +- src/shell/getoptions.c | 29 ++++++----- src/shell/option.c | 3 +- src/shell/option.h | 4 +- src/shell/shell_entry.c | 5 +- 14 files changed, 349 insertions(+), 85 deletions(-) create mode 100644 src/ast/ast_print.c create mode 100755 src/last-ast.sh diff --git a/GRAMMAR b/GRAMMAR index 8239d77..bf2d879 100644 --- a/GRAMMAR +++ b/GRAMMAR @@ -1,5 +1,5 @@ -input: list '\n' - list EOF +input: list '\n' + list EOF | '\n' | EOF @@ -13,9 +13,9 @@ command: simple_command | shell_command (redirection)* | funcdec -simple_command: (prefix)* (element)+ +simple_command: (prefix)* (element)+ -shell_command: '{' compound_list '}' +shell_command: '{' compound_list '}' | '(' compound_list ')' | rule_for | rule_while @@ -25,7 +25,7 @@ shell_command: '{' compound_list '}' funcdec: ['function'] WORD '(' ')' ('\n')* shell_command (redirection)* -redirection: [NUMBER] '>' WORD +redirection: [NUMBER] '>' WORD | [NUMBER] '<' WORD | [NUMBER] '>>' WORD | [NUMBER] '<<' HEREDOC @@ -51,9 +51,9 @@ rule_until: 'until' compound_list do_group rule_case: 'case' WORD ('\n')* 'in' ('\n')* [case_clause] 'esac' -rule_if: 'if' compound_list 'then' compound_list [else_clause] 'fi' +rule_if: 'if' compound_list 'then' compound_list [else_clause] 'fi' -else_clause: 'else' compound_list +else_clause: 'else' compound_list | 'elif' compound_list 'then' compound_list [else_clause] do_group: 'do' compound_list 'done' diff --git a/src/Makefile.am b/src/Makefile.am index 31b0f50..287060c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,11 +15,13 @@ bin_PROGRAMS=42sh ast/ast_if.c \ ast/ast_or.c \ ast/ast_pipe.c \ + ast/ast_print.c \ ast/ast_sep.c \ ast/ast_sepand.c \ ast/ast_subshell.c \ ast/ast_until.c \ ast/ast_while.c \ + common/basename.c \ common/common.h \ common/constant.h \ common/isdigitstr.c \ @@ -27,7 +29,6 @@ bin_PROGRAMS=42sh common/strmerge.c \ common/strvmerge.c \ common/strndup.c \ - common/basename.c \ exec/exec.h \ exec/exec_node.c \ parser/alias.h \ diff --git a/src/ast/ast.h b/src/ast/ast.h index 961e895..291d33e 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -5,12 +5,13 @@ ** Login ** ** Started on Sun Jul 30 04:40:03 2006 Seblu -** Last update Tue Aug 29 00:35:06 2006 Seblu +** Last update Fri Sep 1 00:30:34 2006 Seblu */ #ifndef AST_H_ # define AST_H_ +# include # include "../common/macro.h" typedef struct ast_node s_ast_node; @@ -18,7 +19,7 @@ typedef struct ast_node s_ast_node; /* ** If ast node */ -typedef struct if_node +typedef struct if_node { s_ast_node *cond; s_ast_node *cond_true; @@ -28,7 +29,7 @@ typedef struct if_node /* ** For ast node */ -typedef struct for_node +typedef struct for_node { char *varname; char **values; @@ -39,7 +40,7 @@ typedef struct for_node ** Case item (not an ast node) */ typedef struct case_item s_case_item; -struct case_item +struct case_item { char **pattern; s_ast_node *exec; @@ -49,7 +50,7 @@ struct case_item /* ** Case ast node */ -typedef struct case_node +typedef struct case_node { char *word; s_case_item *items; @@ -58,7 +59,7 @@ typedef struct case_node /* ** While ast node */ -typedef struct while_node +typedef struct while_node { s_ast_node *cond; s_ast_node *exec; @@ -67,7 +68,7 @@ typedef struct while_node /* ** Enumerate different type of redirection */ -typedef enum redir_type +typedef enum redir_type { R_LESS, /* < */ R_LESSAND, /* <& */ @@ -83,8 +84,8 @@ typedef enum redir_type /* ** Redirection ast node */ -typedef struct redir s_redir; -struct redir +typedef struct redir s_redir; +struct redir { e_redir_type type; int fd; @@ -95,7 +96,7 @@ struct redir /* ** Command ast node */ -typedef struct cmd_node +typedef struct cmd_node { char **argv; s_redir *redirs; @@ -108,7 +109,7 @@ typedef struct cmd_node ** T_PIPE, T_SEP* , T_AND, T_OR : binary operator ** T_BANG : unary operator but ts_bin_op with right pointer is always NULL */ -typedef struct bin_node +typedef struct bin_node { s_ast_node *lhs; s_ast_node *rhs; @@ -117,7 +118,7 @@ typedef struct bin_node /* ** Funcdec node */ -typedef struct funcdec_node +typedef struct funcdec_node { char *name; s_ast_node *body; @@ -126,7 +127,7 @@ typedef struct funcdec_node /* ** Enumerate all node type */ -typedef enum node_type +typedef enum node_type { T_IF, T_FOR, @@ -147,7 +148,7 @@ typedef enum node_type /* ** This is a type for a node item */ -typedef union node_item +typedef union node_item { s_if_node child_if; s_for_node child_for; @@ -168,12 +169,29 @@ typedef union node_item /* ** Generic ast node type */ -struct ast_node +struct ast_node { e_node_type type; u_node_item body; }; +/*! +** Print an ast to @arg filename file +** +** @param ast ast to print +** @param filename filename where ast is printed. if it's NULL +** random file name is generated. +*/ +void ast_print(s_ast_node *ast, const char *filename); + +/*! +** Print an ast node +** +** @param ast ast node to add to file +** @param fs file stream where print ast +*/ +void ast_print_node(s_ast_node *ast, FILE *fs, unsigned int *node_id); + /*! ** Destroy node and all its childs ** @@ -305,6 +323,25 @@ void ast_cmd_add_redir(s_ast_node *node, int fd, char *word); +/*! +** Add a arg vector to a cmd node +** +** @param node node where add +** @param argv new arg vector +*/ +void ast_cmd_add_argv(s_ast_node *node, char *argv); + +/*! +** Add a prefix to a cmd node +** +** @param node node for addition +** @param assignment_word word to add +*/ +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 ** diff --git a/src/ast/ast_cmd.c b/src/ast/ast_cmd.c index 024ae4a..a12bfc0 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 Mon Aug 28 23:56:46 2006 Seblu +** Last update Fri Sep 1 00:44:22 2006 Seblu */ #include "ast.h" @@ -42,18 +42,90 @@ void ast_cmd_add_redir(s_ast_node *node, *this = red; } +void ast_cmd_add_prefix(s_ast_node *node, char *assignment_word) +{ + if (node->type != T_CMD) + return; + size_t size = 0; + if (node->body.child_cmd.prefix) + while (node->body.child_cmd.prefix[size]) + ++size; + secrealloc(node->body.child_cmd.prefix, node->body.child_cmd.prefix, + (++size + 1) * sizeof (char *)); + node->body.child_cmd.prefix[size - 1] = assignment_word; + node->body.child_cmd.prefix[size] = NULL; +} + +void ast_cmd_add_argv(s_ast_node *node, char *argv) +{ + if (node->type != T_CMD) + return; + size_t size = 0; + if (node->body.child_cmd.argv) + while (node->body.child_cmd.argv[size]) + ++size; + secrealloc(node->body.child_cmd.argv, node->body.child_cmd.argv, + (++size + 1) * sizeof (char *)); + node->body.child_cmd.argv[size - 1] = argv; + node->body.child_cmd.argv[size] = NULL; +} + +void ast_cmd_print(s_ast_node *node, FILE *fs, unsigned int *node_id) +{ + unsigned cur_id = *node_id; + + if (node->type != T_CMD) + return; + fprintf(fs, "%u [label = \"Command\"];\n", *node_id); + //prefix + char **prefix = node->body.child_cmd.prefix; + if (prefix && prefix[0]) { + ++*node_id; + fprintf(fs, "%u [label = \"", *node_id); + for (int i = 0; prefix && prefix[i]; ++i) { + fprintf(fs, "prefix[%d]=%s\\n", i, prefix[i]); + } + fprintf(fs, "\"];\n"); + fprintf(fs, "%u -> %u\n", cur_id, *node_id); + } + //arguments + char **argv = node->body.child_cmd.argv; + if (argv && argv[0]) { + ++*node_id; + fprintf(fs, "%u [label = \"", *node_id); + for (int i = 0; argv && argv[i]; ++i) + fprintf(fs, "argv[%d]=%s\\n", i, argv[i]); + fprintf(fs, "\"];\n"); + fprintf(fs, "%u -> %u\n", cur_id, *node_id); + } + //redirs + if (node->body.child_cmd.redirs) { + int i = 0; + ++*node_id; + fprintf(fs, "%u [label = \"", *node_id); + for (s_redir *this = node->body.child_cmd.redirs; this; this = this->next, ++i) + fprintf(fs, "redirs[%d]: fd=%d, type=%d, word=%s\\n", i, this->fd, this->type, this->word); + fprintf(fs, "\"];\n"); + fprintf(fs, "%u -> %u\n", cur_id, *node_id); + } +} + void ast_cmd_destruct(s_ast_node *node) { s_redir *this, *buf; if (node->type != T_CMD) return; - for (register int i = 0; node->body.child_cmd.argv[i]; ++i) - free(node->body.child_cmd.argv[i]); - for (register int i = 0; node->body.child_cmd.prefix[i]; ++i) - free(node->body.child_cmd.prefix[i]); - free(node->body.child_cmd.argv); - free(node->body.child_cmd.prefix); + if (node->body.child_cmd.argv) { + for (register int i = 0; node->body.child_cmd.argv[i]; ++i) + free(node->body.child_cmd.argv[i]); + free(node->body.child_cmd.argv); + } + if (node->body.child_cmd.prefix) { + for (register int i = 0; node->body.child_cmd.prefix[i]; ++i) + free(node->body.child_cmd.prefix[i]); + free(node->body.child_cmd.prefix); + } for (this = node->body.child_cmd.redirs; this; this = buf) { free(this->word); buf = this->next; diff --git a/src/ast/ast_print.c b/src/ast/ast_print.c new file mode 100644 index 0000000..01a2819 --- /dev/null +++ b/src/ast/ast_print.c @@ -0,0 +1,95 @@ +/* +** ast_print.c for 42sh +** +** Made by Seblu +** Login +** +** Started on Sat Mar 25 23:11:01 2006 Seblu +** Last update Fri Sep 1 00:31:28 2006 Seblu +*/ + +#include +#include +#include +#include +#include +#include +#include +#include "ast.h" + +#define NODE_TYPE_COUNT 14 + +typedef void (*print_fct)(s_ast_node *, FILE *, unsigned int *); + +struct ast_print_switch +{ + e_node_type type; + print_fct fct; +}; + +struct ast_print_switch print_table[NODE_TYPE_COUNT] = + { + {T_IF, NULL}, // ast_if_print}, + {T_FOR, NULL}, //ast_for_print}, + {T_WHILE, NULL}, //ast_while_print}, + {T_UNTIL, NULL}, //ast_until_print}, + {T_CMD, ast_cmd_print}, + {T_AND, NULL}, //ast_and_print}, + {T_OR, NULL}, //ast_or_print}, + {T_SUBSHELL, NULL}, //ast_subshell_print}, + {T_FUNCDEC, NULL}, //ast_funcdec_print}, + {T_BANG, NULL}, //ast_bang_print}, + {T_PIPE, NULL}, //ast_pipe_print}, + {T_SEPAND, NULL}, //ast_sepand_print}, + {T_SEP, NULL}, //ast_sep_print}, + {T_CASE, NULL} //ast_sepand_print} + }; + +static char *newastfilename(void); + +void ast_print(s_ast_node *ast, const char *filename) +{ + FILE *fs; + unsigned int index; + + if (ast == NULL) + return; + //open file stream + if (!filename) + filename = newastfilename(); + if (!(fs = fopen(filename, "w"))) + return; + //write dot header + fprintf(fs, "digraph \"42sh-ast\" {\n"); + fprintf(fs, "node [fontname=Vera, color=lightblue2, style=filled];\n"); + //start ast node wrinting + ast_print_node(ast, fs, &index); + //write dot foot and close + fprintf(fs, "}"); + fclose(fs); +} + +void ast_print_node(s_ast_node *ast, FILE *fs, unsigned int *node_id) +{ + for (register int i = 0; i < NODE_TYPE_COUNT; ++i) + if (print_table[i].type == ast->type) + (print_table[i].fct)(ast, fs, node_id); +} + +static char *newastfilename(void) +{ + + static char buf[PATH_MAX]; + time_t st; + struct tm *t; + struct stat buf2; + int more = 0; + + st = time(NULL); + t = localtime(&st); + do + snprintf(buf, 256, "/tmp/42sh-ast-%d-%d-%d-%d-%d-%d--%d.dot", 1900 + t->tm_year, + 1 + t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, more++); + while (stat(buf, &buf2) != -1 && more < 50); + return buf; +} diff --git a/src/ast/ast_sep.c b/src/ast/ast_sep.c index 3a28f60..b9d92ad 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 Tue Aug 29 00:00:40 2006 Seblu +** Last update Wed Aug 30 00:36:03 2006 Seblu */ #include "ast.h" diff --git a/src/last-ast.sh b/src/last-ast.sh new file mode 100755 index 0000000..96bd109 --- /dev/null +++ b/src/last-ast.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +for i in /tmp/42sh-ast-*.dot; do + last="$i" +done + +echo "$last to echo x${last%*.dot}" +dot -Tpng $last -o ${last%*.dot}.png +ln -sf ${last%*.dot}.png ast.png diff --git a/src/parser/lexer.c b/src/parser/lexer.c index de30c6c..b18608f 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 Tue Aug 29 02:33:06 2006 Seblu +** Last update Tue Aug 29 21:54:23 2006 Seblu */ #include @@ -154,7 +154,7 @@ static int lexer_cut(s_lexer *lexer); ** @param id new token id ** @param s new token string */ -static void token_set(s_token *token, e_tokenid id, const char *s); +static void token_set(s_token *token, e_tokenid id, char *s); /* @@ -221,10 +221,10 @@ s_token lexer_getheredoc(s_lexer *lexer, const char *delim) return token; } -static void token_set(s_token *token, e_tokenid id, const char *s) +static void token_set(s_token *token, e_tokenid id, char *s) { if (token->id == TOK_WORD) - free((char*) token->str); + free(token->str); token->id = id; token->str = s; if (s) token->len = strlen(s); diff --git a/src/parser/parser.c b/src/parser/parser.c index 9ec6aa3..dcca960 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Wed Aug 2 00:56:07 2006 Seblu -** Last update Tue Aug 29 02:28:28 2006 Seblu +** Last update Fri Sep 1 01:00:42 2006 Seblu */ #include @@ -24,26 +24,26 @@ */ -/* static ts_token keywords[] = */ -/* { */ -/* {TOK_IF, "if"}, */ -/* {TOK_THEN, "then"}, */ -/* {TOK_ELSE, "else"}, */ -/* {TOK_FI, "fi"}, */ -/* {TOK_ELIF, "elif"}, */ -/* {TOK_DO, "do"}, */ -/* {TOK_DONE, "done"}, */ -/* {TOK_CASE, "case"}, */ -/* {TOK_ESAC, "esac"}, */ -/* {TOK_WHILE, "while"}, */ -/* {TOK_UNTIL, "until"}, */ -/* {TOK_FOR, "for"}, */ -/* {TOK_IN, "in"}, */ -/* {TOK_LBRACE, "{"}, */ -/* {TOK_RBRACE, "}"}, */ -/* {TOK_BANG, "!"}, */ -/* {TOK_NONE, NULL} */ -/* }; */ +static s_token keywords[] = + { + {TOK_IF, "if", 2}, + {TOK_THEN, "then", 4}, + {TOK_ELSE, "else", 4}, + {TOK_FI, "fi", 2}, + {TOK_ELIF, "elif", 4}, + {TOK_DO, "do", 2}, + {TOK_DONE, "done", 4}, + {TOK_CASE, "case", 4}, + {TOK_ESAC, "esac", 4}, + {TOK_WHILE, "while", 5}, + {TOK_UNTIL, "until", 5}, + {TOK_FOR, "for", 3}, + {TOK_IN, "in", 2}, + {TOK_LBRACE, "{", 1}, + {TOK_RBRACE, "}", 1}, + {TOK_BANG, "!", 1}, + {TOK_NONE, NULL, 0} + }; static s_ast_node *regnode(s_parser *parser, s_ast_node *node); @@ -69,6 +69,8 @@ static s_ast_node *parse_pipeline(s_parser *parser); static s_ast_node *parse_command(s_parser *parser); +static s_ast_node *parse_simplecommand(s_parser *parser); + /*! ** Notify a parse error ** @@ -128,6 +130,31 @@ static void parse_error(s_parser *parser, s_token t) longjmp(parser->stack, 1); } +/* static int is_keyword(s_token t) */ +/* { */ +/* for (int i = 0; keywords[i].id != TOK_NONE; ++i) */ +/* if (!strncmp(t.str, keywords[i].str, keywords[i].len)) { */ +/* t.id = keywords[i].id; */ +/* return 1; */ +/* } */ +/* return 0; */ +/* } */ + +static int is_assignment(s_token t) +{ + return strchr(t.str, '=') == NULL ? 0 : 1; +} + +static void recon(s_token t) +{ + //check for keywords + for (int i = 0; keywords[i].id != TOK_NONE; ++i) + if (!strncmp(t.str, keywords[i].str, keywords[i].len)) { + t.id = keywords[i].id; + } + //check +} + s_ast_node *parse(s_parser *parser) { parser->regpos = 0; @@ -170,7 +197,7 @@ static s_ast_node *parse_input(s_parser *parser) } buf = parse_list(parser); token = lexer_gettoken(parser->lexer); - if (token.id != TOK_EOF || token.id != TOK_NEWLINE) + if (token.id != TOK_EOF && token.id != TOK_NEWLINE) parse_error(parser, token); return buf; } @@ -235,17 +262,37 @@ static s_ast_node *parse_command(s_parser *parser) { s_token token; - + debugmsg("parse_command"); token = lexer_lookahead(parser->lexer); - //if (token.id == TOK_WORD) + recon(token); + if (token.id == TOK_WORD) { + return parse_simplecommand(parser); + } return NULL; } -/* static s_ast_node *parse_simplecommand(s_parser *parser) */ -/* { */ -/* parser=parser; */ -/* return NULL; */ -/* } */ +static s_ast_node *parse_simplecommand(s_parser *parser) +{ + s_token token; + s_ast_node *cmd; + + debugmsg("parse_simplecommand"); + cmd = regnode(parser, ast_cmd_create()); + //get prefix + while (is_assignment(lexer_lookahead(parser->lexer))) + ast_cmd_add_prefix(cmd, lexer_gettoken(parser->lexer).str); + //get element + if ((token = lexer_gettoken(parser->lexer)).id == TOK_WORD) + ast_cmd_add_argv(cmd, token.str); + else + parse_error(parser, token); + while (recon(token = lexer_lookahead(parser->lexer)), + token.id == TOK_WORD) { + ast_cmd_add_argv(cmd, token.str); + lexer_gettoken(parser->lexer); + } + return cmd; +} /* static s_ast_node *parse_shellcommand(s_parser *parser) */ /* { */ diff --git a/src/parser/parser.h b/src/parser/parser.h index 9d74fcb..e20f5e5 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 Tue Aug 29 02:28:08 2006 Seblu +** Last update Fri Sep 1 00:21:07 2006 Seblu */ #include @@ -66,7 +66,7 @@ typedef enum tokenid typedef struct token { e_tokenid id; - const char *str; + char *str; size_t len; } s_token; diff --git a/src/shell/getoptions.c b/src/shell/getoptions.c index 87d1727..0c52db2 100644 --- a/src/shell/getoptions.c +++ b/src/shell/getoptions.c @@ -5,11 +5,13 @@ ** Login ** ** Started on Sun Jul 30 03:28:26 2006 Seblu -** Last update Tue Aug 29 00:54:37 2006 Seblu +** Last update Wed Aug 30 00:27:53 2006 Seblu */ #include +#include #include "option.h" +#include "shell.h" #include "../common/common.h" /*! @@ -19,29 +21,26 @@ ** @param argv program argv ** @param opt shell opt structure to set with options */ -void getoptions(s_options *opt, int argc, char **argv) +void getoptions(s_options *opt, int argc, char **argv) { #if DEBUG_OPTION == 1 printf("* Option Parser\n"); #endif if (argc == 1) return; - for (int i = 1; i < argc; ++i) - { + for (int i = 1; i < argc; ++i) { #if DEBUG_OPTION == 1 - printf("argv[%d]=%s\n", i, argv[i]); + printf("argv[%d]=%s\n", i, argv[i]); #endif - const char *copt = argv[i]; - if (*copt == '-') - { - if (copt[1] == 'c') - { - opt->command = strvmerge((const char**)argv + i + 1); + const char *copt = argv[i]; + if (!strcmp(copt, "-c") || !strcmp(copt, "--command")) { + opt->command = strvmerge((const char**)argv + i + 1); #if DEBUG_OPTION == 1 - printf("option c: %s\n", opt->command); + printf("option c: %s\n", opt->command); #endif - break; - } - } + break; } + else if (!strcmp(copt, "--ast-print")) + option_set(shell->options, "ast_print"); + } } diff --git a/src/shell/option.c b/src/shell/option.c index 216c09d..2c6f19c 100644 --- a/src/shell/option.c +++ b/src/shell/option.c @@ -5,7 +5,7 @@ ** Login ** ** Started on Tue Mar 21 19:00:38 2006 Seblu -** Last update Tue Aug 29 00:22:20 2006 Seblu +** Last update Wed Aug 30 00:19:38 2006 Seblu */ /* @@ -27,6 +27,7 @@ static const char *opts_table[NBR_OPTION] = "nocaseglob", "nullglob", "expand_aliases", + "ast_print", }; /* diff --git a/src/shell/option.h b/src/shell/option.h index 1444faa..9df1f9d 100644 --- a/src/shell/option.h +++ b/src/shell/option.h @@ -5,13 +5,13 @@ ** Login ** ** Started on Tue Mar 21 18:50:03 2006 Seblu -** Last update Tue Aug 29 00:54:50 2006 Seblu +** Last update Wed Aug 30 00:19:19 2006 Seblu */ #ifndef OPTION_H_ # define OPTION_H_ -#define NBR_OPTION 8 +#define NBR_OPTION 9 #define DEBUG_OPTION 0 diff --git a/src/shell/shell_entry.c b/src/shell/shell_entry.c index 2146d9b..934a667 100644 --- a/src/shell/shell_entry.c +++ b/src/shell/shell_entry.c @@ -5,12 +5,13 @@ ** Login ** ** Started on Mon Apr 10 23:57:28 2006 Seblu -** Last update Tue Aug 29 00:53:31 2006 Seblu +** Last update Wed Aug 30 00:20:33 2006 Seblu */ #include #include #include "shell.h" +#include "option.h" #include "../ast/ast.h" #include "../parser/parser.h" #include "../exec/exec.h" @@ -44,6 +45,8 @@ int main(int argc, char *argv[]) do { ast = parse(parser); + if (!parser->error && option_isset(shell->options, "ast_print")) + ast_print(ast, NULL); if (!parser->error) exec_node(ast); ast_destruct(ast); -- GitLab