1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "tkparse.h"
33
34
35
36
37
38
39static void mark_variables( struct kconfig * scfg )
40{
41 struct kconfig * cfg;
42 int i;
43
44 for ( i = 1; i <= max_varnum; i++ )
45 vartable[i].defined = 0;
46 for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
47 {
48 if ( cfg->token == token_bool
49 || cfg->token == token_choice_item
50 || cfg->token == token_define_bool
51 || cfg->token == token_define_hex
52 || cfg->token == token_define_int
53 || cfg->token == token_define_string
54 || cfg->token == token_define_tristate
55 || cfg->token == token_dep_bool
56 || cfg->token == token_dep_mbool
57 || cfg->token == token_dep_tristate
58 || cfg->token == token_hex
59 || cfg->token == token_int
60 || cfg->token == token_string
61 || cfg->token == token_tristate
62 || cfg->token == token_unset )
63 {
64 if ( cfg->nameindex > 0 )
65 {
66 vartable[cfg->nameindex].defined = 1;
67 }
68 }
69 }
70}
71
72
73
74static void free_cond( struct condition *cond )
75{
76 struct condition *tmp, *tmp1;
77 for ( tmp = cond; tmp; tmp = tmp1 )
78 {
79 tmp1 = tmp->next;
80 free( (void*)tmp );
81 }
82}
83
84
85
86
87
88
89
90
91static struct condition * remove_bang( struct condition * condition )
92{
93 struct condition * conda, * condb, * prev = NULL;
94
95 for ( conda = condition; conda; conda = conda->next )
96 {
97 if ( conda->op == op_bang && conda->next &&
98 ( condb = conda->next->next ) )
99 {
100 if ( condb->op == op_eq || condb->op == op_neq )
101 {
102 condb->op = (condb->op == op_eq) ? op_neq : op_eq;
103 conda->op = op_nuked;
104 if ( prev )
105 {
106 prev->next = conda->next;
107 }
108 else
109 {
110 condition = conda->next;
111 }
112 conda->next = NULL;
113 free_cond( conda );
114 conda = condb;
115 }
116 }
117 prev = conda;
118 }
119 return condition;
120}
121
122
123
124
125
126
127
128static struct condition * join_condition_stack( struct condition * conditions [],
129 int depth )
130{
131 struct condition * cond_list;
132 struct condition * cond_last;
133 int i, is_first = 1;
134
135 cond_list = cond_last = NULL;
136
137 for ( i = 0; i < depth; i++ )
138 {
139 if ( conditions[i]->op == op_false )
140 {
141 struct condition * cnew;
142
143
144 cnew = malloc( sizeof(*cnew) );
145 memset( cnew, 0, sizeof(*cnew) );
146 cnew->op = op_false;
147 cond_list = cond_last = cnew;
148 goto join_done;
149 }
150 }
151 for ( i = 0; i < depth; i++ )
152 {
153 struct condition * cond;
154 struct condition * cnew;
155 int add_paren;
156
157
158 if ( conditions[i]->op == op_true )
159 continue;
160
161
162 if ( !is_first )
163 {
164 cnew = malloc( sizeof(*cnew) );
165 memset( cnew, 0, sizeof(*cnew) );
166 cnew->op = op_and;
167 cond_last->next = cnew;
168 cond_last = cnew;
169 }
170
171 if ( conditions[i]->op != op_lparen )
172 {
173
174 add_paren = 1;
175 cnew = malloc( sizeof(*cnew) );
176 memset( cnew, 0, sizeof(*cnew) );
177 cnew->op = op_lparen;
178 if ( cond_last == NULL )
179 { cond_list = cond_last = cnew; }
180 else
181 { cond_last->next = cnew; cond_last = cnew; }
182 }
183 else
184 {
185 add_paren = 0;
186 }
187
188
189 for ( cond = conditions [i]; cond != NULL; cond = cond->next )
190 {
191 cnew = malloc( sizeof(*cnew) );
192 cnew->next = NULL;
193 cnew->op = cond->op;
194 cnew->str = cond->str ? strdup( cond->str ) : NULL;
195 cnew->nameindex = cond->nameindex;
196 if ( cond_last == NULL )
197 { cond_list = cond_last = cnew; }
198 else
199 { cond_last->next = cnew; cond_last = cnew; }
200 }
201
202 if ( add_paren )
203 {
204
205 cnew = malloc( sizeof(*cnew) );
206 memset( cnew, 0, sizeof(*cnew) );
207 cnew->op = op_rparen;
208 cond_last->next = cnew;
209 cond_last = cnew;
210 }
211 is_first = 0;
212 }
213
214
215
216
217 {
218 struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f;
219
220 for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next )
221 {
222 if ( cond1->op == op_lparen )
223 {
224 cond1b = cond1 ->next; if ( cond1b == NULL ) break;
225 cond1c = cond1b->next; if ( cond1c == NULL ) break;
226 cond1d = cond1c->next; if ( cond1d == NULL ) break;
227 cond1e = cond1d->next; if ( cond1e == NULL ) break;
228 cond1f = cond1e->next; if ( cond1f == NULL ) break;
229
230 if ( cond1b->op == op_variable
231 && ( cond1c->op == op_eq || cond1c->op == op_neq )
232 && cond1d->op == op_constant
233 && cond1e->op == op_rparen )
234 {
235 struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f;
236
237 for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next )
238 {
239 if ( cond2->op == op_lparen )
240 {
241 cond2b = cond2 ->next; if ( cond2b == NULL ) break;
242 cond2c = cond2b->next; if ( cond2c == NULL ) break;
243 cond2d = cond2c->next; if ( cond2d == NULL ) break;
244 cond2e = cond2d->next; if ( cond2e == NULL ) break;
245 cond2f = cond2e->next;
246
247
248 if ( cond2b->op == op_variable
249 && cond2b->nameindex == cond1b->nameindex
250 && cond2c->op == cond1c->op
251 && cond2d->op == op_constant
252 && strcmp( cond2d->str, cond1d->str ) == 0
253 && cond2e->op == op_rparen )
254 {
255
256 if ( cond1f->op == op_and
257 || ( cond2f != NULL && cond2f->op == op_and ) )
258 {
259
260 cond1 ->op = op_nuked;
261 cond1b->op = op_nuked;
262 cond1c->op = op_nuked;
263 cond1d->op = op_nuked;
264 cond1e->op = op_nuked;
265 if ( cond1f->op == op_and )
266 cond1f->op = op_nuked;
267 else
268 cond2f->op = op_nuked;
269 }
270 }
271 }
272 }
273 }
274 }
275 }
276 }
277
278join_done:
279 return cond_list;
280}
281
282
283
284static char * current_arch = NULL;
285
286
287
288
289static struct condition *eliminate_other_arch( struct condition *list )
290{
291 struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL;
292 if ( current_arch == NULL )
293 current_arch = getenv( "ARCH" );
294 if ( current_arch == NULL )
295 {
296 fprintf( stderr, "error: ARCH undefined\n" );
297 exit( 1 );
298 }
299 if ( cond1a->op == op_variable
300 && ! strcmp( vartable[cond1a->nameindex].name, "ARCH" ) )
301 {
302 cond1b = cond1a->next; if ( cond1b == NULL ) goto done;
303 cond1c = cond1b->next; if ( cond1c == NULL ) goto done;
304 cond1d = cond1c->next;
305 if ( cond1c->op == op_constant && cond1d == NULL )
306 {
307 if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))
308 || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) )
309 {
310
311 cond1a->op = op_false;
312 cond1a->next = NULL;
313 free_cond( cond1b );
314 return cond1a;
315 }
316 else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))
317 || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) )
318 {
319
320 cond1a->op = op_true;
321 cond1a->next = NULL;
322 free_cond( cond1b );
323 return cond1a;
324 }
325 }
326 else if ( cond1c->op == op_constant && cond1d->op == op_or )
327 {
328 if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))
329 || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) )
330 {
331
332 cond1b = cond1d->next;
333 cond1d->next = NULL;
334 free_cond( cond1a );
335 return eliminate_other_arch( cond1b );
336 }
337 else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))
338 || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) )
339 {
340
341 cond1a->op = op_true;
342 cond1a->next = NULL;
343 free_cond( cond1b );
344 return cond1a;
345 }
346 }
347 else if ( cond1c->op == op_constant && cond1d->op == op_and )
348 {
349 if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch ))
350 || (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) )
351 {
352
353 int l_par = 0;
354
355 for ( cond1c = cond1d->next; cond1c; cond1c = cond1c->next )
356 {
357 if ( cond1c->op == op_lparen )
358 l_par++;
359 else if ( cond1c->op == op_rparen )
360 l_par--;
361 else if ( cond1c->op == op_or && l_par == 0 )
362
363 return cond1a;
364 else if ( l_par < 0 )
365 {
366 fprintf( stderr, "incorrect condition: programming error ?\n" );
367 exit( 1 );
368 }
369 }
370 cond1a->op = op_false;
371 cond1a->next = NULL;
372 free_cond( cond1b );
373 return cond1a;
374 }
375 else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch ))
376 || (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) )
377 {
378
379 cond1b = cond1d->next;
380 cond1d->next = NULL;
381 free_cond( cond1a );
382 return eliminate_other_arch( cond1b );
383 }
384 }
385 }
386 if ( cond1a->op == op_variable && ! vartable[cond1a->nameindex].defined )
387 {
388 cond1b = cond1a->next; if ( cond1b == NULL ) goto done;
389 cond1c = cond1b->next; if ( cond1c == NULL ) goto done;
390 cond1d = cond1c->next;
391
392 if ( cond1c->op == op_constant
393 && ( cond1d == NULL || cond1d->op == op_and ) )
394 {
395 if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) )
396 {
397 cond1a->op = op_false;
398 cond1a->next = NULL;
399 free_cond( cond1b );
400 return cond1a;
401 }
402 }
403 else if ( cond1c->op == op_constant && cond1d->op == op_or )
404 {
405 if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) )
406 {
407 cond1b = cond1d->next;
408 cond1d->next = NULL;
409 free_cond( cond1a );
410 return eliminate_other_arch( cond1b );
411 }
412 }
413 }
414done:
415 return list;
416}
417
418
419
420
421
422
423void fix_conditionals( struct kconfig * scfg )
424{
425 struct kconfig * cfg;
426
427
428
429
430 mark_variables( scfg );
431
432
433
434
435
436
437
438
439
440
441 {
442 struct condition * cond_stack [32];
443 int depth = 0;
444 struct kconfig * prev = NULL;
445
446 for ( cfg = scfg; cfg != NULL; cfg = cfg->next )
447 {
448 int good = 1;
449 switch ( cfg->token )
450 {
451 default:
452 break;
453
454 case token_if:
455 cond_stack [depth++] =
456 remove_bang( eliminate_other_arch( cfg->cond ) );
457 cfg->cond = NULL;
458 break;
459
460 case token_else:
461 {
462
463
464
465
466
467
468
469 struct condition * cond;
470
471 for ( cond = cond_stack [depth-1];
472 cond != NULL;
473 cond = cond->next )
474 {
475 switch( cond->op )
476 {
477 default: break;
478 case op_and: cond->op = op_or; break;
479 case op_or: cond->op = op_and1; break;
480 case op_neq: cond->op = op_eq; break;
481 case op_eq: cond->op = op_neq; break;
482 case op_true: cond->op = op_false;break;
483 case op_false:cond->op = op_true; break;
484 }
485 }
486 }
487 break;
488
489 case token_fi:
490 --depth;
491 break;
492
493 case token_bool:
494 case token_choice_item:
495 case token_choice_header:
496 case token_comment:
497 case token_define_bool:
498 case token_define_hex:
499 case token_define_int:
500 case token_define_string:
501 case token_define_tristate:
502 case token_endmenu:
503 case token_hex:
504 case token_int:
505 case token_mainmenu_option:
506 case token_string:
507 case token_tristate:
508 case token_unset:
509 cfg->cond = join_condition_stack( cond_stack, depth );
510 if ( cfg->cond && cfg->cond->op == op_false )
511 {
512 good = 0;
513 if ( prev )
514 prev->next = cfg->next;
515 else
516 scfg = cfg->next;
517 }
518 break;
519
520 case token_dep_bool:
521 case token_dep_mbool:
522 case token_dep_tristate:
523
524
525
526
527 if ( cfg->cond )
528 {
529 cond_stack [depth] = eliminate_other_arch( cfg->cond );
530 cfg->cond = join_condition_stack( cond_stack, depth+1 );
531 }
532 else
533 {
534 cfg->cond = join_condition_stack( cond_stack, depth );
535 }
536 if ( cfg->cond && cfg->cond->op == op_false )
537 {
538 good = 0;
539 if ( prev )
540 prev->next = cfg->next;
541 else
542 scfg = cfg->next;
543 }
544 break;
545 }
546 if ( good )
547 prev = cfg;
548 }
549 }
550}
551
552
553
554#if 0
555void dump_condition( struct condition *list )
556{
557 struct condition *tmp;
558 for ( tmp = list; tmp; tmp = tmp->next )
559 {
560 switch (tmp->op)
561 {
562 default:
563 break;
564 case op_variable:
565 printf( " %s", vartable[tmp->nameindex].name );
566 break;
567 case op_constant:
568 printf( " %s", tmp->str );
569 break;
570 case op_eq:
571 printf( " =" );
572 break;
573 case op_bang:
574 printf( " !" );
575 break;
576 case op_neq:
577 printf( " !=" );
578 break;
579 case op_and:
580 case op_and1:
581 printf( " -a" );
582 break;
583 case op_or:
584 printf( " -o" );
585 break;
586 case op_true:
587 printf( " TRUE" );
588 break;
589 case op_false:
590 printf( " FALSE" );
591 break;
592 case op_lparen:
593 printf( " (" );
594 break;
595 case op_rparen:
596 printf( " )" );
597 break;
598 }
599 }
600 printf( "\n" );
601}
602#endif
603