]> git.draconx.ca Git - dxcommon.git/commitdiff
gen-strtab.awk: Add options to tweak the output.
authorNick Bowler <nbowler@draconx.ca>
Tue, 3 Jan 2023 02:31:45 +0000 (21:31 -0500)
committerNick Bowler <nbowler@draconx.ca>
Tue, 3 Jan 2023 03:59:46 +0000 (22:59 -0500)
Add a @nozero option to ensure all strings have non-zero offsets
into the strtab.

scripts/gen-strtab.awk
tests/scripts.at

index 1f27b5cbd9788ca6ce2bbe0d681f2f9a0cd3d3fb..118cf54430015cabcf15fab7b1c7db090e73618f 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/awk -f
 #
-# Copyright © 2021 Nick Bowler
+# Copyright © 2021, 2023 Nick Bowler
 #
 # Generate a C string table based on an input string specification file.
 #
 # processing immediately moves on to the next line and the result is as if
 # the comment line were omitted from the input.
 #
+# Options may be used to alter the normal behaviour.  An option is placed
+# on a line by itself beginning with an @ character, and may appear anywhere
+# in the input file.  The following options are defined:
+#
+#   @nozero
+#     All strings will have a non-zero offset in the strtab.
+#
 # A string is defined by beginning a line with an & character, which must
 # be immediately followed by a C identifier.  A nonempty sequence of
 # whitespace (with at most one newline) separates the identifier from the
@@ -58,12 +65,30 @@ END {
 }
 
 BEGIN {
+  opts["zero"] = 1
   collected = ident = ""
   startline = endline = 0
   num_vars = 0
 }
 
-$0 ~ /^[#]/ { next }
+# Comments
+NF == 0 || $0 ~ /^[#]/ { next }
+
+# Options
+sub(/^@/, "", $0) {
+  if (NF == 1) {
+    orig=$1
+    gsub(/-/, "_", $1);
+    val = !sub(/^no_?/, "", $1);
+    if ($1 in opts) {
+      opts[$1] = val;
+    } else {
+      print "error: unrecognized option: @" orig | "cat 1>&2"
+      exit 1
+    }
+  }
+  next
+}
 
 $0 ~ /^[&]/ {
   if (ident) {
@@ -109,6 +134,9 @@ END {
   print "#endif"
   print "\nstatic const char strtab[] ="
 
+  if (!opts["zero"])
+    print "\t\"\\0\"";
+
   for (i = 0; i < count; i++) {
     s = sorted_strings[i]
     gsub(/\\\\/, "\2", s)
@@ -135,7 +163,7 @@ END {
   for (i = 0; i < num_vars; i++) {
     sep = (i+1) != num_vars ? "," : ""
     s = vars[i]
-    o = offsets[strings[s]]
+    o = offsets[strings[s]] + !opts["zero"]
     print "\t" s " = " o sep
     if (o > max) {
       max = o
index 41dfbb43760bcf95cd87792db5101e851cd1d882..f4a4a105fb057ede633b10df765502855e9e3066 100644 (file)
@@ -1,4 +1,4 @@
-dnl Copyright © 2021-2022 Nick Bowler
+dnl Copyright © 2021-2023 Nick Bowler
 dnl
 dnl License WTFPL2: Do What The Fuck You Want To Public License, version 2.
 dnl This is free software: you are free to do what the fuck you want to.
@@ -302,6 +302,34 @@ oneline
 
 AT_CLEANUP
 
+AT_SETUP([gen-strtab.awk @nozero option])
+AT_KEYWORDS([gen-strtab awk script scripts])
+
+AT_DATA([test0.def],
+[[&hello hello
+]])
+AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test0.def >test0.h])
+
+AT_DATA([test1.def],
+[[@nozero
+&hello hello
+]])
+AT_CHECK([$AWK -f "$builddir/scripts/gen-strtab.awk" <test1.def >test1.h])
+
+AT_DATA([test.c],
+[[#include <stdio.h>
+#include HEADER
+int main(void) { printf("%d %s\n", hello, strtab+hello); return 0; }
+]])
+AT_CHECK([$CC -DHEADER='"test0.h"' -o test0$EXEEXT test.c && ./test0$EXEEXT],
+  [0], [[0 hello
+]])
+AT_CHECK([$CC -DHEADER='"test1.h"' -o test1$EXEEXT test.c && ./test1$EXEEXT],
+  [0], [[1 hello
+]])
+
+AT_CLEANUP
+
 AT_SETUP([gen-tree.awk])
 AT_KEYWORDS([gen-tree awk script scripts])