?? tkgen.c
字號:
/* Generate tk script based upon config.in * * Version 1.0 * Eric Youngdale * 10/95 * * 1996 01 04 * Avery Pennarun - Aesthetic improvements. * * 1996 01 24 * Avery Pennarun - Bugfixes and more aesthetics. * * 1996 03 08 * Avery Pennarun - The int and hex config.in commands work right. * - Choice buttons are more user-friendly. * - Disabling a text entry line greys it out properly. * - dep_tristate now works like in Configure. (not pretty) * - No warnings in gcc -Wall. (Fixed some "interesting" bugs.) * - Faster/prettier "Help" lookups. * * 1996 03 15 * Avery Pennarun - Added new sed script from Axel Boldt to make help even * faster. (Actually awk is downright slow on some machines.) * - Fixed a bug I introduced into Choice dependencies. Thanks * to Robert Krawitz for pointing this out. * * 1996 03 16 * Avery Pennarun - basic "do_make" support added to let sound config work. * * 1996 03 25 * Axel Boldt - Help now works on "choice" buttons. * * 1996 04 06 * Avery Pennarun - Improved sound config stuff. (I think it actually works * now!) * - Window-resize-limits don't use ugly /usr/lib/tk4.0 hack. * - int/hex work with tk3 again. (The "cget" error.) * - Next/Prev buttons switch between menus. I can't take * much credit for this; the code was already there, but * ifdef'd out for some reason. It flickers a lot, but * I suspect there's no "easy" fix for that. * - Labels no longer highlight as you move the mouse over * them (although you can still press them... oh well.) * - Got rid of the last of the literal color settings, to * help out people with mono X-Windows systems. * (Apparently there still are some out there!) * - Tabstops seem sensible now. * * 1996 04 14 * Avery Pennarun - Reduced flicker when creating windows, even with "update * idletasks" hack. * * 1997 12 08 * Michael Chastain - Remove sound driver special cases. * * 1997 11 15 * Michael Chastain - For choice buttons, write values for all options, * not just the single chosen one. This is compatible * with 'make config' and 'make oldconfig', and is * needed so smart-config dependencies work if the * user switches from one configuration method to * another. * * 1998 03 09 * Axel Boldt - Smaller layout of main menu - it's still too big for 800x600. * - Display help in text window to allow for cut and paste. * - Allow for empty lines in help texts. * - update_define should not set all variables unconditionally to * 0: they may have been set to 1 elsewhere. CONFIG_NETLINK is * an example. * * 1999 01 04 * Michael Elizabeth Chastain <mec@shout.net> * - Call clear_globalflags when writing out update_mainmenu. * This fixes the missing global/vfix lines for ARCH=alpha on 2.2.0-pre4. * * 8 January 1999, Michael Elizabeth Chastain <mec@shout.net> * - Emit menus_per_column * * 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. * - Fix flattening of nested menus. The old code simply assigned items to * the most recent token_mainmenu_option, without paying attention to scope. * For example: "menu-1 bool-a menu-2 bool-b endmenu bool-c bool-d endmenu". * The old code would put bool-a in menu-1, bool-b in menu-2, and bool-c * and bool-d in *menu-2*. This hosed the nested submenus in * drives/net/Config.in and other places. * - Fix menu line wraparound at 128 menus (some fool used a 'char' for * a counter). * * 23 January 1999, Michael Elizabeth Chastain <mec@shout.net> * - Remove bug-compatible code. * * 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl> * Some bugfixes, including * - disabling "m" options when CONFIG_MODULES is set to "n" as well as "y" * option in dep_tristate when dependency is set to "m", * - deactivating choices which should not be available, * - basic validation for int and hex introduced if the entered one is not * valid, * - updates of all opened menus instead of the active only. I was afraid * that it would slow down updates, but I don't even see any speed difference * on my machine. If it slows you can still work with only a single menu * opened, * - fixed error when focussing non-existent window (especially Help windows), * Higher level submenus implemented. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "tkparse.h"/* * Total number of menus. */static int tot_menu_num = 0;/* * Pointers to mainmenu_option and endmenu of each menu. */struct kconfig * menu_first [100];struct kconfig * menu_last [100];/* * Generate portion of wish script for the beginning of a submenu. * The guts get filled in with the various options. */static void start_proc( char * label, int menu_num, int toplevel ){ if ( toplevel ) printf( "menu_option menu%d %d \"%s\"\n", menu_num, menu_num, label ); printf( "proc menu%d {w title} {\n", menu_num ); printf( "\tset oldFocus [focus]\n" ); if ( menu_first[menu_num]->menu_number != 0 ) printf( "\tcatch {focus .menu%d}\n", menu_first[menu_num]->menu_number ); printf( "\tcatch {destroy $w; unregister_active %d}\n", menu_num ); printf( "\ttoplevel $w -class Dialog\n" ); printf( "\twm withdraw $w\n" ); printf( "\tglobal active_menus\n" ); printf( "\tset active_menus [lsort -integer [linsert $active_menus end %d]]\n", menu_num ); printf( "\tmessage $w.m -width 400 -aspect 300 -text \\\n" ); printf( "\t\t\"%s\" -relief raised\n", label ); printf( "\tpack $w.m -pady 10 -side top -padx 10\n" ); printf( "\twm title $w \"%s\" \n\n", label ); printf( "\tbind $w <Escape> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; break\"\n", menu_num); printf("\tset nextscript "); printf("\"catch {focus $oldFocus}; " ); /* * We are checking which windows should be destroyed and which are * common parrents with the next one. Remember that menu_num field * in mainmenu_option record reports number of its *parent* menu. */ if ( menu_num < tot_menu_num && menu_first[menu_num + 1]->menu_number != menu_num ) { int to_destr; printf( "destroy $w; unregister_active %d; ", menu_num ); to_destr = menu_first[menu_num]->menu_number; while ( to_destr > 0 && menu_first[menu_num + 1]->menu_number != to_destr ) { printf( "catch {destroy .menu%d}; unregister_active %d; ", to_destr, to_destr ); to_destr = menu_first[to_destr]->menu_number; } } printf( "menu%d .menu%d \\\"$title\\\"\"\n", menu_num+1, menu_num+1 ); /* * Attach the "Prev", "Next" and "OK" buttons at the end of the window. */ printf( "\tframe $w.f\n" ); if ( toplevel ) printf( "\tbutton $w.f.back -text \"Main Menu\" \\\n" ); else printf( "\tbutton $w.f.back -text \"OK\" \\\n" ); printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d\"\n", menu_num ); printf( "\tbutton $w.f.next -text \"Next\" -underline 0\\\n" ); printf( "\t\t-width 15 -command $nextscript\n"); if ( menu_num == tot_menu_num ) { printf( "\t$w.f.next configure -state disabled\n" ); /* * this is a bit hackish but Alt-n must be rebound * otherwise if the user press Alt-n on the last menu * it will give him/her the next menu of one of the * previous options */ printf( "\tbind all <Alt-n> \"puts \\\"no more menus\\\" \"\n"); } else { /* * I should be binding to $w not all - but if I do nehat I get the error "unknown path" */ printf( "\tbind all <Alt-n> $nextscript\n"); } printf( "\tbutton $w.f.prev -text \"Prev\" -underline 0\\\n" ); printf( "\t\t-width 15 -command \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\"\"\n", menu_num, menu_num-1, menu_num-1 ); if ( menu_num == 1 ) { printf( "\t$w.f.prev configure -state disabled\n" ); } else { printf( "\tbind $w <Alt-p> \"catch {focus $oldFocus}; destroy $w; unregister_active %d; menu%d .menu%d \\\"$title\\\";break\"\n", menu_num, menu_num-1, menu_num-1 ); } printf( "\tpack $w.f.back $w.f.next $w.f.prev -side left -expand on\n" ); printf( "\tpack $w.f -pady 10 -side bottom -anchor w -fill x\n" ); /* * Lines between canvas and other areas of the window. */ printf( "\tframe $w.topline -relief ridge -borderwidth 2 -height 2\n" ); printf( "\tpack $w.topline -side top -fill x\n\n" ); printf( "\tframe $w.botline -relief ridge -borderwidth 2 -height 2\n" ); printf( "\tpack $w.botline -side bottom -fill x\n\n" ); /* * The "config" frame contains the canvas and a scrollbar. */ printf( "\tframe $w.config\n" ); printf( "\tpack $w.config -fill y -expand on\n\n" ); printf( "\tscrollbar $w.config.vscroll -command \"$w.config.canvas yview\"\n" ); printf( "\tpack $w.config.vscroll -side right -fill y\n\n" ); /* * The scrollable canvas itself, where the real work (and mess) gets done. */ printf( "\tcanvas $w.config.canvas -height 1\\\n" ); printf( "\t\t-relief flat -borderwidth 0 -yscrollcommand \"$w.config.vscroll set\" \\\n" ); printf( "\t\t-width [expr [winfo screenwidth .] * 1 / 2] \n" ); printf( "\tframe $w.config.f\n" ); printf( "\tbind $w <Key-Down> \"$w.config.canvas yview scroll 1 unit;break;\"\n"); printf( "\tbind $w <Key-Up> \"$w.config.canvas yview scroll -1 unit;break;\"\n"); printf( "\tbind $w <Key-Next> \"$w.config.canvas yview scroll 1 page;break;\"\n"); printf( "\tbind $w <Key-Prior> \"$w.config.canvas yview scroll -1 page;break;\"\n"); printf( "\tbind $w <Key-Home> \"$w.config.canvas yview moveto 0;break;\"\n"); printf( "\tbind $w <Key-End> \"$w.config.canvas yview moveto 1 ;break;\"\n"); printf( "\tpack $w.config.canvas -side right -fill y\n" ); printf("\n\n");}/* * Each proc we create needs a global declaration for any global variables we * use. To minimize the size of the file, we set a flag each time we output * a global declaration so we know whether we need to insert one for a * given function or not. */static void clear_globalflags(void){ int i; for ( i = 1; i <= max_varnum; i++ ) vartable[i].global_written = 0;}/* * Output a "global" line for a given variable. Also include the * call to "vfix". (If vfix is not needed, then it's fine to just printf * a "global" line). */void global( const char *var ){ printf( "\tglobal %s\n", var );}/* * This function walks the chain of conditions that we got from cond.c * and creates a TCL conditional to enable/disable a given widget. */void generate_if( struct kconfig * cfg, struct condition * ocond, int menu_num, int line_num ){ struct condition * cond; struct dependency * tmp; struct kconfig * cfg1; if ( line_num >= -1 ) { if ( cfg->token == token_define_bool || cfg->token == token_define_hex || cfg->token == token_define_int || cfg->token == token_define_string || cfg->token == token_define_tristate || cfg->token == token_unset ) return; if ( cfg->token == token_comment && line_num == -1 ) return; } else { if ( cfg->token == token_string || cfg->token == token_mainmenu_option ) return; } /* * First write any global declarations we need for this conditional. */ for ( cond = ocond; cond != NULL; cond = cond->next ) { switch ( cond->op ) { default: break; case op_variable: if ( ! vartable[cond->nameindex].global_written ) { vartable[cond->nameindex].global_written = 1; global( vartable[cond->nameindex].name ); } break; } } /* * Now write this option. */ if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) { vartable[cfg->nameindex].global_written = 1; global( vartable[cfg->nameindex].name ); } /* * Generate the body of the conditional. */ printf( "\tif {" ); for ( cond = ocond; cond != NULL; cond = cond->next ) { switch ( cond->op ) { default: break; case op_bang: printf( " ! " ); break; case op_eq: printf( " == " ); break; case op_neq: printf( " != " ); break; case op_and: printf( " && " ); break; case op_and1: printf( " && " ); break; case op_or: printf( " || " ); break; case op_lparen: printf( "(" ); break; case op_rparen: printf( ")" ); break; case op_variable: printf( "$%s", vartable[cond->nameindex].name ); break; case op_constant: if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); else if ( strcmp( cond->str, "n" ) == 0 ) printf( "0" ); else if ( strcmp( cond->str, "m" ) == 0 ) printf( "2" ); else if ( strcmp( cond->str, "" ) == 0 ) printf( "4" ); else printf( "\"%s\"", cond->str ); break; } } printf( "} then {" ); /* * Generate a procedure call to write the value. * This code depends on procedures in header.tk. */ if ( line_num >= -1 ) { int modtoyes = 0; switch ( cfg->token ) { default:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -