generic.inc 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. Processor independent implementation for the system unit
  6. (adapted for intel i386.inc file)
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  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.
  12. **********************************************************************}
  13. {****************************************************************************
  14. Primitives
  15. ****************************************************************************}
  16. type
  17. pstring = ^shortstring;
  18. {$ifndef FPC_SYSTEM_HAS_MOVE}
  19. procedure Move(const source;var dest;count:longint);
  20. type
  21. bytearray = array [0..maxlongint] of byte;
  22. var
  23. i,size : longint;
  24. begin
  25. Dec(count);
  26. for i:=0 to count do
  27. bytearray(dest)[i]:=bytearray(source)[i];
  28. end;
  29. {$endif ndef FPC_SYSTEM_HAS_MOVE}
  30. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  31. Procedure FillChar(var x;count:longint;value:byte);
  32. type
  33. longintarray = array [0..maxlongint] of longint;
  34. bytearray = array [0..maxlongint] of byte;
  35. var
  36. i,v : longint;
  37. begin
  38. if count = 0 then exit;
  39. v := 0;
  40. v:=(value shl 8) or (value and $FF);
  41. v:=(v shl 16) or (v and $ffff);
  42. for i:=0 to (count div 4) -1 do
  43. longintarray(x)[i]:=v;
  44. for i:=(count div 4)*4 to count-1 do
  45. bytearray(x)[i]:=value;
  46. end;
  47. {$endif ndef FPC_SYSTEM_HAS_FILLCHAR}
  48. {$ifndef FPC_SYSTEM_HAS_FILLBYTE}
  49. procedure FillByte (var x;count : longint;value : byte );
  50. begin
  51. FillChar (X,Count,CHR(VALUE));
  52. end;
  53. {$endif ndef FPC_SYSTEM_HAS_FILLBYTE}
  54. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  55. procedure fillword(var x;count : longint;value : word);
  56. type
  57. longintarray = array [0..maxlongint] of longint;
  58. wordarray = array [0..maxlongint] of word;
  59. var
  60. i,v : longint;
  61. begin
  62. v:=value*$10000+value;
  63. for i:=0 to (count div 2) -1 do
  64. longintarray(x)[i]:=v;
  65. for i:=(count div 2)*2 to count-1 do
  66. wordarray(x)[i]:=value;
  67. end;
  68. {$endif ndef FPC_SYSTEM_HAS_FILLWORD}
  69. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  70. procedure FillDWord(var x;count : longint;value : DWord);
  71. type
  72. longintarray = array [0..maxlongint] of longint;
  73. var
  74. I : longint;
  75. begin
  76. if Count<>0 then
  77. begin
  78. I:=Count;
  79. while I<>0 do
  80. begin
  81. longintarray(X)[I-1]:=Value;
  82. Dec(I);
  83. end;
  84. end;
  85. end;
  86. {$endif ndef FPC_SYSTEM_HAS_FILLDWORD}
  87. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR}
  88. function IndexChar(var buf;len:longint;b:char):longint;
  89. begin
  90. IndexChar:=IndexByte(Buf,Len,byte(B));
  91. end;
  92. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR}
  93. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  94. function IndexByte(var buf;len:longint;b:byte):longint;
  95. type
  96. bytearray = array [0..maxlongint] of byte;
  97. var
  98. I : longint;
  99. begin
  100. I:=0;
  101. while (bytearray(buf)[I]<>b) and (I<Len) do
  102. inc(I);
  103. if (i=Len) then
  104. i:=-1; {Can't use 0, since it is a possible value}
  105. IndexByte:=I;
  106. end;
  107. {$endif ndef FPC_SYSTEM_HAS_INDEXBYTE}
  108. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  109. function Indexword(var buf;len:longint;b:word):longint;
  110. type
  111. wordarray = array [0..maxlongint] of word;
  112. var
  113. I : longint;
  114. begin
  115. I:=0;
  116. while (wordarray(buf)[I]<>b) and (I<Len) do
  117. inc(I);
  118. if (i=Len) then
  119. i:=-1; {Can't use 0, since it is a possible value for index}
  120. Indexword:=I;
  121. end;
  122. {$endif ndef FPC_SYSTEM_HAS_INDEXWORD}
  123. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  124. function IndexDWord(var buf;len:longint;b:DWord):longint;
  125. type
  126. longintarray = array [0..maxlongint] of longint;
  127. var
  128. I : longint;
  129. begin
  130. I:=0;
  131. while (longintarray(buf)[I]<>b) and (I<Len) do inc(I);
  132. if (i=Len) then
  133. i:=-1; {Can't use 0, since it is a possible value for index}
  134. IndexDWord:=I;
  135. end;
  136. {$endif ndef FPC_SYSTEM_HAS_INDEXDWORD}
  137. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR}
  138. function CompareChar(var buf1,buf2;len:longint):longint;
  139. begin
  140. CompareChar:=CompareByte(buf1,buf2,len);
  141. end;
  142. {$endif ndef FPC_SYSTEM_HAS_COMPARECHAR}
  143. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  144. function CompareByte(var buf1,buf2;len:longint):longint;
  145. type
  146. bytearray = array [0..maxlongint] of byte;
  147. var
  148. I,J : longint;
  149. begin
  150. I:=0;
  151. if (Len<>0) and (@Buf1<>@Buf2) then
  152. begin
  153. while (bytearray(Buf1)[I]=bytearray(Buf2)[I]) and (I<Len) do
  154. inc(I);
  155. if I=Len then {No difference}
  156. I:=0
  157. else
  158. begin
  159. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  160. if I>0 then
  161. I:=1
  162. else
  163. if I<0 then
  164. I:=-1;
  165. end;
  166. end;
  167. CompareByte:=I;
  168. end;
  169. {$endif ndef FPC_SYSTEM_HAS_COMPAREBYTE}
  170. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  171. function CompareWord(var buf1,buf2;len:longint):longint;
  172. type
  173. wordarray = array [0..maxlongint] of word;
  174. var
  175. I,J : longint;
  176. begin
  177. I:=0;
  178. if (Len<>0) and (@Buf1<>@Buf2) then
  179. begin
  180. while (wordarray(Buf1)[I]=wordarray(Buf2)[I]) and (I<Len) do
  181. inc(I);
  182. if I=Len then {No difference}
  183. I:=0
  184. else
  185. begin
  186. I:=wordarray(Buf1)[I]-wordarray(Buf2)[I];
  187. if I>0 then
  188. I:=1
  189. else
  190. if I<0 then
  191. I:=-1;
  192. end;
  193. end;
  194. CompareWord:=I;
  195. end;
  196. {$endif ndef FPC_SYSTEM_HAS_COMPAREWORD}
  197. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  198. function CompareDWord(var buf1,buf2;len:longint):longint;
  199. type
  200. longintarray = array [0..maxlongint] of longint;
  201. var
  202. I,J : longint;
  203. begin
  204. I:=0;
  205. if (Len<>0) and (@Buf1<>@Buf2) then
  206. begin
  207. while (longintarray(Buf1)[I]=longintarray(Buf2)[I]) and (I<Len) do
  208. inc(I);
  209. if I=Len then {No difference}
  210. I:=0
  211. else
  212. begin
  213. I:=longintarray(Buf1)[I]-longintarray(Buf2)[I];
  214. if I>0 then
  215. I:=1
  216. else
  217. if I<0 then
  218. I:=-1;
  219. end;
  220. end;
  221. CompareDWord:=I;
  222. end;
  223. {$endif ndef FPC_SYSTEM_HAS_COMPAREDWORD}
  224. {$ifndef FPC_SYSTEM_HAS_MOVECHAR0}
  225. procedure MoveChar0(var buf1,buf2;len:longint);
  226. var
  227. I : longint;
  228. begin
  229. if Len<> 0 then
  230. begin
  231. I:=IndexByte(Buf1,Len,0);
  232. if I<>0 then
  233. Move(Buf1,Buf2,I);
  234. end;
  235. end;
  236. {$endif ndef FPC_SYSTEM_HAS_MOVECHAR0}
  237. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR0}
  238. function IndexChar0(var buf;len:longint;b:Char):longint;
  239. var
  240. I : longint;
  241. begin
  242. if Len<>0 then
  243. begin
  244. I:=IndexByte(Buf,Len,0);
  245. IndexChar0:=IndexByte(Buf,I,0);
  246. end
  247. else
  248. IndexChar0:=0;
  249. end;
  250. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR0}
  251. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR0}
  252. function CompareChar0(var buf1,buf2;len:longint):longint;
  253. type
  254. bytearray = array [0..maxlongint] of byte;
  255. Var i : longint;
  256. begin
  257. I:=0;
  258. if (Len<>0) and (@Buf1<>@Buf2) then
  259. begin
  260. while (I<Len) And
  261. ((Pbyte(@Buf1)[i]<>0) and (PByte(@buf2)[i]<>0)) and
  262. (pbyte(@Buf1)[I]=pbyte(@Buf2)[I]) do
  263. inc(I);
  264. if (I=Len) or
  265. (PByte(@Buf1)[i]=0) or
  266. (PByte(@buf2)[I]=0) then {No difference or 0 reached }
  267. I:=0
  268. else
  269. begin
  270. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  271. if I>0 then
  272. I:=1
  273. else
  274. if I<0 then
  275. I:=-1;
  276. end;
  277. end;
  278. CompareChar0:=I;
  279. end;
  280. {$endif ndef FPC_SYSTEM_HAS_COMPARECHAR0}
  281. {****************************************************************************
  282. Object Helpers
  283. ****************************************************************************}
  284. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  285. { Generic code does not set the register used for self !
  286. So this needs to be done by the compiler after calling
  287. FPC_HELP_CONSTRUCTOR : generic allways means aa little less efficient (PM) }
  288. { I don't think we really need to save any registers here }
  289. { since this is called at the start of the constructor (CEC) }
  290. procedure int_help_constructor(var _self : pointer; vmt : pointer; vmt_pos : cardinal); [public,alias:'FPC_HELP_CONSTRUCTOR'];
  291. type
  292. ppointer = ^pointer;
  293. pvmt = ^tvmt;
  294. tvmt = packed record
  295. size,msize : longint;
  296. parent : pointer;
  297. end;
  298. var
  299. objectsize : longint;
  300. begin
  301. objectsize:=pvmt(vmt)^.size;
  302. getmem(_self,objectsize);
  303. fillchar(_self,objectsize,#0);
  304. ppointer(_self+vmt_pos)^:=vmt;
  305. end;
  306. {$endif ndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  307. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  308. procedure int_help_destructor(var _self : pointer; vmt : pointer; vmt_pos : cardinal);saveregisters;[public,alias:'FPC_HELP_DESTRUCTOR'];
  309. type
  310. ppointer = ^pointer;
  311. pvmt = ^tvmt;
  312. tvmt = packed record
  313. size,msize : longint;
  314. parent : pointer;
  315. end;
  316. var
  317. objectsize : longint;
  318. begin
  319. if (_self=nil) then
  320. exit;
  321. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  322. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  323. RunError(210);
  324. objectsize:=pvmt(vmt)^.size;
  325. { reset vmt to nil for protection }
  326. ppointer(_self+vmt_pos)^:=nil;
  327. freemem(_self,objectsize);
  328. _self:=nil;
  329. end;
  330. {$endif ndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  331. {$ifndef FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  332. {$error No pascal version of Int_new_class}
  333. (* procedure int_new_class;assembler;saveregisters;[public,alias:'FPC_NEW_CLASS'];
  334. asm
  335. { to be sure in the future, we save also edit }
  336. pushl %edi
  337. { create class ? }
  338. movl 8(%ebp),%edi
  339. orl %edi,%edi
  340. jz .LNEW_CLASS1
  341. { save registers !! }
  342. pushl %ebx
  343. pushl %ecx
  344. pushl %edx
  345. { esi contains the vmt }
  346. pushl %esi
  347. { call newinstance (class method!) }
  348. call *16(%esi)
  349. popl %edx
  350. popl %ecx
  351. popl %ebx
  352. { newinstance returns a pointer to the new created }
  353. { instance in eax }
  354. { load esi and insert self }
  355. movl %eax,%esi
  356. .LNEW_CLASS1:
  357. movl %esi,8(%ebp)
  358. orl %eax,%eax
  359. popl %edi
  360. end; *)
  361. {$endif ndef FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  362. {$ifndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  363. {$error No pascal version of Int_dispose_class}
  364. (* procedure int_dispose_class;assembler;saveregisters;[public,alias:'FPC_DISPOSE_CLASS'];
  365. asm
  366. { to be sure in the future, we save also edit }
  367. pushl %edi
  368. { destroy class ? }
  369. movl 12(%ebp),%edi
  370. orl %edi,%edi
  371. jz .LDISPOSE_CLASS1
  372. { no inherited call }
  373. movl (%esi),%edi
  374. { save registers !! }
  375. pushl %eax
  376. pushl %ebx
  377. pushl %ecx
  378. pushl %edx
  379. { push self }
  380. pushl %esi
  381. { call freeinstance }
  382. call *20(%edi)
  383. popl %edx
  384. popl %ecx
  385. popl %ebx
  386. popl %eax
  387. .LDISPOSE_CLASS1:
  388. popl %edi
  389. end; *)
  390. {$endif ndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  391. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  392. procedure int_check_object(vmt : pointer);saveregisters;[public,alias:'FPC_CHECK_OBJECT'];
  393. type
  394. pvmt = ^tvmt;
  395. tvmt = packed record
  396. size,msize : longint;
  397. parent : pointer;
  398. end;
  399. begin
  400. if (vmt=nil) or
  401. (pvmt(vmt)^.size=0) or
  402. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  403. RunError(210);
  404. end;
  405. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  406. { checks for a correct vmt pointer }
  407. { deeper check to see if the current object is }
  408. { really related to the true }
  409. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  410. procedure int_check_object_ext(vmt, expvmt : pointer);saveregisters;[public,alias:'FPC_CHECK_OBJECT_EXT'];
  411. type
  412. pvmt = ^tvmt;
  413. tvmt = packed record
  414. size,msize : longint;
  415. parent : pointer;
  416. end;
  417. begin
  418. if (vmt=nil) or
  419. (pvmt(vmt)^.size=0) or
  420. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  421. RunError(210);
  422. while assigned(vmt) do
  423. if vmt=expvmt then
  424. exit
  425. else
  426. vmt:=pvmt(vmt)^.parent;
  427. RunError(220);
  428. end;
  429. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  430. {****************************************************************************
  431. String
  432. ****************************************************************************}
  433. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
  434. procedure int_strcopy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY'];
  435. var
  436. slen : byte;
  437. begin
  438. if dstr=nil then
  439. exit;
  440. if sstr=nil then
  441. begin
  442. if dstr<>nil then
  443. pstring(dstr)^[0]:=#0;
  444. exit;
  445. end;
  446. slen:=length(pstring(sstr)^);
  447. if slen<len then
  448. len:=slen;
  449. { don't forget the length character }
  450. if len <> 0 then
  451. move(sstr^,dstr^,len+1);
  452. pstring(dstr)^[0]:=chr(len);
  453. end;
  454. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COPY}
  455. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  456. procedure int_strconcat(s1,s2:pointer);[public,alias:'FPC_SHORTSTR_CONCAT'];
  457. var
  458. s1l, s2l : byte;
  459. begin
  460. if (s1=nil) or (s2=nil) then
  461. exit;
  462. s1l:=length(pstring(s1)^);
  463. s2l:=length(pstring(s2)^);
  464. if s1l+s2l>255 then
  465. s1l:=255-s2l;
  466. move(pstring(s1)^[1],pstring(s2)^[s2l+1],s1l);
  467. pstring(s2)^[0]:=chr(s1l+s2l);
  468. end;
  469. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  470. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  471. function int_strcmp(dstr,sstr:pointer) : longint;[public,alias:'FPC_SHORTSTR_COMPARE'];
  472. var
  473. s1,s2,max,i : byte;
  474. d : longint;
  475. begin
  476. s1:=length(pstring(dstr)^);
  477. s2:=length(pstring(sstr)^);
  478. if s1<s2 then
  479. max:=s1
  480. else
  481. max:=s2;
  482. for i:=1 to max do
  483. begin
  484. d:=byte(pstring(dstr)^[i])-byte(pstring(sstr)^[i]);
  485. if d>0 then
  486. exit(1)
  487. else if d<0 then
  488. exit(-1);
  489. end;
  490. if s1>s2 then
  491. exit(1)
  492. else if s1<s2 then
  493. exit(-1)
  494. else
  495. exit(0);
  496. end;
  497. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  498. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  499. function strpas(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR'];
  500. var
  501. l : longint;
  502. s: shortstring;
  503. begin
  504. if p=nil then
  505. l:=0
  506. else
  507. l:=strlen(p);
  508. if l>255 then
  509. l:=255;
  510. if l>0 then
  511. move(p^,s[1],l);
  512. s[0]:=chr(l);
  513. strpas := s;
  514. end;
  515. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  516. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  517. function strchararray(p:pchar; l : longint):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR'];
  518. var
  519. s: shortstring;
  520. begin
  521. if l>=256 then
  522. l:=255
  523. else if l<0 then
  524. l:=0;
  525. move(p^,s[1],l);
  526. s[0]:=chr(l);
  527. strchararray := s;
  528. end;
  529. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  530. {$ifopt r+}
  531. {$define rangeon}
  532. {$r-}
  533. {$endif}
  534. {$ifndef FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  535. procedure str_to_chararray(strtyp, arraysize: longint; src,dest: pchar);[public,alias:'FPC_STR_TO_CHARARRAY'];
  536. type
  537. plongint = ^longint;
  538. var
  539. len: longint;
  540. begin
  541. case strtyp of
  542. { shortstring }
  543. 0:
  544. begin
  545. len := byte(src[0]);
  546. inc(src);
  547. end;
  548. { ansistring}
  549. 1: len := length(ansistring(pointer(src)));
  550. { longstring }
  551. 2:;
  552. { widestring }
  553. 3:;
  554. end;
  555. if len > arraysize then
  556. len := arraysize;
  557. { make sure we don't dereference src if it can be nil (JM) }
  558. if len > 0 then
  559. move(src^,dest^,len);
  560. fillchar(dest[len],arraysize-len,0);
  561. end;
  562. {$endif FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  563. {$ifdef rangeon}
  564. {$r+}
  565. {undef rangeon}
  566. {$endif rangeon}
  567. {$ifndef FPC_SYSTEM_HAS_STRLEN}
  568. function strlen(p:pchar):longint;
  569. var i : longint;
  570. begin
  571. i:=0;
  572. while p[i]<>#0 do inc(i);
  573. exit(i);
  574. end;
  575. {$endif ndef FPC_SYSTEM_HAS_STRLEN}
  576. {****************************************************************************
  577. Caller/StackFrame Helpers
  578. ****************************************************************************}
  579. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  580. {$error Get_frame must be defined for each processor }
  581. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  582. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  583. {$error Get_caller_addr must be defined for each processor }
  584. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  585. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  586. {$error Get_caller_frame must be defined for each processor }
  587. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  588. {****************************************************************************
  589. Math
  590. ****************************************************************************}
  591. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  592. function abs(l:longint):longint;[internconst:in_const_abs];
  593. begin
  594. if l<0 then
  595. abs:=-l
  596. else
  597. abs:=l;
  598. end;
  599. {$endif ndef FPC_SYSTEM_HAS_ABS_LONGINT}
  600. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  601. function odd(l:longint):boolean;
  602. begin
  603. odd:=boolean(l and 1);
  604. end;
  605. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  606. {$ifndef FPC_SYSTEM_HAS_ODD_CARDINAL}
  607. function odd(l:cardinal):boolean;
  608. begin
  609. odd:=boolean(l and 1);
  610. end;
  611. {$endif ndef FPC_SYSTEM_HAS_ODD_CARDINAL}
  612. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  613. function odd(l:int64):boolean;[internconst:in_const_odd];
  614. begin
  615. odd:=boolean(longint(l) and 1);
  616. end;
  617. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  618. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  619. function odd(l:qword):boolean;
  620. begin
  621. odd:=boolean(longint(l) and 1);
  622. end;
  623. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  624. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  625. function sqr(l:longint):longint;[internconst:in_const_sqr];
  626. begin
  627. sqr:=l*l;
  628. end;
  629. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  630. {$ifndef FPC_SYSTEM_HAS_SPTR}
  631. {$error Sptr must be defined for each processor }
  632. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  633. {****************************************************************************
  634. Str()
  635. ****************************************************************************}
  636. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  637. procedure int_str(l : longint;var s : string);
  638. var
  639. value: longint;
  640. negative: boolean;
  641. begin
  642. negative := false;
  643. s:='';
  644. { Workaround: }
  645. if l=$80000000 then
  646. begin
  647. s:='-2147483648';
  648. exit;
  649. end;
  650. { handle case where l = 0 }
  651. if l = 0 then
  652. begin
  653. s:='0';
  654. exit;
  655. end;
  656. If l < 0 then
  657. begin
  658. negative := true;
  659. value:=abs(l);
  660. end
  661. else
  662. value:=l;
  663. { handle non-zero case }
  664. while value>0 do
  665. begin
  666. s:=char((value mod 10)+ord('0'))+s;
  667. value := value div 10;
  668. end;
  669. if negative then
  670. s := '-' + s;
  671. end;
  672. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  673. {$ifndef FPC_SYSTEM_HAS_INT_STR_CARDINAL}
  674. procedure int_str(l : cardinal;var s : string);
  675. begin
  676. s:='';
  677. if l = 0 then
  678. begin
  679. s := '0';
  680. exit;
  681. end;
  682. while l>0 do
  683. begin
  684. s:=char(ord('0')+(l mod 10))+s;
  685. l:=l div 10;
  686. end;
  687. end;
  688. {$endif ndef FPC_SYSTEM_HAS_INT_STR_CARDINAL}
  689. {****************************************************************************
  690. Bounds Check
  691. ****************************************************************************}
  692. {$ifndef NOBOUNDCHECK}
  693. {$ifndef FPC_SYSTEM_HAS_FPC_BOUNDCHECK}
  694. procedure int_boundcheck(l : longint; range : pointer);[public,alias: 'FPC_BOUNDCHECK'];
  695. type
  696. prange = ^trange;
  697. trange = packed record
  698. min,max : longint;
  699. end;
  700. begin
  701. if (l < prange(range)^.min) or
  702. (l > prange(range)^.max) then
  703. HandleError(201);
  704. end;
  705. {$endif ndef FPC_SYSTEM_HAS_FPC_BOUNDCHECK}
  706. {$endif NOBOUNDCHECK}
  707. {
  708. $Log$
  709. Revision 1.13 2001-05-28 20:43:17 peter
  710. * more saveregisters added (merged)
  711. Revision 1.12 2001/05/18 22:59:59 peter
  712. * merged fixes branch fixes
  713. Revision 1.11 2001/05/16 17:44:25 jonas
  714. + odd() for cardinal, int64 and qword (merged)
  715. Revision 1.10 2001/05/09 19:57:07 peter
  716. *** empty log message ***
  717. Revision 1.9 2001/04/21 12:16:28 peter
  718. * int_str cardinal fix (merged)
  719. Revision 1.8 2001/04/13 18:06:28 peter
  720. * removed rtllite define
  721. Revision 1.7 2001/03/05 17:10:40 jonas
  722. * changed typecast in FPC_STR_TO_CHARARRAY so that no temp ansistring is
  723. generated anymore (merged)
  724. Revision 1.6 2001/03/03 12:41:22 jonas
  725. * simplified and optimized range checking code, FPC_BOUNDCHECK is no longer necessary
  726. Revision 1.5 2000/10/01 13:17:35 michael
  727. + Merged from fixbranch
  728. Revision 1.4 2000/08/09 11:29:01 jonas
  729. Revision 1.1.2.2 2000/10/01 13:14:50 michael
  730. + Corrected and (hopefully) improved compare0
  731. Revision 1.1.2.1 2000/08/09 11:21:32 jonas
  732. + FPC_STR_TO_CHARARRAY routine necessary for string -> chararray
  733. conversions fix (merged fropm fixes branch)
  734. Revision 1.3 2000/07/14 10:33:10 michael
  735. + Conditionals fixed
  736. Revision 1.2 2000/07/13 11:33:43 michael
  737. + removed logs
  738. }