#include <stdio.h>

char *Usage = "Usage: %s [ -h ] [ file1 file2 ... ]\n";

#if defined(sparc)
#define ARGS(x) (/*x*/)
#else
#define ARGS(x) x
#endif

void do_input ARGS((FILE *ifp));
void handle_file_insert ARGS((FILE *ifp));

#define ZERO_BUFFER() \
    if (buffer_size > 0) bzero(query_buffer, buffer_size)

#define STUFF_BUFFER(qb, c) \
{ \
    static char last = '\0'; \
 \
    if (c == '\t') c = ' '; \
    if (c == '\n' || (isspace(last) && isspace(c))) \
	; \
    else \
    { \
	if ((qb - query_buffer + 1) >= buffer_size) \
	{ \
	    int offset = qb - query_buffer; \
	    query_buffer = (char *)realloc(query_buffer, buffer_size + 8192); \
	    qb = query_buffer + offset; \
	    if (!query_buffer) \
	    { \
		fprintf(stderr, "malloc failed - size %d", buffer_size + 8192);\
		exit (1); \
	    } \
	    buffer_size += 8192; \
	} \
	last = *qb++ = c; \
    } \
}
#define PRINT_BUFFER() fprintf(stdout, "%s\n",query_buffer);

main(argc, argv)
    int argc;
    char *argv[];
{
    FILE *inputFp;
    char c;

    if ((c = getopt(argc, argv, "h")) != EOF)
    {
	printf(Usage, argv[0]);
	exit(0);
    }
    switch (argc) {
	int nfiles, i;

	case 1:
	    do_input(stdin);
	    break;
	default:
	    nfiles = argc - 1;
	    for (i = 1; i <= nfiles; i++)
	    {
		inputFp = fopen(argv[i], "r");
		if (!inputFp)
		{
		    fprintf(stderr, "Cannot open %s\n", argv[i]);
		    exit(1);
		}
		do_input(inputFp);
		fclose(inputFp);
	    }
	    break;
    }
}

void
do_input(ifp)
    FILE *ifp;
{
    int c;
    char escape;
    char *qbP;
    static char *query_buffer = NULL;
    static int buffer_size = 0;

    qbP = query_buffer;

    ZERO_BUFFER();
    /*
     *  Processing user input.
     *  Basically we stuff the user input to a temp. file until
     *  an escape char. is detected, after which we switch
     *  to the appropriate routine to handle the escape.
     */

    while ((c = getc(ifp)) != EOF )
    {
	if ( c == '\\')
	{
	    /* handle escapes */
	    escape = getc(ifp);
	    switch( escape ) {
	      case 'g':
		PRINT_BUFFER();
		ZERO_BUFFER();
		qbP = query_buffer;
		break;
	      case 'i':
		handle_file_insert(ifp);
		break;
	      case 'e':
	      case 'p':
	      case 'q':
	      case 'r':
	      case 's':
	      case 't':
	      case 'w':
	      case '?':
	      case 'h':
		break;
	      case '\\':
		c = escape;
		STUFF_BUFFER(qbP, c); 
		break;
	      default:
		fprintf(stderr, "unknown escape given\n");
		break;
	    } /* end-of-switch */
	}
	else if (c == '/')
	{
	    char peek = getc(ifp);
	    if (peek == '*')
	    {
		while (1)
		{
		    while ((peek = getc(ifp)) != '*')
			;
		    if (peek == EOF)
		    {
			fprintf(stderr, "Unterminated comment\n");
			return;
		    }
		    if ((peek = getc(ifp)) == '/')
			break;
		}
	    }
	    else
	    {
		STUFF_BUFFER(qbP, c);
		STUFF_BUFFER(qbP, peek);
	    }
	}
	else
	{
	    STUFF_BUFFER(qbP, c); 
	}
    }
}

void
handle_file_insert(ifp)
    FILE *ifp;
{
    char user_filename[50];
    FILE *nifp;

    fscanf(ifp, "%s",user_filename);
    nifp = fopen(user_filename, "r");
    if (nifp == (FILE *) NULL) {
        fprintf(stderr, "Cannot open %s\n", user_filename);
    } else {
        do_input(nifp);
        fclose (nifp);
    }
}
