]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/ppdmerge.cxx
00bb181b6ad6eda7387172859bf6a5762beb1439
4 // PPD file merge utility for the CUPS PPD Compiler.
6 // Copyright 2007-2008 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/ppd-private.h>
27 #include <cups/cups.h>
28 #include <cups/array.h>
29 #include <cups/string.h>
30 #include <cups/i18n.h>
38 static const char *ppd_locale(ppd_file_t
*ppd
);
39 static void usage(void);
43 // 'main()' - Main entry for the PPD merge utility.
46 int // O - Exit status
47 main(int argc
, // I - Number of command-line arguments
48 char *argv
[]) // I - Command-line arguments
51 char *opt
; // Current option
52 ppd_file_t
*ppd
; // PPD file
53 cups_array_t
*ppds
; // Array of PPD files
54 const char *inname
, // First input filename
55 *outname
; // Output filename (if any)
56 cups_file_t
*infile
, // Input file
57 *outfile
; // Output file
58 cups_array_t
*languages
; // Languages in file
59 const char *locale
; // Current locale
60 char line
[1024]; // Line from file
65 // Scan the command-line...
70 ppds
= cupsArrayNew(NULL
, NULL
);
72 for (i
= 1; i
< argc
; i
++)
73 if (argv
[i
][0] == '-')
75 for (opt
= argv
[i
] + 1; *opt
; opt
++)
78 case 'o' : // Output file
96 // Open and load the PPD file...
97 if ((infile
= cupsFileOpen(argv
[i
], "r")) == NULL
)
99 _cupsLangPrintf(stderr
, _("%s: Unable to open %s - %s\n"), "ppdmerge",
100 argv
[i
], strerror(errno
));
104 // Open the PPD file...
105 if ((ppd
= ppdOpen2(infile
)) == NULL
)
107 ppd_status_t status
; // PPD open status
108 int linenum
; // Line number
111 status
= ppdLastError(&linenum
);
113 _cupsLangPrintf(stderr
, _("%s: Unable to open %s - %s on line %d.\n"),
114 "ppdmerge", argv
[i
], ppdErrorString(status
), linenum
);
116 _cupsLangPrintf(stderr
, "%d: ", linenum
);
117 cupsFileRewind(infile
);
121 while (cupsFileGets(infile
, line
, sizeof(line
)))
128 _cupsLangPrintf(stderr
, "%s\n", line
);
130 cupsFileClose(infile
);
134 // Figure out the locale...
135 if ((locale
= ppd_locale(ppd
)) == NULL
)
137 _cupsLangPrintf(stderr
,
138 _("ppdmerge: Bad LanguageVersion \"%s\" in %s!\n"),
139 ppd
->lang_version
, argv
[i
]);
140 cupsFileClose(infile
);
145 if (!strcmp(locale
, "en") && !inname
&& !outfile
)
147 // Set the English PPD's filename...
149 languages
= _ppdGetLanguages(ppd
);
151 if (outname
&& !strcmp(inname
, outname
))
153 // Rename input filename so that we don't overwrite it...
154 char bckname
[1024]; // Backup filename
157 snprintf(bckname
, sizeof(bckname
), "%s.bck", inname
);
159 if (rename(inname
, bckname
))
161 _cupsLangPrintf(stderr
,
162 _("ppdmerge: Unable to backup %s to %s- %s\n"),
163 inname
, bckname
, strerror(errno
));
170 else if (strcmp(locale
, "en"))
172 // Save this PPD for later processing...
173 cupsArrayAdd(ppds
, ppd
);
177 // Don't need this PPD...
178 _cupsLangPrintf(stderr
, _("ppdmerge: Ignoring PPD file %s...\n"),
183 // Close and move on...
184 cupsFileClose(infile
);
187 // If no PPDs have been loaded, display the program usage message.
191 // Loop through the PPD files we loaded to generate a new language list...
193 languages
= cupsArrayNew((cups_array_func_t
)strcmp
, NULL
);
195 for (ppd
= (ppd_file_t
*)cupsArrayFirst(ppds
);
197 ppd
= (ppd_file_t
*)cupsArrayNext(ppds
))
199 locale
= ppd_locale(ppd
);
201 if (cupsArrayFind(languages
, (void *)locale
))
203 // Already have this language, remove the PPD from the list.
205 cupsArrayRemove(ppds
, ppd
);
208 cupsArrayAdd(languages
, (void *)locale
);
211 // Copy the English PPD starting with a cupsLanguages line...
212 infile
= cupsFileOpen(inname
, "r");
216 const char *ext
= strrchr(outname
, '.');
217 if (ext
&& !strcmp(ext
, ".gz"))
218 outfile
= cupsFileOpen(outname
, "w9");
220 outfile
= cupsFileOpen(outname
, "w");
223 outfile
= cupsFileStdout();
225 cupsFileGets(infile
, line
, sizeof(line
));
226 cupsFilePrintf(outfile
, "%s\n", line
);
227 if ((locale
= (char *)cupsArrayFirst(languages
)) != NULL
)
229 cupsFilePrintf(outfile
, "*cupsLanguages: \"%s", locale
);
230 while ((locale
= (char *)cupsArrayNext(languages
)) != NULL
)
231 cupsFilePrintf(outfile
, " %s", locale
);
232 cupsFilePuts(outfile
, "\"\n");
235 while (cupsFileGets(infile
, line
, sizeof(line
)))
237 if (strncmp(line
, "*cupsLanguages:", 15))
238 cupsFilePrintf(outfile
, "%s\n", line
);
241 // Loop through the other PPD files we loaded to provide the translations...
242 for (ppd
= (ppd_file_t
*)cupsArrayFirst(ppds
);
244 ppd
= (ppd_file_t
*)cupsArrayNext(ppds
))
246 // Output all of the UI text for this language...
247 int j
, k
, l
; // Looping vars
248 ppd_group_t
*g
; // Option group
249 ppd_option_t
*o
; // Option
250 ppd_choice_t
*c
; // Choice
251 ppd_coption_t
*co
; // Custom option
252 ppd_cparam_t
*cp
; // Custom parameter
253 ppd_attr_t
*attr
; // PPD attribute
255 locale
= ppd_locale(ppd
);
257 cupsFilePrintf(outfile
, "*%% %s localization\n", ppd
->lang_version
);
258 cupsFilePrintf(outfile
, "*%s.Translation ModelName/%s: \"\"\n", locale
,
261 for (j
= ppd
->num_groups
, g
= ppd
->groups
; j
> 0; j
--, g
++)
263 cupsFilePrintf(outfile
, "*%s.Translation %s/%s: \"\"\n", locale
,
266 for (k
= g
->num_options
, o
= g
->options
; k
> 0; k
--, o
++)
268 cupsFilePrintf(outfile
, "*%s.Translation %s/%s: \"\"\n", locale
,
269 o
->keyword
, o
->text
);
271 for (l
= o
->num_choices
, c
= o
->choices
; l
> 0; l
--, c
++)
272 cupsFilePrintf(outfile
, "*%s.%s %s/%s: \"\"\n", locale
,
273 o
->keyword
, c
->choice
, c
->text
);
275 if ((co
= ppdFindCustomOption(ppd
, o
->keyword
)) != NULL
)
277 snprintf(line
, sizeof(line
), "Custom%s", o
->keyword
);
278 attr
= ppdFindAttr(ppd
, line
, "True");
279 cupsFilePrintf(outfile
, "*%s.Custom%s True/%s: \"\"\n", locale
,
280 o
->keyword
, attr
->text
);
281 for (cp
= ppdFirstCustomParam(co
); cp
; cp
= ppdNextCustomParam(co
))
282 cupsFilePrintf(outfile
, "*%s.ParamCustom%s %s/%s: \"\"\n", locale
,
283 o
->keyword
, cp
->name
, cp
->text
);
291 cupsArrayDelete(ppds
);
293 cupsFileClose(outfile
);
295 // Return with no errors.
301 // 'ppd_locale()' - Return the locale associated with a PPD file.
304 static const char * // O - Locale string
305 ppd_locale(ppd_file_t
*ppd
) // I - PPD file
307 int i
, // Looping var
308 vlen
; // Length of LanguageVersion string
309 static char locale
[255]; // Locale string
310 static struct // LanguageVersion translation table
312 const char *version
, // LanguageVersion string */
313 *language
; // Language code */
325 { "hungarian", "hu" },
327 { "japanese", "ja" },
329 { "norwegian", "no" },
331 { "portuguese", "pt" },
333 { "simplified chinese", "zh_CN" },
337 { "traditional chinese", "zh_TW" },
342 for (i
= 0; i
< (int)(sizeof(languages
) / sizeof(languages
[0])); i
++)
344 vlen
= strlen(languages
[i
].version
);
346 if (!strncasecmp(ppd
->lang_version
, languages
[i
].version
, vlen
))
348 if (ppd
->lang_version
[vlen
] == '-' ||
349 ppd
->lang_version
[vlen
] == '_')
350 snprintf(locale
, sizeof(locale
), "%s_%s", languages
[i
].language
,
351 ppd
->lang_version
+ vlen
+ 1);
353 strlcpy(locale
, languages
[i
].language
, sizeof(locale
));
363 // 'usage()' - Show usage and exit.
369 _cupsLangPuts(stdout
,
370 _("Usage: ppdmerge [options] filename.ppd "
371 "[ ... filenameN.ppd ]\n"
373 " -o filename.ppd[.gz]\n"));