dbf_parser.pas 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760
  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. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  214. procedure Refresh(Buffer: PChar); override;
  215. end;
  216. TAnsiStringFieldVar = class(TStringFieldVar)
  217. public
  218. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  219. destructor Destroy; override;
  220. procedure Refresh(Buffer: PChar); override;
  221. end;
  222. TFloatFieldVar = class(TFieldVar)
  223. private
  224. FFieldVal: Double;
  225. protected
  226. function GetFieldVal: Pointer; override;
  227. function GetFieldType: TExpressionType; override;
  228. public
  229. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  230. procedure Refresh(Buffer: PChar); override;
  231. end;
  232. TIntegerFieldVar = class(TFieldVar)
  233. private
  234. FFieldVal: Integer;
  235. protected
  236. function GetFieldVal: Pointer; override;
  237. function GetFieldType: TExpressionType; override;
  238. public
  239. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  240. procedure Refresh(Buffer: PChar); override;
  241. end;
  242. {$ifdef SUPPORT_INT64}
  243. TLargeIntFieldVar = class(TFieldVar)
  244. private
  245. FFieldVal: Int64;
  246. protected
  247. function GetFieldVal: Pointer; override;
  248. function GetFieldType: TExpressionType; override;
  249. public
  250. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  251. procedure Refresh(Buffer: PChar); override;
  252. end;
  253. {$endif}
  254. TDateTimeFieldVar = class(TFieldVar)
  255. private
  256. FFieldVal: TDateTimeRec;
  257. function GetFieldType: TExpressionType; override;
  258. protected
  259. function GetFieldVal: Pointer; override;
  260. public
  261. constructor Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  262. procedure Refresh(Buffer: PChar); override;
  263. end;
  264. //--TFieldVar----------------------------------------------------------------
  265. constructor TFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  266. begin
  267. inherited Create;
  268. // store field
  269. FFieldDef := UseFieldDef;
  270. FDbfFile := ADbfFile;
  271. FFieldName := UseFieldDef.FieldName;
  272. end;
  273. //--TStringFieldVar-------------------------------------------------------------
  274. function TStringFieldVar.GetFieldVal: Pointer;
  275. begin
  276. Result := @FFieldVal;
  277. end;
  278. function TStringFieldVar.GetFieldType: TExpressionType;
  279. begin
  280. Result := etString;
  281. end;
  282. //--TRawStringFieldVar----------------------------------------------------------
  283. constructor TRawStringFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  284. begin
  285. inherited;
  286. end;
  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. constructor TFloatFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  317. begin
  318. inherited;
  319. end;
  320. function TFloatFieldVar.GetFieldVal: Pointer;
  321. begin
  322. Result := @FFieldVal;
  323. end;
  324. function TFloatFieldVar.GetFieldType: TExpressionType;
  325. begin
  326. Result := etFloat;
  327. end;
  328. procedure TFloatFieldVar.Refresh(Buffer: PChar);
  329. begin
  330. // database width is default 64-bit double
  331. if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
  332. FFieldVal := 0.0;
  333. end;
  334. //--TIntegerFieldVar----------------------------------------------------------
  335. constructor TIntegerFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  336. begin
  337. inherited;
  338. end;
  339. function TIntegerFieldVar.GetFieldVal: Pointer;
  340. begin
  341. Result := @FFieldVal;
  342. end;
  343. function TIntegerFieldVar.GetFieldType: TExpressionType;
  344. begin
  345. Result := etInteger;
  346. end;
  347. procedure TIntegerFieldVar.Refresh(Buffer: PChar);
  348. begin
  349. FFieldVal := 0;
  350. FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal);
  351. end;
  352. {$ifdef SUPPORT_INT64}
  353. //--TLargeIntFieldVar----------------------------------------------------------
  354. constructor TLargeIntFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  355. begin
  356. inherited;
  357. end;
  358. function TLargeIntFieldVar.GetFieldVal: Pointer;
  359. begin
  360. Result := @FFieldVal;
  361. end;
  362. function TLargeIntFieldVar.GetFieldType: TExpressionType;
  363. begin
  364. Result := etLargeInt;
  365. end;
  366. procedure TLargeIntFieldVar.Refresh(Buffer: PChar);
  367. begin
  368. if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal) then
  369. FFieldVal := 0;
  370. end;
  371. {$endif}
  372. //--TDateTimeFieldVar---------------------------------------------------------
  373. constructor TDateTimeFieldVar.Create(UseFieldDef: TDbfFieldDef; ADbfFile: TDbfFile);
  374. begin
  375. inherited;
  376. end;
  377. function TDateTimeFieldVar.GetFieldVal: Pointer;
  378. begin
  379. Result := @FFieldVal;
  380. end;
  381. function TDateTimeFieldVar.GetFieldType: TExpressionType;
  382. begin
  383. Result := etDateTime;
  384. end;
  385. procedure TDateTimeFieldVar.Refresh(Buffer: PChar);
  386. begin
  387. if FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal) then
  388. begin
  389. {$ifndef SUPPORT_NEW_FIELDDATA}
  390. // convert BDE timestamp to normal datetime
  391. FFieldVal.DateTime := BDETimeStampToDateTime(FFieldVal.DateTime);
  392. {$endif}
  393. end else begin
  394. FFieldVal.DateTime := 0.0;
  395. end;
  396. end;
  397. //--Expression functions-----------------------------------------------------
  398. procedure FuncFloatToStr(Param: PExpressionRec);
  399. var
  400. width, numDigits, resWidth: Integer;
  401. extVal: Extended;
  402. begin
  403. with Param^ do
  404. begin
  405. // get params;
  406. numDigits := 0;
  407. if Args[1] <> nil then
  408. width := PInteger(Args[1])^
  409. else
  410. width := 18;
  411. if Args[2] <> nil then
  412. numDigits := PInteger(Args[2])^;
  413. // convert to string
  414. Res.AssureSpace(width);
  415. extVal := PDouble(Args[0])^;
  416. resWidth := FloatToText(Res.MemoryPos^, extVal, {$ifndef FPC_VERSION}fvExtended,{$endif} ffFixed, 18, numDigits);
  417. // always use dot as decimal separator
  418. if numDigits > 0 then
  419. Res.MemoryPos^[resWidth-numDigits-1] := '.';
  420. // result width smaller than requested width? -> add space to compensate
  421. if (Args[1] <> nil) and (resWidth < width) then
  422. begin
  423. // move string so that it's right-aligned
  424. Move(Res.MemoryPos^^, (Res.MemoryPos^)[width-resWidth], resWidth);
  425. // fill gap with spaces
  426. FillChar(Res.MemoryPos^^, width-resWidth, ' ');
  427. // resWidth has been padded, update
  428. resWidth := width;
  429. end else if resWidth > width then begin
  430. // result width more than requested width, cut
  431. resWidth := width;
  432. end;
  433. // advance pointer
  434. Inc(Res.MemoryPos^, resWidth);
  435. // null-terminate
  436. Res.MemoryPos^^ := #0;
  437. end;
  438. end;
  439. procedure FuncIntToStr_Gen(Param: PExpressionRec; Val: Integer);
  440. var
  441. width: Integer;
  442. begin
  443. with Param^ do
  444. begin
  445. // width specified?
  446. if Args[1] <> nil then
  447. begin
  448. // convert to string
  449. width := PInteger(Args[1])^;
  450. GetStrFromInt_Width(Val, width, Res.MemoryPos^, #32);
  451. // advance pointer
  452. Inc(Res.MemoryPos^, width);
  453. // need to add decimal?
  454. if Args[2] <> nil then
  455. begin
  456. // get number of digits
  457. width := PInteger(Args[2])^;
  458. // add decimal dot
  459. Res.MemoryPos^^ := '.';
  460. Inc(Res.MemoryPos^);
  461. // add zeroes
  462. FillChar(Res.MemoryPos^^, width, '0');
  463. // go to end
  464. Inc(Res.MemoryPos^, width);
  465. end;
  466. end else begin
  467. // convert to string
  468. width := GetStrFromInt(Val, Res.MemoryPos^);
  469. // advance pointer
  470. Inc(Param.Res.MemoryPos^, width);
  471. end;
  472. // null-terminate
  473. Res.MemoryPos^^ := #0;
  474. end;
  475. end;
  476. procedure FuncIntToStr(Param: PExpressionRec);
  477. begin
  478. FuncIntToStr_Gen(Param, PInteger(Param.Args[0])^);
  479. end;
  480. procedure FuncDateToStr(Param: PExpressionRec);
  481. var
  482. TempStr: string;
  483. begin
  484. with Param^ do
  485. begin
  486. // create in temporary string
  487. DateTimeToString(TempStr, 'yyyymmdd', PDateTimeRec(Args[0]).DateTime);
  488. // copy to buffer
  489. Res.Append(PChar(TempStr), Length(TempStr));
  490. end;
  491. end;
  492. procedure FuncSubString(Param: PExpressionRec);
  493. var
  494. srcLen, index, count: Integer;
  495. begin
  496. with Param^ do
  497. begin
  498. srcLen := StrLen(Args[0]);
  499. index := PInteger(Args[1])^ - 1;
  500. count := PInteger(Args[2])^;
  501. if index + count <= srcLen then
  502. Res.Append(Args[0]+index, count)
  503. else
  504. Res.MemoryPos^^ := #0;
  505. end;
  506. end;
  507. procedure FuncUppercase(Param: PExpressionRec);
  508. var
  509. dest: PChar;
  510. begin
  511. with Param^ do
  512. begin
  513. // first copy
  514. dest := (Res.MemoryPos)^;
  515. Res.Append(Args[0], StrLen(Args[0]));
  516. // make uppercase
  517. AnsiStrUpper(dest);
  518. end;
  519. end;
  520. procedure FuncLowercase(Param: PExpressionRec);
  521. var
  522. dest: PChar;
  523. begin
  524. with Param^ do
  525. begin
  526. // first copy
  527. dest := (Res.MemoryPos)^;
  528. Res.Append(Args[0], StrLen(Args[0]));
  529. // make lowercase
  530. AnsiStrLower(dest);
  531. end;
  532. end;
  533. procedure FuncAdd_F_FF(Param: PExpressionRec);
  534. begin
  535. with Param^ do
  536. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PDouble(Args[1])^;
  537. end;
  538. procedure FuncAdd_F_FI(Param: PExpressionRec);
  539. begin
  540. with Param^ do
  541. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInteger(Args[1])^;
  542. end;
  543. procedure FuncAdd_F_II(Param: PExpressionRec);
  544. begin
  545. with Param^ do
  546. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInteger(Args[1])^;
  547. end;
  548. procedure FuncAdd_F_IF(Param: PExpressionRec);
  549. begin
  550. with Param^ do
  551. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ + PDouble(Args[1])^;
  552. end;
  553. {$ifdef SUPPORT_INT64}
  554. procedure FuncAdd_F_FL(Param: PExpressionRec);
  555. begin
  556. with Param^ do
  557. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ + PInt64(Args[1])^;
  558. end;
  559. procedure FuncAdd_F_IL(Param: PExpressionRec);
  560. begin
  561. with Param^ do
  562. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ + PInt64(Args[1])^;
  563. end;
  564. procedure FuncAdd_F_LL(Param: PExpressionRec);
  565. begin
  566. with Param^ do
  567. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInt64(Args[1])^;
  568. end;
  569. procedure FuncAdd_F_LF(Param: PExpressionRec);
  570. begin
  571. with Param^ do
  572. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ + PDouble(Args[1])^;
  573. end;
  574. procedure FuncAdd_F_LI(Param: PExpressionRec);
  575. begin
  576. with Param^ do
  577. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ + PInteger(Args[1])^;
  578. end;
  579. {$endif}
  580. procedure FuncSub_F_FF(Param: PExpressionRec);
  581. begin
  582. with Param^ do
  583. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PDouble(Args[1])^;
  584. end;
  585. procedure FuncSub_F_FI(Param: PExpressionRec);
  586. begin
  587. with Param^ do
  588. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInteger(Args[1])^;
  589. end;
  590. procedure FuncSub_F_II(Param: PExpressionRec);
  591. begin
  592. with Param^ do
  593. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInteger(Args[1])^;
  594. end;
  595. procedure FuncSub_F_IF(Param: PExpressionRec);
  596. begin
  597. with Param^ do
  598. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ - PDouble(Args[1])^;
  599. end;
  600. {$ifdef SUPPORT_INT64}
  601. procedure FuncSub_F_FL(Param: PExpressionRec);
  602. begin
  603. with Param^ do
  604. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ - PInt64(Args[1])^;
  605. end;
  606. procedure FuncSub_F_IL(Param: PExpressionRec);
  607. begin
  608. with Param^ do
  609. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ - PInt64(Args[1])^;
  610. end;
  611. procedure FuncSub_F_LL(Param: PExpressionRec);
  612. begin
  613. with Param^ do
  614. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInt64(Args[1])^;
  615. end;
  616. procedure FuncSub_F_LF(Param: PExpressionRec);
  617. begin
  618. with Param^ do
  619. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ - PDouble(Args[1])^;
  620. end;
  621. procedure FuncSub_F_LI(Param: PExpressionRec);
  622. begin
  623. with Param^ do
  624. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ - PInteger(Args[1])^;
  625. end;
  626. {$endif}
  627. procedure FuncMul_F_FF(Param: PExpressionRec);
  628. begin
  629. with Param^ do
  630. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PDouble(Args[1])^;
  631. end;
  632. procedure FuncMul_F_FI(Param: PExpressionRec);
  633. begin
  634. with Param^ do
  635. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInteger(Args[1])^;
  636. end;
  637. procedure FuncMul_F_II(Param: PExpressionRec);
  638. begin
  639. with Param^ do
  640. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInteger(Args[1])^;
  641. end;
  642. procedure FuncMul_F_IF(Param: PExpressionRec);
  643. begin
  644. with Param^ do
  645. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ * PDouble(Args[1])^;
  646. end;
  647. {$ifdef SUPPORT_INT64}
  648. procedure FuncMul_F_FL(Param: PExpressionRec);
  649. begin
  650. with Param^ do
  651. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ * PInt64(Args[1])^;
  652. end;
  653. procedure FuncMul_F_IL(Param: PExpressionRec);
  654. begin
  655. with Param^ do
  656. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ * PInt64(Args[1])^;
  657. end;
  658. procedure FuncMul_F_LL(Param: PExpressionRec);
  659. begin
  660. with Param^ do
  661. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInt64(Args[1])^;
  662. end;
  663. procedure FuncMul_F_LF(Param: PExpressionRec);
  664. begin
  665. with Param^ do
  666. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ * PDouble(Args[1])^;
  667. end;
  668. procedure FuncMul_F_LI(Param: PExpressionRec);
  669. begin
  670. with Param^ do
  671. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ * PInteger(Args[1])^;
  672. end;
  673. {$endif}
  674. procedure FuncDiv_F_FF(Param: PExpressionRec);
  675. begin
  676. with Param^ do
  677. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PDouble(Args[1])^;
  678. end;
  679. procedure FuncDiv_F_FI(Param: PExpressionRec);
  680. begin
  681. with Param^ do
  682. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInteger(Args[1])^;
  683. end;
  684. procedure FuncDiv_F_II(Param: PExpressionRec);
  685. begin
  686. with Param^ do
  687. PInteger(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInteger(Args[1])^;
  688. end;
  689. procedure FuncDiv_F_IF(Param: PExpressionRec);
  690. begin
  691. with Param^ do
  692. PDouble(Res.MemoryPos^)^ := PInteger(Args[0])^ / PDouble(Args[1])^;
  693. end;
  694. {$ifdef SUPPORT_INT64}
  695. procedure FuncDiv_F_FL(Param: PExpressionRec);
  696. begin
  697. with Param^ do
  698. PDouble(Res.MemoryPos^)^ := PDouble(Args[0])^ / PInt64(Args[1])^;
  699. end;
  700. procedure FuncDiv_F_IL(Param: PExpressionRec);
  701. begin
  702. with Param^ do
  703. PInt64(Res.MemoryPos^)^ := PInteger(Args[0])^ div PInt64(Args[1])^;
  704. end;
  705. procedure FuncDiv_F_LL(Param: PExpressionRec);
  706. begin
  707. with Param^ do
  708. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInt64(Args[1])^;
  709. end;
  710. procedure FuncDiv_F_LF(Param: PExpressionRec);
  711. begin
  712. with Param^ do
  713. PDouble(Res.MemoryPos^)^ := PInt64(Args[0])^ / PDouble(Args[1])^;
  714. end;
  715. procedure FuncDiv_F_LI(Param: PExpressionRec);
  716. begin
  717. with Param^ do
  718. PInt64(Res.MemoryPos^)^ := PInt64(Args[0])^ div PInteger(Args[1])^;
  719. end;
  720. {$endif}
  721. procedure FuncStrI_EQ(Param: PExpressionRec);
  722. begin
  723. with Param^ do
  724. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) = 0);
  725. end;
  726. procedure FuncStrIP_EQ(Param: PExpressionRec);
  727. var
  728. arg0len, arg1len: integer;
  729. match: boolean;
  730. str0, str1: string;
  731. begin
  732. with Param^ do
  733. begin
  734. arg1len := StrLen(Args[1]);
  735. if Args[1][0] = '*' then
  736. begin
  737. if Args[1][arg1len-1] = '*' then
  738. begin
  739. str0 := AnsiStrUpper(Args[0]);
  740. str1 := AnsiStrUpper(Args[1]+1);
  741. setlength(str1, arg1len-2);
  742. match := AnsiPos(str0, str1) = 0;
  743. end else begin
  744. arg0len := StrLen(Args[0]);
  745. // at least length without asterisk
  746. match := arg0len >= arg1len - 1;
  747. if match then
  748. match := AnsiStrLIComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
  749. end;
  750. end else
  751. if Args[1][arg1len-1] = '*' then
  752. begin
  753. arg0len := StrLen(Args[0]);
  754. match := arg1len >= arg0len - 1;
  755. if match then
  756. match := AnsiStrLIComp(Args[0], Args[1], arg1len-1) = 0;
  757. end else begin
  758. match := AnsiStrIComp(Args[0], Args[1]) = 0;
  759. end;
  760. Res.MemoryPos^^ := Char(match);
  761. end;
  762. end;
  763. procedure FuncStrI_NEQ(Param: PExpressionRec);
  764. begin
  765. with Param^ do
  766. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <> 0);
  767. end;
  768. procedure FuncStrI_LT(Param: PExpressionRec);
  769. begin
  770. with Param^ do
  771. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) < 0);
  772. end;
  773. procedure FuncStrI_GT(Param: PExpressionRec);
  774. begin
  775. with Param^ do
  776. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) > 0);
  777. end;
  778. procedure FuncStrI_LTE(Param: PExpressionRec);
  779. begin
  780. with Param^ do
  781. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) <= 0);
  782. end;
  783. procedure FuncStrI_GTE(Param: PExpressionRec);
  784. begin
  785. with Param^ do
  786. Res.MemoryPos^^ := Char(AnsiStrIComp(Args[0], Args[1]) >= 0);
  787. end;
  788. procedure FuncStrP_EQ(Param: PExpressionRec);
  789. var
  790. arg0len, arg1len: integer;
  791. match: boolean;
  792. begin
  793. with Param^ do
  794. begin
  795. arg1len := StrLen(Args[1]);
  796. if Args[1][0] = '*' then
  797. begin
  798. if Args[1][arg1len-1] = '*' then
  799. begin
  800. Args[1][arg1len-1] := #0;
  801. match := AnsiStrPos(Args[0], Args[1]+1) <> nil;
  802. Args[1][arg1len-1] := '*';
  803. end else begin
  804. arg0len := StrLen(Args[0]);
  805. // at least length without asterisk
  806. match := arg0len >= arg1len - 1;
  807. if match then
  808. match := AnsiStrLComp(Args[0]+(arg0len-arg1len+1), Args[1]+1, arg1len-1) = 0;
  809. end;
  810. end else
  811. if Args[1][arg1len-1] = '*' then
  812. begin
  813. arg0len := StrLen(Args[0]);
  814. match := arg1len >= arg0len - 1;
  815. if match then
  816. match := AnsiStrLComp(Args[0], Args[1], arg1len-1) = 0;
  817. end else begin
  818. match := AnsiStrComp(Args[0], Args[1]) = 0;
  819. end;
  820. Res.MemoryPos^^ := Char(match);
  821. end;
  822. end;
  823. procedure FuncStr_EQ(Param: PExpressionRec);
  824. begin
  825. with Param^ do
  826. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) = 0);
  827. end;
  828. procedure FuncStr_NEQ(Param: PExpressionRec);
  829. begin
  830. with Param^ do
  831. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <> 0);
  832. end;
  833. procedure FuncStr_LT(Param: PExpressionRec);
  834. begin
  835. with Param^ do
  836. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) < 0);
  837. end;
  838. procedure FuncStr_GT(Param: PExpressionRec);
  839. begin
  840. with Param^ do
  841. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) > 0);
  842. end;
  843. procedure FuncStr_LTE(Param: PExpressionRec);
  844. begin
  845. with Param^ do
  846. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) <= 0);
  847. end;
  848. procedure FuncStr_GTE(Param: PExpressionRec);
  849. begin
  850. with Param^ do
  851. Res.MemoryPos^^ := Char(AnsiStrComp(Args[0], Args[1]) >= 0);
  852. end;
  853. procedure Func_FF_EQ(Param: PExpressionRec);
  854. begin
  855. with Param^ do
  856. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PDouble(Args[1])^);
  857. end;
  858. procedure Func_FF_NEQ(Param: PExpressionRec);
  859. begin
  860. with Param^ do
  861. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PDouble(Args[1])^);
  862. end;
  863. procedure Func_FF_LT(Param: PExpressionRec);
  864. begin
  865. with Param^ do
  866. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PDouble(Args[1])^);
  867. end;
  868. procedure Func_FF_GT(Param: PExpressionRec);
  869. begin
  870. with Param^ do
  871. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PDouble(Args[1])^);
  872. end;
  873. procedure Func_FF_LTE(Param: PExpressionRec);
  874. begin
  875. with Param^ do
  876. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PDouble(Args[1])^);
  877. end;
  878. procedure Func_FF_GTE(Param: PExpressionRec);
  879. begin
  880. with Param^ do
  881. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PDouble(Args[1])^);
  882. end;
  883. procedure Func_FI_EQ(Param: PExpressionRec);
  884. begin
  885. with Param^ do
  886. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInteger(Args[1])^);
  887. end;
  888. procedure Func_FI_NEQ(Param: PExpressionRec);
  889. begin
  890. with Param^ do
  891. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInteger(Args[1])^);
  892. end;
  893. procedure Func_FI_LT(Param: PExpressionRec);
  894. begin
  895. with Param^ do
  896. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInteger(Args[1])^);
  897. end;
  898. procedure Func_FI_GT(Param: PExpressionRec);
  899. begin
  900. with Param^ do
  901. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInteger(Args[1])^);
  902. end;
  903. procedure Func_FI_LTE(Param: PExpressionRec);
  904. begin
  905. with Param^ do
  906. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInteger(Args[1])^);
  907. end;
  908. procedure Func_FI_GTE(Param: PExpressionRec);
  909. begin
  910. with Param^ do
  911. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInteger(Args[1])^);
  912. end;
  913. procedure Func_II_EQ(Param: PExpressionRec);
  914. begin
  915. with Param^ do
  916. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInteger(Args[1])^);
  917. end;
  918. procedure Func_II_NEQ(Param: PExpressionRec);
  919. begin
  920. with Param^ do
  921. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInteger(Args[1])^);
  922. end;
  923. procedure Func_II_LT(Param: PExpressionRec);
  924. begin
  925. with Param^ do
  926. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInteger(Args[1])^);
  927. end;
  928. procedure Func_II_GT(Param: PExpressionRec);
  929. begin
  930. with Param^ do
  931. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInteger(Args[1])^);
  932. end;
  933. procedure Func_II_LTE(Param: PExpressionRec);
  934. begin
  935. with Param^ do
  936. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInteger(Args[1])^);
  937. end;
  938. procedure Func_II_GTE(Param: PExpressionRec);
  939. begin
  940. with Param^ do
  941. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInteger(Args[1])^);
  942. end;
  943. procedure Func_IF_EQ(Param: PExpressionRec);
  944. begin
  945. with Param^ do
  946. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PDouble(Args[1])^);
  947. end;
  948. procedure Func_IF_NEQ(Param: PExpressionRec);
  949. begin
  950. with Param^ do
  951. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PDouble(Args[1])^);
  952. end;
  953. procedure Func_IF_LT(Param: PExpressionRec);
  954. begin
  955. with Param^ do
  956. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PDouble(Args[1])^);
  957. end;
  958. procedure Func_IF_GT(Param: PExpressionRec);
  959. begin
  960. with Param^ do
  961. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PDouble(Args[1])^);
  962. end;
  963. procedure Func_IF_LTE(Param: PExpressionRec);
  964. begin
  965. with Param^ do
  966. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PDouble(Args[1])^);
  967. end;
  968. procedure Func_IF_GTE(Param: PExpressionRec);
  969. begin
  970. with Param^ do
  971. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PDouble(Args[1])^);
  972. end;
  973. {$ifdef SUPPORT_INT64}
  974. procedure Func_LL_EQ(Param: PExpressionRec);
  975. begin
  976. with Param^ do
  977. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInt64(Args[1])^);
  978. end;
  979. procedure Func_LL_NEQ(Param: PExpressionRec);
  980. begin
  981. with Param^ do
  982. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInt64(Args[1])^);
  983. end;
  984. procedure Func_LL_LT(Param: PExpressionRec);
  985. begin
  986. with Param^ do
  987. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInt64(Args[1])^);
  988. end;
  989. procedure Func_LL_GT(Param: PExpressionRec);
  990. begin
  991. with Param^ do
  992. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInt64(Args[1])^);
  993. end;
  994. procedure Func_LL_LTE(Param: PExpressionRec);
  995. begin
  996. with Param^ do
  997. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInt64(Args[1])^);
  998. end;
  999. procedure Func_LL_GTE(Param: PExpressionRec);
  1000. begin
  1001. with Param^ do
  1002. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInt64(Args[1])^);
  1003. end;
  1004. procedure Func_LF_EQ(Param: PExpressionRec);
  1005. begin
  1006. with Param^ do
  1007. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PDouble(Args[1])^);
  1008. end;
  1009. procedure Func_LF_NEQ(Param: PExpressionRec);
  1010. begin
  1011. with Param^ do
  1012. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PDouble(Args[1])^);
  1013. end;
  1014. procedure Func_LF_LT(Param: PExpressionRec);
  1015. begin
  1016. with Param^ do
  1017. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PDouble(Args[1])^);
  1018. end;
  1019. procedure Func_LF_GT(Param: PExpressionRec);
  1020. begin
  1021. with Param^ do
  1022. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PDouble(Args[1])^);
  1023. end;
  1024. procedure Func_LF_LTE(Param: PExpressionRec);
  1025. begin
  1026. with Param^ do
  1027. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PDouble(Args[1])^);
  1028. end;
  1029. procedure Func_LF_GTE(Param: PExpressionRec);
  1030. begin
  1031. with Param^ do
  1032. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PDouble(Args[1])^);
  1033. end;
  1034. procedure Func_FL_EQ(Param: PExpressionRec);
  1035. begin
  1036. with Param^ do
  1037. Res.MemoryPos^^ := Char(PDouble(Args[0])^ = PInt64(Args[1])^);
  1038. end;
  1039. procedure Func_FL_NEQ(Param: PExpressionRec);
  1040. begin
  1041. with Param^ do
  1042. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <> PInt64(Args[1])^);
  1043. end;
  1044. procedure Func_FL_LT(Param: PExpressionRec);
  1045. begin
  1046. with Param^ do
  1047. Res.MemoryPos^^ := Char(PDouble(Args[0])^ < PInt64(Args[1])^);
  1048. end;
  1049. procedure Func_FL_GT(Param: PExpressionRec);
  1050. begin
  1051. with Param^ do
  1052. Res.MemoryPos^^ := Char(PDouble(Args[0])^ > PInt64(Args[1])^);
  1053. end;
  1054. procedure Func_FL_LTE(Param: PExpressionRec);
  1055. begin
  1056. with Param^ do
  1057. Res.MemoryPos^^ := Char(PDouble(Args[0])^ <= PInt64(Args[1])^);
  1058. end;
  1059. procedure Func_FL_GTE(Param: PExpressionRec);
  1060. begin
  1061. with Param^ do
  1062. Res.MemoryPos^^ := Char(PDouble(Args[0])^ >= PInt64(Args[1])^);
  1063. end;
  1064. procedure Func_LI_EQ(Param: PExpressionRec);
  1065. begin
  1066. with Param^ do
  1067. Res.MemoryPos^^ := Char(PInt64(Args[0])^ = PInteger(Args[1])^);
  1068. end;
  1069. procedure Func_LI_NEQ(Param: PExpressionRec);
  1070. begin
  1071. with Param^ do
  1072. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <> PInteger(Args[1])^);
  1073. end;
  1074. procedure Func_LI_LT(Param: PExpressionRec);
  1075. begin
  1076. with Param^ do
  1077. Res.MemoryPos^^ := Char(PInt64(Args[0])^ < PInteger(Args[1])^);
  1078. end;
  1079. procedure Func_LI_GT(Param: PExpressionRec);
  1080. begin
  1081. with Param^ do
  1082. Res.MemoryPos^^ := Char(PInt64(Args[0])^ > PInteger(Args[1])^);
  1083. end;
  1084. procedure Func_LI_LTE(Param: PExpressionRec);
  1085. begin
  1086. with Param^ do
  1087. Res.MemoryPos^^ := Char(PInt64(Args[0])^ <= PInteger(Args[1])^);
  1088. end;
  1089. procedure Func_LI_GTE(Param: PExpressionRec);
  1090. begin
  1091. with Param^ do
  1092. Res.MemoryPos^^ := Char(PInt64(Args[0])^ >= PInteger(Args[1])^);
  1093. end;
  1094. procedure Func_IL_EQ(Param: PExpressionRec);
  1095. begin
  1096. with Param^ do
  1097. Res.MemoryPos^^ := Char(PInteger(Args[0])^ = PInt64(Args[1])^);
  1098. end;
  1099. procedure Func_IL_NEQ(Param: PExpressionRec);
  1100. begin
  1101. with Param^ do
  1102. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <> PInt64(Args[1])^);
  1103. end;
  1104. procedure Func_IL_LT(Param: PExpressionRec);
  1105. begin
  1106. with Param^ do
  1107. Res.MemoryPos^^ := Char(PInteger(Args[0])^ < PInt64(Args[1])^);
  1108. end;
  1109. procedure Func_IL_GT(Param: PExpressionRec);
  1110. begin
  1111. with Param^ do
  1112. Res.MemoryPos^^ := Char(PInteger(Args[0])^ > PInt64(Args[1])^);
  1113. end;
  1114. procedure Func_IL_LTE(Param: PExpressionRec);
  1115. begin
  1116. with Param^ do
  1117. Res.MemoryPos^^ := Char(PInteger(Args[0])^ <= PInt64(Args[1])^);
  1118. end;
  1119. procedure Func_IL_GTE(Param: PExpressionRec);
  1120. begin
  1121. with Param^ do
  1122. Res.MemoryPos^^ := Char(PInteger(Args[0])^ >= PInt64(Args[1])^);
  1123. end;
  1124. {$endif}
  1125. procedure Func_AND(Param: PExpressionRec);
  1126. begin
  1127. with Param^ do
  1128. Res.MemoryPos^^ := Char(Boolean(Args[0]^) and Boolean(Args[1]^));
  1129. end;
  1130. procedure Func_OR(Param: PExpressionRec);
  1131. begin
  1132. with Param^ do
  1133. Res.MemoryPos^^ := Char(Boolean(Args[0]^) or Boolean(Args[1]^));
  1134. end;
  1135. procedure Func_NOT(Param: PExpressionRec);
  1136. begin
  1137. with Param^ do
  1138. Res.MemoryPos^^ := Char(not Boolean(Args[0]^));
  1139. end;
  1140. //--TDbfParser---------------------------------------------------------------
  1141. var
  1142. DbfWordsSensGeneralList, DbfWordsInsensGeneralList: TExpressList;
  1143. DbfWordsSensPartialList, DbfWordsInsensPartialList: TExpressList;
  1144. DbfWordsSensNoPartialList, DbfWordsInsensNoPartialList: TExpressList;
  1145. DbfWordsGeneralList: TExpressList;
  1146. constructor TDbfParser.Create(ADbfFile: Pointer);
  1147. begin
  1148. FDbfFile := ADbfFile;
  1149. FFieldVarList := TStringList.Create;
  1150. FCaseInsensitive := true;
  1151. FRawStringFields := true;
  1152. inherited Create;
  1153. end;
  1154. destructor TDbfParser.Destroy;
  1155. begin
  1156. ClearExpressions;
  1157. inherited;
  1158. FreeAndNil(FFieldVarList);
  1159. end;
  1160. function TDbfParser.GetResultType: TExpressionType;
  1161. begin
  1162. // if not a real expression, return type ourself
  1163. if FIsExpression then
  1164. Result := inherited GetResultType
  1165. else
  1166. Result := FFieldType;
  1167. end;
  1168. procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean);
  1169. begin
  1170. if FCaseInsensitive <> NewInsensitive then
  1171. begin
  1172. // clear and regenerate functions
  1173. FCaseInsensitive := NewInsensitive;
  1174. FillExpressList;
  1175. if Length(Expression) > 0 then
  1176. ParseExpression(Expression);
  1177. end;
  1178. end;
  1179. procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean);
  1180. begin
  1181. if FPartialMatch <> NewPartialMatch then
  1182. begin
  1183. // refill function list
  1184. FPartialMatch := NewPartialMatch;
  1185. FillExpressList;
  1186. if Length(Expression) > 0 then
  1187. ParseExpression(Expression);
  1188. end;
  1189. end;
  1190. procedure TDbfParser.SetRawStringFields(NewRawFields: Boolean);
  1191. begin
  1192. if FRawStringFields <> NewRawFields then
  1193. begin
  1194. // clear and regenerate functions, custom fields will be deleted too
  1195. FRawStringFields := NewRawFields;
  1196. if Length(Expression) > 0 then
  1197. ParseExpression(Expression);
  1198. end;
  1199. end;
  1200. procedure TDbfParser.FillExpressList;
  1201. begin
  1202. FWordsList.FreeAll;
  1203. FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1);
  1204. if FCaseInsensitive then
  1205. begin
  1206. FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1);
  1207. if FPartialMatch then
  1208. begin
  1209. FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1);
  1210. end else begin
  1211. FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1);
  1212. end;
  1213. end else begin
  1214. FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1);
  1215. if FPartialMatch then
  1216. begin
  1217. FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1);
  1218. end else begin
  1219. FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1);
  1220. end;
  1221. end;
  1222. end;
  1223. function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef;
  1224. begin
  1225. Result := TDbfFile(FDbfFile).GetFieldInfo(VarName);
  1226. end;
  1227. procedure TDbfParser.HandleUnknownVariable(VarName: string);
  1228. var
  1229. FieldInfo: TDbfFieldDef;
  1230. TempFieldVar: TFieldVar;
  1231. begin
  1232. // is this variable a fieldname?
  1233. FieldInfo := GetVariableInfo(VarName);
  1234. if FieldInfo = nil then
  1235. raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]);
  1236. // define field in parser
  1237. case FieldInfo.FieldType of
  1238. ftString, ftBoolean:
  1239. begin
  1240. if RawStringFields then
  1241. begin
  1242. { raw string fields have fixed length, not null-terminated }
  1243. TempFieldVar := TRawStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1244. DefineStringVariableFixedLen(VarName, TempFieldVar.FieldVal, FieldInfo.Size);
  1245. end else begin
  1246. { ansi string field function translates and null-terminates field value }
  1247. TempFieldVar := TAnsiStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
  1248. DefineStringVariable(VarName, TempFieldVar.FieldVal);
  1249. end;
  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.