pxpic.inc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. {---------------------------------------------------------------------------
  2. CncWare
  3. Created and Copyright (c) 1991 J. John Sprenger
  4. ----------------------------------------------------------------------------
  5. Filename..: pxpic.inc
  6. Programmer: Ken J. Wright, [email protected]
  7. Date......: 06/09/2000
  8. Purpose - Duplicates the functionality of the TPXPictureValidator.IsValid
  9. method from Turbo Vision's validate unit. This function was
  10. extracted from a unit called fmtline written by J. John Sprenger.
  11. It was actually written before the validate unit was available
  12. from Borland in TV2.0.
  13. -------------------------------<< REVISIONS >>--------------------------------
  14. Ver | Date | Prog| Description
  15. -------+----------+-----+-----------------------------------------------------
  16. 1.00 | 06/10/00 | kjw | Initial Release.
  17. 1.01 | 06/11/00 | kjw | Finally debugged the spin cycle! The AnyLeft function
  18. | missed a condition that left it an endless loop.
  19. | Added the boolean "done" to fix it.
  20. 1.02 | 06/15/00 | kjw | Added '@' to the match set.
  21. ------------------------------------------------------------------------------}
  22. { Created and Copyright (c) 1991 J. John Sprenger }
  23. { tFormatLine.CheckPicture is the function that inspects }
  24. { the input string passed as S against the Pic string }
  25. { which holds the Paradox-form Picture. If an error is }
  26. { found the position of the error is placed in CPos. }
  27. function nCheckPxPicture(var s, Pic : string;
  28. var CPos : integer) : word;
  29. const
  30. { flError, flCharOk and flFormatOK are constants used }
  31. { by tFormatLine.CheckPicture. flError is returned }
  32. { when an error is found, flCharOk when an character }
  33. { is found to be appropriate, And flFormatOk when the }
  34. { entire input string is found acceptable. }
  35. flError = $0000;
  36. flCharOK = $0001;
  37. flFormatOK = $0002;
  38. var
  39. Resolved : integer;
  40. TempIndex : integer;
  41. { Function Copy represents a bit of syntactic sugar for }
  42. { the benefit of the author. It changes the Copy func. }
  43. { so that its parameters represent start and end points }
  44. { rather than a start point followed by a quantity. }
  45. function Copy(s : string; start, stop : integer) : string;
  46. begin
  47. if stop < start then Copy:=''
  48. else Copy:=System.Copy(s,start,stop-start+1);
  49. end;
  50. { Function FindMatch recursively locates the matching }
  51. (* grouping characters for "{" and "[". *)
  52. function FindMatch(P : string) : integer;
  53. var
  54. i:integer;
  55. match:boolean;
  56. begin
  57. i:=2;
  58. match:=false;
  59. while (i<=length(P)) and not match do begin
  60. if ((p[i]=']') and (p[1]='[')) or ((p[i]='}') and
  61. (p[1]='{')) then
  62. match:=true;
  63. if p[i]='{' then
  64. i:=i+FindMatch(Copy(p,i,length(p)))
  65. else
  66. if p[i]='[' then
  67. i:=i+FindMatch(Copy(p,i,length(P)))
  68. else inc(i);
  69. end;
  70. FindMatch:=i-1;
  71. end;
  72. { Function CP is the heart of tFormatLine. It }
  73. { determines if the string, s, passed to it fits the }
  74. { requirements of the picture, Pic. The number of }
  75. { characters successfully resolved is returned in the }
  76. { parameter resolved. When groups or repetitions are }
  77. { encountered CP will call itself recursively. }
  78. function CP(var s : string; Pic : string; var CPos :
  79. integer; var Resolved : integer) : word;
  80. const
  81. CharMatchSet = ['#', '?', '&', '''', '@', '!'];
  82. var
  83. i : integer;
  84. index : integer;
  85. result_ : word;
  86. commit : boolean;
  87. Groupcount : integer;
  88. { Procedure Succeed resolves defaults and <Space> }
  89. { default requests }
  90. { Note:
  91. The little patch below to exclude group end checking during
  92. expansion lets autofill work as it should, however it also
  93. autofills prematurely when there are more optionals or
  94. alternates. I haven't quite figured how to make this work
  95. correctly within the current recursion scheme.
  96. kjw
  97. }
  98. procedure Succeed;
  99. var
  100. t : integer;
  101. found : boolean;
  102. begin
  103. if (i <= Length(s)) and
  104. (s[i]=' ') and
  105. (Pic[index]<>' ') and
  106. (Pic[index]<>',')
  107. then begin
  108. t:=index;
  109. found:=false;
  110. while (t<=length(pic)) and not found do begin
  111. if not (Pic[t] in (CharMatchSet+
  112. ['*','[','{',',',']','}'])) then begin
  113. if pic[t]=';' then inc(t);
  114. s[i]:=Pic[t];
  115. found:=true;
  116. end;
  117. inc(t);
  118. end;
  119. end;
  120. if (i>length(s)) then
  121. {----------------------}
  122. { Expand with defaults }
  123. while not (Pic[index] in
  124. (CharMatchSet+['*','[','{',',',']','}'])) and
  125. (index<=length(Pic)) and
  126. not(Pic[index-1] in [(*'}',*)','(*,']'*)]) do begin {kjw}
  127. if Pic[index]=';' then inc(index);
  128. s[i]:=Pic[index];
  129. if i>length(s) then begin
  130. CPos:=i;
  131. s[0]:=char(i);
  132. end;
  133. inc(i);
  134. inc(index);
  135. end;
  136. end;
  137. { Function AnyLeft returns true if there are no required }
  138. { characters left in the Picture string. }
  139. function AnyLeft : boolean;
  140. var
  141. TempIndex : integer;
  142. done : boolean; {kjw, 06/11/2000}
  143. begin
  144. done := false;
  145. TempIndex:=index;
  146. while ((Pic[TempIndex]='[') or (Pic[TempIndex]='*'))
  147. and (TempIndex<=Length(Pic))
  148. and (Pic[TempIndex]<>',')
  149. and not done do begin
  150. if Pic[TempIndex]='[' then
  151. Tempindex:=Tempindex+FindMatch(Copy(Pic,index, Length(Pic)))
  152. else begin
  153. if not (Pic[TempIndex+1] in ['0'..'9']) then begin
  154. inc(TempIndex);
  155. if Pic[TempIndex] in ['{','['] then
  156. tempIndex:=TempIndex+ FindMatch(Copy(pic,index,length(pic)))
  157. else inc(TempIndex);
  158. end else done := true;
  159. end;
  160. end;
  161. AnyLeft:=(TempIndex<=length(Pic)) and
  162. (Pic[TempIndex]<>',');
  163. end;
  164. { Function CharMatch determines if the current character }
  165. { matches the corresponding character mask in the }
  166. { Picture string. Alters the character if necessary. }
  167. function CharMatch : word;
  168. var result_ : word;
  169. begin
  170. result_:=flError;
  171. case Pic[index] of
  172. '#': if s[i] in ['0'..'9'] then result_:=flCharOk;
  173. '?': if s[i] in ['A'..'Z','a'..'z'] then
  174. result_:=flCharOk;
  175. '&': if s[i] in ['A'..'Z','a'..'z'] then
  176. begin
  177. result_:=flCharOk;
  178. s[i]:=upcase(s[i]);
  179. end;
  180. '''': result_:=flCharOk;
  181. '@': result_:=flCharOk;
  182. '!': begin
  183. result_:=flCharOk;
  184. s[i]:=upcase(s[i]);
  185. end;
  186. end;
  187. if result_<>flError then commit:=true;
  188. CharMatch:=result_;
  189. end;
  190. { Function Literal handles characters which are needed }
  191. { by the picture but otherwise used as format specifiers. }
  192. { All such characters are preceded by the ';' in the }
  193. { picture string. }
  194. function Literal : word;
  195. var result_ : word;
  196. begin
  197. inc(index);
  198. if s[i]=Pic[index] then result_:=flCharOk
  199. else result_:=flError;
  200. if result_<>flError then commit:=true;
  201. Literal:=result_;
  202. end;
  203. { Function Group handles required and optional groups }
  204. { in the picture string. These are designated by the }
  205. (* "{","}" and "[","]" character pairs. *)
  206. function Group:word;
  207. var
  208. result_: word;
  209. TempS: string;
  210. TempPic: string;
  211. TempCPos: integer;
  212. PicEnd: integer;
  213. TempIndex: integer;
  214. SwapIndex:integer;
  215. SwapPic : string;
  216. begin
  217. TempPic:=Copy(Pic,index,length(Pic));
  218. PicEnd:=FindMatch(TempPic);
  219. TempPic:=Copy(TempPic,2,PicEnd-1);
  220. TempS:=Copy(s,i,length(s));
  221. TempCPos:=1;
  222. result_:=CP(TempS,TempPic,TempCPos,TempIndex);
  223. if result_=flCharOK then inc(GroupCount);
  224. if (result_=flFormatOK) and (groupcount>0) then
  225. dec(GroupCount);
  226. if result_<>flError then result_:=flCharOk;
  227. SwapIndex:=index;
  228. index:=TempIndex;
  229. SwapPic:=Pic;
  230. Pic:=TempPic;
  231. if not AnyLeft then result_:=flCharOk;
  232. pic:=SwapPic;
  233. index:=SwapIndex;
  234. if i>1 then s:=copy(s,1,i-1)+TempS else s:=TempS;
  235. CPos:=Cpos+TempCPos-1;
  236. if Pic[index]='[' then begin
  237. if result_<>flError then
  238. i:=i+TempCPos-1
  239. else dec(i);
  240. result_:=flCharOK;
  241. end
  242. else i:=i+TempCPos-1;
  243. index:=index+PicEnd-1;
  244. Group:=result_;
  245. end;
  246. { Function Repetition handles characters that may be }
  247. { repeated in the input string. The picture string }
  248. { indicates this possiblity with "*" character. }
  249. function Repetition:word;
  250. var
  251. result_:word;
  252. count:integer;
  253. TempPic:string;
  254. TempS:string;
  255. TempCPos:integer;
  256. TempIndex:integer;
  257. SwapIndex:integer;
  258. SwapPic:string;
  259. PicEnd:integer;
  260. commit:boolean;
  261. procedure MakeCount;
  262. var nstr:string;
  263. code:integer;
  264. begin
  265. if Pic[index] in ['0'..'9'] then begin
  266. nstr:='';
  267. repeat
  268. nstr:=nstr+Pic[index];
  269. inc(index);
  270. until not(Pic[index] in ['0'..'9']);
  271. val(nstr,count,code);
  272. end
  273. else count:=512;
  274. end;
  275. procedure MakePic;
  276. begin
  277. if Pic[index] in ['{','['] then begin
  278. TempPic:=copy(Pic,index,length(Pic));
  279. PicEnd:=FindMatch(TempPic);
  280. TempPic:=Copy(TempPic,2,PicEnd-1);
  281. end
  282. else begin
  283. if Pic[index]<>';' then begin
  284. TempPic:=''+Pic[index];
  285. PicEnd:=3;
  286. if index=1 then
  287. pic:='{'+pic[index]+'}'+ copy(pic,index+1,length(pic))
  288. else pic:=copy(pic,1,index-1)+
  289. '{'+pic[index]+'}'+
  290. copy(pic,index+1,length(pic));
  291. end
  292. else begin
  293. TempPic:=Pic[index]+Pic[index+1];
  294. PicEnd:=4;
  295. if index=1 then
  296. pic:='{' + pic[index] + pic[index+1]+'}' +
  297. copy(pic,index+1,length(pic))
  298. else pic:=copy(pic,1,index-1) + '{' + pic[index] +
  299. pic[index+1] + '}' + copy(pic,index+1,length(pic));
  300. end;
  301. end;
  302. end;
  303. begin
  304. inc(index);
  305. MakeCount;
  306. MakePic;
  307. result_:=flCharOk;
  308. while (count<>0) and (result_<>flError) and
  309. (i<=length(s)) do begin
  310. commit:=false;
  311. TempS:=Copy(s,i,length(s));
  312. TempCPos:=1;
  313. result_:=CP(TempS,TempPic,TempCPos,TempIndex);
  314. if result_=flCharOK then inc(GroupCount);
  315. if (result_=flFormatOK) and (groupcount > 0) then
  316. dec(GroupCount);
  317. if result_<>flError then result_:=flCharOk;
  318. SwapIndex:=Index;
  319. Index:=TempIndex;
  320. SwapPic:=Pic;
  321. Pic:=TempPic;
  322. if (not AnyLeft) then result_:=flCharOk;
  323. Pic:=SwapPic;
  324. index:=SwapIndex;
  325. if i>1 then s:=copy(s,1,i-1)+TempS else s:=TempS;
  326. Cpos:=Cpos+TempCpos-1;
  327. if (count>255) then begin
  328. if result_<>flError then begin
  329. i:=i+TempCpos-1;
  330. if not commit then commit:=true;
  331. result_:=flCharOk;
  332. end
  333. else dec(i);
  334. end
  335. else i:=i+TempCPos-1;
  336. inc(i);
  337. dec(count);
  338. end;
  339. dec(i);
  340. index:=index+PicEnd-1;
  341. if result_=flError then
  342. if (count>255) and not commit
  343. then result_:=flCharOk;
  344. repetition:=result_;
  345. end;
  346. begin { of function CP}
  347. i:=1;
  348. index:=1;
  349. result_:=flCharOk;
  350. commit:=false;
  351. Groupcount:=0;
  352. while (i<=length(s)) and (result_<>flError) do begin
  353. if index>length(Pic) then result_:=flError
  354. else begin
  355. if s[i]=' ' then Succeed;
  356. if Pic[index] in CharMatchSet then
  357. result_:=CharMatch
  358. else
  359. if Pic[index]=';' then
  360. result_:=Literal
  361. else
  362. if (Pic[index]='{') or (Pic[index]='[') then
  363. result_:=Group
  364. else
  365. if Pic[index]='*' then
  366. result_:=Repetition
  367. else
  368. if Pic[index] in [',','}',']'] then
  369. result_:=flError
  370. else
  371. if Pic[index]=s[i] then begin
  372. result_:=flCharOk;
  373. commit:=true;
  374. end
  375. else result_:=flError;
  376. if (result_ = flError) and not commit then begin
  377. TempIndex:=Index;
  378. while (TempIndex<=length(Pic)) and
  379. ((Pic[TempIndex]<>',') and
  380. (Pic[TempIndex-1]<>';')) do begin
  381. if (Pic[TempIndex]='{') or
  382. (Pic[TempIndex]=']') then
  383. Index:=FindMatch(Copy( Pic,
  384. TempIndex,length(Pic)))+TempIndex-1;
  385. inc(TempIndex);
  386. end;
  387. if Pic[TempIndex]=',' then begin
  388. if Pic[TempIndex-1]<>';' then begin
  389. result_:=flCharOk;
  390. index:=TempIndex;
  391. inc(index);
  392. end;
  393. end;
  394. end
  395. else if result_<>flError then begin
  396. inc(i);
  397. inc(index);
  398. Succeed;
  399. end;
  400. end;
  401. end;
  402. Resolved:=index;
  403. if (result_=flCharOk) and
  404. (GroupCount=0) and
  405. (not AnyLeft or ((Pic[index-1]=',') and
  406. (Pic[index-2]<>';'))) then
  407. result_:=flFormatOk;
  408. CPos:=i-1;
  409. CP:=result_;
  410. end;
  411. begin{ of function CheckPicture}
  412. Resolved:=0;
  413. CPos := 0;
  414. If (Pic = '') or (s = '') Then
  415. nCheckPxPicture := flFormatOk
  416. Else
  417. nCheckPxPicture:=CP(s,Pic,CPos,Resolved);
  418. end;
  419. {
  420. $Log$
  421. Revision 1.2 2000-07-13 11:33:27 michael
  422. + removed logs
  423. }