diff options
author | 2006-01-31 05:53:10 +1000 | |
---|---|---|
committer | 2006-01-31 05:53:10 +1000 | |
commit | 028e1f36a1d96d321fab65005d56304ab31df73a (patch) | |
tree | a3ce0637aea90f2b8055cc88a25b051a897d5909 /parser.c | |
parent | f59e9baab9f71a1f345dfec20ff27f7bbd1b694b (diff) |
Improve the status builtin
darcs-hash:20060130195310-ac50b-5da6881a847170242be56555646bbf037218d545.gz
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 638 |
1 files changed, 319 insertions, 319 deletions
@@ -157,7 +157,7 @@ The fish parser. Contains functions for parsing code. #define INVALID_SCOPE_ERR_MSG _( L"Tried to evaluate commands using invalid block type '%ls'" ) -/** +/** Error for wrong token type */ #define UNEXPECTED_TOKEN_ERR_MSG _( L"Unexpected token of type '%ls'") @@ -168,73 +168,73 @@ The fish parser. Contains functions for parsing code. #define MISSING_COMMAND_ERR_MSG _( L"Error while searching for command '%ls'" ) -/** +/** While block description */ #define WHILE_BLOCK _( L"'while' block" ) -/** +/** For block description */ #define FOR_BLOCK _( L"'for' block" ) -/** +/** If block description */ #define IF_BLOCK _( L"'if' conditional block" ) -/** +/** function definition block description */ #define FUNCTION_DEF_BLOCK _( L"function definition block" ) -/** +/** Function invocation block description */ #define FUNCTION_CALL_BLOCK _( L"function invocation block" ) -/** +/** Switch block description */ #define SWITCH_BLOCK _( L"'switch' block" ) -/** +/** Fake block description */ #define FAKE_BLOCK _( L"unexecutable block" ) -/** +/** Top block description */ #define TOP_BLOCK _( L"global root block" ) -/** +/** Command substitution block description */ #define SUBST_BLOCK _( L"command substitution block" ) -/** +/** Begin block description */ #define BEGIN_BLOCK _( L"'begin' unconditional block" ) -/** +/** Source block description */ #define SOURCE_BLOCK _( L"Block created by the . builtin" ) -/** +/** Unknown block description */ #define UNKNOWN_BLOCK _( L"unknown/invalid block" ) @@ -322,7 +322,7 @@ typedef struct */ static int block_count( block_t *b ) { - + if( b==0) return 0; return( block_count(b->outer)+1); @@ -348,15 +348,15 @@ void parser_push_block( int type ) new->skip = 0; if( type == FAKE ) new->skip = 1; - - new->job = 0; - + + new->job = 0; + new->loop_status=LOOP_NORMAL; current_block = new; - if( (new->type != FUNCTION_DEF) && - (new->type != FAKE) && + if( (new->type != FUNCTION_DEF) && + (new->type != FAKE) && (new->type != TOP) ) { env_push( type == FUNCTION_CALL ); @@ -369,19 +369,19 @@ void parser_pop_block() debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 ); event_block_t *eb, *eb_next; - if( (current_block->type != FUNCTION_DEF ) && - (current_block->type != FAKE) && + if( (current_block->type != FUNCTION_DEF ) && + (current_block->type != FAKE) && (current_block->type != TOP) ) { env_pop(); } - + switch( current_block->type) { case FOR: { free( current_block->param1.for_variable ); - al_foreach( ¤t_block->param2.for_vars, + al_foreach( ¤t_block->param2.for_vars, (void (*)(const void *))&free ); al_destroy( ¤t_block->param2.for_vars ); break; @@ -399,7 +399,7 @@ void parser_pop_block() free( current_block->param2.function_description ); al_foreach( current_block->param4.function_events, (void (*)(const void *))&event_free ); - al_destroy( current_block->param4.function_events ); + al_destroy( current_block->param4.function_events ); free( current_block->param4.function_events ); break; } @@ -408,7 +408,7 @@ void parser_pop_block() { free( current_block->param1.function_name ); free( current_block->param4.call_filename ); - al_foreach( ¤t_block->param2.function_vars, + al_foreach( ¤t_block->param2.function_vars, (void (*)(const void *))&free ); al_destroy( ¤t_block->param2.function_vars ); break; @@ -427,7 +427,7 @@ void parser_pop_block() { eb_next = eb->next; free(eb); - } + } block_t *old = current_block; current_block = current_block->outer; @@ -440,37 +440,37 @@ const wchar_t *parser_get_block_desc( int block ) { case WHILE: return WHILE_BLOCK; - + case FOR: return FOR_BLOCK; - + case IF: return IF_BLOCK; case FUNCTION_DEF: return FUNCTION_DEF_BLOCK; - + case FUNCTION_CALL: return FUNCTION_CALL_BLOCK; - + case SWITCH: return SWITCH_BLOCK; - + case FAKE: return FAKE_BLOCK; - + case TOP: return TOP_BLOCK; - + case SUBST: return SUBST_BLOCK; - + case BEGIN: return BEGIN_BLOCK; - + case SOURCE: return SOURCE_BLOCK; - + default: return UNKNOWN_BLOCK; } @@ -484,7 +484,7 @@ const wchar_t *parser_get_block_desc( int block ) */ static int parser_skip_arguments( const wchar_t *cmd ) { - + return contains_str( cmd, L"else", L"begin", @@ -493,11 +493,11 @@ static int parser_skip_arguments( const wchar_t *cmd ) int parser_is_subcommand( const wchar_t *cmd ) { - + return parser_skip_arguments( cmd ) || contains_str( cmd, - L"command", - L"builtin", + L"command", + L"builtin", L"while", L"exec", L"if", @@ -513,12 +513,12 @@ int parser_is_subcommand( const wchar_t *cmd ) static int parser_is_block( wchar_t *word) { - return contains_str( word, + return contains_str( word, L"for", - L"while", - L"if", + L"while", + L"if", L"function", - L"switch", + L"switch", L"begin", (void *)0 ); } @@ -527,10 +527,10 @@ int parser_is_reserved( wchar_t *word) { return parser_is_block(word) || parser_is_subcommand( word ) || - contains_str( word, - L"end", - L"case", - L"else", + contains_str( word, + L"end", + L"case", + L"else", L"return", L"continue", L"break", @@ -544,24 +544,24 @@ static int parser_is_pipe_forbidden( wchar_t *word ) { return contains_str( word, L"exec", - L"case", + L"case", L"break", - L"return", - L"continue", + L"return", + L"continue", (void *)0 ); } /** Search the text for the end of the current block */ -static const wchar_t *parser_find_end( const wchar_t * buff ) +static const wchar_t *parser_find_end( const wchar_t * buff ) { tokenizer tok; int had_cmd=0; int count = 0; int error=0; int mark=0; - + for( tok_init( &tok, buff, 0 ); tok_has_next( &tok ) && !error; tok_next( &tok ) ) @@ -590,13 +590,13 @@ static const wchar_t *parser_find_end( const wchar_t * buff ) } break; } - + case TOK_END: { had_cmd = 0; break; } - + case TOK_PIPE: case TOK_BACKGROUND: { @@ -609,7 +609,7 @@ static const wchar_t *parser_find_end( const wchar_t * buff ) error = 1; } break; - + } case TOK_ERROR: @@ -618,24 +618,24 @@ static const wchar_t *parser_find_end( const wchar_t * buff ) default: break; - - } + + } if(!count) { - tok_next( &tok ); - mark = tok_get_pos( &tok ); - break; + tok_next( &tok ); + mark = tok_get_pos( &tok ); + break; } - + } - - tok_destroy( &tok ); + + tok_destroy( &tok ); if(!count && !error){ return buff+mark; } return 0; - + } wchar_t *parser_cdpath_get( wchar_t *dir ) @@ -674,12 +674,12 @@ wchar_t *parser_cdpath_get( wchar_t *dir ) nxt_path = path; path_cpy = wcsdup( path ); - + if( !path_cpy ) { - die_mem(); + die_mem(); } - + for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state ); nxt_path != 0; nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) ) @@ -695,7 +695,7 @@ wchar_t *parser_cdpath_get( wchar_t *dir ) continue; } - whole_path = + whole_path = wcsdupcat2( expanded_path, ( expanded_path[path_len-1] != L'/' )?L"/":L"", dir, 0 ); @@ -747,7 +747,7 @@ void error( int ec, int p, const wchar_t *str, ... ) va_start( va, str ); vswprintf( err_str, 256, str, va ); - va_end( va ); + va_end( va ); } @@ -778,9 +778,9 @@ wchar_t *get_filename( const wchar_t *cmd ) Allocate string long enough to hold the whole command */ wchar_t *new_cmd = malloc( sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) ); - /* + /* We tokenize a copy of the path, since strtok modifies - its arguments + its arguments */ wchar_t *path_cpy = wcsdup( path ); wchar_t *nxt_path = path; @@ -789,7 +789,7 @@ wchar_t *get_filename( const wchar_t *cmd ) if( (new_cmd==0) || (path_cpy==0) ) { die_mem(); - + } for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state ); @@ -849,34 +849,34 @@ void parser_init() al_init( &profile_data); } forbidden_function = al_new(); - + } /** Print profiling information to the specified stream */ -static void print_profile( array_list_t *p, - int pos, +static void print_profile( array_list_t *p, + int pos, FILE *out ) { profile_element_t *me, *prev; - int i; + int i; int my_time; - + if( pos >= al_get_count( p ) ) return; - + me= (profile_element_t *)al_get( p, pos ); if( !me->skipped ) { my_time=me->parse+me->exec; - + for( i=pos+1; i<al_get_count(p); i++ ) { prev = (profile_element_t *)al_get( p, i ); if( prev->skipped ) continue; - + if( prev->level <= me->level ) break; if( prev->level > me->level+1 ) @@ -884,7 +884,7 @@ static void print_profile( array_list_t *p, my_time -= prev->parse; my_time -= prev->exec; } - + if( me->cmd ) { fwprintf( out, L"%d\t%d\t", my_time, me->parse+me->exec ); @@ -895,9 +895,9 @@ static void print_profile( array_list_t *p, fwprintf( out, L"> %ls\n", me->cmd ); } } - print_profile( p, pos+1, out ); - free( me->cmd ); - free( me ); + print_profile( p, pos+1, out ); + free( me->cmd ); + free( me ); } void parser_destroy() @@ -916,7 +916,7 @@ void parser_destroy() } else { - fwprintf( f, + fwprintf( f, _(L"Time\tSum\tCommand\n"), al_get_count( &profile_data ) ); print_profile( &profile_data, 0, f ); @@ -924,7 +924,7 @@ void parser_destroy() } al_destroy( &profile_data ); } - + if( lineinfo ) { sb_destroy( lineinfo ); @@ -934,7 +934,7 @@ void parser_destroy() al_destroy( forbidden_function ); free( forbidden_function ); - + } /** @@ -952,7 +952,7 @@ static void print_errors() current_tokenizer_pos = err_pos; fwprintf( stderr, L"%ls", parser_current_line() ); - + current_tokenizer_pos=tmp; } } @@ -964,7 +964,7 @@ int eval_args( const wchar_t *line, array_list_t *args ) eval_args may be called while evaulating another command, so we save the previous tokenizer and restore it on exit */ - tokenizer *previous_tokenizer=current_tokenizer; + tokenizer *previous_tokenizer=current_tokenizer; int previous_pos=current_tokenizer_pos; int do_loop=1; tok_init( &tok, line, 0 ); @@ -987,12 +987,12 @@ int eval_args( const wchar_t *line, array_list_t *args ) do_loop=0; break; } - + default: { break; } - + } break; @@ -1005,7 +1005,7 @@ int eval_args( const wchar_t *line, array_list_t *args ) tok_get_pos( &tok ), TOK_ERR_MSG, tok_last(&tok) ); - + do_loop=0; break; } @@ -1015,7 +1015,7 @@ int eval_args( const wchar_t *line, array_list_t *args ) tok_get_pos( &tok ), UNEXPECTED_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(&tok)) ); - + do_loop=0; break; @@ -1035,7 +1035,7 @@ void parser_stack_trace( block_t *b, string_buffer_t *buff) { if( !b ) return; - + if( b->type == FUNCTION_CALL || b->type==SOURCE) { int i; @@ -1048,31 +1048,31 @@ void parser_stack_trace( block_t *b, string_buffer_t *buff) const wchar_t *file = b->param4.call_filename; if( file ) - sb_printf( buff, + sb_printf( buff, _(L"\tcalled on line %d of file '%ls',\n"), - b->param3.call_lineno, + b->param3.call_lineno, file ); else - sb_printf( buff, + sb_printf( buff, _(L"\tcalled on standard input,\n") ); - + if( al_get_count( &b->param2.function_vars ) ) { string_buffer_t tmp; sb_init( &tmp ); - + for( i=0; i<al_get_count( &b->param2.function_vars ); i++ ) { sb_append2( &tmp, i?L" ":L"", (wchar_t *)al_get( &b->param2.function_vars, i ), (void *)0 ); } sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff ); - + sb_destroy( &tmp ); - } - sb_printf( buff, + } + sb_printf( buff, L"\n" ); - } - parser_stack_trace( b->outer, buff ); + } + parser_stack_trace( b->outer, buff ); } static const wchar_t *is_function() @@ -1098,7 +1098,7 @@ int parser_get_lineno() int i; const wchar_t *whole_str = tok_string( current_tokenizer ); const wchar_t *function_name; - + int lineno = 1; for( i=0; i<current_tokenizer_pos; i++ ) @@ -1108,31 +1108,31 @@ int parser_get_lineno() lineno++; } } - + if( (function_name = is_function()) ) { lineno += function_get_definition_offset( function_name ); - } - + } + return lineno; } const wchar_t *parser_current_filename() { block_t *b = current_block; - + while( 1 ) { if( !b ) { - return reader_current_filename(); + return reader_current_filename(); } if( b->type == FUNCTION_CALL ) { return function_get_definition_file(b->param1.function_name ); } b=b->outer; - } + } } static int printed_width( const wchar_t *str, int len ) @@ -1167,18 +1167,18 @@ wchar_t *parser_current_line() int current_line_width; const wchar_t *function_name=0; int current_line_start=0; - - + + if( !line ) return L""; - + if( !lineinfo ) { lineinfo = malloc( sizeof(string_buffer_t) ); sb_init( lineinfo ); } - sb_clear( lineinfo ); - + sb_clear( lineinfo ); + /* Calculate line number, line offset, etc. */ @@ -1197,7 +1197,7 @@ wchar_t *parser_current_line() if( (function_name = is_function()) ) { lineno += function_get_definition_offset( function_name ); - } + } /* Copy current line from whole string @@ -1232,7 +1232,7 @@ wchar_t *parser_current_line() } // debug( 1, L"Current pos %d, line pos %d, file_length %d, is_interactive %d, offset %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive, offset); - /* + /* Skip printing character position if we are in interactive mode and the error was on the first character of the line. */ @@ -1249,12 +1249,12 @@ wchar_t *parser_current_line() } else { - sb_printf( lineinfo, + sb_printf( lineinfo, L"%ls\n^\n", line ); } } - + free( line ); parser_stack_trace( current_block, lineinfo ); @@ -1309,10 +1309,10 @@ static void parse_job_main_loop( process_t *p, int proc_is_count=0; int matched_wildcard = 0, unmatched_wildcard = 0; - + wchar_t *unmatched = 0; int unmatched_pos=0; - + /* Test if this is the 'count' command. We need to special case count, since it should display a help message on 'count .h', @@ -1327,12 +1327,12 @@ static void parse_job_main_loop( process_t *p, woot++; proc_is_count = wcscmp( woot, L"count" )==0; } - + while( 1 ) { - + /* debug( 2, L"Read token %ls\n", wcsdup(tok_last( tok )) ); */ - + switch( tok_last_type( tok ) ) { case TOK_PIPE: @@ -1341,7 +1341,7 @@ static void parse_job_main_loop( process_t *p, error( SYNTAX_ERROR, tok_get_pos( tok ), EXEC_ERR_MSG ); - return; + return; } p->pipe_fd = wcstol( tok_last( tok ), 0, 10 ); p->argv = list_to_char_arr( args ); @@ -1356,7 +1356,7 @@ static void parse_job_main_loop( process_t *p, /* Don't do anything on failiure. parse_job will notice the error flag beeing set */ - + } is_finished = 1; break; @@ -1369,9 +1369,9 @@ static void parse_job_main_loop( process_t *p, p->argv = list_to_char_arr( args ); if( tok_has_next(tok)) tok_next(tok); - + is_finished = 1; - + break; } @@ -1385,11 +1385,11 @@ static void parse_job_main_loop( process_t *p, 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 == INTERNAL_BUILTIN ) @@ -1397,7 +1397,7 @@ static void parse_job_main_loop( process_t *p, skip=0; } } - + if( !skip ) { if( proc_is_count && @@ -1410,7 +1410,7 @@ static void parse_job_main_loop( process_t *p, p->type = INTERNAL_BUILTIN; wcscpy( p->actual_cmd, L"count" ); } - + switch( expand_string( wcsdup(tok_last( tok )), args, 0 ) ) { @@ -1423,11 +1423,11 @@ static void parse_job_main_loop( process_t *p, tok_get_pos( tok ), _(L"Could not expand string '%ls'"), tok_last(tok) ); - + } break; } - + case EXPAND_WILDCARD_NO_MATCH: { unmatched_wildcard = 1; @@ -1436,21 +1436,21 @@ static void parse_job_main_loop( process_t *p, unmatched = wcsdup(tok_last( tok )); unmatched_pos = tok_get_pos( tok ); } - + break; } - + case EXPAND_WILDCARD_MATCH: { matched_wildcard = 1; break; } - + case EXPAND_OK: { break; } - + } } @@ -1466,7 +1466,7 @@ static void parse_job_main_loop( process_t *p, int type = tok_last_type( tok ); io_data_t *new_io; wchar_t *target = 0; - + /* Don't check redirections in skipped part @@ -1483,14 +1483,14 @@ static void parse_job_main_loop( process_t *p, REDIRECT_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(tok)) ); } - + break; } - + new_io = calloc( 1, sizeof(io_data_t) ); if( !new_io ) die_mem(); - + new_io->fd = wcstol( tok_last( tok ), 0, 10 ); @@ -1507,7 +1507,7 @@ static void parse_job_main_loop( process_t *p, tok_get_pos( tok ), REDIRECT_TOKEN_ERR_MSG, tok_last( tok ) ); - + } } break; @@ -1517,7 +1517,7 @@ static void parse_job_main_loop( process_t *p, REDIRECT_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(tok)) ); } - + if( target == 0 || wcslen( target )==0 ) { if( error_code == 0 ) @@ -1528,7 +1528,7 @@ static void parse_job_main_loop( process_t *p, } else { - + switch( type ) { @@ -1568,7 +1568,7 @@ static void parse_job_main_loop( process_t *p, tok_get_pos( tok ), _(L"Requested redirection to something that is not a file descriptor %ls"), target ); - + tok_next(tok); } free(target); @@ -1576,19 +1576,19 @@ static void parse_job_main_loop( process_t *p, break; } } - + j->io = io_add( j->io, new_io ); } break; case TOK_ERROR: - { + { error( SYNTAX_ERROR, tok_get_pos( tok ), TOK_ERR_MSG, tok_last(tok) ); - + return; } @@ -1597,14 +1597,14 @@ static void parse_job_main_loop( process_t *p, tok_get_pos( tok ), UNEXPECTED_TOKEN_ERR_MSG, tok_get_desc( tok_last_type(tok)) ); - + tok_next(tok); break; } if( (is_finished) || (error_code != 0) ) break; - + tok_next( tok ); } @@ -1617,16 +1617,16 @@ static void parse_job_main_loop( process_t *p, if( is_interactive && !is_block ) { int tmp; - + debug( 1, WILDCARD_ERR_MSG, unmatched ); tmp = current_tokenizer_pos; current_tokenizer_pos = unmatched_pos; fwprintf( stderr, L"%ls", parser_current_line() ); - + current_tokenizer_pos=tmp; } - + } } free( unmatched ); @@ -1651,10 +1651,10 @@ static int parse_job( process_t *p, array_list_t args; // The list that will become the argc array for the program int use_function = 1; // May functions be considered when checking what action this command represents int use_builtin = 1; // May builtins be considered when checking what action this command represents - int is_new_block=0; // Does this command create a new block? + int is_new_block=0; // Does this command create a new block? + + block_t *prev_block = current_block; - block_t *prev_block = current_block; - debug( 2, L"begin parse_job()\n" ); al_init( &args ); @@ -1677,20 +1677,20 @@ static int parse_job( process_t *p, tok_get_pos( tok ), ILLEGAL_CMD_ERR_MSG, tok_last( tok ) ); - + al_destroy( &args ); return 0; } break; } - + case TOK_ERROR: { error( SYNTAX_ERROR, tok_get_pos( tok ), TOK_ERR_MSG, tok_last(tok) ); - + al_destroy( &args ); return 0; } @@ -1712,23 +1712,23 @@ static int parse_job( process_t *p, CMD_ERR_MSG, tok_get_desc( tok_last_type(tok) ) ); } - + al_destroy( &args ); return 0; } - + default: { error( SYNTAX_ERROR, tok_get_pos( tok ), CMD_ERR_MSG, tok_get_desc( tok_last_type(tok) ) ); - + al_destroy( &args ); return 0; } } - + int mark = tok_get_pos( tok ); if( wcscmp( L"command", nxt )==0 ) @@ -1783,7 +1783,7 @@ static int parse_job( process_t *p, } else { - j->skip = proc_get_last_status(); + j->skip = proc_get_last_status(); free( nxt ); continue; } @@ -1797,7 +1797,7 @@ static int parse_job( process_t *p, } else { - j->skip = !proc_get_last_status(); + j->skip = !proc_get_last_status(); free( nxt ); continue; } @@ -1810,10 +1810,10 @@ static int parse_job( process_t *p, tok_get_pos( tok ), EXEC_ERR_MSG ); al_destroy( &args ); - free(nxt); + free(nxt); return 0; } - + tok_next( tok ); if( tok_last(tok)[0] == L'-' ) { @@ -1823,7 +1823,7 @@ static int parse_job( process_t *p, { use_function = 0; use_builtin=0; - p->type=INTERNAL_EXEC; + p->type=INTERNAL_EXEC; free( nxt ); continue; } @@ -1845,17 +1845,17 @@ static int parse_job( process_t *p, { new_block = 1; } - + if( new_block ) { parser_push_block( WHILE ); current_block->param1.while_state=WHILE_TEST_FIRST; current_block->tok_pos = mark; } - + free( nxt ); is_new_block=1; - + continue; } else if( wcscmp( L"if", nxt ) ==0 ) @@ -1913,12 +1913,12 @@ static int parse_job( process_t *p, { p->type = INTERNAL_BUILTIN; is_new_block = parser_is_block( (wchar_t *)al_get( &args, 0 ) ); - } + } } if( !p->type || (p->type == INTERNAL_EXEC) ) { - /* + /* If we are not executing the current block, allow non-existent commands. */ @@ -1928,17 +1928,17 @@ static int parse_job( process_t *p, } else { - + p->actual_cmd = get_filename( (wchar_t *)al_get( &args, 0 ) ); debug( 2, L"filename '%ls' -> '%ls'", (wchar_t *)al_get( &args, 0 ), p->actual_cmd?p->actual_cmd:L"0" ); - + /* Check if the specified command exists */ if( p->actual_cmd == 0 ) { - + /* That is not a command! Test if it is a directory, in which case, we use 'cd' as the @@ -1950,13 +1950,13 @@ static int parse_job( process_t *p, { wchar_t *tmp; free( pp ); - + tmp = (wchar_t *)al_get( &args, 0 ); al_truncate( &args, 0 ); al_push( &args, wcsdup( L"cd" ) ); al_push( &args, tmp ); /* - If we have defined a wrapper around cd, use it, + If we have defined a wrapper around cd, use it, otherwise use the cd builtin */ if( function_exists( L"cd" ) ) @@ -1972,7 +1972,7 @@ static int parse_job( process_t *p, tok_get_pos( tok ), COMMAND_ASSIGN_ERR_MSG, (wchar_t *)al_get( &args, 0 ) ); - + } else @@ -1981,7 +1981,7 @@ static int parse_job( process_t *p, tok_get_pos( tok ), _(L"Unknown command '%ls'"), (wchar_t *)al_get( &args, 0 ) ); - + } } } @@ -1991,11 +1991,11 @@ static int parse_job( process_t *p, if( is_new_block ) { - const wchar_t *end=parser_find_end( tok_string( tok ) + + const wchar_t *end=parser_find_end( tok_string( tok ) + current_tokenizer_pos ); tokenizer subtok; int make_sub_block = j->first_process != p; - + if( !end ) { error( SYNTAX_ERROR, @@ -2010,7 +2010,7 @@ static int parse_job( process_t *p, { case TOK_END: break; - + case TOK_REDIRECT_OUT: case TOK_REDIRECT_APPEND: case TOK_REDIRECT_IN: @@ -2018,9 +2018,9 @@ static int parse_job( process_t *p, case TOK_PIPE: { make_sub_block = 1; - break; + break; } - + default: { error( SYNTAX_ERROR, @@ -2030,32 +2030,32 @@ static int parse_job( process_t *p, } tok_destroy( &subtok ); } - + if( make_sub_block ) { int end_pos = end-tok_string( tok ); - wchar_t *sub_block= wcsndup( tok_string( tok ) + current_tokenizer_pos, + wchar_t *sub_block= wcsndup( tok_string( tok ) + current_tokenizer_pos, end_pos - current_tokenizer_pos); - + p->type = INTERNAL_BLOCK; free( (void *)al_get( &args, 0 ) ); al_set( &args, 0, sub_block ); - tok_set_pos( tok, + tok_set_pos( tok, end_pos ); while( prev_block != current_block ) { parser_pop_block(); } - + } else tok_next( tok ); - + } else tok_next( tok ); - + if( !error_code ) { if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(&args, 0) ) ) @@ -2068,7 +2068,7 @@ static int parse_job( process_t *p, parse_job_main_loop( p, j, tok, &args ); } } - + if( error_code ) { /* @@ -2077,8 +2077,8 @@ static int parse_job( process_t *p, */ al_foreach( &args, (void (*)(const void *))&free ); - free(p->argv); - p->argv=0; + free(p->argv); + p->argv=0; /* Make sure the block stack is consistent */ @@ -2086,10 +2086,10 @@ static int parse_job( process_t *p, { parser_pop_block(); } - + } al_destroy( &args ); - + // debug( 2, L"end parse_job()\n" ); return !error_code; } @@ -2100,7 +2100,7 @@ static int parse_job( process_t *p, preformed. \param j the job to execute - + */ static void skipped_exec( job_t * j ) { @@ -2154,7 +2154,7 @@ static void skipped_exec( job_t * j ) \param tok The tokenizer to read tokens from */ - + static void eval_job( tokenizer *tok ) { job_t *j; @@ -2168,12 +2168,12 @@ static void eval_job( tokenizer *tok ) if( profile ) { p=malloc( sizeof(profile_element_t)); - p->cmd=0; + p->cmd=0; al_push( &profile_data, p ); p->skipped=1; t1 = get_time(); } - + switch( tok_last_type( tok ) ) { case TOK_STRING: @@ -2183,9 +2183,9 @@ static void eval_job( tokenizer *tok ) j->fg=1; j->constructed=0; j->skip_notification = is_subshell || is_block || is_event || (!is_interactive); - + current_block->job = j; - + if( is_interactive ) { if( tcgetattr (0, &j->tmodes) ) @@ -2196,7 +2196,7 @@ static void eval_job( tokenizer *tok ) break; } } - + j->first_process = calloc( 1, sizeof( process_t ) ); @@ -2206,35 +2206,35 @@ static void eval_job( tokenizer *tok ) if( job_start_pos < tok_get_pos( tok ) ) { int stop_pos = tok_get_pos( tok ); - wchar_t *newline = wcschr( tok_string(tok)+start_pos, + wchar_t *newline = wcschr( tok_string(tok)+start_pos, L'\n' ); if( newline ) stop_pos = mini( stop_pos, newline - tok_string(tok) ); - + j->command = wcsndup( tok_string(tok)+start_pos, stop_pos-start_pos ); } else j->command = wcsdup( L"" ); - + if( profile ) { t2 = get_time(); - p->cmd = wcsdup( j->command ); + p->cmd = wcsdup( j->command ); p->skipped=current_block->skip; } - + skip |= current_block->skip; skip |= j->wildcard_error; skip |= j->skip; - + if(!skip ) { int was_builtin = 0; // if( j->first_process->type==INTERNAL_BUILTIN && !j->first_process->next) // was_builtin = 1; - - exec( j ); + + exec( j ); /* Only external commands require a new fishd barrier */ if( !was_builtin ) @@ -2242,9 +2242,9 @@ static void eval_job( tokenizer *tok ) } else { - skipped_exec( j ); + skipped_exec( j ); } - + if( profile ) { t3 = get_time(); @@ -2255,7 +2255,7 @@ static void eval_job( tokenizer *tok ) if( current_block->type == WHILE ) { - + switch( current_block->param1.while_state ) { case WHILE_TEST_FIRST: @@ -2276,7 +2276,7 @@ static void eval_job( tokenizer *tok ) current_block->param1.if_state++; } } - + } else { @@ -2290,7 +2290,7 @@ static void eval_job( tokenizer *tok ) current_block->job = 0; break; } - + case TOK_END: { if( tok_has_next( tok )) @@ -2315,33 +2315,33 @@ static void eval_job( tokenizer *tok ) CMD_ERR_MSG, tok_get_desc( tok_last_type(tok) ) ); } - + return; } - + case TOK_ERROR: { error( SYNTAX_ERROR, tok_get_pos( tok ), TOK_ERR_MSG, tok_last(tok) ); - + return; } - + default: { error( SYNTAX_ERROR, tok_get_pos( tok ), CMD_ERR_MSG, tok_get_desc( tok_last_type(tok)) ); - + return; } } - + job_reap( 0 ); - + // debug( 2, L"end eval_job()\n" ); } @@ -2358,16 +2358,16 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) { forbidden_function = al_new(); } - + forbid_count = al_get_count( forbidden_function ); - + block_io = io; - + job_reap( 0 ); debug( 4, L"eval: %ls", cmd ); - - + + if( !cmd ) { debug( 1, @@ -2378,30 +2378,30 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) return 1; } - if( (block_type!=TOP) && + if( (block_type!=TOP) && (block_type != FUNCTION_CALL) && (block_type != SUBST)) { debug( 1, INVALID_SCOPE_ERR_MSG, parser_get_block_desc( block_type ) ); - + debug( 1, BUGREPORT_MSG, PACKAGE_BUGREPORT ); return 1; } - + eval_level++; current_tokenizer = malloc( sizeof(tokenizer)); - + parser_push_block( block_type ); - - + + tok_init( current_tokenizer, cmd, 0 ); error_code = 0; - - event_fire( 0 ); + + event_fire( 0 ); while( tok_has_next( current_tokenizer ) && !error_code && @@ -2409,11 +2409,11 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) !exit_status() ) { eval_job( current_tokenizer ); - event_fire( 0 ); + event_fire( 0 ); } - - int prev_block_type = current_block->type; - + + int prev_block_type = current_block->type; + parser_pop_block(); while( start_current_block != current_block ) @@ -2423,31 +2423,31 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) debug( 0, _(L"End of block mismatch. Program terminating.") ); debug( 0, - BUGREPORT_MSG, + BUGREPORT_MSG, PACKAGE_BUGREPORT ); exit(1); break; } - + if( (!error_code) && (!exit_status()) && (!proc_get_last_status()) ) { char *h; //debug( 2, L"Status %d\n", proc_get_last_status() ); - debug( 1, + debug( 1, L"%ls", parser_get_block_desc( current_block->type ) ); - debug( 1, + debug( 1, BLOCK_END_ERR_MSG ); fwprintf( stderr, L"%ls", parser_current_line() ); - + h = builtin_help_get( L"end" ); if( h ) fwprintf( stderr, L"%s", h ); break; - + } - prev_block_type = current_block->type; + prev_block_type = current_block->type; parser_pop_block(); } @@ -2462,15 +2462,15 @@ int eval( const wchar_t *cmd, io_data_t *io, int block_type ) if( block_type == SUBST ) { al_destroy( forbidden_function ); - free( forbidden_function ); + free( forbidden_function ); } - - /* + + /* Restore previous eval state */ - forbidden_function = prev_forbidden; + forbidden_function = prev_forbidden; current_tokenizer=previous_tokenizer; - block_io = prev_io; + block_io = prev_io; eval_level--; code=error_code; @@ -2497,9 +2497,9 @@ int parser_test( wchar_t * buff, int forbid_pipeline = 0; int needs_cmd=0; int require_additional_commands=0; - + current_tokenizer = &tok; - + for( tok_init( &tok, buff, 0 ); tok_has_next( &tok ) && !err; tok_next( &tok ) ) @@ -2515,7 +2515,7 @@ int parser_test( wchar_t * buff, { int mark = tok_get_pos( &tok ); had_cmd = 1; - + if( require_additional_commands ) { if( contains_str( tok_last(&tok), @@ -2524,15 +2524,15 @@ int parser_test( wchar_t * buff, { err=1; if( babble ) - { + { error( SYNTAX_ERROR, tok_get_pos( &tok ), COND_ERR_MSG ); - - print_errors(); + + print_errors(); } } - + require_additional_commands--; } @@ -2545,7 +2545,7 @@ int parser_test( wchar_t * buff, count--; tok_set_pos( &tok, mark ); } - + /* Handle block commands */ @@ -2553,10 +2553,10 @@ int parser_test( wchar_t * buff, { if( count >= BLOCK_MAX_COUNT ) { - error( SYNTAX_ERROR, - tok_get_pos( &tok ), + error( SYNTAX_ERROR, + tok_get_pos( &tok ), BLOCK_ERR_MSG ); - + print_errors(); } else @@ -2573,11 +2573,11 @@ int parser_test( wchar_t * buff, block_type[count] = FUNCTION_DEF; else if( wcscmp( tok_last(&tok), L"begin") == 0 ) block_type[count] = BEGIN; - else - block_type[count] = -1; - + else + block_type[count] = -1; + // debug( 2, L"add block of type %d after cmd %ls\n", block_type[count], tok_last(&tok) ); - + block_pos[count] = current_tokenizer_pos; tok_next( &tok ); @@ -2585,7 +2585,7 @@ int parser_test( wchar_t * buff, tok_set_pos( &tok, mark ); } } - + /* If parser_is_subcommand is true, the command accepts a second command as it's first @@ -2610,18 +2610,18 @@ int parser_test( wchar_t * buff, { err=1; if( babble ) - { + { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - - print_errors(); - + + print_errors(); + } } require_additional_commands=1; } - + /* There are a lot of situations where pipelines are forbidden, inclusing when using the exec @@ -2633,18 +2633,18 @@ int parser_test( wchar_t * buff, { err=1; if( babble ) - { + { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - - print_errors(); - + + print_errors(); + } } - forbid_pipeline = 1; + forbid_pipeline = 1; } - + /* Test that the case builtin is only used in a switch block */ @@ -2653,25 +2653,25 @@ int parser_test( wchar_t * buff, if( !count || block_type[count-1]!=SWITCH ) { err=1; - + // debug( 2, L"Error on block type %d\n", block_type[count-1] ); - + if( babble ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_CASE_ERR_MSG ); - + print_errors(); } } - } + } /* Test that break and continue are only used in loop blocks */ - if( wcscmp( L"break", tok_last( &tok ) )==0 || + if( wcscmp( L"break", tok_last( &tok ) )==0 || wcscmp( L"continue", tok_last( &tok ) )==0) { int found_loop=0; @@ -2685,11 +2685,11 @@ int parser_test( wchar_t * buff, break; } } - + if( !found_loop ) { err=1; - + if( babble ) { error( SYNTAX_ERROR, @@ -2697,9 +2697,9 @@ int parser_test( wchar_t * buff, INVALID_LOOP_ERR_MSG ); print_errors(); } - } + } } - + /* Test that else is only used in an if-block */ @@ -2713,13 +2713,13 @@ int parser_test( wchar_t * buff, error( SYNTAX_ERROR, tok_get_pos( &tok ), INVALID_ELSE_ERR_MSG ); - + print_errors(); } } } - + /* Test that end is not used when not inside a blovk */ @@ -2732,7 +2732,7 @@ int parser_test( wchar_t * buff, tok_get_pos( &tok ), INVALID_END_ERR_MSG ); print_errors(); - } + } } } break; @@ -2761,7 +2761,7 @@ int parser_test( wchar_t * buff, { if( needs_cmd && !had_cmd ) { - err = 1; + err = 1; if( babble ) { error( SYNTAX_ERROR, @@ -2770,10 +2770,10 @@ int parser_test( wchar_t * buff, tok_get_desc( tok_last_type(&tok))); print_errors(); } - } - needs_cmd=0; + } + needs_cmd=0; had_cmd = 0; - is_pipeline=0; + is_pipeline=0; forbid_pipeline=0; break; } @@ -2784,35 +2784,35 @@ int parser_test( wchar_t * buff, { err=1; if( babble ) - { + { error( SYNTAX_ERROR, tok_get_pos( &tok ), EXEC_ERR_MSG ); - - print_errors(); + + print_errors(); } } - needs_cmd=0; + needs_cmd=0; is_pipeline=1; } - + case TOK_BACKGROUND: { if( needs_cmd && !had_cmd ) { - err = 1; + err = 1; if( babble ) { error( SYNTAX_ERROR, tok_get_pos( &tok ), CMD_ERR_MSG, tok_get_desc( tok_last_type(&tok))); - + print_errors(); } - } - + } + if( had_cmd ) { had_cmd = 0; @@ -2829,29 +2829,29 @@ int parser_test( wchar_t * buff, tok_get_pos( &tok ), TOK_ERR_MSG, tok_last(&tok) ); - - + + print_errors(); //debug( 2, tok_last( &tok) ); } break; } } - + if( require_additional_commands ) { err=1; if( babble ) - { + { error( SYNTAX_ERROR, - tok_get_pos( &tok ), + tok_get_pos( &tok ), COND_ERR_MSG ); - - print_errors(); + + print_errors(); } } - - + + if( babble && count>0 ) { error( SYNTAX_ERROR, @@ -2859,9 +2859,9 @@ int parser_test( wchar_t * buff, BLOCK_END_ERR_MSG ); print_errors(); } - + tok_destroy( &tok ); - + current_tokenizer=previous_tokenizer; current_tokenizer_pos = previous_pos; |