and then error_msg
authorTero Marttila <terom@fixme.fi>
Sun, 22 Feb 2009 07:53:34 +0200
changeset 7 844f014409ff
parent 6 240ae8482d64
child 8 be88e543c8ff
and then error_msg
src/error.c
src/error.h
src/nexus.c
--- a/src/error.c	Sun Feb 22 07:21:28 2009 +0200
+++ b/src/error.c	Sun Feb 22 07:53:34 2009 +0200
@@ -1,6 +1,12 @@
 
 #include "error.h"
 
+#include <string.h>
+#include <stdio.h>
+
+#include <netdb.h>
+#include <gnutls/gnutls.h>
+
 /*
  * Helper macros
  */
@@ -26,3 +32,39 @@
     }
 }
 
+const char *error_msg (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;
+    }   
+
+    // return static pointer
+    return msg;
+}
+
--- a/src/error.h	Sun Feb 22 07:21:28 2009 +0200
+++ b/src/error.h	Sun Feb 22 07:53:34 2009 +0200
@@ -13,31 +13,53 @@
 typedef unsigned int err_t;
 
 /*
+ * Bitmask of error_info.extra meanings
+ */
+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      = 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,
+    
+};
+
+
+#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 */
-    ERR_CALLOC                  = 0x000100,
+    _ERROR_CODE( ERR_CALLOC,                        0x000100,   NONE    ),
     
     /* Network resolver errors */
-    ERR_GETADDRINFO             = 0x000200,
-    ERR_GETADDRINFO_EMPTY       = 0x000201,     /* No valid results */
+    _ERROR_CODE( ERR_GETADDRINFO,                   0x000200,   GAI     ),
+    _ERROR_CODE( ERR_GETADDRINFO_EMPTY,             0x000201,   GAI     ),
 
     /* Low-level network errors */
-    ERR_SOCKET                  = 0x000301,
-    ERR_CONNECT                 = 0x000302,
+    _ERROR_CODE( ERR_SOCKET,                        0x000301,   ERRNO   ),
+    _ERROR_CODE( ERR_CONNECT,                       0x000302,   ERRNO   ),
 
     /* Low-level IO errors */
-    ERR_READ                    = 0x000401,
-    ERR_WRITE                   = 0x000402,
+    _ERROR_CODE( ERR_READ,                          0x000401,   ERRNO   ),
+    _ERROR_CODE( ERR_WRITE,                         0x000402,   ERRNO   ),
 
     /* GnuTLS errors */
-    ERR_GNUTLS_CERT_ALLOC_CRED  = 0x010101,
-    ERR_GNUTLS_GLOBAL_INIT      = 0x010102,
-    ERR_GNUTLS_INIT             = 0x010103,
-    ERR_GNUTLS_SET_DEFAULT_PRIORITY         = 0x010104,
-    ERR_GNUTLS_CRED_SET         = 0x010105,
-    ERR_GNUTLS_HANDSHAKE        = 0x010106,
+    _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  ),
+    
+    // mask of bits used for the error_code value
+    _ERROR_CODE_MASK    = 0xffffff,
 };
 
 /*
@@ -52,10 +74,22 @@
 };
 
 /*
- * Translate an err_t into a string.
+ * Translate an err_t into a function name.
  */
 const char *error_name (err_t code);
 
+/*
+ * Maximum length of error messages returned by error_msg (including NUL byte)
+ */
+#define ERROR_MSG_MAXLEN 1024
+
+/*
+ * Translate an error_info into a message.
+ *
+ * This is returned as a pointer into a statically allocated buffer. It is not re-entrant.
+ */
+const char *error_msg (struct error_info *err);
+
 /** No error, evaulates as logical false */
 #define SUCCESS (0)
 
--- a/src/nexus.c	Sun Feb 22 07:21:28 2009 +0200
+++ b/src/nexus.c	Sun Feb 22 07:53:34 2009 +0200
@@ -11,7 +11,7 @@
 #include "sock.h"
 
 #define CONNECT_HOST "irc.fixme.fi"
-#define CONNECT_SERV "6697"
+#define CONNECT_SERV "66976"
 #define LINE_LENGTH 512
 
 struct recvline_state {
@@ -112,13 +112,13 @@
 
     // initialize
     if (sock_init(&err))
-        errx(1, "sock_init: %s", error_name(ERROR_CODE(&err)));
+        errx(1, "sock_init: %s", error_msg(&err));
 
     memset(&recvline_ctx, 0, sizeof(recvline_ctx));
     
     // over-simplified connect
     if (sock_gnutls_connect(&sock, CONNECT_HOST, CONNECT_SERV, &err))
-        errx(1, "sock_gnutls_connect: %s", error_name(ERROR_CODE(&err)));
+        errx(1, "sock_gnutls_connect: %s", error_msg(&err));
 
     // read lines and dump them out
     do {