STR.MOD 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * STR.MOD - String functions *
  5. * *
  6. * COPYRIGHT (C) 1987..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. (*%F _fdata *)
  11. (*# call(seg_name => null) *)
  12. (*%E *)
  13. (*%T _fdata *)
  14. (*# call(seg_name => STR) *)
  15. (*# data(seg_name => null) *)
  16. (*%E *)
  17. (*# module(implementation=>off) *)
  18. (*# call(o_a_copy => off) *)
  19. (*# check(stack=>off,
  20. index=>off,
  21. range=>off,
  22. overflow=>off,
  23. nil_ptr=>off) *)
  24. IMPLEMENTATION MODULE Str;
  25. IMPORT Lib, MATHLIB, SYSTEM;
  26. CONST
  27. StrictRealConv = FALSE ;
  28. (*# save *)
  29. (*%T _DLL *)
  30. (*# call(seg_name=>STRDLL) *)
  31. (*%E *)
  32. PROCEDURE Caps(VAR S: ARRAY OF CHAR); IN AsmLib;
  33. PROCEDURE Lows(VAR S: ARRAY OF CHAR); IN AsmLib;
  34. PROCEDURE Compare(S1,S2: ARRAY OF CHAR) : INTEGER; IN AsmLib;
  35. PROCEDURE Length(S : ARRAY OF CHAR) : CARDINAL; IN AsmLib;
  36. PROCEDURE Concat(VAR R: ARRAY OF CHAR; S1,S2: ARRAY OF CHAR); IN AsmLib;
  37. PROCEDURE Append(VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR); IN AsmLib;
  38. PROCEDURE Copy (VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR); IN AsmLib;
  39. PROCEDURE Slice (VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR; P,L: CARDINAL); IN AsmLib;
  40. PROCEDURE Pos(S,P: ARRAY OF CHAR) : CARDINAL; IN AsmLib;
  41. PROCEDURE NextPos(S,P: ARRAY OF CHAR; Place: CARDINAL) : CARDINAL; IN AsmLib;
  42. PROCEDURE CharPos(S: ARRAY OF CHAR; C: CHAR) : CARDINAL; IN AsmLib;
  43. PROCEDURE RCharPos(S: ARRAY OF CHAR; C: CHAR) : CARDINAL; IN AsmLib;
  44. PROCEDURE Same(Stg,Pattern:ARRAY OF CHAR):BOOLEAN; IN AsmLib;
  45. PROCEDURE Count(Stg:ARRAY OF CHAR;Ch:CHAR):CARDINAL; IN AsmLib;
  46. (*# restore *)
  47. PROCEDURE Prepend(VAR S1: ARRAY OF CHAR; S2: ARRAY OF CHAR);
  48. VAR
  49. ShiftLen: CARDINAL;
  50. S1Len, S2Len: CARDINAL;
  51. BEGIN
  52. S1Len:=Length(S1)+1;
  53. S2Len:=Length(S2);
  54. IF S2Len > HIGH(S1) THEN
  55. Copy(S1, S2);
  56. RETURN;
  57. END;
  58. ShiftLen:=HIGH(S1)-S2Len + 1;
  59. IF ShiftLen > S1Len THEN ShiftLen:=S1Len END;
  60. Lib.Move(ADR(S1), ADR(S1[S2Len]), ShiftLen);
  61. Lib.Move(ADR(S2), ADR(S1), S2Len);
  62. END Prepend;
  63. PROCEDURE Subst(VAR S1: ARRAY OF CHAR; Target: ARRAY OF CHAR; New: ARRAY OF CHAR);
  64. VAR
  65. TargetPos, TargetLen: CARDINAL;
  66. BEGIN
  67. TargetPos:=Pos(S1, Target);
  68. IF TargetPos = MAX(CARDINAL) THEN RETURN END;
  69. TargetLen:=Length(Target);
  70. Lib.Move(ADR(S1[TargetPos+TargetLen]), ADR(S1[TargetPos]), Length(S1)-TargetLen-TargetPos+1);
  71. Insert(S1, New, TargetPos);
  72. END Subst;
  73. PROCEDURE Delete(VAR S: ARRAY OF CHAR; P,L: CARDINAL);
  74. VAR
  75. Le,I : CARDINAL;
  76. BEGIN
  77. IF L # 0 THEN
  78. Le := Length(S);
  79. IF P < Le THEN
  80. IF L < Le - P THEN
  81. I := P+L;
  82. REPEAT
  83. S[P] := S[I];
  84. INC(P);
  85. INC(I);
  86. UNTIL I=Le;
  87. END;
  88. S[P] := CHR(0);
  89. END;
  90. END;
  91. END Delete;
  92. PROCEDURE Insert(VAR S1: ARRAY OF CHAR; S2: ARRAY OF CHAR; P: CARDINAL);
  93. VAR
  94. I,J,C,L : CARDINAL;
  95. BEGIN
  96. L := Length(S1);
  97. I := Length(S2);
  98. C := L;
  99. IF C < P THEN P := C END;
  100. DEC(C,P);
  101. FOR J := C TO 0 BY -1 DO
  102. IF (J+P+I <= HIGH(S1)) THEN S1[J+P+I] := S1[J+P]; END;
  103. END;
  104. J := 0;
  105. WHILE (J<I) AND (P+J <= HIGH(S1)) DO
  106. S1[P+J] := S2[J];
  107. INC(J);
  108. END;
  109. END Insert;
  110. PROCEDURE Item(VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR; T: CHARSET; N: CARDINAL);
  111. VAR
  112. I,J : CARDINAL;
  113. HR,L : CARDINAL;
  114. BEGIN
  115. I := 0;
  116. L := Length(S);
  117. LOOP
  118. WHILE (I < L) AND (S[I] IN T) DO INC(I); END; (* Skip separators *)
  119. IF (N = 0) OR (I = L) THEN EXIT END;
  120. DEC(N);
  121. WHILE (I < L) AND NOT (S[I] IN T) DO INC(I); END; (* Skip item *)
  122. END;
  123. J := 0;
  124. HR := HIGH(R);
  125. WHILE (I < L) AND NOT (S[I] IN T) AND (J <= HR) DO
  126. R[J] := S[I];
  127. INC(I);
  128. INC(J);
  129. END;
  130. IF (J <= HR) THEN R[J] := CHR(0); END;
  131. END Item;
  132. PROCEDURE ItemS(VAR R: ARRAY OF CHAR; S: ARRAY OF CHAR;
  133. T: ARRAY OF CHAR; N: CARDINAL);
  134. VAR
  135. CS : CHARSET;
  136. I : CARDINAL;
  137. BEGIN
  138. I := Length(T);
  139. CS := CHARSET{};
  140. WHILE I>0 DO
  141. DEC(I);
  142. INCL(CS,T[I]);
  143. END;
  144. Item(R,S,CS,N);
  145. END ItemS;
  146. PROCEDURE Match(Source,Pattern: ARRAY OF CHAR) : BOOLEAN;
  147. (*
  148. returns TRUE if the string in Source matches the string in Pattern
  149. The pattern may contain any number of the wild characters '*' and '?'
  150. '?' matches any single character
  151. '*' matches any sequence of charcters (including a zero length sequence)
  152. EG '*m?t*i*' will match 'Automatic'
  153. *)
  154. PROCEDURE Rmatch(VAR s: ARRAY OF CHAR; i: CARDINAL;
  155. VAR p: ARRAY OF CHAR; j: CARDINAL) : BOOLEAN;
  156. (* s = to be tested , i = position in s *)
  157. (* p = pattern to match ,j = position in p *)
  158. VAR
  159. matched: BOOLEAN;
  160. k : CARDINAL;
  161. BEGIN
  162. IF p[0]=CHR(0) THEN RETURN TRUE END;
  163. LOOP
  164. IF ((i > HIGH(s)) OR (s[i] = CHR(0))) AND
  165. ((j > HIGH(p)) OR (p[j] = CHR(0))) THEN
  166. RETURN TRUE
  167. ELSIF ((j > HIGH(p)) OR (p[j] = CHR(0))) THEN
  168. RETURN FALSE
  169. ELSIF (p[j] = '*') THEN
  170. k :=i;
  171. IF ((j = HIGH(p)) OR (p[j+1] = CHR(0))) THEN
  172. RETURN TRUE
  173. ELSE
  174. LOOP
  175. matched := Rmatch(s,k,p,j+1);
  176. IF matched OR (k > HIGH(s)) OR (s[k] = CHR(0)) THEN
  177. RETURN matched;
  178. END;
  179. INC(k);
  180. END;
  181. END
  182. ELSIF ((p[j]='?')AND(s[i]<>0C)) OR (CAP(p[j]) = CAP(s[i])) THEN
  183. INC(i);
  184. INC(j);
  185. ELSE
  186. RETURN FALSE;
  187. END;
  188. END;
  189. END Rmatch;
  190. BEGIN
  191. RETURN Rmatch(Source,0,Pattern,0);
  192. END Match;
  193. TYPE
  194. ConvIntType = ARRAY ['0'..'F'] OF SHORTCARD;
  195. BA = ARRAY[0..1] OF SHORTCARD;
  196. CONST
  197. ConvStr = '0123456789ABCDEF';
  198. 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 );
  199. Div = BA(0,4);
  200. VAR FloatUse : BOOLEAN;
  201. (*%F _WINDOWS *)
  202. PROCEDURE FixRealToStr(V:LONGREAL;Precision:CARDINAL;VAR S:ARRAY OF CHAR;VAR OK:BOOLEAN);
  203. VAR
  204. j,i,l : CARDINAL;
  205. X : MATHLIB.PackedBcd;
  206. c : CHAR;
  207. NoDigits : BOOLEAN;
  208. Z : LONGREAL;
  209. BEGIN
  210. OK := TRUE;
  211. IF Precision > 17 THEN
  212. Precision := 17;
  213. END;
  214. l := HIGH(S);
  215. j := 0;
  216. NoDigits := TRUE;
  217. IF ABS(V) >= 1.0E18 THEN
  218. S[0] := '?';
  219. INC(j);
  220. OK := FALSE;
  221. ELSE
  222. LOOP
  223. Z := V * MATHLIB.IntPow(10.0,Precision);
  224. IF ABS(Z) < 1.0E18 THEN
  225. EXIT;
  226. END;
  227. DEC(Precision);
  228. END;
  229. X := MATHLIB.LongToBcd(Z);
  230. IF X[9]=80H THEN
  231. S[0] := '-';
  232. INC(j);
  233. END;
  234. FOR i := 17 TO 0 BY -1 DO
  235. c := CHAR(SHORTCARD('0') + (X[i DIV 2] >> Div[i MOD 2]) MOD 16);
  236. IF (c # '0') OR (i = Precision) OR NOT NoDigits THEN
  237. NoDigits := FALSE;
  238. IF j > l THEN
  239. OK := FALSE;
  240. RETURN;
  241. END;
  242. S[j] := c;
  243. INC(j);
  244. END;
  245. IF (i = Precision) AND (i # 0) THEN
  246. IF j > l THEN
  247. OK := FALSE;
  248. RETURN;
  249. END;
  250. S[j] := '.';
  251. INC(j);
  252. END;
  253. END;
  254. END;
  255. IF j <= l THEN
  256. S[j] := CHR(0);
  257. END;
  258. END FixRealToStr;
  259. (*%E *)
  260. (*%T _WINDOWS *)
  261. PROCEDURE FixRealToStr(V:LONGREAL;Precision:CARDINAL;VAR S:ARRAY OF CHAR;VAR OK:BOOLEAN);
  262. VAR
  263. j,l,m : INTEGER;
  264. t : LONGREAL;
  265. BEGIN
  266. OK := TRUE;
  267. IF V = 0.0 THEN
  268. FOR j := 0 TO Precision + 1 DO
  269. S[j] := '0';
  270. END; (*FOR*)
  271. S[1] := '.';
  272. S[Precision+2] := 0C;
  273. ELSE
  274. S[0] := 0C;
  275. IF V < 0.0 THEN
  276. Copy(S,'-');
  277. V := -V;
  278. END; (*IF*)
  279. t := MATHLIB.IntPow(10.0,INTEGER(Precision));
  280. V := (V * t + 0.5) / t;
  281. m := TRUNC(MATHLIB.Log10(V));
  282. IF m <= 0 THEN
  283. l := 0;
  284. t := V;
  285. ELSE
  286. l := m;
  287. t := V / MATHLIB.IntPow(10.0,m);
  288. END; (*IF*)
  289. FOR j := l TO (-INTEGER(Precision)) BY -1 DO
  290. Append(S,CHR(TRUNC(t) + 48));
  291. IF j = 0 THEN
  292. Append(S,'.');
  293. END; (*IF*)
  294. t := (t - LONGREAL(TRUNC(t))) * 10.0;
  295. END; (*FOR*)
  296. END; (*IF*)
  297. END FixRealToStr;
  298. (*%E *)
  299. PROCEDURE CheckBase(VAR b: CARDINAL);
  300. BEGIN
  301. IF b < 2 THEN b := 2; END;
  302. IF b > 16 THEN b := 16; END;
  303. END CheckBase;
  304. PROCEDURE Reverse(VAR s: ARRAY OF CHAR; l,h: CARDINAL);
  305. VAR T : CHAR;
  306. BEGIN
  307. WHILE l < h DO
  308. T := s[l];
  309. s[l] := s[h];
  310. s[h] := T;
  311. INC(l);
  312. DEC(h);
  313. END;
  314. END Reverse;
  315. PROCEDURE IntToStr(V: LONGINT;VAR S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN);
  316. VAR
  317. i,l : CARDINAL;
  318. b : LONGCARD;
  319. BEGIN
  320. OK := TRUE;
  321. l := HIGH(S);
  322. CheckBase( Base );
  323. b := VAL( LONGCARD,Base );
  324. IF V < 0 THEN
  325. S[0] := '-';
  326. i := 1;
  327. V := -V;
  328. ELSIF FloatUse THEN
  329. S[0] := '+';
  330. i := 1;
  331. ELSE
  332. i := 0;
  333. END;
  334. LOOP
  335. IF i > l THEN OK := FALSE; EXIT; END;
  336. S[i] := ConvStr[CARDINAL( LONGCARD(V) MOD b )];
  337. INC(i);
  338. V := LONGCARD(V) DIV b;
  339. IF V = 0 THEN EXIT END;
  340. END;
  341. IF i <= l THEN S[i] := CHR(0); END;
  342. IF S[0] < '0' THEN
  343. Reverse( S,1,i-1 );
  344. ELSE
  345. Reverse( S,0,i-1 );
  346. END;
  347. END IntToStr;
  348. PROCEDURE CardToStr(V: LONGCARD; VAR S: ARRAY OF CHAR;
  349. Base: CARDINAL; VAR OK: BOOLEAN);
  350. VAR
  351. i,l : CARDINAL;
  352. b : LONGCARD;
  353. BEGIN
  354. OK := TRUE;
  355. l := HIGH(S);
  356. CheckBase( Base );
  357. b := VAL( LONGCARD,Base );
  358. i := 0;
  359. LOOP
  360. IF i > l THEN OK := FALSE; EXIT END;
  361. S[i] := ConvStr[CARDINAL( V MOD b )];
  362. INC(i);
  363. V := V DIV b;
  364. IF V = 0 THEN EXIT END;
  365. END;
  366. IF i <= l THEN S[i] := CHR(0); END;
  367. Reverse( S,0,i-1 );
  368. END CardToStr;
  369. (*$V-*)
  370. PROCEDURE StrToCI(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGCARD;
  371. VAR
  372. i,l : CARDINAL;
  373. b,t,y : LONGCARD;
  374. c : CHAR;
  375. x : SHORTCARD;
  376. BEGIN
  377. CheckBase( Base );
  378. b := VAL( LONGCARD,Base);
  379. i := 0;
  380. l := HIGH( S );
  381. IF (S[0] = '-') OR (S[0] = '+') THEN
  382. i := 1;
  383. END;
  384. t := 0;
  385. IF S[i] = CHR(0) THEN OK := FALSE; END;
  386. WHILE (i <= l) AND (S[i] # CHR(0)) DO
  387. c := S[i];
  388. IF (c < '0') OR (c > 'F') THEN
  389. OK := FALSE;
  390. RETURN t;
  391. END;
  392. x := ConvInt[c];
  393. IF (x > SHORTCARD(b)-1 ) OR (t > (MAX(LONGCARD)-LONGCARD(x)) DIV b) THEN OK := FALSE; END;
  394. t := t*b+VAL( LONGCARD,x );
  395. INC( i );
  396. END;
  397. RETURN t;
  398. END StrToCI;
  399. PROCEDURE StrToInt(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGINT;
  400. VAR t : LONGCARD;
  401. BEGIN
  402. OK := TRUE;
  403. t := StrToCI( S,Base,OK);
  404. IF t > 7FFFFFFFH THEN OK := FALSE; END;
  405. IF S[0] = '-' THEN
  406. RETURN -LONGINT(t)
  407. ELSE
  408. RETURN LONGINT(t);
  409. END;
  410. END StrToInt;
  411. PROCEDURE StrToCard(S: ARRAY OF CHAR; Base: CARDINAL; VAR OK: BOOLEAN) : LONGCARD;
  412. VAR t : LONGCARD;
  413. BEGIN
  414. OK := TRUE;
  415. t := StrToCI( S,Base,OK);
  416. IF S[0] = '-' THEN OK := FALSE; END;
  417. RETURN t;
  418. END StrToCard;
  419. PROCEDURE StrToReal(S: ARRAY OF CHAR; VAR OK: BOOLEAN) : LONGREAL;
  420. CONST
  421. Zero = 0.0;
  422. VAR
  423. c,expsign : CHAR;
  424. exp,after : INTEGER;
  425. i : CARDINAL;
  426. res,p10 : LONGREAL;
  427. Neg : BOOLEAN;
  428. BEGIN
  429. OK := TRUE;
  430. c := S[0];
  431. Neg := FALSE;
  432. IF c = '+' THEN
  433. i := 1;
  434. ELSIF c = '-' THEN
  435. i := 1;
  436. Neg := TRUE;
  437. ELSE
  438. i := 0;
  439. END; (*IF*)
  440. res := Zero;
  441. c := S[i];
  442. WHILE (c # '.') & (i <= HIGH(S)) DO
  443. IF (c > '9') OR (c < '0') THEN
  444. IF StrictRealConv & (c = 0C) THEN
  445. OK := FALSE;
  446. RETURN Zero;
  447. ELSE
  448. c := '.';
  449. DEC(i) ;
  450. END; (*IF*)
  451. ELSE
  452. res := res * 10.0 + VAL(LONGREAL,ORD(c) - ORD('0'));
  453. INC(i);
  454. c := S[i];
  455. END; (*IF*)
  456. END; (*WHILE*)
  457. after := 0;
  458. IF i >= HIGH(S) THEN
  459. IF StrictRealConv THEN
  460. OK := FALSE;
  461. RETURN Zero;
  462. ELSE
  463. RETURN res;
  464. END; (*IF*)
  465. END; (*IF*)
  466. INC(i);
  467. c := S[i];
  468. WHILE (i <= HIGH(S)) & (c # 0C) & (c # 'E') DO
  469. IF (c > '9') OR (c < '0') THEN
  470. OK := FALSE;
  471. RETURN Zero;
  472. END; (*IF*)
  473. res := res * 10.0 + VAL(LONGREAL,ORD(c) - ORD('0'));
  474. INC(i);
  475. INC(after);
  476. c := S[i];
  477. END; (*WHILE*)
  478. IF c = 'E' THEN
  479. INC(i);
  480. expsign := S[i];
  481. IF expsign = '+' THEN
  482. INC(i)
  483. ELSIF expsign = '-' THEN
  484. INC(i)
  485. END; (*IF*)
  486. c := S[i];
  487. exp := 0;
  488. WHILE (i <= HIGH(S)) & (c # 0C) DO
  489. IF (c > '9') OR (c < '0') THEN
  490. OK := FALSE;
  491. RETURN Zero;
  492. END; (*IF*)
  493. exp := exp * 8 + exp * 2 + INTEGER(ORD(c) - ORD('0'));
  494. INC(i);
  495. c := S[i];
  496. END; (*WHILE*)
  497. IF expsign = '-' THEN
  498. exp := -exp;
  499. END; (*IF*)
  500. ELSE
  501. exp := 0;
  502. END; (*IF*)
  503. exp := exp - after;
  504. p10 := 1.0;
  505. FOR i := 1 TO ABS(exp) DO
  506. p10 := p10 * 10.0;
  507. END; (*FOR*)
  508. IF Neg THEN
  509. res := - res;
  510. END; (*IF*)
  511. IF exp < 0 THEN
  512. RETURN res / p10;
  513. ELSE
  514. RETURN res * p10;
  515. END; (*IF*)
  516. END StrToReal;
  517. (*%F _WINDOWS *)
  518. PROCEDURE RealToStr(V: LONGREAL; Precision: CARDINAL; Eng: BOOLEAN;
  519. VAR S: ARRAY OF CHAR; VAR OK: BOOLEAN);
  520. VAR
  521. X : MATHLIB.PackedBcd;
  522. i,j,l : CARDINAL;
  523. r,t : LONGREAL;
  524. Exp,m : INTEGER;
  525. Str : ARRAY[0..7] OF CHAR;
  526. tb,
  527. FirstTime: BOOLEAN;
  528. BEGIN
  529. OK := TRUE;
  530. l := HIGH( S );
  531. IF Precision = 0 THEN
  532. Precision := 1;
  533. ELSIF Precision > 17 THEN
  534. Precision := 17;
  535. END;
  536. FirstTime := TRUE;
  537. IF V # 0.0 THEN
  538. t := MATHLIB.Log10( ABS( V ) );
  539. ELSE
  540. t := 1.0;
  541. END;
  542. Exp := TRUNC( t );
  543. LOOP
  544. m := 1;
  545. IF Eng THEN
  546. IF (ABS(V) < 1.0) THEN
  547. DEC(m,ABS(Exp) MOD 3 );
  548. IF m < 1 THEN INC(m,3); END;
  549. ELSE
  550. INC(m,Exp MOD 3 );
  551. END;
  552. END;
  553. X := MATHLIB.LongToBcd( V*MATHLIB.IntPow(10.0,INTEGER(Precision)-Exp-1) );
  554. j := 0;
  555. IF NOT FirstTime THEN
  556. EXIT;
  557. ELSIF (X[Precision DIV 2] >> Div[Precision MOD 2 ] ) MOD 16 # 0 THEN
  558. INC( Exp );
  559. FirstTime := FALSE;
  560. ELSIF (X[(Precision-1) DIV 2] >> Div[(Precision-1) MOD 2 ] ) MOD 16 = 0 THEN
  561. DEC( Exp );
  562. FirstTime := FALSE;
  563. ELSE
  564. EXIT;
  565. END;
  566. END;
  567. IF X[9]=80H THEN
  568. S[0] := '-';
  569. ELSE
  570. S[0] := ' ';
  571. END;
  572. INC(j);
  573. FOR i := Precision-1 TO 0 BY -1 DO
  574. IF j > l THEN OK := FALSE; RETURN; END;
  575. S[j] := CHAR( SHORTCARD('0') + (X[i DIV 2] >> Div[i MOD 2 ] ) MOD 16 );
  576. INC( j );
  577. IF i = Precision-CARDINAL(m) THEN
  578. IF j > l THEN OK := FALSE; RETURN; END;
  579. S[j] := '.';
  580. INC(j);
  581. END;
  582. END;
  583. IF j > l THEN OK := FALSE; RETURN; END;
  584. S[j] := 'E';
  585. INC( j );
  586. IF j <= l THEN S[j] := CHR(0); END;
  587. tb := FloatUse;
  588. FloatUse := TRUE;
  589. IntToStr( VAL( LONGINT,Exp-m+1 ),Str,10,OK );
  590. FloatUse := tb;
  591. IF ( Length( Str ) + j )-1 > l THEN OK := FALSE; END;
  592. Append( S,Str );
  593. END RealToStr;
  594. (*%E *)
  595. (*%T _WINDOWS *)
  596. PROCEDURE RealToStr(V:LONGREAL;Precision:CARDINAL;Eng:BOOLEAN;VAR S:ARRAY OF CHAR;VAR OK:BOOLEAN);
  597. VAR
  598. j,w : CARDINAL;
  599. m,i : INTEGER;
  600. t : LONGREAL;
  601. BEGIN
  602. OK := TRUE;
  603. S[0] := 0C;
  604. m := 0;
  605. IF Precision > 17 THEN
  606. Precision := 17;
  607. END; (*IF*)
  608. IF V < 0.0 THEN
  609. Copy(S,'-');
  610. V := -V;
  611. END; (*IF*)
  612. IF V # 0.0 THEN
  613. m := TRUNC(MATHLIB.Log10(V));
  614. IF m > 0 THEN
  615. V := V / MATHLIB.IntPow(10.0,m);
  616. END; (*IF*)
  617. IF V < 1.0 THEN
  618. V := V * 10.0;
  619. DEC(m);
  620. END;
  621. t := MATHLIB.IntPow(10.0,INTEGER(Precision));
  622. V := (V * t + 0.5) / t;
  623. IF V >= 10.0 THEN
  624. V := V / 10.0;
  625. INC(m);
  626. END; (*IF*)
  627. IF Eng THEN
  628. i := m;
  629. IF m > 0 THEN
  630. m := ((m + 2) DIV 3) * 3;
  631. ELSE
  632. m := ((m - 2) DIV 3) * 3;
  633. END; (*IF*)
  634. V := V / MATHLIB.IntPow(10.0,m - i);
  635. END; (*IF*)
  636. END; (*IF*)
  637. w := TRUNC(V);
  638. V := (V - LONGREAL(w)) * 10.0;
  639. IF Eng & (Precision > 0) THEN
  640. IF w DIV 100 > 0 THEN
  641. Str.Append(S,CHR((w DIV 100) + 48));
  642. w := w MOD 100;
  643. DEC(Precision);
  644. END; (*IF*)
  645. IF (w DIV 10 > 0) & (Precision > 0) THEN
  646. Str.Append(S,CHR((w DIV 10) + 48));
  647. w := w MOD 10;
  648. DEC(Precision);
  649. END; (*IF*)
  650. END; (*IF*)
  651. IF Precision > 0 THEN
  652. Str.Append(S,CHR(w + 48));
  653. DEC(Precision);
  654. Str.Append(S,'.');
  655. IF Precision > 0 THEN
  656. FOR j := 1 TO Precision DO
  657. Append(S,CHR(TRUNC(V) + 48));
  658. V := (V - LONGREAL(TRUNC(V))) * 10.0;
  659. END; (*FOR*)
  660. END; (*IF*)
  661. END; (*IF*)
  662. IF m < 0 THEN
  663. Str.Append(S,'E-');
  664. m := -m;
  665. ELSE
  666. Str.Append(S,'E+');
  667. END; (*IF*)
  668. IF m DIV 100 > 0 THEN
  669. Str.Append(S,CHR((m DIV 100) + 48));
  670. m := m MOD 100;
  671. END; (*IF*)
  672. IF m DIV 10 > 0 THEN
  673. Str.Append(S,CHR((m DIV 10) + 48));
  674. END; (*IF*)
  675. Str.Append(S,CHR((m MOD 10) + 48));
  676. END RealToStr;
  677. (*%E *)
  678. (*# save,call(o_a_copy=>off,o_a_size=>on)*)
  679. PROCEDURE FindSubStr(Source,Pattern:ARRAY OF CHAR;VAR Pos:ARRAY OF PosLen):BOOLEAN;
  680. VAR
  681. s,p,n,l : CARDINAL;
  682. BEGIN
  683. Lib.Fill(ADR(Pos),SIZE(Pos),0FFH);
  684. IF Length(Source) = 0 THEN
  685. RETURN FALSE;
  686. END; (*IF*)
  687. l := Length(Pattern);
  688. IF l = 0 THEN
  689. Pos[0] := PosLen(0,0);
  690. RETURN TRUE;
  691. END; (*IF*)
  692. IF (Pattern[0] = '*') OR (Pattern[0] = '?') THEN
  693. IF l = 1 THEN
  694. Pos[0].Pos := 0;
  695. IF Pattern[0] = '*' THEN
  696. Pos[0].Pos := 0;
  697. Pos[0].Len := Length(Source);
  698. ELSE
  699. Pos[0] := PosLen(0,1);
  700. END; (*IF*)
  701. RETURN TRUE;
  702. ELSE
  703. s := 0;
  704. END; (*IF*)
  705. ELSE
  706. s := CharPos(Source,Pattern[0]);
  707. IF s = MAX(CARDINAL) THEN
  708. RETURN FALSE;
  709. END; (*IF*)
  710. END; (*IF*)
  711. n := 0;
  712. p := 1;
  713. WHILE p < l DO
  714. INC(s);
  715. IF (s > HIGH(Source)) OR (Source[s] = 0C) THEN
  716. RETURN FALSE;
  717. END; (*IF*)
  718. CASE Pattern[p] OF
  719. '?' : IF n <= HIGH(Pos) THEN
  720. Pos[n].Pos := s;
  721. Pos[n].Len := 1;
  722. INC(n);
  723. END; (*IF*) |
  724. '*' : IF n <= HIGH(Pos) THEN
  725. Pos[n].Pos := s;
  726. IF (p >= HIGH(Pattern)) OR (Pattern[p+1] = 0C) THEN
  727. RETURN TRUE;
  728. ELSE
  729. Pos[n].Len := NextPos(Source,Pattern[p+1],s); (* s/b NextCharPos *)
  730. IF Pos[n].Len = MAX(CARDINAL) THEN
  731. RETURN FALSE;
  732. ELSE
  733. DEC(Pos[n].Len,s);
  734. INC(s,Pos[n].Len);
  735. INC(n);
  736. END; (*IF*)
  737. END; (*IF*)
  738. END; (*IF*)
  739. INC(p); |
  740. ELSE
  741. IF CAP(Pattern[p]) # CAP(Source[s]) THEN
  742. RETURN FALSE;
  743. END; (*IF*)
  744. END; (*CASE*)
  745. INC(p);
  746. END; (*WHILE*)
  747. RETURN TRUE;
  748. END FindSubStr;
  749. (*# restore *)
  750. (* The following are Implemented in asmlib
  751. PROCEDURE CapS(VAR S: ARRAY OF CHAR);
  752. VAR I : CARDINAL;
  753. BEGIN
  754. FOR I := 0 TO HIGH(S) DO S[I] := CAP(S[I]); END;
  755. END CapS;
  756. PROCEDURE Compare(S1,S2: ARRAY OF CHAR) : INTEGER;
  757. VAR
  758. L1,L2,L,Index : CARDINAL;
  759. BEGIN
  760. L1 := Length(S1);
  761. L2 := Length(S2);
  762. IF L1<L2 THEN L := L1 ELSE L := L2 END;
  763. Index := Lib.Compare(ADR(S1),ADR(S2),L);
  764. IF (Index<L) THEN
  765. IF S1[Index] < S2[Index] THEN
  766. RETURN -1
  767. ELSE
  768. RETURN 1;
  769. END;
  770. ELSIF (L1=L2) THEN
  771. RETURN 0
  772. ELSIF (L1<L2) THEN
  773. RETURN -1
  774. ELSE
  775. RETURN 1;
  776. END;
  777. END Compare;
  778. PROCEDURE Length(S1: ARRAY OF CHAR) : CARDINAL;
  779. VAR I : CARDINAL;
  780. BEGIN
  781. RETURN Lib.ScanR(ADR(S1),HIGH(S1)+1,0);
  782. END Length;
  783. PROCEDURE Append(VAR Ns: ARRAY OF CHAR; S: ARRAY OF CHAR);
  784. VAR
  785. I,J : CARDINAL;
  786. c : CHAR;
  787. BEGIN
  788. I := Length(Ns);
  789. J := 0;
  790. WHILE (I <= HIGH(Ns)) AND (J <= HIGH(S)) AND (S[J] <> CHR(0)) DO
  791. Ns[I] := S[J];
  792. INC(I);
  793. INC(J);
  794. END;
  795. IF I<=HIGH(Ns) THEN Ns[I] := CHR(0) END;
  796. END Append;
  797. PROCEDURE Copy(VAR Ns: ARRAY OF CHAR; S: ARRAY OF CHAR);
  798. VAR
  799. H,L : CARDINAL;
  800. BEGIN
  801. H := HIGH(Ns)+1;
  802. L := Length(S);
  803. IF L > H THEN L := H END;
  804. Lib.Move(ADR(S),ADR(Ns),L);
  805. IF L < H THEN Ns[L] := CHR(0) END;
  806. END Copy;
  807. PROCEDURE Concat(VAR Ns: ARRAY OF CHAR; S1,S2: ARRAY OF CHAR);
  808. VAR
  809. I,J : CARDINAL;
  810. BEGIN
  811. J := 0;
  812. WHILE (J <= HIGH(Ns)) AND (J <= HIGH(S1)) AND (S1[J] <> CHAR(0)) DO
  813. Ns[J] := S1[J];
  814. INC(J);
  815. END;
  816. I := 0;
  817. LOOP
  818. IF (J > HIGH(Ns)) THEN EXIT; END;
  819. IF (I > HIGH(S2)) THEN Ns[J] := CHR(0); EXIT; END;
  820. Ns[J] := S2[I];
  821. IF S2[I] = CHR(0) THEN EXIT; END;
  822. INC(I);
  823. INC(J);
  824. END;
  825. END Concat;
  826. PROCEDURE Pos(S,P: ARRAY OF CHAR) : CARDINAL;
  827. VAR
  828. I,J,K,HP,HS : CARDINAL;
  829. BEGIN
  830. HP := HIGH(P);
  831. HS := HIGH(S);
  832. I := 0;
  833. LOOP
  834. IF (I > HS) OR (S[I] = CHR(0)) THEN RETURN MAX(CARDINAL) END;
  835. J := 0;
  836. K := I;
  837. LOOP
  838. IF (J > HP) OR (P[J] = CHR(0)) THEN RETURN I END;
  839. IF K > HS THEN RETURN MAX( CARDINAL ); END;
  840. IF S[K] # P[J] THEN EXIT END;
  841. INC(J);
  842. INC(K);
  843. END;
  844. INC(I);
  845. END;
  846. END Pos;
  847. *)
  848. PROCEDURE StrToC(S: ARRAY OF CHAR; VAR D: ARRAY OF CHAR): BOOLEAN;
  849. VAR
  850. n: CARDINAL;
  851. c: CHAR;
  852. BEGIN
  853. n := 0;
  854. LOOP
  855. IF n > HIGH(D) THEN
  856. RETURN FALSE;
  857. END;
  858. IF n > HIGH(S) THEN
  859. c := 0C;
  860. ELSE
  861. c := S[n];
  862. END;
  863. D[n] := c;
  864. IF c = 0C THEN
  865. RETURN TRUE
  866. END;
  867. INC(n);
  868. END;
  869. END StrToC;
  870. PROCEDURE StrToPas(S: ARRAY OF CHAR; VAR D: ARRAY OF CHAR): BOOLEAN;
  871. VAR
  872. n: CARDINAL;
  873. c: CHAR;
  874. BEGIN
  875. n := 1;
  876. LOOP
  877. IF n > HIGH(D) THEN
  878. D[0] := 0C;
  879. RETURN FALSE;
  880. END;
  881. IF n > SIZE(S) THEN
  882. c := 0C;
  883. ELSE
  884. c := S[n-1];
  885. END;
  886. IF c = 0C THEN
  887. D[0] := CHAR(n-1);
  888. RETURN TRUE
  889. END;
  890. D[n] := c;
  891. INC(n);
  892. END;
  893. END StrToPas;
  894. BEGIN
  895. FloatUse := FALSE;
  896. END Str.
  897.