2 * Copyright 2001-2004 Brandon Long
5 * ClearSilver Templating System
7 * This code is made available under the terms of the ClearSilver License.
8 * http://www.clearsilver.net/license.hdf
12 #ifndef incl_HPHP_NEO_ERR_H_
13 #define incl_HPHP_NEO_ERR_H_ 1
15 #include "hphp/neo/neo_misc.h"
17 /* For compilers (well, cpp actually) which don't define __PRETTY_FUNCTION__ */
18 #if !defined(__GNUC__) && !defined(__PRETTY_FUNCTION__)
19 #define __PRETTY_FUNCTION__ "unknown_function"
24 /* For 64 bit systems which don't like mixing ints and pointers, we have the
25 * _INT version for doing that comparison */
26 #define STATUS_OK ((NEOERR *)0)
27 #define STATUS_OK_INT 0
28 #define INTERNAL_ERR ((NEOERR *)1)
29 #define INTERNAL_ERR_INT 1
32 #define NE_IN_USE (1<<0)
34 typedef int NERR_TYPE
;
36 /* Predefined Error Types - These are all registered in nerr_init */
37 extern NERR_TYPE NERR_PASS
;
38 extern NERR_TYPE NERR_ASSERT
;
39 extern NERR_TYPE NERR_NOT_FOUND
;
40 extern NERR_TYPE NERR_DUPLICATE
;
41 extern NERR_TYPE NERR_NOMEM
;
42 extern NERR_TYPE NERR_PARSE
;
43 extern NERR_TYPE NERR_OUTOFRANGE
;
44 extern NERR_TYPE NERR_SYSTEM
;
45 extern NERR_TYPE NERR_IO
;
46 extern NERR_TYPE NERR_LOCK
;
47 extern NERR_TYPE NERR_DB
;
48 extern NERR_TYPE NERR_EXISTS
;
49 extern NERR_TYPE NERR_MAX_RECURSION
;
51 typedef struct _neo_err
59 /* internal use only */
60 struct _neo_err
*next
;
63 /* Technically, we could do this in configure and detect what their compiler
64 * can handle, but for now... */
65 #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
67 #define USE_C99_VARARG_MACROS 1
68 #elif __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4) || defined (S_SPLINT_S)
69 #define USE_GNUC_VARARG_MACROS 1
71 #error The compiler is missing support for variable-argument macros.
76 * function: nerr_raise
77 * description: Use this method to create an error "exception" for
78 * return up the call chain
79 * arguments: using the macro, the function name, file, and lineno are
80 * automagically recorded for you. You just provide the
81 * error (from those listed above) and the printf-style
82 * reason. THIS IS A PRINTF STYLE FUNCTION, DO NOT PASS
83 * UNKNOWN STRING DATA AS THE FORMAT STRING.
84 * returns: a pointer to a NEOERR, or INTERNAL_ERR if allocation of
87 #if defined(USE_C99_VARARG_MACROS)
88 #define nerr_raise(e,...) \
89 nerr_raisef(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,__VA_ARGS__)
90 #elif defined(USE_GNUC_VARARG_MACROS)
91 #define nerr_raise(e,f,a...) \
92 nerr_raisef(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,f,##a)
95 NEOERR
*nerr_raisef (const char *func
, const char *file
, int lineno
,
96 NERR_TYPE error
, const char *fmt
, ...)
97 ATTRIBUTE_PRINTF(5,6);
101 #if defined(USE_C99_VARARG_MACROS)
102 #define nerr_raise_errno(e,...) \
103 nerr_raise_errnof(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,__VA_ARGS__)
104 #elif defined(USE_GNUC_VARARG_MACROS)
105 #define nerr_raise_errno(e,a...) \
106 nerr_raise_errnof(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,##a)
109 NEOERR
*nerr_raise_errnof (const char *func
, const char *file
, int lineno
,
110 int error
, const char *fmt
, ...)
111 ATTRIBUTE_PRINTF(5,6);
113 /* function: nerr_pass - pass a clearsilver error up a level in the call chain
114 * description: this function is used to pass an error up a level in the
115 * call chain (ie, if the error isn't handled at the
116 * current level). This allows us to track the traceback
118 * arguments: with the macro, the function name, file and lineno are
119 * automagically recorded. Just pass the error.
120 * returns: a pointer to an error
122 #define nerr_pass(e) \
123 nerr_passf(__PRETTY_FUNCTION__,__FILE__,__LINE__,e)
125 NEOERR
*nerr_passf (const char *func
, const char *file
, int lineno
,
128 /* function: nerr_pass_ctx - pass a clearsilver error up a level in the call
129 * chain with additional information
130 * description: this function is used to pass an error up a level in the
131 * call chain (ie, if the error isn't handled at the
132 * current level). This allows us to track the traceback
134 * This version includes context information about lower
136 * arguments: with the macro, the function name, file and lineno are
137 * automagically recorded. Just pass the error and
138 * a printf format string giving more information about where
139 * the error is occuring.
140 * returns: a pointer to an error
142 #if defined(USE_C99_VARARG_MACROS)
143 #define nerr_pass_ctx(e,...) \
144 nerr_pass_ctxf(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,__VA_ARGS__)
145 #elif defined(USE_GNUC_VARARG_MACROS)
146 #define nerr_pass_ctx(e,a...) \
147 nerr_pass_ctxf(__PRETTY_FUNCTION__,__FILE__,__LINE__,e,##a)
150 NEOERR
*nerr_pass_ctxf (const char *func
, const char *file
, int lineno
,
151 NEOERR
*nerr
, const char *fmt
, ...)
152 ATTRIBUTE_PRINTF(5,6);
154 /* function: nerr_log_error - print the error chain to stderr
155 * description: prints out the error traceback to stderr
157 void nerr_log_error (NEOERR
*nerr
);
159 #include "hphp/neo/neo_str.h"
160 /* function: nerr_error_string - returns the string associated with an error
161 * description: returns the string associated with an error (the bottom
162 * level of the error chain)
163 * arguments: nerr - error
164 * str - string to which the data is appended
165 * returns: None - errors appending to the string are ignored
167 void nerr_error_string (NEOERR
*nerr
, NEOSTRING
*str
);
169 /* function: nerr_register - register a NEOERR type
170 * description: register an error type. This will assign a numeric value
171 * to the type, and keep track of the "pretty name" for it.
172 * arguments: err - pointer to a NERR_TYPE
173 * name - pretty name for the error type
174 * returns: NERR_NOMEM on no memory
176 NEOERR
*nerr_register (NERR_TYPE
*err
, const char *name
);
178 /* function: nerr_init - initialize the NEOERR error subsystem
179 * description: initialize the NEOERR system. Can be called more than once.
180 * This registers all of the built in error types as defined at
181 * the top of this file. If you don't call this, all exceptions
182 * will be returned as UnknownError.
184 * returns: possibly NERR_NOMEM, but somewhat unlikely. Possibly an
185 * UnknownError if NERR_NOMEM hasn't been registered yet.
187 NEOERR
*nerr_init (void);
191 #endif /* incl_HPHP_NEO_ERR_H_ */