/* This program does proper indentation on (some) C programs */
#include <stdio.h>

#define INITIAL		0
#define FOUNDSLASH	1
#define INCOMMENT	2
#define FOUNDSTAR	3

/* this is a nast*y comment, whee! { { { { */

/* this finite state automaton (overkill for this assignment, but a nice
 * idea if you're into this sort of thing) keeps track of where we are
 * in terms of commenting
 */
int dofsa (int state, char ch) {
	switch (state) {
		case INITIAL:
			if (ch == '/') 
				state = FOUNDSLASH;
			else 
				state = INITIAL;
			break;
		case FOUNDSLASH:
			if (ch == '*') 
				state = INCOMMENT;
			else
				state = INITIAL;
			break;
		case INCOMMENT:
			if (ch == '*') 
				state = FOUNDSTAR;
			else
				state = INCOMMENT;
			break;
		case FOUNDSTAR:
			if (ch == '/')
				state = INITIAL;
			else
				state = INCOMMENT;
			break;
	}
	return state;
}

int main (int argc, char *argv[]) {
	char	s[1000];
	int	i, nbracks, pos, quoting, commenting;
	FILE	*f;

	/* open file on command line */

	if (argc != 2) {
		fprintf (stderr, "Usage: %s <filename>\n", argv[0]);
		exit (1);
	}
	f = fopen (argv[1], "r");
	if (!f) {
		perror (argv[1]);
		exit (1);
	}

	/* initialize conditions */

	nbracks = 0;
	quoting = 0;
	commenting = INITIAL;
	for (;;) {

		/* get a single string from the file */

		fgets (s, 1000, f);
		if (feof (f)) break;

		/* find first nonwhitespace char */

		for (pos=0; s[pos] == ' ' || s[pos] == '\t'; pos++);

		/* for each char... */

		for (i=pos; s[i]; i++) {

			/* figure out our commenting state */

			commenting = dofsa (commenting, s[i]);

			/* toggle quoting flag */

			if (s[i] == '"' || s[i] == '\'') quoting = !quoting;

			/* if found a brace and it is syntax, one less level */

			if (!commenting && !quoting && s[i] == '}') nbracks--;
		}

		/* print out tabs and string */

		for (i=0; i<nbracks; i++) printf ("\t");
		printf ("%s", &s[pos]);

		/* same as before, looking for { this time */

		for (i=pos; s[i]; i++) {
			commenting = dofsa (commenting, s[i]);
			if (s[i] == '"' || s[i] == '\'') quoting = !quoting;
			if (!commenting && !quoting && s[i] == '{') nbracks++;
		}
	}
	fclose (f);

	/* error conditions */

	if (nbracks) fprintf (stderr, "unbalanced program!\n");
	if (commenting) fprintf (stderr, "unfinished comment!\n");
	if (quoting) fprintf (stderr, "unfinished quote!\n");
}