root/scripts/tkgen.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. start_proc
  2. clear_globalflags
  3. generate_if
  4. generate_if_for_outfile
  5. end_proc
  6. find_menu_size
  7. dump_tk_script

   1 /* Generate tk script based upon config.in
   2  *
   3  * Version 1.0
   4  * Eric Youngdale
   5  * 10/95
   6  */
   7 #include <stdio.h>
   8 #include "tkparse.h"
   9 
  10 #ifndef TRUE
  11 #define TRUE (1)
  12 #endif
  13 
  14 #ifndef FALSE
  15 #define FALSE (0)
  16 #endif
  17 
  18 /*
  19  * This prevents the Prev/Next buttons from going through the entire sequence
  20  * of submenus.  I need to fix the window titles before it would really be
  21  * appropriate to enable this.
  22  */
  23 /* #define PREVLAST_LIMITED_RANGE */
  24 
  25 /*
  26  * This is the total number of submenus that we have.
  27  */
  28 static int tot_menu_num =0;
  29 
  30 /*
  31  * Generate portion of wish script for the beginning of a submenu.
  32  * The guts get filled in with the various options.
  33  */
  34 static start_proc(char * label, int menu_num, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
  35 {
  36   if( flag )
  37     printf("menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label);
  38   printf("proc menu%d {w title} {\n", menu_num);
  39   printf("\tcatch {destroy $w}\n");
  40   printf("\ttoplevel $w -class Dialog\n");
  41   printf("\tmessage $w.m -width 400 -aspect 300 -background grey -text \\\n");
  42   printf("\t\t\"%s\"  -relief raised -bg grey\n",label);
  43   printf("\tpack $w.m -pady 10 -side top -padx 10\n");
  44   printf("\twm title $w \"%s\" \n\n\n", label);
  45 }
  46 
  47 /*
  48  * Each proc we create needs a global declaration for any global variables we
  49  * use.  To minimize the size of the file, we set a flag each time we output
  50  * a global declaration so we know whether we need to insert one for a
  51  * given function or not.
  52  */
  53 clear_globalflags(struct kconfig * cfg)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55   for(; cfg != NULL; cfg = cfg->next)
  56   {
  57     cfg->flags &= ~GLOBAL_WRITTEN;
  58   }
  59 }
  60 
  61 /*
  62  * This function walks the chain of conditions that we got from cond.c,
  63  * and creates a wish conditional to enable/disable a given widget.
  64  */
  65 generate_if(struct kconfig * item,
     /* [previous][next][first][last][top][bottom][index][help] */
  66             struct condition * cond,
  67             int menu_num,
  68             int line_num)
  69 {
  70   struct condition * ocond;
  71 
  72   /*
  73    * First write any global declarations we need for this conditional.
  74    */
  75   ocond = cond;
  76   while(cond != NULL )
  77     {
  78       switch(cond->op){
  79       case op_variable:
  80         printf("\tglobal %s\n", cond->variable.str);
  81         break;
  82       case op_kvariable:
  83         if(cond->variable.cfg->flags & GLOBAL_WRITTEN) break;
  84         cond->variable.cfg->flags |= GLOBAL_WRITTEN;
  85         printf("\tglobal %s\n", cond->variable.cfg->optionname);
  86         break;
  87       default:
  88         break;
  89       }
  90       cond = cond->next;
  91     }
  92 
  93   /*
  94    * Now write this option.
  95    */
  96   if( (item->flags & GLOBAL_WRITTEN) == 0)
  97     {
  98         printf("\tglobal %s\n", item->optionname);
  99     }
 100 
 101   /*
 102    * Now generate the body of the conditional.
 103    */
 104   printf("\tif {");
 105   cond = ocond;
 106   while(cond != NULL )
 107     {
 108       switch(cond->op){
 109       case op_bang:
 110         printf(" ! ");
 111         break;
 112       case op_eq:
 113         printf(" == ");
 114         break;
 115       case op_neq:
 116         printf(" != ");
 117         break;
 118       case op_and:
 119         printf(" && ");
 120         break;
 121       case op_or:
 122         printf(" || ");
 123         break;
 124       case op_lparen:
 125         printf("(");
 126         break;
 127       case op_rparen:
 128         printf(")");
 129         break;
 130       case op_variable:
 131         printf("$%s", cond->variable.str);
 132         break;
 133       case op_kvariable:
 134         printf("$%s", cond->variable.cfg->optionname);
 135         break;
 136       case op_constant:
 137         if( strcmp(cond->variable.str, "y") == 0 )
 138           printf("1");
 139         else if( strcmp(cond->variable.str, "n") == 0 )
 140           printf("0");
 141         else if( strcmp(cond->variable.str, "m") == 0 )
 142           printf("2");
 143         else
 144           printf("'%s'", cond->variable);
 145         break;
 146       }
 147       cond = cond->next;
 148     }
 149 
 150   /*
 151    * Now we generate what we do depending upon the value of the conditional.
 152    * Depending upon what the token type is, there are different things
 153    * we must do to enable/disable the given widget - this code needs to
 154    * be closely coordinated with the widget creation procedures in header.tk.
 155    */
 156   switch(item->tok)
 157     {
 158     case tok_menuoption:
 159       printf("} then { .f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n",
 160              menu_num, menu_num);
 161       break;
 162     case tok_int:
 163       printf("} then { ");
 164       printf(".menu%d.x%d.x configure -state normal; ", menu_num, line_num);
 165       printf(".menu%d.x%d.l configure -state normal; ", menu_num, line_num);
 166       printf("} else { ");
 167       printf(".menu%d.x%d.x configure -state disabled;", menu_num, line_num );
 168       printf(".menu%d.x%d.l configure -state disabled;", menu_num, line_num );
 169       printf("}\n");
 170       break;
 171     case tok_bool:
 172 #ifdef BOOL_IS_BUTTON
 173       /*
 174        * If a bool is just a button, then use this definition.
 175        */
 176       printf("} then { .menu%d.x%d configure -state normal } else { .menu%d.x%d configure -state disabled }\n",
 177              menu_num, line_num,
 178              menu_num, line_num );
 179 #else
 180       /*
 181        * If a bool is a radiobutton, then use this instead.
 182        */
 183       printf("} then { ");
 184       printf(".menu%d.x%d.y configure -state normal;",menu_num, line_num);
 185       printf(".menu%d.x%d.n configure -state normal;",menu_num, line_num);
 186       printf(".menu%d.x%d.l configure -state normal;",menu_num, line_num);
 187       printf("set %s [expr $%s&15];", item->optionname, item->optionname);
 188       printf("} else { ");
 189       printf(".menu%d.x%d.y configure -state disabled;",menu_num, line_num);
 190       printf(".menu%d.x%d.n configure -state disabled;",menu_num, line_num);
 191       printf(".menu%d.x%d.l configure -state disabled;",menu_num, line_num);
 192       printf("set %s [ expr $%s | 16 ];", item->optionname, item->optionname);
 193       printf("}\n");
 194 #endif
 195       break;
 196     case tok_tristate:
 197     case tok_dep_tristate:
 198       printf("} then { ");
 199       if( item->tok == tok_dep_tristate )
 200         {
 201           printf("if { $%s == 2 } then {", item->depend.str);
 202           printf(".menu%d.x%d.y configure -state disabled;",menu_num, line_num);
 203           printf("} else {");
 204           printf(".menu%d.x%d.y configure -state normal;",menu_num, line_num);
 205           printf("}; ");
 206         }
 207       else
 208         {
 209           printf(".menu%d.x%d.y configure -state normal;",menu_num, line_num);
 210         }
 211       
 212       printf(".menu%d.x%d.n configure -state normal;",menu_num, line_num);
 213       printf(".menu%d.x%d.m configure -state normal;",menu_num, line_num);
 214       printf(".menu%d.x%d.l configure -state normal;",menu_num, line_num);
 215       /*
 216        * Or in a bit to the variable - this causes all of the radiobuttons
 217        * to be deselected (i.e. not be red).
 218        */
 219       printf("set %s [expr $%s&15];", item->optionname, item->optionname);
 220       printf("} else { ");
 221       printf(".menu%d.x%d.y configure -state disabled;",menu_num, line_num);
 222       printf(".menu%d.x%d.n configure -state disabled;",menu_num, line_num);
 223       printf(".menu%d.x%d.m configure -state disabled;",menu_num, line_num);
 224       printf(".menu%d.x%d.l configure -state disabled;",menu_num, line_num);
 225       /*
 226        * Clear the disable bit - this causes the correct radiobutton
 227        * to appear selected (i.e. turn red).
 228        */
 229       printf("set %s [expr $%s|16];", item->optionname, item->optionname);
 230       printf("}\n");
 231       break;
 232     default:
 233       break;
 234     }
 235 }
 236 
 237 /*
 238  * Similar to generate_if, except we come here when generating an
 239  * output file.  Thus instead of enabling/disabling a widget, we
 240  * need to decide whether to write out a given configuration variable
 241  * to the output file.
 242  */
 243 generate_if_for_outfile(struct kconfig * item,
     /* [previous][next][first][last][top][bottom][index][help] */
 244             struct condition * cond)
 245 {
 246   struct condition * ocond;
 247 
 248   /*
 249    * First write any global declarations we need for this conditional.
 250    */
 251   ocond = cond;
 252   for(; cond != NULL; cond = cond->next )
 253     {
 254       switch(cond->op){
 255       case op_variable:
 256         printf("\tglobal %s\n", cond->variable.str);
 257         break;
 258       case op_kvariable:
 259         if(cond->variable.cfg->flags & GLOBAL_WRITTEN) break;
 260         cond->variable.cfg->flags |= GLOBAL_WRITTEN;
 261         printf("\tglobal %s\n", cond->variable.cfg->optionname);
 262         break;
 263       default:
 264         break;
 265       }
 266     }
 267 
 268   /*
 269    * Now generate the body of the conditional.
 270    */
 271   printf("\tif {");
 272   cond = ocond;
 273   while(cond != NULL )
 274     {
 275       switch(cond->op){
 276       case op_bang:
 277         printf(" ! ");
 278         break;
 279       case op_eq:
 280         printf(" == ");
 281         break;
 282       case op_neq:
 283         printf(" != ");
 284         break;
 285       case op_and:
 286         printf(" && ");
 287         break;
 288       case op_or:
 289         printf(" || ");
 290         break;
 291       case op_lparen:
 292         printf("(");
 293         break;
 294       case op_rparen:
 295         printf(")");
 296         break;
 297       case op_variable:
 298         printf("$%s", cond->variable.str);
 299         break;
 300       case op_kvariable:
 301         printf("$%s", cond->variable.cfg->optionname);
 302         break;
 303       case op_constant:
 304         if( strcmp(cond->variable.str, "y") == 0 )
 305           printf("1");
 306         else if( strcmp(cond->variable.str, "n") == 0 )
 307           printf("0");
 308         else if( strcmp(cond->variable.str, "m") == 0 )
 309           printf("2");
 310         else
 311           printf("'%s'", cond->variable);
 312         break;
 313       }
 314       cond = cond->next;
 315     }
 316 
 317   /*
 318    * Now we generate what we do depending upon the value of the
 319    * conditional.  Depending upon what the token type is, there are
 320    * different things we must do write the value the given widget -
 321    * this code needs to be closely coordinated with the widget
 322    * creation procedures in header.tk.  
 323    */
 324   switch(item->tok)
 325     {
 326     case tok_comment:
 327       printf("} then {write_comment $cfg $autocfg \"%s\"}\n", item->label);
 328       break;
 329     case tok_dep_tristate:
 330       printf("} then { write_variable $cfg $autocfg %s $%s $%s } \n", 
 331              item->optionname, item->optionname, item->depend.str);
 332       break;
 333     case tok_tristate:
 334     case tok_bool:
 335     case tok_int:
 336       printf("} then { write_variable $cfg $autocfg %s $%s $notmod }\n", 
 337              item->optionname, item->optionname);
 338       break;
 339     default:
 340       break;
 341     }
 342 }
 343 
 344 /*
 345  * Generates a fragment of wish script that closes out a submenu procedure.
 346  */
 347 static end_proc(int menu_num, int first, int last)
     /* [previous][next][first][last][top][bottom][index][help] */
 348 {
 349   struct kconfig * cfg;
 350 
 351   printf("\n\n\n");
 352   printf("\tset oldFocus [focus]\n");
 353   printf("\tframe $w.f\n");
 354 
 355   /*
 356    * Attach the "Prev", "Next" and "OK" buttons at the end of the window.
 357    */
 358   printf("\tbutton $w.f.prev -text \"Prev\" -activebackground green \\\n");
 359       printf("\t\t-width 15 -command \" destroy $w; focus $oldFocus; menu%d .menu%d \\\"$title\\\"\"\n", menu_num-1, menu_num-1);
 360 #ifdef PREVLAST_LIMITED_RANGE
 361   if(first == menu_num ) printf("\t$w.f.prev configure -state disabled\n");
 362 #else
 363   if( 1 == menu_num ) printf("\t$w.f.prev configure -state disabled\n");
 364 #endif
 365 
 366   printf("\tbutton $w.f.next -text \"Next\" -activebackground green \\\n");
 367   printf("\t\t-width 15 -command \" destroy $w; focus $oldFocus;  menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1);
 368 #ifdef PREVLAST_LIMITED_RANGE
 369   if(last == menu_num ) printf("\t$w.f.next configure -state disabled\n");
 370 #else
 371   if(last == tot_menu_num ) printf("\t$w.f.next configure -state disabled\n");
 372 #endif
 373 
 374   printf("\tbutton $w.f.back -text \"Main Menu\" -activebackground green \\\n");
 375   printf("\t\t-width 15 -command \"destroy $w; focus $oldFocus; update_mainmenu $w\"\n");
 376 
 377   printf("\tpack $w.f.back $w.f.next $w.f.prev -side left -pady 10 -padx 45\n");
 378   printf("\tpack $w.f -pady 10 -side top -padx 10 -anchor w\n");
 379   printf("\tfocus $w\n");
 380   printf("\tupdate_menu%d $w\n", menu_num);
 381   printf("\tglobal winx; global winy\n");
 382   printf("\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n");
 383   printf("\twm geometry $w +$winx+$winy\n");
 384   printf("}\n\n\n");
 385 
 386   /*
 387    * Now we generate the companion procedure for the muen we just
 388    * generated.  This procedure contains all of the code to
 389    * disable/enable widgets based upon the settings of the other
 390    * widgets, and will be called first when the window is mapped,
 391    * and each time one of the buttons in the window are clicked.
 392    */
 393   printf("proc update_menu%d {w}  {\n", menu_num);
 394 
 395   clear_globalflags(config);
 396   for(cfg = config;cfg != NULL; cfg = cfg->next)
 397     {
 398       /*
 399        * Skip items not for this menu, or ones having no conditions.
 400        */
 401       if (cfg->menu_number != menu_num ) continue;
 402       if (cfg->tok == tok_menuoption) continue;
 403       if (cfg->cond != NULL ) 
 404         generate_if(cfg, cfg->cond, menu_num, cfg->menu_line);
 405       else
 406         {
 407           /*
 408            * If this token has no conditionals, check to see whether
 409            * it is a tristate - if so, then generate the conditional
 410            * to enable/disable the "y" button based upon the setting
 411            * of the option it depends upon.
 412            */
 413           if(cfg->tok == tok_dep_tristate)
 414             {
 415               printf("\tif {$%s == 2 } then { .menu3.x5.y configure -state normal} else { .menu3.x5.y configure -state disabled}\n",cfg->depend.str,
 416                      menu_num, cfg->menu_line,
 417                      menu_num, cfg->menu_line);
 418               
 419             }
 420         }
 421 
 422     }
 423 
 424 
 425   printf("}\n\n\n");
 426 }
 427 
 428 /*
 429  * This function goes through and counts up the number of items in
 430  * each submenu. If there are too many options, we need to split it
 431  * into submenus.  This function just calculates how many submenus,
 432  * and how many items go in each submenu.
 433  */
 434 static int find_menu_size(struct kconfig *cfg,
     /* [previous][next][first][last][top][bottom][index][help] */
 435                           int *menu_max, 
 436                           int *menu_maxlines)
 437 
 438 {
 439   struct kconfig * pnt;
 440   int tot;
 441   int div;
 442   
 443   /*
 444    * First count up the number of options in this menu.
 445    */
 446   tot = 0;
 447   for(pnt = cfg->next; pnt; pnt = pnt->next)
 448   {
 449     if( pnt->tok == tok_menuoption) break;
 450     switch (pnt->tok)
 451       {
 452       case tok_bool:
 453       case tok_tristate:
 454       case tok_dep_tristate:
 455       case tok_int:
 456         tot++;
 457         break;
 458       default:
 459         break;
 460       }
 461   }
 462 
 463   /*
 464    * Now figure out how many items go on each page.
 465    */
 466   div = 1;
 467   while(tot / div > 15) div++;
 468   *menu_max = cfg->menu_number + div - 1;
 469   *menu_maxlines = (tot + div -1) / div;
 470 }
 471 
 472 /*
 473  * This is the top level function for generating the tk script.
 474  */
 475 dump_tk_script(struct kconfig *scfg)
     /* [previous][next][first][last][top][bottom][index][help] */
 476 {
 477   int menu_num =0;
 478   int menu_max =0;
 479   int menu_min =0;
 480   int menu_line = 0;
 481   int menu_maxlines = 0;
 482   struct kconfig * cfg;
 483   char * menulabel;
 484 
 485   /*
 486    * Start by assigning menu numbers, and submenu numbers.
 487    */
 488   for(cfg = scfg;cfg != NULL; cfg = cfg->next)
 489     {
 490       switch (cfg->tok)
 491         {
 492         case tok_menuname:
 493           break;
 494         case tok_menuoption:
 495           /*
 496            * At the start of a new menu, calculate the number of items
 497            * we will put into each submenu so we know when to bump the
 498            * menu number. The submenus are really no different from a
 499            * normal menu, but the top level buttons only access the first
 500            * of the chain of menus, and the prev/next buttons are used
 501            * access the submenus.
 502            */
 503           cfg->menu_number = ++menu_num;
 504           find_menu_size(cfg, &menu_max, &menu_maxlines);
 505           cfg->submenu_start = menu_num;
 506           cfg->submenu_end = menu_max;
 507           menu_line = 0;
 508           break;
 509         case tok_bool:
 510         case tok_tristate:
 511         case tok_dep_tristate:
 512         case tok_int:
 513           /*
 514            * If we have overfilled the menu, then go to the next one.
 515            */
 516           if( menu_line == menu_maxlines )
 517             {
 518               menu_line = 0;
 519               menu_num++;
 520             }
 521           cfg->menu_number = menu_num;
 522           cfg->submenu_start = menu_min;
 523           cfg->submenu_end = menu_max;
 524           cfg->menu_line = menu_line++;
 525           break;
 526         default:
 527           break;
 528         };
 529     }
 530 
 531   /*
 532    * Record this so we can set up the prev/next buttons correctly.
 533    * We will be adding one more menu for sound configuration, so
 534    * take this into account.
 535    */
 536   tot_menu_num = menu_num+1;
 537 
 538   /*
 539    * Now start generating the actual wish script that we will use.
 540    * We need to keep track of the menu numbers of the min/max menu
 541    * for a range of submenus so that we can correctly limit the
 542    * prev and next buttons so that they don't go over into some other
 543    * category.
 544    */
 545   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
 546     {
 547       switch (cfg->tok)
 548         {
 549         case tok_menuname:
 550           printf("mainmenu_name \"%s\"\n", cfg->label);
 551           break;
 552         case tok_menuoption:
 553           /*
 554            * We are at the start of a new menu. If we had one that
 555            * we were working on before, close it out, and then generate
 556            * the script to start the new one.
 557            */
 558           if( cfg->menu_number > 1 )
 559             {
 560               end_proc(menu_num, menu_min, menu_max);
 561             }
 562           menulabel = cfg->label;
 563           start_proc(cfg->label, cfg->menu_number, TRUE);
 564           menu_num = cfg->menu_number;
 565           menu_max = cfg->submenu_end;
 566           menu_min = cfg->submenu_start;
 567           break;
 568         case tok_bool:
 569           /*
 570            * If we reached the point where we need to switch over
 571            * to the next submenu, then bump the menu number and generate
 572            * the code to close out the old menu and start the new one.
 573            */
 574           if( cfg->menu_number != menu_num )
 575             {
 576               end_proc(menu_num, menu_min, menu_max);
 577               start_proc(menulabel, cfg->menu_number, FALSE);
 578               menu_num = cfg->menu_number;
 579             }
 580           printf("\tbool $w %d %d \"%s\" %s %s\n",
 581                  cfg->menu_number,
 582                  cfg->menu_line,
 583                  cfg->label,
 584                  cfg->optionname,
 585                  cfg->dflt);
 586           break;
 587 
 588         case tok_tristate:
 589           if( cfg->menu_number != menu_num )
 590             {
 591               end_proc(menu_num, menu_min, menu_max);
 592               start_proc(menulabel, cfg->menu_number, FALSE);
 593               menu_num = cfg->menu_number;
 594             }
 595           printf("\ttristate $w %d %d \"%s\" %s %s\n",
 596                  cfg->menu_number,
 597                  cfg->menu_line,
 598                  cfg->label,
 599                  cfg->optionname,
 600                  cfg->dflt);
 601           break;
 602         case tok_dep_tristate:
 603           if( cfg->menu_number != menu_num )
 604             {
 605               end_proc(menu_num, menu_min, menu_max);
 606               start_proc(menulabel, cfg->menu_number, FALSE);
 607               menu_num = cfg->menu_number;
 608             }
 609           printf("\tdep_tristate $w %d %d \"%s\" %s %s\n",
 610                  cfg->menu_number,
 611                  cfg->menu_line,
 612                  cfg->label,
 613                  cfg->optionname,
 614                  cfg->dflt,
 615                  cfg->depend);
 616           break;
 617         case tok_int:
 618           if( cfg->menu_number != menu_num )
 619             {
 620               end_proc(menu_num, menu_min, menu_max);
 621               start_proc(menulabel, cfg->menu_number, FALSE);
 622               menu_num = cfg->menu_number;
 623             }
 624           printf("\tint $w %d %d \"%s\" %s %s\n",
 625                  cfg->menu_number,
 626                  cfg->menu_line,
 627                  cfg->label,
 628                  cfg->optionname,
 629                  cfg->dflt);
 630         default:
 631           break;
 632         }
 633 
 634     }
 635 
 636   /*
 637    * Generate the code to close out the last menu.
 638    */
 639   end_proc(menu_num, menu_min, menu_max);
 640 
 641   /*
 642    * Generate the code for configuring the sound driver.  Right now this
 643    * cannot be done from the X script, but we insert the menu anyways.
 644    */
 645   start_proc("Configure sound driver", ++menu_num, TRUE);
 646 #if 0
 647   printf("\tdo_make -C drivers/sound config\n");
 648   printf("\techo check_sound_config %d\n",menu_num);
 649 #endif
 650   printf("\tlabel $w.m0 -bitmap error\n");
 651   printf("\tmessage $w.m1 -width 400 -aspect 300 -text \"The sound drivers cannot as of yet be configured via the X-based interface\" -relief raised\n");
 652   printf("\tpack $w.m0 $w.m1 -side top -pady 10\n");
 653 
 654   /*
 655    * Close out the last menu.
 656    */
 657   end_proc(menu_num, menu_num, menu_num);
 658 
 659   /*
 660    * The top level menu also needs an update function.  When we exit a
 661    * submenu, we may need to disable one or more of the submenus on
 662    * the top level menu, and this procedure will ensure that things are
 663    * correct.
 664    */
 665   printf("proc update_mainmenu {w}  {\n");
 666   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
 667     {
 668       switch (cfg->tok)
 669         {
 670         case tok_menuoption:
 671           if (cfg->cond != NULL ) 
 672             generate_if(cfg, cfg->cond, cfg->menu_number, cfg->menu_line);
 673           break;
 674         default:
 675           break;
 676         }
 677     }
 678 
 679   printf("}\n\n\n");
 680 
 681   /*
 682    * Now generate code to load the default settings into the variables.
 683    * Note that the script in tail.tk will attempt to load .config,
 684    * which may override these settings, but that's OK.
 685    */
 686   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
 687     {
 688       switch (cfg->tok)
 689         {
 690         case tok_int:
 691             printf("set %s %s\n", cfg->optionname, cfg->dflt);
 692             break;
 693         case tok_bool:
 694         case tok_tristate:
 695         case tok_dep_tristate:
 696           if( strcmp(cfg->dflt, "y") == 0 )
 697             printf("set %s 1\n", cfg->optionname);
 698           else if( strcmp(cfg->dflt, "n") == 0 )
 699             printf("set %s 0\n", cfg->optionname);
 700           else if( strcmp(cfg->dflt, "m") == 0 )
 701             printf("set %s 2\n", cfg->optionname);
 702           break;
 703         default:
 704           break;
 705         }
 706     }
 707 
 708   /*
 709    * Next generate a function that can be called from the main menu that will
 710    * write all of the variables out.  This also serves double duty - we can
 711    * save configuration to a file using this.
 712    */
 713   printf("proc writeconfig {file1 file2} {\n");
 714   printf("\tset cfg [open $file1 w]\n");
 715   printf("\tset autocfg [open $file2 w]\n");
 716   printf("\tset notmod 1\n");
 717   printf("\tset notset 0\n");
 718   clear_globalflags(config);
 719   printf("\tputs $cfg \"#\"\n");
 720   printf("\tputs $cfg \"# Automatically generated make config: don't edit\"\n");
 721   printf("\tputs $cfg \"#\"\n");
 722 
 723   printf("\tputs $autocfg \"/*\"\n");
 724   printf("\tputs $autocfg \" * Automatically generated C config: don't edit\"\n");
 725   printf("\tputs $autocfg \" */\"\n");
 726   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
 727     {
 728       switch (cfg->tok)
 729         {
 730         case tok_int:
 731         case tok_bool:
 732         case tok_tristate:
 733         case tok_dep_tristate:
 734           if(cfg->flags & GLOBAL_WRITTEN) break;
 735           cfg->flags |= GLOBAL_WRITTEN;
 736           printf("\tglobal %s\n", cfg->optionname);
 737 
 738         case tok_comment:
 739           if (cfg->cond != NULL ) 
 740             generate_if_for_outfile(cfg, cfg->cond);
 741           else
 742             {
 743               if(cfg->tok == tok_dep_tristate)
 744                 {
 745                   printf("\tif {$%s == 2 } then { write_variable $cfg $autocfg %s $%s %s } else { write_variable $cfg $autocfg %s $notset $notmod }\n",
 746                          cfg->optionname,
 747                          cfg->optionname,
 748                          cfg->depend.str,
 749                          cfg->optionname);
 750                 }
 751               else if(cfg->tok == tok_comment)
 752                 {
 753                   printf("\twrite_comment $cfg $autocfg \"%s\"\n", cfg->label);
 754                 }
 755               else
 756                 {
 757                   printf("\twrite_variable $cfg $autocfg %s $%s $notmod\n",
 758                          cfg->optionname,
 759                          cfg->optionname);
 760                          
 761                 }
 762             }
 763           break;
 764         default:
 765           break;
 766         }
 767     }
 768   printf("\tclose $cfg\n");
 769   printf("\tclose $autocfg\n");
 770   printf("}\n\n\n");
 771 
 772   /*
 773    * That's it.  We are done.  The output of this file will have header.tk
 774    * prepended and tail.tk appended to create an executable wish script.
 775    */
 776 }

/* [previous][next][first][last][top][bottom][index][help] */