/* 
  fixcomments   V0.01
  (c) John Donoghue, 1998

  - changes all c++ comments ( // hh ) to thier standard 'c' equivalent. 
  -> / *  hh * /
  - any // comments already inside / *       * / are ignored.

  This code is under the GPL licencing. See the licence, available at
  www.gnu.org for details of the licence.
*/

/************* history **************
V0.01 17/01/98	Initial version
*************************************/
#include <stdio.h>

int ProcessFiles(FILE *from,FILE *to);

int main(int argc,char **argv)
{
  char *fromname,*toname;
  FILE *from=NULL,*to=NULL; 

  printf("fixcomments V0.001 -- (c) John Donoghue, 1998\n");

  /* not enough names given -- show usage */
  if(argc<3) 
  {
    usage:
	    fprintf(stderr,"Usage: %s sourcefilename destfilename\n",argv[0]);
	    exit(0);
  }


	fromname=argv[1];
	toname=argv[2];

	/* user has specified 'unix' help command line - how usage */
	if(*fromname=='-') {
		if(*(fromname+1)=='?') goto usage;
		if(*(fromname+1)=='-' && *(fromname+2)=='?') goto usage;
	}

	/* make sure the filenames arent the same or we will kill it when we open
		 the file to write */
	if(strcmp(fromname,toname)==0) {
		fprintf(stderr,"Error: Destination and source file names can't be the same.\n");
		exit(0);
	}

	/* open the files */
	from=fopen(fromname,"r");
	if(!from) {
		fprintf(stderr,"Error: Cant open source file '%s'\n",fromname);
		exit(0);
	}
	to=fopen(toname,"w");
	if(!to) {
		fprintf(stderr,"Error: Cant open destination file '%s'\n",toname);
	}  
	else {
		fprintf(stderr,"processing file...'%s'\n",fromname);
		ProcessFiles(from,to);
	}
	if(from) fclose(from);
	if(to) fclose(to);

  return 0;
}

int ProcessFiles(FILE *from,FILE *to)
{
	int c;
	char buff;
	char lastchar=0;
	int incppcomment=0;
	int inccomment=0;
	int instring=0;
	int bytecount=0;

	while((c=fgetc(from))!=EOF) {
		if(inccomment) {
			/* keep writing raw text until a * / comes up */
			if(lastchar=='*' && c=='/') {
				/* found the end */
				inccomment=0;
			}
			fprintf(to,"%c",c);
		}
		else if(incppcomment) {
			/* write the stuff until end of line.
				 also if we find a * / we had better kill it */

			if(c=='\n' || c=='\r') { // time to stop
				incppcomment=0;
				fprintf(to,"*/");
			}
			else if(lastchar=='*' && c=='/') {
				c=' ';
			}
			fprintf(to,"%c",c);
		}
		else if(instring) {
			/* write as normal but ignore any / * or * / that may be here */
			if(c=='"') instring=0;
			fprintf(to,"%c",c);
		}
		else if(lastchar=='/' && c=='*') {
			/* start of c comment */
			inccomment=1;
			fprintf(to,"%c",c);
		}
		else if(lastchar=='/' && c=='/') {
			/* start of c++ comment */
			incppcomment=1;
			c='*';
			fprintf(to,"%c",c);
		}
		else {
			// standard code ???
			if(c=='"') instring=1;
			if(lastchar=='*' && c=='/') {
				fprintf(stderr,"Error: Unbalanced c comments found!\n");
				return(0);
			} 
			fprintf(to,"%c",c);
		}

		lastchar=c;

		/* progress marker */
		bytecount++;
		if(bytecount>=1024) {
			fprintf(stderr,".");
			bytecount=0;
		}
	}

	/* at the end all c comments and strings should be 0 */
	if(instring) fprintf(stderr,"Warning: Unterminated strings found.\n");
	if(inccomment) fprintf(stderr,"Warning: Unbalanced C comments found.\n");

	/* it could be possible that we got to end of file without a return
		 and still be in a c++ comment. */
	if(incppcomment) fprintf(to,"*/\n");

	fprintf(stderr,"\nFinished.\n");

	return(0);
}

