sysstr.inc 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296
  1. {
  2. *********************************************************************
  3. $Id$
  4. Copyright (C) 1997, 1998 Gertjan Schouten
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  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. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. *********************************************************************
  17. System Utilities For Free Pascal
  18. }
  19. { NewStr creates a new PString and assigns S to it
  20. if length(s) = 0 NewStr returns Nil }
  21. function NewStr(const S: string): PString;
  22. begin
  23. if (S='') then
  24. Result:=nil
  25. else
  26. begin
  27. getmem(Result,length(s)+1);
  28. if (Result<>nil) then
  29. Result^:=s;
  30. end;
  31. end;
  32. { DisposeStr frees the memory occupied by S }
  33. procedure DisposeStr(S: PString);
  34. begin
  35. if S <> Nil then
  36. begin
  37. Freemem(S,Length(S^)+1);
  38. S:=nil;
  39. end;
  40. end;
  41. { AssignStr assigns S to P^ }
  42. procedure AssignStr(var P: PString; const S: string);
  43. begin
  44. P^ := s;
  45. end ;
  46. { AppendStr appends S to Dest }
  47. procedure AppendStr(var Dest: String; const S: string);
  48. begin
  49. Dest := Dest + S;
  50. end ;
  51. { UpperCase returns a copy of S where all lowercase characters ( from a to z )
  52. have been converted to uppercase }
  53. function UpperCase(const S: string): string;
  54. var i: integer;
  55. begin
  56. result := S;
  57. i := Length(S);
  58. while i <> 0 do begin
  59. if (result[i] in ['a'..'z']) then result[i] := char(byte(result[i]) - 32);
  60. Dec(i);
  61. end;
  62. end;
  63. { LowerCase returns a copy of S where all uppercase characters ( from A to Z )
  64. have been converted to lowercase }
  65. function LowerCase(const S: string): string;
  66. var i: integer;
  67. begin
  68. result := S;
  69. i := Length(result);
  70. while i <> 0 do begin
  71. if (result[i] in ['A'..'Z']) then result[i] := char(byte(result[i]) + 32);
  72. dec(i);
  73. end;
  74. end;
  75. { CompareStr compares S1 and S2, the result is the based on
  76. substraction of the ascii values of the characters in S1 and S2
  77. case result
  78. S1 < S2 < 0
  79. S1 > S2 > 0
  80. S1 = S2 = 0 }
  81. function CompareStr(const S1, S2: string): Integer;
  82. var count, count1, count2: integer;
  83. begin
  84. result := 0;
  85. Count1 := Length(S1);
  86. Count2 := Length(S2);
  87. if Count1>Count2 then
  88. Count:=Count2
  89. else
  90. Count:=Count1;
  91. result := CompareMemRange(Pointer(S1),Pointer(S2), Count);
  92. if result=0 then
  93. result:=Count1-Count2;
  94. end;
  95. { CompareMemRange returns the result of comparison of Length bytes at P1 and P2
  96. case result
  97. P1 < P2 < 0
  98. P1 > P2 > 0
  99. P1 = P2 = 0 }
  100. function CompareMemRange(P1, P2: Pointer; Length: cardinal): integer;
  101. var
  102. i: cardinal;
  103. begin
  104. i := 0;
  105. result := 0;
  106. while (result=0) and (I<length) do
  107. begin
  108. result:=byte(P1^)-byte(P2^);
  109. P1:=pchar(P1)+1; // VP compat.
  110. P2:=pchar(P2)+1;
  111. i := i + 1;
  112. end ;
  113. end ;
  114. function CompareMem(P1, P2: Pointer; Length: cardinal): Boolean;
  115. var
  116. i: cardinal;
  117. begin
  118. Result:=True;
  119. I:=0;
  120. If (P1)<>(P2) then
  121. While Result and (i<Length) do
  122. begin
  123. Result:=PByte(P1)^=PByte(P2)^;
  124. Inc(I);
  125. Inc(pchar(P1));
  126. Inc(pchar(P2));
  127. end;
  128. end;
  129. { CompareText compares S1 and S2, the result is the based on
  130. substraction of the ascii values of characters in S1 and S2
  131. comparison is case-insensitive
  132. case result
  133. S1 < S2 < 0
  134. S1 > S2 > 0
  135. S1 = S2 = 0 }
  136. function CompareText(const S1, S2: string): integer;
  137. var
  138. i, count, count1, count2: integer; Chr1, Chr2: byte;
  139. begin
  140. result := 0;
  141. Count1 := Length(S1);
  142. Count2 := Length(S2);
  143. if (Count1>Count2) then
  144. Count := Count2
  145. else
  146. Count := Count1;
  147. i := 0;
  148. while (result=0) and (i<count) do
  149. begin
  150. inc (i);
  151. Chr1 := byte(s1[i]);
  152. Chr2 := byte(s2[i]);
  153. if Chr1 in [97..122] then
  154. dec(Chr1,32);
  155. if Chr2 in [97..122] then
  156. dec(Chr2,32);
  157. result := Chr1 - Chr2;
  158. end ;
  159. if (result = 0) then
  160. result:=(count1-count2);
  161. end;
  162. function SameText(const s1,s2:String):Boolean;
  163. begin
  164. Result:=CompareText(S1,S2)=0;
  165. end;
  166. {==============================================================================}
  167. { Ansi string functions }
  168. { these functions rely on the character set loaded by the OS }
  169. {==============================================================================}
  170. function AnsiUpperCase(const s: string): string;
  171. var len, i: integer;
  172. begin
  173. len := length(s);
  174. SetLength(result, len);
  175. for i := 1 to len do
  176. result[i] := UpperCaseTable[ord(s[i])];
  177. end ;
  178. function AnsiLowerCase(const s: string): string;
  179. var len, i: integer;
  180. begin
  181. len := length(s);
  182. SetLength(result, len);
  183. for i := 1 to len do
  184. result[i] := LowerCaseTable[ord(s[i])];
  185. end ;
  186. function AnsiCompareStr(const S1, S2: string): integer;
  187. Var I,L1,L2 : Longint;
  188. begin
  189. Result:=0;
  190. L1:=Length(S1);
  191. L2:=Length(S2);
  192. I:=1;
  193. While (Result=0) and ((I<=L1) and (I<=L2)) do
  194. begin
  195. Result:=Ord(S1[I])-Ord(S2[I]); //!! Must be replaced by ansi characters !!
  196. Inc(I);
  197. end;
  198. If Result=0 Then
  199. Result:=L1-L2;
  200. end;
  201. function AnsiCompareText(const S1, S2: string): integer;
  202. Var I,L1,L2 : Longint;
  203. begin
  204. Result:=0;
  205. L1:=Length(S1);
  206. L2:=Length(S2);
  207. I:=1;
  208. While (Result=0) and ((I<=L1) and (I<=L2)) do
  209. begin
  210. Result:=Ord(LowerCaseTable[Ord(S1[I])])-Ord(LowerCaseTable[Ord(S2[I])]); //!! Must be replaced by ansi characters !!
  211. Inc(I);
  212. end;
  213. If Result=0 Then
  214. Result:=L1-L2;
  215. end;
  216. function AnsiSameText(const s1,s2:String):Boolean;
  217. begin
  218. AnsiSameText:=AnsiCompareText(S1,S2)=0;
  219. end;
  220. function AnsiSameStr(const s1,s2:String):Boolean;
  221. begin
  222. AnsiSameStr:=AnsiCompareStr(S1,S2)=0;
  223. end;
  224. function AnsiStrComp(S1, S2: PChar): integer;
  225. begin
  226. Result:=0;
  227. If S1=Nil then
  228. begin
  229. If S2=Nil Then Exit;
  230. result:=-1;
  231. exit;
  232. end;
  233. If S2=Nil then
  234. begin
  235. Result:=1;
  236. exit;
  237. end;
  238. Repeat
  239. Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
  240. Inc(S1);
  241. Inc(S2);
  242. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
  243. end;
  244. function AnsiStrIComp(S1, S2: PChar): integer;
  245. begin
  246. Result:=0;
  247. If S1=Nil then
  248. begin
  249. If S2=Nil Then Exit;
  250. result:=-1;
  251. exit;
  252. end;
  253. If S2=Nil then
  254. begin
  255. Result:=1;
  256. exit;
  257. end;
  258. Repeat
  259. Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
  260. Inc(S1);
  261. Inc(S2);
  262. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
  263. end;
  264. function AnsiStrLComp(S1, S2: PChar; MaxLen: cardinal): integer;
  265. Var I : cardinal;
  266. begin
  267. Result:=0;
  268. If MaxLen=0 then exit;
  269. If S1=Nil then
  270. begin
  271. If S2=Nil Then Exit;
  272. result:=-1;
  273. exit;
  274. end;
  275. If S2=Nil then
  276. begin
  277. Result:=1;
  278. exit;
  279. end;
  280. I:=0;
  281. Repeat
  282. Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
  283. Inc(S1);
  284. Inc(S2);
  285. Inc(I);
  286. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
  287. end ;
  288. function AnsiStrLIComp(S1, S2: PChar; MaxLen: cardinal): integer;
  289. Var I : cardinal;
  290. begin
  291. Result:=0;
  292. If MaxLen=0 then exit;
  293. If S1=Nil then
  294. begin
  295. If S2=Nil Then Exit;
  296. result:=-1;
  297. exit;
  298. end;
  299. If S2=Nil then
  300. begin
  301. Result:=1;
  302. exit;
  303. end;
  304. I:=0;
  305. Repeat
  306. Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
  307. Inc(S1);
  308. Inc(S2);
  309. Inc(I);
  310. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
  311. end ;
  312. function AnsiStrLower(Str: PChar): PChar;
  313. begin
  314. result := Str;
  315. if Str <> Nil then begin
  316. while Str^ <> #0 do begin
  317. Str^ := LowerCaseTable[byte(Str^)];
  318. Str := Str + 1;
  319. end ;
  320. end ;
  321. end ;
  322. function AnsiStrUpper(Str: PChar): PChar;
  323. begin
  324. result := Str;
  325. if Str <> Nil then begin
  326. while Str^ <> #0 do begin
  327. Str^ := UpperCaseTable[byte(Str^)];
  328. Str := Str + 1;
  329. end ;
  330. end ;
  331. end ;
  332. function AnsiLastChar(const S: string): PChar;
  333. begin
  334. //!! No multibyte yet, so we return the last one.
  335. result:=StrEnd(Pchar(S));
  336. Dec(Result);
  337. end ;
  338. function AnsiStrLastChar(Str: PChar): PChar;
  339. begin
  340. //!! No multibyte yet, so we return the last one.
  341. result:=StrEnd(Str);
  342. Dec(Result);
  343. end ;
  344. {==============================================================================}
  345. { End of Ansi functions }
  346. {==============================================================================}
  347. { Trim returns a copy of S with blanks characters on the left and right stripped off }
  348. Const WhiteSpace = [' ',#10,#13,#9];
  349. function Trim(const S: string): string;
  350. var Ofs, Len: integer;
  351. begin
  352. len := Length(S);
  353. while (Len>0) and (S[Len] in WhiteSpace) do
  354. dec(Len);
  355. Ofs := 1;
  356. while (Ofs<=Len) and (S[Ofs] in WhiteSpace) do
  357. Inc(Ofs);
  358. result := Copy(S, Ofs, 1 + Len - Ofs);
  359. end ;
  360. { TrimLeft returns a copy of S with all blank characters on the left stripped off }
  361. function TrimLeft(const S: string): string;
  362. var i,l:integer;
  363. begin
  364. l := length(s);
  365. i := 1;
  366. while (i<=l) and (s[i] in whitespace) do
  367. inc(i);
  368. Result := copy(s, i, l);
  369. end ;
  370. { TrimRight returns a copy of S with all blank characters on the right stripped off }
  371. function TrimRight(const S: string): string;
  372. var l:integer;
  373. begin
  374. l := length(s);
  375. while (l>0) and (s[l] in whitespace) do
  376. dec(l);
  377. result := copy(s,1,l);
  378. end ;
  379. { QuotedStr returns S quoted left and right and every single quote in S
  380. replaced by two quotes }
  381. function QuotedStr(const S: string): string;
  382. begin
  383. result := AnsiQuotedStr(s, '''');
  384. end ;
  385. { AnsiQuotedStr returns S quoted left and right by Quote,
  386. and every single occurance of Quote replaced by two }
  387. function AnsiQuotedStr(const S: string; Quote: char): string;
  388. var i, j, count: integer;
  389. begin
  390. result := '' + Quote;
  391. count := length(s);
  392. i := 0;
  393. j := 0;
  394. while i < count do begin
  395. i := i + 1;
  396. if S[i] = Quote then begin
  397. result := result + copy(S, 1 + j, i - j) + Quote;
  398. j := i;
  399. end ;
  400. end ;
  401. if i <> j then
  402. result := result + copy(S, 1 + j, i - j);
  403. result := result + Quote;
  404. end ;
  405. { AnsiExtractQuotedStr returns a copy of Src with quote characters
  406. deleted to the left and right and double occurances
  407. of Quote replaced by a single Quote }
  408. function AnsiExtractQuotedStr(Const Src: PChar; Quote: Char): string;
  409. var i: integer; P, Q: PChar;
  410. begin
  411. P := Src;
  412. if Src^ = Quote then P := P + 1;
  413. Q := StrEnd(P);
  414. if PChar(Q - 1)^ = Quote then Q := Q - 1;
  415. SetLength(result, Q - P);
  416. i := 0;
  417. while P <> Q do begin
  418. i := i + 1;
  419. result[i] := P^;
  420. if (P^ = Quote) and (PChar(P + 1)^ = Quote) then
  421. P := P + 1;
  422. P := P + 1;
  423. end ;
  424. SetLength(result, i);
  425. end ;
  426. { AdjustLineBreaks returns S with all CR characters not followed by LF
  427. replaced with CR/LF }
  428. // under Linux all CR characters or CR/LF combinations should be replaced with LF
  429. function AdjustLineBreaks(const S: string): string;
  430. begin
  431. Result:=AdjustLineBreaks(S,DefaultTextLineBreakStyle);
  432. end;
  433. function AdjustLineBreaks(const S: string; Style: TTextLineBreakStyle): string;
  434. var
  435. Source,Dest: PChar;
  436. DestLen: Integer;
  437. I,J,L: Longint;
  438. begin
  439. Source:=Pointer(S);
  440. L:=Length(S);
  441. DestLen:=L;
  442. I:=1;
  443. while (I<=L) do
  444. begin
  445. case S[i] of
  446. #10: if (Style=tlbsCRLF) then
  447. Inc(DestLen);
  448. #13: if (Style=tlbsCRLF) then
  449. if (I<L) and (S[i+1]=#10) then
  450. Inc(I)
  451. else
  452. Inc(DestLen)
  453. else if (I<L) and (S[I+1]=#10) then
  454. Dec(DestLen);
  455. end;
  456. Inc(I);
  457. end;
  458. if (DestLen=L) then
  459. Result:=S
  460. else
  461. begin
  462. SetLength(Result, DestLen);
  463. FillChar(Result[1],DestLen,0);
  464. Dest := Pointer(Result);
  465. J:=0;
  466. I:=0;
  467. While I<L do
  468. case Source[I] of
  469. #10: begin
  470. if Style=tlbsCRLF then
  471. begin
  472. Dest[j]:=#13;
  473. Inc(J);
  474. end;
  475. Dest[J] := #10;
  476. Inc(J);
  477. Inc(I);
  478. end;
  479. #13: begin
  480. if Style=tlbsCRLF then
  481. begin
  482. Dest[j] := #13;
  483. Inc(J);
  484. end;
  485. Dest[j]:=#10;
  486. Inc(J);
  487. Inc(I);
  488. if Source[I]=#10 then
  489. Inc(I);
  490. end;
  491. else
  492. Dest[j]:=Source[i];
  493. Inc(J);
  494. Inc(I);
  495. end;
  496. end;
  497. end;
  498. { IsValidIdent returns true if the first character of Ident is in:
  499. 'A' to 'Z', 'a' to 'z' or '_' and the following characters are
  500. on of: 'A' to 'Z', 'a' to 'z', '0'..'9' or '_' }
  501. function IsValidIdent(const Ident: string): boolean;
  502. var i, len: integer;
  503. begin
  504. result := false;
  505. len := length(Ident);
  506. if len <> 0 then begin
  507. result := Ident[1] in ['A'..'Z', 'a'..'z', '_'];
  508. i := 1;
  509. while (result) and (i < len) do begin
  510. i := i + 1;
  511. result := result and (Ident[i] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
  512. end ;
  513. end ;
  514. end ;
  515. { IntToStr returns a string representing the value of Value }
  516. function IntToStr(Value: integer): string;
  517. begin
  518. System.Str(Value, result);
  519. end ;
  520. {$IFNDEF VIRTUALPASCAL}
  521. function IntToStr(Value: int64): string;
  522. begin
  523. System.Str(Value, result);
  524. end ;
  525. {$ENDIF}
  526. function IntToStr(Value: QWord): string;
  527. begin
  528. System.Str(Value, result);
  529. end ;
  530. { IntToHex returns a string representing the hexadecimal value of Value }
  531. const
  532. HexDigits: array[0..15] of char = '0123456789ABCDEF';
  533. function IntToHex(Value: integer; Digits: integer): string;
  534. var i: integer;
  535. begin
  536. SetLength(result, digits);
  537. for i := 0 to digits - 1 do
  538. begin
  539. result[digits - i] := HexDigits[value and 15];
  540. value := value shr 4;
  541. end ;
  542. while value <> 0 do begin
  543. result := HexDigits[value and 15] + result;
  544. value := value shr 4;
  545. end;
  546. end ;
  547. {$IFNDEF VIRTUALPASCAL} // overloading
  548. function IntToHex(Value: int64; Digits: integer): string;
  549. var i: integer;
  550. begin
  551. SetLength(result, digits);
  552. for i := 0 to digits - 1 do
  553. begin
  554. result[digits - i] := HexDigits[value and 15];
  555. value := value shr 4;
  556. end ;
  557. while value <> 0 do begin
  558. result := HexDigits[value and 15] + result;
  559. value := value shr 4;
  560. end;
  561. end ;
  562. {$ENDIF}
  563. function TryStrToInt(const s: string; var i : integer) : boolean;
  564. var Error : word;
  565. begin
  566. Val(s, i, Error);
  567. TryStrToInt:=Error=0
  568. end;
  569. { StrToInt converts the string S to an integer value,
  570. if S does not represent a valid integer value EConvertError is raised }
  571. function StrToInt(const S: string): integer;
  572. {$IFDEF VIRTUALPASCAL}
  573. var Error: longint;
  574. {$ELSE}
  575. var Error: word;
  576. {$ENDIF}
  577. begin
  578. Val(S, result, Error);
  579. if Error <> 0 then raise EConvertError.createfmt(SInValidInteger,[S]);
  580. end ;
  581. function StrToInt64(const S: string): int64;
  582. {$IFDEF VIRTUALPASCAL}
  583. var Error: longint;
  584. {$ELSE}
  585. var Error: word;
  586. {$ENDIF}
  587. begin
  588. Val(S, result, Error);
  589. if Error <> 0 then raise EConvertError.createfmt(SInValidInteger,[S]);
  590. end;
  591. function TryStrToInt64(const s: string; var i : int64) : boolean;
  592. var Error : word;
  593. begin
  594. Val(s, i, Error);
  595. TryStrToInt64:=Error=0
  596. end;
  597. { StrToIntDef converts the string S to an integer value,
  598. Default is returned in case S does not represent a valid integer value }
  599. function StrToIntDef(const S: string; Default: integer): integer;
  600. {$IFDEF VIRTUALPASCAL}
  601. var Error: longint;
  602. {$ELSE}
  603. var Error: word;
  604. {$ENDIF}
  605. begin
  606. Val(S, result, Error);
  607. if Error <> 0 then result := Default;
  608. end ;
  609. { StrToIntDef converts the string S to an integer value,
  610. Default is returned in case S does not represent a valid integer value }
  611. function StrToInt64Def(const S: string; Default: int64): int64;
  612. {$IFDEF VIRTUALPASCAL}
  613. var Error: longint;
  614. {$ELSE}
  615. var Error: word;
  616. {$ENDIF}
  617. begin
  618. Val(S, result, Error);
  619. if Error <> 0 then result := Default;
  620. end ;
  621. { LoadStr returns the string resource Ident. }
  622. function LoadStr(Ident: integer): string;
  623. begin
  624. result:='';
  625. end ;
  626. { FmtLoadStr returns the string resource Ident and formats it accordingly }
  627. function FmtLoadStr(Ident: integer; const Args: array of const): string;
  628. begin
  629. result:='';
  630. end;
  631. Const
  632. feInvalidFormat = 1;
  633. feMissingArgument = 2;
  634. feInvalidArgIndex = 3;
  635. {$ifdef fmtdebug}
  636. Procedure Log (Const S: String);
  637. begin
  638. Writeln (S);
  639. end;
  640. {$endif}
  641. Procedure DoFormatError (ErrCode : Longint);
  642. Var
  643. S : String;
  644. begin
  645. //!! must be changed to contain format string...
  646. S:='';
  647. Case ErrCode of
  648. feInvalidFormat : raise EConvertError.Createfmt(SInvalidFormat,[s]);
  649. feMissingArgument : raise EConvertError.Createfmt(SArgumentMissing,[s]);
  650. feInvalidArgIndex : raise EConvertError.Createfmt(SInvalidArgIndex,[s]);
  651. end;
  652. end;
  653. Function Format (Const Fmt : String; const Args : Array of const) : String;
  654. Var ChPos,OldPos,ArgPos,DoArg,Len : Longint;
  655. Hs,ToAdd : String;
  656. Index,Width,Prec : Longint;
  657. Left : Boolean;
  658. Fchar : char;
  659. {
  660. ReadFormat reads the format string. It returns the type character in
  661. uppercase, and sets index, Width, Prec to their correct values,
  662. or -1 if not set. It sets Left to true if left alignment was requested.
  663. In case of an error, DoFormatError is called.
  664. }
  665. Function ReadFormat : Char;
  666. Var Value : longint;
  667. Procedure ReadInteger;
  668. {$IFDEF VIRTUALPASCAL}
  669. var Code: longint;
  670. {$ELSE}
  671. var Code: word;
  672. {$ENDIF}
  673. begin
  674. If Value<>-1 then exit; // Was already read.
  675. OldPos:=chPos;
  676. While (Chpos<=Len) and
  677. (Pos(Fmt[chpos],'1234567890')<>0) do inc(chpos);
  678. If Chpos>len then
  679. DoFormatError(feInvalidFormat);
  680. If Fmt[Chpos]='*' then
  681. begin
  682. If (Chpos>OldPos) or (ArgPos>High(Args))
  683. or (Args[ArgPos].Vtype<>vtInteger) then
  684. DoFormatError(feInvalidFormat);
  685. Value:=Args[ArgPos].VInteger;
  686. Inc(ArgPos);
  687. Inc(chPos);
  688. end
  689. else
  690. begin
  691. If (OldPos<chPos) Then
  692. begin
  693. Val (Copy(Fmt,OldPos,ChPos-OldPos),value,code);
  694. // This should never happen !!
  695. If Code>0 then DoFormatError (feInvalidFormat);
  696. end
  697. else
  698. Value:=-1;
  699. end;
  700. end;
  701. Procedure ReadIndex;
  702. begin
  703. ReadInteger;
  704. If Fmt[ChPos]=':' then
  705. begin
  706. If Value=-1 then DoFormatError(feMissingArgument);
  707. Index:=Value;
  708. Value:=-1;
  709. Inc(Chpos);
  710. end;
  711. {$ifdef fmtdebug}
  712. Log ('Read index');
  713. {$endif}
  714. end;
  715. Procedure ReadLeft;
  716. begin
  717. If Fmt[chpos]='-' then
  718. begin
  719. left:=True;
  720. Inc(chpos);
  721. end
  722. else
  723. Left:=False;
  724. {$ifdef fmtdebug}
  725. Log ('Read Left');
  726. {$endif}
  727. end;
  728. Procedure ReadWidth;
  729. begin
  730. ReadInteger;
  731. If Value<>-1 then
  732. begin
  733. Width:=Value;
  734. Value:=-1;
  735. end;
  736. {$ifdef fmtdebug}
  737. Log ('Read width');
  738. {$endif}
  739. end;
  740. Procedure ReadPrec;
  741. begin
  742. If Fmt[chpos]='.' then
  743. begin
  744. inc(chpos);
  745. ReadInteger;
  746. If Value=-1 then
  747. Value:=0;
  748. prec:=Value;
  749. end;
  750. {$ifdef fmtdebug}
  751. Log ('Read precision');
  752. {$endif}
  753. end;
  754. begin
  755. {$ifdef fmtdebug}
  756. Log ('Start format');
  757. {$endif}
  758. Index:=-1;
  759. Width:=-1;
  760. Prec:=-1;
  761. Value:=-1;
  762. inc(chpos);
  763. If Fmt[Chpos]='%' then
  764. begin
  765. Result:='%';
  766. exit; // VP fix
  767. end;
  768. ReadIndex;
  769. ReadLeft;
  770. ReadWidth;
  771. ReadPrec;
  772. ReadFormat:=Upcase(Fmt[ChPos]);
  773. {$ifdef fmtdebug}
  774. Log ('End format');
  775. {$endif}
  776. end;
  777. {$ifdef fmtdebug}
  778. Procedure DumpFormat (C : char);
  779. begin
  780. Write ('Fmt : ',fmt:10);
  781. Write (' Index : ',Index:3);
  782. Write (' Left : ',left:5);
  783. Write (' Width : ',Width:3);
  784. Write (' Prec : ',prec:3);
  785. Writeln (' Type : ',C);
  786. end;
  787. {$endif}
  788. function Checkarg (AT : Longint;err:boolean):boolean;
  789. {
  790. Check if argument INDEX is of correct type (AT)
  791. If Index=-1, ArgPos is used, and argpos is augmented with 1
  792. DoArg is set to the argument that must be used.
  793. }
  794. begin
  795. result:=false;
  796. if Index=-1 then
  797. DoArg:=Argpos
  798. else
  799. DoArg:=Index;
  800. ArgPos:=DoArg+1;
  801. If (Doarg>High(Args)) or (Args[Doarg].Vtype<>AT) then
  802. begin
  803. if err then
  804. DoFormatError(feInvalidArgindex);
  805. dec(ArgPos);
  806. exit;
  807. end;
  808. result:=true;
  809. end;
  810. Const Zero = '000000000000000000000000000000000000000000000000000000000000000';
  811. begin
  812. Result:='';
  813. Len:=Length(Fmt);
  814. Chpos:=1;
  815. OldPos:=1;
  816. ArgPos:=0;
  817. While chpos<=len do
  818. begin
  819. While (ChPos<=Len) and (Fmt[chpos]<>'%') do
  820. inc(chpos);
  821. If ChPos>OldPos Then
  822. Result:=Result+Copy(Fmt,OldPos,Chpos-Oldpos);
  823. If ChPos<Len then
  824. begin
  825. FChar:=ReadFormat;
  826. {$ifdef fmtdebug}
  827. DumpFormat(FCHar);
  828. {$endif}
  829. Case FChar of
  830. 'D' : begin
  831. if Checkarg(vtinteger,false) then
  832. Str(Args[Doarg].VInteger,ToAdd)
  833. {$IFNDEF VIRTUALPASCAL}
  834. else if CheckArg(vtInt64,true) then
  835. Str(Args[DoArg].VInt64^,toadd)
  836. {$ENDIF}
  837. ;
  838. Width:=Abs(width);
  839. Index:=Prec-Length(ToAdd);
  840. If ToAdd[1]<>'-' then
  841. ToAdd:=StringOfChar('0',Index)+ToAdd
  842. else
  843. // + 1 to accomodate for - sign in length !!
  844. Insert(StringOfChar('0',Index+1),toadd,2);
  845. end;
  846. 'E' : begin
  847. CheckArg(vtExtended,true);
  848. ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffexponent,Prec,3);
  849. end;
  850. 'F' : begin
  851. CheckArg(vtExtended,true);
  852. ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffFixed,9999,Prec);
  853. end;
  854. 'G' : begin
  855. CheckArg(vtExtended,true);
  856. ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffGeneral,Prec,3);
  857. end;
  858. 'N' : begin
  859. CheckArg(vtExtended,true);
  860. ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffNumber,9999,Prec);
  861. end;
  862. 'M' : begin
  863. CheckArg(vtExtended,true);
  864. ToAdd:=FloatToStrF(Args[doarg].VExtended^,ffCurrency,9999,Prec);
  865. end;
  866. 'S' : begin
  867. if CheckArg(vtString,false) then
  868. hs:=Args[doarg].VString^
  869. else
  870. if CheckArg(vtChar,false) then
  871. hs:=Args[doarg].VChar
  872. else
  873. if CheckArg(vtPChar,false) then
  874. hs:=Args[doarg].VPChar
  875. else
  876. if CheckArg(vtPWideChar,false) then
  877. hs:=char(Args[doarg].VPWideChar^)
  878. else
  879. if CheckArg(vtWideChar,false) then
  880. hs:=char(Args[doarg].VWideChar)
  881. else
  882. if CheckArg(vtWidestring,false) then
  883. hs:=ansistring(Args[doarg].VWideString)
  884. else
  885. if CheckArg(vtAnsiString,true) then
  886. hs:=ansistring(Args[doarg].VAnsiString);
  887. Index:=Length(hs);
  888. If (Prec<>-1) and (Index>Prec) then
  889. Index:=Prec;
  890. ToAdd:=Copy(hs,1,Index);
  891. end;
  892. 'P' : Begin
  893. CheckArg(vtpointer,true);
  894. ToAdd:=HexStr(ptrint(Args[DoArg].VPointer),sizeof(Ptrint)*2);
  895. // Insert ':'. Is this needed in 32 bit ? No it isn't.
  896. // Insert(':',ToAdd,5);
  897. end;
  898. 'X' : begin
  899. Checkarg(vtinteger,true);
  900. If Prec>15 then
  901. ToAdd:=HexStr(Args[Doarg].VInteger,15)
  902. else
  903. begin
  904. // determine minimum needed number of hex digits.
  905. Index:=1;
  906. While (DWord(1 shl (Index*4))<=DWord(Args[DoArg].VInteger)) and (index<8) do
  907. inc(Index);
  908. If Index>Prec then
  909. Prec:=Index;
  910. ToAdd:=HexStr(Args[DoArg].VInteger,Prec);
  911. end;
  912. end;
  913. '%': ToAdd:='%';
  914. end;
  915. If Width<>-1 then
  916. If Length(ToAdd)<Width then
  917. If not Left then
  918. ToAdd:=Space(Width-Length(ToAdd))+ToAdd
  919. else
  920. ToAdd:=ToAdd+space(Width-Length(ToAdd));
  921. Result:=Result+ToAdd;
  922. end;
  923. inc(chpos);
  924. Oldpos:=chpos;
  925. end;
  926. end;
  927. Function FormatBuf (Var Buffer; BufLen : Cardinal;
  928. Const Fmt; fmtLen : Cardinal;
  929. Const Args : Array of const) : Cardinal;
  930. Var S,F : String;
  931. begin
  932. Setlength(F,fmtlen);
  933. if fmtlen > 0 then
  934. Move(fmt,F[1],fmtlen);
  935. S:=Format (F,Args);
  936. If Cardinal(Length(S))<Buflen then
  937. Result:=Length(S)
  938. else
  939. Result:=Buflen;
  940. Move(S[1],Buffer,Result);
  941. end;
  942. Procedure FmtStr(Var Res: String; Const Fmt : String; Const args: Array of const);
  943. begin
  944. Res:=Format(fmt,Args);
  945. end;
  946. Function StrFmt(Buffer,Fmt : PChar; Const args: Array of const) : Pchar;
  947. begin
  948. Buffer[FormatBuf(Buffer^,Maxint,Fmt^,strlen(fmt),args)]:=#0;
  949. Result:=Buffer;
  950. end;
  951. Function StrLFmt(Buffer : PCHar; Maxlen : Cardinal;Fmt : PChar; Const args: Array of const) : Pchar;
  952. begin
  953. Buffer[FormatBuf(Buffer^,MaxLen,Fmt^,strlen(fmt),args)]:=#0;
  954. Result:=Buffer;
  955. end;
  956. Function StrToFloat(Const S: String): Extended;
  957. Begin
  958. If Not TextToFloat(Pchar(S),Result) then
  959. Raise EConvertError.createfmt(SInValidFLoat,[S]);
  960. End;
  961. function StrToFloatDef(const S: string; const Default: Extended): Extended;
  962. begin
  963. if not TextToFloat(PChar(S),Result,fvExtended) then
  964. Result:=Default;
  965. end;
  966. Function TextToFloat(Buffer: PChar; Var Value: Extended): Boolean;
  967. Var
  968. E,P : Integer;
  969. S : String;
  970. Begin
  971. S:=StrPas(Buffer);
  972. P:=Pos(DecimalSeparator,S);
  973. If (P<>0) Then
  974. S[P] := '.';
  975. Val(S,Value,E);
  976. Result:=(E=0);
  977. End;
  978. Function TextToFloat(Buffer: PChar; Var Value; ValueType: TFloatValue): Boolean;
  979. Var
  980. E,P : Integer;
  981. S : String;
  982. C : Currency;
  983. Ext : Extended;
  984. Begin
  985. S:=StrPas(Buffer);
  986. P:=Pos(ThousandSeparator,S);
  987. While (P<>0) do
  988. begin
  989. Delete(S,P,1);
  990. P:=Pos(ThousandSeparator,S);
  991. end;
  992. P:=Pos(DecimalSeparator,S);
  993. If (P<>0) Then
  994. S[P] := '.';
  995. case ValueType of
  996. fvCurrency:
  997. Val(S,Currency(Value),E);
  998. fvExtended:
  999. Val(S,Extended(Value),E);
  1000. fvDouble:
  1001. Val(S,Double(Value),E);
  1002. fvSingle:
  1003. Val(S,Single(Value),E);
  1004. fvComp:
  1005. Val(S,Comp(Value),E);
  1006. fvReal:
  1007. Val(S,Real(Value),E);
  1008. end;
  1009. Result:=(E=0);
  1010. End;
  1011. Function FloatToStr(Value: Extended): String;
  1012. Begin
  1013. Result := FloatToStrF(Value, ffGeneral, 15, 0);
  1014. End;
  1015. Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat; Precision, Digits: Integer): Longint;
  1016. Var
  1017. Tmp: String[40];
  1018. Begin
  1019. Tmp := FloatToStrF(Value, format, Precision, Digits);
  1020. Result := Length(Tmp);
  1021. Move(Tmp[1], Buffer[0], Result);
  1022. End;
  1023. Function FloatToStrF(Value: Extended; format: TFloatFormat; Precision, Digits: Integer): String;
  1024. Var
  1025. P: Integer;
  1026. Negative, TooSmall, TooLarge: Boolean;
  1027. Begin
  1028. Case format Of
  1029. ffGeneral:
  1030. Begin
  1031. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  1032. TooSmall := (Abs(Value) < 0.00001) and (Value>0.0);
  1033. If Not TooSmall Then
  1034. Begin
  1035. Str(Value:0:999, Result);
  1036. P := Pos('.', Result);
  1037. Result[P] := DecimalSeparator;
  1038. TooLarge := P > Precision + 1;
  1039. End;
  1040. If TooSmall Or TooLarge Then
  1041. begin
  1042. Result := FloatToStrF(Value, ffExponent, Precision, Digits);
  1043. // Strip unneeded zeroes.
  1044. P:=Pos('E',result)-1;
  1045. If P<>-1 then
  1046. While (P>1) and (Result[P]='0') do
  1047. begin
  1048. system.Delete(Result,P,1);
  1049. Dec(P);
  1050. end;
  1051. end
  1052. else
  1053. begin
  1054. P := Length(Result);
  1055. While Result[P] = '0' Do Dec(P);
  1056. If Result[P] = DecimalSeparator Then Dec(P);
  1057. SetLength(Result, P);
  1058. end;
  1059. End;
  1060. ffExponent:
  1061. Begin
  1062. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  1063. Str(Value:Precision + 8, Result);
  1064. Result[3] := DecimalSeparator;
  1065. P:=4;
  1066. While (P>0) and (Digits < P) And (Result[Precision + 5] = '0') do
  1067. Begin
  1068. If P<>1 then
  1069. system.Delete(Result, Precision + 5, 1)
  1070. else
  1071. system.Delete(Result, Precision + 3, 3);
  1072. Dec(P);
  1073. end;
  1074. If Result[1] = ' ' Then
  1075. System.Delete(Result, 1, 1);
  1076. End;
  1077. ffFixed:
  1078. Begin
  1079. If Digits = -1 Then Digits := 2
  1080. Else If Digits > 18 Then Digits := 18;
  1081. Str(Value:0:Digits, Result);
  1082. If Result[1] = ' ' Then
  1083. System.Delete(Result, 1, 1);
  1084. P := Pos('.', Result);
  1085. If P <> 0 Then Result[P] := DecimalSeparator;
  1086. End;
  1087. ffNumber:
  1088. Begin
  1089. If Digits = -1 Then Digits := 2
  1090. Else If Digits > 15 Then Digits := 15;
  1091. Str(Value:0:Digits, Result);
  1092. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  1093. P := Pos('.', Result);
  1094. If P <> 0 Then
  1095. Result[P] := DecimalSeparator
  1096. else
  1097. P := Length(Result)+1;
  1098. Dec(P, 3);
  1099. While (P > 1) Do
  1100. Begin
  1101. If Result[P - 1] <> '-' Then Insert(ThousandSeparator, Result, P);
  1102. Dec(P, 3);
  1103. End;
  1104. End;
  1105. ffCurrency:
  1106. Begin
  1107. If Value < 0 Then
  1108. Begin
  1109. Negative := True;
  1110. Value := -Value;
  1111. End
  1112. Else Negative := False;
  1113. If Digits = -1 Then Digits := CurrencyDecimals
  1114. Else If Digits > 18 Then Digits := 18;
  1115. Str(Value:0:Digits, Result);
  1116. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  1117. P := Pos('.', Result);
  1118. If P <> 0 Then Result[P] := DecimalSeparator;
  1119. Dec(P, 3);
  1120. While (P > 1) Do
  1121. Begin
  1122. Insert(ThousandSeparator, Result, P);
  1123. Dec(P, 3);
  1124. End;
  1125. If Not Negative Then
  1126. Begin
  1127. Case CurrencyFormat Of
  1128. 0: Result := CurrencyString + Result;
  1129. 1: Result := Result + CurrencyString;
  1130. 2: Result := CurrencyString + ' ' + Result;
  1131. 3: Result := Result + ' ' + CurrencyString;
  1132. End
  1133. End
  1134. Else
  1135. Begin
  1136. Case NegCurrFormat Of
  1137. 0: Result := '(' + CurrencyString + Result + ')';
  1138. 1: Result := '-' + CurrencyString + Result;
  1139. 2: Result := CurrencyString + '-' + Result;
  1140. 3: Result := CurrencyString + Result + '-';
  1141. 4: Result := '(' + Result + CurrencyString + ')';
  1142. 5: Result := '-' + Result + CurrencyString;
  1143. 6: Result := Result + '-' + CurrencyString;
  1144. 7: Result := Result + CurrencyString + '-';
  1145. 8: Result := '-' + Result + ' ' + CurrencyString;
  1146. 9: Result := '-' + CurrencyString + ' ' + Result;
  1147. 10: Result := CurrencyString + ' ' + Result + '-';
  1148. End;
  1149. End;
  1150. End;
  1151. End;
  1152. End;
  1153. Function FloatToDateTime (Const Value : Extended) : TDateTime;
  1154. begin
  1155. If (Value<MinDateTime) or (Value>MaxDateTime) then
  1156. Raise EConvertError.CreateFmt (SInvalidDateTime,[Value]);
  1157. Result:=Value;
  1158. end;
  1159. function TryFloatToCurr(const Value: Extended; var AResult: Currency): Boolean;
  1160. begin
  1161. {$ifndef VER1_0}
  1162. Result:=(Value>=MinCurrency) and (Value<=MaxCurrency);
  1163. if Result then
  1164. AResult := Value;
  1165. {$else VER1_0}
  1166. Result:=false;
  1167. {$endif VER1_0}
  1168. end;
  1169. function FloatToCurr(const Value: Extended): Currency;
  1170. begin
  1171. if not TryFloatToCurr(Value, Result) then
  1172. Raise EConvertError.CreateFmt(SInvalidCurrency, [FloatToStr(Value)]);
  1173. end;
  1174. Function CurrToStr(Value: Currency): string;
  1175. begin
  1176. Result:=FloatToStrF(Value,ffNumber,15,2);
  1177. end;
  1178. function StrToCurr(const S: string): Currency;
  1179. begin
  1180. if not TextToFloat(PChar(S), Result, fvCurrency) then
  1181. Raise EConvertError.createfmt(SInValidFLoat,[S]);
  1182. end;
  1183. function StrToCurrDef(const S: string; Default : Currency): Currency;
  1184. begin
  1185. if not TextToFloat(PChar(S), Result, fvCurrency) then
  1186. Result:=Default;
  1187. end;
  1188. function StrToBool(const S: string): Boolean;
  1189. Var
  1190. Temp : String;
  1191. D : Double;
  1192. {$IFDEF VIRTUALPASCAL}
  1193. Code: longint;
  1194. {$ELSE}
  1195. Code: word;
  1196. {$ENDIF}
  1197. begin
  1198. Temp:=upcase(S);
  1199. Val(temp,D,code);
  1200. If Code=0 then
  1201. Result:=(D<>0.0)
  1202. else If Temp='TRUE' then
  1203. result:=true
  1204. else if Temp='FALSE' then
  1205. result:=false
  1206. else
  1207. Raise EConvertError.CreateFmt(SInvalidBoolean,[S]);
  1208. end;
  1209. function BoolToStr(B: Boolean): string;
  1210. begin
  1211. If B then
  1212. Result:='TRUE'
  1213. else
  1214. Result:='FALSE';
  1215. end;
  1216. Function FloatToTextFmt(Buffer: PChar; Value: Extended; format: PChar): Integer;
  1217. Var
  1218. Digits: String[40]; { String Of Digits }
  1219. Exponent: String[8]; { Exponent strin }
  1220. FmtStart, FmtStop: PChar; { Start And End Of relevant part }
  1221. { Of format String }
  1222. ExpFmt, ExpSize: Integer; { Type And Length Of }
  1223. { exponential format chosen }
  1224. Placehold: Array[1..4] Of Integer; { Number Of placeholders In All }
  1225. { four Sections }
  1226. thousand: Boolean; { thousand separators? }
  1227. UnexpectedDigits: Integer; { Number Of unexpected Digits that }
  1228. { have To be inserted before the }
  1229. { First placeholder. }
  1230. DigitExponent: Integer; { Exponent Of First digit In }
  1231. { Digits Array. }
  1232. { Find end of format section starting at P. False, if empty }
  1233. Function GetSectionEnd(Var P: PChar): Boolean;
  1234. Var
  1235. C: Char;
  1236. SQ, DQ: Boolean;
  1237. Begin
  1238. Result := False;
  1239. SQ := False;
  1240. DQ := False;
  1241. C := P[0];
  1242. While (C<>#0) And ((C<>';') Or SQ Or DQ) Do
  1243. Begin
  1244. Result := True;
  1245. Case C Of
  1246. #34: If Not SQ Then DQ := Not DQ;
  1247. #39: If Not DQ Then SQ := Not SQ;
  1248. End;
  1249. Inc(P);
  1250. C := P[0];
  1251. End;
  1252. End;
  1253. { Find start and end of format section to apply. If section doesn't exist,
  1254. use section 1. If section 2 is used, the sign of value is ignored. }
  1255. Procedure GetSectionRange(section: Integer);
  1256. Var
  1257. Sec: Array[1..3] Of PChar;
  1258. SecOk: Array[1..3] Of Boolean;
  1259. Begin
  1260. Sec[1] := format;
  1261. SecOk[1] := GetSectionEnd(Sec[1]);
  1262. If section > 1 Then
  1263. Begin
  1264. Sec[2] := Sec[1];
  1265. If Sec[2][0] <> #0 Then
  1266. Inc(Sec[2]);
  1267. SecOk[2] := GetSectionEnd(Sec[2]);
  1268. If section > 2 Then
  1269. Begin
  1270. Sec[3] := Sec[2];
  1271. If Sec[3][0] <> #0 Then
  1272. Inc(Sec[3]);
  1273. SecOk[3] := GetSectionEnd(Sec[3]);
  1274. End;
  1275. End;
  1276. If Not SecOk[1] Then
  1277. FmtStart := Nil
  1278. Else
  1279. Begin
  1280. If Not SecOk[section] Then
  1281. section := 1
  1282. Else If section = 2 Then
  1283. Value := -Value; { Remove sign }
  1284. If section = 1 Then FmtStart := format Else
  1285. Begin
  1286. FmtStart := Sec[section - 1];
  1287. Inc(FmtStart);
  1288. End;
  1289. FmtStop := Sec[section];
  1290. End;
  1291. End;
  1292. { Find format section ranging from FmtStart to FmtStop. }
  1293. Procedure GetFormatOptions;
  1294. Var
  1295. Fmt: PChar;
  1296. SQ, DQ: Boolean;
  1297. area: Integer;
  1298. Begin
  1299. SQ := False;
  1300. DQ := False;
  1301. Fmt := FmtStart;
  1302. ExpFmt := 0;
  1303. area := 1;
  1304. thousand := False;
  1305. Placehold[1] := 0;
  1306. Placehold[2] := 0;
  1307. Placehold[3] := 0;
  1308. Placehold[4] := 0;
  1309. While Fmt < FmtStop Do
  1310. Begin
  1311. Case Fmt[0] Of
  1312. #34:
  1313. Begin
  1314. If Not SQ Then
  1315. DQ := Not DQ;
  1316. Inc(Fmt);
  1317. End;
  1318. #39:
  1319. Begin
  1320. If Not DQ Then
  1321. SQ := Not SQ;
  1322. Inc(Fmt);
  1323. End;
  1324. Else
  1325. { This was 'if not SQ or DQ'. Looked wrong... }
  1326. If Not SQ Or DQ Then
  1327. Begin
  1328. Case Fmt[0] Of
  1329. '0':
  1330. Begin
  1331. Case area Of
  1332. 1:
  1333. area := 2;
  1334. 4:
  1335. Begin
  1336. area := 3;
  1337. Inc(Placehold[3], Placehold[4]);
  1338. Placehold[4] := 0;
  1339. End;
  1340. End;
  1341. Inc(Placehold[area]);
  1342. Inc(Fmt);
  1343. End;
  1344. '#':
  1345. Begin
  1346. If area=3 Then
  1347. area:=4;
  1348. Inc(Placehold[area]);
  1349. Inc(Fmt);
  1350. End;
  1351. '.':
  1352. Begin
  1353. If area<3 Then
  1354. area:=3;
  1355. Inc(Fmt);
  1356. End;
  1357. ',':
  1358. Begin
  1359. thousand := True;
  1360. Inc(Fmt);
  1361. End;
  1362. 'e', 'E':
  1363. If ExpFmt = 0 Then
  1364. Begin
  1365. If (Fmt[0]='E') Then
  1366. ExpFmt:=1
  1367. Else
  1368. ExpFmt := 3;
  1369. Inc(Fmt);
  1370. If (Fmt<FmtStop) Then
  1371. Begin
  1372. Case Fmt[0] Of
  1373. '+':
  1374. Begin
  1375. End;
  1376. '-':
  1377. Inc(ExpFmt);
  1378. Else
  1379. ExpFmt := 0;
  1380. End;
  1381. If ExpFmt <> 0 Then
  1382. Begin
  1383. Inc(Fmt);
  1384. ExpSize := 0;
  1385. While (Fmt<FmtStop) And
  1386. (ExpSize<4) And
  1387. (Fmt[0] In ['0'..'9']) Do
  1388. Begin
  1389. Inc(ExpSize);
  1390. Inc(Fmt);
  1391. End;
  1392. End;
  1393. End;
  1394. End
  1395. Else
  1396. Inc(Fmt);
  1397. Else { Case }
  1398. Inc(Fmt);
  1399. End; { Case }
  1400. End; { Begin }
  1401. End; { Case }
  1402. End; { While .. Begin }
  1403. End;
  1404. Procedure FloatToStr;
  1405. Var
  1406. I, J, Exp, Width, Decimals, DecimalPoint, len: Integer;
  1407. Begin
  1408. If ExpFmt = 0 Then
  1409. Begin
  1410. { Fixpoint }
  1411. Decimals:=Placehold[3]+Placehold[4];
  1412. Width:=Placehold[1]+Placehold[2]+Decimals;
  1413. If (Decimals=0) Then
  1414. Str(Value:Width:0,Digits)
  1415. Else
  1416. Str(Value:Width+1:Decimals,Digits);
  1417. len:=Length(Digits);
  1418. { Find the decimal point }
  1419. If (Decimals=0) Then
  1420. DecimalPoint:=len+1
  1421. Else
  1422. DecimalPoint:=len-Decimals;
  1423. { If value is very small, and no decimal places
  1424. are desired, remove the leading 0. }
  1425. If (Abs(Value) < 1) And (Placehold[2] = 0) Then
  1426. Begin
  1427. If (Placehold[1]=0) Then
  1428. Delete(Digits,DecimalPoint-1,1)
  1429. Else
  1430. Digits[DecimalPoint-1]:=' ';
  1431. End;
  1432. { Convert optional zeroes to spaces. }
  1433. I:=len;
  1434. J:=DecimalPoint+Placehold[3];
  1435. While (I>J) And (Digits[I]='0') Do
  1436. Begin
  1437. Digits[I] := ' ';
  1438. Dec(I);
  1439. End;
  1440. { If integer value and no obligatory decimal
  1441. places, remove decimal point. }
  1442. If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then
  1443. Digits[DecimalPoint] := ' ';
  1444. { Convert spaces left from obligatory decimal point to zeroes. }
  1445. I:=DecimalPoint-Placehold[2];
  1446. While (I<DecimalPoint) And (Digits[I]=' ') Do
  1447. Begin
  1448. Digits[I] := '0';
  1449. Inc(I);
  1450. End;
  1451. Exp := 0;
  1452. End
  1453. Else
  1454. Begin
  1455. { Scientific: exactly <Width> Digits With <Precision> Decimals
  1456. And adjusted Exponent. }
  1457. If Placehold[1]+Placehold[2]=0 Then
  1458. Placehold[1]:=1;
  1459. Decimals := Placehold[3] + Placehold[4];
  1460. Width:=Placehold[1]+Placehold[2]+Decimals;
  1461. Str(Value:Width+8,Digits);
  1462. { Find and cut out exponent. Always the
  1463. last 6 characters in the string.
  1464. -> 0000E+0000 }
  1465. I:=Length(Digits)-5;
  1466. Val(Copy(Digits,I+1,5),Exp,J);
  1467. Exp:=Exp+1-(Placehold[1]+Placehold[2]);
  1468. Delete(Digits, I, 6);
  1469. { Str() always returns at least one digit after the decimal point.
  1470. If we don't want it, we have to remove it. }
  1471. If (Decimals=0) And (Placehold[1]+Placehold[2]<= 1) Then
  1472. Begin
  1473. If (Digits[4]>='5') Then
  1474. Begin
  1475. Inc(Digits[2]);
  1476. If (Digits[2]>'9') Then
  1477. Begin
  1478. Digits[2] := '1';
  1479. Inc(Exp);
  1480. End;
  1481. End;
  1482. Delete(Digits, 3, 2);
  1483. DecimalPoint := Length(Digits) + 1;
  1484. End
  1485. Else
  1486. Begin
  1487. { Move decimal point at the desired position }
  1488. Delete(Digits, 3, 1);
  1489. DecimalPoint:=2+Placehold[1]+Placehold[2];
  1490. If (Decimals<>0) Then
  1491. Insert('.',Digits,DecimalPoint);
  1492. End;
  1493. { Convert optional zeroes to spaces. }
  1494. I := Length(Digits);
  1495. J := DecimalPoint + Placehold[3];
  1496. While (I > J) And (Digits[I] = '0') Do
  1497. Begin
  1498. Digits[I] := ' ';
  1499. Dec(I);
  1500. End;
  1501. { If integer number and no obligatory decimal paces, remove decimal point }
  1502. If (DecimalPoint<Length(Digits)) And
  1503. (Digits[DecimalPoint+1]=' ') Then
  1504. Digits[DecimalPoint]:=' ';
  1505. If (Digits[1]=' ') Then
  1506. Begin
  1507. Delete(Digits, 1, 1);
  1508. Dec(DecimalPoint);
  1509. End;
  1510. { Calculate exponent string }
  1511. Str(Abs(Exp), Exponent);
  1512. While Length(Exponent)<ExpSize Do
  1513. Insert('0',Exponent,1);
  1514. If Exp >= 0 Then
  1515. Begin
  1516. If (ExpFmt In [1,3]) Then
  1517. Insert('+', Exponent, 1);
  1518. End
  1519. Else
  1520. Insert('-',Exponent,1);
  1521. If (ExpFmt<3) Then
  1522. Insert('E',Exponent,1)
  1523. Else
  1524. Insert('e',Exponent,1);
  1525. End;
  1526. DigitExponent:=DecimalPoint-2;
  1527. If (Digits[1]='-') Then
  1528. Dec(DigitExponent);
  1529. UnexpectedDigits:=DecimalPoint-1-(Placehold[1]+Placehold[2]);
  1530. End;
  1531. Function PutResult: LongInt;
  1532. Var
  1533. SQ, DQ: Boolean;
  1534. Fmt, Buf: PChar;
  1535. Dig, N: Integer;
  1536. Begin
  1537. SQ := False;
  1538. DQ := False;
  1539. Fmt := FmtStart;
  1540. Buf := Buffer;
  1541. Dig := 1;
  1542. While (Fmt<FmtStop) Do
  1543. Begin
  1544. //Write(Fmt[0]);
  1545. Case Fmt[0] Of
  1546. #34:
  1547. Begin
  1548. If Not SQ Then
  1549. DQ := Not DQ;
  1550. Inc(Fmt);
  1551. End;
  1552. #39:
  1553. Begin
  1554. If Not DQ Then
  1555. SQ := Not SQ;
  1556. Inc(Fmt);
  1557. End;
  1558. Else
  1559. If Not (SQ Or DQ) Then
  1560. Begin
  1561. Case Fmt[0] Of
  1562. '0', '#', '.':
  1563. Begin
  1564. If (Dig=1) And (UnexpectedDigits>0) Then
  1565. Begin
  1566. { Everything unexpected is written before the first digit }
  1567. For N := 1 To UnexpectedDigits Do
  1568. Begin
  1569. Buf[0] := Digits[N];
  1570. Inc(Buf);
  1571. If thousand And (Digits[N]<>'-') Then
  1572. Begin
  1573. If (DigitExponent Mod 3 = 0) And (DigitExponent>0) Then
  1574. Begin
  1575. Buf[0] := ThousandSeparator;
  1576. Inc(Buf);
  1577. End;
  1578. Dec(DigitExponent);
  1579. End;
  1580. End;
  1581. Inc(Dig, UnexpectedDigits);
  1582. End;
  1583. If (Digits[Dig]<>' ') Then
  1584. Begin
  1585. If (Digits[Dig]='.') Then
  1586. Buf[0] := DecimalSeparator
  1587. Else
  1588. Buf[0] := Digits[Dig];
  1589. Inc(Buf);
  1590. If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then
  1591. Begin
  1592. Buf[0] := ThousandSeparator;
  1593. Inc(Buf);
  1594. End;
  1595. End;
  1596. Inc(Dig);
  1597. Dec(DigitExponent);
  1598. Inc(Fmt);
  1599. End;
  1600. 'e', 'E':
  1601. Begin
  1602. If ExpFmt <> 0 Then
  1603. Begin
  1604. Inc(Fmt);
  1605. If Fmt < FmtStop Then
  1606. Begin
  1607. If Fmt[0] In ['+', '-'] Then
  1608. Begin
  1609. Inc(Fmt, ExpSize);
  1610. For N:=1 To Length(Exponent) Do
  1611. Buf[N-1] := Exponent[N];
  1612. Inc(Buf,Length(Exponent));
  1613. ExpFmt:=0;
  1614. End;
  1615. Inc(Fmt);
  1616. End;
  1617. End
  1618. Else
  1619. Begin
  1620. { No legal exponential format.
  1621. Simply write the 'E' to the result. }
  1622. Buf[0] := Fmt[0];
  1623. Inc(Buf);
  1624. Inc(Fmt);
  1625. End;
  1626. End;
  1627. Else { Case }
  1628. { Usual character }
  1629. If (Fmt[0]<>',') Then
  1630. Begin
  1631. Buf[0] := Fmt[0];
  1632. Inc(Buf);
  1633. End;
  1634. Inc(Fmt);
  1635. End; { Case }
  1636. End
  1637. Else { IF }
  1638. Begin
  1639. { Character inside single or double quotes }
  1640. Buf[0] := Fmt[0];
  1641. Inc(Buf);
  1642. Inc(Fmt);
  1643. End;
  1644. End; { Case }
  1645. End; { While .. Begin }
  1646. Result:=PtrInt(Buf)-PtrInt(Buffer);
  1647. End;
  1648. Begin
  1649. If (Value>0) Then
  1650. GetSectionRange(1)
  1651. Else If (Value<0) Then
  1652. GetSectionRange(2)
  1653. Else
  1654. GetSectionRange(3);
  1655. If FmtStart = Nil Then
  1656. Begin
  1657. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4);
  1658. End
  1659. Else
  1660. Begin
  1661. GetFormatOptions;
  1662. If (ExpFmt = 0) And (Abs(Value) >= 1E18) Then
  1663. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4)
  1664. Else
  1665. Begin
  1666. FloatToStr;
  1667. Result := PutResult;
  1668. End;
  1669. End;
  1670. End;
  1671. Procedure FloatToDecimal(Var Result: TFloatRec; Value: Extended; Precision, Decimals : integer);
  1672. Var
  1673. Buffer: String[24];
  1674. Error, N: Integer;
  1675. Begin
  1676. Str(Value:23, Buffer);
  1677. Result.Negative := (Buffer[1] = '-');
  1678. Val(Copy(Buffer, 19, 5), Result.Exponent, Error);
  1679. Inc(Result. Exponent);
  1680. Result.Digits[0] := Buffer[2];
  1681. Move(Buffer[4], Result.Digits[1], 14);
  1682. If Decimals + Result.Exponent < Precision Then
  1683. N := Decimals + Result.Exponent
  1684. Else
  1685. N := Precision;
  1686. If N > 15 Then
  1687. N := 15;
  1688. If N = 0 Then
  1689. Begin
  1690. If Result.Digits[0] >= '5' Then
  1691. Begin
  1692. Result.Digits[0] := '1';
  1693. Result.Digits[1] := #0;
  1694. Inc(Result.Exponent);
  1695. End
  1696. Else
  1697. Result.Digits[0] := #0;
  1698. End
  1699. Else If N > 0 Then
  1700. Begin
  1701. If Result.Digits[N] >= '5' Then
  1702. Begin
  1703. Repeat
  1704. Result.Digits[N] := #0;
  1705. Dec(N);
  1706. Inc(Result.Digits[N]);
  1707. Until (N = 0) Or (Result.Digits[N] < ':');
  1708. If Result.Digits[0] = ':' Then
  1709. Begin
  1710. Result.Digits[0] := '1';
  1711. Inc(Result.Exponent);
  1712. End;
  1713. End
  1714. Else
  1715. Begin
  1716. Result.Digits[N] := '0';
  1717. While (Result.Digits[N] = '0') And (N > -1) Do
  1718. Begin
  1719. Result.Digits[N] := #0;
  1720. Dec(N);
  1721. End;
  1722. End;
  1723. End
  1724. Else
  1725. Result.Digits[0] := #0;
  1726. If Result.Digits[0] = #0 Then
  1727. Begin
  1728. Result.Exponent := 0;
  1729. Result.Negative := False;
  1730. End;
  1731. End;
  1732. Function FormatFloat(Const format: String; Value: Extended): String;
  1733. Var
  1734. Temp: ShortString;
  1735. buf : Array[0..1024] of char;
  1736. Begin
  1737. Buf[FloatToTextFmt(@Buf[0],Value,Pchar(Format))]:=#0;
  1738. Result:=StrPas(@Buf);
  1739. End;
  1740. {==============================================================================}
  1741. { extra functions }
  1742. {==============================================================================}
  1743. { LeftStr returns Count left-most characters from S }
  1744. function LeftStr(const S: string; Count: integer): string;
  1745. begin
  1746. result := Copy(S, 1, Count);
  1747. end ;
  1748. { RightStr returns Count right-most characters from S }
  1749. function RightStr(const S: string; Count: integer): string;
  1750. begin
  1751. If Count>Length(S) then
  1752. Count:=Length(S);
  1753. result := Copy(S, 1 + Length(S) - Count, Count);
  1754. end;
  1755. { BCDToInt converts the BCD value Value to an integer }
  1756. function BCDToInt(Value: integer): integer;
  1757. var i, j: integer;
  1758. begin
  1759. result := 0;
  1760. j := 1;
  1761. for i := 0 to SizeOf(Value) shr 1 - 1 do begin
  1762. result := result + j * (Value and 15);
  1763. j := j * 10;
  1764. Value := Value shr 4;
  1765. end ;
  1766. end ;
  1767. Function LastDelimiter(const Delimiters, S: string): Integer;
  1768. begin
  1769. Result:=Length(S);
  1770. While (Result>0) and (Pos(S[Result],Delimiters)=0) do
  1771. Dec(Result);
  1772. end;
  1773. Function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
  1774. var
  1775. Srch,OldP,RemS: string; // Srch and Oldp can contain uppercase versions of S,OldPattern
  1776. P : Integer;
  1777. begin
  1778. Srch:=S;
  1779. OldP:=OldPattern;
  1780. if rfIgnoreCase in Flags then
  1781. begin
  1782. Srch:=UpperCase(Srch);
  1783. OldP:=UpperCase(OldP);
  1784. end;
  1785. RemS:=S;
  1786. Result:='';
  1787. while (Length(Srch)<>0) do
  1788. begin
  1789. P:=Pos(OldP, Srch);
  1790. if P=0 then
  1791. begin
  1792. Result:=Result+RemS;
  1793. Srch:='';
  1794. end
  1795. else
  1796. begin
  1797. Result:=Result+Copy(RemS,1,P-1)+NewPattern;
  1798. P:=P+Length(OldP);
  1799. RemS:=Copy(RemS,P,Length(RemS)-P+1);
  1800. if not (rfReplaceAll in Flags) then
  1801. begin
  1802. Result:=Result+RemS;
  1803. Srch:='';
  1804. end
  1805. else
  1806. Srch:=Copy(Srch,P,Length(Srch)-P+1);
  1807. end;
  1808. end;
  1809. end;
  1810. Function IsDelimiter(const Delimiters, S: string; Index: Integer): Boolean;
  1811. begin
  1812. Result:=False;
  1813. If (Index>0) and (Index<=Length(S)) then
  1814. Result:=Pos(S[Index],Delimiters)<>0; // Note we don't do MBCS yet
  1815. end;
  1816. Function ByteToCharLen(const S: string; MaxLen: Integer): Integer;
  1817. begin
  1818. Result:=Length(S);
  1819. If Result>MaxLen then
  1820. Result:=MaxLen;
  1821. end;
  1822. Function ByteToCharIndex(const S: string; Index: Integer): Integer;
  1823. begin
  1824. Result:=Index;
  1825. end;
  1826. Function CharToByteLen(const S: string; MaxLen: Integer): Integer;
  1827. begin
  1828. Result:=Length(S);
  1829. If Result>MaxLen then
  1830. Result:=MaxLen;
  1831. end;
  1832. Function CharToByteIndex(const S: string; Index: Integer): Integer;
  1833. begin
  1834. Result:=Index;
  1835. end;
  1836. Function ByteType(const S: string; Index: Integer): TMbcsByteType;
  1837. begin
  1838. Result:=mbSingleByte;
  1839. end;
  1840. Function StrByteType(Str: PChar; Index: Cardinal): TMbcsByteType;
  1841. begin
  1842. Result:=mbSingleByte;
  1843. end;
  1844. Function FindCmdLineSwitch(const Switch: string; const Chars: TSysCharSet;IgnoreCase: Boolean): Boolean;
  1845. Var
  1846. I,L : Integer;
  1847. S,T : String;
  1848. begin
  1849. Result:=False;
  1850. S:=Switch;
  1851. If IgnoreCase then
  1852. S:=UpperCase(S);
  1853. I:=ParamCount;
  1854. While (Not Result) and (I>0) do
  1855. begin
  1856. L:=Length(Paramstr(I));
  1857. If (L>0) and (ParamStr(I)[1] in Chars) then
  1858. begin
  1859. T:=Copy(ParamStr(I),2,L-1);
  1860. If IgnoreCase then
  1861. T:=UpperCase(T);
  1862. Result:=S=T;
  1863. end;
  1864. Dec(i);
  1865. end;
  1866. end;
  1867. Function FindCmdLineSwitch(const Switch: string; IgnoreCase: Boolean): Boolean;
  1868. begin
  1869. Result:=FindCmdLineSwitch(Switch,SwitchChars,IgnoreCase);
  1870. end;
  1871. Function FindCmdLineSwitch(const Switch: string): Boolean;
  1872. begin
  1873. Result:=FindCmdLineSwitch(Switch,SwitchChars,False);
  1874. end;
  1875. {
  1876. Case Translation Tables
  1877. Can be used in internationalization support.
  1878. Although these tables can be obtained through system calls
  1879. it is better to not use those, since most implementation are not 100%
  1880. WARNING:
  1881. before modifying a translation table make sure that the current codepage
  1882. of the OS corresponds to the one you make changes to
  1883. }
  1884. const
  1885. { upper case translation table for character set 850 }
  1886. CP850UCT: array[128..255] of char =
  1887. ('€', 'š', '�', '¶', 'Ž', '¶', '�', '€', 'Ò', 'Ó', 'Ô', 'Ø', '×', 'Þ', 'Ž', '�',
  1888. '�', '’', '’', 'â', '™', 'ã', 'ê', 'ë', 'Y', '™', 'š', '�', 'œ', '�', 'ž', 'Ÿ',
  1889. 'µ', 'Ö', 'à', 'é', '¥', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1890. '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1891. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1892. 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß',
  1893. 'à', 'á', 'â', 'ã', 'å', 'å', 'æ', 'í', 'è', 'é', 'ê', 'ë', 'í', 'í', 'î', 'ï',
  1894. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1895. { lower case translation table for character set 850 }
  1896. CP850LCT: array[128..255] of char =
  1897. ('‡', '�', '‚', 'ƒ', '„', '…', '†', '‡', 'ˆ', '‰', 'Š', '‹', 'Œ', '�', '„', '†',
  1898. '‚', '‘', '‘', '“', '”', '•', '–', '—', '˜', '”', '�', '›', 'œ', '›', 'ž', 'Ÿ',
  1899. ' ', '¡', '¢', '£', '¤', '¤', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1900. '°', '±', '²', '³', '´', ' ', 'ƒ', '…', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1901. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Æ', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1902. 'Ð', 'Ñ', 'ˆ', '‰', 'Š', 'Õ', '¡', 'Œ', '‹', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', '�', 'ß',
  1903. '¢', 'á', '“', '•', 'ä', 'ä', 'æ', 'í', 'è', '£', '–', '—', 'ì', 'ì', 'î', 'ï',
  1904. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1905. { upper case translation table for character set ISO 8859/1 Latin 1 }
  1906. CPISO88591UCT: array[192..255] of char =
  1907. ( #192, #193, #194, #195, #196, #197, #198, #199,
  1908. #200, #201, #202, #203, #204, #205, #206, #207,
  1909. #208, #209, #210, #211, #212, #213, #214, #215,
  1910. #216, #217, #218, #219, #220, #221, #222, #223,
  1911. #192, #193, #194, #195, #196, #197, #198, #199,
  1912. #200, #201, #202, #203, #204, #205, #206, #207,
  1913. #208, #209, #210, #211, #212, #213, #214, #247,
  1914. #216, #217, #218, #219, #220, #221, #222, #89 );
  1915. { lower case translation table for character set ISO 8859/1 Latin 1 }
  1916. CPISO88591LCT: array[192..255] of char =
  1917. ( #224, #225, #226, #227, #228, #229, #230, #231,
  1918. #232, #233, #234, #235, #236, #237, #238, #239,
  1919. #240, #241, #242, #243, #244, #245, #246, #215,
  1920. #248, #249, #250, #251, #252, #253, #254, #223,
  1921. #224, #225, #226, #227, #228, #229, #230, #231,
  1922. #232, #233, #234, #235, #236, #237, #238, #239,
  1923. #240, #241, #242, #243, #244, #245, #246, #247,
  1924. #248, #249, #250, #251, #252, #253, #254, #255 );
  1925. {
  1926. $Log$
  1927. Revision 1.16 2004-08-30 18:00:12 michael
  1928. + Extra index check in IsDelimiter
  1929. Revision 1.15 2004/08/07 19:32:35 florian
  1930. * fixed CompareStr with a patch from Michalis Kamburelis
  1931. Revision 1.14 2004/08/07 16:56:28 florian
  1932. + TryStrToInt* added
  1933. Revision 1.13 2004/06/13 10:49:50 florian
  1934. * fixed some bootstrapping problems as well as some 64 bit stuff
  1935. Revision 1.12 2004/06/12 13:57:18 michael
  1936. + Enhanced FloatToStrF to 18 digits (Delphi compatibility, bug 3106
  1937. Revision 1.11 2004/06/12 13:23:17 michael
  1938. + Fixed currency<->string conversion support
  1939. Revision 1.10 2004/04/28 20:48:20 peter
  1940. * ordinal-pointer conversions fixed
  1941. Revision 1.9 2004/02/26 08:46:21 michael
  1942. + Added AnsiSameStr
  1943. Revision 1.8 2003/11/26 22:17:42 michael
  1944. + Merged fixbranch fixes, missing in main branch
  1945. Revision 1.7 2003/11/22 17:18:53 marco
  1946. * johill patch applied
  1947. Revision 1.6 2003/11/22 16:17:26 michael
  1948. + Small optimization in comparemem
  1949. Revision 1.5 2003/11/22 15:46:48 michael
  1950. + Patched CompareMem for case when length is 0
  1951. Revision 1.4 2003/11/09 13:37:42 michael
  1952. + Position specifier in format string affects all later specifiers
  1953. Revision 1.3 2003/11/03 09:42:28 marco
  1954. * Peter's Cardinal<->Longint fixes patch
  1955. Revision 1.2 2003/10/07 12:02:47 marco
  1956. * sametext and ansisametext added. (simple (ansi)comparetext wrappers)
  1957. Revision 1.1 2003/10/06 21:01:06 peter
  1958. * moved classes unit to rtl
  1959. Revision 1.26 2003/09/06 21:22:07 marco
  1960. * More objpas fixes
  1961. Revision 1.25 2002/12/23 23:26:08 florian
  1962. + addition to previous commit, forgot to save in the editor
  1963. Revision 1.23 2002/11/28 22:26:30 michael
  1964. + Fixed float<>string conversion routines
  1965. Revision 1.22 2002/11/28 20:29:26 michael
  1966. + made it compile again
  1967. Revision 1.21 2002/11/28 20:15:37 michael
  1968. + Fixed comparestr (merge from fix)
  1969. Revision 1.20 2002/09/15 17:50:35 peter
  1970. * Fixed AnsiStrComp crashes
  1971. Revision 1.1.2.16 2002/11/28 22:25:01 michael
  1972. + Fixed float<>string conversion routines
  1973. Revision 1.1.2.15 2002/11/28 20:24:11 michael
  1974. + merged some fixes from mainbranch
  1975. Revision 1.19 2002/09/07 16:01:22 peter
  1976. * old logs removed and tabs fixed
  1977. Revision 1.1.2.14 2002/11/28 20:13:10 michael
  1978. + Fixed comparestr
  1979. Revision 1.1.2.13 2002/10/29 23:41:06 michael
  1980. + Added lots of D4 functions
  1981. Revision 1.18 2002/09/02 06:07:16 michael
  1982. + Fix for formatbuf not applied correct
  1983. Revision 1.17 2002/08/29 10:04:48 michael
  1984. + Fix for bug report 2097 in formatbuf
  1985. Revision 1.16 2002/08/29 10:04:25 michael
  1986. + Fix for bug report 2097 in formatbuf
  1987. Revision 1.15 2002/07/06 12:14:03 daniel
  1988. - Changes from Strasbourg
  1989. Revision 1.14 2002/01/24 12:33:53 jonas
  1990. * adapted ranges of native types to int64 (e.g. high cardinal is no
  1991. longer longint($ffffffff), but just $fffffff in psystem)
  1992. * small additional fix in 64bit rangecheck code generation for 32 bit
  1993. processors
  1994. * adaption of ranges required the matching talgorithm used for selecting
  1995. which overloaded procedure to call to be adapted. It should now always
  1996. select the closest match for ordinal parameters.
  1997. + inttostr(qword) in sysstr.inc/sysstrh.inc
  1998. + abs(int64), sqr(int64), sqr(qword) in systemh.inc/generic.inc (previous
  1999. fixes were required to be able to add them)
  2000. * is_in_limit() moved from ncal to types unit, should always be used
  2001. instead of direct comparisons of low/high values of orddefs because
  2002. qword is a special case
  2003. }