| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753 |
- unit dbf_parser;
- interface
- {$I dbf_common.inc}
- uses
- SysUtils,
- Classes,
- {$ifdef KYLIX}
- Libc,
- {$endif}
- {$ifndef WIN32}
- dbf_wtil,
- {$endif}
- db,
- dbf_prscore,
- dbf_common,
- dbf_fields,
- dbf_prsdef,
- dbf_prssupp;
- type
- TDbfParser = class(TCustomExpressionParser)
- private
- FDbfFile: Pointer;
- FFieldVarList: TStringList;
- FResultLen: Integer;
- FIsExpression: Boolean; // expression or simple field?
- FFieldType: TExpressionType;
- FCaseInsensitive: Boolean;
- FRawStringFields: Boolean;
- FPartialMatch: boolean;
- protected
- FCurrentExpression: string;
- procedure FillExpressList; override;
- procedure HandleUnknownVariable(VarName: string); override;
- function GetVariableInfo(VarName: string): TDbfFieldDef;
- function CurrentExpression: string; override;
- function GetResultType: TExpressionType; override;
- procedure SetCaseInsensitive(NewInsensitive: Boolean);
- procedure SetRawStringFields(NewRawFields: Boolean);
- procedure SetPartialMatch(NewPartialMatch: boolean);
- public
- constructor Create(ADbfFile: Pointer);
- destructor Destroy; override;
- procedure ClearExpressions; override;
- procedure ParseExpression(Expression: string); virtual;
- function ExtractFromBuffer(Buffer: PChar): PChar; virtual;
- property DbfFile: Pointer read FDbfFile write FDbfFile;
- property Expression: string read FCurrentExpression;
- property ResultLen: Integer read FResultLen;
- property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive;
- property RawStringFields: Boolean read FRawStringFields write SetRawStringFields;
- property PartialMatch: boolean read FPartialMatch write SetPartialMatch;
- end;
- //--Expression functions-----------------------------------------------------
- procedure FuncFloatToStr(Param: PExpressionRec);
- procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: Integer);
- procedure FuncIntToStr(Param: PExpressionRec);
- procedure FuncDateToStr(Param: PExpressionRec);
- procedure FuncSubString(Param: PExpressionRec);
- procedure FuncUppercase(Param: PExpressionRec);
- procedure FuncLowercase(Param: PExpressionRec);
- procedure FuncAdd_F_FF(Param: PExpressionRec);
- procedure FuncAdd_F_FI(Param: PExpressionRec);
- procedure FuncAdd_F_II(Param: PExpressionRec);
- procedure FuncAdd_F_IF(Param: PExpressionRec);
- {$ifdef SUPPORT_INT64}
- procedure FuncAdd_F_FL(Param: PExpressionRec);
- procedure FuncAdd_F_IL(Param: PExpressionRec);
- procedure FuncAdd_F_LL(Param: PExpressionRec);
- procedure FuncAdd_F_LF(Param: PExpressionRec);
- procedure FuncAdd_F_LI(Param: PExpressionRec);
- {$endif}
- procedure FuncSub_F_FF(Param: PExpressionRec);
- procedure FuncSub_F_FI(Param: PExpressionRec);
- procedure FuncSub_F_II(Param: PExpressionRec);
- procedure FuncSub_F_IF(Param: PExpressionRec);
- {$ifdef SUPPORT_INT64}
- procedure FuncSub_F_FL(Param: PExpressionRec);
- procedure FuncSub_F_IL(Param: PExpressionRec);
- procedure FuncSub_F_LL(Param: PExpressionRec);
- procedure FuncSub_F_LF(Param: PExpressionRec);
- procedure FuncSub_F_LI(Param: PExpressionRec);
- {$endif}
- procedure FuncMul_F_FF(Param: PExpressionRec);
- procedure FuncMul_F_FI(Param: PExpressionRec);
- procedure FuncMul_F_II(Param: PExpressionRec);
- procedure FuncMul_F_IF(Param: PExpressionRec);
- {$ifdef SUPPORT_INT64}
- procedure FuncMul_F_FL(Param: PExpressionRec);
- procedure FuncMul_F_IL(Param: PExpressionRec);
- procedure FuncMul_F_LL(Param: PExpressionRec);
- procedure FuncMul_F_LF(Param: PExpressionRec);
- procedure FuncMul_F_LI(Param: PExpressionRec);
- {$endif}
- procedure FuncDiv_F_FF(Param: PExpressionRec);
- procedure FuncDiv_F_FI(Param: PExpressionRec);
- procedure FuncDiv_F_II(Param: PExpressionRec);
- procedure FuncDiv_F_IF(Param: PExpressionRec);
- {$ifdef SUPPORT_INT64}
- procedure FuncDiv_F_FL(Param: PExpressionRec);
- procedure FuncDiv_F_IL(Param: PExpressionRec);
- procedure FuncDiv_F_LL(Param: PExpressionRec);
- procedure FuncDiv_F_LF(Param: PExpressionRec);
- procedure FuncDiv_F_LI(Param: PExpressionRec);
- {$endif}
- procedure FuncStrI_EQ(Param: PExpressionRec);
- procedure FuncStrI_NEQ(Param: PExpressionRec);
- procedure FuncStrI_LT(Param: PExpressionRec);
- procedure FuncStrI_GT(Param: PExpressionRec);
- procedure FuncStrI_LTE(Param: PExpressionRec);
- procedure FuncStrI_GTE(Param: PExpressionRec);
- procedure FuncStr_EQ(Param: PExpressionRec);
- procedure FuncStr_NEQ(Param: PExpressionRec);
- procedure FuncStr_LT(Param: PExpressionRec);
- procedure FuncStr_GT(Param: PExpressionRec);
- procedure FuncStr_LTE(Param: PExpressionRec);
- procedure FuncStr_GTE(Param: PExpressionRec);
- procedure Func_FF_EQ(Param: PExpressionRec);
- procedure Func_FF_NEQ(Param: PExpressionRec);
- procedure Func_FF_LT(Param: PExpressionRec);
- procedure Func_FF_GT(Param: PExpressionRec);
- procedure Func_FF_LTE(Param: PExpressionRec);
- procedure Func_FF_GTE(Param: PExpressionRec);
- procedure Func_FI_EQ(Param: PExpressionRec);
- procedure Func_FI_NEQ(Param: PExpressionRec);
- procedure Func_FI_LT(Param: PExpressionRec);
- procedure Func_FI_GT(Param: PExpressionRec);
- procedure Func_FI_LTE(Param: PExpressionRec);
- procedure Func_FI_GTE(Param: PExpressionRec);
- procedure Func_II_EQ(Param: PExpressionRec);
- procedure Func_II_NEQ(Param: PExpressionRec);
- procedure Func_II_LT(Param: PExpressionRec);
- procedure Func_II_GT(Param: PExpressionRec);
- procedure Func_II_LTE(Param: PExpressionRec);
- procedure Func_II_GTE(Param: PExpressionRec);
- procedure Func_IF_EQ(Param: PExpressionRec);
- procedure Func_IF_NEQ(Param: PExpressionRec);
- procedure Func_IF_LT(Param: PExpressionRec);
- procedure Func_IF_GT(Param: PExpressionRec);
- procedure Func_IF_LTE(Param: PExpressionRec);
- procedure Func_IF_GTE(Param: PExpressionRec);
- {$ifdef SUPPORT_INT64}
- procedure Func_LL_EQ(Param: PExpressionRec);
- procedure Func_LL_NEQ(Param: PExpressionRec);
- procedure Func_LL_LT(Param: PExpressionRec);
- procedure Func_LL_GT(Param: PExpressionRec);
- procedure Func_LL_LTE(Param: PExpressionRec);
- procedure Func_LL_GTE(Param: PExpressionRec);
- procedure Func_LF_EQ(Param: PExpressionRec);
- procedure Func_LF_NEQ(Param: PExpressionRec);
- procedure Func_LF_LT(Param: PExpressionRec);
- procedure Func_LF_GT(Param: PExpressionRec);
- procedure Func_LF_LTE(Param: PExpressionRec);
- procedure Func_LF_GTE(Param: PExpressionRec);
- procedure Func_FL_EQ(Param: PExpressionRec);
- procedure Func_FL_NEQ(Param: PExpressionRec);
- procedure Func_FL_LT(Param: PExpressionRec);
- procedure Func_FL_GT(Param: PExpressionRec);
- procedure Func_FL_LTE(Param: PExpressionRec);
- procedure Func_FL_GTE(Param: PExpressionRec);
- procedure Func_LI_EQ(Param: PExpressionRec);
- procedure Func_LI_NEQ(Param: PExpressionRec);
- procedure Func_LI_LT(Param: PExpressionRec);
- procedure Func_LI_GT(Param: PExpressionRec);
- procedure Func_LI_LTE(Param: PExpressionRec);
- procedure Func_LI_GTE(Param: PExpressionRec);
- procedure Func_IL_EQ(Param: PExpressionRec);
- procedure Func_IL_NEQ(Param: PExpressionRec);
- procedure Func_IL_LT(Param: PExpressionRec);
- procedure Func_IL_GT(Param: PExpressionRec);
- procedure Func_IL_LTE(Param: PExpressionRec);
- procedure Func_IL_GTE(Param: PExpressionRec);
- {$endif}
- procedure Func_AND(Param: PExpressionRec);
- procedure Func_OR(Param: PExpressionRec);
- procedure Func_NOT(Param: PExpressionRec);
- implementation
- uses
- dbf,
- dbf_dbffile,
- dbf_str
- {$ifdef WIN32}
- ,Windows
- {$endif}
- ;
- type
- // TFieldVar aids in retrieving field values from records
- // in their proper type
- TFieldVar = class(TObject)
- private
- FFieldDef: TDbfFieldDef;
- FDbfFile: TDbfFile;
- FFieldName: string;
- protected
- function GetFieldVal: Pointer; virtual; abstract;
- function GetFieldType: TExpressionType; virtual; abstract;
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); virtual; abstract;
- property FieldVal: Pointer read GetFieldVal;
- property FieldDef: TDbfFieldDef read FFieldDef;
- property FieldType: TExpressionType read GetFieldType;
- property DbfFile: TDbfFile read FDbfFile;
- property FieldName: string read FFieldName;
- end;
- TStringFieldVar = class(TFieldVar)
- protected
- FFieldVal: PChar;
- function GetFieldVal: Pointer; override;
- function GetFieldType: TExpressionType; override;
- end;
- TRawStringFieldVar = class(TStringFieldVar)
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); override;
- end;
- TAnsiStringFieldVar = class(TStringFieldVar)
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- destructor Destroy; override;
- procedure Refresh(Buffer: PChar); override;
- end;
- TFloatFieldVar = class(TFieldVar)
- private
- FFieldVal: Double;
- protected
- function GetFieldVal: Pointer; override;
- function GetFieldType: TExpressionType; override;
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); override;
- end;
- TIntegerFieldVar = class(TFieldVar)
- private
- FFieldVal: Integer;
- protected
- function GetFieldVal: Pointer; override;
- function GetFieldType: TExpressionType; override;
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); override;
- end;
- {$ifdef SUPPORT_INT64}
- TLargeIntFieldVar = class(TFieldVar)
- private
- FFieldVal: Int64;
- protected
- function GetFieldVal: Pointer; override;
- function GetFieldType: TExpressionType; override;
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); override;
- end;
- {$endif}
- TDateTimeFieldVar = class(TFieldVar)
- private
- FFieldVal: TDateTimeRec;
- function GetFieldType: TExpressionType; override;
- protected
- function GetFieldVal: Pointer; override;
- public
- constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- procedure Refresh(Buffer: PChar); override;
- end;
- //--TFieldVar----------------------------------------------------------------
- constructor TFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited Create;
- // store field
- FFieldDef := UseFieldDef;
- FDbfFile := ADbfFile;
- FFieldName := UseFieldDef.FieldName;
- end;
- //--TStringFieldVar-------------------------------------------------------------
- function TStringFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TStringFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etString;
- end;
- //--TRawStringFieldVar----------------------------------------------------------
- constructor TRawStringFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- end;
- procedure TRawStringFieldVar.Refresh(Buffer: PChar);
- begin
- FFieldVal := Buffer + FieldDef.Offset;
- end;
- //--TAnsiStringFieldVar---------------------------------------------------------
- constructor TAnsiStringFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- GetMem(FFieldVal, UseFieldDef.Size+1);
- end;
- destructor TAnsiStringFieldVar.Destroy;
- begin
- FreeMem(FFieldVal);
- inherited;
- end;
- procedure TAnsiStringFieldVar.Refresh(Buffer: PChar);
- var
- Len: Integer;
- begin
- // copy field data
- Len := FieldDef.Size;
- Move(Buffer[FieldDef.Offset], FFieldVal[0], Len);
- // trim right side spaces by null-termination
- while (Len >= 1) and (FFieldVal[Len-1] = ' ') do Dec(Len);
- FFieldVal[Len] := #0;
- // translate to ANSI
- TranslateString(DbfFile.UseCodePage, GetACP, FFieldVal, FFieldVal, Len);
- end;
- //--TFloatFieldVar-----------------------------------------------------------
- constructor TFloatFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- end;
- function TFloatFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TFloatFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etFloat;
- end;
- procedure TFloatFieldVar.Refresh(Buffer: PChar);
- begin
- // database width is default 64-bit double
- if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
- FFieldVal := 0.0;
- end;
- //--TIntegerFieldVar----------------------------------------------------------
- constructor TIntegerFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- end;
- function TIntegerFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TIntegerFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etInteger;
- end;
- procedure TIntegerFieldVar.Refresh(Buffer: PChar);
- begin
- FFieldVal := 0;
- FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal);
- end;
- {$ifdef SUPPORT_INT64}
- //--TLargeIntFieldVar----------------------------------------------------------
- constructor TLargeIntFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- end;
- function TLargeIntFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TLargeIntFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etLargeInt;
- end;
- procedure TLargeIntFieldVar.Refresh(Buffer: PChar);
- begin
- if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
- FFieldVal := 0;
- end;
- {$endif}
- //--TDateTimeFieldVar---------------------------------------------------------
- constructor TDateTimeFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
- begin
- inherited;
- end;
- function TDateTimeFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TDateTimeFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etDateTime;
- end;
- procedure TDateTimeFieldVar.Refresh(Buffer: PChar);
- begin
- if not FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal) then
- FFieldVal.DateTime := 0.0;
- end;
- //--Expression functions-----------------------------------------------------
- procedure FuncFloatToStr(Param: PExpressionRec);
- var
- width, numDigits, resWidth: Integer;
- extVal: Extended;
- begin
- with Param^ do
- begin
- // get params;
- numDigits := 0;
- if Args[1] <> nil then
- width := PInteger(Args[1])^
- else
- width := 18;
- if Args[2] <> nil then
- numDigits := PInteger(Args[2])^;
- // convert to string
- Res.AssureSpace(width);
- extVal := PDouble(Args[0])^;
- resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, 18, numDigits);
- // always use dot as decimal separator
- if numDigits > 0 then
- Res.MemoryPos^[resWidth-numDigits-1] := '.';
- // result width smaller than requested width? -> add space to compensate
- if (Args[1] <> nil) and (resWidth < width) then
- begin
- // move string so that it's right-aligned
- Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth);
- // fill gap with spaces
- FillChar(Res.MemoryPos^^, width-resWidth, ' ');
- // resWidth has been padded, update
- resWidth := width;
- end else if resWidth > width then begin
- // result width more than requested width, cut
- resWidth := width;
- end;
- // advance pointer
- Inc(Res.MemoryPos^, resWidth);
- // null-terminate
- Res.MemoryPos^^ := #0;
- end;
- end;
- procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: Integer);
- var
- width: Integer;
- begin
- with Param^ do
- begin
- // width specified?
- if Args[1] <> nil then
- begin
- // convert to string
- width := PInteger(Args[1])^;
- GetStrFromInt_Width(Val, width, Res.MemoryPos^, #32);
- // advance pointer
- Inc(Res.MemoryPos^, width);
- // need to add decimal?
- if Args[2] <> nil then
- begin
- // get number of digits
- width := PInteger(Args[2])^;
- // add decimal dot
- Res.MemoryPos^^ := '.';
- Inc(Res.MemoryPos^);
- // add zeroes
- FillChar(Res.MemoryPos^^, width, '0');
- // go to end
- Inc(Res.MemoryPos^, width);
- end;
- end else begin
- // convert to string
- width := GetStrFromInt(Val, Res.MemoryPos^);
- // advance pointer
- Inc(Param^.Res.MemoryPos^, width);
- end;
- // null-terminate
- Res.MemoryPos^^ := #0;
- end;
- end;
- procedure FuncIntToStr(Param: PExpressionRec);
- begin
- FuncIntToStr_Gen(Param, PInteger(Param^.Args[0])^);
- end;
- procedure FuncDateToStr(Param: PExpressionRec);
- var
- TempStr: string;
- begin
- with Param^ do
- begin
- // create in temporary string
- DateTimeToString(TempStr, 'yyyymmdd', PDateTimeRec(Args[0])^.DateTime);
- // copy to buffer
- Res.Append(PChar(TempStr), Length(TempStr));
- end;
- end;
- procedure FuncSubString(Param: PExpressionRec);
- var
- srcLen, index, count: Integer;
- begin
- with Param^ do
- begin
- srcLen := StrLen(Args[0]);
- index := PInteger(Args[1])^ - 1;
- count := PInteger(Args[2])^;
- if index + count <= srcLen then
- Res.Append(Args[0]+index, count)
- else
- Res.MemoryPos^^ := #0;
- end;
- end;
- procedure FuncUppercase(Param: PExpressionRec);
- var
- dest: PChar;
- begin
- with Param^ do
- begin
- // first copy
- dest := (Res.MemoryPos)^;
- Res.Append(Args[0], StrLen(Args[0]));
- // make uppercase
- AnsiStrUpper(dest);
- end;
- end;
- procedure FuncLowercase(Param: PExpressionRec);
- var
- dest: PChar;
- begin
- with Param^ do
- begin
- // first copy
- dest := (Res.MemoryPos)^;
- Res.Append(Args[0], StrLen(Args[0]));
- // make lowercase
- AnsiStrLower(dest);
- end;
- end;
- procedure FuncAdd_F_FF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^;
- end;
- procedure FuncAdd_F_FI(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^;
- end;
- procedure FuncAdd_F_II(Param: PExpressionRec);
- begin
- with Param^ do
- PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^;
- end;
- procedure FuncAdd_F_IF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^;
- end;
- {$ifdef SUPPORT_INT64}
- procedure FuncAdd_F_FL(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^;
- end;
- procedure FuncAdd_F_IL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^;
- end;
- procedure FuncAdd_F_LL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^;
- end;
- procedure FuncAdd_F_LF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^;
- end;
- procedure FuncAdd_F_LI(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^;
- end;
- {$endif}
- procedure FuncSub_F_FF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^;
- end;
- procedure FuncSub_F_FI(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^;
- end;
- procedure FuncSub_F_II(Param: PExpressionRec);
- begin
- with Param^ do
- PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^;
- end;
- procedure FuncSub_F_IF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^;
- end;
- {$ifdef SUPPORT_INT64}
- procedure FuncSub_F_FL(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^;
- end;
- procedure FuncSub_F_IL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^;
- end;
- procedure FuncSub_F_LL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^;
- end;
- procedure FuncSub_F_LF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^;
- end;
- procedure FuncSub_F_LI(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^;
- end;
- {$endif}
- procedure FuncMul_F_FF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^;
- end;
- procedure FuncMul_F_FI(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^;
- end;
- procedure FuncMul_F_II(Param: PExpressionRec);
- begin
- with Param^ do
- PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^;
- end;
- procedure FuncMul_F_IF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^;
- end;
- {$ifdef SUPPORT_INT64}
- procedure FuncMul_F_FL(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^;
- end;
- procedure FuncMul_F_IL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^;
- end;
- procedure FuncMul_F_LL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^;
- end;
- procedure FuncMul_F_LF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^;
- end;
- procedure FuncMul_F_LI(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^;
- end;
- {$endif}
- procedure FuncDiv_F_FF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^;
- end;
- procedure FuncDiv_F_FI(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^;
- end;
- procedure FuncDiv_F_II(Param: PExpressionRec);
- begin
- with Param^ do
- PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^;
- end;
- procedure FuncDiv_F_IF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^;
- end;
- {$ifdef SUPPORT_INT64}
- procedure FuncDiv_F_FL(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^;
- end;
- procedure FuncDiv_F_IL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^;
- end;
- procedure FuncDiv_F_LL(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^;
- end;
- procedure FuncDiv_F_LF(Param: PExpressionRec);
- begin
- with Param^ do
- PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^;
- end;
- procedure FuncDiv_F_LI(Param: PExpressionRec);
- begin
- with Param^ do
- PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^;
- end;
- {$endif}
- procedure FuncStrI_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0);
- end;
- procedure FuncStrIP_EQ(Param: PExpressionRec);
- var
- arg0len, arg1len: integer;
- match: boolean;
- str0, str1: string;
- begin
- with Param^ do
- begin
- arg1len := StrLen(Args[1]);
- if Args[1][0] = '*' then
- begin
- if Args[1][arg1len-1] = '*' then
- begin
- str0 := AnsiStrUpper(Args[0]);
- str1 := AnsiStrUpper(Args[1]+1);
- setlength(str1, arg1len-2);
- match := AnsiPos(str0, str1) = 0;
- end else begin
- arg0len := StrLen(Args[0]);
- // at least length without asterisk
- match := arg0len >= arg1len - 1;
- if match then
- match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
- end;
- end else
- if Args[1][arg1len-1] = '*' then
- begin
- arg0len := StrLen(Args[0]);
- match := arg1len >= arg0len - 1;
- if match then
- match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0;
- end else begin
- match := AnsiStrIComp(Args[0], Args[1]) = 0;
- end;
- Res.MemoryPos^^ := Char(match);
- end;
- end;
- procedure FuncStrI_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0);
- end;
- procedure FuncStrI_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0);
- end;
- procedure FuncStrI_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0);
- end;
- procedure FuncStrI_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0);
- end;
- procedure FuncStrI_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0);
- end;
- procedure FuncStrP_EQ(Param: PExpressionRec);
- var
- arg0len, arg1len: integer;
- match: boolean;
- begin
- with Param^ do
- begin
- arg1len := StrLen(Args[1]);
- if Args[1][0] = '*' then
- begin
- if Args[1][arg1len-1] = '*' then
- begin
- Args[1][arg1len-1] := #0;
- match := AnsiStrPos(Args[0], Args[1]+1) <> nil;
- Args[1][arg1len-1] := '*';
- end else begin
- arg0len := StrLen(Args[0]);
- // at least length without asterisk
- match := arg0len >= arg1len - 1;
- if match then
- match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
- end;
- end else
- if Args[1][arg1len-1] = '*' then
- begin
- arg0len := StrLen(Args[0]);
- match := arg1len >= arg0len - 1;
- if match then
- match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0;
- end else begin
- match := AnsiStrComp(Args[0], Args[1]) = 0;
- end;
- Res.MemoryPos^^ := Char(match);
- end;
- end;
- procedure FuncStr_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0);
- end;
- procedure FuncStr_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0);
- end;
- procedure FuncStr_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0);
- end;
- procedure FuncStr_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0);
- end;
- procedure FuncStr_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0);
- end;
- procedure FuncStr_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0);
- end;
- procedure Func_FF_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^);
- end;
- procedure Func_FF_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^);
- end;
- procedure Func_FF_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^);
- end;
- procedure Func_FF_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^);
- end;
- procedure Func_FF_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^);
- end;
- procedure Func_FF_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^);
- end;
- procedure Func_FI_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^);
- end;
- procedure Func_FI_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^);
- end;
- procedure Func_FI_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^);
- end;
- procedure Func_FI_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^);
- end;
- procedure Func_FI_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^);
- end;
- procedure Func_FI_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^);
- end;
- procedure Func_II_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^);
- end;
- procedure Func_II_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^);
- end;
- procedure Func_II_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^);
- end;
- procedure Func_II_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^);
- end;
- procedure Func_II_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^);
- end;
- procedure Func_II_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^);
- end;
- procedure Func_IF_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^);
- end;
- procedure Func_IF_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^);
- end;
- procedure Func_IF_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^);
- end;
- procedure Func_IF_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^);
- end;
- procedure Func_IF_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^);
- end;
- procedure Func_IF_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^);
- end;
- {$ifdef SUPPORT_INT64}
- procedure Func_LL_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^);
- end;
- procedure Func_LL_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^);
- end;
- procedure Func_LL_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^);
- end;
- procedure Func_LL_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^);
- end;
- procedure Func_LL_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^);
- end;
- procedure Func_LL_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^);
- end;
- procedure Func_LF_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^);
- end;
- procedure Func_LF_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^);
- end;
- procedure Func_LF_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^);
- end;
- procedure Func_LF_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^);
- end;
- procedure Func_LF_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^);
- end;
- procedure Func_LF_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^);
- end;
- procedure Func_FL_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^);
- end;
- procedure Func_FL_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^);
- end;
- procedure Func_FL_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^);
- end;
- procedure Func_FL_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^);
- end;
- procedure Func_FL_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^);
- end;
- procedure Func_FL_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^);
- end;
- procedure Func_LI_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^);
- end;
- procedure Func_LI_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^);
- end;
- procedure Func_LI_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^);
- end;
- procedure Func_LI_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^);
- end;
- procedure Func_LI_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^);
- end;
- procedure Func_LI_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^);
- end;
- procedure Func_IL_EQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^);
- end;
- procedure Func_IL_NEQ(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^);
- end;
- procedure Func_IL_LT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^);
- end;
- procedure Func_IL_GT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^);
- end;
- procedure Func_IL_LTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^);
- end;
- procedure Func_IL_GTE(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^);
- end;
- {$endif}
- procedure Func_AND(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^));
- end;
- procedure Func_OR(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^));
- end;
- procedure Func_NOT(Param: PExpressionRec);
- begin
- with Param^ do
- Res.MemoryPos^^ := Char(not Boolean(Args[0]^));
- end;
- //--TDbfParser---------------------------------------------------------------
- var
- DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TExpressList;
- DbfWordsSensPartialList, DbfWordsInsensPartialList: TExpressList;
- DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TExpressList;
- DbfWordsGeneralList: TExpressList;
- constructor TDbfParser.Create(ADbfFile: Pointer);
- begin
- FDbfFile := ADbfFile;
- FFieldVarList := TStringList.Create;
- FCaseInsensitive := true;
- FRawStringFields := true;
- inherited Create;
- end;
- destructor TDbfParser.Destroy;
- begin
- ClearExpressions;
- inherited;
- FreeAndNil(FFieldVarList);
- end;
- function TDbfParser.GetResultType: TExpressionType;
- begin
- // if not a real expression, return type ourself
- if FIsExpression then
- Result := inherited GetResultType
- else
- Result := FFieldType;
- end;
- procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean);
- begin
- if FCaseInsensitive <> NewInsensitive then
- begin
- // clear and regenerate functions
- FCaseInsensitive := NewInsensitive;
- FillExpressList;
- if Length(Expression) > 0 then
- ParseExpression(Expression);
- end;
- end;
- procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean);
- begin
- if FPartialMatch <> NewPartialMatch then
- begin
- // refill function list
- FPartialMatch := NewPartialMatch;
- FillExpressList;
- if Length(Expression) > 0 then
- ParseExpression(Expression);
- end;
- end;
- procedure TDbfParser.SetRawStringFields(NewRawFields: Boolean);
- begin
- if FRawStringFields <> NewRawFields then
- begin
- // clear and regenerate functions, custom fields will be deleted too
- FRawStringFields := NewRawFields;
- if Length(Expression) > 0 then
- ParseExpression(Expression);
- end;
- end;
- procedure TDbfParser.FillExpressList;
- begin
- FWordsList.FreeAll;
- FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1);
- if FCaseInsensitive then
- begin
- FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1);
- if FPartialMatch then
- begin
- FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1);
- end else begin
- FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1);
- end;
- end else begin
- FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1);
- if FPartialMatch then
- begin
- FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1);
- end else begin
- FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1);
- end;
- end;
- end;
- function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef;
- begin
- Result := TDbfFile(FDbfFile).GetFieldInfo(VarName);
- end;
- procedure TDbfParser.HandleUnknownVariable(VarName: string);
- var
- FieldInfo: TDbfFieldDef;
- TempFieldVar: TFieldVar;
- begin
- // is this variable a fieldname?
- FieldInfo := GetVariableInfo(VarName);
- if FieldInfo = nil then
- raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]);
- // define field in parser
- case FieldInfo.FieldType of
- ftString, ftBoolean:
- begin
- if RawStringFields then
- begin
- { raw string fields have fixed length, not null-terminated }
- TempFieldVar := TRawStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineStringVariableFixedLen(VarName, TempFieldVar.FieldVal, FieldInfo.Size);
- end else begin
- { ansi string field function translates and null-terminates field value }
- TempFieldVar := TAnsiStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineStringVariable(VarName, TempFieldVar.FieldVal);
- end;
- end;
- ftFloat:
- begin
- TempFieldVar := TFloatFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineFloatVariable(VarName, TempFieldVar.FieldVal);
- end;
- ftAutoInc, ftInteger, ftSmallInt:
- begin
- TempFieldVar := TIntegerFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineIntegerVariable(VarName, TempFieldVar.FieldVal);
- end;
- {
- ftSmallInt:
- begin
- TempFieldVar := TSmallIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineSmallIntVariable(VarName, TempFieldVar.FieldVal);
- end;
- }
- {$ifdef SUPPORT_INT64}
- ftLargeInt:
- begin
- TempFieldVar := TLargeIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineLargeIntVariable(VarName, TempFieldVar.FieldVal);
- end;
- {$endif}
- ftDate, ftDateTime:
- begin
- TempFieldVar := TDateTimeFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineDateTimeVariable(VarName, TempFieldVar.FieldVal);
- end;
- else
- raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_INVALID_FIELD, [VarName]);
- end;
- // add to our own list
- FFieldVarList.AddObject(VarName, TempFieldVar);
- end;
- function TDbfParser.CurrentExpression: string;
- begin
- Result := FCurrentExpression;
- end;
- procedure TDbfParser.ClearExpressions;
- var
- I: Integer;
- begin
- inherited;
- // test if already freed
- if FFieldVarList <> nil then
- begin
- // free field list
- for I := 0 to FFieldVarList.Count - 1 do
- begin
- // replacing with nil = undefining variable
- ReplaceFunction(TFieldVar(FFieldVarList.Objects[I]).FieldName, nil);
- TFieldVar(FFieldVarList.Objects[I]).Free;
- end;
- FFieldVarList.Clear;
- end;
- // clear expression
- FCurrentExpression := EmptyStr;
- end;
- procedure TDbfParser.ParseExpression(Expression: string);
- var
- TempBuffer: array[0..4000] of Char;
- begin
- // clear any current expression
- ClearExpressions;
- // is this a simple field or complex expression?
- FIsExpression := GetVariableInfo(Expression) = nil;
- if FIsExpression then
- begin
- // parse requested
- CompileExpression(Expression);
- // determine length of string length expressions
- if ResultType = etString then
- begin
- // make empty record
- TDbfFile(FDbfFile).InitRecord(@TempBuffer[0]);
- FResultLen := StrLen(ExtractFromBuffer(@TempBuffer[0]));
- end;
- end else begin
- // simple field, create field variable for it
- HandleUnknownVariable(Expression);
- FFieldType := TFieldVar(FFieldVarList.Objects[0]).FieldType;
- // set result len of variable length fields
- if FFieldType = etString then
- FResultLen := TFieldVar(FFieldVarList.Objects[0]).FieldDef.Size
- end;
- // set result len for fixed length expressions / fields
- case ResultType of
- etBoolean: FResultLen := 1;
- etInteger: FResultLen := 4;
- etFloat: FResultLen := 8;
- etDateTime: FResultLen := 8;
- end;
- // check if expression not too long
- if FResultLen > 100 then
- raise EDbfError.CreateFmt(STRING_INDEX_EXPRESSION_TOO_LONG, [Expression, FResultLen]);
- // if no errors, assign current expression
- FCurrentExpression := Expression;
- end;
- function TDbfParser.ExtractFromBuffer(Buffer: PChar): PChar;
- var
- I: Integer;
- begin
- // prepare all field variables
- for I := 0 to FFieldVarList.Count - 1 do
- TFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer);
- // complex expression?
- if FIsExpression then
- begin
- // execute expression
- EvaluateCurrent;
- Result := ExpResult;
- end else begin
- // simple field, get field result
- Result := TFieldVar(FFieldVarList.Objects[0]).FieldVal;
- // if string then dereference
- if FFieldType = etString then
- Result := PPChar(Result)^;
- end;
- end;
- initialization
- DbfWordsGeneralList := TExpressList.Create;
- DbfWordsInsensGeneralList := TExpressList.Create;
- DbfWordsInsensNoPartialList := TExpressList.Create;
- DbfWordsInsensPartialList := TExpressList.Create;
- DbfWordsSensGeneralList := TExpressList.Create;
- DbfWordsSensNoPartialList := TExpressList.Create;
- DbfWordsSensPartialList := TExpressList.Create;
- with DbfWordsGeneralList do
- begin
- // basic function functionality
- Add(TLeftBracket.Create('(', nil));
- Add(TRightBracket.Create(')', nil));
- Add(TComma.Create(',', nil));
- // operators - name, param types, result type, func addr, precedence
- Add(TFunction.CreateOper('+', 'SS', etString, nil, 40));
- Add(TFunction.CreateOper('+', 'FF', etFloat, FuncAdd_F_FF, 40));
- Add(TFunction.CreateOper('+', 'FI', etFloat, FuncAdd_F_FI, 40));
- Add(TFunction.CreateOper('+', 'IF', etFloat, FuncAdd_F_IF, 40));
- Add(TFunction.CreateOper('+', 'II', etInteger, FuncAdd_F_II, 40));
- {$ifdef SUPPORT_INT64}
- Add(TFunction.CreateOper('+', 'FL', etFloat, FuncAdd_F_FL, 40));
- Add(TFunction.CreateOper('+', 'IL', etLargeInt, FuncAdd_F_IL, 40));
- Add(TFunction.CreateOper('+', 'LF', etFloat, FuncAdd_F_LF, 40));
- Add(TFunction.CreateOper('+', 'LL', etLargeInt, FuncAdd_F_LI, 40));
- Add(TFunction.CreateOper('+', 'LI', etLargeInt, FuncAdd_F_LL, 40));
- {$endif}
- Add(TFunction.CreateOper('-', 'FF', etFloat, FuncSub_F_FF, 40));
- Add(TFunction.CreateOper('-', 'FI', etFloat, FuncSub_F_FI, 40));
- Add(TFunction.CreateOper('-', 'IF', etFloat, FuncSub_F_IF, 40));
- Add(TFunction.CreateOper('-', 'II', etInteger, FuncSub_F_II, 40));
- {$ifdef SUPPORT_INT64}
- Add(TFunction.CreateOper('-', 'FL', etFloat, FuncSub_F_FL, 40));
- Add(TFunction.CreateOper('-', 'IL', etLargeInt, FuncSub_F_IL, 40));
- Add(TFunction.CreateOper('-', 'LF', etFloat, FuncSub_F_LF, 40));
- Add(TFunction.CreateOper('-', 'LL', etLargeInt, FuncSub_F_LI, 40));
- Add(TFunction.CreateOper('-', 'LI', etLargeInt, FuncSub_F_LL, 40));
- {$endif}
- Add(TFunction.CreateOper('*', 'FF', etFloat, FuncMul_F_FF, 40));
- Add(TFunction.CreateOper('*', 'FI', etFloat, FuncMul_F_FI, 40));
- Add(TFunction.CreateOper('*', 'IF', etFloat, FuncMul_F_IF, 40));
- Add(TFunction.CreateOper('*', 'II', etInteger, FuncMul_F_II, 40));
- {$ifdef SUPPORT_INT64}
- Add(TFunction.CreateOper('*', 'FL', etFloat, FuncMul_F_FL, 40));
- Add(TFunction.CreateOper('*', 'IL', etLargeInt, FuncMul_F_IL, 40));
- Add(TFunction.CreateOper('*', 'LF', etFloat, FuncMul_F_LF, 40));
- Add(TFunction.CreateOper('*', 'LL', etLargeInt, FuncMul_F_LI, 40));
- Add(TFunction.CreateOper('*', 'LI', etLargeInt, FuncMul_F_LL, 40));
- {$endif}
- Add(TFunction.CreateOper('/', 'FF', etFloat, FuncDiv_F_FF, 40));
- Add(TFunction.CreateOper('/', 'FI', etFloat, FuncDiv_F_FI, 40));
- Add(TFunction.CreateOper('/', 'IF', etFloat, FuncDiv_F_IF, 40));
- Add(TFunction.CreateOper('/', 'II', etInteger, FuncDiv_F_II, 40));
- {$ifdef SUPPORT_INT64}
- Add(TFunction.CreateOper('/', 'FL', etFloat, FuncDiv_F_FL, 40));
- Add(TFunction.CreateOper('/', 'IL', etLargeInt, FuncDiv_F_IL, 40));
- Add(TFunction.CreateOper('/', 'LF', etFloat, FuncDiv_F_LF, 40));
- Add(TFunction.CreateOper('/', 'LL', etLargeInt, FuncDiv_F_LI, 40));
- Add(TFunction.CreateOper('/', 'LI', etLargeInt, FuncDiv_F_LL, 40));
- {$endif}
- Add(TFunction.CreateOper('=', 'FF', etBoolean, Func_FF_EQ , 80));
- Add(TFunction.CreateOper('<', 'FF', etBoolean, Func_FF_LT , 80));
- Add(TFunction.CreateOper('>', 'FF', etBoolean, Func_FF_GT , 80));
- Add(TFunction.CreateOper('<=','FF', etBoolean, Func_FF_LTE, 80));
- Add(TFunction.CreateOper('>=','FF', etBoolean, Func_FF_GTE, 80));
- Add(TFunction.CreateOper('<>','FF', etBoolean, Func_FF_NEQ, 80));
- Add(TFunction.CreateOper('=', 'FI', etBoolean, Func_FI_EQ , 80));
- Add(TFunction.CreateOper('<', 'FI', etBoolean, Func_FI_LT , 80));
- Add(TFunction.CreateOper('>', 'FI', etBoolean, Func_FI_GT , 80));
- Add(TFunction.CreateOper('<=','FI', etBoolean, Func_FI_LTE, 80));
- Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80));
- Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80));
- Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80));
- Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80));
- Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80));
- Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80));
- Add(TFunction.CreateOper('>=','II', etBoolean, Func_II_GTE, 80));
- Add(TFunction.CreateOper('<>','II', etBoolean, Func_II_NEQ, 80));
- Add(TFunction.CreateOper('=', 'IF', etBoolean, Func_IF_EQ , 80));
- Add(TFunction.CreateOper('<', 'IF', etBoolean, Func_IF_LT , 80));
- Add(TFunction.CreateOper('>', 'IF', etBoolean, Func_IF_GT , 80));
- Add(TFunction.CreateOper('<=','IF', etBoolean, Func_IF_LTE, 80));
- Add(TFunction.CreateOper('>=','IF', etBoolean, Func_IF_GTE, 80));
- Add(TFunction.CreateOper('<>','IF', etBoolean, Func_IF_NEQ, 80));
- {$ifdef SUPPORT_INT64}
- Add(TFunction.CreateOper('=', 'LL', etBoolean, Func_LL_EQ , 80));
- Add(TFunction.CreateOper('<', 'LL', etBoolean, Func_LL_LT , 80));
- Add(TFunction.CreateOper('>', 'LL', etBoolean, Func_LL_GT , 80));
- Add(TFunction.CreateOper('<=','LL', etBoolean, Func_LL_LTE, 80));
- Add(TFunction.CreateOper('>=','LL', etBoolean, Func_LL_GTE, 80));
- Add(TFunction.CreateOper('<>','LL', etBoolean, Func_LL_NEQ, 80));
- Add(TFunction.CreateOper('=', 'LF', etBoolean, Func_LF_EQ , 80));
- Add(TFunction.CreateOper('<', 'LF', etBoolean, Func_LF_LT , 80));
- Add(TFunction.CreateOper('>', 'LF', etBoolean, Func_LF_GT , 80));
- Add(TFunction.CreateOper('<=','LF', etBoolean, Func_LF_LTE, 80));
- Add(TFunction.CreateOper('>=','LF', etBoolean, Func_LF_GTE, 80));
- Add(TFunction.CreateOper('<>','FI', etBoolean, Func_LF_NEQ, 80));
- Add(TFunction.CreateOper('=', 'LI', etBoolean, Func_LI_EQ , 80));
- Add(TFunction.CreateOper('<', 'LI', etBoolean, Func_LI_LT , 80));
- Add(TFunction.CreateOper('>', 'LI', etBoolean, Func_LI_GT , 80));
- Add(TFunction.CreateOper('<=','LI', etBoolean, Func_LI_LTE, 80));
- Add(TFunction.CreateOper('>=','LI', etBoolean, Func_LI_GTE, 80));
- Add(TFunction.CreateOper('<>','LI', etBoolean, Func_LI_NEQ, 80));
- Add(TFunction.CreateOper('=', 'FL', etBoolean, Func_FL_EQ , 80));
- Add(TFunction.CreateOper('<', 'FL', etBoolean, Func_FL_LT , 80));
- Add(TFunction.CreateOper('>', 'FL', etBoolean, Func_FL_GT , 80));
- Add(TFunction.CreateOper('<=','FL', etBoolean, Func_FL_LTE, 80));
- Add(TFunction.CreateOper('>=','FL', etBoolean, Func_FL_GTE, 80));
- Add(TFunction.CreateOper('<>','FL', etBoolean, Func_FL_NEQ, 80));
- Add(TFunction.CreateOper('=', 'IL', etBoolean, Func_IL_EQ , 80));
- Add(TFunction.CreateOper('<', 'IL', etBoolean, Func_IL_LT , 80));
- Add(TFunction.CreateOper('>', 'IL', etBoolean, Func_IL_GT , 80));
- Add(TFunction.CreateOper('<=','IL', etBoolean, Func_IL_LTE, 80));
- Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80));
- Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80));
- {$endif}
- Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85));
- Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90));
- Add(TFunction.CreateOper('OR', 'BB', etBoolean, Func_OR, 100));
- // Functions - name, description, param types, min params, result type, Func addr
- Add(TFunction.Create('STR', '', 'FII', 1, etString, FuncFloatToStr, ''));
- Add(TFunction.Create('STR', '', 'III', 1, etString, FuncIntToStr, ''));
- Add(TFunction.Create('DTOS', '', 'D', 1, etString, FuncDateToStr, ''));
- Add(TFunction.Create('SUBSTR', 'SUBS', 'SII', 3, etString, FuncSubString, ''));
- Add(TFunction.Create('UPPERCASE', 'UPPER', 'S', 1, etString, FuncUppercase, ''));
- Add(TFunction.Create('LOWERCASE', 'LOWER', 'S', 1, etString, FuncLowercase, ''));
- end;
- with DbfWordsInsensGeneralList do
- begin
- Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStrI_LT , 80));
- Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStrI_GT , 80));
- Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStrI_LTE, 80));
- Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStrI_GTE, 80));
- Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStrI_NEQ, 80));
- end;
- with DbfWordsInsensNoPartialList do
- Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrI_EQ , 80));
- with DbfWordsInsensPartialList do
- Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrIP_EQ, 80));
- with DbfWordsSensGeneralList do
- begin
- Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStr_LT , 80));
- Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStr_GT , 80));
- Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStr_LTE, 80));
- Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStr_GTE, 80));
- Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStr_NEQ, 80));
- end;
-
- with DbfWordsSensNoPartialList do
- Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStr_EQ , 80));
- with DbfWordsSensPartialList do
- Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrP_EQ , 80));
- finalization
- DbfWordsGeneralList.Free;
- DbfWordsInsensGeneralList.Free;
- DbfWordsInsensNoPartialList.Free;
- DbfWordsInsensPartialList.Free;
- DbfWordsSensGeneralList.Free;
- DbfWordsSensNoPartialList.Free;
- DbfWordsSensPartialList.Free;
- end.
|