void call_bind_rule( OBJECT * target_, OBJECT * boundname_ ) { LIST * const bind_rule = var_get( root_module(), constant_BINDRULE ); if ( !list_empty( bind_rule ) ) { OBJECT * target = object_copy( target_ ); OBJECT * boundname = object_copy( boundname_ ); if ( boundname && target ) { /* Prepare the argument list. */ FRAME frame[ 1 ]; frame_init( frame ); /* First argument is the target name. */ lol_add( frame->args, list_new( target ) ); lol_add( frame->args, list_new( boundname ) ); if ( lol_get( frame->args, 1 ) ) { OBJECT * rulename = list_front( bind_rule ); list_free( evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ) ); } /* Clean up */ frame_free( frame ); } else { if ( boundname ) object_free( boundname ); if ( target ) object_free( target ); } } }
CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell ) { CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) ); FRAME frame[ 1 ]; assert( cmd ); cmd->rule = rule; cmd->shell = shell; cmd->next = 0; cmd->noop = 0; lol_init( &cmd->args ); lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); string_new( cmd->buf ); frame_init( frame ); frame->module = rule->module; lol_init( frame->args ); lol_add( frame->args, list_copy( targets ) ); lol_add( frame->args, list_copy( sources ) ); function_run_actions( rule->actions->command, frame, stack_global(), cmd->buf ); frame_free( frame ); return cmd; }
void headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; LIST *hdrcache; LOL lol; if( !( hdrscan = var_get( "HDRSCAN" ) ) || !( hdrrule = var_get( "HDRRULE" ) ) ) return; /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ if( DEBUG_HEADER ) printf( "header scan %s\n", t->name ); lol_init( &lol ); lol_add( &lol, list_new( L0, t->name, 1 ) ); lol_add( &lol, headers1( t->boundname, hdrscan ) ); if( lol_get( &lol, 1 ) ) list_free( evaluate_rule( 0, hdrrule->string, &lol, L0 ) ); /* Clean up */ lol_free( &lol ); }
static void call_action_rule ( TARGET * target, int status, timing_info const * time, char const * executed_command, char const * command_output ) { LIST * action_rule; pushsettings( root_module(), target->settings ); action_rule = var_get( root_module(), constant_ACTION_RULE ); popsettings( root_module(), target->settings ); if ( !list_empty( action_rule ) ) { /* rule action-rule ( args * : target : command status start end user system : output ? ) */ /* Prepare the argument list. */ FRAME frame[ 1 ]; OBJECT * rulename = list_front( action_rule ); frame_init( frame ); /* args * :: $(__ACTION_RULE__[2-]) */ lol_add( frame->args, list_copy_range( action_rule, list_next( list_begin( action_rule ) ), list_end( action_rule ) ) ); /* target :: the name of the target */ lol_add( frame->args, list_new( object_copy( target->name ) ) ); /* command status start end user system :: info about the action command */ lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_push_back( list_push_back( list_new( object_new( executed_command ) ), outf_int( status ) ), outf_time( &time->start ) ), outf_time( &time->end ) ), outf_double( time->user ) ), outf_double( time->system ) ) ); /* output ? :: the output of the action command */ if ( command_output ) lol_add( frame->args, list_new( object_new( command_output ) ) ); else lol_add( frame->args, L0 ); /* Call the rule. */ evaluate_rule( bindrule( rulename, root_module() ), rulename, frame ); /* Clean up. */ frame_free( frame ); } }
void headers( TARGET * t ) { LIST * hdrscan; LIST * hdrrule; #ifndef OPT_HEADER_CACHE_EXT LIST * headlist = L0; #endif regexp * re[ MAXINC ]; int rec = 0; LISTITER iter, end; hdrscan = var_get( root_module(), constant_HDRSCAN ); if ( list_empty( hdrscan ) ) return; hdrrule = var_get( root_module(), constant_HDRRULE ); if ( list_empty( hdrrule ) ) return; if ( DEBUG_HEADER ) printf( "header scan %s\n", object_str( t->name ) ); /* Compile all regular expressions in HDRSCAN */ iter = list_begin( hdrscan ), end = list_end( hdrscan ); for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) ) { re[ rec++ ] = regex_compile( list_item( iter ) ); } /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ { FRAME frame[1]; frame_init( frame ); lol_add( frame->args, list_new( object_copy( t->name ) ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); #else lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); #endif if ( lol_get( frame->args, 1 ) ) { /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( frame->args, list_new( object_copy( t->boundname ) ) ); list_free( evaluate_rule( list_front( hdrrule ), frame ) ); } /* Clean up. */ frame_free( frame ); } }
/* Look up the __ACTION_RULE__ variable on the given target, and if * non-empty, invoke the rule it names, passing the given info, * timing_info, executed command and command output */ static void call_action_rule(TARGET* target, int status, timing_info* time, char *executed_command, char *command_output) { LIST* action_rule; pushsettings(target->settings); action_rule = var_get( "__ACTION_RULE__" ); popsettings(target->settings); if (action_rule) { /* rule action-rule ( args * : target : command status start end user system : output ? ) */ /* Prepare the argument list */ FRAME frame[1]; frame_init( frame ); /* args * :: $(__ACTION_RULE__[2-]) */ lol_add( frame->args, list_copy( L0, action_rule->next ) ); /* target :: the name of the target */ lol_add( frame->args, list_new( L0, target->name ) ); /* command status start end user system :: info about the action command */ lol_add( frame->args, list_new( list_new( list_new( list_new( list_new( list_new( L0, newstr(executed_command) ), outf_int(status) ), outf_time(time->start) ), outf_time(time->end) ), outf_double(time->user) ), outf_double(time->system) ) ); /* output ? :: the output of the action command */ if (command_output) lol_add(frame->args, list_new(L0, newstr(command_output))); else lol_add(frame->args, L0); /* Call the rule. */ evaluate_rule( action_rule->string, frame ); /* Clean up */ frame_free( frame ); } }
void headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; LIST *headlist = 0; regexp *re[ MAXINC ]; int rec = 0; if( !( hdrscan = var_get( "HDRSCAN" ) ) || !( hdrrule = var_get( "HDRRULE" ) ) ) return; if( DEBUG_HEADER ) printf( "header scan %s\n", t->name ); /* Compile all regular expressions in HDRSCAN */ while( rec < MAXINC && hdrscan ) { re[rec++] = regex_compile( hdrscan->string ); hdrscan = list_next( hdrscan ); } /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ { FRAME frame[1]; frame_init( frame ); lol_add( frame->args, list_new( L0, t->name ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( frame->args, hcache( t, rec, re, hdrscan ) ); #else lol_add( frame->args, headers1( headlist, t->boundname, rec, re ) ); #endif if( lol_get( frame->args, 1 ) ) { /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( frame->args, list_new( L0, t->boundname ) ); list_free( evaluate_rule( hdrrule->string, frame ) ); } /* Clean up */ frame_free( frame ); } }
int LS_jam_evaluaterule(ls_lua_State *L) { LOL lol; int i; LIST *list; int index; int numParams = ls_lua_gettop(L); if (numParams < 1) return 0; if (!ls_lua_isstring(L, 1)) return 0; lol_init(&lol); for (i = 0; i < numParams - 1; ++i) { lol_add(&lol, luahelper_addtolist(L, L0, 2 + i)); } list = evaluate_rule(ls_lua_tostring(L, 1), &lol, L0); lol_free(&lol); ls_lua_newtable(L); index = 1; for (; list; list = list_next(list), ++index) { ls_lua_pushnumber(L, index); ls_lua_pushstring(L, list->string); ls_lua_settable(L, -3); } return 1; }
LIST * call_rule( char * rulename, FRAME * caller_frame, ... ) { va_list va; LIST * result; FRAME inner[1]; frame_init( inner ); inner->prev = caller_frame; inner->prev_user = caller_frame->module->user_module ? caller_frame : caller_frame->prev_user; inner->module = caller_frame->module; inner->procedure = 0; va_start( va, caller_frame ); for ( ; ; ) { LIST * l = va_arg( va, LIST* ); if ( !l ) break; lol_add( inner->args, l ); } va_end( va ); result = evaluate_rule( rulename, inner ); frame_free( inner ); return result; }
LIST * compile_rule( PARSE * parse, FRAME * frame ) { FRAME inner[ 1 ]; LIST * result; PARSE * p; /* Build up the list of arg lists. */ frame_init( inner ); inner->prev = frame; inner->prev_user = frame->module->user_module ? frame : frame->prev_user; inner->module = frame->module; /* This gets fixed up in evaluate_rule(), below. */ inner->procedure = parse; /* Special-case LOL of length 1 where the first list is totally empty. This is created when calling functions with no parameters, due to the way jam grammar is written. This is OK when one jam function calls another, but really not good when Jam function calls Python. */ if ( parse->left->left == NULL && parse->left->right->func == compile_null) ; else for ( p = parse->left; p; p = p->left ) lol_add( inner->args, parse_evaluate( p->right, frame ) ); /* And invoke the rule. */ result = evaluate_rule( parse->string, inner ); frame_free( inner ); return result; }
LIST * compile_rule( PARSE *parse, FRAME *frame ) { FRAME inner[1]; LIST *result; PARSE *p; /* Build up the list of arg lists */ frame_init( inner ); inner->prev = frame; inner->prev_user = frame->module->user_module ? frame : frame->prev_user; 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, parse_evaluate( p->right, frame ) ); /* And invoke rule */ result = evaluate_rule( parse->string, inner ); frame_free( inner ); return result; }
/* Look up the __TIMING_RULE__ variable on the given target, and if * non-empty, invoke the rule it names, passing the given * timing_info */ static void call_timing_rule(TARGET* target, timing_info* time) { LIST* timing_rule; pushsettings(target->settings); timing_rule = var_get( "__TIMING_RULE__" ); popsettings(target->settings); if (timing_rule) { /* We'll prepend $(__TIMING_RULE__[2-]) to the first argument */ LIST* initial_args = list_copy( L0, timing_rule->next ); /* Prepare the argument list */ FRAME frame[1]; frame_init( frame ); /* First argument is the name of the timed target */ lol_add( frame->args, list_new( initial_args, target->name ) ); append_double_string(frame->args, time->user); append_double_string(frame->args, time->system); if( lol_get( frame->args, 2 ) ) evaluate_rule( timing_rule->string, frame ); /* Clean up */ frame_free( frame ); } }
LIST * compile_rule( PARSE *parse, LOL *args, int *jmp ) { LOL nargs[1]; LIST *result = 0; LIST *ll; LISTITEM *l; PARSE *p; /* list of rules to run -- normally 1! */ ll = (*parse->left->func)( parse->left, args, jmp ); /* Build up the list of arg lists */ lol_init( nargs ); for( p = parse->right; p; p = p->left ) lol_add( nargs, (*p->right->func)( p->right, args, jmp ) ); /* Run rules, appending results from each */ for( l = list_first(ll); l; l = list_next( l ) ) { list_free(result); /* Keep only last result */ result = evaluate_rule( list_value(l), nargs, result ); } list_free( ll ); lol_free( nargs ); return result; }
static void type_check ( char * type_name, LIST * values, FRAME * caller, RULE * called, LIST * arg_name ) { static module_t * typecheck = 0; /* If nothing to check, bail now. */ if ( !values || !type_name ) return; if ( !typecheck ) typecheck = bindmodule( ".typecheck" ); /* If the checking rule can not be found, also bail. */ { RULE checker_, *checker = &checker_; checker->name = type_name; if ( !typecheck->rules || !hashcheck( typecheck->rules, (HASHDATA * *)&checker ) ) return; } exit_module( caller->module ); while ( values != 0 ) { LIST *error; FRAME frame[1]; frame_init( frame ); frame->module = typecheck; frame->prev = caller; frame->prev_user = caller->module->user_module ? caller : caller->prev_user; enter_module( typecheck ); /* Prepare the argument list */ lol_add( frame->args, list_new( L0, values->string ) ); error = evaluate_rule( type_name, frame ); exit_module( typecheck ); if ( error ) argument_error( error->string, called, caller, arg_name ); frame_free( frame ); values = values->next; } enter_module( caller->module ); }
/* Look up the __TIMING_RULE__ variable on the given target, and if * non-empty, invoke the rule it names, passing the given * timing_info */ static void call_timing_rule(TARGET* target, timing_info* time) { LIST* timing_rule; pushsettings(target->settings); timing_rule = var_get( "__TIMING_RULE__" ); popsettings(target->settings); if (timing_rule) { /* rule timing-rule ( args * : target : start end user system ) */ /* Prepare the argument list */ FRAME frame[1]; frame_init( frame ); /* args * :: $(__TIMING_RULE__[2-]) */ lol_add( frame->args, list_copy( L0, timing_rule->next ) ); /* target :: the name of the target */ lol_add( frame->args, list_new( L0, target->name ) ); /* start end user system :: info about the action command */ lol_add( frame->args, list_new( list_new( list_new( list_new( L0, outf_time(time->start) ), outf_time(time->end) ), outf_double(time->user) ), outf_double(time->system) ) ); /* Call the rule. */ evaluate_rule( timing_rule->string, frame ); /* Clean up */ frame_free( frame ); } }
void headers( TARGET *t ) { LIST *hdrscan; LIST *hdrrule; LOL lol; if( !list_first( hdrscan = var_get( "HDRSCAN" ) ) || !list_first( hdrrule = var_get( "HDRRULE" ) ) ) return; /* Doctor up call to HDRRULE rule */ /* Call headers1() to get LIST of included files. */ if( DEBUG_HEADER ) printf( "header scan %s\n", t->name ); lol_init( &lol ); lol_add( &lol, list_append( L0, t->name, 1 ) ); #ifdef OPT_HEADER_CACHE_EXT lol_add( &lol, hcache( t, hdrscan ) ); #else lol_add( &lol, headers1( t->boundname, hdrscan ) ); #endif if( list_first(lol_get( &lol, 1 )) ) { #ifdef OPT_HDRRULE_BOUNDNAME_ARG_EXT /* The third argument to HDRRULE is the bound name of * $(<) */ lol_add( &lol, list_append( L0, t->boundname, 0 ) ); #endif list_free( evaluate_rule( list_value(list_first(hdrrule)), &lol, L0 ) ); } /* Clean up */ lol_free( &lol ); }
LIST * headers1( const char *file, LIST *hdrscan ) { FILE *f; LIST *result = 0; LIST *hdrpipe; LIST *hdrpipefile; if ( list_first(hdrpipe = var_get( "HDRPIPE" )) ) { LOL args; BUFFER buff; lol_init( &args ); lol_add( &args, list_append( L0, file, 0 ) ); buffer_init( &buff ); if ( var_string( list_value(list_first(hdrpipe)), &buff, 0, &args, ' ') < 0 ) { printf( "Cannot expand HDRPIPE '%s' !\n", list_value(list_first(hdrpipe)) ); exit( EXITBAD ); } buffer_addchar( &buff, 0 ); if ( !( f = file_popen( (const char*)buffer_ptr( &buff ), "r" ) ) ) { buffer_free( &buff ); return result; } buffer_free( &buff ); lol_free( &args ); } else { if( !( f = fopen( file, "r" ) ) ) return result; } result = headers1helper( f, hdrscan ); if ( list_first(hdrpipe) ) file_pclose( f ); else fclose( f ); if ( list_first(hdrpipefile = var_get( "HDRPIPEFILE" )) ) { if( !( f = fopen( list_value(list_first(hdrpipefile)), "r" ) ) ) return result; result = headers1helper( f, hdrscan ); fclose( f ); } return result; }
void call_bind_rule( char* target_, char* boundname_ ) { LIST* bind_rule = var_get( "BINDRULE" ); if( bind_rule ) { /* No guarantee that target is an allocated string, so be on the * safe side */ char* target = copystr( target_ ); /* Likewise, don't rely on implementation details of newstr.c: allocate * a copy of boundname */ char* boundname = copystr( boundname_ ); if( boundname && target ) { /* Prepare the argument list */ FRAME frame[1]; frame_init( frame ); /* First argument is the target name */ lol_add( frame->args, list_new( L0, target ) ); lol_add( frame->args, list_new( L0, boundname ) ); if( lol_get( frame->args, 1 ) ) evaluate_rule( bind_rule->string, frame ); /* Clean up */ frame_free( frame ); } else { if( boundname ) freestr( boundname ); if( target ) freestr( target ); } } }
static void call_timing_rule( TARGET * target, timing_info const * const time ) { LIST * timing_rule; pushsettings( root_module(), target->settings ); timing_rule = var_get( root_module(), constant_TIMING_RULE ); popsettings( root_module(), target->settings ); if ( !list_empty( timing_rule ) ) { /* rule timing-rule ( args * : target : start end user system ) */ /* Prepare the argument list. */ FRAME frame[ 1 ]; OBJECT * rulename = list_front( timing_rule ); frame_init( frame ); /* args * :: $(__TIMING_RULE__[2-]) */ lol_add( frame->args, list_copy_range( timing_rule, list_next( list_begin( timing_rule ) ), list_end( timing_rule ) ) ); /* target :: the name of the target */ lol_add( frame->args, list_new( object_copy( target->name ) ) ); /* start end user system :: info about the action command */ lol_add( frame->args, list_push_back( list_push_back( list_push_back( list_new( outf_time( &time->start ) ), outf_time( &time->end ) ), outf_double( time->user ) ), outf_double( time->system ) ) ); /* Call the rule. */ evaluate_rule( bindrule( rulename , root_module() ), rulename, frame ); /* Clean up. */ frame_free( frame ); } }
void call_bind_rule ( OBJECT * target_, OBJECT * boundname_ ) { OBJECT * varname = object_new( "BINDRULE" ); LIST * bind_rule = var_get( varname ); object_free( varname ); if ( bind_rule ) { OBJECT * target = object_copy( target_ ); OBJECT * boundname = object_copy( boundname_ ); if ( boundname && target ) { /* Prepare the argument list. */ FRAME frame[1]; frame_init( frame ); /* First argument is the target name. */ lol_add( frame->args, list_new( L0, target ) ); lol_add( frame->args, list_new( L0, boundname ) ); if ( lol_get( frame->args, 1 ) ) list_free( evaluate_rule( bind_rule->value, frame ) ); /* Clean up */ frame_free( frame ); } else { if ( boundname ) object_free( boundname ); if ( target ) object_free( target ); } } }
LIST * compile_setcomp( PARSE * parse, FRAME * frame ) { argument_list * arg_list = 0; /* Create new LOL describing argument requirements if supplied. */ if ( parse->right ) { PARSE * p; arg_list = args_new(); for ( p = parse->right; p; p = p->left ) lol_add( arg_list->data, parse_evaluate( p->right, frame ) ); } new_rule_body( frame->module, parse->string, arg_list, parse->left, !parse->num ); return L0; }
LIST * compile_rule( PARSE *parse, LOL *args, int *jmp ) { LOL nargs[1]; LIST *result = 0; LIST *ll, *l; PARSE *p; /* list of rules to run -- normally 1! */ ll = (*parse->left->func)( parse->left, args, jmp ); /* Build up the list of arg lists */ lol_init( nargs ); for( p = parse->right; p; p = p->left ) lol_add( nargs, (*p->right->func)( p->right, args, jmp ) ); /* Run rules, appending results from each */ for( l = ll; l; l = list_next( l ) ) { int localJmp = JMP_NONE; result = evaluate_rule( l->string, nargs, result, &localJmp ); if (localJmp == JMP_EOF) { *jmp = JMP_EOF; break; } } list_free( ll ); lol_free( nargs ); return result; }
int LS_jam_evaluaterule(ls_lua_State *L) { LOL lol; int i; LIST *list; LISTITEM* item; int index; const char* rule; int numParams = ls_lua_gettop(L); if (numParams < 1) return 0; if (!ls_lua_isstring(L, 1)) return 0; lol_init(&lol); rule = ls_lua_tostring(L, 1); for (i = 0; i < numParams - 1; ++i) { lol_add(&lol, luahelper_addtolist(L, L0, 2 + i)); } list = evaluate_rule(rule, &lol, L0); lol_free(&lol); ls_lua_newtable(L); index = 1; for (item = list_first(list); item; item = list_next(item), ++index) { ls_lua_pushnumber(L, index); ls_lua_pushstring(L, list_value(item)); ls_lua_settable(L, -3); } return 1; }
CMD * cmd_new( RULE *rule, LIST *targets, LIST *sources, LIST *shell ) { CMD *cmd = (CMD *)malloc( sizeof( CMD ) ); /* lift line-length limitation entirely when JAMSHELL is just "%" */ int no_limit = ( shell && !strcmp(shell->string,"%") && !list_next(shell) ); int max_line = MAXLINE; int allocated = -1; if ( DEBUG_PROFILE ) profile_memory( sizeof( CMD ) ); cmd->rule = rule; cmd->shell = shell; cmd->next = 0; lol_init( &cmd->args ); lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); cmd->buf = 0; do { free(cmd->buf); /* free any buffer from previous iteration */ cmd->buf = (char*)malloc(max_line + 1); if ( DEBUG_PROFILE ) profile_memory( max_line + 1 ); if (cmd->buf == 0) break; allocated = var_string( rule->actions->command, cmd->buf, max_line, &cmd->args ); max_line = max_line * 2; } while( allocated < 0 && max_line < INT_MAX / 2 ); if ( !no_limit ) { /* Bail if the result won't fit in MAXLINE */ char *s = cmd->buf; while ( *s ) { size_t l = strcspn( s, "\n" ); if ( l > MAXLINE ) { /* We don't free targets/sources/shell if bailing. */ cmd_free( cmd ); return 0; } s += l; if ( *s ) ++s; } } return cmd; }
LIST * evaluate_rule( const char *rulename, LOL *args, LIST *result ) { #ifdef OPT_EXPAND_RULE_NAMES_EXT RULE *rule; char *expanded; char *c; int i; BUFFER buff; buffer_init( &buff ); if( (i = var_string( rulename, &buff, 0, args, ' ' )) < 0 ) { printf( "Failed to expand rule %s -- expansion too long\n", rulename ); exit( EXITBAD ); } expanded = buffer_ptr( &buff ); while ( expanded[0] == ' ' ) expanded++; while ( (c = strrchr(expanded, ' ')) ) *c = '\0'; if( DEBUG_COMPILE ) { debug_compile( 1, rulename ); if ( strcmp(rulename, expanded) ) printf( "-> %s ", expanded ); lol_print( args ); printf( "\n" ); } rule = bindrule( expanded ); #else RULE *rule = bindrule( rulename ); if( DEBUG_COMPILE ) { debug_compile( 1, rulename ); lol_print( args ); printf( "\n" ); } #endif #ifdef OPT_LOAD_MISSING_RULE_EXT if( !rule->actions && !rule->procedure ) { if( ruleexists( "FindMissingRule" ) ) { LOL lol; LIST *args = list_append( L0, expanded, 0 ); LIST *result; lol_init( &lol ); lol_add( &lol, args ); result = evaluate_rule( "FindMissingRule", &lol, L0 ); lol_free( &lol ); if( list_first( result ) ) { rule = bindrule( list_value( list_first( result ) ) ); } list_free( result ); } } #endif /* OPT_LOAD_MISSING_RULE_EXT */ /* Check traditional targets $(<) and sources $(>) */ #ifdef OPT_IMPROVED_WARNINGS_EXT if( !rule->actions && !rule->procedure && !globs.silence ) printf( "warning: unknown rule %s %s\n", rule->name, file_and_line()); #else if( !rule->actions && !rule->procedure ) printf( "warning: unknown rule %s\n", rule->name ); #endif /* If this rule will be executed for updating the targets */ /* then construct the action for make(). */ if( rule->actions ) { TARGETS *t; ACTION *action; /* The action is associated with this instance of this rule */ action = (ACTION *)malloc( sizeof( ACTION ) ); memset( (char *)action, '\0', sizeof( *action ) ); action->rule = rule; #ifdef OPT_BUILTIN_NEEDS_EXT action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ), 0 ); action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ), 0 ); action->autosettings = targetlist( (TARGETS *)0, lol_get( args, 2 ), 0 ); #else action->targets = targetlist( (TARGETS *)0, lol_get( args, 0 ) ); action->sources = targetlist( (TARGETS *)0, lol_get( args, 1 ) ); #endif #ifdef OPT_USE_CHECKSUMS_EXT action->extratargets = targetlist( (TARGETS *)0, lol_get( args, 3 ), 0 ); #endif /* OPT_USE_CHECKSUMS_EXT */ #ifdef OPT_CLEAN_GLOBS_EXT { TARGETS* targets; for ( targets = action->targets; targets; targets = targets->next ) { if ( !( targets->target->flags & T_FLAG_NOTFILE ) ) add_used_target_to_hash( targets->target ); } } #endif /* OPT_CLEAN_GLOBS_EXT */ /* Append this action to the actions of each target */ #ifdef OPT_MULTIPASS_EXT action->pass = actionpass; for( t = action->targets; t; t = t->next ) { t->target->progress = T_MAKE_INIT; t->target->actions = actionlist( t->target->actions, action ); } #else for( t = action->targets; t; t = t->next ) t->target->actions = actionlist( t->target->actions, action ); #endif } /* Now recursively compile any parse tree associated with this rule */ if( rule->procedure ) { PARSE *parse = rule->procedure; SETTINGS *s = 0; int jmp = JMP_NONE; LISTITEM *l; int i; /* build parameters as local vars */ for( l = list_first(rule->params), i = 0; l; l = list_next(l), i++ ) s = addsettings( s, 0, list_value(l), list_copy( L0, lol_get( args, i ) ) ); /* Run rule. */ /* Bring in local params. */ /* refer/free to ensure rule not freed during use. */ parse_refer( parse ); pushsettings( s ); result = list_appendList( result, (*parse->func)( parse, args, &jmp ) ); popsettings( s ); freesettings( s ); parse_free( parse ); } if( DEBUG_COMPILE ) debug_compile( -1, 0 ); #ifdef OPT_EXPAND_RULE_NAMES_EXT buffer_free( &buff ); #endif return result; }
/* To l, append a 1-element list containing the string representation * of x */ static void append_double_string( LOL *l, double x ) { char buffer[50]; sprintf(buffer, "%f", x); lol_add( l, list_new( L0, newstr( buffer ) ) ); }
LIST * hcache( TARGET *t, LIST *hdrscan ) { HCACHEDATA cachedata, *c = &cachedata; HCACHEFILE *file; LIST *l = 0; int use_cache = 1; const char *target; # ifdef DOWNSHIFT_PATHS char path[ MAXJPATH ]; char *p; # endif target = t->boundname; # ifdef DOWNSHIFT_PATHS p = path; do *p++ = (char)tolower( *target ); while( *target++ ); target = path; # endif ++queries; c->boundname = target; file = hcachefile_get( t ); // if ( file ) { if( hashcheck( file->hcachehash, (HASHDATA **) &c ) ) { #ifdef OPT_BUILTIN_MD5CACHE_EXT if( c->time == t->time && md5matchescommandline( t ) ) #else if( c->time == t->time ) #endif { LIST *l1 = hdrscan, *l2 = c->hdrscan; while( l1 && l2 ) { if( l1->string != l2->string ) { l1 = 0; } else { l1 = list_next( l1 ); l2 = list_next( l2 ); } } if( l1 || l2 ) use_cache = 0; } else use_cache = 0; if( use_cache ) { if( DEBUG_HEADER ) printf( "using header cache for %s\n", t->boundname ); c->age = 0; /* The entry has been used, its young again */ ++hits; l = list_copy( 0, c->includes ); { LIST *hdrfilter = var_get( "HDRFILTER" ); if ( hdrfilter ) { LOL lol; lol_init( &lol ); lol_add( &lol, list_new( L0, t->name, 1 ) ); lol_add( &lol, l ); lol_add( &lol, list_new( L0, t->boundname, 0 ) ); l = evaluate_rule( hdrfilter->string, &lol, L0 ); lol_free( &lol ); } } return l; } else { if( DEBUG_HEADER ) printf( "header cache out of date for %s\n", t->boundname ); list_free( c->includes ); list_free( c->hdrscan ); c->includes = 0; c->hdrscan = 0; } } else { if( hashenter( file->hcachehash, (HASHDATA **)&c ) ) { c->boundname = newstr( c->boundname ); c->next = file->hcachelist; file->hcachelist = c; #ifdef OPT_BUILTIN_MD5CACHE_EXT c->mtime = 0; memset( &c->rulemd5sum, 0, MD5_SUMSIZE ); memset( &c->currentrulemd5sum, 0, MD5_SUMSIZE ); memset( &c->contentmd5sum, 0, MD5_SUMSIZE ); memset( &c->currentcontentmd5sum, 0, MD5_SUMSIZE ); #endif } } } file->dirty = 1; /* 'c' points at the cache entry. Its out of date. */ l = headers1( c->boundname, hdrscan ); l = list_append( list_copy( 0, var_get( "HDREXTRA" ) ), l ); c->includes = list_copy( 0, l ); { LIST *hdrfilter = var_get( "HDRFILTER" ); if ( hdrfilter ) { LOL lol; lol_init( &lol ); lol_add( &lol, list_new( L0, t->name, 1 ) ); lol_add( &lol, l ); lol_add( &lol, list_new( L0, t->boundname, 0 ) ); l = evaluate_rule( hdrfilter->string, &lol, L0 ); lol_free( &lol ); } } c->time = t->time; c->age = 0; c->hdrscan = list_copy( 0, hdrscan ); return l; }