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