~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_error.cc

Merge Stewart's dead code removal

Show diffs side-by-side

added added

removed removed

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