diff --git a/libifupdown/yaml-base.c b/libifupdown/yaml-base.c new file mode 100644 index 0000000..2e104f4 --- /dev/null +++ b/libifupdown/yaml-base.c @@ -0,0 +1,109 @@ +/* + * libifupdown/yaml-base.c + * Purpose: YAML implementation -- base + * + * Copyright (c) 2020 Ariadne Conill + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include +#include "libifupdown/libifupdown.h" +#include "libifupdown/yaml-base.h" + +void +lif_yaml_document_init(struct lif_yaml_node *doc, const char *name) +{ + memset(doc, '\0', sizeof *doc); + doc->value_type = LIF_YAML_OBJECT; + + if (name != NULL) + doc->name = strdup(name); +} + +struct lif_yaml_node * +lif_yaml_document_new(const char *name) +{ + struct lif_yaml_node *doc = calloc(1, sizeof *doc); + + lif_yaml_document_init(doc, name); + doc->malloced = true; + + return doc; +} + +struct lif_yaml_node * +lif_yaml_node_new_string(const char *name, const char *value) +{ + struct lif_yaml_node *node = calloc(1, sizeof *node); + + node->malloced = true; + node->value_type = LIF_YAML_STRING; + + if (name != NULL) + node->name = strdup(name); + + if (value != NULL) + node->value = strdup(value); + + return node; +} + +struct lif_yaml_node * +lif_yaml_node_new_object(const char *name) +{ + struct lif_yaml_node *node = calloc(1, sizeof *node); + + node->malloced = true; + node->value_type = LIF_YAML_OBJECT; + + if (name != NULL) + node->name = strdup(name); + + return node; +} + +struct lif_yaml_node * +lif_yaml_node_new_list(const char *name) +{ + struct lif_yaml_node *node = calloc(1, sizeof *node); + + node->malloced = true; + node->value_type = LIF_YAML_LIST; + + if (name != NULL) + node->name = strdup(name); + + return node; +} + +void +lif_yaml_node_free(struct lif_yaml_node *node) +{ + struct lif_node *iter, *next; + + LIF_LIST_FOREACH_SAFE(iter, next, node->children.head) + { + struct lif_yaml_node *iter_node = iter->data; + + lif_yaml_node_free(iter_node); + } + + free(node->name); + free(node->value); + + if (node->malloced) + free(node); +} + +void +lif_yaml_node_append_child(struct lif_yaml_node *parent, struct lif_yaml_node *child) +{ + lif_node_insert_tail(&child->node, child, &parent->children); +} diff --git a/libifupdown/yaml-base.h b/libifupdown/yaml-base.h new file mode 100644 index 0000000..8735edf --- /dev/null +++ b/libifupdown/yaml-base.h @@ -0,0 +1,47 @@ +/* + * libifupdown/yaml-base.h + * Purpose: YAML implementation -- base + * + * Copyright (c) 2020 Ariadne Conill + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#ifndef LIBIFUPDOWN_YAML_BASE_H__GUARD +#define LIBIFUPDOWN_YAML_BASE_H__GUARD + +#include "libifupdown/libifupdown.h" + +/* this is a subset of types supported by our implementation */ +enum lif_yaml_value { + LIF_YAML_STRING, + LIF_YAML_LIST, + LIF_YAML_OBJECT +}; + +struct lif_yaml_node { + struct lif_node node; + + bool malloced; + char *name; + enum lif_yaml_value value_type; + char *value; /* for string nodes */ + struct lif_list children; /* for list and object nodes */ +}; + +extern void lif_yaml_document_init(struct lif_yaml_node *doc, const char *name); +extern struct lif_yaml_node *lif_yaml_document_new(const char *name); + +extern struct lif_yaml_node *lif_yaml_node_new_string(const char *name, const char *value); +extern struct lif_yaml_node *lif_yaml_node_new_object(const char *name); +extern struct lif_yaml_node *lif_yaml_node_new_list(const char *name); +extern void lif_yaml_node_free(struct lif_yaml_node *node); +extern void lif_yaml_node_append_child(struct lif_yaml_node *parent, struct lif_yaml_node *child); + +#endif diff --git a/libifupdown/yaml-writer.c b/libifupdown/yaml-writer.c new file mode 100644 index 0000000..8b2c589 --- /dev/null +++ b/libifupdown/yaml-writer.c @@ -0,0 +1,63 @@ +/* + * libifupdown/yaml-writer.c + * Purpose: YAML implementation -- writer + * + * Copyright (c) 2020 Ariadne Conill + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include +#include +#include "libifupdown/libifupdown.h" +#include "libifupdown/yaml-base.h" +#include "libifupdown/yaml-writer.h" + +static const size_t INDENT_WIDTH = 2; + +static void +lif_yaml_write_node(struct lif_yaml_node *node, FILE *f, size_t indent) +{ + struct lif_node *iter; + + if (node->name != NULL) + fprintf(f, "%*s%s: ", (int) indent, "", node->name); + + size_t child_indent = indent + INDENT_WIDTH; + + switch (node->value_type) + { + case LIF_YAML_STRING: + fprintf(f, "%s\n", node->value); + break; + case LIF_YAML_OBJECT: + fprintf(f, "\n"); + break; + case LIF_YAML_LIST: + fprintf(f, "\n"); + child_indent += INDENT_WIDTH; + break; + } + + LIF_LIST_FOREACH(iter, node->children.head) + { + struct lif_yaml_node *iter_node = iter->data; + + if (node->value_type == LIF_YAML_LIST) + fprintf(f, "%*s-\n", (int) (child_indent - INDENT_WIDTH), ""); + + lif_yaml_write_node(iter_node, f, child_indent); + } +} + +void +lif_yaml_write(struct lif_yaml_node *doc, FILE *f) +{ + lif_yaml_write_node(doc, f, 0); +} diff --git a/libifupdown/yaml-writer.h b/libifupdown/yaml-writer.h new file mode 100644 index 0000000..3e8a0cc --- /dev/null +++ b/libifupdown/yaml-writer.h @@ -0,0 +1,24 @@ +/* + * libifupdown/yaml-writer.h + * Purpose: YAML implementation -- writer + * + * Copyright (c) 2020 Ariadne Conill + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#ifndef LIBIFUPDOWN_YAML_WRITER_H__GUARD +#define LIBIFUPDOWN_YAML_WRITER_H__GUARD + +#include "libifupdown/libifupdown.h" +#include "libifupdown/yaml-base.h" + +extern void lif_yaml_write(struct lif_yaml_node *doc, FILE *f); + +#endif