
/* 
 コメントを除去し、継続行については前の行に継なげておく。
 継続しない改行については
 ";", ": (case)", "{", "}" を対象とする
 # が行頭にあったら継続行判断はしない
 かなり不完全だがまあ良しとせよ

 */

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

void usage() {
fprintf(stderr, "usage: uncomment [-vn] < infile > outfile \n");
fprintf(stderr, "   v : verbose mode.\n");
  return;
}

char buf[1024];
int bufp=0; /* buf の最後のバイト位置 */
int bufl= -1; /* buf の最後の空白以外の文字の位置 */

int vmode=1;

int purgebuf()
{
  if(bufp==0) return 0;

  buf[bufp++]='\0';  
  printf("%s\n",buf);

  return 0;
}

int pushbuf(int c)
{
  if( c != '\n' ) { /* 通常の文字を積む */
    buf[bufp]=c;
    if( (c != ' ' )&&(c != '\t' ) ) bufl=bufp;
    bufp++;
  } else { /* 改行登場 */
    if( bufl == -1 ) { /* 全く文字無し */
      bufp=0;  /* なにもなかったことに */
    } else if( buf[0] == '#' ) { /* 先頭が # なら改行 */
      buf[bufp++]='\0';
      printf("%s\n",buf);
      bufp=0;
      bufl= -1;      
    } else if( 
	      buf[bufl] == ';' || 
	      buf[bufl] == ':' || 
	      buf[bufl] == '{' || 
	      buf[bufl] == '}'
	      ) { /* 最後が ;:{} だったら改行 */
      buf[bufp++]='\0';
      printf("%s\n",buf);
      bufp=0;
      bufl= -1;
    } else { /* 継続行？ */
      buf[bufp++]=' '; /* 空白を一つ入れておく */
    };
  };

  return 0;
}

int main(int argc, char *argv[])
{
  int ch;
  extern char *optarg;
  extern int optind;
  char buf[256];
  int cmode;
  int c, cc;

  /* option recognise */
  while ((ch = getopt(argc, argv, "vn")) != EOF) {
    switch((char)ch) {
    case 'v': /* verbose mode */
      vmode=1;
      break;
    case 'n': /* quiet mode */
      vmode=0;
      break;
    case '?': /* Help message */
    default:
      usage();
    fprintf(stderr,"locsim : unrecognized parameter exist.\n");
      exit(1);
    };
  };
  /* Skip the position of argc,argv[] */
  argc -= optind;
  argv += optind;

  if(argc!=0) {
    usage();
  fprintf(stderr,"locsim : extra parameter is exist.\n");
    exit(1);
  };
  
  cc= -1; /* 最前の一文字 */
  cmode=0; /* 通常モードからスタート */
  while( (c=fgetc(stdin)) != -1 ) {
    /* printf("#%d=%c=%c#\n",cc, cc, c); */
    switch( cmode ) {
    case 0: /* 通常モード */
      if( (cc=='/') && (c=='*') ) { /* コメントモード 1 に突入 */
	cmode=1;
	cc= -1;
      } else if( (cc=='/') && (c=='/') ) { /* コメントモード 2 に突入 */
	cmode=2;
	cc= -1;
      } else { /* 通常のプログラム部分は出力対象 */
	if(cc != -1) pushbuf( cc );
	cc=c;
      };
      break;
    case 1: /* /,* による コメントモード */
      if( (cc=='*') && (c=='/') ) { /* コメントモードおわり */
	cmode=0;
	cc= -1;
      } else {
	/* コメント部分は出力対象にならない */
	cc= c; /*  * を読んだときに残しておかねば */
      };
      break;
    case 2: /* /,/ による コメントモード */
      if( c=='\n' ) { /* 改行でコメントモードおわり */
	cmode=0;
	cc= '\n'; /* 改行を出力に積んでおく */
      } else {
	/* コメント部分は出力対象にならない */
	cc= c; /*  / を読んだときに残しておかねば */
      };
      break;
    default:
      fprintf(stderr, "never reach\n");
      exit(0);
    };
  };
  if(cc != -1) pushbuf( cc );
  purgebuf();

  return 0;
}
