1 /* Generate tk script based upon config.in
8 * Avery Pennarun - Aesthetic improvements.
11 * Avery Pennarun - Bugfixes and more aesthetics.
14 * Avery Pennarun - The int and hex config.in commands work right.
15 * - Choice buttons are more user-friendly.
16 * - Disabling a text entry line greys it out properly.
17 * - dep_tristate now works like in Configure. (not pretty)
18 * - No warnings in gcc -Wall. (Fixed some "interesting" bugs.)
19 * - Faster/prettier "Help" lookups.
22 * Avery Pennarun - Added new sed script from Axel Boldt to make help even
23 * faster. (Actually awk is downright slow on some machines.)
24 * - Fixed a bug I introduced into Choice dependencies. Thanks
25 * to Robert Krawitz for pointing this out.
28 * Avery Pennarun - basic "do_make" support added to let sound config work.
31 * Axel Boldt - Help now works on "choice" buttons.
34 * Avery Pennarun - Improved sound config stuff. (I think it actually works
36 * - Window-resize-limits don't use ugly /usr/lib/tk4.0 hack.
37 * - int/hex work with tk3 again. (The "cget" error.)
38 * - Next/Prev buttons switch between menus. I can't take
39 * much credit for this; the code was already there, but
40 * ifdef'd out for some reason. It flickers a lot, but
41 * I suspect there's no "easy" fix for that.
42 * - Labels no longer highlight as you move the mouse over
43 * them (although you can still press them... oh well.)
44 * - Got rid of the last of the literal color settings, to
45 * help out people with mono X-Windows systems.
46 * (Apparently there still are some out there!)
47 * - Tabstops seem sensible now.
50 * Avery Pennarun - Reduced flicker when creating windows, even with "update
54 * Michael Chastain - Remove sound driver special cases.
57 * Michael Chastain - For choice buttons, write values for all options,
58 * not just the single chosen one. This is compatible
59 * with 'make config' and 'make oldconfig', and is
60 * needed so smart-config dependencies work if the
61 * user switches from one configuration method to
65 * Axel Boldt - Smaller layout of main menu - it's still too big for 800x600.
66 * - Display help in text window to allow for cut and paste.
67 * - Allow for empty lines in help texts.
68 * - update_define should not set all variables unconditionally to
69 * 0: they may have been set to 1 elsewhere. CONFIG_NETLINK is
73 * Michael Elizabeth Chastain <mec@shout.net>
74 * - Call clear_globalflags when writing out update_mainmenu.
75 * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4.
77 * 8 January 1999, Michael Elizabeth Chastain <mec@shout.net>
78 * - Emit menus_per_column
80 * 14 January 1999, Michael Elizabeth Chastain <mec@shout.net>
81 * - Steam-clean this file. I tested this by generating kconfig.tk for every
82 * architecture and comparing it character-for-character against the output
84 * - Fix flattening of nested menus. The old code simply assigned items to
85 * the most recent token_mainmenu_option, without paying attention to scope.
86 * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu".
87 * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c
88 * and bool-d in *menu-2*. This hosed the nested submenus in
89 * drives/net/Config.in and other places.
90 * - Fix menu line wraparound at 128 menus (some fool used a 'char' for
93 * 23 January 1999, Michael Elizabeth Chastain <mec@shout.net>
94 * - Remove bug-compatible code.
96 * 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl>
97 * Some bugfixes, including
98 * - disabling "m" options when CONFIG_MODULES is set to "n" as well as "y"
99 * option in dep_tristate when dependency is set to "m",
100 * - deactivating choices which should not be available,
101 * - basic validation for int and hex introduced if the entered one is not
103 * - updates of all opened menus instead of the active only. I was afraid
104 * that it would slow down updates, but I don't even see any speed difference
105 * on my machine. If it slows you can still work with only a single menu
107 * - fixed error when focussing non-existent window (especially Help windows),
108 * Higher level submenus implemented.
119 * Total number of menus.
121 static int tot_menu_num
= 0;
124 * Pointers to mainmenu_option and endmenu of each menu.
126 struct kconfig
* menu_first
[100];
127 struct kconfig
* menu_last
[100];
130 * Generate portion of wish script for the beginning of a submenu.
131 * The guts get filled in with the various options.
133 static void start_proc( char * label
, int menu_num
, int toplevel
)
136 printf( "menu_option menu%d %d \"%s\"\n", menu_num
, menu_num
, label
);
137 printf( "proc menu%d {w title} {\n", menu_num
);
138 printf( "\tset oldFocus [focus]\n" );
139 if ( menu_first
[menu_num
]->menu_number
!= 0 )
140 printf( "\tcatch {focus .menu%d}\n",
141 menu_first
[menu_num
]->menu_number
);
142 printf( "\tcatch {destroy $w; unregister_active %d}\n", menu_num
);
143 printf( "\ttoplevel $w -class Dialog\n" );
144 printf( "\twm withdraw $w\n" );
145 printf( "\tglobal active_menus\n" );
146 printf( "\tset active_menus [lsort -integer [linsert $active_menus end %d]]\n", menu_num
);
147 printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" );
148 printf( "\t\t\"%s\" -relief raised\n", label
);
149 printf( "\tpack $w.m -pady 10 -side top -padx 10\n" );
150 printf( "\twm title $w \"%s\" \n\n", label
);
152 printf( "\tbind $w <Escape> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; break\"\n", menu_num
);
154 printf("\tset nextscript ");
155 printf("\"catch {focus $oldFocus}; " );
157 * We are checking which windows should be destroyed and which are
158 * common parrents with the next one. Remember that menu_num field
159 * in mainmenu_option record reports number of its *parent* menu.
161 if ( menu_num
< tot_menu_num
162 && menu_first
[menu_num
+ 1]->menu_number
!= menu_num
)
166 printf( "destroy $w; unregister_active %d; ", menu_num
);
167 to_destr
= menu_first
[menu_num
]->menu_number
;
168 while ( to_destr
> 0 && menu_first
[menu_num
+ 1]->menu_number
!= to_destr
)
170 printf( "catch {destroy .menu%d}; unregister_active %d; ",
171 to_destr
, to_destr
);
172 to_destr
= menu_first
[to_destr
]->menu_number
;
175 printf( "menu%d .menu%d \\\"$title\\\"\"\n",
176 menu_num
+1, menu_num
+1 );
179 * Attach the "Prev", "Next" and "OK" buttons at the end of the window.
181 printf( "\tframe $w.f\n" );
183 printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" );
185 printf( "\tbutton $w.f.back -text \"OK\" \\\n" );
186 printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n",
188 printf( "\tbutton $w.f.next -text \"Next\" -underline 0\\\n" );
189 printf( "\t\t-width 15 -command $nextscript\n");
191 if ( menu_num
== tot_menu_num
) {
192 printf( "\t$w.f.next configure -state disabled\n" );
194 * this is a bit hackish but Alt-n must be rebound
195 * otherwise if the user press Alt-n on the last menu
196 * it will give him/her the next menu of one of the
199 printf( "\tbind all <Alt-n> \"puts \\\"no more menus\\\" \"\n");
204 * I should be binding to $w not all - but if I do nehat I get the error "unknown path"
206 printf( "\tbind all <Alt-n> $nextscript\n");
208 printf( "\tbutton $w.f.prev -text \"Prev\" -underline 0\\\n" );
209 printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\"\"\n",
210 menu_num
, menu_num
-1, menu_num
-1 );
211 if ( menu_num
== 1 ) {
212 printf( "\t$w.f.prev configure -state disabled\n" );
216 printf( "\tbind $w <Alt-p> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\";break\"\n",
217 menu_num
, menu_num
-1, menu_num
-1 );
219 printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" );
220 printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" );
223 * Lines between canvas and other areas of the window.
225 printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" );
226 printf( "\tpack $w.topline -side top -fill x\n\n" );
227 printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" );
228 printf( "\tpack $w.botline -side bottom -fill x\n\n" );
231 * The "config" frame contains the canvas and a scrollbar.
233 printf( "\tframe $w.config\n" );
234 printf( "\tpack $w.config -fill y -expand on\n\n" );
235 printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" );
236 printf( "\tpack $w.config.vscroll -side right -fill y\n\n" );
239 * The scrollable canvas itself, where the real work (and mess) gets done.
241 printf( "\tcanvas $w.config.canvas -height 1\\\n" );
242 printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" );
243 printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" );
244 printf( "\tframe $w.config.f\n" );
245 printf( "\tbind $w <Key-Down> \"$w.config.canvas yview scroll 1 unit;break;\"\n");
246 printf( "\tbind $w <Key-Up> \"$w.config.canvas yview scroll -1 unit;break;\"\n");
247 printf( "\tbind $w <Key-Next> \"$w.config.canvas yview scroll 1 page;break;\"\n");
248 printf( "\tbind $w <Key-Prior> \"$w.config.canvas yview scroll -1 page;break;\"\n");
249 printf( "\tbind $w <Key-Home> \"$w.config.canvas yview moveto 0;break;\"\n");
250 printf( "\tbind $w <Key-End> \"$w.config.canvas yview moveto 1 ;break;\"\n");
251 printf( "\tpack $w.config.canvas -side right -fill y\n" );
258 * Each proc we create needs a global declaration for any global variables we
259 * use. To minimize the size of the file, we set a flag each time we output
260 * a global declaration so we know whether we need to insert one for a
261 * given function or not.
263 static void clear_globalflags(void)
266 for ( i
= 1; i
<= max_varnum
; i
++ )
267 vartable
[i
].global_written
= 0;
273 * Output a "global" line for a given variable. Also include the
274 * call to "vfix". (If vfix is not needed, then it's fine to just printf
277 void global( const char *var
)
279 printf( "\tglobal %s\n", var
);
285 * This function walks the chain of conditions that we got from cond.c
286 * and creates a TCL conditional to enable/disable a given widget.
288 void generate_if( struct kconfig
* cfg
, struct condition
* ocond
,
289 int menu_num
, int line_num
)
291 struct condition
* cond
;
292 struct dependency
* tmp
;
293 struct kconfig
* cfg1
;
295 if ( line_num
>= -1 )
297 if ( cfg
->token
== token_define_bool
|| cfg
->token
== token_define_hex
298 || cfg
->token
== token_define_int
|| cfg
->token
== token_define_string
299 || cfg
->token
== token_define_tristate
|| cfg
->token
== token_unset
)
301 if ( cfg
->token
== token_comment
&& line_num
== -1 )
306 if ( cfg
->token
== token_string
|| cfg
->token
== token_mainmenu_option
)
311 * First write any global declarations we need for this conditional.
313 for ( cond
= ocond
; cond
!= NULL
; cond
= cond
->next
)
321 if ( ! vartable
[cond
->nameindex
].global_written
)
323 vartable
[cond
->nameindex
].global_written
= 1;
324 global( vartable
[cond
->nameindex
].name
);
331 * Now write this option.
333 if ( cfg
->nameindex
> 0 && ! vartable
[cfg
->nameindex
].global_written
)
335 vartable
[cfg
->nameindex
].global_written
= 1;
336 global( vartable
[cfg
->nameindex
].name
);
340 * Generate the body of the conditional.
343 for ( cond
= ocond
; cond
!= NULL
; cond
= cond
->next
)
350 case op_bang
: printf( " ! " ); break;
351 case op_eq
: printf( " == " ); break;
352 case op_neq
: printf( " != " ); break;
353 case op_and
: printf( " && " ); break;
354 case op_and1
: printf( " && " ); break;
355 case op_or
: printf( " || " ); break;
356 case op_lparen
: printf( "(" ); break;
357 case op_rparen
: printf( ")" ); break;
360 printf( "$%s", vartable
[cond
->nameindex
].name
);
364 if ( strcmp( cond
->str
, "y" ) == 0 ) printf( "1" );
365 else if ( strcmp( cond
->str
, "n" ) == 0 ) printf( "0" );
366 else if ( strcmp( cond
->str
, "m" ) == 0 ) printf( "2" );
367 else if ( strcmp( cond
->str
, "" ) == 0 ) printf( "4" );
369 printf( "\"%s\"", cond
->str
);
373 printf( "} then {" );
376 * Generate a procedure call to write the value.
377 * This code depends on procedures in header.tk.
379 if ( line_num
>= -1 )
383 switch ( cfg
->token
)
389 case token_dep_mbool
:
393 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
394 if ( ! vartable
[get_varnum( tmp
->name
)].global_written
)
398 printf( "\tset tmpvar_dep [effective_dep [list" );
399 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
400 printf( " $%s", tmp
->name
);
401 printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];",
402 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
,
404 printf( "if {$tmpvar_dep != 1" );
406 printf( " && $tmpvar_dep != 2" );
407 printf( "} then {configure_entry .menu%d.config.f.x%d disabled {y};",
408 menu_num
, line_num
);
409 printf( "} else {" );
410 printf( "configure_entry .menu%d.config.f.x%d normal {y};",
411 menu_num
, line_num
);
414 if ( cfg
->token
== token_bool
)
416 printf( "configure_entry .menu%d.config.f.x%d normal {n l",
417 menu_num
, line_num
);
418 if ( cfg
->token
== token_bool
)
422 printf( "configure_entry .menu%d.config.f.x%d disabled {y n l}}\n",
423 menu_num
, line_num
);
426 case token_choice_header
:
427 printf( "configure_entry .menu%d.config.f.x%d normal {x l}",
428 menu_num
, line_num
);
429 printf( "} else {" );
430 printf( "configure_entry .menu%d.config.f.x%d disabled {x l}",
431 menu_num
, line_num
);
435 case token_choice_item
:
436 fprintf( stderr
, "Internal error on token_choice_item\n" );
439 case token_dep_tristate
:
441 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
442 if ( ! vartable
[get_varnum( tmp
->name
)].global_written
)
446 printf( "\tset tmpvar_dep [effective_dep [list" );
447 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
448 printf( " $%s", tmp
->name
);
449 printf( "]];set %s [sync_tristate $%s $tmpvar_dep];",
450 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
451 printf( "\tif {$tmpvar_dep != 1} then {" );
452 printf( "configure_entry .menu%d.config.f.x%d disabled {y}",
453 menu_num
, line_num
);
454 printf( "} else {" );
455 printf( "configure_entry .menu%d.config.f.x%d normal {y}",
456 menu_num
, line_num
);
458 printf( "if {$tmpvar_dep == 0} then {" );
459 printf( "configure_entry .menu%d.config.f.x%d disabled {m}",
460 menu_num
, line_num
);
461 printf( "} else {" );
462 printf( "configure_entry .menu%d.config.f.x%d normal {m}",
463 menu_num
, line_num
);
466 if ( cfg
->token
== token_tristate
)
468 printf( "\n\tconfigure_entry .menu%d.config.f.x%d normal {y}; ",
469 menu_num
, line_num
);
471 printf( "if {($CONFIG_MODULES == 1)} then {" );
472 printf( "configure_entry .menu%d.config.f.x%d normal {m}} else {",
473 menu_num
, line_num
);
474 printf( "configure_entry .menu%d.config.f.x%d disabled {m}}; ",
475 menu_num
, line_num
);
476 printf( "configure_entry .menu%d.config.f.x%d normal {n l}",
477 menu_num
, line_num
);
480 * Or in a bit to the variable - this causes all of the radiobuttons
481 * to be deselected (i.e. not be red).
483 printf( "} else {" );
484 printf( "configure_entry .menu%d.config.f.x%d disabled {y n m l}}\n",
485 menu_num
, line_num
);
491 printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ",
492 menu_num
, line_num
);
493 printf( ".menu%d.config.f.x%d.l configure -state normal; ",
494 menu_num
, line_num
);
495 printf( "} else {" );
496 printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ]; ",
497 menu_num
, line_num
);
498 printf( ".menu%d.config.f.x%d.l configure -state disabled}\n",
499 menu_num
, line_num
);
503 case token_mainmenu_option
:
506 printf( "configure_entry .menu%d.config.f.x%d normal {m}",
507 menu_num
, line_num
);
508 printf( "} else {" );
509 printf( "configure_entry .menu%d.config.f.x%d disabled {m}}\n",
510 menu_num
, line_num
);
513 printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
514 menu_num
, menu_num
);
522 switch ( cfg
->token
)
528 case token_dep_mbool
:
532 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
533 if ( ! vartable
[get_varnum( tmp
->name
)].global_written
)
537 printf( "\tset tmpvar_dep [effective_dep [list" );
538 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
539 printf( " $%s", tmp
->name
);
540 printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];",
541 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
,
544 if ( cfg
->token
== token_bool
)
546 printf( "set %s [expr $%s&15]",
547 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
549 printf( "set %s [expr $%s|16]}\n",
550 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
553 case token_choice_header
:
554 printf( "} else {" );
555 for ( cfg1
= cfg
->next
;
556 cfg1
!= NULL
&& cfg1
->token
== token_choice_item
;
558 printf( "set %s 4;", vartable
[cfg1
->nameindex
].name
);
562 case token_choice_item
:
563 fprintf( stderr
, "Internal error on token_choice_item\n" );
566 case token_define_bool
:
567 case token_define_tristate
:
568 if ( ! vartable
[get_varnum( cfg
->value
)].global_written
)
570 global( cfg
->value
);
572 printf( "set %s $%s }\n",
573 vartable
[cfg
->nameindex
].name
, cfg
->value
);
576 case token_define_hex
:
577 case token_define_int
:
578 printf( "set %s %s }\n",
579 vartable
[cfg
->nameindex
].name
, cfg
->value
);
582 case token_define_string
:
583 printf( "set %s \"%s\" }\n",
584 vartable
[cfg
->nameindex
].name
, cfg
->value
);
587 case token_dep_tristate
:
589 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
590 if ( ! vartable
[get_varnum( tmp
->name
)].global_written
)
594 printf( "\tset tmpvar_dep [effective_dep [list" );
595 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
596 printf( " $%s", tmp
->name
);
597 printf( "]]; set %s [sync_tristate $%s $tmpvar_dep]; ",
598 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
600 if ( cfg
->token
== token_tristate
)
601 printf( "if {($CONFIG_MODULES == 0) && ($%s == 2)} then {set %s 1}; ",
602 vartable
[cfg
->nameindex
].name
,
603 vartable
[cfg
->nameindex
].name
);
605 * Or in a bit to the variable - this causes all of the radiobuttons
606 * to be deselected (i.e. not be red).
608 printf( "set %s [expr $%s&15]",
609 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
610 printf( "} else {" );
613 * Clear the disable bit to enable the correct radiobutton.
615 printf( "set %s [expr $%s|16]}\n",
616 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
621 if ( cfg
->value
&& *cfg
->value
== '$' )
623 int index
= get_varnum( cfg
->value
+1 );
625 if ( ! vartable
[index
].global_written
)
627 global( vartable
[index
].name
);
631 if ( cfg
->token
== token_hex
)
632 printf( "validate_hex " );
633 else if ( cfg
->token
== token_int
)
634 printf( "validate_int " );
635 printf( "%s \"$%s\" %s}\n",
636 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
,
641 printf( "set %s 4}\n", vartable
[cfg
->nameindex
].name
);
649 * Generate a line that writes a variable to the output file.
651 void generate_writeconfig( struct kconfig
* cfg
)
653 struct condition
* cond
;
654 struct dependency
* tmp
;
658 * Generate global declaration for this symbol.
660 if ( cfg
->token
!= token_comment
)
662 if ( cfg
->nameindex
> 0 && ! vartable
[cfg
->nameindex
].global_written
)
664 vartable
[cfg
->nameindex
].global_written
= 1;
665 global( vartable
[cfg
->nameindex
].name
);
667 if ( cfg
->token
== token_define_tristate
|| cfg
->token
== token_define_bool
)
669 if ( ! vartable
[get_varnum( cfg
->value
)].global_written
)
671 vartable
[get_varnum( cfg
->value
)].global_written
= 1;
672 global( cfg
->value
);
675 else if ( cfg
->nameindex
<= 0 && cfg
->token
== token_choice_header
)
677 printf( "\tglobal tmpvar_%d\n", -(cfg
->nameindex
) );
682 * Generate global declarations for the condition chain.
684 for ( cond
= cfg
->cond
; cond
!= NULL
; cond
= cond
->next
)
692 if ( ! vartable
[cond
->nameindex
].global_written
)
694 vartable
[cond
->nameindex
].global_written
= 1;
695 global( vartable
[cond
->nameindex
].name
);
702 * Generate indentation.
707 * Generate the conditional.
709 if ( cfg
->cond
!= NULL
)
712 for ( cond
= cfg
->cond
; cond
!= NULL
; cond
= cond
->next
)
717 case op_bang
: printf( " ! " ); break;
718 case op_eq
: printf( " == " ); break;
719 case op_neq
: printf( " != " ); break;
720 case op_and
: printf( " && " ); break;
721 case op_and1
: printf( " && " ); break;
722 case op_or
: printf( " || " ); break;
723 case op_lparen
: printf( "(" ); break;
724 case op_rparen
: printf( ")" ); break;
727 printf( "$%s", vartable
[cond
->nameindex
].name
);
731 if ( strcmp( cond
->str
, "n" ) == 0 ) printf( "0" );
732 else if ( strcmp( cond
->str
, "y" ) == 0 ) printf( "1" );
733 else if ( strcmp( cond
->str
, "m" ) == 0 ) printf( "2" );
734 else if ( strcmp( cond
->str
, "" ) == 0 ) printf( "4" );
736 printf( "\"%s\"", cond
->str
);
740 printf( "} then {" );
744 * Generate a procedure call to write the value.
745 * This code depends on the write_* procedures in header.tk.
747 switch ( cfg
->token
)
750 if ( cfg
->cond
!= NULL
)
757 printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2",
758 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
759 if ( cfg
->cond
!= NULL
)
764 case token_choice_header
:
766 * This is funky code -- it fails if there were any conditionals.
767 * Fortunately all the conditionals got stripped off somewhere
771 struct kconfig
* cfg1
;
772 for ( cfg1
= cfg
->next
;
773 cfg1
!= NULL
&& cfg1
->token
== token_choice_item
;
776 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 }",
777 -(cfg
->nameindex
), cfg1
->label
,
778 vartable
[cfg1
->nameindex
].name
,
779 vartable
[cfg1
->nameindex
].name
);
782 if ( cfg
->cond
!= NULL
)
787 case token_choice_item
:
788 fprintf( stderr
, "Internal error on token_choice_item\n" );
792 printf( "write_comment $cfg $autocfg \"%s\"",
794 if ( cfg
->cond
!= NULL
)
799 case token_define_bool
:
800 case token_define_tristate
:
801 if ( cfg
->cond
== NULL
)
803 printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2\n",
804 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
808 printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2 }\n",
809 vartable
[cfg
->nameindex
].name
, cfg
->value
);
813 case token_dep_mbool
:
816 case token_dep_tristate
:
817 printf( "write_tristate $cfg $autocfg %s $%s [list",
818 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
819 for ( tmp
= cfg
->depend
; tmp
; tmp
= tmp
->next
)
820 printf( " $%s", tmp
->name
);
821 printf( "] %d", depmod
);
822 if ( cfg
->cond
!= NULL
)
827 case token_define_hex
:
828 printf( "write_hex $cfg $autocfg %s %s $notmod",
829 vartable
[cfg
->nameindex
].name
, cfg
->value
);
830 if ( cfg
->cond
!= NULL
)
835 case token_define_int
:
836 printf( "write_int $cfg $autocfg %s %s $notmod",
837 vartable
[cfg
->nameindex
].name
, cfg
->value
);
838 if ( cfg
->cond
!= NULL
)
843 case token_define_string
:
844 printf( "write_string $cfg $autocfg %s \"%s\" $notmod",
845 vartable
[cfg
->nameindex
].name
, cfg
->value
);
846 if ( cfg
->cond
!= NULL
)
852 printf( "write_hex $cfg $autocfg %s $%s $notmod",
853 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
854 if ( cfg
->cond
!= NULL
)
860 printf( "write_int $cfg $autocfg %s $%s $notmod",
861 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
862 if ( cfg
->cond
!= NULL
)
868 printf( "write_string $cfg $autocfg %s \"$%s\" $notmod",
869 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
870 if ( cfg
->cond
!= NULL
)
877 static void generate_update_var( struct kconfig
* scfg
, int menu_num
)
879 struct kconfig
* cfg
;
883 printf( "proc update_define_menu%d {} {\n", menu_num
);
884 printf( "\tupdate_define_mainmenu\n" );
887 printf( "proc update_define_mainmenu {} {\n" );
889 global( "CONFIG_MODULES" );
890 vartable
[ get_varnum( "CONFIG_MODULES" ) ].global_written
= 1;
891 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
893 if ( cfg
->menu_number
== menu_num
&& (cfg
->token
== token_define_bool
|| cfg
->token
== token_define_tristate
894 || cfg
->token
== token_define_hex
|| cfg
->token
== token_define_int
895 || cfg
->token
== token_define_string
|| cfg
->token
== token_unset
896 || cfg
->token
== token_tristate
) )
898 if ( ! vartable
[cfg
->nameindex
].global_written
)
900 vartable
[cfg
->nameindex
].global_written
= 1;
901 global( vartable
[cfg
->nameindex
].name
);
906 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
909 struct kconfig
* cfg1
;
911 if ( cfg
->menu_number
== menu_num
)
913 switch ( cfg
->token
)
916 case token_choice_item
:
918 case token_choice_header
:
919 sprintf( tmp
, "tmpvar_%d", -(cfg
->nameindex
) );
921 for ( cfg1
= cfg
->next
;
922 cfg1
!= NULL
&& cfg1
->token
== token_choice_item
;
925 vartable
[cfg1
->nameindex
].global_written
= 1;
926 global( vartable
[cfg1
->nameindex
].name
);
927 printf( "\tif {$tmpvar_%d == \"%s\"} then {set %s 1} else {set %s 0}\n",
928 -(cfg
->nameindex
), cfg1
->label
,
929 vartable
[cfg1
->nameindex
].name
,
930 vartable
[cfg1
->nameindex
].name
);
934 case token_define_bool
:
935 case token_define_tristate
:
936 case token_define_hex
:
937 case token_define_int
:
938 case token_define_string
:
940 case token_dep_tristate
:
941 case token_dep_mbool
:
944 case token_mainmenu_option
:
947 if ( cfg
->cond
!= NULL
)
948 generate_if( cfg
, cfg
->cond
, menu_num
, -2 );
949 else switch ( cfg
->token
)
952 printf( "\n\tif {($CONFIG_MODULES == 0)} then {if {($%s == 2)} then {set %s 1}}\n",
953 vartable
[cfg
->nameindex
].name
, vartable
[cfg
->nameindex
].name
);
955 case token_define_bool
:
956 case token_define_tristate
:
957 if ( ! vartable
[get_varnum( cfg
->value
)].global_written
)
959 vartable
[get_varnum( cfg
->value
)].global_written
= 1;
960 global( cfg
->value
);
962 printf( "\tset %s $%s\n", vartable
[cfg
->nameindex
].name
,
965 case token_define_hex
:
966 case token_define_int
:
967 printf( "\tset %s %s\n", vartable
[cfg
->nameindex
].name
,
970 case token_define_string
:
971 printf( "\tset %s \"%s\"\n", vartable
[cfg
->nameindex
].name
,
975 printf( "\tset %s 4\n", vartable
[cfg
->nameindex
].name
);
987 * Generates the end of a menu procedure.
989 static void end_proc( struct kconfig
* scfg
, int menu_num
)
991 struct kconfig
* cfg
;
995 printf( "\tfocus $w\n" );
996 printf( "\tupdate_active\n" );
997 printf( "\tglobal winx; global winy\n" );
998 if ( menu_first
[menu_num
]->menu_number
!= 0 )
1000 printf( "\tif {[winfo exists .menu%d] == 0} then ",
1001 menu_first
[menu_num
]->menu_number
);
1002 printf( "{menu%d .menu%d \"%s\"}\n",
1003 menu_first
[menu_num
]->menu_number
, menu_first
[menu_num
]->menu_number
,
1004 menu_first
[menu_first
[menu_num
]->menu_number
]->label
);
1005 printf( "\tset winx [expr [winfo x .menu%d]+30]; set winy [expr [winfo y .menu%d]+30]\n",
1006 menu_first
[menu_num
]->menu_number
, menu_first
[menu_num
]->menu_number
);
1009 printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" );
1010 printf( "\tif {[winfo exists $w]} then {wm geometry $w +$winx+$winy}\n" );
1013 * Now that the whole window is in place, we need to wait for an "update"
1014 * so we can tell the canvas what its virtual size should be.
1016 * Unfortunately, this causes some ugly screen-flashing because the whole
1017 * window is drawn, and then it is immediately resized. It seems
1018 * unavoidable, though, since "frame" objects won't tell us their size
1019 * until after an update, and "canvas" objects can't automatically pack
1020 * around frames. Sigh.
1022 printf( "\tupdate idletasks\n" );
1023 printf( "\tif {[winfo exists $w]} then {$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" );
1024 printf( "\t$w.config.canvas configure \\\n" );
1025 printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" );
1026 printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" );
1027 printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" );
1030 * If the whole canvas will fit in 3/4 of the screen height, do it;
1031 * otherwise, resize to around 1/2 the screen and let us scroll.
1033 printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" );
1034 printf( "\tset scry [expr [winfo screenh $w] / 2]\n" );
1035 printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" );
1036 printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" );
1037 printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" );
1038 printf( "\t\t$w.config.canvas configure -height $canvtotal\n" );
1039 printf( "\t} else {\n" );
1040 printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" );
1041 printf( "\t\t}\n\t}\n" );
1044 * Limit the min/max window size. Height can vary, but not width,
1045 * because of the limitations of canvas and our laziness.
1047 printf( "\tupdate idletasks\n" );
1048 printf( "\tif {[winfo exists $w]} then {\n\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" );
1049 printf( "\twm minsize $w [winfo width $w] 100\n\n" );
1050 printf( "\twm deiconify $w\n" );
1051 printf( "}\n}\n\n" );
1054 * Now we generate the companion procedure for the menu we just
1055 * generated. This procedure contains all of the code to
1056 * disable/enable widgets based upon the settings of the other
1057 * widgets, and will be called first when the window is mapped,
1058 * and each time one of the buttons in the window are clicked.
1060 printf( "proc update_menu%d {} {\n", menu_num
);
1063 * Clear all of the booleans that are defined in this menu.
1065 clear_globalflags();
1066 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1068 if ( cfg
->menu_number
== menu_num
1069 && cfg
->token
!= token_mainmenu_option
1070 && cfg
->token
!= token_choice_item
)
1072 if ( cfg
->cond
!= NULL
)
1075 if ( (cfg
->token
== token_tristate
|| cfg
->token
== token_dep_tristate
)
1076 && ! vartable
[i
= get_varnum( "CONFIG_MODULES" )].global_written
)
1078 global( "CONFIG_MODULES" );
1079 vartable
[i
].global_written
= 1;
1081 generate_if( cfg
, cfg
->cond
, cfg
->menu_number
, cfg
->menu_line
);
1085 if ( cfg
->token
== token_tristate
)
1087 if ( ! vartable
[cfg
->nameindex
].global_written
)
1089 vartable
[cfg
->nameindex
].global_written
= 1;
1090 printf( "\tglobal %s\n", vartable
[cfg
->nameindex
].name
);
1092 if ( ! vartable
[i
= get_varnum( "CONFIG_MODULES" )].global_written
)
1094 global( "CONFIG_MODULES" );
1095 vartable
[i
].global_written
= 1;
1097 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",
1098 menu_num
, cfg
->menu_line
,
1099 menu_num
, cfg
->menu_line
);
1103 else if ( cfg
->token
== token_mainmenu_option
1104 && cfg
->menu_number
== menu_num
1105 && cfg
->cond
!= NULL
)
1107 generate_if( cfg
, cfg
->cond
, menu_num
, cfg
->menu_line
);
1112 generate_update_var( scfg
, menu_num
);
1116 * This is the top level function for generating the tk script.
1118 void dump_tk_script( struct kconfig
* scfg
)
1123 int top_level_num
= 0;
1124 struct kconfig
* cfg
;
1125 struct kconfig
* cfg1
= NULL
;
1126 const char * name
= "No Name";
1129 * Mark begin and end of each menu so I can omit submenus when walking
1130 * over a parent menu.
1136 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1138 switch ( cfg
->token
)
1143 case token_mainmenu_name
:
1147 case token_mainmenu_option
:
1148 if ( ++menu_depth
>= 64 )
1149 { fprintf( stderr
, "menus too deep\n" ); exit( 1 ); }
1150 if ( ++tot_menu_num
>= 100 )
1151 { fprintf( stderr
, "too many menus\n" ); exit( 1 ); }
1152 menu_num
[menu_depth
] = tot_menu_num
;
1153 menu_first
[tot_menu_num
] = cfg
;
1154 menu_last
[tot_menu_num
] = cfg
;
1156 * Note, that menu_number is set to the number of parent
1157 * (upper level) menu.
1159 cfg
->menu_number
= menu_num
[menu_depth
- 1];
1160 if ( menu_depth
== 1 )
1165 menu_last
[menu_num
[menu_depth
]] = cfg
;
1166 /* flatten menus with proper scoping */
1167 if ( --menu_depth
< 0 )
1168 { fprintf( stderr
, "unmatched endmenu\n" ); exit( 1 ); }
1172 case token_choice_header
:
1173 case token_choice_item
:
1175 case token_dep_bool
:
1176 case token_dep_tristate
:
1177 case token_dep_mbool
:
1181 case token_tristate
:
1182 cfg
->menu_number
= menu_num
[menu_depth
];
1183 if ( menu_depth
== 0 )
1184 { fprintf( stderr
, "statement not in menu\n" ); exit( 1 ); }
1187 case token_define_bool
:
1188 case token_define_hex
:
1189 case token_define_int
:
1190 case token_define_string
:
1191 case token_define_tristate
:
1193 cfg
->menu_number
= menu_num
[menu_depth
];
1199 * Generate menus per column setting.
1201 * four extra buttons for save/quit/load/store;
1203 * add two to round up for division
1205 printf( "set menus_per_column %d\n", (top_level_num
+ 4 + 1 + 2) / 3 );
1206 printf( "set total_menus %d\n\n", tot_menu_num
);
1208 printf( "proc toplevel_menu {num} {\n" );
1209 for ( imenu
= 1; imenu
<= tot_menu_num
; ++imenu
)
1213 if ( menu_first
[imenu
]->menu_number
== 0 )
1214 parent
= menu_first
[imenu
]->menu_number
;
1216 printf( "\tif {$num == %d} then {return %d}\n",
1217 imenu
, menu_first
[imenu
]->menu_number
);
1219 printf( "\treturn $num\n}\n\n" );
1222 * Generate the menus.
1224 printf( "mainmenu_name \"%s\"\n", name
);
1225 for ( imenu
= 1; imenu
<= tot_menu_num
; ++imenu
)
1228 int nr_submenu
= imenu
;
1229 int menu_name_omitted
= 0;
1232 clear_globalflags();
1233 start_proc( menu_first
[imenu
]->label
, imenu
,
1234 !menu_first
[imenu
]->menu_number
);
1236 for ( cfg
= menu_first
[imenu
]->next
; cfg
!= NULL
&& cfg
!= menu_last
[imenu
]; cfg
= cfg
->next
)
1238 switch ( cfg
->token
)
1243 case token_mainmenu_option
:
1244 while ( menu_first
[++nr_submenu
]->menu_number
> imenu
)
1246 cfg
->menu_line
= menu_line
++;
1247 printf( "\tsubmenu $w.config.f %d %d \"%s\" %d\n",
1248 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
, nr_submenu
);
1249 cfg
= menu_last
[nr_submenu
];
1253 if ( !cfg
->menu_line
&& !menu_name_omitted
)
1255 cfg
->menu_line
= -1;
1256 menu_name_omitted
= 1;
1260 menu_name_omitted
= 1;
1261 cfg
->menu_line
= menu_line
++;
1262 printf( "\tcomment $w.config.f %d %d \"%s\"\n",
1263 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
);
1268 cfg
->menu_line
= menu_line
++;
1269 printf( "\tbool $w.config.f %d %d \"%s\" %s\n",
1270 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1271 vartable
[cfg
->nameindex
].name
);
1274 case token_choice_header
:
1276 * I need the first token_choice_item to pick out the right
1277 * help text from Documentation/Configure.help.
1279 cfg
->menu_line
= menu_line
++;
1280 printf( "\tglobal tmpvar_%d\n", -(cfg
->nameindex
) );
1281 printf( "\tminimenu $w.config.f %d %d \"%s\" tmpvar_%d %s\n",
1282 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1283 -(cfg
->nameindex
), vartable
[cfg
->next
->nameindex
].name
);
1284 printf( "\tmenu $w.config.f.x%d.x.menu -tearoffcommand \"menutitle \\\"%s\\\"\"\n",
1285 cfg
->menu_line
, cfg
->label
);
1290 case token_choice_item
:
1291 /* note: no menu line; uses choice header menu line */
1292 printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable tmpvar_%d -value \"%s\" -command \"update_active\"\n",
1293 cfg1
->menu_line
, cfg
->label
, -(cfg1
->nameindex
),
1296 if ( cfg
->next
&& cfg
->next
->token
!= token_choice_item
) {
1297 /* last option in the menu */
1298 printf( "\tmenusplit $w $w.config.f.x%d.x.menu %d\n",
1299 cfg1
->menu_line
, opt_count
);
1303 case token_dep_bool
:
1304 case token_dep_mbool
:
1305 cfg
->menu_line
= menu_line
++;
1306 printf( "\tdep_bool $w.config.f %d %d \"%s\" %s\n",
1307 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1308 vartable
[cfg
->nameindex
].name
);
1311 case token_dep_tristate
:
1312 cfg
->menu_line
= menu_line
++;
1313 printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s\n",
1314 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1315 vartable
[cfg
->nameindex
].name
);
1319 cfg
->menu_line
= menu_line
++;
1320 printf( "\thex $w.config.f %d %d \"%s\" %s\n",
1321 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1322 vartable
[cfg
->nameindex
].name
);
1326 cfg
->menu_line
= menu_line
++;
1327 printf( "\tint $w.config.f %d %d \"%s\" %s\n",
1328 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1329 vartable
[cfg
->nameindex
].name
);
1333 cfg
->menu_line
= menu_line
++;
1334 printf( "\tistring $w.config.f %d %d \"%s\" %s\n",
1335 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1336 vartable
[cfg
->nameindex
].name
);
1339 case token_tristate
:
1340 cfg
->menu_line
= menu_line
++;
1341 printf( "\ttristate $w.config.f %d %d \"%s\" %s\n",
1342 cfg
->menu_number
, cfg
->menu_line
, cfg
->label
,
1343 vartable
[cfg
->nameindex
].name
);
1348 end_proc( scfg
, imenu
);
1352 * The top level menu also needs an update function. When we update a
1353 * submenu, we may need to disable one or more of the submenus on
1354 * the top level menu, and this procedure will ensure that things are
1357 clear_globalflags();
1358 printf( "proc update_mainmenu {} {\n" );
1359 for ( imenu
= 1; imenu
<= tot_menu_num
; imenu
++ )
1361 if ( menu_first
[imenu
]->cond
!= NULL
&& menu_first
[imenu
]->menu_number
== 0 )
1362 generate_if( menu_first
[imenu
], menu_first
[imenu
]->cond
, imenu
, -1 );
1364 printf( "}\n\n\n" );
1366 clear_globalflags();
1368 * Generate code to load the default settings into the variables.
1369 * The script in tail.tk will attempt to load .config,
1370 * which may override these settings, but that's OK.
1372 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1374 switch ( cfg
->token
)
1380 case token_choice_item
:
1381 case token_dep_bool
:
1382 case token_dep_tristate
:
1383 case token_dep_mbool
:
1384 case token_tristate
:
1385 if ( ! vartable
[cfg
->nameindex
].global_written
)
1387 printf( "set %s 0\n", vartable
[cfg
->nameindex
].name
);
1388 vartable
[cfg
->nameindex
].global_written
= 1;
1392 case token_choice_header
:
1393 printf( "set tmpvar_%d \"(not set)\"\n", -(cfg
->nameindex
) );
1398 if ( ! vartable
[cfg
->nameindex
].global_written
)
1400 printf( "set %s %s\n", vartable
[cfg
->nameindex
].name
, cfg
->value
? cfg
->value
: "0" );
1401 vartable
[cfg
->nameindex
].global_written
= 1;
1406 if ( ! vartable
[cfg
->nameindex
].global_written
)
1408 printf( "set %s \"%s\"\n", vartable
[cfg
->nameindex
].name
, cfg
->value
);
1409 vartable
[cfg
->nameindex
].global_written
= 1;
1416 * Define to an empty value all other variables (which are never defined)
1418 for ( i
= 1; i
<= max_varnum
; i
++ )
1420 if ( ! vartable
[i
].global_written
1421 && strncmp( vartable
[i
].name
, "CONSTANT_", 9 ) )
1422 printf( "set %s 4\n", vartable
[i
].name
);
1426 * Generate a function to write all of the variables to a file.
1428 printf( "proc writeconfig {file1 file2} {\n" );
1429 printf( "\tset cfg [open $file1 w]\n" );
1430 printf( "\tset autocfg [open $file2 w]\n" );
1431 printf( "\tset notmod 1\n" );
1432 printf( "\tset notset 0\n" );
1433 printf( "\tputs $cfg \"#\"\n");
1434 printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n");
1435 printf( "\tputs $cfg \"#\"\n" );
1437 printf( "\tputs $autocfg \"/*\"\n" );
1438 printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" );
1439 printf( "\tputs $autocfg \" */\"\n" );
1440 printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" );
1442 clear_globalflags();
1443 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1445 switch ( cfg
->token
)
1451 case token_choice_header
:
1453 case token_define_bool
:
1454 case token_define_hex
:
1455 case token_define_int
:
1456 case token_define_string
:
1457 case token_define_tristate
:
1458 case token_dep_bool
:
1459 case token_dep_tristate
:
1460 case token_dep_mbool
:
1464 case token_tristate
:
1465 generate_writeconfig( cfg
);
1469 printf( "\tclose $cfg\n" );
1470 printf( "\tclose $autocfg\n" );
1471 printf( "}\n\n\n" );
1474 * Generate a simple function that updates the master choice
1475 * variable depending upon what values were loaded from a .config
1478 printf( "proc clear_choices { } {\n" );
1479 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1481 if ( cfg
->token
== token_choice_header
)
1483 for ( cfg1
= cfg
->next
;
1484 cfg1
!= NULL
&& cfg1
->token
== token_choice_item
;
1487 printf( "\tglobal %s; set %s 0\n",
1488 vartable
[cfg1
->nameindex
].name
,
1489 vartable
[cfg1
->nameindex
].name
);
1493 printf( "}\n\n\n" );
1495 printf( "proc update_choices { } {\n" );
1496 for ( cfg
= scfg
; cfg
!= NULL
; cfg
= cfg
->next
)
1498 if ( cfg
->token
== token_choice_header
)
1500 printf( "\tglobal tmpvar_%d\n", -(cfg
->nameindex
) );
1501 printf("\tset tmpvar_%d \"%s\"\n", -(cfg
->nameindex
), cfg
->value
);
1502 for ( cfg1
= cfg
->next
;
1503 cfg1
!= NULL
&& cfg1
->token
== token_choice_item
;
1506 printf( "\tglobal %s\n", vartable
[cfg1
->nameindex
].name
);
1507 printf( "\tif { $%s == 1 } then { set tmpvar_%d \"%s\" }\n",
1508 vartable
[cfg1
->nameindex
].name
,
1509 -(cfg
->nameindex
), cfg1
->label
);
1513 printf( "}\n\n\n" );
1515 generate_update_var( scfg
, 0 );
1518 * That's it. We are done. The output of this file will have header.tk
1519 * prepended and tail.tk appended to create an executable wish script.