/* Test for EXPAT parsing library */

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

#define BUFFSIZE        65536
#define MAXTEXTLEN      2048

char data_string[MAXTEXTLEN];
char Buff[BUFFSIZE];

int Depth;

// --- Other functions --------------------------------------------------
char *striphtml (char *s) {
  char *c,t=0,*r;
  c=s;
  r=s;
  while (*s!='\0') {
    if (*s=='<') {
      t++;
    } else if (*s=='>') {
      t--;
    } else if (t<1) {
      *(c++)=*s;
    }
    s++;
  }
  *c='\0';
  return r;
}
char *stripspaces (char *str) {
  char tmp[MAXTEXTLEN];
  char *ptr;
  
  strcpy( tmp, str );
  ptr = strtok( tmp, " \n\t\r" );
  if ( ptr == NULL ) {
    return str;
  }
  strcpy( str, ptr );
  while( (ptr = strtok( NULL, " \n\t\r" )) != NULL ) {
    strcat( str, " ");
    strcat( str, ptr);
  }
  return str;
}

static void XMLCALL
start(void *data, const char *el, const char **attr)
{
  int i;

  for (i = 0; i < Depth; i++)
    printf("  ");

  printf("%s", el);

  for (i = 0; attr[i]; i += 2) {
    printf(" %s='%s'", attr[i], attr[i + 1]);
  }
  
  printf("\n");
  Depth++;
}

static void XMLCALL
end(void *data, const char *el)
{
  printf("(%s)\n", striphtml(stripspaces(data_string)));
  strcpy(data_string, "");
  Depth--;
}

static void
data (void *user_data, const XML_Char * s, int len)
{
  strncat(data_string, s, len);
}

int
main(int argc, char *argv[])
{
  XML_Parser p = XML_ParserCreate(NULL);
  if (! p) {
    fprintf(stderr, "Couldn't allocate memory for parser\n");
    exit(-1);
  }

  XML_SetElementHandler(p, start, end);
  XML_SetCharacterDataHandler(p, data);
  
  for (;;) {
    int done;
    int len;

    len = fread(Buff, 1, BUFFSIZE, stdin);
    if (ferror(stdin)) {
      fprintf(stderr, "Read error\n");
      exit(-1);
    }
    done = feof(stdin);

    if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
      fprintf(stderr, "Parse error at line %d:\n%s\n",
              XML_GetCurrentLineNumber(p),
              XML_ErrorString(XML_GetErrorCode(p)));
      exit(-1);
    }

    if (done)
      break;
  }
  return 0;
}


