From b3b71868463570794236b47272e88e8e05c9aef2 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Wed, 21 Nov 2001 04:39:53 +0000 Subject: [PATCH] Backtrace Debug file/line numbers Local rules not implicitly imported Craig McPheeters' dependency graph output as -d+12 Grammar cleanup Factored parse evaluation into parse_evaluate() Modified Files: compile.c frames.h jam.h jamgram.c jamgram.y jamgram.yy make.c parse.c parse.h rules.c rules.h scan.c scan.h [SVN r11759] --- historic/jam/src/compile.c | 223 +++++++++++---- historic/jam/src/frames.h | 10 + historic/jam/src/jam.h | 3 +- historic/jam/src/jamgram.c | 549 ++++++++++++++++++------------------ historic/jam/src/jamgram.y | 43 +-- historic/jam/src/jamgram.yy | 43 +-- historic/jam/src/make.c | 110 ++++++++ historic/jam/src/parse.c | 19 +- historic/jam/src/parse.h | 16 +- historic/jam/src/rules.c | 36 ++- historic/jam/src/rules.h | 8 +- historic/jam/src/scan.c | 43 ++- historic/jam/src/scan.h | 13 +- jam_src/compile.c | 223 +++++++++++---- jam_src/frames.h | 10 + jam_src/jam.h | 3 +- jam_src/jamgram.c | 549 ++++++++++++++++++------------------ jam_src/jamgram.y | 43 +-- jam_src/jamgram.yy | 43 +-- jam_src/make.c | 110 ++++++++ jam_src/parse.c | 19 +- jam_src/parse.h | 16 +- jam_src/rules.c | 36 ++- jam_src/rules.h | 8 +- jam_src/scan.c | 43 ++- jam_src/scan.h | 13 +- 26 files changed, 1434 insertions(+), 798 deletions(-) diff --git a/historic/jam/src/compile.c b/historic/jam/src/compile.c index ec0dcdd0c..90205adea 100644 --- a/historic/jam/src/compile.c +++ b/historic/jam/src/compile.c @@ -84,10 +84,14 @@ * in jamgram.yy. */ -static void debug_compile( int which, char *s ); +static void debug_compile( int which, char *s, FRAME* frame ); static int evaluate_if( PARSE *parse, FRAME *frame ); +static void backtrace_line( FRAME* frame ); +static void backtrace( FRAME* frame ); +static void frame_info( FRAME* frame, char** file, int* line ); + static LIST *builtin_depends( PARSE *parse, FRAME *frame ); static LIST *builtin_echo( PARSE *parse, FRAME *frame ); static LIST *builtin_exit( PARSE *parse, FRAME *frame ); @@ -95,6 +99,9 @@ static LIST *builtin_flags( PARSE *parse, FRAME *frame ); static LIST *builtin_hdrmacro( PARSE *parse, FRAME *frame ); static LIST *builtin_import( PARSE *parse, FRAME *frame ); static LIST *builtin_caller_module( PARSE *parse, FRAME *frame ); +static LIST *builtin_backtrace( PARSE *parse, FRAME *frame ); + + LIST *builtin_subst( PARSE *parse, FRAME *frame ); int glob( char *s, char *c ); @@ -105,6 +112,8 @@ void frame_init( FRAME* frame ) frame->prev = 0; lol_init(frame->args); frame->module = root_module(); + frame->rulename = "module scope"; + frame->procedure = 0; } void frame_free( FRAME* frame ) @@ -154,7 +163,7 @@ static RULE* bind_builtin( char* name, LIST*(*f)(PARSE*, FRAME*), int flags, cha } return new_rule_body( root_module(), name, arg_list, - parse_make( f, P0, P0, P0, C0, C0, flags ) ); + parse_make( f, P0, P0, P0, C0, C0, flags ), 0 ); } static RULE* duplicate_rule( char* name, RULE* other ) @@ -208,6 +217,11 @@ compile_builtins() char* args[] = { "levels", "?", 0 }; bind_builtin( "CALLER_MODULE", builtin_caller_module, 0, args ); } + + { + char* args[] = { 0 }; + bind_builtin( "BACKTRACE", builtin_backtrace, 0, args ); + } } /* @@ -225,8 +239,8 @@ compile_append( /* Append right to left. */ return list_append( - (*parse->left->func)( parse->left, frame ), - (*parse->right->func)( parse->right, frame ) ); + parse_evaluate( parse->left, frame ), + parse_evaluate( parse->right, frame ) ); } /* @@ -245,7 +259,7 @@ compile_foreach( PARSE *parse, FRAME *frame ) { - LIST *nv = (*parse->left->func)( parse->left, frame ); + LIST *nv = parse_evaluate( parse->left, frame ); LIST *l; SETTINGS *s = 0; @@ -263,7 +277,7 @@ compile_foreach( var_set( parse->string, val, VAR_SET ); - list_free( (*parse->right->func)( parse->right, frame ) ); + list_free( parse_evaluate( parse->right, frame ) ); } if ( parse->num ) @@ -289,11 +303,11 @@ compile_if( { if( evaluate_if( p->left, frame ) ) { - return (*p->right->func)( p->right, frame ); + return parse_evaluate( p->right, frame ); } else { - return (*p->third->func)( p->third, frame ); + return parse_evaluate( p->third, frame ); } } @@ -304,7 +318,7 @@ compile_while( { while ( evaluate_if( p->left, frame ) ) { - list_free( (*p->right->func)( p->right, frame ) ); + list_free( parse_evaluate( p->right, frame ) ); } return L0; } @@ -353,8 +367,8 @@ evaluate_if( /* Handle one of the comparison operators */ /* Expand targets and sources */ - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); /* "a in b" make sure each of a is equal to something in b. */ /* Otherwise, step through pairwise comparison. */ @@ -409,7 +423,7 @@ evaluate_if( if( DEBUG_IF ) { - debug_compile( 0, "if" ); + debug_compile( 0, "if", frame); list_print( nt ); printf( "(%d)", status ); list_print( ns ); @@ -435,11 +449,11 @@ compile_include( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); if( DEBUG_COMPILE ) { - debug_compile( 0, "include" ); + debug_compile( 0, "include", frame); list_print( nt ); printf( "\n" ); } @@ -477,7 +491,7 @@ compile_module( { /* Here we are entering a module declaration block. */ - LIST* module_name = (*p->left->func)( p->left, frame ); + LIST* module_name = parse_evaluate( p->left, frame ); LIST* result; module* outer_module = frame->module; @@ -489,7 +503,7 @@ compile_module( enter_module( frame->module ); } - result = (*p->right->func)( p->right, frame ); + result = parse_evaluate( p->right, frame ); if ( outer_module != frame->module ) { @@ -534,13 +548,13 @@ compile_local( { LIST *l; SETTINGS *s = 0; - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *result; if( DEBUG_COMPILE ) { - debug_compile( 0, "local" ); + debug_compile( 0, "local", frame); list_print( nt ); printf( " = " ); list_print( ns ); @@ -559,7 +573,7 @@ compile_local( /* variable, making it not so much local as layered. */ pushsettings( s ); - result = (*parse->third->func)( parse->third, frame ); + result = parse_evaluate( parse->third, frame ); popsettings( s ); freesettings( s ); @@ -603,9 +617,10 @@ compile_rule( frame_init( inner ); inner->prev = frame; inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */ + inner->procedure = parse; for( p = parse->left; p; p = p->left ) - lol_add( inner->args, (*p->right->func)( p->right, frame ) ); + lol_add( inner->args, parse_evaluate( p->right, frame ) ); /* And invoke rule */ @@ -616,14 +631,17 @@ compile_rule( return result; } -static void argument_error( char* message, RULE* rule, LOL* actual, LIST* arg ) +static void argument_error( char* message, RULE* rule, FRAME* frame, LIST* arg ) { - printf( "### argument error\n# rule %s ( ", rule->name ); + LOL* actual = frame->args; + assert( frame->procedure != 0 ); + backtrace_line( frame->prev ); + printf( "*** argument error\n* rule %s ( ", frame->procedure->file, frame->procedure->line, frame->rulename ); lol_print( rule->arguments->data ); - printf( ")\n# called with: ( " ); + printf( ")\n* called with: ( " ); lol_print( actual ); - printf( ")\n# %s %s", message, arg ? arg->string : "" ); - printf("\n"); + printf( ")\n* %s %s\n", message, arg ? arg->string : "" ); + backtrace( frame->prev ); exit(1); } @@ -632,10 +650,11 @@ static void argument_error( char* message, RULE* rule, LOL* actual, LIST* arg ) * collect_arguments() - local argument checking and collection */ static SETTINGS * -collect_arguments( RULE* rule, LOL* all_actual ) +collect_arguments( RULE* rule, FRAME* frame ) { SETTINGS *locals = 0; + LOL* all_actual = frame->args; LOL *all_formal = rule->arguments ? rule->arguments->data : 0; if ( all_formal ) /* Nothing to set; nothing to check */ { @@ -662,7 +681,7 @@ collect_arguments( RULE* rule, LOL* all_actual ) if ( !actual && modifier != '?' && modifier != '*' ) { - argument_error( "missing argument", rule, all_actual, formal ); + argument_error( "missing argument", rule, frame, formal ); } switch ( modifier ) @@ -692,7 +711,7 @@ collect_arguments( RULE* rule, LOL* all_actual ) if ( actual ) { - argument_error( "extra argument", rule, all_actual, actual ); + argument_error( "extra argument", rule, frame, actual ); } } } @@ -804,7 +823,7 @@ evaluate_rule( if ( DEBUG_COMPILE ) { - debug_compile( 1, l->string ); + debug_compile( 1, l->string, frame); lol_print( frame->args ); printf( "\n" ); } @@ -823,13 +842,23 @@ evaluate_rule( list_free( l ); - if ( DEBUG_PROFILE && rule->procedure ) - profile_enter( rule->procedure->rulename, prof ); + /* record current rule name in frame */ + if ( rule->procedure ) + { + frame->rulename = rule->procedure->rulename; + /* and enter record profile info */ + if ( DEBUG_PROFILE ) + profile_enter( rule->procedure->rulename, prof ); + } /* Check traditional targets $(<) and sources $(>) */ if( !rule->actions && !rule->procedure ) + { + backtrace_line( frame->prev ); printf( "warning: unknown rule %s\n", rule->name ); + backtrace( frame->prev ); + } /* If this rule will be executed for updating the targets */ /* then construct the action for make(). */ @@ -859,12 +888,12 @@ evaluate_rule( if( rule->procedure ) { - SETTINGS *local_args = collect_arguments( rule, frame->args ); + SETTINGS *local_args = collect_arguments( rule, frame ); PARSE *parse = rule->procedure; parse_refer( parse ); pushsettings( local_args ); - result = (*parse->func)( parse, frame ); + result = parse_evaluate( parse, frame ); popsettings( local_args ); parse_free( parse ); @@ -880,7 +909,7 @@ evaluate_rule( profile_exit( prof ); if( DEBUG_COMPILE ) - debug_compile( -1, 0 ); + debug_compile( -1, 0, frame); return result; } @@ -899,8 +928,8 @@ compile_rules( { /* Ignore result from first statement; return the 2nd. */ - list_free( (*parse->left->func)( parse->left, frame ) ); - return (*parse->right->func)( parse->right, frame ); + list_free( parse_evaluate( parse->left, frame ) ); + return parse_evaluate( parse->right, frame ); } /* @@ -916,8 +945,8 @@ compile_set( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *l; int setflag; char *trace; @@ -932,7 +961,7 @@ compile_set( if( DEBUG_COMPILE ) { - debug_compile( 0, "set" ); + debug_compile( 0, "set", frame); list_print( nt ); printf( " %s ", trace ); list_print( ns ); @@ -961,13 +990,13 @@ compile_set_module( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *l; if( DEBUG_COMPILE ) { - debug_compile( 0, "set module" ); + debug_compile( 0, "set module", frame); printf( "(%s)", frame->module->name ); list_print( nt ); printf( " = " ); @@ -1011,10 +1040,10 @@ compile_setcomp( PARSE *p; arg_list = args_new(); for( p = parse->right; p; p = p->left ) - lol_add( arg_list->data, (*p->right->func)( p->right, frame ) ); + lol_add( arg_list->data, parse_evaluate( p->right, frame ) ); } - new_rule_body( frame->module, parse->string, arg_list, parse->left ); + new_rule_body( frame->module, parse->string, arg_list, parse->left, parse->num ); return L0; } @@ -1035,7 +1064,7 @@ compile_setexec( PARSE *parse, FRAME *frame ) { - LIST* bindlist = (*parse->left->func)( parse->left, frame ); + LIST* bindlist = parse_evaluate( parse->left, frame ); new_rule_actions( frame->module, parse->string, parse->string1, bindlist, parse->num ); @@ -1056,15 +1085,15 @@ compile_settings( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->third->func)( parse->third, frame ); - LIST *targets = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->third, frame ); + LIST *targets = parse_evaluate( parse->right, frame ); LIST *ts; int append = parse->num == ASSIGN_APPEND; if( DEBUG_COMPILE ) { - debug_compile( 0, "set" ); + debug_compile( 0, "set", frame); list_print( nt ); printf( "on " ); list_print( targets ); @@ -1111,12 +1140,12 @@ compile_switch( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); LIST *result = 0; if( DEBUG_COMPILE ) { - debug_compile( 0, "switch" ); + debug_compile( 0, "switch", frame); list_print( nt ); printf( "\n" ); } @@ -1129,7 +1158,7 @@ compile_switch( { /* Get & exec parse tree for this case */ parse = parse->left->left; - result = (*parse->func)( parse, frame ); + result = parse_evaluate( parse, frame ); break; } } @@ -1274,8 +1303,9 @@ static void import_rule1( void* r_, void* data_ ) char* target_name = data->target_names ? data->target_names->string : r->name; if (data->target_names) data->target_names = list_next(data->target_names); - - import_rule( r, data->target_module, target_name ); + + if ( !r->local_only ) + import_rule( r, data->target_module, target_name ); } static LIST * @@ -1323,6 +1353,77 @@ builtin_import( return L0; } +/* Retrieve the file and line number that should be indicated for a + * given frame in debug output or an error backtrace + */ +static void frame_info( FRAME* frame, char** file, int* line ) +{ + if ( frame->procedure ) + { + char* f = frame->procedure->file; + int l = frame->procedure->line; + if ( !strcmp( f, "+" ) ) + { + f = "jambase.c"; + l += 3; + } + *file = f; + *line = l; + } + else + { + *file = "(builtin)"; + *line = -1; + } +} + +/* Print a single line of error backtrace for the given frame */ +static void backtrace_line( FRAME *frame ) +{ + char* file; + int line; + + frame_info( frame, &file, &line ); + if ( line < 0 ) + printf( "(builtin): in %s\n", frame->rulename ); + else + printf( "%s:%d: in %s\n", file, line, frame->rulename ); +} + +/* Print the entire backtrace from the given frame to the Jambase + * which invoked it. + */ +static void backtrace( FRAME *frame ) +{ + while ( frame = frame->prev ) + { + backtrace_line( frame ); + } +} + +/* A Jam version of the backtrace function, taking no arguments and + * returning a list of quadruples: FILENAME LINE MODULE. RULENAME + * describing each frame. Note that the module-name is always + * followed by a period. + */ +static LIST *builtin_backtrace( PARSE *parse, FRAME *frame ) +{ + LIST* result = L0; + while ( frame = frame->prev ) + { + char* file; + int line; + char buf[32]; + frame_info( frame, &file, &line ); + sprintf( buf, "%d", line ); + result = list_new( result, newstr( file ) ); + result = list_new( result, newstr( buf ) ); + result = list_new( result, newstr( frame->module->name ) ); + result = list_new( result, newstr( frame->rulename ) ); + } + return result; +} + /* * builtin_caller_module() - CALLER_MODULE ( levels ? ) * @@ -1370,10 +1471,13 @@ static LIST *builtin_caller_module( PARSE *parse, FRAME *frame ) */ static void -debug_compile( int which, char *s ) +debug_compile( int which, char *s, FRAME* frame ) { static int level = 0; static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; + + char* file; + int line; if ( which >= 0 ) { @@ -1385,7 +1489,12 @@ debug_compile( int which, char *s ) printf( indent ); i -= 35; } - printf( "%*.*s ", i, i, indent ); + + frame_info( frame, &file, &line ); + if ( line >= 0 ) + printf( "%s:%d:%*.*s ", file, line, i, i, indent ); + else + printf( "(builtin)%*.*s ", i, i, indent ); } if( s ) diff --git a/historic/jam/src/frames.h b/historic/jam/src/frames.h index e0dc6761e..bd7936eca 100644 --- a/historic/jam/src/frames.h +++ b/historic/jam/src/frames.h @@ -1,9 +1,17 @@ +/* + * (C) Copyright David Abrahams 2001. Permission to copy, use, + * modify, sell and distribute this software is granted provided this + * copyright notice appears in all copies. This software is provided + * "as is" without express or implied warranty, and with no claim as + * to its suitability for any purpose. + */ #ifndef FRAMES_DWA20011021_H # define FRAMES_DWA20011021_H # include "lists.h" # include "modules.h" +typedef struct _PARSE PARSE; typedef struct frame FRAME; struct frame @@ -11,6 +19,8 @@ struct frame FRAME* prev; LOL args[1]; module* module; + PARSE* procedure; + char* rulename; }; void frame_init( FRAME* ); /* implemented in compile.c */ diff --git a/historic/jam/src/jam.h b/historic/jam/src/jam.h index 2d2c2b350..816b1b56e 100644 --- a/historic/jam/src/jam.h +++ b/historic/jam/src/jam.h @@ -453,7 +453,7 @@ int unlink( char *f ); /* In filevms.c */ /* Jam private definitions below. */ -# define DEBUG_MAX 12 +# define DEBUG_MAX 13 struct globs { int noexec; @@ -488,4 +488,5 @@ extern struct globs globs; # define DEBUG_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */ # define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */ +# define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */ diff --git a/historic/jam/src/jamgram.c b/historic/jam/src/jamgram.c index 1c64c2f5b..3d85c487c 100644 --- a/historic/jam/src/jamgram.c +++ b/historic/jam/src/jamgram.c @@ -75,8 +75,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -101,11 +100,11 @@ -#define YYFINAL 145 +#define YYFINAL 143 #define YYFLAG -32768 #define YYNTBASE 46 -#define YYTRANSLATE(x) ((unsigned)(x) <= 299 ? yytranslate[x] : 64) +#define YYTRANSLATE(x) ((unsigned)(x) <= 299 ? yytranslate[x] : 67) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -142,52 +141,52 @@ static const char yytranslate[] = { 0, #if YYDEBUG != 0 static const short yyprhs[] = { 0, - 0, 1, 3, 4, 6, 8, 11, 17, 18, 21, - 25, 29, 33, 38, 44, 51, 55, 63, 72, 78, - 84, 90, 96, 104, 111, 115, 116, 117, 127, 129, - 131, 133, 136, 138, 142, 146, 150, 154, 158, 162, - 166, 169, 173, 177, 181, 182, 185, 190, 192, 196, - 198, 199, 202, 204, 209, 210, 213, 215, 217, 219, - 221, 223, 225, 226 + 0, 1, 3, 5, 7, 9, 12, 18, 19, 22, + 24, 28, 29, 31, 32, 36, 40, 44, 49, 55, + 62, 66, 75, 81, 87, 93, 99, 107, 113, 114, + 115, 125, 127, 129, 131, 134, 136, 140, 144, 148, + 152, 156, 160, 164, 167, 171, 175, 179, 180, 183, + 188, 190, 194, 196, 197, 200, 202, 207, 208, 211, + 213, 215, 217, 219, 221, 223, 224 }; static const short yyrhs[] = { -1, - 48, 0, 0, 48, 0, 50, 0, 50, 48, 0, - 30, 58, 49, 10, 47, 0, 0, 13, 58, 0, - 41, 47, 43, 0, 29, 58, 10, 0, 44, 57, - 10, 0, 60, 53, 58, 10, 0, 31, 30, 58, - 49, 10, 0, 60, 32, 58, 53, 58, 10, 0, - 35, 58, 10, 0, 25, 44, 28, 58, 41, 47, - 43, 0, 25, 30, 44, 28, 58, 41, 47, 43, - 0, 37, 58, 41, 55, 43, 0, 26, 54, 41, - 47, 43, 0, 31, 58, 41, 47, 43, 0, 40, - 54, 41, 47, 43, 0, 26, 54, 41, 47, 43, - 23, 50, 0, 36, 44, 6, 57, 7, 50, 0, - 36, 44, 50, 0, 0, 0, 19, 61, 44, 63, - 41, 51, 45, 52, 43, 0, 13, 0, 8, 0, - 16, 0, 22, 13, 0, 60, 0, 60, 13, 60, - 0, 60, 4, 60, 0, 60, 11, 60, 0, 60, - 12, 60, 0, 60, 14, 60, 0, 60, 15, 60, - 0, 60, 28, 58, 0, 3, 54, 0, 54, 5, - 54, 0, 54, 42, 54, 0, 6, 54, 7, 0, - 0, 56, 55, 0, 21, 44, 9, 47, 0, 58, - 0, 58, 9, 57, 0, 59, 0, 0, 59, 60, - 0, 44, 0, 17, 44, 57, 18, 0, 0, 61, - 62, 0, 39, 0, 38, 0, 27, 0, 34, 0, - 33, 0, 24, 0, 0, 20, 58, 0 + 48, 0, 49, 0, 48, 0, 53, 0, 53, 48, + 0, 30, 61, 50, 10, 47, 0, 0, 13, 61, + 0, 49, 0, 6, 60, 7, 0, 0, 30, 0, + 0, 41, 47, 43, 0, 29, 61, 10, 0, 44, + 60, 10, 0, 63, 56, 61, 10, 0, 31, 30, + 61, 50, 10, 0, 63, 32, 61, 56, 61, 10, + 0, 35, 61, 10, 0, 25, 52, 44, 28, 61, + 41, 47, 43, 0, 37, 61, 41, 58, 43, 0, + 26, 57, 41, 47, 43, 0, 31, 61, 41, 47, + 43, 0, 40, 57, 41, 47, 43, 0, 26, 57, + 41, 47, 43, 23, 53, 0, 52, 36, 44, 51, + 53, 0, 0, 0, 19, 64, 44, 66, 41, 54, + 45, 55, 43, 0, 13, 0, 8, 0, 16, 0, + 22, 13, 0, 63, 0, 63, 13, 63, 0, 63, + 4, 63, 0, 63, 11, 63, 0, 63, 12, 63, + 0, 63, 14, 63, 0, 63, 15, 63, 0, 63, + 28, 61, 0, 3, 57, 0, 57, 5, 57, 0, + 57, 42, 57, 0, 6, 57, 7, 0, 0, 59, + 58, 0, 21, 44, 9, 47, 0, 61, 0, 61, + 9, 60, 0, 62, 0, 0, 62, 63, 0, 44, + 0, 17, 44, 60, 18, 0, 0, 64, 65, 0, + 39, 0, 38, 0, 27, 0, 34, 0, 33, 0, + 24, 0, 0, 20, 61, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 133, 135, 146, 148, 152, 154, 156, 160, 162, 166, - 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, - 188, 190, 192, 194, 196, 198, 201, 203, 210, 212, - 214, 216, 224, 226, 228, 230, 232, 234, 236, 238, - 240, 242, 244, 246, 256, 258, 262, 271, 273, 283, - 287, 289, 293, 295, 305, 307, 311, 313, 315, 317, - 319, 321, 330, 332 + 132, 134, 145, 147, 151, 153, 155, 159, 163, 165, + 169, 171, 175, 177, 181, 183, 185, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 207, 209, 212, + 214, 221, 223, 225, 227, 235, 237, 239, 241, 243, + 245, 247, 249, 251, 253, 255, 257, 267, 269, 273, + 282, 284, 294, 298, 300, 304, 306, 316, 318, 322, + 324, 326, 328, 330, 332, 341, 343 }; #endif @@ -200,127 +199,122 @@ static const char * const yytname[] = { "$","error","$undefined.","_BANG", "_LBRACKET","_RBRACKET","ACTIONS","BIND","CASE","DEFAULT","ELSE","EXISTING", "FOR","IF","IGNORE","IN","INCLUDE","LOCAL","MODULE","ON","PIECEMEAL","QUIETLY", "RETURN","RULE","SWITCH","TOGETHER","UPDATED","WHILE","_LBRACE","_BARBAR","_RBRACE", -"ARG","STRING","run","block","rules","assign_list_opt","rule","@1","@2","assign", -"cond","cases","case","lol","list","listp","arg","eflags","eflag","bindlist", NULL +"ARG","STRING","run","block","rules","null","assign_list_opt","arglist_opt", +"local_opt","rule","@1","@2","assign","cond","cases","case","lol","list","listp", +"arg","eflags","eflag","bindlist", NULL }; #endif static const short yyr1[] = { 0, - 46, 46, 47, 47, 48, 48, 48, 49, 49, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 51, 52, 50, 53, 53, - 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 55, 55, 56, 57, 57, 58, - 59, 59, 60, 60, 61, 61, 62, 62, 62, 62, - 62, 62, 63, 63 + 46, 46, 47, 47, 48, 48, 48, 49, 50, 50, + 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 54, 55, + 53, 56, 56, 56, 56, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 58, 58, 59, + 60, 60, 61, 62, 62, 63, 63, 64, 64, 65, + 65, 65, 65, 65, 65, 66, 66 }; static const short yyr2[] = { 0, - 0, 1, 0, 1, 1, 2, 5, 0, 2, 3, - 3, 3, 4, 5, 6, 3, 7, 8, 5, 5, - 5, 5, 7, 6, 3, 0, 0, 9, 1, 1, - 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, - 2, 3, 3, 3, 0, 2, 4, 1, 3, 1, - 0, 2, 1, 4, 0, 2, 1, 1, 1, 1, - 1, 1, 0, 2 + 0, 1, 1, 1, 1, 2, 5, 0, 2, 1, + 3, 0, 1, 0, 3, 3, 3, 4, 5, 6, + 3, 8, 5, 5, 5, 5, 7, 5, 0, 0, + 9, 1, 1, 1, 2, 1, 3, 3, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 0, 2, 4, + 1, 3, 1, 0, 2, 1, 4, 0, 2, 1, + 1, 1, 1, 1, 1, 0, 2 }; static const short yydefact[] = { 1, - 0, 55, 0, 0, 51, 51, 51, 51, 0, 51, - 0, 3, 53, 2, 5, 0, 51, 0, 0, 0, - 0, 0, 53, 0, 33, 0, 50, 8, 51, 0, - 0, 0, 0, 0, 0, 4, 0, 48, 6, 30, - 29, 31, 0, 51, 51, 0, 62, 59, 61, 60, - 58, 57, 63, 56, 0, 51, 41, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 51, 11, 52, - 51, 0, 8, 3, 16, 51, 25, 45, 3, 10, - 12, 51, 32, 0, 0, 54, 51, 0, 51, 0, - 44, 42, 0, 43, 35, 36, 37, 34, 38, 39, - 40, 9, 3, 0, 0, 0, 0, 0, 45, 0, - 49, 51, 13, 64, 26, 0, 3, 20, 7, 14, - 21, 0, 0, 19, 46, 22, 0, 0, 3, 0, - 0, 24, 3, 15, 27, 0, 17, 23, 47, 0, - 18, 28, 0, 0, 0 + 0, 58, 14, 0, 54, 54, 54, 54, 54, 0, + 8, 56, 2, 0, 5, 0, 54, 0, 13, 0, + 0, 0, 56, 0, 36, 0, 53, 8, 54, 0, + 0, 0, 0, 0, 4, 3, 0, 51, 0, 6, + 33, 32, 34, 0, 54, 54, 0, 65, 62, 64, + 63, 61, 60, 66, 59, 0, 44, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 54, 16, 55, + 54, 10, 0, 8, 8, 21, 48, 8, 15, 17, + 54, 12, 35, 0, 0, 57, 54, 0, 54, 47, + 45, 0, 46, 38, 39, 40, 37, 41, 42, 43, + 9, 8, 0, 0, 0, 0, 48, 0, 52, 54, + 14, 54, 18, 67, 29, 0, 24, 7, 19, 25, + 0, 23, 49, 26, 0, 28, 0, 0, 8, 14, + 8, 11, 20, 30, 0, 27, 50, 0, 22, 31, + 0, 0, 0 }; -static const short yydefgoto[] = { 143, - 35, 36, 72, 15, 128, 140, 45, 24, 108, 109, - 37, 38, 27, 16, 18, 54, 88 +static const short yydefgoto[] = { 141, + 34, 35, 36, 73, 111, 14, 15, 128, 138, 46, + 24, 106, 107, 37, 38, 27, 16, 18, 55, 88 }; -static const short yypact[] = { 106, - -34,-32768, -13, 8,-32768,-32768, -17,-32768, -16,-32768, - 8, 106, 24,-32768, 106, 174,-32768, 95, -15, -12, - 8, 8,-32768, 4, 166, 22, -2, 23,-32768, -6, - 28, 80, 2, 18, 1,-32768, 39, 45,-32768,-32768, --32768,-32768, 42,-32768,-32768, 43,-32768,-32768,-32768,-32768, --32768,-32768, 49,-32768, 34,-32768,-32768, 15, 8, 106, - 8, -2, -2, -2, -2, -2, -2,-32768,-32768,-32768, --32768, 60, 23, 106,-32768,-32768,-32768, 52, 106,-32768, --32768,-32768,-32768, 59, 64,-32768,-32768, 36,-32768, 37, --32768,-32768, 40, 74,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, 106, 85, 53, 91, 56, 58, 52, 61, --32768,-32768,-32768,-32768,-32768, 67, 106, 79,-32768,-32768, --32768, 132, 101,-32768,-32768,-32768, 102, 68, 106, 71, - 132,-32768, 106,-32768,-32768, 75,-32768,-32768,-32768, 83, --32768,-32768, 127, 130,-32768 +static const short yypact[] = { 75, + -34,-32768, -16, 6,-32768, -21, -10,-32768,-32768, 6, + 75, 20,-32768, -3, 75, 121,-32768, 127,-32768, -18, + 6, 6,-32768, 11, 135, 25, -6, 23,-32768, -2, + 33, 3, 26, 4,-32768,-32768, 38, 49, 15,-32768, +-32768,-32768,-32768, 47,-32768,-32768, 43,-32768,-32768,-32768, +-32768,-32768,-32768, 42,-32768, 44,-32768, 14, 6, 75, + 6, -6, -6, -6, -6, -6, -6,-32768,-32768,-32768, +-32768,-32768, 61, 23, 75,-32768, 53, 75,-32768,-32768, +-32768, 69,-32768, 57, 67,-32768,-32768, 39,-32768,-32768, +-32768, 50, 76,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768, 75, 85, 54, 52, 56, 53, 59,-32768,-32768, + 101,-32768,-32768,-32768,-32768, 62, 86,-32768,-32768,-32768, + 99,-32768,-32768,-32768, 106,-32768, 104, 72, 75, 101, + 75,-32768,-32768,-32768, 78,-32768,-32768, 79,-32768,-32768, + 123, 124,-32768 }; static const short yypgoto[] = {-32768, - -53, 12, 65, -28,-32768,-32768, 69, -3, 31,-32768, - -11, -5,-32768, 26,-32768,-32768,-32768 + -53, 27, -20, 51,-32768, 125, -98,-32768,-32768, 60, + -4, 28,-32768, -12, -5,-32768, 24,-32768,-32768,-32768 }; -#define YYLAST 206 +#define YYLAST 171 static const short yytable[] = { 26, - 28, 30, 31, 77, 33, 46, 93, 34, 59, 17, - 21, 14, 29, 22, 1, 56, 19, 57, 58, 59, - 105, 91, 59, 73, 1, 110, 39, 32, 55, 25, - 20, 69, -51, -51, 74, 71, 25, 75, 84, 85, - -51, 23, 78, 80, 60, 61, 25, 25, 81, 119, - 90, 23, 70, 82, 83, 92, 61, 94, 79, 61, - 86, 89, 101, 130, 106, 102, 40, -51, 87, 103, - 111, 41, 107, 113, 42, 136, 115, 117, 59, 139, - 43, 114, 118, 116, 25, 76, 25, 95, 96, 97, - 98, 99, 100, 132, 120, 121, 1, 122, 2, 123, - 124, 131, 138, 126, 3, 4, 127, 129, 5, 133, - 7, 134, 135, 137, 8, 9, 10, 141, 47, 11, - 12, 48, 1, 13, 2, 142, 144, 49, 50, 145, - 3, 4, 51, 52, 5, 6, 7, 104, 53, 125, - 8, 9, 10, 0, 0, 11, 12, 0, 1, 13, - 2, 0, 112, 0, 0, 0, 3, 4, 0, 0, - 5, 0, 7, 0, 0, 0, 8, 9, 10, 62, - 0, 11, 12, 0, 0, 13, 63, 64, 65, 66, - 67, 40, 0, 0, 0, 0, 41, 0, 0, 42, - 0, 0, 0, 68, 0, 43, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 44 + 28, 30, 31, 32, 47, 33, 92, 72, 21, 17, + 1, 22, 126, 19, -13, 59, 57, 58, 59, 29, + 90, 104, 1, 74, 108, 56, 13, 25, -54, -54, + 59, 136, 39, 25, 69, 71, -54, 23, 75, 84, + 85, 40, 76, 77, 25, 25, 79, 80, 118, 23, + 70, 60, 61, 72, 91, 61, 93, 81, 82, 83, + 86, 87, 100, -54, 41, 101, 78, 61, 109, 42, + 102, 89, 43, 105, 110, 135, 113, 137, 44, 115, + 59, 114, 25, 116, 25, 94, 95, 96, 97, 98, + 99, 1, 117, 2, 119, 121, 120, 125, 122, 3, + 4, 124, 129, 5, 6, 7, 127, 131, 130, 8, + -14, 9, 132, 133, 10, 11, 134, 1, 12, 2, + 139, 140, 142, 143, 103, 3, 4, 20, 41, 5, + 19, 7, 0, 42, 123, 8, 43, 9, 62, 0, + 10, 11, 44, 112, 12, 63, 64, 65, 66, 67, + 48, 0, 45, 49, 0, 0, 0, 0, 0, 50, + 51, 0, 68, 0, 52, 53, 0, 0, 0, 0, + 54 }; static const short yycheck[] = { 5, - 6, 7, 8, 32, 10, 17, 60, 11, 5, 44, - 3, 0, 30, 6, 17, 28, 30, 21, 22, 5, - 74, 7, 5, 29, 17, 79, 15, 44, 44, 4, - 44, 10, 9, 10, 41, 13, 11, 10, 44, 45, - 17, 44, 41, 43, 41, 42, 21, 22, 10, 103, - 56, 44, 27, 9, 13, 59, 42, 61, 41, 42, - 18, 28, 68, 117, 76, 71, 8, 44, 20, 10, - 82, 13, 21, 10, 16, 129, 41, 41, 5, 133, - 22, 87, 43, 89, 59, 6, 61, 62, 63, 64, - 65, 66, 67, 122, 10, 43, 17, 7, 19, 44, - 43, 23, 131, 43, 25, 26, 112, 41, 29, 9, - 31, 10, 45, 43, 35, 36, 37, 43, 24, 40, - 41, 27, 17, 44, 19, 43, 0, 33, 34, 0, - 25, 26, 38, 39, 29, 30, 31, 73, 44, 109, - 35, 36, 37, -1, -1, 40, 41, -1, 17, 44, - 19, -1, 84, -1, -1, -1, 25, 26, -1, -1, - 29, -1, 31, -1, -1, -1, 35, 36, 37, 4, - -1, 40, 41, -1, -1, 44, 11, 12, 13, 14, - 15, 8, -1, -1, -1, -1, 13, -1, -1, 16, - -1, -1, -1, 28, -1, 22, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 32 + 6, 7, 8, 9, 17, 10, 60, 28, 3, 44, + 17, 6, 111, 30, 36, 5, 21, 22, 5, 30, + 7, 75, 17, 29, 78, 44, 0, 4, 9, 10, + 5, 130, 36, 10, 10, 13, 17, 44, 41, 45, + 46, 15, 10, 41, 21, 22, 43, 10, 102, 44, + 27, 41, 42, 74, 59, 42, 61, 9, 44, 13, + 18, 20, 68, 44, 8, 71, 41, 42, 81, 13, + 10, 28, 16, 21, 6, 129, 10, 131, 22, 41, + 5, 87, 59, 89, 61, 62, 63, 64, 65, 66, + 67, 17, 43, 19, 10, 44, 43, 110, 43, 25, + 26, 43, 41, 29, 30, 31, 112, 9, 23, 35, + 36, 37, 7, 10, 40, 41, 45, 17, 44, 19, + 43, 43, 0, 0, 74, 25, 26, 3, 8, 29, + 30, 31, -1, 13, 107, 35, 16, 37, 4, -1, + 40, 41, 22, 84, 44, 11, 12, 13, 14, 15, + 24, -1, 32, 27, -1, -1, -1, -1, -1, 33, + 34, -1, 28, -1, 38, 39, -1, -1, -1, -1, + 44 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ @@ -824,7 +818,7 @@ case 2: { parse_save( yyvsp[0].parse ); ; break;} case 3: -{ yyval.parse = pnull(); ; +{ yyval.parse = yyvsp[0].parse; ; break;} case 4: { yyval.parse = yyvsp[0].parse; ; @@ -845,168 +839,177 @@ case 9: { yyval.parse = yyvsp[0].parse; ; break;} case 10: -{ yyval.parse = yyvsp[-1].parse; ; +{ yyval.parse = yyvsp[0].parse; ; break;} case 11: -{ yyval.parse = pincl( yyvsp[-1].parse ); ; +{ yyval.parse = yyvsp[-1].parse; ; break;} case 12: -{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; - break;} -case 13: -{ yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; - break;} -case 14: -{ yyval.parse = psetmodule( yyvsp[-2].parse, yyvsp[-1].parse ); ; - break;} -case 15: -{ yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; - break;} -case 16: -{ yyval.parse = yyvsp[-1].parse; ; - break;} -case 17: -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, 0 ); ; - break;} -case 18: -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, 1 ); ; - break;} -case 19: -{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 20: -{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; - break;} -case 21: -{ yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 22: -{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 23: -{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; - break;} -case 24: -{ yyval.parse = psetc_args( yyvsp[-4].string, yyvsp[0].parse, yyvsp[-2].parse ); ; - break;} -case 25: -{ yyval.parse = psetc( yyvsp[-1].string, yyvsp[0].parse ); ; - break;} -case 26: -{ yymode( SCAN_STRING ); ; - break;} -case 27: -{ yymode( SCAN_NORMAL ); ; - break;} -case 28: -{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; - break;} -case 29: -{ yyval.number = ASSIGN_SET; ; - break;} -case 30: -{ yyval.number = ASSIGN_APPEND; ; - break;} -case 31: -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 32: -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 33: -{ yyval.parse = pcnode( COND_EXISTS, yyvsp[0].parse, pnull() ); ; - break;} -case 34: -{ yyval.parse = pcnode( COND_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 35: -{ yyval.parse = pcnode( COND_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 36: -{ yyval.parse = pcnode( COND_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 37: -{ yyval.parse = pcnode( COND_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 38: -{ yyval.parse = pcnode( COND_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 39: -{ yyval.parse = pcnode( COND_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 40: -{ yyval.parse = pcnode( COND_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 41: -{ yyval.parse = pcnode( COND_NOT, yyvsp[0].parse, P0 ); ; - break;} -case 42: -{ yyval.parse = pcnode( COND_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 43: -{ yyval.parse = pcnode( COND_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 44: -{ yyval.parse = yyvsp[-1].parse; ; - break;} -case 45: { yyval.parse = P0; ; break;} -case 46: -{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; +case 13: +{ yyval.number = 1; ; break;} -case 47: -{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; - break;} -case 48: -{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; - break;} -case 49: -{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; - break;} -case 50: -{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; - break;} -case 51: -{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; - break;} -case 52: -{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; - break;} -case 53: -{ yyval.parse = plist( yyvsp[0].string ); ; - break;} -case 54: -{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; - break;} -case 55: +case 14: { yyval.number = 0; ; break;} +case 15: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 16: +{ yyval.parse = pincl( yyvsp[-1].parse ); ; + break;} +case 17: +{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; + break;} +case 18: +{ yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; + break;} +case 19: +{ yyval.parse = psetmodule( yyvsp[-2].parse, yyvsp[-1].parse ); ; + break;} +case 20: +{ yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; + break;} +case 21: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 22: +{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-6].number ); ; + break;} +case 23: +{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 24: +{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; + break;} +case 25: +{ yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 26: +{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 27: +{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; + break;} +case 28: +{ yyval.parse = psetc( yyvsp[-2].string, yyvsp[0].parse, yyvsp[-1].parse, yyvsp[-4].number ); ; + break;} +case 29: +{ yymode( SCAN_STRING ); ; + break;} +case 30: +{ yymode( SCAN_NORMAL ); ; + break;} +case 31: +{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; + break;} +case 32: +{ yyval.number = ASSIGN_SET; ; + break;} +case 33: +{ yyval.number = ASSIGN_APPEND; ; + break;} +case 34: +{ yyval.number = ASSIGN_DEFAULT; ; + break;} +case 35: +{ yyval.number = ASSIGN_DEFAULT; ; + break;} +case 36: +{ yyval.parse = pcnode( COND_EXISTS, yyvsp[0].parse, pnull() ); ; + break;} +case 37: +{ yyval.parse = pcnode( COND_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 38: +{ yyval.parse = pcnode( COND_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 39: +{ yyval.parse = pcnode( COND_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 40: +{ yyval.parse = pcnode( COND_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 41: +{ yyval.parse = pcnode( COND_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 42: +{ yyval.parse = pcnode( COND_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 43: +{ yyval.parse = pcnode( COND_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 44: +{ yyval.parse = pcnode( COND_NOT, yyvsp[0].parse, P0 ); ; + break;} +case 45: +{ yyval.parse = pcnode( COND_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 46: +{ yyval.parse = pcnode( COND_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 47: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 48: +{ yyval.parse = P0; ; + break;} +case 49: +{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; + break;} +case 50: +{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; + break;} +case 51: +{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; + break;} +case 52: +{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; + break;} +case 53: +{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; + break;} +case 54: +{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; + break;} +case 55: +{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; + break;} case 56: -{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; +{ yyval.parse = plist( yyvsp[0].string ); ; break;} case 57: -{ yyval.number = EXEC_UPDATED; ; +{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; break;} case 58: -{ yyval.number = EXEC_TOGETHER; ; +{ yyval.number = 0; ; break;} case 59: -{ yyval.number = EXEC_IGNORE; ; +{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; break;} case 60: -{ yyval.number = EXEC_QUIETLY; ; +{ yyval.number = EXEC_UPDATED; ; break;} case 61: -{ yyval.number = EXEC_PIECEMEAL; ; +{ yyval.number = EXEC_TOGETHER; ; break;} case 62: -{ yyval.number = EXEC_EXISTING; ; +{ yyval.number = EXEC_IGNORE; ; break;} case 63: -{ yyval.parse = pnull(); ; +{ yyval.number = EXEC_QUIETLY; ; break;} case 64: +{ yyval.number = EXEC_PIECEMEAL; ; + break;} +case 65: +{ yyval.number = EXEC_EXISTING; ; + break;} +case 66: +{ yyval.parse = pnull(); ; + break;} +case 67: { yyval.parse = yyvsp[0].parse; ; break;} } diff --git a/historic/jam/src/jamgram.y b/historic/jam/src/jamgram.y index ba6458f67..7dc5eed7c 100644 --- a/historic/jam/src/jamgram.y +++ b/historic/jam/src/jamgram.y @@ -117,8 +117,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -143,8 +142,8 @@ run : /* empty */ * right-recursive so rules execute in order. */ -block : /* empty */ - { $$.parse = pnull(); } +block : null + { $$.parse = $1.parse; } | rules { $$.parse = $1.parse; } ; @@ -157,12 +156,28 @@ rules : rule { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } ; -assign_list_opt : /* empty */ - { $$.parse = pnull(); } - | _EQUALS list - { $$.parse = $2.parse; } +null : /* empty */ + { $$.parse = pnull(); } ; +assign_list_opt : _EQUALS list + { $$.parse = $2.parse; } + | null + { $$.parse = $1.parse; } + ; + +arglist_opt : _LPAREN lol _RPAREN + { $$.parse = $2.parse; } + | + { $$.parse = P0; } + ; + +local_opt : LOCAL + { $$.number = 1; } + | /* empty */ + { $$.number = 0; } + ; + rule : _LBRACE block _RBRACE { $$.parse = $2.parse; } | INCLUDE list _SEMIC @@ -177,10 +192,8 @@ rule : _LBRACE block _RBRACE { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | RETURN list _SEMIC { $$.parse = $2.parse; } - | FOR ARG IN list _LBRACE block _RBRACE - { $$.parse = pfor( $2.string, $4.parse, $6.parse, 0 ); } - | FOR LOCAL ARG IN list _LBRACE block _RBRACE - { $$.parse = pfor( $3.string, $5.parse, $7.parse, 1 ); } + | FOR local_opt ARG IN list _LBRACE block _RBRACE + { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } | SWITCH list _LBRACE cases _RBRACE { $$.parse = pswitch( $2.parse, $4.parse ); } | IF cond _LBRACE block _RBRACE @@ -191,10 +204,8 @@ rule : _LBRACE block _RBRACE { $$.parse = pwhile( $2.parse, $4.parse ); } | IF cond _LBRACE block _RBRACE ELSE rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | RULE ARG _LPAREN lol _RPAREN rule - { $$.parse = psetc_args( $2.string, $6.parse, $4.parse ); } - | RULE ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | local_opt RULE ARG arglist_opt rule + { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } | ACTIONS eflags ARG bindlist _LBRACE { yymode( SCAN_STRING ); } STRING diff --git a/historic/jam/src/jamgram.yy b/historic/jam/src/jamgram.yy index a515e0ad1..56f45dd1d 100644 --- a/historic/jam/src/jamgram.yy +++ b/historic/jam/src/jamgram.yy @@ -76,8 +76,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -102,8 +101,8 @@ run : /* empty */ * right-recursive so rules execute in order. */ -block : /* empty */ - { $$.parse = pnull(); } +block : null + { $$.parse = $1.parse; } | rules { $$.parse = $1.parse; } ; @@ -116,12 +115,28 @@ rules : rule { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } ; -assign_list_opt : /* empty */ - { $$.parse = pnull(); } - | `=` list - { $$.parse = $2.parse; } +null : /* empty */ + { $$.parse = pnull(); } ; +assign_list_opt : `=` list + { $$.parse = $2.parse; } + | null + { $$.parse = $1.parse; } + ; + +arglist_opt : `(` lol `)` + { $$.parse = $2.parse; } + | + { $$.parse = P0; } + ; + +local_opt : `local` + { $$.number = 1; } + | /* empty */ + { $$.number = 0; } + ; + rule : `{` block `}` { $$.parse = $2.parse; } | `include` list `;` @@ -136,10 +151,8 @@ rule : `{` block `}` { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | `return` list `;` { $$.parse = $2.parse; } - | `for` ARG `in` list `{` block `}` - { $$.parse = pfor( $2.string, $4.parse, $6.parse, 0 ); } - | `for` `local` ARG `in` list `{` block `}` - { $$.parse = pfor( $3.string, $5.parse, $7.parse, 1 ); } + | `for` local_opt ARG `in` list `{` block `}` + { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } | `switch` list `{` cases `}` { $$.parse = pswitch( $2.parse, $4.parse ); } | `if` cond `{` block `}` @@ -150,10 +163,8 @@ rule : `{` block `}` { $$.parse = pwhile( $2.parse, $4.parse ); } | `if` cond `{` block `}` `else` rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | `rule` ARG `(` lol `)` rule - { $$.parse = psetc_args( $2.string, $6.parse, $4.parse ); } - | `rule` ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | local_opt `rule` ARG arglist_opt rule + { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } | `actions` eflags ARG bindlist `{` { yymode( SCAN_STRING ); } STRING diff --git a/historic/jam/src/make.c b/historic/jam/src/make.c index 6b86901b7..b8c201f42 100644 --- a/historic/jam/src/make.c +++ b/historic/jam/src/make.c @@ -75,6 +75,12 @@ typedef struct { static void make0( TARGET *t, int pbinding, time_t ptime, int depth, COUNTS *counts, int anyhow ); +#define OPT_GRAPH_DEBUG_EXT + +#ifdef OPT_GRAPH_DEBUG_EXT +static void dependGraphOutput( TARGET *t, int depth ); +#endif + static char *target_fate[] = { "init", /* T_FATE_INIT */ @@ -122,6 +128,17 @@ make( make0( t, T_BIND_UNBOUND, (time_t)0, 0, counts, anyhow ); } + +#ifdef OPT_GRAPH_DEBUG_EXT + if( DEBUG_GRAPH ) + { + for( i = 0; i < n_targets; i++ ) + { + TARGET *t = bindtarget( targets[i] ); + dependGraphOutput( t, 0 ); + } + } +#endif if( DEBUG_MAKE ) { @@ -454,3 +471,96 @@ make0( spaces( depth ), t->name ); } + +#ifdef OPT_GRAPH_DEBUG_EXT + +/* + * dependGraphOutput() - output the DG after make0 has run + */ + +static void +dependGraphOutput( TARGET *t, int depth ) +{ + TARGETS *c; + + if ( (t->flags & T_FLAG_VISITED) != 0 + || !t->name + || !t->boundname) + return; + + t->flags |= T_FLAG_VISITED; + + switch (t->fate) + { + case T_FATE_TOUCHED: + case T_FATE_MISSING: + case T_FATE_OUTDATED: + case T_FATE_UPDATE: + printf( "->%s%2d Name: %s\n", spaces(depth), depth, t->name ); + break; + default: + printf( " %s%2d Name: %s\n", spaces(depth), depth, t->name ); + break; + } + + if( strcmp (t->name, t->boundname) ) + { + printf( " %s Loc: %s\n", spaces(depth), t->boundname ); + } + + switch (t->fate) { + case T_FATE_STABLE: + printf( " %s : Stable\n", spaces(depth) ); + break; + case T_FATE_NEWER: + printf( " %s : Newer\n", spaces(depth) ); + break; + case T_FATE_ISTMP: + printf( " %s : Up to date temp file\n", spaces(depth) ); + break; + case T_FATE_TOUCHED: + printf( " %s : Been touched, updating it\n", + spaces(depth) ); + break; + case T_FATE_MISSING: + printf( " %s : Missing, creating it\n", spaces(depth) ); + break; + case T_FATE_OUTDATED: + printf( " %s : Outdated, updating it\n", spaces(depth) ); + break; + case T_FATE_UPDATE: + printf( " %s : Updating it\n", spaces(depth) ); + break; + case T_FATE_CANTFIND: + printf( " %s : Can't find it\n", spaces(depth) ); + break; + case T_FATE_CANTMAKE: + printf( " %s : Can't make it\n", spaces(depth) ); + break; + } + + for( c = t->deps[ T_DEPS_DEPENDS ]; c; c = c->next ) + { + printf( " %s : Depends on %s (%s)\n", spaces(depth), + c->target->name, target_fate[ c->target->fate ] ); + } + + for( c = t->deps[ T_DEPS_INCLUDES ]; c; c = c->next ) + { + printf( " %s : Includes %s (%s)\n", spaces(depth), + c->target->name, target_fate[ c->target->fate ] ); + } + + for( c = t->deps[ T_DEPS_DEPENDS ]; c; c = c->next ) + { + dependGraphOutput( c->target, depth + 1 ); + } + + for( c = t->deps[ T_DEPS_INCLUDES ]; c; c = c->next ) + { + dependGraphOutput( c->target, depth + 1 ); + } + +} + +#endif diff --git a/historic/jam/src/parse.c b/historic/jam/src/parse.c index 073a97537..20851d4aa 100644 --- a/historic/jam/src/parse.c +++ b/historic/jam/src/parse.c @@ -58,8 +58,7 @@ parse_file( char *f, FRAME* frame ) /* Run the parse tree. */ - (*(p->func))( p, frame ); - + parse_evaluate( p, frame ); parse_free( p ); } } @@ -92,6 +91,16 @@ parse_make( p->refs = 1; p->module = 0; p->rulename = 0; + + if ( left ) + { + p->file = left->file; + p->line = left->line; + } + else + { + yyinput_stream( &p->file, &p->line ); + } return p; } @@ -123,3 +132,9 @@ parse_free( PARSE *p ) free( (char *)p ); } + +LIST* parse_evaluate( PARSE *p, FRAME* frame ) +{ + frame->procedure = p; + return (*p->func)(p, frame); +} diff --git a/historic/jam/src/parse.h b/historic/jam/src/parse.h index 4eb949447..09b25e1a8 100644 --- a/historic/jam/src/parse.h +++ b/historic/jam/src/parse.h @@ -16,6 +16,7 @@ # define PARSE_DWA20011020_H # include "frames.h" # include "modules.h" +# include "lists.h" /* * parse.h - make and destroy parse trees as driven by the parser @@ -25,8 +26,6 @@ * parse tree node */ -typedef struct _PARSE PARSE; - struct _PARSE { LIST *(*func)( PARSE *p, FRAME *frame ); PARSE *left; @@ -34,10 +33,12 @@ struct _PARSE { PARSE *third; char *string; char *string1; - int num; - int refs; - module* module; - char* rulename; + int num; + int refs; + module* module; + char* rulename; + char* file; + int line; } ; void parse_file( char *f, FRAME* frame ); @@ -50,9 +51,10 @@ PARSE * parse_make( PARSE *third, char *string, char *string1, - int num ); + int num ); void parse_refer( PARSE *p ); void parse_free( PARSE *p ); +LIST* parse_evaluate( PARSE *p, FRAME* frame ); #endif // PARSE_DWA20011020_H diff --git a/historic/jam/src/rules.c b/historic/jam/src/rules.c index 9c4b84f2d..6bf759b50 100644 --- a/historic/jam/src/rules.c +++ b/historic/jam/src/rules.c @@ -63,6 +63,7 @@ enter_rule( char *rulename, module* m ) r->procedure = (PARSE *)0; r->actions = 0; r->arguments = 0; + r->local_only = 0; } return r; @@ -336,23 +337,38 @@ void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure ) rule->procedure = procedure; } -static RULE* global_rule( char* rulename, module* m ) +static char* global_name( char* rulename, module* m ) { - char global_name[4096] = ""; - strncat(global_name, m->name, sizeof(global_name) - 1); - strncat(global_name, rulename, sizeof(global_name) - 1); - return enter_rule( global_name, root_module() ); + char name[4096] = ""; + strncat(name, m->name, sizeof(name) - 1); + strncat(name, rulename, sizeof(name) - 1 ); + return newstr(name); } -RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure ) +static RULE* global_rule( char* rulename, module* m ) +{ + char* name = global_name( rulename, m); + RULE* result = enter_rule( name, root_module() ); + freestr(name); + return result; +} + +RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure, int local_only ) { RULE* local = enter_rule( rulename, m ); - RULE* global = global_rule( rulename, m ); procedure->module = m; - procedure->rulename = copystr( global->name ); + if ( !local_only ) + { + RULE* global = global_rule( rulename, m ); + procedure->rulename = copystr( global->name ); + set_rule_body( global, args, procedure ); + } + else + { + local->local_only = 1; + procedure->rulename = global_name( rulename, m ); + } set_rule_body( local, args, procedure ); - set_rule_body( global, args, procedure ); - return local; } diff --git a/historic/jam/src/rules.h b/historic/jam/src/rules.h index d02b14d7e..993013714 100644 --- a/historic/jam/src/rules.h +++ b/historic/jam/src/rules.h @@ -82,6 +82,7 @@ struct _rule { PARSE *procedure; /* parse tree from RULE */ argument_list* arguments; /* argument checking info, or NULL for unchecked */ rule_actions* actions; /* build actions, or NULL for no actions */ + int local_only; /* nonzero if this rule is local to a module */ } ; /* ACTIONS - a chain of ACTIONs */ @@ -134,13 +135,14 @@ struct _target { # define T_FLAG_TOUCHED 0x08 /* ALWAYS applied or -t target */ # define T_FLAG_LEAVES 0x10 /* LEAVES applied */ # define T_FLAG_NOUPDATE 0x20 /* NOUPDATE applied */ +# define T_FLAG_VISITED 0x40 /* CWM: Used in debugging */ /* this flag was added to support a new builting rule named "FAIL_EXPECTED" */ /* it is used to indicate that the result of running a given action should */ /* be inverted (i.e. ok <=> fail). This is useful to launch certain test */ /* runs from a Jamfile.. */ /* */ -# define T_FLAG_FAIL_EXPECTED 0x40 /* FAIL_EXPECTED applied */ +# define T_FLAG_FAIL_EXPECTED 0x80 /* FAIL_EXPECTED applied */ char binding; /* how target relates to real file */ @@ -201,8 +203,8 @@ struct _target { RULE *bindrule( char *rulename, module* ); RULE* import_rule( RULE* source, module* m, char* name ); -RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure ); -RULE* new_rule_actions( module* m, char* rulename, char* command, LIST* bindlist, int flags ); +RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure, int local ); +RULE* new_rule_actions( module* m, char* rulename, char* command, LIST* bindlist, int flags ); TARGET *bindtarget( char *targetname ); void touchtarget( char *t ); TARGETS *targetlist( TARGETS *chain, LIST *targets ); diff --git a/historic/jam/src/scan.c b/historic/jam/src/scan.c index f26f99204..e9a272e2d 100644 --- a/historic/jam/src/scan.c +++ b/historic/jam/src/scan.c @@ -244,7 +244,9 @@ yylex() *b = 0; yylval.type = STRING; yylval.string = newstr( buf ); - + yylval.file = incp->fname; + yylval.line = incp->line; + } else { @@ -258,17 +260,17 @@ yylex() for( ;; ) { - /* Skip past white space */ + /* Skip past white space */ - while( c != EOF && isspace( c ) ) - c = yychar(); + while( c != EOF && isspace( c ) ) + c = yychar(); - /* Not a comment? Swallow up comment line. */ + /* Not a comment? Swallow up comment line. */ - if( c != '#' ) - break; - while( ( c = yychar() ) != EOF && c != '\n' ) - ; + if( c != '#' ) + break; + while( ( c = yychar() ) != EOF && c != '\n' ) + ; } /* c now points to the first character of a token. */ @@ -276,6 +278,9 @@ yylex() if( c == EOF ) goto eof; + yylval.file = incp->fname; + yylval.line = incp->line; + /* look for white space to delimit word */ /* "'s get stripped but preserve white space */ @@ -343,6 +348,9 @@ yylex() return yylval.type; eof: + yylval.file = "end-of-input"; /* just in case */ + yylval.line = 0; + yylval.type = EOF; return yylval.type; } @@ -372,3 +380,20 @@ symdump( YYSTYPE *s ) } return buf; } + +/* Get information about the current file and line, for those epsilon + * transitions that produce a parse + */ +void yyinput_stream( char** name, int* line ) +{ + if (incp) + { + *name = incp->fname; + *line = incp->line; + } + else + { + *name = "(builtin)"; + *line = -1; + } +} diff --git a/historic/jam/src/scan.h b/historic/jam/src/scan.h index 37b026f1f..8f1454c25 100644 --- a/historic/jam/src/scan.h +++ b/historic/jam/src/scan.h @@ -30,11 +30,13 @@ # define YYSTYPE YYSYMBOL typedef struct _YYSTYPE { - int type; - char *string; - PARSE *parse; - LIST *list; - int number; + int type; + char *string; + PARSE *parse; + LIST *list; + int number; + char *file; + int line; } YYSTYPE; extern YYSTYPE yylval; @@ -46,6 +48,7 @@ void yyfparse( char *s ); int yyline(); int yylex(); int yyparse(); +void yyinput_stream( char** name, int* line ); # define SCAN_NORMAL 0 /* normal parsing */ # define SCAN_STRING 1 /* look only for matching } */ diff --git a/jam_src/compile.c b/jam_src/compile.c index ec0dcdd0c..90205adea 100644 --- a/jam_src/compile.c +++ b/jam_src/compile.c @@ -84,10 +84,14 @@ * in jamgram.yy. */ -static void debug_compile( int which, char *s ); +static void debug_compile( int which, char *s, FRAME* frame ); static int evaluate_if( PARSE *parse, FRAME *frame ); +static void backtrace_line( FRAME* frame ); +static void backtrace( FRAME* frame ); +static void frame_info( FRAME* frame, char** file, int* line ); + static LIST *builtin_depends( PARSE *parse, FRAME *frame ); static LIST *builtin_echo( PARSE *parse, FRAME *frame ); static LIST *builtin_exit( PARSE *parse, FRAME *frame ); @@ -95,6 +99,9 @@ static LIST *builtin_flags( PARSE *parse, FRAME *frame ); static LIST *builtin_hdrmacro( PARSE *parse, FRAME *frame ); static LIST *builtin_import( PARSE *parse, FRAME *frame ); static LIST *builtin_caller_module( PARSE *parse, FRAME *frame ); +static LIST *builtin_backtrace( PARSE *parse, FRAME *frame ); + + LIST *builtin_subst( PARSE *parse, FRAME *frame ); int glob( char *s, char *c ); @@ -105,6 +112,8 @@ void frame_init( FRAME* frame ) frame->prev = 0; lol_init(frame->args); frame->module = root_module(); + frame->rulename = "module scope"; + frame->procedure = 0; } void frame_free( FRAME* frame ) @@ -154,7 +163,7 @@ static RULE* bind_builtin( char* name, LIST*(*f)(PARSE*, FRAME*), int flags, cha } return new_rule_body( root_module(), name, arg_list, - parse_make( f, P0, P0, P0, C0, C0, flags ) ); + parse_make( f, P0, P0, P0, C0, C0, flags ), 0 ); } static RULE* duplicate_rule( char* name, RULE* other ) @@ -208,6 +217,11 @@ compile_builtins() char* args[] = { "levels", "?", 0 }; bind_builtin( "CALLER_MODULE", builtin_caller_module, 0, args ); } + + { + char* args[] = { 0 }; + bind_builtin( "BACKTRACE", builtin_backtrace, 0, args ); + } } /* @@ -225,8 +239,8 @@ compile_append( /* Append right to left. */ return list_append( - (*parse->left->func)( parse->left, frame ), - (*parse->right->func)( parse->right, frame ) ); + parse_evaluate( parse->left, frame ), + parse_evaluate( parse->right, frame ) ); } /* @@ -245,7 +259,7 @@ compile_foreach( PARSE *parse, FRAME *frame ) { - LIST *nv = (*parse->left->func)( parse->left, frame ); + LIST *nv = parse_evaluate( parse->left, frame ); LIST *l; SETTINGS *s = 0; @@ -263,7 +277,7 @@ compile_foreach( var_set( parse->string, val, VAR_SET ); - list_free( (*parse->right->func)( parse->right, frame ) ); + list_free( parse_evaluate( parse->right, frame ) ); } if ( parse->num ) @@ -289,11 +303,11 @@ compile_if( { if( evaluate_if( p->left, frame ) ) { - return (*p->right->func)( p->right, frame ); + return parse_evaluate( p->right, frame ); } else { - return (*p->third->func)( p->third, frame ); + return parse_evaluate( p->third, frame ); } } @@ -304,7 +318,7 @@ compile_while( { while ( evaluate_if( p->left, frame ) ) { - list_free( (*p->right->func)( p->right, frame ) ); + list_free( parse_evaluate( p->right, frame ) ); } return L0; } @@ -353,8 +367,8 @@ evaluate_if( /* Handle one of the comparison operators */ /* Expand targets and sources */ - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); /* "a in b" make sure each of a is equal to something in b. */ /* Otherwise, step through pairwise comparison. */ @@ -409,7 +423,7 @@ evaluate_if( if( DEBUG_IF ) { - debug_compile( 0, "if" ); + debug_compile( 0, "if", frame); list_print( nt ); printf( "(%d)", status ); list_print( ns ); @@ -435,11 +449,11 @@ compile_include( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); if( DEBUG_COMPILE ) { - debug_compile( 0, "include" ); + debug_compile( 0, "include", frame); list_print( nt ); printf( "\n" ); } @@ -477,7 +491,7 @@ compile_module( { /* Here we are entering a module declaration block. */ - LIST* module_name = (*p->left->func)( p->left, frame ); + LIST* module_name = parse_evaluate( p->left, frame ); LIST* result; module* outer_module = frame->module; @@ -489,7 +503,7 @@ compile_module( enter_module( frame->module ); } - result = (*p->right->func)( p->right, frame ); + result = parse_evaluate( p->right, frame ); if ( outer_module != frame->module ) { @@ -534,13 +548,13 @@ compile_local( { LIST *l; SETTINGS *s = 0; - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *result; if( DEBUG_COMPILE ) { - debug_compile( 0, "local" ); + debug_compile( 0, "local", frame); list_print( nt ); printf( " = " ); list_print( ns ); @@ -559,7 +573,7 @@ compile_local( /* variable, making it not so much local as layered. */ pushsettings( s ); - result = (*parse->third->func)( parse->third, frame ); + result = parse_evaluate( parse->third, frame ); popsettings( s ); freesettings( s ); @@ -603,9 +617,10 @@ compile_rule( frame_init( inner ); inner->prev = frame; inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below */ + inner->procedure = parse; for( p = parse->left; p; p = p->left ) - lol_add( inner->args, (*p->right->func)( p->right, frame ) ); + lol_add( inner->args, parse_evaluate( p->right, frame ) ); /* And invoke rule */ @@ -616,14 +631,17 @@ compile_rule( return result; } -static void argument_error( char* message, RULE* rule, LOL* actual, LIST* arg ) +static void argument_error( char* message, RULE* rule, FRAME* frame, LIST* arg ) { - printf( "### argument error\n# rule %s ( ", rule->name ); + LOL* actual = frame->args; + assert( frame->procedure != 0 ); + backtrace_line( frame->prev ); + printf( "*** argument error\n* rule %s ( ", frame->procedure->file, frame->procedure->line, frame->rulename ); lol_print( rule->arguments->data ); - printf( ")\n# called with: ( " ); + printf( ")\n* called with: ( " ); lol_print( actual ); - printf( ")\n# %s %s", message, arg ? arg->string : "" ); - printf("\n"); + printf( ")\n* %s %s\n", message, arg ? arg->string : "" ); + backtrace( frame->prev ); exit(1); } @@ -632,10 +650,11 @@ static void argument_error( char* message, RULE* rule, LOL* actual, LIST* arg ) * collect_arguments() - local argument checking and collection */ static SETTINGS * -collect_arguments( RULE* rule, LOL* all_actual ) +collect_arguments( RULE* rule, FRAME* frame ) { SETTINGS *locals = 0; + LOL* all_actual = frame->args; LOL *all_formal = rule->arguments ? rule->arguments->data : 0; if ( all_formal ) /* Nothing to set; nothing to check */ { @@ -662,7 +681,7 @@ collect_arguments( RULE* rule, LOL* all_actual ) if ( !actual && modifier != '?' && modifier != '*' ) { - argument_error( "missing argument", rule, all_actual, formal ); + argument_error( "missing argument", rule, frame, formal ); } switch ( modifier ) @@ -692,7 +711,7 @@ collect_arguments( RULE* rule, LOL* all_actual ) if ( actual ) { - argument_error( "extra argument", rule, all_actual, actual ); + argument_error( "extra argument", rule, frame, actual ); } } } @@ -804,7 +823,7 @@ evaluate_rule( if ( DEBUG_COMPILE ) { - debug_compile( 1, l->string ); + debug_compile( 1, l->string, frame); lol_print( frame->args ); printf( "\n" ); } @@ -823,13 +842,23 @@ evaluate_rule( list_free( l ); - if ( DEBUG_PROFILE && rule->procedure ) - profile_enter( rule->procedure->rulename, prof ); + /* record current rule name in frame */ + if ( rule->procedure ) + { + frame->rulename = rule->procedure->rulename; + /* and enter record profile info */ + if ( DEBUG_PROFILE ) + profile_enter( rule->procedure->rulename, prof ); + } /* Check traditional targets $(<) and sources $(>) */ if( !rule->actions && !rule->procedure ) + { + backtrace_line( frame->prev ); printf( "warning: unknown rule %s\n", rule->name ); + backtrace( frame->prev ); + } /* If this rule will be executed for updating the targets */ /* then construct the action for make(). */ @@ -859,12 +888,12 @@ evaluate_rule( if( rule->procedure ) { - SETTINGS *local_args = collect_arguments( rule, frame->args ); + SETTINGS *local_args = collect_arguments( rule, frame ); PARSE *parse = rule->procedure; parse_refer( parse ); pushsettings( local_args ); - result = (*parse->func)( parse, frame ); + result = parse_evaluate( parse, frame ); popsettings( local_args ); parse_free( parse ); @@ -880,7 +909,7 @@ evaluate_rule( profile_exit( prof ); if( DEBUG_COMPILE ) - debug_compile( -1, 0 ); + debug_compile( -1, 0, frame); return result; } @@ -899,8 +928,8 @@ compile_rules( { /* Ignore result from first statement; return the 2nd. */ - list_free( (*parse->left->func)( parse->left, frame ) ); - return (*parse->right->func)( parse->right, frame ); + list_free( parse_evaluate( parse->left, frame ) ); + return parse_evaluate( parse->right, frame ); } /* @@ -916,8 +945,8 @@ compile_set( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *l; int setflag; char *trace; @@ -932,7 +961,7 @@ compile_set( if( DEBUG_COMPILE ) { - debug_compile( 0, "set" ); + debug_compile( 0, "set", frame); list_print( nt ); printf( " %s ", trace ); list_print( ns ); @@ -961,13 +990,13 @@ compile_set_module( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->right, frame ); LIST *l; if( DEBUG_COMPILE ) { - debug_compile( 0, "set module" ); + debug_compile( 0, "set module", frame); printf( "(%s)", frame->module->name ); list_print( nt ); printf( " = " ); @@ -1011,10 +1040,10 @@ compile_setcomp( PARSE *p; arg_list = args_new(); for( p = parse->right; p; p = p->left ) - lol_add( arg_list->data, (*p->right->func)( p->right, frame ) ); + lol_add( arg_list->data, parse_evaluate( p->right, frame ) ); } - new_rule_body( frame->module, parse->string, arg_list, parse->left ); + new_rule_body( frame->module, parse->string, arg_list, parse->left, parse->num ); return L0; } @@ -1035,7 +1064,7 @@ compile_setexec( PARSE *parse, FRAME *frame ) { - LIST* bindlist = (*parse->left->func)( parse->left, frame ); + LIST* bindlist = parse_evaluate( parse->left, frame ); new_rule_actions( frame->module, parse->string, parse->string1, bindlist, parse->num ); @@ -1056,15 +1085,15 @@ compile_settings( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); - LIST *ns = (*parse->third->func)( parse->third, frame ); - LIST *targets = (*parse->right->func)( parse->right, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); + LIST *ns = parse_evaluate( parse->third, frame ); + LIST *targets = parse_evaluate( parse->right, frame ); LIST *ts; int append = parse->num == ASSIGN_APPEND; if( DEBUG_COMPILE ) { - debug_compile( 0, "set" ); + debug_compile( 0, "set", frame); list_print( nt ); printf( "on " ); list_print( targets ); @@ -1111,12 +1140,12 @@ compile_switch( PARSE *parse, FRAME *frame ) { - LIST *nt = (*parse->left->func)( parse->left, frame ); + LIST *nt = parse_evaluate( parse->left, frame ); LIST *result = 0; if( DEBUG_COMPILE ) { - debug_compile( 0, "switch" ); + debug_compile( 0, "switch", frame); list_print( nt ); printf( "\n" ); } @@ -1129,7 +1158,7 @@ compile_switch( { /* Get & exec parse tree for this case */ parse = parse->left->left; - result = (*parse->func)( parse, frame ); + result = parse_evaluate( parse, frame ); break; } } @@ -1274,8 +1303,9 @@ static void import_rule1( void* r_, void* data_ ) char* target_name = data->target_names ? data->target_names->string : r->name; if (data->target_names) data->target_names = list_next(data->target_names); - - import_rule( r, data->target_module, target_name ); + + if ( !r->local_only ) + import_rule( r, data->target_module, target_name ); } static LIST * @@ -1323,6 +1353,77 @@ builtin_import( return L0; } +/* Retrieve the file and line number that should be indicated for a + * given frame in debug output or an error backtrace + */ +static void frame_info( FRAME* frame, char** file, int* line ) +{ + if ( frame->procedure ) + { + char* f = frame->procedure->file; + int l = frame->procedure->line; + if ( !strcmp( f, "+" ) ) + { + f = "jambase.c"; + l += 3; + } + *file = f; + *line = l; + } + else + { + *file = "(builtin)"; + *line = -1; + } +} + +/* Print a single line of error backtrace for the given frame */ +static void backtrace_line( FRAME *frame ) +{ + char* file; + int line; + + frame_info( frame, &file, &line ); + if ( line < 0 ) + printf( "(builtin): in %s\n", frame->rulename ); + else + printf( "%s:%d: in %s\n", file, line, frame->rulename ); +} + +/* Print the entire backtrace from the given frame to the Jambase + * which invoked it. + */ +static void backtrace( FRAME *frame ) +{ + while ( frame = frame->prev ) + { + backtrace_line( frame ); + } +} + +/* A Jam version of the backtrace function, taking no arguments and + * returning a list of quadruples: FILENAME LINE MODULE. RULENAME + * describing each frame. Note that the module-name is always + * followed by a period. + */ +static LIST *builtin_backtrace( PARSE *parse, FRAME *frame ) +{ + LIST* result = L0; + while ( frame = frame->prev ) + { + char* file; + int line; + char buf[32]; + frame_info( frame, &file, &line ); + sprintf( buf, "%d", line ); + result = list_new( result, newstr( file ) ); + result = list_new( result, newstr( buf ) ); + result = list_new( result, newstr( frame->module->name ) ); + result = list_new( result, newstr( frame->rulename ) ); + } + return result; +} + /* * builtin_caller_module() - CALLER_MODULE ( levels ? ) * @@ -1370,10 +1471,13 @@ static LIST *builtin_caller_module( PARSE *parse, FRAME *frame ) */ static void -debug_compile( int which, char *s ) +debug_compile( int which, char *s, FRAME* frame ) { static int level = 0; static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|"; + + char* file; + int line; if ( which >= 0 ) { @@ -1385,7 +1489,12 @@ debug_compile( int which, char *s ) printf( indent ); i -= 35; } - printf( "%*.*s ", i, i, indent ); + + frame_info( frame, &file, &line ); + if ( line >= 0 ) + printf( "%s:%d:%*.*s ", file, line, i, i, indent ); + else + printf( "(builtin)%*.*s ", i, i, indent ); } if( s ) diff --git a/jam_src/frames.h b/jam_src/frames.h index e0dc6761e..bd7936eca 100644 --- a/jam_src/frames.h +++ b/jam_src/frames.h @@ -1,9 +1,17 @@ +/* + * (C) Copyright David Abrahams 2001. Permission to copy, use, + * modify, sell and distribute this software is granted provided this + * copyright notice appears in all copies. This software is provided + * "as is" without express or implied warranty, and with no claim as + * to its suitability for any purpose. + */ #ifndef FRAMES_DWA20011021_H # define FRAMES_DWA20011021_H # include "lists.h" # include "modules.h" +typedef struct _PARSE PARSE; typedef struct frame FRAME; struct frame @@ -11,6 +19,8 @@ struct frame FRAME* prev; LOL args[1]; module* module; + PARSE* procedure; + char* rulename; }; void frame_init( FRAME* ); /* implemented in compile.c */ diff --git a/jam_src/jam.h b/jam_src/jam.h index 2d2c2b350..816b1b56e 100644 --- a/jam_src/jam.h +++ b/jam_src/jam.h @@ -453,7 +453,7 @@ int unlink( char *f ); /* In filevms.c */ /* Jam private definitions below. */ -# define DEBUG_MAX 12 +# define DEBUG_MAX 13 struct globs { int noexec; @@ -488,4 +488,5 @@ extern struct globs globs; # define DEBUG_PROFILE ( globs.debug[ 10 ] ) /* dump rule execution times */ # define DEBUG_PARSE ( globs.debug[ 11 ] ) /* debug parsing */ +# define DEBUG_GRAPH ( globs.debug[ 12 ] ) /* debug dependencies */ diff --git a/jam_src/jamgram.c b/jam_src/jamgram.c index 1c64c2f5b..3d85c487c 100644 --- a/jam_src/jamgram.c +++ b/jam_src/jamgram.c @@ -75,8 +75,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -101,11 +100,11 @@ -#define YYFINAL 145 +#define YYFINAL 143 #define YYFLAG -32768 #define YYNTBASE 46 -#define YYTRANSLATE(x) ((unsigned)(x) <= 299 ? yytranslate[x] : 64) +#define YYTRANSLATE(x) ((unsigned)(x) <= 299 ? yytranslate[x] : 67) static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -142,52 +141,52 @@ static const char yytranslate[] = { 0, #if YYDEBUG != 0 static const short yyprhs[] = { 0, - 0, 1, 3, 4, 6, 8, 11, 17, 18, 21, - 25, 29, 33, 38, 44, 51, 55, 63, 72, 78, - 84, 90, 96, 104, 111, 115, 116, 117, 127, 129, - 131, 133, 136, 138, 142, 146, 150, 154, 158, 162, - 166, 169, 173, 177, 181, 182, 185, 190, 192, 196, - 198, 199, 202, 204, 209, 210, 213, 215, 217, 219, - 221, 223, 225, 226 + 0, 1, 3, 5, 7, 9, 12, 18, 19, 22, + 24, 28, 29, 31, 32, 36, 40, 44, 49, 55, + 62, 66, 75, 81, 87, 93, 99, 107, 113, 114, + 115, 125, 127, 129, 131, 134, 136, 140, 144, 148, + 152, 156, 160, 164, 167, 171, 175, 179, 180, 183, + 188, 190, 194, 196, 197, 200, 202, 207, 208, 211, + 213, 215, 217, 219, 221, 223, 224 }; static const short yyrhs[] = { -1, - 48, 0, 0, 48, 0, 50, 0, 50, 48, 0, - 30, 58, 49, 10, 47, 0, 0, 13, 58, 0, - 41, 47, 43, 0, 29, 58, 10, 0, 44, 57, - 10, 0, 60, 53, 58, 10, 0, 31, 30, 58, - 49, 10, 0, 60, 32, 58, 53, 58, 10, 0, - 35, 58, 10, 0, 25, 44, 28, 58, 41, 47, - 43, 0, 25, 30, 44, 28, 58, 41, 47, 43, - 0, 37, 58, 41, 55, 43, 0, 26, 54, 41, - 47, 43, 0, 31, 58, 41, 47, 43, 0, 40, - 54, 41, 47, 43, 0, 26, 54, 41, 47, 43, - 23, 50, 0, 36, 44, 6, 57, 7, 50, 0, - 36, 44, 50, 0, 0, 0, 19, 61, 44, 63, - 41, 51, 45, 52, 43, 0, 13, 0, 8, 0, - 16, 0, 22, 13, 0, 60, 0, 60, 13, 60, - 0, 60, 4, 60, 0, 60, 11, 60, 0, 60, - 12, 60, 0, 60, 14, 60, 0, 60, 15, 60, - 0, 60, 28, 58, 0, 3, 54, 0, 54, 5, - 54, 0, 54, 42, 54, 0, 6, 54, 7, 0, - 0, 56, 55, 0, 21, 44, 9, 47, 0, 58, - 0, 58, 9, 57, 0, 59, 0, 0, 59, 60, - 0, 44, 0, 17, 44, 57, 18, 0, 0, 61, - 62, 0, 39, 0, 38, 0, 27, 0, 34, 0, - 33, 0, 24, 0, 0, 20, 58, 0 + 48, 0, 49, 0, 48, 0, 53, 0, 53, 48, + 0, 30, 61, 50, 10, 47, 0, 0, 13, 61, + 0, 49, 0, 6, 60, 7, 0, 0, 30, 0, + 0, 41, 47, 43, 0, 29, 61, 10, 0, 44, + 60, 10, 0, 63, 56, 61, 10, 0, 31, 30, + 61, 50, 10, 0, 63, 32, 61, 56, 61, 10, + 0, 35, 61, 10, 0, 25, 52, 44, 28, 61, + 41, 47, 43, 0, 37, 61, 41, 58, 43, 0, + 26, 57, 41, 47, 43, 0, 31, 61, 41, 47, + 43, 0, 40, 57, 41, 47, 43, 0, 26, 57, + 41, 47, 43, 23, 53, 0, 52, 36, 44, 51, + 53, 0, 0, 0, 19, 64, 44, 66, 41, 54, + 45, 55, 43, 0, 13, 0, 8, 0, 16, 0, + 22, 13, 0, 63, 0, 63, 13, 63, 0, 63, + 4, 63, 0, 63, 11, 63, 0, 63, 12, 63, + 0, 63, 14, 63, 0, 63, 15, 63, 0, 63, + 28, 61, 0, 3, 57, 0, 57, 5, 57, 0, + 57, 42, 57, 0, 6, 57, 7, 0, 0, 59, + 58, 0, 21, 44, 9, 47, 0, 61, 0, 61, + 9, 60, 0, 62, 0, 0, 62, 63, 0, 44, + 0, 17, 44, 60, 18, 0, 0, 64, 65, 0, + 39, 0, 38, 0, 27, 0, 34, 0, 33, 0, + 24, 0, 0, 20, 61, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 133, 135, 146, 148, 152, 154, 156, 160, 162, 166, - 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, - 188, 190, 192, 194, 196, 198, 201, 203, 210, 212, - 214, 216, 224, 226, 228, 230, 232, 234, 236, 238, - 240, 242, 244, 246, 256, 258, 262, 271, 273, 283, - 287, 289, 293, 295, 305, 307, 311, 313, 315, 317, - 319, 321, 330, 332 + 132, 134, 145, 147, 151, 153, 155, 159, 163, 165, + 169, 171, 175, 177, 181, 183, 185, 187, 189, 191, + 193, 195, 197, 199, 201, 203, 205, 207, 209, 212, + 214, 221, 223, 225, 227, 235, 237, 239, 241, 243, + 245, 247, 249, 251, 253, 255, 257, 267, 269, 273, + 282, 284, 294, 298, 300, 304, 306, 316, 318, 322, + 324, 326, 328, 330, 332, 341, 343 }; #endif @@ -200,127 +199,122 @@ static const char * const yytname[] = { "$","error","$undefined.","_BANG", "_LBRACKET","_RBRACKET","ACTIONS","BIND","CASE","DEFAULT","ELSE","EXISTING", "FOR","IF","IGNORE","IN","INCLUDE","LOCAL","MODULE","ON","PIECEMEAL","QUIETLY", "RETURN","RULE","SWITCH","TOGETHER","UPDATED","WHILE","_LBRACE","_BARBAR","_RBRACE", -"ARG","STRING","run","block","rules","assign_list_opt","rule","@1","@2","assign", -"cond","cases","case","lol","list","listp","arg","eflags","eflag","bindlist", NULL +"ARG","STRING","run","block","rules","null","assign_list_opt","arglist_opt", +"local_opt","rule","@1","@2","assign","cond","cases","case","lol","list","listp", +"arg","eflags","eflag","bindlist", NULL }; #endif static const short yyr1[] = { 0, - 46, 46, 47, 47, 48, 48, 48, 49, 49, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 51, 52, 50, 53, 53, - 53, 53, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 55, 55, 56, 57, 57, 58, - 59, 59, 60, 60, 61, 61, 62, 62, 62, 62, - 62, 62, 63, 63 + 46, 46, 47, 47, 48, 48, 48, 49, 50, 50, + 51, 51, 52, 52, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 54, 55, + 53, 56, 56, 56, 56, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 58, 58, 59, + 60, 60, 61, 62, 62, 63, 63, 64, 64, 65, + 65, 65, 65, 65, 65, 66, 66 }; static const short yyr2[] = { 0, - 0, 1, 0, 1, 1, 2, 5, 0, 2, 3, - 3, 3, 4, 5, 6, 3, 7, 8, 5, 5, - 5, 5, 7, 6, 3, 0, 0, 9, 1, 1, - 1, 2, 1, 3, 3, 3, 3, 3, 3, 3, - 2, 3, 3, 3, 0, 2, 4, 1, 3, 1, - 0, 2, 1, 4, 0, 2, 1, 1, 1, 1, - 1, 1, 0, 2 + 0, 1, 1, 1, 1, 2, 5, 0, 2, 1, + 3, 0, 1, 0, 3, 3, 3, 4, 5, 6, + 3, 8, 5, 5, 5, 5, 7, 5, 0, 0, + 9, 1, 1, 1, 2, 1, 3, 3, 3, 3, + 3, 3, 3, 2, 3, 3, 3, 0, 2, 4, + 1, 3, 1, 0, 2, 1, 4, 0, 2, 1, + 1, 1, 1, 1, 1, 0, 2 }; static const short yydefact[] = { 1, - 0, 55, 0, 0, 51, 51, 51, 51, 0, 51, - 0, 3, 53, 2, 5, 0, 51, 0, 0, 0, - 0, 0, 53, 0, 33, 0, 50, 8, 51, 0, - 0, 0, 0, 0, 0, 4, 0, 48, 6, 30, - 29, 31, 0, 51, 51, 0, 62, 59, 61, 60, - 58, 57, 63, 56, 0, 51, 41, 0, 0, 3, - 0, 0, 0, 0, 0, 0, 0, 51, 11, 52, - 51, 0, 8, 3, 16, 51, 25, 45, 3, 10, - 12, 51, 32, 0, 0, 54, 51, 0, 51, 0, - 44, 42, 0, 43, 35, 36, 37, 34, 38, 39, - 40, 9, 3, 0, 0, 0, 0, 0, 45, 0, - 49, 51, 13, 64, 26, 0, 3, 20, 7, 14, - 21, 0, 0, 19, 46, 22, 0, 0, 3, 0, - 0, 24, 3, 15, 27, 0, 17, 23, 47, 0, - 18, 28, 0, 0, 0 + 0, 58, 14, 0, 54, 54, 54, 54, 54, 0, + 8, 56, 2, 0, 5, 0, 54, 0, 13, 0, + 0, 0, 56, 0, 36, 0, 53, 8, 54, 0, + 0, 0, 0, 0, 4, 3, 0, 51, 0, 6, + 33, 32, 34, 0, 54, 54, 0, 65, 62, 64, + 63, 61, 60, 66, 59, 0, 44, 0, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 54, 16, 55, + 54, 10, 0, 8, 8, 21, 48, 8, 15, 17, + 54, 12, 35, 0, 0, 57, 54, 0, 54, 47, + 45, 0, 46, 38, 39, 40, 37, 41, 42, 43, + 9, 8, 0, 0, 0, 0, 48, 0, 52, 54, + 14, 54, 18, 67, 29, 0, 24, 7, 19, 25, + 0, 23, 49, 26, 0, 28, 0, 0, 8, 14, + 8, 11, 20, 30, 0, 27, 50, 0, 22, 31, + 0, 0, 0 }; -static const short yydefgoto[] = { 143, - 35, 36, 72, 15, 128, 140, 45, 24, 108, 109, - 37, 38, 27, 16, 18, 54, 88 +static const short yydefgoto[] = { 141, + 34, 35, 36, 73, 111, 14, 15, 128, 138, 46, + 24, 106, 107, 37, 38, 27, 16, 18, 55, 88 }; -static const short yypact[] = { 106, - -34,-32768, -13, 8,-32768,-32768, -17,-32768, -16,-32768, - 8, 106, 24,-32768, 106, 174,-32768, 95, -15, -12, - 8, 8,-32768, 4, 166, 22, -2, 23,-32768, -6, - 28, 80, 2, 18, 1,-32768, 39, 45,-32768,-32768, --32768,-32768, 42,-32768,-32768, 43,-32768,-32768,-32768,-32768, --32768,-32768, 49,-32768, 34,-32768,-32768, 15, 8, 106, - 8, -2, -2, -2, -2, -2, -2,-32768,-32768,-32768, --32768, 60, 23, 106,-32768,-32768,-32768, 52, 106,-32768, --32768,-32768,-32768, 59, 64,-32768,-32768, 36,-32768, 37, --32768,-32768, 40, 74,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768, 106, 85, 53, 91, 56, 58, 52, 61, --32768,-32768,-32768,-32768,-32768, 67, 106, 79,-32768,-32768, --32768, 132, 101,-32768,-32768,-32768, 102, 68, 106, 71, - 132,-32768, 106,-32768,-32768, 75,-32768,-32768,-32768, 83, --32768,-32768, 127, 130,-32768 +static const short yypact[] = { 75, + -34,-32768, -16, 6,-32768, -21, -10,-32768,-32768, 6, + 75, 20,-32768, -3, 75, 121,-32768, 127,-32768, -18, + 6, 6,-32768, 11, 135, 25, -6, 23,-32768, -2, + 33, 3, 26, 4,-32768,-32768, 38, 49, 15,-32768, +-32768,-32768,-32768, 47,-32768,-32768, 43,-32768,-32768,-32768, +-32768,-32768,-32768, 42,-32768, 44,-32768, 14, 6, 75, + 6, -6, -6, -6, -6, -6, -6,-32768,-32768,-32768, +-32768,-32768, 61, 23, 75,-32768, 53, 75,-32768,-32768, +-32768, 69,-32768, 57, 67,-32768,-32768, 39,-32768,-32768, +-32768, 50, 76,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768, 75, 85, 54, 52, 56, 53, 59,-32768,-32768, + 101,-32768,-32768,-32768,-32768, 62, 86,-32768,-32768,-32768, + 99,-32768,-32768,-32768, 106,-32768, 104, 72, 75, 101, + 75,-32768,-32768,-32768, 78,-32768,-32768, 79,-32768,-32768, + 123, 124,-32768 }; static const short yypgoto[] = {-32768, - -53, 12, 65, -28,-32768,-32768, 69, -3, 31,-32768, - -11, -5,-32768, 26,-32768,-32768,-32768 + -53, 27, -20, 51,-32768, 125, -98,-32768,-32768, 60, + -4, 28,-32768, -12, -5,-32768, 24,-32768,-32768,-32768 }; -#define YYLAST 206 +#define YYLAST 171 static const short yytable[] = { 26, - 28, 30, 31, 77, 33, 46, 93, 34, 59, 17, - 21, 14, 29, 22, 1, 56, 19, 57, 58, 59, - 105, 91, 59, 73, 1, 110, 39, 32, 55, 25, - 20, 69, -51, -51, 74, 71, 25, 75, 84, 85, - -51, 23, 78, 80, 60, 61, 25, 25, 81, 119, - 90, 23, 70, 82, 83, 92, 61, 94, 79, 61, - 86, 89, 101, 130, 106, 102, 40, -51, 87, 103, - 111, 41, 107, 113, 42, 136, 115, 117, 59, 139, - 43, 114, 118, 116, 25, 76, 25, 95, 96, 97, - 98, 99, 100, 132, 120, 121, 1, 122, 2, 123, - 124, 131, 138, 126, 3, 4, 127, 129, 5, 133, - 7, 134, 135, 137, 8, 9, 10, 141, 47, 11, - 12, 48, 1, 13, 2, 142, 144, 49, 50, 145, - 3, 4, 51, 52, 5, 6, 7, 104, 53, 125, - 8, 9, 10, 0, 0, 11, 12, 0, 1, 13, - 2, 0, 112, 0, 0, 0, 3, 4, 0, 0, - 5, 0, 7, 0, 0, 0, 8, 9, 10, 62, - 0, 11, 12, 0, 0, 13, 63, 64, 65, 66, - 67, 40, 0, 0, 0, 0, 41, 0, 0, 42, - 0, 0, 0, 68, 0, 43, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 44 + 28, 30, 31, 32, 47, 33, 92, 72, 21, 17, + 1, 22, 126, 19, -13, 59, 57, 58, 59, 29, + 90, 104, 1, 74, 108, 56, 13, 25, -54, -54, + 59, 136, 39, 25, 69, 71, -54, 23, 75, 84, + 85, 40, 76, 77, 25, 25, 79, 80, 118, 23, + 70, 60, 61, 72, 91, 61, 93, 81, 82, 83, + 86, 87, 100, -54, 41, 101, 78, 61, 109, 42, + 102, 89, 43, 105, 110, 135, 113, 137, 44, 115, + 59, 114, 25, 116, 25, 94, 95, 96, 97, 98, + 99, 1, 117, 2, 119, 121, 120, 125, 122, 3, + 4, 124, 129, 5, 6, 7, 127, 131, 130, 8, + -14, 9, 132, 133, 10, 11, 134, 1, 12, 2, + 139, 140, 142, 143, 103, 3, 4, 20, 41, 5, + 19, 7, 0, 42, 123, 8, 43, 9, 62, 0, + 10, 11, 44, 112, 12, 63, 64, 65, 66, 67, + 48, 0, 45, 49, 0, 0, 0, 0, 0, 50, + 51, 0, 68, 0, 52, 53, 0, 0, 0, 0, + 54 }; static const short yycheck[] = { 5, - 6, 7, 8, 32, 10, 17, 60, 11, 5, 44, - 3, 0, 30, 6, 17, 28, 30, 21, 22, 5, - 74, 7, 5, 29, 17, 79, 15, 44, 44, 4, - 44, 10, 9, 10, 41, 13, 11, 10, 44, 45, - 17, 44, 41, 43, 41, 42, 21, 22, 10, 103, - 56, 44, 27, 9, 13, 59, 42, 61, 41, 42, - 18, 28, 68, 117, 76, 71, 8, 44, 20, 10, - 82, 13, 21, 10, 16, 129, 41, 41, 5, 133, - 22, 87, 43, 89, 59, 6, 61, 62, 63, 64, - 65, 66, 67, 122, 10, 43, 17, 7, 19, 44, - 43, 23, 131, 43, 25, 26, 112, 41, 29, 9, - 31, 10, 45, 43, 35, 36, 37, 43, 24, 40, - 41, 27, 17, 44, 19, 43, 0, 33, 34, 0, - 25, 26, 38, 39, 29, 30, 31, 73, 44, 109, - 35, 36, 37, -1, -1, 40, 41, -1, 17, 44, - 19, -1, 84, -1, -1, -1, 25, 26, -1, -1, - 29, -1, 31, -1, -1, -1, 35, 36, 37, 4, - -1, 40, 41, -1, -1, 44, 11, 12, 13, 14, - 15, 8, -1, -1, -1, -1, 13, -1, -1, 16, - -1, -1, -1, 28, -1, 22, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 32 + 6, 7, 8, 9, 17, 10, 60, 28, 3, 44, + 17, 6, 111, 30, 36, 5, 21, 22, 5, 30, + 7, 75, 17, 29, 78, 44, 0, 4, 9, 10, + 5, 130, 36, 10, 10, 13, 17, 44, 41, 45, + 46, 15, 10, 41, 21, 22, 43, 10, 102, 44, + 27, 41, 42, 74, 59, 42, 61, 9, 44, 13, + 18, 20, 68, 44, 8, 71, 41, 42, 81, 13, + 10, 28, 16, 21, 6, 129, 10, 131, 22, 41, + 5, 87, 59, 89, 61, 62, 63, 64, 65, 66, + 67, 17, 43, 19, 10, 44, 43, 110, 43, 25, + 26, 43, 41, 29, 30, 31, 112, 9, 23, 35, + 36, 37, 7, 10, 40, 41, 45, 17, 44, 19, + 43, 43, 0, 0, 74, 25, 26, 3, 8, 29, + 30, 31, -1, 13, 107, 35, 16, 37, 4, -1, + 40, 41, 22, 84, 44, 11, 12, 13, 14, 15, + 24, -1, 32, 27, -1, -1, -1, -1, -1, 33, + 34, -1, 28, -1, 38, 39, -1, -1, -1, -1, + 44 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ @@ -824,7 +818,7 @@ case 2: { parse_save( yyvsp[0].parse ); ; break;} case 3: -{ yyval.parse = pnull(); ; +{ yyval.parse = yyvsp[0].parse; ; break;} case 4: { yyval.parse = yyvsp[0].parse; ; @@ -845,168 +839,177 @@ case 9: { yyval.parse = yyvsp[0].parse; ; break;} case 10: -{ yyval.parse = yyvsp[-1].parse; ; +{ yyval.parse = yyvsp[0].parse; ; break;} case 11: -{ yyval.parse = pincl( yyvsp[-1].parse ); ; +{ yyval.parse = yyvsp[-1].parse; ; break;} case 12: -{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; - break;} -case 13: -{ yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; - break;} -case 14: -{ yyval.parse = psetmodule( yyvsp[-2].parse, yyvsp[-1].parse ); ; - break;} -case 15: -{ yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; - break;} -case 16: -{ yyval.parse = yyvsp[-1].parse; ; - break;} -case 17: -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, 0 ); ; - break;} -case 18: -{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, 1 ); ; - break;} -case 19: -{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 20: -{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; - break;} -case 21: -{ yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 22: -{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; - break;} -case 23: -{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; - break;} -case 24: -{ yyval.parse = psetc_args( yyvsp[-4].string, yyvsp[0].parse, yyvsp[-2].parse ); ; - break;} -case 25: -{ yyval.parse = psetc( yyvsp[-1].string, yyvsp[0].parse ); ; - break;} -case 26: -{ yymode( SCAN_STRING ); ; - break;} -case 27: -{ yymode( SCAN_NORMAL ); ; - break;} -case 28: -{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; - break;} -case 29: -{ yyval.number = ASSIGN_SET; ; - break;} -case 30: -{ yyval.number = ASSIGN_APPEND; ; - break;} -case 31: -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 32: -{ yyval.number = ASSIGN_DEFAULT; ; - break;} -case 33: -{ yyval.parse = pcnode( COND_EXISTS, yyvsp[0].parse, pnull() ); ; - break;} -case 34: -{ yyval.parse = pcnode( COND_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 35: -{ yyval.parse = pcnode( COND_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 36: -{ yyval.parse = pcnode( COND_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 37: -{ yyval.parse = pcnode( COND_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 38: -{ yyval.parse = pcnode( COND_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 39: -{ yyval.parse = pcnode( COND_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 40: -{ yyval.parse = pcnode( COND_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 41: -{ yyval.parse = pcnode( COND_NOT, yyvsp[0].parse, P0 ); ; - break;} -case 42: -{ yyval.parse = pcnode( COND_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 43: -{ yyval.parse = pcnode( COND_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; - break;} -case 44: -{ yyval.parse = yyvsp[-1].parse; ; - break;} -case 45: { yyval.parse = P0; ; break;} -case 46: -{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; +case 13: +{ yyval.number = 1; ; break;} -case 47: -{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; - break;} -case 48: -{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; - break;} -case 49: -{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; - break;} -case 50: -{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; - break;} -case 51: -{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; - break;} -case 52: -{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; - break;} -case 53: -{ yyval.parse = plist( yyvsp[0].string ); ; - break;} -case 54: -{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; - break;} -case 55: +case 14: { yyval.number = 0; ; break;} +case 15: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 16: +{ yyval.parse = pincl( yyvsp[-1].parse ); ; + break;} +case 17: +{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; + break;} +case 18: +{ yyval.parse = pset( yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; + break;} +case 19: +{ yyval.parse = psetmodule( yyvsp[-2].parse, yyvsp[-1].parse ); ; + break;} +case 20: +{ yyval.parse = pset1( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-2].number ); ; + break;} +case 21: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 22: +{ yyval.parse = pfor( yyvsp[-5].string, yyvsp[-3].parse, yyvsp[-1].parse, yyvsp[-6].number ); ; + break;} +case 23: +{ yyval.parse = pswitch( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 24: +{ yyval.parse = pif( yyvsp[-3].parse, yyvsp[-1].parse, pnull() ); ; + break;} +case 25: +{ yyval.parse = pmodule( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 26: +{ yyval.parse = pwhile( yyvsp[-3].parse, yyvsp[-1].parse ); ; + break;} +case 27: +{ yyval.parse = pif( yyvsp[-5].parse, yyvsp[-3].parse, yyvsp[0].parse ); ; + break;} +case 28: +{ yyval.parse = psetc( yyvsp[-2].string, yyvsp[0].parse, yyvsp[-1].parse, yyvsp[-4].number ); ; + break;} +case 29: +{ yymode( SCAN_STRING ); ; + break;} +case 30: +{ yymode( SCAN_NORMAL ); ; + break;} +case 31: +{ yyval.parse = psete( yyvsp[-6].string,yyvsp[-5].parse,yyvsp[-2].string,yyvsp[-7].number ); ; + break;} +case 32: +{ yyval.number = ASSIGN_SET; ; + break;} +case 33: +{ yyval.number = ASSIGN_APPEND; ; + break;} +case 34: +{ yyval.number = ASSIGN_DEFAULT; ; + break;} +case 35: +{ yyval.number = ASSIGN_DEFAULT; ; + break;} +case 36: +{ yyval.parse = pcnode( COND_EXISTS, yyvsp[0].parse, pnull() ); ; + break;} +case 37: +{ yyval.parse = pcnode( COND_EQUALS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 38: +{ yyval.parse = pcnode( COND_NOTEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 39: +{ yyval.parse = pcnode( COND_LESS, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 40: +{ yyval.parse = pcnode( COND_LESSEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 41: +{ yyval.parse = pcnode( COND_MORE, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 42: +{ yyval.parse = pcnode( COND_MOREEQ, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 43: +{ yyval.parse = pcnode( COND_IN, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 44: +{ yyval.parse = pcnode( COND_NOT, yyvsp[0].parse, P0 ); ; + break;} +case 45: +{ yyval.parse = pcnode( COND_AND, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 46: +{ yyval.parse = pcnode( COND_OR, yyvsp[-2].parse, yyvsp[0].parse ); ; + break;} +case 47: +{ yyval.parse = yyvsp[-1].parse; ; + break;} +case 48: +{ yyval.parse = P0; ; + break;} +case 49: +{ yyval.parse = pnode( yyvsp[-1].parse, yyvsp[0].parse ); ; + break;} +case 50: +{ yyval.parse = psnode( yyvsp[-2].string, yyvsp[0].parse ); ; + break;} +case 51: +{ yyval.parse = pnode( P0, yyvsp[0].parse ); ; + break;} +case 52: +{ yyval.parse = pnode( yyvsp[0].parse, yyvsp[-2].parse ); ; + break;} +case 53: +{ yyval.parse = yyvsp[0].parse; yymode( SCAN_NORMAL ); ; + break;} +case 54: +{ yyval.parse = pnull(); yymode( SCAN_PUNCT ); ; + break;} +case 55: +{ yyval.parse = pappend( yyvsp[-1].parse, yyvsp[0].parse ); ; + break;} case 56: -{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; +{ yyval.parse = plist( yyvsp[0].string ); ; break;} case 57: -{ yyval.number = EXEC_UPDATED; ; +{ yyval.parse = prule( yyvsp[-2].string, yyvsp[-1].parse ); ; break;} case 58: -{ yyval.number = EXEC_TOGETHER; ; +{ yyval.number = 0; ; break;} case 59: -{ yyval.number = EXEC_IGNORE; ; +{ yyval.number = yyvsp[-1].number | yyvsp[0].number; ; break;} case 60: -{ yyval.number = EXEC_QUIETLY; ; +{ yyval.number = EXEC_UPDATED; ; break;} case 61: -{ yyval.number = EXEC_PIECEMEAL; ; +{ yyval.number = EXEC_TOGETHER; ; break;} case 62: -{ yyval.number = EXEC_EXISTING; ; +{ yyval.number = EXEC_IGNORE; ; break;} case 63: -{ yyval.parse = pnull(); ; +{ yyval.number = EXEC_QUIETLY; ; break;} case 64: +{ yyval.number = EXEC_PIECEMEAL; ; + break;} +case 65: +{ yyval.number = EXEC_EXISTING; ; + break;} +case 66: +{ yyval.parse = pnull(); ; + break;} +case 67: { yyval.parse = yyvsp[0].parse; ; break;} } diff --git a/jam_src/jamgram.y b/jam_src/jamgram.y index ba6458f67..7dc5eed7c 100644 --- a/jam_src/jamgram.y +++ b/jam_src/jamgram.y @@ -117,8 +117,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -143,8 +142,8 @@ run : /* empty */ * right-recursive so rules execute in order. */ -block : /* empty */ - { $$.parse = pnull(); } +block : null + { $$.parse = $1.parse; } | rules { $$.parse = $1.parse; } ; @@ -157,12 +156,28 @@ rules : rule { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } ; -assign_list_opt : /* empty */ - { $$.parse = pnull(); } - | _EQUALS list - { $$.parse = $2.parse; } +null : /* empty */ + { $$.parse = pnull(); } ; +assign_list_opt : _EQUALS list + { $$.parse = $2.parse; } + | null + { $$.parse = $1.parse; } + ; + +arglist_opt : _LPAREN lol _RPAREN + { $$.parse = $2.parse; } + | + { $$.parse = P0; } + ; + +local_opt : LOCAL + { $$.number = 1; } + | /* empty */ + { $$.number = 0; } + ; + rule : _LBRACE block _RBRACE { $$.parse = $2.parse; } | INCLUDE list _SEMIC @@ -177,10 +192,8 @@ rule : _LBRACE block _RBRACE { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | RETURN list _SEMIC { $$.parse = $2.parse; } - | FOR ARG IN list _LBRACE block _RBRACE - { $$.parse = pfor( $2.string, $4.parse, $6.parse, 0 ); } - | FOR LOCAL ARG IN list _LBRACE block _RBRACE - { $$.parse = pfor( $3.string, $5.parse, $7.parse, 1 ); } + | FOR local_opt ARG IN list _LBRACE block _RBRACE + { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } | SWITCH list _LBRACE cases _RBRACE { $$.parse = pswitch( $2.parse, $4.parse ); } | IF cond _LBRACE block _RBRACE @@ -191,10 +204,8 @@ rule : _LBRACE block _RBRACE { $$.parse = pwhile( $2.parse, $4.parse ); } | IF cond _LBRACE block _RBRACE ELSE rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | RULE ARG _LPAREN lol _RPAREN rule - { $$.parse = psetc_args( $2.string, $6.parse, $4.parse ); } - | RULE ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | local_opt RULE ARG arglist_opt rule + { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } | ACTIONS eflags ARG bindlist _LBRACE { yymode( SCAN_STRING ); } STRING diff --git a/jam_src/jamgram.yy b/jam_src/jamgram.yy index a515e0ad1..56f45dd1d 100644 --- a/jam_src/jamgram.yy +++ b/jam_src/jamgram.yy @@ -76,8 +76,7 @@ # define pset( l,r,a ) parse_make( compile_set,l,r,P0,S0,S0,a ) # define psetmodule( l,r ) parse_make( compile_set_module,l,r,P0,S0,S0,0 ) # define pset1( l,r,t,a ) parse_make( compile_settings,l,r,t,S0,S0,a ) -# define psetc( s,p ) parse_make( compile_setcomp,p,P0,P0,s,S0,0 ) -# define psetc_args( s,p,a ) parse_make( compile_setcomp,p,a,P0,s,S0,0 ) +# define psetc( s,p,a,l ) parse_make( compile_setcomp,p,a,P0,s,S0,l ) # define psete( s,l,s1,f ) parse_make( compile_setexec,l,P0,P0,s,s1,f ) # define pswitch( l,r ) parse_make( compile_switch,l,r,P0,S0,S0,0 ) @@ -102,8 +101,8 @@ run : /* empty */ * right-recursive so rules execute in order. */ -block : /* empty */ - { $$.parse = pnull(); } +block : null + { $$.parse = $1.parse; } | rules { $$.parse = $1.parse; } ; @@ -116,12 +115,28 @@ rules : rule { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } ; -assign_list_opt : /* empty */ - { $$.parse = pnull(); } - | `=` list - { $$.parse = $2.parse; } +null : /* empty */ + { $$.parse = pnull(); } ; +assign_list_opt : `=` list + { $$.parse = $2.parse; } + | null + { $$.parse = $1.parse; } + ; + +arglist_opt : `(` lol `)` + { $$.parse = $2.parse; } + | + { $$.parse = P0; } + ; + +local_opt : `local` + { $$.number = 1; } + | /* empty */ + { $$.number = 0; } + ; + rule : `{` block `}` { $$.parse = $2.parse; } | `include` list `;` @@ -136,10 +151,8 @@ rule : `{` block `}` { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } | `return` list `;` { $$.parse = $2.parse; } - | `for` ARG `in` list `{` block `}` - { $$.parse = pfor( $2.string, $4.parse, $6.parse, 0 ); } - | `for` `local` ARG `in` list `{` block `}` - { $$.parse = pfor( $3.string, $5.parse, $7.parse, 1 ); } + | `for` local_opt ARG `in` list `{` block `}` + { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } | `switch` list `{` cases `}` { $$.parse = pswitch( $2.parse, $4.parse ); } | `if` cond `{` block `}` @@ -150,10 +163,8 @@ rule : `{` block `}` { $$.parse = pwhile( $2.parse, $4.parse ); } | `if` cond `{` block `}` `else` rule { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | `rule` ARG `(` lol `)` rule - { $$.parse = psetc_args( $2.string, $6.parse, $4.parse ); } - | `rule` ARG rule - { $$.parse = psetc( $2.string, $3.parse ); } + | local_opt `rule` ARG arglist_opt rule + { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } | `actions` eflags ARG bindlist `{` { yymode( SCAN_STRING ); } STRING diff --git a/jam_src/make.c b/jam_src/make.c index 6b86901b7..b8c201f42 100644 --- a/jam_src/make.c +++ b/jam_src/make.c @@ -75,6 +75,12 @@ typedef struct { static void make0( TARGET *t, int pbinding, time_t ptime, int depth, COUNTS *counts, int anyhow ); +#define OPT_GRAPH_DEBUG_EXT + +#ifdef OPT_GRAPH_DEBUG_EXT +static void dependGraphOutput( TARGET *t, int depth ); +#endif + static char *target_fate[] = { "init", /* T_FATE_INIT */ @@ -122,6 +128,17 @@ make( make0( t, T_BIND_UNBOUND, (time_t)0, 0, counts, anyhow ); } + +#ifdef OPT_GRAPH_DEBUG_EXT + if( DEBUG_GRAPH ) + { + for( i = 0; i < n_targets; i++ ) + { + TARGET *t = bindtarget( targets[i] ); + dependGraphOutput( t, 0 ); + } + } +#endif if( DEBUG_MAKE ) { @@ -454,3 +471,96 @@ make0( spaces( depth ), t->name ); } + +#ifdef OPT_GRAPH_DEBUG_EXT + +/* + * dependGraphOutput() - output the DG after make0 has run + */ + +static void +dependGraphOutput( TARGET *t, int depth ) +{ + TARGETS *c; + + if ( (t->flags & T_FLAG_VISITED) != 0 + || !t->name + || !t->boundname) + return; + + t->flags |= T_FLAG_VISITED; + + switch (t->fate) + { + case T_FATE_TOUCHED: + case T_FATE_MISSING: + case T_FATE_OUTDATED: + case T_FATE_UPDATE: + printf( "->%s%2d Name: %s\n", spaces(depth), depth, t->name ); + break; + default: + printf( " %s%2d Name: %s\n", spaces(depth), depth, t->name ); + break; + } + + if( strcmp (t->name, t->boundname) ) + { + printf( " %s Loc: %s\n", spaces(depth), t->boundname ); + } + + switch (t->fate) { + case T_FATE_STABLE: + printf( " %s : Stable\n", spaces(depth) ); + break; + case T_FATE_NEWER: + printf( " %s : Newer\n", spaces(depth) ); + break; + case T_FATE_ISTMP: + printf( " %s : Up to date temp file\n", spaces(depth) ); + break; + case T_FATE_TOUCHED: + printf( " %s : Been touched, updating it\n", + spaces(depth) ); + break; + case T_FATE_MISSING: + printf( " %s : Missing, creating it\n", spaces(depth) ); + break; + case T_FATE_OUTDATED: + printf( " %s : Outdated, updating it\n", spaces(depth) ); + break; + case T_FATE_UPDATE: + printf( " %s : Updating it\n", spaces(depth) ); + break; + case T_FATE_CANTFIND: + printf( " %s : Can't find it\n", spaces(depth) ); + break; + case T_FATE_CANTMAKE: + printf( " %s : Can't make it\n", spaces(depth) ); + break; + } + + for( c = t->deps[ T_DEPS_DEPENDS ]; c; c = c->next ) + { + printf( " %s : Depends on %s (%s)\n", spaces(depth), + c->target->name, target_fate[ c->target->fate ] ); + } + + for( c = t->deps[ T_DEPS_INCLUDES ]; c; c = c->next ) + { + printf( " %s : Includes %s (%s)\n", spaces(depth), + c->target->name, target_fate[ c->target->fate ] ); + } + + for( c = t->deps[ T_DEPS_DEPENDS ]; c; c = c->next ) + { + dependGraphOutput( c->target, depth + 1 ); + } + + for( c = t->deps[ T_DEPS_INCLUDES ]; c; c = c->next ) + { + dependGraphOutput( c->target, depth + 1 ); + } + +} + +#endif diff --git a/jam_src/parse.c b/jam_src/parse.c index 073a97537..20851d4aa 100644 --- a/jam_src/parse.c +++ b/jam_src/parse.c @@ -58,8 +58,7 @@ parse_file( char *f, FRAME* frame ) /* Run the parse tree. */ - (*(p->func))( p, frame ); - + parse_evaluate( p, frame ); parse_free( p ); } } @@ -92,6 +91,16 @@ parse_make( p->refs = 1; p->module = 0; p->rulename = 0; + + if ( left ) + { + p->file = left->file; + p->line = left->line; + } + else + { + yyinput_stream( &p->file, &p->line ); + } return p; } @@ -123,3 +132,9 @@ parse_free( PARSE *p ) free( (char *)p ); } + +LIST* parse_evaluate( PARSE *p, FRAME* frame ) +{ + frame->procedure = p; + return (*p->func)(p, frame); +} diff --git a/jam_src/parse.h b/jam_src/parse.h index 4eb949447..09b25e1a8 100644 --- a/jam_src/parse.h +++ b/jam_src/parse.h @@ -16,6 +16,7 @@ # define PARSE_DWA20011020_H # include "frames.h" # include "modules.h" +# include "lists.h" /* * parse.h - make and destroy parse trees as driven by the parser @@ -25,8 +26,6 @@ * parse tree node */ -typedef struct _PARSE PARSE; - struct _PARSE { LIST *(*func)( PARSE *p, FRAME *frame ); PARSE *left; @@ -34,10 +33,12 @@ struct _PARSE { PARSE *third; char *string; char *string1; - int num; - int refs; - module* module; - char* rulename; + int num; + int refs; + module* module; + char* rulename; + char* file; + int line; } ; void parse_file( char *f, FRAME* frame ); @@ -50,9 +51,10 @@ PARSE * parse_make( PARSE *third, char *string, char *string1, - int num ); + int num ); void parse_refer( PARSE *p ); void parse_free( PARSE *p ); +LIST* parse_evaluate( PARSE *p, FRAME* frame ); #endif // PARSE_DWA20011020_H diff --git a/jam_src/rules.c b/jam_src/rules.c index 9c4b84f2d..6bf759b50 100644 --- a/jam_src/rules.c +++ b/jam_src/rules.c @@ -63,6 +63,7 @@ enter_rule( char *rulename, module* m ) r->procedure = (PARSE *)0; r->actions = 0; r->arguments = 0; + r->local_only = 0; } return r; @@ -336,23 +337,38 @@ void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure ) rule->procedure = procedure; } -static RULE* global_rule( char* rulename, module* m ) +static char* global_name( char* rulename, module* m ) { - char global_name[4096] = ""; - strncat(global_name, m->name, sizeof(global_name) - 1); - strncat(global_name, rulename, sizeof(global_name) - 1); - return enter_rule( global_name, root_module() ); + char name[4096] = ""; + strncat(name, m->name, sizeof(name) - 1); + strncat(name, rulename, sizeof(name) - 1 ); + return newstr(name); } -RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure ) +static RULE* global_rule( char* rulename, module* m ) +{ + char* name = global_name( rulename, m); + RULE* result = enter_rule( name, root_module() ); + freestr(name); + return result; +} + +RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure, int local_only ) { RULE* local = enter_rule( rulename, m ); - RULE* global = global_rule( rulename, m ); procedure->module = m; - procedure->rulename = copystr( global->name ); + if ( !local_only ) + { + RULE* global = global_rule( rulename, m ); + procedure->rulename = copystr( global->name ); + set_rule_body( global, args, procedure ); + } + else + { + local->local_only = 1; + procedure->rulename = global_name( rulename, m ); + } set_rule_body( local, args, procedure ); - set_rule_body( global, args, procedure ); - return local; } diff --git a/jam_src/rules.h b/jam_src/rules.h index d02b14d7e..993013714 100644 --- a/jam_src/rules.h +++ b/jam_src/rules.h @@ -82,6 +82,7 @@ struct _rule { PARSE *procedure; /* parse tree from RULE */ argument_list* arguments; /* argument checking info, or NULL for unchecked */ rule_actions* actions; /* build actions, or NULL for no actions */ + int local_only; /* nonzero if this rule is local to a module */ } ; /* ACTIONS - a chain of ACTIONs */ @@ -134,13 +135,14 @@ struct _target { # define T_FLAG_TOUCHED 0x08 /* ALWAYS applied or -t target */ # define T_FLAG_LEAVES 0x10 /* LEAVES applied */ # define T_FLAG_NOUPDATE 0x20 /* NOUPDATE applied */ +# define T_FLAG_VISITED 0x40 /* CWM: Used in debugging */ /* this flag was added to support a new builting rule named "FAIL_EXPECTED" */ /* it is used to indicate that the result of running a given action should */ /* be inverted (i.e. ok <=> fail). This is useful to launch certain test */ /* runs from a Jamfile.. */ /* */ -# define T_FLAG_FAIL_EXPECTED 0x40 /* FAIL_EXPECTED applied */ +# define T_FLAG_FAIL_EXPECTED 0x80 /* FAIL_EXPECTED applied */ char binding; /* how target relates to real file */ @@ -201,8 +203,8 @@ struct _target { RULE *bindrule( char *rulename, module* ); RULE* import_rule( RULE* source, module* m, char* name ); -RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure ); -RULE* new_rule_actions( module* m, char* rulename, char* command, LIST* bindlist, int flags ); +RULE* new_rule_body( module* m, char* rulename, argument_list* args, PARSE* procedure, int local ); +RULE* new_rule_actions( module* m, char* rulename, char* command, LIST* bindlist, int flags ); TARGET *bindtarget( char *targetname ); void touchtarget( char *t ); TARGETS *targetlist( TARGETS *chain, LIST *targets ); diff --git a/jam_src/scan.c b/jam_src/scan.c index f26f99204..e9a272e2d 100644 --- a/jam_src/scan.c +++ b/jam_src/scan.c @@ -244,7 +244,9 @@ yylex() *b = 0; yylval.type = STRING; yylval.string = newstr( buf ); - + yylval.file = incp->fname; + yylval.line = incp->line; + } else { @@ -258,17 +260,17 @@ yylex() for( ;; ) { - /* Skip past white space */ + /* Skip past white space */ - while( c != EOF && isspace( c ) ) - c = yychar(); + while( c != EOF && isspace( c ) ) + c = yychar(); - /* Not a comment? Swallow up comment line. */ + /* Not a comment? Swallow up comment line. */ - if( c != '#' ) - break; - while( ( c = yychar() ) != EOF && c != '\n' ) - ; + if( c != '#' ) + break; + while( ( c = yychar() ) != EOF && c != '\n' ) + ; } /* c now points to the first character of a token. */ @@ -276,6 +278,9 @@ yylex() if( c == EOF ) goto eof; + yylval.file = incp->fname; + yylval.line = incp->line; + /* look for white space to delimit word */ /* "'s get stripped but preserve white space */ @@ -343,6 +348,9 @@ yylex() return yylval.type; eof: + yylval.file = "end-of-input"; /* just in case */ + yylval.line = 0; + yylval.type = EOF; return yylval.type; } @@ -372,3 +380,20 @@ symdump( YYSTYPE *s ) } return buf; } + +/* Get information about the current file and line, for those epsilon + * transitions that produce a parse + */ +void yyinput_stream( char** name, int* line ) +{ + if (incp) + { + *name = incp->fname; + *line = incp->line; + } + else + { + *name = "(builtin)"; + *line = -1; + } +} diff --git a/jam_src/scan.h b/jam_src/scan.h index 37b026f1f..8f1454c25 100644 --- a/jam_src/scan.h +++ b/jam_src/scan.h @@ -30,11 +30,13 @@ # define YYSTYPE YYSYMBOL typedef struct _YYSTYPE { - int type; - char *string; - PARSE *parse; - LIST *list; - int number; + int type; + char *string; + PARSE *parse; + LIST *list; + int number; + char *file; + int line; } YYSTYPE; extern YYSTYPE yylval; @@ -46,6 +48,7 @@ void yyfparse( char *s ); int yyline(); int yylex(); int yyparse(); +void yyinput_stream( char** name, int* line ); # define SCAN_NORMAL 0 /* normal parsing */ # define SCAN_STRING 1 /* look only for matching } */