00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027 #include <gutenprint/gutenprint.h>
00028 #include "gutenprint-internal.h"
00029 #include <gutenprint/gutenprint-intl-internal.h>
00030 #include <assert.h>
00031 #include <ctype.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <math.h>
00036 #include <errno.h>
00037 #ifdef HAVE_LIMITS_H
00038 #include <limits.h>
00039 #endif
00040 #if defined(HAVE_VARARGS_H) && !defined(HAVE_STDARG_H)
00041 #include <varargs.h>
00042 #else
00043 #include <stdarg.h>
00044 #endif
00045
00046 typedef struct
00047 {
00048 char *name;
00049 stp_xml_parse_func parse_func;
00050 } stpi_xml_parse_registry;
00051
00052 static stp_list_t *stpi_xml_registry;
00053
00054 static stp_list_t *stpi_xml_preloads;
00055
00056 static const char *
00057 xml_registry_namefunc(const void *item)
00058 {
00059 const stpi_xml_parse_registry *xmlp = (const stpi_xml_parse_registry *) item;
00060 return xmlp->name;
00061 }
00062
00063 static void
00064 xml_registry_freefunc(void *item)
00065 {
00066 stpi_xml_parse_registry *xmlp = (stpi_xml_parse_registry *) item;
00067 stp_free(xmlp->name);
00068 stp_free(xmlp);
00069 }
00070
00071 static const char *
00072 xml_preload_namefunc(const void *item)
00073 {
00074 return (const char *) item;
00075 }
00076
00077 static void
00078 xml_preload_freefunc(void *item)
00079 {
00080 stp_free(item);
00081 }
00082
00083 void
00084 stp_register_xml_parser(const char *name, stp_xml_parse_func parse_func)
00085 {
00086 stpi_xml_parse_registry *xmlp;
00087 stp_list_item_t *item = stp_list_get_item_by_name(stpi_xml_registry, name);
00088 if (item)
00089 xmlp = (stpi_xml_parse_registry *) stp_list_item_get_data(item);
00090 else
00091 {
00092 xmlp = stp_malloc(sizeof(stpi_xml_parse_registry));
00093 xmlp->name = stp_strdup(name);
00094 stp_list_item_create(stpi_xml_registry, NULL, xmlp);
00095 }
00096 xmlp->parse_func = parse_func;
00097 }
00098
00099 void
00100 stp_unregister_xml_parser(const char *name)
00101 {
00102 stp_list_item_t *item = stp_list_get_item_by_name(stpi_xml_registry, name);
00103 if (item)
00104 stp_list_item_destroy(stpi_xml_registry, item);
00105 }
00106
00107 void
00108 stp_register_xml_preload(const char *filename)
00109 {
00110 stp_list_item_t *item = stp_list_get_item_by_name(stpi_xml_preloads, filename);
00111 if (!item)
00112 {
00113 char *the_filename = stp_strdup(filename);
00114 stp_list_item_create(stpi_xml_preloads, NULL, the_filename);
00115 }
00116 }
00117
00118 void
00119 stp_unregister_xml_preload(const char *name)
00120 {
00121 stp_list_item_t *item = stp_list_get_item_by_name(stpi_xml_preloads, name);
00122 if (item)
00123 stp_list_item_destroy(stpi_xml_preloads, item);
00124 }
00125
00126
00127 static void stpi_xml_process_gutenprint(stp_mxml_node_t *gutenprint, const char *file);
00128
00129 static char *saved_lc_collate;
00130 static char *saved_lc_ctype;
00131 static char *saved_lc_numeric;
00132 static int xml_is_initialised;
00133
00134 void
00135 stp_xml_preinit(void)
00136 {
00137 static int xml_is_preinitialized = 0;
00138 if (!xml_is_preinitialized)
00139 {
00140 stpi_xml_registry = stp_list_create();
00141 stp_list_set_freefunc(stpi_xml_registry, xml_registry_freefunc);
00142 stp_list_set_namefunc(stpi_xml_registry, xml_registry_namefunc);
00143 stpi_xml_preloads = stp_list_create();
00144 stp_list_set_freefunc(stpi_xml_preloads, xml_preload_freefunc);
00145 stp_list_set_namefunc(stpi_xml_preloads, xml_preload_namefunc);
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154 void
00155 stp_xml_init(void)
00156 {
00157 if (xml_is_initialised >= 1)
00158 {
00159 xml_is_initialised++;
00160 return;
00161 }
00162
00163
00164 saved_lc_collate = setlocale(LC_COLLATE, "C");
00165 saved_lc_ctype = setlocale(LC_CTYPE, "C");
00166 saved_lc_numeric = setlocale(LC_NUMERIC, "C");
00167
00168 xml_is_initialised = 1;
00169 }
00170
00171
00172
00173
00174
00175 void
00176 stp_xml_exit(void)
00177 {
00178 if (xml_is_initialised > 1)
00179 {
00180 xml_is_initialised--;
00181 return;
00182 }
00183 else if (xml_is_initialised < 1)
00184 return;
00185
00186
00187 setlocale(LC_COLLATE, saved_lc_collate);
00188 setlocale(LC_CTYPE, saved_lc_ctype);
00189 setlocale(LC_NUMERIC, saved_lc_numeric);
00190 xml_is_initialised = 0;
00191 }
00192
00193 void
00194 stp_xml_parse_file_named(const char *name)
00195 {
00196 stp_list_t *dir_list;
00197 stp_list_t *file_list;
00198 stp_list_item_t *item;
00199 if (!(dir_list = stp_list_create()))
00200 return;
00201 stp_list_set_freefunc(dir_list, stp_list_node_free_data);
00202 if (getenv("STP_DATA_PATH"))
00203 stp_path_split(dir_list, getenv("STP_DATA_PATH"));
00204 else
00205 stp_path_split(dir_list, PKGXMLDATADIR);
00206 file_list = stp_path_search(dir_list, name);
00207 stp_list_destroy(dir_list);
00208 item = stp_list_get_start(file_list);
00209 while (item)
00210 {
00211 stp_deprintf(STP_DBG_XML,
00212 "stp_xml_parse_file_named: source file: %s\n",
00213 (const char *) stp_list_item_get_data(item));
00214 stp_xml_parse_file((const char *) stp_list_item_get_data(item));
00215 item = stp_list_item_next(item);
00216 }
00217 stp_list_destroy(file_list);
00218 }
00219
00220
00221
00222
00223
00224 int
00225 stp_xml_init_defaults(void)
00226 {
00227 stp_list_item_t *item;
00228
00229 stp_xml_init();
00230
00231
00232 item = stp_list_get_start(stpi_xml_preloads);
00233 while (item)
00234 {
00235 stp_deprintf(STP_DBG_XML, "stp_xml_init_defaults: source file: %s\n",
00236 (const char *) stp_list_item_get_data(item));
00237 stp_xml_parse_file_named((const char *) stp_list_item_get_data(item));
00238 item = stp_list_item_next(item);
00239 }
00240 stp_list_destroy(stpi_xml_preloads);
00241
00242 stp_xml_exit();
00243
00244 return 0;
00245 }
00246
00247
00248
00249
00250
00251 int
00252 stp_xml_parse_file(const char *file)
00253 {
00254 stp_mxml_node_t *doc;
00255 stp_mxml_node_t *cur;
00256 FILE *fp;
00257
00258 stp_deprintf(STP_DBG_XML, "stp_xml_parse_file: reading `%s'...\n", file);
00259
00260 fp = fopen(file, "r");
00261 if (!fp)
00262 {
00263 stp_erprintf("stp_xml_parse_file: unable to open %s: %s\n", file,
00264 strerror(errno));
00265 return 1;
00266 }
00267
00268 stp_xml_init();
00269
00270 doc = stp_mxmlLoadFile(NULL, fp, STP_MXML_NO_CALLBACK);
00271 fclose(fp);
00272
00273 cur = doc->child;
00274 while (cur &&
00275 (cur->type != STP_MXML_ELEMENT ||
00276 (strcmp(cur->value.element.name, "gutenprint") != 0 &&
00277 strcmp(cur->value.element.name, "gimp-print") != 0)))
00278 cur = cur->next;
00279
00280 if (cur == NULL || cur->type != STP_MXML_ELEMENT)
00281 {
00282 stp_erprintf("stp_xml_parse_file: %s: parse error\n", file);
00283 stp_mxmlDelete(doc);
00284 return 1;
00285 }
00286
00287 if (strcmp(cur->value.element.name, "gutenprint") != 0 &&
00288 strcmp(cur->value.element.name, "gimp-print") != 0)
00289 {
00290 stp_erprintf
00291 ("XML file of the wrong type, root node is %s != (gutenprint || gimp-print)",
00292 cur->value.element.name);
00293 stp_mxmlDelete(doc);
00294 return 1;
00295 }
00296
00297
00298
00299 stpi_xml_process_gutenprint(cur, file);
00300 stp_mxmlDelete(doc);
00301
00302 stp_xml_exit();
00303
00304 return 0;
00305 }
00306
00307
00308
00309
00310 long
00311 stp_xmlstrtol(const char *textval)
00312 {
00313 long val;
00314 val = strtol(textval, (char **)NULL, 10);
00315
00316 return val;
00317 }
00318
00319
00320
00321
00322 unsigned long
00323 stp_xmlstrtoul(const char *textval)
00324 {
00325 unsigned long val;
00326 val = strtoul(textval, (char **)NULL, 10);
00327
00328 return val;
00329 }
00330
00331
00332
00333
00334 double
00335 stp_xmlstrtod(const char *textval)
00336 {
00337 double val;
00338 val = strtod(textval, (char **)NULL);
00339
00340 return val;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 stp_mxml_node_t *
00352 stp_xml_get_node(stp_mxml_node_t *xmlroot, ...)
00353 {
00354 stp_mxml_node_t *child;
00355 va_list ap;
00356 const char *target = NULL;
00357
00358 va_start(ap, xmlroot);
00359
00360 child = xmlroot;
00361 target = va_arg(ap, const char *);
00362
00363 while (target && child)
00364 {
00365 child = stp_mxmlFindElement(child, child, target, NULL, NULL, STP_MXML_DESCEND);
00366 target = va_arg(ap, const char *);
00367 }
00368 va_end(ap);
00369 return child;
00370 }
00371
00372 static void
00373 stpi_xml_process_node(stp_mxml_node_t *node, const char *file)
00374 {
00375 stp_list_item_t *item =
00376 stp_list_get_item_by_name(stpi_xml_registry, node->value.element.name);
00377 if (item)
00378 {
00379 stpi_xml_parse_registry *xmlp =
00380 (stpi_xml_parse_registry *) stp_list_item_get_data(item);
00381 (xmlp->parse_func)(node, file);
00382 }
00383 }
00384
00385
00386
00387
00388 static void
00389 stpi_xml_process_gutenprint(stp_mxml_node_t *cur, const char *file)
00390 {
00391 stp_mxml_node_t *child;
00392
00393 child = cur->child;
00394 while (child)
00395 {
00396
00397 if (child->type == STP_MXML_ELEMENT)
00398 stpi_xml_process_node(child, file);
00399 child = child->next;
00400 }
00401 }
00402
00403
00404
00405
00406 stp_mxml_node_t *
00407 stp_xmldoc_create_generic(void)
00408 {
00409 stp_mxml_node_t *doc;
00410 stp_mxml_node_t *rootnode;
00411
00412
00413 doc = stp_mxmlNewElement(NULL, "?xml");
00414 stp_mxmlElementSetAttr(doc, "version", "1.0");
00415
00416 rootnode = stp_mxmlNewElement(doc, "gutenprint");
00417 stp_mxmlElementSetAttr
00418 (rootnode, "xmlns", "http://gimp-print.sourceforge.net/xsd/gp.xsd-1.0");
00419 stp_mxmlElementSetAttr
00420 (rootnode, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
00421 stp_mxmlElementSetAttr
00422 (rootnode, "xsi:schemaLocation",
00423 "http://gimp-print.sourceforge.net/xsd/gp.xsd-1.0 gutenprint.xsd");
00424
00425 return doc;
00426 }
00427
00428
00429