~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/error.cc

Merged from Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
 
4
 *  Copyright (C) 2000 MySQL AB
4
5
 *  Copyright (C) 2008 Sun Microsystems
5
6
 *
6
7
 *  This program is free software; you can redistribute it and/or modify
23
24
 
24
25
#include "config.h"
25
26
#include "drizzled/internal/my_sys.h"
26
 
#include "drizzled/my_error.h"
27
 
#include <drizzled/definitions.h>
28
 
#include <drizzled/error.h>
29
 
#include <drizzled/gettext.h>
 
27
#include "drizzled/definitions.h"
 
28
#include "drizzled/error.h"
 
29
#include "drizzled/gettext.h"
30
30
 
31
31
namespace drizzled
32
32
{
1491
1491
  return(false);
1492
1492
}
1493
1493
 
 
1494
// -- From here has just been moved from my_error.cc
 
1495
 
 
1496
/* Error message numbers in global map */
 
1497
const char * globerrs[GLOBERRS];
 
1498
 
 
1499
error_handler_func error_handler_hook= NULL;
 
1500
 
 
1501
 
 
1502
void init_glob_errs()
 
1503
{
 
1504
  EE(EE_CANTCREATEFILE) = N_("Can't create/write to file '%s' (Errcode: %d)");
 
1505
  EE(EE_READ)           = N_("Error reading file '%s' (Errcode: %d)");
 
1506
  EE(EE_WRITE)          = N_("Error writing file '%s' (Errcode: %d)");
 
1507
  EE(EE_BADCLOSE)       = N_("Error on close of '%s' (Errcode: %d)");
 
1508
  EE(EE_OUTOFMEMORY)    = N_("Out of memory (Needed %u bytes)");
 
1509
  EE(EE_DELETE)         = N_("Error on delete of '%s' (Errcode: %d)");
 
1510
  EE(EE_LINK)           = N_("Error on rename of '%s' to '%s' (Errcode: %d)");
 
1511
  EE(EE_EOFERR)         = N_("Unexpected eof found when reading file '%s' (Errcode: %d)");
 
1512
  EE(EE_CANTLOCK)       = N_("Can't lock file (Errcode: %d)");
 
1513
  EE(EE_CANTUNLOCK)     = N_("Can't unlock file (Errcode: %d)");
 
1514
  EE(EE_DIR)            = N_("Can't read dir of '%s' (Errcode: %d)");
 
1515
  EE(EE_STAT)           = N_("Can't get stat of '%s' (Errcode: %d)");
 
1516
  EE(EE_CANT_CHSIZE)    = N_("Can't change size of file (Errcode: %d)");
 
1517
  EE(EE_CANT_OPEN_STREAM)= N_("Can't open stream from handle (Errcode: %d)");
 
1518
  EE(EE_GETWD)          = N_("Can't get working dirctory (Errcode: %d)");
 
1519
  EE(EE_SETWD)          = N_("Can't change dir to '%s' (Errcode: %d)");
 
1520
  EE(EE_LINK_WARNING)   = N_("Warning: '%s' had %d links");
 
1521
  EE(EE_OPEN_WARNING)   = N_("Warning: %d files and %d streams is left open\n");
 
1522
  EE(EE_DISK_FULL)      = N_("Disk is full writing '%s'. Waiting for someone to free space...");
 
1523
  EE(EE_CANT_MKDIR)     = N_("Can't create directory '%s' (Errcode: %d)");
 
1524
  EE(EE_UNKNOWN_CHARSET)= N_("Character set '%s' is not a compiled character set and is not specified in the %s file");
 
1525
  EE(EE_OUT_OF_FILERESOURCES)= N_("Out of resources when opening file '%s' (Errcode: %d)");
 
1526
  EE(EE_CANT_READLINK)= N_("Can't read value for symlink '%s' (Error %d)");
 
1527
  EE(EE_CANT_SYMLINK)= N_("Can't create symlink '%s' pointing at '%s' (Error %d)");
 
1528
  EE(EE_REALPATH)= N_("Error on realpath() on '%s' (Error %d)");
 
1529
  EE(EE_SYNC)=   N_("Can't sync file '%s' to disk (Errcode: %d)");
 
1530
  EE(EE_UNKNOWN_COLLATION)= N_("Collation '%s' is not a compiled collation and is not specified in the %s file");
 
1531
  EE(EE_FILENOTFOUND)   = N_("File '%s' not found (Errcode: %d)");
 
1532
  EE(EE_FILE_NOT_CLOSED) = N_("File '%s' (fileno: %d) was not closed");
 
1533
}
 
1534
 
 
1535
/*
 
1536
  WARNING!
 
1537
  my_error family functions have to be used according following rules:
 
1538
  - if message have not parameters use my_message(ER_CODE, ER(ER_CODE), MYF(N))
 
1539
  - if message registered use my_error(ER_CODE, MYF(N), ...).
 
1540
  - With some special text of errror message use:
 
1541
  my_printf_error(ER_CODE, format, MYF(N), ...)
 
1542
*/
 
1543
 
 
1544
/*
 
1545
  Message texts are registered into a linked list of 'my_err_head' structs.
 
1546
  Each struct contains (1.) an array of pointers to C character strings with
 
1547
  '\0' termination, (2.) the error number for the first message in the array
 
1548
  (array index 0) and (3.) the error number for the last message in the array
 
1549
  (array index (last - first)).
 
1550
  The array may contain gaps with NULL pointers and pointers to empty strings.
 
1551
  Both kinds of gaps will be translated to "Unknown error %d.", if my_error()
 
1552
  is called with a respective error number.
 
1553
  The list of header structs is sorted in increasing order of error numbers.
 
1554
  Negative error numbers are allowed. Overlap of error numbers is not allowed.
 
1555
  Not registered error numbers will be translated to "Unknown error %d.".
 
1556
*/
 
1557
static struct my_err_head
 
1558
{
 
1559
  struct my_err_head    *meh_next;      /* chain link */
 
1560
  const char            **meh_errmsgs;  /* error messages array */
 
1561
  int                   meh_first;      /* error number matching array slot 0 */
 
1562
  int                   meh_last;       /* error number matching last slot */
 
1563
  bool                  is_globerrs;
 
1564
} my_errmsgs_globerrs = {NULL, globerrs, EE_ERROR_FIRST, EE_ERROR_LAST, true};
 
1565
 
 
1566
static struct my_err_head *my_errmsgs_list= &my_errmsgs_globerrs;
 
1567
 
 
1568
 
 
1569
/*
 
1570
   Error message to user
 
1571
 
 
1572
   SYNOPSIS
 
1573
     my_error()
 
1574
       nr       Errno
 
1575
       MyFlags  Flags
 
1576
       ...      variable list
 
1577
*/
 
1578
 
 
1579
void my_error(int nr, myf MyFlags, ...)
 
1580
{
 
1581
  const char *format;
 
1582
  struct my_err_head *meh_p;
 
1583
  va_list args;
 
1584
  char ebuff[ERRMSGSIZE + 20];
 
1585
 
 
1586
  /* Search for the error messages array, which could contain the message. */
 
1587
  for (meh_p= my_errmsgs_list; meh_p; meh_p= meh_p->meh_next)
 
1588
    if (nr <= meh_p->meh_last)
 
1589
      break;
 
1590
 
 
1591
  /* get the error message string. Default, if NULL or empty string (""). */
 
1592
  if (! (format= (meh_p && (nr >= meh_p->meh_first)) ?
 
1593
         _(meh_p->meh_errmsgs[nr - meh_p->meh_first]) : NULL) || ! *format)
 
1594
    (void) snprintf (ebuff, sizeof(ebuff), _("Unknown error %d"), nr);
 
1595
  else
 
1596
  {
 
1597
    va_start(args,MyFlags);
 
1598
    (void) vsnprintf (ebuff, sizeof(ebuff), format, args);
 
1599
    va_end(args);
 
1600
  }
 
1601
  (*error_handler_hook)(nr, ebuff, MyFlags);
 
1602
  return;
 
1603
}
 
1604
 
 
1605
 
 
1606
/*
 
1607
  Error as printf
 
1608
 
 
1609
         SYNOPSIS
 
1610
    my_printf_error()
 
1611
      error     Errno
 
1612
      format    Format string
 
1613
      MyFlags   Flags
 
1614
      ...       variable list
 
1615
*/
 
1616
 
 
1617
void my_printf_error(uint32_t error, const char *format, myf MyFlags, ...)
 
1618
{
 
1619
  va_list args;
 
1620
  char ebuff[ERRMSGSIZE+20];
 
1621
 
 
1622
  va_start(args,MyFlags);
 
1623
  (void) vsnprintf (ebuff, sizeof(ebuff), format, args);
 
1624
  va_end(args);
 
1625
  (*error_handler_hook)(error, ebuff, MyFlags);
 
1626
  return;
 
1627
}
 
1628
 
 
1629
/*
 
1630
  Give message using error_handler_hook
 
1631
 
 
1632
  SYNOPSIS
 
1633
    my_message()
 
1634
      error     Errno
 
1635
      str       Error message
 
1636
      MyFlags   Flags
 
1637
*/
 
1638
 
 
1639
void my_message(uint32_t error, const char *str, register myf MyFlags)
 
1640
{
 
1641
  (*error_handler_hook)(error, str, MyFlags);
 
1642
}
 
1643
 
 
1644
 
 
1645
/*
 
1646
  Register error messages for use with my_error().
 
1647
 
 
1648
  SYNOPSIS
 
1649
    my_error_register()
 
1650
    errmsgs                     array of pointers to error messages
 
1651
    first                       error number of first message in the array
 
1652
    last                        error number of last message in the array
 
1653
 
 
1654
  DESCRIPTION
 
1655
    The pointer array is expected to contain addresses to NUL-terminated
 
1656
    C character strings. The array contains (last - first + 1) pointers.
 
1657
    NULL pointers and empty strings ("") are allowed. These will be mapped to
 
1658
    "Unknown error" when my_error() is called with a matching error number.
 
1659
    This function registers the error numbers 'first' to 'last'.
 
1660
    No overlapping with previously registered error numbers is allowed.
 
1661
 
 
1662
  RETURN
 
1663
    0           OK
 
1664
    != 0        Error
 
1665
*/
 
1666
 
 
1667
int my_error_register(const char **errmsgs, int first, int last)
 
1668
{
 
1669
  struct my_err_head *meh_p;
 
1670
  struct my_err_head **search_meh_pp;
 
1671
 
 
1672
  /* Allocate a new header structure. */
 
1673
  if (! (meh_p= (struct my_err_head*) malloc(sizeof(struct my_err_head))))
 
1674
    return 1;
 
1675
  meh_p->meh_errmsgs= errmsgs;
 
1676
  meh_p->meh_first= first;
 
1677
  meh_p->meh_last= last;
 
1678
  meh_p->is_globerrs= false;
 
1679
 
 
1680
  /* Search for the right position in the list. */
 
1681
  for (search_meh_pp= &my_errmsgs_list;
 
1682
       *search_meh_pp;
 
1683
       search_meh_pp= &(*search_meh_pp)->meh_next)
 
1684
  {
 
1685
    if ((*search_meh_pp)->meh_last > first)
 
1686
      break;
 
1687
  }
 
1688
 
 
1689
  /* Error numbers must be unique. No overlapping is allowed. */
 
1690
  if (*search_meh_pp && ((*search_meh_pp)->meh_first <= last))
 
1691
  {
 
1692
    free((unsigned char*)meh_p);
 
1693
    return 1;
 
1694
  }
 
1695
 
 
1696
  /* Insert header into the chain. */
 
1697
  meh_p->meh_next= *search_meh_pp;
 
1698
  *search_meh_pp= meh_p;
 
1699
  return 0;
 
1700
}
 
1701
 
 
1702
 
 
1703
/*
 
1704
  Unregister formerly registered error messages.
 
1705
 
 
1706
  SYNOPSIS
 
1707
    my_error_unregister()
 
1708
    first                       error number of first message
 
1709
    last                        error number of last message
 
1710
 
 
1711
  DESCRIPTION
 
1712
    This function unregisters the error numbers 'first' to 'last'.
 
1713
    These must have been previously registered by my_error_register().
 
1714
    'first' and 'last' must exactly match the registration.
 
1715
    If a matching registration is present, the header is removed from the
 
1716
    list and the pointer to the error messages pointers array is returned.
 
1717
    Otherwise, NULL is returned.
 
1718
 
 
1719
  RETURN
 
1720
    non-NULL    OK, returns address of error messages pointers array.
 
1721
    NULL        Error, no such number range registered.
 
1722
*/
 
1723
 
 
1724
const char **my_error_unregister(int first, int last)
 
1725
{
 
1726
  struct my_err_head    *meh_p;
 
1727
  struct my_err_head    **search_meh_pp;
 
1728
  const char            **errmsgs;
 
1729
 
 
1730
  /* Search for the registration in the list. */
 
1731
  for (search_meh_pp= &my_errmsgs_list;
 
1732
       *search_meh_pp;
 
1733
       search_meh_pp= &(*search_meh_pp)->meh_next)
 
1734
  {
 
1735
    if (((*search_meh_pp)->meh_first == first) &&
 
1736
        ((*search_meh_pp)->meh_last == last))
 
1737
      break;
 
1738
  }
 
1739
  if (! *search_meh_pp)
 
1740
    return NULL;
 
1741
 
 
1742
  /* Remove header from the chain. */
 
1743
  meh_p= *search_meh_pp;
 
1744
  *search_meh_pp= meh_p->meh_next;
 
1745
 
 
1746
  /* Save the return value and free the header. */
 
1747
  errmsgs= meh_p->meh_errmsgs;
 
1748
  bool is_globerrs= meh_p->is_globerrs;
 
1749
 
 
1750
  free((unsigned char*) meh_p);
 
1751
 
 
1752
  if (is_globerrs)
 
1753
    return NULL;
 
1754
 
 
1755
  return errmsgs;
 
1756
}
 
1757
 
 
1758
 
 
1759
void my_error_unregister_all(void)
 
1760
{
 
1761
  struct my_err_head    *list, *next;
 
1762
  for (list= my_errmsgs_globerrs.meh_next; list; list= next)
 
1763
  {
 
1764
    next= list->meh_next;
 
1765
    free((unsigned char*) list);
 
1766
  }
 
1767
  my_errmsgs_list= &my_errmsgs_globerrs;
 
1768
}
 
1769
 
1494
1770
} /* namespace drizzled */