home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / pdl / dd.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  339.8 KB  |  8,337 lines

  1. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  2. --DDRELEASE.ADA
  3. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4. function DD_Release return String is
  5. --| Returns current release number for data dictionary tools
  6. begin
  7.     return "1.1";
  8. end DD_Release;
  9. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  10. --SSTRINGS.SPC
  11. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  12. package Screen_Strings is
  13. --| Varying length strings which are no longer than the maximum number of
  14. --| columns on a terminal screen.
  15.  
  16. --| Overview
  17. --|
  18. --| The following operations are provided:
  19. --|
  20. --|     Create (2)        - Create a Screen_String from a string
  21. --|     Unchecked_Create  - Create a Screen_String from a string
  22. --|     Value             - Returns the string value of a Screen_String
  23. --|     Length            - Returns the length of a Screen_String
  24. --|     "<" (3)           - Less than operation
  25. --|     Equal (3)         - Equality operation
  26. --|     "&" (3)           - Concatenation operation
  27. --|     Substring         - Returns a substring of a given Screen_String
  28. --|     Match_Prefix (3)  - Returns whether one screen string is a prefix 
  29. --|                       - of another
  30. --|     Match_Pattern (3) - Returns starting index of matching pattern
  31. --|
  32.  
  33. -------------------------------------------------------------------------------
  34.  
  35. -- Exceptions
  36.  
  37.     String_Too_Long   : exception;  --| Raised when Create is attempted for a
  38.                                     --| string with length > Max_Screen_Columns
  39.     Invalid_Substring : exception;  --| Raised when substring specified is 
  40.                                     --| outside the bounds of the Screen_String
  41.  
  42. -------------------------------------------------------------------------------
  43.  
  44. -- Types and Objects
  45.  
  46.     type Screen_String is private;
  47.  
  48.     Max_Screen_Columns : constant := 80;  --| Maximum length of Screen_String
  49.     subtype Length_Range is natural range 0 .. Max_Screen_Columns;
  50.  
  51. -------------------------------------------------------------------------------
  52.  
  53. -- Operations
  54.  
  55.     function Create(  --| Create a Screen_String from a string
  56.         S : String    --| String to create a Screen_String from
  57.         ) return Screen_String;
  58.         --| Raises: String_Too_Long
  59.  
  60.     --| Effects: Creates a value of type Screen_String from the String s.
  61.     --| String_Too_Long is raised if the length of S is greater than
  62.     --| Max_Screen_Columns.
  63.  
  64.     --| N/A: Requires, Modifies
  65.  
  66.     ---------------------------------------------------------------------------
  67.  
  68.     procedure Create(                   --| Create Screen_String from string
  69.         S         : String;             --| String to create Screen_String from
  70.         SS        : out Screen_String;  --| Return value
  71.         Truncated : out Boolean         --| Whether any text was truncated
  72.         );
  73.  
  74.     --| Effects: Creates a value of type Screen_String from the String s.
  75.     --| If the length of s is greater than Max_Screen_Columns, the text
  76.     --| is truncated and Truncated is true.
  77.  
  78.     --| N/A: Raises, Requires, Modifies
  79.  
  80.     ---------------------------------------------------------------------------
  81.     
  82.     function Unchecked_Create(  --| Create a Screen_String from a string
  83.         S : String              --| String to create Screen_String from
  84.         ) return Screen_String;
  85.  
  86.     --| Effects: Creates a value of type Screen_String from the string s.
  87.     --| If the length of s is greater than Max_Screen_Columns, the text
  88.     --| is truncated.
  89.  
  90.     ---------------------------------------------------------------------------
  91.  
  92.     function Value(         --| Returns the string value of a Screen_String
  93.         SS : Screen_String  --| Screen_String value
  94.         ) return String;
  95.  
  96.     --| Effects: Returns the value of Screen_String SS.
  97.  
  98.     --| N/A: Raises, Requires, Modifies
  99.  
  100.     ---------------------------------------------------------------------------
  101.  
  102.     function Length(            --| Returns the length of a Screen_String
  103.         SS : Screen_String      --| Screen_String whose length to return
  104.         ) return Length_Range;
  105.  
  106.     --| Effects: Returns the length of Screen_String SS.
  107.  
  108.     --| N/A: Raises, Requires, Modifies
  109.  
  110.     ---------------------------------------------------------------------------
  111.  
  112.     function "<"(                 --| Returns Value(SS1) < Value(SS2)
  113.         SS1, SS2 : Screen_String  --| Screen_Strings to compare
  114.         ) return Boolean;
  115.  
  116.     --| Effects: Returns true if Value(SS1) < Value(SS2); false otherwise.  
  117.  
  118.     --| N/A: Raises, Requires, Modifies
  119.  
  120.     ---------------------------------------------------------------------------
  121.  
  122.     function "<"(            --| Returns Value(SS) < S
  123.         SS : Screen_String;  --| Screen_String to compare
  124.         S  : String          --| String to compare
  125.         ) return Boolean;
  126.  
  127.     --| Effects: Returns true if Value(SS) < S; false otherwise.  
  128.  
  129.     --| N/A: Raises, Requires, Modifies
  130.  
  131.     ---------------------------------------------------------------------------
  132.  
  133.     function "<"(           --| Returns S < Value(SS)
  134.         S  : String;        --| String to compare
  135.         SS : Screen_String  --| Screen_String to compare
  136.         ) return Boolean;
  137.  
  138.     --| Effects: Returns true if S < Value(SS); false otherwise.  
  139.  
  140.     --| N/A: Raises, Requires, Modifies
  141.  
  142.     ---------------------------------------------------------------------------
  143.  
  144.     function Equal(               --| Returns Value(SS1) = Value(SS2)
  145.         SS1, SS2 : Screen_String  --| Screen_Strings to compare
  146.         ) return Boolean;
  147.  
  148.     --| Effects: Returns true if Value(SS1) = Value(SS2); false otherwise.
  149.  
  150.     --| N/A: Raises, Requires, Modifies
  151.  
  152.     ---------------------------------------------------------------------------
  153.  
  154.     function Equal(             --| Returns Value(SS) = S
  155.         SS : Screen_String;     --| Screen_String to compare
  156.         S  : String             --| String to compare
  157.         ) return Boolean;
  158.  
  159.     --| Effects: Returns true if Value(SS) = S; false otherwise.
  160.  
  161.     --| N/A: Raises, Requires, Modifies
  162.  
  163.     ---------------------------------------------------------------------------
  164.  
  165.     function Equal(             --| Returns S = Value(SS)
  166.         S  : String;            --| String to compare
  167.         SS : Screen_String      --| Screen_String to compare
  168.         ) return Boolean;
  169.  
  170.     --| Effects: Returns true if S = Value(SS); false otherwise.
  171.  
  172.     --| N/A: Raises, Requires, Modifies
  173.  
  174.     ---------------------------------------------------------------------------
  175.  
  176.     function "&"(             --| Concatenation operation
  177.         SS1 : Screen_String;  --| First Screen_String to concatenate
  178.         SS2 : Screen_String   --| Second Screen_String to concatenate
  179.         ) return Screen_String;
  180.         --| Raises: String_Too_Long
  181.  
  182.     --| Effects: Concatenates Value(SS1) with Value(SS2) and returns a
  183.     --| Screen_String.
  184.  
  185.     --| N/A: Requires, Modifies
  186.  
  187.     ---------------------------------------------------------------------------
  188.  
  189.     function "&"(            --| Concatenation operation
  190.         SS : Screen_String;  --| Screen_String to concatenate
  191.         S  : String          --| String to concatenate
  192.         ) return Screen_String;
  193.         --| Raises: String_Too_Long
  194.  
  195.     --| Effects: Concatenates Value(SS) with S and returns a Screen_String.
  196.  
  197.     --| N/A: Requires, Modifies
  198.  
  199.     ---------------------------------------------------------------------------
  200.  
  201.     function "&"(            --| Concatenation operation
  202.         S  : String;         --| String to concatenate
  203.         SS : Screen_String   --| Screen_String to concatenate
  204.         ) return Screen_String;
  205.         --| Raises: String_Too_Long
  206.  
  207.     --| Effects: Concatenates S with Value(SS) and returns a Screen_String.
  208.  
  209.     --| N/A: Requires, Modifies
  210.  
  211.     ---------------------------------------------------------------------------
  212.  
  213.     function Substring(          --| Returns a substring of SS
  214.         SS     : Screen_String;  --| Screen string from which to get substring
  215.         Start  : Length_Range;   --| Starting index of substring
  216.         Length : Length_Range    --| Length of substring
  217.         ) return Screen_String;
  218.         --| Raises: Invalid_Substring
  219.  
  220.     --| Effects: Returns the substring of SS starting at Start and having
  221.     --| length Length.  Invalid_Substring is raised when the combination of
  222.     --| Start and Length is outside the bounds of SS.
  223.  
  224.     --| N/A: Requires, Modifies
  225.  
  226.     ---------------------------------------------------------------------------
  227.  
  228.     function Match_Prefix(    --| Returns whether SS1 is a prefix of SS2
  229.         SS1 : Screen_String;  --| The prefix Screen_String
  230.         SS2 : Screen_String   --| Screen_String to compare prefix against
  231.         ) return Boolean;
  232.  
  233.     --| Effects: If SS1 is a prefix of SS2, returns true.  Otherwise returns
  234.     --| false.  Note that this subprogram is not case sensitive; eg. 
  235.     --| CR would be a valid prefix of create.
  236.  
  237.     --| N/A: Raises, Requires, Modifies
  238.  
  239.     ---------------------------------------------------------------------------
  240.  
  241.     function Match_Prefix(   --| Returns whether S is a prefix of SS
  242.         S  : String;         --| The prefix String
  243.         SS : Screen_String   --| Screen_String to compare prefix against
  244.         ) return Boolean;
  245.  
  246.     --| Effects: If S is a prefix of SS, returns true.  Otherwise returns
  247.     --| false.  Note that this subprogram is not case sensitive; eg. 
  248.     --| CR would be a valid prefix of create.
  249.  
  250.     --| N/A: Raises, Requires, Modifies
  251.  
  252.     ---------------------------------------------------------------------------
  253.  
  254.     function Match_Prefix(   --| Returns whether SS is a prefix of S
  255.         SS : Screen_String;  --| The prefix Screen_String
  256.         S  : String          --| String to compare prefix against
  257.         ) return Boolean;
  258.  
  259.     --| Effects: If SS is a prefix of S, returns true.  Otherwise returns
  260.     --| false.  Note that this subprogram is not case sensitive; eg. 
  261.     --| CR would be a valid prefix of create.
  262.  
  263.     --| N/A: Raises, Requires, Modifies
  264.  
  265.     ---------------------------------------------------------------------------
  266.  
  267.     function Match_Pattern(       --| Matches a pattern in a screen_string
  268.         Pattern : Screen_String;  --| The pattern to match
  269.         Text    : Screen_String   --| Text in which to search for pattern
  270.         ) return Length_Range;
  271.  
  272.     --| Effects: Returns the index into Text where it matches Pattern.
  273.     --| If the pattern is not found, then 0 is returned.
  274.  
  275.     --| N/A: Raises, Requires, Modifies
  276.  
  277.     ---------------------------------------------------------------------------
  278.  
  279.     function Match_Pattern(       --| Matches a pattern in a screen_string
  280.         Pattern : String;         --| The pattern to match
  281.         Text    : Screen_String   --| Text in which to search for pattern
  282.         ) return Length_Range;
  283.  
  284.     --| Effects: Returns the index into Text where it matches Pattern.
  285.     --| If the pattern is not found, then 0 is returned.
  286.  
  287.     --| N/A: Raises, Requires, Modifies
  288.  
  289.     ---------------------------------------------------------------------------
  290.  
  291.     function Match_Pattern(       --| Matches a pattern in a screen_string
  292.         Pattern : Screen_String;  --| The pattern to match
  293.         Text    : String          --| Text in which to search for pattern
  294.         ) return Length_Range;
  295.  
  296.     --| Effects: Returns the index into Text where it matches Pattern.
  297.     --| If the pattern is not found, then 0 is returned.
  298.  
  299.     --| N/A: Raises, Requires, Modifies
  300.  
  301.     ---------------------------------------------------------------------------
  302.  
  303. private
  304.  
  305.     type Screen_String is
  306.         record
  307.             Length : Length_Range;
  308.             Text : String(1 .. Length_Range'Last);
  309.         end record;
  310.  
  311.     ---------------------------------------------------------------------------
  312.  
  313. end Screen_Strings;
  314.  
  315. -------------------------------------------------------------------------------
  316. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  317. --TEMPLATES.SPC
  318. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  319. with Screen_Strings;
  320. -------------------------------------------------------------------------------
  321.  
  322. package Templates is
  323. --| Provide a collection of templates and the functions to access them.
  324.  
  325. --| Overview
  326. --|
  327. --| This package provides all of the templates for the Data Dictionary.  The
  328. --| templates are initialized in the body of this package so that they may be
  329. --| changed without requiring recompilation of all packages dependent on this
  330. --| specification.
  331. --| 
  332. --| The following operations are provided:
  333. --|
  334. --|     Field_Count            - Returns the number of fields in a template
  335. --|     Variable_Field_Count   - Returns the number of variable fields
  336. --|     Variable_Field_Number  - Returns the variable field number, given the
  337. --|                              actual field number
  338. --|     Variable_Field_Number  - Returns the variable field number, given the
  339. --|                              field name
  340. --|     Actual_Field_Number    - Returns the actual field number, given the
  341. --|                              variable field number
  342. --|     Actual_Field_Number    - Returns the actual field number, given the
  343. --|                              field name
  344. --|     First_Variable_Field_Number
  345. --|                            - Returns the variable field number of the first
  346. --|                              variable field on a line
  347. --|     Template_Label         - Returns the label of a template
  348. --|     Field_Mode             - Returns the mode of a field
  349. --|     Field_Position         - Returns the position of a field
  350. --|     Field_Label            - Returns the label of a field
  351. --|     Field_Length           - Returns the length of a field
  352. --|     Field_Help             - Returns help line for a field
  353.  
  354. -------------------------------------------------------------------------------
  355.  
  356.     package SS renames Screen_Strings;
  357.  
  358. -------------------------------------------------------------------------------
  359.  
  360. -- Types and Objects
  361.  
  362.     type Template_Name is  --| All template types 
  363.         (Object_Decl, Type_Decl, Procedure_Decl, Function_Decl, Package_Decl,
  364.         Task_Decl, Exception_Decl);
  365.         -- generics?
  366.  
  367.     type Position_Descriptor is  --| Position of a template field
  368.         record
  369.             Line   : Positive;   --| Line where field begins
  370.             Column : Positive;   --| Column where field begins
  371.         end record;
  372.  
  373.     Max_Fields : constant := 45; -- arbitrary and may need to be changed
  374.  
  375.     type Actual_Field_Range is new Natural range 0 .. Max_Fields;
  376.     subtype Actual_Field_Number_Range is
  377.         Actual_Field_Range range 1 .. Actual_Field_Range'Last;
  378.  
  379.     type Variable_Field_Range is new Natural range 0 .. Max_Fields;
  380.     subtype Variable_Field_Number_Range is 
  381.         Variable_Field_Range range 1 .. Variable_Field_Range'Last;
  382.  
  383.     type Field_Mode_Name is  --| Whether or not the field text always appears
  384.         (Variable, Static);  --| on the screen (Variable means that the field
  385.                              --| text is replaced by the text in a dictionary
  386.                              --| entry when the template is filled in. 
  387.  
  388. -------------------------------------------------------------------------------
  389.  
  390. -- Exceptions
  391.  
  392.     No_Such_Field             : exception;  --| The specified field doesn't 
  393.                                             --| exist
  394.     No_Such_Line              : exception;  --| The specified line doesn't
  395.                                             --| exit
  396.     No_Variable_Field_On_Line : exception;  --| No variable fields were found
  397.                                             --| on the specified line
  398.     Not_A_Variable_Field      : exception;  --| Attempt to find variable field
  399.                                             --| number for a static field
  400.  
  401. -------------------------------------------------------------------------------
  402.  
  403. -- Operations
  404.  
  405.     function Field_Count(         --| Returns the number of fields in template
  406.         Template : Template_Name  --| Template containing fields
  407.         ) return Actual_Field_Range;
  408.  
  409.     --| Effects: The number of fields in a template are returned.  "Number of
  410.     --| fields" refers to the total number of fields.  Whether the fields are
  411.     --| variable or static is irrelevant to this count.
  412.  
  413.     --| N/A: Raises, Requires, Modifies
  414.  
  415.     ---------------------------------------------------------------------------
  416.  
  417.     function Variable_Field_Count(  --| Returns the number of variable fields
  418.         Template : Template_Name    --| Template containing fields
  419.         ) return Variable_Field_Range;
  420.  
  421.     --| Effects: The number of variable fields in a template are returned.
  422.  
  423.     --| N/A: Raises, Requires, Modifies
  424.  
  425.     ---------------------------------------------------------------------------
  426.  
  427.     function Variable_Field_Number(   --| Returns the variable field number,
  428.                                       --| given the actual field number
  429.         Template            : Template_Name; 
  430.                                       --| Template containing fields
  431.         Actual_Field_Number : Actual_Field_Number_Range
  432.                                       --| actual field number (out of total)
  433.         ) return Variable_Field_Number_Range;
  434.         --| Raises: No_Such_Field, Not_A_Variable_Field
  435.  
  436.     --| Effects: Returns the variable field number for the field designated by
  437.     --| the actual (total) field number
  438.     --| For example, in the template:
  439.     --|
  440.     --| <identifier> : <type>
  441.     --|
  442.     --| The actual field numbers are:
  443.     --| <identifier>    1
  444.     --| :               2
  445.     --| <type>          3
  446.     --|
  447.     --| but the variable field numbers are:
  448.     --| <identifier>    1
  449.     --| :               not a variable field
  450.     --| <type>          2
  451.     --|
  452.     --| No_Such_Field is raised when the specified field doesn't exist.
  453.     --| Not_A_Variable_Field is raised when the specified field is a static
  454.     --| field.
  455.  
  456.     --| N/A: Requires, Modifies
  457.  
  458.     ---------------------------------------------------------------------------
  459.  
  460.     function Variable_Field_Number(   --| Returns the variable field number,
  461.                                       --| given the field name
  462.         Template   : Template_Name;   --| Template containing fields
  463.         Field_Name : SS.Screen_String --| name of the field
  464.         ) return Variable_Field_Number_Range;
  465.         --| Raises: No_Such_Field
  466.  
  467.     --| Effects: Returns the variable field number for the field Field_Name
  468.     --| No_Such_Field is raised if no variable field with name Field_Name 
  469.     --| exists.
  470.  
  471.     --| N/A: Requires, Modifies
  472.  
  473.     ---------------------------------------------------------------------------
  474.  
  475.     function Actual_Field_Number(     --| Returns the actual field number,
  476.                                       --| given the variable field number
  477.         Template              : Template_Name; 
  478.                                       --| Template containing fields
  479.         Variable_Field_Number : Variable_Field_Number_Range
  480.         ) return Actual_Field_Number_Range;
  481.         --| Raises: No_Such_Field
  482.  
  483.     --| Effects: Returns the actual field number for the nth variable field,
  484.     --| where n is Variable_Field_Number.
  485.     --| For example, in the template:
  486.     --|
  487.     --| <identifier> : <type>
  488.     --|
  489.     --| The actual field numbers are:
  490.     --| <identifier>    1
  491.     --| :               2
  492.     --| <type>          3
  493.     --|
  494.     --| but the variable field numbers are:
  495.     --| <identifier>    1
  496.     --| :               not a variable field
  497.     --| <type>          2
  498.     --|
  499.     --| No_Such_Field is raised if the specified field doesn't exist.
  500.  
  501.     --| N/A: Requires, Modifies
  502.  
  503.     ---------------------------------------------------------------------------
  504.  
  505.     function Actual_Field_Number(     --| Returns the actual field number,
  506.                                       --| given the field name
  507.         Template   : Template_Name;   --| Template containing fields
  508.         Field_Name : SS.Screen_String --| name of the field
  509.         ) return Actual_Field_Number_Range;
  510.         --| Raises: No_Such_Field
  511.  
  512.     --| Effects: Returns the variable field number for the field Field_Name
  513.     --| No_Such_Field is raised if no field with name Field_Name exists.
  514.  
  515.     --| N/A: Requires, Modifies
  516.  
  517.     ---------------------------------------------------------------------------
  518.  
  519.     function First_Variable_Field_Number(  --| Returns the variable field
  520.                                            --| number of the first field on 
  521.                                            --| a line
  522.         Template : Template_Name;          --| Template containing field
  523.         Line     : Positive                --| Line within template
  524.         ) return Variable_Field_Number_Range;
  525.         --| Raises: No_Such_Line, No_Variable_Field_On_Line
  526.  
  527.     --| Effects:  Returns the variable field number for the first field on
  528.     --| the given line.  No_Such_Line is raised if the specified line doesn't
  529.     --| exist.  No_Variable_Field_on_Line is raised if no variable field exists
  530.     --| on the specified line.
  531.  
  532.     --| N/A: Requires, Modifies
  533.  
  534.     ---------------------------------------------------------------------------
  535.  
  536.     function Template_Label(      --| Returns the label of a template
  537.         Template : Template_Name  --| Template from which to get label
  538.         ) return SS.Screen_String;
  539.  
  540.     --| Effects: Returns a label such as "Object Declaration" for the template
  541.     --| specified by Template.
  542.  
  543.     --| N/A: Raises, Requires, Modifies
  544.  
  545.     ---------------------------------------------------------------------------
  546.  
  547.     function Field_Mode(               --| Returns the mode of a field
  548.         Template     : Template_Name;  --| Template containing field
  549.         Field_Number : Actual_Field_Number_Range
  550.                                        --| Field whose mode to return
  551.         ) return Field_Mode_Name;
  552.         --| Raises: No_Such_Field
  553.  
  554.     --| Effects:  The mode (static or variable) of a field is returned for
  555.     --| the given Template and Field_Number.  If Field_Number is greater 
  556.     --| than the number of fields, No_Such_Field is raised.
  557.  
  558.     --| N/A: Requires, Modifies
  559.  
  560.     ---------------------------------------------------------------------------
  561.  
  562.     function Field_Position(           --| Returns the position of a field
  563.         Template     : Template_Name;  --| Template containing field
  564.         Field_Number : Actual_Field_Number_Range
  565.                                        --| Field whose position to return
  566.         ) return Position_Descriptor;
  567.         --| Raises: No_Such_Field
  568.  
  569.     --| Effects:  The position of a field, which includes its line and
  570.     --| starting column, is returned for the given Template and Field_Number.
  571.     --| If Field_Number is greater than the number of fields, No_Such_Field 
  572.     --| is raised.
  573.  
  574.     --| N/A: Requires, Modifies
  575.  
  576.     ---------------------------------------------------------------------------
  577.  
  578.     function Field_Label(             --| Returns the label of a field
  579.         Template     : Template_Name; --| Template containing field
  580.         Field_Number : Actual_Field_Number_Range
  581.                                       --| Field whose label to return
  582.         ) return SS.Screen_String;
  583.         --| Raises: No_Such_Field
  584.  
  585.     --| Effects:  The label of a field is returned for the given Template and
  586.     --| Field_Number.  For static fields, the label is just the text of that
  587.     --| field.  For variable fields, the label is what would be displayed on
  588.     --| the screen if that field is blank.  If Field_Number is greater 
  589.     --| than the number of fields, No_Such_Field is raised.
  590.  
  591.     --| N/A: Requires, Modifies
  592.  
  593.     ---------------------------------------------------------------------------
  594.  
  595.     function Field_Length(             --| Returns the length of a field
  596.         Template     : Template_Name;  --| Template containing field
  597.         Field_Number : Actual_Field_Number_Range
  598.                                        --| Field whose length to return
  599.         ) return Positive;
  600.         --| Raises: No_Such_Field
  601.  
  602.     --| Effects:  The length of a field is returned for the given Template 
  603.     --| and Field_Number.  If Field_Number is greater than the number of 
  604.     --| fields, No_Such_Field is raised.
  605.  
  606.     --| N/A: Requires, Modifies
  607.  
  608.     ---------------------------------------------------------------------------
  609.  
  610.     function Field_Help(                   --| Returns help line for a field
  611.         Template     : Template_Name;      --| Template containing field
  612.         Field_Number : Variable_Field_Number_Range
  613.                                            --| Field whose help to return
  614.         ) return SS.Screen_String;
  615.         --| Raises: No_Such_Field
  616.  
  617.     --| Effects:  The help line for a field is returned for the given Template
  618.     --| and Field_Number.  The help line is one line explaining what 
  619.     --| information belongs in a particular field.  If Field_Number is greater
  620.     --| than the number of fields, No_Such_Field is raised.
  621.  
  622.     --| N/A: Requires, Modifies
  623.  
  624.     ---------------------------------------------------------------------------
  625.  
  626. end Templates;
  627.  
  628. -------------------------------------------------------------------------------
  629. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  630. --DICTMGR.SPC
  631. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  632. with Direct_IO;
  633. with Screen_Strings;
  634. with Templates;
  635. -------------------------------------------------------------------------------
  636.  
  637. package Dictionary_Manager is
  638. --| Provide operations to manage a collection of dictionary entries associated
  639. --| with various template types.
  640.  
  641. --| Overview
  642. --|
  643. --| This package provides operations to access a data dictionary containing 
  644. --| entries which are associated with the template types provided in package
  645. --| Templates.  The operations provided allow creation, deletion and updating
  646. --| of dictionary entries.
  647. --|
  648. --| Open_Dictionary must be called before any accessing of the dictionary
  649. --| can be performed.  Close_Dictionary must be called to close all open
  650. --| files in the dictionary.
  651. --|
  652. --| The following operations are provided:
  653. --|
  654. --|         Create_Dictionary     - Creates a new dictionary
  655. --|         Open_Dictionary       - Opens all dictionary files
  656. --|         Close_Dictionary      - Closes all dictionary files
  657. --|         New_Entry_Handle      - Returns handle to new dictionary entry
  658. --|         Entry_Handle          - Returns handle to existing entry
  659. --|         Entry_Exists          - Determines whether an entry is exists
  660. --|         Unique_Entry          - Determines whether an entry is unique
  661. --|         Overloads             - Returns overload fields for an entry
  662. --|         Delete_Entry          - Deletes dictionary entry
  663. --|         Create_Entry          - Creates a new entry
  664. --|         Update_Entry          - Updates an existing dictionary entry
  665. --|         Update_Field          - Updates a field in a dictionary entry
  666. --|         Field_Contents        - Returns the contents of a field
  667. --|         Template_Kind         - Returns the template type for this handle
  668. --|
  669.  
  670. -------------------------------------------------------------------------------
  671.  
  672.     package SS renames Screen_Strings;
  673.     package TP renames Templates;
  674.  
  675. -------------------------------------------------------------------------------
  676.  
  677. -- Exceptions
  678.  
  679.     Cant_Create_Directory    : exception;  --| Error occured while trying to
  680.                                            --| create a directory
  681.     Invalid_Dictionary_File  : exception;  --| An attempt was made to refer to
  682.                                            --| a nonexistent dictionary file
  683.     Dictionary_Locked        : exception;  --| The dictionary requested is
  684.                                            --| already locked by another user
  685.     Lock_is_Missing          : exception;  --| The lock file for the dictionary
  686.                                            --| is missing
  687.     No_Dictionary_File       : exception;  --| Open_Dictionary hasn't been
  688.                                            --| called
  689.     Index_File_Error         : exception;  --| Error occurred while trying to
  690.                                            --| open an index file
  691.     Data_File_Error          : exception;  --| Error occurred while trying to
  692.                                            --| open a data file
  693.     No_Such_Dictionary_Entry : exception;  --| An attempt was made to refer to
  694.                                            --| a nonexistent entry
  695.     No_Such_Occurrence       : exception;  --| An attempt was made to refer to
  696.                                            --| a nonexistent occurrence of
  697.                                            --| template type + identifier
  698.     Invalid_Entry_Handle     : exception;  --| Entry handle is null
  699.     Field_Not_Found          : exception;  --| An attempt was made to refer to
  700.                                            --| a nonexistent field of an entry
  701.     Null_Identifier          : exception;  --| An attempt was made to create or
  702.                                            --| update an entry with null 
  703.                                            --| identifier field.
  704.     No_Overload_Field        : exception;  --| An attempt was made to create a
  705.                                            --| non-unique entry which had no
  706.                                            --| overload field
  707.     Too_Many_Overloads       : exception;  --| The number of overloads is at
  708.                                            --| its maximum
  709.     Cant_Update_New_Entry    : exception;  --| An attempt was made to "update"
  710.                                            --| an entry which wasn't originally
  711.                                            --| read from the dictionary
  712.  
  713. -------------------------------------------------------------------------------
  714.  
  715.     package Report_Utilities is
  716.     --| Provides subprograms to produce reports on dictionary entries.
  717.  
  718.     --| Overview
  719.     --|
  720.     --| The following operations are provided:
  721.     --|
  722.     --| Set_Up_Report  - initializes parameters for reporting
  723.     --| Make_Report    - makes the report
  724.     --|
  725.  
  726.     ---------------------------------------------------------------------------
  727.  
  728.     -- Types
  729.  
  730.         type Report_Name is (Summary, Full, Command_File);
  731.  
  732.     ---------------------------------------------------------------------------
  733.  
  734.     -- Exceptions
  735.  
  736.         Abort_Report : exception;  --| Dictionary or file couldn't be opened
  737.                                    --| want to return error status in driver
  738.  
  739.     ---------------------------------------------------------------------------
  740.  
  741.     -- Operations
  742.  
  743.         procedure Set_Up_Report(  --| Initializes parameters for reporting
  744.             Dictionary_Name : in String;  --| Name of dictionary to open
  745.             Entries         : in String;  --| Entries to report on
  746.             Entry_Name      : in String   --| File containing entries to report
  747.             ); 
  748.             --| Raises: Abort_Report
  749.  
  750.         --| Effects:  Opens the dictionary and reads and parses the entries 
  751.         --| specified in file Entry_Name to set up which entries are to be
  752.         --| included in the report.  An error message is printed and 
  753.         --| Abort_Report is raised if an error occurs while trying to open
  754.         --| Entry_Name.
  755.  
  756.         --| N/A: Requires, Modifies
  757.  
  758.         -----------------------------------------------------------------------
  759.  
  760.         procedure Make_Report(             --| Makes the report
  761.             Report      : in Report_Name;  --| Which type of report to make
  762.             Output_Name : in String        --| Name of output file
  763.             );
  764.             --| Raises: No_Dictionary_File
  765.  
  766.         --| Effects:  Makes the report.  Report determines whether to make
  767.         --| a Summary, Full or Command_File report.  The summary report is
  768.         --| paginated and has the following form:
  769.         --|
  770.         --| template-name Entries:
  771.         --|     identifier
  772.         --|         first overload of identifier
  773.         --|         second overload of identifier
  774.         --|         .
  775.         --|         .
  776.         --|         .
  777.         --|     .
  778.         --|     .
  779.         --|     .
  780.         --| .
  781.         --| .
  782.         --| .
  783.         --|
  784.         --| The full report has an entry for each selected identifier which is
  785.         --| very similar to the format which appears on the screen in the
  786.         --| Edit_Dictionary tool.  It is also paginated.  Each entry in the
  787.         --| Command_File report has the form:
  788.         --|
  789.         --| UPDATE template-type identifier occurrence
  790.         --| <field-label>field-contents
  791.         --| .
  792.         --| .
  793.         --| .
  794.         --|
  795.         --| The Command_File report is not paginated, as it is intended for
  796.         --| use as input to the Update_Dictionary tool.
  797.  
  798.         --| N/A: Requires, Modifies
  799.  
  800.         -----------------------------------------------------------------------
  801.  
  802.     end Report_Utilities;
  803.  
  804. -------------------------------------------------------------------------------
  805.  
  806. -- Types and Objects
  807.  
  808.     type Dictionary_Entry_Handle is private;
  809.  
  810.     Max_Overloads : constant Natural := 10;  
  811.     --| Maximum number of times a name can be overloaded for one template type
  812.  
  813.     subtype Overload_Range is positive range 1 .. Max_Overloads;
  814.     type Overload_Array is array(Overload_Range) of SS.Screen_String;
  815.     --| Array of <overload> fields for all instances of a name for one template
  816.     --| type
  817.  
  818. -------------------------------------------------------------------------------
  819.  
  820. -- Operations
  821.  
  822.     procedure Create_Dictionary(     --| Creates a new dictionary
  823.         Dictionary_Name : in String  --| Name of dictionary to create
  824.         );
  825.         --| Raises: Cant_Create_Directory
  826.  
  827.     --| Effects: Creates a new dictionary with name Dictionary_Name and
  828.     --| all associated files.  Cant_Create_Directory is raised if an error
  829.     --| occurs while trying to create the dictionary.  The files are not
  830.     --| left open; i.e., Open_Dictionary must be called if other dictionary
  831.     --| manager subprograms are to be called after Create_Dictionary.
  832.  
  833.     --| N/A: Requires, Modifies
  834.  
  835.     ---------------------------------------------------------------------------
  836.  
  837.     procedure Open_Dictionary(        --| Opens all dictionary files
  838.         Dictionary_Name : in String   --| Name of dictionary
  839.         );
  840.     --| Raises: Invalid_Dictionary_File, Dictionary_Locked, Lock_is_Missing,
  841.     --|         Data_File_Error
  842.  
  843.     --| Effects: Opens all the necessary files in the dictionary and makes
  844.     --| the dictionary the current directory.  Invalid_Dictionary_File is
  845.     --| raised if the dictionary requested doesn't exist.  Dictionary_Locked
  846.     --| is raised if another user is accessing the same dictionary.  
  847.     --| Lock_is_Missing is raised if the lock file for the dictionary is 
  848.     --| missing.  Data_File_Error is raised if an error occurred while trying
  849.     --| to open the dictionary's data files.
  850.  
  851.     --| Modifies: Current Dictionary File
  852.  
  853.     --| N/A: Requires
  854.  
  855.     ---------------------------------------------------------------------------
  856.  
  857.     procedure Close_Dictionary;  --| Closes all dictionary files
  858.     --| Raises: No_Dictionary_File
  859.  
  860.     --| Effects: Closes all open files in the dictionary and writes out the
  861.     --| index files.  No_Dictionary_File is raised if Open_Dictionary hasn't
  862.     --| been called first.
  863.  
  864.     --| N/A: Requires, Modifies
  865.  
  866.     ---------------------------------------------------------------------------
  867.  
  868.     function New_Entry_Handle(       --| Returns handle to new dictionary entry
  869.         Template : TP.Template_Name  --| Template type to associate with entry
  870.         ) return Dictionary_Entry_Handle;
  871.         --| Raises: No_Dictionary_File
  872.  
  873.     --| Effects: Returns a handle to a new dictionary entry associated with
  874.     --| a template of type Template.  If Open_Dictionary hasn't been 
  875.     --| called first, No_Dictionary_File is raised.
  876.  
  877.     --| N/A: Requires, Modifies
  878.  
  879.     ---------------------------------------------------------------------------
  880.  
  881.     function Entry_Handle(                --| Returns handle to existing entry
  882.         Template     : TP.Template_Name;  --| Template type of entry
  883.         Identifier   : SS.Screen_String;  --| Entry identifier
  884.         Occurrence   : Overload_Range     --| Occurrence of Entry_Handle to 
  885.             := 1                          --| retrieve.
  886.         ) return Dictionary_Entry_Handle;
  887.         --| Raises: No_Dictionary_File, No_Such_Dictionary_Entry,
  888.         --|         No_Such_Occurrence
  889.  
  890.     --| Effects: Returns a handle to the occurrence Occurence of the dictionary
  891.     --| entry having the type Template and the name Identifier.  If 
  892.     --| Open_Dictionary hasn't been called first, No_Dictionary_File is raised.
  893.     --| If the dictionary does not contain any entries having type Template and
  894.     --| name identifier, No_Such_Dictionary_Entry is raised.  If Occurrence is
  895.     --| greater than the number of occurrences, No_Such_Occurrence is raised.
  896.  
  897.     --| N/A: Requires, Modifies
  898.  
  899.     ---------------------------------------------------------------------------
  900.  
  901.     function Entry_Exists(  --| Determines whether an entry exists
  902.         Template    : TP.Template_Name;  --| Template type of entry
  903.         Identifier  : SS.Screen_String;  --| Entry identifier
  904.         Occurrence  : Overload_Range     --| Occurrence of template, identifier
  905.             := 1
  906.         ) return Boolean;
  907.         --| Raises: No_Dictionary_File
  908.  
  909.     --| Effects: This function returns whether or not an entry of type Template
  910.     --| and name Identifier exists.  If Open_Dictionary hasn't been called 
  911.     --| first, No_Dictionary_File is raised.  In order to check whether a
  912.     --| Template + Identifier pair exists (without checking for a specific
  913.     --| occurrence), let Occurrence default to 1.
  914.  
  915.     --| N/A: Requires, Modifies
  916.  
  917.     ---------------------------------------------------------------------------
  918.  
  919.     function Unique_Entry(  --| Determines whether an entry is unique
  920.         Template     : TP.Template_Name;  --| Template type of entry
  921.         Identifier   : SS.Screen_String   --| Entry identifier
  922.         ) return Boolean;
  923.         --| Raises: No_Dictionary_File, No_Such_Dictionary_Entry
  924.  
  925.     --| Effects: This function returns whether or not an entry of type Template
  926.     --| and name Identifier is unique.  If exactly one entry of type Template
  927.     --| and name Identifier exists, Unique_Entry returns True.  If more than
  928.     --| one entry with type Template and name Identifier exists, Unique_Entry
  929.     --| returns false.  If Open_Dictionary hasn't been called first, 
  930.     --| No_Dictionary_File is raised.  If no entry with type Template and name
  931.     --| Identifier exists in the dictionary,  No_Such_Dictionary_Entry is
  932.     --| raised.
  933.  
  934.     --| N/A: Requires, Modifies
  935.  
  936.     ---------------------------------------------------------------------------
  937.  
  938.     function Overloads(                --| Returns overload fields for an entry
  939.         Template     : TP.Template_Name;  --| Template type of entry
  940.         Identifier   : SS.Screen_String   --| Entry identifier
  941.         ) return Overload_Array;
  942.         --| Raises: No_Dictionary_File, No_Such_Dictionary_Entry
  943.  
  944.     --| Effects
  945.  
  946.     --| Returns an array of <overload> fields for all instances of an 
  947.     --| "overloaded" name (i.e. a name of an entry of a particular template
  948.     --| type which appears more than one time in the dictionary).
  949.     --| If Open_Dictionary hasn't been called first, No_Dictionary_File is
  950.     --| raised.  If no entry with type Template and name Identifier exists in 
  951.     --| the dictionary, No_Such_Dictionary_Entry is raised.
  952.  
  953.     --| N/A: Requires, Modifies
  954.  
  955.     ---------------------------------------------------------------------------
  956.  
  957.     procedure Delete_Entry(             --| Deletes dictionary entry
  958.         Entry_Handle : Dictionary_Entry_Handle  --| Entry to delete
  959.         );
  960.         --| Raises: Invalid_Entry_Handle, No_Such_Dictionary_Entry
  961.  
  962.     --| Effects: The entry referenced by Entry_Handle is deleted.
  963.     --| If Entry_Handle is null, Invalid_Entry_Handle is raised.
  964.     --| If Entry_Handle wasn't originally retrieved from the dictionary (i.e.
  965.     --| it was created with New_Entry_Handle or it was previously deleted),
  966.     --| No_Such_Dictionary_Entry is raised.
  967.  
  968.     --| N/A: Requires, Modifies
  969.  
  970.     ---------------------------------------------------------------------------
  971.  
  972.     procedure Create_Entry(                       --| Creates a new entry
  973.         Entry_Handle : Dictionary_Entry_Handle    --| Entry to create
  974.         );
  975.         --| Raises: No_Dictionary_File, Invalid_Entry_Handle, Null_Identifier,
  976.         --|         No_Overload_Field, Too_Many_Overloads
  977.  
  978.     --| Effects: A new data dictionary entry is created from Entry_Handle.
  979.     --| No_Dictionary_File is raised if Open_Dictionary hasn't been 
  980.     --| called first.  Invalid_Entry_Handle is raised if Entry_Handle is null.
  981.     --| Null_Identifier is raised when the identifier field in the handle is
  982.     --| the null string.  No_Overload_Field is raised if there are more than 
  983.     --| one entry with the particular template type and identifier as 
  984.     --| specified in the object referenced by Entry_Handle, and the <overload>
  985.     --| field is not filled out.  Too_Many_Overloads is raised when an attempt
  986.     --| is made to create an entry whose name has already been overloaded the
  987.     --| maximum number of times.
  988.  
  989.     --| N/A: Requires, Modifies
  990.  
  991.     ---------------------------------------------------------------------------
  992.  
  993.     procedure Update_Entry(  --| Updates an existing dictionary entry
  994.         Entry_Handle : Dictionary_Entry_Handle 
  995.                              --| Handle referencing entry to update
  996.         );
  997.         --| Raises: No_Dictionary_File, Invalid_Entry_Handle, Null_Identifier
  998.         --|         No_Overload_Field, Too_Many_Overloads, Cant_Update_New_Entry
  999.  
  1000.     --| Effects: The entry in the data dictionary corresponding to the object
  1001.     --| referenced by Entry_Handle is updated.  No_Dictionary_File is raised if
  1002.     --| Open_Dictionary hasn't been called.  Invalid_Entry_Handle is raised
  1003.     --| when the Entry_Handle is null.  Null_Identifier is raised when the 
  1004.     --| identifier field in the handle is the null string.  Too_Many_Overloads
  1005.     --| is raised when an attempt is made to create (by updating with a 
  1006.     --| a different identifier field) an entry whose name has already been 
  1007.     --| overloaded the maximum number of times.  Cant_Update_New_Entry is
  1008.     --| raised when an attempt to update an item which does not already exist 
  1009.     --| in the dictionary.
  1010.  
  1011.     --| N/A: Requires, Modifies
  1012.  
  1013.     ---------------------------------------------------------------------------
  1014.  
  1015.     procedure Update_Field(                      --| Updates a field in entry
  1016.         Entry_Handle : Dictionary_Entry_Handle;  --| Entry to update
  1017.         Field_Number : TP.Variable_Field_Number_Range;
  1018.                                                  --| Which field to update
  1019.         New_Contents : SS.Screen_String          --| new contents of field
  1020.         );
  1021.         --| Raises: Field_Not_Found, Invalid_Entry_Handle
  1022.  
  1023.     --| Effects: The contents of field Field_Number are changed to 
  1024.     --| New_Contents in the entry referenced by Entry_Handle.  If the
  1025.     --| Entry_Handle is null, Invalid_Entry_Handle is raised.  If the
  1026.     --| Field_Number is invalid, Field_Not_Found is raised.
  1027.  
  1028.     --| N/A: Requires, Modifies
  1029.  
  1030.     ---------------------------------------------------------------------------
  1031.  
  1032.     function Field_Contents(         --| Returns the contents of a field
  1033.         Entry_Handle : Dictionary_Entry_Handle;
  1034.                                      --| Entry from which to get field contents
  1035.         Field_Number : TP.Variable_Field_Number_Range
  1036.                                      --| Which field to retrieve
  1037.         ) return SS.Screen_String;
  1038.         --| Raises: Invalid_Entry_Handle, Field_Not_Found
  1039.  
  1040.     --| Effects: The contents of the field Field_Number in the entry referenced
  1041.     --| by Entry_Handle are returned.  If the Entry_Handle is null, 
  1042.     --| Invalid_Entry_Handle is rasied.  If the Field_Number is invalid, 
  1043.     --| Field_Not_Found is raised.  Field_Number is the variable field number 
  1044.     --| of the field (Dictionary_Manager has no knowledge of static fields).
  1045.  
  1046.     --| N/A: Requires, Modifies
  1047.  
  1048.     ---------------------------------------------------------------------------
  1049.  
  1050.     function Template_Kind(          --| Returns the template type for handle
  1051.         Entry_Handle : Dictionary_Entry_Handle
  1052.                                      --| Entry from which to get template
  1053.         ) return TP.Template_Name;
  1054.         --| Raises: Invalid_Entry_Handle
  1055.  
  1056.     --| Effects: The template type for Entry_Handle is returned.  
  1057.     --| Invalid_Entry_Handle is raised if Entry_Handle is null.
  1058.  
  1059.     --| N/A: Requires, Modifies
  1060.  
  1061.     ---------------------------------------------------------------------------
  1062.  
  1063. private
  1064.  
  1065.     type Data_Array is 
  1066.         array(TP.Variable_Field_Number_Range) of SS.Screen_String;
  1067.  
  1068.     package DIO is new Direct_IO(Data_Array);
  1069.  
  1070.     type Dictionary_Entry_Descriptor is
  1071.         record
  1072.             Template   : TP.Template_Name;  --| Name of corresponding template
  1073.             Data       : Data_Array;        --| Contents of fields
  1074.             --| Data(TP.Variable_Field_Number_Range'First): identifier field
  1075.             --| Data(TP.Variable_Field_Number_Range'First + 1): overload field
  1076.             Read_From  : DIO.Count;         --| File position from which item 
  1077.                                             --| was read.
  1078.         end record;
  1079.     type Dictionary_Entry_Handle is access Dictionary_Entry_Descriptor;
  1080.  
  1081.     ---------------------------------------------------------------------------
  1082.  
  1083. end Dictionary_Manager;
  1084.  
  1085. -------------------------------------------------------------------------------
  1086. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1087. --CDRIVER.ADA
  1088. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1089. with Text_IO; use Text_IO;
  1090. with Dictionary_Manager;
  1091. with Standard_Interface;
  1092. with DD_Release;
  1093. with String_Pkg;
  1094. with Host_Lib;
  1095. -------------------------------------------------------------------------------
  1096.  
  1097. function Create_Dictionary_Driver return Integer is
  1098. --| Interprets command line and calls DM routine to create a data dictionary
  1099.  
  1100.     package DM renames Dictionary_Manager;
  1101.     package SI renames Standard_Interface;
  1102.     package SP renames String_Pkg;
  1103.       
  1104.     package Str_Argument is new SI.String_Argument("String");  
  1105.     Create_Handle : SI.Process_Handle;
  1106.  
  1107. begin
  1108.    
  1109.     -- Error messages go to standard error
  1110.     Host_Lib.Set_Error;
  1111.  
  1112.     SI.Set_Tool_Identifier(DD_Release);
  1113.     
  1114.     SI.Define_Process(
  1115.         Name => "Create_Dictionary",
  1116.         Help => "Create a data dictionary",
  1117.         Proc => Create_Handle);
  1118.  
  1119.     Str_Argument.Define_Argument(
  1120.         Proc => Create_Handle,
  1121.         Name => "Dictionary",
  1122.         Help => "Full directory name of dictionary to be created");
  1123.     
  1124.     SI.Parse_Line(Create_Handle);
  1125.  
  1126.     DM.Create_Dictionary(SP.Value(Str_Argument.Get_Argument(
  1127.         Proc => Create_Handle,
  1128.         Name => "Dictionary")));
  1129.         
  1130.     return Host_Lib.Return_Code(Host_Lib.Success);
  1131.  
  1132. exception
  1133.     when SI.Abort_Process => 
  1134.         return Host_Lib.Return_Code(Host_Lib.Error);
  1135.     when SI.Process_Help =>
  1136.         return Host_Lib.Return_Code(Host_Lib.Information);
  1137.     when DM.Cant_Create_Directory =>
  1138.         Put_Line(
  1139.             "Can't create dictionary " & 
  1140.             SP.Value(Str_Argument.Get_Argument(
  1141.                 Proc => Create_Handle,
  1142.                 Name => "Dictionary")) & ".");
  1143.         return Host_Lib.Return_Code(Host_Lib.Error);
  1144.     when others =>
  1145.         Put_Line("Create_Dictionary internal error.");
  1146.         return Host_Lib.Return_Code(Host_Lib.Error);
  1147.     
  1148. end Create_Dictionary_Driver;
  1149. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1150. --SCREENMGR.SPC
  1151. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1152. with Screen_Strings;
  1153. with Dictionary_Manager;
  1154. with Templates;
  1155. -------------------------------------------------------------------------------
  1156.  
  1157. package Screen_Manager is
  1158. --| Provide functions for displaying templates, menus, text and lines on the
  1159. --| screen.
  1160.      
  1161. --| Overview
  1162. --|     
  1163. --| This package provides all screen management functions for use in
  1164. --| displaying and editing templates on the screen.  The following
  1165. --| operations are provided:
  1166. --|
  1167. --|     Clear_Message_Line       - Clears the message line 
  1168. --|     Scroll_Prompt_Lines      - Scrolls the prompt lines
  1169. --|     Display_Message          - Displays a message on the message line
  1170. --|     Display_Blank_Template   - Displays a blank template form
  1171. --|     Display_Filled_Template  - Displays a filled in template
  1172. --|     Display_Prompt           - Displays a prompt on the prompt line
  1173. --|     Display_Secondary_Prompt - Displays a "secondary" prompt on prompt line
  1174. --|     Display_Menu             - Displays a menu of choices
  1175. --|     Position_For_Exit        - Repositions the cursor at bottom of screen
  1176. --|     Display_Command_List     - Displays a list of commands
  1177. --|     Display_Field            - Displays the contents of a field
  1178. --|
  1179. --| The screen is divided into 3 sections: the first 20 lines are reserved
  1180. --| for the template, the 21st line is blank, the 22nd and 23rd lines are the
  1181. --| prompt lines (22nd line contains what was just entered and 23rd line is
  1182. --| where user types), and the 24th line is the message line.
  1183.  
  1184. -------------------------------------------------------------------------------
  1185.  
  1186.     package SS renames Screen_Strings;
  1187.     package DM renames Dictionary_Manager;
  1188.     package TP renames Templates;
  1189.  
  1190. -------------------------------------------------------------------------------
  1191.  
  1192. -- Exceptions
  1193.  
  1194.    Secondary_Prompt_Too_Long : exception; --| Secondary prompt is too long to
  1195.                                           --| fit within line
  1196.  
  1197. -------------------------------------------------------------------------------
  1198.  
  1199. -- Types and Objects
  1200.  
  1201.     type Message_Name   is (Error, Warning, Help, Info);
  1202.     --| Type of message being displayed on message line
  1203.  
  1204.     type Menu_Mode_Name is (Prompt, Continue);
  1205.     --| Type of menu being presented (a menu to make a choice from, or just a
  1206.     --| list.
  1207.  
  1208.     Max_Lines : constant := 24;
  1209.     --| Maximum number of lines on the screen
  1210.  
  1211.     subtype Line_Range is Positive range 1 .. Max_Lines;
  1212.     --| Range of lines for the entire screen
  1213.  
  1214.     subtype Section1_Line_Range is Positive range 
  1215.         Line_Range'First .. Line_Range'Last - 3;
  1216.     --| Range of lines for section one of the screen
  1217.  
  1218.     type Screen_Array is array(Section1_Line_Range) of SS.Screen_String;
  1219.     --| Array of screen strings corresponding to what is displayed on screen
  1220.  
  1221. -------------------------------------------------------------------------------
  1222.  
  1223. -- Operations
  1224.  
  1225.     procedure Clear_Message_Line;   --| Clears message line
  1226.  
  1227.     --| Effects:  The message line is cleared.
  1228.  
  1229.     --| N/A: Raises, Requires, Modifies
  1230.  
  1231.     ---------------------------------------------------------------------------
  1232.  
  1233.     procedure Scroll_Prompt_Lines(   --| Scrolls the prompt lines
  1234.         Old_Text : SS.Screen_String  --| Text entered at last prompt
  1235.         );
  1236.  
  1237.     --| Effects:  The line containing the command entered is scrolled up
  1238.     --| one line and the "current prompt" (set by Display_Prompt) is redrawn
  1239.     --| on the prompt line.
  1240.  
  1241.     --| N/A: Raises, Requires, Modifies
  1242.  
  1243.     ---------------------------------------------------------------------------
  1244.  
  1245.     procedure Display_Message(        --| Displays message on the message line
  1246.         Text : SS.Screen_String;      --| Text to be displayed
  1247.         Name : Message_Name := Error  --| Type of message
  1248.         );
  1249.  
  1250.     --| Effects: A message is displayed on the message line.  The first
  1251.     --| part of the message is a code for the type of message, specified
  1252.     --| by Name, and the second part is the message text, specified by Text.
  1253.  
  1254.     --| N/A: Raises, Requires, Modifies
  1255.  
  1256.     ---------------------------------------------------------------------------
  1257.  
  1258.     procedure Display_Blank_Template(  --| Displays a blank template form
  1259.         Template : TP.Template_Name    --| Type of template to display
  1260.         );
  1261.  
  1262.     --| Effects: Displays a blank template of type Template on the screen.
  1263.  
  1264.     --| N/A: Raises, Requires, Modifies
  1265.  
  1266.     ---------------------------------------------------------------------------
  1267.  
  1268.     procedure Display_Filled_Template(   --| Displays filled in template
  1269.         Entry_Handle : DM.Dictionary_Entry_Handle
  1270.         --| Entry which contains information to display
  1271.         );
  1272.  
  1273.     --| Effects: Displays a template filled in with the information in 
  1274.     --| the dictionary entry referenced by Entry_Handle.  If the text in
  1275.     --| a field is null, the field label is displayed rather than the text.
  1276.  
  1277.     --| N/A: Raises, Requires, Modifies
  1278.  
  1279.     ---------------------------------------------------------------------------
  1280.  
  1281.     procedure Display_Prompt(             --| Displays prompt on prompt line
  1282.         Prompt_Text  : SS.Screen_String;  --| Text for the prompt
  1283.         Field_Prompt : Boolean := True    --| type of prompt
  1284.         );
  1285.  
  1286.     --| Effects: Displays a prompt.  If the prompt is a field prompt (as
  1287.     --| specified by Field_Prompt), it consists of the text Prompt_Text
  1288.     --| enclosed in angle brackets and followed by a colon and a space 
  1289.     --| on the prompt line.  Otherwise, just Prompt_Text is displayed, and
  1290.     --| current prompt and previous prompt are not modified.
  1291.  
  1292.     --| Modifies: current prompt, previous prompt
  1293.  
  1294.     --| N/A: Raises, Requires
  1295.  
  1296.     ---------------------------------------------------------------------------
  1297.  
  1298.     procedure Display_Secondary_Prompt(  --| Displays a "secondary" prompt on
  1299.                                          --| the prompt line
  1300.         Prompt_Text : SS.Screen_String   --| Text for the prompt
  1301.         ); --| Raises: Secondary_Prompt_Too_Long
  1302.  
  1303.     --| Effects: Displays a prompt which consists of the text Prompt_Text
  1304.     --| on the prompt line, but starting at the middle column on the screen 
  1305.     --| rather than at the left edge of the screen.  The "current prompt" is
  1306.     --| not altered.  Secondary_Prompt_too_Long is raised if Prompt_Text + 5
  1307.     --| (to allow room for a response) is too long to fit on the screen.
  1308.  
  1309.     --| N/A: Raises, Requires, Modifies
  1310.  
  1311.     ---------------------------------------------------------------------------
  1312.  
  1313.     procedure Display_Menu(               --| Displays a menu of choices
  1314.         Menu       : DM.Overload_Array;   --| Menu to display
  1315.         Menu_Mode  : Menu_Mode_Name :=    --| Mode of menu
  1316.             Prompt;
  1317.         Template   : TP.Template_Name :=  --| Name of template to which menu
  1318.             TP.Object_Decl;               --| corresponds
  1319.         Identifier : SS.Screen_String :=  --| Name of identifier to which menu
  1320.             SS.Create("")                 --| corresponds
  1321.         );
  1322.  
  1323.     --| Effects: The contents of Menu are numbered and displayed on the
  1324.     --| screen.  Menu_Mode specifies whether to display a prompt for a choice
  1325.     --| or the message "--Press return to continue--."  If Identifier is not 
  1326.     --| the null string, then a "header" for the menu is printed containing
  1327.     --| template and identifier.  If Identifier is the null string, this header
  1328.     --| is not printed and the contents of template are irrelevant.
  1329.  
  1330.     --| N/A: Raises, Requires, Modifies
  1331.  
  1332.     ---------------------------------------------------------------------------
  1333.  
  1334.     procedure Position_for_Exit; --| Repositions cursor at bottom of the screen
  1335.  
  1336.     --| Effects: The cursor is repositioned at the bottom of the screen in 
  1337.     --| order that the editor exits neatly.
  1338.  
  1339.     --| N/A: Raises, Requires, Modifies
  1340.  
  1341.     ---------------------------------------------------------------------------
  1342.  
  1343.     procedure Display_Command_List(  --| Displays a list of commands
  1344.         Command_List : Screen_Array  --| List of commands
  1345.         );
  1346.  
  1347.     --| Effects: Command_List is displayed on the screen.  The message
  1348.     --| "--Press return to continue--" is displayed on the prompt line.
  1349.  
  1350.     --| N/A: Raises, Requires, Modifies
  1351.  
  1352.     ---------------------------------------------------------------------------
  1353.  
  1354.     procedure Display_Field(  --| Displays contents of a field
  1355.         Entry_Handle : DM.Dictionary_Entry_Handle;
  1356.                               --| Entry containing field to display
  1357.         Field_Number : TP.Actual_Field_Number_Range
  1358.                               --| Which field to display
  1359.         );
  1360.  
  1361.     --| Effects: The contents of the Field Field_Number in dictionary entry
  1362.     --| referenced by Entry_Handle are displayed on the screen.  If the text in
  1363.     --| a field is null, the field label is displayed rather than the text.
  1364.  
  1365.     --| N/A: Raises, Requires, Modifies
  1366.  
  1367.     ---------------------------------------------------------------------------
  1368.  
  1369. end Screen_Manager; 
  1370.  
  1371. -------------------------------------------------------------------------------
  1372. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1373. --COMMANDS.SPC
  1374. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1375. with Screen_Strings; use Screen_Strings;
  1376. with Templates;
  1377. -------------------------------------------------------------------------------
  1378.  
  1379. package Commands is 
  1380. --| Provide procedures to process all interactive commands.
  1381.  
  1382. --| Overview
  1383. --|
  1384. --| This package provides procedures to process all of the interactive 
  1385. --| commands.  Nested package Editing_Commands contains all of the procedures
  1386. --| for processing the commands once they are parsed.  Procedure 
  1387. --| Process_Commands opens the dictionary, calls the internal procedures which
  1388. --| parse the commands and call the Editing_Commands procedures, and closes
  1389. --| the dictionary.  
  1390.  
  1391. -------------------------------------------------------------------------------
  1392.  
  1393. -- Exceptions
  1394.  
  1395.     Abort_Commands : exception;  --| Raised when interrupt or end of file 
  1396.                                  --| character is read
  1397.  
  1398. -- Operations
  1399.  
  1400.     procedure Process_Commands(           --| Processes editor commands
  1401.             Dictionary_Name : in String;  --| Name of dictionary
  1402.             Template   : in Templates.Template_Name;
  1403.                                           --| Type of template to edit
  1404.             Identifier : in Screen_String := Create("")
  1405.                                           --| Name of dictionary entry
  1406.         ); --| Raises: Abort_Commands
  1407.  
  1408.     --| Effects: This procedure opens the dictionary, processes editor commands
  1409.     --| and closes the dictionary.  Abort_Commands is raised when an interrupt
  1410.     --| or end of file character is read.
  1411.  
  1412.     --| N/A: Requires, Modifies
  1413.  
  1414.     ---------------------------------------------------------------------------
  1415.  
  1416.     package Editing_Commands is
  1417.  
  1418.         procedure Edit(  --| Displays template for editing
  1419.             Template   : in Templates.Template_Name;
  1420.                          --| Type of template to edit
  1421.             Identifier : in Screen_String := Create("")
  1422.                          --| Name of dictionary entry
  1423.             ); --| Raises: Abort_Commands
  1424.  
  1425.         --| Effects: This procedure displays a template on the screen for 
  1426.         --| editing.  If Identifier is "", the default, then an empty template 
  1427.         --| is displayed.  If the entry specified by Template and Identifier
  1428.         --| is not found in the dictionary, an empty template is displayed
  1429.         --| along with a warning message.  The user's prompt is then
  1430.         --| displayed as the first field.  If there are two or more entries
  1431.         --| in the dictionary with the same template type (Template) and name
  1432.         --| (Identifier), a menu of all <overload> fields, which distinguish
  1433.         --| entries with the same name from one another is displayed and the
  1434.         --| user must select the appropriate entry.  Abort_Commands is raised 
  1435.         --| when an interrupt or end of file character is read.
  1436.  
  1437.         --| N/A: Requires, Modifies
  1438.  
  1439.         -----------------------------------------------------------------------
  1440.  
  1441.         procedure Delete(  --| Deletes an entry from the dictionary
  1442.             Template   : in Templates.Template_Name;
  1443.                            --| Type of template to delete
  1444.             Identifier : in Screen_String
  1445.                            --| Name of entry to delete
  1446.             );  --| Raises: Abort_Commands
  1447.  
  1448.         --| Effects: This procedure deletes a dictionary entry of type Template
  1449.         --| and with name Identifier from the dictionary.  If the entry is not
  1450.         --| found in the dictionary, an error message is given.  If there are 
  1451.         --| two or more entries in the dictionary with the same template type
  1452.         --| and identifier, a menu of all <overload> fields, which distinguish
  1453.         --| entries with the same name from one another is displayed and the
  1454.         --| user must select the appropriate entry.  Abort_Commands is raised 
  1455.         --| when an interrupt or end of file character is read.
  1456.  
  1457.         --| N/A: Requires, Modifies
  1458.  
  1459.         -----------------------------------------------------------------------
  1460.  
  1461.         procedure Show_Overloads(  --| Displays a menu of <overload>s
  1462.             Template   : in Templates.Template_Name;
  1463.                                    --| Template type to show
  1464.             Identifier : in Screen_String
  1465.                                    --| Dictionary entry to show
  1466.             ); --| Raises: Abort_Commands
  1467.  
  1468.         --| Effects: This procedure displays a menu of the <overload> fields
  1469.         --| for all templates of type Template and having name Identifier.
  1470.         --| If the entry is not found in the dictionary, an error message is 
  1471.         --| given.  The user does not have to make any choice from this menu 
  1472.         --| and may go back to editing by hitting the return key.  
  1473.         --| Abort_Commands is raised when an interrupt or end of file 
  1474.         --| character is read.
  1475.  
  1476.         --| N/A: Requires, Modifies
  1477.  
  1478.         -----------------------------------------------------------------------
  1479.  
  1480.         procedure Show_Commands;  --| Displays a list of commands
  1481.         --| Raises: Abort_Commands
  1482.  
  1483.         --| Effects: Displays a list of all the commands which are legal
  1484.         --| in the current context.  Abort_Commands is raised when an 
  1485.         --| interrupt or end of file character is read.
  1486.  
  1487.         --| N/A: Requires, Modifies
  1488.  
  1489.         -----------------------------------------------------------------------
  1490.  
  1491.         procedure Refresh;  --| Refreshes screen display
  1492.  
  1493.         --| Effects: Redraws the contents of the screen.
  1494.  
  1495.         --| N/A: Raises, Requires, Modifies
  1496.  
  1497.         -----------------------------------------------------------------------
  1498.  
  1499.         procedure Show_Help_Field;  --| Shows help associated with a field
  1500.  
  1501.         --| Effects: Displays the help associated with the current field.
  1502.  
  1503.         --| N/A: Raises, Requires, Modifies
  1504.  
  1505.         -----------------------------------------------------------------------
  1506.  
  1507.         procedure n_Lines(       --| Move a specified number of lines
  1508.             n : in Integer := 1  --| Number of lines to move
  1509.             );
  1510.  
  1511.         --| Effects: The first field on the line n lines from the current 
  1512.         --| field becomes the current field (and prompt).  If n is positive,
  1513.         --| the field is n lines after the current line; if n is negative, the
  1514.         --| field is n lines before the current line.  The furthest away that
  1515.         --| one may move with this command is the last line on the screen in
  1516.         --| the forward direction and the first line on the screen in the
  1517.         --| backward direction.
  1518.  
  1519.         --| Modifies: Current line, current field and prompt.
  1520.  
  1521.         --| N/A: Raises, Requires
  1522.  
  1523.         -----------------------------------------------------------------------
  1524.  
  1525.         procedure nth_Line(     --| Move to the specified line.
  1526.             n : in Integer      --| Line to move to.
  1527.             );
  1528.  
  1529.         --| Effects:  The first field on the nth line becomes the current 
  1530.         --| field (and prompt).  If n < 1, the first field on the first 
  1531.         --| line becomes the current field; if n > number of fields, the
  1532.         --| first field on the last line becomes the current field.
  1533.  
  1534.         --| Modifies: Current line, current field and prompt.
  1535.  
  1536.         --| N/A: Raises, Requires
  1537.  
  1538.         -----------------------------------------------------------------------
  1539.  
  1540.         procedure n_Fields(      --| Move a specified number of fields
  1541.             n : in Integer := 1  --| Number of fields to move
  1542.             );
  1543.  
  1544.         --| Effects: The field n fields from the current field becomes the
  1545.         --| current field (and prompt).  If n is positive, the field is n
  1546.         --| fields after the current field; if n is negative, the
  1547.         --| field is n fields before the current field.  The furthest away that
  1548.         --| one may move with this command is the last field on the screen in
  1549.         --| the forward direction and the first field on the screen in the
  1550.         --| backward direction.
  1551.  
  1552.         --| Modifies: Current line, current field and prompt.
  1553.  
  1554.         --| N/A: Raises, Requires
  1555.  
  1556.         -----------------------------------------------------------------------
  1557.  
  1558.         procedure nth_Field(    --| Move to the specified field.
  1559.             n : in Integer      --| Field to move to.
  1560.             );
  1561.  
  1562.         --| Effects:  The nth field becomes the current field (and prompt).
  1563.         --| If n < 1, the first field becomes the current field; if n > 
  1564.         --| number of fields, the last field becomes the current field.
  1565.  
  1566.         --| Modifies: Current line, current field and prompt.
  1567.  
  1568.         --| N/A: Raises, Requires
  1569.  
  1570.         -----------------------------------------------------------------------
  1571.  
  1572.         procedure Go_To_Field(            --| Move to the specified field.
  1573.             Fieldname : in Screen_String  --| Field to move to.
  1574.             );
  1575.  
  1576.         --| Effects:  The field with name Fieldname becomes the current field
  1577.         --| (and prompt).  If Fieldname doesn't exist in template, an error 
  1578.         --| message is given and current field doesn't change.
  1579.  
  1580.         --| Modifies: Current line, current field and prompt.
  1581.  
  1582.         --| N/A: Raises, Requires
  1583.  
  1584.         -----------------------------------------------------------------------
  1585.  
  1586.         procedure Insert_Text(       --| Enters text in current field
  1587.             Text : in Screen_String  --| Text to enter
  1588.             );
  1589.  
  1590.         --| Effects: Inserts Text into the current field.  The previous 
  1591.         --| contents of the field are overwritten.  A warning message is 
  1592.         --| given if text must be truncated in order to fit in the field.
  1593.  
  1594.         --| N/A: Raises, Requires, Modifies
  1595.  
  1596.         -----------------------------------------------------------------------
  1597.  
  1598.         procedure Substitute(             --| Substitutes a string for another
  1599.             From_Text : in Screen_String; --| old string
  1600.             To_Text   : in Screen_String  --| new string
  1601.             );
  1602.  
  1603.         --| Effects: Substitutes To_Text for From_Text in the current field.
  1604.         --| A warning message is given if the From_Text does not exist in
  1605.         --| the current field.  A warning message is given if new text would
  1606.         --| be too long too fit into the current field.
  1607.  
  1608.         --| N/A: Raises, Requires, Modifies
  1609.  
  1610.         -----------------------------------------------------------------------
  1611.  
  1612.         procedure Create;  --| Creates a dictionary entry from current template
  1613.  
  1614.         --| Effects: A new dictionary entry is created from the template on the
  1615.         --| screen.  If an entry with this name already exists, the <overload>
  1616.         --| field in the template must be filled out in order for the entry to
  1617.         --| be created.
  1618.  
  1619.         --| N/A: Raises, Requires, Modifies
  1620.  
  1621.         -----------------------------------------------------------------------
  1622.  
  1623.         procedure Update;  --| Updates a dictionary entry from current template
  1624.  
  1625.         --| Effects: Updates an entry in the dictionary.  For new entries this
  1626.         --| command has the same effect as Create.
  1627.  
  1628.         --| N/A: Raises, Requires, Modifies
  1629.  
  1630.         -----------------------------------------------------------------------
  1631.  
  1632.         procedure Exit_Editor;  --| Exits from the editor
  1633.         --| Raises: Abort_Commands
  1634.  
  1635.         --| Effects: Repositions the cursor at the bottom of the screen and
  1636.         --| exits.  Abort_Commands is raised when an interrupt or end of file
  1637.         --| character is read.
  1638.  
  1639.         --| N/A: Requires, Modifies
  1640.  
  1641.         -----------------------------------------------------------------------
  1642.  
  1643.     end Editing_Commands;
  1644.  
  1645.     ---------------------------------------------------------------------------
  1646.  
  1647. end Commands; 
  1648.  
  1649. -------------------------------------------------------------------------------
  1650.  
  1651. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1652. --UPDATE.SPC
  1653. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1654. -------------------------------------------------------------------------------
  1655. package Update is  --| Update command processor
  1656.  
  1657.     -- Exceptions
  1658.  
  1659.     Abort_Update : exception; --| Raised when error occurred opening any files
  1660.  
  1661.     -- Operations
  1662.  
  1663.     procedure Process_Update_Commands(  --| Processes all update commands
  1664.         Dictionary_Name   : String;     --| Name of dictionary
  1665.         Command_File_Name : String      --| File of update commands
  1666.         );
  1667.  
  1668.     --| Effects: Reads Command_File and processes update commands.  Commands
  1669.     --| are create, update and delete.  
  1670.     --|
  1671.     --| delete template-type identifier
  1672.     --| {create, update} template-type identifier
  1673.     --| <fieldname>contents
  1674.     --| <fieldname>contents
  1675.     --| etc.
  1676.     --|
  1677.     --| for example:
  1678.     --| create function foo
  1679.     --| <type>bar
  1680.     --| <overload>explanation
  1681.  
  1682.     -- Exceptions
  1683.  
  1684.     Command_File_Error : exception; --| Error occurred while opening command 
  1685.                                     --| file
  1686.  
  1687.     ---------------------------------------------------------------------------
  1688.  
  1689. end Update;
  1690.  
  1691. -------------------------------------------------------------------------------
  1692. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1693. --COMMANDS.BDY
  1694. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  1695. with Terminal_IO;
  1696. with Dictionary_Manager;
  1697. with Screen_Manager;
  1698. with String_Utilities;
  1699.  
  1700. -------------------------------------------------------------------------------
  1701.  
  1702. package body Commands is 
  1703. --| Provide procedures to process all interactive commands.
  1704.  
  1705. --| Overview
  1706. --|
  1707. --| This package provides procedures to process all of the interactive 
  1708. --| commands.  Nested package Editing_Commands contains all of the subprograms
  1709. --| for processing the commands once they are parsed.  Procedure
  1710. --| Process_Commands opens the dictionary, processes editor commands and calls 
  1711. --| Interpret_Command, and closes the dictionary.  Procedure Interpret_Command 
  1712. --| parses the command and calls the appropriate procedure in the nested 
  1713. --| package Editing_Commands.
  1714.  
  1715.     ---------------------------------------------------------------------------
  1716.     -----------------------------Local Declarations----------------------------
  1717.  
  1718.     package TIO renames Terminal_IO;
  1719.     package DM  renames Dictionary_Manager;
  1720.     package EC  renames Editing_Commands;
  1721.     package SM  renames Screen_Manager;
  1722.     package SS  renames Screen_Strings;
  1723.     package SU  renames String_Utilities;
  1724.     package TP  renames Templates;
  1725.  
  1726.     package Screen_String_Utilities is new SU.Generic_String_Utilities(
  1727.        Generic_String_Type => SS.Screen_String,
  1728.        To_Generic => SS.Unchecked_Create,
  1729.        From_Generic => SS.Value);
  1730.  
  1731.     package SSU renames Screen_String_Utilities;
  1732.  
  1733.     Command_List : SM.Screen_Array := (
  1734.         SS.Create("ED[IT] template-type [identifier] - edit dictionary entry"), 
  1735.         SS.Create("D[ELETE] template-type identifier - delete dictionary entry"), 
  1736.         SS.Create("S[HOW] template-type identifier   - show overloads for dictionary entry"),
  1737.         SS.Create("CO[MMANDS]                        - show command list"),
  1738.         SS.Create("R[EFRESH]                         - refresh the screen"), 
  1739.         SS.Create("H[ELP]                            - help for field"), 
  1740.         SS.Create("+nL[INES]                         - go down n lines"), 
  1741.         SS.Create("-nL[INES]                         - go up n lines"), 
  1742.         SS.Create("nL[INE]                           - go to nth line"),
  1743.         SS.Create("+n[FIELDS]                        - go down n fields"), 
  1744.         SS.Create("-n[FIELDS]                        - go up n fields"), 
  1745.         SS.Create("nF[IELD]                          - go to nth field"),
  1746.         SS.Create("<fieldname>                       - go to field named 'fieldname'"),
  1747.         SS.Create("&text                             - insert 'text'"), 
  1748.         SS.Create("/oldstring/newstring[/]           - replace 'oldstring' with 'newstring'"),
  1749.         SS.Create("CR[EATE]                          - create new entry in dictionary"), 
  1750.         SS.Create("U[PDATE]                          - update existing entry in dictionary"),
  1751.         SS.Create("EX[IT]                            - exit editor"),
  1752.         SS.Create(""),
  1753.         SS.Create("Available templates are: OBJECT_DECL, TYPE_DECL, PROCEDURE_DECL,"),
  1754.         SS.Create("FUNCTION_DECL, TASK_DECL, EXCEPTION_DECL"),
  1755.         SS.Create(""), others => SS.Create(""));
  1756.         -- work around DEC compiler bug with "when others =>"
  1757.   
  1758.     type Abort_Code_Name is (End_of_File_Condition, Interrupt_Condition);
  1759.     --| what type of signal was received, causing an abort
  1760.  
  1761.     Exit_Found           : Boolean := False;  --| Whether exit command was
  1762.                                               --| entered
  1763.     Current_Template     : TP.Template_Name;  --| Template being edited
  1764.     Current_Handle       : DM.Dictionary_Entry_Handle; 
  1765.                                               --| Handle of entry being edited
  1766.     Current_Field        : TP.Variable_Field_Number_Range := 1;
  1767.                                               --| Current field being edited
  1768.     Prompt_Line          : SS.Screen_String := SS.Create("");
  1769.                                               --| Current contents of prompt
  1770.     Modified_Template    : Boolean := False;  --| Whether any changes have 
  1771.                                               --| been made to current entry
  1772.  
  1773.     -- Character constants
  1774.  
  1775.     Plus_Key             : constant Character := '+';  --| Forward key
  1776.     Minus_Key            : constant Character := '-';  --| Backward key
  1777.     Open_Fieldname_Key   : constant Character := '<';  --| Start of fieldname 
  1778.                                                        --| symbol
  1779.     Close_Fieldname_Key  : constant Character := '>';  --| End of fieldname 
  1780.                                                        --| symbol
  1781.     Insert_Key           : constant Character := '&';  --| Insert text command
  1782.     Substitute_Delimiter : constant Character := '/';  --| Substitute command
  1783.     Escape_Character     : constant Character := ''';  --| Substitute command 
  1784.                                                        --| escape character
  1785.  
  1786.     ---------------------------------------------------------------------------
  1787.  
  1788.     --  Exceptions
  1789.  
  1790.     Nonexistent_Command  : exception;  --| Raised when command entered is not 
  1791.                                        --| one of the editor commands
  1792.     Ambiguous_Command    : exception;  --| Raised when command does not 
  1793.                                        --| uniquely match an editor command
  1794.     Too_Many_Parameters  : exception;  --| Raised when command line contains 
  1795.                                        --| characters in addition to command 
  1796.                                        --| and appropriate number of parameters
  1797.     Missing_Nth_Line_or_Field_Command  --| Raised when line or field
  1798.                          : exception;  --| command is not entered
  1799.     Missing_Fieldname    : exception;  --| Raised when fieldname is not entered
  1800.     Incomplete_Fieldname : exception;  --| Raised when Close_Fieldname_Key is 
  1801.                                        --| missing
  1802.     Missing_Old_String   : exception;  --| Raised when oldstring is not entered
  1803.     Incomplete_Substitution            --| Raised when Substitute_Delimiter
  1804.                          : exception;  --| between old and new strings is
  1805.                                        --| missing
  1806.     Invalid_Escape_Sequence            --| Raised when the Escape_Character is 
  1807.                          : exception;  --| not typed in conjunction with itself
  1808.                                        --| or the Substitute_Delimiter
  1809.     Invalid_Substitute_Delimiter       --| Raised when Substitute_Delimiter
  1810.                          : exception;  --| not in appropriate location
  1811.     Missing_Template_Type              --| Raised when a command which requires
  1812.                          : exception;  --| template parameter is missing it
  1813.     Invalid_Template_Type              --| Raised when specified template_type
  1814.                          : exception;  --| doesn't exist
  1815.     Missing_Identifier   : exception;  --| Raised when command which requires
  1816.                                        --| identifier parameter is missing it
  1817.     Not_In_Dictionary    : exception;  --| Raised when dictionary entry 
  1818.                                        --| (Template, Identifier) doesn't exist
  1819.     Fieldname_Not_In_Template          --| Raised when specified fieldname does
  1820.                          : exception;  --| not exist in current template
  1821.     No_Oldstring_Match   : exception;  --| Raised when substitution oldstring 
  1822.                                        --| does not exist in template field
  1823.     Too_Long_For_Field   : exception;  --| Raised when substitution newstring
  1824.                                        --| would not fit in current field
  1825.     Internal_Error       : exception;  --| Raised in case statement for
  1826.                                        --| 'when others' which should never
  1827.                                        --| execute
  1828.     ---------------------------------------------------------------------------
  1829.     -----------------------Local Subprogram Specifications---------------------
  1830.  
  1831.     procedure Abort_Editor(            --| Stops processing of editing commands
  1832.          Abort_Code : Abort_Code_Name  --| What caused processing to abort
  1833.          );  --| Raises: Abort_Commands 
  1834.  
  1835.     --| Effects:  The dictionary is closed and an error message is printed.
  1836.     --| The text of the error message is determined by the Abort_Code.
  1837.     --| Abort_Commands is always raised.
  1838.  
  1839.     --| N/A: Requires, Modifies
  1840.  
  1841.     ---------------------------------------------------------------------------
  1842.  
  1843.     procedure Interpret_Command(     --| Parses In_Text; returns command name
  1844.          In_Text : in Screen_String  --| Command to parse
  1845.          );
  1846.  
  1847.     --| Effects:  This procedure parses In_Text and calls the appropriate
  1848.     --| command routine in nested package Editing_Commands.
  1849.  
  1850.     --| N/A: Raises, Requires, Modifies
  1851.  
  1852.     ---------------------------------------------------------------------------
  1853.  
  1854.     procedure Parse_n_Lines_or_Fields(  --| Parses for number and command and
  1855.                                         --| calls either n_Fields or n_Lines 
  1856.          Text_Scanner : in SU.Scanner   --| Command to parse
  1857.          );  --| Raises: Too_Many_Parameters, Nonexistent_Command
  1858.  
  1859.     --| Effects: Parses Text_Scanner for number and command (lines/fields) 
  1860.     --| and calls either n_Fields or n_Lines.  The acceptable formats for the
  1861.     --| Move n Fields or Lines commands are as follows, where brackets denote
  1862.     --| optional parts:  +nF[IELDS] , -nF[IELDS] , +nL[INES] , -nL[INES] .
  1863.     --| Too_Many_Parameters is raised if command line contains characters 
  1864.     --| after lines/fields command.  Nonexistent_Command is raised if 
  1865.     --| command after n is not either lines or fields command.  
  1866.  
  1867.     --| N/A: Requires, Modifies
  1868.  
  1869.     ---------------------------------------------------------------------------
  1870.  
  1871.     procedure Parse_nth_Line_or_Field(  --| Parses for number and command,
  1872.                                         --| calls either nth_Field or nth_Line
  1873.          Text_Scanner : in SU.Scanner   --| Command to parse
  1874.          );  --| Raises: Missing_Nth_Line_or_Field_Command, 
  1875.              --|         Too_Many_Parameters, Nonexistent_Command
  1876.  
  1877.     --| Effects: Parses Text_Scanner for number and command (line/field) 
  1878.     --| and calls either nth_Field or nth_Line.  The acceptable formats for the
  1879.     --| Go to nth Field or Line commands are as follows, where brackets denote
  1880.     --| optional parts: nL[INE] , nF[IELD] .  Missing_Nth_Line_or_Field_Command
  1881.     --| is raised if line/field command is not entered.  Too_Many_Parameters 
  1882.     --| is raised if command line contains characters after line/field command
  1883.     --| Nonexistent_Command is raised if command is not either line or field 
  1884.     --| command.  
  1885.  
  1886.     --| N/A: Requires, Modifies
  1887.  
  1888.     ---------------------------------------------------------------------------
  1889.  
  1890.     procedure Parse_Fieldname(         --| Parses Text for fieldname, calls 
  1891.                                        --| Go_to_Field 
  1892.          Text_Scanner : in SU.Scanner  --| Command to parse
  1893.          );  --| Raises: Incomplete_Fieldname, Missing_Fieldname,
  1894.              --| Too_Many_Parameters
  1895.  
  1896.     --| Effects: Parses Text_Scanner for parameter (fieldname) and calls
  1897.     --| Go_to_Field.  The acceptable format for the Go to Fieldname command is
  1898.     --| as follows : <fieldname> .  Incomplete_Fieldname is raised if 
  1899.     --| Close_Fieldname_Key is missing.  Missing_Fieldname is raised if 
  1900.     --| fieldname is not entered.  Too_Many_Parameters is raised if command 
  1901.     --| line contains characters after Close_Fieldname_Key (>).
  1902.  
  1903.     --| N/A: Requires, Modifies
  1904.  
  1905.     ---------------------------------------------------------------------------
  1906.  
  1907.     procedure Parse_Insert(             --| Parses for text to insert, 
  1908.                                         --| calls Insert_Text 
  1909.          Text_Scanner : in SU.Scanner   --| Command to parse
  1910.          );
  1911.  
  1912.     --| Effects: Parses Text_Scanner for parameter (text to insert) 
  1913.     --| and calls Insert_Text.  The acceptable format for the Insert Text 
  1914.     --| command is as follows : &text .
  1915.      
  1916.     --| N/A: Requires, Modifies
  1917.  
  1918.     ---------------------------------------------------------------------------
  1919.  
  1920.     procedure Get_Substitution_String(
  1921.          Text_Scanner : in     SU.Scanner;  --| Command to parse
  1922.          Delimiter    : in     Character;   --| Substitution delimiter
  1923.          Escape       : in     Character;   --| Escape character
  1924.          Result       : in out SS.Screen_String;
  1925.                                             --| Substitution string
  1926.          End_of_Line  :    out Boolean      --| Signals end of line
  1927.          );  --| Raises: Invalid_Substitute_Delimiter, Invalid_Escape_Sequence
  1928.  
  1929.     --| Effects: Parses Text_Scanner for string and checks for presence 
  1930.     --| of escape character (''') turning delimiter ('/') and escape into 
  1931.     --| literals. Invalid_Substitute_Delimiter is raised if 
  1932.     --| Substitute_Delimiter not in appropriate location.
  1933.     --| Invalid_Escape_Sequence is raised if the Escape_Character is not
  1934.     --| typed in conjunction with itself or the Substitute_Delimiter.
  1935.  
  1936.     --| N/A: Requires, Modifies
  1937.  
  1938.     ---------------------------------------------------------------------------
  1939.  
  1940.     procedure Parse_Substitute(        --| Parses Text for oldstring and
  1941.                                        --| newstring and calls Substitute 
  1942.          Text_Scanner : in SU.Scanner  --| Command to parse
  1943.          );  --| Raises: Missing_Old_String, Incomplete_Substitution,
  1944.              --|         Too_Many_Parameters
  1945.  
  1946.     --| Effects: Parses Text_Scanner for parameters (oldstring, newstring)
  1947.     --| and calls Substitute.  The acceptable format for the Substitution
  1948.     --| command is as follows, where brackets denote optional parts:
  1949.     --| /oldstring/newstring[/] .  Missing_Old_String is raised if oldstring
  1950.     --| is not entered.  Incomplete_Substitution is raised if the delimiter
  1951.     --| between old and new strings is missing. Too_Many_Parameters is raised
  1952.     --| if command line contains characters after closing delimiter.
  1953.  
  1954.     --| N/A: Requires, Modifies
  1955.  
  1956.     ---------------------------------------------------------------------------
  1957.  
  1958.     procedure Parse_Alphabetic_Commands(  --| Parses Text for command and
  1959.                                           --| parameters and calls appropriate
  1960.                                           --| procedure
  1961.          Text_Scanner : in SU.Scanner     --| Command to parse
  1962.          );  --| Raises: Ambiguous_Command, Nonexistent_Command,
  1963.              --|         Too_Many_Parameters, Missing_Template_Type,
  1964.              --|         Invalid_Template_Type, Missing_Identifier
  1965.  
  1966.     --| Effects:  Parses Text_Scanner for command and parameters and calls 
  1967.     --| appropriate procedure.  The following are the acceptable formats for
  1968.     --| the alphabetic commands, where brackets denote optional parts:  
  1969.     --| CO[MMANDS],
  1970.     --| ED[IT] template-type [identifier] , D[ELETE] template-type identifier ,
  1971.     --| S[HOW] template-type identifier , R[EFRESH] , H[ELP] , CR[EATE] ,
  1972.     --| U[PDATE] , EX[IT] .  Ambiguous_Command is raised if specified command
  1973.     --| does not uniquely match one of array of editor commands.
  1974.     --| Nonexistent_Command is raised if command is not one of acceptable
  1975.     --| editor commands.  Missing_Template_Type is raised if Delete, Edit, or
  1976.     --| Show commands are typed without any parameters.  Missing_Identifier
  1977.     --| is raised if Delete or Show commands are typed without a second
  1978.     --| parameter.  Too_Many_Parameters is raised if the command line contains 
  1979.     --| characters after command and parameters.
  1980.  
  1981.     --| N/A: Requires, Modifies
  1982.  
  1983.     ---------------------------------------------------------------------------
  1984.  
  1985.     function Identifier_Text(     --| Checks text about to be inserted to 
  1986.                                   --| identifier field
  1987.          Text : SS.Screen_String  --| Text to be checked
  1988.          ) return SS.Screen_String;
  1989.  
  1990.     --| Effects: Text is checked to ensure that it is only one word long.
  1991.     --| If it is more than one word long, an error message is printed and
  1992.     --| the first word in the Text is returned.  Otherwise, Text is returned.
  1993.  
  1994.     --| N/A: Raises, Requires, Modifies
  1995.  
  1996.     ---------------------------------------------------------------------------
  1997.     -----------------------External Subprogram Bodies--------------------------
  1998.  
  1999.     procedure Process_Commands(  
  2000.          Dictionary_Name : in String;        --| Name of dictionary
  2001.          Template        : in Templates.Template_Name;  
  2002.                                              --| Type of template to edit
  2003.          Identifier      : in SS.Screen_String := SS.Create("")
  2004.                                              --| Name of dictionary entry
  2005.          ) is
  2006.  
  2007.          Command_Line : Screen_String;  --| Command_Line read from terminal
  2008.          Truncated    : Boolean;        --| whether or not a screen string was
  2009.                                         --| truncated on create.
  2010.  
  2011.     begin
  2012.  
  2013.           DM.Open_Dictionary(Dictionary_Name);
  2014.           TIO.Set_Cursor(1, 1);
  2015.           TIO.Clear_Screen;
  2016.  
  2017.        -- call edit with command line parameters
  2018.           EC.Edit(Template, Identifier);
  2019.           Exit_Found := False;
  2020.           while not Exit_Found loop
  2021.  
  2022.                begin
  2023.                     SS.Create(TIO.Read, Command_Line, Truncated);
  2024.                exception
  2025.                     when TIO.End_of_File_Error =>
  2026.                          Abort_Editor(End_of_File_Condition);
  2027.                end;
  2028.  
  2029.                if Truncated then
  2030.                     SM.Display_Message(
  2031.                          SS.Create("Text was truncated"), 
  2032.                          SM.Warning);
  2033.                end if;
  2034.                SM.Clear_Message_Line;
  2035.  
  2036.             -- interpret command line
  2037.                Interpret_Command(Command_Line);
  2038.  
  2039.             -- scroll the prompt lines
  2040.                if not Exit_Found then
  2041.                     SM.Scroll_Prompt_Lines(Command_Line);
  2042.                end if;
  2043.  
  2044.           end loop;
  2045.           DM.Close_Dictionary;
  2046.  
  2047.     end Process_Commands;
  2048.  
  2049.     ---------------------------------------------------------------------------
  2050.  
  2051.     package body Editing_Commands is
  2052.  
  2053.         procedure Edit(          --| Displays template for editing
  2054.              Template   : in Templates.Template_Name;
  2055.                                  --| Type of template to edit
  2056.              Identifier : in SS.Screen_String := SS.Create("")
  2057.                                  --| Name of dictionary entry
  2058.              ) is
  2059.  
  2060.              Choice        : SS.Screen_String   --| Menu choice
  2061.                   := SS.Create("");
  2062.              Truncated     : Boolean;           --| whether screen_string was
  2063.                                                 --| truncated on a create
  2064.              Occurrence    : Integer := 1;      --| which overload of template
  2065.                                                 --| + identifier
  2066.              Dummy         : SS.Screen_String;
  2067.  
  2068.         begin
  2069.  
  2070.           -- If template has been modified by insert or substitute, prompt
  2071.           -- user to save changes before executing edit command
  2072.              if Modified_Template then
  2073.  
  2074.                   while (SS.Length(Choice) /= 1) or else
  2075.                        not (SS.Equal(Choice, "n") or SS.Equal(Choice, "N") or 
  2076.                             SS.Equal(Choice, "y") or SS.Equal(Choice, "Y") or
  2077.                             SS.Equal(Choice, "*")) loop
  2078.                        SM.Display_Message(
  2079.                             SS.Create("Template has been modified"), 
  2080.                             SM.Warning);
  2081.                        SM.Display_Secondary_Prompt(
  2082.                             SS.Create("Save? (y, n, * to abort) : "));
  2083.  
  2084.                        begin
  2085.                             Choice := SS.Unchecked_Create(TIO.Read);
  2086.                        exception
  2087.                             when TIO.End_of_File_Error =>
  2088.                                  Abort_Editor(End_of_File_Condition);
  2089.                        end;
  2090.  
  2091.                        Choice := SSU.Strip_Leading(Choice);
  2092.                        Choice := SSU.Strip_Trailing(Choice);
  2093.                   end loop;
  2094.  
  2095.                -- legal choices are n, N, y, Y, *
  2096.                   case SS.Value(Choice)(1) is
  2097.                        when 'n' | 'N' => SM.Clear_Message_Line;
  2098.                        when 'y' | 'Y' => 
  2099.  
  2100.                        begin
  2101.  
  2102.                          -- try to use update to save the changes.  If it fails
  2103.                          -- because entry doesn't already exist (and therefore
  2104.                          -- not "updatable", then create instead.)
  2105.                             EC.Update;
  2106.                             SM.Display_Secondary_Prompt(
  2107.                                  SS.Create("--Press return to continue--"));
  2108.                             begin
  2109.                                  Dummy := SS.Unchecked_Create(TIO.Read);
  2110.                             exception
  2111.                                  when TIO.End_of_File_Error =>
  2112.                                       Abort_Editor(End_of_File_Condition);
  2113.                             end;
  2114.  
  2115.                        exception
  2116.                             when DM.Cant_Update_New_Entry =>
  2117.                                  EC.Create;
  2118.                                  SM.Display_Secondary_Prompt(SS.Create(
  2119.                                       "--Press return to continue--"));
  2120.                                  begin
  2121.                                       Dummy := SS.Unchecked_Create(TIO.Read);
  2122.                                  exception
  2123.                                       when TIO.End_of_File_Error =>
  2124.                                            Abort_Editor(End_of_File_Condition);
  2125.                                  end;
  2126.                        end;
  2127.  
  2128.                        when '*' => 
  2129.  
  2130.                          -- abort the edit command
  2131.                             SM.Clear_Message_Line;
  2132.                             return;
  2133.                        when others => raise Internal_Error;
  2134.                   end case;
  2135.    
  2136.              end if; 
  2137.    
  2138.              Current_Field := 1;
  2139.              Current_Template := Template;
  2140.              if not DM.Entry_Exists(Template, Identifier) then
  2141.    
  2142.                -- if it's not found, put up blank template of type Template
  2143.                   SM.Display_Blank_Template(Template);
  2144.    
  2145.                   if not SS.Equal(Identifier, "") then
  2146.                        SM.Display_Message(
  2147.                             SS.Unchecked_Create(
  2148.                                  SS.Value(Identifier) & 
  2149.                                  " not found.  (New Template)"),
  2150.                             SM.Warning);
  2151.                        Current_Handle := DM.New_Entry_Handle(Template);
  2152.    
  2153.                     -- fill in identifier field with specified identifier
  2154.                        DM.Update_Field(
  2155.                             Current_Handle, Current_Field, Identifier);
  2156.                        SM.Display_Field(
  2157.                             Current_Handle, 
  2158.                             TP.Actual_Field_Number(Template, Current_Field));
  2159.    
  2160.                     -- set Modified_Template, since specifying a new identifier
  2161.                     -- is a modification
  2162.                        Modified_Template := True;
  2163.                   else
  2164.                        SM.Display_Message(
  2165.                             SS.Create("New Template"), SM.Warning);
  2166.                        Current_Handle := DM.New_Entry_Handle(Template);
  2167.                   end if;
  2168.  
  2169.              else
  2170.    
  2171.                -- if Template + Identifier exists in the dictionary but isn't 
  2172.                -- unique, display a menu of choices
  2173.                   if not DM.Unique_Entry(Template, Identifier) then
  2174.    
  2175.                        SM.Display_Menu(
  2176.                             DM.Overloads(Template, Identifier), SM.Prompt,
  2177.                             Template, Identifier);
  2178.                        loop
  2179.    
  2180.                          -- Get menu choice
  2181.                             SM.Display_Prompt(
  2182.                                  SS.Create("Enter choice: "),
  2183.                                  Field_Prompt => False);
  2184.    
  2185.                             begin
  2186.                                  SS.Create(TIO.Read, Choice, Truncated);
  2187.                             exception
  2188.                                  when TIO.End_of_File_Error =>
  2189.                                       Abort_Editor(End_of_File_Condition);
  2190.                             end;
  2191.    
  2192.                             SM.Clear_Message_Line;
  2193.                             if Truncated then
  2194.                                  SM.Display_Message(
  2195.                                       SS.Create("Text was truncated"), 
  2196.                                       SM.Warning);
  2197.                             end if;
  2198.    
  2199.                             begin
  2200.                                  Occurrence := Integer'Value(SS.Value(Choice));
  2201.                             exception
  2202.                                   when Constraint_Error => 
  2203.                                        Occurrence := DM.Overload_Range'Last + 1;
  2204.                             end;
  2205.    
  2206.                             if Occurrence not in DM.Overload_Range then
  2207.                                   SM.Display_Message(
  2208.                                        SS.Create("Invalid menu choice"), 
  2209.                                        SM.Warning);
  2210.                             end if;
  2211.                             exit when Occurrence in DM.Overload_Range;
  2212.                        end loop;
  2213.    
  2214.                   end if;
  2215.    
  2216.                -- set Modified_Template to False, since the new template 
  2217.                -- hasn't been modified yet
  2218.                   Modified_Template := False;
  2219.                   SM.Clear_Message_Line;
  2220.                   Current_Handle := 
  2221.                        DM.Entry_Handle(Template, Identifier, Occurrence);
  2222.                   SM.Display_Filled_Template(Current_Handle);
  2223.    
  2224.              end if;
  2225.    
  2226.              Prompt_Line := 
  2227.                   TP.Field_Label(Template, TP.Actual_Field_Number(Template, 1));
  2228.              SM.Display_Prompt(Prompt_Line);
  2229.    
  2230.         end Edit;
  2231.  
  2232.         -----------------------------------------------------------------------
  2233.  
  2234.         procedure Delete(            --| Deletes an entry from the dictionary
  2235.  
  2236.              Template   : in Templates.Template_Name; 
  2237.                                                --| Type of template to delete
  2238.              Identifier : in SS.Screen_String  --| Name of entry to delete
  2239.              ) is
  2240.  
  2241.              Choice     : SS.Screen_String  --| menu choice
  2242.                   := SS.Create("");  
  2243.              Truncated  : Boolean;          --| whether or not screen string
  2244.                                             --| was truncated on create
  2245.              Occurrence : Integer := 1;     --| which occurrence of Template +
  2246.                                             --| Identifier
  2247.  
  2248.         begin
  2249.  
  2250.              if not DM.Entry_Exists(Template, Identifier) then
  2251.                   raise Not_In_Dictionary;
  2252.              end if;
  2253.    
  2254.              if not DM.Unique_Entry(Template, Identifier) then
  2255.                   SM.Display_Menu(DM.Overloads(Template, Identifier), 
  2256.                        SM.Prompt, Template, Identifier);
  2257.    
  2258.                   loop
  2259.    
  2260.                     -- Get menu choice
  2261.                        SM.Display_Prompt(
  2262.                             SS.Create("Enter choice (* to abort): "), 
  2263.                             Field_Prompt => False);
  2264.    
  2265.                        begin
  2266.                             SS.Create(TIO.Read, Choice, Truncated);
  2267.                        exception
  2268.                             when TIO.End_of_File_Error =>
  2269.                                  Abort_Editor(End_of_File_Condition);
  2270.                        end;
  2271.    
  2272.                        Choice := SSU.Strip_Leading(Choice);
  2273.                        Choice := SSU.Strip_Trailing(Choice);
  2274.                        SM.Clear_Message_Line;
  2275.                        if Truncated then
  2276.                             SM.Display_Message(
  2277.                                  SS.Create("Text was truncated"), 
  2278.                                  SM.Warning);
  2279.                        end if;
  2280.    
  2281.                        if SS.Value(Choice) /= "*" then
  2282.                             begin
  2283.                                  Occurrence := Integer'Value(SS.Value(Choice));
  2284.                             exception
  2285.                                  when Constraint_Error => 
  2286.                                       Occurrence := DM.Overload_Range'Last + 1;
  2287.                             end;
  2288.    
  2289.                             if Occurrence not in DM.Overload_Range then
  2290.                                  SM.Display_Message(
  2291.                                       SS.Create("Invalid menu choice"), 
  2292.                                       SM.Warning);
  2293.                             end if;
  2294.                        end if;
  2295.                        exit when (Occurrence in DM.Overload_Range) or 
  2296.                             SS.Value(Choice) = "*";
  2297.                   end loop;
  2298.    
  2299.                   SM.Display_Filled_Template(Current_Handle);
  2300.              end if;
  2301.    
  2302.              if SS.Value(Choice) = "*" then
  2303.                   SM.Display_Message(
  2304.                        SS.Unchecked_Create(
  2305.                             SS.Value(TP.Template_Label(Template)) & 
  2306.                             " " &
  2307.                             SS.Value(Identifier) & 
  2308.                             " was not deleted"),
  2309.                        SM.Info);
  2310.              else
  2311.                   DM.Delete_Entry(
  2312.                        DM.Entry_Handle(Template, Identifier, Occurrence));
  2313.              end if;
  2314.    
  2315.         exception
  2316.    
  2317.                when Not_In_Dictionary => SM.Display_Message(
  2318.                     SS.Unchecked_Create(
  2319.                          SS.Value(TP.Template_Label(Template)) & 
  2320.                          " " & 
  2321.                          SS.Value(Identifier) & 
  2322.                          " not in dictionary"),
  2323.                     SM.Error);
  2324.    
  2325.         end Delete;
  2326.    
  2327.         -----------------------------------------------------------------------
  2328.  
  2329.         procedure Show_Overloads(             --| Displays menu of <overload>s
  2330.  
  2331.              Template   : in Templates.Template_Name;
  2332.                                                --| Template type to show
  2333.              Identifier : in SS.Screen_String  --| Dictionary entry to show
  2334.              ) is
  2335.  
  2336.              Dummy     : SS.Screen_String;
  2337.  
  2338.         begin
  2339.  
  2340.              if not DM.Entry_Exists(Template, Identifier) then
  2341.                   raise Not_In_Dictionary;
  2342.              end if;
  2343.              SM.Display_Menu(
  2344.                   DM.Overloads(Template, Identifier), 
  2345.                   SM.Continue, Template, Identifier);
  2346.    
  2347.              begin
  2348.                   Dummy := SS.Unchecked_Create(TIO.Read);
  2349.              exception
  2350.                   when TIO.End_of_File_Error =>
  2351.                        Abort_Editor(End_of_File_Condition);
  2352.              end;
  2353.    
  2354.              SM.Display_Filled_Template(Current_Handle);
  2355.    
  2356.         exception
  2357.  
  2358.              when Not_In_Dictionary => SM.Display_Message(
  2359.                   SS.Unchecked_Create(
  2360.                        SS.Value(TP.Template_Label(Template)) & 
  2361.                        " " & 
  2362.                        SS.Value(Identifier) & 
  2363.                        " not in dictionary"),
  2364.                   SM.Error);
  2365.  
  2366.         end Show_Overloads;
  2367.  
  2368.         -----------------------------------------------------------------------
  2369.  
  2370.         procedure Show_Commands is
  2371.  
  2372.         --| Displays a list of commands
  2373.  
  2374.              Dummy     : SS.Screen_String;
  2375.  
  2376.         begin
  2377.  
  2378.              SM.Display_Command_List(Command_List);  
  2379.  
  2380.              begin
  2381.                   Dummy := SS.Unchecked_Create(TIO.Read);
  2382.              exception
  2383.                   when TIO.End_of_File_Error =>
  2384.                        Abort_Editor(End_of_File_Condition);
  2385.              end;
  2386.    
  2387.              SM.Display_Filled_Template(Current_Handle);
  2388.  
  2389.         end Show_Commands;
  2390.  
  2391.         -----------------------------------------------------------------------
  2392.  
  2393.         procedure Refresh is
  2394.  
  2395.         --| Refreshes screen display
  2396.  
  2397.         begin
  2398.  
  2399.              SM.Display_Filled_Template(Current_Handle);
  2400.  
  2401.         end Refresh;
  2402.  
  2403.         -----------------------------------------------------------------------
  2404.  
  2405.         procedure Show_Help_Field is
  2406.  
  2407.         --| Shows help associated with a field
  2408.         
  2409.         begin
  2410.  
  2411.              SM.Display_Message(
  2412.                   TP.Field_Help(Current_Template, Current_Field), 
  2413.                   SM.Help);
  2414.    
  2415.         end Show_Help_Field;
  2416.  
  2417.         -----------------------------------------------------------------------
  2418.  
  2419.         procedure n_Lines(          --| Move a specified number of lines
  2420.              n : in Integer := 1    --| Number of lines to move
  2421.              ) is
  2422.  
  2423.              First_Field              : constant TP.Variable_Field_Number_Range
  2424.              --| First (variable) field in the template
  2425.                   := 1;
  2426.  
  2427.              First_Field_on_Last_Line : constant TP.Variable_Field_Number_Range
  2428.              --| First (variable) field on the last line
  2429.                   := TP.First_Variable_Field_Number(
  2430.                        Current_Template,
  2431.                        TP.Field_Position(
  2432.                             Current_Template,
  2433.                             TP.Actual_Field_Number(
  2434.                                  Current_Template,
  2435.                                  TP.Variable_Field_Count(
  2436.                                       Current_Template))).Line);
  2437.  
  2438.              Current_Line             : Positive
  2439.              --| Line where current field is
  2440.                   := TP.Field_Position(
  2441.                       Current_Template,
  2442.                       TP.Actual_Field_Number(
  2443.                            Current_Template, Current_Field)).Line;
  2444.  
  2445.         begin
  2446.  
  2447.           -- If number of lines to move forward is outside bounds of template,
  2448.           -- go to first field on the last line
  2449.              if (Current_Line + n) > 
  2450.                   TP.Field_Position(
  2451.                        Current_Template,
  2452.                        TP.Actual_Field_Number(
  2453.                             Current_Template, First_Field_on_Last_Line)).Line 
  2454.                   then
  2455.                   Current_Field := First_Field_on_Last_Line;
  2456.    
  2457.           -- If number of lines to move back is outside bounds of template, go
  2458.           -- to the first field in the template
  2459.              elsif (Current_Line + n) <
  2460.                   TP.Field_Position(
  2461.                        Current_Template,
  2462.                        TP.Actual_Field_Number(
  2463.                             Current_Template, First_Field)).Line then
  2464.                   Current_Field := First_Field;
  2465.    
  2466.           -- If number of lines to move forward or back is within bounds of 
  2467.           -- template, go to Current_Line + n (or the next line containing
  2468.           -- a variable field)
  2469.              else
  2470.                   for i in First_Field .. First_Field_on_Last_Line loop
  2471.                        if TP.Field_Position(
  2472.                             Current_Template, 
  2473.                             TP.Actual_Field_Number(Current_Template, i)).Line >=
  2474.                             (Current_Line + n) then
  2475.                             Current_Field := i;
  2476.                             exit;
  2477.                        end if;
  2478.                   end loop;
  2479.              end if;
  2480.      
  2481.           -- Set prompt to current_field
  2482.              Prompt_Line := TP.Field_Label(
  2483.                   Current_Template,
  2484.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2485.              SM.Display_Prompt(Prompt_Line);
  2486.    
  2487.         end n_Lines;
  2488.  
  2489.         -----------------------------------------------------------------------
  2490.  
  2491.         procedure nth_Line(        --| Move to the specified line.
  2492.              n : in Integer        --| Line to move to.
  2493.              ) is
  2494.  
  2495.              First_Field              : constant TP.Variable_Field_Number_Range
  2496.              --| First (variable) field in the template
  2497.                   := 1;
  2498.  
  2499.              First_Field_on_Last_Line : constant TP.Variable_Field_Number_Range
  2500.              --| First (variable) field on the last line in template
  2501.                   := TP.First_Variable_Field_Number(
  2502.                        Current_Template,
  2503.                        TP.Field_Position(
  2504.                             Current_Template,
  2505.                             TP.Actual_Field_Number(
  2506.                                  Current_Template,
  2507.                                  TP.Variable_Field_Count(
  2508.                                       Current_Template))).Line);
  2509.  
  2510.              Current_Line             : Positive
  2511.              --| Line where current field is
  2512.                   := TP.Field_Position(
  2513.                        Current_Template,
  2514.                        TP.Actual_Field_Number(
  2515.                             Current_Template, Current_Field)).Line;
  2516.         
  2517.         begin
  2518.  
  2519.           -- If specified line number is too large, go to the first field on
  2520.           -- the last line
  2521.              if n > TP.Field_Position(
  2522.                   Current_Template, 
  2523.                   TP.Actual_Field_Number(
  2524.                        Current_Template,
  2525.                        First_Field_on_Last_Line)).Line then
  2526.                   Current_Field := First_Field_on_Last_Line;
  2527.    
  2528.           -- If specified line number is too small, go to the first field
  2529.              elsif n < TP.Field_Position(
  2530.                   Current_Template,
  2531.                   TP.Actual_Field_Number(
  2532.                        Current_Template, First_Field)).Line then
  2533.                   Current_Field := First_Field;
  2534.    
  2535.           -- If specified line number to move to is within bounds of 
  2536.           -- template, go to nth line (or the next line containing
  2537.           -- a variable field)
  2538.              else
  2539.                   for i in First_Field .. First_Field_on_Last_Line loop
  2540.                        if TP.Field_Position(
  2541.                             Current_Template, 
  2542.                             TP.Actual_Field_Number(
  2543.                                  Current_Template, i)).Line >= n then
  2544.                             Current_Field := i;
  2545.                             exit;
  2546.                        end if;
  2547.                   end loop;
  2548.              end if;
  2549.    
  2550.              Prompt_Line := TP.Field_Label(
  2551.                   Current_Template, 
  2552.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2553.              SM.Display_Prompt(Prompt_Line);
  2554.  
  2555.         end nth_Line;
  2556.  
  2557.         -----------------------------------------------------------------------
  2558.  
  2559.         procedure n_Fields(         --| Move a specified number of fields 
  2560.              n : in Integer := 1    --| Number of fields to move
  2561.              ) is
  2562.  
  2563.              First_Field : constant TP.Variable_Field_Number_Range := 1;
  2564.              --| First (variable) field in template
  2565.  
  2566.              Last_Field  : constant TP.Variable_Field_Number_Range
  2567.              --| Last (variable) field in template
  2568.                   := TP.Variable_Field_Count(Current_Template);
  2569.  
  2570.         begin
  2571.  
  2572.           -- explicit check for n /= 0 because of type conversion problem
  2573.              if n /= 0 then
  2574.       
  2575.                -- If number of fields to move forward is outside bounds of 
  2576.                -- template, then go to last field
  2577.                   if (Integer(Current_Field) + n) > Integer(Last_Field) then
  2578.                        Current_Field := Last_Field;
  2579.    
  2580.                -- If number of fields to move back is outside bounds of
  2581.                -- template, then go to first field
  2582.                   elsif (Integer(Current_Field) + n) < Integer(First_Field) 
  2583.                        then
  2584.                        Current_Field := First_Field;
  2585.                   else
  2586.                        Current_Field := TP.Variable_Field_Number_Range(
  2587.                             Integer(Current_Field) + n);
  2588.                   end if;
  2589.              end if;
  2590.    
  2591.           -- Set prompt to current field 
  2592.              Prompt_Line := TP.Field_Label(
  2593.                   Current_Template, 
  2594.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2595.              SM.Display_Prompt(Prompt_Line);
  2596.  
  2597.         end n_Fields;
  2598.  
  2599.         -----------------------------------------------------------------------
  2600.  
  2601.         procedure nth_Field(       --| Move to the specified field.
  2602.              n : in Integer        --| Field to move to.
  2603.              ) is
  2604.  
  2605.              First_Field : constant TP.Variable_Field_Number_Range := 1;
  2606.              --| First (variable) field in template
  2607.  
  2608.              Last_Field  : constant TP.Variable_Field_Number_Range
  2609.              --| Last (variable) field in template
  2610.                   := TP.Variable_Field_Count(Current_Template);
  2611.         
  2612.         begin
  2613.  
  2614.           -- If specified field number is too large, go to the last field
  2615.              if n > Integer(Last_Field) then
  2616.                   Current_Field := Last_Field;
  2617.    
  2618.           -- If specified field number is too small, go to the first field
  2619.              elsif n < Integer(First_Field) then
  2620.                   Current_Field := First_Field;
  2621.              else
  2622.    
  2623.                -- Set current field to field n
  2624.                   Current_Field := TP.Variable_Field_Number_Range(n);
  2625.              end if;
  2626.    
  2627.           -- Set prompt to current field
  2628.              Prompt_Line := TP.Field_Label(
  2629.                   Current_Template, 
  2630.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2631.              SM.Display_Prompt(Prompt_Line);
  2632.  
  2633.         end nth_Field;
  2634.  
  2635.         -----------------------------------------------------------------------
  2636.  
  2637.         procedure Go_to_Field(                --| Move to the specified field.
  2638.              Fieldname : in SS.Screen_String  --| Field to move to.
  2639.              ) is
  2640.  
  2641.              Fieldname_Exists : Boolean := False;
  2642.  
  2643.         begin
  2644.  
  2645.              for i in 1..TP.Variable_Field_Count(Current_Template) loop
  2646.                   exit when Fieldname_Exists;
  2647.                   if SS.Equal(
  2648.                        Fieldname,
  2649.                        TP.Field_Label(
  2650.                             Current_Template,
  2651.                             TP.Actual_Field_Number(Current_Template, i))) then
  2652.                        Fieldname_Exists := True;
  2653.                        Current_Field := i;
  2654.  
  2655.                     -- Set prompt to field with <fieldname>
  2656.                        Prompt_Line := TP.Field_Label(
  2657.                             Current_Template, 
  2658.                             TP.Actual_Field_Number(
  2659.                                  Current_Template, Current_Field));
  2660.                        SM.Display_Prompt(Prompt_Line);
  2661.                   end if;
  2662.              end loop;
  2663.    
  2664.              if not Fieldname_Exists then
  2665.                   raise Fieldname_Not_In_Template;
  2666.              end if;
  2667.    
  2668.         end Go_to_Field;
  2669.  
  2670.         -----------------------------------------------------------------------
  2671.  
  2672.         procedure Insert_Text(             --| Inserts text in current field
  2673.              Text : in SS.Screen_String    --| Text to insert
  2674.              ) is
  2675.  
  2676.              Start          : Length_Range := 1;
  2677.              Length_Field   : Length_Range;
  2678.              Truncated_Text : SS.Screen_String := Text;
  2679.  
  2680.         begin
  2681.  
  2682.           -- If text is longer than variable part of field, truncate text
  2683.              Length_Field := TP.Field_Length(
  2684.                   Current_Template,
  2685.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2686.              if SS.Length(Text) > Length_Field then
  2687.                   Truncated_Text := SS.Substring(Text, Start, Length_Field);
  2688.                   SM.Display_Message(
  2689.                       SS.Create("Text was truncated"), SM.Warning);
  2690.              end if;
  2691.    
  2692.           -- if current field is the identifier field, restrict contents to one
  2693.           -- word
  2694.              if TP."="(Current_Field, 1) then
  2695.                   Truncated_Text := Identifier_Text(Truncated_Text);
  2696.              end if;
  2697.  
  2698.           -- Change contents of current field to as much text as fits and 
  2699.           -- redisplay
  2700.              DM.Update_Field(
  2701.                   Current_Handle, Current_Field, Truncated_Text);
  2702.              SM.Display_Field(
  2703.                   Current_Handle, 
  2704.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2705.  
  2706.           -- Set the current field to the next field
  2707.              n_Fields;
  2708.    
  2709.           -- Set flag indicating that template has been changed
  2710.              Modified_Template := True;
  2711.  
  2712.         end Insert_Text;
  2713.  
  2714.         -----------------------------------------------------------------------
  2715.  
  2716.         procedure Substitute(           --| Substitutes one string for another
  2717.              From_Text : in SS.Screen_String;   --| old string
  2718.              To_Text   : in SS.Screen_String    --| new string
  2719.              ) is
  2720.  
  2721.              Original_Text    : SS.Screen_String;
  2722.              Index            : Integer;
  2723.              First_Start      : Length_Range := 1;
  2724.              First_Remainder  : SS.Screen_String;
  2725.              Second_Start     : Length_Range;
  2726.              Second_Length    : Length_Range;
  2727.              Second_Remainder : SS.Screen_String;
  2728.              New_Text         : SS.Screen_String;
  2729.              Length_Field     : Length_Range;
  2730.  
  2731.         begin
  2732.  
  2733.              Original_Text := DM.Field_Contents(Current_Handle, Current_Field);
  2734.              Index := SS.Match_Pattern(From_Text, Original_Text);
  2735.    
  2736.           -- If From_Text is not found in current field
  2737.              if Index = 0 then
  2738.                   raise No_Oldstring_Match;
  2739.              end if;
  2740.    
  2741.           -- Find remaining pieces of Original_Text not being substituted
  2742.              First_Remainder := 
  2743.                   SS.Substring(Original_Text, First_Start, Index - 1);
  2744.              Second_Start := Index + SS.Length(From_Text);
  2745.              Second_Length := SS.Length(Original_Text) 
  2746.                             - SS.Length(First_Remainder)
  2747.                             - SS.Length(From_Text);
  2748.              Second_Remainder := 
  2749.                   SS.Substring(Original_Text, Second_Start, Second_Length);
  2750.    
  2751.           -- Concatenate remaining Orginal_Text with To_Text
  2752.              New_Text := 
  2753.                   SS."&"(SS."&"(First_Remainder, To_Text),Second_Remainder);
  2754.              Length_Field := TP.Field_Length(
  2755.                   Current_Template, 
  2756.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2757.    
  2758.           -- if current field is the identifier field, restrict contents to one
  2759.           -- word
  2760.              if TP."="(Current_Field, 1) then
  2761.                   New_Text := Identifier_Text(New_Text);
  2762.              end if;
  2763.  
  2764.           -- If New_Text is longer than variable part of field
  2765.              if SS.Length(New_Text) > Length_Field then
  2766.                   raise Too_Long_For_Field;
  2767.              end if;
  2768.    
  2769.           -- Change contents of current field to reflect substitution 
  2770.           -- and redisplay
  2771.              DM.Update_Field(Current_Handle, Current_Field, New_Text);
  2772.              SM.Display_Field(
  2773.                   Current_Handle,
  2774.                   TP.Actual_Field_Number(Current_Template, Current_Field));
  2775.    
  2776.           -- Set flag indicating that template has been changed
  2777.              Modified_Template := True;
  2778.    
  2779.         end Substitute;
  2780.  
  2781.         -----------------------------------------------------------------------
  2782.  
  2783.         procedure Create is
  2784.  
  2785.         --| Creates a dictionary entry from current template
  2786.         
  2787.         begin
  2788.  
  2789.              DM.Create_Entry(Current_Handle);
  2790.              Modified_Template := False;
  2791.              SM.Display_Message(
  2792.                   SS.Unchecked_Create(
  2793.                        SS.Value(TP.Template_Label(Current_Template)) & " " &
  2794.                        SS.Value(
  2795.                             DM.Field_Contents(
  2796.                                  Current_Handle,
  2797.                                  TP.Variable_Field_Number_Range'First)) &
  2798.                        " has been created"),
  2799.                   SM.Info);
  2800.    
  2801.         end Create;
  2802.  
  2803.         -----------------------------------------------------------------------
  2804.  
  2805.         procedure Update is
  2806.  
  2807.         --| Updates a dictionary entry from current template
  2808.  
  2809.         begin
  2810.  
  2811.              DM.Update_Entry(Current_Handle);
  2812.              Modified_Template := False;
  2813.              SM.Display_Message(
  2814.                   SS.Unchecked_Create(
  2815.                        SS.Value(TP.Template_Label(Current_Template)) & " " &
  2816.                        SS.Value(
  2817.                             DM.Field_Contents(
  2818.                                  Current_Handle,
  2819.                                  TP.Variable_Field_Number_Range'First)) & 
  2820.                        " has been updated"),
  2821.                   SM.Info);
  2822.    
  2823.         end Update;
  2824.  
  2825.         -----------------------------------------------------------------------
  2826.  
  2827.         procedure Exit_Editor is
  2828.  
  2829.         --| Exits from the editor
  2830.  
  2831.              Choice        : SS.Screen_String   --| menu choice
  2832.                   := SS.Create("");
  2833.  
  2834.         begin
  2835.  
  2836.           -- If template has been modified by insert or substitute, prompt 
  2837.           -- user to save changes before executing edit command
  2838.              if Modified_Template then
  2839.       
  2840.                   while (SS.Length(Choice) /= 1) or else
  2841.                        not (SS.Equal(Choice, "n") or 
  2842.                             SS.Equal(Choice, "N") or SS.Equal(Choice, "y") or 
  2843.                             SS.Equal(Choice, "Y") or SS.Equal(Choice, "*")) loop
  2844.                        SM.Display_Message(
  2845.                             SS.Create("Template has been modified"), 
  2846.                             SM.Warning);
  2847.                        SM.Display_Secondary_Prompt(
  2848.                             SS.Create("Save? (y, n, * to abort) : "));
  2849.    
  2850.                        begin
  2851.                             Choice := SS.Unchecked_Create(TIO.Read);
  2852.                        exception
  2853.                             when TIO.End_of_File_Error =>
  2854.                                  Abort_Editor(End_of_File_Condition);
  2855.                        end;
  2856.    
  2857.                        Choice := SSU.Strip_Leading(Choice);
  2858.                        Choice := SSU.Strip_Trailing(Choice);
  2859.                   end loop;
  2860.    
  2861.                   case SS.Value(Choice)(1) is
  2862.                        when 'n' | 'N' => SM.Clear_Message_Line;
  2863.                        when 'y' | 'Y' => 
  2864.                        begin
  2865.                             EC.Update;
  2866.                        exception
  2867.                             when DM.Cant_Update_New_Entry =>
  2868.                                  EC.Create;
  2869.                        end;
  2870.                        when '*' => 
  2871.                             SM.Clear_Message_Line;
  2872.                             return;
  2873.                        when others => raise Internal_Error;
  2874.                   end case;
  2875.    
  2876.              end if; 
  2877.    
  2878.              SM.Position_for_Exit;
  2879.              Exit_Found := True;
  2880.  
  2881.         end Exit_Editor;
  2882.  
  2883.         -----------------------------------------------------------------------
  2884.  
  2885.     end Editing_Commands;
  2886.  
  2887.     ---------------------------------------------------------------------------
  2888.     -----------------------Local Subprogram Bodies-----------------------------
  2889.  
  2890.     procedure Abort_Editor(            --| Stops processing of editing commands
  2891.          Abort_Code : Abort_Code_Name  --| What caused processing to abort
  2892.          ) is
  2893.     begin
  2894.          case Abort_Code is
  2895.               when End_of_File_Condition =>
  2896.                    SM.Display_Message(
  2897.                         SS.Create("End of file detected.  Exiting..."),
  2898.                         SM.Warning);
  2899.               when Interrupt_Condition =>
  2900.                    SM.Display_Message(
  2901.                         SS.Create("Interrupt detected.  Exiting..."),
  2902.                         SM.Warning);
  2903.          end case;
  2904.          DM.Close_Dictionary;
  2905.          SM.Position_for_Exit;
  2906.          raise Abort_Commands;
  2907.  
  2908.     end Abort_Editor;
  2909.  
  2910.     ---------------------------------------------------------------------------
  2911.  
  2912.     procedure Interpret_Command(  
  2913.          In_Text : in SS.Screen_String      --| Command to parse
  2914.          ) is
  2915.  
  2916.     --| Parses Text and calls appropriate editor procedure.  If command is not 
  2917.     --| one of acceptable editor commands, Nonexistent_Command is raised.
  2918.  
  2919.          Text            : SS.Screen_String;
  2920.                                         --| Input text without leading blanks
  2921.          First_Character : Character;   --| First character of Text
  2922.          Text_Scanner    : SU.Scanner;  --| Text converted to scanner
  2923.  
  2924.     begin
  2925.    
  2926.       -- Scan first non blank character
  2927.          Text := SSU.Strip_Leading(In_Text);
  2928.          if not SS.Equal(Text, "") then
  2929.      
  2930.            -- Check first character of command line against special edit 
  2931.            -- characters and call appropriate parsing procedure
  2932.               Text_Scanner := SSU.Make_Scanner(Text);
  2933.               First_Character := SS.Value(Text)(1);
  2934.               case First_Character is
  2935.                    when Plus_Key | Minus_Key => 
  2936.                         Parse_n_Lines_or_Fields(Text_Scanner);
  2937.                    when '0'..'9' =>
  2938.                         Parse_nth_Line_or_Field(Text_Scanner);
  2939.                    when Open_Fieldname_Key => 
  2940.                         Parse_Fieldname(Text_Scanner);
  2941.                    when Insert_Key =>
  2942.                         Parse_Insert(Text_Scanner);
  2943.                    when Substitute_Delimiter => 
  2944.                         Parse_Substitute(Text_Scanner);
  2945.                    when 'a'..'z' | 'A'..'Z'  => 
  2946.                         Parse_Alphabetic_Commands(Text_Scanner);
  2947.                    when others =>
  2948.                         raise Nonexistent_Command;
  2949.               end case;
  2950.  
  2951.          else
  2952.               EC.n_Fields;               
  2953.          end if;
  2954.  
  2955.  
  2956.     exception
  2957.  
  2958.          when Nonexistent_Command => 
  2959.               SM.Display_Message(
  2960.                    SS.Create("Nonexistent command"), SM.Error);
  2961.          when Ambiguous_Command => 
  2962.               SM.Display_Message(
  2963.                    SS.Create("Ambiguous command"), SM.Error);
  2964.          when Too_Many_Parameters => 
  2965.               SM.Display_Message(
  2966.                    SS.Create("Too many parameters"), SM.Error);
  2967.          when Missing_Nth_Line_or_Field_Command => 
  2968.               SM.Display_Message(
  2969.                    SS.Create("Missing line or field command"), SM.Error);
  2970.          when Missing_Fieldname => 
  2971.               SM.Display_Message(
  2972.                    SS.Create("Missing fieldname"), SM.Error);
  2973.          when Incomplete_Fieldname => 
  2974.               SM.Display_Message(
  2975.                    SS.Create("Incomplete fieldname"), SM.Error);
  2976.          when Missing_Old_String => 
  2977.               SM.Display_Message(
  2978.                    SS.Create("Missing old string"), SM.Error);
  2979.          when Incomplete_Substitution => 
  2980.               SM.Display_Message(
  2981.                    SS.Create("Incomplete substitution"), SM.Error);
  2982.          when Invalid_Escape_Sequence => 
  2983.               SM.Display_Message(
  2984.                    SS.Create("Invalid placement of escape character"),
  2985.                    SM.Error);
  2986.          when Invalid_Substitute_Delimiter => 
  2987.               SM.Display_Message(
  2988.                    SS.Create("Invalid substitute delimiter"), SM.Error);
  2989.          when Missing_Template_Type => 
  2990.               SM.Display_Message(
  2991.                    SS.Create("Missing template type"), SM.Error);
  2992.          when Invalid_Template_Type => 
  2993.               SM.Display_Message(
  2994.                    SS.Create("Invalid template type"), SM.Error);
  2995.          when Missing_Identifier => 
  2996.               SM.Display_Message(
  2997.                    SS.Create("Missing identifier"), SM.Error);
  2998.          when Fieldname_Not_In_Template  => 
  2999.               SM.Display_Message(
  3000.                    SS.Create("No field by that name in template"), SM.Error);
  3001.          when No_Oldstring_Match => 
  3002.               SM.Display_Message(
  3003.                    SS.Create("Substitution string does not exist in field"),
  3004.                    SM.Error);
  3005.          when Too_Long_For_Field => 
  3006.               SM.Display_Message(
  3007.                    SS.Create("Substitution is too long for field"), SM.Error);
  3008.          when DM.Null_Identifier => 
  3009.               SM.Display_Message(
  3010.                    SS.Create("Identifier field must be filled out"), 
  3011.                    SM.Error);
  3012.          when DM.No_Overload_Field => 
  3013.               SM.Display_Message(
  3014.                    SS.Create("Overload field must be filled out"), SM.Error);
  3015.          when DM.Too_Many_Overloads => 
  3016.               SM.Display_Message(
  3017.                    SS.Create(
  3018.                         "Too many overloads of this identifier already exist"),
  3019.                    SM.Error);
  3020.          when DM.Cant_Update_New_Entry => 
  3021.               SM.Display_Message(
  3022.                    SS.Create("Cannot update a new entry - use create"),
  3023.                    SM.Error);
  3024.  
  3025.     end Interpret_Command;
  3026.  
  3027.     ---------------------------------------------------------------------------
  3028.  
  3029.     procedure Parse_n_Lines_or_Fields(  --| Parses Text for number and command
  3030.                                         --| (lines/fields) and calls either 
  3031.                                         --| n_Fields or n_Lines procedure
  3032.          Text_Scanner : in SU.Scanner   --| Command to parse
  3033.          ) is 
  3034.  
  3035.          Sign          : Character;
  3036.          Number        : Integer;
  3037.          Found         : Boolean;
  3038.          Dummy         : SS.Screen_String;
  3039.          Large_Number  : constant := 9999999;
  3040.          Command       : SS.Screen_String;
  3041.          Fields_String : SS.Screen_String := SS.Create("fields");
  3042.          Lines_String  : SS.Screen_String := SS.Create("lines");
  3043.  
  3044.    begin
  3045.  
  3046.       -- First character of command line is Plus_Key or Minus_Key
  3047.       -- Not specifying the number of lines/field = 1 line/field
  3048.          if not SU.Is_Signed_Number(Text_Scanner) then
  3049.               SU.Next(Text_Scanner, Sign);
  3050.               if Sign = '+' then
  3051.                    Number := 1;
  3052.               elsif Sign = '-' then
  3053.                    Number := -1;
  3054.               end if;
  3055.          else
  3056.  
  3057.            -- Parse for number of lines/fields to move
  3058.               begin
  3059.                    SU.Scan_Signed_Number(Text_Scanner, Found, Number);
  3060.               exception
  3061.                    when SU.Number_Too_Large =>
  3062.                         SU.Next(Text_Scanner, Sign);
  3063.                         if Sign = '+' then
  3064.                              Number := Large_Number;
  3065.                         elsif Sign = '-' then
  3066.                              Number := -Large_Number;
  3067.                         end if;
  3068.  
  3069.                         -- skip past the number
  3070.                         SSU.Scan_Signed_Number(Text_Scanner, Found, Dummy);
  3071.               end;
  3072.               SU.Skip_Space(Text_Scanner);
  3073.          end if;
  3074.  
  3075.          if SU.Is_Word(Text_Scanner) then
  3076.  
  3077.            -- Parse for lines/fields command
  3078.               SSU.Scan_Word(Text_Scanner, Found, Command);
  3079.               SU.Skip_Space(Text_Scanner);
  3080.          else
  3081.  
  3082.            -- Nonexistent command name will be assumed to be "fields" command
  3083.               Command := Fields_String;
  3084.          end if;
  3085.  
  3086.          if SU.More(Text_Scanner) then
  3087.               raise Too_Many_Parameters;
  3088.          end if;
  3089.  
  3090.       -- Call appropriate procedure for command name
  3091.          if SS.Match_Prefix(Command, Fields_String) then
  3092.               EC.n_Fields(Number);
  3093.          elsif SS.Match_Prefix(Command, Lines_String) then
  3094.               EC.n_Lines(Number);
  3095.          else
  3096.               raise Nonexistent_Command;
  3097.          end if;
  3098.  
  3099.     end Parse_n_Lines_or_Fields;
  3100.  
  3101.     ---------------------------------------------------------------------------
  3102.  
  3103.     procedure Parse_nth_Line_or_Field(  --| Parses Text for number and command 
  3104.                                         --| (line/field) and calls either
  3105.                                         --| nth_Field or nth_Line
  3106.          Text_Scanner : in SU.Scanner   --| Command to parse
  3107.          ) is 
  3108.  
  3109.          Found        : Boolean;
  3110.          Number       : Integer;
  3111.          Dummy        : SS.Screen_String;
  3112.          Large_Number : constant := 9999999;
  3113.          Command      : SS.Screen_String;
  3114.          Field_string : SS.Screen_String := SS.Create("field");
  3115.          Line_string  : SS.Screen_String := SS.Create("line");
  3116.  
  3117.     begin
  3118.  
  3119.       -- First character of command line is a number
  3120.       -- Parse for line/field number to move to
  3121.          begin
  3122.               SU.Scan_Number(Text_Scanner, Found, Number);
  3123.          exception
  3124.               when SU.Number_Too_Large =>
  3125.                    Number := Large_Number;
  3126.  
  3127.                    -- skip past the number
  3128.                    SSU.Scan_Number(Text_Scanner, Found, Dummy);
  3129.          end;
  3130.          SU.Skip_Space(Text_Scanner);
  3131.           
  3132.          if not SU.Is_Word(Text_Scanner) then
  3133.               raise Missing_nth_Line_or_Field_Command;
  3134.          end if;
  3135.  
  3136.       -- Parse for line/field command 
  3137.          SSU.Scan_Word(Text_Scanner, Found, Command);
  3138.          SU.Skip_Space(Text_Scanner);
  3139.  
  3140.          if SU.More(Text_Scanner) then
  3141.               raise Too_Many_Parameters;
  3142.          end if;
  3143.  
  3144.       -- Call appropriate procedure for command name
  3145.          if SS.Match_Prefix(Command, Field_String) then
  3146.               EC.nth_Field(Number);
  3147.          elsif SS.Match_Prefix(Command, Line_String) then
  3148.               EC.nth_Line(Number);
  3149.          else
  3150.               raise Nonexistent_Command;
  3151.          end if;
  3152.  
  3153.     end Parse_nth_Line_or_Field;
  3154.  
  3155.     ---------------------------------------------------------------------------
  3156.  
  3157.     procedure Parse_Fieldname(         --| Parses Text for parameter
  3158.                                        --| (fieldname), calls Go_to_Field 
  3159.          Text_Scanner : in SU.Scanner  --| Command to parse
  3160.          ) is 
  3161.  
  3162.          Found     : Boolean;
  3163.          Fieldname : SS.Screen_String;
  3164.  
  3165.     begin
  3166.  
  3167.       -- First character of command line is Open_Fieldname_Key
  3168.       -- Parse for closing delimiter and fieldname parameter 
  3169.          SSU.Scan_Enclosed(
  3170.               Open_Fieldname_Key, Close_Fieldname_Key, Text_Scanner, Found,
  3171.                    Fieldname, Skip => True);
  3172.          if not Found then
  3173.  
  3174.            -- missing Close_Fieldname_Key
  3175.               raise Incomplete_fieldname;
  3176.          end if;
  3177.  
  3178.          Fieldname := SSU.Strip_Leading(Fieldname);
  3179.          Fieldname := SSU.Strip_Trailing(Fieldname);
  3180.  
  3181.          if SS.Equal(Fieldname, "") then
  3182.               raise Missing_fieldname;
  3183.          end if;
  3184.  
  3185.          if SU.More(Text_Scanner) then
  3186.               raise Too_Many_Parameters;
  3187.          end if;
  3188.  
  3189.          EC.Go_to_Field(Fieldname);
  3190.  
  3191.     end Parse_Fieldname;
  3192.  
  3193.     ---------------------------------------------------------------------------
  3194.  
  3195.     procedure Parse_Insert(     --| Parses Text for parameter (text to insert), 
  3196.                                 --| calls Insert_Text 
  3197.          Text_Scanner : in SU.Scanner  --| Command to parse
  3198.          ) is
  3199.  
  3200.          Found          : Boolean;
  3201.          Text_to_Insert : SS.Screen_String;
  3202.  
  3203.     begin
  3204.  
  3205.       -- First character of command line is Insert_Key
  3206.          SU.Forward(Text_Scanner);
  3207.  
  3208.       -- Parse for Text_to_Insert parameter and call procedure
  3209.          Text_to_Insert := SSU.Get_Remainder(Text_Scanner);
  3210.          EC.Insert_Text(Text_to_Insert);
  3211.  
  3212.     end Parse_Insert;
  3213.  
  3214.     ---------------------------------------------------------------------------
  3215.  
  3216.     procedure Get_Substitution_String(
  3217.          Text_Scanner : in     SU.Scanner;
  3218.          Delimiter    : in     Character;
  3219.          Escape       : in     Character;
  3220.          Result       : in out SS.Screen_String;
  3221.          End_of_Line  :    out Boolean
  3222.          ) is
  3223.  
  3224.          Temp_String   : SS.Screen_String;
  3225.          Double_Escape : Boolean;
  3226.          Found         : Boolean;
  3227.          Index         : Positive;
  3228.          Del_Char      : Character;
  3229.          EOL           : Boolean := False;
  3230.  
  3231.     begin
  3232.  
  3233.          Result := SS.Create("");
  3234.  
  3235.          loop
  3236.               SSU.Scan_Enclosed(
  3237.                    Delimiter, Delimiter, Text_Scanner, Found, Temp_String);
  3238.               if not Found then
  3239.                    if not SU.More(Text_Scanner) then
  3240.                         raise Invalid_Substitute_Delimiter;
  3241.                    end if;
  3242.                    SU.Next(Text_Scanner, Del_Char);
  3243.                    if Del_Char /= Delimiter then
  3244.                         raise Invalid_Substitute_Delimiter;
  3245.                    end if;
  3246.                    Temp_String := SSU.Get_Remainder(Text_Scanner);
  3247.                    EOL := True;
  3248.               end if;
  3249.  
  3250.               Index := 1;
  3251.               Double_Escape := True;
  3252.  
  3253.               for i in 1 .. SS.Length(Temp_String) loop
  3254.                    if SS.Value(Temp_String)(i .. i) = Escape & "" then
  3255.                         if not Double_Escape then
  3256.                              Result := SS."&"(Result, 
  3257.                                   SS.Substring(Temp_String, Index, i-Index));
  3258.                              Index := i + 1;
  3259.                          end if;
  3260.                          Double_Escape := not Double_Escape;
  3261.                    elsif not Double_Escape then
  3262.                         raise Invalid_Escape_Sequence;
  3263.                    end if;
  3264.               end loop;
  3265.  
  3266.               if EOL and not Double_Escape then
  3267.                    raise Invalid_Escape_Sequence;
  3268.               end if;
  3269.               exit when Index > SS.Length(Temp_String);
  3270.               Result := SS."&"(Result, SS.Substring(
  3271.                    Temp_String, Index, SS.Length(Temp_String) - Index));
  3272.               if Double_Escape then
  3273.                    Result := SS."&"(Result, SS.Substring(
  3274.                         Temp_String, SS.Length(Temp_String), 1));
  3275.                    exit;
  3276.               else
  3277.                    Result := SS."&"(Result, Delimiter & "");
  3278.               end if;
  3279.               SU.Backward(Text_Scanner);
  3280.          end loop;
  3281.  
  3282.          End_of_Line := EOL;
  3283.          if not EOL then
  3284.               SU.Backward(Text_Scanner);
  3285.          end if;
  3286.  
  3287.     end Get_Substitution_String;
  3288.  
  3289.  
  3290. ---------------------------------------------------------------------------
  3291.  
  3292.     procedure Parse_Substitute(      --| Parses Text for parameters (oldstring,
  3293.                                      --| newstring), calls Substitute
  3294.         Text_Scanner : in SU.Scanner --| Command to parse
  3295.         ) is
  3296.  
  3297.         Old_String : SS.Screen_String;
  3298.         New_String : SS.Screen_String;
  3299.         Remainder : SS.Screen_String;
  3300.         End_Of_Line : Boolean;
  3301.  
  3302.     begin
  3303.  
  3304.       -- Parse for oldstring parameter and second delimiter
  3305.          Get_Substitution_String(
  3306.               Text_Scanner, Substitute_Delimiter, Escape_Character, Old_String,
  3307.               End_Of_Line);
  3308.  
  3309.          if SS.Equal(Old_String, "") then
  3310.               raise Missing_old_string;
  3311.          end if;
  3312.  
  3313.          if End_Of_Line then
  3314.               raise Incomplete_Substitution;
  3315.          end if;
  3316.  
  3317.       -- Parse for newstring parameter and call procedure
  3318.          Get_Substitution_String(
  3319.               Text_Scanner, Substitute_Delimiter, Escape_Character, New_String,
  3320.               End_Of_Line);
  3321.          if not End_Of_Line then 
  3322.               SU.Forward(Text_Scanner);
  3323.               SU.Skip_Space(Text_Scanner);
  3324.               if SU.More(Text_Scanner) then
  3325.                    raise Too_Many_Parameters;
  3326.               end if;
  3327.          end if;
  3328.          EC.Substitute(Old_String, New_String);
  3329.  
  3330.     end Parse_Substitute;
  3331.  
  3332.     ---------------------------------------------------------------------------
  3333.  
  3334.     procedure Parse_Alphabetic_Commands( --| Parses Text for command, parameters
  3335.                                          --| and calls appropriate procedure
  3336.         Text_Scanner : in SU.Scanner     --| Command to parse
  3337.         ) is 
  3338.  
  3339.         Found          : Boolean;
  3340.         Command        : SS.Screen_String;
  3341.         Template_Image : SS.Screen_String;
  3342.         Template_Type  : TP.Template_Name;
  3343.         Identifier     : SS.Screen_String;
  3344.  
  3345.         type Editor_Command_Name is (Commands_Command, Create_Command, 
  3346.              Exit_Command, Help_Field_Command, Refresh_Command, 
  3347.              Update_Command, Delete_Command, Edit_Command,
  3348.              Show_Overloads_Command); 
  3349.  
  3350.         subtype No_Parameters_Command_Name is Editor_Command_Name range
  3351.              Commands_Command .. Update_Command;
  3352.  
  3353.         Command_Name   : Editor_Command_Name;
  3354.  
  3355.         Editor_Strings : constant array (1..9) of Screen_String
  3356.              := (SS.Create("commands"), SS.Create("create"), 
  3357.                  SS.Create("delete"), SS.Create("edit"),
  3358.                  SS.Create("exit"), SS.Create("help"), 
  3359.                  SS.Create("refresh"), SS.Create("show"),
  3360.                  SS.Create("update"));
  3361.  
  3362.    begin
  3363.  
  3364.          SSU.Scan_Word(Text_Scanner, Found, Command);
  3365.  
  3366.       -- Check for ambiguous command
  3367.          for i in Editor_Strings'First .. Editor_Strings'Last - 1 loop 
  3368.               if SS.Match_Prefix(Command, Editor_Strings(i)) then
  3369.                    if SS.Match_Prefix(Command, Editor_Strings(i + 1)) then
  3370.                         raise Ambiguous_Command;
  3371.                    end if;
  3372.               end if;
  3373.          end loop;
  3374.  
  3375.       -- Match incoming command string against array of command strings
  3376.          if SS.Match_Prefix(Command, Editor_Strings(1)) then
  3377.               Command_Name := Commands_Command;
  3378.          elsif SS.Match_Prefix(Command, Editor_Strings(2)) then
  3379.               Command_Name := Create_Command;
  3380.          elsif SS.Match_Prefix(Command, Editor_Strings(3)) then
  3381.               Command_Name := Delete_Command;
  3382.          elsif SS.Match_Prefix(Command, Editor_Strings(4)) then
  3383.               Command_Name := Edit_Command;
  3384.          elsif SS.Match_Prefix(Command, Editor_Strings(5)) then
  3385.               Command_Name := Exit_Command;
  3386.          elsif SS.Match_Prefix(Command, Editor_Strings(6)) then
  3387.               Command_Name := Help_Field_Command;
  3388.          elsif SS.Match_Prefix(Command, Editor_Strings(7)) then
  3389.               Command_Name := Refresh_Command;
  3390.          elsif SS.Match_Prefix(Command, Editor_Strings(8)) then
  3391.               Command_Name := Show_Overloads_Command;
  3392.          elsif SS.Match_Prefix(Command, Editor_Strings(9)) then
  3393.               Command_Name := Update_Command;
  3394.          else
  3395.               raise Nonexistent_Command;
  3396.          end if;
  3397.  
  3398.          SU.Skip_Space(Text_Scanner);
  3399.          if not SU.More(Text_Scanner) then
  3400.  
  3401.            -- If there is nothing more on the command line, call appropriate 
  3402.            -- procedure if command doesn't take parameters and raise missing 
  3403.            -- parameter exception if command takes parameters.
  3404.               case Command_Name is
  3405.                    when Commands_Command   => EC.Show_Commands;
  3406.                    when Create_Command     => EC.Create;
  3407.                    when Exit_Command       => EC.Exit_Editor;
  3408.                    when Help_Field_Command => EC.Show_Help_Field;
  3409.                    when Refresh_Command    => EC.Refresh;
  3410.                    when Update_Command     => EC.Update;
  3411.                    when others             => raise Missing_template_type;
  3412.               end case;
  3413.  
  3414.          else
  3415.  
  3416.               if Command_Name in No_Parameters_Command_Name then
  3417.                    raise Too_Many_Parameters;
  3418.               end if;
  3419.  
  3420.            -- If there is more on the command line, parse for first parameter
  3421.               SSU.Scan_Word(Text_Scanner, Found, Template_Image);
  3422.  
  3423.               begin
  3424.                    Template_Type := 
  3425.                         TP.Template_Name'Value(SS.Value(Template_Image));
  3426.               exception
  3427.                    when Constraint_Error => raise Invalid_Template_Type;
  3428.               end;
  3429.  
  3430.               SU.Skip_Space(Text_Scanner);
  3431.               if SU.More(Text_Scanner) then
  3432.  
  3433.                 -- If there is more on the command line, parse for second 
  3434.                 -- parameter
  3435.                    SSU.Scan_Word(Text_Scanner, Found, Identifier);
  3436.                    SU.Skip_Space(Text_Scanner);
  3437.                     
  3438.                 -- If there is more on the command line after 2nd parameter, 
  3439.                 -- raise exception 
  3440.                    if SU.More(Text_Scanner) then
  3441.                         raise Too_Many_Parameters;
  3442.                    end if;
  3443.  
  3444.                 -- Call appropriate procedure if command takes 2 parameters 
  3445.                 -- and raise too many parameters exception if command
  3446.                 -- doesn't take parameters.
  3447.                    case Command_Name is
  3448.                         when Delete_Command => 
  3449.                              EC.Delete(Template_Type, Identifier);
  3450.                         when Edit_Command => 
  3451.                              EC.Edit(Template_Type, Identifier);
  3452.                         when Show_Overloads_Command =>
  3453.                              EC.Show_Overloads(Template_Type, Identifier);
  3454.                         when others => 
  3455.                              raise Too_Many_Parameters;
  3456.                    end case;
  3457.  
  3458.          
  3459.               else 
  3460.  
  3461.                 -- If there is no more on the command line after 1st parameter,
  3462.                 -- call appropriate procedure if command has default 2nd
  3463.                 -- parameter, raise missing parameter exception if command
  3464.                 -- requires 2 parameters, and raise too many parameters
  3465.                 -- exception if command doesn't take parameters.
  3466.                    case Command_Name is
  3467.                         when Edit_Command => 
  3468.                              EC.Edit(Template_Type);
  3469.                         when Delete_Command => 
  3470.                              raise Missing_identifier;
  3471.                         when Show_Overloads_Command => 
  3472.                              raise Missing_identifier;
  3473.                         when others => 
  3474.                              raise Too_Many_Parameters;
  3475.                    end case;
  3476.  
  3477.               end if;
  3478.  
  3479.          end if;
  3480.  
  3481.     end Parse_Alphabetic_Commands;
  3482.  
  3483.     ---------------------------------------------------------------------------
  3484.  
  3485.     function Identifier_Text(     --| Checks text about to be inserted to 
  3486.                                   --| identifier field
  3487.          Text : SS.Screen_String  --| Text to be checked
  3488.          ) return SS.Screen_String is
  3489.          Scan_Text   : SU.Scanner;
  3490.          Return_Word : SS.Screen_String;
  3491.          Word        : SS.Screen_String;
  3492.          Found       : Boolean;
  3493.     begin
  3494.          Scan_Text := SSU.Make_Scanner(Text);
  3495.          SSU.Scan_Word(Scan_Text, Found, Return_Word, Skip => True);
  3496.          if SU.More(Scan_Text) then
  3497.                SSU.Scan_Word(Scan_Text, Found, Word, Skip => True);
  3498.                if Found then
  3499.                     SM.Display_Message(
  3500.                          SS.Create("Identifier field must be only one word:" &
  3501.                                    " text was truncated"), 
  3502.                          SM.Warning);
  3503.                     return Return_Word;
  3504.                end if;
  3505.          end if;
  3506.          return Text;
  3507.     end Identifier_Text;
  3508.  
  3509.     ---------------------------------------------------------------------------
  3510.     ---------------------------------------------------------------------------
  3511.  
  3512. end Commands; 
  3513.  
  3514. -------------------------------------------------------------------------------
  3515.  
  3516. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3517. --DICTMGR.BDY
  3518. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  3519. with Host_Lib;
  3520. with File_Manager;
  3521. with DD_Release;
  3522. with Labeled_Trees;
  3523. with Lists;
  3524. with String_Utilities;
  3525. with Paginated_Output;
  3526. with Text_IO;
  3527. -------------------------------------------------------------------------------
  3528.  
  3529. package body Dictionary_Manager is
  3530. --| Provide operations to manage a collection of dictionary entries associated
  3531. --| with various template types.
  3532.  
  3533.     ---------------------------------------------------------------------------
  3534.     -- Local declarations
  3535.     ---------------------------------------------------------------------------
  3536.  
  3537.     package FM renames File_Manager;
  3538.     package SU renames String_Utilities;
  3539.     package PO renames Paginated_Output;
  3540.  
  3541.     package Int_IO is new Text_IO.Integer_IO(DIO.Count);
  3542.  
  3543.     package FL is new Lists(ItemType => DIO.Positive_Count);
  3544.  
  3545.     package SSU is new SU.Generic_String_Utilities(
  3546.         Generic_String_Type => SS.Screen_String,
  3547.         To_Generic => SS.Unchecked_Create,
  3548.         From_Generic => SS.Value);
  3549.  
  3550.     Position_Free_Lists : array(TP.Template_Name) 
  3551.         of FL.List := (others => FL.Create);
  3552.     --| Array of free lists for each template type
  3553.  
  3554.     type File_Position_Array is 
  3555.         array(Overload_Range) of DIO.Count;
  3556.     --| Array of file positions for an identifier
  3557.  
  3558.     package IT is new Labeled_Trees(
  3559.         Label_Type => SS.Screen_String,
  3560.         Value_Type => File_Position_Array,
  3561.         "<" => SS."<");
  3562.  
  3563.     type Lock_Mode_Name is (Unlocked, Locked);
  3564.     Lock_File        : Text_IO.File_Type;  --| File object for lock file
  3565.     Version_File     : Text_IO.File_Type;  --| File object for version file
  3566.  
  3567.     Identifier_Index : constant TP.Variable_Field_Number_Range
  3568.         := TP.Variable_Field_Number_Range'First;
  3569.     --| TP.Variable_Field_Range'First is defined as the index in data array
  3570.     --| at which identifier occurs
  3571.  
  3572.     Overload_Index   : constant TP.Variable_Field_Number_Range
  3573.         := TP."+"(Identifier_Index, 1);
  3574.     --| TP.Variable_Field_Range'First + 1 is defined as the index in data array
  3575.     --| at which overload field occurs
  3576.  
  3577.     type Index_Tree_Descriptor is 
  3578.         record
  3579.             Tree        : IT.Tree;  --| Index used in conjunction with 
  3580.                                     --| Direct_IO file
  3581.             Initialized : Boolean;  --| Whether tree has been initialized
  3582.         end record;
  3583.  
  3584.     Index_Trees : array(TP.Template_Name) of Index_Tree_Descriptor := 
  3585.         (others => (IT.Create, False));
  3586.     --| Index trees for all template types in dictionary
  3587.  
  3588.     Current_Dict     : SS.Screen_String := SS.Create("");
  3589.     --| Current dictionary directory name 
  3590.  
  3591.     type Dictionary_File_Type is  --| File objects for index and data
  3592.         record
  3593.             Index_File : Text_IO.File_Type;
  3594.             --| Index file object for a template type
  3595.             Data_File  : DIO.File_Type;
  3596.             --| Data file object for a template type
  3597.         end record;
  3598.  
  3599.     File_Types  : array(TP.Template_Name) of Dictionary_File_Type;
  3600.     --| File objects for all files in data dictionary
  3601.  
  3602.     ---------------------------------------------------------------------------
  3603.     -- Local subprogram specifications
  3604.     ---------------------------------------------------------------------------
  3605.  
  3606.     procedure Read_Index(  --| Reads in index tree for a template type
  3607.         Template : in TP.Template_Name
  3608.                            --| Template type for which to read in tree
  3609.         );
  3610.         --| Raises: No_Dictionary_File, Index_File_Error
  3611.  
  3612.     --| Effects: Reads in the index tree for a particular template type.
  3613.     --| Also reads in the free list of available positions to which dictionary
  3614.     --| items can be written.  No_Dictionary_File is raised when 
  3615.     --| Open_Dictionary hasn't been called before this procedure is called.
  3616.     --| An error message is printed and Index_File_Error is raised when an
  3617.     --| index file in the dictionary doesn't exist or can't be opened.
  3618.  
  3619.     --| N/A: Requires, Modifies
  3620.  
  3621.     ---------------------------------------------------------------------------
  3622.  
  3623.     procedure Write_Index(  --| Writes out the index tree for a template type
  3624.         Template : in TP.Template_Name
  3625.                             --| Template type for which to write out tree
  3626.         );
  3627.         --| Raises: No_Dictionary_File, Index_File_Error
  3628.  
  3629.     --| Effects: Writes out the free list of available positions to which
  3630.     --| dictionary items can be written, and writes out the index tree for
  3631.     --| a particular template type.  No_Dictionary_File is raised when 
  3632.     --| Open_Dictionary hasn't been called before this procedure is called.
  3633.     --| An error message is printed and Index_File_Error is raised when an
  3634.     --| index file in the dictionary doesn't exist or can't be opened.
  3635.  
  3636.     --| N/A: Requires, Modifies
  3637.  
  3638.     ---------------------------------------------------------------------------
  3639.  
  3640.     function Attach_File_Position(  --| Adds a file position to the array
  3641.         File_Positions : in File_Position_Array; 
  3642.                                     --| Array of file positions
  3643.         Item           : DIO.Positive_Count
  3644.                                     --| File position to attach
  3645.         ) return File_Position_Array;
  3646.         --| Raises: Too_Many_Overloads
  3647.  
  3648.     --| Effects: Adds a new file position to the array of file positions.
  3649.     --| Too_Many_Overloads is raised when the maximum number of overloads
  3650.     --| already exists in the File_Position_Array.
  3651.  
  3652.     --| N/A: Requires, Modifies
  3653.  
  3654.     ---------------------------------------------------------------------------
  3655.  
  3656.     function Delete_File_Position(   --| Deletes a file position from the array
  3657.         File_Positions : in File_Position_Array; 
  3658.                                      --| Array of file positions
  3659.         Item           : DIO.Positive_Count
  3660.                                      --| File position to delete
  3661.         ) return File_Position_Array;
  3662.         --| Raises: No_Such_Occurrence
  3663.  
  3664.     --| Effects: Deletes a file position from the array of file positions
  3665.     --| No_Such_Occurrence is raised when an Item is not in the array.
  3666.  
  3667.     --| N/A: Requires, Modifies
  3668.  
  3669.     ---------------------------------------------------------------------------
  3670.  
  3671.     function Data_File_Name(  --| Returns the data file name for a template
  3672.         Template : TP.Template_Name
  3673.         ) return String;
  3674.  
  3675.     --| Effects: Determines a name for the dictionary data file based on the
  3676.     --| Template_Name passed in.
  3677.  
  3678.     --| N/A: Raises, Requires, Modifies
  3679.  
  3680.     ---------------------------------------------------------------------------
  3681.  
  3682.     function Index_File_Name(  --| Returns the index file name for a template
  3683.         Template : TP.Template_Name
  3684.         ) return String;
  3685.  
  3686.     --| Effects: Determines a name for the dictionary index file based on the
  3687.     --| Template_Name passed in.
  3688.  
  3689.     --| N/A: Raises, Requires, Modifies
  3690.  
  3691.     ---------------------------------------------------------------------------
  3692.  
  3693.     function Lock_File_Name(        --| Returns the lock file name
  3694.         Lock_Mode : Lock_Mode_Name  --| Name for unlocked or locked file
  3695.         ) return String;
  3696.  
  3697.     --| Effects:  Returns a name for the lock file.  Lock_Mode determines
  3698.     --| whether the name is for the unlock file or the lock file.
  3699.  
  3700.     --| N/A: Raises, Requires, Modifies
  3701.  
  3702.     ---------------------------------------------------------------------------
  3703.  
  3704.     package body Report_Utilities is
  3705.     --| Provides subprograms to produce reports on dictionary entries.
  3706.  
  3707.         use Text_IO;
  3708.  
  3709.         Output_File : PO.Paginated_File_Handle;  --| Handle for report output
  3710.  
  3711.         package Identifier_Lists is new Lists(
  3712.             ItemType => SS.Screen_String,
  3713.             Equal    => SS.Equal);
  3714.  
  3715.         type Inclusion_Descriptor is
  3716.             record
  3717.                 All_Selected      : Boolean;
  3718.                 --| whether to print all entries of this template type
  3719.                 Identifier_List   : Identifier_Lists.List;
  3720.                 --| the list of identifiers to print for this template type
  3721.             end record;
  3722.  
  3723.         Entries_to_Include : array(TP.Template_Name) of Inclusion_Descriptor
  3724.             := (others => (False, Identifier_Lists.Create));
  3725.         --| array containing information on which entries to print
  3726.  
  3727.         -----------------------------------------------------------------------
  3728.         -- Local subprogram specifications
  3729.         -----------------------------------------------------------------------
  3730.  
  3731.         procedure Parse_Entries(    --| Parses Entries or line from Entry_Name
  3732.             Entry_Text : in String  --| Text to parse
  3733.             );
  3734.  
  3735.         --| Effects: Parses an entry specification either from Entries or from
  3736.         --| a line in file Entry_Name.  To parse successfully, the line should
  3737.         --| have the form:  template-name identifier identifier identifier ...
  3738.         --| Entries_to_Include is updated to reflect which entries were 
  3739.         --| specified in Entry_Text.  Error messages are printed for
  3740.         --| nonexistent template types and nonexistent entries.
  3741.  
  3742.         --| Modifies: Entries_to_Include
  3743.  
  3744.         --| N/A: Raises, Requires
  3745.  
  3746.         -----------------------------------------------------------------------
  3747.  
  3748.         procedure Print_Full_Entry(  --| Produces the full report for an entry
  3749.             Entry_Handle : in Dictionary_Entry_Handle
  3750.                                      --| Handle of entry on which to report
  3751.             );
  3752.  
  3753.         --| Effects:  Prints a full report for the entry specified by 
  3754.         --| Entry_Handle.  All fields of the entry are printed.  Empty 
  3755.         --| fields are replaced by the template label for the field.
  3756.  
  3757.         --| N/A: Raises, Requires, Modifies
  3758.  
  3759.         -----------------------------------------------------------------------
  3760.  
  3761.         procedure Make_Command_File_Entry(  --| Produces command file line
  3762.             Entry_Handle : in Dictionary_Entry_Handle
  3763.                                             --| Handle of entry to put in 
  3764.                                             --| command file
  3765.             );
  3766.  
  3767.         --| Effects:  Prints a command file entry for the entry specified by
  3768.         --| Entry_Handle.  The format of the command file entry is such that
  3769.         --| it may be used as input to the Update_Dictionary tool.  Each entry
  3770.         --| in the command file is of the form: <field-label>field-contents
  3771.  
  3772.         --| N/A: Raises, Requires, Modifies
  3773.  
  3774.         -----------------------------------------------------------------------
  3775.         -- External subprogram bodies
  3776.         -----------------------------------------------------------------------
  3777.  
  3778.         procedure Set_Up_Report(  --| Initializes parameters for reporting
  3779.             Dictionary_Name : in String;  --| Name of dictionary to open
  3780.             Entries         : in String;  --| Entries to report on
  3781.             Entry_Name      : in String   --| File containing entries to report
  3782.             ) is
  3783.             Entry_File : File_Type;        --| File object for entry file
  3784.             Text       : String(1 .. 256); --| Text read from entry file
  3785.             -- arbitrary length
  3786.             Last       : Natural;          --| Last index of Text read
  3787.         begin
  3788.             Open_Dictionary(Dictionary_Name);
  3789.  
  3790.             -- Entry_Name and Entries both null ==> select everything
  3791.             if Entry_Name = "" then
  3792.                 if Entries = "" then
  3793.                     for i in TP.Template_Name loop
  3794.                         Entries_to_Include(i).All_Selected := True;
  3795.                     end loop;
  3796.                 end if;
  3797.             else
  3798.  
  3799.                 -- read and parse entries from Entry_File
  3800.                 Open(Entry_File, In_File, Entry_Name);
  3801.                 while not End_of_File(Entry_File) loop
  3802.                     Get_Line(Entry_File, Text, Last);
  3803.                     Parse_Entries(Text(1 .. Last));
  3804.                 end loop;
  3805.             end if;
  3806.  
  3807.             -- parse Entries parameter
  3808.             if Entries /= "" then
  3809.                 Parse_Entries(Entries);
  3810.             end if;
  3811.  
  3812.         exception
  3813.             when Name_Error | Status_Error | Use_Error =>
  3814.                 Host_Lib.Set_Error;
  3815.                 Put_Line("Error opening file " & Entry_Name & " for input.");
  3816.                 Close_Dictionary;
  3817.                 raise Abort_Report;
  3818.  
  3819.         end Set_Up_Report;
  3820.     
  3821.         -----------------------------------------------------------------------
  3822.  
  3823.         procedure Make_Report(             --| Makes the report
  3824.             Report      : in Report_Name;  --| Which type of report to make
  3825.             Output_Name : in String        --| Name of output file
  3826.             ) is
  3827.             Index_Iter     : IT.Tree_Iter;         --| Index tree iterator
  3828.             Label          : SS.Screen_String;     --| Identifier Label in tree
  3829.             File_Positions : File_Position_Array;  --| Array of file positions
  3830.                                                    --| in tree
  3831.             Temp_Data      : Data_Array;           --| all data for particular
  3832.                                                    --| entry
  3833.         begin
  3834.             if Report = Command_File then
  3835.  
  3836.                 -- don't want to paginate the command file
  3837.                 PO.Create_Paginated_File(
  3838.                     File_Handle => Output_File,
  3839.                     File_Name   => Output_Name,
  3840.                     Header_Size => 0,
  3841.                     Footer_Size => 0,
  3842.                     Page_Size   => 0);
  3843.             else
  3844.                 PO.Create_Paginated_File(
  3845.                     File_Handle => Output_File,
  3846.                     File_Name   => Output_Name);
  3847.                 PO.Set_Header(File_Handle => Output_File, Header_Line => 1,
  3848.                     Header_Text => "Data Dictionary Report Output on ~d at " & 
  3849.                     "~t                 ~p");
  3850.             end if;
  3851.             
  3852.             for Template in TP.Template_Name loop
  3853.                 if not Index_Trees(Template).Initialized then
  3854.                     Read_Index(Template);
  3855.                 end if;
  3856.  
  3857.                 -- don't want to print any headers without anything under them
  3858.                 -- in summary report
  3859.                 if (Report = Summary) and
  3860.  
  3861.                     -- all were selected and there are some in the tree
  3862.                     ((Entries_to_Include(Template).All_Selected and
  3863.                         not IT.Is_Empty(Index_Trees(Template).Tree)) or
  3864.  
  3865.                     -- not all were selected and list of entries isn't empty
  3866.                     not (Entries_to_Include(Template).All_Selected or
  3867.                     Identifier_Lists.IsEmpty(
  3868.                         Entries_to_Include(Template).Identifier_List))) then
  3869.                     PO.Skip_Line(Output_File, 2);
  3870.                     PO.Put_Line(
  3871.                         Output_File,
  3872.                         TP.Template_Name'Image(Template) & " Entries:");
  3873.                     PO.Skip_Line(Output_File);
  3874.                 end if;
  3875.  
  3876.                 -- Iterate over index tree for the Template
  3877.                 Index_Iter := IT.Make_Tree_Iter_In(Index_Trees(Template).Tree);
  3878.                 while IT.More(Index_Iter) loop
  3879.                     IT.Next(Index_Iter, File_Positions, Label);
  3880.         
  3881.                     -- only print it if all were selected or it is in the list
  3882.                     if (Entries_to_Include(Template).All_Selected or
  3883.                         Identifier_Lists.IsInList(
  3884.                             Entries_to_Include(Template).Identifier_List, 
  3885.                             Label)) and then 
  3886.  
  3887.                         -- only print it if file positions are in the index
  3888.                         DIO."/="(
  3889.                             File_Positions(File_Positions'First),
  3890.                             0) then
  3891.                         if Report = Summary then
  3892.                             PO.Put(Output_File, "    ");
  3893.                             PO.Put(Output_File, SS.Value(Label));
  3894.                             PO.Skip_Line(Output_File);
  3895.                         end if;
  3896.                         for i in File_Positions'Range loop
  3897.                             exit when DIO."="(File_Positions(i), 0);
  3898.                             case Report is
  3899.                                 when Summary =>
  3900.         
  3901.                                     -- read overload and put it out
  3902.                                     DIO.Read(
  3903.                                         File => File_Types(Template).Data_File,
  3904.                                         Item => Temp_Data,
  3905.                                         From => File_Positions(i));
  3906.                                     PO.Put(Output_File, "        ");
  3907.                                     PO.Put(
  3908.                                         Output_File,
  3909.                                         SS.Value(Temp_Data(Overload_Index)));
  3910.                                     PO.Skip_Line(Output_File);
  3911.                                 when Full => 
  3912.                                     PO.Skip_Line(Output_File, 2);
  3913.                                     Print_Full_Entry(
  3914.                                         Entry_Handle(Template, Label, i));
  3915.                                 when Command_File =>
  3916.                                     PO.Put_Line(
  3917.                                         Output_File,
  3918.                                         "UPDATE " &
  3919.                                         TP.Template_Name'Image(Template) & 
  3920.                                         " " & SS.Value(Label) & " " &
  3921.                                         Overload_Range'Image(i));
  3922.                                     Make_Command_File_Entry(
  3923.                                         Entry_Handle(Template, Label, i));
  3924.                             end case;
  3925.                         end loop; -- over overloads
  3926.                     end if; -- if it is in the list to include
  3927.                 end loop; -- over identifiers
  3928.             end loop; -- over template_name
  3929.             Close_Dictionary;
  3930.         exception
  3931.             when PO.File_Error =>
  3932.                 Put_Line("Error opening file " & Output_Name & " for output.");
  3933.                 Close_Dictionary;
  3934.                 raise Abort_Report;
  3935.         end Make_Report;
  3936.     
  3937.         -----------------------------------------------------------------------
  3938.         -- Local subprogram bodies
  3939.         -----------------------------------------------------------------------
  3940.  
  3941.         procedure Parse_Entries(    --| Parses Entries or line from Entry_Name
  3942.             Entry_Text : in String  --| Text to parse
  3943.             ) is
  3944.             Invalid_Template_Type : exception;   --| Raised when the given
  3945.                                                  --| template is invalid
  3946.             Line                  : SU.Scanner;  --| String scanner created 
  3947.                                                  --| from Entry_Text to parse
  3948.             Found                 : Boolean;     --| Whether scanner operation
  3949.                                                  --| completed successfully
  3950.             Word                  : SS.Screen_String;
  3951.                                                  --| Word found in scanner 
  3952.                                                  --| operation
  3953.             Template              : TP.Template_Name;
  3954.                                                  --| Template found in 
  3955.                                                  --| Entry_Text
  3956.             Entries_Specified     : Boolean := False;
  3957.  
  3958.         begin
  3959.             declare
  3960.                 Text      : SS.Screen_String;
  3961.                 Truncated : Boolean;
  3962.             begin
  3963.                 SS.Create(Entry_Text, Text, Truncated);
  3964.                 Line := SSU.Make_Scanner(Text);
  3965.                 if Truncated then
  3966.  
  3967.                     -- print warning message
  3968.                     Put_Line(Entry_Text);
  3969.                     Put_Line("truncated to:");
  3970.                     Put_Line(SS.Value(Text));
  3971.                 end if;
  3972.             end;
  3973.  
  3974.             -- Get template
  3975.             SSU.Scan_Word(Line, Found, Word, Skip => True);
  3976.             if Found then
  3977.  
  3978.                 -- check template's validity
  3979.                 begin
  3980.                     Template := TP.Template_Name'Value(SS.Value(Word));
  3981.                 exception
  3982.                     when Constraint_Error =>
  3983.                         raise Invalid_Template_Type;
  3984.                 end;
  3985.  
  3986.             end if;
  3987.  
  3988.             -- Get selected identifiers for this template
  3989.             while SU.More(Line) and Found loop
  3990.                 SSU.Scan_Word(Line, Found, Word, Skip => True);
  3991.                 if Found then
  3992.  
  3993.                     -- some entries were actually requested, although they
  3994.                     -- will not be put on list if they don't exist in 
  3995.                     -- dictionary
  3996.                     Entries_Specified := True;
  3997.                     if not Entry_Exists(Template, Word) then
  3998.  
  3999.                         -- print a warning message to standard error
  4000.                         Put_Line("No dictionary entry for " &
  4001.                                  TP.Template_Name'Image(Template) & " " &
  4002.                                  SS.Value(Word));
  4003.                     else
  4004.                         Identifier_Lists.Attach(
  4005.                             Entries_to_Include(Template).Identifier_List,
  4006.                             Word);
  4007.                     end if;
  4008.                 end if;
  4009.             end loop;
  4010.  
  4011.             if not Entries_Specified then
  4012.  
  4013.                 -- Mark all entries for template type Template as selected
  4014.                 Entries_to_Include(Template).All_Selected := True;
  4015.             end if;
  4016.  
  4017.         exception
  4018.             when Invalid_Template_Type =>
  4019.                 Put_Line("Invalid Template: " & SS.Value(Word));
  4020.  
  4021.         end Parse_Entries;
  4022.     
  4023.         -----------------------------------------------------------------------
  4024.  
  4025.         procedure Print_Full_Entry(  --| Produces the full report for an entry
  4026.             Entry_Handle : in Dictionary_Entry_Handle
  4027.                                      --| Handle of entry on which to report
  4028.             ) is
  4029.             Template      : TP.Template_Name        --| The template type for
  4030.                 := Template_Kind(Entry_Handle);     --| this Entry_Handle
  4031.             Position      : TP.Position_Descriptor  --| "Screen" position of a
  4032.                 := (1, 1);                          --| field
  4033.             Last_Position : TP.Position_Descriptor; --| "Screen" position of 
  4034.                                                     --| previous field
  4035.             New_Lines     : Integer;                --| New_Lines between the
  4036.                                                     --| last and current field
  4037.             Column        : Positive := 1;          --| Current column
  4038.             Blanks        : String(1 .. SS.Max_Screen_Columns) :=
  4039.                 (others => ' ');
  4040.         begin
  4041.             PO.Put(Output_File, SS.Value(TP.Template_Label(Template)));
  4042.  
  4043.             -- loop through all fields and print them out
  4044.             for i in TP.Actual_Field_Number_Range'First ..
  4045.                 TP.Field_Count(Template) loop
  4046.                 Last_Position := Position;
  4047.                 Position := TP.Field_Position(Template, i);
  4048.                 New_Lines := Position.Line - Last_Position.Line;
  4049.                 if New_Lines > 0 then
  4050.                     PO.Skip_Line(Output_File, New_Lines);
  4051.                     Column := 1;
  4052.                 end if;
  4053.                 PO.Put(Output_File, Blanks(1 .. Position.Column - Column));
  4054.                 if TP."="(TP.Field_Mode(Template, i), TP.Static) then
  4055.                     PO.Put(Output_File, SS.Value(TP.Field_Label(Template, i)));
  4056.                     Column := 
  4057.                         Position.Column + TP.Field_Length(Template, i) + 1;
  4058.                 elsif SS.Equal(
  4059.                     Field_Contents(
  4060.                         Entry_Handle,
  4061.                         TP.Variable_Field_Number(Template, i)),
  4062.                     "") then
  4063.                     PO.Put(
  4064.                         Output_File,
  4065.                         "<" & SS.Value(TP.Field_Label(Template, i)) & ">");
  4066.                     Column := Position.Column + 
  4067.                         SS.Length(TP.Field_Label(Template, i)) + 3;
  4068.                 else
  4069.                     PO.Put(
  4070.                         Output_File,
  4071.                         SS.Value(Field_Contents(
  4072.                             Entry_Handle,
  4073.                             TP.Variable_Field_Number(Template, i))));
  4074.                     Column := Position.Column + 
  4075.                         SS.Length(Field_Contents(
  4076.                             Entry_Handle,
  4077.                             TP.Variable_Field_Number(Template, i))) + 1;
  4078.                 end if;
  4079.             end loop;
  4080.             PO.Skip_Line(Output_File);
  4081.         end Print_Full_Entry;
  4082.  
  4083.         -----------------------------------------------------------------------
  4084.  
  4085.         procedure Make_Command_File_Entry(  --| Produces command file entry
  4086.             Entry_Handle : in Dictionary_Entry_Handle
  4087.                                             --| Handle of entry to put in 
  4088.                                             --| command file
  4089.             ) is
  4090.             Template : TP.Template_Name := Template_Kind(Entry_Handle);
  4091.             --| Template-Type for this Entry_Handle
  4092.         begin
  4093.             for i in TP.Variable_Field_Number_Range'First .. 
  4094.                 TP.Variable_Field_Count(Template) loop
  4095.                 PO.Put_Line(
  4096.                     Output_File,
  4097.                     "<" & 
  4098.                     SS.Value(
  4099.                         TP.Field_Label(
  4100.                             Template, TP.Actual_Field_Number(Template, i))) &
  4101.                     ">" &
  4102.                     SS.Value(Field_Contents(Entry_Handle, i)));
  4103.             end loop;
  4104.         end Make_Command_File_Entry;
  4105.  
  4106.         -----------------------------------------------------------------------
  4107.     
  4108.     end Report_Utilities;
  4109.     
  4110.     ---------------------------------------------------------------------------
  4111.     -- External subprogram bodies
  4112.     ---------------------------------------------------------------------------
  4113.  
  4114.     procedure Create_Dictionary(     --| Creates a new dictionary
  4115.         Dictionary_Name : in String  --| Name of dictionary to create
  4116.         ) is
  4117.     begin
  4118.  
  4119.         -- if the dictionary already exists, can't create it again
  4120.         if FM.Is_Directory(Dictionary_Name) then
  4121.             raise Cant_Create_Directory;
  4122.         end if;
  4123.  
  4124.         -- create dictionary directory
  4125.         FM.Create_Directory(Dictionary_Name);
  4126.         for i in TP.Template_Name loop
  4127.  
  4128.             -- create each data file
  4129.             DIO.Create(
  4130.                 File => File_Types(i).Data_File,
  4131.                 Mode => DIO.Inout_File,
  4132.                 Name => FM.Path_Name(
  4133.                     Dictionary_Name,
  4134.                     Data_File_Name(i)));
  4135.             DIO.Close(File_Types(i).Data_File);
  4136.  
  4137.             -- create each index file
  4138.             Text_IO.Create(
  4139.                 File => File_Types(i).Index_File,
  4140.                 Mode => Text_IO.Out_File,
  4141.                 Name => FM.Path_Name(Dictionary_Name, Index_File_Name(i)));
  4142.             Text_IO.Close(File_Types(i).Index_File);
  4143.         end loop;
  4144.  
  4145.         -- create the (unlocked) lock file
  4146.         Text_IO.Create(
  4147.             File => Lock_File,
  4148.             Mode => Text_IO.Out_File,
  4149.             Name => FM.Path_Name(Dictionary_Name, Lock_File_Name(Unlocked)));
  4150.         Text_IO.Close(Lock_File);
  4151.  
  4152.         -- create the version file
  4153.         Text_IO.Create(
  4154.             File => Version_File,
  4155.             Mode => Text_IO.Out_File,
  4156.             Name => FM.Path_Name(Dictionary_Name, "version"));
  4157.         Text_IO.Put_Line(Version_File, DD_Release);
  4158.         Text_IO.Close(Version_File);
  4159.     exception
  4160.         when FM.Create_Error | FM.Parse_Error =>
  4161.             raise Cant_Create_Directory;
  4162.     end Create_Dictionary;
  4163.  
  4164.     ---------------------------------------------------------------------------
  4165.  
  4166.     procedure Open_Dictionary(        --| Opens all dictionary files
  4167.         Dictionary_Name : in String   --| Name of dictionary
  4168.         ) is
  4169.     begin
  4170.         begin
  4171.             if not FM.Is_Directory(Dictionary_Name) then
  4172.                 Host_Lib.Set_Error;
  4173.                 Text_IO.Put_Line(
  4174.                     "Error opening dictionary " & Dictionary_Name & ".");
  4175.                 raise Invalid_Dictionary_File;
  4176.             end if;
  4177.         exception
  4178.             when FM.Parse_Error =>
  4179.                 Host_Lib.Set_Error;
  4180.                 Text_IO.Put_Line(
  4181.                     "Error opening dictionary " & Dictionary_Name & ".");
  4182.                 raise Invalid_Dictionary_File;
  4183.         end;
  4184.         Current_Dict := SS.Unchecked_Create(Dictionary_Name);
  4185.  
  4186.         -- try to unlock the dictionary.  If this fails, raise exceptions
  4187.         begin
  4188.             FM.Rename(
  4189.                 FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Unlocked)),
  4190.                 FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Locked)));
  4191.         exception
  4192.             when others => 
  4193.  
  4194.                 -- check for existence of locked lock file
  4195.                 declare
  4196.                     Lock_File : Text_IO.File_Type;
  4197.                 begin
  4198.                     begin
  4199.                         Text_IO.Open(
  4200.                             File => Lock_File,
  4201.                             Mode => Text_IO.In_File, 
  4202.                             Name =>
  4203.                                 FM.Path_Name(
  4204.                                     SS.Value(Current_Dict), 
  4205.                                     Lock_File_Name(Locked)));
  4206.                     exception
  4207.                         when Text_IO.Name_Error =>
  4208.                             raise Lock_is_Missing;
  4209.                     end;
  4210.                     Text_IO.Close(Lock_File);
  4211.                     raise Dictionary_Locked;
  4212.                 end;
  4213.         end;
  4214.  
  4215.         for i in TP.Template_Name loop
  4216.             begin
  4217.                 DIO.Open(
  4218.                     File => File_Types(i).Data_File,
  4219.                     Mode => DIO.Inout_File,
  4220.                     Name => FM.Path_Name(
  4221.                         SS.Value(Current_Dict),
  4222.                         Data_File_Name(i)));
  4223.             exception
  4224.                 when DIO.Name_Error =>
  4225.                     Host_Lib.Set_Error;
  4226.                     Text_IO.Put_Line(
  4227.                         "Dictionary data file for " & 
  4228.                         TP.Template_Name'Image(i) & " does not exist.");
  4229.                     Close_Dictionary;
  4230.                     raise Data_File_Error;
  4231.                 when DIO.Use_Error | DIO.Status_Error =>
  4232.                     Host_Lib.Set_Error;
  4233.                     Text_IO.Put_Line(
  4234.                         "Dictionary data file for " &
  4235.                         TP.Template_Name'Image(i) & 
  4236.                         " cannot be opened.");
  4237.                     Text_IO.Put_Line(
  4238.                         "Check protections and that versions of dictionary " &
  4239.                         "and tool are compatible.");
  4240.                     Close_Dictionary;
  4241.                     raise Data_File_Error;
  4242.             end;
  4243.         end loop;
  4244.     end Open_Dictionary;
  4245.  
  4246.     ---------------------------------------------------------------------------
  4247.  
  4248.     procedure Close_Dictionary is
  4249.     begin
  4250.         if SS.Equal(Current_Dict, "") then
  4251.             raise No_Dictionary_File;
  4252.         end if;
  4253.         for i in TP.Template_Name loop
  4254.             if DIO.Is_Open(File => File_Types(i).Data_File) then
  4255.                 DIO.Close(File => File_Types(i).Data_File);
  4256.             end if;
  4257.             if Index_Trees(i).Initialized then
  4258.                 Write_Index(i);
  4259.             end if;
  4260.         end loop;
  4261.  
  4262.         -- rename the lock file back to unlocked status
  4263.         FM.Rename(
  4264.             FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Locked)), 
  4265.             FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Unlocked)));
  4266.     exception
  4267.         when Index_File_Error =>
  4268.  
  4269.             -- rename the lock file back to unlocked status
  4270.             FM.Rename(
  4271.                 FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Locked)), 
  4272.                 FM.Path_Name(SS.Value(Current_Dict), Lock_File_Name(Unlocked)));
  4273.         
  4274.     end Close_Dictionary;
  4275.  
  4276.     ---------------------------------------------------------------------------
  4277.  
  4278.     function New_Entry_Handle(       --| Returns handle to new dictionary entry
  4279.         Template : TP.Template_Name  --| Template type to associate with entry
  4280.         ) return Dictionary_Entry_Handle is
  4281.     begin
  4282.         if SS.Equal(Current_Dict, "") then
  4283.             raise No_Dictionary_File;
  4284.         end if;
  4285.  
  4286.         if not Index_Trees(Template).Initialized then
  4287.             Read_Index(Template);
  4288.         end if;
  4289.  
  4290.         return new Dictionary_Entry_Descriptor'(
  4291.             Template => Template,
  4292.             Data => (others => SS.Create("")),
  4293.             Read_From => 0);
  4294.     end New_Entry_Handle;
  4295.  
  4296.     ---------------------------------------------------------------------------
  4297.  
  4298.     function Entry_Handle(              --| Returns handle to existing entry
  4299.         Template   : TP.Template_Name;  --| Template type of entry
  4300.         Identifier : SS.Screen_String;  --| Entry identifier
  4301.         Occurrence : Overload_Range     --| Occurrence of Entry_Handle to 
  4302.             := 1                        --| retrieve.
  4303.         ) return Dictionary_Entry_Handle is
  4304.         File_Positions : File_Position_Array;  --| Array of file positions for
  4305.                                                --| template, identifier pair
  4306.         Temp_Data      : Data_Array;           --| Data read from data file
  4307.     begin
  4308.         if SS.Equal(Current_Dict, "") then
  4309.             raise No_Dictionary_File;
  4310.         end if;
  4311.  
  4312.         if not Index_Trees(Template).Initialized then
  4313.             Read_Index(Template);
  4314.         end if;
  4315.  
  4316.         if not IT.Is_Label_In_Tree(Index_Trees(Template).Tree, Identifier) then
  4317.             raise No_Such_Dictionary_Entry;
  4318.         end if;
  4319.  
  4320.         -- if the identifier is in the index tree, get the list of file
  4321.         -- positions from the tree
  4322.         File_Positions :=
  4323.             IT.Fetch_Value(Index_Trees(Template).Tree, Identifier);
  4324.  
  4325.         if DIO."="(File_Positions(Occurrence), 0) then
  4326.             raise No_Such_Occurrence;
  4327.         end if;
  4328.  
  4329.         -- Read in data for handle
  4330.         DIO.Read(
  4331.             File => File_Types(Template).Data_File,
  4332.             Item => Temp_Data,
  4333.             From => File_Positions(Occurrence));
  4334.  
  4335.         return new Dictionary_Entry_Descriptor'(
  4336.             Template => Template,
  4337.             Data => Temp_Data,
  4338.             Read_From => File_Positions(Occurrence));
  4339.     end Entry_Handle;
  4340.  
  4341.     ---------------------------------------------------------------------------
  4342.  
  4343.     function Entry_Exists(  --| Determines whether an entry exists
  4344.         Template    : TP.Template_Name;  --| Template type of entry
  4345.         Identifier  : SS.Screen_String;  --| Entry identifier
  4346.         Occurrence  : Overload_Range     --| Occurrence of template, identifier
  4347.             := 1
  4348.         ) return Boolean is
  4349.     begin
  4350.         if SS.Equal(Current_Dict, "") then
  4351.             raise No_Dictionary_File;
  4352.         end if;
  4353.  
  4354.         if not Index_Trees(Template).Initialized then
  4355.             Read_Index(Template);
  4356.         end if;
  4357.  
  4358.         -- Label must be in tree and file position list non-empty at
  4359.         -- location Occurrence for Entry_Exists to be true
  4360.         return 
  4361.             (IT.Is_Label_In_Tree(
  4362.                 Index_Trees(Template).Tree, Identifier)) and then
  4363.             DIO."/="(
  4364.                 IT.Fetch_Value(
  4365.                     Index_Trees(Template).Tree, Identifier)(Occurrence),
  4366.                 0);
  4367.     end Entry_Exists;
  4368.  
  4369.     ---------------------------------------------------------------------------
  4370.  
  4371.     function Unique_Entry(  --| Determines whether an entry is unique
  4372.         Template     : TP.Template_Name;  --| Template type of entry
  4373.         Identifier   : SS.Screen_String   --| Entry identifier
  4374.         ) return Boolean is
  4375.     begin
  4376.  
  4377.         if SS.Equal(Current_Dict, "") then
  4378.             raise No_Dictionary_File;
  4379.         end if;
  4380.  
  4381.         if not Index_Trees(Template).Initialized then
  4382.             Read_Index(Template);
  4383.         end if;
  4384.  
  4385.         if not IT.Is_Label_In_Tree(Index_Trees(Template).Tree, Identifier) then
  4386.             raise No_Such_Dictionary_Entry;
  4387.         end if;
  4388.  
  4389.         return DIO."="(
  4390.             IT.Fetch_Value(
  4391.                 Index_Trees(Template).Tree, 
  4392.                 Identifier)(Overload_Range'First + 1),
  4393.             0);
  4394.  
  4395.     end Unique_Entry;
  4396.  
  4397.     ---------------------------------------------------------------------------
  4398.  
  4399.     function Overloads(                --| Returns overload fields for an entry
  4400.         Template     : TP.Template_Name;  --| Template type of entry
  4401.         Identifier   : SS.Screen_String   --| Entry identifier
  4402.         ) return Overload_Array is
  4403.         File_Positions : File_Position_Array;
  4404.         Temp_Data      : Data_Array;
  4405.         Temp_Array     : Overload_Array := (others => SS.Create(""));
  4406.     begin
  4407.         if SS.Equal(Current_Dict, "") then
  4408.             raise No_Dictionary_File;
  4409.         end if;
  4410.  
  4411.         if not Index_Trees(Template).Initialized then
  4412.             Read_Index(Template);
  4413.         end if;
  4414.  
  4415.         if not IT.Is_Label_In_Tree(Index_Trees(Template).Tree, Identifier) then
  4416.             raise No_Such_Dictionary_Entry;
  4417.         end if;
  4418.  
  4419.         File_Positions := 
  4420.             IT.Fetch_Value(Index_Trees(Template).Tree, Identifier);
  4421.         for i in Overload_Range loop
  4422.             exit when DIO."="(File_Positions(i), 0);
  4423.  
  4424.             -- Read in data for handle
  4425.             DIO.Read(
  4426.                 File => File_Types(Template).Data_File,
  4427.                 Item => Temp_Data,
  4428.                 From => File_Positions(i));
  4429.             Temp_Array(i) := Temp_Data(Overload_Index);
  4430.         end loop;
  4431.  
  4432.         return Temp_Array;
  4433.     end Overloads;
  4434.  
  4435.     ---------------------------------------------------------------------------
  4436.  
  4437.     procedure Delete_Entry(             --| Deletes dictionary entry
  4438.         Entry_Handle : Dictionary_Entry_Handle  --| Entry to delete
  4439.         ) is
  4440.     begin
  4441.         if (Entry_Handle = null) then 
  4442.             raise Invalid_Entry_Handle;
  4443.         end if;
  4444.         if DIO."="(Entry_Handle.Read_From, 0) then 
  4445.             raise No_Such_Dictionary_Entry;
  4446.         end if;
  4447.  
  4448.         -- Delete the file position for this entry from the file position 
  4449.         -- list in the tree.
  4450.         IT.Store_Value(
  4451.             Index_Trees(Entry_Handle.Template).Tree,
  4452.             Entry_Handle.Data(Identifier_Index),
  4453.             Delete_File_Position(
  4454.                 IT.Fetch_Value(
  4455.                     Index_Trees(Entry_Handle.Template).Tree,
  4456.                     Entry_Handle.Data(Identifier_Index)),
  4457.                 Entry_Handle.Read_From));
  4458.  
  4459.         -- put the index it was read from on the free list and set its 
  4460.         -- read_from to 0.
  4461.         FL.Attach(
  4462.             Entry_Handle.Read_From,
  4463.             Position_Free_Lists(Entry_Handle.Template));
  4464.  
  4465.         -- write the index out to the index file to keep index file in synch
  4466.         -- with the deletion which just occurred
  4467.         Write_Index(Entry_Handle.Template);
  4468.         Entry_Handle.Read_From := 0;
  4469.     end Delete_Entry;
  4470.  
  4471.     ---------------------------------------------------------------------------
  4472.  
  4473.     procedure Create_Entry(                      --| Creates a new entry
  4474.         Entry_Handle : Dictionary_Entry_Handle   --| Entry to create
  4475.         ) is
  4476.         Next_Position : DIO.Positive_Count;      --| Next available file 
  4477.                                                  --| position for writing.
  4478.     begin
  4479.         if SS.Equal(Current_Dict, "") then
  4480.             raise No_Dictionary_File;
  4481.         end if;
  4482.         if Entry_Handle = null then
  4483.             raise Invalid_Entry_Handle;
  4484.         end if;
  4485.         if SS.Equal(Entry_Handle.Data(Identifier_Index), "") then
  4486.             raise Null_Identifier;
  4487.         end if;
  4488.         if IT.Is_Label_In_Tree(
  4489.             Index_Trees(Entry_Handle.Template).Tree,
  4490.             Entry_Handle.Data(Identifier_Index)) then
  4491.  
  4492.             -- Can't create entry if no <overload> field exists when there is
  4493.             -- another dictionary item with the same name.
  4494.             if SS.Equal(Entry_Handle.Data(Overload_Index), "") and
  4495.  
  4496.                 -- check that the list of file positions isn't empty (i.e. that
  4497.                 -- all other instances of this identifier have been deleted)
  4498.                 DIO."/="(
  4499.                     IT.Fetch_Value(
  4500.                         Index_Trees(Entry_Handle.Template).Tree, 
  4501.                         Entry_Handle.Data(Identifier_Index))
  4502.                     (Overload_Range'First),
  4503.                     0) then
  4504.                 raise No_Overload_Field;
  4505.             end if;
  4506.  
  4507.             -- If the maximum number of overloads already exist, raise error
  4508.             if DIO."/="(
  4509.                 IT.Fetch_Value(
  4510.                     Index_Trees(Entry_Handle.Template).Tree, 
  4511.                     Entry_Handle.Data(Identifier_Index))
  4512.                 (Max_Overloads),
  4513.                 0) then
  4514.                 raise Too_Many_Overloads;
  4515.             end if;
  4516.         else
  4517.  
  4518.             -- if name isn't already in the tree, have to call insert_node
  4519.             -- and start a new list of file positions
  4520.             IT.Insert_Node(
  4521.                 Index_Trees(Entry_Handle.Template).Tree, 
  4522.                 Entry_Handle.Data(Identifier_Index),
  4523.                 (others => 0));
  4524.         end if;
  4525.  
  4526.         -- Calculate the next free position for writing.  If position is 
  4527.         -- available on the free list, write the item there; otherwise write 
  4528.         -- to the nth position, where n is equal to (current size + 1).
  4529.         if not FL.IsEmpty(
  4530.             Position_Free_Lists(Entry_Handle.Template)) then
  4531.             Next_Position := FL.FirstValue(
  4532.                 Position_Free_Lists(Entry_Handle.Template));
  4533.  
  4534.             -- delete from free list for this template type
  4535.             FL.DeleteHead(
  4536.                 Position_Free_Lists(Entry_Handle.Template));
  4537.         else
  4538.             Next_Position := DIO.Positive_Count'Succ(
  4539.                 DIO.Size(File_Types(Entry_Handle.Template).Data_File));
  4540.         end if;
  4541.         DIO.Write(
  4542.             File => File_Types(Entry_Handle.Template).Data_File,
  4543.             Item => Entry_Handle.Data,
  4544.             To   => Next_Position);
  4545.  
  4546.         -- Add Next_Position to the file position list in the tree
  4547.         IT.Store_Value(
  4548.             Index_Trees(Entry_Handle.Template).Tree,
  4549.             Entry_Handle.Data(Identifier_Index),
  4550.             Attach_File_Position(
  4551.                 IT.Fetch_Value(
  4552.                     Index_Trees(Entry_Handle.Template).Tree, 
  4553.                     Entry_Handle.Data(Identifier_Index)),
  4554.                 Next_Position));
  4555.  
  4556.         -- write the index out to the index file to keep index file in synch
  4557.         -- with data file
  4558.         Write_Index(Entry_Handle.Template);
  4559.  
  4560.         Entry_Handle.Read_From := Next_Position;
  4561.     end Create_Entry;
  4562.  
  4563.     ---------------------------------------------------------------------------
  4564.  
  4565.     procedure Update_Entry(  --| Updates an existing dictionary entry
  4566.         Entry_Handle : Dictionary_Entry_Handle
  4567.                              --| Handle referencing entry to update
  4568.         ) is
  4569.         Compare_Data : Data_Array;  --| array to compare identifier field 
  4570.     begin
  4571.         if SS.Equal(Current_Dict, "") then
  4572.             raise No_Dictionary_File;
  4573.         end if;
  4574.         if Entry_Handle = null then
  4575.             raise Invalid_Entry_Handle;
  4576.         end if;
  4577.         if SS.Equal(Entry_Handle.Data(Identifier_Index), "") then
  4578.             raise Null_Identifier;
  4579.         end if;
  4580.  
  4581.         -- Can't "update" an entry that was not read from the dictionary (or
  4582.         -- was deleted from the dictionary)
  4583.         if DIO."="(Entry_Handle.Read_From, 0) then
  4584.             raise Cant_Update_New_Entry;
  4585.         end if;
  4586.  
  4587.         -- Can't allow empty <overload> field if it is not the only one.
  4588.         if IT.Is_Label_In_Tree(
  4589.             Index_Trees(Entry_Handle.Template).Tree,
  4590.             Entry_Handle.Data(Identifier_Index)) and then
  4591.  
  4592.             SS.Equal(Entry_Handle.Data(Overload_Index), "") and then
  4593.  
  4594.             -- check that there are no more than one instance of this
  4595.             -- identifier
  4596.             DIO."/="(
  4597.                 IT.Fetch_Value(
  4598.                     Index_Trees(Entry_Handle.Template).Tree, 
  4599.                     Entry_Handle.Data(Identifier_Index))
  4600.                 (Overload_Range'First + 1),
  4601.                 0) then
  4602.             raise No_Overload_Field;
  4603.         end if;
  4604.  
  4605.         -- Compare identifier fields.  
  4606.         -- if the identifier field is different, the index tree must
  4607.         -- be updated
  4608.         DIO.Read(
  4609.             File => File_Types(Entry_Handle.Template).Data_File,
  4610.             Item => Compare_Data,
  4611.             From => Entry_Handle.Read_From);
  4612.         if not SS.Equal(
  4613.             Compare_Data(Identifier_Index),
  4614.             Entry_Handle.Data(Identifier_Index)) then
  4615.  
  4616.             -- see whether new identifier is in tree.  If so, check that it
  4617.             -- doesn't already have the maximum overloads before deleting
  4618.             -- old identifier from tree
  4619.             if IT.Is_Label_In_Tree(
  4620.                 Index_Trees(Entry_Handle.Template).Tree,
  4621.                 Entry_Handle.Data(Identifier_Index)) and then
  4622.                 DIO."/="(
  4623.                     IT.Fetch_Value(
  4624.                         Index_Trees(Entry_Handle.Template).Tree, 
  4625.                         Entry_Handle.Data(Identifier_Index))
  4626.                     (Max_Overloads),
  4627.                     0) then
  4628.                 raise Too_Many_Overloads;
  4629.             end if;
  4630.  
  4631.             -- delete the file position from the old identifier's list and
  4632.             -- call Create_Entry for the new identifier
  4633.             IT.Store_Value(
  4634.                 Index_Trees(Entry_Handle.Template).Tree,
  4635.                 Compare_Data(Identifier_Index),
  4636.                 Delete_File_Position(
  4637.                     IT.Fetch_Value(
  4638.                         Index_Trees(Entry_Handle.Template).Tree,
  4639.                         Compare_Data(Identifier_Index)),
  4640.                     Entry_Handle.Read_From));
  4641.             Create_Entry(Entry_Handle);
  4642.         else
  4643.             -- Write the item to the place it was read from.
  4644.             DIO.Write(
  4645.                 File => File_Types(Entry_Handle.Template).Data_File,
  4646.                 Item => Entry_Handle.Data,
  4647.                 To   => Entry_Handle.Read_From);
  4648.  
  4649.             -- index doesn't change, so no need to write the index file
  4650.         end if;
  4651.     end Update_Entry;
  4652.  
  4653.     ---------------------------------------------------------------------------
  4654.  
  4655.     procedure Update_Field(                      --| Updates a field in entry
  4656.         Entry_Handle : Dictionary_Entry_Handle;  --| Entry to update
  4657.         Field_Number : TP.Variable_Field_Number_Range;
  4658.                                                  --| Which field to update
  4659.         New_Contents : SS.Screen_String          --| new contents of field
  4660.         ) is
  4661.     begin
  4662.         if Entry_Handle = null then
  4663.             raise Invalid_Entry_Handle;
  4664.         end if;
  4665.         if TP.">"(
  4666.             Field_Number, 
  4667.             TP.Variable_Field_Count(Entry_Handle.Template)) then
  4668.             raise Field_Not_Found;
  4669.         end if;
  4670.         Entry_Handle.Data(Field_Number) := New_Contents;
  4671.     end Update_Field;
  4672.  
  4673.     ---------------------------------------------------------------------------
  4674.  
  4675.     function Field_Contents(         --| Returns the contents of a field
  4676.         Entry_Handle : Dictionary_Entry_Handle;
  4677.                                      --| Entry from which to get field contents
  4678.         Field_Number : TP.Variable_Field_Number_Range
  4679.                                      --| Which field to retrieve
  4680.         ) return SS.Screen_String is
  4681.     begin
  4682.         if Entry_Handle = null then
  4683.             raise Invalid_Entry_Handle;
  4684.         end if;
  4685.         if TP.">"(
  4686.             Field_Number,
  4687.             TP.Variable_Field_Count(Entry_Handle.Template)) then
  4688.             raise Field_Not_Found;
  4689.         end if;
  4690.         return Entry_Handle.Data(Field_Number);
  4691.     end Field_Contents;
  4692.  
  4693.     ---------------------------------------------------------------------------
  4694.  
  4695.     function Template_Kind(          --| Returns the template type for handle
  4696.         Entry_Handle : Dictionary_Entry_Handle
  4697.                                      --| Entry from which to get template
  4698.         ) return TP.Template_Name is
  4699.     begin
  4700.         if Entry_Handle = null then
  4701.             raise Invalid_Entry_Handle;
  4702.         end if;
  4703.         return Entry_Handle.Template;
  4704.     end Template_Kind;
  4705.  
  4706.     ---------------------------------------------------------------------------
  4707.     -- Local subprogram bodies
  4708.     ---------------------------------------------------------------------------
  4709.  
  4710.     procedure Read_Index(Template : in TP.Template_Name) is
  4711.         File_Position  : DIO.Count; --| Position read from file position list
  4712.         Node_Label     : String(1 .. SS.Length_Range'Last);
  4713.                                     --| Identifier read from index file
  4714.         Last           : Natural;   --| Length of Node_Label
  4715.         File_Positions : File_Position_Array;
  4716.                                     --| Array being built to put into tree
  4717.     begin
  4718.         if SS.Equal(Current_Dict, "") then
  4719.             raise No_Dictionary_File;
  4720.         end if;
  4721.         begin
  4722.             Text_IO.Open(
  4723.                 File => File_Types(Template).Index_File,
  4724.                 Mode => Text_IO.In_File,
  4725.                 Name => FM.Path_Name(
  4726.                     SS.Value(Current_Dict),
  4727.                     Index_File_Name(Template)));
  4728.         exception
  4729.             when Text_IO.Name_Error =>
  4730.                 Host_Lib.Set_Error;
  4731.                 Text_IO.Put_Line(
  4732.                     "Dictionary index file for " & 
  4733.                      TP.Template_Name'Image(Template) & " does not exist.");
  4734.                 Close_Dictionary;
  4735.                 raise Index_File_Error;
  4736.             when Text_IO.Use_Error | Text_IO.Status_Error =>
  4737.                 Host_Lib.Set_Error;
  4738.                 Text_IO.Put_Line(
  4739.                     "Dictionary index file for " &
  4740.                     TP.Template_Name'Image(Template) & 
  4741.                     " cannot be opened: check protections.");
  4742.                 Close_Dictionary;
  4743.                 raise Index_File_Error;
  4744.         end;
  4745.  
  4746.         -- read in free list
  4747.         while not Text_IO.End_of_Line(File_Types(Template).Index_File) loop
  4748.             Int_IO.Get(File_Types(Template).Index_File, File_Position);
  4749.  
  4750.             -- check that it isn't just a placeholder
  4751.             if DIO."/="(File_Position, 0) then
  4752.                 FL.Attach(Position_Free_Lists(Template), File_Position);
  4753.             end if;
  4754.         end loop;
  4755.         Text_IO.Skip_Line(File_Types(Template).Index_File);
  4756.  
  4757.         -- Read in tree
  4758.         while not Text_IO.End_Of_File(File_Types(Template).Index_File) loop
  4759.             Text_IO.Get_Line(
  4760.                 File => File_Types(Template).Index_File,
  4761.                 Item => Node_Label,
  4762.                 Last => Last);
  4763.  
  4764.             -- reinitialize File_Positions
  4765.             File_Positions := (others => 0);
  4766.             for i in Overload_Range loop
  4767.                 exit when Text_IO.End_Of_Line(File_Types(Template).Index_File);
  4768.                 Int_IO.Get(File_Types(Template).Index_File, File_Positions(i));
  4769.             end loop;
  4770.             Text_IO.Skip_Line(File_Types(Template).Index_File);
  4771.             IT.Insert_Node(
  4772.                 Index_Trees(Template).Tree, 
  4773.                 SS.Create(Node_Label(1 .. Last)),
  4774.                 File_Positions);
  4775.         end loop;
  4776.         Index_Trees(Template).Initialized := True;
  4777.         Text_IO.Close(File_Types(Template).Index_File);
  4778.     end Read_Index;
  4779.  
  4780.     ---------------------------------------------------------------------------
  4781.  
  4782.     procedure Write_Index(Template : in TP.Template_Name) is
  4783.         Count_Iter     : FL.ListIter :=       --| File position iterator
  4784.             FL.MakeListIter(Position_Free_Lists(Template));
  4785.         Index_Iter     : IT.Tree_Iter :=      --| Index tree iterator
  4786.             IT.Make_Tree_Iter_Pre(Index_Trees(Template).Tree);
  4787.         Label          : SS.Screen_String;    --| Label in list
  4788.         File_Positions : File_Position_Array; --| Array of file positions
  4789.     begin
  4790.         if SS.Equal(Current_Dict, "") then
  4791.             raise No_Dictionary_File;
  4792.         end if;
  4793.         begin
  4794.             Text_IO.Open(
  4795.                 File => File_Types(Template).Index_File,
  4796.                 Mode => Text_IO.Out_File,
  4797.                 Name => FM.Path_Name(
  4798.                     SS.Value(Current_Dict),
  4799.                     Index_File_Name(Template)));
  4800.         exception
  4801.             when Text_IO.Name_Error =>
  4802.                 Host_Lib.Set_Error;
  4803.                 Text_IO.Put_Line(
  4804.                     "Dictionary index file for " & 
  4805.                      TP.Template_Name'Image(Template) & " does not exist.");
  4806.                 raise Index_File_Error;
  4807.             when Text_IO.Use_Error | Text_IO.Status_Error =>
  4808.                 Host_Lib.Set_Error;
  4809.                 Text_IO.Put_Line(
  4810.                     "Dictionary index file for " &
  4811.                     TP.Template_Name'Image(Template) & 
  4812.                     " cannot be opened: check protections.");
  4813.                 raise Index_File_Error;
  4814.         end;
  4815.  
  4816.         -- If free list is empty, write out zero as a place holder
  4817.         if FL.IsEmpty(Position_Free_Lists(Template)) then
  4818.             Int_IO.Put(File_Types(Template).Index_File, 0);
  4819.         else
  4820.  
  4821.             -- Iterate over free list and write it out on one line
  4822.             while FL.More(Count_Iter) loop
  4823.                 Int_IO.Put(
  4824.                     File_Types(Template).Index_File, 
  4825.                     FL.CellValue(Count_Iter));
  4826.                 FL.Forward(Count_Iter);
  4827.             end loop;
  4828.         end if;
  4829.         Text_IO.New_Line(File_Types(Template).Index_File);
  4830.  
  4831.         -- Iterate over index tree and write out tree in the form:
  4832.         -- node_identifier
  4833.         -- position position position ... 
  4834.         -- node_identifier
  4835.         -- position position position ... 
  4836.         -- etc.
  4837.  
  4838.         while IT.More(Index_Iter) loop
  4839.             IT.Next(Index_Iter, File_Positions, Label);
  4840.  
  4841.             -- don't put it if file position list is empty (i.e. all with
  4842.             -- that name have been deleted)
  4843.             if DIO."/="(File_Positions(Overload_Range'First), 0) then
  4844.                 Text_IO.Put_Line(
  4845.                     File_Types(Template).Index_File, 
  4846.                     SS.Value(Label));
  4847.                 for i in Overload_Range loop
  4848.                     exit when DIO."="(File_Positions(i), 0);
  4849.                     Int_IO.Put(
  4850.                         File_Types(Template).Index_File, 
  4851.                         File_Positions(i));
  4852.                 end loop;
  4853.                 Text_IO.New_Line(File_Types(Template).Index_File);
  4854.             end if;
  4855.         end loop;
  4856.         Text_IO.Close(File_Types(Template).Index_File);
  4857.     end Write_Index;
  4858.  
  4859.     ---------------------------------------------------------------------------
  4860.  
  4861.     function Attach_File_Position(  --| Adds a file position to the array
  4862.         File_Positions : in File_Position_Array; 
  4863.                                     --| Array of file positions
  4864.         Item           : DIO.Positive_Count
  4865.                                     --| File position to attach
  4866.         ) return File_Position_Array is
  4867.         Temp_File_Positions : File_Position_Array := 
  4868.                                     --| return value being built up
  4869.             File_Positions;
  4870.         Index               : Overload_Range := 
  4871.                                     --| Index to iterate over array
  4872.             Overload_Range'First;
  4873.     begin
  4874.         if DIO."/="(File_Positions(File_Position_Array'Last), 0) then
  4875.             raise Too_Many_Overloads;
  4876.         end if;
  4877.         while DIO."/="(File_Positions(Index), 0) loop
  4878.             Index := Index + 1;
  4879.         end loop;
  4880.         Temp_File_Positions(Index) := Item;
  4881.         return Temp_File_Positions;
  4882.     end Attach_File_Position;
  4883.  
  4884.     ---------------------------------------------------------------------------
  4885.  
  4886.     function Delete_File_Position(  --| Deletes a file position from the array
  4887.         File_Positions : in File_Position_Array; 
  4888.                                      --| Array of file positions
  4889.         Item           : DIO.Positive_Count
  4890.                                      --| File position to delete
  4891.         ) return File_Position_Array is
  4892.         Temp_File_Positions : File_Position_Array := 
  4893.                                     --| return value being built up
  4894.             File_Positions;
  4895.         Index               : Positive := 
  4896.                                     --| Index to iterate over array
  4897.             1;
  4898.     begin
  4899.  
  4900.         -- Find index of item to delete
  4901.         while Index in File_Position_Array'Range loop
  4902.             exit when DIO."="(File_Positions(Index), Item);
  4903.             Index := Index + 1;
  4904.         end loop;
  4905.         if not (Index in File_Position_Array'Range) then
  4906.             raise No_Such_Occurrence;
  4907.         end if;
  4908.  
  4909.         -- special case if item to be deleted is last item
  4910.         if Index = File_Position_Array'Last then
  4911.             Temp_File_Positions(Index) := 0;
  4912.         else
  4913.  
  4914.             -- Do slice assignments to delete the item
  4915.             Temp_File_Positions(Index .. File_Position_Array'Last - 1) :=
  4916.                 File_Positions(Index + 1 .. File_Position_Array'Last);
  4917.             Temp_File_Positions(File_Position_Array'Last) := 0;
  4918.         end if;
  4919.         return Temp_File_Positions;
  4920.  
  4921.     end Delete_File_Position;
  4922.  
  4923.     ---------------------------------------------------------------------------
  4924.  
  4925.     function Data_File_Name(  --| Returns the data file name for a template
  4926.         Template : TP.Template_Name
  4927.         ) return String is
  4928.     begin
  4929.         return TP.Template_Name'Image(Template)
  4930.             (1 .. TP.Template_Name'Image(Template)'Last - 5) & ".DAT";
  4931.     end Data_File_Name;
  4932.  
  4933.     ---------------------------------------------------------------------------
  4934.  
  4935.     function Index_File_Name(  --| Returns the index file name for a template
  4936.         Template : TP.Template_Name
  4937.         ) return String is
  4938.     begin
  4939.         return TP.Template_Name'Image(Template)
  4940.             (1 .. TP.Template_Name'Image(Template)'Last - 5) & ".INX";
  4941.     end Index_File_Name;
  4942.  
  4943.     ---------------------------------------------------------------------------
  4944.  
  4945.     function Lock_File_Name(        --| Returns the lock file name
  4946.         Lock_Mode : Lock_Mode_Name  --| Name for unlocked or locked file
  4947.         ) return String is
  4948.     begin
  4949.         case Lock_Mode is
  4950.             when Unlocked =>
  4951.                 return "UNLOCKED.LCK";
  4952.             when Locked =>
  4953.                 return "LOCKED.LCK";
  4954.         end case;
  4955.     end Lock_File_Name;
  4956.  
  4957.     ---------------------------------------------------------------------------
  4958.  
  4959. end Dictionary_Manager;
  4960.  
  4961. -------------------------------------------------------------------------------
  4962. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4963. --UPDATE.BDY
  4964. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  4965. with Text_IO; use Text_IO;
  4966. with Screen_Strings;
  4967. with String_Utilities;
  4968. with Dictionary_Manager;
  4969. with Templates;
  4970. -------------------------------------------------------------------------------
  4971. package body Update is  --| Update command processor
  4972.  
  4973.     package SS renames Screen_Strings;
  4974.     package SU renames String_Utilities;
  4975.     package DM renames Dictionary_Manager;
  4976.     package TP renames Templates;
  4977.  
  4978.     package SSU is new SU.Generic_String_Utilities(
  4979.         Generic_String_Type => SS.Screen_String,
  4980.         To_Generic => SS.Unchecked_Create,
  4981.         From_Generic => SS.Value);
  4982.  
  4983.     package Count_IO is new Text_IO.Integer_IO(Count);
  4984.  
  4985.     Missing_Template         : exception;  --| Raised when Template is missing
  4986.                                            --| from a command which requires it
  4987.     Invalid_Template         : exception;  --| Raised when Template given is
  4988.                                            --| not one of the valid templates
  4989.     Missing_Identifier       : exception;  --| Raised when identifier is 
  4990.                                            --| missing from a command which 
  4991.                                            --| requires it
  4992.     Invalid_Occurrence       : exception;  --| Raised when Occurrence given is 
  4993.                                            --| invalid
  4994.     Too_Many_Parameters      : exception;  --| Raised when extra parameters 
  4995.                                            --| appear on a command line
  4996.     Entry_Doesnt_Exist       : exception;  --| Raised when attempt is made to 
  4997.                                            --| refer to an entry which doesn't
  4998.                                            --| exist
  4999.     Occurrence_Doesnt_Exist  : exception;  --| Raised when attempt is made to 
  5000.                                            --| to an occurrence which doesn't
  5001.                                            --| exist
  5002.     Entry_Isnt_Unique        : exception;  --| Raised when attempt is made to 
  5003.                                            --| refer to a non-unique entry
  5004.                                            --| without specifying an occurrence
  5005.  
  5006.     Identifier_Index             : constant TP.Variable_Field_Number_Range :=
  5007.         TP.Variable_Field_Number_Range'First;
  5008.     --| The first (variable) field in a template is defined as the identifier 
  5009.     --| field
  5010.  
  5011.     Overload_Index               : constant TP.Variable_Field_Number_Range :=
  5012.         TP."+"(Identifier_Index, 1);
  5013.     --| The second (variable) field in a template is defined as the overload 
  5014.     --| field
  5015.  
  5016.     Opening_Field_Delimiter      : constant Character := '<';
  5017.     Closing_Field_Delimiter      : constant Character := '>';
  5018.     Command_File                 : File_Type;   --| Handle for the command file
  5019.     Current_File_Name            : SS.Screen_String;
  5020.                                                 --| Command file name
  5021.     Current_Line                 : SU.Scanner   --| Current line read from 
  5022.                                                 --| command file
  5023.         := SSU.Make_Scanner(SS.Create(""));
  5024.     Current_Line_Number          : Count := 0;  --| Current line number of file
  5025.     Previous_Command_Line        : SU.Scanner;  --| Previous command line read
  5026.     Previous_Command_Line_Number : Count;       --| Line number of previous
  5027.                                                 --| command read
  5028.  
  5029.     type Command_Name is
  5030.         (Create, Update, Delete, Field, Not_A_Command);
  5031.  
  5032.     subtype Real_Command_Name is Command_Name range Create .. Delete;
  5033.  
  5034.     subtype Add_Command_Name is Command_Name range Create .. Update;
  5035.  
  5036.     ---------------------------------------------------------------------------
  5037.     -- Local subprogram specifications
  5038.     ---------------------------------------------------------------------------
  5039.    
  5040.     function Next_Input_Line(  --| Returns the next line in From_File
  5041.         From_File : File_Type  --| File to read
  5042.         ) return SU.Scanner;
  5043.  
  5044.     --| Effects:  Reads the current line and makes a scanner from it.
  5045.  
  5046.     --| N/A: Raises, Requires, Modifies
  5047.  
  5048.     ---------------------------------------------------------------------------
  5049.    
  5050.     function Command_Mode(   --| Scans a line for the command on it
  5051.         Line : SU.Scanner    --| Line to scan
  5052.         ) return Command_Name;
  5053.  
  5054.     --| Effects:  Scans Line for the first word and returns what kind of
  5055.     --| command it is.
  5056.  
  5057.     --| N/A: Raises, Requires, Modifies
  5058.  
  5059.     ---------------------------------------------------------------------------
  5060.  
  5061.     procedure Add_to_Dictionary(     --| Adds a dictionary entry to dictionary
  5062.         Add_Mode : Add_Command_Name  --| whether to create or update
  5063.         );
  5064.  
  5065.     --| Effects:  Adds a dictionary entry to the dictionary.  Add_Mode 
  5066.     --| determines whether to create a new entry or update an existing one.
  5067.  
  5068.     --| N/A: Raises, Requires, Modifies
  5069.  
  5070.     ---------------------------------------------------------------------------
  5071.  
  5072.     procedure Delete;  --| Deletes a dictionary entry from dictionary
  5073.  
  5074.     --| Effects:  Deletes a dictionary entry.
  5075.  
  5076.     --| N/A: Raises, Requires, Modifies
  5077.  
  5078.     ---------------------------------------------------------------------------
  5079.  
  5080.     procedure Put_Error(           --| Prints an error message
  5081.         Error_Line  : SU.Scanner;  --| Text of line where error occurred
  5082.         Line_Number : Count;       --| Line number where error occurred
  5083.         Text        : String       --| Message text
  5084.         );
  5085.  
  5086.     --| Effects: Prints out the line number and the line containing
  5087.     --| the error and prints the error message Text on the next line.
  5088.  
  5089.     --| N/A: Raises, Requires, Modifies
  5090.  
  5091.     ---------------------------------------------------------------------------
  5092.  
  5093.     procedure Get_Parameters(               --| Scans line for template,
  5094.                                             --| identifier and occurrence
  5095.         Line       : SU.Scanner;            --| Line to scan
  5096.         Template   : out TP.Template_Name;  --| Template found
  5097.         Identifier : out SS.Screen_String;  --| Identifier found
  5098.         Occurrence : out Integer            --| Occurrence found
  5099.         );
  5100.         --| Raises: Missing_Template, Invalid_Template, Missing_Identifier, 
  5101.         --|         Invalid_Occurrence, Too_Many_Parameters
  5102.  
  5103.     --| Effects:  Scans a line and returns the template, identifier and 
  5104.     --| occurrence on it (second, third and fourth words).  Checks whether
  5105.     --| or not Template is a legal template, and whether or not occurrence
  5106.     --| is a legal occurrence.  Missing_Template is raised if the Template
  5107.     --| parameter is missing; Invalid_Template is raised if the Template
  5108.     --| parameter given isn't one of the valid template names; 
  5109.     --| Missing_Identifier is raised if the identifier parameter is missing;
  5110.     --| Invalid_Occurrence is raised if the occurrence given is invalid;
  5111.     --| Too_Many_Parameters is raised if more than three parameters appear
  5112.     --| on the line.  If Occurrence is not on command line, 0 is returned
  5113.     --| for Occurrence.
  5114.  
  5115.     --| N/A: Requires, Modifies
  5116.  
  5117.     ---------------------------------------------------------------------------
  5118.  
  5119.     procedure Skip_Fields(     --| Skips over lines containing fields
  5120.         From_File : File_Type  --| File containing lines to skip
  5121.         );
  5122.  
  5123.     --| Effects: Skips over lines in From_File containing fields.
  5124.  
  5125.     --| N/A: Raises, Requires, Modifies
  5126.  
  5127.     ---------------------------------------------------------------------------
  5128.     -- External subprogram bodies
  5129.     ---------------------------------------------------------------------------
  5130.  
  5131.     procedure Process_Update_Commands(  --| Processes all update commands
  5132.         Dictionary_Name   : String;     --| Name of dictionary
  5133.         Command_File_Name : String      --| File of update commands
  5134.         ) is
  5135.  
  5136.         Read : Boolean := True;
  5137.  
  5138.     begin
  5139.  
  5140.     begin
  5141.       Open(Command_File, In_File, Command_File_Name);
  5142.     exception
  5143.       when others =>
  5144.             Put_Line(
  5145.         "Error opening file " & Command_File_Name & " for input.");
  5146.             raise Abort_Update;
  5147.     end;
  5148.         Current_File_Name := SS.Unchecked_Create(Command_File_Name);
  5149.         DM.Open_Dictionary(Dictionary_Name);
  5150.         while not End_of_File(Command_File) loop
  5151.  
  5152.             -- only read when Current_Line has already been processed.  
  5153.             -- Current_Line is updated in Add_to_Dictionary but not
  5154.             -- processed, so don't read after calls to Add_to_Dictionary
  5155.             if Read then 
  5156.                 SU.Destroy_Scanner(Current_Line);
  5157.                 Current_Line := Next_Input_Line(Command_File);
  5158.             end if;
  5159.  
  5160.             Previous_Command_Line := SSU.Make_Scanner(SSU.Get_String(
  5161.                 Current_Line));
  5162.             Previous_Command_Line_Number := Current_Line_Number;
  5163.             case Command_Mode(Current_Line) is
  5164.                 when Create =>
  5165.                     Read := False;
  5166.                     Add_To_Dictionary(Create);
  5167.                 when Update =>
  5168.                     Read := False;
  5169.                     Add_To_Dictionary(Update);
  5170.                 when Delete =>
  5171.                     Read := True;
  5172.                     Delete;
  5173.                 when others =>
  5174.                     Read := True;
  5175.                     Put_Error(
  5176.                         Current_Line,
  5177.                         Current_Line_Number,
  5178.                         "No command found on line");
  5179.             end case;
  5180.  
  5181.         end loop;
  5182.  
  5183.         -- after the loop, if a command hasn't been processed, 
  5184.         -- process it
  5185.         if not Read then
  5186.             case Command_Mode(Current_Line) is
  5187.                 when Create => Add_to_Dictionary(Create);
  5188.                 when Update => Add_to_Dictionary(Update);
  5189.                 when Delete => Delete;
  5190.                 when Field  => null;  -- has already been processed
  5191.                 when others =>
  5192.                     Put_Error(
  5193.                         Current_Line,
  5194.                         Current_Line_Number,
  5195.                         "No command found on line");
  5196.             end case;
  5197.         end if;
  5198.  
  5199.         DM.Close_Dictionary;
  5200.  
  5201.     end Process_Update_Commands;
  5202.  
  5203.     ---------------------------------------------------------------------------
  5204.     -- Local subprogram bodies
  5205.     ---------------------------------------------------------------------------
  5206.  
  5207.     function Next_Input_Line(  --| Returns the next line in From_File
  5208.         From_File : File_Type  --| File to read
  5209.         ) return SU.Scanner is
  5210.  
  5211.         Line           : String(1 .. 256);  -- arbitrary length
  5212.         Last           : Natural;
  5213.         Line_String    : SS.Screen_String;
  5214.         Truncated      : Boolean;
  5215.         Return_Scanner : SU.Scanner;
  5216.  
  5217.     begin
  5218.  
  5219.         while not End_of_File(From_File) loop
  5220.  
  5221.             -- get lines until non-blank line is found
  5222.             Get_Line(From_File, Line, Last);
  5223.             Current_Line_Number := Current_Line_Number + 1;
  5224.             SS.Create(Line(1 .. Last), Line_String, Truncated);
  5225.             if Truncated then
  5226.                 Put_Line(
  5227.                     Count'Image(Current_Line_Number) & ": " & Line(1 .. Last));
  5228.                 Put_Line("Line was truncated");
  5229.             end if;
  5230.             Return_Scanner := SSU.Make_Scanner(Line_String);
  5231.             SU.Skip_Space(Return_Scanner);
  5232.             exit when SU.More(Return_Scanner);
  5233.         end loop;
  5234.         return Return_Scanner;
  5235.  
  5236.      end Next_Input_Line;
  5237.  
  5238.     ---------------------------------------------------------------------------
  5239.    
  5240.     function Command_Mode(   --| Scans a line for the command on it
  5241.         Line : SU.Scanner    --| Line to scan
  5242.         ) return Command_Name is
  5243.  
  5244.         Word     : SS.Screen_String;
  5245.         Found    : Boolean;
  5246.         Commands : array(Real_Command_Name) of SS.Screen_String := 
  5247.             (SS.Create("create"), SS.Create("update"), SS.Create("delete"));
  5248.  
  5249.     begin
  5250.  
  5251.         -- Don't want to update the scanner, just want to test for what kind
  5252.         -- of command it is, so mark the scanner before calling Scan_Word and
  5253.         -- restore it afterwards.
  5254.         SU.Mark(Line);
  5255.         SSU.Scan_Word(Line, Found, Word, Skip => True);
  5256.         SU.Restore(Line);
  5257.         for i in Real_Command_Name loop
  5258.             if SS.Match_Prefix(Word, Commands(i)) then
  5259.                 return i;
  5260.             end if;
  5261.         end loop;
  5262.  
  5263.         -- don't want to update scanner
  5264.         SU.Mark(Line);
  5265.         SSU.Scan_Enclosed(
  5266.             Opening_Field_Delimiter,
  5267.             Closing_Field_Delimiter, 
  5268.             Line,
  5269.             Found,
  5270.             Word, 
  5271.             Skip => True);
  5272.         SU.Restore(Line);
  5273.         if Found then
  5274.             return Field;
  5275.         end if;
  5276.         return Not_A_Command;
  5277.  
  5278.     end Command_Mode;
  5279.  
  5280.     ---------------------------------------------------------------------------
  5281.  
  5282.     procedure Add_to_Dictionary(     --| Adds a dictionary entry to dictionary
  5283.         Add_Mode : Add_Command_Name  --| whether to create or update
  5284.         ) is
  5285.  
  5286.         Template             : TP.Template_Name;
  5287.         Identifier           : SS.Screen_String;
  5288.         Occurrence           : Integer range 0 .. DM.Overload_Range'Last;
  5289.         Handle               : DM.Dictionary_Entry_Handle;
  5290.         Found                : Boolean;
  5291.         Word                 : SS.Screen_String;
  5292.         Field_Number         : TP.Variable_Field_Number_Range;
  5293.         No_Fields            : exception;  --| Raised when create or update 
  5294.                                            --| appears with no fields following
  5295.         No_Occurrence_for_Create : exception;
  5296.  
  5297.     begin
  5298.  
  5299.         if End_of_File(Command_File) then
  5300.             raise No_Fields;
  5301.         end if;
  5302.         Get_Parameters(Current_Line, Template, Identifier, Occurrence);
  5303.         SU.Destroy_Scanner(Current_Line);
  5304.         Current_Line := Next_Input_Line(Command_File);
  5305.         if Command_Mode(Current_Line) /= Field then
  5306.             raise No_Fields;
  5307.         end if;
  5308.         if Add_Mode = Create then
  5309.  
  5310.             -- can't specify an occurrence with create command
  5311.             if Occurrence /= 0 then
  5312.                 raise No_Occurrence_for_Create;
  5313.             end if;
  5314.             Handle := DM.New_Entry_Handle(Template);
  5315.  
  5316.             -- update identifier field with identifier read from command line
  5317.             DM.Update_Field(Handle, Identifier_Index, Identifier);
  5318.         else
  5319.  
  5320.             -- if no occurrences of this entry exist, raise exception
  5321.             if not DM.Entry_Exists(Template, Identifier) then
  5322.                 raise Entry_Doesnt_Exist;
  5323.             end if;
  5324.  
  5325.             -- if it isn't unique and the occurrence hasn't been specified,
  5326.             -- raise Entry_Isnt_Unique.  If occurrence hasn't been specified
  5327.             -- but the entry is unique, set occurrence to 1.
  5328.             if (Occurrence = 0) then
  5329.                 if not DM.Unique_Entry(Template, Identifier) then
  5330.                     raise Entry_Isnt_Unique;
  5331.                 end if;
  5332.                 Occurrence := 1;
  5333.             end if;
  5334.  
  5335.             -- if occurrence of this entry doesn't exist, raise exception
  5336.             if not DM.Entry_Exists(Template, Identifier, Occurrence) then
  5337.                 raise Occurrence_Doesnt_Exist;
  5338.             end if;
  5339.  
  5340.             Handle := DM.Entry_Handle(Template, Identifier, Occurrence);
  5341.  
  5342.         end if;
  5343.  
  5344.         while not End_of_File(Command_File) and 
  5345.             (Command_Mode(Current_Line) = Field) loop
  5346.             SSU.Scan_Enclosed(
  5347.                 Opening_Field_Delimiter,
  5348.                 Closing_Field_Delimiter,
  5349.                 Current_Line,
  5350.                 Found,
  5351.                 Word, 
  5352.                 Skip => True);
  5353.             Field_Number := TP.Variable_Field_Number(Template, Word);
  5354.             DM.Update_Field(
  5355.                 Handle, 
  5356.                 Field_Number,
  5357.                 SSU.Get_Remainder(Current_Line));
  5358.             SU.Destroy_Scanner(Current_Line);
  5359.             Current_Line := Next_Input_Line(Command_File);
  5360.         end loop;
  5361.  
  5362.         -- set Identifier variable to the first field of the entry in case
  5363.         -- it has changed, so error messages will be correct
  5364.         Identifier := DM.Field_Contents(Handle, Identifier_Index);
  5365.  
  5366.         if Add_Mode = Create then
  5367.             begin
  5368.                 DM.Create_Entry(Handle);
  5369.             exception
  5370.                 when DM.No_Overload_Field =>
  5371.                     DM.Update_Field(
  5372.                         Handle,
  5373.                         Overload_Index,
  5374.                         SS.Unchecked_Create(
  5375.                             "File " &
  5376.                             SS.Value(Current_File_Name) &
  5377.                             " line " &
  5378.                             Count'Image(Previous_Command_Line_Number)));
  5379.                     DM.Create_Entry(Handle);
  5380.             end;
  5381.         else
  5382.             begin
  5383.                 DM.Update_Entry(Handle);
  5384.             exception
  5385.                 when DM.No_Overload_Field =>
  5386.                     DM.Update_Field(
  5387.                         Handle,
  5388.                         Overload_Index,
  5389.                         SS."&"(
  5390.                             Current_File_Name,
  5391.                             SS.Unchecked_Create(
  5392.                                 Count'Image(Current_Line_Number))));
  5393.                     DM.Update_Entry(Handle);
  5394.             end;
  5395.         end if;
  5396.  
  5397.     exception
  5398.         when No_Fields =>
  5399.             Put_Error(
  5400.                 Previous_Command_Line,
  5401.                 Previous_Command_Line_Number,
  5402.                 "No fields found for " & 
  5403.                 Real_Command_Name'Image(Add_Mode) & " command");
  5404.         when No_Occurrence_for_Create =>
  5405.             Put_Error(
  5406.                 Previous_Command_Line,
  5407.                 Previous_Command_Line_Number,
  5408.                 "Occurrence parameter cannot be specified for CREATE command");
  5409.             Skip_Fields(Command_File);
  5410.         when Missing_Template =>
  5411.             Put_Error(
  5412.                 Current_Line,
  5413.                 Current_Line_Number,
  5414.                 "Template parameter for " & Real_Command_Name'Image(Add_Mode) &
  5415.                 " command is missing");
  5416.             Skip_Fields(Command_File);
  5417.         when Invalid_Template =>
  5418.             Put_Error(
  5419.                 Current_Line,
  5420.                 Current_Line_Number,
  5421.                 "Template is invalid");
  5422.             Skip_Fields(Command_File);
  5423.         when Missing_Identifier =>
  5424.             Put_Error(
  5425.                 Current_Line,
  5426.                 Current_Line_Number,
  5427.                 "Identifier parameter for " &
  5428.                 Real_Command_Name'Image(Add_Mode) & " command is missing");
  5429.             Skip_Fields(Command_File);
  5430.         when Invalid_Occurrence =>
  5431.             Put_Error(
  5432.                 Current_Line,
  5433.                 Current_Line_Number,
  5434.                 "Occurrence is invalid");
  5435.             Skip_Fields(Command_File);
  5436.         when Too_Many_Parameters =>
  5437.             Put_Error(
  5438.                 Current_Line,
  5439.                 Current_Line_Number,
  5440.                 "Too many parameters for " &
  5441.                 Real_Command_Name'Image(Add_Mode) & " command");
  5442.             Skip_Fields(Command_File);
  5443.         when Entry_Doesnt_Exist =>
  5444.             Put_Error(
  5445.                 Previous_Command_Line,
  5446.                 Previous_Command_Line_Number,
  5447.                 "No dictionary entry for " & TP.Template_Name'Image(Template) &
  5448.                 " " & SS.Value(Identifier));
  5449.             Skip_Fields(Command_File);
  5450.         when Occurrence_Doesnt_Exist =>
  5451.             Put_Error(
  5452.                 Previous_Command_Line,
  5453.                 Previous_Command_Line_Number,
  5454.                 "No occurrence " & DM.Overload_Range'Image(Occurrence) & 
  5455.                 " for dictionary entry " & TP.Template_Name'Image(Template) &
  5456.                 " " & SS.Value(Identifier));
  5457.             Skip_Fields(Command_File);
  5458.         when Entry_Isnt_Unique =>
  5459.             Put_Error(
  5460.                 Previous_Command_Line,
  5461.                 Previous_Command_Line_Number,
  5462.                 "Dictionary entry " & TP.Template_Name'Image(Template) & " " &
  5463.                 SS.Value(Identifier) & " is not unique");
  5464.             Skip_Fields(Command_File);
  5465.         when TP.No_Such_Field =>
  5466.             Put_Error(
  5467.                 Current_Line,
  5468.                 Current_Line_Number,
  5469.                 "No such field " & SS.Value(Word) & " for template " &
  5470.                 TP.Template_Name'Image(Template));
  5471.             SU.Destroy_Scanner(Current_Line);
  5472.             Current_Line := Next_Input_Line(Command_File);
  5473.         when DM.Null_Identifier =>
  5474.             Put_Error(
  5475.                 Previous_Command_Line,
  5476.                 Previous_Command_Line_Number,
  5477.                 "Can't " & Real_Command_Name'Image(Add_Mode) & 
  5478.                 " entry with null identifier field");
  5479.         when DM.Too_Many_Overloads =>
  5480.             Put_Error(
  5481.                 Previous_Command_Line,
  5482.                 Previous_Command_Line_Number,
  5483.                 "Too many overloads of " & TP.Template_Name'Image(Template) &
  5484.                 " " & SS.Value(Identifier) & " already exist");
  5485.  
  5486.     end Add_to_Dictionary;
  5487.  
  5488.     ---------------------------------------------------------------------------
  5489.  
  5490.     procedure Delete is  --| Deletes a dictionary entry from dictionary
  5491.  
  5492.         Template   : TP.Template_Name;
  5493.         Identifier : SS.Screen_String;
  5494.         Occurrence : Integer range 0 .. DM.Overload_Range'Last;
  5495.         Handle     : DM.Dictionary_Entry_Handle;
  5496.  
  5497.     begin
  5498.  
  5499.         Get_Parameters(Current_Line, Template, Identifier, Occurrence);
  5500.  
  5501.         -- if no entry of type template and with name identifier exists,
  5502.         -- then raise exception
  5503.         if not DM.Entry_Exists(Template, Identifier) then
  5504.             raise Entry_Doesnt_Exist;
  5505.         end if;
  5506.  
  5507.         -- if it isn't unique and the occurrence hasn't been specified
  5508.         -- then raise exception
  5509.         if (Occurrence = 0) then
  5510.             if not DM.Unique_Entry(Template, Identifier) then
  5511.                 raise Entry_Isnt_Unique;
  5512.             end if;
  5513.             Occurrence := 1;
  5514.         end if;
  5515.  
  5516.         -- if occurrence of this entry doesn't exist, raise exception
  5517.         if not DM.Entry_Exists(Template, Identifier, Occurrence) then
  5518.             raise Occurrence_Doesnt_Exist;
  5519.         end if;
  5520.  
  5521.         Handle := DM.Entry_Handle(Template, Identifier, Occurrence);
  5522.         DM.Delete_Entry(Handle);
  5523.  
  5524.     exception
  5525.         when Missing_Template =>
  5526.             Put_Error(
  5527.                 Current_Line,
  5528.                 Current_Line_Number,
  5529.                 "Template parameter is missing for DELETE command");
  5530.         when Invalid_Template =>
  5531.             Put_Error(
  5532.                 Current_Line,
  5533.                 Current_Line_Number,
  5534.                 "Template is invalid");
  5535.         when Missing_Identifier =>
  5536.             Put_Error(
  5537.                 Current_Line,
  5538.                 Current_Line_Number,
  5539.                 "Identifier parameter for DELETE command is missing");
  5540.         when Invalid_Occurrence =>
  5541.             Put_Error(
  5542.                 Current_Line,
  5543.                 Current_Line_Number,
  5544.                 "Occurrence is invalid");
  5545.         when Too_Many_Parameters =>
  5546.             Put_Error(
  5547.                 Current_Line,
  5548.                 Current_Line_Number,
  5549.                 "Too many parameters for DELETE command");
  5550.         when Entry_Doesnt_Exist =>
  5551.             Put_Error(
  5552.                 Current_Line,
  5553.                 Current_Line_Number,
  5554.                 "No Dictionary entry for " & TP.Template_Name'Image(Template) &
  5555.                 " " & SS.Value(Identifier));
  5556.         when Occurrence_Doesnt_Exist =>
  5557.             Put_Error(
  5558.                 Current_Line,
  5559.                 Current_Line_Number,
  5560.                 "No occurrence " & DM.Overload_Range'Image(Occurrence) & 
  5561.                 " for dictionary entry " & TP.Template_Name'Image(Template) &
  5562.                 " " & SS.Value(Identifier));
  5563.             Skip_Fields(Command_File);
  5564.         when Entry_Isnt_Unique =>
  5565.             Put_Error(
  5566.                 Current_Line,
  5567.                 Current_Line_Number,
  5568.                 "Dictionary entry " & TP.Template_Name'Image(Template) & " " &
  5569.                 SS.Value(Identifier) & " is not unique");
  5570.  
  5571.     end Delete;
  5572.  
  5573.     ---------------------------------------------------------------------------
  5574.  
  5575.     procedure Get_Parameters(               --| Scans line for template,
  5576.                                             --| identifier and occurrence
  5577.         Line       : SU.Scanner;            --| Line to scan
  5578.         Template   : out TP.Template_Name;  --| Template found
  5579.         Identifier : out SS.Screen_String;  --| Identifier found
  5580.         Occurrence : out Integer            --| Occurrence found
  5581.         ) is
  5582.  
  5583.         Template_Text   : SS.Screen_String;
  5584.         Found           : Boolean;
  5585.         Temp_Occurrence : Integer := 0;
  5586.  
  5587.     begin
  5588.  
  5589.         -- forward scanner over the command part
  5590.         SSU.Scan_Word(Line, Found, Template_Text, True);
  5591.         if not SU.More(Line) then
  5592.             raise Missing_Template;
  5593.         end if;
  5594.  
  5595.         -- get the template
  5596.         SSU.Scan_Word(Line, Found, Template_Text, True);
  5597.  
  5598.         -- check template's validity
  5599.         begin
  5600.             Template := TP.Template_Name'Value(SS.Value(Template_Text));
  5601.         exception
  5602.             when Constraint_Error =>
  5603.                 raise Invalid_Template;
  5604.         end;
  5605.  
  5606.         if not SU.More(Line) then
  5607.             raise Missing_Identifier;
  5608.         end if;
  5609.  
  5610.         -- get the identifier
  5611.         SSU.Scan_Word(Line, Found, Identifier, True);
  5612.  
  5613.         -- get the occurrence if it exists
  5614.         if SU.More(Line) then
  5615.             SU.Scan_Number(Line, Found, Temp_Occurrence, True);
  5616.  
  5617.             -- check occurrence's validity
  5618.             if not Found then 
  5619.                 Temp_Occurrence := 0;
  5620.             elsif Temp_Occurrence not in DM.Overload_Range then
  5621.                 raise Invalid_Occurrence;
  5622.             end if;
  5623.         end if;
  5624.         Occurrence := Temp_Occurrence;
  5625.  
  5626.         if SU.More(Line) then
  5627.             raise Too_Many_Parameters;
  5628.         end if;
  5629.  
  5630.     end Get_Parameters;
  5631.  
  5632.     ---------------------------------------------------------------------------
  5633.  
  5634.     procedure Put_Error(           --| Prints an error message
  5635.         Error_Line  : SU.Scanner;  --| Text of line where error occurred
  5636.         Line_Number : Count;       --| Line number where error occurred
  5637.         Text        : String       --| Message text
  5638.         ) is
  5639.  
  5640.     begin
  5641.  
  5642.         Count_IO.Put(Line_Number, 0);
  5643.         Put_Line(": " & SS.Value(SSU.Get_String(Error_Line)));
  5644.         Put_Line(Text);
  5645.         New_Line;
  5646.  
  5647.     end Put_Error;
  5648.  
  5649.     ---------------------------------------------------------------------------
  5650.  
  5651.     procedure Skip_Fields(     --| Skips over lines containing fields
  5652.         From_File : File_Type  --| File containing lines to skip
  5653.         ) is
  5654.     begin
  5655.  
  5656.         loop
  5657.             SU.Destroy_Scanner(Current_Line);
  5658.             Current_Line := Next_Input_Line(From_File);
  5659.             exit when End_Of_File(From_File) or
  5660.                 (Command_Mode(Current_Line) /= Field);
  5661.         end loop;
  5662.  
  5663.     end Skip_Fields;
  5664.  
  5665.     ---------------------------------------------------------------------------
  5666.  
  5667. end Update;
  5668.  
  5669. -------------------------------------------------------------------------------
  5670. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5671. --EDRIVER.ADA
  5672. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5673. with Text_IO; use Text_IO;
  5674. with Commands;
  5675. with Dictionary_Manager;
  5676. with Templates;
  5677. with String_Pkg;
  5678. with Screen_Strings;
  5679. with Standard_Interface;
  5680. with DD_Release;
  5681. with Terminal_IO;
  5682. with Host_Lib;
  5683. -------------------------------------------------------------------------------
  5684.  
  5685. function Edit_Dictionary_Driver return Integer is
  5686. --| Interprets command line and calls the editor
  5687.  
  5688.     package DM  renames Dictionary_Manager;
  5689.     package SP  renames String_Pkg;
  5690.     package SS  renames Screen_Strings;
  5691.     package SI  renames Standard_Interface;
  5692.     package TIO renames Terminal_IO;
  5693.  
  5694.     package Str_Argument is new SI.String_Argument(
  5695.         String_Type_Name => "String");
  5696.     package Template_Name_Argument is new SI.Enumerated_Argument(
  5697.         Enum_Type      => Templates.Template_Name,
  5698.         Enum_Type_Name => "Template_Name");
  5699.  
  5700.     Edit_Handle : SI.Process_Handle;
  5701.  
  5702. begin
  5703.  
  5704.     -- Error messages go to standard error
  5705.     Host_Lib.Set_Error;
  5706.  
  5707.     -- initialize terminal type
  5708.     TIO.Initialize(Host_Lib.Get_Terminal_Type);
  5709.  
  5710.     SI.Set_Tool_Identifier(DD_Release);
  5711.     
  5712.     SI.Define_Process(
  5713.         Name => "Edit_Dictionary",
  5714.         Help => "Call the interactive dictionary editor",
  5715.         Proc => Edit_Handle);
  5716.  
  5717.     -- define the parameters of Edit_Dictionary
  5718.     Str_Argument.Define_Argument(
  5719.         Proc => Edit_Handle,
  5720.         Name => "Dictionary",
  5721.         Help => "Full directory name for dictionary");
  5722.     Template_Name_Argument.Define_Argument(
  5723.         Proc => Edit_Handle,
  5724.         Name => "Template",
  5725.         Help => "Type of template to edit");
  5726.     Str_Argument.Define_Argument(
  5727.         Proc    => Edit_Handle,
  5728.         Name    => "Identifier",
  5729.         Default => "",
  5730.         Help    => "Name of dictionary entry");
  5731.  
  5732.     -- parse the command line
  5733.     SI.Parse_Line(Edit_Handle);
  5734.  
  5735.     -- set output back to standard output
  5736.     Host_Lib.Reset_Error;
  5737.  
  5738.     -- Call Process_Commands with the appropriate parameters
  5739.     Commands.Process_Commands(
  5740.         SP.Value(Str_Argument.Get_Argument(
  5741.             Proc => Edit_Handle,
  5742.             Name => "Dictionary")),
  5743.         Template_Name_Argument.Get_Argument(
  5744.             Proc => Edit_Handle,
  5745.             Name => "Template"),
  5746.         SS.Unchecked_Create(SP.Value(Str_Argument.Get_Argument(
  5747.             Proc => Edit_Handle,
  5748.             Name => "Identifier"))));
  5749.  
  5750.     return Host_Lib.Return_Code(Host_Lib.Success);
  5751.  
  5752. exception
  5753.     when SI.Abort_Process => 
  5754.         return Host_Lib.Return_Code(Host_Lib.Error);
  5755.     when SI.Process_Help =>
  5756.         return Host_Lib.Return_Code(Host_Lib.Information);
  5757.     when Commands.Abort_Commands =>
  5758.         Host_Lib.Set_Error;
  5759.         return Host_Lib.Return_Code(Host_Lib.Information);
  5760.     when DM.Dictionary_Locked =>
  5761.         Host_Lib.Set_Error;
  5762.         Put_Line("Dictionary is locked by another user.");
  5763.         return Host_Lib.Return_Code(Host_Lib.Error);
  5764.     when DM.Lock_is_Missing =>
  5765.         Host_Lib.Set_Error;
  5766.         Put_Line("Lock file for dictionary is missing.");
  5767.         return Host_Lib.Return_Code(Host_Lib.Error);
  5768.     when DM.Invalid_Dictionary_File =>
  5769.         Host_Lib.Set_Error;
  5770.         return Host_Lib.Return_Code(Host_Lib.Error);
  5771.     when DM.Index_File_Error =>
  5772.         Host_Lib.Set_Error;
  5773.         return Host_Lib.Return_Code(Host_Lib.Error);
  5774.     when DM.Data_File_Error =>
  5775.         Host_Lib.Set_Error;
  5776.         return Host_Lib.Return_Code(Host_Lib.Error);
  5777.     when TIO.Unsupported_Terminal => 
  5778.         Host_Lib.Set_Error;
  5779.         begin
  5780.             Put_Line(
  5781.                 "Unsupported terminal type: " &
  5782.                 Host_Lib.Terminal_Type'Image(Host_Lib.Get_Terminal_Type));
  5783.         exception
  5784.             when Host_Lib.Terminal_Not_Attached =>
  5785.                 Put_Line("Terminal not attached.");
  5786.         end;
  5787.         return Host_Lib.Return_Code(Host_Lib.Error);
  5788.     when Host_Lib.Terminal_Not_Attached =>
  5789.         Host_Lib.Set_Error;
  5790.         Put_Line("Terminal not attached.");
  5791.         return Host_Lib.Return_Code(Host_Lib.Error);
  5792.     when others =>
  5793.         Host_Lib.Set_Error;
  5794.         Put_Line("Edit_Dictionary internal error.");
  5795.         begin
  5796.             DM.Close_Dictionary;
  5797.         exception
  5798.             when others => null;
  5799.         end;
  5800.         return Host_Lib.Return_Code(Host_Lib.Error);
  5801.     
  5802. end Edit_Dictionary_Driver;
  5803. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5804. --RDRIVER.ADA
  5805. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5806. with Text_IO; use Text_IO;
  5807. with Dictionary_Manager;
  5808. with Standard_Interface;
  5809. with DD_Release;
  5810. with String_Pkg;
  5811. with Host_Lib;
  5812. -------------------------------------------------------------------------------
  5813.  
  5814. function Dictionary_Report_Driver return Integer is
  5815. --| Interprets command line and calls reporting routines
  5816.  
  5817.     package SI renames Standard_Interface;
  5818.     package SP renames String_Pkg;
  5819.     package DM renames Dictionary_Manager;
  5820.     package RU renames DM.Report_Utilities;
  5821.       
  5822.     package Str_Argument is new SI.String_Argument("String");
  5823.       
  5824.     package Report_Name_Argument is new SI.Enumerated_Argument(
  5825.         Enum_Type      => RU.Report_Name,
  5826.         Enum_Type_Name => "Report_Name");
  5827.       
  5828.     Report_Handle : SI.Process_Handle;
  5829.  
  5830. begin
  5831.  
  5832.     -- Error messages go to standard error
  5833.     Host_Lib.Set_Error;
  5834.  
  5835.     SI.Set_Tool_Identifier(DD_Release);
  5836.     
  5837.     SI.Define_Process(
  5838.         Name => "Report_Dictionary",
  5839.         Help => "Produce report from data dictionary",
  5840.         Proc => Report_Handle);
  5841.  
  5842.     Str_Argument.Define_Argument(
  5843.         Proc => Report_Handle,
  5844.         Name => "Dictionary",
  5845.         Help => "Full directory name of dictionary to report");
  5846.  
  5847.     Report_Name_Argument.Define_Argument(
  5848.         Proc    => Report_Handle,
  5849.         Name    => "Report",
  5850.         Default => RU.Summary,
  5851.         Help    => "Which kind of report to produce");
  5852.  
  5853.     Str_Argument.Define_Argument(
  5854.         Proc    => Report_Handle,
  5855.         Name    => "Entries",
  5856.         Default => "",
  5857.         Help    => "Entries in dictionary from which to produce report");
  5858.  
  5859.     Str_Argument.Append_Argument_Help(
  5860.         Proc => Report_Handle,
  5861.         Name => "Entries",
  5862.         Help => "(If Entries = """" and Entry_File = """" then entire");
  5863.  
  5864.     Str_Argument.Append_Argument_Help(
  5865.         Proc => Report_Handle,
  5866.         Name => "Entries",
  5867.         Help => "dictionary is reported on)");
  5868.  
  5869.     Str_Argument.Define_Argument(
  5870.         Proc    => Report_Handle,
  5871.         Name    => "Entry_File",
  5872.         Default => "",
  5873.         Help    => "File containing entries in dictionary on which to report");
  5874.  
  5875.     Str_Argument.Define_Argument(
  5876.         Proc    => Report_Handle,
  5877.         Name    => "Output",
  5878.         Default => "",
  5879.         Help    => "Output file for report (default is standard output)");
  5880.  
  5881.     SI.Parse_Line(Report_Handle);
  5882.     
  5883.     RU.Set_Up_Report(
  5884.         SP.Value(Str_Argument.Get_Argument(Report_Handle, "Dictionary")),
  5885.         SP.Value(Str_Argument.Get_Argument(Report_Handle, "Entries")),
  5886.         SP.Value(Str_Argument.Get_Argument(Report_Handle, "Entry_File")));
  5887.  
  5888.     RU.Make_Report(
  5889.         Report_Name_Argument.Get_Argument(Report_Handle, "Report"),
  5890.         SP.Value(Str_Argument.Get_Argument(Report_Handle, "Output")));
  5891.  
  5892.     return Host_Lib.Return_Code(Host_Lib.Success);
  5893.  
  5894. exception
  5895.     when SI.Abort_Process => 
  5896.         return Host_Lib.Return_Code(Host_Lib.Error);
  5897.     when SI.Process_Help =>
  5898.         return Host_Lib.Return_Code(Host_Lib.Information);
  5899.     when RU.Abort_Report =>
  5900.         return Host_Lib.Return_Code(Host_Lib.Error);
  5901.     when DM.Dictionary_Locked =>
  5902.         Put_Line("Dictionary is locked by another user.");
  5903.         return Host_Lib.Return_Code(Host_Lib.Error);
  5904.     when DM.Lock_is_Missing =>
  5905.         Put_Line("Lock file for dictionary is missing.");
  5906.         return Host_Lib.Return_Code(Host_Lib.Error);
  5907.     when DM.Invalid_Dictionary_File =>
  5908.         return Host_Lib.Return_Code(Host_Lib.Error);
  5909.     when DM.Index_File_Error =>
  5910.         return Host_Lib.Return_Code(Host_Lib.Error);
  5911.     when DM.Data_File_Error =>
  5912.         return Host_Lib.Return_Code(Host_Lib.Error);
  5913.     when others =>
  5914.         Put_Line("Report_Dictionary internal error.");
  5915.         begin
  5916.             DM.Close_Dictionary;
  5917.         exception
  5918.             when others => null;
  5919.         end;
  5920.         return Host_Lib.Return_Code(Host_Lib.Error);
  5921.     
  5922. end Dictionary_Report_Driver;
  5923. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5924. --SCREENMGR.BDY
  5925. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  5926. with Text_IO; use Text_IO;
  5927. with Terminal_IO;
  5928. -------------------------------------------------------------------------------
  5929.  
  5930. package body Screen_Manager is
  5931. --| Provide functions for displaying templates, menus, text and lines on the
  5932. --| screen.
  5933.  
  5934.     package TIO renames Terminal_IO;
  5935.  
  5936.     Continue_Message  : constant SS.Screen_String 
  5937.         := SS.Create("--Press return to continue--");
  5938.  
  5939.     Blanks           : constant SS.Screen_String := 
  5940.         SS.Create((1 .. SS.Max_Screen_Columns => ' '));
  5941.  
  5942.     Current_Prompt   : SS.Screen_String  --| Last field prompt displayed on 
  5943.         := SS.Create("");                --| screen
  5944.     Previous_Prompt  : SS.Screen_String  --| Last field prompt displayed prior
  5945.         := SS.Create("");                --| to Current_Prompt
  5946.  
  5947.     ---------------------------------------------------------------------------
  5948.     -- External subprogram bodies
  5949.     ---------------------------------------------------------------------------
  5950.  
  5951.     procedure Clear_Message_Line is   --| Clears message line
  5952.     begin
  5953.         TIO.Set_Cursor(Max_Lines, 1);
  5954.         TIO.Clear_Line;
  5955.     end Clear_Message_Line;
  5956.  
  5957.     ---------------------------------------------------------------------------
  5958.  
  5959.     procedure Scroll_Prompt_Lines(   --| Scrolls the prompt lines
  5960.         Old_Text : SS.Screen_String  --| Text entered at last prompt
  5961.         ) is
  5962.     begin
  5963.         TIO.Set_Cursor(Max_Lines - 2, 1);
  5964.         Put("<" & SS.Value(Previous_Prompt) & ">: ");
  5965.         TIO.Clear_Line;
  5966.         Put(SS.Value(Old_Text));
  5967.         Display_Prompt(Current_Prompt);
  5968.     end Scroll_Prompt_Lines;
  5969.  
  5970.     ---------------------------------------------------------------------------
  5971.  
  5972.     procedure Display_Message(        --| Displays message on the message line
  5973.         Text : SS.Screen_String;      --| Text to be displayed
  5974.         Name : Message_Name := Error  --| Type of message
  5975.         ) is
  5976.         Dummy : SS.Screen_String;
  5977.         Trunc : Boolean;
  5978.     begin
  5979.         TIO.Set_Cursor(Max_Lines, 1);
  5980.         TIO.Clear_Line;
  5981.         Put(Message_Name'Image(Name) & ": " & SS.Value(Text));
  5982.     end Display_Message;
  5983.  
  5984.     ---------------------------------------------------------------------------
  5985.  
  5986.     procedure Display_Blank_Template(  --| Displays a blank template form
  5987.         Template : TP.Template_Name    --| Type of template to display
  5988.         ) is
  5989.         Position : TP.Position_Descriptor;  --| Position of a field
  5990.     begin
  5991.         for i in 1 .. Section1_Line_Range'Last loop
  5992.             TIO.Set_Cursor(i, 1);
  5993.             TIO.Clear_Line;
  5994.         end loop;
  5995.         TIO.Set_Cursor(1, 1);
  5996.         Put_Line(SS.Value(TP.Template_Label(Template)));
  5997.         for i in TP.Actual_Field_Number_Range'First .. 
  5998.             TP.Field_Count(Template) loop
  5999.             Position := TP.Field_Position(Template, i);
  6000.             TIO.Set_Cursor(Position.Line, Position.column);
  6001.  
  6002.             -- if field is variable, then put open brackets around field label
  6003.             if TP."="(TP.Field_Mode(Template, i), TP.Variable) then
  6004.                 Put_Line("<" & SS.Value(TP.Field_Label(Template, i)) & ">");
  6005.             else
  6006.                 Put_Line(SS.Value(TP.Field_Label(Template, i)));
  6007.             end if;
  6008.         end loop;
  6009.     end Display_Blank_Template;
  6010.  
  6011.     ---------------------------------------------------------------------------
  6012.  
  6013.     procedure Display_Filled_Template(   --| Displays filled in template
  6014.         Entry_Handle : DM.Dictionary_Entry_Handle
  6015.         --| Entry which contains information to display
  6016.         ) is
  6017.         Position : TP.Position_Descriptor;
  6018.         Template : TP.Template_Name := DM.Template_Kind(Entry_Handle);
  6019.     begin
  6020.         for i in Section1_Line_Range loop
  6021.             TIO.Set_Cursor(i, 1);
  6022.             TIO.Clear_Line;
  6023.         end loop;
  6024.         TIO.Set_Cursor(1, 1);
  6025.         Put_Line(SS.Value(TP.Template_Label(Template)));
  6026.         for i in TP.Actual_Field_Number_Range'First ..
  6027.             TP.Field_Count(Template) loop
  6028.             Position := TP.Field_Position(Template, i);
  6029.             TIO.Set_Cursor(Position.Line, Position.Column);
  6030.             if TP."="(TP.Field_Mode(Template, i), TP.Static) then
  6031.                 Put_Line(SS.Value(TP.Field_Label(Template, i)));
  6032.  
  6033.             -- if the field is empty, then display the field label
  6034.             elsif SS.Equal(
  6035.                 DM.Field_Contents(
  6036.                     Entry_Handle,
  6037.                     TP.Variable_Field_Number(Template, i)),
  6038.                 "") then
  6039.                 Put_Line("<" & SS.Value(TP.Field_Label(Template, i)) & ">");
  6040.  
  6041.             -- if the field is filled out, then display contents of field
  6042.             else
  6043.                 Put_Line(
  6044.                     SS.Value(
  6045.                         DM.Field_Contents(
  6046.                             Entry_Handle,
  6047.                             TP.Variable_Field_Number(Template, i))));
  6048.             end if;
  6049.         end loop;
  6050.     end Display_Filled_Template;
  6051.  
  6052.     ---------------------------------------------------------------------------
  6053.  
  6054.     procedure Display_Prompt(             --| Displays prompt on prompt line
  6055.         Prompt_Text  : SS.Screen_String;  --| Text for the prompt
  6056.         Field_Prompt : Boolean := True    --| type of prompt
  6057.         ) is
  6058.     begin
  6059.         TIO.Set_Cursor(Max_Lines - 1, 1);
  6060.         TIO.Clear_Line;
  6061.         if not Field_Prompt then
  6062.             Put(SS.Value(Prompt_Text));
  6063.  
  6064.             -- so ^X will work on VMS (clears what has been typed)
  6065.             TIO.Set_Cursor(Max_Lines - 1, SS.Length(Prompt_Text) + 1);
  6066.         else
  6067.             Put("<" & SS.Value(Prompt_Text) & ">: ");
  6068.  
  6069.             -- so ^X will work on VMS (clears what has been typed)
  6070.             -- +4 for the characters <>: , +1 to get to column after prompt
  6071.             TIO.Set_Cursor(Max_Lines - 1, SS.Length(Prompt_Text) + 5);
  6072.  
  6073.             -- check for "" in case this is the first time it's being called
  6074.             if not SS.Equal(Current_Prompt, "") then
  6075.                 Previous_Prompt := Current_Prompt;
  6076.             else
  6077.                 Previous_Prompt := Prompt_Text;
  6078.             end if;
  6079.             Current_Prompt := Prompt_Text;
  6080.         end if;
  6081.  
  6082.     end Display_Prompt;
  6083.  
  6084.     ---------------------------------------------------------------------------
  6085.  
  6086.     procedure Display_Secondary_Prompt(  --| Displays a "secondary" prompt on
  6087.                                          --| the prompt line
  6088.         Prompt_Text : SS.Screen_String   --| Text for the prompt
  6089.         ) is
  6090.         Start_Column      : constant SS.Length_Range := 40;
  6091.         --| Column on screen at which to position cursor before secondary 
  6092.         --| prompt is written
  6093.     begin
  6094.         TIO.Set_Cursor(Max_Lines - 1, Start_Column);
  6095.         TIO.Clear_Line;
  6096.  
  6097.         -- add 5 to allow room for response
  6098.         if SS.Length(Prompt_Text) + 5 > SS.Max_Screen_Columns then
  6099.              raise Secondary_Prompt_Too_Long;
  6100.         end if;
  6101.         Put(SS.Value(Prompt_Text));
  6102.  
  6103.         -- so ^X will work
  6104.         TIO.Set_Cursor(
  6105.             Max_Lines - 1,
  6106.             Start_Column + SS.Length(Prompt_Text));
  6107.     end Display_Secondary_Prompt;
  6108.  
  6109.     ---------------------------------------------------------------------------
  6110.  
  6111.     procedure Display_Menu(               --| Displays a menu of choices
  6112.         Menu       : DM.Overload_Array;   --| Menu to display
  6113.         Menu_Mode  : Menu_Mode_Name :=    --| Mode of menu
  6114.             Prompt;
  6115.         Template   : TP.Template_Name :=  --| Name of template to which menu
  6116.             TP.Object_Decl;               --| corresponds
  6117.         Identifier : SS.Screen_String :=  --| Name of identifier to which menu
  6118.             SS.Create("")                 --| corresponds
  6119.         ) is
  6120.     begin
  6121.         TIO.Set_Cursor(1, 1);
  6122.         TIO.Clear_Screen;
  6123.         if not SS.Equal(Identifier, "") then
  6124.             Put_Line(
  6125.                 "Overloads for " & TP.Template_Name'Image(Template) &
  6126.                 " " & SS.Value(Identifier));
  6127.             New_Line;
  6128.         end if;
  6129.         for i in DM.Overload_Range loop
  6130.             exit when (i > 1) and SS.Equal(Menu(i), "");
  6131.             if i < 10 then
  6132.                 Put_Line(
  6133.                     DM.Overload_Range'Image(i) & " : " & 
  6134.                     SS.Value(Menu(i)));
  6135.             else
  6136.                 Put_Line(
  6137.                     DM.Overload_Range'Image(i) & ": " & 
  6138.                     SS.Value(Menu(i)));
  6139.             end if;
  6140.         end loop;
  6141.         if Menu_Mode = Continue then
  6142.             Display_Prompt(Continue_Message, Field_Prompt => False);
  6143.         end if;
  6144.     end Display_Menu;
  6145.  
  6146.     ---------------------------------------------------------------------------
  6147.  
  6148.     procedure Position_for_Exit is --| Repositions cursor at bottom of the 
  6149.                                    --| screen
  6150.     begin
  6151.         TIO.Set_Cursor(Max_Lines, 1);
  6152.         New_Line;
  6153.     end Position_For_Exit;
  6154.  
  6155.     ---------------------------------------------------------------------------
  6156.  
  6157.     procedure Display_Command_List(  --| Displays a list of commands
  6158.         Command_List : Screen_Array  --| List of commands
  6159.         ) is
  6160.         Longest_Length : SS.Length_Range := 0;
  6161.         Blanks_Length  : SS.Length_Range;
  6162.     begin
  6163.         TIO.Set_Cursor(1, 1);
  6164.         TIO.Clear_Screen;
  6165.  
  6166.         -- find the longest line (for centering)
  6167.         for i in Section1_Line_Range loop
  6168.             if SS.Length(Command_List(i)) > Longest_Length then
  6169.                 Longest_Length := SS.Length(Command_List(i));
  6170.             end if;
  6171.         end loop;
  6172.  
  6173.         -- find the length of white space needed to center list
  6174.         Blanks_Length := (SS.Max_Screen_Columns - Longest_Length) / 2;
  6175.         for i in Section1_Line_Range loop
  6176.             Put_Line(
  6177.                 SS.Value(SS.Substring(Blanks, 1, Blanks_Length)) &
  6178.                 SS.Value(Command_List(i)));
  6179.         end loop;
  6180.         Display_Prompt(Continue_Message, Field_Prompt => False);
  6181.     end Display_Command_List;
  6182.  
  6183.     ---------------------------------------------------------------------------
  6184.  
  6185.     procedure Display_Field(  --| Displays contents of a field
  6186.         Entry_Handle : DM.Dictionary_Entry_Handle;
  6187.                               --| Entry containing field to display
  6188.         Field_Number : TP.Actual_Field_Number_Range
  6189.                               --| Which field to display
  6190.         ) is
  6191.         Position   : TP.Position_Descriptor;
  6192.         Template   : TP.Template_Name := DM.Template_Kind(Entry_Handle);
  6193.     begin
  6194.         Position := TP.Field_Position(Template, Field_Number);
  6195.         TIO.Set_Cursor(Position.Line, Position.Column);
  6196.  
  6197.         -- blank out the current contents of the field
  6198.         Put(SS.Value(Blanks)(1 .. TP.Field_Length(Template, Field_Number)));
  6199.         TIO.Set_Cursor(Position.Line, Position.Column);
  6200.  
  6201.         -- if the field is empty, then display the field label
  6202.         if SS.Equal(
  6203.             DM.Field_Contents(
  6204.                 Entry_Handle,
  6205.                 TP.Variable_Field_Number(Template, Field_Number)),
  6206.             "") then
  6207.             Put_Line("<" & 
  6208.                 SS.Value(TP.Field_Label(Template, Field_Number)) & ">");
  6209.         else
  6210.             Put_Line(
  6211.                 SS.Value(
  6212.                     DM.Field_Contents(
  6213.                         Entry_Handle,
  6214.                         TP.Variable_Field_Number(Template, Field_Number))));
  6215.         end if;
  6216.     end Display_Field;
  6217.  
  6218.     ---------------------------------------------------------------------------
  6219.  
  6220. end Screen_Manager; 
  6221.  
  6222. -------------------------------------------------------------------------------
  6223. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6224. --SSTRINGS.BDY
  6225. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6226. with String_Utilities;
  6227. package body Screen_Strings is
  6228. --| Varying length strings which are no longer than the maximum number of
  6229. --| columns on a terminal screen.
  6230.  
  6231.     package SU renames String_Utilities;
  6232.  
  6233.     package SSU is new SU.Generic_String_Utilities(
  6234.         Generic_String_Type => Screen_String,
  6235.         To_Generic => Unchecked_Create,
  6236.         From_Generic => Value);
  6237.  
  6238.     ---------------------------------------------------------------------------
  6239.     -- External subprogram bodies
  6240.     ---------------------------------------------------------------------------
  6241.  
  6242.     function Create(                  --| Create a Screen_String from a string
  6243.         S                 : String    --| String to create a Screen_String from
  6244.         ) return Screen_String is
  6245.         Temp_Screen_String : Screen_String;
  6246.     begin
  6247.         if S'Length > Length_Range'Last then
  6248.             raise String_Too_Long;
  6249.         end if;
  6250.         Temp_Screen_String.Text(1 .. S'Length) := S;
  6251.         Temp_Screen_String.Length := S'Length;
  6252.         return Temp_Screen_String;
  6253.     end Create;
  6254.  
  6255.     ---------------------------------------------------------------------------
  6256.  
  6257.     procedure Create(                   --| Create Screen_String from string
  6258.         S         : String;             --| String to create Screen_String from
  6259.         SS        : out Screen_String;  --| Return value
  6260.         Truncated : out Boolean         --| Whether any text was truncated
  6261.         ) is
  6262.     begin
  6263.         Truncated := False;
  6264.         if S'Length > Length_Range'Last then
  6265.             Truncated := True;
  6266.             SS.Text(1 .. Length_Range'Last) := S(1 .. Length_Range'Last);
  6267.             SS.Length := Length_Range'Last;
  6268.         else
  6269.             SS.Text(1 .. S'Length) := S;
  6270.             SS.Length := S'Length;
  6271.         end if;
  6272.     end Create;
  6273.  
  6274.     ---------------------------------------------------------------------------
  6275.  
  6276.     function Unchecked_Create(  --| Create a Screen_String from a string
  6277.         S : String              --| String to create Screen_String from
  6278.         ) return Screen_String is
  6279.         Temp_Screen_String : Screen_String;
  6280.     begin
  6281.         if S'Length > Length_Range'Last then
  6282.             Temp_Screen_String.Text := S(1 .. Length_Range'Last);
  6283.             Temp_Screen_String.Length := Length_Range'Last;
  6284.         else
  6285.             Temp_Screen_String.Text(1 .. S'Length) := S;
  6286.             Temp_Screen_String.Length := S'Length;
  6287.         end if;
  6288.         return Temp_Screen_String;
  6289.     end Unchecked_Create;
  6290.  
  6291.     ---------------------------------------------------------------------------
  6292.  
  6293.     function Value(         --| Returns the string value of a Screen_String
  6294.         SS : Screen_String  --| Screen_String value
  6295.         ) return String is
  6296.     begin
  6297.         return SS.Text(1 .. SS.Length);       
  6298.     end Value;
  6299.  
  6300.     ---------------------------------------------------------------------------
  6301.  
  6302.     function Length(            --| Returns the length of a Screen_String
  6303.         SS : Screen_String      --| Screen_String whose length to return
  6304.         ) return Length_Range is
  6305.     begin
  6306.         return SS.Length;
  6307.     end Length;
  6308.  
  6309.     ---------------------------------------------------------------------------
  6310.  
  6311.     function "<"(                 --| Returns SS1 < SS2
  6312.         SS1, SS2 : Screen_String  --| Screen_Strings to compare
  6313.         ) return Boolean is
  6314.     begin
  6315.         if SS1.Length < SS2.Length then
  6316.             return True;
  6317.         end if;
  6318.         if SS1.Length > SS2.Length then
  6319.             return False;
  6320.         end if;
  6321.         return SS1.Text(1 .. SS1.Length) < SS2.Text(1 .. SS2.Length);
  6322.     end "<";
  6323.  
  6324.     ---------------------------------------------------------------------------
  6325.  
  6326.     function "<"(            --| Returns Value(SS) < S
  6327.         SS : Screen_String;  --| Screen_String to compare
  6328.         S  : String          --| String to compare
  6329.         ) return Boolean is
  6330.     begin
  6331.         if SS.Length < S'Length then
  6332.             return True;
  6333.         end if;
  6334.         if SS.Length > S'Length then
  6335.             return False;
  6336.         end if;
  6337.         return SS.Text(1 .. SS.Length) < S;
  6338.     end "<";
  6339.  
  6340.     ---------------------------------------------------------------------------
  6341.  
  6342.     function "<"(           --| Returns S < Value(SS)
  6343.         S  : String;        --| String to compare
  6344.         SS : Screen_String  --| Screen_String to compare
  6345.         ) return Boolean is
  6346.     begin
  6347.         if S'Length < SS.Length then
  6348.             return True;
  6349.         end if;
  6350.         if S'Length > SS.Length then
  6351.             return False;
  6352.         end if;
  6353.         return S < SS.Text(1 .. SS.Length);
  6354.     end "<";
  6355.  
  6356.     ---------------------------------------------------------------------------
  6357.  
  6358.     function Equal(               --| Returns Value(SS1) = Value(SS2)
  6359.         SS1, SS2 : Screen_String  --| Screen_Strings to compare
  6360.         ) return Boolean is
  6361.     begin
  6362.         if SS1.Length /= SS2.Length then
  6363.             return False;
  6364.         end if;
  6365.         return SS1.Text(1 .. SS1.Length) = SS2.Text(1 .. SS2.Length);
  6366.     end Equal;
  6367.  
  6368.     ---------------------------------------------------------------------------
  6369.  
  6370.     function Equal(             --| Returns Value(SS) = S
  6371.         SS : Screen_String;     --| Screen_String to compare
  6372.         S  : String             --| String to compare
  6373.         ) return Boolean is
  6374.     begin
  6375.         if SS.Length /= S'Length then
  6376.             return False;
  6377.         end if;
  6378.         return SS.Text(1 .. SS.Length) = S;
  6379.     end Equal;
  6380.  
  6381.     ---------------------------------------------------------------------------
  6382.  
  6383.     function Equal(             --| Returns S = Value(SS)
  6384.         S  : String;            --| String to compare
  6385.         SS : Screen_String      --| Screen_String to compare
  6386.         ) return Boolean is
  6387.     begin
  6388.         if S'Length /= SS.Length then
  6389.             return False;
  6390.         end if;
  6391.         return S = SS.Text(1 .. SS.Length);
  6392.     end Equal;
  6393.  
  6394.     ---------------------------------------------------------------------------
  6395.  
  6396.     function "&"(             --| Concatenation operation
  6397.         SS1 : Screen_String;  --| First Screen_String to concatenate
  6398.         SS2 : Screen_String   --| Second Screen_String to concatenate
  6399.         ) return Screen_String is
  6400.     begin
  6401.         if SS1.Length + SS2.Length > Max_Screen_Columns then
  6402.             raise String_Too_Long;
  6403.         end if;
  6404.         return Create(Value(SS1) & Value(SS2));
  6405.     end "&";
  6406.  
  6407.     ---------------------------------------------------------------------------
  6408.  
  6409.     function "&"(            --| Concatenation operation
  6410.         SS : Screen_String;  --| Screen_String to concatenate
  6411.         S  : String          --| String to concatenate
  6412.         ) return Screen_String is
  6413.     begin
  6414.         if SS.Length + S'Length > Max_Screen_Columns then
  6415.             raise String_Too_Long;
  6416.         end if;
  6417.         return Create(Value(SS) & S);
  6418.     end "&";
  6419.  
  6420.     ---------------------------------------------------------------------------
  6421.  
  6422.     function "&"(            --| Concatenation operation
  6423.         S  : String;         --| String to concatenate
  6424.         SS : Screen_String   --| Screen_String to concatenate
  6425.         ) return Screen_String is
  6426.     begin
  6427.         if S'Length + SS.Length > Max_Screen_Columns then
  6428.             raise String_Too_Long;
  6429.         end if;
  6430.         return Create(S & Value(SS));
  6431.     end "&";
  6432.  
  6433.     ---------------------------------------------------------------------------
  6434.  
  6435.     function Substring(          --| Returns a substring of SS
  6436.         SS     : Screen_String;  --| Screen string from which to get substring
  6437.         Start  : Length_Range;   --| Starting index of substring
  6438.         Length : Length_Range    --| Length of substring
  6439.         ) return Screen_String is
  6440.         End_Index : Integer := Start + Length - 1;
  6441.     begin
  6442.         if (End_Index not in Length_Range) or (End_Index > SS.Length) then
  6443.             raise Invalid_Substring;
  6444.         end if;
  6445.         return Create(SS.Text(Start .. End_Index));
  6446.     end Substring;
  6447.  
  6448.     ---------------------------------------------------------------------------
  6449.  
  6450.     function Match_Prefix(    --| Returns whether SS1 is a prefix of SS2
  6451.         SS1 : Screen_String;  --| The prefix Screen_String
  6452.         SS2 : Screen_String   --| Screen_String to compare prefix against
  6453.         ) return Boolean is
  6454.         Canon_SS1 : Screen_String := SS1;
  6455.         Canon_SS2 : Screen_String := SS2;
  6456.     begin
  6457.         if SS1.Length > SS2.Length then
  6458.             return False;
  6459.         end if;
  6460.  
  6461.         -- make canonical form of SS1 to compare to, since Match_Prefix is
  6462.         -- not case sensitive
  6463.         for i in 1 .. SS1.Length loop
  6464.             if SS1.Text(i) in 'a' .. 'z' then
  6465.                 Canon_SS1.Text(i) := Character'Val(Character'Pos(SS1.Text(i)) -
  6466.                     Character'Pos('a') + Character'Pos('A'));
  6467.             end if;
  6468.         end loop;
  6469.  
  6470.         -- make canonical form of SS2 to compare to, since Match_Prefix is
  6471.         -- not case sensitive
  6472.         for i in 1 .. SS2.Length loop
  6473.             if SS2.Text(i) in 'a' .. 'z' then
  6474.                 Canon_SS2.Text(i) := Character'Val(Character'Pos(SS2.Text(i)) -
  6475.                     Character'Pos('a') + Character'Pos('A'));
  6476.             end if;
  6477.         end loop;
  6478.         return 
  6479.             Canon_SS1.Text(1 .. SS1.Length) = Canon_SS2.Text(1 .. SS1.Length);
  6480.     end Match_Prefix;
  6481.  
  6482.     ---------------------------------------------------------------------------
  6483.  
  6484.     function Match_Prefix(   --| Returns whether S is a prefix of SS
  6485.         S  : String;         --| The prefix String
  6486.         SS : Screen_String   --| Screen_String to compare prefix against
  6487.         ) return Boolean is
  6488.     begin
  6489.         return Match_Prefix(Create(S), SS);
  6490.     end Match_Prefix;
  6491.  
  6492.     ---------------------------------------------------------------------------
  6493.  
  6494.     function Match_Prefix(   --| Returns whether SS is a prefix of S
  6495.         SS : Screen_String;  --| The prefix Screen_String
  6496.         S  : String          --| String to compare prefix against
  6497.         ) return Boolean is
  6498.     begin
  6499.         return Match_Prefix(SS, Create(S));
  6500.     end Match_Prefix;
  6501.  
  6502.     ---------------------------------------------------------------------------
  6503.  
  6504.     function Match_Pattern(       --| Matches a pattern in a screen_string
  6505.         Pattern : Screen_String;  --| The pattern to match
  6506.         Text    : Screen_String   --| Text in which to search for pattern
  6507.         ) return Length_Range is
  6508.         Text_Scanner : SU.Scanner := SSU.Make_Scanner(Text);
  6509.     begin
  6510.         for i in 1 .. Text.Length loop
  6511.             if SSU.Is_Literal(Pattern, Text_Scanner) then
  6512.                 return i;
  6513.             end if;
  6514.             SU.Forward(Text_Scanner);
  6515.         end loop;
  6516.         return 0;
  6517.     end Match_Pattern;
  6518.  
  6519.     ---------------------------------------------------------------------------
  6520.  
  6521.     function Match_Pattern(       --| Matches a pattern in a screen_string
  6522.         Pattern : String;         --| The pattern to match
  6523.         Text    : Screen_String   --| Text in which to search for pattern
  6524.         ) return Length_Range is
  6525.     begin
  6526.         return Match_Pattern(Create(Pattern), Text);
  6527.     end Match_Pattern;
  6528.  
  6529.     ---------------------------------------------------------------------------
  6530.  
  6531.     function Match_Pattern(       --| Matches a pattern in a screen_string
  6532.         Pattern : Screen_String;  --| The pattern to match
  6533.         Text    : String          --| Text in which to search for pattern
  6534.         ) return Length_Range is
  6535.     begin
  6536.         return Match_Pattern(Pattern, Create(Text));
  6537.     end Match_Pattern;
  6538.  
  6539.     ---------------------------------------------------------------------------
  6540.  
  6541. end Screen_Strings;
  6542.  
  6543. -------------------------------------------------------------------------------
  6544. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6545. --TEMPLATES.BDY
  6546. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6547. package body Templates is
  6548.  
  6549.     -----------------------------------------------------------------
  6550.     -- Local declarations for package Templates
  6551.     -----------------------------------------------------------------
  6552.  
  6553.     type Template_Field(Mode : Field_Mode_Name) is
  6554.         record
  6555.             Position  : Position_Descriptor;
  6556.             Label     : SS.Screen_String;
  6557.             case Mode is
  6558.                 when Variable =>
  6559.                     Length    : Positive;
  6560.                     Help_Line : SS.Screen_String;
  6561.                 when Static =>
  6562.                     null;
  6563.             end case;
  6564.         end record;
  6565.  
  6566.     type Template_Field_Handle is access Template_Field;
  6567.  
  6568.     type Field_Array is 
  6569.         array(Actual_Field_Number_Range) of Template_Field_Handle;
  6570.  
  6571.     type Template_Descriptor is
  6572.         record
  6573.             Label  : SS.Screen_String;
  6574.             Fields : Field_Array := (others => null);
  6575.         end record;
  6576.  
  6577.     type Template_Handle is access Template_Descriptor;
  6578.  
  6579.     -- All templates initialized here.
  6580.     Template_Info : array(Template_Name) of Template_Handle := (
  6581.         Object_Decl => new Template_Descriptor'(
  6582.             Label => SS.Create("Object, Constant or Number Declaration"),
  6583.             Fields => (
  6584.                 new Template_Field'(
  6585.                     Mode => Variable,
  6586.                     Position => (3, 1),
  6587.                     Label => SS.Create("ident"),
  6588.                     Length => 30,
  6589.                     Help_Line => SS.Create("Object declaration identifier")),
  6590.                 new Template_Field'(
  6591.                     Mode => Static,
  6592.                     Position => (3, 31),
  6593.                     Label => SS.Create(": -- ")),
  6594.                 new Template_Field'(
  6595.                     Mode => Variable,
  6596.                     Position => (3, 36),
  6597.                     Label => SS.Create("overload"),
  6598.                     Length => 45,
  6599.                     Help_Line => SS.Create(
  6600.                         "Comment distinguishing this object from others " &
  6601.                         "with the same <ident>")),
  6602.                 new Template_Field'(
  6603.                     Mode => Variable,
  6604.                     Position => (4, 5),
  6605.                     Label => SS.Create("type"),
  6606.                     Length => 76,
  6607.                     Help_Line => SS.Create("The type of the object")),
  6608.                 new Template_Field'(
  6609.                     Mode => Static,
  6610.                     Position => (5, 9),
  6611.                     Label => SS.Create(":= ")),
  6612.                 new Template_Field'(
  6613.                     Mode => Variable,
  6614.                     Position => (5, 12),
  6615.                     Label => SS.Create("expr"),
  6616.                     Length => 69,
  6617.                     Help_Line => SS.Create(
  6618.                         "Initializing expression for object declaration")),
  6619.                 new Template_Field'(
  6620.                     Mode => Static,
  6621.                     Position => (7, 1),
  6622.                     Label => SS.Create("-- Synonym: ")),
  6623.                 new Template_Field'(
  6624.                     Mode => Variable,
  6625.                     Position => (7, 13),
  6626.                     Label => SS.Create("syn"),
  6627.                     Length => 68,
  6628.                     Help_Line => SS.Create(
  6629.                         "Identifier which is a synonym for this <ident>")),
  6630.                 new Template_Field'(
  6631.                     Mode => Static,
  6632.                     Position => (8, 1),
  6633.                     Label => SS.Create("-- ")),
  6634.                 new Template_Field'(
  6635.                     Mode => Variable,
  6636.                     Position => (8, 4),
  6637.                     Label => SS.Create("date"),
  6638.                     Length => 28,
  6639.                     Help_Line => SS.Create(
  6640.                         "Date on which this object declaration was written")),
  6641.                 new Template_Field'(
  6642.                     Mode => Variable,
  6643.                     Position => (8, 33),
  6644.                     Label => SS.Create("author"),
  6645.                     Length => 48,
  6646.                     Help_Line => SS.Create(
  6647.                         "Author of this object declaration")),
  6648.                 new Template_Field'(
  6649.                     Mode => Static,
  6650.                     Position => (10, 1),
  6651.                     Label => SS.Create("-- ")),
  6652.                 new Template_Field'(
  6653.                     Mode => Variable,
  6654.                     Position => (10, 4),
  6655.                     Label => SS.Create("1.desc"),
  6656.                     Length => 77,
  6657.                     Help_Line => SS.Create(
  6658.                         "Descriptive comments for object declaration")),
  6659.                 new Template_Field'(
  6660.                     Mode => Static,
  6661.                     Position => (11, 1),
  6662.                     Label => SS.Create("-- ")),
  6663.                 new Template_Field'(
  6664.                     Mode => Variable,
  6665.                     Position => (11, 4),
  6666.                     Label => SS.Create("2.desc"),
  6667.                     Length => 77,
  6668.                     Help_Line => SS.Create(
  6669.                         "Descriptive comments for object declaration")),
  6670.                 new Template_Field'(
  6671.                     Mode => Static,
  6672.                     Position => (12, 1),
  6673.                     Label => SS.Create("-- ")),
  6674.                 new Template_Field'(
  6675.                     Mode => Variable,
  6676.                     Position => (12, 4),
  6677.                     Label => SS.Create("3.desc"),
  6678.                     Length => 77,
  6679.                     Help_Line => SS.Create(
  6680.                         "Descriptive comments for object declaration")),
  6681.                 new Template_Field'(
  6682.                     Mode => Static,
  6683.                     Position => (13, 1),
  6684.                     Label => SS.Create("-- ")),
  6685.                 new Template_Field'(
  6686.                     Mode => Variable,
  6687.                     Position => (13, 4),
  6688.                     Label => SS.Create("4.desc"),
  6689.                     Length => 77,
  6690.                     Help_Line => SS.Create(
  6691.                         "Descriptive comments for object declaration")),
  6692.                 new Template_Field'(
  6693.                     Mode => Static,
  6694.                     Position => (14, 1),
  6695.                     Label => SS.Create("-- ")),
  6696.                 new Template_Field'(
  6697.                     Mode => Variable,
  6698.                     Position => (14, 4),
  6699.                     Label => SS.Create("5.desc"),
  6700.                     Length => 77,
  6701.                     Help_Line => SS.Create(
  6702.                         "Descriptive comments for object declaration")),
  6703.                 new Template_Field'(
  6704.                     Mode => Static,
  6705.                     Position => (15, 1),
  6706.                     Label => SS.Create("-- ")),
  6707.                 new Template_Field'(
  6708.                     Mode => Variable,
  6709.                     Position => (15, 4),
  6710.                     Label => SS.Create("6.desc"),
  6711.                     Length => 77,
  6712.                     Help_Line => SS.Create(
  6713.                         "Descriptive comments for object declaration")),
  6714.                 new Template_Field'(
  6715.                     Mode => Static,
  6716.                     Position => (16, 1),
  6717.                     Label => SS.Create("-- ")),
  6718.                 new Template_Field'(
  6719.                     Mode => Variable,
  6720.                     Position => (16, 4),
  6721.                     Label => SS.Create("7.desc"),
  6722.                     Length => 77,
  6723.                     Help_Line => SS.Create(
  6724.                         "Descriptive comments for object declaration")),
  6725.                 new Template_Field'(
  6726.                     Mode => Static,
  6727.                     Position => (17, 1),
  6728.                     Label => SS.Create("-- ")),
  6729.                 new Template_Field'(
  6730.                     Mode => Variable,
  6731.                     Position => (17, 4),
  6732.                     Label => SS.Create("8.desc"),
  6733.                     Length => 77,
  6734.                     Help_Line => SS.Create(
  6735.                         "Descriptive comments for object declaration")),
  6736.                 new Template_Field'(
  6737.                     Mode => Static,
  6738.                     Position => (18, 1),
  6739.                     Label => SS.Create("-- ")),
  6740.                 new Template_Field'(
  6741.                     Mode => Variable,
  6742.                     Position => (18, 4),
  6743.                     Label => SS.Create("9.desc"),
  6744.                     Length => 77,
  6745.                     Help_Line => SS.Create(
  6746.                         "Descriptive comments for object declaration")),
  6747.                 new Template_Field'(
  6748.                     Mode => Static,
  6749.                     Position => (19, 1),
  6750.                     Label => SS.Create("-- ")),
  6751.                 new Template_Field'(
  6752.                     Mode => Variable,
  6753.                     Position => (19, 4),
  6754.                     Label => SS.Create("10.desc"),
  6755.                     Length => 77,
  6756.                     Help_Line => SS.Create(
  6757.                         "Descriptive comments for object declaration")),
  6758.                 -- explicit "null" for elements before the others clause
  6759.                 -- because of DEC Ada compiler bug
  6760.                 null,
  6761.                 others => null)),
  6762.         Type_Decl => new Template_Descriptor'(
  6763.             Label => SS.Create("Type Declaration"),
  6764.             Fields => (
  6765.                 new Template_Field'(
  6766.                     Mode => Static,
  6767.                     Position => (3, 1),
  6768.                     Label => SS.Create("type ")),
  6769.                 new Template_Field'(
  6770.                     Mode => Variable,
  6771.                     Position => (3, 6),
  6772.                     Label => SS.Create("ident"),
  6773.                     Length => 26,
  6774.                     Help_Line => SS.Create("Type declaration identifier")),
  6775.                 new Template_Field'(
  6776.                     Mode => Static,
  6777.                     Position => (3, 33),
  6778.                     Label => SS.Create("is -- ")),
  6779.                 new Template_Field'(
  6780.                     Mode => Variable,
  6781.                     Position => (3, 39),
  6782.                     Label => SS.Create("overload"),
  6783.                     Length => 42,
  6784.                     Help_Line => SS.Create(
  6785.                         "Comment distinguishing this type from others " &
  6786.                         "with the same <ident>")),
  6787.                 new Template_Field'(
  6788.                     Mode => Variable,
  6789.                     Position => (4, 5),
  6790.                     Label => SS.Create("1.def"),
  6791.                     Length => 76,
  6792.                     Help_Line => SS.Create(
  6793.                         "Type definition for type <ident>")),
  6794.                 new Template_Field'(
  6795.                     Mode => Variable,
  6796.                     Position => (5, 5),
  6797.                     Label => SS.Create("2.def"),
  6798.                     Length => 76,
  6799.                     Help_Line => SS.Create(
  6800.                         "Type definition for type <ident>")),
  6801.                 new Template_Field'(
  6802.                     Mode => Variable,
  6803.                     Position => (6, 5),
  6804.                     Label => SS.Create("3.def"),
  6805.                     Length => 76,
  6806.                     Help_Line => SS.Create(
  6807.                         "Type definition for type <ident>")),
  6808.                 new Template_Field'(
  6809.                     Mode => Variable,
  6810.                     Position => (7, 5),
  6811.                     Label => SS.Create("4.def"),
  6812.                     Length => 76,
  6813.                     Help_Line => SS.Create(
  6814.                         "Type definition for type <ident>")),
  6815.                 new Template_Field'(
  6816.                     Mode => Variable,
  6817.                     Position => (8, 5),
  6818.                     Label => SS.Create("5.def"),
  6819.                     Length => 76,
  6820.                     Help_Line => SS.Create(
  6821.                         "Type definition for type <ident>")),
  6822.                 new Template_Field'(
  6823.                     Mode => Variable,
  6824.                     Position => (9, 5),
  6825.                     Label => SS.Create("6.def"),
  6826.                     Length => 76,
  6827.                     Help_Line => SS.Create(
  6828.                         "Type definition for type <ident>")),
  6829.                 new Template_Field'(
  6830.                     Mode => Variable,
  6831.                     Position => (10, 5),
  6832.                     Label => SS.Create("7.def"),
  6833.                     Length => 76,
  6834.                     Help_Line => SS.Create(
  6835.                         "Type definition for type <ident>")),
  6836.                 new Template_Field'(
  6837.                     Mode => Variable,
  6838.                     Position => (11, 5),
  6839.                     Label => SS.Create("8.def"),
  6840.                     Length => 76,
  6841.                     Help_Line => SS.Create(
  6842.                         "Type definition for type <ident>")),
  6843.                 new Template_Field'(
  6844.                     Mode => Static,
  6845.                     Position => (13, 1),
  6846.                     Label => SS.Create("-- Synonym: ")),
  6847.                 new Template_Field'(
  6848.                     Mode => Variable,
  6849.                     Position => (13, 13),
  6850.                     Label => SS.Create("syn"),
  6851.                     Length => 68,
  6852.                     Help_Line => SS.Create(
  6853.                         "Identifier which is a synonym for this <ident>")),
  6854.                 new Template_Field'(
  6855.                     Mode => Static,
  6856.                     Position => (14, 1),
  6857.                     Label => SS.Create("-- ")),
  6858.                 new Template_Field'(
  6859.                     Mode => Variable,
  6860.                     Position => (14, 4),
  6861.                     Label => SS.Create("date"),
  6862.                     Length => 28,
  6863.                     Help_Line => SS.Create(
  6864.                         "Date on which this type declaration was written")),
  6865.                 new Template_Field'(
  6866.                     Mode => Variable,
  6867.                     Position => (14, 33),
  6868.                     Label => SS.Create("author"),
  6869.                     Length => 48,
  6870.                     Help_Line => SS.Create(
  6871.                         "Author of this type declaration")),
  6872.                 new Template_Field'(
  6873.                     Mode => Static,
  6874.                     Position => (16, 1),
  6875.                     Label => SS.Create("-- ")),
  6876.                 new Template_Field'(
  6877.                     Mode => Variable,
  6878.                     Position => (16, 4),
  6879.                     Label => SS.Create("1.desc"),
  6880.                     Length => 77,
  6881.                     Help_Line => SS.Create(
  6882.                         "Descriptive comments for type declaration")),
  6883.                 new Template_Field'(
  6884.                     Mode => Static,
  6885.                     Position => (17, 1),
  6886.                     Label => SS.Create("-- ")),
  6887.                 new Template_Field'(
  6888.                     Mode => Variable,
  6889.                     Position => (17, 4),
  6890.                     Label => SS.Create("2.desc"),
  6891.                     Length => 77,
  6892.                     Help_Line => SS.Create(
  6893.                         "Descriptive comments for type declaration")),
  6894.                 new Template_Field'(
  6895.                     Mode => Static,
  6896.                     Position => (18, 1),
  6897.                     Label => SS.Create("-- ")),
  6898.                 new Template_Field'(
  6899.                     Mode => Variable,
  6900.                     Position => (18, 4),
  6901.                     Label => SS.Create("3.desc"),
  6902.                     Length => 77,
  6903.                     Help_Line => SS.Create(
  6904.                         "Descriptive comments for type declaration")),
  6905.                 new Template_Field'(
  6906.                     Mode => Static,
  6907.                     Position => (19, 1),
  6908.                     Label => SS.Create("-- ")),
  6909.                 new Template_Field'(
  6910.                     Mode => Variable,
  6911.                     Position => (19, 4),
  6912.                     Label => SS.Create("4.desc"),
  6913.                     Length => 77,
  6914.                     Help_Line => SS.Create(
  6915.                         "Descriptive comments for type declaration")),
  6916.                 new Template_Field'(
  6917.                     Mode => Static,
  6918.                     Position => (20, 1),
  6919.                     Label => SS.Create("-- ")),
  6920.                 new Template_Field'(
  6921.                     Mode => Variable,
  6922.                     Position => (20, 4),
  6923.                     Label => SS.Create("5.desc"),
  6924.                     Length => 77,
  6925.                     Help_Line => SS.Create(
  6926.                         "Descriptive comments for type declaration")),
  6927.                 -- explicit "null" for elements before the others clause
  6928.                 -- because of DEC Ada compiler bug
  6929.                 null,
  6930.                 others => null)),
  6931.         Procedure_Decl => new Template_Descriptor'(
  6932.             Label => SS.Create("Procedure Declaration"),
  6933.             Fields => (
  6934.                 new Template_Field'(
  6935.                     Mode => Static,
  6936.                     Position => (3, 1),
  6937.                     Label => SS.Create("procedure ")),
  6938.                 new Template_Field'(
  6939.                     Mode => Variable,
  6940.                     Position => (3, 11),
  6941.                     Label => SS.Create("ident"),
  6942.                     Length => 25,
  6943.                     Help_Line => 
  6944.                         SS.Create("Procedure declaration identifier")),
  6945.                 new Template_Field'(
  6946.                     Mode => Static,
  6947.                     Position => (3, 36),
  6948.                     Label => SS.Create("( -- ")),
  6949.                 new Template_Field'(
  6950.                     Mode => Variable,
  6951.                     Position => (3, 41),
  6952.                     Label => SS.Create("overload"),
  6953.                     Length => 40,
  6954.                     Help_Line => SS.Create(
  6955.                         "Comment distinguishing this procedure from others " &
  6956.                         "with the same <ident>")),
  6957.                 new Template_Field'(
  6958.                     Mode => Variable,
  6959.                     Position => (4, 5),
  6960.                     Label => SS.Create("1.param"),
  6961.                     Length => 33,
  6962.                     Help_Line => SS.Create("Parameter of procedure <ident>")),
  6963.                 new Template_Field'(
  6964.                     Mode => Static,
  6965.                     Position => (4, 38),
  6966.                     Label => SS.Create("-- ")),
  6967.                 new Template_Field'(
  6968.                     Mode => Variable,
  6969.                     Position => (4, 41),
  6970.                     Label => SS.Create("1.comm"),
  6971.                     Length => 40,
  6972.                     Help_Line => 
  6973.                         SS.Create("Comment describing this parameter")),
  6974.                 new Template_Field'(
  6975.                     Mode => Variable,
  6976.                     Position => (5, 5),
  6977.                     Label => SS.Create("2.param"),
  6978.                     Length => 33,
  6979.                     Help_Line => SS.Create("Parameter of procedure <ident>")),
  6980.                 new Template_Field'(
  6981.                     Mode => Static,
  6982.                     Position => (5, 38),
  6983.                     Label => SS.Create("-- ")),
  6984.                 new Template_Field'(
  6985.                     Mode => Variable,
  6986.                     Position => (5, 41),
  6987.                     Label => SS.Create("2.comm"),
  6988.                     Length => 40,
  6989.                     Help_Line => 
  6990.                         SS.Create("Comment describing this parameter")),
  6991.                 new Template_Field'(
  6992.                     Mode => Variable,
  6993.                     Position => (6, 5),
  6994.                     Label => SS.Create("3.param"),
  6995.                     Length => 33,
  6996.                     Help_Line => SS.Create("Parameter of procedure <ident>")),
  6997.                 new Template_Field'(
  6998.                     Mode => Static,
  6999.                     Position => (6, 38),
  7000.                     Label => SS.Create("-- ")),
  7001.                 new Template_Field'(
  7002.                     Mode => Variable,
  7003.                     Position => (6, 41),
  7004.                     Label => SS.Create("3.comm"),
  7005.                     Length => 40,
  7006.                     Help_Line => 
  7007.                         SS.Create("Comment describing this parameter")),
  7008.                 new Template_Field'(
  7009.                     Mode => Variable,
  7010.                     Position => (7, 5),
  7011.                     Label => SS.Create("4.param"),
  7012.                     Length => 33,
  7013.                     Help_Line => SS.Create("Parameter of procedure <ident>")),
  7014.                 new Template_Field'(
  7015.                     Mode => Static,
  7016.                     Position => (7, 38),
  7017.                     Label => SS.Create("-- ")),
  7018.                 new Template_Field'(
  7019.                     Mode => Variable,
  7020.                     Position => (7, 41),
  7021.                     Label => SS.Create("4.comm"),
  7022.                     Length => 40,
  7023.                     Help_Line => 
  7024.                         SS.Create("Comment describing this parameter")),
  7025.                 new Template_Field'(
  7026.                     Mode => Static,
  7027.                     Position => (8, 5),
  7028.                     Label => SS.Create(");")),
  7029.                 new Template_Field'(
  7030.                     Mode => Static,
  7031.                     Position => (10, 1),
  7032.                     Label => SS.Create("-- Synonym: ")),
  7033.                 new Template_Field'(
  7034.                     Mode => Variable,
  7035.                     Position => (10, 13),
  7036.                     Label => SS.Create("syn"),
  7037.                     Length => 68,
  7038.                     Help_Line => SS.Create(
  7039.                         "Identifier which is a synonym for this <ident>")),
  7040.                 new Template_Field'(
  7041.                     Mode => Static,
  7042.                     Position => (11, 1),
  7043.                     Label => SS.Create("-- ")),
  7044.                 new Template_Field'(
  7045.                     Mode => Variable,
  7046.                     Position => (11, 4),
  7047.                     Label => SS.Create("date"),
  7048.                     Length => 28,
  7049.                     Help_Line => SS.Create(
  7050.                         "Date on which this procedure declaration was " &
  7051.                         "written")),
  7052.                 new Template_Field'(
  7053.                     Mode => Variable,
  7054.                     Position => (11, 33),
  7055.                     Label => SS.Create("author"),
  7056.                     Length => 48,
  7057.                     Help_Line => SS.Create(
  7058.                         "Author of this procedure declaration")),
  7059.                 new Template_Field'(
  7060.                     Mode => Static,
  7061.                     Position => (13, 1),
  7062.                     Label => SS.Create("-- ")),
  7063.                 new Template_Field'(
  7064.                     Mode => Variable,
  7065.                     Position => (13, 4),
  7066.                     Label => SS.Create("1.desc"),
  7067.                     Length => 77,
  7068.                     Help_Line => SS.Create(
  7069.                         "Descriptive comments for procedure declaration")),
  7070.                 new Template_Field'(
  7071.                     Mode => Static,
  7072.                     Position => (14, 1),
  7073.                     Label => SS.Create("-- ")),
  7074.                 new Template_Field'(
  7075.                     Mode => Variable,
  7076.                     Position => (14, 4),
  7077.                     Label => SS.Create("2.desc"),
  7078.                     Length => 77,
  7079.                     Help_Line => SS.Create(
  7080.                         "Descriptive comments for procedure declaration")),
  7081.                 new Template_Field'(
  7082.                     Mode => Static,
  7083.                     Position => (15, 1),
  7084.                     Label => SS.Create("-- ")),
  7085.                 new Template_Field'(
  7086.                     Mode => Variable,
  7087.                     Position => (15, 4),
  7088.                     Label => SS.Create("3.desc"),
  7089.                     Length => 77,
  7090.                     Help_Line => SS.Create(
  7091.                         "Descriptive comments for procedure declaration")),
  7092.                 new Template_Field'(
  7093.                     Mode => Static,
  7094.                     Position => (16, 1),
  7095.                     Label => SS.Create("-- ")),
  7096.                 new Template_Field'(
  7097.                     Mode => Variable,
  7098.                     Position => (16, 4),
  7099.                     Label => SS.Create("4.desc"),
  7100.                     Length => 77,
  7101.                     Help_Line => SS.Create(
  7102.                         "Descriptive comments for procedure declaration")),
  7103.                 new Template_Field'(
  7104.                     Mode => Static,
  7105.                     Position => (17, 1),
  7106.                     Label => SS.Create("-- ")),
  7107.                 new Template_Field'(
  7108.                     Mode => Variable,
  7109.                     Position => (17, 4),
  7110.                     Label => SS.Create("5.desc"),
  7111.                     Length => 77,
  7112.                     Help_Line => SS.Create(
  7113.                         "Descriptive comments for procedure declaration")),
  7114.                 new Template_Field'(
  7115.                     Mode => Static,
  7116.                     Position => (18, 1),
  7117.                     Label => SS.Create("-- ")),
  7118.                 new Template_Field'(
  7119.                     Mode => Variable,
  7120.                     Position => (18, 4),
  7121.                     Label => SS.Create("6.desc"),
  7122.                     Length => 77,
  7123.                     Help_Line => SS.Create(
  7124.                         "Descriptive comments for procedure declaration")),
  7125.                 new Template_Field'(
  7126.                     Mode => Static,
  7127.                     Position => (19, 1),
  7128.                     Label => SS.Create("-- ")),
  7129.                 new Template_Field'(
  7130.                     Mode => Variable,
  7131.                     Position => (19, 4),
  7132.                     Label => SS.Create("7.desc"),
  7133.                     Length => 77,
  7134.                     Help_Line => SS.Create(
  7135.                         "Descriptive comments for procedure declaration")),
  7136.                 new Template_Field'(
  7137.                     Mode => Static,
  7138.                     Position => (20, 1),
  7139.                     Label => SS.Create("-- ")),
  7140.                 new Template_Field'(
  7141.                     Mode => Variable,
  7142.                     Position => (20, 4),
  7143.                     Label => SS.Create("8.desc"),
  7144.                     Length => 77,
  7145.                     Help_Line => SS.Create(
  7146.                         "Descriptive comments for procedure declaration")),
  7147.                 -- explicit "null" for elements before the others clause
  7148.                 -- because of DEC Ada compiler bug
  7149.                 null,
  7150.                 others => null)),
  7151.         Function_Decl => new Template_Descriptor'(
  7152.             Label => SS.Create("Function Declaration"),
  7153.             Fields => (
  7154.                 new Template_Field'(
  7155.                     Mode => Static,
  7156.                     Position => (3, 1),
  7157.                     Label => SS.Create("function ")),
  7158.                 new Template_Field'(
  7159.                     Mode => Variable,
  7160.                     Position => (3, 10),
  7161.                     Label => SS.Create("ident"),
  7162.                     Length => 26,
  7163.                     Help_Line => 
  7164.                         SS.Create("Function declaration identifier")),
  7165.                 new Template_Field'(
  7166.                     Mode => Static,
  7167.                     Position => (3, 36),
  7168.                     Label => SS.Create("( -- ")),
  7169.                 new Template_Field'(
  7170.                     Mode => Variable,
  7171.                     Position => (3, 41),
  7172.                     Label => SS.Create("overload"),
  7173.                     Length => 40,
  7174.                     Help_Line => SS.Create(
  7175.                         "Comment distinguishing this function from others " &
  7176.                         "with the same <ident>")),
  7177.                 new Template_Field'(
  7178.                     Mode => Variable,
  7179.                     Position => (4, 5),
  7180.                     Label => SS.Create("1.param"),
  7181.                     Length => 33,
  7182.                     Help_Line => SS.Create("Parameter of function <ident>")),
  7183.                 new Template_Field'(
  7184.                     Mode => Static,
  7185.                     Position => (4, 38),
  7186.                     Label => SS.Create("-- ")),
  7187.                 new Template_Field'(
  7188.                     Mode => Variable,
  7189.                     Position => (4, 41),
  7190.                     Label => SS.Create("1.comm"),
  7191.                     Length => 40,
  7192.                     Help_Line => 
  7193.                         SS.Create("Comment describing this parameter")),
  7194.                 new Template_Field'(
  7195.                     Mode => Variable,
  7196.                     Position => (5, 5),
  7197.                     Label => SS.Create("2.param"),
  7198.                     Length => 33,
  7199.                     Help_Line => SS.Create("Parameter of function <ident>")),
  7200.                 new Template_Field'(
  7201.                     Mode => Static,
  7202.                     Position => (5, 38),
  7203.                     Label => SS.Create("-- ")),
  7204.                 new Template_Field'(
  7205.                     Mode => Variable,
  7206.                     Position => (5, 41),
  7207.                     Label => SS.Create("2.comm"),
  7208.                     Length => 40,
  7209.                     Help_Line => 
  7210.                         SS.Create("Comment describing this parameter")),
  7211.                 new Template_Field'(
  7212.                     Mode => Variable,
  7213.                     Position => (6, 5),
  7214.                     Label => SS.Create("3.param"),
  7215.                     Length => 33,
  7216.                     Help_Line => SS.Create("Parameter of function <ident>")),
  7217.                 new Template_Field'(
  7218.                     Mode => Static,
  7219.                     Position => (6, 38),
  7220.                     Label => SS.Create("-- ")),
  7221.                 new Template_Field'(
  7222.                     Mode => Variable,
  7223.                     Position => (6, 41),
  7224.                     Label => SS.Create("3.comm"),
  7225.                     Length => 40,
  7226.                     Help_Line => 
  7227.                         SS.Create("Comment describing this parameter")),
  7228.                 new Template_Field'(
  7229.                     Mode => Variable,
  7230.                     Position => (7, 5),
  7231.                     Label => SS.Create("4.param"),
  7232.                     Length => 33,
  7233.                     Help_Line => SS.Create("Parameter of function <ident>")),
  7234.                 new Template_Field'(
  7235.                     Mode => Static,
  7236.                     Position => (7, 38),
  7237.                     Label => SS.Create("-- ")),
  7238.                 new Template_Field'(
  7239.                     Mode => Variable,
  7240.                     Position => (7, 41),
  7241.                     Label => SS.Create("4.comm"),
  7242.                     Length => 40,
  7243.                     Help_Line => 
  7244.                         SS.Create("Comment describing this parameter")),
  7245.                 new Template_Field'(
  7246.                     Mode => Static,
  7247.                     Position => (8, 5),
  7248.                     Label => SS.Create(") return ")),
  7249.                 new Template_Field'(
  7250.                     Mode => Variable,
  7251.                     Position => (8, 14),
  7252.                     Label => SS.Create("type"),
  7253.                     Length => 67,
  7254.                     Help_Line => SS.Create("Return type for this function")),
  7255.                 new Template_Field'(
  7256.                     Mode => Static,
  7257.                     Position => (10, 1),
  7258.                     Label => SS.Create("-- Synonym: ")),
  7259.                 new Template_Field'(
  7260.                     Mode => Variable,
  7261.                     Position => (10, 13),
  7262.                     Label => SS.Create("syn"),
  7263.                     Length => 68,
  7264.                     Help_Line => SS.Create(
  7265.                         "Identifier which is a synonym for this <ident>")),
  7266.                 new Template_Field'(
  7267.                     Mode => Static,
  7268.                     Position => (11, 1),
  7269.                     Label => SS.Create("-- ")),
  7270.                 new Template_Field'(
  7271.                     Mode => Variable,
  7272.                     Position => (11, 4),
  7273.                     Label => SS.Create("date"),
  7274.                     Length => 28,
  7275.                     Help_Line => SS.Create(
  7276.                         "Date on which this function declaration was " &
  7277.                         "written")),
  7278.                 new Template_Field'(
  7279.                     Mode => Variable,
  7280.                     Position => (11, 33),
  7281.                     Label => SS.Create("author"),
  7282.                     Length => 48,
  7283.                     Help_Line => SS.Create(
  7284.                         "Author of this function declaration")),
  7285.                 new Template_Field'(
  7286.                     Mode => Static,
  7287.                     Position => (13, 1),
  7288.                     Label => SS.Create("-- ")),
  7289.                 new Template_Field'(
  7290.                     Mode => Variable,
  7291.                     Position => (13, 4),
  7292.                     Label => SS.Create("1.desc"),
  7293.                     Length => 77,
  7294.                     Help_Line => SS.Create(
  7295.                         "Descriptive comments for function declaration")),
  7296.                 new Template_Field'(
  7297.                     Mode => Static,
  7298.                     Position => (14, 1),
  7299.                     Label => SS.Create("-- ")),
  7300.                 new Template_Field'(
  7301.                     Mode => Variable,
  7302.                     Position => (14, 4),
  7303.                     Label => SS.Create("2.desc"),
  7304.                     Length => 77,
  7305.                     Help_Line => SS.Create(
  7306.                         "Descriptive comments for function declaration")),
  7307.                 new Template_Field'(
  7308.                     Mode => Static,
  7309.                     Position => (15, 1),
  7310.                     Label => SS.Create("-- ")),
  7311.                 new Template_Field'(
  7312.                     Mode => Variable,
  7313.                     Position => (15, 4),
  7314.                     Label => SS.Create("3.desc"),
  7315.                     Length => 77,
  7316.                     Help_Line => SS.Create(
  7317.                         "Descriptive comments for function declaration")),
  7318.                 new Template_Field'(
  7319.                     Mode => Static,
  7320.                     Position => (16, 1),
  7321.                     Label => SS.Create("-- ")),
  7322.                 new Template_Field'(
  7323.                     Mode => Variable,
  7324.                     Position => (16, 4),
  7325.                     Label => SS.Create("4.desc"),
  7326.                     Length => 77,
  7327.                     Help_Line => SS.Create(
  7328.                         "Descriptive comments for function declaration")),
  7329.                 new Template_Field'(
  7330.                     Mode => Static,
  7331.                     Position => (17, 1),
  7332.                     Label => SS.Create("-- ")),
  7333.                 new Template_Field'(
  7334.                     Mode => Variable,
  7335.                     Position => (17, 4),
  7336.                     Label => SS.Create("5.desc"),
  7337.                     Length => 77,
  7338.                     Help_Line => SS.Create(
  7339.                         "Descriptive comments for function declaration")),
  7340.                 new Template_Field'(
  7341.                     Mode => Static,
  7342.                     Position => (18, 1),
  7343.                     Label => SS.Create("-- ")),
  7344.                 new Template_Field'(
  7345.                     Mode => Variable,
  7346.                     Position => (18, 4),
  7347.                     Label => SS.Create("6.desc"),
  7348.                     Length => 77,
  7349.                     Help_Line => SS.Create(
  7350.                         "Descriptive comments for function declaration")),
  7351.                 new Template_Field'(
  7352.                     Mode => Static,
  7353.                     Position => (19, 1),
  7354.                     Label => SS.Create("-- ")),
  7355.                 new Template_Field'(
  7356.                     Mode => Variable,
  7357.                     Position => (19, 4),
  7358.                     Label => SS.Create("7.desc"),
  7359.                     Length => 77,
  7360.                     Help_Line => SS.Create(
  7361.                         "Descriptive comments for function declaration")),
  7362.                 new Template_Field'(
  7363.                     Mode => Static,
  7364.                     Position => (20, 1),
  7365.                     Label => SS.Create("-- ")),
  7366.                 new Template_Field'(
  7367.                     Mode => Variable,
  7368.                     Position => (20, 4),
  7369.                     Label => SS.Create("8.desc"),
  7370.                     Length => 77,
  7371.                     Help_Line => SS.Create(
  7372.                         "Descriptive comments for function declaration")),
  7373.                 -- explicit "null" for elements before the others clause
  7374.                 -- because of DEC Ada compiler bug
  7375.                 null,
  7376.                 others => null)),
  7377.         Package_Decl => new Template_Descriptor'(
  7378.             Label => SS.Create("Package Declaration"),
  7379.             Fields => (
  7380.                 new Template_Field'(
  7381.                     Mode => Static,
  7382.                     Position => (3, 1),
  7383.                     Label => SS.Create("package ")),
  7384.                 new Template_Field'(
  7385.                     Mode => Variable,
  7386.                     Position => (3, 9),
  7387.                     Label => SS.Create("ident"),
  7388.                     Length => 23,
  7389.                     Help_Line => 
  7390.                         SS.Create("Package declaration identifier")),
  7391.                 new Template_Field'(
  7392.                     Mode => Static,
  7393.                     Position => (3, 33),
  7394.                     Label => SS.Create("is -- ")),
  7395.                 new Template_Field'(
  7396.                     Mode => Variable,
  7397.                     Position => (3, 40),
  7398.                     Label => SS.Create("overload"),
  7399.                     Length => 41,
  7400.                     Help_Line => SS.Create(
  7401.                         "Comment distinguishing this package from others " &
  7402.                         "with the same <ident>")),
  7403.                 new Template_Field'(
  7404.                     Mode => Static,
  7405.                     Position => (4, 1),
  7406.                     Label => SS.Create("-- ")),
  7407.                 new Template_Field'(
  7408.                     Mode => Variable,
  7409.                     Position => (4, 4),
  7410.                     Label => SS.Create("comment"),
  7411.                     Length => 77,
  7412.                     Help_Line => 
  7413.                         SS.Create("Short comment describing this package")),
  7414.                 new Template_Field'(
  7415.                     Mode => Static,
  7416.                     Position => (6, 1),
  7417.                     Label => SS.Create("-- Synonym: ")),
  7418.                 new Template_Field'(
  7419.                     Mode => Variable,
  7420.                     Position => (6, 13),
  7421.                     Label => SS.Create("syn"),
  7422.                     Length => 68,
  7423.                     Help_Line => SS.Create(
  7424.                         "Identifier which is a synonym for this <ident>")),
  7425.                 new Template_Field'(
  7426.                     Mode => Static,
  7427.                     Position => (7, 1),
  7428.                     Label => SS.Create("-- ")),
  7429.                 new Template_Field'(
  7430.                     Mode => Variable,
  7431.                     Position => (7, 4),
  7432.                     Label => SS.Create("date"),
  7433.                     Length => 28,
  7434.                     Help_Line => SS.Create(
  7435.                         "Date on which this package declaration was " &
  7436.                         "written")),
  7437.                 new Template_Field'(
  7438.                     Mode => Variable,
  7439.                     Position => (7, 33),
  7440.                     Label => SS.Create("author"),
  7441.                     Length => 48,
  7442.                     Help_Line => SS.Create(
  7443.                         "Author of this package declaration")),
  7444.                 new Template_Field'(
  7445.                     Mode => Static,
  7446.                     Position => (9, 1),
  7447.                     Label => SS.Create("-- ")),
  7448.                 new Template_Field'(
  7449.                     Mode => Variable,
  7450.                     Position => (9, 4),
  7451.                     Label => SS.Create("1.desc"),
  7452.                     Length => 77,
  7453.                     Help_Line => SS.Create(
  7454.                         "Descriptive comments for package declaration")),
  7455.                 new Template_Field'(
  7456.                     Mode => Static,
  7457.                     Position => (10, 1),
  7458.                     Label => SS.Create("-- ")),
  7459.                 new Template_Field'(
  7460.                     Mode => Variable,
  7461.                     Position => (10, 4),
  7462.                     Label => SS.Create("2.desc"),
  7463.                     Length => 77,
  7464.                     Help_Line => SS.Create(
  7465.                         "Descriptive comments for package declaration")),
  7466.                 new Template_Field'(
  7467.                     Mode => Static,
  7468.                     Position => (11, 1),
  7469.                     Label => SS.Create("-- ")),
  7470.                 new Template_Field'(
  7471.                     Mode => Variable,
  7472.                     Position => (11, 4),
  7473.                     Label => SS.Create("3.desc"),
  7474.                     Length => 77,
  7475.                     Help_Line => SS.Create(
  7476.                         "Descriptive comments for package declaration")),
  7477.                 new Template_Field'(
  7478.                     Mode => Static,
  7479.                     Position => (12, 1),
  7480.                     Label => SS.Create("-- ")),
  7481.                 new Template_Field'(
  7482.                     Mode => Variable,
  7483.                     Position => (12, 4),
  7484.                     Label => SS.Create("4.desc"),
  7485.                     Length => 77,
  7486.                     Help_Line => SS.Create(
  7487.                         "Descriptive comments for package declaration")),
  7488.                 new Template_Field'(
  7489.                     Mode => Static,
  7490.                     Position => (13, 1),
  7491.                     Label => SS.Create("-- ")),
  7492.                 new Template_Field'(
  7493.                     Mode => Variable,
  7494.                     Position => (13, 4),
  7495.                     Label => SS.Create("5.desc"),
  7496.                     Length => 77,
  7497.                     Help_Line => SS.Create(
  7498.                         "Descriptive comments for package declaration")),
  7499.                 new Template_Field'(
  7500.                     Mode => Static,
  7501.                     Position => (14, 1),
  7502.                     Label => SS.Create("-- ")),
  7503.                 new Template_Field'(
  7504.                     Mode => Variable,
  7505.                     Position => (14, 4),
  7506.                     Label => SS.Create("6.desc"),
  7507.                     Length => 77,
  7508.                     Help_Line => SS.Create(
  7509.                         "Descriptive comments for package declaration")),
  7510.                 new Template_Field'(
  7511.                     Mode => Static,
  7512.                     Position => (15, 1),
  7513.                     Label => SS.Create("-- ")),
  7514.                 new Template_Field'(
  7515.                     Mode => Variable,
  7516.                     Position => (15, 4),
  7517.                     Label => SS.Create("7.desc"),
  7518.                     Length => 77,
  7519.                     Help_Line => SS.Create(
  7520.                         "Descriptive comments for package declaration")),
  7521.                 new Template_Field'(
  7522.                     Mode => Static,
  7523.                     Position => (16, 1),
  7524.                     Label => SS.Create("-- ")),
  7525.                 new Template_Field'(
  7526.                     Mode => Variable,
  7527.                     Position => (16, 4),
  7528.                     Label => SS.Create("8.desc"),
  7529.                     Length => 77,
  7530.                     Help_Line => SS.Create(
  7531.                         "Descriptive comments for package declaration")),
  7532.                 new Template_Field'(
  7533.                     Mode => Static,
  7534.                     Position => (17, 1),
  7535.                     Label => SS.Create("-- ")),
  7536.                 new Template_Field'(
  7537.                     Mode => Variable,
  7538.                     Position => (17, 4),
  7539.                     Label => SS.Create("9.desc"),
  7540.                     Length => 77,
  7541.                     Help_Line => SS.Create(
  7542.                         "Descriptive comments for package declaration")),
  7543.                 new Template_Field'(
  7544.                     Mode => Static,
  7545.                     Position => (18, 1),
  7546.                     Label => SS.Create("-- ")),
  7547.                 new Template_Field'(
  7548.                     Mode => Variable,
  7549.                     Position => (18, 4),
  7550.                     Label => SS.Create("10.desc"),
  7551.                     Length => 77,
  7552.                     Help_Line => SS.Create(
  7553.                         "Descriptive comments for package declaration")),
  7554.                 new Template_Field'(
  7555.                     Mode => Static,
  7556.                     Position => (20, 1),
  7557.                     Label => SS.Create("end; ")),
  7558.                 -- explicit "null" for elements before the others clause
  7559.                 -- because of DEC Ada compiler bug
  7560.                 null,
  7561.                 others => null)),
  7562.         Task_Decl => new Template_Descriptor'(
  7563.             Label => SS.Create("Task Declaration"),
  7564.             Fields => (
  7565.                 new Template_Field'(
  7566.                     Mode => Static,
  7567.                     Position => (3, 1),
  7568.                     Label => SS.Create("task ")),
  7569.                 new Template_Field'(
  7570.                     Mode => Variable,
  7571.                     Position => (3, 6),
  7572.                     Label => SS.Create("ident"),
  7573.                     Length => 26,
  7574.                     Help_Line => 
  7575.                         SS.Create("Task declaration identifier")),
  7576.                 new Template_Field'(
  7577.                     Mode => Static,
  7578.                     Position => (3, 33),
  7579.                     Label => SS.Create("is -- ")),
  7580.                 new Template_Field'(
  7581.                     Mode => Variable,
  7582.                     Position => (3, 39),
  7583.                     Label => SS.Create("overload"),
  7584.                     Length => 42,
  7585.                     Help_Line => SS.Create(
  7586.                         "Comment distinguishing this task from others " &
  7587.                         "with the same <ident>")),
  7588.                 new Template_Field'(
  7589.                     Mode => Static,
  7590.                     Position => (4, 1),
  7591.                     Label => SS.Create("-- ")),
  7592.                 new Template_Field'(
  7593.                     Mode => Variable,
  7594.                     Position => (4, 4),
  7595.                     Label => SS.Create("comment"),
  7596.                     Length => 77,
  7597.                     Help_Line => 
  7598.                         SS.Create("Short comment describing this task")),
  7599.                 new Template_Field'(
  7600.                     Mode => Static,
  7601.                     Position => (5, 5),
  7602.                     Label => SS.Create("entry ")),
  7603.                 new Template_Field'(
  7604.                     Mode => Variable,
  7605.                     Position => (5, 11),
  7606.                     Label => SS.Create("1.decl"),
  7607.                     Length => 25,
  7608.                     Help_Line => SS.Create("Entry declaration")),
  7609.                 new Template_Field'(
  7610.                     Mode => Static,
  7611.                     Position => (5, 36),
  7612.                     Label => SS.Create("-- ")),
  7613.                 new Template_Field'(
  7614.                     Mode => Variable,
  7615.                     Position => (5, 39),
  7616.                     Label => SS.Create("1.comm"),
  7617.                     Length => 42,
  7618.                     Help_Line => SS.Create(
  7619.                         "Comment describing this entry declaration")),
  7620.                 new Template_Field'(
  7621.                     Mode => Static,
  7622.                     Position => (6, 5),
  7623.                     Label => SS.Create("entry ")),
  7624.                 new Template_Field'(
  7625.                     Mode => Variable,
  7626.                     Position => (6, 11),
  7627.                     Label => SS.Create("2.decl"),
  7628.                     Length => 25,
  7629.                     Help_Line => SS.Create("Entry declaration")),
  7630.                 new Template_Field'(
  7631.                     Mode => Static,
  7632.                     Position => (6, 36),
  7633.                     Label => SS.Create("-- ")),
  7634.                 new Template_Field'(
  7635.                     Mode => Variable,
  7636.                     Position => (6, 39),
  7637.                     Label => SS.Create("2.comm"),
  7638.                     Length => 42,
  7639.                     Help_Line => SS.Create(
  7640.                         "Comment describing this entry declaration")),
  7641.                 new Template_Field'(
  7642.                     Mode => Static,
  7643.                     Position => (7, 5),
  7644.                     Label => SS.Create("entry ")),
  7645.                 new Template_Field'(
  7646.                     Mode => Variable,
  7647.                     Position => (7, 11),
  7648.                     Label => SS.Create("3.decl"),
  7649.                     Length => 25,
  7650.                     Help_Line => SS.Create("Entry declaration")),
  7651.                 new Template_Field'(
  7652.                     Mode => Static,
  7653.                     Position => (7, 36),
  7654.                     Label => SS.Create("-- ")),
  7655.                 new Template_Field'(
  7656.                     Mode => Variable,
  7657.                     Position => (7, 39),
  7658.                     Label => SS.Create("3.comm"),
  7659.                     Length => 42,
  7660.                     Help_Line => SS.Create(
  7661.                         "Comment describing this entry declaration")),
  7662.                 new Template_Field'(
  7663.                     Mode => Static,
  7664.                     Position => (8, 5),
  7665.                     Label => SS.Create("entry ")),
  7666.                 new Template_Field'(
  7667.                     Mode => Variable,
  7668.                     Position => (8, 11),
  7669.                     Label => SS.Create("4.decl"),
  7670.                     Length => 25,
  7671.                     Help_Line => SS.Create("Entry declaration")),
  7672.                 new Template_Field'(
  7673.                     Mode => Static,
  7674.                     Position => (8, 36),
  7675.                     Label => SS.Create("-- ")),
  7676.                 new Template_Field'(
  7677.                     Mode => Variable,
  7678.                     Position => (8, 39),
  7679.                     Label => SS.Create("4.comm"),
  7680.                     Length => 42,
  7681.                     Help_Line => SS.Create(
  7682.                         "Comment describing this entry declaration")),
  7683.                 new Template_Field'(
  7684.                     Mode => Static,
  7685.                     Position => (9, 1),
  7686.                     Label => SS.Create("end;")),
  7687.                 new Template_Field'(
  7688.                     Mode => Static,
  7689.                     Position => (11, 1),
  7690.                     Label => SS.Create("-- Synonym: ")),
  7691.                 new Template_Field'(
  7692.                     Mode => Variable,
  7693.                     Position => (11, 13),
  7694.                     Label => SS.Create("syn"),
  7695.                     Length => 68,
  7696.                     Help_Line => SS.Create(
  7697.                         "Identifier which is a synonym for this <ident>")),
  7698.                 new Template_Field'(
  7699.                     Mode => Static,
  7700.                     Position => (12, 1),
  7701.                     Label => SS.Create("-- ")),
  7702.                 new Template_Field'(
  7703.                     Mode => Variable,
  7704.                     Position => (12, 4),
  7705.                     Label => SS.Create("date"),
  7706.                     Length => 28,
  7707.                     Help_Line => SS.Create(
  7708.                         "Date on which this task declaration was " &
  7709.                         "written")),
  7710.                 new Template_Field'(
  7711.                     Mode => Variable,
  7712.                     Position => (12 ,33),
  7713.                     Label => SS.Create("author"),
  7714.                     Length => 48,
  7715.                     Help_Line => SS.Create(
  7716.                         "Author of this task declaration")),
  7717.                 new Template_Field'(
  7718.                     Mode => Static,
  7719.                     Position => (14, 1),
  7720.                     Label => SS.Create("-- ")),
  7721.                 new Template_Field'(
  7722.                     Mode => Variable,
  7723.                     Position => (14, 4),
  7724.                     Label => SS.Create("1.desc"),
  7725.                     Length => 77,
  7726.                     Help_Line => SS.Create(
  7727.                         "Descriptive comments for task declaration")),
  7728.                 new Template_Field'(
  7729.                     Mode => Static,
  7730.                     Position => (15, 1),
  7731.                     Label => SS.Create("-- ")),
  7732.                 new Template_Field'(
  7733.                     Mode => Variable,
  7734.                     Position => (15, 4),
  7735.                     Label => SS.Create("2.desc"),
  7736.                     Length => 77,
  7737.                     Help_Line => SS.Create(
  7738.                         "Descriptive comments for task declaration")),
  7739.                 new Template_Field'(
  7740.                     Mode => Static,
  7741.                     Position => (16, 1),
  7742.                     Label => SS.Create("-- ")),
  7743.                 new Template_Field'(
  7744.                     Mode => Variable,
  7745.                     Position => (16, 4),
  7746.                     Label => SS.Create("3.desc"),
  7747.                     Length => 77,
  7748.                     Help_Line => SS.Create(
  7749.                         "Descriptive comments for task declaration")),
  7750.                 new Template_Field'(
  7751.                     Mode => Static,
  7752.                     Position => (17, 1),
  7753.                     Label => SS.Create("-- ")),
  7754.                 new Template_Field'(
  7755.                     Mode => Variable,
  7756.                     Position => (17, 4),
  7757.                     Label => SS.Create("4.desc"),
  7758.                     Length => 77,
  7759.                     Help_Line => SS.Create(
  7760.                         "Descriptive comments for task declaration")),
  7761.                 new Template_Field'(
  7762.                     Mode => Static,
  7763.                     Position => (18, 1),
  7764.                     Label => SS.Create("-- ")),
  7765.                 new Template_Field'(
  7766.                     Mode => Variable,
  7767.                     Position => (18, 4),
  7768.                     Label => SS.Create("5.desc"),
  7769.                     Length => 77,
  7770.                     Help_Line => SS.Create(
  7771.                         "Descriptive comments for task declaration")),
  7772.                 new Template_Field'(
  7773.                     Mode => Static,
  7774.                     Position => (19, 1),
  7775.                     Label => SS.Create("-- ")),
  7776.                 new Template_Field'(
  7777.                     Mode => Variable,
  7778.                     Position => (19, 4),
  7779.                     Label => SS.Create("6.desc"),
  7780.                     Length => 77,
  7781.                     Help_Line => SS.Create(
  7782.                         "Descriptive comments for task declaration")),
  7783.                 new Template_Field'(
  7784.                     Mode => Static,
  7785.                     Position => (20, 1),
  7786.                     Label => SS.Create("-- ")),
  7787.                 new Template_Field'(
  7788.                     Mode => Variable,
  7789.                     Position => (20, 4),
  7790.                     Label => SS.Create("7.desc"),
  7791.                     Length => 77,
  7792.                     Help_Line => SS.Create(
  7793.                         "Descriptive comments for task declaration")),
  7794.                 -- explicit "null" for elements before the others clause
  7795.                 -- because of DEC Ada compiler bug
  7796.                 null,
  7797.                 others => null)),
  7798.         Exception_Decl => new Template_Descriptor'(
  7799.             Label => SS.Create("Exception Declaration"),
  7800.             Fields => (
  7801.                 new Template_Field'(
  7802.                     Mode => Variable,
  7803.                     Position => (3, 1),
  7804.                     Label => SS.Create("ident"),
  7805.                     Length => 30,
  7806.                     Help_Line => 
  7807.                         SS.Create("Exception declaration identifier")),
  7808.                 new Template_Field'(
  7809.                     Mode => Static,
  7810.                     Position => (3, 31),
  7811.                     Label => SS.Create(": -- ")),
  7812.                 new Template_Field'(
  7813.                     Mode => Variable,
  7814.                     Position => (3, 36),
  7815.                     Label => SS.Create("overload"),
  7816.                     Length => 42,
  7817.                     Help_Line => SS.Create(
  7818.                         "Comment distinguishing this object from others " &
  7819.                         "with the same <ident>")),
  7820.                 new Template_Field'(
  7821.                     Mode => Static,
  7822.                     Position => (4, 5),
  7823.                     Label => SS.Create("exception;")),
  7824.                 new Template_Field'(
  7825.                     Mode => Static,
  7826.                     Position => (6, 1),
  7827.                     Label => SS.Create("-- Synonym: ")),
  7828.                 new Template_Field'(
  7829.                     Mode => Variable,
  7830.                     Position => (6, 13),
  7831.                     Label => SS.Create("syn"),
  7832.                     Length => 68,
  7833.                     Help_Line => SS.Create(
  7834.                         "Identifier which is a synonym for this <ident>")),
  7835.                 new Template_Field'(
  7836.                     Mode => Static,
  7837.                     Position => (7, 1),
  7838.                     Label => SS.Create("-- ")),
  7839.                 new Template_Field'(
  7840.                     Mode => Variable,
  7841.                     Position => (7, 4),
  7842.                     Label => SS.Create("date"),
  7843.                     Length => 28,
  7844.                     Help_Line => SS.Create(
  7845.                         "Date on which this exception declaration was " & 
  7846.                         "written")),
  7847.                 new Template_Field'(
  7848.                     Mode => Variable,
  7849.                     Position => (7, 33),
  7850.                     Label => SS.Create("author"),
  7851.                     Length => 48,
  7852.                     Help_Line => SS.Create(
  7853.                         "Author of this exception declaration")),
  7854.                 new Template_Field'(
  7855.                     Mode => Static,
  7856.                     Position => (9, 1),
  7857.                     Label => SS.Create("-- ")),
  7858.                 new Template_Field'(
  7859.                     Mode => Variable,
  7860.                     Position => (9, 4),
  7861.                     Label => SS.Create("1.desc"),
  7862.                     Length => 77,
  7863.                     Help_Line => SS.Create(
  7864.                         "Descriptive comments for exception declaration")),
  7865.                 new Template_Field'(
  7866.                     Mode => Static,
  7867.                     Position => (10, 1),
  7868.                     Label => SS.Create("-- ")),
  7869.                 new Template_Field'(
  7870.                     Mode => Variable,
  7871.                     Position => (10, 4),
  7872.                     Label => SS.Create("2.desc"),
  7873.                     Length => 77,
  7874.                     Help_Line => SS.Create(
  7875.                         "Descriptive comments for exception declaration")),
  7876.                 new Template_Field'(
  7877.                     Mode => Static,
  7878.                     Position => (11, 1),
  7879.                     Label => SS.Create("-- ")),
  7880.                 new Template_Field'(
  7881.                     Mode => Variable,
  7882.                     Position => (11, 4),
  7883.                     Label => SS.Create("3.desc"),
  7884.                     Length => 77,
  7885.                     Help_Line => SS.Create(
  7886.                         "Descriptive comments for exception declaration")),
  7887.                 new Template_Field'(
  7888.                     Mode => Static,
  7889.                     Position => (12, 1),
  7890.                     Label => SS.Create("-- ")),
  7891.                 new Template_Field'(
  7892.                     Mode => Variable,
  7893.                     Position => (12, 4),
  7894.                     Label => SS.Create("4.desc"),
  7895.                     Length => 77,
  7896.                     Help_Line => SS.Create(
  7897.                         "Descriptive comments for exception declaration")),
  7898.                 new Template_Field'(
  7899.                     Mode => Static,
  7900.                     Position => (13, 1),
  7901.                     Label => SS.Create("-- ")),
  7902.                 new Template_Field'(
  7903.                     Mode => Variable,
  7904.                     Position => (13, 4),
  7905.                     Label => SS.Create("5.desc"),
  7906.                     Length => 77,
  7907.                     Help_Line => SS.Create(
  7908.                         "Descriptive comments for exception declaration")),
  7909.                 new Template_Field'(
  7910.                     Mode => Static,
  7911.                     Position => (14, 1),
  7912.                     Label => SS.Create("-- ")),
  7913.                 new Template_Field'(
  7914.                     Mode => Variable,
  7915.                     Position => (14, 4),
  7916.                     Label => SS.Create("6.desc"),
  7917.                     Length => 77,
  7918.                     Help_Line => SS.Create(
  7919.                         "Descriptive comments for exception declaration")),
  7920.                 new Template_Field'(
  7921.                     Mode => Static,
  7922.                     Position => (15, 1),
  7923.                     Label => SS.Create("-- ")),
  7924.                 new Template_Field'(
  7925.                     Mode => Variable,
  7926.                     Position => (15, 4),
  7927.                     Label => SS.Create("7.desc"),
  7928.                     Length => 77,
  7929.                     Help_Line => SS.Create(
  7930.                         "Descriptive comments for exception declaration")),
  7931.                 new Template_Field'(
  7932.                     Mode => Static,
  7933.                     Position => (16, 1),
  7934.                     Label => SS.Create("-- ")),
  7935.                 new Template_Field'(
  7936.                     Mode => Variable,
  7937.                     Position => (16, 4),
  7938.                     Label => SS.Create("8.desc"),
  7939.                     Length => 77,
  7940.                     Help_Line => SS.Create(
  7941.                         "Descriptive comments for exception declaration")),
  7942.                 new Template_Field'(
  7943.                     Mode => Static,
  7944.                     Position => (17, 1),
  7945.                     Label => SS.Create("-- ")),
  7946.                 new Template_Field'(
  7947.                     Mode => Variable,
  7948.                     Position => (17, 4),
  7949.                     Label => SS.Create("9.desc"),
  7950.                     Length => 77,
  7951.                     Help_Line => SS.Create(
  7952.                         "Descriptive comments for exception declaration")),
  7953.                 new Template_Field'(
  7954.                     Mode => Static,
  7955.                     Position => (18, 1),
  7956.                     Label => SS.Create("-- ")),
  7957.                 new Template_Field'(
  7958.                     Mode => Variable,
  7959.                     Position => (18, 4),
  7960.                     Label => SS.Create("10.desc"),
  7961.                     Length => 77,
  7962.                     Help_Line => SS.Create(
  7963.                         "Descriptive comments for exception declaration")),
  7964.                 -- explicit "null" for elements before the others clause
  7965.                 -- because of DEC Ada compiler bug
  7966.                 null,
  7967.                 others => null)));
  7968.  
  7969.     ---------------------------------------------------------------------------
  7970.     -- Bodies of subprograms global to package Templates    
  7971.     ---------------------------------------------------------------------------
  7972.     
  7973.     function Field_Count(         --| Returns the number of fields in template
  7974.         Template : Template_Name  --| Template containing fields
  7975.         ) return Actual_Field_Range is
  7976.         Count : Actual_Field_Range := 0;
  7977.     begin
  7978.         while (Count < Max_Fields) and then 
  7979.             (Template_Info(Template).Fields(Count + 1) /= null) loop
  7980.             Count := Count + 1;
  7981.         end loop;
  7982.         return Count;
  7983.     end Field_Count;
  7984.  
  7985.     ---------------------------------------------------------------------------
  7986.  
  7987.     function Variable_Field_Count(  --| Returns the number of variable fields
  7988.         Template : Template_Name    --| Template containing fields
  7989.         ) return Variable_Field_Range is
  7990.         Count          : Actual_Field_Range   := 0;
  7991.         Variable_Count : Variable_Field_Range := 0;
  7992.     begin
  7993.         while (Count < Max_Fields) and then 
  7994.             (Template_Info(Template).Fields(Count + 1) /= null) loop
  7995.             if Template_Info(Template).Fields(Count + 1).Mode = Variable then
  7996.                 Variable_Count := Variable_Count + 1;
  7997.             end if;
  7998.             Count := Count + 1;
  7999.         end loop;
  8000.         return Variable_Count;
  8001.     end Variable_Field_Count;
  8002.  
  8003.     ---------------------------------------------------------------------------
  8004.  
  8005.     function Variable_Field_Number(   --| Returns the variable field number,
  8006.                                       --| given the actual field number
  8007.         Template            : Template_Name; 
  8008.                                       --| Template containing fields
  8009.         Actual_Field_Number : Actual_Field_Number_Range
  8010.                                       --| actual field number (out of total)
  8011.         ) return Variable_Field_Number_Range is
  8012.         Count : Variable_Field_Range := 0;
  8013.     begin
  8014.         if Actual_Field_Number > Field_Count(Template) then
  8015.             raise No_Such_Field;
  8016.         end if;
  8017.         if Template_Info(Template).Fields(Actual_Field_Number).Mode 
  8018.             /= Variable then
  8019.             raise Not_A_Variable_Field;
  8020.         end if;
  8021.         for i in 1 .. Actual_Field_Number loop
  8022.             if Template_Info(Template).Fields(i).Mode = Variable then
  8023.                 Count := Count + 1;
  8024.             end if;
  8025.         end loop;
  8026.         return Count;
  8027.     end Variable_Field_Number;
  8028.  
  8029.     ---------------------------------------------------------------------------
  8030.  
  8031.     function Variable_Field_Number(   --| Returns the variable field number,
  8032.                                       --| given the field name
  8033.         Template   : Template_Name;   --| Template containing fields
  8034.         Field_Name : SS.Screen_String --| name of the field
  8035.         ) return Variable_Field_Number_Range is
  8036.         Count          : Actual_Field_Range   := 0;
  8037.         Variable_Count : Variable_Field_Range := 0;
  8038.     begin
  8039.         while (Count < Max_Fields) and then 
  8040.             (Template_Info(Template).Fields(Count + 1) /= null) loop
  8041.             if Template_Info(Template).Fields(Count + 1).Mode = Variable then
  8042.                 Variable_Count := Variable_Count + 1;
  8043.                 if SS.Equal(
  8044.                     Template_Info(Template).Fields(Count + 1).Label,
  8045.                     Field_Name) then
  8046.                     return Variable_Count;
  8047.                 end if;
  8048.             end if;
  8049.             Count := Count + 1;
  8050.         end loop;
  8051.         raise No_Such_Field;
  8052.     end Variable_Field_Number;
  8053.  
  8054.     ---------------------------------------------------------------------------
  8055.  
  8056.     function Actual_Field_Number(     --| Returns the actual field number,
  8057.                                       --| given the variable field number
  8058.         Template              : Template_Name; 
  8059.                                       --| Template containing fields
  8060.         Variable_Field_Number : Variable_Field_Number_Range
  8061.         ) return Actual_Field_Number_Range is
  8062.         Count_Total : Actual_Field_Range   := 0;
  8063.         Count_Var   : Variable_Field_Range := 0;
  8064.     begin
  8065.         while Count_Var < Variable_Field_Number loop
  8066.             if Count_Total = Actual_Field_Number_Range'Last then
  8067.                 raise No_Such_Field;
  8068.             end if;
  8069.             Count_Total := Count_Total + 1;
  8070.             if (Template_Info(Template).Fields(Count_Total) = null) then
  8071.                 raise No_Such_Field;
  8072.             end if;
  8073.             if Template_Info(Template).Fields(Count_Total).Mode = Variable then
  8074.                 Count_Var := Count_Var + 1;
  8075.             end if;
  8076.         end loop;
  8077.         return Count_Total;
  8078.     end Actual_Field_Number;
  8079.  
  8080.     ---------------------------------------------------------------------------
  8081.  
  8082.     function Actual_Field_Number(     --| Returns the actual field number,
  8083.                                       --| given the field name
  8084.         Template   : Template_Name;   --| Template containing fields
  8085.         Field_Name : SS.Screen_String --| name of the field
  8086.         ) return Actual_Field_Number_Range is
  8087.         Count : Actual_Field_Range := 0;
  8088.     begin
  8089.         while (Count < Max_Fields) and then 
  8090.             (Template_Info(Template).Fields(Count + 1) /= null) loop
  8091.             Count := Count + 1;
  8092.             if SS.Equal(
  8093.                 Template_Info(Template).Fields(Count).Label,
  8094.                 Field_Name) then
  8095.                 return Count;
  8096.             end if;
  8097.         end loop;
  8098.         raise No_Such_Field;
  8099.     end Actual_Field_Number;
  8100.  
  8101.     ---------------------------------------------------------------------------
  8102.  
  8103.     function First_Variable_Field_Number(  --| Returns the variable field
  8104.                                            --| number of the first field on 
  8105.                                            --| a line
  8106.         Template : Template_Name;          --| Template containing field
  8107.         Line     : Positive                --| Line within template
  8108.         ) return Variable_Field_Number_Range is
  8109.         Last_Field     : Actual_Field_Range := Field_Count(Template);
  8110.         Count          : Actual_Field_Number_Range := 1;
  8111.         Variable_Count : Variable_Field_Range := 0;
  8112.         Variable_Found : Boolean := False;
  8113.     begin
  8114.         if Line > Field_Position(Template, Last_Field).Line then
  8115.             raise No_Such_Line;
  8116.         end if;
  8117.  
  8118.         -- loop through template descriptor, counting variable fields
  8119.         -- until the requested line is found
  8120.         while Field_Position(Template, Count).Line < Line loop
  8121.             if Template_Info(Template).Fields(Count).Mode = Variable then
  8122.                 Variable_Count := Variable_Count + 1;
  8123.             end if;
  8124.             Count := Count + 1;
  8125.         end loop;
  8126.  
  8127.         -- loop until first variable field is found
  8128.         while not Variable_Found and then (Count <= Last_Field) and then
  8129.             (Field_Position(Template, Count).Line = Line) loop
  8130.             if Template_Info(Template).Fields(Count).Mode = Variable then
  8131.                 Variable_Found := True;
  8132.             end if;
  8133.             if Count < Last_Field then
  8134.                 Count := Count + 1;
  8135.             end if;
  8136.         end loop;
  8137.         if not Variable_Found then
  8138.             raise No_Variable_Field_On_Line;
  8139.         end if;
  8140.         return Variable_Count + 1;
  8141.     end First_Variable_Field_Number;
  8142.  
  8143.     ---------------------------------------------------------------------------
  8144.  
  8145.     function Template_Label(      --| Returns the label of a template
  8146.         Template : Template_Name  --| Template from which to get label
  8147.         ) return SS.Screen_String is
  8148.     begin
  8149.         return Template_Info(Template).Label;
  8150.     end Template_Label;
  8151.  
  8152.     ---------------------------------------------------------------------------
  8153.  
  8154.     function Field_Mode(               --| Returns the mode of a field
  8155.         Template     : Template_Name;  --| Template containing field
  8156.         Field_Number : Actual_Field_Number_Range
  8157.                                        --| Field whose mode to return
  8158.         ) return Field_Mode_Name is
  8159.         Field_Handle : Template_Field_Handle;
  8160.     begin
  8161.         Field_Handle := Template_Info(Template).Fields(Field_Number);
  8162.         if Field_Handle = null then
  8163.             raise No_Such_Field;
  8164.         end if;
  8165.         return Field_Handle.Mode;
  8166.     end Field_Mode;
  8167.  
  8168.     ---------------------------------------------------------------------------
  8169.  
  8170.     function Field_Position(           --| Returns the position of a field
  8171.         Template     : Template_Name;  --| Template containing field
  8172.         Field_Number : Actual_Field_Number_Range
  8173.                                        --| Field whose position to return
  8174.         ) return Position_Descriptor is 
  8175.         Field_Handle : Template_Field_Handle;
  8176.     begin
  8177.         Field_Handle := Template_Info(Template).Fields(Field_Number);
  8178.         if Field_Handle = null then
  8179.             raise No_Such_Field;
  8180.         end if;
  8181.         return Field_Handle.Position;
  8182.     end Field_Position;
  8183.  
  8184.     ---------------------------------------------------------------------------
  8185.  
  8186.     function Field_Label(             --| Returns the label of a field
  8187.         Template     : Template_Name; --| Template containing field
  8188.         Field_Number : Actual_Field_Number_Range
  8189.                                       --| Field whose label to return
  8190.         ) return SS.Screen_String is
  8191.         Field_Handle : Template_Field_Handle;
  8192.     begin
  8193.         Field_Handle := Template_Info(Template).Fields(Field_Number);
  8194.         if Field_Handle = null then
  8195.             raise No_Such_Field;
  8196.         end if;
  8197.         return Field_Handle.Label;
  8198.     end Field_Label;
  8199.  
  8200.     ---------------------------------------------------------------------------
  8201.  
  8202.     function Field_Length(             --| Returns the length of a field
  8203.         Template     : Template_Name;  --| Template containing field
  8204.         Field_Number : Actual_Field_Number_Range
  8205.                                        --| Field whose length to return
  8206.         ) return Positive is
  8207.         Field_Handle : Template_Field_Handle;
  8208.     begin
  8209.         Field_Handle := Template_Info(Template).Fields(Field_Number);
  8210.         if Field_Handle = null then
  8211.             raise No_Such_Field;
  8212.         end if;
  8213.         if Field_Handle.Mode = Variable then
  8214.             return Field_Handle.Length;
  8215.         end if;
  8216.         return SS.Length(Field_Handle.Label);
  8217.     end Field_Length;
  8218.  
  8219.     ---------------------------------------------------------------------------
  8220.  
  8221.     function Field_Help(                   --| Returns help line for a field
  8222.         Template     : Template_Name;      --| Template containing field
  8223.         Field_Number : Variable_Field_Number_Range
  8224.                                            --| Field whose help to return
  8225.         ) return SS.Screen_String is
  8226.         Field_Handle : Template_Field_Handle;
  8227.         Count_Total  : Actual_Field_Range   := 0;
  8228.         Count_Var    : Variable_Field_Range := 0;
  8229.     begin
  8230.         while Count_Var < Field_Number loop
  8231.             if Count_Total = Actual_Field_Number_Range'Last then
  8232.                 raise No_Such_Field;
  8233.             end if;
  8234.             Count_Total := Count_Total + 1;
  8235.             if (Template_Info(Template).Fields(Count_Total) = null) then
  8236.                 raise No_Such_Field;
  8237.             end if;
  8238.             if Template_Info(Template).Fields(Count_Total).Mode = Variable then
  8239.                 Count_Var := Count_Var + 1;
  8240.             end if;
  8241.         end loop;
  8242.         Field_Handle := Template_Info(Template).Fields(Count_Total);
  8243.         return Field_Handle.Help_Line;
  8244.     end Field_Help;
  8245.  
  8246.     ---------------------------------------------------------------------------
  8247.  
  8248. end Templates;
  8249.  
  8250. -------------------------------------------------------------------------------
  8251. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8252. --UDRIVER.ADA
  8253. --::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  8254. with Text_IO; use Text_IO;
  8255. with Update;
  8256. with Dictionary_Manager;
  8257. with Standard_Interface;
  8258. with DD_Release;
  8259. with String_Pkg;
  8260. with Host_Lib;
  8261. -------------------------------------------------------------------------------
  8262.  
  8263. function Update_Dictionary_Driver return Integer is
  8264. --| Interprets command line and calls Update_Dictionary routine
  8265.  
  8266.     package DM renames Dictionary_Manager;
  8267.     package SI renames Standard_Interface;
  8268.     package SP renames String_Pkg;
  8269.       
  8270.     package Str_Argument is new SI.String_Argument("String");
  8271.       
  8272.     Update_Handle : SI.Process_Handle;
  8273.  
  8274. begin
  8275.  
  8276.     -- Error messages go to standard error
  8277.     Host_Lib.Set_Error;
  8278.  
  8279.     SI.Set_Tool_Identifier(DD_Release);
  8280.     
  8281.     SI.Define_Process(
  8282.         Name => "Update_Dictionary",
  8283.         Help => "Update data dictionary",
  8284.         Proc => Update_Handle);
  8285.  
  8286.     Str_Argument.Define_Argument(
  8287.         Proc => Update_Handle,
  8288.         Name => "Dictionary",
  8289.         Help => "Full directory name of dictionary to be updated");
  8290.     
  8291.     Str_Argument.Define_Argument(
  8292.         Proc => Update_Handle,
  8293.         Name => "Command_File",
  8294.         Help => "Command file containing update directives");
  8295.  
  8296.     SI.Parse_Line(Update_Handle);
  8297.     
  8298.     Update.Process_Update_Commands(
  8299.         SP.Value(Str_Argument.Get_Argument(
  8300.             Proc => Update_Handle,
  8301.             Name => "Dictionary")),
  8302.         SP.Value(Str_Argument.Get_Argument(
  8303.             Proc => Update_Handle,
  8304.             Name => "Command_File")));
  8305.  
  8306.     return Host_Lib.Return_Code(Host_Lib.Success);
  8307.  
  8308. exception
  8309.     when SI.Abort_Process => 
  8310.         return Host_Lib.Return_Code(Host_Lib.Error);
  8311.     when SI.Process_Help =>
  8312.         return Host_Lib.Return_Code(Host_Lib.Information);
  8313.     when Update.Abort_Update =>
  8314.         return Host_Lib.Return_Code(Host_Lib.Error);
  8315.     when DM.Invalid_Dictionary_File =>
  8316.         return Host_Lib.Return_Code(Host_Lib.Error);
  8317.     when DM.Dictionary_Locked =>
  8318.         Put_Line("Dictionary is locked by another user.");
  8319.         return Host_Lib.Return_Code(Host_Lib.Error);
  8320.     when DM.Lock_is_Missing =>
  8321.         Put_Line("Lock file for dictionary is missing.");
  8322.         return Host_Lib.Return_Code(Host_Lib.Error);
  8323.     when DM.Index_File_Error =>
  8324.         return Host_Lib.Return_Code(Host_Lib.Error);
  8325.     when DM.Data_File_Error =>
  8326.         return Host_Lib.Return_Code(Host_Lib.Error);
  8327.     when others =>
  8328.         Put_Line("Update_Dictionary internal error.");
  8329.         begin
  8330.             DM.Close_Dictionary;
  8331.         exception
  8332.             when others => null;
  8333.         end;
  8334.         return Host_Lib.Return_Code(Host_Lib.Error);
  8335.     
  8336. end Update_Dictionary_Driver;
  8337.