Re: [xslt] plugin patch v3 plus exslt:regexp implementation



On Sun, Jan 09, 2005 at 09:14:18AM -0500, Daniel Veillard wrote:
> On Sat, Jan 08, 2005 at 07:22:04PM -0500, Joel Reed wrote:
> > I've attached a new version of the plugin patch, plus an
> > implementation of exslt:regexp.
> > 
> > The plugin implements exslt:replace, exslt:match, and exslt:test
> > as documented here: http://www.exslt.org/regexp/index.html
> > The plugin uses pcre 5.0 or later. It was tested against libxml2 CVS
> > and libxslt CVS plus plugin patch.
> > 
> > I built some test cases and ran the code thru many permutations
> > all successful, but this is the first time i've coded xpath return 
> > sets and used pcre, so code reviews/testing help appreciated.
> > 
> > The xslt plugin patch has been updated to the new libxml2 module
> > api, plus it now actually calls xmlModuleClose in xsltCleanupGlobals.
> > 
> > I plan to check out and try to add hooks to xslt security module,
> > and eventually test on win32. Please feel free to beat me to win32
> > if you like :-)
> 
>   Joel and I had a little chat on IRC, about some things to fix or
> improve about the patch, but I expect to commit it later today in CVS
> after a bit of cleanup:

patch against CVS with the following changes:

*) plugin names now include full extension namespace minus protocol
   e.g. /usr/local/lib/libxslt/1.1/exslt_org_regular_expressions.so
*) init funcs are now based on extension namespace
   e.g.  exslt_org_regular_expressions_init
*) more comments for xsltExtModuleRegisterDynamic
*) xsltExtModuleRegisterDynamic always a function
*) if regfunc not found unload the module immediately

and attached is libxslt-plugin-regexp-0.2.tar.gz, which uses
the new plugin name and init func naming scheme above.

jr
Index: libxslt/extensions.c
===================================================================
RCS file: /cvs/gnome/libxslt/libxslt/extensions.c,v
retrieving revision 1.37
diff -u -w -b -B -r1.37 extensions.c
--- libxslt/extensions.c	9 Jan 2005 16:05:10 -0000	1.37
+++ libxslt/extensions.c	11 Jan 2005 02:59:25 -0000
@@ -298,8 +298,17 @@
  * xsltExtModuleRegisterDynamic:
  * @URI:  the function or element namespace URI
  *
- * Looks up an extension module to dynamically load
- * based on the namespace URI
+ * Dynamically loads an extension plugin when available.
+ * 
+ * The plugin name is derived from the URI by removing the 
+ * initial protocol designation, e.g. "http://";, then converting
+ * the characters ".", "-", "/", and "\" into "_", the removing
+ * any trailing "/", then concatenating LIBXML_MODULE_EXTENSION.
+ * 
+ * Plugins are loaded from the directory specified by the 
+ * environment variable LIBXSLT_PLUGINS_PATH, or if NULL, 
+ * by LIBXSLT_DEFAULT_PLUGINS_PATH() which is determined at
+ * compile time.
  *
  * Returns 0 if successful, -1 in case of error. 
  */
@@ -310,10 +319,12 @@
 
     xmlModulePtr m;
     exsltRegisterFunction regfunc;
+    xmlChar *ext_name;
     xmlChar module_filename[PATH_MAX];
-    const xmlChar *extNameBegin = NULL;
-    const xmlChar *extDirectory = NULL;
-    int i, rc, seen_before;
+    const xmlChar *ext_directory = NULL;
+    const xmlChar *protocol = NULL;
+    xmlChar *i, *regfunc_name;
+    int rc, seen_before;
 
     /* check for bad inputs */
     if (URI == NULL)
@@ -331,43 +342,68 @@
         return (-1);
     }
 
-    for (i = xmlStrlen(URI); i != 0 && extNameBegin == NULL; --i) {
-        if (URI[i - 1] == '/')
-            extNameBegin = URI + i;
+    /* transform extension namespace into a module name */
+    protocol = xmlStrstr(URI, "://");
+    ext_name = xmlStrdup(protocol+3);
+
+    i = ext_name;
+    while ('\0' != *i) {
+      if (('/' == *i) || ('\\' == *i) || 
+          ('.' == *i) || ('-' == *i)) *i = '_';
+      i++;
     }
 
-    if (extNameBegin == NULL || *extNameBegin == '\0')
-        return (-1);
+    if (*(i-1) == '_') *i = '\0';
 
     /* determine module directory */
-    extDirectory = getenv(BAD_CAST "LIBXSLT_PLUGINS_PATH");
-    if (NULL == extDirectory)
-        extDirectory = LIBXSLT_DEFAULT_PLUGINS_PATH();
-    if (NULL == extDirectory)
+    ext_directory = getenv(BAD_CAST "LIBXSLT_PLUGINS_PATH");
+    if (NULL == ext_directory)
+        ext_directory = LIBXSLT_DEFAULT_PLUGINS_PATH();
+    if (NULL == ext_directory)
         return (-1);
 
     /* build the module filename, and confirm the module exists */
     xmlStrPrintf(module_filename, sizeof(module_filename), "%s%s%s",
-                 extDirectory, extNameBegin, LIBXML_MODULE_EXTENSION);
-    if (1 != xmlCheckFilename(module_filename))
+                 ext_directory, ext_name, LIBXML_MODULE_EXTENSION);
+    if (1 != xmlCheckFilename(module_filename)) {
+      xmlFree(ext_name);
         return (-1);
+    }
 
+    /* attempt to open the module*/
     m = xmlModuleOpen(module_filename, 0);
-    if (NULL == m)
+    if (NULL == m) {
+      xmlFree(ext_name);
         return (-1);
+    }
+
+    /* construct initialization func name */
+    regfunc_name = xmlStrdup(ext_name);
+    regfunc_name = xmlStrcat(regfunc_name, "_init");
 
-    rc = xmlModuleSymbol(m, "exsltRegisterModule", (void **) &regfunc);
+    rc = xmlModuleSymbol(m, regfunc_name, (void **) &regfunc);
     if (0 == rc) {
+      /* call the module's init function */
         (*regfunc) ();
-    }
 
     /* register this module in our hash */
     xmlHashAddEntry(xsltModuleHash, URI, (void *) m);
+    }
+    else {
+      /* if regfunc not found unload the module immediately */
+      xmlModuleClose(m);
+    }
 
+    xmlFree(ext_name);
+    xmlFree(regfunc_name);
     return (NULL == regfunc) ? -1 : 0;
 }
 #else
-#define xsltExtModuleRegisterDynamic(b) -1
+static int
+xsltExtModuleRegisterDynamic(const xmlChar * ATTRIBUTE_UNUSED URI)
+{
+  return -1;
+}
 #endif
 
 /************************************************************************

Attachment: libxslt-plugin-regexp-0.2.tar.gz
Description: application/tar-gz



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]