⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 compile.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 3 页
字号:
    rule = bindrule( l->string, frame->module );#ifdef HAVE_PYTHON    if (rule->python_function)    {        /* The below messing with modules is due to the           way modules are implemented in jam.             Suppose we're in module M1 now.  The global           variable map actually holds 'M1' variables,           and M1->variables hold global variables.           If we call Python right away, and then Python           call back Jam, and jam does:              module M1 {  }           then jam will try to swap current global            variables with M1->variables. The result will           be that global variables map will hold           global variables, and any variables settings           we do will go to global module, not M1.           By restoring basic state, where global           variable map hold global variable, we make           sure any fugure 'module M1' will work OK.  */                   LIST *result;        module_t *m = python_module();        frame->module = m;                exit_module( prev_module );        enter_module( m );        result = call_python_function(rule, frame);        exit_module( m );        enter_module ( prev_module );        return result;    }#endif    /* 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 ) );    if ( DEBUG_COMPILE )    {        /* Try hard to indicate in which module the rule is going to execute */        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);        }        lol_print( frame->args );        printf( "\n" );    }        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 );    }            /* record current rule name in frame */    if ( rule->procedure )    {        frame->rulename = 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( "rule %s unknown in module %s\n", rule->name, frame->module->name );        backtrace( frame->prev );        exit(1);    }    /* 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 *)BJAM_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 ) );                /*  Make targets[1,N-1] depend on targets[0], to describe the multply            generated targets for the rule. Do it with includes, to reflect            non-build dependency. */        if ( action->targets )        {            TARGET * t0 = action->targets->target;            for ( t = action->targets->next; t; t = t->next )            {                TARGET * tn = t->target;                if ( !tn->includes )                {                    tn->includes = copytarget( tn );                    tn->includes->original_target = tn;                }                tn = tn->includes;                tn->depends = targetentry( tn->depends, t0 );            }        }        /* 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 );        freesettings( 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;}/* * Call the given rule with the specified parameters. * The parameters should be of LIST* and end with NULL pointer. * This differs from the 'evaluate_rule' in that frame * for called rule is prepared in 'call_rule'. * * This function is usefull when builtin rule (in C) wants to * call another rule, which might be implemented in Jam. */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;}/* * compile_rules() - compile a chain of rules * *	parse->left	single rule *	parse->right	more compile_rules() by right-recursion */LIST *compile_rules(    PARSE   *parse,    FRAME *frame ){    /* Ignore result from first statement; return the 2nd. */	/* Optimize recursion on the right by looping. */    do list_free( parse_evaluate( parse->left, frame ) );    while( (parse = parse->right)->func == compile_rules );    return parse_evaluate( parse, frame );}/* * assign_var_mode() - convert ASSIGN_XXX compilation flag into *                     corresponding VAR_XXX variable set flag. */static int assign_var_mode(int parsenum, const char **tracetext){    const char *trace;    int setflag;    switch( parsenum )    {        case ASSIGN_SET:     setflag = VAR_SET; trace = "="; break;        case ASSIGN_APPEND:  setflag = VAR_APPEND; trace = "+="; break;        case ASSIGN_DEFAULT: setflag = VAR_DEFAULT; trace = "?="; break;        default:             setflag = VAR_SET; trace = ""; break;    }    if (tracetext)        *tracetext = trace ;    return setflag;}/* * compile_set() - compile the "set variable" statement * *  parse->left variable names *  parse->right    variable values  *  parse->num  ASSIGN_SET/APPEND/DEFAULT */LIST *compile_set(    PARSE   *parse,    FRAME *frame ){    LIST    *nt = parse_evaluate( parse->left, frame );    LIST    *ns = parse_evaluate( parse->right, frame );    LIST    *l;    const char *trace;    int     setflag = assign_var_mode( parse->num, &trace );    if( DEBUG_COMPILE )    {        debug_compile( 0, "set", frame);        list_print( nt );        printf( " %s ", trace );        list_print( ns );        printf( "\n" );    }    /* Call var_set to set variable */    /* var_set keeps ns, so need to copy it */    for( l = nt; l; l = list_next( l ) )        var_set( l->string, list_copy( L0, ns ), setflag );    list_free( nt );    return ns;}/* * compile_setcomp() - support for `rule` - save parse tree  * *  parse->string   rule name *  parse->left rules for rule *  parse->right optional list-of-lists describing arguments */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;}/* * compile_setexec() - support for `actions` - save execution string  * *  parse->string   rule name *  parse->string1  OS command string *  parse->num  flags *  parse->left `bind` variables * * Note that the parse flags (as defined in compile.h) are transfered * directly to the rule flags (as defined in rules.h). */LIST *compile_setexec(    PARSE   *parse,    FRAME *frame ){    LIST* bindlist = parse_evaluate( parse->left, frame );    new_rule_actions( frame->module, parse->string, parse->string1, bindlist, parse->num );    return L0;}/* * compile_settings() - compile the "on =" (set variable on exec) statement * *  parse->left variable names *  parse->right    target name  *  parse->third    variable value  *  parse->num  ASSIGN_SET/APPEND    */LIST *compile_settings(    PARSE   *parse,    FRAME *frame ){    LIST    *nt = parse_evaluate( parse->left, frame );    LIST    *ns = parse_evaluate( parse->third, frame );    LIST    *targets = parse_evaluate( parse->right, frame );    LIST    *ts;    const char *trace;    int     setflag = assign_var_mode( parse->num, &trace );    if( DEBUG_COMPILE )    {        debug_compile( 0, "set", frame);        list_print( nt );        printf( " on " );        list_print( targets );        printf( " %s ", trace );        list_print( ns );        printf( "\n" );    }    /* Call addsettings to save variable setting */    /* addsettings keeps ns, so need to copy it */    /* Pass append flag to addsettings() */    for( ts = targets; ts; ts = list_next( ts ) )    {        TARGET  *t = bindtarget( ts->string );        LIST    *l;        for( l = nt; l; l = list_next( l ) )        t->settings = addsettings( t->settings, setflag,                 l->string, list_copy( (LIST*)0, ns ) );    }    list_free( nt );    list_free( targets );    return ns;}/* * compile_switch() - compile 'switch' rule * *  parse->left switch value (only 1st used) *  parse->right    cases * *  cases->left 1st case *  cases->right    next cases * *  case->string    argument to match *  case->left  parse tree to execute */LIST *compile_switch(    PARSE   *parse,    FRAME *frame ){    LIST    *nt = parse_evaluate( parse->left, frame );    LIST    *result = 0;    if( DEBUG_COMPILE )    {        debug_compile( 0, "switch", frame);        list_print( nt );        printf( "\n" );    }    /* Step through cases */    for( parse = parse->right; parse; parse = parse->right )    {        if( !glob( parse->left->string, nt ? nt->string : "" ) )        {        /* Get & exec parse tree for this case */        parse = parse->left->left;        result = parse_evaluate( parse, frame );        break;        }    }    list_free( nt );    return result;}/* * debug_compile() - printf with indent to show rule expansion. */static voiddebug_compile( int which, char *s, FRAME* frame ){    static int level = 0;    static char indent[36] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|";    if ( which >= 0 )    {      int i;            print_source_line( frame->procedure );            i = (level+1)*2;      while ( i > 35 )      {        printf( indent );        i -= 35;      }      printf( "%*.*s ", i, i, indent );    }    if( s )        printf( "%s ", s );    level += which;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -