GEN.MOD 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. IMPLEMENTATION MODULE Gen;
  2. (*
  3. * ModBase
  4. * Release 3.0
  5. * (c) Copyright 1986 - 1991 PMI
  6. Copyright 1988 - 1991 John McMonagle
  7. * P.O. Box 8402
  8. * Green Bay Wi 53308
  9. * All Rights Reserved
  10. * by Ed Ross
  11. *)
  12. FROM GenLists IMPORT GenList,CopyList,DisposeList,ElmtNow,GetElmt,
  13. GetElmtAdr,ListDelete,ListInsert,ListLength,NewList,StrCode,
  14. ListReplace;
  15. FROM ListUtils IMPORT TextFileToList;
  16. FROM StrEdit IMPORT Append,SetLength,DeleteChar,DeleteRightJustified;
  17. FROM StrConv IMPORT CardinalToStr;
  18. FROM M2Strings IMPORT Length,Delete,Delete;
  19. FROM Str IMPORT Copy,Slice;
  20. FROM PosUtils IMPORT Pos;
  21. FROM StringIO IMPORT ErrorMessage,WriteStr,WriteEol;
  22. FROM HandleIO IMPORT CreateFile;
  23. FROM Prompts IMPORT Prompt;
  24. FROM PosUtils IMPORT Present,Equal;
  25. FROM StrEdit IMPORT CAPstr,CrunchBlanks,ReplaceStr;
  26. FROM DataTypes IMPORT IndexElmtRec,IdxList,FldList,TableName,
  27. DBFName,DataElmtRec,TableName;
  28. CONST
  29. TableNm ='@TABLENAME@'; (* name of table without appendages *)
  30. IdxFldNm='@IDX@'; (* indexed fld name *)
  31. IdxName ='@IDXNAME@'; (* name of index (fld name with trunc to 8)*)
  32. FldName ='@FLDNAME@'; (* field name (indexed and non indexed *)
  33. IdxNbr ='@IDXNBR@'; (* index number *)
  34. IdxChar = '@IDXCHAR@'; (* accel key /Highlight key for menu *)
  35. ForEachFld = '>>FOR EACH FLD<<'; (* for each field start loop *)
  36. EndEachFld = '>>END FLD<<';
  37. ForEachIdx = '>>FOR EACH IDX<<'; (* for every index in table*)
  38. EndEachIdx = '>>END IDX<<';
  39. MakeRec = '>>MAKE RECORD<<'; (* create a record from data *)
  40. MakeDBF = '>>MAKE DATABASE<<';
  41. MoveTo = '>>MOVE TO DB<<'; (* move data from record to db rec *)
  42. MoveFrom = '>>MOVE FROM DB<<';
  43. OutFileName= '>>FILE NAME =';
  44. IfIdx = '>>IF INDEX ='; (* either Real, Character, or *)
  45. (* or Numeric (cardinal ) *)
  46. EndIfIdx = '>>END IF<<'; (* end of conditional*)
  47. Include = '>>INCLUDE FILE ='; (* include a file by name of *)
  48. VAR
  49. FileList : GenList;
  50. Handle : CARDINAL;
  51. SubList : GenList;
  52. Condition : BOOLEAN; (* if processing in a conditional statement *)
  53. ChangingState : BOOLEAN;
  54. ProcessIdxType : CHAR;
  55. PROCEDURE WriteCard(H: CARDINAL; Card : CARDINAL);
  56. VAR
  57. Str : ARRAY[0..10] OF CHAR;
  58. BEGIN
  59. CardinalToStr(Card,3,Str);
  60. WriteStr(H,Str);
  61. END WriteCard;
  62. PROCEDURE MakeModRec(ItemList : GenList);
  63. VAR Str : ARRAY[0..80] OF CHAR;
  64. J : CARDINAL;
  65. Code,Size: CARDINAL;
  66. Item : POINTER TO DataElmtRec;
  67. BEGIN
  68. WriteStr(Handle,TableName);
  69. WriteEol(Handle,'Rec = RECORD');
  70. FOR J := 1 TO ListLength(ItemList) DO
  71. GetElmtAdr(ItemList,J,Item,Code,Size);
  72. WriteStr(Handle,' ');
  73. WriteStr(Handle,Item^.Name);
  74. WriteStr(Handle,' : ');
  75. WriteStr(Handle,Item^.RecType);
  76. WriteStr(Handle,';'); (* write the comments *)
  77. WriteStr(Handle,' (* ');
  78. WriteStr(Handle,Item^.Desc);
  79. WriteEol(Handle,' *)');
  80. END;
  81. WriteEol(Handle,'END;');
  82. END MakeModRec;
  83. PROCEDURE MakeMoveTo(ItemList : GenList); (* create move to record *)
  84. (* generate the code to move data from a record to the database *)
  85. VAR J : CARDINAL;
  86. Item : POINTER TO DataElmtRec;
  87. Size,Code : CARDINAL;
  88. BEGIN
  89. WriteStr(Handle,'PROCEDURE Move');
  90. WriteStr(Handle,TableName);
  91. WriteStr(Handle,'ToDBF(Rec : ');
  92. WriteStr(Handle,TableName);
  93. WriteEol(Handle,'Rec ); ');
  94. WriteEol(Handle,'(* This code will move the data from the record to *)');
  95. WriteEol(Handle,'(* the data base *)');
  96. WriteEol(Handle,'BEGIN');
  97. WriteEol(Handle,' WITH Rec DO');
  98. FOR J := 1 TO ListLength(ItemList) DO
  99. GetElmtAdr(ItemList,J,Item,Code,Size);
  100. CASE Item^.Type OF
  101. 'C' : WriteStr(Handle,' Replace( ');
  102. WriteStr(Handle,DBFName);
  103. WriteStr(Handle,',');
  104. WriteCard(Handle,J);
  105. WriteStr(Handle,',');
  106. WriteStr(Handle,Item^.Name);
  107. WriteStr(Handle,');');
  108. |'N' : WriteStr(Handle,' ReplaceN( ');
  109. WriteStr(Handle,DBFName);
  110. WriteStr(Handle,',');
  111. WriteCard(Handle,J);
  112. WriteStr(Handle,',');
  113. IF Item^.Dec > 0
  114. THEN WriteStr(Handle,Item^.Name);
  115. ELSE WriteStr(Handle,'FLOAT(');
  116. WriteStr(Handle,Item^.Name);
  117. WriteStr(Handle,')');
  118. END;
  119. WriteStr(Handle,');');
  120. |'D' : WriteStr(Handle,' ReplaceD( ');
  121. WriteStr(Handle,DBFName);
  122. WriteStr(Handle,',');
  123. WriteCard(Handle,J);
  124. WriteStr(Handle,',');
  125. WriteStr(Handle,Item^.Name);
  126. WriteStr(Handle,');');
  127. |'L' : WriteStr(Handle,' ReplaceL( ');
  128. WriteStr(Handle,DBFName);
  129. WriteStr(Handle,',');
  130. WriteCard(Handle,J);
  131. WriteStr(Handle,',');
  132. WriteStr(Handle,Item^.Name);
  133. WriteStr(Handle,');');
  134. END; (* end of case of *)
  135. WriteStr(Handle,' (* ');
  136. WriteStr(Handle,Item^.Desc);
  137. WriteEol(Handle,' *)');
  138. END; (* end of for each field *)
  139. WriteEol(Handle,'END; (* end of with REC *)');
  140. WriteStr(Handle,'END Move');
  141. WriteStr(Handle,TableName);
  142. WriteEol(Handle,'ToDBF;');
  143. WriteEol(Handle,'');
  144. WriteEol(Handle,'');
  145. END MakeMoveTo;
  146. PROCEDURE MakeMoveFrom(ItemList : GenList); (* create move to record *)
  147. (* generate the code to move data from a record to the database *)
  148. VAR J : CARDINAL;
  149. Item : POINTER TO DataElmtRec;
  150. Size,Code : CARDINAL;
  151. BEGIN
  152. WriteStr(Handle,'PROCEDURE Move');
  153. WriteStr(Handle,TableName);
  154. WriteStr(Handle,'FromDBF(VAR Rec : ');
  155. WriteStr(Handle,TableName);
  156. WriteEol(Handle,'Rec ); ');
  157. WriteEol(Handle,'(* This code will move the data from the Database to *)');
  158. WriteEol(Handle,'(* the record *)');
  159. WriteEol(Handle,'VAR B : BOOLEAN;');
  160. WriteEol(Handle,' R : Real8;');
  161. WriteEol(Handle,'BEGIN');
  162. WriteEol(Handle,' WITH Rec DO');
  163. FOR J := 1 TO ListLength(ItemList) DO
  164. GetElmtAdr(ItemList,J,Item,Code,Size);
  165. CASE Item^.Type OF
  166. 'C' : WriteStr(Handle,' GetField( ');
  167. WriteStr(Handle,DBFName);
  168. WriteStr(Handle,',');
  169. WriteCard(Handle,J);
  170. WriteStr(Handle,',');
  171. WriteStr(Handle,Item^.Name);
  172. WriteStr(Handle,');');
  173. |'N' : WriteStr(Handle,' GetNumField( ');
  174. WriteStr(Handle,DBFName);
  175. WriteStr(Handle,',');
  176. WriteCard(Handle,J);
  177. WriteStr(Handle,',');
  178. IF Item^.Dec > 0
  179. THEN WriteStr(Handle,Item^.Name);
  180. ELSE WriteEol(Handle,'R);');
  181. WriteStr(Handle,' ');
  182. WriteStr(Handle,Item^.Name);
  183. WriteStr(Handle,':= TRUNC(R');
  184. END;
  185. WriteStr(Handle,');');
  186. |'D' : WriteStr(Handle,' GetDateField( ');
  187. WriteStr(Handle,DBFName);
  188. WriteStr(Handle,',');
  189. WriteCard(Handle,J);
  190. WriteStr(Handle,',');
  191. WriteStr(Handle,Item^.Name);
  192. WriteStr(Handle,');');
  193. |'L' : WriteStr(Handle,' GetLogicalField( ');
  194. WriteStr(Handle,DBFName);
  195. WriteStr(Handle,',');
  196. WriteCard(Handle,J);
  197. WriteStr(Handle,',');
  198. WriteStr(Handle,Item^.Name);
  199. WriteStr(Handle,');');
  200. END; (* end of case of *)
  201. WriteStr(Handle,' (* ');
  202. WriteStr(Handle,Item^.Desc);
  203. WriteEol(Handle,' *)');
  204. END; (* end of for each field *)
  205. WriteEol(Handle,'END; (* end of with REC^ *)');
  206. WriteStr(Handle,'END Move');
  207. WriteStr(Handle,TableName);
  208. WriteEol(Handle,'FromDBF;');
  209. WriteEol(Handle,'');
  210. WriteEol(Handle,'');
  211. END MakeMoveFrom;
  212. PROCEDURE MakeDatabase( ItemList : GenList);
  213. (* produce the code to build the data base *)
  214. VAR
  215. Str : ARRAY[0..80] OF CHAR;
  216. TmpStr : ARRAY[0..15] OF CHAR;
  217. Code, Size : CARDINAL;
  218. Item : POINTER TO DataElmtRec;
  219. J : CARDINAL;
  220. BEGIN
  221. WriteEol(Handle,'PROCEDURE MakeDatabase();');
  222. WriteEol(Handle,'VAR ');
  223. WriteEol(Handle,' Error : CARDINAL;');
  224. WriteEol(Handle,' Desc : POINTER TO ARRAY [1..200] OF DBFieldDescriptor;');
  225. WriteEol(Handle,'BEGIN');
  226. CardinalToStr(ListLength(ItemList),3,Str);
  227. WriteStr(Handle,' ALLOCATE(Desc,');
  228. WriteStr(Handle,Str);
  229. WriteEol(Handle,' * SIZE(DBFieldDescriptor));');
  230. WriteStr(Handle,' Fill(Desc, ');
  231. WriteStr(Handle, Str);
  232. WriteEol(Handle,' * SIZE(DBFieldDescriptor),0);');
  233. FOR J := 1 TO ListLength(ItemList) DO
  234. GetElmtAdr(ItemList,J,Item,Code,Size);
  235. WriteStr(Handle,' MakeDescriptor(');
  236. CardinalToStr(J,3,Str);
  237. TmpStr := ' Desc^[';
  238. Append(TmpStr,Str);
  239. Append(TmpStr,"], '");
  240. WriteStr(Handle,TmpStr);
  241. WriteStr(Handle,Item^.Name);
  242. WriteStr(Handle,"'," );
  243. WriteCard(Handle,Item^.Len);
  244. WriteStr(Handle,"," );
  245. WriteCard(Handle,Item^.Dec);
  246. WriteStr(Handle,", '" );
  247. WriteStr(Handle,Item^.Type);
  248. WriteEol(Handle,"');");
  249. END;
  250. WriteStr(Handle," InitDBF('");
  251. WriteStr(Handle,TableName);
  252. WriteStr(Handle,".DBF',");
  253. WriteStr(Handle,TableName);
  254. WriteEol(Handle,"DBF,0,FALSE,TRUE,FALSE,DefaultFixUp);");
  255. WriteEol(Handle," (* It would be a good to test error.*)");
  256. WriteStr(Handle," Error:=BuildDBF(");
  257. WriteStr(Handle,"Desc^,");
  258. WriteStr(Handle,Str);
  259. WriteStr(Handle,',');
  260. WriteStr(Handle,TableName);
  261. WriteEol(Handle,'DBF);');
  262. WriteStr(Handle,' CloseDBF(');
  263. WriteStr(Handle,TableName);
  264. WriteEol(Handle,'DBF);');
  265. WriteStr(Handle,' DEALLOCATE(Desc,');
  266. WriteStr(Handle,Str);
  267. WriteEol(Handle,' * SIZE(DBFieldDescriptor));');
  268. WriteEol(Handle,'END MakeDatabase;');
  269. END MakeDatabase;
  270. PROCEDURE ReplaceName(SrchStr, ReplStr : ARRAY OF CHAR; VAR TheList : GenList);
  271. (* loop through the file and replace the strings *)
  272. VAR
  273. J : CARDINAL;
  274. Str : ARRAY[0..300] OF CHAR;
  275. Size,Code : CARDINAL;
  276. BEGIN
  277. FOR J := 1 TO ListLength(TheList) DO
  278. GetElmt(TheList,J,Str,Code);
  279. ReplaceStr(SrchStr,ReplStr,Str);
  280. ListReplace(Str,StrCode,TheList,J);
  281. END;
  282. END ReplaceName;
  283. PROCEDURE OKCondition(VAR Str:ARRAY OF CHAR ) : BOOLEAN;
  284. (* this routine will return true if the line should be included
  285. otherwise it will return false - don't include the line
  286. no -duh *)
  287. VAR
  288. IndexType : CHAR;
  289. BEGIN
  290. IF NOT (Present(IfIdx,Str) OR Present(EndIfIdx,Str))
  291. (* check if this is a conditional stm*)
  292. THEN RETURN Condition (* Nope - return current state *)
  293. ELSIF Present(EndIfIdx,Str) (* check for end of condition *)
  294. THEN
  295. Copy(Str , '');
  296. Condition := TRUE;
  297. RETURN TRUE;
  298. END; (* if we fell through this must be the
  299. begining of a conditional statement*)
  300. (* the value must be R - Real *)
  301. (* N - Numeric Cardinal*)
  302. (* C - Character *)
  303. DeleteRightJustified ( Str, 0, Pos('=',Str)+1); (* get rid of the prefix *)
  304. DeleteChar(' ',Str); (* whats left should be index type*)
  305. IF Str[0] = ProcessIdxType
  306. THEN Condition := TRUE
  307. ELSE Condition := FALSE;
  308. END;
  309. Copy(Str , '');
  310. RETURN Condition;
  311. END OKCondition;
  312. PROCEDURE ProcessRepeat(VAR TheList : GenList; VAR Spot : CARDINAL;
  313. StartMark,EndMark: ARRAY OF CHAR); FORWARD;
  314. PROCEDURE WriteList(VAR TheList : GenList);
  315. (* Write the list to the file *)
  316. (* Write until a ">>for each idx<<or >>for each fld<<" is encountered*)
  317. (* Extract the items that are for idx or flds; create a sublist and *)
  318. (* call writelist (recursivly) *)
  319. VAR
  320. J : CARDINAL;
  321. S : ARRAY[0..200] OF CHAR;
  322. Code,Size : CARDINAL;
  323. BEGIN
  324. J := 1;
  325. LOOP
  326. IF J > ListLength(TheList) THEN
  327. EXIT; (* I alter the J variable in a subroutine *)
  328. END; (* so use a loop construct rather than for *)
  329. GetElmt(TheList,J,S,Code);
  330. IF OKCondition(S) (* not in a conditional gen area*)
  331. THEN
  332. IF Present(ForEachIdx,S)
  333. THEN ProcessRepeat(TheList,J,ForEachIdx,EndEachIdx)
  334. ELSIF Present(ForEachFld,S)
  335. THEN ProcessRepeat(TheList,J,ForEachIdx,EndEachIdx);
  336. ELSIF Present(MakeRec,S)
  337. THEN MakeModRec(FldList);
  338. INC(J);
  339. ELSIF Present(MoveTo,S)
  340. THEN MakeMoveTo(FldList);
  341. INC(J);
  342. ELSIF Present(MoveFrom,S)
  343. THEN MakeMoveFrom(FldList);
  344. INC(J);
  345. ELSIF Present(MakeDBF,S)
  346. THEN MakeDatabase(FldList);
  347. INC(J);
  348. ELSE
  349. WriteEol(Handle,S);
  350. INC(J);
  351. END;
  352. ELSE INC(J); (* else if in condition *)
  353. END; (* end of if in condition *)
  354. END; (* end of LOOP *)
  355. END WriteList;
  356. PROCEDURE ProcessRepeat(VAR TheList : GenList; VAR Spot : CARDINAL;
  357. StartMark,EndMark: ARRAY OF CHAR);
  358. (* write out the line containing the for each field *)
  359. (* Make a sublist for the for each fld *)
  360. (* make a copy of the sublist *)
  361. (* for each fld replace the idx stuff *)
  362. (* writelist(the sublist) *)
  363. VAR
  364. S: ARRAY [0..200] OF CHAR;
  365. Size,Code : CARDINAL;
  366. TmpStr : ARRAY[0..200] OF CHAR;
  367. SubList, TmpList : GenList;
  368. J : CARDINAL;
  369. IdxRec : POINTER TO IndexElmtRec;
  370. BEGIN
  371. GetElmt(TheList,Spot,S,Code);
  372. Copy(TmpStr , S); (* for the first line *)
  373. J := Pos(StartMark,TmpStr)+Length(StartMark);
  374. SetLength(TmpStr,Pos(StartMark,TmpStr));
  375. WriteStr(Handle,TmpStr); (* write out the remainder of the currentline*)
  376. Delete(S,0,J); (* dump the front of str + the start mark *)
  377. NewList(SubList);
  378. LOOP (* create a sublist for the repeat field *)
  379. INC(Spot);
  380. IF Present(EndMark,S)
  381. THEN EXIT; (* last line processing *)
  382. END;
  383. ListInsert(S,StrCode,SubList,1000); (* insert a replace line *)
  384. IF Spot > ListLength(TheList)
  385. THEN EXIT;
  386. END;
  387. GetElmt(TheList,Spot,S,Code);
  388. END;
  389. Copy(TmpStr , S);
  390. (********************************************)
  391. (* last line processing *)
  392. (* if I need to have embedded loops put the *)
  393. (* search for start of loop here and call *)
  394. (* process repeating recursive call *)
  395. (********************************************)
  396. IF Present(EndMark,TmpStr)
  397. THEN
  398. SetLength(TmpStr,Pos(EndMark,TmpStr));
  399. J := Pos(EndMark,S)+Length(EndMark);
  400. Delete(S,0,J); (* dump the front of str + the start mark *)
  401. END;
  402. (* DEC(Spot);
  403. ListReplace(S,StrCode,TheList,Spot); Replace with write at end*)
  404. IF Length(TmpStr) > 0
  405. THEN
  406. ListInsert(TmpStr,StrCode,SubList,1000);
  407. END;
  408. (* now for each index or fld copy the list, replace the idx or fld
  409. and write list - NOTICE THIS IS A RECURSIVE CALL to witelist *)
  410. FOR J := 1 TO ListLength(IdxList) DO
  411. GetElmtAdr(IdxList,J,IdxRec,Size,Code);
  412. ProcessIdxType := IdxRec^.IndexType; (* set for conditional gen*)
  413. NewList(TmpList);
  414. CopyList(SubList,TmpList);
  415. ReplaceName(IdxFldNm,IdxRec^.FldName,TmpList);
  416. ReplaceName(FldName,IdxRec^.FldName,TmpList);
  417. ReplaceName(IdxName,IdxRec^.IdxName,TmpList);
  418. ReplaceName(IdxChar,IdxRec^.HighLight,TmpList);
  419. WriteList(TmpList);
  420. DisposeList(TmpList);
  421. WriteStr(Handle,S); (* fininsh the last line *)
  422. END;
  423. DisposeList(SubList);
  424. END ProcessRepeat;
  425. PROCEDURE GenFile(TemplateName : ARRAY OF CHAR);
  426. VAR
  427. FileName : ARRAY[0..80] OF CHAR;
  428. TmpStr : ARRAY [0..80] OF CHAR;
  429. ExtPart : ARRAY[0..3] OF CHAR;
  430. EM : ErrorMessage;
  431. FileList : GenList;
  432. Code : CARDINAL;
  433. BEGIN
  434. NewList(FileList);
  435. Condition := TRUE; (* ititialize the conditional generation stuff*)
  436. ChangingState := FALSE;
  437. EM := TextFileToList(TemplateName,FileList);
  438. ReplaceName(TableNm,TableName,FileList);
  439. (* If the file name is in the template, create a new file *)
  440. GetElmt(FileList,1,FileName,Code);
  441. IF Present(OutFileName,FileName)
  442. THEN
  443. TmpStr := OutFileName;
  444. Code := Length(TmpStr);
  445. Delete(FileName,Pos(OutFileName,FileName),Code); (* dump the front of line*)
  446. DeleteChar(' ',FileName); (* get rid of any excess blanks *)
  447. IF Pos('.',FileName)> 8 (* if name to long 8 + period *)
  448. THEN
  449. Slice(ExtPart,FileName,Pos('.',FileName)+1,3);
  450. SetLength(FileName,8); (* set to max length *)
  451. Append(FileName,'.');
  452. Append(FileName,ExtPart);
  453. END;
  454. EM := CreateFile(Handle,FileName);
  455. ListDelete(FileList,1,1); (* delete file name *)
  456. END; (* if file is named *)
  457. WriteList(FileList);
  458. END GenFile;
  459. END Gen.
  460.