patch-2.3.19 linux/scripts/tkparse.c

Next file: linux/scripts/tkparse.h
Previous file: linux/scripts/tkgen.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.18/linux/scripts/tkparse.c linux/scripts/tkparse.c
@@ -29,6 +29,17 @@
  * 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net>
  * - Remove bug-compatible code.
  *
+ * 07 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl>
+ * - Submenus implemented,
+ * - plenty of option updating/displaying fixes,
+ * - dep_bool, define_hex, define_int, define_string, define_tristate and
+ *   undef implemented,
+ * - dep_tristate fixed to support multiple dependencies,
+ * - handling of variables with an empty value implemented,
+ * - value checking for int and hex fields,
+ * - more checking during condition parsing; choice variables are treated as
+ *   all others now,
+ *
  * TO DO:
  * - xconfig is at the end of its life cycle.  Contact <mec@shout.net> if
  *   you are interested in working on the replacement.
@@ -51,8 +62,6 @@
 int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); }
 #define strcmp my_strcmp
 
-
-
 /*
  * Report a syntax error.
  */
@@ -65,6 +74,30 @@
 
 
 /*
+ * Find index of a specyfic variable in the symbol table.
+ * Create a new entry if it does not exist yet.
+ */
+#define VARTABLE_SIZE 2048
+struct variable vartable[VARTABLE_SIZE];
+int max_varnum = 0;
+
+int get_varnum( char * name )
+{
+    int i;
+    
+    for ( i = 1; i <= max_varnum; i++ )
+	if ( strcmp( vartable[i].name, name ) == 0 )
+	    return i;
+    if (max_varnum > VARTABLE_SIZE-1)
+	syntax_error( "Too many variables defined." );
+    vartable[++max_varnum].name = malloc( strlen( name )+1 );
+    strcpy( vartable[max_varnum].name, name );
+    return max_varnum;
+}
+
+
+
+/*
  * Get a string.
  */
 static const char * get_string( const char * pnt, char ** label )
@@ -138,6 +171,7 @@
 }
 
 
+
 /*
  * Tokenize an 'if' statement condition.
  */
@@ -145,6 +179,7 @@
 {
     struct condition * list;
     struct condition * last;
+    struct condition * prev;
 
     /* eat the open bracket */
     while ( *pnt == ' ' || *pnt == '\t' )
@@ -170,30 +205,53 @@
 	cond = malloc( sizeof(*cond) );
 	memset( cond, 0, sizeof(*cond) );
 	if ( last == NULL )
-	    { list = last = cond; }
+	    { list = last = cond; prev = NULL; }
 	else
-	    { last->next = cond; last = cond; }
+	    { prev = last; last->next = cond; last = cond; }
 
 	/* determine the token value */
 	if ( *pnt == '-' && pnt[1] == 'a' )
-	    { cond->op = op_and;  pnt += 2; continue; }
+	{
+	    if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+		syntax_error( "incorrect argument" );
+	    cond->op = op_and;  pnt += 2; continue;
+	}
 
 	if ( *pnt == '-' && pnt[1] == 'o' )
-	    { cond->op = op_or;   pnt += 2; continue; }
+	{
+	    if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+		syntax_error( "incorrect argument" );
+	    cond->op = op_or;   pnt += 2; continue;
+	}
 
 	if ( *pnt == '!' && pnt[1] == '=' )
-	    { cond->op = op_neq;  pnt += 2; continue; }
+	{
+	    if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+		syntax_error( "incorrect argument" );
+	    cond->op = op_neq;  pnt += 2; continue;
+	}
 
 	if ( *pnt == '=' )
-	    { cond->op = op_eq;   pnt += 1; continue; }
+	{
+	    if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) )
+		syntax_error( "incorrect argument" );
+	    cond->op = op_eq;   pnt += 1; continue;
+	}
 
 	if ( *pnt == '!' )
-	    { cond->op = op_bang; pnt += 1; continue; }
+	{
+	    if ( prev && ( prev->op != op_and && prev->op != op_or
+		      && prev->op != op_bang ) )
+		syntax_error( "incorrect argument" );
+	    cond->op = op_bang; pnt += 1; continue;
+	}
 
 	if ( *pnt == '"' )
 	{
 	    const char * word;
 
+	    if ( prev && ( prev->op == op_variable || prev->op == op_constant ) )
+		syntax_error( "incorrect argument" );
 	    /* advance to the word */
 	    pnt++;
 	    if ( *pnt == '$' )
@@ -217,7 +275,15 @@
 		char * str = malloc( pnt - word + 1 );
 		memcpy( str, word, pnt - word );
 		str [pnt - word] = '\0';
-		cond->str = str;
+		if ( cond->op == op_variable )
+		{
+		    cond->nameindex = get_varnum( str );
+		    free( str );
+		}
+		else /* op_constant */
+		{
+		    cond->str = str;
+		}
 	    }
 
 	    pnt++;
@@ -241,6 +307,7 @@
     for ( ; ; )
     {
 	struct kconfig * cfg;
+	char * buffer = malloc( 64 );
 
 	/* skip whitespace */
 	while ( *pnt == ' ' || *pnt == '\t' )
@@ -262,7 +329,8 @@
 	pnt = get_string( pnt, &cfg->label );
 	while ( *pnt == ' ' || *pnt == '\t' )
 	    pnt++;
-	pnt = get_string( pnt, &cfg->optionname );
+	pnt = get_string( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
     }
 
     return pnt;
@@ -270,8 +338,6 @@
 
 
 
-
-
 /*
  * Tokenize one line.
  */
@@ -280,6 +346,8 @@
     static struct kconfig * last_menuoption = NULL;
     enum e_token token;
     struct kconfig * cfg;
+    struct dependency ** dep_ptr;
+    char * buffer = malloc( 64 );
 
     /* skip white space */
     while ( *pnt == ' ' || *pnt == '\t' )
@@ -313,6 +381,11 @@
 
     case 'd':
 	match_token( token_define_bool, "define_bool" );
+	match_token( token_define_hex, "define_hex" );
+	match_token( token_define_int, "define_int" );
+	match_token( token_define_string, "define_string" );
+	match_token( token_define_tristate, "define_tristate" );
+	match_token( token_dep_bool, "dep_bool" );
 	match_token( token_dep_tristate, "dep_tristate" );
 	break;
 
@@ -371,11 +444,13 @@
 	syntax_error( "bogus 'then'" );
     }
 
+#if 0
     if ( token == token_unset )
     {
 	fprintf( stderr, "Ignoring 'unset' command\n" );
 	return;
     }
+#endif
 
     if ( token == token_UNKNOWN )
 	syntax_error( "unknown command" );
@@ -404,8 +479,9 @@
 
     case token_bool:
     case token_tristate:
-	pnt = get_qstring ( pnt, &cfg->label      );
-	pnt = get_string  ( pnt, &cfg->optionname );
+	pnt = get_qstring ( pnt, &cfg->label );
+	pnt = get_string  ( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
 	break;
 
     case token_choice_header:
@@ -417,9 +493,7 @@
 	    pnt = get_qstring ( pnt, &choice_list );
 	    pnt = get_string  ( pnt, &cfg->value  );
 
-	    cfg->optionname = malloc( 32 );
-	    sprintf( cfg->optionname, "tmpvar_%d", choose_number++ );
-
+	    cfg->nameindex = -(choose_number++);
 	    tokenize_choices( cfg, choice_list );
 	    free( choice_list );
 	}
@@ -436,56 +510,133 @@
 	break;
 
     case token_define_bool:
-	pnt = get_string( pnt, &cfg->optionname );
+    case token_define_tristate:
+	pnt = get_string( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
 	while ( *pnt == ' ' || *pnt == '\t' )
 	    pnt++;
-	if      ( *pnt == 'n' || *pnt == 'N' ) cfg->value = "0";
-	else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = "1";
-	else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = "2";
+	if ( ( pnt[0] == 'Y'  || pnt[0] == 'M' || pnt[0] == 'N'
+	||     pnt[0] == 'y'  || pnt[0] == 'm' || pnt[0] == 'n' )
+	&&   ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
+	{
+	    if      ( *pnt == 'n' || *pnt == 'N' ) cfg->value = strdup( "CONSTANT_N" );
+	    else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = strdup( "CONSTANT_Y" );
+	    else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = strdup( "CONSTANT_M" );
+	}
+	else if ( *pnt == '$' )
+	{
+	    pnt++;
+	    pnt = get_string( pnt, &cfg->value );
+	}
 	else
 	{
 	    syntax_error( "unknown define_bool value" );
 	}
+	get_varnum( cfg->value );
+	break;
+
+    case token_define_hex:
+    case token_define_int:
+	pnt = get_string( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
+	pnt = get_string( pnt, &cfg->value );
 	break;
 
+    case token_define_string:
+	pnt = get_string( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
+	pnt = get_qstring( pnt, &cfg->value );
+	break;
+
+    case token_dep_bool:
     case token_dep_tristate:
-	pnt = get_qstring ( pnt, &cfg->label      );
-	pnt = get_string  ( pnt, &cfg->optionname );
+	pnt = get_qstring ( pnt, &cfg->label );
+	pnt = get_string  ( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
 
 	while ( *pnt == ' ' || *pnt == '\t' )
 	    pnt++;
 
-	if ( ( pnt[0] == 'Y'  || pnt[0] == 'M' || pnt[0] == 'N'
-	||     pnt[0] == 'y'  || pnt[0] == 'm' || pnt[0] == 'n'  )
-	&&   ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
-	{
-	    /* dep_tristate 'foo' CONFIG_FOO m */
-	    if      ( pnt[0] == 'Y' || pnt[0] == 'y' )
-		cfg->depend = strdup( "CONSTANT_Y" );
-	    else if ( pnt[0] == 'M' || pnt[0] == 'm' )
-		cfg->depend = strdup( "CONSTANT_M" );
+	dep_ptr = &(cfg->depend);
+
+	do {
+	    *dep_ptr = (struct dependency *) malloc( sizeof( struct dependency ) );
+	    (*dep_ptr)->next = NULL;
+
+	    if ( ( pnt[0] == 'Y'  || pnt[0] == 'M' || pnt[0] == 'N'
+	    ||     pnt[0] == 'y'  || pnt[0] == 'm' || pnt[0] == 'n' )
+	    &&   ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) )
+	    {
+		/* dep_tristate 'foo' CONFIG_FOO m */
+		if      ( pnt[0] == 'Y' || pnt[0] == 'y' )
+		    (*dep_ptr)->name = strdup( "CONSTANT_Y" );
+		else if ( pnt[0] == 'N' || pnt[0] == 'n' )
+		    (*dep_ptr)->name = strdup( "CONSTANT_N" );
+		else
+		    (*dep_ptr)->name = strdup( "CONSTANT_M" );
+		pnt++;
+		get_varnum( (*dep_ptr)->name );
+	    }
+	    else if ( *pnt == '$' )
+	    {
+		pnt++;
+		pnt = get_string( pnt, &(*dep_ptr)->name );
+		get_varnum( (*dep_ptr)->name );
+	    }
 	    else
-		cfg->depend = strdup( "CONSTANT_N" );
-	    pnt++;
-	}
-	else if ( *pnt == '$' )
-	{
-	    pnt++;
-	    pnt = get_string( pnt, &cfg->depend );
-	}
-	else
-	{
-	    syntax_error( "can't handle dep_tristate condition" );
-	}
+	    {
+		syntax_error( "can't handle dep_bool/dep_tristate condition" );
+	    }
+	    dep_ptr = &(*dep_ptr)->next;
+	    while ( *pnt == ' ' || *pnt == '\t' )
+		pnt++;
+	} while ( *pnt );
 
 	/*
-	 * Create a conditional for this object's dependency.
+	 * Create a conditional for this object's dependencies.
 	 */
 	{
 	    char fake_if [1024];
-	    sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" ]; then",
-		cfg->depend, cfg->depend );
-	    cfg->cond = tokenize_if( fake_if );
+	    struct dependency * dep;
+	    struct condition ** cond_ptr;
+	    int first = 1;
+
+	    cond_ptr = &(cfg->cond);
+	    for ( dep = cfg->depend; dep; dep = dep->next )
+	    {
+		if ( token == token_dep_tristate
+		&& ! strcmp( dep->name, "CONSTANT_M" ) )
+		{
+		    continue;
+		}
+		if ( first )
+		{
+		    first = 0;
+		}
+		else
+		{
+		    *cond_ptr = malloc( sizeof(struct condition) );
+		    memset( *cond_ptr, 0, sizeof(struct condition) );
+		    (*cond_ptr)->op = op_and;
+		    cond_ptr = &(*cond_ptr)->next;
+		}
+		*cond_ptr = malloc( sizeof(struct condition) );
+		memset( *cond_ptr, 0, sizeof(struct condition) );
+		(*cond_ptr)->op = op_lparen;
+		if ( token == token_dep_tristate )
+		    sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then",
+			dep->name, dep->name, dep->name );
+		else
+		    sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then",
+			dep->name, dep->name );
+		(*cond_ptr)->next = tokenize_if( fake_if );
+		while ( *cond_ptr )
+		    cond_ptr = &(*cond_ptr)->next;
+		*cond_ptr = malloc( sizeof(struct condition) );
+		memset( *cond_ptr, 0, sizeof(struct condition) );
+		(*cond_ptr)->op = op_rparen;
+		cond_ptr = &(*cond_ptr)->next;
+	    }
 	}
 	break;
 
@@ -496,15 +647,17 @@
 
     case token_hex:
     case token_int:
-	pnt = get_qstring ( pnt, &cfg->label      );
-	pnt = get_string  ( pnt, &cfg->optionname );
-	pnt = get_string  ( pnt, &cfg->value      );
+	pnt = get_qstring ( pnt, &cfg->label );
+	pnt = get_string  ( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
+	pnt = get_string  ( pnt, &cfg->value );
 	break;
 
     case token_string:
-	pnt = get_qstring ( pnt, &cfg->label      );
-	pnt = get_string  ( pnt, &cfg->optionname );
-	pnt = get_qstring  ( pnt, &cfg->value      );
+	pnt = get_qstring ( pnt, &cfg->label );
+	pnt = get_string  ( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
+	pnt = get_qstring  ( pnt, &cfg->value );
 	break;
 
     case token_if:
@@ -521,8 +674,25 @@
 	else
 	    pnt = get_qstring( pnt, &cfg->label );
 	break;
-    }
 
+    case token_unset:
+	pnt = get_string( pnt, &buffer );
+	cfg->nameindex = get_varnum( buffer );
+	while ( *pnt == ' ' || *pnt == '\t' )
+	    pnt++;
+	while (*pnt)
+	{
+	    cfg->next = (struct kconfig *) malloc( sizeof(struct kconfig) );
+	    memset( cfg->next, 0, sizeof(struct kconfig) );
+	    cfg = cfg->next;
+	    cfg->token = token_unset;
+	    pnt = get_string( pnt, &buffer );
+	    cfg->nameindex = get_varnum( buffer );
+	    while ( *pnt == ' ' || *pnt == '\t' )
+		pnt++;
+	}
+	break;
+    }
     return;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)