]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdmerge.cxx
4 // PPD file merge utility for the CUPS PPD Compiler.
6 // Copyright 2007 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 merge utility.
18 // ppd_locale() - Return the locale associated with a PPD file.
19 // usage() - Show usage and exit.
23 // Include necessary headers...
26 #include <cups/cups.h>
27 #include <cups/array.h>
28 #include <cups/string.h>
36 static const char *ppd_locale(ppd_file_t
*ppd
);
37 static void usage(void);
41 // 'main()' - Main entry for the PPD merge utility.
44 int // O - Exit status
45 main(int argc
, // I - Number of command-line arguments
46 char *argv
[]) // I - Command-line arguments
49 char *opt
; // Current option
50 ppd_file_t
*ppd
; // PPD file
51 cups_array_t
*ppds
; // Array of PPD files
52 const char *inname
, // First input filename
53 *outname
; // Output filename (if any)
54 cups_file_t
*infile
, // Input file
55 *outfile
; // Output file
56 char languages
[1024]; // Languages in file
59 // Scan the command-line...
64 ppds
= cupsArrayNew(NULL
, NULL
);
66 for (i
= 1; i
< argc
; i
++)
67 if (argv
[i
][0] == '-')
69 for (opt
= argv
[i
] + 1; *opt
; opt
++)
72 case 'o' : // Output file
90 // Open and load the driver info file...
91 if ((infile
= cupsFileOpen(argv
[i
], "r")) == NULL
)
93 fprintf(stderr
, "ppdmerge: Unable to open %s - %s\n", argv
[i
],
98 // Open the PPD file...
99 if ((ppd
= ppdOpen2(infile
)) == NULL
)
101 ppd_status_t status
; // PPD open status
102 int linenum
; // Line number
103 char line
[1024]; // First line from file
106 status
= ppdLastError(&linenum
);
108 fprintf(stderr
, "ppdmerge: Unable to open %s - %s on line %d.\n",
109 argv
[i
], ppdErrorString(status
), linenum
);
111 fprintf(stderr
, "%d: ", linenum
);
112 cupsFileRewind(infile
);
116 while (cupsFileGets(infile
, line
, sizeof(line
)))
123 fprintf(stderr
, "%s\n", line
);
125 cupsFileClose(infile
);
130 // Figure out the locale...
131 const char *locale
= ppd_locale(ppd
);
135 fprintf(stderr
, "ppdmerge: Bad LanguageVersion \"%s\" in %s!\n",
136 ppd
->lang_version
, argv
[i
]);
137 cupsFileClose(infile
);
143 if (!strcmp(locale
, "en") && !inname
&& !outfile
)
145 // Set the English PPD's filename...
148 if (outname
&& !strcmp(inname
, outname
))
150 // Rename input filename so that we don't overwrite it...
151 char bckname
[1024]; // Backup filename
154 snprintf(bckname
, sizeof(bckname
), "%s.bck", inname
);
156 if (rename(inname
, bckname
))
158 fprintf(stderr
, "ppdmerge: Unable to backup %s to %s- %s\n",
159 inname
, bckname
, strerror(errno
));
164 // Open the output stream...
167 const char *ext
= strrchr(outname
, '.');
168 if (ext
&& !strcmp(ext
, ".ppd.gz"))
169 outfile
= cupsFileOpen(outname
, "w9");
171 outfile
= cupsFileOpen(outname
, "w");
174 outfile
= cupsFileStdout();
176 // Copy the PPD file to the output stream...
177 char line
[1024]; // Line from file
179 cupsFileRewind(infile
);
181 while (cupsFileGets(infile
, line
, sizeof(line
)))
183 if (!strncmp(line
, "*cupsLanguages:", 15))
185 if (sscanf(line
, "*cupsLanguages:%*[ \t]\"%1023[^\"]",
190 cupsFilePrintf(outfile
, "%s\n", line
);
193 else if (strcmp(locale
, "en") && !strstr(languages
, locale
))
195 // Save this PPD for later processing...
196 cupsArrayAdd(ppds
, ppd
);
200 // Don't need this PPD...
201 fprintf(stderr
, "ppdmerge: Ignoring PPD file %s...\n", argv
[i
]);
205 // Close and move on...
206 cupsFileClose(infile
);
209 // If no PPDs have been loaded, display the program usage message.
213 // Loop through the PPD files we loaded to provide the translations...
214 for (ppd
= (ppd_file_t
*)cupsArrayFirst(ppds
);
216 ppd
= (ppd_file_t
*)cupsArrayNext(ppds
))
218 // Output all of the UI text for this language...
219 int j
, k
, l
; // Looping vars
220 ppd_group_t
*g
; // Option group
221 ppd_option_t
*o
; // Option
222 ppd_choice_t
*c
; // Choice
223 const char *locale
= ppd_locale(ppd
);
227 cupsFilePrintf(outfile
, "*%% %s localization\n", ppd
->lang_version
);
229 cupsFilePrintf(outfile
, "*%s.Translation ModelName/%s: \"\"\n", locale
,
232 for (j
= ppd
->num_groups
, g
= ppd
->groups
; j
> 0; j
--, g
++)
234 cupsFilePrintf(outfile
, "*%s.Translation %s/%s: \"\"\n", locale
,
237 for (k
= g
->num_options
, o
= g
->options
; k
> 0; k
--, o
++)
239 cupsFilePrintf(outfile
, "*%s.Translation %s/%s: \"\"\n", locale
,
240 o
->keyword
, o
->text
);
242 for (l
= o
->num_choices
, c
= o
->choices
; l
> 0; l
--, c
++)
243 cupsFilePrintf(outfile
, "*%s.%s %s/%s: \"\"\n", locale
,
244 o
->keyword
, c
->choice
, c
->text
);
249 strlcat(languages
, " ", sizeof(languages
));
251 strlcat(languages
, locale
, sizeof(languages
));
256 cupsArrayDelete(ppds
);
259 cupsFilePrintf(outfile
, "*cupsLanguages: \"%s\"\n", languages
);
261 cupsFileClose(outfile
);
263 // Return with no errors.
269 for (ppd
= (ppd_file_t
*)cupsArrayFirst(ppds
);
271 ppd
= (ppd_file_t
*)cupsArrayNext(ppds
))
274 cupsArrayDelete(ppds
);
277 cupsFileClose(outfile
);
284 // 'ppd_locale()' - Return the locale associated with a PPD file.
287 static const char * // O - Locale string
288 ppd_locale(ppd_file_t
*ppd
) // I - PPD file
290 int i
, // Looping var
291 vlen
; // Length of LanguageVersion string
292 static char locale
[255]; // Locale string
293 static struct // LanguageVersion translation table
295 const char *version
, // LanguageVersion string */
296 *language
; // Language code */
308 { "hungarian", "hu" },
310 { "japanese", "ja" },
312 { "norwegian", "no" },
314 { "portuguese", "pt" },
316 { "simplified chinese", "zh_CN" },
320 { "traditional chinese", "zh_TW" },
325 for (i
= 0; i
< (int)(sizeof(languages
) / sizeof(languages
[0])); i
++)
327 vlen
= strlen(languages
[i
].version
);
329 if (!strncasecmp(ppd
->lang_version
, languages
[i
].version
, vlen
))
331 if (ppd
->lang_version
[vlen
] == '-' ||
332 ppd
->lang_version
[vlen
] == '_')
333 snprintf(locale
, sizeof(locale
), "%s_%s", languages
[i
].language
,
334 ppd
->lang_version
+ vlen
+ 1);
336 strlcpy(locale
, languages
[i
].language
, sizeof(locale
));
346 // 'usage()' - Show usage and exit.
352 puts("Usage: ppdmerge [options] filename.ppd [ ... filenameN.ppd ]");
354 puts(" -o filename.ppd[.gz]");