sysstr.inc 56 KB

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