Mercurial > molko
changeset 48:55869b5e4761
core: implement properties, closes #2461
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 16 Jan 2020 14:57:51 +0100 |
parents | f053a9f38c0e |
children | a8c7db56ccb0 |
files | .hgignore Makefile src/property.c src/property.h tests/test-property.c |
diffstat | 5 files changed, 288 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Thu Jan 16 13:32:20 2020 +0100 +++ b/.hgignore Thu Jan 16 14:57:51 2020 +0100 @@ -16,7 +16,8 @@ ^tests/test-color(\.exe)?$ ^tests/test-error(\.exe)?$ ^tests/test-map(\.exe)?$ -^tools/molko-map$ +^tests/test-property(\.exe)?$ +^tools/molko-map(\.exe)?$ # doxygen stuff. ^doxygen/html$
--- a/Makefile Thu Jan 16 13:32:20 2020 +0100 +++ b/Makefile Thu Jan 16 14:57:51 2020 +0100 @@ -37,6 +37,7 @@ src/sys.c \ src/texture.c \ src/util.c \ + src/property.c \ src/splashscreen.c \ src/walksprite.c \ src/window.c @@ -55,7 +56,8 @@ TESTS= tests/test-color.c \ tests/test-error.c \ - tests/test-map.c + tests/test-map.c \ + tests/test-property.c TESTS_INCS= -I extern/libgreatest -I src ${SDL_CFLAGS} TESTS_LIBS= ${LIB} ${SDL_LDFLAGS} ${LDFLAGS} TESTS_OBJS= ${TESTS:.c=}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/property.c Thu Jan 16 14:57:51 2020 +0100 @@ -0,0 +1,81 @@ +/* + * property.c -- key-value properties + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "util.h" +#include "property.h" + +struct property * +property_new(const char *key, const char *value) +{ + assert(key && strlen(key) <= PROPERTY_KEY_MAX); + assert(value && strlen(value) <= PROPERTY_VALUE_MAX); + + struct property *prop; + + prop = ecalloc(1, sizeof (struct property)); + strncpy(prop->key, key, PROPERTY_KEY_MAX); + strncpy(prop->value, value, PROPERTY_VALUE_MAX); + + return prop; +} + +void +property_add(struct property_list *head, struct property *prop) +{ + assert(head); + assert(prop); + + if (head->next == NULL) + head->next = prop; + else + head->next->next = prop; +} + +struct property * +property_find(struct property_list *head, const char *key) +{ + assert(head); + assert(key); + + for (struct property *it = head->next; it; it = it->next) + if (strcmp(it->key, key) == 0) + return it; + + return NULL; +} + +void +property_clear(struct property_list *head) +{ + assert(head); + + struct property *it; + struct property *next; + + for (it = head->next; it && it->next; ) { + next = it->next; + free(it); + it = next; + } + + head->next = NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/property.h Thu Jan 16 14:57:51 2020 +0100 @@ -0,0 +1,102 @@ +/* + * property.h -- key-value properties + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_PROPERTY_H +#define MOLKO_PROPERTY_H + +/** + * \file property.h + * \brief Key-value properties. + */ + +/** + * Maximum property key length. + */ +#define PROPERTY_KEY_MAX 32 + +/** + * Maximum property value length. + */ +#define PROPERTY_VALUE_MAX 128 + +/** + * \brief Key-value properties. + * + * This structure is implemented as linked-lists. + */ +struct property { + char key[PROPERTY_KEY_MAX + 1]; /*!< (RW) Property key */ + char value[PROPERTY_VALUE_MAX + 1]; /*!< (RW) Property value */ + struct property *next; /*!< (RO) Pointer to next property */ +}; + +/** + * \brief The linked list of properties. + */ +struct property_list { + struct property *next; /*!< (RO) Property head */ +}; + +/** + * Create a new property. + * + * \pre key != NULL + * \pre value != NULL + * \param key the property key + * \param value the property value + * \return a non-NULL property + * \note The property must be deallocated with free(3) + * \see property_clear + */ +struct property * +property_new(const char *key, const char *value); + +/** + * Add a property to the linked-list specified by head. + * + * \pre head != NULL + * \pre prop != NULL + * \param head the linked-list + * \param prop the property + */ +void +property_add(struct property_list *head, struct property *prop); + +/** + * Try to find a property by key. + * + * \pre head != NULL + * \pre key != NULL + * \param head the linked-list + * \param key the property key + * \return the property or NULL on failure + */ +struct property * +property_find(struct property_list *head, const char *key); + +/** + * Remove and free all properties. + * + * \pre head != NULL + * \param head the linked-list + * \warning All properties must be allocated on the heap. + */ +void +property_clear(struct property_list *head); + +#endif /* !MOLKO_PROPERTY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-property.c Thu Jan 16 14:57:51 2020 +0100 @@ -0,0 +1,100 @@ +/* + * test-property.c -- test properties + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * 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. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <greatest.h> + +#include <property.h> + +TEST +add(void) +{ + struct property_list list = { 0 }; + + /* + * 1 value: + * - 0: "name" = "Jean Dujardin" + */ + property_add(&list, property_new("name", "Jean Dujardin")); + ASSERT_STR_EQ(list.next->key, "name"); + ASSERT_STR_EQ(list.next->value, "Jean Dujardin"); + ASSERT(!list.next->next); + + /* + * 1 value: + * - 0: "name" = "Jean Dujardin" + * - 1: "name" = "Daniel Balavoine" + */ + property_add(&list, property_new("name", "Daniel Balavoine")); + ASSERT_STR_EQ(list.next->key, "name"); + ASSERT_STR_EQ(list.next->value, "Jean Dujardin"); + ASSERT_STR_EQ(list.next->next->key, "name"); + ASSERT_STR_EQ(list.next->next->value, "Daniel Balavoine"); + ASSERT(!list.next->next->next); + + property_clear(&list); + PASS(); +} + +TEST +find(void) +{ + struct property_list list = { 0 }; + + /* + * 2 value: + * - "start-x" = "10" + * - "start-y" = "20" + */ + property_add(&list, property_new("start-x", "10")); + property_add(&list, property_new("start-y", "20")); + ASSERT_STR_EQ("start-x", property_find(&list, "start-x")->key); + ASSERT_STR_EQ("10", property_find(&list, "start-x")->value); + ASSERT_STR_EQ("start-y", property_find(&list, "start-y")->key); + ASSERT_STR_EQ("20", property_find(&list, "start-y")->value); + property_clear(&list); + PASS(); +} + +TEST +clear(void) +{ + struct property_list list = { 0 }; + + property_add(&list, property_new("start-x", "10")); + property_add(&list, property_new("start-y", "20")); + property_clear(&list); + ASSERT(!list.next); + PASS(); +} + +SUITE(simple) +{ + RUN_TEST(add); + RUN_TEST(find); + RUN_TEST(clear); +} + +GREATEST_MAIN_DEFS(); + +int +main(int argc, char **argv) +{ + GREATEST_MAIN_BEGIN(); + RUN_SUITE(simple); + GREATEST_MAIN_END(); +}