strutils.pp 39 KB

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