diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /scripts/tkparse.c | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'scripts/tkparse.c')
-rw-r--r-- | scripts/tkparse.c | 282 |
1 files changed, 226 insertions, 56 deletions
diff --git a/scripts/tkparse.c b/scripts/tkparse.c index 4b593fd0a..86924a08d 100644 --- a/scripts/tkparse.c +++ b/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 @@ static void do_source( const char * ); 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 @@ static void syntax_error( const char * msg ) /* + * 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 @@ static const char * get_qstring( const char * pnt, char ** label ) } + /* * Tokenize an 'if' statement condition. */ @@ -145,6 +179,7 @@ static struct condition * tokenize_if( const char * pnt ) { struct condition * list; struct condition * last; + struct condition * prev; /* eat the open bracket */ while ( *pnt == ' ' || *pnt == '\t' ) @@ -170,30 +205,53 @@ static struct condition * tokenize_if( const char * pnt ) 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 @@ static struct condition * tokenize_if( const char * pnt ) 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 @@ static const char * tokenize_choices( struct kconfig * cfg_choose, for ( ; ; ) { struct kconfig * cfg; + char * buffer = malloc( 64 ); /* skip whitespace */ while ( *pnt == ' ' || *pnt == '\t' ) @@ -262,7 +329,8 @@ static const char * tokenize_choices( struct kconfig * cfg_choose, 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 @@ static const char * tokenize_choices( struct kconfig * cfg_choose, - - /* * Tokenize one line. */ @@ -280,6 +346,8 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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 @@ static void tokenize_line( const char * pnt ) 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; } |