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