mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
More work on the instanced parser
This commit is contained in:
parent
7e486e3b5c
commit
da85bdc401
10 changed files with 145 additions and 157 deletions
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
|
35
exec.cpp
35
exec.cpp
|
@ -782,7 +782,8 @@ 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,
|
||||
static void internal_exec_helper( parser_t &parser,
|
||||
const wchar_t *def,
|
||||
enum block_type_t block_type,
|
||||
io_data_t *io )
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -1247,7 +1247,7 @@ void exec( job_t *j )
|
|||
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;
|
||||
}
|
||||
|
|
3
exec.h
3
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
|
||||
|
|
81
expand.cpp
81
expand.cpp
|
@ -919,7 +919,7 @@ static int parse_slice2( const wchar_t *in, wchar_t **end_ptr, std::vector<long>
|
|||
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<wcstring> &outputs, int last_idx )
|
||||
static int expand_variables2( parser_t &parser, const wcstring &in, std::vector<wcstring> &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<wcstring> outputs )
|
||||
static int expand_brackets2( parser_t &parser, const wcstring &in, int flags, std::vector<wcstring> 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<wcstring> &outList )
|
||||
static int expand_cmdsubst2( parser_t &parser, const wcstring &input, std::vector<wcstring> &outList )
|
||||
{
|
||||
wchar_t *paran_begin=0, *paran_end=0;
|
||||
int len1;
|
||||
|
@ -1505,7 +1505,7 @@ static int expand_cmdsubst2( const wcstring &input, std::vector<wcstring> &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<wcstring> &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<wcstring> &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<wcstring> &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<wcstring> &outLi
|
|||
of the string is inserted into the tail_expand array list
|
||||
*/
|
||||
std::vector<wcstring> 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<wcstring> &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<wcstring> &output, int flags )
|
||||
int expand_string2( parser_t &parser, const wcstring &input, std::vector<wcstring> &output, int flags )
|
||||
{
|
||||
std::vector<wcstring> list1, list2;
|
||||
std::vector<wcstring> *in, *out;
|
||||
|
@ -1790,14 +1790,14 @@ int expand_string2( const wcstring &input, std::vector<wcstring> &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<wcstring> &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<wcstring> &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<wcstring> &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 );
|
||||
|
|
1
expand.h
1
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
|
||||
|
|
9
fish.cpp
9
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);
|
||||
}
|
||||
|
|
137
parser.cpp
137
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<profile_item_t> &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; i<al_get_count(p); i++ )
|
||||
for( i=pos+1; i<items.size(); i++ )
|
||||
{
|
||||
prev = (profile_element_t *)al_get( p, i );
|
||||
prev = &items.at(i);
|
||||
if( prev->skipped )
|
||||
{
|
||||
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 );
|
||||
|
|
17
parser.h
17
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<block_t> 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_item_t> 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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue