From da85bdc4012fb5a5e7ffffe61381fb9ba742958b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 22 Jan 2012 20:47:13 -0800 Subject: [PATCH] More work on the instanced parser --- builtin.cpp | 6 +-- event.cpp | 2 +- exec.cpp | 41 ++++++++-------- exec.h | 3 +- expand.cpp | 81 ++++++++++++++++--------------- expand.h | 1 + fish.cpp | 9 ++-- parser.cpp | 137 +++++++++++++++++++++------------------------------- parser.h | 17 +++++-- tokenizer.h | 5 +- 10 files changed, 145 insertions(+), 157 deletions(-) diff --git a/builtin.cpp b/builtin.cpp index f3f7af1f9..f30d842e9 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -186,7 +186,7 @@ static int count_char( const wchar_t *str, wchar_t c ) return res; } -wchar_t *builtin_help_get( const wchar_t *name ) +wchar_t *builtin_help_get( parser_t &parser, const wchar_t *name ) { wcstring_list_t lst; string_buffer_t cmd; @@ -254,7 +254,7 @@ static void builtin_print_help( parser_t &parser, const wchar_t *cmd, string_buf parser.current_line() ); } - h = builtin_help_get( cmd ); + h = builtin_help_get( parser, cmd ); if( !h ) return; @@ -3914,7 +3914,7 @@ const wchar_t *builtin_get_desc( const wchar_t *b ) return _( hash_get( desc, b )); } -void builtin_push_io( int in ) +void builtin_push_io( parser_t &parser, int in ) { if( builtin_stdin != -1 ) { diff --git a/event.cpp b/event.cpp index b8d1a99b8..efc3de501 100644 --- a/event.cpp +++ b/event.cpp @@ -461,7 +461,7 @@ static void event_fire_internal( event_t *event ) prev_status = proc_get_last_status(); parser.push_block( EVENT ); parser.current_block->param1.event = event; - eval( buffer.c_str(), 0, TOP ); + parser.eval( buffer.c_str(), 0, TOP ); parser.pop_block(); proc_pop_interactive(); proc_set_last_status( prev_status ); diff --git a/exec.cpp b/exec.cpp index 29d4eb66d..dfaf2de74 100644 --- a/exec.cpp +++ b/exec.cpp @@ -782,9 +782,10 @@ static io_data_t *io_transmogrify( io_data_t * in ) \param io the io redirections to be performed on this block */ -static void internal_exec_helper( const wchar_t *def, - enum block_type_t block_type, - io_data_t *io ) +static void internal_exec_helper( parser_t &parser, + const wchar_t *def, + enum block_type_t block_type, + io_data_t *io ) { io_data_t *io_internal = io_transmogrify( io ); int is_block_old=is_block; @@ -801,7 +802,7 @@ static void internal_exec_helper( const wchar_t *def, signal_unblock(); - eval( def, io_internal, block_type ); + parser.eval( def, io_internal, block_type ); signal_block(); @@ -945,7 +946,7 @@ static void do_builtin_io( wchar_t *out, wchar_t *err ) } -void exec( job_t *j ) +void exec( parser_t &parser, job_t *j ) { process_t *p; pid_t pid; @@ -979,15 +980,15 @@ void exec( job_t *j ) debug( 4, L"Exec job '%ls' with id %d", j->command, j->job_id ); - if( block_io ) + if( parser.block_io ) { if( j->io ) { - j->io = io_add( io_duplicate( j, block_io), j->io ); + j->io = io_add( io_duplicate( j, parser.block_io), j->io ); } else { - j->io=io_duplicate( j, block_io); + j->io=io_duplicate( j, parser.block_io); } } @@ -1207,11 +1208,10 @@ void exec( job_t *j ) debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] ); break; } - parser.push_block( shadows?FUNCTION_CALL:FUNCTION_CALL_NO_SHADOW ); parser.current_block->param2.function_call_process = p; - parser.current_block->param1.function_call_name = (wchar_t *)halloc_register( current_block, wcsdup( p->argv[0] ) ); + parser.current_block->param1.function_call_name = (wchar_t *)halloc_register( parser.current_block, wcsdup( p->argv[0] ) ); /* @@ -1223,7 +1223,7 @@ void exec( job_t *j ) parse_util_set_argv( p->argv+1, named_arguments ); signal_block(); - parser_forbid_function( p->argv[0] ); + parser.forbid_function( p->argv[0] ); if( p->next ) { @@ -1231,9 +1231,9 @@ void exec( job_t *j ) j->io = io_add( j->io, io_buffer ); } - internal_exec_helper( def, TOP, j->io ); + internal_exec_helper( parser, def, TOP, j->io ); - parser_allow_function(); + parser.allow_function(); parser.pop_block(); break; @@ -1246,8 +1246,8 @@ void exec( job_t *j ) io_buffer = io_buffer_create( 0 ); j->io = io_add( j->io, io_buffer ); } - - internal_exec_helper( p->argv[0], TOP, j->io ); + + internal_exec_helper( parser, p->argv[0], TOP, j->io ); break; } @@ -1370,7 +1370,7 @@ void exec( job_t *j ) to make exec handle things. */ - builtin_push_io( builtin_stdin ); + builtin_push_io( parser, builtin_stdin ); builtin_out_redirect = has_fd( j->io, 1 ); builtin_err_redirect = has_fd( j->io, 2 ); @@ -1380,7 +1380,7 @@ void exec( job_t *j ) signal_unblock(); - p->status = builtin_run( p->argv, j->io ); + p->status = builtin_run( parser, p->argv, j->io ); builtin_out_redirect=old_out; builtin_err_redirect=old_err; @@ -1658,7 +1658,7 @@ void exec( job_t *j ) } if( p->type == INTERNAL_BUILTIN ) - builtin_pop_io(); + builtin_pop_io(parser); /* Close the pipe the current process uses to read from the @@ -1701,7 +1701,7 @@ void exec( job_t *j ) j->io = io_remove( j->io, &pipe_read ); - for( tmp = block_io; tmp; tmp=tmp->next ) + for( tmp = parser.block_io; tmp; tmp=tmp->next ) j->io = io_remove( j->io, tmp ); job_set_flag( j, JOB_CONSTRUCTED, 1 ); @@ -1765,7 +1765,8 @@ int exec_subshell( const wchar_t *cmd, prev_status = proc_get_last_status(); - if( eval( cmd, io_buffer, SUBST ) ) + parser_t parser(PARSER_TYPE_GENERAL); + if( parser.eval( cmd, io_buffer, SUBST ) ) { status = -1; } diff --git a/exec.h b/exec.h index 00f7bac95..17d29157f 100644 --- a/exec.h +++ b/exec.h @@ -41,7 +41,8 @@ */ -void exec( job_t *j ); +class parser_t; +void exec( parser_t &parser, job_t *j ); /** Evaluate the expression cmd in a subshell, add the outputs into the diff --git a/expand.cpp b/expand.cpp index 7ec94ce51..561bdfba8 100644 --- a/expand.cpp +++ b/expand.cpp @@ -919,7 +919,7 @@ static int parse_slice2( const wchar_t *in, wchar_t **end_ptr, std::vector happens, don't edit it unless you know exactly what you are doing, and do proper testing afterwards. */ -static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) +static int expand_variables( parser_t &parser, wchar_t *in, array_list_t *out, int last_idx ) { wchar_t c; wchar_t prev_char=0; @@ -988,7 +988,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) if( var_len == 0 ) { - expand_variable_error( in, stop_pos-1, -1 ); + expand_variable_error( parser, in, stop_pos-1, -1 ); is_ok = 0; break; @@ -1010,7 +1010,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) if( parse_slice( &in[stop_pos], &slice_end, var_idx_list ) ) { - error( SYNTAX_ERROR, + parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); is_ok = 0; @@ -1039,7 +1039,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) */ if( tmp < 1 || tmp > al_get_count( &var_item_list ) ) { - error( SYNTAX_ERROR, + parser.error( SYNTAX_ERROR, -1, ARRAY_BOUNDS_ERR ); is_ok=0; @@ -1085,7 +1085,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) free( next ); } sb_append( &res, &in[stop_pos] ); - is_ok &= expand_variables( (wchar_t *)res.buff, out, i ); + is_ok &= expand_variables( parser, (wchar_t *)res.buff, out, i ); } else { @@ -1124,7 +1124,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) wcscat( new_in, next ); wcscat( new_in, &in[stop_pos] ); - is_ok &= expand_variables( new_in, out, i ); + is_ok &= expand_variables( parser, new_in, out, i ); } } free( next ); @@ -1163,7 +1163,7 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) sb_append( &res, in ); sb_append( &res, &in[stop_pos] ); - is_ok &= expand_variables( (wchar_t *)res.buff, out, i ); + is_ok &= expand_variables( parser, (wchar_t *)res.buff, out, i ); free(in); return is_ok; } @@ -1187,16 +1187,16 @@ static int expand_variables( wchar_t *in, array_list_t *out, int last_idx ) return is_ok; } -static int expand_variables2( const wcstring &in, std::vector &outputs, int last_idx ) +static int expand_variables2( parser_t &parser, const wcstring &in, std::vector &outputs, int last_idx ) { wcstring_adapter adapter(in, outputs); - return expand_variables(adapter.str, &adapter.lst, last_idx); + return expand_variables(parser, adapter.str, &adapter.lst, last_idx); } /** Perform bracket expansion */ -static int expand_brackets( wchar_t *in, int flags, array_list_t *out ) +static int expand_brackets( parser_t &parser, wchar_t *in, int flags, array_list_t *out ) { wchar_t *pos; int syntax_error=0; @@ -1270,13 +1270,13 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out ) sb_append_char( &mod, BRACKET_END ); } - return expand_brackets( (wchar_t*)mod.buff, 1, out ); + return expand_brackets( parser, (wchar_t*)mod.buff, 1, out ); } } if( syntax_error ) { - error( SYNTAX_ERROR, + parser.error( SYNTAX_ERROR, -1, _(L"Mismatched brackets") ); return 0; @@ -1306,7 +1306,7 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out ) wcslcpy( whole_item+len1, item_begin, item_len+1 ); wcscpy( whole_item+len1+item_len, bracket_end+1 ); - expand_brackets( whole_item, flags, out ); + expand_brackets( parser, whole_item, flags, out ); item_begin = pos+1; if( pos == bracket_end ) @@ -1328,16 +1328,16 @@ static int expand_brackets( wchar_t *in, int flags, array_list_t *out ) return 1; } -static int expand_brackets2( const wcstring &in, int flags, std::vector outputs ) +static int expand_brackets2( parser_t &parser, const wcstring &in, int flags, std::vector outputs ) { wcstring_adapter adapter(in, outputs); - return expand_brackets(adapter.str, flags, &adapter.lst); + return expand_brackets(parser, adapter.str, flags, &adapter.lst); } /** Perform cmdsubst expansion */ -static int expand_cmdsubst( wchar_t *in, array_list_t *out ) +static int expand_cmdsubst( parser_t &parser, wchar_t *in, array_list_t *out ) { wchar_t *paran_begin=0, *paran_end=0; int len1; @@ -1360,7 +1360,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) 0 ) ) { case -1: - error( SYNTAX_ERROR, + parser.error( SYNTAX_ERROR, -1, L"Mismatched parans" ); return 0; @@ -1391,7 +1391,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) if( exec_subshell( subcmd, sub_res) == -1 ) { halloc_free( context ); - error( CMDSUBST_ERROR, -1, L"Unknown error while evaulating command substitution" ); + parser.error( CMDSUBST_ERROR, -1, L"Unknown error while evaulating command substitution" ); return 0; } @@ -1404,7 +1404,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) if( parse_slice( tail_begin, &slice_end, slice_idx ) ) { halloc_free( context ); - error( SYNTAX_ERROR, -1, L"Invalid index value" ); + parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); return 0; } else @@ -1422,7 +1422,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) if( idx < 1 || idx > al_get_count( sub_res ) ) { halloc_free( context ); - error( SYNTAX_ERROR, -1, L"Invalid index value" ); + parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); return 0; } @@ -1445,7 +1445,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) substitutions. The result of this recursive call usiung the tail of the string is inserted into the tail_expand array list */ - expand_cmdsubst( wcsdup(tail_begin), tail_expand ); + expand_cmdsubst( parser, wcsdup(tail_begin), tail_expand ); /* Combine the result of the current command substitution with the @@ -1487,7 +1487,7 @@ static int expand_cmdsubst( wchar_t *in, array_list_t *out ) /** Perform cmdsubst expansion */ -static int expand_cmdsubst2( const wcstring &input, std::vector &outList ) +static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vector &outList ) { wchar_t *paran_begin=0, *paran_end=0; int len1; @@ -1505,7 +1505,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi 0 ) ) { case -1: - error( SYNTAX_ERROR, + parser.error( SYNTAX_ERROR, -1, L"Mismatched parans" ); return 0; @@ -1525,7 +1525,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi if( exec_subshell2( subcmd, sub_res) == -1 ) { - error( CMDSUBST_ERROR, -1, L"Unknown error while evaulating command substitution" ); + parser.error( CMDSUBST_ERROR, -1, L"Unknown error while evaulating command substitution" ); return 0; } @@ -1537,7 +1537,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi if( parse_slice2( tail_begin, &slice_end, slice_idx ) ) { - error( SYNTAX_ERROR, -1, L"Invalid index value" ); + parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); return 0; } else @@ -1554,7 +1554,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi if( idx < 1 || (size_t)idx > sub_res.size() ) { - error( SYNTAX_ERROR, -1, L"Invalid index value" ); + parser.error( SYNTAX_ERROR, -1, L"Invalid index value" ); return 0; } @@ -1575,7 +1575,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi of the string is inserted into the tail_expand array list */ std::vector tail_expand; - expand_cmdsubst2( tail_begin, tail_expand ); + expand_cmdsubst2( parser, tail_begin, tail_expand ); /* Combine the result of the current command substitution with the @@ -1619,11 +1619,11 @@ static int expand_cmdsubst2( const wcstring &input, std::vector &outLi /** Wrapper around unescape funtion. Issues an error() on failiure. */ -static wchar_t *expand_unescape( const wchar_t * in, int escape_special ) +static wchar_t *expand_unescape( parser_t &parser, const wchar_t * in, int escape_special ) { wchar_t *res = unescape( in, escape_special ); if( !res ) - error( SYNTAX_ERROR, -1, L"Unexpected end of string" ); + parser.error( SYNTAX_ERROR, -1, L"Unexpected end of string" ); return res; } @@ -1766,7 +1766,7 @@ static void remove_internal_separator2( wcstring &s, int conv ) } -int expand_string2( const wcstring &input, std::vector &output, int flags ) +int expand_string2( parser_t &parser, const wcstring &input, std::vector &output, int flags ) { std::vector list1, list2; std::vector *in, *out; @@ -1790,14 +1790,14 @@ int expand_string2( const wcstring &input, std::vector &output, int fl &end, 1 ) != 0 ) { - error( CMDSUBST_ERROR, -1, L"Command substitutions not allowed" ); + parser.error( CMDSUBST_ERROR, -1, L"Command substitutions not allowed" ); return EXPAND_ERROR; } list1.push_back(input); } else { - cmdsubst_ok = expand_cmdsubst2(input, list1); + cmdsubst_ok = expand_cmdsubst2(parser, input, list1); } if( !cmdsubst_ok ) @@ -1830,7 +1830,7 @@ int expand_string2( const wcstring &input, std::vector &output, int fl } else { - if(!expand_variables2( next, *out, next.size() - 1 )) + if(!expand_variables2( parser, next, *out, next.size() - 1 )) { return EXPAND_ERROR; } @@ -1846,7 +1846,7 @@ int expand_string2( const wcstring &input, std::vector &output, int fl { wcstring next = in->at(i); - if( !expand_brackets2( next, flags, *out )) + if( !expand_brackets2( parser, next, flags, *out )) { return EXPAND_ERROR; } @@ -1985,7 +1985,8 @@ int expand_string2( const wcstring &input, std::vector &output, int fl /** The real expansion function. expand_one is just a wrapper around this one. */ -int expand_string( void *context, +int expand_string( parser_t &parser, + void *context, wchar_t *str, array_list_t *end_out, int flags ) @@ -2020,7 +2021,7 @@ int expand_string( void *context, &end, 1 ) != 0 ) { - error( CMDSUBST_ERROR, -1, L"Command substitutions not allowed" ); + parser.error( CMDSUBST_ERROR, -1, L"Command substitutions not allowed" ); free( str ); al_destroy( &list1 ); al_destroy( &list2 ); @@ -2030,7 +2031,7 @@ int expand_string( void *context, } else { - cmdsubst_ok = expand_cmdsubst( str, &list1 ); + cmdsubst_ok = expand_cmdsubst( parser, str, &list1 ); } if( !cmdsubst_ok ) @@ -2054,7 +2055,7 @@ int expand_string( void *context, */ int unescape_flags = UNESCAPE_SPECIAL | UNESCAPE_INCOMPLETE; - next = expand_unescape( (wchar_t *)al_get( in, i ), unescape_flags ); + next = expand_unescape( parser, (wchar_t *)al_get( in, i ), unescape_flags ); free( (void *)al_get( in, i ) ); @@ -2074,7 +2075,7 @@ int expand_string( void *context, } else { - if(!expand_variables( next, out, wcslen(next)-1 )) + if(!expand_variables( parser, next, out, wcslen(next)-1 )) { al_destroy( in ); al_destroy( out ); @@ -2098,7 +2099,7 @@ int expand_string( void *context, continue; } - if( !expand_brackets( next, flags, out )) + if( !expand_brackets( parser, next, flags, out )) { al_destroy( in ); al_destroy( out ); diff --git a/expand.h b/expand.h index 4887c06b6..c9c3f138f 100644 --- a/expand.h +++ b/expand.h @@ -123,6 +123,7 @@ enum */ #define ARRAY_BOUNDS_ERR _(L"Array index out of bounds") +class parser_t; /** Perform various forms of expansion on in, such as tilde expansion diff --git a/fish.cpp b/fish.cpp index 54a444949..b37192b9a 100644 --- a/fish.cpp +++ b/fish.cpp @@ -77,7 +77,7 @@ static int read_init() wchar_t *config_dir_escaped; void *context; string_buffer_t *eval_buff; - parser_t parser(); + parser_t parser(PARSER_TYPE_GENERAL); parser.eval( L"builtin . " DATADIR "/fish/config.fish 2>/dev/null", 0, TOP ); parser.eval( L"builtin . " SYSCONFDIR L"/fish/config.fish 2>/dev/null", 0, TOP ); @@ -97,7 +97,7 @@ static int read_init() { config_dir_escaped = escape( config_dir, 1 ); sb_printf( eval_buff, L"builtin . %ls/config.fish 2>/dev/null", config_dir_escaped ); - eval( (wchar_t *)eval_buff->buff, 0, TOP ); + parser.eval( (wchar_t *)eval_buff->buff, 0, TOP ); free( config_dir_escaped ); } @@ -307,7 +307,7 @@ int main( int argc, char **argv ) proc_init(); event_init(); wutil_init(); - parser_init(); + //parser_init(); builtin_init(); function_init(); env_init(); @@ -318,8 +318,9 @@ int main( int argc, char **argv ) { if( cmd != 0 ) { + parser_t parser(PARSER_TYPE_GENERAL); wchar_t *cmd_wcs = str2wcs( cmd ); - res = eval( cmd_wcs, 0, TOP ); + res = parser.eval( cmd_wcs, 0, TOP ); free(cmd_wcs); reader_exit(0, 0); } diff --git a/parser.cpp b/parser.cpp index 30313d631..f681327db 100644 --- a/parser.cpp +++ b/parser.cpp @@ -401,32 +401,6 @@ static int parse_job( process_t *p, job_t *j, tokenizer *tok ); -/** - Struct used to keep track of profiling data for a command -*/ -typedef struct -{ - /** - Time spent executing the specified command, including parse time for nested blocks. - */ - int exec; - /** - Time spent parsing the specified command, including execution time for command substitutions. - */ - int parse; - /** - The block level of the specified command. nested blocks and command substitutions both increase the block level. - */ - int level; - /** - If the execution of this command was skipped. - */ - int skipped; - /** - The command string. - */ - wchar_t *cmd; -} profile_element_t; /** Return the current number of block nestings @@ -441,12 +415,12 @@ static int block_count( block_t *b ) } */ -void parser_push_block( int type ) +void parser_t::push_block( int type ) { block_t *newv = (block_t *)halloc( 0, sizeof( block_t )); - newv->src_lineno = parser_get_lineno(); - newv->src_filename = parser_current_filename()?intern(parser_current_filename()):0; + newv->src_lineno = parser_t::get_lineno(); + newv->src_filename = parser_t::current_filename()?intern(parser_t::current_filename()):0; newv->outer = current_block; newv->type = (current_block && current_block->skip)?FAKE:type; @@ -640,7 +614,7 @@ void parser_allow_function() forbidden_function.pop_back(); } -void error( int ec, int p, const wchar_t *str, ... ) +void parser_t::error( int ec, int p, const wchar_t *str, ... ) { va_list va; @@ -664,27 +638,27 @@ void error( int ec, int p, const wchar_t *str, ... ) /** Print profiling information to the specified stream */ -static void print_profile( array_list_t *p, - int pos, +static void print_profile( const std::vector &items, + size_t pos, FILE *out ) { - profile_element_t *me, *prev; - int i; + const profile_item_t *me, *prev; + size_t i; int my_time; - if( pos >= al_get_count( p ) ) + if( pos >= items.size() ) { return; } - me= (profile_element_t *)al_get( p, pos ); + me= &items.at(pos); if( !me->skipped ) { my_time=me->parse+me->exec; - for( i=pos+1; iskipped ) { continue; @@ -704,7 +678,7 @@ static void print_profile( array_list_t *p, my_time -= prev->exec; } - if( me->cmd ) + if( me->cmd.size() > 0 ) { if( fwprintf( out, L"%d\t%d\t", my_time, me->parse+me->exec ) < 0 ) { @@ -721,7 +695,7 @@ static void print_profile( array_list_t *p, } } - if( fwprintf( out, L"> %ls\n", me->cmd ) < 0 ) + if( fwprintf( out, L"> %ls\n", me->cmd.c_str() ) < 0 ) { wperror( L"fwprintf" ); return; @@ -729,12 +703,10 @@ static void print_profile( array_list_t *p, } } - print_profile( p, pos+1, out ); - free( me->cmd ); - free( me ); + print_profile( items, pos+1, out ); } -void parser_destroy() +void parser_t::destroy() { if( profile ) { @@ -758,7 +730,7 @@ void parser_destroy() } else { - print_profile( &profile_data, 0, f ); + print_profile( profile_items, 0, f ); } if( fclose( f ) ) @@ -785,7 +757,7 @@ void parser_destroy() \param target the buffer to write to \param prefix: The string token to prefix the ech line with. Usually the name of the command trying to parse something. */ -static void print_errors( string_buffer_t *target, const wchar_t *prefix ) +void parser_t::print_errors( string_buffer_t *target, const wchar_t *prefix ) { CHECK( target, ); CHECK( prefix, ); @@ -799,7 +771,7 @@ static void print_errors( string_buffer_t *target, const wchar_t *prefix ) tmp = current_tokenizer_pos; current_tokenizer_pos = err_pos; - sb_printf( target, L"%ls", parser_current_line() ); + sb_printf( target, L"%ls", this->current_line() ); current_tokenizer_pos=tmp; } @@ -808,7 +780,7 @@ static void print_errors( string_buffer_t *target, const wchar_t *prefix ) /** Print error message to stderr if an error has occured while parsing */ -static void print_errors_stderr() +static void print_errors_stderr(parser_t &parser) { if( error_code && err_buff ) { @@ -818,14 +790,14 @@ static void print_errors_stderr() tmp = current_tokenizer_pos; current_tokenizer_pos = err_pos; - fwprintf( stderr, L"%ls", parser_current_line() ); + fwprintf( stderr, L"%ls", parser.current_line() ); current_tokenizer_pos=tmp; } } -int eval_args( const wchar_t *line, array_list_t *args ) +int parser_t::eval_args( const wchar_t *line, array_list_t *args ) { tokenizer tok; /* @@ -897,7 +869,7 @@ int eval_args( const wchar_t *line, array_list_t *args ) } } - print_errors_stderr(); + print_errors_stderr(*this); tok_destroy( &tok ); @@ -1110,7 +1082,7 @@ static int printed_width( const wchar_t *str, int len ) } -const wchar_t *parser_current_line() +const wchar_t *parser_t::current_line() { int lineno=1; @@ -1273,7 +1245,7 @@ int parser_is_help( wchar_t *s, int min_match ) \param tok the tokenizer to read options from \param args the argument list to insert options into */ -static void parse_job_argument_list( process_t *p, +void parser_t::parse_job_argument_list( process_t *p, job_t *j, tokenizer *tok, array_list_t *args ) @@ -1637,7 +1609,7 @@ static void parse_job_argument_list( process_t *p, tmp = current_tokenizer_pos; current_tokenizer_pos = unmatched_pos; - fwprintf( stderr, L"%ls", parser_current_line() ); + fwprintf( stderr, L"%ls", parser_t::current_line() ); current_tokenizer_pos=tmp; } @@ -1668,7 +1640,7 @@ static void parse_job_argument_list( process_t *p, f \return 1 on success, 0 on error */ -static int parse_job( process_t *p, +int parser_t::parse_job( process_t *p, job_t *j, tokenizer *tok ) { @@ -1849,7 +1821,7 @@ static int parse_job( process_t *p, if( new_block ) { - parser.push_block( WHILE ); + this->push_block( WHILE ); current_block->param1.while_state=WHILE_TEST_FIRST; current_block->tok_pos = mark; } @@ -1862,7 +1834,7 @@ static int parse_job( process_t *p, { tok_next( tok ); - parser.push_block( IF ); + this->push_block( IF ); current_block->param1.if_state=0; current_block->tok_pos = mark; @@ -2070,7 +2042,7 @@ static int parse_job( process_t *p, tmp = current_tokenizer_pos; current_tokenizer_pos = tok_get_pos(tok); - fwprintf( stderr, L"%ls", parser_current_line() ); + fwprintf( stderr, L"%ls", parser_t::current_line() ); current_tokenizer_pos=tmp; @@ -2224,7 +2196,7 @@ static int parse_job( process_t *p, \param j the job to execute */ -static void skipped_exec( job_t * j ) +void parser_t::skipped_exec( job_t * j ) { process_t *p; @@ -2237,13 +2209,13 @@ static void skipped_exec( job_t * j ) ( wcscmp( p->argv[0], L"begin" )==0) || ( wcscmp( p->argv[0], L"function" )==0)) { - parser.push_block( FAKE ); + this->push_block( FAKE ); } else if( wcscmp( p->argv[0], L"end" )==0) { if(!current_block->outer->skip ) { - exec( j ); + exec( *this, j ); return; } parser_pop_block(); @@ -2253,7 +2225,7 @@ static void skipped_exec( job_t * j ) if( (current_block->type == IF ) && (current_block->param1.if_state != 0)) { - exec( j ); + exec( *this, j ); return; } } @@ -2261,7 +2233,7 @@ static void skipped_exec( job_t * j ) { if( (current_block->type == SWITCH ) ) { - exec( j ); + exec( *this, j ); return; } } @@ -2277,7 +2249,7 @@ static void skipped_exec( job_t * j ) \param tok The tokenizer to read tokens from */ -static void eval_job( parser_t &parser, tokenizer *tok ) +void parser_t::eval_job( tokenizer *tok ) { job_t *j; @@ -2291,8 +2263,8 @@ static void eval_job( parser_t &parser, tokenizer *tok ) if( profile ) { - parser.profile_items.resize(parser.profile_items.size() + 1); - profile_item = &parser.profile_items.back(); + profile_items.resize(profile_items.size() + 1); + profile_item = &profile_items.back(); profile_item->cmd = L""; profile_item->skipped = 1; t1 = get_time(); @@ -2365,7 +2337,7 @@ static void eval_job( parser_t &parser, tokenizer *tok ) // was_builtin = 1; prev_tokenizer_pos = current_tokenizer_pos; current_tokenizer_pos = job_begin_pos; - exec( j ); + exec( *this, j ); current_tokenizer_pos = prev_tokenizer_pos; /* Only external commands require a new fishd barrier */ @@ -2374,7 +2346,7 @@ static void eval_job( parser_t &parser, tokenizer *tok ) } else { - skipped_exec( j ); + this->skipped_exec( j ); } if( profile ) @@ -2479,8 +2451,9 @@ static void eval_job( parser_t &parser, tokenizer *tok ) } -int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) +int parser_t::eval( const wcstring &cmdStr, io_data_t *io, enum block_type_t block_type ) { + const wchar_t * const cmd = cmdStr.c_str(); size_t forbid_count; int code; tokenizer *previous_tokenizer=current_tokenizer; @@ -2523,7 +2496,7 @@ int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) eval_level++; - parser.push_block( block_type ); + this->push_block( block_type ); current_tokenizer = (tokenizer *)malloc( sizeof(tokenizer)); tok_init( current_tokenizer, cmd, 0 ); @@ -2537,7 +2510,7 @@ int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) !sanity_check() && !exit_status() ) { - eval_job( parser, current_tokenizer ); + this->eval_job( current_tokenizer ); event_fire( NULL ); } @@ -2566,9 +2539,9 @@ int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) L"%ls", parser_get_block_desc( current_block->type ) ); debug( 1, BLOCK_END_ERR_MSG ); - fwprintf( stderr, L"%ls", parser_current_line() ); + fwprintf( stderr, L"%ls", parser_t::current_line() ); - h = builtin_help_get( L"end" ); + h = builtin_help_get( *this, L"end" ); if( h ) fwprintf( stderr, L"%ls", h ); break; @@ -2578,7 +2551,7 @@ int eval( const wchar_t *cmd, io_data_t *io, enum block_type_t block_type ) parser_pop_block(); } - print_errors_stderr(); + print_errors_stderr(*this); tok_destroy( current_tokenizer ); free( current_tokenizer ); @@ -2642,7 +2615,7 @@ const wchar_t *parser_get_block_command( int type ) syntax errors in command substitutions, improperly escaped characters and improper use of the variable expansion operator. */ -static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ) +int parser_t::parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ) { wchar_t *unesc; wchar_t *pos; @@ -2670,7 +2643,7 @@ static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const error( SYNTAX_ERROR, offset, L"Mismatched parans" ); - print_errors( out, prefix); + this->print_errors( out, prefix); } free( arg_cpy ); return 1; @@ -2741,7 +2714,7 @@ static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const err=1; if( out ) { - expand_variable_error( unesc, pos-unesc, offset ); + expand_variable_error( *this, unesc, pos-unesc, offset ); print_errors( out, prefix); } } @@ -2759,7 +2732,7 @@ static int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const } -int parser_test_args(const wchar_t * buff, +int parser_t::parser_test_args(const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ) { tokenizer tok; @@ -2833,7 +2806,7 @@ int parser_test_args(const wchar_t * buff, return err; } -int parser_test( const wchar_t * buff, +int parser_t::parser_test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix ) @@ -3087,7 +3060,7 @@ int parser_test( const wchar_t * buff, INVALID_CASE_ERR_MSG ); print_errors( out, prefix); - h = builtin_help_get( L"case" ); + h = builtin_help_get( *this, L"case" ); if( h ) sb_printf( out, L"%ls", h ); } @@ -3249,7 +3222,7 @@ int parser_test( const wchar_t * buff, tok_get_pos( &tok ), INVALID_END_ERR_MSG ); print_errors( out, prefix ); - h = builtin_help_get( L"end" ); + h = builtin_help_get( *this, L"end" ); if( h ) sb_printf( out, L"%ls", h ); } @@ -3535,7 +3508,7 @@ int parser_test( const wchar_t * buff, cmd = parser_get_block_command( block_type[count -1] ); if( cmd ) { - h = builtin_help_get( cmd ); + h = builtin_help_get( *this, cmd ); if( cmd ) { sb_printf( out, L"%ls", h ); diff --git a/parser.h b/parser.h index db26398e0..1f57829d3 100644 --- a/parser.h +++ b/parser.h @@ -199,7 +199,7 @@ struct profile_item_t { /** The block level of the specified command. nested blocks and command substitutions both increase the block level. */ - int level; + size_t level; /** If the execution of this command was skipped. */ @@ -210,6 +210,8 @@ struct profile_item_t { wcstring cmd; }; +struct tokenizer; + class parser_t { private: std::vector blocks; @@ -218,6 +220,15 @@ class parser_t { parser_t(const parser_t&); parser_t& operator=(const parser_t&); + void parse_job_argument_list( process_t *p, job_t *j, tokenizer *tok, array_list_t *args ); + int parse_job( process_t *p, job_t *j, tokenizer *tok ); + void skipped_exec( job_t * j ); + void eval_job( tokenizer *tok ); + int parser_test_argument( const wchar_t *arg, string_buffer_t *out, const wchar_t *prefix, int offset ); + int parser_test( const wchar_t * buff, int *block_level, string_buffer_t *out, const wchar_t *prefix ); + int parser_test_args(const wchar_t * buff, string_buffer_t *out, const wchar_t *prefix ); + void print_errors( string_buffer_t *target, const wchar_t *prefix ); + public: std::vector profile_items; @@ -231,7 +242,7 @@ class parser_t { event_block_t *global_event_block; /** Current block level io redirections */ - io_data_t &block_io(void) const; + io_data_t *block_io; /** Evaluate the expressions contained in cmd. @@ -268,7 +279,7 @@ class parser_t { init.fish (line 127): ls|grep pancake */ - const wchar_t *current_line() const; + const wchar_t *current_line(); /** Returns the current line number diff --git a/tokenizer.h b/tokenizer.h index ad683d7e5..687fd77c4 100644 --- a/tokenizer.h +++ b/tokenizer.h @@ -62,7 +62,7 @@ enum tokenizer_error /** The tokenizer struct. */ -typedef struct +struct tokenizer { /** A pointer into the original string, showing where the next token begins */ wchar_t *buff; @@ -89,8 +89,7 @@ typedef struct wchar_t last_quote; /** Last error */ int error; -} -tokenizer; +}; /** Initialize the tokenizer. b is the string that is to be