debug_compile( 1, l->string, frame);
if ( rule->module != frame->module && rule->procedure != 0 && strcmp(rulename, rule->procedure->rulename) ) { char buf[256] = ""; strncat( buf, rule->module->name, sizeof(buf) - 1 ); strncat( buf, rule->name, sizeof(buf) - 1 ); debug_compile( 1, buf, frame); } else { debug_compile( 1, rulename, frame); }
evaluate_rule(    char    *rulename,    FRAME *frame ){    LIST      *result = L0;    RULE          *rule;    profile_frame prof[1];    module    *prev_module = frame->module;        LIST      *l;    {        LOL arg_context_, *arg_context = &arg_context_;        if ( !frame->prev )            lol_init(arg_context);        else            arg_context = frame->prev->args;                l = var_expand( L0, rulename, rulename+strlen(rulename), arg_context, 0 );    }    if ( !l )    {        backtrace_line( frame->prev );        printf( "warning: rulename %s expands to empty string\n", rulename );        backtrace( frame->prev );        return result;    }    if ( DEBUG_COMPILE )    {        debug_compile( 1, l->string, frame);        lol_print( frame->args );        printf( "\n" );    }    rulename = l->string;    rule = bindrule( l->string, frame->module );    if ( rule->procedure && rule->module != prev_module )    {        /* propagate current module to nested rule invocations */        frame->module = rule->module;                /* swap variables */        exit_module( prev_module );        enter_module( rule->module );    }    /* drop the rule name */    l = list_pop_front( l );        /* tack the rest of the expansion onto the front of the first argument */    frame->args->list[0] = list_append( l, lol_get( frame->args, 0 ) );        /* 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(). */    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;        action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );        action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );        /* Append this action to the actions of each target */        for( t = action->targets; t; t = t->next )            t->target->actions = actionlist( t->target->actions, action );    }    /* Now recursively compile any parse tree associated with this rule */    /* refer/free to ensure rule not freed during use */    if( rule->procedure )    {        SETTINGS *local_args = collect_arguments( rule, frame );        PARSE *parse = rule->procedure;        parse_refer( parse );                pushsettings( local_args );        result = parse_evaluate( parse, frame );        popsettings( local_args );                parse_free( parse );    }    if ( frame->module != prev_module )    {        exit_module( frame->module );        enter_module( prev_module );    }    if ( DEBUG_PROFILE && rule->procedure )        profile_exit( prof );    if( DEBUG_COMPILE )        debug_compile( -1, 0, frame);    return result;}