]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/software/DEVEL/gdome_xslt/C/gdome_xslt/gdome_xslt.c
reorganization continues ...
[helm.git] / helm / software / DEVEL / gdome_xslt / C / gdome_xslt / gdome_xslt.c
diff --git a/helm/software/DEVEL/gdome_xslt/C/gdome_xslt/gdome_xslt.c b/helm/software/DEVEL/gdome_xslt/C/gdome_xslt/gdome_xslt.c
new file mode 100644 (file)
index 0000000..232f14b
--- /dev/null
@@ -0,0 +1,239 @@
+/* This file implements a XSLT engine working on Gdome documents. In fact,
+ * it just maps Gdome documents to libxml documents back and forth, and
+ * applyes the transformation on libxml documents using libxlt.
+ * 
+ * The code is largely based on the code of T.J. Mather's XML::GDOME::XSLT
+ * Perl module (http://kobesearch.cpan.org/search?dist=XML-GDOME-XSLT)
+ *
+ * Copyright (C) 2002:
+ *     Claudio Sacerdoti Coen          <sacerdot@cs.unibo.it>
+ *     Stefano Zacchiroli              <zack@cs.unibo.it>
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * For more information, please send an email to {sacerdot,zack}@cs.unibo.it
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <gdome.h>
+#include <libxslt/xsltconfig.h>
+#include <libxslt/xslt.h>
+#include <libxslt/xsltutils.h>
+#include <libxslt/transform.h>
+#include <libxslt/imports.h>
+#include "gdome_xslt.h"
+
+// Begin of Gdome internals exposed
+typedef struct _Gdome_xml_Document Gdome_xml_Document;
+struct _Gdome_xml_Document {
+        GdomeDocument super;
+        const GdomeDocumentVtab* vtab;
+        int refcnt;
+        xmlDocPtr n;
+        GdomeAccessType accessType;
+};
+
+GdomeNode* gdome_xml_n_mkref(xmlNode* n);
+// End of Gdome internals exposed
+
+// Begin of the abstraction of Gdome internals. Uses the Gdome internals exposed
+xmlDocPtr libxml_of_gdome(GdomeDocument* doc)
+{
+   return ((Gdome_xml_Document*)doc)->n;
+}
+
+GdomeDocument* gdome_of_libxml(xmlDocPtr n)
+{
+   return (GdomeDocument*)gdome_xml_n_mkref((xmlNode*)n);
+}
+// End of the abstraction of Gdome internals. Uses the Gdome internals exposed.
+
+
+
+// From now on no Gdome internal should be used directly.
+
+       /******************************/
+       /* XSLT stylesheet Processing */
+       /******************************/
+
+xsltStylesheetPtr processStylesheet(GdomeDocument* style)
+{
+   xmlDocPtr style_copy;
+   xmlDocPtr style_libxml;
+
+   if (style == NULL) {
+      return NULL;
+   }
+   style_libxml = libxml_of_gdome(style);
+   style_copy = xmlCopyDoc(style_libxml, 1);
+   style_copy->URL = xmlStrdup(style_libxml->URL);
+
+   xsltSetGenericDebugFunc(NULL, NULL);
+
+   return xsltParseStylesheetDoc(style_copy);
+}
+
+       /*******************************/
+       /* XSLT stylesheet Application */
+       /*******************************/
+
+GdomeDocument* applyStylesheet(GdomeDocument* source, xsltStylesheetPtr
+               style_libxslt, const char** params)
+{
+   xmlDocPtr source_libxml;
+   xmlDocPtr output_libxml;
+
+   if (source == NULL) return NULL;
+   source_libxml = libxml_of_gdome(source);
+
+   xsltSetGenericDebugFunc(NULL, NULL);
+
+   output_libxml = xsltApplyStylesheet(style_libxslt, source_libxml,
+                  params);
+
+   if (output_libxml == NULL) return NULL;
+
+   return gdome_of_libxml(output_libxml);
+}
+
+       /******************/
+       /* Results Output */
+       /******************/
+
+int saveResultToFilename (const char* name, GdomeDocument* result,
+               xsltStylesheetPtr style_libxslt, int compression)
+{
+       xmlDocPtr result_libxml;
+
+       if (result == NULL) return -1;
+       result_libxml = libxml_of_gdome(result);
+
+       xsltSetGenericDebugFunc(NULL, NULL);
+
+       return xsltSaveResultToFilename(name, result_libxml,
+                       style_libxslt, compression);
+}
+
+int saveResultToFile (FILE* file, GdomeDocument* result,
+               xsltStylesheetPtr style_libxslt)
+{
+       xmlDocPtr result_libxml;
+
+       if (result == NULL) return -1;
+       result_libxml = libxml_of_gdome(result);
+
+       xsltSetGenericDebugFunc(NULL, NULL);
+
+       return xsltSaveResultToFile(file, result_libxml, style_libxslt);
+}
+
+int saveResultToFd (int fd, GdomeDocument* result, xsltStylesheetPtr
+               style_libxslt)
+{
+       xmlDocPtr result_libxml;
+
+       if (result == NULL) return -1;
+       result_libxml = libxml_of_gdome(result);
+
+       xsltSetGenericDebugFunc(NULL, NULL);
+
+       return xsltSaveResultToFd(fd, result_libxml, style_libxslt);
+}
+
+       /**********************************************/
+       /* Error and Debugging Callbacks Registration */
+       /**********************************************/
+
+       /* max size of a single message passed to callbacks */
+#define MAX_MSG_SIZE   1024
+#define TRUNCATED_MSG  "... TRUNCATED ..."
+#define TRUNCATED_MSG_LEN      strlen(TRUNCATED_MSG)
+
+               /* ERROR callbacks */
+
+       /* user provided error callback, needs a string input */
+static gdomeXsltMsgCallback errorUserCallback = NULL;
+
+       /* libxslt like error callback, ignore context, builds a string
+        * input for user provided error callback and invoke it */
+void gdomeXsltErrorCallback (void *ctx, const char *msg, ...) {
+       va_list args;
+       char buf[MAX_MSG_SIZE];
+
+       if (errorUserCallback == NULL)
+               return;
+
+       va_start(args, msg);
+       if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
+       {       /* message truncated; write TRUNCATED_MSG on it */
+               strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
+                               TRUNCATED_MSG, TRUNCATED_MSG_LEN);
+       }
+       va_end(args);
+
+       (*errorUserCallback) (buf);
+
+       return;
+}
+
+       /* set user provided error callback */
+void setErrorCallback (gdomeXsltMsgCallback callback)
+{
+       errorUserCallback = callback;
+       xsltSetGenericErrorFunc(NULL,
+               (callback == NULL ? NULL : gdomeXsltErrorCallback));
+
+       return;
+}
+
+               /* DEBUG callbacks */
+
+       /* user provided debug callback, needs a string input */
+static gdomeXsltMsgCallback debugUserCallback = NULL;
+
+       /* libxslt like debug callback, ignore context, builds a string
+        * input for user provided debug callback and invoke it */
+void gdomeXsltDebugCallback (void *ctx, const char *msg, ...) {
+       va_list args;
+       char buf[MAX_MSG_SIZE];
+
+       if (debugUserCallback == NULL)
+               return;
+
+       va_start(args, msg);
+       if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
+       {       /* message truncated; write TRUNCATED_MSG on it */
+               strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
+                               TRUNCATED_MSG, TRUNCATED_MSG_LEN);
+       }
+       va_end(args);
+
+       (*debugUserCallback) (buf);
+
+       return;
+}
+
+       /* set user provided debug callback */
+void setDebugCallback (gdomeXsltMsgCallback callback)
+{
+       debugUserCallback = callback;
+       xsltSetGenericDebugFunc(NULL,
+               (callback == NULL ? NULL : gdomeXsltDebugCallback));
+
+       return;
+}
+