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

📄 rules.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
{	SETTINGS *v;		/* Look for previous setting */	for( v = head; v; v = v->next )	    if( !strcmp( v->symbol, symbol ) )		break;	/* If not previously set, alloc a new. */	/* If appending, do so. */	/* Else free old and set new. */	if( !v )	{        v = settings_freelist;                if ( v )            settings_freelist = v->next;        else        {            v = (SETTINGS *)BJAM_MALLOC( sizeof( *v ) );        }        	    v->symbol = newstr( symbol );	    v->value = value;	    v->next = head;	    head = v;	}	else if( flag == VAR_APPEND )	{	    v->value = list_append( v->value, value );	}	else if( flag != VAR_DEFAULT )	{	    list_free( v->value );	    v->value = value;	}         else            list_free( value );	/* Return (new) head of list. */	return head;}/* * pushsettings() - set all target specific variables */voidpushsettings( SETTINGS *v ){	for( ; v; v = v->next )	    v->value = var_swap( v->symbol, v->value );}/* * popsettings() - reset target specific variables to their pre-push values */voidpopsettings( SETTINGS *v ){	pushsettings( v );	/* just swap again */}/* * copysettings() - duplicate a settings list, returning the new copy */SETTINGS*copysettings( SETTINGS *head ){    SETTINGS *copy = 0, *v;    for (v = head; v; v = v->next)	copy = addsettings(copy, VAR_SET, v->symbol, list_copy(0, v->value));    return copy;}/* *    freetargets() - delete a targets list */void freetargets( TARGETS *chain ){    while( chain )    {        TARGETS* n = chain->next;        BJAM_FREE( chain );        chain = n;    }}/* *    freeactions() - delete an action list */void freeactions( ACTIONS *chain ){    while( chain )    {        ACTIONS* n = chain->next;        BJAM_FREE( chain );        chain = n;    }}/* *    freesettings() - delete a settings list */voidfreesettings( SETTINGS *v ){	while( v )	{	    SETTINGS *n = v->next;	    freestr( v->symbol );	    list_free( v->value );        v->next = settings_freelist;        settings_freelist = v;	    v = n;	}}static void freetarget( void *xt, void *data ){    TARGET* t = (TARGET *)xt;    if ( t->settings )        freesettings( t->settings );    if ( t->depends )        freetargets( t->depends );    if ( t->includes )        freetarget( t->includes, (void*)0);    if ( t->actions )        freeactions( t->actions );}/* * donerules() - free TARGET tables */voiddonerules(){     hashenumerate( targethash, freetarget, 0 );	hashdone( targethash );    while ( settings_freelist )    {        SETTINGS* n = settings_freelist->next;        BJAM_FREE( settings_freelist );        settings_freelist = n;    }}/* * args_new() - make a new reference-counted argument list */argument_list* args_new(){    argument_list* r = (argument_list*)BJAM_MALLOC( sizeof(argument_list) );    r->reference_count = 0;    lol_init(r->data);    return r;}/* * args_refer() - add a new reference to the given argument list */void args_refer( argument_list* a ){    ++a->reference_count;}/* * args_free() - release a reference to the given argument list */void args_free( argument_list* a ){    if (--a->reference_count <= 0)    {        lol_free(a->data);        BJAM_FREE(a);    }}/* * actions_refer() - add a new reference to the given actions */void actions_refer(rule_actions* a){    ++a->reference_count;}/* * actions_free() - release a reference to the given actions */void actions_free(rule_actions* a){    if (--a->reference_count <= 0)    {        freestr(a->command);        list_free(a->bindlist);        BJAM_FREE(a);    }}/* * set_rule_body() - set the argument list and procedure of the given rule */static void set_rule_body( RULE* rule, argument_list* args, PARSE* procedure ){    if ( args )        args_refer( args );    if ( rule->arguments )        args_free( rule->arguments );    rule->arguments = args;        if ( procedure )        parse_refer( procedure );    if ( rule->procedure )        parse_free( rule->procedure );    rule->procedure = procedure;}/* * global_name() - given a rule, return the name for a corresponding rule in the global module */static char* global_rule_name( RULE* r ){    if ( r->module == root_module() )    {        return r->name;    }    else    {        char name[4096] = "";        strncat(name, r->module->name, sizeof(name) - 1);        strncat(name, r->name, sizeof(name) - 1 );        return newstr(name);    }}/* * global_rule() - given a rule, produce the corresponding entry in the global module */static RULE* global_rule( RULE* r ){    if ( r->module == root_module() )    {        return r;    }    else    {        char* name = global_rule_name( r );        RULE* result = define_rule( r->module, name, root_module() );        freestr(name);        return result;    }}/* * new_rule_body() - make a new rule named rulename in the given * module, with the given argument list and procedure. If exported is * true, the rule is exported to the global module as * modulename.rulename. */RULE* new_rule_body( module_t* m, char* rulename, argument_list* args, PARSE* procedure, int exported ){    RULE* local = define_rule( m, rulename, m );    local->exported = exported;    set_rule_body( local, args, procedure );        /* Mark the procedure with the global rule name, regardless of     * whether the rule is exported. That gives us something     * reasonably identifiable that we can use, e.g. in profiling     * output. Only do this once, since this could be called multiple     * times with the same procedure.     */    if ( procedure->rulename == 0 )        procedure->rulename = global_rule_name( local );    return local;}static void set_rule_actions( RULE* rule, rule_actions* actions ){    if ( actions )        actions_refer( actions );    if ( rule->actions )        actions_free( rule->actions );    rule->actions = actions;    }static rule_actions* actions_new( char* command, LIST* bindlist, int flags ){    rule_actions* result = (rule_actions*)BJAM_MALLOC(sizeof(rule_actions));    result->command = copystr( command );    result->bindlist = bindlist;    result->flags = flags;    result->reference_count = 0;    return result;}RULE* new_rule_actions( module_t* m, char* rulename, char* command, LIST* bindlist, int flags ){    RULE* local = define_rule( m, rulename, m );    RULE* global = global_rule( local );    set_rule_actions( local, actions_new( command, bindlist, flags ) );    set_rule_actions( global, local->actions );    return local;}/* Looks for a rule in the specified module, and returns it, if found.   First checks if the rule is present in the module's rule table.   Second, if name of the rule is in the form name1.name2 and name1 is in    the list of imported modules, look in module 'name1' for rule 'name2'.*/RULE *lookup_rule( char *rulename, module_t *m, int local_only ){    RULE rule, *r = &rule, *result = 0;    module_t* original_module = m;    r->name = rulename;    if (m->class_module)        m = m->class_module;    if (m->rules && hashcheck( m->rules, (HASHDATA **)&r ) )        result = r;    else if (!local_only && m->imported_modules) {        /* Try splitting the name into module and rule. */        char *p = strchr(r->name, '.') ;        if (p) {            *p = '\0';            /* Now, r->name keeps the module name, and p+1 keeps the rule name. */            if (hashcheck( m->imported_modules, (HASHDATA **)&r))            {                result = lookup_rule(p+1, bindmodule(rulename), 1);            }            *p = '.';        }            }    if (result)    {        if (local_only && !result->exported)            result = 0;        else        {            /* Lookup started in class module. We've found a rule in class module,               which is marked for execution in that module, or in some instances.               Mark it for execution in the instance where we've started lookup.            */            int execute_in_class = (result->module == m);            int execute_in_some_instance =             (result->module->class_module && result->module->class_module == m);            if (original_module != m && (execute_in_class || execute_in_some_instance))                result->module = original_module;                    }    }    return result;        }RULE *bindrule( char *rulename, module_t* m){    RULE *result;    result = lookup_rule(rulename, m, 0);    if (!result)        result = lookup_rule(rulename, root_module(), 0);    /* We've only one caller, 'evaluate_rule', which will complain about        calling underfined rule. We could issue the error       here, but we don't have necessary information, such as frame.    */    if (!result)        result = enter_rule( rulename, m );    return result;}RULE* import_rule( RULE* source, module_t* m, char* name ){    RULE* dest = define_rule( source->module, name, m );    set_rule_body( dest, source->arguments, source->procedure );    set_rule_actions( dest, source->actions );    return dest;}

⌨️ 快捷键说明

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