* xmlXPathTryStreamCompile: * @ctxt: an XPath context * @str: the XPath expression * * Try to compile the XPath expression as a streamable subset. * * Returns the compiled expression or NULL if failed to compile. */
| 12865 | * Returns the compiled expression or NULL if failed to compile. |
| 12866 | */ |
| 12867 | static xmlXPathCompExprPtr |
| 12868 | xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) { |
| 12869 | /* |
| 12870 | * Optimization: use streaming patterns when the XPath expression can |
| 12871 | * be compiled to a stream lookup |
| 12872 | */ |
| 12873 | xmlPatternPtr stream; |
| 12874 | xmlXPathCompExprPtr comp; |
| 12875 | xmlDictPtr dict = NULL; |
| 12876 | const xmlChar **namespaces = NULL; |
| 12877 | xmlNsPtr ns; |
| 12878 | int i, j; |
| 12879 | |
| 12880 | if ((!xmlStrchr(str, '[')) && (!xmlStrchr(str, '(')) && |
| 12881 | (!xmlStrchr(str, '@'))) { |
| 12882 | const xmlChar *tmp; |
| 12883 | int res; |
| 12884 | |
| 12885 | /* |
| 12886 | * We don't try to handle expressions using the verbose axis |
| 12887 | * specifiers ("::"), just the simplified form at this point. |
| 12888 | * Additionally, if there is no list of namespaces available and |
| 12889 | * there's a ":" in the expression, indicating a prefixed QName, |
| 12890 | * then we won't try to compile either. xmlPatterncompile() needs |
| 12891 | * to have a list of namespaces at compilation time in order to |
| 12892 | * compile prefixed name tests. |
| 12893 | */ |
| 12894 | tmp = xmlStrchr(str, ':'); |
| 12895 | if ((tmp != NULL) && |
| 12896 | ((ctxt == NULL) || (ctxt->nsNr == 0) || (tmp[1] == ':'))) |
| 12897 | return(NULL); |
| 12898 | |
| 12899 | if (ctxt != NULL) { |
| 12900 | dict = ctxt->dict; |
| 12901 | if (ctxt->nsNr > 0) { |
| 12902 | namespaces = xmlMalloc(2 * (ctxt->nsNr + 1) * sizeof(xmlChar*)); |
| 12903 | if (namespaces == NULL) { |
| 12904 | xmlXPathErrMemory(ctxt); |
| 12905 | return(NULL); |
| 12906 | } |
| 12907 | for (i = 0, j = 0; (j < ctxt->nsNr); j++) { |
| 12908 | ns = ctxt->namespaces[j]; |
| 12909 | namespaces[i++] = ns->href; |
| 12910 | namespaces[i++] = ns->prefix; |
| 12911 | } |
| 12912 | namespaces[i++] = NULL; |
| 12913 | namespaces[i] = NULL; |
| 12914 | } |
| 12915 | } |
| 12916 | |
| 12917 | res = xmlPatternCompileSafe(str, dict, XML_PATTERN_XPATH, namespaces, |
| 12918 | &stream); |
| 12919 | if (namespaces != NULL) { |
| 12920 | xmlFree((xmlChar **)namespaces); |
| 12921 | } |
| 12922 | if (res < 0) { |
| 12923 | xmlXPathErrMemory(ctxt); |
| 12924 | return(NULL); |
no test coverage detected