From ca89e4f7548cb64e3dd1b67ea9ebb75ace33a754 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 27 Oct 2016 17:59:44 +0200 Subject: [PATCH] init --- lib/Makefile | 49 ++++++ lib/build/test | Bin 0 -> 56432 bytes lib/ecoli_test.c | 115 +++++++++++++ lib/ecoli_test.h | 94 +++++++++++ lib/ecoli_tk.c | 333 ++++++++++++++++++++++++++++++++++++++ lib/ecoli_tk.h | 123 ++++++++++++++ lib/ecoli_tk_empty.c | 59 +++++++ lib/ecoli_tk_empty.h | 39 +++++ lib/ecoli_tk_int.c | 212 ++++++++++++++++++++++++ lib/ecoli_tk_int.h | 44 +++++ lib/ecoli_tk_or.c | 219 +++++++++++++++++++++++++ lib/ecoli_tk_or.h | 48 ++++++ lib/ecoli_tk_seq.c | 137 ++++++++++++++++ lib/ecoli_tk_seq.h | 48 ++++++ lib/ecoli_tk_space.c | 65 ++++++++ lib/ecoli_tk_space.h | 39 +++++ lib/ecoli_tk_str.c | 183 +++++++++++++++++++++ lib/ecoli_tk_str.h | 41 +++++ lib/main.c | 81 ++++++++++ mk/ecoli-ar-rules.mk | 55 +++++++ mk/ecoli-ar-vars.mk | 75 +++++++++ mk/ecoli-clean-rules.mk | 33 ++++ mk/ecoli-clean-vars.mk | 37 +++++ mk/ecoli-copy-rules.mk | 55 +++++++ mk/ecoli-copy-vars.mk | 74 +++++++++ mk/ecoli-exe-rules.mk | 55 +++++++ mk/ecoli-exe-vars.mk | 79 +++++++++ mk/ecoli-obj-rules.mk | 83 ++++++++++ mk/ecoli-obj-vars.mk | 124 ++++++++++++++ mk/ecoli-objcopy-rules.mk | 74 +++++++++ mk/ecoli-objcopy-vars.mk | 89 ++++++++++ mk/ecoli-post.mk | 108 +++++++++++++ mk/ecoli-pre.mk | 42 +++++ mk/ecoli-shlib-rules.mk | 55 +++++++ mk/ecoli-shlib-vars.mk | 76 +++++++++ mk/ecoli-slink-rules.mk | 55 +++++++ mk/ecoli-slink-vars.mk | 74 +++++++++ mk/ecoli-subdir-rules.mk | 30 ++++ mk/ecoli-subdir-vars.mk | 33 ++++ mk/ecoli-tools.mk | 159 ++++++++++++++++++ mk/ecoli-vars.mk | 47 ++++++ 41 files changed, 3441 insertions(+) create mode 100644 lib/Makefile create mode 100755 lib/build/test create mode 100644 lib/ecoli_test.c create mode 100644 lib/ecoli_test.h create mode 100644 lib/ecoli_tk.c create mode 100644 lib/ecoli_tk.h create mode 100644 lib/ecoli_tk_empty.c create mode 100644 lib/ecoli_tk_empty.h create mode 100644 lib/ecoli_tk_int.c create mode 100644 lib/ecoli_tk_int.h create mode 100644 lib/ecoli_tk_or.c create mode 100644 lib/ecoli_tk_or.h create mode 100644 lib/ecoli_tk_seq.c create mode 100644 lib/ecoli_tk_seq.h create mode 100644 lib/ecoli_tk_space.c create mode 100644 lib/ecoli_tk_space.h create mode 100644 lib/ecoli_tk_str.c create mode 100644 lib/ecoli_tk_str.h create mode 100644 lib/main.c create mode 100644 mk/ecoli-ar-rules.mk create mode 100644 mk/ecoli-ar-vars.mk create mode 100644 mk/ecoli-clean-rules.mk create mode 100644 mk/ecoli-clean-vars.mk create mode 100644 mk/ecoli-copy-rules.mk create mode 100644 mk/ecoli-copy-vars.mk create mode 100644 mk/ecoli-exe-rules.mk create mode 100644 mk/ecoli-exe-vars.mk create mode 100644 mk/ecoli-obj-rules.mk create mode 100644 mk/ecoli-obj-vars.mk create mode 100644 mk/ecoli-objcopy-rules.mk create mode 100644 mk/ecoli-objcopy-vars.mk create mode 100644 mk/ecoli-post.mk create mode 100644 mk/ecoli-pre.mk create mode 100644 mk/ecoli-shlib-rules.mk create mode 100644 mk/ecoli-shlib-vars.mk create mode 100644 mk/ecoli-slink-rules.mk create mode 100644 mk/ecoli-slink-vars.mk create mode 100644 mk/ecoli-subdir-rules.mk create mode 100644 mk/ecoli-subdir-vars.mk create mode 100644 mk/ecoli-tools.mk create mode 100644 mk/ecoli-vars.mk diff --git a/lib/Makefile b/lib/Makefile new file mode 100644 index 0000000..0ce853f --- /dev/null +++ b/lib/Makefile @@ -0,0 +1,49 @@ +# +# Copyright 2016, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +ECOLI ?= $(abspath ..) +include $(ECOLI)/mk/ecoli-pre.mk + +# output path with trailing slash +O ?= build/ + +CFLAGS = -g -O0 -Wall -Werror -W -fPIC +CFLAGS += -I. + +srcs := ecoli_tk.c ecoli_tk_str.c ecoli_tk_seq.c +srcs += ecoli_tk_space.c ecoli_tk_or.c ecoli_test.c +srcs += ecoli_tk_empty.c ecoli_tk_int.c +shlib-y-$(O)libecoli.so := $(srcs) + +exe-y-$(O)test = $(srcs) main.c + +include $(ECOLI)/mk/ecoli-post.mk + +all: _ecoli_all + +clean: _ecoli_clean + +.PHONY: clean all diff --git a/lib/build/test b/lib/build/test new file mode 100755 index 0000000000000000000000000000000000000000..ef618296857eef608dd9deb058415a75f1ebc47c GIT binary patch literal 56432 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 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +static struct ec_test_list test_list = TAILQ_HEAD_INITIALIZER(test_list); + +/* register a driver */ +void ec_test_register(struct ec_test *test) +{ + TAILQ_INSERT_TAIL(&test_list, test, next); +} + +int ec_test_check_tk_parse(const struct ec_tk *tk, const char *input, + const char *expected) +{ + struct ec_parsed_tk *p; + const char *s; + int ret = -1; + + p = ec_tk_parse(tk, input, 0); + s = ec_parsed_tk_to_string(p); + if (s == NULL && expected == NULL) + ret = 0; + else if (s != NULL && expected != NULL && + !strcmp(s, expected)) + ret = 0; + + if (expected == NULL && ret != 0) + printf("tk should not match but matches <%s>\n", s); + if (expected != NULL && ret != 0) + printf("tk should match <%s> but matches <%s>\n", + expected, s); + + ec_parsed_tk_free(p); + + return ret; +} + +int ec_test_check_tk_complete(const struct ec_tk *tk, const char *input, + const char *expected) +{ + struct ec_completed_tk *p; + const char *s; + int ret = -1; + + p = ec_tk_complete(tk, input, 0); + s = ec_completed_tk_smallest_start(p); + if (s == NULL && expected == NULL) + ret = 0; + else if (s != NULL && expected != NULL && + !strcmp(s, expected)) + ret = 0; + + if (expected == NULL && ret != 0) + printf("tk should not complete but completes with <%s>\n", s); + if (expected != NULL && ret != 0) + printf("tk should complete with <%s> but completes with <%s>\n", + expected, s); + + ec_completed_tk_free(p); + + return ret; +} + +/* int ec_test_check_tk_complete_list(const struct ec_tk *tk, */ +/* const char *input, ...) */ + +int ec_test_all(void) +{ + struct ec_test *test; + int ret = 0; + + // XXX register a new malloc to trac memleaks + + TAILQ_FOREACH(test, &test_list, next) { + if (test->test() == 0) { + printf("== test %-20s success\n", test->name); + } else { + printf("== test %-20s failed\n", test->name); + ret = -1; + } + } + + return ret; +} diff --git a/lib/ecoli_test.h b/lib/ecoli_test.h new file mode 100644 index 0000000..61d9950 --- /dev/null +++ b/lib/ecoli_test.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TEST_ +#define ECOLI_TEST_ + +#include + +#include + +#define EC_REGISTER_TEST(t) \ + static void ec_init_##t(void); \ + static void __attribute__((constructor, used)) ec_init_##t(void) \ + { \ + ec_test_register(&t); \ + } + +/** + * Type of test function. Return 0 on success, -1 on error. + */ +typedef int (ec_test_t)(void); + +TAILQ_HEAD(ec_test_list, ec_test); + +/** + * A structure describing a test case. + */ +struct ec_test { + TAILQ_ENTRY(ec_test) next; /**< Next in list. */ + const char *name; /**< Test name. */ + ec_test_t *test; /**< Test function. */ +}; + +/** + * Register a test case. + * + * @param test + * A pointer to a ec_test structure describing the test + * to be registered. + */ +void ec_test_register(struct ec_test *test); + +int ec_test_all(void); + +// XXX could be a macro that display file:line +int ec_test_check_tk_parse(const struct ec_tk *tk, const char *input, + const char *expected); + +#define TEST_ERR() \ + printf("%s:%d: error: test failed\n", \ + __FILE__, __LINE__); \ + +#define EC_TEST_CHECK_TK_PARSE(tk, input, expected) ({ \ + int ret = ec_test_check_tk_parse(tk, input, expected); \ + if (ret) \ + TEST_ERR(); \ + ret; \ +}) + +int ec_test_check_tk_complete(const struct ec_tk *tk, const char *input, + const char *expected); + +#define EC_TEST_CHECK_TK_COMPLETE(tk, input, expected) ({ \ + int ret = ec_test_check_tk_complete(tk, input, expected); \ + if (ret) \ + TEST_ERR(); \ + ret; \ +}) + +#endif diff --git a/lib/ecoli_tk.c b/lib/ecoli_tk.c new file mode 100644 index 0000000..7c5ac21 --- /dev/null +++ b/lib/ecoli_tk.c @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops, + size_t size) +{ + struct ec_tk *tk = NULL; + + assert(size >= sizeof(*tk)); + + tk = calloc(1, size); + if (tk == NULL) + goto fail; + + if (id != NULL) { + tk->id = strdup(id); + if (tk->id == NULL) + goto fail; + } + + tk->ops = ops; + + return tk; + + fail: + ec_tk_free(tk); + return NULL; +} + +void ec_tk_free(struct ec_tk *tk) +{ + if (tk == NULL) + return; + + if (tk->ops != NULL && tk->ops->free_priv != NULL) + tk->ops->free_priv(tk); + free(tk->id); + free(tk); +} + +struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *token, const char *str, + size_t off) +{ + struct ec_parsed_tk *parsed_tk; + + parsed_tk = token->ops->parse(token, str, off); + + return parsed_tk; +} + + +struct ec_parsed_tk *ec_parsed_tk_new(const struct ec_tk *tk) +{ + struct ec_parsed_tk *parsed_tk; + + parsed_tk = calloc(1, sizeof(*parsed_tk)); + if (parsed_tk == NULL) + goto fail; + + parsed_tk->tk = tk; + TAILQ_INIT(&parsed_tk->children); + + return parsed_tk; + + fail: + return NULL; +} + +void ec_parsed_tk_free(struct ec_parsed_tk *parsed_tk) +{ + struct ec_parsed_tk *child; + + if (parsed_tk == NULL) + return; + + while (!TAILQ_EMPTY(&parsed_tk->children)) { + child = TAILQ_FIRST(&parsed_tk->children); + TAILQ_REMOVE(&parsed_tk->children, child, next); + ec_parsed_tk_free(child); + } + free(parsed_tk->str); + free(parsed_tk); +} + +static void __ec_parsed_tk_dump(const struct ec_parsed_tk *parsed_tk, + size_t indent) +{ + struct ec_parsed_tk *child; + size_t i; + const char *s; + + /* XXX enhance */ + for (i = 0; i < indent; i++) + printf(" "); + s = ec_parsed_tk_to_string(parsed_tk); + printf("id=%s, s=<%s>\n", parsed_tk->tk->id, s); + + TAILQ_FOREACH(child, &parsed_tk->children, next) + __ec_parsed_tk_dump(child, indent + 2); +} + +void ec_parsed_tk_dump(const struct ec_parsed_tk *parsed_tk) +{ + if (parsed_tk == NULL) { + printf("no match\n"); + return; + } + + __ec_parsed_tk_dump(parsed_tk, 0); +} + +void ec_parsed_tk_add_child(struct ec_parsed_tk *parsed_tk, + struct ec_parsed_tk *child) +{ + TAILQ_INSERT_TAIL(&parsed_tk->children, child, next); +} + +struct ec_parsed_tk *ec_parsed_tk_find_first(struct ec_parsed_tk *parsed_tk, + const char *id) +{ + struct ec_parsed_tk *child, *ret; + + if (parsed_tk == NULL) + return NULL; + + if (parsed_tk->tk->id != NULL && !strcmp(parsed_tk->tk->id, id)) + return parsed_tk; + + TAILQ_FOREACH(child, &parsed_tk->children, next) { + ret = ec_parsed_tk_find_first(child, id); + if (ret != NULL) + return ret; + } + + return NULL; +} + +const char *ec_parsed_tk_to_string(const struct ec_parsed_tk *parsed_tk) +{ + if (parsed_tk == NULL) + return NULL; + + return parsed_tk->str; +} + +struct ec_completed_tk *ec_tk_complete(const struct ec_tk *token, + const char *str, size_t off) +{ + struct ec_completed_tk *completed_tk; + + completed_tk = token->ops->complete(token, str, off); + + return completed_tk; +} + +struct ec_completed_tk *ec_completed_tk_new(void) +{ + struct ec_completed_tk *completed_tk = NULL; + + completed_tk = calloc(1, sizeof(*completed_tk)); + if (completed_tk == NULL) + return NULL; + + TAILQ_INIT(&completed_tk->elts); + completed_tk->count = 0; + + return completed_tk; +} + +struct ec_completed_tk_elt *ec_completed_tk_elt_new(const struct ec_tk *tk, + const char *add, const char *full) +{ + struct ec_completed_tk_elt *elt = NULL; + + elt = calloc(1, sizeof(*elt)); + if (elt == NULL) + return NULL; + + elt->tk = tk; + elt->add = strdup(add); + elt->full = strdup(full); + if (elt->add == NULL || elt->full == NULL) { + ec_completed_tk_elt_free(elt); + return NULL; + } + + return elt; +} + +/* count the number of identical chars at the beginning of 2 strings */ +static size_t strcmp_count(const char *s1, const char *s2) +{ + size_t i = 0; + + while (s1[i] && s2[i] && s1[i] == s2[i]) + i++; + + return i; +} + +void ec_completed_tk_add_elt( + struct ec_completed_tk *completed_tk, struct ec_completed_tk_elt *elt) +{ + size_t n; + + TAILQ_INSERT_TAIL(&completed_tk->elts, elt, next); + completed_tk->count++; + if (elt->add != NULL) { + if (completed_tk->smallest_start == NULL) { + completed_tk->smallest_start = strdup(elt->add); + } else { + n = strcmp_count(elt->add, + completed_tk->smallest_start); + completed_tk->smallest_start[n] = '\0'; + } + } +} + +void ec_completed_tk_elt_free(struct ec_completed_tk_elt *elt) +{ + free(elt->add); + free(elt->full); + free(elt); +} + +struct ec_completed_tk *ec_completed_tk_merge( + struct ec_completed_tk *completed_tk1, + struct ec_completed_tk *completed_tk2) +{ + struct ec_completed_tk_elt *elt; + + if (completed_tk2 == NULL) + return completed_tk1; + + if (completed_tk1 == NULL) + return completed_tk2; + + while (!TAILQ_EMPTY(&completed_tk2->elts)) { + elt = TAILQ_FIRST(&completed_tk2->elts); + TAILQ_REMOVE(&completed_tk2->elts, elt, next); + ec_completed_tk_add_elt(completed_tk1, elt); + } + + ec_completed_tk_free(completed_tk2); + + return completed_tk1; +} + +void ec_completed_tk_free(struct ec_completed_tk *completed_tk) +{ + struct ec_completed_tk_elt *elt; + + if (completed_tk == NULL) + return; + + while (!TAILQ_EMPTY(&completed_tk->elts)) { + elt = TAILQ_FIRST(&completed_tk->elts); + TAILQ_REMOVE(&completed_tk->elts, elt, next); + ec_completed_tk_elt_free(elt); + } + free(completed_tk->smallest_start); + free(completed_tk); +} + +void ec_completed_tk_dump(const struct ec_completed_tk *completed_tk) +{ + struct ec_completed_tk_elt *elt; + + if (completed_tk == NULL || completed_tk->count == 0) { + printf("no completion\n"); + return; + } + + printf("completion: count=%u smallest_start=<%s>\n", + completed_tk->count, completed_tk->smallest_start); + + TAILQ_FOREACH(elt, &completed_tk->elts, next) + printf("add=<%s> full=<%s>\n", elt->add, elt->full); +} + +const char *ec_completed_tk_smallest_start( + const struct ec_completed_tk *completed_tk) +{ + if (completed_tk == NULL) + return NULL; + + return completed_tk->smallest_start; +} + +unsigned int ec_completed_tk_count(const struct ec_completed_tk *completed_tk) +{ + struct ec_completed_tk_elt *elt; + unsigned int count = 0; + + if (completed_tk == NULL) + return 0; + + TAILQ_FOREACH(elt, &completed_tk->elts, next) + count++; + + return count; +} diff --git a/lib/ecoli_tk.h b/lib/ecoli_tk.h new file mode 100644 index 0000000..15be2be --- /dev/null +++ b/lib/ecoli_tk.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_ +#define ECOLI_TK_ + +#include +#include + +#define EC_TK_ENDLIST ((void *)1) + +struct ec_tk; +struct ec_parsed_tk; + +typedef struct ec_parsed_tk *(*ec_tk_parse_t)(const struct ec_tk *tk, + const char *str, size_t off); +typedef struct ec_completed_tk *(*ec_tk_complete_t)(const struct ec_tk *tk, + const char *str, size_t off); +typedef void (*ec_tk_free_priv_t)(struct ec_tk *); + +struct ec_tk_ops { + ec_tk_parse_t parse; + ec_tk_complete_t complete; + ec_tk_free_priv_t free_priv; +}; + +struct ec_tk { + const struct ec_tk_ops *ops; + char *id; +}; + +struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops, + size_t priv_size); +void ec_tk_free(struct ec_tk *tk); + + +TAILQ_HEAD(ec_parsed_tk_list, ec_parsed_tk); + +struct ec_parsed_tk { + struct ec_parsed_tk_list children; + TAILQ_ENTRY(ec_parsed_tk) next; + const struct ec_tk *tk; + char *str; +}; + +struct ec_parsed_tk *ec_parsed_tk_new(const struct ec_tk *tk); +struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *token, const char *str, + size_t off); +void ec_parsed_tk_add_child(struct ec_parsed_tk *parsed_tk, + struct ec_parsed_tk *child); +void ec_parsed_tk_dump(const struct ec_parsed_tk *parsed_tk); +void ec_parsed_tk_free(struct ec_parsed_tk *parsed_tk); + +struct ec_parsed_tk *ec_parsed_tk_find_first(struct ec_parsed_tk *parsed_tk, + const char *id); + +const char *ec_parsed_tk_to_string(const struct ec_parsed_tk *parsed_tk); + +struct ec_completed_tk_elt { + TAILQ_ENTRY(ec_completed_tk_elt) next; + const struct ec_tk *tk; + char *add; + char *full; +}; + +TAILQ_HEAD(ec_completed_tk_elt_list, ec_completed_tk_elt); + + +struct ec_completed_tk { + struct ec_completed_tk_elt_list elts; + unsigned count; + char *smallest_start; +}; + +/* + * return NULL if it does not match the beginning of the token + * return "" if it matches but does not know how to complete + * return "xyz" if it knows how to complete + */ +struct ec_completed_tk *ec_tk_complete(const struct ec_tk *token, + const char *str, size_t off); +struct ec_completed_tk *ec_completed_tk_new(void); +struct ec_completed_tk_elt *ec_completed_tk_elt_new(const struct ec_tk *tk, + const char *add, const char *full); +void ec_completed_tk_add_elt( + struct ec_completed_tk *completed_tk, struct ec_completed_tk_elt *elt); +void ec_completed_tk_elt_free(struct ec_completed_tk_elt *elt); +struct ec_completed_tk *ec_completed_tk_merge( + struct ec_completed_tk *completed_tk1, + struct ec_completed_tk *completed_tk2); +void ec_completed_tk_free(struct ec_completed_tk *completed_tk); +void ec_completed_tk_dump(const struct ec_completed_tk *completed_tk); + +const char *ec_completed_tk_smallest_start( + const struct ec_completed_tk *completed_tk); + +unsigned int ec_completed_tk_count(const struct ec_completed_tk *completed_tk); + +#endif diff --git a/lib/ecoli_tk_empty.c b/lib/ecoli_tk_empty.c new file mode 100644 index 0000000..e8e98e1 --- /dev/null +++ b/lib/ecoli_tk_empty.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include + +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_parsed_tk *parsed_tk; + + parsed_tk = ec_parsed_tk_new(gen_tk); + if (parsed_tk == NULL) + return NULL; + + (void)str; + (void)off; + parsed_tk->str = strdup(""); + + return parsed_tk; +} + +static struct ec_tk_ops empty_ops = { + .parse = parse, +}; + +struct ec_tk *ec_tk_empty_new(const char *id) +{ + return ec_tk_new(id, &empty_ops, sizeof(struct ec_tk_empty)); +} + diff --git a/lib/ecoli_tk_empty.h b/lib/ecoli_tk_empty.h new file mode 100644 index 0000000..4e22420 --- /dev/null +++ b/lib/ecoli_tk_empty.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_EMPTY_ +#define ECOLI_TK_EMPTY_ + +#include + +struct ec_tk_empty { + struct ec_tk gen; +}; + +struct ec_tk *ec_tk_empty_new(const char *id); + +#endif diff --git a/lib/ecoli_tk_int.c b/lib/ecoli_tk_int.c new file mode 100644 index 0000000..6bd4bfd --- /dev/null +++ b/lib/ecoli_tk_int.c @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +static size_t parse_llint(struct ec_tk_int *tk, const char *str, + long long *val) +{ + char *endptr; + + errno = 0; + *val = strtoll(str, &endptr, tk->base); + + /* starts with a space */ + if (isspace(str[0])) + return 0; + + /* out of range */ + if ((errno == ERANGE && (*val == LLONG_MAX || *val == LLONG_MIN)) || + (errno != 0 && *val == 0)) + return 0; + + if (*val < tk->min || *val > tk->max) + return 0; + + return endptr - str; +} + +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_tk_int *tk = (struct ec_tk_int *)gen_tk; + struct ec_parsed_tk *parsed_tk; + long long val; + size_t len; + + len = parse_llint(tk, str + off, &val); + if (len == 0) + return NULL; + + parsed_tk = ec_parsed_tk_new(gen_tk); + if (parsed_tk == NULL) + return NULL; + + parsed_tk->str = strndup(str + off, len); + + return parsed_tk; +} + +static struct ec_tk_ops int_ops = { + .parse = parse, +}; + +struct ec_tk *ec_tk_int_new(const char *id, long long int min, + long long int max, unsigned int base) +{ + struct ec_tk_int *tk = NULL; + + tk = (struct ec_tk_int *)ec_tk_new(id, &int_ops, sizeof(*tk)); + if (tk == NULL) + return NULL; + + tk->min = min; + tk->max = max; + tk->base = base; + + return &tk->gen; +} + +long long ec_tk_int_getval(struct ec_tk *gen_tk, const char *str) +{ + struct ec_tk_int *tk = (struct ec_tk_int *)gen_tk; + long long val = 0; + + // XXX check type here + // if gen_tk->type != int fail + + parse_llint(tk, str, &val); + + return val; +} + +static int testcase(void) +{ + struct ec_parsed_tk *p; + struct ec_tk *tk; + const char *s; + int ret = 0; + + tk = ec_tk_int_new(NULL, 0, 256, 0); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0", "0"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "256", "256"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0x100", "0x100"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "-1", NULL); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0x101", NULL); + ret |= EC_TEST_CHECK_TK_PARSE(tk, " 1", NULL); + + p = ec_tk_parse(tk, "0", 0); + s = ec_parsed_tk_to_string(p); + if (s == NULL) { + TEST_ERR(); + } else { + if (ec_tk_int_getval(tk, s) != 0) + TEST_ERR(); + } + + p = ec_tk_parse(tk, "10", 0); + s = ec_parsed_tk_to_string(p); + if (s == NULL) { + TEST_ERR(); + } else { + if (ec_tk_int_getval(tk, s) != 10) + TEST_ERR(); + } + + ec_tk_free(tk); + + tk = ec_tk_int_new(NULL, -1, LLONG_MAX, 16); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0", "0"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "-1", "-1"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "7fffffffffffffff", + "7fffffffffffffff"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0x7fffffffffffffff", + "0x7fffffffffffffff"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "-2", NULL); + + p = ec_tk_parse(tk, "10", 0); + s = ec_parsed_tk_to_string(p); + if (s == NULL) { + TEST_ERR(); + } else { + if (ec_tk_int_getval(tk, s) != 16) + TEST_ERR(); + } + + ec_tk_free(tk); + + tk = ec_tk_int_new(NULL, LLONG_MIN, 0, 10); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0", "0"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "-1", "-1"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "-9223372036854775808", + "-9223372036854775808"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "0x0", "0"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "1", NULL); + ec_tk_free(tk); + + /* /\* test completion *\/ */ + /* tk = ec_tk_int_new(NULL, "foo"); */ + /* if (tk == NULL) { */ + /* printf("cannot create tk\n"); */ + /* return -1; */ + /* } */ + /* ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "", "foo"); */ + /* ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "f", "oo"); */ + /* ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "foo", ""); */ + /* ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "x", NULL); */ + /* ec_tk_free(tk); */ + + return ret; +} + +static struct ec_test test = { + .name = "tk_int", + .test = testcase, +}; + +EC_REGISTER_TEST(test); diff --git a/lib/ecoli_tk_int.h b/lib/ecoli_tk_int.h new file mode 100644 index 0000000..e210279 --- /dev/null +++ b/lib/ecoli_tk_int.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_INT_ +#define ECOLI_TK_INT_ + +#include + +struct ec_tk_int { + struct ec_tk gen; + long long int min; + long long int max; + unsigned int base; +}; + +struct ec_tk *ec_tk_int_new(const char *id, long long int min, + long long int max, unsigned int base); +long long ec_tk_int_getval(struct ec_tk *tk, const char *str); + +#endif diff --git a/lib/ecoli_tk_or.c b/lib/ecoli_tk_or.c new file mode 100644 index 0000000..dda2230 --- /dev/null +++ b/lib/ecoli_tk_or.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_tk_or *tk = (struct ec_tk_or *)gen_tk; + struct ec_parsed_tk *parsed_tk, *child_parsed_tk; + unsigned int i; + + parsed_tk = ec_parsed_tk_new(gen_tk); + if (parsed_tk == NULL) + return NULL; + + for (i = 0; i < tk->len; i++) { + child_parsed_tk = ec_tk_parse(tk->table[i], str, off); + if (child_parsed_tk != NULL) + break; + } + + if (child_parsed_tk == NULL) + goto fail; + + ec_parsed_tk_add_child(parsed_tk, child_parsed_tk); + + parsed_tk->str = strndup(child_parsed_tk->str, + strlen(child_parsed_tk->str)); + + return parsed_tk; + + fail: + ec_parsed_tk_free(parsed_tk); + return NULL; +} + +static struct ec_completed_tk *complete(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_tk_or *tk = (struct ec_tk_or *)gen_tk; + struct ec_completed_tk *completed_tk = NULL, *child_completed_tk; + size_t n; + + for (n = 0; n < tk->len; n++) { + child_completed_tk = ec_tk_complete(tk->table[n], str, off); + + if (child_completed_tk == NULL) + continue; + + completed_tk = ec_completed_tk_merge(completed_tk, + child_completed_tk); + } + + return completed_tk; +} + +static void free_priv(struct ec_tk *gen_tk) +{ + struct ec_tk_or *tk = (struct ec_tk_or *)gen_tk; + + free(tk->table); +} + +static struct ec_tk_ops or_ops = { + .parse = parse, + .complete = complete, + .free_priv = free_priv, +}; + +struct ec_tk *ec_tk_or_new(const char *id) +{ + struct ec_tk_or *tk = NULL; + + tk = (struct ec_tk_or *)ec_tk_new(id, &or_ops, sizeof(*tk)); + if (tk == NULL) + goto fail; + + tk->table = NULL; + tk->len = 0; + + return &tk->gen; + +fail: + free(tk); + return NULL; +} + +struct ec_tk *ec_tk_or_new_list(const char *id, ...) +{ + struct ec_tk_or *tk = NULL; + struct ec_tk *child; + va_list ap; + + va_start(ap, id); + + tk = (struct ec_tk_or *)ec_tk_or_new(id); + if (tk == NULL) + goto fail; + + for (child = va_arg(ap, struct ec_tk *); + child != EC_TK_ENDLIST; + child = va_arg(ap, struct ec_tk *)) { + if (child == NULL) + goto fail; + + ec_tk_or_add(&tk->gen, child); + } + + va_end(ap); + return &tk->gen; + +fail: + free(tk); // XXX use tk_free? we need to delete all child on error + va_end(ap); + return NULL; +} + +int ec_tk_or_add(struct ec_tk *tk, struct ec_tk *child) +{ + struct ec_tk_or *or = (struct ec_tk_or *)tk; + struct ec_tk **table; + + assert(tk != NULL); + assert(child != NULL); + + table = realloc(or->table, (or->len + 1) * sizeof(*or->table)); + if (table == NULL) + return -1; + + or->table = table; + table[or->len] = child; + or->len ++; + + return 0; +} + +static int testcase(void) +{ + struct ec_tk *tk; + int ret = 0; + + /* all inputs starting with foo should match */ + tk = ec_tk_or_new_list(NULL, + ec_tk_str_new(NULL, "foo"), + ec_tk_str_new(NULL, "bar"), + EC_TK_ENDLIST); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foo", "foo"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "fooxxx", "foo"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "bar", "bar"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "oo", NULL); + ec_tk_free(tk); + + /* test completion */ + tk = ec_tk_or_new_list(NULL, + ec_tk_str_new(NULL, "foo"), + ec_tk_str_new(NULL, "bar"), + ec_tk_str_new(NULL, "bar2"), + ec_tk_str_new(NULL, "toto"), + ec_tk_str_new(NULL, "titi"), + EC_TK_ENDLIST); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "", ""); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "f", "oo"); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "b", "ar"); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "t", ""); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "to", "to"); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "x", NULL); + ec_tk_free(tk); + + return ret; +} + +static struct ec_test test = { + .name = "tk_or", + .test = testcase, +}; + +EC_REGISTER_TEST(test); diff --git a/lib/ecoli_tk_or.h b/lib/ecoli_tk_or.h new file mode 100644 index 0000000..130ec4d --- /dev/null +++ b/lib/ecoli_tk_or.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_OR_ +#define ECOLI_TK_OR_ + +#include + +#include + +struct ec_tk_or { + struct ec_tk gen; + struct ec_tk **table; + unsigned int len; +}; + +struct ec_tk *ec_tk_or_new(const char *id); + +/* list must be terminated with EC_TK_ENDLIST */ +struct ec_tk *ec_tk_or_new_list(const char *id, ...); + +int ec_tk_or_add(struct ec_tk *tk, struct ec_tk *child); + +#endif diff --git a/lib/ecoli_tk_seq.c b/lib/ecoli_tk_seq.c new file mode 100644 index 0000000..38c633a --- /dev/null +++ b/lib/ecoli_tk_seq.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include +#include + +static struct ec_parsed_tk *parse(const struct ec_tk *tk, + const char *str, size_t off) +{ + struct ec_tk_seq *seq = (struct ec_tk_seq *)tk; + struct ec_parsed_tk *parsed_tk, *child_parsed_tk; + size_t len = 0; + unsigned int i; + + parsed_tk = ec_parsed_tk_new(tk); + if (parsed_tk == NULL) + return NULL; + + for (i = 0; i < seq->len; i++) { + child_parsed_tk = ec_tk_parse(seq->table[i], str, off + len); + if (child_parsed_tk == NULL) + goto fail; + + len += strlen(child_parsed_tk->str); + ec_parsed_tk_add_child(parsed_tk, child_parsed_tk); + } + + parsed_tk->str = strndup(str + off, len); + + return parsed_tk; + + fail: + ec_parsed_tk_free(parsed_tk); + return NULL; +} + +static struct ec_tk_ops seq_ops = { + .parse = parse, +}; + +struct ec_tk *ec_tk_seq_new(const char *id) +{ + struct ec_tk_seq *tk = NULL; + + tk = (struct ec_tk_seq *)ec_tk_new(id, &seq_ops, sizeof(*tk)); + if (tk == NULL) + goto fail; + + tk->table = NULL; + tk->len = 0; + + return &tk->gen; + +fail: + free(tk); + return NULL; +} + +struct ec_tk *ec_tk_seq_new_list(const char *id, ...) +{ + struct ec_tk_seq *tk = NULL; + struct ec_tk *child; + va_list ap; + + va_start(ap, id); + + tk = (struct ec_tk_seq *)ec_tk_seq_new(id); + if (tk == NULL) + goto fail; + + for (child = va_arg(ap, struct ec_tk *); + child != EC_TK_ENDLIST; + child = va_arg(ap, struct ec_tk *)) { + if (child == NULL) + goto fail; + + ec_tk_seq_add(&tk->gen, child); + } + + va_end(ap); + return &tk->gen; + +fail: + free(tk); // XXX use tk_free? we need to delete all child on error + va_end(ap); + return NULL; +} + +int ec_tk_seq_add(struct ec_tk *tk, struct ec_tk *child) +{ + struct ec_tk_seq *seq = (struct ec_tk_seq *)tk; + struct ec_tk **table; + + assert(tk != NULL); + assert(child != NULL); + + table = realloc(seq->table, seq->len + 1); + if (table == NULL) + return -1; + + seq->table = table; + table[seq->len] = child; + seq->len ++; + + return 0; +} + diff --git a/lib/ecoli_tk_seq.h b/lib/ecoli_tk_seq.h new file mode 100644 index 0000000..5c7bfed --- /dev/null +++ b/lib/ecoli_tk_seq.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_SEQ_ +#define ECOLI_TK_SEQ_ + +#include + +#include + +struct ec_tk_seq { + struct ec_tk gen; + struct ec_tk **table; + unsigned int len; +}; + +struct ec_tk *ec_tk_seq_new(const char *id); + +/* list must be terminated with EC_TK_ENDLIST */ +struct ec_tk *ec_tk_seq_new_list(const char *id, ...); + +int ec_tk_seq_add(struct ec_tk *tk, struct ec_tk *child); + +#endif diff --git a/lib/ecoli_tk_space.c b/lib/ecoli_tk_space.c new file mode 100644 index 0000000..ed2ee31 --- /dev/null +++ b/lib/ecoli_tk_space.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include + +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_parsed_tk *parsed_tk; + size_t len = 0; + + if (!isspace(str[off])) + return NULL; + + parsed_tk = ec_parsed_tk_new(gen_tk); + if (parsed_tk == NULL) + return NULL; + + while (isspace(str[off + len])) + len++; + + parsed_tk->str = strndup(str + off, len); + + return parsed_tk; +} + +static struct ec_tk_ops space_ops = { + .parse = parse, +}; + +struct ec_tk *ec_tk_space_new(const char *id) +{ + return ec_tk_new(id, &space_ops, sizeof(struct ec_tk_space)); +} + diff --git a/lib/ecoli_tk_space.h b/lib/ecoli_tk_space.h new file mode 100644 index 0000000..6327c8a --- /dev/null +++ b/lib/ecoli_tk_space.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_SPACE_ +#define ECOLI_TK_SPACE_ + +#include + +struct ec_tk_space { + struct ec_tk gen; +}; + +struct ec_tk *ec_tk_space_new(const char *id); + +#endif diff --git a/lib/ecoli_tk_str.c b/lib/ecoli_tk_str.c new file mode 100644 index 0000000..8152704 --- /dev/null +++ b/lib/ecoli_tk_str.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include + +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_tk_str *tk = (struct ec_tk_str *)gen_tk; + struct ec_parsed_tk *parsed_tk; + + if (strncmp(str + off, tk->string, tk->len) != 0) + return NULL; + + parsed_tk = ec_parsed_tk_new(gen_tk); + if (parsed_tk == NULL) + return NULL; + + parsed_tk->str = strndup(str + off, tk->len); + + return parsed_tk; +} + +static struct ec_completed_tk *complete(const struct ec_tk *gen_tk, + const char *str, size_t off) +{ + struct ec_tk_str *tk = (struct ec_tk_str *)gen_tk; + struct ec_completed_tk *completed_tk; + struct ec_completed_tk_elt *completed_tk_elt; + size_t n; + + for (n = 0; n < tk->len; n++) { + if (str[off + n] != tk->string[n]) + break; + } + + if (str[off + n] != '\0') + return NULL; + + completed_tk = ec_completed_tk_new(); + if (completed_tk == NULL) + return NULL; + + completed_tk_elt = ec_completed_tk_elt_new(gen_tk, tk->string + n, + tk->string); + if (completed_tk_elt == NULL) { + ec_completed_tk_free(completed_tk); + return NULL; + } + + ec_completed_tk_add_elt(completed_tk, completed_tk_elt); + + return completed_tk; +} + +static void free_priv(struct ec_tk *gen_tk) +{ + struct ec_tk_str *tk = (struct ec_tk_str *)gen_tk; + + free(tk->string); +} + +static struct ec_tk_ops str_ops = { + .parse = parse, + .complete = complete, + .free_priv = free_priv, +}; + +struct ec_tk *ec_tk_str_new(const char *id, const char *str) +{ + struct ec_tk_str *tk = NULL; + char *s = NULL; + + tk = (struct ec_tk_str *)ec_tk_new(id, &str_ops, sizeof(*tk)); + if (tk == NULL) + goto fail; + + s = strdup(str); + if (s == NULL) + goto fail; + + tk->string = s; + tk->len = strlen(s); + + return &tk->gen; + +fail: + free(s); + free(tk); + return NULL; +} + +static int testcase(void) +{ + struct ec_tk *tk; + int ret = 0; + + /* all inputs starting with foo should match */ + tk = ec_tk_str_new(NULL, "foo"); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foo", "foo"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foobar", "foo"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, " foo", NULL); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "", NULL); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foo", "foo"); + ec_tk_free(tk); + + /* all inputs starting with foo should match */ + tk = ec_tk_str_new(NULL, "Здравствуйте"); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "Здравствуйте", "Здравствуйте"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "Здравствуйте John!", "Здравствуйте"); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foo", NULL); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "", NULL); + ec_tk_free(tk); + + /* an empty token string always matches */ + tk = ec_tk_str_new(NULL, ""); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_PARSE(tk, "", ""); + ret |= EC_TEST_CHECK_TK_PARSE(tk, "foo", ""); + ec_tk_free(tk); + + /* test completion */ + tk = ec_tk_str_new(NULL, "foo"); + if (tk == NULL) { + printf("cannot create tk\n"); + return -1; + } + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "", "foo"); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "f", "oo"); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "foo", ""); + ret |= EC_TEST_CHECK_TK_COMPLETE(tk, "x", NULL); + ec_tk_free(tk); + + return ret; +} + +static struct ec_test test = { + .name = "tk_str", + .test = testcase, +}; + +EC_REGISTER_TEST(test); diff --git a/lib/ecoli_tk_str.h b/lib/ecoli_tk_str.h new file mode 100644 index 0000000..e7c0759 --- /dev/null +++ b/lib/ecoli_tk_str.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_TK_STR_ +#define ECOLI_TK_STR_ + +#include + +struct ec_tk_str { + struct ec_tk gen; + char *string; + unsigned len; +}; + +struct ec_tk *ec_tk_str_new(const char *id, const char *str); + +#endif diff --git a/lib/main.c b/lib/main.c new file mode 100644 index 0000000..54057b7 --- /dev/null +++ b/lib/main.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +static void test(void) +{ + struct ec_tk *seq; + struct ec_parsed_tk *p; + const char *name; + + seq = ec_tk_seq_new_list(NULL, + ec_tk_str_new(NULL, "hello"), + ec_tk_space_new(NULL), + ec_tk_or_new_list("name", + ec_tk_str_new(NULL, "john"), + ec_tk_str_new(NULL, "mike"), + EC_TK_ENDLIST), + EC_TK_ENDLIST); + if (seq == NULL) { + printf("cannot create token\n"); + return; + } + + /* ok */ + p = ec_tk_parse(seq, "hello mike", 0); + ec_parsed_tk_dump(p); + name = ec_parsed_tk_to_string(ec_parsed_tk_find_first(p, "name")); + printf("parsed with name=%s\n", name); + ec_parsed_tk_free(p); + + /* ko */ + p = ec_tk_parse(seq, "hello robert", 0); + ec_parsed_tk_dump(p); + name = ec_parsed_tk_to_string(ec_parsed_tk_find_first(p, "name")); + printf("parsed with name=%s\n", name); + ec_parsed_tk_free(p); + + ec_tk_free(seq); +} + +int main(void) +{ + ec_test_all(); + + test(); + + return 0; +} diff --git a/mk/ecoli-ar-rules.mk b/mk/ecoli-ar-rules.mk new file mode 100644 index 0000000..4ad30cb --- /dev/null +++ b/mk/ecoli-ar-rules.mk @@ -0,0 +1,55 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-ar,$(all-ar)) +$(foreach ar,$(all-ar),\ + $(info,out-$(ar): $(out-$(ar))) \ + $(call disp_list,pre-$(ar),$(pre-$(ar))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach ar,$(all-ar),\ + $(eval -include $(call depfile,$(ar))) \ + $(eval -include $(call cmdfile,$(ar))) \ +) + +# remove duplicates +filtered-all-ar := $(sort $(all-ar)) + +# link several objects files into one shared object +$(filtered-all-ar): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call ar_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call ar_cmd,$(pre-$(@)),$@),$?),\ + $(call ar_print_cmd,$(pre-$(@)),$@) && \ + $(call ar_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call ar_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-ar-vars.mk b/mk/ecoli-ar-vars.mk new file mode 100644 index 0000000..7d2fab7 --- /dev/null +++ b/mk/ecoli-ar-vars.mk @@ -0,0 +1,75 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# ar-y-$(ar) is provided by the user +# $(ar) is the path of the static library, and the variable contains +# the list of sources. Several ar-y-$(ar) can be present. + +# list all ar builds requested by user +all-ar := $(patsubst ar-y-%,%,$(filter ar-y-%,$(.VARIABLES))) + +# add them to the list of targets +all-targets += $(all-ar) + +# for each ar, create the following variables: +# out-$(ar) = output path of the arcutable +# pre-$(ar) = list of prerequisites for this arcutable +# Some source files need intermediate objects, we define these variables +# for them too, and add them in a list: $(all-iobj). +# Last, we add the generated files in $(all-clean-file). +$(foreach ar,$(all-ar),\ + $(eval out-$(ar) := $(dir $(ar))) \ + $(eval pre-$(ar) := ) \ + $(foreach src,$(ar-y-$(ar)), \ + $(if $(call is_cc_source,$(src)), \ + $(eval iobj := $(call src2iobj,$(src),$(out-$(ar)))) \ + $(eval pre-$(iobj) := $(src)) \ + $(eval all-iobj += $(iobj)) \ + $(eval all-clean-file += $(iobj)) \ + $(eval pre-$(ar) += $(iobj)) \ + , \ + $(if $(call is_obj_source,$(src)),\ + $(eval pre-$(ar) += $(src)) \ + , \ + $(error "unsupported source format: $(src)"))) \ + )\ + $(eval all-clean-file += $(ar)) \ +) + +# link several *.o files into a static libary +# $1: sources (*.o) +# $2: dst (xyz.a) +ar_cmd = ar crsD $(2) $(1) + +# print line used to ar object files +ifeq ($(V),1) +ar_print_cmd = echo $(call protect_quote,$(call ar_cmd,$1,$2)) +else +ar_print_cmd = echo " AR $(2)" +endif + +all-clean-file += $(all-ar) diff --git a/mk/ecoli-clean-rules.mk b/mk/ecoli-clean-rules.mk new file mode 100644 index 0000000..7c5113d --- /dev/null +++ b/mk/ecoli-clean-rules.mk @@ -0,0 +1,33 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +.PHONY: _ecoli_clean +_ecoli_clean: $(all-clean-target) FORCE + @$(call clean_print_cmd,$(all-clean-file) $(call depfile,$(all-clean-file)) \ + $(call cmdfile,$(all-clean-file))) && \ + $(call clean_cmd,$(all-clean-file) $(call depfile,$(all-clean-file)) \ + $(call cmdfile,$(all-clean-file))) diff --git a/mk/ecoli-clean-vars.mk b/mk/ecoli-clean-vars.mk new file mode 100644 index 0000000..53f732e --- /dev/null +++ b/mk/ecoli-clean-vars.mk @@ -0,0 +1,37 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# remove files +# $1: files +clean_cmd = rm -rf $(1) + +# print line used to clean files +ifeq ($(V),1) +clean_print_cmd = echo $(call protect_quote,$(call clean_cmd,$1)) +else +clean_print_cmd = echo " CLEAN $(CURDIR)" +endif diff --git a/mk/ecoli-copy-rules.mk b/mk/ecoli-copy-rules.mk new file mode 100644 index 0000000..6602a9e --- /dev/null +++ b/mk/ecoli-copy-rules.mk @@ -0,0 +1,55 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-copy,$(all-copy)) +$(foreach copy,$(all-copy),\ + $(info,out-$(copy): $(out-$(copy))) \ + $(call disp_list,pre-$(copy),$(pre-$(copy))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach copy,$(all-copy),\ + $(eval -include $(call depfile,$(copy))) \ + $(eval -include $(call cmdfile,$(copy))) \ +) + +# remove duplicates +filtered-all-copy := $(sort $(all-copy)) + +# convert format of executable +$(filtered-all-copy): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call copy_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call copy_cmd,$(pre-$(@)),$@),$?),\ + $(call copy_print_cmd,$(pre-$(@)),$@) && \ + $(call copy_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call copy_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-copy-vars.mk b/mk/ecoli-copy-vars.mk new file mode 100644 index 0000000..677274e --- /dev/null +++ b/mk/ecoli-copy-vars.mk @@ -0,0 +1,74 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# copy a file +# copy-y-$(copy) is provided by the user +# $(copy) is the path of the directory containing the destination +# files, and the variable contains the path of the files to copy. Several +# copy-y-$(copy) can be present. + +# list all path requested by user +_all-copy := $(patsubst copy-y-%,%,$(filter copy-y-%,$(.VARIABLES))) +all-copy := + +# for each copy, create the following variables: +# out-$(copy) = output path of the executable +# pre-$(copy) = list of prerequisites for this executable +# We also add the files in $(all-copy). +$(foreach copy,$(_all-copy),\ + $(if $(notdir $(copy)), \ + $(if $(call compare,$(words $(copy-y-$(copy))),1), \ + $(error "only one source file is allowed in copy-y-$(copy)")) \ + $(eval dst := $(dir $(copy))$(notdir $(copy-y-$(copy)))) \ + $(eval out-$(copy) := $(dir $(copy))) \ + $(eval pre-$(copy) := $(copy-y-$(copy))) \ + $(eval all-copy += $(dst)) \ + , \ + $(foreach src,$(copy-y-$(copy)),\ + $(eval dst := $(copy)$(notdir $(src))) \ + $(eval out-$(copy) := $(copy)) \ + $(eval pre-$(dst) := $(src)) \ + $(eval all-copy += $(dst)) \ + ) \ + ) \ +) + +# add them to the list of targets and clean +all-targets += $(all-copy) +all-clean-file += $(all-copy) + +# convert format of executable from elf to ihex +# $1: source executable (elf) +# $2: destination file +copy_cmd = $(CP) $(1) $(2) + +# print line used to convert executable format +ifeq ($(V),1) +copy_print_cmd = echo $(call protect_quote,$(call copy_cmd,$1,$2)) +else +copy_print_cmd = echo " COPY $(2)" +endif diff --git a/mk/ecoli-exe-rules.mk b/mk/ecoli-exe-rules.mk new file mode 100644 index 0000000..a1a5c42 --- /dev/null +++ b/mk/ecoli-exe-rules.mk @@ -0,0 +1,55 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-exe,$(all-exe)) +$(foreach exe,$(all-exe),\ + $(info,out-$(exe): $(out-$(exe))) \ + $(call disp_list,pre-$(exe),$(pre-$(exe))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach exe,$(all-exe),\ + $(eval -include $(call depfile,$(exe))) \ + $(eval -include $(call cmdfile,$(exe))) \ +) + +# remove duplicates +filtered-all-exe := $(sort $(all-exe)) + +# link several objects files into one executable +$(filtered-all-exe): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call link_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call link_cmd,$(pre-$(@)),$@),$?),\ + $(call link_print_cmd,$(pre-$(@)),$@) && \ + $(call link_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call link_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-exe-vars.mk b/mk/ecoli-exe-vars.mk new file mode 100644 index 0000000..f980be4 --- /dev/null +++ b/mk/ecoli-exe-vars.mk @@ -0,0 +1,79 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# exe-y-$(exe) is provided by the user +# $(exe) is the path of the binary, and the variable contains +# the list of sources. Several exe-y-$(exe) can be present. + +# list all exe builds requested by user +all-exe := $(patsubst exe-y-%,%,$(filter exe-y-%,$(.VARIABLES))) + +# add them to the list of targets +all-targets += $(all-exe) + +# for each exe, create the following variables: +# out-$(exe) = output path of the executable +# pre-$(exe) = list of prerequisites for this executable +# Some source files need intermediate objects, we define these variables +# for them too, and add them in a list: $(all-iobj). +# Last, we add the generated files in $(all-clean-file). +$(foreach exe,$(all-exe),\ + $(eval out-$(exe) := $(dir $(exe))) \ + $(eval pre-$(exe) := ) \ + $(foreach src,$(exe-y-$(exe)), \ + $(if $(call is_cc_source,$(src)), \ + $(eval iobj := $(call src2iobj,$(src),$(out-$(exe)))) \ + $(eval pre-$(iobj) := $(src)) \ + $(eval all-iobj += $(iobj)) \ + $(eval all-clean-file += $(iobj)) \ + $(eval pre-$(exe) += $(iobj)) \ + , \ + $(if $(call is_obj_source,$(src)),\ + $(eval pre-$(exe) += $(src)) \ + , \ + $(if $(call is_alib_source,$(src)),\ + $(eval pre-$(exe) += $(src)) \ + , \ + $(error "unsupported source format: $(src)")))) \ + )\ + $(eval all-clean-file += $(exe)) \ +) + +# link several *.o files into a exeary +# $1: sources (*.o) (*.a) +# $2: dst (xyz.o too) +link_cmd = $(CC) $(LDFLAGS) $(ldflags-$(2)) -o $(2) $(filter %.o,$(1)) \ + $(filter %.a,$(1)) $(LDLIBS) $(ldlibs-$(2)) + +# print line used to link object files +ifeq ($(V),1) +link_print_cmd = echo $(call protect_quote,$(call link_cmd,$1,$2)) +else +link_print_cmd = echo " EXE $(2)" +endif + +all-clean-file += $(all-exe) diff --git a/mk/ecoli-obj-rules.mk b/mk/ecoli-obj-rules.mk new file mode 100644 index 0000000..af208e4 --- /dev/null +++ b/mk/ecoli-obj-rules.mk @@ -0,0 +1,83 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-obj,$(all-obj)) +$(foreach obj,$(all-obj),\ + $(info,out-$(obj): $(out-$(obj))) \ + $(call disp_list,pre-$(obj),$(pre-$(obj))) \ +) +$(call disp_list,------ all-iobj,$(all-iobj)) +$(foreach iobj,$(all-iobj),\ + $(call disp_list,pre-$(iobj),$(pre-$(iobj))) \ +) +endif + +# if a generated file has the same name than a user target, +# generate an error +conflicts := $(filter $(all-iobj),$(all-targets)) +$(if $(conflicts), \ + $(error Intermediate file has the same names than user targets:\ + $(conflicts))) + +# include dependencies and commands files if they exist +$(foreach obj,$(all-obj),\ + $(eval -include $(call depfile,$(obj))) \ + $(eval -include $(call cmdfile,$(obj))) \ +) +$(foreach iobj,$(all-iobj),\ + $(eval -include $(call depfile,$(iobj))) \ + $(eval -include $(call cmdfile,$(iobj))) \ +) + +# remove duplicates +filtered-all-iobj := $(sort $(all-iobj)) + +# convert source files to intermediate object file +$(filtered-all-iobj): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,$(call compile_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call compile_cmd,$(pre-$(@)),$@),$?),\ + $(call compile_print_cmd,$(pre-$(@)),$@) && \ + $(call compile_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call compile_cmd,$(pre-$(@)),$@),$@) && \ + $(call obj-fixdep,$@)) + +# remove duplicates +filtered-all-obj := $(sort $(all-obj)) + +# combine several objects files to one +$(filtered-all-obj): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call combine_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call combine_cmd,$(pre-$(@)),$@),$?),\ + $(call combine_print_cmd,$(pre-$(@)),$@) && \ + $(call combine_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call combine_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-obj-vars.mk b/mk/ecoli-obj-vars.mk new file mode 100644 index 0000000..8bd9101 --- /dev/null +++ b/mk/ecoli-obj-vars.mk @@ -0,0 +1,124 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# obj-y-$(obj) is provided by the user +# $(obj) is the path of the object, and the variable contains +# the list of sources. Several obj-y-$(obj) can be present. + +# list all object builds requested by user +all-obj := $(patsubst obj-y-%,%,$(filter obj-y-%,$(.VARIABLES))) + +# add them to the list of targets +all-targets += $(all-obj) + +# convert source path to intermediate object path, and filter +# objects from sources +# $1: list of source paths +# $2: output directory (including trailing slash) +# return: list of intermediate object paths +src2iobj = $(addprefix $(filter-out ./,$(2)),$(notdir $(strip \ + $(patsubst %.c,%.o,\ + $(patsubst %.s,%.o,\ + $(filter-out %.o,$(1))))))) + +# return the file if it matches a extension that is built with cc +# $1: source file +is_cc_source = $(filter %.c %.s %S,$(1)) + +# return the file if it's already an object file: in this case no +# intermediate object is needed +# $1: source file +is_obj_source = $(filter %.o,$(1)) + +# return the file if it's a static library +# $1: source file +is_alib_source = $(filter %.a,$(1)) + +# for each obj, create the following variables: +# out-$(obj) = output path of the object +# pre-$(obj) = list of prerequisites for this object +# Some source files need intermediate objects, we define these variables +# for them too, and add them in a list: $(all-iobj). +# Last, we add the generated files in $(all-clean-file). +$(foreach obj,$(all-obj),\ + $(eval out-$(obj) := $(dir $(obj))) \ + $(eval pre-$(obj) := ) \ + $(foreach src,$(obj-y-$(obj)), \ + $(if $(call is_cc_source,$(src)), \ + $(eval iobj := $(call src2iobj,$(src),$(out-$(obj)))) \ + $(eval pre-$(iobj) := $(src)) \ + $(eval all-iobj += $(iobj)) \ + $(eval all-clean-file += $(iobj)) \ + $(eval pre-$(obj) += $(iobj)) \ + , \ + $(if $(call is_obj_source,$(src)),\ + $(eval pre-$(obj) += $(src)) \ + , \ + $(error "unsupported source format: $(src)"))) \ + )\ + $(eval all-clean-file += $(obj)) \ +) + +# fix the format of .o.d.tmp (generated by gcc) to a .o.d that defines +# dependencies as makefile variables +# $1: object file (.o) +obj-fixdep = if [ -f $(call file2tmpdep,$(1)) ]; then\ + echo -n "dep-$(1) = " > $(call depfile,$(1)) && \ + sed 's,^[^ ][^:]*: ,,' $(call file2tmpdep,$(1)) >> $(call depfile,$(1)) && \ + rm -f $(call file2tmpdep,$(1)); \ + else \ + $(call create_empty_depfile,$(1)); \ + fi + +# compile a file +# $1: sources +# $2: dst +compile_cmd = $(CC) -Wp,-MD,$(call file2tmpdep,$(2)) \ + $(CPPFLAGS) $(cppflags-$(2)) \ + $(CFLAGS) $(cflags-$(2)) \ + -c -o $2 $1 + +# print line used to compile a file +ifeq ($(V),1) +compile_print_cmd = echo $(call protect_quote,$(call compile_cmd,$1,$2)) +else +compile_print_cmd = echo " CC $(2)" +endif + +# combine several *.o files into one +# $1: sources (*.o) +# $2: dst (xyz.o too) +combine_cmd = $(LD) -r $(1) -o $(2) + +# print line used to combine object files +ifeq ($(V),1) +combine_print_cmd = echo $(call protect_quote,$(call combine_cmd,$1,$2)) +else +combine_print_cmd = echo " LD $(2)" +endif + +all-clean-file += $(all-obj) diff --git a/mk/ecoli-objcopy-rules.mk b/mk/ecoli-objcopy-rules.mk new file mode 100644 index 0000000..86a7cb6 --- /dev/null +++ b/mk/ecoli-objcopy-rules.mk @@ -0,0 +1,74 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-objcopy-hex,$(all-objcopy-hex)) +$(foreach objcopy,$(all-objcopy-hex),\ + $(info,out-$(objcopy): $(out-$(objcopy))) \ + $(call disp_list,pre-$(objcopy),$(pre-$(objcopy))) \ +) +$(call disp_list,------ all-objcopy-bin,$(all-objcopy-bin)) +$(foreach objcopy,$(all-objcopy-bin),\ + $(info,out-$(objcopy): $(out-$(objcopy))) \ + $(call disp_list,pre-$(objcopy),$(pre-$(objcopy))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach objcopy,$(all-objcopy-hex) $(all-objcopy-bin),\ + $(eval -include $(call depfile,$(objcopy))) \ + $(eval -include $(call cmdfile,$(objcopy))) \ +) + +# remove duplicates +filtered-all-objcopy-hex := $(sort $(all-objcopy-hex)) + +# convert format of executable +$(filtered-all-objcopy-hex): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call objcopy_hex_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call objcopy_hex_cmd,$(pre-$(@)),$@),$?),\ + $(call objcopy_print_cmd,$(pre-$(@)),$@) && \ + $(call objcopy_hex_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call objcopy_hex_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) + +# remove duplicates +filtered-all-objcopy-bin := $(sort $(all-objcopy-bin)) + +# convert format of executable +$(filtered-all-objcopy-bin): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call objcopy_bin_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call objcopy_bin_cmd,$(pre-$(@)),$@),$?),\ + $(call objcopy_print_cmd,$(pre-$(@)),$@) && \ + $(call objcopy_bin_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call objcopy_bin_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-objcopy-vars.mk b/mk/ecoli-objcopy-vars.mk new file mode 100644 index 0000000..d515d02 --- /dev/null +++ b/mk/ecoli-objcopy-vars.mk @@ -0,0 +1,89 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# objcopy changes the format of a binary +# objcopy-hex-y-$(objcopy), objcopy-bin-y-$(objcopy) are provided by the user +# $(objcopy) is the path of the binary, and the variable contains +# the path to the elf. Several objcopy-y-$(objcopy) can be present. + +# list all executable builds requested by user +all-objcopy-hex := $(patsubst objcopy-hex-y-%,%,$(filter objcopy-hex-y-%,$(.VARIABLES))) +all-objcopy-bin := $(patsubst objcopy-bin-y-%,%,$(filter objcopy-bin-y-%,$(.VARIABLES))) + +# add them to the list of targets +all-targets += $(all-objcopy-hex) $(all-objcopy-bin) + +# for each objcopy, create the following variables: +# out-$(objcopy) = output path of the executable +# pre-$(objcopy) = list of prerequisites for this executable +# We also add the generated files in $(all-clean-file). +$(foreach objcopy,$(all-objcopy-hex),\ + $(if $(call compare,$(words $(objcopy-hex-y-$(objcopy))),1),\ + $(error "only one source file is allowed in objcopy-hex-y-$(objcopy)")) \ + $(eval out-$(objcopy) := $(dir $(objcopy))) \ + $(eval pre-$(objcopy) := $(objcopy-hex-y-$(objcopy))) \ + $(eval all-clean-file += $(objcopy)) \ +) + +# for each objcopy, create the following variables: +# out-$(objcopy) = output path of the executable +# pre-$(objcopy) = list of prerequisites for this executable +# We also add the generated files in $(all-clean-file). +$(foreach objcopy,$(all-objcopy-bin),\ + $(if $(call compare,$(words $(objcopy-bin-y-$(objcopy))),1),\ + $(error "only one source file is allowed in objcopy-bin-y-$(objcopy)")) \ + $(eval out-$(objcopy) := $(dir $(objcopy))) \ + $(eval pre-$(objcopy) := $(objcopy-bin-y-$(objcopy))) \ + $(eval all-clean-file += $(objcopy)) \ +) + +# convert format of executable from elf to ihex +# $1: source executable (elf) +# $2: destination file +objcopy_hex_cmd = $(OBJCOPY) -O ihex $(1) $(2) + +# print line used to convert executable format +ifeq ($(V),1) +objcopy_print_cmd = echo $(call protect_quote,$(call objcopy_hex_cmd,$1,$2)) +else +objcopy_print_cmd = echo " OBJCOPY $(2)" +endif + +# convert format of executable from elf to binary +# $1: source executable (elf) +# $2: destination file +objcopy_bin_cmd = $(OBJCOPY) -O binary $(1) $(2) + +# print line used to convert executable format +ifeq ($(V),1) +objcopy_print_cmd = echo $(call protect_quote,$(call objcopy_bin_cmd,$1,$2)) +else +objcopy_print_cmd = echo " OBJCOPY $(2)" +endif + +# XXX dup ? +all-clean-file += $(all-objcopy-hex) $(all-objcopy-bin) diff --git a/mk/ecoli-post.mk b/mk/ecoli-post.mk new file mode 100644 index 0000000..e51566e --- /dev/null +++ b/mk/ecoli-post.mk @@ -0,0 +1,108 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# ---- variables that must be defined: +# +# ECOLI: path to ecoli root +# +# ---- variable that can be defined anywhere +# +# CROSS: prefix of the toolchain +# CP, LN, GAWK, GREP: coreutils tools +# CC, CPP, AR, LD, OBJCOPY, OBJDUMP, STRIP: compilers/binutils +# +# ---- variable that can be defined by Makefile: +# +# obj-y-$(path) +# exe-y-$(path) +# ar-y-$(path) +# shlib-y-$(path) +# copy-y-$(path) +# slink-y-$(path) +# objcopy-y-$(path) +# subdir-y +# +# CPPFLAGS, CFLAGS, LDFLAGS, LDLIBS: global flags +# cflags-$(path), cppflags-$(path), ldflags-$(path), ldlibs-$(path): per +# file flags +# mkflags-$(path): flags for subdirectories +# +# ---- variables that can be defined on the command line: +# +# EXTRA_CPPFLAGS, EXTRA_CFLAGS, EXTRA_LDFLAGS, EXTRA_LDLIBS: global +# extra flags +# extra-cflags-$(path), extra-cppflags-$(path): per object extra flags + +ifeq ($(ECOLI),) +$(error ECOLI environment variable is not defined) +endif + +# list of targets asked by user +all-targets := +# list of files generated +all-clean-file := + +# usual internal variables: +# out-$(file) = output path of a generated file +# pre-$(file) = list of files needed to generate $(file) +# all-type = list of targets for this type + +include $(ECOLI)/mk/ecoli-obj-vars.mk +include $(ECOLI)/mk/ecoli-exe-vars.mk +include $(ECOLI)/mk/ecoli-ar-vars.mk +include $(ECOLI)/mk/ecoli-shlib-vars.mk +include $(ECOLI)/mk/ecoli-copy-vars.mk +include $(ECOLI)/mk/ecoli-slink-vars.mk +include $(ECOLI)/mk/ecoli-objcopy-vars.mk +include $(ECOLI)/mk/ecoli-subdir-vars.mk +# must stay at the end +include $(ECOLI)/mk/ecoli-clean-vars.mk + +# dump the list of targets +ifeq ($(D),1) +$(call disp_list,------ all-targets,$(all-targets)) +endif + +# first rule (default) +.PHONY: _ecoli_all +_ecoli_all: $(all-targets) + +# the includes below require second expansion +.SECONDEXPANSION: + +include $(ECOLI)/mk/ecoli-obj-rules.mk +include $(ECOLI)/mk/ecoli-exe-rules.mk +include $(ECOLI)/mk/ecoli-ar-rules.mk +include $(ECOLI)/mk/ecoli-shlib-rules.mk +include $(ECOLI)/mk/ecoli-copy-rules.mk +include $(ECOLI)/mk/ecoli-slink-rules.mk +include $(ECOLI)/mk/ecoli-objcopy-rules.mk +include $(ECOLI)/mk/ecoli-subdir-rules.mk +include $(ECOLI)/mk/ecoli-clean-rules.mk + +.PHONY: FORCE +FORCE: diff --git a/mk/ecoli-pre.mk b/mk/ecoli-pre.mk new file mode 100644 index 0000000..9cc59e9 --- /dev/null +++ b/mk/ecoli-pre.mk @@ -0,0 +1,42 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# ---- variables that must be defined: +# +# ECOLI: path to ecoli root +# + +ifeq ($(ECOLI),) +$(error ECOLI environment variable is not defined) +endif + +MAKEFLAGS += --no-print-directory + +include $(ECOLI)/mk/ecoli-tools.mk + +include $(ECOLI)/mk/ecoli-vars.mk + diff --git a/mk/ecoli-shlib-rules.mk b/mk/ecoli-shlib-rules.mk new file mode 100644 index 0000000..1a131cc --- /dev/null +++ b/mk/ecoli-shlib-rules.mk @@ -0,0 +1,55 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-shlib,$(all-shlib)) +$(foreach shlib,$(all-shlib),\ + $(info,out-$(shlib): $(out-$(shlib))) \ + $(call disp_list,pre-$(shlib),$(pre-$(shlib))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach shlib,$(all-shlib),\ + $(eval -include $(call depfile,$(shlib))) \ + $(eval -include $(call cmdfile,$(shlib))) \ +) + +# remove duplicates +filtered-all-shlib := $(sort $(all-shlib)) + +# link several objects files into one shared object +$(filtered-all-shlib): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call shlib_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call shlib_cmd,$(pre-$(@)),$@),$?),\ + $(call shlib_print_cmd,$(pre-$(@)),$@) && \ + $(call shlib_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call shlib_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-shlib-vars.mk b/mk/ecoli-shlib-vars.mk new file mode 100644 index 0000000..7906510 --- /dev/null +++ b/mk/ecoli-shlib-vars.mk @@ -0,0 +1,76 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# shlib-y-$(shlib) is provided by the user +# $(shlib) is the path of the shared library, and the variable +# contains the list of sources. Several shlib-y-$(shlib) can be +# present. + +# list all shlib builds requested by user +all-shlib := $(patsubst shlib-y-%,%,$(filter shlib-y-%,$(.VARIABLES))) + +# add them to the list of targets +all-targets += $(all-shlib) + +# for each shlib, create the following variables: +# out-$(shlib) = output path of the shlibcutable +# pre-$(shlib) = list of prerequisites for this shlibcutable +# Some source files need intermediate objects, we define these variables +# for them too, and add them in a list: $(all-iobj). +# Last, we add the generated files in $(all-clean-file). +$(foreach shlib,$(all-shlib),\ + $(eval out-$(shlib) := $(dir $(shlib))) \ + $(eval pre-$(shlib) := ) \ + $(foreach src,$(shlib-y-$(shlib)), \ + $(if $(call is_cc_source,$(src)), \ + $(eval iobj := $(call src2iobj,$(src),$(out-$(shlib)))) \ + $(eval pre-$(iobj) := $(src)) \ + $(eval all-iobj += $(iobj)) \ + $(eval all-clean-file += $(iobj)) \ + $(eval pre-$(shlib) += $(iobj)) \ + , \ + $(if $(call is_obj_source,$(src)),\ + $(eval pre-$(shlib) += $(src)) \ + , \ + $(error "unsupported source format: $(src)"))) \ + )\ + $(eval all-clean-file += $(shlib)) \ +) + +# link several *.o files into a shared libary +# $1: sources (*.o) +# $2: dst (xyz.so) +shlib_cmd = $(CC) $(LDFLAGS) $(ldflags-$(2)) -shared -o $(2) $(1) + +# print line used to shlib object files +ifeq ($(V),1) +shlib_print_cmd = echo $(call protect_quote,$(call shlib_cmd,$1,$2)) +else +shlib_print_cmd = echo " SHLIB $(2)" +endif + +all-clean-file += $(all-shlib) diff --git a/mk/ecoli-slink-rules.mk b/mk/ecoli-slink-rules.mk new file mode 100644 index 0000000..bea3aad --- /dev/null +++ b/mk/ecoli-slink-rules.mk @@ -0,0 +1,55 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# dump some infos if debug is enabled +ifeq ($(D),1) +$(call disp_list,------ all-slink,$(all-slink)) +$(foreach slink,$(all-slink),\ + $(info,out-$(slink): $(out-$(slink))) \ + $(call disp_list,pre-$(slink),$(pre-$(slink))) \ +) +endif + +# include dependencies and commands files if they exist +$(foreach slink,$(all-slink),\ + $(eval -include $(call depfile,$(slink))) \ + $(eval -include $(call cmdfile,$(slink))) \ +) + +# remove duplicates +filtered-all-slink := $(sort $(all-slink)) + +# convert format of executable +$(filtered-all-slink): $$(pre-$$@) $$(wildcard $$(dep-$$@)) FORCE + @[ -d $(dir $@) ] || mkdir -p $(dir $@) + @$(call display_deps,$(pre-$(@)),$@,\ + $(call slink_cmd,$(pre-$(@)),$@),$?) + @$(if $(call check_deps,$@,$(call slink_cmd,$(pre-$(@)),$@),$?),\ + $(call slink_print_cmd,$(pre-$(@)),$@) && \ + $(call slink_cmd,$(pre-$(@)),$@) && \ + $(call save_cmd,$(call slink_cmd,$(pre-$(@)),$@),$@) && \ + $(call create_empty_depfile,$@)) diff --git a/mk/ecoli-slink-vars.mk b/mk/ecoli-slink-vars.mk new file mode 100644 index 0000000..428cb25 --- /dev/null +++ b/mk/ecoli-slink-vars.mk @@ -0,0 +1,74 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# create a symbolic link of a file +# slink-y-$(slink) is provided by the user +# $(slink) is the path of the directory containing the destination +# files, and the variable contains the path of the files to linked. Several +# slink-y-$(slink) can be present. + +# list all path requested by user +_all-slink := $(patsubst slink-y-%,%,$(filter slink-y-%,$(.VARIABLES))) +all-slink := + +# for each slink, create the following variables: +# out-$(slink) = output path of the executable +# pre-$(slink) = list of prerequisites for this executable +# We also add the files in $(all-slink). +$(foreach slink,$(_all-slink),\ + $(if $(notdir $(slink)), \ + $(if $(call compare,$(words $(slink-y-$(slink))),1), \ + $(error "only one source file is allowed in slink-y-$(slink)")) \ + $(eval dst := $(dir $(slink))$(notdir $(slink-y-$(slink)))) \ + $(eval out-$(slink) := $(dir $(slink))) \ + $(eval pre-$(slink) := $(slink-y-$(slink))) \ + $(eval all-slink += $(dst)) \ + , \ + $(foreach src,$(slink-y-$(slink)),\ + $(eval dst := $(slink)$(notdir $(src))) \ + $(eval out-$(slink) := $(slink)) \ + $(eval pre-$(dst) := $(src)) \ + $(eval all-slink += $(dst)) \ + ) \ + ) \ +) + +# add them to the list of targets and clean +all-targets += $(all-slink) +all-clean-file += $(all-slink) + +# convert format of executable from elf to ihex +# $1: source executable (elf) +# $2: destination file +slink_cmd = $(LN) -nsf $(abspath $(1)) $(2) + +# print line used to convert executable format +ifeq ($(V),1) +slink_print_cmd = echo $(call protect_quote,$(call slink_cmd,$1,$2)) +else +slink_print_cmd = echo " SLINK $(2)" +endif diff --git a/mk/ecoli-subdir-rules.mk b/mk/ecoli-subdir-rules.mk new file mode 100644 index 0000000..aae82db --- /dev/null +++ b/mk/ecoli-subdir-rules.mk @@ -0,0 +1,30 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +.PHONY: $(subdir-y) +$(subdir-y): FORCE + $(Q)$(MAKE) -C $(@) $(mkflags-$(@)) $(MAKECMDGOALS) diff --git a/mk/ecoli-subdir-vars.mk b/mk/ecoli-subdir-vars.mk new file mode 100644 index 0000000..14e4ee1 --- /dev/null +++ b/mk/ecoli-subdir-vars.mk @@ -0,0 +1,33 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# subdir-y is provided by the user +# it contains the list of directory to build + +# add them to the list of targets +all-targets += $(subdir-y) +all-clean-target += $(subdir-y) diff --git a/mk/ecoli-tools.mk b/mk/ecoli-tools.mk new file mode 100644 index 0000000..484262b --- /dev/null +++ b/mk/ecoli-tools.mk @@ -0,0 +1,159 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +empty:= +space:= $(empty) $(empty) +indent:= $(space)$(space) + +# define a newline char, useful for debugging with $(info) +define newline + + +endef + +# $(prefix shell commands with $(Q) to silent them, except if V=1 +Q=@ +ifeq ("$(V)-$(origin V)", "1-command line") +Q= +endif + +# set variable $1 to $2 if the variable has an implicit value or +# is not defined +# $1 variable name +# $2 new variable content +set_default = $(if \ + $(call not,$(or \ + $(compare $(origin $(1)),default), \ + $(compare $(origin $(1)),undefined) \ + )),\ + $(eval $(1) = $(2)) \ +) + +# display a list +# $1 title +# $2 list +disp_list = $(info $(1)$(newline)\ + $(addsuffix $(newline),$(addprefix $(space),$(2)))) + +# add a dot in front of the file name +# $1 list of paths +# return: full paths with files prefixed by a dot +dotfile = $(strip $(foreach f,$(1),\ + $(join $(dir $f),.$(notdir $f)))) + +# convert source/obj files into dot-dep filename +# $1 list of paths +# return: full paths with files prefixed by a dot and suffixed with .d +depfile = $(strip $(call dotfile,$(addsuffix .d,$(1)))) + +# convert source/obj files into dot-dep filename +# $1 list of paths +# return: full paths with files prefixed by a dot and suffixed with .d.tmp +file2tmpdep = $(strip $(call dotfile,$(addsuffix .d.tmp,$(1)))) + +# convert source/obj files into dot-cmd filename +# $1 list of paths +# return: full paths with files prefixed by a dot and suffixed with .cmd +cmdfile = $(strip $(call dotfile,$(addsuffix .cmd,$(1)))) + +# add a \ before each quote +protect_quote = $(subst ','\'',$(1)) +#'# editor syntax highlight fix + +# return an non-empty string if $1 is empty, and vice versa +# $1 a string +not = $(if $1,,true) + +# return 1 if parameter is a non-empty string, else 0 +boolean = $(if $1,1,0) + +# return an empty string if string are equal +compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1))) + +# return a non-empty string if a file does not exist +# $1: file +file_missing = $(call compare,$(wildcard $1),$1) + +# return a non-empty string if cmdline changed +# $1: file to be built +# $2: the command to build it +cmdline_changed = $(call compare,$(strip $(cmd-$(1))),$(strip $(2))) + +# return an non-empty string if the .d file does not exist +# $1: the dep file (.d) +depfile_missing = $(call compare,$(wildcard $(1)),$(1)) + +# return a non-empty string if, according to dep-xyz variable, a file +# needed to build $1 does not exist. In this case we need to rebuild +# the file and the .d file. +# $1: file to be built +dep-missing = $(call compare,$(wildcard $(dep-$(1))),$(dep-$(1))) + +# return an empty string if no prereq is newer than target +# $1: list of prerequisites newer than target ($?) +dep-newer = $(strip $(filter-out FORCE,$(1))) + +# display why a file should be re-built +# $1: source files +# $2: dst file +# $3: build command +# $4: all prerequisites newer than target ($?) +ifeq ($(D),1) +display_deps = \ + echo -n "$1 -> $2 " ; \ + echo -n "file_missing=$(call boolean,$(call file_missing,$(2))) " ; \ + echo -n "cmdline_changed=$(call boolean,$(call cmdline_changed,$(2),$(3))) " ; \ + echo -n "depfile_missing=$(call boolean,$(call depfile_missing,$(call depfile,$(2)))) " ; \ + echo -n "dep-missing=$(call boolean,$(call dep-missing,$(2))) " ; \ + echo "dep-newer=$(call boolean,$(call dep-newer,$(4)))" +else +display_deps= +endif + +# return an empty string if a file should be rebuilt +# $1: dst file +# $2: build command +# $3: all prerequisites newer than target ($?) +check_deps = \ + $(or $(call file_missing,$(1)),\ + $(call cmdline_changed,$(1),$(2)),\ + $(call depfile_missing,$(call depfile,$(1))),\ + $(call dep-missing,$(1)),\ + $(call dep-newer,$(3))) + +# create a depfile (.d) with no additional deps +# $1: object file (.o) +create_empty_depfile = echo "dep-$(1) =" > $(call depfile,$(1)) + +# save a command in a file +# $1: command to build the file +# $2: name of the file +save_cmd = echo "cmd-$(2) = $(call protect_quote,$(1))" > $(call cmdfile,$(2)) + +# remove the FORCE target from the list of all prerequisites $+ +# no arguments, use $+ +prereq = $(filter-out FORCE,$(+)) diff --git a/mk/ecoli-vars.mk b/mk/ecoli-vars.mk new file mode 100644 index 0000000..79ece82 --- /dev/null +++ b/mk/ecoli-vars.mk @@ -0,0 +1,47 @@ +# +# Copyright 2015, Olivier MATZ +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the University of California, Berkeley nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# core tools +CP ?= cp +LN ?= ln +GAWK ?= gawk +GREP ?= grep +# compiler and binutils, set_default overrides mk implicit value +# but not command line or standard variables +$(call set_default,CC,$(CROSS)gcc) +$(call set_default,CPP,$(CROSS)cpp) +$(call set_default,AR,$(CROSS)ar) +$(call set_default,LD,$(CROSS)ld) +$(call set_default,OBJCOPY,$(CROSS)objcopy) +$(call set_default,OBJDUMP,$(CROSS)objdump) +$(call set_default,STRIP,$(CROSS)strip) +HOSTCC ?= cc + +CFLAGS += $(EXTRA_CFLAGS) +CPPFLAGS += $(EXTRA_CPPFLAGS) +LDFLAGS += $(EXTRA_LDFLAGS) +LDLIBS += $(EXTRA_LDLIBS) -- 2.39.5