]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-source.cxx
2 // Source class for the CUPS PPD Compiler.
4 // Copyright 2007-2014 by Apple Inc.
5 // Copyright 2002-2007 by Easy Software Products.
7 // Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 // Include necessary headers...
14 #include "ppdc-private.h"
18 #include <cups/raster.h>
19 #include "data/epson.h"
21 #include "data/label.h"
23 # include <sys/utsname.h>
31 ppdcArray
*ppdcSource::includes
= 0;
32 const char *ppdcSource::driver_types
[] =
45 // 'ppdcSource::ppdcSource()' - Load a driver source file.
48 ppdcSource::ppdcSource(const char *f
, // I - File to read
49 cups_file_t
*ffp
)// I - File pointer to use
54 filename
= new ppdcString(f
);
55 base_fonts
= new ppdcArray();
56 drivers
= new ppdcArray();
57 po_files
= new ppdcArray();
58 sizes
= new ppdcArray();
59 vars
= new ppdcArray();
60 cond_state
= PPDC_COND_NORMAL
;
61 cond_current
= cond_stack
;
62 cond_stack
[0] = PPDC_COND_NORMAL
;
64 // Add standard #define variables...
65 #define MAKE_STRING(x) #x
67 vars
->add(new ppdcVariable("CUPS_VERSION", MAKE_STRING(CUPS_VERSION
)));
68 vars
->add(new ppdcVariable("CUPS_VERSION_MAJOR", MAKE_STRING(CUPS_VERSION_MAJOR
)));
69 vars
->add(new ppdcVariable("CUPS_VERSION_MINOR", MAKE_STRING(CUPS_VERSION_MINOR
)));
70 vars
->add(new ppdcVariable("CUPS_VERSION_PATCH", MAKE_STRING(CUPS_VERSION_PATCH
)));
73 vars
->add(new ppdcVariable("PLATFORM_NAME", "Windows"));
74 vars
->add(new ppdcVariable("PLATFORM_ARCH", "X86"));
77 struct utsname name
; // uname information
81 vars
->add(new ppdcVariable("PLATFORM_NAME", name
.sysname
));
82 vars
->add(new ppdcVariable("PLATFORM_ARCH", name
.machine
));
86 vars
->add(new ppdcVariable("PLATFORM_NAME", "unknown"));
87 vars
->add(new ppdcVariable("PLATFORM_ARCH", "unknown"));
97 // 'ppdcSource::~ppdcSource()' - Free a driver source file.
100 ppdcSource::~ppdcSource()
105 base_fonts
->release();
114 // 'ppdcSource::add_include()' - Add an include directory.
118 ppdcSource::add_include(const char *d
) // I - Include directory
124 includes
= new ppdcArray();
126 includes
->add(new ppdcString(d
));
131 // 'ppdcSource::find_driver()' - Find a driver.
134 ppdcDriver
* // O - Driver
135 ppdcSource::find_driver(const char *f
) // I - Driver file name
137 ppdcDriver
*d
; // Current driver
140 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
141 if (!_cups_strcasecmp(f
, d
->pc_file_name
->value
))
149 // 'ppdcSource::find_include()' - Find an include file.
152 char * // O - Found path or NULL
153 ppdcSource::find_include(
154 const char *f
, // I - Include filename
155 const char *base
, // I - Current directory
156 char *n
, // I - Path buffer
157 int nlen
) // I - Path buffer length
159 ppdcString
*dir
; // Include directory
160 char temp
[1024], // Temporary path
161 *ptr
; // Pointer to end of path
164 // Range check input...
165 if (!f
|| !*f
|| !n
|| nlen
< 2)
168 // Check the first character to see if we have <name> or "name"...
171 // Remove the surrounding <> from the name...
172 strlcpy(temp
, f
+ 1, sizeof(temp
));
173 ptr
= temp
+ strlen(temp
) - 1;
177 _cupsLangPrintf(stderr
,
178 _("ppdc: Invalid #include/#po filename \"%s\"."), n
);
187 // Check for the local file relative to the current directory...
188 if (base
&& *base
&& f
[0] != '/')
189 snprintf(n
, (size_t)nlen
, "%s/%s", base
, f
);
191 strlcpy(n
, f
, (size_t)nlen
);
197 // Absolute path that doesn't exist...
202 // Search the include directories, if any...
205 for (dir
= (ppdcString
*)includes
->first(); dir
; dir
= (ppdcString
*)includes
->next())
207 snprintf(n
, (size_t)nlen
, "%s/%s", dir
->value
, f
);
213 // Search the standard include directories...
214 _cups_globals_t
*cg
= _cupsGlobals(); // Global data
216 snprintf(n
, (size_t)nlen
, "%s/ppdc/%s", cg
->cups_datadir
, f
);
220 snprintf(n
, (size_t)nlen
, "%s/po/%s", cg
->cups_datadir
, f
);
229 // 'ppdcSource::find_po()' - Find a message catalog for the given locale.
232 ppdcCatalog
* // O - Message catalog or NULL
233 ppdcSource::find_po(const char *l
) // I - Locale name
235 ppdcCatalog
*cat
; // Current message catalog
238 for (cat
= (ppdcCatalog
*)po_files
->first();
240 cat
= (ppdcCatalog
*)po_files
->next())
241 if (!_cups_strcasecmp(l
, cat
->locale
->value
))
249 // 'ppdcSource::find_size()' - Find a media size.
252 ppdcMediaSize
* // O - Size
253 ppdcSource::find_size(const char *s
) // I - Size name
255 ppdcMediaSize
*m
; // Current media size
258 for (m
= (ppdcMediaSize
*)sizes
->first(); m
; m
= (ppdcMediaSize
*)sizes
->next())
259 if (!_cups_strcasecmp(s
, m
->name
->value
))
267 // 'ppdcSource::find_variable()' - Find a variable.
270 ppdcVariable
* // O - Variable
271 ppdcSource::find_variable(const char *n
)// I - Variable name
273 ppdcVariable
*v
; // Current variable
276 for (v
= (ppdcVariable
*)vars
->first(); v
; v
= (ppdcVariable
*)vars
->next())
277 if (!_cups_strcasecmp(n
, v
->name
->value
))
285 // 'ppdcSource::get_attr()' - Get an attribute.
288 ppdcAttr
* // O - Attribute
289 ppdcSource::get_attr(ppdcFile
*fp
, // I - File to read
290 bool loc
) // I - Localize this attribute?
292 char name
[1024], // Name string
293 selector
[1024], // Selector string
294 *text
, // Text string
295 value
[1024]; // Value string
298 // Get the attribute parameters:
300 // Attribute name selector value
301 if (!get_token(fp
, name
, sizeof(name
)))
303 _cupsLangPrintf(stderr
,
304 _("ppdc: Expected name after %s on line %d of %s."),
305 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
309 if (!get_token(fp
, selector
, sizeof(selector
)))
311 _cupsLangPrintf(stderr
,
312 _("ppdc: Expected selector after %s on line %d of %s."),
313 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
317 if ((text
= strchr(selector
, '/')) != NULL
)
320 if (!get_token(fp
, value
, sizeof(value
)))
322 _cupsLangPrintf(stderr
,
323 _("ppdc: Expected value after %s on line %d of %s."),
324 loc
? "LocAttribute" : "Attribute", fp
->line
, fp
->filename
);
328 return (new ppdcAttr(name
, selector
, text
, value
, loc
));
333 // 'ppdcSource::get_boolean()' - Get a boolean value.
336 int // O - Boolean value
337 ppdcSource::get_boolean(ppdcFile
*fp
) // I - File to read
339 char buffer
[256]; // String buffer
342 if (!get_token(fp
, buffer
, sizeof(buffer
)))
344 _cupsLangPrintf(stderr
,
345 _("ppdc: Expected boolean value on line %d of %s."),
346 fp
->line
, fp
->filename
);
350 if (!_cups_strcasecmp(buffer
, "on") ||
351 !_cups_strcasecmp(buffer
, "yes") ||
352 !_cups_strcasecmp(buffer
, "true"))
354 else if (!_cups_strcasecmp(buffer
, "off") ||
355 !_cups_strcasecmp(buffer
, "no") ||
356 !_cups_strcasecmp(buffer
, "false"))
360 _cupsLangPrintf(stderr
,
361 _("ppdc: Bad boolean value (%s) on line %d of %s."),
362 buffer
, fp
->line
, fp
->filename
);
369 // 'ppdcSource::get_choice()' - Get a choice.
372 ppdcChoice
* // O - Choice data
373 ppdcSource::get_choice(ppdcFile
*fp
) // I - File to read
375 char name
[1024], // Name
380 // Read a choice from the file:
382 // Choice name/text code
383 if (!get_token(fp
, name
, sizeof(name
)))
385 _cupsLangPrintf(stderr
,
386 _("ppdc: Expected choice name/text on line %d of %s."),
387 fp
->line
, fp
->filename
);
391 if ((text
= strchr(name
, '/')) != NULL
)
396 if (!get_token(fp
, code
, sizeof(code
)))
398 _cupsLangPrintf(stderr
, _("ppdc: Expected choice code on line %d of %s."),
399 fp
->line
, fp
->filename
);
403 // Return the new choice
404 return (new ppdcChoice(name
, text
, code
));
409 // 'ppdcSource::get_color_model()' - Get an old-style color model option.
412 ppdcChoice
* // O - Choice data
413 ppdcSource::get_color_model(ppdcFile
*fp
)
416 char name
[1024], // Option name
417 *text
, // Text option
418 temp
[256]; // Temporary string
419 int color_space
, // Colorspace
420 color_order
, // Color order
421 compression
; // Compression mode
424 // Get the ColorModel parameters:
426 // ColorModel name/text colorspace colororder compression
427 if (!get_token(fp
, name
, sizeof(name
)))
429 _cupsLangPrintf(stderr
,
430 _("ppdc: Expected name/text combination for ColorModel on "
431 "line %d of %s."), fp
->line
, fp
->filename
);
435 if ((text
= strchr(name
, '/')) != NULL
)
440 if (!get_token(fp
, temp
, sizeof(temp
)))
442 _cupsLangPrintf(stderr
,
443 _("ppdc: Expected colorspace for ColorModel on line %d of "
444 "%s."), fp
->line
, fp
->filename
);
448 if ((color_space
= get_color_space(temp
)) < 0)
449 color_space
= get_integer(temp
);
451 if (!get_token(fp
, temp
, sizeof(temp
)))
453 _cupsLangPrintf(stderr
,
454 _("ppdc: Expected color order for ColorModel on line %d of "
455 "%s."), fp
->line
, fp
->filename
);
459 if ((color_order
= get_color_order(temp
)) < 0)
460 color_order
= get_integer(temp
);
462 if (!get_token(fp
, temp
, sizeof(temp
)))
464 _cupsLangPrintf(stderr
,
465 _("ppdc: Expected compression for ColorModel on line %d of "
466 "%s."), fp
->line
, fp
->filename
);
470 compression
= get_integer(temp
);
472 snprintf(temp
, sizeof(temp
),
473 "<</cupsColorSpace %d/cupsColorOrder %d/cupsCompression %d>>"
475 color_space
, color_order
, compression
);
477 return (new ppdcChoice(name
, text
, temp
));
482 // 'ppdcSource::get_color_order()' - Get an old-style color order value.
485 int // O - Color order value
486 ppdcSource::get_color_order(
487 const char *co
) // I - Color order string
489 if (!_cups_strcasecmp(co
, "chunked") ||
490 !_cups_strcasecmp(co
, "chunky"))
491 return (CUPS_ORDER_CHUNKED
);
492 else if (!_cups_strcasecmp(co
, "banded"))
493 return (CUPS_ORDER_BANDED
);
494 else if (!_cups_strcasecmp(co
, "planar"))
495 return (CUPS_ORDER_PLANAR
);
502 // 'ppdcSource::get_color_profile()' - Get a color profile definition.
505 ppdcProfile
* // O - Color profile
506 ppdcSource::get_color_profile(
507 ppdcFile
*fp
) // I - File to read
509 char resolution
[1024], // Resolution/media type
510 *media_type
; // Media type
511 int i
; // Looping var
512 float g
, // Gamma value
514 m
[9]; // Transform matrix
517 // Get the ColorProfile parameters:
519 // ColorProfile resolution/mediatype gamma density m00 m01 m02 ... m22
520 if (!get_token(fp
, resolution
, sizeof(resolution
)))
522 _cupsLangPrintf(stderr
,
523 _("ppdc: Expected resolution/mediatype following "
524 "ColorProfile on line %d of %s."),
525 fp
->line
, fp
->filename
);
529 if ((media_type
= strchr(resolution
, '/')) != NULL
)
530 *media_type
++ = '\0';
532 media_type
= resolution
;
536 for (i
= 0; i
< 9; i
++)
537 m
[i
] = get_float(fp
);
539 return (new ppdcProfile(resolution
, media_type
, g
, d
, m
));
544 // 'ppdcSource::get_color_space()' - Get an old-style colorspace value.
547 int // O - Colorspace value
548 ppdcSource::get_color_space(
549 const char *cs
) // I - Colorspace string
551 if (!_cups_strcasecmp(cs
, "w"))
552 return (CUPS_CSPACE_W
);
553 else if (!_cups_strcasecmp(cs
, "rgb"))
554 return (CUPS_CSPACE_RGB
);
555 else if (!_cups_strcasecmp(cs
, "rgba"))
556 return (CUPS_CSPACE_RGBA
);
557 else if (!_cups_strcasecmp(cs
, "k"))
558 return (CUPS_CSPACE_K
);
559 else if (!_cups_strcasecmp(cs
, "cmy"))
560 return (CUPS_CSPACE_CMY
);
561 else if (!_cups_strcasecmp(cs
, "ymc"))
562 return (CUPS_CSPACE_YMC
);
563 else if (!_cups_strcasecmp(cs
, "cmyk"))
564 return (CUPS_CSPACE_CMYK
);
565 else if (!_cups_strcasecmp(cs
, "ymck"))
566 return (CUPS_CSPACE_YMCK
);
567 else if (!_cups_strcasecmp(cs
, "kcmy"))
568 return (CUPS_CSPACE_KCMY
);
569 else if (!_cups_strcasecmp(cs
, "kcmycm"))
570 return (CUPS_CSPACE_KCMYcm
);
571 else if (!_cups_strcasecmp(cs
, "gmck"))
572 return (CUPS_CSPACE_GMCK
);
573 else if (!_cups_strcasecmp(cs
, "gmcs"))
574 return (CUPS_CSPACE_GMCS
);
575 else if (!_cups_strcasecmp(cs
, "white"))
576 return (CUPS_CSPACE_WHITE
);
577 else if (!_cups_strcasecmp(cs
, "gold"))
578 return (CUPS_CSPACE_GOLD
);
579 else if (!_cups_strcasecmp(cs
, "silver"))
580 return (CUPS_CSPACE_SILVER
);
581 else if (!_cups_strcasecmp(cs
, "CIEXYZ"))
582 return (CUPS_CSPACE_CIEXYZ
);
583 else if (!_cups_strcasecmp(cs
, "CIELab"))
584 return (CUPS_CSPACE_CIELab
);
585 else if (!_cups_strcasecmp(cs
, "RGBW"))
586 return (CUPS_CSPACE_RGBW
);
587 else if (!_cups_strcasecmp(cs
, "ICC1"))
588 return (CUPS_CSPACE_ICC1
);
589 else if (!_cups_strcasecmp(cs
, "ICC2"))
590 return (CUPS_CSPACE_ICC2
);
591 else if (!_cups_strcasecmp(cs
, "ICC3"))
592 return (CUPS_CSPACE_ICC3
);
593 else if (!_cups_strcasecmp(cs
, "ICC4"))
594 return (CUPS_CSPACE_ICC4
);
595 else if (!_cups_strcasecmp(cs
, "ICC5"))
596 return (CUPS_CSPACE_ICC5
);
597 else if (!_cups_strcasecmp(cs
, "ICC6"))
598 return (CUPS_CSPACE_ICC6
);
599 else if (!_cups_strcasecmp(cs
, "ICC7"))
600 return (CUPS_CSPACE_ICC7
);
601 else if (!_cups_strcasecmp(cs
, "ICC8"))
602 return (CUPS_CSPACE_ICC8
);
603 else if (!_cups_strcasecmp(cs
, "ICC9"))
604 return (CUPS_CSPACE_ICC9
);
605 else if (!_cups_strcasecmp(cs
, "ICCA"))
606 return (CUPS_CSPACE_ICCA
);
607 else if (!_cups_strcasecmp(cs
, "ICCB"))
608 return (CUPS_CSPACE_ICCB
);
609 else if (!_cups_strcasecmp(cs
, "ICCC"))
610 return (CUPS_CSPACE_ICCC
);
611 else if (!_cups_strcasecmp(cs
, "ICCD"))
612 return (CUPS_CSPACE_ICCD
);
613 else if (!_cups_strcasecmp(cs
, "ICCE"))
614 return (CUPS_CSPACE_ICCE
);
615 else if (!_cups_strcasecmp(cs
, "ICCF"))
616 return (CUPS_CSPACE_ICCF
);
623 // 'ppdcSource::get_constraint()' - Get a constraint.
626 ppdcConstraint
* // O - Constraint
627 ppdcSource::get_constraint(ppdcFile
*fp
)// I - File to read
629 char temp
[1024], // One string to rule them all
630 *ptr
, // Pointer into string
631 *option1
, // Constraint option 1
632 *choice1
, // Constraint choice 1
633 *option2
, // Constraint option 2
634 *choice2
; // Constraint choice 2
637 // Read the UIConstaints parameter in one of the following forms:
639 // UIConstraints "*Option1 *Option2"
640 // UIConstraints "*Option1 Choice1 *Option2"
641 // UIConstraints "*Option1 *Option2 Choice2"
642 // UIConstraints "*Option1 Choice1 *Option2 Choice2"
643 if (!get_token(fp
, temp
, sizeof(temp
)))
645 _cupsLangPrintf(stderr
,
646 _("ppdc: Expected constraints string for UIConstraints on "
647 "line %d of %s."), fp
->line
, fp
->filename
);
651 for (ptr
= temp
; isspace(*ptr
); ptr
++);
655 _cupsLangPrintf(stderr
,
656 _("ppdc: Option constraint must *name on line %d of %s."),
657 fp
->line
, fp
->filename
);
663 for (; *ptr
&& !isspace(*ptr
); ptr
++);
664 for (; isspace(*ptr
); *ptr
++ = '\0');
670 for (; *ptr
&& !isspace(*ptr
); ptr
++);
671 for (; isspace(*ptr
); *ptr
++ = '\0');
678 _cupsLangPrintf(stderr
,
679 _("ppdc: Expected two option names on line %d of %s."),
680 fp
->line
, fp
->filename
);
686 for (; *ptr
&& !isspace(*ptr
); ptr
++);
687 for (; isspace(*ptr
); *ptr
++ = '\0');
694 return (new ppdcConstraint(option1
, choice1
, option2
, choice2
));
699 // 'ppdcSource::get_custom_size()' - Get a custom media size definition from a file.
702 ppdcMediaSize
* // O - Media size
703 ppdcSource::get_custom_size(ppdcFile
*fp
)
706 char name
[1024], // Name
708 size_code
[10240], // PageSize code
709 region_code
[10240]; // PageRegion
710 float width
, // Width
713 bottom
, // Bottom margin
714 right
, // Right margin
718 // Get the name, text, width, length, margins, and code:
720 // CustomMedia name/text width length left bottom right top size-code region-code
721 if (!get_token(fp
, name
, sizeof(name
)))
724 if ((text
= strchr(name
, '/')) != NULL
)
729 if ((width
= get_measurement(fp
)) < 0.0f
)
732 if ((length
= get_measurement(fp
)) < 0.0f
)
735 if ((left
= get_measurement(fp
)) < 0.0f
)
738 if ((bottom
= get_measurement(fp
)) < 0.0f
)
741 if ((right
= get_measurement(fp
)) < 0.0f
)
744 if ((top
= get_measurement(fp
)) < 0.0f
)
747 if (!get_token(fp
, size_code
, sizeof(size_code
)))
750 if (!get_token(fp
, region_code
, sizeof(region_code
)))
753 // Return the new media size...
754 return (new ppdcMediaSize(name
, text
, width
, length
, left
, bottom
,
755 right
, top
, size_code
, region_code
));
760 // 'ppdcSource::get_duplex()' - Get a duplex option.
764 ppdcSource::get_duplex(ppdcFile
*fp
, // I - File to read from
765 ppdcDriver
*d
) // I - Current driver
767 char temp
[256]; // Duplex keyword
768 ppdcAttr
*attr
; // cupsFlipDuplex attribute
769 ppdcGroup
*g
; // Current group
770 ppdcOption
*o
; // Duplex option
773 // Duplex {boolean|none|normal|flip}
774 if (!get_token(fp
, temp
, sizeof(temp
)))
776 _cupsLangPrintf(stderr
,
777 _("ppdc: Expected duplex type after Duplex on line %d of "
778 "%s."), fp
->line
, fp
->filename
);
785 if (!_cups_strcasecmp(temp
, "none") || !_cups_strcasecmp(temp
, "false") ||
786 !_cups_strcasecmp(temp
, "no") || !_cups_strcasecmp(temp
, "off"))
788 g
= d
->find_group("General");
789 if ((o
= g
->find_option("Duplex")) != NULL
)
790 g
->options
->remove(o
);
792 for (attr
= (ppdcAttr
*)d
->attrs
->first();
794 attr
= (ppdcAttr
*)d
->attrs
->next())
795 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
797 d
->attrs
->remove(attr
);
801 else if (!_cups_strcasecmp(temp
, "normal") || !_cups_strcasecmp(temp
, "true") ||
802 !_cups_strcasecmp(temp
, "yes") || !_cups_strcasecmp(temp
, "on") ||
803 !_cups_strcasecmp(temp
, "flip") || !_cups_strcasecmp(temp
, "rotated") ||
804 !_cups_strcasecmp(temp
, "manualtumble"))
806 g
= d
->find_group("General");
807 o
= g
->find_option("Duplex");
811 o
= new ppdcOption(PPDC_PICKONE
, "Duplex", "2-Sided Printing",
812 !_cups_strcasecmp(temp
, "flip") ? PPDC_SECTION_PAGE
:
813 PPDC_SECTION_ANY
, 10.0f
);
814 o
->add_choice(new ppdcChoice("None", "Off (1-Sided)",
815 "<</Duplex false>>setpagedevice"));
816 o
->add_choice(new ppdcChoice("DuplexNoTumble", "Long-Edge (Portrait)",
817 "<</Duplex true/Tumble false>>setpagedevice"));
818 o
->add_choice(new ppdcChoice("DuplexTumble", "Short-Edge (Landscape)",
819 "<</Duplex true/Tumble true>>setpagedevice"));
824 for (attr
= (ppdcAttr
*)d
->attrs
->first();
826 attr
= (ppdcAttr
*)d
->attrs
->next())
827 if (!strcmp(attr
->name
->value
, "cupsFlipDuplex"))
829 if (_cups_strcasecmp(temp
, "flip"))
830 d
->attrs
->remove(attr
);
834 if (!_cups_strcasecmp(temp
, "flip") && !attr
)
835 d
->add_attr(new ppdcAttr("cupsFlipDuplex", NULL
, NULL
, "true"));
837 for (attr
= (ppdcAttr
*)d
->attrs
->first();
839 attr
= (ppdcAttr
*)d
->attrs
->next())
840 if (!strcmp(attr
->name
->value
, "cupsBackSide"))
842 d
->attrs
->remove(attr
);
846 if (!_cups_strcasecmp(temp
, "flip"))
847 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Flipped"));
848 else if (!_cups_strcasecmp(temp
, "rotated"))
849 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Rotated"));
850 else if (!_cups_strcasecmp(temp
, "manualtumble"))
851 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "ManualTumble"));
853 d
->add_attr(new ppdcAttr("cupsBackSide", NULL
, NULL
, "Normal"));
856 _cupsLangPrintf(stderr
,
857 _("ppdc: Unknown duplex type \"%s\" on line %d of %s."),
858 temp
, fp
->line
, fp
->filename
);
863 // 'ppdcSource::get_filter()' - Get a filter.
866 ppdcFilter
* // O - Filter
867 ppdcSource::get_filter(ppdcFile
*fp
) // I - File to read
869 char type
[1024], // MIME type
870 program
[1024], // Filter program
871 *ptr
; // Pointer into MIME type
872 int cost
; // Relative cost
875 // Read filter parameters in one of the following formats:
877 // Filter "type cost program"
878 // Filter type cost program
880 if (!get_token(fp
, type
, sizeof(type
)))
882 _cupsLangPrintf(stderr
,
883 _("ppdc: Expected a filter definition on line %d of %s."),
884 fp
->line
, fp
->filename
);
888 if ((ptr
= strchr(type
, ' ')) != NULL
)
890 // Old-style filter definition in one string...
892 cost
= strtol(ptr
, &ptr
, 10);
894 while (isspace(*ptr
))
897 strlcpy(program
, ptr
, sizeof(program
));
901 cost
= get_integer(fp
);
903 if (!get_token(fp
, program
, sizeof(program
)))
905 _cupsLangPrintf(stderr
,
906 _("ppdc: Expected a program name on line %d of %s."),
907 fp
->line
, fp
->filename
);
914 _cupsLangPrintf(stderr
,
915 _("ppdc: Invalid empty MIME type for filter on line %d of "
916 "%s."), fp
->line
, fp
->filename
);
920 if (cost
< 0 || cost
> 200)
922 _cupsLangPrintf(stderr
,
923 _("ppdc: Invalid cost for filter on line %d of %s."),
924 fp
->line
, fp
->filename
);
930 _cupsLangPrintf(stderr
,
931 _("ppdc: Invalid empty program name for filter on line %d "
932 "of %s."), fp
->line
, fp
->filename
);
936 return (new ppdcFilter(type
, program
, cost
));
941 // 'ppdcSource::get_float()' - Get a single floating-point number.
945 ppdcSource::get_float(ppdcFile
*fp
) // I - File to read
947 char temp
[256], // String buffer
948 *ptr
; // Pointer into buffer
949 float val
; // Floating point value
952 // Get the number from the file and range-check...
953 if (!get_token(fp
, temp
, sizeof(temp
)))
955 _cupsLangPrintf(stderr
, _("ppdc: Expected real number on line %d of %s."),
956 fp
->line
, fp
->filename
);
960 val
= (float)strtod(temp
, &ptr
);
964 _cupsLangPrintf(stderr
,
965 _("ppdc: Unknown trailing characters in real number \"%s\" "
966 "on line %d of %s."), temp
, fp
->line
, fp
->filename
);
975 // 'ppdcSource::get_font()' - Get a font definition.
978 ppdcFont
* // O - Font data
979 ppdcSource::get_font(ppdcFile
*fp
) // I - File to read
981 char name
[256], // Font name
982 encoding
[256], // Font encoding
983 version
[256], // Font version
984 charset
[256], // Font charset
985 temp
[256]; // Font status string
986 ppdcFontStatus status
; // Font status enumeration
989 // Read font parameters as follows:
992 // Font name encoding version charset status
993 // %font name encoding version charset status
995 // "Name" is the PostScript font name.
997 // "Encoding" is the default encoding of the font: Standard, ISOLatin1,
998 // Special, Expert, ExpertSubset, etc.
1000 // "Version" is the version number string.
1002 // "Charset" specifies the characters that are included in the font:
1003 // Standard, Special, Expert, Adobe-Identity, etc.
1005 // "Status" is the keyword ROM or Disk.
1006 if (!get_token(fp
, name
, sizeof(name
)))
1008 _cupsLangPrintf(stderr
,
1009 _("ppdc: Expected name after Font on line %d of %s."),
1010 fp
->line
, fp
->filename
);
1014 if (!strcmp(name
, "*"))
1016 // Include all base fonts...
1020 status
= PPDC_FONT_ROM
;
1024 // Load a full font definition...
1025 if (!get_token(fp
, encoding
, sizeof(encoding
)))
1027 _cupsLangPrintf(stderr
,
1028 _("ppdc: Expected encoding after Font on line %d of "
1029 "%s."), fp
->line
, fp
->filename
);
1033 if (!get_token(fp
, version
, sizeof(version
)))
1035 _cupsLangPrintf(stderr
,
1036 _("ppdc: Expected version after Font on line %d of "
1037 "%s."), fp
->line
, fp
->filename
);
1041 if (!get_token(fp
, charset
, sizeof(charset
)))
1043 _cupsLangPrintf(stderr
,
1044 _("ppdc: Expected charset after Font on line %d of "
1045 "%s."), fp
->line
, fp
->filename
);
1049 if (!get_token(fp
, temp
, sizeof(temp
)))
1051 _cupsLangPrintf(stderr
,
1052 _("ppdc: Expected status after Font on line %d of %s."),
1053 fp
->line
, fp
->filename
);
1057 if (!_cups_strcasecmp(temp
, "ROM"))
1058 status
= PPDC_FONT_ROM
;
1059 else if (!_cups_strcasecmp(temp
, "Disk"))
1060 status
= PPDC_FONT_DISK
;
1063 _cupsLangPrintf(stderr
,
1064 _("ppdc: Bad status keyword %s on line %d of %s."),
1065 temp
, fp
->line
, fp
->filename
);
1070 // printf("Font %s %s %s %s %s\n", name, encoding, version, charset, temp);
1072 return (new ppdcFont(name
, encoding
, version
, charset
, status
));
1077 // 'ppdcSource::get_generic()' - Get a generic old-style option.
1080 ppdcChoice
* // O - Choice data
1081 ppdcSource::get_generic(ppdcFile
*fp
, // I - File to read
1082 const char *keyword
,
1085 // I - Text attribute
1087 // I - Numeric attribute
1089 char name
[1024], // Name
1091 command
[256]; // Command string
1092 int val
; // Numeric value
1095 // Read one of the following parameters:
1098 // Foo integer name/text
1100 val
= get_integer(fp
);
1104 if (!get_token(fp
, name
, sizeof(name
)))
1106 _cupsLangPrintf(stderr
,
1107 _("ppdc: Expected name/text after %s on line %d of %s."),
1108 keyword
, fp
->line
, fp
->filename
);
1112 if ((text
= strchr(name
, '/')) != NULL
)
1120 snprintf(command
, sizeof(command
),
1121 "<</%s(%s)/%s %d>>setpagedevice",
1122 tattr
, name
, nattr
, val
);
1124 snprintf(command
, sizeof(command
),
1125 "<</%s %d>>setpagedevice",
1129 snprintf(command
, sizeof(command
),
1130 "<</%s(%s)>>setpagedevice",
1133 return (new ppdcChoice(name
, text
, command
));
1138 // 'ppdcSource::get_group()' - Get an option group.
1141 ppdcGroup
* // O - Group
1142 ppdcSource::get_group(ppdcFile
*fp
, // I - File to read
1143 ppdcDriver
*d
) // I - Printer driver
1145 char name
[1024], // UI name
1147 ppdcGroup
*g
; // Group
1150 // Read the Group parameters:
1153 if (!get_token(fp
, name
, sizeof(name
)))
1155 _cupsLangPrintf(stderr
,
1156 _("ppdc: Expected group name/text on line %d of %s."),
1157 fp
->line
, fp
->filename
);
1161 if ((text
= strchr(name
, '/')) != NULL
)
1166 // See if the group already exists...
1167 if ((g
= d
->find_group(name
)) == NULL
)
1169 // Nope, add a new one...
1170 g
= new ppdcGroup(name
, text
);
1178 // 'ppdcSource::get_installable()' - Get an installable option.
1181 ppdcOption
* // O - Option
1182 ppdcSource::get_installable(ppdcFile
*fp
)
1185 char name
[1024], // Name for installable option
1186 *text
; // Text for installable option
1187 ppdcOption
*o
; // Option
1190 // Read the parameter for an installable option:
1192 // Installable name/text
1193 if (!get_token(fp
, name
, sizeof(name
)))
1195 _cupsLangPrintf(stderr
,
1196 _("ppdc: Expected name/text after Installable on line %d "
1197 "of %s."), fp
->line
, fp
->filename
);
1201 if ((text
= strchr(name
, '/')) != NULL
)
1206 // Create the option...
1207 o
= new ppdcOption(PPDC_BOOLEAN
, name
, text
, PPDC_SECTION_ANY
, 10.0f
);
1209 // Add the false and true choices...
1210 o
->add_choice(new ppdcChoice("False", "Not Installed", ""));
1211 o
->add_choice(new ppdcChoice("True", "Installed", ""));
1218 // 'ppdcSource::get_integer()' - Get an integer value from a string.
1221 #define PPDC_XX -1 // Bad
1222 #define PPDC_EQ 0 // ==
1223 #define PPDC_NE 1 // !=
1224 #define PPDC_LT 2 // <
1225 #define PPDC_LE 3 // <=
1226 #define PPDC_GT 4 // >
1227 #define PPDC_GE 5 // >=
1229 int // O - Integer value
1230 ppdcSource::get_integer(const char *v
) // I - Value string
1233 long temp
, // Temporary value
1234 temp2
; // Second temporary value
1235 char *newv
, // New value string pointer
1236 ch
; // Temporary character
1237 ppdcVariable
*var
; // #define variable
1238 int compop
; // Comparison operator
1241 // Parse the value string...
1245 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1247 // Return a simple integer value
1248 val
= strtol(v
, (char **)&v
, 0);
1249 if (*v
|| val
== LONG_MIN
)
1256 // Evaluate and expression in any of the following formats:
1258 // (number number ... number) Bitwise OR of all numbers
1259 // (NAME == value) 1 if equal, 0 otherwise
1260 // (NAME != value) 1 if not equal, 0 otherwise
1261 // (NAME < value) 1 if less than, 0 otherwise
1262 // (NAME <= value) 1 if less than or equal, 0 otherwise
1263 // (NAME > value) 1 if greater than, 0 otherwise
1264 // (NAME >= value) 1 if greater than or equal, 0 otherwise
1269 while (*v
&& *v
!= ')')
1271 // Skip leading whitespace...
1272 while (*v
&& isspace(*v
& 255))
1275 if (!*v
|| *v
== ')')
1278 if (isdigit(*v
& 255) || *v
== '-' || *v
== '+')
1280 // Bitwise OR a number...
1281 temp
= strtol(v
, &newv
, 0);
1283 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1289 // NAME logicop value
1290 for (newv
= (char *)v
+ 1;
1291 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1298 if ((var
= find_variable(v
)) != NULL
)
1300 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1302 else if (isdigit(var
->value
->value
[0] & 255) ||
1303 var
->value
->value
[0] == '-' ||
1304 var
->value
->value
[0] == '+')
1305 temp
= strtol(var
->value
->value
, NULL
, 0);
1313 while (isspace(*newv
& 255))
1316 if (!strncmp(newv
, "==", 2))
1321 else if (!strncmp(newv
, "!=", 2))
1326 else if (!strncmp(newv
, "<=", 2))
1331 else if (*newv
== '<')
1336 else if (!strncmp(newv
, ">=", 2))
1341 else if (*newv
== '>')
1349 if (compop
!= PPDC_XX
)
1351 while (isspace(*newv
& 255))
1354 if (*newv
== ')' || !*newv
)
1357 if (isdigit(*newv
& 255) || *newv
== '-' || *newv
== '+')
1359 // Get the second number...
1360 temp2
= strtol(newv
, &newv
, 0);
1361 if (!*newv
|| newv
== v
|| !(isspace(*newv
) || *newv
== ')') ||
1367 // Lookup the second name...
1368 for (v
= newv
, newv
++;
1369 *newv
&& (isalnum(*newv
& 255) || *newv
== '_');
1375 if ((var
= find_variable(v
)) != NULL
)
1377 if (!var
->value
|| !var
->value
->value
|| !var
->value
->value
[0])
1379 else if (isdigit(var
->value
->value
[0] & 255) ||
1380 var
->value
->value
[0] == '-' ||
1381 var
->value
->value
[0] == '+')
1382 temp2
= strtol(var
->value
->value
, NULL
, 0);
1392 // Do the comparison...
1396 temp
= temp
== temp2
;
1399 temp
= temp
!= temp2
;
1402 temp
= temp
< temp2
;
1405 temp
= temp
<= temp2
;
1408 temp
= temp
> temp2
;
1411 temp
= temp
>= temp2
;
1421 if (*v
== ')' && !v
[1])
1426 else if ((var
= find_variable(v
)) != NULL
)
1428 // NAME by itself returns 1 if the #define variable is not blank and
1430 return (var
->value
->value
&& var
->value
->value
[0] &&
1431 strcmp(var
->value
->value
, "0"));
1435 // Anything else is an error...
1442 // 'ppdcSource::get_integer()' - Get an integer value from a file.
1445 int // O - Integer value
1446 ppdcSource::get_integer(ppdcFile
*fp
) // I - File to read
1448 char temp
[1024]; // String buffer
1451 if (!get_token(fp
, temp
, sizeof(temp
)))
1453 _cupsLangPrintf(stderr
, _("ppdc: Expected integer on line %d of %s."),
1454 fp
->line
, fp
->filename
);
1458 return (get_integer(temp
));
1463 // 'ppdcSource::get_measurement()' - Get a measurement value.
1466 float // O - Measurement value in points
1467 ppdcSource::get_measurement(ppdcFile
*fp
)
1470 char buffer
[256], // Number buffer
1471 *ptr
; // Pointer into buffer
1472 float val
; // Measurement value
1475 // Grab a token from the file...
1476 if (!get_token(fp
, buffer
, sizeof(buffer
)))
1479 // Get the floating point value of "s" and skip all digits and decimal points.
1480 val
= (float)strtod(buffer
, &ptr
);
1482 // Check for a trailing unit specifier...
1483 if (!_cups_strcasecmp(ptr
, "mm"))
1484 val
*= 72.0f
/ 25.4f
;
1485 else if (!_cups_strcasecmp(ptr
, "cm"))
1486 val
*= 72.0f
/ 2.54f
;
1487 else if (!_cups_strcasecmp(ptr
, "m"))
1488 val
*= 72.0f
/ 0.0254f
;
1489 else if (!_cups_strcasecmp(ptr
, "in"))
1491 else if (!_cups_strcasecmp(ptr
, "ft"))
1492 val
*= 72.0f
* 12.0f
;
1493 else if (_cups_strcasecmp(ptr
, "pt") && *ptr
)
1501 // 'ppdcSource::get_option()' - Get an option definition.
1504 ppdcOption
* // O - Option
1505 ppdcSource::get_option(ppdcFile
*fp
, // I - File to read
1506 ppdcDriver
*d
, // I - Printer driver
1507 ppdcGroup
*g
) // I - Current group
1509 char name
[1024], // UI name
1511 type
[256]; // UI type string
1512 ppdcOptType ot
; // Option type value
1513 ppdcOptSection section
; // Option section
1514 float order
; // Option order
1515 ppdcOption
*o
; // Option
1516 ppdcGroup
*mg
; // Matching group, if any
1519 // Read the Option parameters:
1521 // Option name/text type section order
1522 if (!get_token(fp
, name
, sizeof(name
)))
1524 _cupsLangPrintf(stderr
,
1525 _("ppdc: Expected option name/text on line %d of %s."),
1526 fp
->line
, fp
->filename
);
1530 if ((text
= strchr(name
, '/')) != NULL
)
1535 if (!get_token(fp
, type
, sizeof(type
)))
1537 _cupsLangPrintf(stderr
, _("ppdc: Expected option type on line %d of %s."),
1538 fp
->line
, fp
->filename
);
1542 if (!_cups_strcasecmp(type
, "boolean"))
1544 else if (!_cups_strcasecmp(type
, "pickone"))
1546 else if (!_cups_strcasecmp(type
, "pickmany"))
1550 _cupsLangPrintf(stderr
,
1551 _("ppdc: Invalid option type \"%s\" on line %d of %s."),
1552 type
, fp
->line
, fp
->filename
);
1556 if (!get_token(fp
, type
, sizeof(type
)))
1558 _cupsLangPrintf(stderr
,
1559 _("ppdc: Expected option section on line %d of %s."),
1560 fp
->line
, fp
->filename
);
1564 if (!_cups_strcasecmp(type
, "AnySetup"))
1565 section
= PPDC_SECTION_ANY
;
1566 else if (!_cups_strcasecmp(type
, "DocumentSetup"))
1567 section
= PPDC_SECTION_DOCUMENT
;
1568 else if (!_cups_strcasecmp(type
, "ExitServer"))
1569 section
= PPDC_SECTION_EXIT
;
1570 else if (!_cups_strcasecmp(type
, "JCLSetup"))
1571 section
= PPDC_SECTION_JCL
;
1572 else if (!_cups_strcasecmp(type
, "PageSetup"))
1573 section
= PPDC_SECTION_PAGE
;
1574 else if (!_cups_strcasecmp(type
, "Prolog"))
1575 section
= PPDC_SECTION_PROLOG
;
1578 _cupsLangPrintf(stderr
,
1579 _("ppdc: Invalid option section \"%s\" on line %d of "
1580 "%s."), type
, fp
->line
, fp
->filename
);
1584 order
= get_float(fp
);
1586 // See if the option already exists...
1587 if ((o
= d
->find_option_group(name
, &mg
)) == NULL
)
1589 // Nope, add a new one...
1590 o
= new ppdcOption(ot
, name
, text
, section
, order
);
1592 else if (o
->type
!= ot
)
1594 _cupsLangPrintf(stderr
,
1595 _("ppdc: Option %s redefined with a different type on line "
1596 "%d of %s."), name
, fp
->line
, fp
->filename
);
1601 _cupsLangPrintf(stderr
,
1602 _("ppdc: Option %s defined in two different groups on line "
1603 "%d of %s."), name
, fp
->line
, fp
->filename
);
1612 // 'ppdcSource::get_po()' - Get a message catalog.
1615 ppdcCatalog
* // O - Message catalog
1616 ppdcSource::get_po(ppdcFile
*fp
) // I - File to read
1618 char locale
[32], // Locale name
1619 poname
[1024], // Message catalog filename
1620 basedir
[1024], // Base directory
1621 *baseptr
, // Pointer into directory
1622 pofilename
[1024]; // Full filename of message catalog
1623 ppdcCatalog
*cat
; // Message catalog
1626 // Read the #po parameters:
1628 // #po locale "filename.po"
1629 if (!get_token(fp
, locale
, sizeof(locale
)))
1631 _cupsLangPrintf(stderr
,
1632 _("ppdc: Expected locale after #po on line %d of %s."),
1633 fp
->line
, fp
->filename
);
1637 if (!get_token(fp
, poname
, sizeof(poname
)))
1639 _cupsLangPrintf(stderr
,
1640 _("ppdc: Expected filename after #po %s on line %d of "
1641 "%s."), locale
, fp
->line
, fp
->filename
);
1645 // See if the locale is already loaded...
1646 if (find_po(locale
))
1648 _cupsLangPrintf(stderr
,
1649 _("ppdc: Duplicate #po for locale %s on line %d of %s."),
1650 locale
, fp
->line
, fp
->filename
);
1654 // Figure out the current directory...
1655 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
1657 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
1660 strlcpy(basedir
, ".", sizeof(basedir
));
1662 // Find the po file...
1663 pofilename
[0] = '\0';
1666 find_include(poname
, basedir
, pofilename
, sizeof(pofilename
)))
1668 // Found it, so load it...
1669 cat
= new ppdcCatalog(locale
, pofilename
);
1671 // Reset the filename to the name supplied by the user...
1672 cat
->filename
->release();
1673 cat
->filename
= new ppdcString(poname
);
1675 // Return the catalog...
1680 _cupsLangPrintf(stderr
,
1681 _("ppdc: Unable to find #po file %s on line %d of %s."),
1682 poname
, fp
->line
, fp
->filename
);
1689 // 'ppdcSource::get_resolution()' - Get an old-style resolution option.
1692 ppdcChoice
* // O - Choice data
1693 ppdcSource::get_resolution(ppdcFile
*fp
)// I - File to read
1695 char name
[1024], // Name
1697 temp
[256], // Temporary string
1698 command
[256], // Command string
1699 *commptr
; // Pointer into command
1700 int xdpi
, ydpi
, // X + Y resolution
1701 color_order
, // Color order
1702 color_space
, // Colorspace
1703 compression
, // Compression mode
1704 depth
, // Bits per color
1705 row_count
, // Row count
1706 row_feed
, // Row feed
1707 row_step
; // Row step/interval
1710 // Read the resolution parameters:
1712 // Resolution colorspace bits row-count row-feed row-step name/text
1713 if (!get_token(fp
, temp
, sizeof(temp
)))
1715 _cupsLangPrintf(stderr
,
1716 _("ppdc: Expected override field after Resolution on line "
1717 "%d of %s."), fp
->line
, fp
->filename
);
1721 color_order
= get_color_order(temp
);
1722 color_space
= get_color_space(temp
);
1723 compression
= get_integer(temp
);
1725 depth
= get_integer(fp
);
1726 row_count
= get_integer(fp
);
1727 row_feed
= get_integer(fp
);
1728 row_step
= get_integer(fp
);
1730 if (!get_token(fp
, name
, sizeof(name
)))
1732 _cupsLangPrintf(stderr
,
1733 _("ppdc: Expected name/text after Resolution on line %d of "
1734 "%s."), fp
->line
, fp
->filename
);
1738 if ((text
= strchr(name
, '/')) != NULL
)
1743 switch (sscanf(name
, "%dx%d", &xdpi
, &ydpi
))
1746 _cupsLangPrintf(stderr
,
1747 _("ppdc: Bad resolution name \"%s\" on line %d of "
1748 "%s."), name
, fp
->line
, fp
->filename
);
1755 // Create the necessary PS commands...
1756 snprintf(command
, sizeof(command
),
1757 "<</HWResolution[%d %d]/cupsBitsPerColor %d/cupsRowCount %d"
1758 "/cupsRowFeed %d/cupsRowStep %d",
1759 xdpi
, ydpi
, depth
, row_count
, row_feed
, row_step
);
1760 commptr
= command
+ strlen(command
);
1762 if (color_order
>= 0)
1764 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1765 "/cupsColorOrder %d", color_order
);
1766 commptr
+= strlen(commptr
);
1769 if (color_space
>= 0)
1771 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1772 "/cupsColorSpace %d", color_space
);
1773 commptr
+= strlen(commptr
);
1776 if (compression
>= 0)
1778 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
),
1779 "/cupsCompression %d", compression
);
1780 commptr
+= strlen(commptr
);
1783 snprintf(commptr
, sizeof(command
) - (size_t)(commptr
- command
), ">>setpagedevice");
1785 // Return the new choice...
1786 return (new ppdcChoice(name
, text
, command
));
1791 // 'ppdcSource::get_simple_profile()' - Get a simple color profile definition.
1794 ppdcProfile
* // O - Color profile
1795 ppdcSource::get_simple_profile(ppdcFile
*fp
)
1798 char resolution
[1024], // Resolution/media type
1799 *media_type
; // Media type
1800 float m
[9]; // Transform matrix
1801 float kd
, rd
, g
; // Densities and gamma
1802 float red
, green
, blue
; // RGB adjustments
1803 float yellow
; // Yellow density
1804 float color
; // Color density values
1807 // Get the SimpleColorProfile parameters:
1809 // SimpleColorProfile resolution/mediatype black-density yellow-density
1810 // red-density gamma red-adjust green-adjust blue-adjust
1811 if (!get_token(fp
, resolution
, sizeof(resolution
)))
1813 _cupsLangPrintf(stderr
,
1814 _("ppdc: Expected resolution/mediatype following "
1815 "SimpleColorProfile on line %d of %s."),
1816 fp
->line
, fp
->filename
);
1820 if ((media_type
= strchr(resolution
, '/')) != NULL
)
1821 *media_type
++ = '\0';
1823 media_type
= resolution
;
1825 // Collect the profile parameters...
1827 yellow
= get_float(fp
);
1830 red
= get_float(fp
);
1831 green
= get_float(fp
);
1832 blue
= get_float(fp
);
1834 // Build the color profile...
1835 color
= 0.5f
* rd
/ kd
- kd
;
1837 m
[1] = color
+ blue
; // C + M (blue)
1838 m
[2] = color
- green
; // C + Y (green)
1839 m
[3] = color
- blue
; // M + C (blue)
1841 m
[5] = color
+ red
; // M + Y (red)
1842 m
[6] = yellow
* (color
+ green
); // Y + C (green)
1843 m
[7] = yellow
* (color
- red
); // Y + M (red)
1851 else if (m
[3] > 0.0f
)
1862 else if (m
[6] > 0.0f
)
1873 else if (m
[7] > 0.0f
)
1879 // Return the new profile...
1880 return (new ppdcProfile(resolution
, media_type
, g
, kd
, m
));
1885 // 'ppdcSource::get_size()' - Get a media size definition from a file.
1888 ppdcMediaSize
* // O - Media size
1889 ppdcSource::get_size(ppdcFile
*fp
) // I - File to read
1891 char name
[1024], // Name
1893 float width
, // Width
1897 // Get the name, text, width, and length:
1899 // #media name/text width length
1900 if (!get_token(fp
, name
, sizeof(name
)))
1903 if ((text
= strchr(name
, '/')) != NULL
)
1908 if ((width
= get_measurement(fp
)) < 0.0f
)
1911 if ((length
= get_measurement(fp
)) < 0.0f
)
1914 // Return the new media size...
1915 return (new ppdcMediaSize(name
, text
, width
, length
, 0.0f
, 0.0f
, 0.0f
, 0.0f
));
1920 // 'ppdcSource::get_token()' - Get a token from a file.
1923 char * // O - Token string or NULL
1924 ppdcSource::get_token(ppdcFile
*fp
, // I - File to read
1925 char *buffer
, // I - Buffer
1926 int buflen
) // I - Length of buffer
1928 char *bufptr
, // Pointer into string buffer
1929 *bufend
; // End of string buffer
1930 int ch
, // Character from file
1931 nextch
, // Next char in file
1932 quote
, // Quote character used...
1933 empty
, // Empty input?
1934 startline
; // Start line for quote
1935 char name
[256], // Name string
1936 *nameptr
; // Name pointer
1937 ppdcVariable
*var
; // Variable pointer
1940 // Mark the beginning and end of the buffer...
1942 bufend
= buffer
+ buflen
- 1;
1944 // Loop intil we've read a token...
1949 while ((ch
= fp
->get()) != EOF
)
1951 if (isspace(ch
) && !quote
)
1960 // Variable substitution
1963 for (nameptr
= name
; (ch
= fp
->peek()) != EOF
;)
1965 if (!isalnum(ch
) && ch
!= '_')
1967 else if (nameptr
< (name
+ sizeof(name
) - 1))
1968 *nameptr
++ = (char)fp
->get();
1971 if (nameptr
== name
)
1973 // Just substitute this character...
1977 if (bufptr
< bufend
)
1978 *bufptr
++ = (char)fp
->get();
1983 _cupsLangPrintf(stderr
,
1984 _("ppdc: Bad variable substitution ($%c) on line %d "
1985 "of %s."), ch
, fp
->line
, fp
->filename
);
1987 if (bufptr
< bufend
)
1993 // Substitute the variable value...
1995 var
= find_variable(name
);
1998 strlcpy(bufptr
, var
->value
->value
, (size_t)(bufend
- bufptr
+ 1));
1999 bufptr
+= strlen(bufptr
);
2003 if (!(cond_state
& PPDC_COND_SKIP
))
2004 _cupsLangPrintf(stderr
,
2005 _("ppdc: Undefined variable (%s) on line %d of "
2006 "%s."), name
, fp
->line
, fp
->filename
);
2008 snprintf(bufptr
, (size_t)(bufend
- bufptr
+ 1), "$%s", name
);
2009 bufptr
+= strlen(bufptr
);
2013 else if (ch
== '/' && !quote
)
2015 // Possibly a comment...
2016 nextch
= fp
->peek();
2023 while ((nextch
= fp
->get()) != EOF
)
2025 if (ch
== '*' && nextch
== '/')
2034 else if (nextch
== '/')
2037 while ((nextch
= fp
->get()) != EOF
)
2049 if (bufptr
< bufend
)
2050 *bufptr
++ = (char)ch
;
2053 else if (ch
== '\'' || ch
== '\"')
2059 // Ending the current quoted string...
2064 // Insert the opposing quote char...
2065 if (bufptr
< bufend
)
2066 *bufptr
++ = (char)ch
;
2070 // Start a new quoted string...
2071 startline
= fp
->line
;
2075 else if ((ch
== '(' || ch
== '<') && !quote
)
2079 startline
= fp
->line
;
2081 if (bufptr
< bufend
)
2082 *bufptr
++ = (char)ch
;
2084 else if ((ch
== ')' && quote
== '(') || (ch
== '>' && quote
== '<'))
2088 if (bufptr
< bufend
)
2089 *bufptr
++ = (char)ch
;
2091 else if (ch
== '\\')
2095 if ((ch
= fp
->get()) == EOF
)
2098 if (bufptr
< bufend
)
2099 *bufptr
++ = (char)ch
;
2101 else if (bufptr
< bufend
)
2105 *bufptr
++ = (char)ch
;
2107 if ((ch
== '{' || ch
== '}') && !quote
)
2114 _cupsLangPrintf(stderr
,
2115 _("ppdc: Unterminated string starting with %c on line %d "
2116 "of %s."), quote
, startline
, fp
->filename
);
2131 // 'ppdcSource::get_variable()' - Get a variable definition.
2134 ppdcVariable
* // O - Variable
2135 ppdcSource::get_variable(ppdcFile
*fp
) // I - File to read
2137 char name
[1024], // Name
2138 value
[1024]; // Value
2141 // Get the name and value:
2143 // #define name value
2144 if (!get_token(fp
, name
, sizeof(name
)))
2147 if (!get_token(fp
, value
, sizeof(value
)))
2150 // Set the variable...
2151 return (set_variable(name
, value
));
2156 // 'ppdcSource::quotef()' - Write a formatted, quoted string...
2159 int // O - Number bytes on success, -1 on failure
2160 ppdcSource::quotef(cups_file_t
*fp
, // I - File to write to
2161 const char *format
, // I - Printf-style format string
2162 ...) // I - Additional args as needed
2164 va_list ap
; // Pointer to additional arguments
2165 int bytes
; // Bytes written
2166 char sign
, // Sign of format width
2167 size
, // Size character (h, l, L)
2168 type
; // Format type character
2169 const char *bufformat
; // Start of format
2170 int width
, // Width of field
2171 prec
; // Number of characters of precision
2172 char tformat
[100]; // Temporary format string for fprintf()
2173 char *s
; // Pointer to string
2174 int slen
; // Length of string
2175 int i
; // Looping var
2178 // Range check input...
2182 // Loop through the format string, formatting as needed...
2183 va_start(ap
, format
);
2196 cupsFilePutChar(fp
, *format
++);
2200 else if (strchr(" -+#\'", *format
))
2206 while (isdigit(*format
))
2207 width
= width
* 10 + *format
++ - '0';
2214 while (isdigit(*format
))
2215 prec
= prec
* 10 + *format
++ - '0';
2220 if (*format
== 'l' && format
[1] == 'l')
2225 else if (*format
== 'h' || *format
== 'l' || *format
== 'L')
2237 case 'E' : // Floating point formats
2242 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2245 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2246 tformat
[format
- bufformat
] = '\0';
2248 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, double));
2251 case 'B' : // Integer formats
2259 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2262 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2263 tformat
[format
- bufformat
] = '\0';
2265 # ifdef HAVE_LONG_LONG
2267 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long long));
2269 # endif /* HAVE_LONG_LONG */
2271 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, long));
2273 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, int));
2276 case 'p' : // Pointer value
2277 if ((format
- bufformat
+ 1) > (int)sizeof(tformat
))
2280 memcpy(tformat
, bufformat
, (size_t)(format
- bufformat
));
2281 tformat
[format
- bufformat
] = '\0';
2283 bytes
+= cupsFilePrintf(fp
, tformat
, va_arg(ap
, void *));
2286 case 'c' : // Character or character array
2290 cupsFilePutChar(fp
, va_arg(ap
, int));
2294 cupsFileWrite(fp
, va_arg(ap
, char *), (size_t)width
);
2299 case 's' : // String
2300 if ((s
= va_arg(ap
, char *)) == NULL
)
2301 s
= (char *)"(nil)";
2303 slen
= (int)strlen(s
);
2304 if (slen
> width
&& prec
!= width
)
2312 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2313 cupsFilePutChar(fp
, ' ');
2316 for (i
= slen
; i
> 0; i
--, s
++, bytes
++)
2318 if (*s
== '\\' || *s
== '\"')
2320 cupsFilePutChar(fp
, '\\');
2324 cupsFilePutChar(fp
, *s
);
2329 for (i
= width
- slen
; i
> 0; i
--, bytes
++)
2330 cupsFilePutChar(fp
, ' ');
2337 cupsFilePutChar(fp
, *format
++);
2344 // Return the number of characters written.
2350 // 'ppdcSource::read_file()' - Read a driver source file.
2354 ppdcSource::read_file(const char *f
, // I - File to read
2355 cups_file_t
*ffp
) // I - File pointer to use
2357 ppdcFile
*fp
= new ppdcFile(f
, ffp
);
2361 if (cond_current
!= cond_stack
)
2362 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."), f
);
2367 // 'ppdcSource::scan_file()' - Scan a driver source file.
2371 ppdcSource::scan_file(ppdcFile
*fp
, // I - File to read
2372 ppdcDriver
*td
, // I - Driver template
2373 bool inc
) // I - Including?
2375 ppdcDriver
*d
; // Current driver
2376 ppdcGroup
*g
, // Current group
2377 *mg
, // Matching group
2378 *general
, // General options group
2379 *install
; // Installable options group
2380 ppdcOption
*o
; // Current option
2381 ppdcChoice
*c
; // Current choice
2382 char temp
[256], // Token from file...
2383 *ptr
; // Pointer into token
2384 int isdefault
; // Default option?
2387 // Initialize things as needed...
2394 d
= new ppdcDriver(td
);
2396 if ((general
= d
->find_group("General")) == NULL
)
2398 general
= new ppdcGroup("General", NULL
);
2399 d
->add_group(general
);
2402 if ((install
= d
->find_group("InstallableOptions")) == NULL
)
2404 install
= new ppdcGroup("InstallableOptions", "Installable Options");
2405 d
->add_group(install
);
2408 // Loop until EOF or }
2412 while (get_token(fp
, temp
, sizeof(temp
)))
2416 // Mark the next choice as the default
2419 for (ptr
= temp
; ptr
[1]; ptr
++)
2426 // Don't mark the next choice as the default
2430 if (!_cups_strcasecmp(temp
, "}"))
2432 // Close this one out...
2435 else if (!_cups_strcasecmp(temp
, "{"))
2437 // Open a new child...
2440 else if (!_cups_strcasecmp(temp
, "#if"))
2442 if ((cond_current
- cond_stack
) >= 100)
2444 _cupsLangPrintf(stderr
,
2445 _("ppdc: Too many nested #if's on line %d of %s."),
2446 fp
->line
, fp
->filename
);
2451 if (get_integer(fp
) > 0)
2452 *cond_current
= PPDC_COND_SATISFIED
;
2455 *cond_current
= PPDC_COND_SKIP
;
2456 cond_state
|= PPDC_COND_SKIP
;
2459 else if (!_cups_strcasecmp(temp
, "#elif"))
2461 if (cond_current
== cond_stack
)
2463 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2464 fp
->line
, fp
->filename
);
2468 if (*cond_current
& PPDC_COND_SATISFIED
)
2471 *cond_current
|= PPDC_COND_SKIP
;
2473 else if (get_integer(fp
) > 0)
2475 *cond_current
|= PPDC_COND_SATISFIED
;
2476 *cond_current
&= ~PPDC_COND_SKIP
;
2479 *cond_current
|= PPDC_COND_SKIP
;
2481 // Update the current state
2482 int *cond_temp
= cond_current
; // Temporary stack pointer
2484 cond_state
= PPDC_COND_NORMAL
;
2485 while (cond_temp
> cond_stack
)
2486 if (*cond_temp
& PPDC_COND_SKIP
)
2488 cond_state
= PPDC_COND_SKIP
;
2494 else if (!_cups_strcasecmp(temp
, "#else"))
2496 if (cond_current
== cond_stack
)
2498 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2499 fp
->line
, fp
->filename
);
2503 if (*cond_current
& PPDC_COND_SATISFIED
)
2504 *cond_current
|= PPDC_COND_SKIP
;
2507 *cond_current
|= PPDC_COND_SATISFIED
;
2508 *cond_current
&= ~PPDC_COND_SKIP
;
2511 // Update the current state
2512 int *cond_temp
= cond_current
; // Temporary stack pointer
2514 cond_state
= PPDC_COND_NORMAL
;
2515 while (cond_temp
> cond_stack
)
2516 if (*cond_temp
& PPDC_COND_SKIP
)
2518 cond_state
= PPDC_COND_SKIP
;
2524 else if (!_cups_strcasecmp(temp
, "#endif"))
2526 if (cond_current
== cond_stack
)
2528 _cupsLangPrintf(stderr
, _("ppdc: Missing #if on line %d of %s."),
2529 fp
->line
, fp
->filename
);
2535 // Update the current state
2536 int *cond_temp
= cond_current
; // Temporary stack pointer
2538 cond_state
= PPDC_COND_NORMAL
;
2539 while (cond_temp
> cond_stack
)
2540 if (*cond_temp
& PPDC_COND_SKIP
)
2542 cond_state
= PPDC_COND_SKIP
;
2548 else if (!_cups_strcasecmp(temp
, "#define"))
2550 // Get the variable...
2553 else if (!_cups_strcasecmp(temp
, "#include"))
2555 // #include filename
2556 char basedir
[1024], // Base directory
2557 *baseptr
, // Pointer into directory
2558 inctemp
[1024], // Initial filename
2559 incname
[1024]; // Include filename
2560 ppdcFile
*incfile
; // Include file
2561 int *old_current
= cond_current
;
2562 // Previous current stack
2565 // Get the include name...
2566 if (!get_token(fp
, inctemp
, sizeof(inctemp
)))
2568 _cupsLangPrintf(stderr
,
2569 _("ppdc: Expected include filename on line %d of "
2570 "%s."), fp
->line
, fp
->filename
);
2577 // Figure out the current directory...
2578 strlcpy(basedir
, fp
->filename
, sizeof(basedir
));
2580 if ((baseptr
= strrchr(basedir
, '/')) != NULL
)
2583 strlcpy(basedir
, ".", sizeof(basedir
));
2585 // Find the include file...
2586 if (find_include(inctemp
, basedir
, incname
, sizeof(incname
)))
2588 // Open the include file, scan it, and then close it...
2589 incfile
= new ppdcFile(incname
);
2590 scan_file(incfile
, d
, true);
2593 if (cond_current
!= old_current
)
2594 _cupsLangPrintf(stderr
, _("ppdc: Missing #endif at end of \"%s\"."),
2600 _cupsLangPrintf(stderr
,
2601 _("ppdc: Unable to find include file \"%s\" on line %d "
2602 "of %s."), inctemp
, fp
->line
, fp
->filename
);
2606 else if (!_cups_strcasecmp(temp
, "#media"))
2608 ppdcMediaSize
*m
; // Media size
2611 // Get a media size...
2621 else if (!_cups_strcasecmp(temp
, "#po"))
2623 ppdcCatalog
*cat
; // Message catalog
2626 // Get a message catalog...
2636 else if (!_cups_strcasecmp(temp
, "Attribute") ||
2637 !_cups_strcasecmp(temp
, "LocAttribute"))
2639 ppdcAttr
*a
; // Attribute
2642 // Get an attribute...
2643 a
= get_attr(fp
, !_cups_strcasecmp(temp
, "LocAttribute"));
2652 else if (!_cups_strcasecmp(temp
, "Choice"))
2665 // Add it to the current option...
2668 _cupsLangPrintf(stderr
,
2669 _("ppdc: Choice found on line %d of %s with no "
2670 "Option."), fp
->line
, fp
->filename
);
2677 o
->set_defchoice(c
);
2679 else if (!_cups_strcasecmp(temp
, "ColorDevice"))
2681 // ColorDevice boolean
2685 d
->color_device
= get_boolean(fp
);
2687 else if (!_cups_strcasecmp(temp
, "ColorModel"))
2689 // Get the color model
2690 c
= get_color_model(fp
);
2700 // Add the choice to the ColorModel option...
2701 if ((o
= d
->find_option("ColorModel")) == NULL
)
2703 // Create the ColorModel option...
2704 o
= new ppdcOption(PPDC_PICKONE
, "ColorModel", "Color Mode", PPDC_SECTION_ANY
, 10.0f
);
2712 o
->set_defchoice(c
);
2716 else if (!_cups_strcasecmp(temp
, "ColorProfile"))
2718 ppdcProfile
*p
; // Color profile
2721 // Get the color profile...
2722 p
= get_color_profile(fp
);
2729 d
->profiles
->add(p
);
2732 else if (!_cups_strcasecmp(temp
, "Copyright"))
2735 char copytemp
[8192], // Copyright string
2736 *copyptr
, // Pointer into string
2737 *copyend
; // Pointer to end of string
2740 // Get the copyright string...
2741 if (!get_token(fp
, copytemp
, sizeof(temp
)))
2743 _cupsLangPrintf(stderr
,
2744 _("ppdc: Expected string after Copyright on line %d "
2745 "of %s."), fp
->line
, fp
->filename
);
2752 // Break it up into individual lines...
2753 for (copyptr
= copytemp
; copyptr
; copyptr
= copyend
)
2755 if ((copyend
= strchr(copyptr
, '\n')) != NULL
)
2758 d
->copyright
->add(new ppdcString(copyptr
));
2761 else if (!_cups_strcasecmp(temp
, "CustomMedia"))
2763 ppdcMediaSize
*m
; // Media size
2766 // Get a custom media size...
2767 m
= get_custom_size(fp
);
2779 d
->set_default_size(m
);
2781 else if (!_cups_strcasecmp(temp
, "Cutter"))
2784 int have_cutter
; // Have a paper cutter?
2787 have_cutter
= get_boolean(fp
);
2788 if (have_cutter
<= 0 || cond_state
)
2791 if ((o
= d
->find_option("CutMedia")) == NULL
)
2793 o
= new ppdcOption(PPDC_BOOLEAN
, "CutMedia", "Cut Media", PPDC_SECTION_ANY
, 10.0f
);
2798 c
= new ppdcChoice("False", NULL
, "<</CutMedia 0>>setpagedevice");
2800 o
->set_defchoice(c
);
2802 c
= new ppdcChoice("True", NULL
, "<</CutMedia 4>>setpagedevice");
2808 else if (!_cups_strcasecmp(temp
, "Darkness"))
2810 // Get the darkness choice...
2811 c
= get_generic(fp
, "Darkness", NULL
, "cupsCompression");
2821 // Add the choice to the cupsDarkness option...
2822 if ((o
= d
->find_option_group("cupsDarkness", &mg
)) == NULL
)
2824 // Create the cupsDarkness option...
2825 o
= new ppdcOption(PPDC_PICKONE
, "cupsDarkness", "Darkness", PPDC_SECTION_ANY
, 10.0f
);
2829 else if (mg
!= general
)
2831 _cupsLangPrintf(stderr
,
2832 _("ppdc: Option %s defined in two different groups on "
2833 "line %d of %s."), "cupsDarkness", fp
->line
,
2842 o
->set_defchoice(c
);
2846 else if (!_cups_strcasecmp(temp
, "DriverType"))
2848 int i
; // Looping var
2851 // DriverType keyword
2852 if (!get_token(fp
, temp
, sizeof(temp
)))
2854 _cupsLangPrintf(stderr
,
2855 _("ppdc: Expected driver type keyword following "
2856 "DriverType on line %d of %s."),
2857 fp
->line
, fp
->filename
);
2864 for (i
= 0; i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])); i
++)
2865 if (!_cups_strcasecmp(temp
, driver_types
[i
]))
2868 if (i
< (int)(sizeof(driver_types
) / sizeof(driver_types
[0])))
2869 d
->type
= (ppdcDrvType
)i
;
2870 else if (!_cups_strcasecmp(temp
, "dymo"))
2871 d
->type
= PPDC_DRIVER_LABEL
;
2873 _cupsLangPrintf(stderr
,
2874 _("ppdc: Unknown driver type %s on line %d of %s."),
2875 temp
, fp
->line
, fp
->filename
);
2877 else if (!_cups_strcasecmp(temp
, "Duplex"))
2879 else if (!_cups_strcasecmp(temp
, "Filter"))
2881 ppdcFilter
*f
; // Filter
2884 // Get the filter value...
2894 else if (!_cups_strcasecmp(temp
, "Finishing"))
2896 // Get the finishing choice...
2897 c
= get_generic(fp
, "Finishing", "OutputType", NULL
);
2907 // Add the choice to the cupsFinishing option...
2908 if ((o
= d
->find_option_group("cupsFinishing", &mg
)) == NULL
)
2910 // Create the cupsFinishing option...
2911 o
= new ppdcOption(PPDC_PICKONE
, "cupsFinishing", "Finishing", PPDC_SECTION_ANY
, 10.0f
);
2915 else if (mg
!= general
)
2917 _cupsLangPrintf(stderr
,
2918 _("ppdc: Option %s defined in two different groups on "
2919 "line %d of %s."), "cupsFinishing", fp
->line
,
2928 o
->set_defchoice(c
);
2932 else if (!_cups_strcasecmp(temp
, "Font") ||
2933 !_cups_strcasecmp(temp
, "#font"))
2935 ppdcFont
*f
; // Font
2946 if (!_cups_strcasecmp(temp
, "#font"))
2952 d
->set_default_font(f
);
2956 else if (!_cups_strcasecmp(temp
, "Group"))
2959 ppdcGroup
*tempg
= get_group(fp
, d
);
2966 if (!d
->find_group(tempg
->name
->value
))
2971 if (!d
->find_group(tempg
->name
->value
))
2972 d
->add_group(tempg
);
2977 else if (!_cups_strcasecmp(temp
, "HWMargins"))
2979 // HWMargins left bottom right top
2980 d
->left_margin
= get_measurement(fp
);
2981 d
->bottom_margin
= get_measurement(fp
);
2982 d
->right_margin
= get_measurement(fp
);
2983 d
->top_margin
= get_measurement(fp
);
2985 else if (!_cups_strcasecmp(temp
, "InputSlot"))
2987 // Get the input slot choice...
2988 c
= get_generic(fp
, "InputSlot", NULL
, "MediaPosition");
2998 // Add the choice to the InputSlot option...
3000 if ((o
= d
->find_option_group("InputSlot", &mg
)) == NULL
)
3002 // Create the InputSlot option...
3003 o
= new ppdcOption(PPDC_PICKONE
, "InputSlot", "Media Source",
3004 PPDC_SECTION_ANY
, 10.0f
);
3008 else if (mg
!= general
)
3010 _cupsLangPrintf(stderr
,
3011 _("ppdc: Option %s defined in two different groups on "
3012 "line %d of %s."), "InputSlot", fp
->line
,
3021 o
->set_defchoice(c
);
3025 else if (!_cups_strcasecmp(temp
, "Installable"))
3027 // Get the installable option...
3028 o
= get_installable(fp
);
3030 // Add it as needed...
3036 install
->add_option(o
);
3041 else if (!_cups_strcasecmp(temp
, "ManualCopies"))
3043 // ManualCopies boolean
3047 d
->manual_copies
= get_boolean(fp
);
3049 else if (!_cups_strcasecmp(temp
, "Manufacturer"))
3051 // Manufacturer name
3052 char name
[256]; // Model name string
3055 if (!get_token(fp
, name
, sizeof(name
)))
3057 _cupsLangPrintf(stderr
,
3058 _("ppdc: Expected name after Manufacturer on line %d "
3059 "of %s."), fp
->line
, fp
->filename
);
3064 d
->set_manufacturer(name
);
3066 else if (!_cups_strcasecmp(temp
, "MaxSize"))
3068 // MaxSize width length
3071 get_measurement(fp
);
3072 get_measurement(fp
);
3076 d
->max_width
= get_measurement(fp
);
3077 d
->max_length
= get_measurement(fp
);
3080 else if (!_cups_strcasecmp(temp
, "MediaSize"))
3082 // MediaSize keyword
3083 char name
[41]; // Media size name
3084 ppdcMediaSize
*m
, // Matching media size...
3085 *dm
; // Driver media size...
3088 if (get_token(fp
, name
, sizeof(name
)) == NULL
)
3090 _cupsLangPrintf(stderr
,
3091 _("ppdc: Expected name after MediaSize on line %d of "
3092 "%s."), fp
->line
, fp
->filename
);
3099 m
= find_size(name
);
3103 _cupsLangPrintf(stderr
,
3104 _("ppdc: Unknown media size \"%s\" on line %d of "
3105 "%s."), name
, fp
->line
, fp
->filename
);
3109 // Add this size to the driver...
3110 dm
= new ppdcMediaSize(m
->name
->value
, m
->text
->value
,
3111 m
->width
, m
->length
, d
->left_margin
,
3112 d
->bottom_margin
, d
->right_margin
,
3117 d
->set_default_size(dm
);
3119 else if (!_cups_strcasecmp(temp
, "MediaType"))
3121 // Get the media type choice...
3122 c
= get_generic(fp
, "MediaType", "MediaType", "cupsMediaType");
3132 // Add the choice to the MediaType option...
3133 if ((o
= d
->find_option_group("MediaType", &mg
)) == NULL
)
3135 // Create the MediaType option...
3136 o
= new ppdcOption(PPDC_PICKONE
, "MediaType", "Media Type",
3137 PPDC_SECTION_ANY
, 10.0f
);
3141 else if (mg
!= general
)
3143 _cupsLangPrintf(stderr
,
3144 _("ppdc: Option %s defined in two different groups on "
3145 "line %d of %s."), "MediaType", fp
->line
,
3154 o
->set_defchoice(c
);
3158 else if (!_cups_strcasecmp(temp
, "MinSize"))
3160 // MinSize width length
3163 get_measurement(fp
);
3164 get_measurement(fp
);
3168 d
->min_width
= get_measurement(fp
);
3169 d
->min_length
= get_measurement(fp
);
3172 else if (!_cups_strcasecmp(temp
, "ModelName"))
3175 char name
[256]; // Model name string
3178 if (!get_token(fp
, name
, sizeof(name
)))
3180 _cupsLangPrintf(stderr
,
3181 _("ppdc: Expected name after ModelName on line %d of "
3182 "%s."), fp
->line
, fp
->filename
);
3187 d
->set_model_name(name
);
3189 else if (!_cups_strcasecmp(temp
, "ModelNumber"))
3191 // ModelNumber number
3195 d
->model_number
= get_integer(fp
);
3197 else if (!_cups_strcasecmp(temp
, "Option"))
3200 ppdcOption
*tempo
= get_option(fp
, d
, g
);
3207 if (!g
->find_option(tempo
->name
->value
))
3212 if (!g
->find_option(tempo
->name
->value
))
3213 g
->add_option(tempo
);
3218 else if (!_cups_strcasecmp(temp
, "FileName"))
3221 char name
[256]; // Filename string
3224 if (!get_token(fp
, name
, sizeof(name
)))
3226 _cupsLangPrintf(stderr
,
3227 _("ppdc: Expected name after FileName on line %d of "
3228 "%s."), fp
->line
, fp
->filename
);
3233 d
->set_file_name(name
);
3235 else if (!_cups_strcasecmp(temp
, "PCFileName"))
3238 char name
[256]; // PC filename string
3241 if (!get_token(fp
, name
, sizeof(name
)))
3243 _cupsLangPrintf(stderr
,
3244 _("ppdc: Expected name after PCFileName on line %d of "
3245 "%s."), fp
->line
, fp
->filename
);
3250 d
->set_pc_file_name(name
);
3252 else if (!_cups_strcasecmp(temp
, "Resolution"))
3254 // Get the resolution choice...
3255 c
= get_resolution(fp
);
3265 // Add the choice to the Resolution option...
3266 if ((o
= d
->find_option_group("Resolution", &mg
)) == NULL
)
3268 // Create the Resolution option...
3269 o
= new ppdcOption(PPDC_PICKONE
, "Resolution", NULL
, PPDC_SECTION_ANY
,
3274 else if (mg
!= general
)
3276 _cupsLangPrintf(stderr
,
3277 _("ppdc: Option %s defined in two different groups on "
3278 "line %d of %s."), "Resolution", fp
->line
,
3287 o
->set_defchoice(c
);
3291 else if (!_cups_strcasecmp(temp
, "SimpleColorProfile"))
3293 ppdcProfile
*p
; // Color profile
3296 // Get the color profile...
3297 p
= get_simple_profile(fp
);
3304 d
->profiles
->add(p
);
3307 else if (!_cups_strcasecmp(temp
, "Throughput"))
3309 // Throughput number
3313 d
->throughput
= get_integer(fp
);
3315 else if (!_cups_strcasecmp(temp
, "UIConstraints"))
3317 ppdcConstraint
*con
; // Constraint
3320 con
= get_constraint(fp
);
3327 d
->constraints
->add(con
);
3330 else if (!_cups_strcasecmp(temp
, "VariablePaperSize"))
3332 // VariablePaperSize boolean
3336 d
->variable_paper_size
= get_boolean(fp
);
3338 else if (!_cups_strcasecmp(temp
, "Version"))
3341 char name
[256]; // Model name string
3344 if (!get_token(fp
, name
, sizeof(name
)))
3346 _cupsLangPrintf(stderr
,
3347 _("ppdc: Expected string after Version on line %d of "
3348 "%s."), fp
->line
, fp
->filename
);
3353 d
->set_version(name
);
3357 _cupsLangPrintf(stderr
,
3358 _("ppdc: Unknown token \"%s\" seen on line %d of %s."),
3359 temp
, fp
->line
, fp
->filename
);
3364 // Done processing this block, is there anything to save?
3367 if (!d
->pc_file_name
|| !d
->model_name
|| !d
->manufacturer
|| !d
->version
||
3370 // Nothing to save...
3375 // Got a driver, save it...
3385 // 'ppdcSource::set_variable()' - Set a variable.
3388 ppdcVariable
* // O - Variable
3389 ppdcSource::set_variable(
3390 const char *name
, // I - Name
3391 const char *value
) // I - Value
3393 ppdcVariable
*v
; // Variable
3396 // See if the variable exists already...
3397 v
= find_variable(name
);
3400 // Change the variable value...
3401 v
->set_value(value
);
3405 // Create a new variable and add it...
3406 v
= new ppdcVariable(name
, value
);
3415 // 'ppdcSource::write_file()' - Write the current source data to a file.
3418 int // O - 0 on success, -1 on error
3419 ppdcSource::write_file(const char *f
) // I - File to write
3421 cups_file_t
*fp
; // Output file
3422 char bckname
[1024]; // Backup file
3423 ppdcDriver
*d
; // Current driver
3424 ppdcString
*st
; // Current string
3425 ppdcAttr
*a
; // Current attribute
3426 ppdcConstraint
*co
; // Current constraint
3427 ppdcFilter
*fi
; // Current filter
3428 ppdcFont
*fo
; // Current font
3429 ppdcGroup
*g
; // Current group
3430 ppdcOption
*o
; // Current option
3431 ppdcChoice
*ch
; // Current choice
3432 ppdcProfile
*p
; // Current color profile
3433 ppdcMediaSize
*si
; // Current media size
3434 float left
, // Current left margin
3435 bottom
, // Current bottom margin
3436 right
, // Current right margin
3437 top
; // Current top margin
3438 int dtused
[PPDC_DRIVER_MAX
];// Driver type usage...
3441 // Rename the current file, if any, to .bck...
3442 snprintf(bckname
, sizeof(bckname
), "%s.bck", f
);
3445 // Open the output file...
3446 fp
= cupsFileOpen(f
, "w");
3450 // Can't create file; restore backup and return...
3455 cupsFilePuts(fp
, "// CUPS PPD Compiler " CUPS_SVERSION
"\n\n");
3457 // Include standard files...
3458 cupsFilePuts(fp
, "// Include necessary files...\n");
3459 cupsFilePuts(fp
, "#include <font.defs>\n");
3460 cupsFilePuts(fp
, "#include <media.defs>\n");
3462 memset(dtused
, 0, sizeof(dtused
));
3464 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3465 if (d
->type
> PPDC_DRIVER_PS
&& !dtused
[d
->type
])
3467 cupsFilePrintf(fp
, "#include <%s.h>\n", driver_types
[d
->type
]);
3468 dtused
[d
->type
] = 1;
3471 // Output each driver...
3472 for (d
= (ppdcDriver
*)drivers
->first(); d
; d
= (ppdcDriver
*)drivers
->next())
3474 // Start the driver...
3475 cupsFilePrintf(fp
, "\n// %s %s\n", d
->manufacturer
->value
,
3476 d
->model_name
->value
);
3477 cupsFilePuts(fp
, "{\n");
3479 // Write the copyright stings...
3480 for (st
= (ppdcString
*)d
->copyright
->first();
3482 st
= (ppdcString
*)d
->copyright
->next())
3483 quotef(fp
, " Copyright \"%s\"\n", st
->value
);
3485 // Write other strings and values...
3486 if (d
->manufacturer
&& d
->manufacturer
->value
)
3487 quotef(fp
, " Manufacturer \"%s\"\n", d
->manufacturer
->value
);
3488 if (d
->model_name
->value
)
3489 quotef(fp
, " ModelName \"%s\"\n", d
->model_name
->value
);
3490 if (d
->file_name
&& d
->file_name
->value
)
3491 quotef(fp
, " FileName \"%s\"\n", d
->file_name
->value
);
3492 if (d
->pc_file_name
&& d
->pc_file_name
->value
)
3493 quotef(fp
, " PCFileName \"%s\"\n", d
->pc_file_name
->value
);
3494 if (d
->version
&& d
->version
->value
)
3495 quotef(fp
, " Version \"%s\"\n", d
->version
->value
);
3497 cupsFilePrintf(fp
, " DriverType %s\n", driver_types
[d
->type
]);
3499 if (d
->model_number
)
3503 case PPDC_DRIVER_LABEL
:
3504 cupsFilePuts(fp
, " ModelNumber ");
3506 switch (d
->model_number
)
3509 cupsFilePuts(fp
, "$DYMO_3x0\n");
3512 case ZEBRA_EPL_LINE
:
3513 cupsFilePuts(fp
, "$ZEBRA_EPL_LINE\n");
3516 case ZEBRA_EPL_PAGE
:
3517 cupsFilePuts(fp
, "$ZEBRA_EPL_PAGE\n");
3521 cupsFilePuts(fp
, "$ZEBRA_ZPL\n");
3525 cupsFilePuts(fp
, "$ZEBRA_CPCL\n");
3528 case INTELLITECH_PCL
:
3529 cupsFilePuts(fp
, "$INTELLITECH_PCL\n");
3533 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3538 case PPDC_DRIVER_EPSON
:
3539 cupsFilePuts(fp
, " ModelNumber ");
3541 switch (d
->model_number
)
3544 cupsFilePuts(fp
, "$EPSON_9PIN\n");
3548 cupsFilePuts(fp
, "$EPSON_24PIN\n");
3552 cupsFilePuts(fp
, "$EPSON_COLOR\n");
3556 cupsFilePuts(fp
, "$EPSON_PHOTO\n");
3560 cupsFilePuts(fp
, "$EPSON_ICOLOR\n");
3564 cupsFilePuts(fp
, "$EPSON_IPHOTO\n");
3568 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3573 case PPDC_DRIVER_HP
:
3574 cupsFilePuts(fp
, " ModelNumber ");
3575 switch (d
->model_number
)
3578 cupsFilePuts(fp
, "$HP_LASERJET\n");
3582 cupsFilePuts(fp
, "$HP_DESKJET\n");
3586 cupsFilePuts(fp
, "$HP_DESKJET2\n");
3590 cupsFilePrintf(fp
, "%d\n", d
->model_number
);
3594 cupsFilePuts(fp
, ")\n");
3598 cupsFilePrintf(fp
, " ModelNumber %d\n", d
->model_number
);
3603 if (d
->manual_copies
)
3604 cupsFilePuts(fp
, " ManualCopies Yes\n");
3606 if (d
->color_device
)
3607 cupsFilePuts(fp
, " ColorDevice Yes\n");
3610 cupsFilePrintf(fp
, " Throughput %d\n", d
->throughput
);
3612 // Output all of the attributes...
3613 for (a
= (ppdcAttr
*)d
->attrs
->first();
3615 a
= (ppdcAttr
*)d
->attrs
->next())
3616 if (a
->text
->value
&& a
->text
->value
[0])
3617 quotef(fp
, " Attribute \"%s\" \"%s/%s\" \"%s\"\n",
3618 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3619 a
->text
->value
, a
->value
->value
? a
->value
->value
: "");
3621 quotef(fp
, " Attribute \"%s\" \"%s\" \"%s\"\n",
3622 a
->name
->value
, a
->selector
->value
? a
->selector
->value
: "",
3623 a
->value
->value
? a
->value
->value
: "");
3625 // Output all of the constraints...
3626 for (co
= (ppdcConstraint
*)d
->constraints
->first();
3628 co
= (ppdcConstraint
*)d
->constraints
->next())
3630 if (co
->option1
->value
[0] == '*')
3631 cupsFilePrintf(fp
, " UIConstraints \"%s %s", co
->option1
->value
,
3632 co
->choice1
->value
? co
->choice1
->value
: "");
3634 cupsFilePrintf(fp
, " UIConstraints \"*%s %s", co
->option1
->value
,
3635 co
->choice1
->value
? co
->choice1
->value
: "");
3637 if (co
->option2
->value
[0] == '*')
3638 cupsFilePrintf(fp
, " %s %s\"\n", co
->option2
->value
,
3639 co
->choice2
->value
? co
->choice2
->value
: "");
3641 cupsFilePrintf(fp
, " *%s %s\"\n", co
->option2
->value
,
3642 co
->choice2
->value
? co
->choice2
->value
: "");
3645 // Output all of the filters...
3646 for (fi
= (ppdcFilter
*)d
->filters
->first();
3648 fi
= (ppdcFilter
*)d
->filters
->next())
3649 cupsFilePrintf(fp
, " Filter \"%s %d %s\"\n",
3650 fi
->mime_type
->value
, fi
->cost
, fi
->program
->value
);
3652 // Output all of the fonts...
3653 for (fo
= (ppdcFont
*)d
->fonts
->first();
3655 fo
= (ppdcFont
*)d
->fonts
->next())
3656 if (!strcmp(fo
->name
->value
, "*"))
3657 cupsFilePuts(fp
, " Font *\n");
3659 cupsFilePrintf(fp
, " Font \"%s\" \"%s\" \"%s\" \"%s\" %s\n",
3660 fo
->name
->value
, fo
->encoding
->value
,
3661 fo
->version
->value
, fo
->charset
->value
,
3662 fo
->status
== PPDC_FONT_ROM
? "ROM" : "Disk");
3664 // Output all options...
3665 for (g
= (ppdcGroup
*)d
->groups
->first();
3667 g
= (ppdcGroup
*)d
->groups
->next())
3669 if (g
->options
->count
== 0)
3672 if (g
->text
->value
&& g
->text
->value
[0])
3673 quotef(fp
, " Group \"%s/%s\"\n", g
->name
->value
, g
->text
->value
);
3675 cupsFilePrintf(fp
, " Group \"%s\"\n", g
->name
->value
);
3677 for (o
= (ppdcOption
*)g
->options
->first();
3679 o
= (ppdcOption
*)g
->options
->next())
3681 if (o
->choices
->count
== 0)
3684 if (o
->text
->value
&& o
->text
->value
[0])
3685 quotef(fp
, " Option \"%s/%s\"", o
->name
->value
, o
->text
->value
);
3687 cupsFilePrintf(fp
, " Option \"%s\"", o
->name
->value
);
3689 cupsFilePrintf(fp
, " %s %s %.1f\n",
3690 o
->type
== PPDC_BOOLEAN
? "Boolean" :
3691 o
->type
== PPDC_PICKONE
? "PickOne" : "PickMany",
3692 o
->section
== PPDC_SECTION_ANY
? "AnySetup" :
3693 o
->section
== PPDC_SECTION_DOCUMENT
? "DocumentSetup" :
3694 o
->section
== PPDC_SECTION_EXIT
? "ExitServer" :
3695 o
->section
== PPDC_SECTION_JCL
? "JCLSetup" :
3696 o
->section
== PPDC_SECTION_PAGE
? "PageSetup" :
3700 for (ch
= (ppdcChoice
*)o
->choices
->first();
3702 ch
= (ppdcChoice
*)o
->choices
->next())
3704 if (ch
->text
->value
&& ch
->text
->value
[0])
3705 quotef(fp
, " %sChoice \"%s/%s\" \"%s\"\n",
3706 o
->defchoice
== ch
->name
? "*" : "",
3707 ch
->name
->value
, ch
->text
->value
,
3708 ch
->code
->value
? ch
->code
->value
: "");
3710 quotef(fp
, " %sChoice \"%s\" \"%s\"\n",
3711 o
->defchoice
== ch
->name
? "*" : "",
3713 ch
->code
->value
? ch
->code
->value
: "");
3718 // Output all of the color profiles...
3719 for (p
= (ppdcProfile
*)d
->profiles
->first();
3721 p
= (ppdcProfile
*)d
->profiles
->next())
3722 cupsFilePrintf(fp
, " ColorProfile \"%s/%s\" %.3f %.3f "
3723 "%.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f %.3f\n",
3724 p
->resolution
->value
, p
->media_type
->value
,
3725 p
->density
, p
->gamma
,
3726 p
->profile
[0], p
->profile
[1], p
->profile
[2],
3727 p
->profile
[3], p
->profile
[4], p
->profile
[5],
3728 p
->profile
[6], p
->profile
[7], p
->profile
[8]);
3730 // Output all of the media sizes...
3736 for (si
= (ppdcMediaSize
*)d
->sizes
->first();
3738 si
= (ppdcMediaSize
*)d
->sizes
->next())
3739 if (si
->size_code
->value
&& si
->region_code
->value
)
3741 // Output a custom media size...
3742 quotef(fp
, " %sCustomMedia \"%s/%s\" %.2f %.2f %.2f %.2f %.2f %.2f \"%s\" \"%s\"\n",
3743 si
->name
== d
->default_size
? "*" : "", si
->name
->value
,
3744 si
->text
->value
, si
->width
, si
->length
, si
->left
, si
->bottom
,
3745 si
->right
, si
->top
, si
->size_code
->value
,
3746 si
->region_code
->value
);
3750 // Output a standard media size...
3751 if (fabs(left
- si
->left
) > 0.1 ||
3752 fabs(bottom
- si
->bottom
) > 0.1 ||
3753 fabs(right
- si
->right
) > 0.1 ||
3754 fabs(top
- si
->top
) > 0.1)
3756 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3757 si
->left
, si
->bottom
, si
->right
, si
->top
);
3760 bottom
= si
->bottom
;
3765 cupsFilePrintf(fp
, " %sMediaSize %s\n",
3766 si
->name
== d
->default_size
? "*" : "",
3770 if (d
->variable_paper_size
)
3772 cupsFilePuts(fp
, " VariablePaperSize Yes\n");
3774 if (fabs(left
- d
->left_margin
) > 0.1 ||
3775 fabs(bottom
- d
->bottom_margin
) > 0.1 ||
3776 fabs(right
- d
->right_margin
) > 0.1 ||
3777 fabs(top
- d
->top_margin
) > 0.1)
3779 cupsFilePrintf(fp
, " HWMargins %.2f %.2f %.2f %.2f\n",
3780 d
->left_margin
, d
->bottom_margin
, d
->right_margin
,
3784 cupsFilePrintf(fp
, " MinSize %.2f %.2f\n", d
->min_width
, d
->min_length
);
3785 cupsFilePrintf(fp
, " MaxSize %.2f %.2f\n", d
->max_width
, d
->max_length
);
3788 // End the driver...
3789 cupsFilePuts(fp
, "}\n");
3792 // Close the file and return...