system.inc 18 KB

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