home *** CD-ROM | disk | FTP | other *** search
- From: how@milhow1.UU.NET (Mike Howard)
- Newsgroups: alt.sources
- Subject: simple_menu program - part1/2
- Message-ID: <350@milhow1.UU.NET>
- Date: 25 Mar 91 21:49:52 GMT
-
-
- Submitted-by: Mike Howard <how%milhow1@uunet.uu.net>
- Archive-name: simple_menu/part01
-
- I'm looking for suckers to test this - please reply by e-mail to
- how%milhow1@uunet.uu.net
-
- Currently compiles and appears to work on Sun SparcStation 4.1.1,
- SCO Xenix 2.3.3 and SCO UNIX 3.2. This is the third version I've
- done so I have some expectation that it should not foul up too badly.
-
- simple_menu - executes a simple menus
-
- This is a new version of my 'simple/dumb' menu program. The goal of
- this project is to write a simple menu shell which handles the user
- response loop and simplifies writing and maintaining user menus. Only
- rudimentary pick-one-of-N menus are supported with optional parameters.
-
- For those people (if there are any) who have actually mucked with
- my two previous attempts: the changes in this version are:
- o menu-environment variables to allow dynamic customization of menus
- on the basis of users and system administration changes
- o assignable command processor path and variable assignment format
- o some bug fixes - in particular, hitting return at the menu prompt
- does not cause the program to exit.
- o restructuring the code so that display and user interaction is more
- modular. This is in anticipation of creating an X version of this
- thing. Currently, only character based terminals which can be
- controlled by termcap or terminfo character control are supported.
-
- Menu actions are either to call a sub-menu or to run a shell script.
-
- Shell scripts are run by writing variable definitions to a temp file
- followed by copying a supplied shell script and then feeding this to
- a command interpreter. The command interpreter and assignment format
- default to Bourne shell - but can be changed on either the command line
- (dumb) or in the menu itself [what do you think? should I chuck the
- command line option? - does it have *any* real use or is it dangerous?].
-
- Some dynamic customization of menus is supported by 'menu-environment'
- variables. These are variables which take their values from either the
- user's environment [from-env type] or from a specified file [from-file type].
- In both cases, default values can be supplied in the menu. Also, in both
- cases, all menu-environment variables are defined in the shell script
- fed to the command interpreter.
-
- Take a look at 'menu.def' to see an example of a menu definition.
-
- The Makefile should be pretty straightforward to modify. In general,
- you will not need more than one entry in MENUPATH - but it does take colon
- separated path names.
-
- After building, try './simple_menu -M .' in the build-directory in
- order to test it. That will fire it up using the sample menu.def file.
- This exercises all the options I normally (and some I don't) use. If you
- find some cases which make it die, please document and mail them to me
- for update.
-
- Mike Howard
- how@milhow1.uunet.uu.net
- --------------------------------cut here--------------------------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: MANIFEST Makefile README directory ev-values grammar.y
- # login.menu menu.def patchlevel.h prototypes.h scanner.c
- # simple_menu.h sub.menu tty_display.c
- # Wrapped by mike@milhow4 on Mon Mar 25 16:45:32 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(610 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1 This shipping list
- X Makefile 1
- X README 1
- X directory 1
- X ev-values 1
- X grammar.y 1
- X login.menu 1
- X menu.def 1
- X patchlevel.h 1
- X prototypes.h 1
- X scanner.c 1
- X simple_menu.1 2
- X simple_menu.c 2
- X simple_menu.h 1
- X sub.menu 1
- X tty_display.c 1
- END_OF_FILE
- if test 610 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(3176 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X# installation info
- XBINDIR = /usr/local/bin
- XMENUPATH = /usr/local/lib/simple_menu:/usr/local/lib/dumb_menu
- XLIBDIR = /usr/local/lib/simple_menu
- XMANDIR = /usr/local/man/man1
- XMANEXT = 1
- XINSTALL = install
- XINSTALL_BIN_OPT = -c -m 755
- XINSTALL_MAN_OPT = -c -m 644
- X# INSTALL = cp
- X# INSTALL_BIN_OPT =
- X# INSTALL_MAN_OPT =
- X
- X# pick one which works
- XVOID_FLAG = -DVOID=void
- X# VOID_FLAG = -DVOID=void -DPROTOTYPES_OK
- X# VOID_FLAG = -DVOID=int
- X# VOID_FLAG = -DVOID=int -DPROTOTYPES_OK
- X
- X# os independant compiler flag(s)
- XCIND_FLAGS = -g $(VOID_FLAG) -DDEFAULT_MENU_PATH=\"$(MENUPATH)\"
- X# CIND_FLAGS = -O $(VOID_FLAG) -DDEFAULT_MENU_PATH=\"$(MENUPATH)\"
- X
- X# sun4 sys V compatability
- XCC = /usr/5bin/cc
- X# CC = cc
- X
- X# SYS V
- XCFLAGS = $(CIND_FLAGS) -DTERMINFO
- XLDFLAGS = -lcurses
- X
- X# BSD with termcap & BSD style tty inteface
- X# CFLAGS = $(CIND_FLAGS) -DBSDTTY -DTERMCAP
- X# LDFLAGS = -ltermcap
- X
- X# BSD or SCO Xenix with termcap & termio style tty inteface
- X# CFLAGS = $(CIND_FLAGS) -DTERMIO -DTERMCAP
- X# LDFLAGS = -ltermcap
- X
- X# SCO Xenix small model with termcap & termio style tty inteface
- X# CFLAGS = $(CIND_FLAGS) -DTERMIO -DTERMCAP -M0s
- X# LDFLAGS = -ltermcap
- X
- X# shouldn't have to change below here
- X
- X# C source files
- X# Yacc source files
- XYSRC = grammar.y
- XYCCC = grammar.c
- XYOBJ = grammar.o
- XOBJS = simple_menu.o disp.o $(YOBJ) scanner.o
- XDISP_OBJ = tty_display.o
- X
- XHDRS = patchlevel.h simple_menu.h prototypes.h
- XSRC = simple_menu.c $(YSRC) scanner.c $(HDRS)
- XCSRC = simple_menu.c $(YCCC) scanner.c tty_display.c
- X
- XMISC_SRC = simple_menu.1 menu.def sub.menu login.menu \
- X directory README ev-values
- XDISP_SRC = tty_display.c
- X
- Xsimple_menu : $(OBJS)
- X $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o simple_menu
- X
- X$(YCCC) : $(YSRC)
- X $(YACC) -d $(YSRC)
- X mv y.tab.c $(YCCC)
- X
- Xscanner.o : scanner.c y.tab.h $(HDRS)
- X$(YOBJ) : $(YCCC) $(HDRS)
- Xdisp.o : $(DISP_OBJ)
- X cp $(DISP_OBJ) disp.o
- X$(DISP_OBJ) simple_menu.o scanner.o : $(HDRS)
- X
- Xprt : $(SRC) $(DISP_SRC)
- X for x in $? ; do \
- X /usr/5bin/pr -f -l60 -e8 -o2 $$x | rsh milhow1 -l how 'lp -dlaser' ;\
- X done
- X touch prt
- X
- X# uses an automatic prototype generator
- Xprototypes.h :
- X echo "#ifdef PROTOTYPES_OK" >p-tmp.h
- X cproto $(CFLAGS) -p2 $(CSRC) >>p-tmp.h
- X echo "" >>p-tmp.h
- X echo "#else /* PROTOTYPES_OK */" >>p-tmp.h
- X cproto $(CFLAGS) -p1 $(CSRC) >>p-tmp.h
- X echo "#endif /* PROTOTYPES_OK */" >>p-tmp.h
- X mv p-tmp.h prototypes.h
- X
- Xtar :
- X format /dev/rfd096ds9
- X tar cvf /dev/fd096ds9 $(SRC) $(DISP_SRC) \
- X Makefile $(MISC_SRC) \
- X simple_menu simple_menu.0s
- X
- Xtar.kit :
- X rm -f tar.file.z
- X tar cvf tar.file $(SRC) $(DISP_SRC) \
- X Makefile \
- X $(MISC_SRC) \
- X simple_menu simple_menu.0s
- X pack tar.file
- X
- Xclean :
- X rm -f $(OBJS) $(YCCC) y.tab.h
- X
- Xvery.clean :
- X make clean
- X rm -f simple_menu
- X
- Xinstall : simple_menu simple_menu.1
- X $(INSTALL) $(INSTALL_BIN_OPT) simple_menu $(BINDIR)
- X $(INSTALL) $(INSTALL_MAN_OPT) simple_menu.1 \
- X $(MANDIR)/simple_menu.$(MANEXT)
- X [ ! -s $(LIBDIR) ] || mkdir $(LIBDIR)
- X
- Xkit : $(SRC) $(DISP_SRC) Makefile $(MISC_SRC)
- X makekit -m $(SRC) $(DISP_SRC) Makefile $(MISC_SRC)
- X touch kit
- X
- Xmake-patches :
- X rm -f patches
- X for x in MANIFEST \
- X $(SRC) $(DISP_SRC) Makefile \
- X $(MISC_SRC) ; do \
- X echo "\nIndex: $$x" >>patches ;\
- X cdiff RLSDIR/$$x ./$$x >>patches ;\
- X done
- END_OF_FILE
- if test 3176 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2514 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X simple_menu - executes a simple menus
- X
- X This is a new version of my 'simple/dumb' menu program. The goal of
- Xthis project is to write a simple menu shell which handles the user
- Xresponse loop and simplifies writing and maintaining user menus. Only
- Xrudimentary pick-one-of-N menus are supported with optional parameters.
- X
- X For those people (if there are any) who have actually mucked with
- Xmy two previous attempts: the changes in this version are:
- X o menu-environment variables to allow dynamic customization of menus
- X on the basis of users and system administration changes
- X o assignable command processor path and variable assignment format
- X o some bug fixes - in particular, hitting return at the menu prompt
- X does not cause the program to exit.
- X o restructuring the code so that display and user interaction is more
- X modular. This is in anticipation of creating an X version of this
- X thing. Currently, only character based terminals which can be
- X controlled by termcap or terminfo character control are supported.
- X
- X Menu actions are either to call a sub-menu or to run a shell script.
- X
- X Shell scripts are run by writing variable definitions to a temp file
- Xfollowed by copying a supplied shell script and then feeding this to
- Xa command interpreter. The command interpreter and assignment format
- Xdefault to Bourne shell - but can be changed on either the command line
- X(dumb) or in the menu itself [what do you think? should I chuck the
- Xcommand line option? - does it have *any* real use or is it dangerous?].
- X
- X Some dynamic customization of menus is supported by 'menu-environment'
- Xvariables. These are variables which take their values from either the
- Xuser's environment [from-env type] or from a specified file [from-file type].
- XIn both cases, default values can be supplied in the menu. Also, in both
- Xcases, all menu-environment variables are defined in the shell script
- Xfed to the command interpreter.
- X
- X Take a look at 'menu.def' to see an example of a menu definition.
- X
- X The Makefile should be pretty straightforward to modify. In general,
- Xyou will not need more than one entry in MENUPATH - but it does take colon
- Xseparated path names.
- X
- X After building, try './simple_menu -M .' in the build-directory in
- Xorder to test it. That will fire it up using the sample menu.def file.
- XThis exercises all the options I normally (and some I don't) use. If you
- Xfind some cases which make it die, please document and mail them to me
- Xfor update.
- X
- XMike Howard
- Xhow@milhow1.uunet.uu.net
- END_OF_FILE
- if test 2514 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'directory' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'directory'\"
- else
- echo shar: Extracting \"'directory'\" \(227 characters\)
- sed "s/^X//" >'directory' <<'END_OF_FILE'
- Xsimple_menu.1:The Manual Page
- Xscanner.c:The Lexical Analyzer
- Xsimple_menu.c:Main Program
- Xgrammary.y:The Parser
- Xtty_display.c:A tty display handler
- Xsimple_menu.h:Function definition header file
- Xprototypes.h:Prototype definitions
- END_OF_FILE
- if test 227 -ne `wc -c <'directory'`; then
- echo shar: \"'directory'\" unpacked with wrong size!
- fi
- # end of 'directory'
- fi
- if test -f 'ev-values' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'ev-values'\"
- else
- echo shar: Extracting \"'ev-values'\" \(111 characters\)
- sed "s/^X//" >'ev-values' <<'END_OF_FILE'
- X# environment file definitions
- X
- XEV_FROMFILE_NO_INIT = a new value
- X
- XEV_FROMFILE_DEFINED = the non-default value
- END_OF_FILE
- if test 111 -ne `wc -c <'ev-values'`; then
- echo shar: \"'ev-values'\" unpacked with wrong size!
- fi
- # end of 'ev-values'
- fi
- if test -f 'grammar.y' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'grammar.y'\"
- else
- echo shar: Extracting \"'grammar.y'\" \(9787 characters\)
- sed "s/^X//" >'grammar.y' <<'END_OF_FILE'
- X%{
- X/* %W% %D% */
- X
- Xstatic char *cpy_str =
- X "Copyright (c), Mike Howard, 1990,1991 all rights reserved";
- X
- X/* Conditions of use:
- X
- X This software is not for sale and is not to be sold by or
- X to anyone.
- X
- X You may use this software and may distribute it to anyone
- X you wish to provided you distribute the entire distribution
- X package w/o any deletions (i.e. include all the source code).
- X
- X I do not warrent this software to do anything at all and
- X am not responsible for anything which happens as a result of
- X its use.
- X*/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <ctype.h>
- X#include "simple_menu.h"
- X#include "patchlevel.h"
- X
- X
- X/* Menu definition files begin with an optional environment definition
- X section followed by a manditory menu definition section.
- X
- X The environment definition section consists of one or more environment
- X variable declarations of the forms:
- X
- X shell-path = 'path' ;
- X
- X asg-fmt = 'format' ; # default is asg-fmt = '"%s=\"%s\"\n"' ;
- X
- X from-env "NAME" ;
- X
- X from-env "NAME" = 'default value' ;
- X
- X from-file 'file-path' "NAME" ;
- X
- X from-file 'file-path' "NAME" = 'default value' ;
- X
- X from-env variables are initialized from the environment. from-file
- X variables are initialized from the first value in the file named
- X file-path which is of the form:
- X
- X NAME = string
- X
- X In either case, default values of the Null string or a specified string
- X can be defined.
- X
- X Environment variables are evalutated after the menu file is parsed and
- X before the top level menu is displayed.
- X
- X Environment variables are defined in the environment shell items
- X execute in. Their definition precedes local parameter definitions,
- X so local parameters can be used to over-ride their value.
- X
- X
- X Menu definitions begin with a main menu definition, optionally
- X followed by submenu definitions. The main menu is automatically
- X given the name MAIN, so it may begin with a title directive.
- X
- X title 'text for the title'
- X
- X This is followed by zero or more of the following parameters, which
- X do the `obvious' things:
- X
- X bold clear always-show once wait alpha
- X
- X This is followed by one or more menu-item definitions of the form:
- X
- X prelude 'prompt' %( shell command %)
- X parm "name" 'prompt'
- X parm "name" = 'initializer' 'prompt'
- X parm "name" = "name" 'prompt'
- X ;
- X
- X epilogue 'prompt' %( shell command %)
- X parm "name" 'prompt'
- X parm "name" = 'initializer' 'prompt'
- X parm "name" = "name" 'prompt'
- X ;
- X
- X SHELL 'prompt' %( shell command %)
- X parm "name" 'prompt'
- X parm "name" = 'initializer' 'prompt'
- X parm "name" = "name" 'prompt'
- X ;
- X
- X do-menu "menu-name" 'prompt'
- X ;
- X
- X skip ;
- X
- X Only one prelude and epilogue are allowed per menu.
- X
- X Parameters default values may be set in one of three ways:
- X parm "name" 'prompt' - default is ""
- X parm "name" = 'string' 'prompt' - default is "string"
- X parm "name" = "ev-name" 'prompt' - default is the value of the
- X environment variable ev-name
- X
- X Shell scripts are run by creating a command file and feeding it to
- X a shell. The sequence is:
- X 1. user interactively fills in values for local parameters
- X 2. copy all global variables definition strings to temp file
- X 3. copy all local parameter definitions to temp file
- X 4. copy shell script to temp file
- X 5. fork a shell and feed it the temp file - wait for completion
- X 6. delete the temp file.
- X
- X text can be written in one of three ways:
- X 1. bound by curly braces { & }
- X in which case } and \ are written as by escaping with a backslash
- X character
- X 2. bound by %( & %), in which case %( and and %) are written
- X by doubling (trippling, ...) the percent sign.
- X 3. bound by single quote marks ', in which case a single quote
- X mark is written by doubling - 'foo''s dog' -> foo's dog
- X
- X The text in between the double quotes may ONLY contain letters, digits,
- X and underscores;
- X
- X Sub-menus begin with the sequence:
- X
- X menu "menu-name"
- X
- X followed by definitions as for the main menu.
- X
- X comments are delimited on the left by a '#' sign and on the
- X right by the end of line. In-line comments are allowed.
- X
- X Sub-menus can also be formed by running simple_menu as the shell process,
- X pointed to an appropriate sub-menu definition file.
- X
- X There is no provision for menus which require more than one screen
- X to display.
- X */
- X
- X%}
- X
- X%union {
- X int ival;
- X char *txt;
- X char chr;
- X double dbl;
- X struct item *itm;
- X struct parm *prm;
- X struct ev_var *ev;
- X struct menu *mnu;
- X}
- X
- X%token <ival> NUMBER
- X%token <dbl> FLOAT
- X%token <txt> TEXT NAME
- X%token MENU
- X%token SHELL_PATH ASG_FMT
- X%token FROM_ENV FROM_FILE
- X%token PARM SHELL TITLE ERROR SKIP DO_MENU PRELUDE EPILOGUE
- X%token CLEAR BOLD ALWAYS_SHOW ONCE ALPHA WAIT
- X
- X%type <ival> menu_flags menu_flag
- X%type <itm> item
- X%type <prm> parm
- X%type <ev> ev_list ev_var
- X%type <mnu> menu title
- X
- X%%
- X
- Xmenu_def_file : ev_list menu_list
- X | menu_list
- X ;
- X
- Xev_list : ev_var
- X | ev_list ev_var
- X ;
- X
- Xev_var : SHELL_PATH '=' TEXT ';'
- X {
- X cmd_path = $3;
- X }
- X | ASG_FMT '=' TEXT ';'
- X {
- X asg_fmt = $3;
- X }
- X | FROM_ENV NAME ';'
- X {
- X $$ = make_new_ev_var(EV_FROM_ENV, $2, (char *)0, (char *)0);
- X $$->next = environment_list;
- X environment_list = $$;
- X DEBUG1("env variable %s from environment - no default\n", $2);
- X }
- X | FROM_ENV NAME '=' TEXT ';'
- X {
- X $$ = make_new_ev_var(EV_FROM_ENV, $2, $4, (char *)0);
- X $$->next = environment_list;
- X environment_list = $$;
- X DEBUG2("env variable %s from environment - defaults to %s\n", $2, $4);
- X }
- X | FROM_FILE TEXT NAME ';'
- X {
- X $$ = make_new_ev_var(EV_FROM_FILE, $3, (char *)0, $2);
- X $$->next = environment_list;
- X environment_list = $$;
- X DEBUG2("env variable %s from file %s - no default\n", $3, $2);
- X }
- X | FROM_FILE TEXT NAME '=' TEXT ';'
- X {
- X $$ = make_new_ev_var(EV_FROM_FILE, $3, $5, $2);
- X $$->next = environment_list;
- X environment_list = $$;
- X DEBUG3("env variable %s from file %s - default: %s\n", $3, $2, $5);
- X }
- X ;
- X
- Xmenu_list : menu
- X {
- X menu_list_head =
- X menu_list_tail = $1;
- X }
- X | menu_list menu
- X {
- X menu_list_tail->next = $2;
- X menu_list_tail = menu_list_tail->next;
- X }
- X ;
- X
- Xmenu : title menu_flags item
- X {
- X $1->flags = $2;
- X switch ($3->action) {
- X case ITEM_PRELUDE:
- X $1->prelude = $3;
- X break;
- X case ITEM_EPILOGUE:
- X $1->epilogue = $3;
- X break;
- X default:
- X $1->item_head =
- X $1->item_tail = $3;
- X break;
- X }
- X }
- X | menu item
- X {
- X switch ($2->action) {
- X case ITEM_PRELUDE:
- X if ($1->prelude) {
- X yacc_errors++;
- X fprintf(stderr, "multiple prelude detected -line %d\n",
- X line_number);
- X }
- X else
- X $1->prelude = $2;
- X break;
- X case ITEM_EPILOGUE:
- X if ($1->epilogue) {
- X yacc_errors++;
- X fprintf(stderr, "multiple epilogue detected -line %d\n",
- X line_number);
- X }
- X else
- X $1->epilogue = $2;
- X break;
- X default:
- X if ($1->item_head) {
- X $1->item_tail->next = $2;
- X $1->item_tail = $2;
- X }
- X else
- X $1->item_head =
- X $1->item_tail = $2;
- X break;
- X }
- X }
- X ;
- X
- Xtitle : TITLE TEXT
- X {
- X struct menu *menu_ptr;
- X
- X menu_ptr = make_new_menu();
- X menu_ptr->menu_title = $2;
- X if (menu_list_head) {
- X fprintf(stderr, "untitled sub menu detected near line %d\n",
- X line_number);
- X yacc_errors++;
- X menu_ptr->menu_name = "NOT NAMED";
- X }
- X DEBUG2("\nMenu %s Title '%s'\n", menu_ptr->menu_name, $2);
- X $$ = menu_ptr;
- X }
- X | MENU NAME TITLE TEXT
- X {
- X struct menu *menu_ptr;
- X
- X menu_ptr = make_new_menu();
- X menu_ptr->menu_name = $2;
- X menu_ptr->menu_title = $4;
- X DEBUG2("\nMenu %s Title '%s'\n", $2, $4);
- X $$ = menu_ptr;
- X }
- X ;
- X
- Xmenu_flags :
- X {
- X $$ = 0;
- X }
- X | menu_flags menu_flag
- X {
- X $$ = $1 | $2;
- X }
- X ;
- X
- Xmenu_flag : CLEAR
- X {
- X $$ = CLEAR_FLAG;
- X }
- X | BOLD
- X {
- X $$ = BOLD_FLAG;
- X }
- X | ALWAYS_SHOW
- X {
- X $$ = ALWAYS_DISPLAY_FLAG;
- X }
- X | ONCE
- X {
- X $$ = ONCE_FLAG;
- X }
- X | ALPHA
- X {
- X $$ = ALPHA_FLAG;
- X }
- X | WAIT
- X {
- X $$ = WAIT_FLAG;
- X }
- X ;
- X
- Xitem : SHELL TEXT TEXT parms ';'
- X {
- X $$ = make_new_item($2, $3, parm_list, ITEM_SHELL);
- X parm_list = (struct parm *)0;
- X DEBUG3("shell item: line %d '%s'\n%%(\n%s\n%%)\n",
- X line_number, $2, $3);
- X }
- X | PRELUDE TEXT TEXT parms ';'
- X {
- X $$ = make_new_item($2, $3, parm_list, ITEM_PRELUDE);
- X parm_list = (struct parm *)0;
- X DEBUG3("prelude item: line %d '%s'\n%%(\n%s\n%%)\n",
- X line_number, $2, $3);
- X }
- X | EPILOGUE TEXT TEXT parms ';'
- X {
- X $$ = make_new_item($2, $3, parm_list, ITEM_EPILOGUE);
- X parm_list = (struct parm *)0;
- X DEBUG3("epilogue item: line %d '%s 'n%%(\n%s\n%%)\n",
- X line_number, $2, $3);
- X }
- X | DO_MENU NAME TEXT ';'
- X {
- X $$ = make_new_item($3, $2, (struct parm *)0, ITEM_MENU);
- X DEBUG3("menu item: line %d \"%s\"\n'%s'\n",
- X line_number, $2, $3);
- X }
- X | SKIP ';'
- X {
- X $$ = make_new_item("SKIP", (char *)0, (struct parm *)0,
- X ITEM_SKIP);
- X DEBUG1("skip item: line %d\n", line_number);
- X }
- X ;
- X
- Xparms : /* empty */
- X | parms parm
- X ;
- X
- Xparm : PARM NAME TEXT
- X {
- X $$ = make_new_parm(PARM_NO_DEFAULT, $2, $3, (char *)0);
- X $$->next = parm_list;
- X parm_list = $$;
- X DEBUG2("parm: %s\n'%s'\n", $2, $3);
- X }
- X | PARM NAME '=' TEXT TEXT
- X {
- X $$ = make_new_parm(PARM_STATIC_DEFAULT, $2, $5, $4);
- X $$->next = parm_list;
- X parm_list = $$;
- X DEBUG3("parm: %s = %s\n'%s'\n", $2, $4, $5);
- X }
- X ;
- X | PARM NAME '=' NAME TEXT
- X {
- X $$ = make_new_parm(PARM_ENV_DEFAULT, $2, $5, $4);
- X $$->next = parm_list;
- X parm_list = $$;
- X DEBUG3("parm: %s = \"%s\"\n'%s'\n", $2, $4, $5);
- X if (!find_ev_var_by_name($4)) {
- X yacc_errors++;
- X fprintf(stderr, "parm initialized to non-existant environmental variable - line %s\n",
- X line_number);
- X }
- X }
- X ;
- X
- X%%
- END_OF_FILE
- if test 9787 -ne `wc -c <'grammar.y'`; then
- echo shar: \"'grammar.y'\" unpacked with wrong size!
- fi
- # end of 'grammar.y'
- fi
- if test -f 'login.menu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'login.menu'\"
- else
- echo shar: Extracting \"'login.menu'\" \(495 characters\)
- sed "s/^X//" >'login.menu' <<'END_OF_FILE'
- X# a sample login menu
- X
- Xfrom-env "EDITOR" = 'vi' ;
- Xfrom-env "PAGER" = 'more' ;
- X
- Xtitle 'Login Menu'
- X
- Xclear always-show
- X
- Xprelude 'checking for mail ...'
- X%( mail %)
- X;
- X
- Xepilogue 'checking for mail'
- X%( mail %)
- X;
- X
- Xshell 'Edit a File'
- X%( ${EDITOR} $FILE %)
- Xparm "FILE"='work.doc' 'Name of File to Edit'
- X;
- X
- Xshell 'Browse a File'
- X%( ${PAGER} $FILE %)
- Xparm "FILE"='work.doc' 'Name of File to View'
- X;
- X
- Xshell 'Mail to a User'
- X%( mail -s "$SUBJECT" $TO_WHOM %)
- Xparm "SUBJECT" 'Subject'
- Xparm "TO_WHOM" 'To'
- X;
- END_OF_FILE
- if test 495 -ne `wc -c <'login.menu'`; then
- echo shar: \"'login.menu'\" unpacked with wrong size!
- fi
- # end of 'login.menu'
- fi
- if test -f 'menu.def' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'menu.def'\"
- else
- echo shar: Extracting \"'menu.def'\" \(2442 characters\)
- sed "s/^X//" >'menu.def' <<'END_OF_FILE'
- X# environment definitions
- X
- Xfrom-file './ev-values' "EV_FROMFILE_NO_INIT" ;
- X
- Xfrom-file './ev-values' "EV_FROMFILE_DEFINED" = 'value of file value' ;
- X
- Xfrom-file './ev-values' "EV_FROMEFILE_NOT_THERE" ;
- X
- Xfrom-env "EV_DEFINED" = 'value of EV_DEFINED' ;
- X
- Xfrom-env "EV_UNDEFINED" ;
- X
- X
- X#This is the beginning of the main menu
- X# since it is not named, the name will default to MAIN
- X
- Xtitle 'Test Menu'
- X
- X# clear will cause the screen to be cleared prior to each
- X# redisplay.
- X# bold will cause the text 'Test Menu' to be displayed in
- X# standout mode - if the terminal type is defined and supports
- X# it
- X# always-show will cause the choices to always displayed
- X
- Xclear bold always-show
- X
- X# this is a simple example
- X
- Xshell 'First Item'
- X%( echo $PARM1 %) # this is the shell script which will be executed
- Xparm "PARM1" 'Input Parm 1' # this paramter is set by the user
- X;
- X
- Xshell 'Second Item'
- X%( echo "This is $PARM and $FOO and $BARF" %)
- Xparm "PARM" 'input value for PARM'
- Xparm "FOO"='foo value' 'input value for FOO'
- Xparm "BARF" = "EV_DEFINED" 'environment variable EV_DEFINED default'
- X;
- X
- Xshell 'Display all Menu-Environment Variables and values'
- X%(
- X echo "EV_FROMFILE_NO_INIT: $EV_FROMFILE_NO_INIT"
- X echo "EV_FROMFILE_DEFINED: $EV_FROMFILE_DEFINED"
- X echo "EV_FROMEFILE_NOT_THERE: $EV_FROMEFILE_NOT_THERE"
- X echo "EV_DEFINED: $EV_DEFINED"
- X echo "EV_UNDEFINED: $EV_UNDEFINED"
- X%)
- X;
- X
- X# this will cause a line to be skipped so as to block the first
- X# two items together
- X
- Xskip ;
- X
- Xshell 'Execute a Command'
- X%(
- X $CMD
- X%)
- Xparm "CMD" 'Command Line'
- X;
- X
- Xskip ;
- X
- X# three types of sub-menus folow. The first is an internal
- X# sub menu defined later in this file
- X
- Xdo-menu "SUB_MENU" 'An Internal Submenu'
- X;
- X
- X# this is a sub menu defined in a second file
- X
- Xshell 'Another Submenu in a Separate File'
- X%( ./simple_menu ./sub.menu %)
- X;
- X
- X# this sub menu is constructed dynamically by building a
- X# menu and feeding it to simple_menu
- X
- Xshell 'A Dynamically constructed Submenu'
- X%( awk -F: '
- XBEGIN {
- X print "title %( A dynamically constructed submenu %%)"
- X print "clear bold"
- X}
- X{
- X print "shell %( Browse " $2 " %%) %( " pager " " $1 " %%) ;"
- X}
- X' pager=$PAGER directory | ./simple_menu -
- X%)
- Xparm "PAGER" = 'more' 'name of your pager'
- X;
- X
- X# ============================================================
- X
- X# sub menu definition
- X
- Xmenu "SUB_MENU"
- X
- Xtitle 'a sub menu'
- X
- Xbold alpha once
- X
- Xshell 'spawn a shell'
- X%( /bin/sh -i %)
- X;
- X
- Xshell 'do nothing'
- X%( echo "did nothing" %)
- X;
- END_OF_FILE
- if test 2442 -ne `wc -c <'menu.def'`; then
- echo shar: \"'menu.def'\" unpacked with wrong size!
- fi
- # end of 'menu.def'
- fi
- if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patchlevel.h'\"
- else
- echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
- sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
- X#define PATCHLEVEL 3
- END_OF_FILE
- if test 21 -ne `wc -c <'patchlevel.h'`; then
- echo shar: \"'patchlevel.h'\" unpacked with wrong size!
- fi
- # end of 'patchlevel.h'
- fi
- if test -f 'prototypes.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'prototypes.h'\"
- else
- echo shar: Extracting \"'prototypes.h'\" \(4212 characters\)
- sed "s/^X//" >'prototypes.h' <<'END_OF_FILE'
- X#ifdef PROTOTYPES_OK
- X
- X/* simple_menu.c */
- X
- Xint main(int /*argc*/, char ** /*argv*/);
- Xvoid display_parsed_menus(void);
- Xvoid init(int /*argc*/, char ** /*argv*/);
- Xstruct parm *make_new_parm(int /*flag*/, char * /*identifier*/, char * /*prompt*/, char * /*def_or_evname*/);
- Xstruct ev_var *make_new_ev_var(int /*flag*/, char * /*identifier*/, char * /*deflt*/, char * /*fname*/);
- Xstruct item *make_new_item(char * /*prompt*/, char * /*command*/, struct parm * /*parms*/, int /*action*/);
- Xstruct menu *make_new_menu(void);
- Xvoid init_environment(void);
- Xstruct ev_var *find_ev_var_by_name(char * /*name*/);
- Xvoid init_parm_defaults(void);
- Xvoid init_item_parm_defaults(struct item * /*i_ptr*/);
- Xvoid push_menu(struct menu * /*menu_ptr*/);
- Xint pop_menu(void);
- Xstruct menu *find_menu(char * /*name*/);
- Xint check_menu(void);
- Xvoid do_menu(void);
- Xvoid do_shell_script(struct item * /*selected_item*/);
- Xvoid do_prelude(void);
- Xvoid do_epilogue(void);
- Xvoid fatal(char * /*s*/);
- Xvoid trapoid(int /*sig*/);
- Xvoid do_longjmp(int /*sig*/);
- Xvoid wait_for_child(int /*pid*/);
- Xvoid set_signals(int /*flag*/);
- Xvoid reset_signals(void);
- Xint open_menu_file(void);
- Xint search_menu_path(char * /*path*/, char * /*fname*/);
- Xchar *Malloc(unsigned /*size*/);
- Xchar *Realloc(char * /*ptr*/, unsigned /*size*/);
- Xvoid yyerror(char * /*s*/);
- Xvoid prt_item(struct item * /*item_ptr*/);
- Xvoid simple_menu_exit(int /*code*/);
- X
- X/* grammar.c */
- X
- Xint yyparse(void);
- X
- X/* scanner.c */
- X
- Xint match_token(char * /*s*/);
- Xint make_lower(char /*c*/);
- Xint yylex(void);
- Xint scan_in_token_state(void);
- Xint scan_in_name_state(void);
- Xint scan_in_string_state(void);
- Xint scan_in_text_state(void);
- Xint scan_in_old_text_state(void);
- Xvoid unget_char(char /*c*/);
- Xint next_char(int /*fd*/);
- Xvoid flush_char_input(void);
- Xvoid add_char(char /*c*/);
- Xvoid strip_white_space(void);
- Xchar *take_saved_text(void);
- X
- X/* tty_display.c */
- X
- Xint outc(int /*c*/);
- Xvoid init_terminal(void);
- Xvoid close_terminal(void);
- Xvoid display_menu(void);
- Xchar *get_variable_value(char * /*prompt*/, char * /*deflt*/);
- Xint get_user_rsp(void);
- Xvoid do_pause(int /*flag*/);
- X
- X#else /* PROTOTYPES_OK */
- X
- X/* simple_menu.c */
- X
- Xint main(/*int argc, char **argv*/);
- Xvoid display_parsed_menus(/*void*/);
- Xvoid init(/*int argc, char **argv*/);
- Xstruct parm *make_new_parm(/*int flag, char *identifier, char *prompt, char *def_or_evname*/);
- Xstruct ev_var *make_new_ev_var(/*int flag, char *identifier, char *deflt, char *fname*/);
- Xstruct item *make_new_item(/*char *prompt, char *command, struct parm *parms, int action*/);
- Xstruct menu *make_new_menu(/*void*/);
- Xvoid init_environment(/*void*/);
- Xstruct ev_var *find_ev_var_by_name(/*char *name*/);
- Xvoid init_parm_defaults(/*void*/);
- Xvoid init_item_parm_defaults(/*struct item *i_ptr*/);
- Xvoid push_menu(/*struct menu *menu_ptr*/);
- Xint pop_menu(/*void*/);
- Xstruct menu *find_menu(/*char *name*/);
- Xint check_menu(/*void*/);
- Xvoid do_menu(/*void*/);
- Xvoid do_shell_script(/*struct item *selected_item*/);
- Xvoid do_prelude(/*void*/);
- Xvoid do_epilogue(/*void*/);
- Xvoid fatal(/*char *s*/);
- Xvoid trapoid(/*int sig*/);
- Xvoid do_longjmp(/*int sig*/);
- Xvoid wait_for_child(/*int pid*/);
- Xvoid set_signals(/*int flag*/);
- Xvoid reset_signals(/*void*/);
- Xint open_menu_file(/*void*/);
- Xint search_menu_path(/*char *path, char *fname*/);
- Xchar *Malloc(/*unsigned size*/);
- Xchar *Realloc(/*char *ptr, unsigned size*/);
- Xvoid yyerror(/*char *s*/);
- Xvoid prt_item(/*struct item *item_ptr*/);
- Xvoid simple_menu_exit(/*int code*/);
- X
- X/* grammar.c */
- X
- Xint yyparse(/*void*/);
- X
- X/* scanner.c */
- X
- Xint match_token(/*char *s*/);
- Xint make_lower(/*char c*/);
- Xint yylex(/*void*/);
- Xint scan_in_token_state(/*void*/);
- Xint scan_in_name_state(/*void*/);
- Xint scan_in_string_state(/*void*/);
- Xint scan_in_text_state(/*void*/);
- Xint scan_in_old_text_state(/*void*/);
- Xvoid unget_char(/*char c*/);
- Xint next_char(/*int fd*/);
- Xvoid flush_char_input(/*void*/);
- Xvoid add_char(/*char c*/);
- Xvoid strip_white_space(/*void*/);
- Xchar *take_saved_text(/*void*/);
- X
- X/* tty_display.c */
- X
- Xint outc(/*int c*/);
- Xvoid init_terminal(/*void*/);
- Xvoid close_terminal(/*void*/);
- Xvoid display_menu(/*void*/);
- Xchar *get_variable_value(/*char *prompt, char *deflt*/);
- Xint get_user_rsp(/*void*/);
- Xvoid do_pause(/*int flag*/);
- X#endif /* PROTOTYPES_OK */
- END_OF_FILE
- if test 4212 -ne `wc -c <'prototypes.h'`; then
- echo shar: \"'prototypes.h'\" unpacked with wrong size!
- fi
- # end of 'prototypes.h'
- fi
- if test -f 'scanner.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'scanner.c'\"
- else
- echo shar: Extracting \"'scanner.c'\" \(6770 characters\)
- sed "s/^X//" >'scanner.c' <<'END_OF_FILE'
- X/* %W% %D% */
- X/* copyrite (c) Mike Howard, 1990, 1991 */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include "y.tab.h"
- X#include "simple_menu.h"
- X
- Xextern int debug_mode;
- Xextern int lex_errors;
- Xextern int line_number;
- X
- Xchar *saved_text;
- Xchar *Malloc();
- Xchar *Realloc();
- X
- Xstruct word_cell {
- X char *name;
- X int value;
- X};
- X
- Xstruct word_cell word_list[] = {
- X"ERROR", ERROR,
- X"item", SHELL, /* left over dinosaur */
- X"shell", SHELL,
- X"parm", PARM,
- X"title", TITLE,
- X"clear", CLEAR,
- X"bold", BOLD,
- X"always-show", ALWAYS_SHOW,
- X"once", ONCE,
- X"prelude", PRELUDE,
- X"epilogue", EPILOGUE,
- X"menu", MENU,
- X"do-menu", DO_MENU,
- X"skip", SKIP,
- X"alpha", ALPHA,
- X"wait", WAIT,
- X"shell-path", SHELL_PATH,
- X"asg-fmt", ASG_FMT,
- X"from-env", FROM_ENV,
- X"from-file", FROM_FILE,
- X(char *)0, -1 };
- X
- Xint
- Xmatch_token(s)
- X char *s;
- X{
- X int i;
- X
- X for (i=1;word_list[i].name;i++) {
- X if (*s == word_list[i].name[0] && !strcmp(s, word_list[i].name))
- X return i;
- X }
- X
- X lex_errors++;
- X return 0;
- X}
- X
- Xint
- Xmake_lower(c)
- X char c;
- X{
- X return isupper(c) ? tolower(c) : c;
- X}
- X
- X/* this thing is a state machine - of sorts. */
- X
- Xint
- Xyylex()
- X{
- X char c;
- X
- X while (1) {
- X while (isspace(c = next_char(0)))
- X ;
- X switch (c) {
- X case '"':
- X return scan_in_name_state();
- X case '{':
- X return scan_in_old_text_state();
- X case '\0':
- X return 0;
- X case '%':
- X if ((c = next_char(0)) == '(')
- X return scan_in_text_state();
- X unget_char(c);
- X unget_char('%');
- X return scan_in_token_state();
- X case '\'':
- X return scan_in_string_state();
- X case '#':
- X while (c && c != '\n')
- X c = next_char(0);
- X break;
- X case ';':
- X case '=':
- X VDEBUG2("scanner: line %d - returning %c\n", line_number, c);
- X return c;
- X default:
- X unget_char(c);
- X return scan_in_token_state();
- X }
- X }
- X}
- X
- Xint
- Xscan_in_token_state()
- X{
- X char c;
- X int ret;
- X
- X while (isalpha(c = make_lower(next_char(0))) || c == '-')
- X add_char(c);
- X
- X unget_char(c);
- X ret = match_token(saved_text);
- X VDEBUG3("scanner: line %d: token: %s matches %s\n", line_number,
- X saved_text, word_list[ret].name);
- X free(saved_text);
- X saved_text = (char *)0;
- X
- X return word_list[ret].value;
- X}
- X
- Xint
- Xscan_in_name_state()
- X{
- X char c;
- X
- X while (1) {
- X c = next_char(0);
- X if (isalnum(c) || c == '_')
- X add_char(c);
- X else if (c == '"') {
- X strip_white_space();
- X yylval.txt = take_saved_text();
- X VDEBUG2("scanner: line %d - found Name: \"%s\"\n", line_number,
- X yylval.txt);
- X return NAME;
- X }
- X else {
- X printf("error in line %d - bad character (%c) in name\n",
- X line_number, c);
- X while (c && !isspace(c))
- X c = next_char(0);
- X unget_char(c);
- X lex_errors++;
- X return ERROR;
- X }
- X }
- X}
- X
- X/* scans for ' delimited plain text - translates '' into ' */
- X
- Xint scan_in_string_state()
- X{
- X char c;
- X
- X while (1) {
- X switch (c = next_char(0)) {
- X case 0:
- X printf("error in line %d - premature end of text\n", line_number);
- X lex_errors++;
- X return ERROR;
- X case '\'':
- X if ((c = next_char(0)) != '\'') {
- X strip_white_space();
- X yylval.txt = take_saved_text();
- X VDEBUG2("scanner: line %d - found Text-String\n'%s'\n",
- X line_number, yylval.txt);
- X return TEXT;
- X }
- X add_char('\'');
- X break;
- X default:
- X add_char(c);
- X break;
- X }
- X }
- X}
- X
- X/* scans for %( %) delimited text - a %) may be embedded if written %%) */
- X
- Xint scan_in_text_state()
- X{
- X char c;
- X
- X while (1) {
- X switch (c = next_char(0)) {
- X case 0:
- X printf("error in line %d - premature end of text\n", line_number);
- X lex_errors++;
- X return ERROR;
- X case '%':
- X if ((c = next_char(0)) == ')') {
- X strip_white_space();
- X yylval.txt = take_saved_text();
- X VDEBUG2("scanner: line %d - found Text-String\n%(\n%s\n%)\n",
- X line_number, yylval.txt);
- X return TEXT;
- X }
- X if (c == '%') {
- X if ((c = next_char(0)) == ')' || c == '(') {
- X add_char('%');
- X add_char(c);
- X break;
- X }
- X /* back up two characters and restart */
- X unget_char(c);
- X c = '%';
- X break;
- X }
- X unget_char(c);
- X add_char('%');
- X break;
- X default:
- X add_char(c);
- X break;
- X }
- X }
- X}
- X
- Xint
- Xscan_in_old_text_state()
- X{
- X char c;
- X
- X while (1) {
- X switch (c = next_char(0)) {
- X case 0:
- X printf("error in line %d - premature end of text\n", line_number);
- X lex_errors++;
- X return ERROR;
- X case '\\':
- X switch(c = next_char(0)) {
- X case '\\':
- X case '}':
- X add_char(c);
- X break;
- X default:
- X add_char('\\');
- X add_char(c);
- X break;
- X }
- X break;
- X case '}':
- X strip_white_space();
- X yylval.txt = take_saved_text();
- X VDEBUG2("scanner: line %d - found old style Text-String\n{\n%s\n}\n",
- X line_number, yylval.txt);
- X return TEXT;
- X default:
- X add_char(c);
- X break;
- X }
- X }
- X}
- X
- X#define CHAR_BUFSIZE 1024
- Xunsigned char char_buf[CHAR_BUFSIZE];
- Xint chars_left;
- Xunsigned char *nxt_char;
- X#define UNGET_BUFSIZE 128
- Xchar unget_buf[UNGET_BUFSIZE];
- Xint unget_len;
- X
- XVOID
- Xunget_char(c)
- X char c;
- X{
- X if ((unget_buf[unget_len++] = c) == '\n')
- X line_number--;
- X}
- X
- Xint
- Xnext_char(fd)
- Xint fd;
- X{
- X int c;
- X
- X if (unget_len > 0) {
- X c = unget_buf[--unget_len];
- X }
- X else {
- X if (chars_left <= 0) {
- X if ((chars_left = read(fd, char_buf, CHAR_BUFSIZE)) <= 0)
- X return 0;
- X nxt_char = char_buf;
- X }
- X
- X c = *nxt_char++;
- X chars_left--;
- X }
- X
- X if (c == '\n')
- X line_number++;
- X
- X return c;
- X}
- X
- XVOID flush_char_input()
- X{
- X chars_left =
- X unget_len = 0;
- X}
- X
- X#define INIT_SIZE 256
- X#define INC_SIZE 64
- X
- X
- XVOID
- Xadd_char(c)
- X char c;
- X{
- X static int saved_length;
- X static int room_left;
- X static int saved_size;
- X
- X if (!saved_text) {
- X memset(saved_text = Malloc(INIT_SIZE), '\0', INIT_SIZE);
- X room_left = INIT_SIZE;
- X saved_size = INIT_SIZE;
- X saved_length = 0;
- X }
- X
- X if (room_left < 2) {
- X saved_text = Realloc(saved_text, saved_size += INC_SIZE);
- X room_left += INC_SIZE;
- X }
- X
- X saved_text[saved_length++] = c;
- X saved_text[saved_length] = '\0';
- X room_left--;
- X}
- X
- X
- XVOID
- Xstrip_white_space()
- X{
- X char *cp;
- X char *sp;
- X
- X if (!saved_text)
- X return;
- X
- X for (cp = saved_text + strlen(saved_text) - 1;cp > saved_text;cp--) {
- X if (!isspace(*cp))
- X break;
- X }
- X *++cp = '\0';
- X
- X for (cp=saved_text;*cp && isspace(*cp);cp++)
- X ;
- X
- X /* is it all white? */
- X if (!*cp && cp > saved_text) {
- X saved_text = Realloc(saved_text, 1);
- X *saved_text = '\0';
- X return;
- X }
- X
- X /* is there any leading white space? */
- X if (cp > saved_text) {
- X char *tmp;
- X int len;
- X
- X tmp = Malloc(len = strlen(cp) + 1);
- X memcpy(tmp, cp, len);
- X free(saved_text);
- X saved_text = tmp;
- X
- X return;
- X }
- X
- X saved_text = Realloc(saved_text, strlen(saved_text) + 1);
- X}
- X
- Xchar *
- Xtake_saved_text()
- X{
- X char *cp = saved_text;
- X
- X saved_text = (char *)0;
- X
- X return cp;
- X}
- END_OF_FILE
- if test 6770 -ne `wc -c <'scanner.c'`; then
- echo shar: \"'scanner.c'\" unpacked with wrong size!
- fi
- # end of 'scanner.c'
- fi
- if test -f 'simple_menu.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'simple_menu.h'\"
- else
- echo shar: Extracting \"'simple_menu.h'\" \(3804 characters\)
- sed "s/^X//" >'simple_menu.h' <<'END_OF_FILE'
- X/* %W% %D% */
- X/* copyrite (c) Mike Howard, 1990, 1991 */
- X
- X/* #define VOID void or int is expected to occur in the compilation line */
- X#ifndef VOID
- X# define VOID void
- X#endif
- X
- X/* include some common stuff */
- X#ifndef FILE
- X# include <stdio.h>
- X#endif
- X#include <setjmp.h>
- X
- X#define EV_FROM_FILE 1
- X#define EV_FROM_ENV 2
- X
- Xstruct ev_var {
- X struct ev_var *next;
- X char *identifier;
- X char *value;
- X char *deflt;
- X char *file_name;
- X int flag;
- X};
- X
- X#define PARM_NO_DEFAULT 0
- X#define PARM_STATIC_DEFAULT 1
- X#define PARM_ENV_DEFAULT 2
- X
- Xstruct parm {
- X struct parm *next;
- X char *prompt;
- X char *identifier;
- X char *value;
- X char *def_or_evname;
- X int flag;
- X};
- X
- X#define ITEM_SHELL 1
- X#define ITEM_MENU 2
- X#define ITEM_SKIP 3
- X#define ITEM_PRELUDE 4
- X#define ITEM_EPILOGUE 5
- X
- X
- Xstruct item {
- X struct item *next;
- X int action;
- X int item_idx;
- X char *prompt;
- X char *command;
- X struct parm *parms;
- X};
- X
- X#define CLEAR_FLAG 1
- X#define BOLD_FLAG 2
- X#define ALWAYS_DISPLAY_FLAG 4
- X#define ONCE_FLAG 8
- X#define ALPHA_FLAG 16
- X#define WAIT_FLAG 32
- X#define Clear_Flag (clear_flag&&(active_menu->flags&CLEAR_FLAG))
- X#define Bold_Flag (bold_flag&&(active_menu->flags&BOLD_FLAG))
- X#define Always_Display_Flag (active_menu->flags&ALWAYS_DISPLAY_FLAG)
- X#define Once_Flag (active_menu->flags&ONCE_FLAG)
- X#define Alpha_Flag (active_menu->flags&ALPHA_FLAG)
- X#define Wait_Flag (active_menu->flags&WAIT_FLAG)
- X
- Xstruct menu {
- X struct menu *next;
- X struct menu *menu_stack_ptr;
- X struct item *item_head;
- X struct item *item_tail;
- X struct item *prelude;
- X struct item *epilogue;
- X char *menu_name;
- X char *menu_title;
- X char *short_title;
- X int max_item;
- X int flags;
- X};
- X
- X#define DEBUG0(fmt) if(debug_mode>1)printf(fmt);
- X#define DEBUG1(fmt,aa) if(debug_mode>1)printf(fmt,aa);
- X#define DEBUG2(fmt,aa,bb) if(debug_mode>1)printf(fmt,aa,bb);
- X#define DEBUG3(fmt,aa,bb,cc) if(debug_mode>1)printf(fmt,aa,bb,cc);
- X
- X#define VDEBUG0(fmt) if(debug_mode>2)printf(fmt);
- X#define VDEBUG1(fmt,aa) if(debug_mode>2)printf(fmt,aa);
- X#define VDEBUG2(fmt,aa,bb) if(debug_mode>2)printf(fmt,aa,bb);
- X#define VDEBUG3(fmt,aa,bb,cc) if(debug_mode>2)printf(fmt,aa,bb,cc);
- X
- X/* data declarations and initializations */
- X#ifdef MAIN
- X# define EXTERN
- X#else
- X# define EXTERN extern
- X#endif
- X
- X/* capability flags - set by init_terminal */
- XEXTERN int clear_flag;
- XEXTERN int bold_flag;
- X
- XEXTERN struct menu *menu_list_head;
- XEXTERN struct menu *menu_list_tail;
- XEXTERN struct menu *active_menu;
- X
- XEXTERN struct parm *parm_list;
- XEXTERN struct ev_var *environment_list;
- X
- XEXTERN char *user_rsp;
- XEXTERN int default_timeout;
- X
- XEXTERN int lex_errors;
- XEXTERN int yacc_errors;
- XEXTERN int line_number;
- X
- X
- X
- Xextern char *optarg;
- Xextern int optind, opterr;
- XEXTERN int tty_in;
- XEXTERN char *tty_fname;
- XEXTERN char *ttyname();
- XEXTERN int argcc;
- XEXTERN char **argvv;
- XEXTERN char *progname;
- XEXTERN char *in_fname;
- XEXTERN char *menu_fname;
- X#define MENU_FNAME "menu.def"
- XEXTERN char *menu_path;
- X#ifndef DEFAULT_MENU_PATH
- X# define DEFAULT_MENU_PATH \
- X "/usr/local/lib/simple_menu:/usr/local/lib/dumb_menu"
- X#endif /* DEFAULT_MENU_PATH */
- XEXTERN char *cmd_path;
- XEXTERN char *asg_fmt;
- XEXTERN char *cmd_name;
- X
- XEXTERN struct item *selected_item;
- XEXTERN struct parm *selected_parms;
- XEXTERN FILE *tmp_file;
- XEXTERN char *tmp_fname;
- X
- X/* flags */
- XEXTERN int verbose;
- XEXTERN int debug_mode;
- X
- XEXTERN int display_menu_flag;
- XEXTERN jmp_buf env;
- X#define SIGS_FOR_JMP 1
- X#define SIGS_FOR_CHILD 2
- X
- X#ifdef MAIN
- X
- Xchar *use_msg = "usage: %s (patchlevel %d) [-h | option(s)] [menu-file | -]\n";
- Xchar *item_types[] = {
- X"none",
- X"Shell Item",
- X"Menu Item",
- X"Skip Item",
- X"Prelude Item",
- X"Epilogue Item",
- X(char *)0 };
- X#else
- Xextern char *use_msg;
- Xextern char *item_types[];
- X#endif
- X
- X#include "prototypes.h"
- END_OF_FILE
- if test 3804 -ne `wc -c <'simple_menu.h'`; then
- echo shar: \"'simple_menu.h'\" unpacked with wrong size!
- fi
- # end of 'simple_menu.h'
- fi
- if test -f 'sub.menu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sub.menu'\"
- else
- echo shar: Extracting \"'sub.menu'\" \(226 characters\)
- sed "s/^X//" >'sub.menu' <<'END_OF_FILE'
- X
- Xtitle 'A non-descript submenu
- XWith a multi-line
- X title'
- X
- Xclear wait
- X
- Xshell 'Sub-Item 1
- X long prompt'
- X%( echo "Sub-Item 1" %)
- X;
- X
- Xshell 'Sub-Item 2'
- X%( echo "Sub-Item 2" %)
- X;
- X
- Xshell 'Sub-Item 3'
- X%( echo "Sub-Item 3" %)
- X;
- END_OF_FILE
- if test 226 -ne `wc -c <'sub.menu'`; then
- echo shar: \"'sub.menu'\" unpacked with wrong size!
- fi
- # end of 'sub.menu'
- fi
- if test -f 'tty_display.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tty_display.c'\"
- else
- echo shar: Extracting \"'tty_display.c'\" \(8253 characters\)
- sed "s/^X//" >'tty_display.c' <<'END_OF_FILE'
- X/* %W% %D% */
- X
- Xstatic char *cpy_str =
- X "Copyright (c), Mike Howard, 1990,1991 all rights reserved";
- X
- X/* Conditions of use:
- X
- X This software is not for sale and is not to be sold by or
- X to anyone.
- X
- X You may use this software and may distribute it to anyone
- X you wish to provided you distribute the entire distribution
- X package w/o any deletions (i.e. include all the source code).
- X
- X I do not warrent this software to do anything at all and
- X am not responsible for anything which happens as a result of
- X its use.
- X*/
- X
- X/* this is the display dependant part which knows how to talk to character
- X terminals
- X
- X must define 4 functions:
- X init_terminal() - initializes the display - a tty for tty based stuff
- X display_menu() - draws the menu on the display
- X prepare_for_subshell() - this and the companion routine do whatever
- X return_from_subshell() - is required to the display to run a subshell
- X close_terminal() - does whatever closedown is required for terminal
- X get_user_rsp() - returns single character user choice.
- X get_variable_value(prompt, def) - returns Malloc'ed value of parameter
- X after talking to user
- X do_pause(flag) - implements a timed pause. It should return after a user
- X action or default_timeout seconds have passed. The
- X flag is 0 for an illegal menu choice and 1 if exiting
- X a menu
- X*/
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <string.h>
- X#include <signal.h>
- X#include <ctype.h>
- X
- X#include "simple_menu.h"
- X#include "patchlevel.h"
- X
- X#ifdef TERMCAP
- Xchar tty_bp[1024];
- Xchar tty_caps[1024];
- Xchar *term_cm;
- Xchar *term_so;
- Xchar *term_se;
- Xint term_sg;
- Xchar *term_cl;
- Xint term_lines;
- Xchar PC;
- Xchar *BC;
- Xchar *UP;
- Xshort ospeed;
- X
- Xint
- Xoutc(c)
- X int c;
- X{
- X putc(c, stdout);
- X}
- X
- XVOID
- Xinit_terminal()
- X{
- X char *getenv();
- X char *tty_type = getenv("TERM");
- X char *cp = tty_caps;
- X char *tgetstr();
- X
- X /* assumes fd's 0, 1, & 2 are closed */
- X tty_fname = ttyname(1);
- X if (!isatty(1) || (tty_in = open(tty_fname, O_RDWR)) < 0)
- X fatal("cannot open tty - must be run interactively");
- X close(0);
- X close(1);
- X close(2);
- X dup(tty_in);
- X dup(tty_in);
- X close(tty_in);
- X
- X if (!tty_type || tgetent(tty_bp, tty_type) <= 0) {
- X clear_flag =
- X bold_flag = 0;
- X return;
- X }
- X
- X PC = (BC = tgetstr("pc", &cp)) ? *BC : '\0';
- X BC = tgetstr("bc", &cp);
- X UP = tgetstr("up", &cp);
- X#ifdef TERMIO
- X {
- X#include <termio.h>
- X
- X struct termio termio;
- X
- X ioctl(0, TCGETA, &termio);
- X ospeed = termio.c_cflag & CBAUD;
- X }
- X#undef ECHO /* conflicts with lex code */
- X#endif /* TERMIO */
- X#ifdef BSDTTY
- X {
- X#include <sgtty.h>
- X struct sgttyb sgttyb;
- X
- X ioctl(0, TIOCGETP, &sgttyb);
- X ospeed = sgttyb.sg_ospeed;
- X }
- X#endif /* BSDTTY */
- X
- X term_cm = tgetstr("cm", &cp);
- X term_so = tgetstr("so", &cp);
- X term_se = tgetstr("se", &cp);
- X term_sg = tgetnum("sg");
- X bold_flag = term_so ? 1 : 0;
- X
- X term_cl = tgetstr("cl", &cp);
- X term_lines = tgetnum("li");
- X clear_flag = term_cl ? 1 : 0;
- X
- X flush_char_input();
- X}
- X
- XVOID
- Xclose_terminal()
- X{
- X}
- X
- XVOID
- Xprepare_for_subshell()
- X{
- X}
- X
- XVOID
- Xreturn_from_subshell()
- X{
- X}
- X
- XVOID
- Xdisplay_menu()
- X{
- X struct item *ptr;
- X int i;
- X
- X /* if we clear the screen, then do it, otherwise skip a line */
- X if (Clear_Flag)
- X tputs(term_cl, term_lines, outc);
- X else
- X putc('\n', stdout);
- X
- X /* this is not correct for magic cookie tubes - solving that problem
- X requires counting lines in menu_title, maintaining line counts in the
- X case we don't clear-screen-before-displaying, cursor positioning
- X sequences, ... AND having a known tube environment - i.e. no one
- X has reprogrammed something for their own purposes. So, if you
- X have any such tube, it will probably flash if you set the
- X bold flag */
- X if (Bold_Flag) {
- X tputs(term_so, 1, outc);
- X printf("%s", active_menu->menu_title);
- X tputs(term_se, 1, outc);
- X putc('\n', stdout);
- X }
- X else
- X printf("%s\n", active_menu->menu_title);
- X
- X if (display_menu_flag) {
- X for (ptr=active_menu->item_head;ptr;ptr = ptr->next) {
- X switch (ptr->action) {
- X case ITEM_SKIP:
- X putchar('\n');
- X break;
- X default:
- X if (Alpha_Flag)
- X printf("%c. %s\n", 'A' + ptr->item_idx - 1, ptr->prompt);
- X else
- X printf("%2d. %s\n", ptr->item_idx, ptr->prompt);
- X break;
- X }
- X }
- X }
- X
- X if (Once_Flag)
- X printf("Choice? ");
- X else if (Always_Display_Flag)
- X printf("Q) to End - choice? ");
- X else
- X printf("Q) to End, ?) for Menu - choice? ");
- X fflush(stdout);
- X
- X display_menu_flag = Always_Display_Flag;
- X}
- X#endif /* TERMCAP */
- X
- X#ifdef TERMINFO
- X
- Xint havecalled_setupterm;
- X#include <curses.h>
- X#include <term.h>
- X
- XVOID
- Xinit_terminal()
- X{
- X
- X /* assumes fd's 0, 1, & 2 are closed */
- X tty_fname = ttyname(1);
- X if (!isatty(1) || (tty_in = open(tty_fname, O_RDWR)) < 0)
- X fatal("cannot open tty - must be run interactively");
- X close(0);
- X close(1);
- X close(2);
- X dup(tty_in);
- X dup(tty_in);
- X close(tty_in);
- X
- X
- X setupterm((char *)0, 1, &havecalled_setupterm);
- X if (havecalled_setupterm != 1) {
- X clear_flag =
- X bold_flag = 0;
- X return;
- X }
- X
- X if (clear_screen)
- X clear_flag++;
- X if (enter_standout_mode)
- X bold_flag++;
- X
- X flush_char_input();
- X}
- X
- XVOID
- Xclose_terminal()
- X{
- X if (havecalled_setupterm)
- X resetterm();
- X}
- X
- XVOID
- Xprepare_for_subshell()
- X{
- X if (havecalled_setupterm)
- X resetterm();
- X}
- X
- XVOID
- Xreturn_from_subshell()
- X{
- X if (havecalled_setupterm)
- X fixterm();
- X}
- X
- XVOID
- Xdisplay_menu()
- X{
- X struct item *ptr;
- X int i;
- X
- X /* if we clear the screen, then do it, otherwise skip a line */
- X if (Clear_Flag)
- X putp(clear_screen);
- X else
- X putc('\n', stdout);
- X
- X /* this is not correct for magic cookie tubes - solving that problem
- X requires counting lines in menu_title, maintaining line counts in the
- X case we don't clear-screen-before-displaying, cursor positioning
- X sequences, ... AND having a known tube environment - i.e. no one
- X has reprogrammed something for their own purposes. So, if you
- X have any such tube, it will probably flash if you set the
- X bold flag */
- X if (Bold_Flag) {
- X putp(enter_standout_mode);
- X printf("%s", active_menu->menu_title);
- X putp(exit_standout_mode);
- X putc('\n', stdout);
- X }
- X else
- X printf("%s\n", active_menu->menu_title);
- X
- X if (display_menu_flag) {
- X for (ptr=active_menu->item_head;ptr;ptr = ptr->next) {
- X switch (ptr->action) {
- X case ITEM_SKIP:
- X putchar('\n');
- X break;
- X default:
- X if (Alpha_Flag)
- X printf("%c. %s\n", 'A' + ptr->item_idx - 1, ptr->prompt);
- X else
- X printf("%2d. %s\n", ptr->item_idx, ptr->prompt);
- X break;
- X }
- X }
- X }
- X
- X if (Once_Flag)
- X printf("Choice? ");
- X else if (Always_Display_Flag)
- X printf("Q) to End - choice? ");
- X else
- X printf("Q) to End, ?) for Menu - choice? ");
- X fflush(stdout);
- X
- X display_menu_flag = Always_Display_Flag;
- X}
- X#endif /* TERMINFO */
- X
- Xchar *
- Xget_variable_value(prompt, deflt)
- Xchar *prompt;
- Xchar *deflt;
- X{
- X char *cp;
- X int c;
- X
- X printf("%s[%s]: ", prompt, deflt);
- X fflush(stdout);
- X while ((c = next_char(0)) && c != '\n')
- X add_char(c);
- X
- X if ((cp = take_saved_text()) && strlen(cp)) {
- X return cp;
- X }
- X else if (deflt) {
- X strcpy(cp = Malloc(strlen(deflt) + 1), deflt);
- X }
- X else {
- X cp = Malloc(1);
- X cp[0] = '\0';
- X }
- X
- X return cp;
- X}
- X
- X
- Xint
- Xget_user_rsp()
- X{
- X char c;
- X
- X while ((c = next_char(0)) && c != '\n')
- X add_char(c);
- X strip_white_space();
- X
- X if (user_rsp)
- X free(user_rsp);
- X if (!(user_rsp = take_saved_text()))
- X return c == '\n' ? '\n' : 0;
- X
- X switch (user_rsp[0]) {
- X case 'q':
- X case 'Q':
- X return 'q';
- X case '?':
- X return '?';
- X case '\0':
- X return c == '\n' ? '\n' : 0;
- X default:
- X if (Alpha_Flag) {
- X if (isalpha(user_rsp[0]))
- X return toupper(user_rsp[0]) - 'A' + 1;
- X return 0;
- X }
- X else
- X return atoi(user_rsp);
- X }
- X}
- X
- Xstatic VOID
- Xalarm_trap()
- X{
- X return;
- X}
- X
- XVOID
- Xdo_pause(flag)
- X int flag;
- X{
- X char c;
- X
- X if (Clear_Flag) {
- X if (flag)
- X printf("Returning to '%s' [Press Return to Continue]",
- X active_menu->short_title);
- X else
- X printf("[Press Return to Continue]");
- X fflush(stdout);
- X if (!Wait_Flag) {
- X alarm(default_timeout);
- X signal(SIGALRM, alarm_trap);
- X }
- X while ((c = next_char(0)) && c != '\n')
- X ;
- X alarm(0);
- X signal(SIGALRM, SIG_IGN);
- X }
- X}
- END_OF_FILE
- if test 8253 -ne `wc -c <'tty_display.c'`; then
- echo shar: \"'tty_display.c'\" unpacked with wrong size!
- fi
- # end of 'tty_display.c'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --------------------------------cut here--------------------------------------
- --
- Mike Howard
- uunet!milhow1!how or how%milhow1@uunet.uu.net
-