From f643a4e2007c547c0e224f35a5e10d2bf46ab489 Mon Sep 17 00:00:00 2001 From: axel Date: Sun, 25 Sep 2005 05:31:17 +1000 Subject: Fix minor bugs in parser darcs-hash:20050924193117-ac50b-eb8ecfe4fec3bca6f89356a9079977802eb4a2c8.gz --- ChangeLog | 7 +++++++ common.c | 5 ++++- common.h | 10 +++++----- parser.c | 33 +++++++++++++++++++++++---------- proc.c | 7 +++++++ reader.c | 3 +++ 6 files changed, 49 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index c940a8ba..20904880 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,13 @@ * reader.c (reader_readline): Quit token search on escape + * parser.c (pares_job_main_loop): Make command substitutions for the case command expand properly + + * parser.c (pares_job_main_loop): Fix memory leak on parse error in pipeline + + * common.h, common.c: Make DEBUG_LEVEL constant into debug_level runtime configurable variable + + 2005-09-23 Axel Liljencrantz * reader.c (set_signal_handlers): Ignore SIG_PIPE, generated by fishd socket diff --git a/common.c b/common.c index 1c3ccd03..376b1620 100644 --- a/common.c +++ b/common.c @@ -71,6 +71,9 @@ char *profile=0; wchar_t *program_name; +int debug_level=1; + + static int block_count=0; void common_destroy() @@ -761,7 +764,7 @@ void debug( int level, wchar_t *msg, ... ) { va_list va; - if( level > DEBUG_LEVEL ) + if( level > debug_level ) return; va_start( va, msg ); diff --git a/common.h b/common.h index cb3d7b00..af835d60 100644 --- a/common.h +++ b/common.h @@ -18,11 +18,6 @@ typedef char tputs_arg_t; */ #define MAX_UTF8_BYTES 6 -/** - Amount of debug info to show. Higher level means more debug info will be displayed -*/ -#define DEBUG_LEVEL 1 - /** Color code for set_color. Does not update the color. */ @@ -47,6 +42,11 @@ extern wchar_t ellipsis_char; */ extern int error_max; +/** + The verbosity of fish +*/ +extern int debug_level; + /** Profiling flag. True if commands should be profiled. */ diff --git a/parser.c b/parser.c index 6ab2627c..dd180806 100644 --- a/parser.c +++ b/parser.c @@ -152,7 +152,14 @@ void parser_push_block( int type ) new->outer = current_block; new->type = (current_block && current_block->skip)?FAKE:type; + /* + New blocks should be skipped if the outer block is skipped, + except TOP ans SUBST block, which open up new environments + */ new->skip=current_block?current_block->skip:0; + if( type == TOP || type == SUBST ) + new->skip = 0; + new->loop_status=LOOP_NORMAL; @@ -910,23 +917,20 @@ static void parse_job_main_loop( process_t *p, tok_get_pos( tok ) ); return; } - + p->argv = list_to_char_arr( args ); p->next = calloc( 1, sizeof( process_t ) ); if( p->next == 0 ) { die_mem(); - } tok_next( tok ); if( !parse_job( p->next, j, tok )) { /* - Do not free args content on error - it is - already in p->argv and will be freed by job_free - later on. + Don't do anything on failiure. parse_job will notice the error flag beeing set */ - al_truncate( args, 0 ); + } is_finished = 1; break; @@ -950,14 +954,21 @@ static void parse_job_main_loop( process_t *p, if( current_block->skip ) { + /* + If this command should be skipped, we do not expand the arguments + */ skip=1; + + /* + But if this is in fact a case statement, then it should be evaluated + */ + if( (current_block->type == SWITCH) && (wcscmp( al_get( args, 0), L"case" )==0) && - p->type ) + p->type == INTERNAL_BUILTIN ) { skip=0; } - } if( !skip ) @@ -972,7 +983,7 @@ static void parse_job_main_loop( process_t *p, p->type = INTERNAL_BUILTIN; wcscpy( p->actual_cmd, L"count" ); } - + if( !expand_string( wcsdup(tok_last( tok )), args, 0 ) @@ -986,7 +997,6 @@ static void parse_job_main_loop( process_t *p, tok_last(tok), tok_get_pos( tok ) ); } - } } @@ -1731,6 +1741,9 @@ static void eval_job( tokenizer *tok ) } else { + /* + This job could not be properly parsed. We free it instead. + */ job_free( j ); } break; diff --git a/proc.c b/proc.c index 4c9fbb1c..a007b56a 100644 --- a/proc.c +++ b/proc.c @@ -154,12 +154,19 @@ static void free_process( process_t *p ) if( p==0 ) return; + + free_process( p->next ); + debug( 3, L"Free process %ls", p->actual_cmd ); free( p->actual_cmd ); if( p->argv != 0 ) { + debug( 3, L"Process has argument vector" ); for( arg=p->argv; *arg; arg++ ) + { + debug( 3, L"Free argument %ls", *arg ); free( *arg ); + } free(p->argv ); } free( p ); diff --git a/reader.c b/reader.c index d779e006..a8a2672e 100644 --- a/reader.c +++ b/reader.c @@ -1262,6 +1262,9 @@ static void run_pager( wchar_t *prefix, int is_quoted, array_list_t *comp ) exec_read_io_buffer( out ); + sb_destroy( &cmd ); + + int nil=0; b_append( out->out_buffer, &nil, 1 ); -- cgit v1.2.3