/*
 * quotefix.c
 *
 * by gophi@linux.net.pl 2004
 *
 * prosty filtr, zamieniający pokaszanione cytowanie na 
 * newsach, np. takie:
 * 
 * >>> > >> > > >> dupa
 *
 * na normalne, czyli:
 *
 * >>>>>>>>>> dupa
 *
 * jeśli po cytacie, a przed znakami jest więcej niż jedna spacja, 
 * to zostawia jak jest, a jeśli nie ma, to dostawia. jeśli przed 
 * początkiem >>> jest jakaś spacja, to ją usuwa, a jeśli jest 
 * więcej - zostawia jak jest. każde wystąpienie tabulacji zamienia 
 * na osiem spacji.
 *
 * jako parametry można podać nazwę pliku wejściowego i wyjściowego. 
 * wtedy te pliki będą używane zamiast stdin i stdout. informacje 
 * przydatne podczas debugowania wypluwane są na stderr.
 *
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define OUT_CRLF 1
#undef KISS_QUOTE

#ifdef OUT_CRLF
#	define LF_STR "\r\n"
#else
#	define LF_STR "\n"
#endif

void close_streams (FILE **stre)
{
	if (stre[1] && stre[1] != stdout) {
		fprintf (stderr, "Zamykanie wyjścia.%s", LF_STR);
		fclose (stre[1]);
	} else
		fprintf (stderr, "Pominięto zamykanie wyjścia.%s", LF_STR);

	if (stre[0] && stre[0] != stdin) {
		fprintf (stderr, "Zamykanie wejścia.%s", LF_STR);
		fclose (stre[0]);
	} else
		fprintf (stderr, "Pominięto zamykanie wejścia.%s", LF_STR);
}

void *xrealloc (void *ptr, int sz)
{
	void *new_ptr;

	new_ptr = realloc(ptr, sz);
	if (sz && !new_ptr) {
		if (ptr)
			free (ptr);
		fprintf (stderr, "Nie można zrealokować obszaru %X do %lu bajtów.%s", ptr, sz, LF_STR);
		_exit (-1);
	}

	return new_ptr;
}

char *read_line (FILE *fp)
{
	char *line = NULL, ch, done = 0;
	int len = 0;

	while (!done) {
		ch = fgetc(fp);
		if (feof(fp))
			done = 2;
		else if (ch == 0x0D)
			continue;
		else if (ch == 0x0A)
			done = 1;
		else {
			line = (char *) xrealloc(line, len + 1);
			line[len++] = ch;
		}
	}

	if (done == 2) {
		if (line)
			free (line);

		return (char *) NULL;
	}

	line = (char *) xrealloc(line, len + 1);
	line[len] = (char) NULL;

	return line;
}

void rewrite_line (FILE *fp, char *line)
{
	int i = 0, quot = 0;

	/* policzenie stopni cytowania. kończy, kiedy spotka 
	 * literę lub dwie spacje pod rząd.
	 */

	while (line[i]) {
		if (line[i] == '>')
			quot++;
		else if (line[i] != 0x20 || line[i + 1] == 0x20)
			break;
		i++;
	}

	/* tutaj line[i] to pierwsza litera */

	if (!i)	{	/* bez cytowania */
		fprintf (fp, "%s%s", line, LF_STR);
		return;
	}

#ifdef KISS_QUOTE
	if (quot)
		fputc (':', fp);
#endif

	while (quot--)	/* wypisanie >>> */
#ifdef KISS_QUOTE
		fputc ('*', fp);
#else
		fputc ('>', fp);
#endif

	if (line[i] != 0x20)
		fputc (' ', fp);

	fprintf (fp, "%s%s", line + i, LF_STR);
}

int main (int argc, char **argv)
{
	FILE *stre[2] = {stdin, stdout};
	char *line;
	char done = 0;

	fprintf (stderr, "quotefix.c%sby gophi@linux.net.pl 2004.%s", LF_STR, LF_STR);

	if (argc > 1) {
		fprintf (stderr, "Wejście: plik %s.%s", argv[1], LF_STR);
		stre[0] = fopen(argv[1], "rb");
		if (!stre[0]) {
			fprintf (stderr, "Nie można otworzyć wejścia.%s", LF_STR);
			return -1;
		}
	} else
		fprintf (stderr, "Wejście: stdin.%s", LF_STR);

	if (argc > 2) {
		fprintf (stderr, "Wyjście: plik %s.%s", argv[2], LF_STR);
		stre[1] = fopen(argv[2], "wb");
		if (!stre[1]) {
			fprintf (stderr, "Nie można otworzyć wyjścia.%s", LF_STR);
			close_streams (stre);
			return -1;
		}
	} else
		fprintf (stderr, "Wyjście: stdout.%s", LF_STR);

	fprintf (stderr, "Przepisywanie nagłówków.%s", LF_STR);

	while (!done) {
		line = read_line(stre[0]);
		if (line && *line) {
			fprintf (stre[1], "%s%s", line, LF_STR);
			free (line);
		} else {
			fprintf (stre[1], "%s", LF_STR);
			done = 1;
		}
	}

	fprintf (stderr, "Zakończono przepisywanie nagłówków.%s", LF_STR);
	fprintf (stderr, "Przepisywanie wiadomości.%s", LF_STR);

	done = 0;
	while (!done) {
		line = read_line(stre[0]);
		if (line) {
			rewrite_line (stre[1], line);
			free (line);
		} else
			done = 1;
	}

	fprintf (stderr, "Zakończono przepisywanie wiadomości.%s", LF_STR);

	close_streams (stre);

	return 0;
}
