12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754 |
- 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
- 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
- procedure Refresh(Buffer: PChar); override;
- end;
- TIntegerFieldVar = class(TFieldVar)
- private
- FFieldVal: Integer;
- protected
- function GetFieldVal: Pointer; override;
- function GetFieldType: TExpressionType; override;
- public
- 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
- procedure Refresh(Buffer: PChar); override;
- end;
- {$endif}
- TDateTimeFieldVar = class(TFieldVar)
- private
- FFieldVal: TDateTimeRec;
- function GetFieldType: TExpressionType; override;
- protected
- function GetFieldVal: Pointer; override;
- public
- procedure Refresh(Buffer: PChar); override;
- end;
- TBooleanFieldVar = class(TFieldVar)
- private
- FFieldVal: boolean;
- function GetFieldType: TExpressionType; override;
- protected
- function GetFieldVal: Pointer; override;
- public
- 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----------------------------------------------------------
- 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-----------------------------------------------------------
- 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----------------------------------------------------------
- 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----------------------------------------------------------
- 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---------------------------------------------------------
- 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;
- //--TBooleanFieldVar---------------------------------------------------------
- function TBooleanFieldVar.GetFieldVal: Pointer;
- begin
- Result := @FFieldVal;
- end;
- function TBooleanFieldVar.GetFieldType: TExpressionType;
- begin
- Result := etBoolean;
- end;
- procedure TBooleanFieldVar.Refresh(Buffer: PChar);
- var
- lFieldVal: word;
- begin
- if FDbfFile.GetFieldDataFromDef(FieldDef, ftBoolean, Buffer, @lFieldVal) then
- FFieldVal := lFieldVal <> 0
- else
- FFieldVal := false;
- 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:
- 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;
- ftBoolean:
- begin
- TempFieldVar := TBooleanFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
- DefineBooleanVariable(VarName, TempFieldVar.FieldVal);
- 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.
|