OSDN Git Service

Merge remote-tracking branch 'toybox/master' into HEAD am: b62e8ff3da am: 63a7993a8f
[android-x86/external-toybox.git] / scripts / mkflags.c
index 228cd2f..e0e833c 100644 (file)
@@ -6,10 +6,12 @@
 // This is intentionally crappy code because we control the inputs. It leaks
 // memory like a sieve and segfaults if malloc returns null, but does the job.
 
+#include <unistd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <ctype.h>
 
 struct flag {
   struct flag *next;
@@ -17,12 +19,21 @@ struct flag {
   struct flag *lopt;
 };
 
+int chrtype(char c)
+{
+  if (strchr("?&^-:#|@*; ", c)) return 1;
+  if (strchr("=<>", c)) return 2;
+
+  return 0;
+}
+
 // replace chopped out USE_BLAH() sections with low-ascii characters
 // showing how many flags got skipped
 
 char *mark_gaps(char *flags, char *all)
 {
   char *n, *new, c;
+  int bare = 1;
 
   // Shell feeds in " " for blank args, leading space not meaningful.
   while (isspace(*flags)) flags++;
@@ -30,17 +41,33 @@ char *mark_gaps(char *flags, char *all)
 
   n = new = strdup(all);
   while (*all) {
-    if (*flags == *all) {
-      *(new++) = *(all++);
+    // --longopt parentheticals dealt with as a unit
+    if (*all == '(') {
+      int len = 0;
+
+      while (all[len++] != ')');
+      if (strncmp(flags, all, len)) {
+        // bare longopts need their own skip placeholders
+        if (bare) *(new++) = 1;
+      } else {
+        memcpy(new, all, len);
+        new += len;
+        flags += len;
+      }
+      all += len;
+      continue;
+    }
+    c = *(all++);
+    if (bare) bare = chrtype(c);
+    if (*flags == c) {
+      *(new++) = c;
       *flags++;
       continue;
     }
 
-    c = *(all++);
-    if (strchr("?&^-:#|@*; ", c));
-    else if (strchr("=<>", c)) while (isdigit(*all)) all++;
-    else if (c == '(') while(*(all++) != ')');
-    else *(new++) = 1;
+    c = chrtype(c);
+    if (!c) *(new++) = 1;
+    else if (c==2) while (isdigit(*all)) all++;
   }
   *new = 0;
 
@@ -114,36 +141,38 @@ int main(int argc, char *argv[])
   // See "intentionally crappy", above.
   if (!(out = outbuf)) return 1;
 
-  printf("#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n"
-         "#else\n#define FORCED_FLAG 0\n#endif\n\n");
+  printf("#undef FORCED_FLAG\n#undef FORCED_FLAGLL\n"
+    "#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1LL\n"
+    "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0\n#endif\n\n");
 
   for (;;) {
     struct flag *flist, *aflist, *offlist;
-    char *gaps, *mgaps, c;
+    char *mgaps = 0;
     unsigned bit;
 
-    *command = 0;
+    *command = *flags = *allflags = 0;
     bit = fscanf(stdin, "%255s \"%1023[^\"]\" \"%1023[^\"]\"\n",
                     command, flags, allflags);
 
+    if (getenv("DEBUG"))
+      fprintf(stderr, "command=%s, flags=%s, allflags=%s\n",
+        command, flags, allflags);
+
     if (!*command) break;
     if (bit != 3) {
-      fprintf(stderr, "\nError in %s (duplicate command?)\n", command);
+      fprintf(stderr, "\nError in %s (see generated/flags.raw)\n", command);
       exit(1);
     }
 
     bit = 0;
     printf("// %s %s %s\n", command, flags, allflags);
-    mgaps = mark_gaps(flags, allflags);
-    for (gaps = mgaps; *gaps == 1; gaps++);
-    if (*gaps) c = '"';
-    else {
-      c = ' ';
-      gaps = "0";
-    }
-    printf("#undef OPTSTR_%s\n#define OPTSTR_%s %c%s%c\n",
-            command, command, c, gaps, c);
-    free(mgaps);
+    if (*flags != ' ') mgaps = mark_gaps(flags, allflags);
+    else if (*allflags != ' ') mgaps = allflags;
+    // If command disabled, use allflags for OLDTOY()
+    printf("#undef OPTSTR_%s\n#define OPTSTR_%s ", command, command);
+    if (mgaps) printf("\"%s\"\n", mgaps);
+    else printf("0\n");
+    if (mgaps != allflags) free(mgaps);
 
     flist = digest(flags);
     offlist = aflist = digest(allflags);
@@ -167,28 +196,33 @@ int main(int argc, char *argv[])
     out += strlen(out);
 
     while (aflist) {
+      char *llstr = bit>31 ? "LL" : "";
+
+      // Output flag macro for bare longopts
       if (aflist->lopt) {
         if (flist && flist->lopt &&
             !strcmp(flist->lopt->command, aflist->lopt->command))
         {
-          sprintf(out, "#define FLAG_%s (1<<%d)\n", flist->lopt->command, bit);
+          sprintf(out, "#define FLAG_%s (1%s<<%d)\n", flist->lopt->command,
+            llstr, bit);
           flist->lopt = flist->lopt->next;
-        } else sprintf(out, "#define FLAG_%s (FORCED_FLAG<<%d)\n",
-                       aflist->lopt->command, bit);
+        } else sprintf(out, "#define FLAG_%s (FORCED_FLAG%s<<%d)\n",
+                       aflist->lopt->command, llstr, bit);
         aflist->lopt = aflist->lopt->next;
         if (!aflist->command) {
           aflist = aflist->next;
           bit++;
           if (flist) flist = flist->next;
         }
+      // Output normal flag macro
       } else if (aflist->command) {
-        if (flist && (!aflist->command || *aflist->command == *flist->command))
-        {
+        if (flist && flist->command && *aflist->command == *flist->command) {
           if (aflist->command)
-            sprintf(out, "#define FLAG_%c (1<<%d)\n", *aflist->command, bit);
+            sprintf(out, "#define FLAG_%c (1%s<<%d)\n", *aflist->command,
+              llstr, bit);
           flist = flist->next;
-        } else sprintf(out, "#define FLAG_%c (FORCED_FLAG<<%d)\n",
-                       *aflist->command, bit);
+        } else sprintf(out, "#define FLAG_%c (FORCED_FLAG%s<<%d)\n",
+                       *aflist->command, llstr, bit);
         bit++;
         aflist = aflist->next;
       }