/* File uncmntc.c - demo of a text filter
   Strips C comments.
   Tested to strip itself.
   by C.B. Falconer.  2002-08-15 2006-10-24
   Public Domain. Attribution appreciated
   report bugs to <mailto:cbfalconer@maineline.net>
*/

/* With gcc3.1, must omit -ansi to compile eol comments */

#include <stdio.h>
#include <stdlib.h>

static int   ch, lastch;

/* ---------------- */

static void putlast(void)
{
   if (0 != lastch) fputc(lastch, stdout);
   lastch = ch;
   ch = 0;
} /* putlast */

/* ---------------- */

/* gobble chars until star slash appears */
static int stdcomment(void)
{
   int   ch, lastch;

   ch = 0;
   do {
      lastch = ch;
      if (EOF == (ch = fgetc(stdin))) return EOF;
   } while (!(('*' == lastch) && ('/' == ch)));
   return ch;
} /* stdcomment */

/* ---------------- */

/* gobble chars until EOLine or EOF. i.e. // comments */
static int eolcomment(void)
{
   int   ch, lastch;

   ch = '\0';
   do {
      lastch = ch;
      if (EOF == (ch = fgetc(stdin))) return EOF;
   } while (!(('\n' == ch) && ('\\' != lastch)));
   return ch;
} /* eolcomment */

/* ---------------- */

/* echo chars until '"' or EOF */
static int echostring(void)
{
   putlast();
   if (EOF == (ch = fgetc(stdin))) return EOF;
   do {
      putlast();
      if (EOF == (ch = fgetc(stdin))) return EOF;
      if (('\\' == ch) && ('\\' == lastch)) {
         putlast();
         ch = '\0';
      }
   } while (!(('"' == ch) && ('\\' != lastch)));
   return ch;
} /* echostring */

/* ---------------- */

int main(void)
{
   lastch = '\0';
   while (EOF != (ch = fgetc(stdin))) {
      if ('/' == lastch)
         if (ch == '*') {
            lastch = '\0';
            if (EOF == stdcomment()) break;
            ch = ' ';
            putlast();
         }
         else if (ch == '/') {
            lastch = '\0';
            if (EOF == eolcomment()) break;
            ch = '\n';
            putlast();  // Eolcomment here
            // Eolcomment line \
            with continuation line.
         }
         else {
            putlast();
         }
      else if (('"' == ch) && ('\\' != lastch)
                           && ('\'' != lastch)) {
         if ('"' != (ch = echostring())) {
            fputs("\"Unterminated\" string\n", stderr);

            /* You can exercise this code by feeding the
               program an unterminated string, then EOF */
            fputs("checking for\
 continuation line string\n", stderr);
            fputs("checking for" "concat string\n", stderr);
            printf("What\\" /* embedded string */ "%s joke!\n",
                                  /* doh */ "a /*#(K1N5");

            return EXIT_FAILURE;
         }
         putlast();
      }
      else {
         putlast();
      }
   } /* while */
   putlast(/* embedded comment */);
   return 0;
} /* main */
