# include "jam.h"
# include "lists.h"
# include "parse.h"
# include "variable.h"
# include "rules.h"
# include "newstr.h"
# include "hash.h"
# include <assert.h>
static struct hash *rulehash = 0;
static struct hash *targethash = 0;
RULE *
bindrule( rulename )
char *rulename;
{
RULE rule, *r = &rule;
if( !rulehash )
rulehash = hashinit( sizeof( RULE ), "rules" );
r->name = rulename;
if( hashenter( rulehash, (HASHDATA **)&r ) )
{
r->name = newstr( rulename );
r->procedure = (PARSE *)0;
r->actions = (char *)0;
r->bindlist = L0;
r->flags = 0;
}
assert (r != &rule);
return r;
}
TARGET *
bindtarget( targetname )
char *targetname;
{
TARGET target, *t = ⌖
if( !targethash )
targethash = hashinit( sizeof( TARGET ), "targets" );
t->name = targetname;
if( hashenter( targethash, (HASHDATA **)&t ) )
{
memset( (char *)t, '\0', sizeof( *t ) );
t->name = newstr( targetname );
t->boundname = t->name;
}
assert (t != &target);
return t;
}
void
touchtarget( t )
char *t;
{
bindtarget( t )->flags |= T_FLAG_TOUCHED;
}
TARGETS *
targetlist( chain, targets )
TARGETS *chain;
LIST *targets;
{
for( ; targets; targets = list_next( targets ) )
chain = targetentry( chain, bindtarget( targets->string ) );
return chain;
}
TARGETS *
targetentry( chain, target )
TARGETS *chain;
TARGET *target;
{
TARGETS *c;
c = (TARGETS *)malloc( sizeof( TARGETS ) );
c->target = target;
if( !chain ) chain = c;
else chain->tail->next = c;
chain->tail = c;
c->next = 0;
return chain;
}
ACTIONS *
actionlist( chain, action )
ACTIONS *chain;
ACTION *action;
{
ACTIONS *actions = (ACTIONS *)malloc( sizeof( ACTIONS ) );
actions->action = action;
if( !chain ) chain = actions;
else chain->tail->next = actions;
chain->tail = actions;
actions->next = 0;
return chain;
}
SETTINGS *
addsettings( head, append, symbol, value )
SETTINGS *head;
int append;
char *symbol;
LIST *value;
{
SETTINGS *v;
for( v = head; v; v = v->next )
if( !strcmp( v->symbol, symbol ) )
break;
if( !v )
{
v = (SETTINGS *)malloc( sizeof( *v ) );
v->symbol = newstr( symbol );
v->value = value;
v->next = head;
head = v;
}
else if( append )
{
v->value = list_append( v->value, value );
}
else
{
list_free( v->value );
v->value = value;
}
return head;
}
void
pushsettings( v )
SETTINGS *v;
{
for( ; v; v = v->next )
v->value = var_swap( v->symbol, v->value );
}
void
popsettings( v )
SETTINGS *v;
{
pushsettings( v );
}
void
freesettings( v )
SETTINGS *v;
{
while( v )
{
SETTINGS *n = v->next;
freestr( v->symbol );
list_free( v->value );
free( (char *)v );
v = n;
}
}
void
donerules()
{
hashdone( rulehash );
hashdone( targethash );
}