// Take three word input lines on stdin and produce flag #defines to stdout.
// The three words on each input lnie are command name, option string with
// current config, option string from allyesconfig. The three are space
// separated and the last two are in double quotes.

// 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;
  char *command;
  struct flag *lopt;
};

int chrtype(char c)
{
  // Does this populate a GLOBALS() variable?
  if (strchr("^-:#|@*; %.", c)) return 1;

  // Is this followed by a numeric argument in optstr?
  if (strchr("=<>", c)) return 2;

  if (strchr("?&0", c)) return 3;

  return 0;
}

// replace chopped out USE_BLAH() sections with low-ascii characters
// showing how many flags got skipped so FLAG_ macros stay constant

char *mark_gaps(char *flags, char *all)
{
  char *n, *new, c;
  int bare = 2;

  // Shell feeds in " " for blank args, leading space not meaningful.
  while (isspace(*flags)) flags++;
  while (isspace(*all)) all++;

  n = new = strdup(all);
  while (*all) {
    // --longopt parentheticals dealt with as a unit
    if (*all == '(') {
      int len = 0;

      if (bare) bare = 1;
      while (all[len]) if (all[len++] == ')') break;
      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 && !chrtype(c)) bare = 0;
    if (*flags == c) {
      *(new++) = c;
      flags++;
      continue;
    }

    c = chrtype(c);
    if (!c || (!bare && c==3)) *(new++) = 1;
    else if (c==2) while (isdigit(*all)) all++;
  }
  *new = 0;

  return n;
}

// Break down a command string into linked list of "struct flag".

struct flag *digest(char *string)
{
  struct flag *list = 0;
  char *err = string, c;

  while (*string) {
    // Groups must be at end.
    if (*string == '[') break;

    // Longopts
    if (*string == '(') {
      struct flag *new = calloc(sizeof(struct flag), 1);

      new->command = ++string;

      // Attach longopt to previous short opt, if any.
      if (list && list->command) {
        new->next = list->lopt;
        list->lopt = new;
      } else {
        struct flag *blank = calloc(sizeof(struct flag), 1);

        blank->next = list;
        blank->lopt = new;
        list = blank;
      }
      // An empty longopt () would break this.
      while (*++string != ')') if (*string == '-') *string = '_';
      *(string++) = 0;
      continue;
    }

    c = chrtype(*string);
    if (c == 1 || (c == 3 && !list)) string++;
    else if (c == 2) {
      if (string[1]=='-') string++;
      if (!isdigit(string[1])) {
        fprintf(stderr, "%c without number in '%s'", *string, err);
        exit(1);
      }
      while (isdigit(*++string)) {
        if (!list) {
           string++;
           break;
        }
      }
    } else {
      struct flag *new = calloc(sizeof(struct flag), 1);

      new->command = string++;
      new->next = list;
      list = new;
    }
  }

  return list;
}

// Parse C-style octal escape
void octane(char *from)
{
  unsigned char *to = (void *)from;

  while (*from) {
    if (*from == '\\') {
      *to = 0;
      while (isdigit(*++from)) *to = (8**to)+*from-'0';
      to++;
    } else *to++ = *from++;
  }
  *to = 0;
}

int main(int argc, char *argv[])
{
  char command[256], flags[1024], allflags[1024];
  char *out, *outbuf = malloc(1024*1024);

  // Yes, the output buffer is 1 megabyte with no bounds checking.
  // See "intentionally crappy", above.
  if (!(out = outbuf)) return 1;

  printf("#undef FORCED_FLAG\n#undef FORCED_FLAGLL\n"
    "#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1ULL\n"
    "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0\n#endif\n\n");

  for (;;) {
    struct flag *flist, *aflist, *offlist;
    char *mgaps = 0;
    unsigned bit;

    *command = *flags = *allflags = 0;
    bit = fscanf(stdin, "%255s \"%1023[^\"]\" \"%1023[^\"]\"\n",
                    command, flags, allflags);
    octane(flags);
    octane(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 (see generated/flags.raw)\n", command);
      exit(1);
    }

    bit = 0;
    printf("// %s %s %s\n", command, flags, allflags);
    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);

    printf("#ifdef CLEANUP_%s\n#undef CLEANUP_%s\n#undef FOR_%s\n",
           command, command, command);

    while (offlist) {
      char *s = (char []){0, 0, 0, 0};

      if (!offlist->command) s = offlist->lopt->command;
      else {
        *s = *offlist->command;
        if (127 < (unsigned char)*s) sprintf(s, "X%02X", 127&*s);
      }
      printf("#undef FLAG_%s\n", s);
      offlist = offlist->next;
    }
    printf("#endif\n\n");

    sprintf(out, "#ifdef FOR_%s\n#ifndef TT\n#define TT this.%s\n#endif\n",
            command, command);
    out += strlen(out);

    while (aflist) {
      char *llstr = bit>30 ? "LL" : "", *s = (char []){0, 0, 0, 0};
      int enabled = 0;

      // Output flag macro for bare longopts
      if (!aflist->command) {
        s = aflist->lopt->command;
        if (flist && flist->lopt &&
            !strcmp(flist->lopt->command, aflist->lopt->command)) enabled++;
      // Output normal flag macro
      } else {
        *s = *aflist->command;
        if (127 < (unsigned char)*s) sprintf(s, "X%02X", 127&*s);
        if (flist && flist->command && *aflist->command == *flist->command)
          enabled++;
      }
      out += sprintf(out, "#define FLAG_%s (%s%s<<%d)\n",
                       s, enabled ? "1" : "FORCED_FLAG", llstr, bit++);
      aflist = aflist->next;
      if (enabled) flist = flist->next;
    }
    out = stpcpy(out, "#endif\n\n");
  }

  if (fflush(0) && ferror(stdout)) return 1;

  out = outbuf;
  while (*out) {
    int i = write(1, outbuf, strlen(outbuf));

    if (i<0) return 1;
    out += i;
  }

  return 0;
}
