PRINTFBA.LST 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. Listing:
  2. 1 (* Release 3.10 *)
  3. 2 (*-------------------------------------------------------------------------*
  4. 3 * *
  5. 4 * PRINTFBA.MOD - COMMS Toolkit formatted i/o support *
  6. 5 * *
  7. 6 * COPYRIGHT (C) 1988..1992 Clarion Software Corporation. *
  8. 7 * All Rights Reserved *
  9. 8 * *
  10. 9 *--------------------------------------------------------------------------*)
  11. 10
  12. 11 IMPLEMENTATION MODULE PrintFBase;
  13. 12 IMPORT Lib,IO;
  14. 13
  15. 14 CONST
  16. 15 MaxArgs = 5;
  17. 16 UpperDigits = '0123456789ABCDEF';
  18. ***** ^ not supported yet
  19. 17 LowerDigits = '0123456789abcdef';
  20. ***** ^ not supported yet
  21. 18
  22. 19 TYPE
  23. 20 StringPtr = POINTER TO ARRAY[0..0FFFH] OF CHAR;
  24. ***** ^ not supported yet
  25. ***** ^ not supported yet
  26. 21 JustifyTypes = (Left,Right,Centre);
  27. 22 CardType = (short,card,long);
  28. 23 CardPointer = POINTER TO RECORD
  29. 24 CASE :CardType OF
  30. ***** ^ not supported yet
  31. ***** ^ 'POINTER' expected
  32. 25 short : shortp : SHORTCARD; |
  33. 26 card : cardp : CARDINAL; |
  34. 27 long : longp : LONGCARD; |
  35. 28 END;
  36. 29 END;
  37. 30
  38. 31 VAR
  39. 32 PatAddr,DestAddr : StringPtr;
  40. 33 NumberBase : LONGCARD;
  41. 34 ArgNo,ArgCount,Patp,
  42. 35 Destp,PatMax,DestMax: CARDINAL;
  43. 36 ArgList : ARRAY[0..MaxArgs-1] OF ADDRESS;
  44. 37 Size : ARRAY[0..MaxArgs-1] OF CARDINAL;
  45. 38 Digits : ARRAY[0..15] OF CHAR;
  46. 39 Convert : ARRAY[0..51] OF PROC;
  47. 40
  48. 41 (*....................................*)
  49. 42
  50. 43 PROCEDURE Length(VAR s:ARRAY OF CHAR; Max:CARDINAL):CARDINAL;
  51. 44 BEGIN
  52. 45 RETURN Lib.ScanR(ADR(s),Max,0C);
  53. 46 END Length;
  54. 47
  55. 48 (*....................................*)
  56. 49
  57. 50 PROCEDURE Justify(Justification:JustifyTypes;VAR dest:ARRAY OF CHAR;Lnth:CARDINAL;PadChar:CHAR):CARDINAL;
  58. 51 VAR
  59. 52 Len : CARDINAL;
  60. 53 BEGIN
  61. 54 Len := Lib.ScanR(ADR(dest),HIGH(dest)+1,0C);
  62. 55 LOOP
  63. 56 IF Len>=Lnth THEN
  64. 57 EXIT;
  65. 58 END;
  66. 59 IF (Justification=Right) OR (Justification=Centre) THEN
  67. 60 INC(Len);
  68. 61 Lib.Move(ADR(dest),ADR(dest[1]),Len);
  69. 62 dest[0]:=PadChar;
  70. 63 END;
  71. 64 IF Len>=Lnth THEN
  72. 65 EXIT;
  73. 66 END;
  74. 67 IF (Justification=Left) OR (Justification=Centre) THEN
  75. 68 dest[Len]:=PadChar;
  76. 69 INC(Len);
  77. 70 dest[Len]:=0C;
  78. 71 END
  79. 72 END;
  80. 73 RETURN Len;
  81. 74 END Justify;
  82. 75
  83. 76 (*............................................*)
  84. 77
  85. 78 PROCEDURE Error(ErrNo:CARDINAL);
  86. 79 VAR
  87. 80 argnumstr : ARRAY[0..9] OF CHAR;
  88. 81 BEGIN
  89. 82 IO.WrLn;
  90. 83 IO.WrStr('PrintF Error --> ');
  91. 84 CASE ErrNo OF
  92. 85 1 : IO.WrStr('Unexpected end of spec. input.'); |
  93. 86 2 : IO.WrStr('Argument does not match specification.');|
  94. 87 3 : IO.WrStr('Wrong number of args.'); |
  95. 88 4 : IO.WrStr('Not a recognised field specifier'); |
  96. 89 5 : IO.WrStr('Not enough room in dest string.'); |
  97. 90 6 : IO.WrStr('Char codes must be three digits.'); |
  98. 91 7 : IO.WrStr('Width argument must be cardinal.'); |
  99. 92 8 : IO.WrStr('NewConversion, Type Char must be in {a..z, A..Z}');|
  100. 93 END; (* cases *)
  101. 94 IO.WrLn;
  102. 95 HALT;
  103. 96 END Error;
  104. 97
  105. 98 (*....................................*)
  106. 99
  107. 100 PROCEDURE CToS(c:LONGCARD; VAR i:CARDINAL);
  108. 101 BEGIN
  109. 102 IF c>=NumberBase THEN
  110. 103 CToS(c DIV NumberBase,i);
  111. 104 END;
  112. 105 DestString[i] := Digits[CARDINAL(c MOD NumberBase)];
  113. 106 INC(i);
  114. 107 END CToS;
  115. 108
  116. 109 (*....................................*)
  117. 110
  118. 111 PROCEDURE ReadLong(VAR l:LONGCARD);
  119. 112 VAR
  120. 113 p : CardPointer;
  121. 114 BEGIN
  122. 115 p := Data;
  123. 116 IF DataSize=1 THEN
  124. 117 l := LONGCARD(p^.shortp)
  125. 118 ELSIF DataSize=2 THEN
  126. 119 l := LONGCARD(p^.cardp)
  127. 120 ELSIF DataSize=4 THEN
  128. 121 l := p^.longp
  129. 122 ELSE
  130. 123 Error(2);
  131. 124 END;
  132. 125 END ReadLong;
  133. 126
  134. 127 (*....................................*)
  135. 128
  136. 129 PROCEDURE CardToString;
  137. 130 (* Handle conversion to string of SHORTCARD,CARDINAL and LONGCARD for*)
  138. 131 (* all number bases from 2-16. Note that only bases 8,10 & 16 are *)
  139. 132 (* supported by the field spec protocol. *)
  140. 133 VAR
  141. 134 i : CARDINAL;
  142. 135 c : LONGCARD;
  143. 136 BEGIN
  144. 137 IF TypeChar='o' THEN
  145. 138 NumberBase := 8;
  146. 139 ELSIF TypeChar='u' THEN
  147. 140 NumberBase := 10;
  148. 141 ELSE
  149. 142 NumberBase := 16;
  150. 143 END;
  151. 144 ReadLong(c);
  152. 145 i:=0;
  153. 146 IF AlwaysSigned THEN
  154. 147 DestString[0]:=Positive;
  155. 148 INC(i);
  156. 149 END;
  157. 150 CToS(c,i);
  158. 151 DestString[i]:=0C;
  159. 152 END CardToString;
  160. 153
  161. 154 (*....................................*)
  162. 155
  163. 156 PROCEDURE LowerCaseHex;
  164. 157 BEGIN
  165. 158 Digits:=LowerDigits;
  166. 159 CardToString;
  167. 160 Digits:=UpperDigits
  168. 161 END LowerCaseHex;
  169. 162
  170. 163 (*....................................*)
  171. 164
  172. 165 PROCEDURE IntToString;
  173. 166 (* Handle conversion to string of SHORTINT,INTEGER and LONGINT *)
  174. 167 VAR
  175. 168 i : CARDINAL;
  176. 169 p : CardPointer;
  177. 170 x : LONGINT;
  178. 171 BEGIN
  179. 172 NumberBase := 10;
  180. 173 p := Data;
  181. 174 IF DataSize=1 THEN
  182. 175 x := LONGINT(SHORTINT(p^.shortp))
  183. 176 ELSIF DataSize=2 THEN
  184. 177 x := LONGINT(INTEGER(p^.cardp))
  185. 178 ELSIF DataSize=4 THEN
  186. 179 x := LONGINT(p^.longp)
  187. 180 ELSE
  188. 181 Error(2);
  189. 182 END;
  190. 183 i:=0;
  191. 184 IF x<0 THEN
  192. 185 DestString[0]:='-'; INC(i); x:=-x
  193. 186 ELSIF AlwaysSigned THEN
  194. 187 DestString[0]:=Positive; INC(i)
  195. 188 END;
  196. 189 CToS(LONGCARD(x),i);
  197. 190 DestString[i]:=0C;
  198. 191 END IntToString;
  199. 192
  200. 193 (*....................................*)
  201. 194
  202. 195 PROCEDURE CopyString;
  203. 196 VAR
  204. 197 Lnth : CARDINAL;
  205. 198 stringp : StringPtr;
  206. 199 BEGIN
  207. 200 stringp := Data;
  208. 201 Lnth := Length(stringp^,DataSize);
  209. 202 Lib.Move(Data,ADR(DestString),Lnth);
  210. 203 DestString[Lnth] := 0C;
  211. 204 END CopyString;
  212. 205
  213. 206 (*....................................*)
  214. 207
  215. 208 PROCEDURE StoreChar(Ch:CHAR);
  216. 209 BEGIN
  217. 210 IF Destp<>DestMax THEN
  218. 211 DestAddr^[Destp] := Ch;
  219. 212 INC(Destp);
  220. 213 END;
  221. 214 END StoreChar;
  222. 215
  223. 216 (*....................................*)
  224. 217
  225. 218 PROCEDURE CopyChar;
  226. 219 VAR
  227. 220 charp : POINTER TO CHAR;
  228. 221 BEGIN
  229. 222 IF DataSize=1 THEN
  230. 223 charp := Data;
  231. 224 DestString[0] := charp^;
  232. 225 DestString[1] := 0C
  233. 226 ELSE
  234. 227 Error(2)
  235. 228 END;
  236. 229 END CopyChar;
  237. 230
  238. 231 (*....................................*)
  239. 232
  240. 233 PROCEDURE Parse;
  241. 234 VAR
  242. 235 Ch : CHAR;
  243. 236
  244. 237 (*. . . . . . . . . . . . . . . . . . .*)
  245. 238
  246. 239 PROCEDURE GetChar(VAR Ch:CHAR):BOOLEAN;
  247. 240 BEGIN
  248. 241 IF Patp=PatMax THEN
  249. 242 Ch := 0C;
  250. 243 ELSE
  251. 244 Ch := PatAddr^[Patp];
  252. 245 INC(Patp);
  253. 246 END;
  254. 247 RETURN Ch<>0C;
  255. 248 END GetChar;
  256. 249
  257. 250 (*. . . . . . . . . . . . . . . . . . .*)
  258. 251
  259. 252 PROCEDURE NextChar;
  260. 253 BEGIN
  261. 254 IF NOT GetChar(Ch) THEN
  262. 255 Error(1);
  263. 256 END;
  264. 257 END NextChar;
  265. 258
  266. 259 (*. . . . . . . . . . . . . . . . . . .*)
  267. 260
  268. 261 PROCEDURE ReadNumber(VAR c:CARDINAL);
  269. 262 VAR
  270. 263 temp : LONGCARD;
  271. 264 BEGIN
  272. 265 IF Ch='*' THEN
  273. 266 NextChar;
  274. 267 IF ArgNo=ArgCount THEN
  275. 268 Error(3);
  276. 269 END;
  277. 270 Data:=ArgList[ArgNo];
  278. 271 DataSize:=Size[ArgNo];
  279. 272 INC(ArgNo);
  280. 273 ReadLong(temp);
  281. 274 IF temp>255 THEN
  282. 275 Error(7);
  283. 276 ELSE
  284. 277 c:=CARDINAL(temp);
  285. 278 END;
  286. 279 ELSE
  287. 280 c := 0;
  288. 281 WHILE (Ch>='0') AND (Ch<='9') DO
  289. 282 c := c*10 + ORD(Ch)-48;
  290. 283 NextChar;
  291. 284 END;
  292. 285 END;
  293. 286 END ReadNumber;
  294. 287
  295. 288 (*. . . . . . . . . . . . . . . . . . .*)
  296. 289
  297. 290 PROCEDURE FieldSpecification;
  298. 291 VAR
  299. 292 Lnth,i : CARDINAL;
  300. 293 Just : JustifyTypes;
  301. 294 TestCh : CHAR;
  302. 295 BEGIN
  303. 296 IF ArgNo=ArgCount THEN
  304. 297 Error(3);
  305. 298 END;
  306. 299 RightJustify:=TRUE;
  307. 300 FieldWidth:=0;
  308. 301 Places:=5;
  309. 302 PadChar:=' ';
  310. 303 AlwaysSigned:=FALSE;
  311. 304 NextChar;
  312. 305 IF Ch='%' THEN
  313. 306 StoreChar(Ch);
  314. 307 RETURN;
  315. 308 END;
  316. 309 LOOP
  317. 310 IF Ch='-' THEN
  318. 311 RightJustify:=FALSE;
  319. 312 NextChar;
  320. 313 ELSIF (Ch='+') OR (Ch=' ') THEN
  321. 314 AlwaysSigned:=TRUE; Positive:=Ch; NextChar
  322. 315 ELSIF Ch='0' THEN
  323. 316 PadChar:='0';
  324. 317 NextChar;
  325. 318 ELSIF (Ch>='1') AND (Ch<='9') THEN
  326. 319 ReadNumber(FieldWidth);
  327. 320 IF Ch='.' THEN
  328. 321 NextChar;
  329. 322 ReadNumber(Places);
  330. 323 END;
  331. 324 ELSE
  332. 325 EXIT;
  333. 326 END;
  334. 327 END;
  335. 328 TestCh := CAP(Ch);
  336. 329 IF (TestCh>='A') AND (TestCh<='Z') THEN
  337. 330 TypeChar := Ch;
  338. 331 IF ArgNo=ArgCount THEN
  339. 332 Error(3);
  340. 333 END;
  341. 334 Data := ArgList[ArgNo];
  342. 335 DataSize := Size[ArgNo];
  343. 336 IF (TypeChar>='a') AND (TypeChar<='z') THEN
  344. 337 i := ORD(TypeChar)-ORD('a')
  345. 338 ELSE
  346. 339 i := 26 + (ORD(TypeChar)-ORD('A'))
  347. 340 END;
  348. 341 IF Convert[i]=NULLPROC THEN
  349. 342 Error(4);
  350. 343 ELSE
  351. 344 Convert[i]();
  352. 345 END;
  353. 346 ELSE
  354. 347 Error(4);
  355. 348 END;
  356. 349 IF RightJustify THEN
  357. 350 Just:=Right;
  358. 351 ELSE
  359. 352 Just:=Left;
  360. 353 END;
  361. 354 Lnth := Justify(Just,DestString,FieldWidth,PadChar);
  362. 355 IF Destp+Lnth>DestMax THEN
  363. 356 Lnth:=DestMax-Destp;
  364. 357 END;
  365. 358 Lib.Move(ADR(DestString),ADR(DestAddr^[Destp]),Lnth);
  366. 359 INC(Destp,Lnth);
  367. 360 INC(ArgNo);
  368. 361 END FieldSpecification;
  369. 362
  370. 363 (*. . . . . . . . . . . . . . . . . . .*)
  371. 364
  372. 365 PROCEDURE SwitchChar;
  373. 366 VAR
  374. 367 code,i : CARDINAL;
  375. 368 c : CHAR;
  376. 369 BEGIN
  377. 370 NextChar;
  378. 371 CASE CAP(Ch) OF
  379. 372 'B' : c:=CHR(8); |
  380. 373 'F' : c:=CHR(12); |
  381. 374 'N' : StoreChar(CHR(13));
  382. 375 c:=CHR(10); |
  383. 376 'R' : c:=CHR(13); |
  384. 377 'T' : c:=CHR(9); |
  385. 378 '0'..'9' : code:=ORD(Ch)-48;
  386. 379 FOR i:=0 TO 1 DO
  387. 380 NextChar;
  388. 381 IF (Ch<'0') OR (Ch>'9') THEN
  389. 382 Error(6);
  390. 383 END;
  391. 384 code:=code*10+ORD(Ch)-48;
  392. 385 END;
  393. 386 c := CHR(code); |
  394. 387 ELSE
  395. 388 c := Ch
  396. 389 END; (* cases *)
  397. 390 StoreChar(c);
  398. 391 END SwitchChar;
  399. 392
  400. 393 (*. . . . . . . . . . . . . . . . . . .*)
  401. 394
  402. 395 BEGIN (* Parse *)
  403. 396 ArgNo:=0;
  404. 397 WHILE GetChar(Ch) DO
  405. 398 IF Ch='%' THEN
  406. 399 FieldSpecification
  407. 400 ELSIF Ch='\' THEN
  408. 401 SwitchChar
  409. 402 ELSE
  410. 403 StoreChar(Ch);
  411. 404 END;
  412. 405 END;
  413. 406 StoreChar(0C);
  414. 407 END Parse;
  415. 408
  416. 409 (*...............................................*)
  417. 410
  418. 411 PROCEDURE DoPrintF(VAR pat:ARRAY OF CHAR;VAR arg1,arg2,arg3,arg4,arg5:ARRAY OF BYTE;VAR dest:ARRAY OF CHAR;NumArgs:CARDINAL);
  419. 412 BEGIN
  420. 413 ArgCount := NumArgs;
  421. 414 PatAddr:=ADR(pat);
  422. 415 Patp:=0;
  423. 416 PatMax:=HIGH(pat)+1;
  424. 417 DestAddr:=ADR(dest);
  425. 418 Destp:=0;
  426. 419 DestMax:=HIGH(dest)+1;
  427. 420 ArgList[0]:=ADR(arg1);
  428. 421 Size[0]:=HIGH(arg1)+1;
  429. 422 ArgList[1]:=ADR(arg2);
  430. 423 Size[1]:=HIGH(arg2)+1;
  431. 424 ArgList[2]:=ADR(arg3);
  432. 425 Size[2]:=HIGH(arg3)+1;
  433. 426 ArgList[3]:=ADR(arg4);
  434. 427 Size[3]:=HIGH(arg4)+1;
  435. 428 ArgList[4]:=ADR(arg5);
  436. 429 Size[4]:=HIGH(arg5)+1;
  437. 430 Digits := UpperDigits;
  438. 431 Parse;
  439. 432 END DoPrintF;
  440. 433
  441. 434 (*...............................................*)
  442. 435
  443. 436 PROCEDURE NewConversion(TypeChar:CHAR; ConvertRoutine:PROC);
  444. 437 VAR
  445. 438 i : CARDINAL;
  446. 439 BEGIN
  447. 440 IF (CAP(TypeChar)>='A') AND (CAP(TypeChar)<='Z') THEN
  448. 441 IF (TypeChar>='a') AND (TypeChar<='z') THEN
  449. 442 i := ORD(TypeChar)-ORD('a')
  450. 443 ELSE
  451. 444 i := 26 + (ORD(TypeChar)-ORD('A'))
  452. 445 END;
  453. 446 Convert[i] := ConvertRoutine
  454. 447 ELSE
  455. 448 Error(8);
  456. 449 END;
  457. 450 END NewConversion;
  458. 451
  459. 452 (*..................................................*)
  460. 453
  461. 454 PROCEDURE InitPrintF;
  462. 455 VAR
  463. 456 i : CARDINAL;
  464. 457 BEGIN
  465. 458 FOR i:=0 TO 51 DO
  466. 459 Convert[i]:=PROC(NIL)
  467. 460 END;
  468. 461 NewConversion('i',IntToString);
  469. 462 NewConversion('u',CardToString);
  470. 463 NewConversion('H',CardToString);
  471. 464 NewConversion('h',LowerCaseHex);
  472. 465 NewConversion('X',CardToString);
  473. 466 NewConversion('x',LowerCaseHex);
  474. 467 NewConversion('o',CardToString);
  475. 468 NewConversion('c',CopyChar);
  476. 469 NewConversion('s',CopyString);
  477. 470 END InitPrintF;
  478. 471
  479. 472 (*..................................................*)
  480. 473
  481. 474 BEGIN
  482. 475 InitPrintF;
  483. 476 END PrintFBase.
  484. 477
  485. 6 errors