IMPORTER.MOD 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. MODULE Importer;
  2. (*
  3. * REPERTOIRE
  4. * Release 1.6
  5. * By Charles Bradford and Cole Brecheen
  6. * (c) Copyright 1985-1990 PMI
  7. * Green Bay, WI
  8. * All rights reserved
  9. * (414) 468-6040
  10. *
  11. *)
  12. IMPORT EnvironUtils;
  13. IMPORT ErrorManager;
  14. IMPORT GenLists;
  15. IMPORT ImpLists;
  16. IMPORT KbdInput;
  17. IMPORT ListUtils;
  18. IMPORT LowLevel;
  19. IMPORT M2Strings;
  20. IMPORT Numbers;
  21. IMPORT Parser;
  22. IMPORT PosUtils;
  23. IMPORT StrEdit;
  24. IMPORT StringIO;
  25. IMPORT SYSTEM;
  26. IMPORT InitCompilerMods;
  27. (*# call(reg_param => (),
  28. near_call => off,
  29. ds_eq_ss => off) *)
  30. (*# data(near_ptr => off) *)
  31. VAR
  32. x, fname1, fname2, CurrentWord, LastWord: ARRAY [0..79] OF CHAR;
  33. Terminator: CHAR;
  34. StartOfImpList, EndOfImpList, LineCnt, ColCnt: CARDINAL;
  35. TextList, TmpList, Imports: GenLists.GenList;
  36. cnt, FoundSpot, dumc: CARDINAL;
  37. Sorting, Unqualifying, Qualifying : BOOLEAN;
  38. Dumstr: ARRAY [0..0] OF CHAR;
  39. PROCEDURE yes( TheQuestion: ARRAY OF CHAR ): BOOLEAN;
  40. VAR
  41. tmpkey: CARDINAL;
  42. BEGIN
  43. StringIO.WriteEol( StringIO.outp, '' );
  44. StringIO.WriteStr( StringIO.outp, TheQuestion );
  45. tmpkey := KbdInput.CAPkey( KbdInput.KeyHit( KbdInput.YorN ) );
  46. IF ORD('Y') = tmpkey THEN
  47. StringIO.WriteStr( StringIO.outp, 'yes' );
  48. RETURN TRUE;
  49. ELSIF ORD('Q') = tmpkey THEN
  50. ErrorManager.StraightToDOS('');
  51. END;
  52. StringIO.WriteStr( StringIO.outp, 'no' );
  53. RETURN FALSE;
  54. END yes;
  55. PROCEDURE NextWord( VAR TheStr: ARRAY OF CHAR );
  56. BEGIN
  57. Parser.GetNextWord( TextList, LineCnt, ColCnt, TheStr, Terminator );
  58. M2Strings.Assign( CurrentWord, LastWord );
  59. M2Strings.Assign( TheStr, CurrentWord );
  60. END NextWord;
  61. PROCEDURE StrInList( TheStr: ARRAY OF CHAR; TheList: GenLists.GenList ):
  62. BOOLEAN;
  63. VAR
  64. ListEnd, cnt: CARDINAL;
  65. tmpstr: ARRAY [0..79] OF CHAR;
  66. BEGIN
  67. ListEnd := GenLists.ListLength(TheList);
  68. FOR cnt := 1 TO ListEnd DO
  69. ListUtils.GetStr( TheList, cnt, tmpstr );
  70. IF PosUtils.Equal( tmpstr, TheStr ) THEN
  71. RETURN TRUE;
  72. END;
  73. END;
  74. RETURN FALSE;
  75. END StrInList;
  76. PROCEDURE InsertElmts( ToBeInserted: GenLists.GenList; VAR IntoThis:
  77. GenLists.GenList; AtThisSpot: CARDINAL );
  78. VAR
  79. lngth1, tmpsize, cnt, TypeCode: CARDINAL;
  80. tmpadr: SYSTEM.ADDRESS;
  81. BEGIN
  82. lngth1 := GenLists.ListLength( ToBeInserted );
  83. FOR cnt := lngth1 TO 1 BY -1 DO
  84. (* it's simpler to insert backwards *)
  85. GenLists.GetElmtAdr( ToBeInserted, cnt, tmpadr, tmpsize, TypeCode );
  86. GenLists.ListInsertAdr( tmpadr, tmpsize, TypeCode, IntoThis, AtThisSpot );
  87. END;
  88. END InsertElmts;
  89. PROCEDURE Alphabetize( adr1: SYSTEM.ADDRESS; size1: CARDINAL; adr2:
  90. SYSTEM.ADDRESS; size2: CARDINAL ): INTEGER;
  91. VAR
  92. tmp1, tmp2: ARRAY [0..79] OF CHAR;
  93. BEGIN
  94. LowLevel.Move( adr1, SYSTEM.ADR(tmp1), Numbers.Min(size1, 79) );
  95. tmp1[Numbers.Min(size1, 79)] := 0C;
  96. LowLevel.Move( adr2, SYSTEM.ADR(tmp2), Numbers.Min(size2, 79) );
  97. tmp2[Numbers.Min(size2, 79)] := 0C;
  98. StrEdit.CAPstr( tmp1 );
  99. StrEdit.CAPstr( tmp2 );
  100. RETURN M2Strings.CompareStr( tmp1, tmp2 );
  101. END Alphabetize;
  102. PROCEDURE MakeSortedImpList( TopList: GenLists.GenList; VAR OutList: GenLists.GenList );
  103. VAR
  104. SubList: GenLists.GenList;
  105. TopListEnd, TopListCount: CARDINAL;
  106. SubListCount: CARDINAL;
  107. x: ARRAY [0..31] OF CHAR;
  108. WorkStr: ARRAY [0..1023] OF CHAR;
  109. BEGIN
  110. TopListCount := 0;
  111. TopListEnd := GenLists.ListLength(TopList);
  112. IF TopListEnd < 2 THEN
  113. RETURN;
  114. END;
  115. GenLists.NewList( OutList );
  116. REPEAT
  117. WorkStr := '';
  118. INC( TopListCount );
  119. ListUtils.GetStr( TopList, TopListCount, x );
  120. (* x now ought to contain a module name *)
  121. INC( TopListCount );
  122. GenLists.GetChildList( TopList, TopListCount, SubList );
  123. IF GenLists.Initialized( SubList ) THEN
  124. GenLists.SortList( SubList, Alphabetize );
  125. StrEdit.Append( WorkStr, 'FROM ' );
  126. StrEdit.Append( WorkStr, x );
  127. StrEdit.Append( WorkStr, ' IMPORT ' );
  128. SubListCount := 1;
  129. LOOP
  130. ListUtils.GetStr( SubList, SubListCount, x );
  131. StrEdit.Append( WorkStr, x );
  132. INC( SubListCount );
  133. IF SubListCount > GenLists.ListLength(SubList) THEN
  134. StrEdit.Append( WorkStr, ';' );
  135. EXIT;
  136. ELSE
  137. StrEdit.Append( WorkStr, ', ' );
  138. END;
  139. END;
  140. ELSE
  141. (* This is a FromLess import *)
  142. StrEdit.Append( WorkStr, 'IMPORT ' );
  143. StrEdit.Append( WorkStr, x );
  144. StrEdit.Append( WorkStr, ';' );
  145. END;
  146. GenLists.ListInsert( WorkStr, GenLists.StrCode, OutList, 65535 );
  147. UNTIL TopListCount = TopListEnd;
  148. GenLists.SortList( OutList, Alphabetize );
  149. ListUtils.CheckLength( OutList, 5, 75 );
  150. END MakeSortedImpList;
  151. PROCEDURE InImportList( VAR TheWord: ARRAY OF CHAR; ImportList:
  152. GenLists.GenList; VAR ModuleName: ARRAY OF CHAR ): BOOLEAN;
  153. VAR
  154. SubList: GenLists.GenList;
  155. TopListCount: CARDINAL;
  156. BEGIN
  157. TopListCount := 0;
  158. REPEAT
  159. INC( TopListCount );
  160. ListUtils.GetStr( ImportList, TopListCount, ModuleName );
  161. INC( TopListCount );
  162. GenLists.GetChildList( ImportList, TopListCount, SubList );
  163. IF GenLists.Initialized( SubList ) AND StrInList(TheWord, SubList) THEN
  164. RETURN TRUE;
  165. END;
  166. UNTIL TopListCount = GenLists.ListLength(ImportList);
  167. RETURN FALSE;
  168. END InImportList;
  169. PROCEDURE IsModuleName( ModuleName: ARRAY OF CHAR; ImportList:
  170. GenLists.GenList; VAR SubList: GenLists.GenList ): BOOLEAN;
  171. VAR
  172. TopListCount: CARDINAL;
  173. tmpstr: ARRAY [0..79] OF CHAR;
  174. BEGIN
  175. TopListCount := 0;
  176. GenLists.NilList( SubList );
  177. REPEAT
  178. INC( TopListCount );
  179. ListUtils.GetStr( ImportList, TopListCount, tmpstr );
  180. INC( TopListCount );
  181. IF PosUtils.Equal( ModuleName, tmpstr ) THEN
  182. GenLists.GetChildList( ImportList, TopListCount, SubList );
  183. RETURN TRUE;
  184. END;
  185. UNTIL TopListCount = GenLists.ListLength(ImportList);
  186. RETURN FALSE;
  187. END IsModuleName;
  188. PROCEDURE QualifyAll();
  189. VAR
  190. TopListCount: CARDINAL;
  191. tmpstr: ARRAY [0..79] OF CHAR;
  192. ModuleName: ARRAY [0..31] OF CHAR;
  193. TextEnd, ImportsEnd, LastLine : CARDINAL;
  194. LocalNilList, SubList: GenLists.GenList;
  195. BEGIN
  196. LastLine := 0;
  197. TextEnd := GenLists.ListLength(TextList);
  198. ImportsEnd := GenLists.ListLength(Imports);
  199. REPEAT
  200. NextWord( CurrentWord );
  201. IF InImportList( CurrentWord, Imports, ModuleName ) THEN
  202. M2Strings.Insert( '.', Parser.TheLine, Parser.LastIndex );
  203. M2Strings.Insert( ModuleName, Parser.TheLine, Parser.LastIndex );
  204. GenLists.ListReplace( Parser.TheLine, GenLists.StrCode, TextList, LineCnt );
  205. INC( ColCnt, M2Strings.Length(ModuleName) + 1 );
  206. END;
  207. IF LineCnt > LastLine THEN
  208. StringIO.WriteStr( StringIO.outp, '.' );
  209. LastLine := LineCnt;
  210. END;
  211. UNTIL LineCnt >= TextEnd;
  212. TopListCount := 0;
  213. GenLists.NilList( LocalNilList );
  214. REPEAT
  215. INC( TopListCount, 2 );
  216. GenLists.ListReplace( LocalNilList, GenLists.ListCode, Imports, TopListCount );
  217. (*ListReplace takes care of deallocating the old list.
  218. Note that we don't do GetChildList's and
  219. DisposeList's because that wouldn't nil out the copy
  220. of the pointer that's in the Imports list.*)
  221. UNTIL TopListCount >= ImportsEnd;
  222. END QualifyAll;
  223. PROCEDURE UnqualifyAll();
  224. VAR
  225. ModuleName, tmpstr: ARRAY [0..31] OF CHAR;
  226. SubList: GenLists.GenList;
  227. LastLine : CARDINAL;
  228. BEGIN
  229. LastLine := 0;
  230. REPEAT
  231. NextWord( CurrentWord );
  232. IF IsModuleName( CurrentWord, Imports, SubList ) AND
  233. (Terminator = '.') THEN
  234. M2Strings.Assign( CurrentWord, ModuleName );
  235. NextWord( CurrentWord );
  236. IF NOT GenLists.Initialized( SubList ) THEN
  237. GenLists.NewList( SubList );
  238. GenLists.ListReplace( SubList, GenLists.ListCode, Imports,
  239. GenLists.ElmtNow(Imports) );
  240. END;
  241. IF NOT StrInList( CurrentWord, SubList ) THEN
  242. GenLists.ListInsert( CurrentWord, GenLists.StrCode, SubList, 65535 );
  243. END;
  244. StrEdit.Append( ModuleName, '.' );
  245. StrEdit.ReplaceStr( ModuleName, '', Parser.TheLine );
  246. GenLists.ListReplace( Parser.TheLine, GenLists.StrCode, TextList, LineCnt );
  247. DEC( ColCnt, M2Strings.Length(ModuleName) + 1 );
  248. END;
  249. IF LineCnt > LastLine THEN
  250. StringIO.WriteStr( StringIO.outp, '.' );
  251. LastLine := LineCnt;
  252. END;
  253. UNTIL LineCnt >= GenLists.ListLength(TextList);
  254. END UnqualifyAll;
  255. BEGIN
  256. IF NOT EnvironUtils.ParsedParam( 1, fname1 ) THEN
  257. StringIO.WriteStr( StringIO.outp, 'File name: ' );
  258. StringIO.ReadStr( StringIO.inp, fname1 );
  259. IF M2Strings.Length(fname1) = 0 THEN
  260. RETURN;
  261. END;
  262. END;
  263. PosUtils.CaseSensitive := FALSE;
  264. IF NOT PosUtils.Present( '.', fname1 ) THEN
  265. StrEdit.Append( fname1, '.mod' );
  266. END;
  267. PosUtils.CaseSensitive := TRUE;
  268. IF NOT EnvironUtils.ParsedParam( 2, Dumstr ) THEN
  269. Qualifying := yes( 'Qualify all imported identifiers? ');
  270. IF Qualifying THEN
  271. Unqualifying := FALSE;
  272. Sorting := FALSE;
  273. ELSE
  274. Unqualifying := yes( 'Unqualify all qualified identifiers? ');
  275. IF Unqualifying THEN
  276. Sorting := FALSE;
  277. ELSE
  278. Sorting := yes( 'Sort identifiers in present import list? ');
  279. END;
  280. END;
  281. ELSE
  282. Sorting := CAP(Dumstr[0]) = 'S';
  283. Qualifying := CAP(Dumstr[0]) = 'Q';
  284. Unqualifying := CAP(Dumstr[0]) = 'U';
  285. END;
  286. LineCnt := 1;
  287. ColCnt := 0;
  288. StartOfImpList := 0;
  289. EndOfImpList := 0;
  290. GenLists.NewList( TextList );
  291. StringIO.PrintMessage( ListUtils.TextFileToList( fname1, TextList ) );
  292. LastWord := '';
  293. CurrentWord := '';
  294. ImpLists.ExtractImportList( TextList, Imports, StartOfImpList, EndOfImpList );
  295. IF Qualifying THEN
  296. QualifyAll();
  297. ELSIF Unqualifying THEN
  298. UnqualifyAll();
  299. END;
  300. IF StartOfImpList > 0 THEN
  301. MakeSortedImpList( Imports, TmpList );
  302. GenLists.DisposeList( Imports );
  303. GenLists.ListDelete( TextList, StartOfImpList, EndOfImpList -
  304. StartOfImpList + 1 );
  305. GenLists.ListInsert( '', GenLists.StrCode, TextList, StartOfImpList );
  306. (* insert a blank line to separate imports from rest of
  307. program *)
  308. InsertElmts( TmpList, TextList, StartOfImpList );
  309. GenLists.DisposeList( TmpList );
  310. END;
  311. StringIO.PrintMessage( ListUtils.TextListToFile( TextList, fname1 ) );
  312. GenLists.DisposeList( TextList );
  313. END Importer.
  314.