--- /dev/null
+#
+# Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <ecoli_test.h>
+#include <ecoli_tk.h>
+
+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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <sys/queue.h>
+
+#include <ecoli_tk.h>
+
+#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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <ecoli_tk.h>
+
+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;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <sys/queue.h>
+#include <sys/types.h>
+
+#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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ecoli_tk.h>
+#include <ecoli_tk_empty.h>
+
+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));
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <ecoli_tk.h>
+
+struct ec_tk_empty {
+ struct ec_tk gen;
+};
+
+struct ec_tk *ec_tk_empty_new(const char *id);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <ecoli_tk.h>
+#include <ecoli_tk_int.h>
+#include <ecoli_test.h>
+
+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);
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <ecoli_tk.h>
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include <ecoli_tk.h>
+#include <ecoli_tk_or.h>
+#include <ecoli_tk_str.h>
+#include <ecoli_test.h>
+
+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);
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <sys/queue.h>
+
+#include <ecoli_tk.h>
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include <ecoli_tk.h>
+#include <ecoli_tk_seq.h>
+
+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;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <sys/queue.h>
+
+#include <ecoli_tk.h>
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <ecoli_tk.h>
+#include <ecoli_tk_space.h>
+
+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));
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <ecoli_tk.h>
+
+struct ec_tk_space {
+ struct ec_tk gen;
+};
+
+struct ec_tk *ec_tk_space_new(const char *id);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <ecoli_test.h>
+#include <ecoli_tk.h>
+#include <ecoli_tk_str.h>
+
+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);
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <ecoli_tk.h>
+
+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
--- /dev/null
+/*
+ * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include <ecoli_test.h>
+#include <ecoli_tk_str.h>
+#include <ecoli_tk_seq.h>
+#include <ecoli_tk_space.h>
+#include <ecoli_tk_or.h>
+
+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;
+}
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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:
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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
+
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$@))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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,$(+))
--- /dev/null
+#
+# Copyright 2015, Olivier MATZ <zer0@droids-corp.org>
+#
+# 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)