#ifndef _sgmllib_h
#define _sgmllib_h

/* $Id:
   $Log: */

#include "nsl-defs.h"
#include "lt-mttslib.h" /* must come before nsl-errmsg */
#include "nsl.h" /* must come before nsl-errmsg */
#include "nsl-errmsg.h"
#include "nsl-stack.h"
#include "lt-rhash.h"
#include "ddb.h"

/* NSL-internal types */

#define MAXSGMLNAMELEN 255
#define SAMBUFSIZE 524288
#define BUFCOPYMAX 8192
#define BUFMARGIN 131072

#define RDERR -2
#define REREAD -3

#define IDENTCH "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.0123456789"

/* typedef enum {_qa_text,_qa_rx} QAtype; NOT NEEDED ANYMORE David */
/* _qa_comp_error,               An error in parsing query
   _qa_comp_no_op,               no op
   _qa_comp_equal,               =      string equality
   _qa_comp_not_equal,           !=     string inequality
   _qa_comp_regexp,              ~      regexp match
   _qa_comp_not_regexp,          !~     regexp no-match
   _qa_comp_less,                <      numeric less than
   _qa_comp_not_less,            !<     numeric not less than i.e. >=
   _qa_comp_greater,             >      numeric greater than
   _qa_comp_not_greater,         !>     numeric not greater than i.e. <=
   _qa_comp_user_defined,        ?      user-defined comparison
   _qa_comp_not_user_defined     !?     user-defined comparison negated
*/
#include "query.h"

/* NB must match StandaloneDeclaration in Richard's parser */
typedef enum {sdd_unspecified, sdd_no, sdd_yes} sddCode;

typedef struct OffboardAttrs {
				/* entry for attribute summaries not
				 in element summary space, XML only */
  int oldNumAttr;
  struct ASPtr *asp;
} OffboardAttrs;

typedef struct NSL_Doctype_I {
  const char *doctype;		/* points to doctype name after DDB header */
  boolean XMLMode;
  const DDBHeader *ddb;
  const char *ddbfile;
  const int *charset;
  const char *elementBase;
  const char *permanentBase;	/* elementBase may change in XML,
				   permanent base won't
				*/
  const RHashTableHdr *entities;
  const char *entityBase;
  sddCode sdd;
  CharacterEncoding defaultOutputEncoding;
  CharacterEncoding fallbackEncodingDeclaration;
  const Char *doctypeStatement; /* If the nSGML file contains a */
                            /* <!DOCTYPE> statement, then this */
                            /* points to the entire <?DOCTYPE ... > string */
  int seenDTD;		    /* true if doctype was passed in or has been read;
			       used to prevent reading more than one. */

  /* These used to be global */
  struct Umalloc *itemstack;
  struct Umalloc *datastack;
  struct Umalloc *attrstack;

  /* For XML only below here */
  const RHashTableHdr *attrNames;
  int attrNameCount;
  const RHashTableHdr *elements;
  int elementCount;
  const OffboardAttrs *offAttrsBase;
  int offAttrsIndex;
  int offAttrsLimit;
  const char *elementPtr;
  const char *elementLimit;
  /* For XML only above here */
  struct dtd *rxp_dtd;			/* The rxp-level dtd */
  struct entity *root_entity;		/* Root entity of defining document */
} NSL_Doctype_I;

typedef struct ASPtr {
  const AttributeSummary *as;
  struct ASPtr *next;
} ASPtr;

typedef enum {_markup_identifier, _markup_string, _markup_decl_subset_open,
		_markup_decl_subset_close, _markup_end, _markup_reserved_id,
		_markup_eq, _markup_body_open,
		_markup_com, _markup_null, _markup_error} MarkupTokenType;

#ifdef _LinkIDs_
/*
 * LinkRef allows a link between an SGML item and a C structure.
 */
typedef struct LinkRef {
    char *id;
    void *cref;
    char *ctype;
    NSL_Item *item;
    struct LinkRef *next;
} LinkRef;

extern LinkRef *_refs;                        /* sgmllink.c */
#endif

#include "nslfile.h"

extern struct NSL_File_I *sgstdin, *sgstdout, *sgstderr;
extern NSL_AVType AttrValueType[]; /* defined in sgmlparse.c */
extern NSL_ADefType DefltType[]; /* ditto */

/* See knitGenerator.H for inline c++ definitions of these */

#define NEWSTACK(size) ((void *)salloc(sizeof(void*)*size))

#define POP(stack) ((NSL_ElementSummary_I *)*(--stack.current))

#define POPNV(stack) (--stack.current)

#define TOP(stack) ((NSL_ElementSummary_I *)*(stack.current-1))

#define STACKBAD(stack) (stack.current < stack.base)

#define EMPTY(stack) (stack.current == stack.base)

#define NONEMPTY(stack) (stack.current > stack.base)

#define PUSH(stack,newc) if (stack.current==stack.end) { \
			   stackGrow(&(stack)); \
			 }; \
			 *(stack.current++)=((void*)newc);

#include "nslifunc.h"

#endif /* _sgmllib_h */
