rework error to use a struct error_desc, and move ERR_SOCK/ERR_GNUTLS definitions to sock.h/sock_gnutls.h. error_desc definitions are still in error.c, though :(
authorTero Marttila <terom@fixme.fi>
Tue, 10 Mar 2009 03:27:04 +0200
changeset 30 7f8dd120933f
parent 29 3f0f2898fea3
child 31 98ea2bd59195
rework error to use a struct error_desc, and move ERR_SOCK/ERR_GNUTLS definitions to sock.h/sock_gnutls.h. error_desc definitions are still in error.c, though :(
src/error.c
src/error.h
src/sock.h
src/sock_gnutls.h
src/sock_tcp.c
src/sock_tcp.h
--- a/src/error.c	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/error.c	Tue Mar 10 03:27:04 2009 +0200
@@ -1,70 +1,127 @@
 
 #include "error.h"
 
+// for the error_desc tables
+#include "sock.h"
+#include "sock_gnutls.h"
+
 #include <string.h>
 #include <stdio.h>
 
-#include <netdb.h>
-#include <gnutls/gnutls.h>
+struct error_desc _core_error_desc[] = {
+    {   ERR_CALLOC,             "calloc",                       ERR_EXTRA_NONE  },
+    {   ERR_GETADDRINFO,        "getaddrinfo",                  ERR_EXTRA_GAI   },
+    {   ERR_GETADDRINFO_EMPTY,  "getaddrinfo: no results",      ERR_EXTRA_NONE  },
+    {   ERR_EVENT_NEW,          "event_new",                    ERR_EXTRA_NONE  },
+    {   ERR_EVENT_ADD,          "event_add",                    ERR_EXTRA_NONE  },
+    {   ERR_EVSQL_NEW_PQ,       "evsql_new_pq",                 ERR_EXTRA_NONE  },
+};
 
-/*
- * Helper macros
+struct error_desc _sock_error_desc[] = {
+    {   ERR_SOCKET,             "socket",           ERR_EXTRA_ERRNO },
+    {   ERR_CONNECT,            "connect",          ERR_EXTRA_ERRNO },
+    {   ERR_READ,               "read",             ERR_EXTRA_ERRNO },
+    {   ERR_READ_EOF,           "read: EOF",        ERR_EXTRA_NONE  },
+    {   ERR_WRITE,              "write",            ERR_EXTRA_ERRNO },
+    {   ERR_WRITE_EOF,          "write: EOF",       ERR_EXTRA_NONE  },
+    {   ERR_FCNTL,              "fcntl",            ERR_EXTRA_ERRNO },
+    {   ERR_CLOSE,              "close",            ERR_EXTRA_ERRNO },
+    {   _ERR_INVALID,           NULL,               0               }
+};
+
+struct error_desc _sock_gnutls_error_desc[] = {
+    {   ERR_GNUTLS_CERT_ALLOC_CRED,     "gnutls_certificate_allocate_credentials",  ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_GLOBAL_INIT,         "gnutls_global_init",                       ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_SET_DEFAULT_PRIORITY,"gnutls_set_default_priority",              ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_CRED_SET,            "gnutls_credentials_set",                   ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_HANDSHAKE,           "gnutls_handshake",                         ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_RECORD_SEND,         "gnutls_record_send",                       ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_RECORD_RECV,         "gnutls_record_recv",                       ERR_EXTRA_GNUTLS    },
+    {   ERR_GNUTLS_RECORD_GET_DIRECTION,"gnutls_record_get_direction",              ERR_EXTRA_GNUTLS    },
+    {   _ERR_INVALID,                   NULL,                                       0                   }
+};
+
+/**
+ * Array of error_desc tables
  */
-#define ERROR_NAME(code, name) case code: return name
+static struct error_desc* _desc_tables[] = {
+    _core_error_desc,
+    _sock_error_desc,
+    _sock_gnutls_error_desc,
+    NULL
+};
+
+/**
+ * Look up the error_desc for the given error code
+ */
+static const struct error_desc* error_lookup_desc (err_t code)
+{
+    struct error_desc **desc_table, *desc = NULL;
+
+    // iterate over each defined error_desc array
+    for (desc_table = _desc_tables; desc_table; desc_table++) {
+        for (desc = *desc_table; desc->code && desc->name; desc++) {
+            // compare code
+            if (desc->code == code)
+                // found
+                return desc;
+        }
+    }
+    
+    // not found
+    return NULL;    
+}
 
 const char *error_name (err_t code)
 {
-    switch (code) {
-        ERROR_NAME( ERR_CALLOC,                         "calloc"                                        );
-        ERROR_NAME( ERR_GETADDRINFO,                    "getaddrinfo"                                   );
-        ERROR_NAME( ERR_GETADDRINFO_EMPTY,              "getaddrinfo: no results"                       );
-        ERROR_NAME( ERR_SOCKET,                         "socket"                                        );
-        ERROR_NAME( ERR_CONNECT,                        "connect"                                       );
-        ERROR_NAME( ERR_READ,                           "read"                                          );
-        ERROR_NAME( ERR_READ_EOF,                       "read: EOF"                                     );
-        ERROR_NAME( ERR_WRITE,                          "write"                                         );
-        ERROR_NAME( ERR_FCNTL,                          "fcntl"                                         );
-        ERROR_NAME( ERR_GNUTLS_CERT_ALLOC_CRED,         "gnutls_certificate_allocate_credentials"       );
-        ERROR_NAME( ERR_GNUTLS_GLOBAL_INIT,             "gnutls_global_init"                            );
-        ERROR_NAME( ERR_GNUTLS_INIT,                    "gnutls_init"                                   );
-        ERROR_NAME( ERR_GNUTLS_SET_DEFAULT_PRIORITY,    "gnutls_set_default_priority"                   );
-        ERROR_NAME( ERR_GNUTLS_CRED_SET,                "gnutls_credentials_set"                        );
-        ERROR_NAME( ERR_GNUTLS_HANDSHAKE,               "gnutls_handshake"                              );
-        default: return "[unknown]";
-    }
+    const struct error_desc *desc;
+    
+    // do we have an error_desc for it?
+    if ((desc = error_lookup_desc(code)))
+        return desc->name;
+    else
+        // unknown
+        return "[unknown]";
 }
 
 const char *error_msg (const struct error_info *err)
 {
     static char msg[ERROR_MSG_MAXLEN];
-
-    // intrepret .extra
-    switch (err->code & _ERR_EXTRA_MASK) {
-        case ERR_EXTRA_NONE:
-            // no additional info
-            snprintf(msg, ERROR_MSG_MAXLEN, "%s", error_name(err->code));
-            break;
-        
-        case ERR_EXTRA_ERRNO:
-            // strerror
-            snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), strerror(err->extra));
-            break;
-        
-        case ERR_EXTRA_GAI:
-            // gai_strerror
-            snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gai_strerror(err->extra));
-            break;
-        
-        case ERR_EXTRA_GNUTLS:
-            // gnutls_strerror
-            snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gnutls_strerror(err->extra));
-            break;
-        
-        default:
-            // ???
-            snprintf(msg, ERROR_MSG_MAXLEN, "%s(%#.8x): %#.8x", error_name(err->code), err->code, err->extra);
-            break;
-    }   
+    const struct error_desc *desc;
+    
+    // do we have an error_desc for it?
+    if ((desc = error_lookup_desc(err->code)) == NULL)
+        // ???
+        snprintf(msg, ERROR_MSG_MAXLEN, "[%#.8x]: %#.8x", err->code, err->extra);
+    
+    else
+        // intrepret .extra
+        switch (desc->extra_type) {
+            case ERR_EXTRA_NONE:
+                // no additional info
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s", desc->name);
+                break;
+            
+            case ERR_EXTRA_ERRNO:
+                // strerror
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, strerror(err->extra));
+                break;
+            
+            case ERR_EXTRA_GAI:
+                // gai_strerror
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gai_strerror(err->extra));
+                break;
+            
+            case ERR_EXTRA_GNUTLS:
+                // gnutls_strerror
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra));
+                break;
+            
+            default:
+                // ???
+                snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra);
+                break;
+        }   
 
     // return static pointer
     return msg;
--- a/src/error.h	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/error.h	Tue Mar 10 03:27:04 2009 +0200
@@ -12,75 +12,74 @@
  */
 typedef unsigned int err_t;
 
-/*
- * Bitmask of error_info.extra meanings
+/**
+ * Ways to interpret error_info.extra
  */
 enum error_extra_types {
-    // bit offset of ERR_EXTRA_* mask in error_code
-    _ERR_EXTRA_OFFSET   = 3 * 8,
-    
-    // mask of bits used for the error_extra_types value
-    _ERR_EXTRA_MASK     = 0xff << _ERR_EXTRA_OFFSET,
+    ERR_EXTRA_NONE      = 0,
 
-    ERR_EXTRA_NONE      = 0x00 << _ERR_EXTRA_OFFSET,
-    ERR_EXTRA_ERRNO     = 0x01 << _ERR_EXTRA_OFFSET,
-    ERR_EXTRA_GAI       = 0x02 << _ERR_EXTRA_OFFSET,
-    ERR_EXTRA_GNUTLS    = 0x03 << _ERR_EXTRA_OFFSET,
-    
+    /** libc errno, using strerror() */
+    ERR_EXTRA_ERRNO,
+
+    /** libc resolver, using gai_strerror() */
+    ERR_EXTRA_GAI,
+
+    /** gnutls, using gnutls_strerror() */
+    ERR_EXTRA_GNUTLS,
 };
 
-
-#define _ERROR_CODE(name, code, extra) name = (code | ERR_EXTRA_ ## extra)
-/*
+/**
  * List of defined error codes, organized mostly by function name
  */
 enum error_code {
-    /* Core functions */
-    _ERROR_CODE( ERR_CALLOC,                        0x000100,   NONE    ),
+    _ERR_INVALID    = 0x000000,
     
-    /* Network resolver errors */
-    _ERROR_CODE( ERR_GETADDRINFO,                   0x000200,   GAI     ),
-    _ERROR_CODE( ERR_GETADDRINFO_EMPTY,             0x000201,   NONE    ),
-
-    /* Low-level network errors */
-    _ERROR_CODE( ERR_SOCKET,                        0x000301,   ERRNO   ),
-    _ERROR_CODE( ERR_CONNECT,                       0x000302,   ERRNO   ),
-
-    /* Low-level IO errors */
-    _ERROR_CODE( ERR_READ,                          0x000401,   ERRNO   ),
-    _ERROR_CODE( ERR_READ_EOF,                      0x000402,   NONE    ),
-    _ERROR_CODE( ERR_WRITE,                         0x000403,   ERRNO   ),
-    _ERROR_CODE( ERR_WRITE_EOF,                     0x000404,   NONE    ),
-    _ERROR_CODE( ERR_FCNTL,                         0x000405,   ERRNO   ),
-    _ERROR_CODE( ERR_CLOSE,                         0x000406,   ERRNO   ),
+    /** stdlib.h functions */
+    _ERR_STDLIB     = 0x000100,
+    ERR_CALLOC,
+    
+    /** DNS resolver */
+    _ERR_RESOLVER   = 0x000200,
+    ERR_GETADDRINFO,
+    ERR_GETADDRINFO_EMPTY, 
+    
+    /** @see enum sock_error_code*/
+    _ERR_SOCK       = 0x000300,
 
-    /* GnuTLS errors */
-    _ERROR_CODE( ERR_GNUTLS_CERT_ALLOC_CRED,        0x010101,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_GLOBAL_INIT,            0x010102,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_INIT,                   0x010103,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_SET_DEFAULT_PRIORITY,   0x010104,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_CRED_SET,               0x010105,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_HANDSHAKE,              0x010106,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_RECORD_SEND,            0x010107,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_RECORD_RECV,            0x010108,   GNUTLS  ),
-    _ERROR_CODE( ERR_GNUTLS_RECORD_GET_DIRECTION,   0x010109,   GNUTLS  ),
+    /** @see enum sock_gnutls_error_code */
+    _ERR_GNUTLS     = 0x000400,
 
-    /* Libevent errors */
-    _ERROR_CODE( ERR_EVENT_NEW,                     0x010201,   NONE    ),
-    _ERROR_CODE( ERR_EVENT_ADD,                     0x010202,   NONE    ),
+    /** Libevent errors */
+    _ERR_LIBEVENT   = 0x000500,
+    ERR_EVENT_NEW,
+    ERR_EVENT_ADD,
 
-    /* Evsql errors */
-    _ERROR_CODE( ERR_EVSQL_NEW_PQ,                  0x010301,   NONE    ),
+    /** Evsql errors */
+    _ERR_EVSQL      = 0x000600,
+    ERR_EVSQL_NEW_PQ,
 
-    /* irc_line errors */
-    _ERROR_CODE( ERR_LINE_TOO_LONG,                 0x100101,   NONE    ),
-    _ERROR_CODE( ERR_LINE_INVALID_TOKEN,            0x100102,   NONE    ),
+    /** irc_line errors */
+    _ERR_IRC_LINE   = 0x000700,
+    ERR_LINE_TOO_LONG,
+    ERR_LINE_INVALID_TOKEN,
 
     /** irc_conn errors */
-    _ERROR_CODE( ERR_IRC_CONN_REGISTER_STATE,       0x100201,   NONE    ),
-    
-    // mask of bits used for the error_code value
-    _ERROR_CODE_MASK    = 0xffffff,
+    _ERR_IRC_CONN   = 0x000800,
+    ERR_IRC_CONN_REGISTER_STATE,
+};
+
+/**
+ * Table of error descriptions
+ */
+struct error_desc {
+    /** The flat error code */
+    err_t code;
+
+    /** The short name */
+    const char *name;
+
+    /** How to interpret .extra */
+    enum error_extra_types extra_type;
 };
 
 /*
--- a/src/sock.h	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock.h	Tue Mar 10 03:27:04 2009 +0200
@@ -24,6 +24,34 @@
     void (*on_write)(struct sock_stream *sock, void *arg);
 };
 
+enum sock_error_code {
+    _ERR_SOCK_BEGIN = _ERR_SOCK,
+    
+    /** socket() error */
+    ERR_SOCKET,
+
+    /** connect() error */
+    ERR_CONNECT,
+
+    /** read() error */
+    ERR_READ,
+
+    /** EOF on read() */
+    ERR_READ_EOF,
+
+    /** write() error */
+    ERR_WRITE,
+
+    /** EOF on write()  */
+    ERR_WRITE_EOF,
+
+    /** Error on fcntl() */
+    ERR_FCNTL,
+
+    /** Lingering error on close() */
+    ERR_CLOSE,
+};
+
 /*
  * Initialize the socket module's global state. Call this before calling any other sock_* functions.
  *
--- a/src/sock_gnutls.h	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_gnutls.h	Tue Mar 10 03:27:04 2009 +0200
@@ -1,8 +1,10 @@
 #ifndef SOCK_GNUTLS_H
 #define SOCK_GNUTLS_H
 
-/*
- * A sock_stream implementation using GnuTLS
+/**
+ * @file
+ *
+ * A sock_stream implementation using GnuTLS for SSL
  */
 
 #include "sock_internal.h"
@@ -10,6 +12,23 @@
 
 #include <gnutls/gnutls.h>
 
+/**
+ * GnuTLS library error codes
+ */
+enum sock_gnutls_error_code {
+    _ERR_GNUTLS_BEGIN = _ERR_GNUTLS,
+    
+    ERR_GNUTLS_CERT_ALLOC_CRED,
+    ERR_GNUTLS_GLOBAL_INIT,
+    ERR_GNUTLS_INIT,
+    ERR_GNUTLS_SET_DEFAULT_PRIORITY,
+    ERR_GNUTLS_CRED_SET,
+    ERR_GNUTLS_HANDSHAKE,
+    ERR_GNUTLS_RECORD_SEND,
+    ERR_GNUTLS_RECORD_RECV,
+    ERR_GNUTLS_RECORD_GET_DIRECTION,   
+};
+
 /*
  * Additional gnutls configuration for client sockets.
  *
--- a/src/sock_tcp.c	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_tcp.c	Tue Mar 10 03:27:04 2009 +0200
@@ -4,7 +4,6 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <netdb.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <string.h>
--- a/src/sock_tcp.h	Tue Mar 10 02:51:44 2009 +0200
+++ b/src/sock_tcp.h	Tue Mar 10 03:27:04 2009 +0200
@@ -7,6 +7,7 @@
  * TCP implementation of sock_stream interface.
  */
 #include "sock_internal.h"
+#include <netdb.h>
 
 /**
  * Contains the base sock_stream struct, and the file descriptor