]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdc.cxx
4 // PPD file compiler main entry for the CUPS PPD Compiler.
6 // Copyright 2007-2010 by Apple Inc.
7 // Copyright 2002-2007 by Easy Software Products.
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/".
17 // main() - Main entry for the PPD compiler.
18 // usage() - Show usage and exit.
22 // Include necessary headers...
25 #include "ppdc-private.h"
28 #include <sys/types.h>
35 static void usage(void);
39 // 'main()' - Main entry for the PPD compiler.
42 int // O - Exit status
43 main(int argc
, // I - Number of command-line arguments
44 char *argv
[]) // I - Command-line arguments
46 int i
, j
; // Looping vars
47 ppdcCatalog
*catalog
; // Message catalog
48 const char *outdir
; // Output directory
49 ppdcSource
*src
; // PPD source file data
50 ppdcDriver
*d
; // Current driver
51 cups_file_t
*fp
; // PPD file
52 char *opt
, // Current option
53 *value
, // Value in option
54 *outname
, // Output filename
58 // Lowercase pcfilename
59 filename
[1024]; // PPD filename
61 do_test
, // Test PPD files
62 single_language
,// Generate single-language files
63 use_model_name
, // Use ModelName for filename
65 ppdcLineEnding le
; // Line ending to use
66 ppdcArray
*locales
; // List of locales
67 cups_array_t
*filenames
; // List of generated filenames
72 // Scan the command-line...
80 src
= new ppdcSource();
83 filenames
= cupsArrayNew((cups_array_func_t
)strcasecmp
, NULL
);
85 for (i
= 1; i
< argc
; i
++)
86 if (argv
[i
][0] == '-')
88 for (opt
= argv
[i
] + 1; *opt
; opt
++)
91 case 'D' : // Define variable
96 if ((value
= strchr(argv
[i
], '=')) != NULL
)
100 src
->set_variable(argv
[i
], value
);
103 src
->set_variable(argv
[i
], "1");
106 case 'I' : // Include directory...
112 _cupsLangPrintf(stdout
,
113 _("ppdc: Adding include directory \"%s\".\n"),
116 ppdcSource::add_include(argv
[i
]);
119 case 'c' : // Message catalog...
125 _cupsLangPrintf(stdout
,
126 _("ppdc: Loading messages from \"%s\".\n"),
130 catalog
= new ppdcCatalog("en");
132 if (catalog
->load_messages(argv
[i
]))
134 _cupsLangPrintf(stderr
,
135 _("ppdc: Unable to load localization file "
136 "\"%s\" - %s\n"), argv
[i
], strerror(errno
));
141 case 'd' : // Output directory...
147 _cupsLangPrintf(stdout
,
148 _("ppdc: Writing PPD files to directory "
149 "\"%s\"...\n"), argv
[i
]);
154 case 'l' : // Language(s)...
159 if (strchr(argv
[i
], ','))
161 // Comma-delimited list of languages...
162 char temp
[1024], // Copy of language list
163 *start
, // Start of current locale name
164 *end
; // End of current locale name
167 locales
= new ppdcArray();
169 strlcpy(temp
, argv
[i
], sizeof(temp
));
170 for (start
= temp
; *start
; start
= end
)
172 if ((end
= strchr(start
, ',')) != NULL
)
175 end
= start
+ strlen(start
);
178 locales
->add(new ppdcString(start
));
186 _cupsLangPrintf(stdout
,
187 _("ppdc: Loading messages for locale "
188 "\"%s\"...\n"), argv
[i
]);
193 catalog
= new ppdcCatalog(argv
[i
]);
195 if (catalog
->messages
->count
== 0)
197 _cupsLangPrintf(stderr
,
198 _("ppdc: Unable to find localization for "
199 "\"%s\" - %s\n"), argv
[i
], strerror(errno
));
205 case 'm' : // Use ModelName for filename
209 case 't' : // Test PPDs instead of generating them
213 case 'v' : // Be verbose...
217 case 'z' : // Compress files...
221 case '-' : // --option
222 if (!strcmp(opt
, "-lf"))
225 opt
+= strlen(opt
) - 1;
228 else if (!strcmp(opt
, "-cr"))
231 opt
+= strlen(opt
) - 1;
234 else if (!strcmp(opt
, "-crlf"))
237 opt
+= strlen(opt
) - 1;
248 // Open and load the driver info file...
250 _cupsLangPrintf(stdout
,
251 _("ppdc: Loading driver information file \"%s\".\n"),
254 src
->read_file(argv
[i
]);
258 if (src
->drivers
->count
> 0)
260 // Create the output directory...
261 if (mkdir(outdir
, 0777))
265 _cupsLangPrintf(stderr
,
266 _("ppdc: Unable to create output directory %s: %s\n"),
267 outdir
, strerror(errno
));
272 // Write PPD files...
273 for (d
= (ppdcDriver
*)src
->drivers
->first();
275 d
= (ppdcDriver
*)src
->drivers
->next())
279 // Test the PPD file for this driver...
280 int pid
, // Process ID
281 fds
[2]; // Pipe file descriptors
286 _cupsLangPrintf(stderr
,
287 _("ppdc: Unable to create output pipes: %s\n"),
292 if ((pid
= fork()) == 0)
294 // Child process comes here...
300 execlp("cupstestppd", "cupstestppd", "-", (char *)0);
302 _cupsLangPrintf(stderr
,
303 _("ppdc: Unable to execute cupstestppd: %s\n"),
309 _cupsLangPrintf(stderr
,
310 _("ppdc: Unable to execute cupstestppd: %s\n"),
316 fp
= cupsFileOpenFd(fds
[1], "w");
320 // Write the PPD file for this driver...
323 if (!strncasecmp(d
->model_name
->value
, d
->manufacturer
->value
,
324 strlen(d
->manufacturer
->value
)))
326 // Model name already starts with the manufacturer...
327 outname
= d
->model_name
->value
;
331 // Add manufacturer to the front of the model name...
332 snprintf(make_model
, sizeof(make_model
), "%s %s",
333 d
->manufacturer
->value
, d
->model_name
->value
);
334 outname
= make_model
;
337 else if (d
->file_name
)
338 outname
= d
->file_name
->value
;
340 outname
= d
->pc_file_name
->value
;
342 if (strstr(outname
, ".PPD"))
344 // Convert PCFileName to lowercase...
346 outname
[j
] && j
< (int)(sizeof(pcfilename
) - 1);
348 pcfilename
[j
] = tolower(outname
[j
] & 255);
350 pcfilename
[j
] = '\0';
354 // Leave PCFileName as-is...
355 strlcpy(pcfilename
, outname
, sizeof(pcfilename
));
358 // Open the PPD file for writing...
360 snprintf(filename
, sizeof(filename
), "%s/%s.gz", outdir
, pcfilename
);
362 snprintf(filename
, sizeof(filename
), "%s/%s", outdir
, pcfilename
);
364 if (cupsArrayFind(filenames
, filename
))
365 _cupsLangPrintf(stderr
,
366 _("ppdc: Warning - overlapping filename \"%s\".\n"),
369 cupsArrayAdd(filenames
, strdup(filename
));
371 fp
= cupsFileOpen(filename
, comp
? "w9" : "w");
374 _cupsLangPrintf(stderr
,
375 _("ppdc: Unable to create PPD file \"%s\" - %s.\n"),
376 filename
, strerror(errno
));
381 _cupsLangPrintf(stdout
, _("ppdc: Writing %s.\n"), filename
);
385 * Write the PPD file...
388 ppdcArray
*templocales
= locales
;
390 if (!templocales
&& !single_language
)
392 templocales
= new ppdcArray();
393 for (ppdcCatalog
*tempcatalog
= (ppdcCatalog
*)src
->po_files
->first();
395 tempcatalog
= (ppdcCatalog
*)src
->po_files
->next())
397 tempcatalog
->locale
->retain();
398 templocales
->add(tempcatalog
->locale
);
402 if (d
->write_ppd_file(fp
, catalog
, templocales
, src
, le
))
408 if (templocales
!= locales
)
409 templocales
->release();
417 // Delete the printer driver information...
420 // Message catalog...
424 // Return with no errors.
430 // 'usage()' - Show usage and exit.
436 _cupsLangPuts(stdout
, _("Usage: ppdc [options] filename.drv [ ... "
437 "filenameN.drv ]\n"));
438 _cupsLangPuts(stdout
, _("Options:\n"));
439 _cupsLangPuts(stdout
, _(" -D name=value Set named variable to "
441 _cupsLangPuts(stdout
, _(" -I include-dir Add include directory to "
443 _cupsLangPuts(stdout
, _(" -c catalog.po Load the specified message "
445 _cupsLangPuts(stdout
, _(" -d output-dir Specify the output "
447 _cupsLangPuts(stdout
, _(" -l lang[,lang,...] Specify the output "
448 "language(s) (locale).\n"));
449 _cupsLangPuts(stdout
, _(" -m Use the ModelName value as "
451 _cupsLangPuts(stdout
, _(" -t Test PPDs instead of "
452 "generating them.\n"));
453 _cupsLangPuts(stdout
, _(" -v Be verbose (more v's for "
454 "more verbosity).\n"));
455 _cupsLangPuts(stdout
, _(" -z Compress PPD files using GNU "
457 _cupsLangPuts(stdout
, _(" --cr End lines with CR (Mac OS "
459 _cupsLangPuts(stdout
, _(" --crlf End lines with CR + LF "
461 _cupsLangPuts(stdout
, _(" --lf End lines with LF (UNIX/"
462 "Linux/Mac OS X).\n"));