system.inc 17 KB

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