/* SGML_stream.h
 * $Id
 */

#ifndef SGML_stream_h
#define SGML_stream_h

#include "c_dialect.h"

/*
 * supported variations on the SGML declaration
 */

#ifdef SGML_DECLARATION
#include SGML_DECLARATION
#endif

#ifndef SGML_NAMELEN
#define SGML_NAMELEN 8
#endif

#ifndef SGML_LITLEN
#define SGML_LITLEN 240
#endif

#ifndef SGML_SHORTTAG
#define SGML_SHORTTAG 1
#endif

#ifndef SGML_UCNMCHAR
#define SGML_UCNMCHAR ".-"
#endif

#ifndef SGML_LCNMCHAR
#define SGML_LCNMCHAR ""
#endif

/*
 * supported content types
 */

enum {
  SGML_CDATA,    /* character data. recognize </ only */
  SGML_RCDATA,   /* replaceable character data. recognize </ and &ref; */
  SGML_PCDATA    /* parsed character data. recognize all markup */
  };

typedef VOIDPTR SGML_Object;
typedef int (*SGML_Method)(SGML_Object);
typedef int (*SGML_Method_int)(SGML_Object, int);
typedef int (*SGML_Method_charptrs)(SGML_Object, CONST char*, char*);

#ifndef EOF
#define EOF (-1)
#endif

enum { SGML_start_tag = -3, SGML_end_tag = -2 };

int
  SGML_read PARAMS((SGML_Object stream,
		    SGML_Method getc,
		    char* buf, int nbytes,
		    SGML_Object entities,
		    SGML_Method_charptrs expand_entity,
		    int max_entity_length,
		    int declared_content,
		    int* inout_lookahead));
/* 
 * PRE:
 * stream -- opaque stream object
 * getc -- getc method for stream. returns -1 on EOF
 * buf -- where to store data
 * nbytes -- how much to read MUST BE > 3!
 * entities -- opaque entities object
 * expand_entity -- method for entities
 *    (expand_entity)(entities, name, dest)
 *    stores the expansion of name at dest, and returns the length
 * max_entity_length -- upper bound on return value of expand_entity
 * declared_content -- SGML_CDATA, SGML_RCDATA, or SGML_PCDATA
 * inout_lookahead -- EOF or first character of input
 *
 * POST:
 * returns value:
 *   SGML_start_tag ==> sgml start tag found. *inout_lookahead
 *                      is first character of name. rest of name
 *                      follows on stream.
 *   SGML_end_tag   ==> sgml end tag found, like start tag
 *   EOF            ==> EOF found before any tags or data
 *                      (note that SGML_read may skip over comments,
 *                       processing insructions, and markup declarations
 *                       to get to EOF)
 *                      *inout_lookahead is not defined.
 *   0              ==> possible markup was found ('<' or '&')
 *                      and nbytes was not sufficient to determine
 *                      whether the character was markup or data, or
 *                      '&' found and nbytes is not suffient to expand
 *                      an entity.
 *                      NOTE: if nbytes >= max_entity_length
 *                           and nbytes > 3, SGML_read is guaranteed
 *                           not to return 0.
 *                      *inout_lookahead is set to the last value
 *                       read from stream.
 *   0<ret<nbytes   ==> ret bytes of data found, followed by
 *                      '<', which may begin a tag, or
 *                      '&' with insufficient room to determine
 *                          whether it's data, or insufficient
 *                          room to expand the entity
 *   nbytes         ==> nbytes of data found.
 *                      *inout_lookahead = EOF (ready for next call)
 */


int
  SGML_read_name PARAMS((SGML_Object stream,
			 SGML_Method getc,
			 char* buf,
			 int* inout_lookahead));
/* 
 * PRE:
 * stream -- opaque stream object
 * getc -- getc method for stream. returns -1 on EOF
 * buf -- where to store name (must be at least SGML_NAMELEN chars)
 * inout_lookahead -- EOF or first character of input
 *
 * POST:
 * returns value:
 *   0              ==> first character is not a name.
 *   0<ret<=SGML_NAMELEN
 *                  ==> name is ret bytes long
 *                      folded to lower case and stored at buf.
 *                      trailing whitespace is skipped
 *                      *inout_lookahead = last value read from stream
 */


int
  SGML_read_value PARAMS((SGML_Object stream,
			  SGML_Method getc,
			  char* buf,
			  SGML_Object entities,
			  SGML_Method_charptrs expand_entity,
			  int max_entity_length,
			  int* inout_lookahead));
/*
 * PRE:
 * stream -- opaque stream object
 * getc -- getc method for stream. returns -1 on EOF
 * buf -- where to store value (must be at least SGML_LITLEN chars)
 * entities -- opaque entities object
 * expand_entity -- method for entities
 *    (expand_entity)(entities, name, dest)
 *    stores the expansion of name at dest, and returns the length
 * max_entity_length -- upper bound on return value of expand_entity
 * inout_lookahead -- EOF or first character of input
 *
 * POST:
 * returns value:
 *   0              ==> first character is not a letter, a digit, or a quote.
 *   0<ret<=SGML_LITLEN
 *                  ==> value is ret bytes long
 *                      stored at buf with entities  expanded
 *                      trailing whitespace is skipped
 *                      *inout_lookahead = last value read from stream
 */


#endif /* SGML_stream_h */

