]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-source.cxx
4 // Source class for the CUPS PPD Compiler.
6 // Copyright 2007-2013 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...
63 #include "ppdc-private.h"
67 #include <cups/raster.h>
68 #include "data/epson.h"
70 #include "data/label.h"
72 # include <sys/utsname.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
;
113 // Add standard #define variables...
114 #define MAKE_STRING(x) #x
116 vars
->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION
)));
117 vars
->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR
)));
118 vars
->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR
)));
119 vars
->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH
)));
122 vars
->add(new ppdcVariable("PLATFORM_NAME", "Windows"));
123 vars
->add(new ppdcVariable("PLATFORM_ARCH", "X86"));
126 struct utsname name
; // uname information
130 vars
->add(new ppdcVariable("PLATFORM_NAME", name
.sysname
));
131 vars
->add(new ppdcVariable("PLATFORM_ARCH", name
.machine
));
135 vars
->add(new ppdcVariable("PLATFORM_NAME", "unknown"));
136 vars
->add(new ppdcVariable("PLATFORM_ARCH", "unknown"));
146 // 'ppdcSource::~ppdcSource()' - Free a driver source file.
149 ppdcSource::~ppdcSource()
154 base_fonts
->release();
163 // 'ppdcSource::add_include()' - Add an include directory.
167 ppdcSource::add_include(const char *d
) // I - Include directory
173 includes
= new ppdcArray();
175 includes
->add(new ppdcString(d
));
180 // 'ppdcSource::find_driver()' - Find a driver.
183 ppdcDriver
* // O - Driver
184 ppdcSource::find_driver(const char *f
) // I - Driver file name
186 ppdcDriver
*d
; // Current driver
189 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
190 if (!_cups_strcasecmp(f
, d
->pc_file_name
->value
))
198 // 'ppdcSource::find_include()' - Find an include file.
201 char * // O - Found path or NULL
202 ppdcSource::find_include(
203 const char *f
, // I - Include filename
204 const char *base
, // I - Current directory
205 char *n
, // I - Path buffer
206 int nlen
) // I - Path buffer length
208 ppdcString
*dir
; // Include directory
209 char temp
[1024], // Temporary path
210 *ptr
; // Pointer to end of path
213 // Range check input...
214 if (!f
|| !*f
|| !n
|| nlen
< 2)
217 // Check the first character to see if we have <name> or "name"...
220 // Remove the surrounding <> from the name...
221 strlcpy(temp
, f
+ 1, sizeof(temp
));
222 ptr
= temp
+ strlen(temp
) - 1;
226 _cupsLangPrintf(stderr
,
227 _("ppdc: Invalid #include/#po filename \"%s\"."), n
);
236 // Check for the local file relative to the current directory...
237 if (base
&& *base
&& f
[0] != '/')
238 snprintf(n
, nlen
, "%s/%s", base
, f
);
246 // Absolute path that doesn't exist...
251 // Search the include directories, if any...
254 for (dir
= (ppdcString
*)includes
->first(); dir
; dir
= (ppdcString
*)includes
->next())
256 snprintf(n
, nlen
, "%s/%s", dir
->value
, f
);
262 // Search the standard include directories...
263 _cups_globals_t
*cg
= _cupsGlobals(); // Global data
265 snprintf(n
, nlen
, "%s/ppdc/%s", cg
->cups_datadir
, f
);
269 snprintf(n
, nlen
, "%s/po/%s", cg
->cups_datadir
, f
);
278 // 'ppdcSource::find_po()' - Find a message catalog for the given locale.
281 ppdcCatalog
* // O - Message catalog or NULL
282 ppdcSource::find_po(const char *l
) // I - Locale name
284 ppdcCatalog
*cat
; // Current message catalog
287 for (cat
= (ppdcCatalog
*)po_files
->first();
289 cat
= (ppdcCatalog
*)po_files
->next())
290 if (!_cups_strcasecmp(l
, cat
->locale
->value
))
298 // 'ppdcSource::find_size()' - Find a media size.
301 ppdcMediaSize
* // O - Size
302 ppdcSource::find_size(const char *s
) // I - Size name
304 ppdcMediaSize
*m
; // Current media size
307 for (m
= (ppdcMediaSize
*)sizes
->first(); m
; m
= (ppdcMediaSize
*)sizes
->next())
308 if (!_cups_strcasecmp(s
, m
->name
->value
))
316 // 'ppdcSource::find_variable()' - Find a variable.
319 ppdcVariable
* // O - Variable
320 ppdcSource::find_variable(const char *n
)// I - Variable name
322 ppdcVariable
*v
; // Current variable
325 for (v
= (ppdcVariable
*)vars
->first(); v
; v
= (ppdcVariable
*)vars
->next())
326 if (!_cups_strcasecmp(n
, v
->name
->value
))
334 // 'ppdcSource::get_attr()' - Get an attribute.
337 ppdcAttr
* // O - Attribute
338 ppdcSource::get_attr(ppdcFile
*fp
, // I - File to read
339 bool loc
) // I - Localize this attribute?
341 char name
[1024], // Name string
342 selector
[1024], // Selector string
343 *text
, // Text string
344 value
[1024]; // Value string
347 // Get the attribute parameters:
349 // Attribute name selector value
350 if (!get_token(fp
, name
, sizeof(name
)))
352 _cupsLangPrintf(stderr
,
353 _("ppdc: Expected name after %s on line %d of %s."),
354 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
358 if (!get_token(fp
, selector
, sizeof(selector
)))
360 _cupsLangPrintf(stderr
,
361 _("ppdc: Expected selector after %s on line %d of %s."),
362 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
366 if ((text
= strchr(selector
, '/')) != NULL
)
369 if (!get_token(fp
, value
, sizeof(value
)))
371 _cupsLangPrintf(stderr
,
372 _("ppdc: Expected value after %s on line %d of %s."),
373 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
377 return (new ppdcAttr(name
, selector
, text
, value
, loc
));
382 // 'ppdcSource::get_boolean()' - Get a boolean value.
385 int // O - Boolean value
386 ppdcSource::get_boolean(ppdcFile
*fp
) // I - File to read
388 char buffer
[256]; // String buffer
391 if (!get_token(fp
, buffer
, sizeof(buffer
)))
393 _cupsLangPrintf(stderr
,
394 _("ppdc: Expected boolean value on line %d of %s."),
395 fp
->line
, fp
->filename
);
399 if (!_cups_strcasecmp(buffer
, "on") ||
400 !_cups_strcasecmp(buffer
, "yes") ||
401 !_cups_strcasecmp(buffer
, "true"))
403 else if (!_cups_strcasecmp(buffer
, "off") ||
404 !_cups_strcasecmp(buffer
, "no") ||
405 !_cups_strcasecmp(buffer
, "false"))
409 _cupsLangPrintf(stderr
,
410 _("ppdc: Bad boolean value (%s) on line %d of %s."),
411 buffer
, fp
->line
, fp
->filename
);
418 // 'ppdcSource::get_choice()' - Get a choice.
421 ppdcChoice
* // O - Choice data
422 ppdcSource::get_choice(ppdcFile
*fp
) // I - File to read
424 char name
[1024], // Name
429 // Read a choice from the file:
431 // Choice name/text code
432 if (!get_token(fp
, name
, sizeof(name
)))
434 _cupsLangPrintf(stderr
,
435 _("ppdc: Expected choice name/text on line %d of %s."),
436 fp
->line
, fp
->filename
);
440 if ((text
= strchr(name
, '/')) != NULL
)
445 if (!get_token(fp
, code
, sizeof(code
)))
447 _cupsLangPrintf(stderr
, _("ppdc: Expected choice code on line %d of %s."),
448 fp
->line
, fp
->filename
);
452 // Return the new choice
453 return (new ppdcChoice(name
, text
, code
));
458 // 'ppdcSource::get_color_model()' - Get an old-style color model option.
461 ppdcChoice
* // O - Choice data
462 ppdcSource::get_color_model(ppdcFile
*fp
)
465 char name
[1024], // Option name
466 *text
, // Text option
467 temp
[256]; // Temporary string
468 int color_space
, // Colorspace
469 color_order
, // Color order
470 compression
; // Compression mode
473 // Get the ColorModel parameters:
475 // ColorModel name/text colorspace colororder compression
476 if (!get_token(fp
, name
, sizeof(name
)))
478 _cupsLangPrintf(stderr
,
479 _("ppdc: Expected name/text combination for ColorModel on "
480 "line %d of %s."), fp
->line
, fp
->filename
);
484 if ((text
= strchr(name
, '/')) != NULL
)
489 if (!get_token(fp
, temp
, sizeof(temp
)))
491 _cupsLangPrintf(stderr
,
492 _("ppdc: Expected colorspace for ColorModel on line %d of "
493 "%s."), fp
->line
, fp
->filename
);
497 if ((color_space
= get_color_space(temp
)) < 0)
498 color_space
= get_integer(temp
);
500 if (!get_token(fp
, temp
, sizeof(temp
)))
502 _cupsLangPrintf(stderr
,
503 _("ppdc: Expected color order for ColorModel on line %d of "
504 "%s."), fp
->line
, fp
->filename
);
508 if ((color_order
= get_color_order(temp
)) < 0)
509 color_order
= get_integer(temp
);
511 if (!get_token(fp
, temp
, sizeof(temp
)))
513 _cupsLangPrintf(stderr
,
514 _("ppdc: Expected compression for ColorModel on line %d of "
515 "%s."), fp
->line
, fp
->filename
);
519 compression
= get_integer(temp
);
521 snprintf(temp
, sizeof(temp
),
522 "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
524 color_space
, color_order
, compression
);
526 return (new ppdcChoice(name
, text
, temp
));
531 // 'ppdcSource::get_color_order()' - Get an old-style color order value.
534 int // O - Color order value
535 ppdcSource::get_color_order(
536 const char *co
) // I - Color order string
538 if (!_cups_strcasecmp(co
, "chunked") ||
539 !_cups_strcasecmp(co
, "chunky"))
540 return (CUPS_ORDER_CHUNKED
);
541 else if (!_cups_strcasecmp(co
, "banded"))
542 return (CUPS_ORDER_BANDED
);
543 else if (!_cups_strcasecmp(co
, "planar"))
544 return (CUPS_ORDER_PLANAR
);
551 // 'ppdcSource::get_color_profile()' - Get a color profile definition.
554 ppdcProfile
* // O - Color profile
555 ppdcSource::get_color_profile(
556 ppdcFile
*fp
) // I - File to read
558 char resolution
[1024], // Resolution/media type
559 *media_type
; // Media type
560 int i
; // Looping var
561 float g
, // Gamma value
563 m
[9]; // Transform matrix
566 // Get the ColorProfile parameters:
568 // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
569 if (!get_token(fp
, resolution
, sizeof(resolution
)))
571 _cupsLangPrintf(stderr
,
572 _("ppdc: Expected resolution/mediatype following "
573 "ColorProfile on line %d of %s."),
574 fp
->line
, fp
->filename
);
578 if ((media_type
= strchr(resolution
, '/')) != NULL
)
579 *media_type
++ = '\0';
581 media_type
= resolution
;
585 for (i
= 0; i
< 9; i
++)
586 m
[i
] = get_float(fp
);
588 return (new ppdcProfile(resolution
, media_type
, g
, d
, m
));
593 // 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
596 int // O - Colorspace value
597 ppdcSource::get_color_space(
598 const char *cs
) // I - Colorspace string
600 if (!_cups_strcasecmp(cs
, "w"))
601 return (CUPS_CSPACE_W
);
602 else if (!_cups_strcasecmp(cs
, "rgb"))
603 return (CUPS_CSPACE_RGB
);
604 else if (!_cups_strcasecmp(cs
, "rgba"))
605 return (CUPS_CSPACE_RGBA
);
606 else if (!_cups_strcasecmp(cs
, "k"))
607 return (CUPS_CSPACE_K
);
608 else if (!_cups_strcasecmp(cs
, "cmy"))
609 return (CUPS_CSPACE_CMY
);
610 else if (!_cups_strcasecmp(cs
, "ymc"))
611 return (CUPS_CSPACE_YMC
);
612 else if (!_cups_strcasecmp(cs
, "cmyk"))
613 return (CUPS_CSPACE_CMYK
);
614 else if (!_cups_strcasecmp(cs
, "ymck"))
615 return (CUPS_CSPACE_YMCK
);
616 else if (!_cups_strcasecmp(cs
, "kcmy"))
617 return (CUPS_CSPACE_KCMY
);
618 else if (!_cups_strcasecmp(cs
, "kcmycm"))
619 return (CUPS_CSPACE_KCMYcm
);
620 else if (!_cups_strcasecmp(cs
, "gmck"))
621 return (CUPS_CSPACE_GMCK
);
622 else if (!_cups_strcasecmp(cs
, "gmcs"))
623 return (CUPS_CSPACE_GMCS
);
624 else if (!_cups_strcasecmp(cs
, "white"))
625 return (CUPS_CSPACE_WHITE
);
626 else if (!_cups_strcasecmp(cs
, "gold"))
627 return (CUPS_CSPACE_GOLD
);
628 else if (!_cups_strcasecmp(cs
, "silver"))
629 return (CUPS_CSPACE_SILVER
);
630 else if (!_cups_strcasecmp(cs
, "CIEXYZ"))
631 return (CUPS_CSPACE_CIEXYZ
);
632 else if (!_cups_strcasecmp(cs
, "CIELab"))
633 return (CUPS_CSPACE_CIELab
);
634 else if (!_cups_strcasecmp(cs
, "RGBW"))
635 return (CUPS_CSPACE_RGBW
);
636 else if (!_cups_strcasecmp(cs
, "ICC1"))
637 return (CUPS_CSPACE_ICC1
);
638 else if (!_cups_strcasecmp(cs
, "ICC2"))
639 return (CUPS_CSPACE_ICC2
);
640 else if (!_cups_strcasecmp(cs
, "ICC3"))
641 return (CUPS_CSPACE_ICC3
);
642 else if (!_cups_strcasecmp(cs
, "ICC4"))
643 return (CUPS_CSPACE_ICC4
);
644 else if (!_cups_strcasecmp(cs
, "ICC5"))
645 return (CUPS_CSPACE_ICC5
);
646 else if (!_cups_strcasecmp(cs
, "ICC6"))
647 return (CUPS_CSPACE_ICC6
);
648 else if (!_cups_strcasecmp(cs
, "ICC7"))
649 return (CUPS_CSPACE_ICC7
);
650 else if (!_cups_strcasecmp(cs
, "ICC8"))
651 return (CUPS_CSPACE_ICC8
);
652 else if (!_cups_strcasecmp(cs
, "ICC9"))
653 return (CUPS_CSPACE_ICC9
);
654 else if (!_cups_strcasecmp(cs
, "ICCA"))
655 return (CUPS_CSPACE_ICCA
);
656 else if (!_cups_strcasecmp(cs
, "ICCB"))
657 return (CUPS_CSPACE_ICCB
);
658 else if (!_cups_strcasecmp(cs
, "ICCC"))
659 return (CUPS_CSPACE_ICCC
);
660 else if (!_cups_strcasecmp(cs
, "ICCD"))
661 return (CUPS_CSPACE_ICCD
);
662 else if (!_cups_strcasecmp(cs
, "ICCE"))
663 return (CUPS_CSPACE_ICCE
);
664 else if (!_cups_strcasecmp(cs
, "ICCF"))
665 return (CUPS_CSPACE_ICCF
);
672 // 'ppdcSource::get_constraint()' - Get a constraint.
675 ppdcConstraint
* // O - Constraint
676 ppdcSource::get_constraint(ppdcFile
*fp
)// I - File to read
678 char temp
[1024], // One string to rule them all
679 *ptr
, // Pointer into string
680 *option1
, // Constraint option 1
681 *choice1
, // Constraint choice 1
682 *option2
, // Constraint option 2
683 *choice2
; // Constraint choice 2
686 // Read the UIConstaints parameter in one of the following forms:
688 // UIConstraints "*Option1 *Option2"
689 // UIConstraints "*Option1 Choice1 *Option2"
690 // UIConstraints "*Option1 *Option2 Choice2"
691 // UIConstraints "*Option1 Choice1 *Option2 Choice2"
692 if (!get_token(fp
, temp
, sizeof(temp
)))
694 _cupsLangPrintf(stderr
,
695 _("ppdc: Expected constraints string for UIConstraints on "
696 "line %d of %s."), fp
->line
, fp
->filename
);
700 for (ptr
= temp
; isspace(*ptr
); ptr
++);
704 _cupsLangPrintf(stderr
,
705 _("ppdc: Option constraint must *name on line %d of %s."),
706 fp
->line
, fp
->filename
);
712 for (; *ptr
&& !isspace(*ptr
); ptr
++);
713 for (; isspace(*ptr
); *ptr
++ = '\0');
719 for (; *ptr
&& !isspace(*ptr
); ptr
++);
720 for (; isspace(*ptr
); *ptr
++ = '\0');
727 _cupsLangPrintf(stderr
,
728 _("ppdc: Expected two option names on line %d of %s."),
729 fp
->line
, fp
->filename
);
735 for (; *ptr
&& !isspace(*ptr
); ptr
++);
736 for (; isspace(*ptr
); *ptr
++ = '\0');
743 return (new ppdcConstraint(option1
, choice1
, option2
, choice2
));
748 // 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
751 ppdcMediaSize
* // O - Media size
752 ppdcSource::get_custom_size(ppdcFile
*fp
)
755 char name
[1024], // Name
757 size_code
[10240], // PageSize code
758 region_code
[10240]; // PageRegion
759 float width
, // Width
762 bottom
, // Bottom margin
763 right
, // Right margin
767 // Get the name, text, width, length, margins, and code:
769 // CustomMedia name/text width length left bottom right top size-code region-code
770 if (!get_token(fp
, name
, sizeof(name
)))
773 if ((text
= strchr(name
, '/')) != NULL
)
778 if ((width
= get_measurement(fp
)) < 0.0f
)
781 if ((length
= get_measurement(fp
)) < 0.0f
)
784 if ((left
= get_measurement(fp
)) < 0.0f
)
787 if ((bottom
= get_measurement(fp
)) < 0.0f
)
790 if ((right
= get_measurement(fp
)) < 0.0f
)
793 if ((top
= get_measurement(fp
)) < 0.0f
)
796 if (!get_token(fp
, size_code
, sizeof(size_code
)))
799 if (!get_token(fp
, region_code
, sizeof(region_code
)))
802 // Return the new media size...
803 return (new ppdcMediaSize(name
, text
, width
, length
, left
, bottom
,
804 right
, top
, size_code
, region_code
));
809 // 'ppdcSource::get_duplex()' - Get a duplex option.
813 ppdcSource::get_duplex(ppdcFile
*fp
, // I - File to read from
814 ppdcDriver
*d
) // I - Current driver
816 char temp
[256]; // Duplex keyword
817 ppdcAttr
*attr
; // cupsFlipDuplex attribute
818 ppdcGroup
*g
; // Current group
819 ppdcOption
*o
; // Duplex option
822 // Duplex {boolean|none|normal|flip}
823 if (!get_token(fp
, temp
, sizeof(temp
)))
825 _cupsLangPrintf(stderr
,
826 _("ppdc: Expected duplex type after Duplex on line %d of "
827 "%s."), fp
->line
, fp
->filename
);
834 if (!_cups_strcasecmp(temp
, "none") || !_cups_strcasecmp(temp
, "false") ||
835 !_cups_strcasecmp(temp
, "no") || !_cups_strcasecmp(temp
, "off"))
837 g
= d
->find_group("General");
838 if ((o
= g
->find_option("Duplex")) != NULL
)
839 g
->options
->remove(o
);
841 for (attr
= (ppdcAttr
*)d
->attrs
->first();
843 attr
= (ppdcAttr
*)d
->attrs
->next())
844 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
846 d
->attrs
->remove(attr
);
850 else if (!_cups_strcasecmp(temp
, "normal") || !_cups_strcasecmp(temp
, "true") ||
851 !_cups_strcasecmp(temp
, "yes") || !_cups_strcasecmp(temp
, "on") ||
852 !_cups_strcasecmp(temp
, "flip") || !_cups_strcasecmp(temp
, "rotated") ||
853 !_cups_strcasecmp(temp
, "manualtumble"))
855 g
= d
->find_group("General");
856 o
= g
->find_option("Duplex");
860 o
= new ppdcOption(PPDC_PICKONE
, "Duplex", "2-Sided Printing",
861 !_cups_strcasecmp(temp
, "flip") ? PPDC_SECTION_PAGE
:
862 PPDC_SECTION_ANY
, 10.0f
);
863 o
->add_choice(new ppdcChoice("None", "Off (1-Sided)",
864 "<</Duplex false>>setpagedevice"));
865 o
->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
866 "<</Duplex true/Tumble false>>setpagedevice"));
867 o
->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
868 "<</Duplex true/Tumble true>>setpagedevice"));
873 for (attr
= (ppdcAttr
*)d
->attrs
->first();
875 attr
= (ppdcAttr
*)d
->attrs
->next())
876 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
878 if (_cups_strcasecmp(temp
, "flip"))
879 d
->attrs
->remove(attr
);
883 if (!_cups_strcasecmp(temp
, "flip") && !attr
)
884 d
->add_attr(new ppdcAttr("cupsFlipDuplex", NULL
, NULL
, "true"));
886 for (attr
= (ppdcAttr
*)d
->attrs
->first();
888 attr
= (ppdcAttr
*)d
->attrs
->next())
889 if (!strcmp(attr
->name
->value
, "cupsBackSide"))
891 d
->attrs
->remove(attr
);
895 if (!_cups_strcasecmp(temp
, "flip"))
896 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Flipped"));
897 else if (!_cups_strcasecmp(temp
, "rotated"))
898 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Rotated"));
899 else if (!_cups_strcasecmp(temp
, "manualtumble"))
900 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "ManualTumble"));
902 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Normal"));
905 _cupsLangPrintf(stderr
,
906 _("ppdc: Unknown duplex type \"%s\" on line %d of %s."),
907 temp
, fp
->line
, fp
->filename
);
912 // 'ppdcSource::get_filter()' - Get a filter.
915 ppdcFilter
* // O - Filter
916 ppdcSource::get_filter(ppdcFile
*fp
) // I - File to read
918 char type
[1024], // MIME type
919 program
[1024], // Filter program
920 *ptr
; // Pointer into MIME type
921 int cost
; // Relative cost
924 // Read filter parameters in one of the following formats:
926 // Filter "type cost program"
927 // Filter type cost program
929 if (!get_token(fp
, type
, sizeof(type
)))
931 _cupsLangPrintf(stderr
,
932 _("ppdc: Expected a filter definition on line %d of %s."),
933 fp
->line
, fp
->filename
);
937 if ((ptr
= strchr(type
, ' ')) != NULL
)
939 // Old-style filter definition in one string...
941 cost
= strtol(ptr
, &ptr
, 10);
943 while (isspace(*ptr
))
946 strlcpy(program
, ptr
, sizeof(program
));
950 cost
= get_integer(fp
);
952 if (!get_token(fp
, program
, sizeof(program
)))
954 _cupsLangPrintf(stderr
,
955 _("ppdc: Expected a program name on line %d of %s."),
956 fp
->line
, fp
->filename
);
963 _cupsLangPrintf(stderr
,
964 _("ppdc: Invalid empty MIME type for filter on line %d of "
965 "%s."), fp
->line
, fp
->filename
);
969 if (cost
< 0 || cost
> 200)
971 _cupsLangPrintf(stderr
,
972 _("ppdc: Invalid cost for filter on line %d of %s."),
973 fp
->line
, fp
->filename
);
979 _cupsLangPrintf(stderr
,
980 _("ppdc: Invalid empty program name for filter on line %d "
981 "of %s."), fp
->line
, fp
->filename
);
985 return (new ppdcFilter(type
, program
, cost
));
990 // 'ppdcSource::get_float()' - Get a single floating-point number.
994 ppdcSource::get_float(ppdcFile
*fp
) // I - File to read
996 char temp
[256], // String buffer
997 *ptr
; // Pointer into buffer
998 float val
; // Floating point value
1001 // Get the number from the file and range-check...
1002 if (!get_token(fp
, temp
, sizeof(temp
)))
1004 _cupsLangPrintf(stderr
, _("ppdc: Expected real number on line %d of %s."),
1005 fp
->line
, fp
->filename
);
1009 val
= (float)strtod(temp
, &ptr
);
1013 _cupsLangPrintf(stderr
,
1014 _("ppdc: Unknown trailing characters in real number \"%s\" "
1015 "on line %d of %s."), temp
, fp
->line
, fp
->filename
);
1024 // 'ppdcSource::get_font()' - Get a font definition.
1027 ppdcFont
* // O - Font data
1028 ppdcSource::get_font(ppdcFile
*fp
) // I - File to read
1030 char name
[256], // Font name
1031 encoding
[256], // Font encoding
1032 version
[256], // Font version
1033 charset
[256], // Font charset
1034 temp
[256]; // Font status string
1035 ppdcFontStatus status
; // Font status enumeration
1038 // Read font parameters as follows:
1041 // Font name encoding version charset status
1042 // %font name encoding version charset status
1044 // "Name" is the PostScript font name.
1046 // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
1047 // Special, Expert, ExpertSubset, etc.
1049 // "Version" is the version number string.
1051 // "Charset" specifies the characters that are included in the font:
1052 // Standard, Special, Expert, Adobe-Identity, etc.
1054 // "Status" is the keyword ROM or Disk.
1055 if (!get_token(fp
, name
, sizeof(name
)))
1057 _cupsLangPrintf(stderr
,
1058 _("ppdc: Expected name after Font on line %d of %s."),
1059 fp
->line
, fp
->filename
);
1063 if (!strcmp(name
, "*"))
1065 // Include all base fonts...
1069 status
= PPDC_FONT_ROM
;
1073 // Load a full font definition...
1074 if (!get_token(fp
, encoding
, sizeof(encoding
)))
1076 _cupsLangPrintf(stderr
,
1077 _("ppdc: Expected encoding after Font on line %d of "
1078 "%s."), fp
->line
, fp
->filename
);
1082 if (!get_token(fp
, version
, sizeof(version
)))
1084 _cupsLangPrintf(stderr
,
1085 _("ppdc: Expected version after Font on line %d of "
1086 "%s."), fp
->line
, fp
->filename
);
1090 if (!get_token(fp
, charset
, sizeof(charset
)))
1092 _cupsLangPrintf(stderr
,
1093 _("ppdc: Expected charset after Font on line %d of "
1094 "%s."), fp
->line
, fp
->filename
);
1098 if (!get_token(fp
, temp
, sizeof(temp
)))
1100 _cupsLangPrintf(stderr
,
1101 _("ppdc: Expected status after Font on line %d of %s."),
1102 fp
->line
, fp
->filename
);
1106 if (!_cups_strcasecmp(temp
, "ROM"))
1107 status
= PPDC_FONT_ROM
;
1108 else if (!_cups_strcasecmp(temp
, "Disk"))
1109 status
= PPDC_FONT_DISK
;
1112 _cupsLangPrintf(stderr
,
1113 _("ppdc: Bad status keyword %s on line %d of %s."),
1114 temp
, fp
->line
, fp
->filename
);
1119 // printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
1121 return (new ppdcFont(name
, encoding
, version
, charset
, status
));
1126 // 'ppdcSource::get_generic()' - Get a generic old-style option.
1129 ppdcChoice
* // O - Choice data
1130 ppdcSource::get_generic(ppdcFile
*fp
, // I - File to read
1131 const char *keyword
,
1134 // I - Text attribute
1136 // I - Numeric attribute
1138 char name
[1024], // Name
1140 command
[256]; // Command string
1141 int val
; // Numeric value
1144 // Read one of the following parameters:
1147 // Foo integer name/text
1149 val
= get_integer(fp
);
1153 if (!get_token(fp
, name
, sizeof(name
)))
1155 _cupsLangPrintf(stderr
,
1156 _("ppdc: Expected name/text after %s on line %d of %s."),
1157 keyword
, fp
->line
, fp
->filename
);
1161 if ((text
= strchr(name
, '/')) != NULL
)
1169 snprintf(command
, sizeof(command
),
1170 "<</%s(%s)/%s %d>>setpagedevice",
1171 tattr
, name
, nattr
, val
);
1173 snprintf(command
, sizeof(command
),
1174 "<</%s %d>>setpagedevice",
1178 snprintf(command
, sizeof(command
),
1179 "<</%s(%s)>>setpagedevice",
1182 return (new ppdcChoice(name
, text
, command
));
1187 // 'ppdcSource::get_group()' - Get an option group.
1190 ppdcGroup
* // O - Group
1191 ppdcSource::get_group(ppdcFile
*fp
, // I - File to read
1192 ppdcDriver
*d
) // I - Printer driver
1194 char name
[1024], // UI name
1196 ppdcGroup
*g
; // Group
1199 // Read the Group parameters:
1202 if (!get_token(fp
, name
, sizeof(name
)))
1204 _cupsLangPrintf(stderr
,
1205 _("ppdc: Expected group name/text on line %d of %s."),
1206 fp
->line
, fp
->filename
);
1210 if ((text
= strchr(name
, '/')) != NULL
)
1215 // See if the group already exists...
1216 if ((g
= d
->find_group(name
)) == NULL
)
1218 // Nope, add a new one...
1219 g
= new ppdcGroup(name
, text
);
1227 // 'ppdcSource::get_installable()' - Get an installable option.
1230 ppdcOption
* // O - Option
1231 ppdcSource::get_installable(ppdcFile
*fp
)
1234 char name
[1024], // Name for installable option
1235 *text
; // Text for installable option
1236 ppdcOption
*o
; // Option
1239 // Read the parameter for an installable option:
1241 // Installable name/text
1242 if (!get_token(fp
, name
, sizeof(name
)))
1244 _cupsLangPrintf(stderr
,
1245 _("ppdc: Expected name/text after Installable on line %d "
1246 "of %s."), fp
->line
, fp
->filename
);
1250 if ((text
= strchr(name
, '/')) != NULL
)
1255 // Create the option...
1256 o
= new ppdcOption(PPDC_BOOLEAN
, name
, text
, PPDC_SECTION_ANY
, 10.0f
);
1258 // Add the false and true choices...
1259 o
->add_choice(new ppdcChoice("False", "Not Installed", ""));
1260 o
->add_choice(new ppdcChoice("True", "Installed", ""));
1267 // 'ppdcSource::get_integer()' - Get an integer value from a string.
1270 #define PPDC_XX -1 // Bad
1271 #define PPDC_EQ 0 // ==
1272 #define PPDC_NE 1 // !=
1273 #define PPDC_LT 2 // <
1274 #define PPDC_LE 3 // <=
1275 #define PPDC_GT 4 // >
1276 #define PPDC_GE 5 // >=
1278 int // O - Integer value
1279 ppdcSource::get_integer(const char *v
) // I - Value string
1282 long temp
, // Temporary value
1283 temp2
; // Second temporary value
1284 char *newv
, // New value string pointer
1285 ch
; // Temporary character
1286 ppdcVariable
*var
; // #define variable
1287 int compop
; // Comparison operator
1290 // Parse the value string...
1294 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1296 // Return a simple integer value
1297 val
= strtol(v
, (char **)&v
, 0);
1298 if (*v
|| val
== LONG_MIN
)
1305 // Evaluate and expression in any of the following formats:
1307 // (number number ... number) Bitwise OR of all numbers
1308 // (NAME == value) 1 if equal, 0 otherwise
1309 // (NAME != value) 1 if not equal, 0 otherwise
1310 // (NAME < value) 1 if less than, 0 otherwise
1311 // (NAME <= value) 1 if less than or equal, 0 otherwise
1312 // (NAME > value) 1 if greater than, 0 otherwise
1313 // (NAME >= value) 1 if greater than or equal, 0 otherwise
1318 while (*v
&& *v
!= ')')
1320 // Skip leading whitespace...
1321 while (*v
&& isspace(*v
& 255))
1324 if (!*v
|| *v
== ')')
1327 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1329 // Bitwise OR a number...
1330 temp
= strtol(v
, &newv
, 0);
1332 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1338 // NAME logicop value
1339 for (newv
= (char *)v
+ 1;
1340 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1347 if ((var
= find_variable(v
)) != NULL
)
1349 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1351 else if (isdigit(var
->value
->value
[0] & 255) ||
1352 var
->value
->value
[0] == '-' ||
1353 var
->value
->value
[0] == '+')
1354 temp
= strtol(var
->value
->value
, NULL
, 0);
1362 while (isspace(*newv
& 255))
1365 if (!strncmp(newv
, "==", 2))
1370 else if (!strncmp(newv
, "!=", 2))
1375 else if (!strncmp(newv
, "<=", 2))
1380 else if (*newv
== '<')
1385 else if (!strncmp(newv
, ">=", 2))
1390 else if (*newv
== '>')
1398 if (compop
!= PPDC_XX
)
1400 while (isspace(*newv
& 255))
1403 if (*newv
== ')' || !*newv
)
1406 if (isdigit(*newv
& 255) || *newv
== '-' || *newv
== '+')
1408 // Get the second number...
1409 temp2
= strtol(newv
, &newv
, 0);
1410 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1416 // Lookup the second name...
1417 for (v
= newv
, newv
++;
1418 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1424 if ((var
= find_variable(v
)) != NULL
)
1426 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1428 else if (isdigit(var
->value
->value
[0] & 255) ||
1429 var
->value
->value
[0] == '-' ||
1430 var
->value
->value
[0] == '+')
1431 temp2
= strtol(var
->value
->value
, NULL
, 0);
1441 // Do the comparison...
1445 temp
= temp
== temp2
;
1448 temp
= temp
!= temp2
;
1451 temp
= temp
< temp2
;
1454 temp
= temp
<= temp2
;
1457 temp
= temp
> temp2
;
1460 temp
= temp
>= temp2
;
1470 if (*v
== ')' && !v
[1])
1475 else if ((var
= find_variable(v
)) != NULL
)
1477 // NAME by itself returns 1 if the #define variable is not blank and
1479 return (var
->value
->value
&& var
->value
->value
[0] &&
1480 strcmp(var
->value
->value
, "0"));
1484 // Anything else is an error...
1491 // 'ppdcSource::get_integer()' - Get an integer value from a file.
1494 int // O - Integer value
1495 ppdcSource::get_integer(ppdcFile
*fp
) // I - File to read
1497 char temp
[1024]; // String buffer
1500 if (!get_token(fp
, temp
, sizeof(temp
)))
1502 _cupsLangPrintf(stderr
, _("ppdc: Expected integer on line %d of %s."),
1503 fp
->line
, fp
->filename
);
1507 return (get_integer(temp
));
1512 // 'ppdcSource::get_measurement()' - Get a measurement value.
1515 float // O - Measurement value in points
1516 ppdcSource::get_measurement(ppdcFile
*fp
)
1519 char buffer
[256], // Number buffer
1520 *ptr
; // Pointer into buffer
1521 float val
; // Measurement value
1524 // Grab a token from the file...
1525 if (!get_token(fp
, buffer
, sizeof(buffer
)))
1528 // Get the floating point value of "s" and skip all digits and decimal points.
1529 val
= (float)strtod(buffer
, &ptr
);
1531 // Check for a trailing unit specifier...
1532 if (!_cups_strcasecmp(ptr
, "mm"))
1533 val
*= 72.0f
/ 25.4f
;
1534 else if (!_cups_strcasecmp(ptr
, "cm"))
1535 val
*= 72.0f
/ 2.54f
;
1536 else if (!_cups_strcasecmp(ptr
, "m"))
1537 val
*= 72.0f
/ 0.0254f
;
1538 else if (!_cups_strcasecmp(ptr
, "in"))
1540 else if (!_cups_strcasecmp(ptr
, "ft"))
1541 val
*= 72.0f
* 12.0f
;
1542 else if (_cups_strcasecmp(ptr
, "pt") && *ptr
)
1550 // 'ppdcSource::get_option()' - Get an option definition.
1553 ppdcOption
* // O - Option
1554 ppdcSource::get_option(ppdcFile
*fp
, // I - File to read
1555 ppdcDriver
*d
, // I - Printer driver
1556 ppdcGroup
*g
) // I - Current group
1558 char name
[1024], // UI name
1560 type
[256]; // UI type string
1561 ppdcOptType ot
; // Option type value
1562 ppdcOptSection section
; // Option section
1563 float order
; // Option order
1564 ppdcOption
*o
; // Option
1565 ppdcGroup
*mg
; // Matching group, if any
1568 // Read the Option parameters:
1570 // Option name/text type section order
1571 if (!get_token(fp
, name
, sizeof(name
)))
1573 _cupsLangPrintf(stderr
,
1574 _("ppdc: Expected option name/text on line %d of %s."),
1575 fp
->line
, fp
->filename
);
1579 if ((text
= strchr(name
, '/')) != NULL
)
1584 if (!get_token(fp
, type
, sizeof(type
)))
1586 _cupsLangPrintf(stderr
, _("ppdc: Expected option type on line %d of %s."),
1587 fp
->line
, fp
->filename
);
1591 if (!_cups_strcasecmp(type
, "boolean"))
1593 else if (!_cups_strcasecmp(type
, "pickone"))
1595 else if (!_cups_strcasecmp(type
, "pickmany"))
1599 _cupsLangPrintf(stderr
,
1600 _("ppdc: Invalid option type \"%s\" on line %d of %s."),
1601 type
, fp
->line
, fp
->filename
);
1605 if (!get_token(fp
, type
, sizeof(type
)))
1607 _cupsLangPrintf(stderr
,
1608 _("ppdc: Expected option section on line %d of %s."),
1609 fp
->line
, fp
->filename
);
1613 if (!_cups_strcasecmp(type
, "AnySetup"))
1614 section
= PPDC_SECTION_ANY
;
1615 else if (!_cups_strcasecmp(type
, "DocumentSetup"))
1616 section
= PPDC_SECTION_DOCUMENT
;
1617 else if (!_cups_strcasecmp(type
, "ExitServer"))
1618 section
= PPDC_SECTION_EXIT
;
1619 else if (!_cups_strcasecmp(type
, "JCLSetup"))
1620 section
= PPDC_SECTION_JCL
;
1621 else if (!_cups_strcasecmp(type
, "PageSetup"))
1622 section
= PPDC_SECTION_PAGE
;
1623 else if (!_cups_strcasecmp(type
, "Prolog"))
1624 section
= PPDC_SECTION_PROLOG
;
1627 _cupsLangPrintf(stderr
,
1628 _("ppdc: Invalid option section \"%s\" on line %d of "
1629 "%s."), type
, fp
->line
, fp
->filename
);
1633 order
= get_float(fp
);
1635 // See if the option already exists...
1636 if ((o
= d
->find_option_group(name
, &mg
)) == NULL
)
1638 // Nope, add a new one...
1639 o
= new ppdcOption(ot
, name
, text
, section
, order
);
1641 else if (o
->type
!= ot
)
1643 _cupsLangPrintf(stderr
,
1644 _("ppdc: Option %s redefined with a different type on line "
1645 "%d of %s."), name
, fp
->line
, fp
->filename
);
1650 _cupsLangPrintf(stderr
,
1651 _("ppdc: Option %s defined in two different groups on line "
1652 "%d of %s."), name
, fp
->line
, fp
->filename
);
1661 // 'ppdcSource::get_po()' - Get a message catalog.
1664 ppdcCatalog
* // O - Message catalog
1665 ppdcSource::get_po(ppdcFile
*fp
) // I - File to read
1667 char locale
[32], // Locale name
1668 poname
[1024], // Message catalog filename
1669 basedir
[1024], // Base directory
1670 *baseptr
, // Pointer into directory
1671 pofilename
[1024]; // Full filename of message catalog
1672 ppdcCatalog
*cat
; // Message catalog
1675 // Read the #po parameters:
1677 // #po locale "filename.po"
1678 if (!get_token(fp
, locale
, sizeof(locale
)))
1680 _cupsLangPrintf(stderr
,
1681 _("ppdc: Expected locale after #po on line %d of %s."),
1682 fp
->line
, fp
->filename
);
1686 if (!get_token(fp
, poname
, sizeof(poname
)))
1688 _cupsLangPrintf(stderr
,
1689 _("ppdc: Expected filename after #po %s on line %d of "
1690 "%s."), locale
, fp
->line
, fp
->filename
);
1694 // See if the locale is already loaded...
1695 if (find_po(locale
))
1697 _cupsLangPrintf(stderr
,
1698 _("ppdc: Duplicate #po for locale %s on line %d of %s."),
1699 locale
, fp
->line
, fp
->filename
);
1703 // Figure out the current directory...
1704 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
1706 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
1709 strlcpy(basedir
, ".", sizeof(basedir
));
1711 // Find the po file...
1712 pofilename
[0] = '\0';
1715 find_include(poname
, basedir
, pofilename
, sizeof(pofilename
)))
1717 // Found it, so load it...
1718 cat
= new ppdcCatalog(locale
, pofilename
);
1720 // Reset the filename to the name supplied by the user...
1721 cat
->filename
->release();
1722 cat
->filename
= new ppdcString(poname
);
1724 // Return the catalog...
1729 _cupsLangPrintf(stderr
,
1730 _("ppdc: Unable to find #po file %s on line %d of %s."),
1731 poname
, fp
->line
, fp
->filename
);
1738 // 'ppdcSource::get_resolution()' - Get an old-style resolution option.
1741 ppdcChoice
* // O - Choice data
1742 ppdcSource::get_resolution(ppdcFile
*fp
)// I - File to read
1744 char name
[1024], // Name
1746 temp
[256], // Temporary string
1747 command
[256], // Command string
1748 *commptr
; // Pointer into command
1749 int xdpi
, ydpi
, // X + Y resolution
1750 color_order
, // Color order
1751 color_space
, // Colorspace
1752 compression
, // Compression mode
1753 depth
, // Bits per color
1754 row_count
, // Row count
1755 row_feed
, // Row feed
1756 row_step
; // Row step/interval
1759 // Read the resolution parameters:
1761 // Resolution colorspace bits row-count row-feed row-step name/text
1762 if (!get_token(fp
, temp
, sizeof(temp
)))
1764 _cupsLangPrintf(stderr
,
1765 _("ppdc: Expected override field after Resolution on line "
1766 "%d of %s."), fp
->line
, fp
->filename
);
1770 color_order
= get_color_order(temp
);
1771 color_space
= get_color_space(temp
);
1772 compression
= get_integer(temp
);
1774 depth
= get_integer(fp
);
1775 row_count
= get_integer(fp
);
1776 row_feed
= get_integer(fp
);
1777 row_step
= get_integer(fp
);
1779 if (!get_token(fp
, name
, sizeof(name
)))
1781 _cupsLangPrintf(stderr
,
1782 _("ppdc: Expected name/text after Resolution on line %d of "
1783 "%s."), fp
->line
, fp
->filename
);
1787 if ((text
= strchr(name
, '/')) != NULL
)
1792 switch (sscanf(name
, "%dx%d", &xdpi
, &ydpi
))
1795 _cupsLangPrintf(stderr
,
1796 _("ppdc: Bad resolution name \"%s\" on line %d of "
1797 "%s."), name
, fp
->line
, fp
->filename
);
1804 // Create the necessary PS commands...
1805 snprintf(command
, sizeof(command
),
1806 "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
1807 "/cupsRowFeed %d/cupsRowStep %d",
1808 xdpi
, ydpi
, depth
, row_count
, row_feed
, row_step
);
1809 commptr
= command
+ strlen(command
);
1811 if (color_order
>= 0)
1813 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1814 "/cupsColorOrder %d", color_order
);
1815 commptr
+= strlen(commptr
);
1818 if (color_space
>= 0)
1820 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1821 "/cupsColorSpace %d", color_space
);
1822 commptr
+= strlen(commptr
);
1825 if (compression
>= 0)
1827 snprintf(commptr
, sizeof(command
) - (commptr
- command
),
1828 "/cupsCompression %d", compression
);
1829 commptr
+= strlen(commptr
);
1832 snprintf(commptr
, sizeof(command
) - (commptr
- command
), ">>setpagedevice");
1834 // Return the new choice...
1835 return (new ppdcChoice(name
, text
, command
));
1840 // 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
1843 ppdcProfile
* // O - Color profile
1844 ppdcSource::get_simple_profile(ppdcFile
*fp
)
1847 char resolution
[1024], // Resolution/media type
1848 *media_type
; // Media type
1849 float m
[9]; // Transform matrix
1850 float kd
, rd
, g
; // Densities and gamma
1851 float red
, green
, blue
; // RGB adjustments
1852 float yellow
; // Yellow density
1853 float color
; // Color density values
1856 // Get the SimpleColorProfile parameters:
1858 // SimpleColorProfile resolution/mediatype black-density yellow-density
1859 // red-density gamma red-adjust green-adjust blue-adjust
1860 if (!get_token(fp
, resolution
, sizeof(resolution
)))
1862 _cupsLangPrintf(stderr
,
1863 _("ppdc: Expected resolution/mediatype following "
1864 "SimpleColorProfile on line %d of %s."),
1865 fp
->line
, fp
->filename
);
1869 if ((media_type
= strchr(resolution
, '/')) != NULL
)
1870 *media_type
++ = '\0';
1872 media_type
= resolution
;
1874 // Collect the profile parameters...
1876 yellow
= get_float(fp
);
1879 red
= get_float(fp
);
1880 green
= get_float(fp
);
1881 blue
= get_float(fp
);
1883 // Build the color profile...
1884 color
= 0.5f
* rd
/ kd
- kd
;
1886 m
[1] = color
+ blue
; // C + M (blue)
1887 m
[2] = color
- green
; // C + Y (green)
1888 m
[3] = color
- blue
; // M + C (blue)
1890 m
[5] = color
+ red
; // M + Y (red)
1891 m
[6] = yellow
* (color
+ green
); // Y + C (green)
1892 m
[7] = yellow
* (color
- red
); // Y + M (red)
1900 else if (m
[3] > 0.0f
)
1911 else if (m
[6] > 0.0f
)
1922 else if (m
[7] > 0.0f
)
1928 // Return the new profile...
1929 return (new ppdcProfile(resolution
, media_type
, g
, kd
, m
));
1934 // 'ppdcSource::get_size()' - Get a media size definition from a file.
1937 ppdcMediaSize
* // O - Media size
1938 ppdcSource::get_size(ppdcFile
*fp
) // I - File to read
1940 char name
[1024], // Name
1942 float width
, // Width
1946 // Get the name, text, width, and length:
1948 // #media name/text width length
1949 if (!get_token(fp
, name
, sizeof(name
)))
1952 if ((text
= strchr(name
, '/')) != NULL
)
1957 if ((width
= get_measurement(fp
)) < 0.0f
)
1960 if ((length
= get_measurement(fp
)) < 0.0f
)
1963 // Return the new media size...
1964 return (new ppdcMediaSize(name
, text
, width
, length
, 0.0f
, 0.0f
, 0.0f
, 0.0f
));
1969 // 'ppdcSource::get_token()' - Get a token from a file.
1972 char * // O - Token string or NULL
1973 ppdcSource::get_token(ppdcFile
*fp
, // I - File to read
1974 char *buffer
, // I - Buffer
1975 int buflen
) // I - Length of buffer
1977 char *bufptr
, // Pointer into string buffer
1978 *bufend
; // End of string buffer
1979 int ch
, // Character from file
1980 nextch
, // Next char in file
1981 quote
, // Quote character used...
1982 empty
, // Empty input?
1983 startline
; // Start line for quote
1984 char name
[256], // Name string
1985 *nameptr
; // Name pointer
1986 ppdcVariable
*var
; // Variable pointer
1989 // Mark the beginning and end of the buffer...
1991 bufend
= buffer
+ buflen
- 1;
1993 // Loop intil we've read a token...
1998 while ((ch
= fp
->get()) != EOF
)
2000 if (isspace(ch
) && !quote
)
2009 // Variable substitution
2012 for (nameptr
= name
; (ch
= fp
->peek()) != EOF
;)
2014 if (!isalnum(ch
) && ch
!= '_')
2016 else if (nameptr
< (name
+ sizeof(name
) - 1))
2017 *nameptr
++ = fp
->get();
2020 if (nameptr
== name
)
2022 // Just substitute this character...
2026 if (bufptr
< bufend
)
2027 *bufptr
++ = fp
->get();
2032 _cupsLangPrintf(stderr
,
2033 _("ppdc: Bad variable substitution ($%c) on line %d "
2034 "of %s."), ch
, fp
->line
, fp
->filename
);
2036 if (bufptr
< bufend
)
2042 // Substitute the variable value...
2044 var
= find_variable(name
);
2047 strlcpy(bufptr
, var
->value
->value
, bufend
- bufptr
+ 1);
2048 bufptr
+= strlen(bufptr
);
2052 if (!(cond_state
& PPDC_COND_SKIP
))
2053 _cupsLangPrintf(stderr
,
2054 _("ppdc: Undefined variable (%s) on line %d of "
2055 "%s."), name
, fp
->line
, fp
->filename
);
2057 snprintf(bufptr
, bufend
- bufptr
+ 1, "$%s", name
);
2058 bufptr
+= strlen(bufptr
);
2062 else if (ch
== '/' && !quote
)
2064 // Possibly a comment...
2065 nextch
= fp
->peek();
2072 while ((nextch
= fp
->get()) != EOF
)
2074 if (ch
== '*' && nextch
== '/')
2083 else if (nextch
== '/')
2086 while ((nextch
= fp
->get()) != EOF
)
2098 if (bufptr
< bufend
)
2102 else if (ch
== '\'' || ch
== '\"')
2108 // Ending the current quoted string...
2113 // Insert the opposing quote char...
2114 if (bufptr
< bufend
)
2119 // Start a new quoted string...
2120 startline
= fp
->line
;
2124 else if ((ch
== '(' || ch
== '<') && !quote
)
2128 startline
= fp
->line
;
2130 if (bufptr
< bufend
)
2133 else if ((ch
== ')' && quote
== '(') || (ch
== '>' && quote
== '<'))
2137 if (bufptr
< bufend
)
2140 else if (ch
== '\\')
2144 if ((ch
= fp
->get()) == EOF
)
2147 if (bufptr
< bufend
)
2150 else if (bufptr
< bufend
)
2156 if ((ch
== '{' || ch
== '}') && !quote
)
2163 _cupsLangPrintf(stderr
,
2164 _("ppdc: Unterminated string starting with %c on line %d "
2165 "of %s."), quote
, startline
, fp
->filename
);
2181 // 'ppdcSource::get_variable()' - Get a variable definition.
2184 ppdcVariable
* // O - Variable
2185 ppdcSource::get_variable(ppdcFile
*fp
) // I - File to read
2187 char name
[1024], // Name
2188 value
[1024]; // Value
2191 // Get the name and value:
2193 // #define name value
2194 if (!get_token(fp
, name
, sizeof(name
)))
2197 if (!get_token(fp
, value
, sizeof(value
)))
2200 // Set the variable...
2201 return (set_variable(name
, value
));
2206 // 'ppdcSource::quotef()' - Write a formatted, quoted string...
2209 int // O - Number bytes on success, -1 on failure
2210 ppdcSource::quotef(cups_file_t
*fp
, // I - File to write to
2211 const char *format
, // I - Printf-style format string
2212 ...) // I - Additional args as needed
2214 va_list ap
; // Pointer to additional arguments
2215 int bytes
; // Bytes written
2216 char sign
, // Sign of format width
2217 size
, // Size character (h, l, L)
2218 type
; // Format type character
2219 const char *bufformat
; // Start of format
2220 int width
, // Width of field
2221 prec
; // Number of characters of precision
2222 char tformat
[100]; // Temporary format string for fprintf()
2223 char *s
; // Pointer to string
2224 int slen
; // Length of string
2225 int i
; // Looping var
2228 // Range check input...
2232 // Loop through the format string, formatting as needed...
2233 va_start(ap
, format
);
2246 cupsFilePutChar(fp
, *format
++);
2250 else if (strchr(" -+#\'", *format
))
2256 while (isdigit(*format
))
2257 width
= width
* 10 + *format
++ - '0';
2264 while (isdigit(*format
))
2265 prec
= prec
* 10 + *format
++ - '0';
2270 if (*format
== 'l' && format
[1] == 'l')
2275 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
2287 case 'E' : // Floating point formats
2292 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2295 memcpy(tformat
, bufformat
, format
- bufformat
);
2296 tformat
[format
- bufformat
] = '\0';
2298 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, double));
2301 case 'B' : // Integer formats
2309 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2312 memcpy(tformat
, bufformat
, format
- bufformat
);
2313 tformat
[format
- bufformat
] = '\0';
2315 # ifdef HAVE_LONG_LONG
2317 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long long));
2319 # endif /* HAVE_LONG_LONG */
2321 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long));
2323 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, int));
2326 case 'p' : // Pointer value
2327 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2330 memcpy(tformat
, bufformat
, format
- bufformat
);
2331 tformat
[format
- bufformat
] = '\0';
2333 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, void *));
2336 case 'c' : // Character or character array
2340 cupsFilePutChar(fp
, va_arg(ap
, int));
2344 cupsFileWrite(fp
, va_arg(ap
, char *), width
);
2349 case 's' : // String
2350 if ((s
= va_arg(ap
, char *)) == NULL
)
2351 s
= (char *)"(nil)";
2354 if (slen
> width
&& prec
!= width
)
2362 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2363 cupsFilePutChar(fp
, ' ');
2366 for (i
= slen
; i
> 0; i
--, s
++, bytes
++)
2368 if (*s
== '\\' || *s
== '\"')
2370 cupsFilePutChar(fp
, '\\');
2374 cupsFilePutChar(fp
, *s
);
2379 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2380 cupsFilePutChar(fp
, ' ');
2387 cupsFilePutChar(fp
, *format
++);
2394 // Return the number of characters written.
2400 // 'ppdcSource::read_file()' - Read a driver source file.
2404 ppdcSource::read_file(const char *f
, // I - File to read
2405 cups_file_t
*ffp
) // I - File pointer to use
2407 ppdcFile
*fp
= new ppdcFile(f
, ffp
);
2411 if (cond_current
!= cond_stack
)
2412 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."), f
);
2417 // 'ppdcSource::scan_file()' - Scan a driver source file.
2421 ppdcSource::scan_file(ppdcFile
*fp
, // I - File to read
2422 ppdcDriver
*td
, // I - Driver template
2423 bool inc
) // I - Including?
2425 ppdcDriver
*d
; // Current driver
2426 ppdcGroup
*g
, // Current group
2427 *mg
, // Matching group
2428 *general
, // General options group
2429 *install
; // Installable options group
2430 ppdcOption
*o
; // Current option
2431 ppdcChoice
*c
; // Current choice
2432 char temp
[256], // Token from file...
2433 *ptr
; // Pointer into token
2434 int isdefault
; // Default option?
2437 // Initialize things as needed...
2444 d
= new ppdcDriver(td
);
2446 if ((general
= d
->find_group("General")) == NULL
)
2448 general
= new ppdcGroup("General", NULL
);
2449 d
->add_group(general
);
2452 if ((install
= d
->find_group("InstallableOptions")) == NULL
)
2454 install
= new ppdcGroup("InstallableOptions", "Installable Options");
2455 d
->add_group(install
);
2458 // Loop until EOF or }
2462 while (get_token(fp
, temp
, sizeof(temp
)))
2466 // Mark the next choice as the default
2469 for (ptr
= temp
; ptr
[1]; ptr
++)
2476 // Don't mark the next choice as the default
2480 if (!_cups_strcasecmp(temp
, "}"))
2482 // Close this one out...
2485 else if (!_cups_strcasecmp(temp
, "{"))
2487 // Open a new child...
2490 else if (!_cups_strcasecmp(temp
, "#if"))
2492 if ((cond_current
- cond_stack
) >= 100)
2494 _cupsLangPrintf(stderr
,
2495 _("ppdc: Too many nested #if's on line %d of %s."),
2496 fp
->line
, fp
->filename
);
2501 if (get_integer(fp
) > 0)
2502 *cond_current
= PPDC_COND_SATISFIED
;
2505 *cond_current
= PPDC_COND_SKIP
;
2506 cond_state
|= PPDC_COND_SKIP
;
2509 else if (!_cups_strcasecmp(temp
, "#elif"))
2511 if (cond_current
== cond_stack
)
2513 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2514 fp
->line
, fp
->filename
);
2518 if (*cond_current
& PPDC_COND_SATISFIED
)
2521 *cond_current
|= PPDC_COND_SKIP
;
2523 else if (get_integer(fp
) > 0)
2525 *cond_current
|= PPDC_COND_SATISFIED
;
2526 *cond_current
&= ~PPDC_COND_SKIP
;
2529 *cond_current
|= PPDC_COND_SKIP
;
2531 // Update the current state
2532 int *cond_temp
= cond_current
; // Temporary stack pointer
2534 cond_state
= PPDC_COND_NORMAL
;
2535 while (cond_temp
> cond_stack
)
2536 if (*cond_temp
& PPDC_COND_SKIP
)
2538 cond_state
= PPDC_COND_SKIP
;
2544 else if (!_cups_strcasecmp(temp
, "#else"))
2546 if (cond_current
== cond_stack
)
2548 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2549 fp
->line
, fp
->filename
);
2553 if (*cond_current
& PPDC_COND_SATISFIED
)
2554 *cond_current
|= PPDC_COND_SKIP
;
2557 *cond_current
|= PPDC_COND_SATISFIED
;
2558 *cond_current
&= ~PPDC_COND_SKIP
;
2561 // Update the current state
2562 int *cond_temp
= cond_current
; // Temporary stack pointer
2564 cond_state
= PPDC_COND_NORMAL
;
2565 while (cond_temp
> cond_stack
)
2566 if (*cond_temp
& PPDC_COND_SKIP
)
2568 cond_state
= PPDC_COND_SKIP
;
2574 else if (!_cups_strcasecmp(temp
, "#endif"))
2576 if (cond_current
== cond_stack
)
2578 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2579 fp
->line
, fp
->filename
);
2585 // Update the current state
2586 int *cond_temp
= cond_current
; // Temporary stack pointer
2588 cond_state
= PPDC_COND_NORMAL
;
2589 while (cond_temp
> cond_stack
)
2590 if (*cond_temp
& PPDC_COND_SKIP
)
2592 cond_state
= PPDC_COND_SKIP
;
2598 else if (!_cups_strcasecmp(temp
, "#define"))
2600 // Get the variable...
2603 else if (!_cups_strcasecmp(temp
, "#include"))
2605 // #include filename
2606 char basedir
[1024], // Base directory
2607 *baseptr
, // Pointer into directory
2608 inctemp
[1024], // Initial filename
2609 incname
[1024]; // Include filename
2610 ppdcFile
*incfile
; // Include file
2611 int *old_current
= cond_current
;
2612 // Previous current stack
2615 // Get the include name...
2616 if (!get_token(fp
, inctemp
, sizeof(inctemp
)))
2618 _cupsLangPrintf(stderr
,
2619 _("ppdc: Expected include filename on line %d of "
2620 "%s."), fp
->line
, fp
->filename
);
2627 // Figure out the current directory...
2628 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
2630 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
2633 strlcpy(basedir
, ".", sizeof(basedir
));
2635 // Find the include file...
2636 if (find_include(inctemp
, basedir
, incname
, sizeof(incname
)))
2638 // Open the include file, scan it, and then close it...
2639 incfile
= new ppdcFile(incname
);
2640 scan_file(incfile
, d
, true);
2643 if (cond_current
!= old_current
)
2644 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."),
2650 _cupsLangPrintf(stderr
,
2651 _("ppdc: Unable to find include file \"%s\" on line %d "
2652 "of %s."), inctemp
, fp
->line
, fp
->filename
);
2656 else if (!_cups_strcasecmp(temp
, "#media"))
2658 ppdcMediaSize
*m
; // Media size
2661 // Get a media size...
2671 else if (!_cups_strcasecmp(temp
, "#po"))
2673 ppdcCatalog
*cat
; // Message catalog
2676 // Get a message catalog...
2686 else if (!_cups_strcasecmp(temp
, "Attribute") ||
2687 !_cups_strcasecmp(temp
, "LocAttribute"))
2689 ppdcAttr
*a
; // Attribute
2692 // Get an attribute...
2693 a
= get_attr(fp
, !_cups_strcasecmp(temp
, "LocAttribute"));
2702 else if (!_cups_strcasecmp(temp
, "Choice"))
2715 // Add it to the current option...
2718 _cupsLangPrintf(stderr
,
2719 _("ppdc: Choice found on line %d of %s with no "
2720 "Option."), fp
->line
, fp
->filename
);
2727 o
->set_defchoice(c
);
2729 else if (!_cups_strcasecmp(temp
, "ColorDevice"))
2731 // ColorDevice boolean
2735 d
->color_device
= get_boolean(fp
);
2737 else if (!_cups_strcasecmp(temp
, "ColorModel"))
2739 // Get the color model
2740 c
= get_color_model(fp
);
2750 // Add the choice to the ColorModel option...
2751 if ((o
= d
->find_option("ColorModel")) == NULL
)
2753 // Create the ColorModel option...
2754 o
= new ppdcOption(PPDC_PICKONE
, "ColorModel", "Color Mode", PPDC_SECTION_ANY
, 10.0f
);
2762 o
->set_defchoice(c
);
2766 else if (!_cups_strcasecmp(temp
, "ColorProfile"))
2768 ppdcProfile
*p
; // Color profile
2771 // Get the color profile...
2772 p
= get_color_profile(fp
);
2779 d
->profiles
->add(p
);
2782 else if (!_cups_strcasecmp(temp
, "Copyright"))
2785 char copytemp
[8192], // Copyright string
2786 *copyptr
, // Pointer into string
2787 *copyend
; // Pointer to end of string
2790 // Get the copyright string...
2791 if (!get_token(fp
, copytemp
, sizeof(temp
)))
2793 _cupsLangPrintf(stderr
,
2794 _("ppdc: Expected string after Copyright on line %d "
2795 "of %s."), fp
->line
, fp
->filename
);
2802 // Break it up into individual lines...
2803 for (copyptr
= copytemp
; copyptr
; copyptr
= copyend
)
2805 if ((copyend
= strchr(copyptr
, '\n')) != NULL
)
2808 d
->copyright
->add(new ppdcString(copyptr
));
2811 else if (!_cups_strcasecmp(temp
, "CustomMedia"))
2813 ppdcMediaSize
*m
; // Media size
2816 // Get a custom media size...
2817 m
= get_custom_size(fp
);
2829 d
->set_default_size(m
);
2831 else if (!_cups_strcasecmp(temp
, "Cutter"))
2834 int have_cutter
; // Have a paper cutter?
2837 have_cutter
= get_boolean(fp
);
2838 if (have_cutter
<= 0 || cond_state
)
2841 if ((o
= d
->find_option("CutMedia")) == NULL
)
2843 o
= new ppdcOption(PPDC_BOOLEAN
, "CutMedia", "Cut Media", PPDC_SECTION_ANY
, 10.0f
);
2848 c
= new ppdcChoice("False", NULL
, "<</CutMedia 0>>setpagedevice");
2850 o
->set_defchoice(c
);
2852 c
= new ppdcChoice("True", NULL
, "<</CutMedia 4>>setpagedevice");
2858 else if (!_cups_strcasecmp(temp
, "Darkness"))
2860 // Get the darkness choice...
2861 c
= get_generic(fp
, "Darkness", NULL
, "cupsCompression");
2871 // Add the choice to the cupsDarkness option...
2872 if ((o
= d
->find_option_group("cupsDarkness", &mg
)) == NULL
)
2874 // Create the cupsDarkness option...
2875 o
= new ppdcOption(PPDC_PICKONE
, "cupsDarkness", "Darkness", PPDC_SECTION_ANY
, 10.0f
);
2879 else if (mg
!= general
)
2881 _cupsLangPrintf(stderr
,
2882 _("ppdc: Option %s defined in two different groups on "
2883 "line %d of %s."), "cupsDarkness", fp
->line
,
2892 o
->set_defchoice(c
);
2896 else if (!_cups_strcasecmp(temp
, "DriverType"))
2898 int i
; // Looping var
2901 // DriverType keyword
2902 if (!get_token(fp
, temp
, sizeof(temp
)))
2904 _cupsLangPrintf(stderr
,
2905 _("ppdc: Expected driver type keyword following "
2906 "DriverType on line %d of %s."),
2907 fp
->line
, fp
->filename
);
2914 for (i
= 0; i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])); i
++)
2915 if (!_cups_strcasecmp(temp
, driver_types
[i
]))
2918 if (i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])))
2919 d
->type
= (ppdcDrvType
)i
;
2920 else if (!_cups_strcasecmp(temp
, "dymo"))
2921 d
->type
= PPDC_DRIVER_LABEL
;
2923 _cupsLangPrintf(stderr
,
2924 _("ppdc: Unknown driver type %s on line %d of %s."),
2925 temp
, fp
->line
, fp
->filename
);
2927 else if (!_cups_strcasecmp(temp
, "Duplex"))
2929 else if (!_cups_strcasecmp(temp
, "Filter"))
2931 ppdcFilter
*f
; // Filter
2934 // Get the filter value...
2944 else if (!_cups_strcasecmp(temp
, "Finishing"))
2946 // Get the finishing choice...
2947 c
= get_generic(fp
, "Finishing", "OutputType", NULL
);
2957 // Add the choice to the cupsFinishing option...
2958 if ((o
= d
->find_option_group("cupsFinishing", &mg
)) == NULL
)
2960 // Create the cupsFinishing option...
2961 o
= new ppdcOption(PPDC_PICKONE
, "cupsFinishing", "Finishing", PPDC_SECTION_ANY
, 10.0f
);
2965 else if (mg
!= general
)
2967 _cupsLangPrintf(stderr
,
2968 _("ppdc: Option %s defined in two different groups on "
2969 "line %d of %s."), "cupsFinishing", fp
->line
,
2978 o
->set_defchoice(c
);
2982 else if (!_cups_strcasecmp(temp
, "Font") ||
2983 !_cups_strcasecmp(temp
, "#font"))
2985 ppdcFont
*f
; // Font
2996 if (!_cups_strcasecmp(temp
, "#font"))
3002 d
->set_default_font(f
);
3006 else if (!_cups_strcasecmp(temp
, "Group"))
3009 ppdcGroup
*tempg
= get_group(fp
, d
);
3016 if (!d
->find_group(tempg
->name
->value
))
3021 if (!d
->find_group(tempg
->name
->value
))
3022 d
->add_group(tempg
);
3027 else if (!_cups_strcasecmp(temp
, "HWMargins"))
3029 // HWMargins left bottom right top
3030 d
->left_margin
= get_measurement(fp
);
3031 d
->bottom_margin
= get_measurement(fp
);
3032 d
->right_margin
= get_measurement(fp
);
3033 d
->top_margin
= get_measurement(fp
);
3035 else if (!_cups_strcasecmp(temp
, "InputSlot"))
3037 // Get the input slot choice...
3038 c
= get_generic(fp
, "InputSlot", NULL
, "MediaPosition");
3048 // Add the choice to the InputSlot option...
3050 if ((o
= d
->find_option_group("InputSlot", &mg
)) == NULL
)
3052 // Create the InputSlot option...
3053 o
= new ppdcOption(PPDC_PICKONE
, "InputSlot", "Media Source",
3054 PPDC_SECTION_ANY
, 10.0f
);
3058 else if (mg
!= general
)
3060 _cupsLangPrintf(stderr
,
3061 _("ppdc: Option %s defined in two different groups on "
3062 "line %d of %s."), "InputSlot", fp
->line
,
3071 o
->set_defchoice(c
);
3075 else if (!_cups_strcasecmp(temp
, "Installable"))
3077 // Get the installable option...
3078 o
= get_installable(fp
);
3080 // Add it as needed...
3086 install
->add_option(o
);
3091 else if (!_cups_strcasecmp(temp
, "ManualCopies"))
3093 // ManualCopies boolean
3097 d
->manual_copies
= get_boolean(fp
);
3099 else if (!_cups_strcasecmp(temp
, "Manufacturer"))
3101 // Manufacturer name
3102 char name
[256]; // Model name string
3105 if (!get_token(fp
, name
, sizeof(name
)))
3107 _cupsLangPrintf(stderr
,
3108 _("ppdc: Expected name after Manufacturer on line %d "
3109 "of %s."), fp
->line
, fp
->filename
);
3114 d
->set_manufacturer(name
);
3116 else if (!_cups_strcasecmp(temp
, "MaxSize"))
3118 // MaxSize width length
3121 get_measurement(fp
);
3122 get_measurement(fp
);
3126 d
->max_width
= get_measurement(fp
);
3127 d
->max_length
= get_measurement(fp
);
3130 else if (!_cups_strcasecmp(temp
, "MediaSize"))
3132 // MediaSize keyword
3133 char name
[41]; // Media size name
3134 ppdcMediaSize
*m
, // Matching media size...
3135 *dm
; // Driver media size...
3138 if (get_token(fp
, name
, sizeof(name
)) == NULL
)
3140 _cupsLangPrintf(stderr
,
3141 _("ppdc: Expected name after MediaSize on line %d of "
3142 "%s."), fp
->line
, fp
->filename
);
3149 m
= find_size(name
);
3153 _cupsLangPrintf(stderr
,
3154 _("ppdc: Unknown media size \"%s\" on line %d of "
3155 "%s."), name
, fp
->line
, fp
->filename
);
3159 // Add this size to the driver...
3160 dm
= new ppdcMediaSize(m
->name
->value
, m
->text
->value
,
3161 m
->width
, m
->length
, d
->left_margin
,
3162 d
->bottom_margin
, d
->right_margin
,
3167 d
->set_default_size(dm
);
3169 else if (!_cups_strcasecmp(temp
, "MediaType"))
3171 // Get the media type choice...
3172 c
= get_generic(fp
, "MediaType", "MediaType", "cupsMediaType");
3182 // Add the choice to the MediaType option...
3183 if ((o
= d
->find_option_group("MediaType", &mg
)) == NULL
)
3185 // Create the MediaType option...
3186 o
= new ppdcOption(PPDC_PICKONE
, "MediaType", "Media Type",
3187 PPDC_SECTION_ANY
, 10.0f
);
3191 else if (mg
!= general
)
3193 _cupsLangPrintf(stderr
,
3194 _("ppdc: Option %s defined in two different groups on "
3195 "line %d of %s."), "MediaType", fp
->line
,
3204 o
->set_defchoice(c
);
3208 else if (!_cups_strcasecmp(temp
, "MinSize"))
3210 // MinSize width length
3213 get_measurement(fp
);
3214 get_measurement(fp
);
3218 d
->min_width
= get_measurement(fp
);
3219 d
->min_length
= get_measurement(fp
);
3222 else if (!_cups_strcasecmp(temp
, "ModelName"))
3225 char name
[256]; // Model name string
3228 if (!get_token(fp
, name
, sizeof(name
)))
3230 _cupsLangPrintf(stderr
,
3231 _("ppdc: Expected name after ModelName on line %d of "
3232 "%s."), fp
->line
, fp
->filename
);
3237 d
->set_model_name(name
);
3239 else if (!_cups_strcasecmp(temp
, "ModelNumber"))
3241 // ModelNumber number
3245 d
->model_number
= get_integer(fp
);
3247 else if (!_cups_strcasecmp(temp
, "Option"))
3250 ppdcOption
*tempo
= get_option(fp
, d
, g
);
3257 if (!g
->find_option(tempo
->name
->value
))
3262 if (!g
->find_option(tempo
->name
->value
))
3263 g
->add_option(tempo
);
3268 else if (!_cups_strcasecmp(temp
, "FileName"))
3271 char name
[256]; // Filename string
3274 if (!get_token(fp
, name
, sizeof(name
)))
3276 _cupsLangPrintf(stderr
,
3277 _("ppdc: Expected name after FileName on line %d of "
3278 "%s."), fp
->line
, fp
->filename
);
3283 d
->set_file_name(name
);
3285 else if (!_cups_strcasecmp(temp
, "PCFileName"))
3288 char name
[256]; // PC filename string
3291 if (!get_token(fp
, name
, sizeof(name
)))
3293 _cupsLangPrintf(stderr
,
3294 _("ppdc: Expected name after PCFileName on line %d of "
3295 "%s."), fp
->line
, fp
->filename
);
3300 d
->set_pc_file_name(name
);
3302 else if (!_cups_strcasecmp(temp
, "Resolution"))
3304 // Get the resolution choice...
3305 c
= get_resolution(fp
);
3315 // Add the choice to the Resolution option...
3316 if ((o
= d
->find_option_group("Resolution", &mg
)) == NULL
)
3318 // Create the Resolution option...
3319 o
= new ppdcOption(PPDC_PICKONE
, "Resolution", NULL
, PPDC_SECTION_ANY
,
3324 else if (mg
!= general
)
3326 _cupsLangPrintf(stderr
,
3327 _("ppdc: Option %s defined in two different groups on "
3328 "line %d of %s."), "Resolution", fp
->line
,
3337 o
->set_defchoice(c
);
3341 else if (!_cups_strcasecmp(temp
, "SimpleColorProfile"))
3343 ppdcProfile
*p
; // Color profile
3346 // Get the color profile...
3347 p
= get_simple_profile(fp
);
3354 d
->profiles
->add(p
);
3357 else if (!_cups_strcasecmp(temp
, "Throughput"))
3359 // Throughput number
3363 d
->throughput
= get_integer(fp
);
3365 else if (!_cups_strcasecmp(temp
, "UIConstraints"))
3367 ppdcConstraint
*con
; // Constraint
3370 con
= get_constraint(fp
);
3377 d
->constraints
->add(con
);
3380 else if (!_cups_strcasecmp(temp
, "VariablePaperSize"))
3382 // VariablePaperSize boolean
3386 d
->variable_paper_size
= get_boolean(fp
);
3388 else if (!_cups_strcasecmp(temp
, "Version"))
3391 char name
[256]; // Model name string
3394 if (!get_token(fp
, name
, sizeof(name
)))
3396 _cupsLangPrintf(stderr
,
3397 _("ppdc: Expected string after Version on line %d of "
3398 "%s."), fp
->line
, fp
->filename
);
3403 d
->set_version(name
);
3407 _cupsLangPrintf(stderr
,
3408 _("ppdc: Unknown token \"%s\" seen on line %d of %s."),
3409 temp
, fp
->line
, fp
->filename
);
3414 // Done processing this block, is there anything to save?
3417 if (!d
->pc_file_name
|| !d
->model_name
|| !d
->manufacturer
|| !d
->version
||
3420 // Nothing to save...
3425 // Got a driver, save it...
3435 // 'ppdcSource::set_variable()' - Set a variable.
3438 ppdcVariable
* // O - Variable
3439 ppdcSource::set_variable(
3440 const char *name
, // I - Name
3441 const char *value
) // I - Value
3443 ppdcVariable
*v
; // Variable
3446 // See if the variable exists already...
3447 v
= find_variable(name
);
3450 // Change the variable value...
3451 v
->set_value(value
);
3455 // Create a new variable and add it...
3456 v
= new ppdcVariable(name
, value
);
3465 // 'ppdcSource::write_file()' - Write the current source data to a file.
3468 int // O - 0 on success, -1 on error
3469 ppdcSource::write_file(const char *f
) // I - File to write
3471 cups_file_t
*fp
; // Output file
3472 char bckname
[1024]; // Backup file
3473 ppdcDriver
*d
; // Current driver
3474 ppdcString
*st
; // Current string
3475 ppdcAttr
*a
; // Current attribute
3476 ppdcConstraint
*co
; // Current constraint
3477 ppdcFilter
*fi
; // Current filter
3478 ppdcFont
*fo
; // Current font
3479 ppdcGroup
*g
; // Current group
3480 ppdcOption
*o
; // Current option
3481 ppdcChoice
*ch
; // Current choice
3482 ppdcProfile
*p
; // Current color profile
3483 ppdcMediaSize
*si
; // Current media size
3484 float left
, // Current left margin
3485 bottom
, // Current bottom margin
3486 right
, // Current right margin
3487 top
; // Current top margin
3488 int dtused
[PPDC_DRIVER_MAX
];// Driver type usage...
3491 // Rename the current file, if any, to .bck...
3492 snprintf(bckname
, sizeof(bckname
), "%s.bck", f
);
3495 // Open the output file...
3496 fp
= cupsFileOpen(f
, "w");
3500 // Can't create file; restore backup and return...
3505 cupsFilePuts(fp
, "// CUPS PPD Compiler " CUPS_SVERSION
"\n\n");
3507 // Include standard files...
3508 cupsFilePuts(fp
, "// Include necessary files...\n");
3509 cupsFilePuts(fp
, "#include <font.defs>\n");
3510 cupsFilePuts(fp
, "#include <media.defs>\n");
3512 memset(dtused
, 0, sizeof(dtused
));
3514 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3515 if (d
->type
> PPDC_DRIVER_PS
&& !dtused
[d
->type
])
3517 cupsFilePrintf(fp
, "#include <%s.h>\n", driver_types
[d
->type
]);
3518 dtused
[d
->type
] = 1;
3521 // Output each driver...
3522 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3524 // Start the driver...
3525 cupsFilePrintf(fp
, "\n// %s %s\n", d
->manufacturer
->value
,
3526 d
->model_name
->value
);
3527 cupsFilePuts(fp
, "{\n");
3529 // Write the copyright stings...
3530 for (st
= (ppdcString
*)d
->copyright
->first();
3532 st
= (ppdcString
*)d
->copyright
->next())
3533 quotef(fp
, " Copyright \"%s\"\n", st
->value
);
3535 // Write other strings and values...
3536 if (d
->manufacturer
&& d
->manufacturer
->value
)
3537 quotef(fp
, " Manufacturer \"%s\"\n", d
->manufacturer
->value
);
3538 if (d
->model_name
->value
)
3539 quotef(fp
, " ModelName \"%s\"\n", d
->model_name
->value
);
3540 if (d
->file_name
&& d
->file_name
->value
)
3541 quotef(fp
, " FileName \"%s\"\n", d
->file_name
->value
);
3542 if (d
->pc_file_name
&& d
->pc_file_name
->value
)
3543 quotef(fp
, " PCFileName \"%s\"\n", d
->pc_file_name
->value
);
3544 if (d
->version
&& d
->version
->value
)
3545 quotef(fp
, " Version \"%s\"\n", d
->version
->value
);
3547 cupsFilePrintf(fp
, " DriverType %s\n", driver_types
[d
->type
]);
3549 if (d
->model_number
)
3553 case PPDC_DRIVER_LABEL
:
3554 cupsFilePuts(fp
, " ModelNumber ");
3556 switch (d
->model_number
)
3559 cupsFilePuts(fp
, "$DYMO_3x0\n");
3562 case ZEBRA_EPL_LINE
:
3563 cupsFilePuts(fp
, "$ZEBRA_EPL_LINE\n");
3566 case ZEBRA_EPL_PAGE
:
3567 cupsFilePuts(fp
, "$ZEBRA_EPL_PAGE\n");
3571 cupsFilePuts(fp
, "$ZEBRA_ZPL\n");
3575 cupsFilePuts(fp
, "$ZEBRA_CPCL\n");
3578 case INTELLITECH_PCL
:
3579 cupsFilePuts(fp
, "$INTELLITECH_PCL\n");
3583 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3588 case PPDC_DRIVER_EPSON
:
3589 cupsFilePuts(fp
, " ModelNumber ");
3591 switch (d
->model_number
)
3594 cupsFilePuts(fp
, "$EPSON_9PIN\n");
3598 cupsFilePuts(fp
, "$EPSON_24PIN\n");
3602 cupsFilePuts(fp
, "$EPSON_COLOR\n");
3606 cupsFilePuts(fp
, "$EPSON_PHOTO\n");
3610 cupsFilePuts(fp
, "$EPSON_ICOLOR\n");
3614 cupsFilePuts(fp
, "$EPSON_IPHOTO\n");
3618 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3623 case PPDC_DRIVER_HP
:
3624 cupsFilePuts(fp
, " ModelNumber ");
3625 switch (d
->model_number
)
3628 cupsFilePuts(fp
, "$HP_LASERJET\n");
3632 cupsFilePuts(fp
, "$HP_DESKJET\n");
3636 cupsFilePuts(fp
, "$HP_DESKJET2\n");
3640 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3644 cupsFilePuts(fp
, ")\n");
3648 cupsFilePrintf(fp
, " ModelNumber %d\n", d
->model_number
);
3653 if (d
->manual_copies
)
3654 cupsFilePuts(fp
, " ManualCopies Yes\n");
3656 if (d
->color_device
)
3657 cupsFilePuts(fp
, " ColorDevice Yes\n");
3660 cupsFilePrintf(fp
, " Throughput %d\n", d
->throughput
);
3662 // Output all of the attributes...
3663 for (a
= (ppdcAttr
*)d
->attrs
->first();
3665 a
= (ppdcAttr
*)d
->attrs
->next())
3666 if (a
->text
->value
&& a
->text
->value
[0])
3667 quotef(fp
, " Attribute \"%s\" \"%s/%s\" \"%s\"\n",
3668 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3669 a
->text
->value
, a
->value
->value
? a
->value
->value
: "");
3671 quotef(fp
, " Attribute \"%s\" \"%s\" \"%s\"\n",
3672 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3673 a
->value
->value
? a
->value
->value
: "");
3675 // Output all of the constraints...
3676 for (co
= (ppdcConstraint
*)d
->constraints
->first();
3678 co
= (ppdcConstraint
*)d
->constraints
->next())
3680 if (co
->option1
->value
[0] == '*')
3681 cupsFilePrintf(fp
, " UIConstraints \"%s %s", co
->option1
->value
,
3682 co
->choice1
->value
? co
->choice1
->value
: "");
3684 cupsFilePrintf(fp
, " UIConstraints \"*%s %s", co
->option1
->value
,
3685 co
->choice1
->value
? co
->choice1
->value
: "");
3687 if (co
->option2
->value
[0] == '*')
3688 cupsFilePrintf(fp
, " %s %s\"\n", co
->option2
->value
,
3689 co
->choice2
->value
? co
->choice2
->value
: "");
3691 cupsFilePrintf(fp
, " *%s %s\"\n", co
->option2
->value
,
3692 co
->choice2
->value
? co
->choice2
->value
: "");
3695 // Output all of the filters...
3696 for (fi
= (ppdcFilter
*)d
->filters
->first();
3698 fi
= (ppdcFilter
*)d
->filters
->next())
3699 cupsFilePrintf(fp
, " Filter \"%s %d %s\"\n",
3700 fi
->mime_type
->value
, fi
->cost
, fi
->program
->value
);
3702 // Output all of the fonts...
3703 for (fo
= (ppdcFont
*)d
->fonts
->first();
3705 fo
= (ppdcFont
*)d
->fonts
->next())
3706 if (!strcmp(fo
->name
->value
, "*"))
3707 cupsFilePuts(fp
, " Font *\n");
3709 cupsFilePrintf(fp
, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
3710 fo
->name
->value
, fo
->encoding
->value
,
3711 fo
->version
->value
, fo
->charset
->value
,
3712 fo
->status
== PPDC_FONT_ROM
? "ROM" : "Disk");
3714 // Output all options...
3715 for (g
= (ppdcGroup
*)d
->groups
->first();
3717 g
= (ppdcGroup
*)d
->groups
->next())
3719 if (g
->options
->count
== 0)
3722 if (g
->text
->value
&& g
->text
->value
[0])
3723 quotef(fp
, " Group \"%s/%s\"\n", g
->name
->value
, g
->text
->value
);
3725 cupsFilePrintf(fp
, " Group \"%s\"\n", g
->name
->value
);
3727 for (o
= (ppdcOption
*)g
->options
->first();
3729 o
= (ppdcOption
*)g
->options
->next())
3731 if (o
->choices
->count
== 0)
3734 if (o
->text
->value
&& o
->text
->value
[0])
3735 quotef(fp
, " Option \"%s/%s\"", o
->name
->value
, o
->text
->value
);
3737 cupsFilePrintf(fp
, " Option \"%s\"", o
->name
->value
);
3739 cupsFilePrintf(fp
, " %s %s %.1f\n",
3740 o
->type
== PPDC_BOOLEAN
? "Boolean" :
3741 o
->type
== PPDC_PICKONE
? "PickOne" : "PickMany",
3742 o
->section
== PPDC_SECTION_ANY
? "AnySetup" :
3743 o
->section
== PPDC_SECTION_DOCUMENT
? "DocumentSetup" :
3744 o
->section
== PPDC_SECTION_EXIT
? "ExitServer" :
3745 o
->section
== PPDC_SECTION_JCL
? "JCLSetup" :
3746 o
->section
== PPDC_SECTION_PAGE
? "PageSetup" :
3750 for (ch
= (ppdcChoice
*)o
->choices
->first();
3752 ch
= (ppdcChoice
*)o
->choices
->next())
3754 if (ch
->text
->value
&& ch
->text
->value
[0])
3755 quotef(fp
, " %sChoice \"%s/%s\" \"%s\"\n",
3756 o
->defchoice
== ch
->name
? "*" : "",
3757 ch
->name
->value
, ch
->text
->value
,
3758 ch
->code
->value
? ch
->code
->value
: "");
3760 quotef(fp
, " %sChoice \"%s\" \"%s\"\n",
3761 o
->defchoice
== ch
->name
? "*" : "",
3763 ch
->code
->value
? ch
->code
->value
: "");
3768 // Output all of the color profiles...
3769 for (p
= (ppdcProfile
*)d
->profiles
->first();
3771 p
= (ppdcProfile
*)d
->profiles
->next())
3772 cupsFilePrintf(fp
, " ColorProfile \"%s/%s\" %.3f %.3f "
3773 "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
3774 p
->resolution
->value
, p
->media_type
->value
,
3775 p
->density
, p
->gamma
,
3776 p
->profile
[0], p
->profile
[1], p
->profile
[2],
3777 p
->profile
[3], p
->profile
[4], p
->profile
[5],
3778 p
->profile
[6], p
->profile
[7], p
->profile
[8]);
3780 // Output all of the media sizes...
3786 for (si
= (ppdcMediaSize
*)d
->sizes
->first();
3788 si
= (ppdcMediaSize
*)d
->sizes
->next())
3789 if (si
->size_code
->value
&& si
->region_code
->value
)
3791 // Output a custom media size...
3792 quotef(fp
, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
3793 si
->name
== d
->default_size
? "*" : "", si
->name
->value
,
3794 si
->text
->value
, si
->width
, si
->length
, si
->left
, si
->bottom
,
3795 si
->right
, si
->top
, si
->size_code
->value
,
3796 si
->region_code
->value
);
3800 // Output a standard media size...
3801 if (fabs(left
- si
->left
) > 0.1 ||
3802 fabs(bottom
- si
->bottom
) > 0.1 ||
3803 fabs(right
- si
->right
) > 0.1 ||
3804 fabs(top
- si
->top
) > 0.1)
3806 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3807 si
->left
, si
->bottom
, si
->right
, si
->top
);
3810 bottom
= si
->bottom
;
3815 cupsFilePrintf(fp
, " %sMediaSize %s\n",
3816 si
->name
== d
->default_size
? "*" : "",
3820 if (d
->variable_paper_size
)
3822 cupsFilePuts(fp
, " VariablePaperSize Yes\n");
3824 if (fabs(left
- d
->left_margin
) > 0.1 ||
3825 fabs(bottom
- d
->bottom_margin
) > 0.1 ||
3826 fabs(right
- d
->right_margin
) > 0.1 ||
3827 fabs(top
- d
->top_margin
) > 0.1)
3829 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3830 d
->left_margin
, d
->bottom_margin
, d
->right_margin
,
3834 cupsFilePrintf(fp
, " MinSize %.2f %.2f\n", d
->min_width
, d
->min_length
);
3835 cupsFilePrintf(fp
, " MaxSize %.2f %.2f\n", d
->max_width
, d
->max_length
);
3838 // End the driver...
3839 cupsFilePuts(fp
, "}\n");
3842 // Close the file and return...