]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-source.cxx
4 // Source class for the CUPS PPD Compiler.
6 // Copyright 2007-2009 by Apple Inc.
7 // Copyright 2002-2007 by Easy Software Products.
9 // These coded instructions, statements, and computer programs are the
10 // property of Apple Inc. and are protected by Federal copyright
11 // law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 // which should have been included with this file. If this file is
13 // file is missing or damaged, see the license at "http://www.cups.org/".
17 // ppdcSource::ppdcSource() - Load a driver source file.
18 // ppdcSource::~ppdcSource() - Free a driver source file.
19 // ppdcSource::add_include() - Add an include directory.
20 // ppdcSource::find_driver() - Find a driver.
21 // ppdcSource::find_include() - Find an include file.
22 // ppdcSource::find_po() - Find a message catalog for the given
24 // ppdcSource::find_size() - Find a media size.
25 // ppdcSource::find_variable() - Find a variable.
26 // ppdcSource::get_attr() - Get an attribute.
27 // ppdcSource::get_boolean() - Get a boolean value.
28 // ppdcSource::get_choice() - Get a choice.
29 // ppdcSource::get_color_model() - Get an old-style color model option.
30 // ppdcSource::get_color_order() - Get an old-style color order value.
31 // ppdcSource::get_color_profile() - Get a color profile definition.
32 // ppdcSource::get_color_space() - Get an old-style colorspace value.
33 // ppdcSource::get_constraint() - Get a constraint.
34 // ppdcSource::get_custom_size() - Get a custom media size definition from
36 // ppdcSource::get_duplex() - Get a duplex option.
37 // ppdcSource::get_filter() - Get a filter.
38 // ppdcSource::get_float() - Get a single floating-point number.
39 // ppdcSource::get_font() - Get a font definition.
40 // ppdcSource::get_generic() - Get a generic old-style option.
41 // ppdcSource::get_group() - Get an option group.
42 // ppdcSource::get_installable() - Get an installable option.
43 // ppdcSource::get_integer() - Get an integer value from a file.
44 // ppdcSource::get_measurement() - Get a measurement value.
45 // ppdcSource::get_option() - Get an option definition.
46 // ppdcSource::get_po() - Get a message catalog.
47 // ppdcSource::get_resolution() - Get an old-style resolution option.
48 // ppdcSource::get_simple_profile() - Get a simple color profile definition.
49 // ppdcSource::get_size() - Get a media size definition from a file.
50 // ppdcSource::get_token() - Get a token from a file.
51 // ppdcSource::get_variable() - Get a variable definition.
52 // ppdcSource::quotef() - Write a formatted, quoted string...
53 // ppdcSource::read_file() - Read a driver source file.
54 // ppdcSource::scan_file() - Scan a driver source file.
55 // ppdcSource::set_variable() - Set a variable.
56 // ppdcSource::write_file() - Write the current source data to a file.
60 // Include necessary headers...
64 #include <cups/globals.h>
68 #include <cups/raster.h>
69 #include "data/epson.h"
70 #include "data/escp.h"
72 #include "data/label.h"
80 ppdcArray
*ppdcSource::includes
= 0;
81 const char *ppdcSource::driver_types
[] =
94 // 'ppdcSource::ppdcSource()' - Load a driver source file.
97 ppdcSource::ppdcSource(const char *f
, // I - File to read
98 cups_file_t
*ffp
)// I - File pointer to use
103 filename
= new ppdcString(f
);
104 base_fonts
= new ppdcArray();
105 drivers
= new ppdcArray();
106 po_files
= new ppdcArray();
107 sizes
= new ppdcArray();
108 vars
= new ppdcArray();
109 cond_state
= PPDC_COND_NORMAL
;
110 cond_current
= cond_stack
;
111 cond_stack
[0] = PPDC_COND_NORMAL
;
119 // 'ppdcSource::~ppdcSource()' - Free a driver source file.
122 ppdcSource::~ppdcSource()
127 base_fonts
->release();
136 // 'ppdcSource::add_include()' - Add an include directory.
140 ppdcSource::add_include(const char *d
) // I - Include directory
146 includes
= new ppdcArray();
148 includes
->add(new ppdcString(d
));
153 // 'ppdcSource::find_driver()' - Find a driver.
156 ppdcDriver
* // O - Driver
157 ppdcSource::find_driver(const char *f
) // I - Driver file name
159 ppdcDriver
*d
; // Current driver
162 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
163 if (!strcasecmp(f
, d
->pc_file_name
->value
))
171 // 'ppdcSource::find_include()' - Find an include file.
174 char * // O - Found path or NULL
175 ppdcSource::find_include(
176 const char *f
, // I - Include filename
177 const char *base
, // I - Current directory
178 char *n
, // I - Path buffer
179 int nlen
) // I - Path buffer length
181 ppdcString
*dir
; // Include directory
182 char temp
[1024], // Temporary path
183 *ptr
; // Pointer to end of path
186 // Range check input...
187 if (!f
|| !*f
|| !n
|| nlen
< 2)
190 // Check the first character to see if we have <name> or "name"...
193 // Remove the surrounding <> from the name...
194 strlcpy(temp
, f
+ 1, sizeof(temp
));
195 ptr
= temp
+ strlen(temp
) - 1;
199 _cupsLangPrintf(stderr
,
200 _("ppdc: Invalid #include/#po filename \"%s\"!\n"), n
);
209 // Check for the local file relative to the current directory...
210 if (base
&& *base
&& f
[0] != '/')
211 snprintf(n
, nlen
, "%s/%s", base
, f
);
219 // Absolute path that doesn't exist...
224 // Search the include directories, if any...
227 for (dir
= (ppdcString
*)includes
->first(); dir
; dir
= (ppdcString
*)includes
->next())
229 snprintf(n
, nlen
, "%s/%s", dir
->value
, f
);
235 // Search the standard include directories...
236 _cups_globals_t
*cg
= _cupsGlobals(); // Global data
238 snprintf(n
, nlen
, "%s/ppdc/%s", cg
->cups_datadir
, f
);
242 snprintf(n
, nlen
, "%s/po/%s", cg
->cups_datadir
, f
);
251 // 'ppdcSource::find_po()' - Find a message catalog for the given locale...
254 ppdcCatalog
* // O - Message catalog or NULL
255 ppdcSource::find_po(const char *l
) // I - Locale name
257 ppdcCatalog
*cat
; // Current message catalog
260 for (cat
= (ppdcCatalog
*)po_files
->first();
262 cat
= (ppdcCatalog
*)po_files
->next())
263 if (!strcasecmp(l
, cat
->locale
->value
))
271 // 'ppdcSource::find_size()' - Find a media size.
274 ppdcMediaSize
* // O - Size
275 ppdcSource::find_size(const char *s
) // I - Size name
277 ppdcMediaSize
*m
; // Current media size
280 for (m
= (ppdcMediaSize
*)sizes
->first(); m
; m
= (ppdcMediaSize
*)sizes
->next())
281 if (!strcasecmp(s
, m
->name
->value
))
289 // 'ppdcSource::find_variable()' - Find a variable.
292 ppdcVariable
* // O - Variable
293 ppdcSource::find_variable(const char *n
)// I - Variable name
295 ppdcVariable
*v
; // Current variable
298 for (v
= (ppdcVariable
*)vars
->first(); v
; v
= (ppdcVariable
*)vars
->next())
299 if (!strcasecmp(n
, v
->name
->value
))
307 // 'ppdcSource::get_attr()' - Get an attribute.
310 ppdcAttr
* // O - Attribute
311 ppdcSource::get_attr(ppdcFile
*fp
, // I - File to read
312 bool loc
) // I - Localize this attribute?
314 char name
[1024], // Name string
315 selector
[1024], // Selector string
316 *text
, // Text string
317 value
[1024]; // Value string
320 // Get the attribute parameters:
322 // Attribute name selector value
323 if (!get_token(fp
, name
, sizeof(name
)))
325 _cupsLangPrintf(stderr
,
326 _("ppdc: Expected name after %s on line %d of %s!\n"),
327 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
331 if (!get_token(fp
, selector
, sizeof(selector
)))
333 _cupsLangPrintf(stderr
,
334 _("ppdc: Expected selector after %s on line %d of %s!\n"),
335 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
339 if ((text
= strchr(selector
, '/')) != NULL
)
342 if (!get_token(fp
, value
, sizeof(value
)))
344 _cupsLangPrintf(stderr
,
345 _("ppdc: Expected value after %s on line %d of %s!\n"),
346 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
350 return (new ppdcAttr(name
, selector
, text
, value
, loc
));
355 // 'ppdcSource::get_boolean()' - Get a boolean value.
358 int // O - Boolean value
359 ppdcSource::get_boolean(ppdcFile
*fp
) // I - File to read
361 char buffer
[256]; // String buffer
364 if (!get_token(fp
, buffer
, sizeof(buffer
)))
366 _cupsLangPrintf(stderr
,
367 _("ppdc: Expected boolean value on line %d of %s.\n"),
368 fp
->line
, fp
->filename
);
372 if (!strcasecmp(buffer
, "on") ||
373 !strcasecmp(buffer
, "yes") ||
374 !strcasecmp(buffer
, "true"))
376 else if (!strcasecmp(buffer
, "off") ||
377 !strcasecmp(buffer
, "no") ||
378 !strcasecmp(buffer
, "false"))
382 _cupsLangPrintf(stderr
,
383 _("ppdc: Bad boolean value (%s) on line %d of %s.\n"),
384 buffer
, fp
->line
, fp
->filename
);
391 // 'ppdcSource::get_choice()' - Get a choice.
394 ppdcChoice
* // O - Choice data
395 ppdcSource::get_choice(ppdcFile
*fp
) // I - File to read
397 char name
[1024], // Name
402 // Read a choice from the file:
404 // Choice name/text code
405 if (!get_token(fp
, name
, sizeof(name
)))
407 _cupsLangPrintf(stderr
,
408 _("ppdc: Expected choice name/text on line %d of %s.\n"),
409 fp
->line
, fp
->filename
);
413 if ((text
= strchr(name
, '/')) != NULL
)
418 if (!get_token(fp
, code
, sizeof(code
)))
420 _cupsLangPrintf(stderr
, _("ppdc: Expected choice code on line %d of %s.\n"),
421 fp
->line
, fp
->filename
);
425 // Return the new choice
426 return (new ppdcChoice(name
, text
, code
));
431 // 'ppdcSource::get_color_model()' - Get an old-style color model option.
434 ppdcChoice
* // O - Choice data
435 ppdcSource::get_color_model(ppdcFile
*fp
)
438 char name
[1024], // Option name
439 *text
, // Text option
440 temp
[256]; // Temporary string
441 int color_space
, // Colorspace
442 color_order
, // Color order
443 compression
; // Compression mode
446 // Get the ColorModel parameters:
448 // ColorModel name/text colorspace colororder compression
449 if (!get_token(fp
, name
, sizeof(name
)))
451 _cupsLangPrintf(stderr
,
452 _("ppdc: Expected name/text combination for ColorModel on "
453 "line %d of %s!\n"), fp
->line
, fp
->filename
);
457 if ((text
= strchr(name
, '/')) != NULL
)
462 if (!get_token(fp
, temp
, sizeof(temp
)))
464 _cupsLangPrintf(stderr
,
465 _("ppdc: Expected colorspace for ColorModel on line %d of "
466 "%s!\n"), fp
->line
, fp
->filename
);
470 if ((color_space
= get_color_space(temp
)) < 0)
471 color_space
= get_integer(temp
);
473 if (!get_token(fp
, temp
, sizeof(temp
)))
475 _cupsLangPrintf(stderr
,
476 _("ppdc: Expected color order for ColorModel on line %d of "
477 "%s!\n"), fp
->line
, fp
->filename
);
481 if ((color_order
= get_color_order(temp
)) < 0)
482 color_order
= get_integer(temp
);
484 if (!get_token(fp
, temp
, sizeof(temp
)))
486 _cupsLangPrintf(stderr
,
487 _("ppdc: Expected compression for ColorModel on line %d of "
488 "%s!\n"), fp
->line
, fp
->filename
);
492 compression
= get_integer(temp
);
494 snprintf(temp
, sizeof(temp
),
495 "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
497 color_space
, color_order
, compression
);
499 return (new ppdcChoice(name
, text
, temp
));
504 // 'ppdcSource::get_color_order()' - Get an old-style color order value.
507 int // O - Color order value
508 ppdcSource::get_color_order(
509 const char *co
) // I - Color order string
511 if (!strcasecmp(co
, "chunked") ||
512 !strcasecmp(co
, "chunky"))
513 return (CUPS_ORDER_CHUNKED
);
514 else if (!strcasecmp(co
, "banded"))
515 return (CUPS_ORDER_BANDED
);
516 else if (!strcasecmp(co
, "planar"))
517 return (CUPS_ORDER_PLANAR
);
524 // 'ppdcSource::get_color_profile()' - Get a color profile definition.
527 ppdcProfile
* // O - Color profile
528 ppdcSource::get_color_profile(
529 ppdcFile
*fp
) // I - File to read
531 char resolution
[1024], // Resolution/media type
532 *media_type
; // Media type
533 int i
; // Looping var
534 float g
, // Gamma value
536 m
[9]; // Transform matrix
539 // Get the ColorProfile parameters:
541 // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
542 if (!get_token(fp
, resolution
, sizeof(resolution
)))
544 _cupsLangPrintf(stderr
,
545 _("ppdc: Expected resolution/mediatype following "
546 "ColorProfile on line %d of %s!\n"),
547 fp
->line
, fp
->filename
);
551 if ((media_type
= strchr(resolution
, '/')) != NULL
)
552 *media_type
++ = '\0';
554 media_type
= resolution
;
558 for (i
= 0; i
< 9; i
++)
559 m
[i
] = get_float(fp
);
561 return (new ppdcProfile(resolution
, media_type
, g
, d
, m
));
566 // 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
569 int // O - Colorspace value
570 ppdcSource::get_color_space(
571 const char *cs
) // I - Colorspace string
573 if (!strcasecmp(cs
, "w"))
574 return (CUPS_CSPACE_W
);
575 else if (!strcasecmp(cs
, "rgb"))
576 return (CUPS_CSPACE_RGB
);
577 else if (!strcasecmp(cs
, "rgba"))
578 return (CUPS_CSPACE_RGBA
);
579 else if (!strcasecmp(cs
, "k"))
580 return (CUPS_CSPACE_K
);
581 else if (!strcasecmp(cs
, "cmy"))
582 return (CUPS_CSPACE_CMY
);
583 else if (!strcasecmp(cs
, "ymc"))
584 return (CUPS_CSPACE_YMC
);
585 else if (!strcasecmp(cs
, "cmyk"))
586 return (CUPS_CSPACE_CMYK
);
587 else if (!strcasecmp(cs
, "ymck"))
588 return (CUPS_CSPACE_YMCK
);
589 else if (!strcasecmp(cs
, "kcmy"))
590 return (CUPS_CSPACE_KCMY
);
591 else if (!strcasecmp(cs
, "kcmycm"))
592 return (CUPS_CSPACE_KCMYcm
);
593 else if (!strcasecmp(cs
, "gmck"))
594 return (CUPS_CSPACE_GMCK
);
595 else if (!strcasecmp(cs
, "gmcs"))
596 return (CUPS_CSPACE_GMCS
);
597 else if (!strcasecmp(cs
, "white"))
598 return (CUPS_CSPACE_WHITE
);
599 else if (!strcasecmp(cs
, "gold"))
600 return (CUPS_CSPACE_GOLD
);
601 else if (!strcasecmp(cs
, "silver"))
602 return (CUPS_CSPACE_SILVER
);
603 else if (!strcasecmp(cs
, "CIEXYZ"))
604 return (CUPS_CSPACE_CIEXYZ
);
605 else if (!strcasecmp(cs
, "CIELab"))
606 return (CUPS_CSPACE_CIELab
);
607 else if (!strcasecmp(cs
, "RGBW"))
608 return (CUPS_CSPACE_RGBW
);
609 else if (!strcasecmp(cs
, "ICC1"))
610 return (CUPS_CSPACE_ICC1
);
611 else if (!strcasecmp(cs
, "ICC2"))
612 return (CUPS_CSPACE_ICC2
);
613 else if (!strcasecmp(cs
, "ICC3"))
614 return (CUPS_CSPACE_ICC3
);
615 else if (!strcasecmp(cs
, "ICC4"))
616 return (CUPS_CSPACE_ICC4
);
617 else if (!strcasecmp(cs
, "ICC5"))
618 return (CUPS_CSPACE_ICC5
);
619 else if (!strcasecmp(cs
, "ICC6"))
620 return (CUPS_CSPACE_ICC6
);
621 else if (!strcasecmp(cs
, "ICC7"))
622 return (CUPS_CSPACE_ICC7
);
623 else if (!strcasecmp(cs
, "ICC8"))
624 return (CUPS_CSPACE_ICC8
);
625 else if (!strcasecmp(cs
, "ICC9"))
626 return (CUPS_CSPACE_ICC9
);
627 else if (!strcasecmp(cs
, "ICCA"))
628 return (CUPS_CSPACE_ICCA
);
629 else if (!strcasecmp(cs
, "ICCB"))
630 return (CUPS_CSPACE_ICCB
);
631 else if (!strcasecmp(cs
, "ICCC"))
632 return (CUPS_CSPACE_ICCC
);
633 else if (!strcasecmp(cs
, "ICCD"))
634 return (CUPS_CSPACE_ICCD
);
635 else if (!strcasecmp(cs
, "ICCE"))
636 return (CUPS_CSPACE_ICCE
);
637 else if (!strcasecmp(cs
, "ICCF"))
638 return (CUPS_CSPACE_ICCF
);
645 // 'ppdcSource::get_constraint()' - Get a constraint.
648 ppdcConstraint
* // O - Constraint
649 ppdcSource::get_constraint(ppdcFile
*fp
)// I - File to read
651 char temp
[1024], // One string to rule them all
652 *ptr
, // Pointer into string
653 *option1
, // Constraint option 1
654 *choice1
, // Constraint choice 1
655 *option2
, // Constraint option 2
656 *choice2
; // Constraint choice 2
659 // Read the UIConstaints parameter in one of the following forms:
661 // UIConstraints "*Option1 *Option2"
662 // UIConstraints "*Option1 Choice1 *Option2"
663 // UIConstraints "*Option1 *Option2 Choice2"
664 // UIConstraints "*Option1 Choice1 *Option2 Choice2"
665 if (!get_token(fp
, temp
, sizeof(temp
)))
667 _cupsLangPrintf(stderr
,
668 _("ppdc: Expected constraints string for UIConstraints on "
669 "line %d of %s!\n"), fp
->line
, fp
->filename
);
673 for (ptr
= temp
; isspace(*ptr
); ptr
++);
677 _cupsLangPrintf(stderr
,
678 _("ppdc: Option constraint must *name on line %d of %s!\n"),
679 fp
->line
, fp
->filename
);
685 for (; *ptr
&& !isspace(*ptr
); ptr
++);
686 for (; isspace(*ptr
); *ptr
++ = '\0');
692 for (; *ptr
&& !isspace(*ptr
); ptr
++);
693 for (; isspace(*ptr
); *ptr
++ = '\0');
700 _cupsLangPrintf(stderr
,
701 _("ppdc: Expected two option names on line %d of %s!\n"),
702 fp
->line
, fp
->filename
);
708 for (; *ptr
&& !isspace(*ptr
); ptr
++);
709 for (; isspace(*ptr
); *ptr
++ = '\0');
716 return (new ppdcConstraint(option1
, choice1
, option2
, choice2
));
721 // 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
724 ppdcMediaSize
* // O - Media size
725 ppdcSource::get_custom_size(ppdcFile
*fp
)
728 char name
[1024], // Name
730 size_code
[10240], // PageSize code
731 region_code
[10240]; // PageRegion
732 float width
, // Width
735 bottom
, // Bottom margin
736 right
, // Right margin
740 // Get the name, text, width, length, margins, and code:
742 // CustomMedia name/text width length left bottom right top size-code region-code
743 if (!get_token(fp
, name
, sizeof(name
)))
746 if ((text
= strchr(name
, '/')) != NULL
)
751 if ((width
= get_measurement(fp
)) < 0.0f
)
754 if ((length
= get_measurement(fp
)) < 0.0f
)
757 if ((left
= get_measurement(fp
)) < 0.0f
)
760 if ((bottom
= get_measurement(fp
)) < 0.0f
)
763 if ((right
= get_measurement(fp
)) < 0.0f
)
766 if ((top
= get_measurement(fp
)) < 0.0f
)
769 if (!get_token(fp
, size_code
, sizeof(size_code
)))
772 if (!get_token(fp
, region_code
, sizeof(region_code
)))
775 // Return the new media size...
776 return (new ppdcMediaSize(name
, text
, width
, length
, left
, bottom
,
777 right
, top
, size_code
, region_code
));
782 // 'ppdcSource::get_duplex()' - Get a duplex option.
786 ppdcSource::get_duplex(ppdcFile
*fp
, // I - File to read from
787 ppdcDriver
*d
) // I - Current driver
789 char temp
[256]; // Duplex keyword
790 ppdcAttr
*attr
; // cupsFlipDuplex attribute
791 ppdcGroup
*g
; // Current group
792 ppdcOption
*o
; // Duplex option
795 // Duplex {boolean|none|normal|flip}
796 if (!get_token(fp
, temp
, sizeof(temp
)))
798 _cupsLangPrintf(stderr
,
799 _("ppdc: Expected duplex type after Duplex on line %d of "
800 "%s!\n"), fp
->line
, fp
->filename
);
807 if (!strcasecmp(temp
, "none") || !strcasecmp(temp
, "false") ||
808 !strcasecmp(temp
, "no") || !strcasecmp(temp
, "off"))
810 g
= d
->find_group("General");
811 if ((o
= g
->find_option("Duplex")) != NULL
)
812 g
->options
->remove(o
);
814 for (attr
= (ppdcAttr
*)d
->attrs
->first();
816 attr
= (ppdcAttr
*)d
->attrs
->next())
817 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
819 d
->attrs
->remove(attr
);
823 else if (!strcasecmp(temp
, "normal") || !strcasecmp(temp
, "true") ||
824 !strcasecmp(temp
, "yes") || !strcasecmp(temp
, "on") ||
825 !strcasecmp(temp
, "flip") || !strcasecmp(temp
, "rotated") ||
826 !strcasecmp(temp
, "manualtumble"))
828 g
= d
->find_group("General");
829 o
= g
->find_option("Duplex");
833 o
= new ppdcOption(PPDC_PICKONE
, "Duplex", "2-Sided Printing",
834 !strcasecmp(temp
, "flip") ? PPDC_SECTION_PAGE
:
835 PPDC_SECTION_ANY
, 10.0f
);
836 o
->add_choice(new ppdcChoice("None", "Off (1-Sided)",
837 "<</Duplex false>>setpagedevice"));
838 o
->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
839 "<</Duplex true/Tumble false>>setpagedevice"));
840 o
->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
841 "<</Duplex true/Tumble true>>setpagedevice"));
846 for (attr
= (ppdcAttr
*)d
->attrs
->first();
848 attr
= (ppdcAttr
*)d
->attrs
->next())
849 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
851 if (strcasecmp(temp
, "flip"))
852 d
->attrs
->remove(attr
);
856 if (!strcasecmp(temp
, "flip") && !attr
)
857 d
->add_attr(new ppdcAttr("cupsFlipDuplex", NULL
, NULL
, "true"));
859 for (attr
= (ppdcAttr
*)d
->attrs
->first();
861 attr
= (ppdcAttr
*)d
->attrs
->next())
862 if (!strcmp(attr
->name
->value
, "cupsBackSide"))
864 d
->attrs
->remove(attr
);
868 if (!strcasecmp(temp
, "flip"))
869 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Flipped"));
870 else if (!strcasecmp(temp
, "rotated"))
871 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Rotated"));
872 else if (!strcasecmp(temp
, "manualtumble"))
873 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "ManualTumble"));
875 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Normal"));
878 _cupsLangPrintf(stderr
,
879 _("ppdc: Unknown duplex type \"%s\" on line %d of %s!\n"),
880 temp
, fp
->line
, fp
->filename
);
885 // 'ppdcSource::get_filter()' - Get a filter.
888 ppdcFilter
* // O - Filter
889 ppdcSource::get_filter(ppdcFile
*fp
) // I - File to read
891 char type
[1024], // MIME type
892 program
[1024], // Filter program
893 *ptr
; // Pointer into MIME type
894 int cost
; // Relative cost
897 // Read filter parameters in one of the following formats:
899 // Filter "type cost program"
900 // Filter type cost program
902 if (!get_token(fp
, type
, sizeof(type
)))
904 _cupsLangPrintf(stderr
,
905 _("ppdc: Expected a filter definition on line %d of %s!\n"),
906 fp
->line
, fp
->filename
);
910 if ((ptr
= strchr(type
, ' ')) != NULL
)
912 // Old-style filter definition in one string...
914 cost
= strtol(ptr
, &ptr
, 10);
916 while (isspace(*ptr
))
919 strcpy(program
, ptr
);
923 cost
= get_integer(fp
);
925 if (!get_token(fp
, program
, sizeof(program
)))
927 _cupsLangPrintf(stderr
,
928 _("ppdc: Expected a program name on line %d of %s!\n"),
929 fp
->line
, fp
->filename
);
936 _cupsLangPrintf(stderr
,
937 _("ppdc: Invalid empty MIME type for filter on line %d of "
938 "%s!\n"), fp
->line
, fp
->filename
);
942 if (cost
< 0 || cost
> 200)
944 _cupsLangPrintf(stderr
,
945 _("ppdc: Invalid cost for filter on line %d of %s!\n"),
946 fp
->line
, fp
->filename
);
952 _cupsLangPrintf(stderr
,
953 _("ppdc: Invalid empty program name for filter on line %d "
954 "of %s!\n"), fp
->line
, fp
->filename
);
958 return (new ppdcFilter(type
, program
, cost
));
963 // 'ppdcSource::get_float()' - Get a single floating-point number.
967 ppdcSource::get_float(ppdcFile
*fp
) // I - File to read
969 char temp
[256], // String buffer
970 *ptr
; // Pointer into buffer
971 float val
; // Floating point value
974 // Get the number from the file and range-check...
975 if (!get_token(fp
, temp
, sizeof(temp
)))
977 _cupsLangPrintf(stderr
, _("ppdc: Expected real number on line %d of %s!\n"),
978 fp
->line
, fp
->filename
);
982 val
= (float)strtod(temp
, &ptr
);
986 _cupsLangPrintf(stderr
,
987 _("ppdc: Unknown trailing characters in real number \"%s\" "
988 "on line %d of %s!\n"), temp
, fp
->line
, fp
->filename
);
997 // 'ppdcSource::get_font()' - Get a font definition.
1000 ppdcFont
* // O - Font data
1001 ppdcSource::get_font(ppdcFile
*fp
) // I - File to read
1003 char name
[256], // Font name
1004 encoding
[256], // Font encoding
1005 version
[256], // Font version
1006 charset
[256], // Font charset
1007 temp
[256]; // Font status string
1008 ppdcFontStatus status
; // Font status enumeration
1011 // Read font parameters as follows:
1014 // Font name encoding version charset status
1015 // %font name encoding version charset status
1017 // "Name" is the PostScript font name.
1019 // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
1020 // Special, Expert, ExpertSubset, etc.
1022 // "Version" is the version number string.
1024 // "Charset" specifies the characters that are included in the font:
1025 // Standard, Special, Expert, Adobe-Identity, etc.
1027 // "Status" is the keyword ROM or Disk.
1028 if (!get_token(fp
, name
, sizeof(name
)))
1030 _cupsLangPrintf(stderr
,
1031 _("ppdc: Expected name after Font on line %d of %s!\n"),
1032 fp
->line
, fp
->filename
);
1036 if (!strcmp(name
, "*"))
1038 // Include all base fonts...
1042 status
= PPDC_FONT_ROM
;
1046 // Load a full font definition...
1047 if (!get_token(fp
, encoding
, sizeof(encoding
)))
1049 _cupsLangPrintf(stderr
,
1050 _("ppdc: Expected encoding after Font on line %d of "
1051 "%s!\n"), fp
->line
, fp
->filename
);
1055 if (!get_token(fp
, version
, sizeof(version
)))
1057 _cupsLangPrintf(stderr
,
1058 _("ppdc: Expected version after Font on line %d of "
1059 "%s!\n"), fp
->line
, fp
->filename
);
1063 if (!get_token(fp
, charset
, sizeof(charset
)))
1065 _cupsLangPrintf(stderr
,
1066 _("ppdc: Expected charset after Font on line %d of "
1067 "%s!\n"), fp
->line
, fp
->filename
);
1071 if (!get_token(fp
, temp
, sizeof(temp
)))
1073 _cupsLangPrintf(stderr
,
1074 _("ppdc: Expected status after Font on line %d of %s!\n"),
1075 fp
->line
, fp
->filename
);
1079 if (!strcasecmp(temp
, "ROM"))
1080 status
= PPDC_FONT_ROM
;
1081 else if (!strcasecmp(temp
, "Disk"))
1082 status
= PPDC_FONT_DISK
;
1085 _cupsLangPrintf(stderr
,
1086 _("ppdc: Bad status keyword %s on line %d of %s!\n"),
1087 temp
, fp
->line
, fp
->filename
);
1092 // printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
1094 return (new ppdcFont(name
, encoding
, version
, charset
, status
));
1099 // 'ppdcSource::get_generic()' - Get a generic old-style option.
1102 ppdcChoice
* // O - Choice data
1103 ppdcSource::get_generic(ppdcFile
*fp
, // I - File to read
1104 const char *keyword
,
1107 // I - Text attribute
1109 // I - Numeric attribute
1111 char name
[1024], // Name
1113 command
[256]; // Command string
1114 int val
; // Numeric value
1117 // Read one of the following parameters:
1120 // Foo integer name/text
1122 val
= get_integer(fp
);
1126 if (!get_token(fp
, name
, sizeof(name
)))
1128 _cupsLangPrintf(stderr
,
1129 _("ppdc: Expected name/text after %s on line %d of %s!\n"),
1130 keyword
, fp
->line
, fp
->filename
);
1134 if ((text
= strchr(name
, '/')) != NULL
)
1142 snprintf(command
, sizeof(command
),
1143 "<</%s(%s)/%s %d>>setpagedevice",
1144 tattr
, name
, nattr
, val
);
1146 snprintf(command
, sizeof(command
),
1147 "<</%s %d>>setpagedevice",
1151 snprintf(command
, sizeof(command
),
1152 "<</%s(%s)>>setpagedevice",
1155 return (new ppdcChoice(name
, text
, command
));
1160 // 'ppdcSource::get_group()' - Get an option group.
1163 ppdcGroup
* // O - Group
1164 ppdcSource::get_group(ppdcFile
*fp
, // I - File to read
1165 ppdcDriver
*d
) // I - Printer driver
1167 char name
[1024], // UI name
1169 ppdcGroup
*g
; // Group
1172 // Read the Group parameters:
1175 if (!get_token(fp
, name
, sizeof(name
)))
1177 _cupsLangPrintf(stderr
,
1178 _("ppdc: Expected group name/text on line %d of %s!\n"),
1179 fp
->line
, fp
->filename
);
1183 if ((text
= strchr(name
, '/')) != NULL
)
1188 // See if the group already exists...
1189 if ((g
= d
->find_group(name
)) == NULL
)
1191 // Nope, add a new one...
1192 g
= new ppdcGroup(name
, text
);
1200 // 'ppdcSource::get_installable()' - Get an installable option.
1203 ppdcOption
* // O - Option
1204 ppdcSource::get_installable(ppdcFile
*fp
)
1207 char name
[1024], // Name for installable option
1208 *text
; // Text for installable option
1209 ppdcOption
*o
; // Option
1212 // Read the parameter for an installable option:
1214 // Installable name/text
1215 if (!get_token(fp
, name
, sizeof(name
)))
1217 _cupsLangPrintf(stderr
,
1218 _("ppdc: Expected name/text after Installable on line %d "
1219 "of %s!\n"), fp
->line
, fp
->filename
);
1223 if ((text
= strchr(name
, '/')) != NULL
)
1228 // Create the option...
1229 o
= new ppdcOption(PPDC_BOOLEAN
, name
, text
, PPDC_SECTION_ANY
, 10.0f
);
1231 // Add the false and true choices...
1232 o
->add_choice(new ppdcChoice("False", "Not Installed", ""));
1233 o
->add_choice(new ppdcChoice("True", "Installed", ""));
1240 // 'ppdcSource::get_integer()' - Get an integer value from a string.
1243 #define PPDC_XX -1 // Bad
1244 #define PPDC_EQ 0 // ==
1245 #define PPDC_NE 1 // !=
1246 #define PPDC_LT 2 // <
1247 #define PPDC_LE 3 // <=
1248 #define PPDC_GT 4 // >
1249 #define PPDC_GE 5 // >=
1251 int // O - Integer value
1252 ppdcSource::get_integer(const char *v
) // I - Value string
1255 long temp
, // Temporary value
1256 temp2
; // Second temporary value
1257 char *newv
, // New value string pointer
1258 ch
; // Temporary character
1259 ppdcVariable
*var
; // #define variable
1260 int compop
; // Comparison operator
1263 // Parse the value string...
1267 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1269 // Return a simple integer value
1270 val
= strtol(v
, (char **)&v
, 0);
1271 if (*v
|| val
== LONG_MIN
)
1278 // Evaluate and expression in any of the following formats:
1280 // (number number ... number) Bitwise OR of all numbers
1281 // (NAME == value) 1 if equal, 0 otherwise
1282 // (NAME != value) 1 if not equal, 0 otherwise
1283 // (NAME < value) 1 if less than, 0 otherwise
1284 // (NAME <= value) 1 if less than or equal, 0 otherwise
1285 // (NAME > value) 1 if greater than, 0 otherwise
1286 // (NAME >= value) 1 if greater than or equal, 0 otherwise
1291 while (*v
&& *v
!= ')')
1293 // Skip leading whitespace...
1294 while (*v
&& isspace(*v
& 255));
1297 if (!*v
|| *v
== ')')
1300 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1302 // Bitwise OR a number...
1303 temp
= strtol(v
, &newv
, 0);
1305 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1311 // NAME logicop value
1312 for (newv
= (char *)v
+ 1;
1313 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1319 if ((var
= find_variable(v
)) != NULL
)
1321 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1323 else if (isdigit(var
->value
->value
[0] & 255) ||
1324 var
->value
->value
[0] == '-' ||
1325 var
->value
->value
[0] == '+')
1326 temp
= strtol(var
->value
->value
, NULL
, 0);
1334 while (isspace(*newv
& 255))
1337 if (strncmp(newv
, "==", 2))
1342 else if (strncmp(newv
, "!=", 2))
1347 else if (strncmp(newv
, "<=", 2))
1352 else if (*newv
== '<')
1357 else if (strncmp(newv
, ">=", 2))
1362 else if (*newv
== '>')
1370 if (compop
!= PPDC_XX
)
1372 while (isspace(*newv
& 255))
1375 if (*newv
== ')' || !*newv
)
1378 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1380 // Get the second number...
1381 temp2
= strtol(newv
, &newv
, 0);
1382 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1388 // Lookup the second name...
1389 for (v
= newv
, newv
++;
1390 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1396 if ((var
= find_variable(v
)) != NULL
)
1398 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1400 else if (isdigit(var
->value
->value
[0] & 255) ||
1401 var
->value
->value
[0] == '-' ||
1402 var
->value
->value
[0] == '+')
1403 temp2
= strtol(var
->value
->value
, NULL
, 0);
1413 // Do the comparison...
1417 temp
= temp
== temp2
;
1420 temp
= temp
!= temp2
;
1423 temp
= temp
< temp2
;
1426 temp
= temp
<= temp2
;
1429 temp
= temp
> temp2
;
1432 temp
= temp
>= temp2
;
1442 if (*v
== ')' && !v
[1])
1447 else if ((var
= find_variable(v
)) != NULL
)
1449 // NAME by itself returns 1 if the #define variable is not blank and
1451 return (var
->value
->value
&& var
->value
->value
[0] &&
1452 strcmp(var
->value
->value
, "0"));
1456 // Anything else is an error...
1463 // 'ppdcSource::get_integer()' - Get an integer value from a file.
1466 int // O - Integer value
1467 ppdcSource::get_integer(ppdcFile
*fp
) // I - File to read
1469 char temp
[1024]; // String buffer
1472 if (!get_token(fp
, temp
, sizeof(temp
)))
1474 _cupsLangPrintf(stderr
, _("ppdc: Expected integer on line %d of %s!\n"),
1475 fp
->line
, fp
->filename
);
1479 return (get_integer(temp
));
1484 // 'ppdcSource::get_measurement()' - Get a measurement value.
1487 float // O - Measurement value in points
1488 ppdcSource::get_measurement(ppdcFile
*fp
)
1491 char buffer
[256], // Number buffer
1492 *ptr
; // Pointer into buffer
1493 float val
; // Measurement value
1496 // Grab a token from the file...
1497 if (!get_token(fp
, buffer
, sizeof(buffer
)))
1500 // Get the floating point value of "s" and skip all digits and decimal points.
1501 val
= (float)strtod(buffer
, &ptr
);
1503 // Check for a trailing unit specifier...
1504 if (!strcasecmp(ptr
, "mm"))
1505 val
*= 72.0f
/ 25.4f
;
1506 else if (!strcasecmp(ptr
, "cm"))
1507 val
*= 72.0f
/ 2.54f
;
1508 else if (!strcasecmp(ptr
, "m"))
1509 val
*= 72.0f
/ 0.0254f
;
1510 else if (!strcasecmp(ptr
, "in"))
1512 else if (!strcasecmp(ptr
, "ft"))
1513 val
*= 72.0f
* 12.0f
;
1514 else if (strcasecmp(ptr
, "pt") && *ptr
)
1522 // 'ppdcSource::get_option()' - Get an option definition.
1525 ppdcOption
* // O - Option
1526 ppdcSource::get_option(ppdcFile
*fp
, // I - File to read
1527 ppdcDriver
*d
, // I - Printer driver
1528 ppdcGroup
*g
) // I - Current group
1530 char name
[1024], // UI name
1532 type
[256]; // UI type string
1533 ppdcOptType ot
; // Option type value
1534 ppdcOptSection section
; // Option section
1535 float order
; // Option order
1536 ppdcOption
*o
; // Option
1539 // Read the Option parameters:
1541 // Option name/text type section order
1542 if (!get_token(fp
, name
, sizeof(name
)))
1544 _cupsLangPrintf(stderr
,
1545 _("ppdc: Expected option name/text on line %d of %s!\n"),
1546 fp
->line
, fp
->filename
);
1550 if ((text
= strchr(name
, '/')) != NULL
)
1555 if (!get_token(fp
, type
, sizeof(type
)))
1557 _cupsLangPrintf(stderr
, _("ppdc: Expected option type on line %d of %s!\n"),
1558 fp
->line
, fp
->filename
);
1562 if (!strcasecmp(type
, "boolean"))
1564 else if (!strcasecmp(type
, "pickone"))
1566 else if (!strcasecmp(type
, "pickmany"))
1570 _cupsLangPrintf(stderr
,
1571 _("ppdc: Invalid option type \"%s\" on line %d of %s!\n"),
1572 type
, fp
->line
, fp
->filename
);
1576 if (!get_token(fp
, type
, sizeof(type
)))
1578 _cupsLangPrintf(stderr
,
1579 _("ppdc: Expected option section on line %d of %s!\n"),
1580 fp
->line
, fp
->filename
);
1584 if (!strcasecmp(type
, "AnySetup"))
1585 section
= PPDC_SECTION_ANY
;
1586 else if (!strcasecmp(type
, "DocumentSetup"))
1587 section
= PPDC_SECTION_DOCUMENT
;
1588 else if (!strcasecmp(type
, "ExitServer"))
1589 section
= PPDC_SECTION_EXIT
;
1590 else if (!strcasecmp(type
, "JCLSetup"))
1591 section
= PPDC_SECTION_JCL
;
1592 else if (!strcasecmp(type
, "PageSetup"))
1593 section
= PPDC_SECTION_PAGE
;
1594 else if (!strcasecmp(type
, "Prolog"))
1595 section
= PPDC_SECTION_PROLOG
;
1598 _cupsLangPrintf(stderr
,
1599 _("ppdc: Invalid option section \"%s\" on line %d of "
1600 "%s!\n"), type
, fp
->line
, fp
->filename
);
1604 order
= get_float(fp
);
1606 // See if the option already exists...
1607 if ((o
= d
->find_option(name
)) == NULL
)
1609 // Nope, add a new one...
1610 o
= new ppdcOption(ot
, name
, text
, section
, order
);
1612 else if (o
->type
!= ot
)
1614 _cupsLangPrintf(stderr
,
1615 _("ppdc: Option %s redefined with a different type on line "
1616 "%d of %s!\n"), name
, fp
->line
, fp
->filename
);
1625 // 'ppdcSource::get_po()' - Get a message catalog.
1628 ppdcCatalog
* // O - Message catalog
1629 ppdcSource::get_po(ppdcFile
*fp
) // I - File to read
1631 char locale
[32], // Locale name
1632 poname
[1024], // Message catalog filename
1633 basedir
[1024], // Base directory
1634 *baseptr
, // Pointer into directory
1635 pofilename
[1024]; // Full filename of message catalog
1636 ppdcCatalog
*cat
; // Message catalog
1639 // Read the #po parameters:
1641 // #po locale "filename.po"
1642 if (!get_token(fp
, locale
, sizeof(locale
)))
1644 _cupsLangPrintf(stderr
,
1645 _("ppdc: Expected locale after #po on line %d of %s!\n"),
1646 fp
->line
, fp
->filename
);
1650 if (!get_token(fp
, poname
, sizeof(poname
)))
1652 _cupsLangPrintf(stderr
,
1653 _("ppdc: Expected filename after #po %s on line %d of "
1654 "%s!\n"), locale
, fp
->line
, fp
->filename
);
1658 // See if the locale is already loaded...
1659 if (find_po(locale
))
1661 _cupsLangPrintf(stderr
,
1662 _("ppdc: Duplicate #po for locale %s on line %d of %s!\n"),
1663 locale
, fp
->line
, fp
->filename
);
1667 // Figure out the current directory...
1668 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
1670 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
1673 strcpy(basedir
, ".");
1675 // Find the po file...
1676 pofilename
[0] = '\0';
1679 find_include(poname
, basedir
, pofilename
, sizeof(pofilename
)))
1681 // Found it, so load it...
1682 cat
= new ppdcCatalog(locale
, pofilename
);
1684 // Reset the filename to the name supplied by the user...
1685 cat
->filename
->release();
1686 cat
->filename
= new ppdcString(poname
);
1688 // Return the catalog...
1693 _cupsLangPrintf(stderr
,
1694 _("ppdc: Unable to find #po file %s on line %d of %s!\n"),
1695 poname
, fp
->line
, fp
->filename
);
1702 // 'ppdcSource::get_resolution()' - Get an old-style resolution option.
1705 ppdcChoice
* // O - Choice data
1706 ppdcSource::get_resolution(ppdcFile
*fp
)// I - File to read
1708 char name
[1024], // Name
1710 temp
[256], // Temporary string
1711 command
[256], // Command string
1712 *commptr
; // Pointer into command
1713 int xdpi
, ydpi
, // X + Y resolution
1714 color_order
, // Color order
1715 color_space
, // Colorspace
1716 compression
, // Compression mode
1717 depth
, // Bits per color
1718 row_count
, // Row count
1719 row_feed
, // Row feed
1720 row_step
; // Row step/interval
1723 // Read the resolution parameters:
1725 // Resolution colorspace bits row-count row-feed row-step name/text
1726 if (!get_token(fp
, temp
, sizeof(temp
)))
1728 _cupsLangPrintf(stderr
,
1729 _("ppdc: Expected override field after Resolution on line "
1730 "%d of %s!\n"), fp
->line
, fp
->filename
);
1734 color_order
= get_color_order(temp
);
1735 color_space
= get_color_space(temp
);
1736 compression
= get_integer(temp
);
1738 depth
= get_integer(fp
);
1739 row_count
= get_integer(fp
);
1740 row_feed
= get_integer(fp
);
1741 row_step
= get_integer(fp
);
1743 if (!get_token(fp
, name
, sizeof(name
)))
1745 _cupsLangPrintf(stderr
,
1746 _("ppdc: Expected name/text after Resolution on line %d of "
1747 "%s!\n"), fp
->line
, fp
->filename
);
1751 if ((text
= strchr(name
, '/')) != NULL
)
1756 switch (sscanf(name
, "%dx%d", &xdpi
, &ydpi
))
1759 _cupsLangPrintf(stderr
,
1760 _("ppdc: Bad resolution name \"%s\" on line %d of "
1761 "%s!\n"), name
, fp
->line
, fp
->filename
);
1768 // Create the necessary PS commands...
1769 snprintf(command
, sizeof(command
),
1770 "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
1771 "/cupsRowFeed %d/cupsRowStep %d",
1772 xdpi
, ydpi
, depth
, row_count
, row_feed
, row_step
);
1773 commptr
= command
+ strlen(command
);
1775 if (color_order
>= 0)
1777 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1778 "/cupsColorOrder %d", color_order
);
1779 commptr
+= strlen(commptr
);
1782 if (color_space
>= 0)
1784 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1785 "/cupsColorSpace %d", color_space
);
1786 commptr
+= strlen(commptr
);
1789 if (compression
>= 0)
1791 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1792 "/cupsCompression %d", compression
);
1793 commptr
+= strlen(commptr
);
1796 snprintf(commptr
, sizeof(command
) - (commptr
- command
), ">>setpagedevice");
1798 // Return the new choice...
1799 return (new ppdcChoice(name
, text
, command
));
1804 // 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
1807 ppdcProfile
* // O - Color profile
1808 ppdcSource::get_simple_profile(ppdcFile
*fp
)
1811 char resolution
[1024], // Resolution/media type
1812 *media_type
; // Media type
1813 float m
[9]; // Transform matrix
1814 float kd
, rd
, g
; // Densities and gamma
1815 float red
, green
, blue
; // RGB adjustments
1816 float yellow
; // Yellow density
1817 float color
; // Color density values
1820 // Get the SimpleColorProfile parameters:
1822 // SimpleColorProfile resolution/mediatype black-density yellow-density
1823 // red-density gamma red-adjust green-adjust blue-adjust
1824 if (!get_token(fp
, resolution
, sizeof(resolution
)))
1826 _cupsLangPrintf(stderr
,
1827 _("ppdc: Expected resolution/mediatype following "
1828 "SimpleColorProfile on line %d of %s!\n"),
1829 fp
->line
, fp
->filename
);
1833 if ((media_type
= strchr(resolution
, '/')) != NULL
)
1834 *media_type
++ = '\0';
1836 media_type
= resolution
;
1838 // Collect the profile parameters...
1840 yellow
= get_float(fp
);
1843 red
= get_float(fp
);
1844 green
= get_float(fp
);
1845 blue
= get_float(fp
);
1847 // Build the color profile...
1848 color
= 0.5f
* rd
/ kd
- kd
;
1850 m
[1] = color
+ blue
; // C + M (blue)
1851 m
[2] = color
- green
; // C + Y (green)
1852 m
[3] = color
- blue
; // M + C (blue)
1854 m
[5] = color
+ red
; // M + Y (red)
1855 m
[6] = yellow
* (color
+ green
); // Y + C (green)
1856 m
[7] = yellow
* (color
- red
); // Y + M (red)
1864 else if (m
[3] > 0.0f
)
1875 else if (m
[6] > 0.0f
)
1886 else if (m
[7] > 0.0f
)
1892 // Return the new profile...
1893 return (new ppdcProfile(resolution
, media_type
, g
, kd
, m
));
1898 // 'ppdcSource::get_size()' - Get a media size definition from a file.
1901 ppdcMediaSize
* // O - Media size
1902 ppdcSource::get_size(ppdcFile
*fp
) // I - File to read
1904 char name
[1024], // Name
1906 float width
, // Width
1910 // Get the name, text, width, and length:
1912 // #media name/text width length
1913 if (!get_token(fp
, name
, sizeof(name
)))
1916 if ((text
= strchr(name
, '/')) != NULL
)
1921 if ((width
= get_measurement(fp
)) < 0.0f
)
1924 if ((length
= get_measurement(fp
)) < 0.0f
)
1927 // Return the new media size...
1928 return (new ppdcMediaSize(name
, text
, width
, length
, 0.0f
, 0.0f
, 0.0f
, 0.0f
));
1933 // 'ppdcSource::get_token()' - Get a token from a file.
1936 char * // O - Token string or NULL
1937 ppdcSource::get_token(ppdcFile
*fp
, // I - File to read
1938 char *buffer
, // I - Buffer
1939 int buflen
) // I - Length of buffer
1941 char *bufptr
, // Pointer into string buffer
1942 *bufend
; // End of string buffer
1943 int ch
, // Character from file
1944 nextch
, // Next char in file
1945 quote
, // Quote character used...
1946 empty
, // Empty input?
1947 startline
; // Start line for quote
1948 char name
[256], // Name string
1949 *nameptr
; // Name pointer
1950 ppdcVariable
*var
; // Variable pointer
1953 // Mark the beginning and end of the buffer...
1955 bufend
= buffer
+ buflen
- 1;
1957 // Loop intil we've read a token...
1962 while ((ch
= fp
->get()) != EOF
)
1964 if (isspace(ch
) && !quote
)
1973 // Variable substitution
1976 for (nameptr
= name
; (ch
= fp
->peek()) != EOF
;)
1978 if (!isalnum(ch
) && ch
!= '_')
1980 else if (nameptr
< (name
+ sizeof(name
) - 1))
1981 *nameptr
++ = fp
->get();
1984 if (nameptr
== name
)
1986 // Just substitute this character...
1990 if (bufptr
< bufend
)
1991 *bufptr
++ = fp
->get();
1996 _cupsLangPrintf(stderr
,
1997 _("ppdc: Bad variable substitution ($%c) on line %d "
1998 "of %s.\n"), ch
, fp
->line
, fp
->filename
);
2000 if (bufptr
< bufend
)
2006 // Substitute the variable value...
2008 var
= find_variable(name
);
2011 strncpy(bufptr
, var
->value
->value
, bufend
- bufptr
);
2012 bufptr
+= strlen(var
->value
->value
);
2016 _cupsLangPrintf(stderr
,
2017 _("ppdc: Undefined variable (%s) on line %d of "
2018 "%s.\n"), name
, fp
->line
, fp
->filename
);
2019 snprintf(bufptr
, bufend
- bufptr
+ 1, "$%s", name
);
2020 bufptr
+= strlen(name
) + 1;
2024 else if (ch
== '/' && !quote
)
2026 // Possibly a comment...
2027 nextch
= fp
->peek();
2034 while ((nextch
= fp
->get()) != EOF
)
2036 if (ch
== '*' && nextch
== '/')
2045 else if (nextch
== '/')
2048 while ((nextch
= fp
->get()) != EOF
)
2060 if (bufptr
< bufend
)
2064 else if (ch
== '\'' || ch
== '\"')
2070 // Ending the current quoted string...
2075 // Insert the opposing quote char...
2076 if (bufptr
< bufend
)
2081 // Start a new quoted string...
2082 startline
= fp
->line
;
2086 else if ((ch
== '(' || ch
== '<') && !quote
)
2090 startline
= fp
->line
;
2092 if (bufptr
< bufend
)
2095 else if ((ch
== ')' && quote
== '(') || (ch
== '>' && quote
== '<'))
2099 if (bufptr
< bufend
)
2102 else if (ch
== '\\')
2106 if ((ch
= fp
->get()) == EOF
)
2109 if (bufptr
< bufend
)
2112 else if (bufptr
< bufend
)
2118 if ((ch
== '{' || ch
== '}') && !quote
)
2125 _cupsLangPrintf(stderr
,
2126 _("ppdc: Unterminated string starting with %c on line %d "
2127 "of %s!\n"), quote
, startline
, fp
->filename
);
2143 // 'ppdcSource::get_variable()' - Get a variable definition.
2146 ppdcVariable
* // O - Variable
2147 ppdcSource::get_variable(ppdcFile
*fp
) // I - File to read
2149 char name
[1024], // Name
2150 value
[1024]; // Value
2153 // Get the name and value:
2155 // #define name value
2156 if (!get_token(fp
, name
, sizeof(name
)))
2159 if (!get_token(fp
, value
, sizeof(value
)))
2162 // Set the variable...
2163 return (set_variable(name
, value
));
2168 // 'ppdcSource::quotef()' - Write a formatted, quoted string...
2171 int // O - Number bytes on success, -1 on failure
2172 ppdcSource::quotef(cups_file_t
*fp
, // I - File to write to
2173 const char *format
, // I - Printf-style format string
2174 ...) // I - Additional args as needed
2176 va_list ap
; // Pointer to additional arguments
2177 int bytes
; // Bytes written
2178 char sign
, // Sign of format width
2179 size
, // Size character (h, l, L)
2180 type
; // Format type character
2181 const char *bufformat
; // Start of format
2182 int width
, // Width of field
2183 prec
; // Number of characters of precision
2184 char tformat
[100]; // Temporary format string for fprintf()
2185 char *s
; // Pointer to string
2186 int slen
; // Length of string
2187 int i
; // Looping var
2190 // Range check input...
2194 // Loop through the format string, formatting as needed...
2195 va_start(ap
, format
);
2208 cupsFilePutChar(fp
, *format
++);
2212 else if (strchr(" -+#\'", *format
))
2218 while (isdigit(*format
))
2219 width
= width
* 10 + *format
++ - '0';
2226 while (isdigit(*format
))
2227 prec
= prec
* 10 + *format
++ - '0';
2232 if (*format
== 'l' && format
[1] == 'l')
2237 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
2247 case 'E' : // Floating point formats
2252 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2255 strncpy(tformat
, bufformat
, format
- bufformat
);
2256 tformat
[format
- bufformat
] = '\0';
2258 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, double));
2261 case 'B' : // Integer formats
2269 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2272 strncpy(tformat
, bufformat
, format
- bufformat
);
2273 tformat
[format
- bufformat
] = '\0';
2275 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, int));
2278 case 'p' : // Pointer value
2279 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2282 strncpy(tformat
, bufformat
, format
- bufformat
);
2283 tformat
[format
- bufformat
] = '\0';
2285 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, void *));
2288 case 'c' : // Character or character array
2292 cupsFilePutChar(fp
, va_arg(ap
, int));
2296 cupsFileWrite(fp
, va_arg(ap
, char *), width
);
2301 case 's' : // String
2302 if ((s
= va_arg(ap
, char *)) == NULL
)
2303 s
= (char *)"(nil)";
2306 if (slen
> width
&& prec
!= width
)
2314 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2315 cupsFilePutChar(fp
, ' ');
2318 for (i
= slen
; i
> 0; i
--, s
++, bytes
++)
2320 if (*s
== '\\' || *s
== '\"')
2322 cupsFilePutChar(fp
, '\\');
2326 cupsFilePutChar(fp
, *s
);
2331 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2332 cupsFilePutChar(fp
, ' ');
2339 cupsFilePutChar(fp
, *format
++);
2346 // Return the number of characters written.
2352 // 'ppdcSource::read_file()' - Read a driver source file.
2356 ppdcSource::read_file(const char *f
, // I - File to read
2357 cups_file_t
*ffp
) // I - File pointer to use
2359 ppdcFile
*fp
= new ppdcFile(f
, ffp
);
2363 if (cond_current
!= cond_stack
)
2364 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"!\n"), f
);
2369 // 'ppdcSource::scan_file()' - Scan a driver source file.
2373 ppdcSource::scan_file(ppdcFile
*fp
, // I - File to read
2374 ppdcDriver
*td
, // I - Driver template
2375 bool inc
) // I - Including?
2377 ppdcDriver
*d
; // Current driver
2378 ppdcGroup
*g
, // Current group
2379 *general
, // General options group
2380 *install
; // Installable options group
2381 ppdcOption
*o
; // Current option
2382 ppdcChoice
*c
; // Current choice
2383 char temp
[256], // Token from file...
2384 *ptr
; // Pointer into token
2385 int isdefault
; // Default option?
2388 // Initialize things as needed...
2392 d
= new ppdcDriver(td
);
2394 if ((general
= d
->find_group("General")) == NULL
)
2396 general
= new ppdcGroup("General", NULL
);
2397 d
->add_group(general
);
2400 if ((install
= d
->find_group("InstallableOptions")) == NULL
)
2402 install
= new ppdcGroup("InstallableOptions", "Installable Options");
2403 d
->add_group(install
);
2406 // Loop until EOF or }
2410 while (get_token(fp
, temp
, sizeof(temp
)))
2414 // Mark the next choice as the default
2417 for (ptr
= temp
; ptr
[1]; ptr
++)
2424 // Don't mark the next choice as the default
2428 if (!strcasecmp(temp
, "}"))
2430 // Close this one out...
2433 else if (!strcasecmp(temp
, "{"))
2435 // Open a new child...
2438 else if (!strcasecmp(temp
, "#if"))
2440 if ((cond_current
- cond_stack
) >= 100)
2442 _cupsLangPrintf(stderr
,
2443 _("ppdc: Too many nested #if's on line %d of %s!\n"),
2444 fp
->line
, fp
->filename
);
2449 if (get_integer(fp
))
2450 *cond_current
= PPDC_COND_SATISFIED
;
2453 *cond_current
= PPDC_COND_SKIP
;
2454 cond_state
|= PPDC_COND_SKIP
;
2457 else if (!strcasecmp(temp
, "#elif"))
2459 if (cond_current
== cond_stack
)
2461 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s!\n"),
2462 fp
->line
, fp
->filename
);
2466 if (*cond_current
& PPDC_COND_SATISFIED
)
2469 *cond_current
|= PPDC_COND_SKIP
;
2471 else if (get_integer(fp
))
2473 *cond_current
|= PPDC_COND_SATISFIED
;
2474 *cond_current
&= ~PPDC_COND_SKIP
;
2477 *cond_current
|= PPDC_COND_SKIP
;
2479 // Update the current state
2480 int *cond_temp
= cond_current
; // Temporary stack pointer
2482 cond_state
= PPDC_COND_NORMAL
;
2483 while (cond_temp
> cond_stack
)
2484 if (*cond_temp
& PPDC_COND_SKIP
)
2486 cond_state
= PPDC_COND_SKIP
;
2492 else if (!strcasecmp(temp
, "#else"))
2494 if (cond_current
== cond_stack
)
2496 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s!\n"),
2497 fp
->line
, fp
->filename
);
2501 if (*cond_current
& PPDC_COND_SATISFIED
)
2502 *cond_current
|= PPDC_COND_SKIP
;
2505 *cond_current
|= PPDC_COND_SATISFIED
;
2506 *cond_current
&= ~PPDC_COND_SKIP
;
2509 // Update the current state
2510 int *cond_temp
= cond_current
; // Temporary stack pointer
2512 cond_state
= PPDC_COND_NORMAL
;
2513 while (cond_temp
> cond_stack
)
2514 if (*cond_temp
& PPDC_COND_SKIP
)
2516 cond_state
= PPDC_COND_SKIP
;
2522 else if (!strcasecmp(temp
, "#endif"))
2524 if (cond_current
== cond_stack
)
2526 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s!\n"),
2527 fp
->line
, fp
->filename
);
2533 // Update the current state
2534 int *cond_temp
= cond_current
; // Temporary stack pointer
2536 cond_state
= PPDC_COND_NORMAL
;
2537 while (cond_temp
> cond_stack
)
2538 if (*cond_temp
& PPDC_COND_SKIP
)
2540 cond_state
= PPDC_COND_SKIP
;
2546 else if (!strcasecmp(temp
, "#define"))
2548 // Get the variable...
2551 else if (!strcasecmp(temp
, "#include"))
2553 // #include filename
2554 char basedir
[1024], // Base directory
2555 *baseptr
, // Pointer into directory
2556 inctemp
[1024], // Initial filename
2557 incname
[1024]; // Include filename
2558 ppdcFile
*incfile
; // Include file
2559 int *old_current
= cond_current
;
2560 // Previous current stack
2563 // Get the include name...
2564 if (!get_token(fp
, inctemp
, sizeof(inctemp
)))
2566 _cupsLangPrintf(stderr
,
2567 _("ppdc: Expected include filename on line %d of "
2568 "%s!\n"), fp
->line
, fp
->filename
);
2575 // Figure out the current directory...
2576 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
2578 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
2581 strcpy(basedir
, ".");
2583 // Find the include file...
2584 if (find_include(inctemp
, basedir
, incname
, sizeof(incname
)))
2586 // Open the include file, scan it, and then close it...
2587 incfile
= new ppdcFile(incname
);
2588 scan_file(incfile
, d
, true);
2591 if (cond_current
!= old_current
)
2592 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"!\n"),
2598 _cupsLangPrintf(stderr
,
2599 _("ppdc: Unable to find include file \"%s\" on line %d "
2600 "of %s!\n"), inctemp
, fp
->line
, fp
->filename
);
2604 else if (!strcasecmp(temp
, "#media"))
2606 ppdcMediaSize
*m
; // Media size
2609 // Get a media size...
2619 else if (!strcasecmp(temp
, "#po"))
2621 ppdcCatalog
*cat
; // Message catalog
2624 // Get a message catalog...
2634 else if (!strcasecmp(temp
, "Attribute") ||
2635 !strcasecmp(temp
, "LocAttribute"))
2637 ppdcAttr
*a
; // Attribute
2640 // Get an attribute...
2641 a
= get_attr(fp
, !strcasecmp(temp
, "LocAttribute"));
2650 else if (!strcasecmp(temp
, "Choice"))
2663 // Add it to the current option...
2666 _cupsLangPrintf(stderr
,
2667 _("ppdc: Choice found on line %d of %s with no "
2668 "Option!\n"), fp
->line
, fp
->filename
);
2675 o
->set_defchoice(c
);
2677 else if (!strcasecmp(temp
, "ColorDevice"))
2679 // ColorDevice boolean
2683 d
->color_device
= get_boolean(fp
);
2685 else if (!strcasecmp(temp
, "ColorModel"))
2687 // Get the color model
2688 c
= get_color_model(fp
);
2698 // Add the choice to the ColorModel option...
2699 if ((o
= d
->find_option("ColorModel")) == NULL
)
2701 // Create the ColorModel option...
2702 o
= new ppdcOption(PPDC_PICKONE
, "ColorModel", "Color Mode", PPDC_SECTION_ANY
, 10.0f
);
2710 o
->set_defchoice(c
);
2714 else if (!strcasecmp(temp
, "ColorProfile"))
2716 ppdcProfile
*p
; // Color profile
2719 // Get the color profile...
2720 p
= get_color_profile(fp
);
2727 d
->profiles
->add(p
);
2730 else if (!strcasecmp(temp
, "Copyright"))
2733 char copytemp
[8192], // Copyright string
2734 *copyptr
, // Pointer into string
2735 *copyend
; // Pointer to end of string
2738 // Get the copyright string...
2739 if (!get_token(fp
, copytemp
, sizeof(temp
)))
2741 _cupsLangPrintf(stderr
,
2742 _("ppdc: Expected string after Copyright on line %d "
2743 "of %s!\n"), fp
->line
, fp
->filename
);
2750 // Break it up into individual lines...
2751 for (copyptr
= copytemp
; copyptr
; copyptr
= copyend
)
2753 if ((copyend
= strchr(copyptr
, '\n')) != NULL
)
2756 d
->copyright
->add(new ppdcString(copyptr
));
2759 else if (!strcasecmp(temp
, "CustomMedia"))
2761 ppdcMediaSize
*m
; // Media size
2764 // Get a custom media size...
2765 m
= get_custom_size(fp
);
2777 d
->set_default_size(m
);
2779 else if (!strcasecmp(temp
, "Cutter"))
2782 int have_cutter
; // Have a paper cutter?
2785 have_cutter
= get_boolean(fp
);
2786 if (have_cutter
<= 0 || cond_state
)
2789 if ((o
= d
->find_option("CutMedia")) == NULL
)
2791 o
= new ppdcOption(PPDC_BOOLEAN
, "CutMedia", "Cut Media", PPDC_SECTION_ANY
, 10.0f
);
2796 c
= new ppdcChoice("False", NULL
, "<</CutMedia 0>>setpagedevice");
2798 o
->set_defchoice(c
);
2800 c
= new ppdcChoice("True", NULL
, "<</CutMedia 4>>setpagedevice");
2806 else if (!strcasecmp(temp
, "Darkness"))
2808 // Get the darkness choice...
2809 c
= get_generic(fp
, "Darkness", NULL
, "cupsCompression");
2819 // Add the choice to the cupsDarkness option...
2820 if ((o
= d
->find_option("cupsDarkness")) == NULL
)
2822 // Create the cupsDarkness option...
2823 o
= new ppdcOption(PPDC_PICKONE
, "cupsDarkness", "Darkness", PPDC_SECTION_ANY
, 10.0f
);
2831 o
->set_defchoice(c
);
2835 else if (!strcasecmp(temp
, "DriverType"))
2837 int i
; // Looping var
2840 // DriverType keyword
2841 if (!get_token(fp
, temp
, sizeof(temp
)))
2843 _cupsLangPrintf(stderr
,
2844 _("ppdc: Expected driver type keyword following "
2845 "DriverType on line %d of %s!\n"),
2846 fp
->line
, fp
->filename
);
2853 for (i
= 0; i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])); i
++)
2854 if (!strcasecmp(temp
, driver_types
[i
]))
2857 if (i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])))
2858 d
->type
= (ppdcDrvType
)i
;
2859 else if (!strcasecmp(temp
, "dymo"))
2860 d
->type
= PPDC_DRIVER_LABEL
;
2862 _cupsLangPrintf(stderr
,
2863 _("ppdc: Unknown driver type %s on line %d of %s!\n"),
2864 temp
, fp
->line
, fp
->filename
);
2866 else if (!strcasecmp(temp
, "Duplex"))
2868 else if (!strcasecmp(temp
, "Filter"))
2870 ppdcFilter
*f
; // Filter
2873 // Get the filter value...
2883 else if (!strcasecmp(temp
, "Finishing"))
2885 // Get the finishing choice...
2886 c
= get_generic(fp
, "Finishing", "OutputType", NULL
);
2896 // Add the choice to the cupsFinishing option...
2897 if ((o
= d
->find_option("cupsFinishing")) == NULL
)
2899 // Create the cupsFinishing option...
2900 o
= new ppdcOption(PPDC_PICKONE
, "cupsFinishing", "Finishing", PPDC_SECTION_ANY
, 10.0f
);
2908 o
->set_defchoice(c
);
2912 else if (!strcasecmp(temp
, "Font") ||
2913 !strcasecmp(temp
, "#font"))
2915 ppdcFont
*f
; // Font
2926 if (!strcasecmp(temp
, "#font"))
2932 d
->set_default_font(f
);
2936 else if (!strcasecmp(temp
, "Group"))
2939 ppdcGroup
*tempg
= get_group(fp
, d
);
2946 if (!d
->find_group(tempg
->name
->value
))
2951 if (!d
->find_group(tempg
->name
->value
))
2952 d
->add_group(tempg
);
2957 else if (!strcasecmp(temp
, "HWMargins"))
2959 // HWMargins left bottom right top
2960 d
->left_margin
= get_measurement(fp
);
2961 d
->bottom_margin
= get_measurement(fp
);
2962 d
->right_margin
= get_measurement(fp
);
2963 d
->top_margin
= get_measurement(fp
);
2965 else if (!strcasecmp(temp
, "InputSlot"))
2967 // Get the input slot choice...
2968 c
= get_generic(fp
, "InputSlot", NULL
, "MediaPosition");
2978 // Add the choice to the InputSlot option...
2979 if ((o
= d
->find_option("InputSlot")) == NULL
)
2981 // Create the InputSlot option...
2982 o
= new ppdcOption(PPDC_PICKONE
, "InputSlot", "Media Source",
2983 PPDC_SECTION_ANY
, 10.0f
);
2991 o
->set_defchoice(c
);
2995 else if (!strcasecmp(temp
, "Installable"))
2997 // Get the installable option...
2998 o
= get_installable(fp
);
3000 // Add it as needed...
3006 install
->add_option(o
);
3011 else if (!strcasecmp(temp
, "ManualCopies"))
3013 // ManualCopies boolean
3017 d
->manual_copies
= get_boolean(fp
);
3019 else if (!strcasecmp(temp
, "Manufacturer"))
3021 // Manufacturer name
3022 char name
[256]; // Model name string
3025 if (!get_token(fp
, name
, sizeof(name
)))
3027 _cupsLangPrintf(stderr
,
3028 _("ppdc: Expected name after Manufacturer on line %d "
3029 "of %s!\n"), fp
->line
, fp
->filename
);
3034 d
->set_manufacturer(name
);
3036 else if (!strcasecmp(temp
, "MaxSize"))
3038 // MaxSize width length
3041 get_measurement(fp
);
3042 get_measurement(fp
);
3046 d
->max_width
= get_measurement(fp
);
3047 d
->max_length
= get_measurement(fp
);
3050 else if (!strcasecmp(temp
, "MediaSize"))
3052 // MediaSize keyword
3053 char name
[41]; // Media size name
3054 ppdcMediaSize
*m
, // Matching media size...
3055 *dm
; // Driver media size...
3058 if (get_token(fp
, name
, sizeof(name
)) == NULL
)
3060 _cupsLangPrintf(stderr
,
3061 _("ppdc: Expected name after MediaSize on line %d of "
3062 "%s!\n"), fp
->line
, fp
->filename
);
3069 m
= find_size(name
);
3073 _cupsLangPrintf(stderr
,
3074 _("ppdc: Unknown media size \"%s\" on line %d of "
3075 "%s!\n"), name
, fp
->line
, fp
->filename
);
3079 // Add this size to the driver...
3080 dm
= new ppdcMediaSize(m
->name
->value
, m
->text
->value
,
3081 m
->width
, m
->length
, d
->left_margin
,
3082 d
->bottom_margin
, d
->right_margin
,
3087 d
->set_default_size(dm
);
3089 else if (!strcasecmp(temp
, "MediaType"))
3091 // Get the media type choice...
3092 c
= get_generic(fp
, "MediaType", "MediaType", "cupsMediaType");
3102 // Add the choice to the MediaType option...
3103 if ((o
= d
->find_option("MediaType")) == NULL
)
3105 // Create the MediaType option...
3106 o
= new ppdcOption(PPDC_PICKONE
, "MediaType", "Media Type",
3107 PPDC_SECTION_ANY
, 10.0f
);
3115 o
->set_defchoice(c
);
3119 else if (!strcasecmp(temp
, "MinSize"))
3121 // MinSize width length
3124 get_measurement(fp
);
3125 get_measurement(fp
);
3129 d
->min_width
= get_measurement(fp
);
3130 d
->min_length
= get_measurement(fp
);
3133 else if (!strcasecmp(temp
, "ModelName"))
3136 char name
[256]; // Model name string
3139 if (!get_token(fp
, name
, sizeof(name
)))
3141 _cupsLangPrintf(stderr
,
3142 _("ppdc: Expected name after ModelName on line %d of "
3143 "%s!\n"), fp
->line
, fp
->filename
);
3148 d
->set_model_name(name
);
3150 else if (!strcasecmp(temp
, "ModelNumber"))
3152 // ModelNumber number
3156 d
->model_number
= get_integer(fp
);
3158 else if (!strcasecmp(temp
, "Option"))
3161 ppdcOption
*tempo
= get_option(fp
, d
, g
);
3168 if (!g
->find_option(tempo
->name
->value
))
3173 if (!g
->find_option(tempo
->name
->value
))
3174 g
->add_option(tempo
);
3179 else if (!strcasecmp(temp
, "FileName"))
3182 char name
[256]; // Filename string
3185 if (!get_token(fp
, name
, sizeof(name
)))
3187 _cupsLangPrintf(stderr
,
3188 _("ppdc: Expected name after FileName on line %d of "
3189 "%s!\n"), fp
->line
, fp
->filename
);
3194 d
->set_file_name(name
);
3196 else if (!strcasecmp(temp
, "PCFileName"))
3199 char name
[256]; // PC filename string
3202 if (!get_token(fp
, name
, sizeof(name
)))
3204 _cupsLangPrintf(stderr
,
3205 _("ppdc: Expected name after PCFileName on line %d of "
3206 "%s!\n"), fp
->line
, fp
->filename
);
3211 d
->set_pc_file_name(name
);
3213 else if (!strcasecmp(temp
, "Resolution"))
3215 // Get the resolution choice...
3216 c
= get_resolution(fp
);
3226 // Add the choice to the Resolution option...
3227 if ((o
= d
->find_option("Resolution")) == NULL
)
3229 // Create the Resolution option...
3230 o
= new ppdcOption(PPDC_PICKONE
, "Resolution", NULL
, PPDC_SECTION_ANY
,
3239 o
->set_defchoice(c
);
3243 else if (!strcasecmp(temp
, "SimpleColorProfile"))
3245 ppdcProfile
*p
; // Color profile
3248 // Get the color profile...
3249 p
= get_simple_profile(fp
);
3256 d
->profiles
->add(p
);
3259 else if (!strcasecmp(temp
, "Throughput"))
3261 // Throughput number
3265 d
->throughput
= get_integer(fp
);
3267 else if (!strcasecmp(temp
, "UIConstraints"))
3269 ppdcConstraint
*con
; // Constraint
3272 con
= get_constraint(fp
);
3279 d
->constraints
->add(con
);
3282 else if (!strcasecmp(temp
, "VariablePaperSize"))
3284 // VariablePaperSize boolean
3288 d
->variable_paper_size
= get_boolean(fp
);
3290 else if (!strcasecmp(temp
, "Version"))
3293 char name
[256]; // Model name string
3296 if (!get_token(fp
, name
, sizeof(name
)))
3298 _cupsLangPrintf(stderr
,
3299 _("ppdc: Expected string after Version on line %d of "
3300 "%s!\n"), fp
->line
, fp
->filename
);
3305 d
->set_version(name
);
3309 _cupsLangPrintf(stderr
,
3310 _("ppdc: Unknown token \"%s\" seen on line %d of %s!\n"),
3311 temp
, fp
->line
, fp
->filename
);
3316 // Done processing this block, is there anything to save?
3319 if (!d
->pc_file_name
|| !d
->model_name
|| !d
->manufacturer
|| !d
->version
||
3322 // Nothing to save...
3327 // Got a driver, save it...
3335 // 'ppdcSource::set_variable()' - Set a variable.
3338 ppdcVariable
* // O - Variable
3339 ppdcSource::set_variable(
3340 const char *name
, // I - Name
3341 const char *value
) // I - Value
3343 ppdcVariable
*v
; // Variable
3346 // See if the variable exists already...
3347 v
= find_variable(name
);
3350 // Change the variable value...
3351 v
->set_value(value
);
3355 // Create a new variable and add it...
3356 v
= new ppdcVariable(name
, value
);
3365 // 'ppdcSource::write_file()' - Write the current source data to a file.
3368 int // O - 0 on success, -1 on error
3369 ppdcSource::write_file(const char *f
) // I - File to write
3371 cups_file_t
*fp
; // Output file
3372 char bckname
[1024]; // Backup file
3373 ppdcDriver
*d
; // Current driver
3374 ppdcString
*st
; // Current string
3375 ppdcAttr
*a
; // Current attribute
3376 ppdcConstraint
*co
; // Current constraint
3377 ppdcFilter
*fi
; // Current filter
3378 ppdcFont
*fo
; // Current font
3379 ppdcGroup
*g
; // Current group
3380 ppdcOption
*o
; // Current option
3381 ppdcChoice
*ch
; // Current choice
3382 ppdcProfile
*p
; // Current color profile
3383 ppdcMediaSize
*si
; // Current media size
3384 float left
, // Current left margin
3385 bottom
, // Current bottom margin
3386 right
, // Current right margin
3387 top
; // Current top margin
3388 int dtused
[PPDC_DRIVER_MAX
];// Driver type usage...
3391 // Rename the current file, if any, to .bck...
3392 snprintf(bckname
, sizeof(bckname
), "%s.bck", f
);
3395 // Open the output file...
3396 fp
= cupsFileOpen(f
, "w");
3400 // Can't create file; restore backup and return...
3405 cupsFilePuts(fp
, "// CUPS PPD Compiler " CUPS_SVERSION
"\n\n");
3407 // Include standard files...
3408 cupsFilePuts(fp
, "// Include necessary files...\n");
3409 cupsFilePuts(fp
, "#include <font.defs>\n");
3410 cupsFilePuts(fp
, "#include <media.defs>\n");
3412 memset(dtused
, 0, sizeof(dtused
));
3414 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3415 if (d
->type
> PPDC_DRIVER_PS
&& !dtused
[d
->type
])
3417 cupsFilePrintf(fp
, "#include <%s.h>\n", driver_types
[d
->type
]);
3418 dtused
[d
->type
] = 1;
3421 // Output each driver...
3422 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3424 // Start the driver...
3425 cupsFilePrintf(fp
, "\n// %s %s\n", d
->manufacturer
->value
, d
->model_name
->value
);
3426 cupsFilePuts(fp
, "{\n");
3428 // Write the copyright stings...
3429 for (st
= (ppdcString
*)d
->copyright
->first();
3431 st
= (ppdcString
*)d
->copyright
->next())
3432 quotef(fp
, " Copyright \"%s\"\n", st
->value
);
3434 // Write other strings and values...
3435 if (d
->manufacturer
&& d
->manufacturer
->value
)
3436 quotef(fp
, " Manufacturer \"%s\"\n", d
->manufacturer
->value
);
3437 if (d
->model_name
->value
)
3438 quotef(fp
, " ModelName \"%s\"\n", d
->model_name
->value
);
3439 if (d
->file_name
&& d
->file_name
->value
)
3440 quotef(fp
, " FileName \"%s\"\n", d
->file_name
->value
);
3441 if (d
->pc_file_name
&& d
->pc_file_name
->value
)
3442 quotef(fp
, " PCFileName \"%s\"\n", d
->pc_file_name
->value
);
3443 if (d
->version
&& d
->version
->value
)
3444 quotef(fp
, " Version \"%s\"\n", d
->version
->value
);
3446 cupsFilePrintf(fp
, " DriverType %s\n", driver_types
[d
->type
]);
3448 if (d
->model_number
)
3452 case PPDC_DRIVER_ESCP
:
3453 cupsFilePuts(fp
, " ModelNumber (");
3455 if (d
->model_number
& ESCP_DOTMATRIX
)
3456 cupsFilePuts(fp
, " $ESCP_DOTMATRIX");
3457 if (d
->model_number
& ESCP_MICROWEAVE
)
3458 cupsFilePuts(fp
, " $ESCP_MICROWEAVE");
3459 if (d
->model_number
& ESCP_STAGGER
)
3460 cupsFilePuts(fp
, " $ESCP_STAGGER");
3461 if (d
->model_number
& ESCP_ESCK
)
3462 cupsFilePuts(fp
, " $ESCP_ESCK");
3463 if (d
->model_number
& ESCP_EXT_UNITS
)
3464 cupsFilePuts(fp
, " $ESCP_EXT_UNITS");
3465 if (d
->model_number
& ESCP_EXT_MARGINS
)
3466 cupsFilePuts(fp
, " $ESCP_EXT_MARGINS");
3467 if (d
->model_number
& ESCP_USB
)
3468 cupsFilePuts(fp
, " $ESCP_USB");
3469 if (d
->model_number
& ESCP_PAGE_SIZE
)
3470 cupsFilePuts(fp
, " $ESCP_PAGE_SIZE");
3471 if (d
->model_number
& ESCP_RASTER_ESCI
)
3472 cupsFilePuts(fp
, " $ESCP_RASTER_ESCI");
3473 if (d
->model_number
& ESCP_REMOTE
)
3474 cupsFilePuts(fp
, " $ESCP_REMOTE");
3476 cupsFilePuts(fp
, ")\n");
3479 case PPDC_DRIVER_PCL
:
3480 cupsFilePuts(fp
, " ModelNumber (");
3482 if (d
->model_number
& PCL_PAPER_SIZE
)
3483 cupsFilePuts(fp
, " $PCL_PAPER_SIZE");
3484 if (d
->model_number
& PCL_INKJET
)
3485 cupsFilePuts(fp
, " $PCL_INKJET");
3486 if (d
->model_number
& PCL_RASTER_END_COLOR
)
3487 cupsFilePuts(fp
, " $PCL_RASTER_END_COLOR");
3488 if (d
->model_number
& PCL_RASTER_CID
)
3489 cupsFilePuts(fp
, " $PCL_RASTER_CID");
3490 if (d
->model_number
& PCL_RASTER_CRD
)
3491 cupsFilePuts(fp
, " $PCL_RASTER_CRD");
3492 if (d
->model_number
& PCL_RASTER_SIMPLE
)
3493 cupsFilePuts(fp
, " $PCL_RASTER_SIMPLE");
3494 if (d
->model_number
& PCL_RASTER_RGB24
)
3495 cupsFilePuts(fp
, " $PCL_RASTER_RGB24");
3496 if (d
->model_number
& PCL_PJL
)
3497 cupsFilePuts(fp
, " $PCL_PJL");
3498 if (d
->model_number
& PCL_PJL_PAPERWIDTH
)
3499 cupsFilePuts(fp
, " $PCL_PJL_PAPERWIDTH");
3500 if (d
->model_number
& PCL_PJL_HPGL2
)
3501 cupsFilePuts(fp
, " $PCL_PJL_HPGL2");
3502 if (d
->model_number
& PCL_PJL_PCL3GUI
)
3503 cupsFilePuts(fp
, " $PCL_PJL_PCL3GUI");
3504 if (d
->model_number
& PCL_PJL_RESOLUTION
)
3505 cupsFilePuts(fp
, " $PCL_PJL_RESOLUTION");
3507 cupsFilePuts(fp
, ")\n");
3510 case PPDC_DRIVER_LABEL
:
3511 cupsFilePuts(fp
, " ModelNumber ");
3513 switch (d
->model_number
)
3516 cupsFilePuts(fp
, "$DYMO_3x0\n");
3519 case ZEBRA_EPL_LINE
:
3520 cupsFilePuts(fp
, "$ZEBRA_EPL_LINE\n");
3523 case ZEBRA_EPL_PAGE
:
3524 cupsFilePuts(fp
, "$ZEBRA_EPL_PAGE\n");
3528 cupsFilePuts(fp
, "$ZEBRA_ZPL\n");
3532 cupsFilePuts(fp
, "$ZEBRA_CPCL\n");
3535 case INTELLITECH_PCL
:
3536 cupsFilePuts(fp
, "$INTELLITECH_PCL\n");
3540 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3545 case PPDC_DRIVER_EPSON
:
3546 cupsFilePuts(fp
, " ModelNumber ");
3548 switch (d
->model_number
)
3551 cupsFilePuts(fp
, "$EPSON_9PIN\n");
3555 cupsFilePuts(fp
, "$EPSON_24PIN\n");
3559 cupsFilePuts(fp
, "$EPSON_COLOR\n");
3563 cupsFilePuts(fp
, "$EPSON_PHOTO\n");
3567 cupsFilePuts(fp
, "$EPSON_ICOLOR\n");
3571 cupsFilePuts(fp
, "$EPSON_IPHOTO\n");
3575 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3580 case PPDC_DRIVER_HP
:
3581 cupsFilePuts(fp
, " ModelNumber ");
3582 switch (d
->model_number
)
3585 cupsFilePuts(fp
, "$HP_LASERJET\n");
3589 cupsFilePuts(fp
, "$HP_DESKJET\n");
3593 cupsFilePuts(fp
, "$HP_DESKJET2\n");
3597 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3601 cupsFilePuts(fp
, ")\n");
3605 cupsFilePrintf(fp
, " ModelNumber %d\n", d
->model_number
);
3610 if (d
->manual_copies
)
3611 cupsFilePuts(fp
, " ManualCopies Yes\n");
3613 if (d
->color_device
)
3614 cupsFilePuts(fp
, " ColorDevice Yes\n");
3617 cupsFilePrintf(fp
, " Throughput %d\n", d
->throughput
);
3619 // Output all of the attributes...
3620 for (a
= (ppdcAttr
*)d
->attrs
->first();
3622 a
= (ppdcAttr
*)d
->attrs
->next())
3623 if (a
->text
->value
&& a
->text
->value
[0])
3624 quotef(fp
, " Attribute \"%s\" \"%s/%s\" \"%s\"\n",
3625 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3626 a
->text
->value
, a
->value
->value
? a
->value
->value
: "");
3628 quotef(fp
, " Attribute \"%s\" \"%s\" \"%s\"\n",
3629 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3630 a
->value
->value
? a
->value
->value
: "");
3632 // Output all of the constraints...
3633 for (co
= (ppdcConstraint
*)d
->constraints
->first();
3635 co
= (ppdcConstraint
*)d
->constraints
->next())
3637 if (co
->option1
->value
[0] == '*')
3638 cupsFilePrintf(fp
, " UIConstraints \"%s %s", co
->option1
->value
,
3639 co
->choice1
->value
? co
->choice1
->value
: "");
3641 cupsFilePrintf(fp
, " UIConstraints \"*%s %s", co
->option1
->value
,
3642 co
->choice1
->value
? co
->choice1
->value
: "");
3644 if (co
->option2
->value
[0] == '*')
3645 cupsFilePrintf(fp
, " %s %s\"\n", co
->option2
->value
,
3646 co
->choice2
->value
? co
->choice2
->value
: "");
3648 cupsFilePrintf(fp
, " *%s %s\"\n", co
->option2
->value
,
3649 co
->choice2
->value
? co
->choice2
->value
: "");
3652 // Output all of the filters...
3653 for (fi
= (ppdcFilter
*)d
->filters
->first();
3655 fi
= (ppdcFilter
*)d
->filters
->next())
3656 cupsFilePrintf(fp
, " Filter \"%s %d %s\"\n",
3657 fi
->mime_type
->value
, fi
->cost
, fi
->program
->value
);
3659 // Output all of the fonts...
3660 for (fo
= (ppdcFont
*)d
->fonts
->first();
3662 fo
= (ppdcFont
*)d
->fonts
->next())
3663 if (!strcmp(fo
->name
->value
, "*"))
3664 cupsFilePuts(fp
, " Font *\n");
3666 cupsFilePrintf(fp
, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
3667 fo
->name
->value
, fo
->encoding
->value
,
3668 fo
->version
->value
, fo
->charset
->value
,
3669 fo
->status
== PPDC_FONT_ROM
? "ROM" : "Disk");
3671 // Output all options...
3672 for (g
= (ppdcGroup
*)d
->groups
->first();
3674 g
= (ppdcGroup
*)d
->groups
->next())
3676 if (g
->options
->count
== 0)
3679 if (g
->text
->value
&& g
->text
->value
[0])
3680 quotef(fp
, " Group \"%s/%s\"\n", g
->name
->value
, g
->text
->value
);
3682 cupsFilePrintf(fp
, " Group \"%s\"\n", g
->name
->value
);
3684 for (o
= (ppdcOption
*)g
->options
->first();
3686 o
= (ppdcOption
*)g
->options
->next())
3688 if (o
->choices
->count
== 0)
3691 if (o
->text
->value
&& o
->text
->value
[0])
3692 quotef(fp
, " Option \"%s/%s\"", o
->name
->value
, o
->text
->value
);
3694 cupsFilePrintf(fp
, " Option \"%s\"", o
->name
->value
);
3696 cupsFilePrintf(fp
, " %s %s %.1f\n",
3697 o
->type
== PPDC_BOOLEAN
? "Boolean" :
3698 o
->type
== PPDC_PICKONE
? "PickOne" : "PickMany",
3699 o
->section
== PPDC_SECTION_ANY
? "AnySetup" :
3700 o
->section
== PPDC_SECTION_DOCUMENT
? "DocumentSetup" :
3701 o
->section
== PPDC_SECTION_EXIT
? "ExitServer" :
3702 o
->section
== PPDC_SECTION_JCL
? "JCLSetup" :
3703 o
->section
== PPDC_SECTION_PAGE
? "PageSetup" :
3707 for (ch
= (ppdcChoice
*)o
->choices
->first();
3709 ch
= (ppdcChoice
*)o
->choices
->next())
3711 if (ch
->text
->value
&& ch
->text
->value
[0])
3712 quotef(fp
, " %sChoice \"%s/%s\" \"%s\"\n",
3713 o
->defchoice
== ch
->name
? "*" : "",
3714 ch
->name
->value
, ch
->text
->value
,
3715 ch
->code
->value
? ch
->code
->value
: "");
3717 quotef(fp
, " %sChoice \"%s\" \"%s\"\n",
3718 o
->defchoice
== ch
->name
? "*" : "",
3720 ch
->code
->value
? ch
->code
->value
: "");
3725 // Output all of the color profiles...
3726 for (p
= (ppdcProfile
*)d
->profiles
->first();
3728 p
= (ppdcProfile
*)d
->profiles
->next())
3729 cupsFilePrintf(fp
, " ColorProfile \"%s/%s\" %.3f %.3f "
3730 "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
3731 p
->resolution
->value
, p
->media_type
->value
,
3732 p
->density
, p
->gamma
,
3733 p
->profile
[0], p
->profile
[1], p
->profile
[2],
3734 p
->profile
[3], p
->profile
[4], p
->profile
[5],
3735 p
->profile
[6], p
->profile
[7], p
->profile
[8]);
3737 // Output all of the media sizes...
3743 for (si
= (ppdcMediaSize
*)d
->sizes
->first();
3745 si
= (ppdcMediaSize
*)d
->sizes
->next())
3746 if (si
->size_code
->value
&& si
->region_code
->value
)
3748 // Output a custom media size...
3749 quotef(fp
, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
3750 si
->name
== d
->default_size
? "*" : "", si
->name
->value
,
3751 si
->text
->value
, si
->width
, si
->length
, si
->left
, si
->bottom
,
3752 si
->right
, si
->top
, si
->size_code
->value
,
3753 si
->region_code
->value
);
3757 // Output a standard media size...
3758 if (fabs(left
- si
->left
) > 0.1 ||
3759 fabs(bottom
- si
->bottom
) > 0.1 ||
3760 fabs(right
- si
->right
) > 0.1 ||
3761 fabs(top
- si
->top
) > 0.1)
3763 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3764 si
->left
, si
->bottom
, si
->right
, si
->top
);
3767 bottom
= si
->bottom
;
3772 cupsFilePrintf(fp
, " %sMediaSize %s\n",
3773 si
->name
== d
->default_size
? "*" : "",
3777 if (d
->variable_paper_size
)
3779 cupsFilePuts(fp
, " VariablePaperSize Yes\n");
3781 if (fabs(left
- d
->left_margin
) > 0.1 ||
3782 fabs(bottom
- d
->bottom_margin
) > 0.1 ||
3783 fabs(right
- d
->right_margin
) > 0.1 ||
3784 fabs(top
- d
->top_margin
) > 0.1)
3786 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3787 d
->left_margin
, d
->bottom_margin
, d
->right_margin
,
3791 cupsFilePrintf(fp
, " MinSize %.2f %.2f\n", d
->min_width
, d
->min_length
);
3792 cupsFilePrintf(fp
, " MaxSize %.2f %.2f\n", d
->max_width
, d
->max_length
);
3795 // End the driver...
3796 cupsFilePuts(fp
, "}\n");
3799 // Close the file and return...