home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / menu / mman.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  171.0 KB  |  3,974 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --textsete.ada
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4.  
  5.  
  6.  
  7. -- TEXT_HANDLER_SUBSET;TEXTSETE.ADA;KJL;04/09/85
  8.  
  9. -- This package is a subset of the Text Handler package from the LRM. It
  10. -- contains only the operations needed for the Menu Manager project. The
  11. -- TEXT type is a dynamic character string type, that is implemented using
  12. -- access types where the object is really a pointer to a string. The string
  13. -- can expand dynamicly because the object points to a new string that 
  14. -- includes the text of the previous one and more.
  15.  
  16. -- This is one of the few non generic library units in the Menu Manager set.
  17. -- This package must be compiled before others are.
  18.  
  19. package TEXT_HANDLER_SUBSET is
  20.  
  21.    type TEXT is private;
  22.  
  23.    function VALUE   (T: TEXT) return STRING;
  24.     -- Returns the string which the access type points to, or "" if the access
  25.     -- type points to null.
  26.  
  27.    function LENGTH  (T: TEXT) return NATURAL;
  28.     -- Returns the Length of the accessed string. 0 if access is null.
  29.  
  30.    function EMPTY   (T: TEXT) return BOOLEAN;
  31.     -- Returns true if the accessed string is "", or access is null.
  32.  
  33.  
  34.    function TO_TEXT  (STR: STRING) return TEXT;
  35.     -- Creates an access type that points to a string of the value given.
  36.  
  37.    function TO_TEXT  (CHR: CHARACTER) return TEXT;
  38.     -- Creates an access type poiting to a string that is the character given.
  39.  
  40.    procedure CLEAR_TEXT (T: in out TEXT);
  41.     -- Resets the given access object to point to a null string.
  42.  
  43.  
  44.    procedure PACK_TEXT    (T: in out TEXT);
  45.     -- Takes the leading and trailing blanks off the given accessed string.
  46.  
  47.    procedure UNPACK_TEXT  (T: in out TEXT; LEN: in NATURAL;
  48.                 NO_ROOM: out BOOLEAN);
  49.     -- Adds trailing blanks to the given accessed string to make it the length
  50.     -- requested in LEN. NO_ROOM is true when the LEN is smaller than the
  51.     -- number of characters in the T accessed string.
  52.  
  53.    function UNPACK_VALUE   (T: TEXT;  LEN: NATURAL) return STRING;
  54.     -- Returns a string of length LEN from the accessed string T. If T is too
  55.     -- big, returns a string of blanks.
  56.  
  57.    function PACK_TO_TEXT   (STR: STRING) return TEXT;
  58.     -- Returns an access type pointing to a string with value STR, but with
  59.     -- no leading or trailing blanks.
  60.  
  61.  
  62.    procedure APPEND  (TAIL: TEXT;   TO: in out TEXT);
  63.     -- TO will point to a string that is the accessed string TO concated with
  64.     -- the accessed string TAIL.
  65.  
  66.    procedure APPEND  (TAIL: STRING;   TO: in out TEXT);
  67.     -- TO will point to a string that is the accessed string TO concated with
  68.     -- the string TAIL.
  69.  
  70.    procedure APPEND  (TAIL: CHARACTER;  TO: in out TEXT);
  71.     -- TO will point to a string that is the accessed string TO concated with
  72.     -- the character TAIL.
  73.  
  74.  
  75.    function GIVE_POS (T: TEXT;  POSITION: NATURAL) return CHARACTER;
  76.     -- Returns the character of accessed string T, that is the string index
  77.     -- given in POSITION.
  78.  
  79.  
  80. private        -- Objects of type TEXT point to strings.
  81.    type TEXT is access STRING;
  82.  
  83.  
  84. end TEXT_HANDLER_SUBSET;
  85. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  86. --compgese.ada
  87. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  88.  
  89. -- COMPILER_MESSAGES;COMPGESE.ADA;KJL;04/09/85
  90.  
  91. -- This package contains the procedures, data structures, and values needed
  92. -- for displaying messages during the running of the Menu Compiler.
  93.  
  94. -- All the messages that the Menu Compiler and Menu Handler issue are found in
  95. -- a file "COMERRS". There are 2 lines for each message:
  96. -- The first line is a code of severity for the message: NO_ERROR for 
  97. -- information messages that are not related to errors. WARNING_ERROR for 
  98. -- errors that will not stop the compilation or the creation of the Menu Def
  99. -- Table, DISABLING_ERROR for errors that stop the creation of the Menu Def
  100. -- Table, but the compiler continues to process the Menu Def File, and
  101. -- FATAL_ERROR for errors that are severe enough to warrant stopping the
  102. -- compilation immediately, and no Menu Def Table is created. 
  103. -- The second line in a 236 character line that contains the text of the
  104. -- the message to be displayed.
  105. -- Each message has a numeric code associated with it which is the order that
  106. -- the message entrys appear in the COMERRS file. This numeric code is used
  107. -- when a message is invoked in other procedures.
  108.  
  109. -- One procedure of this package reads the COMERRS file into an array kept in
  110. -- the package. The array is used during the compilation, not the file.
  111. -- The file is open only when it initially being read, then closed for the
  112. -- duration of the program run.
  113.  
  114. with TEXT_HANDLER_SUBSET;
  115. generic
  116.    -- When this package is instantiated during the execution on the Menu
  117.    -- Compiler, the Screen Width is passed (so that the messages are displayed
  118.    -- correctly), a function returning the current lexical unit and one
  119.    -- returning the current line number of the Menu Def File are passed (the
  120.    -- lex unit and line number will be displayed in the error messages).
  121.    SCREEN_WIDTH: POSITIVE;
  122.    with function CURRENT_LEX_STRING return TEXT_HANDLER_SUBSET.TEXT;
  123.    with function CURRENT_LINE_NUMBER return INTEGER;
  124. package COMPILER_MESSAGES is
  125.  
  126.    function FATAL_ERROR_STATUS return BOOLEAN;
  127.     -- Returns true if any errors have been found during this compilation
  128.     -- which are of Fatal severity or worse (nothing is worse yet).
  129.  
  130.    function DISABLE_ERROR_STATUS return BOOLEAN;
  131.     -- Returns true if any errors have been found during this compilation
  132.     -- which are of Disabling severity or worse.
  133.  
  134.    function WARNING_ERROR_STATUS return BOOLEAN;
  135.     -- Returns true if any errors have been found during this compilation
  136.     -- which are of Warning severity or worse.
  137.  
  138.    procedure INITIALIZE_MESSAGES;
  139.     -- Procedure reads the information from the COMERRS file to an array kept
  140.     -- in this package. 
  141.  
  142.    procedure SEND_SIMPLE_MESSAGE(CODE: in INTEGER);
  143.     -- Procedure is used if only the text of a message is to be displayed on
  144.     -- the screen (the message is identified by the numeric code).
  145.  
  146.    procedure SEND_COMPILE_ERROR(CODE: in INTEGER);
  147.     -- Procedure is used to send a compiler error. The text sent to the display
  148.     -- includes the message number code, the line number, the severity of the
  149.     -- error, the lexical unit, and the text of the message.
  150.  
  151.    procedure SEND_FINAL_MESSAGE;
  152.     -- Sends a final summary message to the screen, includes the total number
  153.     -- of errors, the highest severity of error, and message text.
  154.  
  155.    procedure SEND_RUNTIME_ERROR(CODE: in INTEGER);
  156.     -- This procedure is used to send messages during the Menu Handler. It 
  157.     -- shows the numeric code, the message text, and waits for any key to be
  158.     -- typed to return control the calling program.
  159.  
  160. end COMPILER_MESSAGES;
  161. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  162. --continee.ada
  163. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  164.  
  165.  
  166. -- CONTROLLING_MENU_INFO_LINE;CONTINEE.ADA;KJL;04/16/85
  167.  
  168. -- This package contains the text for Menu Information Line, and it contains
  169. -- subprograms for processing this line. The Menu Information Line is a
  170. -- character string that appears in the second to last line of the menu
  171. -- display. The line is often blank but will contain the Bad Selection Message
  172. -- if necessary, or a message telling that a background task has started. If
  173. -- this software system is expanded, this package can be edited to allow more
  174. -- messages to appear in the Menu Information Line.
  175.  
  176.  -- The package is instantiated when the Menu Handler is run so the procedures
  177.  -- will work using the proper configuration constants.
  178. generic
  179.     -- The Screen Width is passed to this package when it is instantiated, so
  180.     -- the string lengths will fit on the display.
  181.    SCREEN_WIDTH: POSITIVE;
  182. package CONTROLLING_MENU_INFO_LINE is
  183.  
  184.     -- Procedure will set the Bad Selection Message that is kept internally is
  185.     -- this package to the string given.
  186.    procedure RECEIVE_BAD_SELECT_MESSAGE (BAD_SELECT_MSG: in STRING);
  187.  
  188.     -- Procedure will set the Menu Information Line to the text of the Bad
  189.     -- Selection Message. 
  190.    procedure SET_BAD_SELECTION;
  191.  
  192.     -- Procedure will set the Menu Information Line to text notifying that a 
  193.     -- task has started (tasks are run in background while the menu is 
  194.     -- displaying and processing inputs).
  195.    procedure SET_TASK_STARTED (FILE_NAME: in STRING);
  196.  
  197.     -- Function returns a string of size SCREEN_WIDTH that is the Menu
  198.     -- Information Line kept internally.
  199.    function RETURN_INFO_LINE return STRING;
  200.  
  201.  
  202. end CONTROLLING_MENU_INFO_LINE;
  203. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  204. --dispinge.ada
  205. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  206.  
  207. -- DISPLAY_PROCESSING;DISPINGE.ADA;KJL;04/09/85
  208.  
  209. -- This package contains procedures to handle the menu display. It stores
  210. -- the display layout in an array of strings. The procedures are used to
  211. -- process this array of strings, and output the display to a CRT.
  212. -- The package keeps a Current Read counter, and a Current Write counter. These
  213. -- value indicate the next display line to be read and written from the display
  214. -- array. Display lines are read when the display is put to the Menu Def Table
  215. -- file, they are written when the Menu Def File contains text to be put in
  216. -- the screen layout, and when the Menu Def Table is read by the Menu Handler.
  217.  
  218. with TEXT_HANDLER_SUBSET;
  219. generic
  220.     -- Passed to this package when instantiated is the Screen Width which
  221.     -- determines the length of each display line. The Screen Length
  222.     -- determines the number of display lines within the display array.
  223.    SCREEN_WIDTH: POSITIVE;
  224.    SCREEN_LENGTH: POSITIVE;
  225. package DISPLAY_PROCESSING is
  226.  
  227.     -- Rename to avoid using DOT notation.
  228.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  229.  
  230.    function GET_NEXT_SCREEN_LINE return STRING;
  231.     -- Returns the next display line as determined by the Current Read counter.
  232.  
  233.    procedure PUT_NEXT_SCREEN_LINE(DISPLAY_TEXT: in STRING);
  234.     -- Writes the next display line as determined by the Current Write counter.
  235.  
  236.    function END_OF_SCREEN return BOOLEAN;
  237.     -- Returns true if the last display line has been read.
  238.  
  239.    procedure PUT_SCREEN_TEXT(LINE, COLUMN: in INTEGER;  DISPLAY_TEXT: in TEXT);
  240.     -- Writes text to the display layout array starting at the display line
  241.     -- given, and the string index of that line given in the Column argument.
  242.  
  243.    procedure CLEAR_SCREEN_LAYOUT;
  244.     -- Puts blanks in all the positions of the display layout array.
  245.  
  246.    procedure PUT_SCREEN_LAYOUT_TO_CRT;
  247.     -- Using Text_Io procedures, each line of the display layout array is
  248.     -- put to the display.
  249.  
  250.  
  251. end DISPLAY_PROCESSING;
  252. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  253. --handntse.ada
  254. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  255.  
  256.  
  257.  
  258. -- HANDLE_COMPILER_COMPONENTS;HANDNTSE.ADA;KJL;04/13/85
  259.  
  260. -- This package contains subprograms used to process the Lexical Units found in
  261. -- the Menu Definition File. The package keeps track or variables used as the
  262. -- compilation is running, ie, current column and line number for the display
  263. -- layout, and the Bad Selection message last specified in the Menu Definition.
  264.  
  265.  
  266. with TEXT_HANDLER_SUBSET;
  267.  -- The package in instantiated at run time so that the subprograms are
  268.  -- executed with the proper configuration values.
  269. generic
  270.     -- Passed to the package when it is instantiated is:
  271.     -- The types of lexical units, used check syntax (most often a User Literal
  272.     -- must follow an Identifier).
  273.    type LEXICAL_UNIT_TYPES is (<>);
  274.  
  275.     -- Types of action - for processing the Select instruction.
  276.    type ACTION_TYPE is (<>);
  277.  
  278.     -- Valid selection keys - for processing the Select instruction.
  279.    USABLE_SELECT_KEYS: STRING;
  280.  
  281.     -- Screen width and length - for valid Line and Column instructions and to
  282.     -- insure that text for the menu layout will fit on the display.
  283.    SCREEN_WIDTH: POSITIVE;
  284.    SCREEN_LENGTH: POSITIVE;
  285.  
  286.     -- Maximum characters in a command name  - checked when the user specifies
  287.     -- a process in a select instruction.
  288.    FILE_STRING_SIZE: POSITIVE;
  289.  
  290.     -- Procedure adds a control item to a dynamic list of control items. A
  291.     -- control item results from a Select instruction, and specifies the
  292.     -- process and its type associated with a menu selection key.
  293.    with procedure ADD_MENU_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  294.         NEXT_MENU: in TEXT_HANDLER_SUBSET.TEXT;
  295.         FILE_NAME_OF_PRCESS: in TEXT_HANDLER_SUBSET.TEXT;
  296.         TYPE_OF_ACTION: in ACTION_TYPE);
  297.  
  298.     -- Procedure makes the next lexical unit available for analyzing.
  299.    with procedure GET_LEXICAL_UNIT_IF_NEEDED;
  300.  
  301.     -- Signals that a lexical unit was made available and has not been used
  302.     -- yet, so the next request for a lexical unit should not get a new one
  303.     -- from the Menu Definition, but should use the one still available.
  304.    with procedure UNIT_RECEIVED;
  305.  
  306.     -- Returns the type of the lexical unit currently available.
  307.    with function CURRENT_LEX_TYPE return LEXICAL_UNIT_TYPES;
  308.  
  309.     -- Returns the text of the lexical unit currently available.
  310.    with function CURRENT_LEX_STRING return TEXT_HANDLER_SUBSET.TEXT;
  311.  
  312.     -- Puts text to the display layout array.
  313.    with procedure PUT_SCREEN_TEXT (ROW,COLUMN: in POSITIVE;
  314.                 DISPLAY_TEXT: in TEXT_HANDLER_SUBSET.TEXT);
  315.  
  316.     -- Send errors messages to user terminal.
  317.    with procedure SEND_COMPILE_ERROR(CODE: in INTEGER);
  318. package HANDLE_COMPILER_COMPONENTS is
  319.  
  320.     -- Rename Text type to avoid using extended name notation.
  321.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  322.  
  323.     -- Procedure gets name of Menu Definition Table to be created. This text
  324.     -- string is kept in this package.
  325.    procedure GET_THE_TITLE;
  326.  
  327.     -- Do the necessary logic to process the given Identifiers string.
  328.    procedure PROCESS_IDENTIFIER(LEXICAL_STRING: in TEXT);
  329.  
  330.     -- Put the given text to the menu display layout at the current line and
  331.     -- column position (User Literals not following an identifier as per the 
  332.     -- language syntax, are interpreted as text put to the display layout).
  333.    procedure WRITE_SCREEN_LAYOUT_TEXT(LEXICAL_STRING: in TEXT);
  334.  
  335.     -- Returns the text that is the Bad Selection message.
  336.    function THE_BAD_SELECTION_MESSAGE return TEXT;
  337.  
  338.     -- Returns the text that is the name of the Menu Def Table to be created.
  339.    function THE_TITLE_NAME return TEXT;
  340.  
  341. end HANDLE_COMPILER_COMPONENTS;
  342. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  343. --handsese.ada
  344. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  345.  
  346. -- HANDLE_PROCESSES;HANDSESE.ADA;KJL;04/17/85
  347.  
  348. -- This package contains subprograms used by the Menu Handler that processes
  349. -- the requests for action, that result from the menu users inputs. This
  350. -- package will also contain the file name of the Menu Definition Table that
  351. -- defined the next menu to be displayed.
  352.  
  353. with TEXT_HANDLER_SUBSET;
  354.  -- The package is instantiated using the following arguments:
  355. generic
  356.  
  357.     -- The enumeration type set of qualifiers for the action to perform on a
  358.     -- menu selection (M - call a menu, P - CLI command, T - CLI command 
  359.     -- performed while the Menu Handler continues, A - call Ada procedure).
  360.    type ACTION_TYPES is (<>);
  361.  
  362.     -- The types of user inputs, a CLI line or a selection key typed.
  363.    type INPUT_TYPES is (<>);
  364.  
  365.     -- This procedure will be used to retrieve the process name to perform, and
  366.     -- its type, given a selection key character. The procedure searches a 
  367.     -- Menu Control List kept in another package. If the selection key is not
  368.     -- found in the list, the NOT_FOUND argument will be set.
  369.    with procedure RETRIEVE_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  370.         NEXT_MENU: out TEXT_HANDLER_SUBSET.TEXT;
  371.         FILE_NAME_OF_PROCESS: out TEXT_HANDLER_SUBSET.TEXT;
  372.         TYPE_OF_ACTION: out ACTION_TYPES;
  373.         NOT_FOUND: out BOOLEAN);
  374.  
  375.     -- This procedure is used to pass a character string to the Command Line
  376.     -- Interpreter of the operating system. A code is sent to specify whether
  377.     -- to wait for the command to complete, or continue immediately with the
  378.     -- Menu Handler.
  379.    with procedure COMMAND_LINE_PROCESSOR (COMMAND_LINE: in STRING;
  380.         CONTINUE_WAIT_CODE: in INTEGER;  ERROR_OCCUR: out BOOLEAN);
  381.  
  382.     -- This procedure is used to call an Ada procedure of the name given as a
  383.     -- string argument. The procedure runs until complete and the Menu Handler
  384.     -- returns when the procedure is finished.
  385.    with procedure ADA_PROCEDURE_CALL (ADA_PROCEDURE_NAME: in STRING;
  386.                     ERROR_OCCUR: out BOOLEAN);
  387.  
  388.     -- This procedure will display an error while the Menu Handler is running.
  389.     -- The error displays, and on the users command, the Menu Handler cont-
  390.     -- inues. The error displayed is identified by the CODE argument.
  391.    with procedure SEND_RUNTIME_ERROR (CODE: in INTEGER);
  392.  
  393.     -- This procedure sets the Menu Info Line to display the Bad Selection
  394.     -- Message.
  395.    with procedure SET_BAD_SELECTION;
  396.  
  397.     -- This procedure sets the Menu Info Line to display that the task of
  398.     -- name given in the string argument has started.
  399.    with procedure SET_TASK_STARTED (FILE_NAME: in STRING);
  400.  
  401. package HANDLE_PROCESSES is
  402.  
  403.     -- Rename the TEXT type to avoid using the extended DOT notation.
  404.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  405.  
  406.  
  407.     -- This procedure is passed the string that is what the user input at the
  408.     -- menu, and the type of input this was. The procedure will perform the
  409.     -- necessary processing based on this users input, including retrieving
  410.     -- the action(s) to perform, updating the name of the next menu to display,
  411.     -- and issuing necessary error messages.
  412.    procedure DO_REQUEST (CURRENT_MENU: in TEXT;  REQUEST_STRING: in TEXT;
  413.              TYPE_OF_REQUEST: in INPUT_TYPES);
  414.  
  415.  
  416.     -- This function will return the name of the next menu to be displayed. The
  417.     -- name will be in TEXT dynamic string form with no leading or trailing
  418.     -- blanks around the name.
  419.    function MENU_TO_BE_DISPLAYED return TEXT;
  420.  
  421.  
  422. end HANDLE_PROCESSES;
  423. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  424. --procblee.ada
  425. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  426.  
  427. -- PROCESS_MENU_CONTROL_TABLE;PROCBLEE.ADA;KJL;04/16/85
  428.  
  429. -- This package contains subprograms necessary to hold and use the Menu Control
  430. -- List. This list is a dynamic list of Menu Control Items, each item
  431. -- characterizes a menu selection. Information contained in each item includes:
  432. -- The selection key that is typed at resulting menu, the type of action that
  433. -- is performed when this key is typed, and the name or file name involved in
  434. -- such action. As an example, a Menu Control Item might contain information
  435. -- defining that when this menu is run, the letter 'A' (selection key) may be
  436. -- typed to invoke an operating system command 'GOJOB' (name or file name) that
  437. -- will be performed in background while the menu returns to the screen (type
  438. -- of action, translating the the TASK type). The Menu Control Item also 
  439. -- contains a Next Menu which specifies the name of a Menu Def Table that will
  440. -- be the next menu following the action performed.
  441.  
  442. -- This procedure also contains the subprograms used to write and read the
  443. -- external file which is the Menu Definition Table. The file is written with
  444. -- records that match the Menu Control Items. Other information written to the
  445. -- file; the lines of the Menu Display Layout, and the Bad Selection Message,
  446. -- are put into the same record structure then written to the file. The same
  447. -- record structures are read from the file, and the Menu Control List, Menu
  448. -- Display Layout, and Bad Selection Message is extracted.
  449.  
  450. with TEXT_HANDLER_SUBSET;
  451.  -- This package is instantiated at when the Menu Compiler or Menu Handler is
  452.  -- running, so that the procedures work correctly for the configuration
  453.  -- specified. The following items are given on instantialing this package.
  454. generic
  455.  
  456.     -- The enumeration set that is the codes for each type of action that can
  457.     -- be performed on a selection (CLI program, background CLI task, Ada
  458.     -- procedure, call another Menu...);
  459.    type ACTION_TYPE is (<>);
  460.  
  461.     -- The Maximum size of a file name or program name allowed.
  462.    FILE_STRING_SIZE: POSITIVE;
  463.  
  464.     -- The number of characters possible for each line of the screen display.
  465.    SCREEN_STRING_SIZE: POSITIVE;
  466.  
  467.     -- Function that returns the text of a line from the Menu Display Layout.
  468.     -- Each time the function is called the next line is returned in order top
  469.     -- to bottom ("next" is the line right after the last one GOT).
  470.    with function GET_NEXT_SCREEN_LINE return STRING;
  471.  
  472.     -- Returns true if the last display layout line hav been returned using the
  473.     -- GET_NEXT_SCREEN_LINE function.
  474.    with function END_OF_SCREEN return BOOLEAN;
  475.  
  476.     -- Puts the text given to the Menu Display Layout. Lines are put in order
  477.     -- from top to bottom. The line in put to the "next" display layout line,
  478.     -- right after the last line that was PUT.
  479.    with procedure PUT_NEXT_SCREEN_LINE(DISPLAY_TEXT: in STRING);
  480.  
  481.     -- Clears the Menu Display Layout.
  482.    with procedure CLEAR_SCREEN_LAYOUT;
  483.  
  484. package PROCESS_MENU_CONTROL_TABLE is
  485.  
  486.  
  487.     -- Rename TEXT type to avoid using the extended name notation.
  488.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  489.  
  490.  
  491.     -- This procedure adds a Menu Control Item to the dynamic Menu Control
  492.     -- List given the information for the item ie, the Selection Key, the
  493.     -- Action Type, the Next Menu and the names or file names involved. The
  494.     -- information is put into the proper data structure. The data structure is
  495.     -- added to the list.
  496.    procedure ADD_MENU_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  497.                                      NEXT_MENU: in TEXT;
  498.                                      FILE_NAME_OF_PROCESS: in TEXT;
  499.                                      TYPE_OF_ACTION: in ACTION_TYPE);
  500.  
  501.  
  502.     -- The procedure is given a character select key, and the returns the
  503.     -- information from the Control Item corrisonding to that selection key.
  504.     -- This procedure is used in the Menu Handler when a select key is typed.
  505.    procedure RETRIEVE_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  506.                     NEXT_MENU: out TEXT;
  507.                     FILE_NAME_OF_PROCESS: out TEXT;
  508.                     TYPE_OF_ACTION: out ACTION_TYPE;
  509.                     NOT_FOUND: out BOOLEAN);
  510.  
  511.  
  512.     -- This procedure writes the Menu Definition Table. It uses the Menu
  513.     -- Control List kept in this package, but also writes the Bad Selection
  514.     -- Message and the Menu Display layout lines. All items written are put
  515.     -- into the record types used by the Menu Control Items, and the external
  516.     -- file is written using these types of records.
  517.    procedure WRITE_MENU_CONTROL_FILE (FILE_NAME_OF_MENU_DEF_TABLE:  in  TEXT;
  518.                                        BAD_SELECTION_MESSAGE: in  TEXT;
  519.                                        ERROR_CODE: out INTEGER);
  520.  
  521.  
  522.     -- This procedure is used by the Menu Handler to read a Menu Definition
  523.     -- Table. The external file read must have been written using the procedure
  524.     -- above since the same structure of records that are written above, is
  525.     -- read here. The procedure will read the file and load the Menu Control
  526.     -- List, it will also return the Bad Selection Message, and load the Menu
  527.     -- Display Layout.
  528.    procedure READ_MENU_CONTROL_FILE (FILE_NAME_OF_MENU_DEF_TABLE: in  TEXT;
  529.                      BAD_SELECTION_MESSAGE:  out TEXT;
  530.                      ERROR_CODE:  out INTEGER);
  531.  
  532.  
  533.  
  534. end PROCESS_MENU_CONTROL_TABLE;
  535. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  536. --procinge.ada
  537. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  538.  
  539.  
  540. -- PROCESS_MENU_DEF_STRING;PROCINGE.ADA;KJL;04/17/85
  541.  
  542. -- This package is used by the Menu Compiler, and contains the subprograms
  543. -- needed to do some basic processing on the Menu Definition File. The Menu
  544. -- Def File is written in the Menu Def Language, and is a description of the
  545. -- Menu display and menu action. The file cna be thought of as a series of
  546. -- Lexical Units, that are characters of set of characters, that are arranged
  547. -- in the file and can be sequentially extracted. This package contains sub-
  548. -- programs to extract and handle these Lexical Units. Analyzing the Lexical
  549. -- Units for correctness in their content and their order is left to another
  550. -- Ada package, so no compiler errors regarding the lexical units appear in
  551. -- this package.
  552.  
  553. -- The Menu Definition File is an external file that is edited using some
  554. -- editor and the operations of the particular operating system. One of the
  555. -- operations performed in this package is to transfer the external file to
  556. -- a Menu Definition String. This string is a dynamic character string that
  557. -- will contain all the characters of the file. This string will be kept in
  558. -- this package, and the string will be processed when lexical units are
  559. -- extracted. This keeps the external Menu Definition File open for a minimum
  560. -- amount of time.
  561.  
  562. with TEXT_IO, TEXT_HANDLER_SUBSET;
  563.  -- The package is instantiated with the following arguments so the procedures
  564.  -- will work with the given configuration:
  565. generic
  566.  
  567.     -- The enumeration type set of lexical unit names. The names do not affect
  568.     -- the processing, but the type of lexical unit is an argument passed in
  569.     -- some of the subprograms.
  570.    type LEXICAL_UNIT_TYPES is (<>);
  571.  
  572.     -- The maximum size of a line in the Menu Definition File. Used when the 
  573.     -- lines form the Menu Def File are read.
  574.    MENU_DEF_FILE_LINE_SIZE: POSITIVE;
  575.  
  576.     -- A string of characters that are the characters signaling separateion of
  577.     -- lexical units within the Menu Def File.
  578.    WORD_SEPARATORS: STRING;
  579.  
  580.     -- Character signaling that the characters following until the end of the
  581.     -- line are comments (can be ignored).
  582.    COMMENT_INDICATOR: CHARACTER;
  583.  
  584.     -- The right and left delimiter character are used to signal User Literal
  585.     -- lexical units. In these lexical units, all characters (whether Comment
  586.     -- Indicator, Word Separateor of whatever...) that are between the delim-
  587.     -- iters are taken as part of the lexical unit.
  588.    RIGHT_DELIMITER: CHARACTER;
  589.    LEFT_DELIMITER: CHARACTER;
  590.  
  591. package PROCESS_MENU_DEF_STRING is
  592.  
  593.     -- Rename the TEXT type to avoid using the extended dot notation.
  594.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  595.  
  596.     -- This procedure is given name of  file which is the Menu Definition File,
  597.     -- and the file is written to a Menu Definition String. The string is kept
  598.     -- in this package for future lexical unit extractions. An error code is
  599.     -- given if there are problems reading the external file.
  600.    procedure WRITE_MENU_DEF_STRING(FILE_NAME_OF_MENU_DEF_FILE: in TEXT;
  601.                                    ERROR_CODE: out INTEGER);
  602.  
  603.     -- This procedure makes the next lexical unit in the Menu Def String
  604.     -- available. It extract the text for the next lexical unit from the Menu
  605.     -- Def String, and keeps it available in this package. It also compacts the
  606.     -- Menu Def String, eliminating the text of all previous lexical elements
  607.     -- in the Menu Def String. In this way the Menu Def String is always
  608.     -- shrinking as lexical elements are extracted.
  609.    procedure GET_LEXICAL_UNIT_IF_NEEDED;
  610.  
  611.     -- This procedure signals this package that the last lexical unit extracted
  612.     -- has not been used yet. Therefore when a request is made for a new
  613.     -- lexical unit, no new lexical unit will be extracted from the Menu Def
  614.     -- String, instead the current lexical unit available will remain the
  615.     -- current lexical unit available.
  616.    procedure UNIT_RECEIVED;
  617.  
  618.     -- Returns the lexical unit type of the current lexical unit available.
  619.    function CURRENT_LEX_TYPE return LEXICAL_UNIT_TYPES;
  620.  
  621.     -- Returns the character position of the current Menu Definition File line,
  622.     -- where the next lexical unit will be extracted.
  623.    function CURRENT_POSITION return INTEGER;
  624.  
  625.     -- returns the current Menu Definition File Line where the next lexical
  626.     -- unit will be extracted.
  627.    function CURRENT_LINE_NUMBER return INTEGER;
  628.  
  629.     -- Returns the text of the current lexical unit available, returned in 
  630.     -- TEXT type form.
  631.    function CURRENT_LEX_STRING return TEXT;
  632.  
  633.     -- Returns the number of characters in the lexical unit that is currently
  634.     -- available.
  635.    function LEXICAL_STRING_LENGTH return INTEGER;
  636.  
  637.  
  638.  
  639. end PROCESS_MENU_DEF_STRING;
  640. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  641. --procione.ada
  642. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  643.  
  644. -- PROCESS_CONFIGURATION;PROCIONE.ADA;KJL;04/18/85
  645.  
  646. -- This package contains the user defined items as read from the
  647. -- configuration file. The objects are kept in the package Spec. so that they 
  648. -- are accessable to the main procedure of the Menu Compiler, and Menu Handler.
  649. -- The objects are also given default values, so that if errors occur while
  650. -- reading the file, all objects will still have legal values.
  651. -- If problems occur when the Configuration file is being read, this is
  652. -- signaled by displaying "!!" on the screen (this is done because before
  653. -- reading the config file, the Menu Manager programs do not know how big the
  654. -- the screen width is, and full text lines may not be displayed correctly). In
  655. -- any case, the config objects will at least have the legal default values so
  656. -- the Menu Manager procedures can perform.
  657.  
  658. with TEXT_IO, TEXT_HANDLER_SUBSET;
  659. package PROCESS_CONFIGURATION is
  660.  
  661.     -- The default name of configuration file is "MENCON". The maximum
  662.     -- characters per line in this file is 100. These two constants can be
  663.     -- changed if the user desired, but the following steps will have to be
  664.     -- taken to make the Menu Compiler and Menu Handler work:
  665.     --         * Recompile this package.
  666.     --         * Recompile the main procedure for the Menu Compiler
  667.     --         * Recompile the main procedure for the Menu Handler
  668.     --         * Relink the main procedures for the Menu Compiler and Handler.
  669.    CONFIG_FILE_NAME    : constant STRING := "MENCON";
  670.    INPUT_LINE_LENGTH   : constant := 100;
  671.  
  672.     -- Rename the TEXT type to avoid using DOT notation.
  673.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  674.  
  675.     -- Configuration ojects, the values are read from the MENCON file.
  676.    MAX_FILE_NAME_LENGTH: POSITIVE := 15;
  677.    MENU_FILE: TEXT := TEXT_HANDLER_SUBSET.TO_TEXT("MENUFILE");
  678.    LENGTH_OF_LINES_IN_MENU_FILE: POSITIVE := 100;
  679.    MENU_TABLE: TEXT := TEXT_HANDLER_SUBSET.TO_TEXT("MENUTABL");
  680.    SCREEN_WIDTH: POSITIVE := 80;
  681.    SCREEN_LENGTH: POSITIVE := 22;
  682.    QUIT_CHARACTER: CHARACTER := '@';
  683.  
  684.  
  685.     -- Other configuration items that are not changable to the user, but are
  686.     -- needed in both Menu Compiler, and Menu Handler.
  687.    type ACTION_TYPES is (X, T, P, A, M);
  688.  
  689.  
  690.    procedure READ_CONFIGURATION_FILE;
  691.     -- Reads the configuration values from the MENCON file.
  692.  
  693. end PROCESS_CONFIGURATION;
  694. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  695. --proctore.ada
  696. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  697.  
  698. -- PROCESS_INITIATOR;PROCTORE.ADA;KJL;04/17/85
  699.  
  700. -- This package contains two procedures, the bodies of which are completely user
  701. -- supplied except for a few sample and skeletal statements. These procedures
  702. -- provide the interface of the Menu Handler with the CLI, and the interface
  703. -- of the Menu Handler with any Ada procedures that are desired to be linked
  704. -- to this Menu Handler program. The package spec for this package contains
  705. -- the procedure specs for the two interface procedures. The procedure specs
  706. -- should not be changed since this is the linkage between the interface
  707. -- procedures and the rest of the Menu Handler software. Therefore the user
  708. -- should supply the statements in the procedure bodies, so that the arguments
  709. -- of the procedures input and return the desired values.
  710.  
  711. package PROCESS_INITIATOR is
  712.  
  713.     -- This interface procedure is used to transfer a string passed it the CLI.
  714.     -- The method of doing this is different for different Ada environments,
  715.     -- and may not even exist in a particular environment. There are two
  716.     -- arguments passed to this procedure to be used by the user provided
  717.     -- statements, and one argument passed back to the calling procedure.
  718.     -- The COMMAND_LINE is a string argument that contains a single word,
  719.     -- like a command or an executable file of commands. This string have no
  720.     -- leading of trailing blanks, and this string is to be passed directly to
  721.     -- the Command Line Interpretor.
  722.     -- The CONTINUE_WAIT_CODE is integer code that specifies  0 - to hold the
  723.     -- Menu Handler program while the command is being processed by the CLI,
  724.     -- or 1 - to make the Menu Handler continue immediately once the line or
  725.     -- command has been passed to the CLI. The use of these codes input the
  726.     -- this interface procedure will depend entirely on the capability 
  727.     -- available to issue statements the CLI from this Ada program (ie, it
  728.     -- may be possible to issue a command to the CLI from this Ada program,
  729.     -- but it may not be possible to issue the command and have the Ada program
  730.     -- wait for command completion).
  731.     -- The ERROR argument is a boolean parameter returned to the calling
  732.     -- procedure. It is ment to be used to return the status of the CLIs
  733.     -- ability to interpret the line given to it. If the CLI could not read
  734.     -- or understand the string passed to it, then the ERROR argument should
  735.     -- return TRUE. The ERROR argument is not ment to return the status of
  736.     -- the actual command of process started, only the CLIs ability to start it.
  737.    procedure COMMAND_LINE_PROCESSOR (COMMAND_LINE: in STRING;
  738.                      CONTINUE_WAIT_CODE: in INTEGER;
  739.                      ERROR: out BOOLEAN);
  740.  
  741.  
  742.  
  743.     -- This interface procedure is used to provide a method for starting other
  744.     -- Ada procedures. The procedures will in some way have to be linked to
  745.     -- the Menu Handle procedure for them to be called. This can be done in a
  746.     -- number of ways. There is one argument passed to this procedure, to
  747.     -- be used by the user supplyed statements in the procedure body, and one
  748.     -- argument passed back to the calling program, the statements of the 
  749.     -- procedure body must supply a value for this argument.
  750.     -- The ADA_PROCEDURE_NAME argument is a string argument given to the
  751.     -- procedure. This string is ment to be used in a multi-conditional
  752.     -- statement, that will call an Ada procedure by the name corresponding to
  753.     -- the string given. The string passed here will always have no leading or
  754.     -- trailing blanks, other than that, they will be the exact string
  755.     -- specified in the Menu Definition File on a Select ... A [string] in-
  756.     -- struction (see the syntax guide).
  757.     -- The ERROR argument passed back to the calling program is ment to be
  758.     -- set TRUE if the string is not found in the multi-conditional statement,
  759.     -- and therefore no corresponding Ada procedure was started.
  760.    procedure ADA_PROCEDURE_CALL (ADA_PROCEDURE_NAME: in STRING;
  761.                  ERROR: out BOOLEAN);
  762.  
  763.  
  764. end PROCESS_INITIATOR;
  765. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  766. --compgesd.ada
  767. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  768.  
  769.  
  770. -- COMPILER_MESSAGES;COMPGESD.ADA;KJL;04/18/85
  771.  
  772. -- Package body to handle compiler messages.
  773.  
  774. -- All the messages that the Menu Compiler and Menu Handler issue are found in
  775. -- a file "COMERRS". There are 2 lines for each message:
  776. -- The first line is a code of severity for the message: NO_ERROR for 
  777. -- information messages that are not related to errors. WARNING_ERROR for 
  778. -- errors that will not stop the compilation or the creation of the Menu Def
  779. -- Table, DISABLING_ERROR for errors that stop the creation of the Menu Def
  780. -- Table, but the compiler continues to process the Menu Def File, and
  781. -- FATAL_ERROR for errors that are severe enough to warrant stopping the
  782. -- compilation immediately, and no Menu Def Table is created. 
  783. -- The second line is a 236 character line that contains the text of the
  784. -- the message to be displayed.
  785. -- Each message has a numeric code associated with it which is the order that
  786. -- the message entrys appear in the COMERRS file. This numeric code is used
  787. -- when a message is invoked in other procedures.
  788.  
  789. -- One procedure of this package reads the COMERRS file into an array kept in
  790. -- the package. The array is used during the compilation, not the file.
  791. -- The file is open only when it is initially being read, then closed for the
  792. -- duration of the program run.
  793.  
  794. with TEXT_IO;
  795. package body COMPILER_MESSAGES is
  796.  
  797.    MESSAGE_SIZE: constant := 236;       -- string size of messages.
  798.    LAST_MESSAGE: constant := 36;        -- number of messages in COMERRS file
  799.  
  800.     -- Set of severity codes
  801.    type ERROR_TYPES is (FATAL_ERROR,DISABLING_ERROR,WARNING_ERROR,NO_ERROR);
  802.  
  803.     -- Structure used to store message information from COMERRs file.
  804.    type MESSAGE_INFO is
  805.      record
  806.         ERROR_STATUS: ERROR_TYPES;
  807.         MESSAGE_LINE: STRING(1..MESSAGE_SIZE);
  808.      end record;
  809.  
  810.    type MESSAGE_LIST_TYPE is array (1..LAST_MESSAGE) of MESSAGE_INFO;
  811.  
  812.  
  813.    NUMBER_OF_ERRORS: INTEGER := 0;      -- Tally of all types of errors
  814.    MESSAGE_LIST: MESSAGE_LIST_TYPE;     -- Message info from COMERRS file
  815.  
  816.     -- The error status will contain the highest severity code as yet received
  817.     -- in a compile error.
  818.    CURRENT_ERROR_STATUS: ERROR_TYPES := NO_ERROR;
  819.  
  820.     -- To allow conversion of integer to string to be displayed
  821.    package INTEGER_IO is new TEXT_IO.INTEGER_IO(INTEGER);
  822.  
  823.  
  824.    procedure PUT_MESSAGE_TO_SCREEN (STR: in STRING) is
  825.     -- This procedure is used to put a string to the display. The string is
  826.     -- split at word breaks so that it will fit on the screen width defined.
  827.  
  828.       START_POS: POSITIVE;    -- Index of 1st char for next output line.
  829.       CHAR_COUNT: POSITIVE;   -- String index for current character.
  830.       BLANK_POS: NATURAL;     -- Index of the last blank found.
  831.  
  832.       function RETURN_STARTING_POSITION (INIT: POSITIVE) return POSITIVE is
  833.         -- Function returns the string index of the first non blank character,
  834.         -- following the string index given in INIT. Operation is done to the
  835.         -- STR string passed to the PUT_MESSAGE_TO_SCREEN procedure.
  836.       begin
  837.          for I in INIT..STR'LAST loop
  838.             if STR(I) /= ' ' then
  839.                return I;
  840.             end if;
  841.          end loop;
  842.           -- if no blanks were found, return value greater than last index.
  843.          return STR'LAST + 1;
  844.       end RETURN_STARTING_POSITION;
  845.  
  846.       procedure PUT_THIS_LINE is
  847.        -- This procedure is used to put a section of the STR string to the
  848.        -- display. 
  849.       begin
  850.           -- if no blank is found on the line, put the full set of characters
  851.           -- received.
  852.          if (BLANK_POS = START_POS -1) then
  853.             TEXT_IO.PUT_LINE(STR(START_POS..CHAR_COUNT-1));
  854.          else
  855.             -- put the section of the string from 1st non blank to before the
  856.             -- last blank found. Set current char to just after the blank
  857.             TEXT_IO.PUT_LINE(STR(START_POS..BLANK_POS-1));
  858.             CHAR_COUNT := BLANK_POS+1;
  859.          end if;
  860.           -- Reset start pos for next line to be output (next non blank).
  861.           -- Set current string index to same value, an set blank pos to signal
  862.           -- that no blanks have yet been found.
  863.          START_POS := RETURN_STARTING_POSITION(CHAR_COUNT);
  864.          CHAR_COUNT := START_POS;
  865.          BLANK_POS := START_POS-1;
  866.       end PUT_THIS_LINE;
  867.  
  868.    begin
  869.     -- Main logic of the PUT_MESSAGE_TO_SCREEN procedure. The string passed
  870.     -- is followed character by character, keeping track of the last blank
  871.     -- incountered and the 1st no blank after the previously written line.
  872.     -- When enough words are found to fit in the screen width then the
  873.     -- accumulated string, which is a section of the passed string, will be 
  874.     -- written to the display.
  875.     -- Start with the first non blank character found.
  876.       START_POS := RETURN_STARTING_POSITION(STR'FIRST);
  877.       CHAR_COUNT := START_POS;
  878.       BLANK_POS := START_POS - 1;
  879.       while (CHAR_COUNT <= STR'LAST) loop    -- Do until the end of the string
  880.          if (STR(CHAR_COUNT) = ' ') then
  881.             BLANK_POS := CHAR_COUNT;         --   Keep last found blank index
  882.          end if;
  883.          if (CHAR_COUNT - START_POS + 1 > SCREEN_WIDTH) then
  884.           -- when the accumulated string gets larger than the screen width
  885.           -- put the accumulated string to the display.
  886.             PUT_THIS_LINE;
  887.          end if; 
  888.          CHAR_COUNT := CHAR_COUNT + 1;
  889.       end loop;                      -- Increment through passed string
  890.  
  891.        -- When the end of the string is reached, check if there is text being
  892.        -- accumulated that has not been written, set blank pos so the whole
  893.        -- set will be written to the display (disregard the last blank
  894.        -- encountered), and put this text on the screen.
  895.       if (START_POS <= STR'LAST) then
  896.          BLANK_POS := START_POS - 1;
  897.          PUT_THIS_LINE;
  898.       end if;
  899.  
  900.    end PUT_MESSAGE_TO_SCREEN;
  901.  
  902.  
  903.  
  904.    procedure INITIALIZE_MESSAGES is
  905.     -- This procedure reads the COMERRS file into the array that will be used
  906.     -- while the Menu Compiler and Menu Handler run.
  907.       ERROR_MESSAGE_FILE: TEXT_IO.FILE_TYPE;      -- internal file name
  908.       ERROR_TYPE_STRING: STRING(1..MESSAGE_SIZE); -- input string used
  909.       LAST_INDEX: POSITIVE;                       -- index for input string
  910.       OLD_LINE: TEXT_IO.POSITIVE_COUNT;           -- Line number of file
  911.    begin
  912.        -- Open the COMERRS file
  913.       TEXT_IO.OPEN(ERROR_MESSAGE_FILE, TEXT_IO.IN_FILE, "COMERRS");
  914.       for I in 1..LAST_MESSAGE loop
  915.        -- Read for each message: the severity code which is converted from
  916.        -- string type to enumeration type, and read the message text.
  917.          TEXT_IO.GET_LINE(ERROR_MESSAGE_FILE,ERROR_TYPE_STRING,LAST_INDEX);
  918.          MESSAGE_LIST(I).ERROR_STATUS := ERROR_TYPES'VALUE
  919.                 (ERROR_TYPE_STRING(1..LAST_INDEX));
  920.  
  921.          OLD_LINE := TEXT_IO.LINE(ERROR_MESSAGE_FILE);
  922.          TEXT_IO.GET_LINE(ERROR_MESSAGE_FILE,ERROR_TYPE_STRING,LAST_INDEX);
  923.          if LAST_INDEX < MESSAGE_SIZE then
  924.             ERROR_TYPE_STRING(LAST_INDEX+1..MESSAGE_SIZE) :=
  925.         (LAST_INDEX+1..MESSAGE_SIZE => ' ');
  926.          end if;
  927.          if INTEGER(TEXT_IO.LINE(ERROR_MESSAGE_FILE)) = INTEGER(OLD_LINE) then
  928.             TEXT_IO.SKIP_LINE(ERROR_MESSAGE_FILE);
  929.          end if;
  930.          MESSAGE_LIST(I).MESSAGE_LINE := ERROR_TYPE_STRING;
  931.       end loop;
  932.        -- Close file after reading all messages, or receiving END_ERROR.
  933.       TEXT_IO.CLOSE(ERROR_MESSAGE_FILE);
  934.    exception
  935.       when CONSTRAINT_ERROR =>
  936.          PUT_MESSAGE_TO_SCREEN(" Error in reading COMERRS file. ");
  937.       when TEXT_IO.DATA_ERROR =>
  938.          PUT_MESSAGE_TO_SCREEN(" Error in reading COMERRS file. ");
  939.       when TEXT_IO.END_ERROR =>
  940.          TEXT_IO.CLOSE(ERROR_MESSAGE_FILE);
  941.    end INITIALIZE_MESSAGES;
  942.  
  943.  
  944.  
  945.  
  946.    procedure SEND_SIMPLE_MESSAGE(CODE: in INTEGER) is
  947.     -- Procedure is used if only the text of a message is to be displayed on
  948.     -- the screen (the message is identified by the numeric code).
  949.    begin
  950.       PUT_MESSAGE_TO_SCREEN(MESSAGE_LIST(CODE).MESSAGE_LINE);
  951.    end SEND_SIMPLE_MESSAGE;
  952.  
  953.  
  954.  
  955.    procedure SEND_COMPILE_ERROR(CODE: in INTEGER) is
  956.     -- Procedure is used to send a compiler error. The text sent to the display
  957.     -- includes the message number code, the line number, the severity of the
  958.     -- error, the lexical unit, and the text of the message.
  959.  
  960.       CODE_STRING : STRING(1..4);       -- String that is numeric error code.
  961.       LINE_POSITION : STRING(1..7);     -- String that is line number of error.
  962.  
  963.    begin
  964.        -- Convert code and line number to string, put line to display
  965.        -- containing numeric error code, line number, and severity code.
  966.       INTEGER_IO.PUT(CODE_STRING,CODE);
  967.       INTEGER_IO.PUT(LINE_POSITION,CURRENT_LINE_NUMBER);
  968.       TEXT_IO.NEW_LINE;
  969.       TEXT_IO.NEW_LINE;
  970.       PUT_MESSAGE_TO_SCREEN (
  971.     " <= Error Number " & CODE_STRING & 
  972.     "     Line Position " & LINE_POSITION & "   " &
  973.     ERROR_TYPES'IMAGE(MESSAGE_LIST(CODE).ERROR_STATUS) );
  974.  
  975.        -- Put text to display containing current lexical string in Menu Def
  976.        -- File where error was detected.
  977.       TEXT_IO.NEW_LINE;
  978.       PUT_MESSAGE_TO_SCREEN(" < " &
  979.         TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING)
  980.                     & " >");
  981.  
  982.        -- Put text of the message to the display.
  983.       TEXT_IO.NEW_LINE;
  984.       PUT_MESSAGE_TO_SCREEN(MESSAGE_LIST(CODE).MESSAGE_LINE);
  985.  
  986.        -- Update Current Error Status so that it always contains the highest
  987.        -- error severity code yet found.
  988.       if (MESSAGE_LIST(CODE).ERROR_STATUS < CURRENT_ERROR_STATUS) then
  989.          CURRENT_ERROR_STATUS := MESSAGE_LIST(CODE).ERROR_STATUS;
  990.       end if;
  991.  
  992.        -- Increment total number of errors.
  993.       NUMBER_OF_ERRORS := NUMBER_OF_ERRORS + 1;
  994.  
  995.    end SEND_COMPILE_ERROR;
  996.  
  997.  
  998.  
  999.    procedure SEND_FINAL_MESSAGE is
  1000.     -- Sends a final summary message to the screen, includes the total number
  1001.     -- of errors, the highest severity of error, and message text.
  1002.       NUMBER_ERRORS_STRING: STRING(1..4);    -- String that is total errors.
  1003.  
  1004.    begin
  1005.        -- Convert total errors to string, put text to display.
  1006.       INTEGER_IO.PUT(NUMBER_ERRORS_STRING,NUMBER_OF_ERRORS);
  1007.       TEXT_IO.NEW_LINE;
  1008.       TEXT_IO.NEW_LINE;
  1009.       PUT_MESSAGE_TO_SCREEN("Menu Compiler EXITING with " &
  1010.         NUMBER_ERRORS_STRING & " error(s).");
  1011.  
  1012.        -- Put text to display depending on the final severity code. The
  1013.        -- different messages explain whether or not compilation finished,
  1014.        -- and/or Menu Def Table is created.
  1015.       TEXT_IO.NEW_LINE;
  1016.       case CURRENT_ERROR_STATUS is
  1017.        when FATAL_ERROR =>
  1018.     PUT_MESSAGE_TO_SCREEN (MESSAGE_LIST(20).MESSAGE_LINE);
  1019.  
  1020.        when DISABLING_ERROR =>
  1021.     PUT_MESSAGE_TO_SCREEN (MESSAGE_LIST(21).MESSAGE_LINE);
  1022.  
  1023.        when WARNING_ERROR =>
  1024.     PUT_MESSAGE_TO_SCREEN (MESSAGE_LIST(22).MESSAGE_LINE);
  1025.  
  1026.        when NO_ERROR =>
  1027.     PUT_MESSAGE_TO_SCREEN (MESSAGE_LIST(23).MESSAGE_LINE);
  1028.  
  1029.       end case;
  1030.  
  1031.    end SEND_FINAL_MESSAGE;
  1032.  
  1033.  
  1034.  
  1035.    procedure SEND_RUNTIME_ERROR (CODE: in INTEGER) is
  1036.     -- This procedure is used to send messages during the Menu Handler. It 
  1037.     -- shows the numeric code, the message text, and waits for any key to be
  1038.     -- typed to return control the calling program.
  1039.  
  1040.       CODE_STRING: STRING(1..4);   -- String that is numeric error code.
  1041.       INPUT_CHAR: CHARACTER;       -- Character input to exit program.
  1042.  
  1043.    begin
  1044.        -- Convert code to string, put text to display.
  1045.       INTEGER_IO.PUT(CODE_STRING,CODE);
  1046.       TEXT_IO.NEW_LINE;
  1047.       PUT_MESSAGE_TO_SCREEN (
  1048.     "<= Run Time Error Number " & CODE_STRING & "     " &
  1049.     ERROR_TYPES'IMAGE(MESSAGE_LIST(CODE).ERROR_STATUS) );
  1050.  
  1051.        -- Always keep current error status to the most severe error yet.
  1052.       if (MESSAGE_LIST(CODE).ERROR_STATUS < CURRENT_ERROR_STATUS) then
  1053.          CURRENT_ERROR_STATUS := MESSAGE_LIST(CODE).ERROR_STATUS;
  1054.       end if;
  1055.  
  1056.        -- Put text corresponding to this error code to the display.
  1057.       PUT_MESSAGE_TO_SCREEN (MESSAGE_LIST(CODE).MESSAGE_LINE);
  1058.       PUT_MESSAGE_TO_SCREEN (" Type Any Key to continue.");
  1059.  
  1060.        -- Wait for user to type any key to continue.
  1061.       TEXT_IO.GET(INPUT_CHAR);
  1062.  
  1063.    end SEND_RUNTIME_ERROR;
  1064.  
  1065.  
  1066.  
  1067.  
  1068.    function FATAL_ERROR_STATUS return BOOLEAN is
  1069.     -- Returns true if any errors have been found during this compilation
  1070.     -- which are of Fatal severity or worse (nothing is worse yet).
  1071.    begin
  1072.       return (CURRENT_ERROR_STATUS <= FATAL_ERROR);
  1073.    end FATAL_ERROR_STATUS;
  1074.  
  1075.  
  1076.  
  1077.    function DISABLE_ERROR_STATUS return BOOLEAN is
  1078.     -- Returns true if any errors have been found during this compilation
  1079.     -- which are of Disabling severity or worse.
  1080.    begin
  1081.       return (CURRENT_ERROR_STATUS <= DISABLING_ERROR);
  1082.    end DISABLE_ERROR_STATUS;
  1083.  
  1084.  
  1085.  
  1086.    function WARNING_ERROR_STATUS return BOOLEAN is
  1087.     -- Returns true if any errors have been found during this compilation
  1088.     -- which are of Warning severity or worse.
  1089.    begin
  1090.       return (CURRENT_ERROR_STATUS <= WARNING_ERROR);
  1091.    end WARNING_ERROR_STATUS;
  1092.  
  1093.  
  1094.  
  1095. end COMPILER_MESSAGES;
  1096. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1097. --contined.ada
  1098. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1099.  
  1100. -- CONTROLLING_MENU_INFO_LINE;CONTINED;KJL;04/16/85
  1101.  
  1102. -- Package body used to hold and process the Menu Information Line. This line
  1103. -- appears at the second to last line of the menu display. It gives simple
  1104. -- information to the menu user, when a menu is displayed. The line is usually
  1105. -- blank, but will display the Bad Selection Message if necessary, or a
  1106. -- message that a task was started. This package can be changed to cause the
  1107. -- Menu Information Line to display other information should the system expand.
  1108.  
  1109. package body CONTROLLING_MENU_INFO_LINE is
  1110.  
  1111.     -- A character string that will fit on the display screen.
  1112.    subtype SCREEN_STRING is STRING(1..SCREEN_WIDTH);
  1113.  
  1114.     -- The Menu Information Line. It is initially blank.
  1115.    MENU_INFO_LINE: SCREEN_STRING := (1..SCREEN_WIDTH => ' ');
  1116.  
  1117.     -- This blank line in assigned to the Menu Info Line to clear it.
  1118.    BLANK_LINE: SCREEN_STRING := (1..SCREEN_WIDTH => ' ');
  1119.  
  1120.     -- The Bad Selection Message is received from the Menu Def Table of the 
  1121.     -- current menu to be displayed.
  1122.    BAD_SELECTION_MESSAGE: SCREEN_STRING;
  1123.  
  1124.  
  1125.     -- This procedure assigns the string given to the Bad Selection Message.
  1126.    procedure RECEIVE_BAD_SELECT_MESSAGE (BAD_SELECT_MSG: in STRING) is
  1127.    begin
  1128.       BAD_SELECTION_MESSAGE := BAD_SELECT_MSG;
  1129.    end RECEIVE_BAD_SELECT_MESSAGE;
  1130.  
  1131.  
  1132.     -- This procedure will set the Menu Information Line to the Bad Selection
  1133.     -- Message. The next time the Info Line is displayed, it will display the
  1134.     -- Bad Selection Message.
  1135.    procedure SET_BAD_SELECTION is
  1136.    begin
  1137.       MENU_INFO_LINE := BAD_SELECTION_MESSAGE;
  1138.    end SET_BAD_SELECTION;
  1139.  
  1140.  
  1141.     -- This procedure sets the Menu Info Line to tell that a task has started
  1142.     -- (a task is a CLI instruction that runs in background while the Menu
  1143.     -- Handler continues to display menus and accept inputs). The task name is
  1144.     -- passed to the procedure. The string assigned to the Menu Info Line is
  1145.     -- first checked to see if it will fit.
  1146.    procedure SET_TASK_STARTED (FILE_NAME: in STRING) is
  1147.        -- String telling task that started.
  1148.       INFO_STRING: constant STRING := " Task " & FILE_NAME & " has started.";
  1149.    begin
  1150.       if INFO_STRING'LENGTH <= SCREEN_WIDTH then
  1151.          MENU_INFO_LINE := BLANK_LINE;
  1152.          MENU_INFO_LINE(1..INFO_STRING'LENGTH) := INFO_STRING;
  1153.       end if;
  1154.    end SET_TASK_STARTED;
  1155.  
  1156.  
  1157.     -- Function returns a string of size SCREEN_WIDTH that is the value of the
  1158.     -- Menu Information Line. The Menu Information Line is blanked out before
  1159.     -- its value is returned so a temp variable is used.
  1160.    function RETURN_INFO_LINE return STRING is
  1161.       INFO_STRING: SCREEN_STRING := MENU_INFO_LINE;
  1162.    begin
  1163.       MENU_INFO_LINE := BLANK_LINE;
  1164.       return INFO_STRING;
  1165.    end RETURN_INFO_LINE;
  1166.  
  1167.  
  1168. end CONTROLLING_MENU_INFO_LINE;
  1169. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1170. --dispingd.ada
  1171. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1172.  
  1173.  
  1174. -- DISPLAY_PROCESSING;DISPINGD.ADA;KJL;04/09/85
  1175.  
  1176. -- This package contains procedures to handle the menu display. It stores
  1177. -- the display layout in an array of strings. The procedures are used to
  1178. -- process this array of strings, and output the display to a CRT.
  1179. -- The package keeps a Current Read counter, and a Current Write counter. These
  1180. -- value indicate the next display line to be read and written from the display
  1181. -- array. Display lines are read when the display is put to the Menu Def Table
  1182. -- file, they are written when the Menu Def File contains text to be put in
  1183. -- the screen layout, and when the Menu Def Table is read by the Menu Handler.
  1184.  
  1185.  
  1186. with TEXT_IO;
  1187. package body DISPLAY_PROCESSING is
  1188.  
  1189.     -- The data structure that will be used for the display layout array.
  1190.    subtype SCREEN_STRING is STRING (1..SCREEN_WIDTH);
  1191.    type SCREEN_TYPE is array (1..SCREEN_LENGTH) of SCREEN_STRING;
  1192.  
  1193.    SCREEN_LAYOUT: SCREEN_TYPE;     -- The display layout array.
  1194.  
  1195.     -- Current Read and Current Write counters
  1196.    CURRENT_LINE_READ, CURRENT_LINE_TO_WRITE: INTEGER;
  1197.  
  1198.  
  1199.    function GET_NEXT_SCREEN_LINE return STRING is
  1200.     -- Returns the next display line as determined by the Current Read counter.
  1201.    begin
  1202.       CURRENT_LINE_READ := CURRENT_LINE_READ + 1;
  1203.       return SCREEN_LAYOUT(CURRENT_LINE_READ);
  1204.    end GET_NEXT_SCREEN_LINE;
  1205.  
  1206.  
  1207.    function END_OF_SCREEN return BOOLEAN is
  1208.    begin
  1209.       return (CURRENT_LINE_READ >= SCREEN_LENGTH);
  1210.    end END_OF_SCREEN;
  1211.  
  1212.  
  1213.    procedure PUT_NEXT_SCREEN_LINE(DISPLAY_TEXT: in STRING) is
  1214.     -- Writes the next display line as determined by the Current Write counter.
  1215.    begin
  1216.       if CURRENT_LINE_TO_WRITE <= SCREEN_LENGTH then
  1217.          SCREEN_LAYOUT(CURRENT_LINE_TO_WRITE) := DISPLAY_TEXT;
  1218.          CURRENT_LINE_TO_WRITE := CURRENT_LINE_TO_WRITE + 1;
  1219.       end if;
  1220.       return;
  1221.    end PUT_NEXT_SCREEN_LINE;
  1222.  
  1223.  
  1224.    procedure PUT_SCREEN_TEXT(LINE, COLUMN: in INTEGER; DISPLAY_TEXT: in TEXT) is
  1225.     -- Writes text to the display layout array starting at the display line
  1226.     -- given, and the string index of that line given in the Column argument.
  1227.    begin
  1228.       SCREEN_LAYOUT(LINE)
  1229.          (COLUMN .. COLUMN + TEXT_HANDLER_SUBSET.LENGTH(DISPLAY_TEXT) - 1) :=
  1230.          TEXT_HANDLER_SUBSET.VALUE(DISPLAY_TEXT);
  1231.    end PUT_SCREEN_TEXT;
  1232.  
  1233.  
  1234.    procedure CLEAR_SCREEN_LAYOUT is
  1235.     -- Puts blanks in all the positions of the display layout array.
  1236.    begin
  1237.       SCREEN_LAYOUT :=
  1238.        (1..SCREEN_LENGTH => (1..SCREEN_WIDTH => ' ') );
  1239.        -- Reset Current Read and Current Write counters
  1240.       CURRENT_LINE_READ := 0;
  1241.       CURRENT_LINE_TO_WRITE := 1;
  1242.    end CLEAR_SCREEN_LAYOUT;
  1243.  
  1244.  
  1245.    procedure PUT_SCREEN_LAYOUT_TO_CRT is
  1246.     -- Using Text_Io procedures, each line of the display layout array is
  1247.     -- put to the display.
  1248.     -- The screen is drawn by sequentially writing each display line to the
  1249.     -- CRT. The Ada Text_Io package is used to do this. Should a particular
  1250.     -- installation contain more features that control the display layout
  1251.     -- of the CRT, this procedure could be changed to take advantage of such
  1252.     -- features. Currently the menu display will appear as a number of lines
  1253.     -- being written to the CRT, each pushing the previous one up the screen.
  1254.    begin
  1255.       for I in 1..SCREEN_LENGTH loop
  1256.          TEXT_IO.PUT_LINE(SCREEN_LAYOUT(I));
  1257.       end loop;
  1258.    end PUT_SCREEN_LAYOUT_TO_CRT;
  1259.  
  1260.  
  1261. end DISPLAY_PROCESSING; 
  1262. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1263. --handntsd.ada
  1264. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1265.  
  1266. -- HANDLE_COMPILER_COMPONENTS;HANDNTSD.ADA;KJL;04/18/85
  1267.  
  1268. -- This package contains subprograms used to process the lexical units found
  1269. -- in the Menu Definition File. The package keeps track of variables used as 
  1270. -- the compilation is running, ie, current column and line numbers for the
  1271. -- display layout, and the Bad Selection message last specified in the
  1272. -- Menu Def File.
  1273.  
  1274. package body HANDLE_COMPILER_COMPONENTS is
  1275.  
  1276.     -- range of valid values for column and line numbers. Values given in the
  1277.     -- Menu Def for column and line will be checked if "in" these sets.
  1278.    subtype VALID_COLUMN_NUMBERS is INTEGER
  1279.           range 1..SCREEN_WIDTH;
  1280.    subtype VALID_LINE_NUMBERS is INTEGER
  1281.           range 1..SCREEN_LENGTH;
  1282.  
  1283.    subtype UPPER_LETTERS is CHARACTER range 'A'..'Z';
  1284.    subtype LOWER_LETTERS is CHARACTER range 'a'..'z';
  1285.  
  1286.     -- Used to determine lex unit type.
  1287.    USER_LITERAL: constant := 1;
  1288.    IDENTIFIER:   constant := 0;
  1289.  
  1290.     -- Name of Menu Def Table to be created.
  1291.    CURRENT_MENU_FILE_NAME: TEXT;
  1292.  
  1293.     -- Column and line of menu display layout for the next request for text
  1294.     -- to be put in the display layout.
  1295.    CURRENT_COLUMN_NUMBER: VALID_COLUMN_NUMBERS := 1;
  1296.    CURRENT_LINE_NUMBER: VALID_LINE_NUMBERS := 1;
  1297.  
  1298.     -- Text for bad selection message.
  1299.    BAD_SELECTION_MESSAGE: TEXT;
  1300.  
  1301.  
  1302.     -- Procedure is instantiated with an enumeration type, it accepts a
  1303.     -- character and gives the element of the enumeration set corresponding to
  1304.     -- the character, or it gives an error if no element matches the char.
  1305.    generic
  1306.       type ENUM_TYPE is (<>);
  1307.    procedure CHAR_TO_ENUM_TYPE (CHAR: in CHARACTER;
  1308.             RETURNED_CODE: out ENUM_TYPE;  INVALID: out BOOLEAN);
  1309.     -- Procedure body
  1310.    procedure CHAR_TO_ENUM_TYPE (CHAR: in CHARACTER;
  1311.             RETURNED_CODE: out ENUM_TYPE;  INVALID: out BOOLEAN) is
  1312.       CHAR_TO_STRING: STRING(1..1) := (1 => CHAR);
  1313.    begin
  1314.        -- Initialize arguments passed.
  1315.       INVALID := FALSE;
  1316.       RETURNED_CODE := ENUM_TYPE'FIRST;
  1317.       RETURNED_CODE := ENUM_TYPE'VALUE(CHAR_TO_STRING);
  1318.    exception
  1319.        -- Exception raised if no correspondence to the character.
  1320.       when CONSTRAINT_ERROR =>
  1321.          INVALID := TRUE;
  1322.    end CHAR_TO_ENUM_TYPE;
  1323.  
  1324.  
  1325.     -- Function returns the upper case of a lower case character. Will return
  1326.     -- the character itself if the input character is not a lower case
  1327.     -- character.
  1328.    function LOWER_TO_UPPER(CHAR: CHARACTER) return CHARACTER is
  1329.      type UPPER_LETTERS is new CHARACTER range 'A'..'Z';
  1330.      type LOWER_LETTERS is new CHARACTER range 'a'..'z';
  1331.      BIG: UPPER_LETTERS;
  1332.      LITTLE: LOWER_LETTERS;
  1333.    begin
  1334.       -- Convert input character to lower case character. If in char is not
  1335.       -- lower case, an exception will be raised.
  1336.      LITTLE := LOWER_LETTERS(CHAR);
  1337.       -- Get the upper case char corresponding to the lower case char.
  1338.      BIG := UPPER_LETTERS'VAL(LOWER_LETTERS'POS(LITTLE));
  1339.       -- return a value of character type.
  1340.      return CHARACTER(BIG);
  1341.    exception
  1342.      when CONSTRAINT_ERROR =>
  1343.         return CHAR;
  1344.    end LOWER_TO_UPPER;
  1345.  
  1346.  
  1347.  
  1348.     -- Procedure is called when a "Select" identifier is found in the Menu
  1349.     -- Definition string. The procedure obtains the other lex units needed for
  1350.     -- a full Select instruction. If a correct syntax instruction is found, a
  1351.     -- Menu Control Item is added to the Control Item List (kept in another
  1352.     -- package).
  1353.    procedure PROCESS_SELECT is
  1354.  
  1355.        -- Used to pack the text (remove trailing and leading blanks).
  1356.       TEMP_TEXT: TEXT;
  1357.  
  1358.        -- The key given to initiate action on the resulting menu.
  1359.       SELECT_KEY: CHARACTER;
  1360.  
  1361.        -- Menu to display following the action performed (defaults to the
  1362.        -- current menu def table if no other name is given).
  1363.       NEXT_MENU: TEXT;
  1364.  
  1365.        -- Type of action to perform on this selection in resulting menu
  1366.        -- (program, task, Ada procedure, menu..).
  1367.       ACTION_CODE: ACTION_TYPE;
  1368.  
  1369.        -- Used if a Next Menu is specified.
  1370.       MENU_ACTION_CODE: ACTION_TYPE;
  1371.  
  1372.        -- Text of command or name of file or procedure to execute on selection.
  1373.       FILE_EXECUTED: TEXT;
  1374.  
  1375.        -- True if action is only to call another menu.
  1376.       MENU_SELECTED: BOOLEAN;
  1377.  
  1378.        -- Used as error argument of procedures returning errors.
  1379.       ERROR: BOOLEAN;
  1380.  
  1381.        -- Converts character given to Action Type.
  1382.       procedure CHAR_TO_ACTION_TYPE is new CHAR_TO_ENUM_TYPE(ACTION_TYPE);
  1383.  
  1384.        -- Returns true if given character is in the give string.
  1385.       function MATCH(CHAR: CHARACTER; STR: STRING) return BOOLEAN is
  1386.          FOUND: BOOLEAN := FALSE;
  1387.       begin
  1388.           -- Compare character to each character in the string until found.
  1389.          for I in STR'FIRST..STR'LAST loop
  1390.             FOUND := (STR(I) = CHAR);
  1391.             exit when FOUND;
  1392.          end loop;
  1393.          return FOUND;
  1394.       end MATCH;
  1395.  
  1396.  
  1397.     -- Start PROCESS_SELECT procedure.
  1398.    begin
  1399.        -- After the "S..." Identifier, the next lex unit must be a valid 
  1400.        -- selection key in a user literal. Make  the next lexical unit
  1401.        -- available, and do the proper checks.
  1402.       GET_LEXICAL_UNIT_IF_NEEDED;
  1403.        -- Pack the text of the lex unit, to get just the key character and no
  1404.        -- blanks.
  1405.       TEMP_TEXT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1406.                (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1407.  
  1408.        -- Lex unit must be a user literal
  1409.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1410.          SEND_COMPILE_ERROR(03);
  1411.          UNIT_RECEIVED;
  1412.          return;
  1413.       end if;
  1414.  
  1415.        -- Length of lex unit must be 1 for single character, or 0 for 
  1416.        -- space bar.
  1417.       if (TEXT_HANDLER_SUBSET.LENGTH(TEMP_TEXT) > 1) or
  1418.          (TEXT_HANDLER_SUBSET.LENGTH(TEMP_TEXT) < 0) then
  1419.          SEND_COMPILE_ERROR(04);
  1420.          return;
  1421.       end if;
  1422.  
  1423.        -- Selection key is a space bar if length is 0,
  1424.       if (TEXT_HANDLER_SUBSET.LENGTH(TEMP_TEXT) = 0) then
  1425.          SELECT_KEY := ' ';
  1426.        -- Selection key must be valid if it is not the space bar.
  1427.       elsif not MATCH (TEXT_HANDLER_SUBSET.GIVE_POS(TEMP_TEXT,1),
  1428.            USABLE_SELECT_KEYS)  then
  1429.          SEND_COMPILE_ERROR(05);
  1430.          return;
  1431.       else
  1432.           -- Assign select key if character is valid.
  1433.          SELECT_KEY := TEXT_HANDLER_SUBSET.GIVE_POS(TEMP_TEXT,1);
  1434.       end if;
  1435.       TEXT_HANDLER_SUBSET.CLEAR_TEXT(TEMP_TEXT);
  1436.  
  1437.      -- Select key is obtained, the next lex unit should be an ACTION
  1438.      -- Identifier, specifying the type of action to perform on this menu
  1439.      -- selection. Make lex unit available, and do checks too insure the proper
  1440.      -- type of Identifier.
  1441.       GET_LEXICAL_UNIT_IF_NEEDED;
  1442.        -- Lex unit must be an Identifier.
  1443.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(IDENTIFIER)) then
  1444.          SEND_COMPILE_ERROR(06);
  1445.          UNIT_RECEIVED;
  1446.          return;
  1447.       end if;
  1448.  
  1449.        -- Convert the 1st character of the lex unit to an ACTION Identifier.
  1450.        -- Error on covertion is a syntax error.
  1451.       CHAR_TO_ACTION_TYPE
  1452.         ( LOWER_TO_UPPER(TEXT_HANDLER_SUBSET.GIVE_POS(CURRENT_LEX_STRING,1)),
  1453.       ACTION_CODE, ERROR );
  1454.       if ERROR then
  1455.          SEND_COMPILE_ERROR(07);
  1456.          UNIT_RECEIVED;
  1457.          return;
  1458.       end if;
  1459.  
  1460.        -- Action Code is obtained from selection instruction. The next lex unit
  1461.        -- must be a user literal giving the name of the command, file or 
  1462.        -- procedure to execute on this menu selection. Make the lex unit
  1463.        -- available, and check value.
  1464.       GET_LEXICAL_UNIT_IF_NEEDED;
  1465.        -- Lex unit must be a User Literal with file/command name.
  1466.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1467.          SEND_COMPILE_ERROR(08);
  1468.          UNIT_RECEIVED;
  1469.          return;
  1470.       end if;
  1471.  
  1472.        -- Pack the user literal to eliminate leading and trailing blanks,
  1473.        -- check that text specified is not longer than the maximum file size
  1474.        -- for a file name.
  1475.       TEMP_TEXT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1476.                (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1477.       if (TEXT_HANDLER_SUBSET.LENGTH(TEMP_TEXT) > FILE_STRING_SIZE) then
  1478.          SEND_COMPILE_ERROR(26);
  1479.          return;
  1480.       end if;
  1481.  
  1482.       FILE_EXECUTED := TEXT_HANDLER_SUBSET.TO_TEXT
  1483.                        (TEXT_HANDLER_SUBSET.VALUE(TEMP_TEXT));
  1484.       TEXT_HANDLER_SUBSET.CLEAR_TEXT(TEMP_TEXT);
  1485.  
  1486.        -- The file to execute is obtained. Now, if the action to be performed
  1487.        -- by this menu selection is to display another menu, then no other
  1488.        -- actions can be specified. If some other action was specified, the
  1489.        -- select instruction can now contain a specification for a Next Menu.
  1490.        -- The following code looks for the "Menu" Action Identifier, and a
  1491.        -- Menu Def Table name given in a User Literal. First check if a Menu
  1492.        -- Action Identifier was already specified.
  1493.       MENU_SELECTED := (ACTION_CODE = ACTION_TYPE'LAST);
  1494.  
  1495.        -- Use a Quit Construct to branch to the bottom of this logic since even
  1496.        -- on errors, the select info already obtained should be added to the
  1497.        -- Menu Control List.
  1498.       if MENU_SELECTED then
  1499.           -- The Next Menu info to be added to the Menu Control list will
  1500.           -- contain the name of the Menu Def Table specified in this selection
  1501.           -- instruction. If no Next Menu is specified, or errors occur while
  1502.           -- trying to find the "next menu", then the name of the Menu Def
  1503.           -- Table currently being defined will be the Next Menu.
  1504.          NEXT_MENU := FILE_EXECUTED;
  1505.          goto CONTINUE;
  1506.       end if;
  1507.  
  1508.        -- Possible that a Next Menu might be specified. Make the next lex unit
  1509.        -- available, and test if it is a "Menu" Identifier. If not, no error
  1510.        -- is displayed, since the next "Menu" specification in a selection
  1511.        -- instruction is optional.
  1512.       GET_LEXICAL_UNIT_IF_NEEDED;
  1513.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(IDENTIFIER)) then
  1514.          UNIT_RECEIVED;
  1515.           -- Menu displayed following this menu selection is the current menu.
  1516.          NEXT_MENU := CURRENT_MENU_FILE_NAME;
  1517.          goto CONTINUE;
  1518.       end if;
  1519.  
  1520.        -- See if the Identifier found is an Action Identifier. If not, no error
  1521.        -- is displayed, sice again, this is not required.
  1522.       CHAR_TO_ACTION_TYPE
  1523.         ( LOWER_TO_UPPER(TEXT_HANDLER_SUBSET.GIVE_POS(CURRENT_LEX_STRING,1)),
  1524.           MENU_ACTION_CODE, ERROR );
  1525.       if ERROR then
  1526.          UNIT_RECEIVED;
  1527.          NEXT_MENU := CURRENT_MENU_FILE_NAME;
  1528.          goto CONTINUE;
  1529.       end if;
  1530.        -- If an Action Identifier is found, it better be a "Menu", since only
  1531.        -- on command/program/procedure... is allowed on a selection. The
  1532.        -- Selection instruction is not thrown out on an error, the current menu
  1533.        -- is set as the next menu, and the first action found is still entered
  1534.        -- in the Menu Control List.
  1535.       if (MENU_ACTION_CODE /= ACTION_TYPE'LAST) then
  1536.          SEND_COMPILE_ERROR(09);
  1537.          NEXT_MENU := CURRENT_MENU_FILE_NAME;
  1538.          goto CONTINUE;
  1539.       end if;
  1540.  
  1541.        -- At this point the Selection instruction contains a Menu Action
  1542.        -- Identifier, and the next lex unit must be a user literal giving the
  1543.        -- name of the Menu Def Table to be used for the menu following the
  1544.        -- selection action. If errors occur in finding this user literal, they
  1545.        -- will be displayed to the user.
  1546.       GET_LEXICAL_UNIT_IF_NEEDED;
  1547.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1548.          SEND_COMPILE_ERROR(10);
  1549.          UNIT_RECEIVED;
  1550.          NEXT_MENU := CURRENT_MENU_FILE_NAME;
  1551.          goto CONTINUE;
  1552.       end if;
  1553.  
  1554.        -- Pack the text that is the Menu Def Table name, check that text is
  1555.        -- within legal size.
  1556.       TEMP_TEXT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1557.                (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1558.       if TEXT_HANDLER_SUBSET.LENGTH(TEMP_TEXT) > FILE_STRING_SIZE then
  1559.          SEND_COMPILE_ERROR(26); -- File name is to long
  1560.          NEXT_MENU := CURRENT_MENU_FILE_NAME;
  1561.       else
  1562.           -- User Literal is the name of the Menu Def Table that is the next
  1563.           -- menu displayed following this selection action.
  1564.          NEXT_MENU := TEXT_HANDLER_SUBSET.TO_TEXT
  1565.                       (TEXT_HANDLER_SUBSET.VALUE(TEMP_TEXT));
  1566.       end if;
  1567.       TEXT_HANDLER_SUBSET.CLEAR_TEXT(TEMP_TEXT);
  1568.       <<CONTINUE>>
  1569.  
  1570.        -- Add all the information found from this selection instruction to the
  1571.        -- Menu Control List. The procedure put the information in the form
  1572.        -- needed for the list, and adds it. The list is in another package.
  1573.       ADD_MENU_CONTROL_ITEM(SELECT_KEY,NEXT_MENU,FILE_EXECUTED,ACTION_CODE);
  1574.  
  1575.    end PROCESS_SELECT;
  1576.  
  1577.  
  1578.  
  1579.     -- Procedure is used when a "Column" Identifier is found in the code. The 
  1580.     -- procedure looks for a User Literal containing a valid column number, and
  1581.     -- updates the Current Column Number for placing text in the display layout
  1582.    procedure LOAD_COLUMN_NUMBER is
  1583.        -- Used to get an integer for the Column number.
  1584.       TEMP_COLUMN: VALID_COLUMN_NUMBERS;
  1585.        -- Used to pack the User Literal Text.
  1586.       TEMP_TEXT: TEXT;
  1587.    begin
  1588.        -- The next lex unit must be a User Literal containing the Column number
  1589.       GET_LEXICAL_UNIT_IF_NEEDED;
  1590.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1591.           SEND_COMPILE_ERROR(11);
  1592.           UNIT_RECEIVED;
  1593.       else
  1594.           -- Pack User Literal, and assign value of string to the object
  1595.           -- constrained to the valid column numbers. If the value is outside
  1596.           -- the valid column number values, a CONSTRAINT_ERROR will result.
  1597.      TEMP_TEXT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1598.                     (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1599.          TEMP_COLUMN := VALID_COLUMN_NUMBERS'VALUE
  1600.                 (TEXT_HANDLER_SUBSET.VALUE(TEMP_TEXT));
  1601.          CURRENT_COLUMN_NUMBER := TEMP_COLUMN;
  1602.       end if;
  1603.       return;
  1604.    exception
  1605.       when CONSTRAINT_ERROR =>
  1606.          -- Exception raised when assignment of a value outside the legal
  1607.          -- column numbers is attempted to a constrained object.
  1608.         SEND_COMPILE_ERROR(12);
  1609.    end LOAD_COLUMN_NUMBER;
  1610.  
  1611.  
  1612.  
  1613.     -- Procedure is used when a "Line" Identifier is found in the code. The 
  1614.     -- procedure looks for a User Literal containing a valid line number, and
  1615.     -- updates the Current Line Number for placing text in the display layout
  1616.    procedure LOAD_LINE_NUMBER is
  1617.        -- Used to get an integer for the Line number.
  1618.       TEMP_LINE: VALID_LINE_NUMBERS;
  1619.        -- Used to pack the User Literal Text.
  1620.       TEMP_TEXT: TEXT;
  1621.    begin
  1622.        -- The next lex unit must be a User Literal containing the Line number
  1623.       GET_LEXICAL_UNIT_IF_NEEDED;
  1624.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1625.           SEND_COMPILE_ERROR(13);
  1626.           UNIT_RECEIVED;
  1627.       else
  1628.           -- Pack User Literal, and assign value of string to the object
  1629.           -- constrained to the valid line numbers. If the value is outside
  1630.           -- the valid line number values, a CONSTRAINT_ERROR will result.
  1631.      TEMP_TEXT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1632.                     (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1633.          TEMP_LINE := VALID_LINE_NUMBERS'VALUE
  1634.                 (TEXT_HANDLER_SUBSET.VALUE(TEMP_TEXT));
  1635.          CURRENT_LINE_NUMBER := TEMP_LINE;
  1636.       end if;
  1637.       return;
  1638.    exception
  1639.       when CONSTRAINT_ERROR =>
  1640.          -- Exception raised when assignment of a value outside the legal
  1641.          -- line numbers is attempted to a constrained object.
  1642.         SEND_COMPILE_ERROR(14);
  1643.    end LOAD_LINE_NUMBER;
  1644.  
  1645.  
  1646.  
  1647.     -- Procedure is used when an "Error.." Identifier is found in the code. It
  1648.     -- will look for a User Literal containing the Bad Selection Message. The
  1649.     -- message must fit on the screen width, so this check is made.
  1650.    procedure LOAD_BAD_SELECTION_MESSAGE is
  1651.    begin
  1652.        -- User Literal containing Bad Selection Message must be found.
  1653.       GET_LEXICAL_UNIT_IF_NEEDED;
  1654.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1655.          SEND_COMPILE_ERROR(15);
  1656.          UNIT_RECEIVED;
  1657.  
  1658.        -- The Message must fit in the screen width.
  1659.       elsif (TEXT_HANDLER_SUBSET.LENGTH(CURRENT_LEX_STRING) > SCREEN_WIDTH) then
  1660.          SEND_COMPILE_ERROR(16);
  1661.       else
  1662.           -- Set Bad Selection Message.
  1663.          BAD_SELECTION_MESSAGE := TEXT_HANDLER_SUBSET.TO_TEXT
  1664.                           (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1665.       end if;
  1666.       return;
  1667.    end LOAD_BAD_SELECTION_MESSAGE;
  1668.  
  1669.  
  1670.  
  1671.     -- The first non-comment lex unit of the Menu Def Table must be a User
  1672.     -- Literal that specifys the name of the Menu Def Table that will be
  1673.     -- created by this Menu Definition. This procedure gets this User Literal,
  1674.     -- and sets the Current Menu File Name.
  1675.    procedure GET_THE_TITLE is
  1676.        -- Used to pack the user literal text.
  1677.       TEMP_TEXT: TEXT;
  1678.    begin
  1679.        -- Make lexical unit available, and check if it is a User Literal
  1680.       GET_LEXICAL_UNIT_IF_NEEDED;
  1681.       if (CURRENT_LEX_TYPE /= LEXICAL_UNIT_TYPES'VAL(USER_LITERAL)) then
  1682.          SEND_COMPILE_ERROR(17);
  1683.           -- On error, the current menu file name is a null string.
  1684.          TEXT_HANDLER_SUBSET.CLEAR_TEXT(CURRENT_MENU_FILE_NAME);
  1685.          UNIT_RECEIVED;
  1686.       else
  1687.      CURRENT_MENU_FILE_NAME := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  1688.                     (TEXT_HANDLER_SUBSET.VALUE(CURRENT_LEX_STRING));
  1689.       end if;
  1690.    end GET_THE_TITLE;
  1691.  
  1692.  
  1693.  
  1694.     -- Procedure is used to process an identifier found in the Menu Definition.
  1695.     -- The Identifier is converted to an identifier code, and the proper
  1696.     -- procedure is called to handle each type of identifier.
  1697.    procedure PROCESS_IDENTIFIER(LEXICAL_STRING: in TEXT) is
  1698.  
  1699.        -- Legal Identifier codes. One of these letters must be the first letter
  1700.        -- of each Control Identifier.
  1701.        --   S - Select...   E - Error...   L - Line...   C - Column....
  1702.       type CONTROL_TYPE is (S,E,L,C);
  1703.  
  1704.        -- Code from conversion of character string to Control Identifier.
  1705.       IDENTIFIER_CODE: CONTROL_TYPE;
  1706.  
  1707.        -- Used as an error argument in procedures requiring it.
  1708.       ERROR: BOOLEAN;
  1709.  
  1710.        -- Procedure to convert a character string to an element within the 
  1711.        -- Control Identifier set.
  1712.       procedure CHAR_TO_CONTROL_TYPE is new CHAR_TO_ENUM_TYPE(CONTROL_TYPE);
  1713.  
  1714.  
  1715.    begin
  1716.        -- Get the Control Identifier referenced by the Lexical String. If the
  1717.        -- string does not correspond to a Control Identifier, an error is sent
  1718.        -- to the user display.
  1719.       CHAR_TO_CONTROL_TYPE
  1720.        ( LOWER_TO_UPPER(TEXT_HANDLER_SUBSET.GIVE_POS(LEXICAL_STRING,1)),
  1721.          IDENTIFIER_CODE, ERROR );
  1722.       if (not ERROR) then
  1723.           -- Call the necessary procedure for what ever type of Control
  1724.           -- Identifier has been found.
  1725.          case IDENTIFIER_CODE is
  1726.                 when S =>
  1727.                    PROCESS_SELECT;
  1728.                 when L =>
  1729.                    LOAD_LINE_NUMBER;
  1730.                 when C =>
  1731.                    LOAD_COLUMN_NUMBER;
  1732.                 when E =>
  1733.                    LOAD_BAD_SELECTION_MESSAGE;
  1734.          end case;
  1735.       else
  1736.           -- Send error if invalid Control Identifier.
  1737.          SEND_COMPILE_ERROR(18);
  1738.       end if;
  1739.  
  1740.    end PROCESS_IDENTIFIER;
  1741.  
  1742.  
  1743.  
  1744.     -- This procedure is used when an unqualifiered User Literal is found in
  1745.     -- the Menu Definition, that is, a User Literal that does not follow any
  1746.     -- Identifiers, or is not expected as qualifying something. The text of
  1747.     -- the User Literal found will be placed in the Menu Display Layout at the
  1748.     -- current line and column position.
  1749.    procedure WRITE_SCREEN_LAYOUT_TEXT(LEXICAL_STRING: in TEXT) is
  1750.        -- Used to determine if the text will fit on the screen.
  1751.       X_COLUMN: INTEGER;
  1752.  
  1753.    begin
  1754.        -- First, determine whether or not the text of the user literal will fit
  1755.        -- on the display layout, given the current column number.
  1756.       X_COLUMN := TEXT_HANDLER_SUBSET.LENGTH(LEXICAL_STRING) + CURRENT_COLUMN_NUMBER - 1;
  1757.        -- Send error if text will not fit.
  1758.       if (X_COLUMN > SCREEN_WIDTH) then
  1759.          SEND_COMPILE_ERROR(19);
  1760.       else
  1761.           -- Put text to display layout.
  1762.          PUT_SCREEN_TEXT(CURRENT_LINE_NUMBER, CURRENT_COLUMN_NUMBER,
  1763.                 LEXICAL_STRING);
  1764.       end if;
  1765.    end WRITE_SCREEN_LAYOUT_TEXT;
  1766.  
  1767.  
  1768.  
  1769.     -- Returns the text that is the Bad Selection Message.
  1770.    function THE_BAD_SELECTION_MESSAGE return TEXT is
  1771.    begin
  1772.       return BAD_SELECTION_MESSAGE;
  1773.    end THE_BAD_SELECTION_MESSAGE;
  1774.  
  1775.  
  1776.  
  1777.     -- Returns the text that is the name or the Menu Def Table being created.
  1778.    function THE_TITLE_NAME return TEXT is
  1779.    begin
  1780.       return CURRENT_MENU_FILE_NAME;
  1781.    end THE_TITLE_NAME;
  1782.  
  1783.  
  1784.  
  1785.  
  1786. end HANDLE_COMPILER_COMPONENTS;
  1787. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1788. --handsesd.ada
  1789. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1790.  
  1791.  
  1792. -- HANDLE_PROCESSES;HANDSESD;KJL;04/17/85
  1793.  
  1794. -- This package contains subprograms used by the Menu Handler that processes
  1795. -- the requests for action, that result from the menu users inputs. This
  1796. -- package will also contain the file name of the Menu Definition Table that
  1797. -- defined the next menu to be displayed.
  1798.  
  1799. package body HANDLE_PROCESSES is
  1800.  
  1801.     -- The name of the next menu to be displayed.
  1802.    MENU_TO_DISPLAY: TEXT;
  1803.  
  1804.  
  1805.  
  1806.     -- This procedure is passed the string that is what the user input at the
  1807.     -- menu, and the type of input this was. The procedure will perform the
  1808.     -- necessary processing based on this users input, including retrieving
  1809.     -- the action(s) to perform, updating the name of the next menu to display,
  1810.     -- and issuing necessary error messages.
  1811.    procedure DO_REQUEST (CURRENT_MENU: in TEXT;  REQUEST_STRING: in TEXT;
  1812.              TYPE_OF_REQUEST: in INPUT_TYPES) is
  1813.  
  1814.        -- Constants used to specify Wait or Dont Wait code when issuing a CLI
  1815.        -- command of file name.
  1816.       WAIT: constant := 0;
  1817.       DONT_WAIT: constant := 1;
  1818.  
  1819.        -- Constant codes to identify types of user inputs.
  1820.       CLI_COMMAND: constant := 0;
  1821.       SELECTION: constant := 1;
  1822.  
  1823.        -- Constant codes to identify Action Codes retrieved from the Menu
  1824.        -- Control List.
  1825.       X: constant := 0;  T: constant := 1;  P: constant := 2;
  1826.       A: constant := 3;  M: constant := 4;
  1827.  
  1828.        -- The name or file name received from the Menu Control List that 
  1829.        -- corresponds to a given selection key.
  1830.       PROCESS_TO_PERFORM: TEXT;
  1831.  
  1832.        -- The type of action received from the Menu Control List, corresponding
  1833.        -- to the action received above.
  1834.       ACTION_OF_PROCESS: ACTION_TYPES;
  1835.  
  1836.        -- The name of the next menu to be displayed as retrieved from the 
  1837.        -- Menu Control List.
  1838.       MENU_FILE: TEXT;
  1839.  
  1840.        -- Error code used for procedures that return an error code.
  1841.       ERROR_CODE: BOOLEAN := TRUE;
  1842.  
  1843.  
  1844.     -- Begin the DO_REQUEST procedure.
  1845.    begin
  1846.        -- Clear the TEXT object holding the menu to be displayed, and set it
  1847.        -- equal to the Current Menu passed as an argument.
  1848.       TEXT_HANDLER_SUBSET.CLEAR_TEXT(MENU_TO_DISPLAY);
  1849.       MENU_TO_DISPLAY := CURRENT_MENU;
  1850.  
  1851.        -- Handle the types of user inputs
  1852.       if TYPE_OF_REQUEST = INPUT_TYPES'VAL(CLI_COMMAND) then
  1853.             -- On a CLI line input at the menu, the text of the line is
  1854.             -- coverted to a character string with no leading or trailing
  1855.             -- blanks, and the line is sent and a command line with a code
  1856.             -- for the Menu Handle to wait until the command is completed.
  1857.            COMMAND_LINE_PROCESSOR (TEXT_HANDLER_SUBSET.VALUE(REQUEST_STRING),
  1858.                     DONT_WAIT, ERROR_CODE);
  1859.             -- Error returned means the CLI could not process the line.
  1860.            if ERROR_CODE then
  1861.               SEND_RUNTIME_ERROR(33);
  1862.            end if;
  1863.            return;
  1864.       end if;
  1865.  
  1866.       if TYPE_OF_REQUEST = INPUT_TYPES'VAL(SELECTION) then
  1867.             -- On a selection input from menu user, first try to retrieve the
  1868.             -- Menu Control information from the Menu Control List, given the
  1869.             -- character select key the user input.
  1870.            RETRIEVE_CONTROL_ITEM (TEXT_HANDLER_SUBSET.GIVE_POS(REQUEST_STRING,
  1871.                    1), MENU_FILE, PROCESS_TO_PERFORM,
  1872.                   ACTION_OF_PROCESS, ERROR_CODE);
  1873.             -- An error means a Bad Selection was made, set the Menu Info Line
  1874.             -- to display the Bad Selection Message.
  1875.            if ERROR_CODE then
  1876.               SET_BAD_SELECTION;
  1877.               return;
  1878.            end if;
  1879.             -- Clear the Menu to be displayed, and assign it the value
  1880.             -- retrieved from the Menu Control List.
  1881.            TEXT_HANDLER_SUBSET.CLEAR_TEXT(MENU_TO_DISPLAY);
  1882.            MENU_TO_DISPLAY := MENU_FILE;
  1883.  
  1884.             -- Process the type of action to perform. The names passed to the
  1885.             -- procedures below will be converted form packed TEXT dynamic
  1886.             -- string types, to regular character strings.
  1887.            if ACTION_OF_PROCESS = ACTION_TYPES'VAL(X) then
  1888.                  -- Null action, do nothing.
  1889.                 null;
  1890.  
  1891.            elsif ACTION_OF_PROCESS = ACTION_TYPES'VAL(T) then
  1892.                  -- The action is a TASK, send the file name/ name to the CLI
  1893.                  -- with the code to continue the Menu Handler immediately.
  1894.                 COMMAND_LINE_PROCESSOR (TEXT_HANDLER_SUBSET.VALUE
  1895.                (PROCESS_TO_PERFORM), DONT_WAIT, ERROR_CODE);
  1896.                  -- Error returned from issuing the CLI command indicates the 
  1897.                  -- CLI could not process that command of or command file. If
  1898.                  -- the string was processed successfully by the CLI, set the
  1899.                  -- Menu Info Line to tell that the task was started.
  1900.                 if ERROR_CODE then
  1901.                    SEND_RUNTIME_ERROR (34);
  1902.                 else
  1903.                    SET_TASK_STARTED (TEXT_HANDLER_SUBSET.VALUE
  1904.                (PROCESS_TO_PERFORM) );
  1905.                 end if;
  1906.  
  1907.            elsif ACTION_OF_PROCESS = ACTION_TYPES'VAL(P) then
  1908.                  -- A PROGRAM action means the send the command name retrieved
  1909.                  -- to the CLI with a code for the Menu Handler to wait until
  1910.                  -- the the command is completed.
  1911.                 COMMAND_LINE_PROCESSOR (TEXT_HANDLER_SUBSET.VALUE
  1912.                        (PROCESS_TO_PERFORM), WAIT, ERROR_CODE);
  1913.                  -- An error returned will signal that the CLI could not
  1914.                  -- process the command of command file name given.
  1915.                 if ERROR_CODE then
  1916.                    SEND_RUNTIME_ERROR (35);
  1917.                 end if;
  1918.  
  1919.            elsif ACTION_OF_PROCESS = ACTION_TYPES'VAL(A) then
  1920.                  -- The A for Ada PROCEDURE CALL action causes the name
  1921.                  -- retrieved to be passed the the procedure that starts Ada
  1922.                  -- procedures. The Ada procedure called will execute to
  1923.                  -- completion before the Menu Handler returns.
  1924.                 ADA_PROCEDURE_CALL (TEXT_HANDLER_SUBSET.VALUE
  1925.                         (PROCESS_TO_PERFORM), ERROR_CODE);
  1926.                  -- The Error returned here means that the Ada procedure was
  1927.                  -- not found. The procedure must be linked to this program
  1928.                  -- for it to run.
  1929.                 if ERROR_CODE then
  1930.                    SEND_RUNTIME_ERROR(36);
  1931.                 end if;
  1932.  
  1933.            elsif ACTION_TYPES'VAL(M) = ACTION_TYPES'VAL(M) then
  1934.                  -- A MENU type action is just to do no action and set the 
  1935.                  -- next menu the be displayed to the name retrieved. This was
  1936.                  -- done at the beginning of this condition statement.
  1937.                 null;
  1938.            else
  1939.                 null;
  1940.            end if;
  1941.            return;
  1942.  
  1943.       end if;  -- Input Type is SELECTION.
  1944.  
  1945.    end DO_REQUEST;
  1946.  
  1947.  
  1948.  
  1949.     -- This function will return the name of the next menu to be displayed. The
  1950.     -- name will be in TEXT dynamic string form with no leading or trailing
  1951.     -- blanks around the name.
  1952.    function MENU_TO_BE_DISPLAYED return TEXT is
  1953.    begin
  1954.       return MENU_TO_DISPLAY;
  1955.    end MENU_TO_BE_DISPLAYED;
  1956.  
  1957.  
  1958.  
  1959. end HANDLE_PROCESSES;
  1960. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1961. --procbled.ada
  1962. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1963.  
  1964.  
  1965. -- PROCESS_MENU_CONTROL_TABLE;PROCBLED.ADA;KJL;04/16/85
  1966.  
  1967. -- This package contains subprograms necessary to hold and use the Menu Control
  1968. -- List. This list is a dynamic list of Menu Control Items, each item
  1969. -- characterizes a menu selection. Information contained in each item includes:
  1970. -- The selection key that is typed at resulting menu, the type of action that
  1971. -- is performed when this key is typed, and the name or file name involved in
  1972. -- such action. As an example, a Menu Control Item might contain information
  1973. -- defining that when this menu is run, the letter 'A' (selection key) may be
  1974. -- typed to invoke an operating system command 'GOJOB' (name or file name) that
  1975. -- will be performed in background while the menu returns to the screen (type
  1976. -- of action, translating the the TASK type). The Menu Control Item also 
  1977. -- contains a Next Menu which specifies the name of a Menu Def Table that will
  1978. -- be the next menu following the action performed.
  1979.  
  1980. -- This procedure also contains the subprograms used to write and read the
  1981. -- external file which is the Menu Definition Table. The file is written with
  1982. -- records that match the Menu Control Items. Other information written to the
  1983. -- file; the lines of the Menu Display Layout, and the Bad Selection Message,
  1984. -- are put into the same record structure then written to the file. The same
  1985. -- record structures are read from the file, and the Menu Control List, Menu
  1986. -- Display Layout, and Bad Selection Message is extracted.
  1987.  
  1988. with SEQUENTIAL_IO, TEXT_IO, UNCHECKED_DEALLOCATION;
  1989. package body PROCESS_MENU_CONTROL_TABLE is
  1990.  
  1991.     -- Character string that will hold the names and file names for processes
  1992.     -- invoked. The STRING type is used so the values can be written to file.
  1993.    subtype FILE_STRING_TYPE is STRING(1..FILE_STRING_SIZE);
  1994.  
  1995.     -- Character string that will hold Display Layout lines. The String type
  1996.     -- is used so the values can be written to file.
  1997.    subtype SCREEN_STRING_TYPE is STRING(1..SCREEN_STRING_SIZE);
  1998.  
  1999.     -- This record is used to hold a process name (file name, Menu Def Table
  2000.     -- name, Ada procedure name...), and the type of process of action.
  2001.    type PROCESS_DESCRIPTION is
  2002.     record
  2003.         ACTION_CODE: ACTION_TYPE;
  2004.         FILE_EXECUTED: FILE_STRING_TYPE;
  2005.      end record;
  2006.  
  2007.  
  2008.     -- This record is the information for the Menu Control Item. The NUMBER is
  2009.     -- the number of Menu Control Item in the list, SELECT_KEY is the character
  2010.     -- key to activate the action at the menu, NEXT_MENU is the Menu Def Table
  2011.     -- file name of the next menu to be displayed, PROCESSES specifies the
  2012.     -- action to perform, and MISC_INFO is used to hold other information when
  2013.     -- needed (such as the Display Layout line, and Bad Selection Message).
  2014.    type MENU_CONTROL_ITEM_TYPE is
  2015.      record
  2016.         NUMBER: INTEGER;
  2017.         SELECT_KEY: CHARACTER;
  2018.         NEXT_MENU: FILE_STRING_TYPE;
  2019.         PROCESSES: PROCESS_DESCRIPTION;
  2020.      MISC_INFO: SCREEN_STRING_TYPE;
  2021.      end record;
  2022.  
  2023.  
  2024.     -- The data structure used for the list of Menu Control Items is a dynamic
  2025.     -- array structure. The object that is the list will be an access type
  2026.     -- that points to an array of Menu Control Items. When a Control Item is
  2027.     -- added to the list, a new access object will point to a new array of
  2028.     -- Menu Control Items that is identical to the old one but one bigger.
  2029.  
  2030.     -- The array is unbounded so the access object can point to different
  2031.     -- arrays of different sizes.
  2032.    type CONTROL_ARRAY is array (POSITIVE range <>) of MENU_CONTROL_ITEM_TYPE;
  2033.  
  2034.     -- The access type that points to the unbounded array.
  2035.    type MENU_CONTROL_LIST_TYPE is access CONTROL_ARRAY;
  2036.  
  2037.  
  2038.     -- Blank line for file name and screen line strings. Used to clear the
  2039.     -- elements of the Menu Control Items.
  2040.    BLANK_FILE_STRING: FILE_STRING_TYPE :=
  2041.         (FILE_STRING_TYPE'FIRST..FILE_STRING_TYPE'LAST => ' ');
  2042.    BLANK_SCREEN_STRING: SCREEN_STRING_TYPE :=
  2043.         (SCREEN_STRING_TYPE'FIRST..SCREEN_STRING_TYPE'LAST => ' ');
  2044.  
  2045.  
  2046.     -- The following variables are all of the menu control item structure. They
  2047.     -- aree used to hold information in the proper structure, so that it can be
  2048.     -- written to the Menu Def Table file.
  2049.  
  2050.     -- The MISC_INFO element holds the Bad Selection Message.
  2051.    BAD_SELECTION_MESSAGE_ITEM: MENU_CONTROL_ITEM_TYPE;
  2052.  
  2053.     -- The NUMBER element holds the number of Menu Control Items written to the
  2054.     -- Menu Def Table file. Tells READ procedure when to look for "other" info.
  2055.    NUMBER_OF_CONTROL_ITEMS: MENU_CONTROL_ITEM_TYPE;
  2056.  
  2057.     -- The MISC_INFO element of this object will hold a line for the 
  2058.     -- Menu Display Layout.   
  2059.    SCREEN_LAYOUT_ITEM: MENU_CONTROL_ITEM_TYPE;
  2060.  
  2061.     -- This object will hold actual Menu Control Items as they are added to the
  2062.     -- Menu Control List, and as they are written to the Menu Def Table file.
  2063.    MENU_CONTROL_ITEM: MENU_CONTROL_ITEM_TYPE;
  2064.  
  2065.     -- The NUMBER element of this object will hold the critical cofiguration 
  2066.     -- items (screen width, and file name size), and these will be written to
  2067.     -- the Menu Def Table first. If these values are not concistent between
  2068.     -- writting in the Menu Compiler, and reading in the Menu Handler, then
  2069.     -- the reading will not complete successfully. An exception will be raised
  2070.     -- by the read procedure if the config info read is not the same as the
  2071.     -- current config info FILE_STRING_SIZE, and SCREEN_STRING_SIZE.
  2072.    CONFIG_INFO_ITEM: MENU_CONTROL_ITEM_TYPE;
  2073.  
  2074.  
  2075.     -- List of Menu Control Items. Really is a pointer to an array, since
  2076.     -- initially there are no elements, set the pointer to null.
  2077.    MENU_CONTROL_LIST: MENU_CONTROL_LIST_TYPE := null;
  2078.  
  2079.     -- Number of Menu Control Elements added to the list.
  2080.    CONTROL_LIST_COUNT: INTEGER := 0;
  2081.  
  2082.  
  2083.     -- This procedure is used to deallocate the space pointed to by old
  2084.     -- access object. Before a pointer is assigned to point to a new array of
  2085.     -- Menu Control Items, the old array must be deallocated.
  2086.    procedure FREE is new UNCHECKED_DEALLOCATION(CONTROL_ARRAY,
  2087.                 MENU_CONTROL_LIST_TYPE);
  2088.  
  2089.  
  2090.     -- Input/Output package that will input and output items of the Menu
  2091.     -- Control Item data structure.
  2092.    package MENU_CONTROL_ITEM_IO is new SEQUENTIAL_IO (MENU_CONTROL_ITEM_TYPE);
  2093.  
  2094.  
  2095.  
  2096.     -- Function returns an array of Menu Control Items that include all the
  2097.     -- items of the array argument, and one more which is the Menu Control
  2098.     -- Item argument.
  2099.    function CONCAT (CONTROL_ARRAY_PARAM: CONTROL_ARRAY;
  2100.     CONTROL_ITEM_PARAM: MENU_CONTROL_ITEM_TYPE) return CONTROL_ARRAY is
  2101.  
  2102.        -- Will hold the array that is one bigger than CONTROL_ARRAY_PARAM.
  2103.       TEMP_ARRAY: CONTROL_ARRAY
  2104.         (CONTROL_ARRAY_PARAM'FIRST..CONTROL_ARRAY_PARAM'LAST+1);
  2105.  
  2106.    begin
  2107.        -- Assign the elements of TEMP_ARRAY. The first elements are those of
  2108.        -- CONTROL_ARRAY_PARAM, the last element is the CONTROL_ITEM_PARAM.
  2109.       TEMP_ARRAY(CONTROL_ARRAY_PARAM'FIRST..CONTROL_ARRAY_PARAM'LAST) :=
  2110.        CONTROL_ARRAY_PARAM(CONTROL_ARRAY_PARAM'FIRST..CONTROL_ARRAY_PARAM'LAST);
  2111.       TEMP_ARRAY(CONTROL_ARRAY_PARAM'LAST+1) := CONTROL_ITEM_PARAM;
  2112.        -- Return the full array.
  2113.       return TEMP_ARRAY;
  2114.  
  2115.    end CONCAT;
  2116.  
  2117.  
  2118.  
  2119.     -- This procedure is used to add a new Menu Control Item to the Menu
  2120.     -- Control List. The procedure always adds the object MENU_CONTROL_ITEM
  2121.     -- to the object MENU_CONTROL_LIST.
  2122.    procedure ADD_ITEM_TO_LIST is
  2123.        -- Temp access object, used to free up allocated space.
  2124.       TEMP: MENU_CONTROL_LIST_TYPE;
  2125.    begin
  2126.       if MENU_CONTROL_LIST = null then
  2127.           -- This is the first entry in the list, so make the access object
  2128.           -- point too an array where the 1st element is the  Menu Control Item
  2129.          MENU_CONTROL_LIST := new CONTROL_ARRAY'((1 => MENU_CONTROL_ITEM));
  2130.       else
  2131.           -- To add an item to an existing list, first make an access object
  2132.           -- that points to an array with identical elements as the array that
  2133.           -- Menu Control List points to. Then free up the space pointed to by
  2134.           -- the Menu Control List pointer.
  2135.          TEMP := new CONTROL_ARRAY'(MENU_CONTROL_LIST.all);
  2136.          FREE(MENU_CONTROL_LIST);
  2137.           -- Make the Menu Control List a new pointer that points to an array
  2138.           -- that is the concatination of the old array elements (which is
  2139.           -- what the temp pointer points too), and the Menu Control Item. Then
  2140.           -- free up the space that the temp pointer is pointing to.
  2141.          MENU_CONTROL_LIST := new CONTROL_ARRAY'
  2142.             (CONCAT(TEMP.all,MENU_CONTROL_ITEM));
  2143.          FREE(TEMP);
  2144.       end if;
  2145.    end ADD_ITEM_TO_LIST;
  2146.  
  2147.  
  2148.  
  2149.     -- This procedure is used to add the information for a Menu Control Item
  2150.     -- to the Menu Control List. The information passed is: the selection key
  2151.     -- typed to initiate action on the menu, the name and type of action
  2152.     -- initiated, and the next menu to be displayed when control returns to
  2153.     -- the Menu Handler. The procedure puts the information in the data
  2154.     -- stucture of a Menu Contol Item then adds the Item to the Control List.
  2155.    procedure ADD_MENU_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  2156.                                     NEXT_MENU: in TEXT;
  2157.                                     FILE_NAME_OF_PROCESS: in TEXT;
  2158.                                     TYPE_OF_ACTION: in ACTION_TYPE) is
  2159.    begin
  2160.        -- Set up the information in a Menu Control Item data structure, blank
  2161.        -- all unneeded fields. The text strings are passed in TEXT format so
  2162.        -- convert the text to string fields of the proper size.
  2163.       MENU_CONTROL_ITEM :=
  2164.           (NUMBER        => CONTROL_LIST_COUNT,
  2165.            SELECT_KEY    => SELECT_KEY,
  2166.            NEXT_MENU     => TEXT_HANDLER_SUBSET.UNPACK_VALUE
  2167.                     (NEXT_MENU,FILE_STRING_SIZE),
  2168.            PROCESSES     =>
  2169.                     (ACTION_CODE    => TYPE_OF_ACTION,
  2170.                      FILE_EXECUTED  => TEXT_HANDLER_SUBSET.UNPACK_VALUE
  2171.                     (FILE_NAME_OF_PROCESS,FILE_STRING_SIZE)),
  2172.            MISC_INFO     => BLANK_SCREEN_STRING  );
  2173.  
  2174.        -- Add the Menu Control Item to the Control list, and increment the
  2175.        -- number of items in the list.
  2176.       ADD_ITEM_TO_LIST;
  2177.       CONTROL_LIST_COUNT := CONTROL_LIST_COUNT + 1;
  2178.  
  2179.    end ADD_MENU_CONTROL_ITEM;
  2180.  
  2181.  
  2182.  
  2183.     -- This procedure looks through the Menu Control List, and finds a Menu
  2184.     -- Control Item with a Select Key that matches the character given. If no
  2185.     -- match exists, an flag for not found is set. The information returned
  2186.     -- is: the name and type of the process to be performed, and the next menu
  2187.     -- to be displayed by the Menu Handler. The names are return in TEXT format
  2188.     -- so the character strings received from the Menu Control List are packed
  2189.     -- to TEXT form (blanks taken away, and put in TEXT form).
  2190.    procedure RETRIEVE_CONTROL_ITEM (SELECT_KEY: in CHARACTER;
  2191.                     NEXT_MENU: out TEXT;
  2192.                     FILE_NAME_OF_PROCESS: out TEXT;
  2193.                     TYPE_OF_ACTION: out ACTION_TYPE;
  2194.                      NOT_FOUND: out BOOLEAN) is
  2195.    begin
  2196.        -- Assume the item is not found, and loop through the number of Menu
  2197.        -- Control Items in the Menu Control List.
  2198.       NOT_FOUND := TRUE;
  2199.       for I in 1..CONTROL_LIST_COUNT loop
  2200.          if MENU_CONTROL_LIST.all(I).SELECT_KEY = SELECT_KEY then
  2201.             -- When the Select Key of a Menu Control Item matches the given
  2202.             -- select key, the item is found, set the return arguments, 
  2203.             -- set NOT FOUND to false, and exit the loop.
  2204.        NEXT_MENU := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  2205.               (MENU_CONTROL_LIST.all(I).NEXT_MENU);
  2206.            FILE_NAME_OF_PROCESS := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  2207.         (MENU_CONTROL_LIST.all(I).PROCESSES.FILE_EXECUTED);
  2208.            TYPE_OF_ACTION := MENU_CONTROL_LIST.all(I).
  2209.             PROCESSES.ACTION_CODE;
  2210.            NOT_FOUND := FALSE;
  2211.            exit;
  2212.          end if;
  2213.       end loop;
  2214.        -- If the Select Key is not found in all the Menu Control Items of the
  2215.        -- Menu Control List, then the Not Found flag will still be true when
  2216.        -- the loop runs out, and this status is returned.
  2217.       return;
  2218.    end RETRIEVE_CONTROL_ITEM;
  2219.  
  2220.  
  2221.  
  2222.  
  2223.     -- Procedure is used to write the Menu Definition File. The Menu Control
  2224.     -- List that is updated by this package, the Display Layout, and the Bad
  2225.     -- Selection Message are written to this file. The text of the Bad
  2226.     -- Selection Message is passed as an actual argument, but the lines of
  2227.     -- the Menu Display Layout are obtained by using the functions provided in
  2228.     -- the instantiation of this package. All information is put into the
  2229.     -- record structure the Menu Control Items, and these records are written
  2230.     -- to the file. The name of the file to created is passed as an argument.
  2231.     -- The name is passed in TEXT format and is packed (no leading or trailing
  2232.     -- blanks). An error code is returned by this procedure reflecting problems
  2233.     -- in creating the Menu Def Table file.
  2234.    procedure WRITE_MENU_CONTROL_FILE (FILE_NAME_OF_MENU_DEF_TABLE: in TEXT;
  2235.                                      BAD_SELECTION_MESSAGE: in TEXT;
  2236.                                      ERROR_CODE: out INTEGER) is
  2237.  
  2238.        -- Internal file name for the Menu Def Table. This name is used by the
  2239.        -- I/O fuctions.
  2240.       TABLE_FILE: MENU_CONTROL_ITEM_IO.FILE_TYPE;
  2241.  
  2242.    begin
  2243.        -- Assume no Errors, and open the file using the External file name
  2244.        -- passed to the procedure. The file name must not contain trailing or
  2245.        -- leading blanks. The CREATE operation will create a file with the
  2246.        -- name of the exact string. A packed file name in TEXT form is assumed.
  2247.       ERROR_CODE := 0;
  2248.       MENU_CONTROL_ITEM_IO.CREATE(TABLE_FILE,MENU_CONTROL_ITEM_IO.OUT_FILE,
  2249.                                    TEXT_HANDLER_SUBSET.VALUE(FILE_NAME_OF_MENU_DEF_TABLE));
  2250.  
  2251.        -- Put screen width and file name size into Menu Control Item type
  2252.        -- records, and write these to the Menu Def Table file. The integer
  2253.        -- values are put in the NUMBER field of the record.
  2254.       CONFIG_INFO_ITEM :=
  2255.           (NUMBER       => FILE_STRING_SIZE,
  2256.            SELECT_KEY    => ' ',
  2257.            NEXT_MENU     => BLANK_FILE_STRING,
  2258.            PROCESSES     =>
  2259.                     (ACTION_CODE     => ACTION_TYPE'FIRST,
  2260.                      FILE_EXECUTED   => BLANK_FILE_STRING),
  2261.            MISC_INFO     => BLANK_SCREEN_STRING);
  2262.       MENU_CONTROL_ITEM_IO.WRITE(TABLE_FILE, CONFIG_INFO_ITEM);
  2263.  
  2264.       CONFIG_INFO_ITEM.NUMBER := SCREEN_STRING_SIZE;
  2265.       MENU_CONTROL_ITEM_IO.WRITE(TABLE_FILE, CONFIG_INFO_ITEM);
  2266.  
  2267.  
  2268.        -- Put the Bad Selection Message in a Menu Control Item type record
  2269.        -- (the string is put into the MISC_INFO field), and write the record
  2270.        -- to the file.
  2271.       BAD_SELECTION_MESSAGE_ITEM :=
  2272.           (NUMBER        => 0,
  2273.            SELECT_KEY    => ' ',
  2274.            NEXT_MENU     => BLANK_FILE_STRING,
  2275.            PROCESSES     =>
  2276.                     (ACTION_CODE    => ACTION_TYPE'FIRST,
  2277.                      FILE_EXECUTED  => BLANK_FILE_STRING),
  2278.        MISC_INFO     => TEXT_HANDLER_SUBSET.UNPACK_VALUE
  2279.                (BAD_SELECTION_MESSAGE,SCREEN_STRING_SIZE) );
  2280.       MENU_CONTROL_ITEM_IO.WRITE(TABLE_FILE, BAD_SELECTION_MESSAGE_ITEM);
  2281.  
  2282.        -- Put the number of Menu Control Items in the Menu Control List into a
  2283.        -- Menu Control Item type record (put the integer into the NUMBER field
  2284.        -- and blank the other fields or the record). Write this record.
  2285.       NUMBER_OF_CONTROL_ITEMS :=
  2286.           (NUMBER        => CONTROL_LIST_COUNT,
  2287.            SELECT_KEY    => ' ',
  2288.            NEXT_MENU     => BLANK_FILE_STRING,
  2289.            PROCESSES     =>
  2290.                     (ACTION_CODE    => ACTION_TYPE'FIRST,
  2291.                      FILE_EXECUTED  => BLANK_FILE_STRING),
  2292.            MISC_INFO     => BLANK_SCREEN_STRING );
  2293.       MENU_CONTROL_ITEM_IO.WRITE(TABLE_FILE, NUMBER_OF_CONTROL_ITEMS);
  2294.  
  2295.  
  2296.        -- For each Menu Control Item in the Menu Control List, write the item
  2297.        -- to the file. The Menu Control List points to an array with all the
  2298.        -- items in it, so referencing an item is done by referencing the
  2299.        -- element of the array that is pointed to by Menu Control List.
  2300.       for I in 1..CONTROL_LIST_COUNT loop
  2301.      MENU_CONTROL_ITEM_IO.WRITE (TABLE_FILE, MENU_CONTROL_LIST.all(I));
  2302.       end loop;
  2303.  
  2304.  
  2305.        -- Now, for each line in the Menu Display Layout (from top to bottom)
  2306.        -- retrieve the text of the line and put it into a Menu Control Item
  2307.        -- type record (put it in the MISC_INFO field). The string retrieved
  2308.        -- is a character string of length SCREEN_STRING_SIZE, so the string
  2309.        -- is put directly into the record w/o converting it to another form.
  2310.        -- Write a record in the file for each line retrieved.
  2311.       while (not END_OF_SCREEN) loop
  2312.          SCREEN_LAYOUT_ITEM :=
  2313.           (NUMBER        => 0,
  2314.            SELECT_KEY    => ' ',
  2315.            NEXT_MENU     => BLANK_FILE_STRING,
  2316.            PROCESSES     =>
  2317.                     (ACTION_CODE    => ACTION_TYPE'FIRST,
  2318.                      FILE_EXECUTED  => BLANK_FILE_STRING),
  2319.        MISC_INFO     => GET_NEXT_SCREEN_LINE );
  2320.          MENU_CONTROL_ITEM_IO.WRITE(TABLE_FILE, SCREEN_LAYOUT_ITEM);
  2321.       end loop;
  2322.  
  2323.  
  2324.        -- The config information, Menu Control List, Menu Display Layout, and
  2325.        -- Bad Selection Message has been written to the file. Close the Menu
  2326.        -- Def Table file.
  2327.       MENU_CONTROL_ITEM_IO.CLOSE(TABLE_FILE);
  2328.  
  2329.    exception
  2330.       when MENU_CONTROL_ITEM_IO.NAME_ERROR =>
  2331.            -- exception will occur if the file name given to the procedure is
  2332.            -- not legal in the current operating system.
  2333.           ERROR_CODE := 1;
  2334.  
  2335.    end WRITE_MENU_CONTROL_FILE;
  2336.  
  2337.  
  2338.  
  2339.     -- This procedure is used by the Menu Handler to read a Menu Def Table
  2340.     -- file. The name of the file is passed to the procedure. The file must
  2341.     -- have been written using the WRITE_MENU_CONTROL_FILE procedure above.
  2342.     -- This procedure will attempt to load the Menu Control List kept in this
  2343.     -- package, and, using the procedures suplied in the instantiation, it will
  2344.     -- attempt to load the Menu Display Layout kept in another Ada package.
  2345.     -- The procedure will return the Bad Selection Message, and an Error Code
  2346.     -- specifying ant problems with reading the file.
  2347.    procedure READ_MENU_CONTROL_FILE (FILE_NAME_OF_MENU_DEF_TABLE: in TEXT;
  2348.                                      BAD_SELECTION_MESSAGE: out TEXT;
  2349.                                      ERROR_CODE: out INTEGER) is
  2350.  
  2351.        -- This exception will be raised if the config information in the file
  2352.        -- read does not match the cofiguration currently running.
  2353.       WRONG_DATA_STRUCTURE: exception;
  2354.  
  2355.        -- Internal file name for Menu Def Table being read. This name is used
  2356.        -- in the I/O operations.
  2357.       TABLE_FILE: MENU_CONTROL_ITEM_IO.FILE_TYPE;
  2358.  
  2359.    begin
  2360.        -- Assume no errors to start with and try to open the file of the name
  2361.        -- passed to this procedure. The name is passed in TEXT format so 
  2362.        -- covert this to a character string.
  2363.       ERROR_CODE := 0;
  2364.       MENU_CONTROL_ITEM_IO.OPEN( TABLE_FILE,MENU_CONTROL_ITEM_IO.IN_FILE,
  2365.                      TEXT_HANDLER_SUBSET.VALUE(FILE_NAME_OF_MENU_DEF_TABLE ));
  2366.  
  2367.  
  2368.        -- Read the config information from the first two records of the file.
  2369.        -- If either the screen width or the file name size are not the same
  2370.        -- as the values used in this instantiation of the package, then the
  2371.        -- records will not be read successfully, therefore raise an exception.
  2372.       MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,CONFIG_INFO_ITEM);
  2373.       if CONFIG_INFO_ITEM.NUMBER /= FILE_STRING_SIZE then
  2374.          raise WRONG_DATA_STRUCTURE;
  2375.       end if;
  2376.  
  2377.       MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,CONFIG_INFO_ITEM);
  2378.       if CONFIG_INFO_ITEM.NUMBER /= SCREEN_STRING_SIZE then
  2379.          raise WRONG_DATA_STRUCTURE;
  2380.       end if;
  2381.  
  2382.  
  2383.        -- Read the record containing the Bad Selection Message next. Extract
  2384.        -- the message from the MISC_INFO field, and convert it to TEXT format
  2385.        -- so it can be passed as a retured argument.
  2386.       MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,BAD_SELECTION_MESSAGE_ITEM);
  2387.       BAD_SELECTION_MESSAGE := TEXT_HANDLER_SUBSET.TO_TEXT
  2388.                 (BAD_SELECTION_MESSAGE_ITEM.MISC_INFO);
  2389.  
  2390.        -- Read the number of Menu Control Items that will be found in this
  2391.        -- file. This value is in the NUMBER field of the next record.
  2392.       MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,NUMBER_OF_CONTROL_ITEMS);
  2393.       CONTROL_LIST_COUNT := NUMBER_OF_CONTROL_ITEMS.NUMBER;
  2394.  
  2395.        -- Initialize the Menu Control List to point to no array of items. Build
  2396.        -- the Menu Control List by reading each Menu Control Item from the file
  2397.        -- and adding each to the Menu Control List (the number of reads/adds
  2398.        -- done is the number of Menu Control Items read above).
  2399.       MENU_CONTROL_LIST := null;
  2400.       for I in 1..CONTROL_LIST_COUNT loop
  2401.          MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,MENU_CONTROL_ITEM);
  2402.          ADD_ITEM_TO_LIST;
  2403.       end loop;
  2404.  
  2405.  
  2406.        -- Next build the Menu Display Layout by reading each record up to the
  2407.        -- end of the file, and sequentially putting the display line (found in
  2408.        -- the MISC_INFO field of each record) to the Menu Display Layout using
  2409.        -- the procedure provided.
  2410.       CLEAR_SCREEN_LAYOUT;
  2411.       while (not MENU_CONTROL_ITEM_IO.END_OF_FILE(TABLE_FILE)) loop
  2412.          MENU_CONTROL_ITEM_IO.READ(TABLE_FILE,SCREEN_LAYOUT_ITEM);
  2413.          PUT_NEXT_SCREEN_LINE(SCREEN_LAYOUT_ITEM.MISC_INFO);
  2414.       end loop;
  2415.  
  2416.  
  2417.        -- The full Menu Def Table file has been read, close the file.
  2418.       MENU_CONTROL_ITEM_IO.CLOSE(TABLE_FILE);
  2419.  
  2420.    exception
  2421.       when MENU_CONTROL_ITEM_IO.NAME_ERROR =>
  2422.            -- Exception occurs when the file named cannot be opened. It could
  2423.            -- be an invalid file name for this operating system, or the file
  2424.            -- may not exist.
  2425.           ERROR_CODE := 1;
  2426.       when WRONG_DATA_STRUCTURE =>
  2427.            -- Exception will occur when the file read was written with another
  2428.            -- configuraion.
  2429.           MENU_CONTROL_ITEM_IO.CLOSE(TABLE_FILE);
  2430.           ERROR_CODE := 2;
  2431.  
  2432.    end READ_MENU_CONTROL_FILE;
  2433.  
  2434.  
  2435.  
  2436.  
  2437. end PROCESS_MENU_CONTROL_TABLE;
  2438. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2439. --procingd.ada
  2440. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2441.  
  2442. -- PROCESS_MENU_DEF_STRING;PROCINGD.ADA;KJL;04/17/85
  2443.  
  2444. -- This package is used by the Menu Compiler, and contains the subprograms
  2445. -- needed to do some basic processing on the Menu Definition File. The Menu
  2446. -- Def File is written in the Menu Def Language, and is a description of the
  2447. -- Menu display and menu action. The file cna be thought of as a series of
  2448. -- Lexical Units, that are characters of set of characters, that are arranged
  2449. -- in the file and can be sequentially extracted. This package contains sub-
  2450. -- programs to extract and handle these Lexical Units. Analyzing the Lexical
  2451. -- Units for correctness in their content and their order is left to another
  2452. -- Ada package, so no compiler errors regarding the lexical units appear in
  2453. -- this package.
  2454.  
  2455. -- The Menu Definition File is an external file that is edited using some
  2456. -- editor and the operations of the particular operating system. One of the
  2457. -- operations performed in this package is to transfer the external file to
  2458. -- a Menu Definition String. This string is a dynamic character string that
  2459. -- will contain all the characters of the file. This string will be kept in
  2460. -- this package, and the string will be processed when lexical units are
  2461. -- extracted. This keeps the external Menu Definition File open for a minimum
  2462. -- amount of time.
  2463.  
  2464. package body PROCESS_MENU_DEF_STRING is
  2465.  
  2466.     -- The dynamic string that is the currently available Lexical Unit.
  2467.    LEXICAL_STRING: TEXT;
  2468.  
  2469.     -- The dynamic string that is the Menu Definition String. The Menu
  2470.     -- Definition File will be written to this string.
  2471.    MENU_DEF_STRING: TEXT;
  2472.  
  2473.     -- The character index of the Menu Def String character that will be
  2474.     -- analyzed. The parser will get each character in the Menu Def String, and
  2475.     -- process it to form the lexical units.
  2476.    STRING_POSITION: NATURAL := 1;
  2477.  
  2478.     -- The current line of the Menu Def File where the character analyzing is
  2479.     -- happening.
  2480.    LINE_NUMBER: NATURAL := 1;
  2481.  
  2482.     -- This will contain the STRING_POSITION value at the beginning of each
  2483.     -- line in the Menu Def String. This will be used to determine the current
  2484.     -- character of the current line where the character is being analyzed.
  2485.    LINE_POSITION: NATURAL := 1;
  2486.  
  2487.     -- The line number where the current lexical unit starts.
  2488.    LEX_UNIT_LINE_NUMBER: NATURAL := 0;
  2489.     -- The character of the line where the current lexical unit starts.
  2490.    LEX_UNIT_POSITION: NATURAL := 0;
  2491.  
  2492.     -- Will hold the Type of the currently available lexical unit.
  2493.    LEXICAL_TYPE: LEXICAL_UNIT_TYPES := LEXICAL_UNIT_TYPES'LAST;
  2494.  
  2495.     -- If TRUE, this will signal that a new lexical unit should not be
  2496.     -- extracted from the Menu Def String on the next request for a new lexical
  2497.     -- unit. Instead, the currently available lexical unit should remain
  2498.     -- the currently available lexical unit, and no parsing is done on the Menu
  2499.     -- Def String.
  2500.    LEXICAL_UNIT_ALREADY_RECEIVED: BOOLEAN := FALSE;
  2501.  
  2502.     -- Constants used to identify the types of lexical units:
  2503.    IDENTIFIER: constant := 0;
  2504.    USER_LITERAL: constant := 1;
  2505.    NO_MORE: constant := 2;
  2506.  
  2507.  
  2508.  
  2509.     -- This procedure extracts a Lexical Unit from the Menu Definition String.
  2510.     -- The text of the lexical unit is TEXT type and always put into the
  2511.     -- LEXICAL_STRING object. The type of the lexical unit is always put into
  2512.     -- the LEXICAL_TYPE object. When called this procedure uses and updates the
  2513.     -- Menu Def String character index as it analyzes characters within the 
  2514.     -- Menu Def String to extract the next lexical unit.
  2515.    procedure GENERATE_NEW_LEXICAL_UNIT is
  2516.  
  2517.        -- As the Menu Def String is parsed, different modes are used to giving
  2518.        -- characters different significance. For example, in Comment Mode,
  2519.        -- only the CR character has significance as the end of the comment.
  2520.       type MODE_TYPE is (INITIAL_MODE, WORD_SEP_MODE,
  2521.                          COMMENT_MODE, USER_LITERAL_MODE);
  2522.  
  2523.        -- Holds the current mode of the parser.
  2524.       MODE: MODE_TYPE := INITIAL_MODE;
  2525.  
  2526.        -- The current character being analyzed.
  2527.       PARSED_CHARACTER: CHARACTER;
  2528.  
  2529.  
  2530.        -- Function will return a substring of string argument given. The new
  2531.        -- string will be characters from the INDEX position to the end.
  2532.       function CHOP_STRING(STR: STRING;  INDEX: POSITIVE) return STRING is
  2533.       begin
  2534.          return STR(INDEX..STR'LAST);
  2535.       end CHOP_STRING;
  2536.  
  2537.  
  2538.        -- This procedure is used to shrink the Menu Def String, so that all
  2539.        -- characters of previously extracted lexical units are eliminated. In
  2540.        -- this way, as a lexical unit is extracted, the Menu Def String is
  2541.        -- stripped of already extracted characters.
  2542.       procedure GARBAGE_COLLECTION is
  2543.  
  2544.           -- A temporary TEXT object to hold the new shortened Menu Def String.
  2545.          TEMP_MENU_DEF_STRING: TEXT;
  2546.  
  2547.       begin
  2548.           -- Make a new TEXT type string that is the Menu Def String with the
  2549.           -- characters that have already been extracted stripped off.
  2550.          TEMP_MENU_DEF_STRING := TEXT_HANDLER_SUBSET.TO_TEXT
  2551.        (CHOP_STRING(TEXT_HANDLER_SUBSET.VALUE(MENU_DEF_STRING), STRING_POSITION) );
  2552.           -- Free up the space allocated for the Menu Def String.
  2553.          TEXT_HANDLER_SUBSET.CLEAR_TEXT(MENU_DEF_STRING);
  2554.           -- Set the Menu Def String equal the characters of the shorter string.
  2555.          MENU_DEF_STRING := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  2556.            (TEXT_HANDLER_SUBSET.VALUE(TEMP_MENU_DEF_STRING) );
  2557.           -- Free up the space allocated for the temp TEXT string.
  2558.          TEXT_HANDLER_SUBSET.CLEAR_TEXT(TEMP_MENU_DEF_STRING);
  2559.           -- The string index for the ne Menu Def String now starts at 1.
  2560.          STRING_POSITION := 1;
  2561.  
  2562.       end GARBAGE_COLLECTION;
  2563.  
  2564.  
  2565.        -- Function returns the character in the Menu Def String at the string
  2566.        -- index. The Text Handler Subset operation is used.
  2567.       function RETURN_NEXT_CHAR return CHARACTER is
  2568.       begin
  2569.      return TEXT_HANDLER_SUBSET.GIVE_POS(MENU_DEF_STRING,STRING_POSITION);
  2570.       end RETURN_NEXT_CHAR;
  2571.  
  2572.  
  2573.        -- Function returns TRUE if the character argument is found in the
  2574.        -- string argument.
  2575.       function MATCH(CHAR: CHARACTER; STR: STRING) return BOOLEAN is
  2576.          FOUND: BOOLEAN := FALSE;
  2577.       begin
  2578.           -- Check each character in the string until CHAR is found. If CHAR is
  2579.           -- not found, the initial FALSE value is returned.
  2580.          for I in STR'FIRST..STR'LAST loop
  2581.             FOUND := (STR(I) = CHAR);
  2582.             exit when FOUND;
  2583.          end loop;
  2584.          return FOUND;
  2585.       end MATCH;
  2586.  
  2587.  
  2588.        -- Procedure sets the line number where a Lexical Unit starts.
  2589.       procedure MARK_START_OF_LEX_UNIT is
  2590.       begin
  2591.          LEX_UNIT_LINE_NUMBER := LINE_NUMBER;
  2592.       end MARK_START_OF_LEX_UNIT;
  2593.  
  2594.  
  2595.        -- Using the Text Handler Subset operation, this procedure adds the
  2596.        -- character argument to the LEXICAL_STRING object.
  2597.       procedure ADD_CHARACTER_TO_LEXICAL_STRING
  2598.                               (PARSED_CHARACTER: in CHARACTER) is
  2599.       begin
  2600.          TEXT_HANDLER_SUBSET.APPEND (PARSED_CHARACTER,LEXICAL_STRING);
  2601.       end ADD_CHARACTER_TO_LEXICAL_STRING;
  2602.  
  2603.  
  2604.     -- Begin the GENERATE_NEW_LEXICAL_UNIT procedure.
  2605.    begin
  2606.        -- Start by clearing and deallocating the old Lexical Unit, and clean
  2607.        -- the Menu Def String so it contains no characters from previously
  2608.        -- extracted lexical units.
  2609.       TEXT_HANDLER_SUBSET.CLEAR_TEXT(LEXICAL_STRING);
  2610.       GARBAGE_COLLECTION;
  2611.  
  2612.        -- The loop will go character by character through the Menu Def String
  2613.        -- analyzing the characters. The procedure is exited when a lexical
  2614.        -- unit is found. The loop is exited if no more characters exist in the
  2615.        -- Menu Def String (in which case there are no more lexical units).
  2616.       loop
  2617.          exit when (STRING_POSITION > TEXT_HANDLER_SUBSET.LENGTH(MENU_DEF_STRING));
  2618.  
  2619.           -- Get the next character in the Menu Def String. If CR, then update
  2620.           -- the line number, and save the string position line break.
  2621.          PARSED_CHARACTER := RETURN_NEXT_CHAR;
  2622.      if PARSED_CHARACTER = ASCII.CR then
  2623.         LINE_NUMBER := LINE_NUMBER + 1;
  2624.      end if;
  2625.  
  2626.           -- The different modes of the parser cause the characters to have
  2627.           -- different significances:
  2628.          case MODE is
  2629.  
  2630.              when INITIAL_MODE =>
  2631.                  -- In the Initial Mode, the parser is looking for characters
  2632.                  -- other than Word Separators. A left delimiter signals the 
  2633.                  -- beginning of a User Literal type lexical unit, the mode
  2634.                  -- is switched. A Comment indicator signals the beginning of
  2635.                  -- a comment, the mode is switched. On other characters, the
  2636.                  -- beginning of an Identifier type lex unit is signaled, the
  2637.                  -- character is added to the new lex unit, and nmode switched.
  2638.                 if MATCH(PARSED_CHARACTER, WORD_SEPARATORS) then
  2639.                   null;
  2640.                 elsif PARSED_CHARACTER = LEFT_DELIMITER then
  2641.                   MODE := USER_LITERAL_MODE;
  2642.                   MARK_START_OF_LEX_UNIT;
  2643.                 elsif PARSED_CHARACTER = COMMENT_INDICATOR then
  2644.                   MODE := COMMENT_MODE;
  2645.                 else
  2646.                   ADD_CHARACTER_TO_LEXICAL_STRING(PARSED_CHARACTER);
  2647.                   MODE := WORD_SEP_MODE;
  2648.                   MARK_START_OF_LEX_UNIT;
  2649.                 end if;
  2650.  
  2651.              when WORD_SEP_MODE =>
  2652.                  -- In Word Sep mode, the parser continues to put characters
  2653.                  -- into the lex unit until a Word Separator, Comment indicator
  2654.                  -- or left delimiter is found. At that the lex unit is a
  2655.                  -- complete Identifier type, and the procedure is exited.
  2656.                 if ((MATCH(PARSED_CHARACTER, WORD_SEPARATORS)) or
  2657.                     (PARSED_CHARACTER = LEFT_DELIMITER) or
  2658.                     (PARSED_CHARACTER = COMMENT_INDICATOR)) then
  2659.                   LEXICAL_TYPE := LEXICAL_UNIT_TYPES'VAL(IDENTIFIER);
  2660.                   return;
  2661.                 else
  2662.                   ADD_CHARACTER_TO_LEXICAL_STRING(PARSED_CHARACTER);
  2663.                 end if;
  2664.  
  2665.              when COMMENT_MODE =>
  2666.                  -- In Comment mode, the parser is looking for a CR character.
  2667.                  -- When found, the comment is over, but this is like nothing
  2668.                  -- was found so which the mode back to the Initial Mode.
  2669.                 if PARSED_CHARACTER = ASCII.CR then
  2670.                   MODE := INITIAL_MODE;
  2671.                 end if;
  2672.  
  2673.              when USER_LITERAL_MODE =>
  2674.                  -- In User Literal mode the parser is adding every character
  2675.                  -- analyzed from the Menu Def String until a right delimiter
  2676.                  -- is found. At that, the User Literal type lex unit is
  2677.                  -- complete, Lex Type is set to USER_LITERAL, and the
  2678.                  -- procedure exited.
  2679.                 if PARSED_CHARACTER = RIGHT_DELIMITER then
  2680.                    -- Now, two consecutive right delimiters are interpreted as
  2681.                    -- one right delimiter character still within the User
  2682.                    -- Literal. Therefore when a right delimiter is found, make
  2683.                    -- sure the next character is not a right delimiter before
  2684.                    -- completing the lexical unit.
  2685.                   STRING_POSITION := STRING_POSITION + 1;
  2686.                   PARSED_CHARACTER := RETURN_NEXT_CHAR;
  2687.                   if PARSED_CHARACTER /= RIGHT_DELIMITER then
  2688.                      LEXICAL_TYPE := LEXICAL_UNIT_TYPES'VAL(USER_LITERAL);
  2689.                      return;
  2690.                   end if;
  2691.                 end if;
  2692.                 ADD_CHARACTER_TO_LEXICAL_STRING(PARSED_CHARACTER);
  2693.  
  2694.         end case;
  2695.          -- Set the string index to analyze the next character in the Menu Def
  2696.          -- String.
  2697.         STRING_POSITION := STRING_POSITION + 1;
  2698.       end loop;
  2699.  
  2700.        -- If the loop has exited w/o the procedure exiting, then the end of the
  2701.        -- Menu Def String has been reached. Set the current lex type to NO_MORE
  2702.       LEXICAL_TYPE := LEXICAL_UNIT_TYPES'VAL(NO_MORE);
  2703.  
  2704.    end GENERATE_NEW_LEXICAL_UNIT;
  2705.  
  2706.  
  2707.  
  2708.  
  2709.     -- This procedure is given name of  file which is the Menu Definition File,
  2710.     -- and the file is written to a Menu Definition String. The string is kept
  2711.     -- in this package for future lexical unit extractions. An error code is
  2712.     -- given if there are problems reading the external file.
  2713.    procedure WRITE_MENU_DEF_STRING
  2714.                (FILE_NAME_OF_MENU_DEF_FILE: in TEXT;
  2715.                 ERROR_CODE: out INTEGER) is
  2716.  
  2717.        -- The type of character string line read from the Menu Def File.
  2718.       subtype MENU_DEF_LINE_TYPE is STRING(1..MENU_DEF_FILE_LINE_SIZE);
  2719.  
  2720.        -- The string read from the Menu Def File.
  2721.       INPUT_STRING: MENU_DEF_LINE_TYPE;
  2722.        -- The character index of the last character read in each line.
  2723.       LAST_INDEX: INTEGER;
  2724.        -- The internal file name given to the Menu Def File. This name will be
  2725.        -- used in the I/O operations.
  2726.       DEFINITION_FILE: TEXT_IO.FILE_TYPE;
  2727.  
  2728.    begin
  2729.        -- Initially there are no errors in reading the file. Try to open the
  2730.        -- file whose file name was given as an argument (the argument is in
  2731.        -- the TEXT form so the file name must be converted to a character
  2732.        -- string, also the TEXT file name is assumed to have no leading and
  2733.        -- trailing blanks).
  2734.       ERROR_CODE := 0;
  2735.       TEXT_IO.OPEN(DEFINITION_FILE, TEXT_IO.IN_FILE,
  2736.                 TEXT_HANDLER_SUBSET.VALUE(FILE_NAME_OF_MENU_DEF_FILE));
  2737.  
  2738.        -- For each line in the Menu Def File, read the line into a character
  2739.        -- string and append the string to the dynamic Menu Def String using
  2740.        -- the Text Handler Subset operation. At each line put a CR character
  2741.        -- in the Menu Def String.
  2742.       loop
  2743.          TEXT_IO.GET_LINE(DEFINITION_FILE,INPUT_STRING,LAST_INDEX);
  2744.      TEXT_HANDLER_SUBSET.APPEND((INPUT_STRING(1..LAST_INDEX) & ASCII.CR),MENU_DEF_STRING);
  2745.       end loop;
  2746.  
  2747.    exception
  2748.       when TEXT_IO.NAME_ERROR =>
  2749.          -- This exception occurs when the file name passed to the procedure
  2750.          -- is invalid for this operating system, of the file doesn't exist.
  2751.         ERROR_CODE := 1;
  2752.       when TEXT_IO.END_ERROR =>
  2753.          -- This exception occurs when the end of the file is reached.
  2754.         TEXT_IO.CLOSE(DEFINITION_FILE);
  2755.  
  2756.    end WRITE_MENU_DEF_STRING;
  2757.  
  2758.  
  2759.  
  2760.  
  2761.     -- This procedure makes the next lexical unit in the Menu Def String
  2762.     -- available. It extract the text for the next lexical unit from the Menu
  2763.     -- Def String, and keeps it available in this package. It also compacts the
  2764.     -- Menu Def String, eliminating the text of all previous lexical elements
  2765.     -- in the Menu Def String. In this way the Menu Def String is always
  2766.     -- shrinking as lexical elements are extracted.
  2767.    procedure GET_LEXICAL_UNIT_IF_NEEDED is
  2768.    begin
  2769.       -- Check if it is necessary to extract another lex unit from the Menu
  2770.       -- Def String. If not keep the current lex unit, and reset the Already
  2771.       -- Received flag.
  2772.      if (LEXICAL_UNIT_ALREADY_RECEIVED) then
  2773.         LEXICAL_UNIT_ALREADY_RECEIVED := FALSE;
  2774.      else
  2775.         GENERATE_NEW_LEXICAL_UNIT;
  2776.      end if;
  2777.    end GET_LEXICAL_UNIT_IF_NEEDED;
  2778.  
  2779.  
  2780.  
  2781.  
  2782.     -- This procedure signals this package that the last lexical unit extracted
  2783.     -- has not been used yet. Therefore when a request is made for a new
  2784.     -- lexical unit, no new lexical unit will be extracted from the Menu Def
  2785.     -- String, instead the current lexical unit available will remain the
  2786.     -- current lexical unit available.
  2787.    procedure UNIT_RECEIVED is
  2788.    begin
  2789.       LEXICAL_UNIT_ALREADY_RECEIVED := TRUE;
  2790.    end UNIT_RECEIVED;
  2791.  
  2792.  
  2793.  
  2794.  
  2795.     -- Returns the lexical unit type of the current lexical unit available.
  2796.    function CURRENT_LEX_TYPE return LEXICAL_UNIT_TYPES is
  2797.    begin
  2798.       return LEXICAL_TYPE;
  2799.    end CURRENT_LEX_TYPE;
  2800.  
  2801.  
  2802.     -- Returns the character position of the current Menu Definition File line,
  2803.     -- where the next lexical unit will be extracted.
  2804.    function CURRENT_POSITION return INTEGER is
  2805.    begin
  2806.        -- Currently this procedure is not used, and will always return 0.
  2807.       return LEX_UNIT_POSITION;
  2808.    end CURRENT_POSITION;
  2809.  
  2810.  
  2811.  
  2812.  
  2813.     -- Returns the current Menu Definition File Line where the next lexical
  2814.     -- unit will be extracted.
  2815.    function CURRENT_LINE_NUMBER return INTEGER is
  2816.    begin
  2817.       return LEX_UNIT_LINE_NUMBER;
  2818.    end;
  2819.  
  2820.  
  2821.  
  2822.  
  2823.     -- Returns the text of the current lexical unit available, returned in 
  2824.     -- TEXT type form.
  2825.    function CURRENT_LEX_STRING return TEXT is
  2826.    begin
  2827.       return LEXICAL_STRING;
  2828.    end CURRENT_LEX_STRING;
  2829.  
  2830.  
  2831.  
  2832.  
  2833.     -- Returns the number of characters in the lexical unit that is currently
  2834.     -- available.
  2835.    function LEXICAL_STRING_LENGTH return INTEGER is
  2836.    begin
  2837.       return TEXT_HANDLER_SUBSET.LENGTH(LEXICAL_STRING);
  2838.    end LEXICAL_STRING_LENGTH;
  2839.  
  2840.  
  2841.  
  2842.  
  2843. end PROCESS_MENU_DEF_STRING;
  2844. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2845. --prociond.ada
  2846. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2847.  
  2848.  
  2849. -- PROCESS_CONFIGURATION;PROCIOND.ADA;KJL;04/18/85
  2850.  
  2851. -- This package contains the user defined items as read from the
  2852. -- configuration file. The objects are kept in the package Spec. so that they 
  2853. -- are accessable to the main procedure of the Menu Compiler, and Menu Handler.
  2854. -- The objects are also given default values, so that if errors occur while
  2855. -- reading the file, all objects will still have legal values.
  2856. -- If problems occur when the Configuration file is being read, this is
  2857. -- signaled by displaying "!!" on the screen (this is done because before
  2858. -- reading the config file, the Menu Manager programs do not know how big the
  2859. -- the screen width is, and full text lines may not be displayed correctly). In
  2860. -- any case, the config objects will at least have the legal default values so
  2861. -- the Menu Manager procedures can perform.
  2862.  
  2863. package body PROCESS_CONFIGURATION is
  2864.  
  2865.     -- Constants containing the configuration value defaults. When the value
  2866.     -- for each object is read, the default is assigned if there is any
  2867.     -- trouble. The TEXT objects use string constants as defaults.
  2868.    MAX_FILE_NAME_LENGTH_DEFAULT  : constant := 15;
  2869.    MENU_FILE_DEFAULT             : constant STRING := "MENUFILE       ";
  2870.    LENGTH_OF_FILE_LINES_DEFAULT  : constant := 100;
  2871.    MENU_TABLE_DEFAULT            : constant STRING := "MENUTABL       ";
  2872.    SCREEN_WIDTH_DEFAULT          : constant := 80;
  2873.    SCREEN_LENGTH_DEFAULT         : constant := 22;
  2874.    QUIT_CHARACTER_DEFAULT     : constant CHARACTER := '@';
  2875.  
  2876.    CONFIG_FILE: TEXT_IO.FILE_TYPE; -- Internal file name for MENCON file.
  2877.  
  2878.     -- Used to read positive numeric values from the file.
  2879.    package INTEGER_IO is new TEXT_IO.INTEGER_IO(POSITIVE);
  2880.  
  2881.  
  2882.    procedure GET_NUMBER (NUMBER_DEFAULT: in POSITIVE; NUMBER: out POSITIVE) is
  2883.     -- Procedure reads a numeric value fron the MENCON file.
  2884.    begin
  2885.       INTEGER_IO.GET(CONFIG_FILE,NUMBER);
  2886.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2887.       return;
  2888.    exception
  2889.       when TEXT_IO.DATA_ERROR =>
  2890.        -- Bad type of value found where a number is expected, display the error
  2891.        -- signal, and assign the default.
  2892.          TEXT_IO.PUT_LINE("!!");
  2893.          NUMBER := NUMBER_DEFAULT;
  2894.       when TEXT_IO.END_ERROR =>
  2895.        -- End of file reached, close file, all subsequent configuration objects
  2896.        -- will contain the default values, or whatever value they had previously.
  2897.          TEXT_IO.CLOSE(CONFIG_FILE);
  2898.       when others =>
  2899.        -- Other exceptions could occur if the file is already closed.
  2900.          null;
  2901.    end GET_NUMBER;
  2902.  
  2903.  
  2904.    procedure GET_FILE_NAME (NAME_DEFAULT: in STRING; NAME: out TEXT) is
  2905.     -- This procedure is used to read a string file name from the MENCON file.
  2906.     -- The resulting string read is put in an object type TEXT.
  2907.       INPUT_STRING: STRING(1..INPUT_LINE_LENGTH); -- Line read from file.
  2908.       LAST_INDEX: POSITIVE;   -- Last string index in INPUT_STRING that
  2909.                               -- contains a character.
  2910.       TX: TEXT;     -- Temp TEXT used as (in out) arguement for PACK_TO_TEXT
  2911.  
  2912.    begin
  2913.        -- Read line from file, and convert to TEXT with no trailing or leading
  2914.        -- blanks.
  2915.       TEXT_IO.GET_LINE(CONFIG_FILE,INPUT_STRING,LAST_INDEX);
  2916.       TX := TEXT_HANDLER_SUBSET.PACK_TO_TEXT(INPUT_STRING(1..LAST_INDEX));
  2917.        -- Make sure file name read from file is not to many characters.
  2918.       if TEXT_HANDLER_SUBSET.LENGTH(TX) > MAX_FILE_NAME_LENGTH then
  2919.          TEXT_IO.PUT_LINE("!!");
  2920.          NAME := TEXT_HANDLER_SUBSET.PACK_TO_TEXT(NAME_DEFAULT);
  2921.       else
  2922.          NAME := TX;
  2923.       end if;
  2924.       return;
  2925.  
  2926.    exception
  2927.       when TEXT_IO.END_ERROR =>
  2928.        -- End of File reached. Close file, subsequent objects will contain
  2929.        -- default values or previously assigned value.
  2930.          TEXT_IO.CLOSE(CONFIG_FILE);
  2931.       when TEXT_IO.DATA_ERROR =>
  2932.        -- Value read from file was not string. Signal error, and assign default
  2933.          TEXT_IO.PUT_LINE("!!");
  2934.          NAME := TEXT_HANDLER_SUBSET.PACK_TO_TEXT(NAME_DEFAULT);
  2935.       when others =>
  2936.        -- Other exception could occur if the file is already closed.
  2937.          null;
  2938.  
  2939.    end GET_FILE_NAME;
  2940.  
  2941.  
  2942.    procedure GET_CHAR_ELEM (CHAR_DEFAULT: in CHARACTER; 
  2943.                 CHAR_ELEM: out CHARACTER) is
  2944.     -- Procedure reads a character from the MENCON file.
  2945.    begin
  2946.       TEXT_IO.GET(CONFIG_FILE,CHAR_ELEM);
  2947.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2948.       return;
  2949.    exception
  2950.       when TEXT_IO.DATA_ERROR =>
  2951.        -- Some other type input was found instead of a character. Signal error
  2952.        -- and use default value.
  2953.          TEXT_IO.PUT_LINE("!!");
  2954.          CHAR_ELEM := CHAR_DEFAULT;
  2955.       when TEXT_IO.END_ERROR =>
  2956.        -- End of file reached, close file, all subsequent config object will
  2957.        -- contain default of proviously assigned value.
  2958.          TEXT_IO.CLOSE(CONFIG_FILE);
  2959.       when others =>
  2960.        -- Other exceptions could occur if the file is already closed.
  2961.          null;
  2962.    end GET_CHAR_ELEM;
  2963.  
  2964.  
  2965.  
  2966.    procedure READ_CONFIGURATION_FILE is
  2967.     -- Procedure opens MENCON configuration file, and reads the configuration
  2968.     -- values. Lines are skipped where neccessary to skip the instruction lines
  2969.     -- of the file.
  2970.    begin
  2971.       TEXT_IO.OPEN(CONFIG_FILE,TEXT_IO.IN_FILE,CONFIG_FILE_NAME);
  2972.       TEXT_IO.SKIP_LINE(CONFIG_FILE,2);
  2973.       GET_NUMBER(MAX_FILE_NAME_LENGTH_DEFAULT,MAX_FILE_NAME_LENGTH);
  2974.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2975.       GET_FILE_NAME(MENU_FILE_DEFAULT,MENU_FILE);
  2976.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2977.       GET_NUMBER(LENGTH_OF_FILE_LINES_DEFAULT,LENGTH_OF_LINES_IN_MENU_FILE);
  2978.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2979.       GET_FILE_NAME(MENU_TABLE_DEFAULT, MENU_TABLE);
  2980.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2981.       GET_NUMBER(SCREEN_WIDTH_DEFAULT, SCREEN_WIDTH);
  2982.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2983.       GET_NUMBER(SCREEN_LENGTH_DEFAULT, SCREEN_LENGTH);
  2984.       TEXT_IO.SKIP_LINE(CONFIG_FILE);
  2985.       GET_CHAR_ELEM(QUIT_CHARACTER_DEFAULT ,QUIT_CHARACTER);
  2986.       TEXT_IO.CLOSE(CONFIG_FILE);
  2987.       return;
  2988.    exception
  2989.       when TEXT_IO.NAME_ERROR =>
  2990.        -- MENCON file is not found. Signal error and use defaults.
  2991.          TEXT_IO.PUT_LINE ("!!");
  2992.       when TEXT_IO.END_ERROR =>
  2993.        -- End of file reached. Close file, use defaults for remaining objects
  2994.          TEXT_IO.CLOSE(CONFIG_FILE);
  2995.       when others =>
  2996.        -- Other exception could occur if file is already closed.
  2997.          null;
  2998.    end READ_CONFIGURATION_FILE;
  2999.  
  3000.  
  3001. end PROCESS_CONFIGURATION;
  3002. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3003. --proctord.ada
  3004. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3005.  
  3006.  
  3007.  
  3008. -- PROCESS_INITIATOR;PROCTORD.ADA;KJL;04/17/85
  3009.  
  3010. -- This package contains two procedures, the bodies of which are completely user
  3011. -- supplied except for a few sample and skeletal statements. These procedures
  3012. -- provide the interface of the Menu Handler with the CLI, and the interface
  3013. -- of the Menu Handler with any Ada procedures that are desired to be linked
  3014. -- to this Menu Handler program. The package spec for this package contains
  3015. -- the procedure specs for the two interface procedures. The procedure specs
  3016. -- should not be changed since this is the linkage between the interface
  3017. -- procedures and the rest of the Menu Handler software. Therefore the user
  3018. -- should supply the statements in the procedure bodies, so that the arguments
  3019. -- of the procedures input and return the desired values.
  3020.  
  3021. with TEXT_IO; -- And any packages needed for procedures run...
  3022. package body PROCESS_INITIATOR is
  3023.  
  3024.     -- The installer of the Menu Manager software can make the Menu Handler
  3025.     -- call other Ada procedures in three ways:
  3026.     --  1) Include the code for the procedure is another package, and put that
  3027.     --     package unit name in the "with" clause above this package body. If
  3028.     --     this is done, the other package must be compiled, then this package
  3029.     --     body must be compiled, then the main procedure MENUSHOW must be
  3030.     --     re-compiled and re-linked.
  3031.     --  2) An external procedure can be written using the "separate" clause
  3032.     --     before its "procedure" statement. The unit name given in that
  3033.     --     procedures "separate" clause will be this unit, "PROCESS_INITIATOR".
  3034.     --     Then in this procedure, a procedure statement is put into the code
  3035.     --     declaring the procedure as separate, ie:
  3036.     --             procedure XYZ is separate;
  3037.     --     If this is done, the other procedure must be compiled, then this 
  3038.     --     package body must be compiled, then the main procedure MENUSHOW must
  3039.     --     be re-compiled and re-linked.
  3040.     --  3) The code for the procedure can be put directly within this package.
  3041.     --     This is what is done for the sample procedure, since no other files
  3042.     --     are involved in this method. In this case, this package body will
  3043.     --     have to be compiled, and the main procedure MENUSHOW must be re-
  3044.     --     compiled and re-linked.
  3045.  
  3046.     -- This SAMPLE_1 procedure shows the third method of including Ada
  3047.     -- procedures to be run by the Menu Handler. The procedure outputs a line
  3048.     -- and waits for user to input a character.
  3049.    procedure SAMPLE_1 is
  3050.       INPUT_CHAR: CHARACTER;
  3051.    begin
  3052.       TEXT_IO.PUT_LINE(" SAMPLE_1 procedure has started... ");
  3053.       TEXT_IO.GET (INPUT_CHAR);
  3054.    end SAMPLE_1;
  3055.  
  3056.  
  3057.  
  3058.  
  3059.     -- This interface procedure is used to provide a method for starting other
  3060.     -- Ada procedures. The procedures will in some way have to be linked to
  3061.     -- the Menu Handle procedure for them to be called. This can be done in a
  3062.     -- number of ways. There is one argument passed to this procedure, to
  3063.     -- be used by the user supplyed statements in the procedure body, and one
  3064.     -- argument passed back to the calling program, the statements of the 
  3065.     -- procedure body must supply a value for this argument.
  3066.     -- The ADA_PROCEDURE_NAME argument is a string argument given to the
  3067.     -- procedure. This string is ment to be used in a multi-conditional
  3068.     -- statement, that will call an Ada procedure by the name corresponding to
  3069.     -- the string given. The string passed here will always have no leading or
  3070.     -- trailing blanks, other than that, they will be the exact string
  3071.     -- specified in the Menu Definition File on a Select ... A [string] in-
  3072.     -- struction (see the syntax guide).
  3073.     -- The ERROR argument passed back to the calling program is ment to be
  3074.     -- set TRUE if the string is not found in the multi-conditional statement,
  3075.     -- and therefore no corresponding Ada procedure was started.
  3076.    procedure ADA_PROCEDURE_CALL (ADA_PROCEDURE_NAME: in STRING;
  3077.                  ERROR: out BOOLEAN) is
  3078.    begin
  3079.        -- This interface procedure must be edited by the user to make Ada
  3080.        -- procedure calls possible. The procedure consists of a multi-
  3081.        -- conditional statement, that test for different character strings
  3082.        -- entering the procedure, and starts corresponding procedures.
  3083.       ERROR := FALSE;
  3084.       if ADA_PROCEDURE_NAME = "SAMPLE_1" then
  3085.          SAMPLE_1;
  3086.  
  3087.        -- Continue the condition for any procedure available to be called, for
  3088.        -- example the follow condition could added to call a procedure in the
  3089.        -- package "SAMPLE_PROCS". "SAMPLE_PROCS" would have been included in
  3090.        -- the "with" clause above this package body.
  3091. --    elsif ADA_PROCEDURE_NAME = "SAMPLE_2" then
  3092. --       SAMPLE_PROCS.SAMPLE_2;
  3093.  
  3094.       else
  3095.           -- Set error if string is not matched by a procedure call.
  3096.          ERROR := TRUE;
  3097.       end if;
  3098.  
  3099.        -- Note that the result of the above statement is a list the valid
  3100.        -- strings that can specified in the Select instruction of the Menu
  3101.        -- Definition File ie, from the above conditional statement, the Select
  3102.        -- instruction:
  3103.        --         Select [x]  Ada [SAMPLE_1]
  3104.        -- will result in a legal process when 'x' is typed at the menu.
  3105.  
  3106.    end ADA_PROCEDURE_CALL;
  3107.  
  3108.  
  3109.  
  3110.  
  3111.     -- This interface procedure is used to transfer a string passed it the CLI.
  3112.     -- The method of doing this is different for different Ada environments,
  3113.     -- and may not even exist in a particular environment. There are two
  3114.     -- arguments passed to this procedure to be used by the user provided
  3115.     -- statements, and one argument passed back to the calling procedure.
  3116.     -- The COMMAND_LINE is a string argument that contains a single word,
  3117.     -- like a command or an executable file of commands. This string have no
  3118.     -- leading of trailing blanks, and this string is to be passed directly to
  3119.     -- the Command Line Interpretor.
  3120.     -- The CONTINUE_WAIT_CODE is integer code that specifies  0 - to hold the
  3121.     -- Menu Handler program while the command is being processed by the CLI,
  3122.     -- or 1 - to make the Menu Handler continue immediately once the line or
  3123.     -- command has been passed to the CLI. The use of these codes input the
  3124.     -- this interface procedure will depend entirely on the capability 
  3125.     -- available to issue statements the CLI from this Ada program (ie, it
  3126.     -- may be possible to issue a command to the CLI from this Ada program,
  3127.     -- but it may not be possible to issue the command and have the Ada program
  3128.     -- wait for command completion).
  3129.     -- The ERROR argument is a boolean parameter returned to the calling
  3130.     -- procedure. It is ment to be used to return the status of the CLIs
  3131.     -- ability to interpret the line given to it. If the CLI could not read
  3132.     -- or understand the string passed to it, then the ERROR argument should
  3133.     -- return TRUE. The ERROR argument is not ment to return the status of
  3134.     -- the actual command of process started, only the CLIs ability to start it.
  3135.    procedure COMMAND_LINE_PROCESSOR (COMMAND_LINE: in STRING;
  3136.                      CONTINUE_WAIT_CODE: in INTEGER;
  3137.                      ERROR: out BOOLEAN)  is
  3138.  
  3139.        -- All of the code lines in this package should be replaced with user
  3140.        -- supplied code. The code existing here now is used only for test 
  3141.        -- purposes, and to give an example of how this procedure is called from
  3142.        -- another procedure outside the package. The code supplied by the
  3143.        -- user for this procedure should the necessary Ada procedure/package(s)
  3144.        -- that enable string to be passed to the Command Line Interpretor,
  3145.        -- in Wait, or Don't Wait mode. Refer to the Ada environment manual
  3146.        -- for the particular system running to see if such procedures exist,
  3147.        -- and how they are called in an Ada program.
  3148.  
  3149.    begin
  3150.  
  3151.       SHOW_PROCEDURE_CALL:
  3152.        -- This code will simply show that the procedure is called, and accepts
  3153.        -- the string passed it. The code should be replaced by the uses.
  3154.       declare
  3155.          INPUT_CHAR: CHARACTER;
  3156.          WAIT: constant := 0;
  3157.       begin
  3158.          TEXT_IO.PUT_LINE(" Issue command " & COMMAND_LINE & " to the CLI.");
  3159.          TEXT_IO.GET(INPUT_CHAR);
  3160.           -- The ERROR is set is the WAIT signal was given. This again is just
  3161.           -- test code to show how an ERROR would be processed.
  3162.          ERROR := (CONTINUE_WAIT_CODE = WAIT);
  3163.       end SHOW_PROCEDURE_CALL;
  3164.  
  3165.  
  3166.    end COMMAND_LINE_PROCESSOR;
  3167.  
  3168.  
  3169.  
  3170.  
  3171. end PROCESS_INITIATOR;
  3172. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3173. --textsetd.ada
  3174. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3175.  
  3176.  
  3177. -- TEXT_HANDLER_SUBSET;TEXTSETD.ADA;KJL;04/18/85
  3178.  
  3179. -- This package is a subset of the Text Handler package from the LRM. It
  3180. -- contains only the operations needed for the Menu Manager project. The
  3181. -- TEXT type is a dynamic character string type, that is implemented using
  3182. -- access types where the object is really a pointer to a string. The string
  3183. -- can expand dynamicly because the object points to a new string that 
  3184. -- includes the text of the previous one and more.
  3185.  
  3186. -- This is one of the few non generic library units in the Menu Manager set.
  3187. -- This package must be compiled before others are.
  3188.  
  3189. with UNCHECKED_DEALLOCATION;
  3190. package body TEXT_HANDLER_SUBSET is
  3191.  
  3192.    procedure FREE is new UNCHECKED_DEALLOCATION (STRING, TEXT);
  3193.     -- procedure to free addresses being pointed to by a TEXT object.
  3194.  
  3195.  
  3196.    function STRNG (C: CHARACTER) return STRING is
  3197.     -- Returns a string of one character that is the given C.
  3198.       TEMP: STRING(1..1) := (1 => C);
  3199.    begin
  3200.       return TEMP;
  3201.    end STRNG;
  3202.  
  3203.  
  3204.    procedure INITIALIZE_TEXT (T: in out TEXT) is
  3205.     -- This procedure is used to initialize a TEXT object to point to a null
  3206.     -- string. This avoids CONSTRAINT_ERRORS ocurring when the accessed string
  3207.     -- of a TEXT object is processed when the object in fact points to null.
  3208.    begin
  3209.       if T = null then
  3210.          FREE (T);
  3211.          T := new STRING'("");
  3212.       end if;
  3213.       return;
  3214.    end INITIALIZE_TEXT;
  3215.  
  3216.  
  3217.  
  3218.    function LENGTH (T: TEXT) return NATURAL is
  3219.     -- Returns the Length of the accessed string. 0 if access is null.
  3220.    begin
  3221.       return T.all'LENGTH;
  3222.    exception
  3223.       when CONSTRAINT_ERROR =>
  3224.          return 0;
  3225.    end LENGTH;
  3226.  
  3227.  
  3228.    function VALUE (T: TEXT) return STRING is
  3229.     -- Returns the string which the access type points to, or "" if the access
  3230.     -- type points to null.
  3231.    begin
  3232.       return T.all;
  3233.    exception
  3234.       when CONSTRAINT_ERROR =>
  3235.          return "";
  3236.    end VALUE;
  3237.  
  3238.  
  3239.    function EMPTY (T: TEXT) return BOOLEAN is
  3240.     -- Returns true if the accessed string is "", or access is null.
  3241.    begin
  3242.       return (T.all = "");
  3243.    exception
  3244.       when CONSTRAINT_ERROR =>
  3245.      return TRUE;
  3246.    end EMPTY;
  3247.  
  3248.  
  3249.    function TO_TEXT (STR: STRING) return TEXT is
  3250.     -- Creates an access type that points to a string of the value given.
  3251.    begin
  3252.       return new STRING'(STR);
  3253.    end TO_TEXT;
  3254.  
  3255.  
  3256.    function TO_TEXT (CHR: CHARACTER) return TEXT is
  3257.     -- Creates an access type pointing to a string that is the character given.
  3258.    begin
  3259.       return  new STRING'(STRNG(CHR));
  3260.    end TO_TEXT;
  3261.  
  3262.  
  3263.    procedure CLEAR_TEXT (T: in out TEXT) is
  3264.     -- Resets the given access object to point to a null string.
  3265.    begin
  3266.       FREE (T);
  3267.       T := new STRING'("");
  3268.    end CLEAR_TEXT;
  3269.  
  3270.  
  3271.    procedure PACK_TEXT (T: in out TEXT) is
  3272.     -- Takes the leading and trailing blanks off the given accessed string.
  3273.       TEMP: TEXT;             -- Used so old addresses can be freed.
  3274.       FRONT, BACK: POSITIVE;  -- 1st and last string idex of new string.
  3275.    begin
  3276.       INITIALIZE_TEXT (T);    -- if T is null, make it point to null string.
  3277.       if EMPTY(T) then
  3278.          return;
  3279.       else
  3280.           -- Start at begining of string and move to the right looking for a
  3281.           -- character other than blank.
  3282.          FRONT := T.all'FIRST;
  3283.          BACK  := T.all'LAST;
  3284.          while (T.all(FRONT) = ' ') loop
  3285.             FRONT := FRONT + 1;
  3286.             if FRONT > BACK then
  3287.              -- The String contains all blanks, return access to a null string.
  3288.                FREE(T);
  3289.                T := new STRING'("");
  3290.                return;
  3291.             end if;
  3292.          end loop;
  3293.  
  3294.           -- The starting string index has been found, now move from the last
  3295.           -- string index to the left until a character other than blank is
  3296.           -- found, this will be the ending string index.
  3297.          while (T.all(BACK) = ' ') loop
  3298.             BACK := BACK - 1;
  3299.          end loop;
  3300.  
  3301.           -- A new string is created so the index will begin at 1.
  3302.          MAKE_NEW_STRING:
  3303.          declare
  3304.             NEW_STRING: STRING(1..BACK-FRONT+1) := T.all(FRONT..BACK);
  3305.          begin
  3306.             TEMP := new STRING'(NEW_STRING);
  3307.          end MAKE_NEW_STRING;
  3308.  
  3309.           -- Free the address currently pointed to by T, make T point to a new
  3310.           -- string, and free the address pointing to the temporary new string.
  3311.          FREE (T);
  3312.          T := new STRING'(TEMP.all);
  3313.          FREE (TEMP);
  3314.          return;
  3315.       end if;
  3316.  
  3317.    end PACK_TEXT;
  3318.  
  3319.  
  3320.    procedure UNPACK_TEXT (T: in out TEXT;  LEN: in NATURAL;
  3321.                 NO_ROOM: out BOOLEAN) is
  3322.     -- Adds trailing blanks to the given accessed string to make it the length
  3323.     -- requested in LEN. NO_ROOM is true when the LEN is smaller than the
  3324.     -- number of characters in the T accessed string.
  3325.       BLANK_AREA, TEMP: TEXT;      -- Blank area is TEXT object of blanks.
  3326.       NUMBER_OF_BLANKS: INTEGER;   -- Number of trailing blanks needed.
  3327.  
  3328.    begin
  3329.       INITIALIZE_TEXT (T);         -- Make T point to null string if T is null.
  3330.       if LENGTH(T) > LEN then
  3331.        -- Accessed string is to big.
  3332.          NO_ROOM := TRUE;
  3333.          return;
  3334.       elsif LENGTH(T) = LEN  then
  3335.        -- Accessed string is the same size as desired string. Keep T the
  3336.        -- same and return.
  3337.          NO_ROOM := FALSE;
  3338.          return;
  3339.       else
  3340.        -- The accessed string will have to be padded with trailing blanks.
  3341.        -- Find out how many blanks are needed, and make a TEXT object pointing
  3342.        -- to a string of that many blanks. Then make a temp TEXT object point
  3343.        -- to the concat of the original text and the blank string.
  3344.          NUMBER_OF_BLANKS := LEN - LENGTH(T);
  3345.          BLANK_AREA := new STRING'(1..NUMBER_OF_BLANKS => ' ');
  3346.          TEMP := new STRING'(T.all & BLANK_AREA.all);
  3347.           -- Free T blank string address, T address. Make T point to a string
  3348.           -- of the new longer value, an free the temp address.
  3349.          FREE (BLANK_AREA);
  3350.          FREE (T);
  3351.          T := new STRING'(TEMP.all);
  3352.          FREE (TEMP);
  3353.          NO_ROOM := FALSE;
  3354.          return;
  3355.       end if;
  3356.  
  3357.    end UNPACK_TEXT;
  3358.  
  3359.  
  3360.    function UNPACK_VALUE (T: TEXT;  LEN: NATURAL) return STRING is
  3361.     -- Returns a string of length LEN from the accessed string T. If T is too
  3362.     -- big, returns a string of blanks.
  3363.       NO_ROOM: BOOLEAN;
  3364.       TEMP_TEXT: TEXT := T;   -- Temp TEXT used as an (in out) parameter in
  3365.                               -- UNPACKED_TEXT call.
  3366.       BLANK_STRING: STRING(1..LEN) := (1..LEN => ' '); -- Blank line passed if
  3367.                                                        -- T is too big.
  3368.    begin
  3369.       UNPACK_TEXT(TEMP_TEXT,LEN,NO_ROOM);
  3370.       if NO_ROOM then
  3371.          return BLANK_STRING;
  3372.       else
  3373.          return VALUE(TEMP_TEXT);
  3374.       end if;
  3375.  
  3376.    end UNPACK_VALUE;
  3377.  
  3378.  
  3379.    function PACK_TO_TEXT (STR: STRING) return TEXT is
  3380.     -- Returns an access type pointing to a string with value STR, but with
  3381.     -- no leading or trailing blanks.
  3382.       TEMP_TEXT: TEXT;
  3383.    begin
  3384.        -- Convert string to TEXT, pack the TEXT oobject, and return the
  3385.        -- resulting object.
  3386.       TEMP_TEXT := TO_TEXT(STR);
  3387.       PACK_TEXT(TEMP_TEXT);
  3388.       return TEMP_TEXT;
  3389.    end PACK_TO_TEXT;
  3390.  
  3391.  
  3392.    procedure APPEND (TAIL: TEXT;  TO: in out TEXT) is
  3393.     -- TO will point to a string that is the accessed string TO concated with
  3394.     -- the accessed string TAIL.
  3395.       TEMP,TAIL1: TEXT;
  3396.  
  3397.     -- In this procedure a new object TAIL1 will point to the accessed string
  3398.     -- to be concatinated. This makes sure that the 2 concat objects do in
  3399.     -- fact point to strings and are not null pointers.
  3400.    begin
  3401.        -- Make sure TAIL1 points to a string.
  3402.       if TAIL = null then
  3403.          TAIL1 := new STRING'("");
  3404.       else
  3405.      TAIL1 := TAIL;
  3406.       end if;
  3407.  
  3408.        -- Make sure TO points to a string.
  3409.       INITIALIZE_TEXT (TO);
  3410.  
  3411.        -- if TO is empty, the new string is TAIL, otherwise free the old T
  3412.        -- address and make T point to a new string that is the concat of the
  3413.        -- two strings. 
  3414.       if EMPTY(TO) then
  3415.          TO := new STRING'(TAIL1.all);
  3416.       else
  3417.          TEMP := new STRING'(TO.all);
  3418.          FREE (TO);
  3419.          TO := new STRING'(TEMP.all & TAIL1.all);
  3420.          FREE (TEMP);
  3421.       end if;
  3422.  
  3423.    end APPEND;
  3424.  
  3425.  
  3426.    procedure APPEND (TAIL: STRING;  TO: in out TEXT) is
  3427.     -- TO will point to a string that is the accessed string TO concated with
  3428.     -- the string TAIL.
  3429.       TEMP: TEXT;
  3430.    begin
  3431.        -- Make sure T points to a string.
  3432.       INITIALIZE_TEXT (TO);
  3433.  
  3434.        -- if TO is empty, the new string is TAIL, otherwise free the old T
  3435.        -- address and make T point to a new string that is the concat of the
  3436.        -- two strings. 
  3437.       if EMPTY(TO) then
  3438.          TO := new STRING'(TAIL);
  3439.       else
  3440.          TEMP := new STRING'(TO.all);
  3441.          FREE (TO);
  3442.          TO := new STRING'(TEMP.all & TAIL);
  3443.          FREE (TEMP);
  3444.       end if;
  3445.  
  3446.    end APPEND;
  3447.  
  3448.  
  3449.    procedure APPEND (TAIL: CHARACTER;  TO: in out TEXT) is
  3450.     -- TO will point to a string that is the accessed string TO concated with
  3451.     -- the character TAIL.
  3452.       TEMP: TEXT;
  3453.  
  3454.    begin
  3455.        -- Make sure T points to a string.
  3456.       INITIALIZE_TEXT (TO);
  3457.  
  3458.        -- if TO is empty, the new string is TAIL, otherwise free the old T
  3459.        -- address and make T point to a new string that is the concat of the
  3460.        -- accessed string and the character given.
  3461.       if EMPTY(TO) then
  3462.          TO := new STRING'(STRNG(TAIL));
  3463.       else
  3464.          TEMP := new STRING'(TO.all);
  3465.          FREE (TO);
  3466.          TO := new STRING'(TEMP.all & STRNG(TAIL));
  3467.          FREE (TEMP);
  3468.       end if;
  3469.  
  3470.    end APPEND;
  3471.  
  3472.  
  3473.    function GIVE_POS (T: TEXT;  POSITION: NATURAL) return CHARACTER is
  3474.     -- Returns the character of accessed string T, that is the string index
  3475.     -- given in POSITION.
  3476.    begin
  3477.       return T.all(POSITION);
  3478.    exception
  3479.       when CONSTRAINT_ERROR =>
  3480.         return ' ';
  3481.    end GIVE_POS;
  3482.  
  3483.  
  3484.  
  3485. end TEXT_HANDLER_SUBSET;
  3486. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3487. --menuread.ada
  3488. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3489.  
  3490.  
  3491.  
  3492. -- MENUREAD;MENUREAD.ADA;KJL;04/11/85
  3493.  
  3494. -- This procedure is the main program executed when the Menu Compiler is run.
  3495. -- The procedure will first read a configuration file, named "MENCON" (this is
  3496. -- always the name of the configuration file). Using the values in the
  3497. -- configuration file, the procedure instantiates packages need, reads the 
  3498. -- input Menu Definition File (the name of the Menu Definition File is given
  3499. -- in the configuration file), and processes the Menu Definition file to create
  3500. -- a Menu Definition Table used by the Menu Handler.
  3501.  
  3502.  -- These packages contain the subprograms used by this program. The names
  3503.  -- listing are package UNIT names, and do not necessarily corrispond to file
  3504.  -- names when the packages are found.
  3505. with TEXT_IO, HANDLE_COMPILER_COMPONENTS, DISPLAY_PROCESSING,
  3506.      PROCESS_MENU_CONTROL_TABLE, PROCESS_MENU_DEF_STRING,
  3507.      COMPILER_MESSAGES, PROCESS_CONFIGURATION, TEXT_HANDLER_SUBSET;
  3508. procedure MENUREAD is
  3509.  
  3510.     -- Rename type to avoid using extended name.
  3511.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  3512.  
  3513.     -- The Menu Definition File is comprised of Lexical Units. The types of
  3514.     -- lexical units are: Identifier - like an instuction for the menu
  3515.     -- processing, and User Literals - literal information like display text
  3516.     -- or line numbers. Identifiers usually perform on User Literals. The 
  3517.     -- No More unit type signals there is no more lexical units, ie end of
  3518.     -- Menu Definition.
  3519.    type LEXICAL_UNIT_TYPES is (IDENTIFIER, USER_LITERAL, NO_MORE);
  3520.  
  3521.     -- Legal characters used to signal the separation of lex units.
  3522.    WORD_SEPARATORS       : constant STRING := ":, ;" 
  3523.             & ASCII.VT & ASCII.HT & ASCII.LF & ASCII.CR;
  3524.  
  3525.     -- Valid characters the user can use as "select keys" typed at the final
  3526.     -- menu to perform a desired action (all defined in the Menu Def File).
  3527.    USABLE_SELECT_KEYS    : constant STRING := "ABCDEFGHIJKLMNOPQRSTUVWXYZ" &
  3528.      "abcdefghijklmnopqrstuvwxyz" & "1234567890" & "!@#$%^&*()_-+=<,>.?/";
  3529.  
  3530.     -- Characters used as left and right delimiters for the User Literals in
  3531.     -- the Menu Def File, characters are currently '[' and ']'. If some other
  3532.     -- characters are desired (say quote marks "") the program can de changed
  3533.     -- here. Remeber the characters cannot in the User Select Keys or Word
  3534.     -- Separators, as this would confuse the parsing, and the compiler will 
  3535.     -- not work correctly.
  3536.    LEFT_DELIMITER        : constant CHARACTER := ASCII.L_BRACKET;
  3537.    RIGHT_DELIMITER       : constant CHARACTER := ASCII.R_BRACKET;
  3538.  
  3539.     -- Character used to indicate that what follows is a comment. The character
  3540.     -- can also be changed as long as it is not a delimiter, or Word Separator.
  3541.    COMMENT_INDICATOR     : constant CHARACTER := '*';
  3542.  
  3543.  
  3544.  
  3545.    MENU_DEF_FILE: TEXT_HANDLER_SUBSET.TEXT;
  3546.     -- Name of the file used as input to the Menu Compiler.
  3547.  
  3548.    FILE_ERROR: INTEGER;
  3549.     -- Used to determine errors in reading and writting the files. The
  3550.     -- procedures used to read and write will return an integer file error.
  3551.  
  3552.    MORE: BOOLEAN := TRUE;
  3553.     -- True if there are more Lexical Units to process.
  3554.  
  3555.  
  3556.  -- The processing first reads the configuration file, then starts a block
  3557.  -- statement that does runtime instantiation of the needed generic packages.
  3558.  -- At that point the procedures needed exist (with the proper configuration 
  3559.  -- constants) within the new packages.
  3560. begin
  3561.    PROCESS_CONFIGURATION.READ_CONFIGURATION_FILE;
  3562.    DO_MAIN_PROCESSING:
  3563.    declare
  3564.  
  3565.        -- Will contain subprograms to handle the Menu Def String
  3566.       package THIS_DEF_STRING is new PROCESS_MENU_DEF_STRING
  3567.     (LEXICAL_UNIT_TYPES,
  3568.          PROCESS_CONFIGURATION.LENGTH_OF_LINES_IN_MENU_FILE,
  3569.      WORD_SEPARATORS, 
  3570.          COMMENT_INDICATOR, 
  3571.          RIGHT_DELIMITER, 
  3572.          LEFT_DELIMITER);
  3573.  
  3574.        -- Will contain subprograms to handle building the menu display.
  3575.       package THIS_DISPLAY is new DISPLAY_PROCESSING
  3576.     (PROCESS_CONFIGURATION.SCREEN_WIDTH, 
  3577.          PROCESS_CONFIGURATION.SCREEN_LENGTH);
  3578.  
  3579.        -- Will contain subprograms to handle the list of "control items" being
  3580.        -- built (control items, ie what select key corrisponds to what type and
  3581.        -- name of program to initiate...).
  3582.       package THIS_MENU_CON_PROCESS is new PROCESS_MENU_CONTROL_TABLE
  3583.     (PROCESS_CONFIGURATION.ACTION_TYPES, 
  3584.          PROCESS_CONFIGURATION.MAX_FILE_NAME_LENGTH,
  3585.      PROCESS_CONFIGURATION.SCREEN_WIDTH, 
  3586.          THIS_DISPLAY.GET_NEXT_SCREEN_LINE,
  3587.      THIS_DISPLAY.END_OF_SCREEN, THIS_DISPLAY.PUT_NEXT_SCREEN_LINE,
  3588.          THIS_DISPLAY.CLEAR_SCREEN_LAYOUT);
  3589.  
  3590.        -- Will contain subprograms to puting message to the dsiplay during
  3591.        -- compilation.
  3592.       package THESE_COMPILER_MSGS is new COMPILER_MESSAGES
  3593.     (PROCESS_CONFIGURATION.SCREEN_WIDTH, 
  3594.          THIS_DEF_STRING.CURRENT_LEX_STRING,
  3595.      THIS_DEF_STRING.CURRENT_LINE_NUMBER);
  3596.  
  3597.        -- Will contain subprograms to evaluate the lexical units as received
  3598.        -- from the Menu Definition.
  3599.       package THIS_HANDLER is new HANDLE_COMPILER_COMPONENTS
  3600.     (LEXICAL_UNIT_TYPES, 
  3601.          PROCESS_CONFIGURATION.ACTION_TYPES, 
  3602.          USABLE_SELECT_KEYS, 
  3603.          PROCESS_CONFIGURATION.SCREEN_WIDTH,
  3604.      PROCESS_CONFIGURATION.SCREEN_LENGTH, 
  3605.          PROCESS_CONFIGURATION.MAX_FILE_NAME_LENGTH,
  3606.      THIS_MENU_CON_PROCESS.ADD_MENU_CONTROL_ITEM, THIS_DEF_STRING.
  3607.      GET_LEXICAL_UNIT_IF_NEEDED, THIS_DEF_STRING.UNIT_RECEIVED,
  3608.      THIS_DEF_STRING.CURRENT_LEX_TYPE, THIS_DEF_STRING.CURRENT_LEX_STRING,
  3609.      THIS_DISPLAY.PUT_SCREEN_TEXT, THESE_COMPILER_MSGS.SEND_COMPILE_ERROR);
  3610.  
  3611.  
  3612.     -- Once the packages are instantiates, the subprograms within them can be
  3613.     -- used in a logical sequence to do the menu compilation.
  3614.    begin
  3615.  
  3616.        -- Read all messages so that they are available for output.
  3617.       THESE_COMPILER_MSGS.INITIALIZE_MESSAGES;
  3618.  
  3619.        -- Initialize the screen layout array with all blanks (this array will
  3620.        -- contain the display layout as it is defined in the menu Definition).
  3621.        -- Write this blank page to the display.
  3622.       THIS_DISPLAY.CLEAR_SCREEN_LAYOUT;
  3623.       THIS_DISPLAY.PUT_SCREEN_LAYOUT_TO_CRT;
  3624.  
  3625.        -- The file used as the input Menu Definition File is the name given in
  3626.        -- the configuration file.
  3627.       MENU_DEF_FILE := PROCESS_CONFIGURATION.MENU_FILE;
  3628.  
  3629.        -- The input Menu Definition File is used to write a Menu Definition
  3630.        -- string which is simply a dynamic array of the whole Menu Def File.
  3631.        -- The external Menu Def File is closed imediately after the string
  3632.        -- is produced, and the Menu Def String is used for the remainder of the
  3633.        -- compilation in parsing and analyzing its lexical units. Error codes
  3634.        -- are returned if there were problems reading the Menu Def File, and
  3635.        -- compiler messages are displayed.
  3636.       THIS_DEF_STRING.WRITE_MENU_DEF_STRING(MENU_DEF_FILE, FILE_ERROR);
  3637.       if FILE_ERROR /= 0 then
  3638.          THESE_COMPILER_MSGS.SEND_COMPILE_ERROR(01);
  3639.       end if;
  3640.  
  3641.        -- The first lexical element to be found in the Menu Definition is a 
  3642.        -- title. The title will be the name of the Menu Def Table created.
  3643.       if not THESE_COMPILER_MSGS.FATAL_ERROR_STATUS then
  3644.          THIS_HANDLER.GET_THE_TITLE;
  3645.       end if;
  3646.  
  3647.        -- For the rest of the Menu Definition, get each lexical unit, and use
  3648.        -- the subprograms to process them, according to their type.
  3649.       while (MORE) and (not THESE_COMPILER_MSGS.FATAL_ERROR_STATUS) loop
  3650.           -- Subprogram makes available the next lexical unit to be analyzed.
  3651.           -- The actual text of the lexical unit is returned with another
  3652.           -- function, however the text in not needed here.
  3653.          THIS_DEF_STRING.GET_LEXICAL_UNIT_IF_NEEDED;
  3654.           -- The type of lexical unit is returned in a function.
  3655.          case THIS_DEF_STRING.CURRENT_LEX_TYPE is
  3656.            when USER_LITERAL =>
  3657.                -- A User Literal by itself is text to be put in the display
  3658.                -- layout. A subprogram is called to do this. The position in
  3659.                -- the display layout is determined by variables within the 
  3660.                -- THIS_HANDLER package, and those values are not needed here.
  3661.               THIS_HANDLER.WRITE_SCREEN_LAYOUT_TEXT
  3662.                               (THIS_DEF_STRING.CURRENT_LEX_STRING);
  3663.  
  3664.            when IDENTIFIER =>
  3665.                -- Identifiers are handled by a subprogram that analyzes what to
  3666.                -- do in the case of each identifier.
  3667.               THIS_HANDLER.PROCESS_IDENTIFIER
  3668.                               (THIS_DEF_STRING.CURRENT_LEX_STRING);
  3669.  
  3670.            when NO_MORE =>
  3671.                -- End of Menu Definition (Menu Definition String)
  3672.               MORE := FALSE;
  3673.          end case;
  3674.  
  3675.       end loop;
  3676.  
  3677.        -- Write a Menu Def Table (if no error has prevented it), from the list
  3678.        -- of control items built, and from the menu display layout built. Also
  3679.        -- include some configuration information in the file, and the Bad 
  3680.        -- Selection Message.
  3681.       if (not THESE_COMPILER_MSGS.DISABLE_ERROR_STATUS) then
  3682.          THIS_MENU_CON_PROCESS.WRITE_MENU_CONTROL_FILE
  3683.             (THIS_HANDLER.THE_TITLE_NAME,
  3684.              THIS_HANDLER.THE_BAD_SELECTION_MESSAGE, FILE_ERROR);
  3685.           -- Errors can occur when an attempt is made to write a file. Issue
  3686.           -- the appropriate message to the user.
  3687.          if FILE_ERROR /= 0 then
  3688.             THESE_COMPILER_MSGS.SEND_COMPILE_ERROR(02);
  3689.          end if;
  3690.       end if;
  3691.  
  3692.        -- Issue a final summary message, number of errors, severity, and
  3693.        -- whether or not Menu Def Table was created.
  3694.       THESE_COMPILER_MSGS.SEND_FINAL_MESSAGE;
  3695.  
  3696.     -- End the block statement, end the compiler.
  3697.    end DO_MAIN_PROCESSING;
  3698.  
  3699. end MENUREAD;
  3700. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3701. --menushow.ada
  3702. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3703.  
  3704.  
  3705.  
  3706. -- MENUSHOW;MENUSHOW.ADA;KJL;04/15/85;
  3707.  
  3708. -- This procedure is the main program executed when the Menu Handler is run.
  3709. -- The procedure will read the configuration file, MENCON (this is always the
  3710. -- name of the configuration file). Using the values read from the config file,
  3711. -- the program will instantiate packages to create procedures that work for
  3712. -- this particular configuration. The program will read a Menu Definition Table
  3713. -- (the name of the file is given in the MENCON config file), and will display
  3714. -- the proper menu layout, and do the proper processing on the users inputs.
  3715.  
  3716.  -- These packages listed contain the subprograms used by this procedure. The
  3717.  -- names are library UNIT names and do not necessarily corrispond to the 
  3718.  -- file names where the packages are found.
  3719. with TEXT_IO, DISPLAY_PROCESSING, PROCESS_MENU_CONTROL_TABLE,
  3720.      COMPILER_MESSAGES, PROCESS_CONFIGURATION, TEXT_HANDLER_SUBSET,
  3721.      CONTROLLING_MENU_INFO_LINE, HANDLE_PROCESSES, PROCESS_INITIATOR;
  3722. procedure MENUSHOW is
  3723.  
  3724.     -- Rename the TEXT type to avoid using the extended dot notation.
  3725.    subtype TEXT is TEXT_HANDLER_SUBSET.TEXT;
  3726.  
  3727.     -- Inputs from the user are either command lines, or a selection key. Each
  3728.     -- input will be given one of these types.
  3729.    type INPUT_TYPES is (CLI_COMMAND, SELECTION);
  3730.  
  3731.     -- The user inputs a "!" which causes the menu processing to then allow a
  3732.     -- line to be typed and passed to the CLI. If a different character is
  3733.     -- desired for this "escape" character, then this constant can be changed.
  3734.    CLI_INDICATOR: constant CHARACTER := '!';
  3735.  
  3736.     -- The name of the Menu Definition Table that is being used for the 
  3737.     -- current Menu Processing. The Menu Def Table contains the layout for the
  3738.     -- menu display, and the selections available, and the corrisponding
  3739.     -- actions.
  3740.    MENU_TABLE_FILE: TEXT;
  3741.  
  3742.     -- Text for the Bad Selection Message used for the current menu being
  3743.     -- processed. This text is read from the Menu Def Table.
  3744.    BAD_SELECTION_MSG: TEXT;
  3745.  
  3746.     -- Used to determine errors when reading the Menu Def Tables.
  3747.    FILE_ERROR: INTEGER;
  3748.    CANNOT_OPEN: constant := 1;
  3749.    IMPROPER_CONFIG: constant := 2;
  3750.  
  3751.     -- Text of the users input to the menu processor.
  3752.    USER_INPUT: TEXT;
  3753.     -- Type of input from the user to the menu processor.
  3754.    USER_INPUT_TYPE: INPUT_TYPES;
  3755.  
  3756.     -- Dummy function used in instantiation of packages. The Menu Handler will
  3757.     -- not need a function to return Lex Units, it is not parsing any files.
  3758.    function DUMMY_RETURN_LEX_STRING return TEXT is
  3759.    begin
  3760.       return TEXT_HANDLER_SUBSET.TO_TEXT("No Function");
  3761.    end DUMMY_RETURN_LEX_STRING;
  3762.  
  3763.     -- Dummy function needed  to instantiate the error messages package. No
  3764.     -- Line number is needed for runtime errors.
  3765.    function DUMMY_RETURN_LINE_NUMBER return INTEGER is
  3766.    begin
  3767.       return 0;
  3768.    end DUMMY_RETURN_LINE_NUMBER;
  3769.  
  3770.  
  3771.  -- Start MENUSHOW procedure. Read the configuration file and start a block
  3772.  -- statement that will do runtime instantiations of the packages needed.
  3773. begin
  3774.  
  3775.    PROCESS_CONFIGURATION.READ_CONFIGURATION_FILE;
  3776.    DO_MENU_HANDLER:
  3777.    declare
  3778.  
  3779.        -- Package will contain subprograms needed to read the Menu Display
  3780.        -- layout from the Menu Def Table, and put the layout to menu display.
  3781.       package THIS_DISPLAY is new DISPLAY_PROCESSING
  3782.        (PROCESS_CONFIGURATION.SCREEN_WIDTH,
  3783.         PROCESS_CONFIGURATION.SCREEN_LENGTH);
  3784.  
  3785.        -- Package will contain subprograms to read the Menu Def Table into
  3786.        -- a list of control items (accessed from menu selections), and into 
  3787.        -- the display layout kept in the THIS_DISPLAY package.
  3788.       package THIS_MENU_CON_PROCESS is new PROCESS_MENU_CONTROL_TABLE
  3789.        (PROCESS_CONFIGURATION.ACTION_TYPES, PROCESS_CONFIGURATION.MAX_FILE_NAME_LENGTH,
  3790.         PROCESS_CONFIGURATION.SCREEN_WIDTH,
  3791.         THIS_DISPLAY.GET_NEXT_SCREEN_LINE, THIS_DISPLAY.END_OF_SCREEN,
  3792.         THIS_DISPLAY.PUT_NEXT_SCREEN_LINE,
  3793.         THIS_DISPLAY.CLEAR_SCREEN_LAYOUT);
  3794.  
  3795.        -- Package will contain the subprograms to output messages to the user
  3796.        -- durring the running of the Menu Handler.
  3797.       package THESE_PROGRAM_MSGS is new COMPILER_MESSAGES
  3798.        (PROCESS_CONFIGURATION.SCREEN_WIDTH,
  3799.         DUMMY_RETURN_LEX_STRING, DUMMY_RETURN_LINE_NUMBER);
  3800.  
  3801.        -- Package will contain the Menu Info Line that appears at the bottom
  3802.        -- of the screen. The subprograms will set the line to certain values,
  3803.        -- and return the text of the line to be displayed with the menu layout.
  3804.       package THIS_INFO_LINE is new CONTROLLING_MENU_INFO_LINE
  3805.        (PROCESS_CONFIGURATION.SCREEN_WIDTH);
  3806.  
  3807.        -- Package will contain subprograms to handle the inputs from the menu
  3808.        -- user once they are received from the terminal.
  3809.       package THESE_PROCESSES is new HANDLE_PROCESSES
  3810.        (PROCESS_CONFIGURATION.ACTION_TYPES, INPUT_TYPES,
  3811.         THIS_MENU_CON_PROCESS.RETRIEVE_CONTROL_ITEM,
  3812.         PROCESS_INITIATOR.COMMAND_LINE_PROCESSOR,
  3813.         PROCESS_INITIATOR.ADA_PROCEDURE_CALL,
  3814.         THESE_PROGRAM_MSGS.SEND_RUNTIME_ERROR,
  3815.         THIS_INFO_LINE.SET_BAD_SELECTION,
  3816.         THIS_INFO_LINE.SET_TASK_STARTED);
  3817.  
  3818.        -- This local procedure accepts inputs from the terminal. Only a
  3819.        -- single character is accepted unless that character is the "escape"
  3820.        -- character '!', in which case a full line is then accepted from the
  3821.        -- terminal. The output of this procedure is the text of the users input
  3822.        -- and the type of input; Selection character or CLI line.
  3823.       procedure ACCEPT_INPUT (SELECT_OR_STRING: out INPUT_TYPES;
  3824.                                    USERS_INPUT: out TEXT) is
  3825.           -- Used as first character received.
  3826.          INPUT_CHAR: CHARACTER;
  3827.           -- Character string input when user enters a CLI line after '!'.
  3828.          INPUT_STRING: STRING(1..PROCESS_CONFIGURATION.SCREEN_WIDTH);
  3829.           -- Index of last character in the string input.
  3830.          LAST_INDEX: POSITIVE;
  3831.  
  3832.       begin
  3833.           -- Get the first character.
  3834.          TEXT_IO.GET(INPUT_CHAR);
  3835.          if INPUT_CHAR = CLI_INDICATOR then
  3836.              -- Accept a CLI line, set the type of input to CLI command.
  3837.             TEXT_IO.GET_LINE(INPUT_STRING,LAST_INDEX);
  3838.             SELECT_OR_STRING := CLI_COMMAND;
  3839.             USERS_INPUT := TEXT_HANDLER_SUBSET.PACK_TO_TEXT
  3840.                               (INPUT_STRING(1..LAST_INDEX));
  3841.          else
  3842.              -- Accept no more characters, set type of input to Selection.
  3843.             SELECT_OR_STRING := SELECTION;
  3844.             USERS_INPUT := TEXT_HANDLER_SUBSET.TO_TEXT(INPUT_CHAR);
  3845.          end if;
  3846.          return;
  3847.       end ACCEPT_INPUT;
  3848.  
  3849.  
  3850.        -- This local procedure is used to set up the user display. It will
  3851.        -- start a new line, put the Menu Display Layout to the screen, and
  3852.        -- put the Menu Info Line to the screen. If the screen width is big
  3853.        -- enough, the prompt line will be put to the screen and the cursor
  3854.        -- will wait following this prompt for user inputs.
  3855.       procedure PUT_MENU_DISPLAY is
  3856.          PROMPT_STRING: constant STRING := "==>>";
  3857.       begin
  3858.          TEXT_IO.NEW_LINE;
  3859.           -- Current Menu Display Layout to the screen.
  3860.          THIS_DISPLAY.PUT_SCREEN_LAYOUT_TO_CRT;
  3861.           -- Current Menu Info Line to the screen.
  3862.          TEXT_IO.PUT_LINE(THIS_INFO_LINE.RETURN_INFO_LINE);
  3863.           -- Prompt line to screen if room.
  3864.          if PROCESS_CONFIGURATION.SCREEN_WIDTH > PROMPT_STRING'LENGTH then
  3865.             TEXT_IO.PUT(PROMPT_STRING);
  3866.          end if;
  3867.       end PUT_MENU_DISPLAY;
  3868.  
  3869.  
  3870.     -- Begin the DO_MENU_HANDLER block which is the logic for the Menu Handler.
  3871.     -- Following the initialization steps, the Menu Handler performs a loop
  3872.     -- until a QUIT character is entered. The loop will:
  3873.     --         Put the full menu display on the screen.
  3874.     --         Accept user input, receive text and the type of input.
  3875.     --         (Exit loop if the input is a QUIT character).
  3876.     --         Pass the text and type input to a processor, that will do all
  3877.     --             processing necessary for the given input.
  3878.     --         Test if the next menu to be displayed is different from the 
  3879.     --             current menu. If so, read the corrisponding Menu Def Table
  3880.     --             for that menu, so that the Display Layout and a Control
  3881.     --             List of selections is made available.
  3882.     -- When the loop exits, the program exits.
  3883.    begin
  3884.  
  3885.        -- Do initialization first. Make the system messages available to be
  3886.        -- output on command. Clear the screen display.
  3887.       THESE_PROGRAM_MSGS.INITIALIZE_MESSAGES;
  3888.       THIS_DISPLAY.CLEAR_SCREEN_LAYOUT;
  3889.       THIS_DISPLAY.PUT_SCREEN_LAYOUT_TO_CRT;
  3890.  
  3891.        -- The program may use a number of Menu Def Tables throughout the course
  3892.        -- of the run. The first Menu Def Table used it receives from the file
  3893.        -- name specified in the MENCON config file. The program will try to
  3894.        -- read from a file with this name first, and if an error occurs, the 
  3895.        -- Menu Handler will abort. A successful read of a Menu Def Table will
  3896.        -- cause the loop to start.
  3897.       MENU_TABLE_FILE := PROCESS_CONFIGURATION.MENU_TABLE;
  3898.       THIS_MENU_CON_PROCESS.READ_MENU_CONTROL_FILE
  3899.           (MENU_TABLE_FILE, BAD_SELECTION_MSG, FILE_ERROR);
  3900.       if FILE_ERROR = CANNOT_OPEN then
  3901.           -- The external file could not be opened. The program always trys to
  3902.           -- open the file of the name given in the config file. The user has
  3903.           -- to copy other Menu Def Tables into that file name if they want to
  3904.           -- use different Menu Def Tables.
  3905.          THESE_PROGRAM_MSGS.SEND_RUNTIME_ERROR(29);
  3906.  
  3907.       elsif FILE_ERROR = IMPROPER_CONFIG then
  3908.           -- The Menu Def Table read was created with a different config than
  3909.           -- what is currently running. This is illegal since foramted records
  3910.           -- have to be read from the file, and the wrong string lengths
  3911.           -- defined would result in improper reading of the records.
  3912.          THESE_PROGRAM_MSGS.SEND_RUNTIME_ERROR(30);
  3913.       else
  3914.  
  3915.           -- The initial file was read correctly. Set up the Bad Selection
  3916.           -- Message and start the loop.
  3917.          THIS_INFO_LINE.RECEIVE_BAD_SELECT_MESSAGE
  3918.             (TEXT_HANDLER_SUBSET.VALUE(BAD_SELECTION_MSG));
  3919.          loop
  3920.              -- Display to screen, accept and process inputs.
  3921.             PUT_MENU_DISPLAY;
  3922.             ACCEPT_INPUT(USER_INPUT_TYPE, USER_INPUT);
  3923.             exit when  (TEXT_HANDLER_SUBSET.GIVE_POS(USER_INPUT,1) =
  3924.                     PROCESS_CONFIGURATION.QUIT_CHARACTER);
  3925.             THESE_PROCESSES.DO_REQUEST(MENU_TABLE_FILE, USER_INPUT,
  3926.                                              USER_INPUT_TYPE);
  3927.  
  3928.              -- From the processing performed on the input, the next menu to
  3929.              -- be displayed may be different from the current menu. Test this
  3930.              -- and read a new Menu Def Table external file if a new menu is
  3931.              -- to be displayed.
  3932.             if TEXT_HANDLER_SUBSET.VALUE(THESE_PROCESSES.MENU_TO_BE_DISPLAYED) /=
  3933.                   TEXT_HANDLER_SUBSET.VALUE(MENU_TABLE_FILE) then
  3934.                THIS_MENU_CON_PROCESS.READ_MENU_CONTROL_FILE
  3935.                  (THESE_PROCESSES.MENU_TO_BE_DISPLAYED, BAD_SELECTION_MSG,
  3936.                   FILE_ERROR);
  3937.                 -- On errors in reading a new Menu Def Table, the old menu
  3938.                 -- is still used for display and selections.
  3939.                if FILE_ERROR = CANNOT_OPEN then
  3940.                    -- The new menus Menu Def Table cannot be opened. Could be
  3941.                    -- the file is missing, of the wrong name given in the Menu
  3942.                    -- Def File. At this point the Menu Handler no longer uses
  3943.                    -- the file name found in the MENCON file. The file name
  3944.                    -- for all further menus to be displayed are those specified
  3945.                    -- in the the Select instructions of the Menu Def Files.
  3946.                   THESE_PROGRAM_MSGS.SEND_RUNTIME_ERROR(31);
  3947.  
  3948.                elsif FILE_ERROR = 2 then
  3949.                    -- The Menu Def Table read was compiled with a different
  3950.                    -- configuration than what is currently running. The Menu
  3951.                    -- Def Table cannot be used.
  3952.                   THESE_PROGRAM_MSGS.SEND_RUNTIME_ERROR(32);
  3953.  
  3954.                else
  3955.                    -- The Menu Def Table can be used for the next menu to be
  3956.                    -- displayed. Set the name of the current menu to the new
  3957.                    -- menu, and reset the Bad Selection Message.
  3958.                   TEXT_HANDLER_SUBSET.CLEAR_TEXT(MENU_TABLE_FILE);
  3959.                   MENU_TABLE_FILE := THESE_PROCESSES.MENU_TO_BE_DISPLAYED;
  3960.                   THIS_INFO_LINE.RECEIVE_BAD_SELECT_MESSAGE
  3961.                          (TEXT_HANDLER_SUBSET.VALUE(BAD_SELECTION_MSG));
  3962.                end if;  -- Test for file errors.
  3963.  
  3964.             end if;  -- Test for new menu specified.
  3965.  
  3966.          end loop;  -- Main loop for Menu Handler.
  3967.       end if;  -- File errors in reading initial Menu Def Table.
  3968.  
  3969.    end DO_MENU_HANDLER;
  3970.  
  3971.  
  3972. end MENUSHOW;
  3973.  
  3974.