/*
Autor : Giovani Facchini
Mail to: giovani AT exatas DOT unisinos DOT br

*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

enum estados { NORMAL, SLASH, SINGLE_LINE, MULTI_LINE, MULTI_LINE_END, STRING, STRING_SPECIAL, CHAR, CHAR_SPECIAL };
/*
a variável estado representa o estado do programa:
NORNAL - Texto normal
SLASH - Leitura de uma barra estando no estado NORNAL
SINGLE_LINE - Leitura de uma barra estando no estado SLASH (comentário de uma linha)
MULTI_LINE - Leitura de um asterisco estando no estado SLASH (comentário de múltiplas linhas)
MULTI_LINE_END - Leitura de um asterisco estando no estado MULTI_LINE (fim do comentário múltiplo)
STRING - Leitura de um duplo asterisco no estado NORNAL (String)
STRING_SPECIAL - Leitura de uma barra invertida no estado STRING (caractere especial)
CHAR - Leitura de uma aspa simples quando no estado NORMAL (Char)
CHAR_SPECIAL - Leitura de uma barra invertida no estado (caractere especial)

*/

int main(int argc, char *argv[]) {
	FILE *input, *output;
	char buffer, special;
	enum estados estado;

	estado = NORMAL;

	//testa se os parâmetros foram inseridos
	if (argc < 3) {
		fprintf(stderr, "Entre com o arquivo de entrada e de saída\n");
		exit(1);
	}
	//abri o arquivo de entrada pra a leitura
	if ((input = fopen (argv[1], "r"))==NULL){
		fprintf(stderr, "Erro ao abrir arquivo %s\n",argv[1]);
		exit(1);
	}
	//abre o arquivo de saída para a gravação
	if ((output = fopen (argv[2], "w"))==NULL){
		fprintf(stderr, "Erro ao criar arquivo %s\n",argv[2]);
		exit(1);
	}
	buffer = (char) fgetc(input);
	//para cada caractere lido pode-se mudar de estado. O switch eh responsável
	while(!feof(input)){
		switch (estado) {
			case NORMAL : {
				if (buffer == '/') {
					estado = SLASH;
					special = buffer;
				} else if (buffer == '"') {
					estado = STRING;
					fputc(buffer,output);
				} else if (buffer == '\'') {
					estado = CHAR;
					fputc(buffer, output);
				} else fputc(buffer, output);
				break;
			}
			case SLASH : {
				if (buffer == '/') {
					estado = SINGLE_LINE;
				} else if (buffer == '*') {
					estado = MULTI_LINE;
				} else {
					estado = NORMAL;
					fputc(special, output);
					fputc(buffer, output);
				}
				break;
			}
			case SINGLE_LINE : {
				if (buffer == '\n') {
					fputc(buffer, output);
					estado = NORMAL;
				}
				break;
			}
			case MULTI_LINE : {
				if (buffer == '*')
					estado = MULTI_LINE_END;
				break;
			}
			case MULTI_LINE_END : {
				if (buffer == '/')
					estado = NORMAL;
				else estado = MULTI_LINE_END;
				break;
			}
			case STRING_SPECIAL : {
				estado = STRING;
				fputc(buffer, output);
				break;
			}
			case STRING : {
				if (buffer == '/')
					estado = STRING_SPECIAL;
				else if (buffer == '\n' )
					estado = NORMAL;
				else if (buffer == '"')
					estado = NORMAL;
				fputc (buffer, output);
				break;
			}
			case CHAR : {
				if (buffer == '/')
					estado = CHAR_SPECIAL;
				else if (buffer == '\n' )
					estado = NORMAL;
				else if (buffer == '\'')
					estado = NORMAL;
				fputc (buffer, output);
				break;
			}
			case CHAR_SPECIAL : {
				estado = CHAR;
				fputc(buffer, output);
				break;
			}
		}
		buffer = (char) fgetc(input);
	}

	fclose(input);
	fclose(output);
	return 0;
}

