From 533bc0a7ef345f2f3791b6fa76d9e15a1b6b0956 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Tue, 1 Jan 2019 19:03:33 +0100 Subject: util/kconfig: Add `toada` Ada spec generation tool Converts `auto.conf` to an Ada spec file. Write to $(obj)/cb-config.ads and set the package name to `CB.Config`. Change-Id: I97c060d8a613c74a82a18aff9524ad4b01f9df56 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/31053 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer Reviewed-by: Patrick Georgi --- util/kconfig/Makefile | 5 ++ util/kconfig/toada.c | 145 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 util/kconfig/toada.c (limited to 'util') diff --git a/util/kconfig/Makefile b/util/kconfig/Makefile index 3b00da3cf1..a79229d975 100644 --- a/util/kconfig/Makefile +++ b/util/kconfig/Makefile @@ -344,6 +344,8 @@ $(objk)/nconf: $(patsubst %,$(objk)/%,$(nconf-objs)) $(HOSTCC) $(HOSTCFLAGS) -o $@ $^ $(HOSTLOADLIBES_nconf) $(objk)/conf: $(patsubst %,$(objk)/%,$(conf-objs)) $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -o $@ $^ +$(objk)/toada: $(objk)/toada.o + $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -o $@ $^ $(objk)/mconf.o: $(srck)/mconf.c $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< @@ -382,5 +384,8 @@ $(objk)/lxdialog/lxdialog: $(objk)/dochecklxdialog \ $(objk)/lxdialog/%.o: $(srck)/lxdialog/%.c $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $^ -c -o $@ +$(objk)/toada.o: $(srck)/toada.c + $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) -c -o $@ $< + $(objk)/%.o: HOSTCFLAGS+=-I$(srck) -I$(objk) $(objk)/%.o: HOSTCXXFLAGS+=-I$(srck) -I$(objk) diff --git a/util/kconfig/toada.c b/util/kconfig/toada.c new file mode 100644 index 0000000000..9a11b04498 --- /dev/null +++ b/util/kconfig/toada.c @@ -0,0 +1,145 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +static void print_bool(const char *const name, const bool val) +{ + printf(" %-46s : constant boolean := %s;\n", + name, val ? "true" : "false"); +} + +static void print_hex(const char *const name, const char *val) +{ + unsigned int hexlen; + + printf(" %-46s : constant := 16#", name); + for (hexlen = strlen(val); hexlen > 0;) { + const unsigned int len = hexlen % 4 ? : 4; + char quad[] = "0000"; + unsigned int i; + + for (i = 0; i < len; ++i) + quad[4 - len + i] = val[i]; + printf("%s", quad); + + val += len; + hexlen -= len; + if (hexlen > 0) + printf("_"); + } + printf ("#;\n"); +} + +static void print_dec(const char *const name, const char *const val) +{ + printf(" %-46s : constant := %s;\n", name, val); +} + +static void print_string(const char *const name, const char *const val) +{ + printf(" %-46s : constant string := \"%s\";\n", name, val); +} + +int main(int argc, char *argv[]) +{ + char unset_fmt[256], string_fmt[256], set_fmt[256], line[256]; + char *prefix = "CONFIG", *package = "KConfig"; + + if (argc > 3) { + fprintf(stderr, + "Usage: %s [ []]\n\n", + argv[0]); + return 1; + } + if (argc > 2) + prefix = argv[2]; + if (argc > 1) + package = argv[1]; + + snprintf(set_fmt, sizeof(set_fmt), "%s_%%255[^=]=%%255s", prefix); + snprintf(string_fmt, sizeof(string_fmt), + "%s_%%255[^=]=\"%%255[^\"]\"", prefix); + snprintf(unset_fmt, sizeof(unset_fmt), + "# %s_%%255s is not set", prefix); + + printf("package %s is\n\n", package); + + while (fgets(line, sizeof(line), stdin)) { + char name[256], val[256]; + + if (line[strlen(line) - 1] != '\n') { + fprintf(stderr, + "Line longer than %zu chars, skipping...\n", + sizeof(line) - 1); + while (fgets(line, sizeof(line), stdin)) { + if (line[strlen(line) - 1] == '\n') + break; + } + continue; + } + + if (sscanf(line, unset_fmt, name) == 1) { + print_bool(name, false); + continue; + } + + if (sscanf(line, string_fmt, name, val) == 2) { + print_string(name, val); + continue; + } + + switch (sscanf(line, set_fmt, name, val)) { + case 1: + /* ignore for now, our Kconfig is full of these atm */ + /* fprintf(stderr, "unset non-bool: %s=\n", name); */ + continue; + case 2: + if (strcmp(val, "\"\"") == 0) { + print_string(name, ""); + } else if (strcmp(val, "y") == 0) { + print_bool(name, true); + } else if (strncmp(val, "0x", 2) == 0) { + print_hex(name, val + 2); + } else if (isdigit(val[0])) { + print_dec(name, val); + } else { + fprintf(stderr, + "couldn't parse value '%s' for '%s'\n", + val, name); + } + continue; + default: + break; + } + + unsigned int i = 0; + while (isspace(line[i])) + ++i; + if (line[i] == '#') { + printf(" --%s", line + i + 1); + continue; + } else if (i == strlen(line)) { + continue; + } + + fprintf(stderr, "spurious line:\n%s", line); + } + + printf("\nend %s;\n", package); + return 0; +} -- cgit v1.2.3