/* Count the number of bytes in a C source file exluding whitespace and comments */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main(int argc, char** argv)
{
	FILE* f;
	int c;
	int prev_c = -1;
	int prev_prev_c = -1;
	int count = 0;

	int in_c_comment = 0;
	int in_cpp_comment = 0;
	int in_string = 0;
	int in_char_constant = 0;

	if (argc != 2) {
		printf("Usage: count <filename>\n");
		exit(1);
	}

	f = fopen(argv[1], "r");
	if (!f) {
		printf("Error opening file \"%s\"", argv[1]);
		exit(1);
	}

	while ((c = fgetc(f)) != EOF) {
		if (in_c_comment) {
			if (c == '*') {
				c = fgetc(f);
				if (c == '/')
					in_c_comment = 0;
			}
		}
		else if (in_cpp_comment) {
			if (c == '\n')
				in_cpp_comment = 0;
		}
		else if (in_string) {
			if (c == '"' && (prev_c != '\\' || (prev_c == '\\'  && prev_prev_c == '\\')))
				in_string = 0;
			printf("%c", c);
			count++;
		}
		else if (in_char_constant) {
			if (c == '\'' && (prev_c != '\\' || (prev_c == '\\' && prev_prev_c == '\\')))
				in_char_constant = 0;
			count++;
			printf("%c", c);
		}
		else {
			if (c == '/') {
				c = fgetc(f);
				if (c == '*')
					in_c_comment = 1;
				else if (c == '/')
					in_cpp_comment = 1;
				else {
					count++;
					printf("%c", c);
					if (!isspace(c) && c != EOF)
						count++, printf("%c", c);
				}
			}
			else if (c == '"') {
				in_string = 1;
				count++;
				printf("%c", c);
			}
			else if (c == '\'') {
				in_char_constant = 1;
				count++;
				printf("%c", c);
			}
			else if (!isspace(c))
				count++, printf("%c", c);
		}
		prev_prev_c = prev_c;
		prev_c = c;
	}

	fclose(f);

	printf("%d bytes\n", count);

	return 0;
}


