add dump_str function to test
authorTero Marttila <terom@fixme.fi>
Fri, 13 Mar 2009 14:59:38 +0200
changeset 50 46c3983638d3
parent 49 96e0f703a58c
child 51 cc61eaa841ef
add dump_str function to test
src/test.c
--- a/src/test.c	Fri Mar 13 00:01:12 2009 +0200
+++ b/src/test.c	Fri Mar 13 14:59:38 2009 +0200
@@ -11,29 +11,115 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <ctype.h>
+
+#define DUMP_STR_BUF 1024
+#define DUMP_STR_COUNT 8
+#define DUMP_STR_TAIL 10
+
+char *dump_str_append (char *buf, const char *str)
+{
+    while (*str)
+        *buf++ = *str++;
+
+    return buf;
+}
+
+/**
+ * This re-formats the given string to escape values, and returns a pointer to an internal static buffer.
+ *
+ * If len is given as >= 0, only the given number of chars will be dumped from str
+ *
+ * The buffer cycles a bit, so you pointers remain valid across DUMP_STR_COUNT calls.
+ */
+const char *dump_strn (const char *str, ssize_t len)
+{
+    static char dump_buf[DUMP_STR_COUNT][DUMP_STR_BUF];
+    static size_t dump_idx = 0;
+    
+    // pick a buffer to use
+    const char *str_ptr = str;
+    char *buf_ptr = dump_buf[dump_idx++], *buf = buf_ptr;
+    
+    // cycle
+    if (dump_idx >= DUMP_STR_COUNT)
+        dump_idx = 0;
+
+    // NULL?
+    if (str == NULL) {
+        buf = dump_str_append(buf, "NULL");
+        *buf = '\0';
+
+        return buf_ptr;
+    }
+
+    // quote
+    *buf++ = '\'';
+    
+    // dump each char
+    for (; *str && (size_t) (buf - buf_ptr) < DUMP_STR_BUF - DUMP_STR_TAIL && (len < 0 || (size_t) (str - str_ptr) < (size_t) len); str++) {
+        if (*str == '\'') {
+            buf = dump_str_append(buf, "\\'"); break;
+
+        } else if (isprint(*str)) {
+            *buf++ = *str;
+
+        } else {
+            switch (*str) {
+                case '\r':
+                    buf = dump_str_append(buf, "\\r"); break;
+
+                case '\n':
+                    buf = dump_str_append(buf, "\\n"); break;
+
+                default:
+                    buf += snprintf(buf, (DUMP_STR_BUF - (buf - buf_ptr)), "\\x%02x", *str);
+                    break;
+            }
+        }
+    }
+
+    // quote
+    *buf++ = '\'';
+
+    // overflow?
+    if ((size_t)(buf - buf_ptr) == DUMP_STR_BUF - DUMP_STR_TAIL)
+        buf = dump_str_append(buf, "...");
+
+    // terminate
+    *buf = '\0';
+
+    // ok
+    return buf_ptr;
+}
+
+const char *dump_str (const char *str) 
+{
+    return dump_strn(str, -1);
+}
 
 void assert_strcmp (const char *is, const char *should_be)
 {
     if (strcmp(is, should_be))
-        FATAL("'%s' != '%s'", is, should_be);
+        FATAL("%s != %s", dump_str(is), dump_str(should_be));
 }
 
 void assert_strncmp (const char *is, const char *should_be, size_t n)
-{
+{   
     if (strncmp(is, should_be, n))
-        FATAL("'%s':%u != '%s'", is, (unsigned) n, should_be);
+        FATAL("%s:%u != %s", dump_strn(is, n), (unsigned) n, dump_strn(should_be, n));
 }
 
 void assert_strlen (const char *str, size_t n)
 {
     if (strlen(str) != n)
-        FATAL("strlen('%s') != %u", str, (unsigned) n);
+        FATAL("strlen(%s) != %u", dump_str(str), (unsigned) n);
 }
 
 void assert_strnull (const char *str)
 {
     if (str != NULL)
-        FATAL("'%s' != NULL", str);
+        FATAL("%s != NULL", dump_str(str));
 }
 
 void assert_success (err_t err)
@@ -59,7 +145,7 @@
 {
     char buf[strlen(str)];
 
-    log_debug("read: %p: '%s'", sock, str);
+    log_debug("read: %p: %s", sock, dump_str(str));
     
     // read it
     assert(sock_stream_read(sock, buf, strlen(str)) == (int) strlen(str));
@@ -70,7 +156,7 @@
 
 void assert_sock_write (struct sock_stream *sock, const char *str)
 {
-    log_debug("write: %p: '%s'", sock, str);
+    log_debug("write: %p: %s", sock, dump_str(str));
 
     // write it
     assert(sock_stream_write(sock, str, strlen(str)) == (int) strlen(str));
@@ -93,7 +179,7 @@
     
     sock_test_get_send_data(sock, &buf, &len);
     
-    log_debug("get_send_data: '%.*s'", (int) len, buf);
+    log_debug("get_send_data: %s", dump_strn(buf, len));
     
     // should be the same
     assert_strncmp(buf, data, len);
@@ -103,6 +189,17 @@
     free(buf);
 }
 
+void test_dump_str (void)
+{
+    log_info("dumping example strings on stdout:");
+
+    log_debug("normal: %s", dump_str("Hello World"));
+    log_debug("escapes: %s", dump_str("foo\r\nbar\a\001"));
+    log_debug("length: %s", dump_strn("<-->**", 4));
+    log_debug("overflow: %s", dump_str( "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
+    log_debug("null: %s", dump_str(NULL));
+}
+
 void test_sock_test (void)
 {
     struct sock_test *sock = sock_test_create();
@@ -144,7 +241,7 @@
 {
     char *line_buf;
     
-    log_debug("expect: '%s'", line_str);
+    log_debug("expect: %s", dump_str(line_str));
 
     assert_success(line_proto_recv(lp, &line_buf));
 
@@ -173,7 +270,7 @@
 {
     struct _lp_test_ctx *ctx = arg;
 
-    log_debug("'%s'", line);
+    log_debug("%s", dump_str(line));
 
     assert_strcmp(line, ctx->line);
 
@@ -461,6 +558,7 @@
     void (*func) (void);
 
 } _tests[] = {
+    {   "dump_str",     &test_dump_str      },
     {   "sock_test",    &test_sock_test     },
     {   "line_proto",   &test_line_proto    },
     {   "irc_conn",     &test_irc_conn      },