mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-07 01:51:14 -03:00
Another halloc:ification of fish. Halloc has been extended to allow registering function calls, this has allowed the creation of halloc-handled arraylists, stringbuffers, etc. More job parsing halloc-ification has reduced the error handling code to only a shadow of it's former self
darcs-hash:20060209155020-ac50b-e119c5293ce2368e252cfc01b98ab7c629fdd678.gz
This commit is contained in:
132
parser.c
132
parser.c
@@ -39,6 +39,7 @@ The fish parser. Contains functions for parsing code.
|
||||
#include "intern.h"
|
||||
#include "parse_util.h"
|
||||
#include "halloc.h"
|
||||
#include "halloc_util.h"
|
||||
|
||||
/**
|
||||
Maximum number of block levels in code. This is not the same as
|
||||
@@ -340,15 +341,15 @@ static int block_count( block_t *b )
|
||||
void parser_push_block( int type )
|
||||
{
|
||||
block_t *new = halloc( 0, sizeof( block_t ));
|
||||
|
||||
|
||||
new->src_lineno = parser_get_lineno();
|
||||
new->src_filename = parser_current_filename()?intern(parser_current_filename()):0;
|
||||
|
||||
// debug( 3, L"Block push %ls %d\n", parser_get_block_desc(type), block_count( current_block)+1 );
|
||||
|
||||
|
||||
new->outer = current_block;
|
||||
new->type = (current_block && current_block->skip)?FAKE:type;
|
||||
|
||||
|
||||
/*
|
||||
New blocks should be skipped if the outer block is skipped,
|
||||
except TOP ans SUBST block, which open up new environments. Fake
|
||||
@@ -359,9 +360,8 @@ void parser_push_block( int type )
|
||||
new->skip = 0;
|
||||
if( type == FAKE )
|
||||
new->skip = 1;
|
||||
|
||||
|
||||
new->job = 0;
|
||||
|
||||
new->loop_status=LOOP_NORMAL;
|
||||
|
||||
current_block = new;
|
||||
@@ -371,20 +371,12 @@ void parser_push_block( int type )
|
||||
(new->type != TOP) )
|
||||
{
|
||||
env_push( type == FUNCTION_CALL );
|
||||
halloc_register_function_void( current_block, &env_pop );
|
||||
}
|
||||
}
|
||||
|
||||
void parser_pop_block()
|
||||
{
|
||||
// debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 );
|
||||
|
||||
if( (current_block->type != FUNCTION_DEF ) &&
|
||||
(current_block->type != FAKE) &&
|
||||
(current_block->type != TOP) )
|
||||
{
|
||||
env_pop();
|
||||
}
|
||||
|
||||
block_t *old = current_block;
|
||||
current_block = current_block->outer;
|
||||
halloc_free( old );
|
||||
@@ -744,11 +736,10 @@ wchar_t *get_filename( const wchar_t *cmd )
|
||||
wchar_t *path_cpy = wcsdup( path );
|
||||
wchar_t *nxt_path = path;
|
||||
wchar_t *state;
|
||||
|
||||
|
||||
if( (new_cmd==0) || (path_cpy==0) )
|
||||
{
|
||||
die_mem();
|
||||
|
||||
}
|
||||
|
||||
for( nxt_path = wcstok( path_cpy, ARRAY_SEP_STR, &state );
|
||||
@@ -940,7 +931,7 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
||||
switch(tok_last_type( &tok ) )
|
||||
{
|
||||
case TOK_STRING:
|
||||
switch( expand_string( wcsdup(tok_last( &tok )), args, 0 ) )
|
||||
switch( expand_string( 0, wcsdup(tok_last( &tok )), args, 0 ) )
|
||||
{
|
||||
case EXPAND_ERROR:
|
||||
{
|
||||
@@ -979,13 +970,12 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
||||
|
||||
do_loop=0;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
print_errors();
|
||||
tok_destroy( &tok );
|
||||
|
||||
|
||||
current_tokenizer=previous_tokenizer;
|
||||
current_tokenizer_pos = previous_pos;
|
||||
is_interactive = was_interactive;
|
||||
@@ -1331,7 +1321,8 @@ static void parse_job_main_loop( process_t *p,
|
||||
return;
|
||||
}
|
||||
p->pipe_fd = wcstol( tok_last( tok ), 0, 10 );
|
||||
p->argv = list_to_char_arr( j, args );
|
||||
p->argv = list_to_char_arr( args );
|
||||
halloc_register( j, p->argv );
|
||||
p->next = halloc( j, sizeof( process_t ) );
|
||||
if( p->next == 0 )
|
||||
{
|
||||
@@ -1353,7 +1344,8 @@ static void parse_job_main_loop( process_t *p,
|
||||
|
||||
case TOK_END:
|
||||
{
|
||||
p->argv = list_to_char_arr( j, args );
|
||||
p->argv = list_to_char_arr( args );
|
||||
halloc_register( j, p->argv );
|
||||
if( tok_has_next(tok))
|
||||
tok_next(tok);
|
||||
|
||||
@@ -1399,7 +1391,7 @@ static void parse_job_main_loop( process_t *p,
|
||||
}
|
||||
|
||||
|
||||
switch( expand_string( wcsdup(tok_last( tok )), args, 0 ) )
|
||||
switch( expand_string( j, wcsdup(tok_last( tok )), args, 0 ) )
|
||||
{
|
||||
case EXPAND_ERROR:
|
||||
{
|
||||
@@ -1487,7 +1479,7 @@ static void parse_job_main_loop( process_t *p,
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
target = (wchar_t *)halloc_register( j, expand_one( wcsdup( tok_last( tok ) ), 0));
|
||||
target = (wchar_t *)expand_one( j, wcsdup( tok_last( tok ) ), 0);
|
||||
|
||||
if( target == 0 && error_code == 0 )
|
||||
{
|
||||
@@ -1634,7 +1626,7 @@ static int parse_job( process_t *p,
|
||||
job_t *j,
|
||||
tokenizer *tok )
|
||||
{
|
||||
array_list_t args; // The list that will become the argc array for the program
|
||||
array_list_t *args = al_halloc( j ); // The list that will become the argc array for the program
|
||||
int use_function = 1; // May functions be considered when checking what action this command represents
|
||||
int use_builtin = 1; // May builtins be considered when checking what action this command represents
|
||||
int is_new_block=0; // Does this command create a new block?
|
||||
@@ -1642,28 +1634,26 @@ static int parse_job( process_t *p,
|
||||
block_t *prev_block = current_block;
|
||||
int prev_tokenizer_pos = current_tokenizer_pos;
|
||||
|
||||
al_init( &args );
|
||||
|
||||
current_tokenizer_pos = tok_get_pos( tok );
|
||||
|
||||
while( al_get_count( &args ) == 0 )
|
||||
while( al_get_count( args ) == 0 )
|
||||
{
|
||||
wchar_t *nxt=0;
|
||||
switch( tok_last_type( tok ))
|
||||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
nxt = expand_one( wcsdup(tok_last( tok )),
|
||||
nxt = expand_one( j,
|
||||
wcsdup(tok_last( tok )),
|
||||
EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES);
|
||||
|
||||
|
||||
if( nxt == 0 )
|
||||
{
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
ILLEGAL_CMD_ERR_MSG,
|
||||
tok_last( tok ) );
|
||||
|
||||
al_destroy( &args );
|
||||
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return 0;
|
||||
}
|
||||
@@ -1677,7 +1667,6 @@ static int parse_job( process_t *p,
|
||||
TOK_ERR_MSG,
|
||||
tok_last(tok) );
|
||||
|
||||
al_destroy( &args );
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return 0;
|
||||
}
|
||||
@@ -1700,7 +1689,6 @@ static int parse_job( process_t *p,
|
||||
tok_get_desc( tok_last_type(tok) ) );
|
||||
}
|
||||
|
||||
al_destroy( &args );
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return 0;
|
||||
}
|
||||
@@ -1712,14 +1700,16 @@ static int parse_job( process_t *p,
|
||||
CMD_ERR_MSG,
|
||||
tok_get_desc( tok_last_type(tok) ) );
|
||||
|
||||
al_destroy( &args );
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int mark = tok_get_pos( tok );
|
||||
|
||||
int consumed = 0;
|
||||
|
||||
|
||||
if( wcscmp( L"command", nxt )==0 )
|
||||
{
|
||||
tok_next( tok );
|
||||
@@ -1731,8 +1721,7 @@ static int parse_job( process_t *p,
|
||||
{
|
||||
use_function = 0;
|
||||
use_builtin=0;
|
||||
free( nxt );
|
||||
continue;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"builtin", nxt )==0 )
|
||||
@@ -1745,8 +1734,7 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
use_function = 0;
|
||||
free( nxt );
|
||||
continue;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"not", nxt )==0 )
|
||||
@@ -1759,8 +1747,7 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
j->negate=1-j->negate;
|
||||
free( nxt );
|
||||
continue;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"and", nxt )==0 )
|
||||
@@ -1773,8 +1760,7 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
j->skip = proc_get_last_status();
|
||||
free( nxt );
|
||||
continue;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"or", nxt )==0 )
|
||||
@@ -1787,8 +1773,7 @@ static int parse_job( process_t *p,
|
||||
else
|
||||
{
|
||||
j->skip = !proc_get_last_status();
|
||||
free( nxt );
|
||||
continue;
|
||||
consumed=1;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"exec", nxt )==0 )
|
||||
@@ -1798,7 +1783,6 @@ static int parse_job( process_t *p,
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
EXEC_ERR_MSG );
|
||||
al_destroy( &args );
|
||||
free(nxt);
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return 0;
|
||||
@@ -1814,9 +1798,8 @@ static int parse_job( process_t *p,
|
||||
use_function = 0;
|
||||
use_builtin=0;
|
||||
p->type=INTERNAL_EXEC;
|
||||
free( nxt );
|
||||
consumed=1;
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if( wcscmp( L"while", nxt ) ==0 )
|
||||
@@ -1844,10 +1827,8 @@ static int parse_job( process_t *p,
|
||||
current_block->tok_pos = mark;
|
||||
}
|
||||
|
||||
free( nxt );
|
||||
consumed=1;
|
||||
is_new_block=1;
|
||||
|
||||
continue;
|
||||
}
|
||||
else if( wcscmp( L"if", nxt ) ==0 )
|
||||
{
|
||||
@@ -1858,8 +1839,12 @@ static int parse_job( process_t *p,
|
||||
current_block->param1.if_state=0;
|
||||
current_block->tok_pos = mark;
|
||||
|
||||
free( nxt );
|
||||
is_new_block=1;
|
||||
consumed=1;
|
||||
}
|
||||
|
||||
if( consumed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1892,7 +1877,7 @@ static int parse_job( process_t *p,
|
||||
}
|
||||
}
|
||||
}
|
||||
al_push( &args, nxt );
|
||||
al_push( args, nxt );
|
||||
}
|
||||
|
||||
if( error_code == 0 )
|
||||
@@ -1900,10 +1885,10 @@ static int parse_job( process_t *p,
|
||||
if( !p->type )
|
||||
{
|
||||
if( use_builtin &&
|
||||
builtin_exists( (wchar_t *)al_get( &args, 0 ) ) )
|
||||
builtin_exists( (wchar_t *)al_get( args, 0 ) ) )
|
||||
{
|
||||
p->type = INTERNAL_BUILTIN;
|
||||
is_new_block = parser_is_block( (wchar_t *)al_get( &args, 0 ) );
|
||||
is_new_block = parser_is_block( (wchar_t *)al_get( args, 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1919,7 +1904,7 @@ static int parse_job( process_t *p,
|
||||
}
|
||||
else
|
||||
{
|
||||
p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( &args, 0 ) ));
|
||||
p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( args, 0 ) ));
|
||||
|
||||
/*
|
||||
Check if the specified command exists
|
||||
@@ -1933,16 +1918,16 @@ static int parse_job( process_t *p,
|
||||
implicit command.
|
||||
*/
|
||||
wchar_t *pp =
|
||||
parser_cdpath_get( (wchar_t *)al_get( &args, 0 ) );
|
||||
parser_cdpath_get( (wchar_t *)al_get( args, 0 ) );
|
||||
if( pp )
|
||||
{
|
||||
wchar_t *tmp;
|
||||
free( pp );
|
||||
|
||||
tmp = (wchar_t *)al_get( &args, 0 );
|
||||
al_truncate( &args, 0 );
|
||||
al_push( &args, wcsdup( L"cd" ) );
|
||||
al_push( &args, tmp );
|
||||
tmp = (wchar_t *)al_get( args, 0 );
|
||||
al_truncate( args, 0 );
|
||||
al_push( args, wcsdup( L"cd" ) );
|
||||
al_push( args, tmp );
|
||||
/*
|
||||
If we have defined a wrapper around cd, use it,
|
||||
otherwise use the cd builtin
|
||||
@@ -1954,12 +1939,12 @@ static int parse_job( process_t *p,
|
||||
}
|
||||
else
|
||||
{
|
||||
if( wcschr( (wchar_t *)al_get( &args, 0 ), L'=' ) )
|
||||
if( wcschr( (wchar_t *)al_get( args, 0 ), L'=' ) )
|
||||
{
|
||||
error( EVAL_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
COMMAND_ASSIGN_ERR_MSG,
|
||||
(wchar_t *)al_get( &args, 0 ) );
|
||||
(wchar_t *)al_get( args, 0 ) );
|
||||
|
||||
|
||||
}
|
||||
@@ -1968,7 +1953,7 @@ static int parse_job( process_t *p,
|
||||
error( EVAL_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
_(L"Unknown command '%ls'"),
|
||||
(wchar_t *)al_get( &args, 0 ) );
|
||||
(wchar_t *)al_get( args, 0 ) );
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1990,6 +1975,7 @@ static int parse_job( process_t *p,
|
||||
error( SYNTAX_ERROR,
|
||||
tok_get_pos( tok ),
|
||||
BLOCK_END_ERR_MSG );
|
||||
|
||||
}
|
||||
|
||||
if( !make_sub_block )
|
||||
@@ -2028,8 +2014,8 @@ static int parse_job( process_t *p,
|
||||
end_pos - current_tokenizer_pos);
|
||||
|
||||
p->type = INTERNAL_BLOCK;
|
||||
free( (void *)al_get( &args, 0 ) );
|
||||
al_set( &args, 0, sub_block );
|
||||
free( (void *)al_get( args, 0 ) );
|
||||
al_set( args, 0, sub_block );
|
||||
|
||||
tok_set_pos( tok,
|
||||
end_pos );
|
||||
@@ -2047,22 +2033,20 @@ static int parse_job( process_t *p,
|
||||
|
||||
if( !error_code )
|
||||
{
|
||||
if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(&args, 0) ) )
|
||||
if( p->type == INTERNAL_BUILTIN && parser_skip_arguments( (wchar_t *)al_get(args, 0) ) )
|
||||
{
|
||||
p->argv = list_to_char_arr( j, &args );
|
||||
p->argv = list_to_char_arr( args );
|
||||
halloc_register( j, p->argv );
|
||||
// tok_next(tok);
|
||||
}
|
||||
else
|
||||
{
|
||||
parse_job_main_loop( p, j, tok, &args );
|
||||
parse_job_main_loop( p, j, tok, args );
|
||||
}
|
||||
}
|
||||
|
||||
if( error_code )
|
||||
{
|
||||
if( !p->argv )
|
||||
al_foreach( &args,
|
||||
(void (*)(const void *))&free );
|
||||
/*
|
||||
Make sure the block stack is consistent
|
||||
*/
|
||||
@@ -2070,9 +2054,7 @@ static int parse_job( process_t *p,
|
||||
{
|
||||
parser_pop_block();
|
||||
}
|
||||
|
||||
}
|
||||
al_destroy( &args );
|
||||
current_tokenizer_pos = prev_tokenizer_pos;
|
||||
return !error_code;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user