system.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. For details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. Local types
  13. ****************************************************************************}
  14. {
  15. TextRec and FileRec are put in a separate file to make it available to other
  16. units without putting it explicitly in systemh.
  17. This way we keep TP compatibility, and the TextRec definition is available
  18. for everyone who needs it.
  19. }
  20. {$i filerec.inc}
  21. {$i textrec.inc}
  22. Procedure HandleError (Errno : Longint); forward;
  23. type
  24. FileFunc = Procedure(var t : TextRec);
  25. const
  26. { Random / Randomize constants }
  27. OldRandSeed : Cardinal = 0;
  28. InitialSeed : Boolean = TRUE;
  29. Seed2 : Cardinal = 0;
  30. Seed3 : Cardinal = 0;
  31. { For Error Handling.}
  32. DoError : Boolean = FALSE;
  33. ErrorBase : Longint = 0;
  34. {****************************************************************************
  35. Routines which have compiler magic
  36. ****************************************************************************}
  37. {$I innr.inc}
  38. Function lo(i : Integer) : byte; [INTERNPROC: In_lo_Word];
  39. Function lo(w : Word) : byte; [INTERNPROC: In_lo_Word];
  40. Function lo(l : Longint) : Word; [INTERNPROC: In_lo_long];
  41. Function hi(i : Integer) : byte; [INTERNPROC: In_hi_Word];
  42. Function hi(w : Word) : byte; [INTERNPROC: In_hi_Word];
  43. Function hi(l : Longint) : Word; [INTERNPROC: In_hi_long];
  44. Function chr(b : byte) : Char; [INTERNPROC: In_chr_byte];
  45. Function Length(s : string) : byte; [INTERNPROC: In_Length_string];
  46. Function Length(c : char) : byte; [INTERNPROC: In_Length_string];
  47. Procedure Reset(var f : TypedFile); [INTERNPROC: In_Reset_TypedFile];
  48. Procedure Rewrite(var f : TypedFile); [INTERNPROC: In_Rewrite_TypedFile];
  49. {****************************************************************************
  50. Include processor specific routines
  51. ****************************************************************************}
  52. {$IFDEF I386}
  53. {$IFDEF M68K}
  54. {$Error Can't determine processor type !}
  55. {$ENDIF}
  56. {$I i386.inc} { Case dependent, don't change }
  57. {$ELSE}
  58. {$IFDEF M68K}
  59. {$I m68k.inc} { Case dependent, don't change }
  60. {$ELSE}
  61. {$Error Can't determine processor type !}
  62. {$ENDIF}
  63. {$ENDIF}
  64. {****************************************************************************
  65. Set Handling
  66. ****************************************************************************}
  67. { Include set support which is processor specific}
  68. {$I set.inc}
  69. {****************************************************************************
  70. Subroutines for String handling
  71. ****************************************************************************}
  72. { Needs to be before RTTI handling }
  73. {$i sstrings.inc}
  74. Type
  75. PLongint = ^Longint;
  76. PByte = ^Byte;
  77. {$i astrings.inc}
  78. {****************************************************************************
  79. Run-Time Type Information (RTTI)
  80. ****************************************************************************}
  81. {$i rtti.inc}
  82. {****************************************************************************
  83. Math Routines
  84. ****************************************************************************}
  85. {$ifndef RTLLITE}
  86. function Hi(b : byte): byte;
  87. begin
  88. Hi := b shr 4
  89. end;
  90. function Lo(b : byte): byte;
  91. begin
  92. Lo := b and $0f
  93. end;
  94. Function swap (X : Word) : Word;[internconst:in_const_swap_word];
  95. Begin
  96. swap:=(X and $ff) shl 8 + (X shr 8)
  97. End;
  98. Function Swap (X : Integer) : Integer;[internconst:in_const_swap_word];
  99. Begin
  100. Swap:=Integer(Swap(Word(X)));
  101. End;
  102. Function swap (X : Longint) : Longint;[internconst:in_const_swap_long];
  103. Begin
  104. Swap:=(X and $ffff) shl 16 + (X shr 16)
  105. End;
  106. Function Swap (X : Cardinal) : Cardinal;[internconst:in_const_swap_long];
  107. Begin
  108. Swap:=Swap(Longint(X));
  109. End;
  110. {$endif RTLLITE}
  111. {****************************************************************************
  112. Random function routines
  113. This implements a very long cycle random number generator by combining
  114. three independant generators. The technique was described in the March
  115. 1987 issue of Byte.
  116. Taken and modified with permission from the PCQ Pascal rtl code.
  117. ****************************************************************************}
  118. {$R-}
  119. {$Q-}
  120. Procedure UseSeed(seed : Longint);Forward;
  121. Function Random : Real;
  122. var
  123. ReturnValue : Real;
  124. begin
  125. if (InitialSeed) OR ((RandSeed <> OldRandSeed) AND (NOT InitialSeed)) then
  126. Begin
  127. { This is a pretty complicated affair }
  128. { Initially we must call UseSeed when RandSeed is initalized }
  129. { We must also call UseSeed each time RandSeed is reinitialized }
  130. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  131. { UNLESS YOU WANT RANDON TO CRASH OF COURSE (CEC) }
  132. InitialSeed:=FALSE;
  133. OldRandSeed:=RandSeed;
  134. UseSeed(RandSeed);
  135. end;
  136. Inc(RandSeed);
  137. RandSeed := (RandSeed * 706) mod 500009;
  138. OldRandSeed:=RandSeed;
  139. INC(Seed2);
  140. Seed2 := (Seed2 * 774) MOD 600011;
  141. INC(Seed3);
  142. Seed3 := (Seed3 * 871) MOD 765241;
  143. ReturnValue := RandSeed/500009.0 +
  144. Seed2/600011.0 +
  145. Seed3/765241.0;
  146. Random := frac(ReturnValue);
  147. end;
  148. Function Random(l : Longint) : Longint;
  149. begin
  150. if (InitialSeed) OR ((RandSeed <> OldRandSeed) AND (NOT InitialSeed)) then
  151. Begin
  152. { This is a pretty complicated affair }
  153. { Initially we must call UseSeed when RandSeed is initalized }
  154. { We must also call UseSeed each time RandSeed is reinitialized }
  155. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  156. { UNLESS YOU WANT RANDON TO CRASH OF COURSE (CEC) }
  157. InitialSeed:=FALSE;
  158. OldRandSeed:=RandSeed;
  159. UseSeed(Randseed);
  160. end;
  161. Inc(RandSeed);
  162. RandSeed := (RandSeed * 998) mod 1000003;
  163. OldRandSeed:=RandSeed;
  164. Random := RandSeed mod l;
  165. end;
  166. Procedure UseSeed(seed : Longint);
  167. begin
  168. randseed := seed mod 1000003;
  169. Seed2 := (Random(65000) * Random(65000)) mod 600011;
  170. Seed3 := (Random(65000) * Random(65000)) mod 765241;
  171. end;
  172. { Include processor specific routines }
  173. {$I math.inc}
  174. {****************************************************************************
  175. Memory Management
  176. ****************************************************************************}
  177. {$ifndef RTLLITE}
  178. Function Ptr(sel,off : Longint) : pointer;[internconst:in_const_ptr];
  179. Begin
  180. sel:=0;
  181. ptr:=pointer(off);
  182. End;
  183. Function Addr (Var X) : Pointer;
  184. Begin
  185. Addr:=@(X);
  186. End;
  187. Function CSeg : Word;
  188. Begin
  189. Cseg:=0;
  190. End;
  191. Function DSeg : Word;
  192. Begin
  193. Dseg:=0;
  194. End;
  195. Function SSeg : Word;
  196. Begin
  197. Sseg:=0;
  198. End;
  199. {$endif RTLLITE}
  200. {*****************************************************************************
  201. Directory support.
  202. *****************************************************************************}
  203. Procedure getdir(drivenr:byte;Var dir:ansistring);
  204. { this is needed to also allow ansistrings, the shortstring version is
  205. OS dependent }
  206. var
  207. s : shortstring;
  208. begin
  209. getdir(drivenr,s);
  210. dir:=s;
  211. end;
  212. {*****************************************************************************
  213. Miscellaneous
  214. *****************************************************************************}
  215. procedure int_overflow;[public,alias: {$ifdef FPCNAMES}'FPC_OVERFLOW'{$else}'RE_OVERFLOW'{$endif}];
  216. var
  217. addr : longint;
  218. begin
  219. addr:=get_caller_addr(get_frame);
  220. If ErrorProc<>Nil then
  221. TErrorProc (ErrorProc)(215,Pointer(Addr));
  222. {$ifndef RTLLITE}
  223. Writeln('Overflow at 0x',HexStr(addr,8));
  224. {$endif}
  225. HandleError(215);
  226. end;
  227. Function IOResult:Word;
  228. Begin
  229. IOResult:=InOutRes;
  230. InOutRes:=0;
  231. End;
  232. procedure fillchar(var x;count : longint;value : char);
  233. begin
  234. fillchar(x,count,byte(value));
  235. end;
  236. {*****************************************************************************
  237. Init / Exit / ExitProc
  238. *****************************************************************************}
  239. Procedure HandleError (Errno : longint;frame : longint);
  240. {
  241. Procedure to handle internal errors, i.e. not user-invoked errors
  242. Internal function should ALWAYS call HandleError instead of RunError.
  243. Can be used for exception handlers to specify the frame
  244. }
  245. var
  246. addr : longint;
  247. begin
  248. addr:=get_caller_addr(frame);
  249. If ErrorProc<>Nil then
  250. TErrorProc (ErrorProc)(Errno,pointer(addr));
  251. errorcode:=Errno;
  252. exitcode:=Errno;
  253. erroraddr:=pointer(addr);
  254. errorbase:=get_caller_frame(frame);
  255. DoError:=true;
  256. halt(errorcode);
  257. end;
  258. Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
  259. {
  260. Procedure to handle internal errors, i.e. not user-invoked errors
  261. Internal function should ALWAYS call HandleError instead of RunError.
  262. }
  263. var
  264. addr : longint;
  265. begin
  266. HandleError(Errno,get_frame);
  267. end;
  268. procedure runerror(w : word);[alias: 'FPC_RUNERROR'];
  269. begin
  270. errorcode:=w;
  271. exitcode:=w;
  272. erroraddr:=pointer(get_caller_addr(get_frame));
  273. errorbase:=get_caller_frame(get_frame);
  274. DoError:=true;
  275. halt(errorcode);
  276. end;
  277. Procedure RunError;
  278. Begin
  279. RunError (0);
  280. End;
  281. Procedure Halt;
  282. Begin
  283. Halt(0);
  284. End;
  285. Procedure dump_stack(bp : Longint);
  286. var
  287. i, prevbp : Longint;
  288. Begin
  289. prevbp:=bp-1;
  290. i:=0;
  291. while bp > prevbp Do
  292. Begin
  293. Writeln(stderr,' 0x',HexStr(get_caller_addr(bp),8));
  294. Inc(i);
  295. If i>max_frame_dump Then
  296. exit;
  297. prevbp:=bp;
  298. bp:=get_caller_frame(bp);
  299. End;
  300. End;
  301. Procedure do_exit;[Public,Alias: {$ifdef FPCNAMES}'FPC_DO_EXIT'{$else}'__EXIT'{$endif}];
  302. {
  303. Don't call this direct, the call is generated by the compiler
  304. and by the halt procedure.
  305. NOTICE: (CEC - 14/Aug/1998)
  306. The order of calling this routine must not be changed, especially
  307. regarding doerror, doerror should only be set by handlerror
  308. and runerror and nowhere else, as certain system units require
  309. exit procedures to clean up, and they rely on this behavior as not
  310. to call themselves recursively.
  311. }
  312. var
  313. current_exit : Procedure;
  314. Begin
  315. while exitProc<>nil Do
  316. Begin
  317. InOutRes:=0;
  318. current_exit:=tProcedure(exitProc);
  319. exitProc:=nil;
  320. current_exit();
  321. End;
  322. If DoError Then
  323. Begin
  324. Writeln('Run time error ',Errorcode,' at 0x',hexstr(Longint(Erroraddr),8));
  325. dump_stack(ErrorBase);
  326. End;
  327. End;
  328. Type
  329. PExitProcInfo = ^TExitProcInfo;
  330. TExitProcInfo = Record
  331. Next : PExitProcInfo;
  332. SaveExit : Pointer;
  333. Proc : TProcedure;
  334. End;
  335. const
  336. ExitProcList: PExitProcInfo = nil;
  337. Procedure DoExitProc;
  338. var
  339. P : PExitProcInfo;
  340. Proc : TProcedure;
  341. Begin
  342. P:=ExitProcList;
  343. ExitProcList:=P^.Next;
  344. ExitProc:=P^.SaveExit;
  345. Proc:=P^.Proc;
  346. DisPose(P);
  347. Proc();
  348. End;
  349. Procedure AddExitProc(Proc: TProcedure);
  350. var
  351. P : PExitProcInfo;
  352. Begin
  353. New(P);
  354. P^.Next:=ExitProcList;
  355. P^.SaveExit:=ExitProc;
  356. P^.Proc:=Proc;
  357. ExitProcList:=P;
  358. ExitProc:=@DoExitProc;
  359. End;
  360. {*****************************************************************************
  361. Abstract/Assert support.
  362. *****************************************************************************}
  363. procedure AbstractError;[public,alias : 'FPC_ABSTRACTERROR'];
  364. Type
  365. TAbstractErrorProc=Procedure;
  366. begin
  367. If AbstractErrorProc<>nil then
  368. TAbstractErrorProc(AbstractErrorProc);
  369. RunError(211);
  370. end;
  371. Procedure int_assert(Const Msg,FName:string;LineNo,ErrorAddr:Longint); [Public,Alias : 'FPC_ASSERT'];
  372. type
  373. TAssertErrorProc=procedure(const msg,fname:string;lineno,erroraddr:longint);
  374. begin
  375. if AssertErrorProc<>nil then
  376. TAssertErrorProc(AssertErrorProc)(Msg,FName,LineNo,ErrorAddr)
  377. else
  378. HandleError(227);
  379. end;
  380. Procedure SysAssert(Const Msg,FName:string;LineNo,ErrorAddr:Longint);
  381. begin
  382. If msg='' then
  383. write(stderr,'Assertion failed')
  384. else
  385. write(stderr,msg);
  386. writeln(stderr,' (',FName,', line ',LineNo,').');
  387. end;
  388. {*****************************************************************************
  389. SetJmp/LongJmp support.
  390. *****************************************************************************}
  391. {$i setjump.inc}
  392. {
  393. $Log$
  394. Revision 1.45 1998-12-01 14:00:10 pierre
  395. + added conversion from exceptions into run time error
  396. (only if syswin32 compiled with -ddebug for now !)
  397. * added HandleError(errno,frame)
  398. where you specify the frame
  399. needed for win32 exception handling
  400. Revision 1.44 1998/11/26 23:16:15 jonas
  401. * changed RandSeed and OldRandSeed to Cardinal to avoid negative random numbers
  402. Revision 1.43 1998/11/17 10:36:07 michael
  403. + renamed astrings.pp to astrings.inc
  404. Revision 1.42 1998/11/16 10:21:25 peter
  405. * fixes for H+
  406. Revision 1.41 1998/11/05 10:29:36 pierre
  407. * fix for length(char) in const expressions
  408. Revision 1.40 1998/11/04 20:34:02 michael
  409. + Removed ifdef useansistrings
  410. Revision 1.39 1998/10/12 22:11:28 jonas
  411. * fixed RandSeed bug
  412. Revision 1.38 1998/10/12 12:43:37 florian
  413. * made FPC_HANDLEERROR public
  414. Revision 1.37 1998/10/07 11:40:08 jonas
  415. * changed seed2 and seed3 to cardinal to prevent overflow
  416. Revision 1.36 1998/10/05 12:32:51 peter
  417. + assert() support
  418. Revision 1.35 1998/10/02 09:25:11 peter
  419. * more constant expression evals
  420. Revision 1.34 1998/09/22 15:30:54 peter
  421. * shortstring=string type added
  422. Revision 1.33 1998/09/16 13:08:03 michael
  423. Added AbstractErrorHandler
  424. Revision 1.32 1998/09/16 12:37:07 michael
  425. Added FPC_ prefix to abstracterror
  426. Revision 1.31 1998/09/15 17:12:32 michael
  427. + Merged changes from fixes branch
  428. Revision 1.30 1998/09/14 10:48:20 peter
  429. * FPC_ names
  430. * Heap manager is now system independent
  431. Revision 1.29.2.1 1998/09/15 17:08:43 michael
  432. + Added abstracterror call
  433. Revision 1.29 1998/09/01 17:36:21 peter
  434. + internconst
  435. Revision 1.28 1998/08/17 12:24:16 carl
  436. + important comment added
  437. Revision 1.27 1998/08/13 16:22:11 jonas
  438. * random now returns a value between 0 and max-1 instead of between 0 and max
  439. Revision 1.26 1998/08/11 00:05:26 peter
  440. * $ifdef ver0_99_5 updates
  441. Revision 1.25 1998/07/30 13:26:18 michael
  442. + Added support for ErrorProc variable. All internal functions are required
  443. to call HandleError instead of runerror from now on.
  444. This is necessary for exception support.
  445. Revision 1.24 1998/07/28 20:37:45 michael
  446. + added setjmp/longjmp and exception support
  447. Revision 1.23 1998/07/23 19:53:20 michael
  448. + Adapted assert to Delphi format
  449. Revision 1.22 1998/07/23 13:08:41 michael
  450. + Implemented DO_ASSERT function.
  451. Revision 1.21 1998/07/15 12:09:35 carl
  452. * would not compile under FPC v0.99.5
  453. Revision 1.20 1998/07/13 21:19:12 florian
  454. * some problems with ansi string support fixed
  455. Revision 1.19 1998/07/08 11:56:55 carl
  456. * randon and Random(l) now work correctly - don't touch it works!
  457. Revision 1.18 1998/07/02 13:01:55 carl
  458. * hmmm... it is luck (BSS zeroed with GAS) that DoError and ErrorBase work.
  459. Now they are initilized instead.
  460. Revision 1.17 1998/07/02 12:53:09 carl
  461. * DOERROR RESOTRED! DON'T TOUCH :)
  462. Revision 1.16 1998/07/02 12:11:50 carl
  463. * no SINGLE in m68k and other processors!
  464. Revision 1.15 1998/07/02 09:25:05 peter
  465. * fixed do_error in runtimeerror
  466. Revision 1.14 1998/07/01 15:29:59 peter
  467. * better readln/writeln
  468. Revision 1.13 1998/06/26 08:21:09 daniel
  469. - Doerror removed.
  470. Revision 1.12 1998/06/25 14:04:25 peter
  471. + internal inc/dec
  472. Revision 1.11 1998/06/25 09:44:20 daniel
  473. + RTLLITE directive to compile minimal RTL.
  474. Revision 1.10 1998/06/15 15:16:26 daniel
  475. * RTLLITE conditional added to produce smaller RTL
  476. Revision 1.9 1998/06/10 07:46:45 michael
  477. + Forgot to commit some changes
  478. Revision 1.8 1998/06/08 12:38:24 michael
  479. Implemented rtti, inserted ansistrings again
  480. Revision 1.7 1998/06/04 23:46:01 peter
  481. * comp,extended are only i386 added support_comp,support_extended
  482. Revision 1.6 1998/05/20 11:23:09 cvs
  483. * test commit. Shouldn't be allowed.
  484. Revision 1.5 1998/05/12 10:42:45 peter
  485. * moved getopts to inc/, all supported OS's need argc,argv exported
  486. + strpas, strlen are now exported in the systemunit
  487. * removed logs
  488. * removed $ifdef ver_above
  489. Revision 1.4 1998/04/16 12:30:47 peter
  490. + inc(pchar), dec(pchar), incc(pchar,a),dec(pchar,a)
  491. Revision 1.3 1998/04/08 07:53:32 michael
  492. + Changed Random() function. Moved from system to processor dependent files (from Pedro Gimeno)
  493. }