~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_error.cc

  • Committer: Brian Aker
  • Date: 2010-04-05 23:46:43 UTC
  • Revision ID: brian@gaz-20100405234643-0he3xnj902rc70r8
Fixing tests to work with PBXT.

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
 
}