sysstr.inc 53 KB

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