strutils.pp 37 KB

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