]> git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc.cxx
Merge CUPS 1.4svn-r7319.
[thirdparty/cups.git] / ppdc / ppdc.cxx
1 //
2 // "$Id$"
3 //
4 // PPD file compiler main entry for the CUPS PPD Compiler.
5 //
6 // Copyright 2007 by Apple Inc.
7 // Copyright 2002-2007 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 // main() - Main entry for the PPD compiler.
18 // usage() - Show usage and exit.
19 //
20
21 //
22 // Include necessary headers...
23 //
24
25 #include "ppdc.h"
26 #include <sys/stat.h>
27 #include <sys/types.h>
28
29
30 //
31 // Local functions...
32 //
33
34 static void usage(void);
35
36
37 //
38 // 'main()' - Main entry for the PPD compiler.
39 //
40
41 int // O - Exit status
42 main(int argc, // I - Number of command-line arguments
43 char *argv[]) // I - Command-line arguments
44 {
45 int i, j; // Looping vars
46 ppdcCatalog *catalog; // Message catalog
47 const char *outdir; // Output directory
48 ppdcSource *src; // PPD source file data
49 ppdcDriver *d; // Current driver
50 cups_file_t *fp; // PPD file
51 char *opt, // Current option
52 *value, // Value in option
53 pcfilename[1024],
54 // Lowercase pcfilename
55 filename[1024]; // PPD filename
56 int verbose; // Verbosity
57 ppdcArray *locales; // List of locales
58 int comp; // Compress
59 ppdcLineEnding le; // Line ending to use
60
61
62 // Scan the command-line...
63 catalog = NULL;
64 outdir = "ppd";
65 src = new ppdcSource();
66 verbose = 0;
67 locales = NULL;
68 comp = 0;
69 le = PPDC_LFONLY;
70
71 for (i = 1; i < argc; i ++)
72 if (argv[i][0] == '-')
73 {
74 for (opt = argv[i] + 1; *opt; opt ++)
75 switch (*opt)
76 {
77 case 'c' : // Message catalog...
78 i ++;
79 if (i >= argc)
80 usage();
81
82 if (verbose > 1)
83 printf("ppdc: Loading messages from \"%s\"...\n", argv[i]);
84
85 if (!catalog)
86 catalog = new ppdcCatalog("en");
87
88 if (catalog->load_messages(argv[i]))
89 {
90 fprintf(stderr,
91 "ppdc: Unable to load localization file \"%s\" - %s\n",
92 argv[i], strerror(errno));
93 return (1);
94 }
95 break;
96
97 case 'd' : // Output directory...
98 i ++;
99 if (i >= argc)
100 usage();
101
102 if (verbose > 1)
103 printf("ppdc: Writing PPD files to directory \"%s\"...\n",
104 argv[i]);
105
106 outdir = argv[i];
107 break;
108
109 case 'l' : // Language(s)...
110 i ++;
111 if (i >= argc)
112 usage();
113
114 if (strchr(argv[i], ','))
115 {
116 // Comma-delimited list of languages...
117 char temp[1024], // Copy of language list
118 *start, // Start of current locale name
119 *end; // End of current locale name
120
121
122 locales = new ppdcArray();
123
124 strlcpy(temp, argv[i], sizeof(temp));
125 for (start = temp; *start; start = end)
126 {
127 if ((end = strchr(start, ',')) != NULL)
128 *end++ = '\0';
129 else
130 end = start + strlen(start);
131
132 if (end > start)
133 locales->add(new ppdcString(start));
134 }
135 }
136 else
137 {
138 if (verbose > 1)
139 printf("ppdc: Loading messages for locale \"%s\"...\n",
140 argv[i]);
141
142 if (catalog)
143 delete catalog;
144
145 catalog = new ppdcCatalog(argv[i]);
146
147 if (catalog->messages->count == 0)
148 {
149 fprintf(stderr,
150 "ppdc: Unable to find localization for \"%s\" - %s\n",
151 argv[i], strerror(errno));
152 return (1);
153 }
154 }
155 break;
156
157 case 'D' : // Define variable
158 i ++;
159 if (i >= argc)
160 usage();
161
162 if ((value = strchr(argv[i], '=')) != NULL)
163 {
164 *value++ = '\0';
165
166 src->set_variable(argv[i], value);
167 }
168 else
169 src->set_variable(argv[i], "1");
170 break;
171
172 case 'I' : // Include directory...
173 i ++;
174 if (i >= argc)
175 usage();
176
177 if (verbose > 1)
178 printf("ppdc: Adding include directory \"%s\"...\n", argv[i]);
179
180 ppdcSource::add_include(argv[i]);
181 break;
182
183 case 'v' : // Be verbose...
184 verbose ++;
185 break;
186
187 case 'z' : // Compress files...
188 comp = 1;
189 break;
190
191 case '-' : // --option
192 if (!strcmp(opt, "-lf"))
193 {
194 le = PPDC_LFONLY;
195 opt += strlen(opt) - 1;
196 break;
197 }
198 else if (!strcmp(opt, "-cr"))
199 {
200 le = PPDC_CRONLY;
201 opt += strlen(opt) - 1;
202 break;
203 }
204 else if (!strcmp(opt, "-crlf"))
205 {
206 le = PPDC_CRLF;
207 opt += strlen(opt) - 1;
208 break;
209 }
210
211 default : // Unknown
212 usage();
213 break;
214 }
215 }
216 else
217 {
218 // Open and load the driver info file...
219 if (verbose > 1)
220 printf("ppdc: Loading driver information file \"%s\"...\n", argv[i]);
221
222 src->read_file(argv[i]);
223 }
224
225
226 if (src->drivers->count > 0)
227 {
228 // Create the output directory...
229 if (mkdir(outdir, 0777))
230 {
231 if (errno != EEXIST)
232 {
233 fprintf(stderr, "ppdc: Unable to create output directory %s: %s\n",
234 outdir, strerror(errno));
235 return (1);
236 }
237 }
238
239 // Write PPD files...
240 for (d = (ppdcDriver *)src->drivers->first();
241 d;
242 d = (ppdcDriver *)src->drivers->next())
243 {
244 // Write the PPD file for this driver...
245 if (strstr(d->pc_file_name->value, ".PPD"))
246 {
247 // Convert PCFileName to lowercase...
248 for (j = 0;
249 d->pc_file_name->value[j] && j < (int)(sizeof(pcfilename) - 1);
250 j ++)
251 pcfilename[j] = tolower(d->pc_file_name->value[j]);
252
253 pcfilename[j] = '\0';
254 }
255 else
256 {
257 // Leave PCFileName as-is...
258 strlcpy(pcfilename, d->pc_file_name->value, sizeof(pcfilename));
259 }
260
261 // Open the PPD file for writing...
262 if (comp)
263 snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
264 else
265 snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
266
267 fp = cupsFileOpen(filename, comp ? "w9" : "w");
268 if (!fp)
269 {
270 fprintf(stderr, "ppdc: Unable to create PPD file \"%s\" - %s.\n",
271 filename, strerror(errno));
272 return (1);
273 }
274
275 if (verbose)
276 printf("ppdc: Writing %s...\n", filename);
277
278 if (d->write_ppd_file(fp, catalog, locales, src, le))
279 {
280 cupsFileClose(fp);
281 return (1);
282 }
283
284 cupsFileClose(fp);
285 }
286 }
287 else
288 usage();
289
290 // Delete the printer driver information...
291 delete src;
292
293 // Message catalog...
294 if (catalog)
295 delete catalog;
296
297 // Return with no errors.
298 return (0);
299 }
300
301
302 //
303 // 'usage()' - Show usage and exit.
304 //
305
306 static void
307 usage(void)
308 {
309 puts("Usage: ppdc [options] filename.drv [ ... filenameN.drv ]");
310 puts("Options:");
311 puts(" -D name=value Set named variable to value.");
312 puts(" -I include-dir Add include directory to search path.");
313 puts(" -c catalog.po Load the specified message catalog.");
314 puts(" -d output-dir Specify the output directory.");
315 puts(" -l lang[,lang,...] Specify the output language(s) (locale).");
316 puts(" -v Be verbose (more v's for more verbosity).");
317 puts(" -z Compress PPD files using GNU zip.");
318 puts(" --cr End lines with CR (Mac OS 9).");
319 puts(" --crlf End lines with CR + LF (Windows).");
320 puts(" --lf End lines with LF (UNIX/Linux/Mac OS X).");
321
322 exit(1);
323 }
324
325
326 //
327 // End of "$Id$".
328 //