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 |
||
16 |
#include "mysys_priv.h" |
|
17 |
#include "mysys_err.h" |
|
212.5.18
by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype. |
18 |
#include <mystrings/m_string.h> |
1
by brian
clean slate |
19 |
#include <stdarg.h> |
212.5.18
by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype. |
20 |
#include <mystrings/m_ctype.h> |
202.3.6
by Monty Taylor
First pass at gettexizing the error messages. |
21 |
#include <libdrizzle/gettext.h> |
1
by brian
clean slate |
22 |
|
23 |
/* Define some external variables for error handling */
|
|
24 |
||
25 |
/*
|
|
26 |
WARNING!
|
|
27 |
my_error family functions have to be used according following rules:
|
|
28 |
- if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
|
|
29 |
- if message registered use my_error(ER_CODE, MYF(N), ...).
|
|
30 |
- With some special text of errror message use:
|
|
31 |
my_printf_error(ER_CODE, format, MYF(N), ...)
|
|
32 |
*/
|
|
33 |
||
34 |
char errbuff[NRERRBUFFS][ERRMSGSIZE]; |
|
35 |
||
36 |
/*
|
|
37 |
Message texts are registered into a linked list of 'my_err_head' structs.
|
|
38 |
Each struct contains (1.) an array of pointers to C character strings with
|
|
39 |
'\0' termination, (2.) the error number for the first message in the array
|
|
40 |
(array index 0) and (3.) the error number for the last message in the array
|
|
41 |
(array index (last - first)).
|
|
42 |
The array may contain gaps with NULL pointers and pointers to empty strings.
|
|
43 |
Both kinds of gaps will be translated to "Unknown error %d.", if my_error()
|
|
44 |
is called with a respective error number.
|
|
45 |
The list of header structs is sorted in increasing order of error numbers.
|
|
46 |
Negative error numbers are allowed. Overlap of error numbers is not allowed.
|
|
47 |
Not registered error numbers will be translated to "Unknown error %d.".
|
|
48 |
*/
|
|
49 |
static struct my_err_head |
|
50 |
{
|
|
51 |
struct my_err_head *meh_next; /* chain link */ |
|
52 |
const char **meh_errmsgs; /* error messages array */ |
|
53 |
int meh_first; /* error number matching array slot 0 */ |
|
54 |
int meh_last; /* error number matching last slot */ |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
55 |
bool is_globerrs; |
56 |
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST, true}; |
|
1
by brian
clean slate |
57 |
|
58 |
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs; |
|
59 |
||
60 |
||
61 |
/*
|
|
62 |
Error message to user
|
|
63 |
||
64 |
SYNOPSIS
|
|
65 |
my_error()
|
|
66 |
nr Errno
|
|
67 |
MyFlags Flags
|
|
68 |
... variable list
|
|
69 |
*/
|
|
70 |
||
71 |
void my_error(int nr, myf MyFlags, ...) |
|
72 |
{
|
|
73 |
const char *format; |
|
74 |
struct my_err_head *meh_p; |
|
75 |
va_list args; |
|
76 |
char ebuff[ERRMSGSIZE + 20]; |
|
77 |
||
78 |
/* Search for the error messages array, which could contain the message. */
|
|
79 |
for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next) |
|
80 |
if (nr <= meh_p->meh_last) |
|
81 |
break; |
|
82 |
||
83 |
/* get the error message string. Default, if NULL or empty string (""). */
|
|
84 |
if (! (format= (meh_p && (nr >= meh_p->meh_first)) ? |
|
202.3.6
by Monty Taylor
First pass at gettexizing the error messages. |
85 |
_(meh_p->meh_errmsgs[nr - meh_p->meh_first]) : NULL) || ! *format) |
86 |
(void) snprintf (ebuff, sizeof(ebuff), _("Unknown error %d"), nr); |
|
1
by brian
clean slate |
87 |
else
|
88 |
{
|
|
89 |
va_start(args,MyFlags); |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
90 |
(void) vsnprintf (ebuff, sizeof(ebuff), format, args); |
1
by brian
clean slate |
91 |
va_end(args); |
92 |
}
|
|
93 |
(*error_handler_hook)(nr, ebuff, MyFlags); |
|
51.3.19
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
94 |
return; |
1
by brian
clean slate |
95 |
}
|
96 |
||
97 |
||
98 |
/*
|
|
99 |
Error as printf
|
|
100 |
||
101 |
SYNOPSIS
|
|
102 |
my_printf_error()
|
|
103 |
error Errno
|
|
104 |
format Format string
|
|
105 |
MyFlags Flags
|
|
106 |
... variable list
|
|
107 |
*/
|
|
108 |
||
109 |
void my_printf_error(uint error, const char *format, myf MyFlags, ...) |
|
110 |
{
|
|
111 |
va_list args; |
|
112 |
char ebuff[ERRMSGSIZE+20]; |
|
113 |
||
114 |
va_start(args,MyFlags); |
|
77.1.18
by Monty Taylor
Removed my_vsnprintf and my_snprintf. |
115 |
(void) vsnprintf (ebuff, sizeof(ebuff), format, args); |
1
by brian
clean slate |
116 |
va_end(args); |
117 |
(*error_handler_hook)(error, ebuff, MyFlags); |
|
51.3.19
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
118 |
return; |
1
by brian
clean slate |
119 |
}
|
120 |
||
121 |
/*
|
|
122 |
Give message using error_handler_hook
|
|
123 |
||
124 |
SYNOPSIS
|
|
125 |
my_message()
|
|
126 |
error Errno
|
|
127 |
str Error message
|
|
128 |
MyFlags Flags
|
|
129 |
*/
|
|
130 |
||
131 |
void my_message(uint error, const char *str, register myf MyFlags) |
|
132 |
{
|
|
133 |
(*error_handler_hook)(error, str, MyFlags); |
|
134 |
}
|
|
135 |
||
136 |
||
137 |
/*
|
|
138 |
Register error messages for use with my_error().
|
|
139 |
||
140 |
SYNOPSIS
|
|
141 |
my_error_register()
|
|
142 |
errmsgs array of pointers to error messages
|
|
143 |
first error number of first message in the array
|
|
144 |
last error number of last message in the array
|
|
145 |
||
146 |
DESCRIPTION
|
|
147 |
The pointer array is expected to contain addresses to NUL-terminated
|
|
148 |
C character strings. The array contains (last - first + 1) pointers.
|
|
149 |
NULL pointers and empty strings ("") are allowed. These will be mapped to
|
|
150 |
"Unknown error" when my_error() is called with a matching error number.
|
|
151 |
This function registers the error numbers 'first' to 'last'.
|
|
152 |
No overlapping with previously registered error numbers is allowed.
|
|
153 |
||
154 |
RETURN
|
|
155 |
0 OK
|
|
156 |
!= 0 Error
|
|
157 |
*/
|
|
158 |
||
159 |
int my_error_register(const char **errmsgs, int first, int last) |
|
160 |
{
|
|
161 |
struct my_err_head *meh_p; |
|
162 |
struct my_err_head **search_meh_pp; |
|
163 |
||
164 |
/* Allocate a new header structure. */
|
|
165 |
if (! (meh_p= (struct my_err_head*) my_malloc(sizeof(struct my_err_head), |
|
166 |
MYF(MY_WME)))) |
|
167 |
return 1; |
|
168 |
meh_p->meh_errmsgs= errmsgs; |
|
169 |
meh_p->meh_first= first; |
|
170 |
meh_p->meh_last= last; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
171 |
meh_p->is_globerrs= false; |
1
by brian
clean slate |
172 |
|
173 |
/* Search for the right position in the list. */
|
|
174 |
for (search_meh_pp= &my_errmsgs_list; |
|
175 |
*search_meh_pp; |
|
176 |
search_meh_pp= &(*search_meh_pp)->meh_next) |
|
177 |
{
|
|
178 |
if ((*search_meh_pp)->meh_last > first) |
|
179 |
break; |
|
180 |
}
|
|
181 |
||
182 |
/* Error numbers must be unique. No overlapping is allowed. */
|
|
183 |
if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last)) |
|
184 |
{
|
|
185 |
my_free((uchar*)meh_p, MYF(0)); |
|
186 |
return 1; |
|
187 |
}
|
|
188 |
||
189 |
/* Insert header into the chain. */
|
|
190 |
meh_p->meh_next= *search_meh_pp; |
|
191 |
*search_meh_pp= meh_p; |
|
192 |
return 0; |
|
193 |
}
|
|
194 |
||
195 |
||
196 |
/*
|
|
197 |
Unregister formerly registered error messages.
|
|
198 |
||
199 |
SYNOPSIS
|
|
200 |
my_error_unregister()
|
|
201 |
first error number of first message
|
|
202 |
last error number of last message
|
|
203 |
||
204 |
DESCRIPTION
|
|
205 |
This function unregisters the error numbers 'first' to 'last'.
|
|
206 |
These must have been previously registered by my_error_register().
|
|
207 |
'first' and 'last' must exactly match the registration.
|
|
208 |
If a matching registration is present, the header is removed from the
|
|
209 |
list and the pointer to the error messages pointers array is returned.
|
|
210 |
Otherwise, NULL is returned.
|
|
211 |
||
212 |
RETURN
|
|
213 |
non-NULL OK, returns address of error messages pointers array.
|
|
214 |
NULL Error, no such number range registered.
|
|
215 |
*/
|
|
216 |
||
217 |
const char **my_error_unregister(int first, int last) |
|
218 |
{
|
|
219 |
struct my_err_head *meh_p; |
|
220 |
struct my_err_head **search_meh_pp; |
|
221 |
const char **errmsgs; |
|
222 |
||
223 |
/* Search for the registration in the list. */
|
|
224 |
for (search_meh_pp= &my_errmsgs_list; |
|
225 |
*search_meh_pp; |
|
226 |
search_meh_pp= &(*search_meh_pp)->meh_next) |
|
227 |
{
|
|
228 |
if (((*search_meh_pp)->meh_first == first) && |
|
229 |
((*search_meh_pp)->meh_last == last)) |
|
230 |
break; |
|
231 |
}
|
|
232 |
if (! *search_meh_pp) |
|
233 |
return NULL; |
|
234 |
||
235 |
/* Remove header from the chain. */
|
|
236 |
meh_p= *search_meh_pp; |
|
237 |
*search_meh_pp= meh_p->meh_next; |
|
238 |
||
239 |
/* Save the return value and free the header. */
|
|
240 |
errmsgs= meh_p->meh_errmsgs; |
|
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
241 |
bool is_globerrs= meh_p->is_globerrs; |
242 |
||
1
by brian
clean slate |
243 |
my_free((uchar*) meh_p, MYF(0)); |
202.3.7
by Monty Taylor
Gettext error compiles and passes test! |
244 |
|
245 |
if (is_globerrs) |
|
246 |
return NULL; |
|
1
by brian
clean slate |
247 |
|
248 |
return errmsgs; |
|
249 |
}
|
|
250 |
||
251 |
||
252 |
void my_error_unregister_all(void) |
|
253 |
{
|
|
254 |
struct my_err_head *list, *next; |
|
255 |
for (list= my_errmsgs_globerrs.meh_next; list; list= next) |
|
256 |
{
|
|
257 |
next= list->meh_next; |
|
258 |
my_free((uchar*) list, MYF(0)); |
|
259 |
}
|
|
260 |
my_errmsgs_list= &my_errmsgs_globerrs; |
|
261 |
}
|