diff options
author | Rob Landley <rob@landley.net> | 2015-12-13 16:52:26 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2015-12-13 16:52:26 -0600 |
commit | f96bb3d8e7ec3882c70b861b998d8573083ffe55 (patch) | |
tree | fdf93b80adb5dcbf23ce68202abe5da6ce6c66b7 | |
parent | fc7543b7f63c159d966ca6b71caf17f877eae985 (diff) | |
download | toybox-f96bb3d8e7ec3882c70b861b998d8573083ffe55.tar.gz |
Start of TAGGED_ARRAY() infrastructure.
This lets you have struct arrays with a string as the first member, ala:
struct {char *name; int x, y} blah thingy[] = TAGGED_ARRAY(BLAH,
{"one", 1, 2}, {"two", 3, 4}, {"three", 5, 6}
);
And it produces #defines for the array index of each, ala:
#define BLAH_one 0
#define BLAH_two 1
#define BLAH_three 2
So you can use thingy[BLAH_two].x and still reorder the elements at will.
Note: if you screw up the array initializers, temporarily replace
TAGGED_ARRAY(BLAH, with { and the ); with }; and the compiler will give you
better error messages. (With the macro the compiler reports errors on the
TAGGED_ARRAY line, not where the comma is missing in its contents.)
Currently the TAGGED_ARRAY( and ); must be on their own lines, and the
{ and start of each attached string must be on the same line.
-rwxr-xr-x | scripts/make.sh | 13 | ||||
-rw-r--r-- | scripts/mktags.c | 55 | ||||
-rw-r--r-- | toys.h | 1 |
3 files changed, 69 insertions, 0 deletions
diff --git a/scripts/make.sh b/scripts/make.sh index 3dd4f90c..e1bc399a 100755 --- a/scripts/make.sh +++ b/scripts/make.sh @@ -210,6 +210,19 @@ then ) > generated/globals.h fi +if [ generated/mktags -ot scripts/mktags.c ] +then + do_loudly $HOSTCC scripts/mktags.c -o generated/mktags || exit 1 +fi + +if isnewer generated/tags.h toys +then + echo -n "generated/tags.h " + + sed -n '/TAGGED_ARRAY(/,/^)/{s/.*TAGGED_ARRAY[(]\([^,]*\),/\1/;p}' \ + toys/*/*.c | generated/mktags > generated/tags.h +fi + echo "generated/help.h" if [ generated/config2help -ot scripts/config2help.c ] then diff --git a/scripts/mktags.c b/scripts/mktags.c new file mode 100644 index 00000000..e6fceeab --- /dev/null +++ b/scripts/mktags.c @@ -0,0 +1,55 @@ +// Process TAGGED_ARRAY() macros to emit TAG_STRING index macros. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char *argv[]) +{ + char *tag = 0; + int idx = 0; + + for (;;) { + char *line = 0, *s; + ssize_t len; + + len = getline(&line, &len, stdin); + if (len<0) break; + while (len && isspace(line[len-1])) line[--len]=0; + + // Very simple parser: If we haven't got a TAG then first line is TAG. + // Then look for { followed by "str" (must be on same line, may have + // more than one per line), for each one emit #define. Current TAG ended + // by ) at start of line. + + if (!tag) { + if (!isalpha(*line)) { + fprintf(stderr, "bad tag %s\n", line); + exit(1); + } + tag = strdup(line); + idx = 0; + + continue; + } + + for (s = line; isspace(*s); s++); + if (*s == ')') tag = 0; + else for (;;) { + char *start; + + while (*s && *s != '{') s++; + while (*s && *s != '"') s++; + if (!*s) break; + + start = ++s; + while (*s && *s != '"') { + if (!isalpha(*s) && !isdigit(*s)) *s = '_'; + s++; + } + printf("% *d\n", + 30-printf("#define %s_%.*s", tag, (int)(s-start), start), ++idx); + } + free(line); + } +} @@ -78,6 +78,7 @@ #include "generated/newtoys.h" #include "generated/flags.h" #include "generated/globals.h" +#include "generated/tags.h" // These live in main.c |