~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/my_error.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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_priv.h"
 
17
#include "mysys_err.h"
 
18
#include <m_string.h>
 
19
#include <stdarg.h>
 
20
#include <m_ctype.h>
 
21
 
 
22
/* Define some external variables for error handling */
 
23
 
 
24
/*
 
25
  WARNING!
 
26
  my_error family functions have to be used according following rules:
 
27
  - if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
 
28
  - if message registered use my_error(ER_CODE, MYF(N), ...).
 
29
  - With some special text of errror message use:
 
30
  my_printf_error(ER_CODE, format, MYF(N), ...)
 
31
*/
 
32
 
 
33
char errbuff[NRERRBUFFS][ERRMSGSIZE];
 
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
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST};
 
55
 
 
56
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
 
57
 
 
58
 
 
59
/*
 
60
   Error message to user
 
61
 
 
62
   SYNOPSIS
 
63
     my_error()
 
64
       nr       Errno
 
65
       MyFlags  Flags
 
66
       ...      variable list
 
67
*/
 
68
 
 
69
void my_error(int nr, myf MyFlags, ...)
 
70
{
 
71
  const char *format;
 
72
  struct my_err_head *meh_p;
 
73
  va_list args;
 
74
  char ebuff[ERRMSGSIZE + 20];
 
75
  DBUG_ENTER("my_error");
 
76
  DBUG_PRINT("my", ("nr: %d  MyFlags: %d  errno: %d", nr, MyFlags, errno));
 
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)) ?
 
85
         meh_p->meh_errmsgs[nr - meh_p->meh_first] : NULL) || ! *format)
 
86
    (void) my_snprintf (ebuff, sizeof(ebuff), "Unknown error %d", nr);
 
87
  else
 
88
  {
 
89
    va_start(args,MyFlags);
 
90
    (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args);
 
91
    va_end(args);
 
92
  }
 
93
  (*error_handler_hook)(nr, ebuff, MyFlags);
 
94
  DBUG_VOID_RETURN;
 
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
  DBUG_ENTER("my_printf_error");
 
114
  DBUG_PRINT("my", ("nr: %d  MyFlags: %d  errno: %d  Format: %s",
 
115
                    error, MyFlags, errno, format));
 
116
 
 
117
  va_start(args,MyFlags);
 
118
  (void) my_vsnprintf (ebuff, sizeof(ebuff), format, args);
 
119
  va_end(args);
 
120
  (*error_handler_hook)(error, ebuff, MyFlags);
 
121
  DBUG_VOID_RETURN;
 
122
}
 
123
 
 
124
/*
 
125
  Give message using error_handler_hook
 
126
 
 
127
  SYNOPSIS
 
128
    my_message()
 
129
      error     Errno
 
130
      str       Error message
 
131
      MyFlags   Flags
 
132
*/
 
133
 
 
134
void my_message(uint error, const char *str, register myf MyFlags)
 
135
{
 
136
  (*error_handler_hook)(error, str, MyFlags);
 
137
}
 
138
 
 
139
 
 
140
/*
 
141
  Register error messages for use with my_error().
 
142
 
 
143
  SYNOPSIS
 
144
    my_error_register()
 
145
    errmsgs                     array of pointers to error messages
 
146
    first                       error number of first message in the array
 
147
    last                        error number of last message in the array
 
148
 
 
149
  DESCRIPTION
 
150
    The pointer array is expected to contain addresses to NUL-terminated
 
151
    C character strings. The array contains (last - first + 1) pointers.
 
152
    NULL pointers and empty strings ("") are allowed. These will be mapped to
 
153
    "Unknown error" when my_error() is called with a matching error number.
 
154
    This function registers the error numbers 'first' to 'last'.
 
155
    No overlapping with previously registered error numbers is allowed.
 
156
 
 
157
  RETURN
 
158
    0           OK
 
159
    != 0        Error
 
160
*/
 
161
 
 
162
int my_error_register(const char **errmsgs, int first, int last)
 
163
{
 
164
  struct my_err_head *meh_p;
 
165
  struct my_err_head **search_meh_pp;
 
166
 
 
167
  /* Allocate a new header structure. */
 
168
  if (! (meh_p= (struct my_err_head*) my_malloc(sizeof(struct my_err_head),
 
169
                                                MYF(MY_WME))))
 
170
    return 1;
 
171
  meh_p->meh_errmsgs= errmsgs;
 
172
  meh_p->meh_first= first;
 
173
  meh_p->meh_last= last;
 
174
 
 
175
  /* Search for the right position in the list. */
 
176
  for (search_meh_pp= &my_errmsgs_list;
 
177
       *search_meh_pp;
 
178
       search_meh_pp= &(*search_meh_pp)->meh_next)
 
179
  {
 
180
    if ((*search_meh_pp)->meh_last > first)
 
181
      break;
 
182
  }
 
183
 
 
184
  /* Error numbers must be unique. No overlapping is allowed. */
 
185
  if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
 
186
  {
 
187
    my_free((uchar*)meh_p, MYF(0));
 
188
    return 1;
 
189
  }
 
190
 
 
191
  /* Insert header into the chain. */
 
192
  meh_p->meh_next= *search_meh_pp;
 
193
  *search_meh_pp= meh_p;
 
194
  return 0;
 
195
}
 
196
 
 
197
 
 
198
/*
 
199
  Unregister formerly registered error messages.
 
200
 
 
201
  SYNOPSIS
 
202
    my_error_unregister()
 
203
    first                       error number of first message
 
204
    last                        error number of last message
 
205
 
 
206
  DESCRIPTION
 
207
    This function unregisters the error numbers 'first' to 'last'.
 
208
    These must have been previously registered by my_error_register().
 
209
    'first' and 'last' must exactly match the registration.
 
210
    If a matching registration is present, the header is removed from the
 
211
    list and the pointer to the error messages pointers array is returned.
 
212
    Otherwise, NULL is returned.
 
213
 
 
214
  RETURN
 
215
    non-NULL    OK, returns address of error messages pointers array.
 
216
    NULL        Error, no such number range registered.
 
217
*/
 
218
 
 
219
const char **my_error_unregister(int first, int last)
 
220
{
 
221
  struct my_err_head    *meh_p;
 
222
  struct my_err_head    **search_meh_pp;
 
223
  const char            **errmsgs;
 
224
 
 
225
  /* Search for the registration in the list. */
 
226
  for (search_meh_pp= &my_errmsgs_list;
 
227
       *search_meh_pp;
 
228
       search_meh_pp= &(*search_meh_pp)->meh_next)
 
229
  {
 
230
    if (((*search_meh_pp)->meh_first == first) &&
 
231
        ((*search_meh_pp)->meh_last == last))
 
232
      break;
 
233
  }
 
234
  if (! *search_meh_pp)
 
235
    return NULL;
 
236
 
 
237
  /* Remove header from the chain. */
 
238
  meh_p= *search_meh_pp;
 
239
  *search_meh_pp= meh_p->meh_next;
 
240
 
 
241
  /* Save the return value and free the header. */
 
242
  errmsgs= meh_p->meh_errmsgs;
 
243
  my_free((uchar*) meh_p, MYF(0));
 
244
  
 
245
  return errmsgs;
 
246
}
 
247
 
 
248
 
 
249
void my_error_unregister_all(void)
 
250
{
 
251
  struct my_err_head    *list, *next;
 
252
  for (list= my_errmsgs_globerrs.meh_next; list; list= next)
 
253
  {
 
254
    next= list->meh_next;
 
255
    my_free((uchar*) list, MYF(0));
 
256
  }
 
257
  my_errmsgs_list= &my_errmsgs_globerrs;
 
258
}