From 67d44b290ac24f4019dc5aaf5adb6991f99e3412 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Wed, 12 Sep 2001 15:02:19 +0000 Subject: [PATCH] trying to incorporate comments from bug #59220 Daniel * win32/dsp/libxslt.def libxslt/variables.[ch]: trying to incorporate comments from bug #59220 Daniel --- ChangeLog | 5 + config.h.in | 6 + libxslt/variables.c | 311 +++++++++++++++++++++++++++++++----------- libxslt/variables.h | 9 ++ win32/dsp/libxslt.def | 3 + 5 files changed, 255 insertions(+), 79 deletions(-) diff --git a/ChangeLog b/ChangeLog index 726bcb46..acaa19e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Sep 12 17:00:53 CEST 2001 Daniel Veillard + + * win32/dsp/libxslt.def libxslt/variables.[ch]: trying to + incorporate comments from bug #59220 + Wed Sep 12 05:51:32 CEST 2001 Thomas Broyer * configure.in libexslt/date.c libexslt/Makefile.am diff --git a/config.h.in b/config.h.in index 24e09d21..3275a08f 100644 --- a/config.h.in +++ b/config.h.in @@ -21,6 +21,9 @@ /* Define if you have the gettimeofday function. */ #undef HAVE_GETTIMEOFDAY +/* Define if you have the gmtime function. */ +#undef HAVE_GMTIME + /* Define if you have the localtime function. */ #undef HAVE_LOCALTIME @@ -30,6 +33,9 @@ /* Define if you have the stat function. */ #undef HAVE_STAT +/* Define if you have the time function. */ +#undef HAVE_TIME + /* Define if you have the header file. */ #undef HAVE_ANSIDECL_H diff --git a/libxslt/variables.c b/libxslt/variables.c index 27796e58..6db477bb 100644 --- a/libxslt/variables.c +++ b/libxslt/variables.c @@ -657,80 +657,107 @@ xsltRegisterGlobalVariable(xsltStylesheetPtr style, const xmlChar *name, } /** - * xsltEvalUserParams: - * @ctxt: the XSLT transformation context - * @params: a NULL terminated arry of parameters names/values tuples + * xsltProcessUserParamInternal * - * Evaluate the global variables of a stylesheet. This needs to be - * done on parsed stylesheets before starting to apply transformations + * @ctxt: the XSLT transformation context + * @name: a null terminated parameter name + * @value: a null terminated value (may be an XPath expression) + * @eval: 0 to treat the value literally, else evaluate as XPath expression + * + * If @eval is 0 then @value is treated literally and is stored in the global + * parameter/variable table without any change. + * + * Uf @eval is 1 then @value is treated as an XPath expression and is + * evaluated. In this case, if you want to pass a string which will be + * interpreted literally then it must be enclosed in single or double quotes. + * If the string contains single quotes (double quotes) then it cannot be + * enclosed single quotes (double quotes). If the string which you want to + * be treated literally contains both single and double quotes (e.g. Meet + * at Joe's for "Twelfth Night" at 7 o'clock) then there is no suitable + * quoting character. You cannot use ' or " inside the string + * because the replacement of character entities with their equivalents is + * done at a different stage of processing. The solution is to call + * xsltQuoteUserParams or xsltQuoteOneUserParam. + * + * This needs to be done on parsed stylesheets before starting to apply + * transformations. Normally this will be called (directly or indirectly) + * only from xsltEvalUserParams, xsltEvalOneUserParam, xsltQuoteUserParams, + * or xsltQuoteOneUserParam. * * Returns 0 in case of success, -1 in case of error */ + +static int -xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { +xsltProcessUserParamInternal(xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value, + int eval) { + xsltStylesheetPtr style; - int indx = 0; - const xmlChar *name; - const xmlChar *value; - xmlChar *ncname, *prefix; + xmlChar *ncname; + xmlChar *prefix; const xmlChar *href; xmlXPathCompExprPtr comp; xmlXPathObjectPtr result; - int oldProximityPosition, oldContextSize; + int oldProximityPosition; + int oldContextSize; int oldNsNr; xmlNsPtr *oldNamespaces; + xsltStackElemPtr elem; + int res; if (ctxt == NULL) return(-1); - if (params == NULL) + if (name == NULL) return(0); - + if (value == NULL) + return(0); + style = ctxt->style; - while (params[indx] != NULL) { - name = (const xmlChar *)params[indx++]; - value = (const xmlChar *)params[indx++]; - if ((name == NULL) || (value == NULL)) - break; #ifdef WITH_XSLT_DEBUG_VARIABLE - xsltGenericDebug(xsltGenericDebugContext, + xsltGenericDebug(xsltGenericDebugContext, "Evaluating user parameter %s=%s\n", name, value); #endif - /* - * Name lookup - */ - ncname = xmlSplitQName2(name, &prefix); - href = NULL; - if (ncname != NULL) { - if (prefix != NULL) { - xmlNsPtr ns; + /* + * Name lookup + */ - ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc), - prefix); - if (ns == NULL) { - xsltPrintErrorContext(ctxt, style, NULL); - xsltGenericError(xsltGenericErrorContext, - "user param : no namespace bound to prefix %s\n", prefix); - href = NULL; - } else { - href = ns->href; - } - xmlFree(prefix); - } else { + ncname = xmlSplitQName2(name, &prefix); + href = NULL; + if (ncname != NULL) { + if (prefix != NULL) { + xmlNsPtr ns; + + ns = xmlSearchNs(style->doc, xmlDocGetRootElement(style->doc), + prefix); + if (ns == NULL) { + xsltPrintErrorContext(ctxt, style, NULL); + xsltGenericError(xsltGenericErrorContext, + "user param : no namespace bound to prefix %s\n", prefix); href = NULL; + } else { + href = ns->href; } - xmlFree(ncname); + xmlFree(prefix); } else { href = NULL; - ncname = xmlStrdup(name); } + xmlFree(ncname); + } else { + href = NULL; + ncname = xmlStrdup(name); + } - /* - * Do the evaluation - */ - result = NULL; - comp = xmlXPathCompile(value); + /* + * Do the evaluation if @eval is non-zero. + */ + + result = NULL; + if (eval != 0) { + comp = xmlXPathCompile(value); if (comp != NULL) { oldProximityPosition = ctxt->xpathCtxt->proximityPosition; oldContextSize = ctxt->xpathCtxt->contextSize; @@ -740,6 +767,7 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { * There is really no in scope namespace for parameters on the * command line. */ + oldNsNr = ctxt->xpathCtxt->nsNr; oldNamespaces = ctxt->xpathCtxt->namespaces; ctxt->xpathCtxt->namespaces = NULL; @@ -756,51 +784,176 @@ xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { xsltGenericError(xsltGenericErrorContext, "Evaluating user parameter %s failed\n", name); ctxt->state = XSLT_STATE_STOPPED; - } else { - xsltStackElemPtr elem; - int res; + xmlFree(ncname); + return(-1); + } + } + + /* + * If @eval is 0 then @value is to be taken literally and result is NULL + * + * If @eval is not 0, then @value is an XPath expression and has been + * successfully evaluated and result contains the resulting value and + * is not NULL. + * + * Now create an xsltStackElemPtr for insertion into the context's + * global variable/parameter hash table. + */ #ifdef WITH_XSLT_DEBUG_VARIABLE #ifdef LIBXML_DEBUG_ENABLED - if ((xsltGenericDebugContext == stdout) || - (xsltGenericDebugContext == stderr)) - xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext, - result, 0); + if ((xsltGenericDebugContext == stdout) || + (xsltGenericDebugContext == stderr)) + xmlXPathDebugDumpObject((FILE *)xsltGenericDebugContext, + result, 0); #endif #endif - elem = xsltNewStackElem(); - if (elem != NULL) { - elem->name = xmlStrdup(ncname); - if (value != NULL) - elem->select = xmlStrdup(value); - else - elem->select = NULL; - if (href) - elem->nameURI = xmlStrdup(href); - elem->tree = NULL; - elem->computed = 1; - elem->value = result; - } - /* - * Global parameters are stored in the XPath context - * variables pool. - */ - res = xmlHashAddEntry2(ctxt->globalVars, - ncname, href, elem); - if (res != 0) { - xsltFreeStackElem(elem); - xsltPrintErrorContext(ctxt, style, NULL); - xsltGenericError(xsltGenericErrorContext, - "Global parameter %s already defined\n", ncname); - } + elem = xsltNewStackElem(); + if (elem != NULL) { + elem->name = xmlStrdup(ncname); + if (value != NULL) + elem->select = xmlStrdup(value); + else + elem->select = NULL; + if (href) + elem->nameURI = xmlStrdup(href); + elem->tree = NULL; + elem->computed = 1; + if (eval == 0) { + elem->value = xmlXPathNewString(value); + } + else { + elem->value = result; } - xmlFree(ncname); } + /* + * Global parameters are stored in the XPath context variables pool. + */ + + res = xmlHashAddEntry2(ctxt->globalVars, ncname, href, elem); + if (res != 0) { + xsltFreeStackElem(elem); + xsltPrintErrorContext(ctxt, style, NULL); + xsltGenericError(xsltGenericErrorContext, + "Global parameter %s already defined\n", ncname); + } + xmlFree(ncname); return(0); } +/** + * xsltEvalUserParams: + * + * @ctxt: the XSLT transformation context + * @params: a NULL terminated array of parameters name/value tuples + * + * Evaluate the global variables of a stylesheet. This needs to be + * done on parsed stylesheets before starting to apply transformations. + * Each of the parameters is evaluated as an XPath expression and stored + * in the global variables/parameter hash table. If you want your + * parameter used literally, use xsltQuoteUserParams. + * + * Returns 0 in case of success, -1 in case of error + */ + +int +xsltEvalUserParams(xsltTransformContextPtr ctxt, const char **params) { + int indx = 0; + const xmlChar *name; + const xmlChar *value; + + if (params == NULL) + return(0); + while (params[indx] != NULL) { + name = (const xmlChar *) params[indx++]; + value = (const xmlChar *) params[indx++]; + if (xsltEvalOneUserParam(ctxt, name, value) != 0) + return(-1); + } + return 0; +} + +/** + * xsltQuoteUserParams: + * + * @ctxt: the XSLT transformation context + * @params: a NULL terminated arry of parameters names/values tuples + * + * Similar to xsltEvalUserParams, but the values are treated literally and + * are * *not* evaluated as XPath expressions. This should be done on parsed + * stylesheets before starting to apply transformations. + * + * Returns 0 in case of success, -1 in case of error. + */ + +int +xsltQuoteUserParams(xsltTransformContextPtr ctxt, const char **params) { + int indx = 0; + const xmlChar *name; + const xmlChar *value; + + if (params == NULL) + return(0); + while (params[indx] != NULL) { + name = (const xmlChar *) params[indx++]; + value = (const xmlChar *) params[indx++]; + if (xsltQuoteOneUserParam(ctxt, name, value) != 0) + return(-1); + } + return 0; +} + +/** + * xsltEvalOneUserParam: + * + * @ctxt: the XSLT transformation context + * @name: a null terminated string giving the name of the parameter + * @value a null terminated string giving the XPath expression to be evaluated + * + * This is normally called from xsltEvalUserParams to process a single + * parameter from a list of parameters. The @value is evaluated as an + * XPath expression and the result is stored in the context's global + * variable/parameter hash table. + * + * To have a parameter treated literally (not as an XPath expression) + * use xsltQuoteUserParams (or xsltQuoteOneUserParam). For more + * details see description of xsltProcessOneUserParamInternal. + * + * Returns 0 in case of success, -1 in case of error. + */ + +int +xsltEvalOneUserParam(xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value) { + return xsltProcessUserParamInternal(ctxt, name, value, + 1 /* xpath eval ? */); +} + +/** + * xsltQuoteOneUserParam: + * + * @ctxt: the XSLT transformation context + * @name: a null terminated string giving the name of the parameter + * @value a null terminated string giving the parameter value + * + * This is normally called from xsltQuoteUserParams to process a single + * parameter from a list of parameters. The @value is stored in the + * context's global variable/parameter hash table. + * + * Returns 0 in case of success, -1 in case of error. + */ + +int +xsltQuoteOneUserParam(xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value) { + return xsltProcessUserParamInternal(ctxt, name, value, + 0 /* xpath eval ? */); +} + /** * xsltBuildVariable: * @ctxt: the XSLT transformation context diff --git a/libxslt/variables.h b/libxslt/variables.h index 135b4280..d118f230 100644 --- a/libxslt/variables.h +++ b/libxslt/variables.h @@ -39,6 +39,15 @@ extern "C" { int xsltEvalGlobalVariables (xsltTransformContextPtr ctxt); int xsltEvalUserParams (xsltTransformContextPtr ctxt, const char **params); +int xsltQuoteUserParams (xsltTransformContextPtr ctxt, + const char **params); +int xsltEvalOneUserParam (xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value); +int xsltQuoteOneUserParam (xsltTransformContextPtr ctxt, + const xmlChar * name, + const xmlChar * value); + void xsltParseGlobalVariable (xsltStylesheetPtr style, xmlNodePtr cur); void xsltParseGlobalParam (xsltStylesheetPtr style, diff --git a/win32/dsp/libxslt.def b/win32/dsp/libxslt.def index 141399d4..66184279 100644 --- a/win32/dsp/libxslt.def +++ b/win32/dsp/libxslt.def @@ -112,6 +112,9 @@ EXPORTS xsltEvalGlobalVariables xsltEvalUserParams + xsltQuoteUserParams + xsltEvalOneUserParam + xsltQuoteOneUserParam xsltParseGlobalVariable xsltParseGlobalParam xsltParseStylesheetVariable