sysstr.inc 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110
  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. new(result);
  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. dispose(s);
  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 GenericAnsiUpperCase(const s: string): string;
  171. var
  172. len, i: integer;
  173. begin
  174. len := length(s);
  175. SetLength(result, len);
  176. for i := 1 to len do
  177. result[i] := UpperCaseTable[ord(s[i])];
  178. end;
  179. function GenericAnsiLowerCase(const s: string): string;
  180. var
  181. len, i: integer;
  182. begin
  183. len := length(s);
  184. SetLength(result, len);
  185. for i := 1 to len do
  186. result[i] := LowerCaseTable[ord(s[i])];
  187. end;
  188. function GenericAnsiCompareStr(const S1, S2: string): PtrInt;
  189. Var
  190. I,L1,L2 : SizeInt;
  191. begin
  192. Result:=0;
  193. L1:=Length(S1);
  194. L2:=Length(S2);
  195. I:=1;
  196. While (Result=0) and ((I<=L1) and (I<=L2)) do
  197. begin
  198. Result:=Ord(S1[I])-Ord(S2[I]); //!! Must be replaced by ansi characters !!
  199. Inc(I);
  200. end;
  201. If Result=0 Then
  202. Result:=L1-L2;
  203. end;
  204. function GenericAnsiCompareText(const S1, S2: string): PtrInt;
  205. Var
  206. I,L1,L2 : SizeInt;
  207. begin
  208. Result:=0;
  209. L1:=Length(S1);
  210. L2:=Length(S2);
  211. I:=1;
  212. While (Result=0) and ((I<=L1) and (I<=L2)) do
  213. begin
  214. Result:=Ord(LowerCaseTable[Ord(S1[I])])-Ord(LowerCaseTable[Ord(S2[I])]); //!! Must be replaced by ansi characters !!
  215. Inc(I);
  216. end;
  217. If Result=0 Then
  218. Result:=L1-L2;
  219. end;
  220. function AnsiSameText(const s1,s2:String):Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
  221. begin
  222. AnsiSameText:=AnsiCompareText(S1,S2)=0;
  223. end;
  224. function AnsiSameStr(const s1,s2:String):Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
  225. begin
  226. AnsiSameStr:=AnsiCompareStr(S1,S2)=0;
  227. end;
  228. function GenericAnsiStrComp(S1, S2: PChar): PtrInt;
  229. begin
  230. Result:=0;
  231. If S1=Nil then
  232. begin
  233. If S2=Nil Then Exit;
  234. result:=-1;
  235. exit;
  236. end;
  237. If S2=Nil then
  238. begin
  239. Result:=1;
  240. exit;
  241. end;
  242. Repeat
  243. Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
  244. Inc(S1);
  245. Inc(S2);
  246. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
  247. end;
  248. function GenericAnsiStrIComp(S1, S2: PChar): PtrInt;
  249. begin
  250. Result:=0;
  251. If S1=Nil then
  252. begin
  253. If S2=Nil Then Exit;
  254. result:=-1;
  255. exit;
  256. end;
  257. If S2=Nil then
  258. begin
  259. Result:=1;
  260. exit;
  261. end;
  262. Repeat
  263. Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
  264. Inc(S1);
  265. Inc(S2);
  266. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0))
  267. end;
  268. function GenericAnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  269. Var I : cardinal;
  270. begin
  271. Result:=0;
  272. If MaxLen=0 then exit;
  273. If S1=Nil then
  274. begin
  275. If S2=Nil Then Exit;
  276. result:=-1;
  277. exit;
  278. end;
  279. If S2=Nil then
  280. begin
  281. Result:=1;
  282. exit;
  283. end;
  284. I:=0;
  285. Repeat
  286. Result:=Ord(S1[0])-Ord(S2[0]); //!! Must be replaced by ansi characters !!
  287. Inc(S1);
  288. Inc(S2);
  289. Inc(I);
  290. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
  291. end;
  292. function GenericAnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt;
  293. Var I : cardinal;
  294. begin
  295. Result:=0;
  296. If MaxLen=0 then exit;
  297. If S1=Nil then
  298. begin
  299. If S2=Nil Then Exit;
  300. result:=-1;
  301. exit;
  302. end;
  303. If S2=Nil then
  304. begin
  305. Result:=1;
  306. exit;
  307. end;
  308. I:=0;
  309. Repeat
  310. Result:=Ord(LowerCaseTable[Ord(S1[0])])-Ord(LowerCaseTable[Ord(S2[0])]); //!! Must be replaced by ansi characters !!
  311. Inc(S1);
  312. Inc(S2);
  313. Inc(I);
  314. Until (Result<>0) or ((S1[0]=#0) or (S2[0]=#0)) or (I=MaxLen)
  315. end;
  316. function GenericAnsiStrLower(Str: PChar): PChar;
  317. begin
  318. result := Str;
  319. if Str <> Nil then begin
  320. while Str^ <> #0 do begin
  321. Str^ := LowerCaseTable[byte(Str^)];
  322. Str := Str + 1;
  323. end;
  324. end;
  325. end;
  326. function GenericAnsiStrUpper(Str: PChar): PChar;
  327. begin
  328. result := Str;
  329. if Str <> Nil then begin
  330. while Str^ <> #0 do begin
  331. Str^ := UpperCaseTable[byte(Str^)];
  332. Str := Str + 1;
  333. end ;
  334. end ;
  335. end ;
  336. function AnsiLastChar(const S: string): PChar;
  337. begin
  338. //!! No multibyte yet, so we return the last one.
  339. result:=StrEnd(Pchar(S));
  340. Dec(Result);
  341. end ;
  342. function AnsiStrLastChar(Str: PChar): PChar;
  343. begin
  344. //!! No multibyte yet, so we return the last one.
  345. result:=StrEnd(Str);
  346. Dec(Result);
  347. end ;
  348. function AnsiUpperCase(const s: string): string;{$ifdef SYSUTILSINLINE}inline;{$endif}
  349. begin
  350. result:=widestringmanager.UpperAnsiStringProc(s);
  351. end;
  352. function AnsiLowerCase(const s: string): string;{$ifdef SYSUTILSINLINE}inline;{$endif}
  353. begin
  354. result:=widestringmanager.LowerAnsiStringProc(s);
  355. end;
  356. function AnsiCompareStr(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  357. begin
  358. result:=widestringmanager.CompareStrAnsiStringProc(s1,s2);
  359. end;
  360. function AnsiCompareText(const S1, S2: string): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  361. begin
  362. result:=widestringmanager.CompareTextAnsiStringProc(s1,s2);
  363. end;
  364. function AnsiStrComp(S1, S2: PChar): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  365. begin
  366. result:=widestringmanager.StrCompAnsiStringProc(s1,s2);
  367. end;
  368. function AnsiStrIComp(S1, S2: PChar): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  369. begin
  370. result:=widestringmanager.StrICompAnsiStringProc(s1,s2);
  371. end;
  372. function AnsiStrLComp(S1, S2: PChar; MaxLen: cardinal): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  373. begin
  374. result:=widestringmanager.StrLCompAnsiStringProc(s1,s2,maxlen);
  375. end;
  376. function AnsiStrLIComp(S1, S2: PChar; MaxLen: cardinal): integer;{$ifdef SYSUTILSINLINE}inline;{$endif}
  377. begin
  378. result:=widestringmanager.StrLICompAnsiStringProc(s1,s2,maxlen);
  379. end;
  380. function AnsiStrLower(Str: PChar): PChar;{$ifdef SYSUTILSINLINE}inline;{$endif}
  381. begin
  382. result:=widestringmanager.StrLowerAnsiStringProc(Str);
  383. end;
  384. function AnsiStrUpper(Str: PChar): PChar;{$ifdef SYSUTILSINLINE}inline;{$endif}
  385. begin
  386. result:=widestringmanager.StrUpperAnsiStringProc(Str);
  387. end;
  388. {==============================================================================}
  389. { End of Ansi functions }
  390. {==============================================================================}
  391. { Trim returns a copy of S with blanks characters on the left and right stripped off }
  392. Const WhiteSpace = [' ',#10,#13,#9];
  393. function Trim(const S: string): string;
  394. var Ofs, Len: integer;
  395. begin
  396. len := Length(S);
  397. while (Len>0) and (S[Len] in WhiteSpace) do
  398. dec(Len);
  399. Ofs := 1;
  400. while (Ofs<=Len) and (S[Ofs] in WhiteSpace) do
  401. Inc(Ofs);
  402. result := Copy(S, Ofs, 1 + Len - Ofs);
  403. end ;
  404. { TrimLeft returns a copy of S with all blank characters on the left stripped off }
  405. function TrimLeft(const S: string): string;
  406. var i,l:integer;
  407. begin
  408. l := length(s);
  409. i := 1;
  410. while (i<=l) and (s[i] in whitespace) do
  411. inc(i);
  412. Result := copy(s, i, l);
  413. end ;
  414. { TrimRight returns a copy of S with all blank characters on the right stripped off }
  415. function TrimRight(const S: string): string;
  416. var l:integer;
  417. begin
  418. l := length(s);
  419. while (l>0) and (s[l] in whitespace) do
  420. dec(l);
  421. result := copy(s,1,l);
  422. end ;
  423. { QuotedStr returns S quoted left and right and every single quote in S
  424. replaced by two quotes }
  425. function QuotedStr(const S: string): string;
  426. begin
  427. result := AnsiQuotedStr(s, '''');
  428. end ;
  429. { AnsiQuotedStr returns S quoted left and right by Quote,
  430. and every single occurance of Quote replaced by two }
  431. function AnsiQuotedStr(const S: string; Quote: char): string;
  432. var i, j, count: integer;
  433. begin
  434. result := '' + Quote;
  435. count := length(s);
  436. i := 0;
  437. j := 0;
  438. while i < count do begin
  439. i := i + 1;
  440. if S[i] = Quote then begin
  441. result := result + copy(S, 1 + j, i - j) + Quote;
  442. j := i;
  443. end ;
  444. end ;
  445. if i <> j then
  446. result := result + copy(S, 1 + j, i - j);
  447. result := result + Quote;
  448. end ;
  449. { AnsiExtractQuotedStr returns a copy of Src with quote characters
  450. deleted to the left and right and double occurances
  451. of Quote replaced by a single Quote }
  452. function AnsiExtractQuotedStr(var Src: PChar; Quote: Char): string;
  453. var i: integer; P, Q,R: PChar;
  454. begin
  455. P := Src;
  456. Q := StrEnd(P);
  457. result:='';
  458. if P=Q then exit;
  459. if P^<>quote then exit;
  460. inc(p);
  461. setlength(result,(Q-P)+1);
  462. R:=@Result[1];
  463. i := 0;
  464. while P <> Q do
  465. begin
  466. R^:=P^;
  467. inc(R);
  468. if (P^ = Quote) then
  469. begin
  470. P := P + 1;
  471. if (p^ <> Quote) then
  472. begin
  473. dec(R);
  474. break;
  475. end;
  476. end;
  477. P := P + 1;
  478. end ;
  479. src:=p;
  480. SetLength(result, (R-pchar(@Result[1])));
  481. end ;
  482. { AdjustLineBreaks returns S with all CR characters not followed by LF
  483. replaced with CR/LF }
  484. // under Linux all CR characters or CR/LF combinations should be replaced with LF
  485. function AdjustLineBreaks(const S: string): string;
  486. begin
  487. Result:=AdjustLineBreaks(S,DefaultTextLineBreakStyle);
  488. end;
  489. function AdjustLineBreaks(const S: string; Style: TTextLineBreakStyle): string;
  490. var
  491. Source,Dest: PChar;
  492. DestLen: Integer;
  493. I,J,L: Longint;
  494. begin
  495. Source:=Pointer(S);
  496. L:=Length(S);
  497. DestLen:=L;
  498. I:=1;
  499. while (I<=L) do
  500. begin
  501. case S[i] of
  502. #10: if (Style=tlbsCRLF) then
  503. Inc(DestLen);
  504. #13: if (Style=tlbsCRLF) then
  505. if (I<L) and (S[i+1]=#10) then
  506. Inc(I)
  507. else
  508. Inc(DestLen)
  509. else if (I<L) and (S[I+1]=#10) then
  510. Dec(DestLen);
  511. end;
  512. Inc(I);
  513. end;
  514. if (DestLen=L) then
  515. Result:=S
  516. else
  517. begin
  518. SetLength(Result, DestLen);
  519. FillChar(Result[1],DestLen,0);
  520. Dest := Pointer(Result);
  521. J:=0;
  522. I:=0;
  523. While I<L do
  524. case Source[I] of
  525. #10: begin
  526. if Style=tlbsCRLF then
  527. begin
  528. Dest[j]:=#13;
  529. Inc(J);
  530. end;
  531. Dest[J] := #10;
  532. Inc(J);
  533. Inc(I);
  534. end;
  535. #13: begin
  536. if Style=tlbsCRLF then
  537. begin
  538. Dest[j] := #13;
  539. Inc(J);
  540. end;
  541. Dest[j]:=#10;
  542. Inc(J);
  543. Inc(I);
  544. if Source[I]=#10 then
  545. Inc(I);
  546. end;
  547. else
  548. Dest[j]:=Source[i];
  549. Inc(J);
  550. Inc(I);
  551. end;
  552. end;
  553. end;
  554. { IsValidIdent returns true if the first character of Ident is in:
  555. 'A' to 'Z', 'a' to 'z' or '_' and the following characters are
  556. on of: 'A' to 'Z', 'a' to 'z', '0'..'9' or '_' }
  557. function IsValidIdent(const Ident: string): boolean;
  558. var i, len: integer;
  559. begin
  560. result := false;
  561. len := length(Ident);
  562. if len <> 0 then begin
  563. result := Ident[1] in ['A'..'Z', 'a'..'z', '_'];
  564. i := 1;
  565. while (result) and (i < len) do begin
  566. i := i + 1;
  567. result := result and (Ident[i] in ['A'..'Z', 'a'..'z', '0'..'9', '_']);
  568. end ;
  569. end ;
  570. end ;
  571. { IntToStr returns a string representing the value of Value }
  572. function IntToStr(Value: integer): string;
  573. begin
  574. System.Str(Value, result);
  575. end ;
  576. {$IFNDEF VIRTUALPASCAL}
  577. function IntToStr(Value: int64): string;
  578. begin
  579. System.Str(Value, result);
  580. end ;
  581. {$ENDIF}
  582. function IntToStr(Value: QWord): string;
  583. begin
  584. System.Str(Value, result);
  585. end ;
  586. { IntToHex returns a string representing the hexadecimal value of Value }
  587. const
  588. HexDigits: array[0..15] of char = '0123456789ABCDEF';
  589. function IntToHex(Value: integer; Digits: integer): string;
  590. var i: integer;
  591. begin
  592. SetLength(result, digits);
  593. for i := 0 to digits - 1 do
  594. begin
  595. result[digits - i] := HexDigits[value and 15];
  596. value := value shr 4;
  597. end ;
  598. while value <> 0 do begin
  599. result := HexDigits[value and 15] + result;
  600. value := value shr 4;
  601. end;
  602. end ;
  603. {$IFNDEF VIRTUALPASCAL} // overloading
  604. function IntToHex(Value: int64; Digits: integer): string;
  605. var i: integer;
  606. begin
  607. SetLength(result, digits);
  608. for i := 0 to digits - 1 do
  609. begin
  610. result[digits - i] := HexDigits[value and 15];
  611. value := value shr 4;
  612. end ;
  613. while value <> 0 do begin
  614. result := HexDigits[value and 15] + result;
  615. value := value shr 4;
  616. end;
  617. end ;
  618. {$ENDIF}
  619. function TryStrToInt(const s: string; var i : integer) : boolean;
  620. var Error : word;
  621. begin
  622. Val(s, i, Error);
  623. TryStrToInt:=Error=0
  624. end;
  625. { StrToInt converts the string S to an integer value,
  626. if S does not represent a valid integer value EConvertError is raised }
  627. function StrToInt(const S: string): integer;
  628. {$IFDEF VIRTUALPASCAL}
  629. var Error: longint;
  630. {$ELSE}
  631. var Error: word;
  632. {$ENDIF}
  633. begin
  634. Val(S, result, Error);
  635. if Error <> 0 then raise EConvertError.createfmt(SInValidInteger,[S]);
  636. end ;
  637. function StrToInt64(const S: string): int64;
  638. {$IFDEF VIRTUALPASCAL}
  639. var Error: longint;
  640. {$ELSE}
  641. var Error: word;
  642. {$ENDIF}
  643. begin
  644. Val(S, result, Error);
  645. if Error <> 0 then raise EConvertError.createfmt(SInValidInteger,[S]);
  646. end;
  647. function TryStrToInt64(const s: string; var i : int64) : boolean;
  648. var Error : word;
  649. begin
  650. Val(s, i, Error);
  651. TryStrToInt64:=Error=0
  652. end;
  653. { StrToIntDef converts the string S to an integer value,
  654. Default is returned in case S does not represent a valid integer value }
  655. function StrToIntDef(const S: string; Default: integer): integer;
  656. {$IFDEF VIRTUALPASCAL}
  657. var Error: longint;
  658. {$ELSE}
  659. var Error: word;
  660. {$ENDIF}
  661. begin
  662. Val(S, result, Error);
  663. if Error <> 0 then result := Default;
  664. end ;
  665. { StrToIntDef converts the string S to an integer value,
  666. Default is returned in case S does not represent a valid integer value }
  667. function StrToInt64Def(const S: string; Default: int64): int64;
  668. {$IFDEF VIRTUALPASCAL}
  669. var Error: longint;
  670. {$ELSE}
  671. var Error: word;
  672. {$ENDIF}
  673. begin
  674. Val(S, result, Error);
  675. if Error <> 0 then result := Default;
  676. end ;
  677. { LoadStr returns the string resource Ident. }
  678. function LoadStr(Ident: integer): string;
  679. begin
  680. result:='';
  681. end ;
  682. { FmtLoadStr returns the string resource Ident and formats it accordingly }
  683. function FmtLoadStr(Ident: integer; const Args: array of const): string;
  684. begin
  685. result:='';
  686. end;
  687. Const
  688. feInvalidFormat = 1;
  689. feMissingArgument = 2;
  690. feInvalidArgIndex = 3;
  691. {$ifdef fmtdebug}
  692. Procedure Log (Const S: String);
  693. begin
  694. Writeln (S);
  695. end;
  696. {$endif}
  697. Procedure DoFormatError (ErrCode : Longint);
  698. Var
  699. S : String;
  700. begin
  701. //!! must be changed to contain format string...
  702. S:='';
  703. Case ErrCode of
  704. feInvalidFormat : raise EConvertError.Createfmt(SInvalidFormat,[s]);
  705. feMissingArgument : raise EConvertError.Createfmt(SArgumentMissing,[s]);
  706. feInvalidArgIndex : raise EConvertError.Createfmt(SInvalidArgIndex,[s]);
  707. end;
  708. end;
  709. { we've no templates, but with includes we can simulate this :) }
  710. {$macro on}
  711. {$define INFORMAT}
  712. {$define TFormatString:=ansistring}
  713. {$define TFormatChar:=char}
  714. Function Format (Const Fmt : AnsiString; const Args : Array of const) : AnsiString;
  715. {$i sysformt.inc}
  716. {$undef TFormatString}
  717. {$undef TFormatChar}
  718. {$undef INFORMAT}
  719. {$macro off}
  720. Function FormatBuf (Var Buffer; BufLen : Cardinal;
  721. Const Fmt; fmtLen : Cardinal;
  722. Const Args : Array of const) : Cardinal;
  723. Var S,F : String;
  724. begin
  725. Setlength(F,fmtlen);
  726. if fmtlen > 0 then
  727. Move(fmt,F[1],fmtlen);
  728. S:=Format (F,Args);
  729. If Cardinal(Length(S))<Buflen then
  730. Result:=Length(S)
  731. else
  732. Result:=Buflen;
  733. Move(S[1],Buffer,Result);
  734. end;
  735. Procedure FmtStr(Var Res: String; Const Fmt : String; Const args: Array of const);
  736. begin
  737. Res:=Format(fmt,Args);
  738. end;
  739. Function StrFmt(Buffer,Fmt : PChar; Const args: Array of const) : Pchar;
  740. begin
  741. Buffer[FormatBuf(Buffer^,Maxint,Fmt^,strlen(fmt),args)]:=#0;
  742. Result:=Buffer;
  743. end;
  744. Function StrLFmt(Buffer : PCHar; Maxlen : Cardinal;Fmt : PChar; Const args: Array of const) : Pchar;
  745. begin
  746. Buffer[FormatBuf(Buffer^,MaxLen,Fmt^,strlen(fmt),args)]:=#0;
  747. Result:=Buffer;
  748. end;
  749. Function StrToFloat(Const S: String): Extended;
  750. Begin
  751. If Not TextToFloat(Pchar(S),Result) then
  752. Raise EConvertError.createfmt(SInValidFLoat,[S]);
  753. End;
  754. function StrToFloatDef(const S: string; const Default: Extended): Extended;
  755. begin
  756. if not TextToFloat(PChar(S),Result,fvExtended) then
  757. Result:=Default;
  758. end;
  759. Function TextToFloat(Buffer: PChar; Var Value: Extended): Boolean;
  760. Var
  761. E,P : Integer;
  762. S : String;
  763. Begin
  764. S:=StrPas(Buffer);
  765. P:=Pos(DecimalSeparator,S);
  766. If (P<>0) Then
  767. S[P] := '.';
  768. Val(S,Value,E);
  769. Result:=(E=0);
  770. End;
  771. Function TextToFloat(Buffer: PChar; Var Value; ValueType: TFloatValue): Boolean;
  772. Var
  773. E,P : Integer;
  774. S : String;
  775. C : Currency;
  776. Ext : Extended;
  777. Begin
  778. S:=StrPas(Buffer);
  779. P:=Pos(ThousandSeparator,S);
  780. While (P<>0) do
  781. begin
  782. Delete(S,P,1);
  783. P:=Pos(ThousandSeparator,S);
  784. end;
  785. P:=Pos(DecimalSeparator,S);
  786. If (P<>0) Then
  787. S[P] := '.';
  788. case ValueType of
  789. fvCurrency:
  790. Val(S,Currency(Value),E);
  791. fvExtended:
  792. Val(S,Extended(Value),E);
  793. fvDouble:
  794. Val(S,Double(Value),E);
  795. fvSingle:
  796. Val(S,Single(Value),E);
  797. fvComp:
  798. Val(S,Comp(Value),E);
  799. fvReal:
  800. Val(S,Real(Value),E);
  801. end;
  802. Result:=(E=0);
  803. End;
  804. Function TryStrToFloat(Const S : String; Var Value: Single): Boolean;
  805. Begin
  806. Result := TextToFloat(PChar(S), Value, fvSingle);
  807. End;
  808. Function TryStrToFloat(Const S : String; Var Value: Double): Boolean;
  809. Begin
  810. Result := TextToFloat(PChar(S), Value, fvDouble);
  811. End;
  812. {$ifdef FPC_HAS_TYPE_EXTENDED}
  813. Function TryStrToFloat(Const S : String; Var Value: Extended): Boolean;
  814. Begin
  815. Result := TextToFloat(PChar(S), Value);
  816. End;
  817. {$endif FPC_HAS_TYPE_EXTENDED}
  818. Function FloatToStr(Value: Extended): String;
  819. Begin
  820. Result := FloatToStrF(Value, ffGeneral, 15, 0);
  821. End;
  822. Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat; Precision, Digits: Integer): Longint;
  823. Var
  824. Tmp: String[40];
  825. Begin
  826. Tmp := FloatToStrF(Value, format, Precision, Digits);
  827. Result := Length(Tmp);
  828. Move(Tmp[1], Buffer[0], Result);
  829. End;
  830. Function FloatToStrF(Value: Extended; format: TFloatFormat; Precision, Digits: Integer): String;
  831. Var
  832. P: Integer;
  833. Negative, TooSmall, TooLarge: Boolean;
  834. Begin
  835. Case format Of
  836. ffGeneral:
  837. Begin
  838. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  839. TooSmall := (Abs(Value) < 0.00001) and (Value>0.0);
  840. If Not TooSmall Then
  841. Begin
  842. Str(Value:digits:precision, Result);
  843. P := Pos('.', Result);
  844. Result[P] := DecimalSeparator;
  845. TooLarge := P > Precision + 1;
  846. End;
  847. If TooSmall Or TooLarge Then
  848. begin
  849. Result := FloatToStrF(Value, ffExponent, Precision, Digits);
  850. // Strip unneeded zeroes.
  851. P:=Pos('E',result)-1;
  852. If P<>-1 then
  853. While (P>1) and (Result[P]='0') do
  854. begin
  855. system.Delete(Result,P,1);
  856. Dec(P);
  857. end;
  858. end
  859. else
  860. begin
  861. P := Length(Result);
  862. While Result[P] = '0' Do Dec(P);
  863. If Result[P] = DecimalSeparator Then Dec(P);
  864. SetLength(Result, P);
  865. end;
  866. End;
  867. ffExponent:
  868. Begin
  869. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  870. Str(Value:Precision + 8, Result);
  871. Result[3] := DecimalSeparator;
  872. P:=4;
  873. While (P>0) and (Digits < P) And (Result[Precision + 5] = '0') do
  874. Begin
  875. If P<>1 then
  876. system.Delete(Result, Precision + 5, 1)
  877. else
  878. system.Delete(Result, Precision + 3, 3);
  879. Dec(P);
  880. end;
  881. If Result[1] = ' ' Then
  882. System.Delete(Result, 1, 1);
  883. End;
  884. ffFixed:
  885. Begin
  886. If Digits = -1 Then Digits := 2
  887. Else If Digits > 18 Then Digits := 18;
  888. Str(Value:0:Digits, Result);
  889. If Result[1] = ' ' Then
  890. System.Delete(Result, 1, 1);
  891. P := Pos('.', Result);
  892. If P <> 0 Then Result[P] := DecimalSeparator;
  893. End;
  894. ffNumber:
  895. Begin
  896. If Digits = -1 Then Digits := 2
  897. Else If Digits > 15 Then Digits := 15;
  898. Str(Value:0:Digits, Result);
  899. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  900. P := Pos('.', Result);
  901. If P <> 0 Then
  902. Result[P] := DecimalSeparator
  903. else
  904. P := Length(Result)+1;
  905. Dec(P, 3);
  906. While (P > 1) Do
  907. Begin
  908. If Result[P - 1] <> '-' Then Insert(ThousandSeparator, Result, P);
  909. Dec(P, 3);
  910. End;
  911. End;
  912. ffCurrency:
  913. Begin
  914. If Value < 0 Then
  915. Begin
  916. Negative := True;
  917. Value := -Value;
  918. End
  919. Else Negative := False;
  920. If Digits = -1 Then Digits := CurrencyDecimals
  921. Else If Digits > 18 Then Digits := 18;
  922. Str(Value:0:Digits, Result);
  923. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  924. P := Pos('.', Result);
  925. If P <> 0 Then Result[P] := DecimalSeparator;
  926. Dec(P, 3);
  927. While (P > 1) Do
  928. Begin
  929. Insert(ThousandSeparator, Result, P);
  930. Dec(P, 3);
  931. End;
  932. If Not Negative Then
  933. Begin
  934. Case CurrencyFormat Of
  935. 0: Result := CurrencyString + Result;
  936. 1: Result := Result + CurrencyString;
  937. 2: Result := CurrencyString + ' ' + Result;
  938. 3: Result := Result + ' ' + CurrencyString;
  939. End
  940. End
  941. Else
  942. Begin
  943. Case NegCurrFormat Of
  944. 0: Result := '(' + CurrencyString + Result + ')';
  945. 1: Result := '-' + CurrencyString + Result;
  946. 2: Result := CurrencyString + '-' + Result;
  947. 3: Result := CurrencyString + Result + '-';
  948. 4: Result := '(' + Result + CurrencyString + ')';
  949. 5: Result := '-' + Result + CurrencyString;
  950. 6: Result := Result + '-' + CurrencyString;
  951. 7: Result := Result + CurrencyString + '-';
  952. 8: Result := '-' + Result + ' ' + CurrencyString;
  953. 9: Result := '-' + CurrencyString + ' ' + Result;
  954. 10: Result := CurrencyString + ' ' + Result + '-';
  955. End;
  956. End;
  957. End;
  958. End;
  959. End;
  960. Function FloatToDateTime (Const Value : Extended) : TDateTime;
  961. begin
  962. If (Value<MinDateTime) or (Value>MaxDateTime) then
  963. Raise EConvertError.CreateFmt (SInvalidDateTime,[Value]);
  964. Result:=Value;
  965. end;
  966. function TryFloatToCurr(const Value: Extended; var AResult: Currency): Boolean;
  967. begin
  968. {$ifndef VER1_0}
  969. Result:=(Value>=MinCurrency) and (Value<=MaxCurrency);
  970. if Result then
  971. AResult := Value;
  972. {$else VER1_0}
  973. Result:=false;
  974. {$endif VER1_0}
  975. end;
  976. function FloatToCurr(const Value: Extended): Currency;
  977. begin
  978. if not TryFloatToCurr(Value, Result) then
  979. Raise EConvertError.CreateFmt(SInvalidCurrency, [FloatToStr(Value)]);
  980. end;
  981. Function CurrToStr(Value: Currency): string;
  982. begin
  983. Result:=FloatToStrF(Value,ffNumber,15,2);
  984. end;
  985. function StrToCurr(const S: string): Currency;
  986. begin
  987. if not TextToFloat(PChar(S), Result, fvCurrency) then
  988. Raise EConvertError.createfmt(SInValidFLoat,[S]);
  989. end;
  990. function StrToCurrDef(const S: string; Default : Currency): Currency;
  991. begin
  992. if not TextToFloat(PChar(S), Result, fvCurrency) then
  993. Result:=Default;
  994. end;
  995. function StrToBool(const S: string): Boolean;
  996. Var
  997. Temp : String;
  998. D : Double;
  999. {$IFDEF VIRTUALPASCAL}
  1000. Code: longint;
  1001. {$ELSE}
  1002. Code: word;
  1003. {$ENDIF}
  1004. begin
  1005. Temp:=upcase(S);
  1006. Val(temp,D,code);
  1007. If Code=0 then
  1008. Result:=(D<>0.0)
  1009. else If Temp='TRUE' then
  1010. result:=true
  1011. else if Temp='FALSE' then
  1012. result:=false
  1013. else
  1014. Raise EConvertError.CreateFmt(SInvalidBoolean,[S]);
  1015. end;
  1016. function BoolToStr(B: Boolean): string;
  1017. begin
  1018. If B then
  1019. Result:='TRUE'
  1020. else
  1021. Result:='FALSE';
  1022. end;
  1023. Function FloatToTextFmt(Buffer: PChar; Value: Extended; format: PChar): Integer;
  1024. Var
  1025. Digits: String[40]; { String Of Digits }
  1026. Exponent: String[8]; { Exponent strin }
  1027. FmtStart, FmtStop: PChar; { Start And End Of relevant part }
  1028. { Of format String }
  1029. ExpFmt, ExpSize: Integer; { Type And Length Of }
  1030. { exponential format chosen }
  1031. Placehold: Array[1..4] Of Integer; { Number Of placeholders In All }
  1032. { four Sections }
  1033. thousand: Boolean; { thousand separators? }
  1034. UnexpectedDigits: Integer; { Number Of unexpected Digits that }
  1035. { have To be inserted before the }
  1036. { First placeholder. }
  1037. DigitExponent: Integer; { Exponent Of First digit In }
  1038. { Digits Array. }
  1039. { Find end of format section starting at P. False, if empty }
  1040. Function GetSectionEnd(Var P: PChar): Boolean;
  1041. Var
  1042. C: Char;
  1043. SQ, DQ: Boolean;
  1044. Begin
  1045. Result := False;
  1046. SQ := False;
  1047. DQ := False;
  1048. C := P[0];
  1049. While (C<>#0) And ((C<>';') Or SQ Or DQ) Do
  1050. Begin
  1051. Result := True;
  1052. Case C Of
  1053. #34: If Not SQ Then DQ := Not DQ;
  1054. #39: If Not DQ Then SQ := Not SQ;
  1055. End;
  1056. Inc(P);
  1057. C := P[0];
  1058. End;
  1059. End;
  1060. { Find start and end of format section to apply. If section doesn't exist,
  1061. use section 1. If section 2 is used, the sign of value is ignored. }
  1062. Procedure GetSectionRange(section: Integer);
  1063. Var
  1064. Sec: Array[1..3] Of PChar;
  1065. SecOk: Array[1..3] Of Boolean;
  1066. Begin
  1067. Sec[1] := format;
  1068. SecOk[1] := GetSectionEnd(Sec[1]);
  1069. If section > 1 Then
  1070. Begin
  1071. Sec[2] := Sec[1];
  1072. If Sec[2][0] <> #0 Then
  1073. Inc(Sec[2]);
  1074. SecOk[2] := GetSectionEnd(Sec[2]);
  1075. If section > 2 Then
  1076. Begin
  1077. Sec[3] := Sec[2];
  1078. If Sec[3][0] <> #0 Then
  1079. Inc(Sec[3]);
  1080. SecOk[3] := GetSectionEnd(Sec[3]);
  1081. End;
  1082. End;
  1083. If Not SecOk[1] Then
  1084. FmtStart := Nil
  1085. Else
  1086. Begin
  1087. If Not SecOk[section] Then
  1088. section := 1
  1089. Else If section = 2 Then
  1090. Value := -Value; { Remove sign }
  1091. If section = 1 Then FmtStart := format Else
  1092. Begin
  1093. FmtStart := Sec[section - 1];
  1094. Inc(FmtStart);
  1095. End;
  1096. FmtStop := Sec[section];
  1097. End;
  1098. End;
  1099. { Find format section ranging from FmtStart to FmtStop. }
  1100. Procedure GetFormatOptions;
  1101. Var
  1102. Fmt: PChar;
  1103. SQ, DQ: Boolean;
  1104. area: Integer;
  1105. Begin
  1106. SQ := False;
  1107. DQ := False;
  1108. Fmt := FmtStart;
  1109. ExpFmt := 0;
  1110. area := 1;
  1111. thousand := False;
  1112. Placehold[1] := 0;
  1113. Placehold[2] := 0;
  1114. Placehold[3] := 0;
  1115. Placehold[4] := 0;
  1116. While Fmt < FmtStop Do
  1117. Begin
  1118. Case Fmt[0] Of
  1119. #34:
  1120. Begin
  1121. If Not SQ Then
  1122. DQ := Not DQ;
  1123. Inc(Fmt);
  1124. End;
  1125. #39:
  1126. Begin
  1127. If Not DQ Then
  1128. SQ := Not SQ;
  1129. Inc(Fmt);
  1130. End;
  1131. Else
  1132. { This was 'if not SQ or DQ'. Looked wrong... }
  1133. If Not SQ Or DQ Then
  1134. Begin
  1135. Case Fmt[0] Of
  1136. '0':
  1137. Begin
  1138. Case area Of
  1139. 1:
  1140. area := 2;
  1141. 4:
  1142. Begin
  1143. area := 3;
  1144. Inc(Placehold[3], Placehold[4]);
  1145. Placehold[4] := 0;
  1146. End;
  1147. End;
  1148. Inc(Placehold[area]);
  1149. Inc(Fmt);
  1150. End;
  1151. '#':
  1152. Begin
  1153. If area=3 Then
  1154. area:=4;
  1155. Inc(Placehold[area]);
  1156. Inc(Fmt);
  1157. End;
  1158. '.':
  1159. Begin
  1160. If area<3 Then
  1161. area:=3;
  1162. Inc(Fmt);
  1163. End;
  1164. ',':
  1165. Begin
  1166. thousand := True;
  1167. Inc(Fmt);
  1168. End;
  1169. 'e', 'E':
  1170. If ExpFmt = 0 Then
  1171. Begin
  1172. If (Fmt[0]='E') Then
  1173. ExpFmt:=1
  1174. Else
  1175. ExpFmt := 3;
  1176. Inc(Fmt);
  1177. If (Fmt<FmtStop) Then
  1178. Begin
  1179. Case Fmt[0] Of
  1180. '+':
  1181. Begin
  1182. End;
  1183. '-':
  1184. Inc(ExpFmt);
  1185. Else
  1186. ExpFmt := 0;
  1187. End;
  1188. If ExpFmt <> 0 Then
  1189. Begin
  1190. Inc(Fmt);
  1191. ExpSize := 0;
  1192. While (Fmt<FmtStop) And
  1193. (ExpSize<4) And
  1194. (Fmt[0] In ['0'..'9']) Do
  1195. Begin
  1196. Inc(ExpSize);
  1197. Inc(Fmt);
  1198. End;
  1199. End;
  1200. End;
  1201. End
  1202. Else
  1203. Inc(Fmt);
  1204. Else { Case }
  1205. Inc(Fmt);
  1206. End; { Case }
  1207. End; { Begin }
  1208. End; { Case }
  1209. End; { While .. Begin }
  1210. End;
  1211. Procedure FloatToStr;
  1212. Var
  1213. I, J, Exp, Width, Decimals, DecimalPoint, len: Integer;
  1214. Begin
  1215. If ExpFmt = 0 Then
  1216. Begin
  1217. { Fixpoint }
  1218. Decimals:=Placehold[3]+Placehold[4];
  1219. Width:=Placehold[1]+Placehold[2]+Decimals;
  1220. If (Decimals=0) Then
  1221. Str(Value:Width:0,Digits)
  1222. Else
  1223. Str(Value:Width+1:Decimals,Digits);
  1224. len:=Length(Digits);
  1225. { Find the decimal point }
  1226. If (Decimals=0) Then
  1227. DecimalPoint:=len+1
  1228. Else
  1229. DecimalPoint:=len-Decimals;
  1230. { If value is very small, and no decimal places
  1231. are desired, remove the leading 0. }
  1232. If (Abs(Value) < 1) And (Placehold[2] = 0) Then
  1233. Begin
  1234. If (Placehold[1]=0) Then
  1235. Delete(Digits,DecimalPoint-1,1)
  1236. Else
  1237. Digits[DecimalPoint-1]:=' ';
  1238. End;
  1239. { Convert optional zeroes to spaces. }
  1240. I:=len;
  1241. J:=DecimalPoint+Placehold[3];
  1242. While (I>J) And (Digits[I]='0') Do
  1243. Begin
  1244. Digits[I] := ' ';
  1245. Dec(I);
  1246. End;
  1247. { If integer value and no obligatory decimal
  1248. places, remove decimal point. }
  1249. If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then
  1250. Digits[DecimalPoint] := ' ';
  1251. { Convert spaces left from obligatory decimal point to zeroes. }
  1252. I:=DecimalPoint-Placehold[2];
  1253. While (I<DecimalPoint) And (Digits[I]=' ') Do
  1254. Begin
  1255. Digits[I] := '0';
  1256. Inc(I);
  1257. End;
  1258. Exp := 0;
  1259. End
  1260. Else
  1261. Begin
  1262. { Scientific: exactly <Width> Digits With <Precision> Decimals
  1263. And adjusted Exponent. }
  1264. If Placehold[1]+Placehold[2]=0 Then
  1265. Placehold[1]:=1;
  1266. Decimals := Placehold[3] + Placehold[4];
  1267. Width:=Placehold[1]+Placehold[2]+Decimals;
  1268. Str(Value:Width+8,Digits);
  1269. { Find and cut out exponent. Always the
  1270. last 6 characters in the string.
  1271. -> 0000E+0000 }
  1272. I:=Length(Digits)-5;
  1273. Val(Copy(Digits,I+1,5),Exp,J);
  1274. Exp:=Exp+1-(Placehold[1]+Placehold[2]);
  1275. Delete(Digits, I, 6);
  1276. { Str() always returns at least one digit after the decimal point.
  1277. If we don't want it, we have to remove it. }
  1278. If (Decimals=0) And (Placehold[1]+Placehold[2]<= 1) Then
  1279. Begin
  1280. If (Digits[4]>='5') Then
  1281. Begin
  1282. Inc(Digits[2]);
  1283. If (Digits[2]>'9') Then
  1284. Begin
  1285. Digits[2] := '1';
  1286. Inc(Exp);
  1287. End;
  1288. End;
  1289. Delete(Digits, 3, 2);
  1290. DecimalPoint := Length(Digits) + 1;
  1291. End
  1292. Else
  1293. Begin
  1294. { Move decimal point at the desired position }
  1295. Delete(Digits, 3, 1);
  1296. DecimalPoint:=2+Placehold[1]+Placehold[2];
  1297. If (Decimals<>0) Then
  1298. Insert('.',Digits,DecimalPoint);
  1299. End;
  1300. { Convert optional zeroes to spaces. }
  1301. I := Length(Digits);
  1302. J := DecimalPoint + Placehold[3];
  1303. While (I > J) And (Digits[I] = '0') Do
  1304. Begin
  1305. Digits[I] := ' ';
  1306. Dec(I);
  1307. End;
  1308. { If integer number and no obligatory decimal paces, remove decimal point }
  1309. If (DecimalPoint<Length(Digits)) And
  1310. (Digits[DecimalPoint+1]=' ') Then
  1311. Digits[DecimalPoint]:=' ';
  1312. If (Digits[1]=' ') Then
  1313. Begin
  1314. Delete(Digits, 1, 1);
  1315. Dec(DecimalPoint);
  1316. End;
  1317. { Calculate exponent string }
  1318. Str(Abs(Exp), Exponent);
  1319. While Length(Exponent)<ExpSize Do
  1320. Insert('0',Exponent,1);
  1321. If Exp >= 0 Then
  1322. Begin
  1323. If (ExpFmt In [1,3]) Then
  1324. Insert('+', Exponent, 1);
  1325. End
  1326. Else
  1327. Insert('-',Exponent,1);
  1328. If (ExpFmt<3) Then
  1329. Insert('E',Exponent,1)
  1330. Else
  1331. Insert('e',Exponent,1);
  1332. End;
  1333. DigitExponent:=DecimalPoint-2;
  1334. If (Digits[1]='-') Then
  1335. Dec(DigitExponent);
  1336. UnexpectedDigits:=DecimalPoint-1-(Placehold[1]+Placehold[2]);
  1337. End;
  1338. Function PutResult: LongInt;
  1339. Var
  1340. SQ, DQ: Boolean;
  1341. Fmt, Buf: PChar;
  1342. Dig, N: Integer;
  1343. Begin
  1344. SQ := False;
  1345. DQ := False;
  1346. Fmt := FmtStart;
  1347. Buf := Buffer;
  1348. Dig := 1;
  1349. While (Fmt<FmtStop) Do
  1350. Begin
  1351. //Write(Fmt[0]);
  1352. Case Fmt[0] Of
  1353. #34:
  1354. Begin
  1355. If Not SQ Then
  1356. DQ := Not DQ;
  1357. Inc(Fmt);
  1358. End;
  1359. #39:
  1360. Begin
  1361. If Not DQ Then
  1362. SQ := Not SQ;
  1363. Inc(Fmt);
  1364. End;
  1365. Else
  1366. If Not (SQ Or DQ) Then
  1367. Begin
  1368. Case Fmt[0] Of
  1369. '0', '#', '.':
  1370. Begin
  1371. If (Dig=1) And (UnexpectedDigits>0) Then
  1372. Begin
  1373. { Everything unexpected is written before the first digit }
  1374. For N := 1 To UnexpectedDigits Do
  1375. Begin
  1376. Buf[0] := Digits[N];
  1377. Inc(Buf);
  1378. If thousand And (Digits[N]<>'-') Then
  1379. Begin
  1380. If (DigitExponent Mod 3 = 0) And (DigitExponent>0) Then
  1381. Begin
  1382. Buf[0] := ThousandSeparator;
  1383. Inc(Buf);
  1384. End;
  1385. Dec(DigitExponent);
  1386. End;
  1387. End;
  1388. Inc(Dig, UnexpectedDigits);
  1389. End;
  1390. If (Digits[Dig]<>' ') Then
  1391. Begin
  1392. If (Digits[Dig]='.') Then
  1393. Buf[0] := DecimalSeparator
  1394. Else
  1395. Buf[0] := Digits[Dig];
  1396. Inc(Buf);
  1397. If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then
  1398. Begin
  1399. Buf[0] := ThousandSeparator;
  1400. Inc(Buf);
  1401. End;
  1402. End;
  1403. Inc(Dig);
  1404. Dec(DigitExponent);
  1405. Inc(Fmt);
  1406. End;
  1407. 'e', 'E':
  1408. Begin
  1409. If ExpFmt <> 0 Then
  1410. Begin
  1411. Inc(Fmt);
  1412. If Fmt < FmtStop Then
  1413. Begin
  1414. If Fmt[0] In ['+', '-'] Then
  1415. Begin
  1416. Inc(Fmt, ExpSize);
  1417. For N:=1 To Length(Exponent) Do
  1418. Buf[N-1] := Exponent[N];
  1419. Inc(Buf,Length(Exponent));
  1420. ExpFmt:=0;
  1421. End;
  1422. Inc(Fmt);
  1423. End;
  1424. End
  1425. Else
  1426. Begin
  1427. { No legal exponential format.
  1428. Simply write the 'E' to the result. }
  1429. Buf[0] := Fmt[0];
  1430. Inc(Buf);
  1431. Inc(Fmt);
  1432. End;
  1433. End;
  1434. Else { Case }
  1435. { Usual character }
  1436. If (Fmt[0]<>',') Then
  1437. Begin
  1438. Buf[0] := Fmt[0];
  1439. Inc(Buf);
  1440. End;
  1441. Inc(Fmt);
  1442. End; { Case }
  1443. End
  1444. Else { IF }
  1445. Begin
  1446. { Character inside single or double quotes }
  1447. Buf[0] := Fmt[0];
  1448. Inc(Buf);
  1449. Inc(Fmt);
  1450. End;
  1451. End; { Case }
  1452. End; { While .. Begin }
  1453. Result:=PtrInt(Buf)-PtrInt(Buffer);
  1454. End;
  1455. Begin
  1456. If (Value>0) Then
  1457. GetSectionRange(1)
  1458. Else If (Value<0) Then
  1459. GetSectionRange(2)
  1460. Else
  1461. GetSectionRange(3);
  1462. If FmtStart = Nil Then
  1463. Begin
  1464. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4);
  1465. End
  1466. Else
  1467. Begin
  1468. GetFormatOptions;
  1469. If (ExpFmt = 0) And (Abs(Value) >= 1E18) Then
  1470. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4)
  1471. Else
  1472. Begin
  1473. FloatToStr;
  1474. Result := PutResult;
  1475. End;
  1476. End;
  1477. End;
  1478. Procedure FloatToDecimal(Var Result: TFloatRec; Value: Extended; Precision, Decimals : integer);
  1479. Var
  1480. Buffer: String[24];
  1481. Error, N: Integer;
  1482. Begin
  1483. Str(Value:23, Buffer);
  1484. Result.Negative := (Buffer[1] = '-');
  1485. Val(Copy(Buffer, 19, 5), Result.Exponent, Error);
  1486. Inc(Result. Exponent);
  1487. Result.Digits[0] := Buffer[2];
  1488. Move(Buffer[4], Result.Digits[1], 14);
  1489. If Decimals + Result.Exponent < Precision Then
  1490. N := Decimals + Result.Exponent
  1491. Else
  1492. N := Precision;
  1493. If N > 15 Then
  1494. N := 15;
  1495. If N = 0 Then
  1496. Begin
  1497. If Result.Digits[0] >= '5' Then
  1498. Begin
  1499. Result.Digits[0] := '1';
  1500. Result.Digits[1] := #0;
  1501. Inc(Result.Exponent);
  1502. End
  1503. Else
  1504. Result.Digits[0] := #0;
  1505. End
  1506. Else If N > 0 Then
  1507. Begin
  1508. If Result.Digits[N] >= '5' Then
  1509. Begin
  1510. Repeat
  1511. Result.Digits[N] := #0;
  1512. Dec(N);
  1513. Inc(Result.Digits[N]);
  1514. Until (N = 0) Or (Result.Digits[N] < ':');
  1515. If Result.Digits[0] = ':' Then
  1516. Begin
  1517. Result.Digits[0] := '1';
  1518. Inc(Result.Exponent);
  1519. End;
  1520. End
  1521. Else
  1522. Begin
  1523. Result.Digits[N] := '0';
  1524. While (Result.Digits[N] = '0') And (N > -1) Do
  1525. Begin
  1526. Result.Digits[N] := #0;
  1527. Dec(N);
  1528. End;
  1529. End;
  1530. End
  1531. Else
  1532. Result.Digits[0] := #0;
  1533. If Result.Digits[0] = #0 Then
  1534. Begin
  1535. Result.Exponent := 0;
  1536. Result.Negative := False;
  1537. End;
  1538. End;
  1539. Function FormatFloat(Const format: String; Value: Extended): String;
  1540. Var
  1541. Temp: ShortString;
  1542. buf : Array[0..1024] of char;
  1543. Begin
  1544. Buf[FloatToTextFmt(@Buf[0],Value,Pchar(Format))]:=#0;
  1545. Result:=StrPas(@Buf);
  1546. End;
  1547. {==============================================================================}
  1548. { extra functions }
  1549. {==============================================================================}
  1550. { LeftStr returns Count left-most characters from S }
  1551. function LeftStr(const S: string; Count: integer): string;
  1552. begin
  1553. result := Copy(S, 1, Count);
  1554. end ;
  1555. { RightStr returns Count right-most characters from S }
  1556. function RightStr(const S: string; Count: integer): string;
  1557. begin
  1558. If Count>Length(S) then
  1559. Count:=Length(S);
  1560. result := Copy(S, 1 + Length(S) - Count, Count);
  1561. end;
  1562. { BCDToInt converts the BCD value Value to an integer }
  1563. function BCDToInt(Value: integer): integer;
  1564. var i, j: integer;
  1565. begin
  1566. result := 0;
  1567. j := 1;
  1568. for i := 0 to SizeOf(Value) shr 1 - 1 do begin
  1569. result := result + j * (Value and 15);
  1570. j := j * 10;
  1571. Value := Value shr 4;
  1572. end ;
  1573. end ;
  1574. Function LastDelimiter(const Delimiters, S: string): Integer;
  1575. begin
  1576. Result:=Length(S);
  1577. While (Result>0) and (Pos(S[Result],Delimiters)=0) do
  1578. Dec(Result);
  1579. end;
  1580. Function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
  1581. var
  1582. Srch,OldP,RemS: string; // Srch and Oldp can contain uppercase versions of S,OldPattern
  1583. P : Integer;
  1584. begin
  1585. Srch:=S;
  1586. OldP:=OldPattern;
  1587. if rfIgnoreCase in Flags then
  1588. begin
  1589. Srch:=UpperCase(Srch);
  1590. OldP:=UpperCase(OldP);
  1591. end;
  1592. RemS:=S;
  1593. Result:='';
  1594. while (Length(Srch)<>0) do
  1595. begin
  1596. P:=Pos(OldP, Srch);
  1597. if P=0 then
  1598. begin
  1599. Result:=Result+RemS;
  1600. Srch:='';
  1601. end
  1602. else
  1603. begin
  1604. Result:=Result+Copy(RemS,1,P-1)+NewPattern;
  1605. P:=P+Length(OldP);
  1606. RemS:=Copy(RemS,P,Length(RemS)-P+1);
  1607. if not (rfReplaceAll in Flags) then
  1608. begin
  1609. Result:=Result+RemS;
  1610. Srch:='';
  1611. end
  1612. else
  1613. Srch:=Copy(Srch,P,Length(Srch)-P+1);
  1614. end;
  1615. end;
  1616. end;
  1617. Function IsDelimiter(const Delimiters, S: string; Index: Integer): Boolean;
  1618. begin
  1619. Result:=False;
  1620. If (Index>0) and (Index<=Length(S)) then
  1621. Result:=Pos(S[Index],Delimiters)<>0; // Note we don't do MBCS yet
  1622. end;
  1623. Function ByteToCharLen(const S: string; MaxLen: Integer): Integer;
  1624. begin
  1625. Result:=Length(S);
  1626. If Result>MaxLen then
  1627. Result:=MaxLen;
  1628. end;
  1629. Function ByteToCharIndex(const S: string; Index: Integer): Integer;
  1630. begin
  1631. Result:=Index;
  1632. end;
  1633. Function CharToByteLen(const S: string; MaxLen: Integer): Integer;
  1634. begin
  1635. Result:=Length(S);
  1636. If Result>MaxLen then
  1637. Result:=MaxLen;
  1638. end;
  1639. Function CharToByteIndex(const S: string; Index: Integer): Integer;
  1640. begin
  1641. Result:=Index;
  1642. end;
  1643. Function ByteType(const S: string; Index: Integer): TMbcsByteType;
  1644. begin
  1645. Result:=mbSingleByte;
  1646. end;
  1647. Function StrByteType(Str: PChar; Index: Cardinal): TMbcsByteType;
  1648. begin
  1649. Result:=mbSingleByte;
  1650. end;
  1651. Function StrCharLength(const Str: PChar): Integer;
  1652. begin
  1653. {$ifdef HASWIDESTRING}
  1654. result:=widestringmanager.CharLengthPCharProc(Str);
  1655. {$endif HASWIDESTRING}
  1656. end;
  1657. Function FindCmdLineSwitch(const Switch: string; const Chars: TSysCharSet;IgnoreCase: Boolean): Boolean;
  1658. Var
  1659. I,L : Integer;
  1660. S,T : String;
  1661. begin
  1662. Result:=False;
  1663. S:=Switch;
  1664. If IgnoreCase then
  1665. S:=UpperCase(S);
  1666. I:=ParamCount;
  1667. While (Not Result) and (I>0) do
  1668. begin
  1669. L:=Length(Paramstr(I));
  1670. If (L>0) and (ParamStr(I)[1] in Chars) then
  1671. begin
  1672. T:=Copy(ParamStr(I),2,L-1);
  1673. If IgnoreCase then
  1674. T:=UpperCase(T);
  1675. Result:=S=T;
  1676. end;
  1677. Dec(i);
  1678. end;
  1679. end;
  1680. Function FindCmdLineSwitch(const Switch: string; IgnoreCase: Boolean): Boolean;
  1681. begin
  1682. Result:=FindCmdLineSwitch(Switch,SwitchChars,IgnoreCase);
  1683. end;
  1684. Function FindCmdLineSwitch(const Switch: string): Boolean;
  1685. begin
  1686. Result:=FindCmdLineSwitch(Switch,SwitchChars,False);
  1687. end;
  1688. function WrapText(const Line, BreakStr: string; const BreakChars: TSysCharSet; MaxCol: Integer): string;
  1689. const
  1690. Quotes = ['''', '"'];
  1691. Var
  1692. L : String;
  1693. C,LQ,BC : Char;
  1694. P,BLen,Len : Integer;
  1695. HB,IBC : Boolean;
  1696. begin
  1697. Result:='';
  1698. L:=Line;
  1699. Blen:=Length(BreakStr);
  1700. If (BLen>0) then
  1701. BC:=BreakStr[1]
  1702. else
  1703. BC:=#0;
  1704. Len:=Length(L);
  1705. While (Len>0) do
  1706. begin
  1707. P:=1;
  1708. LQ:=#0;
  1709. HB:=False;
  1710. IBC:=False;
  1711. While ((P<=Len) and ((P<=MaxCol) or not IBC)) and ((LQ<>#0) or Not HB) do
  1712. begin
  1713. C:=L[P];
  1714. If (C=LQ) then
  1715. LQ:=#0
  1716. else If (C in Quotes) then
  1717. LQ:=C;
  1718. If (LQ<>#0) then
  1719. Inc(P)
  1720. else
  1721. begin
  1722. HB:=((C=BC) and (BreakStr=Copy(L,P,BLen)));
  1723. If HB then
  1724. Inc(P,Blen)
  1725. else
  1726. begin
  1727. If (P>MaxCol) then
  1728. IBC:=C in BreakChars;
  1729. Inc(P);
  1730. end;
  1731. end;
  1732. // Writeln('"',C,'" : IBC : ',IBC,' HB : ',HB,' LQ : ',LQ,' P>MaxCol : ',P>MaxCol);
  1733. end;
  1734. Result:=Result+Copy(L,1,P-1);
  1735. If Not HB then
  1736. Result:=Result+BreakStr;
  1737. Delete(L,1,P-1);
  1738. Len:=Length(L);
  1739. end;
  1740. end;
  1741. function WrapText(const Line: string; MaxCol: Integer): string;
  1742. begin
  1743. Result:=WrapText(Line,sLineBreak, [' ', '-', #9], MaxCol);
  1744. end;
  1745. {
  1746. Case Translation Tables
  1747. Can be used in internationalization support.
  1748. Although these tables can be obtained through system calls
  1749. it is better to not use those, since most implementation are not 100%
  1750. WARNING:
  1751. before modifying a translation table make sure that the current codepage
  1752. of the OS corresponds to the one you make changes to
  1753. }
  1754. const
  1755. { upper case translation table for character set 850 }
  1756. CP850UCT: array[128..255] of char =
  1757. ('€', 'š', '�', '¶', 'Ž', '¶', '�', '€', 'Ò', 'Ó', 'Ô', 'Ø', '×', 'Þ', 'Ž', '�',
  1758. '�', '’', '’', 'â', '™', 'ã', 'ê', 'ë', 'Y', '™', 'š', '�', 'œ', '�', 'ž', 'Ÿ',
  1759. 'µ', 'Ö', 'à', 'é', '¥', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1760. '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1761. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1762. 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß',
  1763. 'à', 'á', 'â', 'ã', 'å', 'å', 'æ', 'í', 'è', 'é', 'ê', 'ë', 'í', 'í', 'î', 'ï',
  1764. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1765. { lower case translation table for character set 850 }
  1766. CP850LCT: array[128..255] of char =
  1767. ('‡', '�', '‚', 'ƒ', '„', '…', '†', '‡', 'ˆ', '‰', 'Š', '‹', 'Œ', '�', '„', '†',
  1768. '‚', '‘', '‘', '“', '”', '•', '–', '—', '˜', '”', '�', '›', 'œ', '›', 'ž', 'Ÿ',
  1769. ' ', '¡', '¢', '£', '¤', '¤', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1770. '°', '±', '²', '³', '´', ' ', 'ƒ', '…', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1771. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Æ', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1772. 'Ð', 'Ñ', 'ˆ', '‰', 'Š', 'Õ', '¡', 'Œ', '‹', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', '�', 'ß',
  1773. '¢', 'á', '“', '•', 'ä', 'ä', 'æ', 'í', 'è', '£', '–', '—', 'ì', 'ì', 'î', 'ï',
  1774. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1775. { upper case translation table for character set ISO 8859/1 Latin 1 }
  1776. CPISO88591UCT: array[192..255] of char =
  1777. ( #192, #193, #194, #195, #196, #197, #198, #199,
  1778. #200, #201, #202, #203, #204, #205, #206, #207,
  1779. #208, #209, #210, #211, #212, #213, #214, #215,
  1780. #216, #217, #218, #219, #220, #221, #222, #223,
  1781. #192, #193, #194, #195, #196, #197, #198, #199,
  1782. #200, #201, #202, #203, #204, #205, #206, #207,
  1783. #208, #209, #210, #211, #212, #213, #214, #247,
  1784. #216, #217, #218, #219, #220, #221, #222, #89 );
  1785. { lower case translation table for character set ISO 8859/1 Latin 1 }
  1786. CPISO88591LCT: array[192..255] of char =
  1787. ( #224, #225, #226, #227, #228, #229, #230, #231,
  1788. #232, #233, #234, #235, #236, #237, #238, #239,
  1789. #240, #241, #242, #243, #244, #245, #246, #215,
  1790. #248, #249, #250, #251, #252, #253, #254, #223,
  1791. #224, #225, #226, #227, #228, #229, #230, #231,
  1792. #232, #233, #234, #235, #236, #237, #238, #239,
  1793. #240, #241, #242, #243, #244, #245, #246, #247,
  1794. #248, #249, #250, #251, #252, #253, #254, #255 );
  1795. {
  1796. $Log$
  1797. Revision 1.33 2005-03-12 14:56:22 florian
  1798. + added Ansi* routines to widestring manager
  1799. * made them using OS calls on windows
  1800. Revision 1.32 2005/03/01 19:23:03 jonas
  1801. * fixed newstr() and disposestr()
  1802. Revision 1.31 2005/02/28 11:12:17 jonas
  1803. * fixed web bug 3708
  1804. Revision 1.30 2005/02/26 10:21:17 florian
  1805. + implemented WideFormat
  1806. + some Widestring stuff implemented
  1807. * some Widestring stuff fixed
  1808. Revision 1.29 2005/02/14 17:13:31 peter
  1809. * truncate log
  1810. Revision 1.28 2005/02/07 08:29:00 michael
  1811. + Patch from peter to fix 1.0 compile
  1812. Revision 1.27 2005/02/06 09:38:45 florian
  1813. + StrCharLength infrastructure
  1814. Revision 1.26 2005/01/17 18:38:48 peter
  1815. * extended overload disabled for powerpc
  1816. Revision 1.25 2005/01/16 17:53:27 michael
  1817. + Patch from Colin Western to implemenet TryStrToFLoat
  1818. }