]> git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc-import.cxx
4794e77151929d427f81552a19b006329d31343c
[thirdparty/cups.git] / ppdc / ppdc-import.cxx
1 //
2 // "$Id$"
3 //
4 // PPD file import methods for the CUPS PPD Compiler.
5 //
6 // Copyright 2007-2011 by Apple Inc.
7 // Copyright 2002-2006 by Easy Software Products.
8 //
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/".
14 //
15 // Contents:
16 //
17 // ppdcSource::import_ppd() - Import a PPD file.
18 // ppd_gets() - Get a line from a PPD file.
19 //
20
21 //
22 // Include necessary headers...
23 //
24
25 #include "ppdc-private.h"
26 #include <cups/ppd.h>
27
28
29 //
30 // 'ppdcSource::import_ppd()' - Import a PPD file.
31 //
32
33 int // O - 1 on success, 0 on failure
34 ppdcSource::import_ppd(const char *f) // I - Filename
35 {
36 int i, j, k; // Looping vars
37 cups_file_t *fp; // File
38 char line[256], // Comment line
39 *ptr; // Pointer into line
40 int cost; // Cost for filter
41 ppd_file_t *ppd; // PPD file data
42 ppd_group_t *group; // PPD group
43 ppd_option_t *option; // PPD option
44 ppd_choice_t *choice; // PPD choice
45 ppd_attr_t *attr; // PPD attribute
46 ppd_const_t *constraint; // PPD UI constraint
47 ppd_const_t *constraint2; // Temp PPD UI constraint
48 ppd_size_t *size; // PPD page size
49 ppdcDriver *driver; // Driver
50 ppdcFilter *filter; // Current filter
51 ppdcFont *font; // Font
52 ppdcGroup *cgroup; // UI group
53 ppdcOption *coption; // UI option
54 ppdcChoice *cchoice; // UI choice
55 ppdcConstraint *cconstraint; // UI constraint
56 ppdcMediaSize *csize; // Media size
57
58
59 // Try opening the PPD file...
60 if ((ppd = ppdOpenFile(f)) == NULL)
61 return (0);
62
63 // All PPD files need a PCFileName attribute...
64 if (!ppd->pcfilename)
65 {
66 ppdClose(ppd);
67 return (0);
68 }
69
70 // See if the driver has already been imported...
71 if ((driver = find_driver(ppd->pcfilename)) == NULL)
72 {
73 // Create a new PPD file...
74 if ((fp = cupsFileOpen(f, "r")) == NULL)
75 {
76 ppdClose(ppd);
77 return (0);
78 }
79
80 driver = new ppdcDriver();
81 driver->type = PPDC_DRIVER_PS;
82
83 drivers->add(driver);
84
85 // Read the initial comments from the PPD file and use them as the
86 // copyright/license text...
87 cupsFileGets(fp, line, sizeof(line));
88 // Skip *PPD-Adobe-M.m
89
90 while (cupsFileGets(fp, line, sizeof(line)))
91 if (strncmp(line, "*%", 2))
92 break;
93 else if (strncmp(line, "*%%%% ", 6))
94 {
95 for (ptr = line + 2; isspace(*ptr); ptr ++);
96
97 driver->add_copyright(ptr);
98 }
99
100 cupsFileClose(fp);
101
102 // Then add the stuff from the PPD file...
103 if (ppd->modelname && ppd->manufacturer &&
104 !_cups_strncasecmp(ppd->modelname, ppd->manufacturer,
105 strlen(ppd->manufacturer)))
106 {
107 ptr = ppd->modelname + strlen(ppd->manufacturer);
108
109 while (isspace(*ptr))
110 ptr ++;
111 }
112 else
113 ptr = ppd->modelname;
114
115 if (ppd->nickname)
116 driver->add_attr(new ppdcAttr("NickName", NULL, NULL, ppd->nickname));
117
118 if (ppd->shortnickname)
119 driver->add_attr(new ppdcAttr("ShortNickName", NULL, NULL,
120 ppd->shortnickname));
121
122 driver->manufacturer = new ppdcString(ppd->manufacturer);
123 driver->model_name = new ppdcString(ptr);
124 driver->pc_file_name = new ppdcString(ppd->pcfilename);
125 attr = ppdFindAttr(ppd, "FileVersion", NULL);
126 driver->version = new ppdcString(attr ? attr->value : NULL);
127 driver->model_number = ppd->model_number;
128 driver->manual_copies = ppd->manual_copies;
129 driver->color_device = ppd->color_device;
130 driver->throughput = ppd->throughput;
131 driver->variable_paper_size = ppd->variable_sizes;
132 driver->max_width = ppd->custom_max[0];
133 driver->max_length = ppd->custom_max[1];
134 driver->min_width = ppd->custom_min[0];
135 driver->min_length = ppd->custom_min[1];
136 driver->left_margin = ppd->custom_margins[0];
137 driver->bottom_margin = ppd->custom_margins[1];
138 driver->right_margin = ppd->custom_margins[2];
139 driver->top_margin = ppd->custom_margins[3];
140
141 for (i = 0; i < ppd->num_filters; i ++)
142 {
143 strlcpy(line, ppd->filters[i], sizeof(line));
144
145 for (ptr = line; *ptr; ptr ++)
146 if (isspace(*ptr & 255))
147 break;
148 *ptr++ = '\0';
149
150 cost = strtol(ptr, &ptr, 10);
151
152 while (isspace(*ptr & 255))
153 ptr ++;
154
155 filter = new ppdcFilter(line, ptr, cost);
156 driver->add_filter(filter);
157 }
158
159 attr = ppdFindAttr(ppd, "DefaultFont", NULL);
160 driver->default_font = new ppdcString(attr ? attr->value : NULL);
161
162 // Collect media sizes...
163 ppd_option_t *region_option, // PageRegion option
164 *size_option; // PageSize option
165 ppd_choice_t *region_choice, // PageRegion choice
166 *size_choice; // PageSize choice
167
168 region_option = ppdFindOption(ppd, "PageRegion");
169 size_option = ppdFindOption(ppd, "PageSize");
170
171 for (i = ppd->num_sizes, size = ppd->sizes; i > 0; i --, size ++)
172 {
173 // Don't do custom size here...
174 if (!_cups_strcasecmp(size->name, "Custom"))
175 continue;
176
177 // Get the code for the PageSize and PageRegion options...
178 region_choice = ppdFindChoice(region_option, size->name);
179 size_choice = ppdFindChoice(size_option, size->name);
180
181 // Create a new media size record and add it to the driver...
182 csize = new ppdcMediaSize(size->name, size_choice->text, size->width,
183 size->length, size->left, size->bottom,
184 size->width - size->right,
185 size->length - size->top,
186 size_choice->code, region_choice->code);
187
188 driver->add_size(csize);
189
190 if (!_cups_strcasecmp(size_option->defchoice, size->name))
191 driver->set_default_size(csize);
192 }
193
194 // Now all of the options...
195 for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
196 {
197 cgroup = new ppdcGroup(group->name, group->text);
198 driver->add_group(cgroup);
199
200 for (j = group->num_options, option = group->options; j > 0; j --, option ++)
201 {
202 if (!strcmp(option->keyword, "PageSize") || !strcmp(option->keyword, "PageRegion"))
203 continue;
204
205 coption = new ppdcOption((ppdcOptType)option->ui, option->keyword,
206 option->text, (ppdcOptSection)option->section,
207 option->order);
208 cgroup->add_option(coption);
209
210 for (k = option->num_choices, choice = option->choices; k > 0; k --, choice ++)
211 {
212 if (!strcmp(choice->choice, "Custom"))
213 continue;
214
215 cchoice = new ppdcChoice(choice->choice, choice->text, choice->code);
216 coption->add_choice(cchoice);
217
218 if (!_cups_strcasecmp(option->defchoice, choice->choice))
219 coption->set_defchoice(cchoice);
220 }
221 }
222 }
223
224 // Now the constraints...
225 for (i = ppd->num_consts, constraint = ppd->consts;
226 i > 0;
227 i --, constraint ++)
228 {
229 // Look for mirrored constraints...
230 for (j = i - 1, constraint2 = constraint + 1;
231 j > 0;
232 j --, constraint2 ++)
233 if (!strcmp(constraint->option1, constraint2->option2) &&
234 !strcmp(constraint->choice1, constraint2->choice2) &&
235 !strcmp(constraint->option2, constraint2->option1) &&
236 !strcmp(constraint->choice2, constraint2->choice1))
237 break;
238
239 if (j)
240 continue;
241
242 cconstraint = new ppdcConstraint(constraint->option2, constraint->choice2,
243 constraint->option1, constraint->choice1);
244 driver->add_constraint(cconstraint);
245 }
246
247 for (i = 0; i < ppd->num_attrs; i ++)
248 {
249 attr = ppd->attrs[i];
250
251 if (!strcmp(attr->name, "Font"))
252 {
253 // Font...
254 char encoding[256], // Encoding string
255 version[256], // Version string
256 charset[256], // Charset string
257 status[256]; // Status string
258 ppdcFontStatus fstatus; // Status enumeration
259
260
261 if (sscanf(attr->value, "%s%*[^\"]\"%[^\"]\"%s%s", encoding, version,
262 charset, status) != 4)
263 {
264 _cupsLangPrintf(stderr, _("ppdc: Bad font attribute: %s"),
265 attr->value);
266 continue;
267 }
268
269 if (!strcmp(status, "ROM"))
270 fstatus = PPDC_FONT_ROM;
271 else
272 fstatus = PPDC_FONT_DISK;
273
274 font = new ppdcFont(attr->spec, encoding, version, charset, fstatus);
275
276 driver->add_font(font);
277 }
278 else if (!strcmp(attr->name, "CustomPageSize"))
279 {
280 driver->set_custom_size_code(attr->value);
281 }
282 else if ((strncmp(attr->name, "Default", 7) ||
283 !strcmp(attr->name, "DefaultColorSpace")) &&
284 strcmp(attr->name, "ColorDevice") &&
285 strcmp(attr->name, "Manufacturer") &&
286 strcmp(attr->name, "ModelName") &&
287 strcmp(attr->name, "MaxMediaHeight") &&
288 strcmp(attr->name, "MaxMediaWidth") &&
289 strcmp(attr->name, "NickName") &&
290 strcmp(attr->name, "ParamCustomPageSize") &&
291 strcmp(attr->name, "ShortNickName") &&
292 strcmp(attr->name, "Throughput") &&
293 strcmp(attr->name, "PCFileName") &&
294 strcmp(attr->name, "FileVersion") &&
295 strcmp(attr->name, "FormatVersion") &&
296 strcmp(attr->name, "HWMargins") &&
297 strcmp(attr->name, "VariablePaperSize") &&
298 strcmp(attr->name, "LanguageEncoding") &&
299 strcmp(attr->name, "LanguageVersion") &&
300 strcmp(attr->name, "cupsFilter") &&
301 strcmp(attr->name, "cupsFlipDuplex") &&
302 strcmp(attr->name, "cupsLanguages") &&
303 strcmp(attr->name, "cupsManualCopies") &&
304 strcmp(attr->name, "cupsModelNumber") &&
305 strcmp(attr->name, "cupsVersion"))
306 {
307 if ((ptr = strchr(attr->name, '.')) != NULL &&
308 ((ptr - attr->name) == 2 || (ptr - attr->name) == 5))
309 {
310 // Might be a localization attribute; test further...
311 if (isalpha(attr->name[0] & 255) &&
312 isalpha(attr->name[1] & 255) &&
313 (attr->name[2] == '.' ||
314 (attr->name[2] == '_' && isalpha(attr->name[3] & 255) &&
315 isalpha(attr->name[4] & 255))))
316 continue;
317 }
318
319 // Attribute...
320 driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
321 attr->value));
322 }
323 else if (!strncmp(attr->name, "Default", 7) &&
324 !ppdFindOption(ppd, attr->name + 7) &&
325 strcmp(attr->name, "DefaultFont") &&
326 strcmp(attr->name, "DefaultImageableArea") &&
327 strcmp(attr->name, "DefaultPaperDimension") &&
328 strcmp(attr->name, "DefaultFont"))
329 {
330 // Default attribute...
331 driver->add_attr(new ppdcAttr(attr->name, attr->spec, attr->text,
332 attr->value));
333 }
334 }
335 }
336
337 return (1);
338 }
339
340
341 //
342 // End of "$Id$".
343 //