]> git.draconx.ca Git - dxcommon.git/blobdiff - scripts/gen-options.awk
Import getline helper from cdecl99.
[dxcommon.git] / scripts / gen-options.awk
index f1dbb1cb2088c135ac00275c4dc7f5de3a648862..450f85c3713f5aeeea09d93f89aa7acedb10ace7 100755 (executable)
@@ -82,7 +82,9 @@
 #
 #   * the object-like macro LOPT_PACK_BITS expands to an integer constant
 #     expression, suitable for use in #if directives, that specifies the
-#     minimum number of bits required by the encoding.
+#     minimum number of bits required by the encoding.  LOPT_PACK_BITS2
+#     is the same, but rounded up to the next power of two greater than
+#     or equal to 8.
 #
 #   * the object-like macro LOPTS_PACKED_INITIALIZER expands to a
 #     comma-separated sequence of integer constant expressions, suitable
@@ -121,6 +123,10 @@ END {
 }
 
 BEGIN {
+  # Check if "\\\\" in substitutions gives just one backslash.
+  bs = "x"; sub(/x/, "\\\\", bs);
+  bs = (length(bs) == 1 ? "\\\\" : "\\");
+
   has_actions = 0
   sopt_string = ""
   num_options = 0
@@ -152,7 +158,7 @@ $0 ~ /^-/ {
   }
 
   # Extract argument name
-  if (work ~ /^\[=[^\] \t]+\]/) {
+  if (work ~ /^\[=[^ \t]+\]/ && sub(/\]/, "&", work) == 1) {
     if (n = index(work, "]")) {
       arg = substr(work, 3, n-3)
       work = substr(work, n+1)
@@ -175,7 +181,7 @@ $0 ~ /^-/ {
     # packed form is not possible w/ actions
     has_actions = 1;
 
-    n = split(work, a, /,[ \t]*/)
+    n = split(work, a, ",[ \t]*")
     if (n == 2) {
       flag = substr(a[1], 2) ", " substr(a[2], 1, length(a[2])-1)
     } else if (n == 1) {
@@ -207,11 +213,10 @@ $0 ~ /^-/ {
 }
 
 # Ignore any line beginning with a #
-$0 ~ /^#/ { next }
+$0 ~ /^#/ { next; }
 
-lopt {
-  sub(/^[ \t]*/, "")
-  if (!$0) { next }
+NF && lopt != "" {
+  sub(/^[ \t]*/, "");
 
   if (lopt in optionhelp)
     $0 = "\n" $0;
@@ -236,7 +241,7 @@ END {
     lopt_strings = add_to_strtab(lopt_strings, sorted_options[i], offsets)
   }
   gsub(/[^ ]+/, "\"&", lopt_strings)
-  gsub(/ /, "\\0\"\n\t", lopt_strings)
+  gsub(/ /, bs"0\"\n\t", lopt_strings)
 
   print "static const char lopt_strings[] ="
   print "\t" lopt_strings "\";\n"
@@ -316,8 +321,8 @@ END {
       help_offsets[opt] = help_pos
       help_pos += length(help) + 1
 
-      gsub(/"/, "\\\"", help)
-      gsub(/\n/, "\\n\"\n\t    \"", help)
+      gsub(/"/, bs"\"", help)
+      gsub(/\n/, bs"n\"\n\t    \"", help)
       help = "\tPN_(\"" opt "\",\n\t    \"" help "\")"
     }
   }
@@ -358,17 +363,18 @@ END {
 # Currently, this only works if none of the options use action specifications
 # (as these would require encoding user-specified pointer expressions and
 # arbitrary int values).
-function output_packed_macros(i, tmp, accum, max)
+function output_packed_macros(i, tmp, accum, max, totalbits)
 {
-  print "\n#define LOPT_PACK_BITS (LOPT_SC_BITS + LOPT_HA_BITS + LOPT_LS_BITS)";
+  print "";
 
   # determine number of bits to encode offsets in SOPT_STRING
   max = length(sopt_string);
-  accum = 0;
+  totalbits = accum = 0;
   for (i = 1; i <= max; i *= 2) {
     accum++;
   }
   print "#define LOPT_SC_BITS " accum;
+  totalbits += accum;
 
   # determine number of bits to encode has_arg values
   max = 0;
@@ -377,7 +383,9 @@ function output_packed_macros(i, tmp, accum, max)
     if (tmp > max)
       max = tmp;
   }
-  print "#define LOPT_HA_BITS " (max > 1 ? 2 : max > 0 ? 1 : 0);
+  accum = (max > 1 ? 2 : max > 0 ? 1 : 0);
+  print "#define LOPT_HA_BITS " accum;
+  totalbits += accum;
 
   # determine number of bits to encode offsets in lopt_strings
   max = 0;
@@ -391,6 +399,12 @@ function output_packed_macros(i, tmp, accum, max)
     accum++;
   }
   print "#define LOPT_LS_BITS " accum;
+  totalbits += accum;
+
+  print "#define LOPT_PACK_BITS " totalbits;
+  for (i = 8; i < totalbits; i *= 2)
+    ;
+  print "#define LOPT_PACK_BITS2 " i;
 
   # Now emit the packed initializer macro
   print "\n#define LOPTS_PACKED_INITIALIZER \\";
@@ -443,25 +457,28 @@ function output_packed_macros(i, tmp, accum, max)
 # placing them into dst[0] ... dst[n].
 #
 # Returns the number of elements.
-function bucketsort(dst, src, buckets, max, count, i, t)
+function bucketsort(dst, src, max, count, i, t)
 {
+  # Note: ULTRIX 4.5 nawk does not support local array parameters
+  split("", bucketsort_buckets);
+
   for (t in src) {
     i = length(src[t])
     if (i > max) { max = i }
-    buckets[i]++
+    bucketsort_buckets[i]++
   }
 
   for (i = max; i > 0; i--) {
-    if (i in buckets) {
-      t = buckets[i]
-      buckets[i] = count
+    if (i in bucketsort_buckets) {
+      t = bucketsort_buckets[i]
+      bucketsort_buckets[i] = count
       count += t
     }
   }
 
   for (t in src) {
     i = length(t = src[t])
-    dst[buckets[i]++] = t
+    dst[bucketsort_buckets[i]++] = t
   }
 
   return count
@@ -490,15 +507,16 @@ function to_enum(lopt)
 # For optimal results, strings should be added in descending length order.
 function add_to_strtab(strtab, str, offsets, pos)
 {
-    if ( (pos = index(strtab, str " ") - 1) < 0) {
-      pos = length(strtab)
-      if (pos) {
-        strtab = strtab " " str
-        pos++
-      } else {
-        strtab = strtab str
-      }
+  if ( (pos = index(strtab, str " ") - 1) < 0) {
+    pos = length(strtab)
+    if (pos) {
+      strtab = strtab " " str
+      pos++
+    } else {
+      strtab = strtab str
     }
-    offsets[str] = pos
-    return strtab
+  }
+
+  offsets[str] = pos
+  return strtab
 }