CR.MOD 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. (* =========================================== *)
  2. (* (c) 1990-1992 Clarion Software Corporation *)
  3. (* =========================================== *)
  4. MODULE CR;
  5. (* Prints a cross-reference table of Modula-2 program. All user-defined
  6. words are listed in alphabetical order together with the count of
  7. the number of references and a list of all reference line numbers.
  8. This program will cross reference the words in comments as well
  9. as those in the source code.
  10. *)
  11. IMPORT Table, IO, Str, Lib, FIO;
  12. (* Modula-2 Keywords and Predefined Identifiers *)
  13. CONST
  14. KeyWords =
  15. 'BY DO IF IN OF OR TO AND DIV END FOR MOD NOT SET VAR CASE ELSE '+
  16. 'EXIT FROM GOTO LOOP THEN TYPE WITH ARRAY BEGIN CONST ELSIF LABEL '+
  17. 'UNTIL WHILE EXPORT IMPORT MODULE RECORD REPEAT RETURN FORWARD '+
  18. 'POINTER PROCEDURE DEFINITION IMPLEMENTATION QUALIFIED CLASS'+
  19. 'SHORTINT INTEGER LONGINT BOOLEAN CHAR BYTE SHORTCARD CARDINAL '+
  20. 'WORD LONGCARD LONGWORD REAL LONGREAL ADDRESS SHORTADDR BITSET '+
  21. 'TRUE FALSE NIL PROC HALT NULLPROC CAP ABS CHR FLOAT HIGH ODD '+
  22. 'TRUNC VAL DEC EXCL INC INCL SIZE VSIZE ADR ORD NEW DISPOSE MAX MIN ';
  23. TYPE
  24. SymTabPtr = POINTER TO SymTab;
  25. CLASS SymTab(Table.Element); (* Symbol table entry *)
  26. Count : INTEGER; (* Reference count *)
  27. LRef : Table.TABLE; (* Cross-Ref List *)
  28. Name : ARRAY [0..30] OF CHAR; (* This word *)
  29. VIRTUAL PROCEDURE Compare( p : Table.ElementPtr ) : INTEGER;
  30. END SymTab ;
  31. CLASS IMPLEMENTATION SymTab;
  32. VIRTUAL PROCEDURE Compare( p : Table.ElementPtr ) : INTEGER;
  33. BEGIN
  34. RETURN Str.Compare(Name,SymTabPtr(p)^.Name);
  35. END Compare;
  36. BEGIN
  37. END SymTab ;
  38. TYPE
  39. LinTabPtr = POINTER TO LinTab;
  40. CLASS LinTab(Table.Element); (* Line number table entry *)
  41. RefLn : INTEGER; (* Line number *)
  42. VIRTUAL PROCEDURE Compare( p : Table.ElementPtr ) : INTEGER;
  43. END LinTab ;
  44. CLASS IMPLEMENTATION LinTab; (* Line number table entry *)
  45. VIRTUAL PROCEDURE Compare( p : Table.ElementPtr ) : INTEGER;
  46. BEGIN
  47. IF (RefLn < LinTabPtr(p)^.RefLn) THEN
  48. RETURN -1;
  49. ELSIF (RefLn > LinTabPtr(p)^.RefLn) THEN
  50. RETURN 1;
  51. ELSE
  52. RETURN 0;
  53. END;
  54. END Compare;
  55. BEGIN
  56. END LinTab ;
  57. VAR
  58. ni : CARDINAL; (* Column count for printing routines *)
  59. PROCEDURE PrintLineNo( p : Table.ElementPtr );
  60. (* Prints the line-number information for 'p', which is of
  61. CLASS 'LinTab'.
  62. *)
  63. VAR
  64. t, l : CARDINAL;
  65. BEGIN
  66. (* These first few lines count the number of digits in 'p.val' and
  67. then check if there's enough room on the line for it.
  68. *)
  69. t := LinTabPtr(p)^.RefLn;
  70. l := 1;
  71. REPEAT
  72. INC(l);
  73. t := t DIV 10;
  74. UNTIL t=0; (* l := number of digits in line number *)
  75. IF (ni < l) THEN (* Not enough room *)
  76. ni := 40;
  77. IO.WrLn;
  78. IO.WrCharRep(' ',37);
  79. END;
  80. IO.WrInt(LinTabPtr(p)^.RefLn,1);
  81. IO.WrChar(' ');
  82. DEC(ni,l);
  83. END PrintLineNo;
  84. PROCEDURE PrintSymbol( r : Table.ElementPtr );
  85. (* Prints the symbol, definition line and cross-reference lines
  86. of the symbol 'r' (of type 'SymtabPtr') *)
  87. BEGIN
  88. IO.WrStrAdj(SymTabPtr(r)^.Name,-30);
  89. IO.WrInt(SymTabPtr(r)^.Count,-4);
  90. IO.WrStr(' : ');
  91. ni := 40;
  92. SymTabPtr(r)^.LRef.Apply(PrintLineNo);
  93. (* List line numbers for symbol *)
  94. IO.WrLn;
  95. END PrintSymbol;
  96. VAR
  97. SymbolTable, (* Actual table *)
  98. Predef : Table.TABLE; (* Key word table *)
  99. LineNr : LinTab; (* Work Area *)
  100. i,Item : CARDINAL;
  101. Symbol : SymTab; (* Word Area *)
  102. FileName : ARRAY [0..100] OF CHAR;
  103. File : FIO.File;
  104. Buffer : ARRAY [1..(1024 + FIO.BufferOverhead)] OF CHAR;
  105. Line : ARRAY [0..1023] OF CHAR;
  106. PROCEDURE FillPre;
  107. (* Fill 'PreDef' with keyword from 'KeyWords' *)
  108. VAR
  109. i, j : CARDINAL;
  110. x : SymTab;
  111. BEGIN
  112. Predef.Init; (* Initialize TABLE *)
  113. i := 0;
  114. WHILE (KeyWords[i] # 0C) DO
  115. j := 0;
  116. WHILE (KeyWords[i] # ' ') DO
  117. x.Name[j] := KeyWords[i];
  118. INC(j);
  119. INC(i);
  120. END;
  121. x.Name[j] := 0C;
  122. IF (j # 0) THEN
  123. Predef.Insert(x);
  124. END;
  125. INC(i);
  126. END (* WHILE *);
  127. END FillPre;
  128. BEGIN
  129. (* check parameters *)
  130. IF Lib.ParamCount() <> 1 THEN
  131. IO.WrStr('Try again : cr input-file');
  132. IO.WrLn;
  133. HALT;
  134. END;
  135. SymbolTable.Init; (* Initialize symbol table *)
  136. Lib.ParamStr(FileName,1); (* Get filename from command line *)
  137. File := FIO.OpenRead(FileName); (* Open - only need to read it *)
  138. FIO.AssignBuffer(File,Buffer); (* Associate a buffer with file
  139. to speed up access *)
  140. LineNr.RefLn := 1; (* Initialise line counter *)
  141. LOOP
  142. FIO.RdStr(File,Line); (* Read line from file *)
  143. IF FIO.EOF THEN (* Check for end-of-file *)
  144. EXIT;
  145. END;
  146. Item := 0;
  147. LOOP
  148. Str.Item(Symbol.Name,Line,
  149. Str.CHARSET{ 0C..CHAR(255) } -
  150. Str.CHARSET{ 'A'..'Z','a'..'z','_','0'..'9','.' },Item);
  151. (* Extracts a single word from 'Line'. Each word
  152. is delimited by any characters except a digit, a letter,
  153. an underbar or a '.'.
  154. *)
  155. IF (Symbol.Name[0] = 0C) THEN (* Check that there was a word *)
  156. EXIT;
  157. END;
  158. INC(Item);
  159. IF (Symbol.Name[0] > '9') THEN (* Don't enter numbers in table *)
  160. IF (SymbolTable.Find(Symbol)) THEN
  161. (* Is word already in tabel? *)
  162. INC(Symbol.Count); (* If, yes, increment count *)
  163. ELSE
  164. Symbol.Count := 1;
  165. Symbol.LRef.Init; (* Initailize line number table *)
  166. END;
  167. Symbol.LRef.Insert(LineNr); (* Insert cross-reference *)
  168. SymbolTable.Insert(Symbol); (* Insert/Update symbol entry *)
  169. END;
  170. END (* LOOP through line *);
  171. INC(LineNr.RefLn); (* Next line *)
  172. END (* LOOP - File *);
  173. FillPre; (* Build table of predefined words *)
  174. SymbolTable.Excl(Predef); (* Exclude predefined words from table *)
  175. SymbolTable.Apply(PrintSymbol); (* Display table *)
  176. Predef.Dispose; (* Reclaim storage for predefined words *)
  177. SymbolTable.Dispose; (* Reclaim storage other names *)
  178. END CR.
  179.