]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-import.cxx
2b36c6bd7847e912a6392b28df452b57c6a7f7b7
2 // PPD file import methods for the CUPS PPD Compiler.
4 // Copyright 2007-2011 by Apple Inc.
5 // Copyright 2002-2006 by Easy Software Products.
7 // These coded instructions, statements, and computer programs are the
8 // property of Apple Inc. and are protected by Federal copyright
9 // law. Distribution and use rights are outlined in the file "LICENSE.txt"
10 // which should have been included with this file. If this file is
11 // file is missing or damaged, see the license at "http://www.cups.org/".
15 // Include necessary headers...
18 #include "ppdc-private.h"
23 // 'ppdcSource::import_ppd()' - Import a PPD file.
26 int // O - 1 on success, 0 on failure
27 ppdcSource::import_ppd(const char *f
) // I - Filename
29 int i
, j
, k
; // Looping vars
30 cups_file_t
*fp
; // File
31 char line
[256], // Comment line
32 *ptr
; // Pointer into line
33 int cost
; // Cost for filter
34 ppd_file_t
*ppd
; // PPD file data
35 ppd_group_t
*group
; // PPD group
36 ppd_option_t
*option
; // PPD option
37 ppd_choice_t
*choice
; // PPD choice
38 ppd_attr_t
*attr
; // PPD attribute
39 ppd_const_t
*constraint
; // PPD UI constraint
40 ppd_const_t
*constraint2
; // Temp PPD UI constraint
41 ppd_size_t
*size
; // PPD page size
42 ppdcDriver
*driver
; // Driver
43 ppdcFilter
*filter
; // Current filter
44 ppdcFont
*font
; // Font
45 ppdcGroup
*cgroup
; // UI group
46 ppdcOption
*coption
; // UI option
47 ppdcChoice
*cchoice
; // UI choice
48 ppdcConstraint
*cconstraint
; // UI constraint
49 ppdcMediaSize
*csize
; // Media size
52 // Try opening the PPD file...
53 if ((ppd
= ppdOpenFile(f
)) == NULL
)
56 // All PPD files need a PCFileName attribute...
63 // See if the driver has already been imported...
64 if ((driver
= find_driver(ppd
->pcfilename
)) == NULL
)
66 // Create a new PPD file...
67 if ((fp
= cupsFileOpen(f
, "r")) == NULL
)
73 driver
= new ppdcDriver();
74 driver
->type
= PPDC_DRIVER_PS
;
78 // Read the initial comments from the PPD file and use them as the
79 // copyright/license text...
80 cupsFileGets(fp
, line
, sizeof(line
));
81 // Skip *PPD-Adobe-M.m
83 while (cupsFileGets(fp
, line
, sizeof(line
)))
84 if (strncmp(line
, "*%", 2))
86 else if (strncmp(line
, "*%%%% ", 6))
88 for (ptr
= line
+ 2; isspace(*ptr
); ptr
++);
90 driver
->add_copyright(ptr
);
95 // Then add the stuff from the PPD file...
96 if (ppd
->modelname
&& ppd
->manufacturer
&&
97 !_cups_strncasecmp(ppd
->modelname
, ppd
->manufacturer
,
98 strlen(ppd
->manufacturer
)))
100 ptr
= ppd
->modelname
+ strlen(ppd
->manufacturer
);
102 while (isspace(*ptr
))
106 ptr
= ppd
->modelname
;
109 driver
->add_attr(new ppdcAttr("NickName", NULL
, NULL
, ppd
->nickname
));
111 if (ppd
->shortnickname
)
112 driver
->add_attr(new ppdcAttr("ShortNickName", NULL
, NULL
,
113 ppd
->shortnickname
));
115 driver
->manufacturer
= new ppdcString(ppd
->manufacturer
);
116 driver
->model_name
= new ppdcString(ptr
);
117 driver
->pc_file_name
= new ppdcString(ppd
->pcfilename
);
118 attr
= ppdFindAttr(ppd
, "FileVersion", NULL
);
119 driver
->version
= new ppdcString(attr
? attr
->value
: NULL
);
120 driver
->model_number
= ppd
->model_number
;
121 driver
->manual_copies
= ppd
->manual_copies
;
122 driver
->color_device
= ppd
->color_device
;
123 driver
->throughput
= ppd
->throughput
;
124 driver
->variable_paper_size
= ppd
->variable_sizes
;
125 driver
->max_width
= ppd
->custom_max
[0];
126 driver
->max_length
= ppd
->custom_max
[1];
127 driver
->min_width
= ppd
->custom_min
[0];
128 driver
->min_length
= ppd
->custom_min
[1];
129 driver
->left_margin
= ppd
->custom_margins
[0];
130 driver
->bottom_margin
= ppd
->custom_margins
[1];
131 driver
->right_margin
= ppd
->custom_margins
[2];
132 driver
->top_margin
= ppd
->custom_margins
[3];
134 for (i
= 0; i
< ppd
->num_filters
; i
++)
136 strlcpy(line
, ppd
->filters
[i
], sizeof(line
));
138 for (ptr
= line
; *ptr
; ptr
++)
139 if (isspace(*ptr
& 255))
143 cost
= strtol(ptr
, &ptr
, 10);
145 while (isspace(*ptr
& 255))
148 filter
= new ppdcFilter(line
, ptr
, cost
);
149 driver
->add_filter(filter
);
152 attr
= ppdFindAttr(ppd
, "DefaultFont", NULL
);
153 driver
->default_font
= new ppdcString(attr
? attr
->value
: NULL
);
155 // Collect media sizes...
156 ppd_option_t
*region_option
, // PageRegion option
157 *size_option
; // PageSize option
158 ppd_choice_t
*region_choice
, // PageRegion choice
159 *size_choice
; // PageSize choice
161 region_option
= ppdFindOption(ppd
, "PageRegion");
162 size_option
= ppdFindOption(ppd
, "PageSize");
164 for (i
= ppd
->num_sizes
, size
= ppd
->sizes
; i
> 0; i
--, size
++)
166 // Don't do custom size here...
167 if (!_cups_strcasecmp(size
->name
, "Custom"))
170 // Get the code for the PageSize and PageRegion options...
171 region_choice
= ppdFindChoice(region_option
, size
->name
);
172 size_choice
= ppdFindChoice(size_option
, size
->name
);
174 // Create a new media size record and add it to the driver...
175 csize
= new ppdcMediaSize(size
->name
, size_choice
->text
, size
->width
,
176 size
->length
, size
->left
, size
->bottom
,
177 size
->width
- size
->right
,
178 size
->length
- size
->top
,
179 size_choice
->code
, region_choice
->code
);
181 driver
->add_size(csize
);
183 if (!_cups_strcasecmp(size_option
->defchoice
, size
->name
))
184 driver
->set_default_size(csize
);
187 // Now all of the options...
188 for (i
= ppd
->num_groups
, group
= ppd
->groups
; i
> 0; i
--, group
++)
190 cgroup
= new ppdcGroup(group
->name
, group
->text
);
191 driver
->add_group(cgroup
);
193 for (j
= group
->num_options
, option
= group
->options
; j
> 0; j
--, option
++)
195 if (!strcmp(option
->keyword
, "PageSize") || !strcmp(option
->keyword
, "PageRegion"))
198 coption
= new ppdcOption((ppdcOptType
)option
->ui
, option
->keyword
,
199 option
->text
, (ppdcOptSection
)option
->section
,
201 cgroup
->add_option(coption
);
203 for (k
= option
->num_choices
, choice
= option
->choices
; k
> 0; k
--, choice
++)
205 if (!strcmp(choice
->choice
, "Custom"))
208 cchoice
= new ppdcChoice(choice
->choice
, choice
->text
, choice
->code
);
209 coption
->add_choice(cchoice
);
211 if (!_cups_strcasecmp(option
->defchoice
, choice
->choice
))
212 coption
->set_defchoice(cchoice
);
217 // Now the constraints...
218 for (i
= ppd
->num_consts
, constraint
= ppd
->consts
;
222 // Look for mirrored constraints...
223 for (j
= i
- 1, constraint2
= constraint
+ 1;
225 j
--, constraint2
++)
226 if (!strcmp(constraint
->option1
, constraint2
->option2
) &&
227 !strcmp(constraint
->choice1
, constraint2
->choice2
) &&
228 !strcmp(constraint
->option2
, constraint2
->option1
) &&
229 !strcmp(constraint
->choice2
, constraint2
->choice1
))
235 cconstraint
= new ppdcConstraint(constraint
->option2
, constraint
->choice2
,
236 constraint
->option1
, constraint
->choice1
);
237 driver
->add_constraint(cconstraint
);
240 for (i
= 0; i
< ppd
->num_attrs
; i
++)
242 attr
= ppd
->attrs
[i
];
244 if (!strcmp(attr
->name
, "Font"))
247 char encoding
[256], // Encoding string
248 version
[256], // Version string
249 charset
[256], // Charset string
250 status
[256]; // Status string
251 ppdcFontStatus fstatus
; // Status enumeration
254 if (sscanf(attr
->value
, "%s%*[^\"]\"%[^\"]\"%s%s", encoding
, version
,
255 charset
, status
) != 4)
257 _cupsLangPrintf(stderr
, _("ppdc: Bad font attribute: %s"),
262 if (!strcmp(status
, "ROM"))
263 fstatus
= PPDC_FONT_ROM
;
265 fstatus
= PPDC_FONT_DISK
;
267 font
= new ppdcFont(attr
->spec
, encoding
, version
, charset
, fstatus
);
269 driver
->add_font(font
);
271 else if (!strcmp(attr
->name
, "CustomPageSize"))
273 driver
->set_custom_size_code(attr
->value
);
275 else if ((strncmp(attr
->name
, "Default", 7) ||
276 !strcmp(attr
->name
, "DefaultColorSpace")) &&
277 strcmp(attr
->name
, "ColorDevice") &&
278 strcmp(attr
->name
, "Manufacturer") &&
279 strcmp(attr
->name
, "ModelName") &&
280 strcmp(attr
->name
, "MaxMediaHeight") &&
281 strcmp(attr
->name
, "MaxMediaWidth") &&
282 strcmp(attr
->name
, "NickName") &&
283 strcmp(attr
->name
, "ParamCustomPageSize") &&
284 strcmp(attr
->name
, "ShortNickName") &&
285 strcmp(attr
->name
, "Throughput") &&
286 strcmp(attr
->name
, "PCFileName") &&
287 strcmp(attr
->name
, "FileVersion") &&
288 strcmp(attr
->name
, "FormatVersion") &&
289 strcmp(attr
->name
, "HWMargins") &&
290 strcmp(attr
->name
, "VariablePaperSize") &&
291 strcmp(attr
->name
, "LanguageEncoding") &&
292 strcmp(attr
->name
, "LanguageVersion") &&
293 strcmp(attr
->name
, "cupsFilter") &&
294 strcmp(attr
->name
, "cupsFlipDuplex") &&
295 strcmp(attr
->name
, "cupsLanguages") &&
296 strcmp(attr
->name
, "cupsManualCopies") &&
297 strcmp(attr
->name
, "cupsModelNumber") &&
298 strcmp(attr
->name
, "cupsVersion"))
300 if ((ptr
= strchr(attr
->name
, '.')) != NULL
&&
301 ((ptr
- attr
->name
) == 2 || (ptr
- attr
->name
) == 5))
303 // Might be a localization attribute; test further...
304 if (isalpha(attr
->name
[0] & 255) &&
305 isalpha(attr
->name
[1] & 255) &&
306 (attr
->name
[2] == '.' ||
307 (attr
->name
[2] == '_' && isalpha(attr
->name
[3] & 255) &&
308 isalpha(attr
->name
[4] & 255))))
313 driver
->add_attr(new ppdcAttr(attr
->name
, attr
->spec
, attr
->text
,
316 else if (!strncmp(attr
->name
, "Default", 7) &&
317 !ppdFindOption(ppd
, attr
->name
+ 7) &&
318 strcmp(attr
->name
, "DefaultFont") &&
319 strcmp(attr
->name
, "DefaultImageableArea") &&
320 strcmp(attr
->name
, "DefaultPaperDimension") &&
321 strcmp(attr
->name
, "DefaultFont"))
323 // Default attribute...
324 driver
->add_attr(new ppdcAttr(attr
->name
, attr
->spec
, attr
->text
,