1 /*
2 * Foomatic Perl Data
3 * ------------------
4 *
5 * Compute the Foomatic Perl data structures out of the
6 * printer/driver combo XML file or overview XML file as generated
7 * by foomatic-combo-xml.c. Compute also a Perl data structure from
8 * printer and driver entries of the Fommatic database.
9 *
10 * The Foomatic Perl data structure for the printer/driver combos is
11 * the basis for all spooler-specific config files and PPD files and
12 * also the data structure used by the filter Perl scripts.
13 *
14 * The other Perl data structures are used by the Foomatic Perl library
15 * to do the database operations provided by its API.
16 *
17 * This program is based on the libxml2 and this is a retianol way to
18 * make a C data structure from a single XML file. This structure is then
19 * converted to Perl
20 *
21 * Copyright 2001 by Till Kamppeter
22 *
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License as
25 * published by the Free Software Foundation; either version 2 of the
26 * License, or (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the Free Software
35 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
36 * 02111-1307 USA
37 *
38 */
39
40 /*
41
42 Compilable with (depending on installed packages):
43
44 gcc `xml2-config --cflags` -lxml2 -o foomatic-perl-data \
45 foomatic-perl-data.c
46
47 or
48
49 gcc `xml-config --cflags` -lxml -o foomatic-perl-data \
50 foomatic-perl-data.c
51
52 */
53
54 #include <stdio.h>
55 #include <string.h>
56 #include <stdlib.h>
57
58 /*
59 * This program should compile and run indifferently with libxml-1.8.8 +
60 * and libxml2-2.1.0 +
61 * Check the COMPAT comments below
62 */
63
64 /*
65 * COMPAT using "xml-config --cflags" to get the include path this will
66 * work with both (on distros with both xml1 and xml2 "xml2-config".
67 */
68 #include <libxml/xmlmemory.h>
69 #include <libxml/parser.h>
70
71 #define DEBUG(x) printf(x)
72
73 /*
74 * an xmlChar * is really an UTF8 encoded char string (0 terminated)
75 */
76
77 /*
78 * Records for the unprintable margins data
79 */
80
81 typedef struct marginRecord {
82 xmlChar *pagesize;
83 xmlChar *unit;
84 xmlChar *absolute;
85 xmlChar *left;
86 xmlChar *right;
87 xmlChar *top;
88 xmlChar *bottom;
89 } marginRecord, *marginRecordPtr;
90
91 typedef struct margins {
92 int num_marginRecords;
93 marginRecordPtr *marginRecords;
94 } margins, *marginsPtr;
95
96 /* For driver list in printer XML, for ready-made PPDs or user-contributed
97 printer entry */
98 typedef struct printerDrvEntry {
99 xmlChar *name;
100 xmlChar const *comment;
101 xmlChar *ppd;
102 /* functionality exceptions */
103 xmlChar *excmaxresx;
104 xmlChar *excmaxresy;
105 xmlChar *exccolor;
106 xmlChar *exctext;
107 xmlChar *exclineart;
108 xmlChar *excgraphics;
109 xmlChar *excphoto;
110 xmlChar *excload;
111 xmlChar *excspeed;
112 } printerDrvEntry, *printerDrvEntryPtr;
113
114 /*
115 * Records for the data of a printer/driver combo
116 */
117
118 typedef struct choice {
119 xmlChar const *value;
120 xmlChar const *comment;
121 xmlChar *idx;
122 xmlChar *driverval;
123 } choice, *choicePtr;
124
125 typedef struct arg {
126 xmlChar const *name;
127 xmlChar const *name_false;
128 xmlChar const *comment;
129 xmlChar *idx;
130 xmlChar *option_type;
131 xmlChar *style;
132 xmlChar *substyle;
133 xmlChar *spot;
134 xmlChar *order;
135 xmlChar *section;
136 xmlChar *grouppath;
137 xmlChar *proto;
138 xmlChar *required;
139 xmlChar *min_value;
140 xmlChar *max_value;
141 xmlChar *max_length;
142 xmlChar *allowed_chars;
143 xmlChar *allowed_regexp;
144 xmlChar const *default_value;
145 /* Choices for enumerated options */
146 int num_choices;
147 choicePtr *choices;
148 } arg, *argPtr;
149
150 typedef struct comboData {
151 /* Printer */
152 xmlChar *id;
153 xmlChar *make;
154 xmlChar *model;
155 xmlChar *pcmodel;
156 xmlChar *ppdurl;
157 /* Printer properties */
158 xmlChar *color;
159 xmlChar *ascii;
160 xmlChar *pjl;
161 xmlChar *printerppdentry;
162 marginsPtr printermargins;
163 /* Printer auto-detection */
164 xmlChar *general_ieee;
165 xmlChar *general_mfg;
166 xmlChar *general_mdl;
167 xmlChar *general_des;
168 xmlChar *general_cmd;
169 xmlChar *par_ieee;
170 xmlChar *par_mfg;
171 xmlChar *par_mdl;
172 xmlChar *par_des;
173 xmlChar *par_cmd;
174 xmlChar *usb_ieee;
175 xmlChar *usb_mfg;
176 xmlChar *usb_mdl;
177 xmlChar *usb_des;
178 xmlChar *usb_cmd;
179 xmlChar *snmp_ieee;
180 xmlChar *snmp_mfg;
181 xmlChar *snmp_mdl;
182 xmlChar *snmp_des;
183 xmlChar *snmp_cmd;
184 xmlChar *recdriver;
185 /* Driver list in printer XML file (for ready-made PPD
186 links) */
187 int num_drivers;
188 printerDrvEntryPtr *drivers;
189 /* Driver */
190 xmlChar *driver;
191 xmlChar *driver_group;
192 xmlChar *pcdriver;
193 xmlChar *driver_type;
194 xmlChar const *driver_comment;
195 xmlChar *url;
196 xmlChar *driver_obsolete;
197 xmlChar const *supplier;
198 xmlChar *manufacturersupplied;
199 xmlChar const *license;
200 xmlChar *licensetext;
201 xmlChar *origlicensetext;
202 xmlChar *licenselink;
203 xmlChar *origlicenselink;
204 xmlChar *free;
205 xmlChar *patents;
206 int num_supportcontacts;
207 xmlChar const **supportcontacts;
208 xmlChar **supportcontacturls;
209 xmlChar **supportcontactlevels;
210 xmlChar const *shortdescription;
211 xmlChar *locales;
212 int num_packages;
213 xmlChar **packageurls;
214 xmlChar **packagescopes;
215 xmlChar **packagefingerprints;
216 xmlChar *drvmaxresx;
217 xmlChar *drvmaxresy;
218 xmlChar *drvcolor;
219 xmlChar *text;
220 xmlChar *lineart;
221 xmlChar *graphics;
222 xmlChar *photo;
223 xmlChar *load;
224 xmlChar *speed;
225 xmlChar *excmaxresx;
226 xmlChar *excmaxresy;
227 xmlChar *exccolor;
228 xmlChar *exctext;
229 xmlChar *exclineart;
230 xmlChar *excgraphics;
231 xmlChar *excphoto;
232 xmlChar *excload;
233 xmlChar *excspeed;
234 int num_requires;
235 xmlChar **requires;
236 xmlChar **requiresversion;
237 xmlChar *cmd;
238 xmlChar *cmd_pdf;
239 xmlChar *nopjl;
240 xmlChar *nopageaccounting;
241 xmlChar *driverppdentry;
242 xmlChar *comboppdentry;
243 marginsPtr drivermargins;
244 marginsPtr combomargins;
245 /* Driver options */
246 int num_args;
247 argPtr *args;
248 xmlChar *maxspot;
249 } comboData, *comboDataPtr;
250
251 /*
252 * Record for a Foomatic printer entry
253 */
254
255 typedef struct printerLanguage {
256 xmlChar *name;
257 xmlChar *level;
258 } printerLanguage, *printerLanguagePtr;
259
260 typedef struct printerEntry {
261 xmlChar *id;
262 xmlChar *make;
263 xmlChar *model;
264 /* Printer properties */
265 xmlChar *printer_type;
266 xmlChar *color;
267 xmlChar *maxxres;
268 xmlChar *maxyres;
269 xmlChar const *refill;
270 xmlChar *ascii;
271 xmlChar *pjl;
272 xmlChar *printerppdentry;
273 marginsPtr printermargins;
274 /* Printer auto-detection */
275 xmlChar *general_ieee;
276 xmlChar *general_mfg;
277 xmlChar *general_mdl;
278 xmlChar *general_des;
279 xmlChar *general_cmd;
280 xmlChar *par_ieee;
281 xmlChar *par_mfg;
282 xmlChar *par_mdl;
283 xmlChar *par_des;
284 xmlChar *par_cmd;
285 xmlChar *usb_ieee;
286 xmlChar *usb_mfg;
287 xmlChar *usb_mdl;
288 xmlChar *usb_des;
289 xmlChar *usb_cmd;
290 xmlChar *snmp_ieee;
291 xmlChar *snmp_mfg;
292 xmlChar *snmp_mdl;
293 xmlChar *snmp_des;
294 xmlChar *snmp_cmd;
295 /* Misc items */
296 xmlChar *functionality;
297 xmlChar *driver;
298 xmlChar *unverified;
299 xmlChar *noxmlentry;
300 xmlChar *url;
301 xmlChar *contriburl;
302 xmlChar *ppdurl;
303 xmlChar const *comment;
304 /* Page Description Languages */
305 int num_languages;
306 printerLanguagePtr *languages;
307 /* Drivers (for user-contributed printer entries and for ready-made PPD
308 links) */
309 int num_drivers;
310 printerDrvEntryPtr *drivers;
311 } printerEntry, *printerEntryPtr;
312
313 /*
314 * Records for a Foomatic driver entry
315 */
316
317 typedef struct drvPrnEntry {
318 xmlChar *id;
319 xmlChar const *comment;
320 /* functionality exceptions */
321 xmlChar *excmaxresx;
322 xmlChar *excmaxresy;
323 xmlChar *exccolor;
324 xmlChar *exctext;
325 xmlChar *exclineart;
326 xmlChar *excgraphics;
327 xmlChar *excphoto;
328 xmlChar *excload;
329 xmlChar *excspeed;
330 } drvPrnEntry, *drvPrnEntryPtr;
331
332 typedef struct driverEntry {
333 xmlChar *id;
334 xmlChar *name;
335 xmlChar *group;
336 xmlChar *url;
337 xmlChar *driver_obsolete;
338 xmlChar const *supplier;
339 xmlChar *manufacturersupplied;
340 xmlChar const *license;
341 xmlChar *licensetext;
342 xmlChar *origlicensetext;
343 xmlChar *licenselink;
344 xmlChar *origlicenselink;
345 xmlChar *free;
346 xmlChar *patents;
347 int num_supportcontacts;
348 xmlChar const **supportcontacts;
349 xmlChar **supportcontacturls;
350 xmlChar **supportcontactlevels;
351 xmlChar const *shortdescription;
352 xmlChar *locales;
353 int num_packages;
354 xmlChar **packageurls;
355 xmlChar **packagescopes;
356 xmlChar **packagefingerprints;
357 xmlChar *maxresx;
358 xmlChar *maxresy;
359 xmlChar *color;
360 xmlChar *text;
361 xmlChar *lineart;
362 xmlChar *graphics;
363 xmlChar *photo;
364 xmlChar *load;
365 xmlChar *speed;
366 int num_requires;
367 xmlChar **requires;
368 xmlChar **requiresversion;
369 xmlChar *driver_type;
370 xmlChar *cmd;
371 xmlChar *cmd_pdf;
372 xmlChar *driverppdentry;
373 marginsPtr drivermargins;
374 xmlChar const *comment;
375 int num_printers;
376 drvPrnEntryPtr *printers;
377 } driverEntry, *driverEntryPtr;
378
379 /*
380 * Records for the data of the overview
381 */
382
383 typedef struct ppdFile {
384 xmlChar *driver;
385 xmlChar *filename;
386 } ppdFile, *ppdFilePtr;
387
388 typedef struct overviewPrinter {
389 /* General info */
390 xmlChar *id;
391 xmlChar *make;
392 xmlChar *model;
393 xmlChar *functionality;
394 xmlChar *unverified;
395 xmlChar *noxmlentry;
396 /* Printer auto-detection */
397 xmlChar *general_ieee;
398 xmlChar *general_mfg;
399 xmlChar *general_mdl;
400 xmlChar *general_des;
401 xmlChar *general_cmd;
402 xmlChar *par_ieee;
403 xmlChar *par_mfg;
404 xmlChar *par_mdl;
405 xmlChar *par_des;
406 xmlChar *par_cmd;
407 xmlChar *usb_ieee;
408 xmlChar *usb_mfg;
409 xmlChar *usb_mdl;
410 xmlChar *usb_des;
411 xmlChar *usb_cmd;
412 xmlChar *snmp_ieee;
413 xmlChar *snmp_mfg;
414 xmlChar *snmp_mdl;
415 xmlChar *snmp_des;
416 xmlChar *snmp_cmd;
417 /* Drivers */
418 xmlChar *driver;
419 int num_drivers;
420 printerDrvEntryPtr *drivers;
421 /* PPD files */
422 int num_ppdfiles;
423 ppdFilePtr *ppdfiles;
424 } overviewPrinter, *overviewPrinterPtr;
425
426 typedef struct overview {
427 int num_overviewDrivers;
428 driverEntryPtr *overviewDrivers;
429 int num_overviewPrinters;
430 overviewPrinterPtr *overviewPrinters;
431 } overview, *overviewPtr;
432
433 /*
434 * Function to quote "'" and "\" in a string
435 */
436
437 static xmlChar* /* O - String with quoted "'" */
perlquote(xmlChar * str)438 perlquote(xmlChar *str) { /* I - Original string */
439 xmlChar *dest, *s;
440 int offset = 0;
441
442 if (str == NULL) return NULL;
443 dest = xmlStrdup(str);
444 while ((s = (xmlChar *)xmlStrchr((const xmlChar *)(dest + offset),
445 (xmlChar)'\'')) ||
446 (s = (xmlChar *)xmlStrchr((const xmlChar *)(dest + offset),
447 (xmlChar)'\\'))) {
448 offset = s - dest;
449 dest = (xmlChar *)realloc((xmlChar *)dest,
450 sizeof(xmlChar) * (xmlStrlen(dest) + 2));
451 s = dest + offset;
452 memmove(s + 1, s, xmlStrlen(dest) + 1 - offset);
453 *s = '\\';
454 offset += 2;
455 }
456 return(dest);
457 }
458
459 /*
460 * Functions to read out localized text, choosing the translation into the
461 * desired language. Reads also simple text without language tags, for
462 * backward compatibility for the case that a not yet localized database
463 * field gets localized. The second function is especially for license text.
464 * It returns always the English (original) version in addition and allows
465 * links to text files as alternative to the text itself, as often license text
466 * has to be in its own file.
467 */
468
469 xmlChar const sc_locale_C [] = "C", sc_locale_POSIX [] = "POSIX";
470
471 static void
getLocalizedText(xmlDocPtr doc,xmlNodePtr node,xmlChar const ** ret,xmlChar const language[],int debug)472 getLocalizedText(xmlDocPtr doc, /* I - The whole data tree */
473 xmlNodePtr node, /* I - Node of XML tree to work on */
474 xmlChar const **ret, /* O - Text which was selected by the
475 language */
476 xmlChar const language [], /* I - User language */
477 int debug) { /* I - Debug mode flag */
478 xmlNodePtr cur1; /* XML node currently worked on */
479
480 cur1 = node->xmlChildrenNode;
481 if
482 (xmlStrcasecmp(cur1->name, sc_locale_C)
483 && xmlStrcasecmp(cur1->name, sc_locale_POSIX)) {
484 while (cur1 != NULL) {
485 /* Exact match of locale ID */
486 if ((!xmlStrcasecmp(cur1->name, language))) {
487 *ret = xmlStrdup
488 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
489 if (debug)
490 fprintf
491 (stderr,
492 " Localized text with full locale ID matched (%s):\n\n%s\n\n",
493 language, *ret);
494 return;
495 }
496 cur1 = cur1->next;
497 }
498 cur1 = node->xmlChildrenNode;
499 while (cur1 != NULL) {
500 /* Fall back to match only the two-character language code */
501 if ((!xmlStrncasecmp(cur1->name, language, 2))) {
502 *ret = xmlStrdup
503 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
504 if (debug)
505 fprintf
506 (stderr,
507 " Localized text with only language ID matched (%s):\n\n%s\n\n",
508 language, *ret);
509 return;
510 }
511 cur1 = cur1->next;
512 }
513 cur1 = node->xmlChildrenNode;
514 }
515 while (cur1 != NULL) {
516 /* Fall back to English */
517 if ((!xmlStrncasecmp(cur1->name, (const xmlChar *) "en", 2))) {
518 *ret = xmlStrdup
519 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
520 if (debug)
521 fprintf(stderr, " English text:\n\n%s\n\n", *ret);
522 return;
523 }
524 cur1 = cur1->next;
525 }
526 cur1 = node->xmlChildrenNode;
527 /* Fall back to non-localized text (allows backward compatibility if
528 deciding on localizing a database item later */
529 *ret = xmlStrdup(perlquote(xmlNodeListGetString(doc, cur1, 1)));
530 if (debug)
531 fprintf(stderr, " Non-localized text:\n\n%s\n\n", *ret);
532 }
533
534 static void
getLocalizedLicenseText(xmlDocPtr doc,xmlNodePtr node,xmlChar ** text,xmlChar ** origtext,xmlChar ** link,xmlChar ** origlink,xmlChar const language[],int debug)535 getLocalizedLicenseText(xmlDocPtr doc, /* I - The whole data tree */
536 xmlNodePtr node, /* I - Node of XML tree to work on */
537 xmlChar **text, /* O - Text which was selected by the
538 language */
539 xmlChar **origtext, /* O - Original text in English */
540 xmlChar **link, /* O - Link which was selected by the
541 language */
542 xmlChar **origlink, /* O - Link to original text in English */
543 xmlChar const language [], /* I - User language */
544 int debug) { /* I - Debug mode flag */
545 xmlNodePtr cur1; /* XML node currently worked on */
546 int localizedtextfound = 0;
547
548 cur1 = node->xmlChildrenNode;
549 if (xmlStrcasecmp(cur1->name, sc_locale_C) && xmlStrcasecmp(cur1->name, sc_locale_POSIX)) {
550 while (cur1 != NULL) {
551 /* Exact match of locale ID */
552 if ((!xmlStrcasecmp(cur1->name, language))) {
553 *link = xmlGetProp(cur1, (const xmlChar *) "url");
554 if (*link == NULL) {
555 *text = xmlStrdup
556 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
557 if (debug)
558 fprintf
559 (stderr,
560 " Localized text with full locale ID matched (%s):\n\n%s\n\n",
561 language, *text);
562 } else {
563 if (debug)
564 fprintf
565 (stderr,
566 " Link to localized text with full locale ID matched (%s):\n\n%s\n\n",
567 language, *link);
568 }
569 localizedtextfound = 1;
570 break;
571 }
572 cur1 = cur1->next;
573 }
574 if (localizedtextfound == 0) {
575 cur1 = node->xmlChildrenNode;
576 while (cur1 != NULL) {
577 /* Fall back to match only the two-character language code */
578 if ((!xmlStrncasecmp(cur1->name, language, 2))) {
579 *link = xmlGetProp(cur1, (const xmlChar *) "url");
580 if (*link == NULL) {
581 *text = xmlStrdup
582 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
583 if (debug)
584 fprintf
585 (stderr,
586 " Localized text with only language ID matched (%s):\n\n%s\n\n",
587 language, *text);
588 } else {
589 if (debug)
590 fprintf
591 (stderr,
592 " Link to localized text with only language ID matched (%s):\n\n%s\n\n",
593 language, *link);
594 }
595 localizedtextfound = 1;
596 break;
597 }
598 cur1 = cur1->next;
599 }
600 }
601 }
602 cur1 = node->xmlChildrenNode;
603 while (cur1 != NULL) {
604 /* Fall back to English and/or extract original, English text/link */
605 if ((!xmlStrncasecmp(cur1->name, (const xmlChar *) "en", 2))) {
606 *origlink = xmlGetProp(cur1, (const xmlChar *) "url");
607 if (*origlink == NULL) {
608 *origtext = xmlStrdup
609 (perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1)));
610 if (debug)
611 fprintf(stderr, " Original English text:\n\n%s\n\n", *origtext);
612 if (localizedtextfound == 0) {
613 *text = *origtext;
614 if (debug)
615 fprintf(stderr,
616 " No localization, using original English text\n");
617 }
618 } else {
619 if (debug)
620 fprintf(stderr, " Link to original English text:\n\n%s\n\n",
621 *origlink);
622 if (localizedtextfound == 0) {
623 *link = *origlink;
624 if (debug)
625 fprintf(stderr,
626 " No localization, using original English link\n");
627 }
628 }
629 return;
630 }
631 cur1 = cur1->next;
632 }
633 cur1 = node->xmlChildrenNode;
634 /* Fall back to non-localized text (allows backward compatibility if
635 deciding on localizing a database item later */
636 *link = xmlGetProp(cur1, (const xmlChar *) "url");
637 if (*link == NULL) {
638 *text = xmlStrdup(perlquote(xmlNodeListGetString(doc, cur1, 1)));
639 *origtext = *text;
640 if (debug)
641 fprintf(stderr, " Non-localized text:\n\n%s\n\n", *text);
642 } else {
643 *origlink = *link;
644 if (debug)
645 fprintf(stderr, " Link to non-localized text:\n\n%s\n\n", *link);
646 }
647 }
648
649 /*
650 * Functions to fill in the unprintable margin data structure with the
651 * data parsed from the XML input
652 */
653
654 static void
parseMarginEntry(xmlDocPtr doc,xmlNodePtr node,int entrytype,marginsPtr ret,xmlChar const language[],int debug)655 parseMarginEntry(xmlDocPtr doc, /* I - The whole combo data tree */
656 xmlNodePtr node, /* I - Node of XML tree to work on */
657 int entrytype, /* I - 0: General, 1: Page size
658 exzception */
659 marginsPtr ret, /* O - C data structure of Foomatic
660 overview */
661 xmlChar const language [], /* I - User language */
662 int debug) { /* I - Debug mode flag */
663 xmlNodePtr cur1; /* XML node currently worked on */
664 xmlChar *pagesize;
665 marginRecordPtr marginRec;
666
667 /* Allocate memory for the margin record */
668 ret->num_marginRecords ++;
669 ret->marginRecords =
670 (marginRecordPtr *)realloc
671 ((marginRecordPtr *)(ret->marginRecords),
672 sizeof(marginRecordPtr) * ret->num_marginRecords);
673 marginRec = (marginRecordPtr) malloc(sizeof(marginRecord));
674 if (marginRec == NULL) {
675 fprintf(stderr,"Out of memory!\n");
676 xmlFreeDoc(doc);
677 exit(1);
678 }
679 ret->marginRecords[ret->num_marginRecords-1] = marginRec;
680 memset(marginRec, 0, sizeof(marginRecord));
681
682 /* Initialization of entries */
683 marginRec->pagesize = NULL;
684 marginRec->unit = NULL;
685 marginRec->absolute = NULL;
686 marginRec->left = NULL;
687 marginRec->right = NULL;
688 marginRec->top = NULL;
689 marginRec->bottom = NULL;
690
691 /* Get page size */
692 if (entrytype > 0) {
693 pagesize = xmlGetProp(node, (const xmlChar *) "PageSize");
694 if (pagesize != NULL) {
695 marginRec->pagesize = perlquote(pagesize);
696 if (debug) fprintf(stderr, " Margins for page size %s\n",
697 marginRec->pagesize);
698 } else {
699 fprintf(stderr,"Page size missing!\n");
700 xmlFreeDoc(doc);
701 exit(1);
702 }
703 } else {
704 if (debug) fprintf(stderr, " General Margins\n");
705 }
706
707 /* Go through subnodes */
708 cur1 = node->xmlChildrenNode;
709 while (cur1 != NULL) {
710 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "unit"))) {
711 marginRec->unit =
712 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
713 if (debug) fprintf(stderr, " Unit: %s\n", marginRec->unit);
714 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "absolute"))) {
715 marginRec->absolute = (xmlChar *)"1";
716 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
717 if (debug) fprintf(stderr, " Absolute values\n");
718 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "relative"))) {
719 marginRec->absolute = (xmlChar *)"0";
720 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
721 if (debug) fprintf(stderr, " Relative values\n");
722 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "left"))) {
723 marginRec->left =
724 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
725 if (debug) fprintf(stderr, " Left margin: %s\n",
726 marginRec->left);
727 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "right"))) {
728 marginRec->right =
729 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
730 if (debug) fprintf(stderr, " Right margin: %s\n",
731 marginRec->right);
732 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "top"))) {
733 marginRec->top =
734 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
735 if (debug) fprintf(stderr, " Top margin: %s\n",
736 marginRec->top);
737 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "bottom"))) {
738 marginRec->bottom =
739 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
740 if (debug) fprintf(stderr, " Bottom margin: %s\n",
741 marginRec->bottom);
742 }
743 cur1 = cur1->next;
744 }
745 }
746
747 static void
parseMargins(xmlDocPtr doc,xmlNodePtr node,marginsPtr * ret,xmlChar const language[],int debug)748 parseMargins(xmlDocPtr doc, /* I - The whole combo data tree */
749 xmlNodePtr node, /* I - Node of XML tree to work on */
750 marginsPtr *ret, /* O - C data structure of Foomatic
751 overview */
752 xmlChar const language [], /* I - User language */
753 int debug) { /* I - Debug mode flag */
754 xmlNodePtr cur1; /* XML node currently worked on */
755
756 /* Allocate memory for the margins data structure */
757 *ret = (marginsPtr) malloc(sizeof(margins));
758 if (*ret == NULL) {
759 fprintf(stderr,"Out of memory!\n");
760 xmlFreeDoc(doc);
761 exit(1);
762 }
763 memset(*ret, 0, sizeof(margins));
764
765 /* Initialization of entries */
766 (*ret)->num_marginRecords = 0;
767 (*ret)->marginRecords = NULL;
768
769 if (debug) fprintf(stderr, " Unprintable margins\n");
770
771 /* Go through subnodes */
772 cur1 = node->xmlChildrenNode;
773 while (cur1 != NULL) {
774 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "general"))) {
775 parseMarginEntry(doc, cur1, 0, *ret, language, debug);
776 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "exception"))) {
777 parseMarginEntry(doc, cur1, 1, *ret, language, debug);
778 }
779 cur1 = cur1->next;
780 }
781 }
782
783 /*
784 * Function to fill in the Foomatic overview data structure with the
785 * data parsed from the XML input
786 */
787
788 static void
parseOverviewPrinter(xmlDocPtr doc,xmlNodePtr node,overviewPtr ret,xmlChar const language[],int debug)789 parseOverviewPrinter(xmlDocPtr doc, /* I - The whole combo data tree */
790 xmlNodePtr node, /* I - Node of XML tree to work on */
791 overviewPtr ret, /* O - C data structure of Foomatic
792 overview */
793 xmlChar const language [], /* I - User language */
794 int debug) { /* I - Debug mode flag */
795 xmlNodePtr cur1; /* XML node currently worked on */
796 xmlNodePtr cur2; /* Another XML node pointer */
797 xmlNodePtr cur3; /* Another XML node pointer */
798 xmlNodePtr cur4; /* Another XML node pointer */
799 xmlChar *id; /* Full printer ID, with "printer/" */
800 xmlChar *charset;
801 xmlChar *drivername;
802 overviewPrinterPtr printer;
803 printerDrvEntryPtr dentry; /* An entry for a driver supporting this
804 printer */
805 ppdFilePtr ppd;
806 int driverfound;
807 int i, j;
808
809 /* Allocate memory for the printer */
810 ret->num_overviewPrinters ++;
811 ret->overviewPrinters =
812 (overviewPrinterPtr *)realloc
813 ((overviewPrinterPtr *)(ret->overviewPrinters),
814 sizeof(overviewPrinterPtr) * ret->num_overviewPrinters);
815 printer = (overviewPrinterPtr) malloc(sizeof(overviewPrinter));
816 if (printer == NULL) {
817 fprintf(stderr,"Out of memory!\n");
818 xmlFreeDoc(doc);
819 exit(1);
820 }
821 ret->overviewPrinters[ret->num_overviewPrinters-1] = printer;
822 memset(printer, 0, sizeof(overviewPrinter));
823
824 /* Initialization of entries */
825 printer->id = NULL;
826 printer->make = NULL;
827 printer->model = NULL;
828 printer->functionality = (xmlChar *)"X";
829 printer->unverified = NULL;
830 printer->noxmlentry = NULL;
831 printer->general_ieee = NULL;
832 printer->general_mfg = NULL;
833 printer->general_mdl = NULL;
834 printer->general_des = NULL;
835 printer->general_cmd = NULL;
836 printer->par_ieee = NULL;
837 printer->par_mfg = NULL;
838 printer->par_mdl = NULL;
839 printer->par_des = NULL;
840 printer->par_cmd = NULL;
841 printer->usb_ieee = NULL;
842 printer->usb_mfg = NULL;
843 printer->usb_mdl = NULL;
844 printer->usb_des = NULL;
845 printer->usb_cmd = NULL;
846 printer->snmp_ieee = NULL;
847 printer->snmp_mfg = NULL;
848 printer->snmp_mdl = NULL;
849 printer->snmp_des = NULL;
850 printer->snmp_cmd = NULL;
851 printer->driver = NULL;
852 printer->num_drivers = 0;
853 printer->drivers = NULL;
854 printer->num_ppdfiles = 0;
855 printer->ppdfiles = NULL;
856
857 /* Go through subnodes */
858 cur1 = node->xmlChildrenNode;
859 while (cur1 != NULL) {
860 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "id"))) {
861 printer->id =
862 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
863 if (debug) fprintf(stderr, " Printer ID: %s\n", printer->id);
864 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "make"))) {
865 printer->make =
866 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
867 if (debug) fprintf(stderr, " Printer Manufacturer: %s\n",
868 printer->make);
869 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "model"))) {
870 printer->model =
871 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
872 if (debug) fprintf(stderr, " Printer Model: %s\n", printer->model);
873 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) {
874 printer->functionality =
875 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
876 if (debug) fprintf(stderr, " Printer Functionality: %s\n",
877 printer->functionality);
878 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "unverified"))) {
879 printer->unverified = (xmlChar *)"1";
880 if (debug) fprintf(stderr, " Printer entry is unverified\n");
881 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "noxmlentry"))) {
882 printer->noxmlentry = (xmlChar *)"1";
883 if (debug) fprintf(stderr, " Printer XML entry does not exist in the database\n");
884 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driver"))) {
885 printer->driver =
886 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
887 if (debug) fprintf(stderr, " Recommended driver: %s\n",
888 printer->driver);
889 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "drivers"))) {
890 cur2 = cur1->xmlChildrenNode;
891 while (cur2 != NULL) {
892 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driver"))) {
893 drivername =
894 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
895 driverfound = 0;
896 for (i = 0; i < printer->num_drivers; i++) {
897 dentry = printer->drivers[i];
898 if ((dentry->name != NULL) &&
899 (!xmlStrcmp(drivername, dentry->name))) {
900 driverfound = 1;
901 break;
902 }
903 }
904 if (!driverfound) {
905 printer->num_drivers ++;
906 printer->drivers =
907 (printerDrvEntryPtr *)
908 realloc((printerDrvEntryPtr *)printer->drivers,
909 sizeof(printerDrvEntryPtr) *
910 printer->num_drivers);
911 dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry));
912 if (dentry == NULL) {
913 fprintf(stderr,"Out of memory!\n");
914 xmlFreeDoc(doc);
915 exit(1);
916 }
917 printer->drivers[printer->num_drivers-1] = dentry;
918 memset(dentry, 0, sizeof(printerDrvEntry));
919 dentry->name = NULL;
920 dentry->comment = NULL;
921 dentry->ppd = NULL;
922 dentry->excmaxresx = NULL;
923 dentry->excmaxresy = NULL;
924 dentry->exccolor = NULL;
925 dentry->exctext = NULL;
926 dentry->exclineart = NULL;
927 dentry->excgraphics = NULL;
928 dentry->excphoto = NULL;
929 dentry->excload = NULL;
930 dentry->excspeed = NULL;
931 }
932 dentry->name = drivername;
933 if (debug) fprintf(stderr, " Printer works with: %s\n",
934 dentry->name);
935 }
936 cur2 = cur2->next;
937 }
938 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driverfunctionalityexceptions"))) {
939 cur2 = cur1->xmlChildrenNode;
940 while (cur2 != NULL) {
941 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driverfunctionalityexception"))) {
942 drivername = NULL;
943 dentry = NULL;
944 cur3 = cur2->xmlChildrenNode;
945 while (cur3 != NULL) {
946 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "driver"))) {
947 drivername =
948 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
949 if (debug)
950 fprintf(stderr, " Functionality exceptions for driver: %s\n",
951 drivername);
952 if ((dentry != NULL) && (dentry->name == NULL)) {
953 dentry->name = drivername;
954 /* Check whether there is already an entry for this driver
955 and delete this old entry */
956 for (i = 0; i < printer->num_drivers - 1; i++) {
957 if ((printer->drivers[i]->name != NULL) &&
958 (!xmlStrcmp(drivername, printer->drivers[i]->name))) {
959 for (j = i + 1; j < printer->num_drivers; j++)
960 printer->drivers[j - 1] = printer->drivers[j];
961 printer->num_drivers --;
962 printer->drivers =
963 (printerDrvEntryPtr *)
964 realloc((printerDrvEntryPtr *)printer->drivers,
965 sizeof(printerDrvEntryPtr) *
966 printer->num_drivers);
967 break;
968 }
969 }
970 }
971 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) {
972 driverfound = 0;
973 dentry = NULL;
974 if (drivername != NULL) {
975 for (i = 0; i < printer->num_drivers; i++) {
976 dentry = printer->drivers[i];
977 if ((dentry->name != NULL) &&
978 (!xmlStrcmp(drivername, dentry->name))) {
979 driverfound = 1;
980 break;
981 }
982 }
983 }
984 if (!driverfound) {
985 printer->num_drivers ++;
986 printer->drivers =
987 (printerDrvEntryPtr *)
988 realloc((printerDrvEntryPtr *)printer->drivers,
989 sizeof(printerDrvEntryPtr) *
990 printer->num_drivers);
991 dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry));
992 if (dentry == NULL) {
993 fprintf(stderr,"Out of memory!\n");
994 xmlFreeDoc(doc);
995 exit(1);
996 }
997 printer->drivers[printer->num_drivers-1] = dentry;
998 memset(dentry, 0, sizeof(printerDrvEntry));
999 dentry->name = NULL;
1000 dentry->comment = NULL;
1001 dentry->ppd = NULL;
1002 dentry->excmaxresx = NULL;
1003 dentry->excmaxresy = NULL;
1004 dentry->exccolor = NULL;
1005 dentry->exctext = NULL;
1006 dentry->exclineart = NULL;
1007 dentry->excgraphics = NULL;
1008 dentry->excphoto = NULL;
1009 dentry->excload = NULL;
1010 dentry->excspeed = NULL;
1011 }
1012 dentry->name = drivername;
1013 if (drivername != NULL) {
1014 if (debug)
1015 fprintf(stderr, " Functionality exceptions for driver: %s\n",
1016 dentry->name);
1017 }
1018 cur4 = cur3->xmlChildrenNode;
1019 while (cur4 != NULL) {
1020 if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) {
1021 dentry->excmaxresx =
1022 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1023 if (debug)
1024 fprintf(stderr, " Maximum X resolution: %s\n",
1025 dentry->excmaxresx);
1026 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) {
1027 dentry->excmaxresy =
1028 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1029 if (debug)
1030 fprintf(stderr, " Maximum Y resolution: %s\n",
1031 dentry->excmaxresy);
1032 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) {
1033 dentry->exccolor = (xmlChar *)"0";
1034 if (debug)
1035 fprintf(stderr, " Color: %s\n",
1036 dentry->exccolor);
1037 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) {
1038 dentry->exccolor = (xmlChar *)"1";
1039 if (debug)
1040 fprintf(stderr, " Color: %s\n",
1041 dentry->exccolor);
1042 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) {
1043 dentry->exctext =
1044 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1045 if (debug)
1046 fprintf(stderr, " Support level for text: %s\n",
1047 dentry->exctext);
1048 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) {
1049 dentry->exclineart =
1050 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1051 if (debug)
1052 fprintf(stderr, " Support level for line art: %s\n",
1053 dentry->exclineart);
1054 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) {
1055 dentry->excgraphics =
1056 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1057 if (debug)
1058 fprintf(stderr, " Support level for graphics: %s\n",
1059 dentry->excgraphics);
1060 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) {
1061 dentry->excphoto =
1062 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1063 if (debug)
1064 fprintf(stderr, " Support level for photos: %s\n",
1065 dentry->excphoto);
1066 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) {
1067 dentry->excload =
1068 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1069 if (debug)
1070 fprintf(stderr, " Expected relative system load: %s\n",
1071 dentry->excload);
1072 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) {
1073 dentry->excspeed =
1074 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1075 if (debug)
1076 fprintf(stderr, " Expected relative driver speed: %s\n",
1077 dentry->excspeed);
1078 }
1079 cur4 = cur4->next;
1080 }
1081 }
1082 cur3 = cur3->next;
1083 }
1084 }
1085 cur2 = cur2->next;
1086 }
1087 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "ppds"))) {
1088 cur2 = cur1->xmlChildrenNode;
1089 while (cur2 != NULL) {
1090 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ppd"))) {
1091 printer->num_ppdfiles ++;
1092 printer->ppdfiles =
1093 (ppdFilePtr *)
1094 realloc((ppdFilePtr *)printer->ppdfiles,
1095 sizeof(ppdFilePtr) *
1096 printer->num_ppdfiles);
1097 ppd = (ppdFilePtr) malloc(sizeof(ppdFile));
1098 if (ppd == NULL) {
1099 fprintf(stderr,"Out of memory!\n");
1100 xmlFreeDoc(doc);
1101 exit(1);
1102 }
1103 printer->ppdfiles[printer->num_ppdfiles-1] = ppd;
1104 memset(ppd, 0, sizeof(ppdFile));
1105 ppd->driver = NULL;
1106 ppd->filename = NULL;
1107 if (debug) fprintf(stderr, " Available ready-made PPD file:\n");
1108 cur3 = cur2->xmlChildrenNode;
1109 while (cur3 != NULL) {
1110 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "driver"))) {
1111 ppd->driver =
1112 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
1113 if (debug) fprintf(stderr, " For driver: %s\n",
1114 ppd->driver);
1115 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppdfile"))) {
1116 ppd->filename =
1117 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
1118 if (debug) fprintf(stderr, " File name: %s\n",
1119 ppd->filename);
1120 }
1121 cur3 = cur3->next;
1122 }
1123 }
1124 cur2 = cur2->next;
1125 }
1126 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "autodetect"))) {
1127 cur2 = cur1->xmlChildrenNode;
1128 while (cur2 != NULL) {
1129 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "general"))) {
1130 cur3 = cur2->xmlChildrenNode;
1131 if (debug) fprintf(stderr, " Printer auto-detection info (general):\n");
1132 while (cur3 != NULL) {
1133 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1134 printer->general_ieee =
1135 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1136 1));
1137 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1138 printer->general_ieee);
1139
1140 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1141 printer->general_mfg =
1142 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1143 1));
1144 if (debug) fprintf(stderr, " MFG: %s\n", printer->general_mfg);
1145
1146 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1147 printer->general_mdl =
1148 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1149 1));
1150 if (debug) fprintf(stderr, " MDL: %s\n", printer->general_mdl);
1151 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1152 printer->general_des =
1153 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1154 1));
1155 if (debug) fprintf(stderr, " DES: %s\n", printer->general_des);
1156 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1157 printer->general_cmd =
1158 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1159 1));
1160 if (debug) fprintf(stderr, " CMD: %s\n", printer->general_cmd);
1161 }
1162 cur3 = cur3->next;
1163 }
1164 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "parallel"))) {
1165 cur3 = cur2->xmlChildrenNode;
1166 if (debug) fprintf(stderr, " Printer auto-detection info (parallel port):\n");
1167 while (cur3 != NULL) {
1168 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1169 printer->par_ieee =
1170 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1171 1));
1172 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1173 printer->par_ieee);
1174
1175 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1176 printer->par_mfg =
1177 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1178 1));
1179 if (debug) fprintf(stderr, " MFG: %s\n", printer->par_mfg);
1180
1181 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1182 printer->par_mdl =
1183 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1184 1));
1185 if (debug) fprintf(stderr, " MDL: %s\n", printer->par_mdl);
1186 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1187 printer->par_des =
1188 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1189 1));
1190 if (debug) fprintf(stderr, " DES: %s\n", printer->par_des);
1191 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1192 printer->par_cmd =
1193 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1194 1));
1195 if (debug) fprintf(stderr, " CMD: %s\n", printer->par_cmd);
1196 }
1197 cur3 = cur3->next;
1198 }
1199 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "usb"))) {
1200 cur3 = cur2->xmlChildrenNode;
1201 if (debug) fprintf(stderr, " Printer auto-detection info (USB):\n");
1202 while (cur3 != NULL) {
1203 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1204 printer->usb_ieee =
1205 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1206 1));
1207 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1208 printer->usb_ieee);
1209
1210 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1211 printer->usb_mfg =
1212 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1213 1));
1214 if (debug) fprintf(stderr, " MFG: %s\n", printer->usb_mfg);
1215
1216 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1217 printer->usb_mdl =
1218 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1219 1));
1220 if (debug) fprintf(stderr, " MDL: %s\n", printer->usb_mdl);
1221 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1222 printer->usb_des =
1223 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1224 1));
1225 if (debug) fprintf(stderr, " DES: %s\n", printer->usb_des);
1226 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1227 printer->usb_cmd =
1228 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1229 1));
1230 if (debug) fprintf(stderr, " CMD: %s\n", printer->usb_cmd);
1231 }
1232 cur3 = cur3->next;
1233 }
1234 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "snmp"))) {
1235 cur3 = cur2->xmlChildrenNode;
1236 if (debug) fprintf(stderr, " Printer auto-detection info (SNMP):\n");
1237 while (cur3 != NULL) {
1238 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1239 printer->snmp_ieee =
1240 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1241 1));
1242 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1243 printer->snmp_ieee);
1244
1245 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1246 printer->snmp_mfg =
1247 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1248 1));
1249 if (debug) fprintf(stderr, " MFG: %s\n", printer->snmp_mfg);
1250
1251 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1252 printer->snmp_mdl =
1253 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1254 1));
1255 if (debug) fprintf(stderr, " MDL: %s\n", printer->snmp_mdl);
1256 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1257 printer->snmp_des =
1258 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1259 1));
1260 if (debug) fprintf(stderr, " DES: %s\n", printer->snmp_des);
1261 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1262 printer->snmp_cmd =
1263 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1264 1));
1265 if (debug) fprintf(stderr, " CMD: %s\n", printer->snmp_cmd);
1266 }
1267 cur3 = cur3->next;
1268 }
1269 }
1270 cur2 = cur2->next;
1271 }
1272 }
1273 cur1 = cur1->next;
1274 }
1275 }
1276
1277 /*
1278 * Functions to fill in the printer/driver combo data structure with the
1279 * data parsed from the XML input
1280 */
1281
1282 static void
parseComboPrinter(xmlDocPtr doc,xmlNodePtr node,comboDataPtr ret,xmlChar const language[],int debug)1283 parseComboPrinter(xmlDocPtr doc, /* I - The whole combo data tree */
1284 xmlNodePtr node, /* I - Node of XML tree to work on */
1285 comboDataPtr ret, /* O - C data structure of Foomatic
1286 combo */
1287 xmlChar const language [], /* I - User language */
1288 int debug) { /* I - Debug mode flag */
1289 xmlNodePtr cur1; /* XML node currently worked on */
1290 xmlNodePtr cur2; /* Another XML node pointer */
1291 xmlNodePtr cur3; /* Another XML node pointer */
1292 xmlNodePtr cur4; /* Another XML node pointer */
1293 xmlChar *id; /* Full printer ID, with "printer/" */
1294 xmlChar *charset;
1295 xmlChar *dname; /* Name of a driver supporting this printer */
1296 xmlChar *dppd; /* Ready-made PPD supporting this printer */
1297 printerDrvEntryPtr dentry; /* An entry for a driver supporting this
1298 printer */
1299
1300 /* Initialization of entries */
1301 ret->id = NULL;
1302 ret->make = NULL;
1303 ret->model = NULL;
1304 ret->pcmodel = NULL;
1305 ret->ppdurl = NULL;
1306 ret->color = (xmlChar *)"0";
1307 ret->pjl = (xmlChar *)"undef";
1308 ret->ascii = (xmlChar *)"0";
1309 ret->printerppdentry = NULL;
1310 ret->printermargins = NULL;
1311 ret->general_ieee = NULL;
1312 ret->general_mfg = NULL;
1313 ret->general_mdl = NULL;
1314 ret->general_des = NULL;
1315 ret->general_cmd = NULL;
1316 ret->par_ieee = NULL;
1317 ret->par_mfg = NULL;
1318 ret->par_mdl = NULL;
1319 ret->par_des = NULL;
1320 ret->par_cmd = NULL;
1321 ret->usb_ieee = NULL;
1322 ret->usb_mfg = NULL;
1323 ret->usb_mdl = NULL;
1324 ret->usb_des = NULL;
1325 ret->usb_cmd = NULL;
1326 ret->snmp_ieee = NULL;
1327 ret->snmp_mfg = NULL;
1328 ret->snmp_mdl = NULL;
1329 ret->snmp_des = NULL;
1330 ret->snmp_cmd = NULL;
1331 ret->recdriver = NULL;
1332 ret->num_drivers = 0;
1333 ret->drivers = NULL;
1334
1335 /* Get printer ID */
1336 id = xmlGetProp(node, (const xmlChar *) "id");
1337 if (id == NULL) {
1338 fprintf(stderr, "No printer ID found\n");
1339 return;
1340 }
1341 ret->id = perlquote(id + 8);
1342 if (debug) fprintf(stderr, " Printer ID: %s\n", ret->id);
1343
1344 /* Go through subnodes */
1345 cur1 = node->xmlChildrenNode;
1346 while (cur1 != NULL) {
1347 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "make"))) {
1348 ret->make =
1349 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1350 if (debug) fprintf(stderr, " Printer Manufacturer: %s\n", ret->make);
1351 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "model"))) {
1352 ret->model =
1353 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1354 if (debug) fprintf(stderr, " Printer Model: %s\n", ret->model);
1355 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driver"))) {
1356 ret->recdriver =
1357 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1358 if (debug) fprintf(stderr, " Recommended driver: %s\n",
1359 ret->recdriver);
1360 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "drivers"))) {
1361 cur2 = cur1->xmlChildrenNode;
1362 while (cur2 != NULL) {
1363 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driver"))) {
1364 ret->num_drivers ++;
1365 ret->drivers =
1366 (printerDrvEntryPtr *)
1367 realloc((printerDrvEntryPtr *)ret->drivers,
1368 sizeof(printerDrvEntryPtr) *
1369 ret->num_drivers);
1370 dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry));
1371 if (dentry == NULL) {
1372 fprintf(stderr,"Out of memory!\n");
1373 xmlFreeDoc(doc);
1374 exit(1);
1375 }
1376 ret->drivers[ret->num_drivers-1] = dentry;
1377 memset(dentry, 0, sizeof(printerDrvEntry));
1378 dentry->name = NULL;
1379 dentry->comment = NULL;
1380 dentry->ppd = NULL;
1381 dentry->excmaxresx = NULL;
1382 dentry->excmaxresy = NULL;
1383 dentry->exccolor = NULL;
1384 dentry->exctext = NULL;
1385 dentry->exclineart = NULL;
1386 dentry->excgraphics = NULL;
1387 dentry->excphoto = NULL;
1388 dentry->excload = NULL;
1389 dentry->excspeed = NULL;
1390 if (debug) fprintf(stderr, " Printer supported by drivers:\n");
1391 cur3 = cur2->xmlChildrenNode;
1392 while (cur3 != NULL) {
1393 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "id"))) {
1394 dname =
1395 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
1396 dentry->name = perlquote(dname);
1397 if (debug) fprintf(stderr, " Name: %s\n",
1398 dentry->name);
1399 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppd"))) {
1400 dppd =
1401 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
1402 dentry->ppd = perlquote(dppd);
1403 if (debug) fprintf(stderr, " Ready-made PPD: %s\n",
1404 dentry->ppd);
1405 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) {
1406 cur4 = cur3->xmlChildrenNode;
1407 while (cur4 != NULL) {
1408 if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) {
1409 dentry->excmaxresx =
1410 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1411 if (debug)
1412 fprintf(stderr, " Maximum X resolution: %s\n",
1413 dentry->excmaxresx);
1414 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) {
1415 dentry->excmaxresy =
1416 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1417 if (debug)
1418 fprintf(stderr, " Maximum Y resolution: %s\n",
1419 dentry->excmaxresy);
1420 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) {
1421 dentry->exccolor = (xmlChar *)"0";
1422 if (debug)
1423 fprintf(stderr, " Color: %s\n",
1424 dentry->exccolor);
1425 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) {
1426 dentry->exccolor = (xmlChar *)"1";
1427 if (debug)
1428 fprintf(stderr, " Color: %s\n",
1429 dentry->exccolor);
1430 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) {
1431 dentry->exctext =
1432 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1433 if (debug)
1434 fprintf(stderr, " Support level for text: %s\n",
1435 dentry->exctext);
1436 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) {
1437 dentry->exclineart =
1438 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1439 if (debug)
1440 fprintf(stderr, " Support level for line art: %s\n",
1441 dentry->exclineart);
1442 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) {
1443 dentry->excgraphics =
1444 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1445 if (debug)
1446 fprintf(stderr, " Support level for graphics: %s\n",
1447 dentry->excgraphics);
1448 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) {
1449 dentry->excphoto =
1450 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1451 if (debug)
1452 fprintf(stderr, " Support level for photos: %s\n",
1453 dentry->excphoto);
1454 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) {
1455 dentry->excload =
1456 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1457 if (debug)
1458 fprintf(stderr, " Expected relative system load: %s\n",
1459 dentry->excload);
1460 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) {
1461 dentry->excspeed =
1462 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
1463 if (debug)
1464 fprintf(stderr, " Expected relative driver speed: %s\n",
1465 dentry->excspeed);
1466 }
1467 cur4 = cur4->next;
1468 }
1469 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) {
1470 if (debug)
1471 fprintf(stderr, " Comments:\n");
1472 getLocalizedText(doc, cur3, &(dentry->comment), language, debug);
1473 }
1474 cur3 = cur3->next;
1475 }
1476 }
1477 cur2 = cur2->next;
1478 }
1479 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "ppdentry"))) {
1480 ret->printerppdentry =
1481 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1482 if (debug) fprintf(stderr, " Extra lines for PPD file:\n%s\n",
1483 ret->printerppdentry);
1484 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "pcmodel"))) {
1485 ret->pcmodel =
1486 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1487 if (debug) fprintf(stderr,
1488 " Model part for PC filename in PPD: %s\n",
1489 ret->pcmodel);
1490 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "lang"))) {
1491 cur2 = cur1->xmlChildrenNode;
1492 while (cur2 != NULL) {
1493 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) {
1494 cur3 = cur2->xmlChildrenNode;
1495 while (cur3 != NULL) {
1496 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppd"))) {
1497 ret->ppdurl =
1498 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1499 1));
1500 if (debug) fprintf(stderr,
1501 " URL for the PPD for this printer: %s\n",
1502 ret->ppdurl);
1503 }
1504 cur3 = cur3->next;
1505 }
1506 }
1507 cur2 = cur2->next;
1508 }
1509 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "mechanism"))) {
1510 cur2 = cur1->xmlChildrenNode;
1511 while (cur2 != NULL) {
1512 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) {
1513 ret->color = (xmlChar *)"1";
1514 if (debug) fprintf(stderr, " Color printer\n");
1515 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "margins"))) {
1516 parseMargins(doc, cur2, &(ret->printermargins), language, debug);
1517 }
1518 cur2 = cur2->next;
1519 }
1520 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "lang"))) {
1521 cur2 = cur1->xmlChildrenNode;
1522 while (cur2 != NULL) {
1523 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "pjl"))) {
1524 ret->pjl = (xmlChar *)"''";
1525 if (debug) fprintf(stderr, " Printer supports PJL\n");
1526 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) {
1527 cur3 = cur2->xmlChildrenNode;
1528 while (cur3 != NULL) {
1529 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "charset"))) {
1530 charset =
1531 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
1532 if ((!xmlStrcmp(charset, (const xmlChar *) "us-ascii")) ||
1533 (!xmlStrcmp(charset, (const xmlChar *) "iso-8859-1")) ||
1534 (!xmlStrcmp(charset, (const xmlChar *) "iso-8859-15"))) {
1535 ret->ascii = (xmlChar *)"1";
1536 if (debug) fprintf(stderr, " Printer prints plain text\n");
1537 }
1538 }
1539 cur3 = cur3->next;
1540 }
1541 }
1542 cur2 = cur2->next;
1543 }
1544 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "autodetect"))) {
1545 cur2 = cur1->xmlChildrenNode;
1546 while (cur2 != NULL) {
1547 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "general"))) {
1548 cur3 = cur2->xmlChildrenNode;
1549 if (debug) fprintf(stderr, " Printer auto-detection info (general):\n");
1550 while (cur3 != NULL) {
1551 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1552 ret->general_ieee =
1553 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1554 1));
1555 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1556 ret->general_ieee);
1557
1558 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1559 ret->general_mfg =
1560 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1561 1));
1562 if (debug) fprintf(stderr, " MFG: %s\n", ret->general_mfg);
1563
1564 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1565 ret->general_mdl =
1566 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1567 1));
1568 if (debug) fprintf(stderr, " MDL: %s\n", ret->general_mdl);
1569 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1570 ret->general_des =
1571 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1572 1));
1573 if (debug) fprintf(stderr, " DES: %s\n", ret->general_des);
1574 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1575 ret->general_cmd =
1576 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1577 1));
1578 if (debug) fprintf(stderr, " CMD: %s\n", ret->general_cmd);
1579 }
1580 cur3 = cur3->next;
1581 }
1582 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "parallel"))) {
1583 cur3 = cur2->xmlChildrenNode;
1584 if (debug) fprintf(stderr, " Printer auto-detection info (parallel port):\n");
1585 while (cur3 != NULL) {
1586 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1587 ret->par_ieee =
1588 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1589 1));
1590 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1591 ret->par_ieee);
1592
1593 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1594 ret->par_mfg =
1595 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1596 1));
1597 if (debug) fprintf(stderr, " MFG: %s\n", ret->par_mfg);
1598
1599 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1600 ret->par_mdl =
1601 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1602 1));
1603 if (debug) fprintf(stderr, " MDL: %s\n", ret->par_mdl);
1604 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1605 ret->par_des =
1606 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1607 1));
1608 if (debug) fprintf(stderr, " DES: %s\n", ret->par_des);
1609 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1610 ret->par_cmd =
1611 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1612 1));
1613 if (debug) fprintf(stderr, " CMD: %s\n", ret->par_cmd);
1614 }
1615 cur3 = cur3->next;
1616 }
1617 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "usb"))) {
1618 cur3 = cur2->xmlChildrenNode;
1619 if (debug) fprintf(stderr, " Printer auto-detection info (USB):\n");
1620 while (cur3 != NULL) {
1621 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1622 ret->usb_ieee =
1623 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1624 1));
1625 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1626 ret->usb_ieee);
1627
1628 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1629 ret->usb_mfg =
1630 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1631 1));
1632 if (debug) fprintf(stderr, " MFG: %s\n", ret->usb_mfg);
1633
1634 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1635 ret->usb_mdl =
1636 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1637 1));
1638 if (debug) fprintf(stderr, " MDL: %s\n", ret->usb_mdl);
1639 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1640 ret->usb_des =
1641 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1642 1));
1643 if (debug) fprintf(stderr, " DES: %s\n", ret->usb_des);
1644 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1645 ret->usb_cmd =
1646 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1647 1));
1648 if (debug) fprintf(stderr, " CMD: %s\n", ret->usb_cmd);
1649 }
1650 cur3 = cur3->next;
1651 }
1652 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "snmp"))) {
1653 cur3 = cur2->xmlChildrenNode;
1654 if (debug) fprintf(stderr, " Printer auto-detection info (SNMP):\n");
1655 while (cur3 != NULL) {
1656 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
1657 ret->snmp_ieee =
1658 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1659 1));
1660 if (debug) fprintf(stderr, " IEEE1284: %s\n",
1661 ret->snmp_ieee);
1662
1663 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
1664 ret->snmp_mfg =
1665 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1666 1));
1667 if (debug) fprintf(stderr, " MFG: %s\n", ret->snmp_mfg);
1668
1669 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
1670 ret->snmp_mdl =
1671 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1672 1));
1673 if (debug) fprintf(stderr, " MDL: %s\n", ret->snmp_mdl);
1674 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
1675 ret->snmp_des =
1676 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1677 1));
1678 if (debug) fprintf(stderr, " DES: %s\n", ret->snmp_des);
1679 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
1680 ret->snmp_cmd =
1681 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
1682 1));
1683 if (debug) fprintf(stderr, " CMD: %s\n", ret->snmp_cmd);
1684 }
1685 cur3 = cur3->next;
1686 }
1687 }
1688 cur2 = cur2->next;
1689 }
1690 }
1691 cur1 = cur1->next;
1692 }
1693 }
1694
1695 static void
parseComboDriver(xmlDocPtr doc,xmlNodePtr node,comboDataPtr ret,xmlChar const language[],int debug)1696 parseComboDriver(xmlDocPtr doc, /* I - The whole combo data tree */
1697 xmlNodePtr node, /* I - Node of XML tree to work on */
1698 comboDataPtr ret, /* O - C data structure of Foomatic
1699 combo */
1700 xmlChar const language [], /* I - User language */
1701 int debug) { /* I - Debug mode flag */
1702 xmlNodePtr cur1; /* XML node currently worked on */
1703 xmlNodePtr cur2; /* Another XML node pointer */
1704 xmlNodePtr cur3; /* Another XML node pointer */
1705 xmlNodePtr cur4; /* Another XML node pointer */
1706 xmlChar *id; /* Full driver ID, with "driver/" */
1707 xmlChar *level, *version, *scope, *fingerprint;
1708 xmlChar *url;
1709
1710 /* Initialization of entries */
1711 ret->driver = NULL;
1712 ret->driver_group = NULL;
1713 ret->driver_type = NULL;
1714 ret->driver_comment = NULL;
1715 ret->url = NULL;
1716 ret->supplier = NULL;
1717 ret->driver_obsolete = NULL;
1718 ret->manufacturersupplied = NULL;
1719 ret->license = NULL;
1720 ret->licensetext = NULL;
1721 ret->origlicensetext = NULL;
1722 ret->licenselink = NULL;
1723 ret->origlicenselink = NULL;
1724 ret->free = NULL;
1725 ret->patents = NULL;
1726 ret->num_supportcontacts = 0;
1727 ret->supportcontacts = NULL;
1728 ret->supportcontacturls = NULL;
1729 ret->supportcontactlevels = NULL;
1730 ret->shortdescription = NULL;
1731 ret->locales = NULL;
1732 ret->num_packages = 0;
1733 ret->packageurls = NULL;
1734 ret->packagescopes = NULL;
1735 ret->packagefingerprints = NULL;
1736 ret->drvmaxresx = NULL;
1737 ret->drvmaxresy = NULL;
1738 ret->drvcolor = NULL;
1739 ret->text = NULL;
1740 ret->lineart = NULL;
1741 ret->graphics = NULL;
1742 ret->photo = NULL;
1743 ret->load = NULL;
1744 ret->speed = NULL;
1745 ret->excmaxresx = NULL;
1746 ret->excmaxresy = NULL;
1747 ret->exccolor = NULL;
1748 ret->exctext = NULL;
1749 ret->exclineart = NULL;
1750 ret->excgraphics = NULL;
1751 ret->excphoto = NULL;
1752 ret->excload = NULL;
1753 ret->excspeed = NULL;
1754 ret->num_requires = 0;
1755 ret->requires = NULL;
1756 ret->requiresversion = NULL;
1757 ret->cmd = NULL;
1758 ret->cmd_pdf = NULL;
1759 ret->nopjl = (xmlChar *)"0";
1760 ret->nopageaccounting = (xmlChar *)"0";
1761 ret->driverppdentry = NULL;
1762 ret->comboppdentry = NULL;
1763 ret->drivermargins = NULL;
1764 ret->combomargins = NULL;
1765
1766 /* Get driver ID */
1767 id = xmlGetProp(node, (const xmlChar *) "id");
1768 if (id == NULL) {
1769 fprintf(stderr, "No driver ID found\n");
1770 return;
1771 }
1772 ret->driver = perlquote(id + 7);
1773 if (debug) fprintf(stderr, " Driver ID: %s\n", ret->driver);
1774
1775 /* Go through subnodes */
1776 cur1 = node->xmlChildrenNode;
1777 while (cur1 != NULL) {
1778 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driver"))) {
1779 ret->driver =
1780 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1781 if (debug) fprintf(stderr, " Driver name: %s\n", ret->driver);
1782 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "group"))) {
1783 ret->driver_group =
1784 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1785 if (debug) fprintf(stderr, " Driver group (for localization): %s\n",
1786 ret->driver_group);
1787 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "pcdriver"))) {
1788 ret->pcdriver =
1789 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1790 if (debug) fprintf(stderr, " Driver part of PC file name in PPD: %s\n",
1791 ret->pcdriver);
1792 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "url"))) {
1793 ret->url =
1794 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1795 if (debug) fprintf(stderr, " Driver URL: %s\n", ret->url);
1796 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "obsolete"))) {
1797 ret->driver_obsolete = xmlGetProp(cur1, (const xmlChar *) "replace");
1798 if (ret->driver_obsolete == NULL) {
1799 if (debug) fprintf(stderr, " No replacement driver found!\n");
1800 ret->driver_obsolete = (xmlChar *)"1";
1801 }
1802 if (debug) fprintf(stderr, " Driver is obsolete: %s\n",
1803 ret->driver_obsolete);
1804 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supplier"))) {
1805 if (debug)
1806 fprintf(stderr, " Driver supplier:\n");
1807 getLocalizedText(doc, cur1, &(ret->supplier), language, debug);
1808 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "manufacturersupplied"))) {
1809 ret->manufacturersupplied =
1810 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1811 if ((ret->manufacturersupplied == NULL) ||
1812 (ret->manufacturersupplied[0] == '\0'))
1813 ret->manufacturersupplied = (xmlChar *)"1";
1814 if (debug) fprintf(stderr, " Driver supplied by manufacturer: %s\n",
1815 ret->manufacturersupplied);
1816 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "thirdpartysupplied"))) {
1817 ret->manufacturersupplied = (xmlChar *)"0";
1818 if (debug) fprintf(stderr, " Driver supplied by a third party\n");
1819 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "license"))) {
1820 if (debug)
1821 fprintf(stderr, " Driver license:\n");
1822 getLocalizedText(doc, cur1, &(ret->license), language, debug);
1823 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "licensetext"))) {
1824 if (debug)
1825 fprintf(stderr, " Driver license text:\n");
1826 getLocalizedLicenseText(doc, cur1,
1827 &(ret->licensetext), &(ret->origlicensetext),
1828 &(ret->licenselink), &(ret->origlicenselink),
1829 language, debug);
1830 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "freesoftware"))) {
1831 ret->free = (xmlChar *)"1";
1832 if (debug) fprintf(stderr, " Driver is free software\n");
1833 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nonfreesoftware"))) {
1834 ret->free = (xmlChar *)"0";
1835 if (debug) fprintf(stderr, " Driver is not free software\n");
1836 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "patents"))) {
1837 ret->patents = (xmlChar *)"1";
1838 if (debug) fprintf(stderr, " There are patents applying to this driver's code\n");
1839 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nopatents"))) {
1840 ret->patents = (xmlChar *)"0";
1841 if (debug) fprintf(stderr, " There are no patents applying to this driver's code\n");
1842 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supportcontacts"))) {
1843 cur2 = cur1->xmlChildrenNode;
1844 if (debug) fprintf(stderr, " Driver support contacts:\n");
1845 while (cur2 != NULL) {
1846 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "supportcontact"))) {
1847 ret->num_supportcontacts ++;
1848 ret->supportcontacts =
1849 (xmlChar const **)
1850 realloc((xmlChar **)ret->supportcontacts,
1851 sizeof(xmlChar *) *
1852 ret->num_supportcontacts);
1853 ret->supportcontacturls =
1854 (xmlChar **)
1855 realloc((xmlChar **)ret->supportcontacturls,
1856 sizeof(xmlChar *) *
1857 ret->num_supportcontacts);
1858 ret->supportcontactlevels =
1859 (xmlChar **)
1860 realloc((xmlChar **)ret->supportcontactlevels,
1861 sizeof(xmlChar *) *
1862 ret->num_supportcontacts);
1863 level = xmlGetProp(cur2, (const xmlChar *) "level");
1864 if (level == NULL) {
1865 level = (xmlChar *)"Unknown";
1866 }
1867 url = xmlGetProp(cur2, (const xmlChar *) "url");
1868 ret->supportcontactlevels[ret->num_supportcontacts - 1] = level;
1869 ret->supportcontacturls[ret->num_supportcontacts - 1] = url;
1870 getLocalizedText
1871 (doc, cur2,
1872 &(ret->supportcontacts[ret->num_supportcontacts - 1]),
1873 language, debug);
1874 if (debug)
1875 fprintf(stderr, " %s (%s):\n %s\n",
1876 ret->supportcontacts[ret->num_supportcontacts - 1],
1877 ret->supportcontactlevels[ret->num_supportcontacts - 1],
1878 ret->supportcontacturls[ret->num_supportcontacts - 1]);
1879 }
1880 cur2 = cur2->next;
1881 }
1882 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "shortdescription"))) {
1883 if (debug)
1884 fprintf(stderr, " Driver short description:\n");
1885 getLocalizedText(doc, cur1, &(ret->shortdescription), language, debug);
1886 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "locales"))) {
1887 ret->locales =
1888 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
1889 if (debug) fprintf(stderr, " Driver list of locales: %s\n", ret->locales);
1890 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "packages"))) {
1891 cur2 = cur1->xmlChildrenNode;
1892 if (debug) fprintf(stderr, " Driver downloadable packages:\n");
1893 while (cur2 != NULL) {
1894 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "package"))) {
1895 ret->num_packages ++;
1896 ret->packageurls =
1897 (xmlChar **)
1898 realloc((xmlChar **)ret->packageurls,
1899 sizeof(xmlChar *) *
1900 ret->num_packages);
1901 ret->packagescopes =
1902 (xmlChar **)
1903 realloc((xmlChar **)ret->packagescopes,
1904 sizeof(xmlChar *) *
1905 ret->num_packages);
1906 scope = xmlGetProp(cur2, (const xmlChar *) "scope");
1907 ret->packagefingerprints =
1908 (xmlChar **)
1909 realloc((xmlChar **)ret->packagefingerprints,
1910 sizeof(xmlChar *) *
1911 ret->num_packages);
1912 fingerprint = xmlGetProp(cur2, (const xmlChar *) "fingerprint");
1913 ret->packageurls[ret->num_packages - 1] =
1914 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1915 ret->packagescopes[ret->num_packages - 1] = perlquote(scope);
1916 ret->packagefingerprints[ret->num_packages - 1] = perlquote(fingerprint);
1917 if (debug)
1918 fprintf(stderr, " %s (%s), key fingerprint on %s\n",
1919 ret->packageurls[ret->num_packages - 1],
1920 ret->packagescopes[ret->num_packages - 1],
1921 ret->packagefingerprints[ret->num_packages - 1]);
1922 }
1923 cur2 = cur2->next;
1924 }
1925 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) {
1926 cur2 = cur1->xmlChildrenNode;
1927 while (cur2 != NULL) {
1928 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresx"))) {
1929 ret->drvmaxresx =
1930 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1931 if (debug)
1932 fprintf(stderr, " Driver functionality: Max X resolution: %s\n",
1933 ret->drvmaxresx);
1934 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresy"))) {
1935 ret->drvmaxresy =
1936 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1937 if (debug)
1938 fprintf(stderr, " Driver functionality: Max Y resolution: %s\n",
1939 ret->drvmaxresy);
1940 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) {
1941 ret->drvcolor = (xmlChar *)"1";
1942 if (debug) fprintf(stderr, " Driver functionality: Color\n");
1943 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) {
1944 ret->drvcolor = (xmlChar *)"0";
1945 if (debug) fprintf(stderr, " Driver functionality: Monochrome\n");
1946 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) {
1947 ret->text =
1948 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1949 if (debug)
1950 fprintf(stderr, " Driver functionality: Text support rating: %s\n",
1951 ret->text);
1952 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "lineart"))) {
1953 ret->lineart =
1954 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1955 if (debug)
1956 fprintf(stderr, " Driver functionality: Line art support rating: %s\n",
1957 ret->lineart);
1958 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "graphics"))) {
1959 ret->graphics =
1960 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1961 if (debug)
1962 fprintf(stderr, " Driver functionality: Graphics support rating: %s\n",
1963 ret->graphics);
1964 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "photo"))) {
1965 ret->photo =
1966 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1967 if (debug)
1968 fprintf(stderr, " Driver functionality: Photo support rating: %s\n",
1969 ret->photo);
1970 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "load"))) {
1971 ret->load =
1972 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1973 if (debug)
1974 fprintf(stderr, " Driver functionality: System load rating: %s\n",
1975 ret->load);
1976 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "speed"))) {
1977 ret->speed =
1978 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
1979 if (debug)
1980 fprintf(stderr, " Driver functionality: Speed rating: %s\n",
1981 ret->speed);
1982 }
1983 cur2 = cur2->next;
1984 }
1985 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "execution"))) {
1986 cur2 = cur1->xmlChildrenNode;
1987 while (cur2 != NULL) {
1988 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "requires"))) {
1989 ret->num_requires ++;
1990 ret->requires =
1991 (xmlChar **)
1992 realloc((xmlChar **)ret->requires,
1993 sizeof(xmlChar *) *
1994 ret->num_requires);
1995 ret->requiresversion =
1996 (xmlChar **)
1997 realloc((xmlChar **)ret->requiresversion,
1998 sizeof(xmlChar *) *
1999 ret->num_requires);
2000 version = xmlGetProp(cur2, (const xmlChar *) "version");
2001 ret->requires[ret->num_requires - 1] =
2002 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2003 ret->requiresversion[ret->num_requires - 1] = perlquote(version);
2004 if (debug) /* an explicit brace for GCC thought police */ {
2005 if (!version)
2006 fprintf(stderr, " Driver requires driver: %s\n",
2007 ret->requires[ret->num_requires - 1]);
2008 else
2009 fprintf(stderr, " Driver requires driver: %s (%s)\n",
2010 ret->requires[ret->num_requires - 1],
2011 ret->requiresversion[ret->num_requires - 1]); }
2012 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "cups"))) {
2013 ret->driver_type = (xmlChar *)"C";
2014 if (debug) fprintf(stderr, " Driver type: CUPS Raster\n");
2015 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ijs"))) {
2016 ret->driver_type = (xmlChar *)"I";
2017 if (debug) fprintf(stderr, " Driver type: IJS\n");
2018 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "opvp"))) {
2019 ret->driver_type = (xmlChar *)"V";
2020 if (debug) fprintf(stderr, " Driver type: OpenPrinting Vector\n");
2021 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) {
2022 ret->driver_type = (xmlChar *)"G";
2023 if (debug) fprintf(stderr, " Driver type: Ghostscript built-in\n");
2024 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "filter"))) {
2025 ret->driver_type = (xmlChar *)"F";
2026 if (debug) fprintf(stderr, " Driver type: Filter\n");
2027 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "uniprint"))) {
2028 ret->driver_type = (xmlChar *)"U";
2029 if (debug) fprintf(stderr, " Driver type: Ghostscript Uniprint\n");
2030 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) {
2031 ret->driver_type = (xmlChar *)"P";
2032 if (debug) fprintf(stderr, " Driver type: PostScript\n");
2033 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "nopjl"))) {
2034 ret->nopjl = (xmlChar *)"1";
2035 if (debug) fprintf(stderr, " Driver suppresses PJL options\n");
2036 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "nopageaccounting"))) {
2037 ret->nopageaccounting = (xmlChar *)"1";
2038 if (debug) fprintf(stderr, " Driver suppresses CUPS page accounting\n");
2039 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "prototype"))) {
2040 ret->cmd =
2041 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2042 if (debug) fprintf(stderr, " Driver command line:\n\n %s\n\n",
2043 ret->cmd);
2044 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "prototype_pdf"))) {
2045 ret->cmd_pdf =
2046 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2047 if (debug) fprintf(stderr, " Driver PDF command line:\n\n %s\n\n",
2048 ret->cmd_pdf);
2049 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ppdentry"))) {
2050 ret->driverppdentry =
2051 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2052 if (debug) fprintf(stderr, " Extra lines for PPD file:\n%s\n",
2053 ret->driverppdentry);
2054 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "margins"))) {
2055 parseMargins(doc, cur2, &(ret->drivermargins), language, debug);
2056 }
2057 cur2 = cur2->next;
2058 }
2059 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) {
2060 if (debug)
2061 fprintf(stderr, " Driver Comment:\n");
2062 getLocalizedText(doc, cur1, &(ret->driver_comment), language, debug);
2063 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "printers"))) {
2064 cur2 = cur1->xmlChildrenNode;
2065 while (cur2 != NULL) {
2066 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "printer"))) {
2067 cur3 = cur2->xmlChildrenNode;
2068 while (cur3 != NULL) {
2069 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppdentry"))) {
2070 ret->comboppdentry =
2071 perlquote(xmlNodeListGetString(doc,
2072 cur3->xmlChildrenNode, 1));
2073 if (debug)
2074 fprintf(stderr, " Extra lines for PPD file:\n%s\n",
2075 ret->comboppdentry);
2076 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "margins"))) {
2077 parseMargins(doc, cur3, &(ret->combomargins),
2078 language, debug);
2079 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) {
2080 cur4 = cur3->xmlChildrenNode;
2081 while (cur4 != NULL) {
2082 if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) {
2083 ret->excmaxresx =
2084 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2085 if (debug)
2086 fprintf(stderr, " Combo exception: Maximum X resolution: %s\n",
2087 ret->excmaxresx);
2088 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) {
2089 ret->excmaxresy =
2090 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2091 if (debug)
2092 fprintf(stderr, " Combo exception: Maximum Y resolution: %s\n",
2093 ret->excmaxresy);
2094 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) {
2095 ret->exccolor = (xmlChar *)"0";
2096 if (debug)
2097 fprintf(stderr, " Combo exception: Color: %s\n",
2098 ret->exccolor);
2099 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) {
2100 ret->exccolor = (xmlChar *)"1";
2101 if (debug)
2102 fprintf(stderr, " Combo exception: Color: %s\n",
2103 ret->exccolor);
2104 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) {
2105 ret->exctext =
2106 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2107 if (debug)
2108 fprintf(stderr, " Combo exception: Support level for text: %s\n",
2109 ret->exctext);
2110 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) {
2111 ret->exclineart =
2112 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2113 if (debug)
2114 fprintf(stderr, " Combo exception: Support level for line art: %s\n",
2115 ret->exclineart);
2116 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) {
2117 ret->excgraphics =
2118 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2119 if (debug)
2120 fprintf(stderr, " Combo exception: Support level for graphics: %s\n",
2121 ret->excgraphics);
2122 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) {
2123 ret->excphoto =
2124 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2125 if (debug)
2126 fprintf(stderr, " Combo exception: Support level for photos: %s\n",
2127 ret->excphoto);
2128 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) {
2129 ret->excload =
2130 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2131 if (debug)
2132 fprintf(stderr, " Combo exception: Expected relative system load: %s\n",
2133 ret->excload);
2134 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) {
2135 ret->excspeed =
2136 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
2137 if (debug)
2138 fprintf(stderr, " Combo exception: Expected relative driver speed: %s\n",
2139 ret->excspeed);
2140 }
2141 cur4 = cur4->next;
2142 }
2143 }
2144 cur3 = cur3->next;
2145 }
2146 }
2147 cur2 = cur2->next;
2148 }
2149 }
2150 cur1 = cur1->next;
2151 }
2152 }
2153
2154 static void
parseChoices(xmlDocPtr doc,xmlNodePtr node,argPtr option,xmlChar const language[],int debug)2155 parseChoices(xmlDocPtr doc, /* I - The whole combo data tree */
2156 xmlNodePtr node, /* I - Node of XML tree to work on */
2157 argPtr option, /* O - C data structure of Foomatic option */
2158 xmlChar const language [], /* I - User language */
2159 int debug) { /* I - Debug mode flag */
2160 xmlNodePtr cur1; /* XML node currently worked on */
2161 xmlNodePtr cur2; /* Another XML node pointer */
2162 xmlNodePtr cur3; /* Another XML node pointer */
2163 xmlChar *id; /* Full choice ID, with "ev/" */
2164 choicePtr enum_val; /* Data structure for the choice currently
2165 parsed */
2166
2167 /* Initialization of entries */
2168 option->num_choices = 0;
2169 option->choices = NULL;
2170
2171 /* Go through the choice nodes */
2172 cur1 = node->xmlChildrenNode;
2173 while (cur1 != NULL) {
2174 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "enum_val"))) {
2175
2176 /* Allocate memory for the option */
2177 option->num_choices ++;
2178 option->choices =
2179 (choicePtr *)realloc((choicePtr *)(option->choices),
2180 sizeof(choicePtr) * option->num_choices);
2181 enum_val = (choicePtr) malloc(sizeof(arg));
2182 if (enum_val == NULL) {
2183 fprintf(stderr,"Out of memory!\n");
2184 xmlFreeDoc(doc);
2185 exit(1);
2186 }
2187 option->choices[option->num_choices-1] = enum_val;
2188 memset(enum_val, 0, sizeof(choice));
2189
2190 /* Initialization of entries */
2191 enum_val->value = NULL;
2192 enum_val->comment = NULL;
2193 enum_val->idx = NULL;
2194 enum_val->driverval = NULL;
2195
2196 /* Get option ID */
2197 id = xmlGetProp(cur1, (const xmlChar *) "id");
2198 if (id == NULL) {
2199 fprintf(stderr, "No choice ID found\n");
2200 return;
2201 }
2202 enum_val->idx = perlquote(id);
2203 if (debug) fprintf(stderr, " Choice ID: %s\n", enum_val->idx);
2204
2205 /* Go through subnodes */
2206 cur2 = cur1->xmlChildrenNode;
2207 while (cur2 != NULL) {
2208 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_shortname"))) {
2209 if (debug)
2210 fprintf(stderr, " Choice short name (do not translate):\n");
2211 getLocalizedText (doc, cur2, &(enum_val->value), sc_locale_C, debug);
2212 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_longname"))) {
2213 if (debug)
2214 fprintf(stderr, " Choice long name:\n");
2215 getLocalizedText(doc, cur2, &(enum_val->comment), language, debug);
2216 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ev_driverval"))) {
2217 enum_val->driverval =
2218 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2219 if (debug) fprintf(stderr, " String to insert at %%s: %s\n",
2220 enum_val->driverval);
2221 }
2222 cur2 = cur2->next;
2223 }
2224 }
2225 cur1 = cur1->next;
2226 }
2227 }
2228
2229 static void
parseOptions(xmlDocPtr doc,xmlNodePtr node,comboDataPtr ret,xmlChar const language[],int debug)2230 parseOptions(xmlDocPtr doc, /* I - The whole combo data tree */
2231 xmlNodePtr node, /* I - Node of XML tree to work on */
2232 comboDataPtr ret, /* O - C data structure of Foomatic combo */
2233 xmlChar const language [], /* I - User language */
2234 int debug) { /* I - Debug mode flag */
2235 xmlNodePtr cur1; /* XML node currently worked on */
2236 xmlNodePtr cur2; /* Another XML node pointer */
2237 xmlNodePtr cur3; /* Another XML node pointer */
2238 xmlChar *id, /* Full option ID, with "opt/" */
2239 *option_type; /* Option type */
2240 argPtr option;/* Data structure for the option currently parsed */
2241
2242 /* Initialization of entries */
2243 ret->num_args = 0;
2244 ret->args = NULL;
2245 ret->maxspot = (xmlChar *)"A";
2246
2247 /* Go through the option nodes */
2248 cur1 = node->xmlChildrenNode;
2249 while (cur1 != NULL) {
2250 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "option"))) {
2251
2252 /* Allocate memory for the option */
2253 ret->num_args ++;
2254 ret->args =
2255 (argPtr *)realloc((argPtr *)(ret->args),
2256 sizeof(argPtr) * ret->num_args);
2257 option = (argPtr) malloc(sizeof(arg));
2258 if (option == NULL) {
2259 fprintf(stderr,"Out of memory!\n");
2260 xmlFreeDoc(doc);
2261 exit(1);
2262 }
2263 ret->args[ret->num_args-1] = option;
2264 memset(option, 0, sizeof(arg));
2265
2266 /* Initialization of entries */
2267 option->name = NULL;
2268 option->name_false = NULL;
2269 option->comment = NULL;
2270 option->idx = NULL;
2271 option->option_type = NULL;
2272 option->style = NULL;
2273 option->substyle= NULL;
2274 option->spot = NULL;
2275 option->order = NULL;
2276 option->section = NULL;
2277 option->grouppath = NULL;
2278 option->proto = NULL;
2279 option->required = NULL;
2280 option->min_value = NULL;
2281 option->max_value = NULL;
2282 option->max_length = NULL;
2283 option->allowed_chars = NULL;
2284 option->allowed_regexp = NULL;
2285 option->default_value = NULL;
2286 option->num_choices = 0;
2287 option->choices = NULL;
2288
2289 /* Get option ID */
2290 id = xmlGetProp(cur1, (const xmlChar *) "id");
2291 if (id == NULL) {
2292 fprintf(stderr, "No option ID found\n");
2293 return;
2294 }
2295 option->idx = perlquote(id);
2296 if (debug) fprintf(stderr, " Option ID: %s\n", option->idx);
2297
2298 /* Get option type */
2299 option_type = xmlGetProp(cur1, (const xmlChar *) "type");
2300 if (option_type == NULL) {
2301 fprintf(stderr, "No option type found\n");
2302 return;
2303 }
2304 option->option_type = perlquote(option_type);
2305 if (debug) fprintf(stderr, " Option type: %s\n",
2306 option->option_type);
2307
2308 /* Go through subnodes */
2309 cur2 = cur1->xmlChildrenNode;
2310 while (cur2 != NULL) {
2311 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_shortname"))) {
2312 if (debug)
2313 fprintf(stderr, " Option short name (do not translate):\n");
2314 getLocalizedText(doc, cur2, &(option->name), sc_locale_C, debug);
2315 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_shortname_false"))) {
2316 if (debug)
2317 fprintf(stderr,
2318 " Option short name if false (do not translate):\n");
2319 getLocalizedText(doc, cur2, &(option->name_false), sc_locale_C, debug);
2320 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_longname"))) {
2321 if (debug)
2322 fprintf(stderr, " Option long name:\n");
2323 getLocalizedText(doc, cur2, &(option->comment), language, debug);
2324 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_execution"))) {
2325 cur3 = cur2->xmlChildrenNode;
2326 while (cur3 != NULL) {
2327 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_substitution"))) {
2328 option->style = (xmlChar *)"C";
2329 option->substyle = NULL;
2330 if (debug)
2331 fprintf(stderr,
2332 " Option style: Command line Substitution\n");
2333 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_postscript"))) {
2334 option->style = (xmlChar *)"G";
2335 option->substyle = NULL;
2336 if (debug)
2337 fprintf(stderr,
2338 " Option style: PostScript code\n");
2339 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_pjl"))) {
2340 option->style = (xmlChar *)"J";
2341 option->substyle = NULL;
2342 if (debug)
2343 fprintf(stderr,
2344 " Option style: PJL command\n");
2345 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_composite"))) {
2346 option->style = (xmlChar *)"X";
2347 option->substyle = NULL;
2348 if (debug)
2349 fprintf(stderr,
2350 " Option style: Composite option\n");
2351 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_forced_composite"))) {
2352 option->style = (xmlChar *)"X";
2353 option->substyle = (xmlChar *)"F";
2354 if (debug)
2355 fprintf(stderr,
2356 " Option style: Forced composite option\n");
2357 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_spot"))) {
2358 option->spot =
2359 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2360 1));
2361 if (debug) fprintf(stderr,
2362 " Command line insertion spot: %%%s\n",
2363 option->spot);
2364 if ((xmlStrcmp(option->spot, ret->maxspot) > 0)) {
2365 ret->maxspot = option->spot;
2366 }
2367 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_order"))) {
2368 option->order =
2369 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2370 1));
2371 if (debug) fprintf(stderr,
2372 " Command line insertion order: %s\n",
2373 option->order);
2374 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_section"))) {
2375 option->section =
2376 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2377 1));
2378 if (debug) fprintf(stderr,
2379 " Section in PostScript file: %s\n",
2380 option->section);
2381 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_group"))) {
2382 option->grouppath =
2383 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2384 1));
2385 if (debug) fprintf(stderr,
2386 " Option Group: %s\n",
2387 option->grouppath);
2388 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_proto"))) {
2389 option->proto =
2390 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2391 1));
2392 if (debug) fprintf(stderr,
2393 " Code to insert: %s\n",
2394 option->proto);
2395 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "arg_required"))) {
2396 option->required = (xmlChar *)"1";
2397 if (debug) fprintf(stderr,
2398 " This option is required\n");
2399 }
2400 cur3 = cur3->next;
2401 }
2402 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_min"))) {
2403 option->min_value =
2404 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2405 if (debug) fprintf(stderr,
2406 " Minimum value: %s\n",
2407 option->min_value);
2408 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_max"))) {
2409 option->max_value =
2410 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2411 if (debug) fprintf(stderr,
2412 " Maximum value: %s\n",
2413 option->max_value);
2414 } else if ((!xmlStrcmp(cur2->name,
2415 (const xmlChar *) "arg_maxlength"))) {
2416 option->max_length =
2417 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2418 if (debug) fprintf(stderr,
2419 " Maximum string length: %s\n",
2420 option->max_length);
2421 } else if ((!xmlStrcmp(cur2->name,
2422 (const xmlChar *) "arg_allowedchars"))) {
2423 option->allowed_chars =
2424 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2425 if (debug) fprintf(stderr,
2426 " Allowed characters in string: %s\n",
2427 option->allowed_chars);
2428 } else if ((!xmlStrcmp(cur2->name,
2429 (const xmlChar *) "arg_allowedregexp"))) {
2430 option->allowed_regexp =
2431 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2432 if (debug) fprintf(stderr,
2433 " String must match Perl regexp: %s\n",
2434 option->allowed_regexp);
2435 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "arg_defval"))) {
2436 option->default_value =
2437 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
2438 if (debug) fprintf(stderr,
2439 " Default: %s\n",
2440 option->default_value);
2441 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "enum_vals"))) {
2442 if (debug) fprintf(stderr, " --> Parsing choice data\n");
2443 parseChoices(doc, cur2, option, language, debug);
2444 }
2445 cur2 = cur2->next;
2446 }
2447 }
2448 cur1 = cur1->next;
2449 }
2450 if (debug) fprintf(stderr,
2451 " Last command line insertion spot: %%%s\n",
2452 ret->maxspot);
2453 }
2454
2455 /*
2456 * Functions to fill in the printer and driver data structures with the
2457 * data parsed from the XML input
2458 */
2459
2460 static void
parsePrinterEntry(xmlDocPtr doc,xmlNodePtr node,printerEntryPtr ret,xmlChar const language[],int debug)2461 parsePrinterEntry(xmlDocPtr doc, /* I - The whole printer data tree */
2462 xmlNodePtr node, /* I - Node of XML tree to work on */
2463 printerEntryPtr ret, /* O - C data structure of Foomatic
2464 printer entry */
2465 xmlChar const language [], /* I - User language */
2466 int debug) { /* I - Debug mode flag */
2467 xmlNodePtr cur1; /* XML node currently worked on */
2468 xmlNodePtr cur2; /* Another XML node pointer */
2469 xmlNodePtr cur3; /* Another XML node pointer */
2470 xmlNodePtr cur4; /* Another XML node pointer */
2471 xmlChar *id; /* Full printer ID, with "printer/" */
2472 xmlChar *dname; /* Name of a driver supporting this printer */
2473 xmlChar *dppd; /* Ready-made PPD supporting this printer */
2474 printerLanguagePtr lentry; /* An entry for a language used by this
2475 printer */
2476 printerDrvEntryPtr dentry; /* An entry for a driver supporting this
2477 printer */
2478
2479 /* Initialization of entries */
2480 ret->id = NULL;
2481 ret->make = NULL;
2482 ret->model = NULL;
2483 ret->printer_type = NULL;
2484 ret->color = (xmlChar *)"0";
2485 ret->maxxres = NULL;
2486 ret->maxyres = NULL;
2487 ret->printerppdentry = NULL;
2488 ret->printermargins = NULL;
2489 ret->refill = NULL;
2490 ret->ascii = NULL;
2491 ret->pjl = (xmlChar *)"0";
2492 ret->general_ieee = NULL;
2493 ret->general_mfg = NULL;
2494 ret->general_mdl = NULL;
2495 ret->general_des = NULL;
2496 ret->general_cmd = NULL;
2497 ret->par_ieee = NULL;
2498 ret->par_mfg = NULL;
2499 ret->par_mdl = NULL;
2500 ret->par_des = NULL;
2501 ret->par_cmd = NULL;
2502 ret->usb_ieee = NULL;
2503 ret->usb_mfg = NULL;
2504 ret->usb_mdl = NULL;
2505 ret->usb_des = NULL;
2506 ret->usb_cmd = NULL;
2507 ret->snmp_ieee = NULL;
2508 ret->snmp_mfg = NULL;
2509 ret->snmp_mdl = NULL;
2510 ret->snmp_des = NULL;
2511 ret->snmp_cmd = NULL;
2512 ret->functionality = (xmlChar *)"X";
2513 ret->driver = NULL;
2514 ret->unverified = (xmlChar *)"0";
2515 ret->noxmlentry = (xmlChar *)"0";
2516 ret->url = NULL;
2517 ret->contriburl = NULL;
2518 ret->comment = NULL;
2519 ret->ppdurl = NULL;
2520 ret->num_languages = 0;
2521 ret->languages = NULL;
2522 ret->num_drivers = 0;
2523 ret->drivers = NULL;
2524
2525 /* Get printer ID */
2526 id = xmlGetProp(node, (const xmlChar *) "id");
2527 if (id == NULL) {
2528 fprintf(stderr, "No printer ID found\n");
2529 return;
2530 }
2531 ret->id = perlquote(id + 8);
2532 if (debug) fprintf(stderr, " Printer ID: %s\n", ret->id);
2533
2534 /* Go through subnodes */
2535 cur1 = node->xmlChildrenNode;
2536 while (cur1 != NULL) {
2537 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "make"))) {
2538 ret->make =
2539 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2540 if (debug) fprintf(stderr, " Printer Manufacturer: %s\n", ret->make);
2541 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "model"))) {
2542 ret->model =
2543 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2544 if (debug) fprintf(stderr, " Printer Model: %s\n", ret->model);
2545 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "mechanism"))) {
2546 cur2 = cur1->xmlChildrenNode;
2547 while (cur2 != NULL) {
2548 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "inkjet"))) {
2549 ret->printer_type = (xmlChar *)"inkjet";
2550 if (debug) fprintf(stderr, " Inkjet printer\n");
2551 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "laser"))) {
2552 ret->printer_type = (xmlChar *)"laser";
2553 if (debug) fprintf(stderr, " Laser printer\n");
2554 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "impact"))) {
2555 ret->printer_type = (xmlChar *)"impact";
2556 if (debug) fprintf(stderr, " Impact printer\n");
2557 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "dotmatrix"))) {
2558 ret->printer_type = (xmlChar *)"dotmatrix";
2559 if (debug) fprintf(stderr, " Dot matrix printer\n");
2560 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "led"))) {
2561 ret->printer_type = (xmlChar *)"led";
2562 if (debug) fprintf(stderr, " LED printer\n");
2563 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "sublimation"))) {
2564 ret->printer_type = (xmlChar *)"sublimation";
2565 if (debug) fprintf(stderr, " Dye sublimation printer\n");
2566 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "transfer"))) {
2567 ret->printer_type = (xmlChar *)"transfer";
2568 if (debug) fprintf(stderr, " Thermal transfer printer\n");
2569 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) {
2570 ret->color = (xmlChar *)"1";
2571 if (debug) fprintf(stderr, " Color printer\n");
2572 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) {
2573 ret->color = (xmlChar *)"0";
2574 if (debug) fprintf(stderr, " Monochrome printer\n");
2575 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "resolution"))) {
2576 cur3 = cur2->xmlChildrenNode;
2577 while (cur3 != NULL) {
2578 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "dpi"))) {
2579 cur4 = cur3->xmlChildrenNode;
2580 while (cur4 != NULL) {
2581 if ((!xmlStrcmp(cur4->name, (const xmlChar *) "x"))) {
2582 ret->maxxres =
2583 perlquote(xmlNodeListGetString(doc,
2584 cur4->xmlChildrenNode,
2585 1));
2586 if (debug) fprintf(stderr,
2587 " Maximum X resolution: %s\n",
2588 ret->maxxres);
2589
2590 } else if ((!xmlStrcmp(cur4->name,(const xmlChar *) "y"))) {
2591 ret->maxyres =
2592 perlquote(xmlNodeListGetString(doc,
2593 cur4->xmlChildrenNode,
2594 1));
2595 if (debug) fprintf(stderr,
2596 " Maximum Y resolution: %s\n",
2597 ret->maxyres);
2598
2599 }
2600 cur4 = cur4->next;
2601 }
2602 }
2603 cur3 = cur3->next;
2604 }
2605 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "margins"))) {
2606 parseMargins(doc, cur2, &(ret->printermargins), language, debug);
2607 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "consumables"))) {
2608 cur3 = cur2->xmlChildrenNode;
2609 while (cur3 != NULL) {
2610 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) {
2611 if (debug)
2612 fprintf(stderr, " Consumables:\n");
2613 getLocalizedText(doc, cur3, &(ret->refill), language, debug);
2614 }
2615 cur3 = cur3->next;
2616 }
2617 }
2618 cur2 = cur2->next;
2619 }
2620 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "lang"))) {
2621 cur2 = cur1->xmlChildrenNode;
2622 while (cur2 != NULL) {
2623 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "pjl"))) {
2624 ret->pjl = (xmlChar *)"1";
2625 if (debug) fprintf(stderr, " Printer supports PJL\n");
2626 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) {
2627 cur3 = cur2->xmlChildrenNode;
2628 while (cur3 != NULL) {
2629 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "charset"))) {
2630 ret->ascii =
2631 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2632 1));
2633 if (debug) fprintf(stderr,
2634 " Printer prints plain text: %s\n",
2635 ret->ascii);
2636 }
2637 cur3 = cur3->next;
2638 }
2639 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) {
2640 cur3 = cur2->xmlChildrenNode;
2641 while (cur3 != NULL) {
2642 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppd"))) {
2643 ret->ppdurl =
2644 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2645 1));
2646 if (debug) fprintf(stderr,
2647 " URL for the PPD for this printer: %s\n",
2648 ret->ppdurl);
2649 }
2650 cur3 = cur3->next;
2651 }
2652 }
2653 if ((xmlStrcmp(cur2->name, (const xmlChar *) "pjl")) &&
2654 (xmlStrcmp(cur2->name, (const xmlChar *) "text")) &&
2655 (xmlStrcmp(cur2->name, (const xmlChar *) "comment"))) {
2656 ret->num_languages ++;
2657 ret->languages =
2658 (printerLanguagePtr *)
2659 realloc((printerLanguagePtr *)ret->languages,
2660 sizeof(printerLanguagePtr) *
2661 ret->num_languages);
2662 lentry = (printerLanguagePtr) malloc(sizeof(printerLanguage));
2663 if (lentry == NULL) {
2664 fprintf(stderr,"Out of memory!\n");
2665 xmlFreeDoc(doc);
2666 exit(1);
2667 }
2668 ret->languages[ret->num_languages-1] = lentry;
2669 memset(lentry, 0, sizeof(printerLanguage));
2670 lentry->name = perlquote((xmlChar *)(cur2->name));
2671 lentry->level =
2672 perlquote(xmlGetProp(cur2, (const xmlChar *) "level"));
2673 if (lentry->level == NULL) lentry->level = (xmlChar *) "";
2674 if (debug)
2675 fprintf(stderr, " Printer understands PDL: %s Level %s\n",
2676 lentry->name, lentry->level);
2677 }
2678 cur2 = cur2->next;
2679 }
2680 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "autodetect"))) {
2681 cur2 = cur1->xmlChildrenNode;
2682 while (cur2 != NULL) {
2683 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "general"))) {
2684 cur3 = cur2->xmlChildrenNode;
2685 if (debug) fprintf(stderr, " Printer auto-detection info (general):\n");
2686 while (cur3 != NULL) {
2687 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
2688 ret->general_ieee =
2689 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2690 1));
2691 if (debug) fprintf(stderr, " IEEE1284: %s\n",
2692 ret->general_ieee);
2693
2694 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
2695 ret->general_mfg =
2696 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2697 1));
2698 if (debug) fprintf(stderr, " MFG: %s\n", ret->general_mfg);
2699
2700 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
2701 ret->general_mdl =
2702 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2703 1));
2704 if (debug) fprintf(stderr, " MDL: %s\n", ret->general_mdl);
2705 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
2706 ret->general_des =
2707 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2708 1));
2709 if (debug) fprintf(stderr, " DES: %s\n", ret->general_des);
2710 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
2711 ret->general_cmd =
2712 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2713 1));
2714 if (debug) fprintf(stderr, " CMD: %s\n", ret->general_cmd);
2715 }
2716 cur3 = cur3->next;
2717 }
2718 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "parallel"))) {
2719 cur3 = cur2->xmlChildrenNode;
2720 if (debug) fprintf(stderr, " Printer auto-detection info (parallel port):\n");
2721 while (cur3 != NULL) {
2722 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
2723 ret->par_ieee =
2724 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2725 1));
2726 if (debug) fprintf(stderr, " IEEE1284: %s\n",
2727 ret->par_ieee);
2728
2729 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
2730 ret->par_mfg =
2731 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2732 1));
2733 if (debug) fprintf(stderr, " MFG: %s\n", ret->par_mfg);
2734
2735 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
2736 ret->par_mdl =
2737 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2738 1));
2739 if (debug) fprintf(stderr, " MDL: %s\n", ret->par_mdl);
2740 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
2741 ret->par_des =
2742 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2743 1));
2744 if (debug) fprintf(stderr, " DES: %s\n", ret->par_des);
2745 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
2746 ret->par_cmd =
2747 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2748 1));
2749 if (debug) fprintf(stderr, " CMD: %s\n", ret->par_cmd);
2750 }
2751 cur3 = cur3->next;
2752 }
2753 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "usb"))) {
2754 cur3 = cur2->xmlChildrenNode;
2755 if (debug) fprintf(stderr, " Printer auto-detection info (USB):\n");
2756 while (cur3 != NULL) {
2757 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
2758 ret->usb_ieee =
2759 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2760 1));
2761 if (debug) fprintf(stderr, " IEEE1284: %s\n",
2762 ret->usb_ieee);
2763
2764 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
2765 ret->usb_mfg =
2766 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2767 1));
2768 if (debug) fprintf(stderr, " MFG: %s\n", ret->usb_mfg);
2769
2770 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
2771 ret->usb_mdl =
2772 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2773 1));
2774 if (debug) fprintf(stderr, " MDL: %s\n", ret->usb_mdl);
2775 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
2776 ret->usb_des =
2777 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2778 1));
2779 if (debug) fprintf(stderr, " DES: %s\n", ret->usb_des);
2780 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
2781 ret->usb_cmd =
2782 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2783 1));
2784 if (debug) fprintf(stderr, " CMD: %s\n", ret->usb_cmd);
2785 }
2786 cur3 = cur3->next;
2787 }
2788 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "snmp"))) {
2789 cur3 = cur2->xmlChildrenNode;
2790 if (debug) fprintf(stderr, " Printer auto-detection info (SNMP):\n");
2791 while (cur3 != NULL) {
2792 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ieee1284"))) {
2793 ret->snmp_ieee =
2794 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2795 1));
2796 if (debug) fprintf(stderr, " IEEE1284: %s\n",
2797 ret->snmp_ieee);
2798
2799 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "manufacturer"))) {
2800 ret->snmp_mfg =
2801 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2802 1));
2803 if (debug) fprintf(stderr, " MFG: %s\n", ret->snmp_mfg);
2804
2805 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "model"))) {
2806 ret->snmp_mdl =
2807 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2808 1));
2809 if (debug) fprintf(stderr, " MDL: %s\n", ret->snmp_mdl);
2810 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "description"))) {
2811 ret->snmp_des =
2812 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2813 1));
2814 if (debug) fprintf(stderr, " DES: %s\n", ret->snmp_des);
2815 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "commandset"))) {
2816 ret->snmp_cmd =
2817 perlquote(xmlNodeListGetString(doc, cur3->xmlChildrenNode,
2818 1));
2819 if (debug) fprintf(stderr, " CMD: %s\n", ret->snmp_cmd);
2820 }
2821 cur3 = cur3->next;
2822 }
2823 }
2824 cur2 = cur2->next;
2825 }
2826 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) {
2827 ret->functionality =
2828 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2829 if (debug) fprintf(stderr, " Printer Functionality: %s\n",
2830 ret->functionality);
2831 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "driver"))) {
2832 ret->driver =
2833 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2834 if (debug) fprintf(stderr, " Recommended driver: %s\n", ret->driver);
2835 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "ppdentry"))) {
2836 ret->printerppdentry =
2837 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2838 if (debug) fprintf(stderr, " Extra lines for PPD file:\n%s\n",
2839 ret->printerppdentry);
2840 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "unverified"))) {
2841 ret->unverified = (xmlChar *)"1";
2842 if (debug) fprintf(stderr, " Printer entry is unverified\n");
2843 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "noxmlentry"))) {
2844 ret->noxmlentry = (xmlChar *)"1";
2845 if (debug) fprintf(stderr, " Printer XML entry does not exist in the database\n");
2846 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "url"))) {
2847 ret->url =
2848 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2849 if (debug) fprintf(stderr, " Printer URL: %s\n", ret->url);
2850 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "contrib_url"))) {
2851 ret->contriburl =
2852 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2853 if (debug) fprintf(stderr, " Contributed URL: %s\n",
2854 ret->contriburl);
2855 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) {
2856 if (debug)
2857 fprintf(stderr, " Comment:\n");
2858 getLocalizedText(doc, cur1, &(ret->comment), language, debug);
2859 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "drivers"))) {
2860 cur2 = cur1->xmlChildrenNode;
2861 while (cur2 != NULL) {
2862 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "driver"))) {
2863 ret->num_drivers ++;
2864 ret->drivers =
2865 (printerDrvEntryPtr *)
2866 realloc((printerDrvEntryPtr *)ret->drivers,
2867 sizeof(printerDrvEntryPtr) *
2868 ret->num_drivers);
2869 dentry = (printerDrvEntryPtr) malloc(sizeof(printerDrvEntry));
2870 if (dentry == NULL) {
2871 fprintf(stderr,"Out of memory!\n");
2872 xmlFreeDoc(doc);
2873 exit(1);
2874 }
2875 ret->drivers[ret->num_drivers-1] = dentry;
2876 memset(dentry, 0, sizeof(printerDrvEntry));
2877 dentry->name = NULL;
2878 dentry->comment = NULL;
2879 dentry->ppd = NULL;
2880 dentry->excmaxresx = NULL;
2881 dentry->excmaxresy = NULL;
2882 dentry->exccolor = NULL;
2883 dentry->exctext = NULL;
2884 dentry->exclineart = NULL;
2885 dentry->excgraphics = NULL;
2886 dentry->excphoto = NULL;
2887 dentry->excload = NULL;
2888 dentry->excspeed = NULL;
2889 if (debug) fprintf(stderr, " Printer supported by drivers:\n");
2890 cur3 = cur2->xmlChildrenNode;
2891 while (cur3 != NULL) {
2892 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "id"))) {
2893 dname =
2894 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
2895 dentry->name = perlquote(dname);
2896 if (debug) fprintf(stderr, " Name: %s\n",
2897 dentry->name);
2898 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "ppd"))) {
2899 dppd =
2900 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
2901 dentry->ppd = perlquote(dppd);
2902 if (debug) fprintf(stderr, " Ready-made PPD: %s\n",
2903 dentry->ppd);
2904 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) {
2905 if (debug)
2906 fprintf(stderr, " Comment:\n");
2907 getLocalizedText(doc, cur3, &(dentry->comment), language, debug);
2908 }
2909 cur3 = cur3->next;
2910 }
2911 }
2912 cur2 = cur2->next;
2913 }
2914 }
2915 cur1 = cur1->next;
2916 }
2917 }
2918
2919 static void
parseDriverEntry(xmlDocPtr doc,xmlNodePtr node,driverEntryPtr ret,xmlChar const language[],int debug)2920 parseDriverEntry(xmlDocPtr doc, /* I - The whole driver data tree */
2921 xmlNodePtr node, /* I - Node of XML tree to work on */
2922 driverEntryPtr ret, /* O - C data structure of Foomatic
2923 driver entry */
2924 xmlChar const language [], /* I - User language */
2925 int debug) { /* I - Debug mode flag */
2926 xmlNodePtr cur1; /* XML node currently worked on */
2927 xmlNodePtr cur2; /* Another XML node pointer */
2928 xmlNodePtr cur3; /* Another XML node pointer */
2929 xmlNodePtr cur4; /* Another XML node pointer */
2930 xmlChar *id; /* Full driver ID, with "driver/" */
2931 drvPrnEntryPtr entry; /* An entry for a printer supported by this driver*/
2932 xmlChar *url, *level, *version, *scope, *fingerprint;
2933
2934 /* Initialization of entries */
2935 ret->id = NULL;
2936 ret->name = NULL;
2937 ret->group = NULL;
2938 ret->url = NULL;
2939 ret->driver_obsolete = NULL;
2940 ret->supplier = NULL;
2941 ret->manufacturersupplied = NULL;
2942 ret->license = NULL;
2943 ret->licensetext = NULL;
2944 ret->origlicensetext = NULL;
2945 ret->licenselink = NULL;
2946 ret->origlicenselink = NULL;
2947 ret->free = NULL;
2948 ret->patents = NULL;
2949 ret->num_supportcontacts = 0;
2950 ret->supportcontacts = NULL;
2951 ret->supportcontacturls = NULL;
2952 ret->supportcontactlevels = NULL;
2953 ret->shortdescription = NULL;
2954 ret->locales = NULL;
2955 ret->num_packages = 0;
2956 ret->packageurls = NULL;
2957 ret->packagescopes = NULL;
2958 ret->packagefingerprints = NULL;
2959 ret->maxresx = NULL;
2960 ret->maxresy = NULL;
2961 ret->color = NULL;
2962 ret->text = NULL;
2963 ret->lineart = NULL;
2964 ret->graphics = NULL;
2965 ret->photo = NULL;
2966 ret->load = NULL;
2967 ret->speed = NULL;
2968 ret->num_requires = 0;
2969 ret->requires = NULL;
2970 ret->requiresversion = NULL;
2971 ret->driver_type = NULL;
2972 ret->cmd = NULL;
2973 ret->cmd_pdf = NULL;
2974 ret->driverppdentry = NULL;
2975 ret->drivermargins = NULL;
2976 ret->comment = NULL;
2977 ret->num_printers = 0;
2978 ret->printers = NULL;
2979
2980 /* Get driver ID */
2981 id = xmlGetProp(node, (const xmlChar *) "id");
2982 if (id == NULL) {
2983 fprintf(stderr, "No driver ID found\n");
2984 return;
2985 }
2986 ret->id = perlquote(id + 7);
2987 if (debug) fprintf(stderr, " Driver ID: %s\n", ret->id);
2988
2989 /* Go through subnodes */
2990 cur1 = node->xmlChildrenNode;
2991 while (cur1 != NULL) {
2992 if ((!xmlStrcmp(cur1->name, (const xmlChar *) "name"))) {
2993 ret->name =
2994 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2995 if (debug) fprintf(stderr, " Driver name: %s\n", ret->name);
2996 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "group"))) {
2997 ret->group =
2998 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
2999 if (debug) fprintf(stderr, " Driver group (for localization): %s\n",
3000 ret->group);
3001 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "url"))) {
3002 ret->url =
3003 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
3004 if (debug) fprintf(stderr, " Driver URL: %s\n", ret->url);
3005 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "obsolete"))) {
3006 ret->driver_obsolete = xmlGetProp(cur1, (const xmlChar *) "replace");
3007 if (ret->driver_obsolete == NULL) {
3008 if (debug) fprintf(stderr, " No replacement driver found!\n");
3009 ret->driver_obsolete = (xmlChar *)"1";
3010 }
3011 if (debug) fprintf(stderr, " Driver is obsolete: %s\n",
3012 ret->driver_obsolete);
3013 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supplier"))) {
3014 if (debug)
3015 fprintf(stderr, " Driver supplier:\n");
3016 getLocalizedText(doc, cur1, &(ret->supplier), language, debug);
3017 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "manufacturersupplied"))) {
3018 ret->manufacturersupplied =
3019 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
3020 if ((ret->manufacturersupplied == NULL) ||
3021 (ret->manufacturersupplied[0] == '\0'))
3022 ret->manufacturersupplied = (xmlChar *)"1";
3023 if (debug) fprintf(stderr, " Driver supplied by manufacturer: %s\n",
3024 ret->manufacturersupplied);
3025 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "thirdpartysupplied"))) {
3026 ret->manufacturersupplied = (xmlChar *)"0";
3027 if (debug) fprintf(stderr, " Driver supplied by a third party\n");
3028 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "license"))) {
3029 if (debug)
3030 fprintf(stderr, " Driver license:\n");
3031 getLocalizedText(doc, cur1, &(ret->license), language, debug);
3032 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "licensetext"))) {
3033 if (debug)
3034 fprintf(stderr, " Driver license text:\n");
3035 getLocalizedLicenseText(doc, cur1,
3036 &(ret->licensetext), &(ret->origlicensetext),
3037 &(ret->licenselink), &(ret->origlicenselink),
3038 language, debug);
3039 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "freesoftware"))) {
3040 ret->free = (xmlChar *)"1";
3041 if (debug) fprintf(stderr, " Driver is free software\n");
3042 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nonfreesoftware"))) {
3043 ret->free = (xmlChar *)"0";
3044 if (debug) fprintf(stderr, " Driver is not free software\n");
3045 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "patents"))) {
3046 ret->patents = (xmlChar *)"1";
3047 if (debug) fprintf(stderr, " There are patents applying to this driver's code\n");
3048 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "nopatents"))) {
3049 ret->patents = (xmlChar *)"0";
3050 if (debug) fprintf(stderr, " There are no patents applying to this driver's code\n");
3051 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "supportcontacts"))) {
3052 cur2 = cur1->xmlChildrenNode;
3053 if (debug) fprintf(stderr, " Driver support contacts:\n");
3054 while (cur2 != NULL) {
3055 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "supportcontact"))) {
3056 ret->num_supportcontacts ++;
3057 ret->supportcontacts =
3058 (xmlChar const **)
3059 realloc((xmlChar **)ret->supportcontacts,
3060 sizeof(xmlChar *) *
3061 ret->num_supportcontacts);
3062 ret->supportcontacturls =
3063 (xmlChar **)
3064 realloc((xmlChar **)ret->supportcontacturls,
3065 sizeof(xmlChar *) *
3066 ret->num_supportcontacts);
3067 ret->supportcontactlevels =
3068 (xmlChar **)
3069 realloc((xmlChar **)ret->supportcontactlevels,
3070 sizeof(xmlChar *) *
3071 ret->num_supportcontacts);
3072 level = xmlGetProp(cur2, (const xmlChar *) "level");
3073 if (level == NULL) {
3074 level = (xmlChar *)"Unknown";
3075 }
3076 url = xmlGetProp(cur2, (const xmlChar *) "url");
3077 ret->supportcontactlevels[ret->num_supportcontacts - 1] = level;
3078 ret->supportcontacturls[ret->num_supportcontacts - 1] = url;
3079 getLocalizedText
3080 (doc, cur2,
3081 &(ret->supportcontacts[ret->num_supportcontacts - 1]),
3082 language, debug);
3083 if (debug)
3084 fprintf(stderr, " %s (%s):\n %s\n",
3085 ret->supportcontacts[ret->num_supportcontacts - 1],
3086 ret->supportcontactlevels[ret->num_supportcontacts - 1],
3087 ret->supportcontacturls[ret->num_supportcontacts - 1]);
3088 }
3089 cur2 = cur2->next;
3090 }
3091 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "shortdescription"))) {
3092 if (debug)
3093 fprintf(stderr, " Driver short description:\n");
3094 getLocalizedText(doc, cur1, &(ret->shortdescription), language, debug);
3095 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "locales"))) {
3096 ret->locales =
3097 perlquote(xmlNodeListGetString(doc, cur1->xmlChildrenNode, 1));
3098 if (debug) fprintf(stderr, " Driver list of locales: %s\n", ret->locales);
3099 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "packages"))) {
3100 cur2 = cur1->xmlChildrenNode;
3101 if (debug) fprintf(stderr, " Driver downloadable packages:\n");
3102 while (cur2 != NULL) {
3103 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "package"))) {
3104 ret->num_packages ++;
3105 ret->packageurls =
3106 (xmlChar **)
3107 realloc((xmlChar **)ret->packageurls,
3108 sizeof(xmlChar *) *
3109 ret->num_packages);
3110 ret->packagescopes =
3111 (xmlChar **)
3112 realloc((xmlChar **)ret->packagescopes,
3113 sizeof(xmlChar *) *
3114 ret->num_packages);
3115 scope = xmlGetProp(cur2, (const xmlChar *) "scope");
3116 ret->packagefingerprints =
3117 (xmlChar **)
3118 realloc((xmlChar **)ret->packagefingerprints,
3119 sizeof(xmlChar *) *
3120 ret->num_packages);
3121 fingerprint = xmlGetProp(cur2, (const xmlChar *) "fingerprint");
3122 ret->packageurls[ret->num_packages - 1] =
3123 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3124 ret->packagescopes[ret->num_packages - 1] = perlquote(scope);
3125 ret->packagefingerprints[ret->num_packages - 1] = perlquote(fingerprint);
3126 if (debug)
3127 fprintf(stderr, " %s (%s), key fingerprint on %s\n",
3128 ret->packageurls[ret->num_packages - 1],
3129 ret->packagescopes[ret->num_packages - 1],\
3130 ret->packagefingerprints[ret->num_packages - 1]);
3131 }
3132 cur2 = cur2->next;
3133 }
3134 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "functionality"))) {
3135 cur2 = cur1->xmlChildrenNode;
3136 while (cur2 != NULL) {
3137 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresx"))) {
3138 ret->maxresx =
3139 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3140 if (debug)
3141 fprintf(stderr, " Driver functionality: Max X resolution: %s\n",
3142 ret->maxresx);
3143 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "maxresy"))) {
3144 ret->maxresy =
3145 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3146 if (debug)
3147 fprintf(stderr, " Driver functionality: Max Y resolution: %s\n",
3148 ret->maxresy);
3149 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "color"))) {
3150 ret->color = (xmlChar *)"1";
3151 if (debug) fprintf(stderr, " Driver functionality: Color\n");
3152 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "monochrome"))) {
3153 ret->color = (xmlChar *)"0";
3154 if (debug) fprintf(stderr, " Driver functionality: Monochrome\n");
3155 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "text"))) {
3156 ret->text =
3157 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3158 if (debug)
3159 fprintf(stderr, " Driver functionality: Text support rating: %s\n",
3160 ret->text);
3161 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "lineart"))) {
3162 ret->lineart =
3163 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3164 if (debug)
3165 fprintf(stderr, " Driver functionality: Line art support rating: %s\n",
3166 ret->lineart);
3167 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "graphics"))) {
3168 ret->graphics =
3169 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3170 if (debug)
3171 fprintf(stderr, " Driver functionality: Graphics support rating: %s\n",
3172 ret->graphics);
3173 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "photo"))) {
3174 ret->photo =
3175 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3176 if (debug)
3177 fprintf(stderr, " Driver functionality: Photo support rating: %s\n",
3178 ret->photo);
3179 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "load"))) {
3180 ret->load =
3181 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3182 if (debug)
3183 fprintf(stderr, " Driver functionality: System load rating: %s\n",
3184 ret->load);
3185 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "speed"))) {
3186 ret->speed =
3187 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3188 if (debug)
3189 fprintf(stderr, " Driver functionality: Speed rating: %s\n",
3190 ret->speed);
3191 }
3192 cur2 = cur2->next;
3193 }
3194 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "execution"))) {
3195 cur2 = cur1->xmlChildrenNode;
3196 while (cur2 != NULL) {
3197 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "requires"))) {
3198 ret->num_requires ++;
3199 ret->requires =
3200 (xmlChar **)
3201 realloc((xmlChar **)ret->requires,
3202 sizeof(xmlChar *) *
3203 ret->num_requires);
3204 ret->requiresversion =
3205 (xmlChar **)
3206 realloc((xmlChar **)ret->requiresversion,
3207 sizeof(xmlChar *) *
3208 ret->num_requires);
3209 version = xmlGetProp(cur2, (const xmlChar *) "version");
3210 ret->requires[ret->num_requires - 1] =
3211 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3212 ret->requiresversion[ret->num_requires - 1] = perlquote(version);
3213 if (debug) {
3214 if (!version)
3215 fprintf(stderr, " Driver requires driver: %s\n",
3216 ret->requires[ret->num_requires - 1]);
3217 else
3218 fprintf(stderr, " Driver requires driver: %s (%s)\n",
3219 ret->requires[ret->num_requires - 1],
3220 ret->requiresversion[ret->num_requires - 1]); }
3221 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "cups"))) {
3222 ret->driver_type = (xmlChar *)"C";
3223 if (debug) fprintf(stderr, " Driver type: CUPS Raster\n");
3224 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ijs"))) {
3225 ret->driver_type = (xmlChar *)"I";
3226 if (debug) fprintf(stderr, " Driver type: IJS\n");
3227 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "opvp"))) {
3228 ret->driver_type = (xmlChar *)"V";
3229 if (debug) fprintf(stderr, " Driver type: OpenPrinting Vector\n");
3230 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ghostscript"))) {
3231 ret->driver_type = (xmlChar *)"G";
3232 if (debug) fprintf(stderr, " Driver type: Ghostscript built-in\n");
3233 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "filter"))) {
3234 ret->driver_type = (xmlChar *)"F";
3235 if (debug) fprintf(stderr, " Driver type: Filter\n");
3236 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "uniprint"))) {
3237 ret->driver_type = (xmlChar *)"U";
3238 if (debug) fprintf(stderr, " Driver type: Ghostscript Uniprint\n");
3239 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "postscript"))) {
3240 ret->driver_type = (xmlChar *)"P";
3241 if (debug) fprintf(stderr, " Driver type: PostScript\n");
3242 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "prototype"))) {
3243 ret->cmd =
3244 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3245 if (debug) fprintf(stderr, " Driver command line:\n\n %s\n\n",
3246 ret->cmd);
3247 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "prototype_pdf"))) {
3248 ret->cmd_pdf =
3249 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3250 if (debug) fprintf(stderr, " Driver PDF command line:\n\n %s\n\n",
3251 ret->cmd_pdf);
3252 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "ppdentry"))) {
3253 ret->driverppdentry =
3254 perlquote(xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1));
3255 if (debug) fprintf(stderr, " Extra lines for PPD file:\n%s\n",
3256 ret->driverppdentry);
3257 } else if ((!xmlStrcmp(cur2->name, (const xmlChar *) "margins"))) {
3258 parseMargins(doc, cur2, &(ret->drivermargins), language, debug);
3259 }
3260 cur2 = cur2->next;
3261 }
3262 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "comments"))) {
3263 if (debug)
3264 fprintf(stderr, " Comment:\n");
3265 getLocalizedText(doc, cur1, &(ret->comment), language, debug);
3266 } else if ((!xmlStrcmp(cur1->name, (const xmlChar *) "printers"))) {
3267 cur2 = cur1->xmlChildrenNode;
3268 while (cur2 != NULL) {
3269 if ((!xmlStrcmp(cur2->name, (const xmlChar *) "printer"))) {
3270 ret->num_printers ++;
3271 ret->printers =
3272 (drvPrnEntryPtr *)realloc((drvPrnEntryPtr *)ret->printers,
3273 sizeof(drvPrnEntryPtr) *
3274 ret->num_printers);
3275 entry = (drvPrnEntryPtr) malloc(sizeof(drvPrnEntry));
3276 if (entry == NULL) {
3277 fprintf(stderr,"Out of memory!\n");
3278 xmlFreeDoc(doc);
3279 exit(1);
3280 }
3281 ret->printers[ret->num_printers-1] = entry;
3282 memset(entry, 0, sizeof(drvPrnEntry));
3283 entry->id = NULL;
3284 entry->comment = NULL;
3285 entry->excmaxresx = NULL;
3286 entry->excmaxresy = NULL;
3287 entry->exccolor = NULL;
3288 entry->exctext = NULL;
3289 entry->exclineart = NULL;
3290 entry->excgraphics = NULL;
3291 entry->excphoto = NULL;
3292 entry->excload = NULL;
3293 entry->excspeed = NULL;
3294 if (debug) fprintf(stderr, " Driver supports printer:\n");
3295 cur3 = cur2->xmlChildrenNode;
3296 while (cur3 != NULL) {
3297 if ((!xmlStrcmp(cur3->name, (const xmlChar *) "id"))) {
3298 id =
3299 xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
3300 entry->id = perlquote(id + 8);
3301 if (debug) fprintf(stderr, " ID: %s\n",
3302 entry->id);
3303 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "comments"))) {
3304 if (debug)
3305 fprintf(stderr, " Comment:\n");
3306 getLocalizedText(doc, cur3, &(entry->comment), language, debug);
3307 } else if ((!xmlStrcmp(cur3->name, (const xmlChar *) "functionality"))) {
3308 cur4 = cur3->xmlChildrenNode;
3309 while (cur4 != NULL) {
3310 if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresx"))) {
3311 entry->excmaxresx =
3312 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3313 if (debug)
3314 fprintf(stderr, " Printer exception: Maximum X resolution: %s\n",
3315 entry->excmaxresx);
3316 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "maxresy"))) {
3317 entry->excmaxresy =
3318 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3319 if (debug)
3320 fprintf(stderr, " Printer exception: Maximum Y resolution: %s\n",
3321 entry->excmaxresy);
3322 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "monochrome"))) {
3323 entry->exccolor = (xmlChar *)"0";
3324 if (debug)
3325 fprintf(stderr, " Printer exception: Color: %s\n",
3326 entry->exccolor);
3327 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "color"))) {
3328 entry->exccolor = (xmlChar *)"1";
3329 if (debug)
3330 fprintf(stderr, " Printer exception: Color: %s\n",
3331 entry->exccolor);
3332 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "text"))) {
3333 entry->exctext =
3334 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3335 if (debug)
3336 fprintf(stderr, " Printer exception: Support level for text: %s\n",
3337 entry->exctext);
3338 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "lineart"))) {
3339 entry->exclineart =
3340 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3341 if (debug)
3342 fprintf(stderr, " Printer exception: Support level for line art: %s\n",
3343 entry->exclineart);
3344 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "graphics"))) {
3345 entry->excgraphics =
3346 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3347 if (debug)
3348 fprintf(stderr, " Printer exception: Support level for graphics: %s\n",
3349 entry->excgraphics);
3350 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "photo"))) {
3351 entry->excphoto =
3352 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3353 if (debug)
3354 fprintf(stderr, " Printer exception: Support level for photos: %s\n",
3355 entry->excphoto);
3356 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "load"))) {
3357 entry->excload =
3358 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3359 if (debug)
3360 fprintf(stderr, " Printer exception: Expected relative system load: %s\n",
3361 entry->excload);
3362 } else if ((!xmlStrcmp(cur4->name, (const xmlChar *) "speed"))) {
3363 entry->excspeed =
3364 perlquote(xmlNodeListGetString(doc, cur4->xmlChildrenNode, 1));
3365 if (debug)
3366 fprintf(stderr, " Printer exception: Expected relative driver speed: %s\n",
3367 entry->excspeed);
3368 }
3369 cur4 = cur4->next;
3370 }
3371 }
3372 cur3 = cur3->next;
3373 }
3374 }
3375 cur2 = cur2->next;
3376 }
3377 }
3378 cur1 = cur1->next;
3379 }
3380 }
3381
3382 static xmlDocPtr /* O - Tree with data parsed from stdin */
parseXMLFromStdin()3383 parseXMLFromStdin() {
3384
3385 FILE *f;
3386 xmlDocPtr doc = NULL;
3387
3388 if (stdin != NULL) {
3389 int res, size = 1024;
3390 char chars[1024];
3391 xmlParserCtxtPtr ctxt;
3392
3393 res = fread(chars, 1, 4, stdin);
3394 if (res > 0) {
3395 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
3396 chars, res, NULL);
3397 while ((res = fread(chars, 1, size, stdin)) > 0) {
3398 xmlParseChunk(ctxt, chars, res, 0);
3399 }
3400 xmlParseChunk(ctxt, chars, 0, 1);
3401 doc = ctxt->myDoc;
3402 xmlFreeParserCtxt(ctxt);
3403 }
3404 }
3405 return doc;
3406 }
3407
3408 static overviewPtr /* O - C data structure of overview */
parseOverviewFile(char * filename,xmlChar const language[],int debug)3409 parseOverviewFile(char *filename, /* I - Input file name, NULL: stdin */
3410 xmlChar const language [], /* I - User language */
3411 int debug) { /* I - Debug mode flag */
3412 xmlDocPtr doc; /* Output of XML parser */
3413 overviewPtr ret; /* C data structure of overview */
3414 xmlNodePtr cur; /* XML node currently worked on */
3415 driverEntryPtr driver;
3416
3417 /*
3418 * build an XML tree from a file or stdin;
3419 */
3420
3421 if (filename == NULL) {
3422 doc = parseXMLFromStdin();
3423 } else {
3424 doc = xmlParseFile(filename);
3425 }
3426 if (doc == NULL) return(NULL);
3427
3428 /*
3429 * Check the document is of the right kind
3430 */
3431
3432 cur = xmlDocGetRootElement(doc);
3433 if (cur == NULL) {
3434 fprintf(stderr,"Empty input document!\n");
3435 xmlFreeDoc(doc);
3436 return(NULL);
3437 }
3438
3439 if (xmlStrcmp(cur->name, (const xmlChar *) "overview")) {
3440 fprintf(stderr,"Input document is not a Foomatic overview XML file (no \"<overview>\" tag)!\n");
3441 xmlFreeDoc(doc);
3442 return(NULL);
3443 }
3444
3445 /*
3446 * Allocate the structure to be returned.
3447 */
3448 ret = (overviewPtr) malloc(sizeof(overview));
3449 if (ret == NULL) {
3450 fprintf(stderr,"Out of memory!\n");
3451 xmlFreeDoc(doc);
3452 return(NULL);
3453 }
3454 memset(ret, 0, sizeof(overview));
3455 ret->num_overviewPrinters = 0;
3456 ret->overviewPrinters = NULL;
3457
3458 /*
3459 * Now, walk through the tree.
3460 */
3461
3462 /* On the first level we have the printer entries */
3463
3464 cur = cur->xmlChildrenNode;
3465 while (cur) {
3466 if (xmlIsBlankNode(cur)) {
3467 cur = cur->next;
3468 continue;
3469 }
3470 if (!xmlStrcmp(cur->name, (const xmlChar *) "driver")) {
3471 ret->num_overviewDrivers ++;
3472 ret->overviewDrivers =
3473 (driverEntryPtr *)realloc
3474 ((driverEntryPtr *)(ret->overviewDrivers),
3475 sizeof(driverEntryPtr) * ret->num_overviewDrivers);
3476 driver = (driverEntryPtr) malloc(sizeof(driverEntry));
3477 if (driver == NULL) {
3478 fprintf(stderr,"Out of memory!\n");
3479 xmlFreeDoc(doc);
3480 exit(1);
3481 }
3482 ret->overviewDrivers[ret->num_overviewDrivers-1] = driver;
3483 memset(driver, 0, sizeof(driverEntry));
3484 if (debug) fprintf(stderr, "--> Parsing driver data\n");
3485 parseDriverEntry(doc, cur, driver, language, debug);
3486 } else if (!xmlStrcmp(cur->name, (const xmlChar *) "printer")) {
3487 if (debug) fprintf(stderr, "--> Parsing printer data\n");
3488 parseOverviewPrinter(doc, cur, ret, language, debug);
3489 }
3490 cur = cur->next;
3491 }
3492
3493 /* We succeeded, return the result */
3494
3495 return(ret);
3496 }
3497
3498 static comboDataPtr /* O - C data structure of printer/driver combo */
parseComboFile(char * filename,xmlChar const language[],int debug)3499 parseComboFile(char *filename, /* I - Input file name, NULL: stdin */
3500 xmlChar const language [], /* I - User language */
3501 int debug) { /* I - Debug mode flag */
3502 xmlDocPtr doc; /* Output of XML parser */
3503 comboDataPtr ret; /* C data structure of printer/driver combo */
3504 xmlNodePtr cur; /* XML node currently worked on */
3505
3506 /*
3507 * build an XML tree from a file or stdin;
3508 */
3509
3510 if (filename == NULL) {
3511 doc = parseXMLFromStdin();
3512 } else {
3513 doc = xmlParseFile(filename);
3514 }
3515 if (doc == NULL) return(NULL);
3516
3517 /*
3518 * Check the document is of the right kind
3519 */
3520
3521 cur = xmlDocGetRootElement(doc);
3522 if (cur == NULL) {
3523 fprintf(stderr,"Empty input document!\n");
3524 xmlFreeDoc(doc);
3525 return(NULL);
3526 }
3527
3528 if (xmlStrcmp(cur->name, (const xmlChar *) "foomatic")) {
3529 fprintf(stderr,"Input document is not a Foomatic combo XML file (no \"<foomatic>\" tag)!\n");
3530 xmlFreeDoc(doc);
3531 return(NULL);
3532 }
3533
3534 /*
3535 * Allocate the structure to be returned.
3536 */
3537 ret = (comboDataPtr) malloc(sizeof(comboData));
3538 if (ret == NULL) {
3539 fprintf(stderr,"Out of memory!\n");
3540 xmlFreeDoc(doc);
3541 return(NULL);
3542 }
3543 memset(ret, 0, sizeof(comboData));
3544 ret->make = NULL;
3545 ret->driver = NULL;
3546 ret->num_args = 0;
3547 ret->args = NULL;
3548
3549 /*
3550 * Now, walk through the tree.
3551 */
3552
3553 /* On the first level we have the printer, the driver,
3554 and the options */
3555
3556 cur = cur->xmlChildrenNode;
3557 while (cur) {
3558 if (xmlIsBlankNode(cur)) {
3559 cur = cur->next;
3560 continue;
3561 }
3562 if (!xmlStrcmp(cur->name, (const xmlChar *) "printer")) {
3563 if (debug) fprintf(stderr, "--> Parsing printer data\n");
3564 parseComboPrinter(doc, cur, ret, language, debug);
3565 } else if (!xmlStrcmp(cur->name, (const xmlChar *) "driver")) {
3566 if (debug) fprintf(stderr, "--> Parsing driver data\n");
3567 parseComboDriver(doc, cur, ret, language, debug);
3568 } else if (!xmlStrcmp(cur->name, (const xmlChar *) "options")) {
3569 if (debug) fprintf(stderr, "--> Parsing option data\n");
3570 parseOptions(doc, cur, ret, language, debug);
3571 }
3572 cur = cur->next;
3573 }
3574
3575 /* All sections present in combo XML? */
3576
3577 if (ret->make == NULL) {
3578 fprintf(stderr,"\"<printer>\" tag not found!\n");
3579 exit(1);
3580 }
3581
3582 if (ret->driver == NULL) {
3583 fprintf(stderr,"\"<driver>\" tag not found!\n");
3584 exit(1);
3585 }
3586
3587 /* We succeeded, return the result */
3588
3589 return(ret);
3590 }
3591
3592 static printerEntryPtr /* O - C data structure of printer entry */
parsePrinterFile(char * filename,xmlChar const language[],int debug)3593 parsePrinterFile(char *filename, /* I - Input file name, NULL: stdin */
3594 xmlChar const language [], /* I - User language */
3595 int debug) { /* I - Debug mode flag */
3596 xmlDocPtr doc; /* Output of XML parser */
3597 printerEntryPtr ret; /* C data structure of printer entry */
3598 xmlNodePtr cur; /* XML node currently worked on */
3599
3600 /*
3601 * build an XML tree from a file or stdin;
3602 */
3603
3604 if (filename == NULL) {
3605 doc = parseXMLFromStdin();
3606 } else {
3607 doc = xmlParseFile(filename);
3608 }
3609 if (doc == NULL) return(NULL);
3610
3611 /*
3612 * Check the document is of the right kind
3613 */
3614
3615 cur = xmlDocGetRootElement(doc);
3616 if (cur == NULL) {
3617 fprintf(stderr,"Empty input document!\n");
3618 xmlFreeDoc(doc);
3619 return(NULL);
3620 }
3621
3622 if (xmlStrcmp(cur->name, (const xmlChar *) "printer")) {
3623 fprintf(stderr,"Input document is not a Foomatic printer XML file (no \"<printer>\" tag)!\n");
3624 xmlFreeDoc(doc);
3625 return(NULL);
3626 }
3627
3628 /*
3629 * Allocate the structure to be returned.
3630 */
3631 ret = (printerEntryPtr) malloc(sizeof(printerEntry));
3632 if (ret == NULL) {
3633 fprintf(stderr,"Out of memory!\n");
3634 xmlFreeDoc(doc);
3635 return(NULL);
3636 }
3637 memset(ret, 0, sizeof(printerEntry));
3638
3639 /*
3640 * Now, walk through the tree.
3641 */
3642
3643 if (debug) fprintf(stderr, "--> Parsing printer data\n");
3644 parsePrinterEntry(doc, cur, ret, language, debug);
3645
3646 /* We succeeded, return the result */
3647
3648 return(ret);
3649 }
3650
3651 static driverEntryPtr /* O - C data structure of driver entry */
parseDriverFile(char * filename,xmlChar const language[],int debug)3652 parseDriverFile(char *filename, /* I - Input file name, NULL: stdin */
3653 xmlChar const language [], /* I - User language */
3654 int debug) { /* I - Debug mode flag */
3655 xmlDocPtr doc; /* Output of XML parser */
3656 driverEntryPtr ret; /* C data structure of driver entry */
3657 xmlNodePtr cur; /* XML node currently worked on */
3658
3659 /*
3660 * build an XML tree from a file or stdin;
3661 */
3662
3663 if (filename == NULL) {
3664 doc = parseXMLFromStdin();
3665 } else {
3666 doc = xmlParseFile(filename);
3667 }
3668 if (doc == NULL) return(NULL);
3669
3670 /*
3671 * Check the document is of the right kind
3672 */
3673
3674 cur = xmlDocGetRootElement(doc);
3675 if (cur == NULL) {
3676 fprintf(stderr,"Empty input document!\n");
3677 xmlFreeDoc(doc);
3678 return(NULL);
3679 }
3680
3681 if (xmlStrcmp(cur->name, (const xmlChar *) "driver")) {
3682 fprintf(stderr,"Input document is not a Foomatic driver XML file (no \"<driver>\" tag)!\n");
3683 xmlFreeDoc(doc);
3684 return(NULL);
3685 }
3686
3687 /*
3688 * Allocate the structure to be returned.
3689 */
3690 ret = (driverEntryPtr) malloc(sizeof(driverEntry));
3691 if (ret == NULL) {
3692 fprintf(stderr,"Out of memory!\n");
3693 xmlFreeDoc(doc);
3694 return(NULL);
3695 }
3696 memset(ret, 0, sizeof(driverEntry));
3697
3698 /*
3699 * Now, walk through the tree.
3700 */
3701
3702 if (debug) fprintf(stderr, "--> Parsing driver data\n");
3703 parseDriverEntry(doc, cur, ret, language, debug);
3704
3705 /* We succeeded, return the result */
3706
3707 return(ret);
3708 }
3709
3710 void
prepareComboData(comboDataPtr combo,xmlChar ** defaultsettings,int num_defaultsettings,int debug)3711 prepareComboData(comboDataPtr combo, /* I/O - Foomatic combo data parsed
3712 from XML input */
3713 xmlChar **defaultsettings, /* User-supplied default option
3714 settings */
3715 int num_defaultsettings, /* number of default option
3716 settings */
3717 int debug) { /* Debug flag */
3718
3719 int i, j; /* loop variables */
3720 xmlChar *option, *value, *s;/* User option and value, temporary pointer */
3721
3722 /* Insert the default values (not choice IDs) for the enumerated
3723 options */
3724
3725 for (i = 0; i < combo->num_args; i ++) {
3726 for (j = 0; j < combo->args[i]->num_choices; j ++) {
3727 if (!xmlStrcmp(combo->args[i]->choices[j]->idx,
3728 combo->args[i]->default_value)) {
3729 combo->args[i]->default_value = combo->args[i]->choices[j]->value;
3730 if (debug)
3731 fprintf(stderr,
3732 " Setting default value for enumerated option %s: %s\n",
3733 combo->args[i]->name,
3734 combo->args[i]->default_value);
3735 }
3736 }
3737 }
3738
3739 /* Insert the user-supplied defaults */
3740
3741 for (i = 0; i < num_defaultsettings; i ++) {
3742 s =
3743 xmlStrchr ((defaultsettings[i]), '=')
3744 - (defaultsettings[i]) + (defaultsettings[i]);
3745 *s = (xmlChar)'\0';
3746 s ++;
3747 option = defaultsettings[i];
3748 value = s;
3749 for (j = 0; j < combo->num_args; j ++) {
3750 if (!xmlStrcmp(combo->args[j]->name, option)) {
3751 combo->args[j]->default_value = value;
3752 if (debug) fprintf(stderr,
3753 " Setting user default for option %s: %s\n",
3754 combo->args[j]->name,
3755 combo->args[j]->default_value);
3756 }
3757 }
3758 }
3759
3760 }
3761
3762 void
generateOverviewPerlData(overviewPtr overview,int debug)3763 generateOverviewPerlData(overviewPtr overview, /* I/O - Foomatic overview
3764 data parsed from XML
3765 input */
3766 int debug) { /* Debug flag */
3767
3768 int i, j, k, l; /* loop variables */
3769 overviewPrinterPtr printer;
3770
3771 printf("$VAR1 = [\n");
3772 for (i = 0; i < overview->num_overviewPrinters; i ++) {
3773 printer = overview->overviewPrinters[i];
3774 printf(" {\n");
3775 printf(" 'id' => '%s',\n", printer->id);
3776 printf(" 'make' => '%s',\n", printer->make);
3777 printf(" 'model' => '%s',\n", printer->model);
3778 if (printer->general_ieee) {
3779 printf(" 'general_ieee' => '%s',\n",
3780 printer->general_ieee);
3781 }
3782 if (printer->general_mfg) {
3783 printf(" 'general_mfg' => '%s',\n", printer->general_mfg);
3784 }
3785 if (printer->general_mdl) {
3786 printf(" 'general_mdl' => '%s',\n", printer->general_mdl);
3787 }
3788 if (printer->general_des) {
3789 printf(" 'general_des' => '%s',\n", printer->general_des);
3790 }
3791 if (printer->general_cmd) {
3792 printf(" 'general_cmd' => '%s',\n", printer->general_cmd);
3793 }
3794 if (printer->par_ieee) {
3795 printf(" 'par_ieee' => '%s',\n", printer->par_ieee);
3796 }
3797 if (printer->par_mfg) {
3798 printf(" 'par_mfg' => '%s',\n", printer->par_mfg);
3799 }
3800 if (printer->par_mdl) {
3801 printf(" 'par_mdl' => '%s',\n", printer->par_mdl);
3802 }
3803 if (printer->par_des) {
3804 printf(" 'par_des' => '%s',\n", printer->par_des);
3805 }
3806 if (printer->par_cmd) {
3807 printf(" 'par_cmd' => '%s',\n", printer->par_cmd);
3808 }
3809 if (printer->usb_ieee) {
3810 printf(" 'usb_ieee' => '%s',\n", printer->usb_ieee);
3811 }
3812 if (printer->usb_mfg) {
3813 printf(" 'usb_mfg' => '%s',\n", printer->usb_mfg);
3814 }
3815 if (printer->usb_mdl) {
3816 printf(" 'usb_mdl' => '%s',\n", printer->usb_mdl);
3817 }
3818 if (printer->usb_des) {
3819 printf(" 'usb_des' => '%s',\n", printer->usb_des);
3820 }
3821 if (printer->usb_cmd) {
3822 printf(" 'usb_cmd' => '%s',\n", printer->usb_cmd);
3823 }
3824 if (printer->snmp_ieee) {
3825 printf(" 'snmp_ieee' => '%s',\n", printer->snmp_ieee);
3826 }
3827 if (printer->snmp_mfg) {
3828 printf(" 'snmp_mfg' => '%s',\n", printer->snmp_mfg);
3829 }
3830 if (printer->snmp_mdl) {
3831 printf(" 'snmp_mdl' => '%s',\n", printer->snmp_mdl);
3832 }
3833 if (printer->snmp_des) {
3834 printf(" 'snmp_des' => '%s',\n", printer->snmp_des);
3835 }
3836 if (printer->snmp_cmd) {
3837 printf(" 'snmp_cmd' => '%s',\n", printer->snmp_cmd);
3838 }
3839 printf(" 'functionality' => '%s',\n",
3840 printer->functionality);
3841 if (printer->unverified) {
3842 printf(" 'unverified' => 1,\n");
3843 } else {
3844 printf(" 'unverified' => 0,\n");
3845 }
3846 if (printer->noxmlentry) {
3847 printf(" 'noxmlentry' => 1,\n");
3848 } else {
3849 printf(" 'noxmlentry' => 0,\n");
3850 }
3851 if (printer->driver) {
3852 printf(" 'driver' => '%s',\n", printer->driver);
3853 }
3854 if (printer->num_drivers > 0) {
3855 printf(" 'drivers' => [\n");
3856 for (j = 0; j < printer->num_drivers; j ++)
3857 if (printer->drivers[j]->name != NULL)
3858 printf(" '%s',\n",
3859 printer->drivers[j]->name);
3860 printf(" ],\n");
3861 printf(" 'driverproperties' => {\n");
3862 for (j = 0; j < printer->num_drivers; j ++) {
3863 for (k = 0; k < overview->num_overviewDrivers; k ++) {
3864 if (!xmlStrcmp(overview->overviewDrivers[k]->name,
3865 printer->drivers[j]->name)) break;
3866 }
3867 if ((k < overview->num_overviewDrivers) &&
3868 (!xmlStrcmp(overview->overviewDrivers[k]->name,
3869 printer->drivers[j]->name))) {
3870 printf(" '%s' => {\n",
3871 printer->drivers[j]->name);
3872 if (overview->overviewDrivers[k]->group != NULL) {
3873 printf(" 'group' => '%s',\n",
3874 overview->overviewDrivers[k]->group);
3875 }
3876 if (overview->overviewDrivers[k]->url != NULL) {
3877 printf(" 'url' => '%s',\n",
3878 overview->overviewDrivers[k]->url);
3879 }
3880 if (overview->overviewDrivers[k]->driver_obsolete != NULL) {
3881 printf(" 'obsolete' => '%s',\n",
3882 overview->overviewDrivers[k]->driver_obsolete);
3883 }
3884 if (overview->overviewDrivers[k]->supplier != NULL) {
3885 printf(" 'supplier' => '%s',\n",
3886 overview->overviewDrivers[k]->supplier);
3887 }
3888 if (overview->overviewDrivers[k]->manufacturersupplied != NULL) {
3889 printf(" 'manufacturersupplied' => '%s',\n",
3890 overview->overviewDrivers[k]->manufacturersupplied);
3891 }
3892 if (overview->overviewDrivers[k]->license != NULL) {
3893 printf(" 'license' => '%s',\n",
3894 overview->overviewDrivers[k]->license);
3895 }
3896 if (overview->overviewDrivers[k]->licensetext != NULL) {
3897 printf(" 'licensetext' => '%s',\n",
3898 overview->overviewDrivers[k]->licensetext);
3899 }
3900 if (overview->overviewDrivers[k]->origlicensetext != NULL) {
3901 printf(" 'origlicensetext' => '%s',\n",
3902 overview->overviewDrivers[k]->origlicensetext);
3903 }
3904 if (overview->overviewDrivers[k]->licenselink != NULL) {
3905 printf(" 'licenselink' => '%s',\n",
3906 overview->overviewDrivers[k]->licenselink);
3907 }
3908 if (overview->overviewDrivers[k]->origlicenselink != NULL) {
3909 printf(" 'origlicenselink' => '%s',\n",
3910 overview->overviewDrivers[k]->origlicenselink);
3911 }
3912 if (overview->overviewDrivers[k]->free != NULL) {
3913 printf(" 'free' => '%s',\n",
3914 overview->overviewDrivers[k]->free);
3915 }
3916 if (overview->overviewDrivers[k]->patents != NULL) {
3917 printf(" 'patents' => '%s',\n",
3918 overview->overviewDrivers[k]->patents);
3919 }
3920 if (overview->overviewDrivers[k]->num_supportcontacts != 0) {
3921 printf(" 'supportcontacts' => [\n");
3922 for (l = 0;
3923 l < overview->overviewDrivers[k]->num_supportcontacts; l ++) {
3924 if (overview->overviewDrivers[k]->supportcontacturls[l] !=
3925 NULL) {
3926 printf(" {\n");
3927 printf(" 'description' => '%s',\n",
3928 overview->overviewDrivers[k]->supportcontacts[l]);
3929 if (overview->overviewDrivers[k]->supportcontacturls[l]
3930 != NULL)
3931 printf(" 'url' => '%s',\n",
3932 overview->overviewDrivers[k]->supportcontacturls[l]);
3933 printf(" 'level' => '%s',\n",
3934 overview->overviewDrivers[k]->supportcontactlevels[l]);
3935 printf(" },\n");
3936 }
3937 }
3938 printf(" ],\n");
3939 }
3940 if (overview->overviewDrivers[k]->shortdescription != NULL) {
3941 printf(" 'shortdescription' => '%s',\n",
3942 overview->overviewDrivers[k]->shortdescription);
3943 }
3944 if (overview->overviewDrivers[k]->locales != NULL) {
3945 printf(" 'locales' => '%s',\n",
3946 overview->overviewDrivers[k]->locales);
3947 }
3948 if (overview->overviewDrivers[k]->num_packages != 0) {
3949 printf(" 'packages' => [\n");
3950 for (l = 0;
3951 l < overview->overviewDrivers[k]->num_packages; l ++) {
3952 if (overview->overviewDrivers[k]->packageurls[l] !=
3953 NULL) {
3954 printf(" {\n");
3955 printf(" 'url' => '%s',\n",
3956 overview->overviewDrivers[k]->packageurls[l]);
3957 if (overview->overviewDrivers[k]->packagescopes[l]
3958 != NULL)
3959 printf(" 'scope' => '%s',\n",
3960 overview->overviewDrivers[k]->packagescopes[l]);
3961 if (overview->overviewDrivers[k]->packagefingerprints[l]
3962 != NULL)
3963 printf(" 'fingerprint' => '%s',\n",
3964 overview->overviewDrivers[k]->packagefingerprints[l]);
3965 printf(" },\n");
3966 }
3967 }
3968 printf(" ],\n");
3969 }
3970 if (overview->overviewDrivers[k]->num_requires != 0) {
3971 printf(" 'requires' => [\n");
3972 for (l = 0;
3973 l < overview->overviewDrivers[k]->num_requires; l ++) {
3974 if (overview->overviewDrivers[k]->requires[l] !=
3975 NULL) {
3976 printf(" {\n");
3977 printf(" 'driver' => '%s',\n",
3978 overview->overviewDrivers[k]->requires[l]);
3979 if (overview->overviewDrivers[k]->requiresversion[l]
3980 != NULL)
3981 printf(" 'version' => '%s',\n",
3982 overview->overviewDrivers[k]->requiresversion[l]);
3983 printf(" },\n");
3984 }
3985 }
3986 printf(" ],\n");
3987 }
3988 if (overview->overviewDrivers[k]->driver_type != NULL) {
3989 printf(" 'type' => '%s',\n",
3990 overview->overviewDrivers[k]->driver_type);
3991 }
3992 if (printer->drivers[j]->excmaxresx != NULL) {
3993 printf(" 'drvmaxresx' => '%s',\n",
3994 printer->drivers[j]->excmaxresx);
3995 } else if (overview->overviewDrivers[k]->maxresx != NULL) {
3996 printf(" 'drvmaxresx' => '%s',\n",
3997 overview->overviewDrivers[k]->maxresx);
3998 }
3999 if (printer->drivers[j]->excmaxresy != NULL) {
4000 printf(" 'drvmaxresy' => '%s',\n",
4001 printer->drivers[j]->excmaxresy);
4002 } else if (overview->overviewDrivers[k]->maxresy != NULL) {
4003 printf(" 'drvmaxresy' => '%s',\n",
4004 overview->overviewDrivers[k]->maxresy);
4005 }
4006 if (printer->drivers[j]->exccolor != NULL) {
4007 printf(" 'drvcolor' => '%s',\n",
4008 printer->drivers[j]->exccolor);
4009 } else if (overview->overviewDrivers[k]->color != NULL) {
4010 printf(" 'drvcolor' => '%s',\n",
4011 overview->overviewDrivers[k]->color);
4012 }
4013 if (printer->drivers[j]->exctext != NULL) {
4014 printf(" 'text' => '%s',\n",
4015 printer->drivers[j]->exctext);
4016 } else if (overview->overviewDrivers[k]->text != NULL) {
4017 printf(" 'text' => '%s',\n",
4018 overview->overviewDrivers[k]->text);
4019 }
4020 if (printer->drivers[j]->exclineart != NULL) {
4021 printf(" 'lineart' => '%s',\n",
4022 printer->drivers[j]->exclineart);
4023 } else if (overview->overviewDrivers[k]->lineart != NULL) {
4024 printf(" 'lineart' => '%s',\n",
4025 overview->overviewDrivers[k]->lineart);
4026 }
4027 if (printer->drivers[j]->excgraphics != NULL) {
4028 printf(" 'graphics' => '%s',\n",
4029 printer->drivers[j]->excgraphics);
4030 } else if (overview->overviewDrivers[k]->graphics != NULL) {
4031 printf(" 'graphics' => '%s',\n",
4032 overview->overviewDrivers[k]->graphics);
4033 }
4034 if (printer->drivers[j]->excphoto != NULL) {
4035 printf(" 'photo' => '%s',\n",
4036 printer->drivers[j]->excphoto);
4037 } else if (overview->overviewDrivers[k]->photo != NULL) {
4038 printf(" 'photo' => '%s',\n",
4039 overview->overviewDrivers[k]->photo);
4040 }
4041 if (printer->drivers[j]->excload != NULL) {
4042 printf(" 'load' => '%s',\n",
4043 printer->drivers[j]->excload);
4044 } else if (overview->overviewDrivers[k]->load != NULL) {
4045 printf(" 'load' => '%s',\n",
4046 overview->overviewDrivers[k]->load);
4047 }
4048 if (printer->drivers[j]->excspeed != NULL) {
4049 printf(" 'speed' => '%s',\n",
4050 printer->drivers[j]->excspeed);
4051 } else if (overview->overviewDrivers[k]->speed != NULL) {
4052 printf(" 'speed' => '%s',\n",
4053 overview->overviewDrivers[k]->speed);
4054 }
4055 printf(" },\n");
4056 }
4057 }
4058 printf(" },\n");
4059 } else {
4060 printf(" 'drivers' => [],\n");
4061 }
4062 if (printer->num_ppdfiles > 0) {
4063 printf(" 'ppds' => [\n");
4064 for (j = 0; j < printer->num_ppdfiles; j ++)
4065 if ((printer->ppdfiles[j]->driver != NULL) &&
4066 (printer->ppdfiles[j]->filename != NULL)) {
4067 printf(" {\n");
4068 printf(" 'driver' => '%s',\n",
4069 printer->ppdfiles[j]->driver);
4070 printf(" 'ppdfile' => '%s',\n",
4071 printer->ppdfiles[j]->filename);
4072 printf(" },\n");
4073 }
4074 printf(" ],\n");
4075 }
4076 printf(" },\n");
4077 }
4078 printf(" ];\n");
4079
4080 }
4081
4082 void
generateMarginsPerlData(marginsPtr margins,int debug)4083 generateMarginsPerlData(marginsPtr margins, /* I/O - Foomatic margins data
4084 parsed from XML input */
4085 int debug) { /* Debug flag */
4086
4087 int i; /* loop variable */
4088
4089 for (i = 0; i < margins->num_marginRecords; i ++) {
4090 if (margins->marginRecords[i]->pagesize) {
4091 printf(" '%s' => {\n", margins->marginRecords[i]->pagesize);
4092 } else {
4093 printf(" '_general' => {\n");
4094 }
4095 if (margins->marginRecords[i]->unit) {
4096 printf(" 'unit' => '%s',\n", margins->marginRecords[i]->unit);
4097 }
4098 if (margins->marginRecords[i]->absolute) {
4099 printf(" 'absolute' => '%s',\n",
4100 margins->marginRecords[i]->absolute);
4101 }
4102 if (margins->marginRecords[i]->left) {
4103 printf(" 'left' => '%s',\n", margins->marginRecords[i]->left);
4104 }
4105 if (margins->marginRecords[i]->right) {
4106 printf(" 'right' => '%s',\n", margins->marginRecords[i]->right);
4107 }
4108 if (margins->marginRecords[i]->top) {
4109 printf(" 'top' => '%s',\n", margins->marginRecords[i]->top);
4110 }
4111 if (margins->marginRecords[i]->bottom) {
4112 printf(" 'bottom' => '%s',\n", margins->marginRecords[i]->bottom);
4113 }
4114 printf(" },\n");
4115 }
4116 }
4117
4118 xmlChar const sc_Postscript [] = "Postscript";
4119
4120 void
generateComboPerlData(comboDataPtr combo,int debug)4121 generateComboPerlData(comboDataPtr combo, /* I/O - Foomatic combo data
4122 parsed from XML input */
4123 int debug) { /* Debug flag */
4124
4125 int i, j; /* loop variables */
4126 int haspsdriver = 0; /* Is the "Postscript" driver in the printer's
4127 driver list? */
4128
4129 printf("$VAR1 = {\n");
4130 printf(" 'id' => '%s',\n", combo->id);
4131 printf(" 'make' => '%s',\n", combo->make);
4132 printf(" 'model' => '%s',\n", combo->model);
4133 if (combo->recdriver) {
4134 printf(" 'recdriver' => '%s',\n", combo->recdriver);
4135 } else {
4136 printf(" 'recdriver' => undef,\n");
4137 }
4138 if ((combo->num_drivers > 0) || (combo->ppdurl)) {
4139 printf(" 'drivers' => [\n");
4140 for (i = 0; i < combo->num_drivers; i ++) {
4141 printf(" {\n");
4142 if (combo->drivers[i]->name) {
4143 if (xmlStrncmp(combo->drivers[i]->name, sc_Postscript, 10))
4144 haspsdriver = 1;
4145 printf(" 'name' => '%s',\n",
4146 combo->drivers[i]->name);
4147 printf(" 'id' => '%s',\n",
4148 combo->drivers[i]->name);
4149 }
4150 if (combo->drivers[i]->ppd) {
4151 printf(" 'ppd' => '%s',\n",
4152 combo->drivers[i]->ppd);
4153 }
4154 if (combo->drivers[i]->comment) {
4155 printf(" 'comment' => '%s',\n",
4156 combo->drivers[i]->comment);
4157 }
4158 printf(" },\n");
4159 }
4160 if ((combo->ppdurl) && !haspsdriver) {
4161 printf(" {\n");
4162 printf(" 'name' => '%s',\n",
4163 "Postscript");
4164 printf(" 'id' => '%s',\n",
4165 "Postscript");
4166 printf(" 'ppd' => '%s',\n",
4167 combo->ppdurl);
4168 printf(" },\n");
4169 }
4170 printf(" ],\n");
4171 }
4172 if (combo->pcmodel) {
4173 printf(" 'pcmodel' => '%s',\n", combo->pcmodel);
4174 } else {
4175 printf(" 'pcmodel' => undef,\n");
4176 }
4177 if (combo->ppdurl) {
4178 printf(" 'ppdurl' => '%s',\n", combo->ppdurl);
4179 }
4180 printf(" 'color' => %s,\n", combo->color);
4181 printf(" 'ascii' => %s,\n", combo->ascii);
4182 printf(" 'pjl' => %s,\n", combo->pjl);
4183 if (combo->printerppdentry) {
4184 printf(" 'printerppdentry' => '%s',\n", combo->printerppdentry);
4185 } else {
4186 printf(" 'printerppdentry' => undef,\n");
4187 }
4188 if (combo->printermargins) {
4189 printf(" 'printermargins' => {\n");
4190 generateMarginsPerlData(combo->printermargins, debug);
4191 printf(" },\n");
4192 }
4193 if (combo->general_ieee) {
4194 printf(" 'pnp_ieee' => '%s',\n", combo->general_ieee);
4195 printf(" 'general_ieee' => '%s',\n", combo->general_ieee);
4196 } else {
4197 printf(" 'pnp_ieee' => undef,\n");
4198 printf(" 'general_ieee' => undef,\n");
4199 }
4200 if (combo->general_mfg) {
4201 printf(" 'pnp_mfg' => '%s',\n", combo->general_mfg);
4202 printf(" 'general_mfg' => '%s',\n", combo->general_mfg);
4203 } else {
4204 printf(" 'pnp_mfg' => undef,\n");
4205 printf(" 'general_mfg' => undef,\n");
4206 }
4207 if (combo->general_mdl) {
4208 printf(" 'pnp_mdl' => '%s',\n", combo->general_mdl);
4209 printf(" 'general_mdl' => '%s',\n", combo->general_mdl);
4210 } else {
4211 printf(" 'pnp_mdl' => undef,\n");
4212 printf(" 'general_mdl' => undef,\n");
4213 }
4214 if (combo->general_des) {
4215 printf(" 'pnp_des' => '%s',\n", combo->general_des);
4216 printf(" 'general_des' => '%s',\n", combo->general_des);
4217 } else {
4218 printf(" 'pnp_des' => undef,\n");
4219 printf(" 'general_des' => undef,\n");
4220 }
4221 if (combo->general_cmd) {
4222 printf(" 'pnp_cmd' => '%s',\n", combo->general_cmd);
4223 printf(" 'general_cmd' => '%s',\n", combo->general_cmd);
4224 } else {
4225 printf(" 'pnp_cmd' => undef,\n");
4226 printf(" 'general_cmd' => undef,\n");
4227 }
4228 if (combo->par_ieee) {
4229 printf(" 'par_ieee' => '%s',\n", combo->par_ieee);
4230 } else {
4231 printf(" 'par_ieee' => undef,\n");
4232 }
4233 if (combo->par_mfg) {
4234 printf(" 'par_mfg' => '%s',\n", combo->par_mfg);
4235 } else {
4236 printf(" 'par_mfg' => undef,\n");
4237 }
4238 if (combo->par_mdl) {
4239 printf(" 'par_mdl' => '%s',\n", combo->par_mdl);
4240 } else {
4241 printf(" 'par_mdl' => undef,\n");
4242 }
4243 if (combo->par_des) {
4244 printf(" 'par_des' => '%s',\n", combo->par_des);
4245 } else {
4246 printf(" 'par_des' => undef,\n");
4247 }
4248 if (combo->par_cmd) {
4249 printf(" 'par_cmd' => '%s',\n", combo->par_cmd);
4250 } else {
4251 printf(" 'par_cmd' => undef,\n");
4252 }
4253 if (combo->usb_ieee) {
4254 printf(" 'usb_ieee' => '%s',\n", combo->usb_ieee);
4255 } else {
4256 printf(" 'usb_ieee' => undef,\n");
4257 }
4258 if (combo->usb_mfg) {
4259 printf(" 'usb_mfg' => '%s',\n", combo->usb_mfg);
4260 } else {
4261 printf(" 'usb_mfg' => undef,\n");
4262 }
4263 if (combo->usb_mdl) {
4264 printf(" 'usb_mdl' => '%s',\n", combo->usb_mdl);
4265 } else {
4266 printf(" 'usb_mdl' => undef,\n");
4267 }
4268 if (combo->usb_des) {
4269 printf(" 'usb_des' => '%s',\n", combo->usb_des);
4270 } else {
4271 printf(" 'usb_des' => undef,\n");
4272 }
4273 if (combo->usb_cmd) {
4274 printf(" 'usb_cmd' => '%s',\n", combo->usb_cmd);
4275 } else {
4276 printf(" 'usb_cmd' => undef,\n");
4277 }
4278 if (combo->snmp_ieee) {
4279 printf(" 'snmp_ieee' => '%s',\n", combo->snmp_ieee);
4280 } else {
4281 printf(" 'snmp_ieee' => undef,\n");
4282 }
4283 if (combo->snmp_mfg) {
4284 printf(" 'snmp_mfg' => '%s',\n", combo->snmp_mfg);
4285 } else {
4286 printf(" 'snmp_mfg' => undef,\n");
4287 }
4288 if (combo->snmp_mdl) {
4289 printf(" 'snmp_mdl' => '%s',\n", combo->snmp_mdl);
4290 } else {
4291 printf(" 'snmp_mdl' => undef,\n");
4292 }
4293 if (combo->snmp_des) {
4294 printf(" 'snmp_des' => '%s',\n", combo->snmp_des);
4295 } else {
4296 printf(" 'snmp_des' => undef,\n");
4297 }
4298 if (combo->snmp_cmd) {
4299 printf(" 'snmp_cmd' => '%s',\n", combo->snmp_cmd);
4300 } else {
4301 printf(" 'snmp_cmd' => undef,\n");
4302 }
4303 printf(" 'driver' => '%s',\n", combo->driver);
4304 if (combo->driver_group) {
4305 printf(" 'group' => '%s',\n", combo->driver_group);
4306 }
4307 if (combo->pcdriver) {
4308 printf(" 'pcdriver' => '%s',\n", combo->pcdriver);
4309 } else {
4310 printf(" 'pcdriver' => undef,\n");
4311 }
4312 printf(" 'type' => '%s',\n", combo->driver_type);
4313 if (combo->driver_comment) {
4314 printf(" 'comment' => '%s',\n", combo->driver_comment);
4315 } else {
4316 printf(" 'comment' => undef,\n");
4317 }
4318 if (combo->url) {
4319 printf(" 'url' => '%s',\n", combo->url);
4320 } else {
4321 printf(" 'url' => undef,\n");
4322 }
4323 if (combo->driver_obsolete) {
4324 printf(" 'obsolete' => '%s',\n", combo->driver_obsolete);
4325 }
4326 if (combo->supplier != NULL) {
4327 printf(" 'supplier' => '%s',\n",
4328 combo->supplier);
4329 }
4330 if (combo->manufacturersupplied != NULL) {
4331 printf(" 'manufacturersupplied' => '%s',\n",
4332 combo->manufacturersupplied);
4333 }
4334 if (combo->license != NULL) {
4335 printf(" 'license' => '%s',\n",
4336 combo->license);
4337 }
4338 if (combo->licensetext != NULL) {
4339 printf(" 'licensetext' => '%s',\n",
4340 combo->licensetext);
4341 }
4342 if (combo->origlicensetext != NULL) {
4343 printf(" 'origlicensetext' => '%s',\n",
4344 combo->origlicensetext);
4345 }
4346 if (combo->licenselink != NULL) {
4347 printf(" 'licenselink' => '%s',\n",
4348 combo->licenselink);
4349 }
4350 if (combo->origlicenselink != NULL) {
4351 printf(" 'origlicenselink' => '%s',\n",
4352 combo->origlicenselink);
4353 }
4354 if (combo->free != NULL) {
4355 printf(" 'free' => '%s',\n",
4356 combo->free);
4357 }
4358 if (combo->patents != NULL) {
4359 printf(" 'patents' => '%s',\n",
4360 combo->patents);
4361 }
4362 if (combo->num_supportcontacts != 0) {
4363 printf(" 'supportcontacts' => [\n");
4364 for (i = 0;
4365 i < combo->num_supportcontacts; i ++) {
4366 if (combo->supportcontacturls[i] !=
4367 NULL) {
4368 printf(" {\n");
4369 printf(" 'description' => '%s',\n",
4370 combo->supportcontacts[i]);
4371 if (combo->supportcontacturls[i]
4372 != NULL)
4373 printf(" 'url' => '%s',\n",
4374 combo->supportcontacturls[i]);
4375 printf(" 'level' => '%s',\n",
4376 combo->supportcontactlevels[i]);
4377 printf(" },\n");
4378 }
4379 }
4380 printf(" ],\n");
4381 }
4382 if (combo->shortdescription != NULL) {
4383 printf(" 'shortdescription' => '%s',\n",
4384 combo->shortdescription);
4385 }
4386 if (combo->locales != NULL) {
4387 printf(" 'locales' => '%s',\n",
4388 combo->locales);
4389 }
4390 if (combo->num_packages != 0) {
4391 printf(" 'packages' => [\n");
4392 for (i = 0;
4393 i < combo->num_packages; i ++) {
4394 if (combo->packageurls[i] !=
4395 NULL) {
4396 printf(" {\n");
4397 printf(" 'url' => '%s',\n",
4398 combo->packageurls[i]);
4399 if (combo->packagescopes[i]
4400 != NULL)
4401 printf(" 'scope' => '%s',\n",
4402 combo->packagescopes[i]);
4403 if (combo->packagefingerprints[i]
4404 != NULL)
4405 printf(" 'fingerprint' => '%s',\n",
4406 combo->packagefingerprints[i]);
4407 printf(" },\n");
4408 }
4409 }
4410 printf(" ],\n");
4411 }
4412 if (combo->excmaxresx != NULL) {
4413 printf(" 'drvmaxresx' => '%s',\n",
4414 combo->excmaxresx);
4415 } else if (combo->drvmaxresx != NULL) {
4416 printf(" 'drvmaxresx' => '%s',\n",
4417 combo->drvmaxresx);
4418 }
4419 if (combo->excmaxresy != NULL) {
4420 printf(" 'drvmaxresy' => '%s',\n",
4421 combo->excmaxresy);
4422 } else if (combo->drvmaxresy != NULL) {
4423 printf(" 'drvmaxresy' => '%s',\n",
4424 combo->drvmaxresy);
4425 }
4426 if (combo->exccolor != NULL) {
4427 printf(" 'drvcolor' => '%s',\n",
4428 combo->exccolor);
4429 } else if (combo->drvcolor != NULL) {
4430 printf(" 'drvcolor' => '%s',\n",
4431 combo->drvcolor);
4432 }
4433 if (combo->exctext != NULL) {
4434 printf(" 'text' => '%s',\n",
4435 combo->exctext);
4436 } else if (combo->text != NULL) {
4437 printf(" 'text' => '%s',\n",
4438 combo->text);
4439 }
4440 if (combo->exclineart != NULL) {
4441 printf(" 'lineart' => '%s',\n",
4442 combo->exclineart);
4443 } else if (combo->lineart != NULL) {
4444 printf(" 'lineart' => '%s',\n",
4445 combo->lineart);
4446 }
4447 if (combo->excgraphics != NULL) {
4448 printf(" 'graphics' => '%s',\n",
4449 combo->excgraphics);
4450 } else if (combo->graphics != NULL) {
4451 printf(" 'graphics' => '%s',\n",
4452 combo->graphics);
4453 }
4454 if (combo->excphoto != NULL) {
4455 printf(" 'photo' => '%s',\n",
4456 combo->excphoto);
4457 } else if (combo->photo != NULL) {
4458 printf(" 'photo' => '%s',\n",
4459 combo->photo);
4460 }
4461 if (combo->excload != NULL) {
4462 printf(" 'load' => '%s',\n",
4463 combo->excload);
4464 } else if (combo->load != NULL) {
4465 printf(" 'load' => '%s',\n",
4466 combo->load);
4467 }
4468 if (combo->excspeed != NULL) {
4469 printf(" 'speed' => '%s',\n",
4470 combo->excspeed);
4471 } else if (combo->speed != NULL) {
4472 printf(" 'speed' => '%s',\n",
4473 combo->speed);
4474 }
4475 if (combo->num_requires != 0) {
4476 printf(" 'requires' => [\n");
4477 for (i = 0;
4478 i < combo->num_requires; i ++) {
4479 if (combo->requires[i] !=
4480 NULL) {
4481 printf(" {\n");
4482 printf(" 'driver' => '%s',\n",
4483 combo->requires[i]);
4484 if (combo->requiresversion[i]
4485 != NULL)
4486 printf(" 'version' => '%s',\n",
4487 combo->requiresversion[i]);
4488 printf(" },\n");
4489 }
4490 }
4491 printf(" ],\n");
4492 }
4493 if (combo->cmd) {
4494 printf(" 'cmd' => '%s',\n", combo->cmd);
4495 } else {
4496 printf(" 'cmd' => undef,\n");
4497 }
4498 if (combo->cmd_pdf) {
4499 printf(" 'cmd_pdf' => '%s',\n", combo->cmd_pdf);
4500 } else {
4501 printf(" 'cmd_pdf' => undef,\n");
4502 }
4503 if (combo->nopjl) {
4504 printf(" 'drivernopjl' => %s,\n", combo->nopjl);
4505 } else {
4506 printf(" 'drivernopjl' => 0,\n");
4507 }
4508 if (combo->nopageaccounting) {
4509 printf(" 'drivernopageaccounting' => %s,\n", combo->nopageaccounting);
4510 } else {
4511 printf(" 'drivernopageaccounting' => 0,\n");
4512 }
4513 if (combo->driverppdentry) {
4514 printf(" 'driverppdentry' => '%s',\n", combo->driverppdentry);
4515 } else {
4516 printf(" 'driverppdentry' => undef,\n");
4517 }
4518 if (combo->comboppdentry) {
4519 printf(" 'comboppdentry' => '%s',\n", combo->comboppdentry);
4520 } else {
4521 printf(" 'comboppdentry' => undef,\n");
4522 }
4523 if (combo->drivermargins) {
4524 printf(" 'drivermargins' => {\n");
4525 generateMarginsPerlData(combo->drivermargins, debug);
4526 printf(" },\n");
4527 }
4528 if (combo->combomargins) {
4529 printf(" 'combomargins' => {\n");
4530 generateMarginsPerlData(combo->combomargins, debug);
4531 printf(" },\n");
4532 }
4533 if (combo->maxspot > 0) {
4534 printf(" 'maxspot' => '%s',\n", combo->maxspot);
4535 } else {
4536 printf(" 'maxspot' => 'A',\n");
4537 }
4538 printf(" 'args_byname' => {\n");
4539 for (i = 0; i < combo->num_args; i ++) {
4540 printf(" '%s' => {},\n", combo->args[i]->name);
4541 }
4542 printf(" },\n");
4543 printf(" 'args' => [\n");
4544 for (i = 0; i < combo->num_args; i ++) {
4545 printf(" {\n");
4546 printf(" 'name' => '%s',\n", combo->args[i]->name);
4547 if (combo->args[i]->name_false) {
4548 printf(" 'name_false' => '%s',\n", combo->args[i]->name_false);
4549 }
4550 printf(" 'comment' => '%s',\n", combo->args[i]->comment);
4551 printf(" 'idx' => '%s',\n", combo->args[i]->idx);
4552 printf(" 'type' => '%s',\n", combo->args[i]->option_type);
4553 printf(" 'style' => '%s',\n", combo->args[i]->style);
4554 if (combo->args[i]->substyle) {
4555 printf(" 'substyle' => '%s',\n", combo->args[i]->substyle);
4556 }
4557 printf(" 'spot' => '%s',\n", combo->args[i]->spot);
4558 printf(" 'order' => '%s',\n", combo->args[i]->order);
4559 if (combo->args[i]->section) {
4560 printf(" 'section' => '%s',\n", combo->args[i]->section);
4561 }
4562 if (combo->args[i]->grouppath) {
4563 printf(" 'group' => '%s',\n", combo->args[i]->grouppath);
4564 }
4565 if (combo->args[i]->proto) {
4566 printf(" 'proto' => '%s',\n", combo->args[i]->proto);
4567 }
4568 if (combo->args[i]->required) {
4569 printf(" 'required' => 1,\n");
4570 }
4571 if (combo->args[i]->min_value) {
4572 printf(" 'min' => '%s',\n", combo->args[i]->min_value);
4573 }
4574 if (combo->args[i]->max_value) {
4575 printf(" 'max' => '%s',\n", combo->args[i]->max_value);
4576 }
4577 if (combo->args[i]->max_length) {
4578 printf(" 'maxlength' => '%s',\n", combo->args[i]->max_length);
4579 }
4580 if (combo->args[i]->allowed_chars) {
4581 printf(" 'allowedchars' => '%s',\n", combo->args[i]->allowed_chars);
4582 }
4583 if (combo->args[i]->allowed_regexp) {
4584 printf(" 'allowedregexp' => '%s',\n",
4585 combo->args[i]->allowed_regexp);
4586 }
4587 if (combo->args[i]->default_value) {
4588 printf(" 'default' => '%s',\n", combo->args[i]->default_value);
4589 } else {
4590 printf(" 'default' => 'None',\n");
4591 }
4592 if (combo->args[i]->num_choices > 0) {
4593 printf(" 'vals_byname' => {\n");
4594 for (j = 0; j < combo->args[i]->num_choices; j ++) {
4595 if (combo->args[i]->choices[j]->value == NULL) {
4596 static xmlChar sc_None [] = "None";
4597 combo->args[i]->choices[j]->value = sc_None;
4598 }
4599 printf(" '%s' => {\n", combo->args[i]->choices[j]->value);
4600 printf(" 'value' => '%s',\n",
4601 combo->args[i]->choices[j]->value);
4602 if (combo->args[i]->choices[j]->comment) {
4603 printf(" 'comment' => '%s',\n",
4604 combo->args[i]->choices[j]->comment);
4605 }
4606 printf(" 'idx' => '%s',\n",
4607 combo->args[i]->choices[j]->idx);
4608 if (combo->args[i]->choices[j]->driverval) {
4609 printf(" 'driverval' => '%s'\n",
4610 combo->args[i]->choices[j]->driverval);
4611 } else {
4612 printf(" 'driverval' => ''\n");
4613 }
4614 printf(" },\n");
4615 }
4616 printf(" },\n");
4617 printf(" 'vals' => [\n");
4618 for (j = 0; j < combo->args[i]->num_choices; j ++) {
4619 printf(" {},\n");
4620 }
4621 printf(" ]\n");
4622 }
4623 printf(" },\n");
4624 }
4625 printf(" ]\n");
4626 printf("};\n");
4627 for (i = 0; i < combo->num_args; i ++) {
4628 for (j = 0; j < combo->args[i]->num_choices; j ++) {
4629 printf("$VAR1->{'args'}[%d]{'vals'}[%d] = $VAR1->{'args'}[%d]{'vals_byname'}{'%s'};\n",
4630 i, j, i, combo->args[i]->choices[j]->value);
4631 }
4632 }
4633 for (i = 0; i < combo->num_args; i ++) {
4634 printf("$VAR1->{'args_byname'}{'%s'} = $VAR1->{'args'}[%d];\n",
4635 combo->args[i]->name, i);
4636 }
4637
4638 }
4639
4640 void
generatePrinterPerlData(printerEntryPtr printer,int debug)4641 generatePrinterPerlData(printerEntryPtr printer, /* I/O - Foomatic printer
4642 data parsed from XML
4643 input */
4644 int debug) { /* Debug flag */
4645
4646 int i; /* loop variable */
4647 int haspsdriver = 0; /* Is the "Postscript" driver in the printer's
4648 driver list? */
4649
4650 printf("$VAR1 = {\n");
4651 printf(" 'id' => '%s',\n", printer->id);
4652 printf(" 'make' => '%s',\n", printer->make);
4653 printf(" 'model' => '%s',\n", printer->model);
4654 if (printer->printer_type) {
4655 printf(" 'type' => '%s',\n", printer->printer_type);
4656 }
4657 if (printer->color) {
4658 printf(" 'color' => '%s',\n", printer->color);
4659 }
4660 if (printer->maxxres) {
4661 printf(" 'maxxres' => '%s',\n", printer->maxxres);
4662 }
4663 if (printer->maxyres) {
4664 printf(" 'maxyres' => '%s',\n", printer->maxyres);
4665 }
4666 if (printer->printerppdentry) {
4667 printf(" 'ppdentry' => '%s',\n", printer->printerppdentry);
4668 } else {
4669 printf(" 'ppdentry' => undef,\n");
4670 }
4671 if (printer->printermargins) {
4672 printf(" 'margins' => {\n");
4673 generateMarginsPerlData(printer->printermargins, debug);
4674 printf(" },\n");
4675 }
4676 if (printer->refill) {
4677 printf(" 'refill' => '%s',\n", printer->refill);
4678 }
4679 if (printer->ascii) {
4680 printf(" 'ascii' => '%s',\n", printer->ascii);
4681 }
4682 if (printer->pjl) {
4683 printf(" 'pjl' => '%s',\n", printer->pjl);
4684 }
4685 if (printer->num_languages > 0) {
4686 printf(" 'languages' => [\n");
4687 for (i = 0; i < printer->num_languages; i ++) {
4688 printf(" {\n");
4689 printf(" 'name' => '%s',\n",
4690 printer->languages[i]->name);
4691 printf(" 'level' => '%s',\n",
4692 printer->languages[i]->level);
4693 printf(" },\n");
4694 }
4695 printf(" ],\n");
4696 }
4697 if (printer->ppdurl) {
4698 printf(" 'ppdurl' => '%s',\n", printer->ppdurl);
4699 }
4700 if (printer->general_ieee) {
4701 printf(" 'general_ieee' => '%s',\n", printer->general_ieee);
4702 }
4703 if (printer->general_mfg) {
4704 printf(" 'general_mfg' => '%s',\n", printer->general_mfg);
4705 }
4706 if (printer->general_mdl) {
4707 printf(" 'general_mdl' => '%s',\n", printer->general_mdl);
4708 }
4709 if (printer->general_des) {
4710 printf(" 'general_des' => '%s',\n", printer->general_des);
4711 }
4712 if (printer->general_cmd) {
4713 printf(" 'general_cmd' => '%s',\n", printer->general_cmd);
4714 }
4715 if (printer->par_ieee) {
4716 printf(" 'par_ieee' => '%s',\n", printer->par_ieee);
4717 }
4718 if (printer->par_mfg) {
4719 printf(" 'par_mfg' => '%s',\n", printer->par_mfg);
4720 }
4721 if (printer->par_mdl) {
4722 printf(" 'par_mdl' => '%s',\n", printer->par_mdl);
4723 }
4724 if (printer->par_des) {
4725 printf(" 'par_des' => '%s',\n", printer->par_des);
4726 }
4727 if (printer->par_cmd) {
4728 printf(" 'par_cmd' => '%s',\n", printer->par_cmd);
4729 }
4730 if (printer->usb_ieee) {
4731 printf(" 'usb_ieee' => '%s',\n", printer->usb_ieee);
4732 }
4733 if (printer->usb_mfg) {
4734 printf(" 'usb_mfg' => '%s',\n", printer->usb_mfg);
4735 }
4736 if (printer->usb_mdl) {
4737 printf(" 'usb_mdl' => '%s',\n", printer->usb_mdl);
4738 }
4739 if (printer->usb_des) {
4740 printf(" 'usb_des' => '%s',\n", printer->usb_des);
4741 }
4742 if (printer->usb_cmd) {
4743 printf(" 'usb_cmd' => '%s',\n", printer->usb_cmd);
4744 }
4745 if (printer->snmp_ieee) {
4746 printf(" 'snmp_ieee' => '%s',\n", printer->snmp_ieee);
4747 }
4748 if (printer->snmp_mfg) {
4749 printf(" 'snmp_mfg' => '%s',\n", printer->snmp_mfg);
4750 }
4751 if (printer->snmp_mdl) {
4752 printf(" 'snmp_mdl' => '%s',\n", printer->snmp_mdl);
4753 }
4754 if (printer->snmp_des) {
4755 printf(" 'snmp_des' => '%s',\n", printer->snmp_des);
4756 }
4757 if (printer->snmp_cmd) {
4758 printf(" 'snmp_cmd' => '%s',\n", printer->snmp_cmd);
4759 }
4760 if (printer->functionality) {
4761 printf(" 'functionality' => '%s',\n", printer->functionality);
4762 }
4763 if (printer->driver) {
4764 printf(" 'driver' => '%s',\n", printer->driver);
4765 }
4766 if ((printer->num_drivers > 0) || (printer->ppdurl)) {
4767 printf(" 'drivers' => [\n");
4768 for (i = 0; i < printer->num_drivers; i ++) {
4769 printf(" {\n");
4770 if (printer->drivers[i]->name) {
4771 if (xmlStrncmp(printer->drivers[i]->name, sc_Postscript, 10))
4772 haspsdriver = 1;
4773 printf(" 'name' => '%s',\n",
4774 printer->drivers[i]->name);
4775 printf(" 'id' => '%s',\n",
4776 printer->drivers[i]->name);
4777 }
4778 if (printer->drivers[i]->ppd) {
4779 printf(" 'ppd' => '%s',\n",
4780 printer->drivers[i]->ppd);
4781 }
4782 if (printer->drivers[i]->comment) {
4783 printf(" 'comment' => '%s',\n",
4784 printer->drivers[i]->comment);
4785 }
4786 printf(" },\n");
4787 }
4788 if ((printer->ppdurl) && !haspsdriver) {
4789 printf(" {\n");
4790 printf(" 'name' => '%s',\n",
4791 "Postscript");
4792 printf(" 'id' => '%s',\n",
4793 "Postscript");
4794 printf(" 'ppd' => '%s',\n",
4795 printer->ppdurl);
4796 printf(" },\n");
4797 }
4798 printf(" ],\n");
4799 }
4800 if (printer->unverified) {
4801 printf(" 'unverified' => '%s',\n", printer->unverified);
4802 }
4803 if (printer->noxmlentry) {
4804 printf(" 'noxmlentry' => '%s',\n", printer->noxmlentry);
4805 }
4806 if (printer->url) {
4807 printf(" 'url' => '%s',\n", printer->url);
4808 }
4809 if (printer->contriburl) {
4810 printf(" 'contriburl' => '%s',\n", printer->contriburl);
4811 }
4812 if (printer->comment) {
4813 printf(" 'comment' => '%s',\n", printer->comment);
4814 }
4815 printf("};\n");
4816
4817 }
4818
4819 void
generateDriverPerlData(driverEntryPtr driver,int debug)4820 generateDriverPerlData(driverEntryPtr driver, /* I/O - Foomatic driver
4821 data parsed from XML
4822 input */
4823 int debug) { /* Debug flag */
4824
4825 int i; /* loop variable */
4826
4827 xmlChar *id;
4828 xmlChar *name;
4829 xmlChar *url;
4830 xmlChar *driver_type;
4831 xmlChar *cmd;
4832 xmlChar *comment;
4833 int num_printers;
4834 xmlChar **printers;
4835 printf("$VAR1 = {\n");
4836 printf(" 'name' => '%s',\n", driver->name);
4837 if (driver->group) {
4838 printf(" 'group' => '%s',\n", driver->group);
4839 }
4840 if (driver->url) {
4841 printf(" 'url' => '%s',\n", driver->url);
4842 }
4843 if (driver->driver_obsolete) {
4844 printf(" 'obsolete' => '%s',\n", driver->driver_obsolete);
4845 }
4846 if (driver->supplier != NULL) {
4847 printf(" 'supplier' => '%s',\n",
4848 driver->supplier);
4849 }
4850 if (driver->manufacturersupplied != NULL) {
4851 printf(" 'manufacturersupplied' => '%s',\n",
4852 driver->manufacturersupplied);
4853 }
4854 if (driver->license != NULL) {
4855 printf(" 'license' => '%s',\n",
4856 driver->license);
4857 }
4858 if (driver->licensetext != NULL) {
4859 printf(" 'licensetext' => '%s',\n",
4860 driver->licensetext);
4861 }
4862 if (driver->origlicensetext != NULL) {
4863 printf(" 'origlicensetext' => '%s',\n",
4864 driver->origlicensetext);
4865 }
4866 if (driver->licenselink != NULL) {
4867 printf(" 'licenselink' => '%s',\n",
4868 driver->licenselink);
4869 }
4870 if (driver->origlicenselink != NULL) {
4871 printf(" 'origlicenselink' => '%s',\n",
4872 driver->origlicenselink);
4873 }
4874 if (driver->free != NULL) {
4875 printf(" 'free' => '%s',\n",
4876 driver->free);
4877 }
4878 if (driver->patents != NULL) {
4879 printf(" 'patents' => '%s',\n",
4880 driver->patents);
4881 }
4882 if (driver->num_supportcontacts != 0) {
4883 printf(" 'supportcontacts' => [\n");
4884 for (i = 0;
4885 i < driver->num_supportcontacts; i ++) {
4886 if (driver->supportcontacturls[i] !=
4887 NULL) {
4888 printf(" {\n");
4889 printf(" 'description' => '%s',\n",
4890 driver->supportcontacts[i]);
4891 if (driver->supportcontacturls[i]
4892 != NULL)
4893 printf(" 'url' => '%s',\n",
4894 driver->supportcontacturls[i]);
4895 printf(" 'level' => '%s',\n",
4896 driver->supportcontactlevels[i]);
4897 printf(" },\n");
4898 }
4899 }
4900 printf(" ],\n");
4901 }
4902 if (driver->shortdescription != NULL) {
4903 printf(" 'shortdescription' => '%s',\n",
4904 driver->shortdescription);
4905 }
4906 if (driver->locales != NULL) {
4907 printf(" 'locales' => '%s',\n",
4908 driver->locales);
4909 }
4910 if (driver->num_packages != 0) {
4911 printf(" 'packages' => [\n");
4912 for (i = 0;
4913 i < driver->num_packages; i ++) {
4914 if (driver->packageurls[i] !=
4915 NULL) {
4916 printf(" {\n");
4917 printf(" 'url' => '%s',\n",
4918 driver->packageurls[i]);
4919 if (driver->packagescopes[i]
4920 != NULL)
4921 printf(" 'scope' => '%s',\n",
4922 driver->packagescopes[i]);
4923 if (driver->packagefingerprints[i]
4924 != NULL)
4925 printf(" 'fingerprint' => '%s',\n",
4926 driver->packagefingerprints[i]);
4927 printf(" },\n");
4928 }
4929 }
4930 printf(" ],\n");
4931 }
4932 if (driver->maxresx != NULL) {
4933 printf(" 'drvmaxresx' => '%s',\n",
4934 driver->maxresx);
4935 }
4936 if (driver->maxresy != NULL) {
4937 printf(" 'drvmaxresy' => '%s',\n",
4938 driver->maxresy);
4939 }
4940 if (driver->color != NULL) {
4941 printf(" 'drvcolor' => '%s',\n",
4942 driver->color);
4943 }
4944 if (driver->text != NULL) {
4945 printf(" 'text' => '%s',\n",
4946 driver->text);
4947 }
4948 if (driver->lineart != NULL) {
4949 printf(" 'lineart' => '%s',\n",
4950 driver->lineart);
4951 }
4952 if (driver->graphics != NULL) {
4953 printf(" 'graphics' => '%s',\n",
4954 driver->graphics);
4955 }
4956 if (driver->photo != NULL) {
4957 printf(" 'photo' => '%s',\n",
4958 driver->photo);
4959 }
4960 if (driver->load != NULL) {
4961 printf(" 'load' => '%s',\n",
4962 driver->load);
4963 }
4964 if (driver->speed != NULL) {
4965 printf(" 'speed' => '%s',\n",
4966 driver->speed);
4967 }
4968 if (driver->num_requires != 0) {
4969 printf(" 'requires' => [\n");
4970 for (i = 0;
4971 i < driver->num_requires; i ++) {
4972 if (driver->requires[i] !=
4973 NULL) {
4974 printf(" {\n");
4975 printf(" 'driver' => '%s',\n",
4976 driver->requires[i]);
4977 if (driver->requiresversion[i]
4978 != NULL)
4979 printf(" 'version' => '%s',\n",
4980 driver->requiresversion[i]);
4981 printf(" },\n");
4982 }
4983 }
4984 printf(" ],\n");
4985 }
4986 if (driver->driver_type) {
4987 printf(" 'type' => '%s',\n", driver->driver_type);
4988 }
4989 if (driver->cmd) {
4990 printf(" 'cmd' => '%s',\n", driver->cmd);
4991 }
4992 if (driver->cmd_pdf) {
4993 printf(" 'cmd_cmd' => '%s',\n", driver->cmd_pdf);
4994 }
4995 if (driver->driverppdentry) {
4996 printf(" 'ppdentry' => '%s',\n", driver->driverppdentry);
4997 } else {
4998 printf(" 'ppdentry' => undef,\n");
4999 }
5000 if (driver->drivermargins) {
5001 printf(" 'margins' => {\n");
5002 generateMarginsPerlData(driver->drivermargins, debug);
5003 printf(" },\n");
5004 }
5005 if (driver->comment) {
5006 printf(" 'comment' => '%s',\n", driver->comment);
5007 }
5008 if (driver->num_printers > 0) {
5009 printf(" 'printers' => [\n");
5010 for (i = 0; i < driver->num_printers; i ++) {
5011 printf(" {\n");
5012 printf(" 'id' => '%s',\n",
5013 driver->printers[i]->id);
5014 if (driver->printers[i]->comment) {
5015 printf(" 'comment' => '%s'\n",
5016 driver->printers[i]->comment);
5017 }
5018 if (driver->printers[i]->excmaxresx != NULL) {
5019 printf(" 'excmaxresx' => '%s',\n",
5020 driver->printers[i]->excmaxresx);
5021 }
5022 if (driver->printers[i]->excmaxresy != NULL) {
5023 printf(" 'excmaxresy' => '%s',\n",
5024 driver->printers[i]->excmaxresy);
5025 }
5026 if (driver->printers[i]->exccolor != NULL) {
5027 printf(" 'exccolor' => '%s',\n",
5028 driver->printers[i]->exccolor);
5029 }
5030 if (driver->printers[i]->exctext != NULL) {
5031 printf(" 'exctext' => '%s',\n",
5032 driver->printers[i]->exctext);
5033 }
5034 if (driver->printers[i]->exclineart != NULL) {
5035 printf(" 'exclineart' => '%s',\n",
5036 driver->printers[i]->exclineart);
5037 }
5038 if (driver->printers[i]->excgraphics != NULL) {
5039 printf(" 'excgraphics' => '%s',\n",
5040 driver->printers[i]->excgraphics);
5041 }
5042 if (driver->printers[i]->excphoto != NULL) {
5043 printf(" 'excphoto' => '%s',\n",
5044 driver->printers[i]->excphoto);
5045 }
5046 if (driver->printers[i]->excload != NULL) {
5047 printf(" 'excload' => '%s',\n",
5048 driver->printers[i]->excload);
5049 }
5050 if (driver->printers[i]->excspeed != NULL) {
5051 printf(" 'excspeed' => '%s',\n",
5052 driver->printers[i]->excspeed);
5053 }
5054 printf(" },\n");
5055 }
5056 printf(" ]\n");
5057 } else {
5058 printf(" 'printers' => []\n");
5059 }
5060 printf("};\n");
5061
5062 }
5063
5064 int /* O - Error state */
main(int argc,char ** argv)5065 main(int argc, char **argv) { /* I - Command line arguments */
5066 int i, j; /* loop variables */
5067 int debug = 0; /* Debug output level */
5068 xmlChar *setting;
5069 xmlChar const *language = sc_locale_C;
5070 xmlChar **defaultsettings = NULL; /* User-supplied option settings*/
5071 int num_defaultsettings = 0;
5072 char *filename = NULL;
5073 int datatype = 1; /* Data type to parse: 0: Overview, 1: Combo
5074 2: Printer, 3: Driver */
5075 comboDataPtr combo; /* C data structure of printer/driver combo */
5076 overviewPtr overview; /* C data structure of printer/driver combo */
5077 printerEntryPtr printer; /* C data structure of printer entry */
5078 driverEntryPtr driver; /* C data structure of driver entry*/
5079
5080 /* COMPAT: Do not genrate nodes for formatting spaces */
5081 LIBXML_TEST_VERSION
5082 xmlKeepBlanksDefault(0);
5083
5084 /* Read the command line arguments */
5085 for (i = 1; i < argc; i ++) {
5086 if (argv[i][0] == '-') {
5087 switch (argv[i][1]) {
5088 case 'O' : /* Parse overview */
5089 datatype = 0;
5090 break;
5091 case 'C' : /* Parse combo */
5092 datatype = 1;
5093 break;
5094 case 'P' : /* Parse printer */
5095 datatype = 2;
5096 break;
5097 case 'D' : /* Parse driver */
5098 datatype = 3;
5099 break;
5100 case 'o' : /* option setting */
5101 if (argv[i][2] != '\0')
5102 setting = (xmlChar *)(argv[i] + 2);
5103 else {
5104 i ++;
5105 setting = (xmlChar *)(argv[i]);
5106 }
5107 num_defaultsettings ++;
5108 defaultsettings =
5109 (xmlChar **)realloc((xmlChar **)defaultsettings,
5110 sizeof(xmlChar *) * num_defaultsettings);
5111 defaultsettings[num_defaultsettings-1] = xmlStrdup (setting);
5112 break;
5113 case 'l' : /* language */
5114 if (argv[i][2] != '\0')
5115 language = (xmlChar *)(argv[i] + 2);
5116 else {
5117 i ++;
5118 language = (xmlChar *)(argv[i]);
5119 }
5120 break;
5121 case 'v' : /* verbose */
5122 debug++;
5123 j = 2;
5124 while (argv[i][j] != '\0') {
5125 if (argv[i][j] == 'v') debug++;
5126 j++;
5127 }
5128 break;
5129 case '?' :
5130 case 'h' : /* Help */
5131 fprintf(stderr, "Usage: foomatic-perl-data [ -O ] [ -C ] [ -P ] [ -D ]\n [ -o option=setting ] [ -o ... ] [ -l language ]\n [ -v ] [ -vv ] [ filename ]\n");
5132 fprintf(stderr, "\n");
5133 fprintf(stderr, " -O Parse overview XML data\n");
5134 fprintf(stderr, " -C Parse printer/driver combo XML data (default)\n");
5135 fprintf(stderr, " -P Parse printer entry XML data\n");
5136 fprintf(stderr, " -D Parse driver entry XML data\n");
5137 fprintf(stderr, " -o option=setting\n");
5138 fprintf(stderr, " Default option settings for the generated Perl data (combo\n");
5139 fprintf(stderr, " only, no range-checking)\n");
5140 fprintf(stderr, " -l language Language in which the texts are returned, default is \"en\"\n");
5141 fprintf(stderr, " (English). If the text in the requested language is missing,\n");
5142 fprintf(stderr, " english text will be returned.\n");
5143 fprintf(stderr, " -v Verbose (debug) mode\n");
5144 fprintf(stderr, " -vv Very verbose (debug) mode\n");
5145 fprintf(stderr, " filename Read input from a file and not from standard input\n");
5146 fprintf(stderr, "\n");
5147 exit(1);
5148 break;
5149 default :
5150 fprintf(stderr, "Unknown option \'-%c\'!\n", argv[i][1]);
5151 exit(1);
5152 }
5153 } else {
5154 filename = argv[i];
5155 }
5156 }
5157
5158 if (debug) fprintf(stderr,"Language: %s\n", language);
5159
5160 if (datatype == 0) { /* Parse overview data */
5161
5162 /* Parse the XML input */
5163 overview = parseOverviewFile(filename, language, debug);
5164
5165 if (overview) {
5166
5167 /* Generate the Perl data structure on standard output */
5168 generateOverviewPerlData(overview, debug);
5169
5170 } else {
5171 exit(1);
5172 }
5173
5174 } else if (datatype == 1) { /* Parse printer/driver combo data */
5175
5176 /* Parse the XML input */
5177 combo = parseComboFile(filename, language, debug);
5178
5179 if (combo) {
5180
5181 /* Prepare the data for the output */
5182 prepareComboData(combo, defaultsettings, num_defaultsettings, debug);
5183
5184 /* Generate the Perl data structure on standard output */
5185 generateComboPerlData(combo, debug);
5186
5187 } else {
5188 exit(1);
5189 }
5190
5191 } else if (datatype == 2) { /* Parse overview data */
5192
5193 /* Parse the XML input */
5194 printer = parsePrinterFile(filename, language, debug);
5195
5196 if (printer) {
5197
5198 /* Generate the Perl data structure on standard output */
5199 generatePrinterPerlData(printer, debug);
5200
5201 } else {
5202 exit(1);
5203 }
5204
5205 } else if (datatype == 3) { /* Parse overview data */
5206
5207 /* Parse the XML input */
5208 driver = parseDriverFile(filename, language, debug);
5209
5210 if (driver) {
5211
5212 /* Generate the Perl data structure on standard output */
5213 generateDriverPerlData(driver, debug);
5214
5215 } else {
5216 exit(1);
5217 }
5218
5219 }
5220
5221 /* Clean up everything else before quitting. */
5222 xmlCleanupParser();
5223
5224 return(0);
5225 }
5226