home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3132 < prev    next >
Internet Message Format  |  1991-03-25  |  54KB

  1. From: how@milhow1.UU.NET (Mike Howard)
  2. Newsgroups: alt.sources
  3. Subject: simple_menu program - part1/2
  4. Message-ID: <350@milhow1.UU.NET>
  5. Date: 25 Mar 91 21:49:52 GMT
  6.  
  7.  
  8. Submitted-by: Mike Howard <how%milhow1@uunet.uu.net>
  9. Archive-name: simple_menu/part01
  10.  
  11. I'm looking for suckers to test this - please reply by e-mail to
  12.   how%milhow1@uunet.uu.net
  13.  
  14.   Currently compiles and appears to work on Sun SparcStation 4.1.1,
  15.   SCO Xenix 2.3.3 and SCO UNIX 3.2.  This is the third version I've
  16.   done so I have some expectation that it should not foul up too badly.
  17.  
  18.   simple_menu - executes a simple menus
  19.  
  20.   This is a new version of my 'simple/dumb' menu program.  The goal of
  21. this project is to write a simple menu shell which handles the user
  22. response loop and simplifies writing and maintaining user menus.  Only
  23. rudimentary pick-one-of-N menus are supported with optional parameters.
  24.  
  25.   For those people (if there are any) who have actually mucked with
  26. my two previous attempts: the changes in this version are:
  27.  o  menu-environment variables to allow dynamic customization of menus
  28.     on the basis of users and system administration changes
  29.  o  assignable command processor path and variable assignment format
  30.  o  some bug fixes - in particular, hitting return at the menu prompt
  31.     does not cause the program to exit.
  32.  o  restructuring the code so that display and user interaction is more
  33.     modular.  This is in anticipation of creating an X version of this
  34.     thing.  Currently, only character based terminals which can be
  35.     controlled by termcap or terminfo character control are supported.
  36.  
  37.   Menu actions are either to call a sub-menu or to run a shell script.
  38.  
  39.   Shell scripts are run by writing variable definitions to a temp file
  40. followed by copying a supplied shell script and then feeding this to
  41. a command interpreter.  The command interpreter and assignment format
  42. default to Bourne shell - but can be changed on either the command line
  43. (dumb) or in the menu itself [what do you think? should I chuck the
  44. command line option? - does it have *any* real use or is it dangerous?].
  45.  
  46.   Some dynamic customization of menus is supported by 'menu-environment'
  47. variables.  These are variables which take their values from either the
  48. user's environment [from-env type] or from a specified file [from-file type].
  49. In both cases, default values can be supplied in the menu.  Also, in both
  50. cases, all menu-environment variables are defined in the shell script
  51. fed to the command interpreter.
  52.  
  53.   Take a look at 'menu.def' to see an example of a menu definition.
  54.  
  55.   The Makefile should be pretty straightforward to modify.  In general,
  56. you will not need more than one entry in MENUPATH - but it does take colon
  57. separated path names.
  58.  
  59.   After building, try './simple_menu -M .' in the build-directory in
  60. order to test it.  That will fire it up using the sample menu.def file.
  61. This exercises all the options I normally (and some I don't) use.  If you
  62. find some cases which make it die, please document and mail them to me
  63. for update.
  64.  
  65. Mike Howard
  66. how@milhow1.uunet.uu.net
  67. --------------------------------cut here--------------------------------------
  68. #! /bin/sh
  69. # This is a shell archive.  Remove anything before this line, then unpack
  70. # it by saving it into a file and typing "sh file".  To overwrite existing
  71. # files, type "sh file -c".  You can also feed this as standard input via
  72. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  73. # will see the following message at the end:
  74. #        "End of archive 1 (of 2)."
  75. # Contents:  MANIFEST Makefile README directory ev-values grammar.y
  76. #   login.menu menu.def patchlevel.h prototypes.h scanner.c
  77. #   simple_menu.h sub.menu tty_display.c
  78. # Wrapped by mike@milhow4 on Mon Mar 25 16:45:32 1991
  79. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  80. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  81.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  82. else
  83. echo shar: Extracting \"'MANIFEST'\" \(610 characters\)
  84. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  85. X   File Name        Archive #    Description
  86. X-----------------------------------------------------------
  87. X MANIFEST                   1    This shipping list
  88. X Makefile                   1    
  89. X README                     1    
  90. X directory                  1    
  91. X ev-values                  1    
  92. X grammar.y                  1    
  93. X login.menu                 1    
  94. X menu.def                   1    
  95. X patchlevel.h               1    
  96. X prototypes.h               1    
  97. X scanner.c                  1    
  98. X simple_menu.1              2    
  99. X simple_menu.c              2    
  100. X simple_menu.h              1    
  101. X sub.menu                   1    
  102. X tty_display.c              1    
  103. END_OF_FILE
  104. if test 610 -ne `wc -c <'MANIFEST'`; then
  105.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  106. fi
  107. # end of 'MANIFEST'
  108. fi
  109. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  110.   echo shar: Will not clobber existing file \"'Makefile'\"
  111. else
  112. echo shar: Extracting \"'Makefile'\" \(3176 characters\)
  113. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  114. X# installation info
  115. XBINDIR    =    /usr/local/bin
  116. XMENUPATH    =    /usr/local/lib/simple_menu:/usr/local/lib/dumb_menu
  117. XLIBDIR    =    /usr/local/lib/simple_menu
  118. XMANDIR    =    /usr/local/man/man1
  119. XMANEXT    =    1
  120. XINSTALL    =    install
  121. XINSTALL_BIN_OPT    =    -c -m 755
  122. XINSTALL_MAN_OPT    =    -c -m 644
  123. X# INSTALL    =    cp
  124. X# INSTALL_BIN_OPT    =
  125. X# INSTALL_MAN_OPT    =
  126. X
  127. X# pick one which works
  128. XVOID_FLAG    =    -DVOID=void
  129. X# VOID_FLAG    =    -DVOID=void -DPROTOTYPES_OK
  130. X# VOID_FLAG    =    -DVOID=int
  131. X# VOID_FLAG    =    -DVOID=int -DPROTOTYPES_OK
  132. X
  133. X# os independant compiler flag(s)
  134. XCIND_FLAGS    =    -g $(VOID_FLAG) -DDEFAULT_MENU_PATH=\"$(MENUPATH)\"
  135. X# CIND_FLAGS    =    -O $(VOID_FLAG) -DDEFAULT_MENU_PATH=\"$(MENUPATH)\"
  136. X
  137. X# sun4 sys V compatability
  138. XCC    =    /usr/5bin/cc
  139. X# CC    =    cc
  140. X
  141. X# SYS V
  142. XCFLAGS    =    $(CIND_FLAGS) -DTERMINFO
  143. XLDFLAGS    =    -lcurses
  144. X
  145. X# BSD with termcap & BSD style tty inteface
  146. X# CFLAGS    =    $(CIND_FLAGS) -DBSDTTY -DTERMCAP
  147. X# LDFLAGS    =    -ltermcap
  148. X
  149. X# BSD or SCO Xenix with termcap & termio style tty inteface
  150. X# CFLAGS    =    $(CIND_FLAGS) -DTERMIO -DTERMCAP
  151. X# LDFLAGS    =    -ltermcap
  152. X
  153. X# SCO Xenix small model with termcap & termio style tty inteface
  154. X# CFLAGS    =    $(CIND_FLAGS) -DTERMIO -DTERMCAP -M0s
  155. X# LDFLAGS    =    -ltermcap
  156. X
  157. X#  shouldn't have to change below here
  158. X
  159. X# C source files
  160. X# Yacc source files
  161. XYSRC    =    grammar.y
  162. XYCCC    =    grammar.c
  163. XYOBJ    =    grammar.o
  164. XOBJS    =    simple_menu.o disp.o $(YOBJ) scanner.o
  165. XDISP_OBJ    =    tty_display.o
  166. X
  167. XHDRS    =    patchlevel.h simple_menu.h prototypes.h
  168. XSRC    =    simple_menu.c $(YSRC) scanner.c $(HDRS)
  169. XCSRC    =    simple_menu.c $(YCCC) scanner.c tty_display.c
  170. X
  171. XMISC_SRC    =    simple_menu.1 menu.def sub.menu login.menu \
  172. X            directory README ev-values
  173. XDISP_SRC    =    tty_display.c
  174. X
  175. Xsimple_menu :  $(OBJS)
  176. X    $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -o simple_menu
  177. X
  178. X$(YCCC) : $(YSRC)
  179. X    $(YACC) -d $(YSRC)
  180. X    mv y.tab.c $(YCCC)
  181. X
  182. Xscanner.o : scanner.c y.tab.h $(HDRS)
  183. X$(YOBJ) : $(YCCC) $(HDRS)
  184. Xdisp.o : $(DISP_OBJ)
  185. X    cp $(DISP_OBJ) disp.o
  186. X$(DISP_OBJ) simple_menu.o scanner.o : $(HDRS)
  187. X
  188. Xprt : $(SRC) $(DISP_SRC)
  189. X    for x in $? ; do \
  190. X    /usr/5bin/pr -f -l60 -e8 -o2 $$x | rsh milhow1 -l how 'lp -dlaser' ;\
  191. X    done
  192. X    touch prt
  193. X
  194. X# uses an automatic prototype generator
  195. Xprototypes.h :
  196. X    echo "#ifdef PROTOTYPES_OK" >p-tmp.h
  197. X    cproto $(CFLAGS) -p2 $(CSRC) >>p-tmp.h
  198. X    echo "" >>p-tmp.h
  199. X    echo "#else /* PROTOTYPES_OK */" >>p-tmp.h
  200. X    cproto $(CFLAGS) -p1 $(CSRC) >>p-tmp.h
  201. X    echo "#endif /* PROTOTYPES_OK */" >>p-tmp.h
  202. X    mv p-tmp.h prototypes.h
  203. X
  204. Xtar :
  205. X    format /dev/rfd096ds9
  206. X    tar cvf /dev/fd096ds9 $(SRC) $(DISP_SRC) \
  207. X        Makefile $(MISC_SRC) \
  208. X        simple_menu simple_menu.0s
  209. X
  210. Xtar.kit :
  211. X    rm -f tar.file.z
  212. X    tar cvf tar.file $(SRC) $(DISP_SRC) \
  213. X        Makefile \
  214. X        $(MISC_SRC) \
  215. X        simple_menu simple_menu.0s
  216. X    pack tar.file
  217. X
  218. Xclean :
  219. X    rm -f $(OBJS) $(YCCC) y.tab.h
  220. X
  221. Xvery.clean :
  222. X    make clean
  223. X    rm -f simple_menu
  224. X
  225. Xinstall : simple_menu simple_menu.1
  226. X    $(INSTALL) $(INSTALL_BIN_OPT) simple_menu $(BINDIR)
  227. X    $(INSTALL) $(INSTALL_MAN_OPT) simple_menu.1 \
  228. X        $(MANDIR)/simple_menu.$(MANEXT)
  229. X    [ ! -s $(LIBDIR) ] || mkdir $(LIBDIR)
  230. X
  231. Xkit : $(SRC) $(DISP_SRC) Makefile $(MISC_SRC)
  232. X    makekit -m $(SRC) $(DISP_SRC) Makefile $(MISC_SRC)
  233. X    touch kit
  234. X
  235. Xmake-patches :
  236. X    rm -f patches
  237. X    for x in MANIFEST \
  238. X        $(SRC) $(DISP_SRC) Makefile \
  239. X        $(MISC_SRC) ; do \
  240. X        echo "\nIndex: $$x" >>patches ;\
  241. X         cdiff RLSDIR/$$x ./$$x >>patches ;\
  242. X    done
  243. END_OF_FILE
  244. if test 3176 -ne `wc -c <'Makefile'`; then
  245.     echo shar: \"'Makefile'\" unpacked with wrong size!
  246. fi
  247. # end of 'Makefile'
  248. fi
  249. if test -f 'README' -a "${1}" != "-c" ; then 
  250.   echo shar: Will not clobber existing file \"'README'\"
  251. else
  252. echo shar: Extracting \"'README'\" \(2514 characters\)
  253. sed "s/^X//" >'README' <<'END_OF_FILE'
  254. X  simple_menu - executes a simple menus
  255. X
  256. X  This is a new version of my 'simple/dumb' menu program.  The goal of
  257. Xthis project is to write a simple menu shell which handles the user
  258. Xresponse loop and simplifies writing and maintaining user menus.  Only
  259. Xrudimentary pick-one-of-N menus are supported with optional parameters.
  260. X
  261. X  For those people (if there are any) who have actually mucked with
  262. Xmy two previous attempts: the changes in this version are:
  263. X o  menu-environment variables to allow dynamic customization of menus
  264. X    on the basis of users and system administration changes
  265. X o  assignable command processor path and variable assignment format
  266. X o  some bug fixes - in particular, hitting return at the menu prompt
  267. X    does not cause the program to exit.
  268. X o  restructuring the code so that display and user interaction is more
  269. X    modular.  This is in anticipation of creating an X version of this
  270. X    thing.  Currently, only character based terminals which can be
  271. X    controlled by termcap or terminfo character control are supported.
  272. X
  273. X  Menu actions are either to call a sub-menu or to run a shell script.
  274. X
  275. X  Shell scripts are run by writing variable definitions to a temp file
  276. Xfollowed by copying a supplied shell script and then feeding this to
  277. Xa command interpreter.  The command interpreter and assignment format
  278. Xdefault to Bourne shell - but can be changed on either the command line
  279. X(dumb) or in the menu itself [what do you think? should I chuck the
  280. Xcommand line option? - does it have *any* real use or is it dangerous?].
  281. X
  282. X  Some dynamic customization of menus is supported by 'menu-environment'
  283. Xvariables.  These are variables which take their values from either the
  284. Xuser's environment [from-env type] or from a specified file [from-file type].
  285. XIn both cases, default values can be supplied in the menu.  Also, in both
  286. Xcases, all menu-environment variables are defined in the shell script
  287. Xfed to the command interpreter.
  288. X
  289. X  Take a look at 'menu.def' to see an example of a menu definition.
  290. X
  291. X  The Makefile should be pretty straightforward to modify.  In general,
  292. Xyou will not need more than one entry in MENUPATH - but it does take colon
  293. Xseparated path names.
  294. X
  295. X  After building, try './simple_menu -M .' in the build-directory in
  296. Xorder to test it.  That will fire it up using the sample menu.def file.
  297. XThis exercises all the options I normally (and some I don't) use.  If you
  298. Xfind some cases which make it die, please document and mail them to me
  299. Xfor update.
  300. X
  301. XMike Howard
  302. Xhow@milhow1.uunet.uu.net
  303. END_OF_FILE
  304. if test 2514 -ne `wc -c <'README'`; then
  305.     echo shar: \"'README'\" unpacked with wrong size!
  306. fi
  307. # end of 'README'
  308. fi
  309. if test -f 'directory' -a "${1}" != "-c" ; then 
  310.   echo shar: Will not clobber existing file \"'directory'\"
  311. else
  312. echo shar: Extracting \"'directory'\" \(227 characters\)
  313. sed "s/^X//" >'directory' <<'END_OF_FILE'
  314. Xsimple_menu.1:The Manual Page
  315. Xscanner.c:The Lexical Analyzer
  316. Xsimple_menu.c:Main Program
  317. Xgrammary.y:The Parser
  318. Xtty_display.c:A tty display handler
  319. Xsimple_menu.h:Function definition header file
  320. Xprototypes.h:Prototype definitions
  321. END_OF_FILE
  322. if test 227 -ne `wc -c <'directory'`; then
  323.     echo shar: \"'directory'\" unpacked with wrong size!
  324. fi
  325. # end of 'directory'
  326. fi
  327. if test -f 'ev-values' -a "${1}" != "-c" ; then 
  328.   echo shar: Will not clobber existing file \"'ev-values'\"
  329. else
  330. echo shar: Extracting \"'ev-values'\" \(111 characters\)
  331. sed "s/^X//" >'ev-values' <<'END_OF_FILE'
  332. X# environment file definitions
  333. X
  334. XEV_FROMFILE_NO_INIT = a new value
  335. X
  336. XEV_FROMFILE_DEFINED = the non-default value
  337. END_OF_FILE
  338. if test 111 -ne `wc -c <'ev-values'`; then
  339.     echo shar: \"'ev-values'\" unpacked with wrong size!
  340. fi
  341. # end of 'ev-values'
  342. fi
  343. if test -f 'grammar.y' -a "${1}" != "-c" ; then 
  344.   echo shar: Will not clobber existing file \"'grammar.y'\"
  345. else
  346. echo shar: Extracting \"'grammar.y'\" \(9787 characters\)
  347. sed "s/^X//" >'grammar.y' <<'END_OF_FILE'
  348. X%{
  349. X/* %W% %D% */
  350. X
  351. Xstatic char *cpy_str =
  352. X  "Copyright (c), Mike Howard, 1990,1991 all rights reserved";
  353. X
  354. X/* Conditions of use:
  355. X
  356. X   This software is not for sale and is not to be sold by or
  357. X   to anyone.
  358. X
  359. X   You may use this software and may distribute it to anyone
  360. X   you wish to provided you distribute the entire distribution
  361. X   package w/o any deletions (i.e. include all the source code).
  362. X
  363. X   I do not warrent this software to do anything at all and
  364. X   am not responsible for anything which happens as a result of
  365. X   its use.
  366. X*/
  367. X
  368. X#include <stdio.h>
  369. X#include <fcntl.h>
  370. X#include <string.h>
  371. X#include <signal.h>
  372. X#include <ctype.h>
  373. X#include "simple_menu.h"
  374. X#include "patchlevel.h"
  375. X
  376. X
  377. X/* Menu definition files begin with an optional environment definition
  378. X   section followed by a manditory menu definition section.
  379. X
  380. X   The environment definition section consists of one or more environment
  381. X   variable declarations of the forms:
  382. X
  383. X   shell-path = 'path' ;
  384. X
  385. X   asg-fmt = 'format' ; # default is asg-fmt = '"%s=\"%s\"\n"' ;
  386. X
  387. X   from-env "NAME" ;
  388. X
  389. X   from-env "NAME" = 'default value' ;
  390. X
  391. X   from-file 'file-path' "NAME" ;
  392. X
  393. X   from-file 'file-path' "NAME" = 'default value' ;
  394. X
  395. X   from-env variables are initialized from the environment.  from-file
  396. X   variables are initialized from the first value in the file named
  397. X   file-path which is of the form:
  398. X
  399. X      NAME = string
  400. X
  401. X   In either case, default values of the Null string or a specified string
  402. X   can be defined.
  403. X
  404. X   Environment variables are evalutated after the menu file is parsed and
  405. X   before the top level menu is displayed.
  406. X
  407. X   Environment variables are defined in the environment shell items
  408. X   execute in.  Their definition precedes local parameter definitions,
  409. X   so local parameters can be used to over-ride their value.
  410. X
  411. X
  412. X   Menu definitions begin with a main menu definition, optionally
  413. X   followed by submenu definitions.  The main menu is automatically
  414. X   given the name MAIN, so it may begin with a title directive.
  415. X   
  416. X   title 'text for the title'
  417. X   
  418. X   This is followed by zero or more of the following parameters, which
  419. X   do the `obvious' things:
  420. X   
  421. X   bold clear always-show once wait alpha
  422. X   
  423. X   This is followed by one or more menu-item definitions of the form:
  424. X   
  425. X   prelude 'prompt' %( shell command %)
  426. X   parm "name" 'prompt'
  427. X   parm "name" = 'initializer' 'prompt'
  428. X   parm "name" = "name" 'prompt'
  429. X   ;
  430. X   
  431. X   epilogue 'prompt' %( shell command %)
  432. X   parm "name" 'prompt'
  433. X   parm "name" = 'initializer' 'prompt'
  434. X   parm "name" = "name" 'prompt'
  435. X   ;
  436. X   
  437. X   SHELL 'prompt' %( shell command %)
  438. X   parm "name" 'prompt'
  439. X   parm "name" = 'initializer' 'prompt'
  440. X   parm "name" = "name" 'prompt'
  441. X   ;
  442. X   
  443. X   do-menu "menu-name" 'prompt'
  444. X   ;
  445. X   
  446. X   skip ;
  447. X
  448. X   Only one prelude and epilogue are allowed per menu.
  449. X
  450. X   Parameters default values may be set in one of three ways:
  451. X    parm "name" 'prompt' - default is ""
  452. X    parm "name" = 'string' 'prompt' - default is "string"
  453. X    parm "name" = "ev-name" 'prompt' - default is the value of the
  454. X               environment variable ev-name
  455. X
  456. X   Shell scripts are run by creating a command file and feeding it to
  457. X   a shell.  The sequence is:
  458. X    1. user interactively fills in values for local parameters
  459. X    2. copy all global variables definition strings to temp file
  460. X    3. copy all local parameter definitions to temp file
  461. X    4. copy shell script to temp file
  462. X    5. fork a shell and feed it the temp file - wait for completion
  463. X    6. delete the temp file.
  464. X   
  465. X   text can be written in one of three ways:
  466. X   1. bound by curly braces { & }
  467. X     in which case } and \ are written as by escaping with a backslash
  468. X     character
  469. X   2. bound by %( & %), in which case %( and and %) are written
  470. X     by doubling (trippling, ...) the percent sign.
  471. X   3. bound by single quote marks ', in which case a single quote
  472. X     mark is written by doubling - 'foo''s dog' -> foo's dog
  473. X   
  474. X   The text in between the double quotes may ONLY contain letters, digits,
  475. X   and underscores;
  476. X   
  477. X   Sub-menus begin with the sequence:
  478. X   
  479. X   menu "menu-name"
  480. X   
  481. X   followed by definitions as for the main menu.
  482. X   
  483. X   comments are delimited on the left by a '#' sign and on the
  484. X   right by the end of line.  In-line comments are allowed.
  485. X   
  486. X   Sub-menus can also be formed by running simple_menu as the shell process,
  487. X   pointed to an appropriate sub-menu definition file.
  488. X   
  489. X   There is no provision for menus which require more than one screen 
  490. X   to display.
  491. X   */
  492. X
  493. X%}
  494. X
  495. X%union {
  496. X  int ival;
  497. X  char *txt;
  498. X  char chr;
  499. X  double dbl;
  500. X  struct item *itm;
  501. X  struct parm *prm;
  502. X  struct ev_var *ev;
  503. X  struct menu *mnu;
  504. X}
  505. X
  506. X%token <ival> NUMBER
  507. X%token <dbl> FLOAT
  508. X%token <txt> TEXT NAME
  509. X%token MENU
  510. X%token SHELL_PATH ASG_FMT
  511. X%token FROM_ENV FROM_FILE
  512. X%token PARM SHELL TITLE ERROR SKIP DO_MENU PRELUDE EPILOGUE
  513. X%token CLEAR BOLD ALWAYS_SHOW ONCE ALPHA WAIT
  514. X
  515. X%type <ival> menu_flags menu_flag
  516. X%type <itm> item
  517. X%type <prm> parm
  518. X%type <ev> ev_list ev_var
  519. X%type <mnu> menu title
  520. X
  521. X%%
  522. X
  523. Xmenu_def_file : ev_list menu_list
  524. X    | menu_list
  525. X    ;
  526. X
  527. Xev_list : ev_var
  528. X    | ev_list ev_var
  529. X    ;
  530. X
  531. Xev_var : SHELL_PATH '=' TEXT ';'
  532. X    {
  533. X      cmd_path = $3;
  534. X    }
  535. X    | ASG_FMT '=' TEXT ';'
  536. X    {
  537. X      asg_fmt = $3;
  538. X    }
  539. X    | FROM_ENV NAME ';'
  540. X    {
  541. X      $$ = make_new_ev_var(EV_FROM_ENV, $2, (char *)0, (char *)0);
  542. X      $$->next = environment_list;
  543. X      environment_list = $$;
  544. X      DEBUG1("env variable %s from environment - no default\n", $2);
  545. X    }
  546. X    | FROM_ENV NAME '=' TEXT ';'
  547. X    {
  548. X      $$ = make_new_ev_var(EV_FROM_ENV, $2, $4, (char *)0);
  549. X      $$->next = environment_list;
  550. X      environment_list = $$;
  551. X      DEBUG2("env variable %s from environment - defaults to %s\n", $2, $4);
  552. X    }
  553. X    | FROM_FILE TEXT NAME ';'
  554. X    {
  555. X      $$ = make_new_ev_var(EV_FROM_FILE, $3, (char *)0, $2);
  556. X      $$->next = environment_list;
  557. X      environment_list = $$;
  558. X      DEBUG2("env variable %s from file %s - no default\n", $3, $2);
  559. X    }
  560. X    | FROM_FILE TEXT NAME '=' TEXT ';'
  561. X    {
  562. X      $$ = make_new_ev_var(EV_FROM_FILE, $3, $5, $2);
  563. X      $$->next = environment_list;
  564. X      environment_list = $$;
  565. X      DEBUG3("env variable %s from file %s - default: %s\n", $3, $2, $5);
  566. X    }
  567. X    ;
  568. X  
  569. Xmenu_list : menu
  570. X    {
  571. X      menu_list_head =
  572. X        menu_list_tail = $1;
  573. X    }
  574. X    | menu_list menu
  575. X    {
  576. X      menu_list_tail->next =  $2;
  577. X      menu_list_tail = menu_list_tail->next;
  578. X    }
  579. X    ;
  580. X
  581. Xmenu : title menu_flags item
  582. X    {
  583. X      $1->flags = $2;
  584. X      switch ($3->action) {
  585. X      case ITEM_PRELUDE:
  586. X        $1->prelude = $3;
  587. X        break;
  588. X      case ITEM_EPILOGUE:
  589. X        $1->epilogue = $3;
  590. X        break;
  591. X      default:
  592. X        $1->item_head =
  593. X          $1->item_tail = $3;
  594. X        break;
  595. X      }
  596. X    }
  597. X    | menu item
  598. X    {
  599. X      switch ($2->action) {
  600. X      case ITEM_PRELUDE:
  601. X        if ($1->prelude) {
  602. X          yacc_errors++;
  603. X          fprintf(stderr, "multiple prelude detected -line %d\n",
  604. X              line_number);
  605. X        }
  606. X        else
  607. X          $1->prelude = $2;
  608. X        break;
  609. X      case ITEM_EPILOGUE:
  610. X        if ($1->epilogue) {
  611. X          yacc_errors++;
  612. X          fprintf(stderr, "multiple epilogue detected -line %d\n",
  613. X              line_number);
  614. X        }
  615. X        else
  616. X          $1->epilogue = $2;
  617. X        break;
  618. X      default:
  619. X        if ($1->item_head) {
  620. X          $1->item_tail->next = $2;
  621. X          $1->item_tail = $2;
  622. X        }
  623. X        else
  624. X          $1->item_head =
  625. X        $1->item_tail = $2;
  626. X        break;
  627. X      }
  628. X    }
  629. X    ;
  630. X
  631. Xtitle : TITLE TEXT
  632. X    {
  633. X      struct menu *menu_ptr;
  634. X
  635. X      menu_ptr = make_new_menu();
  636. X      menu_ptr->menu_title = $2;
  637. X      if (menu_list_head) {
  638. X        fprintf(stderr, "untitled sub menu detected near line %d\n",
  639. X            line_number);
  640. X        yacc_errors++;
  641. X        menu_ptr->menu_name = "NOT NAMED";
  642. X      }
  643. X      DEBUG2("\nMenu %s Title '%s'\n", menu_ptr->menu_name, $2);
  644. X      $$ = menu_ptr;
  645. X    }
  646. X    | MENU NAME TITLE TEXT
  647. X    {
  648. X      struct menu *menu_ptr;
  649. X
  650. X      menu_ptr = make_new_menu();
  651. X      menu_ptr->menu_name = $2;
  652. X      menu_ptr->menu_title = $4;
  653. X      DEBUG2("\nMenu %s Title '%s'\n", $2, $4);
  654. X      $$ = menu_ptr;
  655. X    }
  656. X    ;
  657. X
  658. Xmenu_flags :
  659. X    {
  660. X      $$ = 0;
  661. X    }
  662. X    | menu_flags menu_flag
  663. X    {  
  664. X      $$ = $1 | $2;
  665. X    }
  666. X    ;
  667. X
  668. Xmenu_flag : CLEAR
  669. X    {
  670. X      $$ = CLEAR_FLAG;
  671. X    }
  672. X    | BOLD
  673. X    {
  674. X        $$ = BOLD_FLAG;
  675. X    }
  676. X    | ALWAYS_SHOW
  677. X    {
  678. X        $$ = ALWAYS_DISPLAY_FLAG;
  679. X    }
  680. X    | ONCE
  681. X    {
  682. X      $$ = ONCE_FLAG;
  683. X    }
  684. X    | ALPHA
  685. X    {
  686. X      $$ = ALPHA_FLAG;
  687. X    }
  688. X    | WAIT
  689. X    {
  690. X      $$ = WAIT_FLAG;
  691. X    }
  692. X    ;
  693. X
  694. Xitem : SHELL TEXT  TEXT  parms ';'
  695. X    {
  696. X      $$ = make_new_item($2, $3, parm_list, ITEM_SHELL);
  697. X      parm_list = (struct parm *)0;
  698. X      DEBUG3("shell item: line %d '%s'\n%%(\n%s\n%%)\n",
  699. X                 line_number, $2, $3);
  700. X    }
  701. X    | PRELUDE  TEXT  TEXT  parms ';'
  702. X    {
  703. X      $$ = make_new_item($2, $3, parm_list, ITEM_PRELUDE);
  704. X      parm_list = (struct parm *)0;
  705. X      DEBUG3("prelude item: line %d '%s'\n%%(\n%s\n%%)\n",
  706. X                 line_number, $2, $3);
  707. X    }
  708. X    | EPILOGUE  TEXT  TEXT  parms ';'
  709. X    {
  710. X      $$ = make_new_item($2, $3, parm_list, ITEM_EPILOGUE);
  711. X      parm_list = (struct parm *)0;
  712. X      DEBUG3("epilogue item: line %d '%s 'n%%(\n%s\n%%)\n",
  713. X                 line_number, $2, $3);
  714. X    }
  715. X    | DO_MENU NAME TEXT ';'
  716. X    {
  717. X      $$ = make_new_item($3, $2, (struct parm *)0, ITEM_MENU);
  718. X      DEBUG3("menu item: line %d \"%s\"\n'%s'\n",
  719. X                 line_number, $2, $3);
  720. X    }
  721. X    | SKIP ';'
  722. X    {
  723. X      $$ = make_new_item("SKIP", (char *)0, (struct parm *)0,
  724. X                 ITEM_SKIP);
  725. X      DEBUG1("skip item: line %d\n", line_number);
  726. X    }
  727. X    ;
  728. X
  729. Xparms : /* empty */
  730. X    | parms parm
  731. X    ;
  732. X
  733. Xparm : PARM NAME TEXT
  734. X    {
  735. X      $$ = make_new_parm(PARM_NO_DEFAULT, $2, $3, (char *)0);
  736. X      $$->next = parm_list;
  737. X      parm_list = $$;
  738. X      DEBUG2("parm: %s\n'%s'\n", $2, $3);
  739. X    }
  740. X    | PARM NAME '=' TEXT TEXT
  741. X    {
  742. X      $$ = make_new_parm(PARM_STATIC_DEFAULT, $2, $5, $4);
  743. X      $$->next = parm_list;
  744. X      parm_list = $$;
  745. X      DEBUG3("parm: %s = %s\n'%s'\n", $2, $4, $5);
  746. X    }
  747. X    ;
  748. X    | PARM NAME '=' NAME TEXT
  749. X    {
  750. X      $$ = make_new_parm(PARM_ENV_DEFAULT, $2, $5, $4);
  751. X      $$->next = parm_list;
  752. X      parm_list = $$;
  753. X      DEBUG3("parm: %s = \"%s\"\n'%s'\n", $2, $4, $5);
  754. X      if (!find_ev_var_by_name($4)) {
  755. X        yacc_errors++;
  756. X        fprintf(stderr, "parm initialized to non-existant environmental variable - line %s\n",
  757. X            line_number);
  758. X      }
  759. X    }
  760. X    ;
  761. X
  762. X%%
  763. END_OF_FILE
  764. if test 9787 -ne `wc -c <'grammar.y'`; then
  765.     echo shar: \"'grammar.y'\" unpacked with wrong size!
  766. fi
  767. # end of 'grammar.y'
  768. fi
  769. if test -f 'login.menu' -a "${1}" != "-c" ; then 
  770.   echo shar: Will not clobber existing file \"'login.menu'\"
  771. else
  772. echo shar: Extracting \"'login.menu'\" \(495 characters\)
  773. sed "s/^X//" >'login.menu' <<'END_OF_FILE'
  774. X#    a sample login menu
  775. X
  776. Xfrom-env "EDITOR" = 'vi' ;
  777. Xfrom-env "PAGER"  = 'more' ;
  778. X
  779. Xtitle 'Login Menu'
  780. X
  781. Xclear always-show
  782. X
  783. Xprelude 'checking for mail ...'
  784. X%( mail %)
  785. X;
  786. X
  787. Xepilogue 'checking for mail'
  788. X%( mail %)
  789. X;
  790. X
  791. Xshell 'Edit a File'
  792. X%( ${EDITOR} $FILE %)
  793. Xparm "FILE"='work.doc' 'Name of File to Edit'
  794. X;
  795. X
  796. Xshell 'Browse a File'
  797. X%( ${PAGER} $FILE %)
  798. Xparm "FILE"='work.doc' 'Name of File to View'
  799. X;
  800. X
  801. Xshell 'Mail to a User'
  802. X%( mail -s "$SUBJECT" $TO_WHOM %)
  803. Xparm "SUBJECT" 'Subject'
  804. Xparm "TO_WHOM" 'To'
  805. X;
  806. END_OF_FILE
  807. if test 495 -ne `wc -c <'login.menu'`; then
  808.     echo shar: \"'login.menu'\" unpacked with wrong size!
  809. fi
  810. # end of 'login.menu'
  811. fi
  812. if test -f 'menu.def' -a "${1}" != "-c" ; then 
  813.   echo shar: Will not clobber existing file \"'menu.def'\"
  814. else
  815. echo shar: Extracting \"'menu.def'\" \(2442 characters\)
  816. sed "s/^X//" >'menu.def' <<'END_OF_FILE'
  817. X# environment definitions
  818. X
  819. Xfrom-file './ev-values' "EV_FROMFILE_NO_INIT" ;
  820. X
  821. Xfrom-file './ev-values' "EV_FROMFILE_DEFINED" = 'value of file value' ;
  822. X
  823. Xfrom-file './ev-values' "EV_FROMEFILE_NOT_THERE" ;
  824. X
  825. Xfrom-env "EV_DEFINED" = 'value of EV_DEFINED' ;
  826. X
  827. Xfrom-env "EV_UNDEFINED" ;
  828. X
  829. X
  830. X#This is the beginning of the main menu
  831. X# since it is not named, the name will default to MAIN
  832. X
  833. Xtitle 'Test Menu'
  834. X
  835. X# clear will cause the screen to be cleared prior to each
  836. X#  redisplay.
  837. X# bold will cause the text 'Test Menu' to be displayed in
  838. X#  standout mode - if the terminal type is defined and supports
  839. X#  it
  840. X# always-show will cause the choices to always displayed
  841. X
  842. Xclear bold always-show
  843. X
  844. X# this is a simple example
  845. X
  846. Xshell 'First Item'
  847. X%( echo $PARM1 %)  # this is the shell script which will be executed
  848. Xparm "PARM1" 'Input Parm 1'  # this paramter is set by the user
  849. X;
  850. X
  851. Xshell 'Second Item'
  852. X%( echo "This is $PARM and $FOO and $BARF" %)
  853. Xparm "PARM" 'input value for PARM'
  854. Xparm "FOO"='foo value' 'input value for FOO'
  855. Xparm "BARF" = "EV_DEFINED" 'environment variable EV_DEFINED default'
  856. X;
  857. X
  858. Xshell 'Display all Menu-Environment Variables and values'
  859. X%(
  860. X  echo "EV_FROMFILE_NO_INIT: $EV_FROMFILE_NO_INIT"
  861. X  echo "EV_FROMFILE_DEFINED: $EV_FROMFILE_DEFINED"
  862. X  echo "EV_FROMEFILE_NOT_THERE: $EV_FROMEFILE_NOT_THERE"
  863. X  echo "EV_DEFINED: $EV_DEFINED"
  864. X  echo "EV_UNDEFINED: $EV_UNDEFINED"
  865. X%)
  866. X;
  867. X
  868. X# this will cause a line to be skipped so as to block the first
  869. X#  two items together
  870. X
  871. Xskip ;
  872. X
  873. Xshell 'Execute a Command'
  874. X%(
  875. X $CMD
  876. X%)
  877. Xparm "CMD" 'Command Line'
  878. X;
  879. X
  880. Xskip ;
  881. X
  882. X#  three types of sub-menus folow.  The first is an internal
  883. X#   sub menu defined later in this file
  884. X
  885. Xdo-menu "SUB_MENU" 'An Internal Submenu'
  886. X;
  887. X
  888. X# this is a sub menu defined in a second file
  889. X
  890. Xshell 'Another Submenu in a Separate File'
  891. X%(  ./simple_menu ./sub.menu %)
  892. X;
  893. X
  894. X#  this sub menu is constructed dynamically by building a
  895. X#  menu and feeding it to simple_menu
  896. X
  897. Xshell 'A Dynamically constructed Submenu'
  898. X%( awk -F: '
  899. XBEGIN {
  900. X  print "title %( A dynamically constructed submenu %%)"
  901. X  print "clear bold"
  902. X}
  903. X{
  904. X  print "shell %( Browse " $2 " %%) %( " pager " " $1 " %%) ;"
  905. X}
  906. X' pager=$PAGER directory | ./simple_menu  -
  907. X%)
  908. Xparm "PAGER" = 'more' 'name of your pager'
  909. X;
  910. X
  911. X# ============================================================
  912. X
  913. X# sub menu definition
  914. X
  915. Xmenu "SUB_MENU"
  916. X
  917. Xtitle 'a sub menu'
  918. X
  919. Xbold alpha once
  920. X
  921. Xshell 'spawn a shell'
  922. X%( /bin/sh -i %)
  923. X;
  924. X
  925. Xshell 'do nothing'
  926. X%( echo "did nothing" %)
  927. X;
  928. END_OF_FILE
  929. if test 2442 -ne `wc -c <'menu.def'`; then
  930.     echo shar: \"'menu.def'\" unpacked with wrong size!
  931. fi
  932. # end of 'menu.def'
  933. fi
  934. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  935.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  936. else
  937. echo shar: Extracting \"'patchlevel.h'\" \(21 characters\)
  938. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  939. X#define PATCHLEVEL 3
  940. END_OF_FILE
  941. if test 21 -ne `wc -c <'patchlevel.h'`; then
  942.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  943. fi
  944. # end of 'patchlevel.h'
  945. fi
  946. if test -f 'prototypes.h' -a "${1}" != "-c" ; then 
  947.   echo shar: Will not clobber existing file \"'prototypes.h'\"
  948. else
  949. echo shar: Extracting \"'prototypes.h'\" \(4212 characters\)
  950. sed "s/^X//" >'prototypes.h' <<'END_OF_FILE'
  951. X#ifdef PROTOTYPES_OK
  952. X
  953. X/* simple_menu.c */
  954. X
  955. Xint main(int /*argc*/, char ** /*argv*/);
  956. Xvoid display_parsed_menus(void);
  957. Xvoid init(int /*argc*/, char ** /*argv*/);
  958. Xstruct parm *make_new_parm(int /*flag*/, char * /*identifier*/, char * /*prompt*/, char * /*def_or_evname*/);
  959. Xstruct ev_var *make_new_ev_var(int /*flag*/, char * /*identifier*/, char * /*deflt*/, char * /*fname*/);
  960. Xstruct item *make_new_item(char * /*prompt*/, char * /*command*/, struct parm * /*parms*/, int /*action*/);
  961. Xstruct menu *make_new_menu(void);
  962. Xvoid init_environment(void);
  963. Xstruct ev_var *find_ev_var_by_name(char * /*name*/);
  964. Xvoid init_parm_defaults(void);
  965. Xvoid init_item_parm_defaults(struct item * /*i_ptr*/);
  966. Xvoid push_menu(struct menu * /*menu_ptr*/);
  967. Xint pop_menu(void);
  968. Xstruct menu *find_menu(char * /*name*/);
  969. Xint check_menu(void);
  970. Xvoid do_menu(void);
  971. Xvoid do_shell_script(struct item * /*selected_item*/);
  972. Xvoid do_prelude(void);
  973. Xvoid do_epilogue(void);
  974. Xvoid fatal(char * /*s*/);
  975. Xvoid trapoid(int /*sig*/);
  976. Xvoid do_longjmp(int /*sig*/);
  977. Xvoid wait_for_child(int /*pid*/);
  978. Xvoid set_signals(int /*flag*/);
  979. Xvoid reset_signals(void);
  980. Xint open_menu_file(void);
  981. Xint search_menu_path(char * /*path*/, char * /*fname*/);
  982. Xchar *Malloc(unsigned /*size*/);
  983. Xchar *Realloc(char * /*ptr*/, unsigned /*size*/);
  984. Xvoid yyerror(char * /*s*/);
  985. Xvoid prt_item(struct item * /*item_ptr*/);
  986. Xvoid simple_menu_exit(int /*code*/);
  987. X
  988. X/* grammar.c */
  989. X
  990. Xint yyparse(void);
  991. X
  992. X/* scanner.c */
  993. X
  994. Xint match_token(char * /*s*/);
  995. Xint make_lower(char /*c*/);
  996. Xint yylex(void);
  997. Xint scan_in_token_state(void);
  998. Xint scan_in_name_state(void);
  999. Xint scan_in_string_state(void);
  1000. Xint scan_in_text_state(void);
  1001. Xint scan_in_old_text_state(void);
  1002. Xvoid unget_char(char /*c*/);
  1003. Xint next_char(int /*fd*/);
  1004. Xvoid flush_char_input(void);
  1005. Xvoid add_char(char /*c*/);
  1006. Xvoid strip_white_space(void);
  1007. Xchar *take_saved_text(void);
  1008. X
  1009. X/* tty_display.c */
  1010. X
  1011. Xint outc(int /*c*/);
  1012. Xvoid init_terminal(void);
  1013. Xvoid close_terminal(void);
  1014. Xvoid display_menu(void);
  1015. Xchar *get_variable_value(char * /*prompt*/, char * /*deflt*/);
  1016. Xint get_user_rsp(void);
  1017. Xvoid do_pause(int /*flag*/);
  1018. X
  1019. X#else /* PROTOTYPES_OK */
  1020. X
  1021. X/* simple_menu.c */
  1022. X
  1023. Xint main(/*int argc, char **argv*/);
  1024. Xvoid display_parsed_menus(/*void*/);
  1025. Xvoid init(/*int argc, char **argv*/);
  1026. Xstruct parm *make_new_parm(/*int flag, char *identifier, char *prompt, char *def_or_evname*/);
  1027. Xstruct ev_var *make_new_ev_var(/*int flag, char *identifier, char *deflt, char *fname*/);
  1028. Xstruct item *make_new_item(/*char *prompt, char *command, struct parm *parms, int action*/);
  1029. Xstruct menu *make_new_menu(/*void*/);
  1030. Xvoid init_environment(/*void*/);
  1031. Xstruct ev_var *find_ev_var_by_name(/*char *name*/);
  1032. Xvoid init_parm_defaults(/*void*/);
  1033. Xvoid init_item_parm_defaults(/*struct item *i_ptr*/);
  1034. Xvoid push_menu(/*struct menu *menu_ptr*/);
  1035. Xint pop_menu(/*void*/);
  1036. Xstruct menu *find_menu(/*char *name*/);
  1037. Xint check_menu(/*void*/);
  1038. Xvoid do_menu(/*void*/);
  1039. Xvoid do_shell_script(/*struct item *selected_item*/);
  1040. Xvoid do_prelude(/*void*/);
  1041. Xvoid do_epilogue(/*void*/);
  1042. Xvoid fatal(/*char *s*/);
  1043. Xvoid trapoid(/*int sig*/);
  1044. Xvoid do_longjmp(/*int sig*/);
  1045. Xvoid wait_for_child(/*int pid*/);
  1046. Xvoid set_signals(/*int flag*/);
  1047. Xvoid reset_signals(/*void*/);
  1048. Xint open_menu_file(/*void*/);
  1049. Xint search_menu_path(/*char *path, char *fname*/);
  1050. Xchar *Malloc(/*unsigned size*/);
  1051. Xchar *Realloc(/*char *ptr, unsigned size*/);
  1052. Xvoid yyerror(/*char *s*/);
  1053. Xvoid prt_item(/*struct item *item_ptr*/);
  1054. Xvoid simple_menu_exit(/*int code*/);
  1055. X
  1056. X/* grammar.c */
  1057. X
  1058. Xint yyparse(/*void*/);
  1059. X
  1060. X/* scanner.c */
  1061. X
  1062. Xint match_token(/*char *s*/);
  1063. Xint make_lower(/*char c*/);
  1064. Xint yylex(/*void*/);
  1065. Xint scan_in_token_state(/*void*/);
  1066. Xint scan_in_name_state(/*void*/);
  1067. Xint scan_in_string_state(/*void*/);
  1068. Xint scan_in_text_state(/*void*/);
  1069. Xint scan_in_old_text_state(/*void*/);
  1070. Xvoid unget_char(/*char c*/);
  1071. Xint next_char(/*int fd*/);
  1072. Xvoid flush_char_input(/*void*/);
  1073. Xvoid add_char(/*char c*/);
  1074. Xvoid strip_white_space(/*void*/);
  1075. Xchar *take_saved_text(/*void*/);
  1076. X
  1077. X/* tty_display.c */
  1078. X
  1079. Xint outc(/*int c*/);
  1080. Xvoid init_terminal(/*void*/);
  1081. Xvoid close_terminal(/*void*/);
  1082. Xvoid display_menu(/*void*/);
  1083. Xchar *get_variable_value(/*char *prompt, char *deflt*/);
  1084. Xint get_user_rsp(/*void*/);
  1085. Xvoid do_pause(/*int flag*/);
  1086. X#endif /* PROTOTYPES_OK */
  1087. END_OF_FILE
  1088. if test 4212 -ne `wc -c <'prototypes.h'`; then
  1089.     echo shar: \"'prototypes.h'\" unpacked with wrong size!
  1090. fi
  1091. # end of 'prototypes.h'
  1092. fi
  1093. if test -f 'scanner.c' -a "${1}" != "-c" ; then 
  1094.   echo shar: Will not clobber existing file \"'scanner.c'\"
  1095. else
  1096. echo shar: Extracting \"'scanner.c'\" \(6770 characters\)
  1097. sed "s/^X//" >'scanner.c' <<'END_OF_FILE'
  1098. X/* %W% %D% */
  1099. X/* copyrite (c) Mike Howard, 1990, 1991 */
  1100. X
  1101. X#include <stdio.h>
  1102. X#include <ctype.h>
  1103. X#include "y.tab.h"
  1104. X#include "simple_menu.h"
  1105. X
  1106. Xextern int debug_mode;
  1107. Xextern int lex_errors;
  1108. Xextern int line_number;
  1109. X
  1110. Xchar *saved_text;
  1111. Xchar *Malloc();
  1112. Xchar *Realloc();
  1113. X
  1114. Xstruct word_cell {
  1115. X  char *name;
  1116. X  int value;
  1117. X};
  1118. X
  1119. Xstruct word_cell word_list[] =  {
  1120. X"ERROR", ERROR,
  1121. X"item", SHELL,       /* left over dinosaur */
  1122. X"shell", SHELL,
  1123. X"parm", PARM,
  1124. X"title", TITLE,
  1125. X"clear", CLEAR,
  1126. X"bold", BOLD,
  1127. X"always-show", ALWAYS_SHOW,
  1128. X"once", ONCE,
  1129. X"prelude", PRELUDE,
  1130. X"epilogue", EPILOGUE,
  1131. X"menu", MENU,
  1132. X"do-menu", DO_MENU,
  1133. X"skip", SKIP,
  1134. X"alpha", ALPHA,
  1135. X"wait", WAIT,
  1136. X"shell-path", SHELL_PATH,
  1137. X"asg-fmt", ASG_FMT,
  1138. X"from-env", FROM_ENV,
  1139. X"from-file", FROM_FILE,
  1140. X(char *)0, -1 };
  1141. X
  1142. Xint
  1143. Xmatch_token(s)
  1144. X     char *s;
  1145. X{
  1146. X  int i;
  1147. X
  1148. X  for (i=1;word_list[i].name;i++) {
  1149. X    if (*s == word_list[i].name[0] && !strcmp(s, word_list[i].name))
  1150. X      return i;
  1151. X  }
  1152. X
  1153. X  lex_errors++;
  1154. X  return 0;
  1155. X}
  1156. X
  1157. Xint
  1158. Xmake_lower(c)
  1159. X     char c;
  1160. X{
  1161. X  return isupper(c) ? tolower(c) : c;
  1162. X}
  1163. X
  1164. X/* this thing is a state machine - of sorts.  */
  1165. X
  1166. Xint
  1167. Xyylex()
  1168. X{
  1169. X  char c;
  1170. X
  1171. X  while (1) {
  1172. X    while (isspace(c = next_char(0)))
  1173. X      ;
  1174. X    switch (c) {
  1175. X    case '"':
  1176. X      return scan_in_name_state();
  1177. X    case '{':
  1178. X      return scan_in_old_text_state();
  1179. X    case '\0':
  1180. X      return 0;
  1181. X    case '%':
  1182. X      if ((c = next_char(0)) == '(')
  1183. X    return scan_in_text_state();
  1184. X      unget_char(c);
  1185. X      unget_char('%');
  1186. X      return scan_in_token_state();
  1187. X    case '\'':
  1188. X      return scan_in_string_state();
  1189. X    case '#':
  1190. X      while (c && c != '\n')
  1191. X    c = next_char(0);
  1192. X      break;
  1193. X    case ';':
  1194. X    case '=':
  1195. X      VDEBUG2("scanner: line %d - returning %c\n", line_number, c);
  1196. X      return c;
  1197. X    default:
  1198. X      unget_char(c);
  1199. X      return scan_in_token_state();
  1200. X    }
  1201. X  }
  1202. X}
  1203. X
  1204. Xint
  1205. Xscan_in_token_state()
  1206. X{
  1207. X  char c;
  1208. X  int ret;
  1209. X
  1210. X  while (isalpha(c = make_lower(next_char(0))) || c == '-')
  1211. X    add_char(c);
  1212. X
  1213. X  unget_char(c);
  1214. X  ret = match_token(saved_text);
  1215. X  VDEBUG3("scanner: line %d: token: %s matches %s\n", line_number,
  1216. X     saved_text, word_list[ret].name);
  1217. X  free(saved_text);
  1218. X  saved_text = (char *)0;
  1219. X
  1220. X  return word_list[ret].value;
  1221. X}
  1222. X
  1223. Xint
  1224. Xscan_in_name_state()
  1225. X{
  1226. X  char c;
  1227. X
  1228. X  while (1) {
  1229. X    c = next_char(0);
  1230. X    if (isalnum(c) || c == '_')
  1231. X      add_char(c);
  1232. X    else if (c == '"') {
  1233. X      strip_white_space();
  1234. X      yylval.txt = take_saved_text();
  1235. X      VDEBUG2("scanner: line %d - found Name: \"%s\"\n", line_number,
  1236. X         yylval.txt);
  1237. X      return NAME;
  1238. X    }
  1239. X    else {
  1240. X      printf("error in line %d - bad character (%c) in name\n",
  1241. X         line_number, c);
  1242. X      while (c && !isspace(c))
  1243. X    c = next_char(0);
  1244. X      unget_char(c);
  1245. X      lex_errors++;
  1246. X      return ERROR;
  1247. X    }
  1248. X  }
  1249. X}
  1250. X
  1251. X/* scans for ' delimited plain text - translates '' into ' */
  1252. X
  1253. Xint scan_in_string_state()
  1254. X{
  1255. X  char c;
  1256. X
  1257. X  while (1) {
  1258. X    switch (c = next_char(0)) {
  1259. X    case 0:
  1260. X      printf("error in line %d - premature end of text\n", line_number);
  1261. X      lex_errors++;
  1262. X      return ERROR;
  1263. X    case '\'':
  1264. X      if ((c = next_char(0)) != '\'') {
  1265. X    strip_white_space();
  1266. X    yylval.txt = take_saved_text();
  1267. X    VDEBUG2("scanner: line %d - found Text-String\n'%s'\n",
  1268. X           line_number, yylval.txt);
  1269. X    return TEXT;
  1270. X      }
  1271. X      add_char('\'');
  1272. X      break;
  1273. X    default:
  1274. X      add_char(c);
  1275. X      break;
  1276. X    }
  1277. X  }
  1278. X}
  1279. X
  1280. X/* scans for %( %) delimited text - a %) may be embedded if written %%) */
  1281. X
  1282. Xint scan_in_text_state()
  1283. X{
  1284. X  char c;
  1285. X
  1286. X  while (1) {
  1287. X    switch (c = next_char(0)) {
  1288. X    case 0:
  1289. X      printf("error in line %d - premature end of text\n", line_number);
  1290. X      lex_errors++;
  1291. X      return ERROR;
  1292. X    case '%':
  1293. X      if ((c = next_char(0)) == ')') {
  1294. X    strip_white_space();
  1295. X    yylval.txt = take_saved_text();
  1296. X    VDEBUG2("scanner: line %d - found Text-String\n%(\n%s\n%)\n",
  1297. X        line_number, yylval.txt);
  1298. X    return TEXT;
  1299. X      }
  1300. X      if (c == '%') {
  1301. X    if ((c = next_char(0)) == ')' || c == '(') {
  1302. X      add_char('%');
  1303. X      add_char(c);
  1304. X      break;
  1305. X    }
  1306. X    /* back up two characters and restart */
  1307. X    unget_char(c);
  1308. X    c = '%';
  1309. X    break;
  1310. X      }
  1311. X      unget_char(c);
  1312. X      add_char('%');
  1313. X      break;
  1314. X    default:
  1315. X      add_char(c);
  1316. X      break;
  1317. X    }
  1318. X  }
  1319. X}
  1320. X
  1321. Xint
  1322. Xscan_in_old_text_state()
  1323. X{
  1324. X  char c;
  1325. X
  1326. X  while (1) {
  1327. X    switch (c = next_char(0)) {
  1328. X    case 0:
  1329. X      printf("error in line %d - premature end of text\n", line_number);
  1330. X      lex_errors++;
  1331. X      return ERROR;
  1332. X    case '\\':
  1333. X      switch(c = next_char(0)) {
  1334. X      case '\\':
  1335. X      case '}':
  1336. X    add_char(c);
  1337. X    break;
  1338. X      default:
  1339. X    add_char('\\');
  1340. X    add_char(c);
  1341. X    break;
  1342. X      }
  1343. X      break;
  1344. X    case '}':
  1345. X      strip_white_space();
  1346. X      yylval.txt = take_saved_text();
  1347. X      VDEBUG2("scanner: line %d - found old style Text-String\n{\n%s\n}\n",
  1348. X          line_number, yylval.txt);
  1349. X      return TEXT;
  1350. X    default:
  1351. X      add_char(c);
  1352. X      break;
  1353. X    }
  1354. X  }
  1355. X}
  1356. X
  1357. X#define CHAR_BUFSIZE  1024
  1358. Xunsigned char char_buf[CHAR_BUFSIZE];
  1359. Xint chars_left;
  1360. Xunsigned char *nxt_char;
  1361. X#define UNGET_BUFSIZE 128
  1362. Xchar unget_buf[UNGET_BUFSIZE];
  1363. Xint unget_len;
  1364. X
  1365. XVOID
  1366. Xunget_char(c)
  1367. X     char c;
  1368. X{
  1369. X  if ((unget_buf[unget_len++] = c) == '\n')
  1370. X    line_number--;
  1371. X}
  1372. X
  1373. Xint
  1374. Xnext_char(fd)
  1375. Xint fd;
  1376. X{
  1377. X  int c;
  1378. X
  1379. X  if (unget_len > 0) {
  1380. X    c = unget_buf[--unget_len];
  1381. X  }
  1382. X  else {
  1383. X    if (chars_left <= 0) {
  1384. X      if ((chars_left = read(fd, char_buf, CHAR_BUFSIZE)) <= 0)
  1385. X    return 0;
  1386. X      nxt_char = char_buf;
  1387. X    }
  1388. X
  1389. X    c = *nxt_char++;
  1390. X    chars_left--;
  1391. X  }
  1392. X
  1393. X  if (c == '\n')
  1394. X    line_number++;
  1395. X
  1396. X  return c;
  1397. X}
  1398. X
  1399. XVOID flush_char_input()
  1400. X{
  1401. X  chars_left =
  1402. X    unget_len = 0;
  1403. X}
  1404. X
  1405. X#define INIT_SIZE    256
  1406. X#define INC_SIZE    64
  1407. X
  1408. X
  1409. XVOID
  1410. Xadd_char(c)
  1411. X     char c;
  1412. X{
  1413. X  static int saved_length;
  1414. X  static int room_left;
  1415. X  static int saved_size;
  1416. X
  1417. X  if (!saved_text) {
  1418. X    memset(saved_text = Malloc(INIT_SIZE), '\0', INIT_SIZE);
  1419. X    room_left = INIT_SIZE;
  1420. X    saved_size = INIT_SIZE;
  1421. X    saved_length = 0;
  1422. X  }
  1423. X
  1424. X  if (room_left < 2) {
  1425. X    saved_text = Realloc(saved_text, saved_size += INC_SIZE);
  1426. X    room_left += INC_SIZE;
  1427. X  }
  1428. X
  1429. X  saved_text[saved_length++] = c;
  1430. X  saved_text[saved_length] = '\0';
  1431. X  room_left--;
  1432. X}
  1433. X
  1434. X
  1435. XVOID
  1436. Xstrip_white_space()
  1437. X{
  1438. X  char *cp;
  1439. X  char *sp;
  1440. X
  1441. X  if (!saved_text)
  1442. X    return;
  1443. X
  1444. X  for (cp = saved_text + strlen(saved_text) - 1;cp > saved_text;cp--) {
  1445. X    if (!isspace(*cp))
  1446. X      break;
  1447. X  }
  1448. X  *++cp = '\0';
  1449. X
  1450. X  for (cp=saved_text;*cp && isspace(*cp);cp++)
  1451. X    ;
  1452. X
  1453. X  /* is it all white? */
  1454. X  if (!*cp && cp > saved_text) {
  1455. X    saved_text = Realloc(saved_text, 1);
  1456. X    *saved_text = '\0';
  1457. X    return;
  1458. X  }
  1459. X
  1460. X  /* is there any leading white space? */
  1461. X  if (cp > saved_text) {
  1462. X    char *tmp;
  1463. X    int len;
  1464. X
  1465. X    tmp = Malloc(len = strlen(cp) + 1);
  1466. X    memcpy(tmp, cp, len);
  1467. X    free(saved_text);
  1468. X    saved_text = tmp;
  1469. X
  1470. X    return;
  1471. X  }
  1472. X
  1473. X  saved_text = Realloc(saved_text, strlen(saved_text) + 1);
  1474. X}
  1475. X
  1476. Xchar *
  1477. Xtake_saved_text()
  1478. X{
  1479. X  char *cp = saved_text;
  1480. X
  1481. X  saved_text = (char *)0;
  1482. X
  1483. X  return cp;
  1484. X}
  1485. END_OF_FILE
  1486. if test 6770 -ne `wc -c <'scanner.c'`; then
  1487.     echo shar: \"'scanner.c'\" unpacked with wrong size!
  1488. fi
  1489. # end of 'scanner.c'
  1490. fi
  1491. if test -f 'simple_menu.h' -a "${1}" != "-c" ; then 
  1492.   echo shar: Will not clobber existing file \"'simple_menu.h'\"
  1493. else
  1494. echo shar: Extracting \"'simple_menu.h'\" \(3804 characters\)
  1495. sed "s/^X//" >'simple_menu.h' <<'END_OF_FILE'
  1496. X/* %W% %D% */
  1497. X/* copyrite (c) Mike Howard, 1990, 1991 */
  1498. X
  1499. X/* #define VOID  void or int is expected to occur in the compilation line */
  1500. X#ifndef VOID
  1501. X# define VOID void
  1502. X#endif
  1503. X
  1504. X/* include some common stuff */
  1505. X#ifndef FILE
  1506. X# include <stdio.h>
  1507. X#endif
  1508. X#include <setjmp.h>
  1509. X
  1510. X#define EV_FROM_FILE 1
  1511. X#define EV_FROM_ENV  2
  1512. X
  1513. Xstruct ev_var {
  1514. X  struct ev_var *next;
  1515. X  char *identifier;
  1516. X  char *value;
  1517. X  char *deflt;
  1518. X  char *file_name;
  1519. X  int   flag;
  1520. X};
  1521. X
  1522. X#define PARM_NO_DEFAULT       0
  1523. X#define PARM_STATIC_DEFAULT   1
  1524. X#define PARM_ENV_DEFAULT      2
  1525. X
  1526. Xstruct parm {
  1527. X  struct parm *next;
  1528. X  char *prompt;
  1529. X  char *identifier;
  1530. X  char *value;
  1531. X  char *def_or_evname;
  1532. X  int   flag;
  1533. X};
  1534. X
  1535. X#define ITEM_SHELL       1
  1536. X#define ITEM_MENU        2
  1537. X#define ITEM_SKIP        3
  1538. X#define ITEM_PRELUDE     4
  1539. X#define ITEM_EPILOGUE    5
  1540. X
  1541. X
  1542. Xstruct item {
  1543. X  struct item *next;
  1544. X  int action;
  1545. X  int item_idx;
  1546. X  char *prompt;
  1547. X  char *command;
  1548. X  struct parm *parms;
  1549. X};
  1550. X
  1551. X#define CLEAR_FLAG                1
  1552. X#define BOLD_FLAG                 2
  1553. X#define ALWAYS_DISPLAY_FLAG       4
  1554. X#define ONCE_FLAG                 8
  1555. X#define ALPHA_FLAG               16
  1556. X#define WAIT_FLAG                32
  1557. X#define Clear_Flag    (clear_flag&&(active_menu->flags&CLEAR_FLAG))
  1558. X#define Bold_Flag    (bold_flag&&(active_menu->flags&BOLD_FLAG))
  1559. X#define Always_Display_Flag    (active_menu->flags&ALWAYS_DISPLAY_FLAG)
  1560. X#define Once_Flag       (active_menu->flags&ONCE_FLAG)
  1561. X#define Alpha_Flag      (active_menu->flags&ALPHA_FLAG)
  1562. X#define Wait_Flag       (active_menu->flags&WAIT_FLAG)
  1563. X
  1564. Xstruct menu {
  1565. X  struct menu *next;
  1566. X  struct menu *menu_stack_ptr;
  1567. X  struct item *item_head;
  1568. X  struct item *item_tail;
  1569. X  struct item *prelude;
  1570. X  struct item *epilogue;
  1571. X  char *menu_name;
  1572. X  char *menu_title;
  1573. X  char *short_title;
  1574. X  int max_item;
  1575. X  int flags;
  1576. X};
  1577. X
  1578. X#define DEBUG0(fmt)    if(debug_mode>1)printf(fmt);
  1579. X#define DEBUG1(fmt,aa)    if(debug_mode>1)printf(fmt,aa);
  1580. X#define DEBUG2(fmt,aa,bb)    if(debug_mode>1)printf(fmt,aa,bb);
  1581. X#define DEBUG3(fmt,aa,bb,cc)    if(debug_mode>1)printf(fmt,aa,bb,cc);
  1582. X
  1583. X#define VDEBUG0(fmt)    if(debug_mode>2)printf(fmt);
  1584. X#define VDEBUG1(fmt,aa)    if(debug_mode>2)printf(fmt,aa);
  1585. X#define VDEBUG2(fmt,aa,bb)    if(debug_mode>2)printf(fmt,aa,bb);
  1586. X#define VDEBUG3(fmt,aa,bb,cc)    if(debug_mode>2)printf(fmt,aa,bb,cc);
  1587. X
  1588. X/* data declarations and initializations */
  1589. X#ifdef MAIN
  1590. X# define EXTERN
  1591. X#else
  1592. X# define EXTERN extern
  1593. X#endif
  1594. X
  1595. X/* capability flags - set by init_terminal */
  1596. XEXTERN int clear_flag;
  1597. XEXTERN int bold_flag;
  1598. X
  1599. XEXTERN struct menu *menu_list_head;
  1600. XEXTERN struct menu *menu_list_tail;
  1601. XEXTERN struct menu *active_menu;
  1602. X
  1603. XEXTERN struct parm *parm_list;
  1604. XEXTERN struct ev_var *environment_list;
  1605. X
  1606. XEXTERN char *user_rsp;
  1607. XEXTERN int default_timeout;
  1608. X
  1609. XEXTERN int lex_errors;
  1610. XEXTERN int yacc_errors;
  1611. XEXTERN int line_number;
  1612. X
  1613. X
  1614. X
  1615. Xextern char *optarg;
  1616. Xextern int optind, opterr;
  1617. XEXTERN int tty_in;
  1618. XEXTERN char *tty_fname;
  1619. XEXTERN char *ttyname();
  1620. XEXTERN int argcc;
  1621. XEXTERN char **argvv;
  1622. XEXTERN char *progname;
  1623. XEXTERN char *in_fname;
  1624. XEXTERN char *menu_fname;
  1625. X#define MENU_FNAME "menu.def"
  1626. XEXTERN char *menu_path;
  1627. X#ifndef DEFAULT_MENU_PATH
  1628. X# define DEFAULT_MENU_PATH \
  1629. X   "/usr/local/lib/simple_menu:/usr/local/lib/dumb_menu"
  1630. X#endif /* DEFAULT_MENU_PATH */
  1631. XEXTERN char *cmd_path;
  1632. XEXTERN char *asg_fmt;
  1633. XEXTERN char *cmd_name;
  1634. X
  1635. XEXTERN struct item *selected_item;
  1636. XEXTERN struct parm *selected_parms;
  1637. XEXTERN FILE *tmp_file;
  1638. XEXTERN char *tmp_fname;
  1639. X
  1640. X/* flags */
  1641. XEXTERN int verbose;
  1642. XEXTERN int debug_mode;
  1643. X
  1644. XEXTERN int display_menu_flag;
  1645. XEXTERN jmp_buf env;
  1646. X#define SIGS_FOR_JMP   1
  1647. X#define SIGS_FOR_CHILD 2
  1648. X
  1649. X#ifdef MAIN
  1650. X
  1651. Xchar *use_msg = "usage: %s (patchlevel %d) [-h | option(s)] [menu-file | -]\n";
  1652. Xchar *item_types[] = {
  1653. X"none",
  1654. X"Shell Item",
  1655. X"Menu Item",
  1656. X"Skip Item",
  1657. X"Prelude Item",
  1658. X"Epilogue Item",
  1659. X(char *)0 };
  1660. X#else
  1661. Xextern char *use_msg;
  1662. Xextern char *item_types[];
  1663. X#endif
  1664. X
  1665. X#include "prototypes.h"
  1666. END_OF_FILE
  1667. if test 3804 -ne `wc -c <'simple_menu.h'`; then
  1668.     echo shar: \"'simple_menu.h'\" unpacked with wrong size!
  1669. fi
  1670. # end of 'simple_menu.h'
  1671. fi
  1672. if test -f 'sub.menu' -a "${1}" != "-c" ; then 
  1673.   echo shar: Will not clobber existing file \"'sub.menu'\"
  1674. else
  1675. echo shar: Extracting \"'sub.menu'\" \(226 characters\)
  1676. sed "s/^X//" >'sub.menu' <<'END_OF_FILE'
  1677. X
  1678. Xtitle 'A non-descript submenu
  1679. XWith a multi-line
  1680. X   title'
  1681. X
  1682. Xclear wait
  1683. X
  1684. Xshell 'Sub-Item 1
  1685. X     long prompt'
  1686. X%( echo "Sub-Item 1" %)
  1687. X;
  1688. X
  1689. Xshell 'Sub-Item 2'
  1690. X%( echo "Sub-Item 2" %)
  1691. X;
  1692. X
  1693. Xshell 'Sub-Item 3'
  1694. X%( echo "Sub-Item 3" %)
  1695. X;
  1696. END_OF_FILE
  1697. if test 226 -ne `wc -c <'sub.menu'`; then
  1698.     echo shar: \"'sub.menu'\" unpacked with wrong size!
  1699. fi
  1700. # end of 'sub.menu'
  1701. fi
  1702. if test -f 'tty_display.c' -a "${1}" != "-c" ; then 
  1703.   echo shar: Will not clobber existing file \"'tty_display.c'\"
  1704. else
  1705. echo shar: Extracting \"'tty_display.c'\" \(8253 characters\)
  1706. sed "s/^X//" >'tty_display.c' <<'END_OF_FILE'
  1707. X/* %W% %D% */
  1708. X
  1709. Xstatic char *cpy_str =
  1710. X  "Copyright (c), Mike Howard, 1990,1991 all rights reserved";
  1711. X
  1712. X/* Conditions of use:
  1713. X
  1714. X   This software is not for sale and is not to be sold by or
  1715. X   to anyone.
  1716. X
  1717. X   You may use this software and may distribute it to anyone
  1718. X   you wish to provided you distribute the entire distribution
  1719. X   package w/o any deletions (i.e. include all the source code).
  1720. X
  1721. X   I do not warrent this software to do anything at all and
  1722. X   am not responsible for anything which happens as a result of
  1723. X   its use.
  1724. X*/
  1725. X
  1726. X/* this is the display dependant part which knows how to talk to character
  1727. X   terminals
  1728. X
  1729. X   must define 4 functions:
  1730. X   init_terminal() - initializes the display - a tty for tty based stuff
  1731. X   display_menu() - draws the menu on the display
  1732. X   prepare_for_subshell() - this and the companion routine do whatever
  1733. X   return_from_subshell() -  is required to the display to run a subshell
  1734. X   close_terminal() - does whatever closedown is required for terminal
  1735. X   get_user_rsp() - returns single character user choice.
  1736. X   get_variable_value(prompt, def) - returns Malloc'ed value of parameter
  1737. X                                 after talking to user
  1738. X   do_pause(flag) - implements a timed pause.  It should return after a user
  1739. X                    action or default_timeout seconds have passed.  The
  1740. X            flag is 0 for an illegal menu choice and 1 if exiting
  1741. X            a menu
  1742. X*/
  1743. X
  1744. X#include <stdio.h>
  1745. X#include <fcntl.h>
  1746. X#include <string.h>
  1747. X#include <signal.h>
  1748. X#include <ctype.h>
  1749. X
  1750. X#include "simple_menu.h"
  1751. X#include "patchlevel.h"
  1752. X
  1753. X#ifdef TERMCAP
  1754. Xchar tty_bp[1024];
  1755. Xchar tty_caps[1024];
  1756. Xchar *term_cm;
  1757. Xchar *term_so;
  1758. Xchar *term_se;
  1759. Xint term_sg;
  1760. Xchar *term_cl;
  1761. Xint term_lines;
  1762. Xchar PC;
  1763. Xchar *BC;
  1764. Xchar *UP;
  1765. Xshort ospeed;
  1766. X
  1767. Xint
  1768. Xoutc(c)
  1769. X     int c;
  1770. X{
  1771. X  putc(c, stdout);
  1772. X}
  1773. X
  1774. XVOID
  1775. Xinit_terminal()
  1776. X{
  1777. X  char *getenv();
  1778. X  char *tty_type = getenv("TERM");
  1779. X  char *cp = tty_caps;
  1780. X  char *tgetstr();
  1781. X
  1782. X  /* assumes fd's 0, 1, & 2 are closed */
  1783. X  tty_fname = ttyname(1);
  1784. X  if (!isatty(1) || (tty_in = open(tty_fname, O_RDWR)) < 0)
  1785. X    fatal("cannot open tty - must be run interactively");
  1786. X  close(0);
  1787. X  close(1);
  1788. X  close(2);
  1789. X  dup(tty_in);
  1790. X  dup(tty_in);
  1791. X  close(tty_in);
  1792. X
  1793. X  if (!tty_type || tgetent(tty_bp, tty_type) <= 0) {
  1794. X    clear_flag =
  1795. X      bold_flag = 0;
  1796. X    return;
  1797. X  }
  1798. X
  1799. X  PC = (BC = tgetstr("pc", &cp)) ? *BC : '\0';
  1800. X  BC = tgetstr("bc", &cp);
  1801. X  UP = tgetstr("up", &cp);
  1802. X#ifdef TERMIO
  1803. X  {
  1804. X#include <termio.h>
  1805. X
  1806. X    struct termio termio;
  1807. X
  1808. X    ioctl(0, TCGETA, &termio);
  1809. X    ospeed = termio.c_cflag & CBAUD;
  1810. X  }
  1811. X#undef ECHO /* conflicts with lex code */
  1812. X#endif /* TERMIO */
  1813. X#ifdef BSDTTY
  1814. X  {
  1815. X#include <sgtty.h>
  1816. X    struct sgttyb sgttyb;
  1817. X
  1818. X    ioctl(0, TIOCGETP, &sgttyb);
  1819. X    ospeed = sgttyb.sg_ospeed;
  1820. X  }
  1821. X#endif /* BSDTTY */
  1822. X
  1823. X  term_cm = tgetstr("cm", &cp);
  1824. X  term_so = tgetstr("so", &cp);
  1825. X  term_se = tgetstr("se", &cp);
  1826. X  term_sg = tgetnum("sg");
  1827. X  bold_flag = term_so ? 1 : 0;
  1828. X
  1829. X  term_cl = tgetstr("cl", &cp);
  1830. X  term_lines = tgetnum("li");
  1831. X  clear_flag = term_cl ? 1 : 0;
  1832. X
  1833. X  flush_char_input();
  1834. X}
  1835. X
  1836. XVOID
  1837. Xclose_terminal()
  1838. X{
  1839. X}
  1840. X
  1841. XVOID
  1842. Xprepare_for_subshell()
  1843. X{
  1844. X}
  1845. X
  1846. XVOID
  1847. Xreturn_from_subshell()
  1848. X{
  1849. X}
  1850. X
  1851. XVOID
  1852. Xdisplay_menu()
  1853. X{
  1854. X  struct item *ptr;
  1855. X  int i;
  1856. X
  1857. X  /* if we clear the screen, then do it, otherwise skip a line */
  1858. X  if (Clear_Flag)
  1859. X    tputs(term_cl, term_lines, outc);
  1860. X  else
  1861. X    putc('\n', stdout);
  1862. X
  1863. X  /* this is not correct for magic cookie tubes - solving that problem
  1864. X     requires counting lines in menu_title, maintaining line counts in the
  1865. X     case we don't clear-screen-before-displaying, cursor positioning
  1866. X     sequences, ... AND having a known tube environment - i.e. no one
  1867. X     has reprogrammed something for their own purposes.  So, if you
  1868. X     have any such tube, it will probably flash if you set the
  1869. X     bold flag     */
  1870. X  if (Bold_Flag) {
  1871. X    tputs(term_so, 1, outc);
  1872. X    printf("%s", active_menu->menu_title);
  1873. X    tputs(term_se, 1, outc);
  1874. X    putc('\n', stdout);
  1875. X  }
  1876. X  else
  1877. X    printf("%s\n", active_menu->menu_title);
  1878. X
  1879. X  if (display_menu_flag) {
  1880. X    for (ptr=active_menu->item_head;ptr;ptr = ptr->next) {
  1881. X      switch (ptr->action) {
  1882. X      case ITEM_SKIP:
  1883. X    putchar('\n');
  1884. X    break;
  1885. X      default:
  1886. X    if (Alpha_Flag)
  1887. X      printf("%c. %s\n", 'A' + ptr->item_idx - 1, ptr->prompt);
  1888. X    else
  1889. X      printf("%2d. %s\n", ptr->item_idx, ptr->prompt);
  1890. X    break;
  1891. X      }
  1892. X    }
  1893. X  }
  1894. X
  1895. X  if (Once_Flag)
  1896. X    printf("Choice? ");
  1897. X  else if (Always_Display_Flag)
  1898. X    printf("Q) to End - choice? ");
  1899. X  else
  1900. X    printf("Q) to End, ?) for Menu - choice? ");
  1901. X  fflush(stdout);
  1902. X
  1903. X  display_menu_flag = Always_Display_Flag;
  1904. X}
  1905. X#endif /* TERMCAP */
  1906. X
  1907. X#ifdef TERMINFO
  1908. X
  1909. Xint havecalled_setupterm;
  1910. X#include <curses.h>
  1911. X#include <term.h>
  1912. X
  1913. XVOID
  1914. Xinit_terminal()
  1915. X{
  1916. X
  1917. X  /* assumes fd's 0, 1, & 2 are closed */
  1918. X  tty_fname = ttyname(1);
  1919. X  if (!isatty(1) || (tty_in = open(tty_fname, O_RDWR)) < 0)
  1920. X    fatal("cannot open tty - must be run interactively");
  1921. X  close(0);
  1922. X  close(1);
  1923. X  close(2);
  1924. X  dup(tty_in);
  1925. X  dup(tty_in);
  1926. X  close(tty_in);
  1927. X
  1928. X
  1929. X  setupterm((char *)0, 1, &havecalled_setupterm);
  1930. X  if (havecalled_setupterm != 1) {
  1931. X    clear_flag =
  1932. X      bold_flag = 0;
  1933. X    return;
  1934. X  }
  1935. X
  1936. X  if (clear_screen)
  1937. X    clear_flag++;
  1938. X  if (enter_standout_mode)
  1939. X    bold_flag++;
  1940. X
  1941. X  flush_char_input();
  1942. X}
  1943. X
  1944. XVOID
  1945. Xclose_terminal()
  1946. X{
  1947. X  if (havecalled_setupterm)
  1948. X    resetterm();
  1949. X}
  1950. X
  1951. XVOID
  1952. Xprepare_for_subshell()
  1953. X{
  1954. X  if (havecalled_setupterm)
  1955. X    resetterm();
  1956. X}
  1957. X
  1958. XVOID
  1959. Xreturn_from_subshell()
  1960. X{
  1961. X  if (havecalled_setupterm)
  1962. X    fixterm();
  1963. X}
  1964. X
  1965. XVOID
  1966. Xdisplay_menu()
  1967. X{
  1968. X  struct item *ptr;
  1969. X  int i;
  1970. X
  1971. X  /* if we clear the screen, then do it, otherwise skip a line */
  1972. X  if (Clear_Flag)
  1973. X    putp(clear_screen);
  1974. X  else
  1975. X    putc('\n', stdout);
  1976. X
  1977. X  /* this is not correct for magic cookie tubes - solving that problem
  1978. X     requires counting lines in menu_title, maintaining line counts in the
  1979. X     case we don't clear-screen-before-displaying, cursor positioning
  1980. X     sequences, ... AND having a known tube environment - i.e. no one
  1981. X     has reprogrammed something for their own purposes.  So, if you
  1982. X     have any such tube, it will probably flash if you set the
  1983. X     bold flag     */
  1984. X  if (Bold_Flag) {
  1985. X    putp(enter_standout_mode);
  1986. X    printf("%s", active_menu->menu_title);
  1987. X    putp(exit_standout_mode);
  1988. X    putc('\n', stdout);
  1989. X  }
  1990. X  else
  1991. X    printf("%s\n", active_menu->menu_title);
  1992. X
  1993. X  if (display_menu_flag) {
  1994. X    for (ptr=active_menu->item_head;ptr;ptr = ptr->next) {
  1995. X      switch (ptr->action) {
  1996. X      case ITEM_SKIP:
  1997. X    putchar('\n');
  1998. X    break;
  1999. X      default:
  2000. X    if (Alpha_Flag)
  2001. X      printf("%c. %s\n", 'A' + ptr->item_idx - 1, ptr->prompt);
  2002. X    else
  2003. X      printf("%2d. %s\n", ptr->item_idx, ptr->prompt);
  2004. X    break;
  2005. X      }
  2006. X    }
  2007. X  }
  2008. X
  2009. X  if (Once_Flag)
  2010. X    printf("Choice? ");
  2011. X  else if (Always_Display_Flag)
  2012. X    printf("Q) to End - choice? ");
  2013. X  else
  2014. X    printf("Q) to End, ?) for Menu - choice? ");
  2015. X  fflush(stdout);
  2016. X
  2017. X  display_menu_flag = Always_Display_Flag;
  2018. X}
  2019. X#endif /* TERMINFO */
  2020. X
  2021. Xchar *
  2022. Xget_variable_value(prompt, deflt)
  2023. Xchar *prompt;
  2024. Xchar *deflt;
  2025. X{
  2026. X  char *cp;
  2027. X  int c;
  2028. X
  2029. X  printf("%s[%s]: ", prompt, deflt);
  2030. X  fflush(stdout);
  2031. X  while ((c = next_char(0)) && c != '\n')
  2032. X    add_char(c);
  2033. X
  2034. X  if ((cp = take_saved_text()) && strlen(cp)) {
  2035. X    return cp;
  2036. X  }
  2037. X  else if (deflt) {
  2038. X    strcpy(cp = Malloc(strlen(deflt) + 1), deflt);
  2039. X  }
  2040. X  else {
  2041. X    cp = Malloc(1);
  2042. X    cp[0] = '\0';
  2043. X  }
  2044. X
  2045. X  return cp;
  2046. X}
  2047. X
  2048. X
  2049. Xint
  2050. Xget_user_rsp()
  2051. X{
  2052. X  char c;
  2053. X
  2054. X  while ((c = next_char(0)) && c != '\n')
  2055. X    add_char(c);
  2056. X  strip_white_space();
  2057. X
  2058. X  if (user_rsp)
  2059. X    free(user_rsp);
  2060. X  if (!(user_rsp = take_saved_text()))
  2061. X    return c == '\n' ? '\n' : 0;
  2062. X
  2063. X  switch (user_rsp[0]) {
  2064. X  case 'q':
  2065. X  case 'Q':
  2066. X    return 'q';
  2067. X  case '?':
  2068. X    return '?';
  2069. X  case '\0':
  2070. X    return c == '\n' ? '\n' : 0;
  2071. X  default:
  2072. X    if (Alpha_Flag) {
  2073. X      if (isalpha(user_rsp[0]))
  2074. X    return toupper(user_rsp[0]) - 'A' + 1;
  2075. X      return 0;
  2076. X    }
  2077. X    else
  2078. X      return atoi(user_rsp);
  2079. X  }
  2080. X}
  2081. X
  2082. Xstatic VOID
  2083. Xalarm_trap()
  2084. X{
  2085. X  return;
  2086. X}
  2087. X
  2088. XVOID
  2089. Xdo_pause(flag)
  2090. X     int flag;
  2091. X{
  2092. X  char c;
  2093. X
  2094. X  if (Clear_Flag) {
  2095. X    if (flag)
  2096. X      printf("Returning to '%s' [Press Return to Continue]",
  2097. X         active_menu->short_title);
  2098. X    else
  2099. X      printf("[Press Return to Continue]");
  2100. X    fflush(stdout);
  2101. X    if (!Wait_Flag) {
  2102. X      alarm(default_timeout);
  2103. X      signal(SIGALRM, alarm_trap);
  2104. X    }
  2105. X    while ((c = next_char(0)) && c != '\n')
  2106. X      ;
  2107. X    alarm(0);
  2108. X    signal(SIGALRM, SIG_IGN);
  2109. X  }
  2110. X}
  2111. END_OF_FILE
  2112. if test 8253 -ne `wc -c <'tty_display.c'`; then
  2113.     echo shar: \"'tty_display.c'\" unpacked with wrong size!
  2114. fi
  2115. # end of 'tty_display.c'
  2116. fi
  2117. echo shar: End of archive 1 \(of 2\).
  2118. cp /dev/null ark1isdone
  2119. MISSING=""
  2120. for I in 1 2 ; do
  2121.     if test ! -f ark${I}isdone ; then
  2122.     MISSING="${MISSING} ${I}"
  2123.     fi
  2124. done
  2125. if test "${MISSING}" = "" ; then
  2126.     echo You have unpacked both archives.
  2127.     rm -f ark[1-9]isdone
  2128. else
  2129.     echo You still need to unpack the following archives:
  2130.     echo "        " ${MISSING}
  2131. fi
  2132. ##  End of shell archive.
  2133. exit 0
  2134. --------------------------------cut here--------------------------------------
  2135. -- 
  2136. Mike Howard
  2137. uunet!milhow1!how or how%milhow1@uunet.uu.net
  2138.