/* PURPOSE:
 *    The MAIN function:
 *    Open an input stream; scan, count, and print tokens until EOF.
 * HISTORY:
 *    Ian D. Allen   idallen@freenet.carleton.ca
 * ALGORITHM:
 *    Initialize a file name buffer
 *    LOOP:
 *       Clear the file name buffer
 *       CALL a function to prompt for a good file name and open the file
 *    UNTIL we have an open stream, or no file name, or hit EOF
 *    IF we have no open stream, quit the program
 *    Initialize the scanner
 *    LOOP:
 *       CALL the scanner to get a token from the stream
 *       PRINT the token and its characteristics
 *    UNTIL we see the final EOF token
 *    PRINT some statistics
 *    Terminate the scanner
 *    Close streams and tidy up buffers
 *    END
 */

#include <stdio.h>
#include <stdlib.h>

#include "misc.h"
#include "cover.h"
#include "buffer.h"
#include "my.h"
#include "scanner.h"

#define FNAME_INIT 20	/* initial size of file name buffer */
#define FNAME_INCR 10	/* incremental increase for file name buffer */

char *cmdname = "UNKNOWN";	/* set by main; used by eprintf */

	int
main(int argc, char **argv) {
	FILE *fd;		/* descriptor of input stream */
	Buffer *fbuf;		/* file name buffer */
	Token token;		/* returned by scanner */
	int countIds;		/* count of identifiers */
	int countOther;		/* count of other things */

	if( argc >= 1) cmdname = argv[0];/* save command name for eprintf */

	/* Note the order of operations here is (1), (2), (3).
	 *
	 * (1) Allocate a File Name Buffer.
	 * LOOP:
	 *    Clear the file name buffer.
	 *    Prompt for an input file and try (2) to open the input file.
	 *    (Note that my_open() may return stdin itself as the open fd.)
	 * UNTIL we have an open stream, or no file name, or hit EOF
	 * IF no stream is open, simply say goodbye and exit.
	 * (3) Initialize the Scanner to read from the open stream.
	 */
	fbuf = bf_alloc(FNAME_INIT, FNAME_INCR);	/* (1) */

	do {
		bf_clear(fbuf);
		fd = my_open(fbuf, NULL, MY_READONLY, TRUE); /* (2) */
	} while ( fd == NULL && ! BF_EMPTY(fbuf) && ! feof(stdin) );

	if( fd == NULL ){
		eprintf("No file name given.  Goodbye.");
		return EXIT_SUCCESS;/* not an error */
	}

	printf("Successfully opened input stream '%s'\n", fbuf->buf);
	scanner_init(fd,fbuf->buf);			/* (3) */
	printf("Now scanning for tokens from '%s'\n", fbuf->buf);
	countIds = countOther = 0;

	/* LOOP: Scan, count, and print tokens until seeing the TT_EOF token.
	 */
	do {
		int count;

		token = scanner();

		count = (token.type == TT_ID) ? ++countIds : ++countOther;

		printf("%05d type %d '%-12s' line %ld is '%s'\n",
			count,
			token.type,
			token_name(token.type),
			token.lineno,
			token.lexeme);
	} while( token.type != TT_EOF );

	printf("File '%s': Identifiers %d,  Other %d\n",
		fbuf->buf, countIds, countOther);

	/* Note the order of operations following is the exact reverse
	 * of the complementary operations above: (3), (2), (1).
	 *
	 * (3) Terminate the Scanner.
	 * (2) Close or flush the input stream.
	 * (1) Free the file name buffer.
	 */
	scanner_term();					/* (3) */
	my_close(fd, fbuf->buf);			/* (2) */
	bf_free(fbuf);					/* (1) */

	return EXIT_SUCCESS;
}
