sysstr.inc 57 KB

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