/* main.c -- test driver for WWW io routines
 * $Id: SGMLmain.c,v 1.3 93/01/06 18:40:27 connolly Exp Locker: connolly $
 */

#include "HTMLwriter.h"
#include "MIFwriter.h"
#include "plaintext.h"
#include "SGML.h"

#include <stdio.h>
#include <string.h>

static HMWriteProc filewrite;

static int
  filewrite(out, buf, n)
HMStream out;
CONST VOIDPTR buf;
unsigned n;
{
  return (int)fwrite(buf, 1, n, (FILE*)out);
}

/* Traditional C implements getc only as a macro... */

static int
  getc_function(f)
FILE* f;
{
  return getc(f);
}


main(argc, argv)
     int argc;
     char* argv[];
{
  if(argc <= 1)
    sgml_test();
  else{
    HMDoc* writer;
    HMDoc_Class* wclass;
    HMParseProc* read;

    if(strcmp(argv[1], "plaintext"))
      read = SGML_parseInstance;
    else
      read = Plaintext_parse;
    
    if(argc < 3 || strcmp(argv[2], "MIF")){
      wclass = &HTMLwriter;
      writer = wclass->writer((HMStream)stdout, filewrite);
    }else{
      wclass = &MIFwriter;
      writer = wclass->fileWriter(stdout);
    }

    if(argc < 4){
      (read)((HMStream)stdin, (HMGetcProc*)getc_function, writer, wclass);
    }else{
      /* test incore */
      HMDoc* incore = InCore_new();

      (read)((HMStream)stdin, (HMGetcProc*)getc_function, incore, &InCore);

      InCore_traverse(incore, writer, wclass);
      InCore.delete(incore);
    }
    (wclass->delete)(writer);
  }

  exit(0);
}

sgml_test()
{
  int read;
  char buffer[72 + 1];
  int content = SGML_MIXED;
  int lookahead = EOF;
  char name[SGML_NAMELEN+1];
  char name_chars;
  char value[SGML_LITLEN+1];
  char out[sizeof(value) * 6];

  while((read = SGML_read((HMStream)stdin, (HMGetcProc*)getc_function,
			   buffer, sizeof(buffer) - 1,
			   content,
			   &lookahead)) != EOF){
    switch(read){
    case SGML_end_tag:
    case SGML_start_tag:
      name_chars = SGML_read_name((HMStream)stdin, (HMGetcProc*)getc_function,
				  name, &lookahead);
      name[name_chars] = '\0';
      if(read == SGML_end_tag){
	printf("</%s>", name);
	content = SGML_MIXED;
      }else{
	printf("<%s", name);

	/*
	 * certain tags change parsing mode
	 * @@ this should be table-driven
	 */
	if(!strcmp(name, "TITLE") ||
	   !strcmp(name, "XMP") ||
	   !strcmp(name, "LISTING")){
	  content = SGML_RCDATA;
	}

	while(isalpha(lookahead)){ /* iterate over attributes */
	  name_chars = SGML_read_name((HMStream)stdin, (HMGetcProc*)getc_function,
				      name, &lookahead);
	  name[name_chars] = '\0';
	  if(lookahead == '='){
	    int len;
	    lookahead = EOF;
	    read = SGML_read_value((HMStream)stdin,
				   (HMGetcProc*)getc_function,
				   value,
				   &lookahead);
	    value[read] = '\0';
	    len = SGML_replen(value, "\"&");

	    SGML_repcpy(out, value, "\"&");
	    printf(" %s=\"", name);
	    fwrite(out, sizeof(char), len, stdout);
	    fputs("\"", stdout);
	  }
	}
	printf(">");
      }

      /* look for tag close */
      while(isspace(lookahead))
	  lookahead = getc(stdin);
      lookahead = EOF;
      break;

    case SGML_entity:
      /* support old <, >, & representations */
      if(!strcmp(buffer, "lt"))
	printf("&#60;");
      else if(!strcmp(buffer, "gt"))
	printf("&#62;");
      else if(!strcmp(buffer, "amp"))
	printf("&#38;");
      else
	printf("&%s;", buffer);
      break;

    case SGML_record_end:
      printf("\n");
      break;

    default:
      if(read>0){
	int len;
	
	buffer[read] = 0;
	len = SGML_replen(buffer, "<>&");
	
	SGML_repcpy(out, buffer, "<>&");
	fwrite(out, sizeof(char), len, stdout);
      }
    }
  }
  exit(0);
}