]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-source.cxx
2 // Source class for the CUPS PPD Compiler.
4 // Copyright 2007-2018 by Apple Inc.
5 // Copyright 2002-2007 by Easy Software Products.
7 // Licensed under Apache License v2.0. See the file "LICENSE" for more
12 // Include necessary headers...
15 #include "ppdc-private.h"
19 #include <cups/raster.h>
20 #include "data/epson.h"
22 #include "data/label.h"
24 # include <sys/utsname.h>
32 ppdcArray
*ppdcSource::includes
= 0;
33 const char *ppdcSource::driver_types
[] =
46 // 'ppdcSource::ppdcSource()' - Load a driver source file.
49 ppdcSource::ppdcSource(const char *f
, // I - File to read
50 cups_file_t
*ffp
)// I - File pointer to use
55 filename
= new ppdcString(f
);
56 base_fonts
= new ppdcArray();
57 drivers
= new ppdcArray();
58 po_files
= new ppdcArray();
59 sizes
= new ppdcArray();
60 vars
= new ppdcArray();
61 cond_state
= PPDC_COND_NORMAL
;
62 cond_current
= cond_stack
;
63 cond_stack
[0] = PPDC_COND_NORMAL
;
65 // Add standard #define variables...
66 #define MAKE_STRING(x) #x
68 vars
->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION
)));
69 vars
->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR
)));
70 vars
->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR
)));
71 vars
->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH
)));
74 vars
->add(new ppdcVariable("PLATFORM_NAME", "Windows"));
75 vars
->add(new ppdcVariable("PLATFORM_ARCH", "X86"));
78 struct utsname name
; // uname information
82 vars
->add(new ppdcVariable("PLATFORM_NAME", name
.sysname
));
83 vars
->add(new ppdcVariable("PLATFORM_ARCH", name
.machine
));
87 vars
->add(new ppdcVariable("PLATFORM_NAME", "unknown"));
88 vars
->add(new ppdcVariable("PLATFORM_ARCH", "unknown"));
98 // 'ppdcSource::~ppdcSource()' - Free a driver source file.
101 ppdcSource::~ppdcSource()
106 base_fonts
->release();
115 // 'ppdcSource::add_include()' - Add an include directory.
119 ppdcSource::add_include(const char *d
) // I - Include directory
125 includes
= new ppdcArray();
127 includes
->add(new ppdcString(d
));
132 // 'ppdcSource::find_driver()' - Find a driver.
135 ppdcDriver
* // O - Driver
136 ppdcSource::find_driver(const char *f
) // I - Driver file name
138 ppdcDriver
*d
; // Current driver
141 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
142 if (!_cups_strcasecmp(f
, d
->pc_file_name
->value
))
150 // 'ppdcSource::find_include()' - Find an include file.
153 char * // O - Found path or NULL
154 ppdcSource::find_include(
155 const char *f
, // I - Include filename
156 const char *base
, // I - Current directory
157 char *n
, // I - Path buffer
158 int nlen
) // I - Path buffer length
160 ppdcString
*dir
; // Include directory
161 char temp
[1024], // Temporary path
162 *ptr
; // Pointer to end of path
165 // Range check input...
166 if (!f
|| !*f
|| !n
|| nlen
< 2)
169 // Check the first character to see if we have <name> or "name"...
172 // Remove the surrounding <> from the name...
173 strlcpy(temp
, f
+ 1, sizeof(temp
));
174 ptr
= temp
+ strlen(temp
) - 1;
178 _cupsLangPrintf(stderr
,
179 _("ppdc: Invalid #include/#po filename \"%s\"."), n
);
188 // Check for the local file relative to the current directory...
189 if (base
&& *base
&& f
[0] != '/')
190 snprintf(n
, (size_t)nlen
, "%s/%s", base
, f
);
192 strlcpy(n
, f
, (size_t)nlen
);
198 // Absolute path that doesn't exist...
203 // Search the include directories, if any...
206 for (dir
= (ppdcString
*)includes
->first(); dir
; dir
= (ppdcString
*)includes
->next())
208 snprintf(n
, (size_t)nlen
, "%s/%s", dir
->value
, f
);
214 // Search the standard include directories...
215 _cups_globals_t
*cg
= _cupsGlobals(); // Global data
217 snprintf(n
, (size_t)nlen
, "%s/ppdc/%s", cg
->cups_datadir
, f
);
221 snprintf(n
, (size_t)nlen
, "%s/po/%s", cg
->cups_datadir
, f
);
230 // 'ppdcSource::find_po()' - Find a message catalog for the given locale.
233 ppdcCatalog
* // O - Message catalog or NULL
234 ppdcSource::find_po(const char *l
) // I - Locale name
236 ppdcCatalog
*cat
; // Current message catalog
239 for (cat
= (ppdcCatalog
*)po_files
->first();
241 cat
= (ppdcCatalog
*)po_files
->next())
242 if (!_cups_strcasecmp(l
, cat
->locale
->value
))
250 // 'ppdcSource::find_size()' - Find a media size.
253 ppdcMediaSize
* // O - Size
254 ppdcSource::find_size(const char *s
) // I - Size name
256 ppdcMediaSize
*m
; // Current media size
259 for (m
= (ppdcMediaSize
*)sizes
->first(); m
; m
= (ppdcMediaSize
*)sizes
->next())
260 if (!_cups_strcasecmp(s
, m
->name
->value
))
268 // 'ppdcSource::find_variable()' - Find a variable.
271 ppdcVariable
* // O - Variable
272 ppdcSource::find_variable(const char *n
)// I - Variable name
274 ppdcVariable
*v
; // Current variable
277 for (v
= (ppdcVariable
*)vars
->first(); v
; v
= (ppdcVariable
*)vars
->next())
278 if (!_cups_strcasecmp(n
, v
->name
->value
))
286 // 'ppdcSource::get_attr()' - Get an attribute.
289 ppdcAttr
* // O - Attribute
290 ppdcSource::get_attr(ppdcFile
*fp
, // I - File to read
291 bool loc
) // I - Localize this attribute?
293 char name
[1024], // Name string
294 selector
[1024], // Selector string
295 *text
, // Text string
296 value
[1024]; // Value string
299 // Get the attribute parameters:
301 // Attribute name selector value
302 if (!get_token(fp
, name
, sizeof(name
)))
304 _cupsLangPrintf(stderr
,
305 _("ppdc: Expected name after %s on line %d of %s."),
306 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
310 if (!get_token(fp
, selector
, sizeof(selector
)))
312 _cupsLangPrintf(stderr
,
313 _("ppdc: Expected selector after %s on line %d of %s."),
314 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
318 if ((text
= strchr(selector
, '/')) != NULL
)
321 if (!get_token(fp
, value
, sizeof(value
)))
323 _cupsLangPrintf(stderr
,
324 _("ppdc: Expected value after %s on line %d of %s."),
325 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
329 return (new ppdcAttr(name
, selector
, text
, value
, loc
));
334 // 'ppdcSource::get_boolean()' - Get a boolean value.
337 int // O - Boolean value
338 ppdcSource::get_boolean(ppdcFile
*fp
) // I - File to read
340 char buffer
[256]; // String buffer
343 if (!get_token(fp
, buffer
, sizeof(buffer
)))
345 _cupsLangPrintf(stderr
,
346 _("ppdc: Expected boolean value on line %d of %s."),
347 fp
->line
, fp
->filename
);
351 if (!_cups_strcasecmp(buffer
, "on") ||
352 !_cups_strcasecmp(buffer
, "yes") ||
353 !_cups_strcasecmp(buffer
, "true"))
355 else if (!_cups_strcasecmp(buffer
, "off") ||
356 !_cups_strcasecmp(buffer
, "no") ||
357 !_cups_strcasecmp(buffer
, "false"))
361 _cupsLangPrintf(stderr
,
362 _("ppdc: Bad boolean value (%s) on line %d of %s."),
363 buffer
, fp
->line
, fp
->filename
);
370 // 'ppdcSource::get_choice()' - Get a choice.
373 ppdcChoice
* // O - Choice data
374 ppdcSource::get_choice(ppdcFile
*fp
) // I - File to read
376 char name
[1024], // Name
381 // Read a choice from the file:
383 // Choice name/text code
384 if (!get_token(fp
, name
, sizeof(name
)))
386 _cupsLangPrintf(stderr
,
387 _("ppdc: Expected choice name/text on line %d of %s."),
388 fp
->line
, fp
->filename
);
392 if ((text
= strchr(name
, '/')) != NULL
)
397 if (!get_token(fp
, code
, sizeof(code
)))
399 _cupsLangPrintf(stderr
, _("ppdc: Expected choice code on line %d of %s."),
400 fp
->line
, fp
->filename
);
404 // Return the new choice
405 return (new ppdcChoice(name
, text
, code
));
410 // 'ppdcSource::get_color_model()' - Get an old-style color model option.
413 ppdcChoice
* // O - Choice data
414 ppdcSource::get_color_model(ppdcFile
*fp
)
417 char name
[1024], // Option name
418 *text
, // Text option
419 temp
[256]; // Temporary string
420 int color_space
, // Colorspace
421 color_order
, // Color order
422 compression
; // Compression mode
425 // Get the ColorModel parameters:
427 // ColorModel name/text colorspace colororder compression
428 if (!get_token(fp
, name
, sizeof(name
)))
430 _cupsLangPrintf(stderr
,
431 _("ppdc: Expected name/text combination for ColorModel on "
432 "line %d of %s."), fp
->line
, fp
->filename
);
436 if ((text
= strchr(name
, '/')) != NULL
)
441 if (!get_token(fp
, temp
, sizeof(temp
)))
443 _cupsLangPrintf(stderr
,
444 _("ppdc: Expected colorspace for ColorModel on line %d of "
445 "%s."), fp
->line
, fp
->filename
);
449 if ((color_space
= get_color_space(temp
)) < 0)
450 color_space
= get_integer(temp
);
452 if (!get_token(fp
, temp
, sizeof(temp
)))
454 _cupsLangPrintf(stderr
,
455 _("ppdc: Expected color order for ColorModel on line %d of "
456 "%s."), fp
->line
, fp
->filename
);
460 if ((color_order
= get_color_order(temp
)) < 0)
461 color_order
= get_integer(temp
);
463 if (!get_token(fp
, temp
, sizeof(temp
)))
465 _cupsLangPrintf(stderr
,
466 _("ppdc: Expected compression for ColorModel on line %d of "
467 "%s."), fp
->line
, fp
->filename
);
471 compression
= get_integer(temp
);
473 snprintf(temp
, sizeof(temp
),
474 "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
476 color_space
, color_order
, compression
);
478 return (new ppdcChoice(name
, text
, temp
));
483 // 'ppdcSource::get_color_order()' - Get an old-style color order value.
486 int // O - Color order value
487 ppdcSource::get_color_order(
488 const char *co
) // I - Color order string
490 if (!_cups_strcasecmp(co
, "chunked") ||
491 !_cups_strcasecmp(co
, "chunky"))
492 return (CUPS_ORDER_CHUNKED
);
493 else if (!_cups_strcasecmp(co
, "banded"))
494 return (CUPS_ORDER_BANDED
);
495 else if (!_cups_strcasecmp(co
, "planar"))
496 return (CUPS_ORDER_PLANAR
);
503 // 'ppdcSource::get_color_profile()' - Get a color profile definition.
506 ppdcProfile
* // O - Color profile
507 ppdcSource::get_color_profile(
508 ppdcFile
*fp
) // I - File to read
510 char resolution
[1024], // Resolution/media type
511 *media_type
; // Media type
512 int i
; // Looping var
513 float g
, // Gamma value
515 m
[9]; // Transform matrix
518 // Get the ColorProfile parameters:
520 // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
521 if (!get_token(fp
, resolution
, sizeof(resolution
)))
523 _cupsLangPrintf(stderr
,
524 _("ppdc: Expected resolution/mediatype following "
525 "ColorProfile on line %d of %s."),
526 fp
->line
, fp
->filename
);
530 if ((media_type
= strchr(resolution
, '/')) != NULL
)
531 *media_type
++ = '\0';
533 media_type
= resolution
;
537 for (i
= 0; i
< 9; i
++)
538 m
[i
] = get_float(fp
);
540 return (new ppdcProfile(resolution
, media_type
, g
, d
, m
));
545 // 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
548 int // O - Colorspace value
549 ppdcSource::get_color_space(
550 const char *cs
) // I - Colorspace string
552 if (!_cups_strcasecmp(cs
, "w"))
553 return (CUPS_CSPACE_W
);
554 else if (!_cups_strcasecmp(cs
, "rgb"))
555 return (CUPS_CSPACE_RGB
);
556 else if (!_cups_strcasecmp(cs
, "rgba"))
557 return (CUPS_CSPACE_RGBA
);
558 else if (!_cups_strcasecmp(cs
, "k"))
559 return (CUPS_CSPACE_K
);
560 else if (!_cups_strcasecmp(cs
, "cmy"))
561 return (CUPS_CSPACE_CMY
);
562 else if (!_cups_strcasecmp(cs
, "ymc"))
563 return (CUPS_CSPACE_YMC
);
564 else if (!_cups_strcasecmp(cs
, "cmyk"))
565 return (CUPS_CSPACE_CMYK
);
566 else if (!_cups_strcasecmp(cs
, "ymck"))
567 return (CUPS_CSPACE_YMCK
);
568 else if (!_cups_strcasecmp(cs
, "kcmy"))
569 return (CUPS_CSPACE_KCMY
);
570 else if (!_cups_strcasecmp(cs
, "kcmycm"))
571 return (CUPS_CSPACE_KCMYcm
);
572 else if (!_cups_strcasecmp(cs
, "gmck"))
573 return (CUPS_CSPACE_GMCK
);
574 else if (!_cups_strcasecmp(cs
, "gmcs"))
575 return (CUPS_CSPACE_GMCS
);
576 else if (!_cups_strcasecmp(cs
, "white"))
577 return (CUPS_CSPACE_WHITE
);
578 else if (!_cups_strcasecmp(cs
, "gold"))
579 return (CUPS_CSPACE_GOLD
);
580 else if (!_cups_strcasecmp(cs
, "silver"))
581 return (CUPS_CSPACE_SILVER
);
582 else if (!_cups_strcasecmp(cs
, "CIEXYZ"))
583 return (CUPS_CSPACE_CIEXYZ
);
584 else if (!_cups_strcasecmp(cs
, "CIELab"))
585 return (CUPS_CSPACE_CIELab
);
586 else if (!_cups_strcasecmp(cs
, "RGBW"))
587 return (CUPS_CSPACE_RGBW
);
588 else if (!_cups_strcasecmp(cs
, "ICC1"))
589 return (CUPS_CSPACE_ICC1
);
590 else if (!_cups_strcasecmp(cs
, "ICC2"))
591 return (CUPS_CSPACE_ICC2
);
592 else if (!_cups_strcasecmp(cs
, "ICC3"))
593 return (CUPS_CSPACE_ICC3
);
594 else if (!_cups_strcasecmp(cs
, "ICC4"))
595 return (CUPS_CSPACE_ICC4
);
596 else if (!_cups_strcasecmp(cs
, "ICC5"))
597 return (CUPS_CSPACE_ICC5
);
598 else if (!_cups_strcasecmp(cs
, "ICC6"))
599 return (CUPS_CSPACE_ICC6
);
600 else if (!_cups_strcasecmp(cs
, "ICC7"))
601 return (CUPS_CSPACE_ICC7
);
602 else if (!_cups_strcasecmp(cs
, "ICC8"))
603 return (CUPS_CSPACE_ICC8
);
604 else if (!_cups_strcasecmp(cs
, "ICC9"))
605 return (CUPS_CSPACE_ICC9
);
606 else if (!_cups_strcasecmp(cs
, "ICCA"))
607 return (CUPS_CSPACE_ICCA
);
608 else if (!_cups_strcasecmp(cs
, "ICCB"))
609 return (CUPS_CSPACE_ICCB
);
610 else if (!_cups_strcasecmp(cs
, "ICCC"))
611 return (CUPS_CSPACE_ICCC
);
612 else if (!_cups_strcasecmp(cs
, "ICCD"))
613 return (CUPS_CSPACE_ICCD
);
614 else if (!_cups_strcasecmp(cs
, "ICCE"))
615 return (CUPS_CSPACE_ICCE
);
616 else if (!_cups_strcasecmp(cs
, "ICCF"))
617 return (CUPS_CSPACE_ICCF
);
624 // 'ppdcSource::get_constraint()' - Get a constraint.
627 ppdcConstraint
* // O - Constraint
628 ppdcSource::get_constraint(ppdcFile
*fp
)// I - File to read
630 char temp
[1024], // One string to rule them all
631 *ptr
, // Pointer into string
632 *option1
, // Constraint option 1
633 *choice1
, // Constraint choice 1
634 *option2
, // Constraint option 2
635 *choice2
; // Constraint choice 2
638 // Read the UIConstaints parameter in one of the following forms:
640 // UIConstraints "*Option1 *Option2"
641 // UIConstraints "*Option1 Choice1 *Option2"
642 // UIConstraints "*Option1 *Option2 Choice2"
643 // UIConstraints "*Option1 Choice1 *Option2 Choice2"
644 if (!get_token(fp
, temp
, sizeof(temp
)))
646 _cupsLangPrintf(stderr
,
647 _("ppdc: Expected constraints string for UIConstraints on "
648 "line %d of %s."), fp
->line
, fp
->filename
);
652 for (ptr
= temp
; isspace(*ptr
); ptr
++);
656 _cupsLangPrintf(stderr
,
657 _("ppdc: Option constraint must *name on line %d of %s."),
658 fp
->line
, fp
->filename
);
664 for (; *ptr
&& !isspace(*ptr
); ptr
++);
665 for (; isspace(*ptr
); *ptr
++ = '\0');
671 for (; *ptr
&& !isspace(*ptr
); ptr
++);
672 for (; isspace(*ptr
); *ptr
++ = '\0');
679 _cupsLangPrintf(stderr
,
680 _("ppdc: Expected two option names on line %d of %s."),
681 fp
->line
, fp
->filename
);
687 for (; *ptr
&& !isspace(*ptr
); ptr
++);
688 for (; isspace(*ptr
); *ptr
++ = '\0');
695 return (new ppdcConstraint(option1
, choice1
, option2
, choice2
));
700 // 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
703 ppdcMediaSize
* // O - Media size
704 ppdcSource::get_custom_size(ppdcFile
*fp
)
707 char name
[1024], // Name
709 size_code
[10240], // PageSize code
710 region_code
[10240]; // PageRegion
711 float width
, // Width
714 bottom
, // Bottom margin
715 right
, // Right margin
719 // Get the name, text, width, length, margins, and code:
721 // CustomMedia name/text width length left bottom right top size-code region-code
722 if (!get_token(fp
, name
, sizeof(name
)))
725 if ((text
= strchr(name
, '/')) != NULL
)
730 if ((width
= get_measurement(fp
)) < 0.0f
)
733 if ((length
= get_measurement(fp
)) < 0.0f
)
736 if ((left
= get_measurement(fp
)) < 0.0f
)
739 if ((bottom
= get_measurement(fp
)) < 0.0f
)
742 if ((right
= get_measurement(fp
)) < 0.0f
)
745 if ((top
= get_measurement(fp
)) < 0.0f
)
748 if (!get_token(fp
, size_code
, sizeof(size_code
)))
751 if (!get_token(fp
, region_code
, sizeof(region_code
)))
754 // Return the new media size...
755 return (new ppdcMediaSize(name
, text
, width
, length
, left
, bottom
,
756 right
, top
, size_code
, region_code
));
761 // 'ppdcSource::get_duplex()' - Get a duplex option.
765 ppdcSource::get_duplex(ppdcFile
*fp
, // I - File to read from
766 ppdcDriver
*d
) // I - Current driver
768 char temp
[256]; // Duplex keyword
769 ppdcAttr
*attr
; // cupsFlipDuplex attribute
770 ppdcGroup
*g
; // Current group
771 ppdcOption
*o
; // Duplex option
774 // Duplex {boolean|none|normal|flip}
775 if (!get_token(fp
, temp
, sizeof(temp
)))
777 _cupsLangPrintf(stderr
,
778 _("ppdc: Expected duplex type after Duplex on line %d of "
779 "%s."), fp
->line
, fp
->filename
);
786 if (!_cups_strcasecmp(temp
, "none") || !_cups_strcasecmp(temp
, "false") ||
787 !_cups_strcasecmp(temp
, "no") || !_cups_strcasecmp(temp
, "off"))
789 g
= d
->find_group("General");
790 if ((o
= g
->find_option("Duplex")) != NULL
)
791 g
->options
->remove(o
);
793 for (attr
= (ppdcAttr
*)d
->attrs
->first();
795 attr
= (ppdcAttr
*)d
->attrs
->next())
796 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
798 d
->attrs
->remove(attr
);
802 else if (!_cups_strcasecmp(temp
, "normal") || !_cups_strcasecmp(temp
, "true") ||
803 !_cups_strcasecmp(temp
, "yes") || !_cups_strcasecmp(temp
, "on") ||
804 !_cups_strcasecmp(temp
, "flip") || !_cups_strcasecmp(temp
, "rotated") ||
805 !_cups_strcasecmp(temp
, "manualtumble"))
807 g
= d
->find_group("General");
808 o
= g
->find_option("Duplex");
812 o
= new ppdcOption(PPDC_PICKONE
, "Duplex", "2-Sided Printing",
813 !_cups_strcasecmp(temp
, "flip") ? PPDC_SECTION_PAGE
:
814 PPDC_SECTION_ANY
, 10.0f
);
815 o
->add_choice(new ppdcChoice("None", "Off (1-Sided)",
816 "<</Duplex false>>setpagedevice"));
817 o
->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
818 "<</Duplex true/Tumble false>>setpagedevice"));
819 o
->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
820 "<</Duplex true/Tumble true>>setpagedevice"));
825 for (attr
= (ppdcAttr
*)d
->attrs
->first();
827 attr
= (ppdcAttr
*)d
->attrs
->next())
828 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
830 if (_cups_strcasecmp(temp
, "flip"))
831 d
->attrs
->remove(attr
);
835 if (!_cups_strcasecmp(temp
, "flip") && !attr
)
836 d
->add_attr(new ppdcAttr("cupsFlipDuplex", NULL
, NULL
, "true"));
838 for (attr
= (ppdcAttr
*)d
->attrs
->first();
840 attr
= (ppdcAttr
*)d
->attrs
->next())
841 if (!strcmp(attr
->name
->value
, "cupsBackSide"))
843 d
->attrs
->remove(attr
);
847 if (!_cups_strcasecmp(temp
, "flip"))
848 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Flipped"));
849 else if (!_cups_strcasecmp(temp
, "rotated"))
850 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Rotated"));
851 else if (!_cups_strcasecmp(temp
, "manualtumble"))
852 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "ManualTumble"));
854 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Normal"));
857 _cupsLangPrintf(stderr
,
858 _("ppdc: Unknown duplex type \"%s\" on line %d of %s."),
859 temp
, fp
->line
, fp
->filename
);
864 // 'ppdcSource::get_filter()' - Get a filter.
867 ppdcFilter
* // O - Filter
868 ppdcSource::get_filter(ppdcFile
*fp
) // I - File to read
870 char type
[1024], // MIME type
871 program
[1024], // Filter program
872 *ptr
; // Pointer into MIME type
873 int cost
; // Relative cost
876 // Read filter parameters in one of the following formats:
878 // Filter "type cost program"
879 // Filter type cost program
881 if (!get_token(fp
, type
, sizeof(type
)))
883 _cupsLangPrintf(stderr
,
884 _("ppdc: Expected a filter definition on line %d of %s."),
885 fp
->line
, fp
->filename
);
889 if ((ptr
= strchr(type
, ' ')) != NULL
)
891 // Old-style filter definition in one string...
893 cost
= strtol(ptr
, &ptr
, 10);
895 while (isspace(*ptr
))
898 strlcpy(program
, ptr
, sizeof(program
));
902 cost
= get_integer(fp
);
904 if (!get_token(fp
, program
, sizeof(program
)))
906 _cupsLangPrintf(stderr
,
907 _("ppdc: Expected a program name on line %d of %s."),
908 fp
->line
, fp
->filename
);
915 _cupsLangPrintf(stderr
,
916 _("ppdc: Invalid empty MIME type for filter on line %d of "
917 "%s."), fp
->line
, fp
->filename
);
921 if (cost
< 0 || cost
> 200)
923 _cupsLangPrintf(stderr
,
924 _("ppdc: Invalid cost for filter on line %d of %s."),
925 fp
->line
, fp
->filename
);
931 _cupsLangPrintf(stderr
,
932 _("ppdc: Invalid empty program name for filter on line %d "
933 "of %s."), fp
->line
, fp
->filename
);
937 return (new ppdcFilter(type
, program
, cost
));
942 // 'ppdcSource::get_float()' - Get a single floating-point number.
946 ppdcSource::get_float(ppdcFile
*fp
) // I - File to read
948 char temp
[256], // String buffer
949 *ptr
; // Pointer into buffer
950 float val
; // Floating point value
953 // Get the number from the file and range-check...
954 if (!get_token(fp
, temp
, sizeof(temp
)))
956 _cupsLangPrintf(stderr
, _("ppdc: Expected real number on line %d of %s."),
957 fp
->line
, fp
->filename
);
961 val
= (float)strtod(temp
, &ptr
);
965 _cupsLangPrintf(stderr
,
966 _("ppdc: Unknown trailing characters in real number \"%s\" "
967 "on line %d of %s."), temp
, fp
->line
, fp
->filename
);
976 // 'ppdcSource::get_font()' - Get a font definition.
979 ppdcFont
* // O - Font data
980 ppdcSource::get_font(ppdcFile
*fp
) // I - File to read
982 char name
[256], // Font name
983 encoding
[256], // Font encoding
984 version
[256], // Font version
985 charset
[256], // Font charset
986 temp
[256]; // Font status string
987 ppdcFontStatus status
; // Font status enumeration
990 // Read font parameters as follows:
993 // Font name encoding version charset status
994 // %font name encoding version charset status
996 // "Name" is the PostScript font name.
998 // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
999 // Special, Expert, ExpertSubset, etc.
1001 // "Version" is the version number string.
1003 // "Charset" specifies the characters that are included in the font:
1004 // Standard, Special, Expert, Adobe-Identity, etc.
1006 // "Status" is the keyword ROM or Disk.
1007 if (!get_token(fp
, name
, sizeof(name
)))
1009 _cupsLangPrintf(stderr
,
1010 _("ppdc: Expected name after Font on line %d of %s."),
1011 fp
->line
, fp
->filename
);
1015 if (!strcmp(name
, "*"))
1017 // Include all base fonts...
1021 status
= PPDC_FONT_ROM
;
1025 // Load a full font definition...
1026 if (!get_token(fp
, encoding
, sizeof(encoding
)))
1028 _cupsLangPrintf(stderr
,
1029 _("ppdc: Expected encoding after Font on line %d of "
1030 "%s."), fp
->line
, fp
->filename
);
1034 if (!get_token(fp
, version
, sizeof(version
)))
1036 _cupsLangPrintf(stderr
,
1037 _("ppdc: Expected version after Font on line %d of "
1038 "%s."), fp
->line
, fp
->filename
);
1042 if (!get_token(fp
, charset
, sizeof(charset
)))
1044 _cupsLangPrintf(stderr
,
1045 _("ppdc: Expected charset after Font on line %d of "
1046 "%s."), fp
->line
, fp
->filename
);
1050 if (!get_token(fp
, temp
, sizeof(temp
)))
1052 _cupsLangPrintf(stderr
,
1053 _("ppdc: Expected status after Font on line %d of %s."),
1054 fp
->line
, fp
->filename
);
1058 if (!_cups_strcasecmp(temp
, "ROM"))
1059 status
= PPDC_FONT_ROM
;
1060 else if (!_cups_strcasecmp(temp
, "Disk"))
1061 status
= PPDC_FONT_DISK
;
1064 _cupsLangPrintf(stderr
,
1065 _("ppdc: Bad status keyword %s on line %d of %s."),
1066 temp
, fp
->line
, fp
->filename
);
1071 // printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
1073 return (new ppdcFont(name
, encoding
, version
, charset
, status
));
1078 // 'ppdcSource::get_generic()' - Get a generic old-style option.
1081 ppdcChoice
* // O - Choice data
1082 ppdcSource::get_generic(ppdcFile
*fp
, // I - File to read
1083 const char *keyword
,
1086 // I - Text attribute
1088 // I - Numeric attribute
1090 char name
[1024], // Name
1092 command
[256]; // Command string
1093 int val
; // Numeric value
1096 // Read one of the following parameters:
1099 // Foo integer name/text
1101 val
= get_integer(fp
);
1105 if (!get_token(fp
, name
, sizeof(name
)))
1107 _cupsLangPrintf(stderr
,
1108 _("ppdc: Expected name/text after %s on line %d of %s."),
1109 keyword
, fp
->line
, fp
->filename
);
1113 if ((text
= strchr(name
, '/')) != NULL
)
1121 snprintf(command
, sizeof(command
),
1122 "<</%s(%s)/%s %d>>setpagedevice",
1123 tattr
, name
, nattr
, val
);
1125 snprintf(command
, sizeof(command
),
1126 "<</%s %d>>setpagedevice",
1130 snprintf(command
, sizeof(command
),
1131 "<</%s(%s)>>setpagedevice",
1134 return (new ppdcChoice(name
, text
, command
));
1139 // 'ppdcSource::get_group()' - Get an option group.
1142 ppdcGroup
* // O - Group
1143 ppdcSource::get_group(ppdcFile
*fp
, // I - File to read
1144 ppdcDriver
*d
) // I - Printer driver
1146 char name
[1024], // UI name
1148 ppdcGroup
*g
; // Group
1151 // Read the Group parameters:
1154 if (!get_token(fp
, name
, sizeof(name
)))
1156 _cupsLangPrintf(stderr
,
1157 _("ppdc: Expected group name/text on line %d of %s."),
1158 fp
->line
, fp
->filename
);
1162 if ((text
= strchr(name
, '/')) != NULL
)
1167 // See if the group already exists...
1168 if ((g
= d
->find_group(name
)) == NULL
)
1170 // Nope, add a new one...
1171 g
= new ppdcGroup(name
, text
);
1179 // 'ppdcSource::get_installable()' - Get an installable option.
1182 ppdcOption
* // O - Option
1183 ppdcSource::get_installable(ppdcFile
*fp
)
1186 char name
[1024], // Name for installable option
1187 *text
; // Text for installable option
1188 ppdcOption
*o
; // Option
1191 // Read the parameter for an installable option:
1193 // Installable name/text
1194 if (!get_token(fp
, name
, sizeof(name
)))
1196 _cupsLangPrintf(stderr
,
1197 _("ppdc: Expected name/text after Installable on line %d "
1198 "of %s."), fp
->line
, fp
->filename
);
1202 if ((text
= strchr(name
, '/')) != NULL
)
1207 // Create the option...
1208 o
= new ppdcOption(PPDC_BOOLEAN
, name
, text
, PPDC_SECTION_ANY
, 10.0f
);
1210 // Add the false and true choices...
1211 o
->add_choice(new ppdcChoice("False", "Not Installed", ""));
1212 o
->add_choice(new ppdcChoice("True", "Installed", ""));
1219 // 'ppdcSource::get_integer()' - Get an integer value from a string.
1222 #define PPDC_XX -1 // Bad
1223 #define PPDC_EQ 0 // ==
1224 #define PPDC_NE 1 // !=
1225 #define PPDC_LT 2 // <
1226 #define PPDC_LE 3 // <=
1227 #define PPDC_GT 4 // >
1228 #define PPDC_GE 5 // >=
1230 int // O - Integer value
1231 ppdcSource::get_integer(const char *v
) // I - Value string
1234 long temp
, // Temporary value
1235 temp2
; // Second temporary value
1236 char *newv
, // New value string pointer
1237 ch
; // Temporary character
1238 ppdcVariable
*var
; // #define variable
1239 int compop
; // Comparison operator
1242 // Parse the value string...
1246 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1248 // Return a simple integer value
1249 val
= strtol(v
, (char **)&v
, 0);
1250 if (*v
|| val
== LONG_MIN
)
1257 // Evaluate and expression in any of the following formats:
1259 // (number number ... number) Bitwise OR of all numbers
1260 // (NAME == value) 1 if equal, 0 otherwise
1261 // (NAME != value) 1 if not equal, 0 otherwise
1262 // (NAME < value) 1 if less than, 0 otherwise
1263 // (NAME <= value) 1 if less than or equal, 0 otherwise
1264 // (NAME > value) 1 if greater than, 0 otherwise
1265 // (NAME >= value) 1 if greater than or equal, 0 otherwise
1270 while (*v
&& *v
!= ')')
1272 // Skip leading whitespace...
1273 while (*v
&& isspace(*v
& 255))
1276 if (!*v
|| *v
== ')')
1279 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1281 // Bitwise OR a number...
1282 temp
= strtol(v
, &newv
, 0);
1284 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1290 // NAME logicop value
1291 for (newv
= (char *)v
+ 1;
1292 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1299 if ((var
= find_variable(v
)) != NULL
)
1301 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1303 else if (isdigit(var
->value
->value
[0] & 255) ||
1304 var
->value
->value
[0] == '-' ||
1305 var
->value
->value
[0] == '+')
1306 temp
= strtol(var
->value
->value
, NULL
, 0);
1314 while (isspace(*newv
& 255))
1317 if (!strncmp(newv
, "==", 2))
1322 else if (!strncmp(newv
, "!=", 2))
1327 else if (!strncmp(newv
, "<=", 2))
1332 else if (*newv
== '<')
1337 else if (!strncmp(newv
, ">=", 2))
1342 else if (*newv
== '>')
1350 if (compop
!= PPDC_XX
)
1352 while (isspace(*newv
& 255))
1355 if (*newv
== ')' || !*newv
)
1358 if (isdigit(*newv
& 255) || *newv
== '-' || *newv
== '+')
1360 // Get the second number...
1361 temp2
= strtol(newv
, &newv
, 0);
1362 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1368 // Lookup the second name...
1369 for (v
= newv
, newv
++;
1370 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1376 if ((var
= find_variable(v
)) != NULL
)
1378 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1380 else if (isdigit(var
->value
->value
[0] & 255) ||
1381 var
->value
->value
[0] == '-' ||
1382 var
->value
->value
[0] == '+')
1383 temp2
= strtol(var
->value
->value
, NULL
, 0);
1393 // Do the comparison...
1397 temp
= temp
== temp2
;
1400 temp
= temp
!= temp2
;
1403 temp
= temp
< temp2
;
1406 temp
= temp
<= temp2
;
1409 temp
= temp
> temp2
;
1412 temp
= temp
>= temp2
;
1422 if (*v
== ')' && !v
[1])
1427 else if ((var
= find_variable(v
)) != NULL
)
1429 // NAME by itself returns 1 if the #define variable is not blank and
1431 return (var
->value
->value
&& var
->value
->value
[0] &&
1432 strcmp(var
->value
->value
, "0"));
1436 // Anything else is an error...
1443 // 'ppdcSource::get_integer()' - Get an integer value from a file.
1446 int // O - Integer value
1447 ppdcSource::get_integer(ppdcFile
*fp
) // I - File to read
1449 char temp
[1024]; // String buffer
1452 if (!get_token(fp
, temp
, sizeof(temp
)))
1454 _cupsLangPrintf(stderr
, _("ppdc: Expected integer on line %d of %s."),
1455 fp
->line
, fp
->filename
);
1459 return (get_integer(temp
));
1464 // 'ppdcSource::get_measurement()' - Get a measurement value.
1467 float // O - Measurement value in points
1468 ppdcSource::get_measurement(ppdcFile
*fp
)
1471 char buffer
[256], // Number buffer
1472 *ptr
; // Pointer into buffer
1473 float val
; // Measurement value
1476 // Grab a token from the file...
1477 if (!get_token(fp
, buffer
, sizeof(buffer
)))
1480 // Get the floating point value of "s" and skip all digits and decimal points.
1481 val
= (float)strtod(buffer
, &ptr
);
1483 // Check for a trailing unit specifier...
1484 if (!_cups_strcasecmp(ptr
, "mm"))
1485 val
*= 72.0f
/ 25.4f
;
1486 else if (!_cups_strcasecmp(ptr
, "cm"))
1487 val
*= 72.0f
/ 2.54f
;
1488 else if (!_cups_strcasecmp(ptr
, "m"))
1489 val
*= 72.0f
/ 0.0254f
;
1490 else if (!_cups_strcasecmp(ptr
, "in"))
1492 else if (!_cups_strcasecmp(ptr
, "ft"))
1493 val
*= 72.0f
* 12.0f
;
1494 else if (_cups_strcasecmp(ptr
, "pt") && *ptr
)
1502 // 'ppdcSource::get_option()' - Get an option definition.
1505 ppdcOption
* // O - Option
1506 ppdcSource::get_option(ppdcFile
*fp
, // I - File to read
1507 ppdcDriver
*d
, // I - Printer driver
1508 ppdcGroup
*g
) // I - Current group
1510 char name
[1024], // UI name
1512 type
[256]; // UI type string
1513 ppdcOptType ot
; // Option type value
1514 ppdcOptSection section
; // Option section
1515 float order
; // Option order
1516 ppdcOption
*o
; // Option
1517 ppdcGroup
*mg
; // Matching group, if any
1520 // Read the Option parameters:
1522 // Option name/text type section order
1523 if (!get_token(fp
, name
, sizeof(name
)))
1525 _cupsLangPrintf(stderr
,
1526 _("ppdc: Expected option name/text on line %d of %s."),
1527 fp
->line
, fp
->filename
);
1531 if ((text
= strchr(name
, '/')) != NULL
)
1536 if (!get_token(fp
, type
, sizeof(type
)))
1538 _cupsLangPrintf(stderr
, _("ppdc: Expected option type on line %d of %s."),
1539 fp
->line
, fp
->filename
);
1543 if (!_cups_strcasecmp(type
, "boolean"))
1545 else if (!_cups_strcasecmp(type
, "pickone"))
1547 else if (!_cups_strcasecmp(type
, "pickmany"))
1551 _cupsLangPrintf(stderr
,
1552 _("ppdc: Invalid option type \"%s\" on line %d of %s."),
1553 type
, fp
->line
, fp
->filename
);
1557 if (!get_token(fp
, type
, sizeof(type
)))
1559 _cupsLangPrintf(stderr
,
1560 _("ppdc: Expected option section on line %d of %s."),
1561 fp
->line
, fp
->filename
);
1565 if (!_cups_strcasecmp(type
, "AnySetup"))
1566 section
= PPDC_SECTION_ANY
;
1567 else if (!_cups_strcasecmp(type
, "DocumentSetup"))
1568 section
= PPDC_SECTION_DOCUMENT
;
1569 else if (!_cups_strcasecmp(type
, "ExitServer"))
1570 section
= PPDC_SECTION_EXIT
;
1571 else if (!_cups_strcasecmp(type
, "JCLSetup"))
1572 section
= PPDC_SECTION_JCL
;
1573 else if (!_cups_strcasecmp(type
, "PageSetup"))
1574 section
= PPDC_SECTION_PAGE
;
1575 else if (!_cups_strcasecmp(type
, "Prolog"))
1576 section
= PPDC_SECTION_PROLOG
;
1579 _cupsLangPrintf(stderr
,
1580 _("ppdc: Invalid option section \"%s\" on line %d of "
1581 "%s."), type
, fp
->line
, fp
->filename
);
1585 order
= get_float(fp
);
1587 // See if the option already exists...
1588 if ((o
= d
->find_option_group(name
, &mg
)) == NULL
)
1590 // Nope, add a new one...
1591 o
= new ppdcOption(ot
, name
, text
, section
, order
);
1593 else if (o
->type
!= ot
)
1595 _cupsLangPrintf(stderr
,
1596 _("ppdc: Option %s redefined with a different type on line "
1597 "%d of %s."), name
, fp
->line
, fp
->filename
);
1602 _cupsLangPrintf(stderr
,
1603 _("ppdc: Option %s defined in two different groups on line "
1604 "%d of %s."), name
, fp
->line
, fp
->filename
);
1613 // 'ppdcSource::get_po()' - Get a message catalog.
1616 ppdcCatalog
* // O - Message catalog
1617 ppdcSource::get_po(ppdcFile
*fp
) // I - File to read
1619 char locale
[32], // Locale name
1620 poname
[1024], // Message catalog filename
1621 basedir
[1024], // Base directory
1622 *baseptr
, // Pointer into directory
1623 pofilename
[1024]; // Full filename of message catalog
1624 ppdcCatalog
*cat
; // Message catalog
1627 // Read the #po parameters:
1629 // #po locale "filename.po"
1630 if (!get_token(fp
, locale
, sizeof(locale
)))
1632 _cupsLangPrintf(stderr
,
1633 _("ppdc: Expected locale after #po on line %d of %s."),
1634 fp
->line
, fp
->filename
);
1638 if (!get_token(fp
, poname
, sizeof(poname
)))
1640 _cupsLangPrintf(stderr
,
1641 _("ppdc: Expected filename after #po %s on line %d of "
1642 "%s."), locale
, fp
->line
, fp
->filename
);
1646 // See if the locale is already loaded...
1647 if (find_po(locale
))
1649 _cupsLangPrintf(stderr
,
1650 _("ppdc: Duplicate #po for locale %s on line %d of %s."),
1651 locale
, fp
->line
, fp
->filename
);
1655 // Figure out the current directory...
1656 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
1658 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
1661 strlcpy(basedir
, ".", sizeof(basedir
));
1663 // Find the po file...
1664 pofilename
[0] = '\0';
1667 find_include(poname
, basedir
, pofilename
, sizeof(pofilename
)))
1669 // Found it, so load it...
1670 cat
= new ppdcCatalog(locale
, pofilename
);
1672 // Reset the filename to the name supplied by the user...
1673 cat
->filename
->release();
1674 cat
->filename
= new ppdcString(poname
);
1676 // Return the catalog...
1681 _cupsLangPrintf(stderr
,
1682 _("ppdc: Unable to find #po file %s on line %d of %s."),
1683 poname
, fp
->line
, fp
->filename
);
1690 // 'ppdcSource::get_resolution()' - Get an old-style resolution option.
1693 ppdcChoice
* // O - Choice data
1694 ppdcSource::get_resolution(ppdcFile
*fp
)// I - File to read
1696 char name
[1024], // Name
1698 temp
[256], // Temporary string
1699 command
[256], // Command string
1700 *commptr
; // Pointer into command
1701 int xdpi
, ydpi
, // X + Y resolution
1702 color_order
, // Color order
1703 color_space
, // Colorspace
1704 compression
, // Compression mode
1705 depth
, // Bits per color
1706 row_count
, // Row count
1707 row_feed
, // Row feed
1708 row_step
; // Row step/interval
1711 // Read the resolution parameters:
1713 // Resolution colorspace bits row-count row-feed row-step name/text
1714 if (!get_token(fp
, temp
, sizeof(temp
)))
1716 _cupsLangPrintf(stderr
,
1717 _("ppdc: Expected override field after Resolution on line "
1718 "%d of %s."), fp
->line
, fp
->filename
);
1722 color_order
= get_color_order(temp
);
1723 color_space
= get_color_space(temp
);
1724 compression
= get_integer(temp
);
1726 depth
= get_integer(fp
);
1727 row_count
= get_integer(fp
);
1728 row_feed
= get_integer(fp
);
1729 row_step
= get_integer(fp
);
1731 if (!get_token(fp
, name
, sizeof(name
)))
1733 _cupsLangPrintf(stderr
,
1734 _("ppdc: Expected name/text after Resolution on line %d of "
1735 "%s."), fp
->line
, fp
->filename
);
1739 if ((text
= strchr(name
, '/')) != NULL
)
1744 switch (sscanf(name
, "%dx%d", &xdpi
, &ydpi
))
1747 _cupsLangPrintf(stderr
,
1748 _("ppdc: Bad resolution name \"%s\" on line %d of "
1749 "%s."), name
, fp
->line
, fp
->filename
);
1756 // Create the necessary PS commands...
1757 snprintf(command
, sizeof(command
),
1758 "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
1759 "/cupsRowFeed %d/cupsRowStep %d",
1760 xdpi
, ydpi
, depth
, row_count
, row_feed
, row_step
);
1761 commptr
= command
+ strlen(command
);
1763 if (color_order
>= 0)
1765 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1766 "/cupsColorOrder %d", color_order
);
1767 commptr
+= strlen(commptr
);
1770 if (color_space
>= 0)
1772 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1773 "/cupsColorSpace %d", color_space
);
1774 commptr
+= strlen(commptr
);
1777 if (compression
>= 0)
1779 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1780 "/cupsCompression %d", compression
);
1781 commptr
+= strlen(commptr
);
1784 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
), ">>setpagedevice");
1786 // Return the new choice...
1787 return (new ppdcChoice(name
, text
, command
));
1792 // 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
1795 ppdcProfile
* // O - Color profile
1796 ppdcSource::get_simple_profile(ppdcFile
*fp
)
1799 char resolution
[1024], // Resolution/media type
1800 *media_type
; // Media type
1801 float m
[9]; // Transform matrix
1802 float kd
, rd
, g
; // Densities and gamma
1803 float red
, green
, blue
; // RGB adjustments
1804 float yellow
; // Yellow density
1805 float color
; // Color density values
1808 // Get the SimpleColorProfile parameters:
1810 // SimpleColorProfile resolution/mediatype black-density yellow-density
1811 // red-density gamma red-adjust green-adjust blue-adjust
1812 if (!get_token(fp
, resolution
, sizeof(resolution
)))
1814 _cupsLangPrintf(stderr
,
1815 _("ppdc: Expected resolution/mediatype following "
1816 "SimpleColorProfile on line %d of %s."),
1817 fp
->line
, fp
->filename
);
1821 if ((media_type
= strchr(resolution
, '/')) != NULL
)
1822 *media_type
++ = '\0';
1824 media_type
= resolution
;
1826 // Collect the profile parameters...
1828 yellow
= get_float(fp
);
1831 red
= get_float(fp
);
1832 green
= get_float(fp
);
1833 blue
= get_float(fp
);
1835 // Build the color profile...
1836 color
= 0.5f
* rd
/ kd
- kd
;
1838 m
[1] = color
+ blue
; // C + M (blue)
1839 m
[2] = color
- green
; // C + Y (green)
1840 m
[3] = color
- blue
; // M + C (blue)
1842 m
[5] = color
+ red
; // M + Y (red)
1843 m
[6] = yellow
* (color
+ green
); // Y + C (green)
1844 m
[7] = yellow
* (color
- red
); // Y + M (red)
1852 else if (m
[3] > 0.0f
)
1863 else if (m
[6] > 0.0f
)
1874 else if (m
[7] > 0.0f
)
1880 // Return the new profile...
1881 return (new ppdcProfile(resolution
, media_type
, g
, kd
, m
));
1886 // 'ppdcSource::get_size()' - Get a media size definition from a file.
1889 ppdcMediaSize
* // O - Media size
1890 ppdcSource::get_size(ppdcFile
*fp
) // I - File to read
1892 char name
[1024], // Name
1894 float width
, // Width
1898 // Get the name, text, width, and length:
1900 // #media name/text width length
1901 if (!get_token(fp
, name
, sizeof(name
)))
1904 if ((text
= strchr(name
, '/')) != NULL
)
1909 if ((width
= get_measurement(fp
)) < 0.0f
)
1912 if ((length
= get_measurement(fp
)) < 0.0f
)
1915 // Return the new media size...
1916 return (new ppdcMediaSize(name
, text
, width
, length
, 0.0f
, 0.0f
, 0.0f
, 0.0f
));
1921 // 'ppdcSource::get_token()' - Get a token from a file.
1924 char * // O - Token string or NULL
1925 ppdcSource::get_token(ppdcFile
*fp
, // I - File to read
1926 char *buffer
, // I - Buffer
1927 int buflen
) // I - Length of buffer
1929 char *bufptr
, // Pointer into string buffer
1930 *bufend
; // End of string buffer
1931 int ch
, // Character from file
1932 nextch
, // Next char in file
1933 quote
, // Quote character used...
1934 empty
, // Empty input?
1935 startline
; // Start line for quote
1936 char name
[256], // Name string
1937 *nameptr
; // Name pointer
1938 ppdcVariable
*var
; // Variable pointer
1941 // Mark the beginning and end of the buffer...
1943 bufend
= buffer
+ buflen
- 1;
1945 // Loop intil we've read a token...
1950 while ((ch
= fp
->get()) != EOF
)
1952 if (isspace(ch
) && !quote
)
1961 // Variable substitution
1964 for (nameptr
= name
; (ch
= fp
->peek()) != EOF
;)
1966 if (!isalnum(ch
) && ch
!= '_')
1968 else if (nameptr
< (name
+ sizeof(name
) - 1))
1969 *nameptr
++ = (char)fp
->get();
1972 if (nameptr
== name
)
1974 // Just substitute this character...
1978 if (bufptr
< bufend
)
1979 *bufptr
++ = (char)fp
->get();
1984 _cupsLangPrintf(stderr
,
1985 _("ppdc: Bad variable substitution ($%c) on line %d "
1986 "of %s."), ch
, fp
->line
, fp
->filename
);
1988 if (bufptr
< bufend
)
1994 // Substitute the variable value...
1996 var
= find_variable(name
);
1999 strlcpy(bufptr
, var
->value
->value
, (size_t)(bufend
- bufptr
+ 1));
2000 bufptr
+= strlen(bufptr
);
2004 if (!(cond_state
& PPDC_COND_SKIP
))
2005 _cupsLangPrintf(stderr
,
2006 _("ppdc: Undefined variable (%s) on line %d of "
2007 "%s."), name
, fp
->line
, fp
->filename
);
2009 snprintf(bufptr
, (size_t)(bufend
- bufptr
+ 1), "$%s", name
);
2010 bufptr
+= strlen(bufptr
);
2014 else if (ch
== '/' && !quote
)
2016 // Possibly a comment...
2017 nextch
= fp
->peek();
2024 while ((nextch
= fp
->get()) != EOF
)
2026 if (ch
== '*' && nextch
== '/')
2035 else if (nextch
== '/')
2038 while ((nextch
= fp
->get()) != EOF
)
2050 if (bufptr
< bufend
)
2051 *bufptr
++ = (char)ch
;
2054 else if (ch
== '\'' || ch
== '\"')
2060 // Ending the current quoted string...
2065 // Insert the opposing quote char...
2066 if (bufptr
< bufend
)
2067 *bufptr
++ = (char)ch
;
2071 // Start a new quoted string...
2072 startline
= fp
->line
;
2076 else if ((ch
== '(' || ch
== '<') && !quote
)
2080 startline
= fp
->line
;
2082 if (bufptr
< bufend
)
2083 *bufptr
++ = (char)ch
;
2085 else if ((ch
== ')' && quote
== '(') || (ch
== '>' && quote
== '<'))
2089 if (bufptr
< bufend
)
2090 *bufptr
++ = (char)ch
;
2092 else if (ch
== '\\')
2096 if ((ch
= fp
->get()) == EOF
)
2099 if (bufptr
< bufend
)
2100 *bufptr
++ = (char)ch
;
2102 else if (bufptr
< bufend
)
2106 *bufptr
++ = (char)ch
;
2108 if ((ch
== '{' || ch
== '}') && !quote
)
2115 _cupsLangPrintf(stderr
,
2116 _("ppdc: Unterminated string starting with %c on line %d "
2117 "of %s."), quote
, startline
, fp
->filename
);
2132 // 'ppdcSource::get_variable()' - Get a variable definition.
2135 ppdcVariable
* // O - Variable
2136 ppdcSource::get_variable(ppdcFile
*fp
) // I - File to read
2138 char name
[1024], // Name
2139 value
[1024]; // Value
2142 // Get the name and value:
2144 // #define name value
2145 if (!get_token(fp
, name
, sizeof(name
)))
2148 if (!get_token(fp
, value
, sizeof(value
)))
2151 // Set the variable...
2152 return (set_variable(name
, value
));
2157 // 'ppdcSource::quotef()' - Write a formatted, quoted string...
2160 int // O - Number bytes on success, -1 on failure
2161 ppdcSource::quotef(cups_file_t
*fp
, // I - File to write to
2162 const char *format
, // I - Printf-style format string
2163 ...) // I - Additional args as needed
2165 va_list ap
; // Pointer to additional arguments
2166 int bytes
; // Bytes written
2167 char sign
, // Sign of format width
2168 size
, // Size character (h, l, L)
2169 type
; // Format type character
2170 const char *bufformat
; // Start of format
2171 int width
, // Width of field
2172 prec
; // Number of characters of precision
2173 char tformat
[100]; // Temporary format string for fprintf()
2174 char *s
; // Pointer to string
2175 int slen
; // Length of string
2176 int i
; // Looping var
2179 // Range check input...
2183 // Loop through the format string, formatting as needed...
2184 va_start(ap
, format
);
2197 cupsFilePutChar(fp
, *format
++);
2201 else if (strchr(" -+#\'", *format
))
2207 while (isdigit(*format
))
2208 width
= width
* 10 + *format
++ - '0';
2215 while (isdigit(*format
))
2216 prec
= prec
* 10 + *format
++ - '0';
2221 if (*format
== 'l' && format
[1] == 'l')
2226 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
2238 case 'E' : // Floating point formats
2243 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2246 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2247 tformat
[format
- bufformat
] = '\0';
2249 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, double));
2252 case 'B' : // Integer formats
2260 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2263 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2264 tformat
[format
- bufformat
] = '\0';
2266 # ifdef HAVE_LONG_LONG
2268 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long long));
2270 # endif /* HAVE_LONG_LONG */
2272 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long));
2274 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, int));
2277 case 'p' : // Pointer value
2278 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2281 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2282 tformat
[format
- bufformat
] = '\0';
2284 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, void *));
2287 case 'c' : // Character or character array
2291 cupsFilePutChar(fp
, va_arg(ap
, int));
2295 cupsFileWrite(fp
, va_arg(ap
, char *), (size_t)width
);
2300 case 's' : // String
2301 if ((s
= va_arg(ap
, char *)) == NULL
)
2302 s
= (char *)"(nil)";
2304 slen
= (int)strlen(s
);
2305 if (slen
> width
&& prec
!= width
)
2313 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2314 cupsFilePutChar(fp
, ' ');
2317 for (i
= slen
; i
> 0; i
--, s
++, bytes
++)
2319 if (*s
== '\\' || *s
== '\"')
2321 cupsFilePutChar(fp
, '\\');
2325 cupsFilePutChar(fp
, *s
);
2330 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2331 cupsFilePutChar(fp
, ' ');
2338 cupsFilePutChar(fp
, *format
++);
2345 // Return the number of characters written.
2351 // 'ppdcSource::read_file()' - Read a driver source file.
2355 ppdcSource::read_file(const char *f
, // I - File to read
2356 cups_file_t
*ffp
) // I - File pointer to use
2358 ppdcFile
*fp
= new ppdcFile(f
, ffp
);
2362 if (cond_current
!= cond_stack
)
2363 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."), f
);
2368 // 'ppdcSource::scan_file()' - Scan a driver source file.
2372 ppdcSource::scan_file(ppdcFile
*fp
, // I - File to read
2373 ppdcDriver
*td
, // I - Driver template
2374 bool inc
) // I - Including?
2376 ppdcDriver
*d
; // Current driver
2377 ppdcGroup
*g
, // Current group
2378 *mg
, // Matching 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...
2395 d
= new ppdcDriver(td
);
2397 if ((general
= d
->find_group("General")) == NULL
)
2399 general
= new ppdcGroup("General", NULL
);
2400 d
->add_group(general
);
2403 if ((install
= d
->find_group("InstallableOptions")) == NULL
)
2405 install
= new ppdcGroup("InstallableOptions", "Installable Options");
2406 d
->add_group(install
);
2409 // Loop until EOF or }
2413 while (get_token(fp
, temp
, sizeof(temp
)))
2417 // Mark the next choice as the default
2420 for (ptr
= temp
; ptr
[1]; ptr
++)
2427 // Don't mark the next choice as the default
2431 if (!_cups_strcasecmp(temp
, "}"))
2433 // Close this one out...
2436 else if (!_cups_strcasecmp(temp
, "{"))
2438 // Open a new child...
2441 else if (!_cups_strcasecmp(temp
, "#if"))
2443 if ((cond_current
- cond_stack
) >= 100)
2445 _cupsLangPrintf(stderr
,
2446 _("ppdc: Too many nested #if's on line %d of %s."),
2447 fp
->line
, fp
->filename
);
2452 if (get_integer(fp
) > 0)
2453 *cond_current
= PPDC_COND_SATISFIED
;
2456 *cond_current
= PPDC_COND_SKIP
;
2457 cond_state
|= PPDC_COND_SKIP
;
2460 else if (!_cups_strcasecmp(temp
, "#elif"))
2462 if (cond_current
== cond_stack
)
2464 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2465 fp
->line
, fp
->filename
);
2469 if (*cond_current
& PPDC_COND_SATISFIED
)
2472 *cond_current
|= PPDC_COND_SKIP
;
2474 else if (get_integer(fp
) > 0)
2476 *cond_current
|= PPDC_COND_SATISFIED
;
2477 *cond_current
&= ~PPDC_COND_SKIP
;
2480 *cond_current
|= PPDC_COND_SKIP
;
2482 // Update the current state
2483 int *cond_temp
= cond_current
; // Temporary stack pointer
2485 cond_state
= PPDC_COND_NORMAL
;
2486 while (cond_temp
> cond_stack
)
2487 if (*cond_temp
& PPDC_COND_SKIP
)
2489 cond_state
= PPDC_COND_SKIP
;
2495 else if (!_cups_strcasecmp(temp
, "#else"))
2497 if (cond_current
== cond_stack
)
2499 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2500 fp
->line
, fp
->filename
);
2504 if (*cond_current
& PPDC_COND_SATISFIED
)
2505 *cond_current
|= PPDC_COND_SKIP
;
2508 *cond_current
|= PPDC_COND_SATISFIED
;
2509 *cond_current
&= ~PPDC_COND_SKIP
;
2512 // Update the current state
2513 int *cond_temp
= cond_current
; // Temporary stack pointer
2515 cond_state
= PPDC_COND_NORMAL
;
2516 while (cond_temp
> cond_stack
)
2517 if (*cond_temp
& PPDC_COND_SKIP
)
2519 cond_state
= PPDC_COND_SKIP
;
2525 else if (!_cups_strcasecmp(temp
, "#endif"))
2527 if (cond_current
== cond_stack
)
2529 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2530 fp
->line
, fp
->filename
);
2536 // Update the current state
2537 int *cond_temp
= cond_current
; // Temporary stack pointer
2539 cond_state
= PPDC_COND_NORMAL
;
2540 while (cond_temp
> cond_stack
)
2541 if (*cond_temp
& PPDC_COND_SKIP
)
2543 cond_state
= PPDC_COND_SKIP
;
2549 else if (!_cups_strcasecmp(temp
, "#define"))
2551 // Get the variable...
2554 else if (!_cups_strcasecmp(temp
, "#include"))
2556 // #include filename
2557 char basedir
[1024], // Base directory
2558 *baseptr
, // Pointer into directory
2559 inctemp
[1024], // Initial filename
2560 incname
[1024]; // Include filename
2561 ppdcFile
*incfile
; // Include file
2562 int *old_current
= cond_current
;
2563 // Previous current stack
2566 // Get the include name...
2567 if (!get_token(fp
, inctemp
, sizeof(inctemp
)))
2569 _cupsLangPrintf(stderr
,
2570 _("ppdc: Expected include filename on line %d of "
2571 "%s."), fp
->line
, fp
->filename
);
2578 // Figure out the current directory...
2579 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
2581 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
2584 strlcpy(basedir
, ".", sizeof(basedir
));
2586 // Find the include file...
2587 if (find_include(inctemp
, basedir
, incname
, sizeof(incname
)))
2589 // Open the include file, scan it, and then close it...
2590 incfile
= new ppdcFile(incname
);
2591 scan_file(incfile
, d
, true);
2594 if (cond_current
!= old_current
)
2595 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."),
2601 _cupsLangPrintf(stderr
,
2602 _("ppdc: Unable to find include file \"%s\" on line %d "
2603 "of %s."), inctemp
, fp
->line
, fp
->filename
);
2607 else if (!_cups_strcasecmp(temp
, "#media"))
2609 ppdcMediaSize
*m
; // Media size
2612 // Get a media size...
2622 else if (!_cups_strcasecmp(temp
, "#po"))
2624 ppdcCatalog
*cat
; // Message catalog
2627 // Get a message catalog...
2637 else if (!_cups_strcasecmp(temp
, "Attribute") ||
2638 !_cups_strcasecmp(temp
, "LocAttribute"))
2640 ppdcAttr
*a
; // Attribute
2643 // Get an attribute...
2644 a
= get_attr(fp
, !_cups_strcasecmp(temp
, "LocAttribute"));
2653 else if (!_cups_strcasecmp(temp
, "Choice"))
2666 // Add it to the current option...
2670 _cupsLangPrintf(stderr
,
2671 _("ppdc: Choice found on line %d of %s with no "
2672 "Option."), fp
->line
, fp
->filename
);
2679 o
->set_defchoice(c
);
2681 else if (!_cups_strcasecmp(temp
, "ColorDevice"))
2683 // ColorDevice boolean
2687 d
->color_device
= get_boolean(fp
);
2689 else if (!_cups_strcasecmp(temp
, "ColorModel"))
2691 // Get the color model
2692 c
= get_color_model(fp
);
2702 // Add the choice to the ColorModel option...
2703 if ((o
= d
->find_option("ColorModel")) == NULL
)
2705 // Create the ColorModel option...
2706 o
= new ppdcOption(PPDC_PICKONE
, "ColorModel", "Color Mode", PPDC_SECTION_ANY
, 10.0f
);
2714 o
->set_defchoice(c
);
2718 else if (!_cups_strcasecmp(temp
, "ColorProfile"))
2720 ppdcProfile
*p
; // Color profile
2723 // Get the color profile...
2724 p
= get_color_profile(fp
);
2731 d
->profiles
->add(p
);
2734 else if (!_cups_strcasecmp(temp
, "Copyright"))
2737 char copytemp
[8192], // Copyright string
2738 *copyptr
, // Pointer into string
2739 *copyend
; // Pointer to end of string
2742 // Get the copyright string...
2743 if (!get_token(fp
, copytemp
, sizeof(temp
)))
2745 _cupsLangPrintf(stderr
,
2746 _("ppdc: Expected string after Copyright on line %d "
2747 "of %s."), fp
->line
, fp
->filename
);
2754 // Break it up into individual lines...
2755 for (copyptr
= copytemp
; copyptr
; copyptr
= copyend
)
2757 if ((copyend
= strchr(copyptr
, '\n')) != NULL
)
2760 d
->copyright
->add(new ppdcString(copyptr
));
2763 else if (!_cups_strcasecmp(temp
, "CustomMedia"))
2765 ppdcMediaSize
*m
; // Media size
2768 // Get a custom media size...
2769 m
= get_custom_size(fp
);
2781 d
->set_default_size(m
);
2783 else if (!_cups_strcasecmp(temp
, "Cutter"))
2786 int have_cutter
; // Have a paper cutter?
2789 have_cutter
= get_boolean(fp
);
2790 if (have_cutter
<= 0 || cond_state
)
2793 if ((o
= d
->find_option("CutMedia")) == NULL
)
2795 o
= new ppdcOption(PPDC_BOOLEAN
, "CutMedia", "Cut Media", PPDC_SECTION_ANY
, 10.0f
);
2800 c
= new ppdcChoice("False", NULL
, "<</CutMedia 0>>setpagedevice");
2802 o
->set_defchoice(c
);
2804 c
= new ppdcChoice("True", NULL
, "<</CutMedia 4>>setpagedevice");
2810 else if (!_cups_strcasecmp(temp
, "Darkness"))
2812 // Get the darkness choice...
2813 c
= get_generic(fp
, "Darkness", NULL
, "cupsCompression");
2823 // Add the choice to the cupsDarkness option...
2824 if ((o
= d
->find_option_group("cupsDarkness", &mg
)) == NULL
)
2826 // Create the cupsDarkness option...
2827 o
= new ppdcOption(PPDC_PICKONE
, "cupsDarkness", "Darkness", PPDC_SECTION_ANY
, 10.0f
);
2831 else if (mg
!= general
)
2833 _cupsLangPrintf(stderr
,
2834 _("ppdc: Option %s defined in two different groups on "
2835 "line %d of %s."), "cupsDarkness", fp
->line
,
2844 o
->set_defchoice(c
);
2848 else if (!_cups_strcasecmp(temp
, "DriverType"))
2850 int i
; // Looping var
2853 // DriverType keyword
2854 if (!get_token(fp
, temp
, sizeof(temp
)))
2856 _cupsLangPrintf(stderr
,
2857 _("ppdc: Expected driver type keyword following "
2858 "DriverType on line %d of %s."),
2859 fp
->line
, fp
->filename
);
2866 for (i
= 0; i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])); i
++)
2867 if (!_cups_strcasecmp(temp
, driver_types
[i
]))
2870 if (i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])))
2871 d
->type
= (ppdcDrvType
)i
;
2872 else if (!_cups_strcasecmp(temp
, "dymo"))
2873 d
->type
= PPDC_DRIVER_LABEL
;
2875 _cupsLangPrintf(stderr
,
2876 _("ppdc: Unknown driver type %s on line %d of %s."),
2877 temp
, fp
->line
, fp
->filename
);
2879 else if (!_cups_strcasecmp(temp
, "Duplex"))
2881 else if (!_cups_strcasecmp(temp
, "Filter"))
2883 ppdcFilter
*f
; // Filter
2886 // Get the filter value...
2896 else if (!_cups_strcasecmp(temp
, "Finishing"))
2898 // Get the finishing choice...
2899 c
= get_generic(fp
, "Finishing", "OutputType", NULL
);
2909 // Add the choice to the cupsFinishing option...
2910 if ((o
= d
->find_option_group("cupsFinishing", &mg
)) == NULL
)
2912 // Create the cupsFinishing option...
2913 o
= new ppdcOption(PPDC_PICKONE
, "cupsFinishing", "Finishing", PPDC_SECTION_ANY
, 10.0f
);
2917 else if (mg
!= general
)
2919 _cupsLangPrintf(stderr
,
2920 _("ppdc: Option %s defined in two different groups on "
2921 "line %d of %s."), "cupsFinishing", fp
->line
,
2930 o
->set_defchoice(c
);
2934 else if (!_cups_strcasecmp(temp
, "Font") ||
2935 !_cups_strcasecmp(temp
, "#font"))
2937 ppdcFont
*f
; // Font
2948 if (!_cups_strcasecmp(temp
, "#font"))
2954 d
->set_default_font(f
);
2958 else if (!_cups_strcasecmp(temp
, "Group"))
2961 ppdcGroup
*tempg
= get_group(fp
, d
);
2968 if (!d
->find_group(tempg
->name
->value
))
2973 if (!d
->find_group(tempg
->name
->value
))
2974 d
->add_group(tempg
);
2979 else if (!_cups_strcasecmp(temp
, "HWMargins"))
2981 // HWMargins left bottom right top
2982 d
->left_margin
= get_measurement(fp
);
2983 d
->bottom_margin
= get_measurement(fp
);
2984 d
->right_margin
= get_measurement(fp
);
2985 d
->top_margin
= get_measurement(fp
);
2987 else if (!_cups_strcasecmp(temp
, "InputSlot"))
2989 // Get the input slot choice...
2990 c
= get_generic(fp
, "InputSlot", NULL
, "MediaPosition");
3000 // Add the choice to the InputSlot option...
3002 if ((o
= d
->find_option_group("InputSlot", &mg
)) == NULL
)
3004 // Create the InputSlot option...
3005 o
= new ppdcOption(PPDC_PICKONE
, "InputSlot", "Media Source",
3006 PPDC_SECTION_ANY
, 10.0f
);
3010 else if (mg
!= general
)
3012 _cupsLangPrintf(stderr
,
3013 _("ppdc: Option %s defined in two different groups on "
3014 "line %d of %s."), "InputSlot", fp
->line
,
3023 o
->set_defchoice(c
);
3027 else if (!_cups_strcasecmp(temp
, "Installable"))
3029 // Get the installable option...
3030 o
= get_installable(fp
);
3032 // Add it as needed...
3038 install
->add_option(o
);
3043 else if (!_cups_strcasecmp(temp
, "ManualCopies"))
3045 // ManualCopies boolean
3049 d
->manual_copies
= get_boolean(fp
);
3051 else if (!_cups_strcasecmp(temp
, "Manufacturer"))
3053 // Manufacturer name
3054 char name
[256]; // Model name string
3057 if (!get_token(fp
, name
, sizeof(name
)))
3059 _cupsLangPrintf(stderr
,
3060 _("ppdc: Expected name after Manufacturer on line %d "
3061 "of %s."), fp
->line
, fp
->filename
);
3066 d
->set_manufacturer(name
);
3068 else if (!_cups_strcasecmp(temp
, "MaxSize"))
3070 // MaxSize width length
3073 get_measurement(fp
);
3074 get_measurement(fp
);
3078 d
->max_width
= get_measurement(fp
);
3079 d
->max_length
= get_measurement(fp
);
3082 else if (!_cups_strcasecmp(temp
, "MediaSize"))
3084 // MediaSize keyword
3085 char name
[41]; // Media size name
3086 ppdcMediaSize
*m
, // Matching media size...
3087 *dm
; // Driver media size...
3090 if (get_token(fp
, name
, sizeof(name
)) == NULL
)
3092 _cupsLangPrintf(stderr
,
3093 _("ppdc: Expected name after MediaSize on line %d of "
3094 "%s."), fp
->line
, fp
->filename
);
3101 m
= find_size(name
);
3105 _cupsLangPrintf(stderr
,
3106 _("ppdc: Unknown media size \"%s\" on line %d of "
3107 "%s."), name
, fp
->line
, fp
->filename
);
3111 // Add this size to the driver...
3112 dm
= new ppdcMediaSize(m
->name
->value
, m
->text
->value
,
3113 m
->width
, m
->length
, d
->left_margin
,
3114 d
->bottom_margin
, d
->right_margin
,
3119 d
->set_default_size(dm
);
3121 else if (!_cups_strcasecmp(temp
, "MediaType"))
3123 // Get the media type choice...
3124 c
= get_generic(fp
, "MediaType", "MediaType", "cupsMediaType");
3134 // Add the choice to the MediaType option...
3135 if ((o
= d
->find_option_group("MediaType", &mg
)) == NULL
)
3137 // Create the MediaType option...
3138 o
= new ppdcOption(PPDC_PICKONE
, "MediaType", "Media Type",
3139 PPDC_SECTION_ANY
, 10.0f
);
3143 else if (mg
!= general
)
3145 _cupsLangPrintf(stderr
,
3146 _("ppdc: Option %s defined in two different groups on "
3147 "line %d of %s."), "MediaType", fp
->line
,
3156 o
->set_defchoice(c
);
3160 else if (!_cups_strcasecmp(temp
, "MinSize"))
3162 // MinSize width length
3165 get_measurement(fp
);
3166 get_measurement(fp
);
3170 d
->min_width
= get_measurement(fp
);
3171 d
->min_length
= get_measurement(fp
);
3174 else if (!_cups_strcasecmp(temp
, "ModelName"))
3177 char name
[256]; // Model name string
3180 if (!get_token(fp
, name
, sizeof(name
)))
3182 _cupsLangPrintf(stderr
,
3183 _("ppdc: Expected name after ModelName on line %d of "
3184 "%s."), fp
->line
, fp
->filename
);
3189 d
->set_model_name(name
);
3191 else if (!_cups_strcasecmp(temp
, "ModelNumber"))
3193 // ModelNumber number
3197 d
->model_number
= get_integer(fp
);
3199 else if (!_cups_strcasecmp(temp
, "Option"))
3202 ppdcOption
*tempo
= get_option(fp
, d
, g
);
3209 if (!g
->find_option(tempo
->name
->value
))
3214 if (!g
->find_option(tempo
->name
->value
))
3215 g
->add_option(tempo
);
3220 else if (!_cups_strcasecmp(temp
, "FileName"))
3223 char name
[256]; // Filename string
3226 if (!get_token(fp
, name
, sizeof(name
)))
3228 _cupsLangPrintf(stderr
,
3229 _("ppdc: Expected name after FileName on line %d of "
3230 "%s."), fp
->line
, fp
->filename
);
3235 d
->set_file_name(name
);
3237 else if (!_cups_strcasecmp(temp
, "PCFileName"))
3240 char name
[256]; // PC filename string
3243 if (!get_token(fp
, name
, sizeof(name
)))
3245 _cupsLangPrintf(stderr
,
3246 _("ppdc: Expected name after PCFileName on line %d of "
3247 "%s."), fp
->line
, fp
->filename
);
3252 d
->set_pc_file_name(name
);
3254 else if (!_cups_strcasecmp(temp
, "Resolution"))
3256 // Get the resolution choice...
3257 c
= get_resolution(fp
);
3267 // Add the choice to the Resolution option...
3268 if ((o
= d
->find_option_group("Resolution", &mg
)) == NULL
)
3270 // Create the Resolution option...
3271 o
= new ppdcOption(PPDC_PICKONE
, "Resolution", NULL
, PPDC_SECTION_ANY
,
3276 else if (mg
!= general
)
3278 _cupsLangPrintf(stderr
,
3279 _("ppdc: Option %s defined in two different groups on "
3280 "line %d of %s."), "Resolution", fp
->line
,
3289 o
->set_defchoice(c
);
3293 else if (!_cups_strcasecmp(temp
, "SimpleColorProfile"))
3295 ppdcProfile
*p
; // Color profile
3298 // Get the color profile...
3299 p
= get_simple_profile(fp
);
3306 d
->profiles
->add(p
);
3309 else if (!_cups_strcasecmp(temp
, "Throughput"))
3311 // Throughput number
3315 d
->throughput
= get_integer(fp
);
3317 else if (!_cups_strcasecmp(temp
, "UIConstraints"))
3319 ppdcConstraint
*con
; // Constraint
3322 con
= get_constraint(fp
);
3329 d
->constraints
->add(con
);
3332 else if (!_cups_strcasecmp(temp
, "VariablePaperSize"))
3334 // VariablePaperSize boolean
3338 d
->variable_paper_size
= get_boolean(fp
);
3340 else if (!_cups_strcasecmp(temp
, "Version"))
3343 char name
[256]; // Model name string
3346 if (!get_token(fp
, name
, sizeof(name
)))
3348 _cupsLangPrintf(stderr
,
3349 _("ppdc: Expected string after Version on line %d of "
3350 "%s."), fp
->line
, fp
->filename
);
3355 d
->set_version(name
);
3359 _cupsLangPrintf(stderr
,
3360 _("ppdc: Unknown token \"%s\" seen on line %d of %s."),
3361 temp
, fp
->line
, fp
->filename
);
3366 // Done processing this block, is there anything to save?
3369 if (!d
->pc_file_name
|| !d
->model_name
|| !d
->manufacturer
|| !d
->version
||
3372 // Nothing to save...
3377 // Got a driver, save it...
3387 // 'ppdcSource::set_variable()' - Set a variable.
3390 ppdcVariable
* // O - Variable
3391 ppdcSource::set_variable(
3392 const char *name
, // I - Name
3393 const char *value
) // I - Value
3395 ppdcVariable
*v
; // Variable
3398 // See if the variable exists already...
3399 v
= find_variable(name
);
3402 // Change the variable value...
3403 v
->set_value(value
);
3407 // Create a new variable and add it...
3408 v
= new ppdcVariable(name
, value
);
3417 // 'ppdcSource::write_file()' - Write the current source data to a file.
3420 int // O - 0 on success, -1 on error
3421 ppdcSource::write_file(const char *f
) // I - File to write
3423 cups_file_t
*fp
; // Output file
3424 char bckname
[1024]; // Backup file
3425 ppdcDriver
*d
; // Current driver
3426 ppdcString
*st
; // Current string
3427 ppdcAttr
*a
; // Current attribute
3428 ppdcConstraint
*co
; // Current constraint
3429 ppdcFilter
*fi
; // Current filter
3430 ppdcFont
*fo
; // Current font
3431 ppdcGroup
*g
; // Current group
3432 ppdcOption
*o
; // Current option
3433 ppdcChoice
*ch
; // Current choice
3434 ppdcProfile
*p
; // Current color profile
3435 ppdcMediaSize
*si
; // Current media size
3436 float left
, // Current left margin
3437 bottom
, // Current bottom margin
3438 right
, // Current right margin
3439 top
; // Current top margin
3440 int dtused
[PPDC_DRIVER_MAX
];// Driver type usage...
3443 // Rename the current file, if any, to .bck...
3444 snprintf(bckname
, sizeof(bckname
), "%s.bck", f
);
3447 // Open the output file...
3448 fp
= cupsFileOpen(f
, "w");
3452 // Can't create file; restore backup and return...
3457 cupsFilePuts(fp
, "// CUPS PPD Compiler " CUPS_SVERSION
"\n\n");
3459 // Include standard files...
3460 cupsFilePuts(fp
, "// Include necessary files...\n");
3461 cupsFilePuts(fp
, "#include <font.defs>\n");
3462 cupsFilePuts(fp
, "#include <media.defs>\n");
3464 memset(dtused
, 0, sizeof(dtused
));
3466 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3467 if (d
->type
> PPDC_DRIVER_PS
&& !dtused
[d
->type
])
3469 cupsFilePrintf(fp
, "#include <%s.h>\n", driver_types
[d
->type
]);
3470 dtused
[d
->type
] = 1;
3473 // Output each driver...
3474 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3476 // Start the driver...
3477 cupsFilePrintf(fp
, "\n// %s %s\n", d
->manufacturer
->value
,
3478 d
->model_name
->value
);
3479 cupsFilePuts(fp
, "{\n");
3481 // Write the copyright stings...
3482 for (st
= (ppdcString
*)d
->copyright
->first();
3484 st
= (ppdcString
*)d
->copyright
->next())
3485 quotef(fp
, " Copyright \"%s\"\n", st
->value
);
3487 // Write other strings and values...
3488 if (d
->manufacturer
&& d
->manufacturer
->value
)
3489 quotef(fp
, " Manufacturer \"%s\"\n", d
->manufacturer
->value
);
3490 if (d
->model_name
->value
)
3491 quotef(fp
, " ModelName \"%s\"\n", d
->model_name
->value
);
3492 if (d
->file_name
&& d
->file_name
->value
)
3493 quotef(fp
, " FileName \"%s\"\n", d
->file_name
->value
);
3494 if (d
->pc_file_name
&& d
->pc_file_name
->value
)
3495 quotef(fp
, " PCFileName \"%s\"\n", d
->pc_file_name
->value
);
3496 if (d
->version
&& d
->version
->value
)
3497 quotef(fp
, " Version \"%s\"\n", d
->version
->value
);
3499 cupsFilePrintf(fp
, " DriverType %s\n", driver_types
[d
->type
]);
3501 if (d
->model_number
)
3505 case PPDC_DRIVER_LABEL
:
3506 cupsFilePuts(fp
, " ModelNumber ");
3508 switch (d
->model_number
)
3511 cupsFilePuts(fp
, "$DYMO_3x0\n");
3514 case ZEBRA_EPL_LINE
:
3515 cupsFilePuts(fp
, "$ZEBRA_EPL_LINE\n");
3518 case ZEBRA_EPL_PAGE
:
3519 cupsFilePuts(fp
, "$ZEBRA_EPL_PAGE\n");
3523 cupsFilePuts(fp
, "$ZEBRA_ZPL\n");
3527 cupsFilePuts(fp
, "$ZEBRA_CPCL\n");
3530 case INTELLITECH_PCL
:
3531 cupsFilePuts(fp
, "$INTELLITECH_PCL\n");
3535 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3540 case PPDC_DRIVER_EPSON
:
3541 cupsFilePuts(fp
, " ModelNumber ");
3543 switch (d
->model_number
)
3546 cupsFilePuts(fp
, "$EPSON_9PIN\n");
3550 cupsFilePuts(fp
, "$EPSON_24PIN\n");
3554 cupsFilePuts(fp
, "$EPSON_COLOR\n");
3558 cupsFilePuts(fp
, "$EPSON_PHOTO\n");
3562 cupsFilePuts(fp
, "$EPSON_ICOLOR\n");
3566 cupsFilePuts(fp
, "$EPSON_IPHOTO\n");
3570 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3575 case PPDC_DRIVER_HP
:
3576 cupsFilePuts(fp
, " ModelNumber ");
3577 switch (d
->model_number
)
3580 cupsFilePuts(fp
, "$HP_LASERJET\n");
3584 cupsFilePuts(fp
, "$HP_DESKJET\n");
3588 cupsFilePuts(fp
, "$HP_DESKJET2\n");
3592 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3596 cupsFilePuts(fp
, ")\n");
3600 cupsFilePrintf(fp
, " ModelNumber %d\n", d
->model_number
);
3605 if (d
->manual_copies
)
3606 cupsFilePuts(fp
, " ManualCopies Yes\n");
3608 if (d
->color_device
)
3609 cupsFilePuts(fp
, " ColorDevice Yes\n");
3612 cupsFilePrintf(fp
, " Throughput %d\n", d
->throughput
);
3614 // Output all of the attributes...
3615 for (a
= (ppdcAttr
*)d
->attrs
->first();
3617 a
= (ppdcAttr
*)d
->attrs
->next())
3618 if (a
->text
->value
&& a
->text
->value
[0])
3619 quotef(fp
, " Attribute \"%s\" \"%s/%s\" \"%s\"\n",
3620 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3621 a
->text
->value
, a
->value
->value
? a
->value
->value
: "");
3623 quotef(fp
, " Attribute \"%s\" \"%s\" \"%s\"\n",
3624 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3625 a
->value
->value
? a
->value
->value
: "");
3627 // Output all of the constraints...
3628 for (co
= (ppdcConstraint
*)d
->constraints
->first();
3630 co
= (ppdcConstraint
*)d
->constraints
->next())
3632 if (co
->option1
->value
[0] == '*')
3633 cupsFilePrintf(fp
, " UIConstraints \"%s %s", co
->option1
->value
,
3634 co
->choice1
->value
? co
->choice1
->value
: "");
3636 cupsFilePrintf(fp
, " UIConstraints \"*%s %s", co
->option1
->value
,
3637 co
->choice1
->value
? co
->choice1
->value
: "");
3639 if (co
->option2
->value
[0] == '*')
3640 cupsFilePrintf(fp
, " %s %s\"\n", co
->option2
->value
,
3641 co
->choice2
->value
? co
->choice2
->value
: "");
3643 cupsFilePrintf(fp
, " *%s %s\"\n", co
->option2
->value
,
3644 co
->choice2
->value
? co
->choice2
->value
: "");
3647 // Output all of the filters...
3648 for (fi
= (ppdcFilter
*)d
->filters
->first();
3650 fi
= (ppdcFilter
*)d
->filters
->next())
3651 cupsFilePrintf(fp
, " Filter \"%s %d %s\"\n",
3652 fi
->mime_type
->value
, fi
->cost
, fi
->program
->value
);
3654 // Output all of the fonts...
3655 for (fo
= (ppdcFont
*)d
->fonts
->first();
3657 fo
= (ppdcFont
*)d
->fonts
->next())
3658 if (!strcmp(fo
->name
->value
, "*"))
3659 cupsFilePuts(fp
, " Font *\n");
3661 cupsFilePrintf(fp
, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
3662 fo
->name
->value
, fo
->encoding
->value
,
3663 fo
->version
->value
, fo
->charset
->value
,
3664 fo
->status
== PPDC_FONT_ROM
? "ROM" : "Disk");
3666 // Output all options...
3667 for (g
= (ppdcGroup
*)d
->groups
->first();
3669 g
= (ppdcGroup
*)d
->groups
->next())
3671 if (g
->options
->count
== 0)
3674 if (g
->text
->value
&& g
->text
->value
[0])
3675 quotef(fp
, " Group \"%s/%s\"\n", g
->name
->value
, g
->text
->value
);
3677 cupsFilePrintf(fp
, " Group \"%s\"\n", g
->name
->value
);
3679 for (o
= (ppdcOption
*)g
->options
->first();
3681 o
= (ppdcOption
*)g
->options
->next())
3683 if (o
->choices
->count
== 0)
3686 if (o
->text
->value
&& o
->text
->value
[0])
3687 quotef(fp
, " Option \"%s/%s\"", o
->name
->value
, o
->text
->value
);
3689 cupsFilePrintf(fp
, " Option \"%s\"", o
->name
->value
);
3691 cupsFilePrintf(fp
, " %s %s %.1f\n",
3692 o
->type
== PPDC_BOOLEAN
? "Boolean" :
3693 o
->type
== PPDC_PICKONE
? "PickOne" : "PickMany",
3694 o
->section
== PPDC_SECTION_ANY
? "AnySetup" :
3695 o
->section
== PPDC_SECTION_DOCUMENT
? "DocumentSetup" :
3696 o
->section
== PPDC_SECTION_EXIT
? "ExitServer" :
3697 o
->section
== PPDC_SECTION_JCL
? "JCLSetup" :
3698 o
->section
== PPDC_SECTION_PAGE
? "PageSetup" :
3702 for (ch
= (ppdcChoice
*)o
->choices
->first();
3704 ch
= (ppdcChoice
*)o
->choices
->next())
3706 if (ch
->text
->value
&& ch
->text
->value
[0])
3707 quotef(fp
, " %sChoice \"%s/%s\" \"%s\"\n",
3708 o
->defchoice
== ch
->name
? "*" : "",
3709 ch
->name
->value
, ch
->text
->value
,
3710 ch
->code
->value
? ch
->code
->value
: "");
3712 quotef(fp
, " %sChoice \"%s\" \"%s\"\n",
3713 o
->defchoice
== ch
->name
? "*" : "",
3715 ch
->code
->value
? ch
->code
->value
: "");
3720 // Output all of the color profiles...
3721 for (p
= (ppdcProfile
*)d
->profiles
->first();
3723 p
= (ppdcProfile
*)d
->profiles
->next())
3724 cupsFilePrintf(fp
, " ColorProfile \"%s/%s\" %.3f %.3f "
3725 "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
3726 p
->resolution
->value
, p
->media_type
->value
,
3727 p
->density
, p
->gamma
,
3728 p
->profile
[0], p
->profile
[1], p
->profile
[2],
3729 p
->profile
[3], p
->profile
[4], p
->profile
[5],
3730 p
->profile
[6], p
->profile
[7], p
->profile
[8]);
3732 // Output all of the media sizes...
3738 for (si
= (ppdcMediaSize
*)d
->sizes
->first();
3740 si
= (ppdcMediaSize
*)d
->sizes
->next())
3741 if (si
->size_code
->value
&& si
->region_code
->value
)
3743 // Output a custom media size...
3744 quotef(fp
, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
3745 si
->name
== d
->default_size
? "*" : "", si
->name
->value
,
3746 si
->text
->value
, si
->width
, si
->length
, si
->left
, si
->bottom
,
3747 si
->right
, si
->top
, si
->size_code
->value
,
3748 si
->region_code
->value
);
3752 // Output a standard media size...
3753 if (fabs(left
- si
->left
) > 0.1 ||
3754 fabs(bottom
- si
->bottom
) > 0.1 ||
3755 fabs(right
- si
->right
) > 0.1 ||
3756 fabs(top
- si
->top
) > 0.1)
3758 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3759 si
->left
, si
->bottom
, si
->right
, si
->top
);
3762 bottom
= si
->bottom
;
3767 cupsFilePrintf(fp
, " %sMediaSize %s\n",
3768 si
->name
== d
->default_size
? "*" : "",
3772 if (d
->variable_paper_size
)
3774 cupsFilePuts(fp
, " VariablePaperSize Yes\n");
3776 if (fabs(left
- d
->left_margin
) > 0.1 ||
3777 fabs(bottom
- d
->bottom_margin
) > 0.1 ||
3778 fabs(right
- d
->right_margin
) > 0.1 ||
3779 fabs(top
- d
->top_margin
) > 0.1)
3781 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3782 d
->left_margin
, d
->bottom_margin
, d
->right_margin
,
3786 cupsFilePrintf(fp
, " MinSize %.2f %.2f\n", d
->min_width
, d
->min_length
);
3787 cupsFilePrintf(fp
, " MaxSize %.2f %.2f\n", d
->max_width
, d
->max_length
);
3790 // End the driver...
3791 cupsFilePuts(fp
, "}\n");
3794 // Close the file and return...