home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / style / stylesrc.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  400.1 KB  |  10,162 lines

  1. ::::::::::
  2. stylesrc.dis
  3. ::::::::::
  4. @STYLE_CMP.DIS
  5. STYLE_CMP.CLI
  6. -- The following is the command file to invoke the style checker
  7. STYLE.CLI
  8. style_help.ini
  9. ::::::::::
  10. STYLE_CMP.DIS
  11. ::::::::::
  12.  
  13. --
  14. --    Compilation order for STYLE_CHECKER
  15. --
  16. --
  17. --    DYN (dynamic string) package (specification and body)
  18. dyn.ada
  19. --    FILE_HANDLING package specification
  20. -- file_spec.ada
  21. filespec.ada
  22. --    TOKENIZER package specification
  23. -- tokenizer_spec.ada
  24. tokenzspe.ada
  25. --    STYLE_PARAMETERS package specification
  26. -- style_param_spec.ada
  27. sparamspe.ada
  28. --    REPORT_GENERATOR package specification
  29. -- report_gen_spec.ada
  30. repgenspe.ada
  31. --    STACK_PACKAGE package (specification and body)
  32. -- stack_package.ada
  33. stackpack.ada
  34. --    two packages from spelling checker
  35. --       TOKEN_DEFINITION package (specification and body)
  36. -- token_definition.ada
  37. tokendefi.ada
  38. --       MANAGER package (specification and body)
  39. manager.ada
  40. --    HELP package specification
  41. -- help_file_spec.ada
  42. helpfiles.ada
  43. --    COMMAND_LINE_HANDLER package (specification and body)
  44. -- command_line.ada
  45. commandli.ada
  46. --    HELP_UTILITY packages
  47. -- HELP_SPEC.ADA
  48. helpspec.ada
  49. -- HELPINFO_SPEC.ADA
  50. HELPINFOS.ADA
  51. -- HELPINFO_BODY.ADA
  52. HELPINFOB.ADA
  53. -- HELP_BODY.ADA
  54. HELPBODY.ADA
  55. -- HELP_DIS_ALL.ADA
  56. HELPDISAL.ADA
  57. -- HELP_EXIT.ADA
  58. HELPEXIT.ADA
  59. -- HELP_FIND.ADA
  60. HELPFIND.ADA
  61. -- HELP_GET.ADA
  62. HELPGET.ADA
  63. -- HELP_INIT.ADA
  64. HELPINIT.ADA
  65. -- HELP_ME.ADA
  66. HELPME.ADA
  67. -- HELP_MENU.ADA
  68. HELPMENU.ADA
  69. -- HELP_PROMPT.ADA
  70. HELPPROMP.ADA
  71. -- HELP_RESET.ADA
  72. HELPRESET.ADA
  73. -- HELP_TEXT.ADA
  74. HELPTEXT.ADA
  75. --
  76. --
  77. -- And now the bodies...
  78. --
  79. --    HELP package body
  80. -- help_file_body.ada
  81. HELPFILEB.ADA
  82. --    FILE_HANDLING package body
  83. -- file_body.ada
  84. filebody.ada
  85. --    TOKENIZER package body and all its seperate files
  86. -- tokenizer_body.ada
  87. tokenzbod.ada
  88. insert.ada
  89. -- is_a_reserved_word.ada
  90. isareserv.ada
  91. -- reserved_word.ada
  92. reservedw.ada
  93. -- next_character.ada
  94. nextchara.ada
  95. -- next_identifier.ada
  96. nextident.ada
  97. -- build_tokens.ada
  98. buildtoke.ada
  99. -- line_containing.ada
  100. lineconta.ada
  101. -- tree_root.ada
  102. treeroot.ada
  103. --    STYLE_PARAMETERS package body
  104. -- style_param_body.ada
  105. SPARAMBOD.ADA
  106. --    REPORT_GENERATOR package body
  107. -- report_gen_body.ada
  108. repgenbod.ada
  109. --    Main procedure (STYLE_CHECKER) and all its seperate files
  110. -- style_checker.ada
  111. stylechec.ada
  112. -- begin_of_line_indent.ada
  113. beginofli.ada
  114. -- check_statements.ada
  115. checkstat.ada
  116. -- check_end_of_blocks.ada
  117. checkendo.ada
  118. -- check_the_style.ada
  119. checkthes.ada
  120. -- check_for_attribute.ada
  121. checkfora.ada
  122. -- check_object_names.ada
  123. checkobje.ada
  124. -- check_universal.ada
  125. checkuniv.ada
  126. -- comment_token.ada
  127. commentto.ada
  128. -- current_token.ada
  129. currentto.ada
  130. -- entering_block.ada
  131. enteringb.ada
  132. -- entering_sub_block.ada
  133. enterings.ada
  134. -- exiting_block.ada
  135. exitingbl.ada
  136. -- get_next_token.ada
  137. getnextto.ada
  138. -- is_statement.ada
  139. isstateme.ada
  140. literal.ada
  141. -- new_line_token.ada
  142. newlineto.ada
  143. -- non_trivial_token.ada
  144. nontrivia.ada
  145. -- object_name.ada
  146. objectnam.ada
  147. -- reserve_word.ada
  148. reservewo.ada
  149. -- search_backward.ada
  150. srchbackw.ada
  151. -- search_back_one_of.ada
  152. srchbacko.ada
  153. -- search_forward.ada
  154. srchforwa.ada
  155. -- search_fore_one_of.ada
  156. srchforeo.ada
  157. -- type_declaration.ada
  158. typedecla.ada
  159. ::::::::::
  160. dyn.ada
  161. ::::::::::
  162. with text_io; use text_io;
  163. package DYN is
  164.  
  165. ------------------------------------------------------------------------------
  166. --  This is a package of several string manipulation functions based on     --
  167. -- a built-in dynamic string type DYN_STRING.  It is an adaptation and      --
  168. -- extension of the package proposed by Sylvan Rubin of Ford Aerospace and  --
  169. -- Communications Corporation in the Nov/Dec 1984 issue of the Journal of   --
  170. -- Pascal, Ada and Modula-2.  Some new functions have been added, the       --
  171. -- SUBSTRING function has been modified to permit it to return the right    --
  172. -- part of a string if the third parameter is permitted to default, and     --
  173. -- much of the body code has been rewritten.                                --
  174. ------------------------------------------------------------------------------
  175. -- R.G. Cleaveland 07 December 1984:                                        --
  176. --  Implementation initially with the Telesoft Ada version                  --
  177. -- This required definition of the DYN_STRING type without use of a         --
  178. -- discriminant; an arbitrary maximum string length was chosen.  This       --
  179. -- should be changed when an improved compiler is available.                --
  180. ------------------------------------------------------------------------------
  181. -- Richard Powers 03 January 1985:                                          --
  182. -- changed to be used with a real compiler.                                 --
  183. -- Some of the routines removed by my whim.                                 --
  184. ------------------------------------------------------------------------------
  185. -- Richard Powers 26 January 1985:
  186. -- Added UPPER_CASE function
  187. ------------------------------------------------------------------------------
  188.  
  189. type DYN_STRING is private;
  190.  
  191. STRING_TOO_SHORT: exception;
  192.  
  193. function D_STRING(CHAR: character)  return DYN_STRING;
  194.         -- Creates a one-byte dynamic string of contents CHAR.
  195.  
  196. function D_STRING(STR : string   )  return DYN_STRING;
  197.         -- Creates a dynamic string of contents STR.
  198.  
  199. -- The following four functions convert from dynamic strings to the
  200. -- desired representation:
  201. function CHAR(DSTR: DYN_STRING) return character;
  202. function STR (DSTR: DYN_STRING) return string;
  203. function INT (DSTR: DYN_STRING) return integer;
  204. function FLT (DSTR: DYN_STRING) return float;
  205.  
  206. function LENGTH(DSTR: DYN_STRING) return natural;
  207. function "<" (DS1, DS2: DYN_STRING) return boolean;
  208. function "&" (DS1, DS2: DYN_STRING) return DYN_STRING;
  209.  
  210. function SUBSTRING (DSTR: DYN_STRING;      -- Returns a subpart of this string
  211.                     START  : natural;      -- starting at this position
  212.                     LENGTH : natural := 0) -- and of this length.
  213.                 return DYN_STRING;
  214.                 -- if LENGTH is zero or not specified, the remainder of the
  215.                 -- string is returned (eg the "RIGHT" function).
  216.  
  217. function INDEX (SOURCE_STRING,              --If this string contains
  218.                 PATTERN_STRING: DYN_STRING; --this string starting at or AFTER
  219.                 START_POS: integer)         --this position, the position of
  220.                 return integer;             --such start is returned.
  221.                 -- If the string lengths prohibit the search -1 is returned.
  222.                 -- If no match was found, 0 is returned.
  223.                 -- (This is like the INSTR function of BASIC).
  224.  
  225. function RINDEX (SOURCE_STRING,             --If this string contains
  226.                 PATTERN_STRING: DYN_STRING; --this string starting at or BEFORE
  227.                 START_POS: integer)         --this position, the position of
  228.                 return integer;             --such start is returned.
  229.                 -- If the string lengths prohibit the search -1 is returned.
  230.                 -- If no match was found, 0 is returned.
  231.  
  232. function UPPER_CASE(STRG : in DYN.DYN_STRING) return STRING;
  233.                 -- Return the input string in upper case
  234.  
  235. private
  236.  
  237.         type STRING_CONTENTS(SIZE : natural := 0) is
  238.            record
  239.                DATA: string(1..SIZE);
  240.            end record;
  241.  
  242.         type DYN_STRING is access STRING_CONTENTS;
  243.  
  244. end DYN;
  245.  
  246. ----------------------------------------------------------------------------
  247.  
  248. package body DYN is
  249.  
  250. package MY_INTEGER_IO is new INTEGER_IO(INTEGER);
  251.  
  252. package MY_FLOAT_IO is new FLOAT_IO(FLOAT);
  253.  
  254. function "&" (DS1, DS2: DYN_STRING) return DYN_STRING is
  255.         DS3 : DYN_STRING;
  256.     begin
  257.         DS3 := new STRING_CONTENTS(DS1.SIZE+DS2.SIZE);
  258.         DS3.DATA(1..DS3.SIZE):=   DS1.DATA(1..DS1.SIZE)
  259.                                 & DS2.DATA(1..DS2.SIZE);
  260.         return DS3;
  261.     end "&";
  262.  
  263. function D_STRING(CHAR: character)  return DYN_STRING is
  264.         DS : DYN_STRING;
  265.     begin
  266.         DS := new STRING_CONTENTS(SIZE=>1);
  267.         DS.DATA(1) := CHAR;
  268.         return DS;
  269.     end D_STRING;
  270.  
  271. function D_STRING(STR : string   )  return DYN_STRING is
  272.         DS : DYN_STRING;
  273.     begin
  274.         DS := new STRING_CONTENTS(SIZE => STR'length);
  275.         DS.DATA(1..DS.SIZE)  := STR;
  276.         return DS;
  277.     end D_STRING;
  278.  
  279. function CHAR(DSTR: DYN_STRING) return character is
  280.     begin
  281.         return DSTR.DATA(1);
  282.     end CHAR;
  283.  
  284. function STR (DSTR: DYN_STRING) return string is
  285.     begin
  286.         return DSTR.DATA(1..DSTR.SIZE);
  287.     end STR;
  288.  
  289. function INT (DSTR: DYN_STRING) return integer is
  290.         V: integer;
  291.         L: positive;
  292.     begin
  293.         MY_INTEGER_IO.get(STR(DSTR),V,L);
  294.         return V;
  295.     end INT;
  296.  
  297. function FLT (DSTR: DYN_STRING) return float is
  298.         V: float;
  299.         L: positive;
  300.     begin
  301.         MY_FLOAT_IO.get(STR(DSTR),V,L);
  302.         return V;
  303.     end FLT;
  304.  
  305. function LENGTH(DSTR: DYN_STRING) return natural is
  306.     begin
  307.         return DSTR.SIZE;
  308.     end LENGTH;
  309.  
  310. function "<" (DS1, DS2: DYN_STRING) return boolean is
  311.     begin
  312.         if STR(DS1) < STR(DS2)
  313.         then return (TRUE);
  314.         else return (FALSE);
  315.         end if;
  316.     end "<";
  317.  
  318. function SUBSTRING (DSTR: DYN_STRING;
  319.                     START  : natural;
  320.                     LENGTH : natural := 0)
  321.                                            return DYN_STRING is
  322.         DS: DYN_STRING;
  323.         L : natural := LENGTH;
  324.     begin
  325.         if (START < 1) or (START > DSTR.SIZE)
  326.         then raise CONSTRAINT_ERROR;
  327.         else if L = 0
  328.              then L := DSTR.SIZE-START+1;
  329.              end if;
  330.              if DSTR.SIZE < START + L - 1
  331.              then  raise STRING_TOO_SHORT;
  332.              else
  333.                    DS := new STRING_CONTENTS(L);
  334.                    DS.DATA(1..L) := DSTR.DATA(START..START+L-1);
  335.                    return DS;
  336.              end if;
  337.          end if;
  338.     end SUBSTRING;
  339.  
  340. function INDEX(SOURCE_STRING, PATTERN_STRING: DYN_STRING;
  341.                         START_POS: integer) return integer is
  342.         NO_MATCH        : integer := 0;
  343.         NO_FIT          : integer := -1;
  344.     begin
  345.         if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POS - 1
  346.         or START_POS < 1
  347.         then return NO_FIT;
  348.         end if;
  349.         for I in START_POS..SOURCE_STRING.SIZE-PATTERN_STRING.SIZE+1 loop
  350.             if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
  351.                = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE)
  352.             then return I;
  353.             end if;
  354.         end loop;
  355.         return NO_MATCH;
  356.     end INDEX;
  357.  
  358. function RINDEX(SOURCE_STRING, PATTERN_STRING: DYN_STRING;
  359.                         START_POS: integer) return integer is
  360.         NO_MATCH        : integer := 0;
  361.         NO_FIT          : integer := -1;
  362.     begin
  363.         if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POS - 1
  364.         or START_POS < 1
  365.         then return NO_FIT;
  366.         end if;
  367.         for I in reverse 1..START_POS loop
  368.             if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
  369.                = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE)
  370.             then return I;
  371.             end if;
  372.         end loop;
  373.         return NO_MATCH;
  374.     end RINDEX;
  375.  
  376.     function UPPER_CASE(STRG : in DYN.DYN_STRING) return STRING is
  377.         ANSWER : STRING(1..LENGTH(STRG));
  378.     begin
  379.         ANSWER := STR(STRG);
  380.         for I in 1..LENGTH(STRG) loop
  381.             if (ANSWER(I) >= 'a') and (ANSWER(I) <= 'z') then
  382.                 ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(ANSWER(I)) -
  383.                     CHARACTER'POS('a') + CHARACTER'POS('A'));
  384.             end if;
  385.         end loop;
  386.         return ANSWER;
  387. end UPPER_CASE;
  388.  
  389. end DYN;
  390. ::::::::::
  391. filespec.ada
  392. ::::::::::
  393. --
  394. -- FILE_HANDLING by Richard Conn, TI Ada Technology Branch
  395. -- 28 Feb 85
  396. --
  397. with TEXT_IO;
  398. package FILE_HANDLING is
  399. --------------------------------------------------------------------------
  400. -- Abstract   : FILE_HANDLING returns FILE_IDs for all files specified
  401. --               as parameters, either directly or indirectly, in the
  402. --               command line.  Any file name prefixed by the special
  403. --               character '@' is an indirect file, which contains the
  404. --               names of other files to check and other indirect files.
  405. --               Indirect files may be nested several levels deep (set by
  406. --               a constant), and the prefix character for indirect files
  407. --               may be changed (also by a constant).
  408. --------------------------------------------------------------------------
  409.  
  410.     HELP_ASKED_FOR         : exception;
  411.  
  412.     HELP_FILE_NAME         : constant STRING := "STYLE_HELP.INI";
  413.     STYLE_DICTIONARY_NAME  : constant STRING :=
  414.         "STYLE_DICTIONARY.INI";
  415.  
  416.     procedure INPUT_FILE_ID (FILE_ID    : in out TEXT_IO.FILE_TYPE;
  417.                              MORE_FILES : out BOOLEAN);
  418. --------------------------------------------------------------------------
  419. -- Abstract   : INPUT_FILE_ID returns the next file id of the next file
  420. --               in the direct or indirect file name list from the
  421. --               command line.
  422. --------------------------------------------------------------------------
  423. -- Parameters : FILE_ID        - ID of next file
  424. --              MORE_FILES     - FALSE if no more files available
  425. --                                (FILE_ID is also invalid at this point)
  426. --------------------------------------------------------------------------
  427.  
  428.  
  429.     procedure OUTPUT_FILE_ID (FLAWS_FILE_ID : in out TEXT_IO.FILE_TYPE;
  430.                               STYLE_FILE_ID : in out TEXT_IO.FILE_TYPE);
  431. --------------------------------------------------------------------------
  432. -- Abstract   : OUTPUT_FILE_ID returns the file IDs of the Flaws and Style
  433. --               files.  The names of these files were built from the first
  434. --               file indicated in the list of file names.
  435. --------------------------------------------------------------------------
  436. -- Parameters : FLAWS_FILE_ID  - ID of Flaws File
  437. --              STYLE_FILE_ID  - ID of Style File
  438. --------------------------------------------------------------------------
  439.  
  440. end FILE_HANDLING;
  441. ::::::::::
  442. tokenzspe.ada
  443. ::::::::::
  444. with DYN;
  445. with TEXT_IO;
  446. package TOKENIZER is
  447. --------------------------------------------------------------------------
  448. -- Abstract   : This package contains the interfaces to the Tokenizer part
  449. --              of the Style_Checker.  The tokenizer splits the input Ada
  450. --              source into "tokens".
  451. --------------------------------------------------------------------------
  452.  
  453.     type TOKEN is private;
  454.  
  455. -- Ranges
  456.     subtype LINE_NUM_RANGE is NATURAL range 0 .. NATURAL'LAST;
  457.     subtype LINE_INDEX_RANGE is NATURAL range 0 .. 255;
  458. -- Types of tokens
  459.  
  460.     type TOKEN_TYPE is (
  461.         --  First the reserved word tokens, alphabetized by LENGTH
  462.         AT_TOKEN, DO_TOKEN, IF_TOKEN, IN_TOKEN, IS_TOKEN, OF_TOKEN, OR_TOKEN,
  463.         ABS_TOKEN, ALL_TOKEN, AND_TOKEN, END_TOKEN, FOR_TOKEN,  MOD_TOKEN,
  464.         NEW_TOKEN, NOT_TOKEN, OUT_TOKEN, REM_TOKEN, USE_TOKEN, XOR_TOKEN,
  465.         BODY_TOKEN, CASE_TOKEN, ELSE_TOKEN, EXIT_TOKEN, GOTO_TOKEN, LOOP_TOKEN,
  466.         NULL_TOKEN, TASK_TOKEN, THEN_TOKEN, TYPE_TOKEN, WHEN_TOKEN, WITH_TOKEN,
  467.         ABORT_TOKEN, ARRAY_TOKEN, BEGIN_TOKEN, DELAY_TOKEN, DELTA_TOKEN,
  468.         ELSIF_TOKEN, ENTRY_TOKEN, RAISE_TOKEN, RANGE_TOKEN, WHILE_TOKEN,
  469.         ACCEPT_TOKEN, ACCESS_TOKEN, DIGITS_TOKEN, OTHERS_TOKEN, PRAGMA_TOKEN,
  470.         RECORD_TOKEN, RETURN_TOKEN, SELECT_TOKEN,
  471.         DECLARE_TOKEN, GENERIC_TOKEN, LIMITED_TOKEN, PACKAGE_TOKEN,
  472.         PRIVATE_TOKEN, RENAMES_TOKEN, REVERSE_TOKEN, SUBTYPE_TOKEN,
  473.         CONSTANT_TOKEN, FUNCTION_TOKEN, SEPARATE_TOKEN,
  474.         EXCEPTION_TOKEN, PROCEDURE_TOKEN, TERMINATE_TOKEN,
  475.         --  Followed by the other tokens (in no particular order)
  476.         END_OF_LINE,
  477.         END_OF_FILE,
  478.         IDENTIFIER,
  479.         NUMERIC_LITERAL,
  480.         STRING_LITERAL,
  481.         CHARACTER_LITERAL,
  482.         CONCATENATION_OPERATOR,         -- &
  483.         TICK,                           -- '
  484.         RIGHT_PARENTHESIS,              -- (
  485.         LEFT_PARENTHESIS,               -- )
  486.         MULTIPLICATION_OPERATOR,        -- *
  487.         ADDITION_OPERATOR,              -- +
  488.         COMMA,                          -- ,
  489.         SUBTRACTION_OPERATOR,           -- -
  490.         PERIOD,                         -- .
  491.         DIVISION_OPERATOR,              -- /
  492.         COLON,                          -- :
  493.         SEMICOLON,                      -- ;
  494.         LESS_THAN_OPERATOR,             -- <
  495.         EQUAL_OPERATOR,                 -- =
  496.         GREATER_THAN_OPERATOR,          -- >
  497.         VERTICAL_BAR,                   -- |
  498.         COMMENT,                        -- --
  499.         ARROW,                          -- =>
  500.         DOUBLE_DOT,                     -- ..
  501.         EXPONENTIATE_OPERATOR,          -- **
  502.         ASSIGNMENT_OPERATOR,            -- :=
  503.         INEQUAL_OPERATOR,               -- /=
  504.         GREATER_THAN_OR_EQUAL_OPERATOR, -- >=
  505.         LESS_THAN_OR_EQUAL_OPERATOR,    -- <=
  506.         LEFT_LABEL_BRACKET,             -- <<
  507.         RIGHT_LABEL_BRACKET,            -- >>
  508.         BOX,                            -- <>
  509.         ANYTHING_ELSE);
  510.  
  511.   subtype KEYWORDS is TOKEN_TYPE range AT_TOKEN .. TERMINATE_TOKEN;
  512.  
  513. --  Types associated with the IDENTIFIER binary tree
  514.  
  515.     type REFS;                                   -- occurrence of an identifier
  516.  
  517.     type REFPTR is access REFS;                  -- pointers to references
  518.  
  519.     type REFS is                                 --
  520.         record
  521.             STRG : DYN.DYN_STRING;               -- identifier
  522.             NEXT : REFPTR;                       -- chained to other occurrences
  523.         end record;
  524.  
  525.     type IDENTIFIER_NODE;                        -- element of identifier tree
  526.  
  527.     type IDENTIFIER_TREE is access IDENTIFIER_NODE;
  528.                                                  -- binary tree used to sort
  529.     type IDENTIFIER_NODE is                      -- Tokens
  530.         record
  531.             LEFT, RIGHT : IDENTIFIER_TREE;       -- links to other nodes
  532.             REFERENCES : REFPTR;                 -- identifier chain
  533.         end record;
  534.  
  535. --  Externally visible functions and procedures
  536.  
  537.     function EXTERNAL_REPRESENTATION(CURRENT_TOKEN : in TOKEN) return
  538.         DYN.DYN_STRING;
  539.  
  540.     function TREE_ROOT return IDENTIFIER_TREE;
  541.     function FIRST_TOKEN return TOKEN;
  542.     function LENGTH_OF_COMMENT(CURRENT_TOKEN : in TOKEN) return NATURAL;
  543.     function NEXT_TOKEN(CURRENT_TOKEN : in TOKEN) return TOKEN;
  544.     function PREVIOUS_TOKEN(CURRENT_TOKEN : in TOKEN) return TOKEN;
  545.     function TYPE_OF_TOKEN_IS(CURRENT_TOKEN : in TOKEN) return TOKEN_TYPE;
  546.  
  547.     procedure BUILD_TOKENS;
  548.     procedure TOKEN_POSITION(CURRENT_TOKEN : in TOKEN;
  549.                              LINE : out LINE_NUM_RANGE;
  550.                              COLUMN : out LINE_INDEX_RANGE);
  551.     procedure LINE_CONTAINING_TOKEN(CURRENT_TOKEN : in TOKEN;
  552.                                     LINE : out DYN.DYN_STRING);
  553. --  Exceptions exported
  554.  
  555.     END_OF_TOKENS : exception;                   -- End of token signal
  556.  
  557.     INVALID_TOKEN : exception;                   -- Invalid token passed in
  558.  
  559. private
  560. --  Types used for identifier tree
  561.  
  562.     type TOKEN_POINTER is access TOKEN;
  563.  
  564.     type TOKEN_POSITION_RECORD is
  565.         record
  566.             LINE : LINE_NUM_RANGE;
  567.             COLUMN : LINE_INDEX_RANGE;
  568.         end record;
  569.  
  570.     type TOKEN is
  571.         record
  572.             TYPE_OF_TOKEN : TOKEN_TYPE;
  573.             PHYSICAL_REPRESENTATION : DYN.DYN_STRING;
  574.             TOKEN_POSITION : TOKEN_POSITION_RECORD;
  575.             NEXT_TOKEN : TOKEN_POINTER;
  576.             PREVIOUS_TOKEN : TOKEN_POINTER;
  577.         end record;
  578. end TOKENIZER;
  579. ::::::::::
  580. sparamspe.ada
  581. ::::::::::
  582. ------ CPCI-Level PROLOGUE ------
  583.  
  584. --|CPCI Name    I: Style_Parameters
  585. --|Responsible Manager  : John Mellby
  586. --|CPCI II: Style_Parameters
  587. --|Compliance   I:
  588. --
  589. --|Abstract     I: This package is responsible for inputting the
  590. --                        parameters determining the style from a file,
  591. --                        then making them available to the 'style-checking'
  592. --                        remainder of the system.
  593. --
  594. --|Notes        I:
  595. --
  596. --|Implementation Language : Ada
  597. --|LOC  II:
  598. --|Requirements I:
  599. --|Requirements, Derived: The parameters defining the "Style" will be
  600. --                        read into the program from a file.
  601. --|Requirements, Implied:
  602. --|Technical References :
  603. --
  604. --|Program References
  605.         with DYN;                -- Dynamic String Package
  606.         with Tokenizer;
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621. ---- END CPCI-Level PROLOGUE ----
  622.  
  623.  
  624. --                         Style Checker
  625. --                      P A R A M E T E R S
  626.  
  627. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  628. package Style_Parameters is
  629.  
  630.    Number_of_Keywords : constant integer
  631.         := 1 + (Tokenizer.Keywords'pos(Tokenizer.Keywords'last))
  632.              - (Tokenizer.Keywords'pos(Tokenizer.Keywords'first));
  633.    subtype Keyword_Range is integer range 0..Number_of_Keywords;
  634.    type Keyword_Options  is (All_Keys, Used, Not_Used, Errors, None);
  635.    type Require_Type     is (Required, Not_Required);
  636.  
  637. -- Word and case parameters
  638.    subtype Word_Lengths       is natural;
  639.  
  640.    type Reserve_Word_Cases is (Reserved_Case_Upper,
  641.                               Reserved_Case_Lower,
  642.                               Reserved_Case_Consistant,
  643.                               Reserved_Case_Any);
  644.  
  645.    type Object_Name_Cases  is (Name_Case_Upper,
  646.                               Name_Case_Lower,
  647.                               Name_Case_First_Capitalized,
  648.                               Name_Case_Consistant,
  649.                               Name_Case_Any);
  650.  
  651.  
  652.    subtype Abbreviation_Aves is Float;
  653.  
  654. -- Physical Layout
  655.    type Loop_Names_Needs is  (Required, Average, not_Required);
  656.  
  657. -- Transportability
  658.    type Character_Set_Types is (Basic, Graphic, Extended);
  659.    type Pragma_Classes   is  (All_Pragmas, System_Dependent, None);
  660. --
  661. -- The following is probably to be located in the package body.
  662. --   type Package_Name_Node;
  663. --   type Package_List     is access Package_Name_node;
  664. --   type Package_Name_Node is
  665. --         record
  666. --           P_Name : DYN.DYN_STRING;
  667. --           Next   : Package_List;
  668. --         end record;
  669.  
  670. -- Statement Use
  671.    type Keyword_Use_Type is  (No_Use, Restricted_Use, Free_Use);
  672.    type Keyword_Use_Descript is record
  673.                              Use_Class : Keyword_Use_Type := Free_Use;
  674.                              Use_Freq  : float := 0.0;
  675.                            end record;
  676.    type Keyword_Uses    is array( Tokenizer.keywords ) of Keyword_Use_descript;
  677.  
  678. -------------------------------------
  679. -- This procedure obtains the 'style
  680. -------------------------------------
  681.   Procedure Set_Style_Parameters;
  682.           -- This sets the parameter variables.
  683.  
  684. --------------------------------------------
  685. -- These return style individual parameters
  686. --------------------------------------------
  687.   function Number_of_Errors_to_Report return natural;
  688.   -- This returns a number telling how many times to list
  689.   -- a error in the "Flaws" output.  I.E. If this returns
  690.   -- "3", then only the first three occurences of each
  691.   -- type of error are listed.
  692.  
  693.   function OUTPUT_KEYWORD_LIST return Keyword_Options;
  694.   -- This function returns a value specifying the output format for
  695.   -- listing the reserved word usage.  It specifys which class of
  696.   -- reserved words to output, all keywords, only those keywords
  697.   -- used or not used, keywords used in violation of style restrictions,
  698.   -- or no keywords output.
  699.  
  700.   function OUTPUT_OPERATOR_LIST return boolean;
  701.   -- This function returns true if the operator list is to be printed
  702.   -- as part of the style report.
  703.  
  704.   function SMALL_PROGRAM_SIZE return natural;
  705.   -- returns size of programs considered 'too small' so limits of
  706.   -- some things may be violated with not penalty.
  707.  
  708.   function Small_Word_Size    return Word_Lengths;
  709.   -- returns size of words considered 'too small' so limits of
  710.   -- some things may be violated with no penalty.
  711.  
  712.   function Small_Structure_Size    return Natural;
  713.   -- returns size (in statements) of structures considered 'too small' so
  714.   -- some constraints may be violated with no penalty.
  715.  
  716.   function Case_of_Reserved_Words return Reserve_Word_Cases;
  717.  
  718.   function Case_of_Object_Names return Object_Name_Cases;
  719.  
  720.   function Average_Name_Size  return Word_Lengths;
  721.   -- The average size of names in the program should be greater than
  722.   -- this minimum.
  723.  
  724.   function Is_Underscore_Required return boolean;
  725.   function Average_Underscore_Size return Word_Lengths;
  726.   -- If underscores are required and the word under inspection is
  727.   -- longer than a "Small_Word", then the parts separated by
  728.   -- underscores should be longer than this minimum.
  729.  
  730.   function Vowel_Frequency return float;
  731.   -- To keep people from abbreviating too much, check the percentage of
  732.   -- vowels to consonants.  If (Vowel / Total-letters) is less than
  733.   -- Vowel_Frequency percent, there is something wrong.
  734.   function SPELLING_REQUIRED return Require_Type;
  735.   -- This function returns 'Required' if the style checker is to
  736.   -- send words to a spelling checker to validate variable names.
  737.  
  738.   function Is_One_Statement_per_line_Required return boolean;
  739.   function Is_Declaration_Indentation_Required return boolean;
  740.   -- Forced to indent properly on object, type declarations?
  741.   function Is_Comment_Indentation_Required return boolean;
  742.   -- Forced to indent the trailing comments after statement on a line?
  743.  
  744.   function Is_Blank_Lines_around_Blocks_Required return boolean;
  745.   -- Should blank lines around blocks, loops, etc. be required?
  746.  
  747. -- We deleted this function
  748. --   function Average_Blank_Lines return float;
  749. --   -- The average # of blank lines should be 'Ave-blank-lines' +- delta
  750. --   -- for readability's sake
  751.  
  752.   function Loop_Name_Required return Loop_Names_Needs;
  753.   -- Are loop-names necessary, should loops of a certain size need names.
  754.  
  755.   procedure Reserved_Word_Info ( Usage : out Keyword_Uses );
  756.  
  757.   function Average_Comment_Size return positive;
  758.   -- To prevent style "tricking" comments must have a minimum average
  759.   -- size;
  760.  
  761.   function Average_Literal_in_Body return float;
  762.   -- Literals should be in the declaration rather then the body, so
  763.   -- the number of literals in the body should be less than "ave-literal"
  764.  
  765.   function Average_Universal_Usage return float;
  766.   -- In general, good use should be made of programmer-defined types
  767.   -- rather than universal integer, float, etc.  The percentage of
  768.   -- types which are universal integer, float, natural, positive, etc.
  769.   -- should be less then "ave-universals"
  770.  
  771.   function Is_Data_Structure_Use_Required return boolean;
  772.   -- Should we check for enumeration types, records?
  773.  
  774.   function ATTRIBUTE_CHECK return Require_Type;
  775.   -- This function tells whether the style checker notes the
  776.   -- use of attributes.
  777.  
  778.   procedure Average_Subprogram_Size (SMALL_LIMIT : out natural;
  779.                                      LARGE_LIMIT : out natural );
  780.  
  781.   procedure SUBPROGRAM_PARAMETERS (SMALL_LIMIT : out natural;
  782.                                    LARGE_LIMIT : out natural );
  783.  
  784.  
  785.   function CONTROL_NESTING_LEVEL return Natural;
  786.   -- This is the expected depth of nesting of control structures.
  787.  
  788.   function PACKAGE_NESTING_LEVEL return Natural;
  789.   -- This is the expected depth of nesting of packages.
  790.  
  791.   function SUBPROGRAM_NESTING_LEVEL return Natural;
  792.   -- This is the expected depth of nesting of subprograms.
  793.  
  794.   function NUMBER_OF_LOOP_EXITS return natural;
  795.   -- This number is a limit on the number of exits from a loop.
  796.  
  797.   function LINE_SIZE return natural;
  798.   -- This number is a limit on the number of characters in a line.
  799.  
  800.   function CHARACTER_SET return Character_Set_Types;
  801.   -- This enumeration type determines the characters which are
  802.   -- not flagged as style errors.  This is to limit use of
  803.   -- graphic or extended characters which may not transport to
  804.   -- other machines.
  805.  
  806.   function REPRESENTATION_SPECS_ALLOWED return boolean;
  807.   -- This returns true if rep specs are allowed in the style.
  808.  
  809.   function ADDRESS_CLAUSE_ALLOWED return boolean;
  810.   -- This returns true if address clauses are allowed in the style.
  811.  
  812.   function NOTE_PRAGMAS return Pragma_Classes;
  813.   -- This is an enumeration type defining which pragmas (all, system-
  814.   -- dependent, or none) are illegal as defined in the style
  815.  
  816.   function IS_A_PREDEFINED_PRAGMA (name : in DYN.DYN_STRING ) return boolean;
  817.   -- This returns true if the input name is a predefined pragma as listed
  818.   -- in the LRM appendix B.
  819.  
  820.   function IS_A_PROSCRIBED_PACKAGE (name : in DYN.DYN_STRING) return boolean;
  821.   -- This returns true if the input name is a package on the
  822.   -- list of 'stylistically incorrect' packages as defined by the style.
  823.  
  824. end Style_Parameters;
  825. ::::::::::
  826. repgenspe.ada
  827. ::::::::::
  828. with TEXT_IO;
  829. with STYLE_PARAMETERS;
  830. with TOKENIZER;
  831. with DYN;
  832. package REPORT_GENERATOR is
  833. --------------------------------------------------------------------------
  834. -- Abstract   : This is the package that exports the types and routines
  835. --              necessary to create and write the two report files
  836. --              from the Style_Checker.
  837. --------------------------------------------------------------------------
  838.  
  839.     type TOKEN_COUNT_ARRAY is array (TOKENIZER.TOKEN_TYPE) of NATURAL;
  840.  
  841.     type AVERAGE_KEEPING_RECORD is record
  842.         NUMBER_OF_ITEMS : NATURAL := 0;
  843.         TOTAL_SIZE_OF_ITEMS : NATURAL := 0;
  844.     end record;
  845.  
  846.     type DATA_STRUCTURE_TYPES is (ARRAY_TYPES,
  847.                                   ENUMERATION_TYPES,
  848.                                   RECORD_TYPES);
  849.  
  850.     type DATA_STRUCTURE_TYPES_USED is array (DATA_STRUCTURE_TYPES) of BOOLEAN;
  851.  
  852.     type STRING_NODE;
  853.     type STRING_LIST_TYPE is access STRING_NODE;
  854.     type STRING_NODE is
  855.       record
  856.          NAME : DYN.DYN_STRING;
  857.          NEXT : STRING_LIST_TYPE := null;
  858.       end record;
  859.  
  860.     type CHARACTER_COUNT is array (CHARACTER) of NATURAL;
  861.  
  862.     type REPORT_RECORD is record
  863.         -- Naming Conventions
  864.         INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER           : NATURAL := 0;
  865.         INVALID_CASE_FOR_A_KEYWORD                      : NATURAL := 0;
  866.         ABBREVIATIONS                                   : BOOLEAN := FALSE;
  867.         NAME_SEGMENT_SIZE_DESIRED_MAXIMUM               : NATURAL :=
  868.                                 STYLE_PARAMETERS.AVERAGE_UNDERSCORE_SIZE;
  869.         NAME_SEGMENT_SIZE_ACTUAL                        : FLOAT := 0.0;
  870.         AVERAGE_NAME_SIZE_DESIRED_MINIMUM               : NATURAL :=
  871.                                 STYLE_PARAMETERS.AVERAGE_NAME_SIZE;
  872.         AVERAGE_NAME_SIZE_ACTUAL                        : FLOAT := 0.0;
  873.  
  874.         -- Physical Layout
  875.         OCCURRENCES_OF_MORE_THAN_ONE_STATEMENT_PER_LINE : NATURAL := 0;
  876.         INCONSISTANT_INDENTATION                        : NATURAL := 0;
  877.         MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK          : NATURAL := 0;
  878.         MISSING_PROLOG                                  : NATURAL := 0;
  879.         LOOPS_WITHOUT_NAMES                             : NATURAL := 0;
  880.         PERCENT_OF_BLANK_LINES_DESIRED_MINIMUM          : FLOAT := 0.0;
  881.         PERCENT_OF_BLANK_LINES_ACTUAL                   : FLOAT := 0.0;
  882.  
  883.         -- Information Hiding, Abstraction, Data Use
  884.         PERCENT_OF_LITERALS_IN_BODY_DESIRED_MAXIMUM     : FLOAT :=
  885.                                 STYLE_PARAMETERS.AVERAGE_LITERAL_IN_BODY;
  886.         PERCENT_OF_LITERALS_IN_BODY_ACTUAL              : FLOAT := 0.0;
  887.         PERCENT_OF_UNIVERSAL_TYPES_DESIRED_MAXIMUM      : FLOAT :=
  888.                                 STYLE_PARAMETERS.AVERAGE_UNIVERSAL_USAGE;
  889.         PERCENT_OF_UNIVERSAL_TYPES_ACTUAL               : FLOAT := 0.0;
  890.         DATA_STRUCTURING_TYPES_NOT_USED : DATA_STRUCTURE_TYPES_USED :=
  891.                 (DATA_STRUCTURE_TYPES'FIRST .. DATA_STRUCTURE_TYPES'LAST =>
  892.                  TRUE);
  893.         ATTRIBUTES_USED                                 : BOOLEAN := FALSE;
  894.         OR_ELSES_USED                                   : BOOLEAN := FALSE;
  895.         AND_THENS_USED                                  : BOOLEAN := FALSE;
  896.         EXITS_USED                                      : BOOLEAN := FALSE;
  897.         XORS_USED                                       : BOOLEAN := FALSE;
  898.         ELSIFS_USED                                     : BOOLEAN := FALSE;
  899.         EXCEPTIONS_USED                                 : BOOLEAN := FALSE;
  900.         INS_USED                                        : BOOLEAN := FALSE;
  901.         OUTS_USED                                       : BOOLEAN := FALSE;
  902.         IN_OUTS_USED                                    : BOOLEAN := FALSE;
  903.         PRIVATES_USED                                   : BOOLEAN := FALSE;
  904.         -- Modularity
  905.         AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MINIMUM    : NATURAL := 0;
  906.         AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MAXIMUM    : NATURAL := 0;
  907.         INSTANCES_OF_PARAMETERS_BELOW_MINIMUM           : NATURAL := 0;
  908.         INSTANCES_OF_PARAMETERS_ABOVE_MAXIMUM           : NATURAL := 0;
  909.         AVERAGE_SUBPROGRAM_SIZE_DESIRED_MINIMUM         : NATURAL := 0;
  910.         AVERAGE_SUBPROGRAM_SIZE_DESIRED_MAXIMUM         : NATURAL := 0;
  911.         INSTANCES_OF_SIZE_BELOW_MINIMUM                 : NATURAL := 0;
  912.         INSTANCES_OF_SIZE_ABOVE_MAXIMUM                 : NATURAL := 0;
  913.         INSTANCES_OF_TOO_MANY_EXITS                     : NATURAL := 0;
  914.         CONTROL_STRUCTURE_NESTING_DESIRED_MAXIMUM       : NATURAL :=
  915.                                 STYLE_PARAMETERS.CONTROL_NESTING_LEVEL;
  916.         CONTROL_STRUCTURE_NESTING_EXCEEDING_MAXIMUM     : NATURAL := 0;
  917.         PACKAGE_NESTING_DESIRED_MAXIMUM                 : NATURAL :=
  918.                                 STYLE_PARAMETERS.PACKAGE_NESTING_LEVEL;
  919.         PACKAGE_NESTING_EXCEEDING_MAXIMUM               : NATURAL := 0;
  920.         SUBPROGRAM_NESTING_DESIRED_MAXIMUM              : NATURAL :=
  921.                                 STYLE_PARAMETERS.SUBPROGRAM_NESTING_LEVEL;
  922.         SUBPROGRAM_NESTING_EXCEEDING_MAXIMUM            : NATURAL := 0;
  923.  
  924.         -- Comment Usage
  925.         NUMBER_OF_COMMENTS                              : NATURAL := 0;
  926.         AVERAGE_COMMENT_SIZE_DESIRED_MINIMUM            : NATURAL :=
  927.                                 STYLE_PARAMETERS.AVERAGE_COMMENT_SIZE;
  928.         AVERAGE_COMMENT_SIZE_ACTUAL                     : FLOAT := 0.0;
  929.  
  930.         -- Transportability
  931.         NUMBER_OF_LINES_EXCEEDING_LINE_LENGTH           : NATURAL := 0;
  932.         GRAPHIC_CHARACTERS_USED                         : CHARACTER_COUNT :=
  933.                                 (CHARACTER'FIRST..CHARACTER'LAST => 0);
  934.         NON_GRAPHIC_CHARACTERS_USED                     : CHARACTER_COUNT :=
  935.                                 (CHARACTER'FIRST..CHARACTER'LAST => 0);
  936.         ADDRESS_CLAUSES                                 : NATURAL := 0;
  937.         REPRESENTATION_SPECIFICATIONS                   : NATURAL := 0;
  938.         PRAGMAS_USED                           : STRING_LIST_TYPE := null;
  939.         NON_STANDARD_PRAGMAS_USED              : STRING_LIST_TYPE := null;
  940.         PACKAGES_PROCEDURES_WITHED             : STRING_LIST_TYPE := null;
  941.  
  942.         -- Keyword Usage
  943.         KEYWORD_USAGE                   : STYLE_PARAMETERS.KEYWORD_USES;
  944.         TOKEN_COUNT                     : TOKEN_COUNT_ARRAY :=
  945.                                           (TOKENIZER.TOKEN_TYPE'FIRST ..
  946.                                            TOKENIZER.TOKEN_TYPE'LAST => 0);
  947.     end record;
  948.  
  949.     type ERRORS is
  950.           (INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER,
  951.            INVALID_CASE_FOR_A_KEYWORD,
  952.            ABBREVIATION,
  953.  
  954.            -- Physical Layout
  955.  
  956.            MORE_THAN_ONE_STATEMENT_ON_LINE,
  957.            INCONSISTANT_INDENTATION,
  958.            MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK,
  959.            MISSING_PROLOG,
  960.            LOOP_WITHOUT_NAME,
  961.  
  962.            -- Modularity
  963.  
  964.            TOO_FEW_PARAMETERS,
  965.            TOO_MANY_PARAMETERS,
  966.            SUBPROGRAM_SIZE_BELOW_MINIMUM,
  967.            SUBPROGRAM_SIZE_ABOVE_MAXIMUM,
  968.            TOO_MANY_EXITS,
  969.            PACKAGE_NESTED_TOO_DEEP,
  970.            CONTROL_STRUCTURE_NESTED_TOO_DEEP,
  971.            SUBPROGRAM_NESTED_TOO_DEEP,
  972.  
  973.            -- Transportability
  974.  
  975.            LINE_EXCEEDING_LINE_LENGTH,
  976.            GRAPHIC_CHARACTER_USED,
  977.            NON_GRAPHIC_CHARACTER_USED,
  978.            ADDRESS_CLAUSE_USED,
  979.            REPRESENTATION_SPECIFICATION_USED,
  980.            PRAGMA_USED,
  981.            NON_STANDARD_PRAGMA_USED,
  982.  
  983.            -- Other
  984.  
  985.            UNMATCHED_NESTING,
  986.            OTHER);
  987.  
  988.     procedure PUT_FLAW(TO_THIS : in TEXT_IO.FILE_TYPE;
  989.                        BAD_TOKEN : in TOKENIZER.TOKEN;
  990.                        ERROR_MESSAGE : in DYN.DYN_STRING;
  991.                        ERROR_TYPE : in ERRORS := OTHER  );
  992.  
  993.     procedure PUT_FLAW(TO_THIS : in TEXT_IO.FILE_TYPE;
  994.                        BAD_TOKEN : in TOKENIZER.TOKEN;
  995.                        ERROR_MESSAGE : in STRING;
  996.                        ERROR_TYPE : in ERRORS := OTHER  );
  997.  
  998.     procedure GENERATE_REPORT(FROM_THIS : in REPORT_RECORD;
  999.                               TO_THIS : in TEXT_IO.FILE_TYPE;
  1000.                               FILE_NAME : in DYN.DYN_STRING );
  1001.  
  1002.  
  1003.     procedure INSERT_INTO_LIST ( LIST : in out STRING_LIST_TYPE;
  1004.                                  ELEMENT : DYN.DYN_STRING );
  1005.  
  1006. end REPORT_GENERATOR;
  1007. ::::::::::
  1008. stackpack.ada
  1009. ::::::::::
  1010. -------------------------PROLOGUE---------------------------------------
  1011. --                                                                    -*
  1012. -- Unit name    : STACK_PACKAGE
  1013. -- Author       : Tom Duke
  1014. -- Date created : Sept. 7, 1984
  1015. -- Last update  : Sept. 20, 1984
  1016. --                                                                    -*
  1017. ------------------------------------------------------------------------
  1018. --                                                                    -*
  1019. -- Abstract     : This is a generic package that provides the types,
  1020. ----------------: procedures, and exceptions to define an abstract stack
  1021. ----------------: and its corresponding operations.  Using an
  1022. ----------------: instantiation of this generic package, one can declare
  1023. ----------------: multiple versions of a stack of type HELP_INFO_STACK.
  1024. ----------------: The stack operations provided include:
  1025. ----------------: 1. clear the stack,
  1026. ----------------: 2. pop the stack,
  1027. ----------------: 3. push an element onto the stack, and
  1028. ----------------: 4. access the top element on the stack.
  1029. --                                                                    -*
  1030. ------------------------------------------------------------------------
  1031. --
  1032. -- Mnemonic     :
  1033. -- Name         :
  1034. -- Release date :
  1035. ------------------ Revision history ------------------------------------
  1036. --
  1037. -- DATE  AUTHOR   HISTORY
  1038. --
  1039. --
  1040. --
  1041. --------------------END-PROLOGUE----------------------------------------
  1042.  
  1043. generic
  1044.  
  1045.   type ELEMENTS is private;
  1046.   SIZE : POSITIVE;
  1047.  
  1048. package STACK_PACKAGE is
  1049.  
  1050.   type HELP_INFO_STACK is  private;
  1051.  
  1052.  
  1053.   function TOP_ELEMENT( STACK  : in  HELP_INFO_STACK )
  1054.     return ELEMENTS;
  1055.  
  1056.   function STACK_IS_EMPTY( STACK : in HELP_INFO_STACK )
  1057.     return BOOLEAN;
  1058.  
  1059.   procedure CLEAR_STACK( STACK : in out HELP_INFO_STACK );
  1060.  
  1061.  
  1062.   procedure PUSH       ( FRAME : in ELEMENTS;
  1063.                          STACK : in out HELP_INFO_STACK );
  1064.  
  1065.   procedure POP        ( FRAME : out ELEMENTS;
  1066.                          STACK : in out HELP_INFO_STACK );
  1067.  
  1068.   NULL_STACK      : exception;
  1069.   STACK_OVERFLOW  : exception;
  1070.   STACK_UNDERFLOW : exception;
  1071.  
  1072.  
  1073. private
  1074.  
  1075.   type STACK_LIST is array ( 1 .. SIZE ) of ELEMENTS;
  1076.  
  1077.   type HELP_INFO_STACK  is
  1078.      record
  1079.       CONTENTS       :  STACK_LIST;
  1080.       TOP            :  NATURAL range NATURAL'FIRST .. SIZE := NATURAL'FIRST;
  1081.      end record;
  1082.  
  1083. end STACK_PACKAGE;
  1084.  
  1085.  
  1086. -------------------------------------------------------------------------
  1087.  
  1088.  
  1089. package body STACK_PACKAGE is
  1090.  
  1091. ---------------
  1092. --  function TOP_ELEMENT  --  This function returns the value of the top
  1093. --                            element on the stack.  It does not return a
  1094. --  pointer to the top element.  If the stack is empty, a constraint error
  1095. --  occurs.  The exception handler will then raise the NULL_STACK
  1096. --  exception and pass it to the calling procedure.
  1097. ---------------
  1098.   function TOP_ELEMENT( STACK : in  HELP_INFO_STACK ) return ELEMENTS is
  1099.   begin
  1100.    return STACK.CONTENTS(STACK.TOP);
  1101.    exception
  1102.       when CONSTRAINT_ERROR =>
  1103.          raise NULL_STACK;
  1104.       when others =>
  1105.          raise;
  1106.   end TOP_ELEMENT;
  1107.  
  1108.   ----------
  1109.   --  Is stack empty?
  1110.   ----------
  1111.   function STACK_IS_EMPTY( STACK : in HELP_INFO_STACK )
  1112.     return BOOLEAN is
  1113.   begin
  1114.     return (STACK.TOP = NATURAL'FIRST);
  1115.   exception
  1116.     when OTHERS =>
  1117.          raise;
  1118.   end STACK_IS_EMPTY;
  1119.  
  1120.  
  1121. ---------------
  1122. --  procedure CLEAR_STACK  --  This procedure resets the stack pointer, TOP,
  1123. --                             to a value representing an empty stack.
  1124. ---------------
  1125.   procedure CLEAR_STACK( STACK : in out HELP_INFO_STACK ) is
  1126.   begin
  1127.    STACK.TOP := NATURAL'FIRST;
  1128.   end CLEAR_STACK;
  1129.  
  1130.  
  1131. ---------------
  1132. --  procedure PUSH  --  This procedure attempts to push another element onto
  1133. --                      the stack.  If the stack is full, a constraint error
  1134. --  occurs.  The exception handler will then raise the STACK_OVERFLOW
  1135. --  exception and pass it to the calling procedure.
  1136. ---------------
  1137.   procedure PUSH       ( FRAME : in ELEMENTS;
  1138.                          STACK : in out HELP_INFO_STACK ) is
  1139.   begin
  1140.    STACK.TOP := STACK.TOP + 1;
  1141.    STACK.CONTENTS(STACK.TOP) := FRAME;
  1142.    exception
  1143.       when CONSTRAINT_ERROR =>
  1144.          raise STACK_OVERFLOW;
  1145.       when others =>
  1146.          raise;
  1147.   end PUSH;
  1148.  
  1149.  
  1150. ---------------
  1151. --  procedure POP  --  This procedure attempts to pop an element from
  1152. --                     the stack.  If the stack is empty, a constraint error
  1153. --  occurs.  The exception handler will then raise the STACK_UNDERFLOW
  1154. --  exception and pass it to the calling procedure.
  1155. ---------------
  1156.   procedure POP        ( FRAME : out ELEMENTS;
  1157.                          STACK : in out HELP_INFO_STACK ) is
  1158.   begin
  1159.    FRAME := STACK.CONTENTS(STACK.TOP);
  1160.    STACK.TOP := STACK.TOP - 1;
  1161.    exception
  1162.       when CONSTRAINT_ERROR =>
  1163.          raise STACK_UNDERFLOW;
  1164.       when others =>
  1165.          raise;
  1166.   end POP;
  1167.  
  1168. end STACK_PACKAGE;
  1169. ::::::::::
  1170. tokendefi.ada
  1171. ::::::::::
  1172. -- 
  1173. -- Token-Specific Information for the Spelling Checker
  1174. -- 
  1175. package TOKEN_DEFINITION is
  1176. --------------------------------------------------------------------------
  1177. -- Abstract   : TOKEN_DEFINITION contains the definition of a token
  1178. --               (see type TOKEN_TYPE), including the length of its
  1179. --               word which may be easily changed (see TOKEN_LENGTH).
  1180. -- 
  1181. --              IS_SPECIAL_CHAR is also provided since it is a commonly-
  1182. --               used routine which is employed by more than one package.
  1183. --------------------------------------------------------------------------
  1184.  
  1185. -- 
  1186. -- Definition of a Token (Word)
  1187. -- 
  1188.     TOKEN_LENGTH : constant NATURAL := 25; -- number of characters
  1189.     subtype TOKEN_STRING is STRING (1 .. TOKEN_LENGTH);
  1190.     type TOKEN_TYPE is
  1191.     record
  1192.         WORD   : TOKEN_STRING;
  1193.         LENGTH : NATURAL;
  1194.     end record;
  1195.  
  1196.  
  1197.     function IS_SPECIAL_CHAR (CH : CHARACTER) return BOOLEAN;
  1198. --------------------------------------------------------------------------
  1199. -- Abstract   : Returns a BOOLEAN indicating if the indicated character
  1200. --               is one of the special characters which may be found
  1201. --               within a word or at the end of a word.
  1202. --------------------------------------------------------------------------
  1203. -- Parameters : CH             - character to test
  1204. --------------------------------------------------------------------------
  1205.  
  1206. end TOKEN_DEFINITION;
  1207.  
  1208. package body TOKEN_DEFINITION is
  1209.  
  1210.     SPECIAL_CHARS : constant STRING (1 .. 3) := "-'.";
  1211.  
  1212.     function IS_SPECIAL_CHAR (CH : CHARACTER) return BOOLEAN is
  1213.     begin
  1214.     for I in SPECIAL_CHARS'FIRST .. SPECIAL_CHARS'LAST loop
  1215.         if CH = SPECIAL_CHARS (I) then
  1216.         return TRUE;
  1217.         end if;
  1218.     end loop;
  1219.     return FALSE;
  1220.     end IS_SPECIAL_CHAR;
  1221.  
  1222. end TOKEN_DEFINITION;
  1223. ::::::::::
  1224. manager.ada
  1225. ::::::::::
  1226. ------------------------------------------------------------
  1227. --
  1228. -- Abstract     :   This unit outlines the procedures and functions
  1229. --              :   contained in this package.  The visible section
  1230. --              :   provides the interfaces necessary for commun-
  1231. --              :   ication with the various subunits contained in
  1232. --              :   the package.
  1233. --              :
  1234. --              :   The package is concerned with the handling of the
  1235. --              :   data structures that are utilized for the storage of the
  1236. --              :   information, (words and acronyms), which is used
  1237. --              :   within the Spelling Corrector tool.
  1238. --
  1239. ----------------------------------------------------------------
  1240.  
  1241. with TEXT_IO,
  1242.      TOKEN_DEFINITION;
  1243. package DICTIONARY_MANAGER is
  1244.  
  1245. --Establishes the types of dictionaries available
  1246.   type DICTIONARY_TYPE is (MASTER,ACRONYM,USER);
  1247.  
  1248.   type DICTIONARY_PTR  is private;
  1249.  
  1250.   subtype FILE_NAME_TYPE  is TEXT_IO.FILE_TYPE;
  1251.  
  1252. --A test variable to be removed later
  1253. WORD_COUNTER : NATURAL;
  1254. --
  1255.  
  1256.   NO_MORE_WORDS          : exception; --raised when the NEXT_WORD
  1257.                                       --procedure can no longer return
  1258.                                       --the required number of words or
  1259.                                       --the procedure is called with a
  1260.                                       --word count of 0
  1261.  
  1262.   BAD_WORD               : exception; --An illegal word format
  1263.                                       --raised in the HASH_VALUE function
  1264.   DICTIONARY_ERROR       : exception; --A nonexistent dictionary
  1265.                                       --or dictionary error
  1266.   WORD_NOT_VALID         : exception; --A word not in the dictionary
  1267.                                       --raised in the DELETE_WORD procedure
  1268.   HARDWARE_FAILURE       : exception; --Failure of IO devices
  1269.  
  1270. -- The following procedures and functions are documented in the
  1271. -- package body (DICTIONARY_MANAGER)
  1272.  
  1273.   procedure CREATE_DICTIONARY(DICTIONARY_KIND : in DICTIONARY_TYPE;
  1274.                               DICTIONARY_IN : out DICTIONARY_PTR;
  1275.                               FILENAME : in STRING);
  1276.  
  1277.   procedure TOKEN_IS_FOUND(IN_DICTIONARY : out DICTIONARY_PTR;
  1278.                            WORD : in TOKEN_DEFINITION.TOKEN_TYPE;
  1279.                            FOUND : out BOOLEAN);
  1280.  
  1281. private
  1282.  
  1283.   type WORD_RECORD;
  1284.  
  1285.   type WORD_RECORD_PTR is access WORD_RECORD;
  1286.  
  1287.   type WORD_RECORD is
  1288.     record
  1289.       TOKEN   : TOKEN_DEFINITION.TOKEN_TYPE;
  1290.       NEXT    : WORD_RECORD_PTR;
  1291.     end record;
  1292.  
  1293.   MAX_HASH_BUCKETS : constant POSITIVE := 101;
  1294.  
  1295.   subtype HASH_BUCKET_TYPE is POSITIVE
  1296.                               range POSITIVE'FIRST..MAX_HASH_BUCKETS;
  1297.  
  1298.   type DICTIONARY_HASH_STRUCTURE is array (HASH_BUCKET_TYPE)
  1299.                                     of WORD_RECORD_PTR;
  1300.  
  1301.   type DICTIONARY_RECORD;
  1302.  
  1303.   type DICTIONARY_PTR is access DICTIONARY_RECORD;
  1304.  
  1305.   type DICTIONARY_RECORD is
  1306.     record
  1307.       DICTIONARY_NAME : DICTIONARY_TYPE;
  1308.       ENABLED         : BOOLEAN := FALSE;
  1309.       HASH_TABLE      : DICTIONARY_HASH_STRUCTURE;
  1310.       NEXT_DICTIONARY : DICTIONARY_PTR;
  1311.       ALTER_FLAG      : BOOLEAN := FALSE;
  1312.     end record;
  1313.  
  1314. end DICTIONARY_MANAGER;
  1315.  
  1316. ----------------------------------------------------------------
  1317. --
  1318. -- Abstract     :   This unit is the STUB for the dictionary manager
  1319. --
  1320. ----------------------------------------------------------------
  1321.  
  1322. package body  DICTIONARY_MANAGER is
  1323.  
  1324.   procedure CREATE_DICTIONARY(DICTIONARY_KIND : in DICTIONARY_TYPE;
  1325.                               DICTIONARY_IN : out DICTIONARY_PTR;
  1326.                               FILENAME : in STRING) is
  1327.   begin
  1328.     return;
  1329.   end CREATE_DICTIONARY;
  1330.  
  1331.   procedure TOKEN_IS_FOUND(IN_DICTIONARY : out DICTIONARY_PTR;
  1332.                            WORD : in TOKEN_DEFINITION.TOKEN_TYPE;
  1333.                            FOUND : out BOOLEAN) is
  1334.   begin
  1335.     FOUND := TRUE;
  1336.   end TOKEN_IS_FOUND;
  1337.  
  1338. end DICTIONARY_MANAGER;
  1339. ::::::::::
  1340. helpfiles.ada
  1341. ::::::::::
  1342. package HELP is
  1343. --------------------------------------------------------------------------
  1344. -- Abstract   : This is a help package.  It gives access to a help routine
  1345. --              that can be called from the Style_Checker.
  1346. --------------------------------------------------------------------------
  1347.  
  1348.     subtype LEVEL_TYPE is string(1..4) ;
  1349.  
  1350.     HELP  : constant LEVEL_TYPE := "HELP";
  1351.  
  1352.     procedure HELP_SCREEN (LEVEL  : LEVEL_TYPE; HELP_FILE_NAME : string);
  1353.  
  1354.  
  1355.  -- exceptions
  1356.  
  1357.     HELP_OPEN_ERROR : exception;
  1358.     HELP_FILE_ERROR : exception;
  1359.     HELP_FORMAT_ERROR : exception;
  1360.  
  1361. end HELP;
  1362. ::::::::::
  1363. commandli.ada
  1364. ::::::::::
  1365. --
  1366. -- COMMAND_LINE_HANDLER by Richard Conn, TI Ada Technology Branch
  1367. -- 27 Feb 85
  1368. --
  1369. package COMMAND_LINE_HANDLER is
  1370. --------------------------------------------------------------------------
  1371. -- Abstract   : This package contains routines which return words
  1372. --               from the command line tail (parameters following
  1373. --               the command line verb).  It expects a file to have
  1374. --               been created externally which contains these words,
  1375. --               one word per line.
  1376. --------------------------------------------------------------------------
  1377.  
  1378.     NO_COMMAND_LINE_FILE : exception;
  1379.     NO_MORE_WORDS        : exception;
  1380.  
  1381.  
  1382.     procedure NEXT_WORD (COMMAND_LINE_FILE_NAME : in STRING;
  1383.                          WORD : out STRING; LENGTH : out NATURAL);
  1384. --------------------------------------------------------------------------
  1385. -- Abstract   : NEXT_WORD returns the next word from the command
  1386. --               line tail.  If there are no more words, NO_MORE_WORDS
  1387. --               is raised.  If there is no command line file,
  1388. --               NO_COMMAND_LINE_FILE is raised.
  1389. --------------------------------------------------------------------------
  1390. -- Parameters : WORD           - string containing the next word
  1391. --              LENGTH         - number of chars in next word
  1392. --------------------------------------------------------------------------
  1393.  
  1394.  
  1395.     procedure RESET;
  1396. --------------------------------------------------------------------------
  1397. -- Abstract   : If the file containing the command line's words
  1398. --               is open, this file is closed.  The net effect is
  1399. --               that the next invocation of NEXT_WORD will return
  1400. --               the first word of the command line tail.
  1401. --------------------------------------------------------------------------
  1402.  
  1403. end COMMAND_LINE_HANDLER;
  1404.  
  1405.  
  1406. with TEXT_IO;
  1407. package body COMMAND_LINE_HANDLER is
  1408.  
  1409.  
  1410.     COMMAND_FILE           : TEXT_IO.FILE_TYPE;
  1411.  
  1412.  
  1413.     procedure RESET is
  1414.     begin
  1415.         if TEXT_IO.IS_OPEN (COMMAND_FILE) then
  1416.             TEXT_IO.CLOSE (COMMAND_FILE);
  1417.         end if;
  1418.     end RESET;
  1419.  
  1420.     procedure NEXT_WORD (COMMAND_LINE_FILE_NAME : in STRING;
  1421.                          WORD : out STRING; LENGTH : out NATURAL) is
  1422.     begin
  1423.         if not TEXT_IO.IS_OPEN (COMMAND_FILE) then
  1424.             begin
  1425.                 TEXT_IO.OPEN (COMMAND_FILE, TEXT_IO.IN_FILE,
  1426.                               COMMAND_LINE_FILE_NAME);
  1427.             exception
  1428.                 when others =>
  1429.                     raise NO_COMMAND_LINE_FILE;
  1430.             end;
  1431.         end if;
  1432.         TEXT_IO.GET_LINE (COMMAND_FILE, WORD, LENGTH);
  1433.     exception
  1434.         when NO_COMMAND_LINE_FILE =>
  1435.             raise;
  1436.         when others =>
  1437.             raise NO_MORE_WORDS;
  1438.     end NEXT_WORD;
  1439.  
  1440. end COMMAND_LINE_HANDLER;
  1441. ::::::::::
  1442. helpspec.ada
  1443. ::::::::::
  1444. -------------------------PROLOGUE---------------------------------------
  1445. --                                                                    -*
  1446. -- Unit name    :  HELP_UTILITY                         spec
  1447. -- Author       :  BASKETTE
  1448. -- Date created :  28 January 1985
  1449. -- Last update  :
  1450. --                                                                    -*
  1451. ------------------------------------------------------------------------
  1452. --                                                                    -*
  1453. -- Abstract     : VAX like HELP Utility. Thera are three procedures:
  1454. ----------------: 1) Initialize - reads the help file into a data structure
  1455. ----------------: 2) Help_Me - the help driver
  1456. ----------------: 3) Terminate_help - terminates the help utility
  1457. ----------------:
  1458. ----------------: A function is provided to check if help is active
  1459. --                                                                    -*
  1460. ------------------------------------------------------------------------
  1461. --
  1462. -- Mnemonic     :
  1463. -- Name         :
  1464. -- Release date :
  1465. ------------------ Revision history ------------------------------------
  1466. --
  1467. -- DATE  AUTHOR   HISTORY
  1468. --
  1469. --
  1470. --
  1471. --------------------END-PROLOGUE----------------------------------------
  1472.  
  1473. package HELP_UTILITY is
  1474.  
  1475.     ILLEGAL_FORMAT_FOR_HELP_FILE: exception;
  1476.     HELP_FILE_DOES_NOT_EXIST:     exception;
  1477.     CANNOT_OPEN_HELP_FILE:        exception;
  1478.     HELP_FILE_NOT_INITIALIZED:    exception;
  1479.     NOTHING_TO_OUTPUT:            exception;
  1480.  
  1481.     procedure INITIALIZE(HELP_FILE_NAME: in string);
  1482.  
  1483.     procedure HELP_ME(CLI_BUFFER: in string);
  1484.  
  1485.     procedure GET_TEXT_LINE(LINE: out string;
  1486.                             CHAR_COUNT: out natural;
  1487.                             IS_LAST: out boolean);
  1488.  
  1489.     procedure EXIT_HELP;
  1490.  
  1491.     procedure RESET_HELP;
  1492.  
  1493.     function HELP_IS_TERMINATED return boolean;
  1494.  
  1495. end HELP_UTILITY;
  1496. ::::::::::
  1497. HELPINFOS.ADA
  1498. ::::::::::
  1499.  
  1500. ------------------------------------------------------------------------
  1501. --                                                                    -*
  1502. -- Abstract     : The HELP_INFO_SUPPORT package provides the constants
  1503. ----------------: and types to support the implementation of the AIM
  1504. ----------------: Help and Info utilities.
  1505. --                                                                    -*
  1506. ------------------------------------------------------------------------
  1507.  
  1508.  
  1509. package HELP_INFO_SUPPORT is
  1510.  
  1511.  
  1512. MAX_LINE_LENGTH              :  constant INTEGER := 80;
  1513. MAX_LEVEL                    :  constant INTEGER := 10;
  1514.  
  1515. TOKEN_SEPARATER              :  constant CHARACTER := ' ';
  1516.  
  1517.  
  1518. -- types and pointers for APPEND_TO_DISPLAY ------------
  1519.  
  1520. subtype FILE_TEXT_LINE is string(1..MAX_LINE_LENGTH);
  1521.  
  1522. type TEXT_LINE;
  1523. type TEXT_LINK  is access TEXT_LINE;
  1524. type TEXT_LINE is
  1525.      record
  1526.             TEXT_LINE        : FILE_TEXT_LINE;
  1527.             LINE_LENGTH      : natural := 0;
  1528.             NEXT_LINE        : TEXT_LINK := null;
  1529.     end record;
  1530.  
  1531. TOP_LINE: TEXT_LINK := new TEXT_LINE;
  1532. CURRENT_LINE: TEXT_LINK := TOP_LINE;
  1533. PREVIOUS_LINE: TEXT_LINK := TOP_LINE;
  1534. IS_FIRST_TIME: boolean := true;
  1535.  
  1536. -----------------------------------------------------------
  1537.  
  1538. subtype LEVEL_RANGE is NATURAL range 0..MAX_LEVEL;
  1539.  
  1540. subtype HELP_INFO_TEXT_LINE is STRING(1..MAX_LINE_LENGTH);
  1541.  
  1542. ----------
  1543. --  type declarations for the parsed input buffer
  1544. ----------
  1545.  
  1546. subtype LINE_LENGTH is NATURAL range 0..MAX_LINE_LENGTH;
  1547. subtype LINE_INDEX is POSITIVE range 1..MAX_LINE_LENGTH;
  1548. type TOKEN_RECORD is
  1549.    record
  1550.       TOKEN      : HELP_INFO_TEXT_LINE;
  1551.       LENGTH     : LINE_LENGTH;
  1552.       BUFFER_POS : POSITIVE;    -- 1..aim_support.max_data_length
  1553.    end record;
  1554. subtype NUMBER_OF_TOKENS_RANGE is NATURAL
  1555.                       range 0..MAX_LEVEL;
  1556. subtype TOKEN_ARRAY_RANGE is POSITIVE
  1557.                       range 1..MAX_LEVEL;
  1558. type TOKEN_ARRAY is array( TOKEN_ARRAY_RANGE ) of TOKEN_RECORD;
  1559.  
  1560. ----------
  1561. --  Subtype and type which define the structure of the table used
  1562. --  for implicit conversion of characters from lowercase to uppercase.
  1563. ----------
  1564. subtype LOWER_CASE_RANGE is CHARACTER range ASCII.LC_A .. ASCII.LC_Z;
  1565. type CASE_CONVERSION_TABLE is array( LOWER_CASE_RANGE ) of CHARACTER;
  1566.  
  1567. ----------
  1568. --  Variables used when working with the INPUT_TOKEN_TABLE.
  1569. ----------
  1570. TOKEN_LENGTH    : LINE_LENGTH;
  1571. TOKEN_STRING    : HELP_INFO_TEXT_LINE;
  1572. TOKEN_POS       : POSITIVE;
  1573.  
  1574. ----------
  1575. --  Pointer to the next character position of the user input string
  1576. --  to be accessed during the procedures PARSE and GET_NEXT_INFO_TOKEN.
  1577. ----------
  1578. INPUT_STRING_POS  : POSITIVE;
  1579.  
  1580. ----------
  1581. --  Table used to store individual tokens, their length, and their
  1582. --  position in the user's input string.
  1583. ----------
  1584. INPUT_TOKEN_TABLE : TOKEN_ARRAY;
  1585.  
  1586. ----------
  1587. --  Counter for saving the number of tokens extracted from the user's
  1588. --  input string.
  1589. ----------
  1590. NUMBER_OF_TOKENS  : NUMBER_OF_TOKENS_RANGE;
  1591.  
  1592. ----------
  1593. --  As the variable type indicates, the case conversion table used
  1594. --  for implicit conversion from lowercase to uppercase.
  1595. ----------
  1596. UPPER_CASE : CASE_CONVERSION_TABLE := "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  1597.  
  1598.  
  1599. KEYWORD_NOT_FOUND : exception;
  1600.  
  1601. -----------------------------------------------------------
  1602.  
  1603. procedure APPEND_TO_DISPLAY(LINE       : in STRING;
  1604.                             CHAR_COUNT: in natural);
  1605.  
  1606.  
  1607. procedure IDENTIFY_KEYWORD(
  1608.           TOKEN_STRING : in HELP_INFO_TEXT_LINE;
  1609.           TOKEN_LENGTH : in LINE_LENGTH;
  1610.           KEYWORD      : in HELP_INFO_TEXT_LINE );
  1611.  
  1612.  
  1613. procedure GET_NEXT_TOKEN(
  1614.             INPUT_STRING : in  STRING;
  1615.             NEXT_STRING  : out HELP_INFO_TEXT_LINE;
  1616.             NEXT_LENGTH  : out LINE_LENGTH;
  1617.             NEXT_POS     : out POSITIVE );
  1618.  
  1619.  
  1620. procedure PARSE(INPUT_STRING : in STRING);
  1621.  
  1622.  
  1623. end HELP_INFO_SUPPORT;
  1624. ::::::::::
  1625. HELPINFOB.ADA
  1626. ::::::::::
  1627.  
  1628. ------------------------------------------------------------------------
  1629. --                                                                    -*
  1630. -- Abstract     : The HELP_INFO_SUPPORT package provides the constants
  1631. ----------------: and types to support the implementation of the AIM
  1632. ----------------: Help and Info utilities.
  1633. --                                                                    -*
  1634. ------------------------------------------------------------------------
  1635.  
  1636. package body HELP_INFO_SUPPORT is
  1637.  
  1638.  
  1639. procedure APPEND_TO_DISPLAY(LINE       : in STRING;
  1640.                             CHAR_COUNT: in natural) is
  1641.  
  1642. begin
  1643.  
  1644.   if LINE'length <= FILE_TEXT_LINE'length then
  1645.     CURRENT_LINE.TEXT_LINE := FILE_TEXT_LINE'(others => ' ');
  1646.     CURRENT_LINE.TEXT_LINE(1..LINE'length) := LINE;
  1647.     CURRENT_LINE.LINE_LENGTH := CHAR_COUNT;
  1648.   else
  1649.     CURRENT_LINE.TEXT_LINE := LINE(1..FILE_TEXT_LINE'length);
  1650.     CURRENT_LINE.LINE_LENGTH := FILE_TEXT_LINE'length;
  1651.   end if;
  1652.  
  1653.   PREVIOUS_LINE.NEXT_LINE := CURRENT_LINE;
  1654.   CURRENT_LINE.NEXT_LINE := null;
  1655.   PREVIOUS_LINE := CURRENT_LINE;
  1656.   CURRENT_LINE := new TEXT_LINE;
  1657.  
  1658. exception
  1659.    when others =>
  1660.       raise;
  1661. end APPEND_TO_DISPLAY;
  1662.  
  1663.  
  1664. ----------
  1665. --  The procedure IDENTIFY_KEYWORD compares the parameter TOKEN_STRING
  1666. --                                 to the parameter KEYWORD in an
  1667. --  attempt to identify a match.  The global array UPPER_CASE is used
  1668. --  to convert the input character to upper case for comparison purposes.
  1669. --  Note that the input token string actually remains unchanged.
  1670. --     The logic assumes that if the character position pointer TEST_POS
  1671. --  is incremented past the value of the parameter TOKEN_LENGTH (the
  1672. --  actual length of the input token string) then the TOKEN_STRING must
  1673. --  be valid.  This logic allows for abbreviations as small as one character
  1674. --  to be identified.
  1675. --     If a character mismatch or the CONSTRAINT_ERROR exception is raised,
  1676. --  the exception KEYWORD_NOT_FOUND is raised.
  1677. ----------
  1678. procedure IDENTIFY_KEYWORD(
  1679.           TOKEN_STRING : in HELP_INFO_TEXT_LINE;
  1680.           TOKEN_LENGTH : in LINE_LENGTH;
  1681.           KEYWORD      : in HELP_INFO_TEXT_LINE ) is
  1682.  
  1683. TEST_POS : POSITIVE;             --  character test position
  1684. DONE     : BOOLEAN;
  1685.  
  1686. begin
  1687.    TEST_POS := 1;
  1688.    DONE := FALSE;
  1689.    while TEST_POS <= TOKEN_LENGTH and then not DONE loop
  1690.       case TOKEN_STRING(TEST_POS) is
  1691.          when LOWER_CASE_RANGE =>
  1692.             if UPPER_CASE(TOKEN_STRING(TEST_POS)) = KEYWORD(TEST_POS) then
  1693.                TEST_POS := TEST_POS + 1;
  1694.             else
  1695.                DONE := TRUE;
  1696.             end if;
  1697.          when others =>
  1698.             if TOKEN_STRING(TEST_POS) = KEYWORD(TEST_POS) then
  1699.                TEST_POS := TEST_POS + 1;
  1700.             else
  1701.                DONE := TRUE;
  1702.             end if;
  1703.       end case;
  1704.    end loop;
  1705.    if TEST_POS <= TOKEN_LENGTH then
  1706.       raise KEYWORD_NOT_FOUND;
  1707.    end if;
  1708.  
  1709. exception
  1710.    when CONSTRAINT_ERROR =>
  1711.       raise KEYWORD_NOT_FOUND;
  1712.    when KEYWORD_NOT_FOUND =>
  1713.       raise;
  1714.    when others =>
  1715.       raise;
  1716.  
  1717. end IDENTIFY_KEYWORD;
  1718.  
  1719.  
  1720. ----------
  1721. --  The procedure GET_NEXT_TOKEN extracts, from INPUT_STRING, the
  1722. --                                    next character(s) bounded by a
  1723. --  valid token separater and another valid token separater or the end
  1724. --  of the string.  This procedure assumes that INPUT_STRING_POS is
  1725. --  currently positioned between tokens (pointing at a separater
  1726. --  character) or is positioned at the first character of some token in
  1727. --  the INPUT_STRING.
  1728. --     The exception CONSTRAINT_ERROR will be raised when the global
  1729. --  variable INPUT_STRING_POS (of type POSITIVE)
  1730. --  is greater than the length of INPUT_STRING.  Therefore, this
  1731. --  exception is not propagated upward but, is handled to identify the
  1732. --  last token in the INPUT_STRING and its length.
  1733. --     The expected format of INPUT_STRING is:
  1734. --
  1735. --                  [^^^]AAA[^^^AAA...][^^^][<CR>]
  1736. --
  1737. --  where
  1738. --          ^^^   represents any number of separaters (spaces or less),
  1739. --
  1740. --          AAA   represents any number of characters greater than spaces,
  1741. --
  1742. --          ...   indicates the preceeding pattern may be repeated,
  1743. --
  1744. --          [ ]   indicates an optional entry in the string,
  1745. --
  1746. --          <CR>  represents the string delimiter,
  1747. --                normally ASCII.CR or ASCII.LF.
  1748. --
  1749. ----------
  1750. procedure GET_NEXT_TOKEN(
  1751.             INPUT_STRING : in  STRING;
  1752.             NEXT_STRING  : out HELP_INFO_TEXT_LINE;
  1753.             NEXT_LENGTH  : out LINE_LENGTH;
  1754.             NEXT_POS     : out POSITIVE ) is
  1755.  
  1756. TEST_POS    : LINE_INDEX;     -- character test position
  1757. TEMP_STRING : HELP_INFO_TEXT_LINE := (others => ' ');
  1758.  
  1759. begin
  1760.  
  1761.    TEST_POS := 1;
  1762. ----------
  1763. --  Find first non-separater character.  Will raise CONSTRAINT_ERROR
  1764. --  if INPUT_STRING has trailing spaces with no delimiter.  The
  1765. --  exception block correctly handles this situation.
  1766. ----------
  1767.    NEXT_POS := INPUT_STRING_POS;
  1768.    while INPUT_STRING_POS <= INPUT_STRING'last and then
  1769.          INPUT_STRING(INPUT_STRING_POS) <= TOKEN_SEPARATER loop
  1770.       INPUT_STRING_POS := INPUT_STRING_POS + 1;
  1771.    end loop;
  1772.    NEXT_POS := INPUT_STRING_POS;
  1773.  
  1774. ----------
  1775. --  Extract next token string from input buffer.  A string delimiter,
  1776. --  normally ASCII.CR or ASCII.LF, is expected after the last token.
  1777. --  If no delimiter exists, a CONSTRINT_ERROR will be raised at the
  1778. --  end of the last token in the string.
  1779. ----------
  1780.    while INPUT_STRING_POS <= INPUT_STRING'last and then
  1781.          INPUT_STRING(INPUT_STRING_POS) > TOKEN_SEPARATER loop
  1782.       TEMP_STRING(TEST_POS) := INPUT_STRING(INPUT_STRING_POS);
  1783.       TEST_POS := TEST_POS + 1;
  1784.       INPUT_STRING_POS := INPUT_STRING_POS + 1;
  1785.    end loop;
  1786.    NEXT_LENGTH := TEST_POS - 1;
  1787.    NEXT_STRING := TEMP_STRING;
  1788.  
  1789. exception
  1790.    when CONSTRAINT_ERROR =>
  1791.       NEXT_LENGTH := 0;                 --  throw away last token
  1792.       NEXT_STRING := TEMP_STRING;
  1793.    when others =>
  1794.       raise;
  1795.  
  1796. end GET_NEXT_TOKEN;
  1797.  
  1798.  
  1799. ----------
  1800. --  The procedure PARSE calls the procedure GET_NEXT_TOKEN to extract
  1801. --                      individual tokens from the parameter INPUT_STRING
  1802. --  and places these tokens in the INPUT_TOKEN_TABLE along with their
  1803. --  length and position within the INPUT_STRING.
  1804. --     The exception CONSTRAINT_ERROR is trapped to prevent a premature
  1805. --  exit from the info utility.  This exception will occur if the user
  1806. --  entered more than the allowable number of tokens, as defined by the
  1807. --  subtype TOKEN_ARRAY_RANGE.
  1808. --     It is expected that INPUT_STRING will not contain characters with
  1809. --  an ascii code less than TOKEN_SEPARATER (space character) except for
  1810. --  ASCII.HT (between tokens only) and ASCII.CR or ASCII.LF (possible
  1811. --  string delimiters).  If any other character less than TOKEN_SEPARATER
  1812. --  is encountered, the character is treated as a string delimiter.
  1813. ----------
  1814. procedure PARSE(INPUT_STRING : in STRING) is
  1815.  
  1816. begin
  1817.    NUMBER_OF_TOKENS := 0;
  1818.    INPUT_STRING_POS := 1;
  1819.    TOKEN_LENGTH := 1;
  1820.    while INPUT_STRING_POS <= INPUT_STRING'LENGTH
  1821.          and then TOKEN_LENGTH > 0 loop
  1822.       GET_NEXT_TOKEN(INPUT_STRING,
  1823.                      TOKEN_STRING,
  1824.                      TOKEN_LENGTH,
  1825.                      TOKEN_POS);
  1826.       if TOKEN_LENGTH > 0 and then
  1827.             NUMBER_OF_TOKENS < MAX_LEVEL then
  1828.          NUMBER_OF_TOKENS := NUMBER_OF_TOKENS + 1;
  1829.          INPUT_TOKEN_TABLE(NUMBER_OF_TOKENS).TOKEN := TOKEN_STRING;
  1830.          INPUT_TOKEN_TABLE(NUMBER_OF_TOKENS).LENGTH := TOKEN_LENGTH;
  1831.          INPUT_TOKEN_TABLE(NUMBER_OF_TOKENS).BUFFER_POS := TOKEN_POS;
  1832.       else
  1833.          exit;
  1834.       end if;
  1835.    end loop;
  1836. --  exception
  1837. -- when CONSTRAINT_ERROR =>
  1838.       --  occurs when NUMBER_OF_TOKENS > MAX_LEVEL
  1839. --    null;
  1840. -- when others =>
  1841. --    raise;
  1842. end PARSE;
  1843.  
  1844. end HELP_INFO_SUPPORT;
  1845. ::::::::::
  1846. HELPBODY.ADA
  1847. ::::::::::
  1848. -------------------------PROLOGUE---------------------------------------
  1849. --                                                                    -*
  1850. -- Unit name    :  HELP_UTILITY         body
  1851. -- Author       :  Baskette
  1852. -- Date created :  28 January 1985
  1853. -- Last update  :
  1854. --                                                                    -*
  1855. ------------------------------------------------------------------------
  1856. --                                                                    -*
  1857. -- Abstract     : Body for the HELP Utility
  1858. ----------------: Contains the data strucutures and procedures used in the
  1859. ----------------: help utility other than those in the support package.
  1860. --                                                                    -*
  1861. ------------------------------------------------------------------------
  1862. --
  1863. -- Mnemonic     :
  1864. -- Name         :
  1865. -- Release date :
  1866. ------------------ Revision history ------------------------------------
  1867. --
  1868. -- DATE  AUTHOR   HISTORY
  1869. --
  1870. --
  1871. --
  1872. --------------------END-PROLOGUE----------------------------------------
  1873.  
  1874. with TEXT_IO;
  1875. with HELP_INFO_SUPPORT;
  1876. use HELP_INFO_SUPPORT;
  1877.  
  1878. package body HELP_UTILITY is
  1879.  
  1880. -- Text File for Help Utility
  1881.  
  1882.     HELP_FILE_TYPE: text_io.file_type;
  1883.  
  1884. -- Tree Data Structures
  1885.  
  1886.     type HELP_TOPIC;
  1887.     type HELP_LINK  is access HELP_TOPIC;
  1888.     type HELP_TOPIC is
  1889.         record
  1890.             NAME             : FILE_TEXT_LINE;
  1891.             NAME_LENGTH      : positive := 1;
  1892.             LEVEL            : natural := 1;
  1893.             TEXT_LINES       : HELP_INFO_SUPPORT.TEXT_LINK := null;
  1894.             SUBTOPICS        : HELP_LINK := null; -- link to first subtopic
  1895.             PARENT           : HELP_LINK := null; -- link to parent record
  1896.             NEXT_TOPIC       : HELP_LINK := null; -- link to next on same level
  1897.         end record;
  1898.  
  1899. -- other common needs
  1900.  
  1901.     TOP_NODE     : HELP_LINK := new HELP_TOPIC;
  1902.     CURRENT_NODE: HELP_LINK := null;
  1903.  
  1904.     OUTPUT_LINE: HELP_INFO_SUPPORT.HELP_INFO_TEXT_LINE;
  1905.     BLANK_LINE : HELP_INFO_TEXT_LINE :=
  1906.                          (1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH =>' ');
  1907.     HEADER_LINE: constant string := "Information Available:";
  1908.     ADD_HEADER_LINE: constant string := "Additional Information Available:";
  1909.     TERM_LINE: constant string := "Help Terminated";
  1910.     TOPIC_LINE: constant string := "topic? ";
  1911.     SUBTOPIC_LINE: constant string := "subtopic? ";
  1912.     NO_DOC_LINE: constant string := "Sorry, no documentation available on ";
  1913.  
  1914.     HELP_MODE: boolean := false;
  1915.     FIRST_HELP_ME_CALL: boolean := true;
  1916.     INITIALIZED: boolean := false;
  1917.  
  1918. -- Procedures
  1919.  
  1920.     procedure INITIALIZE(HELP_FILE_NAME: in string)
  1921.            is separate;
  1922.  
  1923.     procedure FIND_KEYWORD(NODE_NAME: in string;
  1924.                            NODE_NAME_LENGTH: in natural;
  1925.                            NODE: in HELP_LINK;
  1926.                            KEYWORD_MATCHES: out HELP_LINK;
  1927.                            MATCH_COUNT: in out natural)
  1928.            is separate;
  1929.  
  1930.     procedure PRINT_TOPIC_MENU(NODE: in HELP_LINK)
  1931.            is separate;
  1932.  
  1933.     procedure PRINT_TOPIC_TEXT(NODE: in HELP_LINK)
  1934.            is separate;
  1935.  
  1936.     procedure PRINT_CURRENT_PROMPT(NODE: in HELP_LINK)
  1937.            is separate;
  1938.  
  1939.     procedure DISPLAY_ALL_HELP_INFO(NODE: in HELP_LINK)
  1940.            is separate;
  1941.  
  1942.     procedure HELP_ME(CLI_BUFFER: in string)
  1943.            is separate;
  1944.  
  1945.     procedure GET_TEXT_LINE(LINE: out string;
  1946.                             CHAR_COUNT: out natural;
  1947.                             IS_LAST: out boolean)
  1948.            is separate;
  1949.  
  1950.     procedure EXIT_HELP
  1951.            is separate;
  1952.  
  1953.     procedure RESET_HELP
  1954.            is separate;
  1955.  
  1956.     function HELP_IS_TERMINATED return boolean is
  1957.     begin
  1958.       if HELP_MODE then
  1959.         return false;
  1960.       else
  1961.         return true;
  1962.       end if;
  1963.     end HELP_IS_TERMINATED;
  1964.  
  1965. end HELP_UTILITY;
  1966. ::::::::::
  1967. HELPDISAL.ADA
  1968. ::::::::::
  1969. -------------------------PROLOGUE---------------------------------------
  1970. --                                                                    -*
  1971. -- Unit name    :  DISPLAY_ALL_HELP_INFO
  1972. -- Date created :  28 January 1985
  1973. -- Last update  :
  1974. --                                                                    -*
  1975. ------------------------------------------------------------------------
  1976. --                                                                    -*
  1977. -- Abstract     :  This procedure prints all information under the
  1978. ----------------: given node including text and menu.
  1979. ----------------: It traverses the tree using recursion.
  1980. --                                                                    -*
  1981. ------------------------------------------------------------------------
  1982. --
  1983. -- Mnemonic     :
  1984. -- Name         :
  1985. -- Release date :
  1986. ------------------ Revision history ------------------------------------
  1987. --
  1988. -- DATE  AUTHOR   HISTORY
  1989. --
  1990. --
  1991. --
  1992. --------------------END-PROLOGUE----------------------------------------
  1993.  
  1994.  
  1995. separate(HELP_UTILITY)
  1996. procedure DISPLAY_ALL_HELP_INFO(NODE: in HELP_UTILITY.HELP_LINK) is
  1997.  
  1998. BLANK_LINE_LENGTH: constant natural := 0;
  1999.  
  2000. begin
  2001.  
  2002. HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2003.                                     BLANK_LINE_LENGTH);
  2004. HELP_UTILITY.OUTPUT_LINE := HELP_UTILITY.BLANK_LINE;
  2005. HELP_UTILITY.OUTPUT_LINE(1..NODE.NAME_LENGTH) := NODE.NAME(1..NODE.NAME_LENGTH);
  2006. HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2007.                                     NODE.NAME_LENGTH);
  2008. HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2009.                                     BLANK_LINE_LENGTH);
  2010. HELP_UTILITY.PRINT_TOPIC_TEXT(NODE);
  2011.  
  2012. if NODE.SUBTOPICS /= null then
  2013.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2014.                                     BLANK_LINE_LENGTH);
  2015.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.ADD_HEADER_LINE,
  2016.                                     HELP_UTILITY.ADD_HEADER_LINE'length);
  2017.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2018.                                     BLANK_LINE_LENGTH);
  2019.   HELP_UTILITY.PRINT_TOPIC_MENU(NODE);
  2020. end if;
  2021.  
  2022. -- go down subtopics link first
  2023.  
  2024. if NODE.SUBTOPICS /= null then
  2025.   DISPLAY_ALL_HELP_INFO(NODE.SUBTOPICS);
  2026. end if;
  2027.  
  2028. -- go down next topic link last
  2029.  
  2030. if NODE.NEXT_TOPIC /= null then
  2031.   DISPLAY_ALL_HELP_INFO(NODE.NEXT_TOPIC);
  2032. end if;
  2033.  
  2034. end DISPLAY_ALL_HELP_INFO;
  2035. ::::::::::
  2036. HELPEXIT.ADA
  2037. ::::::::::
  2038. -------------------------PROLOGUE---------------------------------------
  2039. --                                                                    -*
  2040. -- Unit name    :  EXIT_HELP
  2041. -- Date created :  28 January 1985
  2042. -- Last update  :
  2043. --                                                                    -*
  2044. ------------------------------------------------------------------------
  2045. --                                                                    -*
  2046. -- Abstract     :  The procedure sets the help mode flag to false and
  2047. ----------------: resets the current node pointer to the top node of the
  2048. ----------------: tree.
  2049. --                                                                    -*
  2050. ------------------------------------------------------------------------
  2051. --
  2052. -- Mnemonic     :
  2053. -- Name         :
  2054. -- Release date :
  2055. ------------------ Revision history ------------------------------------
  2056. --
  2057. -- DATE  AUTHOR   HISTORY
  2058. --
  2059. --
  2060. --
  2061. --------------------END-PROLOGUE----------------------------------------
  2062.  
  2063.  
  2064. separate (HELP_UTILITY)
  2065. procedure EXIT_HELP is
  2066.  
  2067. begin
  2068.  
  2069. HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.TOP_NODE;
  2070.  
  2071. -- reset HELP_MODE to off
  2072.  
  2073. HELP_UTILITY.HELP_MODE := false;
  2074. HELP_UTILITY.FIRST_HELP_ME_CALL := TRUE;
  2075.  
  2076. end EXIT_HELP;
  2077. ::::::::::
  2078. HELPFIND.ADA
  2079. ::::::::::
  2080. -------------------------PROLOGUE---------------------------------------
  2081. --                                                                    -*
  2082. -- Unit name    :  FIND_KEYWORD
  2083. -- Date created :  28 January 1985
  2084. -- Last update  :
  2085. --                                                                    -*
  2086. ------------------------------------------------------------------------
  2087. --                                                                    -*
  2088. -- Abstract     : This procedure will return a node (list of nodes) that
  2089. ----------------: potentially matches the given name. A count is returned
  2090. ----------------: of the number of matches.
  2091. --                                                                    -*
  2092. ------------------------------------------------------------------------
  2093. --
  2094. -- Mnemonic     :
  2095. -- Name         :
  2096. -- Release date :
  2097. ------------------ Revision history ------------------------------------
  2098. --
  2099. -- DATE  AUTHOR   HISTORY
  2100. --
  2101. --
  2102. --
  2103. --------------------END-PROLOGUE----------------------------------------
  2104.  
  2105.  
  2106. separate (HELP_UTILITY)
  2107. procedure FIND_KEYWORD (NODE_NAME: in string;
  2108.                         NODE_NAME_LENGTH: in natural;
  2109.                         NODE: in HELP_UTILITY.HELP_LINK;
  2110.                         KEYWORD_MATCHES: out HELP_UTILITY.HELP_LINK;
  2111.                         MATCH_COUNT: in out natural) is
  2112.  
  2113. KEYWORD_NODE: HELP_UTILITY.HELP_LINK := null;
  2114. PREV_NODE: HELP_UTILITY.HELP_LINK := null;
  2115. CURR_NODE: HELP_UTILITY.HELP_LINK := null;
  2116. TOP: HELP_UTILITY.HELP_LINK := CURR_NODE;
  2117.  
  2118. begin
  2119.  
  2120. KEYWORD_NODE := NODE.SUBTOPICS;
  2121. MATCH_COUNT := 0;
  2122.  
  2123. -- loop through all subtopics of current level and save any potential matches
  2124.  
  2125. while KEYWORD_NODE /= null loop
  2126.  begin
  2127.  
  2128. -- make the procedure call with input and subtopic name
  2129.  
  2130.   HELP_INFO_SUPPORT.IDENTIFY_KEYWORD(
  2131.               NODE_NAME,
  2132.               NODE_NAME_LENGTH,
  2133.               KEYWORD_NODE.NAME);
  2134.  
  2135. -- if a match is found, control returns to here, else exception is raised
  2136. -- save the match (could be partial match)
  2137.  
  2138.   CURR_NODE := new HELP_UTILITY.HELP_TOPIC;
  2139.   CURR_NODE.all := KEYWORD_NODE.all;
  2140.  
  2141.   if PREV_NODE = null then
  2142.     TOP := CURR_NODE;
  2143.   else
  2144.     PREV_NODE.NEXT_TOPIC := CURR_NODE;
  2145.   end if;
  2146.  
  2147.   PREV_NODE := CURR_NODE;
  2148.   MATCH_COUNT := MATCH_COUNT + 1;
  2149.  
  2150. -- if a match is not made then exception is raised
  2151.  
  2152.   exception
  2153.     when KEYWORD_NOT_FOUND => null;
  2154.  end;
  2155.  
  2156.  KEYWORD_NODE := KEYWORD_NODE.NEXT_TOPIC;
  2157. end loop;
  2158.  
  2159. KEYWORD_MATCHES := TOP;
  2160.  
  2161. -- other exceptions handled here
  2162.  
  2163.   exception
  2164.     when others => raise;
  2165. end FIND_KEYWORD;
  2166. ::::::::::
  2167. HELPGET.ADA
  2168. ::::::::::
  2169. -------------------------PROLOGUE---------------------------------------
  2170. --                                                                    -*
  2171. -- Unit name    :  GET_TEXT_LINE
  2172. -- Date created :  20 Febrauary 1985
  2173. -- Last update  :
  2174. --                                                                    -*
  2175. ------------------------------------------------------------------------
  2176. --                                                                    -*
  2177. -- Abstract     : This procedure allows the user of the HELP_UTILITY
  2178. --              : to print the data accumulated by HELP_ME;
  2179. --                                                                    -*
  2180. ------------------------------------------------------------------------
  2181. --
  2182. -- Mnemonic     :
  2183. -- Name         :
  2184. -- Release date :
  2185. ------------------ Revision history ------------------------------------
  2186. --
  2187. -- DATE  AUTHOR   HISTORY
  2188. --
  2189. --
  2190. --
  2191. --------------------END-PROLOGUE----------------------------------------
  2192.  
  2193.  
  2194. separate (HELP_UTILITY)
  2195. procedure GET_TEXT_LINE (LINE: out string;
  2196.                          CHAR_COUNT: out natural;
  2197.                          IS_LAST: out boolean) is
  2198.  
  2199. IS_LAST_TIME: boolean := false;
  2200. LAST_CHAR_POS: natural := 0;
  2201.  
  2202. begin
  2203.  
  2204. IS_LAST := false;
  2205.  
  2206. if HELP_INFO_SUPPORT.TOP_LINE = null then
  2207.   raise HELP_UTILITY.NOTHING_TO_OUTPUT;
  2208.  
  2209. else
  2210.   if HELP_INFO_SUPPORT.IS_FIRST_TIME then
  2211.     HELP_INFO_SUPPORT.CURRENT_LINE := HELP_INFO_SUPPORT.TOP_LINE;
  2212.     HELP_INFO_SUPPORT.IS_FIRST_TIME := false;
  2213.   end if;
  2214.  
  2215.   if LINE'length > HELP_INFO_SUPPORT.CURRENT_LINE.LINE_LENGTH then
  2216.     LINE := (1..LINE'length => ' ');
  2217.     LINE(1..HELP_INFO_SUPPORT.CURRENT_LINE.LINE_LENGTH)
  2218.                            := HELP_INFO_SUPPORT.CURRENT_LINE.
  2219.              TEXT_LINE(1..HELP_INFO_SUPPORT.CURRENT_LINE.LINE_LENGTH);
  2220.     CHAR_COUNT := HELP_INFO_SUPPORT.CURRENT_LINE.LINE_LENGTH;
  2221.   else
  2222.     LINE := HELP_INFO_SUPPORT.CURRENT_LINE.TEXT_LINE
  2223.                          (1..LINE'length);
  2224.     CHAR_COUNT := LINE'length;
  2225.   end if;
  2226.  
  2227.   if HELP_INFO_SUPPORT.CURRENT_LINE.NEXT_LINE = null then
  2228.      HELP_INFO_SUPPORT.CURRENT_LINE := HELP_INFO_SUPPORT.TOP_LINE;
  2229.      IS_LAST := true;
  2230.      IS_LAST_TIME := true;
  2231.  
  2232.   else
  2233.     HELP_INFO_SUPPORT.CURRENT_LINE :=
  2234.                     HELP_INFO_SUPPORT.CURRENT_LINE.NEXT_LINE;
  2235.   end if;
  2236. end if;
  2237.  
  2238. if IS_LAST_TIME then
  2239.   HELP_INFO_SUPPORT.CURRENT_LINE := HELP_INFO_SUPPORT.TOP_LINE;
  2240.   HELP_INFO_SUPPORT.PREVIOUS_LINE := HELP_INFO_SUPPORT.TOP_LINE;
  2241.   HELP_INFO_SUPPORT.IS_FIRST_TIME := true;
  2242. end if;
  2243.  
  2244. exception
  2245.     when HELP_UTILITY.NOTHING_TO_OUTPUT => raise;
  2246.  
  2247.     when others => raise;
  2248. end GET_TEXT_LINE;
  2249. ::::::::::
  2250. HELPINIT.ADA
  2251. ::::::::::
  2252. -------------------------PROLOGUE---------------------------------------
  2253. --                                                                    -*
  2254. -- Unit name    :  INITIALIZE
  2255. -- Date created :  28 January 1985
  2256. -- Last update  :
  2257. --                                                                    -*
  2258. ------------------------------------------------------------------------
  2259. --                                                                    -*
  2260. -- Abstract     :  This procedure reads in the specified help file into a
  2261. ----------------: data structure (linked list). Comments are ignored. Any
  2262. ----------------: input line starting with a digit is considered a new
  2263. ----------------: level. All other lines are considered text lines.
  2264. --                                                                    -*
  2265. ------------------------------------------------------------------------
  2266. --
  2267. -- Mnemonic     :
  2268. -- Name         :
  2269. -- Release date :
  2270. ------------------ Revision history ------------------------------------
  2271. --
  2272. -- DATE  AUTHOR   HISTORY
  2273. --
  2274. --
  2275. --
  2276. --------------------END-PROLOGUE----------------------------------------
  2277.  
  2278.  
  2279. separate (HELP_UTILITY)
  2280. procedure INITIALIZE(HELP_FILE_NAME: in string) is
  2281.  
  2282.     PREVIOUS_NODE             : HELP_UTILITY.HELP_LINK := TOP_NODE;
  2283.     PREVIOUS_LINE             : HELP_INFO_SUPPORT.TEXT_LINK := null;
  2284.     CURRENT_LINE              : HELP_INFO_SUPPORT.TEXT_LINK := null;
  2285.     CURRENT_LEVEL             : integer := 1;        -- current topic level
  2286.     TOKEN_IS_DIGITS           : boolean := false;  -- indicates if new record
  2287.     FIRST_DIGIT_FOUND         : boolean := false; -- topic must be before text
  2288.     LINE_BUFFER               : HELP_INFO_SUPPORT.FILE_TEXT_LINE;
  2289.     LAST                      : natural := 0; -- # of characters in LINE_BUFFER
  2290.     FIRST_TEXT_CHAR           : natural := 0; -- first non-digit character
  2291.  
  2292. -- exception
  2293.  
  2294.     TEXT_FILE_LEVEL_BAD       : exception;
  2295.     TEXT_BEFORE_TOPIC         : exception;
  2296.  
  2297. begin
  2298.  
  2299.     HELP_UTILITY.HELP_MODE := true;
  2300.     HELP_UTILITY.FIRST_HELP_ME_CALL := true;
  2301.  
  2302.     text_io.open (HELP_UTILITY.HELP_FILE_TYPE,   -- open the help file
  2303.                   text_io.in_file,
  2304.                   HELP_FILE_NAME,
  2305.                   "");
  2306.  
  2307.     while not text_io.end_of_file (HELP_UTILITY.HELP_FILE_TYPE) loop
  2308.  
  2309. --    blank the input buffer before using
  2310.  
  2311.       LINE_BUFFER := HELP_UTILITY.BLANK_LINE;
  2312.  
  2313.       text_io.get_line (HELP_UTILITY.HELP_FILE_TYPE, LINE_BUFFER, LAST);
  2314.  
  2315. --    Check if comment input. If so, skip the record.
  2316.  
  2317.       if LINE_BUFFER(LINE_BUFFER'first) = '-' and then
  2318.             LINE_BUFFER(LINE_BUFFER'first+1) = '-' then
  2319.             null;  -- comment read, ignore it
  2320.  
  2321.       else
  2322.  
  2323. --      Check if new topic read, i.e., digit is first character of record.
  2324.  
  2325.         if LINE_BUFFER (LINE_BUFFER'first) in '0' .. '9' then
  2326.             TOKEN_IS_DIGITS := true;
  2327.             FIRST_DIGIT_FOUND := true;
  2328.             FIRST_TEXT_CHAR := 1;
  2329.  
  2330. --        loop until all digits found
  2331.  
  2332.           while LINE_BUFFER(FIRST_TEXT_CHAR) in '0' .. '9' and
  2333.                   FIRST_TEXT_CHAR < HELP_INFO_SUPPORT.MAX_LINE_LENGTH loop
  2334.  
  2335.               FIRST_TEXT_CHAR := FIRST_TEXT_CHAR + 1;
  2336.           end loop;
  2337.  
  2338. --        convert to integer value
  2339.  
  2340.           CURRENT_LEVEL := integer'value(LINE_BUFFER
  2341.                              (LINE_BUFFER'first .. FIRST_TEXT_CHAR - 1)) -
  2342.                              integer'value ("0");
  2343.  
  2344. --        skip any blanks between level and keyword
  2345.  
  2346.           while LINE_BUFFER(FIRST_TEXT_CHAR) = ' ' loop
  2347.             FIRST_TEXT_CHAR := FIRST_TEXT_CHAR + 1;
  2348.           end loop;
  2349.         end if;
  2350.  
  2351.         if TOKEN_IS_DIGITS then
  2352.  
  2353. -- NEW TOPIC:
  2354. --          Tree structure note: SUBTOPICS links are for children
  2355. --                               NEXT_TOPIC links are for siblings
  2356. --                               TOP_NODE is the Papa/Mama node
  2357. --     Three cases:
  2358. --     1) Current topic level is greater than previous topic level
  2359. --          (current is subtopic of previous)
  2360. --     2) Current topic level is less than previous topic level
  2361. --     3) Current topic level is same as previous (or default when first)
  2362.  
  2363.           PREVIOUS_LINE := null;
  2364.           HELP_UTILITY.CURRENT_NODE := new HELP_UTILITY.HELP_TOPIC ;
  2365.  
  2366.           if CURRENT_LEVEL > PREVIOUS_NODE.LEVEL then
  2367.  
  2368. --  CASE 1: Current topic level is greater than previous topic level
  2369. --          Set double links
  2370.  
  2371. --          check that level increases by only one
  2372.  
  2373.             if CURRENT_LEVEL - PREVIOUS_NODE.LEVEL > 1 then
  2374.               raise TEXT_FILE_LEVEL_BAD;
  2375.             end if;
  2376.  
  2377.             PREVIOUS_NODE.SUBTOPICS := HELP_UTILITY.CURRENT_NODE;
  2378.             HELP_UTILITY.CURRENT_NODE.PARENT := PREVIOUS_NODE;
  2379.  
  2380.           elsif CURRENT_LEVEL < PREVIOUS_NODE.LEVEL then
  2381.  
  2382. -- CASE 2: Current topic level is less than previous topic level
  2383. --         Go back up tree to same level as current.
  2384.  
  2385.             while CURRENT_LEVEL < PREVIOUS_NODE.LEVEL loop
  2386.                     PREVIOUS_NODE := PREVIOUS_NODE.PARENT;
  2387.             end loop;
  2388.  
  2389.             PREVIOUS_NODE.NEXT_TOPIC := HELP_UTILITY.CURRENT_NODE;
  2390.             HELP_UTILITY.CURRENT_NODE.PARENT := PREVIOUS_NODE;
  2391.  
  2392. -- CASE 3: Level has not changed.
  2393.  
  2394.           else
  2395.  
  2396. --          initial case only. Link off of TOP_NODE's subtopic link
  2397.  
  2398.             if PREVIOUS_NODE = HELP_UTILITY.TOP_NODE then
  2399.               PREVIOUS_NODE.SUBTOPICS := HELP_UTILITY.CURRENT_NODE;
  2400.               HELP_UTILITY.CURRENT_NODE.PARENT := PREVIOUS_NODE;
  2401.  
  2402. --          all other cases when same level, link to next_topic.
  2403.  
  2404.             else
  2405.               PREVIOUS_NODE.NEXT_TOPIC := HELP_UTILITY.CURRENT_NODE;
  2406.               HELP_UTILITY.CURRENT_NODE.PARENT := PREVIOUS_NODE;
  2407.             end if;
  2408.           end if;
  2409.  
  2410. --        Save the topics name, name length, and level
  2411.  
  2412.           HELP_UTILITY.CURRENT_NODE.NAME(
  2413.               1..HELP_INFO_SUPPORT.FILE_TEXT_LINE'last)
  2414.                  := LINE_BUFFER (FIRST_TEXT_CHAR .. LAST) &
  2415.                      (LAST - FIRST_TEXT_CHAR +
  2416.                         2..HELP_INFO_SUPPORT.FILE_TEXT_LINE'last => ' ');
  2417.           HELP_UTILITY.CURRENT_NODE.NAME_LENGTH := LAST - FIRST_TEXT_CHAR + 1;
  2418.           HELP_UTILITY.CURRENT_NODE.LEVEL := CURRENT_LEVEL;
  2419.  
  2420. --        update previous to current and go get next
  2421.  
  2422.           PREVIOUS_NODE := HELP_UTILITY.CURRENT_NODE;
  2423.  
  2424. -- TEXT INPUT
  2425. --      Add text to buffer
  2426.  
  2427.         elsif FIRST_DIGIT_FOUND then
  2428.  
  2429. --        get a new blank line pointer
  2430.  
  2431.           CURRENT_LINE := new HELP_INFO_SUPPORT.TEXT_LINE;
  2432.  
  2433. --        save the text
  2434.  
  2435.           CURRENT_LINE.TEXT_LINE :=
  2436.                   LINE_BUFFER(1..LAST) &
  2437.                       (LAST+1 .. HELP_INFO_SUPPORT.FILE_TEXT_LINE'last => ' ');
  2438.  
  2439. --        save the length
  2440.  
  2441.           if LAST = natural'first then
  2442.             CURRENT_LINE.LINE_LENGTH := LAST + 1;
  2443.           else
  2444.             CURRENT_LINE.LINE_LENGTH := LAST;
  2445.           end if;
  2446.  
  2447. --        update pointers. First time, link to node, otherwise link to previous
  2448.  
  2449.           if PREVIOUS_LINE = null then
  2450.              HELP_UTILITY.CURRENT_NODE.TEXT_LINES := CURRENT_LINE;
  2451.           else
  2452.              PREVIOUS_LINE.NEXT_LINE := CURRENT_LINE;
  2453.           end if;
  2454.  
  2455. --        update the previous line
  2456.  
  2457.           PREVIOUS_LINE := CURRENT_LINE;
  2458.  
  2459.         else
  2460.           raise TEXT_BEFORE_TOPIC;
  2461.  
  2462.         end if;
  2463.  
  2464. --       reset flag. Loop back for next
  2465.  
  2466.         TOKEN_IS_DIGITS := false;                  -- reset flag
  2467.       end if;
  2468.     end loop;
  2469.  
  2470.     text_io.close (HELP_UTILITY.HELP_FILE_TYPE);
  2471.  
  2472. --  set top node to a level of zero. This denotes the top
  2473.  
  2474.     HELP_UTILITY.TOP_NODE.LEVEL := 0;
  2475.     HELP_UTILITY.CURRENT_NODE := TOP_NODE;
  2476.     HELP_UTILITY.INITIALIZED := true;
  2477.  
  2478. exception
  2479.     when TEXT_FILE_LEVEL_BAD | TEXT_BEFORE_TOPIC =>
  2480.          raise HELP_UTILITY.ILLEGAL_FORMAT_FOR_HELP_FILE;
  2481.  
  2482.     when text_io.name_error =>
  2483.          raise HELP_UTILITY.HELP_FILE_DOES_NOT_EXIST;
  2484.  
  2485.     when text_io.status_error | text_io.use_error =>
  2486.          raise HELP_UTILITY.CANNOT_OPEN_HELP_FILE;
  2487.  
  2488.     when others => raise;
  2489. end INITIALIZE;
  2490. ::::::::::
  2491. HELPME.ADA
  2492. ::::::::::
  2493. -------------------------PROLOGUE---------------------------------------
  2494. --                                                                    -*
  2495. -- Unit name    :  HELP_ME
  2496. -- Date created :  28 January 1985
  2497. -- Last update  :
  2498. --                                                                    -*
  2499. ------------------------------------------------------------------------
  2500. --                                                                    -*
  2501. -- Abstract     :  This is procedure is the driver of the Help utility.
  2502. ----------------: It accepts the input from the CLI and determines the
  2503. ----------------: appropriate action to take.
  2504. --                                                                    -*
  2505. ------------------------------------------------------------------------
  2506. --
  2507. -- Mnemonic     :
  2508. -- Name         :
  2509. -- Release date :
  2510. ------------------ Revision history ------------------------------------
  2511. --
  2512. -- DATE  AUTHOR   HISTORY
  2513. --
  2514. --
  2515. --
  2516. --------------------END-PROLOGUE----------------------------------------
  2517.  
  2518.  
  2519. separate (HELP_UTILITY)
  2520. procedure HELP_ME(CLI_BUFFER: in string) is
  2521.  
  2522. TOKEN_COUNT: positive := 1; -- number of tokens in input string
  2523. MATCH_COUNT: natural := 0; -- number of token matches at current level
  2524. COUNTER: natural := 0; -- loop control
  2525. KEYWORD_MATCHES: HELP_UTILITY.HELP_LINK := null; -- list of nodes that match
  2526. TOP_SAVE: HELP_UTILITY.HELP_LINK := null; -- first node of KEYWORD_MATCHES
  2527. SAME_LEVEL: natural := 0; -- copy of current level of node
  2528. MSG_NAME: HELP_INFO_SUPPORT.HELP_INFO_TEXT_LINE;
  2529. BLANK_LINE_LENGTH: constant natural := 0;
  2530. TEMP_NODE: HELP_UTILITY.HELP_LINK := new HELP_UTILITY.HELP_TOPIC;
  2531. OUT_LINE_LENGTH:  natural := 0;
  2532.  
  2533. -- exceptions
  2534.  
  2535. HELP_FILE_NOT_READ: exception;
  2536.  
  2537. begin
  2538.  
  2539. if not HELP_UTILITY.INITIALIZED then
  2540.   raise HELP_FILE_NOT_READ;
  2541. end if;
  2542.  
  2543. if HELP_UTILITY.HELP_MODE then
  2544.  
  2545. -- parse the input string. A table of tokens is returned
  2546.  
  2547. HELP_INFO_SUPPORT.PARSE(CLI_BUFFER);
  2548.  
  2549. -- if no tokens, a carriage return was entered. move up a level
  2550.  
  2551. if HELP_INFO_SUPPORT.NUMBER_OF_TOKENS = 0 then
  2552.  
  2553. -- if this is the first time help is entered and no topic is specified,
  2554. --    output the first level memu
  2555.  
  2556.   if HELP_UTILITY.FIRST_HELP_ME_CALL then
  2557.     HELP_UTILITY.OUTPUT_LINE := HELP_UTILITY.BLANK_LINE;
  2558.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2559.                         BLANK_LINE_LENGTH);
  2560.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.HEADER_LINE,
  2561.                         HELP_UTILITY.HEADER_LINE'length);
  2562.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2563.                         BLANK_LINE_LENGTH);
  2564.     HELP_UTILITY.PRINT_TOPIC_MENU(CURRENT_NODE);
  2565.  
  2566. -- else, if at the upper most level and a carriage return is entered, set
  2567. --       terminate to true.
  2568.  
  2569.   else
  2570.     if HELP_UTILITY.CURRENT_NODE = HELP_UTILITY.TOP_NODE then
  2571.       HELP_UTILITY.EXIT_HELP;
  2572.  
  2573.     else
  2574.  
  2575. --    not at top level. back up one level (until level changes)
  2576.  
  2577.       SAME_LEVEL := HELP_UTILITY.CURRENT_NODE.LEVEL;
  2578.  
  2579.       while HELP_UTILITY.CURRENT_NODE.LEVEL = SAME_LEVEL loop
  2580.         HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.CURRENT_NODE.PARENT;
  2581.       end loop;
  2582.     end if;
  2583.   end if;
  2584.  
  2585. else
  2586.  
  2587. --  loop through the token table returned from PARSE until either:
  2588. --       1) "*" found,
  2589. --       2) "?" found,
  2590. --       3) more than one match is found at a level or
  2591. --       4) tokens are exhausted
  2592.  
  2593.   loop
  2594.     if HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2595.           HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH) = "*"  or
  2596.           HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2597.           HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH) = "?" then
  2598.       exit;
  2599.     end if;
  2600.  
  2601.     FIND_KEYWORD(HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN,
  2602.                HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH,
  2603.                HELP_UTILITY.CURRENT_NODE,
  2604.                KEYWORD_MATCHES,
  2605.                MATCH_COUNT);
  2606.  
  2607. --  if more than one (ambiguous input) or no match is found, then ignore the
  2608. --     remaining tokens, exit loop
  2609.  
  2610.     if MATCH_COUNT /= 1 then
  2611.       exit;
  2612.     end if;
  2613.  
  2614. --  if all tokens checked, exit loop
  2615.  
  2616.     if TOKEN_COUNT = HELP_INFO_SUPPORT.NUMBER_OF_TOKENS then
  2617.       exit;
  2618.  
  2619.     else
  2620.  
  2621. --  increment the counter and update the current node to the match found
  2622.  
  2623.       TOKEN_COUNT := TOKEN_COUNT + 1;
  2624.       HELP_UTILITY.CURRENT_NODE := KEYWORD_MATCHES;
  2625.     end if;
  2626.   end loop;
  2627.  
  2628. -- check if all info from current level on down is requested
  2629.  
  2630.   if HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2631.           HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH) = "*" then
  2632.  
  2633.       if CURRENT_NODE = TOP_NODE then
  2634.         TEMP_NODE.all := HELP_UTILITY.CURRENT_NODE.SUBTOPICS.all;
  2635.       else
  2636.         TEMP_NODE.all := HELP_UTILITY.CURRENT_NODE.all;
  2637.         TEMP_NODE.NEXT_TOPIC := null;
  2638.       end if;
  2639.  
  2640.       HELP_UTILITY.DISPLAY_ALL_HELP_INFO(TEMP_NODE);
  2641.  
  2642.       if HELP_UTILITY.CURRENT_NODE.SUBTOPICS = null then
  2643.         SAME_LEVEL := HELP_UTILITY.CURRENT_NODE.LEVEL;
  2644.  
  2645.         while HELP_UTILITY.CURRENT_NODE.LEVEL = SAME_LEVEL loop
  2646.           HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.CURRENT_NODE.PARENT ;
  2647.         end loop;
  2648.       end if;
  2649.  
  2650. -- check if an implied help was requested, i.e., menu for current level
  2651.  
  2652.   elsif HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2653.           HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH) = "?" then
  2654.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2655.                         BLANK_LINE_LENGTH);
  2656.     HELP_UTILITY.PRINT_TOPIC_TEXT(HELP_UTILITY.CURRENT_NODE);
  2657.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2658.                         BLANK_LINE_LENGTH);
  2659.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.ADD_HEADER_LINE,
  2660.                         HELP_UTILITY.ADD_HEADER_LINE'length);
  2661.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2662.                         BLANK_LINE_LENGTH);
  2663.     HELP_UTILITY.PRINT_TOPIC_MENU(HELP_UTILITY.CURRENT_NODE);
  2664.  
  2665. -- if a match(es) was found, output the info for that match(es)
  2666.  
  2667.   elsif MATCH_COUNT /= 0 then
  2668.     COUNTER := MATCH_COUNT;  -- counter will be used for loop control
  2669.     TOP_SAVE := KEYWORD_MATCHES; -- save the top for later restoration
  2670.  
  2671. --  this loop goes through the list (possibly only one) of matches found
  2672. --       above. KEYWORD_MATCHES is a linked list of the matches. Each
  2673. --       match has its text and menu of subtopics output
  2674.  
  2675.     while COUNTER /= 0 loop
  2676.       HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2677.                         BLANK_LINE_LENGTH);
  2678.       HELP_UTILITY.OUTPUT_LINE := HELP_UTILITY.BLANK_LINE;
  2679.       HELP_UTILITY.OUTPUT_LINE(1..KEYWORD_MATCHES.NAME_LENGTH) :=
  2680.                          KEYWORD_MATCHES.NAME(1..KEYWORD_MATCHES.NAME_LENGTH);
  2681.       HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2682.                         KEYWORD_MATCHES.NAME_LENGTH);
  2683.       HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2684.                         BLANK_LINE_LENGTH);
  2685.       HELP_UTILITY.PRINT_TOPIC_TEXT(KEYWORD_MATCHES);
  2686.  
  2687. --    check if any subtopics, i.e., if a menu should be output
  2688.  
  2689.       if KEYWORD_MATCHES.SUBTOPICS /= null then
  2690.         if TOKEN_COUNT < HELP_INFO_SUPPORT.NUMBER_OF_TOKENS then
  2691.  
  2692. --        this checks for the case where an ambiguous token was entered followed
  2693. --          by an "*". in this case, output all info for all the matches of the
  2694. --          ambiguous input
  2695.  
  2696.           if HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT + 1).TOKEN(1..
  2697.              HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT + 1).LENGTH) = "*"
  2698.              then
  2699.  
  2700.             HELP_UTILITY.DISPLAY_ALL_HELP_INFO(KEYWORD_MATCHES.SUBTOPICS);
  2701.           end if;
  2702.         else
  2703.           HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2704.                         BLANK_LINE_LENGTH);
  2705.           HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.ADD_HEADER_LINE,
  2706.                         HELP_UTILITY.ADD_HEADER_LINE'length);
  2707.           HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2708.                         BLANK_LINE_LENGTH);
  2709.           HELP_UTILITY.PRINT_TOPIC_MENU(KEYWORD_MATCHES);
  2710.         end if;
  2711.       end if;
  2712.  
  2713.       KEYWORD_MATCHES := KEYWORD_MATCHES.NEXT_TOPIC;
  2714.       COUNTER := COUNTER - 1;
  2715.     end loop;
  2716.  
  2717. --  restore the top of the list
  2718.  
  2719.     KEYWORD_MATCHES := TOP_SAVE;
  2720.  
  2721. --  now we must decide what the next prompt should be (and thus, what the
  2722. --      current node should be [or vice versa]).
  2723. --      this only matters if one and only one match was found. Else, the
  2724. --      current node did not change.
  2725.  
  2726.     if MATCH_COUNT = 1 then
  2727.  
  2728. --     if there are no subtopics, the prompt should be for the next higher
  2729. --        level.
  2730.  
  2731.       if KEYWORD_MATCHES.SUBTOPICS = null then
  2732.  
  2733. --        if already at the highest level, set current to top
  2734.  
  2735.         if KEYWORD_MATCHES.LEVEL <= 1 then
  2736.           HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.TOP_NODE;
  2737.         else
  2738.  
  2739. --        else, move up the links until the level changes. That node will then
  2740. --              become the current level
  2741.  
  2742.           SAME_LEVEL := KEYWORD_MATCHES.LEVEL;
  2743.  
  2744.           while KEYWORD_MATCHES.LEVEL = SAME_LEVEL loop
  2745.             KEYWORD_MATCHES := KEYWORD_MATCHES.PARENT;
  2746.           end loop;
  2747.  
  2748.           HELP_UTILITY.CURRENT_NODE := KEYWORD_MATCHES;
  2749.         end if;
  2750.  
  2751.       else
  2752.  
  2753. --    if there are subtopics, the current node becomes the one found and
  2754. --       the user is prompted for subtopic input
  2755.  
  2756.         HELP_UTILITY.CURRENT_NODE := KEYWORD_MATCHES;
  2757.       end if;
  2758.     end if;
  2759.  
  2760.   else
  2761.  
  2762. --  if no match was found and not a special character (* or ?) then no info
  2763. --     for user input request
  2764.  
  2765.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2766.                         BLANK_LINE_LENGTH);
  2767.  
  2768.     if HELP_UTILITY.NO_DOC_LINE'length +
  2769.             HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH >=
  2770.                 HELP_INFO_SUPPORT.MAX_LINE_LENGTH then
  2771.       MSG_NAME(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH) :=
  2772.                  HELP_UTILITY.NO_DOC_LINE &
  2773.                  HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2774.                  HELP_INFO_SUPPORT.MAX_LINE_LENGTH -
  2775.                  HELP_UTILITY.NO_DOC_LINE'length);
  2776.       OUT_LINE_LENGTH := HELP_INFO_SUPPORT.MAX_LINE_LENGTH;
  2777.  
  2778.     else
  2779.       MSG_NAME(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH) :=
  2780.                  HELP_UTILITY.NO_DOC_LINE &
  2781.                  HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).TOKEN(1..
  2782.                    HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH) &
  2783.                  (HELP_UTILITY.NO_DOC_LINE'length +
  2784.                   HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH + 1 ..
  2785.                   HELP_INFO_SUPPORT.HELP_INFO_TEXT_LINE'last => ' ');
  2786.       OUT_LINE_LENGTH := HELP_UTILITY.NO_DOC_LINE'length +
  2787.                   HELP_INFO_SUPPORT.INPUT_TOKEN_TABLE(TOKEN_COUNT).LENGTH;
  2788.     end if;
  2789.  
  2790.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(MSG_NAME, OUT_LINE_LENGTH);
  2791.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2792.                         BLANK_LINE_LENGTH);
  2793.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.ADD_HEADER_LINE,
  2794.                         HELP_UTILITY.ADD_HEADER_LINE'length);
  2795.     HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  2796.                         BLANK_LINE_LENGTH);
  2797.  
  2798.     if HELP_UTILITY.CURRENT_NODE.LEVEL >= 1 then
  2799.       if TOKEN_COUNT > 1 and HELP_UTILITY.CURRENT_NODE.LEVEL /=
  2800.                            HELP_UTILITY.CURRENT_NODE.PARENT.LEVEL then
  2801.         HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.CURRENT_NODE.PARENT;
  2802.       end if;
  2803.     end if;
  2804.  
  2805.     HELP_UTILITY.PRINT_TOPIC_MENU(HELP_UTILITY.CURRENT_NODE);
  2806.     TOKEN_COUNT := HELP_INFO_SUPPORT.NUMBER_OF_TOKENS;
  2807.   end if;
  2808. end if;
  2809.  
  2810. -- before outputting the prompt, check that help was not terminated
  2811.  
  2812. if HELP_UTILITY.HELP_MODE then
  2813.   HELP_UTILITY.PRINT_CURRENT_PROMPT(HELP_UTILITY.CURRENT_NODE);
  2814. end if;
  2815.  
  2816. -- indicate that HELP is active
  2817.  
  2818. HELP_UTILITY.FIRST_HELP_ME_CALL := false;
  2819.  
  2820. end if;
  2821.  
  2822. exception
  2823.   when HELP_FILE_NOT_READ =>
  2824.     raise HELP_UTILITY.HELP_FILE_NOT_INITIALIZED;
  2825.  
  2826.   when others => HELP_UTILITY.HELP_MODE := false;
  2827.                  raise;
  2828. end HELP_ME;
  2829. ::::::::::
  2830. HELPMENU.ADA
  2831. ::::::::::
  2832. -------------------------PROLOGUE---------------------------------------
  2833. --                                                                    -*
  2834. -- Unit name    :  PRINT_TOPIC_MENU
  2835. -- Date created :  28 January 1985
  2836. -- Last update  :
  2837. --                                                                    -*
  2838. ------------------------------------------------------------------------
  2839. --                                                                    -*
  2840. -- Abstract     :  This procedure will print a list of subtopics (menu) for
  2841. ----------------: the given node (if any exist). The subtopics are listed
  2842. ----------------: in two columns.
  2843. --                                                                    -*
  2844. ------------------------------------------------------------------------
  2845. --
  2846. -- Mnemonic     :
  2847. -- Name         :
  2848. -- Release date :
  2849. ------------------ Revision history ------------------------------------
  2850. --
  2851. -- DATE  AUTHOR   HISTORY
  2852. --
  2853. --
  2854. --
  2855. --------------------END-PROLOGUE----------------------------------------
  2856.  
  2857.  
  2858. separate (HELP_UTILITY)
  2859. procedure PRINT_TOPIC_MENU (NODE: in HELP_UTILITY.HELP_LINK) is
  2860.  
  2861.     TOTAL_NUMBER_OF_TOPICS:   natural := 0;
  2862.     NUM_TOPICS_IN_COLUMN_ONE: positive := 1;
  2863.     TOPICS_IN_COLUMN_TWO:     boolean := false;
  2864.     COL_WIDTH: integer := (HELP_INFO_SUPPORT.MAX_LINE_LENGTH/2) - 1;
  2865.     RIGHT_COLUMN_START: integer := COL_WIDTH + 3;
  2866.     EVEN:                     boolean := false;
  2867.     CURRENT_NODE:             HELP_UTILITY.HELP_LINK := null;
  2868.     COL_ONE_NODE:             HELP_UTILITY.HELP_LINK := null;
  2869.     COL_TWO_NODE:             HELP_UTILITY.HELP_LINK := null;
  2870.  
  2871. begin
  2872.  
  2873. CURRENT_NODE := NODE.SUBTOPICS;
  2874.  
  2875. -- count the number of subtopics for this node
  2876.  
  2877. while CURRENT_NODE /= null loop
  2878.   TOTAL_NUMBER_OF_TOPICS := TOTAL_NUMBER_OF_TOPICS + 1;
  2879.   CURRENT_NODE:= CURRENT_NODE.NEXT_TOPIC;
  2880. end loop;
  2881.  
  2882. -- If there is more than one topic, then split the topics into two columns
  2883. -- Column one will have the first half and column two the second half.
  2884. -- If there are an odd number of topics, column one will have the odd number
  2885.  
  2886. if TOTAL_NUMBER_OF_TOPICS /= 0 then
  2887.   if TOTAL_NUMBER_OF_TOPICS >= 2 then
  2888.     TOPICS_IN_COLUMN_TWO := true;
  2889.     NUM_TOPICS_IN_COLUMN_ONE := TOTAL_NUMBER_OF_TOPICS / 2;
  2890.  
  2891. -- More than one topic, split the number
  2892. -- See if odd number. If so, increment the topic count so odd goes in 1st col.
  2893.  
  2894.     if TOTAL_NUMBER_OF_TOPICS /= (TOTAL_NUMBER_OF_TOPICS/2) * 2 then
  2895.       NUM_TOPICS_IN_COLUMN_ONE := NUM_TOPICS_IN_COLUMN_ONE + 1;
  2896.  
  2897.     else
  2898.       EVEN := true;
  2899.     end if;
  2900.   end if;
  2901.  
  2902. -- set the beginning node for each column
  2903.  
  2904.   COL_ONE_NODE := NODE.SUBTOPICS;
  2905.   CURRENT_NODE := NODE.SUBTOPICS;
  2906.  
  2907.   for I in 1..NUM_TOPICS_IN_COLUMN_ONE loop
  2908.     COL_TWO_NODE := CURRENT_NODE.NEXT_TOPIC;
  2909.     CURRENT_NODE := CURRENT_NODE.NEXT_TOPIC;
  2910.   end loop;
  2911.  
  2912.   if TOPICS_IN_COLUMN_TWO then
  2913.     while COL_TWO_NODE /= null loop
  2914.       HELP_UTILITY.OUTPUT_LINE :=
  2915.                  HELP_UTILITY.BLANK_LINE; -- blank the line buffer
  2916.  
  2917. -- Put first topic in left half of output line
  2918. --     if full name will not fit then truncate
  2919.  
  2920.       if COL_WIDTH > COL_ONE_NODE.NAME_LENGTH then
  2921.  
  2922. --      full name will fit
  2923.  
  2924.         HELP_UTILITY.OUTPUT_LINE(1..COL_ONE_NODE.NAME_LENGTH) :=
  2925.          COL_ONE_NODE.NAME(1..COL_ONE_NODE.NAME_LENGTH);
  2926.  
  2927.       else
  2928.  
  2929. --      truncate
  2930.  
  2931.         HELP_UTILITY.OUTPUT_LINE(1..COL_WIDTH) :=
  2932.          COL_ONE_NODE.NAME(1..COL_WIDTH);
  2933.       end if;
  2934.  
  2935. -- Put second topic in second half of output line
  2936. --     if full name will not fit then truncate
  2937.  
  2938.       if COL_WIDTH > COL_TWO_NODE.NAME_LENGTH then
  2939.  
  2940. --      full name will fit
  2941.  
  2942.         HELP_UTILITY.OUTPUT_LINE(RIGHT_COLUMN_START..RIGHT_COLUMN_START +
  2943.                COL_TWO_NODE.NAME_LENGTH - 1 ) :=
  2944.                 COL_TWO_NODE.NAME(1..COL_TWO_NODE.NAME_LENGTH);
  2945.         HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2946.                      RIGHT_COLUMN_START - 1 + COL_TWO_NODE.NAME_LENGTH);
  2947.  
  2948.       else
  2949.  
  2950. --      truncate
  2951.  
  2952.         HELP_UTILITY.OUTPUT_LINE(RIGHT_COLUMN_START..RIGHT_COLUMN_START +
  2953.                COL_WIDTH - 1) :=
  2954.                 COL_TWO_NODE.NAME(1..COL_WIDTH);
  2955.         HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2956.                      RIGHT_COLUMN_START - 1 + COL_WIDTH);
  2957.  
  2958.       end if;
  2959.  
  2960.       COL_ONE_NODE := COL_ONE_NODE.NEXT_TOPIC;
  2961.       COL_TWO_NODE := COL_TWO_NODE.NEXT_TOPIC;
  2962.     end loop;
  2963.   end if;
  2964.  
  2965.   if not EVEN then
  2966.  
  2967. -- Put the odd topic in the output buffer
  2968.  
  2969.     HELP_UTILITY.OUTPUT_LINE := HELP_UTILITY.BLANK_LINE;
  2970.  
  2971. --  check if name will fit on output line
  2972.  
  2973.     if HELP_INFO_SUPPORT.MAX_LINE_LENGTH > COL_ONE_NODE.NAME_LENGTH then
  2974.  
  2975. --    name fits
  2976.  
  2977.       HELP_UTILITY.OUTPUT_LINE(1..COL_ONE_NODE.NAME_LENGTH) :=
  2978.              COL_ONE_NODE.NAME(1..COL_ONE_NODE.NAME_LENGTH);
  2979.       HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2980.                                   COL_ONE_NODE.NAME_LENGTH);
  2981.  
  2982. --  truncate
  2983.  
  2984.     else
  2985.       HELP_UTILITY.OUTPUT_LINE(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH) :=
  2986.              COL_ONE_NODE.NAME(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH);
  2987.       HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.OUTPUT_LINE,
  2988.                                   HELP_INFO_SUPPORT.MAX_LINE_LENGTH);
  2989.     end if;
  2990.   end if;
  2991. end if;
  2992.  
  2993. exception
  2994.     when others =>  raise;
  2995.  
  2996. end PRINT_TOPIC_MENU;
  2997. ::::::::::
  2998. HELPPROMP.ADA
  2999. ::::::::::
  3000. -------------------------PROLOGUE---------------------------------------
  3001. --                                                                    -*
  3002. -- Unit name    :  PRINT_CURRENT_PROMPT
  3003. -- Date created :  28 January 1985
  3004. -- Last update  :
  3005. --                                                                    -*
  3006. ------------------------------------------------------------------------
  3007. --                                                                    -*
  3008. -- Abstract     :  This procedure determines the prompt and outputs it.
  3009. --                                                                    -*
  3010. ------------------------------------------------------------------------
  3011. --
  3012. -- Mnemonic     :
  3013. -- Name         :
  3014. -- Release date :
  3015. ------------------ Revision history ------------------------------------
  3016. --
  3017. -- DATE  AUTHOR   HISTORY
  3018. --
  3019. --
  3020. --
  3021. --------------------END-PROLOGUE----------------------------------------
  3022.  
  3023.  
  3024. separate(HELP_UTILITY)
  3025. procedure PRINT_CURRENT_PROMPT(NODE: in HELP_UTILITY.HELP_LINK) is
  3026.  
  3027. TEMP_NODE: HELP_UTILITY.HELP_LINK := null;
  3028. PROMPT_END: integer := 1; -- number of allowable characters for prompt
  3029. SAVE_CURRENT_LEVEL: integer := 0;  -- used in reverse tree traversal
  3030. PROMPT_NAME: HELP_INFO_SUPPORT.HELP_INFO_TEXT_LINE := HELP_UTILITY.BLANK_LINE;
  3031. BLANK_LINE_LENGTH: constant natural := 0;
  3032.  
  3033. begin
  3034.  
  3035. -- there are two types of prompts:
  3036. -- 1) "topic? "
  3037. -- 2) "subtopic? "
  3038.  
  3039. -- "topic? " is output when at the highest level (at the top node)
  3040.  
  3041. if NODE = HELP_UTILITY.TOP_NODE then
  3042.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  3043.                                       BLANK_LINE_LENGTH);
  3044.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.TOPIC_LINE,
  3045.                                       HELP_UTILITY.TOPIC_LINE'length);
  3046.  
  3047. else
  3048.  
  3049. -- when at a lower level output the topic name(s) followed by "subtopic? "
  3050.  
  3051.   TEMP_NODE := NODE;
  3052.   SAVE_CURRENT_LEVEL := NODE.LEVEL;
  3053.  
  3054. -- put the prompt "subtopic? " in the buffer
  3055.  
  3056.   PROMPT_NAME(1..HELP_UTILITY.SUBTOPIC_LINE'length) :=
  3057.              HELP_UTILITY.SUBTOPIC_LINE;
  3058.   PROMPT_END := HELP_INFO_SUPPORT.MAX_LINE_LENGTH -
  3059.                      HELP_UTILITY.SUBTOPIC_LINE'length - 1;
  3060.  
  3061. -- now put the name of the current node in the buffer before the prompt
  3062.  
  3063.   PROMPT_NAME(1..TEMP_NODE.NAME_LENGTH +
  3064.          HELP_INFO_SUPPORT.MAX_LINE_LENGTH - PROMPT_END + 1) :=
  3065.               TEMP_NODE.NAME(1..TEMP_NODE.NAME_LENGTH) & ' ' &
  3066.                    PROMPT_NAME(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH -
  3067.                           PROMPT_END);
  3068.  
  3069.   PROMPT_END := PROMPT_END - TEMP_NODE.NAME_LENGTH - 1;
  3070.  
  3071. -- do a reverse tree traversal starting at the current node. if a level
  3072. --  changes, put that node's name in the output string
  3073.  
  3074.   while TEMP_NODE.LEVEL > 0 loop
  3075.     if SAVE_CURRENT_LEVEL /= TEMP_NODE.LEVEL then
  3076.       SAVE_CURRENT_LEVEL := TEMP_NODE.LEVEL;
  3077.  
  3078.       if SAVE_CURRENT_LEVEL > 0 then
  3079.  
  3080. --      if the name will not fit then exit and go with what we have
  3081.  
  3082.         if TEMP_NODE.NAME_LENGTH + 1 > PROMPT_END then
  3083.           exit;
  3084.         end if;
  3085.  
  3086.         PROMPT_NAME(1..TEMP_NODE.NAME_LENGTH +
  3087.                HELP_INFO_SUPPORT.MAX_LINE_LENGTH - PROMPT_END + 1) :=
  3088.                     TEMP_NODE.NAME(1..TEMP_NODE.NAME_LENGTH) & ' ' &
  3089.                     PROMPT_NAME(1..HELP_INFO_SUPPORT.MAX_LINE_LENGTH -
  3090.                            PROMPT_END);
  3091.  
  3092.         PROMPT_END := PROMPT_END - TEMP_NODE.NAME_LENGTH - 1;
  3093.       end if;
  3094.     end if;
  3095.  
  3096.     TEMP_NODE := TEMP_NODE.PARENT;
  3097.   end loop;
  3098.  
  3099.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(HELP_UTILITY.BLANK_LINE,
  3100.                                       BLANK_LINE_LENGTH);
  3101.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(PROMPT_NAME,
  3102.                       HELP_INFO_SUPPORT.MAX_LINE_LENGTH - PROMPT_END - 1);
  3103.  
  3104. end if;
  3105.  
  3106. exception
  3107.     when others => raise;
  3108. end PRINT_CURRENT_PROMPT;
  3109. ::::::::::
  3110. HELPRESET.ADA
  3111. ::::::::::
  3112. -------------------------PROLOGUE---------------------------------------
  3113. --                                                                    -*
  3114. -- Unit name    :  RESET_HELP
  3115. -- Date created :  04 March 1985
  3116. -- Last update  :
  3117. --                                                                    -*
  3118. ------------------------------------------------------------------------
  3119. --                                                                    -*
  3120. -- Abstract     :  The procedure sets the help mode flag to true and
  3121. ----------------: resets the current node pointer to the top node of the
  3122. ----------------: tree.
  3123. --                                                                    -*
  3124. ------------------------------------------------------------------------
  3125. --
  3126. -- Mnemonic     :
  3127. -- Name         :
  3128. -- Release date :
  3129. ------------------ Revision history ------------------------------------
  3130. --
  3131. -- DATE  AUTHOR   HISTORY
  3132. --
  3133. --
  3134. --
  3135. --------------------END-PROLOGUE----------------------------------------
  3136.  
  3137.  
  3138. separate (HELP_UTILITY)
  3139. procedure RESET_HELP is
  3140.  
  3141. begin
  3142.  
  3143. HELP_UTILITY.CURRENT_NODE := HELP_UTILITY.TOP_NODE;
  3144.  
  3145. -- set HELP_MODE to on
  3146.  
  3147. HELP_UTILITY.HELP_MODE := true;
  3148. HELP_UTILITY.FIRST_HELP_ME_CALL := true;
  3149.  
  3150. end RESET_HELP;
  3151. ::::::::::
  3152. HELPTEXT.ADA
  3153. ::::::::::
  3154. -------------------------PROLOGUE---------------------------------------
  3155. --                                                                    -*
  3156. -- Unit name    :  PRINT_TOPIC_TEXT
  3157. -- Date created :  28 January 1985
  3158. -- Last update  :
  3159. --                                                                    -*
  3160. ------------------------------------------------------------------------
  3161. --                                                                    -*
  3162. -- Abstract     : This procedure prints the text assoicated with the
  3163. ----------------: given node.
  3164. --                                                                    -*
  3165. ------------------------------------------------------------------------
  3166. --
  3167. -- Mnemonic     :
  3168. -- Name         :
  3169. -- Release date :
  3170. ------------------ Revision history ------------------------------------
  3171. --
  3172. -- DATE  AUTHOR   HISTORY
  3173. --
  3174. --
  3175. --
  3176. --------------------END-PROLOGUE----------------------------------------
  3177.  
  3178.  
  3179. separate (HELP_UTILITY)
  3180. procedure PRINT_TOPIC_TEXT (NODE: in HELP_UTILITY.HELP_LINK) is
  3181.  
  3182.    CURRENT_LINE: HELP_INFO_SUPPORT.TEXT_LINK;
  3183.  
  3184. begin
  3185.  
  3186. CURRENT_LINE := NODE.TEXT_LINES;
  3187.  
  3188. while CURRENT_LINE /= null loop
  3189.   HELP_INFO_SUPPORT.APPEND_TO_DISPLAY(CURRENT_LINE.TEXT_LINE,
  3190.                                       CURRENT_LINE.LINE_LENGTH);
  3191.   CURRENT_LINE := CURRENT_LINE.NEXT_LINE;
  3192. end loop;
  3193.  
  3194. exception
  3195.     when others => raise;
  3196. end PRINT_TOPIC_TEXT;
  3197. ::::::::::
  3198. HELPFILEB.ADA
  3199. ::::::::::
  3200.  
  3201. with TEXT_IO;
  3202. with HELP_UTILITY;
  3203.  
  3204. package body HELP is
  3205.  
  3206.  procedure HELP_SCREEN (LEVEL: LEVEL_TYPE; HELP_FILE_NAME : string) is
  3207. --------------------------------------------------------------------------
  3208. -- Abstract   : This routine provides a help_screen, based on the two
  3209. --              parameters.
  3210. --------------------------------------------------------------------------
  3211. -- Parameters : LEVEL          - Level of help requested
  3212. --              HELP_FILE_NAME - Name of help file
  3213. --------------------------------------------------------------------------
  3214.  
  3215.  
  3216.  -- Constants and variables
  3217.  
  3218.    HELP_TOPIC : string (1..80);
  3219.    TOPIC_LENGTH : natural;
  3220.    FIRST_CALL: BOOLEAN := TRUE;
  3221.  
  3222.    procedure  OUTPUT_HELP_INFO is
  3223.  
  3224.      HELP_INFO  : string (1..80);
  3225.      HELP_INFO_LENGTH: natural;
  3226.      IS_LAST : BOOLEAN;
  3227.  
  3228.    begin
  3229.  
  3230.      TEXT_IO.NEW_LINE;
  3231.      HELP_UTILITY.GET_TEXT_LINE(HELP_INFO,HELP_INFO_LENGTH,IS_LAST);
  3232.  
  3233.      while not IS_LAST loop
  3234.         TEXT_IO.PUT_LINE(HELP_INFO);
  3235.         TEXT_IO.NEW_LINE;
  3236.         HELP_INFO_LENGTH := HELP_INFO'LENGTH;
  3237.         HELP_UTILITY.GET_TEXT_LINE(HELP_INFO,HELP_INFO_LENGTH,IS_LAST);
  3238.      end loop;
  3239.  
  3240.      TEXT_IO.PUT(HELP_INFO(1..HELP_INFO_LENGTH));
  3241.  
  3242.  
  3243.    end OUTPUT_HELP_INFO;
  3244.  
  3245.  begin       -- begin main procedure
  3246.  
  3247.  --
  3248.  -- Initialize HELP_FILE the first time through
  3249.  --
  3250.  
  3251.      if FIRST_CALL then
  3252.         HELP_UTILITY.INITIALIZE(HELP_FILE_NAME);
  3253.         FIRST_CALL := FALSE;
  3254.      end if;
  3255.  --
  3256.  -- Clear screen
  3257.  --
  3258.  
  3259.     TEXT_IO.NEW_PAGE;
  3260.  
  3261.  --
  3262.  -- Make initial call to HELP entering at level call was made
  3263.  
  3264.        HELP_UTILITY.HELP_ME(LEVEL);
  3265.  
  3266.     --
  3267.     -- Handle other help requests at this level
  3268.     --
  3269.  
  3270.  
  3271.        while not HELP_UTILITY.HELP_IS_TERMINATED loop
  3272.  
  3273.         OUTPUT_HELP_INFO;
  3274.         TEXT_IO.GET_LINE(HELP_TOPIC,TOPIC_LENGTH);
  3275.         HELP_UTILITY.HELP_ME(HELP_TOPIC(1..TOPIC_LENGTH));
  3276.  
  3277.        end loop;
  3278.  
  3279.      TEXT_IO.NEW_LINE;
  3280.      HELP_UTILITY.RESET_HELP;     -- Make sure you reset HELP for future
  3281.                                  -- entries into Help_screen
  3282.  
  3283.  
  3284.    exception
  3285.         when HELP_UTILITY.HELP_FILE_DOES_NOT_EXIST => raise HELP_FILE_ERROR;
  3286.  
  3287.         when HELP_UTILITY.CANNOT_OPEN_HELP_FILE => raise HELP_OPEN_ERROR;
  3288.  
  3289.         when HELP_UTILITY.ILLEGAL_FORMAT_FOR_HELP_FILE =>
  3290.                                                raise HELP_FORMAT_ERROR;
  3291.  
  3292.    end HELP_SCREEN;
  3293.  
  3294.  end HELP;
  3295. ::::::::::
  3296. filebody.ada
  3297. ::::::::::
  3298. with COMMAND_LINE_HANDLER;
  3299. with CURRENT_EXCEPTION;
  3300. with TEXT_IO;
  3301.  
  3302. package body FILE_HANDLING is
  3303.  
  3304.     MAX_FILE_NAME_LENGTH : constant NATURAL := 128;
  3305.     subtype FILE_NAME_STRING is STRING (1 .. MAX_FILE_NAME_LENGTH);
  3306.  
  3307.     FILE_STACK_SIZE        : constant NATURAL := 20;
  3308.     FILE_STACK             : array (1 .. FILE_STACK_SIZE) of TEXT_IO.FILE_TYPE;
  3309.     FILE_STACK_POINTER     : NATURAL := 0;
  3310.     NESTED_FILE_INDICATOR  : constant CHARACTER := '@';
  3311.     EXTENSION_CHAR         : constant CHARACTER := '.';
  3312.     HELP_CHAR              : constant CHARACTER := '?';
  3313.  
  3314.  
  3315.     FILE_NAME              : FILE_NAME_STRING;
  3316.     FILE_NAME_LENGTH       : NATURAL;
  3317.     FLAW_FILE_NAME         : FILE_NAME_STRING;
  3318.     FLAW_FILE_NAME_LENGTH  : NATURAL;
  3319.     FLAW_TYPE              : constant STRING (1 .. 3) := "FLW";
  3320.     STYLE_FILE_NAME        : FILE_NAME_STRING;
  3321.     STYLE_FILE_NAME_LENGTH : NATURAL;
  3322.     STYLE_TYPE             : constant STRING (1 .. 3) := "STY";
  3323.     IS_FILE_NAME_DEFINED   : BOOLEAN := FALSE;
  3324.     COMMAND_LINE_FILE_NAME : constant STRING := "COMMAND_LINE.TXT";
  3325.  
  3326.     NO_MORE_FILES          : exception;
  3327.     INCLUDE_STACK_OVERFLOW : exception;
  3328.     INPUT_FILE_MISSING     : exception;
  3329.     FILE_NAME_ILLEGAL      : exception;
  3330.  
  3331. --
  3332. -- Close the current file on the top of the file stack and pop down
  3333. --  to the next element on the file stack (viz, the file opened before
  3334. --  the file that was just closed).  POP the old file from the top of
  3335. --  the file stack.
  3336. --
  3337.     procedure POP is
  3338.     begin
  3339.         TEXT_IO.CLOSE (FILE_STACK (FILE_STACK_POINTER));
  3340.         FILE_STACK_POINTER := FILE_STACK_POINTER - 1;
  3341.     end POP;
  3342.  
  3343. --
  3344. -- If file stack is not full, increment file stack pointer and open
  3345. --  the file whose name is in FILE_NAME (2..FILE_NAME_LENGTH) as the
  3346. --  new current file on the file stack.  PUSH a new file onto the file
  3347. --  stack.
  3348. --
  3349.     procedure PUSH is
  3350.     begin
  3351.         if FILE_STACK_POINTER = FILE_STACK_SIZE then
  3352.             raise INCLUDE_STACK_OVERFLOW;
  3353.         end if;
  3354.         FILE_STACK_POINTER := FILE_STACK_POINTER + 1;
  3355.         TEXT_IO.OPEN (FILE_STACK (FILE_STACK_POINTER), TEXT_IO.IN_FILE,
  3356.                       FILE_NAME (2 .. FILE_NAME_LENGTH));
  3357.     exception
  3358.         when INCLUDE_STACK_OVERFLOW =>
  3359.             raise;
  3360.         when others =>
  3361.             raise INPUT_FILE_MISSING;
  3362.     end PUSH;
  3363.  
  3364. --
  3365. -- Return the next file name in FILE_NAME and FILE_NAME_LENGTH from
  3366. --  the command line and all included files.
  3367. --
  3368.     procedure RETURN_NEXT_FILE_NAME is
  3369.         INDEX : NATURAL;
  3370.         RETRY : BOOLEAN;
  3371.     begin
  3372. --
  3373. -- Loop until we encounter a file name which is NOT an include file
  3374. --
  3375.         loop
  3376. --
  3377. -- Loop until we encounter a file name
  3378. --
  3379.             loop
  3380.                 RETRY := TRUE;
  3381.                 if FILE_STACK_POINTER = 0 then
  3382.                     begin
  3383.                         COMMAND_LINE_HANDLER.NEXT_WORD
  3384.                            (COMMAND_LINE_FILE_NAME,
  3385.                             FILE_NAME, FILE_NAME_LENGTH);
  3386.                         RETRY := FALSE;
  3387.                     exception
  3388.                         when others =>
  3389.                             raise NO_MORE_FILES;
  3390.                     end;
  3391.                 else
  3392.                     begin
  3393.                         TEXT_IO.GET_LINE
  3394.                            (FILE_STACK (FILE_STACK_POINTER), FILE_NAME,
  3395.                             FILE_NAME_LENGTH);
  3396.                         RETRY := FALSE;
  3397.                     exception
  3398.                         when others =>
  3399.                             POP;
  3400.                             RETRY := TRUE;
  3401.                     end;
  3402.                 end if;
  3403.                 exit when not RETRY;
  3404.             end loop;
  3405.             if FILE_NAME (1) = NESTED_FILE_INDICATOR then
  3406.                 PUSH;
  3407.                 RETRY := TRUE;
  3408.             end if;
  3409.             exit when not RETRY;
  3410.         end loop;
  3411.         --
  3412.         -- If this is the first file name provided, name the Flaw and Style
  3413.         --  files after it
  3414.         --
  3415.         if not IS_FILE_NAME_DEFINED then
  3416.             if FILE_NAME(1) = HELP_CHAR then
  3417.                 raise HELP_ASKED_FOR;
  3418.             else
  3419.                 INDEX := FILE_NAME_LENGTH + 1;
  3420.                 for I in 1 .. FILE_NAME_LENGTH loop
  3421.                     -- search for the LAST EXTENSION character ('.')
  3422.                     -- Note on Data General there can be several '.'
  3423.                     -- in a file name!
  3424.                     if FILE_NAME(I) = EXTENSION_CHAR then
  3425.                         INDEX := I;
  3426.                     end if;
  3427.                 end loop;
  3428.                 FLAW_FILE_NAME (1 .. INDEX+FLAW_TYPE'LAST) :=
  3429.                     FILE_NAME(1..INDEX-1) & EXTENSION_CHAR & FLAW_TYPE;
  3430.                 STYLE_FILE_NAME (1 .. INDEX + STYLE_TYPE'LAST) :=
  3431.                     FILE_NAME(1..INDEX-1) & EXTENSION_CHAR & STYLE_TYPE;
  3432.                 FLAW_FILE_NAME_LENGTH := INDEX + FLAW_TYPE'LAST;
  3433.                 STYLE_FILE_NAME_LENGTH := INDEX + FLAW_TYPE'LAST;
  3434.                 IS_FILE_NAME_DEFINED := TRUE;
  3435.             end if;
  3436.         end if;
  3437.     exception
  3438.         when NO_MORE_FILES =>
  3439.             raise;
  3440.         when HELP_ASKED_FOR =>
  3441.             raise;
  3442.         when others =>
  3443.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3444.             TEXT_IO.PUT_LINE(" in RETURN_NEXT_FILE_NAME.");
  3445.             raise;
  3446.     end RETURN_NEXT_FILE_NAME;
  3447.  
  3448. --
  3449. -- Obtain the next file name and open it
  3450. --
  3451.     procedure INPUT_FILE_ID (FILE_ID    : in out TEXT_IO.FILE_TYPE;
  3452.                              MORE_FILES : out BOOLEAN) is
  3453.         OPEN_SUCCESSFUL : BOOLEAN;
  3454.         CANNOT_OPEN_MSG : constant STRING :=
  3455.             "This file cannot be opened!  : ";
  3456.         STACK_OFLOW_MSG : constant STRING :=
  3457.             "The File-list stack overflowed.  Attempting to continue!?";
  3458.  
  3459.     begin
  3460.       loop
  3461.         begin
  3462.             OPEN_SUCCESSFUL := true;
  3463.             RETURN_NEXT_FILE_NAME;
  3464.             if TEXT_IO.IS_OPEN( FILE_ID ) then
  3465.                 TEXT_IO.CLOSE( FILE_ID );
  3466.             end if;
  3467.             TEXT_IO.OPEN (FILE_ID, TEXT_IO.IN_FILE,
  3468.             FILE_NAME (1 .. FILE_NAME_LENGTH));
  3469.             MORE_FILES := TRUE;
  3470.         exception
  3471.             when TEXT_IO.NAME_ERROR | TEXT_IO.USE_ERROR =>
  3472.                 TEXT_IO.PUT_LINE(CANNOT_OPEN_MSG &
  3473.                                  FILE_NAME(1 .. FILE_NAME_LENGTH) );
  3474.                 OPEN_SUCCESSFUL := false;
  3475.             when INCLUDE_STACK_OVERFLOW =>
  3476.                 TEXT_IO.PUT_LINE(STACK_OFLOW_MSG);
  3477.                 OPEN_SUCCESSFUL := false;
  3478.             when OTHERS =>
  3479.                 raise;
  3480.         end;
  3481.  
  3482.         exit when OPEN_SUCCESSFUL;
  3483.       end loop;
  3484.  
  3485.     exception
  3486.         when TEXT_IO.NAME_ERROR | TEXT_IO.USE_ERROR =>
  3487.             TEXT_IO.PUT_LINE( CANNOT_OPEN_MSG );
  3488.             raise;
  3489.         when HELP_ASKED_FOR =>
  3490.             raise;
  3491.         when NO_MORE_FILES =>
  3492.             MORE_FILES := FALSE;
  3493.         when others =>
  3494.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3495.             TEXT_IO.PUT_LINE(" in RETURN_NEXT_FILE_NAME.");
  3496.             raise FILE_NAME_ILLEGAL;
  3497.     end INPUT_FILE_ID;
  3498.  
  3499. --
  3500. -- Create the Flaw and Style files and return their IDs
  3501. --
  3502.     procedure OUTPUT_FILE_ID (FLAWS_FILE_ID : in out TEXT_IO.FILE_TYPE;
  3503.                               STYLE_FILE_ID : in out TEXT_IO.FILE_TYPE) is
  3504.         CANNOT_OPEN_MSG : constant STRING :=
  3505.           "Cannot OPEN output files!  This program will fail uncleanly!";
  3506.     begin
  3507.         TEXT_IO.CREATE (FLAWS_FILE_ID, TEXT_IO.OUT_FILE,
  3508.                         FLAW_FILE_NAME (1 .. FLAW_FILE_NAME_LENGTH));
  3509.         TEXT_IO.CREATE (STYLE_FILE_ID, TEXT_IO.OUT_FILE,
  3510.                         STYLE_FILE_NAME (1 .. STYLE_FILE_NAME_LENGTH));
  3511.  
  3512.     exception
  3513.         when TEXT_IO.NAME_ERROR | TEXT_IO.USE_ERROR =>
  3514.             TEXT_IO.PUT_LINE( CANNOT_OPEN_MSG );
  3515.             raise;
  3516.         when OTHERS =>
  3517.             raise;
  3518.     end OUTPUT_FILE_ID;
  3519.  
  3520.  
  3521. end FILE_HANDLING;
  3522. ::::::::::
  3523. tokenzbod.ada
  3524. ::::::::::
  3525. with FILE_HANDLING;
  3526. with CURRENT_EXCEPTION;
  3527. with DYN;
  3528. use DYN;                                         -- must use use to overload
  3529.                                                  -- operators
  3530. package body TOKENIZER is
  3531. --------------------------------------------------------------------------
  3532. -- Abstract   : This is the body to the Tokenizer package.  This body
  3533. --              contains all the routines to build the token chain from
  3534. --              the input Ada source.
  3535. --------------------------------------------------------------------------
  3536.  
  3537. -- types used for input files
  3538.  
  3539.     subtype LINE_STRING is STRING(1..LINE_INDEX_RANGE'LAST);
  3540.                                                  -- an input line record
  3541.     subtype LINE_COLUMN is INTEGER range -1..LINE_INDEX_RANGE'LAST;
  3542.  
  3543.     type LINE_RECORD is                          -- Buffer containing current
  3544.         record                                   -- Line of file
  3545.             LINE : LINE_STRING;                  -- Line of text
  3546.             COLUMN : LINE_COLUMN := 0;           -- Current column
  3547.             LENGTH : LINE_COLUMN := 0;           -- Length of current line
  3548.         end record;
  3549.  
  3550. -- "global" variables
  3551.  
  3552.     CURRENT_LINE_NUMBER : LINE_NUM_RANGE := 0;
  3553.     CURRENT_LINE : LINE_RECORD;
  3554.     ID : DYN.DYN_STRING;                              -- Current identifier
  3555.     ROOT : IDENTIFIER_TREE := null;              -- Root of binary tree
  3556.     ROOT_TOKEN : TOKEN_POINTER;                  -- First token
  3557.     INPUT_FILE : TEXT_IO.FILE_TYPE;
  3558.  
  3559.     END_LINE : exception;
  3560.     END_FILE : exception;
  3561.  
  3562. -- Internal procedures and functions
  3563.  
  3564.     procedure INSERT                             -- Insert identifier into tree
  3565.                            (STRG : in DYN.DYN_STRING; -- String to be inserted
  3566.                             T : in out IDENTIFIER_TREE);
  3567.                                                  -- Tree to add it to
  3568.     function IS_A_RESERVED_WORD                  -- determines if Id is a
  3569.                                                  -- reserved word
  3570.                            (ID : in DYN.DYN_STRING)   -- String to check
  3571.                             return BOOLEAN;
  3572.     function RESERVED_WORD (ID : in DYN.DYN_STRING)
  3573.                             return KEYWORDS;
  3574.     function NEXT_CHARACTER return CHARACTER;    -- Gets next character from
  3575.                                                  -- input file
  3576.     function NEXT_IDENTIFIER return TOKEN;       -- Gets next token from input
  3577.  
  3578.  
  3579.     procedure INSERT(STRG : in DYN.DYN_STRING;
  3580.                      T : in out IDENTIFIER_TREE) is separate;
  3581.  
  3582.     function IS_A_RESERVED_WORD(ID : in DYN.DYN_STRING)
  3583.                 return BOOLEAN is separate;
  3584.     function RESERVED_WORD (ID : in DYN.DYN_STRING) return KEYWORDS is separate;
  3585.     function NEXT_CHARACTER return CHARACTER is separate;
  3586.     function NEXT_IDENTIFIER return TOKEN is separate;
  3587.     function TREE_ROOT return IDENTIFIER_TREE is separate;
  3588.  
  3589.  
  3590.     function EXTERNAL_REPRESENTATION(CURRENT_TOKEN : in TOKEN) return
  3591.              DYN.DYN_STRING is
  3592. --------------------------------------------------------------------------
  3593. -- Abstract   : This function returns the exact physical represeantation
  3594. --              in the input source for the token.
  3595. --------------------------------------------------------------------------
  3596. -- Parameters : CURRENT_TOKEN - Token to give representation for
  3597. --------------------------------------------------------------------------
  3598.  
  3599.         ANSWER : DYN.DYN_STRING;
  3600.  
  3601.         begin
  3602.             case CURRENT_TOKEN.TYPE_OF_TOKEN is
  3603.                 --  Check for tokens that have a constant representation
  3604.                 --  ( operators , etc.)
  3605.                 when END_OF_LINE =>
  3606.                     ANSWER := D_STRING("");
  3607.                 when CONCATENATION_OPERATOR =>
  3608.                     ANSWER := D_STRING("&");
  3609.                 when TICK =>
  3610.                     ANSWER := D_STRING("'");
  3611.                 when RIGHT_PARENTHESIS =>
  3612.                     ANSWER := D_STRING(")");
  3613.                 when LEFT_PARENTHESIS =>
  3614.                     ANSWER := D_STRING("(");
  3615.                 when MULTIPLICATION_OPERATOR =>
  3616.                     ANSWER := D_STRING("*");
  3617.                 when ADDITION_OPERATOR =>
  3618.                     ANSWER := D_STRING("+");
  3619.                 when COMMA =>
  3620.                     ANSWER := D_STRING(",");
  3621.                 when SUBTRACTION_OPERATOR =>
  3622.                     ANSWER := D_STRING("-");
  3623.                 when PERIOD =>
  3624.                     ANSWER := D_STRING(".");
  3625.                 when DIVISION_OPERATOR =>
  3626.                     ANSWER := D_STRING("/");
  3627.                 when COLON =>
  3628.                     ANSWER := D_STRING(":");
  3629.                 when SEMICOLON =>
  3630.                     ANSWER := D_STRING(";");
  3631.                 when LESS_THAN_OPERATOR =>
  3632.                     ANSWER := D_STRING("<");
  3633.                 when EQUAL_OPERATOR =>
  3634.                     ANSWER := D_STRING("=");
  3635.                 when GREATER_THAN_OPERATOR =>
  3636.                     ANSWER := D_STRING(">");
  3637.                 when VERTICAL_BAR =>
  3638.                     ANSWER := D_STRING("|");
  3639.                 when COMMENT =>
  3640.                     ANSWER := D_STRING("--") &
  3641.                         CURRENT_TOKEN.PHYSICAL_REPRESENTATION;
  3642.                 when ARROW =>
  3643.                     ANSWER := D_STRING("=>");
  3644.                 when DOUBLE_DOT =>
  3645.                     ANSWER := D_STRING("..");
  3646.                 when EXPONENTIATE_OPERATOR =>
  3647.                     ANSWER := D_STRING("**");
  3648.                 when ASSIGNMENT_OPERATOR =>
  3649.                     ANSWER := D_STRING(":=");
  3650.                 when INEQUAL_OPERATOR =>
  3651.                     ANSWER := D_STRING("/=");
  3652.                 when GREATER_THAN_OR_EQUAL_OPERATOR =>
  3653.                     ANSWER := D_STRING(">=");
  3654.                 when LESS_THAN_OR_EQUAL_OPERATOR =>
  3655.                     ANSWER := D_STRING("<=");
  3656.                 when LEFT_LABEL_BRACKET =>
  3657.                     ANSWER := D_STRING("<<");
  3658.                 when RIGHT_LABEL_BRACKET =>
  3659.                     ANSWER := D_STRING(">>");
  3660.                 when BOX =>
  3661.                     ANSWER := D_STRING("<>");
  3662.                 when STRING_LITERAL =>
  3663.                     ANSWER := D_STRING('"') &
  3664.                         CURRENT_TOKEN.PHYSICAL_REPRESENTATION & D_STRING('"');
  3665.                 when CHARACTER_LITERAL =>
  3666.                     ANSWER := D_STRING("'") &
  3667.                         CURRENT_TOKEN.PHYSICAL_REPRESENTATION & D_STRING("'");
  3668.                 when others =>
  3669.                     ANSWER := CURRENT_TOKEN.PHYSICAL_REPRESENTATION;
  3670.             end case;
  3671.             return ANSWER;
  3672.             exception
  3673.                 when others =>
  3674.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3675.                     TEXT_IO.PUT_LINE(" in EXTERNAL_REPRESENTATION");
  3676.                     raise;
  3677.         end  EXTERNAL_REPRESENTATION;
  3678.  
  3679.     function FIRST_TOKEN return TOKEN is
  3680. --------------------------------------------------------------------------
  3681. -- Abstract   : This function returns the first token in the input file.
  3682. --              The first token is used as a starting point by the
  3683. --              Style_Checker.
  3684. --------------------------------------------------------------------------
  3685.         begin
  3686.             return ROOT_TOKEN.all;
  3687.             exception
  3688.                 when others =>
  3689.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3690.                     TEXT_IO.PUT_LINE(" in FIRST_TOKEN");
  3691.                     raise;
  3692.         end FIRST_TOKEN;
  3693.  
  3694.     function LENGTH_OF_COMMENT(CURRENT_TOKEN : in TOKEN) return NATURAL is
  3695. --------------------------------------------------------------------------
  3696. -- Abstract   : This routine returns the length of a comment token
  3697. --------------------------------------------------------------------------
  3698. -- Parameters : CURRENT_TOKEN - Comment token
  3699. --------------------------------------------------------------------------
  3700.         begin
  3701.             if TYPE_OF_TOKEN_IS(CURRENT_TOKEN) = COMMENT then
  3702.                 return LENGTH(CURRENT_TOKEN.PHYSICAL_REPRESENTATION);
  3703.             else
  3704.                 raise INVALID_TOKEN;
  3705.             end if;
  3706.             exception
  3707.                 when INVALID_TOKEN => raise;
  3708.                 when others =>
  3709.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3710.                     TEXT_IO.PUT_LINE(" in LENGTH_OF_COMMENT");
  3711.                     raise;
  3712.         end LENGTH_OF_COMMENT;
  3713.  
  3714.     function NEXT_TOKEN(CURRENT_TOKEN : in TOKEN) return TOKEN is
  3715. --------------------------------------------------------------------------
  3716. -- Abstract   : This function returns the token in the input stream that
  3717. --              follows the token input to this routine.
  3718. --------------------------------------------------------------------------
  3719. -- Parameters : CURRENT_TOKEN - Return token that follows this token
  3720. --------------------------------------------------------------------------
  3721.         begin
  3722.             if CURRENT_TOKEN.NEXT_TOKEN /= null then
  3723.                 return CURRENT_TOKEN.NEXT_TOKEN.all;
  3724.             else
  3725.                 raise END_OF_TOKENS;
  3726.             end if;
  3727.             exception
  3728.                 when END_OF_TOKENS => raise;
  3729.                 when others =>
  3730.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3731.                     TEXT_IO.PUT_LINE(" in NEXT_TOKEN");
  3732.                     raise;
  3733.         end  NEXT_TOKEN;
  3734.  
  3735.     function PREVIOUS_TOKEN(CURRENT_TOKEN : in TOKEN) return TOKEN is
  3736. --------------------------------------------------------------------------
  3737. -- Abstract   : This function returns the token in the input stream that
  3738. --              precedes the token input to this routine.
  3739. --------------------------------------------------------------------------
  3740. -- Parameters : CURRENT_TOKEN - Return token that precedes this token
  3741. --------------------------------------------------------------------------
  3742.         begin
  3743.             if CURRENT_TOKEN.PREVIOUS_TOKEN /= null then
  3744.                 return CURRENT_TOKEN.PREVIOUS_TOKEN.all;
  3745.             else
  3746.                 raise END_OF_TOKENS;
  3747.             end if;
  3748.             exception
  3749.                 when END_OF_TOKENS => raise;
  3750.                 when others =>
  3751.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3752.                     TEXT_IO.PUT_LINE(" in PREVIOUS_TOKEN");
  3753.                     raise;
  3754.         end  PREVIOUS_TOKEN;
  3755.  
  3756.     function TYPE_OF_TOKEN_IS(CURRENT_TOKEN : in TOKEN) return TOKEN_TYPE is
  3757. --------------------------------------------------------------------------
  3758. -- Abstract   : This function returns the type associated with the input
  3759. --              token.
  3760. --------------------------------------------------------------------------
  3761. -- Parameters : CURRENT_TOKEN - Token to return type of.
  3762. --------------------------------------------------------------------------
  3763.         begin
  3764.             return CURRENT_TOKEN.TYPE_OF_TOKEN;
  3765.             exception
  3766.                 when others =>
  3767.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3768.                     TEXT_IO.PUT_LINE(" in TYPE_OF_TOKEN_IS");
  3769.                     raise;
  3770.         end  TYPE_OF_TOKEN_IS;
  3771.  
  3772.     procedure BUILD_TOKENS is separate;
  3773.  
  3774.     procedure TOKEN_POSITION(CURRENT_TOKEN : in TOKEN;
  3775.                              LINE : out LINE_NUM_RANGE;
  3776.                              COLUMN : out LINE_INDEX_RANGE) is
  3777. --------------------------------------------------------------------------
  3778. -- Abstract   : This routine returns the line and column position of the
  3779. --              input token.
  3780. --------------------------------------------------------------------------
  3781. -- Parameters : CURRENT_TOKEN - Input token
  3782. --              LINE          - Line number associated with input token
  3783. --              COLUMN        - Column number associated with input token
  3784. --------------------------------------------------------------------------
  3785.         begin
  3786.             LINE := CURRENT_TOKEN.TOKEN_POSITION.LINE;
  3787.             COLUMN := CURRENT_TOKEN.TOKEN_POSITION.COLUMN;
  3788.             exception
  3789.                 when others =>
  3790.                     TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3791.                     TEXT_IO.PUT_LINE(" in TOKEN_POSITION");
  3792.                     raise;
  3793.         end TOKEN_Position;
  3794.  
  3795.     procedure LINE_CONTAINING_TOKEN(CURRENT_TOKEN : in TOKEN;
  3796.                                     LINE : out DYN.DYN_STRING) is separate;
  3797.  
  3798. end TOKENIZER;
  3799. ::::::::::
  3800. insert.ada
  3801. ::::::::::
  3802. separate (TOKENIZER)
  3803.  
  3804. procedure INSERT                                -- Insert identifier into tree
  3805.         (STRG : in DYN.DYN_STRING;              -- String to be inserted
  3806.          T : in out IDENTIFIER_TREE) is         -- Tree to add it to
  3807. --------------------------------------------------------------------------
  3808. -- Abstract   : This routine inserts an identifier into the binary tree
  3809. --              of identifiers exported by the Tokenizer package.
  3810. --------------------------------------------------------------------------
  3811. -- Parameters : STRG    - Identifier to add to tree (if not already in it)
  3812. --              T       - Root of tree to add it to.
  3813. --------------------------------------------------------------------------
  3814. -- Algorithm  : Typical binary tree insertion.
  3815. --                  If T is null then insert identifier at T
  3816. --                  Else
  3817. --                      If T is the identifier add new reference
  3818. --                      Else
  3819. --                          Recursively call this routine with
  3820. --                              Left or Right pointer
  3821. --------------------------------------------------------------------------
  3822.  
  3823.     FOLLOW_CHAIN : REFPTR;
  3824.  
  3825. begin
  3826.     if T = null then                            -- add to tree here
  3827.         T := new IDENTIFIER_NODE;
  3828.         T.LEFT := null;
  3829.         T.RIGHT := null;
  3830.         T.REFERENCES := new REFS;
  3831.         T.REFERENCES.STRG := STRG;
  3832.         T.REFERENCES.NEXT := null;
  3833.     else
  3834.         if UPPER_CASE(T.REFERENCES.STRG) =      -- new reference to identifier
  3835.             UPPER_CASE(STRG) then
  3836.             FOLLOW_CHAIN := T.REFERENCES;
  3837.             while FOLLOW_CHAIN.NEXT /= null loop
  3838.                 FOLLOW_CHAIN := FOLLOW_CHAIN.NEXT;
  3839.             end loop;
  3840.             FOLLOW_CHAIN.NEXT := new REFS;
  3841.             FOLLOW_CHAIN.NEXT.NEXT := null;
  3842.             FOLLOW_CHAIN.NEXT.STRG := STRG;
  3843.         else
  3844.             if UPPER_CASE(T.REFERENCES.STRG) > UPPER_CASE(STRG) then
  3845.                 INSERT(STRG,T.LEFT);
  3846.             else
  3847.                 INSERT(STRG,T.RIGHT);
  3848.             end if;
  3849.         end if;
  3850.     end if;
  3851.     exception
  3852.         when others =>
  3853.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3854.             TEXT_IO.PUT_LINE("in INSERT");
  3855.             raise;
  3856. end INSERT;
  3857. ::::::::::
  3858. isareserv.ada
  3859. ::::::::::
  3860. separate (TOKENIZER)
  3861.  
  3862. function IS_A_RESERVED_WORD                     -- determines if Id is a
  3863.                                                 -- reserved word
  3864.         (ID : in DYN.DYN_STRING) return BOOLEAN is   -- String to check
  3865. --------------------------------------------------------------------------
  3866. -- Abstract   : This function returns true if the input name is an Ada
  3867. --              reserved word, otherwise it returns false.
  3868. --------------------------------------------------------------------------
  3869. -- Parameters : ID      - Name to check
  3870. --------------------------------------------------------------------------
  3871.  
  3872.     ANSWER : BOOLEAN;                           -- this is the return
  3873. begin
  3874.     case DYN.LENGTH(ID) is
  3875.         when 2 => ANSWER := UPPER_CASE(ID) = "AT"
  3876.                          or UPPER_CASE(ID) = "DO"
  3877.                          or UPPER_CASE(ID) = "IF"
  3878.                          or UPPER_CASE(ID) = "IN"
  3879.                          or UPPER_CASE(ID) = "IS"
  3880.                          or UPPER_CASE(ID) = "OF"
  3881.                          or UPPER_CASE(ID) = "OR";
  3882.         when 3 => ANSWER := UPPER_CASE(ID) = "ABS"
  3883.                          or UPPER_CASE(ID) = "ALL"
  3884.                          or UPPER_CASE(ID) = "AND"
  3885.                          or UPPER_CASE(ID) = "END"
  3886.                          or UPPER_CASE(ID) = "FOR"
  3887.                          or UPPER_CASE(ID) = "MOD"
  3888.                          or UPPER_CASE(ID) = "NEW"
  3889.                          or UPPER_CASE(ID) = "NOT"
  3890.                          or UPPER_CASE(ID) = "OUT"
  3891.                          or UPPER_CASE(ID) = "REM"
  3892.                          or UPPER_CASE(ID) = "USE"
  3893.                          or UPPER_CASE(ID) = "XOR";
  3894.         when 4 => ANSWER := UPPER_CASE(ID) = "BODY"
  3895.                          or UPPER_CASE(ID) = "CASE"
  3896.                          or UPPER_CASE(ID) = "ELSE"
  3897.                          or UPPER_CASE(ID) = "EXIT"
  3898.                          or UPPER_CASE(ID) = "GOTO"
  3899.                          or UPPER_CASE(ID) = "LOOP"
  3900.                          or UPPER_CASE(ID) = "NULL"
  3901.                          or UPPER_CASE(ID) = "TASK"
  3902.                          or UPPER_CASE(ID) = "THEN"
  3903.                          or UPPER_CASE(ID) = "TYPE"
  3904.                          or UPPER_CASE(ID) = "WHEN"
  3905.                          or UPPER_CASE(ID) = "WITH";
  3906.         when 5 => ANSWER := UPPER_CASE(ID) = "ABORT"
  3907.                          or UPPER_CASE(ID) = "ARRAY"
  3908.                          or UPPER_CASE(ID) = "BEGIN"
  3909.                          or UPPER_CASE(ID) = "DELAY"
  3910.                          or UPPER_CASE(ID) = "DELTA"
  3911.                          or UPPER_CASE(ID) = "ELSIF"
  3912.                          or UPPER_CASE(ID) = "ENTRY"
  3913.                          or UPPER_CASE(ID) = "RAISE"
  3914.                          or UPPER_CASE(ID) = "RANGE"
  3915.                          or UPPER_CASE(ID) = "WHILE";
  3916.         when 6 => ANSWER := UPPER_CASE(ID) = "ACCEPT"
  3917.                          or UPPER_CASE(ID) = "ACCESS"
  3918.                          or UPPER_CASE(ID) = "DIGITS"
  3919.                          or UPPER_CASE(ID) = "OTHERS"
  3920.                          or UPPER_CASE(ID) = "PRAGMA"
  3921.                          or UPPER_CASE(ID) = "RECORD"
  3922.                          or UPPER_CASE(ID) = "RETURN"
  3923.                          or UPPER_CASE(ID) = "SELECT";
  3924.         when 7 => ANSWER := UPPER_CASE(ID) = "DECLARE"
  3925.                          or UPPER_CASE(ID) = "GENERIC"
  3926.                          or UPPER_CASE(ID) = "LIMITED"
  3927.                          or UPPER_CASE(ID) = "PACKAGE"
  3928.                          or UPPER_CASE(ID) = "PRIVATE"
  3929.                          or UPPER_CASE(ID) = "RENAMES"
  3930.                          or UPPER_CASE(ID) = "REVERSE"
  3931.                          or UPPER_CASE(ID) = "SUBTYPE";
  3932.         when 8 => ANSWER := UPPER_CASE(ID) = "CONSTANT"
  3933.                          or UPPER_CASE(ID) = "FUNCTION"
  3934.                          or UPPER_CASE(ID) = "SEPARATE";
  3935.         when 9 => ANSWER := UPPER_CASE(ID) = "EXCEPTION"
  3936.                          or UPPER_CASE(ID) = "PROCEDURE"
  3937.                          or UPPER_CASE(ID) = "TERMINATE";
  3938.         when OTHERS => ANSWER := FALSE;
  3939.     end case;
  3940.     return ANSWER;
  3941.     exception
  3942.         when others =>
  3943.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  3944.             TEXT_IO.PUT_LINE("in IS_A_RESERVED_WORD");
  3945.             raise;
  3946. end IS_A_RESERVED_WORD;
  3947. ::::::::::
  3948. reservedw.ada
  3949. ::::::::::
  3950. separate (TOKENIZER)
  3951.  
  3952. function RESERVED_WORD (ID : in DYN.DYN_STRING) return KEYWORDS is
  3953. --------------------------------------------------------------------------
  3954. -- Abstract   : This function returns the Keywords enumeration value of
  3955. --              the input reserve word string.
  3956. --------------------------------------------------------------------------
  3957. -- Parameters : ID      - The string representation of  some reserve word
  3958. --------------------------------------------------------------------------
  3959.  
  3960.     ANSWER : KEYWORDS;                          -- this is the return
  3961. begin
  3962.     case DYN.LENGTH(ID) is
  3963.         when 2 =>
  3964.             if UPPER_CASE(ID) = "AT" then
  3965.                 ANSWER := AT_TOKEN;
  3966.             elsif UPPER_CASE(ID) = "DO" then
  3967.                 ANSWER := DO_TOKEN;
  3968.             elsif UPPER_CASE(ID) = "IF" then
  3969.                 ANSWER := IF_TOKEN;
  3970.             elsif UPPER_CASE(ID) = "IN" then
  3971.                 ANSWER := IN_TOKEN;
  3972.             elsif UPPER_CASE(ID) = "IS" then
  3973.                 ANSWER := IS_TOKEN;
  3974.             elsif UPPER_CASE(ID) = "OF" then
  3975.                 ANSWER := OF_TOKEN;
  3976.             elsif UPPER_CASE(ID) = "OR" then
  3977.                 ANSWER := OR_TOKEN;
  3978.             else raise INVALID_TOKEN;
  3979.             end if;
  3980.         when 3 =>
  3981.             if UPPER_CASE(ID) = "ABS" then
  3982.                 ANSWER := ABS_TOKEN;
  3983.             elsif UPPER_CASE(ID) = "ALL" then
  3984.                 ANSWER := ALL_TOKEN;
  3985.             elsif UPPER_CASE(ID) = "AND" then
  3986.                 ANSWER := AND_TOKEN;
  3987.             elsif UPPER_CASE(ID) = "END" then
  3988.                 ANSWER := END_TOKEN;
  3989.             elsif UPPER_CASE(ID) = "FOR" then
  3990.                 ANSWER := FOR_TOKEN;
  3991.             elsif UPPER_CASE(ID) = "MOD" then
  3992.                 ANSWER := MOD_TOKEN;
  3993.             elsif UPPER_CASE(ID) = "NEW" then
  3994.                 ANSWER := NEW_TOKEN;
  3995.             elsif UPPER_CASE(ID) = "NOT" then
  3996.                 ANSWER := NOT_TOKEN;
  3997.             elsif UPPER_CASE(ID) = "OUT" then
  3998.                 ANSWER := OUT_TOKEN;
  3999.             elsif UPPER_CASE(ID) = "REM" then
  4000.                 ANSWER := REM_TOKEN;
  4001.             elsif UPPER_CASE(ID) = "USE" then
  4002.                 ANSWER := USE_TOKEN;
  4003.             elsif UPPER_CASE(ID) = "XOR" then
  4004.                 ANSWER := XOR_TOKEN;
  4005.             else raise INVALID_TOKEN;
  4006.             end if;
  4007.         when 4 =>
  4008.             if UPPER_CASE(ID) = "BODY" then
  4009.                 ANSWER := BODY_TOKEN;
  4010.             elsif UPPER_CASE(ID) = "CASE" then
  4011.                 ANSWER := CASE_TOKEN;
  4012.             elsif UPPER_CASE(ID) = "ELSE" then
  4013.                 ANSWER := ELSE_TOKEN;
  4014.             elsif UPPER_CASE(ID) = "EXIT" then
  4015.                 ANSWER := EXIT_TOKEN;
  4016.             elsif UPPER_CASE(ID) = "GOTO" then
  4017.                 ANSWER := GOTO_TOKEN;
  4018.             elsif UPPER_CASE(ID) = "LOOP" then
  4019.                 ANSWER := LOOP_TOKEN;
  4020.             elsif UPPER_CASE(ID) = "NULL" then
  4021.                 ANSWER := NULL_TOKEN;
  4022.             elsif UPPER_CASE(ID) = "TASK" then
  4023.                 ANSWER := TASK_TOKEN;
  4024.             elsif UPPER_CASE(ID) = "THEN" then
  4025.                 ANSWER := THEN_TOKEN;
  4026.             elsif UPPER_CASE(ID) = "TYPE" then
  4027.                 ANSWER := TYPE_TOKEN;
  4028.             elsif UPPER_CASE(ID) = "WHEN" then
  4029.                 ANSWER := WHEN_TOKEN;
  4030.             elsif UPPER_CASE(ID) = "WITH" then
  4031.                 ANSWER := WITH_TOKEN;
  4032.             else raise INVALID_TOKEN;
  4033.             end if;
  4034.         when 5 =>
  4035.             if UPPER_CASE(ID) = "ABORT" then
  4036.                 ANSWER := ABORT_TOKEN;
  4037.             elsif UPPER_CASE(ID) = "ARRAY" then
  4038.                 ANSWER := ARRAY_TOKEN;
  4039.             elsif UPPER_CASE(ID) = "BEGIN" then
  4040.                 ANSWER := BEGIN_TOKEN;
  4041.             elsif UPPER_CASE(ID) = "DELAY" then
  4042.                 ANSWER := DELAY_TOKEN;
  4043.             elsif UPPER_CASE(ID) = "DELTA" then
  4044.                 ANSWER := DELTA_TOKEN;
  4045.             elsif UPPER_CASE(ID) = "ELSIF" then
  4046.                 ANSWER := ELSIF_TOKEN;
  4047.             elsif UPPER_CASE(ID) = "ENTRY" then
  4048.                 ANSWER := ENTRY_TOKEN;
  4049.             elsif UPPER_CASE(ID) = "RAISE" then
  4050.                 ANSWER := RAISE_TOKEN;
  4051.             elsif UPPER_CASE(ID) = "RANGE" then
  4052.                 ANSWER := RANGE_TOKEN;
  4053.             elsif UPPER_CASE(ID) = "WHILE" then
  4054.                 ANSWER := WHILE_TOKEN;
  4055.             else raise INVALID_TOKEN;
  4056.             end if;
  4057.         when 6 =>
  4058.             if UPPER_CASE(ID) = "ACCEPT" then
  4059.                 ANSWER := ACCEPT_TOKEN;
  4060.             elsif UPPER_CASE(ID) = "ACCESS" then
  4061.                 ANSWER := ACCESS_TOKEN;
  4062.             elsif UPPER_CASE(ID) = "DIGITS" then
  4063.                 ANSWER := DIGITS_TOKEN;
  4064.             elsif UPPER_CASE(ID) = "OTHERS" then
  4065.                 ANSWER := OTHERS_TOKEN;
  4066.             elsif UPPER_CASE(ID) = "PRAGMA" then
  4067.                 ANSWER := PRAGMA_TOKEN;
  4068.             elsif UPPER_CASE(ID) = "RECORD" then
  4069.                 ANSWER := RECORD_TOKEN;
  4070.             elsif UPPER_CASE(ID) = "RETURN" then
  4071.                 ANSWER := RETURN_TOKEN;
  4072.             elsif UPPER_CASE(ID) = "SELECT" then
  4073.                 ANSWER := SELECT_TOKEN;
  4074.             else raise INVALID_TOKEN;
  4075.             end if;
  4076.         when 7 =>
  4077.             if UPPER_CASE(ID) = "DECLARE" then
  4078.                 ANSWER := DECLARE_TOKEN;
  4079.             elsif UPPER_CASE(ID) = "GENERIC" then
  4080.                 ANSWER := GENERIC_TOKEN;
  4081.             elsif UPPER_CASE(ID) = "LIMITED" then
  4082.                 ANSWER := LIMITED_TOKEN;
  4083.             elsif UPPER_CASE(ID) = "PACKAGE" then
  4084.                 ANSWER := PACKAGE_TOKEN;
  4085.             elsif UPPER_CASE(ID) = "PRIVATE" then
  4086.                 ANSWER := PRIVATE_TOKEN;
  4087.             elsif UPPER_CASE(ID) = "RENAMES" then
  4088.                 ANSWER := RENAMES_TOKEN;
  4089.             elsif UPPER_CASE(ID) = "REVERSE" then
  4090.                 ANSWER := REVERSE_TOKEN;
  4091.             elsif UPPER_CASE(ID) = "SUBTYPE" then
  4092.                 ANSWER := SUBTYPE_TOKEN;
  4093.             else raise INVALID_TOKEN;
  4094.             end if;
  4095.         when 8 =>
  4096.             if UPPER_CASE(ID) = "CONSTANT" then
  4097.                 ANSWER := CONSTANT_TOKEN;
  4098.             elsif UPPER_CASE(ID) = "FUNCTION" then
  4099.                 ANSWER := FUNCTION_TOKEN;
  4100.             elsif UPPER_CASE(ID) = "SEPARATE" then
  4101.                 ANSWER := SEPARATE_TOKEN;
  4102.             else raise INVALID_TOKEN;
  4103.             end if;
  4104.         when 9 =>
  4105.             if UPPER_CASE(ID) = "EXCEPTION" then
  4106.                 ANSWER := EXCEPTION_TOKEN;
  4107.             elsif UPPER_CASE(ID) = "PROCEDURE" then
  4108.                 ANSWER := PROCEDURE_TOKEN;
  4109.             elsif UPPER_CASE(ID) = "TERMINATE" then
  4110.                 ANSWER := TERMINATE_TOKEN;
  4111.             else raise INVALID_TOKEN;
  4112.             end if;
  4113.         when OTHERS => raise INVALID_TOKEN;
  4114.     end case;
  4115.     return ANSWER;
  4116.     exception
  4117.         when others =>
  4118.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4119.             TEXT_IO.PUT_LINE(" in RESERVED_WORD");
  4120.             raise;
  4121. end RESERVED_WORD;
  4122. ::::::::::
  4123. nextchara.ada
  4124. ::::::::::
  4125. separate (TOKENIZER)
  4126.  
  4127. function NEXT_CHARACTER return CHARACTER is     -- Gets next character from
  4128.                                                 -- input file
  4129. --------------------------------------------------------------------------
  4130. -- Abstract   : This function returns the next character to be parsed
  4131. --              by the tokenizer build_tokens procedure.  This routine
  4132. --              also translates horizontal tabs into the correct number
  4133. --              of spaces (based on the constant TAB_LENGTH).
  4134. --------------------------------------------------------------------------
  4135.  
  4136.     TAB_LENGTH  : constant NATURAL := 8;
  4137.  
  4138.     SPACES_TO_ADD : NATURAL;                    -- Used if tab is found
  4139.  
  4140.     procedure GET_LINE(LINE : out LINE_RECORD) is
  4141.         NEW_INPUT_LINE : LINE_STRING;           -- parameters sent to TEXT_IO
  4142.         NEW_INPUT_LINE_LENGTH : LINE_COLUMN;
  4143.     begin
  4144.         if TEXT_IO.END_OF_FILE(INPUT_FILE) then
  4145.             CURRENT_LINE_NUMBER := CURRENT_LINE_NUMBER + 1;
  4146.             LINE.LENGTH := -1;
  4147.             LINE.COLUMN := 0;
  4148.         else
  4149.             CURRENT_LINE_NUMBER := CURRENT_LINE_NUMBER + 1;
  4150.             TEXT_IO.GET_LINE(INPUT_FILE,NEW_INPUT_LINE,NEW_INPUT_LINE_LENGTH);
  4151.             LINE.LINE(1..NEW_INPUT_LINE_LENGTH + 1) :=
  4152.                 NEW_INPUT_LINE(1..NEW_INPUT_LINE_LENGTH) & " ";
  4153.             LINE.COLUMN := 0;
  4154.             LINE.LENGTH := NEW_INPUT_LINE_LENGTH + 1;
  4155.         end if;
  4156.     exception
  4157.         when others =>
  4158.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4159.             TEXT_IO.PUT_LINE("in GET_LINE");
  4160.             raise;
  4161.     end GET_LINE;
  4162.  
  4163. begin
  4164.     if CURRENT_LINE.COLUMN < CURRENT_LINE.LENGTH  then
  4165.         CURRENT_LINE.COLUMN := CURRENT_LINE.COLUMN + 1;
  4166.         if CURRENT_LINE.LINE(CURRENT_LINE.COLUMN) /= ASCII.HT then
  4167.             return CURRENT_LINE.LINE(CURRENT_LINE.COLUMN);
  4168.         else   -- special case to handle tabs in input!
  4169.             CURRENT_LINE.LINE(CURRENT_LINE.COLUMN) := ' ';
  4170.             SPACES_TO_ADD := TAB_LENGTH - (CURRENT_LINE.COLUMN mod TAB_LENGTH);
  4171.             CURRENT_LINE.LINE(CURRENT_LINE.COLUMN + SPACES_TO_ADD..
  4172.                               CURRENT_LINE.LENGTH + SPACES_TO_ADD) :=
  4173.                 CURRENT_LINE.LINE(CURRENT_LINE.COLUMN..CURRENT_LINE.LENGTH);
  4174.             for I in 1..SPACES_TO_ADD loop
  4175.                 CURRENT_LINE.LINE(CURRENT_LINE.COLUMN + I - 1) := ' ';
  4176.             end loop;
  4177.             CURRENT_LINE.LENGTH := CURRENT_LINE.LENGTH + SPACES_TO_ADD;
  4178.             return ' ';
  4179.         end if;
  4180.     elsif CURRENT_LINE.LENGTH > -1 then
  4181.         GET_LINE(CURRENT_LINE);
  4182.         if CURRENT_LINE_NUMBER /= 1 then
  4183.             raise END_LINE;
  4184.         else    -- if CURRENT_LINE_NUMBER is 1 then this is the first time
  4185.                 -- through NEXT_CHARACTER, so get next character
  4186.             return NEXT_CHARACTER;
  4187.         end if;
  4188.     else
  4189.         raise END_FILE;
  4190.     end if;
  4191.     exception
  4192.         when END_LINE | END_FILE => raise;              -- Let 'em go
  4193.         when others =>
  4194.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4195.             TEXT_IO.PUT_LINE("in NEXT_CHARACTER");
  4196.             raise;
  4197. end NEXT_CHARACTER;
  4198. ::::::::::
  4199. nextident.ada
  4200. ::::::::::
  4201. separate (TOKENIZER)
  4202.  
  4203. function NEXT_IDENTIFIER return TOKEN is        -- Gets next token from input
  4204. --------------------------------------------------------------------------
  4205. -- Abstract   : This function builds the next token from the input stream.
  4206. --------------------------------------------------------------------------
  4207.  
  4208.     CURRENT_CHARACTER : CHARACTER;
  4209.     INDEX             : LINE_INDEX_RANGE;
  4210.     BUILD_A_TOKEN     : TOKEN_POINTER;
  4211.     TEMPORARY_ID      : STRING(1..LINE_INDEX_RANGE'last);
  4212.     TEMPORARY_ID_LENGTH : LINE_INDEX_RANGE := 0;
  4213.  
  4214.     function LOOK_AHEAD(CHARACTER_COUNT : in LINE_COLUMN := 1)
  4215.              return CHARACTER is
  4216.  
  4217.     begin
  4218.         if (CURRENT_LINE.COLUMN + CHARACTER_COUNT <= CURRENT_LINE.LENGTH) then
  4219.             return CURRENT_LINE.LINE(CURRENT_LINE.COLUMN + CHARACTER_COUNT);
  4220.         else return ' ';
  4221.         end if;
  4222.         exception
  4223.             when others =>
  4224.                 TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4225.                 TEXT_IO.PUT_LINE(" in LOOK_AHEAD");
  4226.                 raise;
  4227.     end LOOK_AHEAD;
  4228.  
  4229.     procedure PUSH_BACK_CHARACTER is
  4230.  
  4231.     begin
  4232.         if (CURRENT_LINE.COLUMN - 1 > 0) then
  4233.             CURRENT_LINE.COLUMN := CURRENT_LINE.COLUMN - 1;
  4234.         end if;
  4235.         exception
  4236.             when others =>
  4237.                 TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4238.                 TEXT_IO.PUT_LINE(" in PUSH_BACK_CHARACTER");
  4239.                 raise;
  4240.     end PUSH_BACK_CHARACTER;
  4241.  
  4242. begin
  4243.     BUILD_A_TOKEN := new TOKEN;
  4244.     BUILD_A_TOKEN.NEXT_TOKEN := null;
  4245.     BUILD_A_TOKEN.PREVIOUS_TOKEN := null;
  4246.     -- Set the column to the length of the current line in case END_LINE or
  4247.     -- END_FILE is raised by NEXT_CHARACTER
  4248.     if CURRENT_LINE.LENGTH > 0 then
  4249.         BUILD_A_TOKEN.TOKEN_POSITION.COLUMN := CURRENT_LINE.LENGTH - 1;
  4250.     else
  4251.         BUILD_A_TOKEN.TOKEN_POSITION.COLUMN := 0;
  4252.     end if;
  4253.     begin -- block to handle exceptions raised by NEXT_CHARACTER
  4254.         CURRENT_CHARACTER := NEXT_CHARACTER;
  4255.         while CURRENT_CHARACTER = ' ' loop
  4256.             CURRENT_CHARACTER := NEXT_CHARACTER;
  4257.         end loop;
  4258.         BUILD_A_TOKEN.TOKEN_POSITION.LINE := CURRENT_LINE_NUMBER;
  4259.         BUILD_A_TOKEN.TOKEN_POSITION.COLUMN := CURRENT_LINE.COLUMN;
  4260.         case CURRENT_CHARACTER is
  4261.             when '&' =>
  4262.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := CONCATENATION_OPERATOR;
  4263.             when ')' =>
  4264.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := RIGHT_PARENTHESIS;
  4265.             when '(' =>
  4266.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := LEFT_PARENTHESIS;
  4267.             when '+' =>
  4268.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := ADDITION_OPERATOR;
  4269.             when ',' =>
  4270.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := COMMA;
  4271.             when ';' =>
  4272.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := SEMICOLON;
  4273.             when '|' =>
  4274.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := VERTICAL_BAR;
  4275.             when '.' =>
  4276.                 if (LOOK_AHEAD = '.') then
  4277.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4278.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := DOUBLE_DOT;
  4279.                 else
  4280.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := PERIOD;
  4281.                 end if;
  4282.             when ':' =>
  4283.                 if (LOOK_AHEAD = '=') then
  4284.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4285.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := ASSIGNMENT_OPERATOR;
  4286.                 else
  4287.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := COLON;
  4288.                 end if;
  4289.             when '-' =>
  4290.                 if (LOOK_AHEAD = '-') then
  4291.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4292.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := COMMENT;
  4293.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4294.                     BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4295.                         DYN.D_STRING(CURRENT_LINE.LINE(
  4296.                         CURRENT_LINE.COLUMN..CURRENT_LINE.LENGTH));
  4297.                     CURRENT_LINE.COLUMN := CURRENT_LINE.LENGTH;
  4298.                 else
  4299.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := SUBTRACTION_OPERATOR;
  4300.                 end if;
  4301.             when '*' =>
  4302.                 if (LOOK_AHEAD = '*') then
  4303.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4304.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := EXPONENTIATE_OPERATOR;
  4305.                 else
  4306.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := MULTIPLICATION_OPERATOR;
  4307.                 end if;
  4308.             when '=' =>
  4309.                 if (LOOK_AHEAD = '>') then
  4310.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4311.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := ARROW;
  4312.                 else
  4313.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := EQUAL_OPERATOR;
  4314.                 end if;
  4315.             when '/' =>
  4316.                 if (LOOK_AHEAD = '=') then
  4317.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4318.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := INEQUAL_OPERATOR;
  4319.                 else
  4320.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := DIVISION_OPERATOR;
  4321.                 end if;
  4322.             when '>' =>
  4323.                 if (LOOK_AHEAD = '=') then
  4324.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4325.                     BUILD_A_TOKEN.TYPE_OF_TOKEN :=
  4326.                         GREATER_THAN_OR_EQUAL_OPERATOR;
  4327.                 elsif (LOOK_AHEAD = '>') then
  4328.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4329.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := RIGHT_LABEL_BRACKET;
  4330.                 else
  4331.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := GREATER_THAN_OPERATOR;
  4332.                 end if;
  4333.             when '<' =>
  4334.                 if (LOOK_AHEAD = '=') then
  4335.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4336.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := LESS_THAN_OR_EQUAL_OPERATOR;
  4337.                 elsif (LOOK_AHEAD = '>') then
  4338.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4339.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := BOX;
  4340.                 elsif (LOOK_AHEAD = '<') then
  4341.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4342.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := LEFT_LABEL_BRACKET;
  4343.                 else
  4344.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := LESS_THAN_OPERATOR;
  4345.                 end if;
  4346.             when ''' =>
  4347.                 if (LOOK_AHEAD(2) = ''') then
  4348.                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4349.                     BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4350.                         DYN.D_STRING(CURRENT_CHARACTER);
  4351.                     CURRENT_CHARACTER := NEXT_CHARACTER;-- skip tick
  4352.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := CHARACTER_LITERAL;
  4353.                 else
  4354.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := TICK;
  4355.                 end if;
  4356.             when '"' =>
  4357.                 CURRENT_CHARACTER := NEXT_CHARACTER;
  4358.                 begin   -- block to handle unexpected end of line in incorrect
  4359.                         -- input code
  4360.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := STRING_LITERAL;
  4361.                     while CURRENT_CHARACTER /= '"' loop
  4362.                         TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4363.                         TEMPORARY_ID(TEMPORARY_ID_LENGTH) := CURRENT_CHARACTER;
  4364.                         CURRENT_CHARACTER := NEXT_CHARACTER;
  4365.                     end loop;
  4366.                     BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4367.                         DYN.D_STRING(TEMPORARY_ID(1..TEMPORARY_ID_LENGTH));
  4368.                     exception
  4369.                         when END_LINE =>
  4370.                             BUILD_A_TOKEN.TYPE_OF_TOKEN := END_OF_LINE;
  4371.                         when END_FILE =>
  4372.                             BUILD_A_TOKEN.TYPE_OF_TOKEN := END_OF_FILE;
  4373.                             BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4374.                                 DYN.D_STRING(TEXT_IO.NAME(INPUT_FILE));
  4375.                         when others =>
  4376.                             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4377.                             TEXT_IO.PUT_LINE
  4378.                                 ("in block to handle quoted string");
  4379.                             raise;
  4380.                 end;
  4381.             when 'A' .. 'Z' | 'a' .. 'z' =>
  4382.                 begin   -- block to handle end of line or end of file
  4383.                     while ((CURRENT_CHARACTER >= 'A') and
  4384.                            (CURRENT_CHARACTER <= 'Z')) or
  4385.                           ((CURRENT_CHARACTER >= 'a') and
  4386.                            (CURRENT_CHARACTER <= 'z')) or
  4387.                           ((CURRENT_CHARACTER >= '0') and
  4388.                            (CURRENT_CHARACTER <= '9')) or
  4389.                            (CURRENT_CHARACTER = '_') loop
  4390.                         TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4391.                         TEMPORARY_ID(TEMPORARY_ID_LENGTH) := CURRENT_CHARACTER;
  4392.                         CURRENT_CHARACTER := NEXT_CHARACTER;
  4393.                     end loop;
  4394.                     if CURRENT_CHARACTER /= ' ' then
  4395.                         PUSH_BACK_CHARACTER;    -- last character not part of
  4396.                     end if;                     -- ID and not "parsed"
  4397.                     exception
  4398. --                      when END_FILE | END_LINE => null; -- ok exceptions
  4399.                         when others =>
  4400.                             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4401.                             TEXT_IO.PUT_LINE("in block to handle identifiers ");
  4402.                             raise;
  4403.                 end;
  4404.                 BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4405.                     DYN.D_STRING(TEMPORARY_ID(1..TEMPORARY_ID_LENGTH));
  4406.                 if IS_A_RESERVED_WORD(BUILD_A_TOKEN.PHYSICAL_REPRESENTATION)
  4407.                 then
  4408.                     BUILD_A_TOKEN.TYPE_OF_TOKEN :=
  4409.                         RESERVED_WORD(BUILD_A_TOKEN.PHYSICAL_REPRESENTATION);
  4410.                 else
  4411.                     BUILD_A_TOKEN.TYPE_OF_TOKEN := IDENTIFIER;
  4412.                 end if;
  4413.             when '0' .. '9' =>
  4414.                 begin   -- block to handle end of line or end of file
  4415.                     while ((CURRENT_CHARACTER >= '0') and
  4416.                            (CURRENT_CHARACTER <= '9')) or
  4417.                            (CURRENT_CHARACTER = '_') loop
  4418.                         TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4419.                         TEMPORARY_ID(TEMPORARY_ID_LENGTH) := CURRENT_CHARACTER;
  4420.                         CURRENT_CHARACTER := NEXT_CHARACTER;
  4421.                         case CURRENT_CHARACTER is
  4422.                             when '.' =>         -- skip decimal point
  4423.                                 if (LOOK_AHEAD >= '0') and
  4424.                                    (LOOK_AHEAD <= '9') then
  4425.                                     TEMPORARY_ID_LENGTH :=
  4426.                                         TEMPORARY_ID_LENGTH + 1;
  4427.                                     TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4428.                                         CURRENT_CHARACTER;
  4429.                                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4430.                                 end if;
  4431.                             when 'E' | 'e' =>   -- skip E and optional sign
  4432.                                 TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4433.                                 TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4434.                                     CURRENT_CHARACTER;
  4435.                                 CURRENT_CHARACTER := NEXT_CHARACTER;
  4436.                                 if (CURRENT_CHARACTER = '-') or
  4437.                                    (CURRENT_CHARACTER = '+') then
  4438.                                     TEMPORARY_ID_LENGTH :=
  4439.                                         TEMPORARY_ID_LENGTH + 1;
  4440.                                     TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4441.                                         CURRENT_CHARACTER;
  4442.                                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4443.                                 end if;
  4444.                             when '#' =>         -- based literal
  4445.                                 TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4446.                                 TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4447.                                     CURRENT_CHARACTER;
  4448.                                 CURRENT_CHARACTER := NEXT_CHARACTER;
  4449.                                 -- There is a chance that we will skip over
  4450.                                 -- valid tokens searching for closing '#' if it
  4451.                                 -- is missing, but ill formed inpute is NOT our
  4452.                                 -- problem.
  4453.                                 while (CURRENT_CHARACTER /= '#') loop
  4454.                                     TEMPORARY_ID_LENGTH :=
  4455.                                         TEMPORARY_ID_LENGTH + 1;
  4456.                                     TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4457.                                         CURRENT_CHARACTER;
  4458.                                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4459.                                 end loop;
  4460.                                 -- Now stick # into ID and continue
  4461.                                 TEMPORARY_ID_LENGTH := TEMPORARY_ID_LENGTH + 1;
  4462.                                 TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4463.                                     CURRENT_CHARACTER;
  4464.                                 CURRENT_CHARACTER := NEXT_CHARACTER;
  4465.                                 if (CURRENT_CHARACTER = 'E') or
  4466.                                    (CURRENT_CHARACTER = 'e') then
  4467.                                                 -- skip E and optional sign
  4468.                                     TEMPORARY_ID_LENGTH :=
  4469.                                         TEMPORARY_ID_LENGTH + 1;
  4470.                                     TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4471.                                         CURRENT_CHARACTER;
  4472.                                     CURRENT_CHARACTER := NEXT_CHARACTER;
  4473.                                     if (CURRENT_CHARACTER = '-') or
  4474.                                        (CURRENT_CHARACTER = '+') then
  4475.                                         TEMPORARY_ID_LENGTH :=
  4476.                                             TEMPORARY_ID_LENGTH + 1;
  4477.                                         TEMPORARY_ID(TEMPORARY_ID_LENGTH) :=
  4478.                                             CURRENT_CHARACTER;
  4479.                                         CURRENT_CHARACTER := NEXT_CHARACTER;
  4480.                                     end if;
  4481.                                 end if;
  4482.                             when others => null;
  4483.                         end case;
  4484.                     end loop;
  4485.                     if CURRENT_CHARACTER /= ' ' then
  4486.                         PUSH_BACK_CHARACTER;    -- last character not part of
  4487.                     end if;                     -- number and not "parsed"
  4488.                     exception
  4489. --                      when END_FILE | END_LINE => null; -- ok exceptions
  4490.                         when others =>
  4491.                             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4492.                             TEXT_IO.PUT_LINE("in block to handle numeric " &
  4493.                                              "literals");
  4494.                             raise;
  4495.                 end;
  4496.                 BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4497.                     DYN.D_STRING(TEMPORARY_ID(1..TEMPORARY_ID_LENGTH));
  4498.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := NUMERIC_LITERAL;
  4499.             when others =>
  4500.                 BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4501.                     DYN.D_STRING(CURRENT_CHARACTER);
  4502.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := ANYTHING_ELSE;
  4503.         end case;
  4504.         exception
  4505.             when END_LINE =>
  4506.                 BUILD_A_TOKEN.TOKEN_POSITION.LINE := CURRENT_LINE_NUMBER - 1;
  4507.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := END_OF_LINE;
  4508.             when END_FILE =>
  4509.                 BUILD_A_TOKEN.TOKEN_POSITION.LINE := CURRENT_LINE_NUMBER;
  4510.                 BUILD_A_TOKEN.TYPE_OF_TOKEN := END_OF_FILE;
  4511.                 BUILD_A_TOKEN.PHYSICAL_REPRESENTATION :=
  4512.                     DYN.D_STRING(TEXT_IO.NAME(INPUT_FILE));
  4513.             when others =>
  4514.                 TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4515.                 TEXT_IO.PUT_LINE("in NEXT_IDENTIFIER");
  4516.                 raise;
  4517.     end;
  4518.     return BUILD_A_TOKEN.all;
  4519. end NEXT_IDENTIFIER;
  4520. ::::::::::
  4521. buildtoke.ada
  4522. ::::::::::
  4523. separate (TOKENIZER)
  4524.  
  4525. procedure BUILD_TOKENS is
  4526. --------------------------------------------------------------------------
  4527. -- Abstract   : This is the procedure that builds the token stream from
  4528. --              the input Ada source file(s).
  4529. --------------------------------------------------------------------------
  4530.  
  4531.     CURRENT_TOKEN : TOKEN_POINTER;
  4532.     LAST_TOKEN : TOKEN_POINTER;
  4533.     MORE_FILES : BOOLEAN := TRUE;
  4534. begin
  4535.     ROOT_TOKEN := null;
  4536.     LAST_TOKEN := null;
  4537.     FILE_HANDLING.INPUT_FILE_ID(INPUT_FILE,MORE_FILES);
  4538.     while MORE_FILES loop
  4539.         CURRENT_LINE_NUMBER := 0;
  4540.         CURRENT_LINE.LENGTH := 0;
  4541.         CURRENT_LINE.COLUMN := 0;
  4542.         loop
  4543.             CURRENT_TOKEN := new TOKEN;
  4544.             CURRENT_TOKEN.all := NEXT_IDENTIFIER;
  4545.             if TYPE_OF_TOKEN_IS(CURRENT_TOKEN.all) = IDENTIFIER then
  4546.                 INSERT(CURRENT_TOKEN.PHYSICAL_REPRESENTATION,ROOT);
  4547.             end if;
  4548.             if ROOT_TOKEN = null then
  4549.                 ROOT_TOKEN := CURRENT_TOKEN;
  4550.                 LAST_TOKEN := CURRENT_TOKEN;
  4551.             else
  4552.                 LAST_TOKEN.NEXT_TOKEN := CURRENT_TOKEN;
  4553.                 CURRENT_TOKEN.PREVIOUS_TOKEN := LAST_TOKEN;
  4554.                 LAST_TOKEN := CURRENT_TOKEN;
  4555.             end if;
  4556.             exit when TYPE_OF_TOKEN_IS(CURRENT_TOKEN.all) = END_OF_FILE;
  4557.         end loop;
  4558.         FILE_HANDLING.INPUT_FILE_ID(INPUT_FILE,MORE_FILES);
  4559.     end loop;
  4560.     exception
  4561.         when FILE_HANDLING.HELP_ASKED_FOR =>
  4562.             raise;
  4563.         when others =>
  4564.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4565.             TEXT_IO.PUT_LINE(" in BUILD_TOKENS");
  4566.             raise;
  4567. end BUILD_TOKENS;
  4568. ::::::::::
  4569. lineconta.ada
  4570. ::::::::::
  4571. separate (TOKENIZER)
  4572.  
  4573. procedure LINE_CONTAINING_TOKEN(CURRENT_TOKEN : in TOKEN;
  4574.                                 LINE : out DYN.DYN_STRING) is
  4575. --------------------------------------------------------------------------
  4576. -- Abstract   : This procedure builds the source line containing the input
  4577. --              token by scanning the tokens in each direction.
  4578. --------------------------------------------------------------------------
  4579. -- Parameters : CURRENT_TOKEN   - token to build line for
  4580. --              LINE            - Copy of input line
  4581. --------------------------------------------------------------------------
  4582.     RETURN_STRING : LINE_STRING := (1..LINE_STRING'length => ' ');
  4583.     STRING_LENGTH : LINE_INDEX_RANGE := 0;
  4584.     CUR_TOKEN     : TOKEN;
  4585. begin
  4586.     CUR_TOKEN := CURRENT_TOKEN;
  4587.     -- get to the token that ends the line before the line containing this token
  4588.     -- block to encapsulate PREVIOUS_TOKEN calls in case this is the first
  4589.     -- line of the source file
  4590.     begin
  4591.         while CUR_TOKEN.TOKEN_POSITION.LINE = CURRENT_TOKEN.TOKEN_POSITION.LINE
  4592.             loop
  4593.             CUR_TOKEN := PREVIOUS_TOKEN(CUR_TOKEN);
  4594.         end loop;
  4595.         CUR_TOKEN := NEXT_TOKEN(CUR_TOKEN);
  4596.         exception
  4597.             when END_OF_TOKENS =>               -- will be raised if this is 1st
  4598.                 null;                           -- line
  4599.             when others => raise;
  4600.     end;
  4601.     -- CUR_TOKEN should now point to the first token of the line
  4602.     while (TYPE_OF_TOKEN_IS(CUR_TOKEN) /= END_OF_LINE) and
  4603.          (TYPE_OF_TOKEN_IS(CUR_TOKEN) /= END_OF_FILE) loop
  4604.         RETURN_STRING(CUR_TOKEN.TOKEN_POSITION.COLUMN ..
  4605.             (CUR_TOKEN.TOKEN_POSITION.COLUMN - 1) +
  4606.             DYN.LENGTH(EXTERNAL_REPRESENTATION(CUR_TOKEN))) :=
  4607.             DYN.STR(EXTERNAL_REPRESENTATION(CUR_TOKEN));
  4608.         STRING_LENGTH := (CUR_TOKEN.TOKEN_POSITION.COLUMN - 1) +
  4609.             DYN.LENGTH(EXTERNAL_REPRESENTATION(CUR_TOKEN));
  4610.         CUR_TOKEN := NEXT_TOKEN(CUR_TOKEN);
  4611.     end loop;
  4612.     LINE := DYN.D_STRING(RETURN_STRING(1..STRING_LENGTH));
  4613.     exception
  4614.         when others =>
  4615.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4616.             TEXT_IO.PUT_LINE(" in LINE_CONTAINING_TOKEN");
  4617.             raise;
  4618. end LINE_CONTAINING_TOKEN;
  4619. ::::::::::
  4620. treeroot.ada
  4621. ::::::::::
  4622. separate (TOKENIZER)
  4623.  
  4624. function TREE_ROOT return IDENTIFIER_TREE is
  4625. --------------------------------------------------------------------------
  4626. -- Abstract   : This function returns the root of the binary tree created
  4627. --              by the tokenizer
  4628. --------------------------------------------------------------------------
  4629.  
  4630. begin
  4631.     return ROOT;
  4632.     exception
  4633.         when others =>
  4634.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  4635.             TEXT_IO.PUT_LINE(" in TREE_ROOT");
  4636.             raise;
  4637. end TREE_ROOT;
  4638. ::::::::::
  4639. SPARAMBOD.ADA
  4640. ::::::::::
  4641. Package body Style_Parameters is
  4642.     use TOKENIZER;
  4643.  
  4644.    type Package_Name_Node;
  4645.    type Package_List     is access Package_Name_node;
  4646.    type Package_Name_Node is
  4647.          record
  4648.            P_Name : DYN.DYN_STRING;
  4649.            Next   : Package_List;
  4650.          end record;
  4651.  
  4652.    ERRORS_TO_LIST : Natural := 5;
  4653.    KEYWORD_OUTPUT : Keyword_Options := None;
  4654.    OPERATOR_OUTPUT: boolean;
  4655.  
  4656.    SHORT_PROGRAM : Natural   := 100;    -- Any program this length or shorter
  4657.                                         -- may ignore limits when checking
  4658.                                         -- complexity, keyword frequency,
  4659.                                         -- etc.
  4660.  
  4661.  
  4662.    SHORT_WORD : Word_Lengths := 6;      -- Any word this length or shorter
  4663.                                         -- may ignore Limits when checking
  4664.                                         -- underscores and vowels.
  4665.  
  4666.    SHORT_STRUCTURE : Natural := 5;      -- Any structure this length or shorter
  4667.                                         -- may ignore style when checking for
  4668.                                         -- surrounding blank lines or
  4669.                                         -- loop names.
  4670.  
  4671.    RESERVED_CASE : Reserve_Word_Cases := Reserved_Case_Lower;
  4672.  
  4673.    OBJECT_CASE : Object_Name_Cases := Name_Case_Upper;
  4674.  
  4675.    NAME_LENGTH_AVE : Word_Lengths range 1..Word_Lengths'last := 5;
  4676.  
  4677.    UNDERSCORE_REQUIRED : boolean;
  4678.    UNDERSCORE_LENGTH_AVE : Word_Lengths range 1..Word_Lengths'last
  4679.           := Name_Length_Ave;
  4680.  
  4681.    ABBREV_AVE : Abbreviation_Aves := 0.35;
  4682.    SPELLING_REQUIREMENT : Require_Type := Not_Required;
  4683.  
  4684. -- Physical Layout
  4685.    ONE_LINE_PER_STATEMENT  : boolean;
  4686.   -- Indentation
  4687.   -- Initial on line    is Always Required!  No parameter!
  4688.    TYPE_INDENTATION        : boolean;
  4689.    COMMENT_INDENTATION     : boolean;
  4690.   -- Blank Space
  4691.    BLANKS_AROUND_BLOCKS    : boolean;
  4692.    BLANK_LINE_PERCENT      : float     := 0.20;
  4693.    PROLOG_NEEDED           : boolean;
  4694.    LOOP_NAME_NEEDED        : Loop_Names_Needs;
  4695.    LOOP_NAME_PERCENT       : float     := 0.30; -- 30% of loops have names.
  4696.  
  4697. -- Statement USE
  4698.    KEYWRD_ARRAY            : Keyword_Uses;
  4699.    AVE_SIZE_OF_COMMENT     : Positive  := 15;   -- Average chars/comment
  4700.  
  4701. -- Information hiding, abstraction, data use
  4702.   -- constants/literals in code vs. specification
  4703.    LITERAL_FREQ_IN_BODY    : Float     := 0.10; -- 90% should be in spec.
  4704.   -- Should declare own types
  4705.    UNIVERSAL_TYPE_USAGE    : Float    := 0.40;  -- Just a WAG
  4706.   -- Should use enumeration and record facilities
  4707.    DATA_STRUCTURE_USE      : boolean  := TRUE;   -- Do we check for structures?
  4708.    ATTRIBUTE_USE           : Require_Type := Required; -- or attributes?
  4709.  
  4710. -- Modularity
  4711.    LOWER_PARAMETER_SIZE    : Natural  := 1;
  4712.    UPPER_PARAMETER_SIZE    : Natural  := 8;
  4713.    LOWER_SUBPROGRAM_SIZE   : Natural  := 10;
  4714.    UPPER_SUBPROGRAM_SIZE   : Natural  := 200;
  4715.  
  4716. -- Complexity
  4717.    KEYWORD_TYPES_USED      : float     := 0.65; -- This applies when program
  4718.                                                 -- is not 'short'.  # keywords
  4719.                                                 -- is Number_of_Keywords;
  4720.    CONTROL_NESTING_LIMIT   : Natural   := 8;
  4721.    SUBPROGRAM_NESTING_LIMIT: Natural   := 4;
  4722.    PACKAGE_NESTING_LIMIT   : Natural   := 2;
  4723.    MAX_LOOP_EXITS          : Natural   := 1;    -- Structured programming df
  4724.    LINE_SIZE_LIMIT         : Positive  := 80;
  4725.    CHAR_SET_ALLOWED        : Character_Set_Types := Graphic;
  4726.    REP_SPECS_PERMITTED     : boolean   := TRUE;
  4727.    ADDR_CLAUSES_PERMITTED  : boolean   := TRUE;
  4728.    PRAGMAS_TO_BE_NOTED     : Pragma_Classes := System_Dependent;
  4729.    PROSCRIBED : constant array (1.. 5) of DYN.DYN_STRING :=
  4730.         (DYN.D_STRING("SYSTEM"),
  4731.         DYN.D_STRING("TTY_IO"),
  4732.         DYN.D_STRING("UNCHECKED_CONVERSION"),
  4733.         DYN.D_STRING("UNCHECKED_DEALLOCATION"),
  4734.         DYN.D_STRING("CURRENT_EXCEPTION"));
  4735.  
  4736. -------------------------------------
  4737. -- This procedure obtains the 'style
  4738. -------------------------------------
  4739.   Procedure Set_Style_Parameters is
  4740.           -- This sets the parameter variables
  4741.     TEMP_PACKAGE : Package_List;
  4742.     END_OF_PACKAGE_LIST : Package_List;
  4743.     KWD_DEFAULT  : Keyword_Use_Descript
  4744.                  := (Use_Class => Free_Use,
  4745.                      Use_Freq  => 0.0);
  4746.   begin
  4747.     ERRORS_TO_LIST  := 10;
  4748.     KEYWORD_OUTPUT  :=   Used;
  4749.     OPERATOR_OUTPUT :=   FALSE;
  4750.     SHORT_PROGRAM   := 100;
  4751.     SHORT_WORD      :=   6;
  4752.     SHORT_STRUCTURE :=   5;
  4753.     RESERVED_CASE   := Reserved_Case_Lower;
  4754.     OBJECT_CASE     := Name_Case_Upper;
  4755.     NAME_LENGTH_AVE := 5;
  4756.     UNDERSCORE_REQUIRED := TRUE;
  4757.     UNDERSCORE_LENGTH_AVE := 5;
  4758.     ABBREV_AVE      := 0.35;
  4759.     SPELLING_REQUIREMENT := Not_Required;
  4760.     ONE_LINE_PER_STATEMENT := TRUE;
  4761.     TYPE_INDENTATION := TRUE;
  4762.     COMMENT_INDENTATION := FALSE;
  4763.     BLANKS_AROUND_BLOCKS := TRUE;
  4764.     LOOP_NAME_NEEDED := Required;
  4765.     LOOP_NAME_PERCENT := 0.30;
  4766.     AVE_SIZE_OF_COMMENT := 15;
  4767.     LITERAL_FREQ_IN_BODY := 0.30;
  4768.     UNIVERSAL_TYPE_USAGE := 0.40;
  4769.     DATA_STRUCTURE_USE := TRUE;
  4770.     ATTRIBUTE_USE := Required;
  4771.     LOWER_PARAMETER_SIZE := 0;
  4772.     UPPER_PARAMETER_SIZE := 4;
  4773.     LOWER_SUBPROGRAM_SIZE := 10;
  4774.     UPPER_SUBPROGRAM_SIZE := 200;
  4775.     CONTROL_NESTING_LIMIT := 8;
  4776.     SUBPROGRAM_NESTING_LIMIT := 4;
  4777.     PACKAGE_NESTING_LIMIT := 2;
  4778.     MAX_LOOP_EXITS           := 1;    -- Structured programming df
  4779.     LINE_SIZE_LIMIT         := 80;
  4780.     CHAR_SET_ALLOWED       := Graphic;
  4781.     REP_SPECS_PERMITTED      := FALSE;
  4782.     ADDR_CLAUSES_PERMITTED   := FALSE;
  4783. --    KEYWRD_ARRAY := TBD;
  4784.     For kwd in TOKENIZER.KEYWORDS loop
  4785.       KEYWRD_ARRAY(kwd) := KWD_DEFAULT;
  4786.     end loop;
  4787.     KEYWRD_ARRAY( TOKENIZER.KEYWORDS'(TOKENIZER.GOTO_TOKEN) ):=
  4788.       (Use_Class => No_Use,         Use_Freq => 0.00);
  4789.     KEYWRD_ARRAY( TOKENIZER.USE_TOKEN ) :=
  4790.       (Use_Class => Restricted_Use, Use_Freq => 0.20);
  4791.  
  4792.     PRAGMAS_TO_BE_NOTED := All_Pragmas;
  4793.  
  4794. --    Set of the LIST of PROSCRIBED ('bad') PACKAGES
  4795. --    These packages are defined by the constant array PROSCRIBED, above.
  4796. --    To change the proscribed packages, change that array.
  4797.  
  4798.   end;
  4799.  
  4800. --------------------------------------------
  4801. -- These return style individual parameters
  4802. --------------------------------------------
  4803.   function Number_of_Errors_to_Report return natural is
  4804.   -- This returns a number telling how many times to list
  4805.   -- a error in the "Flaws" output.  I.E. If this returns
  4806.   -- "3", then only the first three occurences of each
  4807.   -- type of error are listed.
  4808.   begin
  4809.     return ERRORS_TO_LIST;
  4810.   end;
  4811.  
  4812.   function OUTPUT_KEYWORD_LIST return Keyword_Options is
  4813.   -- This function returns a value specifying the output format for
  4814.   -- listing the reserved word usage.  It specifys which class of
  4815.   -- reserved words to output, all keywords, only those keywords
  4816.   -- used or not used, keywords used in violation of style restrictions,
  4817.   -- or no keywords output.
  4818.   begin
  4819.     return KEYWORD_OUTPUT;
  4820.   end;
  4821.  
  4822.   function OUTPUT_OPERATOR_LIST return boolean is
  4823.   -- This function returns true if the operator list is to be printed
  4824.   -- as part of the style report.
  4825.   begin
  4826.     return OPERATOR_OUTPUT;
  4827.   end;
  4828.  
  4829.   function SMALL_PROGRAM_SIZE return natural is
  4830.   -- returns size of programs considered 'too small' so limits of
  4831.   -- some things may be violated with not penalty.
  4832.   begin
  4833.     return SHORT_PROGRAM;
  4834.   end;
  4835.  
  4836.   function Small_Word_Size    return Word_Lengths is
  4837.   -- returns size of words considered 'too small' so limits of
  4838.   -- some things may be violated with no penalty.
  4839.   begin
  4840.     return SHORT_WORD;
  4841.   end;
  4842.  
  4843.   function Small_Structure_Size    return Natural is
  4844.   -- returns size (in statements) of structures considered 'too small' so
  4845.   -- some constraints may be violated with no penalty.
  4846.   begin
  4847.     return SHORT_STRUCTURE;
  4848.   end;
  4849.  
  4850.   function Case_of_Reserved_Words return Reserve_Word_Cases is
  4851.   begin
  4852.     return RESERVED_CASE;
  4853.   end;
  4854.  
  4855.   function Case_of_Object_Names return Object_Name_Cases is
  4856.   begin
  4857.     return OBJECT_CASE;
  4858.   end;
  4859.  
  4860.   function Average_Name_Size  return Word_Lengths is
  4861.   -- The average size of names in the program should be greater than
  4862.   -- this minimum.
  4863.   begin
  4864.     return NAME_LENGTH_AVE;
  4865.   end;
  4866.  
  4867.   function Is_Underscore_Required return boolean is
  4868.   begin
  4869.     return UNDERSCORE_REQUIRED;
  4870.   end;
  4871.  
  4872.   function Average_Underscore_Size return Word_Lengths is
  4873.   -- If underscores are required and the word under inspection is
  4874.   -- longer than a "Small_Word", then the parts separated by
  4875.   -- underscores should be longer than this minimum.
  4876.   begin
  4877.     return UNDERSCORE_LENGTH_AVE;
  4878.   end;
  4879.  
  4880.   function Vowel_Frequency return float is
  4881.   -- To keep people from abbreviating too much, check the percentage of
  4882.   -- vowels to consonants.  If (Vowel / Total-letters) is less than
  4883.   -- Vowel_Frequency percent, there is something wrong.
  4884.   begin
  4885.     return ABBREV_AVE;
  4886.   end;
  4887.   function SPELLING_REQUIRED return Require_Type is
  4888.   -- This function returns 'Required' if the style checker is to
  4889.   -- send words to a spelling checker to validate variable names.
  4890.   begin
  4891.     return SPELLING_REQUIREMENT;
  4892.   end;
  4893.  
  4894.   function Is_One_Statement_per_line_Required return boolean is
  4895.   begin
  4896.     return ONE_LINE_PER_STATEMENT;
  4897.   end;
  4898.   function Is_Declaration_Indentation_Required return boolean is
  4899.   -- Forced to indent properly on object, type declarations?
  4900.   begin
  4901.     return TYPE_INDENTATION;
  4902.   end;
  4903.   function Is_Comment_Indentation_Required return boolean is
  4904.   -- Forced to indent the trailing comments after statement on a line?
  4905.   begin
  4906.     return COMMENT_INDENTATION;
  4907.   end;
  4908.  
  4909.   function Is_Blank_Lines_around_Blocks_Required return boolean is
  4910.   -- Should blank lines around blocks, loops, etc. be required?
  4911.   begin
  4912.     return BLANKS_AROUND_BLOCKS;
  4913.   end;
  4914. --  I think we deleted this function!
  4915. --      function Average_Blank_Lines return float is
  4916. --      -- The average # of blank lines should be 'Ave-blank-lines' +- delta
  4917. --      -- for readability's sake
  4918. --        begin
  4919. --          return ;
  4920. --        end;
  4921.  
  4922.   function Loop_Name_Required return Loop_Names_Needs is
  4923.   -- Are loop-names necessary, should loops of a certain size need names.
  4924.   begin
  4925.     return LOOP_NAME_NEEDED;
  4926.   end;
  4927.  
  4928.   procedure Reserved_Word_Info ( Usage : out Keyword_Uses ) is
  4929.   begin
  4930.     Usage := KEYWRD_ARRAY;
  4931.   end;
  4932.  
  4933.   function Average_Comment_Size return positive is
  4934.   -- To prevent style "tricking" comments must have a minimum average
  4935.   -- size;
  4936.   begin
  4937.     return AVE_SIZE_OF_COMMENT;
  4938.   end;
  4939.  
  4940.   function Average_Literal_in_Body return float is
  4941.   -- Literals should be in the declaration rather then the body, so
  4942.   -- the number of literals in the body should be less than "ave-literal"
  4943.   begin
  4944.     return LITERAL_FREQ_IN_BODY;
  4945.   end;
  4946.  
  4947.   function Average_Universal_Usage return float is
  4948.   -- In general, good use should be made of programmer-defined types
  4949.   -- rather than universal integer, float, etc.  The percentage of
  4950.   -- types which are universal integer, float, natural, positive, etc.
  4951.   -- should be less then "ave-universals"
  4952.   begin
  4953.     return UNIVERSAL_TYPE_USAGE;
  4954.   end;
  4955.  
  4956.   function Is_Data_Structure_Use_Required return boolean is
  4957.   -- Should we check for enumeration types, records?
  4958.   begin
  4959.     return DATA_STRUCTURE_USE;
  4960.   end;
  4961.  
  4962.   function ATTRIBUTE_CHECK return Require_Type is
  4963.   -- This function tells whether the style checker notes the
  4964.   -- use of attributes.
  4965.   begin
  4966.     return ATTRIBUTE_USE;
  4967.   end;
  4968.  
  4969.   procedure Average_Subprogram_Size (SMALL_LIMIT : out Natural;
  4970.                                      LARGE_LIMIT : out Natural ) is
  4971.   begin
  4972.      SMALL_LIMIT := LOWER_SUBPROGRAM_SIZE;
  4973.      LARGE_LIMIT := UPPER_SUBPROGRAM_SIZE;
  4974.   end AVERAGE_SUBPROGRAM_SIZE;
  4975.  
  4976.   procedure SUBPROGRAM_PARAMETERS (SMALL_LIMIT : out Natural;
  4977.                                    LARGE_LIMIT : out Natural ) is
  4978.   begin
  4979.      SMALL_LIMIT := LOWER_PARAMETER_SIZE;
  4980.      LARGE_LIMIT := UPPER_PARAMETER_SIZE;
  4981.   end SUBPROGRAM_PARAMETERS;
  4982.  
  4983.  
  4984.   function CONTROL_NESTING_LEVEL return natural is
  4985.   -- This is the expected depth of nesting of control structures.
  4986.   begin
  4987.     return CONTROL_NESTING_LIMIT;
  4988.   end;
  4989.  
  4990.   function PACKAGE_NESTING_LEVEL return natural is
  4991.   -- This is the expected depth of nesting of packages.
  4992.   begin
  4993.     return PACKAGE_NESTING_LIMIT;
  4994.   end;
  4995.  
  4996.   function SUBPROGRAM_NESTING_LEVEL return natural is
  4997.   -- This is the expected depth of nesting of subprograms.
  4998.   begin
  4999.     return SUBPROGRAM_NESTING_LIMIT;
  5000.   end;
  5001.  
  5002.   function NUMBER_OF_LOOP_EXITS return natural is
  5003.   -- This number is a limit on the number of exits from a loop.
  5004.   begin
  5005.     return MAX_LOOP_EXITS;
  5006.   end;
  5007.  
  5008.   function LINE_SIZE return natural is
  5009.   -- This number is a limit on the number of characters in a line.
  5010.   begin
  5011.     return LINE_SIZE_LIMIT;
  5012.   end;
  5013.  
  5014.   function CHARACTER_SET return Character_Set_Types is
  5015.   -- This enumeration type determines the characters which are
  5016.   -- not flagged as style errors.  This is to limit use of
  5017.   -- graphic or extended characters which may not transport to
  5018.   -- other machines.
  5019.   begin
  5020.     return CHAR_SET_ALLOWED;
  5021.   end;
  5022.  
  5023.   function REPRESENTATION_SPECS_ALLOWED return boolean is
  5024.   -- This returns true if rep specs are allowed in the style.
  5025.   begin
  5026.     return REP_SPECS_PERMITTED;
  5027.   end;
  5028.  
  5029.   function ADDRESS_CLAUSE_ALLOWED return boolean is
  5030.   -- This returns true if address clauses are allowed in the style.
  5031.   begin
  5032.     return ADDR_CLAUSES_PERMITTED;
  5033.   end;
  5034.  
  5035.   function NOTE_PRAGMAS return Pragma_Classes is
  5036.   -- This is an enumeration type defining which pragmas (all, system-
  5037.   -- dependent, or none) are illegal as defined in the style
  5038.   begin
  5039.     return PRAGMAS_TO_BE_NOTED;
  5040.   end;
  5041.  
  5042.   function DYN_EQUAL(STR1 : in DYN.DYN_STRING;STR2: in DYN.DYN_STRING)
  5043.     return boolean is
  5044.   begin
  5045.     if DYN.LENGTH(STR1) = DYN.LENGTH(STR2) then
  5046.         return DYN.STR(STR1) = DYN.STR(STR2);
  5047.     else
  5048.         return false;
  5049.     end if;
  5050.   end DYN_EQUAL;
  5051.  
  5052.  
  5053.   function IS_A_PREDEFINED_PRAGMA (NAME : in DYN.DYN_STRING ) return boolean is
  5054.   -- This returns true if the input name is a predefined pragma as listed
  5055.   -- in the LRM appendix B.
  5056.     PRAGMA_PREDEFINED : constant array (1..14) of DYN.DYN_STRING :=
  5057.         (DYN.D_STRING("CONTROLLED"),
  5058.         DYN.D_STRING("ELABORATE"),
  5059.         DYN.D_STRING("INLINE"),
  5060.         DYN.D_STRING("INTERFACE"),
  5061.         DYN.D_STRING("LIST"),
  5062.         DYN.D_STRING("MEMORY_SIZE"),
  5063.         DYN.D_STRING("OPTIMIZE"),
  5064.         DYN.D_STRING("PACK"),
  5065.         DYN.D_STRING("PAGE"),
  5066.         DYN.D_STRING("PRIORITY"),
  5067.         DYN.D_STRING("SHARED"),
  5068.         DYN.D_STRING("STORAGE_UNIT"),
  5069.         DYN.D_STRING("SUPPRESS"),
  5070.         DYN.D_STRING("SYSTEM_NAME") );
  5071.  
  5072.     begin
  5073.        for I in PRAGMA_PREDEFINED'FIRST..PRAGMA_PREDEFINED'LAST loop
  5074.            if DYN_EQUAL( NAME, PRAGMA_PREDEFINED(I)) then
  5075.                return true;
  5076.            end if;
  5077.        end loop;
  5078.        return false;
  5079.     end IS_A_PREDEFINED_PRAGMA;
  5080.  
  5081.  
  5082.   function IS_A_PROSCRIBED_PACKAGE (NAME : in DYN.DYN_STRING) return boolean is
  5083.   -- This returns true if the input name is a package on the
  5084.   -- list of 'stylistically incorrect' packages as defined by the style.
  5085.  
  5086.     begin
  5087.        for I in PROSCRIBED'FIRST..PROSCRIBED'LAST loop
  5088.            if DYN_EQUAL(NAME, PROSCRIBED(I) ) then
  5089.                return true;
  5090.            end if;
  5091.        end loop;
  5092.        return false;
  5093.   end IS_A_PROSCRIBED_PACKAGE;
  5094.  
  5095.  
  5096. begin
  5097.     Set_Style_Parameters;
  5098.  
  5099.  
  5100. end Style_Parameters;
  5101. ::::::::::
  5102. repgenbod.ada
  5103. ::::::::::
  5104. with CURRENT_EXCEPTION;
  5105. package body REPORT_GENERATOR is
  5106. --------------------------------------------------------------------------
  5107. -- Abstract   : This is the package body for all the report routines.
  5108. --------------------------------------------------------------------------
  5109.  
  5110.     ERROR_OCCURRENCE_COUNT : array (ERRORS) of NATURAL :=
  5111.                              (ERRORS'FIRST .. ERRORS'LAST => 0);
  5112.  
  5113.     ADA_SPECIFICS_USED     : BOOLEAN := FALSE;
  5114.  
  5115.     procedure PUT_FLAW(TO_THIS : in TEXT_IO.FILE_TYPE;
  5116.                        BAD_TOKEN : in TOKENIZER.TOKEN;
  5117.                        ERROR_MESSAGE : in DYN.DYN_STRING;
  5118.                        ERROR_TYPE : in ERRORS := OTHER) is
  5119. --------------------------------------------------------------------------
  5120. -- Abstract   : This routine adds a flaw to the flaws listing file.
  5121. --------------------------------------------------------------------------
  5122. -- Parameters : TO_THIS         - File of Flaws list
  5123. --              BAD_TOKEN       - Token that points out the flaw
  5124. --              ERROR_MESSAGE   - The error message
  5125. --              ERROR_TYPE      - The type of the error
  5126. --------------------------------------------------------------------------
  5127.  
  5128.  
  5129.         BAD_LINE : DYN.DYN_STRING;
  5130.  
  5131.     begin
  5132.         ERROR_OCCURRENCE_COUNT(ERROR_TYPE) :=
  5133.             ERROR_OCCURRENCE_COUNT(ERROR_TYPE) + 1;
  5134.         if (ERROR_OCCURRENCE_COUNT(ERROR_TYPE) <=
  5135.             STYLE_PARAMETERS.NUMBER_OF_ERRORS_TO_REPORT) or
  5136.            (ERROR_TYPE > NON_STANDARD_PRAGMA_USED) then
  5137.             TOKENIZER.LINE_CONTAINING_TOKEN(BAD_TOKEN,BAD_LINE);
  5138.             TEXT_IO.PUT_LINE(TO_THIS,DYN.STR(BAD_LINE));
  5139.             TEXT_IO.PUT_LINE(TO_THIS,DYN.STR(ERROR_MESSAGE));
  5140.             TEXT_IO.NEW_LINE(TO_THIS);
  5141.         end if;
  5142.     end PUT_FLAW;
  5143.  
  5144.     procedure PUT_FLAW(TO_THIS : in TEXT_IO.FILE_TYPE;
  5145.                        BAD_TOKEN : in TOKENIZER.TOKEN;
  5146.                        ERROR_MESSAGE : in STRING;
  5147.                        ERROR_TYPE : in ERRORS := OTHER) is
  5148. --------------------------------------------------------------------------
  5149. -- Abstract   : This routine adds a flaw to the flaws listing file.
  5150. --------------------------------------------------------------------------
  5151. -- Parameters : TO_THIS         - File of Flaws list
  5152. --              BAD_TOKEN       - Token that points out the flaw
  5153. --              ERROR_MESSAGE   - The error message
  5154. --              ERROR_TYPE      - The type of the error
  5155. --------------------------------------------------------------------------
  5156.  
  5157.         BAD_LINE : DYN.DYN_STRING;
  5158.  
  5159.     begin
  5160.         ERROR_OCCURRENCE_COUNT(ERROR_TYPE) :=
  5161.             ERROR_OCCURRENCE_COUNT(ERROR_TYPE) + 1;
  5162.         if (ERROR_OCCURRENCE_COUNT(ERROR_TYPE) <=
  5163.             STYLE_PARAMETERS.NUMBER_OF_ERRORS_TO_REPORT) or
  5164.            (ERROR_TYPE > NON_STANDARD_PRAGMA_USED) then
  5165.             TOKENIZER.LINE_CONTAINING_TOKEN(BAD_TOKEN,BAD_LINE);
  5166.             TEXT_IO.PUT_LINE(TO_THIS,DYN.STR(BAD_LINE));
  5167.             TEXT_IO.PUT_LINE(TO_THIS,ERROR_MESSAGE);
  5168.             TEXT_IO.NEW_LINE(TO_THIS);
  5169.         end if;
  5170.     end PUT_FLAW;
  5171.  
  5172.     procedure GENERATE_REPORT(FROM_THIS : in REPORT_RECORD;
  5173.                               TO_THIS : in TEXT_IO.FILE_TYPE;
  5174.                               FILE_NAME : in DYN.DYN_STRING ) is
  5175.  
  5176. --------------------------------------------------------------------------
  5177. -- Abstract   : This routine generates the final error report for the
  5178. --              Style_Checker.
  5179. --------------------------------------------------------------------------
  5180. -- Parameters : FROM_THIS       - Record of errors
  5181. --              TO_THIS         - Output file
  5182. --              FILE_NAME       - Name of input file
  5183. --------------------------------------------------------------------------
  5184.     use STYLE_PARAMETERS;
  5185.  
  5186.         package NATURAL_IO is new TEXT_IO.INTEGER_IO(NATURAL);
  5187.         package MY_FLOAT_IO is new TEXT_IO.FLOAT_IO(FLOAT);
  5188.  
  5189.         -- Column constants
  5190.         DECIMAL_POINT_COLUMN    : constant NATURAL := 58;
  5191.         ERROR_FLAG_COLUMN       : constant NATURAL := 3;
  5192.         FIRST_COLUMN_START      : constant NATURAL := 7;
  5193.         SECOND_COLUMN_START     : constant NATURAL := 44;
  5194.         THIRD_COLUMN_START      : constant NATURAL := 64;
  5195.  
  5196.  
  5197.  
  5198.         -- String constants used again and again
  5199.         ACTUAL          : constant STRING := "Actual";
  5200.         ASTERIK         : constant STRING := "*";
  5201.         CHARACTERS      : constant STRING := "Characters";
  5202.         COMMENTS        : constant STRING := "Comments";
  5203.         DESIRED         : constant STRING := "Desired";
  5204.         DOT_DOT         : constant STRING := "..";
  5205.         ERRORS          : constant STRING := "Errors";
  5206.         EXCEEDED        : constant STRING := "Exceeded";
  5207.         EXCLAMATION     : constant STRING := "!";
  5208.         GREATER_THAN    : constant CHARACTER := '>';
  5209.         HEADER_LINE     : constant STRING(1 .. 74) := (1 .. 74 => '-');
  5210.         INSTANCES       : constant STRING := "Instances";
  5211.         LESS_THAN       : constant CHARACTER := '<';
  5212.         MAXIMUM         : constant STRING := "Maximum";
  5213.         PARAMETERS      : constant STRING := "Parameters";
  5214.         PERCENT         : constant STRING := "%";
  5215.         STATEMENTS      : constant STRING := "Statements";
  5216.  
  5217.         ASCII_IMAGE     : STRING(1..5);
  5218.         COLUMN          : POSITIVE;
  5219.         KEYWORD_COUNT   : NATURAL := 0;
  5220.         type KEYWORD_PERCENTAGE_ARRAY is array(TOKENIZER.TOKEN_TYPE) of FLOAT;
  5221.         KEYWORD_PERCENTAGES     : KEYWORD_PERCENTAGE_ARRAY :=
  5222.             (TOKENIZER.TOKEN_TYPE'FIRST .. TOKENIZER.TOKEN_TYPE'LAST => 0.0);
  5223.  
  5224.     procedure PUT_REPORT_LINE(INDENTION         : in NATURAL;
  5225.                               HEADER            : in STRING;
  5226.                               ASTERIK_NEEDED    : in BOOLEAN := FALSE;
  5227.                               EXCLAMATION_NEEDED: in BOOLEAN := FALSE) is
  5228.  
  5229.     begin
  5230.         if ASTERIK_NEEDED then
  5231.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5232.             TEXT_IO.PUT(TO_THIS,ASTERIK);
  5233.         elsif EXCLAMATION_NEEDED then
  5234.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5235.             TEXT_IO.PUT(TO_THIS,EXCLAMATION);
  5236.         end if;
  5237.         if INDENTION > 0 then
  5238.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(INDENTION));
  5239.         end if;
  5240.         TEXT_IO.PUT_LINE(TO_THIS,HEADER);
  5241.     exception
  5242.         when others =>
  5243.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5244.             TEXT_IO.PUT_LINE(" in PUT_REPORT_LINE(for HEADER)");
  5245.             raise;
  5246.     end PUT_REPORT_LINE;
  5247.  
  5248.     procedure PUT_REPORT_LINE(INDENTION         : in NATURAL;
  5249.                               STYLE_ISSUE       : in STRING;
  5250.                               SUB_HEADING       : in STRING;
  5251.                               LEAD_IN           : in CHARACTER;
  5252.                               COUNT             : in NATURAL;
  5253.                               UNITS             : in STRING;
  5254.                               ASTERIK_NEEDED    : in BOOLEAN := FALSE;
  5255.                               EXCLAMATION_NEEDED: in BOOLEAN := FALSE) is
  5256.  
  5257.         COLUMN          : POSITIVE;
  5258.  
  5259.     begin
  5260.         if ASTERIK_NEEDED then
  5261.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5262.             TEXT_IO.PUT(TO_THIS,ASTERIK);
  5263.         elsif EXCLAMATION_NEEDED then
  5264.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5265.             TEXT_IO.PUT(TO_THIS,EXCLAMATION);
  5266.         end if;
  5267.         if INDENTION > 0 then
  5268.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(INDENTION));
  5269.         end if;
  5270.         TEXT_IO.PUT(TO_THIS,STYLE_ISSUE);
  5271.         if SUB_HEADING /= "" then
  5272.             TEXT_IO.SET_COL(TO_THIS,
  5273.                 TEXT_IO.POSITIVE_COUNT(SECOND_COLUMN_START));
  5274.             TEXT_IO.PUT(TO_THIS,SUB_HEADING);
  5275.         end if;
  5276.         if (COUNT < 10) then
  5277.             COLUMN := DECIMAL_POINT_COLUMN - 2;
  5278.         elsif (COUNT < 100)
  5279.             then COLUMN := DECIMAL_POINT_COLUMN - 3;
  5280.         elsif (COUNT < 1000)
  5281.             then COLUMN := DECIMAL_POINT_COLUMN - 4;
  5282.         else COLUMN := DECIMAL_POINT_COLUMN - 5;
  5283.         end if;
  5284.         TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(COLUMN));
  5285.         TEXT_IO.PUT(TO_THIS,LEAD_IN);
  5286.         NATURAL_IO.PUT(TO_THIS,COUNT,0);
  5287.         TEXT_IO.SET_COL(TO_THIS,
  5288.             TEXT_IO.POSITIVE_COUNT(THIRD_COLUMN_START));
  5289.         if (COUNT = 1) and (UNITS /= "") then
  5290.             TEXT_IO.PUT_LINE(TO_THIS,UNITS(1..UNITS'LENGTH - 1));
  5291.         else
  5292.             TEXT_IO.PUT_LINE(TO_THIS,UNITS);
  5293.         end if;
  5294.     exception
  5295.         when others =>
  5296.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5297.             TEXT_IO.PUT_LINE(" in PUT_REPORT_LINE(for INTEGER)");
  5298.             raise;
  5299.     end PUT_REPORT_LINE;
  5300.  
  5301.     procedure PUT_REPORT_LINE(INDENTION         : in NATURAL;
  5302.                               STYLE_ISSUE       : in STRING;
  5303.                               SUB_HEADING       : in STRING;
  5304.                               LEAD_IN           : in CHARACTER;
  5305.                               COUNT             : in FLOAT;
  5306.                               UNITS             : in STRING;
  5307.                               ASTERIK_NEEDED    : in BOOLEAN := FALSE;
  5308.                               EXCLAMATION_NEEDED: in BOOLEAN := FALSE) is
  5309.  
  5310.         COLUMN          : POSITIVE;
  5311.  
  5312.     begin
  5313.         if ASTERIK_NEEDED then
  5314.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5315.             TEXT_IO.PUT(TO_THIS,ASTERIK);
  5316.         elsif EXCLAMATION_NEEDED then
  5317.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5318.             TEXT_IO.PUT(TO_THIS,EXCLAMATION);
  5319.         end if;
  5320.         if INDENTION > 0 then
  5321.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(INDENTION));
  5322.         end if;
  5323.         TEXT_IO.PUT(TO_THIS,STYLE_ISSUE);
  5324.         if SUB_HEADING /= "" then
  5325.             TEXT_IO.SET_COL(TO_THIS,
  5326.                 TEXT_IO.POSITIVE_COUNT(SECOND_COLUMN_START));
  5327.             TEXT_IO.PUT(TO_THIS,SUB_HEADING);
  5328.         end if;
  5329.         TEXT_IO.SET_COL(TO_THIS,
  5330.                 TEXT_IO.POSITIVE_COUNT(DECIMAL_POINT_COLUMN - 4));
  5331.         TEXT_IO.PUT(TO_THIS,LEAD_IN);
  5332.         if UNITS /= PERCENT then
  5333.             -- if COUNT is too small then FLOAT_IO raises CONSTRAINT_ERROR
  5334.             if COUNT < 0.1 then
  5335.                 MY_FLOAT_IO.PUT(TO_THIS,0.0,FORE => 3, AFT => 1, EXP => 0);
  5336.                 TEXT_IO.SET_COL(TO_THIS,
  5337.                                 TEXT_IO.POSITIVE_COUNT(THIRD_COLUMN_START));
  5338.             else
  5339.                 MY_FLOAT_IO.PUT(TO_THIS,COUNT,FORE => 3, AFT => 1, EXP => 0);
  5340.                 TEXT_IO.SET_COL(TO_THIS,
  5341.                                 TEXT_IO.POSITIVE_COUNT(THIRD_COLUMN_START));
  5342.             end if;
  5343.         else
  5344.             -- if COUNT is too small then FLOAT_IO raises CONSTRAINT_ERROR
  5345.             if COUNT < 0.001 then
  5346.                 MY_FLOAT_IO.PUT(TO_THIS,0.0,FORE => 3, AFT => 1, EXP => 0);
  5347.             else
  5348.                 MY_FLOAT_IO.PUT(TO_THIS,(COUNT*100.0),
  5349.                                 FORE => 3,AFT => 1,EXP => 0);
  5350.             end if;
  5351.         end if;
  5352.         TEXT_IO.PUT_LINE(TO_THIS,UNITS);
  5353.     exception
  5354.         when others =>
  5355.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5356.             TEXT_IO.PUT_LINE(" in PUT_REPORT_LINE(for FLOAT)");
  5357.             raise;
  5358.     end PUT_REPORT_LINE;
  5359.  
  5360.     procedure PUT_REPORT_LINE(INDENTION         : in NATURAL;
  5361.                               STYLE_ISSUE       : in STRING;
  5362.                               SUB_HEADING       : in STRING;
  5363.                               LOWER_BOUND       : in NATURAL;
  5364.                               UPPER_BOUND       : in NATURAL;
  5365.                               UNITS             : in STRING;
  5366.                               ASTERIK_NEEDED    : in BOOLEAN := FALSE;
  5367.                               EXCLAMATION_NEEDED: in BOOLEAN := FALSE) is
  5368.  
  5369.         COLUMN          : POSITIVE;
  5370.  
  5371.     begin
  5372.         if ASTERIK_NEEDED then
  5373.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5374.             TEXT_IO.PUT(TO_THIS,ASTERIK);
  5375.         elsif EXCLAMATION_NEEDED then
  5376.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5377.             TEXT_IO.PUT(TO_THIS,EXCLAMATION);
  5378.         end if;
  5379.         if INDENTION > 0 then
  5380.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(INDENTION));
  5381.         end if;
  5382.         TEXT_IO.PUT(TO_THIS,STYLE_ISSUE);
  5383.         if SUB_HEADING /= "" then
  5384.             TEXT_IO.SET_COL(TO_THIS,
  5385.                 TEXT_IO.POSITIVE_COUNT(SECOND_COLUMN_START));
  5386.             TEXT_IO.PUT(TO_THIS,SUB_HEADING);
  5387.         end if;
  5388.         if (LOWER_BOUND < 10) then
  5389.             COLUMN := DECIMAL_POINT_COLUMN - 1;
  5390.         elsif (LOWER_BOUND < 100)
  5391.             then COLUMN := DECIMAL_POINT_COLUMN - 2;
  5392.         elsif (LOWER_BOUND < 1000)
  5393.             then COLUMN := DECIMAL_POINT_COLUMN - 3;
  5394.         else COLUMN := DECIMAL_POINT_COLUMN - 4;
  5395.         end if;
  5396.         if (UPPER_BOUND < 10) then
  5397.             COLUMN := COLUMN - 1;
  5398.         elsif (UPPER_BOUND < 100)
  5399.             then COLUMN := COLUMN - 2;
  5400.         elsif (UPPER_BOUND < 1000)
  5401.             then COLUMN := COLUMN - 3;
  5402.         else COLUMN := COLUMN - 4;
  5403.         end if;
  5404.         COLUMN := COLUMN - 2;
  5405.         TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(COLUMN));
  5406.         NATURAL_IO.PUT(TO_THIS,LOWER_BOUND,0);
  5407.         TEXT_IO.PUT(TO_THIS,DOT_DOT);
  5408.         NATURAL_IO.PUT(TO_THIS,UPPER_BOUND,0);
  5409.         TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(THIRD_COLUMN_START));
  5410.         TEXT_IO.PUT_LINE(TO_THIS,UNITS);
  5411.     exception
  5412.         when others =>
  5413.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5414.             TEXT_IO.PUT_LINE(" in PUT_REPORT_LINE(for RANGES)");
  5415.             raise;
  5416.     end PUT_REPORT_LINE;
  5417.  
  5418.     procedure PUT_REPORT_LINE(
  5419.                 KEYWORD_REPORT  : in STYLE_PARAMETERS.KEYWORD_USE_DESCRIPT;
  5420.                 KEYWORD_COUNT   : in NATURAL;
  5421.                 KEYWORD_USAGE   : in FLOAT;
  5422.                 KEYWORD_TYPE    : in TOKENIZER.TOKEN_TYPE) is
  5423.  
  5424.     use STYLE_PARAMETERS;
  5425.         package TOKEN_TYPE_IO is new
  5426.                 TEXT_IO.ENUMERATION_IO(TOKENIZER.TOKEN_TYPE);
  5427.         TOKEN_STRING    : STRING(1..20);
  5428.         UNDERSCORE_COLUMN : NATURAL := 1;
  5429.  
  5430.     begin
  5431.         if (KEYWORD_REPORT.USE_CLASS /= FREE_USE) and
  5432.            (KEYWORD_USAGE > KEYWORD_REPORT.USE_FREQ) then
  5433.             TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(ERROR_FLAG_COLUMN));
  5434.             TEXT_IO.PUT(TO_THIS,ASTERIK);
  5435.         end if;
  5436.         TEXT_IO.SET_COL(TO_THIS,TEXT_IO.POSITIVE_COUNT(FIRST_COLUMN_START));
  5437.         TOKEN_TYPE_IO.PUT(TOKEN_STRING,KEYWORD_TYPE);
  5438.         while TOKEN_STRING(UNDERSCORE_COLUMN) /= '_' loop
  5439.             UNDERSCORE_COLUMN := UNDERSCORE_COLUMN + 1;
  5440.         end loop;
  5441.         TEXT_IO.PUT(TO_THIS,TOKEN_STRING(1..UNDERSCORE_COLUMN - 1));
  5442.         TEXT_IO.SET_COL(TO_THIS,17);
  5443.         if KEYWORD_REPORT.USE_CLASS = NO_USE then
  5444.             TEXT_IO.PUT(TO_THIS," no");
  5445.         else
  5446.             TEXT_IO.PUT(TO_THIS,"yes");
  5447.         end if;
  5448.         TEXT_IO.SET_COL(TO_THIS,31);
  5449.         -- if number is too small then FLOAT_IO raises CONSTRAINT_ERROR
  5450.         if KEYWORD_REPORT.USE_FREQ < 0.001 then
  5451.             MY_FLOAT_IO.PUT(TO_THIS,0.0,FORE => 3, AFT => 1, EXP => 0);
  5452.         else
  5453.             MY_FLOAT_IO.PUT(TO_THIS,(KEYWORD_REPORT.USE_FREQ * 100.0),
  5454.                 FORE => 3, AFT => 1, EXP => 0);
  5455.         end if;
  5456.         TEXT_IO.PUT(TO_THIS,PERCENT);
  5457.  
  5458.         TEXT_IO.SET_COL(TO_THIS,47);
  5459.         NATURAL_IO.PUT(TO_THIS,KEYWORD_COUNT,3);
  5460.  
  5461.         TEXT_IO.SET_COL(TO_THIS,63);
  5462.  
  5463.         -- if number is too small then FLOAT_IO raises CONSTRAINT_ERROR
  5464.         if KEYWORD_USAGE < 0.001 then
  5465.             MY_FLOAT_IO.PUT(TO_THIS,0.0,FORE => 3, AFT => 1, EXP => 0);
  5466.         else
  5467.             MY_FLOAT_IO.PUT(TO_THIS,(KEYWORD_USAGE * 100.0),
  5468.                 FORE => 3, AFT => 1, EXP => 0);
  5469.         end if;
  5470.         TEXT_IO.PUT_LINE(TO_THIS,PERCENT);
  5471.     exception
  5472.         when others =>
  5473.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5474.             TEXT_IO.PUT_LINE(" in PUT_REPORT_LINE(for KEYWORDS)");
  5475.             raise;
  5476.     end PUT_REPORT_LINE;
  5477.  
  5478.  
  5479.     procedure PRINT_LIST ( LIST : in STRING_LIST_TYPE ) is
  5480.     NODE : STRING_LIST_TYPE;
  5481.     begin
  5482.         NODE := LIST;
  5483.         while NODE /= null loop
  5484.            PUT_REPORT_LINE( SECOND_COLUMN_START, DYN.STR(NODE.NAME) );
  5485.            NODE := NODE.NEXT;
  5486.         end loop;
  5487.     end PRINT_LIST;
  5488.  
  5489.  
  5490.     begin
  5491.  
  5492.         PUT_REPORT_LINE(0,"STYLE Report");
  5493.         PUT_REPORT_LINE(0,DYN.STR(FILE_NAME));
  5494.         PUT_REPORT_LINE(0,"");
  5495.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5496.                              "Naming Conventions");
  5497.         PUT_REPORT_LINE(0,HEADER_LINE);
  5498.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5499.                 "Invalid Case for an Object Identifier","",' ',
  5500.                 FROM_THIS.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER,ERRORS,
  5501.                 FROM_THIS.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER /= 0);
  5502.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Invalid Case for a Keyword",
  5503.                 "",' ',FROM_THIS.INVALID_CASE_FOR_A_KEYWORD,ERRORS,
  5504.                 FROM_THIS.INVALID_CASE_FOR_A_KEYWORD /= 0);
  5505.         if FROM_THIS.ABBREVIATIONS then
  5506.             PUT_REPORT_LINE(FIRST_COLUMN_START,"Too many abbreviations",
  5507.                             TRUE,FALSE);
  5508.         end if;
  5509.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5510.                 "Name Segment Size (Separated",DESIRED,LESS_THAN,
  5511.                 FROM_THIS.NAME_SEGMENT_SIZE_DESIRED_MAXIMUM,CHARACTERS);
  5512.         PUT_REPORT_LINE(19,"by Underscores)",ACTUAL,' ',
  5513.                 FROM_THIS.NAME_SEGMENT_SIZE_ACTUAL,CHARACTERS,
  5514.                 FROM_THIS.NAME_SEGMENT_SIZE_ACTUAL >
  5515.                 FLOAT(FROM_THIS.NAME_SEGMENT_SIZE_DESIRED_MAXIMUM));
  5516.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Average Name Size",
  5517.                 DESIRED,GREATER_THAN,
  5518.                 FROM_THIS.AVERAGE_NAME_SIZE_DESIRED_MINIMUM,CHARACTERS);
  5519.         PUT_REPORT_LINE(0,"",ACTUAL,' ',FROM_THIS.AVERAGE_NAME_SIZE_ACTUAL,
  5520.                 CHARACTERS,FROM_THIS.AVERAGE_NAME_SIZE_ACTUAL <
  5521.                 FLOAT(FROM_THIS.AVERAGE_NAME_SIZE_DESIRED_MINIMUM));
  5522.  
  5523.         PUT_REPORT_LINE(0,HEADER_LINE);
  5524.         PUT_REPORT_LINE(0,"");
  5525.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Physical Layout");
  5526.         PUT_REPORT_LINE(0,HEADER_LINE);
  5527.  
  5528.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5529.                 "Occurrences of More Than One Statement/Line","",' ',
  5530.                 FROM_THIS.OCCURRENCES_OF_MORE_THAN_ONE_STATEMENT_PER_LINE,
  5531.                 ERRORS,
  5532.                 FROM_THIS.OCCURRENCES_OF_MORE_THAN_ONE_STATEMENT_PER_LINE > 0);
  5533.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Inconsistant Indentation","",' ',
  5534.                 FROM_THIS.INCONSISTANT_INDENTATION,ERRORS,
  5535.                 FROM_THIS.INCONSISTANT_INDENTATION > 0);
  5536.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5537.                 "Missing Blank Lines to Set Off a Block","",' ',
  5538.                 FROM_THIS.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK,ERRORS,
  5539.                 FROM_THIS.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK > 0);
  5540. -- Don't look for prologs!
  5541. --      PUT_REPORT_LINE(FIRST_COLUMN_START,
  5542. --              "Missing Prolog","",' ',FROM_THIS.MISSING_PROLOG,
  5543. --              ERRORS,FROM_THIS.MISSING_PROLOG > 0);
  5544.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Loops Without Names","",' ',
  5545.                 FROM_THIS.LOOPS_WITHOUT_NAMES,"",
  5546.                 FROM_THIS.LOOPS_WITHOUT_NAMES > 0);
  5547. -- Don't care about blank lines
  5548. --      PUT_REPORT_LINE(FIRST_COLUMN_START,"Percent of Blank Lines",
  5549. --              DESIRED,GREATER_THAN,
  5550. --              FROM_THIS.PERCENT_OF_BLANK_LINES_DESIRED_MINIMUM,PERCENT);
  5551. --      PUT_REPORT_LINE(0,"",ACTUAL,' ',FROM_THIS.PERCENT_OF_BLANK_LINES_ACTUAL,
  5552. --              PERCENT,FROM_THIS.PERCENT_OF_BLANK_LINES_ACTUAL <
  5553. --              FROM_THIS.PERCENT_OF_BLANK_LINES_DESIRED_MINIMUM);
  5554.  
  5555.         PUT_REPORT_LINE(0,HEADER_LINE);
  5556.         PUT_REPORT_LINE(0,"");
  5557.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5558.                 "Information Hiding, Abstraction, Data Use");
  5559.         PUT_REPORT_LINE(0,HEADER_LINE);
  5560.  
  5561.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5562.                 "Percent of Literals In Body ",DESIRED,LESS_THAN,
  5563.                 FROM_THIS.PERCENT_OF_LITERALS_IN_BODY_DESIRED_MAXIMUM,PERCENT);
  5564.         PUT_REPORT_LINE(0,"",ACTUAL,' ',
  5565.                 FROM_THIS.PERCENT_OF_LITERALS_IN_BODY_ACTUAL,PERCENT,
  5566.                 FROM_THIS.PERCENT_OF_LITERALS_IN_BODY_ACTUAL >
  5567.                 FROM_THIS.PERCENT_OF_LITERALS_IN_BODY_DESIRED_MAXIMUM);
  5568.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5569.                 "Percent of Universal Types",DESIRED,LESS_THAN,
  5570.                 FROM_THIS.PERCENT_OF_UNIVERSAL_TYPES_DESIRED_MAXIMUM,PERCENT);
  5571.         PUT_REPORT_LINE(0,"",ACTUAL,' ',
  5572.                 FROM_THIS.PERCENT_OF_UNIVERSAL_TYPES_ACTUAL,PERCENT,
  5573.                 FROM_THIS.PERCENT_OF_UNIVERSAL_TYPES_ACTUAL >
  5574.                 FROM_THIS.PERCENT_OF_UNIVERSAL_TYPES_DESIRED_MAXIMUM);
  5575.         if FROM_THIS.DATA_STRUCTURING_TYPES_NOT_USED /=
  5576.                 (DATA_STRUCTURE_TYPES'FIRST .. DATA_STRUCTURE_TYPES'LAST =>
  5577.                  FALSE) then
  5578.             PUT_REPORT_LINE(FIRST_COLUMN_START,
  5579.                 "Data Structuring Types NOT Used",FALSE,TRUE);
  5580.             for DATA_TYPES in DATA_STRUCTURE_TYPES loop
  5581.                 if FROM_THIS.DATA_STRUCTURING_TYPES_NOT_USED(DATA_TYPES) then
  5582.                     case DATA_TYPES is
  5583.                         when ARRAY_TYPES =>
  5584.                             PUT_REPORT_LINE(SECOND_COLUMN_START,"Array Types");
  5585.                         when ENUMERATION_TYPES =>
  5586.                             PUT_REPORT_LINE(SECOND_COLUMN_START,
  5587.                                 "Enumeration Types");
  5588.                         when RECORD_TYPES =>
  5589.                             PUT_REPORT_LINE(SECOND_COLUMN_START,"Record Types");
  5590.                     end case;
  5591.                 end if;
  5592.             end loop;
  5593.         end if;
  5594.         if not FROM_THIS.ATTRIBUTES_USED then
  5595.             PUT_REPORT_LINE(FIRST_COLUMN_START,"No Attributes are Used",
  5596.                 FALSE,TRUE);
  5597.         end if;
  5598.  
  5599.         ADA_SPECIFICS_USED :=      FROM_THIS.AND_THENS_USED and
  5600.             FROM_THIS.OR_ELSES_USED and FROM_THIS.EXITS_USED and
  5601.             FROM_THIS.XORS_USED     and FROM_THIS.ELSIFS_USED and
  5602.             FROM_THIS.EXCEPTIONS_USED and FROM_THIS.INS_USED  and
  5603.             FROM_THIS.OUTS_USED     and FROM_THIS.IN_OUTS_USED and
  5604.             FROM_THIS.PRIVATES_USED;
  5605.         if NOT ADA_SPECIFICS_USED then
  5606.             PUT_REPORT_LINE( FIRST_COLUMN_START,
  5607.                 "Ada-Specific Features NOT used", FALSE, TRUE);
  5608.             if not FROM_THIS.AND_THENS_USED then
  5609.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"AND THEN");
  5610.             end if;
  5611.             if not FROM_THIS.OR_ELSES_USED then
  5612.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"OR ELSE");
  5613.             end if;
  5614.             if not FROM_THIS.EXITS_USED then
  5615.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"EXITS");
  5616.             end if;
  5617.             if not FROM_THIS.XORS_USED then
  5618.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"XOR");
  5619.             end if;
  5620.             if not FROM_THIS.ELSIFS_USED then
  5621.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"ELSIF");
  5622.             end if;
  5623.             if not FROM_THIS.EXCEPTIONS_USED then
  5624.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"EXCEPTION");
  5625.             end if;
  5626.             if not FROM_THIS.INS_USED then
  5627.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"IN parameters");
  5628.             end if;
  5629.             if not FROM_THIS.OUTS_USED then
  5630.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"OUT parameters");
  5631.             end if;
  5632.             if not FROM_THIS.IN_OUTS_USED then
  5633.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"IN OUT parameters");
  5634.             end if;
  5635.             if not FROM_THIS.PRIVATES_USED then
  5636.                 PUT_REPORT_LINE(SECOND_COLUMN_START,"PRIVATEs");
  5637.             end if;
  5638.         end if;
  5639.  
  5640.  
  5641.         PUT_REPORT_LINE(0,HEADER_LINE);
  5642.         PUT_REPORT_LINE(0,"");
  5643.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Modularity");
  5644.         PUT_REPORT_LINE(0,HEADER_LINE);
  5645.  
  5646.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Average Number of Parameters",
  5647.                 "Range",FROM_THIS.AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MINIMUM,
  5648.                 FROM_THIS.AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MAXIMUM,
  5649.                 PARAMETERS);
  5650.         PUT_REPORT_LINE(FIRST_COLUMN_START + 2,
  5651.                 "Instances of parameters below minimum","",' ',
  5652.                 FROM_THIS.INSTANCES_OF_PARAMETERS_BELOW_MINIMUM,"",
  5653.                 FROM_THIS.INSTANCES_OF_PARAMETERS_BELOW_MINIMUM > 0);
  5654.         PUT_REPORT_LINE(FIRST_COLUMN_START + 2,
  5655.                 "Instances of parameters above maximum","",' ',
  5656.                 FROM_THIS.INSTANCES_OF_PARAMETERS_ABOVE_MAXIMUM,"",
  5657.                 FROM_THIS.INSTANCES_OF_PARAMETERS_ABOVE_MAXIMUM > 0);
  5658.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Average Subprogram Size","Range",
  5659.                 FROM_THIS.AVERAGE_SUBPROGRAM_SIZE_DESIRED_MINIMUM,
  5660.                 FROM_THIS.AVERAGE_SUBPROGRAM_SIZE_DESIRED_MAXIMUM,
  5661.                 STATEMENTS);
  5662.         PUT_REPORT_LINE(FIRST_COLUMN_START + 2,
  5663.                 "Instances of size below minimum","",' ',
  5664.                 FROM_THIS.INSTANCES_OF_SIZE_BELOW_MINIMUM,"",
  5665.                 FROM_THIS.INSTANCES_OF_SIZE_BELOW_MINIMUM > 0);
  5666.         PUT_REPORT_LINE(FIRST_COLUMN_START +2,
  5667.                 "Instances of size above maximum","",' ',
  5668.                 FROM_THIS.INSTANCES_OF_SIZE_ABOVE_MAXIMUM,"",
  5669.                 FROM_THIS.INSTANCES_OF_SIZE_ABOVE_MAXIMUM > 0);
  5670.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5671.                 "Loops with too many exit statements","",' ',
  5672.                 FROM_THIS.INSTANCES_OF_TOO_MANY_EXITS,INSTANCES,
  5673.                 FROM_THIS.INSTANCES_OF_TOO_MANY_EXITS > 0);
  5674.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Control Structure Nesting",MAXIMUM,
  5675.                 ' ',FROM_THIS.CONTROL_STRUCTURE_NESTING_DESIRED_MAXIMUM,"");
  5676.         PUT_REPORT_LINE(0,"",EXCEEDED,' ',
  5677.                 FROM_THIS.CONTROL_STRUCTURE_NESTING_EXCEEDING_MAXIMUM,
  5678.                 INSTANCES,
  5679.                 FROM_THIS.CONTROL_STRUCTURE_NESTING_EXCEEDING_MAXIMUM > 0);
  5680.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Package Nesting",MAXIMUM,' ',
  5681.                 FROM_THIS.PACKAGE_NESTING_DESIRED_MAXIMUM,"");
  5682.         PUT_REPORT_LINE(0,"",EXCEEDED,' ',
  5683.                 FROM_THIS.PACKAGE_NESTING_EXCEEDING_MAXIMUM,INSTANCES,
  5684.                 FROM_THIS.PACKAGE_NESTING_EXCEEDING_MAXIMUM > 0);
  5685.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Subprogram Nesting",MAXIMUM,' ',
  5686.                 FROM_THIS.SUBPROGRAM_NESTING_DESIRED_MAXIMUM,"");
  5687.         PUT_REPORT_LINE(0,"",EXCEEDED,' ',
  5688.                 FROM_THIS.SUBPROGRAM_NESTING_EXCEEDING_MAXIMUM,INSTANCES,
  5689.                 FROM_THIS.SUBPROGRAM_NESTING_EXCEEDING_MAXIMUM > 0);
  5690.  
  5691.         PUT_REPORT_LINE(0,HEADER_LINE);
  5692.         PUT_REPORT_LINE(0,"");
  5693.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Comment Usage");
  5694.         PUT_REPORT_LINE(0,HEADER_LINE);
  5695.  
  5696.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Number of Comments","",' ',
  5697.                 FROM_THIS.NUMBER_OF_COMMENTS,COMMENTS);
  5698.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Average Comment Size",
  5699.                 DESIRED,GREATER_THAN,
  5700.                 FROM_THIS.AVERAGE_COMMENT_SIZE_DESIRED_MINIMUM,CHARACTERS);
  5701.         PUT_REPORT_LINE(0,"",ACTUAL,' ',FROM_THIS.AVERAGE_COMMENT_SIZE_ACTUAL,
  5702.                 CHARACTERS,FROM_THIS.AVERAGE_COMMENT_SIZE_ACTUAL <
  5703.                 FLOAT(FROM_THIS.AVERAGE_COMMENT_SIZE_DESIRED_MINIMUM));
  5704.  
  5705.         PUT_REPORT_LINE(0,HEADER_LINE);
  5706.         PUT_REPORT_LINE(0,"");
  5707.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Transportability");
  5708.         PUT_REPORT_LINE(0,HEADER_LINE);
  5709.  
  5710.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5711.                 "Number of Lines Exceeding Line Length","",' ',
  5712.                 FROM_THIS.NUMBER_OF_LINES_EXCEEDING_LINE_LENGTH,"",
  5713.                 FROM_THIS.NUMBER_OF_LINES_EXCEEDING_LINE_LENGTH > 0);
  5714.         for I in CHARACTER'FIRST .. CHARACTER'LAST loop
  5715.             if FROM_THIS.GRAPHIC_CHARACTERS_USED(I) > 0 then
  5716.                 case I is
  5717.                     when ASCII.NUL => ASCII_IMAGE := "'NUL'";
  5718.                     when ASCII.SOH => ASCII_IMAGE := "'SOH'";
  5719.                     when ASCII.STX => ASCII_IMAGE := "'STX'";
  5720.                     when ASCII.ETX => ASCII_IMAGE := "'ETX'";
  5721.                     when ASCII.EOT => ASCII_IMAGE := "'EOT'";
  5722.                     when ASCII.ENQ => ASCII_IMAGE := "'ENQ'";
  5723.                     when ASCII.ACK => ASCII_IMAGE := "'ACK'";
  5724.                     when ASCII.BEL => ASCII_IMAGE := "'BEL'";
  5725.                     when ASCII.BS  => ASCII_IMAGE := "'BS '";
  5726.                     when ASCII.HT  => ASCII_IMAGE := "'HT '";
  5727.                     when ASCII.LF  => ASCII_IMAGE := "'LF '";
  5728.                     when ASCII.VT  => ASCII_IMAGE := "'VT '";
  5729.                     when ASCII.FF  => ASCII_IMAGE := "'FF '";
  5730.                     when ASCII.CR  => ASCII_IMAGE := "'CR '";
  5731.                     when ASCII.SO  => ASCII_IMAGE := "'SO '";
  5732.                     when ASCII.SI  => ASCII_IMAGE := "'SI '";
  5733.                     when ASCII.DLE => ASCII_IMAGE := "'DLE'";
  5734.                     when ASCII.DC1 => ASCII_IMAGE := "'DC1'";
  5735.                     when ASCII.DC2 => ASCII_IMAGE := "'DC2'";
  5736.                     when ASCII.DC3 => ASCII_IMAGE := "'DC3'";
  5737.                     when ASCII.DC4 => ASCII_IMAGE := "'DC4'";
  5738.                     when ASCII.NAK => ASCII_IMAGE := "'NAK'";
  5739.                     when ASCII.SYN => ASCII_IMAGE := "'SYN'";
  5740.                     when ASCII.ETB => ASCII_IMAGE := "'ETB'";
  5741.                     when ASCII.CAN => ASCII_IMAGE := "'CAN'";
  5742.                     when ASCII.EM  => ASCII_IMAGE := "'EM '";
  5743.                     when ASCII.SUB => ASCII_IMAGE := "'SUB'";
  5744.                     when ASCII.ESC => ASCII_IMAGE := "'ESC'";
  5745.                     when ASCII.FS  => ASCII_IMAGE := "'FS '";
  5746.                     when ASCII.GS  => ASCII_IMAGE := "'GS '";
  5747.                     when ASCII.RS  => ASCII_IMAGE := "'RS '";
  5748.                     when ASCII.US  => ASCII_IMAGE := "'US '";
  5749.                     when ASCII.DEL => ASCII_IMAGE := "'DEL'";
  5750.                     when others => ASCII_IMAGE := "' "& I & " '";
  5751.                 end case;
  5752.                 PUT_REPORT_LINE(FIRST_COLUMN_START,
  5753.                     "Graphic (Non-Basic) Chararacter Used",
  5754.                     ASCII_IMAGE,' ',
  5755.                     FROM_THIS.GRAPHIC_CHARACTERS_USED(I),"",TRUE);
  5756.             end if;
  5757.         end loop;
  5758. -- Needs to be fixed later
  5759. --      PUT_REPORT_LINE(FIRST_COLUMN_START,
  5760. --              "Graphic (Non-Basic) Characters Used","",' ',
  5761. --              FROM_THIS.GRAPHIC_CHARACTERS_USED,"");
  5762. -- Needs to be fixed later
  5763. --      PUT_REPORT_LINE(FIRST_COLUMN_START,
  5764. --              "Non-Graphic Characters Used","",' ',
  5765. --              FROM_THIS.NON_GRAPHIC_CHARACTERS_USED,"");
  5766.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Address Clauses","",' ',
  5767.                 FROM_THIS.ADDRESS_CLAUSES,"",
  5768.                 FROM_THIS.ADDRESS_CLAUSES > 0);
  5769.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Representation Specifications","",
  5770.                 ' ',FROM_THIS.REPRESENTATION_SPECIFICATIONS,"",
  5771.                 FROM_THIS.REPRESENTATION_SPECIFICATIONS > 0);
  5772.  
  5773.         PUT_REPORT_LINE(FIRST_COLUMN_START,"PRAGMA'S used:" );
  5774.         PRINT_LIST(FROM_THIS.PRAGMAS_USED);
  5775.  
  5776.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Non-Standard PRAGMA's Used");
  5777.         PRINT_LIST(FROM_THIS.NON_STANDARD_PRAGMAS_USED );
  5778.  
  5779.         PUT_REPORT_LINE(FIRST_COLUMN_START,"Packages/Procedures WITHed" );
  5780.         PRINT_LIST( FROM_THIS.PACKAGES_PROCEDURES_WITHED );
  5781.  
  5782.         PUT_REPORT_LINE(0,HEADER_LINE);
  5783.         PUT_REPORT_LINE(0,"");
  5784.         PUT_REPORT_LINE(FIRST_COLUMN_START,
  5785.                 "* => Style Flaw        ! => Note: Potential for improvement");
  5786.         PUT_REPORT_LINE(0,"");
  5787.  
  5788.         if STYLE_PARAMETERS.OUTPUT_KEYWORD_LIST /= STYLE_PARAMETERS.NONE then
  5789.             PUT_REPORT_LINE(0,"Keyword Usage");
  5790.             PUT_REPORT_LINE(0," Used Keyword    Allowed         " &
  5791.                     "Restriction     Occurrences     Percentage");
  5792.             PUT_REPORT_LINE(0,HEADER_LINE);
  5793.             -- Figure out how many total keywords were used so we can figure
  5794.             -- percentages
  5795.             for I in TOKENIZER.KEYWORDS loop
  5796.                 KEYWORD_COUNT := KEYWORD_COUNT + FROM_THIS.TOKEN_COUNT(I);
  5797.             end loop;
  5798.             for I in TOKENIZER.KEYWORDS loop
  5799.                 if KEYWORD_COUNT > 0 then
  5800.                     KEYWORD_PERCENTAGES(I) := FLOAT(FROM_THIS.TOKEN_COUNT(I)) /
  5801.                         FLOAT(KEYWORD_COUNT);
  5802.                 else
  5803.                     KEYWORD_PERCENTAGES(I) := 0.0;
  5804.                 end if;
  5805.                 case STYLE_PARAMETERS.OUTPUT_KEYWORD_LIST is
  5806.                     when STYLE_PARAMETERS.ALL_KEYS =>
  5807.                         PUT_REPORT_LINE(FROM_THIS.KEYWORD_USAGE(I),
  5808.                             FROM_THIS.TOKEN_COUNT(I),KEYWORD_PERCENTAGES(I),I);
  5809.                     when STYLE_PARAMETERS.USED =>
  5810.                         if FROM_THIS.TOKEN_COUNT(I) > 0 then
  5811.                             PUT_REPORT_LINE(FROM_THIS.KEYWORD_USAGE(I),
  5812.                                 FROM_THIS.TOKEN_COUNT(I),KEYWORD_PERCENTAGES(I),
  5813.                                 I);
  5814.                         end if;
  5815.                     when STYLE_PARAMETERS.NOT_USED =>
  5816.                         if FROM_THIS.TOKEN_COUNT(I) = 0 then
  5817.                             PUT_REPORT_LINE(FROM_THIS.KEYWORD_USAGE(I),
  5818.                                 FROM_THIS.TOKEN_COUNT(I),KEYWORD_PERCENTAGES(I),
  5819.                                 I);
  5820.                         end if;
  5821.                     when STYLE_PARAMETERS.ERRORS =>
  5822.                         if (FROM_THIS.KEYWORD_USAGE(I).USE_CLASS /= FREE_USE)
  5823.                            and (KEYWORD_PERCENTAGES(I) >
  5824.                                 FROM_THIS.KEYWORD_USAGE(I).USE_FREQ) then
  5825.                             PUT_REPORT_LINE(FROM_THIS.KEYWORD_USAGE(I),
  5826.                                 FROM_THIS.TOKEN_COUNT(I),KEYWORD_PERCENTAGES(I),
  5827.                                 I);
  5828.                         end if;
  5829.                     when STYLE_PARAMETERS.NONE => null;
  5830.                 end case;
  5831.             end loop;
  5832.             PUT_REPORT_LINE(0,HEADER_LINE);
  5833.         end if;
  5834.         exception
  5835.             when others =>
  5836.                 TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  5837.                 TEXT_IO.PUT_LINE(" in GENERATE_REPORT");
  5838.                 raise;
  5839.     end GENERATE_REPORT;
  5840.  
  5841.     procedure INSERT_INTO_LIST ( LIST : in out STRING_LIST_TYPE;
  5842.                                  ELEMENT : DYN.DYN_STRING ) is
  5843.     -- Insert the element name into the list.
  5844.     -- Algorithm:  search the list.  If the element is not there,
  5845.     -- insert it at the end.
  5846.     LOOKAHEAD : STRING_LIST_TYPE;
  5847.     NEW_NODE  : STRING_LIST_TYPE;
  5848.     begin
  5849.         if LIST = null then
  5850.            -- Empty list, insert at beginning
  5851.            NEW_NODE := new STRING_NODE;
  5852.            NEW_NODE.NAME := DYN.D_STRING( DYN.UPPER_CASE( ELEMENT ) );
  5853.            LIST := NEW_NODE;
  5854.            return;
  5855.         else
  5856.            LOOKAHEAD := LIST;
  5857.         end if;
  5858.  
  5859.         -- Now search the list
  5860.         while LOOKAHEAD.NEXT /= null and
  5861.               DYN.STR(LOOKAHEAD.NAME) /= DYN.UPPER_CASE( ELEMENT ) loop
  5862.                 LOOKAHEAD  := LOOKAHEAD.NEXT;
  5863.         end loop;
  5864.         if LOOKAHEAD.NEXT = null then
  5865.             NEW_NODE := new STRING_NODE;
  5866.             NEW_NODE.NAME := DYN.D_STRING( DYN.UPPER_CASE( ELEMENT ) );
  5867.             LOOKAHEAD.NEXT := NEW_NODE;
  5868.         end if;
  5869.         return;
  5870.  
  5871. end INSERT_INTO_LIST;
  5872.  
  5873.  
  5874. end REPORT_GENERATOR;
  5875. ::::::::::
  5876. stylechec.ada
  5877. ::::::::::
  5878.  
  5879. with TOKENIZER;
  5880. with STYLE_PARAMETERS;
  5881. with REPORT_GENERATOR;
  5882. with DYN;
  5883. with HELP;
  5884. with DICTIONARY_MANAGER;
  5885. with CURRENT_EXCEPTION;
  5886. with TEXT_IO;
  5887. with FILE_HANDLING;
  5888. with STACK_PACKAGE;
  5889. procedure STYLE_CHECKER is
  5890. --------------------------------------------------------------------------
  5891. -- Abstract   : This is the main procedure of the Style_Checker.  It
  5892. --              contains types and global variables used by all the
  5893. --              style checker routines.
  5894. --------------------------------------------------------------------------
  5895.  
  5896.     type UNIVERSAL_DATA_TYPE is (INTEGER,
  5897.                                  SHORT_INTEGER,
  5898.                                  LONG_INTEGER,
  5899.                                  FLOAT,
  5900.                                  SHORT_FLOAT,
  5901.                                  LONG_FLOAT,
  5902.                                  NATURAL,
  5903.                                  POSITIVE);
  5904.  
  5905.  
  5906.     type STATUS_RECORD is record
  5907.         CURRENT_TOKEN : TOKENIZER.TOKEN;
  5908.         CURRENT_INDENT     : NATURAL := 0;
  5909.         CURRENT_TRAIL_COMMENT_INDENT : NATURAL := 0;
  5910.         CURRENT_STATEMENTS : NATURAL := 0;
  5911.         CURRENT_LINE       : NATURAL := 0;
  5912.         EXITS_IN_LOOPS     : NATURAL := 0;
  5913.         TOTAL_LINES        : NATURAL := 0;
  5914.         TOTAL_BLANK_LINES  : NATURAL := 0;
  5915.         IN_BODY : BOOLEAN := FALSE;   --  As opposed to being in declarations
  5916.         IN_GENERIC         :BOOLEAN  := FALSE;
  5917.         PACKAGE_NEST_LEVEL : TOKENIZER.LINE_INDEX_RANGE;
  5918.         CONTROL_NEST_LEVEL : TOKENIZER.LINE_INDEX_RANGE;
  5919.         PROCEDURE_NEST_LEVEL : TOKENIZER.LINE_INDEX_RANGE;
  5920.         BEGIN_INDENT : BOOLEAN := true;
  5921.         SUBPROGRAM_NESTING_INFORMATION :
  5922.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5923.         BLANK_LINES_INFORMATION :
  5924.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5925.         COMMENT_INFORMATION :
  5926.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5927.         LITERAL_INFORMATION :
  5928.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5929.         UNIVERSAL_INFORMATION :
  5930.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5931.         IDENTIFIERS_INFORMATION :
  5932.             REPORT_GENERATOR.AVERAGE_KEEPING_RECORD;
  5933.         -- case of names and reserve words
  5934.         CASE_OF_RESERVED_WORDS  : STYLE_PARAMETERS.RESERVE_WORD_CASES :=
  5935.             STYLE_PARAMETERS.CASE_OF_RESERVED_WORDS;
  5936.         CASE_OF_OBJECT_NAMES    : STYLE_PARAMETERS.OBJECT_NAME_CASES :=
  5937.             STYLE_PARAMETERS.CASE_OF_OBJECT_NAMES;
  5938.     end record;
  5939.  
  5940.     type USAGE_RECORD is record
  5941.         ATTRIBUTES                      : boolean := false;
  5942.         DATA_STR_ARRAY                  : boolean := false;
  5943.         DATA_STR_ENUMERATION            : boolean := false;
  5944.         DATA_STR_RECORD                 : boolean := false;
  5945.         REPRESENTATION_SPECIFICATIONS   : boolean := false;
  5946.         ADDRESS_CLAUSES                 : boolean := false;
  5947.     end record;
  5948.  
  5949. --  Variables
  5950.  
  5951.     STYLE_REPORT : REPORT_GENERATOR.REPORT_RECORD;
  5952.  
  5953. --  Miscellaneous mistake records
  5954.  
  5955.     ABBREVIATIONS : NATURAL := 0;
  5956.  
  5957.     CONTROL_STRUCTURES_WITHOUT_LEADING_WHITE_SPACE :
  5958.         NATURAL := 0;
  5959.  
  5960.     COULD_HAVE_USED_AN_ELSIF : NATURAL := 0;
  5961.  
  5962.     DEEPEST_IF_NESTING : NATURAL := 0;
  5963.  
  5964.     DEEPEST_PACKAGE_NESTING : NATURAL := 0;
  5965.  
  5966.     DEEPEST_PROCEDURE_NESTING : NATURAL := 0;
  5967.  
  5968.     INDENTATION_ERRORS : NATURAL := 0;
  5969.  
  5970.     LONG_LOOPS_WITHOUT_LOOP_NAMES : NATURAL := 0;
  5971.  
  5972.     MISSING_UNDERSCORES : NATURAL := 0;
  5973.  
  5974.     MORE_THAN_ONE_STATEMENT_PER_LINE : NATURAL := 0;
  5975.  
  5976.     OBJECT_NAME_CAPITALIZATION_MISTAKES :
  5977.         array(STYLE_PARAMETERS.OBJECT_NAME_CASES) of NATURAL :=
  5978.              (STYLE_PARAMETERS.OBJECT_NAME_CASES'FIRST ..
  5979.               STYLE_PARAMETERS.OBJECT_NAME_CASES'LAST => 0);
  5980.  
  5981.     RESERVE_WORD_CAPITALIZATION_MISTAKES :
  5982.         array(STYLE_PARAMETERS.RESERVE_WORD_CASES) of NATURAL :=
  5983.              (STYLE_PARAMETERS.RESERVE_WORD_CASES'FIRST ..
  5984.               STYLE_PARAMETERS.RESERVE_WORD_CASES'LAST => 0);
  5985.  
  5986. -- Stack
  5987.  
  5988.    MAX_NESTING : constant positive := TOKENIZER.LINE_INDEX_RANGE'LAST;
  5989.  
  5990.    type NEST_TYPE is      (HEADER, PACKAGE_NEST, SUBPROGRAM_NEST, CONTROL_NEST);
  5991.    type NESTING_RECORD is
  5992.      record
  5993.        LEVEL : natural range 0..MAX_NESTING;
  5994.        INDENT : TOKENIZER.LINE_INDEX_RANGE;
  5995.        STATEMENTS      : natural := 0;
  5996.        EXITS           : natural := 0;
  5997.        IN_BODY         : BOOLEAN := FALSE;
  5998.        KIND_OF_NEST    : NEST_TYPE;
  5999.        START_TOKEN     : TOKENIZER.TOKEN;
  6000.        PARAMETERS      : natural := 0;
  6001.        -- IN_PARAMS       : natural := 0;
  6002.        -- OUT_PARAMS      : natural := 0;
  6003.        -- IN_OUT_PARAMS   : natural := 0;
  6004.      end record;
  6005.    STACK_LIMIT : positive := MAX_NESTING;
  6006.  
  6007.    package  NEST_STACK is new STACK_PACKAGE(
  6008.                     ELEMENTS => NESTING_RECORD,
  6009.                     SIZE     => STACK_LIMIT );
  6010.  
  6011.    -- The stack itself
  6012.    MISC_NEST_STACK : NEST_STACK.HELP_INFO_STACK;
  6013.  
  6014. --  Dictionary pointer
  6015.  
  6016.     STYLE_DICTIONARY : DICTIONARY_MANAGER.DICTIONARY_PTR;
  6017.  
  6018. --  Files
  6019.  
  6020.     FLAWS_FILE : TEXT_IO.FILE_TYPE;
  6021.     STYLE_FILE : TEXT_IO.FILE_TYPE;
  6022.     FILE_NAME  : DYN.DYN_STRING := DYN.D_STRING("   ");
  6023.  
  6024. --  General purpose current status global variable
  6025.  
  6026.     CURRENT_STATUS : STATUS_RECORD;
  6027.     CURRENT_USAGE  : USAGE_RECORD;
  6028.  
  6029. --  functions
  6030.  
  6031.     function CURRENT_TOKEN return TOKENIZER.TOKEN;
  6032.  
  6033.     function PREVIOUS_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6034.         return TOKENIZER.TOKEN;
  6035.  
  6036.     function NEXT_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6037.         return TOKENIZER.TOKEN;
  6038.  
  6039.     function GET_NEXT_TOKEN_AND_UPDATE_COUNT return TOKENIZER.TOKEN;
  6040.  
  6041.     function IS_STATEMENT(EXAMINED_TOKEN : in TOKENIZER.TOKEN) return boolean;
  6042.  
  6043.     procedure NEW_LINE_TOKEN_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6044.  
  6045.     function SEARCH_FORWARD ( START_TOKEN : TOKENIZER.TOKEN;
  6046.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE )
  6047.                           return TOKENIZER.TOKEN;
  6048.  
  6049.  
  6050.     function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6051.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6052.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  6053.                                              return TOKENIZER.TOKEN;
  6054.  
  6055.  -- Moving this to ENTERING_BLOCK
  6056.  -- function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6057.  --                       GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6058.  --                       GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE;
  6059.  --                       GOAL_TYPE3   : TOKENIZER.TOKEN_TYPE )
  6060.  --                                          return TOKENIZER.TOKEN;
  6061.  
  6062.     function SEARCH_BACKWARD ( START_TOKEN : TOKENIZER.TOKEN;
  6063.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE )
  6064.                           return TOKENIZER.TOKEN;
  6065.  
  6066.  
  6067.     function SEARCH_BACKWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6068.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6069.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  6070.                                              return TOKENIZER.TOKEN;
  6071.  
  6072.     procedure BEGIN_OF_LINE_INDENTATION( CURRENT_TOKEN : TOKENIZER.TOKEN);
  6073.  
  6074.     procedure LITERAL_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6075.  
  6076.     procedure COMMENT_TOKEN_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6077.  
  6078.     procedure RESERVE_WORD_ENCOUNTERED(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN);
  6079.  
  6080.     procedure OBJECT_NAME_ENCOUNTERED(OBJECT_NAME_TOKEN : in TOKENIZER.TOKEN);
  6081.  
  6082.     procedure ENTERING_BLOCK_STRUCTURE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6083.  
  6084.     procedure ENTERING_SUB_BLOCK_STRUCTURE(FROM_THIS_TOKEN: in TOKENIZER.TOKEN);
  6085.  
  6086.     procedure EXITING_BLOCK_STRUCTURE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6087.  
  6088.     procedure TYPE_DECLARATION(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6089.  
  6090.     procedure CHECK_THE_STYLE;
  6091.  
  6092.     procedure CHECK_END_OF_BLOCKS;
  6093.  
  6094.     procedure CHECK_STATEMENTS_PER_LINE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN);
  6095.  
  6096.     function CURRENT_TOKEN return TOKENIZER.TOKEN is separate;
  6097.  
  6098.     function PREVIOUS_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6099.         return TOKENIZER.TOKEN is separate;
  6100.  
  6101.     function NEXT_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6102.         return TOKENIZER.TOKEN is separate;
  6103.  
  6104.     function GET_NEXT_TOKEN_AND_UPDATE_COUNT return TOKENIZER.TOKEN is separate;
  6105.  
  6106.  
  6107.     function IS_STATEMENT(EXAMINED_TOKEN : in TOKENIZER.TOKEN) return boolean
  6108.         is separate;
  6109.  
  6110.     function SEARCH_FORWARD ( START_TOKEN : TOKENIZER.TOKEN;
  6111.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE )
  6112.                           return TOKENIZER.TOKEN is separate;
  6113.  
  6114.  
  6115.     function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6116.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6117.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  6118.                                              return TOKENIZER.TOKEN is separate;
  6119.  
  6120. --  function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6121. --                        GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6122. --                        GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE;
  6123. --                        GOAL_TYPE3   : TOKENIZER.TOKEN_TYPE )
  6124. --                                           return TOKENIZER.TOKEN is separate;
  6125. --
  6126.  
  6127.     function SEARCH_BACKWARD ( START_TOKEN : TOKENIZER.TOKEN;
  6128.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE )
  6129.                           return TOKENIZER.TOKEN is separate;
  6130.  
  6131.  
  6132.     function SEARCH_BACKWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  6133.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  6134.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  6135.                                              return TOKENIZER.TOKEN is separate;
  6136.  
  6137.     procedure NEW_LINE_TOKEN_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6138.               is separate;
  6139.  
  6140.     procedure BEGIN_OF_LINE_INDENTATION( CURRENT_TOKEN : TOKENIZER.TOKEN)
  6141.               is separate;
  6142.  
  6143.     procedure LITERAL_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6144.               is separate;
  6145.  
  6146.     procedure COMMENT_TOKEN_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6147.               is separate;
  6148.  
  6149.     procedure RESERVE_WORD_ENCOUNTERED(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN)
  6150.               is separate;
  6151.  
  6152.     procedure OBJECT_NAME_ENCOUNTERED(OBJECT_NAME_TOKEN : in TOKENIZER.TOKEN)
  6153.               is separate;
  6154.  
  6155.     procedure ENTERING_BLOCK_STRUCTURE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6156.               is separate;
  6157.  
  6158.     procedure ENTERING_SUB_BLOCK_STRUCTURE(FROM_THIS_TOKEN: in TOKENIZER.TOKEN)
  6159.               is separate;
  6160.  
  6161.     procedure EXITING_BLOCK_STRUCTURE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6162.               is separate;
  6163.  
  6164.     procedure TYPE_DECLARATION(FROM_THIS_TOKEN : in TOKENIZER.TOKEN) is
  6165.               separate;
  6166.  
  6167.     procedure CHECK_THE_STYLE is separate;
  6168.  
  6169.     procedure CHECK_END_OF_BLOCKS is separate;
  6170.  
  6171.     procedure CHECK_STATEMENTS_PER_LINE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  6172.  
  6173.               is separate;
  6174.  
  6175. begin -- Style_Checker
  6176.     TOKENIZER.BUILD_TOKENS;
  6177.     FILE_HANDLING.OUTPUT_FILE_ID(FLAWS_FILE,STYLE_FILE);
  6178.     DICTIONARY_MANAGER.CREATE_DICTIONARY(
  6179.         DICTIONARY_KIND => DICTIONARY_MANAGER.MASTER,
  6180.         DICTIONARY_IN   => STYLE_DICTIONARY,
  6181.         FILENAME        => FILE_HANDLING.STYLE_DICTIONARY_NAME );
  6182.     CHECK_THE_STYLE;
  6183.     REPORT_GENERATOR.GENERATE_REPORT(STYLE_REPORT,STYLE_FILE,FILE_NAME);
  6184.     TEXT_IO.CLOSE(FLAWS_FILE);
  6185.     TEXT_IO.CLOSE(STYLE_FILE);
  6186.     exception
  6187.         when FILE_HANDLING.HELP_ASKED_FOR =>
  6188.              begin  -- exceptions can be raised here!
  6189.                 --  call help file FILE_HANDLING.HELP_FILE_NAME
  6190.                 HELP.HELP_SCREEN( HELP.HELP,      FILE_HANDLING.HELP_FILE_NAME);
  6191.              exception
  6192.                 when HELP.HELP_OPEN_ERROR =>
  6193.                         TEXT_IO.PUT_LINE("Cannot Open the HELP File!");
  6194.                 when HELP.HELP_FILE_ERROR =>
  6195.                         TEXT_IO.PUT_LINE("Cannot find the HELP File!");
  6196.                 when HELP.HELP_FORMAT_ERROR =>
  6197.                         TEXT_IO.PUT_LINE(
  6198.                            "The HELP file is in the wrong format!");
  6199.              end;
  6200.         when others =>
  6201.              TEXT_IO.PUT("In STYLE_CHECKER main body: exception --");
  6202.              TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  6203.              TEXT_IO.PUT_LINE("Attempting to generate a partial Style Report");
  6204.              REPORT_GENERATOR.GENERATE_REPORT(STYLE_REPORT,
  6205.                                               STYLE_FILE,FILE_NAME);
  6206.              TEXT_IO.CLOSE(FLAWS_FILE);
  6207.              TEXT_IO.CLOSE(STYLE_FILE);
  6208.              raise;
  6209. end STYLE_CHECKER;
  6210. pragma MAIN;
  6211. ::::::::::
  6212. beginofli.ada
  6213. ::::::::::
  6214.  
  6215. separate( STYLE_CHECKER )
  6216.  
  6217.  
  6218. procedure BEGIN_OF_LINE_INDENTATION ( CURRENT_TOKEN : TOKENIZER.TOKEN) is
  6219. --
  6220. -- PARAMETERS:
  6221. -- This is passed a token which should be at the start of
  6222. -- a line.
  6223. -- ABSTRACT:  This checks the indentation of the token.
  6224. -- ALGORITHM
  6225. -- Cases:
  6226. --          -- Comments.  There are too many radically different commenting
  6227. --          styles.  Comments are ignored for indentation.  (Note trailing
  6228. --          comments.)
  6229. -- Outdent for:  << labels >>
  6230. -- Indent for:   Statements, and {
  6231. --          else
  6232. --          when
  6233. --          elsif
  6234. --          begin
  6235. --          record
  6236. --          declare
  6237. --          generic
  6238. --          limited
  6239. --          private
  6240. --          "<<"}  -- left label brackett;
  6241. --
  6242. -- Otherwise:  Consider as the continuation of a statement.  In this case,
  6243. --          indentation should be greater than the 'normal'.
  6244. --
  6245. -- Determining indentation level.
  6246. -- The 'entering-block-structure' and 'leaving ...' sets flags about current
  6247. -- indentation levels.
  6248. --  If this is the first element after a block enter,
  6249. --    a flag will be set to indicate further indnetation is necessary.
  6250. --    If a comment - this is allowed to stay at the same level of indentation,
  6251. --    or be indented.
  6252. --    The first line is checked to see indentation is more than the outer block
  6253. --    level.  This sets the indentation level for the block.  The flags are
  6254. --    reset.
  6255. --  If this is a further line in the block, the indentation should match
  6256. --    what was there before.
  6257. --
  6258.  
  6259. use TOKENIZER;
  6260.  
  6261.   LOOKAHEAD : TOKENIZER.TOKEN;
  6262.   LINE      : TOKENIZER.LINE_NUM_RANGE;
  6263.   COLUMN    : TOKENIZER.LINE_INDEX_RANGE;
  6264.   SOURCE_LINE : DYN.DYN_STRING;
  6265.  
  6266.   -- Error messages
  6267.   LABEL_NOT_OUTDENTED : constant string :=
  6268.         "This Label should be outdented further!";
  6269.   LOOP_NOT_OUTDENTED  : constant string :=
  6270.         "This Loop-name should be outdented further!";
  6271.   CONTINUATION_NOT_INDENTED : constant string :=
  6272.         "The statement-continuation in this line should be indented!";
  6273.   LINE_NOT_INDENTED :         constant string :=
  6274.         "This line is not indented Properly!";
  6275.   LINE_SHOULD_BE_INDENTED :   constant string :=
  6276.         "This line should be indented to column:  ";
  6277.   LINE_TOO_LITTLE_INDENTED :  constant string :=
  6278.         "This line is not indented enough!";
  6279.   BEGIN_NOT_INDENTED :        constant string :=
  6280. "Beginning of this block not indented properly. Line ignored for Indentation!";
  6281.  
  6282.   function OTHER_INDENT_CASES( A_TOKEN : in TOKENIZER.TOKEN ) return boolean is
  6283.  
  6284.   begin
  6285.     case TOKENIZER.TYPE_OF_TOKEN_IS( A_TOKEN ) is
  6286.       when TOKENIZER.ELSE_TOKEN => return true;
  6287.       when TOKENIZER.WHEN_TOKEN => return true;
  6288.       when TOKENIZER.BEGIN_TOKEN => return true;
  6289.       when TOKENIZER.ELSIF_TOKEN => return true;
  6290.       when TOKENIZER.DECLARE_TOKEN => return true;  -- Is this correct?
  6291.       when TOKENIZER.GENERIC_TOKEN => return true;
  6292.       when TOKENIZER.LIMITED_TOKEN => return true;
  6293.       when TOKENIZER.PRIVATE_TOKEN => return true;
  6294.  
  6295.       when others => return false;
  6296.     end case;
  6297.  
  6298.   end OTHER_INDENT_CASES;
  6299.  
  6300.   function IS_LOOP_NAME( NAME_TOKEN : TOKENIZER.TOKEN ) return boolean is
  6301.   -- checks to find "IDENTIFIER :" which is a loop name
  6302.      LOOKAHEAD : TOKENIZER.TOKEN;
  6303.      LOOK2     : TOKENIZER.TOKEN;
  6304.   begin
  6305.      LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( NAME_TOKEN );
  6306.      LOOK2     := NEXT_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  6307.      return TOKENIZER.TYPE_OF_TOKEN_IS( NAME_TOKEN) = TOKENIZER.IDENTIFIER and
  6308.         TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) = TOKENIZER.COLON  and
  6309.        (TOKENIZER.TYPE_OF_TOKEN_IS( LOOK2 ) = TOKENIZER.FOR_TOKEN or
  6310.         TOKENIZER.TYPE_OF_TOKEN_IS( LOOK2 ) = TOKENIZER.WHILE_TOKEN or
  6311.         TOKENIZER.TYPE_OF_TOKEN_IS( LOOK2 ) = TOKENIZER.LOOP_TOKEN);
  6312.   exception
  6313.     when END_OF_TOKENS =>
  6314.         return false;           -- at least let this continue!
  6315.     when others =>
  6316.         raise;
  6317.   end IS_LOOP_NAME;
  6318.  
  6319.  
  6320.   function LOOP_CONTINUATION( LOOP_TOKEN : TOKENIZER.TOKEN ) return boolean is
  6321.   -- ABSTRACT : Determine whether this is the LOOP token of a WHILE. . .LOOP
  6322.   --            statement.
  6323.   -- PARAMETER: LOOP_TOKEN is a token which is matched against the LOOP
  6324.   --            part of the WHILE... LOOP template
  6325.         LOOKAHEAD      : TOKENIZER.TOKEN;
  6326.         LOOKAHEAD_TYPE : TOKENIZER.TOKEN_TYPE;
  6327.  
  6328.   begin
  6329.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOP_TOKEN)=TOKENIZER.LOOP_TOKEN then
  6330.              -- look for a "FOR" or "WHILE"
  6331.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN( LOOP_TOKEN );
  6332.              while not IS_STATEMENT(LOOKAHEAD) loop
  6333.                      LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  6334.              end loop;
  6335.              LOOKAHEAD_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD );
  6336.              if (LOOKAHEAD_TYPE = TOKENIZER.WHILE_TOKEN or
  6337.                      LOOKAHEAD_TYPE = TOKENIZER.FOR_TOKEN) then
  6338.                  -- this is the continuation of a while...loop statement!
  6339.                  return TRUE;
  6340.              else
  6341.                  return FALSE;
  6342.              end if;
  6343.         else
  6344.              return FALSE;
  6345.         end if;
  6346.   end LOOP_CONTINUATION;
  6347.  
  6348.  
  6349. begin
  6350.  
  6351.   -- check whether this is declarations and if those are required to be indented
  6352.   if CURRENT_STATUS.IN_BODY or
  6353.      STYLE_PARAMETERS.IS_DECLARATION_INDENTATION_REQUIRED then
  6354.  
  6355.    -- Position of Token
  6356.    TOKENIZER.TOKEN_POSITION( CURRENT_TOKEN, LINE, COLUMN );
  6357.  
  6358.    -- Determine indentation case
  6359.    if TOKENIZER.TYPE_OF_TOKEN_IS( CURRENT_TOKEN ) = LEFT_LABEL_BRACKET then
  6360.       -- Label - outdent!?
  6361.       if COLUMN >= CURRENT_STATUS.CURRENT_INDENT then
  6362.         -- Error! should be outdented!
  6363.         if not CURRENT_STATUS.BEGIN_INDENT then
  6364.             REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6365.                                 CURRENT_TOKEN, LABEL_NOT_OUTDENTED,
  6366.                                 REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6367.             STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6368.              STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6369.         -- else
  6370.         --   Hard to check for label indentation at the beginning of a block
  6371.         end if;
  6372.       end if;
  6373.  
  6374.    elsif IS_LOOP_NAME( CURRENT_TOKEN ) then
  6375.         if COLUMN > CURRENT_STATUS.CURRENT_INDENT or else
  6376.           (COLUMN = CURRENT_STATUS.CURRENT_INDENT and
  6377.            not CURRENT_STATUS.BEGIN_INDENT) then
  6378.             REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6379.                                 CURRENT_TOKEN, LOOP_NOT_OUTDENTED,
  6380.                                 REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6381.             STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6382.              STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6383.         end if;
  6384.  
  6385.  
  6386.    elsif (IS_STATEMENT(CURRENT_TOKEN) and not LOOP_CONTINUATION(CURRENT_TOKEN))
  6387.          or OTHER_INDENT_CASES(CURRENT_TOKEN) then
  6388.          -- Normal Statements!
  6389.          if CURRENT_STATUS.BEGIN_INDENT then
  6390.             -- This case is the beginning of an indented block
  6391.             if COLUMN > CURRENT_STATUS.CURRENT_INDENT then
  6392.                -- update the indentation count (beginning of block)
  6393.                CURRENT_STATUS.BEGIN_INDENT := false;
  6394.                -- This line established the indentation for the block!
  6395.                CURRENT_STATUS.CURRENT_INDENT := COLUMN;
  6396.             else
  6397.               case TOKENIZER.TYPE_OF_TOKEN_IS( CURRENT_TOKEN ) is
  6398.                 when
  6399.                     TOKENIZER.ELSE_TOKEN |
  6400.                     TOKENIZER.ELSIF_TOKEN |
  6401.                     TOKENIZER.WHEN_TOKEN |
  6402.                     TOKENIZER.BEGIN_TOKEN |
  6403.                     TOKENIZER.PRIVATE_TOKEN |
  6404.                     TOKENIZER.LIMITED_TOKEN |
  6405.                     TOKENIZER.GENERIC_TOKEN |
  6406.                     TOKENIZER.END_TOKEN |
  6407.                     TOKENIZER.EXCEPTION_TOKEN =>
  6408.                                 -- actually these should be indented to the
  6409.                                 -- last level of indentation to be precise!
  6410.                      if COLUMN < CURRENT_STATUS.CURRENT_INDENT then
  6411.                         REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6412.                           CURRENT_TOKEN, BEGIN_NOT_INDENTED,
  6413.                           REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6414.                         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6415.                           STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6416.                      end if;
  6417.                 when TOKENIZER.COMMENT =>
  6418.                      null;
  6419.                 when others =>
  6420.                   REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6421.                         CURRENT_TOKEN, BEGIN_NOT_INDENTED,
  6422.                         REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6423.                         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6424.                             STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6425.               end case;
  6426.             end if;
  6427.  
  6428.          else
  6429.             -- Indentation normal
  6430.             if COLUMN > CURRENT_STATUS.CURRENT_INDENT then
  6431.                    REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, CURRENT_TOKEN,
  6432.                       LINE_SHOULD_BE_INDENTED &
  6433.                       INTEGER'IMAGE(CURRENT_STATUS.CURRENT_INDENT),
  6434.                       REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6435.                    STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6436.                       STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6437.             elsif COLUMN < CURRENT_STATUS.CURRENT_INDENT then
  6438.               case TOKENIZER.TYPE_OF_TOKEN_IS( CURRENT_TOKEN ) is
  6439.                 when TOKENIZER.ELSE_TOKEN |
  6440.                     TOKENIZER.ELSIF_TOKEN |
  6441.                     TOKENIZER.WHEN_TOKEN |
  6442.                     TOKENIZER.BEGIN_TOKEN |
  6443.                     TOKENIZER.PRIVATE_TOKEN |
  6444.                     TOKENIZER.LIMITED_TOKEN |
  6445.                     TOKENIZER.GENERIC_TOKEN |
  6446.                     TOKENIZER.END_TOKEN |
  6447.                     TOKENIZER.EXCEPTION_TOKEN =>
  6448.                                 -- actually these should be indented to the
  6449.                                 -- last level of indentation to be precise!
  6450.                                 null; -- these are o.k.
  6451.                 when TOKENIZER.IDENTIFIER =>
  6452.                   -- check for loop names!
  6453.                   LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( CURRENT_TOKEN );
  6454.                   if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD)/=TOKENIZER.COLON
  6455.                     then
  6456.                       -- Not a loop name and should be indented!
  6457.                       REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6458.                         CURRENT_TOKEN, LINE_TOO_LITTLE_INDENTED,
  6459.                         REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6460.                         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6461.                             STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6462.                   end if;
  6463.                 when TOKENIZER.FUNCTION_TOKEN |
  6464.                      TOKENIZER.PROCEDURE_TOKEN |
  6465.                      TOKENIZER.PACKAGE_TOKEN =>
  6466.                     if CURRENT_STATUS.IN_GENERIC then
  6467.                         null; -- spec should be outdented to generic level
  6468.                     else
  6469.                         REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6470.                             CURRENT_TOKEN, LINE_TOO_LITTLE_INDENTED,
  6471.                             REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6472.                         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6473.                             STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6474.                     end if;
  6475.                 when others =>
  6476.                   REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6477.                         CURRENT_TOKEN, LINE_TOO_LITTLE_INDENTED,
  6478.                         REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6479.                         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6480.                             STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6481.               end case;
  6482.             end if;
  6483.          end if;
  6484.  
  6485.    elsif TOKENIZER.TYPE_OF_TOKEN_IS( CURRENT_TOKEN ) = COMMENT then
  6486.          -- COMMENTS are ignored for indentation
  6487.          null;
  6488.  
  6489.    else
  6490.       -- Statement continuation - should be indented more than norm.
  6491.       -- UNLESS! this is a blank line!
  6492.      if TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= TOKENIZER.END_OF_LINE and
  6493.         TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= TOKENIZER.END_OF_FILE then
  6494.       if COLUMN <= CURRENT_STATUS.CURRENT_INDENT then
  6495.          REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  6496.                      CURRENT_TOKEN, CONTINUATION_NOT_INDENTED,
  6497.                      REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  6498.         STYLE_REPORT.INCONSISTANT_INDENTATION:=
  6499.              STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  6500.       end if;
  6501.      end if;
  6502.    end if;
  6503.   end if; -- if in declaration and no indentation checking required!
  6504. exception
  6505.    when others =>
  6506.       TEXT_IO.NEW_LINE;
  6507.       TEXT_IO.PUT("Inside BEGIN_OF_LINE_INDENTATION -- exception: " );
  6508.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME  );
  6509.       TEXT_IO.PUT("While in line:");
  6510.       TOKENIZER.LINE_CONTAINING_TOKEN(CURRENT_TOKEN,SOURCE_LINE );
  6511.       TEXT_IO.PUT_LINE( DYN.STR( SOURCE_LINE ) );
  6512.  
  6513. end BEGIN_OF_LINE_INDENTATION;
  6514. ::::::::::
  6515. checkstat.ada
  6516. ::::::::::
  6517. separate( STYLE_CHECKER )
  6518.  
  6519. procedure CHECK_STATEMENTS_PER_LINE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN ) is
  6520. -- ABSTRACT: This procedure checks to see if there are multiple statements
  6521. -- in this line.
  6522. --
  6523. -- Parameter:  FROM_THIS_TOKEN is a token which should be the first token
  6524. --             on the line.
  6525. -- Algorithm:  Every time a statement is encountered, we increment the
  6526. --             Current_statements counter.  Past the first token, a
  6527. --             statement sets the multiple-statements-per-line flag
  6528. --             UNLESS it is the following cases.
  6529. --              for . . . loop (loop ok)
  6530. --              while. . .loop (loop ok)
  6531. --              when. . => statement (is o.k.)
  6532. --             Finally, if multiple statements encountered, PUT_FLAW.
  6533. --
  6534. --             It was decided that the following case WAS ILLEGAL!
  6535. --             This has been commented out!
  6536. --              with X; use X; (use allowed)
  6537.  
  6538.  
  6539.  
  6540.  
  6541. use TOKENIZER;
  6542. MULTI_STATEMENT_FLAG : boolean;
  6543. LOOKAHEAD            : TOKENIZER.TOKEN;
  6544. FIRST_TYPE           : TOKENIZER.TOKEN_TYPE;
  6545. LOOKAHEAD_TYPE       : TOKENIZER.TOKEN_TYPE;
  6546. STATEMENTS_ON_LINE   : natural := 0;
  6547. MULTI_STMN_MSG       : constant string :=
  6548.         "There are more than one statements on this line!";
  6549. begin
  6550.     if IS_STATEMENT( FROM_THIS_TOKEN ) then
  6551.        STATEMENTS_ON_LINE := 1;
  6552.     else
  6553.        STATEMENTS_ON_LINE := 0;
  6554.     end if;
  6555.     FIRST_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS( FROM_THIS_TOKEN );
  6556.     LOOKAHEAD := TOKENIZER.NEXT_TOKEN( FROM_THIS_TOKEN );
  6557.     MULTI_STATEMENT_FLAG := false;
  6558.  
  6559.     while TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) /= TOKENIZER.END_OF_LINE and
  6560.           TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) /= TOKENIZER.END_OF_FILE loop
  6561.        if IS_STATEMENT( LOOKAHEAD ) then
  6562.           STATEMENTS_ON_LINE := STATEMENTS_ON_LINE + 1;
  6563.           case TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) is
  6564.              when TOKENIZER.LOOP_TOKEN =>
  6565.                 -- Good examples:
  6566.                 --   for ... loop
  6567.                 --   for ...
  6568.                 --       ... loop
  6569.                 -- Bad
  6570.                 -- x := (y+z)*
  6571.                 --    p;  loop
  6572.                 if STATEMENTS_ON_LINE > 2 then
  6573.                     MULTI_STATEMENT_FLAG := true;
  6574.                 elsif IS_STATEMENT (FROM_THIS_TOKEN) then
  6575.                    if (FIRST_TYPE /= TOKENIZER.WHILE_TOKEN and
  6576.                      FIRST_TYPE /= TOKENIZER.FOR_TOKEN) then
  6577.                       MULTI_STATEMENT_FLAG := true;
  6578.                    end if;
  6579.                 else
  6580.                    -- look for a "FOR" or "WHILE"
  6581.                    LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN( FROM_THIS_TOKEN );
  6582.                    while not IS_STATEMENT(LOOKAHEAD) loop
  6583.                      LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  6584.                    end loop;
  6585.                    LOOKAHEAD_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD );
  6586.                    if (LOOKAHEAD_TYPE /= TOKENIZER.WHILE_TOKEN and
  6587.                      LOOKAHEAD_TYPE /= TOKENIZER.FOR_TOKEN) then
  6588.                       MULTI_STATEMENT_FLAG := true;
  6589.                    end if;
  6590.                 end if;
  6591.  
  6592.             when others =>
  6593.                 if FIRST_TYPE = TOKENIZER.WHEN_TOKEN and
  6594.                    STATEMENTS_ON_LINE <2 then
  6595.                    null; -- this is ok!
  6596.                 else
  6597.                 MULTI_STATEMENT_FLAG := true;
  6598.                 end if;
  6599.           end case;
  6600.        end if;
  6601.  
  6602.        LOOKAHEAD := TOKENIZER.NEXT_TOKEN( LOOKAHEAD );
  6603.     end loop;
  6604.  
  6605.     if MULTI_STATEMENT_FLAG then
  6606.        REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, FROM_THIS_TOKEN,
  6607.          MULTI_STMN_MSG, REPORT_GENERATOR.MORE_THAN_ONE_STATEMENT_ON_LINE);
  6608.        STYLE_REPORT.OCCURRENCES_OF_MORE_THAN_ONE_STATEMENT_PER_LINE :=
  6609.        STYLE_REPORT.OCCURRENCES_OF_MORE_THAN_ONE_STATEMENT_PER_LINE + 1;
  6610.  
  6611.     end if;
  6612.  
  6613.    null;
  6614.     exception
  6615.         when END_OF_TOKENS =>
  6616.          null;
  6617.          -- This should be o.k.  END-OF-TOKENS will be handled elsewhere!
  6618.          -- TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6619.          -- TEXT_IO.PUT_LINE(" in CHECK_STATEMENTS_PER_LINE");
  6620.         when others =>
  6621.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6622.             TEXT_IO.PUT_LINE(" in CHECK_STATEMENTS_PER_LINE");
  6623.             raise;
  6624. end CHECK_STATEMENTS_PER_LINE;
  6625. ::::::::::
  6626. checkendo.ada
  6627. ::::::::::
  6628. separate (STYLE_CHECKER)
  6629.  
  6630. procedure CHECK_END_OF_BLOCKS is
  6631. -- ABSTRACT: This checks to see if there are any extraneous
  6632. --           nesting elements left on the stack at the end of input.
  6633. --           If so it put out an error in the flaws file.
  6634.  
  6635. OLD_NEST_REC : NESTING_RECORD;
  6636. UNMATCHED_NEST_MSG : constant string :=
  6637.   "There are not enough 'ends' to close all the blocks at the end of input!";
  6638.  
  6639. begin
  6640.     NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  6641.     while OLD_NEST_REC.KIND_OF_NEST /= HEADER loop
  6642.        -- unmatched nesting elements!
  6643.         REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, OLD_NEST_REC.START_TOKEN,
  6644.                 UNMATCHED_NEST_MSG, REPORT_GENERATOR.UNMATCHED_NESTING);
  6645.         NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  6646.     end loop;
  6647.     -- restore the header record, just to make sure?
  6648.     NEST_STACK.PUSH( OLD_NEST_REC, MISC_NEST_STACK );
  6649.  
  6650.  
  6651.     null;
  6652.  
  6653. exception
  6654.         when others =>
  6655.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6656.             TEXT_IO.PUT_LINE(" in CHECK_END_OF_BLOCKS");
  6657.             raise;
  6658. end CHECK_END_OF_BLOCKS;
  6659. ::::::::::
  6660. checkthes.ada
  6661. ::::::::::
  6662. separate (STYLE_CHECKER)
  6663.  
  6664. procedure CHECK_THE_STYLE is
  6665. --------------------------------------------------------------------------
  6666. -- Abstract   : This procedure contains the main loop for the Style_Checker
  6667. --------------------------------------------------------------------------
  6668. -- Algorithm  : General algorithm is :
  6669. --                 Perform necessary initialization of global variables
  6670. --                 Get first token
  6671. --                 Go through all tokens in order, calling routines
  6672. --                      to handle each particular type of token
  6673. --                 Final clean up and name length checking
  6674. --------------------------------------------------------------------------
  6675.     use TOKENIZER;
  6676.     CURRENT_TOKEN : TOKENIZER.TOKEN;
  6677.     LOOK_AHEAD_TOKEN : TOKENIZER.TOKEN;
  6678.     NEST_HEADER      : NESTING_RECORD;
  6679.     SOURCE_LINE      : DYN.DYN_STRING;
  6680.     CH               : CHARACTER;
  6681.  
  6682.     FINAL_MSG : constant STRING :=
  6683.      "Finish checking started in above statement.  Total statements:";
  6684.  
  6685.     procedure CHECK_OBJECT_NAMES_SIZE is separate;
  6686.  
  6687.     procedure CHECK_FOR_ATTRIBUTE( AT_THIS_TOKEN : in TOKENIZER.TOKEN )
  6688.         is separate;
  6689.  
  6690.     procedure CHECK_UNIVERSAL ( THIS_TOKEN : TOKENIZER.TOKEN)
  6691.         is separate;
  6692.  
  6693. begin
  6694.     -- Initialize the Nesting Stack -- JRM 2-20-85
  6695.     NEST_HEADER.LEVEL := 0;
  6696.     NEST_HEADER.INDENT := 1;
  6697.     NEST_HEADER.STATEMENTS := 0;
  6698.     NEST_HEADER.KIND_OF_NEST := HEADER;
  6699.     NEST_HEADER.START_TOKEN := TOKENIZER.FIRST_TOKEN;
  6700.     NEST_STACK.PUSH( NEST_HEADER, MISC_NEST_STACK );
  6701.  
  6702.     STYLE_PARAMETERS.RESERVED_WORD_INFO(STYLE_REPORT.KEYWORD_USAGE);
  6703.  
  6704.     STYLE_PARAMETERS.AVERAGE_SUBPROGRAM_SIZE
  6705.         (STYLE_REPORT.AVERAGE_SUBPROGRAM_SIZE_DESIRED_MINIMUM,
  6706.         STYLE_REPORT.AVERAGE_SUBPROGRAM_SIZE_DESIRED_MAXIMUM);
  6707.     STYLE_PARAMETERS.SUBPROGRAM_PARAMETERS
  6708.         (STYLE_REPORT.AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MINIMUM,
  6709.         STYLE_REPORT.AVERAGE_NUMBER_OF_PARAMETERS_DESIRED_MAXIMUM);
  6710.     begin
  6711.         loop
  6712.             CURRENT_TOKEN := GET_NEXT_TOKEN_AND_UPDATE_COUNT;
  6713.             -- First statement on the line
  6714.             if IS_STATEMENT(CURRENT_TOKEN) and
  6715.                TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN)/=WHILE_TOKEN and
  6716.                -- FOR and WHILE statements are covered by LOOP!
  6717.                TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN)/=FOR_TOKEN then
  6718.                 CURRENT_STATUS.CURRENT_STATEMENTS :=
  6719.                     CURRENT_STATUS.CURRENT_STATEMENTS + 1;
  6720.                 -- TEXT_IO.NEW_LINE;
  6721.                 -- TOKENIZER.LINE_CONTAINING_TOKEN(CURRENT_TOKEN, SOURCE_LINE );
  6722.                 -- TEXT_IO.PUT("New Statement in line:");
  6723.                 -- TEXT_IO.PUT_LINE( DYN.STR( SOURCE_LINE ) );
  6724.                 -- Check declarations.
  6725.                 if not CURRENT_STATUS.IN_BODY then
  6726.                    -- Count declarations & universal types.
  6727.                    CHECK_UNIVERSAL( CURRENT_TOKEN );
  6728.                 end if;
  6729.             end if;
  6730.             begin
  6731.                 LOOK_AHEAD_TOKEN := TOKENIZER.PREVIOUS_TOKEN(CURRENT_TOKEN);
  6732.                 if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  6733.                     TOKENIZER.END_OF_LINE then
  6734.                     CURRENT_STATUS.TOTAL_LINES:=CURRENT_STATUS.TOTAL_LINES+1;
  6735.  
  6736.                     if                        TOKENIZER.END_OF_LINE /=
  6737.                     TOKENIZER.TYPE_OF_TOKEN_IS( CURRENT_TOKEN ) then
  6738.                       -- Check for indentation at beginning of a
  6739.                       -- NON-BLANK line!
  6740.                       BEGIN_OF_LINE_INDENTATION(CURRENT_TOKEN);
  6741.                       --
  6742.                       -- Check for multiple statements per line
  6743.                       CHECK_STATEMENTS_PER_LINE( CURRENT_TOKEN );
  6744.                     else
  6745.                       CURRENT_STATUS.TOTAL_BLANK_LINES :=
  6746.                         CURRENT_STATUS.TOTAL_BLANK_LINES + 1;
  6747.                     end if;
  6748.                     -- Does this work for floating divide?
  6749.                     STYLE_REPORT.PERCENT_OF_BLANK_LINES_ACTUAL :=
  6750.                 FLOAT(CURRENT_STATUS.TOTAL_BLANK_LINES)      /
  6751.                   FLOAT(CURRENT_STATUS.TOTAL_LINES);
  6752.  
  6753.                 end if;
  6754.                 exception
  6755.                     when TOKENIZER.END_OF_TOKENS =>
  6756.                         BEGIN_OF_LINE_INDENTATION(CURRENT_TOKEN);
  6757.                 --
  6758.                 -- Check for multiple statements per line
  6759.                 CHECK_STATEMENTS_PER_LINE( CURRENT_TOKEN );
  6760.                     when others => raise;
  6761.             end;
  6762.             case TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) is
  6763.                 when TOKENIZER.KEYWORDS =>
  6764.                     RESERVE_WORD_ENCOUNTERED(CURRENT_TOKEN);
  6765.                 when TOKENIZER.END_OF_LINE =>
  6766.                     NEW_LINE_TOKEN_ENCOUNTERED(CURRENT_TOKEN);
  6767.                 when TOKENIZER.END_OF_FILE =>
  6768.                     if DYN.STR(FILE_NAME) = "   " then
  6769.                         FILE_NAME := TOKENIZER.EXTERNAL_REPRESENTATION(
  6770.                                          CURRENT_TOKEN);
  6771.                     end if;
  6772.                 when TOKENIZER.IDENTIFIER =>
  6773.                     OBJECT_NAME_ENCOUNTERED(CURRENT_TOKEN);
  6774.                 when TOKENIZER.NUMERIC_LITERAL | TOKENIZER.STRING_LITERAL  |
  6775.                     TOKENIZER.CHARACTER_LITERAL =>
  6776.                     LITERAL_ENCOUNTERED(CURRENT_TOKEN);
  6777.                 when TOKENIZER.SEMICOLON => null;
  6778.                 when TOKENIZER.COMMENT =>
  6779.                     COMMENT_TOKEN_ENCOUNTERED(CURRENT_TOKEN);
  6780.                 when TOKENIZER.TICK    =>
  6781.                     CHECK_FOR_ATTRIBUTE(CURRENT_TOKEN);
  6782. --      CONCATENATION_OPERATOR,  RIGHT_PARENTHESIS, LEFT_PARENTHESIS,
  6783. --      MULTIPLICATION_OPERATOR, ADDITION_OPERATOR, COMMA, SUBTRACTION_OPERATOR,
  6784. --      PERIOD, DIVISION_OPERATOR, COLON, LESS_THAN_OPERATOR, EQUAL_OPERATOR,
  6785. --      GREATER_THAN_OPERATOR, VERTICAL_BAR, ARROW, DOUBLE_DOT,
  6786. --      EXPONENTIATE_OPERATOR, ASSIGNMENT_OPERATOR, INEQUAL_OPERATOR,
  6787. --      GREATER_THAN_OR_EQUAL_OPERATOR, LESS_THAN_OR_EQUAL_OPERATOR,
  6788. --      LEFT_LABEL_BRACKET, RIGHT_LABEL_BRACKET, BOX
  6789.                 when TOKENIZER.ANYTHING_ELSE =>
  6790.                     for I in 1..DYN.LENGTH(
  6791.                         TOKENIZER.EXTERNAL_REPRESENTATION(CURRENT_TOKEN)) loop
  6792.                         case STYLE_PARAMETERS.CHARACTER_SET is
  6793.                             -- letters and numbers will not be handled here
  6794.                             -- Also most "Special characters"
  6795.                             when STYLE_PARAMETERS.GRAPHIC =>
  6796.                                 CH := DYN.STR(TOKENIZER.
  6797.                                         EXTERNAL_REPRESENTATION(
  6798.                                         CURRENT_TOKEN))(I);
  6799.                                 if CH /= ASCII.HT and CH /= ASCII.VT and
  6800.                                    CH /= ASCII.LF and CH /= ASCII.FF then
  6801.                                     REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,
  6802.                                         CURRENT_TOKEN, "Illegal character "
  6803.                                         & "in this line",
  6804.                                        REPORT_GENERATOR.GRAPHIC_CHARACTER_USED);
  6805.                                     STYLE_REPORT.GRAPHIC_CHARACTERS_USED(CH) :=
  6806.                                         STYLE_REPORT.GRAPHIC_CHARACTERS_USED(CH)
  6807.                                         + 1;
  6808.                                 end if;
  6809.                             when STYLE_PARAMETERS.BASIC =>
  6810.                                 CH := DYN.STR(TOKENIZER.EXTERNAL_REPRESENTATION(
  6811.                                               CURRENT_TOKEN))(I);
  6812.                                 REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,
  6813.                                     CURRENT_TOKEN, "Illegal character "
  6814.                                     & "in this line",
  6815.                                     REPORT_GENERATOR.GRAPHIC_CHARACTER_USED);
  6816.                                 STYLE_REPORT.GRAPHIC_CHARACTERS_USED(CH) :=
  6817.                                   STYLE_REPORT.GRAPHIC_CHARACTERS_USED(CH) + 1;
  6818.                             when STYLE_PARAMETERS.EXTENDED => null;
  6819.                         end case;
  6820.                     end loop;
  6821.                 when others => null;
  6822.             end case;
  6823.         end loop;
  6824.     exception
  6825.         when TOKENIZER.END_OF_TOKENS => null;
  6826.         when others => raise;
  6827.     end;
  6828.     -- check to see if there are no unmatched block on the nest stack
  6829.     CHECK_END_OF_BLOCKS;
  6830.  
  6831.     CHECK_OBJECT_NAMES_SIZE;
  6832.  
  6833.     if CURRENT_STATUS.IDENTIFIERS_INFORMATION.NUMBER_OF_ITEMS /= 0 then
  6834.         STYLE_REPORT.AVERAGE_NAME_SIZE_ACTUAL :=
  6835.             FLOAT(CURRENT_STATUS.IDENTIFIERS_INFORMATION.TOTAL_SIZE_OF_ITEMS) /
  6836.             FLOAT(CURRENT_STATUS.IDENTIFIERS_INFORMATION.NUMBER_OF_ITEMS);
  6837.     end if;
  6838.  
  6839.     STYLE_REPORT.NUMBER_OF_COMMENTS :=
  6840.             CURRENT_STATUS.COMMENT_INFORMATION.NUMBER_OF_ITEMS;
  6841.     if CURRENT_STATUS.COMMENT_INFORMATION.NUMBER_OF_ITEMS /= 0 then
  6842.         STYLE_REPORT.AVERAGE_COMMENT_SIZE_ACTUAL :=
  6843.             FLOAT(CURRENT_STATUS.COMMENT_INFORMATION.TOTAL_SIZE_OF_ITEMS) /
  6844.             FLOAT(CURRENT_STATUS.COMMENT_INFORMATION.NUMBER_OF_ITEMS);
  6845.     end if;
  6846.  
  6847.     if CURRENT_STATUS.LITERAL_INFORMATION.NUMBER_OF_ITEMS /= 0 then
  6848.         STYLE_REPORT.PERCENT_OF_LITERALS_IN_BODY_ACTUAL :=
  6849.             FLOAT(CURRENT_STATUS.LITERAL_INFORMATION.TOTAL_SIZE_OF_ITEMS) /
  6850.             FLOAT(CURRENT_STATUS.LITERAL_INFORMATION.NUMBER_OF_ITEMS);
  6851.     end if;
  6852.  
  6853.     if CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS /= 0 then
  6854.         STYLE_REPORT.PERCENT_OF_UNIVERSAL_TYPES_ACTUAL :=
  6855.             FLOAT(CURRENT_STATUS.UNIVERSAL_INFORMATION.TOTAL_SIZE_OF_ITEMS) /
  6856.             FLOAT(CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS);
  6857.     end if;
  6858.  
  6859.     -- Print a final message of statement count!
  6860.     NEST_STACK.POP ( NEST_HEADER, MISC_NEST_STACK );
  6861.     REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, NEST_HEADER.START_TOKEN,
  6862.       FINAL_MSG & INTEGER'IMAGE(NEST_HEADER.STATEMENTS)  );
  6863.  
  6864.     exception
  6865.         when TOKENIZER.END_OF_TOKENS => null;
  6866.         when others =>
  6867.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6868.             TEXT_IO.PUT_LINE(" in CHECK_THE_STYLE");
  6869.             TEXT_IO.PUT_LINE("Trying to generate a Style Report anyway!");
  6870.             CHECK_OBJECT_NAMES_SIZE;
  6871.             raise;
  6872. end CHECK_THE_STYLE;
  6873. ::::::::::
  6874. checkfora.ada
  6875. ::::::::::
  6876. separate( STYLE_CHECKER.CHECK_THE_STYLE )
  6877.  
  6878. procedure CHECK_FOR_ATTRIBUTE ( AT_THIS_TOKEN : in TOKENIZER.TOKEN ) is
  6879. -- ABSTRACT: Check whether this is an attribute and set the usage-flag.
  6880. ---------------------------------------------------------------------
  6881. -- PARAMETERS:  AT_THIS_TOKEN is a token pointing to  the TICK
  6882. --              which we are trying to recognise as an attribute.
  6883. ----------------------------------------------------------------------
  6884. -- ALGORITHM:   A tick can either be an attribute or the separator
  6885. --              before an aggregate.
  6886. ----------------------------------------------------------------------
  6887. LOOKAHEAD : TOKENIZER.TOKEN;
  6888.  
  6889. begin
  6890.     LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( AT_THIS_TOKEN );
  6891.     if TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) /= TOKENIZER.LEFT_PARENTHESIS
  6892.                 then
  6893.         CURRENT_USAGE.ATTRIBUTES := true;
  6894.         STYLE_REPORT.ATTRIBUTES_USED := true;
  6895.     end if;
  6896.     exception
  6897.         when others =>
  6898.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6899.             TEXT_IO.PUT_LINE(" in CHECK_FOR_ATTRIBUTE.");
  6900.             raise;
  6901. end CHECK_FOR_ATTRIBUTE;
  6902. ::::::::::
  6903. checkobje.ada
  6904. ::::::::::
  6905. with TOKEN_DEFINITION;
  6906. separate (STYLE_CHECKER.CHECK_THE_STYLE)
  6907.  
  6908. procedure CHECK_OBJECT_NAMES_SIZE is
  6909. --------------------------------------------------------------------------
  6910. -- Abstract   : This routine calculates the name size information
  6911. --              for the Style_Checker
  6912. --------------------------------------------------------------------------
  6913.  
  6914.  
  6915.     TREE_ROOT : TOKENIZER.IDENTIFIER_TREE := TOKENIZER.TREE_ROOT;
  6916.     TOTAL_VOWELS_IN_NAMES       : NATURAL := 0;
  6917.     TOTAL_NAME_SEGMENTS         : NATURAL := 0;
  6918.     TOTAL_CHARACTERS_IN_SEGMENTS: NATURAL := 0;
  6919.     SPELL_CHECK_WORD            : TOKEN_DEFINITION.TOKEN_TYPE;
  6920.     FOUND                       : BOOLEAN;
  6921.  
  6922.     procedure TREE_FOLLOWER(T : in out TOKENIZER.IDENTIFIER_TREE) is
  6923.  
  6924.     begin
  6925.         if T /= null then
  6926.             -- traverse left tree
  6927.             TREE_FOLLOWER(T.LEFT);
  6928.             -- Update name segment information
  6929.             if DYN.LENGTH(T.REFERENCES.STRG) > STYLE_PARAMETERS.SMALL_WORD_SIZE
  6930.                 then
  6931.                 SPELL_CHECK_WORD.LENGTH := 0;
  6932.                 for I in 1..DYN.LENGTH(T.REFERENCES.STRG) loop
  6933.                     if (DYN.STR(T.REFERENCES.STRG)(I) = '_') then
  6934.                         TOTAL_NAME_SEGMENTS := TOTAL_NAME_SEGMENTS + 1;
  6935.                         DICTIONARY_MANAGER.TOKEN_IS_FOUND(STYLE_DICTIONARY,
  6936.                                                           SPELL_CHECK_WORD,
  6937.                                                           FOUND);
  6938.                         if not FOUND then
  6939.                             -- Not handled now...
  6940.                             null;
  6941.                         end if;
  6942.                         SPELL_CHECK_WORD.LENGTH := 0;
  6943.                     else
  6944.                         if SPELL_CHECK_WORD.LENGTH <
  6945.                             TOKEN_DEFINITION.TOKEN_LENGTH then
  6946.                             SPELL_CHECK_WORD.LENGTH :=
  6947.                                 SPELL_CHECK_WORD.LENGTH + 1;
  6948.                             SPELL_CHECK_WORD.WORD(SPELL_CHECK_WORD.LENGTH) :=
  6949.                                 DYN.STR(T.REFERENCES.STRG)(I);
  6950.                         end if;
  6951.                         TOTAL_CHARACTERS_IN_SEGMENTS :=
  6952.                             TOTAL_CHARACTERS_IN_SEGMENTS + 1;
  6953.                     end if;
  6954.                 end loop;
  6955.                 TOTAL_NAME_SEGMENTS := TOTAL_NAME_SEGMENTS + 1;
  6956.                 DICTIONARY_MANAGER.TOKEN_IS_FOUND(STYLE_DICTIONARY,
  6957.                     SPELL_CHECK_WORD,FOUND);
  6958.                 if not FOUND then
  6959.                 -- Not handled now...
  6960.                     null;
  6961.                 end if;
  6962.             end if;
  6963.             -- Count characters and vowels
  6964.             for I in 1..DYN.LENGTH(T.REFERENCES.STRG) loop
  6965.                 case DYN.STR(T.REFERENCES.STRG)(I) is
  6966.                     when 'a' | 'e' | 'i' | 'o' | 'u' | 'y' |
  6967.                          'A' | 'E' | 'I' | 'O' | 'U' | 'Y' =>
  6968.                         TOTAL_VOWELS_IN_NAMES := TOTAL_VOWELS_IN_NAMES + 1;
  6969.                     when others => null;
  6970.                 end case;
  6971.             end loop;
  6972.             -- Update name length information
  6973.             CURRENT_STATUS.IDENTIFIERS_INFORMATION.NUMBER_OF_ITEMS :=
  6974.                 CURRENT_STATUS.IDENTIFIERS_INFORMATION.NUMBER_OF_ITEMS + 1;
  6975.             CURRENT_STATUS.IDENTIFIERS_INFORMATION.TOTAL_SIZE_OF_ITEMS :=
  6976.                 CURRENT_STATUS.IDENTIFIERS_INFORMATION.TOTAL_SIZE_OF_ITEMS +
  6977.                 DYN.LENGTH(T.REFERENCES.STRG);
  6978.             -- traverse right tree
  6979.             TREE_FOLLOWER(T.RIGHT);
  6980.         end if;
  6981.     exception
  6982.         when others =>
  6983.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  6984.             TEXT_IO.PUT_LINE(" in TREE_FOLLOWER");
  6985.             raise;
  6986.     end TREE_FOLLOWER;
  6987.  
  6988. begin
  6989.     TREE_FOLLOWER(TREE_ROOT);
  6990.     STYLE_REPORT.ABBREVIATIONS :=
  6991.        TOTAL_CHARACTERS_IN_SEGMENTS /= 0 and then
  6992.        (FLOAT(TOTAL_VOWELS_IN_NAMES) / FLOAT(TOTAL_CHARACTERS_IN_SEGMENTS)) <
  6993.        STYLE_PARAMETERS.VOWEL_FREQUENCY;
  6994.     if TOTAL_NAME_SEGMENTS > 0 then
  6995.         STYLE_REPORT.NAME_SEGMENT_SIZE_ACTUAL :=
  6996.             FLOAT(TOTAL_CHARACTERS_IN_SEGMENTS) / FLOAT(TOTAL_NAME_SEGMENTS);
  6997.     end if;
  6998.     exception
  6999.         when others =>
  7000.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7001.             TEXT_IO.PUT_LINE(" in CHECK_OBJECT_NAMES_SIZE");
  7002.             raise;
  7003. end CHECK_OBJECT_NAMES_SIZE;
  7004. ::::::::::
  7005. checkuniv.ada
  7006. ::::::::::
  7007. separate( STYLE_CHECKER.CHECK_THE_STYLE )
  7008.  
  7009. procedure CHECK_UNIVERSAL ( THIS_TOKEN : TOKENIZER.TOKEN ) is
  7010. -- ABSTRACT:  this procedure checks for the presence of a declaration
  7011. -- which is a universal type.
  7012. -- Parameters  THIS_ToKEN points to the token which is the
  7013. --      beginning of the declaration.
  7014.  
  7015.   use TOKENIZER;
  7016.  
  7017.   LOOKAHEAD : TOKENIZER.TOKEN;
  7018.   ID_COUNT  : POSITIVE;
  7019.  
  7020.   -- Until declarations are parsed better, these will not be used!
  7021.   MIS_PARSED_DECLARATION : exception;
  7022.   MIS_PARSED_MSG : constant string :=
  7023.  "Failed to parse declaration.  Either Ada is wrong or this program in error!";
  7024.  
  7025.   function IS_UNIVERSAL( TYPE_TOKEN : TOKENIZER.TOKEN ) return boolean is
  7026.     NAME : DYN.DYN_STRING;
  7027.   begin
  7028.     NAME      := TOKENIZER.EXTERNAL_REPRESENTATION( TYPE_TOKEN );
  7029.  
  7030.     return
  7031.         DYN.UPPER_CASE(NAME) = "INTEGER" or
  7032.         DYN.UPPER_CASE(NAME) = "SHORT_INTEGER" or
  7033.         DYN.UPPER_CASE(NAME) = "LONG_INTEGER"  or
  7034.         DYN.UPPER_CASE(NAME) = "FLOAT"         or
  7035.         DYN.UPPER_CASE(NAME) = "SHORT_FLOAT"   or
  7036.         DYN.UPPER_CASE(NAME) = "LONG_FLOAT"  or
  7037.         DYN.UPPER_CASE(NAME) = "NATURAL"       or
  7038.         DYN.UPPER_CASE(NAME) = "POSITIVE";
  7039. end IS_UNIVERSAL;
  7040.  
  7041. begin
  7042.     LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( THIS_TOKEN );
  7043.     case TOKENIZER.TYPE_OF_TOKEN_IS( THIS_TOKEN ) is
  7044.         when TOKENIZER.TYPE_TOKEN    =>
  7045.             CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS :=
  7046.                 CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS + 1;
  7047.  
  7048.         when TOKENIZER.SUBTYPE_TOKEN =>
  7049.             CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS :=
  7050.                 CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS + 1;
  7051.  
  7052.         when TOKENIZER.IDENTIFIER    =>
  7053.             -- Find out how many identifiers
  7054.             ID_COUNT := 1;
  7055.             LOOKAHEAD := SEARCH_FORWARD_FOR_ONE_OF(THIS_TOKEN,
  7056.                          TOKENIZER.COMMA,TOKENIZER.COLON);
  7057.             while TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD)=TOKENIZER.COMMA loop
  7058.                 ID_COUNT := ID_COUNT + 1;
  7059.                 LOOKAHEAD := SEARCH_FORWARD_FOR_ONE_OF(LOOKAHEAD,
  7060.                          TOKENIZER.COMMA,TOKENIZER.COLON);
  7061.             end loop;
  7062.  
  7063.             CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS :=
  7064.                CURRENT_STATUS.UNIVERSAL_INFORMATION.NUMBER_OF_ITEMS + ID_COUNT;
  7065.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) = TOKENIZER.COLON then
  7066.                 -- object declaration
  7067.                 LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  7068.                 -- look for exception or array
  7069.                 if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) =
  7070.                    TOKENIZER.EXCEPTION_TOKEN   or
  7071.                    TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) =
  7072.                    TOKENIZER.ARRAY_TOKEN then
  7073.                         -- these are O.K.!
  7074.                         null;
  7075.                 else
  7076.                   -- look for CONSTANT
  7077.                   if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) =
  7078.                    TOKENIZER.CONSTANT_TOKEN then
  7079.                         -- move to the identifier past CONSTANT!
  7080.                         LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  7081.                   end if;
  7082.                   if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) =
  7083.                    TOKENIZER.IDENTIFIER then
  7084.                     if IS_UNIVERSAL( LOOKAHEAD ) then
  7085.                        CURRENT_STATUS.UNIVERSAL_INFORMATION.
  7086.                                      TOTAL_SIZE_OF_ITEMS :=
  7087.                         CURRENT_STATUS.UNIVERSAL_INFORMATION.
  7088.                                      TOTAL_SIZE_OF_ITEMS + ID_COUNT;
  7089.                     end if;
  7090.                   else
  7091.                     null;
  7092.                     -- We need to parse declarations better here before
  7093.                     -- bad syntax can be noted!
  7094.                     -- raise MIS_PARSED_DECLARATION;
  7095.                   end if;
  7096.                 end if;
  7097.             end if;
  7098.         when others =>
  7099.             null;
  7100.     end case;
  7101.  
  7102.     exception
  7103.         when END_OF_TOKENS =>
  7104.             REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, THIS_TOKEN,
  7105.                                        MIS_PARSED_MSG );
  7106.         when MIS_PARSED_DECLARATION =>
  7107.             REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, THIS_TOKEN,
  7108.                                        MIS_PARSED_MSG );
  7109.             null;
  7110.         when others =>
  7111.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7112.             TEXT_IO.PUT_LINE(" in CHECK_UNIVERSAL.");
  7113.             raise;
  7114. end CHECK_UNIVERSAL;
  7115. ::::::::::
  7116. commentto.ada
  7117. ::::::::::
  7118. separate (STYLE_CHECKER)
  7119.  
  7120. procedure COMMENT_TOKEN_ENCOUNTERED ( FROM_THIS_TOKEN : TOKENIZER.TOKEN ) is
  7121. -- ABSTRACT : This determines whether this is a 'trailing' comment,
  7122. --            If it is, its indentation is checked.
  7123. -- PARAMETERS : COMMENT_TOKEN is the token containing the comment to check.
  7124. -- ALGORITHM  : This is a trailing comment if:
  7125. --      The indentation level is
  7126. --      greater then current-indentation.
  7127. --      The trailing indentation level is set when:
  7128. --        The first trailing comment in a section is discovered (i.e. the
  7129. --        old trailing-indent is 0), or
  7130. --        Reset when a trailing comment has different indentation (this
  7131. --        offending comment is flagged if the style requires, or
  7132. --        Reset to 0 when a package, procedure, etc. is exited.
  7133.   use TOKENIZER;
  7134.  
  7135.   LOOKAROUND    : TOKENIZER.TOKEN;
  7136.   LINE          : TOKENIZER.LINE_NUM_RANGE;
  7137.   COLUMN        : TOKENIZER.LINE_INDEX_RANGE;
  7138.  
  7139.   BAD_TRAILING_MSG      : constant string :=
  7140.     "The trailing comment here is inconsistantly indented.";
  7141.  
  7142. begin
  7143.   -- Increment comment size counters
  7144.   CURRENT_STATUS.COMMENT_INFORMATION.NUMBER_OF_ITEMS :=
  7145.     CURRENT_STATUS.COMMENT_INFORMATION.NUMBER_OF_ITEMS + 1;
  7146.   CURRENT_STATUS.COMMENT_INFORMATION.TOTAL_SIZE_OF_ITEMS :=
  7147.     CURRENT_STATUS.COMMENT_INFORMATION.TOTAL_SIZE_OF_ITEMS +
  7148.     TOKENIZER.LENGTH_OF_COMMENT( FROM_THIS_TOKEN );
  7149.  
  7150.   -- Check Trailing indentation?
  7151.   if STYLE_PARAMETERS.IS_COMMENT_INDENTATION_REQUIRED then
  7152.     -- The style says we should indent check indentation on trailing comments!
  7153.     LOOKAROUND := TOKENIZER.PREVIOUS_TOKEN( FROM_THIS_TOKEN );
  7154.     TOKENIZER.TOKEN_POSITION( FROM_THIS_TOKEN, LINE, COLUMN );
  7155.     if COLUMN > CURRENT_STATUS.CURRENT_INDENT then
  7156.         -- this is a trailing comment!
  7157.         if CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT = 0 then
  7158.             -- a first trailing comment!
  7159.             CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT := COLUMN;
  7160.         else
  7161.             if CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT /= COLUMN then
  7162.                 -- Bad trailing comment!
  7163.                 -- Reset the trailing indentation counter.
  7164.                 CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT := COLUMN;
  7165.                 REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, FROM_THIS_TOKEN,
  7166.                         BAD_TRAILING_MSG,
  7167.                         REPORT_GENERATOR.INCONSISTANT_INDENTATION);
  7168.                 STYLE_REPORT.INCONSISTANT_INDENTATION :=
  7169.                         STYLE_REPORT.INCONSISTANT_INDENTATION + 1;
  7170.             end if;
  7171.         end if;
  7172.     end if;
  7173.   end if;
  7174.     exception
  7175.         when TOKENIZER.END_OF_TOKENS =>
  7176.             -- First on the input.  No handling required!
  7177.             null;
  7178.         when others =>
  7179.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7180.             TEXT_IO.PUT_LINE(" in COMMENT_TOKEN_ENCOUNTERED");
  7181.             raise;
  7182. end COMMENT_TOKEN_ENCOUNTERED;
  7183. ::::::::::
  7184. currentto.ada
  7185. ::::::::::
  7186. separate (STYLE_CHECKER)
  7187.  
  7188. function CURRENT_TOKEN return TOKENIZER.TOKEN is
  7189. --------------------------------------------------------------------------
  7190. -- Abstract   : This function returns the token that is considered to be
  7191. --              the current token for the Style_Checker.  The current
  7192. --              token is the last one "counted" by
  7193. --              GET_NEXT_TOKEN_AND_UPDATE_COUNT.
  7194. --------------------------------------------------------------------------
  7195.  
  7196. begin
  7197.     return CURRENT_STATUS.CURRENT_TOKEN;
  7198.     exception
  7199.         when others =>
  7200.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7201.             TEXT_IO.PUT_LINE(" in CURRENT_TOKEN");
  7202.             raise;
  7203. end CURRENT_TOKEN;
  7204. ::::::::::
  7205. enteringb.ada
  7206. ::::::::::
  7207.  
  7208. separate( STYLE_CHECKER )
  7209.  
  7210. procedure ENTERING_BLOCK_STRUCTURE( FROM_THIS_TOKEN : in TOKENIZER.TOKEN ) is
  7211. -- ABSTRACT: This performs the operations necessary for entering a
  7212. --           block structure.  This initializes a record for the
  7213. --           nesting stack, prepares for indentation.  For Procedures,
  7214. --           and functions, it counts parameters.
  7215. --
  7216. -- PARAMETER: This is a token which is the beginning of the block.
  7217. -- ALGORITHM:
  7218. --   Check to make sure its the beginning of a block really.
  7219. --   Increment previous nesting counter (Partial count of statements!)
  7220. --   Prepare new nesting record.
  7221. --   if FROM_THIS_TOKEN = procedure | function then
  7222. --      Count parameters
  7223. --      Check parameter limits
  7224. --   end if;
  7225. --   Push nesting record.
  7226. --   Check indentation flag, and increment proper nesting counter;
  7227. --      Nesting is checked for:
  7228. --      Packages,
  7229. --      Functions, procedures, and tasks
  7230. --      Control Structures
  7231. -- Begin
  7232. -- Case
  7233. -- Declare (special handling, this prefaces a 'begin'
  7234. -- Do
  7235. -- Exception (block)
  7236. -- For
  7237. -- Function
  7238. -- Loop
  7239. -- Package
  7240. -- Procedure
  7241. -- Record
  7242. -- Select
  7243. -- Task
  7244. -- Then
  7245. use TOKENIZER;
  7246.  
  7247. NEW_NEST_REC : NESTING_RECORD;
  7248. OLD_NEST_REC : NESTING_RECORD;
  7249. SEARCH_TOKEN : TOKENIZER.TOKEN;
  7250. PARAM_COUNT  : natural;
  7251. BAD_BLOCK_START : exception;
  7252. SOURCE_LINE     : DYN.DYN_STRING;
  7253. SUBPROGRAM_NEST_EXCEEDED : constant string :=
  7254.     "This subprogram is nested too deeply!";
  7255. PACKAGE_NEST_EXCEEDED    : constant string :=
  7256.     "This package is nested too deeply!";
  7257. CONTROL_NEST_EXCEEDED    : constant string :=
  7258.     "This control structure is nested too deeply!";
  7259. OVERFLOW_MSG             : constant string :=
  7260.  "This is nested so deep the stack overflowed! Further results are uncertain!";
  7261. UNDERFLOW_MSG            : constant string :=
  7262.  "The nesting stack has underflowed unexpectedly.  Please check Ada syntax.";
  7263.  
  7264. function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  7265.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  7266.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE;
  7267.                           GOAL_TYPE3   : TOKENIZER.TOKEN_TYPE )
  7268.                                              return TOKENIZER.TOKEN is
  7269. use TOKENIZER;
  7270. -- This searches FORWARD until it finds one of the token types
  7271. -- If the end of the list is found, the END_OF_FILE token is
  7272. -- returned as a 'failed' signal.
  7273.   CURRENT_TOKEN : TOKENIZER.TOKEN;
  7274.   SOURCE_LINE   : DYN.DYN_STRING;
  7275.  
  7276. begin
  7277.    CURRENT_TOKEN := NEXT_NON_TRIVIAL_TOKEN( START_TOKEN );
  7278.    while (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE1) and
  7279.          (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE2) and
  7280.          (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE3) loop
  7281.      if TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) = END_OF_FILE then
  7282.         exit;  -- just return this token as a 'failed' signal.
  7283.      end if;
  7284.      CURRENT_TOKEN := NEXT_NON_TRIVIAL_TOKEN( CURRENT_TOKEN );
  7285.    end loop;
  7286.    return CURRENT_TOKEN;
  7287. exception
  7288.    when others =>
  7289.       TEXT_IO.NEW_LINE;
  7290.       TEXT_IO.PUT("Inside SEARCH_FORWARD -- exception:" );
  7291.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  7292.       TEXT_IO.PUT_LINE("While in line:");
  7293.       TOKENIZER.LINE_CONTAINING_TOKEN( START_TOKEN, SOURCE_LINE );
  7294.       TEXT_IO.PUT( DYN.STR( SOURCE_LINE ) );
  7295. end SEARCH_FORWARD_FOR_ONE_OF;
  7296.  
  7297.  
  7298.  
  7299.  
  7300.  
  7301.  
  7302. procedure HANDLE_PARAMETER_LIST( START : in TOKENIZER.TOKEN;
  7303.                                  PARAMETERS : out natural) is
  7304. -- ABSTRACT: This locates a parameter (declaration) list.  It
  7305. --           counts the parameters on the list.  This currently
  7306. --           only handles function and procedures.  (Entry and
  7307. --           accept are other possibilities.)
  7308. --           NOTE - It seems more obvious to do this as a function,
  7309. --           however there may later be other things to do to parameter
  7310. --           lists.
  7311. -- PARAMETERS: START is a token which is the start of the statement
  7312. --             (function or PROCEDURE).
  7313. --             PARAMETERS is returned as the number of parameters on the list.
  7314. -- ALGORITHM
  7315. --  If there is a parameter list, it starts with a "(" two tokens
  7316. --  past the START.  Then each individual parameter is separated by a
  7317. --  ";" with multiple names separated by ",".
  7318. -- So the number of parameters is the number of ";" and "," before a ")".
  7319.  
  7320. LOOKAHEAD : TOKENIZER.TOKEN;
  7321. COUNT     : natural;
  7322. SMALL_LIMIT : natural;
  7323. LARGE_LIMIT : natural;
  7324.  
  7325. BAD_FORMAL_PART : exception;
  7326. BAD_FORMAL_MSG : constant string :=
  7327.                          "The formal part is not recognized properly?";
  7328. TOO_FEW_PARAMS : constant string :=
  7329.     "The number of parameters is BELOW the set limit!";
  7330. TOO_MANY_PARAMS : constant string :=
  7331.     "The number of parameters is ABOVE the set limit!";
  7332.  
  7333. begin
  7334.  
  7335.    -- Make sure this is the proper kind of statement!
  7336.    case TOKENIZER.TYPE_OF_TOKEN_IS( START ) is
  7337.      when TOKENIZER.PROCEDURE_TOKEN | TOKENIZER.FUNCTION_TOKEN =>
  7338.        -- Determine whether there is a "format_part".
  7339.        LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( START );
  7340.        LOOKAHEAD := NEXT_NON_TRIVIAL_TOKEN( LOOKAHEAD );
  7341.        if TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) = TOKENIZER.LEFT_PARENTHESIS
  7342.         then
  7343.          -- Number of parameters is number of ";" or ","
  7344.          -- between "(" and ")" plus one.
  7345.          COUNT := 1;
  7346.          LOOKAHEAD := SEARCH_FORWARD_FOR_ONE_OF( LOOKAHEAD,
  7347.                       TOKENIZER.RIGHT_PARENTHESIS,TOKENIZER.SEMICOLON,
  7348.                       TOKENIZER.COMMA);
  7349.          while TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) = TOKENIZER.SEMICOLON or
  7350.                TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) = TOKENIZER.COMMA loop
  7351.             COUNT := COUNT + 1;
  7352.             LOOKAHEAD := SEARCH_FORWARD_FOR_ONE_OF( LOOKAHEAD,
  7353.                          TOKENIZER.RIGHT_PARENTHESIS,TOKENIZER.SEMICOLON,
  7354.                          TOKENIZER.COMMA );
  7355.             if TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) = TOKENIZER.END_OF_FILE
  7356.               then
  7357.                 -- cannot recognize the formal part properly.
  7358.                 raise BAD_FORMAL_PART;
  7359.             end if;
  7360.          end loop;
  7361.        else
  7362.          COUNT := 0;
  7363.        end if;
  7364.        -- Check for the parameter range:
  7365.        STYLE_PARAMETERS.SUBPROGRAM_PARAMETERS( SMALL_LIMIT, LARGE_LIMIT);
  7366.        if COUNT < SMALL_LIMIT then
  7367.            REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START, TOO_FEW_PARAMS,
  7368.            REPORT_GENERATOR.TOO_FEW_PARAMETERS);
  7369.            STYLE_REPORT.INSTANCES_OF_PARAMETERS_BELOW_MINIMUM :=
  7370.              STYLE_REPORT.INSTANCES_OF_PARAMETERS_BELOW_MINIMUM + 1;
  7371.        end if;
  7372.        if COUNT > LARGE_LIMIT then
  7373.            REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START, TOO_MANY_PARAMS,
  7374.            REPORT_GENERATOR.TOO_MANY_PARAMETERS);
  7375.            STYLE_REPORT.INSTANCES_OF_PARAMETERS_ABOVE_MAXIMUM :=
  7376.              STYLE_REPORT.INSTANCES_OF_PARAMETERS_ABOVE_MAXIMUM + 1;
  7377.        end if;
  7378.  
  7379.      when others =>
  7380.  
  7381.  
  7382.        COUNT := 0;
  7383.    end case;
  7384.  
  7385.    PARAMETERS := COUNT;
  7386.    return;
  7387.  
  7388. exception
  7389.    when BAD_FORMAL_PART =>
  7390.       TEXT_IO.NEW_LINE;
  7391.       TEXT_IO.PUT(BAD_FORMAL_MSG);
  7392.    when others =>
  7393.       TEXT_IO.NEW_LINE;
  7394.       TEXT_IO.PUT("Inside HANDLE_PARAMETER_LIST -- exception:" );
  7395.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  7396.  
  7397. end HANDLE_PARAMETER_LIST;
  7398.  
  7399. begin
  7400.    -- All the checking should have been done before this!
  7401.    -- We should only be here if we're entering an actual block
  7402.  
  7403.    -- Handle nesting records
  7404.    NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  7405.    -- add on statements-to-date
  7406.    OLD_NEST_REC.STATEMENTS := OLD_NEST_REC.STATEMENTS +
  7407.                               CURRENT_STATUS.CURRENT_STATEMENTS;
  7408.    CURRENT_STATUS.CURRENT_STATEMENTS := 0;
  7409.    NEST_STACK.PUSH( OLD_NEST_REC, MISC_NEST_STACK );
  7410.    NEW_NEST_REC.INDENT := CURRENT_STATUS.CURRENT_INDENT;
  7411.    NEW_NEST_REC.STATEMENTS := 0;
  7412.    NEW_NEST_REC.START_TOKEN := FROM_THIS_TOKEN;
  7413.    NEW_NEST_REC.IN_BODY := CURRENT_STATUS.IN_BODY;
  7414.  
  7415.    CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT := 0;
  7416.  
  7417.    -- Determine kind of structure
  7418.    --  Possibilities are:
  7419.  
  7420.    case TOKENIZER.TYPE_OF_TOKEN_IS( FROM_THIS_TOKEN ) is
  7421.    -- Control blocks
  7422.      when TOKENIZER.BEGIN_TOKEN  =>
  7423. -------------------------------------------------------
  7424.          -- Check to see if preceeded by 'DECLARE'
  7425. -------------------------------------------------------
  7426.          CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7427.                       CURRENT_STATUS.CONTROL_NEST_LEVEL + 1;
  7428.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.CONTROL_NEST_LEVEL;
  7429.          NEW_NEST_REC.KIND_OF_NEST := CONTROL_NEST;
  7430.          NEW_NEST_REC.PARAMETERS   := 0;
  7431.          NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7432.  
  7433.      when TOKENIZER.CASE_TOKEN |
  7434.       TOKENIZER.FOR_TOKEN |
  7435.       TOKENIZER.DECLARE_TOKEN |
  7436.       TOKENIZER.RECORD_TOKEN |
  7437.       TOKENIZER.SELECT_TOKEN =>
  7438.          CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7439.                         CURRENT_STATUS.CONTROL_NEST_LEVEL + 1;
  7440.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.CONTROL_NEST_LEVEL;
  7441.          NEW_NEST_REC.KIND_OF_NEST := CONTROL_NEST;
  7442.          NEW_NEST_REC.PARAMETERS   := 0;
  7443.          NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7444.  
  7445.      when TOKENIZER.DO_TOKEN =>
  7446. -------------------------------------------------------
  7447.         -- ACCEPT is the beginning of the block!
  7448. -------------------------------------------------------
  7449.          SEARCH_TOKEN := SEARCH_BACKWARD(FROM_THIS_TOKEN,
  7450.                                          TOKENIZER.ACCEPT_TOKEN);
  7451.          CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7452.                         CURRENT_STATUS.CONTROL_NEST_LEVEL + 1;
  7453.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.CONTROL_NEST_LEVEL;
  7454.          NEW_NEST_REC.KIND_OF_NEST := CONTROL_NEST;
  7455.          NEW_NEST_REC.PARAMETERS   := 0;
  7456.          NEW_NEST_REC.START_TOKEN  := SEARCH_TOKEN;
  7457.  
  7458.      when TOKENIZER.LOOP_TOKEN =>
  7459.          -- FOR or WHILE may be the beginning of the block!
  7460.          -- Find the appropriate (if any) FOR or WHILE token.
  7461.          SEARCH_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN( FROM_THIS_TOKEN );
  7462.          begin
  7463.              while not IS_STATEMENT( SEARCH_TOKEN ) loop
  7464.                 SEARCH_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN( SEARCH_TOKEN );
  7465.              end loop;
  7466.          exception
  7467.              when END_OF_TOKENS =>
  7468.                 null;
  7469.              when others =>
  7470.                 raise;
  7471.          end;
  7472.          CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7473.                         CURRENT_STATUS.CONTROL_NEST_LEVEL + 1;
  7474.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.CONTROL_NEST_LEVEL;
  7475.          NEW_NEST_REC.KIND_OF_NEST := CONTROL_NEST;
  7476.          NEW_NEST_REC.PARAMETERS   := 0;
  7477.          if TOKENIZER.TYPE_OF_TOKEN_IS(SEARCH_TOKEN)=TOKENIZER.WHILE_TOKEN or
  7478.             TOKENIZER.TYPE_OF_TOKEN_IS(SEARCH_TOKEN)=TOKENIZER.FOR_TOKEN then
  7479.                 NEW_NEST_REC.START_TOKEN  := SEARCH_TOKEN;
  7480.          else
  7481.                 NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7482.          end if;
  7483.  
  7484.      when TOKENIZER.THEN_TOKEN =>
  7485.         -- IF is the beginning of the block!
  7486.          SEARCH_TOKEN := SEARCH_BACKWARD(FROM_THIS_TOKEN,  TOKENIZER.IF_TOKEN);
  7487.          CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7488.                             CURRENT_STATUS.CONTROL_NEST_LEVEL + 1;
  7489.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.CONTROL_NEST_LEVEL;
  7490.          NEW_NEST_REC.KIND_OF_NEST := CONTROL_NEST;
  7491.          NEW_NEST_REC.PARAMETERS   := 0;
  7492.          NEW_NEST_REC.START_TOKEN  := SEARCH_TOKEN;
  7493.  
  7494.    -- Package
  7495.      when TOKENIZER.PACKAGE_TOKEN  =>
  7496.          CURRENT_STATUS.PACKAGE_NEST_LEVEL :=
  7497.                        CURRENT_STATUS.PACKAGE_NEST_LEVEL + 1;
  7498.          CURRENT_STATUS.IN_BODY := FALSE;
  7499.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.PACKAGE_NEST_LEVEL;
  7500.          NEW_NEST_REC.KIND_OF_NEST := PACKAGE_NEST;
  7501.          NEW_NEST_REC.PARAMETERS   := 0;
  7502.          NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7503.  
  7504.    -- Subprogram
  7505.      when TOKENIZER.FUNCTION_TOKEN |
  7506.        TOKENIZER.PROCEDURE_TOKEN =>
  7507.          CURRENT_STATUS.PROCEDURE_NEST_LEVEL :=
  7508.                        CURRENT_STATUS.PROCEDURE_NEST_LEVEL + 1;
  7509.          CURRENT_STATUS.IN_BODY := FALSE;
  7510.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.PROCEDURE_NEST_LEVEL;
  7511.          NEW_NEST_REC.KIND_OF_NEST := SUBPROGRAM_NEST;
  7512.          -- Find parameter list!
  7513.          HANDLE_PARAMETER_LIST( FROM_THIS_TOKEN, PARAM_COUNT );
  7514.          NEW_NEST_REC.PARAMETERS   := PARAM_COUNT;
  7515.          NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7516.  
  7517.      when TOKENIZER.TASK_TOKEN =>
  7518.         -- SUBPROGRAM?
  7519.          CURRENT_STATUS.PROCEDURE_NEST_LEVEL :=
  7520.                       CURRENT_STATUS.PROCEDURE_NEST_LEVEL + 1;
  7521.          CURRENT_STATUS.IN_BODY := FALSE;
  7522.          NEW_NEST_REC.LEVEL := CURRENT_STATUS.PROCEDURE_NEST_LEVEL;
  7523.          NEW_NEST_REC.KIND_OF_NEST := SUBPROGRAM_NEST;
  7524.          NEW_NEST_REC.PARAMETERS   := 0;
  7525.          NEW_NEST_REC.START_TOKEN  := FROM_THIS_TOKEN;
  7526.       when others => raise BAD_BLOCK_START;
  7527.     end case;
  7528.  
  7529.     -- Now check to see if nesting has exceeded maximum level
  7530.     case NEW_NEST_REC.KIND_OF_NEST is
  7531.       when SUBPROGRAM_NEST =>
  7532.          if CURRENT_STATUS.PROCEDURE_NEST_LEVEL >
  7533.             STYLE_PARAMETERS.SUBPROGRAM_NESTING_LEVEL then
  7534.                    REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,FROM_THIS_TOKEN,
  7535.                    SUBPROGRAM_NEST_EXCEEDED,
  7536.                    REPORT_GENERATOR.SUBPROGRAM_NESTED_TOO_DEEP);
  7537.                    STYLE_REPORT.SUBPROGRAM_NESTING_EXCEEDING_MAXIMUM :=
  7538.                      STYLE_REPORT.SUBPROGRAM_NESTING_EXCEEDING_MAXIMUM + 1;
  7539.          end if;
  7540.  
  7541.       when PACKAGE_NEST    =>
  7542.          if CURRENT_STATUS.PACKAGE_NEST_LEVEL >
  7543.             STYLE_PARAMETERS.PACKAGE_NESTING_LEVEL then
  7544.                REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,FROM_THIS_TOKEN,
  7545.                    PACKAGE_NEST_EXCEEDED,
  7546.                    REPORT_GENERATOR.PACKAGE_NESTED_TOO_DEEP);
  7547.                STYLE_REPORT.PACKAGE_NESTING_EXCEEDING_MAXIMUM :=
  7548.                    STYLE_REPORT.PACKAGE_NESTING_EXCEEDING_MAXIMUM + 1;
  7549.          end if;
  7550.  
  7551.       when CONTROL_NEST    =>
  7552.          if CURRENT_STATUS.CONTROL_NEST_LEVEL >
  7553.             STYLE_PARAMETERS.CONTROL_NESTING_LEVEL then
  7554.                REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,FROM_THIS_TOKEN,
  7555.                  CONTROL_NEST_EXCEEDED,
  7556.                  REPORT_GENERATOR.CONTROL_STRUCTURE_NESTED_TOO_DEEP);
  7557.                STYLE_REPORT.CONTROL_STRUCTURE_NESTING_EXCEEDING_MAXIMUM :=
  7558.                  STYLE_REPORT.CONTROL_STRUCTURE_NESTING_EXCEEDING_MAXIMUM + 1;
  7559.          end if;
  7560.        when HEADER         => null;
  7561.     end case;
  7562.  
  7563.     NEW_NEST_REC.EXITS := CURRENT_STATUS.EXITS_IN_LOOPS;
  7564.     CURRENT_STATUS.EXITS_IN_LOOPS := 0;
  7565.  
  7566.     -- Now push the Nesting record onto the stack!
  7567.     NEST_STACK.PUSH( NEW_NEST_REC, MISC_NEST_STACK );
  7568.  
  7569.  
  7570.  
  7571.  
  7572.     -- Tag current indent markers;
  7573.     CURRENT_STATUS.BEGIN_INDENT := true;
  7574.                   -- Flag indicating we're at the beginning of a block
  7575.  
  7576.  
  7577. exception
  7578.    when BAD_BLOCK_START =>
  7579.       TEXT_IO.NEW_LINE;
  7580.       TEXT_IO.PUT("Inside ENTERING_BLOCK -- exception:");
  7581.       TEXT_IO.PUT(" A bad start-of-block token has been sent!");
  7582.  
  7583.    when NEST_STACK.STACK_OVERFLOW =>
  7584.       REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE, FROM_THIS_TOKEN,
  7585.                                 OVERFLOW_MSG,
  7586.                                 REPORT_GENERATOR.UNMATCHED_NESTING);
  7587.  
  7588.    when NEST_STACK.STACK_UNDERFLOW =>
  7589.       REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE, FROM_THIS_TOKEN,
  7590.                                 UNDERFLOW_MSG,
  7591.                                 REPORT_GENERATOR.UNMATCHED_NESTING);
  7592.  
  7593.    when others =>
  7594.       TEXT_IO.NEW_LINE;
  7595.       TEXT_IO.PUT("Inside ENTERING_BLOCK -- exception:" );
  7596.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  7597.       TEXT_IO.PUT("While inside line:" );
  7598.       TOKENIZER.LINE_CONTAINING_TOKEN(FROM_THIS_TOKEN, SOURCE_LINE );
  7599.       TEXT_IO.PUT_LINE( DYN.STR( SOURCE_LINE ) );
  7600.  
  7601. end ENTERING_BLOCK_STRUCTURE;
  7602. ::::::::::
  7603. enterings.ada
  7604. ::::::::::
  7605. separate (STYLE_CHECKER)
  7606.  
  7607. procedure ENTERING_SUB_BLOCK_STRUCTURE(FROM_THIS_TOKEN : in TOKENIZER.TOKEN) is
  7608. -- ABSTRACT : This handles the case of intermediate levels of indentation
  7609. --            without really entering a complete block such as
  7610. --            the "else" within and if-then-else-endif statement.
  7611. -- PARAMETER: This token points to the RESERVED WORD which starts a sub-block
  7612.  
  7613.      OLD_NEST_REC : NESTING_RECORD;  -- for temporary POP!
  7614.  
  7615. begin
  7616.     -- All we have to do is allow the indentation to reset!
  7617.     CURRENT_STATUS.BEGIN_INDENT := true;
  7618.     NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  7619.     -- Reset old indentation level!
  7620.     CURRENT_STATUS.CURRENT_INDENT := OLD_NEST_REC.INDENT;
  7621.     -- Restore nesting record!
  7622.     NEST_STACK.PUSH( OLD_NEST_REC, MISC_NEST_STACK );
  7623.  
  7624.     exception
  7625.         when others =>
  7626.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7627.             TEXT_IO.PUT_LINE(" in ENTERING_SUB_BLOCK_STRUCTURE");
  7628.             raise;
  7629. end ENTERING_SUB_BLOCK_STRUCTURE;
  7630. ::::::::::
  7631. exitingbl.ada
  7632. ::::::::::
  7633.  
  7634. separate( STYLE_CHECKER )
  7635.  
  7636. procedure EXITING_BLOCK_STRUCTURE( FROM_THIS_TOKEN : TOKENIZER.TOKEN ) is
  7637. -- ABSTRACT: This cleans up after blocks, and does checks on the block
  7638. --           which can now be done, i.e. loop name, size of block, etc.
  7639. --           blank lines before the block.
  7640. -- PARAMETERS: FROM_THIS_TOKEN is the token signifying the end of block.
  7641. --             This will likely be and "END" word.
  7642. -- ALGORITHM: Look to the Start of the block (The start token should be
  7643. --            on the NEST-Stack).
  7644. --            Figure out the number of statements in the structure (the
  7645. --            nest-record should have a partial count and add to this
  7646. --            the remainder statement count, including the 'end' statement.
  7647. --            Determine the kind of structure.  Record the size (counter)
  7648. --            For subprograms determine whether it is past the limit.
  7649. --            If Control-structure AND large-enough
  7650. --              Check presence of LOOP-NAMES, blank lines around
  7651. --              block.
  7652. --            Reset the indentation counts.
  7653. --            Reset the EXITs count if exiting a LOOP, FOR, or WHILE
  7654. --            Reset the IN_BODY flag if this is a package or subprogram
  7655.  
  7656. use TOKENIZER;
  7657. use STYLE_PARAMETERS;
  7658. package INT_IO is new TEXT_IO.INTEGER_IO( natural );
  7659.  
  7660. LOOKAROUND : TOKENIZER.TOKEN;
  7661. START_BLOCK_TOKEN : TOKENIZER.TOKEN;
  7662. TEMP_TOKEN_TYPE   : TOKENIZER.TOKEN_TYPE;
  7663. BLOCK_SIZE : natural;
  7664. OLD_NEST_REC : NESTING_RECORD;
  7665. LOOKBACK_NEST_REC : NESTING_RECORD;
  7666. SMALL_LIMIT : natural;
  7667. LARGE_LIMIT : natural;
  7668. SOURCE_LINE : DYN.DYN_STRING;
  7669. NO_BLANKS_FLAG : boolean := false;
  7670.  
  7671. SUBPROGRAM_TOO_SMALL    : constant string :=
  7672.      "This subprogram is smaller than the defined limits!";
  7673. SUBPROGRAM_TOO_LARGE    : constant string :=
  7674.      "This subprogram is larger than the defined limits!";
  7675. MISSING_NAME_MSG        : constant string :=
  7676.      "This structure is large enough that it should have a loop-name!";
  7677. NO_BEGINNING_BLANKS_MSG : constant string :=
  7678.      "This structure should have preceeding blank lines to set it off.";
  7679. NO_TRAILING_BLANKS_MSG  : constant string :=
  7680.      "This structure should have following blank lines to set it off.";
  7681. TOO_MANY_EXITS_MSG      : constant string :=
  7682.      "This loop has more EXITS than allowed by the style.";
  7683. UNDERFLOW_MSG           : constant string :=
  7684.  "Too many ENDs.  Check Ada syntax.  Otherwise we didn't catch a block enter!";
  7685.  
  7686. begin
  7687.    NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  7688.    -- Reset to old indentation level
  7689.    CURRENT_STATUS.CURRENT_INDENT := OLD_NEST_REC.INDENT;
  7690.    CURRENT_STATUS.BEGIN_INDENT   := false; -- this should be redundant!
  7691.  
  7692.  
  7693.    -- Check for error in our nesting detection!
  7694.    if OLD_NEST_REC.KIND_OF_NEST = HEADER then
  7695.        -- Try to partially recover by dummying a header record!
  7696.        NEST_STACK.PUSH( OLD_NEST_REC, MISC_NEST_STACK );
  7697.        REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, FROM_THIS_TOKEN,
  7698.         UNDERFLOW_MSG,REPORT_GENERATOR.OTHER);
  7699.    end if;
  7700.  
  7701.    -- Determine the number of statements in the block
  7702.    -- NOTE! We may have to add one here to account for the 'end' statement
  7703.    -- depending on where we check for statements.
  7704.    BLOCK_SIZE := CURRENT_STATUS.CURRENT_STATEMENTS + OLD_NEST_REC.STATEMENTS;
  7705. -- if OLD_NEST_REC.KIND_OF_NEST = CONTROL_NEST then
  7706. --   TEXT_IO.NEW_LINE;
  7707. --   TEXT_IO.PUT("Exiting a control block of ");
  7708. --   INT_IO.PUT( BLOCK_SIZE );
  7709. --   TEXT_IO.PUT_LINE(" statements.");
  7710. -- else
  7711. --   TEXT_IO.NEW_LINE;
  7712. --   LOOKAROUND := NEXT_NON_TRIVIAL_TOKEN( FROM_THIS_TOKEN );
  7713. --   TEXT_IO.PUT("Exiting PACKAGE/SUBPROGRAM " &
  7714. --               DYN.STR(TOKENIZER.EXTERNAL_REPRESENTATION(LOOKAROUND))
  7715. --               & " of ");
  7716. --   INT_IO.PUT( BLOCK_SIZE );
  7717. --   TEXT_IO.PUT_LINE(" statements.");
  7718. -- end if;
  7719.  
  7720.    NEST_STACK.POP( LOOKBACK_NEST_REC, MISC_NEST_STACK );
  7721.    -- Update statement count for enclosing block!
  7722.    LOOKBACK_NEST_REC.STATEMENTS := LOOKBACK_NEST_REC.STATEMENTS + BLOCK_SIZE;
  7723.    CURRENT_STATUS.CURRENT_STATEMENTS := 0;
  7724.    -- Get last IN_BODY status!
  7725.    CURRENT_STATUS.IN_BODY := LOOKBACK_NEST_REC.IN_BODY;
  7726.    -- Restore updated nest-record
  7727.    NEST_STACK.PUSH( LOOKBACK_NEST_REC, MISC_NEST_STACK );
  7728.  
  7729.    -- Find beginning of loop
  7730.    START_BLOCK_TOKEN := OLD_NEST_REC.START_TOKEN;
  7731.  
  7732.    -- Is this loop of significant size?
  7733.    if BLOCK_SIZE > STYLE_PARAMETERS.SMALL_STRUCTURE_SIZE  then
  7734.      ----------------------------------------
  7735.      -- Check for blank lines before the loop.
  7736.      ----------------------------------------
  7737.      -- check preceeding blank line
  7738.      declare
  7739.        PREV_TYPE : TOKENIZER.TOKEN_TYPE;
  7740.      begin -- for overrunning beginning of tokens!
  7741.         LOOKAROUND := SEARCH_BACKWARD( START_BLOCK_TOKEN,TOKENIZER.END_OF_LINE);
  7742.         -- End of previous line.  If this is the only token on the line,
  7743.         -- then this is a blank line and it is O.K.
  7744.         --   NOTE:  Is a comment equivalent to a blank line?
  7745.         --   For now, comments or 'withs' are o.k.
  7746.         PREV_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS(
  7747.                      PREVIOUS_TOKEN( LOOKAROUND ));
  7748.         if PREV_TYPE /= TOKENIZER.END_OF_LINE and
  7749.            PREV_TYPE /= TOKENIZER.COMMENT     then
  7750.            -- look for with's!  (USE is NOT acceptable)
  7751.            LOOKAROUND := SEARCH_BACKWARD( LOOKAROUND,TOKENIZER.END_OF_LINE);
  7752.            LOOKAROUND := TOKENIZER.NEXT_TOKEN(LOOKAROUND);
  7753.            if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAROUND) = TOKENIZER.WITH_TOKEN or
  7754.             (TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAROUND) = TOKENIZER.IDENTIFIER and
  7755.             (TOKENIZER.TYPE_OF_TOKEN_IS(NEXT_TOKEN(LOOKAROUND)) =
  7756.              TOKENIZER.COLON) and
  7757.             (TOKENIZER.TYPE_OF_TOKEN_IS(NEXT_TOKEN(NEXT_TOKEN(LOOKAROUND))) =
  7758.              TOKENIZER.END_OF_LINE) ) then
  7759.  
  7760.                null;
  7761.            else
  7762.                 REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7763.                   NO_BEGINNING_BLANKS_MSG,
  7764.                   REPORT_GENERATOR.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK);
  7765.                 NO_BLANKS_FLAG := true;
  7766.            end if;
  7767.         end if;
  7768.  
  7769.      exception
  7770.         when END_OF_TOKENS =>   -- at beginning of tokens
  7771.                                 -- this shouldn't occur but is is acceptable.
  7772.                 null;
  7773.         when others =>
  7774.                 raise;
  7775.      end;
  7776.  
  7777.      -- check following  blank line
  7778.      begin -- for overrunning beginning of tokens!
  7779.         LOOKAROUND := SEARCH_FORWARD ( START_BLOCK_TOKEN,TOKENIZER.END_OF_LINE);
  7780.         -- End of this line.  If the next token is END_OF_TOKEN
  7781.         -- then this is a blank line and it is O.K.
  7782.         --   NOTE:  Is a comment equivalent to a blank line?
  7783.         if TOKENIZER.TYPE_OF_TOKEN_IS(TOKENIZER.NEXT_TOKEN (LOOKAROUND ))
  7784.            /= TOKENIZER.END_OF_LINE then
  7785.            REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7786.                 NO_TRAILING_BLANKS_MSG,
  7787.                 REPORT_GENERATOR.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK);
  7788.            NO_BLANKS_FLAG := true;
  7789.         end if;
  7790.      exception
  7791.         when END_OF_TOKENS =>   -- at end of tokens
  7792.                                 -- this shouldn't occur but is is acceptable.
  7793.                 null;
  7794.         when others =>
  7795.                 raise;
  7796.      end;
  7797.  
  7798.      if NO_BLANKS_FLAG then
  7799.         STYLE_REPORT.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK :=
  7800.         STYLE_REPORT.MISSING_BLANK_LINES_TO_SET_OFF_A_BLOCK + 1;
  7801.      end if;
  7802.  
  7803.  
  7804.      -- If this is a 'loop' (including for, and while).  If so
  7805.      -- check for loop names!
  7806.      -- and the number of exits!
  7807.      TEMP_TOKEN_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS(START_BLOCK_TOKEN);
  7808.      if TEMP_TOKEN_TYPE = TOKENIZER.LOOP_TOKEN or
  7809.         TEMP_TOKEN_TYPE = TOKENIZER.FOR_TOKEN or
  7810.         TEMP_TOKEN_TYPE = TOKENIZER.WHILE_TOKEN  then
  7811.  
  7812.         if STYLE_PARAMETERS.LOOP_NAME_REQUIRED /=
  7813.            STYLE_PARAMETERS.NOT_REQUIRED then
  7814.            -- Check loop names
  7815.            LOOKAROUND := PREVIOUS_NON_TRIVIAL_TOKEN( START_BLOCK_TOKEN );
  7816.            if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAROUND) /=
  7817.                         TOKENIZER.LEFT_LABEL_BRACKET then
  7818.                 REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7819.                                            MISSING_NAME_MSG,
  7820.                                            REPORT_GENERATOR.LOOP_WITHOUT_NAME);
  7821.                 STYLE_REPORT.LOOPS_WITHOUT_NAMES :=
  7822.                    STYLE_REPORT.LOOPS_WITHOUT_NAMES + 1;
  7823.            end if;
  7824.         end if;
  7825.  
  7826.         -- Check number of exits!
  7827.         if CURRENT_STATUS.EXITS_IN_LOOPS >
  7828.            STYLE_PARAMETERS.NUMBER_OF_LOOP_EXITS then
  7829.              REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7830.                                         TOO_MANY_EXITS_MSG,
  7831.                                         REPORT_GENERATOR.TOO_MANY_EXITS);
  7832.              STYLE_REPORT.INSTANCES_OF_TOO_MANY_EXITS :=
  7833.                 STYLE_REPORT.INSTANCES_OF_TOO_MANY_EXITS + 1;
  7834.         end if;
  7835.         -- reset "exits" counter
  7836.         -- This many not cover all the situations, but with good Ada
  7837.         -- input it should work
  7838.         CURRENT_STATUS.EXITS_IN_LOOPS := OLD_NEST_REC.EXITS;
  7839.  
  7840.      end if;
  7841.  
  7842.    end if;
  7843.  
  7844.    -- If in a Package-block then
  7845.    if OLD_NEST_REC.KIND_OF_NEST = PACKAGE_NEST then
  7846.       CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT := 0;
  7847.    end if;
  7848.  
  7849.    -- If a Subprogram-block then
  7850.    if OLD_NEST_REC.KIND_OF_NEST = SUBPROGRAM_NEST then
  7851.       CURRENT_STATUS.CURRENT_TRAIL_COMMENT_INDENT := 0;
  7852.       -- Check for the limits on subprogram size
  7853.       STYLE_PARAMETERS.AVERAGE_SUBPROGRAM_SIZE (SMALL_LIMIT, LARGE_LIMIT);
  7854.       if BLOCK_SIZE < SMALL_LIMIT then
  7855.          REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7856.                 SUBPROGRAM_TOO_SMALL,
  7857.                 REPORT_GENERATOR.SUBPROGRAM_SIZE_BELOW_MINIMUM);
  7858.          STYLE_REPORT.INSTANCES_OF_SIZE_BELOW_MINIMUM :=
  7859.             STYLE_REPORT.INSTANCES_OF_SIZE_BELOW_MINIMUM + 1;
  7860.       elsif BLOCK_SIZE > LARGE_LIMIT then
  7861.          REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, START_BLOCK_TOKEN,
  7862.                 SUBPROGRAM_TOO_LARGE,
  7863.                 REPORT_GENERATOR.SUBPROGRAM_SIZE_ABOVE_MAXIMUM);
  7864.          STYLE_REPORT.INSTANCES_OF_SIZE_ABOVE_MAXIMUM :=
  7865.             STYLE_REPORT.INSTANCES_OF_SIZE_ABOVE_MAXIMUM + 1;
  7866.       end if;
  7867.    end if;
  7868.  
  7869.    -- Update the nexting counter
  7870.    case OLD_NEST_REC.KIND_OF_NEST is
  7871.      when PACKAGE_NEST =>
  7872.         CURRENT_STATUS.PACKAGE_NEST_LEVEL :=
  7873.           CURRENT_STATUS.PACKAGE_NEST_LEVEL - 1;
  7874.      when SUBPROGRAM_NEST =>
  7875.         CURRENT_STATUS.PROCEDURE_NEST_LEVEL :=
  7876.           CURRENT_STATUS.PROCEDURE_NEST_LEVEL - 1;
  7877.      when CONTROL_NEST =>
  7878.         CURRENT_STATUS.CONTROL_NEST_LEVEL :=
  7879.           CURRENT_STATUS.CONTROL_NEST_LEVEL - 1;
  7880.      when others =>
  7881.        null;
  7882.    end case;
  7883.  
  7884.  
  7885. exception
  7886.  
  7887.    when others =>
  7888.       TEXT_IO.NEW_LINE;
  7889.       TEXT_IO.PUT("Inside EXITING_BLOCK_STRUCTURE   -- exception:" );
  7890.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  7891.       TEXT_IO.PUT_LINE("While inside line:");
  7892.       TOKENIZER.LINE_CONTAINING_TOKEN(FROM_THIS_TOKEN, SOURCE_LINE );
  7893.       TEXT_IO.PUT_LINE( DYN.STR( SOURCE_LINE ) );
  7894.  
  7895. end EXITING_BLOCK_STRUCTURE;
  7896. ::::::::::
  7897. getnextto.ada
  7898. ::::::::::
  7899. separate (STYLE_CHECKER)
  7900.  
  7901. function GET_NEXT_TOKEN_AND_UPDATE_COUNT return TOKENIZER.TOKEN is
  7902. --------------------------------------------------------------------------
  7903. -- Abstract   : This function gets the next "uncounted" token from the
  7904. --              token stream and updates neccessary count information.
  7905. --------------------------------------------------------------------------
  7906.  
  7907. begin
  7908.     if CURRENT_STATUS.CURRENT_LINE = 0 then
  7909.         CURRENT_STATUS.CURRENT_TOKEN := TOKENIZER.FIRST_TOKEN;
  7910.         CURRENT_STATUS.CURRENT_LINE := 1;
  7911.     else
  7912.         CURRENT_STATUS.CURRENT_TOKEN :=
  7913.             TOKENIZER.NEXT_TOKEN(CURRENT_STATUS.CURRENT_TOKEN);
  7914.     end if;
  7915.     STYLE_REPORT.TOKEN_COUNT(
  7916.         TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_STATUS.CURRENT_TOKEN)) :=
  7917.         STYLE_REPORT.TOKEN_COUNT(
  7918.         TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_STATUS.CURRENT_TOKEN)) + 1;
  7919.     return CURRENT_STATUS.CURRENT_TOKEN;
  7920.     exception
  7921.         when TOKENIZER.END_OF_TOKENS =>
  7922.             raise;
  7923.         when others =>
  7924.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  7925.             TEXT_IO.PUT_LINE(" in GET_NEXT_TOKEN_AND_UPDATE_COUNT");
  7926.             raise;
  7927. end GET_NEXT_TOKEN_AND_UPDATE_COUNT;
  7928. ::::::::::
  7929. isstateme.ada
  7930. ::::::::::
  7931.  
  7932. separate (STYLE_CHECKER)
  7933.  
  7934. function IS_STATEMENT(EXAMINED_TOKEN : in TOKENIZER.TOKEN) return boolean is
  7935. -- Determine whether or not this token is the start of a statement.
  7936. -- Cases: If it is one of the following reserved words:
  7937. --     IF (not after an END), END, FOR, USE (except rep specs),
  7938. --     CASE (not after an 'END'), EXIT, GOTO, LOOP (not after an 'END'), TASK,
  7939. --     TYPE, WITH, ABORT, BEGIN, DELAY, ENTRY, RAISE, WHILE, ACCEPT,
  7940. --     PRAGMA, RETURN (not in a function declaration!),
  7941. --     SELECT (not after an 'END'), PACKAGE, SUBTYPE, FUNCTION,
  7942. --     EXCEPTION, PROCEDURE, TERMINATE.
  7943. -- If the token is an IDENTIFIER
  7944. -- AND
  7945. --    The previous (significant) token is:
  7946. --    ;  =>  >>  SELECT, THEN, ELSE, DO, IS, RECORD, OTHERS;
  7947. -- AND
  7948. --    This is not in a (..) pair (in this case this is a parameter declaration)
  7949. -- THEN
  7950. --    The token IS A STATEMENT start.
  7951.  
  7952. use TOKENIZER;
  7953. LOOKAHEAD : TOKENIZER.TOKEN;
  7954.  
  7955. begin -- IS_STATEMENT
  7956.  begin
  7957.  
  7958.    case TOKENIZER.TYPE_OF_TOKEN_IS(EXAMINED_TOKEN) is
  7959.        when IF_TOKEN =>
  7960.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  7961.              if TOKENIZER.TYPE_OF_TOKEN_IS
  7962.                 (LOOKAHEAD) /= TOKENIZER.END_TOKEN then
  7963.                 return true;
  7964.              else
  7965.                 return false;
  7966.              end if;
  7967.        when END_TOKEN => return true;
  7968.        when FOR_TOKEN => return true;
  7969.        when USE_TOKEN => -- except rep specs
  7970.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  7971.              return TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  7972.                     TOKENIZER.IDENTIFIER;
  7973.        when CASE_TOKEN => -- not after an 'end'
  7974.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  7975.              if TOKENIZER.TYPE_OF_TOKEN_IS
  7976.                 (LOOKAHEAD) /= TOKENIZER.END_TOKEN then
  7977.                 return true;
  7978.              else
  7979.                 return false;
  7980.              end if;
  7981.        when EXIT_TOKEN => return true;
  7982.        when GOTO_TOKEN =>  return true;
  7983.        when LOOP_TOKEN => -- not after an 'end'
  7984.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  7985.              if TOKENIZER.TYPE_OF_TOKEN_IS
  7986.                 (LOOKAHEAD) /= TOKENIZER.END_TOKEN then
  7987.                 return true;
  7988.              else
  7989.                 return false;
  7990.              end if;
  7991.        when TASK_TOKEN =>  return true;
  7992.        when TYPE_TOKEN =>  return true;
  7993.        when WITH_TOKEN =>  return true;
  7994.        when ABORT_TOKEN =>  return true;
  7995.        when BEGIN_TOKEN =>  return true;
  7996.        when DELAY_TOKEN =>  return true;
  7997.        when ENTRY_TOKEN =>  return true;
  7998.        when RAISE_TOKEN =>  return true;
  7999.        when WHILE_TOKEN =>  return true;
  8000.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8001.              if TOKENIZER.TYPE_OF_TOKEN_IS
  8002.                   (LOOKAHEAD) /= TOKENIZER.END_TOKEN then
  8003.                 return true;
  8004.              else
  8005.                 return false;
  8006.              end if;
  8007.        when ACCEPT_TOKEN =>  return true;
  8008.        when PRAGMA_TOKEN =>  return true;
  8009. --                    when RECORD_TOKEN =>
  8010.        when RETURN_TOKEN =>
  8011.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8012.              if TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  8013.                  TOKENIZER.RIGHT_PARENTHESIS and
  8014.                 TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  8015.                  TOKENIZER.IDENTIFIER        then
  8016.                 return true;
  8017.              else
  8018.                 return false;
  8019.              end if;
  8020.  
  8021.        when SELECT_TOKEN =>
  8022.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8023.              return TOKENIZER.TYPE_OF_TOKEN_IS ( LOOKAHEAD )
  8024.                  /= TOKENIZER.END_TOKEN;
  8025.        when PACKAGE_TOKEN =>  return true;
  8026.        when SUBTYPE_TOKEN =>  return true;
  8027.        when FUNCTION_TOKEN =>  return true;
  8028.        when SEPARATE_TOKEN =>
  8029.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8030.              -- if declaration -> X : exception; -- then not a statement!
  8031.              return TOKENIZER.TYPE_OF_TOKEN_IS ( LOOKAHEAD )
  8032.                  /= TOKENIZER.IS_TOKEN;
  8033.        when EXCEPTION_TOKEN =>
  8034.              LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8035.              -- if declaration -> X : exception; -- then not a statement!
  8036.              return TOKENIZER.TYPE_OF_TOKEN_IS ( LOOKAHEAD )
  8037.                  /= TOKENIZER.COLON;
  8038.        when PROCEDURE_TOKEN =>  return true;
  8039.        when TERMINATE_TOKEN =>  return true;
  8040.  
  8041.        when IDENTIFIER |
  8042.             NULL_TOKEN =>
  8043.              if LEFT_PARENTHESIS = TOKENIZER.TYPE_OF_TOKEN_IS(
  8044.                                    SEARCH_BACKWARD_FOR_ONE_OF(EXAMINED_TOKEN,
  8045.                                            TOKENIZER.RIGHT_PARENTHESIS,
  8046.                                            TOKENIZER.LEFT_PARENTHESIS) ) then
  8047.                 return false;       -- Inside (..), i.e. parameter declaration
  8048.              else
  8049.                 -- look at the last token
  8050.                 LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(EXAMINED_TOKEN);
  8051.                 case TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) is
  8052.                    when TOKENIZER.SEMICOLON | TOKENIZER.ARROW |
  8053.                         TOKENIZER.RIGHT_LABEL_BRACKET |
  8054.                         TOKENIZER.DO_TOKEN     | TOKENIZER.BEGIN_TOKEN |
  8055.                         TOKENIZER.RECORD_TOKEN | TOKENIZER.OTHERS_TOKEN =>
  8056.                                   return TRUE;
  8057.                    when TOKENIZER.ELSE_TOKEN =>
  8058.                         LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(LOOKAHEAD);
  8059.                         -- OR ELSE identifier is NOT a statement!
  8060.                         return TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  8061.                                TOKENIZER.OR_TOKEN;
  8062.                    when TOKENIZER.THEN_TOKEN =>
  8063.                         LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(LOOKAHEAD);
  8064.                         -- AND ELSE identifier is NOT a statement!
  8065.                         return TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  8066.                                TOKENIZER.AND_TOKEN;
  8067.                    when TOKENIZER.LOOP_TOKEN |
  8068.                         TOKENIZER.SELECT_TOKEN =>
  8069.                         -- could be "end loop identifier"
  8070.                         LOOKAHEAD := PREVIOUS_NON_TRIVIAL_TOKEN(LOOKAHEAD);
  8071.                         return TOKENIZER.TYPE_OF_TOKEN_IS(LOOKAHEAD) /=
  8072.                                TOKENIZER.END_TOKEN;
  8073.                    when TOKENIZER.IS_TOKEN =>
  8074.                         -- true only if at begin of declarations!
  8075.                         return CURRENT_STATUS.BEGIN_INDENT
  8076.                                and not CURRENT_STATUS.IN_BODY;
  8077.                    when others =>
  8078.                                   return false;
  8079.                 end case;
  8080.              end if;
  8081.  
  8082.        when others => return false;
  8083.    end case;
  8084.  
  8085.     exception
  8086.         when END_OF_TOKENS =>
  8087.             return TRUE;
  8088.         when others =>
  8089.             raise;
  8090.  end;
  8091. exception
  8092.         when others =>
  8093.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8094.             TEXT_IO.PUT_LINE(" in IS_STATEMENT");
  8095.             raise;
  8096. end IS_STATEMENT;
  8097. ::::::::::
  8098. literal.ada
  8099. ::::::::::
  8100. separate (STYLE_CHECKER)
  8101.  
  8102. procedure LITERAL_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN) is
  8103. --------------------------------------------------------------------------
  8104. -- Abstract   : This procedure is called when a literal token is encountered.
  8105. --------------------------------------------------------------------------
  8106. -- Parameters : FROM_THIS_TOKEN - token that is a literal
  8107. --------------------------------------------------------------------------
  8108. -- Algorithm  : Update the count of literals
  8109. --              If in a body update literal size information
  8110. --------------------------------------------------------------------------
  8111.  
  8112. begin
  8113.         CURRENT_STATUS.LITERAL_INFORMATION.NUMBER_OF_ITEMS :=
  8114.           CURRENT_STATUS.LITERAL_INFORMATION.NUMBER_OF_ITEMS + 1;
  8115.         if CURRENT_STATUS.IN_BODY then
  8116.            CURRENT_STATUS.LITERAL_INFORMATION.TOTAL_SIZE_OF_ITEMS :=
  8117.               CURRENT_STATUS.LITERAL_INFORMATION.TOTAL_SIZE_OF_ITEMS + 1;
  8118.         end if;
  8119.  
  8120.     exception
  8121.         when others =>
  8122.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8123.             TEXT_IO.PUT_LINE(" in LITERAL_ENCOUNTERED");
  8124.             raise;
  8125. end LITERAL_ENCOUNTERED;
  8126. ::::::::::
  8127. newlineto.ada
  8128. ::::::::::
  8129. separate (STYLE_CHECKER)
  8130.  
  8131. procedure NEW_LINE_TOKEN_ENCOUNTERED(FROM_THIS_TOKEN : in TOKENIZER.TOKEN) is
  8132. --------------------------------------------------------------------------
  8133. -- Abstract   : This procedure is called when an end of line token is
  8134. --              encountered.
  8135. --------------------------------------------------------------------------
  8136. -- Parameters : FROM_THIS_TOKEN - Token that is an end of line
  8137. --------------------------------------------------------------------------
  8138. -- Algorithm  : Check the line length and output an error message if
  8139. --                      neccessary.
  8140. --------------------------------------------------------------------------
  8141.  
  8142.     LINE        : TOKENIZER.LINE_NUM_RANGE;
  8143.     COLUMN      : TOKENIZER.LINE_INDEX_RANGE;
  8144. begin
  8145.     TOKENIZER.TOKEN_POSITION(FROM_THIS_TOKEN,LINE,COLUMN);
  8146.     if COLUMN > STYLE_PARAMETERS.LINE_SIZE then
  8147.         REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,FROM_THIS_TOKEN,
  8148.             "This line exceeds maximum line length",
  8149.             REPORT_GENERATOR.LINE_EXCEEDING_LINE_LENGTH);
  8150.         STYLE_REPORT.NUMBER_OF_LINES_EXCEEDING_LINE_LENGTH :=
  8151.             STYLE_REPORT.NUMBER_OF_LINES_EXCEEDING_LINE_LENGTH + 1;
  8152.     end if;
  8153.     exception
  8154.         when others =>
  8155.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8156.             TEXT_IO.PUT_LINE(" in NEW_LINE_TOKEN_ENCOUNTERED");
  8157.             raise;
  8158. end NEW_LINE_TOKEN_ENCOUNTERED;
  8159. ::::::::::
  8160. nontrivia.ada
  8161. ::::::::::
  8162. separate (STYLE_CHECKER)
  8163.  
  8164. function PREVIOUS_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  8165.     return TOKENIZER.TOKEN is
  8166. --------------------------------------------------------------------------
  8167. -- Abstract   : This function gets the last "non-trivial" token from the
  8168. --              input token.
  8169. --------------------------------------------------------------------------
  8170. -- Parameters : FROM_THIS_TOKEN - starting point in search for a "non-trivial"
  8171. --                                token.
  8172. --------------------------------------------------------------------------
  8173. -- Algorithm  : Starting at input token, go backward in token stream until
  8174. --                 a token that is not considered trivial is encountered.
  8175. --                 Specifically, trivial tokens are end_of_lines, comments,
  8176. --                      end_of_files, and garbage characters
  8177. --------------------------------------------------------------------------
  8178.  
  8179. use TOKENIZER;
  8180.  
  8181.     RETURN_TOKEN : TOKENIZER.TOKEN;
  8182.  
  8183. begin
  8184.         RETURN_TOKEN := TOKENIZER.PREVIOUS_TOKEN(FROM_THIS_TOKEN);
  8185.         while (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.COMMENT)
  8186.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.END_OF_LINE)
  8187.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.END_OF_FILE)
  8188.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) =
  8189.                 TOKENIZER.ANYTHING_ELSE)
  8190.             loop
  8191.                 RETURN_TOKEN := TOKENIZER.PREVIOUS_TOKEN(RETURN_TOKEN);
  8192.             end loop;
  8193.         return RETURN_TOKEN;
  8194.     exception
  8195.         when TOKENIZER.END_OF_TOKENS => raise;
  8196.         when others =>
  8197.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8198.             TEXT_IO.PUT_LINE(" in PREVIOUS_NON_TRIVIAL_TOKEN");
  8199.             raise;
  8200. end PREVIOUS_NON_TRIVIAL_TOKEN;
  8201.  
  8202. separate (STYLE_CHECKER)
  8203.  
  8204.  
  8205. function NEXT_NON_TRIVIAL_TOKEN(FROM_THIS_TOKEN : in TOKENIZER.TOKEN)
  8206.     return TOKENIZER.TOKEN is
  8207. --------------------------------------------------------------------------
  8208. -- Abstract   : This function gets the next "non-trivial" token from the
  8209. --              input token.
  8210. --------------------------------------------------------------------------
  8211. -- Parameters : FROM_THIS_TOKEN - starting point in search for a "non-trivial"
  8212. --                                token.
  8213. --------------------------------------------------------------------------
  8214. -- Algorithm  : Starting at input token, go forward in token stream until
  8215. --                 a token that is not considered trivial is encountered.
  8216. --                 Specifically, trivial tokens are end_of_lines, comments,
  8217. --                      end_of_files, and garbage characters
  8218. --------------------------------------------------------------------------
  8219.  
  8220. use TOKENIZER;
  8221.  
  8222.     RETURN_TOKEN : TOKENIZER.TOKEN;
  8223.  
  8224. begin
  8225.         RETURN_TOKEN := TOKENIZER.NEXT_TOKEN(FROM_THIS_TOKEN);
  8226.         while (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.COMMENT)
  8227.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.END_OF_LINE)
  8228.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) = TOKENIZER.END_OF_FILE)
  8229.           or (TOKENIZER.TYPE_OF_TOKEN_IS(RETURN_TOKEN) =
  8230.                 TOKENIZER.ANYTHING_ELSE)
  8231.             loop
  8232.                 RETURN_TOKEN := TOKENIZER.NEXT_TOKEN(RETURN_TOKEN);
  8233.             end loop;
  8234.         return RETURN_TOKEN;
  8235.     exception
  8236.         when TOKENIZER.END_OF_TOKENS => raise;
  8237.         when others =>
  8238.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8239.             TEXT_IO.PUT_LINE(" in NEXT_NON_TRIVIAL_TOKEN");
  8240.             raise;
  8241. end NEXT_NON_TRIVIAL_TOKEN;
  8242. ::::::::::
  8243. objectnam.ada
  8244. ::::::::::
  8245. separate (STYLE_CHECKER)
  8246.  
  8247. procedure OBJECT_NAME_ENCOUNTERED(OBJECT_NAME_TOKEN : in TOKENIZER.TOKEN) is
  8248. --------------------------------------------------------------------------
  8249. -- Abstract   : This procedure is called when an object_name token is
  8250. --              encountered.
  8251. --------------------------------------------------------------------------
  8252. -- Parameters : OBJECT_NAME_TOKEN - token that is an object_name
  8253. --------------------------------------------------------------------------
  8254. -- Algorithm  : Check case of object name and output error message if
  8255. --                      neccessary.
  8256. --------------------------------------------------------------------------
  8257.  
  8258.     PHYSICAL_REPRESENTATION     : DYN.DYN_STRING :=
  8259.         TOKENIZER.EXTERNAL_REPRESENTATION(OBJECT_NAME_TOKEN);
  8260.  
  8261.     function CASELESS_CHAR( CHAR : in CHARACTER ) return boolean is
  8262.     -- This function checks for characters which should not effect
  8263.     -- the case of a name.
  8264.     -- This includes underscore '_' and numerics.
  8265.     begin
  8266.         return (CHAR = '_') or (CHAR >= '0' and CHAR <= '9');
  8267.     end CASELESS_CHAR;
  8268.  
  8269. begin
  8270.     -- Check case of object name
  8271.     case CURRENT_STATUS.CASE_OF_OBJECT_NAMES is
  8272.         when STYLE_PARAMETERS.NAME_CASE_UPPER =>
  8273.             for I in 1..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8274.                 if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'A') or
  8275.                    (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'Z')) and
  8276.                 not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8277.                     REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,OBJECT_NAME_TOKEN,
  8278.                         "Object name " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8279.                         " should be in upper case",
  8280.                         REPORT_GENERATOR.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER);
  8281.                     STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER :=
  8282.                         STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER + 1;
  8283.                     exit;
  8284.                 end if;
  8285.             end loop;
  8286.         when STYLE_PARAMETERS.NAME_CASE_LOWER =>
  8287.             for I in 1..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8288.                 if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'a') or
  8289.                    (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'z')) and
  8290.                 not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8291.                     REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,OBJECT_NAME_TOKEN,
  8292.                         "Object name " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8293.                         " should be in lower case",
  8294.                         REPORT_GENERATOR.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER);
  8295.                     STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER :=
  8296.                         STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER + 1;
  8297.                     exit;
  8298.                 end if;
  8299.             end loop;
  8300.         when STYLE_PARAMETERS.NAME_CASE_CONSISTANT =>
  8301.         --  This will only be selected if this is the first object name
  8302.         --  encountered, in which case it will be used to decide which case
  8303.         --  to use.
  8304.             if (DYN.STR(PHYSICAL_REPRESENTATION)(1) >= 'a') and
  8305.                (DYN.STR(PHYSICAL_REPRESENTATION)(1) <= 'z') then
  8306.                 CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8307.                     STYLE_PARAMETERS.NAME_CASE_LOWER;
  8308.                 for I in 2..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8309.                     if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'a') or
  8310.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'z')) and
  8311.                    not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8312.                         CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8313.                     STYLE_PARAMETERS.NAME_CASE_ANY;
  8314.                         exit;
  8315.                     end if;
  8316.                 end loop;
  8317.             elsif (DYN.STR(PHYSICAL_REPRESENTATION)(2) >= 'a') and
  8318.                (DYN.STR(PHYSICAL_REPRESENTATION)(2) <= 'z') then
  8319.                 CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8320.                     STYLE_PARAMETERS.NAME_CASE_FIRST_CAPITALIZED;
  8321.                 for I in 3..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8322.                     if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'a') or
  8323.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'z')) and
  8324.                    not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8325.                         CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8326.                         STYLE_PARAMETERS.NAME_CASE_ANY;
  8327.                         exit;
  8328.                     end if;
  8329.                 end loop;
  8330.             else
  8331.                 CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8332.                     STYLE_PARAMETERS.NAME_CASE_UPPER;
  8333.                 for I in 2..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8334.                     if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'A') or
  8335.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'Z')) and
  8336.                    not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8337.                         CURRENT_STATUS.CASE_OF_OBJECT_NAMES :=
  8338.                         STYLE_PARAMETERS.NAME_CASE_ANY;
  8339.                         exit;
  8340.                     end if;
  8341.                 end loop;
  8342.             end if;
  8343.         when STYLE_PARAMETERS.NAME_CASE_FIRST_CAPITALIZED =>
  8344.             if ((DYN.STR(PHYSICAL_REPRESENTATION)(1) < 'A') or
  8345.                (DYN.STR(PHYSICAL_REPRESENTATION)(1) > 'Z')) then
  8346.                 REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,OBJECT_NAME_TOKEN,
  8347.                     "Object name " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8348.                     " should have first character capitalized ",
  8349.                     REPORT_GENERATOR.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER);
  8350.                 STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER :=
  8351.                     STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER + 1;
  8352.             else
  8353.                 for I in 1..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8354.                     if ((DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'A') or
  8355.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'Z')) and
  8356.                    not CASELESS_CHAR(DYN.STR(PHYSICAL_REPRESENTATION)(I)) then
  8357.                        REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,OBJECT_NAME_TOKEN,
  8358.                            "Object name " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8359.                            " should have all but first character in lower" &
  8360.                            " case",
  8361.                         REPORT_GENERATOR.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER);
  8362.                         STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER :=
  8363.                             STYLE_REPORT.INVALID_CASE_FOR_AN_OBJECT_IDENTIFIER
  8364.                             + 1;
  8365.                        exit;
  8366.                     end if;
  8367.                 end loop;
  8368.             end if;
  8369.         when STYLE_PARAMETERS.NAME_CASE_ANY => null;
  8370.     end case;
  8371.     exception
  8372.         when others =>
  8373.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  8374.             TEXT_IO.PUT_LINE(" in OBJECT_NAME_ENCOUNTERED");
  8375.             raise;
  8376. end OBJECT_NAME_ENCOUNTERED;
  8377. ::::::::::
  8378. reservewo.ada
  8379. ::::::::::
  8380.  
  8381. separate (STYLE_CHECKER)
  8382.  
  8383. procedure RESERVE_WORD_ENCOUNTERED(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN) is
  8384. --------------------------------------------------------------------------
  8385. -- Abstract   : This procedure handles reserve word tokens.
  8386. --------------------------------------------------------------------------
  8387. -- Parameters : RESERVE_WORD_TOKEN - token that is a reserve_word
  8388. --------------------------------------------------------------------------
  8389. -- Algorithm  : Check case of reserve word, outputing necessary error
  8390. --                      messages.
  8391. --              Do a case on the reserve word, handling each appropriately
  8392. --------------------------------------------------------------------------
  8393.  
  8394. use TOKENIZER;
  8395. use STYLE_PARAMETERS;
  8396.  
  8397.   PHYSICAL_REPRESENTATION     : DYN.DYN_STRING;
  8398.  
  8399.   LOOK_AHEAD_TOKEN            : TOKENIZER.TOKEN;
  8400.  
  8401.   NAME_TOKEN                  : TOKENIZER.TOKEN;
  8402.  
  8403.   SEPARATOR_TYPE              : TOKENIZER.TOKEN_TYPE;
  8404.  
  8405.   LINE                        : TOKENIZER.LINE_NUM_RANGE;
  8406.   COLUMN                      : TOKENIZER.LINE_INDEX_RANGE;
  8407.  
  8408.   OLD_NEST_REC                : NESTING_RECORD; -- used for manipulation
  8409.                                                 -- of IN_BODY detection!
  8410.  
  8411.   PRAGMA_NAME : DYN.DYN_STRING;
  8412.  
  8413.   PREDEFINED_PRAGMA_MSG         : constant string :=
  8414.        "Transportability Note:  Pragma.";
  8415.   NON_STANDARD_PRAGMA_MSG       : constant string :=
  8416.        "Transportability Note:  Non-Standard Pragma!";
  8417.  
  8418.   ADDRESS_CLAUSE_MSG            : constant string :=
  8419.    "This may be a non-transportable statement (Address Clause).";
  8420.   REPRESENTATION_SPECS_MSG      : constant string :=
  8421.    "This may be a non-transportable statement (Representation Specification).";
  8422.  
  8423.   BAD_PACKAGE_MSG               : constant string :=
  8424.    "This package is on the list of packages to be warned against.";
  8425.  
  8426. function MATCH_PAREN(LEFT_PAREN : in TOKENIZER.TOKEN) RETURN TOKENIZER.TOKEN;
  8427. procedure PACKAGE_TOKEN_HANDLER(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN);
  8428. procedure TASK_TOKEN_HANDLER(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN);
  8429. procedure FUNCTION_PROCEDURE_TOKENS_HANDLER(
  8430.                 RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN);
  8431.  
  8432. function MATCH_PAREN(LEFT_PAREN : in TOKENIZER.TOKEN) RETURN TOKENIZER.TOKEN is
  8433.  
  8434.     NEXT_PAREN  : TOKENIZER.TOKEN := LEFT_PAREN;
  8435.  
  8436. begin
  8437.     NEXT_PAREN := NEXT_TOKEN(NEXT_PAREN);
  8438.     loop
  8439.         NEXT_PAREN := SEARCH_FORWARD_FOR_ONE_OF(NEXT_PAREN,
  8440.             TOKENIZER.RIGHT_PARENTHESIS, TOKENIZER.LEFT_PARENTHESIS);
  8441.         if TYPE_OF_TOKEN_IS(NEXT_PAREN) = TOKENIZER.LEFT_PARENTHESIS then
  8442.             NEXT_PAREN := MATCH_PAREN(NEXT_PAREN);
  8443.         else
  8444.             exit;
  8445.         end if;
  8446.     end loop;
  8447.     return NEXT_PAREN;
  8448. end MATCH_PAREN;
  8449.  
  8450. procedure PACKAGE_TOKEN_HANDLER(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN) is
  8451.  
  8452.     LOOK_AHEAD_TOKEN : TOKENIZER.TOKEN;
  8453.  
  8454. begin
  8455. -- *******************************
  8456. -- When a PACKAGE token is encountered there are five
  8457. --      possibilities of context:
  8458. -- 1. PACKAGE specification
  8459. -- 2. PACKAGE BODY
  8460. -- 3. Rename of a package
  8461. -- 4. Instantiation of a generic package
  8462. -- 5. PACKAGE BODY <name> IS SEPARATE
  8463. -- *******************************
  8464.     LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8465.     if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = TOKENIZER.BODY_TOKEN then
  8466.         -- skip package name (an indentifier)
  8467.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8468.         -- skip IS token
  8469.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8470.         -- get next token after IS
  8471.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8472.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8473.             TOKENIZER.SEPARATE_TOKEN then
  8474.                 -- 2. Package body
  8475.                 CURRENT_STATUS.IN_GENERIC := FALSE;
  8476.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8477.                 -- else
  8478.                 -- 5. package body <name> is separate
  8479.         end if;
  8480.     else
  8481.         -- either
  8482.         -- 1. Package specification
  8483.         -- 3. Rename of a package
  8484.         -- 4. Instantiation of a generic package
  8485.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8486.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8487.             TOKENIZER.RENAMES_TOKEN then
  8488.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8489.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8490.                 TOKENIZER.NEW_TOKEN then
  8491.                 -- 1. Package specification
  8492.                 CURRENT_STATUS.IN_GENERIC := FALSE;
  8493.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8494.             -- else
  8495.             -- 4. Instantiation of a generic package
  8496.             end if;
  8497.         -- else
  8498.         -- 3. Rename of a package
  8499.         end if;
  8500.     end if;
  8501. end PACKAGE_TOKEN_HANDLER;
  8502.  
  8503. procedure TASK_TOKEN_HANDLER(RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN) is
  8504.  
  8505.     LOOK_AHEAD_TOKEN : TOKENIZER.TOKEN;
  8506.  
  8507. begin
  8508.     LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8509.     if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = TOKENIZER.BODY_TOKEN then
  8510.         --  TASK BODY task_simple_name IS ...
  8511.         --  or
  8512.         --  TASK BODY task_simple_name    IS SEPARATE ;
  8513.         -- skip the identifier
  8514.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8515.         -- skip the "IS"
  8516.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8517.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8518.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8519.             TOKENIZER.SEPARATE_TOKEN then
  8520.             ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8521.         end if;
  8522.     else
  8523.         --  TASK [TYPE] identifier
  8524.         --  or
  8525.         --  TASK [TYPE] identifier IS ...
  8526.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = TOKENIZER.TYPE_TOKEN
  8527.             then
  8528.             -- skip the TYPE token
  8529.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8530.         end if;
  8531.         -- skip the identifier
  8532.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8533.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8534.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = TOKENIZER.IS_TOKEN
  8535.             then
  8536.             ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8537.         end if;
  8538.     end if;
  8539. end TASK_TOKEN_HANDLER;
  8540.  
  8541. procedure FUNCTION_PROCEDURE_TOKENS_HANDLER(
  8542.                 RESERVE_WORD_TOKEN : in TOKENIZER.TOKEN) is
  8543.  
  8544.     LOOK_AHEAD_TOKEN : TOKENIZER.TOKEN;
  8545.  
  8546. begin
  8547.     begin
  8548.       LOOK_AHEAD_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8549.     exception
  8550.       when TOKENIZER.END_OF_TOKENS =>
  8551.           LOOK_AHEAD_TOKEN := RESERVE_WORD_TOKEN; -- not a WITH!
  8552.       when others =>
  8553.           raise;
  8554.     end;
  8555.     if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = WITH_TOKEN then
  8556.         --  WITH subprogram_specification [IS__name__or__<>] ;
  8557.         null;
  8558.     else
  8559.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8560.         -- skip the identifier
  8561.         LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8562.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = LEFT_PARENTHESIS then
  8563.             LOOK_AHEAD_TOKEN := MATCH_PAREN(LOOK_AHEAD_TOKEN);
  8564.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8565.         end if;
  8566.         -- for FUNCTION spec, pass by "return type_mark"
  8567.         if TOKENIZER.TYPE_OF_TOKEN_IS(RESERVE_WORD_TOKEN) = FUNCTION_TOKEN then
  8568.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8569.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8570.             while TOKENIZER.TYPE_OF_TOKEN_IS( LOOK_AHEAD_TOKEN ) =
  8571.                 TOKENIZER.PERIOD loop
  8572.                    -- This is an expanded name, i.e. name.name.name
  8573.                    LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8574.                    LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8575.             end loop;
  8576.         end if;
  8577.         if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = RENAMES_TOKEN then
  8578.             --  subprogram_specification  RENAMES subprogram_or_entry_name ;
  8579.             null;
  8580.         elsif TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = IS_TOKEN then
  8581.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8582.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) = NEW_TOKEN then
  8583.                 --  FUNCTION  designator IS
  8584.                 --      NEW generic_function_name [generic_actual_part] ;
  8585.                 -- or
  8586.                 --  PROCEDURE identifier IS
  8587.                 --      NEW generic_procedure_name [generic_actual_part] ;
  8588.                 null;
  8589.             elsif TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8590.                 SEPARATE_TOKEN then
  8591.                 --  subprogram_specification IS SEPARATE ;
  8592.                 null;
  8593.             else
  8594.                 --  subprogram_body  ::=
  8595.                 --      subprogram_specification IS ...
  8596.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8597.                 CURRENT_STATUS.IN_GENERIC := FALSE;
  8598.             end if;
  8599.         else
  8600.         --  Subprogram specification
  8601.             null;
  8602.         end if;
  8603.     end if;
  8604. end FUNCTION_PROCEDURE_TOKENS_HANDLER;
  8605.  
  8606.  
  8607.  
  8608. begin -- RESERVE_WORD_ENCOUNTERED
  8609.  
  8610.     -- Check case of reserve word
  8611.     case CURRENT_STATUS.CASE_OF_RESERVED_WORDS is
  8612.         when STYLE_PARAMETERS.RESERVED_CASE_UPPER =>
  8613.             PHYSICAL_REPRESENTATION :=
  8614.                 TOKENIZER.EXTERNAL_REPRESENTATION(RESERVE_WORD_TOKEN);
  8615.             for I in 1..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8616.                 if (DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'A') or
  8617.                    (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'Z') then
  8618.                     REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,RESERVE_WORD_TOKEN,
  8619.                         "Reserve word " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8620.                         " should be in upper case",
  8621.                         REPORT_GENERATOR.INVALID_CASE_FOR_A_KEYWORD);
  8622.                     STYLE_REPORT.INVALID_CASE_FOR_A_KEYWORD :=
  8623.                         STYLE_REPORT.INVALID_CASE_FOR_A_KEYWORD + 1;
  8624.                     exit;
  8625.                 end if;
  8626.             end loop;
  8627.         when STYLE_PARAMETERS.RESERVED_CASE_LOWER =>
  8628.             PHYSICAL_REPRESENTATION :=
  8629.                 TOKENIZER.EXTERNAL_REPRESENTATION(RESERVE_WORD_TOKEN);
  8630.             for I in 1..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8631.                 if (DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'a') or
  8632.                    (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'z') then
  8633.                     REPORT_GENERATOR.PUT_FLAW(FLAWS_FILE,RESERVE_WORD_TOKEN,
  8634.                         "Reserve word " & DYN.STR(PHYSICAL_REPRESENTATION) &
  8635.                         " should be in lower case",
  8636.                         REPORT_GENERATOR.INVALID_CASE_FOR_A_KEYWORD);
  8637.                     STYLE_REPORT.INVALID_CASE_FOR_A_KEYWORD :=
  8638.                         STYLE_REPORT.INVALID_CASE_FOR_A_KEYWORD + 1;
  8639.                     exit;
  8640.                 end if;
  8641.             end loop;
  8642.         when STYLE_PARAMETERS.RESERVED_CASE_CONSISTANT =>
  8643.         --  This will only be selected if this is the first reserve word
  8644.         --  encountered, in which case it will be used to decide which case
  8645.         --  to use.
  8646.             PHYSICAL_REPRESENTATION :=
  8647.                 TOKENIZER.EXTERNAL_REPRESENTATION(RESERVE_WORD_TOKEN);
  8648.             if (DYN.STR(PHYSICAL_REPRESENTATION)(1) >= 'a') and
  8649.                (DYN.STR(PHYSICAL_REPRESENTATION)(1) <= 'z') then
  8650.                 CURRENT_STATUS.CASE_OF_RESERVED_WORDS :=
  8651.                     STYLE_PARAMETERS.RESERVED_CASE_LOWER;
  8652.                 for I in 2..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8653.                     if (DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'a') or
  8654.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'z') then
  8655.                         CURRENT_STATUS.CASE_OF_RESERVED_WORDS :=
  8656.                     STYLE_PARAMETERS.RESERVED_CASE_ANY;
  8657.                     exit;
  8658.                 end if;
  8659.             end loop;
  8660.             else
  8661.                 CURRENT_STATUS.CASE_OF_RESERVED_WORDS :=
  8662.                     STYLE_PARAMETERS.RESERVED_CASE_UPPER;
  8663.                 for I in 2..DYN.LENGTH(PHYSICAL_REPRESENTATION) loop
  8664.                     if (DYN.STR(PHYSICAL_REPRESENTATION)(I) < 'A') or
  8665.                        (DYN.STR(PHYSICAL_REPRESENTATION)(I) > 'Z') then
  8666.                         CURRENT_STATUS.CASE_OF_RESERVED_WORDS :=
  8667.                     STYLE_PARAMETERS.RESERVED_CASE_ANY;
  8668.                     exit;
  8669.                 end if;
  8670.             end loop;
  8671.             end if;
  8672.         when STYLE_PARAMETERS.RESERVED_CASE_ANY => null;
  8673.     end case;
  8674.     case TOKENIZER.TYPE_OF_TOKEN_IS(RESERVE_WORD_TOKEN) is
  8675.         when ABORT_TOKEN => null;
  8676.         when ABS_TOKEN => null;
  8677.         when ACCEPT_TOKEN => null;
  8678.         when ACCESS_TOKEN => null;
  8679.         when ALL_TOKEN => null;
  8680.         when AND_TOKEN => null;
  8681.         when ARRAY_TOKEN =>
  8682.             -- Array data structuring used!
  8683.             STYLE_REPORT.DATA_STRUCTURING_TYPES_NOT_USED(
  8684.                          REPORT_GENERATOR.ARRAY_TYPES):=false;
  8685.         when AT_TOKEN =>
  8686.             null;
  8687.         when BEGIN_TOKEN =>
  8688.             -- Either a block statement or a "body"
  8689.             if CURRENT_STATUS.IN_BODY then
  8690.                 ENTERING_BLOCK_STRUCTURE( RESERVE_WORD_TOKEN );
  8691.             else
  8692.                 CURRENT_STATUS.IN_BODY := TRUE;
  8693.                 -- Reset this block's IN_BODY status!
  8694.                 NEST_STACK.POP( OLD_NEST_REC, MISC_NEST_STACK );
  8695.                 OLD_NEST_REC.IN_BODY := TRUE;
  8696.                 NEST_STACK.PUSH( OLD_NEST_REC, MISC_NEST_STACK );
  8697.  
  8698.                 ENTERING_SUB_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8699.             end if;
  8700.         when BODY_TOKEN => null;
  8701.         when CASE_TOKEN =>
  8702.             -- Two possibilities
  8703.             -- 1. Start of an CASE statement
  8704.             -- 2. End of an CASE statement
  8705.             LOOK_AHEAD_TOKEN :=
  8706.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8707.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8708.                 TOKENIZER.END_TOKEN) then
  8709.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8710.             end if;
  8711.         when CONSTANT_TOKEN => null;
  8712.         when DECLARE_TOKEN =>
  8713.             CURRENT_STATUS.IN_BODY := FALSE;
  8714.             ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8715.         when DELAY_TOKEN => null;
  8716.         when DELTA_TOKEN => null;
  8717.         when DIGITS_TOKEN => null;
  8718.         when DO_TOKEN =>
  8719.             -- Must accept statement block
  8720.             ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8721.         when ELSE_TOKEN =>
  8722.             -- Two possibilities
  8723.             -- 1. ELSE in an if or select
  8724.             -- 2. OR ELSE in an expression
  8725.             LOOK_AHEAD_TOKEN :=
  8726.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8727.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8728.                 TOKENIZER.OR_TOKEN) then
  8729.                 null;
  8730.             else
  8731.                 STYLE_REPORT.OR_ELSES_USED := TRUE;
  8732.             end if;
  8733.         when ELSIF_TOKEN =>
  8734.                 STYLE_REPORT.ELSIFS_USED   := TRUE;
  8735.         when END_TOKEN =>
  8736.             EXITING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8737.         when ENTRY_TOKEN => null;
  8738.         when EXCEPTION_TOKEN => null;
  8739.             -- Two possibilities
  8740.             -- 1. Exception block
  8741.             -- 2. Exception declaration
  8742.             LOOK_AHEAD_TOKEN :=
  8743.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8744.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8745.                 TOKENIZER.COLON) then
  8746.                 ENTERING_SUB_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8747.                 STYLE_REPORT.EXCEPTIONS_USED := TRUE;
  8748.             end if;
  8749.         when EXIT_TOKEN =>
  8750.             -- Handle exit in loop counting (only possibility)
  8751.             CURRENT_STATUS.EXITS_IN_LOOPS := CURRENT_STATUS.EXITS_IN_LOOPS + 1;
  8752.                 STYLE_REPORT.EXITS_USED    := TRUE;
  8753.         when FOR_TOKEN =>
  8754.             --  Three possibilities exist.
  8755.             --  1. FOR loop
  8756.             --  2. FOR attribute USE ...
  8757.             --  3. FOR name USE
  8758.             --  1 implies entering a block structure, but will be
  8759.             --    handled when the LOOP is encountered
  8760.             --  2 and 3 imply non-transportable things.
  8761.             --    To figure out which one we must look forward two
  8762.             --    tokens.
  8763.             LOOK_AHEAD_TOKEN :=
  8764.                 NEXT_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8765.             LOOK_AHEAD_TOKEN :=
  8766.                 NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8767.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8768.                 TOKENIZER.USE_TOKEN) or
  8769.                (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8770.                 TOKENIZER.TICK) then
  8771.                 -- This is a Representation-specification or address clause.
  8772.                 -- If the current case is:   "USE AT" then this is an
  8773.                 --  address clause, else Rep Spec.
  8774.                 LOOK_AHEAD_TOKEN :=
  8775.                     NEXT_NON_TRIVIAL_TOKEN(LOOK_AHEAD_TOKEN);
  8776.                 if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8777.                    TOKENIZER.AT_TOKEN then
  8778.                     -- Address Clauses
  8779.                     STYLE_REPORT.ADDRESS_CLAUSES :=
  8780.                         STYLE_REPORT.ADDRESS_CLAUSES + 1;
  8781.                     if not STYLE_PARAMETERS.ADDRESS_CLAUSE_ALLOWED then
  8782.                         REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  8783.                            RESERVE_WORD_TOKEN,ADDRESS_CLAUSE_MSG,
  8784.                            REPORT_GENERATOR.ADDRESS_CLAUSE_USED);
  8785.                     end if;
  8786.  
  8787.                 else
  8788.                     -- Representation Specifications
  8789.                     STYLE_REPORT.REPRESENTATION_SPECIFICATIONS :=
  8790.                         STYLE_REPORT.REPRESENTATION_SPECIFICATIONS + 1;
  8791.                     if not STYLE_PARAMETERS.REPRESENTATION_SPECS_ALLOWED then
  8792.                         REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  8793.                            RESERVE_WORD_TOKEN,REPRESENTATION_SPECS_MSG,
  8794.                            REPORT_GENERATOR.REPRESENTATION_SPECIFICATION_USED);
  8795.                     end if;
  8796.                 end if;
  8797.             end if;
  8798.  
  8799.         when FUNCTION_TOKEN =>
  8800.             FUNCTION_PROCEDURE_TOKENS_HANDLER(RESERVE_WORD_TOKEN);
  8801.         when GENERIC_TOKEN => ENTERING_SUB_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8802.                               CURRENT_STATUS.IN_GENERIC := TRUE;
  8803.         when GOTO_TOKEN => null;
  8804.         when IF_TOKEN => null;
  8805.             -- Two possibilities
  8806.             -- 1. Start of an IF statement - will be handled when
  8807.             --         the THEN is encountered
  8808.             -- 2. End of an IF statement - will have been handled on the
  8809.             --         END statement
  8810.         when IN_TOKEN =>
  8811.             LOOK_AHEAD_TOKEN :=
  8812.                 NEXT_NON_TRIVIAL_TOKEN  ( RESERVE_WORD_TOKEN);
  8813.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8814.                 TOKENIZER.OUT_TOKEN then
  8815.                 STYLE_REPORT.IN_OUTS_USED := TRUE;
  8816.             else
  8817.                 STYLE_REPORT.INS_USED     := TRUE;
  8818.             end if;
  8819.             when IS_TOKEN => null;
  8820.         when LIMITED_TOKEN => null;
  8821.         when LOOP_TOKEN =>
  8822.             LOOK_AHEAD_TOKEN :=
  8823.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8824.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8825.                 TOKENIZER.END_TOKEN) then
  8826.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8827.             end if;
  8828.         when MOD_TOKEN => null;
  8829.         when NEW_TOKEN => null;
  8830.         when NOT_TOKEN => null;
  8831.         when NULL_TOKEN => null;
  8832.         when OF_TOKEN => null;
  8833.         when OR_TOKEN =>
  8834.             null;
  8835.         when OTHERS_TOKEN => null;
  8836.         when OUT_TOKEN =>
  8837.             LOOK_AHEAD_TOKEN :=
  8838.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8839.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8840.                 TOKENIZER.IN_TOKEN then
  8841.                 STYLE_REPORT.OUTS_USED   := TRUE;
  8842.             end if;
  8843.         when PACKAGE_TOKEN => PACKAGE_TOKEN_HANDLER(RESERVE_WORD_TOKEN);
  8844.         when PRAGMA_TOKEN => null;
  8845.             -- Handle PRAGMA checks
  8846.             LOOK_AHEAD_TOKEN :=
  8847.                 NEXT_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8848.             PRAGMA_NAME :=
  8849.                 TOKENIZER.EXTERNAL_REPRESENTATION( LOOK_AHEAD_TOKEN );
  8850.             if STYLE_PARAMETERS.IS_A_PREDEFINED_PRAGMA(PRAGMA_NAME) then
  8851.                 REPORT_GENERATOR.INSERT_INTO_LIST(
  8852.                         STYLE_REPORT.PRAGMAS_USED,      PRAGMA_NAME );
  8853.                 if STYLE_PARAMETERS.NOTE_PRAGMAS = STYLE_PARAMETERS.ALL_PRAGMAS
  8854.                     then
  8855.                      REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  8856.                             RESERVE_WORD_TOKEN, PREDEFINED_PRAGMA_MSG,
  8857.                             REPORT_GENERATOR.PRAGMA_USED);
  8858.                 end if;
  8859.             else
  8860.                 REPORT_GENERATOR.INSERT_INTO_LIST(
  8861.                       STYLE_REPORT.NON_STANDARD_PRAGMAS_USED,    PRAGMA_NAME );
  8862.                 if STYLE_PARAMETERS.NOTE_PRAGMAS/= STYLE_PARAMETERS.NONE
  8863.                            then
  8864.                      REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE,
  8865.                             RESERVE_WORD_TOKEN, NON_STANDARD_PRAGMA_MSG,
  8866.                             REPORT_GENERATOR.NON_STANDARD_PRAGMA_USED);
  8867.                 end if;
  8868.             end if;
  8869.  
  8870.         when PRIVATE_TOKEN =>
  8871.             STYLE_REPORT.PRIVATES_USED := TRUE;
  8872.             -- Either a type declaration or private part
  8873.             LOOK_AHEAD_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8874.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8875.                 TOKENIZER.IS_TOKEN) and
  8876.                (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8877.                 TOKENIZER.LIMITED_TOKEN) then
  8878.                 ENTERING_SUB_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8879.             end if;
  8880.         when PROCEDURE_TOKEN =>
  8881.             FUNCTION_PROCEDURE_TOKENS_HANDLER(RESERVE_WORD_TOKEN);
  8882.         when RAISE_TOKEN => null;
  8883.         when RANGE_TOKEN => null;
  8884.         when RECORD_TOKEN => null;
  8885.             -- Either entering or exiting record declaration
  8886.             LOOK_AHEAD_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8887.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8888.                 TOKENIZER.END_TOKEN) then
  8889.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8890.                 -- Record types are used!  This includes their use in
  8891.                 -- representation specifications.
  8892.                 STYLE_REPORT.DATA_STRUCTURING_TYPES_NOT_USED(
  8893.                            REPORT_GENERATOR.RECORD_TYPES) := false;
  8894.             end if;
  8895.         when REM_TOKEN => null;
  8896.         when RENAMES_TOKEN => null;
  8897.         when RETURN_TOKEN => null;
  8898.         when REVERSE_TOKEN => null;
  8899.         when SELECT_TOKEN => null;
  8900.             -- Either entering or exiting select statement
  8901.             LOOK_AHEAD_TOKEN :=
  8902.                 PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8903.             if (TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8904.                 TOKENIZER.END_TOKEN) then
  8905.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8906.             end if;
  8907.         when SEPARATE_TOKEN => null;
  8908.         when SUBTYPE_TOKEN => null;
  8909.         when TASK_TOKEN =>
  8910.             LOOK_AHEAD_TOKEN := SEARCH_FORWARD_FOR_ONE_OF( RESERVE_WORD_TOKEN,
  8911.                                 TOKENIZER.IS_TOKEN,     -- means a block
  8912.                                 TOKENIZER.SEMICOLON);   -- just spec.
  8913.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8914.                 TOKENIZER.IS_TOKEN then
  8915.                 ENTERING_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8916.             end if;
  8917.         when TERMINATE_TOKEN => null;
  8918.         when THEN_TOKEN => null;
  8919.             -- Three possibilities
  8920.             -- 1. AND THEN
  8921.             -- 2. IF <condition> THEN
  8922.             -- 3. ELSIF <condition> THEN
  8923.             -- If 1 then just count it
  8924.             -- If 2 then entering block structure
  8925.             -- If 3 then entering sub block structure
  8926.             --
  8927.             -- check for AND THEN
  8928.             LOOK_AHEAD_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN(RESERVE_WORD_TOKEN);
  8929.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) /=
  8930.                 TOKENIZER.AND_TOKEN then
  8931.                 -- this is either if..then or elsif..then
  8932.                 LOOK_AHEAD_TOKEN := SEARCH_BACKWARD_FOR_ONE_OF(
  8933.                                       RESERVE_WORD_TOKEN,
  8934.                                       TOKENIZER.IF_TOKEN,
  8935.                                       TOKENIZER.ELSIF_TOKEN );
  8936.                 if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN) =
  8937.                     TOKENIZER.IF_TOKEN then
  8938.                         ENTERING_BLOCK_STRUCTURE( RESERVE_WORD_TOKEN );
  8939.                 else
  8940.                         ENTERING_SUB_BLOCK_STRUCTURE( RESERVE_WORD_TOKEN );
  8941.                 end if;
  8942.             else
  8943.                 STYLE_REPORT.AND_THENS_USED := TRUE;
  8944.             end if;
  8945.         when TYPE_TOKEN => TYPE_DECLARATION(RESERVE_WORD_TOKEN);
  8946.         when USE_TOKEN =>
  8947.             null;
  8948.         when WHEN_TOKEN =>
  8949.             -- Possibilities
  8950.             -- 1. Variant record
  8951.             --  WHEN choice[|choice] =>
  8952.             -- 2. Case statement
  8953.             --  same as 1
  8954.             -- 3. Exception handler
  8955.             --  same as 1
  8956.             -- 4. Guarded select
  8957.             --  same as 1
  8958.             -- 5. EXIT [loop_name] WHEN
  8959.             --  EXIT loop_name WHEN-condition
  8960.             -- #1-4 are subblocks.  Distinguished in that they should NOT
  8961.             -- have an identifier before  the WHEN
  8962.             LOOK_AHEAD_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN( RESERVE_WORD_TOKEN);
  8963.             if TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN)
  8964.                /= TOKENIZER.IDENTIFIER then
  8965.                ENTERING_SUB_BLOCK_STRUCTURE(RESERVE_WORD_TOKEN);
  8966.                TOKENIZER.TOKEN_POSITION( RESERVE_WORD_TOKEN, LINE, COLUMN );
  8967.                --  The elements of the 'WHEN' clause must be indented
  8968.                --  further than the WHEN
  8969.                CURRENT_STATUS.CURRENT_INDENT := COLUMN;
  8970.             end if;
  8971.         when WHILE_TOKEN => null;
  8972.         when WITH_TOKEN => null;
  8973.             -- Possibilities
  8974.             -- 1. WITH package[,package|procedure]
  8975.             -- 2. WITH subprogram spec
  8976.             --          (generic parameter declaration)
  8977.             -- If this is withing packages then it is:
  8978.             -- with name [,name];
  8979.             NAME_TOKEN := NEXT_NON_TRIVIAL_TOKEN( RESERVE_WORD_TOKEN );
  8980.             LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN( NAME_TOKEN );
  8981.             SEPARATOR_TYPE   := TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN);
  8982.  
  8983.             while SEPARATOR_TYPE = TOKENIZER.COMMA or
  8984.                   SEPARATOR_TYPE = TOKENIZER.SEMICOLON loop
  8985.                -- Check package name
  8986.                if STYLE_PARAMETERS.IS_A_PROSCRIBED_PACKAGE(
  8987.                         TOKENIZER.EXTERNAL_REPRESENTATION( NAME_TOKEN ) ) then
  8988.                      REPORT_GENERATOR.INSERT_INTO_LIST(
  8989.                         STYLE_REPORT.PACKAGES_PROCEDURES_WITHED,
  8990.                         TOKENIZER.EXTERNAL_REPRESENTATION( NAME_TOKEN ));
  8991.                      -- Add an error class for 'withed packages'
  8992.                      REPORT_GENERATOR.PUT_FLAW( FLAWS_FILE, RESERVE_WORD_TOKEN,
  8993.                         BAD_PACKAGE_MSG, REPORT_GENERATOR.OTHER);
  8994.                end if;
  8995.                exit when SEPARATOR_TYPE = TOKENIZER.SEMICOLON;
  8996.                NAME_TOKEN := NEXT_NON_TRIVIAL_TOKEN( LOOK_AHEAD_TOKEN );
  8997.                LOOK_AHEAD_TOKEN := NEXT_NON_TRIVIAL_TOKEN( NAME_TOKEN );
  8998.                SEPARATOR_TYPE := TOKENIZER.TYPE_OF_TOKEN_IS(LOOK_AHEAD_TOKEN);
  8999.             end loop;
  9000.         when XOR_TOKEN =>
  9001.             STYLE_REPORT.XORS_USED := TRUE;
  9002.         when others => null;
  9003.     end case;
  9004.     exception
  9005.         when others =>
  9006.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  9007.             TEXT_IO.PUT_LINE(" in RESERVE_WORD_ENCOUNTERED");
  9008.             raise;
  9009. end RESERVE_WORD_ENCOUNTERED;
  9010. ::::::::::
  9011. srchbackw.ada
  9012. ::::::::::
  9013. separate( STYLE_CHECKER )
  9014.  
  9015. function SEARCH_BACKWARD ( START_TOKEN : TOKENIZER.TOKEN;
  9016.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE ) return
  9017.                               TOKENIZER.TOKEN is
  9018. --------------------------------------------------------------------------
  9019. -- Abstract   : This searches backward until it finds a given token type
  9020. --              If the beginning of the list is found, the first token is
  9021. --              returned as a 'failed' signal.
  9022. --------------------------------------------------------------------------
  9023. -- Parameters : START_TOKEN - Where to start searching from
  9024. --              GOAL_TYPE   - Type to look for
  9025. --------------------------------------------------------------------------
  9026. use TOKENIZER;
  9027.  
  9028.   CURRENT_TOKEN : TOKENIZER.TOKEN;
  9029. begin
  9030.    CURRENT_TOKEN := TOKENIZER.PREVIOUS_TOKEN( START_TOKEN );
  9031.    while TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE loop
  9032.       CURRENT_TOKEN := TOKENIZER.PREVIOUS_TOKEN( CURRENT_TOKEN );
  9033.    end loop;
  9034.    return CURRENT_TOKEN;
  9035. exception
  9036.    when TOKENIZER.END_OF_TOKENS =>        -- and first-token call?
  9037.       return TOKENIZER.FIRST_TOKEN;
  9038.  
  9039.    when others =>
  9040.       TEXT_IO.NEW_LINE;
  9041.       TEXT_IO.PUT("Inside SEARCH_BACKWARD -- exception:" );
  9042.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  9043. end SEARCH_BACKWARD;
  9044. ::::::::::
  9045. srchbacko.ada
  9046. ::::::::::
  9047. separate(STYLE_CHECKER)
  9048.  
  9049. function SEARCH_BACKWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  9050.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  9051.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  9052.                                              return TOKENIZER.TOKEN is
  9053. use TOKENIZER;
  9054. --------------------------------------------------------------------------
  9055. -- Abstract   : This searches backward until it finds one of the token types
  9056. --              If the beginning of the list is found, the first token is
  9057. --              returned as a 'failed' signal.
  9058. --------------------------------------------------------------------------
  9059. -- Parameters : START_TOKEN   - where to start the search
  9060. --              GOAL_TYPE1    - what to look for
  9061. --              GOAL_TYPE2    - what else to look for
  9062. --------------------------------------------------------------------------
  9063.   CURRENT_TOKEN : TOKENIZER.TOKEN;
  9064.   SOURCE_LINE   : DYN.DYN_STRING;
  9065.  
  9066. begin
  9067.    CURRENT_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN( START_TOKEN );
  9068.    while (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE1) and
  9069.          (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE2) loop
  9070.      CURRENT_TOKEN := PREVIOUS_NON_TRIVIAL_TOKEN( CURRENT_TOKEN );
  9071.    end loop;
  9072.    return CURRENT_TOKEN;
  9073. exception
  9074.  
  9075.    when TOKENIZER.END_OF_TOKENS =>
  9076.       return TOKENIZER.FIRST_TOKEN;
  9077.  
  9078.    when others =>
  9079.       TEXT_IO.NEW_LINE;
  9080.       TEXT_IO.PUT("Inside SEARCH_BACKWARD_FOR_ONE_OF -- exception:" );
  9081.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  9082.       TEXT_IO.PUT_LINE("While in line:");
  9083.       TOKENIZER.LINE_CONTAINING_TOKEN( START_TOKEN, SOURCE_LINE );
  9084.       TEXT_IO.PUT_LINE( DYN.STR( SOURCE_LINE ) );
  9085. end SEARCH_BACKWARD_FOR_ONE_OF;
  9086. ::::::::::
  9087. srchforwa.ada
  9088. ::::::::::
  9089. separate( STYLE_CHECKER )
  9090.  
  9091. function SEARCH_FORWARD ( START_TOKEN : TOKENIZER.TOKEN;
  9092.                           GOAL_TYPE   : TOKENIZER.TOKEN_TYPE ) return
  9093.                               TOKENIZER.TOKEN is
  9094. --------------------------------------------------------------------------
  9095. -- Abstract   : This searches until it finds a given token type
  9096. --              If the END_OF_FILE token is found, it is returned as
  9097. --              a 'fail' signal.
  9098. --------------------------------------------------------------------------
  9099. -- Parameters : START_TOKEN - where to start the search
  9100. --              GOAL_TYPE   - what to look for
  9101. --------------------------------------------------------------------------
  9102. use TOKENIZER;
  9103.  
  9104.   CURRENT_TOKEN : TOKENIZER.TOKEN;
  9105. begin
  9106. -- CURRENT_TOKEN := START_TOKEN; -- start the search with NEXT TOKEN!
  9107.    CURRENT_TOKEN := TOKENIZER.NEXT_TOKEN( START_TOKEN );
  9108.    while TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE loop
  9109.       if TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) = TOKENIZER.END_OF_FILE then
  9110.          exit;  -- just return this token as a 'failed' signal.
  9111.       end if;
  9112.       CURRENT_TOKEN := TOKENIZER.NEXT_TOKEN( CURRENT_TOKEN );
  9113.    end loop;
  9114.    return CURRENT_TOKEN;
  9115. exception
  9116.    when others =>
  9117.       TEXT_IO.NEW_LINE;
  9118.       TEXT_IO.PUT("Inside SEARCH_FORWARD -- exception:" );
  9119.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  9120. end SEARCH_FORWARD;
  9121. ::::::::::
  9122. srchforeo.ada
  9123. ::::::::::
  9124. separate( STYLE_CHECKER )
  9125.  
  9126. function SEARCH_FORWARD_FOR_ONE_OF ( START_TOKEN : TOKENIZER.TOKEN;
  9127.                           GOAL_TYPE1   : TOKENIZER.TOKEN_TYPE;
  9128.                           GOAL_TYPE2   : TOKENIZER.TOKEN_TYPE )
  9129.                                              return TOKENIZER.TOKEN is
  9130. use TOKENIZER;
  9131. --------------------------------------------------------------------------
  9132. -- Abstract   : This searches FORWARD until it finds one of the token types
  9133. --              If the end of the list is found, the END_OF_FILE token is
  9134. --              returned as a 'failed' signal.
  9135. --------------------------------------------------------------------------
  9136. -- Parameters : START_TOKEN - where to start the search
  9137. --              GOAL_TYPE1  - what to look for
  9138. --              GOAL_TYPE2  - what else to look for
  9139. --------------------------------------------------------------------------
  9140.   CURRENT_TOKEN : TOKENIZER.TOKEN;
  9141.   SOURCE_LINE   : DYN.DYN_STRING;
  9142.  
  9143. begin
  9144.    CURRENT_TOKEN := NEXT_NON_TRIVIAL_TOKEN( START_TOKEN );
  9145.    while (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE1) and
  9146.          (TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) /= GOAL_TYPE2) loop
  9147.      if TOKENIZER.TYPE_OF_TOKEN_IS(CURRENT_TOKEN) = END_OF_FILE then
  9148.         exit;  -- just return this token as a 'failed' signal.
  9149.      end if;
  9150.      CURRENT_TOKEN := NEXT_NON_TRIVIAL_TOKEN( CURRENT_TOKEN );
  9151.    end loop;
  9152.    return CURRENT_TOKEN;
  9153. exception
  9154.    when others =>
  9155.       TEXT_IO.NEW_LINE;
  9156.       TEXT_IO.PUT("Inside SEARCH_FORWARD -- exception:" );
  9157.       TEXT_IO.PUT_LINE(CURRENT_EXCEPTION.NAME);
  9158.       TEXT_IO.PUT_LINE("While in line:");
  9159.       TOKENIZER.LINE_CONTAINING_TOKEN( START_TOKEN, SOURCE_LINE );
  9160.       TEXT_IO.PUT( DYN.STR( SOURCE_LINE ) );
  9161. end SEARCH_FORWARD_FOR_ONE_OF;
  9162. ::::::::::
  9163. typedecla.ada
  9164. ::::::::::
  9165. separate (STYLE_CHECKER)
  9166.  
  9167. procedure TYPE_DECLARATION(FROM_THIS_TOKEN : in TOKENIZER.TOKEN) is
  9168.  
  9169. procedure CHECK_FOR_ENUMERATION( AT_THIS_TOKEN : in TOKENIZER.TOKEN ) is
  9170. -- ABSTRACT:  Check whether this TYPE definition is an enumeration type.
  9171. -- PARAMETERS: AT_THIS_TOKEN is pointing to the TYPE_TOKEN for the
  9172. --      type we are going to check.
  9173. -- ALGORITHM:
  9174. --      The relavent cases are:
  9175. --              TYPE name [Discriminant-part] ; -- incomplete type def
  9176. --              TASK TYPE name IS               -- TASK TYPE
  9177. --              TYPE name IS ( <> )             -- generic type
  9178. --              TYPE name [discriminant-part] IS ( enumeration
  9179. --                                              -- enumeration type!
  9180. --                                              -- I hope!
  9181. use TOKENIZER;
  9182.  
  9183. LOOKAHEAD  : TOKENIZER.TOKEN;
  9184. LOOKAROUND : TOKENIZER.TOKEN;
  9185.  
  9186. begin
  9187.     -- find the IS to eliminate the incomplete task type
  9188.     LOOKAHEAD := SEARCH_FORWARD_FOR_ONE_OF(AT_THIS_TOKEN,
  9189.                 TOKENIZER.SEMICOLON,  TOKENIZER.LEFT_PARENTHESIS );
  9190.  
  9191.     if TOKENIZER.TYPE_OF_TOKEN_IS( LOOKAHEAD ) = TOKENIZER.LEFT_PARENTHESIS then
  9192.        -- Inside here is NOT an incomplete type def.
  9193.        if TOKENIZER.TYPE_OF_TOKEN_IS(PREVIOUS_NON_TRIVIAL_TOKEN(
  9194.                AT_THIS_TOKEN ) ) /= TOKENIZER.TASK_TOKEN THEN
  9195.           -- Inside her if it is NOT a TASK TYPE
  9196.           if TOKENIZER.TYPE_OF_TOKEN_IS(
  9197.              NEXT_NON_TRIVIAL_TOKEN( LOOKAHEAD ) )
  9198.              /= TOKENIZER.BOX   then
  9199.                 -- Inside here if NOT a generic type.
  9200.  
  9201.                 -- This should be an enumeration type!
  9202.                 STYLE_REPORT.DATA_STRUCTURING_TYPES_NOT_USED(
  9203.                         REPORT_GENERATOR.ENUMERATION_TYPES) := false;
  9204.  
  9205.           end if;
  9206.        end if;
  9207.     end if;
  9208.  
  9209.     exception
  9210.         when others =>
  9211.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  9212.             TEXT_IO.PUT_LINE(" in CHECK_FOR_ENUMERATION");
  9213.             raise;
  9214. end CHECK_FOR_ENUMERATION;
  9215.  
  9216. begin
  9217.         CHECK_FOR_ENUMERATION( FROM_THIS_TOKEN );
  9218.     exception
  9219.         when others =>
  9220.             TEXT_IO.PUT(CURRENT_EXCEPTION.NAME);
  9221.             TEXT_IO.PUT_LINE(" in TYPE_DECLARATION");
  9222.             raise;
  9223. end TYPE_DECLARATION;
  9224. ::::::::::
  9225. STYLE_CMP.CLI
  9226. ::::::::::
  9227. --
  9228. --    Compilation order for STYLE_CHECKER
  9229. --
  9230. --
  9231. --    DYN (dynamic string) package (specification and body)
  9232. dyn.ada
  9233. --    FILE_HANDLING package specification
  9234. file_spec.ada
  9235. --    TOKENIZER package specification
  9236. tokenizer_spec.ada
  9237. --    STYLE_PARAMETERS package specification
  9238. style_param_spec.ada
  9239. --    REPORT_GENERATOR package specification
  9240. report_gen_spec.ada
  9241. --    STACK_PACKAGE package (specification and body)
  9242. stack_package.ada
  9243. --    two packages from spelling checker
  9244. --       TOKEN_DEFINITION package (specification and body)
  9245. token_definition.ada
  9246. --       MANAGER package (specification and body)
  9247. manager.ada
  9248. --    HELP package specification
  9249. help_file_spec.ada
  9250. --    COMMAND_LINE_HANDLER package (specification and body)
  9251. command_line.ada
  9252. --    HELP_UTILITY packages
  9253. HELP_SPEC.ADA
  9254. HELP_BODY.ADA
  9255. HELP_DIS_ALL.ADA
  9256. HELP_EXIT.ADA
  9257. HELP_FIND.ADA
  9258. HELP_GET.ADA
  9259. HELP_INIT.ADA
  9260. HELP_ME.ADA
  9261. HELP_MENU.ADA
  9262. HELP_PROMPT.ADA
  9263. HELP_RESET.ADA
  9264. HELP_TEXT.ADA
  9265. --
  9266. --
  9267. -- And now the bodies...
  9268. --
  9269. --    HELP package body
  9270. help_file_body.ada
  9271. --    FILE_HANDLING package body
  9272. file_body.ada
  9273. --    TOKENIZER package body and all its seperate files
  9274. tokenizer_body.ada
  9275. insert.ada
  9276. is_a_reserved_word.ada
  9277. reserved_word.ada
  9278. next_character.ada
  9279. next_identifier.ada
  9280. build_tokens.ada
  9281. line_containing.ada
  9282. tree_root.ada
  9283. --    STYLE_PARAMETERS package body
  9284. style_param_body.ada
  9285. --    REPORT_GENERATOR package body
  9286. report_gen_body.ada
  9287. --    Main procedure (STYLE_CHECKER) and all its seperate files
  9288. style_checker.ada
  9289. begin_of_line_indent.ada
  9290. check_statements.ada
  9291. check_end_of_blocks.ada
  9292. check_the_style.ada
  9293. check_for_attribute.ada
  9294. check_object_names.ada
  9295. check_universal.ada
  9296. comment_token.ada
  9297. current_token.ada
  9298. entering_block.ada
  9299. entering_sub_block.ada
  9300. exiting_block.ada
  9301. get_next_token.ada
  9302. is_statement.ada
  9303. literal.ada
  9304. new_line_token.ada
  9305. non_trivial_token.ada
  9306. object_name.ada
  9307. reserve_word.ada
  9308. search_backward.ada
  9309. search_back_one_of.ada
  9310. search_forward.ada
  9311. search_fore_one_of.ada
  9312. type_declaration.ada
  9313. ::::::::::
  9314. STYLE.CLI
  9315. ::::::::::
  9316. delete/l=???.delete.log.tmp command_line.txt
  9317. write/l=command_line.txt (%1-%)
  9318. x style_checker
  9319. delete/l=???.delete.log.tmp command_line.txt
  9320. delete ???.delete.log.tmp
  9321. ::::::::::
  9322. style_help.ini
  9323. ::::::::::
  9324. 1 HELP
  9325. -- The text file used by the HELP_UTILITY Package is required to have a
  9326. -- particular format. If the file is not in this format, an exception will be
  9327. -- raised.  The following explains the required format.
  9328. --
  9329. -- COMMENTS: Comments may be embeded in the text file. All comments are ignored
  9330. -- when the file is read into memory. A text line is considered a comment if
  9331. -- the first and second characters of the line are minus signs ( -- ).
  9332. --
  9333. -- TOPICS: The first non-comment text line MUST begin with the digit 1 in
  9334. -- column one. This number is the topic level. In other words, text (as
  9335. -- defined below) cannot be found in the text file before a topic is found to
  9336. -- which the text can be associated. Topics are those subjects for which
  9337. -- information is being provided. A topic name may contain any printable
  9338. -- character except blanks.  Embedded blanks are NOT allowed in a topic name.
  9339. -- This will not be flagged as an error but the name will be truncated at
  9340. -- the first blank. All letters in the name must be capitals. It is not
  9341. -- required to have a space separating the topic level from the topic name.
  9342. -- Any line beginning with a digit will be considered a topic line.
  9343. --
  9344. -- SUBTOPICS: A topic may have subtopics. Subtopics are denoted by having a
  9345. -- level exactly one greater than the associated topic level. Subtopics
  9346. -- follow the same rules as topics in all other aspects. There is no
  9347. -- constraint (other than a lack of memory) on the number of subtopic levels.
  9348. --
  9349. -- TEXT: All text lines not beginning with two consecutive minus signs or a
  9350. -- digit will be considered text.
  9351. --
  9352. -- The text file is saved exactly as the user sees it (including blank lines)
  9353. -- with the follow exceptions:
  9354. --
  9355. --       o topic and subtopic names have leading blanks stripped off
  9356. --       o if the topic or subtopic name is longer than one half the screen
  9357. --         size, it may be truncated when a menu of information is output
  9358. --       o if the text line is longer than the screen size, the text line is
  9359. --         truncated before output
  9360. --       o the text file lines are assumed to be eighty characters maximum.
  9361. This is the Help Facility for the Style Checker. More information
  9362. on specific topics may be obtained by entering the leading portion
  9363. of the name of any of the topics.
  9364.  
  9365. To get the list of topics available at any time, enter a ? at
  9366. the prompt.
  9367.  
  9368. To list the information on all topics below the current topic, enter
  9369. a * at the prompt.
  9370.  
  9371. To exit the Help Facility, enter a <CR> for each level of information.
  9372.  
  9373. 2 INSTALLATION
  9374. The original STYLE_CHECKER program was written on a Data General MV-10000
  9375. using the Data General Ada Development Environment.  No features specific
  9376. to the ADE were used and moving the system to another computer should be
  9377. simple.
  9378.  
  9379. The command file invoking the tool may have to be rewritten, two or three
  9380. file names specific to the installation may have to be changed, and the
  9381. system will have to be compiled.
  9382.  
  9383. Moving the system should require no rewriting of the Ada source code (other
  9384. than changing three internal file names).
  9385.  
  9386. For more information on modifying the Style Checker, see the MAINTENANCE
  9387. section of HELP.
  9388.  
  9389. 3 COMPILATION
  9390. The Style-Checker consists of nine packages.  They are:
  9391.  
  9392. DYN              -- Dynamic strings
  9393. STACK_PACKAGE    -- Generic stacks
  9394. COMMAND_LINE     -- Get parameters from the command line
  9395. HELP_PACKAGE     -- Display Help Information
  9396. FILE_HANDLING    -- System dependencies & front-end file handling
  9397. TOKENIZER        -- Convert Ada to tokens
  9398. STYLE_PARAMETERS -- Deliver parameters defining the style
  9399. REPORT_GENERATOR -- Produce style outputs
  9400. STYLE_CHECKER    -- Main Procedure
  9401.  
  9402. Some of these packages contain both specifications and bodies.  Also, there
  9403. are 'separate' procedures for some of the packages.  Because of the
  9404. dependencies, the individual files must be compiled in specific order.
  9405.  
  9406. The order of compilation is defined in a file in the Style Checker
  9407. Source directory.  That file is named "COMPILE.CLI".
  9408.  
  9409. 3 SPECIFIC_FILE_NAMES
  9410. There are three hard-coded file names in the tool which may have to be
  9411. modified.  These three file name constants are all located in the
  9412. FILE_HANDLING package.  They may have to be modified to reflect where
  9413. the Style Checker is installed, or to conform to the host's file-naming
  9414. conventions.
  9415.  
  9416. COMMAND_LINE_FILE_NAME -- This file will contain the parameters from
  9417.   the command line which invokes the tool.  The default name given is
  9418.   COMMAND_LINE.TXT (on the MV-10000).  This file will be created in
  9419.   the users current directory as the tool is run.  SEE the HELP section
  9420.   on the COMMAND_FILE and on Style Checker OPERATION.
  9421.   This is defined in the FILE_HANDLING body, currently named:
  9422.   FILE_BODY.ADA
  9423.  
  9424. HELP_FILE_NAME -- This file points to the HELP file.  This file will
  9425.   be located in the Style Checker source directory.
  9426.   The current name is "STYLE_HELP.INI".
  9427.   This is defined in the FILE_HANDLING specifications, currently named:
  9428.   FILE_SPEC.ADA
  9429.  
  9430. STYLE_DICTIONARY_NAME -- This file points to the DICTIONARY file.
  9431.   Currently this feature IS NOT USED.  This constant exists for future
  9432.   expansion.
  9433.   The current name is "STYLE_DICTIONARY.INI".
  9434.   This is defined in the FILE_HANDLING specifications, currently named:
  9435.   FILE_SPEC.ADA
  9436.  
  9437. 3 COMMAND_FILE
  9438. A command procedure is used to invoke the Style Checker.  This is written in
  9439. the host's command language.  Its function is to process the parameters
  9440. on the command line and call the Style Checker.
  9441.  
  9442. The command line parameters are passed to the Style Checker by putting them
  9443. into a text file.  Each parameter becomes a single line in the file.  This
  9444. file's name is predefined and corresponds to the COMMAND_LINE_FILE_NAME
  9445. defined in the FILE_HANDLING package.
  9446.  
  9447. The command procedure supplied with the Style Checker is written for the
  9448. Data General command language.  This file is in the Style Checker's
  9449. source directory and the file is "STYLE.CLI".
  9450.  
  9451. The parameters on the command line are the files to be style-checked.  The
  9452. parameters are explained more in the OPERATION section of HELP
  9453.  
  9454. 2 OPERATION
  9455. The Style Checker is invoked by the command procedure and is given parameters
  9456. describing the input files.  On the Data General this looks like:
  9457.  
  9458. STYLE FILE1 FILE2 FILE3
  9459.  
  9460. More information on the format of the command line is below in
  9461. STYLE_CHECKER_COMMAND
  9462.  
  9463. The Style Checker will read in the set of input
  9464. files.  This input will be style-checked.  The results will be written out
  9465. as two files, a flaws file, listing individual stylistic errors, and a style
  9466. report, which summarizes the style of the document.
  9467.  
  9468. The output file names are derived from the name of the FIRST input file.
  9469.  
  9470. 3 STYLE_CHECKER_COMMAND
  9471. The command to invoke the Style Checker contains the phrase for the command
  9472. procedure (on the Data General this is "STYLE") and one or more file
  9473. descriptors.
  9474.  
  9475. The file descriptor is either a file name, or a file name preceeded by a
  9476. "@" character.
  9477.  
  9478. If it is a file name, that file contains the Ada source code to be style-
  9479. checked.
  9480.  
  9481. If the file name is preceeded by a "@", then this file is a list, containing
  9482. the names of other files to be style checked.  This is useful when the user
  9483. wishes to check a large number of files.  For example, if the file
  9484. "FILE_HANDLING.DIS" contains the following:
  9485. COMMAND_LINE.ADA
  9486. FILE_SPEC.ADA
  9487. FILE_BODY.ADA
  9488. <EOF>
  9489.  
  9490. then these three files could be style checked by the following command:
  9491.  
  9492. STYLE @FILE_HANDLING.DIS
  9493.  
  9494. These "list" files are ordinary text files.  They can contain nested references
  9495. to other "list" files.  This can be nested up to 10 levels deep.
  9496.  
  9497. An example of this can be seen as the following file:
  9498. @FILE_HANDLING.DIS
  9499. DYN.ADA
  9500. @TOKENIZER
  9501. HELP.ADA
  9502. STACK.ADA
  9503. @REPORT_GEN.DIS
  9504. @STYLE_PARAM.DIS
  9505. @STYLE_CHECKER.DIS
  9506. <EOF>
  9507.  
  9508. If the above were used as input to the Style Checker, it would check
  9509. the three files and the other files listed in the five "list" files.
  9510.  
  9511. 3 INPUT_FILES
  9512. The input to the Style Checker is a set of input files which are concatenated
  9513. together and treated as if they were one input file.
  9514.  
  9515. The input is expected to be syntactically correct Ada.  If the input is not
  9516. correct Ada, the Style Checker will in many cases be able to check the
  9517. input anyway, but this may cause erroneous results.
  9518.  
  9519. There are some cases where incorrect Ada input will cause the Style Checker
  9520. to malfunction.  A major example of this is the nesting of blocks.  If the
  9521. input program contains too many "END" statements, the Style Checker currently
  9522. is unable to recover and will usually fail, producing only a partial "flaws"
  9523. list and no "report" output.
  9524.  
  9525. Because of this, it is best to be sure the input is correct Ada before trying
  9526. to check its style.
  9527.  
  9528. 3 OUTPUT_FILES
  9529. The Style Checker produces two output files.  The names of these files are
  9530. derived from the first real input file (not from the "list" files).  The
  9531. file name extension is stripped from the input file name.  The extension
  9532. "FLW" is added to create the "flaws" file name.  The extension "STY" is
  9533. added to create the "report" file name.
  9534.  
  9535. EXAMPLE:  If the Style Checker were invoked by:
  9536.  
  9537. STYLE TEST1.ADA COPYFILE.ADA ANOTHER.ADA
  9538.  
  9539. then the output file names would be:
  9540. TEST1.FLW, and
  9541. TEST1.STY.
  9542.  
  9543. Examples of "flaws" and "report" files can be found in the Style Checker
  9544. Testing directory.  For each test file, there will be a "flaw" file and
  9545. a "report" file.
  9546.  
  9547.  
  9548. 4 FLAWS_FILE
  9549. The "flaws" file contains notices of individual style mistakes.  Each notice
  9550. includes the style "flaw" which was found, and a copy of the source line in
  9551. which the flaw was located.
  9552.  
  9553. Discussions of the individual flaws reported can be found under the discussion
  9554. of INDIVIDUAL_PARAMETERS in HELP.
  9555.  
  9556. OUTPUT DISCREPANCIES:
  9557.      Be aware that the output of flaws is generated when the flaw is discovered.
  9558. This may not be when the line is first parsed.  For example, the size of loops,
  9559. or procedures is not known until the end of the loop or procedure, so the
  9560. flaws file will contain output flaws from the middle of the loop, and then
  9561. later show the start of the loop and say that this loop is too large.
  9562.  
  9563. Statements which span lines will not be completely be printed when a flaw
  9564. is reported.  The Style Checker trys to print the line containing the erroneous
  9565. part of the statement, but it does not always succeed.
  9566.  
  9567. If one particular error occurs too many times, it would be repetitive to
  9568. continue listing that error.  Accordingly, there is a parameter,
  9569. "ERRORS_TO_LIST", which puts a limit on how many times an individual error
  9570. is output.  The default setting is 5.  This means that if the input contained
  9571. many indentation errors, only the first 5 would be noted in the flaws file.
  9572. The other indentation errors would still be included as part of the style
  9573. report file.
  9574.  
  9575. 4 REPORT_FILE
  9576. The "report" file contains a summary of the style problems encountered in
  9577. the source.  This is a combined summary for the total input.  If reports are
  9578. desired for individual files, they will have to be style-checked separately.
  9579.  
  9580. The style report indicates
  9581.   A. Counts of flaws
  9582.   B. Limits exceeded -- this is typically the average of some check
  9583.      mode over the entire input, such as average length of names.
  9584.   C. Notes of other style issues -- this may be notes that the input
  9585.      does not show use of some Ada feature such as enumeration types.
  9586.  
  9587. If the line is showing a style error, then the line is flagged by putting
  9588. a "*" before the line.  If the line contains minor problems, or
  9589. nothing is wrong, but the user might be able to improve, the line
  9590. is flagged with a "!".
  9591.  
  9592. The individual sections of the style report are in subsections below.
  9593. These describe the meaning of the information.  The actual results depend
  9594. on the definition of the style parameters.  For more information on the actual
  9595. style checked, see the HELP section on INDIVIDUAL_PARAMETERS.
  9596.  
  9597. 5 NAMING_CONVENTIONS
  9598. Example:
  9599. >-------------------------------------------------------------------------
  9600. > *   Invalid Case for an Object Identifier           133      Errors
  9601. > *   Invalid Case for a Keyword                        3      Errors
  9602. >     Name Segment Size (Separated         Desired     <5      Characters
  9603. >                 by Underscores)          Actual       4.1    Characters
  9604. >     Average Name Size                    Desired     >5      Characters
  9605. >                                          Actual      15.5    Characters
  9606. >-------------------------------------------------------------------------
  9607.  
  9608. This section deals with words.  The instances of names being typed in the
  9609. wrong case are shown.  Also shown is the average length of names,
  9610. and a measurement showing whether enough underscores are used.
  9611.  
  9612. See Help information on INDIVIDUAL_PARAMETERS for explanations of the
  9613. following:
  9614.  
  9615. SHORT_WORD     RESERVED_CASE  OBJECT_CASE    AVE_NAME_LEN
  9616. UNDERSCORES    UNDERSCORE_SIZE
  9617.  
  9618.  
  9619. 5 PHYSICAL_LAYOUT
  9620. >-------------------------------------------------------------------------
  9621. > *   Occurrences of More Than One Statement/Line      51      Errors
  9622. > *   Inconsistant Indentation                        596      Errors
  9623. > *   Missing Blank Lines to Set Off a Block          113      Errors
  9624. > *   Loops Without Names                              12
  9625. >-------------------------------------------------------------------------
  9626. This section relates to readability.  Most of these are self-explanatory.
  9627. Note that structures (packages, loops, etc.) may be required to have blank
  9628. lines surrounding them, and loops should have loop-names.  These are only
  9629. required when the given structure is larger than a limit defined in the style.
  9630.  
  9631. See Help information on INDIVIDUAL_PARAMETERS for explanations of the
  9632. following:
  9633.  
  9634. SMALL_STRUCTURE     STATEMENT_LINE      INDENT_TYPES        INDENT_COMMENTS
  9635. BLANK_LINES         LOOP_NAMES
  9636.  
  9637.  
  9638. 5 INFORMATION_HIDING
  9639. >-------------------------------------------------------------------------
  9640. >     Percent of Literals In Body          Desired   < 10.0%
  9641. > *                                        Actual      79.7%
  9642. >     Percent of Universal Types           Desired   < 40.0%
  9643. >                                          Actual      20.0%
  9644. > !   Data Structuring Types NOT Used
  9645. >                                          Array Types
  9646. >                                          Enumeration Types
  9647. >                                          Record Types
  9648. > !   No Attributes are Used
  9649. > !   Ada-Specific Features NOT used
  9650. >                                          AND THEN
  9651. >                                          OR ELSE
  9652. >                                          EXITS
  9653. >                                          XOR
  9654. >                                          ELSIF
  9655. >                                          EXCEPTION
  9656. >                                          IN parameters
  9657. >                                          OUT parameters
  9658. >                                          IN OUT parameters
  9659. >-------------------------------------------------------------------------
  9660. This measures the number of literals (both string and numeric) in the body
  9661. with respect to those in the declaration sections.  Also the percentage of
  9662. universal type (integer, etc.) compared to other type is measured.  The use
  9663. of data structuring types and Ada-specific features is also detected.  The
  9664. next line indicates that the input uses no attributes.
  9665.  
  9666. The "!" shows that the user might profit by learning more about these features.
  9667.  
  9668. See Help information on INDIVIDUAL_PARAMETERS for explanations on the
  9669. following:
  9670.  
  9671. PERCENT_LITERALS    PERCENT_UNIVERSALS       ATTRIBUTE_CHECK
  9672. DATA_STRUCTURES
  9673.  
  9674. 5 MODULARITY
  9675. >-------------------------------------------------------------------------
  9676. >     Average Number of Parameters         Range     1..8      Parameters
  9677. > *     Instances of parameters below minimum           6
  9678. >       Instances of parameters above maximum           0
  9679. >     Average Subprogram Size              Range  10..200      Statements
  9680. > *     Instances of size below minimum                 6
  9681. > *     Instances of size above maximum                 2
  9682. >     Loops with too many exit statements               0      Instances
  9683. >     Control Structure Nesting            Maximum      8
  9684. >                                          Exceeded     0      Instances
  9685. >     Package Nesting                      Maximum      2
  9686. >                                          Exceeded     0      Instances
  9687. >     Subprogram Nesting                   Maximum      4
  9688. >                                          Exceeded     0      Instances
  9689. >-------------------------------------------------------------------------
  9690.  
  9691. Size and nesting are used as measurements of modularity.  There are limits
  9692. on the size of subprograms, and on how many parameters they have.
  9693. There is a limit on the number of exits a loop may have.  The last six lines
  9694. show the nesting of the input.
  9695.  
  9696. See Help information on INDIVIDUAL_PARAMETERS for explanations on
  9697. the following :
  9698.  
  9699. SUBPROGRAM_SIZE     SUBPROGRAM_PARAMETERS    NUMBER_OF_LOOP_EXITS
  9700. CONTROL_NESTING     PACKAGE_NESTING          SUBPROGRAM_NESTING
  9701.  
  9702. 5 COMMENT_USAGE
  9703. >-------------------------------------------------------------------------
  9704. >     Number of Comments                              606      Comments
  9705. >     Average Comment Size                 Desired    >15      Characters
  9706. >                                          Actual      38.8    Characters
  9707. >-------------------------------------------------------------------------
  9708. The comment size is recorded so that the program cannot be fooled by
  9709. simply adding a large number of blank comments.
  9710.  
  9711. See Help information on INDIVIDUAL_PARAMETERS for COMMENT_SIZE explanation.
  9712.  
  9713. 5 TRANSPORTABILITY
  9714. >-------------------------------------------------------------------------
  9715. > *   Number of Lines Exceeding Line Length            69
  9716. >     Address Clauses                                   0
  9717. >     Representation Specifications                     0
  9718. >     PRAGMA'S used:
  9719. >                                          INLINE
  9720. >     Non-Standard PRAGMA's Used
  9721. >                                          MAIN
  9722. >     Packages/Procedures WITHed
  9723. >                                          CURRENT_EXCEPTION
  9724. >-------------------------------------------------------------------------
  9725.  
  9726. This notes features which may be untransportable.  "Pragma's used" lists
  9727. pragmas defined in the LRM.  "Non-Standard pragma's" lists other pragmas.
  9728. "Packages withed" lists any packages in the input which are defined in the
  9729. style as "proscribed" packages.  This typically includes non-transportable
  9730. packages such as SYSTEM, UNCHECKED_CONVERSION, etc.
  9731. This section might also show the presence of any characters which are not
  9732. in the allowable set defined in the style.  The final item is a notice
  9733. describing the use of Ada features which are not available in other languages.
  9734. This is intended to provide information for the user to see what could be
  9735. learned to improve their programs.
  9736.  
  9737. See Help information on INDIVIDUAL_PARAMETERS for explanations on the
  9738. following:
  9739.  
  9740. LINE_SIZE           REPRESENTATION_SPECS     ADDRESS_CLAUSE
  9741. PRAGMAS             PREDEFINED_PRAGMA        PROSCRIBED_PACKAGE
  9742. CHARACTER_SET
  9743.  
  9744.  
  9745. 5 KEYWORD_USAGE
  9746. >Used Keyword    Allowed         Restriction     Occurrences     Percentage
  9747. >-------------------------------------------------------------------------
  9748. >     AT        yes             0.0%            0               0.0%
  9749. >     DO        yes             0.0%            0               0.0%
  9750. >     IF        yes             0.0%          258              13.5%
  9751. >     IN        yes             0.0%           74               3.9%
  9752. .
  9753. .
  9754. .
  9755. >     GOTO      yes             5.0%            0               0.0%
  9756. >     LOOP      yes             0.0%           60               3.1%
  9757. >--------------------------------------------------------------------------
  9758.  
  9759. This optional list shows the Ada reserved words, whether the style allows
  9760. their use, and how often they were used in the input.
  9761.  
  9762. See Help on INDIVIDUAL_PARAMETERS for KEYWORD_PARAMETERS explanation.
  9763.  
  9764.  
  9765. 2 INDIVIDUAL_PARAMETERS
  9766. The parameters defining the limits of the Ada style are  defined
  9767. in the body of the FILE_HANDLING package.  In that body the default values
  9768. are specified as defaults for the individual parameter variables.  There
  9769. is also a procedure SET_STYLE_PARAMETERS which sets the actual values for
  9770. the style.
  9771.  
  9772. It is expected that any local changes to the style parameters will be done in
  9773. the SET_STYLE_PARAMETERS procedure, so that the original defaults remain
  9774. unchanged.
  9775.  
  9776.  
  9777. 3 ERRORS_TO_LIST
  9778. To  avoid  redundantly  repeating  instances of detected errors,
  9779. the ' errors-to-list'  parameter  restricts  the number of times
  9780. any  one  error  is  listed.  This  means, for example, only the
  9781. first 5 times the user forgot to use loop-names would be listed.
  9782. Other  occurences  of  each  individual error  would be counted,
  9783. and the total instances of the error would be noted on the style
  9784. summary.
  9785.  
  9786. 3 OUTPUT_KEYWORD_LIST
  9787. To shorten the output, the Style Checker may be set to not  print
  9788. the  complete  summary of reserved words used.   The options are:
  9789.      ALL_KEYS       Print all keywords
  9790.      USED           Print only those keywords which are used
  9791.      NOT_USED       Print only those keywords which are not used
  9792.      ERRORS         Print those keywords whose usage is in error
  9793.      NONE           Do not print keywords
  9794.  
  9795. 3 SHORT_PROGRAM
  9796. The  Short-Program  parameter  measures  the size of subprograms
  9797. which  are  too  small  to  be  considered  significant for some
  9798. measures.  The  parameter  is an integer, N, where programs less
  9799. than N statements are 'short'.
  9800.  
  9801. Short  programs  may  not  contain enough  information  to  make
  9802. valid  judgements  on  whether  'restricted'  reserved words are
  9803. used  too  often.  These  measurements  will still be made,  but
  9804. the user should be aware that they not be significant.
  9805.  
  9806. 3 SHORT_WORD
  9807. The  Short-Word  parameter  defines  the size, in characters, of
  9808. 'small'  words.  Words this small or smaller are detected as too
  9809. small  to   effectively  identify  the   object's  contents.  In
  9810. addition,  words this short will not be checked for the presence
  9811. of underscores,  or  checked for abbreviations.
  9812.  
  9813. 3 SHORT_STRUCTURE
  9814. Some sections of  code are too short to be  reasonably  checked.
  9815. For  example,  loop names may be required on control structures,
  9816. but  it  is  not  reasonable to require them on very short loops
  9817. (such   as   a   1-statement   loop).   Anything   which     has
  9818. 'short-structure'  statements  or less is small and doesn't have
  9819. to be checked for loop-names, blank  lines around the loop, etc.
  9820.  
  9821. 3 RESERVED_CASE
  9822. Reserved-Case is an  enumeration object  indicating  the defined
  9823. style of  presenting  reserved  words as all capitals, all lower
  9824. case, or mixed cases.   The values are:
  9825.  
  9826.       *  ReservedCaseUpper:  Reserved words  must  be  upper
  9827.          case.
  9828.  
  9829.       *  ReservedCaseLower:  Reserved words  must  be  lower
  9830.          case.
  9831.  
  9832.       *  ReservedCaseConsistant:   Reserved  word  case   is
  9833.          determined  by  the case of the FIRST reserved word
  9834.          encountered.  All subsequent words must be the same
  9835.          case.
  9836.  
  9837.       *  ReservedCaseAny:  Reserved words  do  not  have  to
  9838.          follow any convention.
  9839.  
  9840. 3 OBJECT_CASE
  9841. Object-Case is  an  enumeration  object indicating  the  defined
  9842. style  of  presenting names as all capitals,  all lower case, or
  9843. mixed cases.  The values are:
  9844.  
  9845.       *  NameCaseUpper:  Names must be upper case.
  9846.  
  9847.       *  NameCaseLower:  Names must be lower case.
  9848.  
  9849.       *  NameCaseFirstCapitalized:   The  first  letter   of
  9850.          names  must  be  capitalized.  The name may contain
  9851.          other capitalized letters such as when  a  name  is
  9852.          the    concatenation   of   several   words   like:
  9853.          LinesOfCode or GeometricMean.
  9854.  
  9855.       *  NameCaseConsistant:  Name case is determined by the
  9856.          case of the FIRST name encountered.  All subsequent
  9857.          words must be the same case.
  9858.  
  9859.       *  NameCaseAny:  Names  do  not  have  to  follow  any
  9860.          convention.
  9861.  
  9862. 3 AVE_NAME_LEN
  9863. This parameter is a  positive  integer used to judge whether the
  9864. user is replying on too many small names.  If the average length
  9865. of names over the whole program is less than this value,  then a
  9866. style  flaw  has occured.  The user is told he is using too many
  9867. short names.
  9868.  
  9869. 3 UNDERSCORES
  9870. This is a flag indicating  whether underscores should be checked
  9871. for.  On some computers or for some  systems underscores may not
  9872. be a desirable feature.  If the  flag is TRUE,  the presence and
  9873. frequency of underscores will be  checked  as  detailed  in  the
  9874. HELP on underscore-size.  If the flag is FALSE, underscores will
  9875. be ignored.   Note that FALSE does not mean that underscores are
  9876. incorrect.
  9877.  
  9878. 3 UNDERSCORE_SIZE
  9879. If underscores are required, the style  checker  will  check the
  9880. average number of characters not  separated  by underscores in a
  9881. program.    If   the   resultant   average   is   greater   then
  9882. underscore-size, the user has too few  underscores in his names.
  9883.  
  9884. The specific method of checking this is as follows:
  9885.  
  9886.      A.  If the  name  is  short  (less  than  or  equal  to
  9887.          'small-word' characters) it is ignored.
  9888.  
  9889.      B.  Count the characters in each segment of  the  name,
  9890.          where segments are separated by underscores.
  9891.  
  9892.      C.  Average these counts over the whole program.
  9893.  
  9894.      D.  If   the   program   average   is   greater    than
  9895.          underscore-size, an error report is made.
  9896.  
  9897. 3 VOWEL_FREQUENCY
  9898. While  abbreviations  save typing time, it is easy to abbreviate
  9899. too much, and for maintenance programmers,  who  are  not at all
  9900. familiar with a program, any abbreviations  are  confusing.  The
  9901. heuristic used to try to detect abbreviations is the  percentage
  9902. of  vowels   WRT consonants in  the  names.   Since  the  common
  9903. forms  of abbreviation  involve striping out the vowels, if  the
  9904. names have  too  few   vowels,   the   programmer   is  probably
  9905. abbreviating.
  9906.  
  9907. The program calculates the percentage of vowels versus the total
  9908. number of letters in the word.  These percentages  are  averaged
  9909. over the entire program and if  this  percentage  is  under  the
  9910. 'Vowel-Frequency'  parameter,  a  style  flaw is noted.
  9911.  
  9912. 3 SPELLING_REQUIRED
  9913. This function is currently only existant as a stub.
  9914. It is eventually intended to check individual  name  segments  of
  9915. words  against  a project dictionary to see if the words used are
  9916. allowable.
  9917.  
  9918. 3 INDENT_TYPES
  9919. This  is  a  flag  indicating whether  to check  for  consistant
  9920. indenting in the declaration portions of a program. If TRUE, the
  9921. style  checker  will  note  inconsistant   indentation   in  the
  9922. declarations  as a style flaw.
  9923.  
  9924. 3 INDENT_COMMENTS
  9925. This  is  a  flag indicating  whether to  check  for  consistant
  9926. indenting  in the comments which follow  statements  on the same
  9927. line.
  9928.  
  9929.      NULL;               -- This is a trailing comment
  9930.  
  9931. If  TRUE,  the  style checker will note inconsistant indentation
  9932. in the trailing comments as a style flaw.
  9933.  
  9934. 3 BLANK_LINES
  9935. To physically separate control structure  on  the  listing,  the
  9936. style  may  require  blank lines to  be  placed  around  control
  9937. structures.  If  this  parameter is TRUE, the absence  of  blank
  9938. lines  around  control structures will be noted as a style flaw.
  9939. For example:
  9940.  
  9941.      NULL;                            -- Previous statement
  9942.  
  9943.      LOOP                             -- Blank line before and after
  9944.         NULL;                         -- this loop
  9945.      END LOOP;
  9946.  
  9947.      NULL;                            -- Next statement(s)
  9948.  
  9949. 3 LOOP_NAMES
  9950. To help locate the beginning and end of  structures,  the  style
  9951. may require loop names at the start  and  end.  These  names are
  9952. required if the parameter is TRUE.
  9953.  
  9954. 3 COMMENT_SIZE
  9955. To  prevent  coders  from entering empty comments  to  fool  the
  9956. style checker, the average size of comments (in characters) over
  9957. the  whole  program  must  be greater  than  'comment-size' or a
  9958. style flaw will be noted.
  9959.  
  9960. 3 PERCENT_LITERALS
  9961. The use of literal values such as numeric constants  or  strings
  9962. in   the   body  of a   program   significantly   reduces    the
  9963. maintainability  of the  program. Literals should preferably  be
  9964. in   the  declaration  to  give  them   greater  visibility  and
  9965. modifiability.   This  parameter is the maximum allowable amount
  9966. of literals allowed in the program  bodies.   The  number is the
  9967. percentage of literals in the  bodies  compared  to all literals
  9968. in the program.
  9969.  
  9970. If the program's percentage of literals in the bodies is greater
  9971. than 'percent-literals', then a style flaw is noted.
  9972.  
  9973. 3 PERCENT_UNIVERSAL
  9974. Programmers which  are  used to restricted  data  typing such as
  9975. Fortran's integer and real, may not initially use the freedom to
  9976. create types which  Ada allows. In  addition,  some  programmers
  9977. may only use the universal types (integer) out of laziness.   To
  9978. discourage the exclusive  use  of universal types, the style can
  9979. check the  percentage  of  universal  types  used as compared to
  9980. other user-defined numeric types.
  9981.  
  9982. If  the  average  percentage  of universal types is greater than
  9983. 'percent-universal', a style flaw will be noted.
  9984.  
  9985. 3 DATA_STRUCTURES
  9986. Programmers use to more  primitive languages  such as Fortran or
  9987. assembler  may  not  have  learned to use the  data  structuring
  9988. facilities  of  Ada  such  as records  or enumeration types.  If
  9989. the 'data-structures' flag is TRUE, the style checker will  note
  9990. whether  these  data  structuring  facilities  are  used  in the
  9991. program. If they are not used, a the style report will note that
  9992. fact  and  suggest  the   programmer   investigate  Ada's   data
  9993. structuring abilities.
  9994.  
  9995. 3 ATTRIBUTE_CHECK
  9996. The use of attributes is important for such purposes as limiting the
  9997. number of constants in the program.  The style definition includes
  9998. a parameter which tells the style checker to detect the use of
  9999. attributes in the input.  If the input contains NO attributes, a
  10000. flag is raised indicating potential for improvement by learning the
  10001. use of attributes.
  10002.  
  10003. 3 SUBPROGRAM_SIZE
  10004. The size of a subprogram  directly impacts its understandability
  10005. and   maintainability.  The  style  will   define  limits  on  a
  10006. subprogram's size, both  large and small.  This parameter is two
  10007. numbers limiting the size, in statements of  a  subprogram.   If
  10008. these  limits   are violated, a style flaw is noted.
  10009.  
  10010. 3 SUBPROGRAM_PARAMETERS
  10011. The number of parameters to a subprogram impacts its modularity.
  10012. The  style  defines  limits  on the number of parameters.  These
  10013. are both maximum and minimum limits.   The  applicable  function
  10014. will  return  two  numbers giving the limits for parameters.  If
  10015. limits are violated, a style flaw is noted.
  10016.  
  10017. 3 CONTROL_NESTING
  10018. If programs are nested too deeply this may indicate improper modularity.
  10019. This parameter indicates that nesting of control structures too deeply
  10020. be flagged as a style flaw.
  10021.  
  10022.  
  10023. 3 PACKAGE_NESTING
  10024. If programs are nested too deeply this may indicate improper modularity.
  10025. This parameter indicates that nesting of packages too deeply
  10026. be flagged as a style flaw.
  10027.  
  10028. 3 SUBPROGRAM_NESTING
  10029. If programs are nested too deeply this may indicate improper modularity.
  10030. This parameter indicates that nesting of subprograms too deeply
  10031. be flagged as a style flaw.
  10032.  
  10033. 3 NUMBER_OF_LOOP_EXITS
  10034. Structured programming limits the possible exits from a structure.
  10035. This parameter defines the limit on the number of exits.  If a
  10036. loop has more exit statements than defined by this parameter, a
  10037. style flaw is noted.
  10038.  
  10039. 3 LINE_SIZE
  10040. In transporting a program to a different machine, the new machine may impose
  10041. different limits on the size of lines.  This parameter allows the style
  10042. to flag lines which are longer than a certain size.  In this way, those
  10043. line which might have to be changed for transportability can be easily found.
  10044.  
  10045. 3 CHARACTER_SET
  10046. The LRM defines two different classes of characters.  The BASIC characters
  10047. are those required to be processable by any Ada system.  The GRAPHIC
  10048. characters are the additional normal characters which are usually available.
  10049. Since some machines may not support all characters, the style checker will
  10050. note special characters which may have to be changed for transportability.
  10051. This can also catch non-printing character which have inadvertently gotten
  10052. into the source.
  10053.  
  10054. The character classes allowed are (see LRM for complete definition):
  10055.      BASIC        -- Upper case letters, 0..9, punctuation
  10056.      GRAPHIC      -- Lower case letters, special punctuation:
  10057.                      ! $ % ? @ [ \ ] ^ ` { } ~
  10058.      EXTENDED     -- Other non-graphic ASCII characters, <ESC>, etc.
  10059.  
  10060. 3 REPRESENTATION_SPECS
  10061. Representation specifications are very non-transportable features in Ada.
  10062. The Style Checker can be told by this parameter to locate and flag uses
  10063. of representation specifications.  If this parameter is FALSE then
  10064. representation specifications are not allowed and are flagged as flaws.
  10065.  
  10066. 3 ADDRESS_CLAUSE
  10067. Address clauses are very non-transportable features in Ada.
  10068. The Style Checker can be told by this parameter to locate and flag uses
  10069. of address clauses.  If this parameter is FALSE then
  10070. address clauses are not allowed and are flagged as flaws.
  10071.  
  10072. 3 PRAGMAS
  10073. Pragmas may be compiler-dependant parts of a system.  This parameter tells
  10074. whether to flag occurrences of pragmas in the input.  The possible values
  10075. may be:
  10076.      ALL                 -- flag all pragmas
  10077.      SYSTEM-DEPENDENT    -- flag pragmas not defined in the LRM
  10078.      NONE                -- do not flag pragmas
  10079.  
  10080. 3 PREDEFINED_PRAGMA
  10081. This is not a parameter, but is a definition of which pragmas are defined
  10082. in the LRM.  This is a function called which returns TRUE if the input
  10083. pragma-name is defined in the LRM.  There are 14 predefined pragmas.
  10084.  
  10085. 3 PROSCRIBED_PACKAGE
  10086. The use of some packages depend highly on the supporting host.  These
  10087. packages may make transporting a system difficult.  The Style Checker
  10088. can be provided with a list of the packages which the user wants flagged.
  10089. These packages are called PROSCRIBED PACKAGES.
  10090.  
  10091. Typical packages might include UNCHECKED_CONVERSION, and SYSTEM.
  10092.  
  10093. These packages are defined by an array of strings naming the proscribed
  10094. packages.  The array is PROSCRIBED.
  10095.  
  10096. This is a special parameter in that its value must be changed in the
  10097. default definition of the parameter.  All other parameters are changed
  10098. in the SET_STYLE_PARAMETERS procedure.
  10099.  
  10100. 3 KEYWORD_PARAMETERS
  10101. The use of  each  Ada  reserved  word  may  be limited for style
  10102. purposes.  Each reserved word is specified separately. The usage
  10103. classes are
  10104.  
  10105.       *  Prohibited:  Any use at all is a style flaw.
  10106.  
  10107.       *  Restricted:   This  requires  a   second,   numeric
  10108.          parameter which is the maximum allowed frequency of
  10109.          the reserved word.  The number is the percentage of
  10110.          statements  which  may  contain  the reserved word.
  10111.          For  example,  if  the  number  is  0.05  then  the
  10112.          reserved  word  cannot  appear more than five times
  10113.          per 100 statements.
  10114.  
  10115.       *  Unlimited:  The reserved word can be used freely.
  10116.  
  10117.  
  10118.  
  10119. 2 STYLE_ISSUES_IN_GENERAL
  10120. This tool has been designed to provide a level of style checking to
  10121. give the user confidence that his system is following good guidelines.
  10122.  
  10123. Since few programmers agree completely on the correct way to structure code,
  10124. much of the style checking is dependent on a set of style parameters delivered
  10125. by the STYLE_PARAMETERS package.  These parameters are changable by altering
  10126. values in the body of that package.  For instructions on altering the style
  10127. values, see CHANGING_STYLE_PARAMETERS, below.
  10128.  
  10129. It should be noted that because of the wide variety in possible styles, some
  10130. compromises had to be made.  For example, checking indentation of comments
  10131. has basically been eliminated since so many people use different styles.
  10132. There are a few areas where it is possible to violate the "correct style" and
  10133. this program will not catch the error.  Usually this is the case so that
  10134. other correct style instances will not be caught along with the bad.
  10135.  
  10136. 3 CHANGING_STYLE_PARAMETERS
  10137. Inside the STYLE_PARAMETERS package, the values of the parameters are
  10138. defined in two different places.  In the declarations for the BODY, the
  10139. default values are set.  These default values should not be changed so as
  10140. to provide a standard basic style.  (There is one exception noted below.)
  10141.  
  10142. The actual values are set in the SET_STYLE_PARAMETERS procedure which is
  10143. called in the STYLE_PARAMETERS body.  This is where new style parameter
  10144. values should be changed.
  10145.  
  10146. Most of the possible values are obvious, such as POSITIVE or BOOLEAN values.
  10147. There are a few special enumeration types used.  These types are defined
  10148. in the STYLE_PARAMETERS specification.
  10149.  
  10150. Exception: The only style parameter which should be changed in the
  10151. declarations rather than in the SET_STYLE_PARAMETERS procedure is
  10152. the PROSCRIBED variable, defining those packages which are to be
  10153. flagged as undesirable packages.  This should be changed in the
  10154. declaration itself.
  10155.  
  10156.  
  10157. 2 MAINTENANCE
  10158. For maintenance information look under the HELP file for INSTALLATION
  10159. instructions, or look at the MAINTENANCE manual in the documentation
  10160. directory
  10161.  
  10162.