~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/my_error.cc

Merged from Monty

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