#!/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
}
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) {
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)
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
-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.
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])