filter.c

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

    /* Bug: appears to get %c wrong if followed by a trailing space */
    /* Also Imp80 allows ... %c <newline> <newline> code ... */

    #define huge 1000000
    char outbuf[huge] = { 255 };
    char *outp = outbuf+1;

    #define maxline 4096
      char buffer[maxline+2];
      char *line, *s;
      int mode = '\n', savemode = '\n', c, pendch = -1, peek, bracedepth = 0;;

    int lastch(void) {
    int c;
      outp -= 1;
      c = *outp;  /* I don't trust *outp[-1] */
      outp += 1;
      return(c);
    }

    void outch(char c) {
      int x;

      if (c == '\0') { /* Explicit flush */
        /* for now we assume outout buffer bigger than source file */
        fwrite(outbuf+1, outp-outbuf-1, 1, stdout);
        outp = outbuf+1;
        return;
      }

      if ((c != '\n') || (mode == '!')) { *outp++ = c; return;}

      if (lastch() == 'c') {
        outp -= 1;
        fwrite(outbuf+1, outp-outbuf-1, 1, stdout);
        outp = outbuf+1; /* empty the buffer */
        return;
      }

      *outp++ = c;

    }

    int main(int argc, char **argv) {

      buffer[0] = '\n';
      for (;;) {
      line = fgets(buffer+1, maxline, stdin);
      if (line == NULL) break;

      /* zap all DOS-style CR's, just in case */
      while ((s = strchr(line, '\r')) != NULL) {
        memmove(s, s+1, strlen(s) /* incl NUL */);
      }

      s = line+strlen(line); /* points to NUL */
      if (s == line) break;
      if (*--s != '\n') {
        /* Line does not terminate in \n??? */
        exit(1);
      }
      while (*--s == ' ' || *s == '\t') /* strip trailing spaces */;
      *++s = '\n'; /* Reinsert newline - we can now guarantee %c\n */
      for (;;) {
        c = *line++;
        if (c == '\0') break;
        retry:
        switch (mode) {
        case '\n': /* pre-statement space */
          bracedepth = 0;
                  if (isspace(c)) continue;
                  if (c == ';') continue;
                  assert(c != '\n');
                  if ((c == '\'')
                    ||(c == '%')
                    ||(c == '!')) {
                    if ((c == '\'') || (c == '!')) outch(c);
                    /* why did I invent 'pendch'??? - use it here? ^ */
                    bracedepth = 0;
                    savemode = mode; mode = c; continue;
    	      }
                  mode = '.'; pendch = c;
                  continue;
        case '+': /* post %c space */
                  if ((c == ' ') || (c == '\t')) continue;
                  mode = '.';
                  goto retry;
        case '!': /* in ! comment */ /* ERROR: %c at end of comment matters! */
                  /* %COMMENT not handled by this code */
                  if (c == '%') {
                    c = *line++;
                    if (isalpha(c) && (toupper(c) == 'C') && (*line == '\n')) {
                      line++;
                      break; /* Join next line */
    		} else {
                      outch('%'); outch(c);
    		}
    	      } else outch(c);
                  if (c == '\n') mode = c;
                  continue;
        case '%': /* in keyword */
                  /* THIS DOES NOT HANDLE %comment CORRECTLY! */
                  if (isalpha(c)) {
                    c = tolower(c);
                    peek = *line;
                    if ((c == 'c') && (peek == '\n')) {
                      mode = '+'; line += 1; break;
    		}
                    outch(c);
                  if (c == 't') {
                    if (
    		    ( *(outp-1) == 't') &&
                        ( *(outp-2) == 'n') &&
                        ( *(outp-3) == 'e') &&
                        ( *(outp-4) == 'm') &&
                        ( *(outp-5) == 'm') &&
                        ( *(outp-6) == 'o') &&
    		    ( *(outp-7) == 'c'))
                    {
                      // copy over rest of comment up to newline
                      mode = '!';
                      continue;
    		}
    	      }
                    continue;
    	      } else {
                   mode = '.'; goto retry;
    	      }
        case '\'': /* in 'const' */
                  if ((c == mode) && (*line == mode)) {
                    outch(c);
                    outch(c);
                    line += 1; /* past 2nd ' */
                    continue;
    	      }
                  if (c == mode) {
                    /* end of string */
                    outch(c);
                    mode = '.';
                    continue; /* reclassify on next ch */
    	      }
                  outch(c);
                  continue;
        case '.': /* everything else */;
                  if (pendch >= 0) {
                    if (isalpha(pendch) && islower(pendch)) pendch = toupper(pendch);
                    outch(pendch);
                    pendch = -1;
                  };
                  if (isalpha(c) && islower(c)) c = toupper(c);
                  if (c == ' ' || c == '\t') continue;

    	      if (
    	       (c == '\'') &&
    	       (
    		      (isalpha(lastch()) && isupper(lastch()))
    		      || isdigit(lastch())
                          || (lastch() == '\'')  // a X' or X'' variable...
                    )) {
    		outch(c); continue;
    	      }

                  if (c == '(') {
                    bracedepth += 1;
    	      } else if (c == ')') {
                    bracedepth -= 1;
    	      } else if ((c == ':') && (bracedepth == 0)) {
                    /* emit label on line of its own - makes for easier parsing */
                    outch(c);
                    outch('\n');
                    mode = '\n';
                    continue;
    	      }

                  if (c == ';') c = '\n';
                  if (strchr("\n%'", c) != NULL) {
                    if (strchr("\n'", c) != NULL) outch(c);
                    savemode = mode; mode = c;
                    continue;
                  };
                  outch(c);
        }
      }
      }
      outch(0); /* Flush buffer */
    }