Xifier now discovers typedefs by itself, and doesn't require a wrapper script
authorNick Downing <downing.nick@gmail.com>
Thu, 2 Feb 2017 12:19:36 +0000 (23:19 +1100)
committerNick Downing <downing.nick@gmail.com>
Thu, 2 Feb 2017 12:19:36 +0000 (23:19 +1100)
.gitignore
lib/libc/linux/sys/linux.h
xify/Makefile
xify/cc.sh
xify/xify.c [moved from xify/xifyfilt.c with 69% similarity]
xify/xify.sh [deleted file]

index 0b0f95a..b55d3a2 100644 (file)
@@ -148,4 +148,4 @@ usr.bin/tty
 usr.bin/uniq
 usr.bin/units
 usr.bin/yacc/yacc
-xify/xifyfilt
+xify/xify
index 70e558c..836b7e7 100644 (file)
@@ -5,6 +5,7 @@
 #pragma include <sys/resource.h>
 #pragma include <sys/stat.h>
 #pragma include <sys/types.h>
+#pragma typedef nox_int
 
 #include <sys/resource.h>
 #include <sys/stat.h>
index 892d7e2..0687641 100644 (file)
@@ -1,13 +1,12 @@
 CFLAGS=-fno-strict-aliasing -g -Wall -Wno-char-subscripts -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-parentheses -Wno-strict-aliasing -Wno-unused-result
 
-xifyfilt: xifyfilt.c
-       ${CC} ${CFLAGS} -o $@ xifyfilt.c
+xify: xify.c
+       ${CC} ${CFLAGS} -o $@ xify.c
 
 clean:
-       rm -f xifyfilt *.o
+       rm -f xify *.o
 
-install: xifyfilt
+install: xify
        install cc.sh ${DESTDIR}/bin/cc
        install ld.sh ${DESTDIR}/bin/ld
-       install -s xifyfilt ${DESTDIR}/lib
-       install xify.sh ${DESTDIR}/lib/xify
+       install -s xify ${DESTDIR}/lib
index 0333532..69c38c8 100755 (executable)
@@ -243,20 +243,28 @@ then
       j=
       if test -z "$xflag"
       then
-        j=" $tmp.c"
-      fi
-      if test -n "$debug"
-      then
-        echo $xify $tmp_i$j
-      fi
-      if ! $xify $tmp_i$j
-      then
-        cflag=1
-        eflag=1
-        continue
-      fi
-      if test -n "$xflag"
-      then
+# a bit horrible because we cannot redirect sed output to $tmp.c conditionally
+        if test -n "$debug"
+        then
+          echo $xify $tmp_i "|"sed -e "'s/va_arg(x_argp, x_\\\\(unsigned_\\\\)\\\\?\\\\(short\\\\|int\\\\|long\\\\))/_va_arg_\\\\1\\\\2(x_argp)/g'" ">"$tmp.c
+        fi
+        if ! $xify $tmp_i |sed -e 's/va_arg(x_argp, x_\(unsigned_\)\?\(short\|int\|long\))/_va_arg_\1\2(x_argp)/g' >$tmp.c
+        then
+          cflag=1
+          eflag=1
+          continue
+        fi
+      else
+        if test -n "$debug"
+        then
+          echo $xify $tmp_i "|"sed -e "'s/va_arg(x_argp, x_\\(unsigned_\\)\\?\\(short\\|int\\|long\\))/_va_arg_\\1\\2(x_argp)/g'"
+        fi
+        if ! $xify $tmp_i |sed -e 's/va_arg(x_argp, x_\(unsigned_\)\?\(short\|int\|long\))/_va_arg_\1\2(x_argp)/g'
+        then
+          cflag=1
+          eflag=1
+          continue
+        fi
         cflag=1
         continue
       fi
similarity index 69%
rename from xify/xifyfilt.c
rename to xify/xify.c
index 0bf2959..925b66f 100644 (file)
@@ -63,15 +63,53 @@ int n_typedefs = 11;
 
 char buf[1024];
 
+/* 0 = in statement, first word wasn't typedef */
+/* 1 = beginning of statement, look for typedef */
+/* 2 = in statement, first word was typedef */
+/* 3 = in statement, first word was typedef, got potential name */
+/* 4-7 = in preprocessor line, subtract 4 when newline seen */
+int typedef_state = 1;
+/* "typedef struct { something; } typename;" or "typedef int jmp_buf[7];" */
+/* ignore what's in brackets, counter is only active in typedef_state 2-3 */
+int typedef_count;
+int typedef_str_len;
+char typedef_str_data[1024];
+
 int main(argc, argv) int argc; char **argv; {
+  FILE *fin, *fout;
   char *p, *q, *r;
   int l, m, n;
   int e, i;
 
-  while (fgets(buf, sizeof(buf), stdin)) {
+  if (argc < 2 || strcmp(argv[1], "-") == 0)
+    fin = stdin;
+  else if ((fin = fopen(argv[1], "r")) == 0)
+    abort();
+
+  if (argc < 3 || strcmp(argv[2], "-") == 0)
+    fout = stdout;
+  else if ((fout = fopen(argv[2], "w")) == 0)
+    abort();
+
+  fputs("#include <stdint.h>\n\
+typedef int16_t x_short;\n\
+typedef int32_t x_int;\n\
+typedef int32_t x_long;\n\
+typedef uint16_t x_unsigned_short;\n\
+typedef uint32_t x_unsigned_int;\n\
+typedef uint32_t x_unsigned_long;\n\
+#define _va_arg_short(argp) va_arg(argp, int)\n\
+#define _va_arg_int(argp) va_arg(argp, int)\n\
+#define _va_arg_long(argp) va_arg(argp, int)\n\
+#define _va_arg_unsigned_short(argp) va_arg(argp, unsigned int)\n\
+#define _va_arg_unsigned_int(argp) va_arg(argp, unsigned int)\n\
+#define _va_arg_unsigned_long(argp) va_arg(argp, unsigned int)\n", fout);
+
+  while (fgets(buf, sizeof(buf), fin)) {
     p = buf;
     l = 0;
     if (p[l] == '#') {
+      typedef_state |= 4;
       ++l;
       while (isblank(p[l]))
         ++l;
@@ -92,7 +130,7 @@ int main(argc, argv) int argc; char **argv; {
           else if (p[l] == '"') {
             e = '"';
           include:
-            fwrite(p, ++l, 1, stdout);
+            fwrite(p, ++l, 1, fout);
             p += l;
             for (m = 0; p[m] && p[m] != e; ++m)
               ;
@@ -101,28 +139,28 @@ int main(argc, argv) int argc; char **argv; {
             q = p + l;
             m -= l;
             if (m >= 4 && memcmp(q, "nox_", 4) == 0) {
-              fwrite(p, l, 1, stdout);
+              fwrite(p, l, 1, fout);
               p = q + 4;
               l = m - 4;
             }
             else if (
               (l != 0 || m != 8 || memcmp(p, "setjmp.h", 8) != 0) &&
               (l != 0 || m != 8 || memcmp(p, "stdarg.h", 8) != 0) &&
-              (l != 0 || m != 8 || memcmp(p, "stdint.h", 8) != 0) &&
+              (l != 0 || m != 8 || memcmp(p, "fint.h", 8) != 0) &&
               (l != 0 || m != 9 || memcmp(p, "varargs.h", 9) != 0)
             ) {
 #if 1
-              fwrite(p, l, 1, stdout);
+              fwrite(p, l, 1, fout);
 #else
               fwrite(p - 1, l + m + 2, 1, stderr); /* include <> or "" */
-              fputc('\n', stderr);
+              putc('\n', stderr);
               if (l) {
-                fwrite("../", 3, 1, stdout);
-                fwrite(p, l, 1, stdout);
-                fwrite(".xify/", 6, 1, stdout);
+                fwrite("../", 3, 1, fout);
+                fwrite(p, l, 1, fout);
+                fwrite(".xify/", 6, 1, fout);
               }
 #endif
-              fwrite("x_", 2, 1, stdout);
+              fwrite("x_", 2, 1, fout);
               p = q;
               l = m;
             }
@@ -216,28 +254,52 @@ int main(argc, argv) int argc; char **argv; {
               continue;
             }
           }
-          fwrite(p, l, 1, stdout);
-          fputs(p + l + m, stdout);
+          fwrite(p, l, 1, fout);
+          fputs(p + l + m, fout);
           continue;
         }
         else
           l += m;
-        fwrite(p, l, 1, stdout);
+        fwrite(p, l, 1, fout);
         p += l;
         l = 0;
       }
     }
+    else
+      typedef_state &= 3;
     while (p[l]) {
+      if (isspace(p[l]) || p[l] == '\n') {
+        ++l;
+        while (isspace(p[l]) || p[l] == '\n')
+          ++l;
+        goto flush;
+      }
       if (isalpha(p[l]) || p[l] == '_') {
         ++l;
         while (isalnum(p[l]) || p[l] == '_')
           ++l;
+        switch (typedef_state) {
+        case 1:
+          if (l == 7 && memcmp(p, "typedef", 7) == 0)
+            typedef_state = 2;
+          else
+            typedef_state = 0;
+          break;
+        case 2:
+        case 3:
+          if (typedef_count == 0) {
+            typedef_str_len = l;
+            memcpy(typedef_str_data, p, l);
+            typedef_state = 3;
+          }
+          break;
+        }
         if (
           (l == 6 && memcmp(p, "extern", 6) == 0) ||
           (l == 8 && memcmp(p, "register", 8) == 0) ||
           (l == 6 && memcmp(p, "static", 6) == 0)
         ) {
-          fwrite(p, l, 1, stdout);
+          fwrite(p, l, 1, fout);
           p += l;
           l = 0;
           while (isblank(p[l]))
@@ -259,15 +321,15 @@ int main(argc, argv) int argc; char **argv; {
             while (isblank(q[m]))
               ++m;
             if (q[m] != '*') /* avoid something like: register FILE *fp; */
-              fwrite(" x_int", 6, 1, stdout);
+              fwrite(" x_int", 6, 1, fout);
           found_typedef:
             ;
           }
         else /* maybe something like: register *p; */
-          fwrite(" x_int", 6, 1, stdout);
+          fwrite(" x_int", 6, 1, fout);
         }
         else if (l == 3 && memcmp(p, "int", 3) == 0) {
-          fwrite("x_int", 5, 1, stdout);
+          fwrite("x_int", 5, 1, fout);
           p += l;
           l = 0;
         }
@@ -275,8 +337,8 @@ int main(argc, argv) int argc; char **argv; {
           (l == 5 && memcmp(p, "short", 5) == 0) ||
           (l == 4 && memcmp(p, "long", 4) == 0) 
         ) {
-          fwrite("x_", 2, 1, stdout);
-          fwrite(p, l, 1, stdout);
+          fwrite("x_", 2, 1, fout);
+          fwrite(p, l, 1, fout);
           p += l;
           l = 0;
           while (isblank(p[l]))
@@ -303,7 +365,7 @@ int main(argc, argv) int argc; char **argv; {
             while (isalnum(q[m]) || q[m] == '_')
               ++m;
             if (m == 3 && memcmp(q, "int", 3) == 0) {
-              fwrite("x_unsigned_int", 14, 1, stdout);
+              fwrite("x_unsigned_int", 14, 1, fout);
               p += l + m;
               l = 0;
             }
@@ -311,8 +373,8 @@ int main(argc, argv) int argc; char **argv; {
               (m == 5 && memcmp(q, "short", 5) == 0) ||
               (m == 4 && memcmp(q, "long", 4) == 0) 
             ) {
-              fwrite("x_unsigned_", 11, 1, stdout);
-              fwrite(q, m, 1, stdout);
+              fwrite("x_unsigned_", 11, 1, fout);
+              fwrite(q, m, 1, fout);
               p += l + m;
               l = 0;
               while (isblank(p[l]))
@@ -330,7 +392,7 @@ int main(argc, argv) int argc; char **argv; {
               }
             }
             else if (m != 4 || memcmp(q, "char", 4) != 0) {
-              fwrite("x_unsigned_int", 14, 1, stdout);
+              fwrite("x_unsigned_int", 14, 1, fout);
               p += 8;
               l -= 8;
             }
@@ -347,12 +409,52 @@ int main(argc, argv) int argc; char **argv; {
               memcmp(p, keywords[i].str_data, l) == 0
             )
               goto found_keyword;
-          fwrite("x_", 2, 1, stdout);
+          fwrite("x_", 2, 1, fout);
         found_keyword:
           ;
         }
+        goto flush;
+      }
+      switch (typedef_state) {
+      case 2:
+      case 3:
+        if (p[l] == '{' || p[l] == '[') {
+          ++l;
+          ++typedef_count;
+          goto flush;
+        }
+        if (p[l] == '}' || p[l] == ']' && typedef_count > 0) {
+          ++l;
+          --typedef_count;
+          goto flush;
+        }
+        /* fallthru */
+      case 0:
+      case 1:
+        if (typedef_count == 0) {
+          if (p[l] == ';') {
+            ++l;
+            if (typedef_state == 3) {
+ fwrite("typedef: ", 9, 1, stderr);
+ fwrite(typedef_str_data, typedef_str_len, 1, stderr);
+ putc('\n', stderr);
+              if ((q = malloc(typedef_str_len)) == 0)
+                abort();
+              memcpy(q, typedef_str_data, typedef_str_len);
+              if (n_typedefs >= sizeof(typedefs) / sizeof(struct str))
+                abort();
+              typedefs[n_typedefs].str_len = typedef_str_len;
+              typedefs[n_typedefs].str_data = q;
+              ++n_typedefs;
+            }
+            typedef_state = 1;
+            goto flush;
+          }
+          typedef_state &= ~1;
+        }
+        break;
       }
-      else if (p[l] == '.' && isdigit(p[l + 1])) {
+      if (p[l] == '.' && isdigit(p[l + 1])) {
         l += 2;
         goto decimal;
       }
@@ -396,8 +498,8 @@ int main(argc, argv) int argc; char **argv; {
           if (p[l] == '\\')
             ++l;
           if (p[l] == 0) {
-            fwrite(p, l, 1, stdout);
-            if (fgets(buf, sizeof(buf), stdin) == 0)
+            fwrite(p, l, 1, fout);
+            if (fgets(buf, sizeof(buf), fin) == 0)
               return 0;
             p = buf;
             l = 0;
@@ -411,8 +513,8 @@ int main(argc, argv) int argc; char **argv; {
         l += 2;
         while (p[l] != '*' || p[l + 1] != '/')
           if (p[l] == 0) {
-            fwrite(p, l, 1, stdout);
-            if (fgets(buf, sizeof(buf), stdin) == 0)
+            fwrite(p, l, 1, fout);
+            if (fgets(buf, sizeof(buf), fin) == 0)
               return 0;
             p = buf;
             l = 0;
@@ -423,7 +525,8 @@ int main(argc, argv) int argc; char **argv; {
       }
       else
         ++l;
-      fwrite(p, l, 1, stdout);
+    flush:
+      fwrite(p, l, 1, fout);
       p += l;
       l = 0;
     }
diff --git a/xify/xify.sh b/xify/xify.sh
deleted file mode 100755 (executable)
index 725ab4a..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-(
-  cat <<EOF
-#include <stdint.h>
-
-#define _va_arg_short(argp) va_arg(argp, int)
-#define _va_arg_int(argp) va_arg(argp, int)
-#define _va_arg_long(argp) va_arg(argp, int)
-#define _va_arg_unsigned_short(argp) va_arg(argp, unsigned int)
-#define _va_arg_unsigned_int(argp) va_arg(argp, unsigned int)
-#define _va_arg_unsigned_long(argp) va_arg(argp, unsigned int)
-
-typedef int16_t x_short;
-typedef int32_t x_int;
-typedef int32_t x_long;
-typedef uint16_t x_unsigned_short;
-typedef uint32_t x_unsigned_int;
-typedef uint32_t x_unsigned_long;
-EOF
-  "`dirname "$0"`/xifyfilt" <$1 |sed -e 's/\(extern\|register\|static\) x_int\([        ]\+\(int\|long\|short\|unsigned\|x_Bignum\|x_Iptr\|x_YYSTYPE\|x_bytetoktype\|x_bool\|x_caddr_t\|x_chptr\|x_datum\|x_inttoktype\|x_lgtype\|x_off_t\|x_time_t\|x_u_char\|x_u_int\|x_u_short\|x_u_long\)\)/\1\2/g; s/va_arg(x_argp, x_\(unsigned_\)\?\(short\|int\|long\))/_va_arg_\1\2(x_argp)/g'
-) >$2