同步操作将从 Gitee 极速下载/MiniGUI 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** tkcond.c** Eric Youngdale was the original author of xconfig.* Michael Elizabeth Chastain (mec@shout.net) is the current maintainer.** 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.** 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.** 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl>* - kvariables removed; all variables are stored in a single table now* - some elimination of options non-valid for current architecture* implemented.* - negation (!) eliminated from conditions** 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"/** Mark variables which are defined anywhere.*/static void mark_variables( struct kconfig * scfg ){struct kconfig * cfg;int i;for ( i = 1; i <= max_varnum; i++ )vartable[i].defined = 0;for ( cfg = scfg; cfg != NULL; cfg = cfg->next ){if ( cfg->token == token_bool|| cfg->token == token_choice_item|| 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_dep_bool|| cfg->token == token_dep_mbool|| cfg->token == token_dep_tristate|| cfg->token == token_hex|| cfg->token == token_int|| cfg->token == token_string|| cfg->token == token_tristate|| cfg->token == token_unset ){if ( cfg->nameindex > 0 ) /* paranoid */{vartable[cfg->nameindex].defined = 1;}}}}static void free_cond( struct condition *cond ){struct condition *tmp, *tmp1;for ( tmp = cond; tmp; tmp = tmp1 ){tmp1 = tmp->next;free( (void*)tmp );}}/** Remove the bang operator from a condition to avoid priority problems.* "!" has different priorities as "test" command argument and in* a tk script.*/static struct condition * remove_bang( struct condition * condition ){struct condition * conda, * condb, * prev = NULL;for ( conda = condition; conda; conda = conda->next ){if ( conda->op == op_bang && conda->next &&( condb = conda->next->next ) ){if ( condb->op == op_eq || condb->op == op_neq ){condb->op = (condb->op == op_eq) ? op_neq : op_eq;conda->op = op_nuked;if ( prev ){prev->next = conda->next;}else{condition = conda->next;}conda->next = NULL;free_cond( conda );conda = condb;}}prev = conda;}return condition;}/** Make a new condition chain by joining the current condition stack with* the "&&" operator for glue.*/static struct condition * join_condition_stack( struct condition * conditions [],int depth ){struct condition * cond_list;struct condition * cond_last;int i, is_first = 1;cond_list = cond_last = NULL;for ( i = 0; i < depth; i++ ){if ( conditions[i]->op == op_false ){struct condition * cnew;/* It is always false condition */cnew = malloc( sizeof(*cnew) );memset( cnew, 0, sizeof(*cnew) );cnew->op = op_false;cond_list = cond_last = cnew;goto join_done;}}for ( i = 0; i < depth; i++ ){struct condition * cond;struct condition * cnew;int add_paren;/* omit always true conditions */if ( conditions[i]->op == op_true )continue;/* if i have another condition, add an '&&' operator */if ( !is_first ){cnew = malloc( sizeof(*cnew) );memset( cnew, 0, sizeof(*cnew) );cnew->op = op_and;cond_last->next = cnew;cond_last = cnew;}if ( conditions[i]->op != op_lparen ){/* add a '(' */add_paren = 1;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; }}else{add_paren = 0;}/* 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->nameindex = cond->nameindex;if ( cond_last == NULL ){ cond_list = cond_last = cnew; }else{ cond_last->next = cnew; cond_last = cnew; }}if ( add_paren ){/* add a ')' */cnew = malloc( sizeof(*cnew) );memset( cnew, 0, sizeof(*cnew) );cnew->op = op_rparen;cond_last->next = cnew;cond_last = cnew;}is_first = 0;}/** Remove duplicate conditions.*/{struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f;for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next ){if ( cond1->op == op_lparen ){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_variable&& ( cond1c->op == op_eq || cond1c->op == op_neq )&& cond1d->op == op_constant&& cond1e->op == op_rparen ){struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f;for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next ){if ( cond2->op == op_lparen ){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_variable&& cond2b->nameindex == cond1b->nameindex&& 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;elsecond2f->op = op_nuked;}}}}}}}}join_done:return cond_list;}static char * current_arch = NULL;/** Eliminating conditions with ARCH = <not current>.*/static struct condition *eliminate_other_arch( struct condition *list ){struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL;if ( current_arch == NULL )current_arch = getenv( "ARCH" );if ( current_arch == NULL ){fprintf( stderr, "error: ARCH undefined\n" );exit( 1 );}if ( cond1a->op == op_variable&& ! strcmp( vartable[cond1a->nameindex].name, "ARCH" ) ){cond1b = cond1a->next; if ( cond1b == NULL ) goto done;cond1c = cond1b->next; if ( cond1c == NULL ) goto done;cond1d = cond1c->next;if ( cond1c->op == op_constant && cond1d == NULL ){if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ){/* This is for another architecture */cond1a->op = op_false;cond1a->next = NULL;free_cond( cond1b );return cond1a;}else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ){/* This is for current architecture */cond1a->op = op_true;cond1a->next = NULL;free_cond( cond1b );return cond1a;}}else if ( cond1c->op == op_constant && cond1d->op == op_or ){if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ){/* This is for another architecture */cond1b = cond1d->next;cond1d->next = NULL;free_cond( cond1a );return eliminate_other_arch( cond1b );}else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ){/* This is for current architecture */cond1a->op = op_true;cond1a->next = NULL;free_cond( cond1b );return cond1a;}}else if ( cond1c->op == op_constant && cond1d->op == op_and ){if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ){/* This is for another architecture */int l_par = 0;for ( cond1c = cond1d->next; cond1c; cond1c = cond1c->next ){if ( cond1c->op == op_lparen )l_par++;else if ( cond1c->op == op_rparen )l_par--;else if ( cond1c->op == op_or && l_par == 0 )/* Expression too complex - don't touch */return cond1a;else if ( l_par < 0 ){fprintf( stderr, "incorrect condition: programming error ?\n" );exit( 1 );}}cond1a->op = op_false;cond1a->next = NULL;free_cond( cond1b );return cond1a;}else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ){/* This is for current architecture */cond1b = cond1d->next;cond1d->next = NULL;free_cond( cond1a );return eliminate_other_arch( cond1b );}}}if ( cond1a->op == op_variable && ! vartable[cond1a->nameindex].defined ){cond1b = cond1a->next; if ( cond1b == NULL ) goto done;cond1c = cond1b->next; if ( cond1c == NULL ) goto done;cond1d = cond1c->next;if ( cond1c->op == op_constant&& ( cond1d == NULL || cond1d->op == op_and ) ) /*???*/{if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ){cond1a->op = op_false;cond1a->next = NULL;free_cond( cond1b );return cond1a;}}else if ( cond1c->op == op_constant && cond1d->op == op_or ){if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ){cond1b = cond1d->next;cond1d->next = NULL;free_cond( cond1a );return eliminate_other_arch( cond1b );}}}done:return list;}/** This is the main transformation function.*/void fix_conditionals( struct kconfig * scfg ){struct kconfig * cfg;/** Transform op_variable to op_kvariable.*/mark_variables( scfg );/** 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.*/{struct condition * cond_stack [32];int depth = 0;struct kconfig * prev = NULL;for ( cfg = scfg; cfg != NULL; cfg = cfg->next ){int good = 1;switch ( cfg->token ){default:break;case token_if:cond_stack [depth++] =remove_bang( eliminate_other_arch( cfg->cond ) );cfg->cond = NULL;break;case token_else:{/** 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 ){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;case op_true: cond->op = op_false;break;case op_false:cond->op = op_true; break;}}}break;case token_fi:--depth;break;case token_bool:case token_choice_item:case token_choice_header:case token_comment:case token_define_bool:case token_define_hex:case token_define_int:case token_define_string:case token_define_tristate:case token_endmenu:case token_hex:case token_int:case token_mainmenu_option:case token_string:case token_tristate:case token_unset:cfg->cond = join_condition_stack( cond_stack, depth );if ( cfg->cond && cfg->cond->op == op_false ){good = 0;if ( prev )prev->next = cfg->next;elsescfg = cfg->next;}break;case token_dep_bool:case token_dep_mbool:case token_dep_tristate:/** Same as the other simple statements, plus an additional* condition for the dependency.*/if ( cfg->cond ){cond_stack [depth] = eliminate_other_arch( cfg->cond );cfg->cond = join_condition_stack( cond_stack, depth+1 );}else{cfg->cond = join_condition_stack( cond_stack, depth );}if ( cfg->cond && cfg->cond->op == op_false ){good = 0;if ( prev )prev->next = cfg->next;elsescfg = cfg->next;}break;}if ( good )prev = cfg;}}}#if 0void dump_condition( struct condition *list ){struct condition *tmp;for ( tmp = list; tmp; tmp = tmp->next ){switch (tmp->op){default:break;case op_variable:printf( " %s", vartable[tmp->nameindex].name );break;case op_constant:printf( " %s", tmp->str );break;case op_eq:printf( " =" );break;case op_bang:printf( " !" );break;case op_neq:printf( " !=" );break;case op_and:case op_and1:printf( " -a" );break;case op_or:printf( " -o" );break;case op_true:printf( " TRUE" );break;case op_false:printf( " FALSE" );break;case op_lparen:printf( " (" );break;case op_rparen:printf( " )" );break;}}printf( "\n" );}#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。