sysstr.inc 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132
  1. {
  2. *********************************************************************
  3. $Id: sysstr.inc,v 1.38 2005/05/09 18:35:06 michael Exp $
  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
  454. P,Q,R: PChar;
  455. begin
  456. P := Src;
  457. Q := StrEnd(P);
  458. result:='';
  459. if P=Q then exit;
  460. if P^<>quote then exit;
  461. inc(p);
  462. setlength(result,(Q-P)+1);
  463. R:=@Result[1];
  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(trim(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. Begin
  776. S:=StrPas(Buffer);
  777. P:=Pos(ThousandSeparator,S);
  778. While (P<>0) do
  779. begin
  780. Delete(S,P,1);
  781. P:=Pos(ThousandSeparator,S);
  782. end;
  783. P:=Pos(DecimalSeparator,S);
  784. If (P<>0) Then
  785. S[P] := '.';
  786. case ValueType of
  787. fvCurrency:
  788. Val(S,Currency(Value),E);
  789. fvExtended:
  790. Val(S,Extended(Value),E);
  791. fvDouble:
  792. Val(S,Double(Value),E);
  793. fvSingle:
  794. Val(S,Single(Value),E);
  795. fvComp:
  796. Val(S,Comp(Value),E);
  797. fvReal:
  798. Val(S,Real(Value),E);
  799. end;
  800. Result:=(E=0);
  801. End;
  802. Function TryStrToFloat(Const S : String; Var Value: Single): Boolean;
  803. Begin
  804. Result := TextToFloat(PChar(S), Value, fvSingle);
  805. End;
  806. Function TryStrToFloat(Const S : String; Var Value: Double): Boolean;
  807. Begin
  808. Result := TextToFloat(PChar(S), Value, fvDouble);
  809. End;
  810. {$ifdef FPC_HAS_TYPE_EXTENDED}
  811. Function TryStrToFloat(Const S : String; Var Value: Extended): Boolean;
  812. Begin
  813. Result := TextToFloat(PChar(S), Value);
  814. End;
  815. {$endif FPC_HAS_TYPE_EXTENDED}
  816. Function FloatToStr(Value: Extended): String;
  817. Begin
  818. Result := FloatToStrF(Value, ffGeneral, 15, 0);
  819. End;
  820. Function FloatToText(Buffer: PChar; Value: Extended; format: TFloatFormat; Precision, Digits: Integer): Longint;
  821. Var
  822. Tmp: String[40];
  823. Begin
  824. Tmp := FloatToStrF(Value, format, Precision, Digits);
  825. Result := Length(Tmp);
  826. Move(Tmp[1], Buffer[0], Result);
  827. End;
  828. Function FloatToStrF(Value: Extended; format: TFloatFormat; Precision, Digits: Integer): String;
  829. Var
  830. P: Integer;
  831. Negative, TooSmall, TooLarge: Boolean;
  832. Begin
  833. Case format Of
  834. ffGeneral:
  835. Begin
  836. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  837. TooSmall := (Abs(Value) < 0.00001) and (Value>0.0);
  838. If Not TooSmall Then
  839. Begin
  840. Str(Value:digits:precision, Result);
  841. P := Pos('.', Result);
  842. if P<>0 then
  843. Result[P] := DecimalSeparator;
  844. TooLarge := P > Precision + 1;
  845. End;
  846. If TooSmall Or TooLarge Then
  847. begin
  848. Result := FloatToStrF(Value, ffExponent, Precision, Digits);
  849. // Strip unneeded zeroes.
  850. P:=Pos('E',result)-1;
  851. If P<>-1 then
  852. While (P>1) and (Result[P]='0') do
  853. begin
  854. system.Delete(Result,P,1);
  855. Dec(P);
  856. end;
  857. end
  858. else if (P<>0) then // we have a decimalseparator
  859. begin
  860. P := Length(Result);
  861. While (P>0) and (Result[P] = '0') Do
  862. Dec(P);
  863. If (P>0) and (Result[P]=DecimalSeparator) Then
  864. Dec(P);
  865. SetLength(Result, P);
  866. end;
  867. End;
  868. ffExponent:
  869. Begin
  870. If (Precision = -1) Or (Precision > 15) Then Precision := 15;
  871. Str(Value:Precision + 8, Result);
  872. Result[3] := DecimalSeparator;
  873. P:=4;
  874. While (P>0) and (Digits < P) And (Result[Precision + 5] = '0') do
  875. Begin
  876. If P<>1 then
  877. system.Delete(Result, Precision + 5, 1)
  878. else
  879. system.Delete(Result, Precision + 3, 3);
  880. Dec(P);
  881. end;
  882. If Result[1] = ' ' Then
  883. System.Delete(Result, 1, 1);
  884. End;
  885. ffFixed:
  886. Begin
  887. If Digits = -1 Then Digits := 2
  888. Else If Digits > 18 Then Digits := 18;
  889. Str(Value:0:Digits, Result);
  890. If Result[1] = ' ' Then
  891. System.Delete(Result, 1, 1);
  892. P := Pos('.', Result);
  893. If P <> 0 Then Result[P] := DecimalSeparator;
  894. End;
  895. ffNumber:
  896. Begin
  897. If Digits = -1 Then Digits := 2
  898. Else If Digits > 15 Then Digits := 15;
  899. Str(Value:0:Digits, Result);
  900. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  901. P := Pos('.', Result);
  902. If P <> 0 Then
  903. Result[P] := DecimalSeparator
  904. else
  905. P := Length(Result)+1;
  906. Dec(P, 3);
  907. While (P > 1) Do
  908. Begin
  909. If Result[P - 1] <> '-' Then Insert(ThousandSeparator, Result, P);
  910. Dec(P, 3);
  911. End;
  912. End;
  913. ffCurrency:
  914. Begin
  915. If Value < 0 Then
  916. Begin
  917. Negative := True;
  918. Value := -Value;
  919. End
  920. Else Negative := False;
  921. If Digits = -1 Then Digits := CurrencyDecimals
  922. Else If Digits > 18 Then Digits := 18;
  923. Str(Value:0:Digits, Result);
  924. If Result[1] = ' ' Then System.Delete(Result, 1, 1);
  925. P := Pos('.', Result);
  926. If P <> 0 Then Result[P] := DecimalSeparator;
  927. Dec(P, 3);
  928. While (P > 1) Do
  929. Begin
  930. Insert(ThousandSeparator, Result, P);
  931. Dec(P, 3);
  932. End;
  933. If Not Negative Then
  934. Begin
  935. Case CurrencyFormat Of
  936. 0: Result := CurrencyString + Result;
  937. 1: Result := Result + CurrencyString;
  938. 2: Result := CurrencyString + ' ' + Result;
  939. 3: Result := Result + ' ' + CurrencyString;
  940. End
  941. End
  942. Else
  943. Begin
  944. Case NegCurrFormat Of
  945. 0: Result := '(' + CurrencyString + Result + ')';
  946. 1: Result := '-' + CurrencyString + Result;
  947. 2: Result := CurrencyString + '-' + Result;
  948. 3: Result := CurrencyString + Result + '-';
  949. 4: Result := '(' + Result + CurrencyString + ')';
  950. 5: Result := '-' + Result + CurrencyString;
  951. 6: Result := Result + '-' + CurrencyString;
  952. 7: Result := Result + CurrencyString + '-';
  953. 8: Result := '-' + Result + ' ' + CurrencyString;
  954. 9: Result := '-' + CurrencyString + ' ' + Result;
  955. 10: Result := CurrencyString + ' ' + Result + '-';
  956. End;
  957. End;
  958. End;
  959. End;
  960. End;
  961. Function FloatToDateTime (Const Value : Extended) : TDateTime;
  962. begin
  963. If (Value<MinDateTime) or (Value>MaxDateTime) then
  964. Raise EConvertError.CreateFmt (SInvalidDateTime,[Value]);
  965. Result:=Value;
  966. end;
  967. function TryFloatToCurr(const Value: Extended; var AResult: Currency): Boolean;
  968. begin
  969. Result:=(Value>=MinCurrency) and (Value<=MaxCurrency);
  970. if Result then
  971. AResult := Value;
  972. end;
  973. function FloatToCurr(const Value: Extended): Currency;
  974. begin
  975. if not TryFloatToCurr(Value, Result) then
  976. Raise EConvertError.CreateFmt(SInvalidCurrency, [FloatToStr(Value)]);
  977. end;
  978. Function CurrToStr(Value: Currency): string;
  979. begin
  980. Result:=FloatToStrF(Value,ffNumber,15,2);
  981. end;
  982. function StrToCurr(const S: string): Currency;
  983. begin
  984. if not TextToFloat(PChar(S), Result, fvCurrency) then
  985. Raise EConvertError.createfmt(SInValidFLoat,[S]);
  986. end;
  987. Function TryStrToCurr(Const S : String; Var Value: Currency): Boolean;
  988. Begin
  989. Result := TextToFloat(PChar(S), Value, fvCurrency);
  990. End;
  991. function StrToCurrDef(const S: string; Default : Currency): Currency;
  992. begin
  993. if not TextToFloat(PChar(S), Result, fvCurrency) then
  994. Result:=Default;
  995. end;
  996. function StrToBool(const S: string): Boolean;
  997. Var
  998. Temp : String;
  999. D : Double;
  1000. {$IFDEF VIRTUALPASCAL}
  1001. Code: longint;
  1002. {$ELSE}
  1003. Code: word;
  1004. {$ENDIF}
  1005. begin
  1006. Temp:=upcase(S);
  1007. Val(temp,D,code);
  1008. If Code=0 then
  1009. Result:=(D<>0.0)
  1010. else If Temp='TRUE' then
  1011. result:=true
  1012. else if Temp='FALSE' then
  1013. result:=false
  1014. else
  1015. Raise EConvertError.CreateFmt(SInvalidBoolean,[S]);
  1016. end;
  1017. function BoolToStr(B: Boolean): string;
  1018. begin
  1019. If B then
  1020. Result:='TRUE'
  1021. else
  1022. Result:='FALSE';
  1023. end;
  1024. Function FloatToTextFmt(Buffer: PChar; Value: Extended; format: PChar): Integer;
  1025. Var
  1026. Digits: String[40]; { String Of Digits }
  1027. Exponent: String[8]; { Exponent strin }
  1028. FmtStart, FmtStop: PChar; { Start And End Of relevant part }
  1029. { Of format String }
  1030. ExpFmt, ExpSize: Integer; { Type And Length Of }
  1031. { exponential format chosen }
  1032. Placehold: Array[1..4] Of Integer; { Number Of placeholders In All }
  1033. { four Sections }
  1034. thousand: Boolean; { thousand separators? }
  1035. UnexpectedDigits: Integer; { Number Of unexpected Digits that }
  1036. { have To be inserted before the }
  1037. { First placeholder. }
  1038. DigitExponent: Integer; { Exponent Of First digit In }
  1039. { Digits Array. }
  1040. { Find end of format section starting at P. False, if empty }
  1041. Function GetSectionEnd(Var P: PChar): Boolean;
  1042. Var
  1043. C: Char;
  1044. SQ, DQ: Boolean;
  1045. Begin
  1046. Result := False;
  1047. SQ := False;
  1048. DQ := False;
  1049. C := P[0];
  1050. While (C<>#0) And ((C<>';') Or SQ Or DQ) Do
  1051. Begin
  1052. Result := True;
  1053. Case C Of
  1054. #34: If Not SQ Then DQ := Not DQ;
  1055. #39: If Not DQ Then SQ := Not SQ;
  1056. End;
  1057. Inc(P);
  1058. C := P[0];
  1059. End;
  1060. End;
  1061. { Find start and end of format section to apply. If section doesn't exist,
  1062. use section 1. If section 2 is used, the sign of value is ignored. }
  1063. Procedure GetSectionRange(section: Integer);
  1064. Var
  1065. Sec: Array[1..3] Of PChar;
  1066. SecOk: Array[1..3] Of Boolean;
  1067. Begin
  1068. Sec[1] := format;
  1069. SecOk[1] := GetSectionEnd(Sec[1]);
  1070. If section > 1 Then
  1071. Begin
  1072. Sec[2] := Sec[1];
  1073. If Sec[2][0] <> #0 Then
  1074. Inc(Sec[2]);
  1075. SecOk[2] := GetSectionEnd(Sec[2]);
  1076. If section > 2 Then
  1077. Begin
  1078. Sec[3] := Sec[2];
  1079. If Sec[3][0] <> #0 Then
  1080. Inc(Sec[3]);
  1081. SecOk[3] := GetSectionEnd(Sec[3]);
  1082. End;
  1083. End;
  1084. If Not SecOk[1] Then
  1085. FmtStart := Nil
  1086. Else
  1087. Begin
  1088. If Not SecOk[section] Then
  1089. section := 1
  1090. Else If section = 2 Then
  1091. Value := -Value; { Remove sign }
  1092. If section = 1 Then FmtStart := format Else
  1093. Begin
  1094. FmtStart := Sec[section - 1];
  1095. Inc(FmtStart);
  1096. End;
  1097. FmtStop := Sec[section];
  1098. End;
  1099. End;
  1100. { Find format section ranging from FmtStart to FmtStop. }
  1101. Procedure GetFormatOptions;
  1102. Var
  1103. Fmt: PChar;
  1104. SQ, DQ: Boolean;
  1105. area: Integer;
  1106. Begin
  1107. SQ := False;
  1108. DQ := False;
  1109. Fmt := FmtStart;
  1110. ExpFmt := 0;
  1111. area := 1;
  1112. thousand := False;
  1113. Placehold[1] := 0;
  1114. Placehold[2] := 0;
  1115. Placehold[3] := 0;
  1116. Placehold[4] := 0;
  1117. While Fmt < FmtStop Do
  1118. Begin
  1119. Case Fmt[0] Of
  1120. #34:
  1121. Begin
  1122. If Not SQ Then
  1123. DQ := Not DQ;
  1124. Inc(Fmt);
  1125. End;
  1126. #39:
  1127. Begin
  1128. If Not DQ Then
  1129. SQ := Not SQ;
  1130. Inc(Fmt);
  1131. End;
  1132. Else
  1133. { This was 'if not SQ or DQ'. Looked wrong... }
  1134. If Not SQ Or DQ Then
  1135. Begin
  1136. Case Fmt[0] Of
  1137. '0':
  1138. Begin
  1139. Case area Of
  1140. 1:
  1141. area := 2;
  1142. 4:
  1143. Begin
  1144. area := 3;
  1145. Inc(Placehold[3], Placehold[4]);
  1146. Placehold[4] := 0;
  1147. End;
  1148. End;
  1149. Inc(Placehold[area]);
  1150. Inc(Fmt);
  1151. End;
  1152. '#':
  1153. Begin
  1154. If area=3 Then
  1155. area:=4;
  1156. Inc(Placehold[area]);
  1157. Inc(Fmt);
  1158. End;
  1159. '.':
  1160. Begin
  1161. If area<3 Then
  1162. area:=3;
  1163. Inc(Fmt);
  1164. End;
  1165. ',':
  1166. Begin
  1167. thousand := True;
  1168. Inc(Fmt);
  1169. End;
  1170. 'e', 'E':
  1171. If ExpFmt = 0 Then
  1172. Begin
  1173. If (Fmt[0]='E') Then
  1174. ExpFmt:=1
  1175. Else
  1176. ExpFmt := 3;
  1177. Inc(Fmt);
  1178. If (Fmt<FmtStop) Then
  1179. Begin
  1180. Case Fmt[0] Of
  1181. '+':
  1182. Begin
  1183. End;
  1184. '-':
  1185. Inc(ExpFmt);
  1186. Else
  1187. ExpFmt := 0;
  1188. End;
  1189. If ExpFmt <> 0 Then
  1190. Begin
  1191. Inc(Fmt);
  1192. ExpSize := 0;
  1193. While (Fmt<FmtStop) And
  1194. (ExpSize<4) And
  1195. (Fmt[0] In ['0'..'9']) Do
  1196. Begin
  1197. Inc(ExpSize);
  1198. Inc(Fmt);
  1199. End;
  1200. End;
  1201. End;
  1202. End
  1203. Else
  1204. Inc(Fmt);
  1205. Else { Case }
  1206. Inc(Fmt);
  1207. End; { Case }
  1208. End; { Begin }
  1209. End; { Case }
  1210. End; { While .. Begin }
  1211. End;
  1212. Procedure FloatToStr;
  1213. Var
  1214. I, J, Exp, Width, Decimals, DecimalPoint, len: Integer;
  1215. Begin
  1216. If ExpFmt = 0 Then
  1217. Begin
  1218. { Fixpoint }
  1219. Decimals:=Placehold[3]+Placehold[4];
  1220. Width:=Placehold[1]+Placehold[2]+Decimals;
  1221. If (Decimals=0) Then
  1222. Str(Value:Width:0,Digits)
  1223. Else
  1224. Str(Value:Width+1:Decimals,Digits);
  1225. len:=Length(Digits);
  1226. { Find the decimal point }
  1227. If (Decimals=0) Then
  1228. DecimalPoint:=len+1
  1229. Else
  1230. DecimalPoint:=len-Decimals;
  1231. { If value is very small, and no decimal places
  1232. are desired, remove the leading 0. }
  1233. If (Abs(Value) < 1) And (Placehold[2] = 0) Then
  1234. Begin
  1235. If (Placehold[1]=0) Then
  1236. Delete(Digits,DecimalPoint-1,1)
  1237. Else
  1238. Digits[DecimalPoint-1]:=' ';
  1239. End;
  1240. { Convert optional zeroes to spaces. }
  1241. I:=len;
  1242. J:=DecimalPoint+Placehold[3];
  1243. While (I>J) And (Digits[I]='0') Do
  1244. Begin
  1245. Digits[I] := ' ';
  1246. Dec(I);
  1247. End;
  1248. { If integer value and no obligatory decimal
  1249. places, remove decimal point. }
  1250. If (DecimalPoint < len) And (Digits[DecimalPoint + 1] = ' ') Then
  1251. Digits[DecimalPoint] := ' ';
  1252. { Convert spaces left from obligatory decimal point to zeroes. }
  1253. I:=DecimalPoint-Placehold[2];
  1254. While (I<DecimalPoint) And (Digits[I]=' ') Do
  1255. Begin
  1256. Digits[I] := '0';
  1257. Inc(I);
  1258. End;
  1259. Exp := 0;
  1260. End
  1261. Else
  1262. Begin
  1263. { Scientific: exactly <Width> Digits With <Precision> Decimals
  1264. And adjusted Exponent. }
  1265. If Placehold[1]+Placehold[2]=0 Then
  1266. Placehold[1]:=1;
  1267. Decimals := Placehold[3] + Placehold[4];
  1268. Width:=Placehold[1]+Placehold[2]+Decimals;
  1269. Str(Value:Width+8,Digits);
  1270. { Find and cut out exponent. Always the
  1271. last 6 characters in the string.
  1272. -> 0000E+0000 }
  1273. I:=Length(Digits)-5;
  1274. Val(Copy(Digits,I+1,5),Exp,J);
  1275. Exp:=Exp+1-(Placehold[1]+Placehold[2]);
  1276. Delete(Digits, I, 6);
  1277. { Str() always returns at least one digit after the decimal point.
  1278. If we don't want it, we have to remove it. }
  1279. If (Decimals=0) And (Placehold[1]+Placehold[2]<= 1) Then
  1280. Begin
  1281. If (Digits[4]>='5') Then
  1282. Begin
  1283. Inc(Digits[2]);
  1284. If (Digits[2]>'9') Then
  1285. Begin
  1286. Digits[2] := '1';
  1287. Inc(Exp);
  1288. End;
  1289. End;
  1290. Delete(Digits, 3, 2);
  1291. DecimalPoint := Length(Digits) + 1;
  1292. End
  1293. Else
  1294. Begin
  1295. { Move decimal point at the desired position }
  1296. Delete(Digits, 3, 1);
  1297. DecimalPoint:=2+Placehold[1]+Placehold[2];
  1298. If (Decimals<>0) Then
  1299. Insert('.',Digits,DecimalPoint);
  1300. End;
  1301. { Convert optional zeroes to spaces. }
  1302. I := Length(Digits);
  1303. J := DecimalPoint + Placehold[3];
  1304. While (I > J) And (Digits[I] = '0') Do
  1305. Begin
  1306. Digits[I] := ' ';
  1307. Dec(I);
  1308. End;
  1309. { If integer number and no obligatory decimal paces, remove decimal point }
  1310. If (DecimalPoint<Length(Digits)) And
  1311. (Digits[DecimalPoint+1]=' ') Then
  1312. Digits[DecimalPoint]:=' ';
  1313. If (Digits[1]=' ') Then
  1314. Begin
  1315. Delete(Digits, 1, 1);
  1316. Dec(DecimalPoint);
  1317. End;
  1318. { Calculate exponent string }
  1319. Str(Abs(Exp), Exponent);
  1320. While Length(Exponent)<ExpSize Do
  1321. Insert('0',Exponent,1);
  1322. If Exp >= 0 Then
  1323. Begin
  1324. If (ExpFmt In [1,3]) Then
  1325. Insert('+', Exponent, 1);
  1326. End
  1327. Else
  1328. Insert('-',Exponent,1);
  1329. If (ExpFmt<3) Then
  1330. Insert('E',Exponent,1)
  1331. Else
  1332. Insert('e',Exponent,1);
  1333. End;
  1334. DigitExponent:=DecimalPoint-2;
  1335. If (Digits[1]='-') Then
  1336. Dec(DigitExponent);
  1337. UnexpectedDigits:=DecimalPoint-1-(Placehold[1]+Placehold[2]);
  1338. End;
  1339. Function PutResult: LongInt;
  1340. Var
  1341. SQ, DQ: Boolean;
  1342. Fmt, Buf: PChar;
  1343. Dig, N: Integer;
  1344. Begin
  1345. SQ := False;
  1346. DQ := False;
  1347. Fmt := FmtStart;
  1348. Buf := Buffer;
  1349. Dig := 1;
  1350. While (Fmt<FmtStop) Do
  1351. Begin
  1352. //Write(Fmt[0]);
  1353. Case Fmt[0] Of
  1354. #34:
  1355. Begin
  1356. If Not SQ Then
  1357. DQ := Not DQ;
  1358. Inc(Fmt);
  1359. End;
  1360. #39:
  1361. Begin
  1362. If Not DQ Then
  1363. SQ := Not SQ;
  1364. Inc(Fmt);
  1365. End;
  1366. Else
  1367. If Not (SQ Or DQ) Then
  1368. Begin
  1369. Case Fmt[0] Of
  1370. '0', '#', '.':
  1371. Begin
  1372. If (Dig=1) And (UnexpectedDigits>0) Then
  1373. Begin
  1374. { Everything unexpected is written before the first digit }
  1375. For N := 1 To UnexpectedDigits Do
  1376. Begin
  1377. Buf[0] := Digits[N];
  1378. Inc(Buf);
  1379. If thousand And (Digits[N]<>'-') Then
  1380. Begin
  1381. If (DigitExponent Mod 3 = 0) And (DigitExponent>0) Then
  1382. Begin
  1383. Buf[0] := ThousandSeparator;
  1384. Inc(Buf);
  1385. End;
  1386. Dec(DigitExponent);
  1387. End;
  1388. End;
  1389. Inc(Dig, UnexpectedDigits);
  1390. End;
  1391. If (Digits[Dig]<>' ') Then
  1392. Begin
  1393. If (Digits[Dig]='.') Then
  1394. Buf[0] := DecimalSeparator
  1395. Else
  1396. Buf[0] := Digits[Dig];
  1397. Inc(Buf);
  1398. If thousand And (DigitExponent Mod 3 = 0) And (DigitExponent > 0) Then
  1399. Begin
  1400. Buf[0] := ThousandSeparator;
  1401. Inc(Buf);
  1402. End;
  1403. End;
  1404. Inc(Dig);
  1405. Dec(DigitExponent);
  1406. Inc(Fmt);
  1407. End;
  1408. 'e', 'E':
  1409. Begin
  1410. If ExpFmt <> 0 Then
  1411. Begin
  1412. Inc(Fmt);
  1413. If Fmt < FmtStop Then
  1414. Begin
  1415. If Fmt[0] In ['+', '-'] Then
  1416. Begin
  1417. Inc(Fmt, ExpSize);
  1418. For N:=1 To Length(Exponent) Do
  1419. Buf[N-1] := Exponent[N];
  1420. Inc(Buf,Length(Exponent));
  1421. ExpFmt:=0;
  1422. End;
  1423. Inc(Fmt);
  1424. End;
  1425. End
  1426. Else
  1427. Begin
  1428. { No legal exponential format.
  1429. Simply write the 'E' to the result. }
  1430. Buf[0] := Fmt[0];
  1431. Inc(Buf);
  1432. Inc(Fmt);
  1433. End;
  1434. End;
  1435. Else { Case }
  1436. { Usual character }
  1437. If (Fmt[0]<>',') Then
  1438. Begin
  1439. Buf[0] := Fmt[0];
  1440. Inc(Buf);
  1441. End;
  1442. Inc(Fmt);
  1443. End; { Case }
  1444. End
  1445. Else { IF }
  1446. Begin
  1447. { Character inside single or double quotes }
  1448. Buf[0] := Fmt[0];
  1449. Inc(Buf);
  1450. Inc(Fmt);
  1451. End;
  1452. End; { Case }
  1453. End; { While .. Begin }
  1454. Result:=PtrInt(Buf)-PtrInt(Buffer);
  1455. End;
  1456. Begin
  1457. If (Value>0) Then
  1458. GetSectionRange(1)
  1459. Else If (Value<0) Then
  1460. GetSectionRange(2)
  1461. Else
  1462. GetSectionRange(3);
  1463. If FmtStart = Nil Then
  1464. Begin
  1465. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4);
  1466. End
  1467. Else
  1468. Begin
  1469. GetFormatOptions;
  1470. If (ExpFmt = 0) And (Abs(Value) >= 1E18) Then
  1471. Result := FloatToText(Buffer, Value, ffGeneral, 15, 4)
  1472. Else
  1473. Begin
  1474. FloatToStr;
  1475. Result := PutResult;
  1476. End;
  1477. End;
  1478. End;
  1479. Procedure FloatToDecimal(Var Result: TFloatRec; Value: Extended; Precision, Decimals : integer);
  1480. Var
  1481. Buffer: String[24];
  1482. Error, N: Integer;
  1483. Begin
  1484. Str(Value:23, Buffer);
  1485. Result.Negative := (Buffer[1] = '-');
  1486. Val(Copy(Buffer, 19, 5), Result.Exponent, Error);
  1487. Inc(Result. Exponent);
  1488. Result.Digits[0] := Buffer[2];
  1489. Move(Buffer[4], Result.Digits[1], 14);
  1490. If Decimals + Result.Exponent < Precision Then
  1491. N := Decimals + Result.Exponent
  1492. Else
  1493. N := Precision;
  1494. If N > 15 Then
  1495. N := 15;
  1496. If N = 0 Then
  1497. Begin
  1498. If Result.Digits[0] >= '5' Then
  1499. Begin
  1500. Result.Digits[0] := '1';
  1501. Result.Digits[1] := #0;
  1502. Inc(Result.Exponent);
  1503. End
  1504. Else
  1505. Result.Digits[0] := #0;
  1506. End
  1507. Else If N > 0 Then
  1508. Begin
  1509. If Result.Digits[N] >= '5' Then
  1510. Begin
  1511. Repeat
  1512. Result.Digits[N] := #0;
  1513. Dec(N);
  1514. Inc(Result.Digits[N]);
  1515. Until (N = 0) Or (Result.Digits[N] < ':');
  1516. If Result.Digits[0] = ':' Then
  1517. Begin
  1518. Result.Digits[0] := '1';
  1519. Inc(Result.Exponent);
  1520. End;
  1521. End
  1522. Else
  1523. Begin
  1524. Result.Digits[N] := '0';
  1525. While (Result.Digits[N] = '0') And (N > -1) Do
  1526. Begin
  1527. Result.Digits[N] := #0;
  1528. Dec(N);
  1529. End;
  1530. End;
  1531. End
  1532. Else
  1533. Result.Digits[0] := #0;
  1534. If Result.Digits[0] = #0 Then
  1535. Begin
  1536. Result.Exponent := 0;
  1537. Result.Negative := False;
  1538. End;
  1539. End;
  1540. Function FormatFloat(Const format: String; Value: Extended): String;
  1541. Var
  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. function FormatCurr(const Format: string; Value: Currency): string;
  1548. begin
  1549. Result := FormatFloat(Format, Value);
  1550. end;
  1551. {==============================================================================}
  1552. { extra functions }
  1553. {==============================================================================}
  1554. { LeftStr returns Count left-most characters from S }
  1555. function LeftStr(const S: string; Count: integer): string;
  1556. begin
  1557. result := Copy(S, 1, Count);
  1558. end ;
  1559. { RightStr returns Count right-most characters from S }
  1560. function RightStr(const S: string; Count: integer): string;
  1561. begin
  1562. If Count>Length(S) then
  1563. Count:=Length(S);
  1564. result := Copy(S, 1 + Length(S) - Count, Count);
  1565. end;
  1566. { BCDToInt converts the BCD value Value to an integer }
  1567. function BCDToInt(Value: integer): integer;
  1568. var i, j: integer;
  1569. begin
  1570. result := 0;
  1571. j := 1;
  1572. for i := 0 to SizeOf(Value) shr 1 - 1 do begin
  1573. result := result + j * (Value and 15);
  1574. j := j * 10;
  1575. Value := Value shr 4;
  1576. end ;
  1577. end ;
  1578. Function LastDelimiter(const Delimiters, S: string): Integer;
  1579. begin
  1580. Result:=Length(S);
  1581. While (Result>0) and (Pos(S[Result],Delimiters)=0) do
  1582. Dec(Result);
  1583. end;
  1584. Function StringReplace(const S, OldPattern, NewPattern: string; Flags: TReplaceFlags): string;
  1585. var
  1586. Srch,OldP,RemS: string; // Srch and Oldp can contain uppercase versions of S,OldPattern
  1587. P : Integer;
  1588. begin
  1589. Srch:=S;
  1590. OldP:=OldPattern;
  1591. if rfIgnoreCase in Flags then
  1592. begin
  1593. Srch:=UpperCase(Srch);
  1594. OldP:=UpperCase(OldP);
  1595. end;
  1596. RemS:=S;
  1597. Result:='';
  1598. while (Length(Srch)<>0) do
  1599. begin
  1600. P:=Pos(OldP, Srch);
  1601. if P=0 then
  1602. begin
  1603. Result:=Result+RemS;
  1604. Srch:='';
  1605. end
  1606. else
  1607. begin
  1608. Result:=Result+Copy(RemS,1,P-1)+NewPattern;
  1609. P:=P+Length(OldP);
  1610. RemS:=Copy(RemS,P,Length(RemS)-P+1);
  1611. if not (rfReplaceAll in Flags) then
  1612. begin
  1613. Result:=Result+RemS;
  1614. Srch:='';
  1615. end
  1616. else
  1617. Srch:=Copy(Srch,P,Length(Srch)-P+1);
  1618. end;
  1619. end;
  1620. end;
  1621. Function IsDelimiter(const Delimiters, S: string; Index: Integer): Boolean;
  1622. begin
  1623. Result:=False;
  1624. If (Index>0) and (Index<=Length(S)) then
  1625. Result:=Pos(S[Index],Delimiters)<>0; // Note we don't do MBCS yet
  1626. end;
  1627. Function ByteToCharLen(const S: string; MaxLen: Integer): Integer;
  1628. begin
  1629. Result:=Length(S);
  1630. If Result>MaxLen then
  1631. Result:=MaxLen;
  1632. end;
  1633. Function ByteToCharIndex(const S: string; Index: Integer): Integer;
  1634. begin
  1635. Result:=Index;
  1636. end;
  1637. Function CharToByteLen(const S: string; MaxLen: Integer): Integer;
  1638. begin
  1639. Result:=Length(S);
  1640. If Result>MaxLen then
  1641. Result:=MaxLen;
  1642. end;
  1643. Function CharToByteIndex(const S: string; Index: Integer): Integer;
  1644. begin
  1645. Result:=Index;
  1646. end;
  1647. Function ByteType(const S: string; Index: Integer): TMbcsByteType;
  1648. begin
  1649. Result:=mbSingleByte;
  1650. end;
  1651. Function StrByteType(Str: PChar; Index: Cardinal): TMbcsByteType;
  1652. begin
  1653. Result:=mbSingleByte;
  1654. end;
  1655. Function StrCharLength(const Str: PChar): Integer;
  1656. begin
  1657. {$ifdef HASWIDESTRING}
  1658. result:=widestringmanager.CharLengthPCharProc(Str);
  1659. {$endif HASWIDESTRING}
  1660. end;
  1661. Function FindCmdLineSwitch(const Switch: string; const Chars: TSysCharSet;IgnoreCase: Boolean): Boolean;
  1662. Var
  1663. I,L : Integer;
  1664. S,T : String;
  1665. begin
  1666. Result:=False;
  1667. S:=Switch;
  1668. If IgnoreCase then
  1669. S:=UpperCase(S);
  1670. I:=ParamCount;
  1671. While (Not Result) and (I>0) do
  1672. begin
  1673. L:=Length(Paramstr(I));
  1674. If (L>0) and (ParamStr(I)[1] in Chars) then
  1675. begin
  1676. T:=Copy(ParamStr(I),2,L-1);
  1677. If IgnoreCase then
  1678. T:=UpperCase(T);
  1679. Result:=S=T;
  1680. end;
  1681. Dec(i);
  1682. end;
  1683. end;
  1684. Function FindCmdLineSwitch(const Switch: string; IgnoreCase: Boolean): Boolean;
  1685. begin
  1686. Result:=FindCmdLineSwitch(Switch,SwitchChars,IgnoreCase);
  1687. end;
  1688. Function FindCmdLineSwitch(const Switch: string): Boolean;
  1689. begin
  1690. Result:=FindCmdLineSwitch(Switch,SwitchChars,False);
  1691. end;
  1692. function WrapText(const Line, BreakStr: string; const BreakChars: TSysCharSet; MaxCol: Integer): string;
  1693. const
  1694. Quotes = ['''', '"'];
  1695. Var
  1696. L : String;
  1697. C,LQ,BC : Char;
  1698. P,BLen,Len : Integer;
  1699. HB,IBC : Boolean;
  1700. begin
  1701. Result:='';
  1702. L:=Line;
  1703. Blen:=Length(BreakStr);
  1704. If (BLen>0) then
  1705. BC:=BreakStr[1]
  1706. else
  1707. BC:=#0;
  1708. Len:=Length(L);
  1709. While (Len>0) do
  1710. begin
  1711. P:=1;
  1712. LQ:=#0;
  1713. HB:=False;
  1714. IBC:=False;
  1715. While ((P<=Len) and ((P<=MaxCol) or not IBC)) and ((LQ<>#0) or Not HB) do
  1716. begin
  1717. C:=L[P];
  1718. If (C=LQ) then
  1719. LQ:=#0
  1720. else If (C in Quotes) then
  1721. LQ:=C;
  1722. If (LQ<>#0) then
  1723. Inc(P)
  1724. else
  1725. begin
  1726. HB:=((C=BC) and (BreakStr=Copy(L,P,BLen)));
  1727. If HB then
  1728. Inc(P,Blen)
  1729. else
  1730. begin
  1731. If (P>MaxCol) then
  1732. IBC:=C in BreakChars;
  1733. Inc(P);
  1734. end;
  1735. end;
  1736. // Writeln('"',C,'" : IBC : ',IBC,' HB : ',HB,' LQ : ',LQ,' P>MaxCol : ',P>MaxCol);
  1737. end;
  1738. Result:=Result+Copy(L,1,P-1);
  1739. If Not HB then
  1740. Result:=Result+BreakStr;
  1741. Delete(L,1,P-1);
  1742. Len:=Length(L);
  1743. end;
  1744. end;
  1745. function WrapText(const Line: string; MaxCol: Integer): string;
  1746. begin
  1747. Result:=WrapText(Line,sLineBreak, [' ', '-', #9], MaxCol);
  1748. end;
  1749. {
  1750. Case Translation Tables
  1751. Can be used in internationalization support.
  1752. Although these tables can be obtained through system calls
  1753. it is better to not use those, since most implementation are not 100%
  1754. WARNING:
  1755. before modifying a translation table make sure that the current codepage
  1756. of the OS corresponds to the one you make changes to
  1757. }
  1758. const
  1759. { upper case translation table for character set 850 }
  1760. CP850UCT: array[128..255] of char =
  1761. ('€', 'š', '�', '¶', 'Ž', '¶', '�', '€', 'Ò', 'Ó', 'Ô', 'Ø', '×', 'Þ', 'Ž', '�',
  1762. '�', '’', '’', 'â', '™', 'ã', 'ê', 'ë', 'Y', '™', 'š', '�', 'œ', '�', 'ž', 'Ÿ',
  1763. 'µ', 'Ö', 'à', 'é', '¥', '¥', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1764. '°', '±', '²', '³', '´', 'µ', '¶', '·', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1765. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Ç', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1766. 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', '×', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß',
  1767. 'à', 'á', 'â', 'ã', 'å', 'å', 'æ', 'í', 'è', 'é', 'ê', 'ë', 'í', 'í', 'î', 'ï',
  1768. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1769. { lower case translation table for character set 850 }
  1770. CP850LCT: array[128..255] of char =
  1771. ('‡', '�', '‚', 'ƒ', '„', '…', '†', '‡', 'ˆ', '‰', 'Š', '‹', 'Œ', '�', '„', '†',
  1772. '‚', '‘', '‘', '“', '”', '•', '–', '—', '˜', '”', '�', '›', 'œ', '›', 'ž', 'Ÿ',
  1773. ' ', '¡', '¢', '£', '¤', '¤', '¦', '§', '¨', '©', 'ª', '«', '¬', '­', '®', '¯',
  1774. '°', '±', '²', '³', '´', ' ', 'ƒ', '…', '¸', '¹', 'º', '»', '¼', '½', '¾', '¿',
  1775. 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Æ', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
  1776. 'Ð', 'Ñ', 'ˆ', '‰', 'Š', 'Õ', '¡', 'Œ', '‹', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', '�', 'ß',
  1777. '¢', 'á', '“', '•', 'ä', 'ä', 'æ', 'í', 'è', '£', '–', '—', 'ì', 'ì', 'î', 'ï',
  1778. 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', '÷', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'þ', 'ÿ');
  1779. { upper case translation table for character set ISO 8859/1 Latin 1 }
  1780. CPISO88591UCT: array[192..255] of char =
  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, #215,
  1784. #216, #217, #218, #219, #220, #221, #222, #223,
  1785. #192, #193, #194, #195, #196, #197, #198, #199,
  1786. #200, #201, #202, #203, #204, #205, #206, #207,
  1787. #208, #209, #210, #211, #212, #213, #214, #247,
  1788. #216, #217, #218, #219, #220, #221, #222, #89 );
  1789. { lower case translation table for character set ISO 8859/1 Latin 1 }
  1790. CPISO88591LCT: array[192..255] of char =
  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, #215,
  1794. #248, #249, #250, #251, #252, #253, #254, #223,
  1795. #224, #225, #226, #227, #228, #229, #230, #231,
  1796. #232, #233, #234, #235, #236, #237, #238, #239,
  1797. #240, #241, #242, #243, #244, #245, #246, #247,
  1798. #248, #249, #250, #251, #252, #253, #254, #255 );
  1799. {
  1800. $Log: sysstr.inc,v $
  1801. Revision 1.38 2005/05/09 18:35:06 michael
  1802. + Fixed bug 3957
  1803. Revision 1.37 2005/04/28 09:15:44 florian
  1804. + variants: string -> float/int casts
  1805. Revision 1.36 2005/04/26 16:40:51 michael
  1806. + Added FormatCurr by Uberto Barbini
  1807. Revision 1.35 2005/03/25 22:53:39 jonas
  1808. * fixed several warnings and notes about unused variables (mainly) or
  1809. uninitialised use of variables/function results (a few)
  1810. Revision 1.34 2005/03/13 14:30:24 marco
  1811. * some 1.0.x fixes
  1812. Revision 1.33 2005/03/12 14:56:22 florian
  1813. + added Ansi* routines to widestring manager
  1814. * made them using OS calls on windows
  1815. Revision 1.32 2005/03/01 19:23:03 jonas
  1816. * fixed newstr() and disposestr()
  1817. Revision 1.31 2005/02/28 11:12:17 jonas
  1818. * fixed web bug 3708
  1819. Revision 1.30 2005/02/26 10:21:17 florian
  1820. + implemented WideFormat
  1821. + some Widestring stuff implemented
  1822. * some Widestring stuff fixed
  1823. Revision 1.29 2005/02/14 17:13:31 peter
  1824. * truncate log
  1825. Revision 1.28 2005/02/07 08:29:00 michael
  1826. + Patch from peter to fix 1.0 compile
  1827. Revision 1.27 2005/02/06 09:38:45 florian
  1828. + StrCharLength infrastructure
  1829. Revision 1.26 2005/01/17 18:38:48 peter
  1830. * extended overload disabled for powerpc
  1831. Revision 1.25 2005/01/16 17:53:27 michael
  1832. + Patch from Colin Western to implemenet TryStrToFLoat
  1833. }