! Explanation at end of file $ MNGR__QUIET = %x10000000 ! Inhibit display (bit 28) $ MNGR__SUCCESS = MNGR__QUIET + %x0001 ! Severity 1 (success) $ MNGR__FATAL = MNGR__QUIET + %x0004 ! Severity 4 (fatal error) $ MNGR__CONTROLY = MNGR__FATAL $ on warning then exit MNGR__QUIET .or. $STATUS $ on control_y then exit MNGR__CONTROLY $ if f$type(MNGR__QUIET) .eqs. "" then exit %x10000000 ! ! ! ========== Symbol definitions ! $ MNGR_CURDIR = f$environment("DEFAULT") $ MNGR_DEPTH = f$environment("DEPTH") $ MNGR_PROFULL = f$environment("PROCEDURE") $ MNGR_PRONAME = f$parse(MNGR_PROFULL,,,"NAME") ! ! ! ========== Initialize symbol/logicals ! $ if f$trnlnm("$COM") .eqs. "" then - $ @'f$parse(MNGR_PROFULL,,,"DEVICE")''f$parse(MNGR_PROFULL,,,"DIRECTORY")'LIBINIT ! ! ! ========== Read file P1 to get module names, one line descriptor and ! (optional) type of input file name ! Only the file name part of P1 is used. The directory is ! supposed to be $AUX; the file type .PLAY ! $ MKPL = 0 $ if P1 .nes. "" $ then $ if f$extract (0,1,P1) .eqs. "@" then MKPL = 1 $ P1 = P1-"@" $ if P1 .nes. "" then P1 = f$parse(P1,,,"NAME") $ endif $ STRING = "" $ GET_MNGR: $ MENU_FILE = f$search("$AUX:"+P1+"*.PLAY") $ if MENU_FILE .nes. "" $ then $ STRING = STRING+","+f$parse(MENU_FILE,,,"NAME") $ if P1 .eqs. "" then goto GET_MNGR $ endif $! $ if STRING .eqs. "" ! No matching menu file found $ then $ if .not. MKPL then signal MNGR E NOMNGR - "No matching .PLAY files found in ''f$trnlnm("$AUX")'" $ STRING = P1 ! Continue only if new menu file is to be created $ else $ STRING = STRING-"," $ endif $ if P1 .eqs. "" $ then $! set noon $! directory $AUX:*.PLAY $! set on $ @$COM:LIBTOOL CHECKMOD LIB__ANS 'STRING "" " Available PLAY menus:" $ P1 = LIB__ANS $ else $ P1 = STRING $ endif ! ! Structure of record for each line in menu ! _T_ refers to starting position of string (in byte) ! _S_ refers to length of string (in byte) ! ! ========== Define structure of records in *.PLAY file ! $ MNGR_T_MOD = 0 ! Module $ MNGR_S_MOD = 10 $ MNGR_T_SUB = 10 ! Submodule (usually label) $ MNGR_S_SUB = 10 $ MNGR_T_LAB = 20 ! Descriptor string $ MNGR_S_LAB = 60 ! Total record lenght 100 bytes ! $ MNGR_NAME = P1 $ MENU_FILE = "$AUX:"+MNGR_NAME+".PLAY" $! $ if MKPL then goto MKPLAY $! $ open/read/share=read MENU 'MENU_FILE /error=OPEN_ERROR $ goto P2_TEST $ OPEN_ERROR: $ signal 'MNGR_PRONAME E OPENERR "Open error on list file ''MENU_FILE'" $ P2_TEST: $ if P2 .nes. "" $ then $ read MENU /index=0/key="''P2'" RECORD /error=P2_NOT_PRESENT $ close MENU $ STAY = 0 $ MODULE = f$edit(f$extract(MNGR_T_MOD,MNGR_S_MOD,RECORD),"TRIM,UPCASE,COMPRESS") $ if f$extract(f$length(MODULE)-1,1,MODULE) .eqs. "&" then - MODULE = f$extract(0,f$length(MODULE)-1,MODULE) $ _'MODULE = f$edit(f$extract(MNGR_T_LAB,MNGR_S_LAB,RECORD),"TRIM") $ LABEL = MODULE $ SUBMODULE = f$edit(f$extract(MNGR_T_SUB,MNGR_S_SUB,RECORD),"TRIM,UPCASE,COMPRESS") $ if SUBMODULE .nes. "" then MODULE = SUBMODULE+" "+MODULE $ goto P2_PRESENT $ P2_NOT_PRESENT: $ close MENU $ signal 'MNGR_PRONAME E NOMODULE "Module ''P2' is not available" $ P2_PRESENT: $ endif ! $ on warning then goto EMPTY_MENU $ on control_y then goto EMPTY_MENU $ PLAY_STOP == 1 $ MNGR_MESSAGE = "" $ read MENU /index=0/key="+" RECORD /error=READ_TRAILER $ MNGR_MESSAGE = f$extract(MNGR_T_LAB,MNGR_S_LAB,RECORD) $ READ_TRAILER: $ MNGR_CLOSING = "" $ read MENU /index=0/key="-" RECORD /error=READ_CLEANUP $ MNGR_CLOSING = f$extract(MNGR_T_LAB,MNGR_S_LAB,RECORD) $ READ_CLEANUP: $ CLEANUP = 0 $ read MENU /index=0/key="CLEANUP" RECORD /error=READ_ERASER $ CLEANUP = 1 $ READ_ERASER: $ ERASER = 0 $ read MENU /index=0/key="ERASER" RECORD /error=READ_REST $ ERASER = 1 $ _ERASER = f$edit(f$extract(MNGR_T_LAB,MNGR_S_LAB,RECORD),"TRIM") $ ERASER_MODULE = f$extract(MNGR_T_SUB,MNGR_S_SUB,RECORD) $ ERASER_MODULE = f$edit(ERASER_MODULE,"TRIM,UPCASE,COMPRESS")+" ERASER" $ READ_REST: $ if P2 .nes. "" then goto EXECUTE_MODULE ! $ MNGR_CLOCK = 0 $ read MENU /index=0/key="*" RECORD /error=NO_CLOCK $ MNGR_CLOCK = 1 ! $ NO_CLOCK: $ MENU_DISPLAY = "" $ LABEL = "" $ I = -1 $ SKEY[0,10] := "" $ STRIP_NEXT_RECORD: $ if SKEY .eqs. " " $ then $ read MENU /index=0/key="''SKEY'"/match=GE RECORD /error=EMPTY_MENU $ else $ read MENU RECORD /error=CONTINUE_MODULES $ endif $ SKEY = "XX" ! $ MODULE = f$edit(f$extract(MNGR_T_MOD,MNGR_S_MOD,RECORD),"TRIM,UPCASE,COMPRESS") $ FR = f$extract(0,1,MODULE) $ if FR .eqs. "+" .or. FR .eqs. "-" .or. FR .eqs. "*" .or. FR .eqs. "!" - then goto STRIP_NEXT_RECORD $ if MODULE .eqs. "CLEANUP" .or. MODULE .eqs. "ERASER" then goto STRIP_NEXT_RECORD ! $ if f$extract(f$length(MODULE)-1,1,MODULE) .eqs. "&" $ then $ MODULE = f$extract(0,f$length(MODULE)-1,MODULE) $ if LABEL .eqs. "" then LABEL = MODULE $ endif ! $ I = I+1 $ MENU_DISPLAY = MENU_DISPLAY+","+MODULE $ _'MODULE = f$edit(f$extract(MNGR_T_LAB,MNGR_S_LAB,RECORD),"TRIM") $ if _'MODULE .eqs. "" then _'MODULE = "No description available" $ SUBMODULE = f$edit(f$extract(MNGR_T_SUB,MNGR_S_SUB,RECORD),"TRIM,UPCASE,COMPRESS") $ if SUBMODULE .nes. "" then 'MODULE'$$ = SUBMODULE $ goto STRIP_NEXT_RECORD ! $ EMPTY_MENU: $ close/nolog MENU $ signal 'MNGR_PRONAME E READERR "Read error on menu file ''MENU_FILE'" $ CONTINUE_MODULES: $ close MENU $ on warning then exit MNGR__QUIET .or. $STATUS $ on control_y then exit MNGR__CONTROLY $ if MENU_DISPLAY .eqs. "" then signal 'MNGR_PRONAME E NOMODULES "No modules read from list file ''MENU_FILE'" $ MENU_DISPLAY = MENU_DISPLAY-"," $! STAY = 0 $! if P2 .nes. "" then goto TRANSLATE_P2 ! ! ! ========== Loop to display available modules (in symbol MENU_DISPLAY) ! $ DISPLAY_MODULES: $! $ STAY = 1 $ if MNGR_CLOCK .and. f$search("$EXE:CLOCK.EXE") .nes. "" then run $EXE:CLOCK $ STRING = " List of "+MNGR_NAME+" modules" $ say f$fao("!/!70AS LEVEL !SL!/",STRING,MNGR_DEPTH) $ if MNGR_MESSAGE .nes. "" then say f$fao(" !AS!/",MNGR_MESSAGE) $ I = -1 $ DISPLAY_NEXT_MODULE: $ I = I+1 $ MODULE = f$element(I,",",MENU_DISPLAY) $ if MODULE .nes. "," $ then $ say f$fao(" !12AS !AS",MODULE,_'MODULE') $ goto DISPLAY_NEXT_MODULE $ endif $ if LABEL .eqs. "" then LABEL = f$element(0,",",MENU_DISPLAY) $ echo LIB__ANS S " Run module (^Z=Exit) ?" 'LABEL U,Z,S $ P2 = f$element(0," ",LIB__ANS) $ if P2 .eqs. "^Z" $ then $ STATUS = MNGR__SUCCESS $ STAY = 0 $ PLAY_STOP == 0 $ goto MNGR_CONTINUE $ endif $ P3 = f$element(1," ",LIB__ANS) $ if P3 .eqs. " " then P3 = "" $ P4 = f$element(2," ",LIB__ANS) $ if P4 .eqs. " " then P4 = "" $ P5 = f$element(3," ",LIB__ANS) $ if P5 .eqs. " " then P5 = "" $ P6 = f$element(3," ",LIB__ANS) $ if P6 .eqs. " " then P6 = "" $ P7 = f$element(3," ",LIB__ANS) $ if P7 .eqs. " " then P7 = "" $ P8 = f$element(3," ",LIB__ANS) $ if P8 .eqs. " " then P8 = "" $! $! $! ========== The value of argument P2 determines which module is run $! $! TRANSLATE_P2: $! $ if f$extract(0,1,P2) .eqs. "$" $ then $ on warning then goto MNGR_ERROR $ on control_y then goto MNGR_ERROR $ MODULE = "DCL" $ P2 = f$extract(1,999,P2) $ 'P2 $ STATUS = MNGR__SUCCESS $ goto MNGR_CONTINUE $ endif $! $ @$COM:LIBSUB LOOKUP_KEY LIB__ANS 'P2 'MENU_DISPLAY FIRST_MATCH $ if LIB__ANS .eqs. "" $ then $ if .not. STAY then signal 'MNGR_PRONAME E NOMODULE "Module ''P2' is not available" $ signal 'MNGR_PRONAME W NOMODULE "Module ''P2' not available" $ goto DISPLAY_MODULES $ endif $ LABEL = LIB__ANS $ MODULE = LABEL $ if f$type('LABEL'$$) .eqs. "STRING" then MODULE = 'LABEL'$$+" "+LABEL $! $ EXECUTE_MODULE: $ say f$fao("!/ ********** Module !AS!/",MODULE) $ say f$fao(" > !AS " ^Z Z $ PLAY_STOP == 1 $ goto DISPLAY_MODULES $ endif $ if ERASER ! Special clean-up $ then $ LABEL = "ERASER" $ MODULE = ERASER_MODULE $ ERASER = 0 $ goto EXECUTE_MODULE $ endif $ if CLEANUP ! Generic cleanup $ then $ say f$fao("!/ ********** > !AS Manager for running DCL procedures and EXE executables from a menu >MKPLAY: Create and modify menu files for the LIBPLAY utility INPUTS: (prompts follow for omitted arguments) P1 Name of the menu file with list of procedures/executables P2 One of the labels as it would appear on the menu (see procedure). >MKPLAY: (to modify menu files) P1 "@"[menu file] P2 Modify option RESTRICTIONS: > The LIBSUB.COM file containing the signal and echo procedures should be present in the directory indicated by the logical $COM. All DCL procedures to be executed should also be located in $COM. All executables should be located in $EXE. The menu file containing the information for building the module should be located in $AUX. If a HELP module is included the .HLB file should be located in $LIB. >MKPLAY: The values in index 0 (the module name) cannot be modified PROCEDURES: > The menu file P1 is an indexed file with the following record structure: Byte [0,9] index 0; module name. This will usually be the DCL/EXE program name, or the value of an argument passed into the command procedure or executable (e.g. the name of a statement label in a DCL procedure). The module name will be displayed in the menu. Byte [10,19] program name; if the module name is an argument for a command procedure or executable, the program name should be given here. If the module name is the same as the program name, leave this entry blank. Byte [20,79] Title; one line description of the task performed > The module name (index 0) can take several special values: - Module names: !,+,-,* ! are ignored (intended for comments); + : the title is interpreted as a message displayed above the menu; - : the title is interpreted as a message displayed before final exit * : will (hopefully) result in clearing the page using CLOCK.EXE - Adding & to the module name: at startup the module presented as default is the first one in alphabetical order. If this is no adequate, then a specific module can be selected as the startup default by adding the character & to the module name. > The module name can be input for the program given in the 'program name' entry. If the program is a command procedure, the module name is interpreted as a P1 value. If the program is a FORTRAN executable the argument can be pulled into the program using the system function LIB$GET_FOREIGN > The menu as it appears on the screen will contain one line for each procedure. Each line consist of the module name and the title string. > The display of the menu can be circumvented by supplying the module name explicitly as P2 argument in a call to LIBPLAY from the DCL prompt, i.e. @$COM:LIBPLAY . The corresponding action is performed and LIBPLAY exits again. (NOTE: the indexed menus file were introduced to speed up this form of calling LIBPLAY). > If the menu file contains CLEANUP as "module name", a generic clean-up is performed before final exit. The generic CLEANUP consist of an automatic dismount and return to the original working directory. > If the menu file contains the module ERASER, the module name is combined with the program name and is executed as a special clean-up on exit. > CLEANUP and ERASER do not appear on the menu. > If module HELP is present, the VAX HELP can be used provided the HELP file $LIB:'P1'.HLB exists. > When execution of a program ends, and control returns to LIBPLAY then - if the clock option is not used, the menu is displayed again - if the clock option is used the message "" is issued. This message can be skipped (and the menu displayed) if the global symbol PLAY_STOP is set to zero in the executed program just before exit. >MKPLAY: The following actions are available: ADD Add entries to menu file CREATE Create new menu file LIST List content of menu file UPDATE Update entry in menu file DELETE Delete entry from menu file MODIFICATION HISTORY: SEP-1991, Paul Hick (ARC) NOV-1991, Paul Hick (UCSD), introduced MENU_DISPLAY symbol to speed up display of menu (still contains a loop. Tried using a single f$fao call to do the job, but that doesn't work if the menu contains as many as 8-10 items) AUG-1992, Paul Hick (UCSD); the menu file is now assumed to be an indexed file rather than a sequential ASCII file. The old version is still available under the name LIBMNGR.COM The MKPLAY section allows creation and modification of the indexed .PLAY files. APR-1994, Paul Hick (UCSD); added the option to define the default module at startup (by adding "&" to the module name (index 0; see PROCEDURE) !-