/**
 * 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;

    /*
     * dictionnary 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"
