xref: /aosp_15_r20/external/libcups/ppdc/ppdmerge.cxx (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker //
2*5e7646d2SAndroid Build Coastguard Worker // PPD file merge utility for the CUPS PPD Compiler.
3*5e7646d2SAndroid Build Coastguard Worker //
4*5e7646d2SAndroid Build Coastguard Worker // Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker // Copyright © 2002-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker //
7*5e7646d2SAndroid Build Coastguard Worker // Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker // information.
9*5e7646d2SAndroid Build Coastguard Worker //
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker //
12*5e7646d2SAndroid Build Coastguard Worker // Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker //
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd-private.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/array.h>
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker 
20*5e7646d2SAndroid Build Coastguard Worker //
21*5e7646d2SAndroid Build Coastguard Worker // Local functions...
22*5e7646d2SAndroid Build Coastguard Worker //
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker static const char	*ppd_locale(ppd_file_t *ppd);
25*5e7646d2SAndroid Build Coastguard Worker static void		usage(void) _CUPS_NORETURN;
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker //
29*5e7646d2SAndroid Build Coastguard Worker // 'main()' - Main entry for the PPD merge utility.
30*5e7646d2SAndroid Build Coastguard Worker //
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker int					// O - Exit status
main(int argc,char * argv[])33*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				// I - Number of command-line arguments
34*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			// I - Command-line arguments
35*5e7646d2SAndroid Build Coastguard Worker {
36*5e7646d2SAndroid Build Coastguard Worker   int		i;			// Looping var
37*5e7646d2SAndroid Build Coastguard Worker   char		*opt;			// Current option
38*5e7646d2SAndroid Build Coastguard Worker   ppd_file_t	*ppd;			// PPD file
39*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*ppds;			// Array of PPD files
40*5e7646d2SAndroid Build Coastguard Worker   const char	*inname,		// First input filename
41*5e7646d2SAndroid Build Coastguard Worker 		*outname;		// Output filename (if any)
42*5e7646d2SAndroid Build Coastguard Worker   char		bckname[1024];		// Backup filename
43*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*infile,		// Input file
44*5e7646d2SAndroid Build Coastguard Worker 		*outfile;		// Output file
45*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*languages;		// Languages in file
46*5e7646d2SAndroid Build Coastguard Worker   const char	*locale;		// Current locale
47*5e7646d2SAndroid Build Coastguard Worker   char		line[1024];		// Line from file
48*5e7646d2SAndroid Build Coastguard Worker 
49*5e7646d2SAndroid Build Coastguard Worker 
50*5e7646d2SAndroid Build Coastguard Worker   _cupsSetLocale(argv);
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker   // Scan the command-line...
53*5e7646d2SAndroid Build Coastguard Worker   inname    = NULL;
54*5e7646d2SAndroid Build Coastguard Worker   outname   = NULL;
55*5e7646d2SAndroid Build Coastguard Worker   outfile   = NULL;
56*5e7646d2SAndroid Build Coastguard Worker   languages = NULL;
57*5e7646d2SAndroid Build Coastguard Worker   ppds      = cupsArrayNew(NULL, NULL);
58*5e7646d2SAndroid Build Coastguard Worker 
59*5e7646d2SAndroid Build Coastguard Worker   for (i = 1; i < argc; i ++)
60*5e7646d2SAndroid Build Coastguard Worker     if (argv[i][0] == '-')
61*5e7646d2SAndroid Build Coastguard Worker     {
62*5e7646d2SAndroid Build Coastguard Worker       for (opt = argv[i] + 1; *opt; opt ++)
63*5e7646d2SAndroid Build Coastguard Worker         switch (*opt)
64*5e7646d2SAndroid Build Coastguard Worker 	{
65*5e7646d2SAndroid Build Coastguard Worker 	  case 'o' :			// Output file
66*5e7646d2SAndroid Build Coastguard Worker               if (outname)
67*5e7646d2SAndroid Build Coastguard Worker 	        usage();
68*5e7646d2SAndroid Build Coastguard Worker 
69*5e7646d2SAndroid Build Coastguard Worker 	      i ++;
70*5e7646d2SAndroid Build Coastguard Worker 	      if (i >= argc)
71*5e7646d2SAndroid Build Coastguard Worker         	usage();
72*5e7646d2SAndroid Build Coastguard Worker 
73*5e7646d2SAndroid Build Coastguard Worker 	      outname = argv[i];
74*5e7646d2SAndroid Build Coastguard Worker 	      break;
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker 	  default :			// Unknown
77*5e7646d2SAndroid Build Coastguard Worker 	      usage();
78*5e7646d2SAndroid Build Coastguard Worker 	      break;
79*5e7646d2SAndroid Build Coastguard Worker         }
80*5e7646d2SAndroid Build Coastguard Worker     }
81*5e7646d2SAndroid Build Coastguard Worker     else
82*5e7646d2SAndroid Build Coastguard Worker     {
83*5e7646d2SAndroid Build Coastguard Worker       // Open and load the PPD file...
84*5e7646d2SAndroid Build Coastguard Worker       if ((infile = cupsFileOpen(argv[i], "r")) == NULL)
85*5e7646d2SAndroid Build Coastguard Worker       {
86*5e7646d2SAndroid Build Coastguard Worker         _cupsLangPrintf(stderr, _("%s: Unable to open %s: %s"), "ppdmerge",
87*5e7646d2SAndroid Build Coastguard Worker 	                argv[i], strerror(errno));
88*5e7646d2SAndroid Build Coastguard Worker 	return (1);
89*5e7646d2SAndroid Build Coastguard Worker       }
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker       // Open the PPD file...
92*5e7646d2SAndroid Build Coastguard Worker       if ((ppd = ppdOpen2(infile)) == NULL)
93*5e7646d2SAndroid Build Coastguard Worker       {
94*5e7646d2SAndroid Build Coastguard Worker         ppd_status_t	status;		// PPD open status
95*5e7646d2SAndroid Build Coastguard Worker 	int		curline,	// Current line
96*5e7646d2SAndroid Build Coastguard Worker 			linenum;	// Line number
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker 
99*5e7646d2SAndroid Build Coastguard Worker         status = ppdLastError(&linenum);
100*5e7646d2SAndroid Build Coastguard Worker 
101*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stderr,
102*5e7646d2SAndroid Build Coastguard Worker 	                _("%s: Unable to open PPD file: %s on line %d."),
103*5e7646d2SAndroid Build Coastguard Worker 	                "ppdmerge", ppdErrorString(status), linenum);
104*5e7646d2SAndroid Build Coastguard Worker         cupsFileRewind(infile);
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker         line[0] = '\0';
107*5e7646d2SAndroid Build Coastguard Worker 	curline = 0;
108*5e7646d2SAndroid Build Coastguard Worker 
109*5e7646d2SAndroid Build Coastguard Worker         while (cupsFileGets(infile, line, sizeof(line)))
110*5e7646d2SAndroid Build Coastguard Worker 	{
111*5e7646d2SAndroid Build Coastguard Worker 	  curline ++;
112*5e7646d2SAndroid Build Coastguard Worker 	  if (curline >= linenum)
113*5e7646d2SAndroid Build Coastguard Worker 	    break;
114*5e7646d2SAndroid Build Coastguard Worker 	}
115*5e7646d2SAndroid Build Coastguard Worker 
116*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stderr, "%d: %s", linenum, line);
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker         cupsFileClose(infile);
119*5e7646d2SAndroid Build Coastguard Worker 	return (1);
120*5e7646d2SAndroid Build Coastguard Worker       }
121*5e7646d2SAndroid Build Coastguard Worker 
122*5e7646d2SAndroid Build Coastguard Worker       // Figure out the locale...
123*5e7646d2SAndroid Build Coastguard Worker       if ((locale = ppd_locale(ppd)) == NULL)
124*5e7646d2SAndroid Build Coastguard Worker       {
125*5e7646d2SAndroid Build Coastguard Worker         _cupsLangPrintf(stderr,
126*5e7646d2SAndroid Build Coastguard Worker 	                _("ppdmerge: Bad LanguageVersion \"%s\" in %s."),
127*5e7646d2SAndroid Build Coastguard Worker 			ppd->lang_version, argv[i]);
128*5e7646d2SAndroid Build Coastguard Worker         cupsFileClose(infile);
129*5e7646d2SAndroid Build Coastguard Worker 	ppdClose(ppd);
130*5e7646d2SAndroid Build Coastguard Worker 	return (1);
131*5e7646d2SAndroid Build Coastguard Worker       }
132*5e7646d2SAndroid Build Coastguard Worker 
133*5e7646d2SAndroid Build Coastguard Worker       if (!strcmp(locale, "en") && !inname && !outfile)
134*5e7646d2SAndroid Build Coastguard Worker       {
135*5e7646d2SAndroid Build Coastguard Worker         // Set the English PPD's filename...
136*5e7646d2SAndroid Build Coastguard Worker 	inname    = argv[i];
137*5e7646d2SAndroid Build Coastguard Worker 	languages = _ppdGetLanguages(ppd);
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker         if (outname && !strcmp(inname, outname))
140*5e7646d2SAndroid Build Coastguard Worker 	{
141*5e7646d2SAndroid Build Coastguard Worker 	  // Rename input filename so that we don't overwrite it...
142*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(bckname, sizeof(bckname), "%s.bck", inname);
143*5e7646d2SAndroid Build Coastguard Worker 
144*5e7646d2SAndroid Build Coastguard Worker 	  if (rename(inname, bckname))
145*5e7646d2SAndroid Build Coastguard Worker 	  {
146*5e7646d2SAndroid Build Coastguard Worker 	    _cupsLangPrintf(stderr,
147*5e7646d2SAndroid Build Coastguard Worker 	                    _("ppdmerge: Unable to backup %s to %s - %s"),
148*5e7646d2SAndroid Build Coastguard Worker 			    inname, bckname, strerror(errno));
149*5e7646d2SAndroid Build Coastguard Worker 	    return (1);
150*5e7646d2SAndroid Build Coastguard Worker 	  }
151*5e7646d2SAndroid Build Coastguard Worker 
152*5e7646d2SAndroid Build Coastguard Worker 	  inname = bckname;
153*5e7646d2SAndroid Build Coastguard Worker 	}
154*5e7646d2SAndroid Build Coastguard Worker       }
155*5e7646d2SAndroid Build Coastguard Worker       else if (strcmp(locale, "en"))
156*5e7646d2SAndroid Build Coastguard Worker       {
157*5e7646d2SAndroid Build Coastguard Worker 	// Save this PPD for later processing...
158*5e7646d2SAndroid Build Coastguard Worker         cupsArrayAdd(ppds, ppd);
159*5e7646d2SAndroid Build Coastguard Worker       }
160*5e7646d2SAndroid Build Coastguard Worker       else
161*5e7646d2SAndroid Build Coastguard Worker       {
162*5e7646d2SAndroid Build Coastguard Worker         // Don't need this PPD...
163*5e7646d2SAndroid Build Coastguard Worker 	_cupsLangPrintf(stderr, _("ppdmerge: Ignoring PPD file %s."),
164*5e7646d2SAndroid Build Coastguard Worker 	                argv[i]);
165*5e7646d2SAndroid Build Coastguard Worker         ppdClose(ppd);
166*5e7646d2SAndroid Build Coastguard Worker       }
167*5e7646d2SAndroid Build Coastguard Worker 
168*5e7646d2SAndroid Build Coastguard Worker       // Close and move on...
169*5e7646d2SAndroid Build Coastguard Worker       cupsFileClose(infile);
170*5e7646d2SAndroid Build Coastguard Worker     }
171*5e7646d2SAndroid Build Coastguard Worker 
172*5e7646d2SAndroid Build Coastguard Worker   // If no PPDs have been loaded, display the program usage message.
173*5e7646d2SAndroid Build Coastguard Worker   if (!inname)
174*5e7646d2SAndroid Build Coastguard Worker     usage();
175*5e7646d2SAndroid Build Coastguard Worker 
176*5e7646d2SAndroid Build Coastguard Worker   // Loop through the PPD files we loaded to generate a new language list...
177*5e7646d2SAndroid Build Coastguard Worker   if (!languages)
178*5e7646d2SAndroid Build Coastguard Worker     languages = cupsArrayNew((cups_array_func_t)strcmp, NULL);
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker   for (ppd = (ppd_file_t *)cupsArrayFirst(ppds);
181*5e7646d2SAndroid Build Coastguard Worker        ppd;
182*5e7646d2SAndroid Build Coastguard Worker        ppd = (ppd_file_t *)cupsArrayNext(ppds))
183*5e7646d2SAndroid Build Coastguard Worker   {
184*5e7646d2SAndroid Build Coastguard Worker     locale = ppd_locale(ppd);
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker     if (cupsArrayFind(languages, (void *)locale))
187*5e7646d2SAndroid Build Coastguard Worker     {
188*5e7646d2SAndroid Build Coastguard Worker       // Already have this language, remove the PPD from the list.
189*5e7646d2SAndroid Build Coastguard Worker       ppdClose(ppd);
190*5e7646d2SAndroid Build Coastguard Worker       cupsArrayRemove(ppds, ppd);
191*5e7646d2SAndroid Build Coastguard Worker     }
192*5e7646d2SAndroid Build Coastguard Worker     else
193*5e7646d2SAndroid Build Coastguard Worker       cupsArrayAdd(languages, (void *)locale);
194*5e7646d2SAndroid Build Coastguard Worker   }
195*5e7646d2SAndroid Build Coastguard Worker 
196*5e7646d2SAndroid Build Coastguard Worker   // Copy the English PPD starting with a cupsLanguages line...
197*5e7646d2SAndroid Build Coastguard Worker   infile = cupsFileOpen(inname, "r");
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker   if (outname)
200*5e7646d2SAndroid Build Coastguard Worker   {
201*5e7646d2SAndroid Build Coastguard Worker     const char *ext = strrchr(outname, '.');
202*5e7646d2SAndroid Build Coastguard Worker     if (ext && !strcmp(ext, ".gz"))
203*5e7646d2SAndroid Build Coastguard Worker       outfile = cupsFileOpen(outname, "w9");
204*5e7646d2SAndroid Build Coastguard Worker     else
205*5e7646d2SAndroid Build Coastguard Worker       outfile = cupsFileOpen(outname, "w");
206*5e7646d2SAndroid Build Coastguard Worker   }
207*5e7646d2SAndroid Build Coastguard Worker   else
208*5e7646d2SAndroid Build Coastguard Worker     outfile = cupsFileStdout();
209*5e7646d2SAndroid Build Coastguard Worker 
210*5e7646d2SAndroid Build Coastguard Worker   cupsFileGets(infile, line, sizeof(line));
211*5e7646d2SAndroid Build Coastguard Worker   cupsFilePrintf(outfile, "%s\n", line);
212*5e7646d2SAndroid Build Coastguard Worker   if ((locale = (char *)cupsArrayFirst(languages)) != NULL)
213*5e7646d2SAndroid Build Coastguard Worker   {
214*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(outfile, "*cupsLanguages: \"%s", locale);
215*5e7646d2SAndroid Build Coastguard Worker     while ((locale = (char *)cupsArrayNext(languages)) != NULL)
216*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(outfile, " %s", locale);
217*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(outfile, "\"\n");
218*5e7646d2SAndroid Build Coastguard Worker   }
219*5e7646d2SAndroid Build Coastguard Worker 
220*5e7646d2SAndroid Build Coastguard Worker   while (cupsFileGets(infile, line, sizeof(line)))
221*5e7646d2SAndroid Build Coastguard Worker   {
222*5e7646d2SAndroid Build Coastguard Worker     if (strncmp(line, "*cupsLanguages:", 15))
223*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(outfile, "%s\n", line);
224*5e7646d2SAndroid Build Coastguard Worker   }
225*5e7646d2SAndroid Build Coastguard Worker 
226*5e7646d2SAndroid Build Coastguard Worker   // Loop through the other PPD files we loaded to provide the translations...
227*5e7646d2SAndroid Build Coastguard Worker   for (ppd = (ppd_file_t *)cupsArrayFirst(ppds);
228*5e7646d2SAndroid Build Coastguard Worker        ppd;
229*5e7646d2SAndroid Build Coastguard Worker        ppd = (ppd_file_t *)cupsArrayNext(ppds))
230*5e7646d2SAndroid Build Coastguard Worker   {
231*5e7646d2SAndroid Build Coastguard Worker     // Output all of the UI text for this language...
232*5e7646d2SAndroid Build Coastguard Worker     int			j, k, l;	// Looping vars
233*5e7646d2SAndroid Build Coastguard Worker     ppd_group_t		*g;		// Option group
234*5e7646d2SAndroid Build Coastguard Worker     ppd_option_t	*o;		// Option
235*5e7646d2SAndroid Build Coastguard Worker     ppd_choice_t	*c;		// Choice
236*5e7646d2SAndroid Build Coastguard Worker     ppd_coption_t	*co;		// Custom option
237*5e7646d2SAndroid Build Coastguard Worker     ppd_cparam_t	*cp;		// Custom parameter
238*5e7646d2SAndroid Build Coastguard Worker     ppd_attr_t		*attr;		// PPD attribute
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker     locale = ppd_locale(ppd);
241*5e7646d2SAndroid Build Coastguard Worker 
242*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(outfile, "*%% %s localization\n", ppd->lang_version);
243*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(outfile, "*%s.Translation ModelName/%s: \"\"\n", locale,
244*5e7646d2SAndroid Build Coastguard Worker 		   ppd->modelname);
245*5e7646d2SAndroid Build Coastguard Worker 
246*5e7646d2SAndroid Build Coastguard Worker     for (j = ppd->num_groups, g = ppd->groups; j > 0; j --, g ++)
247*5e7646d2SAndroid Build Coastguard Worker     {
248*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale,
249*5e7646d2SAndroid Build Coastguard Worker 		     g->name, g->text);
250*5e7646d2SAndroid Build Coastguard Worker 
251*5e7646d2SAndroid Build Coastguard Worker       for (k = g->num_options, o = g->options; k > 0; k --, o ++)
252*5e7646d2SAndroid Build Coastguard Worker       {
253*5e7646d2SAndroid Build Coastguard Worker 	cupsFilePrintf(outfile, "*%s.Translation %s/%s: \"\"\n", locale,
254*5e7646d2SAndroid Build Coastguard Worker 		       o->keyword, o->text);
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker 	for (l = o->num_choices, c = o->choices; l > 0; l --, c ++)
257*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(outfile, "*%s.%s %s/%s: \"\"\n", locale,
258*5e7646d2SAndroid Build Coastguard Worker 			 o->keyword, c->choice, c->text);
259*5e7646d2SAndroid Build Coastguard Worker 
260*5e7646d2SAndroid Build Coastguard Worker 	if ((co = ppdFindCustomOption(ppd, o->keyword)) != NULL)
261*5e7646d2SAndroid Build Coastguard Worker 	{
262*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(line, sizeof(line), "Custom%s", o->keyword);
263*5e7646d2SAndroid Build Coastguard Worker 	  attr = ppdFindAttr(ppd, line, "True");
264*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(outfile, "*%s.Custom%s True/%s: \"\"\n", locale,
265*5e7646d2SAndroid Build Coastguard Worker 			 o->keyword, attr->text);
266*5e7646d2SAndroid Build Coastguard Worker 	  for (cp = ppdFirstCustomParam(co); cp; cp = ppdNextCustomParam(co))
267*5e7646d2SAndroid Build Coastguard Worker 	    cupsFilePrintf(outfile, "*%s.ParamCustom%s %s/%s: \"\"\n", locale,
268*5e7646d2SAndroid Build Coastguard Worker 			   o->keyword, cp->name, cp->text);
269*5e7646d2SAndroid Build Coastguard Worker 	}
270*5e7646d2SAndroid Build Coastguard Worker       }
271*5e7646d2SAndroid Build Coastguard Worker     }
272*5e7646d2SAndroid Build Coastguard Worker 
273*5e7646d2SAndroid Build Coastguard Worker     ppdClose(ppd);
274*5e7646d2SAndroid Build Coastguard Worker   }
275*5e7646d2SAndroid Build Coastguard Worker 
276*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(ppds);
277*5e7646d2SAndroid Build Coastguard Worker 
278*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(outfile);
279*5e7646d2SAndroid Build Coastguard Worker 
280*5e7646d2SAndroid Build Coastguard Worker   // Return with no errors.
281*5e7646d2SAndroid Build Coastguard Worker   return (0);
282*5e7646d2SAndroid Build Coastguard Worker }
283*5e7646d2SAndroid Build Coastguard Worker 
284*5e7646d2SAndroid Build Coastguard Worker 
285*5e7646d2SAndroid Build Coastguard Worker //
286*5e7646d2SAndroid Build Coastguard Worker // 'ppd_locale()' - Return the locale associated with a PPD file.
287*5e7646d2SAndroid Build Coastguard Worker //
288*5e7646d2SAndroid Build Coastguard Worker 
289*5e7646d2SAndroid Build Coastguard Worker static const char *			// O - Locale string
ppd_locale(ppd_file_t * ppd)290*5e7646d2SAndroid Build Coastguard Worker ppd_locale(ppd_file_t *ppd)		// I - PPD file
291*5e7646d2SAndroid Build Coastguard Worker {
292*5e7646d2SAndroid Build Coastguard Worker   int		i;			// Looping var
293*5e7646d2SAndroid Build Coastguard Worker   size_t	vlen;			// Length of LanguageVersion string
294*5e7646d2SAndroid Build Coastguard Worker   static char	locale[255];		// Locale string
295*5e7646d2SAndroid Build Coastguard Worker   static struct				// LanguageVersion translation table
296*5e7646d2SAndroid Build Coastguard Worker   {
297*5e7646d2SAndroid Build Coastguard Worker     const char	*version,		// LanguageVersion string */
298*5e7646d2SAndroid Build Coastguard Worker 		*language;		// Language code */
299*5e7646d2SAndroid Build Coastguard Worker   }		languages[] =
300*5e7646d2SAndroid Build Coastguard Worker   {
301*5e7646d2SAndroid Build Coastguard Worker     { "chinese",		"zh" },
302*5e7646d2SAndroid Build Coastguard Worker     { "czech",			"cs" },
303*5e7646d2SAndroid Build Coastguard Worker     { "danish",			"da" },
304*5e7646d2SAndroid Build Coastguard Worker     { "dutch",			"nl" },
305*5e7646d2SAndroid Build Coastguard Worker     { "english",		"en" },
306*5e7646d2SAndroid Build Coastguard Worker     { "finnish",		"fi" },
307*5e7646d2SAndroid Build Coastguard Worker     { "french",			"fr" },
308*5e7646d2SAndroid Build Coastguard Worker     { "german",			"de" },
309*5e7646d2SAndroid Build Coastguard Worker     { "greek",			"el" },
310*5e7646d2SAndroid Build Coastguard Worker     { "hungarian",		"hu" },
311*5e7646d2SAndroid Build Coastguard Worker     { "italian",		"it" },
312*5e7646d2SAndroid Build Coastguard Worker     { "japanese",		"ja" },
313*5e7646d2SAndroid Build Coastguard Worker     { "korean",			"ko" },
314*5e7646d2SAndroid Build Coastguard Worker     { "norwegian",		"no" },
315*5e7646d2SAndroid Build Coastguard Worker     { "polish",			"pl" },
316*5e7646d2SAndroid Build Coastguard Worker     { "portuguese",		"pt" },
317*5e7646d2SAndroid Build Coastguard Worker     { "russian",		"ru" },
318*5e7646d2SAndroid Build Coastguard Worker     { "simplified chinese",	"zh_CN" },
319*5e7646d2SAndroid Build Coastguard Worker     { "slovak",			"sk" },
320*5e7646d2SAndroid Build Coastguard Worker     { "spanish",		"es" },
321*5e7646d2SAndroid Build Coastguard Worker     { "swedish",		"sv" },
322*5e7646d2SAndroid Build Coastguard Worker     { "traditional chinese",	"zh_TW" },
323*5e7646d2SAndroid Build Coastguard Worker     { "turkish",		"tr" }
324*5e7646d2SAndroid Build Coastguard Worker   };
325*5e7646d2SAndroid Build Coastguard Worker 
326*5e7646d2SAndroid Build Coastguard Worker 
327*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < (int)(sizeof(languages) / sizeof(languages[0])); i ++)
328*5e7646d2SAndroid Build Coastguard Worker   {
329*5e7646d2SAndroid Build Coastguard Worker     vlen = strlen(languages[i].version);
330*5e7646d2SAndroid Build Coastguard Worker 
331*5e7646d2SAndroid Build Coastguard Worker     if (!_cups_strncasecmp(ppd->lang_version, languages[i].version, vlen))
332*5e7646d2SAndroid Build Coastguard Worker     {
333*5e7646d2SAndroid Build Coastguard Worker       if (ppd->lang_version[vlen] == '-' ||
334*5e7646d2SAndroid Build Coastguard Worker           ppd->lang_version[vlen] == '_')
335*5e7646d2SAndroid Build Coastguard Worker         snprintf(locale, sizeof(locale), "%s_%s", languages[i].language,
336*5e7646d2SAndroid Build Coastguard Worker 	         ppd->lang_version + vlen + 1);
337*5e7646d2SAndroid Build Coastguard Worker       else
338*5e7646d2SAndroid Build Coastguard Worker         strlcpy(locale, languages[i].language, sizeof(locale));
339*5e7646d2SAndroid Build Coastguard Worker 
340*5e7646d2SAndroid Build Coastguard Worker       return (locale);
341*5e7646d2SAndroid Build Coastguard Worker     }
342*5e7646d2SAndroid Build Coastguard Worker   }
343*5e7646d2SAndroid Build Coastguard Worker 
344*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
345*5e7646d2SAndroid Build Coastguard Worker }
346*5e7646d2SAndroid Build Coastguard Worker 
347*5e7646d2SAndroid Build Coastguard Worker //
348*5e7646d2SAndroid Build Coastguard Worker // 'usage()' - Show usage and exit.
349*5e7646d2SAndroid Build Coastguard Worker //
350*5e7646d2SAndroid Build Coastguard Worker 
351*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)352*5e7646d2SAndroid Build Coastguard Worker usage(void)
353*5e7646d2SAndroid Build Coastguard Worker {
354*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Usage: ppdmerge [options] filename.ppd [ ... "
355*5e7646d2SAndroid Build Coastguard Worker                           "filenameN.ppd ]"));
356*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("Options:"));
357*5e7646d2SAndroid Build Coastguard Worker   _cupsLangPuts(stdout, _("  -o filename.ppd[.gz]    Set output file "
358*5e7646d2SAndroid Build Coastguard Worker                           "(otherwise stdout)."));
359*5e7646d2SAndroid Build Coastguard Worker 
360*5e7646d2SAndroid Build Coastguard Worker   exit(1);
361*5e7646d2SAndroid Build Coastguard Worker }
362