strutils.pp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557
  1. {$mode objfpc}
  2. {$h+}
  3. {
  4. $Id$
  5. This file is part of the Free Pascal run time library.
  6. Copyright (c) 1999-2000 by the Free Pascal development team
  7. Delphi/Kylix compatibility unit: String handling routines.
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit strutils;
  15. interface
  16. uses
  17. SysUtils{, Types};
  18. { ---------------------------------------------------------------------
  19. Case sensitive search/replace
  20. ---------------------------------------------------------------------}
  21. Function AnsiResemblesText(const AText, AOther: string): Boolean;
  22. Function AnsiContainsText(const AText, ASubText: string): Boolean;
  23. Function AnsiStartsText(const ASubText, AText: string): Boolean;
  24. Function AnsiEndsText(const ASubText, AText: string): Boolean;
  25. Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
  26. Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
  27. Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
  28. { ---------------------------------------------------------------------
  29. Case insensitive search/replace
  30. ---------------------------------------------------------------------}
  31. Function AnsiContainsStr(const AText, ASubText: string): Boolean;
  32. Function AnsiStartsStr(const ASubText, AText: string): Boolean;
  33. Function AnsiEndsStr(const ASubText, AText: string): Boolean;
  34. Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
  35. Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
  36. Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
  37. { ---------------------------------------------------------------------
  38. Playthingies
  39. ---------------------------------------------------------------------}
  40. Function DupeString(const AText: string; ACount: Integer): string;
  41. Function ReverseString(const AText: string): string;
  42. Function AnsiReverseString(const AText: AnsiString): AnsiString;
  43. Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
  44. Function RandomFrom(const AValues: array of string): string; overload;
  45. Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;
  46. Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
  47. { ---------------------------------------------------------------------
  48. VB emulations.
  49. ---------------------------------------------------------------------}
  50. Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  51. Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  52. Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  53. Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  54. Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
  55. Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  56. Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  57. Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  58. {$ifndef ver1_0}
  59. Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  60. Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
  61. Function RightStr(const AText: WideString; const ACount: Integer): WideString;
  62. Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
  63. {$endif}
  64. { ---------------------------------------------------------------------
  65. Extended search and replace
  66. ---------------------------------------------------------------------}
  67. const
  68. { Default word delimiters are any character except the core alphanumerics. }
  69. WordDelimiters: set of Char = [#0..#255] - ['a'..'z','A'..'Z','1'..'9','0'];
  70. type
  71. TStringSearchOption = (soDown, soMatchCase, soWholeWord);
  72. TStringSearchOptions = set of TStringSearchOption;
  73. TStringSeachOption = TStringSearchOption;
  74. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
  75. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar; // ; Options: TStringSearchOptions = [soDown]
  76. Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
  77. Function PosEx(const SubStr, S: string): Integer; // Offset: Cardinal = 1
  78. Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
  79. { ---------------------------------------------------------------------
  80. Soundex Functions.
  81. ---------------------------------------------------------------------}
  82. type
  83. TSoundexLength = 1..MaxInt;
  84. Function Soundex(const AText: string; ALength: TSoundexLength): string;
  85. Function Soundex(const AText: string): string; // ; ALength: TSoundexLength = 4
  86. type
  87. TSoundexIntLength = 1..8;
  88. Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
  89. Function SoundexInt(const AText: string): Integer; //; ALength: TSoundexIntLength = 4
  90. Function DecodeSoundexInt(AValue: Integer): string;
  91. Function SoundexWord(const AText: string): Word;
  92. Function DecodeSoundexWord(AValue: Word): string;
  93. Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;
  94. Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
  95. Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
  96. Function SoundexCompare(const AText, AOther: string): Integer; //; ALength: TSoundexLength = 4
  97. Function SoundexProc(const AText, AOther: string): Boolean;
  98. type
  99. TCompareTextProc = Function(const AText, AOther: string): Boolean;
  100. Const
  101. AnsiResemblesProc: TCompareTextProc = @SoundexProc;
  102. { ---------------------------------------------------------------------
  103. Other functions, based on RxStrUtils.
  104. ---------------------------------------------------------------------}
  105. function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
  106. function DelSpace(const S: string): string;
  107. function DelChars(const S: string; Chr: Char): string;
  108. function DelSpace1(const S: string): string;
  109. function Tab2Space(const S: string; Numb: Byte): string;
  110. function NPos(const C: string; S: string; N: Integer): Integer;
  111. function AddChar(C: Char; const S: string; N: Integer): string;
  112. function AddCharR(C: Char; const S: string; N: Integer): string;
  113. function PadLeft(const S: string; N: Integer): string;
  114. function PadRight(const S: string; N: Integer): string;
  115. function PadCenter(const S: string; Len: Integer): string;
  116. function Copy2Symb(const S: string; Symb: Char): string;
  117. function Copy2SymbDel(var S: string; Symb: Char): string;
  118. function Copy2Space(const S: string): string;
  119. function Copy2SpaceDel(var S: string): string;
  120. function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
  121. function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
  122. function WordPosition(const N: Integer; const S: string; const WordDelims: TSysCharSet): Integer;
  123. function ExtractWord(N: Integer; const S: string; const WordDelims: TSysCharSet): string;
  124. function ExtractWordPos(N: Integer; const S: string; const WordDelims: TSysCharSet; var Pos: Integer): string;
  125. function ExtractDelimited(N: Integer; const S: string; const Delims: TSysCharSet): string;
  126. function ExtractSubstr(const S: string; var Pos: Integer; const Delims: TSysCharSet): string;
  127. function IsWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
  128. function FindPart(const HelpWilds, InputStr: string): Integer;
  129. function IsWild(InputStr, Wilds: string; IgnoreCase: Boolean): Boolean;
  130. function XorString(const Key, Src: ShortString): ShortString;
  131. function XorEncode(const Key, Source: string): string;
  132. function XorDecode(const Key, Source: string): string;
  133. function GetCmdLineArg(const Switch: string; SwitchChars: TSysCharSet): string;
  134. function Numb2USA(const S: string): string;
  135. function Hex2Dec(const S: string): Longint;
  136. function Dec2Numb(N: Longint; Len, Base: Byte): string;
  137. function Numb2Dec(S: string; Base: Byte): Longint;
  138. function IntToBin(Value: Longint; Digits, Spaces: Integer): string;
  139. function IntToRoman(Value: Longint): string;
  140. function RomanToInt(const S: string): Longint;
  141. const
  142. DigitChars = ['0'..'9'];
  143. Brackets = ['(',')','[',']','{','}'];
  144. StdWordDelims = [#0..' ',',','.',';','/','\',':','''','"','`'] + Brackets;
  145. StdSwitchChars = ['-','/'];
  146. implementation
  147. { ---------------------------------------------------------------------
  148. Auxiliary functions
  149. ---------------------------------------------------------------------}
  150. Procedure NotYetImplemented (FN : String);
  151. begin
  152. Raise Exception.CreateFmt('Function "%s" (strutils) is not yet implemented',[FN]);
  153. end;
  154. { ---------------------------------------------------------------------
  155. Case sensitive search/replace
  156. ---------------------------------------------------------------------}
  157. Function AnsiResemblesText(const AText, AOther: string): Boolean;
  158. begin
  159. if Assigned(AnsiResemblesProc) then
  160. Result:=AnsiResemblesProc(AText,AOther)
  161. else
  162. Result:=False;
  163. end;
  164. Function AnsiContainsText(const AText, ASubText: string): Boolean;
  165. begin
  166. AnsiContainsText:=Pos(ASubText,AText)<>0;
  167. end;
  168. Function AnsiStartsText(const ASubText, AText: string): Boolean;
  169. begin
  170. Result:=Copy(AText,1,Length(AsubText))=ASubText;
  171. end;
  172. Function AnsiEndsText(const ASubText, AText: string): Boolean;
  173. begin
  174. result:=Copy(AText,Length(AText)-Length(ASubText)+1,Length(ASubText))=asubtext;
  175. end;
  176. Function AnsiReplaceText(const AText, AFromText, AToText: string): string;
  177. var iFrom, iTo: longint;
  178. begin
  179. iTo:=Pos(AFromText,AText);
  180. if iTo=0 then
  181. result:=AText
  182. else
  183. begin
  184. result:='';
  185. iFrom:=1;
  186. while (ito<>0) do
  187. begin
  188. result:=Result+Copy(AText,IFrom,Ito-IFrom+1)+AToText;
  189. ifrom:=ITo+Length(afromtext);
  190. ito:=Posex(Afromtext,atext,ifrom);
  191. end;
  192. if ifrom<=length(atext) then
  193. result:=result+copy(AText,ifrom, length(atext));
  194. end;
  195. end;
  196. Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
  197. begin
  198. Result:=(AnsiIndexText(AText,AValues)<>-1)
  199. end;
  200. Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
  201. var i : longint;
  202. begin
  203. result:=-1;
  204. if high(AValues)=-1 Then
  205. Exit;
  206. for i:=low(AValues) to High(Avalues) do
  207. if CompareText(avalues[i],atext)=0 Then
  208. exit(i); // make sure it is the first val.
  209. end;
  210. { ---------------------------------------------------------------------
  211. Case insensitive search/replace
  212. ---------------------------------------------------------------------}
  213. Function AnsiContainsStr(const AText, ASubText: string): Boolean;
  214. begin
  215. Result := Pos(ASubText,AText)<>0;
  216. end;
  217. Function AnsiStartsStr(const ASubText, AText: string): Boolean;
  218. begin
  219. Result := Pos(ASubText,AText)=1;
  220. end;
  221. Function AnsiEndsStr(const ASubText, AText: string): Boolean;
  222. begin
  223. Result := Pos(ASubText,AText)=(length(AText)-length(ASubText)+1);
  224. end;
  225. Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;
  226. begin
  227. Result := StringReplace(AText,AFromText,AToText,[rfReplaceAll]);
  228. end;
  229. Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
  230. begin
  231. Result:=AnsiIndexStr(AText,Avalues)<>-1;
  232. end;
  233. Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
  234. var i : longint;
  235. begin
  236. result:=-1;
  237. if high(AValues)=-1 Then
  238. Exit;
  239. for i:=low(AValues) to High(Avalues) do
  240. if (avalues[i]=AText) Then
  241. exit(i); // make sure it is the first val.
  242. end;
  243. { ---------------------------------------------------------------------
  244. Playthingies
  245. ---------------------------------------------------------------------}
  246. Function DupeString(const AText: string; ACount: Integer): string;
  247. var i,l : integer;
  248. begin
  249. result:='';
  250. if aCount>=0 then
  251. begin
  252. l:=length(atext);
  253. SetLength(result,aCount*l);
  254. for i:=0 to ACount-1 do
  255. move(atext[1],Result[l*i+1],l);
  256. end;
  257. end;
  258. Function ReverseString(const AText: string): string;
  259. var c: char;
  260. i,j:longint;
  261. begin
  262. setlength(result,length(atext));
  263. i:=1; j:=length(atext);
  264. while (i<=j) do
  265. begin
  266. result[i]:=atext[j-i+1];
  267. inc(i);
  268. end;
  269. end;
  270. Function AnsiReverseString(const AText: AnsiString): AnsiString;
  271. begin
  272. Result:=ReverseString(AText);
  273. end;
  274. Function StuffString(const AText: string; AStart, ALength: Cardinal; const ASubText: string): string;
  275. var i,j : longint;
  276. begin
  277. j:=length(ASubText);
  278. i:=length(AText);
  279. SetLength(Result,i-ALength+j);
  280. move (AText[1],result[1],AStart-1);
  281. move (ASubText[1],result[AStart],j);
  282. move (AText[AStart+ALength], Result[AStart+j],i-AStart-ALength+1);
  283. end;
  284. Function RandomFrom(const AValues: array of string): string; overload;
  285. begin
  286. if high(AValues)=-1 then exit('');
  287. result:=Avalues[random(High(AValues)+1)];
  288. end;
  289. Function IfThen(AValue: Boolean; const ATrue: string; AFalse: string): string;
  290. begin
  291. if avalue then
  292. result:=atrue
  293. else
  294. result:=afalse;
  295. end;
  296. Function IfThen(AValue: Boolean; const ATrue: string): string; // ; AFalse: string = ''
  297. begin
  298. if avalue then
  299. result:=atrue
  300. else
  301. result:='';
  302. end;
  303. { ---------------------------------------------------------------------
  304. VB emulations.
  305. ---------------------------------------------------------------------}
  306. Function LeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  307. begin
  308. Result:=Copy(AText,1,ACount);
  309. end;
  310. Function RightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  311. var j,l:integer;
  312. begin
  313. l:=length(atext);
  314. j:=ACount;
  315. if j>l then j:=l;
  316. Result:=Copy(AText,l-j+1,j);
  317. end;
  318. Function MidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  319. begin
  320. if (ACount=0) or (AStart>length(atext)) then
  321. exit('');
  322. Result:=Copy(AText,AStart,ACount);
  323. end;
  324. Function LeftBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  325. begin
  326. Result:=LeftStr(AText,AByteCount);
  327. end;
  328. Function RightBStr(const AText: AnsiString; const AByteCount: Integer): AnsiString;
  329. begin
  330. Result:=RightStr(Atext,AByteCount);
  331. end;
  332. Function MidBStr(const AText: AnsiString; const AByteStart, AByteCount: Integer): AnsiString;
  333. begin
  334. Result:=MidStr(AText,AByteStart,AByteCount);
  335. end;
  336. Function AnsiLeftStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  337. begin
  338. Result := copy(AText,1,ACount);
  339. end;
  340. Function AnsiRightStr(const AText: AnsiString; const ACount: Integer): AnsiString;
  341. begin
  342. Result := copy(AText,length(AText)-ACount+1,ACount);
  343. end;
  344. Function AnsiMidStr(const AText: AnsiString; const AStart, ACount: Integer): AnsiString;
  345. begin
  346. Result:=Copy(AText,AStart,ACount);
  347. end;
  348. {$ifndef ver1_0}
  349. Function LeftStr(const AText: WideString; const ACount: Integer): WideString;
  350. begin
  351. Result:=Copy(AText,1,ACount);
  352. end;
  353. Function RightStr(const AText: WideString; const ACount: Integer): WideString;
  354. var
  355. j,l:integer;
  356. begin
  357. l:=length(atext);
  358. j:=ACount;
  359. if j>l then j:=l;
  360. Result:=Copy(AText,l-j+1,j);
  361. end;
  362. Function MidStr(const AText: WideString; const AStart, ACount: Integer): WideString;
  363. begin
  364. Result:=Copy(AText,AStart,ACount);
  365. end;
  366. {$endif}
  367. { ---------------------------------------------------------------------
  368. Extended search and replace
  369. ---------------------------------------------------------------------}
  370. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String; Options: TStringSearchOptions): PChar;
  371. var
  372. Len,I,SLen: Integer;
  373. C: Char;
  374. Found : Boolean;
  375. Direction: Shortint;
  376. CharMap: array[Char] of Char;
  377. Function GotoNextWord(var P : PChar): Boolean;
  378. begin
  379. if (Direction=1) then
  380. begin
  381. // Skip characters
  382. While (Len>0) and not (P^ in WordDelimiters) do
  383. begin
  384. Inc(P);
  385. Dec(Len);
  386. end;
  387. // skip delimiters
  388. While (Len>0) and (P^ in WordDelimiters) do
  389. begin
  390. Inc(P);
  391. Dec(Len);
  392. end;
  393. Result:=Len>0;
  394. end
  395. else
  396. begin
  397. // Skip Delimiters
  398. While (Len>0) and (P^ in WordDelimiters) do
  399. begin
  400. Dec(P);
  401. Dec(Len);
  402. end;
  403. // skip characters
  404. While (Len>0) and not (P^ in WordDelimiters) do
  405. begin
  406. Dec(P);
  407. Dec(Len);
  408. end;
  409. Result:=Len>0;
  410. // We're on the first delimiter. Pos back on char.
  411. Inc(P);
  412. Inc(Len);
  413. end;
  414. end;
  415. begin
  416. Result:=nil;
  417. Slen:=Length(SearchString);
  418. if (BufLen<=0) or (Slen=0) then
  419. Exit;
  420. if soDown in Options then
  421. begin
  422. Direction:=1;
  423. Inc(SelStart,SelLength);
  424. Len:=BufLen-SelStart-SLen+1;
  425. if (Len<=0) then
  426. Exit;
  427. end
  428. else
  429. begin
  430. Direction:=-1;
  431. Dec(SelStart,Length(SearchString));
  432. Len:=SelStart+1;
  433. end;
  434. if (SelStart<0) or (SelStart>BufLen) then
  435. Exit;
  436. Result:=@Buf[SelStart];
  437. for C:=Low(Char) to High(Char) do
  438. if (soMatchCase in Options) then
  439. CharMap[C]:=C
  440. else
  441. CharMap[C]:=Upcase(C);
  442. if Not (soMatchCase in Options) then
  443. SearchString:=UpCase(SearchString);
  444. Found:=False;
  445. while (Result<>Nil) and (Not Found) do
  446. begin
  447. if ((soWholeWord in Options) and
  448. (Result<>@Buf[SelStart]) and
  449. not GotoNextWord(Result)) then
  450. Result:=Nil
  451. else
  452. begin
  453. // try to match whole searchstring
  454. I:=0;
  455. while (I<Slen) and (CharMap[Result[I]]=SearchString[I+1]) do
  456. Inc(I);
  457. // Whole searchstring matched ?
  458. if (I=SLen) then
  459. Found:=(Len=0) or
  460. (not (soWholeWord in Options)) or
  461. (Result[SLen] in WordDelimiters);
  462. if not Found then
  463. begin
  464. Inc(Result,Direction);
  465. Dec(Len);
  466. If (Len=0) then
  467. Result:=Nil;
  468. end;
  469. end;
  470. end;
  471. end;
  472. Function SearchBuf(Buf: PChar; BufLen: Integer; SelStart, SelLength: Integer; SearchString: String): PChar; // ; Options: TStringSearchOptions = [soDown]
  473. begin
  474. Result:=SearchBuf(Buf,BufLen,SelStart,SelLength,SearchString,[soDown]);
  475. end;
  476. Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
  477. var i : pchar;
  478. begin
  479. if (offset<1) or (offset>length(s)) then exit(0);
  480. i:=strpos(@s[offset],@substr[1]);
  481. if i=nil then
  482. PosEx:=0
  483. else
  484. PosEx:=succ(i-pchar(s));
  485. end;
  486. Function PosEx(const SubStr, S: string): Integer; // Offset: Cardinal = 1
  487. begin
  488. posex:=posex(substr,s,1);
  489. end;
  490. Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
  491. var l : longint;
  492. begin
  493. if (offset<1) or (offset>length(s)) then exit(0);
  494. l:=length(s);
  495. {$ifndef useindexbyte}
  496. while (offset<=l) and (s[offset]<>c) do inc(offset);
  497. if offset>l then
  498. posex:=0
  499. else
  500. posex:=offset;
  501. {$else}
  502. posex:=offset+indexbyte(s[offset],l-offset+1);
  503. if posex=(offset-1) then
  504. posex:=0;
  505. {$endif}
  506. end;
  507. { ---------------------------------------------------------------------
  508. Soundex Functions.
  509. ---------------------------------------------------------------------}
  510. Const
  511. SScore : array[1..255] of Char =
  512. ('0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 1..32
  513. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 33..64
  514. '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 64..90
  515. '0','0','0','0','0','0', // 91..95
  516. '0','1','2','3','0','1','2','i','0','2','2','4','5','5','0','1','2','6','2','3','0','1','i','2','i','2', // 96..122
  517. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 123..154
  518. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 155..186
  519. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 187..218
  520. '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0', // 219..250
  521. '0','0','0','0','0'); // 251..255
  522. Function Soundex(const AText: string; ALength: TSoundexLength): string;
  523. Var
  524. S,PS : Char;
  525. I,L : integer;
  526. begin
  527. Result:='';
  528. PS:=#0;
  529. If Length(AText)>0 then
  530. begin
  531. Result:=Upcase(AText[1]);
  532. I:=2;
  533. L:=Length(AText);
  534. While (I<=L) and (Length(Result)<ALength) do
  535. begin
  536. S:=SScore[Ord(AText[i])];
  537. If Not (S in ['0','i',PS]) then
  538. Result:=Result+S;
  539. If (S<>'i') then
  540. PS:=S;
  541. Inc(I);
  542. end;
  543. end;
  544. L:=Length(Result);
  545. If (L<ALength) then
  546. Result:=Result+StringOfChar('0',Alength-L);
  547. end;
  548. Function Soundex(const AText: string): string; // ; ALength: TSoundexLength = 4
  549. begin
  550. Result:=Soundex(AText,4);
  551. end;
  552. Const
  553. Ord0 = Ord('0');
  554. OrdA = Ord('A');
  555. Function SoundexInt(const AText: string; ALength: TSoundexIntLength): Integer;
  556. var
  557. SE: string;
  558. I: Integer;
  559. begin
  560. Result:=-1;
  561. SE:=Soundex(AText,ALength);
  562. If Length(SE)>0 then
  563. begin
  564. Result:=Ord(SE[1])-OrdA;
  565. if ALength > 1 then
  566. begin
  567. Result:=Result*26+(Ord(SE[2])-Ord0);
  568. for I:=3 to ALength do
  569. Result:=(Ord(SE[I])-Ord0)+Result*7;
  570. end;
  571. Result:=ALength+Result*9;
  572. end;
  573. end;
  574. Function SoundexInt(const AText: string): Integer; //; ALength: TSoundexIntLength = 4
  575. begin
  576. Result:=SoundexInt(AText,4);
  577. end;
  578. Function DecodeSoundexInt(AValue: Integer): string;
  579. var
  580. I, Len: Integer;
  581. begin
  582. Result := '';
  583. Len := AValue mod 9;
  584. AValue := AValue div 9;
  585. for I:=Len downto 3 do
  586. begin
  587. Result:=Chr(Ord0+(AValue mod 7))+Result;
  588. AValue:=AValue div 7;
  589. end;
  590. if Len>2 then
  591. Result:=IntToStr(AValue mod 26)+Result;
  592. AValue:=AValue div 26;
  593. Result:=Chr(OrdA+AValue)+Result;
  594. end;
  595. Function SoundexWord(const AText: string): Word;
  596. Var
  597. S : String;
  598. begin
  599. S:=SoundEx(Atext,4);
  600. Result:=Ord(S[1])-OrdA;
  601. Result:=Result*26+StrToInt(S[2]);
  602. Result:=Result*7+StrToInt(S[3]);
  603. Result:=Result*7+StrToInt(S[4]);
  604. end;
  605. Function DecodeSoundexWord(AValue: Word): string;
  606. begin
  607. Result := Chr(Ord0+ (AValue mod 7)) + Result;
  608. AValue := AValue div 7;
  609. Result := Chr(Ord0+ (AValue mod 7)) + Result;
  610. AValue := AValue div 7;
  611. Result := IntToStr(AValue mod 26) + Result;
  612. AValue := AValue div 26;
  613. Result := Chr(OrdA+AValue) + Result;
  614. end;
  615. Function SoundexSimilar(const AText, AOther: string; ALength: TSoundexLength): Boolean;
  616. begin
  617. Result:=Soundex(AText,ALength)=Soundex(AOther,ALength);
  618. end;
  619. Function SoundexSimilar(const AText, AOther: string): Boolean; //; ALength: TSoundexLength = 4
  620. begin
  621. Result:=SoundexSimilar(AText,AOther,4);
  622. end;
  623. Function SoundexCompare(const AText, AOther: string; ALength: TSoundexLength): Integer;
  624. begin
  625. Result:=AnsiCompareStr(Soundex(AText,ALength),Soundex(AOther,ALength));
  626. end;
  627. Function SoundexCompare(const AText, AOther: string): Integer; //; ALength: TSoundexLength = 4
  628. begin
  629. Result:=SoundexCompare(AText,AOther,4);
  630. end;
  631. Function SoundexProc(const AText, AOther: string): Boolean;
  632. begin
  633. Result:=SoundexSimilar(AText,AOther);
  634. end;
  635. { ---------------------------------------------------------------------
  636. RxStrUtils-like functions.
  637. ---------------------------------------------------------------------}
  638. function IsEmptyStr(const S: string; const EmptyChars: TSysCharSet): Boolean;
  639. var
  640. i,l: Integer;
  641. begin
  642. l:=Length(S);
  643. i:=1;
  644. Result:=True;
  645. while Result and (i<=l) do
  646. begin
  647. Result:=Not (S[i] in EmptyChars);
  648. Inc(i);
  649. end;
  650. end;
  651. function DelSpace(const S: String): string;
  652. begin
  653. Result:=DelChars(S,' ');
  654. end;
  655. function DelChars(const S: string; Chr: Char): string;
  656. var
  657. I,J: Integer;
  658. begin
  659. Result:=S;
  660. I:=Length(Result);
  661. While I>0 do
  662. begin
  663. if Result[I]=Chr then
  664. begin
  665. J:=I-1;
  666. While (J>0) and (Result[J]=Chr) do
  667. Dec(j);
  668. Delete(Result,J+1,I-J);
  669. I:=J+1;
  670. end;
  671. dec(I);
  672. end;
  673. end;
  674. function DelSpace1(const S: string): string;
  675. var
  676. i: Integer;
  677. begin
  678. Result:=S;
  679. for i:=Length(Result) downto 2 do
  680. if (Result[i]=' ') and (Result[I-1]=' ') then
  681. Delete(Result,I,1);
  682. end;
  683. function Tab2Space(const S: string; Numb: Byte): string;
  684. var
  685. I: Integer;
  686. begin
  687. I:=1;
  688. Result:=S;
  689. while I <= Length(Result) do
  690. if Result[I]<>Chr(9) then
  691. inc(I)
  692. else
  693. begin
  694. Result[I]:=' ';
  695. If (Numb>1) then
  696. Insert(StringOfChar('0',Numb-1),Result,I);
  697. Inc(I,Numb);
  698. end;
  699. end;
  700. function NPos(const C: string; S: string; N: Integer): Integer;
  701. var
  702. i,p,k: Integer;
  703. begin
  704. Result:=0;
  705. if N<1 then
  706. Exit;
  707. k:=0;
  708. i:=1;
  709. Repeat
  710. p:=pos(C,S);
  711. Inc(k,p);
  712. if p>0 then
  713. delete(S,1,p);
  714. Inc(i);
  715. Until (i>n) or (p=0);
  716. If (P>0) then
  717. Result:=K;
  718. end;
  719. function AddChar(C: Char; const S: string; N: Integer): string;
  720. Var
  721. l : Integer;
  722. begin
  723. Result:=S;
  724. l:=Length(Result);
  725. if l<N then
  726. Result:=StringOfChar(C,N-l)+Result;
  727. end;
  728. function AddCharR(C: Char; const S: string; N: Integer): string;
  729. Var
  730. l : Integer;
  731. begin
  732. Result:=S;
  733. l:=Length(Result);
  734. if l<N then
  735. Result:=Result+StringOfChar(C,N-l);
  736. end;
  737. function PadRight(const S: string; N: Integer): string;
  738. begin
  739. Result:=AddCharR(' ',S,N);
  740. end;
  741. function PadLeft(const S: string; N: Integer): string;
  742. begin
  743. Result:=AddChar(' ',S,N);
  744. end;
  745. function Copy2Symb(const S: string; Symb: Char): string;
  746. var
  747. p: Integer;
  748. begin
  749. p:=Pos(Symb,S);
  750. if p=0 then
  751. p:=Length(S)+1;
  752. Result:=Copy(S,1,p-1);
  753. end;
  754. function Copy2SymbDel(var S: string; Symb: Char): string;
  755. begin
  756. Result:=Copy2Symb(S,Symb);
  757. S:=TrimRight(Copy(S,Length(Result)+1,Length(S)));
  758. end;
  759. function Copy2Space(const S: string): string;
  760. begin
  761. Result:=Copy2Symb(S,' ');
  762. end;
  763. function Copy2SpaceDel(var S: string): string;
  764. begin
  765. Result:=Copy2SymbDel(S,' ');
  766. end;
  767. function AnsiProperCase(const S: string; const WordDelims: TSysCharSet): string;
  768. var
  769. l : Integer;
  770. P,PE : PChar;
  771. begin
  772. Result:=AnsiLowerCase(S);
  773. P:=PChar(Result);
  774. PE:=P+Length(Result);
  775. while (P<PE) do
  776. begin
  777. while (P<PE) and (P^ in WordDelims) do
  778. inc(P);
  779. if (P<PE) then
  780. P^:=UpCase(P^);
  781. while (P<PE) and not (P^ in WordDelims) do
  782. inc(P);
  783. end;
  784. end;
  785. function WordCount(const S: string; const WordDelims: TSysCharSet): Integer;
  786. var
  787. P,PE : PChar;
  788. begin
  789. Result:=0;
  790. P:=Pchar(S);
  791. PE:=P+Length(S);
  792. while (P<PE) do
  793. begin
  794. while (P<PE) and (P^ in WordDelims) do
  795. Inc(P);
  796. if (P<PE) then
  797. inc(Result);
  798. while (P<PE) and not (P^ in WordDelims) do
  799. inc(P);
  800. end;
  801. end;
  802. function WordPosition(const N: Integer; const S: string; const WordDelims: TSysCharSet): Integer;
  803. var
  804. PS,P,PE : PChar;
  805. Count: Integer;
  806. begin
  807. Result:=0;
  808. Count:=0;
  809. PS:=PChar(S);
  810. PE:=PS+Length(S);
  811. P:=PS;
  812. while (P<PE) and (Count<>N) do
  813. begin
  814. while (P<PE) and (P^ in WordDelims) do
  815. inc(P);
  816. if (P<PE) then
  817. inc(Count);
  818. if (Count<>N) then
  819. while (P<PE) and not (P^ in WordDelims) do
  820. inc(P)
  821. else
  822. Result:=(P-PS)+1;
  823. end;
  824. end;
  825. function ExtractWord(N: Integer; const S: string; const WordDelims: TSysCharSet): string;
  826. var
  827. i: Integer;
  828. begin
  829. Result:=ExtractWordPos(N,S,WordDelims,i);
  830. end;
  831. function ExtractWordPos(N: Integer; const S: string; const WordDelims: TSysCharSet; var Pos: Integer): string;
  832. var
  833. i,j,l: Integer;
  834. begin
  835. j:=0;
  836. i:=WordPosition(N, S, WordDelims);
  837. Pos:=i;
  838. if (i<>0) then
  839. begin
  840. j:=i;
  841. l:=Length(S);
  842. while (j<=L) and not (S[j] in WordDelims) do
  843. inc(j);
  844. end;
  845. SetLength(Result,j-i);
  846. If ((j-i)>0) then
  847. Move(S[i],Result[1],j-i);
  848. end;
  849. function ExtractDelimited(N: Integer; const S: string; const Delims: TSysCharSet): string;
  850. var
  851. w,i,l,len: Integer;
  852. begin
  853. w:=0;
  854. i:=1;
  855. l:=0;
  856. len:=Length(S);
  857. SetLength(Result, 0);
  858. while (i<=len) and (w<>N) do
  859. begin
  860. if s[i] in Delims then
  861. inc(w)
  862. else
  863. begin
  864. if (N-1)=w then
  865. begin
  866. inc(l);
  867. SetLength(Result,l);
  868. Result[L]:=S[i];
  869. end;
  870. end;
  871. inc(i);
  872. end;
  873. end;
  874. function ExtractSubstr(const S: string; var Pos: Integer; const Delims: TSysCharSet): string;
  875. var
  876. i,l: Integer;
  877. begin
  878. i:=Pos;
  879. l:=Length(S);
  880. while (i<=l) and not (S[i] in Delims) do
  881. inc(i);
  882. Result:=Copy(S,Pos,i-Pos);
  883. if (i<=l) and (S[i] in Delims) then
  884. inc(i);
  885. Pos:=i;
  886. end;
  887. function isWordPresent(const W, S: string; const WordDelims: TSysCharSet): Boolean;
  888. var
  889. i,Count : Integer;
  890. begin
  891. Result:=False;
  892. Count:=WordCount(S, WordDelims);
  893. I:=1;
  894. While (Not Result) and (I<=Count) do
  895. Result:=ExtractWord(i,S,WordDelims)=W;
  896. end;
  897. function Numb2USA(const S: string): string;
  898. var
  899. i, NA: Integer;
  900. begin
  901. i:=Length(S);
  902. Result:=S;
  903. NA:=0;
  904. while (i > 0) do begin
  905. if ((Length(Result) - i + 1 - NA) mod 3 = 0) and (i <> 1) then
  906. begin
  907. insert(',', Result, i);
  908. inc(NA);
  909. end;
  910. Dec(i);
  911. end;
  912. end;
  913. function PadCenter(const S: string; Len: Integer): string;
  914. begin
  915. if Length(S)<Len then
  916. begin
  917. Result:=StringOfChar(' ',(Len div 2) -(Length(S) div 2))+S;
  918. Result:=Result+StringOfChar(' ',Len-Length(Result));
  919. end
  920. else
  921. Result:=S;
  922. end;
  923. function Hex2Dec(const S: string): Longint;
  924. var
  925. HexStr: string;
  926. begin
  927. if Pos('$',S)=0 then
  928. HexStr:='$'+ S
  929. else
  930. HexStr:=S;
  931. Result:=StrTointDef(HexStr,0);
  932. end;
  933. function Dec2Numb(N: Longint; Len, Base: Byte): string;
  934. var
  935. C: Integer;
  936. Number: Longint;
  937. begin
  938. if N=0 then
  939. Result:='0'
  940. else
  941. begin
  942. Number:=N;
  943. Result:='';
  944. while Number>0 do
  945. begin
  946. C:=Number mod Base;
  947. if C>9 then
  948. C:=C+55
  949. else
  950. C:=C+48;
  951. Result:=Chr(C)+Result;
  952. Number:=Number div Base;
  953. end;
  954. end;
  955. if (Result<>'') then
  956. Result:=AddChar('0',Result,Len);
  957. end;
  958. function Numb2Dec(S: string; Base: Byte): Longint;
  959. var
  960. i, P: Longint;
  961. begin
  962. i:=Length(S);
  963. Result:=0;
  964. S:=UpperCase(S);
  965. P:=1;
  966. while (i>=1) do
  967. begin
  968. if (S[i]>'@') then
  969. Result:=Result+(Ord(S[i])-55)*P
  970. else
  971. Result:=Result+(Ord(S[i])-48)*P;
  972. Dec(i);
  973. P:=P*Base;
  974. end;
  975. end;
  976. function RomanToint(const S: string): Longint;
  977. const
  978. RomanChars = ['C','D','i','L','M','V','X'];
  979. RomanValues : array['C'..'X'] of Word
  980. = (100,500,0,0,0,0,1,0,0,50,1000,0,0,0,0,0,0,0,0,5,0,10);
  981. var
  982. index, Next: Char;
  983. i,l: Integer;
  984. Negative: Boolean;
  985. begin
  986. Result:=0;
  987. i:=0;
  988. Negative:=(Length(S)>0) and (S[1]='-');
  989. if Negative then
  990. inc(i);
  991. l:=Length(S);
  992. while (i<l) do
  993. begin
  994. inc(i);
  995. index:=UpCase(S[i]);
  996. if index in RomanChars then
  997. begin
  998. if Succ(i)<=l then
  999. Next:=UpCase(S[i+1])
  1000. else
  1001. Next:=#0;
  1002. if (Next in RomanChars) and (RomanValues[index]<RomanValues[Next]) then
  1003. begin
  1004. inc(Result, RomanValues[Next]);
  1005. Dec(Result, RomanValues[index]);
  1006. inc(i);
  1007. end
  1008. else
  1009. inc(Result, RomanValues[index]);
  1010. end
  1011. else
  1012. begin
  1013. Result:=0;
  1014. Exit;
  1015. end;
  1016. end;
  1017. if Negative then
  1018. Result:=-Result;
  1019. end;
  1020. function intToRoman(Value: Longint): string;
  1021. const
  1022. Arabics : Array[1..13] of Integer
  1023. = (1,4,5,9,10,40,50,90,100,400,500,900,1000);
  1024. Romans : Array[1..13] of String
  1025. = ('i','iV','V','iX','X','XL','L','XC','C','CD','D','CM','M');
  1026. var
  1027. i: Integer;
  1028. begin
  1029. for i:=13 downto 1 do
  1030. while (Value >= Arabics[i]) do
  1031. begin
  1032. Value:=Value-Arabics[i];
  1033. Result:=Result+Romans[i];
  1034. end;
  1035. end;
  1036. function intToBin(Value: Longint; Digits, Spaces: Integer): string;
  1037. begin
  1038. Result:='';
  1039. if (Digits>32) then
  1040. Digits:=32;
  1041. while (Digits>0) do
  1042. begin
  1043. if (Digits mod Spaces)=0 then
  1044. Result:=Result+' ';
  1045. Dec(Digits);
  1046. Result:=Result+intToStr((Value shr Digits) and 1);
  1047. end;
  1048. end;
  1049. function FindPart(const HelpWilds, inputStr: string): Integer;
  1050. var
  1051. i, J: Integer;
  1052. Diff: Integer;
  1053. begin
  1054. Result:=0;
  1055. i:=Pos('?',HelpWilds);
  1056. if (i=0) then
  1057. Result:=Pos(HelpWilds, inputStr)
  1058. else
  1059. begin
  1060. Diff:=Length(inputStr) - Length(HelpWilds);
  1061. for i:=0 to Diff do
  1062. begin
  1063. for J:=1 to Length(HelpWilds) do
  1064. if (inputStr[i + J] = HelpWilds[J]) or (HelpWilds[J] = '?') then
  1065. begin
  1066. if (J=Length(HelpWilds)) then
  1067. begin
  1068. Result:=i+1;
  1069. Exit;
  1070. end;
  1071. end
  1072. else
  1073. Break;
  1074. end;
  1075. end;
  1076. end;
  1077. function isWild(inputStr, Wilds: string; ignoreCase: Boolean): Boolean;
  1078. function SearchNext(var Wilds: string): Integer;
  1079. begin
  1080. Result:=Pos('*', Wilds);
  1081. if Result>0 then
  1082. Wilds:=Copy(Wilds,1,Result - 1);
  1083. end;
  1084. var
  1085. CWild, CinputWord: Integer; { counter for positions }
  1086. i, LenHelpWilds: Integer;
  1087. MaxinputWord, MaxWilds: Integer; { Length of inputStr and Wilds }
  1088. HelpWilds: string;
  1089. begin
  1090. if Wilds = inputStr then begin
  1091. Result:=True;
  1092. Exit;
  1093. end;
  1094. repeat { delete '**', because '**' = '*' }
  1095. i:=Pos('**', Wilds);
  1096. if i > 0 then
  1097. Wilds:=Copy(Wilds, 1, i - 1) + '*' + Copy(Wilds, i + 2, Maxint);
  1098. until i = 0;
  1099. if Wilds = '*' then begin { for fast end, if Wilds only '*' }
  1100. Result:=True;
  1101. Exit;
  1102. end;
  1103. MaxinputWord:=Length(inputStr);
  1104. MaxWilds:=Length(Wilds);
  1105. if ignoreCase then begin { upcase all letters }
  1106. inputStr:=AnsiUpperCase(inputStr);
  1107. Wilds:=AnsiUpperCase(Wilds);
  1108. end;
  1109. if (MaxWilds = 0) or (MaxinputWord = 0) then begin
  1110. Result:=False;
  1111. Exit;
  1112. end;
  1113. CinputWord:=1;
  1114. CWild:=1;
  1115. Result:=True;
  1116. repeat
  1117. if inputStr[CinputWord] = Wilds[CWild] then begin { equal letters }
  1118. { goto next letter }
  1119. inc(CWild);
  1120. inc(CinputWord);
  1121. Continue;
  1122. end;
  1123. if Wilds[CWild] = '?' then begin { equal to '?' }
  1124. { goto next letter }
  1125. inc(CWild);
  1126. inc(CinputWord);
  1127. Continue;
  1128. end;
  1129. if Wilds[CWild] = '*' then begin { handling of '*' }
  1130. HelpWilds:=Copy(Wilds, CWild + 1, MaxWilds);
  1131. i:=SearchNext(HelpWilds);
  1132. LenHelpWilds:=Length(HelpWilds);
  1133. if i = 0 then begin
  1134. { no '*' in the rest, compare the ends }
  1135. if HelpWilds = '' then Exit; { '*' is the last letter }
  1136. { check the rest for equal Length and no '?' }
  1137. for i:=0 to LenHelpWilds - 1 do begin
  1138. if (HelpWilds[LenHelpWilds - i] <> inputStr[MaxinputWord - i]) and
  1139. (HelpWilds[LenHelpWilds - i]<> '?') then
  1140. begin
  1141. Result:=False;
  1142. Exit;
  1143. end;
  1144. end;
  1145. Exit;
  1146. end;
  1147. { handle all to the next '*' }
  1148. inc(CWild, 1 + LenHelpWilds);
  1149. i:=FindPart(HelpWilds, Copy(inputStr, CinputWord, Maxint));
  1150. if i= 0 then begin
  1151. Result:=False;
  1152. Exit;
  1153. end;
  1154. CinputWord:=i + LenHelpWilds;
  1155. Continue;
  1156. end;
  1157. Result:=False;
  1158. Exit;
  1159. until (CinputWord > MaxinputWord) or (CWild > MaxWilds);
  1160. { no completed evaluation }
  1161. if CinputWord <= MaxinputWord then Result:=False;
  1162. if (CWild <= MaxWilds) and (Wilds[MaxWilds] <> '*') then Result:=False;
  1163. end;
  1164. function XorString(const Key, Src: ShortString): ShortString;
  1165. var
  1166. i: Integer;
  1167. begin
  1168. Result:=Src;
  1169. if Length(Key) > 0 then
  1170. for i:=1 to Length(Src) do
  1171. Result[i]:=Chr(Byte(Key[1 + ((i - 1) mod Length(Key))]) xor Ord(Src[i]));
  1172. end;
  1173. function XorEncode(const Key, Source: string): string;
  1174. var
  1175. i: Integer;
  1176. C: Byte;
  1177. begin
  1178. Result:='';
  1179. for i:=1 to Length(Source) do
  1180. begin
  1181. if Length(Key) > 0 then
  1182. C:=Byte(Key[1 + ((i - 1) mod Length(Key))]) xor Byte(Source[i])
  1183. else
  1184. C:=Byte(Source[i]);
  1185. Result:=Result+AnsiLowerCase(intToHex(C, 2));
  1186. end;
  1187. end;
  1188. function XorDecode(const Key, Source: string): string;
  1189. var
  1190. i: Integer;
  1191. C: Char;
  1192. begin
  1193. Result:='';
  1194. for i:=0 to Length(Source) div 2 - 1 do
  1195. begin
  1196. C:=Chr(StrTointDef('$' + Copy(Source, (i * 2) + 1, 2), Ord(' ')));
  1197. if Length(Key) > 0 then
  1198. C:=Chr(Byte(Key[1 + (i mod Length(Key))]) xor Byte(C));
  1199. Result:=Result + C;
  1200. end;
  1201. end;
  1202. function GetCmdLineArg(const Switch: string; SwitchChars: TSysCharSet): string;
  1203. var
  1204. i: Integer;
  1205. S: string;
  1206. begin
  1207. i:=1;
  1208. Result:='';
  1209. while (Result='') and (i<=ParamCount) do
  1210. begin
  1211. S:=ParamStr(i);
  1212. if (SwitchChars=[]) or ((S[1] in SwitchChars) and (Length(S) > 1)) and
  1213. (AnsiCompareText(Copy(S,2,Length(S)-1),Switch)=0) then
  1214. begin
  1215. inc(i);
  1216. if i<=ParamCount then
  1217. Result:=ParamStr(i);
  1218. end;
  1219. inc(i);
  1220. end;
  1221. end;
  1222. end.
  1223. {
  1224. $Log$
  1225. Revision 1.10 2004-12-30 18:12:43 michael
  1226. + Fix for extractdelimited
  1227. Revision 1.9 2004/07/21 20:37:03 michael
  1228. + Implemented all functions
  1229. Revision 1.8 2004/07/13 18:42:39 michael
  1230. + Added some RxStrUtils functions for Rx compatibility
  1231. Revision 1.7 2004/07/01 15:42:18 peter
  1232. * fix 1.0.x compile
  1233. Revision 1.6 2004/06/29 19:37:17 marco
  1234. * updates from B. Tierens
  1235. Revision 1.5 2004/05/17 07:33:01 marco
  1236. * fixes from Luiz Am?rico
  1237. Revision 1.4 2004/03/19 12:54:22 marco
  1238. * more strutils small things
  1239. Revision 1.3 2004/03/18 16:55:47 marco
  1240. * more simple implementations done, based on copy() Largely untested
  1241. }