generic.inc 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  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:SizeInt);[public, alias: 'FPC_MOVE'];
  20. type
  21. bytearray = array [0..high(sizeint)-1] of byte;
  22. var
  23. i:longint;
  24. begin
  25. if count <= 0 then exit;
  26. Dec(count);
  27. if @source<@dest then
  28. begin
  29. for i:=count downto 0 do
  30. bytearray(dest)[i]:=bytearray(source)[i];
  31. end
  32. else
  33. begin
  34. for i:=0 to count do
  35. bytearray(dest)[i]:=bytearray(source)[i];
  36. end;
  37. end;
  38. {$endif not FPC_SYSTEM_HAS_MOVE}
  39. {$ifndef FPC_SYSTEM_HAS_FILLCHAR}
  40. Procedure FillChar(var x;count:SizeInt;value:byte);
  41. type
  42. longintarray = array [0..high(sizeint) div 4-1] of longint;
  43. bytearray = array [0..high(sizeint)-1] of byte;
  44. var
  45. i,v : longint;
  46. begin
  47. if count <= 0 then exit;
  48. v := 0;
  49. { aligned? }
  50. if (PtrUInt(@x) mod sizeof(PtrUInt))<>0 then
  51. begin
  52. for i:=0 to count-1 do
  53. bytearray(x)[i]:=value;
  54. end
  55. else
  56. begin
  57. v:=(value shl 8) or (value and $FF);
  58. v:=(v shl 16) or (v and $ffff);
  59. for i:=0 to (count div 4)-1 do
  60. longintarray(x)[i]:=v;
  61. for i:=(count div 4)*4 to count-1 do
  62. bytearray(x)[i]:=value;
  63. end;
  64. end;
  65. {$endif FPC_SYSTEM_HAS_FILLCHAR}
  66. {$ifndef FPC_SYSTEM_HAS_FILLBYTE}
  67. procedure FillByte (var x;count : SizeInt;value : byte );
  68. begin
  69. FillChar (X,Count,CHR(VALUE));
  70. end;
  71. {$endif not FPC_SYSTEM_HAS_FILLBYTE}
  72. {$ifndef FPC_SYSTEM_HAS_FILLWORD}
  73. procedure fillword(var x;count : SizeInt;value : word);
  74. type
  75. longintarray = array [0..high(sizeint) div 4-1] of longint;
  76. wordarray = array [0..high(sizeint) div 2-1] of word;
  77. var
  78. i,v : longint;
  79. begin
  80. if Count <= 0 then exit;
  81. { aligned? }
  82. if (PtrUInt(@x) mod sizeof(PtrUInt))<>0 then
  83. begin
  84. for i:=0 to count-1 do
  85. wordarray(x)[i]:=value;
  86. end
  87. else
  88. begin
  89. v:=value*$10000+value;
  90. for i:=0 to (count div 2) -1 do
  91. longintarray(x)[i]:=v;
  92. for i:=(count div 2)*2 to count-1 do
  93. wordarray(x)[i]:=value;
  94. end;
  95. end;
  96. {$endif not FPC_SYSTEM_HAS_FILLWORD}
  97. {$ifndef FPC_SYSTEM_HAS_FILLDWORD}
  98. procedure FillDWord(var x;count : SizeInt;value : DWord);
  99. type
  100. longintarray = array [0..high(sizeint) div 4-1] of longint;
  101. begin
  102. if count <= 0 then exit;
  103. while Count<>0 do
  104. begin
  105. { range checking must be disabled here }
  106. longintarray(x)[count-1]:=longint(value);
  107. Dec(count);
  108. end;
  109. end;
  110. {$endif FPC_SYSTEM_HAS_FILLDWORD}
  111. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR}
  112. function IndexChar(Const buf;len:SizeInt;b:char):SizeInt;
  113. begin
  114. IndexChar:=IndexByte(Buf,Len,byte(B));
  115. end;
  116. {$endif not FPC_SYSTEM_HAS_INDEXCHAR}
  117. {$ifndef FPC_SYSTEM_HAS_INDEXBYTE}
  118. function IndexByte(Const buf;len:SizeInt;b:byte):SizeInt;
  119. type
  120. bytearray = array [0..high(sizeint)-1] of byte;
  121. var
  122. I : longint;
  123. begin
  124. I:=0;
  125. { simulate assembler implementations behaviour, which is expected }
  126. { fpc_pchar_to_ansistr in astrings.inc }
  127. if (len < 0) then
  128. len := high(longint);
  129. while (I<Len) and (bytearray(buf)[I]<>b) do
  130. inc(I);
  131. if (i=Len) then
  132. i:=-1; {Can't use 0, since it is a possible value}
  133. IndexByte:=I;
  134. end;
  135. {$endif not FPC_SYSTEM_HAS_INDEXBYTE}
  136. {$ifndef FPC_SYSTEM_HAS_INDEXWORD}
  137. function Indexword(Const buf;len:SizeInt;b:word):SizeInt;
  138. type
  139. wordarray = array [0..high(sizeint) div 2-1] of word;
  140. var
  141. I : longint;
  142. begin
  143. I:=0;
  144. if (len < 0) then
  145. len := high(longint);
  146. while (I<Len) and (wordarray(buf)[I]<>b) do
  147. inc(I);
  148. if (i=Len) then
  149. i:=-1; {Can't use 0, since it is a possible value for index}
  150. Indexword:=I;
  151. end;
  152. {$endif not FPC_SYSTEM_HAS_INDEXWORD}
  153. {$ifndef FPC_SYSTEM_HAS_INDEXDWORD}
  154. function IndexDWord(Const buf;len:SizeInt;b:DWord):SizeInt;
  155. type
  156. dwordarray = array [0..high(sizeint) div 4-1] of dword;
  157. var
  158. I : longint;
  159. begin
  160. I:=0;
  161. if (len < 0) then
  162. len := high(longint);
  163. while (I<Len) and (dwordarray(buf)[I]<>b) do
  164. inc(I);
  165. if (i=Len) then
  166. i:=-1; {Can't use 0, since it is a possible value for index}
  167. IndexDWord:=I;
  168. end;
  169. {$endif not FPC_SYSTEM_HAS_INDEXDWORD}
  170. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR}
  171. function CompareChar(Const buf1,buf2;len:SizeInt):SizeInt;
  172. begin
  173. CompareChar:=CompareByte(buf1,buf2,len);
  174. end;
  175. {$endif not FPC_SYSTEM_HAS_COMPARECHAR}
  176. {$ifndef FPC_SYSTEM_HAS_COMPAREBYTE}
  177. function CompareByte(Const buf1,buf2;len:SizeInt):SizeInt;
  178. type
  179. bytearray = array [0..high(sizeint)-1] of byte;
  180. var
  181. I : longint;
  182. begin
  183. I:=0;
  184. if (Len<>0) and (@Buf1<>@Buf2) then
  185. begin
  186. while (bytearray(Buf1)[I]=bytearray(Buf2)[I]) and (I<Len) do
  187. inc(I);
  188. if I=Len then {No difference}
  189. I:=0
  190. else
  191. begin
  192. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  193. if I>0 then
  194. I:=1
  195. else
  196. if I<0 then
  197. I:=-1;
  198. end;
  199. end;
  200. CompareByte:=I;
  201. end;
  202. {$endif not FPC_SYSTEM_HAS_COMPAREBYTE}
  203. {$ifndef FPC_SYSTEM_HAS_COMPAREWORD}
  204. function CompareWord(Const buf1,buf2;len:SizeInt):SizeInt;
  205. type
  206. wordarray = array [0..high(sizeint) div 2-1] of word;
  207. var
  208. I : longint;
  209. begin
  210. I:=0;
  211. if (Len<>0) and (@Buf1<>@Buf2) then
  212. begin
  213. while (wordarray(Buf1)[I]=wordarray(Buf2)[I]) and (I<Len) do
  214. inc(I);
  215. if I=Len then {No difference}
  216. I:=0
  217. else
  218. begin
  219. I:=wordarray(Buf1)[I]-wordarray(Buf2)[I];
  220. if I>0 then
  221. I:=1
  222. else
  223. if I<0 then
  224. I:=-1;
  225. end;
  226. end;
  227. CompareWord:=I;
  228. end;
  229. {$endif not FPC_SYSTEM_HAS_COMPAREWORD}
  230. {$ifndef FPC_SYSTEM_HAS_COMPAREDWORD}
  231. function CompareDWord(Const buf1,buf2;len:SizeInt):SizeInt;
  232. type
  233. longintarray = array [0..high(sizeint) div 4-1] of longint;
  234. var
  235. I : longint;
  236. begin
  237. I:=0;
  238. if (Len<>0) and (@Buf1<>@Buf2) then
  239. begin
  240. while (longintarray(Buf1)[I]=longintarray(Buf2)[I]) and (I<Len) do
  241. inc(I);
  242. if I=Len then {No difference}
  243. I:=0
  244. else
  245. begin
  246. I:=longintarray(Buf1)[I]-longintarray(Buf2)[I];
  247. if I>0 then
  248. I:=1
  249. else
  250. if I<0 then
  251. I:=-1;
  252. end;
  253. end;
  254. CompareDWord:=I;
  255. end;
  256. {$endif ndef FPC_SYSTEM_HAS_COMPAREDWORD}
  257. {$ifndef FPC_SYSTEM_HAS_MOVECHAR0}
  258. procedure MoveChar0(Const buf1;var buf2;len:SizeInt);
  259. var
  260. I : longint;
  261. begin
  262. if Len = 0 then exit;
  263. I:=IndexByte(Buf1,Len,0);
  264. if I<>-1 then
  265. Move(Buf1,Buf2,I)
  266. else
  267. Move(Buf1,Buf2,len);
  268. end;
  269. {$endif ndef FPC_SYSTEM_HAS_MOVECHAR0}
  270. {$ifndef FPC_SYSTEM_HAS_INDEXCHAR0}
  271. function IndexChar0(Const buf;len:SizeInt;b:Char):SizeInt;
  272. var
  273. I : longint;
  274. begin
  275. if Len<>0 then
  276. begin
  277. I:=IndexByte(Buf,Len,0);
  278. If (I=-1) then
  279. I:=Len;
  280. IndexChar0:=IndexByte(Buf,I,byte(b));
  281. end
  282. else
  283. IndexChar0:=0;
  284. end;
  285. {$endif ndef FPC_SYSTEM_HAS_INDEXCHAR0}
  286. {$ifndef FPC_SYSTEM_HAS_COMPARECHAR0}
  287. function CompareChar0(Const buf1,buf2;len:SizeInt):SizeInt;
  288. type
  289. bytearray = array [0..high(sizeint)-1] of byte;
  290. var
  291. i : longint;
  292. begin
  293. I:=0;
  294. if (Len<>0) and (@Buf1<>@Buf2) then
  295. begin
  296. while (I<Len) And
  297. ((Pbyte(@Buf1)[i]<>0) and (PByte(@buf2)[i]<>0)) and
  298. (pbyte(@Buf1)[I]=pbyte(@Buf2)[I]) do
  299. inc(I);
  300. if (I=Len) or
  301. (PByte(@Buf1)[i]=0) or
  302. (PByte(@buf2)[I]=0) then {No difference or 0 reached }
  303. I:=0
  304. else
  305. begin
  306. I:=bytearray(Buf1)[I]-bytearray(Buf2)[I];
  307. if I>0 then
  308. I:=1
  309. else
  310. if I<0 then
  311. I:=-1;
  312. end;
  313. end;
  314. CompareChar0:=I;
  315. end;
  316. {$endif not FPC_SYSTEM_HAS_COMPARECHAR0}
  317. {****************************************************************************
  318. Object Helpers
  319. ****************************************************************************}
  320. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  321. { Note: _vmt will be reset to -1 when memory is allocated,
  322. this is needed for fpc_help_fail }
  323. function fpc_help_constructor(_self:pointer;var _vmt:pointer;_vmt_pos:cardinal):pointer;[public,alias:'FPC_HELP_CONSTRUCTOR'];{$ifdef hascompilerproc}compilerproc;{$endif}
  324. type
  325. ppointer = ^pointer;
  326. pvmt = ^tvmt;
  327. tvmt=packed record
  328. size,msize:ptrint;
  329. parent:pointer;
  330. end;
  331. var
  332. vmtcopy : pointer;
  333. begin
  334. { Inherited call? }
  335. if _vmt=nil then
  336. begin
  337. fpc_help_constructor:=_self;
  338. exit;
  339. end;
  340. vmtcopy:=_vmt;
  341. if (_self=nil) and
  342. (pvmt(_vmt)^.size>0) then
  343. begin
  344. getmem(_self,pvmt(_vmt)^.size);
  345. { reset vmt needed for fail }
  346. _vmt:=pointer(-1);
  347. end;
  348. if _self<>nil then
  349. begin
  350. fillchar(_self^,pvmt(vmtcopy)^.size,#0);
  351. ppointer(_self+_vmt_pos)^:=vmtcopy;
  352. end;
  353. fpc_help_constructor:=_self;
  354. end;
  355. {$endif FPC_SYSTEM_HAS_FPC_HELP_CONSTRUCTOR}
  356. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  357. { Note: _self will not be reset, the compiler has to generate the reset }
  358. procedure fpc_help_destructor(_self,_vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_DESTRUCTOR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  359. type
  360. ppointer = ^pointer;
  361. pvmt = ^tvmt;
  362. tvmt = packed record
  363. size,msize : ptrint;
  364. parent : pointer;
  365. end;
  366. begin
  367. { already released? }
  368. if (_self=nil) or
  369. (_vmt=nil) or
  370. (ppointer(_self+vmt_pos)^=nil) then
  371. exit;
  372. if (pvmt(ppointer(_self+vmt_pos)^)^.size=0) or
  373. (pvmt(ppointer(_self+vmt_pos)^)^.size+pvmt(ppointer(_self+vmt_pos)^)^.msize<>0) then
  374. RunError(210);
  375. { reset vmt to nil for protection }
  376. ppointer(_self+vmt_pos)^:=nil;
  377. freemem(_self);
  378. end;
  379. {$endif FPC_SYSTEM_HAS_FPC_HELP_DESTRUCTOR}
  380. {$ifndef FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  381. { Note: _self will not be reset, the compiler has to generate the reset }
  382. procedure fpc_help_fail(_self:pointer;var _vmt:pointer;vmt_pos:cardinal);[public,alias:'FPC_HELP_FAIL'];compilerproc;
  383. type
  384. ppointer = ^pointer;
  385. pvmt = ^tvmt;
  386. tvmt = packed record
  387. size,msize : ptrint;
  388. parent : pointer;
  389. end;
  390. begin
  391. if (_self=nil) or (_vmt=nil) then
  392. exit;
  393. { vmt=-1 when memory was allocated }
  394. if ptrint(_vmt)=-1 then
  395. begin
  396. if (_self=nil) or (ppointer(_self+vmt_pos)^=nil) then
  397. HandleError(210)
  398. else
  399. begin
  400. ppointer(_self+vmt_pos)^:=nil;
  401. freemem(_self);
  402. { reset _vmt to nil so it will not be freed a
  403. second time }
  404. _vmt:=nil;
  405. end;
  406. end
  407. else
  408. ppointer(_self+vmt_pos)^:=nil;
  409. end;
  410. {$endif FPC_SYSTEM_HAS_FPC_HELP_FAIL}
  411. {$ifndef NOCLASSHELPERS}
  412. {$ifndef FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  413. function fpc_new_class(_self,_vmt:pointer):pointer;[public,alias:'FPC_NEW_CLASS']; {$ifdef hascompilerproc} compilerproc; {$endif}
  414. begin
  415. { Inherited call? }
  416. if _vmt=nil then
  417. begin
  418. fpc_new_class:=_self;
  419. exit;
  420. end;
  421. fpc_new_class := tclass(_vmt).NewInstance
  422. end;
  423. {$endif FPC_SYSTEM_HAS_FPC_NEW_CLASS}
  424. {$ifndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  425. procedure fpc_dispose_class(_self: pointer; flag : longint);[public,alias:'FPC_DISPOSE_CLASS'];compilerproc;
  426. begin
  427. { inherited -> flag = 0 -> no destroy }
  428. { normal -> flag = 1 -> destroy }
  429. if (_self <> nil) and (flag = 1) then
  430. tobject(_self).FreeInstance;
  431. end;
  432. {$endif ndef FPC_SYSTEM_HAS_FPC_DISPOSE_CLASS}
  433. {$endif NOCLASSHELPERS}
  434. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  435. procedure fpc_check_object(_vmt : pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif}[public,alias:'FPC_CHECK_OBJECT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  436. type
  437. pvmt = ^tvmt;
  438. tvmt = packed record
  439. size,msize : ptrint;
  440. parent : pointer;
  441. end;
  442. begin
  443. if (_vmt=nil) or
  444. (pvmt(_vmt)^.size=0) or
  445. (pvmt(_vmt)^.size+pvmt(_vmt)^.msize<>0) then
  446. RunError(210);
  447. end;
  448. {$endif ndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT}
  449. {$ifndef FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  450. { checks for a correct vmt pointer }
  451. { deeper check to see if the current object is }
  452. { really related to the true }
  453. procedure fpc_check_object_ext(vmt, expvmt : pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif}[public,alias:'FPC_CHECK_OBJECT_EXT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  454. type
  455. pvmt = ^tvmt;
  456. tvmt = packed record
  457. size,msize : ptrint;
  458. parent : pointer;
  459. end;
  460. begin
  461. if (vmt=nil) or
  462. (pvmt(vmt)^.size=0) or
  463. (pvmt(vmt)^.size+pvmt(vmt)^.msize<>0) then
  464. RunError(210);
  465. while assigned(vmt) do
  466. if vmt=expvmt then
  467. exit
  468. else
  469. vmt:=pvmt(vmt)^.parent;
  470. RunError(219);
  471. end;
  472. {$endif not FPC_SYSTEM_HAS_FPC_CHECK_OBJECT_EXT}
  473. {****************************************************************************
  474. String
  475. ****************************************************************************}
  476. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  477. function fpc_shortstr_to_shortstr(len:longint;const sstr:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  478. var
  479. slen : byte;
  480. begin
  481. slen:=length(sstr);
  482. if slen<len then
  483. len:=slen;
  484. move(sstr[0],result[0],len+1);
  485. if slen>len then
  486. result[0]:=chr(len);
  487. end;
  488. {$ifdef interncopy}
  489. procedure fpc_shortstr_assign(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_ASSIGN']; {$ifdef HAS_COMPILER_PROC} compilerproc; {$endif}
  490. {$else}
  491. procedure fpc_shortstr_copy(len:longint;sstr,dstr:pointer);[public,alias:'FPC_SHORTSTR_COPY']; {$ifdef HAS_COMPILER_PROC} compilerproc; {$endif}
  492. {$endif}
  493. var
  494. slen : byte;
  495. type
  496. pstring = ^string;
  497. begin
  498. slen:=length(pstring(sstr)^);
  499. if slen<len then
  500. len:=slen;
  501. move(sstr^,dstr^,len+1);
  502. if slen>len then
  503. pchar(dstr)^:=chr(len);
  504. end;
  505. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_ASSIGN}
  506. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  507. function fpc_shortstr_concat(const s1,s2:shortstring): shortstring;[public,alias:'FPC_SHORTSTR_CONCAT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  508. var
  509. s1l, s2l : byte;
  510. begin
  511. s1l:=length(s1);
  512. s2l:=length(s2);
  513. if s1l+s2l>255 then
  514. s2l:=255-s1l;
  515. move(s1[1],fpc_shortstr_concat[1],s1l);
  516. move(s2[1],fpc_shortstr_concat[s1l+1],s2l);
  517. fpc_shortstr_concat[0]:=chr(s1l+s2l);
  518. end;
  519. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_CONCAT}
  520. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  521. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring);{$ifdef hascompilerproc} compilerproc; {$endif}
  522. [public,alias:'FPC_SHORTSTR_APPEND_SHORTSTR'];
  523. var
  524. s1l, s2l : byte;
  525. begin
  526. s1l:=length(s1);
  527. s2l:=length(s2);
  528. if s1l+s2l>high(s1) then
  529. s2l:=high(s1)-s1l;
  530. move(s2[1],s1[s1l+1],s2l);
  531. s1[0]:=chr(s1l+s2l);
  532. end;
  533. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_APPEND_SHORTSTR}
  534. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  535. function fpc_shortstr_compare(const left,right:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
  536. var
  537. s1,s2,max,i : byte;
  538. d : longint;
  539. begin
  540. s1:=length(left);
  541. s2:=length(right);
  542. if s1<s2 then
  543. max:=s1
  544. else
  545. max:=s2;
  546. for i:=1 to max do
  547. begin
  548. d:=byte(left[i])-byte(right[i]);
  549. if d>0 then
  550. exit(1)
  551. else if d<0 then
  552. exit(-1);
  553. end;
  554. if s1>s2 then
  555. exit(1)
  556. else if s1<s2 then
  557. exit(-1)
  558. else
  559. exit(0);
  560. end;
  561. {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
  562. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  563. function fpc_pchar_to_shortstr(p:pchar):shortstring;[public,alias:'FPC_PCHAR_TO_SHORTSTR']; {$ifdef hascompilerproc} compilerproc; {$endif}
  564. var
  565. l : longint;
  566. s: shortstring;
  567. begin
  568. if p=nil then
  569. l:=0
  570. else
  571. l:=strlen(p);
  572. if l>255 then
  573. l:=255;
  574. if l>0 then
  575. move(p^,s[1],l);
  576. s[0]:=chr(l);
  577. fpc_pchar_to_shortstr := s;
  578. end;
  579. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_TO_SHORTSTR}
  580. {$ifndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  581. {$ifdef hascompilerproc}
  582. function fpc_chararray_to_shortstr(const arr: array of char):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR']; compilerproc;
  583. var
  584. l: longint;
  585. {$else hascompilerproc}
  586. function fpc_chararray_to_shortstr(arr:pchar; l : longint):shortstring;[public,alias:'FPC_CHARARRAY_TO_SHORTSTR'];
  587. var
  588. {$endif hascompilerproc}
  589. index: longint;
  590. len: byte;
  591. begin
  592. {$ifdef hascompilerproc}
  593. l := high(arr)+1;
  594. {$endif hascompilerproc}
  595. if l>=256 then
  596. l:=255
  597. else if l<0 then
  598. l:=0;
  599. index:=IndexByte(arr[0],l,0);
  600. if (index < 0) then
  601. len := l
  602. else
  603. len := index;
  604. move(arr[0],fpc_chararray_to_shortstr[1],len);
  605. fpc_chararray_to_shortstr[0]:=chr(len);
  606. end;
  607. {$endif ndef FPC_SYSTEM_HAS_FPC_CHARARRAY_TO_SHORTSTR}
  608. {$ifdef hascompilerproc}
  609. {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  610. { inside the compiler, the resulttype is modified to that of the actual }
  611. { chararray we're converting to (JM) }
  612. function fpc_shortstr_to_chararray(arraysize: longint; const src: ShortString): fpc_big_chararray;[public,alias: 'FPC_SHORTSTR_TO_CHARARRAY']; compilerproc;
  613. var
  614. len: longint;
  615. begin
  616. len := length(src);
  617. if len > arraysize then
  618. len := arraysize;
  619. { make sure we don't access char 1 if length is 0 (JM) }
  620. if len > 0 then
  621. move(src[1],fpc_shortstr_to_chararray[0],len);
  622. fillchar(fpc_shortstr_to_chararray[len],arraysize-len,0);
  623. end;
  624. {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_TO_CHARARRAY}
  625. {$else hascompilerproc}
  626. {$ifopt r+}
  627. {$define rangeon}
  628. {$r-}
  629. {$endif}
  630. {$ifndef FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  631. procedure fpc_str_to_chararray(strtyp, arraysize: longint; src,dest: pchar);[public,alias:'FPC_STR_TO_CHARARRAY']; {$ifdef hascompilerproc} compilerproc; {$endif}
  632. type
  633. plongint = ^longint;
  634. var
  635. len: longint;
  636. begin
  637. case strtyp of
  638. { shortstring }
  639. 0:
  640. begin
  641. len := byte(src[0]);
  642. inc(src);
  643. end;
  644. {$ifdef SUPPORT_ANSISTRING}
  645. { ansistring}
  646. 1: len := length(ansistring(pointer(src)));
  647. {$endif SUPPORT_ANSISTRING}
  648. { longstring }
  649. 2:;
  650. { widestring }
  651. 3: ;
  652. end;
  653. if len > arraysize then
  654. len := arraysize;
  655. { make sure we don't dereference src if it can be nil (JM) }
  656. if len > 0 then
  657. move(src^,dest^,len);
  658. fillchar(dest[len],arraysize-len,0);
  659. end;
  660. {$endif FPC_SYSTEM_HAS_FPC_STR_TO_CHARARRAY}
  661. {$ifdef rangeon}
  662. {$r+}
  663. {undef rangeon}
  664. {$endif rangeon}
  665. {$endif hascompilerproc}
  666. {$ifndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  667. function fpc_pchar_length(p:pchar):longint;[public,alias:'FPC_PCHAR_LENGTH']; {$ifdef hascompilerproc} compilerproc; {$endif}
  668. var i : longint;
  669. begin
  670. i:=0;
  671. while p[i]<>#0 do inc(i);
  672. exit(i);
  673. end;
  674. {$endif ndef FPC_SYSTEM_HAS_FPC_PCHAR_LENGTH}
  675. {$ifdef HASWIDESTRING}
  676. {$ifndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  677. function fpc_pwidechar_length(p:pwidechar):longint;[public,alias:'FPC_PWIDECHAR_LENGTH']; {$ifdef hascompilerproc} compilerproc; {$endif}
  678. var i : longint;
  679. begin
  680. i:=0;
  681. while p[i]<>#0 do inc(i);
  682. exit(i);
  683. end;
  684. {$endif ndef FPC_SYSTEM_HAS_FPC_PWIDECHAR_LENGTH}
  685. {$endif HASWIDESTRING}
  686. {****************************************************************************
  687. Caller/StackFrame Helpers
  688. ****************************************************************************}
  689. {$ifndef FPC_SYSTEM_HAS_GET_FRAME}
  690. {_$error Get_frame must be defined for each processor }
  691. {$endif ndef FPC_SYSTEM_HAS_GET_FRAME}
  692. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  693. {_$error Get_caller_addr must be defined for each processor }
  694. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  695. {$ifndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  696. {_$error Get_caller_frame must be defined for each processor }
  697. {$endif ndef FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  698. {****************************************************************************
  699. Math
  700. ****************************************************************************}
  701. {****************************************************************************
  702. Software longint/dword division
  703. ****************************************************************************}
  704. {$ifdef FPC_INCLUDE_SOFTWARE_MOD_DIV}
  705. function count_leading_zeros_32bit(l : longint) : longint;
  706. var
  707. i : longint;
  708. begin
  709. for i:=0 to 31 do
  710. begin
  711. if (l and (longint($80000000) shr i))<>0 then
  712. begin
  713. result:=i;
  714. exit;
  715. end;
  716. end;
  717. result:=i;
  718. end;
  719. {$ifndef FPC_SYSTEM_HAS_DIV_DWORD}
  720. function fpc_div_dword(n,z : dword) : dword; [public,alias: 'FPC_DIV_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  721. var
  722. shift,lzz,lzn : longint;
  723. begin
  724. result:=0;
  725. if n=0 then
  726. HandleErrorFrame(200,get_frame);
  727. lzz:=count_leading_zeros_32bit(z);
  728. lzn:=count_leading_zeros_32bit(n);
  729. { if the denominator contains less zeros
  730. then the numerator
  731. the d is greater than the n }
  732. if lzn<lzz then
  733. exit;
  734. shift:=lzn-lzz;
  735. n:=n shl shift;
  736. repeat
  737. if z>=n then
  738. begin
  739. z:=z-n;
  740. result:=result+dword(1 shl shift);
  741. end;
  742. dec(shift);
  743. n:=n shr 1;
  744. until shift<0;
  745. end;
  746. {$endif FPC_SYSTEM_HAS_DIV_DWORD}
  747. {$ifndef FPC_SYSTEM_HAS_MOD_DWORD}
  748. function fpc_mod_dword(n,z : dword) : dword; [public,alias: 'FPC_MOD_DWORD']; {$ifdef hascompilerproc} compilerproc; {$endif}
  749. var
  750. shift,lzz,lzn : longint;
  751. begin
  752. result:=0;
  753. if n=0 then
  754. HandleErrorFrame(200,get_frame);
  755. lzz:=count_leading_zeros_32bit(z);
  756. lzn:=count_leading_zeros_32bit(n);
  757. { if the denominator contains less zeros
  758. then the numerator
  759. the d is greater than the n }
  760. if lzn<lzz then
  761. begin
  762. result:=z;
  763. exit;
  764. end;
  765. shift:=lzn-lzz;
  766. n:=n shl shift;
  767. repeat
  768. if z>=n then
  769. z:=z-n;
  770. dec(shift);
  771. n:=n shr 1;
  772. until shift<0;
  773. result:=z;
  774. end;
  775. {$endif FPC_SYSTEM_HAS_MOD_DWORD}
  776. {$ifndef FPC_SYSTEM_HAS_DIV_LONGINT}
  777. function fpc_div_longint(n,z : longint) : longint; [public,alias: 'FPC_DIV_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  778. var
  779. sign : boolean;
  780. d1,d2 : dword;
  781. begin
  782. if n=0 then
  783. HandleErrorFrame(200,get_frame);
  784. sign:=false;
  785. if z<0 then
  786. begin
  787. sign:=not(sign);
  788. d1:=dword(-z);
  789. end
  790. else
  791. d1:=z;
  792. if n<0 then
  793. begin
  794. sign:=not(sign);
  795. d2:=dword(-n);
  796. end
  797. else
  798. d2:=n;
  799. { the div is coded by the compiler as call to divdword }
  800. if sign then
  801. result:=-(d1 div d2)
  802. else
  803. result:=d1 div d2;
  804. end;
  805. {$endif FPC_SYSTEM_HAS_DIV_LONGINT}
  806. {$ifndef FPC_SYSTEM_HAS_MOD_LONGINT}
  807. function fpc_mod_longint(n,z : longint) : longint; [public,alias: 'FPC_MOD_LONGINT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  808. var
  809. signed : boolean;
  810. r,nq,zq : dword;
  811. begin
  812. if n=0 then
  813. HandleErrorFrame(200,get_frame);
  814. nq:=abs(n);
  815. if z<0 then
  816. begin
  817. zq:=dword(-z);
  818. signed:=true;
  819. end
  820. else
  821. begin
  822. zq:=z;
  823. signed:=false;
  824. end;
  825. r:=zq mod nq;
  826. if signed then
  827. result:=-longint(r)
  828. else
  829. result:=r;
  830. end;
  831. {$endif FPC_SYSTEM_HAS_MOD_LONGINT}
  832. {$endif FPC_INCLUDE_SOFTWARE_MOD_DIV}
  833. {****************************************************************************}
  834. {$ifndef FPC_SYSTEM_HAS_ABS_LONGINT}
  835. function abs(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_abs];{$endif}
  836. begin
  837. if l<0 then
  838. abs:=-l
  839. else
  840. abs:=l;
  841. end;
  842. {$endif not FPC_SYSTEM_HAS_ABS_LONGINT}
  843. {$ifndef FPC_SYSTEM_HAS_ODD_LONGINT}
  844. function odd(l:longint):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_odd];{$endif}
  845. begin
  846. odd:=boolean(l and 1);
  847. end;
  848. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGINT}
  849. {$ifndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  850. function odd(l:longword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_odd];{$endif}
  851. begin
  852. odd:=boolean(l and 1);
  853. end;
  854. {$endif ndef FPC_SYSTEM_HAS_ODD_LONGWORD}
  855. {$ifndef FPC_SYSTEM_HAS_ODD_INT64}
  856. function odd(l:int64):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_odd];{$endif}
  857. begin
  858. odd:=boolean(longint(l) and 1);
  859. end;
  860. {$endif ndef FPC_SYSTEM_HAS_ODD_INT64}
  861. {$ifndef FPC_SYSTEM_HAS_ODD_QWORD}
  862. function odd(l:qword):boolean;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_odd];{$endif}
  863. begin
  864. odd:=boolean(longint(l) and 1);
  865. end;
  866. {$endif ndef FPC_SYSTEM_HAS_ODD_QWORD}
  867. {$ifndef FPC_SYSTEM_HAS_SQR_LONGINT}
  868. function sqr(l:longint):longint;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_sqr];{$endif}
  869. begin
  870. sqr:=l*l;
  871. end;
  872. {$endif ndef FPC_SYSTEM_HAS_SQR_LONGINT}
  873. {$ifndef FPC_SYSTEM_HAS_ABS_INT64}
  874. function abs(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_abs];{$endif}
  875. begin
  876. if l < 0 then
  877. abs := -l
  878. else
  879. abs := l;
  880. end;
  881. {$endif ndef FPC_SYSTEM_HAS_ABS_INT64}
  882. {$ifndef FPC_SYSTEM_HAS_SQR_INT64}
  883. function sqr(l: Int64): Int64;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_sqr];{$endif}
  884. begin
  885. sqr := l*l;
  886. end;
  887. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  888. {$ifndef FPC_SYSTEM_HAS_SQR_QWORD}
  889. function sqr(l: QWord): QWord;{$ifdef SYSTEMINLINE}inline;{$endif}{$ifndef INTERNCONSTINTF}[internconst:fpc_in_const_sqr];{$endif}
  890. begin
  891. sqr := l*l;
  892. end;
  893. {$endif ndef FPC_SYSTEM_HAS_SQR_INT64}
  894. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  895. function declocked(var l:longint):boolean;
  896. begin
  897. Dec(l);
  898. declocked:=(l=0);
  899. end;
  900. {$endif FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  901. {$ifndef FPC_SYSTEM_HAS_DECLOCKED_INT64}
  902. function declocked(var l:int64):boolean;
  903. begin
  904. Dec(l);
  905. declocked:=(l=0);
  906. end;
  907. {$endif FPC_SYSTEM_HAS_DECLOCKED_INT64}
  908. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  909. procedure inclocked(var l:longint);
  910. begin
  911. Inc(l);
  912. end;
  913. {$endif FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  914. {$ifndef FPC_SYSTEM_HAS_INCLOCKED_INT64}
  915. procedure inclocked(var l:int64);
  916. begin
  917. Inc(l);
  918. end;
  919. {$endif FPC_SYSTEM_HAS_INCLOCKED_INT64}
  920. {$ifndef FPC_SYSTEM_HAS_SPTR}
  921. {_$error Sptr must be defined for each processor }
  922. {$endif ndef FPC_SYSTEM_HAS_SPTR}
  923. {$ifndef INTERNCONSTINTF}
  924. procedure prefetch(const mem);[internproc:fpc_in_prefetch_var];
  925. {$endif}
  926. function align(addr : PtrInt;alignment : PtrInt) : PtrInt;{$ifdef SYSTEMINLINE}inline;{$endif}
  927. begin
  928. if addr mod alignment<>0 then
  929. result:=addr+(alignment-(addr mod alignment))
  930. else
  931. result:=addr;
  932. end;
  933. function align(addr : Pointer;alignment : PtrInt) : Pointer;{$ifdef SYSTEMINLINE}inline;{$endif}
  934. begin
  935. if PtrInt(addr) mod alignment<>0 then
  936. result:=pointer(addr+(alignment-(PtrInt(addr) mod alignment)))
  937. else
  938. result:=addr;
  939. end;
  940. {****************************************************************************
  941. Str()
  942. ****************************************************************************}
  943. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  944. procedure int_str(l : longint;var s : string);
  945. var
  946. value: longint;
  947. negative: boolean;
  948. begin
  949. negative := false;
  950. s:='';
  951. { Workaround: }
  952. if l=longint($80000000) then
  953. begin
  954. s:='-2147483648';
  955. exit;
  956. end;
  957. { handle case where l = 0 }
  958. if l = 0 then
  959. begin
  960. s:='0';
  961. exit;
  962. end;
  963. If l < 0 then
  964. begin
  965. negative := true;
  966. value:=abs(l);
  967. end
  968. else
  969. value:=l;
  970. { handle non-zero case }
  971. while value>0 do
  972. begin
  973. s:=char((value mod 10)+ord('0'))+s;
  974. value := value div 10;
  975. end;
  976. if negative then
  977. s := '-' + s;
  978. end;
  979. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
  980. {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  981. procedure int_str(l : longword;var s : string);
  982. begin
  983. s:='';
  984. if l = 0 then
  985. begin
  986. s := '0';
  987. exit;
  988. end;
  989. while l>0 do
  990. begin
  991. s:=char(ord('0')+(l mod 10))+s;
  992. l:=l div 10;
  993. end;
  994. end;
  995. {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
  996. {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
  997. procedure int_str(l : int64;var s : string);
  998. var
  999. value: int64;
  1000. negative: boolean;
  1001. begin
  1002. negative := false;
  1003. s:='';
  1004. { Workaround: }
  1005. {$ifdef ver1_0}
  1006. if (l shr 32=$80000000) and ((l and $ffffffff)=0) then
  1007. {$else}
  1008. if l=int64($8000000000000000) then
  1009. {$endif}
  1010. begin
  1011. s:='-9223372036854775808';
  1012. exit;
  1013. end;
  1014. { handle case where l = 0 }
  1015. if l = 0 then
  1016. begin
  1017. s:='0';
  1018. exit;
  1019. end;
  1020. If l < 0 then
  1021. begin
  1022. negative := true;
  1023. value:=abs(l);
  1024. end
  1025. else
  1026. value:=l;
  1027. { handle non-zero case }
  1028. while value>0 do
  1029. begin
  1030. s:=char((value mod 10)+ord('0'))+s;
  1031. value := value div 10;
  1032. end;
  1033. if negative then
  1034. s := '-' + s;
  1035. end;
  1036. {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
  1037. {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1038. procedure int_str(l : qword;var s : string);
  1039. begin
  1040. s:='';
  1041. if l = 0 then
  1042. begin
  1043. s := '0';
  1044. exit;
  1045. end;
  1046. while l>0 do
  1047. begin
  1048. s:=char(ord('0')+(l mod 10))+s;
  1049. l:=l div 10;
  1050. end;
  1051. end;
  1052. {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}
  1053. {$ifndef FPC_SYSTEM_HAS_SYSRESETFPU}
  1054. procedure SysResetFpu;{$ifdef SYSTEMINLINE}inline;{$endif}
  1055. begin
  1056. { nothing todo }
  1057. end;
  1058. {$endif FPC_SYSTEM_HAS_SYSRESETFPU}
  1059. {
  1060. $Log$
  1061. Revision 1.90 2005-02-14 17:13:22 peter
  1062. * truncate log
  1063. }