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:
axel
2006-02-10 01:50:20 +10:00
parent 49973b85da
commit d1c9bca2e9
27 changed files with 389 additions and 359 deletions

132
parser.c
View File

@@ -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;
}