123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- {---------------------------------------------------------------------------
- CncWare
- Created and Copyright (c) 1991 J. John Sprenger
- ----------------------------------------------------------------------------
- Filename..: pxpic.inc
- Programmer: Ken J. Wright, [email protected]
- Date......: 06/09/2000
- Purpose - Duplicates the functionality of the TPXPictureValidator.IsValid
- method from Turbo Vision's validate unit. This function was
- extracted from a unit called fmtline written by J. John Sprenger.
- It was actually written before the validate unit was available
- from Borland in TV2.0.
- -------------------------------<< REVISIONS >>--------------------------------
- Ver | Date | Prog| Description
- -------+----------+-----+-----------------------------------------------------
- 1.00 | 06/10/00 | kjw | Initial Release.
- 1.01 | 06/11/00 | kjw | Finally debugged the spin cycle! The AnyLeft function
- | missed a condition that left it an endless loop.
- | Added the boolean "done" to fix it.
- 1.02 | 06/15/00 | kjw | Added '@' to the match set.
- ------------------------------------------------------------------------------}
- { Created and Copyright (c) 1991 J. John Sprenger }
- { tFormatLine.CheckPicture is the function that inspects }
- { the input string passed as S against the Pic string }
- { which holds the Paradox-form Picture. If an error is }
- { found the position of the error is placed in CPos. }
- function nCheckPxPicture(var s, Pic : string;
- var CPos : integer) : word;
- const
- { flError, flCharOk and flFormatOK are constants used }
- { by tFormatLine.CheckPicture. flError is returned }
- { when an error is found, flCharOk when an character }
- { is found to be appropriate, And flFormatOk when the }
- { entire input string is found acceptable. }
- flError = $0000;
- flCharOK = $0001;
- flFormatOK = $0002;
- var
- Resolved : integer;
- TempIndex : integer;
- { Function Copy represents a bit of syntactic sugar for }
- { the benefit of the author. It changes the Copy func. }
- { so that its parameters represent start and end points }
- { rather than a start point followed by a quantity. }
- function Copy(s : string; start, stop : integer) : string;
- begin
- if stop < start then Copy:=''
- else Copy:=System.Copy(s,start,stop-start+1);
- end;
- { Function FindMatch recursively locates the matching }
- (* grouping characters for "{" and "[". *)
- function FindMatch(P : string) : integer;
- var
- i:integer;
- match:boolean;
- begin
- i:=2;
- match:=false;
- while (i<=length(P)) and not match do begin
- if ((p[i]=']') and (p[1]='[')) or ((p[i]='}') and
- (p[1]='{')) then
- match:=true;
- if p[i]='{' then
- i:=i+FindMatch(Copy(p,i,length(p)))
- else
- if p[i]='[' then
- i:=i+FindMatch(Copy(p,i,length(P)))
- else inc(i);
- end;
- FindMatch:=i-1;
- end;
- { Function CP is the heart of tFormatLine. It }
- { determines if the string, s, passed to it fits the }
- { requirements of the picture, Pic. The number of }
- { characters successfully resolved is returned in the }
- { parameter resolved. When groups or repetitions are }
- { encountered CP will call itself recursively. }
- function CP(var s : string; Pic : string; var CPos :
- integer; var Resolved : integer) : word;
- const
- CharMatchSet = ['#', '?', '&', '''', '@', '!'];
- var
- i : integer;
- index : integer;
- result_ : word;
- commit : boolean;
- Groupcount : integer;
- { Procedure Succeed resolves defaults and <Space> }
- { default requests }
- { Note:
- The little patch below to exclude group end checking during
- expansion lets autofill work as it should, however it also
- autofills prematurely when there are more optionals or
- alternates. I haven't quite figured how to make this work
- correctly within the current recursion scheme.
- kjw
- }
- procedure Succeed;
- var
- t : integer;
- found : boolean;
- begin
- if (i <= Length(s)) and
- (s[i]=' ') and
- (Pic[index]<>' ') and
- (Pic[index]<>',')
- then begin
- t:=index;
- found:=false;
- while (t<=length(pic)) and not found do begin
- if not (Pic[t] in (CharMatchSet+
- ['*','[','{',',',']','}'])) then begin
- if pic[t]=';' then inc(t);
- s[i]:=Pic[t];
- found:=true;
- end;
- inc(t);
- end;
- end;
- if (i>length(s)) then
- {----------------------}
- { Expand with defaults }
- while not (Pic[index] in
- (CharMatchSet+['*','[','{',',',']','}'])) and
- (index<=length(Pic)) and
- not(Pic[index-1] in [(*'}',*)','(*,']'*)]) do begin {kjw}
- if Pic[index]=';' then inc(index);
- s[i]:=Pic[index];
- if i>length(s) then begin
- CPos:=i;
- s[0]:=char(i);
- end;
- inc(i);
- inc(index);
- end;
- end;
- { Function AnyLeft returns true if there are no required }
- { characters left in the Picture string. }
- function AnyLeft : boolean;
- var
- TempIndex : integer;
- done : boolean; {kjw, 06/11/2000}
- begin
- done := false;
- TempIndex:=index;
- while ((Pic[TempIndex]='[') or (Pic[TempIndex]='*'))
- and (TempIndex<=Length(Pic))
- and (Pic[TempIndex]<>',')
- and not done do begin
- if Pic[TempIndex]='[' then
- Tempindex:=Tempindex+FindMatch(Copy(Pic,index, Length(Pic)))
- else begin
- if not (Pic[TempIndex+1] in ['0'..'9']) then begin
- inc(TempIndex);
- if Pic[TempIndex] in ['{','['] then
- tempIndex:=TempIndex+ FindMatch(Copy(pic,index,length(pic)))
- else inc(TempIndex);
- end else done := true;
- end;
- end;
- AnyLeft:=(TempIndex<=length(Pic)) and
- (Pic[TempIndex]<>',');
- end;
- { Function CharMatch determines if the current character }
- { matches the corresponding character mask in the }
- { Picture string. Alters the character if necessary. }
- function CharMatch : word;
- var result_ : word;
- begin
- result_:=flError;
- case Pic[index] of
- '#': if s[i] in ['0'..'9'] then result_:=flCharOk;
- '?': if s[i] in ['A'..'Z','a'..'z'] then
- result_:=flCharOk;
- '&': if s[i] in ['A'..'Z','a'..'z'] then
- begin
- result_:=flCharOk;
- s[i]:=upcase(s[i]);
- end;
- '''': result_:=flCharOk;
- '@': result_:=flCharOk;
- '!': begin
- result_:=flCharOk;
- s[i]:=upcase(s[i]);
- end;
- end;
- if result_<>flError then commit:=true;
- CharMatch:=result_;
- end;
- { Function Literal handles characters which are needed }
- { by the picture but otherwise used as format specifiers. }
- { All such characters are preceded by the ';' in the }
- { picture string. }
- function Literal : word;
- var result_ : word;
- begin
- inc(index);
- if s[i]=Pic[index] then result_:=flCharOk
- else result_:=flError;
- if result_<>flError then commit:=true;
- Literal:=result_;
- end;
- { Function Group handles required and optional groups }
- { in the picture string. These are designated by the }
- (* "{","}" and "[","]" character pairs. *)
- function Group:word;
- var
- result_: word;
- TempS: string;
- TempPic: string;
- TempCPos: integer;
- PicEnd: integer;
- TempIndex: integer;
- SwapIndex:integer;
- SwapPic : string;
- begin
- TempPic:=Copy(Pic,index,length(Pic));
- PicEnd:=FindMatch(TempPic);
- TempPic:=Copy(TempPic,2,PicEnd-1);
- TempS:=Copy(s,i,length(s));
- TempCPos:=1;
- result_:=CP(TempS,TempPic,TempCPos,TempIndex);
- if result_=flCharOK then inc(GroupCount);
- if (result_=flFormatOK) and (groupcount>0) then
- dec(GroupCount);
- if result_<>flError then result_:=flCharOk;
- SwapIndex:=index;
- index:=TempIndex;
- SwapPic:=Pic;
- Pic:=TempPic;
- if not AnyLeft then result_:=flCharOk;
- pic:=SwapPic;
- index:=SwapIndex;
- if i>1 then s:=copy(s,1,i-1)+TempS else s:=TempS;
- CPos:=Cpos+TempCPos-1;
- if Pic[index]='[' then begin
- if result_<>flError then
- i:=i+TempCPos-1
- else dec(i);
- result_:=flCharOK;
- end
- else i:=i+TempCPos-1;
- index:=index+PicEnd-1;
- Group:=result_;
- end;
- { Function Repetition handles characters that may be }
- { repeated in the input string. The picture string }
- { indicates this possiblity with "*" character. }
- function Repetition:word;
- var
- result_:word;
- count:integer;
- TempPic:string;
- TempS:string;
- TempCPos:integer;
- TempIndex:integer;
- SwapIndex:integer;
- SwapPic:string;
- PicEnd:integer;
- commit:boolean;
- procedure MakeCount;
- var nstr:string;
- code:integer;
- begin
- if Pic[index] in ['0'..'9'] then begin
- nstr:='';
- repeat
- nstr:=nstr+Pic[index];
- inc(index);
- until not(Pic[index] in ['0'..'9']);
- val(nstr,count,code);
- end
- else count:=512;
- end;
- procedure MakePic;
- begin
- if Pic[index] in ['{','['] then begin
- TempPic:=copy(Pic,index,length(Pic));
- PicEnd:=FindMatch(TempPic);
- TempPic:=Copy(TempPic,2,PicEnd-1);
- end
- else begin
- if Pic[index]<>';' then begin
- TempPic:=''+Pic[index];
- PicEnd:=3;
- if index=1 then
- pic:='{'+pic[index]+'}'+ copy(pic,index+1,length(pic))
- else pic:=copy(pic,1,index-1)+
- '{'+pic[index]+'}'+
- copy(pic,index+1,length(pic));
- end
- else begin
- TempPic:=Pic[index]+Pic[index+1];
- PicEnd:=4;
- if index=1 then
- pic:='{' + pic[index] + pic[index+1]+'}' +
- copy(pic,index+1,length(pic))
- else pic:=copy(pic,1,index-1) + '{' + pic[index] +
- pic[index+1] + '}' + copy(pic,index+1,length(pic));
- end;
- end;
- end;
- begin
- inc(index);
- MakeCount;
- MakePic;
- result_:=flCharOk;
- while (count<>0) and (result_<>flError) and
- (i<=length(s)) do begin
- commit:=false;
- TempS:=Copy(s,i,length(s));
- TempCPos:=1;
- result_:=CP(TempS,TempPic,TempCPos,TempIndex);
- if result_=flCharOK then inc(GroupCount);
- if (result_=flFormatOK) and (groupcount > 0) then
- dec(GroupCount);
- if result_<>flError then result_:=flCharOk;
- SwapIndex:=Index;
- Index:=TempIndex;
- SwapPic:=Pic;
- Pic:=TempPic;
- if (not AnyLeft) then result_:=flCharOk;
- Pic:=SwapPic;
- index:=SwapIndex;
- if i>1 then s:=copy(s,1,i-1)+TempS else s:=TempS;
- Cpos:=Cpos+TempCpos-1;
- if (count>255) then begin
- if result_<>flError then begin
- i:=i+TempCpos-1;
- if not commit then commit:=true;
- result_:=flCharOk;
- end
- else dec(i);
- end
- else i:=i+TempCPos-1;
- inc(i);
- dec(count);
- end;
- dec(i);
- index:=index+PicEnd-1;
- if result_=flError then
- if (count>255) and not commit
- then result_:=flCharOk;
- repetition:=result_;
- end;
- begin { of function CP}
- i:=1;
- index:=1;
- result_:=flCharOk;
- commit:=false;
- Groupcount:=0;
- while (i<=length(s)) and (result_<>flError) do begin
- if index>length(Pic) then result_:=flError
- else begin
- if s[i]=' ' then Succeed;
- if Pic[index] in CharMatchSet then
- result_:=CharMatch
- else
- if Pic[index]=';' then
- result_:=Literal
- else
- if (Pic[index]='{') or (Pic[index]='[') then
- result_:=Group
- else
- if Pic[index]='*' then
- result_:=Repetition
- else
- if Pic[index] in [',','}',']'] then
- result_:=flError
- else
- if Pic[index]=s[i] then begin
- result_:=flCharOk;
- commit:=true;
- end
- else result_:=flError;
- if (result_ = flError) and not commit then begin
- TempIndex:=Index;
- while (TempIndex<=length(Pic)) and
- ((Pic[TempIndex]<>',') and
- (Pic[TempIndex-1]<>';')) do begin
- if (Pic[TempIndex]='{') or
- (Pic[TempIndex]=']') then
- Index:=FindMatch(Copy( Pic,
- TempIndex,length(Pic)))+TempIndex-1;
- inc(TempIndex);
- end;
- if Pic[TempIndex]=',' then begin
- if Pic[TempIndex-1]<>';' then begin
- result_:=flCharOk;
- index:=TempIndex;
- inc(index);
- end;
- end;
- end
- else if result_<>flError then begin
- inc(i);
- inc(index);
- Succeed;
- end;
- end;
- end;
- Resolved:=index;
- if (result_=flCharOk) and
- (GroupCount=0) and
- (not AnyLeft or ((Pic[index-1]=',') and
- (Pic[index-2]<>';'))) then
- result_:=flFormatOk;
- CPos:=i-1;
- CP:=result_;
- end;
- begin{ of function CheckPicture}
- Resolved:=0;
- CPos := 0;
- If (Pic = '') or (s = '') Then
- nCheckPxPicture := flFormatOk
- Else
- nCheckPxPicture:=CP(s,Pic,CPos,Resolved);
- end;
- {
- $Log$
- Revision 1.2 2000-07-13 11:33:27 michael
- + removed logs
-
- }
|