
/*-------------------------------------------------------------------------
	                        CASER.C

	Takes a file and converts it to upper or lower case.
	(c) 1986 by Greg Lindahl. This program may be copied,
	distributed, and modified as long as this notice is
	kept at the top of the program.
	Install CASER.TOS as a "TOS takes parameters", input line is
	    	
		 input_file output_file [-fulc]
					
	input_file is then converted and output to output_file 
	The options are in brackets [], f-fortran program, u-uppercase, 
					l-lowercase, c-c program
	The default is to convert to uppercase.
 
		      Greg Lindahl - CPS 76515,1122
---------------------------------------------------------------------------*/

#include	"stdio.h"
#define		ERROR	0
#define		TRUE	(1)
#define		_change(c)	(down ? _lower(c) : _upper(c))
#define		_lower(c)	(isupper(c) ? tolower(c) : c)
#define 	_upper(c)	(islower(c) ? toupper(c) : c)

main(argc, argv)
int argc;
char **argv;
{
        FILE	*fi,*fo,*fopen();
        char	c,c_getc();
	int	down, fort, cee, i, fd;

	if (argc < 3) {
	    fprintf(stderr, "Usage: caser input_file output_file [-fulc]\n");
	    fprintf(stderr, "  default: lower_case");
	    exit(ERROR);
	}

/*  open the input file and output file. */

	if ((fi = fopen(*++argv,"r")) == NULL) {
		printf("%%caser-e-inf, input file not found\n");
		exit(ERROR);		
	}
	if ((fo = fopen(*++argv,"w")) == NULL) {
		printf("%%caser-e-oof, ouput file open failure\n");
		exit(ERROR);
	}
	argv++;

/* take apart options if they are here */

	down = TRUE;
	cee  = !TRUE;
	fort = !TRUE;
	if (argc > 3) {
	   while ((c = *++*argv) != '\0') {
		if ( _lower(c) == 'u')
		    down = !TRUE;
		if ( _lower(c) == 'f')
		    fort = TRUE;
		if ( _lower(c) == 'c')
		    cee  = TRUE;
	   }
	}
	if (cee && fort) {
	    printf("%%caser-e-odd; Can't be fortran and cee at once!");
	    exit(ERROR);
	}

/* do actual processing */

	if (!fort && !cee) {
				/* plain vanilla upcase or downcase */
	    while ( (c = c_getc(fi,fo)) != EOF)
		putc(_change(c), fo);
	} else {
	  if (fort) {
				/* fortran upcase or downcase */
	    while ( (c = c_getc(fi,fo)) != EOF) {
		if (c == '\n') {
		    putc(c,fo);
		    if ((c = c_getc(fi,fo)) != EOF) {
			putc(_change(c), fo);
						/* skip comment lines */
			if (_lower(c) == 'c')
			    skip_line(fi,fo);
			if (c == '!')
			    skip_line(fi,fo);
		    } else {
			ungetc(c,fi);  /* put it back to exit while loop */
		    }
		} else {
		    putc(_change(c), fo);
					/* skip single quote or ! comments */
		    if (c == '\'')
			skip_to_char(fi,fo, '\'');
		    if (c == '!')
			skip_line(fi,fo);
		}
	    }
	  } else {
						/* must be c */
	    while ( (c = c_getc(fi,fo)) != EOF) {		
		putc(_change(c), fo);
					/* skip single or double quotes */
		if (c == '\'')
		    skip_to_char(fi,fo,'\'');
		if (c == '\"')
		    skip_to_char(fi,fo,'\"');
	    }
	  }
	}
	fclose(fi);
	fclose(fo);
}

skip_line(fi,fo)
FILE *fi,*fo;
{
			/* for fortran, skips to end of current line */
	char c,c_getc();

	c = c_getc(fi,fo);
	while ((c != EOF) && (c != '\n')) {
	    putc(c,fo);
	    c = c_getc(fi,fo);
	}
	ungetc(c,fi);    /* put it back - possibly 2 comments in a row. */
}

skip_to_char(fi,fo,ch)
FILE *fi,*fo;
char ch;
{
	char c,c_getc();

			/* generic: skips along until it sees ch */
	c = c_getc(fi,fo);
	while ((c != EOF) && (c != ch)) {
	    putc(c,fo);
	    c = c_getc(fi,fo);
	}
	if (c == ch)
	    putc(c,fo);
	if (c == EOF)
	    ungetc(c,fi);    /* put it back to exit while loop */
}
char c_getc(fi,fo)
FILE *fi,*fo;
{
	char c;

	c = getc(fi);
	while (c == '\\') {
	    putc(c,fo);
	    putc(getc(fi),fo);
	    c = getc(fi);
	}
}
isupper(x)		/* test for upper case */
char x;
{
	
	if (x<='Z' && x>= 'A')
		return(1);
	else
		return(0);
}
islower(x)		/* test for lower case */
char x;
{
	
	if (x<='z' && x>= 'a')
		return(1);
	else
		return(0);
}
tolower(x)		/* to lower case */
char x;
{
	return(x+('a'-'A'));
}
toupper(x)		/* to upper case */
char x;
{
	return(x-('a'-'A'));
}
