WINSTR.MOD 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. (* Release 3.00 *)
  2. (* Copyright (C) 1987..1991 Jensen & Partners International *)
  3. (*# call(o_a_copy => off, near_call=>off, ds_eq_ss=>off) *)
  4. (*# call(seg_name => null) *)
  5. (*# module(implementation=>off, init_code=>off) *)
  6. (*# data(seg_name => null, near_ptr=>off) *)
  7. (*# check(stack=>off,
  8. index=>off,
  9. range=>off,
  10. overflow=>off,
  11. nil_ptr=>off) *)
  12. IMPLEMENTATION MODULE WinStr;
  13. IMPORT Lib, MATHLIB, SYSTEM;
  14. PROCEDURE Compare(S1,S2:ARRAY OF CHAR):INTEGER; IN FarAsm;
  15. PROCEDURE Length(S:ARRAY OF CHAR):CARDINAL; IN FarAsm;
  16. PROCEDURE Concat(VAR R:ARRAY OF CHAR;S1,S2:ARRAY OF CHAR); IN FarAsm;
  17. PROCEDURE Append(VAR R:ARRAY OF CHAR;S:ARRAY OF CHAR); IN FarAsm;
  18. PROCEDURE Copy(VAR R:ARRAY OF CHAR;S:ARRAY OF CHAR); IN FarAsm;
  19. PROCEDURE CharPos(S:ARRAY OF CHAR;C:CHAR):CARDINAL; IN FarAsm;
  20. PROCEDURE Caps(VAR S:ARRAY OF CHAR); IN FarAsm;
  21. PROCEDURE Lows(VAR S:ARRAY OF CHAR); IN FarAsm;
  22. PROCEDURE Slice(VAR R:ARRAY OF CHAR;S:ARRAY OF CHAR;P,L:CARDINAL); IN FarAsm;
  23. PROCEDURE Pos(S,P:ARRAY OF CHAR):CARDINAL; IN FarAsm;
  24. PROCEDURE NextPos(S,P:ARRAY OF CHAR;Place:CARDINAL):CARDINAL; IN FarAsm;
  25. PROCEDURE RCharPos(S:ARRAY OF CHAR;C:CHAR):CARDINAL; IN FarAsm;
  26. PROCEDURE Prepend(VAR S1:ARRAY OF CHAR;S2:ARRAY OF CHAR);
  27. VAR
  28. ShiftLen : CARDINAL;
  29. S1Len,S2Len : CARDINAL;
  30. BEGIN
  31. S1Len:=Length(S1)+1;
  32. S2Len:=Length(S2);
  33. IF S2Len > HIGH(S1) THEN
  34. Copy(S1,S2);
  35. RETURN;
  36. END;
  37. ShiftLen := HIGH(S1) - S2Len + 1;
  38. IF ShiftLen > S1Len THEN
  39. ShiftLen := S1Len
  40. END; (*IF*)
  41. Lib.Move(ADR(S1),ADR(S1[S2Len]),ShiftLen);
  42. Lib.Move(ADR(S2),ADR(S1),S2Len);
  43. END Prepend;
  44. PROCEDURE Subst(VAR S1:ARRAY OF CHAR;Target:ARRAY OF CHAR;New:ARRAY OF CHAR);
  45. VAR
  46. TargetPos,
  47. TargetLen : CARDINAL;
  48. BEGIN
  49. TargetPos := Pos(S1,Target);
  50. IF TargetPos = MAX(CARDINAL) THEN
  51. RETURN
  52. END; (*IF*)
  53. TargetLen := Length(Target);
  54. Lib.Move(ADR(S1[TargetPos+TargetLen]),ADR(S1[TargetPos]),Length(S1)-TargetLen-TargetPos+1);
  55. Insert(S1,New,TargetPos);
  56. END Subst;
  57. PROCEDURE Delete(VAR S:ARRAY OF CHAR;P,L:CARDINAL);
  58. VAR
  59. Len,i : CARDINAL;
  60. BEGIN
  61. IF L # 0 THEN
  62. Len := Length(S);
  63. IF P < Len THEN
  64. IF L < Len - P THEN
  65. i := P+L;
  66. REPEAT
  67. S[P] := S[i];
  68. INC(P);
  69. INC(i);
  70. UNTIL i=Len;
  71. END; (*IF*)
  72. S[P] := 0C;
  73. END; (*IF*)
  74. END; (*IF*)
  75. END Delete;
  76. PROCEDURE Insert(VAR S1:ARRAY OF CHAR;S2:ARRAY OF CHAR;P:CARDINAL);
  77. VAR
  78. I,J,C,L : CARDINAL;
  79. BEGIN
  80. L := Length(S1);
  81. I := Length(S2);
  82. C := L;
  83. IF C < P THEN
  84. P := C;
  85. END; (*IF*)
  86. DEC(C,P);
  87. FOR J := C TO 0 BY -1 DO
  88. IF (J+P+I <= HIGH(S1)) THEN
  89. S1[J+P+I] := S1[J+P];
  90. END; (*IF*)
  91. END; (*FOR*)
  92. J := 0;
  93. WHILE (J<I) & (P+J <= HIGH(S1)) DO
  94. S1[P+J] := S2[J];
  95. INC(J);
  96. END; (*WHILE*)
  97. END Insert;
  98. PROCEDURE Item(VAR R:ARRAY OF CHAR;S:ARRAY OF CHAR;T:CHARSET;N:CARDINAL);
  99. VAR
  100. I,J : CARDINAL;
  101. HR,L : CARDINAL;
  102. BEGIN
  103. I := 0;
  104. L := Length(S);
  105. LOOP
  106. WHILE (I < L) & (S[I] IN T) DO
  107. INC(I);
  108. END; (*WHILE*)
  109. IF (N = 0) OR (I = L) THEN
  110. EXIT
  111. END; (*IF*)
  112. DEC(N);
  113. WHILE (I < L) & ~(S[I] IN T) DO
  114. INC(I);
  115. END; (*WHILE*)
  116. END; (*LOOP*)
  117. J := 0;
  118. HR := HIGH(R);
  119. WHILE (I < L) & ~(S[I] IN T) & (J <= HR) DO
  120. R[J] := S[I];
  121. INC(I);
  122. INC(J);
  123. END; (*WHILE*)
  124. IF (J <= HR) THEN
  125. R[J] := 0C;
  126. END; (*IF*)
  127. END Item;
  128. PROCEDURE ItemS(VAR R:ARRAY OF CHAR;S,T:ARRAY OF CHAR;N:CARDINAL);
  129. VAR
  130. CS : CHARSET;
  131. I : CARDINAL;
  132. BEGIN
  133. I := Length(T);
  134. CS := CHARSET{};
  135. WHILE I > 0 DO
  136. DEC(I);
  137. INCL(CS,T[I]);
  138. END;
  139. Item(R,S,CS,N);
  140. END ItemS;
  141. PROCEDURE Match(Source,Pattern:ARRAY OF CHAR):BOOLEAN;
  142. PROCEDURE Rmatch(VAR s:ARRAY OF CHAR;i:CARDINAL;VAR p:ARRAY OF CHAR;j:CARDINAL):BOOLEAN;
  143. VAR
  144. matched : BOOLEAN;
  145. k : CARDINAL;
  146. BEGIN
  147. IF p[0]=0C THEN
  148. RETURN TRUE;
  149. END; (*IF*)
  150. LOOP
  151. IF ((i>HIGH(s)) OR (s[i]=0C)) & ((j>HIGH(p)) OR (p[j]=0C)) THEN
  152. RETURN TRUE;
  153. ELSIF ((j>HIGH(p)) OR (p[j]=0C)) THEN
  154. RETURN FALSE;
  155. ELSIF (p[j]='*') THEN
  156. k :=i;
  157. IF ((j=HIGH(p)) OR (p[j+1]=0C)) THEN
  158. RETURN TRUE;
  159. ELSE
  160. LOOP
  161. matched := Rmatch(s,k,p,j+1);
  162. IF matched OR (k>HIGH(s)) OR (s[k]=0C) THEN
  163. RETURN matched;
  164. END; (*IF*)
  165. INC(k);
  166. END; (*LOOP*)
  167. END; (*IF*)
  168. ELSIF ((p[j]='?') & (s[i]#0C)) OR (CAP(p[j])=CAP(s[i])) THEN
  169. INC(i);
  170. INC(j);
  171. ELSE
  172. RETURN FALSE;
  173. END; (*IF*)
  174. END; (*LOOP*)
  175. END Rmatch;
  176. BEGIN (*Match*)
  177. RETURN Rmatch(Source,0,Pattern,0);
  178. END Match;
  179. TYPE
  180. ConvIntType = ARRAY ['0'..'F'] OF SHORTCARD;
  181. BA = ARRAY[0..1] OF SHORTCARD;
  182. CONST
  183. ConvStr = '0123456789ABCDEF';
  184. 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 );
  185. Div = BA(0,4);
  186. PROCEDURE CheckBase(VAR b:CARDINAL);
  187. BEGIN
  188. IF b < 2 THEN
  189. b := 2;
  190. END; (*IF*)
  191. IF b > 16 THEN
  192. b := 16;
  193. END; (*IF*)
  194. END CheckBase;
  195. PROCEDURE Reverse(VAR s: ARRAY OF CHAR; l,h: CARDINAL);
  196. VAR
  197. T : CHAR;
  198. BEGIN
  199. WHILE l < h DO
  200. T := s[l];
  201. s[l] := s[h];
  202. s[h] := T;
  203. INC(l);
  204. DEC(h);
  205. END; (*WHILE*)
  206. END Reverse;
  207. PROCEDURE IntToStr(V:LONGINT;VAR S:ARRAY OF CHAR;Base:CARDINAL;VAR OK:BOOLEAN);
  208. VAR
  209. i,l : CARDINAL;
  210. b : LONGCARD;
  211. BEGIN
  212. OK := TRUE;
  213. l := HIGH(S);
  214. CheckBase(Base);
  215. b := VAL(LONGCARD,Base);
  216. IF V < 0 THEN
  217. S[0] := '-';
  218. i := 1;
  219. V := -V;
  220. ELSE
  221. i := 0;
  222. END; (*IF*)
  223. LOOP
  224. IF i > l THEN
  225. OK := FALSE;
  226. EXIT;
  227. END; (*IF*)
  228. S[i] := ConvStr[CARDINAL(LONGCARD(V) MOD b)];
  229. INC(i);
  230. V := LONGCARD(V) DIV b;
  231. IF V = 0 THEN
  232. EXIT;
  233. END; (*IF*)
  234. END; (*LOOP*)
  235. IF i <= l THEN
  236. S[i] := 0C;
  237. END; (*IF*)
  238. IF S[0] < '0' THEN
  239. Reverse(S,1,i-1);
  240. ELSE
  241. Reverse(S,0,i-1);
  242. END; (*IF*)
  243. END IntToStr;
  244. PROCEDURE CardToStr(V:LONGCARD;VAR S:ARRAY OF CHAR;Base:CARDINAL;VAR OK:BOOLEAN);
  245. VAR
  246. i,l : CARDINAL;
  247. b : LONGCARD;
  248. BEGIN
  249. OK := TRUE;
  250. l := HIGH(S);
  251. CheckBase(Base);
  252. b := VAL(LONGCARD,Base);
  253. i := 0;
  254. LOOP
  255. IF i > l THEN
  256. OK := FALSE;
  257. EXIT;
  258. END; (*IF*)
  259. S[i] := ConvStr[CARDINAL(V MOD b)];
  260. INC(i);
  261. V := V DIV b;
  262. IF V = 0 THEN
  263. EXIT;
  264. END; (*IF*)
  265. END; (*LOOP*)
  266. IF i <= l THEN
  267. S[i] := 0C;
  268. END; (*IF*)
  269. Reverse(S,0,i-1);
  270. END CardToStr;
  271. (*# save,call(o_a_copy=>off)*)
  272. PROCEDURE StrToCI(S:ARRAY OF CHAR;Base:CARDINAL;VAR OK:BOOLEAN):LONGCARD;
  273. VAR
  274. i,l : CARDINAL;
  275. b,t,y : LONGCARD;
  276. c : CHAR;
  277. x : SHORTCARD;
  278. BEGIN
  279. CheckBase(Base);
  280. b := VAL(LONGCARD,Base);
  281. i := 0;
  282. l := HIGH(S);
  283. IF (S[0] = '-') OR (S[0] = '+') THEN
  284. i := 1;
  285. END; (*IF*)
  286. t := 0;
  287. IF S[i] = 0C THEN
  288. OK := FALSE;
  289. END; (*IF*)
  290. WHILE (i <= l) & (S[i] # 0C) DO
  291. c := S[i];
  292. IF (c < '0') OR (c > 'F') THEN
  293. OK := FALSE;
  294. RETURN t;
  295. END; (*IF*)
  296. x := ConvInt[c];
  297. IF (x > SHORTCARD(b)-1) OR (t > (MAX(LONGCARD)-LONGCARD(x)) DIV b) THEN
  298. OK := FALSE;
  299. END; (*IF*)
  300. t := t*b+VAL(LONGCARD,x);
  301. INC(i);
  302. END; (*WHILE*)
  303. RETURN t;
  304. END StrToCI;
  305. PROCEDURE StrToInt(S:ARRAY OF CHAR;Base:CARDINAL;VAR OK:BOOLEAN):LONGINT;
  306. VAR
  307. t : LONGCARD;
  308. BEGIN
  309. OK := TRUE;
  310. t := StrToCI(S,Base,OK);
  311. IF t > 7FFFFFFFH THEN
  312. OK := FALSE;
  313. END; (*IF*)
  314. IF S[0] = '-' THEN
  315. RETURN -LONGINT(t);
  316. ELSE
  317. RETURN LONGINT(t);
  318. END; (*IF*)
  319. END StrToInt;
  320. PROCEDURE StrToCard(S:ARRAY OF CHAR;Base:CARDINAL;VAR OK:BOOLEAN):LONGCARD;
  321. VAR
  322. t : LONGCARD;
  323. BEGIN
  324. OK := TRUE;
  325. t := StrToCI(S,Base,OK);
  326. IF S[0] = '-' THEN
  327. OK := FALSE;
  328. END; (*IF*)
  329. RETURN t;
  330. END StrToCard;
  331. PROCEDURE FindSubStr(Source,Pattern: ARRAY OF CHAR;VAR pos:ARRAY OF PosLen) : BOOLEAN;
  332. PROCEDURE Rmatch(i,j,p:CARDINAL):BOOLEAN;
  333. VAR
  334. matched : BOOLEAN;
  335. k : CARDINAL;
  336. BEGIN
  337. LOOP
  338. IF ((i>HIGH(Source)) OR (Source[i]=0C)) & ((j>HIGH(Pattern)) OR (Pattern[j]=0C)) THEN
  339. RETURN TRUE;
  340. ELSIF ((j > HIGH(Pattern)) OR (Pattern[j] = 0C)) THEN
  341. RETURN FALSE;
  342. ELSIF (Pattern[j]='*') THEN
  343. k :=i;
  344. IF ((j=HIGH(Pattern)) OR (Pattern[j+1]=0C)) THEN
  345. IF p<=HIGH(pos) THEN
  346. pos[p].Pos := i;
  347. WHILE (k#HIGH(Source)) & (Source[k+1]#0C) DO
  348. INC(k);
  349. END; (*WHILE*)
  350. pos[p].Len := 1+k-i;
  351. END; (*IF*)
  352. RETURN TRUE;
  353. ELSE
  354. LOOP
  355. matched := Rmatch(k,j+1,p+1);
  356. IF matched OR (k > HIGH(Source)) OR (Source[k] = 0C) THEN
  357. IF matched AND (p<=HIGH(pos)) THEN
  358. pos[p].Pos := i;
  359. pos[p].Len := k-i;
  360. END; (*IF*)
  361. RETURN matched;
  362. END;
  363. INC(k);
  364. END; (*LOOP*)
  365. END; (*IF*)
  366. ELSIF (Pattern[j] # '?') & (CAP(Pattern[j]) # CAP(Source[i])) THEN
  367. RETURN FALSE;
  368. ELSE
  369. IF Pattern[j]='?' THEN
  370. pos[p].Pos:=i;
  371. pos[p].Len:=1;
  372. INC(p);
  373. END; (*IF*)
  374. INC(i);
  375. INC(j);
  376. END; (*IF*)
  377. END; (*LOOP*)
  378. END Rmatch;
  379. BEGIN
  380. IF Pattern[0]=0C THEN
  381. RETURN TRUE;
  382. ELSE
  383. RETURN Rmatch(0,0,0);
  384. END;
  385. END FindSubStr;
  386. PROCEDURE StrToC(S:ARRAY OF CHAR;VAR D:ARRAY OF CHAR):BOOLEAN;
  387. VAR
  388. n : CARDINAL;
  389. c : CHAR;
  390. BEGIN
  391. n := 0;
  392. LOOP
  393. IF n > HIGH(D) THEN
  394. RETURN FALSE;
  395. END; (*IF*)
  396. IF n > HIGH(S) THEN
  397. c := 0C;
  398. ELSE
  399. c := S[n];
  400. END; (*IF*)
  401. D[n] := c;
  402. IF c = 0C THEN
  403. RETURN TRUE;
  404. END; (*IF*)
  405. INC(n);
  406. END; (*LOOP*)
  407. END StrToC;
  408. PROCEDURE StrToPas(S:ARRAY OF CHAR;VAR D:ARRAY OF CHAR):BOOLEAN;
  409. VAR
  410. n : CARDINAL;
  411. c : CHAR;
  412. BEGIN
  413. n := 1;
  414. LOOP
  415. IF n > HIGH(D) THEN
  416. D[0] := 0C;
  417. RETURN FALSE;
  418. END; (*IF*)
  419. IF n > SIZE(S) THEN
  420. c := 0C;
  421. ELSE
  422. c := S[n-1];
  423. END; (*IF*)
  424. IF c = 0C THEN
  425. D[0] := CHAR(n-1);
  426. RETURN TRUE;
  427. END; (*IF*)
  428. D[n] := c;
  429. INC(n);
  430. END; (*LOOP*)
  431. END StrToPas;
  432. END WinStr.
  433.