]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-source.cxx
4 // Source class for the CUPS PPD Compiler.
6 // Copyright 2007-2014 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 // Include necessary headers...
20 #include "ppdc-private.h"
24 #include <cups/raster.h>
25 #include "data/epson.h"
27 #include "data/label.h"
29 # include <sys/utsname.h>
37 ppdcArray
*ppdcSource::includes
= 0;
38 const char *ppdcSource::driver_types
[] =
51 // 'ppdcSource::ppdcSource()' - Load a driver source file.
54 ppdcSource::ppdcSource(const char *f
, // I - File to read
55 cups_file_t
*ffp
)// I - File pointer to use
60 filename
= new ppdcString(f
);
61 base_fonts
= new ppdcArray();
62 drivers
= new ppdcArray();
63 po_files
= new ppdcArray();
64 sizes
= new ppdcArray();
65 vars
= new ppdcArray();
66 cond_state
= PPDC_COND_NORMAL
;
67 cond_current
= cond_stack
;
68 cond_stack
[0] = PPDC_COND_NORMAL
;
70 // Add standard #define variables...
71 #define MAKE_STRING(x) #x
73 vars
->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION
)));
74 vars
->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR
)));
75 vars
->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR
)));
76 vars
->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH
)));
79 vars
->add(new ppdcVariable("PLATFORM_NAME", "Windows"));
80 vars
->add(new ppdcVariable("PLATFORM_ARCH", "X86"));
83 struct utsname name
; // uname information
87 vars
->add(new ppdcVariable("PLATFORM_NAME", name
.sysname
));
88 vars
->add(new ppdcVariable("PLATFORM_ARCH", name
.machine
));
92 vars
->add(new ppdcVariable("PLATFORM_NAME", "unknown"));
93 vars
->add(new ppdcVariable("PLATFORM_ARCH", "unknown"));
103 // 'ppdcSource::~ppdcSource()' - Free a driver source file.
106 ppdcSource::~ppdcSource()
111 base_fonts
->release();
120 // 'ppdcSource::add_include()' - Add an include directory.
124 ppdcSource::add_include(const char *d
) // I - Include directory
130 includes
= new ppdcArray();
132 includes
->add(new ppdcString(d
));
137 // 'ppdcSource::find_driver()' - Find a driver.
140 ppdcDriver
* // O - Driver
141 ppdcSource::find_driver(const char *f
) // I - Driver file name
143 ppdcDriver
*d
; // Current driver
146 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
147 if (!_cups_strcasecmp(f
, d
->pc_file_name
->value
))
155 // 'ppdcSource::find_include()' - Find an include file.
158 char * // O - Found path or NULL
159 ppdcSource::find_include(
160 const char *f
, // I - Include filename
161 const char *base
, // I - Current directory
162 char *n
, // I - Path buffer
163 int nlen
) // I - Path buffer length
165 ppdcString
*dir
; // Include directory
166 char temp
[1024], // Temporary path
167 *ptr
; // Pointer to end of path
170 // Range check input...
171 if (!f
|| !*f
|| !n
|| nlen
< 2)
174 // Check the first character to see if we have <name> or "name"...
177 // Remove the surrounding <> from the name...
178 strlcpy(temp
, f
+ 1, sizeof(temp
));
179 ptr
= temp
+ strlen(temp
) - 1;
183 _cupsLangPrintf(stderr
,
184 _("ppdc: Invalid #include/#po filename \"%s\"."), n
);
193 // Check for the local file relative to the current directory...
194 if (base
&& *base
&& f
[0] != '/')
195 snprintf(n
, (size_t)nlen
, "%s/%s", base
, f
);
197 strlcpy(n
, f
, (size_t)nlen
);
203 // Absolute path that doesn't exist...
208 // Search the include directories, if any...
211 for (dir
= (ppdcString
*)includes
->first(); dir
; dir
= (ppdcString
*)includes
->next())
213 snprintf(n
, (size_t)nlen
, "%s/%s", dir
->value
, f
);
219 // Search the standard include directories...
220 _cups_globals_t
*cg
= _cupsGlobals(); // Global data
222 snprintf(n
, (size_t)nlen
, "%s/ppdc/%s", cg
->cups_datadir
, f
);
226 snprintf(n
, (size_t)nlen
, "%s/po/%s", cg
->cups_datadir
, f
);
235 // 'ppdcSource::find_po()' - Find a message catalog for the given locale.
238 ppdcCatalog
* // O - Message catalog or NULL
239 ppdcSource::find_po(const char *l
) // I - Locale name
241 ppdcCatalog
*cat
; // Current message catalog
244 for (cat
= (ppdcCatalog
*)po_files
->first();
246 cat
= (ppdcCatalog
*)po_files
->next())
247 if (!_cups_strcasecmp(l
, cat
->locale
->value
))
255 // 'ppdcSource::find_size()' - Find a media size.
258 ppdcMediaSize
* // O - Size
259 ppdcSource::find_size(const char *s
) // I - Size name
261 ppdcMediaSize
*m
; // Current media size
264 for (m
= (ppdcMediaSize
*)sizes
->first(); m
; m
= (ppdcMediaSize
*)sizes
->next())
265 if (!_cups_strcasecmp(s
, m
->name
->value
))
273 // 'ppdcSource::find_variable()' - Find a variable.
276 ppdcVariable
* // O - Variable
277 ppdcSource::find_variable(const char *n
)// I - Variable name
279 ppdcVariable
*v
; // Current variable
282 for (v
= (ppdcVariable
*)vars
->first(); v
; v
= (ppdcVariable
*)vars
->next())
283 if (!_cups_strcasecmp(n
, v
->name
->value
))
291 // 'ppdcSource::get_attr()' - Get an attribute.
294 ppdcAttr
* // O - Attribute
295 ppdcSource::get_attr(ppdcFile
*fp
, // I - File to read
296 bool loc
) // I - Localize this attribute?
298 char name
[1024], // Name string
299 selector
[1024], // Selector string
300 *text
, // Text string
301 value
[1024]; // Value string
304 // Get the attribute parameters:
306 // Attribute name selector value
307 if (!get_token(fp
, name
, sizeof(name
)))
309 _cupsLangPrintf(stderr
,
310 _("ppdc: Expected name after %s on line %d of %s."),
311 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
315 if (!get_token(fp
, selector
, sizeof(selector
)))
317 _cupsLangPrintf(stderr
,
318 _("ppdc: Expected selector after %s on line %d of %s."),
319 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
323 if ((text
= strchr(selector
, '/')) != NULL
)
326 if (!get_token(fp
, value
, sizeof(value
)))
328 _cupsLangPrintf(stderr
,
329 _("ppdc: Expected value after %s on line %d of %s."),
330 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
334 return (new ppdcAttr(name
, selector
, text
, value
, loc
));
339 // 'ppdcSource::get_boolean()' - Get a boolean value.
342 int // O - Boolean value
343 ppdcSource::get_boolean(ppdcFile
*fp
) // I - File to read
345 char buffer
[256]; // String buffer
348 if (!get_token(fp
, buffer
, sizeof(buffer
)))
350 _cupsLangPrintf(stderr
,
351 _("ppdc: Expected boolean value on line %d of %s."),
352 fp
->line
, fp
->filename
);
356 if (!_cups_strcasecmp(buffer
, "on") ||
357 !_cups_strcasecmp(buffer
, "yes") ||
358 !_cups_strcasecmp(buffer
, "true"))
360 else if (!_cups_strcasecmp(buffer
, "off") ||
361 !_cups_strcasecmp(buffer
, "no") ||
362 !_cups_strcasecmp(buffer
, "false"))
366 _cupsLangPrintf(stderr
,
367 _("ppdc: Bad boolean value (%s) on line %d of %s."),
368 buffer
, fp
->line
, fp
->filename
);
375 // 'ppdcSource::get_choice()' - Get a choice.
378 ppdcChoice
* // O - Choice data
379 ppdcSource::get_choice(ppdcFile
*fp
) // I - File to read
381 char name
[1024], // Name
386 // Read a choice from the file:
388 // Choice name/text code
389 if (!get_token(fp
, name
, sizeof(name
)))
391 _cupsLangPrintf(stderr
,
392 _("ppdc: Expected choice name/text on line %d of %s."),
393 fp
->line
, fp
->filename
);
397 if ((text
= strchr(name
, '/')) != NULL
)
402 if (!get_token(fp
, code
, sizeof(code
)))
404 _cupsLangPrintf(stderr
, _("ppdc: Expected choice code on line %d of %s."),
405 fp
->line
, fp
->filename
);
409 // Return the new choice
410 return (new ppdcChoice(name
, text
, code
));
415 // 'ppdcSource::get_color_model()' - Get an old-style color model option.
418 ppdcChoice
* // O - Choice data
419 ppdcSource::get_color_model(ppdcFile
*fp
)
422 char name
[1024], // Option name
423 *text
, // Text option
424 temp
[256]; // Temporary string
425 int color_space
, // Colorspace
426 color_order
, // Color order
427 compression
; // Compression mode
430 // Get the ColorModel parameters:
432 // ColorModel name/text colorspace colororder compression
433 if (!get_token(fp
, name
, sizeof(name
)))
435 _cupsLangPrintf(stderr
,
436 _("ppdc: Expected name/text combination for ColorModel on "
437 "line %d of %s."), fp
->line
, fp
->filename
);
441 if ((text
= strchr(name
, '/')) != NULL
)
446 if (!get_token(fp
, temp
, sizeof(temp
)))
448 _cupsLangPrintf(stderr
,
449 _("ppdc: Expected colorspace for ColorModel on line %d of "
450 "%s."), fp
->line
, fp
->filename
);
454 if ((color_space
= get_color_space(temp
)) < 0)
455 color_space
= get_integer(temp
);
457 if (!get_token(fp
, temp
, sizeof(temp
)))
459 _cupsLangPrintf(stderr
,
460 _("ppdc: Expected color order for ColorModel on line %d of "
461 "%s."), fp
->line
, fp
->filename
);
465 if ((color_order
= get_color_order(temp
)) < 0)
466 color_order
= get_integer(temp
);
468 if (!get_token(fp
, temp
, sizeof(temp
)))
470 _cupsLangPrintf(stderr
,
471 _("ppdc: Expected compression for ColorModel on line %d of "
472 "%s."), fp
->line
, fp
->filename
);
476 compression
= get_integer(temp
);
478 snprintf(temp
, sizeof(temp
),
479 "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
481 color_space
, color_order
, compression
);
483 return (new ppdcChoice(name
, text
, temp
));
488 // 'ppdcSource::get_color_order()' - Get an old-style color order value.
491 int // O - Color order value
492 ppdcSource::get_color_order(
493 const char *co
) // I - Color order string
495 if (!_cups_strcasecmp(co
, "chunked") ||
496 !_cups_strcasecmp(co
, "chunky"))
497 return (CUPS_ORDER_CHUNKED
);
498 else if (!_cups_strcasecmp(co
, "banded"))
499 return (CUPS_ORDER_BANDED
);
500 else if (!_cups_strcasecmp(co
, "planar"))
501 return (CUPS_ORDER_PLANAR
);
508 // 'ppdcSource::get_color_profile()' - Get a color profile definition.
511 ppdcProfile
* // O - Color profile
512 ppdcSource::get_color_profile(
513 ppdcFile
*fp
) // I - File to read
515 char resolution
[1024], // Resolution/media type
516 *media_type
; // Media type
517 int i
; // Looping var
518 float g
, // Gamma value
520 m
[9]; // Transform matrix
523 // Get the ColorProfile parameters:
525 // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
526 if (!get_token(fp
, resolution
, sizeof(resolution
)))
528 _cupsLangPrintf(stderr
,
529 _("ppdc: Expected resolution/mediatype following "
530 "ColorProfile on line %d of %s."),
531 fp
->line
, fp
->filename
);
535 if ((media_type
= strchr(resolution
, '/')) != NULL
)
536 *media_type
++ = '\0';
538 media_type
= resolution
;
542 for (i
= 0; i
< 9; i
++)
543 m
[i
] = get_float(fp
);
545 return (new ppdcProfile(resolution
, media_type
, g
, d
, m
));
550 // 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
553 int // O - Colorspace value
554 ppdcSource::get_color_space(
555 const char *cs
) // I - Colorspace string
557 if (!_cups_strcasecmp(cs
, "w"))
558 return (CUPS_CSPACE_W
);
559 else if (!_cups_strcasecmp(cs
, "rgb"))
560 return (CUPS_CSPACE_RGB
);
561 else if (!_cups_strcasecmp(cs
, "rgba"))
562 return (CUPS_CSPACE_RGBA
);
563 else if (!_cups_strcasecmp(cs
, "k"))
564 return (CUPS_CSPACE_K
);
565 else if (!_cups_strcasecmp(cs
, "cmy"))
566 return (CUPS_CSPACE_CMY
);
567 else if (!_cups_strcasecmp(cs
, "ymc"))
568 return (CUPS_CSPACE_YMC
);
569 else if (!_cups_strcasecmp(cs
, "cmyk"))
570 return (CUPS_CSPACE_CMYK
);
571 else if (!_cups_strcasecmp(cs
, "ymck"))
572 return (CUPS_CSPACE_YMCK
);
573 else if (!_cups_strcasecmp(cs
, "kcmy"))
574 return (CUPS_CSPACE_KCMY
);
575 else if (!_cups_strcasecmp(cs
, "kcmycm"))
576 return (CUPS_CSPACE_KCMYcm
);
577 else if (!_cups_strcasecmp(cs
, "gmck"))
578 return (CUPS_CSPACE_GMCK
);
579 else if (!_cups_strcasecmp(cs
, "gmcs"))
580 return (CUPS_CSPACE_GMCS
);
581 else if (!_cups_strcasecmp(cs
, "white"))
582 return (CUPS_CSPACE_WHITE
);
583 else if (!_cups_strcasecmp(cs
, "gold"))
584 return (CUPS_CSPACE_GOLD
);
585 else if (!_cups_strcasecmp(cs
, "silver"))
586 return (CUPS_CSPACE_SILVER
);
587 else if (!_cups_strcasecmp(cs
, "CIEXYZ"))
588 return (CUPS_CSPACE_CIEXYZ
);
589 else if (!_cups_strcasecmp(cs
, "CIELab"))
590 return (CUPS_CSPACE_CIELab
);
591 else if (!_cups_strcasecmp(cs
, "RGBW"))
592 return (CUPS_CSPACE_RGBW
);
593 else if (!_cups_strcasecmp(cs
, "ICC1"))
594 return (CUPS_CSPACE_ICC1
);
595 else if (!_cups_strcasecmp(cs
, "ICC2"))
596 return (CUPS_CSPACE_ICC2
);
597 else if (!_cups_strcasecmp(cs
, "ICC3"))
598 return (CUPS_CSPACE_ICC3
);
599 else if (!_cups_strcasecmp(cs
, "ICC4"))
600 return (CUPS_CSPACE_ICC4
);
601 else if (!_cups_strcasecmp(cs
, "ICC5"))
602 return (CUPS_CSPACE_ICC5
);
603 else if (!_cups_strcasecmp(cs
, "ICC6"))
604 return (CUPS_CSPACE_ICC6
);
605 else if (!_cups_strcasecmp(cs
, "ICC7"))
606 return (CUPS_CSPACE_ICC7
);
607 else if (!_cups_strcasecmp(cs
, "ICC8"))
608 return (CUPS_CSPACE_ICC8
);
609 else if (!_cups_strcasecmp(cs
, "ICC9"))
610 return (CUPS_CSPACE_ICC9
);
611 else if (!_cups_strcasecmp(cs
, "ICCA"))
612 return (CUPS_CSPACE_ICCA
);
613 else if (!_cups_strcasecmp(cs
, "ICCB"))
614 return (CUPS_CSPACE_ICCB
);
615 else if (!_cups_strcasecmp(cs
, "ICCC"))
616 return (CUPS_CSPACE_ICCC
);
617 else if (!_cups_strcasecmp(cs
, "ICCD"))
618 return (CUPS_CSPACE_ICCD
);
619 else if (!_cups_strcasecmp(cs
, "ICCE"))
620 return (CUPS_CSPACE_ICCE
);
621 else if (!_cups_strcasecmp(cs
, "ICCF"))
622 return (CUPS_CSPACE_ICCF
);
629 // 'ppdcSource::get_constraint()' - Get a constraint.
632 ppdcConstraint
* // O - Constraint
633 ppdcSource::get_constraint(ppdcFile
*fp
)// I - File to read
635 char temp
[1024], // One string to rule them all
636 *ptr
, // Pointer into string
637 *option1
, // Constraint option 1
638 *choice1
, // Constraint choice 1
639 *option2
, // Constraint option 2
640 *choice2
; // Constraint choice 2
643 // Read the UIConstaints parameter in one of the following forms:
645 // UIConstraints "*Option1 *Option2"
646 // UIConstraints "*Option1 Choice1 *Option2"
647 // UIConstraints "*Option1 *Option2 Choice2"
648 // UIConstraints "*Option1 Choice1 *Option2 Choice2"
649 if (!get_token(fp
, temp
, sizeof(temp
)))
651 _cupsLangPrintf(stderr
,
652 _("ppdc: Expected constraints string for UIConstraints on "
653 "line %d of %s."), fp
->line
, fp
->filename
);
657 for (ptr
= temp
; isspace(*ptr
); ptr
++);
661 _cupsLangPrintf(stderr
,
662 _("ppdc: Option constraint must *name on line %d of %s."),
663 fp
->line
, fp
->filename
);
669 for (; *ptr
&& !isspace(*ptr
); ptr
++);
670 for (; isspace(*ptr
); *ptr
++ = '\0');
676 for (; *ptr
&& !isspace(*ptr
); ptr
++);
677 for (; isspace(*ptr
); *ptr
++ = '\0');
684 _cupsLangPrintf(stderr
,
685 _("ppdc: Expected two option names on line %d of %s."),
686 fp
->line
, fp
->filename
);
692 for (; *ptr
&& !isspace(*ptr
); ptr
++);
693 for (; isspace(*ptr
); *ptr
++ = '\0');
700 return (new ppdcConstraint(option1
, choice1
, option2
, choice2
));
705 // 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
708 ppdcMediaSize
* // O - Media size
709 ppdcSource::get_custom_size(ppdcFile
*fp
)
712 char name
[1024], // Name
714 size_code
[10240], // PageSize code
715 region_code
[10240]; // PageRegion
716 float width
, // Width
719 bottom
, // Bottom margin
720 right
, // Right margin
724 // Get the name, text, width, length, margins, and code:
726 // CustomMedia name/text width length left bottom right top size-code region-code
727 if (!get_token(fp
, name
, sizeof(name
)))
730 if ((text
= strchr(name
, '/')) != NULL
)
735 if ((width
= get_measurement(fp
)) < 0.0f
)
738 if ((length
= get_measurement(fp
)) < 0.0f
)
741 if ((left
= get_measurement(fp
)) < 0.0f
)
744 if ((bottom
= get_measurement(fp
)) < 0.0f
)
747 if ((right
= get_measurement(fp
)) < 0.0f
)
750 if ((top
= get_measurement(fp
)) < 0.0f
)
753 if (!get_token(fp
, size_code
, sizeof(size_code
)))
756 if (!get_token(fp
, region_code
, sizeof(region_code
)))
759 // Return the new media size...
760 return (new ppdcMediaSize(name
, text
, width
, length
, left
, bottom
,
761 right
, top
, size_code
, region_code
));
766 // 'ppdcSource::get_duplex()' - Get a duplex option.
770 ppdcSource::get_duplex(ppdcFile
*fp
, // I - File to read from
771 ppdcDriver
*d
) // I - Current driver
773 char temp
[256]; // Duplex keyword
774 ppdcAttr
*attr
; // cupsFlipDuplex attribute
775 ppdcGroup
*g
; // Current group
776 ppdcOption
*o
; // Duplex option
779 // Duplex {boolean|none|normal|flip}
780 if (!get_token(fp
, temp
, sizeof(temp
)))
782 _cupsLangPrintf(stderr
,
783 _("ppdc: Expected duplex type after Duplex on line %d of "
784 "%s."), fp
->line
, fp
->filename
);
791 if (!_cups_strcasecmp(temp
, "none") || !_cups_strcasecmp(temp
, "false") ||
792 !_cups_strcasecmp(temp
, "no") || !_cups_strcasecmp(temp
, "off"))
794 g
= d
->find_group("General");
795 if ((o
= g
->find_option("Duplex")) != NULL
)
796 g
->options
->remove(o
);
798 for (attr
= (ppdcAttr
*)d
->attrs
->first();
800 attr
= (ppdcAttr
*)d
->attrs
->next())
801 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
803 d
->attrs
->remove(attr
);
807 else if (!_cups_strcasecmp(temp
, "normal") || !_cups_strcasecmp(temp
, "true") ||
808 !_cups_strcasecmp(temp
, "yes") || !_cups_strcasecmp(temp
, "on") ||
809 !_cups_strcasecmp(temp
, "flip") || !_cups_strcasecmp(temp
, "rotated") ||
810 !_cups_strcasecmp(temp
, "manualtumble"))
812 g
= d
->find_group("General");
813 o
= g
->find_option("Duplex");
817 o
= new ppdcOption(PPDC_PICKONE
, "Duplex", "2-Sided Printing",
818 !_cups_strcasecmp(temp
, "flip") ? PPDC_SECTION_PAGE
:
819 PPDC_SECTION_ANY
, 10.0f
);
820 o
->add_choice(new ppdcChoice("None", "Off (1-Sided)",
821 "<</Duplex false>>setpagedevice"));
822 o
->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
823 "<</Duplex true/Tumble false>>setpagedevice"));
824 o
->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
825 "<</Duplex true/Tumble true>>setpagedevice"));
830 for (attr
= (ppdcAttr
*)d
->attrs
->first();
832 attr
= (ppdcAttr
*)d
->attrs
->next())
833 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
835 if (_cups_strcasecmp(temp
, "flip"))
836 d
->attrs
->remove(attr
);
840 if (!_cups_strcasecmp(temp
, "flip") && !attr
)
841 d
->add_attr(new ppdcAttr("cupsFlipDuplex", NULL
, NULL
, "true"));
843 for (attr
= (ppdcAttr
*)d
->attrs
->first();
845 attr
= (ppdcAttr
*)d
->attrs
->next())
846 if (!strcmp(attr
->name
->value
, "cupsBackSide"))
848 d
->attrs
->remove(attr
);
852 if (!_cups_strcasecmp(temp
, "flip"))
853 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Flipped"));
854 else if (!_cups_strcasecmp(temp
, "rotated"))
855 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Rotated"));
856 else if (!_cups_strcasecmp(temp
, "manualtumble"))
857 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "ManualTumble"));
859 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Normal"));
862 _cupsLangPrintf(stderr
,
863 _("ppdc: Unknown duplex type \"%s\" on line %d of %s."),
864 temp
, fp
->line
, fp
->filename
);
869 // 'ppdcSource::get_filter()' - Get a filter.
872 ppdcFilter
* // O - Filter
873 ppdcSource::get_filter(ppdcFile
*fp
) // I - File to read
875 char type
[1024], // MIME type
876 program
[1024], // Filter program
877 *ptr
; // Pointer into MIME type
878 int cost
; // Relative cost
881 // Read filter parameters in one of the following formats:
883 // Filter "type cost program"
884 // Filter type cost program
886 if (!get_token(fp
, type
, sizeof(type
)))
888 _cupsLangPrintf(stderr
,
889 _("ppdc: Expected a filter definition on line %d of %s."),
890 fp
->line
, fp
->filename
);
894 if ((ptr
= strchr(type
, ' ')) != NULL
)
896 // Old-style filter definition in one string...
898 cost
= strtol(ptr
, &ptr
, 10);
900 while (isspace(*ptr
))
903 strlcpy(program
, ptr
, sizeof(program
));
907 cost
= get_integer(fp
);
909 if (!get_token(fp
, program
, sizeof(program
)))
911 _cupsLangPrintf(stderr
,
912 _("ppdc: Expected a program name on line %d of %s."),
913 fp
->line
, fp
->filename
);
920 _cupsLangPrintf(stderr
,
921 _("ppdc: Invalid empty MIME type for filter on line %d of "
922 "%s."), fp
->line
, fp
->filename
);
926 if (cost
< 0 || cost
> 200)
928 _cupsLangPrintf(stderr
,
929 _("ppdc: Invalid cost for filter on line %d of %s."),
930 fp
->line
, fp
->filename
);
936 _cupsLangPrintf(stderr
,
937 _("ppdc: Invalid empty program name for filter on line %d "
938 "of %s."), fp
->line
, fp
->filename
);
942 return (new ppdcFilter(type
, program
, cost
));
947 // 'ppdcSource::get_float()' - Get a single floating-point number.
951 ppdcSource::get_float(ppdcFile
*fp
) // I - File to read
953 char temp
[256], // String buffer
954 *ptr
; // Pointer into buffer
955 float val
; // Floating point value
958 // Get the number from the file and range-check...
959 if (!get_token(fp
, temp
, sizeof(temp
)))
961 _cupsLangPrintf(stderr
, _("ppdc: Expected real number on line %d of %s."),
962 fp
->line
, fp
->filename
);
966 val
= (float)strtod(temp
, &ptr
);
970 _cupsLangPrintf(stderr
,
971 _("ppdc: Unknown trailing characters in real number \"%s\" "
972 "on line %d of %s."), temp
, fp
->line
, fp
->filename
);
981 // 'ppdcSource::get_font()' - Get a font definition.
984 ppdcFont
* // O - Font data
985 ppdcSource::get_font(ppdcFile
*fp
) // I - File to read
987 char name
[256], // Font name
988 encoding
[256], // Font encoding
989 version
[256], // Font version
990 charset
[256], // Font charset
991 temp
[256]; // Font status string
992 ppdcFontStatus status
; // Font status enumeration
995 // Read font parameters as follows:
998 // Font name encoding version charset status
999 // %font name encoding version charset status
1001 // "Name" is the PostScript font name.
1003 // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
1004 // Special, Expert, ExpertSubset, etc.
1006 // "Version" is the version number string.
1008 // "Charset" specifies the characters that are included in the font:
1009 // Standard, Special, Expert, Adobe-Identity, etc.
1011 // "Status" is the keyword ROM or Disk.
1012 if (!get_token(fp
, name
, sizeof(name
)))
1014 _cupsLangPrintf(stderr
,
1015 _("ppdc: Expected name after Font on line %d of %s."),
1016 fp
->line
, fp
->filename
);
1020 if (!strcmp(name
, "*"))
1022 // Include all base fonts...
1026 status
= PPDC_FONT_ROM
;
1030 // Load a full font definition...
1031 if (!get_token(fp
, encoding
, sizeof(encoding
)))
1033 _cupsLangPrintf(stderr
,
1034 _("ppdc: Expected encoding after Font on line %d of "
1035 "%s."), fp
->line
, fp
->filename
);
1039 if (!get_token(fp
, version
, sizeof(version
)))
1041 _cupsLangPrintf(stderr
,
1042 _("ppdc: Expected version after Font on line %d of "
1043 "%s."), fp
->line
, fp
->filename
);
1047 if (!get_token(fp
, charset
, sizeof(charset
)))
1049 _cupsLangPrintf(stderr
,
1050 _("ppdc: Expected charset after Font on line %d of "
1051 "%s."), fp
->line
, fp
->filename
);
1055 if (!get_token(fp
, temp
, sizeof(temp
)))
1057 _cupsLangPrintf(stderr
,
1058 _("ppdc: Expected status after Font on line %d of %s."),
1059 fp
->line
, fp
->filename
);
1063 if (!_cups_strcasecmp(temp
, "ROM"))
1064 status
= PPDC_FONT_ROM
;
1065 else if (!_cups_strcasecmp(temp
, "Disk"))
1066 status
= PPDC_FONT_DISK
;
1069 _cupsLangPrintf(stderr
,
1070 _("ppdc: Bad status keyword %s on line %d of %s."),
1071 temp
, fp
->line
, fp
->filename
);
1076 // printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
1078 return (new ppdcFont(name
, encoding
, version
, charset
, status
));
1083 // 'ppdcSource::get_generic()' - Get a generic old-style option.
1086 ppdcChoice
* // O - Choice data
1087 ppdcSource::get_generic(ppdcFile
*fp
, // I - File to read
1088 const char *keyword
,
1091 // I - Text attribute
1093 // I - Numeric attribute
1095 char name
[1024], // Name
1097 command
[256]; // Command string
1098 int val
; // Numeric value
1101 // Read one of the following parameters:
1104 // Foo integer name/text
1106 val
= get_integer(fp
);
1110 if (!get_token(fp
, name
, sizeof(name
)))
1112 _cupsLangPrintf(stderr
,
1113 _("ppdc: Expected name/text after %s on line %d of %s."),
1114 keyword
, fp
->line
, fp
->filename
);
1118 if ((text
= strchr(name
, '/')) != NULL
)
1126 snprintf(command
, sizeof(command
),
1127 "<</%s(%s)/%s %d>>setpagedevice",
1128 tattr
, name
, nattr
, val
);
1130 snprintf(command
, sizeof(command
),
1131 "<</%s %d>>setpagedevice",
1135 snprintf(command
, sizeof(command
),
1136 "<</%s(%s)>>setpagedevice",
1139 return (new ppdcChoice(name
, text
, command
));
1144 // 'ppdcSource::get_group()' - Get an option group.
1147 ppdcGroup
* // O - Group
1148 ppdcSource::get_group(ppdcFile
*fp
, // I - File to read
1149 ppdcDriver
*d
) // I - Printer driver
1151 char name
[1024], // UI name
1153 ppdcGroup
*g
; // Group
1156 // Read the Group parameters:
1159 if (!get_token(fp
, name
, sizeof(name
)))
1161 _cupsLangPrintf(stderr
,
1162 _("ppdc: Expected group name/text on line %d of %s."),
1163 fp
->line
, fp
->filename
);
1167 if ((text
= strchr(name
, '/')) != NULL
)
1172 // See if the group already exists...
1173 if ((g
= d
->find_group(name
)) == NULL
)
1175 // Nope, add a new one...
1176 g
= new ppdcGroup(name
, text
);
1184 // 'ppdcSource::get_installable()' - Get an installable option.
1187 ppdcOption
* // O - Option
1188 ppdcSource::get_installable(ppdcFile
*fp
)
1191 char name
[1024], // Name for installable option
1192 *text
; // Text for installable option
1193 ppdcOption
*o
; // Option
1196 // Read the parameter for an installable option:
1198 // Installable name/text
1199 if (!get_token(fp
, name
, sizeof(name
)))
1201 _cupsLangPrintf(stderr
,
1202 _("ppdc: Expected name/text after Installable on line %d "
1203 "of %s."), fp
->line
, fp
->filename
);
1207 if ((text
= strchr(name
, '/')) != NULL
)
1212 // Create the option...
1213 o
= new ppdcOption(PPDC_BOOLEAN
, name
, text
, PPDC_SECTION_ANY
, 10.0f
);
1215 // Add the false and true choices...
1216 o
->add_choice(new ppdcChoice("False", "Not Installed", ""));
1217 o
->add_choice(new ppdcChoice("True", "Installed", ""));
1224 // 'ppdcSource::get_integer()' - Get an integer value from a string.
1227 #define PPDC_XX -1 // Bad
1228 #define PPDC_EQ 0 // ==
1229 #define PPDC_NE 1 // !=
1230 #define PPDC_LT 2 // <
1231 #define PPDC_LE 3 // <=
1232 #define PPDC_GT 4 // >
1233 #define PPDC_GE 5 // >=
1235 int // O - Integer value
1236 ppdcSource::get_integer(const char *v
) // I - Value string
1239 long temp
, // Temporary value
1240 temp2
; // Second temporary value
1241 char *newv
, // New value string pointer
1242 ch
; // Temporary character
1243 ppdcVariable
*var
; // #define variable
1244 int compop
; // Comparison operator
1247 // Parse the value string...
1251 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1253 // Return a simple integer value
1254 val
= strtol(v
, (char **)&v
, 0);
1255 if (*v
|| val
== LONG_MIN
)
1262 // Evaluate and expression in any of the following formats:
1264 // (number number ... number) Bitwise OR of all numbers
1265 // (NAME == value) 1 if equal, 0 otherwise
1266 // (NAME != value) 1 if not equal, 0 otherwise
1267 // (NAME < value) 1 if less than, 0 otherwise
1268 // (NAME <= value) 1 if less than or equal, 0 otherwise
1269 // (NAME > value) 1 if greater than, 0 otherwise
1270 // (NAME >= value) 1 if greater than or equal, 0 otherwise
1275 while (*v
&& *v
!= ')')
1277 // Skip leading whitespace...
1278 while (*v
&& isspace(*v
& 255))
1281 if (!*v
|| *v
== ')')
1284 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1286 // Bitwise OR a number...
1287 temp
= strtol(v
, &newv
, 0);
1289 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1295 // NAME logicop value
1296 for (newv
= (char *)v
+ 1;
1297 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1304 if ((var
= find_variable(v
)) != NULL
)
1306 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1308 else if (isdigit(var
->value
->value
[0] & 255) ||
1309 var
->value
->value
[0] == '-' ||
1310 var
->value
->value
[0] == '+')
1311 temp
= strtol(var
->value
->value
, NULL
, 0);
1319 while (isspace(*newv
& 255))
1322 if (!strncmp(newv
, "==", 2))
1327 else if (!strncmp(newv
, "!=", 2))
1332 else if (!strncmp(newv
, "<=", 2))
1337 else if (*newv
== '<')
1342 else if (!strncmp(newv
, ">=", 2))
1347 else if (*newv
== '>')
1355 if (compop
!= PPDC_XX
)
1357 while (isspace(*newv
& 255))
1360 if (*newv
== ')' || !*newv
)
1363 if (isdigit(*newv
& 255) || *newv
== '-' || *newv
== '+')
1365 // Get the second number...
1366 temp2
= strtol(newv
, &newv
, 0);
1367 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1373 // Lookup the second name...
1374 for (v
= newv
, newv
++;
1375 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1381 if ((var
= find_variable(v
)) != NULL
)
1383 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1385 else if (isdigit(var
->value
->value
[0] & 255) ||
1386 var
->value
->value
[0] == '-' ||
1387 var
->value
->value
[0] == '+')
1388 temp2
= strtol(var
->value
->value
, NULL
, 0);
1398 // Do the comparison...
1402 temp
= temp
== temp2
;
1405 temp
= temp
!= temp2
;
1408 temp
= temp
< temp2
;
1411 temp
= temp
<= temp2
;
1414 temp
= temp
> temp2
;
1417 temp
= temp
>= temp2
;
1427 if (*v
== ')' && !v
[1])
1432 else if ((var
= find_variable(v
)) != NULL
)
1434 // NAME by itself returns 1 if the #define variable is not blank and
1436 return (var
->value
->value
&& var
->value
->value
[0] &&
1437 strcmp(var
->value
->value
, "0"));
1441 // Anything else is an error...
1448 // 'ppdcSource::get_integer()' - Get an integer value from a file.
1451 int // O - Integer value
1452 ppdcSource::get_integer(ppdcFile
*fp
) // I - File to read
1454 char temp
[1024]; // String buffer
1457 if (!get_token(fp
, temp
, sizeof(temp
)))
1459 _cupsLangPrintf(stderr
, _("ppdc: Expected integer on line %d of %s."),
1460 fp
->line
, fp
->filename
);
1464 return (get_integer(temp
));
1469 // 'ppdcSource::get_measurement()' - Get a measurement value.
1472 float // O - Measurement value in points
1473 ppdcSource::get_measurement(ppdcFile
*fp
)
1476 char buffer
[256], // Number buffer
1477 *ptr
; // Pointer into buffer
1478 float val
; // Measurement value
1481 // Grab a token from the file...
1482 if (!get_token(fp
, buffer
, sizeof(buffer
)))
1485 // Get the floating point value of "s" and skip all digits and decimal points.
1486 val
= (float)strtod(buffer
, &ptr
);
1488 // Check for a trailing unit specifier...
1489 if (!_cups_strcasecmp(ptr
, "mm"))
1490 val
*= 72.0f
/ 25.4f
;
1491 else if (!_cups_strcasecmp(ptr
, "cm"))
1492 val
*= 72.0f
/ 2.54f
;
1493 else if (!_cups_strcasecmp(ptr
, "m"))
1494 val
*= 72.0f
/ 0.0254f
;
1495 else if (!_cups_strcasecmp(ptr
, "in"))
1497 else if (!_cups_strcasecmp(ptr
, "ft"))
1498 val
*= 72.0f
* 12.0f
;
1499 else if (_cups_strcasecmp(ptr
, "pt") && *ptr
)
1507 // 'ppdcSource::get_option()' - Get an option definition.
1510 ppdcOption
* // O - Option
1511 ppdcSource::get_option(ppdcFile
*fp
, // I - File to read
1512 ppdcDriver
*d
, // I - Printer driver
1513 ppdcGroup
*g
) // I - Current group
1515 char name
[1024], // UI name
1517 type
[256]; // UI type string
1518 ppdcOptType ot
; // Option type value
1519 ppdcOptSection section
; // Option section
1520 float order
; // Option order
1521 ppdcOption
*o
; // Option
1522 ppdcGroup
*mg
; // Matching group, if any
1525 // Read the Option parameters:
1527 // Option name/text type section order
1528 if (!get_token(fp
, name
, sizeof(name
)))
1530 _cupsLangPrintf(stderr
,
1531 _("ppdc: Expected option name/text on line %d of %s."),
1532 fp
->line
, fp
->filename
);
1536 if ((text
= strchr(name
, '/')) != NULL
)
1541 if (!get_token(fp
, type
, sizeof(type
)))
1543 _cupsLangPrintf(stderr
, _("ppdc: Expected option type on line %d of %s."),
1544 fp
->line
, fp
->filename
);
1548 if (!_cups_strcasecmp(type
, "boolean"))
1550 else if (!_cups_strcasecmp(type
, "pickone"))
1552 else if (!_cups_strcasecmp(type
, "pickmany"))
1556 _cupsLangPrintf(stderr
,
1557 _("ppdc: Invalid option type \"%s\" on line %d of %s."),
1558 type
, fp
->line
, fp
->filename
);
1562 if (!get_token(fp
, type
, sizeof(type
)))
1564 _cupsLangPrintf(stderr
,
1565 _("ppdc: Expected option section on line %d of %s."),
1566 fp
->line
, fp
->filename
);
1570 if (!_cups_strcasecmp(type
, "AnySetup"))
1571 section
= PPDC_SECTION_ANY
;
1572 else if (!_cups_strcasecmp(type
, "DocumentSetup"))
1573 section
= PPDC_SECTION_DOCUMENT
;
1574 else if (!_cups_strcasecmp(type
, "ExitServer"))
1575 section
= PPDC_SECTION_EXIT
;
1576 else if (!_cups_strcasecmp(type
, "JCLSetup"))
1577 section
= PPDC_SECTION_JCL
;
1578 else if (!_cups_strcasecmp(type
, "PageSetup"))
1579 section
= PPDC_SECTION_PAGE
;
1580 else if (!_cups_strcasecmp(type
, "Prolog"))
1581 section
= PPDC_SECTION_PROLOG
;
1584 _cupsLangPrintf(stderr
,
1585 _("ppdc: Invalid option section \"%s\" on line %d of "
1586 "%s."), type
, fp
->line
, fp
->filename
);
1590 order
= get_float(fp
);
1592 // See if the option already exists...
1593 if ((o
= d
->find_option_group(name
, &mg
)) == NULL
)
1595 // Nope, add a new one...
1596 o
= new ppdcOption(ot
, name
, text
, section
, order
);
1598 else if (o
->type
!= ot
)
1600 _cupsLangPrintf(stderr
,
1601 _("ppdc: Option %s redefined with a different type on line "
1602 "%d of %s."), name
, fp
->line
, fp
->filename
);
1607 _cupsLangPrintf(stderr
,
1608 _("ppdc: Option %s defined in two different groups on line "
1609 "%d of %s."), name
, fp
->line
, fp
->filename
);
1618 // 'ppdcSource::get_po()' - Get a message catalog.
1621 ppdcCatalog
* // O - Message catalog
1622 ppdcSource::get_po(ppdcFile
*fp
) // I - File to read
1624 char locale
[32], // Locale name
1625 poname
[1024], // Message catalog filename
1626 basedir
[1024], // Base directory
1627 *baseptr
, // Pointer into directory
1628 pofilename
[1024]; // Full filename of message catalog
1629 ppdcCatalog
*cat
; // Message catalog
1632 // Read the #po parameters:
1634 // #po locale "filename.po"
1635 if (!get_token(fp
, locale
, sizeof(locale
)))
1637 _cupsLangPrintf(stderr
,
1638 _("ppdc: Expected locale after #po on line %d of %s."),
1639 fp
->line
, fp
->filename
);
1643 if (!get_token(fp
, poname
, sizeof(poname
)))
1645 _cupsLangPrintf(stderr
,
1646 _("ppdc: Expected filename after #po %s on line %d of "
1647 "%s."), locale
, fp
->line
, fp
->filename
);
1651 // See if the locale is already loaded...
1652 if (find_po(locale
))
1654 _cupsLangPrintf(stderr
,
1655 _("ppdc: Duplicate #po for locale %s on line %d of %s."),
1656 locale
, fp
->line
, fp
->filename
);
1660 // Figure out the current directory...
1661 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
1663 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
1666 strlcpy(basedir
, ".", sizeof(basedir
));
1668 // Find the po file...
1669 pofilename
[0] = '\0';
1672 find_include(poname
, basedir
, pofilename
, sizeof(pofilename
)))
1674 // Found it, so load it...
1675 cat
= new ppdcCatalog(locale
, pofilename
);
1677 // Reset the filename to the name supplied by the user...
1678 cat
->filename
->release();
1679 cat
->filename
= new ppdcString(poname
);
1681 // Return the catalog...
1686 _cupsLangPrintf(stderr
,
1687 _("ppdc: Unable to find #po file %s on line %d of %s."),
1688 poname
, fp
->line
, fp
->filename
);
1695 // 'ppdcSource::get_resolution()' - Get an old-style resolution option.
1698 ppdcChoice
* // O - Choice data
1699 ppdcSource::get_resolution(ppdcFile
*fp
)// I - File to read
1701 char name
[1024], // Name
1703 temp
[256], // Temporary string
1704 command
[256], // Command string
1705 *commptr
; // Pointer into command
1706 int xdpi
, ydpi
, // X + Y resolution
1707 color_order
, // Color order
1708 color_space
, // Colorspace
1709 compression
, // Compression mode
1710 depth
, // Bits per color
1711 row_count
, // Row count
1712 row_feed
, // Row feed
1713 row_step
; // Row step/interval
1716 // Read the resolution parameters:
1718 // Resolution colorspace bits row-count row-feed row-step name/text
1719 if (!get_token(fp
, temp
, sizeof(temp
)))
1721 _cupsLangPrintf(stderr
,
1722 _("ppdc: Expected override field after Resolution on line "
1723 "%d of %s."), fp
->line
, fp
->filename
);
1727 color_order
= get_color_order(temp
);
1728 color_space
= get_color_space(temp
);
1729 compression
= get_integer(temp
);
1731 depth
= get_integer(fp
);
1732 row_count
= get_integer(fp
);
1733 row_feed
= get_integer(fp
);
1734 row_step
= get_integer(fp
);
1736 if (!get_token(fp
, name
, sizeof(name
)))
1738 _cupsLangPrintf(stderr
,
1739 _("ppdc: Expected name/text after Resolution on line %d of "
1740 "%s."), fp
->line
, fp
->filename
);
1744 if ((text
= strchr(name
, '/')) != NULL
)
1749 switch (sscanf(name
, "%dx%d", &xdpi
, &ydpi
))
1752 _cupsLangPrintf(stderr
,
1753 _("ppdc: Bad resolution name \"%s\" on line %d of "
1754 "%s."), name
, fp
->line
, fp
->filename
);
1761 // Create the necessary PS commands...
1762 snprintf(command
, sizeof(command
),
1763 "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
1764 "/cupsRowFeed %d/cupsRowStep %d",
1765 xdpi
, ydpi
, depth
, row_count
, row_feed
, row_step
);
1766 commptr
= command
+ strlen(command
);
1768 if (color_order
>= 0)
1770 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1771 "/cupsColorOrder %d", color_order
);
1772 commptr
+= strlen(commptr
);
1775 if (color_space
>= 0)
1777 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1778 "/cupsColorSpace %d", color_space
);
1779 commptr
+= strlen(commptr
);
1782 if (compression
>= 0)
1784 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1785 "/cupsCompression %d", compression
);
1786 commptr
+= strlen(commptr
);
1789 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
), ">>setpagedevice");
1791 // Return the new choice...
1792 return (new ppdcChoice(name
, text
, command
));
1797 // 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
1800 ppdcProfile
* // O - Color profile
1801 ppdcSource::get_simple_profile(ppdcFile
*fp
)
1804 char resolution
[1024], // Resolution/media type
1805 *media_type
; // Media type
1806 float m
[9]; // Transform matrix
1807 float kd
, rd
, g
; // Densities and gamma
1808 float red
, green
, blue
; // RGB adjustments
1809 float yellow
; // Yellow density
1810 float color
; // Color density values
1813 // Get the SimpleColorProfile parameters:
1815 // SimpleColorProfile resolution/mediatype black-density yellow-density
1816 // red-density gamma red-adjust green-adjust blue-adjust
1817 if (!get_token(fp
, resolution
, sizeof(resolution
)))
1819 _cupsLangPrintf(stderr
,
1820 _("ppdc: Expected resolution/mediatype following "
1821 "SimpleColorProfile on line %d of %s."),
1822 fp
->line
, fp
->filename
);
1826 if ((media_type
= strchr(resolution
, '/')) != NULL
)
1827 *media_type
++ = '\0';
1829 media_type
= resolution
;
1831 // Collect the profile parameters...
1833 yellow
= get_float(fp
);
1836 red
= get_float(fp
);
1837 green
= get_float(fp
);
1838 blue
= get_float(fp
);
1840 // Build the color profile...
1841 color
= 0.5f
* rd
/ kd
- kd
;
1843 m
[1] = color
+ blue
; // C + M (blue)
1844 m
[2] = color
- green
; // C + Y (green)
1845 m
[3] = color
- blue
; // M + C (blue)
1847 m
[5] = color
+ red
; // M + Y (red)
1848 m
[6] = yellow
* (color
+ green
); // Y + C (green)
1849 m
[7] = yellow
* (color
- red
); // Y + M (red)
1857 else if (m
[3] > 0.0f
)
1868 else if (m
[6] > 0.0f
)
1879 else if (m
[7] > 0.0f
)
1885 // Return the new profile...
1886 return (new ppdcProfile(resolution
, media_type
, g
, kd
, m
));
1891 // 'ppdcSource::get_size()' - Get a media size definition from a file.
1894 ppdcMediaSize
* // O - Media size
1895 ppdcSource::get_size(ppdcFile
*fp
) // I - File to read
1897 char name
[1024], // Name
1899 float width
, // Width
1903 // Get the name, text, width, and length:
1905 // #media name/text width length
1906 if (!get_token(fp
, name
, sizeof(name
)))
1909 if ((text
= strchr(name
, '/')) != NULL
)
1914 if ((width
= get_measurement(fp
)) < 0.0f
)
1917 if ((length
= get_measurement(fp
)) < 0.0f
)
1920 // Return the new media size...
1921 return (new ppdcMediaSize(name
, text
, width
, length
, 0.0f
, 0.0f
, 0.0f
, 0.0f
));
1926 // 'ppdcSource::get_token()' - Get a token from a file.
1929 char * // O - Token string or NULL
1930 ppdcSource::get_token(ppdcFile
*fp
, // I - File to read
1931 char *buffer
, // I - Buffer
1932 int buflen
) // I - Length of buffer
1934 char *bufptr
, // Pointer into string buffer
1935 *bufend
; // End of string buffer
1936 int ch
, // Character from file
1937 nextch
, // Next char in file
1938 quote
, // Quote character used...
1939 empty
, // Empty input?
1940 startline
; // Start line for quote
1941 char name
[256], // Name string
1942 *nameptr
; // Name pointer
1943 ppdcVariable
*var
; // Variable pointer
1946 // Mark the beginning and end of the buffer...
1948 bufend
= buffer
+ buflen
- 1;
1950 // Loop intil we've read a token...
1955 while ((ch
= fp
->get()) != EOF
)
1957 if (isspace(ch
) && !quote
)
1966 // Variable substitution
1969 for (nameptr
= name
; (ch
= fp
->peek()) != EOF
;)
1971 if (!isalnum(ch
) && ch
!= '_')
1973 else if (nameptr
< (name
+ sizeof(name
) - 1))
1974 *nameptr
++ = (char)fp
->get();
1977 if (nameptr
== name
)
1979 // Just substitute this character...
1983 if (bufptr
< bufend
)
1984 *bufptr
++ = (char)fp
->get();
1989 _cupsLangPrintf(stderr
,
1990 _("ppdc: Bad variable substitution ($%c) on line %d "
1991 "of %s."), ch
, fp
->line
, fp
->filename
);
1993 if (bufptr
< bufend
)
1999 // Substitute the variable value...
2001 var
= find_variable(name
);
2004 strlcpy(bufptr
, var
->value
->value
, (size_t)(bufend
- bufptr
+ 1));
2005 bufptr
+= strlen(bufptr
);
2009 if (!(cond_state
& PPDC_COND_SKIP
))
2010 _cupsLangPrintf(stderr
,
2011 _("ppdc: Undefined variable (%s) on line %d of "
2012 "%s."), name
, fp
->line
, fp
->filename
);
2014 snprintf(bufptr
, (size_t)(bufend
- bufptr
+ 1), "$%s", name
);
2015 bufptr
+= strlen(bufptr
);
2019 else if (ch
== '/' && !quote
)
2021 // Possibly a comment...
2022 nextch
= fp
->peek();
2029 while ((nextch
= fp
->get()) != EOF
)
2031 if (ch
== '*' && nextch
== '/')
2040 else if (nextch
== '/')
2043 while ((nextch
= fp
->get()) != EOF
)
2055 if (bufptr
< bufend
)
2056 *bufptr
++ = (char)ch
;
2059 else if (ch
== '\'' || ch
== '\"')
2065 // Ending the current quoted string...
2070 // Insert the opposing quote char...
2071 if (bufptr
< bufend
)
2072 *bufptr
++ = (char)ch
;
2076 // Start a new quoted string...
2077 startline
= fp
->line
;
2081 else if ((ch
== '(' || ch
== '<') && !quote
)
2085 startline
= fp
->line
;
2087 if (bufptr
< bufend
)
2088 *bufptr
++ = (char)ch
;
2090 else if ((ch
== ')' && quote
== '(') || (ch
== '>' && quote
== '<'))
2094 if (bufptr
< bufend
)
2095 *bufptr
++ = (char)ch
;
2097 else if (ch
== '\\')
2101 if ((ch
= fp
->get()) == EOF
)
2104 if (bufptr
< bufend
)
2105 *bufptr
++ = (char)ch
;
2107 else if (bufptr
< bufend
)
2111 *bufptr
++ = (char)ch
;
2113 if ((ch
== '{' || ch
== '}') && !quote
)
2120 _cupsLangPrintf(stderr
,
2121 _("ppdc: Unterminated string starting with %c on line %d "
2122 "of %s."), quote
, startline
, fp
->filename
);
2137 // 'ppdcSource::get_variable()' - Get a variable definition.
2140 ppdcVariable
* // O - Variable
2141 ppdcSource::get_variable(ppdcFile
*fp
) // I - File to read
2143 char name
[1024], // Name
2144 value
[1024]; // Value
2147 // Get the name and value:
2149 // #define name value
2150 if (!get_token(fp
, name
, sizeof(name
)))
2153 if (!get_token(fp
, value
, sizeof(value
)))
2156 // Set the variable...
2157 return (set_variable(name
, value
));
2162 // 'ppdcSource::quotef()' - Write a formatted, quoted string...
2165 int // O - Number bytes on success, -1 on failure
2166 ppdcSource::quotef(cups_file_t
*fp
, // I - File to write to
2167 const char *format
, // I - Printf-style format string
2168 ...) // I - Additional args as needed
2170 va_list ap
; // Pointer to additional arguments
2171 int bytes
; // Bytes written
2172 char sign
, // Sign of format width
2173 size
, // Size character (h, l, L)
2174 type
; // Format type character
2175 const char *bufformat
; // Start of format
2176 int width
, // Width of field
2177 prec
; // Number of characters of precision
2178 char tformat
[100]; // Temporary format string for fprintf()
2179 char *s
; // Pointer to string
2180 int slen
; // Length of string
2181 int i
; // Looping var
2184 // Range check input...
2188 // Loop through the format string, formatting as needed...
2189 va_start(ap
, format
);
2202 cupsFilePutChar(fp
, *format
++);
2206 else if (strchr(" -+#\'", *format
))
2212 while (isdigit(*format
))
2213 width
= width
* 10 + *format
++ - '0';
2220 while (isdigit(*format
))
2221 prec
= prec
* 10 + *format
++ - '0';
2226 if (*format
== 'l' && format
[1] == 'l')
2231 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
2243 case 'E' : // Floating point formats
2248 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2251 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2252 tformat
[format
- bufformat
] = '\0';
2254 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, double));
2257 case 'B' : // Integer formats
2265 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2268 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2269 tformat
[format
- bufformat
] = '\0';
2271 # ifdef HAVE_LONG_LONG
2273 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long long));
2275 # endif /* HAVE_LONG_LONG */
2277 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long));
2279 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, int));
2282 case 'p' : // Pointer value
2283 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2286 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2287 tformat
[format
- bufformat
] = '\0';
2289 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, void *));
2292 case 'c' : // Character or character array
2296 cupsFilePutChar(fp
, va_arg(ap
, int));
2300 cupsFileWrite(fp
, va_arg(ap
, char *), (size_t)width
);
2305 case 's' : // String
2306 if ((s
= va_arg(ap
, char *)) == NULL
)
2307 s
= (char *)"(nil)";
2309 slen
= (int)strlen(s
);
2310 if (slen
> width
&& prec
!= width
)
2318 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2319 cupsFilePutChar(fp
, ' ');
2322 for (i
= slen
; i
> 0; i
--, s
++, bytes
++)
2324 if (*s
== '\\' || *s
== '\"')
2326 cupsFilePutChar(fp
, '\\');
2330 cupsFilePutChar(fp
, *s
);
2335 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2336 cupsFilePutChar(fp
, ' ');
2343 cupsFilePutChar(fp
, *format
++);
2350 // Return the number of characters written.
2356 // 'ppdcSource::read_file()' - Read a driver source file.
2360 ppdcSource::read_file(const char *f
, // I - File to read
2361 cups_file_t
*ffp
) // I - File pointer to use
2363 ppdcFile
*fp
= new ppdcFile(f
, ffp
);
2367 if (cond_current
!= cond_stack
)
2368 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."), f
);
2373 // 'ppdcSource::scan_file()' - Scan a driver source file.
2377 ppdcSource::scan_file(ppdcFile
*fp
, // I - File to read
2378 ppdcDriver
*td
, // I - Driver template
2379 bool inc
) // I - Including?
2381 ppdcDriver
*d
; // Current driver
2382 ppdcGroup
*g
, // Current group
2383 *mg
, // Matching group
2384 *general
, // General options group
2385 *install
; // Installable options group
2386 ppdcOption
*o
; // Current option
2387 ppdcChoice
*c
; // Current choice
2388 char temp
[256], // Token from file...
2389 *ptr
; // Pointer into token
2390 int isdefault
; // Default option?
2393 // Initialize things as needed...
2400 d
= new ppdcDriver(td
);
2402 if ((general
= d
->find_group("General")) == NULL
)
2404 general
= new ppdcGroup("General", NULL
);
2405 d
->add_group(general
);
2408 if ((install
= d
->find_group("InstallableOptions")) == NULL
)
2410 install
= new ppdcGroup("InstallableOptions", "Installable Options");
2411 d
->add_group(install
);
2414 // Loop until EOF or }
2418 while (get_token(fp
, temp
, sizeof(temp
)))
2422 // Mark the next choice as the default
2425 for (ptr
= temp
; ptr
[1]; ptr
++)
2432 // Don't mark the next choice as the default
2436 if (!_cups_strcasecmp(temp
, "}"))
2438 // Close this one out...
2441 else if (!_cups_strcasecmp(temp
, "{"))
2443 // Open a new child...
2446 else if (!_cups_strcasecmp(temp
, "#if"))
2448 if ((cond_current
- cond_stack
) >= 100)
2450 _cupsLangPrintf(stderr
,
2451 _("ppdc: Too many nested #if's on line %d of %s."),
2452 fp
->line
, fp
->filename
);
2457 if (get_integer(fp
) > 0)
2458 *cond_current
= PPDC_COND_SATISFIED
;
2461 *cond_current
= PPDC_COND_SKIP
;
2462 cond_state
|= PPDC_COND_SKIP
;
2465 else if (!_cups_strcasecmp(temp
, "#elif"))
2467 if (cond_current
== cond_stack
)
2469 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2470 fp
->line
, fp
->filename
);
2474 if (*cond_current
& PPDC_COND_SATISFIED
)
2477 *cond_current
|= PPDC_COND_SKIP
;
2479 else if (get_integer(fp
) > 0)
2481 *cond_current
|= PPDC_COND_SATISFIED
;
2482 *cond_current
&= ~PPDC_COND_SKIP
;
2485 *cond_current
|= PPDC_COND_SKIP
;
2487 // Update the current state
2488 int *cond_temp
= cond_current
; // Temporary stack pointer
2490 cond_state
= PPDC_COND_NORMAL
;
2491 while (cond_temp
> cond_stack
)
2492 if (*cond_temp
& PPDC_COND_SKIP
)
2494 cond_state
= PPDC_COND_SKIP
;
2500 else if (!_cups_strcasecmp(temp
, "#else"))
2502 if (cond_current
== cond_stack
)
2504 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2505 fp
->line
, fp
->filename
);
2509 if (*cond_current
& PPDC_COND_SATISFIED
)
2510 *cond_current
|= PPDC_COND_SKIP
;
2513 *cond_current
|= PPDC_COND_SATISFIED
;
2514 *cond_current
&= ~PPDC_COND_SKIP
;
2517 // Update the current state
2518 int *cond_temp
= cond_current
; // Temporary stack pointer
2520 cond_state
= PPDC_COND_NORMAL
;
2521 while (cond_temp
> cond_stack
)
2522 if (*cond_temp
& PPDC_COND_SKIP
)
2524 cond_state
= PPDC_COND_SKIP
;
2530 else if (!_cups_strcasecmp(temp
, "#endif"))
2532 if (cond_current
== cond_stack
)
2534 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2535 fp
->line
, fp
->filename
);
2541 // Update the current state
2542 int *cond_temp
= cond_current
; // Temporary stack pointer
2544 cond_state
= PPDC_COND_NORMAL
;
2545 while (cond_temp
> cond_stack
)
2546 if (*cond_temp
& PPDC_COND_SKIP
)
2548 cond_state
= PPDC_COND_SKIP
;
2554 else if (!_cups_strcasecmp(temp
, "#define"))
2556 // Get the variable...
2559 else if (!_cups_strcasecmp(temp
, "#include"))
2561 // #include filename
2562 char basedir
[1024], // Base directory
2563 *baseptr
, // Pointer into directory
2564 inctemp
[1024], // Initial filename
2565 incname
[1024]; // Include filename
2566 ppdcFile
*incfile
; // Include file
2567 int *old_current
= cond_current
;
2568 // Previous current stack
2571 // Get the include name...
2572 if (!get_token(fp
, inctemp
, sizeof(inctemp
)))
2574 _cupsLangPrintf(stderr
,
2575 _("ppdc: Expected include filename on line %d of "
2576 "%s."), fp
->line
, fp
->filename
);
2583 // Figure out the current directory...
2584 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
2586 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
2589 strlcpy(basedir
, ".", sizeof(basedir
));
2591 // Find the include file...
2592 if (find_include(inctemp
, basedir
, incname
, sizeof(incname
)))
2594 // Open the include file, scan it, and then close it...
2595 incfile
= new ppdcFile(incname
);
2596 scan_file(incfile
, d
, true);
2599 if (cond_current
!= old_current
)
2600 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."),
2606 _cupsLangPrintf(stderr
,
2607 _("ppdc: Unable to find include file \"%s\" on line %d "
2608 "of %s."), inctemp
, fp
->line
, fp
->filename
);
2612 else if (!_cups_strcasecmp(temp
, "#media"))
2614 ppdcMediaSize
*m
; // Media size
2617 // Get a media size...
2627 else if (!_cups_strcasecmp(temp
, "#po"))
2629 ppdcCatalog
*cat
; // Message catalog
2632 // Get a message catalog...
2642 else if (!_cups_strcasecmp(temp
, "Attribute") ||
2643 !_cups_strcasecmp(temp
, "LocAttribute"))
2645 ppdcAttr
*a
; // Attribute
2648 // Get an attribute...
2649 a
= get_attr(fp
, !_cups_strcasecmp(temp
, "LocAttribute"));
2658 else if (!_cups_strcasecmp(temp
, "Choice"))
2671 // Add it to the current option...
2674 _cupsLangPrintf(stderr
,
2675 _("ppdc: Choice found on line %d of %s with no "
2676 "Option."), fp
->line
, fp
->filename
);
2683 o
->set_defchoice(c
);
2685 else if (!_cups_strcasecmp(temp
, "ColorDevice"))
2687 // ColorDevice boolean
2691 d
->color_device
= get_boolean(fp
);
2693 else if (!_cups_strcasecmp(temp
, "ColorModel"))
2695 // Get the color model
2696 c
= get_color_model(fp
);
2706 // Add the choice to the ColorModel option...
2707 if ((o
= d
->find_option("ColorModel")) == NULL
)
2709 // Create the ColorModel option...
2710 o
= new ppdcOption(PPDC_PICKONE
, "ColorModel", "Color Mode", PPDC_SECTION_ANY
, 10.0f
);
2718 o
->set_defchoice(c
);
2722 else if (!_cups_strcasecmp(temp
, "ColorProfile"))
2724 ppdcProfile
*p
; // Color profile
2727 // Get the color profile...
2728 p
= get_color_profile(fp
);
2735 d
->profiles
->add(p
);
2738 else if (!_cups_strcasecmp(temp
, "Copyright"))
2741 char copytemp
[8192], // Copyright string
2742 *copyptr
, // Pointer into string
2743 *copyend
; // Pointer to end of string
2746 // Get the copyright string...
2747 if (!get_token(fp
, copytemp
, sizeof(temp
)))
2749 _cupsLangPrintf(stderr
,
2750 _("ppdc: Expected string after Copyright on line %d "
2751 "of %s."), fp
->line
, fp
->filename
);
2758 // Break it up into individual lines...
2759 for (copyptr
= copytemp
; copyptr
; copyptr
= copyend
)
2761 if ((copyend
= strchr(copyptr
, '\n')) != NULL
)
2764 d
->copyright
->add(new ppdcString(copyptr
));
2767 else if (!_cups_strcasecmp(temp
, "CustomMedia"))
2769 ppdcMediaSize
*m
; // Media size
2772 // Get a custom media size...
2773 m
= get_custom_size(fp
);
2785 d
->set_default_size(m
);
2787 else if (!_cups_strcasecmp(temp
, "Cutter"))
2790 int have_cutter
; // Have a paper cutter?
2793 have_cutter
= get_boolean(fp
);
2794 if (have_cutter
<= 0 || cond_state
)
2797 if ((o
= d
->find_option("CutMedia")) == NULL
)
2799 o
= new ppdcOption(PPDC_BOOLEAN
, "CutMedia", "Cut Media", PPDC_SECTION_ANY
, 10.0f
);
2804 c
= new ppdcChoice("False", NULL
, "<</CutMedia 0>>setpagedevice");
2806 o
->set_defchoice(c
);
2808 c
= new ppdcChoice("True", NULL
, "<</CutMedia 4>>setpagedevice");
2814 else if (!_cups_strcasecmp(temp
, "Darkness"))
2816 // Get the darkness choice...
2817 c
= get_generic(fp
, "Darkness", NULL
, "cupsCompression");
2827 // Add the choice to the cupsDarkness option...
2828 if ((o
= d
->find_option_group("cupsDarkness", &mg
)) == NULL
)
2830 // Create the cupsDarkness option...
2831 o
= new ppdcOption(PPDC_PICKONE
, "cupsDarkness", "Darkness", PPDC_SECTION_ANY
, 10.0f
);
2835 else if (mg
!= general
)
2837 _cupsLangPrintf(stderr
,
2838 _("ppdc: Option %s defined in two different groups on "
2839 "line %d of %s."), "cupsDarkness", fp
->line
,
2848 o
->set_defchoice(c
);
2852 else if (!_cups_strcasecmp(temp
, "DriverType"))
2854 int i
; // Looping var
2857 // DriverType keyword
2858 if (!get_token(fp
, temp
, sizeof(temp
)))
2860 _cupsLangPrintf(stderr
,
2861 _("ppdc: Expected driver type keyword following "
2862 "DriverType on line %d of %s."),
2863 fp
->line
, fp
->filename
);
2870 for (i
= 0; i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])); i
++)
2871 if (!_cups_strcasecmp(temp
, driver_types
[i
]))
2874 if (i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])))
2875 d
->type
= (ppdcDrvType
)i
;
2876 else if (!_cups_strcasecmp(temp
, "dymo"))
2877 d
->type
= PPDC_DRIVER_LABEL
;
2879 _cupsLangPrintf(stderr
,
2880 _("ppdc: Unknown driver type %s on line %d of %s."),
2881 temp
, fp
->line
, fp
->filename
);
2883 else if (!_cups_strcasecmp(temp
, "Duplex"))
2885 else if (!_cups_strcasecmp(temp
, "Filter"))
2887 ppdcFilter
*f
; // Filter
2890 // Get the filter value...
2900 else if (!_cups_strcasecmp(temp
, "Finishing"))
2902 // Get the finishing choice...
2903 c
= get_generic(fp
, "Finishing", "OutputType", NULL
);
2913 // Add the choice to the cupsFinishing option...
2914 if ((o
= d
->find_option_group("cupsFinishing", &mg
)) == NULL
)
2916 // Create the cupsFinishing option...
2917 o
= new ppdcOption(PPDC_PICKONE
, "cupsFinishing", "Finishing", PPDC_SECTION_ANY
, 10.0f
);
2921 else if (mg
!= general
)
2923 _cupsLangPrintf(stderr
,
2924 _("ppdc: Option %s defined in two different groups on "
2925 "line %d of %s."), "cupsFinishing", fp
->line
,
2934 o
->set_defchoice(c
);
2938 else if (!_cups_strcasecmp(temp
, "Font") ||
2939 !_cups_strcasecmp(temp
, "#font"))
2941 ppdcFont
*f
; // Font
2952 if (!_cups_strcasecmp(temp
, "#font"))
2958 d
->set_default_font(f
);
2962 else if (!_cups_strcasecmp(temp
, "Group"))
2965 ppdcGroup
*tempg
= get_group(fp
, d
);
2972 if (!d
->find_group(tempg
->name
->value
))
2977 if (!d
->find_group(tempg
->name
->value
))
2978 d
->add_group(tempg
);
2983 else if (!_cups_strcasecmp(temp
, "HWMargins"))
2985 // HWMargins left bottom right top
2986 d
->left_margin
= get_measurement(fp
);
2987 d
->bottom_margin
= get_measurement(fp
);
2988 d
->right_margin
= get_measurement(fp
);
2989 d
->top_margin
= get_measurement(fp
);
2991 else if (!_cups_strcasecmp(temp
, "InputSlot"))
2993 // Get the input slot choice...
2994 c
= get_generic(fp
, "InputSlot", NULL
, "MediaPosition");
3004 // Add the choice to the InputSlot option...
3006 if ((o
= d
->find_option_group("InputSlot", &mg
)) == NULL
)
3008 // Create the InputSlot option...
3009 o
= new ppdcOption(PPDC_PICKONE
, "InputSlot", "Media Source",
3010 PPDC_SECTION_ANY
, 10.0f
);
3014 else if (mg
!= general
)
3016 _cupsLangPrintf(stderr
,
3017 _("ppdc: Option %s defined in two different groups on "
3018 "line %d of %s."), "InputSlot", fp
->line
,
3027 o
->set_defchoice(c
);
3031 else if (!_cups_strcasecmp(temp
, "Installable"))
3033 // Get the installable option...
3034 o
= get_installable(fp
);
3036 // Add it as needed...
3042 install
->add_option(o
);
3047 else if (!_cups_strcasecmp(temp
, "ManualCopies"))
3049 // ManualCopies boolean
3053 d
->manual_copies
= get_boolean(fp
);
3055 else if (!_cups_strcasecmp(temp
, "Manufacturer"))
3057 // Manufacturer name
3058 char name
[256]; // Model name string
3061 if (!get_token(fp
, name
, sizeof(name
)))
3063 _cupsLangPrintf(stderr
,
3064 _("ppdc: Expected name after Manufacturer on line %d "
3065 "of %s."), fp
->line
, fp
->filename
);
3070 d
->set_manufacturer(name
);
3072 else if (!_cups_strcasecmp(temp
, "MaxSize"))
3074 // MaxSize width length
3077 get_measurement(fp
);
3078 get_measurement(fp
);
3082 d
->max_width
= get_measurement(fp
);
3083 d
->max_length
= get_measurement(fp
);
3086 else if (!_cups_strcasecmp(temp
, "MediaSize"))
3088 // MediaSize keyword
3089 char name
[41]; // Media size name
3090 ppdcMediaSize
*m
, // Matching media size...
3091 *dm
; // Driver media size...
3094 if (get_token(fp
, name
, sizeof(name
)) == NULL
)
3096 _cupsLangPrintf(stderr
,
3097 _("ppdc: Expected name after MediaSize on line %d of "
3098 "%s."), fp
->line
, fp
->filename
);
3105 m
= find_size(name
);
3109 _cupsLangPrintf(stderr
,
3110 _("ppdc: Unknown media size \"%s\" on line %d of "
3111 "%s."), name
, fp
->line
, fp
->filename
);
3115 // Add this size to the driver...
3116 dm
= new ppdcMediaSize(m
->name
->value
, m
->text
->value
,
3117 m
->width
, m
->length
, d
->left_margin
,
3118 d
->bottom_margin
, d
->right_margin
,
3123 d
->set_default_size(dm
);
3125 else if (!_cups_strcasecmp(temp
, "MediaType"))
3127 // Get the media type choice...
3128 c
= get_generic(fp
, "MediaType", "MediaType", "cupsMediaType");
3138 // Add the choice to the MediaType option...
3139 if ((o
= d
->find_option_group("MediaType", &mg
)) == NULL
)
3141 // Create the MediaType option...
3142 o
= new ppdcOption(PPDC_PICKONE
, "MediaType", "Media Type",
3143 PPDC_SECTION_ANY
, 10.0f
);
3147 else if (mg
!= general
)
3149 _cupsLangPrintf(stderr
,
3150 _("ppdc: Option %s defined in two different groups on "
3151 "line %d of %s."), "MediaType", fp
->line
,
3160 o
->set_defchoice(c
);
3164 else if (!_cups_strcasecmp(temp
, "MinSize"))
3166 // MinSize width length
3169 get_measurement(fp
);
3170 get_measurement(fp
);
3174 d
->min_width
= get_measurement(fp
);
3175 d
->min_length
= get_measurement(fp
);
3178 else if (!_cups_strcasecmp(temp
, "ModelName"))
3181 char name
[256]; // Model name string
3184 if (!get_token(fp
, name
, sizeof(name
)))
3186 _cupsLangPrintf(stderr
,
3187 _("ppdc: Expected name after ModelName on line %d of "
3188 "%s."), fp
->line
, fp
->filename
);
3193 d
->set_model_name(name
);
3195 else if (!_cups_strcasecmp(temp
, "ModelNumber"))
3197 // ModelNumber number
3201 d
->model_number
= get_integer(fp
);
3203 else if (!_cups_strcasecmp(temp
, "Option"))
3206 ppdcOption
*tempo
= get_option(fp
, d
, g
);
3213 if (!g
->find_option(tempo
->name
->value
))
3218 if (!g
->find_option(tempo
->name
->value
))
3219 g
->add_option(tempo
);
3224 else if (!_cups_strcasecmp(temp
, "FileName"))
3227 char name
[256]; // Filename string
3230 if (!get_token(fp
, name
, sizeof(name
)))
3232 _cupsLangPrintf(stderr
,
3233 _("ppdc: Expected name after FileName on line %d of "
3234 "%s."), fp
->line
, fp
->filename
);
3239 d
->set_file_name(name
);
3241 else if (!_cups_strcasecmp(temp
, "PCFileName"))
3244 char name
[256]; // PC filename string
3247 if (!get_token(fp
, name
, sizeof(name
)))
3249 _cupsLangPrintf(stderr
,
3250 _("ppdc: Expected name after PCFileName on line %d of "
3251 "%s."), fp
->line
, fp
->filename
);
3256 d
->set_pc_file_name(name
);
3258 else if (!_cups_strcasecmp(temp
, "Resolution"))
3260 // Get the resolution choice...
3261 c
= get_resolution(fp
);
3271 // Add the choice to the Resolution option...
3272 if ((o
= d
->find_option_group("Resolution", &mg
)) == NULL
)
3274 // Create the Resolution option...
3275 o
= new ppdcOption(PPDC_PICKONE
, "Resolution", NULL
, PPDC_SECTION_ANY
,
3280 else if (mg
!= general
)
3282 _cupsLangPrintf(stderr
,
3283 _("ppdc: Option %s defined in two different groups on "
3284 "line %d of %s."), "Resolution", fp
->line
,
3293 o
->set_defchoice(c
);
3297 else if (!_cups_strcasecmp(temp
, "SimpleColorProfile"))
3299 ppdcProfile
*p
; // Color profile
3302 // Get the color profile...
3303 p
= get_simple_profile(fp
);
3310 d
->profiles
->add(p
);
3313 else if (!_cups_strcasecmp(temp
, "Throughput"))
3315 // Throughput number
3319 d
->throughput
= get_integer(fp
);
3321 else if (!_cups_strcasecmp(temp
, "UIConstraints"))
3323 ppdcConstraint
*con
; // Constraint
3326 con
= get_constraint(fp
);
3333 d
->constraints
->add(con
);
3336 else if (!_cups_strcasecmp(temp
, "VariablePaperSize"))
3338 // VariablePaperSize boolean
3342 d
->variable_paper_size
= get_boolean(fp
);
3344 else if (!_cups_strcasecmp(temp
, "Version"))
3347 char name
[256]; // Model name string
3350 if (!get_token(fp
, name
, sizeof(name
)))
3352 _cupsLangPrintf(stderr
,
3353 _("ppdc: Expected string after Version on line %d of "
3354 "%s."), fp
->line
, fp
->filename
);
3359 d
->set_version(name
);
3363 _cupsLangPrintf(stderr
,
3364 _("ppdc: Unknown token \"%s\" seen on line %d of %s."),
3365 temp
, fp
->line
, fp
->filename
);
3370 // Done processing this block, is there anything to save?
3373 if (!d
->pc_file_name
|| !d
->model_name
|| !d
->manufacturer
|| !d
->version
||
3376 // Nothing to save...
3381 // Got a driver, save it...
3391 // 'ppdcSource::set_variable()' - Set a variable.
3394 ppdcVariable
* // O - Variable
3395 ppdcSource::set_variable(
3396 const char *name
, // I - Name
3397 const char *value
) // I - Value
3399 ppdcVariable
*v
; // Variable
3402 // See if the variable exists already...
3403 v
= find_variable(name
);
3406 // Change the variable value...
3407 v
->set_value(value
);
3411 // Create a new variable and add it...
3412 v
= new ppdcVariable(name
, value
);
3421 // 'ppdcSource::write_file()' - Write the current source data to a file.
3424 int // O - 0 on success, -1 on error
3425 ppdcSource::write_file(const char *f
) // I - File to write
3427 cups_file_t
*fp
; // Output file
3428 char bckname
[1024]; // Backup file
3429 ppdcDriver
*d
; // Current driver
3430 ppdcString
*st
; // Current string
3431 ppdcAttr
*a
; // Current attribute
3432 ppdcConstraint
*co
; // Current constraint
3433 ppdcFilter
*fi
; // Current filter
3434 ppdcFont
*fo
; // Current font
3435 ppdcGroup
*g
; // Current group
3436 ppdcOption
*o
; // Current option
3437 ppdcChoice
*ch
; // Current choice
3438 ppdcProfile
*p
; // Current color profile
3439 ppdcMediaSize
*si
; // Current media size
3440 float left
, // Current left margin
3441 bottom
, // Current bottom margin
3442 right
, // Current right margin
3443 top
; // Current top margin
3444 int dtused
[PPDC_DRIVER_MAX
];// Driver type usage...
3447 // Rename the current file, if any, to .bck...
3448 snprintf(bckname
, sizeof(bckname
), "%s.bck", f
);
3451 // Open the output file...
3452 fp
= cupsFileOpen(f
, "w");
3456 // Can't create file; restore backup and return...
3461 cupsFilePuts(fp
, "// CUPS PPD Compiler " CUPS_SVERSION
"\n\n");
3463 // Include standard files...
3464 cupsFilePuts(fp
, "// Include necessary files...\n");
3465 cupsFilePuts(fp
, "#include <font.defs>\n");
3466 cupsFilePuts(fp
, "#include <media.defs>\n");
3468 memset(dtused
, 0, sizeof(dtused
));
3470 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3471 if (d
->type
> PPDC_DRIVER_PS
&& !dtused
[d
->type
])
3473 cupsFilePrintf(fp
, "#include <%s.h>\n", driver_types
[d
->type
]);
3474 dtused
[d
->type
] = 1;
3477 // Output each driver...
3478 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3480 // Start the driver...
3481 cupsFilePrintf(fp
, "\n// %s %s\n", d
->manufacturer
->value
,
3482 d
->model_name
->value
);
3483 cupsFilePuts(fp
, "{\n");
3485 // Write the copyright stings...
3486 for (st
= (ppdcString
*)d
->copyright
->first();
3488 st
= (ppdcString
*)d
->copyright
->next())
3489 quotef(fp
, " Copyright \"%s\"\n", st
->value
);
3491 // Write other strings and values...
3492 if (d
->manufacturer
&& d
->manufacturer
->value
)
3493 quotef(fp
, " Manufacturer \"%s\"\n", d
->manufacturer
->value
);
3494 if (d
->model_name
->value
)
3495 quotef(fp
, " ModelName \"%s\"\n", d
->model_name
->value
);
3496 if (d
->file_name
&& d
->file_name
->value
)
3497 quotef(fp
, " FileName \"%s\"\n", d
->file_name
->value
);
3498 if (d
->pc_file_name
&& d
->pc_file_name
->value
)
3499 quotef(fp
, " PCFileName \"%s\"\n", d
->pc_file_name
->value
);
3500 if (d
->version
&& d
->version
->value
)
3501 quotef(fp
, " Version \"%s\"\n", d
->version
->value
);
3503 cupsFilePrintf(fp
, " DriverType %s\n", driver_types
[d
->type
]);
3505 if (d
->model_number
)
3509 case PPDC_DRIVER_LABEL
:
3510 cupsFilePuts(fp
, " ModelNumber ");
3512 switch (d
->model_number
)
3515 cupsFilePuts(fp
, "$DYMO_3x0\n");
3518 case ZEBRA_EPL_LINE
:
3519 cupsFilePuts(fp
, "$ZEBRA_EPL_LINE\n");
3522 case ZEBRA_EPL_PAGE
:
3523 cupsFilePuts(fp
, "$ZEBRA_EPL_PAGE\n");
3527 cupsFilePuts(fp
, "$ZEBRA_ZPL\n");
3531 cupsFilePuts(fp
, "$ZEBRA_CPCL\n");
3534 case INTELLITECH_PCL
:
3535 cupsFilePuts(fp
, "$INTELLITECH_PCL\n");
3539 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3544 case PPDC_DRIVER_EPSON
:
3545 cupsFilePuts(fp
, " ModelNumber ");
3547 switch (d
->model_number
)
3550 cupsFilePuts(fp
, "$EPSON_9PIN\n");
3554 cupsFilePuts(fp
, "$EPSON_24PIN\n");
3558 cupsFilePuts(fp
, "$EPSON_COLOR\n");
3562 cupsFilePuts(fp
, "$EPSON_PHOTO\n");
3566 cupsFilePuts(fp
, "$EPSON_ICOLOR\n");
3570 cupsFilePuts(fp
, "$EPSON_IPHOTO\n");
3574 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3579 case PPDC_DRIVER_HP
:
3580 cupsFilePuts(fp
, " ModelNumber ");
3581 switch (d
->model_number
)
3584 cupsFilePuts(fp
, "$HP_LASERJET\n");
3588 cupsFilePuts(fp
, "$HP_DESKJET\n");
3592 cupsFilePuts(fp
, "$HP_DESKJET2\n");
3596 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3600 cupsFilePuts(fp
, ")\n");
3604 cupsFilePrintf(fp
, " ModelNumber %d\n", d
->model_number
);
3609 if (d
->manual_copies
)
3610 cupsFilePuts(fp
, " ManualCopies Yes\n");
3612 if (d
->color_device
)
3613 cupsFilePuts(fp
, " ColorDevice Yes\n");
3616 cupsFilePrintf(fp
, " Throughput %d\n", d
->throughput
);
3618 // Output all of the attributes...
3619 for (a
= (ppdcAttr
*)d
->attrs
->first();
3621 a
= (ppdcAttr
*)d
->attrs
->next())
3622 if (a
->text
->value
&& a
->text
->value
[0])
3623 quotef(fp
, " Attribute \"%s\" \"%s/%s\" \"%s\"\n",
3624 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3625 a
->text
->value
, a
->value
->value
? a
->value
->value
: "");
3627 quotef(fp
, " Attribute \"%s\" \"%s\" \"%s\"\n",
3628 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3629 a
->value
->value
? a
->value
->value
: "");
3631 // Output all of the constraints...
3632 for (co
= (ppdcConstraint
*)d
->constraints
->first();
3634 co
= (ppdcConstraint
*)d
->constraints
->next())
3636 if (co
->option1
->value
[0] == '*')
3637 cupsFilePrintf(fp
, " UIConstraints \"%s %s", co
->option1
->value
,
3638 co
->choice1
->value
? co
->choice1
->value
: "");
3640 cupsFilePrintf(fp
, " UIConstraints \"*%s %s", co
->option1
->value
,
3641 co
->choice1
->value
? co
->choice1
->value
: "");
3643 if (co
->option2
->value
[0] == '*')
3644 cupsFilePrintf(fp
, " %s %s\"\n", co
->option2
->value
,
3645 co
->choice2
->value
? co
->choice2
->value
: "");
3647 cupsFilePrintf(fp
, " *%s %s\"\n", co
->option2
->value
,
3648 co
->choice2
->value
? co
->choice2
->value
: "");
3651 // Output all of the filters...
3652 for (fi
= (ppdcFilter
*)d
->filters
->first();
3654 fi
= (ppdcFilter
*)d
->filters
->next())
3655 cupsFilePrintf(fp
, " Filter \"%s %d %s\"\n",
3656 fi
->mime_type
->value
, fi
->cost
, fi
->program
->value
);
3658 // Output all of the fonts...
3659 for (fo
= (ppdcFont
*)d
->fonts
->first();
3661 fo
= (ppdcFont
*)d
->fonts
->next())
3662 if (!strcmp(fo
->name
->value
, "*"))
3663 cupsFilePuts(fp
, " Font *\n");
3665 cupsFilePrintf(fp
, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
3666 fo
->name
->value
, fo
->encoding
->value
,
3667 fo
->version
->value
, fo
->charset
->value
,
3668 fo
->status
== PPDC_FONT_ROM
? "ROM" : "Disk");
3670 // Output all options...
3671 for (g
= (ppdcGroup
*)d
->groups
->first();
3673 g
= (ppdcGroup
*)d
->groups
->next())
3675 if (g
->options
->count
== 0)
3678 if (g
->text
->value
&& g
->text
->value
[0])
3679 quotef(fp
, " Group \"%s/%s\"\n", g
->name
->value
, g
->text
->value
);
3681 cupsFilePrintf(fp
, " Group \"%s\"\n", g
->name
->value
);
3683 for (o
= (ppdcOption
*)g
->options
->first();
3685 o
= (ppdcOption
*)g
->options
->next())
3687 if (o
->choices
->count
== 0)
3690 if (o
->text
->value
&& o
->text
->value
[0])
3691 quotef(fp
, " Option \"%s/%s\"", o
->name
->value
, o
->text
->value
);
3693 cupsFilePrintf(fp
, " Option \"%s\"", o
->name
->value
);
3695 cupsFilePrintf(fp
, " %s %s %.1f\n",
3696 o
->type
== PPDC_BOOLEAN
? "Boolean" :
3697 o
->type
== PPDC_PICKONE
? "PickOne" : "PickMany",
3698 o
->section
== PPDC_SECTION_ANY
? "AnySetup" :
3699 o
->section
== PPDC_SECTION_DOCUMENT
? "DocumentSetup" :
3700 o
->section
== PPDC_SECTION_EXIT
? "ExitServer" :
3701 o
->section
== PPDC_SECTION_JCL
? "JCLSetup" :
3702 o
->section
== PPDC_SECTION_PAGE
? "PageSetup" :
3706 for (ch
= (ppdcChoice
*)o
->choices
->first();
3708 ch
= (ppdcChoice
*)o
->choices
->next())
3710 if (ch
->text
->value
&& ch
->text
->value
[0])
3711 quotef(fp
, " %sChoice \"%s/%s\" \"%s\"\n",
3712 o
->defchoice
== ch
->name
? "*" : "",
3713 ch
->name
->value
, ch
->text
->value
,
3714 ch
->code
->value
? ch
->code
->value
: "");
3716 quotef(fp
, " %sChoice \"%s\" \"%s\"\n",
3717 o
->defchoice
== ch
->name
? "*" : "",
3719 ch
->code
->value
? ch
->code
->value
: "");
3724 // Output all of the color profiles...
3725 for (p
= (ppdcProfile
*)d
->profiles
->first();
3727 p
= (ppdcProfile
*)d
->profiles
->next())
3728 cupsFilePrintf(fp
, " ColorProfile \"%s/%s\" %.3f %.3f "
3729 "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
3730 p
->resolution
->value
, p
->media_type
->value
,
3731 p
->density
, p
->gamma
,
3732 p
->profile
[0], p
->profile
[1], p
->profile
[2],
3733 p
->profile
[3], p
->profile
[4], p
->profile
[5],
3734 p
->profile
[6], p
->profile
[7], p
->profile
[8]);
3736 // Output all of the media sizes...
3742 for (si
= (ppdcMediaSize
*)d
->sizes
->first();
3744 si
= (ppdcMediaSize
*)d
->sizes
->next())
3745 if (si
->size_code
->value
&& si
->region_code
->value
)
3747 // Output a custom media size...
3748 quotef(fp
, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
3749 si
->name
== d
->default_size
? "*" : "", si
->name
->value
,
3750 si
->text
->value
, si
->width
, si
->length
, si
->left
, si
->bottom
,
3751 si
->right
, si
->top
, si
->size_code
->value
,
3752 si
->region_code
->value
);
3756 // Output a standard media size...
3757 if (fabs(left
- si
->left
) > 0.1 ||
3758 fabs(bottom
- si
->bottom
) > 0.1 ||
3759 fabs(right
- si
->right
) > 0.1 ||
3760 fabs(top
- si
->top
) > 0.1)
3762 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3763 si
->left
, si
->bottom
, si
->right
, si
->top
);
3766 bottom
= si
->bottom
;
3771 cupsFilePrintf(fp
, " %sMediaSize %s\n",
3772 si
->name
== d
->default_size
? "*" : "",
3776 if (d
->variable_paper_size
)
3778 cupsFilePuts(fp
, " VariablePaperSize Yes\n");
3780 if (fabs(left
- d
->left_margin
) > 0.1 ||
3781 fabs(bottom
- d
->bottom_margin
) > 0.1 ||
3782 fabs(right
- d
->right_margin
) > 0.1 ||
3783 fabs(top
- d
->top_margin
) > 0.1)
3785 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3786 d
->left_margin
, d
->bottom_margin
, d
->right_margin
,
3790 cupsFilePrintf(fp
, " MinSize %.2f %.2f\n", d
->min_width
, d
->min_length
);
3791 cupsFilePrintf(fp
, " MaxSize %.2f %.2f\n", d
->max_width
, d
->max_length
);
3794 // End the driver...
3795 cupsFilePuts(fp
, "}\n");
3798 // Close the file and return...