⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 relaxng.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    ret->nbAttrLeft = ret->nbAttrs;
    return (ret);
}

/**
 * xmlRelaxNGCopyValidState:
 * @ctxt:  a Relax-NG validation context
 * @state:  a validation state
 *
 * Copy the validation state
 *
 * Returns the newly allocated structure or NULL in case or error
 */
static xmlRelaxNGValidStatePtr
xmlRelaxNGCopyValidState(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidStatePtr state)
{
    xmlRelaxNGValidStatePtr ret;
    unsigned int maxAttrs;
    xmlAttrPtr *attrs;

    if (state == NULL)
        return (NULL);
    if ((ctxt->freeState != NULL) && (ctxt->freeState->nbState > 0)) {
        ctxt->freeState->nbState--;
        ret = ctxt->freeState->tabState[ctxt->freeState->nbState];
    } else {
        ret =
            (xmlRelaxNGValidStatePtr)
            xmlMalloc(sizeof(xmlRelaxNGValidState));
        if (ret == NULL) {
            xmlRngVErrMemory(ctxt, "allocating states\n");
            return (NULL);
        }
        memset(ret, 0, sizeof(xmlRelaxNGValidState));
    }
    attrs = ret->attrs;
    maxAttrs = ret->maxAttrs;
    memcpy(ret, state, sizeof(xmlRelaxNGValidState));
    ret->attrs = attrs;
    ret->maxAttrs = maxAttrs;
    if (state->nbAttrs > 0) {
        if (ret->attrs == NULL) {
            ret->maxAttrs = state->maxAttrs;
            ret->attrs = (xmlAttrPtr *) xmlMalloc(ret->maxAttrs *
                                                  sizeof(xmlAttrPtr));
            if (ret->attrs == NULL) {
                xmlRngVErrMemory(ctxt, "allocating states\n");
                ret->nbAttrs = 0;
                return (ret);
            }
        } else if (ret->maxAttrs < state->nbAttrs) {
            xmlAttrPtr *tmp;

            tmp = (xmlAttrPtr *) xmlRealloc(ret->attrs, state->maxAttrs *
                                            sizeof(xmlAttrPtr));
            if (tmp == NULL) {
                xmlRngVErrMemory(ctxt, "allocating states\n");
                ret->nbAttrs = 0;
                return (ret);
            }
            ret->maxAttrs = state->maxAttrs;
            ret->attrs = tmp;
        }
        memcpy(ret->attrs, state->attrs,
               state->nbAttrs * sizeof(xmlAttrPtr));
    }
    return (ret);
}

/**
 * xmlRelaxNGEqualValidState:
 * @ctxt:  a Relax-NG validation context
 * @state1:  a validation state
 * @state2:  a validation state
 *
 * Compare the validation states for equality
 *
 * Returns 1 if equald, 0 otherwise
 */
static int
xmlRelaxNGEqualValidState(xmlRelaxNGValidCtxtPtr ctxt ATTRIBUTE_UNUSED,
                          xmlRelaxNGValidStatePtr state1,
                          xmlRelaxNGValidStatePtr state2)
{
    int i;

    if ((state1 == NULL) || (state2 == NULL))
        return (0);
    if (state1 == state2)
        return (1);
    if (state1->node != state2->node)
        return (0);
    if (state1->seq != state2->seq)
        return (0);
    if (state1->nbAttrLeft != state2->nbAttrLeft)
        return (0);
    if (state1->nbAttrs != state2->nbAttrs)
        return (0);
    if (state1->endvalue != state2->endvalue)
        return (0);
    if ((state1->value != state2->value) &&
        (!xmlStrEqual(state1->value, state2->value)))
        return (0);
    for (i = 0; i < state1->nbAttrs; i++) {
        if (state1->attrs[i] != state2->attrs[i])
            return (0);
    }
    return (1);
}

/**
 * xmlRelaxNGFreeValidState:
 * @state:  a validation state structure
 *
 * Deallocate a RelaxNG validation state structure.
 */
static void
xmlRelaxNGFreeValidState(xmlRelaxNGValidCtxtPtr ctxt,
                         xmlRelaxNGValidStatePtr state)
{
    if (state == NULL)
        return;

    if ((ctxt != NULL) && (ctxt->freeState == NULL)) {
        ctxt->freeState = xmlRelaxNGNewStates(ctxt, 40);
    }
    if ((ctxt == NULL) || (ctxt->freeState == NULL)) {
        if (state->attrs != NULL)
            xmlFree(state->attrs);
        xmlFree(state);
    } else {
        xmlRelaxNGAddStatesUniq(ctxt, ctxt->freeState, state);
    }
}

/************************************************************************
 * 									*
 * 			Semi internal functions				*
 * 									*
 ************************************************************************/

/**
 * xmlRelaxParserSetFlag:
 * @ctxt: a RelaxNG parser context
 * @flags: a set of flags values
 *
 * Semi private function used to pass informations to a parser context
 * which are a combination of xmlRelaxNGParserFlag .
 *
 * Returns 0 if success and -1 in case of error
 */
int
xmlRelaxParserSetFlag(xmlRelaxNGParserCtxtPtr ctxt, int flags)
{
    if (ctxt == NULL) return(-1);
    if (flags & XML_RELAXNGP_FREE_DOC) {
        ctxt->crng |= XML_RELAXNGP_FREE_DOC;
	flags -= XML_RELAXNGP_FREE_DOC;
    }
    if (flags & XML_RELAXNGP_CRNG) {
        ctxt->crng |= XML_RELAXNGP_CRNG;
	flags -= XML_RELAXNGP_CRNG;
    }
    if (flags != 0) return(-1);
    return(0);
}

/************************************************************************
 * 									*
 * 			Document functions				*
 * 									*
 ************************************************************************/
static xmlDocPtr xmlRelaxNGCleanupDoc(xmlRelaxNGParserCtxtPtr ctxt,
                                      xmlDocPtr doc);

/**
 * xmlRelaxNGIncludePush:
 * @ctxt:  the parser context
 * @value:  the element doc
 *
 * Pushes a new include on top of the include stack
 *
 * Returns 0 in case of error, the index in the stack otherwise
 */
static int
xmlRelaxNGIncludePush(xmlRelaxNGParserCtxtPtr ctxt,
                      xmlRelaxNGIncludePtr value)
{
    if (ctxt->incTab == NULL) {
        ctxt->incMax = 4;
        ctxt->incNr = 0;
        ctxt->incTab =
            (xmlRelaxNGIncludePtr *) xmlMalloc(ctxt->incMax *
                                               sizeof(ctxt->incTab[0]));
        if (ctxt->incTab == NULL) {
            xmlRngPErrMemory(ctxt, "allocating include\n");
            return (0);
        }
    }
    if (ctxt->incNr >= ctxt->incMax) {
        ctxt->incMax *= 2;
        ctxt->incTab =
            (xmlRelaxNGIncludePtr *) xmlRealloc(ctxt->incTab,
                                                ctxt->incMax *
                                                sizeof(ctxt->incTab[0]));
        if (ctxt->incTab == NULL) {
            xmlRngPErrMemory(ctxt, "allocating include\n");
            return (0);
        }
    }
    ctxt->incTab[ctxt->incNr] = value;
    ctxt->inc = value;
    return (ctxt->incNr++);
}

/**
 * xmlRelaxNGIncludePop:
 * @ctxt: the parser context
 *
 * Pops the top include from the include stack
 *
 * Returns the include just removed
 */
static xmlRelaxNGIncludePtr
xmlRelaxNGIncludePop(xmlRelaxNGParserCtxtPtr ctxt)
{
    xmlRelaxNGIncludePtr ret;

    if (ctxt->incNr <= 0)
        return (0);
    ctxt->incNr--;
    if (ctxt->incNr > 0)
        ctxt->inc = ctxt->incTab[ctxt->incNr - 1];
    else
        ctxt->inc = NULL;
    ret = ctxt->incTab[ctxt->incNr];
    ctxt->incTab[ctxt->incNr] = 0;
    return (ret);
}

/**
 * xmlRelaxNGRemoveRedefine:
 * @ctxt: the parser context
 * @URL:  the normalized URL
 * @target:  the included target
 * @name:  the define name to eliminate
 *
 * Applies the elimination algorithm of 4.7
 *
 * Returns 0 in case of error, 1 in case of success.
 */
static int
xmlRelaxNGRemoveRedefine(xmlRelaxNGParserCtxtPtr ctxt,
                         const xmlChar * URL ATTRIBUTE_UNUSED,
                         xmlNodePtr target, const xmlChar * name)
{
    int found = 0;
    xmlNodePtr tmp, tmp2;
    xmlChar *name2;

#ifdef DEBUG_INCLUDE
    if (name == NULL)
        xmlGenericError(xmlGenericErrorContext,
                        "Elimination of <include> start from %s\n", URL);
    else
        xmlGenericError(xmlGenericErrorContext,
                        "Elimination of <include> define %s from %s\n",
                        name, URL);
#endif
    tmp = target;
    while (tmp != NULL) {
        tmp2 = tmp->next;
        if ((name == NULL) && (IS_RELAXNG(tmp, "start"))) {
            found = 1;
            xmlUnlinkNode(tmp);
            xmlFreeNode(tmp);
        } else if ((name != NULL) && (IS_RELAXNG(tmp, "define"))) {
            name2 = xmlGetProp(tmp, BAD_CAST "name");
            xmlRelaxNGNormExtSpace(name2);
            if (name2 != NULL) {
                if (xmlStrEqual(name, name2)) {
                    found = 1;
                    xmlUnlinkNode(tmp);
                    xmlFreeNode(tmp);
                }
                xmlFree(name2);
            }
        } else if (IS_RELAXNG(tmp, "include")) {
            xmlChar *href = NULL;
            xmlRelaxNGDocumentPtr inc = tmp->psvi;

            if ((inc != NULL) && (inc->doc != NULL) &&
                (inc->doc->children != NULL)) {

                if (xmlStrEqual
                    (inc->doc->children->name, BAD_CAST "grammar")) {
#ifdef DEBUG_INCLUDE
                    href = xmlGetProp(tmp, BAD_CAST "href");
#endif
                    if (xmlRelaxNGRemoveRedefine(ctxt, href,
                                                 inc->doc->children->
                                                 children, name) == 1) {
                        found = 1;
                    }
                    if (href != NULL)
                        xmlFree(href);
                }
            }
        }
        tmp = tmp2;
    }
    return (found);
}

/**
 * xmlRelaxNGLoadInclude:
 * @ctxt: the parser context
 * @URL:  the normalized URL
 * @node: the include node.
 * @ns:  the namespace passed from the context.
 *
 * First lookup if the document is already loaded into the parser context,
 * check against recursion. If not found the resource is loaded and
 * the content is preprocessed before being returned back to the caller.
 *
 * Returns the xmlRelaxNGIncludePtr or NULL in case of error
 */
static xmlRelaxNGIncludePtr
xmlRelaxNGLoadInclude(xmlRelaxNGParserCtxtPtr ctxt, const xmlChar * URL,
                      xmlNodePtr node, const xmlChar * ns)
{
    xmlRelaxNGIncludePtr ret = NULL;
    xmlDocPtr doc;
    int i;
    xmlNodePtr root, cur;

#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext,
                    "xmlRelaxNGLoadInclude(%s)\n", URL);
#endif

    /*
     * check against recursion in the stack
     */
    for (i = 0; i < ctxt->incNr; i++) {
        if (xmlStrEqual(ctxt->incTab[i]->href, URL)) {
            xmlRngPErr(ctxt, NULL, XML_RNGP_INCLUDE_RECURSE,
                       "Detected an Include recursion for %s\n", URL,
                       NULL);
            return (NULL);
        }
    }

    /*
     * load the document
     */
    doc = xmlReadFile((const char *) URL,NULL,0);
    if (doc == NULL) {
        xmlRngPErr(ctxt, node, XML_RNGP_PARSE_ERROR,
                   "xmlRelaxNG: could not load %s\n", URL, NULL);
        return (NULL);
    }
#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext, "Parsed %s Okay\n", URL);
#endif

    /*
     * Allocate the document structures and register it first.
     */
    ret = (xmlRelaxNGIncludePtr) xmlMalloc(sizeof(xmlRelaxNGInclude));
    if (ret == NULL) {
        xmlRngPErrMemory(ctxt, "allocating include\n");
        xmlFreeDoc(doc);
        return (NULL);
    }
    memset(ret, 0, sizeof(xmlRelaxNGInclude));
    ret->doc = doc;
    ret->href = xmlStrdup(URL);
    ret->next = ctxt->includes;
    ctxt->includes = ret;

    /*
     * transmit the ns if needed
     */
    if (ns != NULL) {
        root = xmlDocGetRootElement(doc);
        if (root != NULL) {
            if (xmlHasProp(root, BAD_CAST "ns") == NULL) {
                xmlSetProp(root, BAD_CAST "ns", ns);
            }
        }
    }

    /*
     * push it on the stack
     */
    xmlRelaxNGIncludePush(ctxt, ret);

    /*
     * Some preprocessing of the document content, this include recursing
     * in the include stack.
     */
#ifdef DEBUG_INCLUDE
    xmlGenericError(xmlGenericErrorContext, "cleanup of %s\n", URL);
#endif

    doc = xmlRelaxNGCleanupDoc(ctxt, doc);
    if (doc == NULL) {
        ctxt->inc = NULL;
        return (NULL);
    }

    /*
     * Pop up the include from the stack

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -