1 //
2 // PPD file message catalog program for the CUPS PPD Compiler.
3 //
4 // Copyright 2007-2015 by Apple Inc.
5 // Copyright 2002-2005 by Easy Software Products.
6 //
7 // Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8 //
9
10 //
11 // Include necessary headers...
12 //
13
14 #include "ppdc-private.h"
15 #include <sys/stat.h>
16 #include <sys/types.h>
17
18
19 //
20 // Local functions...
21 //
22
23 static void add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog);
24 static void usage(void);
25
26
27 //
28 // 'main()' - Main entry for the PPD compiler.
29 //
30
31 int // O - Exit status
main(int argc,char * argv[])32 main(int argc, // I - Number of command-line arguments
33 char *argv[]) // I - Command-line arguments
34 {
35 int i; // Looping var
36 ppdcCatalog *catalog; // Message catalog
37 ppdcSource *src; // PPD source file data
38 ppdcDriver *d; // Current driver
39 char *opt; // Current option
40 int verbose; // Verbosity
41 const char *outfile; // Output file
42 char *value; // Value in option
43
44
45 _cupsSetLocale(argv);
46
47 // Scan the command-line...
48 catalog = new ppdcCatalog("en");
49 src = new ppdcSource();
50 verbose = 0;
51 outfile = 0;
52
53 for (i = 1; i < argc; i ++)
54 if (argv[i][0] == '-')
55 {
56 for (opt = argv[i] + 1; *opt; opt ++)
57 switch (*opt)
58 {
59 case 'D' : // Define variable
60 i ++;
61 if (i >= argc)
62 usage();
63
64 if ((value = strchr(argv[i], '=')) != NULL)
65 {
66 *value++ = '\0';
67
68 src->set_variable(argv[i], value);
69 }
70 else
71 src->set_variable(argv[i], "1");
72 break;
73
74 case 'I' : // Include directory...
75 i ++;
76 if (i >= argc)
77 usage();
78
79 if (verbose > 1)
80 _cupsLangPrintf(stdout,
81 _("ppdc: Adding include directory \"%s\"."),
82 argv[i]);
83
84 ppdcSource::add_include(argv[i]);
85 break;
86
87 case 'o' : // Output file...
88 i ++;
89 if (i >= argc || outfile)
90 usage();
91
92 outfile = argv[i];
93
94 catalog->load_messages(outfile);
95 break;
96
97 case 'v' : // Be verbose...
98 verbose ++;
99 break;
100
101 default : // Unknown
102 usage();
103 break;
104 }
105 }
106 else
107 {
108 // Open and load the driver info file...
109 if (verbose > 1)
110 _cupsLangPrintf(stdout,
111 _("ppdc: Loading driver information file \"%s\"."),
112 argv[i]);
113
114 src->read_file(argv[i]);
115 }
116
117 // If no drivers have been loaded, display the program usage message.
118 if ((d = (ppdcDriver *)src->drivers->first()) != NULL)
119 {
120 // Add UI strings...
121 while (d != NULL)
122 {
123 if (verbose)
124 _cupsLangPrintf(stderr, _("ppdc: Adding/updating UI text from %s."), argv[i]);
125
126 add_ui_strings(d, catalog);
127
128 d = (ppdcDriver *)src->drivers->next();
129 }
130 }
131 else
132 usage();
133
134 // Delete the printer driver information...
135 src->release();
136
137 // Write the message catalog...
138 if (!outfile)
139 usage();
140 else
141 catalog->save_messages(outfile);
142
143 catalog->release();
144
145 // Return with no errors.
146 return (0);
147 }
148
149
150 //
151 // 'add_ui_strings()' - Add all UI strings from the driver.
152 //
153
154 static void
add_ui_strings(ppdcDriver * d,ppdcCatalog * catalog)155 add_ui_strings(ppdcDriver *d, // I - Driver data
156 ppdcCatalog *catalog) // I - Message catalog
157 {
158 // Add the make/model/language strings...
159 catalog->add_message(d->manufacturer->value);
160 catalog->add_message(d->model_name->value);
161
162 // Add the media size strings...
163 ppdcMediaSize *m; // Current media size
164
165 for (m = (ppdcMediaSize *)d->sizes->first();
166 m;
167 m = (ppdcMediaSize *)d->sizes->next())
168 catalog->add_message(m->text->value);
169
170 // Add the group/option/choice strings...
171 ppdcGroup *g; // Current group
172 ppdcOption *o; // Current option
173 ppdcChoice *c; // Current choice
174
175 for (g = (ppdcGroup *)d->groups->first();
176 g;
177 g = (ppdcGroup *)d->groups->next())
178 {
179 if (!g->options->count)
180 continue;
181
182 if (_cups_strcasecmp(g->name->value, "General"))
183 catalog->add_message(g->text->value);
184
185 for (o = (ppdcOption *)g->options->first();
186 o;
187 o = (ppdcOption *)g->options->next())
188 {
189 if (!o->choices->count)
190 continue;
191
192 if (o->text->value)
193 catalog->add_message(o->text->value);
194 else
195 catalog->add_message(o->name->value);
196
197 for (c = (ppdcChoice *)o->choices->first();
198 c;
199 c = (ppdcChoice *)o->choices->next())
200 if (c->text->value)
201 catalog->add_message(c->text->value);
202 else
203 catalog->add_message(c->name->value);
204 }
205 }
206
207 // Add profile and preset strings...
208 ppdcAttr *a; // Current attribute
209 for (a = (ppdcAttr *)d->attrs->first();
210 a;
211 a = (ppdcAttr *)d->attrs->next())
212 if (a->text->value && a->text->value[0] &&
213 (a->localizable ||
214 !strncmp(a->name->value, "Custom", 6) ||
215 !strncmp(a->name->value, "ParamCustom", 11) ||
216 !strcmp(a->name->value, "APCustomColorMatchingName") ||
217 !strcmp(a->name->value, "APPrinterPreset") ||
218 !strcmp(a->name->value, "cupsICCProfile") ||
219 !strcmp(a->name->value, "cupsIPPReason") ||
220 !strcmp(a->name->value, "cupsMarkerName")))
221 {
222 catalog->add_message(a->text->value);
223
224 if ((a->localizable && a->value->value[0]) ||
225 !strcmp(a->name->value, "cupsIPPReason"))
226 catalog->add_message(a->value->value);
227 }
228 else if (!strncmp(a->name->value, "Custom", 6) ||
229 !strncmp(a->name->value, "ParamCustom", 11))
230 catalog->add_message(a->name->value);
231 }
232
233
234 //
235 // 'usage()' - Show usage and exit.
236 //
237
238 static void
usage(void)239 usage(void)
240 {
241 _cupsLangPuts(stdout, _("Usage: ppdpo [options] -o filename.po filename.drv "
242 "[ ... filenameN.drv ]"));
243 _cupsLangPuts(stdout, _("Options:"));
244 _cupsLangPuts(stdout, _(" -D name=value Set named variable to "
245 "value."));
246 _cupsLangPuts(stdout, _(" -I include-dir Add include directory to "
247 "search path."));
248 _cupsLangPuts(stdout, _(" -v Be verbose."));
249
250 exit(1);
251 }
252