some fixes and some documentation

Wed, 17 Jul 2013 15:56:01 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 17 Jul 2013 15:56:01 +0200
changeset 116
234920008754
parent 115
965fd17ed9cf
child 117
ec0ae0c8854e

some fixes and some documentation

test/string_tests.c file | annotate | diff | comparison | revisions
ucx/map.c file | annotate | diff | comparison | revisions
ucx/mempool.c file | annotate | diff | comparison | revisions
ucx/properties.c file | annotate | diff | comparison | revisions
ucx/string.c file | annotate | diff | comparison | revisions
ucx/string.h file | annotate | diff | comparison | revisions
ucx/ucx.h file | annotate | diff | comparison | revisions
--- a/test/string_tests.c	Wed Jul 17 12:32:03 2013 +0200
+++ b/test/string_tests.c	Wed Jul 17 15:56:01 2013 +0200
@@ -41,9 +41,9 @@
 }
 
 UCX_TEST_IMPLEMENT(test_sstr_len_cat) {
-    sstr_t s1 = S("1234");
-    sstr_t s2 = S(".:.:.");
-    sstr_t s3 = S("X");
+    sstr_t s1 = ST("1234");
+    sstr_t s2 = ST(".:.:.");
+    sstr_t s3 = ST("X");
     
     size_t len = sstrnlen(3, s1, s2, s3);
     sstr_t cat;
@@ -72,7 +72,7 @@
 UCX_TEST_IMPLEMENT(test_sstrsplit) {
 
     const char *original = "this,is,a,csv,string";
-    sstr_t test = S("this,is,a,csv,string"); /* use copy of original here */
+    sstr_t test = ST("this,is,a,csv,string"); /* use copy of original here */
     size_t n;
     sstr_t *list;
 
@@ -80,12 +80,12 @@
 
     /* Nullpointer check */
     n = 0;
-    UCX_TEST_ASSERT(sstrsplit(test, ST(""), &n) == NULL,
+    UCX_TEST_ASSERT(sstrsplit(test, S(""), &n) == NULL,
             "empty delimiter must return NULL");
 
     /* no delimiter occurence (ndo) */
     n = 0;
-    list = sstrsplit(test, ST("z"), &n);
+    list = sstrsplit(test, S("z"), &n);
     UCX_TEST_ASSERT(n == 1, "ndo, list length must be 1");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, original) == 0, "ndo, "
             "original string shall be returned as single list element");
@@ -95,7 +95,7 @@
 
     /* partially matching delimiter (pmd) */
     n = 0;
-    list = sstrsplit(test, ST("stringbuilder"), &n);
+    list = sstrsplit(test, S("stringbuilder"), &n);
     UCX_TEST_ASSERT(n == 1, "pmd, list length must be 1");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, original) == 0, "pmd, "
             "original string shall be returned as single list element");
@@ -105,7 +105,7 @@
 
     /* matching single-char delimiter (mscd) */
     n = 0;
-    list = sstrsplit(test, ST(","), &n);
+    list = sstrsplit(test, S(","), &n);
     UCX_TEST_ASSERT(n == 5, "mscd, list length must be 5");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, "this") == 0, "mscd, item 0 mismatch");
     UCX_TEST_ASSERT(strcmp(list[1].ptr, "is") == 0, "mscd, item 1 mismatch");
@@ -118,7 +118,7 @@
 
     /* matching multi-char delimiter (mmcd) */
     n = 0;
-    list = sstrsplit(test, ST("is"), &n);
+    list = sstrsplit(test, S("is"), &n);
     UCX_TEST_ASSERT(n == 3, "mscd, list length must be 3");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, "th") == 0, "mmcd, item 0 mismatch");
     UCX_TEST_ASSERT(strcmp(list[1].ptr, ",") == 0, "mmcd, item 1 mismatch");
@@ -130,7 +130,7 @@
 
     /* bounded list using single-char delimiter (blsc) */
     n = 3;
-    list = sstrsplit(test, ST(","), &n);
+    list = sstrsplit(test, S(","), &n);
     UCX_TEST_ASSERT(n == 3, "blsc, list length must be 3");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, "this") == 0, "blsc, item 0 mismatch");
     UCX_TEST_ASSERT(strcmp(list[1].ptr, "is") == 0, "blsc, item 1 mismatch");
@@ -142,7 +142,7 @@
 
     /* bounded list using multi-char delimiter (blmc) */
     n = 2;
-    list = sstrsplit(test, ST("is"), &n);
+    list = sstrsplit(test, S("is"), &n);
     UCX_TEST_ASSERT(n == 2, "blmc, list length must be 2");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, "th") == 0, "blmc, item 0 mismatch");
     UCX_TEST_ASSERT(strcmp(list[1].ptr, ",is,a,csv,string") == 0,
@@ -153,7 +153,7 @@
 
     /* start with delimiter (swd) */
     n = 0;
-    list = sstrsplit(test, ST("this"), &n);
+    list = sstrsplit(test, S("this"), &n);
     UCX_TEST_ASSERT(n == 2, "swd, list length must be 2");
     UCX_TEST_ASSERT(list[0].length == 0, "swd, first item must be empty");
     UCX_TEST_ASSERT(strcmp(list[1].ptr, ",is,a,csv,string") == 0,
@@ -164,7 +164,7 @@
 
     /* end with delimiter (ewd) */
     n = 0;
-    list = sstrsplit(test, ST("string"), &n);
+    list = sstrsplit(test, S("string"), &n);
     UCX_TEST_ASSERT(n == 2, "ewd, list length must be 2");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, "this,is,a,csv,") == 0,
             "swd, first item corrupt");
@@ -175,14 +175,14 @@
 
     /* exact match (exm) */
     n = 0;
-    list = sstrsplit(test, ST("this,is,a,csv,string"), &n);
+    list = sstrsplit(test, S("this,is,a,csv,string"), &n);
     UCX_TEST_ASSERT(n == 0, "exm, list length must be 0");
     UCX_TEST_ASSERT(list == NULL, "exm, list must be NULL");
     free(list);
 
     /* substring (subs) */
     n = 0;
-    list = sstrsplit(test, ST("this,is,a,csv,string,with,extension"), &n);
+    list = sstrsplit(test, S("this,is,a,csv,string,with,extension"), &n);
     UCX_TEST_ASSERT(n == 1, "subs, list length must be 1");
     UCX_TEST_ASSERT(strcmp(list[0].ptr, original) == 0,
             "subs, single item must be the original string");
--- a/ucx/map.c	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/map.c	Wed Jul 17 15:56:01 2013 +0200
@@ -64,7 +64,7 @@
     return map;
 }
 
-void ucx_map_free_elmlist(UcxMap *map) {
+static void ucx_map_free_elmlist(UcxMap *map) {
     for (size_t n = 0 ; n < map->size ; n++) {
         UcxMapElement *elem = map->map[n];
         if (elem != NULL) {
--- a/ucx/mempool.c	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/mempool.c	Wed Jul 17 15:56:01 2013 +0200
@@ -112,7 +112,7 @@
                 return newm + sizeof(ucx_destructor);
             }
         }
-        fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
+        fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
           (intptr_t)ptr, (intptr_t)pool);
         exit(1);
     } else {
@@ -136,7 +136,7 @@
             return;
         }
     }
-    fprintf(stderr, "FATAL: 0x%08"PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
+    fprintf(stderr, "FATAL: 0x%08" PRIxPTR" not in mpool 0x%08" PRIxPTR"\n",
             (intptr_t)ptr, (intptr_t)pool);
     exit(1);
 }
--- a/ucx/properties.c	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/properties.c	Wed Jul 17 15:56:01 2013 +0200
@@ -199,17 +199,11 @@
     sstr_t name;
     sstr_t value;
     while(ucx_properties_next(parser, &name, &value)) {
-        name = sstrdup_alloc(map->allocator, name);
-        if(!name.ptr) {
-            return 1;
-        }
-        value = sstrdup_alloc(map->allocator, value);
+        value = sstrdupa(map->allocator, value);
         if(!value.ptr) {
-            map->allocator->free(map->allocator->pool, value.ptr);
             return 1;
         }
         if(ucx_map_sstr_put(map, name, value.ptr)) {
-            map->allocator->free(map->allocator->pool, name.ptr);
             map->allocator->free(map->allocator->pool, value.ptr);
             return 1;
         }
--- a/ucx/string.c	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/string.c	Wed Jul 17 15:56:01 2013 +0200
@@ -33,17 +33,17 @@
 #include "string.h"
 #include "allocator.h"
 
-sstr_t sstr(char *s) {
+sstr_t sstr(char *cstring) {
     sstr_t string;
-    string.ptr = s;
-    string.length = strlen(s);
+    string.ptr = cstring;
+    string.length = strlen(cstring);
     return string;
 }
 
-sstr_t sstrn(char *s, size_t n) {
+sstr_t sstrn(char *cstring, size_t length) {
     sstr_t string;
-    string.ptr = s;
-    string.length = n;
+    string.ptr = cstring;
+    string.length = length;
     return string;
 }
 
@@ -52,7 +52,7 @@
     size_t size = s.length;
     va_start(ap, s);
 
-    for (size_t i = 0 ; i < n-1 ; i++) {
+    for (size_t i = 1 ; i < n ; i++) {
         sstr_t str = va_arg(ap, sstr_t);
         size += str.length;
     }
@@ -175,25 +175,20 @@
 }
 
 int sstrcmp(sstr_t s1, sstr_t s2) {
-    return strncmp(s1.ptr, s2.ptr, s1.length>s2.length ? s2.length: s1.length);
+    if (s1.length == s2.length) {
+        return memcmp(s1.ptr, s2.ptr, s1.length);
+    } else if (s1.length > s2.length) {
+        return 1;
+    } else {
+        return -1;
+    }
 }
 
 sstr_t sstrdup(sstr_t s) {
-    sstr_t newstring;
-    newstring.ptr = (char*) malloc(s.length + 1);
-    if (newstring.ptr) {
-        newstring.length = s.length;
-        newstring.ptr[newstring.length] = 0;
-        
-        memcpy(newstring.ptr, s.ptr, s.length);
-    } else {
-        newstring.length = 0;
-    }
-    
-    return newstring;
+    return sstrdupa(ucx_default_allocator(), s);
 }
 
-sstr_t sstrdup_alloc(UcxAllocator *allocator, sstr_t s) {
+sstr_t sstrdupa(UcxAllocator *allocator, sstr_t s) {
     sstr_t newstring;
     newstring.ptr = (char*)allocator->malloc(allocator->pool, s.length + 1);
     if (newstring.ptr) {
--- a/ucx/string.h	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/string.h	Wed Jul 17 15:56:01 2013 +0200
@@ -25,51 +25,98 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+/**
+ * Bounded string implementation.
+ * 
+ * The UCX strings (<code>sstr_t</code>) provide an alternative to C strings.
+ * The main difference to C strings is, that <code>sstr_t</code> does <b>not
+ * need to be <code>NULL</code>-terminated</b>. Instead the length is stored
+ * within the structure.
+ * 
+ * When using <code>sstr_t</code>, developers must be full aware of what type
+ * of string (<code>NULL</code>-terminated) or not) they are using, when 
+ * accessing the <code>char* ptr</code> directly.
+ * 
+ * The UCX string module provides some common string functions, known from
+ * standard libc, working with <code>sstr_t</code>.
+ * 
+ * @file   string.h
+ * @author Mike Becker
+ * @author Olaf Wintermann
+ */
 
-#ifndef _SSTRING_H
-#define	_SSTRING_H
+#ifndef UCX_STRING_H
+#define	UCX_STRING_H
 
 #include "ucx.h"
 #include "allocator.h"
 #include <stddef.h>
 
-/* use macros for literals only */
-#define S(s) { (char*)s, sizeof(s)-1 }
-#define ST(s) sstrn((char*)s, sizeof(s)-1)
+/** Shortcut for a <code>sstr_t struct</code> literal. */
+#define ST(s) { (char*)s, sizeof(s)-1 }
+/** Shortcut for the conversion of a C string to a <code>sstr_t</code>. */
+#define S(s) sstrn((char*)s, sizeof(s)-1)
 
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
-typedef struct sstring {
+/**
+ * The UCX string structure.
+ */
+typedef struct {
+   /** A reference to the string (<b>not necessarily  <code>NULL</code>
+    * -terminated</b>) */
     char   *ptr;
+    /** The length of the string */
     size_t length;
 } sstr_t;
 
-/*
- * creates a new sstr_t from a null terminated string
+/**
+ * Creates a new sstr_t based on a C string.
+ * 
+ * The length is implicitly inferred by using a call to <code>strlen()</code>.
  *
- * s  null terminated string
+ * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you
+ * do want a copy, use sstrdup() on the return value of this function.
+ * 
+ * @param cstring the C string to wrap
+ * @return a new sstr_t containing the C string
+ * 
+ * @see sstrn()
  */
-sstr_t sstr(char *s);
+sstr_t sstr(char *cstring);
 
-/*
- * creates a new sstr_t from a string and length
+/**
+ * Creates a new sstr_t of the specified length based on a C string.
  *
- * s  string
- * n  length of string
+ * <b>Note:</b> the sstr_t will hold a <i>reference</i> to the C string. If you
+ * do want a copy, use sstrdup() on the return value of this function.
+ * 
+ * @param cstring  the C string to wrap
+ * @param length   the length of the string
+ * @return a new sstr_t containing the C string
+ * 
+ * @see sstr()
+ * @see S()
  */
-sstr_t sstrn(char *s, size_t n);
+sstr_t sstrn(char *cstring, size_t length);
 
 
-/*
- * gets the length of n sstr_t strings
+/**
+ * Returns the cumulated length of all specified strings.
  *
- * n    number of strings
- * s    string
- * ...  strings
+ * At least one string must be specified.
+ * 
+ * <b>Attention:</b> if the count argument does not match the count of the
+ * specified strings, the behavior is undefined.
+ *
+ * @param count    the total number of specified strings (so at least 1)
+ * @param string   the first string
+ * @param ...      all other strings
+ * @return the cumulated length of all strings
  */
-size_t sstrnlen(size_t n, sstr_t s, ...);
+size_t sstrnlen(size_t count, sstr_t string, ...);
 
 
 /*
@@ -115,10 +162,32 @@
  */
 sstr_t* sstrsplit(sstr_t s, sstr_t d, size_t *n);
 
+/**
+ * Compares two UCX strings with standard <code>memcmp()</code>.
+ * 
+ * At first it compares the sstr_t.length attribute of the two strings. The
+ * <code>memcmp()</code> function is called, if and only if the lengths match.
+ * 
+ * @param s1 the first string
+ * @param s2 the second string
+ * @return -1, if the length of s1 is less than the length of s2 or 1, if the 
+ * length of s1 is greater than the length of s2 or the result of
+ * <code>memcmp()</code> otherwise (i.e. 0 if the strings match)
+ */
 int sstrcmp(sstr_t s1, sstr_t s2);
 
-sstr_t sstrdup(sstr_t s);
-sstr_t sstrdup_alloc(UcxAllocator *allocator, sstr_t s);
+/**
+ * Creates a duplicate of the specified string.
+ * 
+ * The new sstr_t will contain a copy allocated by standard
+ * <code>malloc()</code>. So developers <b>MUST</b> pass the sstr_t.ptr to
+ * <code>free()</code>.
+ * 
+ * @param string the string to duplicate
+ * @return a duplicate of the argument
+ */
+sstr_t sstrdup(sstr_t string);
+sstr_t sstrdupa(UcxAllocator *allocator, sstr_t s);
 
 sstr_t sstrtrim(sstr_t string);
 
@@ -126,4 +195,4 @@
 }
 #endif
 
-#endif	/* _SSTRING_H */
+#endif	/* UCX_STRING_H */
--- a/ucx/ucx.h	Wed Jul 17 12:32:03 2013 +0200
+++ b/ucx/ucx.h	Wed Jul 17 15:56:01 2013 +0200
@@ -51,7 +51,6 @@
  * 
  * The first argument is the type of the list and its elements (e.g. UcxList).
  * The structure invariant of the list must be as follows:
- *
  * <ul>
  *   <li>a first (non-<code>NULL</code>) element</li>
  *   <li>for each element a reference to the <code>next</code> element (the
@@ -107,7 +106,8 @@
  * source and destination.
  * 
  * The arguments shall contain (in ascending order): a pointer to the source,
- * the length of one element, the element count, a pointer to the destination.
+ * the length of one element, the element count and a pointer to the
+ * destination.
  */
 typedef size_t(*write_func)(const void*, size_t, size_t, void*);
 
@@ -119,8 +119,8 @@
  * source and destination.
  * 
  * The arguments shall contain (in ascending order): a pointer to the
- * destination, the length of one element, the element count, a pointer to the
- * source.
+ * destination, the length of one element, the element count and a pointer to
+ * the source.
  */
 typedef size_t(*read_func)(void*, size_t, size_t, void*);
 

mercurial