aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2015-12-13 16:52:26 -0600
committerRob Landley <rob@landley.net>2015-12-13 16:52:26 -0600
commitf96bb3d8e7ec3882c70b861b998d8573083ffe55 (patch)
treefdf93b80adb5dcbf23ce68202abe5da6ce6c66b7
parentfc7543b7f63c159d966ca6b71caf17f877eae985 (diff)
downloadtoybox-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-xscripts/make.sh13
-rw-r--r--scripts/mktags.c55
-rw-r--r--toys.h1
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);
+ }
+}
diff --git a/toys.h b/toys.h
index 6aa7d479..8bd3be27 100644
--- a/toys.h
+++ b/toys.h
@@ -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