summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2010-10-20 21:03:04 +0100
committerLars Wirzenius <liw@liw.fi>2010-10-20 21:03:04 +0100
commit9ca4e13afe8a15fd08c761d92d4facfe49bbbbaf (patch)
treee28e5ef48e4b35462c65814c7f82575bf081a289
parent1945a17b30ef084d79a11f4954c85104748e074d (diff)
downloaddynstr-9ca4e13afe8a15fd08c761d92d4facfe49bbbbaf.tar.gz
Implement dynstr_new_empty, dynstr_len, and dynstr_is_empty.
-rw-r--r--dynstr.c56
-rw-r--r--unittests.c12
2 files changed, 67 insertions, 1 deletions
diff --git a/dynstr.c b/dynstr.c
index 3c78e5e..bd025f4 100644
--- a/dynstr.c
+++ b/dynstr.c
@@ -9,7 +9,7 @@
struct Dynstr {
- char *mem;
+ const char *mem;
size_t size;
bool dynamic;
};
@@ -42,3 +42,57 @@ void dynstr_malloc_error_abort(int error, size_t size, void *oldptr)
{
abort();
}
+
+/* Dynamically allocate a number of bytes. */
+static void *alloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+ if (p == NULL)
+ error_handler(errno, size, NULL);
+ return p;
+}
+
+/* Allocate a new dynamic string. If dynamic is true, the contents of the
+ * new string is copied from mem. Otherwise the new string just uses mem
+ * directly. */
+static Dynstr *new(const void *mem, size_t size, bool dynamic)
+{
+ Dynstr *dynstr;
+
+ dynstr = alloc(sizeof(Dynstr));
+ if (dynstr == NULL)
+ return NULL;
+ if (dynamic) {
+ void *newmem = alloc(size);
+ if (newmem == NULL) {
+ free(dynstr);
+ return NULL;
+ }
+ memcpy(newmem, mem, size);
+ dynstr->mem = newmem;
+ dynstr->size = size;
+ dynstr->dynamic = true;
+ } else {
+ dynstr->mem = mem;
+ dynstr->size = size;
+ dynstr->dynamic = false;
+ }
+ return dynstr;
+}
+
+Dynstr *dynstr_new_empty(void)
+{
+ return new(NULL, 0, true);
+}
+
+size_t dynstr_len(Dynstr *dynstr)
+{
+ return dynstr->size;
+}
+
+bool dynstr_is_empty(Dynstr *dynstr)
+{
+ return dynstr_len(dynstr) == 0;
+}
diff --git a/unittests.c b/unittests.c
index e0880d1..adb8e32 100644
--- a/unittests.c
+++ b/unittests.c
@@ -89,6 +89,17 @@ static int test_abort_handler_calls_abort(void)
}
+static int test_empty_string_is_empty(void)
+{
+ Dynstr *dynstr;
+
+ dynstr = dynstr_new_empty();
+ FAIL_UNLESS_EQUAL(dynstr_len(dynstr), 0);
+ FAIL_UNLESS_EQUAL(dynstr_is_empty(dynstr), true);
+ return true;
+}
+
+
struct test {
const char *name;
int (*test)(void);
@@ -102,6 +113,7 @@ static const struct test tests[] = {
TEST(test_sets_error_handler),
TEST(test_init_resets_error_handler),
TEST(test_abort_handler_calls_abort),
+ TEST(test_empty_string_is_empty),
};
static const int num_tests = sizeof(tests) / sizeof(tests[0]);