/**
 * rngparser.c: parser for the Relax-NG compact syntax.
 *
 * Based on:
 *   RELAX NG Compact Syntax
 *   Committee Specification 21 November 2002
 *   http://www.oasis-open.org/committees/relax-ng/compact-20021121.html
 *
 * See Copyright for the status of this software.
 *
 * Daniel Veillard <veillard@redhat.com>
 */

#include <string.h>

#include <libxml/parser.h>
#include <libxml/parserInternals.h>
#include <libxml/relaxng.h>
#include <libxml/dict.h>

#define TODO								\
    xmlGenericError(xmlGenericErrorContext,				\
	    "Unimplemented block at %s:%d\n",				\
            __FILE__, __LINE__);

#define MAX_TOKEN 10

typedef enum {
    CRNG_NONE = 0,
    CRNG_OP = 1,
    CRNG_KEYWORD,
    CRNG_IDENTIFIER,
    CRNG_LITERAL_SEGMENT,
    CRNG_CNAME,
    CRNG_QNAME,
    CRNG_NSNAME,
    CRNG_DOCUMENTATION
} xmlCRNGTokType;

typedef enum {
    CRNG_OKAY = 0,
    CRNG_MEMORY_ERROR,
    CRNG_INVALID_CHAR_ERROR,
    CRNG_END_ERROR,
    CRNG_ENCODING_ERROR
} xmlCRNGError;

typedef enum {
    XML_CRNG_ERROR = -1,
    XML_CRNG_OK = 0,
    XML_CRNG_EOF = 1
} xmlCRelaxNGParserState;

typedef struct _token _token;
typedef _token *tokenPtr;
struct _token {
    xmlCRNGTokType toktype;
    int toklen;
    const xmlChar *token;
    const xmlChar *prefix;
};

typedef struct _xmlCRelaxNGParserCtxt xmlCRelaxNGParserCtxt;
typedef xmlCRelaxNGParserCtxt *xmlCRelaxNGParserCtxtPtr;
struct _xmlCRelaxNGParserCtxt {
    void *userData;			/* user specific data block */
    xmlRelaxNGValidityErrorFunc error;	/* the callback in case of errors */
    xmlRelaxNGValidityWarningFunc warning;/* the callback in case of warning */
    xmlRelaxNGValidErr err;

    const xmlChar *compact;
    const xmlChar *end;
    const xmlChar *cur;
    int isElem;
    int lineno;
    const xmlChar *linestart;
    const char *filename;

    int  nbTokens;
    int  firstToken;
    _token tokens[MAX_TOKEN];
    int  totalToken;

    xmlCRelaxNGParserState state;

    int            nbErrors;

    xmlDocPtr      res;			/* the result */
    xmlNodePtr     ins;			/* the current insertion node */

    xmlNsPtr       nsDef;
    tokenPtr token;

    xmlHashTablePtr namespaces;
    xmlHashTablePtr datatypes;

    /*
     * dictionary and keywords
     */
    xmlDictPtr     dict;
    const xmlChar *key_attribute;
    const xmlChar *key_default;
    const xmlChar *key_datatypes;
    const xmlChar *key_div;
    const xmlChar *key_element;
    const xmlChar *key_empty;
    const xmlChar *key_external;
    const xmlChar *key_grammar;
    const xmlChar *key_include;
    const xmlChar *key_inherit;
    const xmlChar *key_list;
    const xmlChar *key_mixed;
    const xmlChar *key_namespace;
    const xmlChar *key_notAllowed;
    const xmlChar *key_parent;
    const xmlChar *key_start;
    const xmlChar *key_string;
    const xmlChar *key_text;
    const xmlChar *key_token;
    const xmlChar *key_equal;
    const xmlChar *key_orequal;
    const xmlChar *key_andequal;
    const xmlChar *key_combine;
    const xmlChar *key_or;
    const xmlChar *key_comma;
    const xmlChar *key_and;
    const xmlChar *key_choice;
    const xmlChar *key_group;
    const xmlChar *key_interleave;
    const xmlChar *key_ref;
    const xmlChar *key_define;

    /* results */
    xmlDocPtr doc;	/* the resulting doc */
    xmlNodePtr insert;	/* the insertion point */
    xmlAttrPtr attrs;   /* pending attributes */
};

static const xmlChar *xmlCRelaxNGInherit = BAD_CAST "Inherit string";
static const xmlChar *xmlCRelaxNGDefault = BAD_CAST "Default string";

#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
/**
 * IS_BLANK:
 * @c:  an UNICODE value (int)
 *
 * Macro to check the following production in the XML spec:
 *
 * [3] S ::= (#x20 | #x9 | #xD | #xA)+
 */
#ifndef IS_BLANK
#define IS_BLANK(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) ||	\
                     ((c) == 0x0D))
#endif
#define IS_SEPARATOR(c) (((c) == 0x20) || ((c) == 0x09) || ((c) == 0xA) || \
                     ((c) == 0x0D) || (c == '#'))

#define CRNG_ERROR0(X)							\
    { xmlCRNGErr(ctxt, X, NULL); return(0); }
#define CRNG_ERROR(X)							\
    { xmlCRNGErr(ctxt, X, NULL); }

#define CRNG_MEM_ERROR0()						\
    { xmlCRNGErr(ctxt, CRNG_MEMORY_ERROR, NULL); return(0); }
#define CRNG_MEM_ERROR()						\
    { xmlCRNGErr(ctxt, CRNG_MEMORY_ERROR, NULL); }

#define ERROR(str) xmlCRNGErr(ctxt, 0, str);

static void
xmlCRNGErr(xmlCRelaxNGParserCtxtPtr ctxt, int err_no, const char *err_msg) {
    const xmlChar *cur;
    xmlChar buffer[150];
    int i, l;

    if (ctxt != NULL) {
        if (ctxt->filename != NULL)
	    fprintf(stderr, "%s:%d ", ctxt->filename, ctxt->lineno);
    }
    if (err_msg != NULL) {
	fprintf(stderr, "error: %s\n", err_msg);
    } else if (err_no != 0)
	fprintf(stderr, "error %d\n", err_no);
    cur = ctxt->cur;
    while ((*cur != '\n') && (*cur != '\r') && (ctxt->cur - cur < 80)) cur--;
    l = ctxt->cur - cur;
    cur++;
    for (i = 0; i < 100;i++) {
        if ((*cur == '\n') || (*cur == '\r')) break;
        buffer[i] = *cur++;
    }
    buffer[i] = 0;
    fprintf(stderr, "%s\n", buffer);
    for (i = 0; i < l;i++) buffer[i] = ' ';
    buffer[i++] = '^';
    buffer[i++] = 0;
    fprintf(stderr, "%s\n", buffer);
}

/**
 * IS_OP
 * @c:  an UNICODE value (int)
 *
 * Macro to check for operator value
 */
#ifndef IS_OP
#define IS_OP(c) (((c) == ',') || ((c) == '&') || ((c) == '|') ||	\
		  ((c) == '?') || ((c) == '-') || ((c) == '*') ||	\
		  ((c) == '{') || ((c) == '}') || ((c) == '(') ||	\
		  ((c) == ')') || ((c) == '+') || ((c) == '=') ||	\
		  ((c) == ':'))
#endif

static int
xmlCRNGIsKeyword(xmlCRelaxNGParserCtxtPtr ctxt, const xmlChar *str) {
    if ((str == ctxt->key_attribute) ||
        (str == ctxt->key_default) ||
        (str == ctxt->key_datatypes) ||
        (str == ctxt->key_div) ||
        (str == ctxt->key_element) ||
        (str == ctxt->key_empty) ||
        (str == ctxt->key_external) ||
        (str == ctxt->key_grammar) ||
        (str == ctxt->key_include) ||
        (str == ctxt->key_inherit) ||
        (str == ctxt->key_list) ||
        (str == ctxt->key_mixed) ||
        (str == ctxt->key_namespace) ||
        (str == ctxt->key_notAllowed) ||
        (str == ctxt->key_parent) ||
        (str == ctxt->key_start) ||
        (str == ctxt->key_string) ||
        (str == ctxt->key_text) ||
        (str == ctxt->key_token))
	return(1);
    return(0);

}

/*
 * xmlCRNGNextToken:
 * ctxt:  a compact RNG parser context
 *
 * Scan the schema to get the next token
 *
 * Return 0 if success and -1 in case of error
 */

static int
xmlCRNGNextToken(xmlCRelaxNGParserCtxtPtr ctxt) {
    const xmlChar *cur;
    tokenPtr token;

    if (ctxt == NULL) return(-1);
    if (ctxt->nbTokens >= MAX_TOKEN) return(-1);
    token = &(ctxt->tokens[(ctxt->firstToken + ctxt->nbTokens) % MAX_TOKEN]);
    token->toktype = CRNG_NONE;

    if (ctxt->cur == NULL) {
        ctxt->cur = ctxt->compact;
    }
retry:
    if (ctxt->cur >= ctxt->end) {
	ctxt->state = XML_CRNG_EOF;
	return(-1);
    }
    while ((ctxt->cur < ctxt->end) &&
           (IS_BLANK(*ctxt->cur))) ctxt->cur++;
    if (ctxt->cur >= ctxt->end) {
	ctxt->state = XML_CRNG_EOF;
	return(-1);
    }
    if (*ctxt->cur == '#') {
        cur = ctxt->cur;
	cur++;
	while ((cur < ctxt->end) && (*cur != '\n') && (*cur != '\r'))
	    cur++;
        ctxt->cur = cur;
	goto retry;
    } else if (*ctxt->cur == '"') {
        /* string, check for '"""' */
	ctxt->cur++;
	if (ctxt->cur >= ctxt->end) goto eof;
	cur = ctxt->cur;
        if ((ctxt->end - ctxt->end > 2) &&
	    (*cur == '"') && (cur[1] == '"')) {
	    TODO
	} else {
	    while ((cur < ctxt->end) && (*cur != '"')) cur++;
	    if (cur >= ctxt->end) goto eof;
	    token->toklen = cur - ctxt->cur;
	    token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
	    token->toktype = CRNG_LITERAL_SEGMENT;
	    token->prefix = NULL;
	    cur++;
	    ctxt->cur = cur;
	}
    } else if (*ctxt->cur == '\'') {
        /* string, check for "'''" */
	TODO
    } else if ((IS_OP(*ctxt->cur)) || (*ctxt->cur == ':')) {
        cur = ctxt->cur;
	cur++;
	if ((cur < ctxt->end) &&
	    (((*cur == '=') &&
	      ((*ctxt->cur == '|') || (*ctxt->cur == '&'))) ||
	     ((*cur == '*') && (*ctxt->cur == ':')))) {
	    token->toklen = 2;
	} else {
	    token->toklen = 1;
	}
	token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
	token->toktype = CRNG_OP;
	token->prefix = NULL;
	ctxt->cur += token->toklen;
    } else {
        int escape = 0;

        cur = ctxt->cur;
        if (*cur == '\\') {
	    escape = 1;
	    cur++;
	    ctxt->cur++;
	}
	while ((cur < ctxt->end) &&
	       (!(IS_SEPARATOR(*cur))) && (!(IS_OP(*cur)))) cur++;

	token->toklen = cur - ctxt->cur;
	token->token = xmlDictLookup(ctxt->dict, ctxt->cur, token->toklen);
	token->prefix = NULL;
	ctxt->cur = cur;
	if ((escape == 0) && (xmlCRNGIsKeyword(ctxt, token->token)))
	    token->toktype = CRNG_KEYWORD;
	else {
	    token->toktype = CRNG_IDENTIFIER;
	}
	if (*ctxt->cur == ':') {
	    ctxt->cur++;
	    if (*ctxt->cur == '*') {
		ctxt->cur++;
		token->toktype = CRNG_NSNAME;
	    } else {
	        cur = ctxt->cur;
		while ((cur < ctxt->end) &&
		       (!(IS_SEPARATOR(*cur))) && (!(IS_OP(*cur)))) cur++;
		token->prefix = token->token;
		token->toklen = cur - ctxt->cur;
		token->token = xmlDictLookup(ctxt->dict, ctxt->cur,
		                             token->toklen);
		ctxt->cur = cur;
		if (xmlValidateNCName(token->token, 0) == 0)
		    token->toktype = CRNG_QNAME;
		else {
		    TODO /* sounds like an error ! */
		    token->toktype = CRNG_IDENTIFIER;
		}
	    }
	}
    }
    ctxt->nbTokens++;
    return(0);
eof:
    ctxt->state = XML_CRNG_EOF;
    CRNG_ERROR(CRNG_END_ERROR);
    return(-1);
}

/**
 * xmlParseCRNGGetToken:
 * @ctxt: a compact RNG parser context
 * @no: the number of the token from 1 for the first one
 *      and 2, 3 ... for read-ahead
 *
 * Token reading interface
 *
 * returns a pointer to the new token, or NULL in case of error or EOF
 */
static tokenPtr
xmlParseCRNGGetToken(xmlCRelaxNGParserCtxtPtr ctxt, int no) {
    tokenPtr ret;
    int res;

    if ((no <= 0) || (no >= MAX_TOKEN)) return(NULL);
    no--;
    while (ctxt->nbTokens <= no) {
        res = xmlCRNGNextToken(ctxt);
	if (res < 0)
	    return(NULL);
    }
    ret = &(ctxt->tokens[(ctxt->firstToken + no) % MAX_TOKEN]);
    return(ret);
}

/**
 * xmlParseCRNGDropTokens:
 * @ctxt: a compact RNG parser context
 * @nr: the number of token marked as read
 *
 * mark a number of token as read and consumed.
 *
 * Returns -1 in case of error and 0 otherwise
 */
static int
xmlParseCRNGDropTokens(xmlCRelaxNGParserCtxtPtr ctxt, int nr) {
    if ((nr <= 0) || (nr >= MAX_TOKEN)) return(-1);
    while ((ctxt->nbTokens >0) && (nr > 0)) {
        ctxt->firstToken++;
	nr--;
	ctxt->nbTokens--;
	ctxt->totalToken++;
	if (ctxt->totalToken == 384)
	    fprintf(stderr, "found\n");
    }
    ctxt->firstToken = ctxt->firstToken % MAX_TOKEN;
    return(0);
}

static void
xmlParseCRNGTokenize(xmlCRelaxNGParserCtxtPtr ctxt) {
    tokenPtr token;

    token = xmlParseCRNGGetToken(ctxt, 1);
    while (token != NULL) {
        switch (token->toktype) {
            case CRNG_NONE: printf("none"); break;
            case CRNG_OP: printf("op"); break;
            case CRNG_KEYWORD: printf("keyword"); break;
            case CRNG_IDENTIFIER: printf("identifier"); break;
            case CRNG_LITERAL_SEGMENT: printf("literal"); break;
            case CRNG_CNAME: printf("cname"); break;
            case CRNG_QNAME: printf("qname"); break;
            case CRNG_NSNAME: printf("nsname"); break;
            case CRNG_DOCUMENTATION: printf("doc"); break;
	}
        printf(":%s\n", token->token);
	xmlParseCRNGDropTokens(ctxt, 1);
	token = xmlParseCRNGGetToken(ctxt, 1);
    }
}

/**
 * xmlParseCRNG_attribute:
 * @ctxt: a compact RNG parser context
 * @name: the attribute name
 * @ns: the attribute namespace
 * @value: the attribute value
 *
 * implements attribute of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_attribute(xmlCRelaxNGParserCtxtPtr ctxt,
                       const xmlChar *name,
                       xmlNsPtr ns,
		       const xmlChar *value)
{
    xmlAttrPtr attr;

    attr = xmlNewNsPropEatName(NULL, ns, (xmlChar *) name, value);
    if (attr == NULL) CRNG_MEM_ERROR0();
    attr->next = ctxt->attrs;
    if (ctxt->attrs != NULL)
        ctxt->attrs->prev = attr;
    ctxt->attrs = attr;
    return(0);
}

/**
 * xmlParseCRNG_bindPrefix:
 * @ctxt: a compact RNG parser context
 * @prefix: the namespace prefix or NULL
 * @namespace: the namespace name
 *
 * implements bindPrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_bindPrefix(xmlCRelaxNGParserCtxtPtr ctxt,
                        const xmlChar *prefix,
			const xmlChar *namespace)
{
    int ret;

    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))  &&
        (!xmlStrEqual(namespace, XML_XML_NAMESPACE))) {
	ERROR("The \"xml\" prefix must be bound to \"http://www.w3.org/XML/1998/namespace\"");
	return(-1);
    } else if ((xmlStrEqual(namespace, XML_XML_NAMESPACE)) &&
               (!xmlStrEqual(prefix, BAD_CAST "xml"))) {
	ERROR("The \"http://www.w3.org/XML/1998/namespace\" name must be bound to \"xml\" prefix");
	return(-1);
    }
    if (ctxt->namespaces == NULL)
        ctxt->namespaces = xmlHashCreate(10);
    if (ctxt->namespaces == NULL) {
        ERROR("Failed to create namespace hash table");
	return(-1);
    }
    if (prefix == NULL)
        ret = xmlHashAddEntry(ctxt->namespaces, xmlCRelaxNGDefault,
	                      (void *) namespace);
    else
        ret = xmlHashAddEntry(ctxt->namespaces, prefix,
	                      (void *) namespace);
    if (ret < 0) {
        if (prefix == NULL) {
	    ERROR("Redefinition of default namespace");
	} else {
	    ERROR("Redefinition of namespace");
	}
	return(-1);
    }

    return(0);
}

/**
 * xmlParseCRNG_bindDatatypePrefix:
 * @ctxt: a compact RNG parser context
 * @prefix: the datatype prefix
 * @namespace: the datatype identifier
 *
 * implements bindDatatypePrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_bindDatatypePrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                                const xmlChar *prefix,
			        const xmlChar *namespace)
{
    int ret;

    if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xsd"))  &&
        (!xmlStrEqual(namespace,
		  BAD_CAST "http://www.w3.org/2001/XMLSchema-datatypes"))) {
	ERROR("The \"xsd\" prefix must be bound to \"http://www.w3.org/2001/XMLSchema-datatypes\"");
	return(-1);
    }
    if (ctxt->datatypes == NULL)
        ctxt->datatypes = xmlHashCreate(10);
    if (ctxt->datatypes == NULL) {
        ERROR("Failed to create namespace hash table");
	return(-1);
    }
    ret = xmlHashAddEntry(ctxt->datatypes, prefix,
                          (void *) namespace);
    if (ret < 0) {
	ERROR("Redefinition of datatype");
	return(-1);
    }
    return(0);
}

/**
 * xmlParseCRNG_lookupPrefix:
 * @ctxt: a compact RNG parser context
 * @prefix: the namespace prefix or NULL
 *
 * implements lookupPrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns the prefix in case of success or NULL in case of error
 */
static const xmlChar *
xmlParseCRNG_lookupPrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                        const xmlChar *prefix)
{
    const xmlChar *ret;

    if (prefix == NULL)
        ret = xmlHashLookup(ctxt->namespaces, xmlCRelaxNGDefault);
    else
        ret = xmlHashLookup(ctxt->namespaces, prefix);
    return(ret);
}

/**
 * xmlParseCRNG_lookupDatatypePrefix:
 * @ctxt: a compact RNG parser context
 * @prefix: the namespace prefix or NULL
 *
 * implements lookupDatatypePrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns the prefix in case of success or NULL in case of error
 */
static const xmlChar *
xmlParseCRNG_lookupDatatypePrefix(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                        const xmlChar *prefix)
{
    const xmlChar *ret;
    ret = xmlHashLookup(ctxt->datatypes, prefix);
    return(ret);
}

/**
 * xmlParseCRNG_datatypeAttributes:
 * @ctxt: a compact RNG parser context
 * @prefix: the namespace prefix or NULL
 *
 * implements lookupPrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns the prefix in case of success or NULL in case of error
 */
static xmlAttrPtr
xmlParseCRNG_datatypeAttributes(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
                        const xmlChar *library, const xmlChar *type)
{
    xmlAttrPtr lib, typ;

    lib = xmlNewNsProp(NULL, NULL, BAD_CAST "datatypeLibrary", library);
    if (lib == NULL) {
        CRNG_MEM_ERROR();
	return(NULL);
    }
    typ = xmlNewNsProp(NULL, NULL, BAD_CAST "type", type);
    if (typ == NULL) {
        CRNG_MEM_ERROR();
	return(lib);
    }
    lib->next = typ;

    return(lib);
}

/**
 * xmlParseCRNG_XXX:
 * @ctxt: a compact RNG parser context
 *
 * Parse XXX of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_XXX(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    return(0);
}

static int xmlParseCRNG_pattern(xmlCRelaxNGParserCtxtPtr ctxt);
static int xmlParseCRNG_nameClass(xmlCRelaxNGParserCtxtPtr ctxt);

/**
 * xmlParseCRNG_params:
 * @ctxt: a compact RNG parser context
 *
 * Parse params of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_params(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    TODO
    return(0);
}

/**
 * xmlParseCRNG_exceptNameClass:
 * @ctxt: a compact RNG parser context
 *
 * Parse exceptNameClass of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_exceptNameClass(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    tokenPtr token;
    xmlNodePtr insert = ctxt->insert, cur;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if ((token->toktype == CRNG_OP) &&
        (token->token[0] == '-') && (token->token[1] == 0)) {
	xmlParseCRNGDropTokens(ctxt, 1);
	cur = xmlNewNode(NULL, BAD_CAST "except");
	if (cur == NULL) CRNG_MEM_ERROR0();
	if (ctxt->insert != NULL)
	    xmlAddChild(ctxt->insert, cur);
	ctxt->insert = cur;
	xmlParseCRNG_nameClass(ctxt);
    }
    ctxt->insert = insert;
    return(0);
}

/**
 * xmlParseCRNG_innerNameClass:
 * @ctxt: a compact RNG parser context
 *
 * Parse innerNameClass of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_innerNameClass(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;
    xmlNodePtr cur;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token->toktype == CRNG_OP) {
        if ((token->token[0] == '(') && (token->token[1] == 0)) {
	    xmlParseCRNGDropTokens(ctxt, 1);
	    xmlParseCRNG_nameClass(ctxt);
	    token = xmlParseCRNGGetToken(ctxt, 1);
	    if ((token->toktype != CRNG_OP) ||
	        (token->token[0] != ')') || (token->token[1] != 0)) {
		ERROR("Expecting \")\" here");
	    }
	    xmlParseCRNGDropTokens(ctxt, 1);
	} else if ((token->token[0] == '*') && (token->token[1] == 0)) {
	    xmlParseCRNGDropTokens(ctxt, 1);
	    cur = xmlNewNode(NULL, BAD_CAST "anyName");
	    if (cur == NULL) CRNG_MEM_ERROR0();
	    if (ctxt->insert != NULL)
		xmlAddChild(ctxt->insert, cur);
	    ctxt->insert = cur;
	    xmlParseCRNG_exceptNameClass(ctxt);
	} else {
	    TODO
	}
    } else if ((token->toktype == CRNG_IDENTIFIER) ||
               (token->toktype == CRNG_KEYWORD)) {
	cur = xmlNewNode(NULL, BAD_CAST "name");
	if (cur == NULL) CRNG_MEM_ERROR0();
	if (ctxt->isElem) {
	    xmlSetProp(cur, BAD_CAST "ns",
	               xmlParseCRNG_lookupPrefix(ctxt, NULL));
	} else {
	    xmlSetProp(cur, BAD_CAST "ns", BAD_CAST "");
	}
	xmlNodeAddContent(cur, token->token);
	if (ctxt->insert != NULL)
	    xmlAddChild(ctxt->insert, cur);
	ctxt->insert = cur;
	xmlParseCRNGDropTokens(ctxt, 1);
    } else if (token->toktype == CRNG_CNAME) {
        TODO
    } else if (token->toktype == CRNG_NSNAME) {
	cur = xmlNewNode(NULL, BAD_CAST "nsName");
	if (cur == NULL) CRNG_MEM_ERROR0();
        xmlSetProp(cur, BAD_CAST "ns",
	           xmlParseCRNG_lookupPrefix(ctxt, token->token));
	if (ctxt->insert != NULL)
	    xmlAddChild(ctxt->insert, cur);
	ctxt->insert = cur;
	xmlParseCRNGDropTokens(ctxt, 1);
	xmlParseCRNG_exceptNameClass(ctxt);
    } else {
        TODO /* probably an error */
    }

    return(0);
}

/**
 * xmlParseCRNG_nameClass:
 * @ctxt: a compact RNG parser context
 *
 * Parse nameClass of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_nameClass(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;
    xmlNodePtr insert = ctxt->insert, last, choice;

    ctxt->insert = NULL;
    xmlParseCRNG_innerNameClass(ctxt);
    last = ctxt->insert;
    token = xmlParseCRNGGetToken(ctxt, 1);
    while ((token->toktype == CRNG_OP) &&
        (token->token[0] == '|') && (token->token[1] == 0)) {
	choice = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_choice);
	xmlParseCRNGDropTokens(ctxt, 1);
	if (choice == NULL) CRNG_MEM_ERROR0();
	ctxt->insert = NULL;
	xmlParseCRNG_innerNameClass(ctxt);
	xmlAddChild(choice, last);
	xmlAddChild(choice, ctxt->insert);
	last = choice;
	token = xmlParseCRNGGetToken(ctxt, 1);
    }
    xmlAddChild(insert, last);

    ctxt->insert = insert;
    return(0);
}

/**
 * xmlParseCRNG_patternBlock:
 * @ctxt: a compact RNG parser context
 *
 * Parse a pattern block of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_patternBlock(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if ((token->toktype != CRNG_OP) ||
	(token->token[0] != '{') || (token->token[1] != 0)) {
	ERROR("Expecting \"{\" here");
    }
    xmlParseCRNGDropTokens(ctxt, 1);
    xmlParseCRNG_pattern(ctxt);
    token = xmlParseCRNGGetToken(ctxt, 1);
    if ((token->toktype != CRNG_OP) ||
	(token->token[0] != '}') || (token->token[1] != 0)) {
	ERROR("Expecting \"}\" here");
    }
    xmlParseCRNGDropTokens(ctxt, 1);
    return(0);
}

/**
 * xmlParseCRNG_datatype:
 * @ctxt: a compact RNG parser context
 *
 * Parse datatype of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_datatype(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    tokenPtr token;
    xmlAttrPtr attrs = NULL;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token->toktype == CRNG_KEYWORD) {
	if (token->token == ctxt->key_string) {
	    attrs = xmlParseCRNG_datatypeAttributes(ctxt, BAD_CAST "",
	                                            token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	} else if (token->token == ctxt->key_token) {
	    attrs = xmlParseCRNG_datatypeAttributes(ctxt, BAD_CAST "",
	                                            token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	} else {
	    TODO /* probably an error */
	}
    } else if (token->toktype == CRNG_LITERAL_SEGMENT) {
	ctxt->insert = xmlNewNode(NULL, BAD_CAST "value");
	xmlParseCRNGDropTokens(ctxt, 1);
	if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	xmlNodeAddContent(ctxt->insert, token->token);
    } else if (token->toktype == CRNG_QNAME) {
	attrs = xmlParseCRNG_datatypeAttributes(ctxt,
	            xmlParseCRNG_lookupDatatypePrefix(ctxt, token->prefix),
		    token->token);
    } else {
        TODO
    }
    if (attrs != NULL) {
	token = xmlParseCRNGGetToken(ctxt, 1);
	if (token->toktype == CRNG_LITERAL_SEGMENT) {
	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "value");
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) {
	        xmlFreePropList(attrs);
		CRNG_MEM_ERROR0();
	    }
	    ctxt->insert->properties = attrs;
	    xmlNodeAddContent(ctxt->insert, token->token);
	} else if ((token->toktype == CRNG_OP) &&
	           (token->token[0] == '{') && (token->token[0] == 0)) {
	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "data");
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) {
	        xmlFreePropList(attrs);
		CRNG_MEM_ERROR0();
	    }
	    ctxt->insert->properties = attrs;
	    xmlParseCRNG_params(ctxt);
        } else {
	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "data");
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) {
	        xmlFreePropList(attrs);
		CRNG_MEM_ERROR0();
	    }
	    ctxt->insert->properties = attrs;
	    xmlNodeAddContent(ctxt->insert, token->token);
	}
    }
    return(0);
}

/**
 * xmlParseCRNG_primary:
 * @ctxt: a compact RNG parser context
 *
 * Parse primary of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_primary(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    tokenPtr token;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token == NULL)
        return(0);
    if (token->toktype == CRNG_KEYWORD) {
        if (token->token == ctxt->key_element) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    ctxt->isElem = 1;
	    xmlParseCRNG_nameClass(ctxt);
	    xmlParseCRNG_patternBlock(ctxt);
	} else if (token->token == ctxt->key_attribute) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    ctxt->isElem = 0;
	    xmlParseCRNG_nameClass(ctxt);
	    xmlParseCRNG_patternBlock(ctxt);
	} else if (token->token == ctxt->key_mixed) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    xmlParseCRNG_patternBlock(ctxt);
	} else if (token->token == ctxt->key_list) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    xmlParseCRNG_patternBlock(ctxt);
	} else if (token->token == ctxt->key_empty) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	} else if (token->token == ctxt->key_notAllowed) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	} else if (token->token == ctxt->key_text) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	} else if (token->token == ctxt->key_parent) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    TODO
	} else if (token->token == ctxt->key_grammar) {
	    ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) token->token);
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    TODO
	} else if (token->token == ctxt->key_external) {
	    ctxt->insert = xmlNewNode(NULL, BAD_CAST "externalRef");
	    xmlParseCRNGDropTokens(ctxt, 1);
	    if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	    TODO
	} else {
	   TODO
	}
    } else if (token->toktype == CRNG_IDENTIFIER) {
	ctxt->insert = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_ref);
	if (ctxt->insert == NULL) CRNG_MEM_ERROR0();
	xmlSetProp(ctxt->insert, BAD_CAST "name", token->token);
	xmlParseCRNGDropTokens(ctxt, 1);
    } else if (token->toktype == CRNG_QNAME) {
        xmlParseCRNG_datatype(ctxt);
    } else if (token->toktype == CRNG_LITERAL_SEGMENT) {
        xmlParseCRNG_datatype(ctxt);
    } else if ((token->toktype == CRNG_OP) &&
               (token->token[0] == '(') && (token->token[1] == 0)) {
	xmlParseCRNGDropTokens(ctxt, 1);
	xmlParseCRNG_pattern(ctxt);
	token = xmlParseCRNGGetToken(ctxt, 1);
	if ((token->toktype != CRNG_OP) ||
	    (token->token[0] != ')') || (token->token[1] != 0)) {
	    ERROR("Expecting \")\" here");
	}
	xmlParseCRNGDropTokens(ctxt, 1);
    }
    return(0);
}

/**
 * xmlParseCRNG_particle:
 * @ctxt: a compact RNG parser context
 *
 * Parse particle of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_particle(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;
    xmlNodePtr insert = ctxt->insert, res, tmp = NULL;

    ctxt->insert = NULL;
    xmlParseCRNG_primary(ctxt);
    res = ctxt->insert;
    token = xmlParseCRNGGetToken(ctxt, 1);
    if ((token != NULL) && (token->toktype == CRNG_OP)) {
        if ((token->token[0] == '*') && (token->token[1] == 0)) {
	    tmp = xmlNewNode(NULL, BAD_CAST "zeroOrMore");
	    if (tmp == NULL) CRNG_MEM_ERROR0();
	} else if ((token->token[0] == '+') && (token->token[1] == 0)) {
	    tmp = xmlNewNode(NULL, BAD_CAST "oneOrMore");
	    if (tmp == NULL) CRNG_MEM_ERROR0();
	} else if ((token->token[0] == '?') && (token->token[1] == 0)) {
	    tmp = xmlNewNode(NULL, BAD_CAST "optional");
	    if (tmp == NULL) CRNG_MEM_ERROR0();
	}
	if (tmp != NULL) {
	    xmlAddChild(tmp, res);
	    res = tmp;
	    xmlParseCRNGDropTokens(ctxt, 1);
	}
    }
    if (insert != NULL) {
        xmlAddChild(insert, res);
	ctxt->insert = insert;
    } else
        ctxt->insert = res;
    return(0);
}

/**
 * xmlParseCRNG_pattern:
 * @ctxt: a compact RNG parser context
 *
 * Parse pattern of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_pattern(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;
    xmlNodePtr insert = ctxt->insert, prev, grp;

    ctxt->insert = NULL;
    xmlParseCRNG_particle(ctxt);
    prev = ctxt->insert;
    token = xmlParseCRNGGetToken(ctxt, 1);
    while ((prev != NULL) && (token != NULL) && (token->toktype == CRNG_OP)) {
        if (token->token == ctxt->key_or) {
	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_choice);
	    if (grp == NULL) CRNG_MEM_ERROR0();
	} else if (token->token == ctxt->key_and) {
	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_interleave);
	    if (grp == NULL) CRNG_MEM_ERROR0();
	} else if (token->token == ctxt->key_comma) {
	    grp = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_group);
	    if (grp == NULL) CRNG_MEM_ERROR0();
	} else
	   break;
	xmlParseCRNGDropTokens(ctxt, 1);
        ctxt->insert = NULL;
	xmlParseCRNG_particle(ctxt);
	xmlAddChild(grp, prev);
	xmlAddChild(grp, ctxt->insert);
	prev = grp;
	token = xmlParseCRNGGetToken(ctxt, 1);
    }
    if (insert != NULL) {
	xmlAddChild(insert, prev);
	ctxt->insert = insert;
    } else {
	ctxt->insert = prev;
    }

    return(0);
}

/**
 * xmlParseCRNG_component:
 * @ctxt: a compact RNG parser context
 *
 * Parse component of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_component(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token, tok2;
    xmlNodePtr insert = ctxt->insert;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token == NULL)
        return(0);
    if (token->toktype == CRNG_KEYWORD) {
        if (token->token == ctxt->key_start) {
	    xmlNodePtr start;

	    start = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_start);
	    if (start == NULL) CRNG_MEM_ERROR0();
	    if (ctxt->insert != NULL)
	        xmlAddChild(ctxt->insert, start);
	    ctxt->insert = start;
            xmlParseCRNGDropTokens(ctxt, 1);
	    token = xmlParseCRNGGetToken(ctxt, 1);

            if ((token->toktype == CRNG_OP) &&
	        (token->token == ctxt->key_equal)) {
	    } else if ((token->toktype == CRNG_OP) &&
	               (token->token == ctxt->key_orequal)) {
		xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
		                       BAD_CAST "choice");
	    } else if ((token->toktype == CRNG_OP) &&
	               (token->token == ctxt->key_andequal)) {
		xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
		                       BAD_CAST "interleave");
	    } else {
	        ERROR("expecting \"=\" or \"&=\" or \"|=\" here")
		return(-1);
	    }
	    start->properties = ctxt->attrs;
	    ctxt->attrs = NULL;
            xmlParseCRNGDropTokens(ctxt, 1);
	    xmlParseCRNG_pattern(ctxt);

	} else if (token->token == ctxt->key_include) {
	    TODO
	} else if (token->token == ctxt->key_div) {
	    TODO
	} else {
	    return(-1);
	}
    } else if (token->toktype == CRNG_IDENTIFIER) {
        xmlNodePtr define;
	const xmlChar *identifier;

        identifier = token->token;
	tok2 = xmlParseCRNGGetToken(ctxt, 2);
	if ((tok2->toktype == CRNG_OP) &&
	    (tok2->token == ctxt->key_equal)) {
	} else if ((tok2->toktype == CRNG_OP) &&
		   (tok2->token == ctxt->key_orequal)) {
	    xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
				   BAD_CAST "choice");
	} else if ((tok2->toktype == CRNG_OP) &&
		   (tok2->token == ctxt->key_andequal)) {
	    xmlParseCRNG_attribute(ctxt, ctxt->key_combine, NULL,
				   BAD_CAST "interleave");
	} else {
	    ERROR("expecting \"=\" or \"&=\" or \"|=\" here")
	    return(-1);
	}
	xmlParseCRNGDropTokens(ctxt, 2);

	define = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_define);
	if (define == NULL) CRNG_MEM_ERROR0();
	define->properties = ctxt->attrs;
	ctxt->attrs = NULL;
	xmlSetProp(define, BAD_CAST "name", identifier);
	if (ctxt->insert != NULL)
	    xmlAddChild(ctxt->insert, define);
	ctxt->insert = define;
	xmlParseCRNG_pattern(ctxt);
    } else {
	return(-1);
    }
    ctxt->insert = insert;
    return(0);
}

/**
 * xmlParseCRNG_grammar:
 * @ctxt: a compact RNG parser context
 *
 * Parse grammar of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_grammar(xmlCRelaxNGParserCtxtPtr ctxt ATTRIBUTE_UNUSED)
{
    tokenPtr token;
    int ret;

    token = xmlParseCRNGGetToken(ctxt, 1);
    while (token != NULL) {
        ret = xmlParseCRNG_component(ctxt);
	if (ret != 0)
	    break;
	token = xmlParseCRNGGetToken(ctxt, 1);
    }
    return(0);
}

/**
 * xmlParseCRNG_topLevelBody:
 * @ctxt: a compact RNG parser context
 *
 * Parse topLevelBody of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_topLevelBody(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token, tok2;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token->toktype == CRNG_KEYWORD) {
        if ((token->token == ctxt->key_start) ||
	    (token->token == ctxt->key_include) ||
	    (token->token == ctxt->key_div)) {
	    xmlNodePtr grammar;

	    grammar = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_grammar);
	    if (grammar == NULL) CRNG_MEM_ERROR0();
	    xmlDocSetRootElement(ctxt->doc, grammar);
	    ctxt->insert = grammar;

	    xmlParseCRNG_grammar(ctxt);
	} else {
	    xmlParseCRNG_pattern(ctxt);
	}
    } else {
        tok2 = xmlParseCRNGGetToken(ctxt, 2);
	if ((tok2->toktype == CRNG_OP) &&
	    ((tok2->token == ctxt->key_equal) ||
	     (tok2->token == ctxt->key_orequal) ||
	     (tok2->token == ctxt->key_andequal))) {
	    xmlNodePtr grammar;

	    grammar = xmlNewNodeEatName(NULL, (xmlChar *) ctxt->key_grammar);
	    if (grammar == NULL) CRNG_MEM_ERROR0();
	    xmlDocSetRootElement(ctxt->doc, grammar);
	    ctxt->insert = grammar;

	    xmlParseCRNG_grammar(ctxt);
	} else {
	    xmlParseCRNG_pattern(ctxt);
	}
    }
    return(0);
}

/**
 * xmlParseCRNG_namespacePrefix:
 * @ctxt: a compact RNG parser context
 *
 * Parse namespacePrefix of the RELAX NG Compact Syntax Appendix A
 *
 * Returns the prefix or NULL in case of error
 */
static const xmlChar *
xmlParseCRNG_namespacePrefix(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;
    const xmlChar *prefix = NULL;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token->toktype == CRNG_IDENTIFIER) {
        prefix = token->token;
    } else if (token->toktype == CRNG_OP) {
	if ((token->token[0] == '=') && (token->token[1] == 0))
	    return(NULL);
        prefix = token->token;
    } else {
	ERROR("Expecting a namespace prefix");
	return(NULL);
    }
    xmlParseCRNGDropTokens(ctxt, 1);

    if (xmlStrEqual(prefix, BAD_CAST "xmlns")) {
	ERROR("Namespace prefix \"xmlns\" is forbidden");
    }
    return(prefix);
}

/**
 * xmlParseCRNG_decl:
 * @ctxt: a compact RNG parser context
 *
 * Parse decl of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_decl(xmlCRelaxNGParserCtxtPtr ctxt)
{
    const xmlChar *prefix = NULL;
    const xmlChar *namespace = NULL;
    tokenPtr token;

    token = xmlParseCRNGGetToken(ctxt, 1);
    if (token->toktype != CRNG_KEYWORD) return(-1);
    if (token->token == ctxt->key_default) {
        xmlParseCRNGDropTokens(ctxt, 1);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype != CRNG_KEYWORD) ||
	    (token->token != ctxt->key_namespace)) {
	    ERROR("Expecting keyword \"namespace\" after \"default\"");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
	prefix = xmlParseCRNG_namespacePrefix(ctxt);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype != CRNG_OP) ||
	    (token->token[0] != '=') || (token->token[1] != 0)) {
	    ERROR("Expecting keyword \"=\" here");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype == CRNG_KEYWORD) &&
	    (token->token == ctxt->key_inherit)) {
	    namespace = xmlCRelaxNGInherit;
	} else if (token->toktype == CRNG_LITERAL_SEGMENT) {
	    namespace = token->token;
	} else {
	    ERROR("Expecting an URI or \"inherit\" value");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        if (namespace != NULL) {
	    if (prefix != NULL)
		xmlParseCRNG_bindPrefix(ctxt, prefix, namespace);
            xmlParseCRNG_bindPrefix(ctxt, NULL, namespace);
	}
    } else if (token->token == ctxt->key_namespace) {
        xmlParseCRNGDropTokens(ctxt, 1);
	prefix = xmlParseCRNG_namespacePrefix(ctxt);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype != CRNG_OP) ||
	    (token->token[0] != '=') || (token->token[1] != 0)) {
	    ERROR("Expecting keyword \"=\" here");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype == CRNG_KEYWORD) &&
	    (token->token == ctxt->key_inherit)) {
	    namespace = xmlCRelaxNGInherit;
	} else if (token->toktype == CRNG_LITERAL_SEGMENT) {
	    namespace = token->token;
	} else {
	    ERROR("Expecting an URI or \"inherit\" value");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        if (namespace != NULL)
	    xmlParseCRNG_bindPrefix(ctxt, prefix, namespace);
    } else if (token->token == ctxt->key_datatypes) {
        xmlParseCRNGDropTokens(ctxt, 1);

        token = xmlParseCRNGGetToken(ctxt, 1);
	if ((token->toktype != CRNG_KEYWORD) &&
	    (token->toktype != CRNG_IDENTIFIER)) {
	    ERROR("Expecting a datatype prefix identifier here");
	} else
	    prefix = token->token;
        xmlParseCRNGDropTokens(ctxt, 1);
        token = xmlParseCRNGGetToken(ctxt, 1);
        if ((token->toktype != CRNG_OP) ||
	    (token->token[0] != '=') || (token->token[1] != 0)) {
	    ERROR("Expecting keyword \"=\" here");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        token = xmlParseCRNGGetToken(ctxt, 1);
	if (token->toktype == CRNG_LITERAL_SEGMENT) {
	    namespace = token->token;
	} else {
	    ERROR("Expecting a literal value for the datatype identifier");
	}
        xmlParseCRNGDropTokens(ctxt, 1);
        if ((namespace != NULL) && (prefix != NULL))
	    xmlParseCRNG_bindDatatypePrefix(ctxt, prefix, namespace);
    }

    return(0);
}

/**
 * xmlParseCRNG_preamble:
 * @ctxt: a compact RNG parser context
 *
 * Parse preamble of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_preamble(xmlCRelaxNGParserCtxtPtr ctxt)
{
    tokenPtr token;

    token = xmlParseCRNGGetToken(ctxt, 1);
    while (token != NULL) {
	if (token == NULL) return(-1);
	if ((token->toktype == CRNG_KEYWORD) &&
	    ((token->token == ctxt->key_default) ||
	     (token->token == ctxt->key_namespace) ||
	     (token->token == ctxt->key_datatypes))) {
	    xmlParseCRNG_decl(ctxt);
	} else
	    break;
	token = xmlParseCRNGGetToken(ctxt, 1);
    }
    return(0);
}

/**
 * xmlParseCRNG_topLevel:
 * @ctxt: a compact RNG parser context
 *
 * Parse topLevel of the RELAX NG Compact Syntax Appendix A
 *
 * Returns 0 in case of success and -1 in case of error
 */
static int
xmlParseCRNG_topLevel(xmlCRelaxNGParserCtxtPtr ctxt)
{
    xmlParseCRNG_preamble(ctxt);
    xmlParseCRNG_topLevelBody(ctxt);
    return(0);
}

/**
 * xmlConvertCRNG:
 * @schemas:  pointer to the text of the compact schemas
 * @len:  length of the schemas in bytes (or 0)
 * @encoding:  encoding indicated by the context or NULL
 *
 * Compiles the schemas into the equivalent Relax-NG XML structure
 *
 * Returns the xmlDocPtr resulting from the compilation or
 *         NULL in case of error
 */
xmlDocPtr
xmlConvertCRNG(const char *schemas, int len, const char *encoding) {
    struct _xmlCRelaxNGParserCtxt ctxt;
    xmlDocPtr ret = NULL;

    if (schemas == NULL) return(NULL);
    if (len <= 5) len = xmlStrlen((const unsigned char *) schemas);
    if (len <= 0) return(NULL);

    memset(&ctxt, 0, sizeof(ctxt));
    ctxt.compact = (const unsigned char *) schemas;
    ctxt.cur = (const unsigned char *) schemas;
    ctxt.end = (const unsigned char *) &schemas[len];
    ctxt.dict = xmlDictCreate();
    if (ctxt.dict == NULL)
        return(NULL);
    ctxt.doc = xmlNewDoc(NULL);
    if (ctxt.doc == NULL) {
	xmlDictFree(ctxt.dict);
	return(NULL);
    }
    ctxt.doc->dict = ctxt.dict;
    xmlDictReference(ctxt.dict);

    ctxt.nbTokens = 0;
    ctxt.firstToken = 0;
    ctxt.key_attribute = xmlDictLookup(ctxt.dict, BAD_CAST "attribute", -1);
    ctxt.key_default = xmlDictLookup(ctxt.dict, BAD_CAST "default", -1);
    ctxt.key_datatypes = xmlDictLookup(ctxt.dict, BAD_CAST "datatypes", -1);
    ctxt.key_div = xmlDictLookup(ctxt.dict, BAD_CAST "div", -1);
    ctxt.key_element = xmlDictLookup(ctxt.dict, BAD_CAST "element", -1);
    ctxt.key_empty = xmlDictLookup(ctxt.dict, BAD_CAST "empty", -1);
    ctxt.key_external = xmlDictLookup(ctxt.dict, BAD_CAST "external", -1);
    ctxt.key_grammar = xmlDictLookup(ctxt.dict, BAD_CAST "grammar", -1);
    ctxt.key_include = xmlDictLookup(ctxt.dict, BAD_CAST "include", -1);
    ctxt.key_inherit = xmlDictLookup(ctxt.dict, BAD_CAST "inherit", -1);
    ctxt.key_list = xmlDictLookup(ctxt.dict, BAD_CAST "list", -1);
    ctxt.key_mixed = xmlDictLookup(ctxt.dict, BAD_CAST "mixed", -1);
    ctxt.key_namespace = xmlDictLookup(ctxt.dict, BAD_CAST "namespace", -1);
    ctxt.key_notAllowed = xmlDictLookup(ctxt.dict, BAD_CAST "notAllowed", -1);
    ctxt.key_parent = xmlDictLookup(ctxt.dict, BAD_CAST "parent", -1);
    ctxt.key_start = xmlDictLookup(ctxt.dict, BAD_CAST "start", -1);
    ctxt.key_string = xmlDictLookup(ctxt.dict, BAD_CAST "string", -1);
    ctxt.key_text = xmlDictLookup(ctxt.dict, BAD_CAST "text", -1);
    ctxt.key_token = xmlDictLookup(ctxt.dict, BAD_CAST "token", -1);
    ctxt.key_equal = xmlDictLookup(ctxt.dict, BAD_CAST "=", 1);
    ctxt.key_orequal = xmlDictLookup(ctxt.dict, BAD_CAST "|=", 2);
    ctxt.key_andequal = xmlDictLookup(ctxt.dict, BAD_CAST "&=", 2);
    ctxt.key_combine = xmlDictLookup(ctxt.dict, BAD_CAST "&=", 2);
    ctxt.key_or = xmlDictLookup(ctxt.dict, BAD_CAST "|", 1);
    ctxt.key_comma = xmlDictLookup(ctxt.dict, BAD_CAST ",", 1);
    ctxt.key_and = xmlDictLookup(ctxt.dict, BAD_CAST "&", 1);
    ctxt.key_choice = xmlDictLookup(ctxt.dict, BAD_CAST "choice", -1);
    ctxt.key_group = xmlDictLookup(ctxt.dict, BAD_CAST "group", -1);
    ctxt.key_interleave = xmlDictLookup(ctxt.dict, BAD_CAST "interleave", -1);
    ctxt.key_ref = xmlDictLookup(ctxt.dict, BAD_CAST "ref", 3);
    ctxt.key_define = xmlDictLookup(ctxt.dict, BAD_CAST "define", 6);

    /* xmlConvertCRNGTokenize(&ctxt); */
    xmlConvertCRNG_topLevel(&ctxt);

    xmlDictFree(ctxt.dict);

    ret = ctxt.doc;
    return(ret);
}

/**
 * xmlConvertCRNGFile:
 * @URL: URL or filename for the resource
 * @encoding:  encoding indicated by the context or NULL
 *
 * Compiles the schemas into the equivalent Relax-NG XML structure
 *
 * Returns the xmlDocPtr resulting from the compilation or
 *         NULL in case of error
 */
xmlDocPtr
xmlConvertCRNGFile(const char *URL, const char *encoding) {
}

#ifdef STANDALONE
const xmlChar *schemas =
"# RELAX NG XML syntax specified in compact syntax.\n\
\n\
default namespace rng = \"http://relaxng.org/ns/structure/1.0\"\n\
namespace local = \"\"\n\
datatypes xsd = \"http://www.w3.org/2001/XMLSchema-datatypes\"\n\
\n\
start = pattern\n\
\n\
pattern =\n\
  element element { (nameQName | nameClass), (common & pattern+) }\n\
  | element attribute { (nameQName | nameClass), (common & pattern?) }\n\
  | element group|interleave|choice|optional\n\
            |zeroOrMore|oneOrMore|list|mixed { common & pattern+ }\n\
  | element ref|parentRef { nameNCName, common }\n\
  | element empty|notAllowed|text { common }\n\
  | element data { type, param*, (common & exceptPattern?) }\n\
  | element value { commonAttributes, type?, xsd:string }\n\
  | element externalRef { href, common }\n\
  | element grammar { common & grammarContent* }\n\
\n\
param = element param { commonAttributes, nameNCName, xsd:string }\n\
\n\
exceptPattern = element except { common & pattern+ }\n\
\n\
grammarContent =\n\
  definition\n\
  | element div { common & grammarContent* }\n\
  | element include { href, (common & includeContent*) }\n\
\n\
includeContent =\n\
  definition\n\
  | element div { common & includeContent* }\n\
\n\
definition =\n\
  element start { combine?, (common & pattern+) }\n\
  | element define { nameNCName, combine?, (common & pattern+) }\n\
\n\
combine = attribute combine { \"choice\" | \"interleave\" }\n\
\n\
nameClass =\n\
  element name { commonAttributes, xsd:QName }\n\
  | element anyName { common & exceptNameClass? }\n\
  | element nsName { common & exceptNameClass? }\n\
  | element choice { common & nameClass+ }\n\
\n\
exceptNameClass = element except { common & nameClass+ }\n\
\n\
nameQName = attribute name { xsd:QName }\n\
nameNCName = attribute name { xsd:NCName }\n\
href = attribute href { xsd:anyURI }\n\
type = attribute type { xsd:NCName }\n\
\n\
common = commonAttributes, foreignElement*\n\
\n\
commonAttributes =\n\
  attribute ns { xsd:string }?,\n\
  attribute datatypeLibrary { xsd:anyURI }?,\n\
  foreignAttribute*\n\
\n\
foreignElement = element * - rng:* { (anyAttribute | text | anyElement)* }\n\
foreignAttribute = attribute * - (rng:*|local:*) { text }\n\
anyElement = element * { (anyAttribute | text | anyElement)* }\n\
anyAttribute = attribute * { text }\n\
";

int main(int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED) {
    xmlDocPtr res;

    res = xmlConvertCRNG(schemas, -1);
    if (res != NULL) {
        xmlDocFormatDump(stdout, res, 1);
	xmlFreeDoc(res);
    }
    return(0);
}
#endif
#define bottom_rngparser
#include "elfgcchack.h"
