1
by brian
clean slate |
1 |
/* Copyright (C) 2000 MySQL AB
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
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. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
14 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
15 |
||
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
16 |
#include "config.h" |
17 |
||
18 |
#include <cstdio> |
|
19 |
#include <stdarg.h> |
|
20 |
||
612.2.6
by Monty Taylor
OpenSolaris builds. |
21 |
#include <drizzled/gettext.h> |
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
22 |
#include "drizzled/my_error.h" |
23 |
#include "drizzled/definitions.h" |
|
24 |
||
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
25 |
namespace drizzled |
26 |
{
|
|
27 |
||
1241.9.57
by Monty Taylor
Oy. Bigger change than I normally like - but this stuff is all intertwined. |
28 |
/* Error message numbers in global map */
|
29 |
const char * globerrs[GLOBERRS]; |
|
30 |
||
31 |
error_handler_func error_handler_hook= NULL; |
|
32 |
||
33 |
||
34 |
void init_glob_errs() |
|
35 |
{
|
|
36 |
EE(EE_CANTCREATEFILE) = N_("Can't create/write to file '%s' (Errcode: %d)"); |
|
37 |
EE(EE_READ) = N_("Error reading file '%s' (Errcode: %d)"); |
|
38 |
EE(EE_WRITE) = N_("Error writing file '%s' (Errcode: %d)"); |
|
39 |
EE(EE_BADCLOSE) = N_("Error on close of '%s' (Errcode: %d)"); |
|
40 |
EE(EE_OUTOFMEMORY) = N_("Out of memory (Needed %u bytes)"); |
|
41 |
EE(EE_DELETE) = N_("Error on delete of '%s' (Errcode: %d)"); |
|
42 |
EE(EE_LINK) = N_("Error on rename of '%s' to '%s' (Errcode: %d)"); |
|
43 |
EE(EE_EOFERR) = N_("Unexpected eof found when reading file '%s' (Errcode: %d)"); |
|
44 |
EE(EE_CANTLOCK) = N_("Can't lock file (Errcode: %d)"); |
|
45 |
EE(EE_CANTUNLOCK) = N_("Can't unlock file (Errcode: %d)"); |
|
46 |
EE(EE_DIR) = N_("Can't read dir of '%s' (Errcode: %d)"); |
|
47 |
EE(EE_STAT) = N_("Can't get stat of '%s' (Errcode: %d)"); |
|
48 |
EE(EE_CANT_CHSIZE) = N_("Can't change size of file (Errcode: %d)"); |
|
49 |
EE(EE_CANT_OPEN_STREAM)= N_("Can't open stream from handle (Errcode: %d)"); |
|
50 |
EE(EE_GETWD) = N_("Can't get working dirctory (Errcode: %d)"); |
|
51 |
EE(EE_SETWD) = N_("Can't change dir to '%s' (Errcode: %d)"); |
|
52 |
EE(EE_LINK_WARNING) = N_("Warning: '%s' had %d links"); |
|
53 |
EE(EE_OPEN_WARNING) = N_("Warning: %d files and %d streams is left open\n"); |
|
54 |
EE(EE_DISK_FULL) = N_("Disk is full writing '%s'. Waiting for someone to free space..."); |
|
55 |
EE(EE_CANT_MKDIR) = N_("Can't create directory '%s' (Errcode: %d)"); |
|
56 |
EE(EE_UNKNOWN_CHARSET)= N_("Character set '%s' is not a compiled character set and is not specified in the %s file"); |
|
57 |
EE(EE_OUT_OF_FILERESOURCES)= N_("Out of resources when opening file '%s' (Errcode: %d)"); |
|
58 |
EE(EE_CANT_READLINK)= N_("Can't read value for symlink '%s' (Error %d)"); |
|
59 |
EE(EE_CANT_SYMLINK)= N_("Can't create symlink '%s' pointing at '%s' (Error %d)"); |
|
60 |
EE(EE_REALPATH)= N_("Error on realpath() on '%s' (Error %d)"); |
|
61 |
EE(EE_SYNC)= N_("Can't sync file '%s' to disk (Errcode: %d)"); |
|
62 |
EE(EE_UNKNOWN_COLLATION)= N_("Collation '%s' is not a compiled collation and is not specified in the %s file"); |
|
63 |
EE(EE_FILENOTFOUND) = N_("File '%s' not found (Errcode: %d)"); |
|
64 |
EE(EE_FILE_NOT_CLOSED) = N_("File '%s' (fileno: %d) was not closed"); |
|
65 |
}
|
|
1
by brian
clean slate |
66 |
|
67 |
/*
|
|
68 |
WARNING!
|
|
69 |
my_error family functions have to be used according following rules:
|
|
70 |
- if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
|
|
71 |
- if message registered use my_error(ER_CODE, MYF(N), ...).
|
|
72 |
- With some special text of errror message use:
|
|
73 |
my_printf_error(ER_CODE, format, MYF(N), ...)
|
|
74 |
*/
|
|
75 |
||
76 |
/*
|
|
77 |
Message texts are registered into a linked list of 'my_err_head' structs.
|
|
78 |
Each struct contains (1.) an array of pointers to C character strings with
|
|
79 |
'\0' termination, (2.) the error number for the first message in the array
|
|
80 |
(array index 0) and (3.) the error number for the last message in the array
|
|
81 |
(array index (last - first)).
|
|
82 |
The array may contain gaps with NULL pointers and pointers to empty strings.
|
|
83 |
Both kinds of gaps will be translated to "Unknown error %d.", if my_error()
|
|
84 |
is called with a respective error number.
|
|
85 |
The list of header structs is sorted in increasing order of error numbers.
|
|
86 |
Negative error numbers are allowed. Overlap of error numbers is not allowed.
|
|
87 |
Not registered error numbers will be translated to "Unknown error %d.".
|
|
88 |
*/
|
|
89 |
static struct my_err_head |
|
90 |
{
|
|
91 |
struct my_err_head *meh_next; /* chain link */ |
|
92 |
const char **meh_errmsgs; /* error messages array */ |
|
93 |
int meh_first; /* error number matching array slot 0 */ |
|
94 |
int meh_last; /* error number matching last slot */ |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
95 |
bool is_globerrs; |
96 |
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST, true}; |
|
1
by brian
clean slate |
97 |
|
98 |
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs; |
|
99 |
||
100 |
||
101 |
/*
|
|
102 |
Error message to user
|
|
103 |
||
104 |
SYNOPSIS
|
|
105 |
my_error()
|
|
106 |
nr Errno
|
|
107 |
MyFlags Flags
|
|
108 |
... variable list
|
|
109 |
*/
|
|
110 |
||
111 |
void my_error(int nr, myf MyFlags, ...) |
|
112 |
{
|
|
113 |
const char *format; |
|
114 |
struct my_err_head *meh_p; |
|
115 |
va_list args; |
|
116 |
char ebuff[ERRMSGSIZE + 20]; |
|
117 |
||
118 |
/* Search for the error messages array, which could contain the message. */
|
|
119 |
for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next) |
|
120 |
if (nr <= meh_p->meh_last) |
|
121 |
break; |
|
122 |
||
123 |
/* get the error message string. Default, if NULL or empty string (""). */
|
|
124 |
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ? |
|
202.3.6
by Monty Taylor
First pass at gettexizing the error messages. |
125 |
_(meh_p->meh_errmsgs[nr - meh_p->meh_first]) : NULL) || ! *format) |
126 |
(void) snprintf (ebuff, sizeof(ebuff), _("Unknown error %d"), nr); |
|
1
by brian
clean slate |
127 |
else
|
128 |
{
|
|
129 |
va_start(args,MyFlags); |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
130 |
(void) vsnprintf (ebuff, sizeof(ebuff), format, args); |
1
by brian
clean slate |
131 |
va_end(args); |
132 |
}
|
|
133 |
(*error_handler_hook)(nr, ebuff, MyFlags); |
|
51.3.19
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
134 |
return; |
1
by brian
clean slate |
135 |
}
|
136 |
||
137 |
||
138 |
/*
|
|
139 |
Error as printf
|
|
140 |
||
141 |
SYNOPSIS
|
|
142 |
my_printf_error()
|
|
143 |
error Errno
|
|
144 |
format Format string
|
|
145 |
MyFlags Flags
|
|
146 |
... variable list
|
|
147 |
*/
|
|
148 |
||
482
by Brian Aker
Remove uint. |
149 |
void my_printf_error(uint32_t error, const char *format, myf MyFlags, ...) |
1
by brian
clean slate |
150 |
{
|
151 |
va_list args; |
|
152 |
char ebuff[ERRMSGSIZE+20]; |
|
153 |
||
154 |
va_start(args,MyFlags); |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
155 |
(void) vsnprintf (ebuff, sizeof(ebuff), format, args); |
1
by brian
clean slate |
156 |
va_end(args); |
157 |
(*error_handler_hook)(error, ebuff, MyFlags); |
|
51.3.19
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
158 |
return; |
1
by brian
clean slate |
159 |
}
|
160 |
||
161 |
/*
|
|
162 |
Give message using error_handler_hook
|
|
163 |
||
164 |
SYNOPSIS
|
|
165 |
my_message()
|
|
166 |
error Errno
|
|
167 |
str Error message
|
|
168 |
MyFlags Flags
|
|
169 |
*/
|
|
170 |
||
482
by Brian Aker
Remove uint. |
171 |
void my_message(uint32_t error, const char *str, register myf MyFlags) |
1
by brian
clean slate |
172 |
{
|
173 |
(*error_handler_hook)(error, str, MyFlags); |
|
174 |
}
|
|
175 |
||
176 |
||
177 |
/*
|
|
178 |
Register error messages for use with my_error().
|
|
179 |
||
180 |
SYNOPSIS
|
|
181 |
my_error_register()
|
|
182 |
errmsgs array of pointers to error messages
|
|
183 |
first error number of first message in the array
|
|
184 |
last error number of last message in the array
|
|
185 |
||
186 |
DESCRIPTION
|
|
187 |
The pointer array is expected to contain addresses to NUL-terminated
|
|
188 |
C character strings. The array contains (last - first + 1) pointers.
|
|
189 |
NULL pointers and empty strings ("") are allowed. These will be mapped to
|
|
190 |
"Unknown error" when my_error() is called with a matching error number.
|
|
191 |
This function registers the error numbers 'first' to 'last'.
|
|
192 |
No overlapping with previously registered error numbers is allowed.
|
|
193 |
||
194 |
RETURN
|
|
195 |
0 OK
|
|
196 |
!= 0 Error
|
|
197 |
*/
|
|
198 |
||
199 |
int my_error_register(const char **errmsgs, int first, int last) |
|
200 |
{
|
|
201 |
struct my_err_head *meh_p; |
|
202 |
struct my_err_head **search_meh_pp; |
|
203 |
||
204 |
/* Allocate a new header structure. */
|
|
656.1.26
by Monty Taylor
Finally removed all of the my_malloc stuff. |
205 |
if (! (meh_p= (struct my_err_head*) malloc(sizeof(struct my_err_head)))) |
1
by brian
clean slate |
206 |
return 1; |
207 |
meh_p->meh_errmsgs= errmsgs; |
|
208 |
meh_p->meh_first= first; |
|
209 |
meh_p->meh_last= last; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
210 |
meh_p->is_globerrs= false; |
1
by brian
clean slate |
211 |
|
212 |
/* Search for the right position in the list. */
|
|
213 |
for (search_meh_pp= &my_errmsgs_list; |
|
214 |
*search_meh_pp; |
|
215 |
search_meh_pp= &(*search_meh_pp)->meh_next) |
|
216 |
{
|
|
217 |
if ((*search_meh_pp)->meh_last > first) |
|
218 |
break; |
|
219 |
}
|
|
220 |
||
221 |
/* Error numbers must be unique. No overlapping is allowed. */
|
|
222 |
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last)) |
|
223 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
224 |
free((unsigned char*)meh_p); |
1
by brian
clean slate |
225 |
return 1; |
226 |
}
|
|
227 |
||
228 |
/* Insert header into the chain. */
|
|
229 |
meh_p->meh_next= *search_meh_pp; |
|
230 |
*search_meh_pp= meh_p; |
|
231 |
return 0; |
|
232 |
}
|
|
233 |
||
234 |
||
235 |
/*
|
|
236 |
Unregister formerly registered error messages.
|
|
237 |
||
238 |
SYNOPSIS
|
|
239 |
my_error_unregister()
|
|
240 |
first error number of first message
|
|
241 |
last error number of last message
|
|
242 |
||
243 |
DESCRIPTION
|
|
244 |
This function unregisters the error numbers 'first' to 'last'.
|
|
245 |
These must have been previously registered by my_error_register().
|
|
246 |
'first' and 'last' must exactly match the registration.
|
|
247 |
If a matching registration is present, the header is removed from the
|
|
248 |
list and the pointer to the error messages pointers array is returned.
|
|
249 |
Otherwise, NULL is returned.
|
|
250 |
||
251 |
RETURN
|
|
252 |
non-NULL OK, returns address of error messages pointers array.
|
|
253 |
NULL Error, no such number range registered.
|
|
254 |
*/
|
|
255 |
||
256 |
const char **my_error_unregister(int first, int last) |
|
257 |
{
|
|
258 |
struct my_err_head *meh_p; |
|
259 |
struct my_err_head **search_meh_pp; |
|
260 |
const char **errmsgs; |
|
261 |
||
262 |
/* Search for the registration in the list. */
|
|
263 |
for (search_meh_pp= &my_errmsgs_list; |
|
264 |
*search_meh_pp; |
|
265 |
search_meh_pp= &(*search_meh_pp)->meh_next) |
|
266 |
{
|
|
267 |
if (((*search_meh_pp)->meh_first == first) && |
|
268 |
((*search_meh_pp)->meh_last == last)) |
|
269 |
break; |
|
270 |
}
|
|
271 |
if (! *search_meh_pp) |
|
272 |
return NULL; |
|
273 |
||
274 |
/* Remove header from the chain. */
|
|
275 |
meh_p= *search_meh_pp; |
|
276 |
*search_meh_pp= meh_p->meh_next; |
|
277 |
||
278 |
/* Save the return value and free the header. */
|
|
279 |
errmsgs= meh_p->meh_errmsgs; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
280 |
bool is_globerrs= meh_p->is_globerrs; |
281 |
||
481
by Brian Aker
Remove all of uchar. |
282 |
free((unsigned char*) meh_p); |
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
283 |
|
284 |
if (is_globerrs) |
|
285 |
return NULL; |
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
286 |
|
1
by brian
clean slate |
287 |
return errmsgs; |
288 |
}
|
|
289 |
||
290 |
||
291 |
void my_error_unregister_all(void) |
|
292 |
{
|
|
293 |
struct my_err_head *list, *next; |
|
294 |
for (list= my_errmsgs_globerrs.meh_next; list; list= next) |
|
295 |
{
|
|
296 |
next= list->meh_next; |
|
481
by Brian Aker
Remove all of uchar. |
297 |
free((unsigned char*) list); |
1
by brian
clean slate |
298 |
}
|
299 |
my_errmsgs_list= &my_errmsgs_globerrs; |
|
300 |
}
|
|
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
301 |
|
302 |
} /* namespace drizzled */ |