summaryrefslogtreecommitdiff
path: root/src/node.c
diff options
context:
space:
mode:
authorNick Wellnhofer <wellnhofer@aevum.de>2014-11-18 18:27:18 +0100
committerNick Wellnhofer <wellnhofer@aevum.de>2014-11-18 18:43:04 +0100
commit3f9fec6998fccabe5d61bfe84b9d2431f9d5ae53 (patch)
tree7a81e02d98354252f1c0c009031ba3e918bf3811 /src/node.c
parent41a73d5285368d19ac1ef17a7992bf13a352817c (diff)
Add node constructor and accessors to the public API
The approach I'm taking is to copy inline literals internally to NULL-terminated C strings if requested by an accessor. This allows to return a 'const char *' that doesn't have to be freed by the caller.
Diffstat (limited to 'src/node.c')
-rw-r--r--src/node.c85
1 files changed, 84 insertions, 1 deletions
diff --git a/src/node.c b/src/node.c
index 489ac7c..c5ce642 100644
--- a/src/node.c
+++ b/src/node.c
@@ -1,8 +1,26 @@
-#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
#include "config.h"
#include "node.h"
+static void
+S_node_unlink(cmark_node *node);
+
+cmark_node*
+cmark_node_new(cmark_node_type type) {
+ cmark_node *node = (cmark_node *)calloc(1, sizeof(*node));
+ node->type = type;
+ return node;
+}
+
+void
+cmark_node_destroy(cmark_node *node) {
+ S_node_unlink(node);
+ node->next = NULL;
+ cmark_free_nodes(node);
+}
+
cmark_node_type
cmark_node_get_type(cmark_node *node)
{
@@ -69,6 +87,71 @@ cmark_node_last_child(cmark_node *node)
return node->last_child;
}
+static char*
+S_strdup(const char *str) {
+ size_t size = strlen(str) + 1;
+ char *dup = (char *)malloc(size);
+ memcpy(dup, str, size);
+ return dup;
+}
+
+const char*
+cmark_node_get_content(cmark_node *node) {
+ switch (node->type) {
+ case NODE_STRING:
+ case NODE_INLINE_HTML:
+ case NODE_INLINE_CODE:
+ return cmark_chunk_to_cstr(&node->as.literal);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+int
+cmark_node_set_content(cmark_node *node, const char *content) {
+ switch (node->type) {
+ case NODE_STRING:
+ case NODE_INLINE_HTML:
+ case NODE_INLINE_CODE:
+ cmark_chunk_set_cstr(&node->as.literal, content);
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+const char*
+cmark_node_get_url(cmark_node *node) {
+ switch (node->type) {
+ case NODE_LINK:
+ case NODE_IMAGE:
+ return (char *)node->as.link.url;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+int
+cmark_node_set_url(cmark_node *node, const char *url) {
+ switch (node->type) {
+ case NODE_LINK:
+ case NODE_IMAGE:
+ free(node->as.link.url);
+ node->as.link.url = (unsigned char *)S_strdup(url);
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static inline bool
S_is_block(cmark_node *node) {
return node->type >= CMARK_NODE_FIRST_BLOCK