diff options
| author | Roman Zippel <zippel@linux-m68k.org> | 2002-11-07 00:39:40 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-11-07 00:39:40 -0800 |
| commit | 7f60c550fac20cc1167d5ff597b1e621688e3327 (patch) | |
| tree | 84a5c458ffb0f4affe635ba541e04473487d1839 /scripts/tkparse.c | |
| parent | 4e81d4aa3fc44e5853cc58ae7e391e0f8f0bf754 (diff) | |
[PATCH] remove old config tools
This deletes the old config tools and moves Michael's maintainer entry
for them to CREDITS and I added myself for KCONFIG instead.
Diffstat (limited to 'scripts/tkparse.c')
| -rw-r--r-- | scripts/tkparse.c | 828 |
1 files changed, 0 insertions, 828 deletions
diff --git a/scripts/tkparse.c b/scripts/tkparse.c deleted file mode 100644 index dbede1326f17..000000000000 --- a/scripts/tkparse.c +++ /dev/null @@ -1,828 +0,0 @@ -/* - * tkparse.c - * - * Eric Youngdale was the original author of xconfig. - * Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. - * - * Parse a config.in file and translate it to a wish script. - * This task has three parts: - * - * tkparse.c tokenize the input - * tkcond.c transform 'if ...' statements - * tkgen.c generate output - * - * Change History - * - * 7 January 1999, Michael Elizabeth Chastain, <mec@shout.net> - * - Teach dep_tristate about a few literals, such as: - * dep_tristate 'foo' CONFIG_FOO m - * Also have it print an error message and exit on some parse failures. - * - * 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> - * - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one. - * - * 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. - * - * 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "tkparse.h" - -static struct kconfig * config_list = NULL; -static struct kconfig * config_last = NULL; -static const char * current_file = "<unknown file>"; -static int lineno = 0; - -static void do_source( const char * ); - -#undef strcmp -int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } -#define strcmp my_strcmp - -/* - * Report a syntax error. - */ -static void syntax_error( const char * msg ) -{ - fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); - exit( 1 ); -} - - - -/* - * Find index of a specific variable in the symbol table. - * Create a new entry if it does not exist yet. - */ -struct variable *vartable; -int max_varnum = 0; -static int vartable_size = 0; - -int get_varnum( char * name ) -{ - int i; - - for ( i = 1; i <= max_varnum; i++ ) - if ( strcmp( vartable[i].name, name ) == 0 ) - return i; - while (max_varnum+1 >= vartable_size) { - vartable = realloc(vartable, (vartable_size += 1000)*sizeof(*vartable)); - if (!vartable) { - fprintf(stderr, "tkparse realloc vartable failed\n"); - exit(1); - } - } - 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 ) -{ - const char * word; - - word = pnt; - for ( ; ; ) - { - if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' ) - break; - pnt++; - } - - *label = malloc( pnt - word + 1 ); - memcpy( *label, word, pnt - word ); - (*label)[pnt - word] = '\0'; - - if ( *pnt != '\0' ) - pnt++; - return pnt; -} - - - -/* - * Get a quoted string. - * Insert a '\' before any characters that need quoting. - */ -static const char * get_qstring( const char * pnt, char ** label ) -{ - char quote_char; - char newlabel [2048]; - char * pnt1; - - /* advance to the open quote */ - for ( ; ; ) - { - if ( *pnt == '\0' ) - return pnt; - quote_char = *pnt++; - if ( quote_char == '"' || quote_char == '\'' ) - break; - } - - /* copy into an intermediate buffer */ - pnt1 = newlabel; - for ( ; ; ) - { - if ( *pnt == '\0' ) - syntax_error( "unterminated quoted string" ); - if ( *pnt == quote_char && pnt[-1] != '\\' ) - break; - - /* copy the character, quoting if needed */ - if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' ) - *pnt1++ = '\\'; - *pnt1++ = *pnt++; - } - - /* copy the label into a permanent location */ - *pnt1++ = '\0'; - *label = (char *) malloc( pnt1 - newlabel ); - memcpy( *label, newlabel, pnt1 - newlabel ); - - /* skip over last quote and next whitespace */ - pnt++; - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - return pnt; -} - - - -/* - * Get a quoted or unquoted string. It is recognized by the first - * non-white character. '"' and '"' are not allowed inside the string. - */ -static const char * get_qnqstring( const char * pnt, char ** label ) -{ - char quote_char; - - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - - if ( *pnt == '\0' ) - return pnt; - quote_char = *pnt; - if ( quote_char == '"' || quote_char == '\'' ) - return get_qstring( pnt, label ); - else - return get_string( pnt, label ); -} - - - -/* - * Tokenize an 'if' statement condition. - */ -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' ) - pnt++; - if ( *pnt != '[' ) - syntax_error( "bad 'if' condition" ); - pnt++; - - list = last = NULL; - for ( ; ; ) - { - struct condition * cond; - - /* advance to the next token */ - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - if ( *pnt == '\0' ) - syntax_error( "unterminated 'if' condition" ); - if ( *pnt == ']' ) - return list; - - /* allocate a new token */ - cond = malloc( sizeof(*cond) ); - memset( cond, 0, sizeof(*cond) ); - if ( last == NULL ) - { list = last = cond; prev = NULL; } - else - { prev = last; last->next = cond; last = cond; } - - /* determine the token value */ - if ( *pnt == '-' && pnt[1] == 'a' ) - { - 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' ) - { - 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] == '=' ) - { - if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) - syntax_error( "incorrect argument" ); - cond->op = op_neq; pnt += 2; continue; - } - - if ( *pnt == '=' ) - { - if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) - syntax_error( "incorrect argument" ); - cond->op = op_eq; pnt += 1; continue; - } - - if ( *pnt == '!' ) - { - 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 == '$' ) - { cond->op = op_variable; pnt++; } - else - { cond->op = op_constant; } - - /* find the end of the word */ - word = pnt; - for ( ; ; ) - { - if ( *pnt == '\0' ) - syntax_error( "unterminated double quote" ); - if ( *pnt == '"' ) - break; - pnt++; - } - - /* store a copy of this word */ - { - char * str = malloc( pnt - word + 1 ); - memcpy( str, word, pnt - word ); - str [pnt - word] = '\0'; - if ( cond->op == op_variable ) - { - cond->nameindex = get_varnum( str ); - free( str ); - } - else /* op_constant */ - { - cond->str = str; - } - } - - pnt++; - continue; - } - - /* unknown token */ - syntax_error( "bad if condition" ); - } -} - - - -/* - * Tokenize a choice list. Choices appear as pairs of strings; - * note that I am parsing *inside* the double quotes. Ugh. - */ -static const char * tokenize_choices( struct kconfig * cfg_choose, - const char * pnt ) -{ - int default_checked = 0; - for ( ; ; ) - { - struct kconfig * cfg; - char * buffer = malloc( 64 ); - - /* skip whitespace */ - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - if ( *pnt == '\0' ) - return pnt; - - /* allocate a new kconfig line */ - cfg = malloc( sizeof(*cfg) ); - memset( cfg, 0, sizeof(*cfg) ); - if ( config_last == NULL ) - { config_last = config_list = cfg; } - else - { config_last->next = cfg; config_last = cfg; } - - /* fill out the line */ - cfg->token = token_choice_item; - cfg->cfg_parent = cfg_choose; - pnt = get_string( pnt, &cfg->label ); - if ( ! default_checked && - ! strncmp( cfg->label, cfg_choose->value, strlen( cfg_choose->value ) ) ) - { - default_checked = 1; - free( cfg_choose->value ); - cfg_choose->value = cfg->label; - } - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - pnt = get_string( pnt, &buffer ); - cfg->nameindex = get_varnum( buffer ); - } - if ( ! default_checked ) - syntax_error( "bad 'choice' default value" ); - return pnt; -} - - - -/* - * Tokenize one line. - */ -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' ) - pnt++; - - /* - * categorize the next token - */ - -#define match_token(t, s) \ - if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; } - - token = token_UNKNOWN; - switch ( *pnt ) - { - default: - break; - - case '#': - case '\0': - return; - - case 'b': - match_token( token_bool, "bool" ); - break; - - case 'c': - match_token( token_choice_header, "choice" ); - match_token( token_comment, "comment" ); - break; - - 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_mbool, "dep_mbool" ); - match_token( token_dep_tristate, "dep_tristate" ); - break; - - case 'e': - match_token( token_else, "else" ); - match_token( token_endmenu, "endmenu" ); - break; - - case 'f': - match_token( token_fi, "fi" ); - break; - - case 'h': - match_token( token_hex, "hex" ); - break; - - case 'i': - match_token( token_if, "if" ); - match_token( token_int, "int" ); - break; - - case 'm': - match_token( token_mainmenu_name, "mainmenu_name" ); - match_token( token_mainmenu_option, "mainmenu_option" ); - break; - - case 's': - match_token( token_source, "source" ); - match_token( token_string, "string" ); - break; - - case 't': - match_token( token_then, "then" ); - match_token( token_tristate, "tristate" ); - break; - - case 'u': - match_token( token_unset, "unset" ); - break; - } - -#undef match_token - - if ( token == token_source ) - { - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - do_source( pnt ); - return; - } - - if ( token == token_then ) - { - if ( config_last != NULL && config_last->token == token_if ) - return; - 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" ); - - /* - * Allocate an item. - */ - cfg = malloc( sizeof(*cfg) ); - memset( cfg, 0, sizeof(*cfg) ); - if ( config_last == NULL ) - { config_last = config_list = cfg; } - else - { config_last->next = cfg; config_last = cfg; } - - /* - * Tokenize the arguments. - */ - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - - cfg->token = token; - switch ( token ) - { - default: - syntax_error( "unknown token" ); - - case token_bool: - case token_tristate: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &buffer ); - cfg->nameindex = get_varnum( buffer ); - break; - - case token_choice_header: - { - static int choose_number = 0; - char * choice_list; - - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_qstring ( pnt, &choice_list ); - pnt = get_string ( pnt, &cfg->value ); - cfg->nameindex = -(choose_number++); - tokenize_choices( cfg, choice_list ); - free( choice_list ); - } - break; - - case token_comment: - pnt = get_qstring(pnt, &cfg->label); - if ( last_menuoption != NULL ) - { - pnt = get_qstring(pnt, &cfg->label); - if (cfg->label == NULL) - syntax_error( "missing comment text" ); - last_menuoption->label = cfg->label; - last_menuoption = NULL; - } - break; - - case token_define_bool: - case token_define_tristate: - 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' ) ) - { - 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_qnqstring( pnt, &cfg->value ); - if (cfg->value == NULL) - syntax_error( "missing value" ); - break; - - case token_dep_bool: - case token_dep_mbool: - case token_dep_tristate: - pnt = get_qstring ( pnt, &cfg->label ); - pnt = get_string ( pnt, &buffer ); - cfg->nameindex = get_varnum( buffer ); - - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - - 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 - { - syntax_error( "can't handle dep_bool/dep_mbool/dep_tristate condition" ); - } - dep_ptr = &(*dep_ptr)->next; - while ( *pnt == ' ' || *pnt == '\t' ) - pnt++; - } while ( *pnt ); - - /* - * Create a conditional for this object's dependencies. - */ - { - char fake_if [1024]; - 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_bool ) - sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then", - dep->name, dep->name ); - else - sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then", - dep->name, 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; - - case token_else: - case token_endmenu: - case token_fi: - break; - - case token_hex: - case token_int: - 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, &buffer ); - cfg->nameindex = get_varnum( buffer ); - pnt = get_qnqstring ( pnt, &cfg->value ); - if (cfg->value == NULL) - syntax_error( "missing initial value" ); - break; - - case token_if: - cfg->cond = tokenize_if( pnt ); - break; - - case token_mainmenu_name: - pnt = get_qstring( pnt, &cfg->label ); - break; - - case token_mainmenu_option: - if ( strncmp( pnt, "next_comment", 12 ) == 0 ) - last_menuoption = cfg; - 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; -} - - - -/* - * Implement the "source" command. - */ -static void do_source( const char * filename ) -{ - char buffer [2048]; - FILE * infile; - const char * old_file; - int old_lineno; - int offset; - - /* open the file */ - if ( strcmp( filename, "-" ) == 0 ) - infile = stdin; - else - infile = fopen( filename, "r" ); - - /* if that failed, try ../filename */ - if ( infile == NULL ) - { - sprintf( buffer, "../%s", filename ); - infile = fopen( buffer, "r" ); - } - - if ( infile == NULL ) - { - sprintf( buffer, "unable to open %s", filename ); - syntax_error( buffer ); - } - - /* push the new file name and line number */ - old_file = current_file; - old_lineno = lineno; - current_file = filename; - lineno = 0; - - /* read and process lines */ - for ( offset = 0; ; ) - { - char * pnt; - - /* read a line */ - fgets( buffer + offset, sizeof(buffer) - offset, infile ); - if ( feof( infile ) ) - break; - lineno++; - - /* strip the trailing return character */ - pnt = buffer + strlen(buffer) - 1; - if ( *pnt == '\n' ) - *pnt-- = '\0'; - - /* eat \ NL pairs */ - if ( *pnt == '\\' ) - { - offset = pnt - buffer; - continue; - } - - /* tokenize this line */ - tokenize_line( buffer ); - offset = 0; - } - - /* that's all, folks */ - if ( infile != stdin ) - fclose( infile ); - current_file = old_file; - lineno = old_lineno; - return; -} - - - -/* - * Main program. - */ -int main( int argc, const char * argv [] ) -{ - do_source ( "-" ); - fix_conditionals ( config_list ); - dump_tk_script ( config_list ); - free(vartable); - return 0; -} |
