patch-2.2.0-pre9 linux/scripts/tkcond.c
Next file: linux/scripts/tkgen.c
Previous file: linux/net/sunrpc/xprt.c
Back to the patch index
Back to the overall index
- Lines: 831
- Date:
Wed Jan 20 10:05:49 1999
- Orig file:
v2.2.0-pre8/linux/scripts/tkcond.c
- Orig date:
Mon Jan 4 15:08:18 1999
diff -u --recursive --new-file v2.2.0-pre8/linux/scripts/tkcond.c linux/scripts/tkcond.c
@@ -1,544 +1,359 @@
-/* parser config.in
- *
- * Version 1.0
- * Eric Youngdale
- * 10/95
- *
- * The general idea here is that we want to parse a config.in file and
- * from this, we generate a wish script which gives us effectively the
- * same functionality that the original config.in script provided.
- *
- * This task is split roughly into 3 parts. The first parse is the parse
- * of the input file itself. The second part is where we analyze the
- * #ifdef clauses, and attach a linked list of tokens to each of the
- * menu items. In this way, each menu item has a complete list of
- * dependencies that are used to enable/disable the options.
- * The third part is to take the configuration database we have build,
- * and build the actual wish script.
- *
- * This file contains the code to further process the conditions from
- * the "ifdef" clauses.
+/*
+ * tkcond.c
*
- * The conditions are assumed to be one of the following formats
+ * Eric Youngdale was the original author of xconfig.
+ * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.
*
- * simple_condition:= "$VARIABLE" == y/n/m
- * simple_condition:= "$VARIABLE != y/n/m
+ * This file takes the tokenized statement list and transforms 'if ...'
+ * statements. For each simple statement, I find all of the 'if' statements
+ * that enclose it, and attach the aggregate conditionals of those 'if'
+ * statements to the cond list of the simple statement.
*
- * simple_condition -a simple_condition
+ * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
+ * - Steam-clean this file. I tested this by generating kconfig.tk for
+ * every architecture and comparing it character-for-character against
+ * the output of the old tkparse.
*
- * If the input condition contains '(' or ')' it would screw us up, but for now
- * this is not a problem.
+ * TO DO:
+ * - xconfig is at the end of its life cycle. Contact <mec@shout.net> if
+ * you are interested in working on the replacement.
*/
-#include <stdlib.h>
+
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include "tkparse.h"
-
-
-/*
- * Walk a condition chain and invert it so that the logical result is
- * inverted.
- */
-static void invert_condition(struct condition * cnd)
-{
- /*
- * This is simple. Just walk through the list, and invert
- * all of the operators.
- */
- for(;cnd; cnd = cnd->next)
- {
- switch(cnd->op)
- {
- case op_and:
- cnd->op = op_or;
- break;
- case op_or:
- /*
- * This is not turned into op_and - we need to keep track
- * of what operators were used here since we have an optimization
- * later on to remove duplicate conditions, and having
- * inverted ors in there would make it harder if we did not
- * distinguish an inverted or from an and we inserted because
- * of nested ifs.
- */
- cnd->op = op_and1;
- break;
- case op_neq:
- cnd->op = op_eq;
- break;
- case op_eq:
- cnd->op = op_neq;
- break;
- default:
- break;
- }
- }
-}
-/*
- * Walk a condition chain, and free the memory associated with it.
- */
-static void free_condition(struct condition * cnd)
-{
- struct condition * next;
- for(;cnd; cnd = next)
- {
- next = cnd->next;
+#include "tkparse.h"
- if( cnd->variable.str != NULL )
- free(cnd->variable.str);
- free(cnd);
- }
-}
/*
- * Walk all of the conditions, and look for choice values. Convert
- * the tokens into something more digestible.
+ * Transform op_variable to op_kvariable.
+ *
+ * This works, but it's gross, speed-wise. It would benefit greatly
+ * from a simple hash table that maps names to cfg.
+ *
+ * Note well: this is actually better than the loop structure xconfig
+ * has been staggering along with for three years, which performs
+ * this whole procedure inside *another* loop on active conditionals.
*/
-void fix_choice_cond(void)
+void transform_to_kvariable( struct kconfig * scfg )
{
- struct condition * cond;
- struct condition * cond2;
- struct kconfig * cfg;
- char tmpbuf[255];
+ struct kconfig * cfg;
- for(cfg = config;cfg != NULL; cfg = cfg->next)
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
{
- if( cfg->cond == NULL )
- {
- continue;
- }
+ struct condition * cond;
- for(cond = cfg->cond; cond != NULL; cond = cond->next)
+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )
{
- if( cond->op != op_kvariable )
- continue;
-
- if( cond->variable.cfg->tok != tok_choice )
- continue;
-
- /*
- * Look ahead for what we are comparing this to. There should
- * be one operator in between.
- */
- cond2 = cond->next->next;
- strcpy(tmpbuf, cond->variable.cfg->label);
-
- if( strcmp(cond2->variable.str, "y") == 0 )
+ if ( cond->op == op_variable )
{
- cond->variable.cfg = cond->variable.cfg->choice_label;
- cond2->variable.str = strdup(tmpbuf);
+ /* Here's where it gets DISGUSTING. */
+ struct kconfig * cfg1;
+
+ for ( cfg1 = scfg; cfg1 != NULL; cfg1 = cfg1->next )
+ {
+ if ( cfg1->token == token_bool
+ || cfg1->token == token_choice_item
+ || cfg1->token == token_dep_tristate
+ || cfg1->token == token_hex
+ || cfg1->token == token_int
+ || cfg1->token == token_string
+ || cfg1->token == token_tristate )
+ {
+ if ( strcmp( cond->str, cfg1->optionname ) == 0 )
+ {
+ cond->op = op_kvariable;
+ cond->str = NULL;
+ cond->cfg = cfg1;
+ break;
+ }
+ }
+ }
}
- else
+
+#if 0
+ /*
+ * Maybe someday this will be useful, but right now it
+ * gives a lot of false positives on files like
+ * drivers/video/Config.in that are meant for more
+ * than one architecture. Turn it on if you want to play
+ * with it though; it does work. -- mec
+ */
+ if ( cond->op == op_variable )
{
- fprintf(stderr,"tkparse can't handle this conditional\n");
- exit(1);
+ if ( strcmp( cond->str, "ARCH" ) != 0
+ && strcmp( cond->str, "CONSTANT_Y" ) != 0
+ && strcmp( cond->str, "CONSTANT_M" ) != 0
+ && strcmp( cond->str, "CONSTANT_N" ) != 0 )
+ {
+ fprintf( stderr, "warning: $%s used but not defined\n",
+ cond->str );
+ }
}
+#endif
}
-
}
}
+
+
/*
- * Walk the stack of conditions, and clone all of them with "&&" operators
- * gluing them together. The conditions from each level of the stack
- * are wrapped in parenthesis so as to guarantee that the results
- * are logically correct.
+ * Make a new condition chain by joining the current condition stack with
+ * the "&&" operator for glue.
*/
-struct condition * get_token_cond(struct condition ** cond, int depth)
+struct condition * join_condition_stack( struct condition * conditions [],
+ int depth )
{
- int i;
- struct condition * newcond;
- struct condition * tail;
- struct condition * new;
- struct condition * ocond;
- struct kconfig * cfg;
+ struct condition * cond_list;
+ struct condition * cond_last;
+ int i;
- newcond = tail = NULL;
- for(i=0; i<depth; i++, cond++)
+ cond_list = cond_last = NULL;
+ for ( i = 0; i < depth; i++ )
{
- /*
- * First insert the left parenthesis
- */
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_lparen;
- if( tail == NULL )
- {
- newcond = tail = new;
- }
- else
- {
- tail->next = new;
- tail = new;
+ struct condition * cond;
+ struct condition * cnew;
+
+ /* add a '(' */
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_lparen;
+ if ( cond_last == NULL )
+ { cond_list = cond_last = cnew; }
+ else
+ { cond_last->next = cnew; cond_last = cnew; }
+
+ /* duplicate the chain */
+ for ( cond = conditions [i]; cond != NULL; cond = cond->next )
+ {
+ cnew = malloc( sizeof(*cnew) );
+ cnew->next = NULL;
+ cnew->op = cond->op;
+ cnew->str = cond->str ? strdup( cond->str ) : NULL;
+ cnew->cfg = cond->cfg;
+ cond_last->next = cnew;
+ cond_last = cnew;
+ }
+
+ /* add a ')' */
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_rparen;
+ cond_last->next = cnew;
+ cond_last = cnew;
+
+ /* if i have another condition, add an '&&' operator */
+ if ( i < depth - 1 )
+ {
+ cnew = malloc( sizeof(*cnew) );
+ memset( cnew, 0, sizeof(*cnew) );
+ cnew->op = op_and;
+ cond_last->next = cnew;
+ cond_last = cnew;
}
+ }
- /*
- * Now duplicate the chain.
- */
- ocond = *cond;
- for(;ocond != NULL; ocond = ocond->next)
+ /*
+ * Remove duplicate conditions.
+ */
+ {
+ struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f;
+
+ for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next )
{
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = ocond->op;
- if( ocond->variable.str != NULL )
+ if ( cond1->op == op_lparen )
{
- if( ocond->op == op_variable )
+ cond1b = cond1 ->next; if ( cond1b == NULL ) break;
+ cond1c = cond1b->next; if ( cond1c == NULL ) break;
+ cond1d = cond1c->next; if ( cond1d == NULL ) break;
+ cond1e = cond1d->next; if ( cond1e == NULL ) break;
+ cond1f = cond1e->next; if ( cond1f == NULL ) break;
+
+ if ( cond1b->op == op_kvariable
+ && ( cond1c->op == op_eq || cond1c->op == op_neq )
+ && cond1d->op == op_constant
+ && cond1e->op == op_rparen )
{
- /*
- * Search for structure to insert here.
- */
- for(cfg = config;cfg != NULL; cfg = cfg->next)
+ struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f;
+
+ for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next )
{
- if( cfg->tok != tok_bool
- && cfg->tok != tok_int
- && cfg->tok != tok_hex
- && cfg->tok != tok_string
- && cfg->tok != tok_tristate
- && cfg->tok != tok_choice
- && cfg->tok != tok_dep_tristate)
+ if ( cond2->op == op_lparen )
{
- continue;
+ cond2b = cond2 ->next; if ( cond2b == NULL ) break;
+ cond2c = cond2b->next; if ( cond2c == NULL ) break;
+ cond2d = cond2c->next; if ( cond2d == NULL ) break;
+ cond2e = cond2d->next; if ( cond2e == NULL ) break;
+ cond2f = cond2e->next;
+
+ /* look for match */
+ if ( cond2b->op == op_kvariable
+ && cond2b->cfg == cond1b->cfg
+ && cond2c->op == cond1c->op
+ && cond2d->op == op_constant
+ && strcmp( cond2d->str, cond1d->str ) == 0
+ && cond2e->op == op_rparen )
+ {
+ /* one of these must be followed by && */
+ if ( cond1f->op == op_and
+ || ( cond2f != NULL && cond2f->op == op_and ) )
+ {
+ /* nuke the first duplicate */
+ cond1 ->op = op_nuked;
+ cond1b->op = op_nuked;
+ cond1c->op = op_nuked;
+ cond1d->op = op_nuked;
+ cond1e->op = op_nuked;
+ if ( cond1f->op == op_and )
+ cond1f->op = op_nuked;
+ else
+ cond2f->op = op_nuked;
+ }
+ }
}
- if( strcmp(cfg->optionname, ocond->variable.str) == 0)
- {
- new->variable.cfg = cfg;
- new->op = op_kvariable;
- break;
- }
- }
- if( cfg == NULL )
- {
- new->variable.str = strdup(ocond->variable.str);
}
}
- else
- {
- new->variable.str = strdup(ocond->variable.str);
- }
}
- tail->next = new;
- tail = new;
}
-
- /*
- * Next insert the left parenthesis
- */
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_rparen;
- tail->next = new;
- tail = new;
-
- /*
- * Insert an and operator, if we have another condition.
- */
- if( i < depth - 1 )
- {
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_and;
- tail->next = new;
- tail = new;
- }
-
}
- return newcond;
+ return cond_list;
}
-/*
- * Walk a single chain of conditions and clone it. These are assumed
- * to be created/processed by get_token_cond in a previous pass.
- */
-struct condition * get_token_cond_frag(struct condition * cond,
- struct condition ** last)
-{
- struct condition * newcond;
- struct condition * tail;
- struct condition * new;
- struct condition * ocond;
-
- newcond = tail = NULL;
-
- /*
- * Now duplicate the chain.
- */
- for(ocond = cond;ocond != NULL; ocond = ocond->next)
- {
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = ocond->op;
- new->variable.cfg = ocond->variable.cfg;
- if( tail == NULL )
- {
- newcond = tail = new;
- }
- else
- {
- tail->next = new;
- tail = new;
- }
- }
- new = (struct condition *) malloc(sizeof(struct condition));
- memset(new, 0, sizeof(*new));
- new->op = op_and;
- tail->next = new;
- tail = new;
-
- *last = tail;
- return newcond;
-}
/*
- * Walk through the if conditionals and maintain a chain.
+ * This is the main transformation function.
*/
-void fix_conditionals(struct kconfig * scfg)
+void fix_conditionals( struct kconfig * scfg )
{
- int depth = 0;
- int i;
- struct kconfig * cfg;
- struct kconfig * cfg1;
- struct condition * conditions[25];
- struct condition * cnd;
- struct condition * cnd1;
- struct condition * cnd2;
- struct condition * cnd3;
- struct condition * newcond;
- struct condition * last;
-
- /*
- * Start by walking the chain. Every time we see an ifdef, push
- * the condition chain on the stack. When we see an "else", we invert
- * the condition at the top of the stack, and when we see an "endif"
- * we free all of the memory for the condition at the top of the stack
- * and remove the condition from the top of the stack.
- *
- * For any other type of token (i.e. a bool), we clone a new condition chain
- * by anding together all of the conditions that are currently stored on
- * the stack. In this way, we have a correct representation of whatever
- * conditions govern the usage of each option.
- */
- memset(conditions, 0, sizeof(conditions));
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
- {
- switch(cfg->tok)
- {
- case tok_if:
- /*
- * Push this condition on the stack, and nuke the token
- * representing the ifdef, since we no longer need it.
- */
- conditions[depth] = cfg->cond;
- depth++;
- cfg->tok = tok_nop;
- cfg->cond = NULL;
- break;
- case tok_else:
- /*
- * For an else, we just invert the condition at the top of
- * the stack. This is done in place with no reallocation
- * of memory taking place.
- */
- invert_condition(conditions[depth-1]);
- cfg->tok = tok_nop;
- break;
- case tok_fi:
- depth--;
- free_condition(conditions[depth]);
- conditions[depth] = NULL;
- cfg->tok = tok_nop;
- break;
- case tok_comment:
- case tok_define:
- case tok_menuoption:
- case tok_bool:
- case tok_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- case tok_choice:
- /*
- * We need to duplicate the chain of conditions and attach them to
- * this token.
- */
- cfg->cond = get_token_cond(&conditions[0], depth);
- break;
- case tok_dep_tristate:
- /*
- * Same as tok_tristate et al except we have a temporary
- * conditional. (Sort of a hybrid tok_if, tok_tristate, tok_fi
- * option)
- */
- conditions[depth] = cfg->cond;
- depth++;
- cfg->cond = get_token_cond(&conditions[0], depth);
- depth--;
- free_condition(conditions[depth]);
- conditions[depth] = NULL;
- default:
- break;
- }
- }
+ struct kconfig * cfg;
- /*
- * Fix any conditions involving the "choice" operator.
- */
- fix_choice_cond();
-
- /*
- * Walk through and see if there are multiple options that control the
- * same kvariable. If there are we need to treat them a little bit
- * special.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
+ /*
+ * Transform op_variable to op_kvariable.
+ */
+ transform_to_kvariable( scfg );
+
+ /*
+ * Transform conditions that use variables from "choice" statements.
+ * Choice values appear to the user as a collection of booleans, and the
+ * script can test the individual booleans. But internally, all I have is
+ * the N-way value of an unnamed temporary for the whole statement. So I
+ * have to tranform '"$CONFIG_M386" != "y"'
+ * into '"$tmpvar_N" != "CONFIG_M386"'.
+ */
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
{
- switch(cfg->tok)
+ struct condition * cond;
+
+ for ( cond = cfg->cond; cond != NULL; cond = cond->next )
{
- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- for(cfg1=cfg;cfg1 != NULL; cfg1 = cfg1->next)
+ if ( cond->op == op_kvariable && cond->cfg->token == token_choice_item )
{
- switch(cfg1->tok)
+ /*
+ * Look two more tokens down for the comparison token.
+ * It has to be "y" for this trick to work.
+ *
+ * If you get this error, don't even think about relaxing the
+ * strcmp test. You will produce incorrect TK code. Instead,
+ * look for the place in your Config.in script where you are
+ * comparing a 'choice' variable to a value other than 'y',
+ * and rewrite the comparison to be '= "y"' or '!= "y"'.
+ */
+ struct condition * cond2 = cond->next->next;
+ const char * label;
+
+ if ( strcmp( cond2->str, "y" ) != 0 )
{
- case tok_define:
- case tok_bool:
- case tok_tristate:
- case tok_dep_tristate:
- case tok_int:
- case tok_hex:
- case tok_string:
- if( strcmp(cfg->optionname, cfg1->optionname) == 0)
- {
- cfg->flags |= CFG_DUP;
- cfg1->flags |= CFG_DUP;
- }
- break;
- default:
- break;
+ fprintf( stderr, "tkparse choked in fix_choice_cond\n" );
+ exit( 1 );
}
+
+ label = cond->cfg->label;
+ cond->cfg = cond->cfg->cfg_parent;
+ cond2->str = strdup( label );
}
- break;
- default:
- break;
}
}
- /*
- * Now go through the list, and every time we see a kvariable, check
- * to see whether it also has some dependencies. If so, then
- * append it to our list. The reason we do this is that we might have
- * option CONFIG_FOO which is only used if CONFIG_BAR is set. It may
- * turn out that in config.in that the default value for CONFIG_BAR is
- * set to "y", but that CONFIG_BAR is not enabled because CONFIG_XYZZY
- * is not set. The current condition chain does not reflect this, but
- * we can fix this by searching for the tokens that this option depends
- * upon and cloning the conditions and merging them with the list.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
+ /*
+ * Walk the statement list, maintaining a stack of current conditions.
+ * token_if push its condition onto the stack.
+ * token_else invert the condition on the top of the stack.
+ * token_endif pop the stack.
+ *
+ * For a simple statement, create a condition chain by joining together
+ * all of the conditions on the stack.
+ */
{
- /*
- * Search for a token that has a condition list.
- */
- if(cfg->cond == NULL) continue;
- for(cnd = cfg->cond; cnd; cnd=cnd->next)
- {
- /*
- * Now search the condition list for a known configuration variable
- * that has conditions of its own.
- */
- if(cnd->op != op_kvariable) continue;
- if(cnd->variable.cfg->cond == NULL) continue;
-
- if(cnd->variable.cfg->flags & CFG_DUP) continue;
- /*
- * OK, we have some conditions to append to cfg. Make a clone
- * of the conditions,
- */
- newcond = get_token_cond_frag(cnd->variable.cfg->cond, &last);
-
- /*
- * Finally, we splice it into our list.
- */
- last->next = cfg->cond;
- cfg->cond = newcond;
+ struct condition * cond_stack [32];
+ int depth = 0;
- }
- }
-
- /*
- * There is a strong possibility that we have duplicate conditions
- * in here. It would make the script more efficient and readable to
- * remove these. Here is where we assume here that there are no
- * parenthesis in the input script.
- */
- for(cfg=scfg;cfg != NULL; cfg = cfg->next)
- {
- /*
- * Search for configuration options that have conditions.
- */
- if(cfg->cond == NULL) continue;
- for(cnd = cfg->cond; cnd; cnd=cnd->next)
+ for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
{
- /*
- * Search for a left parenthesis.
- */
- if(cnd->op != op_lparen) continue;
- for(cnd1 = cnd->next; cnd1; cnd1=cnd1->next)
+ switch ( cfg->token )
{
- /*
- * Search after the previous left parenthesis, and try
- * and find a second left parenthesis.
- */
- if(cnd1->op != op_lparen) continue;
-
- /*
- * Now compare the next 5 tokens to see if they are
- * identical. We are looking for two chains that
- * are like: '(' $VARIABLE operator constant ')'.
- */
- cnd2 = cnd;
- cnd3 = cnd1;
- for(i=0; i<5; i++, cnd2=cnd2->next, cnd3=cnd3->next)
- {
- if(!cnd2 || !cnd3) break;
- if(cnd2->op != cnd3->op) break;
- if(i == 1 && (cnd2->op != op_kvariable
- || cnd2->variable.cfg != cnd3->variable.cfg) ) break;
- if(i==2 && cnd2->op != op_eq && cnd2->op != op_neq) break;
- if(i == 3 && cnd2->op != op_constant &&
- strcmp(cnd2->variable.str, cnd3->variable.str) != 0)
- break;
- if(i==4 && cnd2->op != op_rparen) break;
- }
- /*
- * If these match, and there is an and gluing these together,
- * then we can nuke the second one.
- */
- if(i==5 && ((cnd3 && cnd3->op == op_and)
- ||(cnd2 && cnd2->op == op_and)))
+ default:
+ break;
+
+ case token_if:
+ cond_stack [depth++] = cfg->cond;
+ cfg->cond = NULL;
+ break;
+
+ case token_else:
{
- /*
- * We have a duplicate. Nuke 5 ops.
- */
- cnd3 = cnd1;
- for(i=0; i<5; i++, cnd3=cnd3->next)
+ /*
+ * Invert the condition chain.
+ *
+ * Be careful to transfrom op_or to op_and1, not op_and.
+ * I will need this later in the code that removes
+ * duplicate conditions.
+ */
+ struct condition * cond;
+
+ for ( cond = cond_stack [depth-1];
+ cond != NULL;
+ cond = cond->next )
{
- cnd3->op = op_nuked;
+ switch( cond->op )
+ {
+ default: break;
+ case op_and: cond->op = op_or; break;
+ case op_or: cond->op = op_and1; break;
+ case op_neq: cond->op = op_eq; break;
+ case op_eq: cond->op = op_neq; break;
+ }
}
- /*
- * Nuke the and that glues the conditions together.
- */
- if(cnd3 && cnd3->op == op_and) cnd3->op = op_nuked;
- else if(cnd2 && cnd2->op == op_and) cnd2->op = op_nuked;
}
+ break;
+
+ case token_fi:
+ --depth;
+ break;
+
+ case token_bool:
+ case token_choice_item:
+ case token_comment:
+ case token_define_bool:
+ case token_hex:
+ case token_int:
+ case token_mainmenu_option:
+ case token_string:
+ case token_tristate:
+ cfg->cond = join_condition_stack( cond_stack, depth );
+ break;
+
+ case token_dep_tristate:
+ /*
+ * Same as the other simple statements, plus an additional
+ * condition for the dependency.
+ */
+ cond_stack [depth] = cfg->cond;
+ cfg->cond = join_condition_stack( cond_stack, depth+1 );
+ break;
}
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov