str.mod 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. (* Copyright (C) 1987 Jensen & Partners International *)
  2. (*$R-,S-,I-,V-,O-*)
  3. IMPLEMENTATION MODULE Str;
  4. IMPORT Lib;
  5. FROM MATHLIB IMPORT PackedBcd,Log10,Pow,LongToBcd;
  6. CONST
  7. StrictRealConv = FALSE ;
  8. PROCEDURE Delete(VAR S: ARRAY OF CHAR; P,L: CARDINAL);
  9. VAR
  10. Le,I : CARDINAL;
  11. BEGIN
  12. Le := Length(S);
  13. IF P < Le THEN
  14. IF L < Le - P THEN
  15. I := P+L;
  16. REPEAT
  17. S[P] := S[I];
  18. INC(P);
  19. INC(I);
  20. UNTIL I=Le;
  21. END;
  22. S[P] := CHR(0);
  23. END;
  24. END Delete;
  25. PROCEDURE Insert(VAR S1: ARRAY OF CHAR; S2: ARRAY OF CHAR; P: CARDINAL);
  26. VAR
  27. I,J,C,L : CARDINAL;
  28. BEGIN
  29. L := Length(S1);
  30. I := Length(S2);
  31. C := L;
  32. IF C < P THEN P := C END;
  33. DEC(C,P);
  34. FOR J := C TO 0 BY -1 DO
  35. IF (J+P+I <= HIGH(S1)) THEN S1[J+P+I] := S1[J+P]; END;
  36. END;
  37. J := 0;
  38. WHILE (J<I) AND (P+J <= HIGH(S1)) DO
  39. S1[P+J] := S2[J];
  40. INC(J);
  41. END;
  42. END Insert;
  43. PROCEDURE Item(VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR; T: CHARSET; N: CARDINAL);
  44. VAR
  45. I,J : CARDINAL;
  46. HR,L : CARDINAL;
  47. BEGIN
  48. I := 0;
  49. L := Length(S);
  50. LOOP
  51. WHILE (I < L) AND (S[I] IN T) DO INC(I); END; (* Skip separators *)
  52. IF (N = 0) OR (I = L) THEN EXIT END;
  53. DEC(N);
  54. WHILE (I < L) AND NOT (S[I] IN T) DO INC(I); END; (* Skip item *)
  55. END;
  56. J := 0;
  57. HR := HIGH(R);
  58. WHILE (I < L) AND NOT (S[I] IN T) AND (J <= HR) DO
  59. R[J] := S[I];
  60. INC(I);
  61. INC(J);
  62. END;
  63. IF (J <= HR) THEN R[J] := CHR(0); END;
  64. END Item;
  65. PROCEDURE ItemS(VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR;
  66. T: ARRAY OF CHAR; N: CARDINAL);
  67. VAR
  68. CS : CHARSET;
  69. I : CARDINAL;
  70. BEGIN
  71. I := Length(T);
  72. CS := CHARSET{};
  73. WHILE I>0 DO
  74. DEC(I);
  75. INCL(CS,T[I]);
  76. END;
  77. Item(R,S,CS,N);
  78. END ItemS;
  79. PROCEDURE Match(Source,Pattern: ARRAY OF CHAR) : BOOLEAN;
  80. (*
  81. returns TRUE if the string in Source matches the string in Pattern
  82. The pattern may contain any number of the wild characters '*' and '?'
  83. '?' matches any single character
  84. '*' matches any sequence of charcters (including a zero length sequence)
  85. EG '*m?t*i*' will match 'Automatic'
  86. *)
  87. PROCEDURE Rmatch(VAR s: ARRAY OF CHAR; i: CARDINAL;
  88. VAR p: ARRAY OF CHAR; j: CARDINAL) : BOOLEAN;
  89. (* s = to be tested , i = position in s *)
  90. (* p = pattern to match ,j = position in p *)
  91. VAR
  92. matched: BOOLEAN;
  93. k : CARDINAL;
  94. BEGIN
  95. IF p[0]=CHR(0) THEN RETURN TRUE END;
  96. LOOP
  97. IF ((i > HIGH(s)) OR (s[i] = CHR(0))) AND
  98. ((j > HIGH(p)) OR (p[j] = CHR(0))) THEN
  99. RETURN TRUE
  100. ELSIF ((j > HIGH(p)) OR (p[j] = CHR(0))) THEN
  101. RETURN FALSE
  102. ELSIF (p[j] = '*') THEN
  103. k :=i;
  104. IF ((j = HIGH(p)) OR (p[j+1] = CHR(0))) THEN
  105. RETURN TRUE
  106. ELSE
  107. REPEAT
  108. matched := Rmatch(s,k,p,j+1);
  109. INC(k);
  110. UNTIL matched OR (k > HIGH(s)) OR (s[k] = CHR(0));
  111. RETURN matched;
  112. END
  113. ELSIF (p[j] <> '?') AND (CAP(p[j]) <> CAP(s[i])) THEN
  114. RETURN FALSE
  115. ELSE
  116. INC(i);
  117. INC(j);
  118. END;
  119. END;
  120. END Rmatch;
  121. BEGIN
  122. RETURN Rmatch(Source,0,Pattern,0);
  123. END Match;
  124. (*$V+*)
  125. (*$R-,S-,I-*)
  126. TYPE
  127. ConvIntType = ARRAY ['0'..'F'] OF SHORTCARD;
  128. BA = ARRAY[0..1] OF SHORTCARD;
  129. CONST
  130. ConvStr = '0123456789ABCDEF';
  131. ConvInt = ConvIntType( 0,1,2,3,4,5,6,7,8,9,255,255,255,255,255,255,255,10,11,12,13,14,15 );
  132. Div = BA(0,4);
  133. VAR FloatUse : BOOLEAN;
  134. PROCEDURE FixRealToStr(V: LONGREAL; Precision: CARDINAL;
  135. VAR S: ARRAY OF CHAR; VAR OK: BOOLEAN);
  136. VAR
  137. j,i,l : CARDINAL;
  138. X : PackedBcd;
  139. c : CHAR;
  140. NoDigits : BOOLEAN;
  141. BEGIN
  142. OK := TRUE;
  143. IF Precision > 17 THEN Precision := 17; END;
  144. l := HIGH( S );
  145. j := 0;
  146. NoDigits := TRUE;
  147. V := V * Pow ( 10.0,VAL( LONGREAL,Precision ) );
  148. IF ABS( V ) >= 1.0E18 THEN
  149. S[0] := '?';
  150. INC( j );
  151. OK := FALSE;
  152. ELSE
  153. X := LongToBcd( V );
  154. IF X[9]=80H THEN
  155. S[0] := '-';
  156. INC(j);
  157. END;
  158. FOR i := 17 TO 0 BY -1 DO
  159. c := CHAR( SHORTCARD('0') + (X[i DIV 2] >> Div[i MOD 2 ] ) MOD 16 );
  160. IF (c # '0') OR (i = Precision) OR NOT NoDigits THEN
  161. NoDigits := FALSE;
  162. IF j > l THEN OK := FALSE; RETURN; END;
  163. S[j] := c;
  164. INC( j );
  165. END;
  166. IF (i = Precision) AND (i # 0) THEN
  167. IF j > l THEN OK := FALSE; RETURN; END;
  168. S[j] := '.';
  169. INC(j);
  170. END;
  171. END;
  172. END;
  173. IF j <= l THEN S[j] := CHR(0); END;
  174. END FixRealToStr;
  175. PROCEDURE CheckBase(VAR b: CARDINAL);
  176. BEGIN
  177. IF b < 2 THEN b := 2; END;
  178. IF b > 16 THEN b := 16; END;
  179. END CheckBase;
  180. PROCEDURE Reverse(VAR s: ARRAY OF CHAR; l,h: CARDINAL);
  181. VAR T : CHAR;
  182. BEGIN
  183. WHILE l < h DO
  184. T := s[l];
  185. s[l] := s[h];
  186. s[h] := T;
  187. INC(l);
  188. DEC(h);
  189. END;
  190. END Reverse;
  191. PROCEDURE IntToStr(V: LONGINT;VAR S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN);
  192. VAR
  193. i,l : CARDINAL;
  194. b : LONGCARD;
  195. BEGIN
  196. OK := TRUE;
  197. l := HIGH(S);
  198. CheckBase( Base );
  199. b := VAL( LONGCARD,Base );
  200. IF V < 0 THEN
  201. S[0] := '-';
  202. i := 1;
  203. V := -V;
  204. ELSIF FloatUse THEN
  205. S[0] := '+';
  206. i := 1;
  207. ELSE
  208. i := 0;
  209. END;
  210. LOOP
  211. IF i > l THEN OK := FALSE; EXIT; END;
  212. S[i] := ConvStr[CARDINAL( LONGCARD(V) MOD b )];
  213. INC(i);
  214. V := LONGCARD(V) DIV b;
  215. IF V = 0 THEN EXIT END;
  216. END;
  217. IF i <= l THEN S[i] := CHR(0); END;
  218. IF S[0] < '0' THEN
  219. Reverse( S,1,i-1 );
  220. ELSE
  221. Reverse( S,0,i-1 );
  222. END;
  223. END IntToStr;
  224. PROCEDURE CardToStr(V: LONGCARD; VAR S: ARRAY OF CHAR;
  225. Base: CARDINAL; VAR OK: BOOLEAN);
  226. VAR
  227. i,l : CARDINAL;
  228. b : LONGCARD;
  229. BEGIN
  230. OK := TRUE;
  231. l := HIGH(S);
  232. CheckBase( Base );
  233. b := VAL( LONGCARD,Base );
  234. i := 0;
  235. LOOP
  236. IF i > l THEN OK := FALSE; EXIT END;
  237. S[i] := ConvStr[CARDINAL( V MOD b )];
  238. INC(i);
  239. V := V DIV b;
  240. IF V = 0 THEN EXIT END;
  241. END;
  242. IF i <= l THEN S[i] := CHR(0); END;
  243. Reverse( S,0,i-1 );
  244. END CardToStr;
  245. (*$V-*)
  246. PROCEDURE StrToCI(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGCARD;
  247. VAR
  248. i,l : CARDINAL;
  249. b,t,y : LONGCARD;
  250. c : CHAR;
  251. x : SHORTCARD;
  252. BEGIN
  253. CheckBase( Base );
  254. b := VAL( LONGCARD,Base);
  255. i := 0;
  256. l := HIGH( S );
  257. IF (S[0] = '-') OR (S[0] = '+') THEN
  258. i := 1;
  259. END;
  260. t := 0;
  261. IF S[i] = CHR(0) THEN OK := FALSE; END;
  262. WHILE (i <= l) AND (S[i] # CHR(0)) DO
  263. c := S[i];
  264. IF (c < '0') OR (c > 'F') THEN OK := FALSE; END;
  265. x := ConvInt[c];
  266. IF (x > SHORTCARD(b)-1 ) OR (t > (MAX(LONGCARD)-LONGCARD(x)) DIV b) THEN OK := FALSE; END;
  267. t := t*b+VAL( LONGCARD,x );
  268. INC( i );
  269. END;
  270. RETURN t;
  271. END StrToCI;
  272. PROCEDURE StrToInt(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGINT;
  273. VAR t : LONGCARD;
  274. BEGIN
  275. OK := TRUE;
  276. t := StrToCI( S,Base,OK);
  277. IF t > 7FFFFFFFH THEN OK := FALSE; END;
  278. IF S[0] = '-' THEN
  279. RETURN -LONGINT(t)
  280. ELSE
  281. RETURN LONGINT(t);
  282. END;
  283. END StrToInt;
  284. PROCEDURE StrToCard(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGCARD;
  285. VAR t : LONGCARD;
  286. BEGIN
  287. OK := TRUE;
  288. t := StrToCI( S,Base,OK);
  289. IF S[0] = '-' THEN OK := FALSE; END;
  290. RETURN t;
  291. END StrToCard;
  292. PROCEDURE StrToReal(S: ARRAY OF CHAR; VAR OK: BOOLEAN) : LONGREAL;
  293. VAR
  294. c,expsign : CHAR;
  295. exp,after : INTEGER;
  296. i : CARDINAL;
  297. res,p10 : LONGREAL;
  298. Neg : BOOLEAN;
  299. CONST
  300. Zero = 0.0;
  301. BEGIN
  302. OK := TRUE;
  303. c := S[0];
  304. Neg := FALSE;
  305. IF c = '+' THEN
  306. i := 1;
  307. ELSIF c = '-' THEN
  308. i := 1; Neg := TRUE;
  309. ELSE
  310. i := 0;
  311. END;
  312. res := 0.0;
  313. c := S[i];
  314. WHILE c <> '.' DO
  315. IF (c > '9') OR (c < '0') THEN
  316. IF StrictRealConv AND ( c = CHAR(0) ) THEN
  317. OK := FALSE; RETURN Zero;
  318. ELSE
  319. c := '.' ; DEC(i) ;
  320. END ;
  321. ELSE
  322. res := res * 10.0 + VAL( LONGREAL, ORD(c) - ORD('0') );
  323. INC(i);
  324. c := S[i];
  325. END ;
  326. END;
  327. after := 0;
  328. INC(i);
  329. c := S[i];
  330. WHILE ( c <> CHAR(0) ) AND ( c <> 'E' ) DO
  331. IF ( c > '9' ) OR ( c < '0' ) THEN OK := FALSE; RETURN Zero; END;
  332. res := res * 10.0 + VAL( LONGREAL, SHORTCARD(c) - SHORTCARD('0') );
  333. INC(i);
  334. INC(after);
  335. c := S[i];
  336. END;
  337. IF c = 'E' THEN
  338. INC(i);
  339. expsign := S[i];
  340. IF expsign = '+' THEN
  341. INC(i)
  342. ELSIF expsign = '-' THEN
  343. INC(i)
  344. END;
  345. c := S[i];
  346. exp := 0;
  347. WHILE c <> CHAR(0) DO
  348. IF ( c > '9' ) OR ( c < '0' ) THEN OK := FALSE; RETURN Zero; END;
  349. exp := exp*8 + exp*2 + INTEGER( SHORTCARD(c) - SHORTCARD('0') );
  350. INC(i);
  351. c := S[i];
  352. END;
  353. IF expsign = '-' THEN exp := -exp END;
  354. ELSE
  355. exp := 0;
  356. END;
  357. exp := exp - after;
  358. p10 := 1.0;
  359. FOR i := 1 TO ABS(exp) DO
  360. p10 := p10 * 10.0;
  361. END;
  362. IF Neg THEN res := - res END;
  363. IF exp < 0 THEN
  364. RETURN res / p10
  365. ELSE
  366. RETURN res * p10;
  367. END;
  368. END StrToReal;
  369. PROCEDURE RealToStr(V: LONGREAL; Precision: CARDINAL; Eng: BOOLEAN;
  370. VAR S: ARRAY OF CHAR; VAR OK: BOOLEAN);
  371. VAR
  372. X : PackedBcd;
  373. i,j,l : CARDINAL;
  374. r,t : LONGREAL;
  375. Exp,m : INTEGER;
  376. Str : ARRAY[0..7] OF CHAR;
  377. tb,
  378. FirstTime: BOOLEAN;
  379. BEGIN
  380. OK := TRUE;
  381. l := HIGH( S );
  382. IF Precision = 0 THEN
  383. Precision := 1;
  384. ELSIF Precision > 17 THEN
  385. Precision := 17;
  386. END;
  387. FirstTime := TRUE;
  388. IF V # 0.0 THEN
  389. t := Log10( ABS( V ) );
  390. ELSE
  391. t := 1.0;
  392. END;
  393. Exp := TRUNC( t );
  394. LOOP
  395. m := 1;
  396. IF Eng THEN
  397. IF (ABS(V) < 1.0) THEN
  398. DEC(m,ABS(Exp) MOD 3 );
  399. IF m < 1 THEN INC(m,3); END;
  400. ELSE
  401. INC(m,Exp MOD 3 );
  402. END;
  403. END;
  404. X := LongToBcd( V*Pow( 10.0,VAL( LONGREAL,INTEGER(Precision)-Exp-1)) );
  405. j := 0;
  406. IF NOT FirstTime THEN
  407. EXIT;
  408. ELSIF (X[Precision DIV 2] >> Div[Precision MOD 2 ] ) MOD 16 # 0 THEN
  409. INC( Exp );
  410. FirstTime := FALSE;
  411. ELSIF (X[(Precision-1) DIV 2] >> Div[(Precision-1) MOD 2 ] ) MOD 16 = 0 THEN
  412. DEC( Exp );
  413. FirstTime := FALSE;
  414. ELSE
  415. EXIT;
  416. END;
  417. END;
  418. IF X[9]=80H THEN
  419. S[0] := '-';
  420. ELSE
  421. S[0] := ' ';
  422. END;
  423. INC(j);
  424. FOR i := Precision-1 TO 0 BY -1 DO
  425. IF j > l THEN OK := FALSE; RETURN; END;
  426. S[j] := CHAR( SHORTCARD('0') + (X[i DIV 2] >> Div[i MOD 2 ] ) MOD 16 );
  427. INC( j );
  428. IF i = Precision-CARDINAL(m) THEN
  429. IF j > l THEN OK := FALSE; RETURN; END;
  430. S[j] := '.';
  431. INC(j);
  432. END;
  433. END;
  434. IF j > l THEN OK := FALSE; RETURN; END;
  435. S[j] := 'E';
  436. INC( j );
  437. IF j <= l THEN S[j] := CHR(0); END;
  438. tb := FloatUse;
  439. FloatUse := TRUE;
  440. IntToStr( VAL( LONGINT,Exp-m+1 ),Str,10,OK );
  441. FloatUse := tb;
  442. IF ( Length( Str ) + j )-1 > l THEN OK := FALSE; END;
  443. Append( S,Str );
  444. END RealToStr;
  445. (* The following are Implemented in AsmLib
  446. PROCEDURE CapS(VAR S: ARRAY OF CHAR);
  447. VAR I : CARDINAL;
  448. BEGIN
  449. FOR I := 0 TO HIGH(S) DO S[I] := CAP(S[I]); END;
  450. END CapS;
  451. PROCEDURE Compare(S1,S2: ARRAY OF CHAR) : INTEGER;
  452. VAR
  453. L1,L2,L,Index : CARDINAL;
  454. BEGIN
  455. L1 := Length(S1);
  456. L2 := Length(S2);
  457. IF L1<L2 THEN L := L1 ELSE L := L2 END;
  458. Index := Lib.Compare(ADR(S1),ADR(S2),L);
  459. IF (Index<L) THEN
  460. IF S1[Index] < S2[Index] THEN
  461. RETURN -1
  462. ELSE
  463. RETURN 1;
  464. END;
  465. ELSIF (L1=L2) THEN
  466. RETURN 0
  467. ELSIF (L1<L2) THEN
  468. RETURN -1
  469. ELSE
  470. RETURN 1;
  471. END;
  472. END Compare;
  473. PROCEDURE Length(S1: ARRAY OF CHAR) : CARDINAL;
  474. VAR I : CARDINAL;
  475. BEGIN
  476. RETURN Lib.ScanR(ADR(S1),HIGH(S1)+1,0);
  477. END Length;
  478. PROCEDURE Append(VAR Ns: ARRAY OF CHAR; S: ARRAY OF CHAR);
  479. VAR
  480. I,J : CARDINAL;
  481. c : CHAR;
  482. BEGIN
  483. I := Length(Ns);
  484. J := 0;
  485. WHILE (I <= HIGH(Ns)) AND (J <= HIGH(S)) AND (S[J] <> CHR(0)) DO
  486. Ns[I] := S[J];
  487. INC(I);
  488. INC(J);
  489. END;
  490. IF I<=HIGH(Ns) THEN Ns[I] := CHR(0) END;
  491. END Append;
  492. PROCEDURE Copy(VAR Ns: ARRAY OF CHAR; S: ARRAY OF CHAR);
  493. VAR
  494. H,L : CARDINAL;
  495. BEGIN
  496. H := HIGH(Ns)+1;
  497. L := Length(S);
  498. IF L > H THEN L := H END;
  499. Lib.Move(ADR(S),ADR(Ns),L);
  500. IF L < H THEN Ns[L] := CHR(0) END;
  501. END Copy;
  502. PROCEDURE Concat(VAR Ns: ARRAY OF CHAR; S1,S2: ARRAY OF CHAR);
  503. VAR
  504. I,J : CARDINAL;
  505. BEGIN
  506. J := 0;
  507. WHILE (J <= HIGH(Ns)) AND (J <= HIGH(S1)) AND (S1[J] <> CHAR(0)) DO
  508. Ns[J] := S1[J];
  509. INC(J);
  510. END;
  511. I := 0;
  512. LOOP
  513. IF (J > HIGH(Ns)) THEN EXIT; END;
  514. IF (I > HIGH(S2)) THEN Ns[J] := CHR(0); EXIT; END;
  515. Ns[J] := S2[I];
  516. IF S2[I] = CHR(0) THEN EXIT; END;
  517. INC(I);
  518. INC(J);
  519. END;
  520. END Concat;
  521. PROCEDURE Pos(S,P: ARRAY OF CHAR) : CARDINAL;
  522. VAR
  523. I,J,K,HP,HS : CARDINAL;
  524. BEGIN
  525. HP := HIGH(P);
  526. HS := HIGH(S);
  527. I := 0;
  528. LOOP
  529. IF (I > HS) OR (S[I] = CHR(0)) THEN RETURN MAX(CARDINAL) END;
  530. J := 0;
  531. K := I;
  532. LOOP
  533. IF (J > HP) OR (P[J] = CHR(0)) THEN RETURN I END;
  534. IF K > HS THEN RETURN MAX( CARDINAL ); END;
  535. IF S[K] # P[J] THEN EXIT END;
  536. INC(J);
  537. INC(K);
  538. END;
  539. INC(I);
  540. END;
  541. END Pos;
  542. *)
  543. BEGIN
  544. FloatUse := FALSE;
  545. END Str.
  546.