#include <ctype.h>
#include <stdio.h>
#include <string.h>

typedef enum {
  Normal,
  DelFunc,		/* Deleting non-X function */
  DelDef,		/* Just deleted #define */
  DelCom		/* Deleting comment following #define */
} status_t;

int main(int argc, char **argv)
{
  FILE *in, *out;
  status_t status = Normal;
  char outname[256];
  char *leaf;

  strcpy(outname, argv[1]);
  leaf = strrchr(outname, '.');
  if (!leaf++)
  {
    leaf = strrchr(outname, ':');
    if (!leaf++)
      leaf = outname;
  }
  if (!strcmp(leaf, "types"))
    return 0;
  if (!strcmp(argv[2], "-v"))
    printf("Processing %s\n", leaf);
  strcpy(leaf, "_tmp");
  in = fopen(argv[1], "r");
  out = fopen(outname, "w");
  if (!in || !out)
  {
    fprintf(stderr, "Couldn't open file\n");
    return 0;
  }

  while (!feof(in))
  {
    int n;
    int len;
    char line[256];
    int output;

    output = 1;
    if (!fgets(line, 256, in))
      break;
    len = strlen(line);
    switch (status)
    {
      case DelDef:
        for (n = 0; isspace(line[n]); ++n);
        if (line[n] == '/' && line[n + 1] == '*')
          status = DelCom;
        else
        {
          status = Normal;
          goto Normal1;
        }
      case DelCom:
        output = 0;
        if (len >= 3 && line[len - 2] == '/' && line[len - 3] == '*')
          status = Normal;
        break;
      case Normal:
      Normal1:
        if (len < 7)
        {
          output = 1;
          break;
        }
        if (!strncmp(line, "__swi", 5) ||
        	!strncmp(line, "extern ", 7) &&
        	strncmp(line + 7, "os_error *", 10))
        {
          output = 0;
          status = DelFunc;
        }
        else if (!strncmp(line, "#define ", 8) &&
        	(line[len - 2] != 'H' || line[len - 3] != '_') &&
        	line[len - 2] != '\\')
        {
          output = 0;
          status = DelDef;
          break;
        }
        else if (!strncmp(line, "#undef ", 7))
        {
          output = 0;
          status = Normal;
          break;
        }
        else
        {
          output = 1;
          status = Normal;
          break;
        }
      case DelFunc:
        output = 0;
        if (len >= 2 && line[len - 2] == ';')
          status = Normal;
    }
    if (output)
      fputs(line, out);
  }
  fclose(in);
  fclose(out);
  remove(argv[1]);
  if (rename(outname, argv[1]))
  {
    fprintf(stderr, "Couldn't rename temporary file\n");
    return 1;
  }
  return 0;
}
