]> matita.cs.unibo.it Git - helm.git/blob - helm/DEVEL/gdome_xslt/C/gdome_xslt/gdome_xslt.c
ocaml 3.09 transition
[helm.git] / helm / DEVEL / gdome_xslt / C / gdome_xslt / gdome_xslt.c
1 /* This file implements a XSLT engine working on Gdome documents. In fact,
2  * it just maps Gdome documents to libxml documents back and forth, and
3  * applyes the transformation on libxml documents using libxlt.
4  * 
5  * The code is largely based on the code of T.J. Mather's XML::GDOME::XSLT
6  * Perl module (http://kobesearch.cpan.org/search?dist=XML-GDOME-XSLT)
7  *
8  * Copyright (C) 2002:
9  *      Claudio Sacerdoti Coen          <sacerdot@cs.unibo.it>
10  *      Stefano Zacchiroli              <zack@cs.unibo.it>
11  * 
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  * 
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  * 
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  *
26  * For more information, please send an email to {sacerdot,zack}@cs.unibo.it
27  */
28
29 #include <stdio.h>
30 #include <stdarg.h>
31 #include <string.h>
32 #include <gdome.h>
33 #include <libxslt/xsltconfig.h>
34 #include <libxslt/xslt.h>
35 #include <libxslt/xsltutils.h>
36 #include <libxslt/transform.h>
37 #include <libxslt/imports.h>
38 #include "gdome_xslt.h"
39
40 // Begin of Gdome internals exposed
41 typedef struct _Gdome_xml_Document Gdome_xml_Document;
42 struct _Gdome_xml_Document {
43         GdomeDocument super;
44         const GdomeDocumentVtab* vtab;
45         int refcnt;
46         xmlDocPtr n;
47         GdomeAccessType accessType;
48 };
49
50 GdomeNode* gdome_xml_n_mkref(xmlNode* n);
51 // End of Gdome internals exposed
52
53 // Begin of the abstraction of Gdome internals. Uses the Gdome internals exposed
54 xmlDocPtr libxml_of_gdome(GdomeDocument* doc)
55 {
56    return ((Gdome_xml_Document*)doc)->n;
57 }
58
59 GdomeDocument* gdome_of_libxml(xmlDocPtr n)
60 {
61    return (GdomeDocument*)gdome_xml_n_mkref((xmlNode*)n);
62 }
63 // End of the abstraction of Gdome internals. Uses the Gdome internals exposed.
64
65
66
67 // From now on no Gdome internal should be used directly.
68
69         /******************************/
70         /* XSLT stylesheet Processing */
71         /******************************/
72
73 xsltStylesheetPtr processStylesheet(GdomeDocument* style)
74 {
75    xmlDocPtr style_copy;
76    xmlDocPtr style_libxml;
77
78    if (style == NULL) {
79       return NULL;
80    }
81    style_libxml = libxml_of_gdome(style);
82    style_copy = xmlCopyDoc(style_libxml, 1);
83    style_copy->URL = xmlStrdup(style_libxml->URL);
84
85    xsltSetGenericDebugFunc(NULL, NULL);
86
87    return xsltParseStylesheetDoc(style_copy);
88 }
89
90         /*******************************/
91         /* XSLT stylesheet Application */
92         /*******************************/
93
94 GdomeDocument* applyStylesheet(GdomeDocument* source, xsltStylesheetPtr
95                 style_libxslt, const char** params)
96 {
97    xmlDocPtr source_libxml;
98    xmlDocPtr output_libxml;
99
100    if (source == NULL) return NULL;
101    source_libxml = libxml_of_gdome(source);
102
103    xsltSetGenericDebugFunc(NULL, NULL);
104
105    output_libxml = xsltApplyStylesheet(style_libxslt, source_libxml,
106                    params);
107
108    if (output_libxml == NULL) return NULL;
109
110    return gdome_of_libxml(output_libxml);
111 }
112
113         /******************/
114         /* Results Output */
115         /******************/
116
117 int saveResultToFilename (const char* name, GdomeDocument* result,
118                 xsltStylesheetPtr style_libxslt, int compression)
119 {
120         xmlDocPtr result_libxml;
121
122         if (result == NULL) return -1;
123         result_libxml = libxml_of_gdome(result);
124
125         xsltSetGenericDebugFunc(NULL, NULL);
126
127         return xsltSaveResultToFilename(name, result_libxml,
128                         style_libxslt, compression);
129 }
130
131 int saveResultToFile (FILE* file, GdomeDocument* result,
132                 xsltStylesheetPtr style_libxslt)
133 {
134         xmlDocPtr result_libxml;
135
136         if (result == NULL) return -1;
137         result_libxml = libxml_of_gdome(result);
138
139         xsltSetGenericDebugFunc(NULL, NULL);
140
141         return xsltSaveResultToFile(file, result_libxml, style_libxslt);
142 }
143
144 int saveResultToFd (int fd, GdomeDocument* result, xsltStylesheetPtr
145                 style_libxslt)
146 {
147         xmlDocPtr result_libxml;
148
149         if (result == NULL) return -1;
150         result_libxml = libxml_of_gdome(result);
151
152         xsltSetGenericDebugFunc(NULL, NULL);
153
154         return xsltSaveResultToFd(fd, result_libxml, style_libxslt);
155 }
156
157         /**********************************************/
158         /* Error and Debugging Callbacks Registration */
159         /**********************************************/
160
161         /* max size of a single message passed to callbacks */
162 #define MAX_MSG_SIZE    1024
163 #define TRUNCATED_MSG   "... TRUNCATED ..."
164 #define TRUNCATED_MSG_LEN       strlen(TRUNCATED_MSG)
165
166                 /* ERROR callbacks */
167
168         /* user provided error callback, needs a string input */
169 static gdomeXsltMsgCallback errorUserCallback = NULL;
170
171         /* libxslt like error callback, ignore context, builds a string
172          * input for user provided error callback and invoke it */
173 void gdomeXsltErrorCallback (void *ctx, const char *msg, ...) {
174         va_list args;
175         char buf[MAX_MSG_SIZE];
176
177         if (errorUserCallback == NULL)
178                 return;
179
180         va_start(args, msg);
181         if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
182         {       /* message truncated; write TRUNCATED_MSG on it */
183                 strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
184                                 TRUNCATED_MSG, TRUNCATED_MSG_LEN);
185         }
186         va_end(args);
187
188         (*errorUserCallback) (buf);
189
190         return;
191 }
192
193         /* set user provided error callback */
194 void setErrorCallback (gdomeXsltMsgCallback callback)
195 {
196         errorUserCallback = callback;
197         xsltSetGenericErrorFunc(NULL,
198                 (callback == NULL ? NULL : gdomeXsltErrorCallback));
199
200         return;
201 }
202
203                 /* DEBUG callbacks */
204
205         /* user provided debug callback, needs a string input */
206 static gdomeXsltMsgCallback debugUserCallback = NULL;
207
208         /* libxslt like debug callback, ignore context, builds a string
209          * input for user provided debug callback and invoke it */
210 void gdomeXsltDebugCallback (void *ctx, const char *msg, ...) {
211         va_list args;
212         char buf[MAX_MSG_SIZE];
213
214         if (debugUserCallback == NULL)
215                 return;
216
217         va_start(args, msg);
218         if (vsnprintf(buf, MAX_MSG_SIZE, msg, args) > MAX_MSG_SIZE - 1)
219         {       /* message truncated; write TRUNCATED_MSG on it */
220                 strncpy(buf+(strlen(buf) - TRUNCATED_MSG_LEN),
221                                 TRUNCATED_MSG, TRUNCATED_MSG_LEN);
222         }
223         va_end(args);
224
225         (*debugUserCallback) (buf);
226
227         return;
228 }
229
230         /* set user provided debug callback */
231 void setDebugCallback (gdomeXsltMsgCallback callback)
232 {
233         debugUserCallback = callback;
234         xsltSetGenericDebugFunc(NULL,
235                 (callback == NULL ? NULL : gdomeXsltDebugCallback));
236
237         return;
238 }
239