ADDRESS2.MOD 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. MODULE Address2;
  2. (*
  3. Copyright 1989 by Jensen & Partners International, All Rights Reserved
  4. *)
  5. IMPORT IO, FIO, Window, Btree, Str, Lib, Misc;
  6. TYPE
  7. AddrKey = ARRAY[0..25] OF CHAR;
  8. AddrRec = RECORD
  9. LName : ARRAY[0..14] OF CHAR;
  10. FName : ARRAY[0..9] OF CHAR;
  11. Street : ARRAY[0..25] OF CHAR;
  12. City : ARRAY[0..15] OF CHAR;
  13. State : ARRAY[0..1] OF CHAR;
  14. Zip : ARRAY[0..4] OF CHAR;
  15. Phone : ARRAY[0..12] OF CHAR;
  16. END; (* record *)
  17. CharSet = SET OF CHAR;
  18. VAR
  19. choice, ch2 : CHAR;
  20. FOUND,
  21. DONE : BOOLEAN;
  22. DataColor,
  23. TemplateColor : Window.Color;
  24. NameFile : Btree.FHandle; (* physical file handle *)
  25. NameData, (* logical data file handle *)
  26. NameIndex : Btree.IHandle; (* logical index file handle *)
  27. blankAddr,
  28. tempAddr : AddrRec;
  29. Create : BOOLEAN;
  30. PROCEDURE MAKEKEY(keyA,myRecA: ADDRESS);
  31. VAR
  32. key : POINTER TO AddrKey;
  33. myRec : POINTER TO AddrRec;
  34. i,j : CARDINAL;
  35. BEGIN
  36. key := keyA;
  37. myRec := myRecA;
  38. Str.Copy(key^,myRec^.LName);
  39. i := Str.Length(key^);
  40. WHILE (i#0) AND (key^[i-1]=' ') DO
  41. key^[i-1] := 0C;
  42. DEC(i);
  43. END; (* while *)
  44. Str.Append(key^," ");
  45. Str.Append(key^,myRec^.FName);
  46. i := Str.Length(key^);
  47. WHILE (i#0) AND (key^[i-1]=' ') DO
  48. key^[i-1] := 0C;
  49. DEC(i);
  50. END; (* while *)
  51. Str.Caps(key^);
  52. END MAKEKEY;
  53. PROCEDURE COMPARE(key1,key2: ADDRESS): Btree.CmpRes;
  54. (* compare two keys, and determine which is "smaller" *)
  55. BEGIN
  56. RETURN Btree.CmpRes(Str.Compare(AddrKey(key1^),AddrKey(key2^))+1);
  57. END COMPARE;
  58. PROCEDURE Beep();
  59. BEGIN
  60. (* generic *) FIO.WrChar(FIO.StandardOutput,CHR(7));
  61. (* OS/2 *) (* Lib.Speaker(1500,10); *)
  62. (* DOS *) (* Lib.Sound(1500);
  63. Lib.Delay(10);
  64. Lib.NoSound(); *)
  65. END Beep;
  66. PROCEDURE WriteAt(row,col: CARDINAL; txt: ARRAY OF CHAR);
  67. BEGIN
  68. Window.GotoXY(col,row);
  69. IO.WrStr(txt);
  70. END WriteAt;
  71. PROCEDURE Template();
  72. BEGIN
  73. Window.TextColor(TemplateColor);
  74. WriteAt(3,3,"Name:");
  75. WriteAt(3,50,"(first last)");
  76. WriteAt(4,3,"Address:");
  77. WriteAt(5,3,"City:");
  78. WriteAt(5,40,"State:");
  79. WriteAt(5,55,"Zip:");
  80. WriteAt(6,3,"Phone:");
  81. END Template;
  82. PROCEDURE Display(myRec: AddrRec);
  83. BEGIN
  84. Window.TextColor(DataColor);
  85. WriteAt(3,12,myRec.FName); IO.WrStr(" "); IO.WrStr(myRec.LName);
  86. WriteAt(4,12,myRec.Street);
  87. WriteAt(5,12,myRec.City);
  88. WriteAt(5,47,myRec.State);
  89. WriteAt(5,60,myRec.Zip);
  90. WriteAt(6,12,myRec.Phone);
  91. END Display;
  92. PROCEDURE GetMenu(Prompt: ARRAY OF CHAR; OKChars: CharSet;
  93. VAR ch: CHAR);
  94. VAR
  95. OK : BOOLEAN;
  96. MenuWin : Window.WinType;
  97. i : CARDINAL;
  98. BEGIN
  99. MenuWin := Window.Open( Window.WinDef( 0, 22, 79, 24,
  100. Window.White,Window.Black,TRUE,FALSE,TRUE,TRUE,
  101. Window.SingleFrame,Window.White,Window.Black) );
  102. i := Str.Length(Prompt);
  103. Window.Change(MenuWin,((80-i) DIV 2) -2,22, ((80-i) DIV 2) + i + 3, 24);
  104. Window.SetFrame(MenuWin,Window.SingleFrame,TemplateColor,Window.Black);
  105. Window.TextColor(DataColor);
  106. Window.Use(MenuWin);
  107. Window.PutOnTop(MenuWin);
  108. IO.WrStr(" ");
  109. IO.WrStr(Prompt);
  110. OK := FALSE;
  111. REPEAT
  112. ch := CAP(IO.RdKey());
  113. IF ch IN OKChars THEN
  114. OK := TRUE;
  115. ELSE
  116. Beep();
  117. END;
  118. UNTIL OK;
  119. Window.Close(MenuWin);
  120. END GetMenu;
  121. PROCEDURE ShowNames();
  122. VAR
  123. myRec : AddrRec;
  124. ch : CHAR;
  125. row : CARDINAL;
  126. switchColor : BOOLEAN;
  127. loc : LONGCARD;
  128. BEGIN
  129. Window.Clear();
  130. Btree.Reset(NameData);
  131. row := 1;
  132. switchColor := TRUE;
  133. LOOP
  134. IF Btree.Next(NameIndex,myRec) THEN
  135. IF switchColor THEN
  136. Window.TextColor(TemplateColor);
  137. ELSE
  138. Window.TextColor(DataColor);
  139. END;
  140. switchColor := NOT switchColor;
  141. IO.WrStrAdj(myRec.LName, -17);
  142. IO.WrStrAdj(myRec.FName, -12);
  143. IO.WrStrAdj(myRec.Phone, -15);
  144. IO.WrLn();
  145. INC(row);
  146. Btree.Release(NameIndex);
  147. IF row>23 THEN
  148. IO.WrLn();
  149. IO.WrStr("Press <ESC> to quit, any other key to continue: ");
  150. ch := IO.RdKey();
  151. IF ch = 33C THEN RETURN; END;
  152. Window.Clear();
  153. row := 1;
  154. END; (* if *)
  155. ELSE
  156. CASE Btree.LastError(NameIndex) OF
  157. Btree.OK : EXIT;
  158. | Btree.Locked : IF Btree.NextIndex(NameIndex,loc) THEN
  159. IO.WrStr('[LOCKED]');
  160. IO.WrLn;
  161. ELSE
  162. CASE Btree.LastError(NameIndex) OF
  163. Btree.OK : EXIT; (* Huh? *)
  164. | Btree.Locked : IO.WrStr('[INDEX LOCKED]');
  165. IO.WrLn;
  166. EXIT;
  167. ELSE
  168. IO.WrStr('[ERROR]');
  169. IO.WrLn;
  170. EXIT;
  171. END;
  172. END;
  173. ELSE
  174. IO.WrStr('[ERROR]');
  175. IO.WrLn;
  176. EXIT;
  177. END;
  178. END;
  179. END;
  180. END ShowNames;
  181. PROCEDURE FindName();
  182. VAR
  183. fname : AddrKey;
  184. myRec : AddrRec;
  185. ch : CHAR;
  186. BEGIN
  187. Window.Clear();
  188. Window.TextColor(TemplateColor);
  189. FOUND := FALSE;
  190. WriteAt(3,3,"Enter name as 'Last First' (e.g. 'Smith John').");
  191. WriteAt(4,3,"Be sure to include the space between the names.");
  192. WriteAt(5,3,"> ");
  193. Window.TextColor(DataColor);
  194. Misc.InputStr(fname,25);
  195. Str.Caps(fname);
  196. Window.TextColor(TemplateColor);
  197. WriteAt(7,3,"Searching... ");
  198. IF Btree.Find(NameIndex,fname,myRec) THEN
  199. Window.Clear();
  200. Template();
  201. Display(myRec);
  202. FOUND := TRUE;
  203. ELSIF Btree.LastError(NameIndex) # Btree.Locked THEN
  204. WriteAt(7,20,"done. Failed exact search. Trying closest match.");
  205. Window.TextColor(DataColor);
  206. WriteAt(9,3,"Searching... ");
  207. IF Btree.Search(NameIndex,fname,myRec) THEN
  208. Window.Clear();
  209. Template();
  210. Display(myRec);
  211. FOUND := TRUE;
  212. REPEAT
  213. GetMenu("N)ext, P)revious, or T)his one? ",
  214. CharSet{'N','P','T'},ch);
  215. WriteAt(10,3," ");
  216. CASE ch OF
  217. 'N' : IF Btree.Next(NameIndex,myRec) THEN
  218. Display(blankAddr);
  219. Display(myRec);
  220. ELSIF Btree.LastError(NameIndex) = Btree.Locked THEN
  221. WriteAt(10,3,"Locked");
  222. Beep();
  223. ELSE
  224. WriteAt(10,3,"No more records found");
  225. Beep();
  226. Btree.Reset(NameIndex);
  227. Display(blankAddr);
  228. IF Btree.Prev(NameIndex,myRec) THEN
  229. Display(myRec);
  230. ELSE
  231. FOUND := FALSE;
  232. END;
  233. END;
  234. | 'P' : IF Btree.Prev(NameIndex,myRec) THEN
  235. Display(blankAddr);
  236. Display(myRec);
  237. ELSIF Btree.LastError(NameIndex) = Btree.Locked THEN
  238. WriteAt(10,3,"Locked");
  239. Beep();
  240. ELSE
  241. WriteAt(10,3,"No more records found");
  242. Beep();
  243. Btree.Reset(NameIndex);
  244. Display(blankAddr);
  245. IF Btree.Next(NameIndex,myRec) THEN
  246. Display(myRec);
  247. ELSE
  248. FOUND := FALSE;
  249. END;
  250. END;
  251. ELSE
  252. Beep();
  253. END; (* case *)
  254. UNTIL ch = 'T';
  255. ELSE
  256. WriteAt(9,20,"done. Failed closest match search.");
  257. END; (* if *)
  258. ELSE
  259. WriteAt(9,20,"done. Locking conflict occured.");
  260. END; (* if *)
  261. END FindName;
  262. PROCEDURE AddName();
  263. VAR
  264. myRec : AddrRec;
  265. ch : CHAR;
  266. BEGIN
  267. Window.Clear();
  268. Template();
  269. ch := 'N';
  270. myRec := blankAddr;
  271. REPEAT
  272. Window.TextColor(DataColor);
  273. Window.GotoXY(12,3); Misc.InputStr(myRec.FName,10);
  274. Window.GotoXY(35,3); Misc.InputStr(myRec.LName,15);
  275. Window.GotoXY(12,4); Misc.InputStr(myRec.Street,25);
  276. Window.GotoXY(12,5); Misc.InputStr(myRec.City,15);
  277. Window.GotoXY(47,5); Misc.InputStr(myRec.State,2);
  278. Window.GotoXY(60,5); Misc.InputStr(myRec.Zip,5);
  279. Window.GotoXY(12,6); Misc.InputStr(myRec.Phone,12);
  280. GetMenu("Do these look ok? (Y/N) ",CharSet{'Y','N'},ch);
  281. UNTIL ch = 'Y';
  282. (* Now put it in the file *)
  283. Btree.Add(NameData,myRec,SIZE(myRec));
  284. END AddName;
  285. PROCEDURE DeleteName();
  286. VAR
  287. ch : CHAR;
  288. BEGIN
  289. FindName();
  290. IF FOUND THEN
  291. GetMenu("Delete this one? (Y/N) ",CharSet{'Y','N'},ch);
  292. IF ch = 'Y' THEN
  293. Btree.Delete(NameData);
  294. END; (* if *)
  295. END; (* if *)
  296. Btree.Release(NameIndex);
  297. FOUND := FALSE;
  298. END DeleteName;
  299. BEGIN (* main program *)
  300. TemplateColor := Window.LightGreen;
  301. DataColor := Window.Yellow;
  302. Str.Copy(blankAddr.LName," ");
  303. Str.Copy(blankAddr.FName," ");
  304. Str.Copy(blankAddr.Street," ");
  305. Str.Copy(blankAddr.City," ");
  306. Str.Copy(blankAddr.State," ");
  307. Str.Copy(blankAddr.Zip," ");
  308. Str.Copy(blankAddr.Phone," ");
  309. Window.Clear();
  310. Create := NOT FIO.Exists("Addressb.ook");
  311. LOOP
  312. NameFile := Btree.Open("Addressb.ook",2,Btree.FixSize,FALSE,NOT Create,Create);
  313. NameData := Btree.OpenData(NameFile,1,SIZE(AddrRec),Create);
  314. NameIndex := Btree.OpenIndex(NameFile,NameData,2,COMPARE,MAKEKEY,
  315. SIZE(AddrKey),TRUE,Create);
  316. IF Create THEN
  317. Btree.Close(NameFile);
  318. Create := FALSE;
  319. ELSE
  320. EXIT;
  321. END;
  322. END;
  323. DONE := FALSE;
  324. choice := ' ';
  325. REPEAT
  326. GetMenu("S)howNames F)indSomeone A)ddSomeone D)eleteSomeone Q)uit :",
  327. CharSet{'S','F','A','D','Q'},choice);
  328. CASE choice OF
  329. 'S' : ShowNames();
  330. | 'F' : FindName();
  331. Btree.Release(NameIndex);
  332. | 'A' : AddName();
  333. | 'D' : DeleteName();
  334. | 'Q' : DONE := TRUE;
  335. ELSE
  336. Beep();
  337. END; (* case *)
  338. UNTIL DONE;
  339. Btree.Close(NameFile);
  340. END Address2.
  341.