home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / d / desklib / !DeskLib / h_doc / Error < prev    next >
Encoding:
Text File  |  1996-05-21  |  8.8 KB  |  291 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Error.h
  12.     Author:  Copyright © 1992 Jason Williams
  13.              Philip Colmer: Varargs improvements.
  14.              Julian Smith:  Desk_error_PLACE
  15.              Sergio Monesi: Desk_error_FIXED, Desk_error_global (with some ideas and code from
  16.                             Martin Ebourne)
  17.     Version: 1.60 (06 Jun 1995)
  18.     Purpose: Centralised error reporting, with hopefully useful routines,
  19.              but which YOU (the user) can change if you want something
  20.              different.
  21.              Also, a few useful error-releated macros.
  22.     Mods:    7 Apr 1992 - JCW - Added Desk_Error_OutOfMemory
  23.             14 Jun 1993 - PJC - Allowed Desk_Error_Report(Fatal) to take
  24.                                 variable arguments
  25.             13 Jul 1993 - PJC - Added varargs to "Internal" versions of above
  26.             06 Jun 1995 - JPS - Added Desk_error_PLACE
  27.             06 Jun 1995 - SM  - Added Desk_error_global and Desk_error_FIXED,
  28.             06 Jun 1995 - JPS - made Desk_error_global DLL-friendly.
  29.             08 Jul 1995 - JPS - Removed #include of kernel.h
  30.             21 Jul 1995 - SM  - Added Desk_error_STATIC
  31. */
  32.  
  33. #ifndef __Desk_Error_h
  34. #define __Desk_Error_h
  35.  
  36. #ifdef __cplusplus
  37.     extern "C" {
  38. #endif
  39.  
  40.  
  41. #ifndef __Desk_Core_h
  42.     #include "Desk.Core.h"
  43. #endif
  44.  
  45.  
  46.  
  47. extern void Desk_Error_ReportInternal(int errornum, const char *report, ...);
  48. /*
  49. This is identical to Desk_Error_Report, except it is used for most DeskLib
  50. library internal errors. User code should use Desk_Error_Report. This allows
  51. you to modify the treatment of internal errors, without affecting your
  52. own error handling.
  53. */
  54.  
  55.  
  56. extern void Desk_Error_ReportFatalInternal(int errornum, const char *report, ...);
  57. /*
  58. This does an Desk_Error_ReportInternal, and then calls exit()
  59. */
  60.  
  61.  
  62. extern void Desk_Error_Report(int errornum, const char *report, ...);
  63. /*
  64. This is a centralised user-error reporting function. Call it, citing any
  65. error number you want, and any error string you want. The current
  66. implementation merely invokes Desk_Wimp_ReportError, but use it from your
  67. code, as then the method by which you report errors can be altered just
  68. by changing Error.c
  69.  
  70. The report is a 'printf' style formatting string, optionally followed by
  71. arguments just as in printf commands. This saves you from having to
  72. pre-assemble strings to pass in.
  73.  
  74. examples:
  75.  
  76. Desk_Error_Report(5, "My VIDC just blew up!");
  77.  
  78. Desk_Error_Report(6, "You can't put the number %d in there!", thenumber);
  79. */
  80.  
  81.  
  82.  
  83. extern void Desk_Error_ReportFatal(int errornum, const char *report, ...);
  84. /*
  85. Exactly the same as Desk_Error_Report, except after reporting the error, it
  86. terminates the program by calling exit()
  87.  
  88. Takes variable arguments a la 'printf'. See Desk_Error_Report for more info.
  89. */
  90.  
  91.  
  92. extern Desk_bool Desk_Error_Check( const Desk_os_error *error);
  93. /*
  94. Used to encapsulate an OS call to automatically check for error return.
  95. If the OS call returns an error, then it will be reported, and the
  96. function returns Desk_bool_TRUE. Otherwise, no action is taken, and Desk_bool_FALSE is
  97. returned
  98. */
  99.  
  100.  
  101. /* Desk_Error_CheckFatal --------------------------------------------------------
  102.  * Identical to Desk_Error_Check, but calls exit() if an error ocurred
  103.  */
  104. extern void Desk_Error_CheckFatal( const Desk_os_error *error);
  105.  
  106.  
  107. extern Desk_bool Desk_Error_OutOfMemory(Desk_bool fatal, const char *place);
  108. /*
  109. Reports a memory error (e.g. "Unable to claim enough memory for
  110. [Messages]"), where you supply just the "place" of the failure
  111. (e.g. in this case, in the "Messages" section)
  112. if "fatal" is Desk_bool_TRUE, Desk_Error_ReportFatal is used, else Desk_Error_Report is used.
  113.  
  114. This function ALWAYS returns Desk_bool_FALSE (== 0 == NULL), so you can use:
  115.  
  116. if (spritearea == NULL) return( Desk_Error_OutOfMemory( Desk_bool_FALSE, "icon sprites"));
  117. */
  118.  
  119.  
  120.  
  121.  
  122. #define Desk_error__SR(x)    Desk_error__VL(x)
  123. #define Desk_error__VL(x)    #x
  124.  
  125.  
  126. #define Desk_error_PLACE    "File '" __FILE__ "', line " Desk_error__SR( __LINE__) ". "
  127. /*
  128. Desk_error_PLACE turns into something like: "File 'c.main', line 67. "
  129.  
  130. Thus you can use:
  131.  
  132. if (x<0) Desk_Error_Report( 0, Desk_error_PLACE "x negative (x=%g)", x);
  133. (Note that there is no comma after Desk_error_PLACE.)
  134.  
  135. - and automatically get the filename and linenumber where the error
  136. occurred: e.g. "File 'c.main', line 67. x negative (x=-3.5)"
  137.  
  138. It would be nicer to use a macro to #define Desk_Error_Report so that
  139. __LINE__ and __FILE__ get inserted automatically, but macros can't cope
  140. with variable length argument lists, as used in Desk_Error_Report().
  141.  
  142. ALl the clever macro stuff is copied from DeskLib:WAssert.h
  143. */
  144.  
  145.  
  146.  
  147.  
  148. #ifdef Desk__using_SDLS
  149.   extern Desk_os_error *Desk_Error__Ref_global( void);
  150. #endif
  151.  
  152. #if defined( Desk__using_SDLS) && !defined( Desk__making_Error)
  153.   #define Desk_error_global (*Desk_Error__Ref_global())
  154. #else
  155.   extern Desk_os_error Desk_error_global;
  156. /*
  157. Desk_error_global is a global variable that can be used by any function that
  158. needs to return a custom (Desk_os_error *). This should be used if you want
  159. to build the error inside the function itself (using, for example,
  160. sprintf()). You should use Desk_error_FIXED if the error is fixed (ie.
  161. hard-coded into the program).
  162.  
  163. eg:
  164.  
  165. Desk_os_error *Function(...)
  166. {
  167. [...]
  168. if ( (buf=malloc(buflen)) == NULL) {
  169.   Desk_error_global.errnum=0x80003;
  170.   sprintf( Desk_error_global.errmess,
  171.            "Unable to allocate %d bytes",
  172.            buflen
  173.            );
  174.   return &Desk_error_global;
  175.   }
  176. [...]
  177. }
  178.  
  179. SeeAlso: Desk_os_error_fixed;
  180. */
  181. #endif
  182.  
  183.  
  184. #define Desk_error_FIXED( id, number, description) \
  185.   const struct {                              \
  186.     int  errnum;                              \
  187.     char errmess[ 1 + sizeof( description)];  \
  188.     }                                         \
  189.   id##_= { number, description};              \
  190.   Desk_os_error *id = (Desk_os_error *) &id##_
  191. /*
  192. This defines a fixed error message. The result of this macro can be
  193. achieved in the following way:
  194.  
  195. Desk_os_error Desk_id_= { number, description};
  196. Desk_os_error *id = &Desk_id_;
  197.  
  198. By using this macro however, no space will be lost if 'description' is
  199. less than 252 chars (usually it is just a short string) while the
  200. equivalent Desk_os_error definition will allocate all the 252 chars
  201. regardless of the length of 'description'.
  202.  
  203. The typical use of this macro is to define the 'custom' errors returned
  204. by the user's functions. This definition should be static and should be
  205. placed at top level (ie. not inside a function).
  206.  
  207. eg:
  208.  
  209. static Desk_error_FIXED( outofmemory, 0x80003, "Not enough memory");
  210.  
  211. Desk_os_error *function(...)
  212. {
  213. [...]
  214. if ( ( buf=malloc( buflen)) == NULL)
  215. return outofmemory;
  216. [...]
  217. }
  218.  
  219. Inputs:
  220.  
  221. id          - The name of the error that will be defined. You can
  222.               then use this name as a pointer to the error block
  223.               itself.
  224. number      - The error number.
  225. description - The error message. This should be a constant string
  226.  
  227. SeeAlso:  Desk_error_global;
  228. */
  229.  
  230.  
  231.  
  232.  
  233.  
  234. #define Desk_error_STATIC( id, number, description) \
  235.   static const struct {                              \
  236.     int  errnum;                              \
  237.     char errmess[ 1 + sizeof( description)];  \
  238.     }                                         \
  239.   id##_= { number, description};              \
  240.   static Desk_os_error *id = (Desk_os_error *) &id##_
  241. /*
  242. This defines a fixed (and static) error message. The result of this macro can
  243. be achieved in the following way:
  244.  
  245. static Desk_os_error Desk_id_= { number, description};
  246. static Desk_os_error *id = &Desk_id_;
  247.  
  248. By using this macro however, no space will be lost if 'description' is
  249. less than 252 chars (usually it is just a short string) while the
  250. equivalent Desk_os_error definition will allocate all the 252 chars
  251. regardless of the length of 'description'.
  252.  
  253. The typical use of this macro is to define the 'custom' errors returned
  254. by the user's functions.
  255. If you need a global definition of the error you should use Desk_error_FIXED.
  256.  
  257. eg:
  258.  
  259. Desk_error_STATIC( outofmemory, 0x80003, "Not enough memory");
  260.  
  261. Desk_os_error *function(...)
  262. {
  263. [...]
  264. if ( ( buf=malloc( buflen)) == NULL)
  265. return outofmemory;
  266. [...]
  267. }
  268.  
  269. Inputs:
  270.  
  271. id          - The name of the error that will be defined. You can
  272.               then use this name as a pointer to the error block
  273.               itself.
  274. number      - The error number.
  275. description - The error message. This should be a constant string
  276.  
  277. SeeAlso:  Desk_error_global; Desk_error_FIXED;
  278. */
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285. #ifdef __cplusplus
  286. }
  287. #endif
  288.  
  289.  
  290. #endif
  291.