sysstr.inc 52 KB

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