mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Add function stack trace to error output
darcs-hash:20060126144810-ac50b-3426191f596674504ce49dd61fcfa3c2c0c0f2bb.gz
This commit is contained in:
parent
2e35e1ea60
commit
312c7ab7b2
7 changed files with 263 additions and 33 deletions
17
exec.c
17
exec.c
|
@ -806,7 +806,7 @@ void exec( job_t *j )
|
||||||
wchar_t **arg;
|
wchar_t **arg;
|
||||||
int i;
|
int i;
|
||||||
string_buffer_t sb;
|
string_buffer_t sb;
|
||||||
|
|
||||||
const wchar_t * def = function_get_definition( p->argv[0] );
|
const wchar_t * def = function_get_definition( p->argv[0] );
|
||||||
// fwprintf( stderr, L"run function %ls\n", argv[0] );
|
// fwprintf( stderr, L"run function %ls\n", argv[0] );
|
||||||
if( def == 0 )
|
if( def == 0 )
|
||||||
|
@ -814,14 +814,24 @@ void exec( job_t *j )
|
||||||
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
debug( 0, _( L"Unknown function '%ls'" ), p->argv[0] );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lineno = parser_get_lineno();
|
||||||
|
|
||||||
parser_push_block( FUNCTION_CALL );
|
parser_push_block( FUNCTION_CALL );
|
||||||
|
|
||||||
|
al_init( ¤t_block->param2.function_vars );
|
||||||
|
current_block->param1.function_name = wcsdup( p->argv[0] );
|
||||||
|
current_block->param3.function_lineno = lineno;
|
||||||
|
|
||||||
if( builtin_count_args(p->argv)>1 )
|
if( builtin_count_args(p->argv)>1 )
|
||||||
{
|
{
|
||||||
sb_init( &sb );
|
sb_init( &sb );
|
||||||
|
|
||||||
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
|
for( i=1, arg=p->argv+1; *arg; i++, arg++ )
|
||||||
{
|
{
|
||||||
|
al_push( ¤t_block->param2.function_vars,
|
||||||
|
escape(*arg, 1) );
|
||||||
|
|
||||||
if( i != 1 )
|
if( i != 1 )
|
||||||
sb_append( &sb, ARRAY_SEP_STR );
|
sb_append( &sb, ARRAY_SEP_STR );
|
||||||
sb_append( &sb, *arg );
|
sb_append( &sb, *arg );
|
||||||
|
@ -830,6 +840,11 @@ void exec( job_t *j )
|
||||||
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
|
env_set( L"argv", (wchar_t *)sb.buff, ENV_LOCAL );
|
||||||
sb_destroy( &sb );
|
sb_destroy( &sb );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
env_set( L"argv", 0, ENV_LOCAL );
|
||||||
|
}
|
||||||
|
|
||||||
parser_forbid_function( p->argv[0] );
|
parser_forbid_function( p->argv[0] );
|
||||||
|
|
||||||
if( p->next )
|
if( p->next )
|
||||||
|
|
47
function.c
47
function.c
|
@ -17,6 +17,7 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "intern.h"
|
#include "intern.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
|
#include "reader.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,6 +29,8 @@ typedef struct
|
||||||
wchar_t *cmd;
|
wchar_t *cmd;
|
||||||
/** Function description */
|
/** Function description */
|
||||||
wchar_t *desc;
|
wchar_t *desc;
|
||||||
|
const wchar_t *definition_file;
|
||||||
|
int definition_offset;
|
||||||
int is_binding;
|
int is_binding;
|
||||||
}
|
}
|
||||||
function_data_t;
|
function_data_t;
|
||||||
|
@ -62,6 +65,19 @@ void function_destroy()
|
||||||
hash_destroy( &function );
|
hash_destroy( &function );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int count_lineno( const wchar_t *str, int len )
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
int i;
|
||||||
|
for( i=0; i<len; i++ )
|
||||||
|
{
|
||||||
|
if( str[i] == L'\n' )
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void function_add( const wchar_t *name,
|
void function_add( const wchar_t *name,
|
||||||
const wchar_t *val,
|
const wchar_t *val,
|
||||||
const wchar_t *desc,
|
const wchar_t *desc,
|
||||||
|
@ -75,18 +91,22 @@ void function_add( const wchar_t *name,
|
||||||
if( function_exists( name ) )
|
if( function_exists( name ) )
|
||||||
function_remove( name );
|
function_remove( name );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function_data_t *d = malloc( sizeof( function_data_t ) );
|
function_data_t *d = malloc( sizeof( function_data_t ) );
|
||||||
|
d->definition_offset = count_lineno( parser_get_buffer(), current_block->tok_pos );
|
||||||
d->cmd = wcsdup( val );
|
d->cmd = wcsdup( val );
|
||||||
cmd_end = d->cmd + wcslen(d->cmd)-1;
|
cmd_end = d->cmd + wcslen(d->cmd)-1;
|
||||||
while( (cmd_end>d->cmd) && wcschr( L"\n\r\t ", *cmd_end ) )
|
while( (cmd_end>d->cmd) && wcschr( L"\n\r\t ", *cmd_end ) )
|
||||||
{
|
{
|
||||||
*cmd_end--=0;
|
*cmd_end-- = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->desc = desc?wcsdup( desc ):0;
|
d->desc = desc?wcsdup( desc ):0;
|
||||||
d->is_binding = is_binding;
|
d->is_binding = is_binding;
|
||||||
|
d->definition_file = reader_current_filename()?intern(reader_current_filename()):0;
|
||||||
hash_put( &function, intern(name), d );
|
hash_put( &function, intern(name), d );
|
||||||
|
|
||||||
for( i=0; i<al_get_count( events ); i++ )
|
for( i=0; i<al_get_count( events ); i++ )
|
||||||
{
|
{
|
||||||
event_add_handler( (event_t *)al_get( events, i ) );
|
event_add_handler( (event_t *)al_get( events, i ) );
|
||||||
|
@ -172,3 +192,26 @@ void function_get_names( array_list_t *list, int get_hidden )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wchar_t *function_get_definition_file( const wchar_t *argv )
|
||||||
|
{
|
||||||
|
function_data_t *data =
|
||||||
|
(function_data_t *)hash_get( &function, argv );
|
||||||
|
if( data == 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return data->definition_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int function_get_definition_offset( const wchar_t *argv )
|
||||||
|
{
|
||||||
|
function_data_t *data =
|
||||||
|
(function_data_t *)hash_get( &function, argv );
|
||||||
|
if( data == 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return data->definition_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,4 +69,8 @@ int function_exists( const wchar_t *name );
|
||||||
void function_get_names( array_list_t *list,
|
void function_get_names( array_list_t *list,
|
||||||
int get_hidden );
|
int get_hidden );
|
||||||
|
|
||||||
|
const wchar_t *function_get_definition_file( const wchar_t *name );
|
||||||
|
|
||||||
|
int function_get_definition_offset( const wchar_t *name );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
14
main.c
14
main.c
|
@ -184,7 +184,7 @@ int main( int argc, char **argv )
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
fwprintf( stderr,
|
fwprintf( stderr,
|
||||||
L"%s, version %s\n",
|
_(L"%s, version %s\n"),
|
||||||
PACKAGE_NAME,
|
PACKAGE_NAME,
|
||||||
PACKAGE_VERSION );
|
PACKAGE_VERSION );
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
|
@ -222,8 +222,6 @@ int main( int argc, char **argv )
|
||||||
complete_init();
|
complete_init();
|
||||||
reader_init();
|
reader_init();
|
||||||
|
|
||||||
reader_push_current_filename( L"(internal)" );
|
|
||||||
|
|
||||||
if( read_init() )
|
if( read_init() )
|
||||||
{
|
{
|
||||||
if( cmd != 0 )
|
if( cmd != 0 )
|
||||||
|
@ -237,9 +235,7 @@ int main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
if( my_optind == argc )
|
if( my_optind == argc )
|
||||||
{
|
{
|
||||||
reader_push_current_filename( L"(stdin)" );
|
|
||||||
res = reader_read( 0 );
|
res = reader_read( 0 );
|
||||||
reader_pop_current_filename();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -278,8 +274,8 @@ int main( int argc, char **argv )
|
||||||
if( res )
|
if( res )
|
||||||
{
|
{
|
||||||
debug( 1,
|
debug( 1,
|
||||||
L"Error while reading file %ls\n",
|
_(L"Error while reading file %ls\n"),
|
||||||
reader_current_filename() );
|
reader_current_filename()?reader_current_filename(): _(L"Standard input") );
|
||||||
}
|
}
|
||||||
free(reader_pop_current_filename());
|
free(reader_pop_current_filename());
|
||||||
}
|
}
|
||||||
|
@ -287,9 +283,7 @@ int main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
proc_fire_event( L"PROCESS_EXIT", EVENT_EXIT, getpid(), res );
|
||||||
|
|
||||||
reader_pop_current_filename();
|
|
||||||
|
|
||||||
proc_destroy();
|
proc_destroy();
|
||||||
env_destroy();
|
env_destroy();
|
||||||
builtin_destroy();
|
builtin_destroy();
|
||||||
|
|
203
parser.c
203
parser.c
|
@ -398,6 +398,15 @@ void parser_pop_block()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case FUNCTION_CALL:
|
||||||
|
{
|
||||||
|
free( current_block->param1.function_name );
|
||||||
|
al_foreach( ¤t_block->param2.function_vars,
|
||||||
|
(void (*)(const void *))&free );
|
||||||
|
al_destroy( ¤t_block->param2.function_vars );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for( eb=current_block->first_event_block; eb; eb=eb_next )
|
for( eb=current_block->first_event_block; eb; eb=eb_next )
|
||||||
|
@ -899,6 +908,14 @@ void parser_destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
al_destroy( &forbidden_function );
|
al_destroy( &forbidden_function );
|
||||||
|
|
||||||
|
if( lineinfo )
|
||||||
|
{
|
||||||
|
sb_destroy( lineinfo );
|
||||||
|
free(lineinfo );
|
||||||
|
lineinfo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -995,17 +1012,139 @@ int eval_args( const wchar_t *line, array_list_t *args )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void parser_stack_trace( block_t *b, string_buffer_t *buff)
|
||||||
|
{
|
||||||
|
if( !b )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( b->type == FUNCTION_CALL )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sb_printf( buff, _(L"in function '%ls',\n"), b->param1.function_name );
|
||||||
|
|
||||||
|
const wchar_t *file = function_get_definition_file( b->param1.function_name );
|
||||||
|
if( file )
|
||||||
|
sb_printf( buff,
|
||||||
|
_(L"\tcalled on line %d of file '%ls'\n"),
|
||||||
|
b->param3.function_lineno,
|
||||||
|
file );
|
||||||
|
else
|
||||||
|
sb_printf( buff,
|
||||||
|
_(L"\tcalled on standard input\n") );
|
||||||
|
|
||||||
|
if( al_get_count( &b->param2.function_vars ) )
|
||||||
|
{
|
||||||
|
string_buffer_t tmp;
|
||||||
|
sb_init( &tmp );
|
||||||
|
|
||||||
|
for( i=0; i<al_get_count( &b->param2.function_vars ); i++ )
|
||||||
|
{
|
||||||
|
sb_append2( &tmp, i?L" ":L"", (wchar_t *)al_get( &b->param2.function_vars, i ), (void *)0 );
|
||||||
|
}
|
||||||
|
sb_printf( buff, _(L"\twith parameters '%ls',\n"), (wchar_t *)tmp.buff );
|
||||||
|
|
||||||
|
sb_destroy( &tmp );
|
||||||
|
}
|
||||||
|
sb_printf( buff,
|
||||||
|
L"\n" );
|
||||||
|
}
|
||||||
|
parser_stack_trace( b->outer, buff );
|
||||||
|
}
|
||||||
|
|
||||||
|
static const wchar_t *is_function()
|
||||||
|
{
|
||||||
|
block_t *b = current_block;
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
if( !b )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if( b->type == FUNCTION_CALL )
|
||||||
|
{
|
||||||
|
return b->param1.function_name;
|
||||||
|
}
|
||||||
|
b=b->outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int parser_get_lineno()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const wchar_t *whole_str = tok_string( current_tokenizer );
|
||||||
|
const wchar_t *function_name;
|
||||||
|
|
||||||
|
int lineno = 1;
|
||||||
|
|
||||||
|
for( i=0; i<current_tokenizer_pos; i++ )
|
||||||
|
{
|
||||||
|
if( whole_str[i] == L'\n' )
|
||||||
|
{
|
||||||
|
lineno++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( (function_name = is_function()) )
|
||||||
|
{
|
||||||
|
lineno += function_get_definition_offset( function_name );
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const wchar_t *parser_current_filename()
|
||||||
|
{
|
||||||
|
block_t *b = current_block;
|
||||||
|
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
if( !b )
|
||||||
|
{
|
||||||
|
return reader_current_filename();
|
||||||
|
}
|
||||||
|
if( b->type == FUNCTION_CALL )
|
||||||
|
{
|
||||||
|
return function_get_definition_file(b->param1.function_name );
|
||||||
|
}
|
||||||
|
b=b->outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int printed_width( const wchar_t *str, int len )
|
||||||
|
{
|
||||||
|
int res=0;
|
||||||
|
int i;
|
||||||
|
for( i=0; i<len; i++ )
|
||||||
|
{
|
||||||
|
if( str[i] == L'\t' )
|
||||||
|
{
|
||||||
|
res=(res+8)&~7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res += wcwidth( str[i] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
wchar_t *parser_current_line()
|
wchar_t *parser_current_line()
|
||||||
{
|
{
|
||||||
int lineno=1;
|
int lineno=1;
|
||||||
|
|
||||||
wchar_t *file = reader_current_filename();
|
const wchar_t *file = parser_current_filename();
|
||||||
wchar_t *whole_str = tok_string( current_tokenizer );
|
wchar_t *whole_str = tok_string( current_tokenizer );
|
||||||
wchar_t *line = whole_str;
|
wchar_t *line = whole_str;
|
||||||
wchar_t *line_end;
|
wchar_t *line_end;
|
||||||
int i;
|
int i;
|
||||||
int offset;
|
int offset;
|
||||||
int current_line_pos=current_tokenizer_pos;
|
int current_line_width;
|
||||||
|
const wchar_t *function_name=0;
|
||||||
|
int current_line_start=0;
|
||||||
|
|
||||||
|
|
||||||
if( !line )
|
if( !line )
|
||||||
return L"";
|
return L"";
|
||||||
|
@ -1015,7 +1154,7 @@ wchar_t *parser_current_line()
|
||||||
lineinfo = malloc( sizeof(string_buffer_t) );
|
lineinfo = malloc( sizeof(string_buffer_t) );
|
||||||
sb_init( lineinfo );
|
sb_init( lineinfo );
|
||||||
}
|
}
|
||||||
sb_clear( lineinfo );
|
sb_clear( lineinfo );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate line number, line offset, etc.
|
Calculate line number, line offset, etc.
|
||||||
|
@ -1025,11 +1164,18 @@ wchar_t *parser_current_line()
|
||||||
if( whole_str[i] == L'\n' )
|
if( whole_str[i] == L'\n' )
|
||||||
{
|
{
|
||||||
lineno++;
|
lineno++;
|
||||||
current_line_pos = current_tokenizer_pos-i-1;
|
current_line_start=i+1;
|
||||||
line = &whole_str[i+1];
|
line = &whole_str[i+1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_line_width=printed_width(whole_str+current_line_start, current_tokenizer_pos-current_line_start );
|
||||||
|
|
||||||
|
if( (function_name = is_function()) )
|
||||||
|
{
|
||||||
|
lineno += function_get_definition_offset( function_name );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copy current line from whole string
|
Copy current line from whole string
|
||||||
*/
|
*/
|
||||||
|
@ -1039,34 +1185,55 @@ wchar_t *parser_current_line()
|
||||||
|
|
||||||
line = wcsndup( line, line_end-line );
|
line = wcsndup( line, line_end-line );
|
||||||
|
|
||||||
debug( 4, L"Current pos %d, line pos %d, file_length %d, is_interactive %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive);
|
/**
|
||||||
|
If we are not going to print a stack trace, at least print the line number and filename
|
||||||
|
*/
|
||||||
if( !is_interactive )
|
if( !is_interactive )
|
||||||
{
|
{
|
||||||
sb_printf( lineinfo,
|
int prev_width = my_wcswidth( (wchar_t *)lineinfo->buff );
|
||||||
_(L"%ls (line %d): "),
|
if( file )
|
||||||
file,
|
sb_printf( lineinfo,
|
||||||
lineno );
|
_(L"%ls (line %d): "),
|
||||||
offset = my_wcswidth( (wchar_t *)lineinfo->buff );
|
file,
|
||||||
|
lineno );
|
||||||
|
else
|
||||||
|
sb_printf( lineinfo,
|
||||||
|
L"%ls: ",
|
||||||
|
_(L"Standard input"),
|
||||||
|
lineno );
|
||||||
|
offset = my_wcswidth( (wchar_t *)lineinfo->buff ) - prev_width;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
offset=0;
|
offset=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug( 1, L"Current pos %d, line pos %d, file_length %d, is_interactive %d, offset %d\n", current_tokenizer_pos, current_line_pos, wcslen(whole_str), is_interactive, offset);
|
||||||
/*
|
/*
|
||||||
Skip printing character position if we are in interactive mode
|
Skip printing character position if we are in interactive mode
|
||||||
and the error was on the first character of the line
|
and the error was on the first character of the line.
|
||||||
*/
|
*/
|
||||||
if( !is_interactive || (current_line_pos!=0) )
|
if( !is_interactive || is_function() || (current_line_width!=0) )
|
||||||
{
|
{
|
||||||
sb_printf( lineinfo,
|
// Workaround since it seems impossible to print 0 copies of a character using printf
|
||||||
L"%ls\n%*c^\n",
|
if( offset+current_line_width )
|
||||||
line,
|
{
|
||||||
offset+current_line_pos,
|
sb_printf( lineinfo,
|
||||||
L' ' );
|
L"%ls\n%*lc^\n",
|
||||||
|
line,
|
||||||
|
offset+current_line_width,
|
||||||
|
L' ' );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb_printf( lineinfo,
|
||||||
|
L"%ls\n^\n",
|
||||||
|
line );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free( line );
|
free( line );
|
||||||
|
parser_stack_trace( current_block, lineinfo );
|
||||||
|
|
||||||
return (wchar_t *)lineinfo->buff;
|
return (wchar_t *)lineinfo->buff;
|
||||||
}
|
}
|
||||||
|
|
9
parser.h
9
parser.h
|
@ -63,7 +63,7 @@ typedef struct block
|
||||||
wchar_t *for_variable; /**< Name of the variable to loop over */
|
wchar_t *for_variable; /**< Name of the variable to loop over */
|
||||||
int if_state; /**< The state of the if block */
|
int if_state; /**< The state of the if block */
|
||||||
wchar_t *switch_value; /**< The value to test in a switch block */
|
wchar_t *switch_value; /**< The value to test in a switch block */
|
||||||
wchar_t *function_name; /**< The name of the function to define */
|
wchar_t *function_name; /**< The name of the function to define or the function called*/
|
||||||
} param1;
|
} param1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,6 +74,7 @@ typedef struct block
|
||||||
array_list_t for_vars; /**< List of values for a for block */
|
array_list_t for_vars; /**< List of values for a for block */
|
||||||
int switch_taken; /**< Whether a switch match has already been found */
|
int switch_taken; /**< Whether a switch match has already been found */
|
||||||
wchar_t *function_description; /**< The description of the function to define */
|
wchar_t *function_description; /**< The description of the function to define */
|
||||||
|
array_list_t function_vars; /**< List of arguments for a function call */
|
||||||
} param2;
|
} param2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +83,7 @@ typedef struct block
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
int function_is_binding; /**< Whether a function is a keybinding */
|
int function_is_binding; /**< Whether a function is a keybinding */
|
||||||
|
int function_lineno; /**< Function invocation line number */
|
||||||
} param3;
|
} param3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -251,6 +253,11 @@ int parser_is_reserved( wchar_t *word );
|
||||||
*/
|
*/
|
||||||
wchar_t *parser_current_line();
|
wchar_t *parser_current_line();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns the current line number
|
||||||
|
*/
|
||||||
|
int parser_get_lineno();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the current position in the latest string of the tokenizer.
|
Returns the current position in the latest string of the tokenizer.
|
||||||
*/
|
*/
|
||||||
|
|
2
reader.c
2
reader.c
|
@ -385,7 +385,7 @@ void reader_handle_int( int sig )
|
||||||
|
|
||||||
wchar_t *reader_current_filename()
|
wchar_t *reader_current_filename()
|
||||||
{
|
{
|
||||||
return (wchar_t *)al_peek( ¤t_filename );
|
return al_get_count( ¤t_filename )?(wchar_t *)al_peek( ¤t_filename ):0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue