URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/or1k/trunk/linux/linux-2.4/scripts
- from Rev 1275 to Rev 1765
- ↔ Reverse comparison
Rev 1275 → Rev 1765
/README.Menuconfig
0,0 → 1,194
Menuconfig gives the Linux kernel configuration a long needed face |
lift. Featuring text based color menus and dialogs, it does not |
require X Windows. With this utility you can easily select a kernel |
option to modify without sifting through 100 other options. |
|
Overview |
-------- |
Some kernel features may be built directly into the kernel. |
Some may be made into loadable runtime modules. Some features |
may be completely removed altogether. There are also certain |
kernel parameters which are not really features, but must be |
entered in as decimal or hexadecimal numbers or possibly text. |
|
Menu items beginning with [*], <M> or [ ] represent features |
configured to be built in, modularized or removed respectively. |
Pointed brackets <> represent module capable features. |
more... |
|
To change any of these features, highlight it with the cursor |
keys and press <Y> to build it in, <M> to make it a module or |
<N> to removed it. You may also press the <Space Bar> to cycle |
through the available options (ie. Y->N->M->Y). |
|
Items beginning with numbers or other text within parenthesis can |
be changed by highlighting the item and pressing <Enter>. Then |
enter the new parameter into the dialog box that pops up. |
|
|
Some additional keyboard hints: |
|
Menus |
---------- |
o Use the Up/Down arrow keys (cursor keys) to highlight the item |
you wish to change or submenu wish to select and press <Enter>. |
Submenus are designated by "--->". |
|
Shortcut: Press the option's highlighted letter (hotkey). |
Pressing a hotkey more than once will sequence |
through all visible items which use that hotkey. |
|
You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll |
unseen options into view. |
|
o To exit a menu use the cursor keys to highlight the <Exit> button |
and press <ENTER>. |
|
Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey |
using those letters. You may press a single <ESC>, but |
there is a delayed response which you may find annoying. |
|
Also, the <TAB> and cursor keys will cycle between <Select>, |
<Exit> and <Help> |
|
o To get help with an item, use the cursor keys to highlight <Help> |
and Press <ENTER>. |
|
Shortcut: Press <H> or <?>. |
|
|
Radiolists (Choice lists) |
----------- |
o Use the cursor keys to select the option you wish to set and press |
<S> or the <SPACE BAR>. |
|
Shortcut: Press the first letter of the option you wish to set then |
press <S> or <SPACE BAR>. |
|
o To see available help for the item, use the cursor keys to highlight |
<Help> and Press <ENTER>. |
|
Shortcut: Press <H> or <?>. |
|
Also, the <TAB> and cursor keys will cycle between <Select> and |
<Help> |
|
|
Data Entry |
----------- |
o Enter the requested information and press <ENTER> |
If you are entering hexadecimal values, it is not necessary to |
add the '0x' prefix to the entry. |
|
o For help, use the <TAB> or cursor keys to highlight the help option |
and press <ENTER>. You can try <TAB><H> as well. |
|
|
Text Box (Help Window) |
-------- |
o Use the cursor keys to scroll up/down/left/right. The VI editor |
keys h,j,k,l function here as do <SPACE BAR> and <B> for those |
who are familiar with less and lynx. |
|
o Press <E>, <X>, <Enter> or <Esc><Esc> to exit. |
|
|
Final Acceptance |
---------------- |
With the exception of the old style sound configuration, |
YOUR CHANGES ARE NOT FINAL. You will be given a last chance to |
confirm them prior to exiting Menuconfig. |
|
If Menuconfig quits with an error while saving your configuration, |
you may look in the file /usr/src/linux/.menuconfig.log for |
information which may help you determine the cause. |
|
Alternate Configuration Files |
----------------------------- |
Menuconfig supports the use of alternate configuration files for |
those who, for various reasons, find it necessary to switch |
between different kernel configurations. |
|
At the end of the main menu you will find two options. One is |
for saving the current configuration to a file of your choosing. |
The other option is for loading a previously saved alternate |
configuration. |
|
Even if you don't use alternate configuration files, but you |
find during a Menuconfig session that you have completely messed |
up your settings, you may use the "Load Alternate..." option to |
restore your previously saved settings from ".config" without |
restarting Menuconfig. |
|
Other information |
----------------- |
The windowing utility, lxdialog, will only be rebuilt if your kernel |
source tree is fresh, or changes are patched into it via a kernel |
patch or you do 'make mrproper'. If changes to lxdialog are patched |
in, most likely the rebuild time will be short. You may force a |
complete rebuild of lxdialog by changing to it's directory and doing |
'make clean all' |
|
If you use Menuconfig in an XTERM window make sure you have your |
$TERM variable set to point to a xterm definition which supports color. |
Otherwise, Menuconfig will look rather bad. Menuconfig will not |
display correctly in a RXVT window because rxvt displays only one |
intensity of color, bright. |
|
Menuconfig will display larger menus on screens or xterms which are |
set to display more than the standard 25 row by 80 column geometry. |
In order for this to work, the "stty size" command must be able to |
display the screen's current row and column geometry. I STRONGLY |
RECOMMEND that you make sure you do NOT have the shell variables |
LINES and COLUMNS exported into your environment. Some distributions |
export those variables via /etc/profile. Some ncurses programs can |
become confused when those variables (LINES & COLUMNS) don't reflect |
the true screen size. |
|
|
NOTICE: lxdialog requires the ncurses libraries to compile. If you |
don't already have ncurses you really should get it. |
|
The makefile for lxdialog attempts to find your ncurses |
header file. Although it should find the header for older |
versions of ncurses, it is probably a good idea to get the |
latest ncurses anyway. |
|
If you have upgraded your ncurses libraries, MAKE SURE you |
remove the old ncurses header files. If you don't you |
will most certainly get a segmentation fault. |
|
WARNING: It is not recommended that you change any defines in |
lxdialog's header files. If you have a grayscale display and |
are brave, you may tinker with color.h to tune the colors to |
your preference. |
|
COMPATIBILITY ISSUE: |
There have been some compatibility problems reported with |
older versions of bash and sed. I am trying to work these |
out but it is preferable that you upgrade those utilities. |
|
|
******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ******** |
******** ******** |
If you prefer to have all of the kernel options listed in a single |
menu, rather than the default multimenu hierarchy, you may edit the |
Menuconfig script and change the line "single_menu_mode=" to |
"single_menu_mode=TRUE". |
|
This mode is not recommended unless you have a fairly fast machine. |
********************************************************************* |
|
|
Propaganda |
---------- |
The windowing support utility (lxdialog) is a VERY modified version of |
the dialog utility by Savio Lam <lam836@cs.cuhk.hk>. Although lxdialog |
is significantly different from dialog, I have left Savio's copyrights |
intact. Please DO NOT contact Savio with questions about lxdialog. |
He will not be able to assist. |
|
William Roadcap was the original author of Menuconfig. |
Michael Elizabeth Chastain <mec@shout.net> is the current maintainer. |
|
<END OF FILE> |
/mkuboot.sh
0,0 → 1,16
#!/bin/bash |
|
# |
# Build U-Boot image when `mkimage' tool is available. |
# |
|
MKIMAGE=$(type -path mkimage) |
|
if [ -z "${MKIMAGE}" ]; then |
# Doesn't exist |
echo '"mkimage" command not found - U-Boot images will not be built' >&2 |
exit 0; |
fi |
|
# Call "mkimage" to create U-Boot image |
${MKIMAGE} "$@" |
/split-include.c
0,0 → 1,226
/* |
* split-include.c |
* |
* Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>. |
* This is a C version of syncdep.pl by Werner Almesberger. |
* |
* This program takes autoconf.h as input and outputs a directory full |
* of one-line include files, merging onto the old values. |
* |
* Think of the configuration options as key-value pairs. Then there |
* are five cases: |
* |
* key old value new value action |
* |
* KEY-1 VALUE-1 VALUE-1 leave file alone |
* KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file |
* KEY-3 - VALUE-3 write VALUE-3 into file |
* KEY-4 VALUE-4 - write an empty file |
* KEY-5 (empty) - leave old empty file alone |
*/ |
|
#include <sys/types.h> |
#include <sys/stat.h> |
|
#include <ctype.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
|
#define ERROR_EXIT(strExit) \ |
{ \ |
const int errnoSave = errno; \ |
fprintf(stderr, "%s: ", str_my_name); \ |
errno = errnoSave; \ |
perror((strExit)); \ |
exit(1); \ |
} |
|
|
|
int main(int argc, const char * argv []) |
{ |
const char * str_my_name; |
const char * str_file_autoconf; |
const char * str_dir_config; |
|
FILE * fp_config; |
FILE * fp_target; |
FILE * fp_find; |
|
int buffer_size; |
|
char * line; |
char * old_line; |
char * list_target; |
char * ptarget; |
|
struct stat stat_buf; |
|
/* Check arg count. */ |
if (argc != 3) |
{ |
fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]); |
exit(1); |
} |
|
str_my_name = argv[0]; |
str_file_autoconf = argv[1]; |
str_dir_config = argv[2]; |
|
/* Find a buffer size. */ |
if (stat(str_file_autoconf, &stat_buf) != 0) |
ERROR_EXIT(str_file_autoconf); |
buffer_size = 2 * stat_buf.st_size + 4096; |
|
/* Allocate buffers. */ |
if ( (line = malloc(buffer_size)) == NULL |
|| (old_line = malloc(buffer_size)) == NULL |
|| (list_target = malloc(buffer_size)) == NULL ) |
ERROR_EXIT(str_file_autoconf); |
|
/* Open autoconfig file. */ |
if ((fp_config = fopen(str_file_autoconf, "r")) == NULL) |
ERROR_EXIT(str_file_autoconf); |
|
/* Make output directory if needed. */ |
if (stat(str_dir_config, &stat_buf) != 0) |
{ |
if (mkdir(str_dir_config, 0755) != 0) |
ERROR_EXIT(str_dir_config); |
} |
|
/* Change to output directory. */ |
if (chdir(str_dir_config) != 0) |
ERROR_EXIT(str_dir_config); |
|
/* Put initial separator into target list. */ |
ptarget = list_target; |
*ptarget++ = '\n'; |
|
/* Read config lines. */ |
while (fgets(line, buffer_size, fp_config)) |
{ |
const char * str_config; |
int is_same; |
int itarget; |
|
if (line[0] != '#') |
continue; |
if ((str_config = strstr(line, "CONFIG_")) == NULL) |
continue; |
|
/* Make the output file name. */ |
str_config += sizeof("CONFIG_") - 1; |
for (itarget = 0; !isspace((int)str_config[itarget]); itarget++) |
{ |
char c = str_config[itarget]; |
if (isupper((int)c)) c = tolower((int)c); |
if (c == '_') c = '/'; |
ptarget[itarget] = c; |
} |
ptarget[itarget++] = '.'; |
ptarget[itarget++] = 'h'; |
ptarget[itarget++] = '\0'; |
|
/* Check for existing file. */ |
is_same = 0; |
if ((fp_target = fopen(ptarget, "r")) != NULL) |
{ |
fgets(old_line, buffer_size, fp_target); |
if (fclose(fp_target) != 0) |
ERROR_EXIT(ptarget); |
if (!strcmp(line, old_line)) |
is_same = 1; |
} |
|
if (!is_same) |
{ |
/* Auto-create directories. */ |
int islash; |
for (islash = 0; islash < itarget; islash++) |
{ |
if (ptarget[islash] == '/') |
{ |
ptarget[islash] = '\0'; |
if (stat(ptarget, &stat_buf) != 0 |
&& mkdir(ptarget, 0755) != 0) |
ERROR_EXIT( ptarget ); |
ptarget[islash] = '/'; |
} |
} |
|
/* Write the file. */ |
if ((fp_target = fopen(ptarget, "w" )) == NULL) |
ERROR_EXIT(ptarget); |
fputs(line, fp_target); |
if (ferror(fp_target) || fclose(fp_target) != 0) |
ERROR_EXIT(ptarget); |
} |
|
/* Update target list */ |
ptarget += itarget; |
*(ptarget-1) = '\n'; |
} |
|
/* |
* Close autoconfig file. |
* Terminate the target list. |
*/ |
if (fclose(fp_config) != 0) |
ERROR_EXIT(str_file_autoconf); |
*ptarget = '\0'; |
|
/* |
* Fix up existing files which have no new value. |
* This is Case 4 and Case 5. |
* |
* I re-read the tree and filter it against list_target. |
* This is crude. But it avoids data copies. Also, list_target |
* is compact and contiguous, so it easily fits into cache. |
* |
* Notice that list_target contains strings separated by \n, |
* with a \n before the first string and after the last. |
* fgets gives the incoming names a terminating \n. |
* So by having an initial \n, strstr will find exact matches. |
*/ |
|
fp_find = popen("find * -type f -name \"*.h\" -print", "r"); |
if (fp_find == 0) |
ERROR_EXIT( "find" ); |
|
line[0] = '\n'; |
while (fgets(line+1, buffer_size, fp_find)) |
{ |
if (strstr(list_target, line) == NULL) |
{ |
/* |
* This is an old file with no CONFIG_* flag in autoconf.h. |
*/ |
|
/* First strip the \n. */ |
line[strlen(line)-1] = '\0'; |
|
/* Grab size. */ |
if (stat(line+1, &stat_buf) != 0) |
ERROR_EXIT(line); |
|
/* If file is not empty, make it empty and give it a fresh date. */ |
if (stat_buf.st_size != 0) |
{ |
if ((fp_target = fopen(line+1, "w")) == NULL) |
ERROR_EXIT(line); |
if (fclose(fp_target) != 0) |
ERROR_EXIT(line); |
} |
} |
} |
|
if (pclose(fp_find) != 0) |
ERROR_EXIT("find"); |
|
return 0; |
} |
/pathdown.sh
0,0 → 1,13
#!/bin/sh |
UP= |
DN=${PWD:?} |
TP=${TOPDIR:?} |
|
while [ ! $TP/$UP/. -ef $DN ] ;do |
UP=`basename $PWD`/$UP |
cd .. |
if [ "$PWD" = "/" ]; then echo "Lost"; exit 1; fi |
done |
|
echo $UP |
exit 0 |
/makelst
0,0 → 1,22
#!/bin/bash |
# A script to dump mixed source code & assembly |
# with correct relocations from System.map |
# Requires the following lines in Rules.make. |
# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) |
# William Stearns <wstearns@pobox.com> |
#%.lst: %.c |
# $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $< |
# $(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP) |
# |
# Copyright (C) 2000 IBM Corporation |
# Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) |
# |
|
t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1` |
t2=`echo $t1 | gawk '{ print $6 }'` |
t3=`grep $t2 $2/System.map` |
t4=`echo $t3 | gawk '{ print $1 }'` |
t5=`echo $t1 | gawk '{ print $1 }'` |
t6=`echo $t4 - $t5 | sed -e s/a/A/g -e s/b/B/g -e s/c/C/g -e s/d/D/g -e s/e/E/g -e s/f/F/g` |
t7=`( echo ibase=16 ; echo $t6 ) | bc` |
$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst |
/extract-ikconfig
0,0 → 1,17
#! /bin/bash -x |
# extracts .config info from a [b]zImage file |
# uses: binoffset (new), dd, zcat, strings, grep |
# $arg1 is [b]zImage filename |
|
HDR=`binoffset $1 0x1f 0x8b 0x08 0x0` |
PID=$$ |
TMPFILE="$1.vmlin.$PID" |
|
# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \ |
# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID |
# exit |
|
dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE |
strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID |
wc $1.oldconfig.$PID |
rm $TMPFILE |
/lxdialog/msgbox.c
0,0 → 1,85
/* |
* msgbox.c -- implements the message box and info box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
/* |
* Display a message box. Program will pause and display an "OK" button |
* if the parameter 'pause' is non-zero. |
*/ |
int |
dialog_msgbox (const char *title, const char *prompt, int height, int width, |
int pause) |
{ |
int i, x, y, key = 0; |
WINDOW *dialog; |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
wattrset (dialog, dialog_attr); |
print_autowrap (dialog, prompt, width - 2, 1, 2); |
|
if (pause) { |
wattrset (dialog, border_attr); |
mvwaddch (dialog, height - 3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
waddch (dialog, ACS_RTEE); |
|
print_button (dialog, " Ok ", |
height - 2, width / 2 - 4, TRUE); |
|
wrefresh (dialog); |
while (key != ESC && key != '\n' && key != ' ' && |
key != 'O' && key != 'o' && key != 'X' && key != 'x') |
key = wgetch (dialog); |
} else { |
key = '\n'; |
wrefresh (dialog); |
} |
|
delwin (dialog); |
return key == ESC ? -1 : 0; |
} |
/lxdialog/lxdialog.c
0,0 → 1,226
/* |
* dialog - Display simple dialog boxes from shell scripts |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
static void Usage (const char *name); |
|
typedef int (jumperFn) (const char *title, int argc, const char * const * argv); |
|
struct Mode { |
char *name; |
int argmin, argmax, argmod; |
jumperFn *jumper; |
}; |
|
jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox; |
jumperFn j_msgbox, j_infobox; |
|
static struct Mode modes[] = |
{ |
{"--menu", 9, 0, 3, j_menu}, |
{"--checklist", 9, 0, 3, j_checklist}, |
{"--radiolist", 9, 0, 3, j_radiolist}, |
{"--yesno", 5,5,1, j_yesno}, |
{"--textbox", 5,5,1, j_textbox}, |
{"--inputbox", 5, 6, 1, j_inputbox}, |
{"--msgbox", 5, 5, 1, j_msgbox}, |
{"--infobox", 5, 5, 1, j_infobox}, |
{NULL, 0, 0, 0, NULL} |
}; |
|
static struct Mode *modePtr; |
|
#ifdef LOCALE |
#include <locale.h> |
#endif |
|
int |
main (int argc, const char * const * argv) |
{ |
int offset = 0, clear_screen = 0, end_common_opts = 0, retval; |
const char *title = NULL; |
|
#ifdef LOCALE |
(void) setlocale (LC_ALL, ""); |
#endif |
|
#ifdef TRACE |
trace(TRACE_CALLS|TRACE_UPDATE); |
#endif |
if (argc < 2) { |
Usage (argv[0]); |
exit (-1); |
} |
|
while (offset < argc - 1 && !end_common_opts) { /* Common options */ |
if (!strcmp (argv[offset + 1], "--title")) { |
if (argc - offset < 3 || title != NULL) { |
Usage (argv[0]); |
exit (-1); |
} else { |
title = argv[offset + 2]; |
offset += 2; |
} |
} else if (!strcmp (argv[offset + 1], "--backtitle")) { |
if (backtitle != NULL) { |
Usage (argv[0]); |
exit (-1); |
} else { |
backtitle = argv[offset + 2]; |
offset += 2; |
} |
} else if (!strcmp (argv[offset + 1], "--clear")) { |
if (clear_screen) { /* Hey, "--clear" can't appear twice! */ |
Usage (argv[0]); |
exit (-1); |
} else if (argc == 2) { /* we only want to clear the screen */ |
init_dialog (); |
refresh (); /* init_dialog() will clear the screen for us */ |
end_dialog (); |
return 0; |
} else { |
clear_screen = 1; |
offset++; |
} |
} else /* no more common options */ |
end_common_opts = 1; |
} |
|
if (argc - 1 == offset) { /* no more options */ |
Usage (argv[0]); |
exit (-1); |
} |
/* use a table to look for the requested mode, to avoid code duplication */ |
|
for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */ |
if (!strcmp (argv[offset + 1], modePtr->name)) |
break; |
|
if (!modePtr->name) |
Usage (argv[0]); |
if (argc - offset < modePtr->argmin) |
Usage (argv[0]); |
if (modePtr->argmax && argc - offset > modePtr->argmax) |
Usage (argv[0]); |
|
|
|
init_dialog (); |
retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset); |
|
if (clear_screen) { /* clear screen before exit */ |
attr_clear (stdscr, LINES, COLS, screen_attr); |
refresh (); |
} |
end_dialog(); |
|
exit (retval); |
} |
|
/* |
* Print program usage |
*/ |
static void |
Usage (const char *name) |
{ |
fprintf (stderr, "\ |
\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\ |
\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\ |
\n modified/gutted for use as a Linux kernel config tool by \ |
\n William Roadcap (roadcapw@cfw.com)\ |
\n\ |
\n* Display dialog boxes from shell scripts *\ |
\n\ |
\nUsage: %s --clear\ |
\n %s [--title <title>] [--backtitle <backtitle>] --clear <Box options>\ |
\n\ |
\nBox options:\ |
\n\ |
\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\ |
\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ |
\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ |
\n --textbox <file> <height> <width>\ |
\n --inputbox <text> <height> <width> [<init>]\ |
\n --yesno <text> <height> <width>\ |
\n", name, name); |
exit (-1); |
} |
|
/* |
* These are the program jumpers |
*/ |
|
int |
j_menu (const char *t, int ac, const char * const * av) |
{ |
return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]), |
atoi (av[5]), av[6], (ac - 6) / 2, av + 7); |
} |
|
int |
j_checklist (const char *t, int ac, const char * const * av) |
{ |
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]), |
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK); |
} |
|
int |
j_radiolist (const char *t, int ac, const char * const * av) |
{ |
return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]), |
atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO); |
} |
|
int |
j_textbox (const char *t, int ac, const char * const * av) |
{ |
return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4])); |
} |
|
int |
j_yesno (const char *t, int ac, const char * const * av) |
{ |
return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4])); |
} |
|
int |
j_inputbox (const char *t, int ac, const char * const * av) |
{ |
int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]), |
ac == 6 ? av[5] : (char *) NULL); |
if (ret == 0) |
fprintf(stderr, dialog_input_result); |
return ret; |
} |
|
int |
j_msgbox (const char *t, int ac, const char * const * av) |
{ |
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1); |
} |
|
int |
j_infobox (const char *t, int ac, const char * const * av) |
{ |
return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0); |
} |
|
/lxdialog/dialog.h
0,0 → 1,184
|
/* |
* dialog.h -- common declarations for all dialog modules |
* |
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include <sys/types.h> |
#include <fcntl.h> |
#include <unistd.h> |
#include <ctype.h> |
#include <stdlib.h> |
#include <string.h> |
|
#include CURSES_LOC |
|
/* |
* Colors in ncurses 1.9.9e do not work properly since foreground and |
* background colors are OR'd rather than separately masked. This version |
* of dialog was hacked to work with ncurses 1.9.9e, making it incompatible |
* with standard curses. The simplest fix (to make this work with standard |
* curses) uses the wbkgdset() function, not used in the original hack. |
* Turn it off if we're building with 1.9.9e, since it just confuses things. |
*/ |
#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE) |
#define OLD_NCURSES 1 |
#undef wbkgdset |
#define wbkgdset(w,p) /*nothing*/ |
#else |
#define OLD_NCURSES 0 |
#endif |
|
#define TR(params) _tracef params |
|
#define ESC 27 |
#define TAB 9 |
#define MAX_LEN 2048 |
#define BUF_SIZE (10*1024) |
#define MIN(x,y) (x < y ? x : y) |
#define MAX(x,y) (x > y ? x : y) |
|
|
#ifndef ACS_ULCORNER |
#define ACS_ULCORNER '+' |
#endif |
#ifndef ACS_LLCORNER |
#define ACS_LLCORNER '+' |
#endif |
#ifndef ACS_URCORNER |
#define ACS_URCORNER '+' |
#endif |
#ifndef ACS_LRCORNER |
#define ACS_LRCORNER '+' |
#endif |
#ifndef ACS_HLINE |
#define ACS_HLINE '-' |
#endif |
#ifndef ACS_VLINE |
#define ACS_VLINE '|' |
#endif |
#ifndef ACS_LTEE |
#define ACS_LTEE '+' |
#endif |
#ifndef ACS_RTEE |
#define ACS_RTEE '+' |
#endif |
#ifndef ACS_UARROW |
#define ACS_UARROW '^' |
#endif |
#ifndef ACS_DARROW |
#define ACS_DARROW 'v' |
#endif |
|
/* |
* Attribute names |
*/ |
#define screen_attr attributes[0] |
#define shadow_attr attributes[1] |
#define dialog_attr attributes[2] |
#define title_attr attributes[3] |
#define border_attr attributes[4] |
#define button_active_attr attributes[5] |
#define button_inactive_attr attributes[6] |
#define button_key_active_attr attributes[7] |
#define button_key_inactive_attr attributes[8] |
#define button_label_active_attr attributes[9] |
#define button_label_inactive_attr attributes[10] |
#define inputbox_attr attributes[11] |
#define inputbox_border_attr attributes[12] |
#define searchbox_attr attributes[13] |
#define searchbox_title_attr attributes[14] |
#define searchbox_border_attr attributes[15] |
#define position_indicator_attr attributes[16] |
#define menubox_attr attributes[17] |
#define menubox_border_attr attributes[18] |
#define item_attr attributes[19] |
#define item_selected_attr attributes[20] |
#define tag_attr attributes[21] |
#define tag_selected_attr attributes[22] |
#define tag_key_attr attributes[23] |
#define tag_key_selected_attr attributes[24] |
#define check_attr attributes[25] |
#define check_selected_attr attributes[26] |
#define uarrow_attr attributes[27] |
#define darrow_attr attributes[28] |
|
/* number of attributes */ |
#define ATTRIBUTE_COUNT 29 |
|
/* |
* Global variables |
*/ |
extern bool use_colors; |
extern bool use_shadow; |
|
extern chtype attributes[]; |
|
extern const char *backtitle; |
|
/* |
* Function prototypes |
*/ |
extern void create_rc (const char *filename); |
extern int parse_rc (void); |
|
|
void init_dialog (void); |
void end_dialog (void); |
void attr_clear (WINDOW * win, int height, int width, chtype attr); |
void dialog_clear (void); |
void color_setup (void); |
void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); |
void print_button (WINDOW * win, const char *label, int y, int x, int selected); |
void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, |
chtype border); |
void draw_shadow (WINDOW * win, int y, int x, int height, int width); |
|
int first_alpha (const char *string, const char *exempt); |
int dialog_yesno (const char *title, const char *prompt, int height, int width); |
int dialog_msgbox (const char *title, const char *prompt, int height, |
int width, int pause); |
int dialog_textbox (const char *title, const char *file, int height, int width); |
int dialog_menu (const char *title, const char *prompt, int height, int width, |
int menu_height, const char *choice, int item_no, |
const char * const * items); |
int dialog_checklist (const char *title, const char *prompt, int height, |
int width, int list_height, int item_no, |
const char * const * items, int flag); |
extern unsigned char dialog_input_result[]; |
int dialog_inputbox (const char *title, const char *prompt, int height, |
int width, const char *init); |
|
/* |
* This is the base for fictitious keys, which activate |
* the buttons. |
* |
* Mouse-generated keys are the following: |
* -- the first 32 are used as numbers, in addition to '0'-'9' |
* -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') |
* -- uppercase chars are used to invoke the button (M_EVENT + 'O') |
*/ |
#define M_EVENT (KEY_MAX+1) |
|
|
/* |
* The `flag' parameter in checklist is used to select between |
* radiolist and checklist |
*/ |
#define FLAG_CHECK 1 |
#define FLAG_RADIO 0 |
/lxdialog/colors.h
0,0 → 1,161
/* |
* colors.h -- color attribute definitions |
* |
* AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
|
/* |
* Default color definitions |
* |
* *_FG = foreground |
* *_BG = background |
* *_HL = highlight? |
*/ |
#define SCREEN_FG COLOR_CYAN |
#define SCREEN_BG COLOR_BLUE |
#define SCREEN_HL TRUE |
|
#define SHADOW_FG COLOR_BLACK |
#define SHADOW_BG COLOR_BLACK |
#define SHADOW_HL TRUE |
|
#define DIALOG_FG COLOR_BLACK |
#define DIALOG_BG COLOR_WHITE |
#define DIALOG_HL FALSE |
|
#define TITLE_FG COLOR_YELLOW |
#define TITLE_BG COLOR_WHITE |
#define TITLE_HL TRUE |
|
#define BORDER_FG COLOR_WHITE |
#define BORDER_BG COLOR_WHITE |
#define BORDER_HL TRUE |
|
#define BUTTON_ACTIVE_FG COLOR_WHITE |
#define BUTTON_ACTIVE_BG COLOR_BLUE |
#define BUTTON_ACTIVE_HL TRUE |
|
#define BUTTON_INACTIVE_FG COLOR_BLACK |
#define BUTTON_INACTIVE_BG COLOR_WHITE |
#define BUTTON_INACTIVE_HL FALSE |
|
#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE |
#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE |
#define BUTTON_KEY_ACTIVE_HL TRUE |
|
#define BUTTON_KEY_INACTIVE_FG COLOR_RED |
#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE |
#define BUTTON_KEY_INACTIVE_HL FALSE |
|
#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW |
#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE |
#define BUTTON_LABEL_ACTIVE_HL TRUE |
|
#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK |
#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE |
#define BUTTON_LABEL_INACTIVE_HL TRUE |
|
#define INPUTBOX_FG COLOR_BLACK |
#define INPUTBOX_BG COLOR_WHITE |
#define INPUTBOX_HL FALSE |
|
#define INPUTBOX_BORDER_FG COLOR_BLACK |
#define INPUTBOX_BORDER_BG COLOR_WHITE |
#define INPUTBOX_BORDER_HL FALSE |
|
#define SEARCHBOX_FG COLOR_BLACK |
#define SEARCHBOX_BG COLOR_WHITE |
#define SEARCHBOX_HL FALSE |
|
#define SEARCHBOX_TITLE_FG COLOR_YELLOW |
#define SEARCHBOX_TITLE_BG COLOR_WHITE |
#define SEARCHBOX_TITLE_HL TRUE |
|
#define SEARCHBOX_BORDER_FG COLOR_WHITE |
#define SEARCHBOX_BORDER_BG COLOR_WHITE |
#define SEARCHBOX_BORDER_HL TRUE |
|
#define POSITION_INDICATOR_FG COLOR_YELLOW |
#define POSITION_INDICATOR_BG COLOR_WHITE |
#define POSITION_INDICATOR_HL TRUE |
|
#define MENUBOX_FG COLOR_BLACK |
#define MENUBOX_BG COLOR_WHITE |
#define MENUBOX_HL FALSE |
|
#define MENUBOX_BORDER_FG COLOR_WHITE |
#define MENUBOX_BORDER_BG COLOR_WHITE |
#define MENUBOX_BORDER_HL TRUE |
|
#define ITEM_FG COLOR_BLACK |
#define ITEM_BG COLOR_WHITE |
#define ITEM_HL FALSE |
|
#define ITEM_SELECTED_FG COLOR_WHITE |
#define ITEM_SELECTED_BG COLOR_BLUE |
#define ITEM_SELECTED_HL TRUE |
|
#define TAG_FG COLOR_YELLOW |
#define TAG_BG COLOR_WHITE |
#define TAG_HL TRUE |
|
#define TAG_SELECTED_FG COLOR_YELLOW |
#define TAG_SELECTED_BG COLOR_BLUE |
#define TAG_SELECTED_HL TRUE |
|
#define TAG_KEY_FG COLOR_YELLOW |
#define TAG_KEY_BG COLOR_WHITE |
#define TAG_KEY_HL TRUE |
|
#define TAG_KEY_SELECTED_FG COLOR_YELLOW |
#define TAG_KEY_SELECTED_BG COLOR_BLUE |
#define TAG_KEY_SELECTED_HL TRUE |
|
#define CHECK_FG COLOR_BLACK |
#define CHECK_BG COLOR_WHITE |
#define CHECK_HL FALSE |
|
#define CHECK_SELECTED_FG COLOR_WHITE |
#define CHECK_SELECTED_BG COLOR_BLUE |
#define CHECK_SELECTED_HL TRUE |
|
#define UARROW_FG COLOR_GREEN |
#define UARROW_BG COLOR_WHITE |
#define UARROW_HL TRUE |
|
#define DARROW_FG COLOR_GREEN |
#define DARROW_BG COLOR_WHITE |
#define DARROW_HL TRUE |
|
/* End of default color definitions */ |
|
#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) |
#define COLOR_NAME_LEN 10 |
#define COLOR_COUNT 8 |
|
/* |
* Global variables |
*/ |
|
typedef struct { |
char name[COLOR_NAME_LEN]; |
int value; |
} color_names_st; |
|
extern color_names_st color_names[]; |
extern int color_table[][3]; |
/lxdialog/inputbox.c
0,0 → 1,240
/* |
* inputbox.c -- implements the input box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
unsigned char dialog_input_result[MAX_LEN + 1]; |
|
/* |
* Print the termination buttons |
*/ |
static void |
print_buttons(WINDOW *dialog, int height, int width, int selected) |
{ |
int x = width / 2 - 11; |
int y = height - 2; |
|
print_button (dialog, " Ok ", y, x, selected==0); |
print_button (dialog, " Help ", y, x + 14, selected==1); |
|
wmove(dialog, y, x+1+14*selected); |
wrefresh(dialog); |
} |
|
/* |
* Display a dialog box for inputing a string |
*/ |
int |
dialog_inputbox (const char *title, const char *prompt, int height, int width, |
const char *init) |
{ |
int i, x, y, box_y, box_x, box_width; |
int input_x = 0, scroll = 0, key = 0, button = -1; |
unsigned char *instr = dialog_input_result; |
WINDOW *dialog; |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
wattrset (dialog, border_attr); |
mvwaddch (dialog, height-3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
waddch (dialog, ACS_RTEE); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
|
wattrset (dialog, dialog_attr); |
print_autowrap (dialog, prompt, width - 2, 1, 3); |
|
/* Draw the input field box */ |
box_width = width - 6; |
getyx (dialog, y, x); |
box_y = y + 2; |
box_x = (width - box_width) / 2; |
draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, |
border_attr, dialog_attr); |
|
print_buttons(dialog, height, width, 0); |
|
/* Set up the initial value */ |
wmove (dialog, box_y, box_x); |
wattrset (dialog, inputbox_attr); |
|
if (!init) |
instr[0] = '\0'; |
else |
strcpy (instr, init); |
|
input_x = strlen (instr); |
|
if (input_x >= box_width) { |
scroll = input_x - box_width + 1; |
input_x = box_width - 1; |
for (i = 0; i < box_width - 1; i++) |
waddch (dialog, instr[scroll + i]); |
} else |
waddstr (dialog, instr); |
|
wmove (dialog, box_y, box_x + input_x); |
|
wrefresh (dialog); |
|
while (key != ESC) { |
key = wgetch (dialog); |
|
if (button == -1) { /* Input box selected */ |
switch (key) { |
case TAB: |
case KEY_UP: |
case KEY_DOWN: |
break; |
case KEY_LEFT: |
continue; |
case KEY_RIGHT: |
continue; |
case KEY_BACKSPACE: |
case 127: |
if (input_x || scroll) { |
wattrset (dialog, inputbox_attr); |
if (!input_x) { |
scroll = scroll < box_width - 1 ? |
0 : scroll - (box_width - 1); |
wmove (dialog, box_y, box_x); |
for (i = 0; i < box_width; i++) |
waddch (dialog, instr[scroll + input_x + i] ? |
instr[scroll + input_x + i] : ' '); |
input_x = strlen (instr) - scroll; |
} else |
input_x--; |
instr[scroll + input_x] = '\0'; |
mvwaddch (dialog, box_y, input_x + box_x, ' '); |
wmove (dialog, box_y, input_x + box_x); |
wrefresh (dialog); |
} |
continue; |
default: |
if (key < 0x100 && isprint (key)) { |
if (scroll + input_x < MAX_LEN) { |
wattrset (dialog, inputbox_attr); |
instr[scroll + input_x] = key; |
instr[scroll + input_x + 1] = '\0'; |
if (input_x == box_width - 1) { |
scroll++; |
wmove (dialog, box_y, box_x); |
for (i = 0; i < box_width - 1; i++) |
waddch (dialog, instr[scroll + i]); |
} else { |
wmove (dialog, box_y, input_x++ + box_x); |
waddch (dialog, key); |
} |
wrefresh (dialog); |
} else |
flash (); /* Alarm user about overflow */ |
continue; |
} |
} |
} |
switch (key) { |
case 'O': |
case 'o': |
delwin (dialog); |
return 0; |
case 'H': |
case 'h': |
delwin (dialog); |
return 1; |
case KEY_UP: |
case KEY_LEFT: |
switch (button) { |
case -1: |
button = 1; /* Indicates "Cancel" button is selected */ |
print_buttons(dialog, height, width, 1); |
break; |
case 0: |
button = -1; /* Indicates input box is selected */ |
print_buttons(dialog, height, width, 0); |
wmove (dialog, box_y, box_x + input_x); |
wrefresh (dialog); |
break; |
case 1: |
button = 0; /* Indicates "OK" button is selected */ |
print_buttons(dialog, height, width, 0); |
break; |
} |
break; |
case TAB: |
case KEY_DOWN: |
case KEY_RIGHT: |
switch (button) { |
case -1: |
button = 0; /* Indicates "OK" button is selected */ |
print_buttons(dialog, height, width, 0); |
break; |
case 0: |
button = 1; /* Indicates "Cancel" button is selected */ |
print_buttons(dialog, height, width, 1); |
break; |
case 1: |
button = -1; /* Indicates input box is selected */ |
print_buttons(dialog, height, width, 0); |
wmove (dialog, box_y, box_x + input_x); |
wrefresh (dialog); |
break; |
} |
break; |
case ' ': |
case '\n': |
delwin (dialog); |
return (button == -1 ? 0 : button); |
case 'X': |
case 'x': |
key = ESC; |
case ESC: |
break; |
} |
} |
|
delwin (dialog); |
return -1; /* ESC pressed */ |
} |
/lxdialog/checklist.c
0,0 → 1,369
/* |
* checklist.c -- implements the checklist box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension |
* Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
static int list_width, check_x, item_x, checkflag; |
|
/* |
* Print list item |
*/ |
static void |
print_item (WINDOW * win, const char *item, int status, |
int choice, int selected) |
{ |
int i; |
|
/* Clear 'residue' of last item */ |
wattrset (win, menubox_attr); |
wmove (win, choice, 0); |
for (i = 0; i < list_width; i++) |
waddch (win, ' '); |
|
wmove (win, choice, check_x); |
wattrset (win, selected ? check_selected_attr : check_attr); |
if (checkflag == FLAG_CHECK) |
wprintw (win, "[%c]", status ? 'X' : ' '); |
else |
wprintw (win, "(%c)", status ? 'X' : ' '); |
|
wattrset (win, selected ? tag_selected_attr : tag_attr); |
mvwaddch(win, choice, item_x, item[0]); |
wattrset (win, selected ? item_selected_attr : item_attr); |
waddstr (win, (char *)item+1); |
if (selected) { |
wmove (win, choice, check_x+1); |
wrefresh (win); |
} |
} |
|
/* |
* Print the scroll indicators. |
*/ |
static void |
print_arrows (WINDOW * win, int choice, int item_no, int scroll, |
int y, int x, int height) |
{ |
wmove(win, y, x); |
|
if (scroll > 0) { |
wattrset (win, uarrow_attr); |
waddch (win, ACS_UARROW); |
waddstr (win, "(-)"); |
} |
else { |
wattrset (win, menubox_attr); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
} |
|
y = y + height + 1; |
wmove(win, y, x); |
|
if ((height < item_no) && (scroll + choice < item_no - 1)) { |
wattrset (win, darrow_attr); |
waddch (win, ACS_DARROW); |
waddstr (win, "(+)"); |
} |
else { |
wattrset (win, menubox_border_attr); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
} |
} |
|
/* |
* Display the termination buttons |
*/ |
static void |
print_buttons( WINDOW *dialog, int height, int width, int selected) |
{ |
int x = width / 2 - 11; |
int y = height - 2; |
|
print_button (dialog, "Select", y, x, selected == 0); |
print_button (dialog, " Help ", y, x + 14, selected == 1); |
|
wmove(dialog, y, x+1 + 14*selected); |
wrefresh (dialog); |
} |
|
/* |
* Display a dialog box with a list of options that can be turned on or off |
* The `flag' parameter is used to select between radiolist and checklist. |
*/ |
int |
dialog_checklist (const char *title, const char *prompt, int height, int width, |
int list_height, int item_no, const char * const * items, int flag) |
|
{ |
int i, x, y, box_x, box_y; |
int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; |
WINDOW *dialog, *list; |
|
checkflag = flag; |
|
/* Allocate space for storing item on/off status */ |
if ((status = malloc (sizeof (int) * item_no)) == NULL) { |
endwin (); |
fprintf (stderr, |
"\nCan't allocate memory in dialog_checklist().\n"); |
exit (-1); |
} |
|
/* Initializes status */ |
for (i = 0; i < item_no; i++) { |
status[i] = !strcasecmp (items[i * 3 + 2], "on"); |
if (!choice && status[i]) |
choice = i; |
} |
|
max_choice = MIN (list_height, item_no); |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
wattrset (dialog, border_attr); |
mvwaddch (dialog, height-3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
waddch (dialog, ACS_RTEE); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
|
wattrset (dialog, dialog_attr); |
print_autowrap (dialog, prompt, width - 2, 1, 3); |
|
list_width = width - 6; |
box_y = height - list_height - 5; |
box_x = (width - list_width) / 2 - 1; |
|
/* create new window for the list */ |
list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1); |
|
keypad (list, TRUE); |
|
/* draw a box around the list items */ |
draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2, |
menubox_border_attr, menubox_attr); |
|
/* Find length of longest item in order to center checklist */ |
check_x = 0; |
for (i = 0; i < item_no; i++) |
check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4); |
|
check_x = (list_width - check_x) / 2; |
item_x = check_x + 4; |
|
if (choice >= list_height) { |
scroll = choice - list_height + 1; |
choice -= scroll; |
} |
|
/* Print the list */ |
for (i = 0; i < max_choice; i++) { |
print_item (list, items[(scroll+i) * 3 + 1], |
status[i+scroll], i, i == choice); |
} |
|
print_arrows(dialog, choice, item_no, scroll, |
box_y, box_x + check_x + 5, list_height); |
|
print_buttons(dialog, height, width, 0); |
|
wnoutrefresh (list); |
wnoutrefresh (dialog); |
doupdate (); |
|
while (key != ESC) { |
key = wgetch (dialog); |
|
for (i = 0; i < max_choice; i++) |
if (toupper(key) == toupper(items[(scroll+i)*3+1][0])) |
break; |
|
|
if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || |
key == '+' || key == '-' ) { |
if (key == KEY_UP || key == '-') { |
if (!choice) { |
if (!scroll) |
continue; |
/* Scroll list down */ |
if (list_height > 1) { |
/* De-highlight current first item */ |
print_item (list, items[scroll * 3 + 1], |
status[scroll], 0, FALSE); |
scrollok (list, TRUE); |
wscrl (list, -1); |
scrollok (list, FALSE); |
} |
scroll--; |
print_item (list, items[scroll * 3 + 1], |
status[scroll], 0, TRUE); |
wnoutrefresh (list); |
|
print_arrows(dialog, choice, item_no, scroll, |
box_y, box_x + check_x + 5, list_height); |
|
wrefresh (dialog); |
|
continue; /* wait for another key press */ |
} else |
i = choice - 1; |
} else if (key == KEY_DOWN || key == '+') { |
if (choice == max_choice - 1) { |
if (scroll + choice >= item_no - 1) |
continue; |
/* Scroll list up */ |
if (list_height > 1) { |
/* De-highlight current last item before scrolling up */ |
print_item (list, items[(scroll + max_choice - 1) * 3 + 1], |
status[scroll + max_choice - 1], |
max_choice - 1, FALSE); |
scrollok (list, TRUE); |
scroll (list); |
scrollok (list, FALSE); |
} |
scroll++; |
print_item (list, items[(scroll + max_choice - 1) * 3 + 1], |
status[scroll + max_choice - 1], |
max_choice - 1, TRUE); |
wnoutrefresh (list); |
|
print_arrows(dialog, choice, item_no, scroll, |
box_y, box_x + check_x + 5, list_height); |
|
wrefresh (dialog); |
|
continue; /* wait for another key press */ |
} else |
i = choice + 1; |
} |
if (i != choice) { |
/* De-highlight current item */ |
print_item (list, items[(scroll + choice) * 3 + 1], |
status[scroll + choice], choice, FALSE); |
/* Highlight new item */ |
choice = i; |
print_item (list, items[(scroll + choice) * 3 + 1], |
status[scroll + choice], choice, TRUE); |
wnoutrefresh (list); |
wrefresh (dialog); |
} |
continue; /* wait for another key press */ |
} |
switch (key) { |
case 'H': |
case 'h': |
case '?': |
delwin (dialog); |
free (status); |
return 1; |
case TAB: |
case KEY_LEFT: |
case KEY_RIGHT: |
button = ((key == KEY_LEFT ? --button : ++button) < 0) |
? 1 : (button > 1 ? 0 : button); |
|
print_buttons(dialog, height, width, button); |
wrefresh (dialog); |
break; |
case 'S': |
case 's': |
case ' ': |
case '\n': |
if (!button) { |
if (flag == FLAG_CHECK) { |
status[scroll + choice] = !status[scroll + choice]; |
wmove (list, choice, check_x); |
wattrset (list, check_selected_attr); |
wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); |
} else { |
if (!status[scroll + choice]) { |
for (i = 0; i < item_no; i++) |
status[i] = 0; |
status[scroll + choice] = 1; |
for (i = 0; i < max_choice; i++) |
print_item (list, items[(scroll + i) * 3 + 1], |
status[scroll + i], i, i == choice); |
} |
} |
wnoutrefresh (list); |
wrefresh (dialog); |
|
for (i = 0; i < item_no; i++) { |
if (status[i]) { |
if (flag == FLAG_CHECK) { |
fprintf (stderr, "\"%s\" ", items[i * 3]); |
} else { |
fprintf (stderr, "%s", items[i * 3]); |
} |
|
} |
} |
} |
delwin (dialog); |
free (status); |
return button; |
case 'X': |
case 'x': |
key = ESC; |
case ESC: |
break; |
} |
|
/* Now, update everything... */ |
doupdate (); |
} |
|
|
delwin (dialog); |
free (status); |
return -1; /* ESC pressed */ |
} |
/lxdialog/Makefile
0,0 → 1,46
HOSTCFLAGS += -DLOCALE |
LIBS = -lncurses |
|
ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) |
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>" |
else |
ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) |
HOSTCFLAGS += -I/usr/include/ncurses -DCURSES_LOC="<ncurses/curses.h>" |
else |
ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) |
HOSTCFLAGS += -DCURSES_LOC="<ncurses.h>" |
else |
HOSTCFLAGS += -DCURSES_LOC="<curses.h>" |
endif |
endif |
endif |
|
|
OBJS = checklist.o menubox.o textbox.o yesno.o inputbox.o \ |
util.o lxdialog.o msgbox.o |
|
%.o: %.c |
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $< |
|
all: ncurses lxdialog |
|
lxdialog: $(OBJS) |
$(HOSTCC) -o lxdialog $(OBJS) $(LIBS) |
|
ncurses: |
@echo "main() {}" > lxtemp.c |
@if $(HOSTCC) -lncurses lxtemp.c ; then \ |
rm -f lxtemp.c a.out; \ |
else \ |
rm -f lxtemp.c; \ |
echo -e "\007" ;\ |
echo ">> Unable to find the Ncurses libraries." ;\ |
echo ">>" ;\ |
echo ">> You must have Ncurses installed in order" ;\ |
echo ">> to use 'make menuconfig'" ;\ |
echo ;\ |
exit 1 ;\ |
fi |
|
clean: |
rm -f core *.o *~ lxdialog |
/lxdialog/menubox.c
0,0 → 1,443
/* |
* menubox.c -- implements the menu box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
/* |
* Changes by Clifford Wolf (god@clifford.at) |
* |
* [ 1998-06-13 ] |
* |
* *) A bugfix for the Page-Down problem |
* |
* *) Formerly when I used Page Down and Page Up, the cursor would be set |
* to the first position in the menu box. Now lxdialog is a bit |
* smarter and works more like other menu systems (just have a look at |
* it). |
* |
* *) Formerly if I selected something my scrolling would be broken because |
* lxdialog is re-invoked by the Menuconfig shell script, can't |
* remember the last scrolling position, and just sets it so that the |
* cursor is at the bottom of the box. Now it writes the temporary file |
* lxdialog.scrltmp which contains this information. The file is |
* deleted by lxdialog if the user leaves a submenu or enters a new |
* one, but it would be nice if Menuconfig could make another "rm -f" |
* just to be sure. Just try it out - you will recognise a difference! |
* |
* [ 1998-06-14 ] |
* |
* *) Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files |
* and menus change their size on the fly. |
* |
* *) If for some reason the last scrolling position is not saved by |
* lxdialog, it sets the scrolling so that the selected item is in the |
* middle of the menu box, not at the bottom. |
* |
* 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) |
* Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus. |
* This fixes a bug in Menuconfig where using ' ' to descend into menus |
* would leave mis-synchronized lxdialog.scrltmp files lying around, |
* fscanf would read in 'scroll', and eventually that value would get used. |
*/ |
|
#include "dialog.h" |
|
static int menu_width, item_x; |
|
/* |
* Print menu item |
*/ |
static void |
print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) |
{ |
int j; |
char menu_item[menu_width+1]; |
|
strncpy(menu_item, item, menu_width); |
menu_item[menu_width] = 0; |
j = first_alpha(menu_item, "YyNnMm"); |
|
/* Clear 'residue' of last item */ |
wattrset (win, menubox_attr); |
wmove (win, choice, 0); |
#if OLD_NCURSES |
{ |
int i; |
for (i = 0; i < menu_width; i++) |
waddch (win, ' '); |
} |
#else |
wclrtoeol(win); |
#endif |
wattrset (win, selected ? item_selected_attr : item_attr); |
mvwaddstr (win, choice, item_x, menu_item); |
if (hotkey) { |
wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); |
mvwaddch(win, choice, item_x+j, menu_item[j]); |
} |
if (selected) { |
wmove (win, choice, item_x+1); |
wrefresh (win); |
} |
} |
|
/* |
* Print the scroll indicators. |
*/ |
static void |
print_arrows (WINDOW * win, int item_no, int scroll, |
int y, int x, int height) |
{ |
int cur_y, cur_x; |
|
getyx(win, cur_y, cur_x); |
|
wmove(win, y, x); |
|
if (scroll > 0) { |
wattrset (win, uarrow_attr); |
waddch (win, ACS_UARROW); |
waddstr (win, "(-)"); |
} |
else { |
wattrset (win, menubox_attr); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
} |
|
y = y + height + 1; |
wmove(win, y, x); |
|
if ((height < item_no) && (scroll + height < item_no)) { |
wattrset (win, darrow_attr); |
waddch (win, ACS_DARROW); |
waddstr (win, "(+)"); |
} |
else { |
wattrset (win, menubox_border_attr); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
waddch (win, ACS_HLINE); |
} |
|
wmove(win, cur_y, cur_x); |
} |
|
/* |
* Display the termination buttons. |
*/ |
static void |
print_buttons (WINDOW *win, int height, int width, int selected) |
{ |
int x = width / 2 - 16; |
int y = height - 2; |
|
print_button (win, "Select", y, x, selected == 0); |
print_button (win, " Exit ", y, x + 12, selected == 1); |
print_button (win, " Help ", y, x + 24, selected == 2); |
|
wmove(win, y, x+1+12*selected); |
wrefresh (win); |
} |
|
/* |
* Display a menu for choosing among a number of options |
*/ |
int |
dialog_menu (const char *title, const char *prompt, int height, int width, |
int menu_height, const char *current, int item_no, |
const char * const * items) |
|
{ |
int i, j, x, y, box_x, box_y; |
int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; |
WINDOW *dialog, *menu; |
FILE *f; |
|
max_choice = MIN (menu_height, item_no); |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
wattrset (dialog, border_attr); |
mvwaddch (dialog, height - 3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
wbkgdset (dialog, dialog_attr & A_COLOR); |
waddch (dialog, ACS_RTEE); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
|
wattrset (dialog, dialog_attr); |
print_autowrap (dialog, prompt, width - 2, 1, 3); |
|
menu_width = width - 6; |
box_y = height - menu_height - 5; |
box_x = (width - menu_width) / 2 - 1; |
|
/* create new window for the menu */ |
menu = subwin (dialog, menu_height, menu_width, |
y + box_y + 1, x + box_x + 1); |
keypad (menu, TRUE); |
|
/* draw a box around the menu items */ |
draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2, |
menubox_border_attr, menubox_attr); |
|
/* |
* Find length of longest item in order to center menu. |
* Set 'choice' to default item. |
*/ |
item_x = 0; |
for (i = 0; i < item_no; i++) { |
item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2)); |
if (strcmp(current, items[i*2]) == 0) choice = i; |
} |
|
item_x = (menu_width - item_x) / 2; |
|
/* get the scroll info from the temp file */ |
if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) { |
if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) && |
(scroll+max_choice > choice) && (scroll >= 0) && |
(scroll+max_choice <= item_no) ) { |
first_item = scroll; |
choice = choice - scroll; |
fclose(f); |
} else { |
scroll=0; |
remove("lxdialog.scrltmp"); |
fclose(f); |
f=NULL; |
} |
} |
if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) { |
if (choice >= item_no-max_choice/2) |
scroll = first_item = item_no-max_choice; |
else |
scroll = first_item = choice - max_choice/2; |
choice = choice - scroll; |
} |
|
/* Print the menu */ |
for (i=0; i < max_choice; i++) { |
print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice, |
(items[(first_item + i)*2][0] != ':')); |
} |
|
wnoutrefresh (menu); |
|
print_arrows(dialog, item_no, scroll, |
box_y, box_x+item_x+1, menu_height); |
|
print_buttons (dialog, height, width, 0); |
wmove (menu, choice, item_x+1); |
wrefresh (menu); |
|
while (key != ESC) { |
key = wgetch(menu); |
|
if (key < 256 && isalpha(key)) key = tolower(key); |
|
if (strchr("ynm", key)) |
i = max_choice; |
else { |
for (i = choice+1; i < max_choice; i++) { |
j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); |
if (key == tolower(items[(scroll+i)*2+1][j])) |
break; |
} |
if (i == max_choice) |
for (i = 0; i < max_choice; i++) { |
j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); |
if (key == tolower(items[(scroll+i)*2+1][j])) |
break; |
} |
} |
|
if (i < max_choice || |
key == KEY_UP || key == KEY_DOWN || |
key == '-' || key == '+' || |
key == KEY_PPAGE || key == KEY_NPAGE) { |
|
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, |
(items[(scroll+choice)*2][0] != ':')); |
|
if (key == KEY_UP || key == '-') { |
if (choice < 2 && scroll) { |
/* Scroll menu down */ |
scrollok (menu, TRUE); |
wscrl (menu, -1); |
scrollok (menu, FALSE); |
|
scroll--; |
|
print_item (menu, items[scroll * 2 + 1], 0, FALSE, |
(items[scroll*2][0] != ':')); |
} else |
choice = MAX(choice - 1, 0); |
|
} else if (key == KEY_DOWN || key == '+') { |
|
print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, |
(items[(scroll+choice)*2][0] != ':')); |
|
if ((choice > max_choice-3) && |
(scroll + max_choice < item_no) |
) { |
/* Scroll menu up */ |
scrollok (menu, TRUE); |
scroll (menu); |
scrollok (menu, FALSE); |
|
scroll++; |
|
print_item (menu, items[(scroll+max_choice-1)*2+1], |
max_choice-1, FALSE, |
(items[(scroll+max_choice-1)*2][0] != ':')); |
} else |
choice = MIN(choice+1, max_choice-1); |
|
} else if (key == KEY_PPAGE) { |
scrollok (menu, TRUE); |
for (i=0; (i < max_choice); i++) { |
if (scroll > 0) { |
wscrl (menu, -1); |
scroll--; |
print_item (menu, items[scroll * 2 + 1], 0, FALSE, |
(items[scroll*2][0] != ':')); |
} else { |
if (choice > 0) |
choice--; |
} |
} |
scrollok (menu, FALSE); |
|
} else if (key == KEY_NPAGE) { |
for (i=0; (i < max_choice); i++) { |
if (scroll+max_choice < item_no) { |
scrollok (menu, TRUE); |
scroll(menu); |
scrollok (menu, FALSE); |
scroll++; |
print_item (menu, items[(scroll+max_choice-1)*2+1], |
max_choice-1, FALSE, |
(items[(scroll+max_choice-1)*2][0] != ':')); |
} else { |
if (choice+1 < max_choice) |
choice++; |
} |
} |
|
} else |
choice = i; |
|
print_item (menu, items[(scroll+choice)*2+1], choice, TRUE, |
(items[(scroll+choice)*2][0] != ':')); |
|
print_arrows(dialog, item_no, scroll, |
box_y, box_x+item_x+1, menu_height); |
|
wnoutrefresh (dialog); |
wrefresh (menu); |
|
continue; /* wait for another key press */ |
} |
|
switch (key) { |
case KEY_LEFT: |
case TAB: |
case KEY_RIGHT: |
button = ((key == KEY_LEFT ? --button : ++button) < 0) |
? 2 : (button > 2 ? 0 : button); |
|
print_buttons(dialog, height, width, button); |
wrefresh (menu); |
break; |
case ' ': |
case 's': |
case 'y': |
case 'n': |
case 'm': |
/* save scroll info */ |
if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) { |
fprintf(f,"%d\n",scroll); |
fclose(f); |
} |
delwin (dialog); |
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); |
switch (key) { |
case 's': return 3; |
case 'y': return 3; |
case 'n': return 4; |
case 'm': return 5; |
case ' ': return 6; |
} |
return 0; |
case 'h': |
case '?': |
button = 2; |
case '\n': |
delwin (dialog); |
if (button == 2) |
fprintf(stderr, "%s \"%s\"\n", |
items[(scroll + choice) * 2], |
items[(scroll + choice) * 2 + 1] + |
first_alpha(items[(scroll + choice) * 2 + 1],"")); |
else |
fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); |
|
remove("lxdialog.scrltmp"); |
return button; |
case 'e': |
case 'x': |
key = ESC; |
case ESC: |
break; |
} |
} |
|
delwin (dialog); |
remove("lxdialog.scrltmp"); |
return -1; /* ESC pressed */ |
} |
/lxdialog/yesno.c
0,0 → 1,118
/* |
* yesno.c -- implements the yes/no box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
/* |
* Display termination buttons |
*/ |
static void |
print_buttons(WINDOW *dialog, int height, int width, int selected) |
{ |
int x = width / 2 - 10; |
int y = height - 2; |
|
print_button (dialog, " Yes ", y, x, selected == 0); |
print_button (dialog, " No ", y, x + 13, selected == 1); |
|
wmove(dialog, y, x+1 + 13*selected ); |
wrefresh (dialog); |
} |
|
/* |
* Display a dialog box with two buttons - Yes and No |
*/ |
int |
dialog_yesno (const char *title, const char *prompt, int height, int width) |
{ |
int i, x, y, key = 0, button = 0; |
WINDOW *dialog; |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
wattrset (dialog, border_attr); |
mvwaddch (dialog, height-3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
waddch (dialog, ACS_RTEE); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
|
wattrset (dialog, dialog_attr); |
print_autowrap (dialog, prompt, width - 2, 1, 3); |
|
print_buttons(dialog, height, width, 0); |
|
while (key != ESC) { |
key = wgetch (dialog); |
switch (key) { |
case 'Y': |
case 'y': |
delwin (dialog); |
return 0; |
case 'N': |
case 'n': |
delwin (dialog); |
return 1; |
|
case TAB: |
case KEY_LEFT: |
case KEY_RIGHT: |
button = ((key == KEY_LEFT ? --button : ++button) < 0) |
? 1 : (button > 1 ? 0 : button); |
|
print_buttons(dialog, height, width, button); |
wrefresh (dialog); |
break; |
case ' ': |
case '\n': |
delwin (dialog); |
return button; |
case ESC: |
break; |
} |
} |
|
delwin (dialog); |
return -1; /* ESC pressed */ |
} |
/lxdialog/BIG.FAT.WARNING
0,0 → 1,4
This is NOT the official version of dialog. This version has been |
significantly modified from the original. It is for use by the Linux |
kernel configuration script. Please do not bother Savio Lam with |
questions about this program. |
/lxdialog/textbox.c
0,0 → 1,556
/* |
* textbox.c -- implements the text box |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
static void back_lines (int n); |
static void print_page (WINDOW * win, int height, int width); |
static void print_line (WINDOW * win, int row, int width); |
static char *get_line (void); |
static void print_position (WINDOW * win, int height, int width); |
|
static int hscroll = 0, fd, file_size, bytes_read; |
static int begin_reached = 1, end_reached = 0, page_length; |
static char *buf, *page; |
|
/* |
* Display text from a file in a dialog box. |
*/ |
int |
dialog_textbox (const char *title, const char *file, int height, int width) |
{ |
int i, x, y, cur_x, cur_y, fpos, key = 0; |
int passed_end; |
char search_term[MAX_LEN + 1]; |
WINDOW *dialog, *text; |
|
search_term[0] = '\0'; /* no search term entered yet */ |
|
/* Open input file for reading */ |
if ((fd = open (file, O_RDONLY)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nCan't open input file in dialog_textbox().\n"); |
exit (-1); |
} |
/* Get file size. Actually, 'file_size' is the real file size - 1, |
since it's only the last byte offset from the beginning */ |
if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { |
endwin (); |
fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); |
exit (-1); |
} |
/* Restore file pointer to beginning of file after getting file size */ |
if (lseek (fd, 0, SEEK_SET) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); |
exit (-1); |
} |
/* Allocate space for read buffer */ |
if ((buf = malloc (BUF_SIZE + 1)) == NULL) { |
endwin (); |
fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); |
exit (-1); |
} |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, "\nError reading file in dialog_textbox().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; /* mark end of valid data */ |
page = buf; /* page is pointer to start of page to be displayed */ |
|
/* center dialog box on screen */ |
x = (COLS - width) / 2; |
y = (LINES - height) / 2; |
|
|
draw_shadow (stdscr, y, x, height, width); |
|
dialog = newwin (height, width, y, x); |
keypad (dialog, TRUE); |
|
/* Create window for text region, used for scrolling text */ |
text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); |
wattrset (text, dialog_attr); |
wbkgdset (text, dialog_attr & A_COLOR); |
|
keypad (text, TRUE); |
|
/* register the new window, along with its borders */ |
draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); |
|
wattrset (dialog, border_attr); |
mvwaddch (dialog, height-3, 0, ACS_LTEE); |
for (i = 0; i < width - 2; i++) |
waddch (dialog, ACS_HLINE); |
wattrset (dialog, dialog_attr); |
wbkgdset (dialog, dialog_attr & A_COLOR); |
waddch (dialog, ACS_RTEE); |
|
if (title != NULL && strlen(title) >= width-2 ) { |
/* truncate long title -- mec */ |
char * title2 = malloc(width-2+1); |
memcpy( title2, title, width-2 ); |
title2[width-2] = '\0'; |
title = title2; |
} |
|
if (title != NULL) { |
wattrset (dialog, title_attr); |
mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); |
waddstr (dialog, (char *)title); |
waddch (dialog, ' '); |
} |
print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE); |
wnoutrefresh (dialog); |
getyx (dialog, cur_y, cur_x); /* Save cursor position */ |
|
/* Print first page of text */ |
attr_clear (text, height - 4, width - 2, dialog_attr); |
print_page (text, height - 4, width - 2); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ |
wrefresh (dialog); |
|
while ((key != ESC) && (key != '\n')) { |
key = wgetch (dialog); |
switch (key) { |
case 'E': /* Exit */ |
case 'e': |
case 'X': |
case 'x': |
delwin (dialog); |
free (buf); |
close (fd); |
return 0; |
case 'g': /* First page */ |
case KEY_HOME: |
if (!begin_reached) { |
begin_reached = 1; |
/* First page not in buffer? */ |
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError moving file pointer in dialog_textbox().\n"); |
exit (-1); |
} |
if (fpos > bytes_read) { /* Yes, we have to read it in */ |
if (lseek (fd, 0, SEEK_SET) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in " |
"dialog_textbox().\n"); |
exit (-1); |
} |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError reading file in dialog_textbox().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; |
} |
page = buf; |
print_page (text, height - 4, width - 2); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ |
wrefresh (dialog); |
} |
break; |
case 'G': /* Last page */ |
case KEY_END: |
|
end_reached = 1; |
/* Last page not in buffer? */ |
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError moving file pointer in dialog_textbox().\n"); |
exit (-1); |
} |
if (fpos < file_size) { /* Yes, we have to read it in */ |
if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError moving file pointer in dialog_textbox().\n"); |
exit (-1); |
} |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError reading file in dialog_textbox().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; |
} |
page = buf + bytes_read; |
back_lines (height - 4); |
print_page (text, height - 4, width - 2); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ |
wrefresh (dialog); |
break; |
case 'K': /* Previous line */ |
case 'k': |
case KEY_UP: |
if (!begin_reached) { |
back_lines (page_length + 1); |
|
/* We don't call print_page() here but use scrolling to ensure |
faster screen update. However, 'end_reached' and |
'page_length' should still be updated, and 'page' should |
point to start of next page. This is done by calling |
get_line() in the following 'for' loop. */ |
scrollok (text, TRUE); |
wscrl (text, -1); /* Scroll text region down one line */ |
scrollok (text, FALSE); |
page_length = 0; |
passed_end = 0; |
for (i = 0; i < height - 4; i++) { |
if (!i) { |
/* print first line of page */ |
print_line (text, 0, width - 2); |
wnoutrefresh (text); |
} else |
/* Called to update 'end_reached' and 'page' */ |
get_line (); |
if (!passed_end) |
page_length++; |
if (end_reached && !passed_end) |
passed_end = 1; |
} |
|
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ |
wrefresh (dialog); |
} |
break; |
case 'B': /* Previous page */ |
case 'b': |
case KEY_PPAGE: |
if (begin_reached) |
break; |
back_lines (page_length + height - 4); |
print_page (text, height - 4, width - 2); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); |
wrefresh (dialog); |
break; |
case 'J': /* Next line */ |
case 'j': |
case KEY_DOWN: |
if (!end_reached) { |
begin_reached = 0; |
scrollok (text, TRUE); |
scroll (text); /* Scroll text region up one line */ |
scrollok (text, FALSE); |
print_line (text, height - 5, width - 2); |
wnoutrefresh (text); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); /* Restore cursor position */ |
wrefresh (dialog); |
} |
break; |
case KEY_NPAGE: /* Next page */ |
case ' ': |
if (end_reached) |
break; |
|
begin_reached = 0; |
print_page (text, height - 4, width - 2); |
print_position (dialog, height, width); |
wmove (dialog, cur_y, cur_x); |
wrefresh (dialog); |
break; |
case '0': /* Beginning of line */ |
case 'H': /* Scroll left */ |
case 'h': |
case KEY_LEFT: |
if (hscroll <= 0) |
break; |
|
if (key == '0') |
hscroll = 0; |
else |
hscroll--; |
/* Reprint current page to scroll horizontally */ |
back_lines (page_length); |
print_page (text, height - 4, width - 2); |
wmove (dialog, cur_y, cur_x); |
wrefresh (dialog); |
break; |
case 'L': /* Scroll right */ |
case 'l': |
case KEY_RIGHT: |
if (hscroll >= MAX_LEN) |
break; |
hscroll++; |
/* Reprint current page to scroll horizontally */ |
back_lines (page_length); |
print_page (text, height - 4, width - 2); |
wmove (dialog, cur_y, cur_x); |
wrefresh (dialog); |
break; |
case ESC: |
break; |
} |
} |
|
delwin (dialog); |
free (buf); |
close (fd); |
return -1; /* ESC pressed */ |
} |
|
/* |
* Go back 'n' lines in text file. Called by dialog_textbox(). |
* 'page' will be updated to point to the desired line in 'buf'. |
*/ |
static void |
back_lines (int n) |
{ |
int i, fpos; |
|
begin_reached = 0; |
/* We have to distinguish between end_reached and !end_reached |
since at end of file, the line is not ended by a '\n'. |
The code inside 'if' basically does a '--page' to move one |
character backward so as to skip '\n' of the previous line */ |
if (!end_reached) { |
/* Either beginning of buffer or beginning of file reached? */ |
if (page == buf) { |
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in " |
"back_lines().\n"); |
exit (-1); |
} |
if (fpos > bytes_read) { /* Not beginning of file yet */ |
/* We've reached beginning of buffer, but not beginning of |
file yet, so read previous part of file into buffer. |
Note that we only move backward for BUF_SIZE/2 bytes, |
but not BUF_SIZE bytes to avoid re-reading again in |
print_page() later */ |
/* Really possible to move backward BUF_SIZE/2 bytes? */ |
if (fpos < BUF_SIZE / 2 + bytes_read) { |
/* No, move less then */ |
if (lseek (fd, 0, SEEK_SET) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in " |
"back_lines().\n"); |
exit (-1); |
} |
page = buf + fpos - bytes_read; |
} else { /* Move backward BUF_SIZE/2 bytes */ |
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) |
== -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer " |
"in back_lines().\n"); |
exit (-1); |
} |
page = buf + BUF_SIZE / 2; |
} |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, "\nError reading file in back_lines().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; |
} else { /* Beginning of file reached */ |
begin_reached = 1; |
return; |
} |
} |
if (*(--page) != '\n') { /* '--page' here */ |
/* Something's wrong... */ |
endwin (); |
fprintf (stderr, "\nInternal error in back_lines().\n"); |
exit (-1); |
} |
} |
/* Go back 'n' lines */ |
for (i = 0; i < n; i++) |
do { |
if (page == buf) { |
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, |
"\nError moving file pointer in back_lines().\n"); |
exit (-1); |
} |
if (fpos > bytes_read) { |
/* Really possible to move backward BUF_SIZE/2 bytes? */ |
if (fpos < BUF_SIZE / 2 + bytes_read) { |
/* No, move less then */ |
if (lseek (fd, 0, SEEK_SET) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer " |
"in back_lines().\n"); |
exit (-1); |
} |
page = buf + fpos - bytes_read; |
} else { /* Move backward BUF_SIZE/2 bytes */ |
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), |
SEEK_CUR) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer" |
" in back_lines().\n"); |
exit (-1); |
} |
page = buf + BUF_SIZE / 2; |
} |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, "\nError reading file in " |
"back_lines().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; |
} else { /* Beginning of file reached */ |
begin_reached = 1; |
return; |
} |
} |
} while (*(--page) != '\n'); |
page++; |
} |
|
/* |
* Print a new page of text. Called by dialog_textbox(). |
*/ |
static void |
print_page (WINDOW * win, int height, int width) |
{ |
int i, passed_end = 0; |
|
page_length = 0; |
for (i = 0; i < height; i++) { |
print_line (win, i, width); |
if (!passed_end) |
page_length++; |
if (end_reached && !passed_end) |
passed_end = 1; |
} |
wnoutrefresh (win); |
} |
|
/* |
* Print a new line of text. Called by dialog_textbox() and print_page(). |
*/ |
static void |
print_line (WINDOW * win, int row, int width) |
{ |
int y, x; |
char *line; |
|
line = get_line (); |
line += MIN (strlen (line), hscroll); /* Scroll horizontally */ |
wmove (win, row, 0); /* move cursor to correct line */ |
waddch (win, ' '); |
waddnstr (win, line, MIN (strlen (line), width - 2)); |
|
getyx (win, y, x); |
/* Clear 'residue' of previous line */ |
#if OLD_NCURSES |
{ |
int i; |
for (i = 0; i < width - x; i++) |
waddch (win, ' '); |
} |
#else |
wclrtoeol(win); |
#endif |
} |
|
/* |
* Return current line of text. Called by dialog_textbox() and print_line(). |
* 'page' should point to start of current line before calling, and will be |
* updated to point to start of next line. |
*/ |
static char * |
get_line (void) |
{ |
int i = 0, fpos; |
static char line[MAX_LEN + 1]; |
|
end_reached = 0; |
while (*page != '\n') { |
if (*page == '\0') { |
/* Either end of file or end of buffer reached */ |
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in " |
"get_line().\n"); |
exit (-1); |
} |
if (fpos < file_size) { /* Not end of file yet */ |
/* We've reached end of buffer, but not end of file yet, |
so read next part of file into buffer */ |
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { |
endwin (); |
fprintf (stderr, "\nError reading file in get_line().\n"); |
exit (-1); |
} |
buf[bytes_read] = '\0'; |
page = buf; |
} else { |
if (!end_reached) |
end_reached = 1; |
break; |
} |
} else if (i < MAX_LEN) |
line[i++] = *(page++); |
else { |
/* Truncate lines longer than MAX_LEN characters */ |
if (i == MAX_LEN) |
line[i++] = '\0'; |
page++; |
} |
} |
if (i <= MAX_LEN) |
line[i] = '\0'; |
if (!end_reached) |
page++; /* move pass '\n' */ |
|
return line; |
} |
|
/* |
* Print current position |
*/ |
static void |
print_position (WINDOW * win, int height, int width) |
{ |
int fpos, percent; |
|
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { |
endwin (); |
fprintf (stderr, "\nError moving file pointer in print_position().\n"); |
exit (-1); |
} |
wattrset (win, position_indicator_attr); |
wbkgdset (win, position_indicator_attr & A_COLOR); |
percent = !file_size ? |
100 : ((fpos - bytes_read + page - buf) * 100) / file_size; |
wmove (win, height - 3, width - 9); |
wprintw (win, "(%3d%%)", percent); |
} |
/lxdialog/util.c
0,0 → 1,359
/* |
* util.c |
* |
* ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) |
* MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) |
* |
* This program is free software; you can redistribute it and/or |
* modify it under the terms of the GNU General Public License |
* as published by the Free Software Foundation; either version 2 |
* of the License, or (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
*/ |
|
#include "dialog.h" |
|
|
/* use colors by default? */ |
bool use_colors = 1; |
|
const char *backtitle = NULL; |
|
const char *dialog_result; |
|
/* |
* Attribute values, default is for mono display |
*/ |
chtype attributes[] = |
{ |
A_NORMAL, /* screen_attr */ |
A_NORMAL, /* shadow_attr */ |
A_NORMAL, /* dialog_attr */ |
A_BOLD, /* title_attr */ |
A_NORMAL, /* border_attr */ |
A_REVERSE, /* button_active_attr */ |
A_DIM, /* button_inactive_attr */ |
A_REVERSE, /* button_key_active_attr */ |
A_BOLD, /* button_key_inactive_attr */ |
A_REVERSE, /* button_label_active_attr */ |
A_NORMAL, /* button_label_inactive_attr */ |
A_NORMAL, /* inputbox_attr */ |
A_NORMAL, /* inputbox_border_attr */ |
A_NORMAL, /* searchbox_attr */ |
A_BOLD, /* searchbox_title_attr */ |
A_NORMAL, /* searchbox_border_attr */ |
A_BOLD, /* position_indicator_attr */ |
A_NORMAL, /* menubox_attr */ |
A_NORMAL, /* menubox_border_attr */ |
A_NORMAL, /* item_attr */ |
A_REVERSE, /* item_selected_attr */ |
A_BOLD, /* tag_attr */ |
A_REVERSE, /* tag_selected_attr */ |
A_BOLD, /* tag_key_attr */ |
A_REVERSE, /* tag_key_selected_attr */ |
A_BOLD, /* check_attr */ |
A_REVERSE, /* check_selected_attr */ |
A_BOLD, /* uarrow_attr */ |
A_BOLD /* darrow_attr */ |
}; |
|
|
#include "colors.h" |
|
/* |
* Table of color values |
*/ |
int color_table[][3] = |
{ |
{SCREEN_FG, SCREEN_BG, SCREEN_HL}, |
{SHADOW_FG, SHADOW_BG, SHADOW_HL}, |
{DIALOG_FG, DIALOG_BG, DIALOG_HL}, |
{TITLE_FG, TITLE_BG, TITLE_HL}, |
{BORDER_FG, BORDER_BG, BORDER_HL}, |
{BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, |
{BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, |
{BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, |
{BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, |
{BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, |
{BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, |
BUTTON_LABEL_INACTIVE_HL}, |
{INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, |
{INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, |
{SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, |
{SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, |
{SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, |
{POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, |
{MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, |
{MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, |
{ITEM_FG, ITEM_BG, ITEM_HL}, |
{ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, |
{TAG_FG, TAG_BG, TAG_HL}, |
{TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, |
{TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, |
{TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, |
{CHECK_FG, CHECK_BG, CHECK_HL}, |
{CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, |
{UARROW_FG, UARROW_BG, UARROW_HL}, |
{DARROW_FG, DARROW_BG, DARROW_HL}, |
}; /* color_table */ |
|
/* |
* Set window to attribute 'attr' |
*/ |
void |
attr_clear (WINDOW * win, int height, int width, chtype attr) |
{ |
int i, j; |
|
wattrset (win, attr); |
for (i = 0; i < height; i++) { |
wmove (win, i, 0); |
for (j = 0; j < width; j++) |
waddch (win, ' '); |
} |
touchwin (win); |
} |
|
void dialog_clear (void) |
{ |
attr_clear (stdscr, LINES, COLS, screen_attr); |
/* Display background title if it exists ... - SLH */ |
if (backtitle != NULL) { |
int i; |
|
wattrset (stdscr, screen_attr); |
mvwaddstr (stdscr, 0, 1, (char *)backtitle); |
wmove (stdscr, 1, 1); |
for (i = 1; i < COLS - 1; i++) |
waddch (stdscr, ACS_HLINE); |
} |
wnoutrefresh (stdscr); |
} |
|
/* |
* Do some initialization for dialog |
*/ |
void |
init_dialog (void) |
{ |
initscr (); /* Init curses */ |
keypad (stdscr, TRUE); |
cbreak (); |
noecho (); |
|
|
if (use_colors) /* Set up colors */ |
color_setup (); |
|
|
dialog_clear (); |
} |
|
/* |
* Setup for color display |
*/ |
void |
color_setup (void) |
{ |
int i; |
|
if (has_colors ()) { /* Terminal supports color? */ |
start_color (); |
|
/* Initialize color pairs */ |
for (i = 0; i < ATTRIBUTE_COUNT; i++) |
init_pair (i + 1, color_table[i][0], color_table[i][1]); |
|
/* Setup color attributes */ |
for (i = 0; i < ATTRIBUTE_COUNT; i++) |
attributes[i] = C_ATTR (color_table[i][2], i + 1); |
} |
} |
|
/* |
* End using dialog functions. |
*/ |
void |
end_dialog (void) |
{ |
endwin (); |
} |
|
|
/* |
* Print a string of text in a window, automatically wrap around to the |
* next line if the string is too long to fit on one line. Newline |
* characters '\n' are replaced by spaces. We start on a new line |
* if there is no room for at least 4 nonblanks following a double-space. |
*/ |
void |
print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) |
{ |
int newl, cur_x, cur_y; |
int i, prompt_len, room, wlen; |
char tempstr[MAX_LEN + 1], *word, *sp, *sp2; |
|
strcpy (tempstr, prompt); |
|
prompt_len = strlen(tempstr); |
|
/* |
* Remove newlines |
*/ |
for(i=0; i<prompt_len; i++) { |
if(tempstr[i] == '\n') tempstr[i] = ' '; |
} |
|
if (prompt_len <= width - x * 2) { /* If prompt is short */ |
wmove (win, y, (width - prompt_len) / 2); |
waddstr (win, tempstr); |
} else { |
cur_x = x; |
cur_y = y; |
newl = 1; |
word = tempstr; |
while (word && *word) { |
sp = index(word, ' '); |
if (sp) |
*sp++ = 0; |
|
/* Wrap to next line if either the word does not fit, |
or it is the first word of a new sentence, and it is |
short, and the next word does not fit. */ |
room = width - cur_x; |
wlen = strlen(word); |
if (wlen > room || |
(newl && wlen < 4 && sp && wlen+1+strlen(sp) > room |
&& (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { |
cur_y++; |
cur_x = x; |
} |
wmove (win, cur_y, cur_x); |
waddstr (win, word); |
getyx (win, cur_y, cur_x); |
cur_x++; |
if (sp && *sp == ' ') { |
cur_x++; /* double space */ |
while (*++sp == ' '); |
newl = 1; |
} else |
newl = 0; |
word = sp; |
} |
} |
} |
|
/* |
* Print a button |
*/ |
void |
print_button (WINDOW * win, const char *label, int y, int x, int selected) |
{ |
int i, temp; |
|
wmove (win, y, x); |
wattrset (win, selected ? button_active_attr : button_inactive_attr); |
waddstr (win, "<"); |
temp = strspn (label, " "); |
label += temp; |
wattrset (win, selected ? button_label_active_attr |
: button_label_inactive_attr); |
for (i = 0; i < temp; i++) |
waddch (win, ' '); |
wattrset (win, selected ? button_key_active_attr |
: button_key_inactive_attr); |
waddch (win, label[0]); |
wattrset (win, selected ? button_label_active_attr |
: button_label_inactive_attr); |
waddstr (win, (char *)label + 1); |
wattrset (win, selected ? button_active_attr : button_inactive_attr); |
waddstr (win, ">"); |
wmove (win, y, x + temp + 1); |
} |
|
/* |
* Draw a rectangular box with line drawing characters |
*/ |
void |
draw_box (WINDOW * win, int y, int x, int height, int width, |
chtype box, chtype border) |
{ |
int i, j; |
|
wattrset (win, 0); |
for (i = 0; i < height; i++) { |
wmove (win, y + i, x); |
for (j = 0; j < width; j++) |
if (!i && !j) |
waddch (win, border | ACS_ULCORNER); |
else if (i == height - 1 && !j) |
waddch (win, border | ACS_LLCORNER); |
else if (!i && j == width - 1) |
waddch (win, box | ACS_URCORNER); |
else if (i == height - 1 && j == width - 1) |
waddch (win, box | ACS_LRCORNER); |
else if (!i) |
waddch (win, border | ACS_HLINE); |
else if (i == height - 1) |
waddch (win, box | ACS_HLINE); |
else if (!j) |
waddch (win, border | ACS_VLINE); |
else if (j == width - 1) |
waddch (win, box | ACS_VLINE); |
else |
waddch (win, box | ' '); |
} |
} |
|
/* |
* Draw shadows along the right and bottom edge to give a more 3D look |
* to the boxes |
*/ |
void |
draw_shadow (WINDOW * win, int y, int x, int height, int width) |
{ |
int i; |
|
if (has_colors ()) { /* Whether terminal supports color? */ |
wattrset (win, shadow_attr); |
wmove (win, y + height, x + 2); |
for (i = 0; i < width; i++) |
waddch (win, winch (win) & A_CHARTEXT); |
for (i = y + 1; i < y + height + 1; i++) { |
wmove (win, i, x + width); |
waddch (win, winch (win) & A_CHARTEXT); |
waddch (win, winch (win) & A_CHARTEXT); |
} |
wnoutrefresh (win); |
} |
} |
|
/* |
* Return the position of the first alphabetic character in a string. |
*/ |
int |
first_alpha(const char *string, const char *exempt) |
{ |
int i, in_paren=0, c; |
|
for (i = 0; i < strlen(string); i++) { |
c = tolower(string[i]); |
|
if (strchr("<[(", c)) ++in_paren; |
if (strchr(">])", c)) --in_paren; |
|
if ((! in_paren) && isalpha(c) && |
strchr(exempt, c) == 0) |
return i; |
} |
|
return 0; |
} |
/header.tk
0,0 → 1,637
# FILE: header.tk |
# This file is boilerplate TCL/TK function definitions for 'make xconfig'. |
# |
# CHANGES |
# ======= |
# |
# 8 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
# - Remove unused do_cmd function (part of the 2.0 sound support). |
# - Arrange buttons in three columns for better screen fitting. |
# - Add CONSTANT_Y, CONSTANT_M, CONSTANT_N for commands like: |
# dep_tristate 'foo' CONFIG_FOO m |
# |
# 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
# - Shut vfix the hell up. |
# |
# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
# - Improve the exit message (Jeff Ronne). |
|
# |
# This is a handy replacement for ".widget cget" that requires neither tk4 |
# nor additional source code uglification. |
# |
proc cget { w option } { |
return "[lindex [$w configure $option] 4]" |
} |
|
# |
# Function to compensate for broken config.in scripts like the sound driver, |
# which make dependencies on variables that are never even conditionally |
# defined. |
# |
proc vfix { var } { |
global $var |
if [ catch {eval concat $$var} ] { |
set $var 4 |
} |
} |
|
# |
# Constant values used by certain dep_tristate commands. |
# |
set CONSTANT_Y 1 |
set CONSTANT_M 2 |
set CONSTANT_N 0 |
set CONSTANT_E 4 |
|
# |
# Create a "reference" object to steal colors from. |
# |
button .ref |
|
# |
# On monochrome displays, -disabledforeground is blank by default; that's |
# bad. Fill it with -foreground instead. |
# |
if { [cget .ref -disabledforeground] == "" } { |
.ref configure -disabledforeground [cget .ref -foreground] |
} |
|
|
# |
# Define some macros we will need to parse the config.in file. |
# |
|
proc mainmenu_name { text } { |
wm title . "$text" |
} |
|
proc menu_option { w menu_num text } { |
global menus_per_column |
global processed_top_level |
set processed_top_level [expr $processed_top_level + 1] |
if { $processed_top_level <= $menus_per_column } then { |
set myframe left |
} elseif { $processed_top_level <= [expr 2 * $menus_per_column] } then { |
set myframe middle |
} else { |
set myframe right |
} |
button .f0.x$menu_num -anchor w -text "$text" \ |
-command "$w .$w \"$text\"" |
pack .f0.x$menu_num -pady 0 -side top -fill x -in .f0.$myframe |
} |
|
proc load_configfile { w title func } { |
catch {destroy $w} |
toplevel $w -class Dialog |
global loadfile |
frame $w.x |
label $w.bm -bitmap questhead |
pack $w.bm -pady 10 -side top -padx 10 |
label $w.x.l -text "Enter filename:" -relief raised |
entry $w.x.x -width 35 -relief sunken -borderwidth 2 \ |
-textvariable loadfile |
pack $w.x.l $w.x.x -anchor w -side left |
pack $w.x -side top -pady 10 |
wm title $w "$title" |
|
set oldFocus [focus] |
frame $w.f |
button $w.f.back -text "OK" -width 20 \ |
-command "destroy $w; focus $oldFocus;$func .fileio" |
button $w.f.canc -text "Cancel" \ |
-width 20 -command "destroy $w; focus $oldFocus" |
pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 |
pack $w.f -pady 10 -side bottom -padx 10 -anchor w |
focus $w |
global winx; global winy |
set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] |
wm geometry $w +$winx+$winy |
} |
|
bind all <Alt-q> {maybe_exit .maybe} |
|
proc maybe_exit { w } { |
catch {destroy $w} |
toplevel $w -class Dialog |
label $w.bm -bitmap questhead |
pack $w.bm -pady 10 -side top -padx 10 |
message $w.m -width 400 -aspect 300 \ |
-text "Changes will be lost. Are you sure?" -relief flat |
pack $w.m -pady 10 -side top -padx 10 |
wm title $w "Are you sure?" |
|
set oldFocus [focus] |
frame $w.f |
button $w.f.back -text "OK" -width 20 \ |
-command "exit" |
button $w.f.canc -text "Cancel" \ |
-width 20 -command "destroy $w; focus $oldFocus" |
pack $w.f.back $w.f.canc -side left -pady 10 -padx 45 |
pack $w.f -pady 10 -side bottom -padx 10 -anchor w |
bind $w <Return> "exit" |
bind $w <Escape> "destroy $w; focus $oldFocus" |
focus $w |
global winx; global winy |
set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] |
wm geometry $w +$winx+$winy |
} |
|
proc read_config_file { w } { |
global loadfile |
if { [string length $loadfile] != 0 && [file readable $loadfile] == 1 } then { |
read_config $loadfile |
} else { |
catch {destroy $w} |
toplevel $w -class Dialog |
message $w.m -width 400 -aspect 300 -text \ |
"Unable to read file $loadfile" \ |
-relief raised |
label $w.bm -bitmap error |
pack $w.bm $w.m -pady 10 -side top -padx 10 |
wm title $w "Xconfig Internal Error" |
|
set oldFocus [focus] |
frame $w.f |
button $w.f.back -text "Bummer" \ |
-width 10 -command "destroy $w; focus $oldFocus" |
pack $w.f.back -side bottom -pady 10 -anchor s |
pack $w.f -pady 10 -side top -padx 10 -anchor s |
focus $w |
global winx; global winy |
set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] |
wm geometry $w +$winx+$winy |
} |
} |
|
proc write_config_file { w } { |
global loadfile |
if { [string length $loadfile] != 0 |
&& ([file writable $loadfile] == 1 || ([file exists $loadfile] == 0 && [file writable [file dirname $loadfile]] == 1)) } then { |
writeconfig $loadfile /dev/null |
} else { |
catch {destroy $w} |
toplevel $w -class Dialog |
message $w.m -width 400 -aspect 300 -text \ |
"Unable to write file $loadfile" \ |
-relief raised |
label $w.bm -bitmap error |
pack $w.bm $w.m -pady 10 -side top -padx 10 |
wm title $w "Xconfig Internal Error" |
|
set oldFocus [focus] |
frame $w.f |
button $w.f.back -text "OK" \ |
-width 10 -command "destroy $w; focus $oldFocus" |
pack $w.f.back -side bottom -pady 10 -anchor s |
pack $w.f -pady 10 -side top -padx 10 -anchor s |
focus $w |
global winx; global winy |
set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] |
wm geometry $w +$winx+$winy |
} |
} |
|
proc read_config { filename } { |
set file1 [open $filename r] |
clear_choices |
while { [gets $file1 line] >= 0} { |
if [regexp {([0-9A-Za-z_]+)=([ynm])} $line foo var value] { |
if { $value == "y" } then { set cmd "global $var; set $var 1" } |
if { $value == "n" } then { set cmd "global $var; set $var 0" } |
if { $value == "m" } then { set cmd "global $var; set $var 2" } |
eval $cmd |
} |
if [regexp {# ([0-9A-Za-z_]+) is not set} $line foo var] { |
set cmd "global $var; set $var 0" |
eval $cmd |
} |
if [regexp {([0-9A-Za-z_]+)=([0-9A-Fa-f]+)} $line foo var value] { |
set cmd "global $var; set $var $value" |
eval $cmd |
} |
if [regexp {([0-9A-Za-z_]+)="([^"]*)"} $line foo var value] { |
set cmd "global $var; set $var \"$value\"" |
eval $cmd |
} |
} |
close $file1 |
update_choices |
update_mainmenu |
} |
proc write_comment { file1 file2 text } { |
puts $file1 "" |
puts $file1 "#" |
puts $file1 "# $text" |
puts $file1 "#" |
puts $file2 "/*" |
puts $file2 " * $text" |
puts $file2 " */" |
} |
|
proc effective_dep { deplist } { |
global CONFIG_MODULES |
set depend 1 |
foreach i $deplist { |
if {$i == 0} then {set depend 0} |
if {$i == 2 && $depend == 1} then {set depend 2} |
} |
if {$depend == 2 && $CONFIG_MODULES == 0} then {set depend 0} |
return $depend |
} |
|
proc sync_tristate { var dep } { |
global CONFIG_MODULES |
if {$dep == 0 && ($var == 1 || $var == 2)} then { |
set var 0 |
} elseif {$dep == 2 && $var == 1} then { |
set var 2 |
} elseif {$var == 2 && $CONFIG_MODULES == 0} then { |
if {$dep == 1} then {set var 1} else {set var 0} |
} |
return $var |
} |
|
proc sync_bool { var dep modset } { |
set var [sync_tristate $var $dep] |
if {$dep == 2 && $var == 2} then { |
set var $modset |
} |
return $var |
} |
|
proc write_tristate { file1 file2 varname variable deplist modset } { |
set variable [sync_tristate $variable [effective_dep $deplist]] |
if { $variable == 2 } \ |
then { set variable $modset } |
if { $variable == 1 } \ |
then { puts $file1 "$varname=y"; \ |
puts $file2 "#define $varname 1" } \ |
elseif { $variable == 2 } \ |
then { puts $file1 "$varname=m"; \ |
puts $file2 "#undef $varname"; \ |
puts $file2 "#define ${varname}_MODULE 1" } \ |
elseif { $variable == 0 } \ |
then { puts $file1 "# $varname is not set"; \ |
puts $file2 "#undef $varname"} \ |
else { \ |
puts stdout "ERROR - Attempting to write value for unconfigured variable ($varname)." \ |
} |
} |
|
proc write_int { file1 file2 varname variable dep } { |
if { $dep == 0 } \ |
then { puts $file1 "# $varname is not set"; \ |
puts $file2 "#undef $varname"} \ |
else { |
puts $file1 "$varname=$variable"; \ |
puts $file2 "#define $varname ($variable)"; \ |
} |
} |
|
proc write_hex { file1 file2 varname variable dep } { |
if { $dep == 0 } \ |
then { puts $file1 "# $varname is not set"; \ |
puts $file2 "#undef $varname"} \ |
else { |
puts $file1 "$varname=$variable"; \ |
puts -nonewline $file2 "#define $varname 0x"; \ |
puts $file2 [exec echo $variable | sed s/^0\[xX\]//]; \ |
} |
} |
|
proc write_string { file1 file2 varname variable dep } { |
if { $dep == 0 } \ |
then { puts $file1 "# $varname is not set"; \ |
puts $file2 "#undef $varname"} \ |
else { |
puts $file1 "$varname=\"$variable\""; \ |
puts $file2 "#define $varname \"$variable\""; \ |
} |
} |
|
proc option_name {w mnum line text helpidx} { |
button $w.x$line.l -text "$text" -relief groove -anchor w |
$w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ |
-activeback [cget $w.x$line.l -bg] |
button $w.x$line.help -text "Help" -relief raised \ |
-command "dohelp .dohelp $helpidx .menu$mnum" |
pack $w.x$line.help -side right -fill y |
pack $w.x$line.l -side right -fill both -expand on |
} |
|
proc toggle_switch2 {w mnum line text variable} { |
frame $w.x$line -relief sunken |
radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ |
-relief groove -width 2 -command "update_active" |
radiobutton $w.x$line.m -text "-" -variable $variable -value 2 \ |
-relief groove -width 2 -command "update_active" |
radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ |
-relief groove -width 2 -command "update_active" |
|
option_name $w $mnum $line $text $variable |
|
pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y |
} |
|
proc toggle_switch3 {w mnum line text variable} { |
frame $w.x$line -relief sunken |
radiobutton $w.x$line.y -text "y" -variable $variable -value 1 \ |
-relief groove -width 2 -command "update_active" |
radiobutton $w.x$line.m -text "m" -variable $variable -value 2 \ |
-relief groove -width 2 -command "update_active" |
radiobutton $w.x$line.n -text "n" -variable $variable -value 0 \ |
-relief groove -width 2 -command "update_active" |
|
option_name $w $mnum $line $text $variable |
|
global CONFIG_MODULES |
if {($CONFIG_MODULES == 0)} then { |
$w.x$line.m configure -state disabled |
} |
pack $w.x$line.n $w.x$line.m $w.x$line.y -side right -fill y |
} |
|
proc bool {w mnum line text variable} { |
toggle_switch2 $w $mnum $line $text $variable |
$w.x$line.m configure -state disabled |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc tristate {w mnum line text variable } { |
toggle_switch3 $w $mnum $line $text $variable |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc dep_tristate {w mnum line text variable } { |
tristate $w $mnum $line $text $variable |
} |
|
proc dep_bool {w mnum line text variable } { |
bool $w $mnum $line $text $variable |
} |
|
proc int { w mnum line text variable } { |
frame $w.x$line |
entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ |
-textvariable $variable |
option_name $w $mnum $line $text $variable |
pack $w.x$line.x -anchor w -side right -fill y |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc hex { w mnum line text variable } { |
int $w $mnum $line $text $variable |
} |
|
proc istring { w mnum line text variable } { |
frame $w.x$line |
entry $w.x$line.x -width 18 -relief sunken -borderwidth 2 \ |
-textvariable $variable |
option_name $w $mnum $line $text $variable |
pack $w.x$line.x -anchor w -side right -fill y |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc minimenu { w mnum line text variable helpidx } { |
frame $w.x$line |
menubutton $w.x$line.x -textvariable $variable -menu \ |
$w.x$line.x.menu -relief raised \ |
-anchor w |
option_name $w $mnum $line $text $helpidx |
pack $w.x$line.x -anchor w -side right -fill y |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc menusplit {w m n} { |
if { $n > 2 } then { |
update idletasks |
set menuoptsize [expr [$m yposition 2] - [$m yposition 1]] |
set maxsize [winfo screenheight $w] |
set splitpoint [expr $maxsize * 4 / 5 / $menuoptsize - 1] |
for {set i [expr $splitpoint + 1]} {$i <= $n} {incr i $splitpoint} { |
$m entryconfigure $i -columnbreak 1 |
} |
} |
} |
|
proc menutitle {text menu w} { |
wm title $w "$text" |
} |
|
proc submenu { w mnum line text subnum } { |
frame $w.x$line |
button $w.x$line.l -text "" -width 15 -relief groove |
$w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ |
-activeback [cget $w.x$line.l -bg] -state disabled |
button $w.x$line.m -text "$text" -relief raised -anchor w \ |
-command "catch {destroy .menu$subnum}; menu$subnum .menu$subnum \"$text\"" |
pack $w.x$line.l -side left -fill both |
pack $w.x$line.m -anchor w -side right -fill both -expand on |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc comment {w mnum line text } { |
frame $w.x$line |
button $w.x$line.l -text "" -width 15 -relief groove |
$w.x$line.l configure -activefore [cget $w.x$line.l -fg] \ |
-activeback [cget $w.x$line.l -bg] -state disabled |
button $w.x$line.m -text "$text" -relief groove -anchor w |
$w.x$line.m configure -activefore [cget $w.x$line.m -fg] \ |
-activeback [cget $w.x$line.m -bg] |
pack $w.x$line.l -side left -fill both |
pack $w.x$line.m -anchor w -side right -fill both -expand on |
pack $w.x$line -anchor w -fill both -expand on |
} |
|
proc dohelp {w var parent} { |
catch {destroy $w} |
toplevel $w -class Dialog |
|
set filefound 0 |
set found 0 |
set lineno 0 |
|
if { [file readable Documentation/Configure.help] == 1} then { |
set filefound 1 |
# First escape sed regexp special characters in var: |
set var [exec echo "$var" | sed s/\[\]\[\/.^$*\]/\\\\&/g] |
# Now pick out right help text: |
set message [exec sed -n " |
/^$var\[ \]*\$/,\${ |
/^$var\[ \]*\$/c\\ |
${var}:\\ |
|
/^#/b |
/^\[^ \]/q |
s/^ // |
/<file:\\(\[^>\]*\\)>/s//\\1/g |
p |
} |
" Documentation/Configure.help] |
set found [expr [string length "$message"] > 0] |
} |
|
frame $w.f1 |
pack $w.f1 -fill both -expand on |
|
# Do the OK button |
# |
set oldFocus [focus] |
frame $w.f2 |
button $w.f2.ok -text "OK" \ |
-width 10 -command "destroy $w; catch {focus $oldFocus}" |
pack $w.f2.ok -side bottom -pady 6 -anchor n |
pack $w.f2 -side bottom -padx 10 -anchor s |
|
scrollbar $w.f1.vscroll -command "$w.f1.canvas yview" |
pack $w.f1.vscroll -side right -fill y |
|
canvas $w.f1.canvas -relief flat -borderwidth 0 \ |
-yscrollcommand "$w.f1.vscroll set" |
frame $w.f1.f |
pack $w.f1.canvas -side right -fill y -expand on |
|
if { $found == 0 } then { |
if { $filefound == 0 } then { |
message $w.f1.f.m -width 750 -aspect 300 -relief flat -text \ |
"No help available - unable to open file Documentation/Configure.help. This file should have come with your kernel." |
} else { |
message $w.f1.f.m -width 400 -aspect 300 -relief flat -text \ |
"No help available for $var" |
} |
label $w.f1.bm -bitmap error |
wm title $w "RTFM" |
} else { |
text $w.f1.f.m -width 73 -relief flat -wrap word |
$w.f1.f.m insert 0.0 $message |
$w.f1.f.m conf -state disabled -height [$w.f1.f.m index end] |
|
label $w.f1.bm -bitmap info |
wm title $w "Configuration help" |
} |
pack $w.f1.f.m -side left |
pack $w.f1.bm $w.f1.f -side left -padx 10 |
|
focus $w |
set winx [expr [winfo x $parent]+20] |
set winy [expr [winfo y $parent]+20] |
wm geometry $w +$winx+$winy |
set sizok [expr [winfo reqheight $w.f2.ok] + 12] |
set maxy [expr [winfo screenheight .] * 3 / 4] |
set canvtotal [winfo reqheight $w.f1.f.m] |
if [expr $sizok + $canvtotal < $maxy] { |
set sizy $canvtotal |
} else { |
set sizy [expr $maxy - $sizok] |
} |
$w.f1.canvas configure -height $sizy -width [winfo reqwidth $w.f1.f.m] \ |
-scrollregion "0 0 [winfo reqwidth $w.f1.f.m] \ |
[winfo reqheight $w.f1.f.m]" |
$w.f1.canvas create window 0 0 -anchor nw -window $w.f1.f |
update idletasks |
|
set maxy [winfo screenheight .] |
if [expr $sizok + $canvtotal < $maxy] { |
set sizy [expr $sizok + $canvtotal] |
} else { |
set sizy $maxy |
} |
wm maxsize $w [winfo width $w] $sizy |
} |
|
bind all <Alt-s> { catch {exec cp -f .config .config.old}; \ |
writeconfig .config include/linux/autoconf.h; wrapup .wrap } |
|
proc wrapup {w } { |
catch {destroy $w} |
toplevel $w -class Dialog |
|
global CONFIG_MODVERSIONS; vfix CONFIG_MODVERSIONS |
if { ([file exists .hdepend] != 1) || ($CONFIG_MODVERSIONS == 1) } then { |
message $w.m -width 400 -aspect 300 -relief raised -text \ |
"End of Linux kernel configuration. Check the top-level Makefile for additional configuration. Next, you must run 'make dep'." |
} else { |
message $w.m -width 400 -aspect 300 -relief raised -text \ |
"End of Linux kernel configuration. Check the top-level Makefile for additional configuration. Next, you may 'make bzImage', 'make bzdisk', or 'make bzlilo.'" |
} |
label $w.bm -bitmap info |
pack $w.bm $w.m -pady 10 -side top -padx 10 |
wm title $w "Kernel build instructions" |
|
set oldFocus [focus] |
frame $w.f |
button $w.f.back -text "OK" \ |
-width 10 -command "exit" |
pack $w.f.back -side bottom -pady 10 -anchor s |
pack $w.f -pady 10 -side top -padx 10 -anchor s |
focus $w |
bind $w <Return> "exit" |
global winx; global winy |
set winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30] |
wm geometry $w +$winx+$winy |
|
} |
|
proc unregister_active {num} { |
global active_menus |
set index [lsearch -exact $active_menus $num] |
if {$index != -1} then {set active_menus [lreplace $active_menus $index $index]} |
} |
|
proc update_active {} { |
global active_menus total_menus |
set max 0 |
if {[llength $active_menus] > 0} then { |
set max [lindex $active_menus end] |
update_define [toplevel_menu [lindex $active_menus 0]] $max 0 |
} |
foreach i $active_menus { |
if {[winfo exists .menu$i] == 0} then { |
unregister_active $i |
} else { |
update_menu$i |
} |
} |
update_define [expr $max + 1] $total_menus 1 |
update_mainmenu |
} |
|
proc configure_entry {w option items} { |
foreach i $items { |
$w.$i configure -state $option |
} |
} |
|
proc validate_int {name val default} { |
if {([exec echo $val | sed s/^-//g | tr -d \[:digit:\] ] != "")} then { |
global $name; set $name $default |
} |
} |
|
proc validate_hex {name val default} { |
if {([exec echo $val | tr -d \[:xdigit:\] ] != "")} then { |
global $name; set $name $default |
} |
} |
|
proc update_define {first last allow_update} { |
for {set i $first} {$i <= $last} {incr i} { |
update_define_menu$i |
if {$allow_update == 1} then update |
} |
} |
|
# |
# Next set up the particulars for the top level menu, and define a few |
# buttons which we will stick down at the bottom. |
# |
|
frame .f0 |
frame .f0.left |
frame .f0.middle |
frame .f0.right |
|
set active_menus [list] |
set processed_top_level 0 |
/tail.tk
0,0 → 1,89
# FILE: tail.tk |
# This file is boilerplate TCL/TK function definitions for 'make xconfig'. |
# |
# CHANGES |
# ======= |
# |
# 8 January 1998, Michael Elizabeth Chastain, <mec@shout.net> |
# Arrange buttons in three columns for better screen fitting. |
# |
|
# |
# Read the user's settings from .config. These will override whatever is |
# in config.in. Don't do this if the user specified a -D to force |
# the defaults. |
# |
if { [file readable .config] == 1} then { |
if { $argc > 0 } then { |
if { [lindex $argv 0] != "-D" } then { |
read_config .config |
} |
else |
{ |
read_config $defaults |
} |
} else { |
read_config .config |
} |
} else { |
read_config $defaults |
} |
|
update_define 1 $total_menus 0 |
update_mainmenu |
|
button .f0.right.save -anchor w -text "Save and Exit" -underline 0\ |
-command { catch {exec cp -f .config .config.old}; \ |
writeconfig .config include/linux/autoconf.h; wrapup .wrap } |
|
button .f0.right.quit -anchor w -text "Quit Without Saving" -underline 0\ |
-command { maybe_exit .maybe } |
|
button .f0.right.load -anchor w -text "Load Configuration from File" \ |
-command { load_configfile .load "Load Configuration from file" read_config_file |
} |
|
button .f0.right.store -anchor w -text "Store Configuration to File" \ |
-command { load_configfile .load "Store Configuration to file" write_config_file } |
|
# |
# Now pack everything. |
# |
|
pack .f0.right.store .f0.right.load .f0.right.quit .f0.right.save \ |
-padx 0 -pady 0 -side bottom -fill x |
pack .f0.left .f0.middle .f0.right -side left -padx 5 -pady 0 -fill y |
pack .f0 -padx 5 -pady 5 |
|
update idletasks |
set winy [expr 10 + [winfo reqheight .f0]] |
set scry [lindex [wm maxsize .] 1] |
set winx [expr 10 + [winfo reqwidth .f0]] |
set scrx [lindex [wm maxsize .] 0] |
if {$winx < $scrx} then {set maxx -1} else {set maxx $winx} |
if {$winy < $scry} then {set maxy -1} else {set maxy $winy} |
.f0 configure -width $winx -height $winy |
wm maxsize . $maxx $maxy |
|
# |
# If we cannot write our config files, disable the write button. |
# |
if { [file exists .config] == 1 } then { |
if { [file writable .config] == 0 } then { |
.f0.right.save configure -state disabled |
} |
} else { |
if { [file writable .] == 0 } then { |
.f0.right.save configure -state disabled |
} |
} |
|
if { [file exists include/linux/autoconf.h] == 1 } then { |
if { [file writable include/linux/autoconf.h] == 0 } then { |
.f0.right.save configure -state disabled |
} |
} else { |
if { [file writable include/linux/] == 0 } then { |
.f0.right.save configure -state disabled |
} |
} |
/gen-all-syms
0,0 → 1,7
#!/bin/sh |
for i in $* |
do |
grep "EXPORT_SYMBOL.*(.*)" "$i" \ |
| sed -e "s/EXPORT_SYMBOL.*(/ /" \ |
| sed -e "s/).*$//" | sed -e "s/^ //" |
done |
/ver_linux
0,0 → 1,85
#!/bin/sh |
# Before running this script please ensure that your PATH is |
# typical as you use for compilation/istallation. I use |
# /bin /sbin /usr/bin /usr/sbin /usr/local/bin, but it may |
# differ on your system. |
# |
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:$PATH |
echo 'If some fields are empty or look unusual you may have an old version.' |
echo 'Compare to the current minimal requirements in Documentation/Changes.' |
echo ' ' |
|
uname -a |
echo ' ' |
|
gcc --version 2>&1| head -n 1 | grep -v gcc | awk \ |
'NR==1{print "Gnu C ", $1}' |
|
gcc --version 2>&1| grep gcc | awk \ |
'NR==1{print "Gnu C ", $3}' |
|
make --version 2>&1 | awk -F, '{print $1}' | awk \ |
'/GNU Make/{print "Gnu make ",$NF}' |
|
ld -v 2>&1 | awk -F\) '{print $1}' | awk \ |
'/BFD/{print "binutils ",$NF}' |
|
fdformat --version | awk -F\- '{print "util-linux ", $NF}' |
|
mount --version | awk -F\- '{print "mount ", $NF}' |
|
insmod -V 2>&1 | awk 'NR==1 {print "modutils ",$NF}' |
|
tune2fs 2>&1 | grep "^tune2fs" | sed 's/,//' | awk \ |
'NR==1 {print "e2fsprogs ", $2}' |
|
fsck.jfs -V 2>&1 | grep version | sed 's/,//' | awk \ |
'NR==1 {print "jfsutils ", $3}' |
|
reiserfsck -V 2>&1 | grep reiserfsprogs | awk \ |
'NR==1{print "reiserfsprogs ", $NF}' |
|
xfs_db -V 2>&1 | grep version | awk \ |
'NR==1{print "xfsprogs ", $3}' |
|
cardmgr -V 2>&1| grep version | awk \ |
'NR==1{print "pcmcia-cs ", $3}' |
|
quota -V 2>&1 | grep version | awk \ |
'NR==1{print "quota-tools ", $NF}' |
|
pppd --version 2>&1| grep version | awk \ |
'NR==1{print "PPP ", $3}' |
|
isdnctrl 2>&1 | grep version | awk \ |
'NR==1{print "isdn4k-utils ", $NF}' |
|
ls -l `ldd /bin/sh | awk '/libc/{print $3}'` | sed \ |
-e 's/\.so$//' | awk -F'[.-]' '{print "Linux C Library " \ |
$(NF-2)"."$(NF-1)"."$NF}' |
|
ldd -v > /dev/null 2>&1 && ldd -v || ldd --version |head -1 | awk \ |
'NR==1{print "Dynamic linker (ldd) ", $NF}' |
|
ls -l /usr/lib/lib{g,stdc}++.so 2>/dev/null | awk -F. \ |
'{print "Linux C++ Library " $4"."$5"."$6}' |
|
ps --version 2>&1 | awk 'NR==1{print "Procps ", $NF}' |
|
ifconfig --version 2>&1 | grep tools | awk \ |
'NR==1{print "Net-tools ", $NF}' |
|
# Kbd needs 'loadkeys -h', |
loadkeys -h 2>&1 | awk \ |
'(NR==1 && ($3 !~ /option/)) {print "Kbd ", $3}' |
|
# while console-tools needs 'loadkeys -V'. |
loadkeys -V 2>&1 | awk \ |
'(NR==1 && ($2 ~ /console-tools/)) {print "Console-tools ", $3}' |
|
expr --v 2>&1 | awk 'NR==1{print "Sh-utils ", $NF}' |
|
if [ -e /proc/modules ]; then |
X=`cat /proc/modules | sed -e "s/ .*$//"` |
echo "Modules Loaded "$X |
fi |
/mkversion
0,0 → 1,6
if [ ! -f .version ] |
then |
echo 1 |
else |
expr 0`cat .version` + 1 |
fi |
/Makefile
0,0 → 1,45
HEADER=header.tk |
TAIL=tail.tk |
|
# Previous versions always remade kconfig.tk because they always depended |
# on soundscript. This runs fairly fast, and I can't find all the |
# Config.in files to depend on anyways. So I'll force it to remake. |
|
kconfig.tk: dummy |
|
kconfig.tk: ${TOPDIR}/Makefile ${TOPDIR}/arch/${ARCH}/config.in \ |
tkparse ${HEADER} ${TAIL} |
@if [ -f /usr/local/bin/wish ]; then \ |
echo '#!'"/usr/local/bin/wish -f" > kconfig.tk; \ |
else \ |
echo '#!'"/usr/bin/wish -f" > kconfig.tk; \ |
fi |
cat ${HEADER} >> ./kconfig.tk |
./tkparse < ../arch/${ARCH}/config.in >> kconfig.tk |
echo "set defaults \"arch/${ARCH}/defconfig\"" >> kconfig.tk |
echo "set ARCH \"${ARCH}\"" >> kconfig.tk |
cat ${TAIL} >> kconfig.tk |
chmod 755 kconfig.tk |
|
tkparse: tkparse.o tkcond.o tkgen.o |
${HOSTCC} -o tkparse tkparse.o tkcond.o tkgen.o |
|
tkparse.o: tkparse.c tkparse.h |
|
tkcond.o: tkcond.c tkparse.h |
|
tkgen.o: tkgen.c tkparse.h |
|
tkparse.o tkcond.o tkgen.o: |
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $(@:.o=.c) |
|
docproc.o: docproc.c |
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $(@:.o=.c) |
|
docproc: docproc.o |
${HOSTCC} -o docproc docproc.o |
|
clean: |
rm -f *~ kconfig.tk *.o tkparse mkdep split-include docproc |
|
include $(TOPDIR)/Rules.make |
/checkconfig.pl
0,0 → 1,65
#! /usr/bin/perl |
# |
# checkconfig: find uses of CONFIG_* names without matching definitions. |
# Copyright abandoned, 1998, Michael Elizabeth Chastain <mailto:mec@shout.net>. |
|
use integer; |
|
$| = 1; |
|
foreach $file (@ARGV) |
{ |
# Open this file. |
open(FILE, $file) || die "Can't open $file: $!\n"; |
|
# Initialize variables. |
my $fInComment = 0; |
my $fInString = 0; |
my $fUseConfig = 0; |
my $iLinuxConfig = 0; |
my %configList = (); |
|
LINE: while ( <FILE> ) |
{ |
# Strip comments. |
$fInComment && (s+^.*?\*/+ +o ? ($fInComment = 0) : next); |
m+/\*+o && (s+/\*.*?\*/+ +go, (s+/\*.*$+ +o && ($fInComment = 1))); |
|
# Pick up definitions. |
if ( m/^\s*#/o ) |
{ |
$iLinuxConfig = $. if m/^\s*#\s*include\s*"linux\/config\.h"/o; |
$configList{uc $1} = 1 if m/^\s*#\s*include\s*"config\/(\S*)\.h"/o; |
} |
|
# Strip strings. |
$fInString && (s+^.*?"+ +o ? ($fInString = 0) : next); |
m+"+o && (s+".*?"+ +go, (s+".*$+ +o && ($fInString = 1))); |
|
# Pick up definitions. |
if ( m/^\s*#/o ) |
{ |
$iLinuxConfig = $. if m/^\s*#\s*include\s*<linux\/config\.h>/o; |
$configList{uc $1} = 1 if m/^\s*#\s*include\s*<config\/(\S*)\.h>/o; |
$configList{$1} = 1 if m/^\s*#\s*define\s+CONFIG_(\w*)/o; |
$configList{$1} = 1 if m/^\s*#\s*undef\s+CONFIG_(\w*)/o; |
} |
|
# Look for usages. |
next unless m/CONFIG_/o; |
WORD: while ( m/\bCONFIG_(\w+)/og ) |
{ |
$fUseConfig = 1; |
last LINE if $iLinuxConfig; |
next WORD if exists $configList{$1}; |
print "$file: $.: need CONFIG_$1.\n"; |
$configList{$1} = 0; |
} |
} |
|
# Report superfluous includes. |
if ( $iLinuxConfig && ! $fUseConfig ) |
{ print "$file: $iLinuxConfig: linux/config.h not needed.\n"; } |
|
close(FILE); |
} |
/checkincludes.pl
0,0 → 1,24
#!/usr/bin/perl |
# |
# checkincludes: Find files included more than once in (other) files. |
# Copyright abandoned, 2000, Niels Kristian Bech Jensen <nkbj@image.dk>. |
|
foreach $file (@ARGV) { |
open(FILE, $file) or die "Cannot open $file: $!.\n"; |
|
my %includedfiles = (); |
|
while (<FILE>) { |
if (m/^\s*#\s*include\s*[<"](\S*)[>"]/o) { |
++$includedfiles{$1}; |
} |
} |
|
foreach $filename (keys %includedfiles) { |
if ($includedfiles{$filename} > 1) { |
print "$file: $filename is included more than once.\n"; |
} |
} |
|
close(FILE); |
} |
/Configure
0,0 → 1,575
#! /bin/sh |
# |
# This script is used to configure the Linux kernel. |
# |
# It was inspired by the challenge in the original Configure script |
# to ``do something better'', combined with the actual need to ``do |
# something better'' because the old configure script wasn't flexible |
# enough. |
# |
# Raymond Chen was the original author of Configure. |
# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. |
# |
# 050793 - use IFS='@' to get around a bug in a pre-version of bash-1.13 |
# with an empty IFS. |
# |
# 030995 (storner@osiris.ping.dk) - added support for tri-state answers, |
# for selecting modules to compile. |
# |
# 180995 Bernhard Kaindl (bkaindl@ping.at) - added dummy functions for |
# use with a config.in modified for make menuconfig. |
# |
# 301195 (boldt@math.ucsb.edu) - added help text support |
# |
# 281295 Paul Gortmaker - make tri_state functions collapse to boolean |
# if module support is not enabled. |
# |
# 010296 Aaron Ucko (ucko@vax1.rockhurst.edu) - fix int and hex to accept |
# arbitrary ranges |
# |
# 150296 Dick Streefland (dicks@tasking.nl) - report new configuration |
# items and ask for a value even when doing a "make oldconfig" |
# |
# 200396 Tom Dyas (tdyas@eden.rutgers.edu) - when the module option is |
# chosen for an item, define the macro <option_name>_MODULE |
# |
# 090397 Axel Boldt (boldt@math.ucsb.edu) - avoid ? and + in regular |
# expressions for GNU expr since version 1.15 and up use \? and \+. |
# |
# 300397 Phil Blundell (pjb27@cam.ac.uk) - added support for min/max |
# arguments to "int", allow dep_tristate to take a list of dependencies |
# rather than just one. |
# |
# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help |
# texts. |
# |
# 102598 Michael Chastain (mec@shout.net) - put temporary files in |
# current directory, not in /tmp. |
# |
# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
# - Improve the exit message (Jeff Ronne). |
|
# |
# Make sure we're really running bash. |
# |
# I would really have preferred to write this script in a language with |
# better string handling, but alas, bash is the only scripting language |
# that I can be reasonable sure everybody has on their linux machine. |
# |
[ -z "$BASH" ] && { echo "Configure requires bash" 1>&2; exit 1; } |
|
# Disable filename globbing once and for all. |
# Enable function cacheing. |
set -f -h |
|
# |
# Dummy functions for use with a config.in modified for menuconf |
# |
function mainmenu_option () { |
: |
} |
function mainmenu_name () { |
: |
} |
function endmenu () { |
: |
} |
|
# |
# help prints the corresponding help text from Configure.help to stdout |
# |
# help variable |
# |
function help () { |
if [ -f Documentation/Configure.help ] |
then |
#first escape regexp special characters in the argument: |
var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g') |
#now pick out the right help text: |
text=$(sed -n "/^$var[ ]*\$/,\${ |
/^$var[ ]*\$/c\\ |
${var}:\\ |
|
/^#/b |
/^[^ ]/q |
/<file:\\([^>]*\\)>/s//\\1/g |
p |
}" Documentation/Configure.help) |
if [ -z "$text" ] |
then |
echo; echo " Sorry, no help available for this option yet.";echo |
else |
(echo; echo "$text") | ${PAGER:-more} |
fi |
else |
echo; |
echo " Can't access the file Documentation/Configure.help which" |
echo " should contain the help texts." |
echo |
fi |
} |
|
|
# |
# readln reads a line into $ans. |
# |
# readln prompt default oldval |
# |
function readln () { |
if [ "$DEFAULT" = "-d" -a -n "$3" ]; then |
echo "$1" |
ans=$2 |
else |
echo -n "$1" |
[ -z "$3" ] && echo -n "(NEW) " |
IFS='@' read ans || exit 1 |
[ -z "$ans" ] && ans=$2 |
fi |
} |
|
# |
# comment does some pretty-printing |
# |
# comment 'xxx' |
# |
function comment () { |
echo "*"; echo "* $1" ; echo "*" |
(echo "" ; echo "#"; echo "# $1" ; echo "#") >>$CONFIG |
(echo "" ; echo "/*"; echo " * $1" ; echo " */") >>$CONFIG_H |
} |
|
# |
# define_bool sets the value of a boolean argument |
# |
# define_bool define value |
# |
function define_bool () { |
define_tristate $1 $2 |
} |
|
function define_tristate () { |
case "$2" in |
"y") |
echo "$1=y" >>$CONFIG |
echo "#define $1 1" >>$CONFIG_H |
;; |
|
"m") |
echo "$1=m" >>$CONFIG |
echo "#undef $1" >>$CONFIG_H |
echo "#define $1_MODULE 1" >>$CONFIG_H |
;; |
|
"n") |
echo "# $1 is not set" >>$CONFIG |
echo "#undef $1" >>$CONFIG_H |
;; |
esac |
eval "$1=$2" |
} |
|
# |
# bool processes a boolean argument |
# |
# bool question define |
# |
function bool () { |
old=$(eval echo "\${$2}") |
def=${old:-'n'} |
case "$def" in |
"y" | "m") defprompt="Y/n/?" |
def="y" |
;; |
"n") defprompt="N/y/?" |
;; |
esac |
while :; do |
readln "$1 ($2) [$defprompt] " "$def" "$old" |
case "$ans" in |
[yY] | [yY]es ) define_bool "$2" "y" |
break;; |
[nN] | [nN]o ) define_bool "$2" "n" |
break;; |
* ) help "$2" |
;; |
esac |
done |
} |
|
# |
# tristate processes a tristate argument |
# |
# tristate question define |
# |
function tristate () { |
if [ "$CONFIG_MODULES" != "y" ]; then |
bool "$1" "$2" |
else |
old=$(eval echo "\${$2}") |
def=${old:-'n'} |
case "$def" in |
"y") defprompt="Y/m/n/?" |
;; |
"m") defprompt="M/n/y/?" |
;; |
"n") defprompt="N/y/m/?" |
;; |
esac |
while :; do |
readln "$1 ($2) [$defprompt] " "$def" "$old" |
case "$ans" in |
[yY] | [yY]es ) define_tristate "$2" "y" |
break ;; |
[nN] | [nN]o ) define_tristate "$2" "n" |
break ;; |
[mM] ) define_tristate "$2" "m" |
break ;; |
* ) help "$2" |
;; |
esac |
done |
fi |
} |
|
# |
# dep_tristate processes a tristate argument that depends upon |
# another option or options. If any of the options we depend upon is a |
# module, then the only allowable options are M or N. If all are Y, then |
# this is a normal tristate. This is used in cases where modules |
# are nested, and one module requires the presence of something |
# else in the kernel. |
# |
# dep_tristate question define default ... |
# |
function dep_tristate () { |
old=$(eval echo "\${$2}") |
def=${old:-'n'} |
ques=$1 |
var=$2 |
need_module=0 |
shift 2 |
while [ $# -gt 0 ]; do |
case "$1" in |
n) |
define_tristate "$var" "n" |
return |
;; |
m) |
need_module=1 |
;; |
esac |
shift |
done |
|
if [ $need_module = 1 ]; then |
if [ "$CONFIG_MODULES" = "y" ]; then |
case "$def" in |
"y" | "m") defprompt="M/n/?" |
def="m" |
;; |
"n") defprompt="N/m/?" |
;; |
esac |
while :; do |
readln "$ques ($var) [$defprompt] " "$def" "$old" |
case "$ans" in |
[nN] | [nN]o ) define_tristate "$var" "n" |
break ;; |
[mM] ) define_tristate "$var" "m" |
break ;; |
[yY] | [yY]es ) echo |
echo " This answer is not allowed, because it is not consistent with" |
echo " your other choices." |
echo " This driver depends on another one which you chose to compile" |
echo " as a module. This means that you can either compile this one" |
echo " as a module as well (with M) or leave it out altogether (N)." |
echo |
;; |
* ) help "$var" |
;; |
esac |
done |
fi |
else |
tristate "$ques" "$var" |
fi |
} |
|
function dep_bool () { |
ques=$1 |
var=$2 |
shift 2 |
while [ $# -gt 0 ]; do |
case "$1" in |
m | n) |
define_bool "$var" "n" |
return |
;; |
esac |
shift |
done |
|
bool "$ques" "$var" |
} |
|
function dep_mbool () { |
ques=$1 |
var=$2 |
shift 2 |
while [ $# -gt 0 ]; do |
case "$1" in |
n) |
define_bool "$var" "n" |
return |
;; |
esac |
shift |
done |
|
bool "$ques" "$var" |
} |
|
# |
# define_int sets the value of a integer argument |
# |
# define_int define value |
# |
function define_int () { |
echo "$1=$2" >>$CONFIG |
echo "#define $1 ($2)" >>$CONFIG_H |
eval "$1=$2" |
} |
|
# |
# int processes an integer argument with optional limits |
# |
# int question define default |
# |
function int () { |
old=$(eval echo "\${$2}") |
def=${old:-$3} |
while :; do |
readln "$1 ($2) [$def] " "$def" "$old" |
if expr "$ans" : '[0-9]*$' > /dev/null; then |
define_int "$2" "$ans" |
break |
else |
help "$2" |
fi |
done |
} |
|
# |
# define_hex sets the value of a hexadecimal argument |
# |
# define_hex define value |
# |
function define_hex () { |
echo "$1=$2" >>$CONFIG |
echo "#define $1 0x${2#*[x,X]}" >>$CONFIG_H |
eval "$1=$2" |
} |
|
# |
# hex processes an hexadecimal argument |
# |
# hex question define default |
# |
function hex () { |
old=$(eval echo "\${$2}") |
def=${old:-$3} |
def=${def#*[x,X]} |
while :; do |
readln "$1 ($2) [$def] " "$def" "$old" |
ans=${ans#*[x,X]} |
if expr "$ans" : '[0-9a-fA-F][0-9a-fA-F]*$' > /dev/null; then |
define_hex "$2" "$ans" |
break |
else |
help "$2" |
fi |
done |
} |
|
# |
# define_string sets the value of a string argument |
# |
# define_string define value |
# |
function define_string () { |
echo "$1=\"$2\"" >>$CONFIG |
echo "#define $1 \"$2\"" >>$CONFIG_H |
eval "$1=\"$2\"" |
} |
|
# |
# string processes a string argument |
# |
# string question define default |
# |
function string () { |
old=$(eval echo "\${$2}") |
def=${old:-$3} |
while :; do |
if [ "$old" = "?" ]; then |
readln "$1 ($2) [$def] " "$def" "" |
else |
readln "$1 ($2) [$def] " "$def" "$old" |
fi |
if [ "$ans" = "?" ]; then |
help "$2" |
else |
break |
fi |
done |
define_string "$2" "$ans" |
} |
# |
# choice processes a choice list (1-out-of-n) |
# |
# choice question choice-list default |
# |
# The choice list has a syntax of: |
# NAME WHITESPACE VALUE { WHITESPACE NAME WHITESPACE VALUE } |
# The user may enter any unique prefix of one of the NAMEs and |
# choice will define VALUE as if it were a boolean option. |
# VALUE must be in all uppercase. Normally, VALUE is of the |
# form CONFIG_<something>. Thus, if the user selects <something>, |
# the CPP symbol CONFIG_<something> will be defined and the |
# shell variable CONFIG_<something> will be set to "y". |
# |
function choice () { |
question="$1" |
choices="$2" |
old= |
def=$3 |
|
# determine default answer: |
names="" |
set -- $choices |
firstvar=$2 |
while [ -n "$2" ]; do |
if [ -n "$names" ]; then |
names="$names, $1" |
else |
names="$1" |
fi |
if [ "$(eval echo \"\${$2}\")" = "y" ]; then |
old=$1 |
def=$1 |
fi |
shift; shift |
done |
|
val="" |
while [ -z "$val" ]; do |
ambg=n |
readln "$question ($names) [$def] " "$def" "$old" |
ans=$(echo $ans | tr a-z A-Z) |
set -- $choices |
while [ -n "$1" ]; do |
name=$(echo $1 | tr a-z A-Z) |
case "$name" in |
"$ans"* | */"$ans"* ) |
case "$name" in |
"$ans" | */"$ans"/* | \ |
"$ans"/* | */"$ans" ) |
val="$2" |
break # exact match |
;; |
esac |
if [ -n "$val" ]; then |
echo;echo \ |
" Sorry, \"$ans\" is ambiguous; please enter a longer string." |
echo |
val="" |
ambg=y |
break |
else |
val="$2" |
fi;; |
esac |
shift; shift |
done |
if [ "$val" = "" -a "$ambg" = "n" ]; then |
help "$firstvar" |
fi |
done |
set -- $choices |
while [ -n "$2" ]; do |
if [ "$2" = "$val" ]; then |
echo " defined $val" |
define_bool "$2" "y" |
else |
define_bool "$2" "n" |
fi |
shift; shift |
done |
} |
|
CONFIG=.tmpconfig |
CONFIG_H=.tmpconfig.h |
trap "rm -f $CONFIG $CONFIG_H ; exit 1" 1 2 |
|
# |
# Make sure we start out with a clean slate. |
# |
echo "#" > $CONFIG |
echo "# Automatically generated make config: don't edit" >> $CONFIG |
echo "#" >> $CONFIG |
|
echo "/*" > $CONFIG_H |
echo " * Automatically generated C config: don't edit" >> $CONFIG_H |
echo " */" >> $CONFIG_H |
echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H |
|
DEFAULT="" |
if [ "$1" = "-d" ] ; then |
DEFAULT="-d" |
shift |
fi |
|
CONFIG_IN=./config.in |
if [ "$1" != "" ] ; then |
CONFIG_IN=$1 |
fi |
|
DEFAULTS=arch/$ARCH/defconfig |
if [ -f .config ]; then |
DEFAULTS=.config |
fi |
|
if [ -f $DEFAULTS ]; then |
echo "#" |
echo "# Using defaults found in" $DEFAULTS |
echo "#" |
. $DEFAULTS |
sed -e 's/# \(CONFIG_[^ ]*\) is not.*/\1=n/' <$DEFAULTS >.config-is-not.$$ |
. .config-is-not.$$ |
rm .config-is-not.$$ |
else |
echo "#" |
echo "# No defaults found" |
echo "#" |
fi |
|
. $CONFIG_IN |
|
rm -f .config.old |
if [ -f .config ]; then |
mv .config .config.old |
fi |
mv .tmpconfig .config |
mv .tmpconfig.h include/linux/autoconf.h |
|
echo |
echo "*** End of Linux kernel configuration." |
echo "*** Check the top-level Makefile for additional configuration." |
if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then |
echo "*** Next, you must run 'make dep'." |
else |
echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'." |
fi |
echo |
|
exit 0 |
/mkdep.c
0,0 → 1,628
/* |
* Originally by Linus Torvalds. |
* Smart CONFIG_* processing by Werner Almesberger, Michael Chastain. |
* |
* Usage: mkdep cflags -- file ... |
* |
* Read source files and output makefile dependency lines for them. |
* I make simple dependency lines for #include <*.h> and #include "*.h". |
* I also find instances of CONFIG_FOO and generate dependencies |
* like include/config/foo.h. |
* |
* 1 August 1999, Michael Elizabeth Chastain, <mec@shout.net> |
* - Keith Owens reported a bug in smart config processing. There used |
* to be an optimization for "#define CONFIG_FOO ... #ifdef CONFIG_FOO", |
* so that the file would not depend on CONFIG_FOO because the file defines |
* this symbol itself. But this optimization is bogus! Consider this code: |
* "#if 0 \n #define CONFIG_FOO \n #endif ... #ifdef CONFIG_FOO". Here |
* the definition is inactivated, but I still used it. It turns out this |
* actually happens a few times in the kernel source. The simple way to |
* fix this problem is to remove this particular optimization. |
* |
* 2.3.99-pre1, Andrew Morton <andrewm@uow.edu.au> |
* - Changed so that 'filename.o' depends upon 'filename.[cS]'. This is so that |
* missing source files are noticed, rather than silently ignored. |
* |
* 2.4.2-pre3, Keith Owens <kaos@ocs.com.au> |
* - Accept cflags followed by '--' followed by filenames. mkdep extracts -I |
* options from cflags and looks in the specified directories as well as the |
* defaults. Only -I is supported, no attempt is made to handle -idirafter, |
* -isystem, -I- etc. |
*/ |
|
#include <ctype.h> |
#include <fcntl.h> |
#include <limits.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
|
#include <sys/fcntl.h> |
#include <sys/mman.h> |
#include <sys/stat.h> |
#include <sys/types.h> |
|
|
|
char __depname[512] = "\n\t@touch "; |
#define depname (__depname+9) |
int hasdep; |
|
struct path_struct { |
int len; |
char *buffer; |
}; |
struct path_struct *path_array; |
int paths; |
|
|
/* Current input file */ |
static const char *g_filename; |
|
/* |
* This records all the configuration options seen. |
* In perl this would be a hash, but here it's a long string |
* of values separated by newlines. This is simple and |
* extremely fast. |
*/ |
char * str_config = NULL; |
int size_config = 0; |
int len_config = 0; |
|
static void |
do_depname(void) |
{ |
if (!hasdep) { |
hasdep = 1; |
printf("%s:", depname); |
if (g_filename) |
printf(" %s", g_filename); |
} |
} |
|
/* |
* Grow the configuration string to a desired length. |
* Usually the first growth is plenty. |
*/ |
void grow_config(int len) |
{ |
while (len_config + len > size_config) { |
if (size_config == 0) |
size_config = 2048; |
str_config = realloc(str_config, size_config *= 2); |
if (str_config == NULL) |
{ perror("malloc config"); exit(1); } |
} |
} |
|
|
|
/* |
* Lookup a value in the configuration string. |
*/ |
int is_defined_config(const char * name, int len) |
{ |
const char * pconfig; |
const char * plast = str_config + len_config - len; |
for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { |
if (pconfig[ -1] == '\n' |
&& pconfig[len] == '\n' |
&& !memcmp(pconfig, name, len)) |
return 1; |
} |
return 0; |
} |
|
|
|
/* |
* Add a new value to the configuration string. |
*/ |
void define_config(const char * name, int len) |
{ |
grow_config(len + 1); |
|
memcpy(str_config+len_config, name, len); |
len_config += len; |
str_config[len_config++] = '\n'; |
} |
|
|
|
/* |
* Clear the set of configuration strings. |
*/ |
void clear_config(void) |
{ |
len_config = 0; |
define_config("", 0); |
} |
|
|
|
/* |
* This records all the precious .h filenames. No need for a hash, |
* it's a long string of values enclosed in tab and newline. |
*/ |
char * str_precious = NULL; |
int size_precious = 0; |
int len_precious = 0; |
|
|
|
/* |
* Grow the precious string to a desired length. |
* Usually the first growth is plenty. |
*/ |
void grow_precious(int len) |
{ |
while (len_precious + len > size_precious) { |
if (size_precious == 0) |
size_precious = 2048; |
str_precious = realloc(str_precious, size_precious *= 2); |
if (str_precious == NULL) |
{ perror("malloc"); exit(1); } |
} |
} |
|
|
|
/* |
* Add a new value to the precious string. |
*/ |
void define_precious(const char * filename) |
{ |
int len = strlen(filename); |
grow_precious(len + 4); |
*(str_precious+len_precious++) = '\t'; |
memcpy(str_precious+len_precious, filename, len); |
len_precious += len; |
memcpy(str_precious+len_precious, " \\\n", 3); |
len_precious += 3; |
} |
|
|
|
/* |
* Handle an #include line. |
*/ |
void handle_include(int start, const char * name, int len) |
{ |
struct path_struct *path; |
int i; |
|
if (len == 14 && !memcmp(name, "linux/config.h", len)) |
return; |
|
if (len >= 7 && !memcmp(name, "config/", 7)) |
define_config(name+7, len-7-2); |
|
for (i = start, path = path_array+start; i < paths; ++i, ++path) { |
memcpy(path->buffer+path->len, name, len); |
path->buffer[path->len+len] = '\0'; |
if (access(path->buffer, F_OK) == 0) { |
do_depname(); |
printf(" \\\n %s", path->buffer); |
return; |
} |
} |
|
} |
|
|
|
/* |
* Add a path to the list of include paths. |
*/ |
void add_path(const char * name) |
{ |
struct path_struct *path; |
char resolved_path[PATH_MAX+1]; |
const char *name2; |
|
if (strcmp(name, ".")) { |
name2 = realpath(name, resolved_path); |
if (!name2) { |
fprintf(stderr, "realpath(%s) failed, %m\n", name); |
exit(1); |
} |
} |
else { |
name2 = ""; |
} |
|
path_array = realloc(path_array, (++paths)*sizeof(*path_array)); |
if (!path_array) { |
fprintf(stderr, "cannot expand path_arry\n"); |
exit(1); |
} |
|
path = path_array+paths-1; |
path->len = strlen(name2); |
path->buffer = malloc(path->len+1+256+1); |
if (!path->buffer) { |
fprintf(stderr, "cannot allocate path buffer\n"); |
exit(1); |
} |
strcpy(path->buffer, name2); |
if (path->len && *(path->buffer+path->len-1) != '/') { |
*(path->buffer+path->len) = '/'; |
*(path->buffer+(++(path->len))) = '\0'; |
} |
} |
|
|
|
/* |
* Record the use of a CONFIG_* word. |
*/ |
void use_config(const char * name, int len) |
{ |
char *pc; |
int i; |
|
pc = path_array[paths-1].buffer + path_array[paths-1].len; |
memcpy(pc, "config/", 7); |
pc += 7; |
|
for (i = 0; i < len; i++) { |
char c = name[i]; |
if (isupper((int)c)) c = tolower((int)c); |
if (c == '_') c = '/'; |
pc[i] = c; |
} |
pc[len] = '\0'; |
|
if (is_defined_config(pc, len)) |
return; |
|
define_config(pc, len); |
|
do_depname(); |
printf(" \\\n $(wildcard %s.h)", path_array[paths-1].buffer); |
} |
|
|
|
/* |
* Macros for stunningly fast map-based character access. |
* __buf is a register which holds the current word of the input. |
* Thus, there is one memory access per sizeof(unsigned long) characters. |
*/ |
|
#if defined(__alpha__) || defined(__i386__) || defined(__ia64__) || defined(__x86_64__) || defined(__MIPSEL__) \ |
|| defined(__arm__) |
#define LE_MACHINE |
#endif |
|
#ifdef LE_MACHINE |
#define next_byte(x) (x >>= 8) |
#define current ((unsigned char) __buf) |
#else |
#define next_byte(x) (x <<= 8) |
#define current (__buf >> 8*(sizeof(unsigned long)-1)) |
#endif |
|
#define GETNEXT { \ |
next_byte(__buf); \ |
if ((unsigned long) next % sizeof(unsigned long) == 0) { \ |
if (next >= end) \ |
break; \ |
__buf = * (unsigned long *) next; \ |
} \ |
next++; \ |
} |
|
/* |
* State machine macros. |
*/ |
#define CASE(c,label) if (current == c) goto label |
#define NOTCASE(c,label) if (current != c) goto label |
|
/* |
* Yet another state machine speedup. |
*/ |
#define MAX2(a,b) ((a)>(b)?(a):(b)) |
#define MIN2(a,b) ((a)<(b)?(a):(b)) |
#define MAX5(a,b,c,d,e) (MAX2(a,MAX2(b,MAX2(c,MAX2(d,e))))) |
#define MIN5(a,b,c,d,e) (MIN2(a,MIN2(b,MIN2(c,MIN2(d,e))))) |
|
|
|
/* |
* The state machine looks for (approximately) these Perl regular expressions: |
* |
* m|\/\*.*?\*\/| |
* m|\/\/.*| |
* m|'.*?'| |
* m|".*?"| |
* m|#\s*include\s*"(.*?)"| |
* m|#\s*include\s*<(.*?>"| |
* m|#\s*(?define|undef)\s*CONFIG_(\w*)| |
* m|(?!\w)CONFIG_| |
* |
* About 98% of the CPU time is spent here, and most of that is in |
* the 'start' paragraph. Because the current characters are |
* in a register, the start loop usually eats 4 or 8 characters |
* per memory read. The MAX5 and MIN5 tests dispose of most |
* input characters with 1 or 2 comparisons. |
*/ |
void state_machine(const char * map, const char * end) |
{ |
const char * next = map; |
const char * map_dot; |
unsigned long __buf = 0; |
|
for (;;) { |
start: |
GETNEXT |
__start: |
if (current > MAX5('/','\'','"','#','C')) goto start; |
if (current < MIN5('/','\'','"','#','C')) goto start; |
CASE('/', slash); |
CASE('\'', squote); |
CASE('"', dquote); |
CASE('#', pound); |
CASE('C', cee); |
goto start; |
|
/* // */ |
slash_slash: |
GETNEXT |
CASE('\n', start); |
NOTCASE('\\', slash_slash); |
GETNEXT |
goto slash_slash; |
|
/* / */ |
slash: |
GETNEXT |
CASE('/', slash_slash); |
NOTCASE('*', __start); |
slash_star_dot_star: |
GETNEXT |
__slash_star_dot_star: |
NOTCASE('*', slash_star_dot_star); |
GETNEXT |
NOTCASE('/', __slash_star_dot_star); |
goto start; |
|
/* '.*?' */ |
squote: |
GETNEXT |
CASE('\'', start); |
NOTCASE('\\', squote); |
GETNEXT |
goto squote; |
|
/* ".*?" */ |
dquote: |
GETNEXT |
CASE('"', start); |
NOTCASE('\\', dquote); |
GETNEXT |
goto dquote; |
|
/* #\s* */ |
pound: |
GETNEXT |
CASE(' ', pound); |
CASE('\t', pound); |
CASE('i', pound_i); |
CASE('d', pound_d); |
CASE('u', pound_u); |
goto __start; |
|
/* #\s*i */ |
pound_i: |
GETNEXT NOTCASE('n', __start); |
GETNEXT NOTCASE('c', __start); |
GETNEXT NOTCASE('l', __start); |
GETNEXT NOTCASE('u', __start); |
GETNEXT NOTCASE('d', __start); |
GETNEXT NOTCASE('e', __start); |
goto pound_include; |
|
/* #\s*include\s* */ |
pound_include: |
GETNEXT |
CASE(' ', pound_include); |
CASE('\t', pound_include); |
map_dot = next; |
CASE('"', pound_include_dquote); |
CASE('<', pound_include_langle); |
goto __start; |
|
/* #\s*include\s*"(.*)" */ |
pound_include_dquote: |
GETNEXT |
CASE('\n', start); |
NOTCASE('"', pound_include_dquote); |
handle_include(0, map_dot, next - map_dot - 1); |
goto start; |
|
/* #\s*include\s*<(.*)> */ |
pound_include_langle: |
GETNEXT |
CASE('\n', start); |
NOTCASE('>', pound_include_langle); |
handle_include(1, map_dot, next - map_dot - 1); |
goto start; |
|
/* #\s*d */ |
pound_d: |
GETNEXT NOTCASE('e', __start); |
GETNEXT NOTCASE('f', __start); |
GETNEXT NOTCASE('i', __start); |
GETNEXT NOTCASE('n', __start); |
GETNEXT NOTCASE('e', __start); |
goto pound_define_undef; |
|
/* #\s*u */ |
pound_u: |
GETNEXT NOTCASE('n', __start); |
GETNEXT NOTCASE('d', __start); |
GETNEXT NOTCASE('e', __start); |
GETNEXT NOTCASE('f', __start); |
goto pound_define_undef; |
|
/* |
* #\s*(define|undef)\s*CONFIG_(\w*) |
* |
* this does not define the word, because it could be inside another |
* conditional (#if 0). But I do parse the word so that this instance |
* does not count as a use. -- mec |
*/ |
pound_define_undef: |
GETNEXT |
CASE(' ', pound_define_undef); |
CASE('\t', pound_define_undef); |
|
NOTCASE('C', __start); |
GETNEXT NOTCASE('O', __start); |
GETNEXT NOTCASE('N', __start); |
GETNEXT NOTCASE('F', __start); |
GETNEXT NOTCASE('I', __start); |
GETNEXT NOTCASE('G', __start); |
GETNEXT NOTCASE('_', __start); |
|
map_dot = next; |
pound_define_undef_CONFIG_word: |
GETNEXT |
if (isalnum(current) || current == '_') |
goto pound_define_undef_CONFIG_word; |
goto __start; |
|
/* \<CONFIG_(\w*) */ |
cee: |
if (next >= map+2 && (isalnum((int)next[-2]) || next[-2] == '_')) |
goto start; |
GETNEXT NOTCASE('O', __start); |
GETNEXT NOTCASE('N', __start); |
GETNEXT NOTCASE('F', __start); |
GETNEXT NOTCASE('I', __start); |
GETNEXT NOTCASE('G', __start); |
GETNEXT NOTCASE('_', __start); |
|
map_dot = next; |
cee_CONFIG_word: |
GETNEXT |
if (isalnum(current) || current == '_') |
goto cee_CONFIG_word; |
use_config(map_dot, next - map_dot - 1); |
goto __start; |
} |
} |
|
|
|
/* |
* Generate dependencies for one file. |
*/ |
void do_depend(const char * filename, const char * command) |
{ |
int mapsize; |
int pagesizem1 = getpagesize()-1; |
int fd; |
struct stat st; |
char * map; |
|
fd = open(filename, O_RDONLY); |
if (fd < 0) { |
perror(filename); |
return; |
} |
|
fstat(fd, &st); |
if (st.st_size == 0) { |
fprintf(stderr,"%s is empty\n",filename); |
close(fd); |
return; |
} |
|
mapsize = st.st_size; |
mapsize = (mapsize+pagesizem1) & ~pagesizem1; |
map = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, fd, 0); |
if ((long) map == -1) { |
perror("mkdep: mmap"); |
close(fd); |
return; |
} |
if ((unsigned long) map % sizeof(unsigned long) != 0) |
{ |
fprintf(stderr, "do_depend: map not aligned\n"); |
exit(1); |
} |
|
hasdep = 0; |
clear_config(); |
state_machine(map, map+st.st_size); |
if (hasdep) { |
puts(command); |
if (*command) |
define_precious(filename); |
} |
|
munmap(map, mapsize); |
close(fd); |
} |
|
|
|
/* |
* Generate dependencies for all files. |
*/ |
int main(int argc, char **argv) |
{ |
int len; |
const char *hpath; |
|
hpath = getenv("HPATH"); |
if (!hpath) { |
fputs("mkdep: HPATH not set in environment. " |
"Don't bypass the top level Makefile.\n", stderr); |
return 1; |
} |
|
add_path("."); /* for #include "..." */ |
|
while (++argv, --argc > 0) { |
if (strncmp(*argv, "-I", 2) == 0) { |
if (*((*argv)+2)) { |
add_path((*argv)+2); |
} |
else { |
++argv; |
--argc; |
add_path(*argv); |
} |
} |
else if (strcmp(*argv, "--") == 0) { |
break; |
} |
} |
|
add_path(hpath); /* must be last entry, for config files */ |
|
while (--argc > 0) { |
const char * filename = *++argv; |
const char * command = __depname; |
g_filename = 0; |
len = strlen(filename); |
memcpy(depname, filename, len+1); |
if (len > 2 && filename[len-2] == '.') { |
if (filename[len-1] == 'c' || filename[len-1] == 'S') { |
depname[len-1] = 'o'; |
g_filename = filename; |
command = ""; |
} |
} |
do_depend(filename, command); |
} |
if (len_precious) { |
*(str_precious+len_precious) = '\0'; |
printf(".PRECIOUS:%s\n", str_precious); |
} |
return 0; |
} |
/mkspec
0,0 → 1,77
#!/bin/sh |
# |
# Output a simple RPM spec file that uses no fancy features requring |
# RPM v4. This is intended to work with any RPM distro. |
# |
# The only gothic bit here is redefining install_post to avoid |
# stripping the symbols from files in the kernel which we want |
# |
# Patched for non-x86 by Opencon (L) 2002 <opencon@rio.skydome.net> |
# |
# That's the voodoo to see if it's a x86. |
ISX86=`arch | grep -ie i.86` |
if [ ! -z $ISX86 ]; then |
PC=1 |
else |
PC=0 |
fi |
# starting to output the spec |
if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then |
PROVIDES=kernel-drm |
fi |
|
PROVIDES="$PROVIDES kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
|
echo "Name: kernel" |
echo "Summary: The Linux Kernel" |
echo "Version: "$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION | sed -e "s/-//g" |
# we need to determine the NEXT version number so that uname and |
# rpm -q will agree |
echo "Release: `. scripts/mkversion`" |
echo "License: GPL" |
echo "Group: System Environment/Kernel" |
echo "Vendor: The Linux Community" |
echo "URL: http://www.kernel.org" |
echo -n "Source: kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL" |
echo "$EXTRAVERSION.tar.gz" | sed -e "s/-//g" |
echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" |
echo "Provides: $PROVIDES" |
echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" |
echo "" |
echo "%description" |
echo "The Linux Kernel, the operating system core itself" |
echo "" |
echo "%prep" |
echo "%setup -q" |
echo "" |
echo "%build" |
# This is the first 'disagreement' between x86 and other archs. |
if [ $PC = 1 ]; then |
echo "make oldconfig dep clean bzImage modules" |
else |
echo "make oldconfig dep clean vmlinux modules" |
fi |
# Back on track |
echo "" |
echo "%install" |
echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules' |
echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install' |
# And that's the second |
if [ $PC = 1 ]; then |
echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
else |
echo 'cp vmlinux $RPM_BUILD_ROOT'"/boot/vmlinux-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
fi |
# Back on track, again |
echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
echo "" |
echo "%clean" |
echo '#echo -rf $RPM_BUILD_ROOT' |
echo "" |
echo "%files" |
echo '%defattr (-, root, root)' |
echo "%dir /lib/modules" |
echo "/lib/modules/$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION" |
echo "/boot/*" |
echo "" |
/kernel-doc
0,0 → 1,1723
#!/usr/bin/perl -w |
|
use strict; |
|
## Copyright (c) 1998 Michael Zucchi, All Rights Reserved ## |
## Copyright (C) 2000, 1 Tim Waugh <twaugh@redhat.com> ## |
## Copyright (C) 2001 Simon Huggins ## |
## ## |
## #define enhancements by Armin Kuster <akuster@mvista.com> ## |
## Copyright (c) 2000 MontaVista Software, Inc. ## |
## ## |
## This software falls under the GNU General Public License. ## |
## Please read the COPYING file for more information ## |
|
# w.o. 03-11-2000: added the '-filelist' option. |
|
# 18/01/2001 - Cleanups |
# Functions prototyped as foo(void) same as foo() |
# Stop eval'ing where we don't need to. |
# -- huggie@earth.li |
|
# 27/06/2001 - Allowed whitespace after initial "/**" and |
# allowed comments before function declarations. |
# -- Christian Kreibich <ck@whoop.org> |
|
# Still to do: |
# - add perldoc documentation |
# - Look more closely at some of the scarier bits :) |
|
# 26/05/2001 - Support for separate source and object trees. |
# Return error code. |
# Keith Owens <kaos@ocs.com.au> |
|
# 23/09/2001 - Added support for typedefs, structs, enums and unions |
# Support for Context section; can be terminated using empty line |
# Small fixes (like spaces vs. \s in regex) |
# -- Tim Jansen <tim@tjansen.de> |
|
|
# |
# This will read a 'c' file and scan for embedded comments in the |
# style of gnome comments (+minor extensions - see below). |
# |
|
# Note: This only supports 'c'. |
|
# usage: |
# kerneldoc [ -docbook | -html | -text | -man ] |
# [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile |
# or |
# [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile |
# |
# Set output format using one of -docbook -html -text or -man. Default is man. |
# |
# -function funcname |
# If set, then only generate documentation for the given function(s). All |
# other functions are ignored. |
# |
# -nofunction funcname |
# If set, then only generate documentation for the other function(s). All |
# other functions are ignored. Cannot be used with -function together |
# (yes thats a bug - perl hackers can fix it 8)) |
# |
# c files - list of 'c' files to process |
# |
# All output goes to stdout, with errors to stderr. |
|
# |
# format of comments. |
# In the following table, (...)? signifies optional structure. |
# (...)* signifies 0 or more structure elements |
# /** |
# * function_name(:)? (- short description)? |
# (* @parameterx: (description of parameter x)?)* |
# (* a blank line)? |
# * (Description:)? (Description of function)? |
# * (section header: (section description)? )* |
# (*)?*/ |
# |
# So .. the trivial example would be: |
# |
# /** |
# * my_function |
# **/ |
# |
# If the Description: header tag is ommitted, then there must be a blank line |
# after the last parameter specification. |
# e.g. |
# /** |
# * my_function - does my stuff |
# * @my_arg: its mine damnit |
# * |
# * Does my stuff explained. |
# */ |
# |
# or, could also use: |
# /** |
# * my_function - does my stuff |
# * @my_arg: its mine damnit |
# * Description: Does my stuff explained. |
# */ |
# etc. |
# |
# Beside functions you can also write documentation for structs, unions, |
# enums and typedefs. Instead of the function name you must write the name |
# of the declaration; the struct/union/enum/typedef must always precede |
# the name. Nesting of declarations is not supported. |
# Use the argument mechanism to document members or constants. In |
# structs and unions you must declare one member per declaration |
# (comma-separated members are not allowed - the parser does not support |
# this). |
# e.g. |
# /** |
# * struct my_struct - short description |
# * @a: first member |
# * @b: second member |
# * |
# * Longer description |
# */ |
# struct my_struct { |
# int a; |
# int b; |
# }; |
# |
# All descriptions can be multiline, except the short function description. |
# |
# You can also add additional sections. When documenting kernel functions you |
# should document the "Context:" of the function, e.g. whether the functions |
# can be called form interrupts. Unlike other sections you can end it with an |
# empty line. |
# Example-sections should contain the string EXAMPLE so that they are marked |
# appropriately in DocBook. |
# |
# Example: |
# /** |
# * user_function - function that can only be called in user context |
# * @a: some argument |
# * Context: !in_interrupt() |
# * |
# * Some description |
# * Example: |
# * user_function(22); |
# */ |
# ... |
# |
# |
# All descriptive text is further processed, scanning for the following special |
# patterns, which are highlighted appropriately. |
# |
# 'funcname()' - function |
# '$ENVVAR' - environmental variable |
# '&struct_name' - name of a structure (up to two words including 'struct') |
# '@parameter' - name of a parameter |
# '%CONST' - name of a constant. |
|
my $errors = 0; |
|
# match expressions used to find embedded type information |
my $type_constant = '\%([-_\w]+)'; |
my $type_func = '(\w+)\(\)'; |
my $type_param = '\@(\w+)'; |
my $type_struct = '\&((struct\s*)?[_\w]+)'; |
my $type_env = '(\$\w+)'; |
|
# Output conversion substitutions. |
# One for each output format |
|
# these work fairly well |
my %highlights_html = ( $type_constant, "<i>\$1</i>", |
$type_func, "<b>\$1</b>", |
$type_struct, "<i>\$1</i>", |
$type_param, "<tt><b>\$1</b></tt>" ); |
my $blankline_html = "<p>"; |
|
# sgml, docbook format |
my %highlights_sgml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>", |
$type_constant, "<constant>\$1</constant>", |
$type_func, "<function>\$1</function>", |
$type_struct, "<structname>\$1</structname>", |
$type_env, "<envar>\$1</envar>", |
$type_param, "<parameter>\$1</parameter>" ); |
my $blankline_sgml = "</para><para>\n"; |
|
# gnome, docbook format |
my %highlights_gnome = ( $type_constant, "<replaceable class=\"option\">\$1</replaceable>", |
$type_func, "<function>\$1</function>", |
$type_struct, "<structname>\$1</structname>", |
$type_env, "<envar>\$1</envar>", |
$type_param, "<parameter>\$1</parameter>" ); |
my $blankline_gnome = "</para><para>\n"; |
|
# these are pretty rough |
my %highlights_man = ( $type_constant, "\$1", |
$type_func, "\\\\fB\$1\\\\fP", |
$type_struct, "\\\\fI\$1\\\\fP", |
$type_param, "\\\\fI\$1\\\\fP" ); |
my $blankline_man = ""; |
|
# text-mode |
my %highlights_text = ( $type_constant, "\$1", |
$type_func, "\$1", |
$type_struct, "\$1", |
$type_param, "\$1" ); |
my $blankline_text = ""; |
|
|
sub usage { |
print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man ]\n"; |
print " [ -function funcname [ -function funcname ...] ]\n"; |
print " [ -nofunction funcname [ -nofunction funcname ...] ]\n"; |
print " c source file(s) > outputfile\n"; |
exit 1; |
} |
|
# read arguments |
if ($#ARGV==-1) { |
usage(); |
} |
|
my $verbose = 0; |
my $output_mode = "man"; |
my %highlights = %highlights_man; |
my $blankline = $blankline_man; |
my $modulename = "Kernel API"; |
my $function_only = 0; |
my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', |
'July', 'August', 'September', 'October', |
'November', 'December')[(localtime)[4]] . |
" " . ((localtime)[5]+1900); |
|
# Essentially these are globals |
# They probably want to be tidied up made more localised or summat. |
# CAVEAT EMPTOR! Some of the others I localised may not want to be which |
# could cause "use of undefined value" or other bugs. |
my ($function, %function_table,%parametertypes,$declaration_purpose); |
my ($type,$declaration_name,$return_type); |
my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map); |
|
# Generated docbook code is inserted in a template at a point where |
# docbook v3.1 requires a non-zero sequence of RefEntry's; see: |
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html |
# We keep track of number of generated entries and generate a dummy |
# if needs be to ensure the expanded template can be postprocessed |
# into html. |
my $section_counter = 0; |
|
my $lineprefix=""; |
|
# states |
# 0 - normal code |
# 1 - looking for function name |
# 2 - scanning field start. |
# 3 - scanning prototype. |
# 4 - documentation block |
my $state; |
|
#declaration types: can be |
# 'function', 'struct', 'union', 'enum', 'typedef' |
my $decl_type; |
|
my $doc_special = "\@\%\$\&"; |
|
my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. |
my $doc_end = '\*/'; |
my $doc_com = '\s*\*\s*'; |
my $doc_decl = $doc_com.'(\w+)'; |
my $doc_sect = $doc_com.'(['.$doc_special.']?[\w ]+):(.*)'; |
my $doc_content = $doc_com.'(.*)'; |
my $doc_block = $doc_com.'DOC:\s*(.*)?'; |
|
my %constants; |
my %parameterdescs; |
my @parameterlist; |
my %sections; |
my @sectionlist; |
|
my $contents = ""; |
my $section_default = "Description"; # default section |
my $section_intro = "Introduction"; |
my $section = $section_default; |
my $section_context = "Context"; |
|
my $undescribed = "-- undescribed --"; |
|
reset_state(); |
|
while ($ARGV[0] =~ m/^-(.*)/) { |
my $cmd = shift @ARGV; |
if ($cmd eq "-html") { |
$output_mode = "html"; |
%highlights = %highlights_html; |
$blankline = $blankline_html; |
} elsif ($cmd eq "-man") { |
$output_mode = "man"; |
%highlights = %highlights_man; |
$blankline = $blankline_man; |
} elsif ($cmd eq "-text") { |
$output_mode = "text"; |
%highlights = %highlights_text; |
$blankline = $blankline_text; |
} elsif ($cmd eq "-docbook") { |
$output_mode = "sgml"; |
%highlights = %highlights_sgml; |
$blankline = $blankline_sgml; |
} elsif ($cmd eq "-gnome") { |
$output_mode = "gnome"; |
%highlights = %highlights_gnome; |
$blankline = $blankline_gnome; |
} elsif ($cmd eq "-module") { # not needed for sgml, inherits from calling document |
$modulename = shift @ARGV; |
} elsif ($cmd eq "-function") { # to only output specific functions |
$function_only = 1; |
$function = shift @ARGV; |
$function_table{$function} = 1; |
} elsif ($cmd eq "-nofunction") { # to only output specific functions |
$function_only = 2; |
$function = shift @ARGV; |
$function_table{$function} = 1; |
} elsif ($cmd eq "-v") { |
$verbose = 1; |
} elsif (($cmd eq "-h") || ($cmd eq "--help")) { |
usage(); |
} elsif ($cmd eq '-filelist') { |
$filelist = shift @ARGV; |
} |
} |
|
|
# generate a sequence of code that will splice in highlighting information |
# using the s// operator. |
my $dohighlight = ""; |
foreach my $pattern (keys %highlights) { |
# print "scanning pattern $pattern ($highlights{$pattern})\n"; |
$dohighlight .= "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n"; |
} |
|
## |
# dumps section contents to arrays/hashes intended for that purpose. |
# |
sub dump_section { |
my $name = shift; |
my $contents = join "\n", @_; |
|
if ($name =~ m/$type_constant/) { |
$name = $1; |
# print STDERR "constant section '$1' = '$contents'\n"; |
$constants{$name} = $contents; |
} elsif ($name =~ m/$type_param/) { |
# print STDERR "parameter def '$1' = '$contents'\n"; |
$name = $1; |
$parameterdescs{$name} = $contents; |
} else { |
# print STDERR "other section '$name' = '$contents'\n"; |
$sections{$name} = $contents; |
push @sectionlist, $name; |
} |
} |
|
## |
# output function |
# |
# parameterdescs, a hash. |
# function => "function name" |
# parameterlist => @list of parameters |
# parameterdescs => %parameter descriptions |
# sectionlist => @list of sections |
# sections => %descriont descriptions |
# |
|
sub output_highlight { |
my $contents = join "\n",@_; |
my $line; |
|
# DEBUG |
# if (!defined $contents) { |
# use Carp; |
# confess "output_highlight got called with no args?\n"; |
# } |
|
eval $dohighlight; |
die $@ if $@; |
foreach $line (split "\n", $contents) { |
if ($line eq ""){ |
print $lineprefix, $blankline; |
} else { |
$line =~ s/\\\\\\/\&/g; |
print $lineprefix, $line; |
} |
print "\n"; |
} |
} |
|
#output sections in html |
sub output_section_html(%) { |
my %args = %{$_[0]}; |
my $section; |
|
foreach $section (@{$args{'sectionlist'}}) { |
print "<h3>$section</h3>\n"; |
print "<blockquote>\n"; |
output_highlight($args{'sections'}{$section}); |
print "</blockquote>\n"; |
} |
} |
|
# output enum in html |
sub output_enum_html(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
my $count; |
print "<h2>enum ".$args{'enum'}."</h2>\n"; |
|
print "<b>enum ".$args{'enum'}."</b> {<br>\n"; |
$count = 0; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print " <b>".$parameter."</b>"; |
if ($count != $#{$args{'parameterlist'}}) { |
$count++; |
print ",\n"; |
} |
print "<br>"; |
} |
print "};<br>\n"; |
|
print "<h3>Constants</h3>\n"; |
print "<dl>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print "<dt><b>".$parameter."</b>\n"; |
print "<dd>"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
print "</dl>\n"; |
output_section_html(@_); |
print "<hr>\n"; |
} |
|
# output tyepdef in html |
sub output_typedef_html(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
my $count; |
print "<h2>typedef ".$args{'typedef'}."</h2>\n"; |
|
print "<b>typedef ".$args{'typedef'}."</b>\n"; |
output_section_html(@_); |
print "<hr>\n"; |
} |
|
# output struct in html |
sub output_struct_html(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
|
print "<h2>".$args{'type'}." ".$args{'struct'}."</h2>\n"; |
print "<b>".$args{'type'}." ".$args{'struct'}."</b> {<br>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print " <i>$1</i><b>$parameter</b>) <i>($2)</i>;<br>\n"; |
} elsif ($type =~ m/^(.*?)\s*(:.*)/) { |
print " <i>$1</i> <b>$parameter</b>$2;<br>\n"; |
} else { |
print " <i>$type</i> <b>$parameter</b>;<br>\n"; |
} |
} |
print "};<br>\n"; |
|
print "<h3>Members</h3>\n"; |
print "<dl>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print "<dt><b>".$parameter."</b>\n"; |
print "<dd>"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
print "</dl>\n"; |
output_section_html(@_); |
print "<hr>\n"; |
} |
|
# output function in html |
sub output_function_html(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
print "<h2>Function</h2>\n"; |
|
print "<i>".$args{'functiontype'}."</i>\n"; |
print "<b>".$args{'function'}."</b>\n"; |
print "("; |
$count = 0; |
foreach $parameter (@{$args{'parameterlist'}}) { |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print "<i>$1</i><b>$parameter</b>) <i>($2)</i>"; |
} else { |
print "<i>".$type."</i> <b>".$parameter."</b>"; |
} |
if ($count != $#{$args{'parameterlist'}}) { |
$count++; |
print ",\n"; |
} |
} |
print ")\n"; |
|
print "<h3>Arguments</h3>\n"; |
print "<dl>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print "<dt><b>".$parameter."</b>\n"; |
print "<dd>"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
print "</dl>\n"; |
output_section_html(@_); |
print "<hr>\n"; |
} |
|
# output intro in html |
sub output_intro_html(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
|
foreach $section (@{$args{'sectionlist'}}) { |
print "<h3>$section</h3>\n"; |
print "<ul>\n"; |
output_highlight($args{'sections'}{$section}); |
print "</ul>\n"; |
} |
print "<hr>\n"; |
} |
|
sub output_section_sgml(%) { |
my %args = %{$_[0]}; |
my $section; |
# print out each section |
$lineprefix=" "; |
foreach $section (@{$args{'sectionlist'}}) { |
print "<refsect1>\n <title>$section</title>\n <para>\n"; |
if ($section =~ m/EXAMPLE/i) { |
print "<example><para>\n"; |
} |
output_highlight($args{'sections'}{$section}); |
if ($section =~ m/EXAMPLE/i) { |
print "</para></example>\n"; |
} |
print " </para>\n</refsect1>\n"; |
} |
} |
|
# output function in sgml DocBook |
sub output_function_sgml(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
my $id; |
|
$id = "API-".$args{'function'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
print "<refentry>\n"; |
print "<refmeta>\n"; |
print "<refentrytitle><phrase id=\"$id\">".$args{'function'}."</phrase></refentrytitle>\n"; |
print "</refmeta>\n"; |
print "<refnamediv>\n"; |
print " <refname>".$args{'function'}."</refname>\n"; |
print " <refpurpose>\n"; |
print " "; |
output_highlight ($args{'purpose'}); |
print " </refpurpose>\n"; |
print "</refnamediv>\n"; |
|
print "<refsynopsisdiv>\n"; |
print " <title>Synopsis</title>\n"; |
print " <funcsynopsis><funcprototype>\n"; |
print " <funcdef>".$args{'functiontype'}." "; |
print "<function>".$args{'function'}." </function></funcdef>\n"; |
|
$count = 0; |
if ($#{$args{'parameterlist'}} >= 0) { |
foreach $parameter (@{$args{'parameterlist'}}) { |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print " <paramdef>$1<parameter>$parameter</parameter>)\n"; |
print " <funcparams>$2</funcparams></paramdef>\n"; |
} else { |
print " <paramdef>".$type; |
print " <parameter>$parameter</parameter></paramdef>\n"; |
} |
} |
} else { |
print " <void>\n"; |
} |
print " </funcprototype></funcsynopsis>\n"; |
print "</refsynopsisdiv>\n"; |
|
# print parameters |
print "<refsect1>\n <title>Arguments</title>\n"; |
if ($#{$args{'parameterlist'}} >= 0) { |
print " <variablelist>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print " <varlistentry>\n <term><parameter>$parameter</parameter></term>\n"; |
print " <listitem>\n <para>\n"; |
$lineprefix=" "; |
output_highlight($args{'parameterdescs'}{$parameter}); |
print " </para>\n </listitem>\n </varlistentry>\n"; |
} |
print " </variablelist>\n"; |
} else { |
print " <para>\n None\n </para>\n"; |
} |
print "</refsect1>\n"; |
|
output_section_sgml(@_); |
print "</refentry>\n\n"; |
} |
|
# output struct in sgml DocBook |
sub output_struct_sgml(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $id; |
|
$id = "API-struct-".$args{'struct'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
print "<refentry>\n"; |
print "<refmeta>\n"; |
print "<refentrytitle><phrase id=\"$id\">".$args{'type'}." ".$args{'struct'}."</phrase></refentrytitle>\n"; |
print "</refmeta>\n"; |
print "<refnamediv>\n"; |
print " <refname>".$args{'type'}." ".$args{'struct'}."</refname>\n"; |
print " <refpurpose>\n"; |
print " "; |
output_highlight ($args{'purpose'}); |
print " </refpurpose>\n"; |
print "</refnamediv>\n"; |
|
print "<refsynopsisdiv>\n"; |
print " <title>Synopsis</title>\n"; |
print " <programlisting>\n"; |
print $args{'type'}." ".$args{'struct'}." {\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print " $1 $parameter ($2);\n"; |
} elsif ($type =~ m/^(.*?)\s*(:.*)/) { |
print " $1 $parameter$2;\n"; |
} else { |
print " ".$type." ".$parameter.";\n"; |
} |
} |
print "};"; |
print " </programlisting>\n"; |
print "</refsynopsisdiv>\n"; |
|
print " <refsect1>\n"; |
print " <title>Members</title>\n"; |
|
print " <variablelist>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print " <varlistentry>"; |
print " <term>$parameter</term>\n"; |
print " <listitem><para>\n"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
print " </para></listitem>\n"; |
print " </varlistentry>\n"; |
} |
print " </variablelist>\n"; |
print " </refsect1>\n"; |
|
output_section_sgml(@_); |
|
print "</refentry>\n\n"; |
} |
|
# output enum in sgml DocBook |
sub output_enum_sgml(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
my $id; |
|
$id = "API-enum-".$args{'enum'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
print "<refentry>\n"; |
print "<refmeta>\n"; |
print "<refentrytitle><phrase id=\"$id\">enum ".$args{'enum'}."</phrase></refentrytitle>\n"; |
print "</refmeta>\n"; |
print "<refnamediv>\n"; |
print " <refname>enum ".$args{'enum'}."</refname>\n"; |
print " <refpurpose>\n"; |
print " "; |
output_highlight ($args{'purpose'}); |
print " </refpurpose>\n"; |
print "</refnamediv>\n"; |
|
print "<refsynopsisdiv>\n"; |
print " <title>Synopsis</title>\n"; |
print " <programlisting>\n"; |
print "enum ".$args{'enum'}." {\n"; |
$count = 0; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print " $parameter"; |
if ($count != $#{$args{'parameterlist'}}) { |
$count++; |
print ","; |
} |
print "\n"; |
} |
print "};"; |
print " </programlisting>\n"; |
print "</refsynopsisdiv>\n"; |
|
print "<refsect1>\n"; |
print " <title>Constants</title>\n"; |
print " <variablelist>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print " <varlistentry>"; |
print " <term>$parameter</term>\n"; |
print " <listitem><para>\n"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
print " </para></listitem>\n"; |
print " </varlistentry>\n"; |
} |
print " </variablelist>\n"; |
print "</refsect1>\n"; |
|
output_section_sgml(@_); |
|
print "</refentry>\n\n"; |
} |
|
# output typedef in sgml DocBook |
sub output_typedef_sgml(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $id; |
|
$id = "API-typedef-".$args{'typedef'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
print "<refentry>\n"; |
print "<refmeta>\n"; |
print "<refentrytitle><phrase id=\"$id\">typedef ".$args{'typedef'}."</phrase></refentrytitle>\n"; |
print "</refmeta>\n"; |
print "<refnamediv>\n"; |
print " <refname>typedef ".$args{'typedef'}."</refname>\n"; |
print " <refpurpose>\n"; |
print " "; |
output_highlight ($args{'purpose'}); |
print " </refpurpose>\n"; |
print "</refnamediv>\n"; |
|
print "<refsynopsisdiv>\n"; |
print " <title>Synopsis</title>\n"; |
print " <synopsis>typedef ".$args{'typedef'}.";</synopsis>\n"; |
print "</refsynopsisdiv>\n"; |
|
output_section_sgml(@_); |
|
print "</refentry>\n\n"; |
} |
|
# output in sgml DocBook |
sub output_intro_sgml(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
|
my $id = $args{'module'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
# print out each section |
$lineprefix=" "; |
foreach $section (@{$args{'sectionlist'}}) { |
print "<refsect1>\n <title>$section</title>\n <para>\n"; |
if ($section =~ m/EXAMPLE/i) { |
print "<example><para>\n"; |
} |
output_highlight($args{'sections'}{$section}); |
if ($section =~ m/EXAMPLE/i) { |
print "</para></example>\n"; |
} |
print " </para>\n</refsect1>\n"; |
} |
|
print "\n\n"; |
} |
|
# output in sgml DocBook |
sub output_function_gnome { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
my $id; |
|
$id = $args{'module'}."-".$args{'function'}; |
$id =~ s/[^A-Za-z0-9]/-/g; |
|
print "<sect2>\n"; |
print " <title id=\"$id\">".$args{'function'}."</title>\n"; |
|
print " <funcsynopsis>\n"; |
print " <funcdef>".$args{'functiontype'}." "; |
print "<function>".$args{'function'}." "; |
print "</function></funcdef>\n"; |
|
$count = 0; |
if ($#{$args{'parameterlist'}} >= 0) { |
foreach $parameter (@{$args{'parameterlist'}}) { |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print " <paramdef>$1 <parameter>$parameter</parameter>)\n"; |
print " <funcparams>$2</funcparams></paramdef>\n"; |
} else { |
print " <paramdef>".$type; |
print " <parameter>$parameter</parameter></paramdef>\n"; |
} |
} |
} else { |
print " <void>\n"; |
} |
print " </funcsynopsis>\n"; |
if ($#{$args{'parameterlist'}} >= 0) { |
print " <informaltable pgwide=\"1\" frame=\"none\" role=\"params\">\n"; |
print "<tgroup cols=\"2\">\n"; |
print "<colspec colwidth=\"2*\">\n"; |
print "<colspec colwidth=\"8*\">\n"; |
print "<tbody>\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print " <row><entry align=\"right\"><parameter>$parameter</parameter></entry>\n"; |
print " <entry>\n"; |
$lineprefix=" "; |
output_highlight($args{'parameterdescs'}{$parameter}); |
print " </entry></row>\n"; |
} |
print " </tbody></tgroup></informaltable>\n"; |
} else { |
print " <para>\n None\n </para>\n"; |
} |
|
# print out each section |
$lineprefix=" "; |
foreach $section (@{$args{'sectionlist'}}) { |
print "<simplesect>\n <title>$section</title>\n"; |
if ($section =~ m/EXAMPLE/i) { |
print "<example><programlisting>\n"; |
} else { |
} |
print "<para>\n"; |
output_highlight($args{'sections'}{$section}); |
print "</para>\n"; |
if ($section =~ m/EXAMPLE/i) { |
print "</programlisting></example>\n"; |
} else { |
} |
print " </simplesect>\n"; |
} |
|
print "</sect2>\n\n"; |
} |
|
## |
# output function in man |
sub output_function_man(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
|
print ".TH \"$args{'function'}\" 9 \"$args{'function'}\" \"25 May 1998\" \"Kernel Hacker's Manual\" LINUX\n"; |
|
print ".SH NAME\n"; |
print $args{'function'}." \\- ".$args{'purpose'}."\n"; |
|
print ".SH SYNOPSIS\n"; |
print ".B \"".$args{'functiontype'}."\" ".$args{'function'}."\n"; |
$count = 0; |
my $parenth = "("; |
my $post = ","; |
foreach my $parameter (@{$args{'parameterlist'}}) { |
if ($count == $#{$args{'parameterlist'}}) { |
$post = ");"; |
} |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print ".BI \"".$parenth.$1."\" ".$parameter." \") (".$2.")".$post."\"\n"; |
} else { |
$type =~ s/([^\*])$/$1 /; |
print ".BI \"".$parenth.$type."\" ".$parameter." \"".$post."\"\n"; |
} |
$count++; |
$parenth = ""; |
} |
|
print ".SH ARGUMENTS\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print ".IP \"".$parameter."\" 12\n"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
foreach $section (@{$args{'sectionlist'}}) { |
print ".SH \"", uc $section, "\"\n"; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
## |
# output enum in man |
sub output_enum_man(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
|
print ".TH \"$args{'module'}\" 9 \"enum $args{'enum'}\" \"$man_date\" \"API Manual\" LINUX\n"; |
|
print ".SH NAME\n"; |
print "enum ".$args{'enum'}." \\- ".$args{'purpose'}."\n"; |
|
print ".SH SYNOPSIS\n"; |
print "enum ".$args{'enum'}." {\n"; |
$count = 0; |
foreach my $parameter (@{$args{'parameterlist'}}) { |
print ".br\n.BI \" $parameter\"\n"; |
if ($count == $#{$args{'parameterlist'}}) { |
print "\n};\n"; |
last; |
} |
else { |
print ", \n.br\n"; |
} |
$count++; |
} |
|
print ".SH Constants\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print ".IP \"".$parameter."\" 12\n"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
foreach $section (@{$args{'sectionlist'}}) { |
print ".SH \"$section\"\n"; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
## |
# output struct in man |
sub output_struct_man(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
|
print ".TH \"$args{'module'}\" 9 \"".$args{'type'}." ".$args{'struct'}."\" \"$man_date\" \"API Manual\" LINUX\n"; |
|
print ".SH NAME\n"; |
print $args{'type'}." ".$args{'struct'}." \\- ".$args{'purpose'}."\n"; |
|
print ".SH SYNOPSIS\n"; |
print $args{'type'}." ".$args{'struct'}." {\n"; |
|
foreach my $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print "\n.br\n"; |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print ".BI \" ".$1."\" ".$parameter." \") (".$2.")"."\"\n;\n"; |
} elsif ($type =~ m/^(.*?)\s*(:.*)/) { |
print ".BI \" ".$1."\" ".$parameter.$2." \""."\"\n;\n"; |
} else { |
$type =~ s/([^\*])$/$1 /; |
print ".BI \" ".$type."\" ".$parameter." \""."\"\n;\n"; |
} |
print "\n.br\n"; |
} |
print "};\n.br\n"; |
|
print ".SH Arguments\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print ".IP \"".$parameter."\" 12\n"; |
output_highlight($args{'parameterdescs'}{$parameter}); |
} |
foreach $section (@{$args{'sectionlist'}}) { |
print ".SH \"$section\"\n"; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
## |
# output typedef in man |
sub output_typedef_man(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
|
print ".TH \"$args{'module'}\" 9 \"$args{'typedef'}\" \"$man_date\" \"API Manual\" LINUX\n"; |
|
print ".SH NAME\n"; |
print "typedef ".$args{'typedef'}." \\- ".$args{'purpose'}."\n"; |
|
foreach $section (@{$args{'sectionlist'}}) { |
print ".SH \"$section\"\n"; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
sub output_intro_man(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
my $count; |
|
print ".TH \"$args{'module'}\" 9 \"$args{'module'}\" \"$man_date\" \"API Manual\" LINUX\n"; |
|
foreach $section (@{$args{'sectionlist'}}) { |
print ".SH \"$section\"\n"; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
## |
# output in text |
sub output_function_text(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
|
print "Function:\n\n"; |
my $start=$args{'functiontype'}." ".$args{'function'}." ("; |
print $start; |
my $count = 0; |
foreach my $parameter (@{$args{'parameterlist'}}) { |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print $1.$parameter.") (".$2; |
} else { |
print $type." ".$parameter; |
} |
if ($count != $#{$args{'parameterlist'}}) { |
$count++; |
print ",\n"; |
print " " x length($start); |
} else { |
print ");\n\n"; |
} |
} |
|
print "Arguments:\n\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print $parameter."\n\t".$args{'parameterdescs'}{$parameter}."\n"; |
} |
output_section_text(@_); |
} |
|
#output sections in text |
sub output_section_text(%) { |
my %args = %{$_[0]}; |
my $section; |
|
print "\n"; |
foreach $section (@{$args{'sectionlist'}}) { |
print "$section:\n\n"; |
output_highlight($args{'sections'}{$section}); |
} |
print "\n\n"; |
} |
|
# output enum in text |
sub output_enum_text(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
my $count; |
print "Enum:\n\n"; |
|
print "enum ".$args{'enum'}." {\n"; |
$count = 0; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print "\t$parameter"; |
if ($count != $#{$args{'parameterlist'}}) { |
$count++; |
print ","; |
} |
print "\n"; |
} |
print "};\n\n"; |
|
print "Constants:\n\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
print "$parameter\n\t"; |
print $args{'parameterdescs'}{$parameter}."\n"; |
} |
|
output_section_text(@_); |
} |
|
# output typedef in text |
sub output_typedef_text(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
my $count; |
print "Typedef:\n\n"; |
|
print "typedef ".$args{'typedef'}."\n"; |
output_section_text(@_); |
} |
|
# output struct as text |
sub output_struct_text(%) { |
my %args = %{$_[0]}; |
my ($parameter); |
|
print $args{'type'}." ".$args{'struct'}.":\n\n"; |
print $args{'type'}." ".$args{'struct'}." {\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
$type = $args{'parametertypes'}{$parameter}; |
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { |
# pointer-to-function |
print "\t$1 $parameter) ($2);\n"; |
} elsif ($type =~ m/^(.*?)\s*(:.*)/) { |
print "\t$1 $parameter$2;\n"; |
} else { |
print "\t".$type." ".$parameter.";\n"; |
} |
} |
print "};\n\n"; |
|
print "Members:\n\n"; |
foreach $parameter (@{$args{'parameterlist'}}) { |
($args{'parameterdescs'}{$parameter} ne $undescribed) || next; |
print "$parameter\n\t"; |
print $args{'parameterdescs'}{$parameter}."\n"; |
} |
print "\n"; |
output_section_text(@_); |
} |
|
sub output_intro_text(%) { |
my %args = %{$_[0]}; |
my ($parameter, $section); |
|
foreach $section (@{$args{'sectionlist'}}) { |
print " $section:\n"; |
print " -> "; |
output_highlight($args{'sections'}{$section}); |
} |
} |
|
## |
# generic output function for typedefs |
sub output_declaration { |
no strict 'refs'; |
my $name = shift; |
my $functype = shift; |
my $func = "output_${functype}_$output_mode"; |
if (($function_only==0) || |
( $function_only == 1 && defined($function_table{$name})) || |
( $function_only == 2 && !defined($function_table{$name}))) |
{ |
&$func(@_); |
$section_counter++; |
} |
} |
|
## |
# generic output function - calls the right one based |
# on current output mode. |
sub output_intro { |
no strict 'refs'; |
my $func = "output_intro_".$output_mode; |
&$func(@_); |
$section_counter++; |
} |
|
## |
# takes a declaration (struct, union, enum, typedef) and |
# invokes the right handler. NOT called for functions. |
sub dump_declaration($$) { |
no strict 'refs'; |
my ($prototype, $file) = @_; |
my $func = "dump_".$decl_type; |
&$func(@_); |
} |
|
sub dump_union($$) { |
dump_struct(@_); |
} |
|
sub dump_struct($$) { |
my $x = shift; |
my $file = shift; |
|
if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { |
$declaration_name = $2; |
my $members = $3; |
|
# ignore embedded structs or unions |
$members =~ s/{.*}//g; |
|
create_parameterlist($members, ';', $file); |
|
output_declaration($declaration_name, |
'struct', |
{'struct' => $declaration_name, |
'module' => $modulename, |
'parameterlist' => \@parameterlist, |
'parameterdescs' => \%parameterdescs, |
'parametertypes' => \%parametertypes, |
'sectionlist' => \@sectionlist, |
'sections' => \%sections, |
'purpose' => $declaration_purpose, |
'type' => $decl_type |
}); |
} |
else { |
print STDERR "Error(${file}:$.): Cannot parse struct or union!\n"; |
++$errors; |
} |
} |
|
sub dump_enum($$) { |
my $x = shift; |
my $file = shift; |
|
if ($x =~ /enum\s+(\w+)\s*{(.*)}/) { |
$declaration_name = $1; |
my $members = $2; |
|
foreach my $arg (split ',', $members) { |
$arg =~ s/^\s*(\w+).*/$1/; |
push @parameterlist, $arg; |
if (!$parameterdescs{$arg}) { |
$parameterdescs{$arg} = $undescribed; |
print STDERR "Warning(${file}:$.): Enum value '$arg' ". |
"not described in enum '$declaration_name'\n"; |
} |
|
} |
|
output_declaration($declaration_name, |
'enum', |
{'enum' => $declaration_name, |
'module' => $modulename, |
'parameterlist' => \@parameterlist, |
'parameterdescs' => \%parameterdescs, |
'sectionlist' => \@sectionlist, |
'sections' => \%sections, |
'purpose' => $declaration_purpose |
}); |
} |
else { |
print STDERR "Error(${file}:$.): Cannot parse enum!\n"; |
++$errors; |
} |
} |
|
sub dump_typedef($$) { |
my $x = shift; |
my $file = shift; |
|
while (($x =~ /\(*.\)\s*;$/) || ($x =~ /\[*.\]\s*;$/)) { |
$x =~ s/\(*.\)\s*;$/;/; |
$x =~ s/\[*.\]\s*;$/;/; |
} |
|
if ($x =~ /typedef.*\s+(\w+)\s*;/) { |
$declaration_name = $1; |
|
output_declaration($declaration_name, |
'typedef', |
{'typedef' => $declaration_name, |
'module' => $modulename, |
'sectionlist' => \@sectionlist, |
'sections' => \%sections, |
'purpose' => $declaration_purpose |
}); |
} |
else { |
print STDERR "Error(${file}:$.): Cannot parse typedef!\n"; |
++$errors; |
} |
} |
|
sub create_parameterlist($$$) { |
my $args = shift; |
my $splitter = shift; |
my $file = shift; |
my $type; |
my $param; |
|
while ($args =~ /(\([^\),]+),/) { |
$args =~ s/(\([^\),]+),/$1#/g; |
} |
|
foreach my $arg (split($splitter, $args)) { |
# strip leading/trailing spaces |
$arg =~ s/^\s*//; |
$arg =~ s/\s*$//; |
$arg =~ s/\s+/ /; |
|
if ($arg =~ m/\(/) { |
# pointer-to-function |
$arg =~ tr/#/,/; |
$arg =~ m/[^\(]+\(\*([^\)]+)\)/; |
$param = $1; |
$type = $arg; |
$type =~ s/([^\(]+\(\*)$param/$1/; |
} else { |
# evil magic to get fixed array parameters to work |
$arg =~ s/(.+\s+)(.+)\[.*/$1* $2/; |
my @args = split('\s', $arg); |
|
$param = pop @args; |
if ($param =~ m/^(\*+)(.*)/) { |
$param = $2; |
push @args, $1; |
} |
elsif ($param =~ m/(.*?)\s*:\s*(\d+)/) { |
$param = $1; |
push @args, ":$2"; |
} |
$type = join " ", @args; |
} |
|
if ($type eq "" && $param eq "...") |
{ |
$type="..."; |
$param="..."; |
$parameterdescs{"..."} = "variable arguments"; |
} |
elsif ($type eq "" && ($param eq "" or $param eq "void")) |
{ |
$type=""; |
$param="void"; |
$parameterdescs{void} = "no arguments"; |
} |
if (defined $type && $type && !defined $parameterdescs{$param}) { |
$parameterdescs{$param} = $undescribed; |
|
if (($type eq 'function') || ($type eq 'enum')) { |
print STDERR "Warning(${file}:$.): Function parameter ". |
"or member '$param' not " . |
"described in '$declaration_name'\n"; |
} |
++$errors; |
} |
|
push @parameterlist, $param; |
$parametertypes{$param} = $type; |
} |
} |
|
## |
# takes a function prototype and the name of the current file being |
# processed and spits out all the details stored in the global |
# arrays/hashes. |
sub dump_function($$) { |
my $prototype = shift; |
my $file = shift; |
|
$prototype =~ s/^static +//; |
$prototype =~ s/^extern +//; |
$prototype =~ s/^inline +//; |
$prototype =~ s/^__inline__ +//; |
$prototype =~ s/^#define +//; #ak added |
|
# Yes, this truly is vile. We are looking for: |
# 1. Return type (may be nothing if we're looking at a macro) |
# 2. Function name |
# 3. Function parameters. |
# |
# All the while we have to watch out for function pointer parameters |
# (which IIRC is what the two sections are for), C types (these |
# regexps don't even start to express all the possibilities), and |
# so on. |
# |
# If you mess with these regexps, it's a good idea to check that |
# the following functions' documentation still comes out right: |
# - parport_register_device (function pointer parameters) |
# - atomic_set (macro) |
# - pci_match_device (long return type) |
|
if ($prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\(]*)\)/ || |
$prototype =~ m/^()([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s+\w+)\s+([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/ || |
$prototype =~ m/^(\w+\s+\w+\s+\w+\s*\*)\s*([a-zA-Z0-9_~:]+)\s*\(([^\{]*)\)/) { |
$return_type = $1; |
$declaration_name = $2; |
my $args = $3; |
|
create_parameterlist($args, ',', $file); |
} else { |
print STDERR "Error(${file}:$.): cannot understand prototype: '$prototype'\n"; |
++$errors; |
return; |
} |
|
output_declaration($declaration_name, |
'function', |
{'function' => $declaration_name, |
'module' => $modulename, |
'functiontype' => $return_type, |
'parameterlist' => \@parameterlist, |
'parameterdescs' => \%parameterdescs, |
'parametertypes' => \%parametertypes, |
'sectionlist' => \@sectionlist, |
'sections' => \%sections, |
'purpose' => $declaration_purpose |
}); |
} |
|
sub process_file($); |
|
# Read the file that maps relative names to absolute names for |
# separate source and object directories and for shadow trees. |
if (open(SOURCE_MAP, "<.tmp_filelist.txt")) { |
my ($relname, $absname); |
while(<SOURCE_MAP>) { |
chop(); |
($relname, $absname) = (split())[0..1]; |
$relname =~ s:^/+::; |
$source_map{$relname} = $absname; |
} |
close(SOURCE_MAP); |
} |
|
if ($filelist) { |
open(FLIST,"<$filelist") or die "Can't open file list $filelist"; |
while(<FLIST>) { |
chop; |
process_file($_); |
} |
} |
|
foreach (@ARGV) { |
chomp; |
process_file($_); |
} |
|
exit($errors); |
|
sub reset_state { |
$function = ""; |
%constants = (); |
%parameterdescs = (); |
%parametertypes = (); |
@parameterlist = (); |
%sections = (); |
@sectionlist = (); |
$prototype = ""; |
|
$state = 0; |
} |
|
sub process_state3_function($$) { |
my $x = shift; |
my $file = shift; |
|
if ($x =~ m#\s*/\*\s+MACDOC\s*#io) { |
# do nothing |
} |
elsif ($x =~ /([^\{]*)/) { |
$prototype .= $1; |
} |
if (($x =~ /\{/) || ($x =~ /\#/) || ($x =~ /;/)) { |
$prototype =~ s@/\*.*?\*/@@gos; # strip comments. |
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's. |
$prototype =~ s@^\s+@@gos; # strip leading spaces |
dump_function($prototype,$file); |
reset_state(); |
} |
} |
|
sub process_state3_type($$) { |
my $x = shift; |
my $file = shift; |
|
$x =~ s@/\*.*?\*/@@gos; # strip comments. |
$x =~ s@[\r\n]+@ @gos; # strip newlines/cr's. |
$x =~ s@^\s+@@gos; # strip leading spaces |
$x =~ s@\s+$@@gos; # strip trailing spaces |
|
while (1) { |
if ( $x =~ /([^{};]*)([{};])(.*)/ ) { |
$prototype .= $1 . $2; |
($2 eq '{') && $brcount++; |
($2 eq '}') && $brcount--; |
if (($2 eq ';') && ($brcount == 0)) { |
dump_declaration($prototype,$file); |
reset_state(); |
last; |
} |
$x = $3; |
} else { |
$prototype .= $x; |
last; |
} |
} |
} |
|
sub process_file($) { |
my ($file) = @_; |
my $identifier; |
my $func; |
my $initial_section_counter = $section_counter; |
|
if (defined($source_map{$file})) { |
$file = $source_map{$file}; |
} |
|
if (!open(IN,"<$file")) { |
print STDERR "Error: Cannot open file $file\n"; |
++$errors; |
return; |
} |
|
$section_counter = 0; |
while (<IN>) { |
if ($state == 0) { |
if (/$doc_start/o) { |
$state = 1; # next line is always the function name |
} |
} elsif ($state == 1) { # this line is the function name (always) |
if (/$doc_block/o) { |
$state = 4; |
$contents = ""; |
if ( $1 eq "" ) { |
$section = $section_intro; |
} else { |
$section = $1; |
} |
} |
elsif (/$doc_decl/o) { |
$identifier = $1; |
if (/\s*([\w\s]+?)\s*-/) { |
$identifier = $1; |
} |
|
$state = 2; |
if (/-(.*)/) { |
$declaration_purpose = $1; |
} else { |
$declaration_purpose = ""; |
} |
if ($identifier =~ m/^struct/) { |
$decl_type = 'struct'; |
} elsif ($identifier =~ m/^union/) { |
$decl_type = 'union'; |
} elsif ($identifier =~ m/^enum/) { |
$decl_type = 'enum'; |
} elsif ($identifier =~ m/^typedef/) { |
$decl_type = 'typedef'; |
} else { |
$decl_type = 'function'; |
} |
|
if ($verbose) { |
print STDERR "Info(${file}:$.): Scanning doc for $identifier\n"; |
} |
} else { |
print STDERR "Warning(${file}:$.): Cannot understand $_ on line $.", |
" - I thought it was a doc line\n"; |
++$errors; |
$state = 0; |
} |
} elsif ($state == 2) { # look for head: lines, and include content |
if (/$doc_sect/o) { |
$newsection = $1; |
$newcontents = $2; |
|
if ($contents ne "") { |
$contents =~ s/\&/\\\\\\amp;/g; |
$contents =~ s/\</\\\\\\lt;/g; |
$contents =~ s/\>/\\\\\\gt;/g; |
dump_section($section, $contents); |
$section = $section_default; |
} |
|
$contents = $newcontents; |
if ($contents ne "") { |
$contents .= "\n"; |
} |
$section = $newsection; |
} elsif (/$doc_end/) { |
|
if ($contents ne "") { |
$contents =~ s/\&/\\\\\\amp;/g; |
$contents =~ s/\</\\\\\\lt;/g; |
$contents =~ s/\>/\\\\\\gt;/g; |
dump_section($section, $contents); |
$section = $section_default; |
$contents = ""; |
} |
|
$prototype = ""; |
$state = 3; |
$brcount = 0; |
# print STDERR "end of doc comment, looking for prototype\n"; |
} elsif (/$doc_content/) { |
# miguel-style comment kludge, look for blank lines after |
# @parameter line to signify start of description |
if ($1 eq "" && |
($section =~ m/^@/ || $section eq $section_context)) { |
$contents =~ s/\&/\\\\\\amp;/g; |
$contents =~ s/\</\\\\\\lt;/g; |
$contents =~ s/\>/\\\\\\gt;/g; |
dump_section($section, $contents); |
$section = $section_default; |
$contents = ""; |
} else { |
$contents .= $1."\n"; |
} |
} else { |
# i dont know - bad line? ignore. |
print STDERR "Warning(${file}:$.): bad line: $_"; |
++$errors; |
} |
} elsif ($state == 3) { # scanning for function { (end of prototype) |
if ($decl_type eq 'function') { |
process_state3_function($_, $file); |
} else { |
process_state3_type($_, $file); |
} |
} elsif ($state == 4) { |
# Documentation block |
if (/$doc_block/) { |
dump_section($section, $contents); |
output_intro({'sectionlist' => \@sectionlist, |
'sections' => \%sections }); |
$contents = ""; |
$function = ""; |
%constants = (); |
%parameterdescs = (); |
%parametertypes = (); |
@parameterlist = (); |
%sections = (); |
@sectionlist = (); |
$prototype = ""; |
if ( $1 eq "" ) { |
$section = $section_intro; |
} else { |
$section = $1; |
} |
} |
elsif (/$doc_end/) |
{ |
dump_section($section, $contents); |
output_intro({'sectionlist' => \@sectionlist, |
'sections' => \%sections }); |
$contents = ""; |
$function = ""; |
%constants = (); |
%parameterdescs = (); |
%parametertypes = (); |
@parameterlist = (); |
%sections = (); |
@sectionlist = (); |
$prototype = ""; |
$state = 0; |
} |
elsif (/$doc_content/) |
{ |
if ( $1 eq "" ) |
{ |
$contents .= $blankline; |
} |
else |
{ |
$contents .= $1 . "\n"; |
} |
} |
} |
} |
if ($initial_section_counter == $section_counter) { |
print STDERR "Warning(${file}): no structured comments found\n"; |
if ($output_mode eq "sgml") { |
# The template wants at least one RefEntry here; make one. |
print "<refentry>\n"; |
print " <refnamediv>\n"; |
print " <refname>\n"; |
print " ${file}\n"; |
print " </refname>\n"; |
print " <refpurpose>\n"; |
print " Document generation inconsistency\n"; |
print " </refpurpose>\n"; |
print " </refnamediv>\n"; |
print " <refsect1>\n"; |
print " <title>\n"; |
print " Oops\n"; |
print " </title>\n"; |
print " <warning>\n"; |
print " <para>\n"; |
print " The template for this document tried to insert\n"; |
print " the structured comment from the file\n"; |
print " <filename>${file}</filename> at this point,\n"; |
print " but none was found.\n"; |
print " This dummy section is inserted to allow\n"; |
print " generation to continue.\n"; |
print " </para>\n"; |
print " </warning>\n"; |
print " </refsect1>\n"; |
print "</refentry>\n"; |
} |
} |
} |
/ksymoops/README
0,0 → 1,8
ksymoops has been removed from the kernel. It was always meant to be a |
free standing utility, not linked to any particular kernel version. |
The latest version can be found in |
ftp://ftp.<country>.kernel.org/pub/linux/utils/kernel/ksymoops together |
with patches to other utilities in order to give more accurate Oops |
debugging. |
|
Keith Owens <kaos@ocs.com.au> Sat Jun 19 10:30:34 EST 1999 |
/tkgen.c
0,0 → 1,1521
/* 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 parents 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: |
printf( " }\n" ); |
break; |
|
case token_dep_mbool: |
modtoyes = 1; |
case token_dep_bool: |
printf( "\n" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
if ( ! vartable[get_varnum( tmp->name )].global_written ) |
{ |
global( tmp->name ); |
} |
printf( "\tset tmpvar_dep [effective_dep [list" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
printf( " $%s", tmp->name ); |
printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, |
modtoyes ); |
printf( "if {$tmpvar_dep != 1" ); |
if (modtoyes) |
printf( " && $tmpvar_dep != 2" ); |
printf( "} then {configure_entry .menu%d.config.f.x%d disabled {y};", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d normal {y};", |
menu_num, line_num ); |
printf( "}; " ); |
case token_bool: |
if ( cfg->token == token_bool ) |
printf( "\n\t" ); |
printf( "configure_entry .menu%d.config.f.x%d normal {n l", |
menu_num, line_num ); |
if ( cfg->token == token_bool ) |
printf( " y" ); |
printf( "}" ); |
printf( "} else {"); |
printf( "configure_entry .menu%d.config.f.x%d disabled {y n l}}\n", |
menu_num, line_num ); |
break; |
|
case token_choice_header: |
printf( "configure_entry .menu%d.config.f.x%d normal {x l}", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {x l}", |
menu_num, line_num ); |
printf( "}\n" ); |
break; |
|
case token_choice_item: |
fprintf( stderr, "Internal error on token_choice_item\n" ); |
exit( 1 ); |
|
case token_dep_tristate: |
printf( "\n" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
if ( ! vartable[get_varnum( tmp->name )].global_written ) |
{ |
global( tmp->name ); |
} |
printf( "\tset tmpvar_dep [effective_dep [list" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
printf( " $%s", tmp->name ); |
printf( "]];set %s [sync_tristate $%s $tmpvar_dep];", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
printf( "\tif {$tmpvar_dep != 1} then {" ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {y}", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d normal {y}", |
menu_num, line_num ); |
printf( "}; " ); |
printf( "if {$tmpvar_dep == 0} then {" ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {m}", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d normal {m}", |
menu_num, line_num ); |
printf( "}; " ); |
case token_tristate: |
if ( cfg->token == token_tristate ) |
{ |
printf( "\n\tconfigure_entry .menu%d.config.f.x%d normal {y}; ", |
menu_num, line_num ); |
} |
printf( "if {($CONFIG_MODULES == 1)} then {" ); |
printf( "configure_entry .menu%d.config.f.x%d normal {m}} else {", |
menu_num, line_num ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {m}}; ", |
menu_num, line_num ); |
printf( "configure_entry .menu%d.config.f.x%d normal {n l}", |
menu_num, line_num ); |
|
/* |
* Or in a bit to the variable - this causes all of the radiobuttons |
* to be deselected (i.e. not be red). |
*/ |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {y n m l}}\n", |
menu_num, line_num ); |
break; |
|
case token_hex: |
case token_int: |
case token_string: |
printf( ".menu%d.config.f.x%d.x configure -state normal -foreground [ cget .ref -foreground ]; ", |
menu_num, line_num ); |
printf( ".menu%d.config.f.x%d.l configure -state normal; ", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( ".menu%d.config.f.x%d.x configure -state disabled -foreground [ cget .ref -disabledforeground ]; ", |
menu_num, line_num ); |
printf( ".menu%d.config.f.x%d.l configure -state disabled}\n", |
menu_num, line_num ); |
break; |
|
case token_comment: |
case token_mainmenu_option: |
if ( line_num >= 0 ) |
{ |
printf( "configure_entry .menu%d.config.f.x%d normal {m}", |
menu_num, line_num ); |
printf( "} else {" ); |
printf( "configure_entry .menu%d.config.f.x%d disabled {m}}\n", |
menu_num, line_num ); |
} |
else |
printf( ".f0.x%d configure -state normal } else { .f0.x%d configure -state disabled }\n", |
menu_num, menu_num ); |
break; |
} |
} |
else |
{ |
int modtoyes = 0; |
|
switch ( cfg->token ) |
{ |
default: |
printf( " }\n" ); |
break; |
|
case token_dep_mbool: |
modtoyes = 1; |
case token_dep_bool: |
printf( "\n" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
if ( ! vartable[get_varnum( tmp->name )].global_written ) |
{ |
global( tmp->name ); |
} |
printf( "\tset tmpvar_dep [effective_dep [list" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
printf( " $%s", tmp->name ); |
printf( "]];set %s [sync_bool $%s $tmpvar_dep %d];", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, |
modtoyes ); |
case token_bool: |
if ( cfg->token == token_bool ) |
printf( "\n\t" ); |
printf( "set %s [expr $%s&15]", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
printf( "} else {"); |
printf( "set %s [expr $%s|16]}\n", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
break; |
|
case token_choice_header: |
printf( "} else {" ); |
for ( cfg1 = cfg->next; |
cfg1 != NULL && cfg1->token == token_choice_item; |
cfg1 = cfg1->next ) |
printf( "set %s 4;", vartable[cfg1->nameindex].name ); |
printf( "}\n" ); |
break; |
|
case token_choice_item: |
fprintf( stderr, "Internal error on token_choice_item\n" ); |
exit( 1 ); |
|
case token_define_bool: |
case token_define_tristate: |
if ( ! vartable[get_varnum( cfg->value )].global_written ) |
{ |
global( cfg->value ); |
} |
printf( "set %s $%s }\n", |
vartable[cfg->nameindex].name, cfg->value ); |
break; |
|
case token_define_hex: |
case token_define_int: |
printf( "set %s %s }\n", |
vartable[cfg->nameindex].name, cfg->value ); |
break; |
|
case token_define_string: |
printf( "set %s \"%s\" }\n", |
vartable[cfg->nameindex].name, cfg->value ); |
break; |
|
case token_dep_tristate: |
printf( "\n" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
if ( ! vartable[get_varnum( tmp->name )].global_written ) |
{ |
global( tmp->name ); |
} |
printf( "\tset tmpvar_dep [effective_dep [list" ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
printf( " $%s", tmp->name ); |
printf( "]]; set %s [sync_tristate $%s $tmpvar_dep]; ", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
case token_tristate: |
if ( cfg->token == token_tristate ) |
printf( "if {($CONFIG_MODULES == 0) && ($%s == 2)} then {set %s 1}; ", |
vartable[cfg->nameindex].name, |
vartable[cfg->nameindex].name ); |
/* |
* Or in a bit to the variable - this causes all of the radiobuttons |
* to be deselected (i.e. not be red). |
*/ |
printf( "set %s [expr $%s&15]", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
printf( "} else {" ); |
|
/* |
* Clear the disable bit to enable the correct radiobutton. |
*/ |
printf( "set %s [expr $%s|16]}\n", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
break; |
|
case token_hex: |
case token_int: |
if ( cfg->value && *cfg->value == '$' ) |
{ |
int i = get_varnum( cfg->value+1 ); |
printf( "\n" ); |
if ( ! vartable[i].global_written ) |
{ |
global( vartable[i].name ); |
} |
printf( "\t" ); |
} |
if ( cfg->token == token_hex ) |
printf( "validate_hex " ); |
else if ( cfg->token == token_int ) |
printf( "validate_int " ); |
printf( "%s \"$%s\" %s}\n", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name, |
cfg->value ); |
break; |
|
case token_unset: |
printf( "set %s 4}\n", vartable[cfg->nameindex].name ); |
break; |
} |
} |
} |
|
|
/* |
* Generate a line that writes a variable to the output file. |
*/ |
void generate_writeconfig( struct kconfig * cfg ) |
{ |
struct condition * cond; |
struct dependency * tmp; |
int depmod = 2; |
|
/* |
* Generate global declaration for this symbol. |
*/ |
if ( cfg->token != token_comment ) |
{ |
if ( cfg->nameindex > 0 && ! vartable[cfg->nameindex].global_written ) |
{ |
vartable[cfg->nameindex].global_written = 1; |
global( vartable[cfg->nameindex].name ); |
} |
if ( cfg->token == token_define_tristate || cfg->token == token_define_bool ) |
{ |
if ( ! vartable[get_varnum( cfg->value )].global_written ) |
{ |
vartable[get_varnum( cfg->value )].global_written = 1; |
global( cfg->value ); |
} |
} |
else if ( cfg->nameindex <= 0 && cfg->token == token_choice_header ) |
{ |
printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); |
} |
} |
|
/* |
* Generate global declarations for the condition chain. |
*/ |
for ( cond = cfg->cond; 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; |
} |
} |
|
/* |
* Generate indentation. |
*/ |
printf( "\t" ); |
|
/* |
* Generate the conditional. |
*/ |
if ( cfg->cond != NULL ) |
{ |
printf( "if {" ); |
for ( cond = cfg->cond; 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, "n" ) == 0 ) printf( "0" ); |
else if ( strcmp( cond->str, "y" ) == 0 ) printf( "1" ); |
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 the write_* procedures in header.tk. |
*/ |
switch ( cfg->token ) |
{ |
default: |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_bool: |
case token_tristate: |
printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_choice_header: |
/* |
* This is funky code -- it fails if there were any conditionals. |
* Fortunately all the conditionals got stripped off somewhere |
* else. |
*/ |
{ |
struct kconfig * cfg1; |
for ( cfg1 = cfg->next; |
cfg1 != NULL && cfg1->token == token_choice_item; |
cfg1 = cfg1->next ) |
{ |
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 }", |
-(cfg->nameindex), cfg1->label, |
vartable[cfg1->nameindex].name, |
vartable[cfg1->nameindex].name ); |
} |
} |
if ( cfg->cond != NULL ) |
printf( "}" ); |
printf( "\n" ); |
break; |
|
case token_choice_item: |
fprintf( stderr, "Internal error on token_choice_item\n" ); |
exit( 1 ); |
|
case token_comment: |
printf( "write_comment $cfg $autocfg \"%s\"", |
cfg->label ); |
if ( cfg->cond != NULL ) |
printf( "}" ); |
printf( "\n" ); |
break; |
|
case token_define_bool: |
case token_define_tristate: |
if ( cfg->cond == NULL ) |
{ |
printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2\n", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
} |
else |
{ |
printf( "write_tristate $cfg $autocfg %s $%s [list $notmod] 2 }\n", |
vartable[cfg->nameindex].name, cfg->value ); |
} |
break; |
|
case token_dep_mbool: |
depmod = 1; |
case token_dep_bool: |
case token_dep_tristate: |
printf( "write_tristate $cfg $autocfg %s $%s [list", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
for ( tmp = cfg->depend; tmp; tmp = tmp->next ) |
printf( " $%s", tmp->name ); |
printf( "] %d", depmod ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_define_hex: |
printf( "write_hex $cfg $autocfg %s %s $notmod", |
vartable[cfg->nameindex].name, cfg->value ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_define_int: |
printf( "write_int $cfg $autocfg %s %s $notmod", |
vartable[cfg->nameindex].name, cfg->value ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_define_string: |
printf( "write_string $cfg $autocfg %s \"%s\" $notmod", |
vartable[cfg->nameindex].name, cfg->value ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_hex: |
printf( "write_hex $cfg $autocfg %s $%s $notmod", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_int: |
printf( "write_int $cfg $autocfg %s $%s $notmod", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
|
case token_string: |
printf( "write_string $cfg $autocfg %s \"$%s\" $notmod", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
if ( cfg->cond != NULL ) |
printf( " }" ); |
printf( "\n" ); |
break; |
} |
} |
|
static void generate_update_var( struct kconfig * scfg, int menu_num ) |
{ |
struct kconfig * cfg; |
|
if ( menu_num>0 ) |
{ |
printf( "proc update_define_menu%d {} {\n", menu_num ); |
printf( "\tupdate_define_mainmenu\n" ); |
} |
else |
printf( "proc update_define_mainmenu {} {\n" ); |
clear_globalflags(); |
global( "CONFIG_MODULES" ); |
vartable[ get_varnum( "CONFIG_MODULES" ) ].global_written = 1; |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
if ( cfg->menu_number == menu_num && (cfg->token == token_define_bool || cfg->token == token_define_tristate |
|| cfg->token == token_define_hex || cfg->token == token_define_int |
|| cfg->token == token_define_string || cfg->token == token_unset |
|| cfg->token == token_tristate) ) |
{ |
if ( ! vartable[cfg->nameindex].global_written ) |
{ |
vartable[cfg->nameindex].global_written = 1; |
global( vartable[cfg->nameindex].name ); |
} |
} |
} |
|
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
char tmp[20]; |
struct kconfig * cfg1; |
|
if ( cfg->menu_number == menu_num ) |
{ |
switch ( cfg->token ) |
{ |
default: |
case token_choice_item: |
break; |
case token_choice_header: |
sprintf( tmp, "tmpvar_%d", -(cfg->nameindex) ); |
global( tmp ); |
for ( cfg1 = cfg->next; |
cfg1 != NULL && cfg1->token == token_choice_item; |
cfg1 = cfg1->next ) |
{ |
vartable[cfg1->nameindex].global_written = 1; |
global( vartable[cfg1->nameindex].name ); |
printf( "\tif {$tmpvar_%d == \"%s\"} then {set %s 1} else {set %s 0}\n", |
-(cfg->nameindex), cfg1->label, |
vartable[cfg1->nameindex].name, |
vartable[cfg1->nameindex].name ); |
} |
break; |
case token_bool: |
case token_define_bool: |
case token_define_tristate: |
case token_define_hex: |
case token_define_int: |
case token_define_string: |
case token_dep_bool: |
case token_dep_tristate: |
case token_dep_mbool: |
case token_int: |
case token_hex: |
case token_mainmenu_option: |
case token_tristate: |
case token_unset: |
if ( cfg->cond != NULL ) |
generate_if( cfg, cfg->cond, menu_num, -2 ); |
else switch ( cfg->token ) |
{ |
case token_tristate: |
printf( "\n\tif {($CONFIG_MODULES == 0)} then {if {($%s == 2)} then {set %s 1}}\n", |
vartable[cfg->nameindex].name, vartable[cfg->nameindex].name ); |
break; |
case token_define_bool: |
case token_define_tristate: |
if ( ! vartable[get_varnum( cfg->value )].global_written ) |
{ |
vartable[get_varnum( cfg->value )].global_written = 1; |
global( cfg->value ); |
} |
printf( "\tset %s $%s\n", vartable[cfg->nameindex].name, |
cfg->value ); |
break; |
case token_define_hex: |
case token_define_int: |
printf( "\tset %s %s\n", vartable[cfg->nameindex].name, |
cfg->value ); |
break; |
case token_define_string: |
printf( "\tset %s \"%s\"\n", vartable[cfg->nameindex].name, |
cfg->value ); |
break; |
case token_unset: |
printf( "\tset %s 4\n", vartable[cfg->nameindex].name ); |
default: |
break; |
} |
} |
} |
} |
printf( "}\n\n\n" ); |
} |
|
|
/* |
* Generates the end of a menu procedure. |
*/ |
static void end_proc( struct kconfig * scfg, int menu_num ) |
{ |
struct kconfig * cfg; |
|
printf( "\n\n\n" ); |
printf( "\tfocus $w\n" ); |
printf( "\tupdate_active\n" ); |
printf( "\tglobal winx; global winy\n" ); |
if ( menu_first[menu_num]->menu_number != 0 ) |
{ |
printf( "\tif {[winfo exists .menu%d] == 0} then ", |
menu_first[menu_num]->menu_number ); |
printf( "{menu%d .menu%d \"%s\"}\n", |
menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number, |
menu_first[menu_first[menu_num]->menu_number]->label ); |
printf( "\tset winx [expr [winfo x .menu%d]+30]; set winy [expr [winfo y .menu%d]+30]\n", |
menu_first[menu_num]->menu_number, menu_first[menu_num]->menu_number ); |
} |
else |
printf( "\tset winx [expr [winfo x .]+30]; set winy [expr [winfo y .]+30]\n" ); |
printf( "\tif {[winfo exists $w]} then {wm geometry $w +$winx+$winy}\n" ); |
|
/* |
* Now that the whole window is in place, we need to wait for an "update" |
* so we can tell the canvas what its virtual size should be. |
* |
* Unfortunately, this causes some ugly screen-flashing because the whole |
* window is drawn, and then it is immediately resized. It seems |
* unavoidable, though, since "frame" objects won't tell us their size |
* until after an update, and "canvas" objects can't automatically pack |
* around frames. Sigh. |
*/ |
printf( "\tupdate idletasks\n" ); |
printf( "\tif {[winfo exists $w]} then {$w.config.canvas create window 0 0 -anchor nw -window $w.config.f\n\n" ); |
printf( "\t$w.config.canvas configure \\\n" ); |
printf( "\t\t-width [expr [winfo reqwidth $w.config.f] + 1]\\\n" ); |
printf( "\t\t-scrollregion \"-1 -1 [expr [winfo reqwidth $w.config.f] + 1] \\\n" ); |
printf( "\t\t\t [expr [winfo reqheight $w.config.f] + 1]\"\n\n" ); |
|
/* |
* If the whole canvas will fit in 3/4 of the screen height, do it; |
* otherwise, resize to around 1/2 the screen and let us scroll. |
*/ |
printf( "\tset winy [expr [winfo reqh $w] - [winfo reqh $w.config.canvas]]\n" ); |
printf( "\tset scry [expr [winfo screenh $w] / 2]\n" ); |
printf( "\tset maxy [expr [winfo screenh $w] * 3 / 4]\n" ); |
printf( "\tset canvtotal [expr [winfo reqh $w.config.f] + 2]\n" ); |
printf( "\tif [expr $winy + $canvtotal < $maxy] {\n" ); |
printf( "\t\t$w.config.canvas configure -height $canvtotal\n" ); |
printf( "\t} else {\n" ); |
printf( "\t\t$w.config.canvas configure -height [expr $scry - $winy]\n" ); |
printf( "\t\t}\n\t}\n" ); |
|
/* |
* Limit the min/max window size. Height can vary, but not width, |
* because of the limitations of canvas and our laziness. |
*/ |
printf( "\tupdate idletasks\n" ); |
printf( "\tif {[winfo exists $w]} then {\n\twm maxsize $w [winfo width $w] [winfo screenheight $w]\n" ); |
printf( "\twm minsize $w [winfo width $w] 100\n\n" ); |
printf( "\twm deiconify $w\n" ); |
printf( "}\n}\n\n" ); |
|
/* |
* Now we generate the companion procedure for the menu we just |
* generated. This procedure contains all of the code to |
* disable/enable widgets based upon the settings of the other |
* widgets, and will be called first when the window is mapped, |
* and each time one of the buttons in the window are clicked. |
*/ |
printf( "proc update_menu%d {} {\n", menu_num ); |
|
/* |
* Clear all of the booleans that are defined in this menu. |
*/ |
clear_globalflags(); |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
if ( cfg->menu_number == menu_num |
&& cfg->token != token_mainmenu_option |
&& cfg->token != token_choice_item ) |
{ |
if ( cfg->cond != NULL ) |
{ |
int i; |
if ( (cfg->token == token_tristate || cfg->token == token_dep_tristate) |
&& ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) |
{ |
global( "CONFIG_MODULES" ); |
vartable[i].global_written = 1; |
} |
generate_if( cfg, cfg->cond, cfg->menu_number, cfg->menu_line ); |
} |
else |
{ |
if ( cfg->token == token_tristate ) |
{ |
int i; |
if ( ! vartable[cfg->nameindex].global_written ) |
{ |
vartable[cfg->nameindex].global_written = 1; |
printf( "\tglobal %s\n", vartable[cfg->nameindex].name ); |
} |
if ( ! vartable[i = get_varnum( "CONFIG_MODULES" )].global_written ) |
{ |
global( "CONFIG_MODULES" ); |
vartable[i].global_written = 1; |
} |
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", |
menu_num, cfg->menu_line, |
menu_num, cfg->menu_line ); |
} |
} |
} |
else if ( cfg->token == token_mainmenu_option |
&& cfg->menu_number == menu_num |
&& cfg->cond != NULL ) |
{ |
generate_if( cfg, cfg->cond, menu_num, cfg->menu_line ); |
} |
} |
printf("}\n\n\n"); |
|
generate_update_var( scfg, menu_num ); |
} |
|
/* |
* This is the top level function for generating the tk script. |
*/ |
void dump_tk_script( struct kconfig * scfg ) |
{ |
int menu_depth; |
int menu_num [64]; |
int imenu, i; |
int top_level_num = 0; |
struct kconfig * cfg; |
struct kconfig * cfg1 = NULL; |
const char * name = "No Name"; |
|
/* |
* Mark begin and end of each menu so I can omit submenus when walking |
* over a parent menu. |
*/ |
tot_menu_num = 0; |
menu_depth = 0; |
menu_num [0] = 0; |
|
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
switch ( cfg->token ) |
{ |
default: |
break; |
|
case token_mainmenu_name: |
name = cfg->label; |
break; |
|
case token_mainmenu_option: |
if ( ++menu_depth >= 64 ) |
{ fprintf( stderr, "menus too deep\n" ); exit( 1 ); } |
if ( ++tot_menu_num >= 100 ) |
{ fprintf( stderr, "too many menus\n" ); exit( 1 ); } |
menu_num [menu_depth] = tot_menu_num; |
menu_first [tot_menu_num] = cfg; |
menu_last [tot_menu_num] = cfg; |
/* |
* Note, that menu_number is set to the number of parent |
* (upper level) menu. |
*/ |
cfg->menu_number = menu_num[menu_depth - 1]; |
if ( menu_depth == 1 ) |
++top_level_num; |
break; |
|
case token_endmenu: |
menu_last [menu_num [menu_depth]] = cfg; |
/* flatten menus with proper scoping */ |
if ( --menu_depth < 0 ) |
{ fprintf( stderr, "unmatched endmenu\n" ); exit( 1 ); } |
break; |
|
case token_bool: |
case token_choice_header: |
case token_choice_item: |
case token_comment: |
case token_dep_bool: |
case token_dep_tristate: |
case token_dep_mbool: |
case token_hex: |
case token_int: |
case token_string: |
case token_tristate: |
cfg->menu_number = menu_num[menu_depth]; |
if ( menu_depth == 0 ) |
{ fprintf( stderr, "statement not in menu\n" ); exit( 1 ); } |
break; |
|
case token_define_bool: |
case token_define_hex: |
case token_define_int: |
case token_define_string: |
case token_define_tristate: |
case token_unset: |
cfg->menu_number = menu_num[menu_depth]; |
break; |
} |
} |
|
/* |
* Generate menus per column setting. |
* There are: |
* four extra buttons for save/quit/load/store; |
* one blank button |
* add two to round up for division |
*/ |
printf( "set menus_per_column %d\n", (top_level_num + 4 + 1 + 2) / 3 ); |
printf( "set total_menus %d\n\n", tot_menu_num ); |
|
printf( "proc toplevel_menu {num} {\n" ); |
for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) |
{ |
int parent = 1; |
|
if ( menu_first[imenu]->menu_number == 0 ) |
parent = menu_first[imenu]->menu_number; |
else |
printf( "\tif {$num == %d} then {return %d}\n", |
imenu, menu_first[imenu]->menu_number ); |
} |
printf( "\treturn $num\n}\n\n" ); |
|
/* |
* Generate the menus. |
*/ |
printf( "mainmenu_name \"%s\"\n", name ); |
for ( imenu = 1; imenu <= tot_menu_num; ++imenu ) |
{ |
int menu_line = 0; |
int nr_submenu = imenu; |
int menu_name_omitted = 0; |
int opt_count = 0; |
|
clear_globalflags(); |
start_proc( menu_first[imenu]->label, imenu, |
!menu_first[imenu]->menu_number ); |
|
for ( cfg = menu_first[imenu]->next; cfg != NULL && cfg != menu_last[imenu]; cfg = cfg->next ) |
{ |
switch ( cfg->token ) |
{ |
default: |
break; |
|
case token_mainmenu_option: |
while ( menu_first[++nr_submenu]->menu_number > imenu ) |
; |
cfg->menu_line = menu_line++; |
printf( "\tsubmenu $w.config.f %d %d \"%s\" %d\n", |
cfg->menu_number, cfg->menu_line, cfg->label, nr_submenu ); |
cfg = menu_last[nr_submenu]; |
break; |
|
case token_comment: |
if ( !cfg->menu_line && !menu_name_omitted ) |
{ |
cfg->menu_line = -1; |
menu_name_omitted = 1; |
} |
else |
{ |
menu_name_omitted = 1; |
cfg->menu_line = menu_line++; |
printf( "\tcomment $w.config.f %d %d \"%s\"\n", |
cfg->menu_number, cfg->menu_line, cfg->label ); |
} |
break; |
|
case token_bool: |
cfg->menu_line = menu_line++; |
printf( "\tbool $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_choice_header: |
/* |
* I need the first token_choice_item to pick out the right |
* help text from Documentation/Configure.help. |
*/ |
cfg->menu_line = menu_line++; |
printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); |
printf( "\tminimenu $w.config.f %d %d \"%s\" tmpvar_%d %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
-(cfg->nameindex), vartable[cfg->next->nameindex].name ); |
printf( "\tmenu $w.config.f.x%d.x.menu -tearoffcommand \"menutitle \\\"%s\\\"\"\n", |
cfg->menu_line, cfg->label ); |
cfg1 = cfg; |
opt_count = 0; |
break; |
|
case token_choice_item: |
/* note: no menu line; uses choice header menu line */ |
printf( "\t$w.config.f.x%d.x.menu add radiobutton -label \"%s\" -variable tmpvar_%d -value \"%s\" -command \"update_active\"\n", |
cfg1->menu_line, cfg->label, -(cfg1->nameindex), |
cfg->label ); |
opt_count++; |
if ( cfg->next && cfg->next->token != token_choice_item ) { |
/* last option in the menu */ |
printf( "\tmenusplit $w $w.config.f.x%d.x.menu %d\n", |
cfg1->menu_line, opt_count ); |
} |
break; |
|
case token_dep_bool: |
case token_dep_mbool: |
cfg->menu_line = menu_line++; |
printf( "\tdep_bool $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_dep_tristate: |
cfg->menu_line = menu_line++; |
printf( "\tdep_tristate $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_hex: |
cfg->menu_line = menu_line++; |
printf( "\thex $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_int: |
cfg->menu_line = menu_line++; |
printf( "\tint $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_string: |
cfg->menu_line = menu_line++; |
printf( "\tistring $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
|
case token_tristate: |
cfg->menu_line = menu_line++; |
printf( "\ttristate $w.config.f %d %d \"%s\" %s\n", |
cfg->menu_number, cfg->menu_line, cfg->label, |
vartable[cfg->nameindex].name ); |
break; |
} |
} |
|
end_proc( scfg, imenu ); |
} |
|
/* |
* The top level menu also needs an update function. When we update a |
* submenu, we may need to disable one or more of the submenus on |
* the top level menu, and this procedure will ensure that things are |
* correct. |
*/ |
clear_globalflags(); |
printf( "proc update_mainmenu {} {\n" ); |
for ( imenu = 1; imenu <= tot_menu_num; imenu++ ) |
{ |
if ( menu_first[imenu]->cond != NULL && menu_first[imenu]->menu_number == 0 ) |
generate_if( menu_first[imenu], menu_first[imenu]->cond, imenu, -1 ); |
} |
printf( "}\n\n\n" ); |
|
clear_globalflags(); |
/* |
* Generate code to load the default settings into the variables. |
* The script in tail.tk will attempt to load .config, |
* which may override these settings, but that's OK. |
*/ |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
switch ( cfg->token ) |
{ |
default: |
break; |
|
case token_bool: |
case token_choice_item: |
case token_dep_bool: |
case token_dep_tristate: |
case token_dep_mbool: |
case token_tristate: |
if ( ! vartable[cfg->nameindex].global_written ) |
{ |
printf( "set %s 0\n", vartable[cfg->nameindex].name ); |
vartable[cfg->nameindex].global_written = 1; |
} |
break; |
|
case token_choice_header: |
printf( "set tmpvar_%d \"(not set)\"\n", -(cfg->nameindex) ); |
break; |
|
case token_hex: |
case token_int: |
if ( ! vartable[cfg->nameindex].global_written ) |
{ |
printf( "set %s %s\n", vartable[cfg->nameindex].name, cfg->value ? cfg->value : "0" ); |
vartable[cfg->nameindex].global_written = 1; |
} |
break; |
|
case token_string: |
if ( ! vartable[cfg->nameindex].global_written ) |
{ |
printf( "set %s \"%s\"\n", vartable[cfg->nameindex].name, cfg->value ); |
vartable[cfg->nameindex].global_written = 1; |
} |
break; |
} |
} |
|
/* |
* Define to an empty value all other variables (which are never defined) |
*/ |
for ( i = 1; i <= max_varnum; i++ ) |
{ |
if ( ! vartable[i].global_written |
&& strncmp( vartable[i].name, "CONSTANT_", 9 ) ) |
printf( "set %s 4\n", vartable[i].name ); |
} |
|
/* |
* Generate a function to write all of the variables to a file. |
*/ |
printf( "proc writeconfig {file1 file2} {\n" ); |
printf( "\tset cfg [open $file1 w]\n" ); |
printf( "\tset autocfg [open $file2 w]\n" ); |
printf( "\tset notmod 1\n" ); |
printf( "\tset notset 0\n" ); |
printf( "\tputs $cfg \"#\"\n"); |
printf( "\tputs $cfg \"# Automatically generated make config: don't edit\"\n"); |
printf( "\tputs $cfg \"#\"\n" ); |
|
printf( "\tputs $autocfg \"/*\"\n" ); |
printf( "\tputs $autocfg \" * Automatically generated C config: don't edit\"\n" ); |
printf( "\tputs $autocfg \" */\"\n" ); |
printf( "\tputs $autocfg \"#define AUTOCONF_INCLUDED\"\n" ); |
|
clear_globalflags(); |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
switch ( cfg->token ) |
{ |
default: |
break; |
|
case token_bool: |
case token_choice_header: |
case token_comment: |
case token_define_bool: |
case token_define_hex: |
case token_define_int: |
case token_define_string: |
case token_define_tristate: |
case token_dep_bool: |
case token_dep_tristate: |
case token_dep_mbool: |
case token_hex: |
case token_int: |
case token_string: |
case token_tristate: |
generate_writeconfig( cfg ); |
break; |
} |
} |
printf( "\tclose $cfg\n" ); |
printf( "\tclose $autocfg\n" ); |
printf( "}\n\n\n" ); |
|
/* |
* Generate a simple function that updates the master choice |
* variable depending upon what values were loaded from a .config |
* file. |
*/ |
printf( "proc clear_choices { } {\n" ); |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
if ( cfg->token == token_choice_header ) |
{ |
for ( cfg1 = cfg->next; |
cfg1 != NULL && cfg1->token == token_choice_item; |
cfg1 = cfg1->next ) |
{ |
printf( "\tglobal %s; set %s 0\n", |
vartable[cfg1->nameindex].name, |
vartable[cfg1->nameindex].name ); |
} |
} |
} |
printf( "}\n\n\n" ); |
|
printf( "proc update_choices { } {\n" ); |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
if ( cfg->token == token_choice_header ) |
{ |
printf( "\tglobal tmpvar_%d\n", -(cfg->nameindex) ); |
printf("\tset tmpvar_%d \"%s\"\n", -(cfg->nameindex), cfg->value); |
for ( cfg1 = cfg->next; |
cfg1 != NULL && cfg1->token == token_choice_item; |
cfg1 = cfg1->next ) |
{ |
printf( "\tglobal %s\n", vartable[cfg1->nameindex].name ); |
printf( "\tif { $%s == 1 } then { set tmpvar_%d \"%s\" }\n", |
vartable[cfg1->nameindex].name, |
-(cfg->nameindex), cfg1->label ); |
} |
} |
} |
printf( "}\n\n\n" ); |
|
generate_update_var( scfg, 0 ); |
|
/* |
* That's it. We are done. The output of this file will have header.tk |
* prepended and tail.tk appended to create an executable wish script. |
*/ |
} |
/tkparse.c
0,0 → 1,828
/* |
* tkparse.c |
* |
* Eric Youngdale was the original author of xconfig. |
* Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. |
* |
* Parse a config.in file and translate it to a wish script. |
* This task has three parts: |
* |
* tkparse.c tokenize the input |
* tkcond.c transform 'if ...' statements |
* tkgen.c generate output |
* |
* Change History |
* |
* 7 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
* - Teach dep_tristate about a few literals, such as: |
* dep_tristate 'foo' CONFIG_FOO m |
* Also have it print an error message and exit on some parse failures. |
* |
* 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
* - Don't fclose stdin. Thanks to Tony Hoyle for nailing this one. |
* |
* 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. |
* |
* 23 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
* - Remove bug-compatible code. |
* |
* 07 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl> |
* - Submenus implemented, |
* - plenty of option updating/displaying fixes, |
* - dep_bool, define_hex, define_int, define_string, define_tristate and |
* undef implemented, |
* - dep_tristate fixed to support multiple dependencies, |
* - handling of variables with an empty value implemented, |
* - value checking for int and hex fields, |
* - more checking during condition parsing; choice variables are treated as |
* all others now, |
* |
* TO DO: |
* - xconfig is at the end of its life cycle. Contact <mec@shout.net> if |
* you are interested in working on the replacement. |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
#include "tkparse.h" |
|
static struct kconfig * config_list = NULL; |
static struct kconfig * config_last = NULL; |
static const char * current_file = "<unknown file>"; |
static int lineno = 0; |
|
static void do_source( const char * ); |
|
#undef strcmp |
int my_strcmp( const char * s1, const char * s2 ) { return strcmp( s1, s2 ); } |
#define strcmp my_strcmp |
|
/* |
* Report a syntax error. |
*/ |
static void syntax_error( const char * msg ) |
{ |
fprintf( stderr, "%s: %d: %s\n", current_file, lineno, msg ); |
exit( 1 ); |
} |
|
|
|
/* |
* Find index of a specific variable in the symbol table. |
* Create a new entry if it does not exist yet. |
*/ |
struct variable *vartable; |
int max_varnum = 0; |
static int vartable_size = 0; |
|
int get_varnum( char * name ) |
{ |
int i; |
|
for ( i = 1; i <= max_varnum; i++ ) |
if ( strcmp( vartable[i].name, name ) == 0 ) |
return i; |
while (max_varnum+1 >= vartable_size) { |
vartable = realloc(vartable, (vartable_size += 1000)*sizeof(*vartable)); |
if (!vartable) { |
fprintf(stderr, "tkparse realloc vartable failed\n"); |
exit(1); |
} |
} |
vartable[++max_varnum].name = malloc( strlen( name )+1 ); |
strcpy( vartable[max_varnum].name, name ); |
return max_varnum; |
} |
|
|
|
/* |
* Get a string. |
*/ |
static const char * get_string( const char * pnt, char ** label ) |
{ |
const char * word; |
|
word = pnt; |
for ( ; ; ) |
{ |
if ( *pnt == '\0' || *pnt == ' ' || *pnt == '\t' ) |
break; |
pnt++; |
} |
|
*label = malloc( pnt - word + 1 ); |
memcpy( *label, word, pnt - word ); |
(*label)[pnt - word] = '\0'; |
|
if ( *pnt != '\0' ) |
pnt++; |
return pnt; |
} |
|
|
|
/* |
* Get a quoted string. |
* Insert a '\' before any characters that need quoting. |
*/ |
static const char * get_qstring( const char * pnt, char ** label ) |
{ |
char quote_char; |
char newlabel [2048]; |
char * pnt1; |
|
/* advance to the open quote */ |
for ( ; ; ) |
{ |
if ( *pnt == '\0' ) |
return pnt; |
quote_char = *pnt++; |
if ( quote_char == '"' || quote_char == '\'' ) |
break; |
} |
|
/* copy into an intermediate buffer */ |
pnt1 = newlabel; |
for ( ; ; ) |
{ |
if ( *pnt == '\0' ) |
syntax_error( "unterminated quoted string" ); |
if ( *pnt == quote_char && pnt[-1] != '\\' ) |
break; |
|
/* copy the character, quoting if needed */ |
if ( *pnt == '"' || *pnt == '\'' || *pnt == '[' || *pnt == ']' ) |
*pnt1++ = '\\'; |
*pnt1++ = *pnt++; |
} |
|
/* copy the label into a permanent location */ |
*pnt1++ = '\0'; |
*label = (char *) malloc( pnt1 - newlabel ); |
memcpy( *label, newlabel, pnt1 - newlabel ); |
|
/* skip over last quote and next whitespace */ |
pnt++; |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
return pnt; |
} |
|
|
|
/* |
* Get a quoted or unquoted string. It is recognized by the first |
* non-white character. '"' and '"' are not allowed inside the string. |
*/ |
static const char * get_qnqstring( const char * pnt, char ** label ) |
{ |
char quote_char; |
|
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
|
if ( *pnt == '\0' ) |
return pnt; |
quote_char = *pnt; |
if ( quote_char == '"' || quote_char == '\'' ) |
return get_qstring( pnt, label ); |
else |
return get_string( pnt, label ); |
} |
|
|
|
/* |
* Tokenize an 'if' statement condition. |
*/ |
static struct condition * tokenize_if( const char * pnt ) |
{ |
struct condition * list; |
struct condition * last; |
struct condition * prev; |
|
/* eat the open bracket */ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
if ( *pnt != '[' ) |
syntax_error( "bad 'if' condition" ); |
pnt++; |
|
list = last = NULL; |
for ( ; ; ) |
{ |
struct condition * cond; |
|
/* advance to the next token */ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
if ( *pnt == '\0' ) |
syntax_error( "unterminated 'if' condition" ); |
if ( *pnt == ']' ) |
return list; |
|
/* allocate a new token */ |
cond = malloc( sizeof(*cond) ); |
memset( cond, 0, sizeof(*cond) ); |
if ( last == NULL ) |
{ list = last = cond; prev = NULL; } |
else |
{ prev = last; last->next = cond; last = cond; } |
|
/* determine the token value */ |
if ( *pnt == '-' && pnt[1] == 'a' ) |
{ |
if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) |
syntax_error( "incorrect argument" ); |
cond->op = op_and; pnt += 2; continue; |
} |
|
if ( *pnt == '-' && pnt[1] == 'o' ) |
{ |
if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) |
syntax_error( "incorrect argument" ); |
cond->op = op_or; pnt += 2; continue; |
} |
|
if ( *pnt == '!' && pnt[1] == '=' ) |
{ |
if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) |
syntax_error( "incorrect argument" ); |
cond->op = op_neq; pnt += 2; continue; |
} |
|
if ( *pnt == '=' ) |
{ |
if ( ! prev || ( prev->op != op_variable && prev->op != op_constant ) ) |
syntax_error( "incorrect argument" ); |
cond->op = op_eq; pnt += 1; continue; |
} |
|
if ( *pnt == '!' ) |
{ |
if ( prev && ( prev->op != op_and && prev->op != op_or |
&& prev->op != op_bang ) ) |
syntax_error( "incorrect argument" ); |
cond->op = op_bang; pnt += 1; continue; |
} |
|
if ( *pnt == '"' ) |
{ |
const char * word; |
|
if ( prev && ( prev->op == op_variable || prev->op == op_constant ) ) |
syntax_error( "incorrect argument" ); |
/* advance to the word */ |
pnt++; |
if ( *pnt == '$' ) |
{ cond->op = op_variable; pnt++; } |
else |
{ cond->op = op_constant; } |
|
/* find the end of the word */ |
word = pnt; |
for ( ; ; ) |
{ |
if ( *pnt == '\0' ) |
syntax_error( "unterminated double quote" ); |
if ( *pnt == '"' ) |
break; |
pnt++; |
} |
|
/* store a copy of this word */ |
{ |
char * str = malloc( pnt - word + 1 ); |
memcpy( str, word, pnt - word ); |
str [pnt - word] = '\0'; |
if ( cond->op == op_variable ) |
{ |
cond->nameindex = get_varnum( str ); |
free( str ); |
} |
else /* op_constant */ |
{ |
cond->str = str; |
} |
} |
|
pnt++; |
continue; |
} |
|
/* unknown token */ |
syntax_error( "bad if condition" ); |
} |
} |
|
|
|
/* |
* Tokenize a choice list. Choices appear as pairs of strings; |
* note that I am parsing *inside* the double quotes. Ugh. |
*/ |
static const char * tokenize_choices( struct kconfig * cfg_choose, |
const char * pnt ) |
{ |
int default_checked = 0; |
for ( ; ; ) |
{ |
struct kconfig * cfg; |
char * buffer = malloc( 64 ); |
|
/* skip whitespace */ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
if ( *pnt == '\0' ) |
return pnt; |
|
/* allocate a new kconfig line */ |
cfg = malloc( sizeof(*cfg) ); |
memset( cfg, 0, sizeof(*cfg) ); |
if ( config_last == NULL ) |
{ config_last = config_list = cfg; } |
else |
{ config_last->next = cfg; config_last = cfg; } |
|
/* fill out the line */ |
cfg->token = token_choice_item; |
cfg->cfg_parent = cfg_choose; |
pnt = get_string( pnt, &cfg->label ); |
if ( ! default_checked && |
! strncmp( cfg->label, cfg_choose->value, strlen( cfg_choose->value ) ) ) |
{ |
default_checked = 1; |
free( cfg_choose->value ); |
cfg_choose->value = cfg->label; |
} |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
} |
if ( ! default_checked ) |
syntax_error( "bad 'choice' default value" ); |
return pnt; |
} |
|
|
|
/* |
* Tokenize one line. |
*/ |
static void tokenize_line( const char * pnt ) |
{ |
static struct kconfig * last_menuoption = NULL; |
enum e_token token; |
struct kconfig * cfg; |
struct dependency ** dep_ptr; |
char * buffer = malloc( 64 ); |
|
/* skip white space */ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
|
/* |
* categorize the next token |
*/ |
|
#define match_token(t, s) \ |
if (strncmp(pnt, s, strlen(s)) == 0) { token = t; pnt += strlen(s); break; } |
|
token = token_UNKNOWN; |
switch ( *pnt ) |
{ |
default: |
break; |
|
case '#': |
case '\0': |
return; |
|
case 'b': |
match_token( token_bool, "bool" ); |
break; |
|
case 'c': |
match_token( token_choice_header, "choice" ); |
match_token( token_comment, "comment" ); |
break; |
|
case 'd': |
match_token( token_define_bool, "define_bool" ); |
match_token( token_define_hex, "define_hex" ); |
match_token( token_define_int, "define_int" ); |
match_token( token_define_string, "define_string" ); |
match_token( token_define_tristate, "define_tristate" ); |
match_token( token_dep_bool, "dep_bool" ); |
match_token( token_dep_mbool, "dep_mbool" ); |
match_token( token_dep_tristate, "dep_tristate" ); |
break; |
|
case 'e': |
match_token( token_else, "else" ); |
match_token( token_endmenu, "endmenu" ); |
break; |
|
case 'f': |
match_token( token_fi, "fi" ); |
break; |
|
case 'h': |
match_token( token_hex, "hex" ); |
break; |
|
case 'i': |
match_token( token_if, "if" ); |
match_token( token_int, "int" ); |
break; |
|
case 'm': |
match_token( token_mainmenu_name, "mainmenu_name" ); |
match_token( token_mainmenu_option, "mainmenu_option" ); |
break; |
|
case 's': |
match_token( token_source, "source" ); |
match_token( token_string, "string" ); |
break; |
|
case 't': |
match_token( token_then, "then" ); |
match_token( token_tristate, "tristate" ); |
break; |
|
case 'u': |
match_token( token_unset, "unset" ); |
break; |
} |
|
#undef match_token |
|
if ( token == token_source ) |
{ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
do_source( pnt ); |
return; |
} |
|
if ( token == token_then ) |
{ |
if ( config_last != NULL && config_last->token == token_if ) |
return; |
syntax_error( "bogus 'then'" ); |
} |
|
#if 0 |
if ( token == token_unset ) |
{ |
fprintf( stderr, "Ignoring 'unset' command\n" ); |
return; |
} |
#endif |
|
if ( token == token_UNKNOWN ) |
syntax_error( "unknown command" ); |
|
/* |
* Allocate an item. |
*/ |
cfg = malloc( sizeof(*cfg) ); |
memset( cfg, 0, sizeof(*cfg) ); |
if ( config_last == NULL ) |
{ config_last = config_list = cfg; } |
else |
{ config_last->next = cfg; config_last = cfg; } |
|
/* |
* Tokenize the arguments. |
*/ |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
|
cfg->token = token; |
switch ( token ) |
{ |
default: |
syntax_error( "unknown token" ); |
|
case token_bool: |
case token_tristate: |
pnt = get_qstring ( pnt, &cfg->label ); |
pnt = get_string ( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
break; |
|
case token_choice_header: |
{ |
static int choose_number = 0; |
char * choice_list; |
|
pnt = get_qstring ( pnt, &cfg->label ); |
pnt = get_qstring ( pnt, &choice_list ); |
pnt = get_string ( pnt, &cfg->value ); |
cfg->nameindex = -(choose_number++); |
tokenize_choices( cfg, choice_list ); |
free( choice_list ); |
} |
break; |
|
case token_comment: |
pnt = get_qstring(pnt, &cfg->label); |
if ( last_menuoption != NULL ) |
{ |
pnt = get_qstring(pnt, &cfg->label); |
if (cfg->label == NULL) |
syntax_error( "missing comment text" ); |
last_menuoption->label = cfg->label; |
last_menuoption = NULL; |
} |
break; |
|
case token_define_bool: |
case token_define_tristate: |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' |
|| pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) |
&& ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) |
{ |
if ( *pnt == 'n' || *pnt == 'N' ) cfg->value = strdup( "CONSTANT_N" ); |
else if ( *pnt == 'y' || *pnt == 'Y' ) cfg->value = strdup( "CONSTANT_Y" ); |
else if ( *pnt == 'm' || *pnt == 'M' ) cfg->value = strdup( "CONSTANT_M" ); |
} |
else if ( *pnt == '$' ) |
{ |
pnt++; |
pnt = get_string( pnt, &cfg->value ); |
} |
else |
{ |
syntax_error( "unknown define_bool value" ); |
} |
get_varnum( cfg->value ); |
break; |
|
case token_define_hex: |
case token_define_int: |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
pnt = get_string( pnt, &cfg->value ); |
break; |
|
case token_define_string: |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
pnt = get_qnqstring( pnt, &cfg->value ); |
if (cfg->value == NULL) |
syntax_error( "missing value" ); |
break; |
|
case token_dep_bool: |
case token_dep_mbool: |
case token_dep_tristate: |
pnt = get_qstring ( pnt, &cfg->label ); |
pnt = get_string ( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
|
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
|
dep_ptr = &(cfg->depend); |
|
do { |
*dep_ptr = (struct dependency *) malloc( sizeof( struct dependency ) ); |
(*dep_ptr)->next = NULL; |
|
if ( ( pnt[0] == 'Y' || pnt[0] == 'M' || pnt[0] == 'N' |
|| pnt[0] == 'y' || pnt[0] == 'm' || pnt[0] == 'n' ) |
&& ( pnt[1] == '\0' || pnt[1] == ' ' || pnt[1] == '\t' ) ) |
{ |
/* dep_tristate 'foo' CONFIG_FOO m */ |
if ( pnt[0] == 'Y' || pnt[0] == 'y' ) |
(*dep_ptr)->name = strdup( "CONSTANT_Y" ); |
else if ( pnt[0] == 'N' || pnt[0] == 'n' ) |
(*dep_ptr)->name = strdup( "CONSTANT_N" ); |
else |
(*dep_ptr)->name = strdup( "CONSTANT_M" ); |
pnt++; |
get_varnum( (*dep_ptr)->name ); |
} |
else if ( *pnt == '$' ) |
{ |
pnt++; |
pnt = get_string( pnt, &(*dep_ptr)->name ); |
get_varnum( (*dep_ptr)->name ); |
} |
else |
{ |
syntax_error( "can't handle dep_bool/dep_mbool/dep_tristate condition" ); |
} |
dep_ptr = &(*dep_ptr)->next; |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
} while ( *pnt ); |
|
/* |
* Create a conditional for this object's dependencies. |
*/ |
{ |
char fake_if [1024]; |
struct dependency * dep; |
struct condition ** cond_ptr; |
int first = 1; |
|
cond_ptr = &(cfg->cond); |
for ( dep = cfg->depend; dep; dep = dep->next ) |
{ |
if ( token == token_dep_tristate |
&& ! strcmp( dep->name, "CONSTANT_M" ) ) |
{ |
continue; |
} |
if ( first ) |
{ |
first = 0; |
} |
else |
{ |
*cond_ptr = malloc( sizeof(struct condition) ); |
memset( *cond_ptr, 0, sizeof(struct condition) ); |
(*cond_ptr)->op = op_and; |
cond_ptr = &(*cond_ptr)->next; |
} |
*cond_ptr = malloc( sizeof(struct condition) ); |
memset( *cond_ptr, 0, sizeof(struct condition) ); |
(*cond_ptr)->op = op_lparen; |
if ( token == token_dep_bool ) |
sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"\" ]; then", |
dep->name, dep->name ); |
else |
sprintf( fake_if, "[ \"$%s\" = \"y\" -o \"$%s\" = \"m\" -o \"$%s\" = \"\" ]; then", |
dep->name, dep->name, dep->name ); |
(*cond_ptr)->next = tokenize_if( fake_if ); |
while ( *cond_ptr ) |
cond_ptr = &(*cond_ptr)->next; |
*cond_ptr = malloc( sizeof(struct condition) ); |
memset( *cond_ptr, 0, sizeof(struct condition) ); |
(*cond_ptr)->op = op_rparen; |
cond_ptr = &(*cond_ptr)->next; |
} |
} |
break; |
|
case token_else: |
case token_endmenu: |
case token_fi: |
break; |
|
case token_hex: |
case token_int: |
pnt = get_qstring ( pnt, &cfg->label ); |
pnt = get_string ( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
pnt = get_string ( pnt, &cfg->value ); |
break; |
|
case token_string: |
pnt = get_qstring ( pnt, &cfg->label ); |
pnt = get_string ( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
pnt = get_qnqstring ( pnt, &cfg->value ); |
if (cfg->value == NULL) |
syntax_error( "missing initial value" ); |
break; |
|
case token_if: |
cfg->cond = tokenize_if( pnt ); |
break; |
|
case token_mainmenu_name: |
pnt = get_qstring( pnt, &cfg->label ); |
break; |
|
case token_mainmenu_option: |
if ( strncmp( pnt, "next_comment", 12 ) == 0 ) |
last_menuoption = cfg; |
else |
pnt = get_qstring( pnt, &cfg->label ); |
break; |
|
case token_unset: |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
while (*pnt) |
{ |
cfg->next = (struct kconfig *) malloc( sizeof(struct kconfig) ); |
memset( cfg->next, 0, sizeof(struct kconfig) ); |
cfg = cfg->next; |
cfg->token = token_unset; |
pnt = get_string( pnt, &buffer ); |
cfg->nameindex = get_varnum( buffer ); |
while ( *pnt == ' ' || *pnt == '\t' ) |
pnt++; |
} |
break; |
} |
return; |
} |
|
|
|
/* |
* Implement the "source" command. |
*/ |
static void do_source( const char * filename ) |
{ |
char buffer [2048]; |
FILE * infile; |
const char * old_file; |
int old_lineno; |
int offset; |
|
/* open the file */ |
if ( strcmp( filename, "-" ) == 0 ) |
infile = stdin; |
else |
infile = fopen( filename, "r" ); |
|
/* if that failed, try ../filename */ |
if ( infile == NULL ) |
{ |
sprintf( buffer, "../%s", filename ); |
infile = fopen( buffer, "r" ); |
} |
|
if ( infile == NULL ) |
{ |
sprintf( buffer, "unable to open %s", filename ); |
syntax_error( buffer ); |
} |
|
/* push the new file name and line number */ |
old_file = current_file; |
old_lineno = lineno; |
current_file = filename; |
lineno = 0; |
|
/* read and process lines */ |
for ( offset = 0; ; ) |
{ |
char * pnt; |
|
/* read a line */ |
fgets( buffer + offset, sizeof(buffer) - offset, infile ); |
if ( feof( infile ) ) |
break; |
lineno++; |
|
/* strip the trailing return character */ |
pnt = buffer + strlen(buffer) - 1; |
if ( *pnt == '\n' ) |
*pnt-- = '\0'; |
|
/* eat \ NL pairs */ |
if ( *pnt == '\\' ) |
{ |
offset = pnt - buffer; |
continue; |
} |
|
/* tokenize this line */ |
tokenize_line( buffer ); |
offset = 0; |
} |
|
/* that's all, folks */ |
if ( infile != stdin ) |
fclose( infile ); |
current_file = old_file; |
lineno = old_lineno; |
return; |
} |
|
|
|
/* |
* Main program. |
*/ |
int main( int argc, const char * argv [] ) |
{ |
do_source ( "-" ); |
fix_conditionals ( config_list ); |
dump_tk_script ( config_list ); |
free(vartable); |
return 0; |
} |
/Menuconfig
0,0 → 1,1474
#! /bin/sh |
# |
# This script is used to configure the linux kernel. |
# |
# It was inspired by a desire to not have to hit <enter> 9 million times |
# or startup the X server just to change a single kernel parameter. |
# |
# This script attempts to parse the configuration files, which are |
# scattered throughout the kernel source tree, and creates a temporary |
# set of mini scripts which are in turn used to create nested menus and |
# radiolists. |
# |
# It uses a very modified/mutilated version of the "dialog" utility |
# written by Savio Lam (lam836@cs.cuhk.hk). Savio is not responsible |
# for this script or the version of dialog used by this script. |
# Please do not contact him with questions. The official version of |
# dialog is available at sunsite.unc.edu or a sunsite mirror. |
# |
# Portions of this script were borrowed from the original Configure |
# script. |
# |
# William Roadcap was the original author of Menuconfig. |
# Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. |
# |
# 070497 Bernhard Kaindl (bkaindl@netway.at) - get default values for |
# new bool, tristate and dep_tristate parameters from the defconfig file. |
# new configuration parameters are marked with '(NEW)' as in make config. |
# |
# 180697 Bernhard Kaindl (bkaindl@netway.at) - added the needed support |
# for string options. They are handled like the int and hex options. |
# |
# 081297 Pavel Machek (pavel@atrey.karlin.mff.cuni.cz) - better error |
# handling |
# |
# 131197 Michael Chastain (mec@shout.net) - output all lines for a |
# choice list, not just the selected one. This makes the output |
# the same as Configure output, which is important for smart config |
# dependencies. |
# |
# 101297 Michael Chastain (mec@shout.net) - remove sound driver cruft. |
# |
# 221297 Michael Chastain (mec@shout.net) - make define_bool actually |
# define its arguments so that later tests on them work right. |
# |
# 160198 Michael Chastain (mec@shout.net) - fix bug with 'c' command |
# (complement existing value) when used on virgin uninitialized variables. |
# |
# 090398 Axel Boldt (boldt@math.ucsb.edu) - allow for empty lines in help |
# texts. |
# |
# 12 Dec 1998, Michael Elizabeth Chastain (mec@shout.net) |
# Remove a /tmp security hole in get_def (also makes it faster). |
# Give uninitialized variables canonical values rather than null value. |
# Change a lot of places to call set_x_info uniformly. |
# Take out message about preparing version (old sound driver cruft). |
# |
# 13 Dec 1998, Riley H Williams <Riley@Williams.Name> |
# When an error occurs, actually display the error message as well as |
# our comments thereon. |
# |
# 31 Dec 1998, Michael Elizabeth Chastain (mec@shout.net) |
# Fix mod_bool to honor $CONFIG_MODULES. |
# Fix dep_tristate to call define_bool when dependency is "n". |
# |
# 02 January 1999, Michael Elizabeth Chastain (mec@shout.net) |
# Blow away lxdialog.scrltmp on entry to activate_menu. This protects |
# against people who use commands like ' ' to select menus. |
# |
# 24 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
# - Improve the exit message (Jeff Ronne). |
# |
# 06 July 1999, Andrzej M. Krzysztofowicz, <ankry@mif.pg.gda.pl> |
# - Support for multiple conditions in dep_tristate(). |
# - Implemented new functions: define_tristate(), define_int(), define_hex(), |
# define_string(), dep_bool(). |
# |
# 12 November 2001, Keith Owens <kaos@ocs.com.au> |
# Escape double quotes on eval so the quotes are still there on the second |
# evaluation, required to handle strings with special characters. |
# |
|
|
# |
# Change this to TRUE if you prefer all kernel options listed |
# in a single menu rather than the standard menu hierarchy. |
# |
single_menu_mode= |
|
# |
# Make sure we're really running bash. |
# |
[ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; } |
|
# |
# Cache function definitions, turn off posix compliance |
# |
set -h +o posix |
|
|
|
# Given a configuration variable, set the global variable $x to its value, |
# and the global variable $info to the string " (NEW)" if this is a new |
# variable. |
# |
# This function looks for: (1) the current value, or (2) the default value |
# from the arch-dependent defconfig file, or (3) a default passed by the caller. |
|
function set_x_info () { |
eval x=\$$1 |
if [ -z "$x" ]; then |
eval `sed -n -e 's/# \(.*\) is not set.*/\1=n/' -e "/^$1=/p" arch/$ARCH/defconfig` |
eval x=\${$1:-\"$2\"} |
eval $1=$x |
eval INFO_$1="' (NEW)'" |
fi |
eval info=\"\$INFO_$1\" |
} |
|
# |
# Load the functions used by the config.in files. |
# |
# I do this because these functions must be redefined depending |
# on whether they are being called for interactive use or for |
# saving a configuration to a file. |
# |
# Thank the heavens bash supports nesting function definitions. |
# |
load_functions () { |
|
# |
# Additional comments |
# |
function comment () { |
comment_ctr=$[ comment_ctr + 1 ] |
echo -ne "': $comment_ctr' '--- $1' " >>MCmenu |
} |
|
# |
# Define a boolean to a specific value. |
# |
function define_bool () { |
eval $1=$2 |
} |
|
function define_tristate () { |
eval $1=$2 |
} |
|
function define_hex () { |
eval $1=$2 |
} |
|
function define_int () { |
eval $1=$2 |
} |
|
function define_string () { |
eval $1=\"$2\" |
} |
|
# |
# Create a boolean (Yes/No) function for our current menu |
# which calls our local bool function. |
# |
function bool () { |
set_x_info "$2" "n" |
|
case $x in |
y|m) flag="*" ;; |
n) flag=" " ;; |
esac |
|
echo -ne "'$2' '[$flag] $1$info' " >>MCmenu |
|
echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists |
} |
|
# |
# Create a tristate (Yes/No/Module) radiolist function |
# which calls our local tristate function. |
# |
# Collapses to a boolean (Yes/No) if module support is disabled. |
# |
function tristate () { |
if [ "$CONFIG_MODULES" != "y" ] |
then |
bool "$1" "$2" |
else |
set_x_info "$2" "n" |
|
case $x in |
y) flag="*" ;; |
m) flag="M" ;; |
*) flag=" " ;; |
esac |
|
echo -ne "'$2' '<$flag> $1$info' " >>MCmenu |
|
echo -e " |
function $2 () { l_tristate '$2' \"\$1\" ;}" >>MCradiolists |
fi |
} |
|
# |
# Create a tristate radiolist function which is dependent on |
# another kernel configuration option. |
# |
# Quote from the original configure script: |
# |
# If the option we depend upon is a module, |
# then the only allowable options are M or N. If Y, then |
# this is a normal tristate. This is used in cases where modules |
# are nested, and one module requires the presence of something |
# else in the kernel. |
# |
function dep_tristate () { |
ques="$1" |
var="$2" |
dep=y |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y ]; then |
shift |
elif [ "$1" = m ]; then |
dep=m |
shift |
else |
dep=n |
shift $# |
fi |
done |
if [ "$dep" = y ]; then |
tristate "$ques" "$var" |
elif [ "$dep" = m ]; then |
mod_bool "$ques" "$var" |
else |
define_tristate "$var" n |
fi |
} |
|
# |
# Same as above, but now only Y and N are allowed as dependency |
# (i.e. third and next arguments). |
# |
function dep_bool () { |
ques="$1" |
var="$2" |
dep=y |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y ]; then |
shift |
else |
dep=n |
shift $# |
fi |
done |
if [ "$dep" = y ]; then |
bool "$ques" "$var" |
else |
define_bool "$var" n |
fi |
} |
|
function dep_mbool () { |
ques="$1" |
var="$2" |
dep=y |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y -o "$1" = m ]; then |
shift |
else |
dep=n |
shift $# |
fi |
done |
if [ "$dep" = y ]; then |
bool "$ques" "$var" |
else |
define_bool "$var" n |
fi |
} |
|
# |
# Add a menu item which will call our local int function. |
# |
function int () { |
set_x_info "$2" "$3" |
|
echo -ne "'$2' '($x) $1$info' " >>MCmenu |
|
echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
} |
|
# |
# Add a menu item which will call our local hex function. |
# |
function hex () { |
set_x_info "$2" "$3" |
x=${x##*[x,X]} |
|
echo -ne "'$2' '($x) $1$info' " >>MCmenu |
|
echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
} |
|
# |
# Add a menu item which will call our local string function. |
# |
function string () { |
set_x_info "$2" "$3" |
|
echo -ne "'$2' ' $1: \"$x\"$info' " >>MCmenu |
|
echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists |
} |
|
# |
# Add a menu item which will call our local One-of-Many choice list. |
# |
function choice () { |
# |
# Need to remember params cause they're gonna get reset. |
# |
title=$1 |
choices=$2 |
default=$3 |
current= |
|
# |
# Find out if one of the choices is already set. |
# If it's not then make it the default. |
# |
set -- $choices |
firstchoice=$2 |
|
while [ -n "$2" ] |
do |
if eval [ \"_\$$2\" = \"_y\" ] |
then |
current=$1 |
break |
fi |
shift ; shift |
done |
|
: ${current:=$default} |
|
echo -ne "'$firstchoice' '($current) $title' " >>MCmenu |
|
echo -e " |
function $firstchoice () \ |
{ l_choice '$title' \"$choices\" \"$current\" ;}" >>MCradiolists |
} |
|
} # END load_functions() |
|
|
|
|
|
# |
# Extract available help for an option from Configure.help |
# and send it to standard output. |
# |
# Most of this function was borrowed from the original kernel |
# Configure script. |
# |
function extract_help () { |
if [ -f Documentation/Configure.help ] |
then |
#first escape regexp special characters in the argument: |
var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g') |
#now pick out the right help text: |
text=$(sed -n "/^$var[ ]*\$/,\${ |
/^$var[ ]*\$/c\\ |
${var}:\\ |
|
/^#/b |
/^[^ ]/q |
s/^ // |
/<file:\\([^>]*\\)>/s//\\1/g |
p |
}" Documentation/Configure.help) |
|
if [ -z "$text" ] |
then |
echo "There is no help available for this kernel option." |
return 1 |
else |
echo "$text" |
fi |
else |
echo "There is no help available for this kernel option." |
return 1 |
fi |
} |
|
# |
# Activate a help dialog. |
# |
function help () { |
if extract_help $1 >help.out |
then |
$DIALOG --backtitle "$backtitle" --title "$2"\ |
--textbox help.out $ROWS $COLS |
else |
$DIALOG --backtitle "$backtitle" \ |
--textbox help.out $ROWS $COLS |
fi |
rm -f help.out |
} |
|
# |
# Show the README file. |
# |
function show_readme () { |
$DIALOG --backtitle "$backtitle" \ |
--textbox scripts/README.Menuconfig $ROWS $COLS |
} |
|
# |
# Begin building the dialog menu command and Initialize the |
# Radiolist function file. |
# |
function menu_name () { |
echo -ne "$DIALOG --title '$1'\ |
--backtitle '$backtitle' \ |
--menu '$menu_instructions' \ |
$ROWS $COLS $((ROWS-10)) \ |
'$default' " >MCmenu |
>MCradiolists |
} |
|
# |
# Add a submenu option to the menu currently under construction. |
# |
function submenu () { |
echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu |
} |
|
# |
# Handle a boolean (Yes/No) option. |
# |
function l_bool () { |
if [ -n "$2" ] |
then |
case "$2" in |
y|m) eval $1=y ;; |
c) eval x=\$$1 |
case $x in |
y) eval $1=n ;; |
n) eval $1=y ;; |
*) eval $1=y ;; |
esac ;; |
*) eval $1=n ;; |
esac |
else |
echo -ne "\007" |
fi |
} |
|
# |
# Same as bool() except options are (Module/No) |
# |
function mod_bool () { |
if [ "$CONFIG_MODULES" != "y" ]; then |
define_bool "$2" "n" |
else |
set_x_info "$2" "n" |
|
case $x in |
y|m) flag='M' ;; |
*) flag=' ' ;; |
esac |
|
echo -ne "'$2' '<$flag> $1$info' " >>MCmenu |
|
echo -e "function $2 () { l_mod_bool '$2' \"\$1\" ;}" >>MCradiolists |
fi |
} |
|
# |
# Same as l_bool() except options are (Module/No) |
# |
function l_mod_bool() { |
if [ -n "$2" ] |
then |
case "$2" in |
y) echo -en "\007" |
${DIALOG} --backtitle "$backtitle" \ |
--infobox "\ |
This feature depends on another which has been configured as a module. \ |
As a result, this feature will be built as a module." 4 70 |
sleep 5 |
eval $1=m ;; |
m) eval $1=m ;; |
c) eval x=\$$1 |
case $x in |
m) eval $1=n ;; |
n) eval $1=m ;; |
*) eval $1=m ;; |
esac ;; |
*) eval $1=n ;; |
esac |
else |
echo -ne "\007" |
fi |
} |
|
# |
# Handle a tristate (Yes/No/Module) option. |
# |
function l_tristate () { |
if [ -n "$2" ] |
then |
eval x=\$$1 |
|
case "$2" in |
y) eval $1=y ;; |
m) eval $1=m ;; |
c) eval x=\$$1 |
case $x in |
y) eval $1=n ;; |
n) eval $1=m ;; |
m) eval $1=y ;; |
*) eval $1=y ;; |
esac ;; |
*) eval $1=n ;; |
esac |
else |
echo -ne "\007" |
fi |
} |
|
# |
# Create a dialog for entering an integer into a kernel option. |
# |
function l_int () { |
while true |
do |
if $DIALOG --title "$1" \ |
--backtitle "$backtitle" \ |
--inputbox "$inputbox_instructions_int" \ |
10 75 "$4" 2>MCdialog.out |
then |
answer="`cat MCdialog.out`" |
answer="${answer:-$3}" |
|
# Semantics of + and ? in GNU expr changed, so |
# we avoid them: |
if expr "$answer" : '0$' '|' "$answer" : '[1-9][0-9]*$' '|' "$answer" : '-[1-9][0-9]*$' >/dev/null |
then |
eval $2=\"$answer\" |
else |
eval $2=\"$3\" |
echo -en "\007" |
${DIALOG} --backtitle "$backtitle" \ |
--infobox "You have made an invalid entry." 3 43 |
sleep 2 |
fi |
|
break |
fi |
|
help "$2" "$1" |
done |
} |
|
# |
# Create a dialog for entering a hexadecimal into a kernel option. |
# |
function l_hex () { |
while true |
do |
if $DIALOG --title "$1" \ |
--backtitle "$backtitle" \ |
--inputbox "$inputbox_instructions_hex" \ |
10 75 "$4" 2>MCdialog.out |
then |
answer="`cat MCdialog.out`" |
answer="${answer:-$3}" |
answer="${answer##*[x,X]}" |
|
if expr "$answer" : '[0-9a-fA-F][0-9a-fA-F]*$' >/dev/null |
then |
eval $2=\"$answer\" |
else |
eval $2=\"$3\" |
echo -en "\007" |
${DIALOG} --backtitle "$backtitle" \ |
--infobox "You have made an invalid entry." 3 43 |
sleep 2 |
fi |
|
break |
fi |
|
help "$2" "$1" |
done |
} |
|
# |
# Create a dialog for entering a string into a kernel option. |
# |
function l_string () { |
while true |
do |
if $DIALOG --title "$1" \ |
--backtitle "$backtitle" \ |
--inputbox "$inputbox_instructions_string" \ |
10 75 "$4" 2>MCdialog.out |
then |
answer="`cat MCdialog.out`" |
answer="${answer:-$3}" |
|
# |
# Someone may add a nice check for the entered |
# string here... |
# |
eval $2=\"$answer\" |
|
break |
fi |
|
help "$2" "$1" |
done |
} |
|
|
# |
# Handle a one-of-many choice list. |
# |
function l_choice () { |
# |
# Need to remember params cause they're gonna get reset. |
# |
title="$1" |
choices="$2" |
current="$3" |
chosen= |
|
# |
# Scan current value of choices and set radiolist switches. |
# |
list= |
set -- $choices |
firstchoice=$2 |
while [ -n "$2" ] |
do |
case "$1" in |
"$current"*) if [ -z "$chosen" ]; then |
list="$list $2 $1 ON " |
chosen=1 |
else |
list="$list $2 $1 OFF " |
fi ;; |
*) list="$list $2 $1 OFF " ;; |
esac |
|
shift ; shift |
done |
|
while true |
do |
if $DIALOG --title "$title" \ |
--backtitle "$backtitle" \ |
--radiolist "$radiolist_instructions" \ |
15 70 6 $list 2>MCdialog.out |
then |
choice=`cat MCdialog.out` |
break |
fi |
|
help "$firstchoice" "$title" |
done |
|
# |
# Now set the boolean value of each option based on |
# the selection made from the radiolist. |
# |
set -- $choices |
while [ -n "$2" ] |
do |
if [ "$2" = "$choice" ] |
then |
eval $2=\"y\" |
else |
eval $2=\"n\" |
fi |
|
shift ; shift |
done |
} |
|
# |
# Call awk, and watch for error codes, etc. |
# |
function callawk () { |
awk "$1" || { echo "Awk died with error code $?. Giving up."; exit 1; } |
} |
|
# |
# A faster awk based recursive parser. (I hope) |
# |
function parser1 () { |
callawk ' |
BEGIN { |
menu_no = 0 |
comment_is_option = 0 |
parser("'$CONFIG_IN'","MCmenu0") |
} |
|
function parser(ifile,menu) { |
|
while (getline <ifile) { |
if ($1 == "mainmenu_option") { |
comment_is_option = "1" |
} |
else if ($1 == "comment" && comment_is_option == "1") { |
comment_is_option= "0" |
sub($1,"",$0) |
++menu_no |
|
printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu |
|
newmenu = sprintf("MCmenu%d", menu_no); |
printf( "function MCmenu%s () {\n"\ |
"default=$1\n"\ |
"menu_name %s\n",\ |
menu_no, $0) >newmenu |
|
parser(ifile, newmenu) |
} |
else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { |
printf("") >>menu |
} |
else if ($1 ~ "endmenu") { |
printf("}\n") >>menu |
return |
} |
else if ($1 == "source") { |
parser($2,menu) |
} |
else { |
print >>menu |
} |
} |
}' |
} |
|
# |
# Secondary parser for single menu mode. |
# |
function parser2 () { |
callawk ' |
BEGIN { |
parser("'$CONFIG_IN'","MCmenu0") |
} |
|
function parser(ifile,menu) { |
|
while (getline <ifile) { |
if ($0 ~ /^#|$MAKE|mainmenu_name/) { |
printf("") >>menu |
} |
else if ($1 ~ /mainmenu_option|endmenu/) { |
printf("") >>menu |
} |
else if ($1 == "source") { |
parser($2,menu) |
} |
else { |
print >>menu |
} |
} |
}' |
} |
|
# |
# Parse all the config.in files into mini scripts. |
# |
function parse_config_files () { |
rm -f MCmenu* |
|
echo "function MCmenu0 () {" >MCmenu0 |
echo 'default=$1' >>MCmenu0 |
echo "menu_name 'Main Menu'" >>MCmenu0 |
|
if [ "_$single_menu_mode" = "_TRUE" ] |
then |
parser2 |
else |
parser1 |
fi |
|
echo "comment ''" >>MCmenu0 |
echo "g_alt_config" >>MCmenu0 |
echo "s_alt_config" >>MCmenu0 |
|
echo "}" >>MCmenu0 |
|
# |
# These mini scripts must be sourced into the current |
# environment in order for all of this to work. Leaving |
# them on the disk as executables screws up the recursion |
# in activate_menu(), among other things. Once they are |
# sourced we can discard them. |
# |
for i in MCmenu* |
do |
echo -n "." |
source ./$i |
done |
rm -f MCmenu* |
} |
|
# |
# This is the menu tree's bootstrap. |
# |
# Executes the parsed menus on demand and creates a set of functions, |
# one per configuration option. These functions will in turn execute |
# dialog commands or recursively call other menus. |
# |
function activate_menu () { |
rm -f lxdialog.scrltmp |
while true |
do |
comment_ctr=0 #So comment lines get unique tags |
|
$1 "$default" 2> MCerror #Create the lxdialog menu & functions |
|
if [ "$?" != "0" ] |
then |
clear |
cat <<EOM |
|
Menuconfig has encountered a possible error in one of the kernel's |
configuration files and is unable to continue. Here is the error |
report: |
|
EOM |
sed 's/^/ Q> /' MCerror |
cat <<EOM |
|
Please report this to the maintainer <mec@shout.net>. You may also |
send a problem report to <linux-kernel@vger.kernel.org>. |
|
Please indicate the kernel version you are trying to configure and |
which menu you were trying to enter when this error occurred. |
|
EOM |
cleanup |
exit 1 |
fi |
rm -f MCerror |
|
. ./MCradiolists #Source the menu's functions |
|
. ./MCmenu 2>MCdialog.out #Activate the lxdialog menu |
ret=$? |
|
read selection <MCdialog.out |
|
case "$ret" in |
0|3|4|5|6) |
defaults="$selection$defaults" #pseudo stack |
case "$ret" in |
0) eval $selection ;; |
3) eval $selection y ;; |
4) eval $selection n ;; |
5) eval $selection m ;; |
6) eval $selection c ;; |
esac |
default="${defaults%%*}" defaults="${defaults#*}" |
;; |
2) |
default="${selection%%\ *}" |
|
case "$selection" in |
*"-->"*|*"alt_config"*) |
show_readme ;; |
*) |
eval help $selection ;; |
esac |
;; |
255|1) |
break |
;; |
139) |
stty sane |
clear |
cat <<EOM |
|
There seems to be a problem with the lxdialog companion utility which is |
built prior to running Menuconfig. Usually this is an indicator that you |
have upgraded/downgraded your ncurses libraries and did not remove the |
old ncurses header file(s) in /usr/include or /usr/include/ncurses. |
|
It is VERY important that you have only one set of ncurses header files |
and that those files are properly version matched to the ncurses libraries |
installed on your machine. |
|
You may also need to rebuild lxdialog. This can be done by moving to |
the /usr/src/linux/scripts/lxdialog directory and issuing the |
"make clean all" command. |
|
If you have verified that your ncurses install is correct, you may email |
the maintainer <mec@shout.net> or post a message to |
<linux-kernel@vger.kernel.org> for additional assistance. |
|
EOM |
cleanup |
exit 139 |
;; |
esac |
done |
} |
|
# |
# Create a menu item to load an alternate configuration file. |
# |
g_alt_config () { |
echo -n "get_alt_config 'Load an Alternate Configuration File' "\ |
>>MCmenu |
} |
|
# |
# Get alternate config file name and load the |
# configuration from it. |
# |
get_alt_config () { |
set -f ## Switch file expansion OFF |
|
while true |
do |
ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}" |
|
$DIALOG --backtitle "$backtitle" \ |
--inputbox "\ |
Enter the name of the configuration file you wish to load. \ |
Accept the name shown to restore the configuration you \ |
last retrieved. Leave blank to abort."\ |
11 55 "$ALT_CONFIG" 2>MCdialog.out |
|
if [ "$?" = "0" ] |
then |
ALT_CONFIG=`cat MCdialog.out` |
|
[ "_" = "_$ALT_CONFIG" ] && break |
|
if eval [ -r \"$ALT_CONFIG\" ] |
then |
eval load_config_file \"$ALT_CONFIG\" |
break |
else |
echo -ne "\007" |
$DIALOG --backtitle "$backtitle" \ |
--infobox "File does not exist!" 3 38 |
sleep 2 |
fi |
else |
cat <<EOM >help.out |
|
For various reasons, one may wish to keep several different kernel |
configurations available on a single machine. |
|
If you have saved a previous configuration in a file other than the |
kernel's default, entering the name of the file here will allow you |
to modify that configuration. |
|
If you are uncertain, then you have probably never used alternate |
configuration files. You should therefor leave this blank to abort. |
|
EOM |
$DIALOG --backtitle "$backtitle"\ |
--title "Load Alternate Configuration"\ |
--textbox help.out $ROWS $COLS |
fi |
done |
|
set +f ## Switch file expansion ON |
rm -f help.out MCdialog.out |
} |
|
# |
# Create a menu item to store an alternate config file. |
# |
s_alt_config () { |
echo -n "save_alt_config 'Save Configuration to an Alternate File' "\ |
>>MCmenu |
} |
|
# |
# Get an alternate config file name and save the current |
# configuration to it. |
# |
save_alt_config () { |
set -f ## Switch file expansion OFF |
|
while true |
do |
$DIALOG --backtitle "$backtitle" \ |
--inputbox "\ |
Enter a filename to which this configuration should be saved \ |
as an alternate. Leave blank to abort."\ |
10 55 "$ALT_CONFIG" 2>MCdialog.out |
|
if [ "$?" = "0" ] |
then |
ALT_CONFIG=`cat MCdialog.out` |
|
[ "_" = "_$ALT_CONFIG" ] && break |
|
if eval touch $ALT_CONFIG 2>/dev/null |
then |
eval save_configuration $ALT_CONFIG |
load_functions ## RELOAD |
break |
else |
echo -ne "\007" |
$DIALOG --backtitle "$backtitle" \ |
--infobox "Can't create file! Probably a nonexistent directory." 3 60 |
sleep 2 |
fi |
else |
cat <<EOM >help.out |
|
For various reasons, one may wish to keep different kernel |
configurations available on a single machine. |
|
Entering a file name here will allow you to later retrieve, modify |
and use the current configuration as an alternate to whatever |
configuration options you have selected at that time. |
|
If you are uncertain what all this means then you should probably |
leave this blank. |
EOM |
$DIALOG --backtitle "$backtitle"\ |
--title "Save Alternate Configuration"\ |
--textbox help.out $ROWS $COLS |
fi |
done |
|
set +f ## Switch file expansion ON |
rm -f help.out MCdialog.out |
} |
|
# |
# Load config options from a file. |
# Converts all "# OPTION is not set" lines to "OPTION=n" lines |
# |
function load_config_file () { |
awk ' |
/# .* is not set.*/ { printf("%s=n\n", $2) } |
! /# .* is not set.*/ { print } |
' $1 >.tmpconfig |
|
source ./.tmpconfig |
rm -f .tmpconfig |
} |
|
# |
# Just what it says. |
# |
save_configuration () { |
echo |
echo -n "Saving your kernel configuration." |
|
# |
# Now, let's redefine the configuration functions for final |
# output to the config files. |
# |
# Nested function definitions, YIPEE! |
# |
function bool () { |
set_x_info "$2" "n" |
eval define_bool \"$2\" \"$x\" |
} |
|
function tristate () { |
set_x_info "$2" "n" |
eval define_tristate \"$2\" \"$x\" |
} |
|
function dep_tristate () { |
set_x_info "$2" "n" |
var="$2" |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y ]; then |
shift |
elif [ "$1" = m -a "$x" != n ]; then |
x=m; shift |
else |
x=n; shift $# |
fi |
done |
define_tristate "$var" "$x" |
} |
|
function dep_bool () { |
set_x_info "$2" "n" |
var="$2" |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y ]; then |
shift |
else |
x=n; shift $# |
fi |
done |
define_bool "$var" "$x" |
} |
|
function dep_mbool () { |
set_x_info "$2" "n" |
var="$2" |
shift 2 |
while [ $# -gt 0 ]; do |
if [ "$1" = y -o "$1" = m ]; then |
shift |
else |
x=n; shift $# |
fi |
done |
define_bool "$var" "$x" |
} |
|
function int () { |
set_x_info "$2" "$3" |
echo "$2=$x" >>$CONFIG |
echo "#define $2 ($x)" >>$CONFIG_H |
} |
|
function hex () { |
set_x_info "$2" "$3" |
echo "$2=$x" >>$CONFIG |
echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H |
} |
|
function string () { |
set_x_info "$2" "$3" |
echo "$2=\"$x\"" >>$CONFIG |
echo "#define $2 \"$x\"" >>$CONFIG_H |
} |
|
function define_hex () { |
eval $1=\"$2\" |
echo "$1=$2" >>$CONFIG |
echo "#define $1 0x${2##*[x,X]}" >>$CONFIG_H |
} |
|
function define_int () { |
eval $1=\"$2\" |
echo "$1=$2" >>$CONFIG |
echo "#define $1 ($2)" >>$CONFIG_H |
} |
|
function define_string () { |
eval $1=\"$2\" |
echo "$1=\"$2\"" >>$CONFIG |
echo "#define $1 \"$2\"" >>$CONFIG_H |
} |
|
function define_bool () { |
define_tristate "$1" "$2" |
} |
|
function define_tristate () { |
eval $1=\"$2\" |
|
case "$2" in |
y) |
echo "$1=y" >>$CONFIG |
echo "#define $1 1" >>$CONFIG_H |
;; |
|
m) |
if [ "$CONFIG_MODULES" = "y" ] |
then |
echo "$1=m" >>$CONFIG |
echo "#undef $1" >>$CONFIG_H |
echo "#define $1_MODULE 1" >>$CONFIG_H |
else |
echo "$1=y" >>$CONFIG |
echo "#define $1 1" >>$CONFIG_H |
fi |
;; |
|
n) |
echo "# $1 is not set" >>$CONFIG |
echo "#undef $1" >>$CONFIG_H |
;; |
esac |
} |
|
function choice () { |
# |
# Find the first choice that's already set to 'y' |
# |
choices="$2" |
default="$3" |
current= |
chosen= |
|
set -- $choices |
while [ -n "$2" ] |
do |
if eval [ \"_\$$2\" = \"_y\" ] |
then |
current=$1 |
break |
fi |
shift ; shift |
done |
|
# |
# Use the default if none were set. |
# |
: ${current:=$default} |
|
# |
# Output all choices (to be compatible with other configs). |
# |
set -- $choices |
while [ -n "$2" ] |
do |
case "$1" in |
"$current"*) if [ -z "$chosen" ]; then |
define_bool "$2" "y" |
chosen=1 |
else |
define_bool "$2" "n" |
fi ;; |
*) define_bool "$2" "n" ;; |
esac |
shift ; shift |
done |
} |
|
function mainmenu_name () { |
: |
} |
|
function mainmenu_option () { |
comment_is_option=TRUE |
} |
|
function endmenu () { |
: |
} |
|
function comment () { |
if [ "$comment_is_option" ] |
then |
comment_is_option= |
echo >>$CONFIG |
echo "#" >>$CONFIG |
echo "# $1" >>$CONFIG |
echo "#" >>$CONFIG |
|
echo >>$CONFIG_H |
echo "/*" >>$CONFIG_H |
echo " * $1" >>$CONFIG_H |
echo " */" >>$CONFIG_H |
fi |
} |
|
echo -n "." |
|
DEF_CONFIG="${1:-.config}" |
DEF_CONFIG_H="include/linux/autoconf.h" |
|
CONFIG=.tmpconfig |
CONFIG_H=.tmpconfig.h |
|
echo "#" >$CONFIG |
echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG |
echo "#" >>$CONFIG |
|
echo "/*" >$CONFIG_H |
echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H |
echo " */" >>$CONFIG_H |
echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H |
|
echo -n "." |
if . $CONFIG_IN >>.menuconfig.log 2>&1 |
then |
if [ "$DEF_CONFIG" = ".config" ] |
then |
mv $CONFIG_H $DEF_CONFIG_H |
fi |
|
if [ -f "$DEF_CONFIG" ] |
then |
rm -f ${DEF_CONFIG}.old |
mv $DEF_CONFIG ${DEF_CONFIG}.old |
fi |
|
mv $CONFIG $DEF_CONFIG |
|
return 0 |
else |
return 1 |
fi |
} |
|
# |
# Remove temporary files |
# |
cleanup () { |
cleanup1 |
cleanup2 |
} |
|
cleanup1 () { |
rm -f MCmenu* MCradiolists MCdialog.out help.out |
} |
|
cleanup2 () { |
rm -f .tmpconfig .tmpconfig.h |
} |
|
set_geometry () { |
# Some distributions export these with incorrect values |
# which can really screw up some ncurses programs. |
LINES= COLUMNS= |
|
ROWS=${1:-24} COLS=${2:-80} |
|
# Just in case the nasty rlogin bug returns. |
# |
[ $ROWS = 0 ] && ROWS=24 |
[ $COLS = 0 ] && COLS=80 |
|
if [ $ROWS -lt 19 -o $COLS -lt 80 ] |
then |
echo -e "\n\007Your display is too small to run Menuconfig!" |
echo "It must be at least 19 lines by 80 columns." |
exit 1 |
fi |
|
ROWS=$((ROWS-4)) COLS=$((COLS-5)) |
} |
|
|
set_geometry `stty size 2>/dev/null` |
|
menu_instructions="\ |
Arrow keys navigate the menu. \ |
<Enter> selects submenus --->. \ |
Highlighted letters are hotkeys. \ |
Pressing <Y> includes, <N> excludes, <M> modularizes features. \ |
Press <Esc><Esc> to exit, <?> for Help. \ |
Legend: [*] built-in [ ] excluded <M> module < > module capable" |
|
radiolist_instructions="\ |
Use the arrow keys to navigate this window or \ |
press the hotkey of the item you wish to select \ |
followed by the <SPACE BAR>. |
Press <?> for additional information about this option." |
|
inputbox_instructions_int="\ |
Please enter a decimal value. \ |
Fractions will not be accepted. \ |
Use the <TAB> key to move from the input field to the buttons below it." |
|
inputbox_instructions_hex="\ |
Please enter a hexadecimal value. \ |
Use the <TAB> key to move from the input field to the buttons below it." |
|
inputbox_instructions_string="\ |
Please enter a string value. \ |
Use the <TAB> key to move from the input field to the buttons below it." |
|
DIALOG="./scripts/lxdialog/lxdialog" |
|
kernel_version="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" |
|
backtitle="Linux Kernel v$kernel_version Configuration" |
|
trap "cleanup ; exit 1" 1 2 15 |
|
|
# |
# Locate default files. |
# |
CONFIG_IN=./config.in |
if [ "$1" != "" ] ; then |
CONFIG_IN=$1 |
fi |
|
DEFAULTS=arch/$ARCH/defconfig |
if [ -f .config ]; then |
DEFAULTS=.config |
fi |
|
if [ -f $DEFAULTS ] |
then |
echo "Using defaults found in" $DEFAULTS |
load_config_file $DEFAULTS |
else |
echo "No defaults found" |
fi |
|
|
# Fresh new log. |
>.menuconfig.log |
|
# Load the functions used by the config.in files. |
echo -n "Preparing scripts: functions" |
load_functions |
|
if [ ! -e $CONFIG_IN ] |
then |
echo "Your main config.in file ($CONFIG_IN) does not exist" |
exit 1 |
fi |
|
if [ ! -x $DIALOG ] |
then |
echo "Your lxdialog utility does not exist" |
exit 1 |
fi |
|
# |
# Read config.in files and parse them into one shell function per menu. |
# |
echo -n ", parsing" |
parse_config_files $CONFIG_IN |
|
echo "done." |
# |
# Start the ball rolling from the top. |
# |
activate_menu MCmenu0 |
|
# |
# All done! |
# |
cleanup1 |
|
# |
# Confirm and Save |
# |
if $DIALOG --backtitle "$backtitle" \ |
--yesno "Do you wish to save your new kernel configuration?" 5 60 |
then |
save_configuration |
echo |
echo |
echo "*** End of Linux kernel configuration." |
echo "*** Check the top-level Makefile for additional configuration." |
if [ ! -f .hdepend -o "$CONFIG_MODVERSIONS" = "y" ] ; then |
echo "*** Next, you must run 'make dep'." |
else |
echo "*** Next, you may run 'make bzImage', 'make bzdisk', or 'make install'." |
fi |
echo |
else |
echo |
echo |
echo Your kernel configuration changes were NOT saved. |
echo |
fi |
|
# Remove log if empty. |
if [ ! -s .menuconfig.log ] ; then |
rm -f .menuconfig.log |
fi |
|
exit 0 |
/Lindent
0,0 → 1,2
#!/bin/sh |
indent -kr -i8 -ts8 -sob -l80 -ss -bs -psl "$@" |
/tkparse.h
0,0 → 1,127
/* |
* tkparse.h |
*/ |
|
/* |
* Token types (mostly statement types). |
*/ |
|
enum e_token |
{ |
token_UNKNOWN, |
token_bool, |
token_choice_header, |
token_choice_item, |
token_comment, |
token_define_bool, |
token_define_hex, |
token_define_int, |
token_define_string, |
token_define_tristate, |
token_dep_bool, |
token_dep_mbool, |
token_dep_tristate, |
token_else, |
token_endmenu, |
token_fi, |
token_hex, |
token_if, |
token_int, |
token_mainmenu_name, |
token_mainmenu_option, |
token_source, |
token_string, |
token_then, |
token_tristate, |
token_unset, |
}; |
|
/* |
* Operator types for conditionals. |
*/ |
|
enum operator |
{ |
op_eq, |
op_neq, |
op_and, |
op_and1, |
op_or, |
op_bang, |
op_lparen, |
op_rparen, |
op_constant, |
op_variable, |
op_true, |
op_false, |
op_nuked |
}; |
|
/* |
* Conditions come in linked lists. |
* Some operators take strings: |
* |
* op_constant "foo" |
* op_variable "$ARCH", "$CONFIG_PMAC", "$CONFIG_EXPERIMENTAL" |
* |
* Most "$..." constructs refer to a variable which is defined somewhere |
* in the script. Note that it is legal to test variables which are never |
* defined, such as variables that are meaningful only on other architectures. |
*/ |
|
struct condition |
{ |
struct condition * next; |
enum operator op; |
const char * str; /* op_constant */ |
int nameindex; /* op_variable */ |
}; |
|
/* |
* Dependency list for dep_bool, dep_mbool, dep_tristate |
*/ |
|
struct dependency |
{ |
char * name; |
struct dependency * next; |
}; |
|
/* |
* A statement from a config.in file |
*/ |
|
struct kconfig |
{ |
struct kconfig * next; |
enum e_token token; |
int nameindex; |
char * label; |
char * value; |
struct condition * cond; |
struct dependency * depend; /* token_dep_tristate */ |
struct kconfig * cfg_parent; /* token_choice_item */ |
|
/* used only in tkgen.c */ |
int menu_number; |
int menu_line; |
struct kconfig * menu_next; |
}; |
|
struct variable |
{ |
char * name; |
char defined; |
char global_written; |
}; |
|
extern struct variable *vartable; |
extern int max_varnum; |
|
/* |
* Prototypes |
*/ |
|
extern void fix_conditionals ( struct kconfig * scfg ); /* tkcond.c */ |
extern void dump_tk_script ( struct kconfig * scfg ); /* tkgen.c */ |
extern int get_varnum ( char * name ); /* tkparse.c */ |
/docgen
0,0 → 1,10
#!/bin/sh |
set -e |
if [ -z "$scripts_objtree" ] |
then |
X=`$TOPDIR/scripts/gen-all-syms "$*"` |
$TOPDIR/scripts/docproc $X |
else |
X=`${scripts_objtree}gen-all-syms "$*"` |
TOPDIR=. ${scripts_objtree}docproc $X |
fi |
/checkhelp.pl
0,0 → 1,30
#!/usr/bin/perl |
# checkhelp.pl - finds configuration options that have no |
# corresponding section in the help file |
# |
# made by Meelis Roos (mroos@tartu.cyber.ee) |
|
# read the help file |
@options=split /\n/, `grep '^CONFIG' Documentation/Configure.help`; |
die "Can't read Documentation/Configure.help\n" if $#options == -1; |
|
#read all the files |
foreach $file (@ARGV) |
{ |
open (FILE, $file) || die "Can't open $file: $!\n"; |
while (<FILE>) { |
# repeat until no CONFIG_* are left |
while (/^\s*(bool|tristate|dep_tristate|string|int|hex).*' *(.*)'.*(CONFIG_\w*)/) { |
$what=$3; |
$name=$2; |
s/$3//; |
@found = grep (/$what$/, @options); |
if ($#found == -1) { |
next if $nohelp{$what}; |
print "$name\n$what\n No help for $what\n\n"; |
$nohelp{$what}=1; |
} |
} |
} |
close (FILE); |
} |
/mkconfigs.c
0,0 → 1,181
/*************************************************************************** |
* mkconfigs.c |
* (C) 2002 Randy Dunlap <rddunlap@osdl.org> |
|
# This program is free software; you can redistribute it and/or modify |
# it under the terms of the GNU General Public License as published by |
# the Free Software Foundation; either version 2 of the License, or |
# (at your option) any later version. |
# |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
# GNU General Public License for more details. |
# |
# You should have received a copy of the GNU General Public License |
# along with this program; if not, write to the Free Software |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
# Rules for scripts/mkconfigs.c input.config output.c |
# to generate configs.c from linux/.config: |
# - drop lines that begin with '#' |
# - drop blank lines |
# - lines that use double-quotes must \\-escape-quote them |
|
################## skeleton configs.c file: #################### |
|
#include <linux/init.h> |
#include <linux/module.h> |
|
static char *configs[] __initdata = |
|
<insert lines selected lines of .config, quoted, with added '\n'>, |
|
; |
|
################### end configs.c file ###################### |
|
* Changelog for ver. 0.2, 2002-02-15, rddunlap@osdl.org: |
- strip leading "CONFIG_" from config option strings; |
- use "static" and "__attribute__((unused))"; |
- don't use EXPORT_SYMBOL(); |
- separate each config line with \newline instead of space; |
|
* Changelog for ver. 0.3, 2002-02-18, rddunlap@osdl.org: |
- keep all "not set" comment lines from .config so that 'make *config' |
will be happy, but don't keep other comments; |
- keep leading "CONFIG_" on each line; |
|
****************************************************************/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <errno.h> |
|
#define VERSION "0.2" |
#define LINE_SIZE 1000 |
|
int include_all_lines = 1; // whether to include "=n" lines in the output |
|
void usage (const char *progname) |
{ |
fprintf (stderr, "%s ver. %s\n", progname, VERSION); |
fprintf (stderr, "usage: %s input.config.name path/configs.c\n", |
progname); |
exit (1); |
} |
|
void make_intro (FILE *sourcefile) |
{ |
fprintf (sourcefile, "#include <linux/init.h>\n"); |
///// fprintf (sourcefile, "#include <linux/module.h>\n"); |
fprintf (sourcefile, "\n"); |
///// fprintf (sourcefile, "char *configs[] __initdata = {\n"); |
fprintf (sourcefile, "static char __attribute__ ((unused)) *configs[] __initdata = {\n"); |
fprintf (sourcefile, " \"CONFIG_BEGIN=n\\n\" ,\n"); |
} |
|
void make_ending (FILE *sourcefile) |
{ |
fprintf (sourcefile, " \"CONFIG_END=n\\n\"\n"); |
fprintf (sourcefile, "};\n"); |
///// fprintf (sourcefile, "EXPORT_SYMBOL (configs);\n"); |
} |
|
void make_lines (FILE *configfile, FILE *sourcefile) |
{ |
char cfgline[LINE_SIZE]; |
char *ch; |
|
while (fgets (cfgline, LINE_SIZE, configfile)) { |
/* kill the trailing newline in cfgline */ |
cfgline[strlen (cfgline) - 1] = '\0'; |
|
/* don't keep #-only line or an empty/blank line */ |
if ((cfgline[0] == '#' && cfgline[1] == '\0') || |
cfgline[0] == '\0') |
continue; |
|
if (!include_all_lines && |
cfgline[0] == '#') // strip out all comment lines |
continue; |
|
/* really only want to keep lines that begin with |
* "CONFIG_" or "# CONFIG_" */ |
if (strncmp (cfgline, "CONFIG_", 7) && |
strncmp (cfgline, "# CONFIG_", 9)) |
continue; |
|
/* |
* use strchr() to check for "-quote in cfgline; |
* if not found, output the line, quoted; |
* if found, output a char at a time, with \\-quote |
* preceding double-quote chars |
*/ |
if (!strchr (cfgline, '"')) { |
fprintf (sourcefile, " \"%s\\n\" ,\n", cfgline); |
continue; |
} |
|
/* go to char-at-a-time mode for this config and |
* precede any double-quote with a backslash */ |
fprintf (sourcefile, " \""); /* lead-in */ |
for (ch = cfgline; *ch; ch++) { |
if (*ch == '"') |
fputc ('\\', sourcefile); |
fputc (*ch, sourcefile); |
} |
fprintf (sourcefile, "\\n\" ,\n"); |
} |
} |
|
void make_configs (FILE *configfile, FILE *sourcefile) |
{ |
make_intro (sourcefile); |
make_lines (configfile, sourcefile); |
make_ending (sourcefile); |
} |
|
int main (int argc, char *argv[]) |
{ |
char *progname = argv[0]; |
char *configname, *sourcename; |
FILE *configfile, *sourcefile; |
|
if (argc != 3) |
usage (progname); |
|
configname = argv[1]; |
sourcename = argv[2]; |
|
configfile = fopen (configname, "r"); |
if (!configfile) { |
fprintf (stderr, "%s: cannot open '%s'\n", |
progname, configname); |
exit (2); |
} |
sourcefile = fopen (sourcename, "w"); |
if (!sourcefile) { |
fprintf (stderr, "%s: cannot open '%s'\n", |
progname, sourcename); |
exit (2); |
} |
|
make_configs (configfile, sourcefile); |
|
if (fclose (sourcefile)) { |
fprintf (stderr, "%s: error %d closing '%s'\n", |
progname, errno, sourcename); |
exit (3); |
} |
if (fclose (configfile)) { |
fprintf (stderr, "%s: error %d closing '%s'\n", |
progname, errno, configname); |
exit (3); |
} |
|
exit (0); |
} |
|
/* end mkconfigs.c */ |
/tkcond.c
0,0 → 1,602
/* |
* tkcond.c |
* |
* Eric Youngdale was the original author of xconfig. |
* Michael Elizabeth Chastain (mec@shout.net) is the current maintainer. |
* |
* This file takes the tokenized statement list and transforms 'if ...' |
* statements. For each simple statement, I find all of the 'if' statements |
* that enclose it, and attach the aggregate conditionals of those 'if' |
* statements to the cond list of the simple statement. |
* |
* 14 January 1999, Michael Elizabeth Chastain, <mec@shout.net> |
* - Steam-clean this file. I tested this by generating kconfig.tk for |
* every architecture and comparing it character-for-character against |
* the output of the old tkparse. |
* |
* 07 July 1999, Andrzej M. Krzysztofowicz <ankry@mif.pg.gda.pl> |
* - kvariables removed; all variables are stored in a single table now |
* - some elimination of options non-valid for current architecture |
* implemented. |
* - negation (!) eliminated from conditions |
* |
* TO DO: |
* - xconfig is at the end of its life cycle. Contact <mec@shout.net> if |
* you are interested in working on the replacement. |
*/ |
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
|
#include "tkparse.h" |
|
|
|
/* |
* Mark variables which are defined anywhere. |
*/ |
static void mark_variables( struct kconfig * scfg ) |
{ |
struct kconfig * cfg; |
int i; |
|
for ( i = 1; i <= max_varnum; i++ ) |
vartable[i].defined = 0; |
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
if ( cfg->token == token_bool |
|| cfg->token == token_choice_item |
|| cfg->token == token_define_bool |
|| cfg->token == token_define_hex |
|| cfg->token == token_define_int |
|| cfg->token == token_define_string |
|| cfg->token == token_define_tristate |
|| cfg->token == token_dep_bool |
|| cfg->token == token_dep_mbool |
|| cfg->token == token_dep_tristate |
|| cfg->token == token_hex |
|| cfg->token == token_int |
|| cfg->token == token_string |
|| cfg->token == token_tristate |
|| cfg->token == token_unset ) |
{ |
if ( cfg->nameindex > 0 ) /* paranoid */ |
{ |
vartable[cfg->nameindex].defined = 1; |
} |
} |
} |
} |
|
|
|
static void free_cond( struct condition *cond ) |
{ |
struct condition *tmp, *tmp1; |
for ( tmp = cond; tmp; tmp = tmp1 ) |
{ |
tmp1 = tmp->next; |
free( (void*)tmp ); |
} |
} |
|
|
|
/* |
* Remove the bang operator from a condition to avoid priority problems. |
* "!" has different priorities as "test" command argument and in |
* a tk script. |
*/ |
static struct condition * remove_bang( struct condition * condition ) |
{ |
struct condition * conda, * condb, * prev = NULL; |
|
for ( conda = condition; conda; conda = conda->next ) |
{ |
if ( conda->op == op_bang && conda->next && |
( condb = conda->next->next ) ) |
{ |
if ( condb->op == op_eq || condb->op == op_neq ) |
{ |
condb->op = (condb->op == op_eq) ? op_neq : op_eq; |
conda->op = op_nuked; |
if ( prev ) |
{ |
prev->next = conda->next; |
} |
else |
{ |
condition = conda->next; |
} |
conda->next = NULL; |
free_cond( conda ); |
conda = condb; |
} |
} |
prev = conda; |
} |
return condition; |
} |
|
|
|
/* |
* Make a new condition chain by joining the current condition stack with |
* the "&&" operator for glue. |
*/ |
static struct condition * join_condition_stack( struct condition * conditions [], |
int depth ) |
{ |
struct condition * cond_list; |
struct condition * cond_last; |
int i, is_first = 1; |
|
cond_list = cond_last = NULL; |
|
for ( i = 0; i < depth; i++ ) |
{ |
if ( conditions[i]->op == op_false ) |
{ |
struct condition * cnew; |
|
/* It is always false condition */ |
cnew = malloc( sizeof(*cnew) ); |
memset( cnew, 0, sizeof(*cnew) ); |
cnew->op = op_false; |
cond_list = cond_last = cnew; |
goto join_done; |
} |
} |
for ( i = 0; i < depth; i++ ) |
{ |
struct condition * cond; |
struct condition * cnew; |
int add_paren; |
|
/* omit always true conditions */ |
if ( conditions[i]->op == op_true ) |
continue; |
|
/* if i have another condition, add an '&&' operator */ |
if ( !is_first ) |
{ |
cnew = malloc( sizeof(*cnew) ); |
memset( cnew, 0, sizeof(*cnew) ); |
cnew->op = op_and; |
cond_last->next = cnew; |
cond_last = cnew; |
} |
|
if ( conditions[i]->op != op_lparen ) |
{ |
/* add a '(' */ |
add_paren = 1; |
cnew = malloc( sizeof(*cnew) ); |
memset( cnew, 0, sizeof(*cnew) ); |
cnew->op = op_lparen; |
if ( cond_last == NULL ) |
{ cond_list = cond_last = cnew; } |
else |
{ cond_last->next = cnew; cond_last = cnew; } |
} |
else |
{ |
add_paren = 0; |
} |
|
/* duplicate the chain */ |
for ( cond = conditions [i]; cond != NULL; cond = cond->next ) |
{ |
cnew = malloc( sizeof(*cnew) ); |
cnew->next = NULL; |
cnew->op = cond->op; |
cnew->str = cond->str ? strdup( cond->str ) : NULL; |
cnew->nameindex = cond->nameindex; |
if ( cond_last == NULL ) |
{ cond_list = cond_last = cnew; } |
else |
{ cond_last->next = cnew; cond_last = cnew; } |
} |
|
if ( add_paren ) |
{ |
/* add a ')' */ |
cnew = malloc( sizeof(*cnew) ); |
memset( cnew, 0, sizeof(*cnew) ); |
cnew->op = op_rparen; |
cond_last->next = cnew; |
cond_last = cnew; |
} |
is_first = 0; |
} |
|
/* |
* Remove duplicate conditions. |
*/ |
{ |
struct condition *cond1, *cond1b, *cond1c, *cond1d, *cond1e, *cond1f; |
|
for ( cond1 = cond_list; cond1 != NULL; cond1 = cond1->next ) |
{ |
if ( cond1->op == op_lparen ) |
{ |
cond1b = cond1 ->next; if ( cond1b == NULL ) break; |
cond1c = cond1b->next; if ( cond1c == NULL ) break; |
cond1d = cond1c->next; if ( cond1d == NULL ) break; |
cond1e = cond1d->next; if ( cond1e == NULL ) break; |
cond1f = cond1e->next; if ( cond1f == NULL ) break; |
|
if ( cond1b->op == op_variable |
&& ( cond1c->op == op_eq || cond1c->op == op_neq ) |
&& cond1d->op == op_constant |
&& cond1e->op == op_rparen ) |
{ |
struct condition *cond2, *cond2b, *cond2c, *cond2d, *cond2e, *cond2f; |
|
for ( cond2 = cond1f->next; cond2 != NULL; cond2 = cond2->next ) |
{ |
if ( cond2->op == op_lparen ) |
{ |
cond2b = cond2 ->next; if ( cond2b == NULL ) break; |
cond2c = cond2b->next; if ( cond2c == NULL ) break; |
cond2d = cond2c->next; if ( cond2d == NULL ) break; |
cond2e = cond2d->next; if ( cond2e == NULL ) break; |
cond2f = cond2e->next; |
|
/* look for match */ |
if ( cond2b->op == op_variable |
&& cond2b->nameindex == cond1b->nameindex |
&& cond2c->op == cond1c->op |
&& cond2d->op == op_constant |
&& strcmp( cond2d->str, cond1d->str ) == 0 |
&& cond2e->op == op_rparen ) |
{ |
/* one of these must be followed by && */ |
if ( cond1f->op == op_and |
|| ( cond2f != NULL && cond2f->op == op_and ) ) |
{ |
/* nuke the first duplicate */ |
cond1 ->op = op_nuked; |
cond1b->op = op_nuked; |
cond1c->op = op_nuked; |
cond1d->op = op_nuked; |
cond1e->op = op_nuked; |
if ( cond1f->op == op_and ) |
cond1f->op = op_nuked; |
else |
cond2f->op = op_nuked; |
} |
} |
} |
} |
} |
} |
} |
} |
|
join_done: |
return cond_list; |
} |
|
|
|
static char * current_arch = NULL; |
|
/* |
* Eliminating conditions with ARCH = <not current>. |
*/ |
static struct condition *eliminate_other_arch( struct condition *list ) |
{ |
struct condition *cond1a = list, *cond1b = NULL, *cond1c = NULL, *cond1d = NULL; |
if ( current_arch == NULL ) |
current_arch = getenv( "ARCH" ); |
if ( current_arch == NULL ) |
{ |
fprintf( stderr, "error: ARCH undefined\n" ); |
exit( 1 ); |
} |
if ( cond1a->op == op_variable |
&& ! strcmp( vartable[cond1a->nameindex].name, "ARCH" ) ) |
{ |
cond1b = cond1a->next; if ( cond1b == NULL ) goto done; |
cond1c = cond1b->next; if ( cond1c == NULL ) goto done; |
cond1d = cond1c->next; |
if ( cond1c->op == op_constant && cond1d == NULL ) |
{ |
if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for another architecture */ |
cond1a->op = op_false; |
cond1a->next = NULL; |
free_cond( cond1b ); |
return cond1a; |
} |
else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for current architecture */ |
cond1a->op = op_true; |
cond1a->next = NULL; |
free_cond( cond1b ); |
return cond1a; |
} |
} |
else if ( cond1c->op == op_constant && cond1d->op == op_or ) |
{ |
if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for another architecture */ |
cond1b = cond1d->next; |
cond1d->next = NULL; |
free_cond( cond1a ); |
return eliminate_other_arch( cond1b ); |
} |
else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for current architecture */ |
cond1a->op = op_true; |
cond1a->next = NULL; |
free_cond( cond1b ); |
return cond1a; |
} |
} |
else if ( cond1c->op == op_constant && cond1d->op == op_and ) |
{ |
if ( (cond1b->op == op_eq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_neq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for another architecture */ |
int l_par = 0; |
|
for ( cond1c = cond1d->next; cond1c; cond1c = cond1c->next ) |
{ |
if ( cond1c->op == op_lparen ) |
l_par++; |
else if ( cond1c->op == op_rparen ) |
l_par--; |
else if ( cond1c->op == op_or && l_par == 0 ) |
/* Expression too complex - don't touch */ |
return cond1a; |
else if ( l_par < 0 ) |
{ |
fprintf( stderr, "incorrect condition: programming error ?\n" ); |
exit( 1 ); |
} |
} |
cond1a->op = op_false; |
cond1a->next = NULL; |
free_cond( cond1b ); |
return cond1a; |
} |
else if ( (cond1b->op == op_neq && strcmp( cond1c->str, current_arch )) |
|| (cond1b->op == op_eq && ! strcmp( cond1c->str, current_arch )) ) |
{ |
/* This is for current architecture */ |
cond1b = cond1d->next; |
cond1d->next = NULL; |
free_cond( cond1a ); |
return eliminate_other_arch( cond1b ); |
} |
} |
} |
if ( cond1a->op == op_variable && ! vartable[cond1a->nameindex].defined ) |
{ |
cond1b = cond1a->next; if ( cond1b == NULL ) goto done; |
cond1c = cond1b->next; if ( cond1c == NULL ) goto done; |
cond1d = cond1c->next; |
|
if ( cond1c->op == op_constant |
&& ( cond1d == NULL || cond1d->op == op_and ) ) /*???*/ |
{ |
if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) |
{ |
cond1a->op = op_false; |
cond1a->next = NULL; |
free_cond( cond1b ); |
return cond1a; |
} |
} |
else if ( cond1c->op == op_constant && cond1d->op == op_or ) |
{ |
if ( cond1b->op == op_eq && strcmp( cond1c->str, "" ) ) |
{ |
cond1b = cond1d->next; |
cond1d->next = NULL; |
free_cond( cond1a ); |
return eliminate_other_arch( cond1b ); |
} |
} |
} |
done: |
return list; |
} |
|
|
|
/* |
* This is the main transformation function. |
*/ |
void fix_conditionals( struct kconfig * scfg ) |
{ |
struct kconfig * cfg; |
|
/* |
* Transform op_variable to op_kvariable. |
*/ |
mark_variables( scfg ); |
|
/* |
* Walk the statement list, maintaining a stack of current conditions. |
* token_if push its condition onto the stack. |
* token_else invert the condition on the top of the stack. |
* token_endif pop the stack. |
* |
* For a simple statement, create a condition chain by joining together |
* all of the conditions on the stack. |
*/ |
{ |
struct condition * cond_stack [32]; |
int depth = 0; |
struct kconfig * prev = NULL; |
|
for ( cfg = scfg; cfg != NULL; cfg = cfg->next ) |
{ |
int good = 1; |
switch ( cfg->token ) |
{ |
default: |
break; |
|
case token_if: |
cond_stack [depth++] = |
remove_bang( eliminate_other_arch( cfg->cond ) ); |
cfg->cond = NULL; |
break; |
|
case token_else: |
{ |
/* |
* Invert the condition chain. |
* |
* Be careful to transfrom op_or to op_and1, not op_and. |
* I will need this later in the code that removes |
* duplicate conditions. |
*/ |
struct condition * cond; |
|
for ( cond = cond_stack [depth-1]; |
cond != NULL; |
cond = cond->next ) |
{ |
switch( cond->op ) |
{ |
default: break; |
case op_and: cond->op = op_or; break; |
case op_or: cond->op = op_and1; break; |
case op_neq: cond->op = op_eq; break; |
case op_eq: cond->op = op_neq; break; |
case op_true: cond->op = op_false;break; |
case op_false:cond->op = op_true; break; |
} |
} |
} |
break; |
|
case token_fi: |
--depth; |
break; |
|
case token_bool: |
case token_choice_item: |
case token_choice_header: |
case token_comment: |
case token_define_bool: |
case token_define_hex: |
case token_define_int: |
case token_define_string: |
case token_define_tristate: |
case token_endmenu: |
case token_hex: |
case token_int: |
case token_mainmenu_option: |
case token_string: |
case token_tristate: |
case token_unset: |
cfg->cond = join_condition_stack( cond_stack, depth ); |
if ( cfg->cond && cfg->cond->op == op_false ) |
{ |
good = 0; |
if ( prev ) |
prev->next = cfg->next; |
else |
scfg = cfg->next; |
} |
break; |
|
case token_dep_bool: |
case token_dep_mbool: |
case token_dep_tristate: |
/* |
* Same as the other simple statements, plus an additional |
* condition for the dependency. |
*/ |
if ( cfg->cond ) |
{ |
cond_stack [depth] = eliminate_other_arch( cfg->cond ); |
cfg->cond = join_condition_stack( cond_stack, depth+1 ); |
} |
else |
{ |
cfg->cond = join_condition_stack( cond_stack, depth ); |
} |
if ( cfg->cond && cfg->cond->op == op_false ) |
{ |
good = 0; |
if ( prev ) |
prev->next = cfg->next; |
else |
scfg = cfg->next; |
} |
break; |
} |
if ( good ) |
prev = cfg; |
} |
} |
} |
|
|
|
#if 0 |
void dump_condition( struct condition *list ) |
{ |
struct condition *tmp; |
for ( tmp = list; tmp; tmp = tmp->next ) |
{ |
switch (tmp->op) |
{ |
default: |
break; |
case op_variable: |
printf( " %s", vartable[tmp->nameindex].name ); |
break; |
case op_constant: |
printf( " %s", tmp->str ); |
break; |
case op_eq: |
printf( " =" ); |
break; |
case op_bang: |
printf( " !" ); |
break; |
case op_neq: |
printf( " !=" ); |
break; |
case op_and: |
case op_and1: |
printf( " -a" ); |
break; |
case op_or: |
printf( " -o" ); |
break; |
case op_true: |
printf( " TRUE" ); |
break; |
case op_false: |
printf( " FALSE" ); |
break; |
case op_lparen: |
printf( " (" ); |
break; |
case op_rparen: |
printf( " )" ); |
break; |
} |
} |
printf( "\n" ); |
} |
#endif |
/split-man
0,0 → 1,33
#!/usr/bin/perl |
# |
# split-man: create man pages from kernel-doc -man output |
# |
# Author: Tim Waugh <twaugh@redhat.com> |
# Modified by: Christoph Hellwig <hch@infradead.org> |
# |
|
use strict; |
|
die "$0: where do I put the results?\n" unless ($#ARGV >= 0); |
die "$0: can't create $ARGV[0]: $!\n" unless mkdir $ARGV[0], 0777; |
|
my $state = 0; |
|
while (<STDIN>) { |
s/&(\w+)/\\fB\1\\fP/g; # fix smgl uglinesses |
if (/^\.TH \"[^\"]*\" 9 \"([^\"]*)\"/) { |
close OUT unless ($state++ == 0); |
my $fn = "$ARGV[0]/$1.9"; |
if (open OUT, ">$fn") { |
print STDERR "creating $fn\n"; |
} else { |
die "can't open $fn: $!\n"; |
} |
|
print OUT $_; |
} elsif ($state != 0) { |
print OUT $_; |
} |
} |
|
close OUT; |
/docproc.c
0,0 → 1,104
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <sys/types.h> |
#include <sys/wait.h> |
|
/* |
* A simple filter for the templates |
*/ |
|
int main(int argc, char *argv[]) |
{ |
char buf[1024]; |
char *vec[8192]; |
char *fvec[200]; |
char **svec; |
char type[64]; |
int i; |
int vp=2; |
int ret=0; |
pid_t pid; |
|
|
if(chdir(getenv("TOPDIR"))) |
{ |
perror("chdir"); |
exit(1); |
} |
|
/* |
* Build the exec array ahead of time. |
*/ |
vec[0]="kernel-doc"; |
vec[1]="-docbook"; |
for(i=1;vp<8189;i++) |
{ |
if(argv[i]==NULL) |
break; |
vec[vp++]=type; |
vec[vp++]=argv[i]; |
} |
vec[vp++]=buf+2; |
vec[vp++]=NULL; |
|
/* |
* Now process the template |
*/ |
|
while(fgets(buf, 1024, stdin)) |
{ |
if(*buf!='!') { |
printf("%s", buf); |
continue; |
} |
|
fflush(stdout); |
svec = vec; |
if(buf[1]=='E') |
strcpy(type, "-function"); |
else if(buf[1]=='I') |
strcpy(type, "-nofunction"); |
else if(buf[1]=='F') { |
int snarf = 0; |
fvec[0] = "kernel-doc"; |
fvec[1] = "-docbook"; |
strcpy (type, "-function"); |
vp = 2; |
for (i = 2; buf[i]; i++) { |
if (buf[i] == ' ' || buf[i] == '\n') { |
buf[i] = '\0'; |
snarf = 1; |
continue; |
} |
|
if (snarf) { |
snarf = 0; |
fvec[vp++] = type; |
fvec[vp++] = &buf[i]; |
} |
} |
fvec[vp++] = &buf[2]; |
fvec[vp] = NULL; |
svec = fvec; |
} else |
{ |
fprintf(stderr, "Unknown ! escape.\n"); |
exit(1); |
} |
switch(pid=fork()) |
{ |
case -1: |
perror("fork"); |
exit(1); |
case 0: |
execvp("scripts/kernel-doc", svec); |
perror("exec scripts/kernel-doc"); |
exit(1); |
default: |
waitpid(pid, &ret ,0); |
} |
} |
exit(ret); |
} |
/MAKEDEV.ide
0,0 → 1,49
#!/bin/sh |
# |
# This script creates the proper /dev/ entries for IDE devices |
# on the primary, secondary, tertiary, and quaternary interfaces. |
# See ../Documentation/ide.txt for more information. |
# |
makedev () { |
rm -f /dev/$1 |
echo mknod /dev/$1 $2 $3 $4 |
mknod /dev/$1 $2 $3 $4 |
chown root:disk /dev/$1 |
chmod 660 /dev/$1 |
} |
|
makedevs () { |
rm -f /dev/$1* |
makedev $1 b $2 $3 |
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
do |
makedev $1$part b $2 `expr $3 + $part` |
done |
} |
|
makedevs hda 3 0 |
makedevs hdb 3 64 |
makedevs hdc 22 0 |
makedevs hdd 22 64 |
makedevs hde 33 0 |
makedevs hdf 33 64 |
makedevs hdg 34 0 |
makedevs hdh 34 64 |
makedevs hdi 56 0 |
makedevs hdj 56 64 |
makedevs hdk 57 0 |
makedevs hdl 57 64 |
makedevs hdm 88 0 |
makedevs hdn 88 64 |
makedevs hdo 89 0 |
makedevs hdp 89 64 |
makedevs hdq 90 0 |
makedevs hdr 90 64 |
makedevs hds 91 0 |
makedevs hdt 91 64 |
|
for tape in 0 1 2 3 4 5 6 7 |
do |
makedev ht$tape c 37 $tape |
makedev nht$tape c 37 `expr $tape + 128` |
done |
/patch-kernel
0,0 → 1,202
#! /bin/sh |
# Script to apply kernel patches. |
# usage: patch-kernel [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] |
# The source directory defaults to /usr/src/linux, and the patch |
# directory defaults to the current directory. |
# e.g. |
# scripts/patch-kernel . .. |
# Update the kernel tree in the current directory using patches in the |
# directory above to the latest Linus kernel |
# scripts/patch-kernel . .. -ac |
# Get the latest Linux kernel and patch it with the latest ac patch |
# scripts/patch-kernel . .. 2.4.9 |
# Gets standard kernel 2.4.9 |
# scripts/patch-kernel . .. 2.4.9 -ac |
# Gets 2.4.9 with latest ac patches |
# scripts/patch-kernel . .. 2.4.9 -ac11 |
# Gets 2.4.9 with ac patch ac11 |
# Note: It uses the patches relative to the Linus kernels, not the |
# ac to ac relative patches |
# |
# It determines the current kernel version from the top-level Makefile. |
# It then looks for patches for the next sublevel in the patch directory. |
# This is applied using "patch -p1 -s" from within the kernel directory. |
# A check is then made for "*.rej" files to see if the patch was |
# successful. If it is, then all of the "*.orig" files are removed. |
# |
# Nick Holloway <Nick.Holloway@alfie.demon.co.uk>, 2nd January 1995. |
# |
# Added support for handling multiple types of compression. What includes |
# gzip, bzip, bzip2, zip, compress, and plaintext. |
# |
# Adam Sulmicki <adam@cfar.umd.edu>, 1st January 1997. |
# |
# Added ability to stop at a given version number |
# Put the full version number (i.e. 2.3.31) as the last parameter |
# Dave Gilbert <linux@treblig.org>, 11th December 1999. |
|
# Fixed previous patch so that if we are already at the correct version |
# not to patch up. |
# |
# Added -ac option, use -ac or -ac9 (say) to stop at a particular version |
# Dave Gilbert <linux@treblig.org>, 29th September 2001. |
|
# Set directories from arguments, or use defaults. |
sourcedir=${1-/usr/src/linux} |
patchdir=${2-.} |
stopvers=${3-imnotaversion} |
|
if [ "$1" = -h -o "$1" = --help -o ! -r "$sourcedir/Makefile" ]; then |
cat << USAGE |
usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] |
The source directory defaults to /usr/src/linux, and |
the patch directory defaults to the current directory. |
USAGE |
exit 1 |
fi |
|
# See if we have any -ac options |
for PARM in $* |
do |
case $PARM in |
-ac*) |
gotac=$PARM; |
|
esac; |
done |
|
# --------------------------------------------------------------------------- |
# Find a file, first parameter is basename of file |
# it tries many compression mechanisms and sets variables to say how to get it |
findFile () { |
filebase=$1; |
|
if [ -r ${filebase}.gz ]; then |
ext=".gz" |
name="gzip" |
uncomp="gunzip -dc" |
elif [ -r ${filebase}.bz ]; then |
ext=".bz" |
name="bzip" |
uncomp="bunzip -dc" |
elif [ -r ${filebase}.bz2 ]; then |
ext=".bz2" |
name="bzip2" |
uncomp="bunzip2 -dc" |
elif [ -r ${filebase}.zip ]; then |
ext=".zip" |
name="zip" |
uncomp="unzip -d" |
elif [ -r ${filebase}.Z ]; then |
ext=".Z" |
name="uncompress" |
uncomp="uncompress -c" |
elif [ -r ${filebase} ]; then |
ext="" |
name="plaintext" |
uncomp="cat" |
else |
return 1; |
fi |
|
return 0; |
} |
|
# --------------------------------------------------------------------------- |
# Apply a patch and check it goes in cleanly |
# First param is patch name (e.g. patch-2.4.9-ac5) - without path or extension |
|
applyPatch () { |
echo -n "Applying $1 (${name})... " |
if $uncomp ${patchdir}/$1${ext} | patch -p1 -s -N -E -d $sourcedir |
then |
echo "done." |
else |
echo "failed. Clean up yourself." |
return 1; |
fi |
if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] |
then |
echo "Aborting. Reject files found." |
return 1; |
fi |
# Remove backup files |
find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; |
|
return 0; |
} |
|
# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTERVERSION |
eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $sourcedir/Makefile` |
if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ] |
then |
echo "unable to determine current kernel version" >&2 |
exit 1 |
fi |
|
echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}" |
|
if [ x$EXTRAVERSION != "x" ] |
then |
echo "I'm sorry but patch-kernel can't work with a kernel source tree that is not a base version" |
exit 1; |
fi |
|
while : |
do |
CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" |
if [ $stopvers = $CURRENTFULLVERSION ] |
then |
echo "Stoping at $CURRENTFULLVERSION base as requested." |
break |
fi |
|
SUBLEVEL=`expr $SUBLEVEL + 1` |
FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" |
|
patch=patch-$FULLVERSION |
|
# See if the file exists and find extension |
findFile $patchdir/${patch} || break |
|
# Apply the patch and check all is OK |
applyPatch $patch || break |
done |
|
if [ x$gotac != x ]; then |
# Out great user wants the -ac patches |
# They could have done -ac (get latest) or -acxx where xx=version they want |
if [ $gotac == "-ac" ] |
then |
# They want the latest version |
HIGHESTPATCH=0 |
for PATCHNAMES in $patchdir/patch-${CURRENTFULLVERSION}-ac*\.* |
do |
ACVALUE=`echo $PATCHNAMES | sed -e 's/^.*patch-[0-9.]*-ac\([0-9]*\).*/\1/'` |
# Check it is actually a recognised patch type |
findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${ACVALUE} || break |
|
if [ $ACVALUE -gt $HIGHESTPATCH ] |
then |
HIGHESTPATCH=$ACVALUE |
fi |
done |
|
if [ $HIGHESTPATCH -ne 0 ] |
then |
findFile $patchdir/patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} || break |
applyPatch patch-${CURRENTFULLVERSION}-ac${HIGHESTPATCH} |
else |
echo "No ac patches found" |
fi |
else |
# They want an exact version |
findFile $patchdir/patch-${CURRENTFULLVERSION}${gotac} || { |
echo "Sorry, I couldn't find the $gotac patch for $CURRENTFULLVERSION. Hohum." |
exit 1 |
} |
applyPatch patch-${CURRENTFULLVERSION}${gotac} |
fi |
fi |
|
|
patch-kernel
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property