aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2015-04-15 12:56:54 -0300
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2015-04-15 12:56:54 -0300
commit0b694d89cefae8e8ca3422bbdbfbca4d5920ac4b (patch)
tree212c4d2ac7e269cc9f03f2240e36f865d4ce2493 /src
parenta8e0fedb3f12ed1ceda7879944606c8e1e7d4a08 (diff)
downloadblogc-0b694d89cefae8e8ca3422bbdbfbca4d5920ac4b.tar.gz
blogc-0b694d89cefae8e8ca3422bbdbfbca4d5920ac4b.tar.bz2
blogc-0b694d89cefae8e8ca3422bbdbfbca4d5920ac4b.zip
initial structure
Diffstat (limited to 'src')
-rw-r--r--src/main.c21
-rw-r--r--src/utils/slist.c64
-rw-r--r--src/utils/strings.c277
-rw-r--r--src/utils/trie.c193
-rw-r--r--src/utils/utils.h71
5 files changed, 626 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..f989f62
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,21 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file COPYING.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+
+
+int
+main(int argc, char **argv)
+{
+ printf("Hello, World!\n");
+ return 0;
+}
diff --git a/src/utils/slist.c b/src/utils/slist.c
new file mode 100644
index 0000000..e0c1a44
--- /dev/null
+++ b/src/utils/slist.c
@@ -0,0 +1,64 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2015 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file COPYING.
+ */
+
+#include <stdlib.h>
+#include "utils.h"
+
+
+b_slist_t*
+b_slist_append(b_slist_t *l, void *data)
+{
+ b_slist_t *node = malloc(sizeof(b_slist_t));
+ if (node == NULL) {
+ l = NULL;
+ return l;
+ }
+ node->data = data;
+ node->next = NULL;
+ if (l == NULL)
+ l = node;
+ else {
+ b_slist_t *tmp;
+ for (tmp = l; tmp->next != NULL; tmp = tmp->next);
+ tmp->next = node;
+ }
+ return l;
+}
+
+
+void
+b_slist_free_full(b_slist_t *l, void (*free_func)(void *ptr))
+{
+ while (l != NULL) {
+ b_slist_t *tmp = l->next;
+ free_func(l->data);
+ free(l);
+ l = tmp;
+ }
+}
+
+
+void
+b_slist_free(b_slist_t *l)
+{
+ while (l != NULL) {
+ b_slist_t *tmp = l->next;
+ free(l);
+ l = tmp;
+ }
+}
+
+
+unsigned int
+b_slist_length(b_slist_t *l)
+{
+ unsigned int i;
+ b_slist_t *tmp;
+ for (tmp = l, i = 0; tmp != NULL; tmp = tmp->next, i++);
+ return i;
+}
diff --git a/src/utils/strings.c b/src/utils/strings.c
new file mode 100644
index 0000000..b3a19cc
--- /dev/null
+++ b/src/utils/strings.c
@@ -0,0 +1,277 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2015 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file COPYING.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+
+char*
+b_strdup(const char *s)
+{
+ if (s == NULL)
+ return NULL;
+ size_t l = strlen(s);
+ char *tmp = malloc(l + 1);
+ if (tmp == NULL)
+ return NULL;
+ memcpy(tmp, s, l + 1);
+ return tmp;
+}
+
+
+char*
+b_strndup(const char *s, size_t n)
+{
+ if (s == NULL)
+ return NULL;
+ size_t l = strnlen(s, n);
+ char *tmp = malloc(l + 1);
+ if (tmp == NULL)
+ return NULL;
+ memcpy(tmp, s, l);
+ tmp[l] = '\0';
+ return tmp;
+}
+
+
+char*
+b_strdup_vprintf(const char *format, va_list ap)
+{
+ va_list ap2;
+ va_copy(ap2, ap);
+ int l = vsnprintf(NULL, 0, format, ap2);
+ va_end(ap2);
+ if (l < 0)
+ return NULL;
+ char *tmp = malloc(l + 1);
+ if (!tmp)
+ return NULL;
+ int l2 = vsnprintf(tmp, l + 1, format, ap);
+ if (l2 < 0)
+ return NULL;
+ return tmp;
+}
+
+
+char*
+b_strdup_printf(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ char *tmp = b_strdup_vprintf(format, ap);
+ va_end(ap);
+ return tmp;
+}
+
+
+bool
+b_str_starts_with(const char *str, const char *prefix)
+{
+ int str_l = strlen(str);
+ int str_lp = strlen(prefix);
+ if (str_lp > str_l)
+ return false;
+ return strncmp(str, prefix, str_lp) == 0;
+}
+
+
+bool
+b_str_ends_with(const char *str, const char *suffix)
+{
+ int str_l = strlen(str);
+ int str_ls = strlen(suffix);
+ if (str_ls > str_l)
+ return false;
+ return strcmp(str + str_l - str_ls, suffix) == 0;
+}
+
+
+char*
+b_str_strip(char *str)
+{
+ if (str == NULL)
+ return str;
+ int i;
+ size_t str_len = strlen(str);
+ for (i = str_len - 1; i >= 0; i--) {
+ if (!isspace(str[i])) {
+ str[i + 1] = '\0';
+ break;
+ }
+ }
+ str_len = strlen(str);
+ for (i = 0; i < str_len; i++) {
+ if (!isspace(str[i])) {
+ str = str + i;
+ break;
+ }
+ }
+ return str;
+}
+
+
+char**
+b_str_split(const char *str, char c, unsigned int max_pieces)
+{
+ if (!str)
+ return NULL;
+ char **rv = malloc(sizeof(char*));
+ unsigned int i, start = 0, count = 0;
+ for (i = 0; i < strlen(str) + 1; i++) {
+ if (str[0] == '\0')
+ break;
+ if ((str[i] == c && (!max_pieces || count + 1 < max_pieces)) || str[i] == '\0') {
+ rv = realloc(rv, (count + 1) * sizeof(char*));
+ rv[count] = malloc(i - start + 1);
+ memcpy(rv[count], str + start, i - start);
+ rv[count++][i - start] = '\0';
+ start = i + 1;
+ }
+ }
+ rv = realloc(rv, (count + 1) * sizeof(char*));
+ rv[count] = NULL;
+ return rv;
+}
+
+
+char*
+b_str_replace(const char *str, const char search, const char *replace)
+{
+ char **pieces = b_str_split(str, search, 0);
+ if (pieces == NULL)
+ return NULL;
+ char* rv = b_strv_join((const char**) pieces, replace);
+ b_strv_free(pieces);
+ return rv;
+}
+
+
+void
+b_strv_free(char **strv)
+{
+ if (strv == NULL)
+ return;
+ unsigned int i;
+ for (i = 0; strv[i] != NULL; i++)
+ free(strv[i]);
+ free(strv);
+}
+
+
+char*
+b_strv_join(const char **strv, const char *separator)
+{
+ if (strv == NULL)
+ return NULL;
+ unsigned int i = 0;
+ b_string_t *str = b_string_new();
+ for (i = 0; strv[i] != NULL; i++) {
+ str = b_string_append(str, strv[i]);
+ if (strv[i+1] != NULL)
+ str = b_string_append(str, separator);
+ }
+ return b_string_free(str, false);
+}
+
+
+unsigned int
+b_strv_length(char **strv)
+{
+ if (!strv)
+ return 0;
+ unsigned int i;
+ for (i = 0; strv[i] != NULL; i++);
+ return i;
+}
+
+
+b_string_t*
+b_string_new(void)
+{
+ b_string_t* rv = malloc(sizeof(b_string_t));
+ rv->str = NULL;
+ rv->len = 0;
+ rv->allocated_len = 0;
+
+ // initialize with empty string
+ rv = b_string_append(rv, "");
+
+ return rv;
+}
+
+
+char*
+b_string_free(b_string_t *str, bool free_str)
+{
+ char *rv = NULL;
+ if (free_str)
+ free(str->str);
+ else
+ rv = str->str;
+ free(str);
+ return rv;
+}
+
+
+b_string_t*
+b_string_append_len(b_string_t *str, const char *suffix, size_t len)
+{
+ if (suffix == NULL)
+ return str;
+ size_t old_len = str->len;
+ str->len += len;
+ if (str->len + 1 > str->allocated_len) {
+ str->allocated_len = (((str->len + 1) / B_STRING_CHUNK_SIZE) + 1) * B_STRING_CHUNK_SIZE;
+ str->str = realloc(str->str, str->allocated_len);
+ }
+ memcpy(str->str + old_len, suffix, len);
+ str->str[str->len] = '\0';
+ return str;
+}
+
+
+b_string_t*
+b_string_append(b_string_t *str, const char *suffix)
+{
+ if (suffix == NULL)
+ return str;
+ return b_string_append_len(str, suffix, strlen(suffix));
+}
+
+
+b_string_t*
+b_string_append_c(b_string_t *str, char c)
+{
+ size_t old_len = str->len;
+ str->len += 1;
+ if (str->len + 1 > str->allocated_len) {
+ str->allocated_len = (((str->len + 1) / B_STRING_CHUNK_SIZE) + 1) * B_STRING_CHUNK_SIZE;
+ str->str = realloc(str->str, str->allocated_len);
+ }
+ str->str[old_len] = c;
+ str->str[str->len] = '\0';
+ return str;
+}
+
+
+b_string_t*
+b_string_append_printf(b_string_t *str, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ char *tmp = b_strdup_vprintf(format, ap);
+ va_end(ap);
+ str = b_string_append(str, tmp);
+ free(tmp);
+ return str;
+}
diff --git a/src/utils/trie.c b/src/utils/trie.c
new file mode 100644
index 0000000..f447860
--- /dev/null
+++ b/src/utils/trie.c
@@ -0,0 +1,193 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2015 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file COPYING.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "utils.h"
+
+
+b_trie_t*
+b_trie_new(void (*free_func)(void *ptr))
+{
+ b_trie_t *trie = malloc(sizeof(b_trie_t));
+ trie->root = NULL;
+ trie->free_func = free_func;
+ return trie;
+}
+
+
+static void
+b_trie_free_node(b_trie_t *trie, b_trie_node_t *node)
+{
+ if (node == NULL)
+ return;
+ if (node->data != NULL && trie->free_func != NULL)
+ trie->free_func(node->data);
+ b_trie_free_node(trie, node->next);
+ b_trie_free_node(trie, node->child);
+ free(node);
+}
+
+
+void
+b_trie_free(b_trie_t *trie)
+{
+ b_trie_free_node(trie, trie->root);
+ free(trie);
+}
+
+
+void
+b_trie_insert(b_trie_t *trie, const char *key, void *data)
+{
+ if (data == NULL || key == NULL)
+ return;
+
+ b_trie_node_t *parent = NULL;
+ b_trie_node_t *previous;
+ b_trie_node_t *current;
+ b_trie_node_t *tmp;
+
+ while (1) {
+
+ if (trie->root == NULL || (parent != NULL && parent->child == NULL)) {
+ current = malloc(sizeof(b_trie_node_t));
+ current->key = *key;
+ current->data = NULL;
+ current->next = NULL;
+ current->child = NULL;
+ if (trie->root == NULL)
+ trie->root = current;
+ else
+ parent->child = current;
+ parent = current;
+ goto clean;
+ }
+
+ tmp = parent == NULL ? trie->root : parent->child;
+ previous = NULL;
+
+ while (tmp != NULL && tmp->key != *key) {
+ previous = tmp;
+ tmp = tmp->next;
+ }
+
+ parent = tmp;
+
+ if (previous == NULL || parent != NULL)
+ goto clean;
+
+ current = malloc(sizeof(b_trie_node_t));
+ current->key = *key;
+ current->data = NULL;
+ current->next = NULL;
+ current->child = NULL;
+ previous->next = current;
+ parent = current;
+
+clean:
+ if (*key == '\0') {
+ parent->data = data;
+ break;
+ }
+ key++;
+ }
+}
+
+
+void*
+b_trie_lookup(b_trie_t *trie, const char *key)
+{
+ if (trie->root == NULL || key == NULL)
+ return NULL;
+
+ b_trie_node_t *parent = trie->root;
+ b_trie_node_t *tmp;
+ while (1) {
+ for (tmp = parent; tmp != NULL; tmp = tmp->next) {
+
+ if (tmp->key == *key) {
+ if (tmp->key == '\0')
+ return tmp->data;
+ parent = tmp->child;
+ break;
+ }
+ }
+ if (tmp == NULL)
+ return NULL;
+
+ if (*key == '\0')
+ break;
+ key++;
+ }
+ return NULL;
+}
+
+
+static void
+b_trie_size_node(b_trie_node_t *node, unsigned int *count)
+{
+ if (node == NULL)
+ return;
+
+ if (node->key == '\0')
+ (*count)++;
+
+ b_trie_size_node(node->next, count);
+ b_trie_size_node(node->child, count);
+}
+
+
+unsigned int
+b_trie_size(b_trie_t *trie)
+{
+ if (trie == NULL)
+ return 0;
+
+ unsigned int count = 0;
+ b_trie_size_node(trie->root, &count);
+ return count;
+}
+
+
+static void
+b_trie_foreach_node(b_trie_node_t *node, b_string_t *str, void (*func)(const char *key, void *data))
+{
+ if (node == NULL)
+ return;
+
+ if (node->key == '\0') {
+ func(str->str, node->data);
+ b_string_free(str, true);
+ }
+
+ if (node->child != NULL) {
+ b_string_t *child = b_string_new();
+ child = b_string_append(child, str->str);
+ child = b_string_append_c(child, node->key);
+ b_trie_foreach_node(node->child, child, func);
+ }
+
+ if (node->next != NULL)
+ b_trie_foreach_node(node->next, str, func);
+
+ if (node->child != NULL && node->next == NULL)
+ b_string_free(str, true);
+}
+
+
+void
+b_trie_foreach(b_trie_t *trie, void (*func)(const char *key, void *data))
+{
+ if (trie->root == NULL)
+ return;
+
+ b_string_t *str = b_string_new();
+ b_trie_foreach_node(trie->root, str, func);
+}
diff --git a/src/utils/utils.h b/src/utils/utils.h
new file mode 100644
index 0000000..20259d8
--- /dev/null
+++ b/src/utils/utils.h
@@ -0,0 +1,71 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2014-2015 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file COPYING.
+ */
+
+#ifndef _UTILS_UTILS_H
+#define _UTILS_UTILS_H
+
+#include <stdbool.h>
+#include <stdarg.h>
+
+#define B_STRING_CHUNK_SIZE 128
+
+typedef struct _b_slist_t {
+ struct _b_slist_t *next;
+ void *data;
+} b_slist_t;
+
+typedef struct _b_string_t {
+ char *str;
+ size_t len;
+ size_t allocated_len;
+} b_string_t;
+
+typedef struct _b_trie_node_t {
+ char key;
+ void *data;
+ struct _b_trie_node_t *next, *child;
+} b_trie_node_t;
+
+typedef struct _b_trie_t {
+ b_trie_node_t *root;
+ void (*free_func)(void *ptr);
+} b_trie_t;
+
+b_slist_t* b_slist_append(b_slist_t *l, void *data);
+void b_slist_free_full(b_slist_t *l, void (*free_func)(void *ptr));
+void b_slist_free(b_slist_t *l);
+unsigned int b_slist_length(b_slist_t *l);
+
+char* b_strdup(const char *s);
+char* b_strndup(const char *s, size_t n);
+char* b_strdup_vprintf(const char *format, va_list ap);
+char* b_strdup_printf(const char *format, ...);
+bool b_str_starts_with(const char *str, const char *prefix);
+bool b_str_ends_with(const char *str, const char *suffix);
+char* b_str_strip(char *str);
+char** b_str_split(const char *str, char c, unsigned int max_pieces);
+char* b_str_replace(const char *str, const char search, const char *replace);
+void b_strv_free(char **strv);
+char* b_strv_join(const char **strv, const char *separator);
+unsigned int b_strv_length(char **strv);
+
+b_string_t* b_string_new(void);
+char* b_string_free(b_string_t *str, bool free_str);
+b_string_t* b_string_append_len(b_string_t *str, const char *suffix, size_t len);
+b_string_t* b_string_append(b_string_t *str, const char *suffix);
+b_string_t* b_string_append_c(b_string_t *str, char c);
+b_string_t* b_string_append_printf(b_string_t *str, const char *format, ...);
+
+b_trie_t* b_trie_new(void (*free_func)(void *ptr));
+void b_trie_free(b_trie_t *trie);
+void b_trie_insert(b_trie_t *trie, const char *key, void *data);
+void* b_trie_lookup(b_trie_t *trie, const char *key);
+unsigned int b_trie_size(b_trie_t *trie);
+void b_trie_foreach(b_trie_t *trie, void (*func)(const char *key, void *data));
+
+#endif /* _UTILS_UTILS_H */