sysutils.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  15. { force ansistrings }
  16. {$H+}
  17. uses
  18. {$ifdef linux}
  19. linux
  20. {$endif}
  21. {$ifdef win32}
  22. dos,windows
  23. {$endif}
  24. {$ifdef go32v1}
  25. go32,dos
  26. {$endif}
  27. {$ifdef go32v2}
  28. go32,dos
  29. {$endif}
  30. {$ifdef os2}
  31. doscalls,dos
  32. {$endif}
  33. ;
  34. type
  35. { some helpful data types }
  36. tprocedure = procedure;
  37. tfilename = string;
  38. tsyscharset = set of char;
  39. longrec = packed record
  40. lo,hi : word;
  41. end;
  42. wordrec = packed record
  43. lo,hi : byte;
  44. end;
  45. TMethod = packed record
  46. Code, Data: Pointer;
  47. end;
  48. { exceptions }
  49. exception = class(TObject)
  50. private
  51. fmessage : string;
  52. fhelpcontext : longint;
  53. public
  54. constructor create(const msg : string);
  55. constructor createfmt(const msg : string; const args : array of const);
  56. constructor createres(ident : longint);
  57. { !!!! }
  58. property helpcontext : longint read fhelpcontext write fhelpcontext;
  59. property message : string read fmessage write fmessage;
  60. end;
  61. exceptclass = class of exception;
  62. { integer math exceptions }
  63. EInterror = Class(Exception);
  64. EDivByZero = Class(EIntError);
  65. ERangeError = Class(EIntError);
  66. EIntOverflow = Class(EIntError);
  67. { General math errors }
  68. EMathError = Class(Exception);
  69. EInvalidOp = Class(EMathError);
  70. EZeroDivide = Class(EMathError);
  71. EOverflow = Class(EMathError);
  72. EUnderflow = Class(EMathError);
  73. { Run-time and I/O Errors }
  74. EInOutError = class(Exception)
  75. public
  76. ErrorCode : Longint;
  77. end;
  78. EInvalidPointer = Class(Exception);
  79. EOutOfMemory = Class(Exception);
  80. EAccessViolation = Class(Exception);
  81. EInvalidCast = Class(Exception);
  82. { String conversion errors }
  83. EConvertError = class(Exception);
  84. { Other errors }
  85. EAbort = Class(Exception);
  86. EAbstractError = Class(Exception);
  87. EAssertionFailed = Class(Exception);
  88. { Exception handling routines }
  89. function ExceptObject: TObject;
  90. function ExceptAddr: Pointer;
  91. function ExceptionErrorMessage(ExceptObject: TObject; ExceptAddr: Pointer;
  92. Buffer: PChar; Size: Integer): Integer;
  93. procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);
  94. procedure Abort;
  95. procedure OutOfMemoryError;
  96. procedure Beep;
  97. Var
  98. OnShowException : Procedure (Msg : ShortString);
  99. { FileRec/TextRec }
  100. {$i filerec.inc}
  101. {$i textrec.inc}
  102. { Read internationalization settings }
  103. {$i sysinth.inc}
  104. { Read date & Time function declarations }
  105. {$i datih.inc}
  106. { Read String Handling functions declaration }
  107. {$i sysstrh.inc}
  108. { Read pchar handling functions declration }
  109. {$i syspchh.inc}
  110. { Read filename handling functions declaration }
  111. {$i finah.inc}
  112. { Read other file handling function declarations }
  113. {$i filutilh.inc}
  114. { Read disk function declarations }
  115. {$i diskh.inc}
  116. implementation
  117. { Read message string definitions }
  118. {
  119. Add a language with IFDEF LANG_NAME
  120. just befor the final ELSE. This way English will always be the default.
  121. }
  122. {$IFDEF LANG_GERMAN}
  123. {$i strg.inc} // Does not exist yet !!
  124. {$ELSE}
  125. {$i stre.inc}
  126. {$ENDIF}
  127. { Read filename handling functions implementation }
  128. {$i fina.inc}
  129. { Read String Handling functions implementation }
  130. {$i sysstr.inc}
  131. { Read other file handling function implementations }
  132. {$i filutil.inc}
  133. { Read disk function implementations }
  134. {$i disk.inc}
  135. { Read date & Time function implementations }
  136. {$i dati.inc}
  137. { Read pchar handling functions implementation }
  138. {$i syspch.inc}
  139. constructor exception.create(const msg : string);
  140. begin
  141. inherited create;
  142. fmessage:=msg;
  143. end;
  144. constructor exception.createfmt(const msg : string; const args : array of const);
  145. begin
  146. inherited create;
  147. fmessage:=Format(msg,args);
  148. end;
  149. constructor exception.createres(ident : longint);
  150. begin
  151. inherited create;
  152. {!!!!!}
  153. end;
  154. {$ifopt S+}
  155. {$define STACKCHECK_WAS_ON}
  156. {$S-}
  157. {$endif OPT S }
  158. Procedure CatchUnhandledException (Obj : TObject; Addr,Frame: Pointer);
  159. Var
  160. Message : String;
  161. begin
  162. Writeln(stdout,'An unhandled exception occurred at 0x',HexStr(Longint(Addr),8),' :');
  163. if Obj is exception then
  164. begin
  165. Message:=Exception(Obj).Message;
  166. Writeln(stdout,Message);
  167. end
  168. else
  169. Writeln(stdout,'Exception object ',Obj.ClassName,' is not of class Exception.');
  170. { to get a nice symify }
  171. Writeln(stdout,BackTraceStrFunc(Longint(Addr)));
  172. Dump_Stack(stdout,longint(frame));
  173. Writeln(stdout,'');
  174. Halt(217);
  175. end;
  176. Var OutOfMemory : EOutOfMemory;
  177. InValidPointer : EInvalidPointer;
  178. Procedure RunErrorToExcept (ErrNo : Longint; Address,Frame : Pointer);
  179. Var E : Exception;
  180. S : String;
  181. begin
  182. Case Errno of
  183. 1,203 : E:=OutOfMemory;
  184. 204 : E:=InvalidPointer;
  185. 2,3,4,5,6,100,101,102,103,105,106 : { I/O errors }
  186. begin
  187. Case Errno of
  188. 2 : S:=SFileNotFound;
  189. 3 : S:=SInvalidFileName;
  190. 4 : S:=STooManyOpenFiles;
  191. 5 : S:=SAccessDenied;
  192. 6 : S:=SInvalidFileHandle;
  193. 15 : S:=SInvalidDrive;
  194. 100 : S:=SEndOfFile;
  195. 101 : S:=SDiskFull;
  196. 102 : S:=SFileNotAssigned;
  197. 103 : S:=SFileNotOpen;
  198. 104 : S:=SFileNotOpenForInput;
  199. 105 : S:=SFileNotOpenForOutput;
  200. 106 : S:=SInvalidInput;
  201. end;
  202. E:=EinOutError.Create (S);
  203. EInoutError(E).ErrorCode:=IOresult; // Clears InOutRes !!
  204. end;
  205. // We don't set abstracterrorhandler, but we do it here.
  206. // Unless the use sets another handler we'll get here anyway...
  207. 200 : E:=EDivByZero.Create(SDivByZero);
  208. 201 : E:=ERangeError.Create(SRangeError);
  209. 205 : E:=EOverflow.Create(SOverflow);
  210. 206 : E:=EOverflow.Create(SUnderflow);
  211. 207 : E:=EInvalidOp.Create(SInvalidOp);
  212. 211 : E:=EAbstractError.Create(SAbstractError);
  213. 215 : E:=EIntOverflow.Create(SIntOverflow);
  214. 216 : E:=EAccessViolation.Create(SAccessViolation);
  215. 219 : E:=EInvalidCast.Create(SInvalidCast);
  216. 227 : E:=EAssertionFailed.Create(SAssertionFailed);
  217. else
  218. E:=Exception.CreateFmt (SUnKnownRunTimeError,[Errno]);
  219. end;
  220. Raise E at longint(Address){$ifdef ENHANCEDRAISE},longint(Frame){$endif};
  221. end;
  222. Procedure AssertErrorHandler (Const Msg,FN : ShortString;LineNo,TheAddr : Longint);
  223. Var
  224. S : String;
  225. begin
  226. If Msg='' then
  227. S:=SAssertionFailed
  228. else
  229. S:=Msg;
  230. Raise EAssertionFailed.Createfmt(SAssertError,[S,Fn,LineNo]); // at Pointer(theAddr);
  231. end;
  232. {$ifdef STACKCHECK_WAS_ON}
  233. {$S+}
  234. {$endif}
  235. Procedure InitExceptions;
  236. {
  237. Must install uncaught exception handler (ExceptProc)
  238. and install exceptions for system exceptions or signals.
  239. (e.g: SIGSEGV -> ESegFault or so.)
  240. }
  241. begin
  242. ExceptProc:=@CatchUnhandledException;
  243. // Create objects that may have problems when there is no memory.
  244. OutOfMemory:=EOutOfMemory.Create(SOutOfMemory);
  245. InvalidPointer:=EInvalidPointer.Create(SInvalidPointer);
  246. AssertErrorProc:=@AssertErrorHandler;
  247. ErrorProc:=@RunErrorToExcept;
  248. OnShowException:=Nil;
  249. end;
  250. { Exception handling routines }
  251. function ExceptObject: TObject;
  252. begin
  253. If RaiseList=Nil then
  254. Result:=Nil
  255. else
  256. Result:=RaiseList^.FObject;
  257. end;
  258. function ExceptAddr: Pointer;
  259. begin
  260. If RaiseList=Nil then
  261. Result:=Nil
  262. else
  263. Result:=RaiseList^.Addr;
  264. end;
  265. function ExceptionErrorMessage(ExceptObject: TObject; ExceptAddr: Pointer;
  266. Buffer: PChar; Size: Integer): Integer;
  267. Var
  268. S : AnsiString;
  269. Len : Integer;
  270. begin
  271. S:=Format(SExceptionErrorMessage,[ExceptObject.ClassName,ExceptAddr]);
  272. If ExceptObject is Exception then
  273. S:=Format('%s:'#10'%s',[S,Exception(ExceptObject).Message]);
  274. Len:=Length(S);
  275. If S[Len]<>'.' then
  276. begin
  277. S:=S+'.';
  278. Inc(len);
  279. end;
  280. If Len>Size then
  281. Len:=Size;
  282. Move(S[1],Buffer^,Len);
  283. Result:=Len;
  284. end;
  285. procedure ShowException(ExceptObject: TObject; ExceptAddr: Pointer);
  286. // use shortstring. On exception, the heap may be corrupt.
  287. Var
  288. Buf : ShortString;
  289. begin
  290. SetLength(Buf,ExceptionErrorMessage(ExceptObject,ExceptAddr,@Buf[1],255));
  291. If IsConsole Then
  292. writeln(Buf)
  293. else
  294. If Assigned(OnShowException) Then
  295. OnShowException (Buf);
  296. end;
  297. procedure Abort;
  298. begin
  299. Raise EAbort.Create(SAbortError) at Get_Caller_addr(Get_Frame)
  300. end;
  301. procedure OutOfMemoryError;
  302. begin
  303. Raise OutOfMemory;
  304. end;
  305. procedure Beep;
  306. begin
  307. {$ifdef win32}
  308. MessageBeep(0);
  309. {$else}
  310. {$endif}
  311. end;
  312. { Initialization code. }
  313. Initialization
  314. InitExceptions; { Initialize exceptions. OS independent }
  315. InitInternational; { Initialize internationalization settings }
  316. Finalization
  317. OutOfMemory.Free;
  318. InValidPointer.Free;
  319. end.
  320. {
  321. $Log$
  322. Revision 1.47 2000-06-22 18:05:18 michael
  323. + Added ExceptObject, ExceptAddr,ExceptionErrorMessage
  324. ShowException Abort; OutOfMemoryError; Beep;
  325. Revision 1.46 2000/06/11 07:07:23 peter
  326. + TSysCharSet
  327. Revision 1.45 2000/04/24 13:34:29 peter
  328. * added enhancedraise define
  329. Revision 1.43 2000/03/30 13:54:15 pierre
  330. No stack check inside CatchUnhandledException
  331. Revision 1.42 2000/02/10 22:56:43 florian
  332. * quick hack for stack trace in the case of an unhandled exception
  333. Revision 1.41 2000/02/09 16:59:33 peter
  334. * truncated log
  335. Revision 1.40 2000/01/16 19:10:25 hajny
  336. * 'uses Dos' added for OS/2 target
  337. Revision 1.39 2000/01/07 16:41:44 daniel
  338. * copyright 2000
  339. Revision 1.38 1999/12/26 19:30:53 hajny
  340. * OS/2 target added to the uses clause
  341. Revision 1.36 1999/11/15 21:49:47 peter
  342. * exception address fixes
  343. Revision 1.35 1999/11/06 14:41:31 peter
  344. * truncated log
  345. Revision 1.34 1999/10/30 17:39:05 peter
  346. * memorymanager expanded with allocmem/reallocmem
  347. Revision 1.33 1999/10/26 12:29:07 peter
  348. * assert handler must use shortstring
  349. Revision 1.32 1999/09/15 20:26:30 florian
  350. * patch from Sebastian Guenther applied: TMethod implementation
  351. Revision 1.31 1999/08/28 14:53:27 florian
  352. * bug 471 fixed: run time error 2 is now converted into a file not
  353. found exception
  354. Revision 1.30 1999/08/18 11:28:24 michael
  355. * Fixed reallocmem bug 535
  356. Revision 1.29 1999/07/27 13:01:12 peter
  357. + filerec,textrec declarations
  358. }