Removed discriminated union from block_t type, allowing us to store wcstrings in it

This commit is contained in:
ridiculousfish 2012-02-07 17:06:45 -08:00
parent e8af86017a
commit a0a43046b3
12 changed files with 156 additions and 93 deletions

View file

@ -65,7 +65,7 @@
D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal_common.cpp; sourceTree = "<group>"; }; D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal_common.cpp; sourceTree = "<group>"; };
D0A0853913B3ACEE0099B651 /* env_universal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal.cpp; sourceTree = "<group>"; }; D0A0853913B3ACEE0099B651 /* env_universal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env_universal.cpp; sourceTree = "<group>"; };
D0A0853A13B3ACEE0099B651 /* env.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env.cpp; sourceTree = "<group>"; }; D0A0853A13B3ACEE0099B651 /* env.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = env.cpp; sourceTree = "<group>"; };
D0A0853B13B3ACEE0099B651 /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = event.cpp; sourceTree = "<group>"; }; D0A0853B13B3ACEE0099B651 /* event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = event.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
D0A0853C13B3ACEE0099B651 /* exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec.cpp; sourceTree = "<group>"; }; D0A0853C13B3ACEE0099B651 /* exec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = exec.cpp; sourceTree = "<group>"; };
D0A0853D13B3ACEE0099B651 /* expand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expand.cpp; sourceTree = "<group>"; }; D0A0853D13B3ACEE0099B651 /* expand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = expand.cpp; sourceTree = "<group>"; };
D0A0853E13B3ACEE0099B651 /* fallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fallback.cpp; sourceTree = "<group>"; }; D0A0853E13B3ACEE0099B651 /* fallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fallback.cpp; sourceTree = "<group>"; };
@ -90,7 +90,7 @@
D0A0855113B3ACEE0099B651 /* output.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = output.cpp; sourceTree = "<group>"; }; D0A0855113B3ACEE0099B651 /* output.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = output.cpp; sourceTree = "<group>"; };
D0A0855213B3ACEE0099B651 /* parse_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_util.cpp; sourceTree = "<group>"; }; D0A0855213B3ACEE0099B651 /* parse_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parse_util.cpp; sourceTree = "<group>"; };
D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_keywords.cpp; sourceTree = "<group>"; }; D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser_keywords.cpp; sourceTree = "<group>"; };
D0A0855413B3ACEE0099B651 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = parser.cpp; sourceTree = "<group>"; }; D0A0855413B3ACEE0099B651 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = parser.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
D0A0855513B3ACEE0099B651 /* path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = path.cpp; sourceTree = "<group>"; }; D0A0855513B3ACEE0099B651 /* path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = path.cpp; sourceTree = "<group>"; };
D0A0855613B3ACEE0099B651 /* print_help.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = print_help.cpp; sourceTree = "<group>"; }; D0A0855613B3ACEE0099B651 /* print_help.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = print_help.cpp; sourceTree = "<group>"; };
D0A0855713B3ACEE0099B651 /* proc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = proc.cpp; sourceTree = "<group>"; }; D0A0855713B3ACEE0099B651 /* proc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = proc.cpp; sourceTree = "<group>"; };

View file

@ -415,20 +415,13 @@ static void builtin_bind_list()
*/ */
static void builtin_bind_key_names( int all ) static void builtin_bind_key_names( int all )
{ {
array_list_t lst; const wcstring_list_t names = input_terminfo_get_names(!all);
int i; for( size_t i=0; i<names.size(); i++ )
al_init( &lst );
input_terminfo_get_names( &lst, !all );
for( i=0; i<al_get_count(&lst); i++ )
{ {
wchar_t *seq = (wchar_t *)al_get( &lst, i ); const wcstring &name = names.at(i);
sb_printf( sb_out, L"%ls\n", seq ); sb_printf( sb_out, L"%ls\n", name.c_str() );
} }
al_destroy( &lst );
} }
/** /**
@ -1091,14 +1084,12 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
const wchar_t *desc = function_get_desc( name ); const wchar_t *desc = function_get_desc( name );
const wchar_t *def = function_get_definition(name); const wchar_t *def = function_get_definition(name);
array_list_t ev;
event_t search; event_t search;
int i;
search.function_name = name; search.function_name = name;
search.type = EVENT_ANY; search.type = EVENT_ANY;
al_init( &ev ); std::vector<event_t *> ev;
event_get( &search, &ev ); event_get( &search, &ev );
sb_append( out, sb_append( out,
@ -1119,9 +1110,9 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
sb_append( out, L" --no-scope-shadowing", NULL ); sb_append( out, L" --no-scope-shadowing", NULL );
} }
for( i=0; i<al_get_count( &ev); i++ ) for( size_t i=0; i<ev.size(); i++ )
{ {
event_t *next = (event_t *)al_get( &ev, i ); event_t *next = ev.at(i);
switch( next->type ) switch( next->type )
{ {
case EVENT_SIGNAL: case EVENT_SIGNAL:
@ -1163,13 +1154,12 @@ static void functions_def( wchar_t *name, string_buffer_t *out )
} }
al_destroy( &ev );
wcstring_list_t named = function_get_named_arguments( name ); wcstring_list_t named = function_get_named_arguments( name );
if( named.size() > 0 ) if( named.size() > 0 )
{ {
sb_printf( out, L" --argument" ); sb_printf( out, L" --argument" );
for( i=0; i<(int)named.size(); i++ ) for( size_t i=0; i < named.size(); i++ )
{ {
sb_printf( out, L" %ls", named.at(i).c_str() ); sb_printf( out, L" %ls", named.at(i).c_str() );
} }
@ -2835,7 +2825,7 @@ static int builtin_source( parser_t &parser, wchar_t ** argv )
parser.push_block( SOURCE ); parser.push_block( SOURCE );
reader_push_current_filename( fn_intern ); reader_push_current_filename( fn_intern );
parser.current_block->param1.source_dest = fn_intern; parser.current_block->state1<const wchar_t *>() = fn_intern;
parse_util_set_argv( (argc>2)?(argv+2):(argv+1), wcstring_list_t()); parse_util_set_argv( (argc>2)?(argv+2):(argv+1), wcstring_list_t());
@ -3173,21 +3163,19 @@ static int builtin_for( parser_t &parser, wchar_t **argv )
else else
{ {
parser.push_block( FOR ); parser.push_block( FOR );
al_init( &parser.current_block->param2.for_vars);
int i; int i;
const wcstring for_variable = argv[1];
parser.current_block->tok_pos = parser.get_pos(); parser.current_block->tok_pos = parser.get_pos();
parser.current_block->param1.for_variable = halloc_wcsdup( parser.current_block, argv[1] ); parser.current_block->state1<wcstring>() = for_variable;
wcstring_list_t &for_vars = parser.current_block->state2<wcstring_list_t>();
for( i=argc-1; i>3; i-- ) for( i=argc-1; i>3; i-- )
{ for_vars.push_back(argv[i]);
al_push( &parser.current_block->param2.for_vars, halloc_wcsdup( parser.current_block, argv[ i ] ) );
}
halloc_register( parser.current_block, parser.current_block->param2.for_vars.arr );
if( argc > 3 ) if( argc > 3 )
{ {
env_set( parser.current_block->param1.for_variable, argv[3], ENV_LOCAL ); env_set( for_variable.c_str(), argv[3], ENV_LOCAL );
} }
else else
{ {
@ -3247,7 +3235,7 @@ static int builtin_end( parser_t &parser, wchar_t **argv )
parser.current_block->skip = 0; parser.current_block->skip = 0;
kill_block = 0; kill_block = 0;
parser.set_pos( parser.current_block->tok_pos); parser.set_pos( parser.current_block->tok_pos);
parser.current_block->param1.while_state = WHILE_TEST_AGAIN; parser.current_block->state1<int>() = WHILE_TEST_AGAIN;
} }
break; break;
@ -3267,15 +3255,18 @@ static int builtin_end( parser_t &parser, wchar_t **argv )
/* /*
set loop variable to next element, and rewind to the beginning of the block. set loop variable to next element, and rewind to the beginning of the block.
*/ */
wcstring_list_t &for_vars = parser.current_block->state2<wcstring_list_t>();
if( parser.current_block->loop_status == LOOP_BREAK ) if( parser.current_block->loop_status == LOOP_BREAK )
{ {
al_truncate( &parser.current_block->param2.for_vars, 0 ); for_vars.clear();
} }
if( al_get_count( &parser.current_block->param2.for_vars ) ) if( ! for_vars.empty() )
{ {
wchar_t *val = (wchar_t *)al_pop( &parser.current_block->param2.for_vars ); const wcstring val = for_vars.back();
env_set( parser.current_block->param1.for_variable, val, ENV_LOCAL); for_vars.pop_back();
const wcstring for_variable = parser.current_block->state1<wcstring>();
env_set( for_variable.c_str(), val.c_str(), ENV_LOCAL);
parser.current_block->loop_status = LOOP_NORMAL; parser.current_block->loop_status = LOOP_NORMAL;
parser.current_block->skip = 0; parser.current_block->skip = 0;
@ -3336,7 +3327,7 @@ static int builtin_else( parser_t &parser, wchar_t **argv )
{ {
if( parser.current_block == 0 || if( parser.current_block == 0 ||
parser.current_block->type != IF || parser.current_block->type != IF ||
parser.current_block->param1.if_state != 1) parser.current_block->state1<int>() != 1)
{ {
sb_printf( sb_err, sb_printf( sb_err,
_( L"%ls: Not inside of 'if' block\n" ), _( L"%ls: Not inside of 'if' block\n" ),
@ -3346,7 +3337,8 @@ static int builtin_else( parser_t &parser, wchar_t **argv )
} }
else else
{ {
parser.current_block->param1.if_state++; int &if_state = parser.current_block->state1<int>();
if_state++;
parser.current_block->skip = !parser.current_block->skip; parser.current_block->skip = !parser.current_block->skip;
env_pop(); env_pop();
env_push(0); env_push(0);
@ -3517,9 +3509,9 @@ static int builtin_switch( parser_t &parser, wchar_t **argv )
else else
{ {
parser.push_block( SWITCH ); parser.push_block( SWITCH );
parser.current_block->param1.switch_value = halloc_wcsdup( parser.current_block, argv[1]); parser.current_block->state1<wcstring>() = argv[1];
parser.current_block->skip=1; parser.current_block->skip=1;
parser.current_block->param2.switch_taken=0; parser.current_block->state2<int>() = 0;
} }
return res; return res;
@ -3546,7 +3538,7 @@ static int builtin_case( parser_t &parser, wchar_t **argv )
parser.current_block->skip = 1; parser.current_block->skip = 1;
if( parser.current_block->param2.switch_taken ) if( parser.current_block->state2<int>() )
{ {
return STATUS_BUILTIN_OK; return STATUS_BUILTIN_OK;
} }
@ -3556,13 +3548,14 @@ static int builtin_case( parser_t &parser, wchar_t **argv )
int match; int match;
unescaped = parse_util_unescape_wildcards( argv[i] ); unescaped = parse_util_unescape_wildcards( argv[i] );
match = wildcard_match( parser.current_block->param1.switch_value, unescaped ); const wcstring &switch_value = parser.current_block->state1<wcstring>();
match = wildcard_match( switch_value, unescaped );
free( unescaped ); free( unescaped );
if( match ) if( match )
{ {
parser.current_block->skip = 0; parser.current_block->skip = 0;
parser.current_block->param2.switch_taken = 1; parser.current_block->state2<int>() = 1;
break; break;
} }
} }

View file

@ -822,10 +822,6 @@ static int builtin_set( parser_t &parser, wchar_t **argv )
std::vector<long> indexes; std::vector<long> indexes;
wcstring_list_t result; wcstring_list_t result;
// al_init(&values);
// al_init(&indexes);
// al_init(&result);
const env_var_t dest_str = env_get_string(dest); const env_var_t dest_str = env_get_string(dest);
if (! dest_str.missing()) if (! dest_str.missing())
tokenize_variable_array2( dest_str, result ); tokenize_variable_array2( dest_str, result );

View file

@ -336,7 +336,7 @@ void event_remove( event_t *criterion )
events.swap(new_list); events.swap(new_list);
} }
int event_get( event_t *criterion, array_list_t *out ) int event_get( event_t *criterion, std::vector<event_t *> *out )
{ {
size_t i; size_t i;
int found = 0; int found = 0;
@ -353,7 +353,7 @@ int event_get( event_t *criterion, array_list_t *out )
{ {
found++; found++;
if( out ) if( out )
al_push( out, n ); out->push_back(n);
} }
} }
return found; return found;
@ -461,7 +461,7 @@ static void event_fire_internal( event_t *event )
prev_status = proc_get_last_status(); prev_status = proc_get_last_status();
parser_t &parser = parser_t::principal_parser(); parser_t &parser = parser_t::principal_parser();
parser.push_block( EVENT ); parser.push_block( EVENT );
parser.current_block->param1.event = event; parser.current_block->state1<event_t *>() = event;
parser.eval( buffer.c_str(), 0, TOP ); parser.eval( buffer.c_str(), 0, TOP );
parser.pop_block(); parser.pop_block();
proc_pop_interactive(); proc_pop_interactive();

View file

@ -121,7 +121,7 @@ void event_remove( event_t *event );
\return the number of found matches \return the number of found matches
*/ */
int event_get( event_t *criterion, array_list_t *out ); int event_get( event_t *criterion, std::vector<event_t *> *out );
/** /**
Fire the specified event. The function_name field of the event must Fire the specified event. The function_name field of the event must

View file

@ -1196,8 +1196,8 @@ void exec( parser_t &parser, job_t *j )
} }
parser.push_block( shadows?FUNCTION_CALL:FUNCTION_CALL_NO_SHADOW ); parser.push_block( shadows?FUNCTION_CALL:FUNCTION_CALL_NO_SHADOW );
parser.current_block->param2.function_call_process = p; parser.current_block->state2<process_t *>() = p;
parser.current_block->param1.function_call_name = (wchar_t *)halloc_register( parser.current_block, wcsdup( p->argv0() ) ); parser.current_block->state1<wcstring>() = p->argv0();
/* /*

View file

@ -816,14 +816,14 @@ bool input_terminfo_get_name( const wcstring &seq, wcstring &name )
return false; return false;
} }
void input_terminfo_get_names( array_list_t *lst, int skip_null ) wcstring_list_t input_terminfo_get_names( bool skip_null )
{ {
int i; wcstring_list_t result;
result.reserve(al_get_count(terminfo_mappings));
CHECK( lst, );
input_init(); input_init();
for( i=0; i<al_get_count( terminfo_mappings ); i++ ) for( int i=0; i<al_get_count( terminfo_mappings ); i++ )
{ {
terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i ); terminfo_mapping_t *m = (terminfo_mapping_t *)al_get( terminfo_mappings, i );
@ -831,8 +831,9 @@ void input_terminfo_get_names( array_list_t *lst, int skip_null )
{ {
continue; continue;
} }
al_push( lst, m->name ); result.push_back(wcstring(m->name));
} }
return result;
} }
wcstring_list_t input_function_get_names( void ) wcstring_list_t input_function_get_names( void )

View file

@ -124,10 +124,8 @@ const wchar_t *input_terminfo_get_sequence( const wchar_t *name );
*/ */
bool input_terminfo_get_name( const wcstring &seq, wcstring &name ); bool input_terminfo_get_name( const wcstring &seq, wcstring &name );
/** /** Return a list of all known terminfo names */
Return a list of all known terminfo names wcstring_list_t input_terminfo_get_names( bool skip_null );
*/
void input_terminfo_get_names( array_list_t *lst, int skip_null );
/** /**

View file

@ -396,7 +396,11 @@ static int block_count( block_t *b )
void parser_t::push_block( int type ) void parser_t::push_block( int type )
{ {
block_t *newv = (block_t *)halloc( 0, sizeof( block_t )); // block_t zerod = {};
// block_t *newv = new block_t(zerod);
void *buffer = halloc( 0, sizeof( block_t ));
bzero(buffer, sizeof(block_t));
block_t *newv = new(buffer) block_t();
newv->src_lineno = parser_t::get_lineno(); newv->src_lineno = parser_t::get_lineno();
newv->src_filename = parser_t::current_filename()?intern(parser_t::current_filename()):0; newv->src_filename = parser_t::current_filename()?intern(parser_t::current_filename()):0;
@ -437,7 +441,7 @@ void parser_t::push_block( int type )
(newv->type != TOP) ) (newv->type != TOP) )
{ {
env_push( type == FUNCTION_CALL ); env_push( type == FUNCTION_CALL );
halloc_register_function_void( current_block, &env_pop ); newv->wants_pop_env = true;
} }
} }
@ -454,7 +458,12 @@ void parser_t::pop_block()
} }
current_block = current_block->outer; current_block = current_block->outer;
halloc_free( old );
if (old->wants_pop_env)
env_pop();
old->~block_t();
halloc_free(old);
} }
const wchar_t *parser_t::get_block_desc( int block ) const const wchar_t *parser_t::get_block_desc( int block ) const
@ -873,7 +882,7 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
/* /*
This is an event handler This is an event handler
*/ */
sb_printf( buff, _(L"in event handler: %ls\n"), event_get_desc( b->param1.event )); sb_printf( buff, _(L"in event handler: %ls\n"), event_get_desc( b->state1<event_t *>() ));
sb_printf( buff, sb_printf( buff,
L"\n" ); L"\n" );
@ -900,12 +909,14 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
{ {
case SOURCE: case SOURCE:
{ {
sb_printf( buff, _(L"in . (source) call of file '%ls',\n"), b->param1.source_dest ); const wcstring &source_dest = b->state1<wcstring>();
sb_printf( buff, _(L"in . (source) call of file '%ls',\n"), source_dest.c_str() );
break; break;
} }
case FUNCTION_CALL: case FUNCTION_CALL:
{ {
sb_printf( buff, _(L"in function '%ls',\n"), b->param1.function_call_name ); const wcstring &function_call_name = b->state1<wcstring>();
sb_printf( buff, _(L"in function '%ls',\n"), function_call_name.c_str() );
break; break;
} }
case SUBST: case SUBST:
@ -932,14 +943,15 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
if( b->type == FUNCTION_CALL ) if( b->type == FUNCTION_CALL )
{ {
if( b->param2.function_call_process->argv(1) ) const process_t * const process = b->state2<process_t*>();
if( process->argv(1) )
{ {
string_buffer_t tmp; string_buffer_t tmp;
sb_init( &tmp ); sb_init( &tmp );
for( i=1; b->param2.function_call_process->argv(i); i++ ) for( i=1; process->argv(i); i++ )
{ {
sb_append( &tmp, i>1?L" ":L"", b->param2.function_call_process->argv(i), NULL ); sb_append( &tmp, i>1?L" ":L"", process->argv(i), NULL );
} }
sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff ); sb_printf( buff, _(L"\twith parameter list '%ls'\n"), (wchar_t *)tmp.buff );
@ -965,16 +977,21 @@ void parser_t::stack_trace( block_t *b, string_buffer_t *buff)
*/ */
const wchar_t *parser_t::is_function() const const wchar_t *parser_t::is_function() const
{ {
// PCA: Have to make this a string somehow
ASSERT_IS_MAIN_THREAD();
wcstring result;
block_t *b = current_block; block_t *b = current_block;
while( 1 ) while( 1 )
{ {
if( !b ) if( !b )
{ {
return 0; return NULL;
} }
if( b->type == FUNCTION_CALL ) if( b->type == FUNCTION_CALL )
{ {
return b->param1.function_call_name; result = b->state1<wcstring>();
return result.c_str();
} }
b=b->outer; b=b->outer;
} }
@ -1026,7 +1043,8 @@ const wchar_t *parser_t::current_filename() const
} }
if( b->type == FUNCTION_CALL ) if( b->type == FUNCTION_CALL )
{ {
return function_get_definition_file(b->param1.function_call_name ); wcstring function_call_name = b->state1<wcstring>();
return function_get_definition_file(function_call_name.c_str());
} }
b=b->outer; b=b->outer;
} }
@ -1784,9 +1802,9 @@ int parser_t::parse_job( process_t *p,
{ {
new_block = 1; new_block = 1;
} }
else if( current_block->param1.while_state == WHILE_TEST_AGAIN ) else if( current_block->state1<int>() == WHILE_TEST_AGAIN )
{ {
current_block->param1.while_state = WHILE_TEST_FIRST; current_block->state1<int>() = WHILE_TEST_FIRST;
} }
else else
{ {
@ -1796,7 +1814,7 @@ int parser_t::parse_job( process_t *p,
if( new_block ) if( new_block )
{ {
this->push_block( WHILE ); this->push_block( WHILE );
current_block->param1.while_state=WHILE_TEST_FIRST; current_block->state1<int>() = WHILE_TEST_FIRST;
current_block->tok_pos = mark; current_block->tok_pos = mark;
} }
@ -1810,7 +1828,7 @@ int parser_t::parse_job( process_t *p,
this->push_block( IF ); this->push_block( IF );
current_block->param1.if_state=0; current_block->state1<int>()=0;
current_block->tok_pos = mark; current_block->tok_pos = mark;
is_new_block=1; is_new_block=1;
@ -2193,7 +2211,7 @@ void parser_t::skipped_exec( job_t * j )
else if( wcscmp( p->argv0(), L"else" )==0) else if( wcscmp( p->argv0(), L"else" )==0)
{ {
if( (current_block->type == IF ) && if( (current_block->type == IF ) &&
(current_block->param1.if_state != 0)) (current_block->state1<int>() != 0))
{ {
exec( *this, j ); exec( *this, j );
return; return;
@ -2328,12 +2346,12 @@ void parser_t::eval_job( tokenizer *tok )
if( current_block->type == WHILE ) if( current_block->type == WHILE )
{ {
switch( current_block->param1.while_state ) switch( current_block->state1<int>() )
{ {
case WHILE_TEST_FIRST: case WHILE_TEST_FIRST:
{ {
current_block->skip = proc_get_last_status()!= 0; current_block->skip = proc_get_last_status()!= 0;
current_block->param1.while_state=WHILE_TESTED; current_block->state1<int>()=WHILE_TESTED;
} }
break; break;
} }
@ -2341,11 +2359,11 @@ void parser_t::eval_job( tokenizer *tok )
if( current_block->type == IF ) if( current_block->type == IF )
{ {
if( (!current_block->param1.if_state) && if( (!current_block->state1<int>()) &&
(!current_block->skip) ) (!current_block->skip) )
{ {
current_block->skip = proc_get_last_status()!= 0; current_block->skip = proc_get_last_status()!= 0;
current_block->param1.if_state++; current_block->state1<int>()++;
} }
} }

View file

@ -35,10 +35,20 @@ typedef struct event_block
The next event_block struct The next event_block struct
*/ */
struct event_block *next; struct event_block *next;
} } event_block_t;
event_block_t;
/** Block state template, to replace the discriminated union */
struct block_state_base_t {
public:
virtual ~block_state_base_t() {}
};
template<typename T>
struct block_state_t : public block_state_base_t {
T value;
block_state_t() : value() {}
};
/** /**
block_t represents a block of commands. block_t represents a block of commands.
@ -65,9 +75,7 @@ typedef struct block
*/ */
void *data; void *data;
/** #if 0
First block type specific variable
*/
union union
{ {
int while_state; /**< True if the loop condition has not yet been evaluated*/ int while_state; /**< True if the loop condition has not yet been evaluated*/
@ -78,7 +86,42 @@ typedef struct block
event_t *event; /**<The event that triggered this block */ event_t *event; /**<The event that triggered this block */
wchar_t *function_call_name; wchar_t *function_call_name;
} param1; } param1;
#endif
/** First block type specific variable */
block_state_base_t *state1_ptr;
template<typename T>
T& state1(void) {
block_state_t<T> *state;
if (state1_ptr == NULL) {
state = new block_state_t<T>();
state1_ptr = state;
} else {
state = dynamic_cast<block_state_t<T> *>(state1_ptr);
assert(state != NULL);
}
return state->value;
}
/** Second block type specific variable */
block_state_base_t *state2_ptr;
template<typename T>
T& state2(void) {
block_state_t<T> *state;
if (state2_ptr == NULL) {
state = new block_state_t<T>();
state2_ptr = state;
} else {
state = dynamic_cast<block_state_t<T> *>(state2_ptr);
assert(state != NULL);
}
return state->value;
}
#if 0
/** /**
Second block type specific variable Second block type specific variable
*/ */
@ -88,6 +131,7 @@ typedef struct block
int switch_taken; /**< Whether a switch match has already been found */ int switch_taken; /**< Whether a switch match has already been found */
process_t *function_call_process; /**< The process representing this function call */ process_t *function_call_process; /**< The process representing this function call */
} param2; } param2;
#endif
/** /**
@ -99,6 +143,9 @@ typedef struct block
Line number where this block was created Line number where this block was created
*/ */
int src_lineno; int src_lineno;
/** Whether we should pop the environment variable stack when we're popped */
bool wants_pop_env;
/** /**
Some naming confusion. This is a pointer to the first element in the list of all event blocks. Some naming confusion. This is a pointer to the first element in the list of all event blocks.
@ -108,7 +155,16 @@ typedef struct block
/** /**
Next outer block Next outer block
*/ */
struct block *outer; struct block *outer;
/** Destructor */
~block()
{
if (state1_ptr != NULL)
delete state1_ptr;
if (state2_ptr != NULL)
delete state2_ptr;
}
} block_t; } block_t;
/** /**
@ -278,7 +334,7 @@ class parser_t {
/** Create a parser of the given type */ /** Create a parser of the given type */
parser_t(enum parser_type_t type); parser_t(enum parser_type_t type);
/** The current innermost block */ /** The current innermost block, allocated with new */
block_t *current_block; block_t *current_block;
/** Global event blocks */ /** Global event blocks */

View file

@ -153,10 +153,12 @@ int wildcard_has( const wchar_t *str, int internal )
\param wc The wildcard. \param wc The wildcard.
\param is_first Whether files beginning with dots should not be matched against wildcards. \param is_first Whether files beginning with dots should not be matched against wildcards.
*/ */
static int wildcard_match2( const wchar_t *str, static int wildcard_match2( const wcstring &str_str,
const wchar_t *wc, const wcstring &wc_str,
int is_first ) int is_first )
{ {
const wchar_t *str = str_str.c_str();
const wchar_t *wc = wc_str.c_str();
if( *str == 0 && *wc==0 ) if( *str == 0 && *wc==0 )
return 1; return 1;
@ -329,7 +331,7 @@ int wildcard_complete( const wchar_t *str,
} }
int wildcard_match( const wchar_t *str, const wchar_t *wc ) int wildcard_match( const wcstring &str, const wcstring &wc )
{ {
return wildcard_match2( str, wc, 1 ); return wildcard_match2( str, wc, 1 );
} }

View file

@ -79,8 +79,7 @@ int wildcard_expand_string(const wcstring &wc, const wcstring &base_dir, int fla
\param wc The wildcard to test against \param wc The wildcard to test against
\return true if the wildcard matched \return true if the wildcard matched
*/ */
int wildcard_match( const wchar_t *str, int wildcard_match( const wcstring &str, const wcstring &wc );
const wchar_t *wc );
/** /**