예제 #1
0
파일: tkparse.c 프로젝트: EliasLuiz/TCC
/*
 * 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;
}
예제 #2
0
파일: tkparse.c 프로젝트: EliasLuiz/TCC
/*
 * 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;
}
예제 #3
0
파일: tkparse.c 프로젝트: EliasLuiz/TCC
/*
 * 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" );
    }
}
예제 #4
0
static void generate_update_var( struct kconfig * scfg, int menu_num )
{
    struct kconfig * cfg;

    if ( menu_num>0 )
    {
	printf( "proc update_define_menu%d {} {\n", menu_num );
	printf( "\tupdate_define_mainmenu\n" );
    }
    else
	printf( "proc update_define_mainmenu {} {\n" );
    clear_globalflags();
    global( "CONFIG_MODULES" );
    vartable[ get_varnum( "CONFIG_MODULES" ) ].global_written = 1;
    for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
    {
	if ( cfg->menu_number == menu_num && (cfg->token == token_define_bool || cfg->token == token_define_tristate
	||   cfg->token == token_define_hex || cfg->token == token_define_int
	||   cfg->token == token_define_string || cfg->token == token_unset 
	||   cfg->token == token_tristate) )
	{
	    if ( ! vartable[cfg->nameindex].global_written )
	    {
		vartable[cfg->nameindex].global_written = 1;
		global( vartable[cfg->nameindex].name );
	    }
	}
    }

/*
 *	set all conditional bool/tristates to off unless changed later
 */
    for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) {
		if (cfg->menu_number != menu_num)
			continue;
		if (!cfg->cond)
			continue;
		switch (cfg->token) {
		case token_bool:
		case token_tristate:
			if (! vartable[cfg->nameindex].global_written) {
				vartable[cfg->nameindex].global_written = 1;
				global(vartable[cfg->nameindex].name);
			}
			printf("set %s [expr $%s|16]\n", vartable[cfg->nameindex].name,
					vartable[cfg->nameindex].name);
			break;
		default:
			break;
		}
	}

    for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
    {
	char tmp[20];
	struct kconfig * cfg1;

	if ( cfg->menu_number == menu_num )
	{
	    switch ( cfg->token )
	    {
	    default:
	    case token_choice_item:
		break;
	    case token_choice_header:
		sprintf( tmp, "tmpvar_%d", -(cfg->nameindex) );
		global( tmp );
		for ( cfg1  = cfg->next;
		      cfg1 != NULL && cfg1->token == token_choice_item;
		      cfg1  = cfg1->next )
		{
		    vartable[cfg1->nameindex].global_written = 1;
		    global( vartable[cfg1->nameindex].name );
		    printf( "\tif {$tmpvar_%d == \"%s\"} then {set %s 1} else {set %s 0}\n",
			-(cfg->nameindex), cfg1->label,
			vartable[cfg1->nameindex].name,
			vartable[cfg1->nameindex].name );
		}
		break;
	    case token_bool:
	    case token_define_bool:
	    case token_define_tristate:
	    case token_define_hex:
	    case token_define_int:
	    case token_define_string:
	    case token_dep_bool:
	    case token_dep_tristate:
	    case token_dep_mbool:
	    case token_int:
	    case token_hex:
	    case token_mainmenu_option:
	    case token_tristate:
	    case token_unset:
		if ( cfg->cond != NULL )
		    generate_if( cfg, cfg->cond, menu_num, -2 );
		else switch ( cfg->token )
		{
		case token_tristate:
		    printf( "\n\tif {($CONFIG_MODULES == 0)} then {if {($%s == 2)} then {set %s 1}}\n",
			vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
		    break;
		case token_define_bool:
		case token_define_tristate:
		    if ( ! vartable[get_varnum( cfg->value )].global_written )
		    {
			vartable[get_varnum( cfg->value )].global_written = 1;
			global( cfg->value );
		    }
		    printf( "\tset %s $%s\n", vartable[cfg->nameindex].name,
			cfg->value );
		    break;
		case token_define_hex:
		case token_define_int:
		    printf( "\tset %s %s\n", vartable[cfg->nameindex].name,
			cfg->value );
		    break;
		case token_define_string:
		    printf( "\tset %s \"%s\"\n", vartable[cfg->nameindex].name,
			cfg->value );
		    break;
		case token_unset:
		    printf( "\tset %s 4\n", vartable[cfg->nameindex].name );
		default:
		    break;
		}
	    }
	}
    }
    printf( "}\n\n\n" );
}
예제 #5
0
/*
 * Generate a line that writes a variable to the output file.
 */
void generate_writeconfig( struct kconfig * cfg )
{
    struct condition * cond;
    struct dependency * tmp;
    int depmod = 2;
    
    /*
     * Generate global declaration for this symbol.
     */
    if ( cfg->token != token_comment )
    {
	if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written )
	{
	    vartable[cfg->nameindex].global_written = 1;
	    global( vartable[cfg->nameindex].name );
	}
	if ( cfg->token == token_define_tristate || cfg->token == token_define_bool )
	{
	    if ( ! vartable[get_varnum( cfg->value )].global_written )
	    {
		vartable[get_varnum( cfg->value )].global_written = 1;
		global( cfg->value );
	    }
	}
	else if ( cfg->nameindex <= 0 && cfg->token == token_choice_header )
	{
	    printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) );
	}
    }

    /*
     * Generate global declarations for the condition chain.
     */
    for ( cond = cfg->cond; cond != NULL; cond = cond->next )
    {
	switch( cond->op )
	{
	default:
	    break;

	case op_variable:
	    if ( ! vartable[cond->nameindex].global_written )
	    {
		vartable[cond->nameindex].global_written = 1;
		global( vartable[cond->nameindex].name );
	    }
	    break;
	}
    }

    /*
     * Generate indentation.
     */
	printf( "\t" );

    /*
     * Generate the conditional.
     */
    if ( cfg->cond != NULL )
    {
	printf( "if {" );
	for ( cond = cfg->cond; cond != NULL; cond = cond->next )
	{
	    switch ( cond->op )
	    {
	    default:           break;
	    case op_bang:      printf( " ! "  ); break;
	    case op_eq:        printf( " == " ); break;
	    case op_neq:       printf( " != " ); break;
	    case op_and:       printf( " && " ); break;
	    case op_and1:      printf( " && " ); break;
	    case op_or:        printf( " || " ); break;
	    case op_lparen:    printf( "("    ); break;
	    case op_rparen:    printf( ")"    ); break;

	    case op_variable:
		printf( "$%s", vartable[cond->nameindex].name );
		break;

	    case op_constant:
		if      ( strcmp( cond->str, "n" ) == 0 ) printf( "0" );
		else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" );
		else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" );
		else if ( strcmp( cond->str, "" ) == 0 )  printf( "4" );
		else
		    printf( "\"%s\"", cond->str );
		break;
	    }
	}
	printf( "} then {" );
    }

    /*
     * Generate a procedure call to write the value.
     * This code depends on the write_* procedures in header.tk.
     */
    switch ( cfg->token )
    {
    default:
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_bool:
    case token_tristate:
	printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2", 
	    vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_choice_header:
	/*
	 * This is funky code -- it fails if there were any conditionals.
	 * Fortunately all the conditionals got stripped off somewhere
	 * else.
	 */
	{
	    struct kconfig * cfg1;
	    for ( cfg1  = cfg->next;
		  cfg1 != NULL && cfg1->token == token_choice_item;
		  cfg1  = cfg1->next )
	    {
		printf("\n\tif { $tmpvar_%d == \"%s\" } then { write_tristate $cfg $autocfg %s 1 [list $notmod] 2 } else { write_tristate $cfg $autocfg %s 0 [list $notmod] 2 }",
		    -(cfg->nameindex), cfg1->label,
		    vartable[cfg1->nameindex].name,
		    vartable[cfg1->nameindex].name );
	    }
	}
	if ( cfg->cond != NULL )
	    printf( "}" );
	printf( "\n" );
	break;

    case token_choice_item:
	fprintf( stderr, "Internal error on token_choice_item\n" );
	exit( 1 );

    case token_comment:
	printf( "write_comment $cfg $autocfg \"%s\"",
	    cfg->label );
	if ( cfg->cond != NULL )
	    printf( "}" );
	printf( "\n" );
	break;

    case token_define_bool:
    case token_define_tristate:
	if ( cfg->cond == NULL )
	{
	    printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2\n",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	}
	else
	{
	    printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2 }\n",
		vartable[cfg->nameindex].name, cfg->value );
	}
	break;

    case token_dep_mbool:
	depmod = 1;
    case token_dep_bool:
    case token_dep_tristate:
	printf( "write_tristate $cfg $autocfg %s $%s [list",
	    vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	for ( tmp = cfg->depend; tmp; tmp = tmp->next )
	    printf( " $%s", tmp->name );
	printf( "] %d", depmod );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_define_hex:
	printf( "write_hex $cfg $autocfg %s %s $notmod",
	    vartable[cfg->nameindex].name, cfg->value );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_define_int:
	printf( "write_int $cfg $autocfg %s %s $notmod",
	    vartable[cfg->nameindex].name, cfg->value );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_define_string:
	printf( "write_string $cfg $autocfg %s \"%s\" $notmod",
	    vartable[cfg->nameindex].name, cfg->value );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_hex:
	printf( "write_hex $cfg $autocfg %s $%s $notmod",
	    vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_int:
	printf( "write_int $cfg $autocfg %s $%s $notmod",
	    vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;

    case token_string:
	printf( "write_string $cfg $autocfg %s \"$%s\" $notmod",
	    vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	if ( cfg->cond != NULL )
	    printf( " }" );
	printf( "\n" );
	break;
    }
}
예제 #6
0
/*
 * This function walks the chain of conditions that we got from cond.c
 * and creates a TCL conditional to enable/disable a given widget.
 */
void generate_if( struct kconfig * cfg, struct condition * ocond,
    int menu_num, int line_num )
{
    struct condition * cond;
    struct dependency * tmp;
    struct kconfig * cfg1;

    if ( line_num >= -1 )
    {
	if ( cfg->token == token_define_bool || cfg->token == token_define_hex
	||   cfg->token == token_define_int || cfg->token == token_define_string
	||   cfg->token == token_define_tristate || cfg->token == token_unset )
	    return;
	if ( cfg->token == token_comment && line_num == -1 )
	    return;
    }
    else
    {
	if ( cfg->token == token_string || cfg->token == token_mainmenu_option )
	    return;
    }

    /*
     * First write any global declarations we need for this conditional.
     */
    for ( cond = ocond; cond != NULL; cond = cond->next )
    {
	switch ( cond->op )
	{
	default:
	    break;

	case op_variable:
	    if ( ! vartable[cond->nameindex].global_written )
	    {
		vartable[cond->nameindex].global_written = 1;
		global( vartable[cond->nameindex].name );
	    }
	    break;
	}
    }

    /*
     * Now write this option.
     */
    if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written )
    {
	vartable[cfg->nameindex].global_written = 1;
	global( vartable[cfg->nameindex].name );
    }

    /*
     * Generate the body of the conditional.
     */
    printf( "\tif {" );
    for ( cond = ocond; cond != NULL; cond = cond->next )
    {
	switch ( cond->op )
	{
	default:
	    break;

	case op_bang:   printf( " ! "  ); break;
	case op_eq:     printf( " == " ); break;
	case op_neq:    printf( " != " ); break;
	case op_and:    printf( " && " ); break;
	case op_and1:   printf( " && " ); break;
	case op_or:     printf( " || " ); break;
	case op_lparen: printf( "("    ); break;
	case op_rparen: printf( ")"    ); break;

	case op_variable:
	    printf( "$%s", vartable[cond->nameindex].name );
	    break;

	case op_constant:
	    if      ( strcmp( cond->str, "y" ) == 0 ) printf( "1" );
	    else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" );
	    else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" );
	    else if ( strcmp( cond->str, "" ) == 0 )  printf( "4" );
	    else
		printf( "\"%s\"", cond->str );
	    break;
	}
    }
    printf( "} then {" );

    /*
     * Generate a procedure call to write the value.
     * This code depends on procedures in header.tk.
     */
    if ( line_num >= -1 )
    {
	int modtoyes = 0;

	switch ( cfg->token )
	{
	default:
	    printf( " }\n" );
	    break;

	case token_dep_mbool:
	    modtoyes = 1;
	case token_dep_bool:
	    printf( "\n" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		if ( ! vartable[get_varnum( tmp->name )].global_written )
		{
		    global( tmp->name );
		}
	    printf( "\tset tmpvar_dep [effective_dep [list" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		printf( " $%s", tmp->name );
	    printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name,
		modtoyes );
	    printf( "if {$tmpvar_dep != 1" );
	    if (modtoyes)
		printf( " && $tmpvar_dep != 2" );
	    printf( "} then {configure_entry .menu%d.config.f.x%d disabled {y};",
		menu_num, line_num );
	    printf( "} else {" );
	    printf( "configure_entry .menu%d.config.f.x%d normal {y};",
		menu_num, line_num );
	    printf( "}; " );
	case token_bool:
	    if ( cfg->token == token_bool )
		printf( "\n\t" );
	    printf( "configure_entry .menu%d.config.f.x%d normal {n l",
		menu_num, line_num );
	    if ( cfg->token == token_bool )
		printf( " y" );
	    printf( "}" );
	    printf( "} else {");
	    printf( "configure_entry .menu%d.config.f.x%d disabled {y n l}}\n",
		menu_num, line_num );
	    break;

	case token_choice_header:
	    printf( "configure_entry .menu%d.config.f.x%d normal {x l}",
		menu_num, line_num );
	    printf( "} else {" );
	    printf( "configure_entry .menu%d.config.f.x%d disabled {x l}",
		menu_num, line_num );
	    printf( "}\n" );
	    break;

	case token_choice_item:
	    fprintf( stderr, "Internal error on token_choice_item\n" );
	    exit( 1 );

	case token_dep_tristate:
	    printf( "\n" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		if ( ! vartable[get_varnum( tmp->name )].global_written )
		{
		    global( tmp->name );
		}
	    printf( "\tset tmpvar_dep [effective_dep [list" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		printf( " $%s", tmp->name );
	    printf( "]];set %s [sync_tristate $%s $tmpvar_dep];",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	    printf( "\tif {$tmpvar_dep != 1} then {" );
	    printf( "configure_entry .menu%d.config.f.x%d disabled {y}",
		menu_num, line_num );
	    printf( "} else {" );
	    printf( "configure_entry .menu%d.config.f.x%d normal {y}",
		menu_num, line_num );
	    printf( "}; " );
	    printf( "if {$tmpvar_dep == 0} then {" );
	    printf( "configure_entry .menu%d.config.f.x%d disabled {m}",
		menu_num, line_num );
	    printf( "} else {" );
	    printf( "configure_entry .menu%d.config.f.x%d normal {m}",
		menu_num, line_num );
	    printf( "}; " );
	case token_tristate:
	    if ( cfg->token == token_tristate )
	    {
		printf( "\n\tconfigure_entry .menu%d.config.f.x%d normal {y}; ",
		    menu_num, line_num );
	    }
	    printf( "if {($CONFIG_MODULES == 1)} then {" );
	    printf( "configure_entry .menu%d.config.f.x%d normal {m}} else {",
		menu_num, line_num );
	    printf( "configure_entry .menu%d.config.f.x%d disabled {m}}; ",
		menu_num, line_num );
	    printf( "configure_entry .menu%d.config.f.x%d normal {n l}",
		menu_num, line_num );

	/*
	 * Or in a bit to the variable - this causes all of the radiobuttons
	 * to be deselected (i.e. not be red).
	 */
	    printf( "} else {" );
	    printf( "configure_entry .menu%d.config.f.x%d disabled {y n m l}}\n",
		menu_num, line_num );
	    break;

	case token_hex:
	case token_int:
	case token_string:
	    printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ",
		menu_num, line_num );
	    printf( ".menu%d.config.f.x%d.l configure -state normal; ",
		menu_num, line_num );
	    printf( "} else {" );
	    printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ]; ",
		menu_num, line_num );
	    printf( ".menu%d.config.f.x%d.l configure -state disabled}\n",
		menu_num, line_num );
	    break;

	case token_comment:
	case token_mainmenu_option:
	    if ( line_num >= 0 )
	    {
		printf( "configure_entry .menu%d.config.f.x%d normal {m}",
		    menu_num, line_num );
		printf( "} else {" );
		printf( "configure_entry .menu%d.config.f.x%d disabled {m}}\n",
		    menu_num, line_num );
	    }
	    else
		printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
		    menu_num, menu_num );
	    break;
	}
    }
    else
    {
	int modtoyes = 0;

	switch ( cfg->token )
	{
	default:
	    printf( " }\n" );
	    break;

	case token_dep_mbool:
	    modtoyes = 1;
	case token_dep_bool:
	    printf( "\n" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		if ( ! vartable[get_varnum( tmp->name )].global_written )
		{
		    global( tmp->name );
		}
	    printf( "\tset tmpvar_dep [effective_dep [list" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		printf( " $%s", tmp->name );
	    printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name,
		modtoyes );
	case token_bool:
	    if ( cfg->token == token_bool )
		printf( "\n\t" );
	    printf( "set %s [expr $%s&15]",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
		printf( "}\n");
	    break;

	case token_choice_header:
	    printf( "} else {" );
	    for ( cfg1  = cfg->next;
		  cfg1 != NULL && cfg1->token == token_choice_item;
		  cfg1  = cfg1->next )
		printf( "set %s 4;", vartable[cfg1->nameindex].name );
	    printf( "}\n" );
	    break;

	case token_choice_item:
	    fprintf( stderr, "Internal error on token_choice_item\n" );
	    exit( 1 );

	case token_define_bool:
	case token_define_tristate:
	    if ( ! vartable[get_varnum( cfg->value )].global_written )
	    {
		global( cfg->value );
	    }
	    printf( "set %s $%s }\n",
		vartable[cfg->nameindex].name, cfg->value );
	    break;

	case token_define_hex:
	case token_define_int:
	    printf( "set %s %s }\n",
		vartable[cfg->nameindex].name, cfg->value );
	    break;

	case token_define_string:
	    printf( "set %s \"%s\" }\n",
		vartable[cfg->nameindex].name, cfg->value );
	    break;

	case token_dep_tristate:
	    printf( "\n" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		if ( ! vartable[get_varnum( tmp->name )].global_written )
		{
		    global( tmp->name );
		}
	    printf( "\tset tmpvar_dep [effective_dep [list" );
	    for ( tmp = cfg->depend; tmp; tmp = tmp->next )
		printf( " $%s", tmp->name );
	    printf( "]]; set %s [sync_tristate $%s $tmpvar_dep]; ",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	case token_tristate:
	    if ( cfg->token == token_tristate )
		printf( "if {($CONFIG_MODULES == 0) && ($%s == 2)} then {set %s 1}; ",
		    vartable[cfg->nameindex].name,
		    vartable[cfg->nameindex].name );
	/*
	 * Or in a bit to the variable - this causes all of the radiobuttons
	 * to be deselected (i.e. not be red).
	 */
	    printf( "set %s [expr $%s&15]",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name );
	    printf( "}\n" );
	    break;

	case token_hex:
	case token_int:
	    if ( cfg->value && *cfg->value == '$' )
	    {
		int i = get_varnum( cfg->value+1 );
		printf( "\n" );
		if ( ! vartable[i].global_written )
		{
		    global( vartable[i].name );
		}
		printf( "\t" );
	    }
	    if ( cfg->token == token_hex )
		printf( "validate_hex " );
	    else if ( cfg->token == token_int )
		printf( "validate_int " );
	    printf( "%s \"$%s\" %s}\n",
		vartable[cfg->nameindex].name, vartable[cfg->nameindex].name,
		cfg->value );
	    break;

	case token_unset:
	    printf( "set %s 4}\n", vartable[cfg->nameindex].name );
	    break;
	}
    }
}
예제 #7
0
/*
 * Generates the end of a menu procedure.
 */
static void end_proc( struct kconfig * scfg, int menu_num )
{
    struct kconfig * cfg;

    printf( "\n\n\n" );
    printf( "\tfocus $w\n" );
    printf( "\tupdate_active\n" );
    printf( "\tglobal winx; global winy\n" );
    if ( menu_first[menu_num]->menu_number != 0 )
    {
	printf( "\tif {[winfo exists .menu%d] == 0} then ",
		menu_first[menu_num]->menu_number );
	printf( "{menu%d .menu%d \"%s\"}\n",
		menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number,
		menu_first[menu_first[menu_num]->menu_number]->label );
	printf( "\tset winx [expr [winfo x .menu%d]+30]; set winy [expr [winfo y .menu%d]+30]\n",
		menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number );
    }
    else
	printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" );
    printf( "\tif {[winfo exists $w]} then {wm geometry $w +$winx+$winy}\n" );

    /*
     * Now that the whole window is in place, we need to wait for an "update"
     * so we can tell the canvas what its virtual size should be.
     *
     * Unfortunately, this causes some ugly screen-flashing because the whole
     * window is drawn, and then it is immediately resized.  It seems
     * unavoidable, though, since "frame" objects won't tell us their size
     * until after an update, and "canvas" objects can't automatically pack
     * around frames.  Sigh.
     */
    printf( "\tupdate idletasks\n" );
    printf( "\tif {[winfo exists $w]} then  {$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" );
    printf( "\t$w.config.canvas configure \\\n" );
    printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" );
    printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" );
    printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" );
	 
    /*
     * If the whole canvas will fit in 3/4 of the screen height, do it;
     * otherwise, resize to around 1/2 the screen and let us scroll.
     */
    printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" );
    printf( "\tset scry [expr [winfo screenh $w] / 2]\n" );
    printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" );
    printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" );
    printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" );
    printf( "\t\t$w.config.canvas configure -height $canvtotal\n" );
    printf( "\t} else {\n" );
    printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" );
    printf( "\t\t}\n\t}\n" );

    /*
     * Limit the min/max window size.  Height can vary, but not width,
     * because of the limitations of canvas and our laziness.
     */
    printf( "\tupdate idletasks\n" );
    printf( "\tif {[winfo exists $w]} then {\n\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" );
    printf( "\twm minsize $w [winfo width $w] 100\n\n" );
    printf( "\twm deiconify $w\n" );
    printf( "}\n}\n\n" );

    /*
     * Now we generate the companion procedure for the menu we just
     * generated.  This procedure contains all of the code to
     * disable/enable widgets based upon the settings of the other
     * widgets, and will be called first when the window is mapped,
     * and each time one of the buttons in the window are clicked.
     */
    printf( "proc update_menu%d {} {\n", menu_num );

    /*
     * Clear all of the booleans that are defined in this menu.
     */
    clear_globalflags();
    for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
    {
	if ( cfg->menu_number == menu_num
	&&   cfg->token != token_mainmenu_option
	&&   cfg->token != token_choice_item )
	{
	    if ( cfg->cond != NULL )
	    {
		int i;
		if ( (cfg->token == token_tristate || cfg->token == token_dep_tristate)
		&& ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written )
		{
		    global( "CONFIG_MODULES" );
		    vartable[i].global_written = 1;
		}
		generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line );
	    }
	    else
	    {
		if ( cfg->token == token_tristate )
		{
		    int i;
		    if ( ! vartable[cfg->nameindex].global_written )
		    {
			vartable[cfg->nameindex].global_written = 1;
			printf( "\tglobal %s\n", vartable[cfg->nameindex].name );
		    }
		    if ( ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written )
		    {
			global( "CONFIG_MODULES" );
			vartable[i].global_written = 1;
		    }
		    printf( "\n\tif {($CONFIG_MODULES == 1)} then {configure_entry .menu%d.config.f.x%d normal {m}} else {configure_entry .menu%d.config.f.x%d disabled {m}}\n",
			menu_num, cfg->menu_line,
			menu_num, cfg->menu_line );
		}
	    }
	}
	else if ( cfg->token == token_mainmenu_option
	     &&   cfg->menu_number == menu_num
	     &&   cfg->cond != NULL )
	{
	    generate_if( cfg, cfg->cond, menu_num, cfg->menu_line );
	}
    }
    printf("}\n\n\n");

    generate_update_var( scfg, menu_num );
}