📄 tree.c
字号:
return(0);
}
/**
* xmlValidateName:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of Name
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
xmlValidateName(const xmlChar *value, int space) {
const xmlChar *cur = value;
int c,l;
if (value == NULL)
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
while (IS_BLANK_CH(*cur)) cur++;
if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
(*cur == '_') || (*cur == ':'))
cur++;
else
goto try_complex;
while (((*cur >= 'a') && (*cur <= 'z')) ||
((*cur >= 'A') && (*cur <= 'Z')) ||
((*cur >= '0') && (*cur <= '9')) ||
(*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
cur++;
if (space)
while (IS_BLANK_CH(*cur)) cur++;
if (*cur == 0)
return(0);
try_complex:
/*
* Second check for chars outside the ASCII range
*/
cur = value;
c = CUR_SCHAR(cur, l);
if (space) {
while (IS_BLANK(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
}
if ((!IS_LETTER(c)) && (c != '_') && (c != ':'))
return(1);
cur += l;
c = CUR_SCHAR(cur, l);
while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
(c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
}
if (c != 0)
return(1);
return(0);
}
/**
* xmlValidateNMToken:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of NMToken
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
xmlValidateNMToken(const xmlChar *value, int space) {
const xmlChar *cur = value;
int c,l;
if (value == NULL)
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
while (IS_BLANK_CH(*cur)) cur++;
if (((*cur >= 'a') && (*cur <= 'z')) ||
((*cur >= 'A') && (*cur <= 'Z')) ||
((*cur >= '0') && (*cur <= '9')) ||
(*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
cur++;
else
goto try_complex;
while (((*cur >= 'a') && (*cur <= 'z')) ||
((*cur >= 'A') && (*cur <= 'Z')) ||
((*cur >= '0') && (*cur <= '9')) ||
(*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
cur++;
if (space)
while (IS_BLANK_CH(*cur)) cur++;
if (*cur == 0)
return(0);
try_complex:
/*
* Second check for chars outside the ASCII range
*/
cur = value;
c = CUR_SCHAR(cur, l);
if (space) {
while (IS_BLANK(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
}
if (!(IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
(c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)))
return(1);
cur += l;
c = CUR_SCHAR(cur, l);
while (IS_LETTER(c) || IS_DIGIT(c) || (c == '.') || (c == ':') ||
(c == '-') || (c == '_') || IS_COMBINING(c) || IS_EXTENDER(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
c = CUR_SCHAR(cur, l);
}
}
if (c != 0)
return(1);
return(0);
}
#endif /* LIBXML_TREE_ENABLED */
/************************************************************************
* *
* Allocation and deallocation of basic structures *
* *
************************************************************************/
/**
* xmlSetBufferAllocationScheme:
* @scheme: allocation method to use
*
* Set the buffer allocation method. Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*/
void
xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
xmlBufferAllocScheme = scheme;
}
/**
* xmlGetBufferAllocationScheme:
*
* Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*
* Returns the current allocation scheme
*/
xmlBufferAllocationScheme
xmlGetBufferAllocationScheme(void) {
return(xmlBufferAllocScheme);
}
/**
* xmlNewNs:
* @node: the element carrying the namespace
* @href: the URI associated
* @prefix: the prefix for the namespace
*
* Creation of a new Namespace. This function will refuse to create
* a namespace with a similar prefix than an existing one present on this
* node.
* We use href==NULL in the case of an element creation where the namespace
* was not defined.
* Returns a new namespace pointer or NULL
*/
xmlNsPtr
xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
xmlNsPtr cur;
if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
return(NULL);
if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
return(NULL);
/*
* Allocate a new Namespace and fill the fields.
*/
cur = (xmlNsPtr) xmlMalloc(sizeof(xmlNs));
if (cur == NULL) {
xmlTreeErrMemory("building namespace");
return(NULL);
}
memset(cur, 0, sizeof(xmlNs));
cur->type = XML_LOCAL_NAMESPACE;
if (href != NULL)
cur->href = xmlStrdup(href);
if (prefix != NULL)
cur->prefix = xmlStrdup(prefix);
/*
* Add it at the end to preserve parsing order ...
* and checks for existing use of the prefix
*/
if (node != NULL) {
if (node->nsDef == NULL) {
node->nsDef = cur;
} else {
xmlNsPtr prev = node->nsDef;
if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
(xmlStrEqual(prev->prefix, cur->prefix))) {
xmlFreeNs(cur);
return(NULL);
}
while (prev->next != NULL) {
prev = prev->next;
if (((prev->prefix == NULL) && (cur->prefix == NULL)) ||
(xmlStrEqual(prev->prefix, cur->prefix))) {
xmlFreeNs(cur);
return(NULL);
}
}
prev->next = cur;
}
}
return(cur);
}
/**
* xmlSetNs:
* @node: a node in the document
* @ns: a namespace pointer
*
* Associate a namespace to a node, a posteriori.
*/
void
xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
if (node == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlSetNs: node == NULL\n");
#endif
return;
}
node->ns = ns;
}
/**
* xmlFreeNs:
* @cur: the namespace pointer
*
* Free up the structures associated to a namespace
*/
void
xmlFreeNs(xmlNsPtr cur) {
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlFreeNs : ns == NULL\n");
#endif
return;
}
if (cur->href != NULL) xmlFree((char *) cur->href);
if (cur->prefix != NULL) xmlFree((char *) cur->prefix);
xmlFree(cur);
}
/**
* xmlFreeNsList:
* @cur: the first namespace pointer
*
* Free up all the structures associated to the chained namespaces.
*/
void
xmlFreeNsList(xmlNsPtr cur) {
xmlNsPtr next;
if (cur == NULL) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlFreeNsList : ns == NULL\n");
#endif
return;
}
while (cur != NULL) {
next = cur->next;
xmlFreeNs(cur);
cur = next;
}
}
/**
* xmlNewDtd:
* @doc: the document pointer
* @name: the DTD name
* @ExternalID: the external ID
* @SystemID: the system ID
*
* Creation of a new DTD for the external subset. To create an
* internal subset, use xmlCreateIntSubset().
*
* Returns a pointer to the new DTD structure
*/
xmlDtdPtr
xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
const xmlChar *ExternalID, const xmlChar *SystemID) {
xmlDtdPtr cur;
if ((doc != NULL) && (doc->extSubset != NULL)) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlNewDtd(%s): document %s already have a DTD %s\n",
/* !!! */ (char *) name, doc->name,
/* !!! */ (char *)doc->extSubset->name);
#endif
return(NULL);
}
/*
* Allocate a new DTD and fill the fields.
*/
cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
if (cur == NULL) {
xmlTreeErrMemory("building DTD");
return(NULL);
}
memset(cur, 0 , sizeof(xmlDtd));
cur->type = XML_DTD_NODE;
if (name != NULL)
cur->name = xmlStrdup(name);
if (ExternalID != NULL)
cur->ExternalID = xmlStrdup(ExternalID);
if (SystemID != NULL)
cur->SystemID = xmlStrdup(SystemID);
if (doc != NULL)
doc->extSubset = cur;
cur->doc = doc;
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
/**
* xmlGetIntSubset:
* @doc: the document pointer
*
* Get the internal subset of a document
* Returns a pointer to the DTD structure or NULL if not found
*/
xmlDtdPtr
xmlGetIntSubset(xmlDocPtr doc) {
xmlNodePtr cur;
if (doc == NULL)
return(NULL);
cur = doc->children;
while (cur != NULL) {
if (cur->type == XML_DTD_NODE)
return((xmlDtdPtr) cur);
cur = cur->next;
}
return((xmlDtdPtr) doc->intSubset);
}
/**
* xmlCreateIntSubset:
* @doc: the document pointer
* @name: the DTD name
* @ExternalID: the external (PUBLIC) ID
* @SystemID: the system ID
*
* Create the internal subset of a document
* Returns a pointer to the new DTD structure
*/
xmlDtdPtr
xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
const xmlChar *ExternalID, const xmlChar *SystemID) {
xmlDtdPtr cur;
if ((doc != NULL) && (xmlGetIntSubset(doc) != NULL)) {
#ifdef DEBUG_TREE
xmlGenericError(xmlGenericErrorContext,
"xmlCreateIntSubset(): document %s already have an internal subset\n",
doc->name);
#endif
return(NULL);
}
/*
* Allocate a new DTD and fill the fields.
*/
cur = (xmlDtdPtr) xmlMalloc(sizeof(xmlDtd));
if (cur == NULL) {
xmlTreeErrMemory("building internal subset");
return(NULL);
}
memset(cur, 0, sizeof(xmlDtd));
cur->type = XML_DTD_NODE;
if (name != NULL) {
cur->name = xmlStrdup(name);
if (cur->name == NULL) {
xmlTreeErrMemory("building internal subset");
xmlFree(cur);
return(NULL);
}
}
if (ExternalID != NULL) {
cur->ExternalID = xmlStrdup(ExternalID);
if (cur->ExternalID == NULL) {
xmlTreeErrMemory("building internal subset");
if (cur->name != NULL)
xmlFree((char *)cur->name);
xmlFree(cur);
return(NULL);
}
}
if (SystemID != NULL) {
cur->SystemID = xmlStrdup(SystemID);
if (cur->SystemID == NULL) {
xmlTreeErrMemory("building internal subset");
if (cur->name != NULL)
xmlFree((char *)cur->name);
if (cur->ExternalID != NULL)
xmlFree((char *)cur->ExternalID);
xmlFree(cur);
return(NULL);
}
}
if (doc != NULL) {
doc->intSubset = cur;
cur->parent = doc;
cur->doc = doc;
if (doc->children == NULL) {
doc->children = (xmlNodePtr) cur;
doc->last = (xmlNodePtr) cur;
} else {
if (doc->type == XML_HTML_DOCUMENT_NODE) {
xmlNodePtr prev;
prev = doc->children;
prev->prev = (xmlNodePtr) cur;
cur->next = prev;
doc->children = (xmlNodePtr) cur;
} else {
xmlNodePtr next;
next = doc->children;
while ((next != NULL) && (next->type != XML_ELEMENT_NODE))
next = next->next;
if (next == NULL) {
cur->prev = doc->last;
cur->prev->next = (xmlNodePtr) cur;
cur->next = NULL;
doc->last = (xmlNodePtr) cur;
} else {
cur->next = next;
cur->prev = next->prev;
if (cur->prev == NULL)
doc->children = (xmlNodePtr) cur;
else
cur->prev->next = (xmlNodePtr) cur;
next->prev = (xmlNodePtr) cur;
}
}
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
xmlRegisterNodeDefaultValue((xmlNodePtr)cur);
return(cur);
}
/**
* DICT_FREE:
* @str: a string
*
* Free a string if it is not owned by the "dict" dictionnary in the
* current scope
*/
#define DICT_FREE(str) \
if ((str) && ((!dict) || \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -