Revert manifest to default one
[external/cups.git] / ppdc / ppdc-import.cxx
1 //
2 // "$Id: ppdc-import.cxx 9793 2011-05-20 03:49:49Z mike $"
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: ppdc-import.cxx 9793 2011-05-20 03:49:49Z mike $".
343 //