dbf_parser.pas 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754
  1. unit dbf_parser;
  2. interface
  3. {$I dbf_common.inc}
  4. uses
  5. SysUtils,
  6. Classes,
  7. {$ifdef KYLIX}
  8. Libc,
  9. {$endif}
  10. {$ifndef WIN32}
  11. dbf_wtil,
  12. {$endif}
  13. db,
  14. dbf_prscore,
  15. dbf_common,
  16. dbf_fields,
  17. dbf_prsdef,
  18. dbf_prssupp;
  19. type
  20. TDbfParser = class(TCustomExpressionParser)
  21. private
  22. FDbfFile: Pointer;
  23. FFieldVarList: TStringList;
  24. FResultLen: Integer;
  25. FIsExpression: Boolean; // expression or simple field?
  26. FFieldType: TExpressionType;
  27. FCaseInsensitive: Boolean;
  28. FRawStringFields: Boolean;
  29. FPartialMatch: boolean;
  30. protected
  31. FCurrentExpression: string;
  32. procedure FillExpressList; override;
  33. procedure HandleUnknownVariable(VarName: string); override;
  34. function GetVariableInfo(VarName: string): TDbfFieldDef;
  35. function CurrentExpression: string; override;
  36. function GetResultType: TExpressionType; override;
  37. procedure SetCaseInsensitive(NewInsensitive: Boolean);
  38. procedure SetRawStringFields(NewRawFields: Boolean);
  39. procedure SetPartialMatch(NewPartialMatch: boolean);
  40. public
  41. constructor Create(ADbfFile: Pointer);
  42. destructor Destroy; override;
  43. procedure ClearExpressions; override;
  44. procedure ParseExpression(Expression: string); virtual;
  45. function ExtractFromBuffer(Buffer: PChar): PChar; virtual;
  46. property DbfFile: Pointer read FDbfFile write FDbfFile;
  47. property Expression: string read FCurrentExpression;
  48. property ResultLen: Integer read FResultLen;
  49. property CaseInsensitive: Boolean read FCaseInsensitive write SetCaseInsensitive;
  50. property RawStringFields: Boolean read FRawStringFields write SetRawStringFields;
  51. property PartialMatch: boolean read FPartialMatch write SetPartialMatch;
  52. end;
  53. //--Expression functions-----------------------------------------------------
  54. procedure FuncFloatToStr(Param: PExpressionRec);
  55. procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: Integer);
  56. procedure FuncIntToStr(Param: PExpressionRec);
  57. procedure FuncDateToStr(Param: PExpressionRec);
  58. procedure FuncSubString(Param: PExpressionRec);
  59. procedure FuncUppercase(Param: PExpressionRec);
  60. procedure FuncLowercase(Param: PExpressionRec);
  61. procedure FuncAdd_F_FF(Param: PExpressionRec);
  62. procedure FuncAdd_F_FI(Param: PExpressionRec);
  63. procedure FuncAdd_F_II(Param: PExpressionRec);
  64. procedure FuncAdd_F_IF(Param: PExpressionRec);
  65. {$ifdef SUPPORT_INT64}
  66. procedure FuncAdd_F_FL(Param: PExpressionRec);
  67. procedure FuncAdd_F_IL(Param: PExpressionRec);
  68. procedure FuncAdd_F_LL(Param: PExpressionRec);
  69. procedure FuncAdd_F_LF(Param: PExpressionRec);
  70. procedure FuncAdd_F_LI(Param: PExpressionRec);
  71. {$endif}
  72. procedure FuncSub_F_FF(Param: PExpressionRec);
  73. procedure FuncSub_F_FI(Param: PExpressionRec);
  74. procedure FuncSub_F_II(Param: PExpressionRec);
  75. procedure FuncSub_F_IF(Param: PExpressionRec);
  76. {$ifdef SUPPORT_INT64}
  77. procedure FuncSub_F_FL(Param: PExpressionRec);
  78. procedure FuncSub_F_IL(Param: PExpressionRec);
  79. procedure FuncSub_F_LL(Param: PExpressionRec);
  80. procedure FuncSub_F_LF(Param: PExpressionRec);
  81. procedure FuncSub_F_LI(Param: PExpressionRec);
  82. {$endif}
  83. procedure FuncMul_F_FF(Param: PExpressionRec);
  84. procedure FuncMul_F_FI(Param: PExpressionRec);
  85. procedure FuncMul_F_II(Param: PExpressionRec);
  86. procedure FuncMul_F_IF(Param: PExpressionRec);
  87. {$ifdef SUPPORT_INT64}
  88. procedure FuncMul_F_FL(Param: PExpressionRec);
  89. procedure FuncMul_F_IL(Param: PExpressionRec);
  90. procedure FuncMul_F_LL(Param: PExpressionRec);
  91. procedure FuncMul_F_LF(Param: PExpressionRec);
  92. procedure FuncMul_F_LI(Param: PExpressionRec);
  93. {$endif}
  94. procedure FuncDiv_F_FF(Param: PExpressionRec);
  95. procedure FuncDiv_F_FI(Param: PExpressionRec);
  96. procedure FuncDiv_F_II(Param: PExpressionRec);
  97. procedure FuncDiv_F_IF(Param: PExpressionRec);
  98. {$ifdef SUPPORT_INT64}
  99. procedure FuncDiv_F_FL(Param: PExpressionRec);
  100. procedure FuncDiv_F_IL(Param: PExpressionRec);
  101. procedure FuncDiv_F_LL(Param: PExpressionRec);
  102. procedure FuncDiv_F_LF(Param: PExpressionRec);
  103. procedure FuncDiv_F_LI(Param: PExpressionRec);
  104. {$endif}
  105. procedure FuncStrI_EQ(Param: PExpressionRec);
  106. procedure FuncStrI_NEQ(Param: PExpressionRec);
  107. procedure FuncStrI_LT(Param: PExpressionRec);
  108. procedure FuncStrI_GT(Param: PExpressionRec);
  109. procedure FuncStrI_LTE(Param: PExpressionRec);
  110. procedure FuncStrI_GTE(Param: PExpressionRec);
  111. procedure FuncStr_EQ(Param: PExpressionRec);
  112. procedure FuncStr_NEQ(Param: PExpressionRec);
  113. procedure FuncStr_LT(Param: PExpressionRec);
  114. procedure FuncStr_GT(Param: PExpressionRec);
  115. procedure FuncStr_LTE(Param: PExpressionRec);
  116. procedure FuncStr_GTE(Param: PExpressionRec);
  117. procedure Func_FF_EQ(Param: PExpressionRec);
  118. procedure Func_FF_NEQ(Param: PExpressionRec);
  119. procedure Func_FF_LT(Param: PExpressionRec);
  120. procedure Func_FF_GT(Param: PExpressionRec);
  121. procedure Func_FF_LTE(Param: PExpressionRec);
  122. procedure Func_FF_GTE(Param: PExpressionRec);
  123. procedure Func_FI_EQ(Param: PExpressionRec);
  124. procedure Func_FI_NEQ(Param: PExpressionRec);
  125. procedure Func_FI_LT(Param: PExpressionRec);
  126. procedure Func_FI_GT(Param: PExpressionRec);
  127. procedure Func_FI_LTE(Param: PExpressionRec);
  128. procedure Func_FI_GTE(Param: PExpressionRec);
  129. procedure Func_II_EQ(Param: PExpressionRec);
  130. procedure Func_II_NEQ(Param: PExpressionRec);
  131. procedure Func_II_LT(Param: PExpressionRec);
  132. procedure Func_II_GT(Param: PExpressionRec);
  133. procedure Func_II_LTE(Param: PExpressionRec);
  134. procedure Func_II_GTE(Param: PExpressionRec);
  135. procedure Func_IF_EQ(Param: PExpressionRec);
  136. procedure Func_IF_NEQ(Param: PExpressionRec);
  137. procedure Func_IF_LT(Param: PExpressionRec);
  138. procedure Func_IF_GT(Param: PExpressionRec);
  139. procedure Func_IF_LTE(Param: PExpressionRec);
  140. procedure Func_IF_GTE(Param: PExpressionRec);
  141. {$ifdef SUPPORT_INT64}
  142. procedure Func_LL_EQ(Param: PExpressionRec);
  143. procedure Func_LL_NEQ(Param: PExpressionRec);
  144. procedure Func_LL_LT(Param: PExpressionRec);
  145. procedure Func_LL_GT(Param: PExpressionRec);
  146. procedure Func_LL_LTE(Param: PExpressionRec);
  147. procedure Func_LL_GTE(Param: PExpressionRec);
  148. procedure Func_LF_EQ(Param: PExpressionRec);
  149. procedure Func_LF_NEQ(Param: PExpressionRec);
  150. procedure Func_LF_LT(Param: PExpressionRec);
  151. procedure Func_LF_GT(Param: PExpressionRec);
  152. procedure Func_LF_LTE(Param: PExpressionRec);
  153. procedure Func_LF_GTE(Param: PExpressionRec);
  154. procedure Func_FL_EQ(Param: PExpressionRec);
  155. procedure Func_FL_NEQ(Param: PExpressionRec);
  156. procedure Func_FL_LT(Param: PExpressionRec);
  157. procedure Func_FL_GT(Param: PExpressionRec);
  158. procedure Func_FL_LTE(Param: PExpressionRec);
  159. procedure Func_FL_GTE(Param: PExpressionRec);
  160. procedure Func_LI_EQ(Param: PExpressionRec);
  161. procedure Func_LI_NEQ(Param: PExpressionRec);
  162. procedure Func_LI_LT(Param: PExpressionRec);
  163. procedure Func_LI_GT(Param: PExpressionRec);
  164. procedure Func_LI_LTE(Param: PExpressionRec);
  165. procedure Func_LI_GTE(Param: PExpressionRec);
  166. procedure Func_IL_EQ(Param: PExpressionRec);
  167. procedure Func_IL_NEQ(Param: PExpressionRec);
  168. procedure Func_IL_LT(Param: PExpressionRec);
  169. procedure Func_IL_GT(Param: PExpressionRec);
  170. procedure Func_IL_LTE(Param: PExpressionRec);
  171. procedure Func_IL_GTE(Param: PExpressionRec);
  172. {$endif}
  173. procedure Func_AND(Param: PExpressionRec);
  174. procedure Func_OR(Param: PExpressionRec);
  175. procedure Func_NOT(Param: PExpressionRec);
  176. implementation
  177. uses
  178. dbf,
  179. dbf_dbffile,
  180. dbf_str
  181. {$ifdef WIN32}
  182. ,Windows
  183. {$endif}
  184. ;
  185. type
  186. // TFieldVar aids in retrieving field values from records
  187. // in their proper type
  188. TFieldVar = class(TObject)
  189. private
  190. FFieldDef: TDbfFieldDef;
  191. FDbfFile: TDbfFile;
  192. FFieldName: string;
  193. protected
  194. function GetFieldVal: Pointer; virtual; abstract;
  195. function GetFieldType: TExpressionType; virtual; abstract;
  196. public
  197. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  198. procedure Refresh(Buffer: PChar); virtual; abstract;
  199. property FieldVal: Pointer read GetFieldVal;
  200. property FieldDef: TDbfFieldDef read FFieldDef;
  201. property FieldType: TExpressionType read GetFieldType;
  202. property DbfFile: TDbfFile read FDbfFile;
  203. property FieldName: string read FFieldName;
  204. end;
  205. TStringFieldVar = class(TFieldVar)
  206. protected
  207. FFieldVal: PChar;
  208. function GetFieldVal: Pointer; override;
  209. function GetFieldType: TExpressionType; override;
  210. end;
  211. TRawStringFieldVar = class(TStringFieldVar)
  212. public
  213. procedure Refresh(Buffer: PChar); override;
  214. end;
  215. TAnsiStringFieldVar = class(TStringFieldVar)
  216. public
  217. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  218. destructor Destroy; override;
  219. procedure Refresh(Buffer: PChar); override;
  220. end;
  221. TFloatFieldVar = class(TFieldVar)
  222. private
  223. FFieldVal: Double;
  224. protected
  225. function GetFieldVal: Pointer; override;
  226. function GetFieldType: TExpressionType; override;
  227. public
  228. procedure Refresh(Buffer: PChar); override;
  229. end;
  230. TIntegerFieldVar = class(TFieldVar)
  231. private
  232. FFieldVal: Integer;
  233. protected
  234. function GetFieldVal: Pointer; override;
  235. function GetFieldType: TExpressionType; override;
  236. public
  237. procedure Refresh(Buffer: PChar); override;
  238. end;
  239. {$ifdef SUPPORT_INT64}
  240. TLargeIntFieldVar = class(TFieldVar)
  241. private
  242. FFieldVal: Int64;
  243. protected
  244. function GetFieldVal: Pointer; override;
  245. function GetFieldType: TExpressionType; override;
  246. public
  247. procedure Refresh(Buffer: PChar); override;
  248. end;
  249. {$endif}
  250. TDateTimeFieldVar = class(TFieldVar)
  251. private
  252. FFieldVal: TDateTimeRec;
  253. function GetFieldType: TExpressionType; override;
  254. protected
  255. function GetFieldVal: Pointer; override;
  256. public
  257. procedure Refresh(Buffer: PChar); override;
  258. end;
  259. TBooleanFieldVar = class(TFieldVar)
  260. private
  261. FFieldVal: boolean;
  262. function GetFieldType: TExpressionType; override;
  263. protected
  264. function GetFieldVal: Pointer; override;
  265. public
  266. procedure Refresh(Buffer: PChar); override;
  267. end;
  268. //--TFieldVar----------------------------------------------------------------
  269. constructor TFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  270. begin
  271. inherited Create;
  272. // store field
  273. FFieldDef := UseFieldDef;
  274. FDbfFile := ADbfFile;
  275. FFieldName := UseFieldDef.FieldName;
  276. end;
  277. //--TStringFieldVar-------------------------------------------------------------
  278. function TStringFieldVar.GetFieldVal: Pointer;
  279. begin
  280. Result := @FFieldVal;
  281. end;
  282. function TStringFieldVar.GetFieldType: TExpressionType;
  283. begin
  284. Result := etString;
  285. end;
  286. //--TRawStringFieldVar----------------------------------------------------------
  287. procedure TRawStringFieldVar.Refresh(Buffer: PChar);
  288. begin
  289. FFieldVal := Buffer + FieldDef.Offset;
  290. end;
  291. //--TAnsiStringFieldVar---------------------------------------------------------
  292. constructor TAnsiStringFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  293. begin
  294. inherited;
  295. GetMem(FFieldVal, UseFieldDef.Size+1);
  296. end;
  297. destructor TAnsiStringFieldVar.Destroy;
  298. begin
  299. FreeMem(FFieldVal);
  300. inherited;
  301. end;
  302. procedure TAnsiStringFieldVar.Refresh(Buffer: PChar);
  303. var
  304. Len: Integer;
  305. begin
  306. // copy field data
  307. Len := FieldDef.Size;
  308. Move(Buffer[FieldDef.Offset], FFieldVal[0], Len);
  309. // trim right side spaces by null-termination
  310. while (Len >= 1) and (FFieldVal[Len-1] = ' ') do Dec(Len);
  311. FFieldVal[Len] := #0;
  312. // translate to ANSI
  313. TranslateString(DbfFile.UseCodePage, GetACP, FFieldVal, FFieldVal, Len);
  314. end;
  315. //--TFloatFieldVar-----------------------------------------------------------
  316. function TFloatFieldVar.GetFieldVal: Pointer;
  317. begin
  318. Result := @FFieldVal;
  319. end;
  320. function TFloatFieldVar.GetFieldType: TExpressionType;
  321. begin
  322. Result := etFloat;
  323. end;
  324. procedure TFloatFieldVar.Refresh(Buffer: PChar);
  325. begin
  326. // database width is default 64-bit double
  327. if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
  328. FFieldVal := 0.0;
  329. end;
  330. //--TIntegerFieldVar----------------------------------------------------------
  331. function TIntegerFieldVar.GetFieldVal: Pointer;
  332. begin
  333. Result := @FFieldVal;
  334. end;
  335. function TIntegerFieldVar.GetFieldType: TExpressionType;
  336. begin
  337. Result := etInteger;
  338. end;
  339. procedure TIntegerFieldVar.Refresh(Buffer: PChar);
  340. begin
  341. FFieldVal := 0;
  342. FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal);
  343. end;
  344. {$ifdef SUPPORT_INT64}
  345. //--TLargeIntFieldVar----------------------------------------------------------
  346. function TLargeIntFieldVar.GetFieldVal: Pointer;
  347. begin
  348. Result := @FFieldVal;
  349. end;
  350. function TLargeIntFieldVar.GetFieldType: TExpressionType;
  351. begin
  352. Result := etLargeInt;
  353. end;
  354. procedure TLargeIntFieldVar.Refresh(Buffer: PChar);
  355. begin
  356. if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
  357. FFieldVal := 0;
  358. end;
  359. {$endif}
  360. //--TDateTimeFieldVar---------------------------------------------------------
  361. function TDateTimeFieldVar.GetFieldVal: Pointer;
  362. begin
  363. Result := @FFieldVal;
  364. end;
  365. function TDateTimeFieldVar.GetFieldType: TExpressionType;
  366. begin
  367. Result := etDateTime;
  368. end;
  369. procedure TDateTimeFieldVar.Refresh(Buffer: PChar);
  370. begin
  371. if not FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal) then
  372. FFieldVal.DateTime := 0.0;
  373. end;
  374. //--TBooleanFieldVar---------------------------------------------------------
  375. function TBooleanFieldVar.GetFieldVal: Pointer;
  376. begin
  377. Result := @FFieldVal;
  378. end;
  379. function TBooleanFieldVar.GetFieldType: TExpressionType;
  380. begin
  381. Result := etBoolean;
  382. end;
  383. procedure TBooleanFieldVar.Refresh(Buffer: PChar);
  384. var
  385. lFieldVal: word;
  386. begin
  387. if FDbfFile.GetFieldDataFromDef(FieldDef, ftBoolean, Buffer, @lFieldVal) then
  388. FFieldVal := lFieldVal <> 0
  389. else
  390. FFieldVal := false;
  391. end;
  392. //--Expression functions-----------------------------------------------------
  393. procedure FuncFloatToStr(Param: PExpressionRec);
  394. var
  395. width, numDigits, resWidth: Integer;
  396. extVal: Extended;
  397. begin
  398. with Param^ do
  399. begin
  400. // get params;
  401. numDigits := 0;
  402. if Args[1] <> nil then
  403. width := PInteger(Args[1])^
  404. else
  405. width := 18;
  406. if Args[2] <> nil then
  407. numDigits := PInteger(Args[2])^;
  408. // convert to string
  409. Res.AssureSpace(width);
  410. extVal := PDouble(Args[0])^;
  411. resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, 18, numDigits);
  412. // always use dot as decimal separator
  413. if numDigits > 0 then
  414. Res.MemoryPos^[resWidth-numDigits-1] := '.';
  415. // result width smaller than requested width? -> add space to compensate
  416. if (Args[1] <> nil) and (resWidth < width) then
  417. begin
  418. // move string so that it's right-aligned
  419. Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth);
  420. // fill gap with spaces
  421. FillChar(Res.MemoryPos^^, width-resWidth, ' ');
  422. // resWidth has been padded, update
  423. resWidth := width;
  424. end else if resWidth > width then begin
  425. // result width more than requested width, cut
  426. resWidth := width;
  427. end;
  428. // advance pointer
  429. Inc(Res.MemoryPos^, resWidth);
  430. // null-terminate
  431. Res.MemoryPos^^ := #0;
  432. end;
  433. end;
  434. procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: Integer);
  435. var
  436. width: Integer;
  437. begin
  438. with Param^ do
  439. begin
  440. // width specified?
  441. if Args[1] <> nil then
  442. begin
  443. // convert to string
  444. width := PInteger(Args[1])^;
  445. GetStrFromInt_Width(Val, width, Res.MemoryPos^, #32);
  446. // advance pointer
  447. Inc(Res.MemoryPos^, width);
  448. // need to add decimal?
  449. if Args[2] <> nil then
  450. begin
  451. // get number of digits
  452. width := PInteger(Args[2])^;
  453. // add decimal dot
  454. Res.MemoryPos^^ := '.';
  455. Inc(Res.MemoryPos^);
  456. // add zeroes
  457. FillChar(Res.MemoryPos^^, width, '0');
  458. // go to end
  459. Inc(Res.MemoryPos^, width);
  460. end;
  461. end else begin
  462. // convert to string
  463. width := GetStrFromInt(Val, Res.MemoryPos^);
  464. // advance pointer
  465. Inc(Param^.Res.MemoryPos^, width);
  466. end;
  467. // null-terminate
  468. Res.MemoryPos^^ := #0;
  469. end;
  470. end;
  471. procedure FuncIntToStr(Param: PExpressionRec);
  472. begin
  473. FuncIntToStr_Gen(Param, PInteger(Param^.Args[0])^);
  474. end;
  475. procedure FuncDateToStr(Param: PExpressionRec);
  476. var
  477. TempStr: string;
  478. begin
  479. with Param^ do
  480. begin
  481. // create in temporary string
  482. DateTimeToString(TempStr, 'yyyymmdd', PDateTimeRec(Args[0])^.DateTime);
  483. // copy to buffer
  484. Res.Append(PChar(TempStr), Length(TempStr));
  485. end;
  486. end;
  487. procedure FuncSubString(Param: PExpressionRec);
  488. var
  489. srcLen, index, count: Integer;
  490. begin
  491. with Param^ do
  492. begin
  493. srcLen := StrLen(Args[0]);
  494. index := PInteger(Args[1])^ - 1;
  495. count := PInteger(Args[2])^;
  496. if index + count <= srcLen then
  497. Res.Append(Args[0]+index, count)
  498. else
  499. Res.MemoryPos^^ := #0;
  500. end;
  501. end;
  502. procedure FuncUppercase(Param: PExpressionRec);
  503. var
  504. dest: PChar;
  505. begin
  506. with Param^ do
  507. begin
  508. // first copy
  509. dest := (Res.MemoryPos)^;
  510. Res.Append(Args[0], StrLen(Args[0]));
  511. // make uppercase
  512. AnsiStrUpper(dest);
  513. end;
  514. end;
  515. procedure FuncLowercase(Param: PExpressionRec);
  516. var
  517. dest: PChar;
  518. begin
  519. with Param^ do
  520. begin
  521. // first copy
  522. dest := (Res.MemoryPos)^;
  523. Res.Append(Args[0], StrLen(Args[0]));
  524. // make lowercase
  525. AnsiStrLower(dest);
  526. end;
  527. end;
  528. procedure FuncAdd_F_FF(Param: PExpressionRec);
  529. begin
  530. with Param^ do
  531. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^;
  532. end;
  533. procedure FuncAdd_F_FI(Param: PExpressionRec);
  534. begin
  535. with Param^ do
  536. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^;
  537. end;
  538. procedure FuncAdd_F_II(Param: PExpressionRec);
  539. begin
  540. with Param^ do
  541. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^;
  542. end;
  543. procedure FuncAdd_F_IF(Param: PExpressionRec);
  544. begin
  545. with Param^ do
  546. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^;
  547. end;
  548. {$ifdef SUPPORT_INT64}
  549. procedure FuncAdd_F_FL(Param: PExpressionRec);
  550. begin
  551. with Param^ do
  552. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^;
  553. end;
  554. procedure FuncAdd_F_IL(Param: PExpressionRec);
  555. begin
  556. with Param^ do
  557. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^;
  558. end;
  559. procedure FuncAdd_F_LL(Param: PExpressionRec);
  560. begin
  561. with Param^ do
  562. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^;
  563. end;
  564. procedure FuncAdd_F_LF(Param: PExpressionRec);
  565. begin
  566. with Param^ do
  567. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^;
  568. end;
  569. procedure FuncAdd_F_LI(Param: PExpressionRec);
  570. begin
  571. with Param^ do
  572. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^;
  573. end;
  574. {$endif}
  575. procedure FuncSub_F_FF(Param: PExpressionRec);
  576. begin
  577. with Param^ do
  578. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^;
  579. end;
  580. procedure FuncSub_F_FI(Param: PExpressionRec);
  581. begin
  582. with Param^ do
  583. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^;
  584. end;
  585. procedure FuncSub_F_II(Param: PExpressionRec);
  586. begin
  587. with Param^ do
  588. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^;
  589. end;
  590. procedure FuncSub_F_IF(Param: PExpressionRec);
  591. begin
  592. with Param^ do
  593. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^;
  594. end;
  595. {$ifdef SUPPORT_INT64}
  596. procedure FuncSub_F_FL(Param: PExpressionRec);
  597. begin
  598. with Param^ do
  599. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^;
  600. end;
  601. procedure FuncSub_F_IL(Param: PExpressionRec);
  602. begin
  603. with Param^ do
  604. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^;
  605. end;
  606. procedure FuncSub_F_LL(Param: PExpressionRec);
  607. begin
  608. with Param^ do
  609. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^;
  610. end;
  611. procedure FuncSub_F_LF(Param: PExpressionRec);
  612. begin
  613. with Param^ do
  614. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^;
  615. end;
  616. procedure FuncSub_F_LI(Param: PExpressionRec);
  617. begin
  618. with Param^ do
  619. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^;
  620. end;
  621. {$endif}
  622. procedure FuncMul_F_FF(Param: PExpressionRec);
  623. begin
  624. with Param^ do
  625. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^;
  626. end;
  627. procedure FuncMul_F_FI(Param: PExpressionRec);
  628. begin
  629. with Param^ do
  630. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^;
  631. end;
  632. procedure FuncMul_F_II(Param: PExpressionRec);
  633. begin
  634. with Param^ do
  635. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^;
  636. end;
  637. procedure FuncMul_F_IF(Param: PExpressionRec);
  638. begin
  639. with Param^ do
  640. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^;
  641. end;
  642. {$ifdef SUPPORT_INT64}
  643. procedure FuncMul_F_FL(Param: PExpressionRec);
  644. begin
  645. with Param^ do
  646. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^;
  647. end;
  648. procedure FuncMul_F_IL(Param: PExpressionRec);
  649. begin
  650. with Param^ do
  651. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^;
  652. end;
  653. procedure FuncMul_F_LL(Param: PExpressionRec);
  654. begin
  655. with Param^ do
  656. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^;
  657. end;
  658. procedure FuncMul_F_LF(Param: PExpressionRec);
  659. begin
  660. with Param^ do
  661. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^;
  662. end;
  663. procedure FuncMul_F_LI(Param: PExpressionRec);
  664. begin
  665. with Param^ do
  666. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^;
  667. end;
  668. {$endif}
  669. procedure FuncDiv_F_FF(Param: PExpressionRec);
  670. begin
  671. with Param^ do
  672. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^;
  673. end;
  674. procedure FuncDiv_F_FI(Param: PExpressionRec);
  675. begin
  676. with Param^ do
  677. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^;
  678. end;
  679. procedure FuncDiv_F_II(Param: PExpressionRec);
  680. begin
  681. with Param^ do
  682. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^;
  683. end;
  684. procedure FuncDiv_F_IF(Param: PExpressionRec);
  685. begin
  686. with Param^ do
  687. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^;
  688. end;
  689. {$ifdef SUPPORT_INT64}
  690. procedure FuncDiv_F_FL(Param: PExpressionRec);
  691. begin
  692. with Param^ do
  693. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^;
  694. end;
  695. procedure FuncDiv_F_IL(Param: PExpressionRec);
  696. begin
  697. with Param^ do
  698. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^;
  699. end;
  700. procedure FuncDiv_F_LL(Param: PExpressionRec);
  701. begin
  702. with Param^ do
  703. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^;
  704. end;
  705. procedure FuncDiv_F_LF(Param: PExpressionRec);
  706. begin
  707. with Param^ do
  708. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^;
  709. end;
  710. procedure FuncDiv_F_LI(Param: PExpressionRec);
  711. begin
  712. with Param^ do
  713. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^;
  714. end;
  715. {$endif}
  716. procedure FuncStrI_EQ(Param: PExpressionRec);
  717. begin
  718. with Param^ do
  719. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0);
  720. end;
  721. procedure FuncStrIP_EQ(Param: PExpressionRec);
  722. var
  723. arg0len, arg1len: integer;
  724. match: boolean;
  725. str0, str1: string;
  726. begin
  727. with Param^ do
  728. begin
  729. arg1len := StrLen(Args[1]);
  730. if Args[1][0] = '*' then
  731. begin
  732. if Args[1][arg1len-1] = '*' then
  733. begin
  734. str0 := AnsiStrUpper(Args[0]);
  735. str1 := AnsiStrUpper(Args[1]+1);
  736. setlength(str1, arg1len-2);
  737. match := AnsiPos(str0, str1) = 0;
  738. end else begin
  739. arg0len := StrLen(Args[0]);
  740. // at least length without asterisk
  741. match := arg0len >= arg1len - 1;
  742. if match then
  743. match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
  744. end;
  745. end else
  746. if Args[1][arg1len-1] = '*' then
  747. begin
  748. arg0len := StrLen(Args[0]);
  749. match := arg1len >= arg0len - 1;
  750. if match then
  751. match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0;
  752. end else begin
  753. match := AnsiStrIComp(Args[0], Args[1]) = 0;
  754. end;
  755. Res.MemoryPos^^ := Char(match);
  756. end;
  757. end;
  758. procedure FuncStrI_NEQ(Param: PExpressionRec);
  759. begin
  760. with Param^ do
  761. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0);
  762. end;
  763. procedure FuncStrI_LT(Param: PExpressionRec);
  764. begin
  765. with Param^ do
  766. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0);
  767. end;
  768. procedure FuncStrI_GT(Param: PExpressionRec);
  769. begin
  770. with Param^ do
  771. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0);
  772. end;
  773. procedure FuncStrI_LTE(Param: PExpressionRec);
  774. begin
  775. with Param^ do
  776. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0);
  777. end;
  778. procedure FuncStrI_GTE(Param: PExpressionRec);
  779. begin
  780. with Param^ do
  781. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0);
  782. end;
  783. procedure FuncStrP_EQ(Param: PExpressionRec);
  784. var
  785. arg0len, arg1len: integer;
  786. match: boolean;
  787. begin
  788. with Param^ do
  789. begin
  790. arg1len := StrLen(Args[1]);
  791. if Args[1][0] = '*' then
  792. begin
  793. if Args[1][arg1len-1] = '*' then
  794. begin
  795. Args[1][arg1len-1] := #0;
  796. match := AnsiStrPos(Args[0], Args[1]+1) <> nil;
  797. Args[1][arg1len-1] := '*';
  798. end else begin
  799. arg0len := StrLen(Args[0]);
  800. // at least length without asterisk
  801. match := arg0len >= arg1len - 1;
  802. if match then
  803. match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
  804. end;
  805. end else
  806. if Args[1][arg1len-1] = '*' then
  807. begin
  808. arg0len := StrLen(Args[0]);
  809. match := arg1len >= arg0len - 1;
  810. if match then
  811. match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0;
  812. end else begin
  813. match := AnsiStrComp(Args[0], Args[1]) = 0;
  814. end;
  815. Res.MemoryPos^^ := Char(match);
  816. end;
  817. end;
  818. procedure FuncStr_EQ(Param: PExpressionRec);
  819. begin
  820. with Param^ do
  821. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0);
  822. end;
  823. procedure FuncStr_NEQ(Param: PExpressionRec);
  824. begin
  825. with Param^ do
  826. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0);
  827. end;
  828. procedure FuncStr_LT(Param: PExpressionRec);
  829. begin
  830. with Param^ do
  831. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0);
  832. end;
  833. procedure FuncStr_GT(Param: PExpressionRec);
  834. begin
  835. with Param^ do
  836. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0);
  837. end;
  838. procedure FuncStr_LTE(Param: PExpressionRec);
  839. begin
  840. with Param^ do
  841. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0);
  842. end;
  843. procedure FuncStr_GTE(Param: PExpressionRec);
  844. begin
  845. with Param^ do
  846. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0);
  847. end;
  848. procedure Func_FF_EQ(Param: PExpressionRec);
  849. begin
  850. with Param^ do
  851. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^);
  852. end;
  853. procedure Func_FF_NEQ(Param: PExpressionRec);
  854. begin
  855. with Param^ do
  856. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^);
  857. end;
  858. procedure Func_FF_LT(Param: PExpressionRec);
  859. begin
  860. with Param^ do
  861. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^);
  862. end;
  863. procedure Func_FF_GT(Param: PExpressionRec);
  864. begin
  865. with Param^ do
  866. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^);
  867. end;
  868. procedure Func_FF_LTE(Param: PExpressionRec);
  869. begin
  870. with Param^ do
  871. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^);
  872. end;
  873. procedure Func_FF_GTE(Param: PExpressionRec);
  874. begin
  875. with Param^ do
  876. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^);
  877. end;
  878. procedure Func_FI_EQ(Param: PExpressionRec);
  879. begin
  880. with Param^ do
  881. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^);
  882. end;
  883. procedure Func_FI_NEQ(Param: PExpressionRec);
  884. begin
  885. with Param^ do
  886. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^);
  887. end;
  888. procedure Func_FI_LT(Param: PExpressionRec);
  889. begin
  890. with Param^ do
  891. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^);
  892. end;
  893. procedure Func_FI_GT(Param: PExpressionRec);
  894. begin
  895. with Param^ do
  896. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^);
  897. end;
  898. procedure Func_FI_LTE(Param: PExpressionRec);
  899. begin
  900. with Param^ do
  901. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^);
  902. end;
  903. procedure Func_FI_GTE(Param: PExpressionRec);
  904. begin
  905. with Param^ do
  906. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^);
  907. end;
  908. procedure Func_II_EQ(Param: PExpressionRec);
  909. begin
  910. with Param^ do
  911. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^);
  912. end;
  913. procedure Func_II_NEQ(Param: PExpressionRec);
  914. begin
  915. with Param^ do
  916. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^);
  917. end;
  918. procedure Func_II_LT(Param: PExpressionRec);
  919. begin
  920. with Param^ do
  921. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^);
  922. end;
  923. procedure Func_II_GT(Param: PExpressionRec);
  924. begin
  925. with Param^ do
  926. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^);
  927. end;
  928. procedure Func_II_LTE(Param: PExpressionRec);
  929. begin
  930. with Param^ do
  931. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^);
  932. end;
  933. procedure Func_II_GTE(Param: PExpressionRec);
  934. begin
  935. with Param^ do
  936. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^);
  937. end;
  938. procedure Func_IF_EQ(Param: PExpressionRec);
  939. begin
  940. with Param^ do
  941. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^);
  942. end;
  943. procedure Func_IF_NEQ(Param: PExpressionRec);
  944. begin
  945. with Param^ do
  946. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^);
  947. end;
  948. procedure Func_IF_LT(Param: PExpressionRec);
  949. begin
  950. with Param^ do
  951. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^);
  952. end;
  953. procedure Func_IF_GT(Param: PExpressionRec);
  954. begin
  955. with Param^ do
  956. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^);
  957. end;
  958. procedure Func_IF_LTE(Param: PExpressionRec);
  959. begin
  960. with Param^ do
  961. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^);
  962. end;
  963. procedure Func_IF_GTE(Param: PExpressionRec);
  964. begin
  965. with Param^ do
  966. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^);
  967. end;
  968. {$ifdef SUPPORT_INT64}
  969. procedure Func_LL_EQ(Param: PExpressionRec);
  970. begin
  971. with Param^ do
  972. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^);
  973. end;
  974. procedure Func_LL_NEQ(Param: PExpressionRec);
  975. begin
  976. with Param^ do
  977. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^);
  978. end;
  979. procedure Func_LL_LT(Param: PExpressionRec);
  980. begin
  981. with Param^ do
  982. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^);
  983. end;
  984. procedure Func_LL_GT(Param: PExpressionRec);
  985. begin
  986. with Param^ do
  987. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^);
  988. end;
  989. procedure Func_LL_LTE(Param: PExpressionRec);
  990. begin
  991. with Param^ do
  992. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^);
  993. end;
  994. procedure Func_LL_GTE(Param: PExpressionRec);
  995. begin
  996. with Param^ do
  997. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^);
  998. end;
  999. procedure Func_LF_EQ(Param: PExpressionRec);
  1000. begin
  1001. with Param^ do
  1002. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^);
  1003. end;
  1004. procedure Func_LF_NEQ(Param: PExpressionRec);
  1005. begin
  1006. with Param^ do
  1007. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^);
  1008. end;
  1009. procedure Func_LF_LT(Param: PExpressionRec);
  1010. begin
  1011. with Param^ do
  1012. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^);
  1013. end;
  1014. procedure Func_LF_GT(Param: PExpressionRec);
  1015. begin
  1016. with Param^ do
  1017. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^);
  1018. end;
  1019. procedure Func_LF_LTE(Param: PExpressionRec);
  1020. begin
  1021. with Param^ do
  1022. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^);
  1023. end;
  1024. procedure Func_LF_GTE(Param: PExpressionRec);
  1025. begin
  1026. with Param^ do
  1027. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^);
  1028. end;
  1029. procedure Func_FL_EQ(Param: PExpressionRec);
  1030. begin
  1031. with Param^ do
  1032. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^);
  1033. end;
  1034. procedure Func_FL_NEQ(Param: PExpressionRec);
  1035. begin
  1036. with Param^ do
  1037. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^);
  1038. end;
  1039. procedure Func_FL_LT(Param: PExpressionRec);
  1040. begin
  1041. with Param^ do
  1042. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^);
  1043. end;
  1044. procedure Func_FL_GT(Param: PExpressionRec);
  1045. begin
  1046. with Param^ do
  1047. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^);
  1048. end;
  1049. procedure Func_FL_LTE(Param: PExpressionRec);
  1050. begin
  1051. with Param^ do
  1052. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^);
  1053. end;
  1054. procedure Func_FL_GTE(Param: PExpressionRec);
  1055. begin
  1056. with Param^ do
  1057. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^);
  1058. end;
  1059. procedure Func_LI_EQ(Param: PExpressionRec);
  1060. begin
  1061. with Param^ do
  1062. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^);
  1063. end;
  1064. procedure Func_LI_NEQ(Param: PExpressionRec);
  1065. begin
  1066. with Param^ do
  1067. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^);
  1068. end;
  1069. procedure Func_LI_LT(Param: PExpressionRec);
  1070. begin
  1071. with Param^ do
  1072. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^);
  1073. end;
  1074. procedure Func_LI_GT(Param: PExpressionRec);
  1075. begin
  1076. with Param^ do
  1077. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^);
  1078. end;
  1079. procedure Func_LI_LTE(Param: PExpressionRec);
  1080. begin
  1081. with Param^ do
  1082. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^);
  1083. end;
  1084. procedure Func_LI_GTE(Param: PExpressionRec);
  1085. begin
  1086. with Param^ do
  1087. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^);
  1088. end;
  1089. procedure Func_IL_EQ(Param: PExpressionRec);
  1090. begin
  1091. with Param^ do
  1092. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^);
  1093. end;
  1094. procedure Func_IL_NEQ(Param: PExpressionRec);
  1095. begin
  1096. with Param^ do
  1097. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^);
  1098. end;
  1099. procedure Func_IL_LT(Param: PExpressionRec);
  1100. begin
  1101. with Param^ do
  1102. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^);
  1103. end;
  1104. procedure Func_IL_GT(Param: PExpressionRec);
  1105. begin
  1106. with Param^ do
  1107. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^);
  1108. end;
  1109. procedure Func_IL_LTE(Param: PExpressionRec);
  1110. begin
  1111. with Param^ do
  1112. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^);
  1113. end;
  1114. procedure Func_IL_GTE(Param: PExpressionRec);
  1115. begin
  1116. with Param^ do
  1117. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^);
  1118. end;
  1119. {$endif}
  1120. procedure Func_AND(Param: PExpressionRec);
  1121. begin
  1122. with Param^ do
  1123. Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^));
  1124. end;
  1125. procedure Func_OR(Param: PExpressionRec);
  1126. begin
  1127. with Param^ do
  1128. Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^));
  1129. end;
  1130. procedure Func_NOT(Param: PExpressionRec);
  1131. begin
  1132. with Param^ do
  1133. Res.MemoryPos^^ := Char(not Boolean(Args[0]^));
  1134. end;
  1135. //--TDbfParser---------------------------------------------------------------
  1136. var
  1137. DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TExpressList;
  1138. DbfWordsSensPartialList, DbfWordsInsensPartialList: TExpressList;
  1139. DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TExpressList;
  1140. DbfWordsGeneralList: TExpressList;
  1141. constructor TDbfParser.Create(ADbfFile: Pointer);
  1142. begin
  1143. FDbfFile := ADbfFile;
  1144. FFieldVarList := TStringList.Create;
  1145. FCaseInsensitive := true;
  1146. FRawStringFields := true;
  1147. inherited Create;
  1148. end;
  1149. destructor TDbfParser.Destroy;
  1150. begin
  1151. ClearExpressions;
  1152. inherited;
  1153. FreeAndNil(FFieldVarList);
  1154. end;
  1155. function TDbfParser.GetResultType: TExpressionType;
  1156. begin
  1157. // if not a real expression, return type ourself
  1158. if FIsExpression then
  1159. Result := inherited GetResultType
  1160. else
  1161. Result := FFieldType;
  1162. end;
  1163. procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean);
  1164. begin
  1165. if FCaseInsensitive <> NewInsensitive then
  1166. begin
  1167. // clear and regenerate functions
  1168. FCaseInsensitive := NewInsensitive;
  1169. FillExpressList;
  1170. if Length(Expression) > 0 then
  1171. ParseExpression(Expression);
  1172. end;
  1173. end;
  1174. procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean);
  1175. begin
  1176. if FPartialMatch <> NewPartialMatch then
  1177. begin
  1178. // refill function list
  1179. FPartialMatch := NewPartialMatch;
  1180. FillExpressList;
  1181. if Length(Expression) > 0 then
  1182. ParseExpression(Expression);
  1183. end;
  1184. end;
  1185. procedure TDbfParser.SetRawStringFields(NewRawFields: Boolean);
  1186. begin
  1187. if FRawStringFields <> NewRawFields then
  1188. begin
  1189. // clear and regenerate functions, custom fields will be deleted too
  1190. FRawStringFields := NewRawFields;
  1191. if Length(Expression) > 0 then
  1192. ParseExpression(Expression);
  1193. end;
  1194. end;
  1195. procedure TDbfParser.FillExpressList;
  1196. begin
  1197. FWordsList.FreeAll;
  1198. FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1);
  1199. if FCaseInsensitive then
  1200. begin
  1201. FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1);
  1202. if FPartialMatch then
  1203. begin
  1204. FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1);
  1205. end else begin
  1206. FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1);
  1207. end;
  1208. end else begin
  1209. FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1);
  1210. if FPartialMatch then
  1211. begin
  1212. FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1);
  1213. end else begin
  1214. FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1);
  1215. end;
  1216. end;
  1217. end;
  1218. function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef;
  1219. begin
  1220. Result := TDbfFile(FDbfFile).GetFieldInfo(VarName);
  1221. end;
  1222. procedure TDbfParser.HandleUnknownVariable(VarName: string);
  1223. var
  1224. FieldInfo: TDbfFieldDef;
  1225. TempFieldVar: TFieldVar;
  1226. begin
  1227. // is this variable a fieldname?
  1228. FieldInfo := GetVariableInfo(VarName);
  1229. if FieldInfo = nil then
  1230. raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]);
  1231. // define field in parser
  1232. case FieldInfo.FieldType of
  1233. ftString:
  1234. begin
  1235. if RawStringFields then
  1236. begin
  1237. { raw string fields have fixed length, not null-terminated }
  1238. TempFieldVar := TRawStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1239. DefineStringVariableFixedLen(VarName, TempFieldVar.FieldVal, FieldInfo.Size);
  1240. end else begin
  1241. { ansi string field function translates and null-terminates field value }
  1242. TempFieldVar := TAnsiStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1243. DefineStringVariable(VarName, TempFieldVar.FieldVal);
  1244. end;
  1245. end;
  1246. ftBoolean:
  1247. begin
  1248. TempFieldVar := TBooleanFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1249. DefineBooleanVariable(VarName, TempFieldVar.FieldVal);
  1250. end;
  1251. ftFloat:
  1252. begin
  1253. TempFieldVar := TFloatFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1254. DefineFloatVariable(VarName, TempFieldVar.FieldVal);
  1255. end;
  1256. ftAutoInc, ftInteger, ftSmallInt:
  1257. begin
  1258. TempFieldVar := TIntegerFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1259. DefineIntegerVariable(VarName, TempFieldVar.FieldVal);
  1260. end;
  1261. {
  1262. ftSmallInt:
  1263. begin
  1264. TempFieldVar := TSmallIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1265. DefineSmallIntVariable(VarName, TempFieldVar.FieldVal);
  1266. end;
  1267. }
  1268. {$ifdef SUPPORT_INT64}
  1269. ftLargeInt:
  1270. begin
  1271. TempFieldVar := TLargeIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1272. DefineLargeIntVariable(VarName, TempFieldVar.FieldVal);
  1273. end;
  1274. {$endif}
  1275. ftDate, ftDateTime:
  1276. begin
  1277. TempFieldVar := TDateTimeFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1278. DefineDateTimeVariable(VarName, TempFieldVar.FieldVal);
  1279. end;
  1280. else
  1281. raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_INVALID_FIELD, [VarName]);
  1282. end;
  1283. // add to our own list
  1284. FFieldVarList.AddObject(VarName, TempFieldVar);
  1285. end;
  1286. function TDbfParser.CurrentExpression: string;
  1287. begin
  1288. Result := FCurrentExpression;
  1289. end;
  1290. procedure TDbfParser.ClearExpressions;
  1291. var
  1292. I: Integer;
  1293. begin
  1294. inherited;
  1295. // test if already freed
  1296. if FFieldVarList <> nil then
  1297. begin
  1298. // free field list
  1299. for I := 0 to FFieldVarList.Count - 1 do
  1300. begin
  1301. // replacing with nil = undefining variable
  1302. ReplaceFunction(TFieldVar(FFieldVarList.Objects[I]).FieldName, nil);
  1303. TFieldVar(FFieldVarList.Objects[I]).Free;
  1304. end;
  1305. FFieldVarList.Clear;
  1306. end;
  1307. // clear expression
  1308. FCurrentExpression := EmptyStr;
  1309. end;
  1310. procedure TDbfParser.ParseExpression(Expression: string);
  1311. var
  1312. TempBuffer: array[0..4000] of Char;
  1313. begin
  1314. // clear any current expression
  1315. ClearExpressions;
  1316. // is this a simple field or complex expression?
  1317. FIsExpression := GetVariableInfo(Expression) = nil;
  1318. if FIsExpression then
  1319. begin
  1320. // parse requested
  1321. CompileExpression(Expression);
  1322. // determine length of string length expressions
  1323. if ResultType = etString then
  1324. begin
  1325. // make empty record
  1326. TDbfFile(FDbfFile).InitRecord(@TempBuffer[0]);
  1327. FResultLen := StrLen(ExtractFromBuffer(@TempBuffer[0]));
  1328. end;
  1329. end else begin
  1330. // simple field, create field variable for it
  1331. HandleUnknownVariable(Expression);
  1332. FFieldType := TFieldVar(FFieldVarList.Objects[0]).FieldType;
  1333. // set result len of variable length fields
  1334. if FFieldType = etString then
  1335. FResultLen := TFieldVar(FFieldVarList.Objects[0]).FieldDef.Size
  1336. end;
  1337. // set result len for fixed length expressions / fields
  1338. case ResultType of
  1339. etBoolean: FResultLen := 1;
  1340. etInteger: FResultLen := 4;
  1341. etFloat: FResultLen := 8;
  1342. etDateTime: FResultLen := 8;
  1343. end;
  1344. // check if expression not too long
  1345. if FResultLen > 100 then
  1346. raise EDbfError.CreateFmt(STRING_INDEX_EXPRESSION_TOO_LONG, [Expression, FResultLen]);
  1347. // if no errors, assign current expression
  1348. FCurrentExpression := Expression;
  1349. end;
  1350. function TDbfParser.ExtractFromBuffer(Buffer: PChar): PChar;
  1351. var
  1352. I: Integer;
  1353. begin
  1354. // prepare all field variables
  1355. for I := 0 to FFieldVarList.Count - 1 do
  1356. TFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer);
  1357. // complex expression?
  1358. if FIsExpression then
  1359. begin
  1360. // execute expression
  1361. EvaluateCurrent;
  1362. Result := ExpResult;
  1363. end else begin
  1364. // simple field, get field result
  1365. Result := TFieldVar(FFieldVarList.Objects[0]).FieldVal;
  1366. // if string then dereference
  1367. if FFieldType = etString then
  1368. Result := PPChar(Result)^;
  1369. end;
  1370. end;
  1371. initialization
  1372. DbfWordsGeneralList := TExpressList.Create;
  1373. DbfWordsInsensGeneralList := TExpressList.Create;
  1374. DbfWordsInsensNoPartialList := TExpressList.Create;
  1375. DbfWordsInsensPartialList := TExpressList.Create;
  1376. DbfWordsSensGeneralList := TExpressList.Create;
  1377. DbfWordsSensNoPartialList := TExpressList.Create;
  1378. DbfWordsSensPartialList := TExpressList.Create;
  1379. with DbfWordsGeneralList do
  1380. begin
  1381. // basic function functionality
  1382. Add(TLeftBracket.Create('(', nil));
  1383. Add(TRightBracket.Create(')', nil));
  1384. Add(TComma.Create(',', nil));
  1385. // operators - name, param types, result type, func addr, precedence
  1386. Add(TFunction.CreateOper('+', 'SS', etString, nil, 40));
  1387. Add(TFunction.CreateOper('+', 'FF', etFloat, FuncAdd_F_FF, 40));
  1388. Add(TFunction.CreateOper('+', 'FI', etFloat, FuncAdd_F_FI, 40));
  1389. Add(TFunction.CreateOper('+', 'IF', etFloat, FuncAdd_F_IF, 40));
  1390. Add(TFunction.CreateOper('+', 'II', etInteger, FuncAdd_F_II, 40));
  1391. {$ifdef SUPPORT_INT64}
  1392. Add(TFunction.CreateOper('+', 'FL', etFloat, FuncAdd_F_FL, 40));
  1393. Add(TFunction.CreateOper('+', 'IL', etLargeInt, FuncAdd_F_IL, 40));
  1394. Add(TFunction.CreateOper('+', 'LF', etFloat, FuncAdd_F_LF, 40));
  1395. Add(TFunction.CreateOper('+', 'LL', etLargeInt, FuncAdd_F_LI, 40));
  1396. Add(TFunction.CreateOper('+', 'LI', etLargeInt, FuncAdd_F_LL, 40));
  1397. {$endif}
  1398. Add(TFunction.CreateOper('-', 'FF', etFloat, FuncSub_F_FF, 40));
  1399. Add(TFunction.CreateOper('-', 'FI', etFloat, FuncSub_F_FI, 40));
  1400. Add(TFunction.CreateOper('-', 'IF', etFloat, FuncSub_F_IF, 40));
  1401. Add(TFunction.CreateOper('-', 'II', etInteger, FuncSub_F_II, 40));
  1402. {$ifdef SUPPORT_INT64}
  1403. Add(TFunction.CreateOper('-', 'FL', etFloat, FuncSub_F_FL, 40));
  1404. Add(TFunction.CreateOper('-', 'IL', etLargeInt, FuncSub_F_IL, 40));
  1405. Add(TFunction.CreateOper('-', 'LF', etFloat, FuncSub_F_LF, 40));
  1406. Add(TFunction.CreateOper('-', 'LL', etLargeInt, FuncSub_F_LI, 40));
  1407. Add(TFunction.CreateOper('-', 'LI', etLargeInt, FuncSub_F_LL, 40));
  1408. {$endif}
  1409. Add(TFunction.CreateOper('*', 'FF', etFloat, FuncMul_F_FF, 40));
  1410. Add(TFunction.CreateOper('*', 'FI', etFloat, FuncMul_F_FI, 40));
  1411. Add(TFunction.CreateOper('*', 'IF', etFloat, FuncMul_F_IF, 40));
  1412. Add(TFunction.CreateOper('*', 'II', etInteger, FuncMul_F_II, 40));
  1413. {$ifdef SUPPORT_INT64}
  1414. Add(TFunction.CreateOper('*', 'FL', etFloat, FuncMul_F_FL, 40));
  1415. Add(TFunction.CreateOper('*', 'IL', etLargeInt, FuncMul_F_IL, 40));
  1416. Add(TFunction.CreateOper('*', 'LF', etFloat, FuncMul_F_LF, 40));
  1417. Add(TFunction.CreateOper('*', 'LL', etLargeInt, FuncMul_F_LI, 40));
  1418. Add(TFunction.CreateOper('*', 'LI', etLargeInt, FuncMul_F_LL, 40));
  1419. {$endif}
  1420. Add(TFunction.CreateOper('/', 'FF', etFloat, FuncDiv_F_FF, 40));
  1421. Add(TFunction.CreateOper('/', 'FI', etFloat, FuncDiv_F_FI, 40));
  1422. Add(TFunction.CreateOper('/', 'IF', etFloat, FuncDiv_F_IF, 40));
  1423. Add(TFunction.CreateOper('/', 'II', etInteger, FuncDiv_F_II, 40));
  1424. {$ifdef SUPPORT_INT64}
  1425. Add(TFunction.CreateOper('/', 'FL', etFloat, FuncDiv_F_FL, 40));
  1426. Add(TFunction.CreateOper('/', 'IL', etLargeInt, FuncDiv_F_IL, 40));
  1427. Add(TFunction.CreateOper('/', 'LF', etFloat, FuncDiv_F_LF, 40));
  1428. Add(TFunction.CreateOper('/', 'LL', etLargeInt, FuncDiv_F_LI, 40));
  1429. Add(TFunction.CreateOper('/', 'LI', etLargeInt, FuncDiv_F_LL, 40));
  1430. {$endif}
  1431. Add(TFunction.CreateOper('=', 'FF', etBoolean, Func_FF_EQ , 80));
  1432. Add(TFunction.CreateOper('<', 'FF', etBoolean, Func_FF_LT , 80));
  1433. Add(TFunction.CreateOper('>', 'FF', etBoolean, Func_FF_GT , 80));
  1434. Add(TFunction.CreateOper('<=','FF', etBoolean, Func_FF_LTE, 80));
  1435. Add(TFunction.CreateOper('>=','FF', etBoolean, Func_FF_GTE, 80));
  1436. Add(TFunction.CreateOper('<>','FF', etBoolean, Func_FF_NEQ, 80));
  1437. Add(TFunction.CreateOper('=', 'FI', etBoolean, Func_FI_EQ , 80));
  1438. Add(TFunction.CreateOper('<', 'FI', etBoolean, Func_FI_LT , 80));
  1439. Add(TFunction.CreateOper('>', 'FI', etBoolean, Func_FI_GT , 80));
  1440. Add(TFunction.CreateOper('<=','FI', etBoolean, Func_FI_LTE, 80));
  1441. Add(TFunction.CreateOper('>=','FI', etBoolean, Func_FI_GTE, 80));
  1442. Add(TFunction.CreateOper('<>','FI', etBoolean, Func_FI_NEQ, 80));
  1443. Add(TFunction.CreateOper('=', 'II', etBoolean, Func_II_EQ , 80));
  1444. Add(TFunction.CreateOper('<', 'II', etBoolean, Func_II_LT , 80));
  1445. Add(TFunction.CreateOper('>', 'II', etBoolean, Func_II_GT , 80));
  1446. Add(TFunction.CreateOper('<=','II', etBoolean, Func_II_LTE, 80));
  1447. Add(TFunction.CreateOper('>=','II', etBoolean, Func_II_GTE, 80));
  1448. Add(TFunction.CreateOper('<>','II', etBoolean, Func_II_NEQ, 80));
  1449. Add(TFunction.CreateOper('=', 'IF', etBoolean, Func_IF_EQ , 80));
  1450. Add(TFunction.CreateOper('<', 'IF', etBoolean, Func_IF_LT , 80));
  1451. Add(TFunction.CreateOper('>', 'IF', etBoolean, Func_IF_GT , 80));
  1452. Add(TFunction.CreateOper('<=','IF', etBoolean, Func_IF_LTE, 80));
  1453. Add(TFunction.CreateOper('>=','IF', etBoolean, Func_IF_GTE, 80));
  1454. Add(TFunction.CreateOper('<>','IF', etBoolean, Func_IF_NEQ, 80));
  1455. {$ifdef SUPPORT_INT64}
  1456. Add(TFunction.CreateOper('=', 'LL', etBoolean, Func_LL_EQ , 80));
  1457. Add(TFunction.CreateOper('<', 'LL', etBoolean, Func_LL_LT , 80));
  1458. Add(TFunction.CreateOper('>', 'LL', etBoolean, Func_LL_GT , 80));
  1459. Add(TFunction.CreateOper('<=','LL', etBoolean, Func_LL_LTE, 80));
  1460. Add(TFunction.CreateOper('>=','LL', etBoolean, Func_LL_GTE, 80));
  1461. Add(TFunction.CreateOper('<>','LL', etBoolean, Func_LL_NEQ, 80));
  1462. Add(TFunction.CreateOper('=', 'LF', etBoolean, Func_LF_EQ , 80));
  1463. Add(TFunction.CreateOper('<', 'LF', etBoolean, Func_LF_LT , 80));
  1464. Add(TFunction.CreateOper('>', 'LF', etBoolean, Func_LF_GT , 80));
  1465. Add(TFunction.CreateOper('<=','LF', etBoolean, Func_LF_LTE, 80));
  1466. Add(TFunction.CreateOper('>=','LF', etBoolean, Func_LF_GTE, 80));
  1467. Add(TFunction.CreateOper('<>','FI', etBoolean, Func_LF_NEQ, 80));
  1468. Add(TFunction.CreateOper('=', 'LI', etBoolean, Func_LI_EQ , 80));
  1469. Add(TFunction.CreateOper('<', 'LI', etBoolean, Func_LI_LT , 80));
  1470. Add(TFunction.CreateOper('>', 'LI', etBoolean, Func_LI_GT , 80));
  1471. Add(TFunction.CreateOper('<=','LI', etBoolean, Func_LI_LTE, 80));
  1472. Add(TFunction.CreateOper('>=','LI', etBoolean, Func_LI_GTE, 80));
  1473. Add(TFunction.CreateOper('<>','LI', etBoolean, Func_LI_NEQ, 80));
  1474. Add(TFunction.CreateOper('=', 'FL', etBoolean, Func_FL_EQ , 80));
  1475. Add(TFunction.CreateOper('<', 'FL', etBoolean, Func_FL_LT , 80));
  1476. Add(TFunction.CreateOper('>', 'FL', etBoolean, Func_FL_GT , 80));
  1477. Add(TFunction.CreateOper('<=','FL', etBoolean, Func_FL_LTE, 80));
  1478. Add(TFunction.CreateOper('>=','FL', etBoolean, Func_FL_GTE, 80));
  1479. Add(TFunction.CreateOper('<>','FL', etBoolean, Func_FL_NEQ, 80));
  1480. Add(TFunction.CreateOper('=', 'IL', etBoolean, Func_IL_EQ , 80));
  1481. Add(TFunction.CreateOper('<', 'IL', etBoolean, Func_IL_LT , 80));
  1482. Add(TFunction.CreateOper('>', 'IL', etBoolean, Func_IL_GT , 80));
  1483. Add(TFunction.CreateOper('<=','IL', etBoolean, Func_IL_LTE, 80));
  1484. Add(TFunction.CreateOper('>=','IL', etBoolean, Func_IL_GTE, 80));
  1485. Add(TFunction.CreateOper('<>','IL', etBoolean, Func_IL_NEQ, 80));
  1486. {$endif}
  1487. Add(TFunction.CreateOper('NOT', 'B', etBoolean, Func_NOT, 85));
  1488. Add(TFunction.CreateOper('AND', 'BB', etBoolean, Func_AND, 90));
  1489. Add(TFunction.CreateOper('OR', 'BB', etBoolean, Func_OR, 100));
  1490. // Functions - name, description, param types, min params, result type, Func addr
  1491. Add(TFunction.Create('STR', '', 'FII', 1, etString, FuncFloatToStr, ''));
  1492. Add(TFunction.Create('STR', '', 'III', 1, etString, FuncIntToStr, ''));
  1493. Add(TFunction.Create('DTOS', '', 'D', 1, etString, FuncDateToStr, ''));
  1494. Add(TFunction.Create('SUBSTR', 'SUBS', 'SII', 3, etString, FuncSubString, ''));
  1495. Add(TFunction.Create('UPPERCASE', 'UPPER', 'S', 1, etString, FuncUppercase, ''));
  1496. Add(TFunction.Create('LOWERCASE', 'LOWER', 'S', 1, etString, FuncLowercase, ''));
  1497. end;
  1498. with DbfWordsInsensGeneralList do
  1499. begin
  1500. Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStrI_LT , 80));
  1501. Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStrI_GT , 80));
  1502. Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStrI_LTE, 80));
  1503. Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStrI_GTE, 80));
  1504. Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStrI_NEQ, 80));
  1505. end;
  1506. with DbfWordsInsensNoPartialList do
  1507. Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrI_EQ , 80));
  1508. with DbfWordsInsensPartialList do
  1509. Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrIP_EQ, 80));
  1510. with DbfWordsSensGeneralList do
  1511. begin
  1512. Add(TFunction.CreateOper('<', 'SS', etBoolean, FuncStr_LT , 80));
  1513. Add(TFunction.CreateOper('>', 'SS', etBoolean, FuncStr_GT , 80));
  1514. Add(TFunction.CreateOper('<=','SS', etBoolean, FuncStr_LTE, 80));
  1515. Add(TFunction.CreateOper('>=','SS', etBoolean, FuncStr_GTE, 80));
  1516. Add(TFunction.CreateOper('<>','SS', etBoolean, FuncStr_NEQ, 80));
  1517. end;
  1518. with DbfWordsSensNoPartialList do
  1519. Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStr_EQ , 80));
  1520. with DbfWordsSensPartialList do
  1521. Add(TFunction.CreateOper('=', 'SS', etBoolean, FuncStrP_EQ , 80));
  1522. finalization
  1523. DbfWordsGeneralList.Free;
  1524. DbfWordsInsensGeneralList.Free;
  1525. DbfWordsInsensNoPartialList.Free;
  1526. DbfWordsInsensPartialList.Free;
  1527. DbfWordsSensGeneralList.Free;
  1528. DbfWordsSensNoPartialList.Free;
  1529. DbfWordsSensPartialList.Free;
  1530. end.