• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // PPD file message catalog program for the CUPS PPD Compiler.
3 //
4 // Copyright © 2020-2024 by OpenPrinting.
5 // Copyright 2007-2015 by Apple Inc.
6 // Copyright 2002-2005 by Easy Software Products.
7 //
8 // Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
9 //
10 
11 //
12 // Include necessary headers...
13 //
14 
15 #include "ppdc-private.h"
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 
19 
20 //
21 // Local functions...
22 //
23 
24 static void	add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog);
25 static void	usage(void) _CUPS_NORETURN;
26 
27 
28 //
29 // 'main()' - Main entry for the PPD compiler.
30 //
31 
32 int					// O - Exit status
main(int argc,char * argv[])33 main(int  argc,				// I - Number of command-line arguments
34      char *argv[])			// I - Command-line arguments
35 {
36   int		i;			// Looping var
37   ppdcCatalog	*catalog;		// Message catalog
38   ppdcSource	*src;			// PPD source file data
39   ppdcDriver	*d;			// Current driver
40   char		*opt;			// Current option
41   int		verbose;		// Verbosity
42   const char	*outfile;		// Output file
43   char		*value;			// Value in option
44 
45 
46   _cupsSetLocale(argv);
47 
48   // Scan the command-line...
49   catalog = new ppdcCatalog("en");
50   src     = new ppdcSource();
51   verbose = 0;
52   outfile = 0;
53 
54   for (i = 1; i < argc; i ++)
55     if (argv[i][0] == '-')
56     {
57       for (opt = argv[i] + 1; *opt; opt ++)
58         switch (*opt)
59 	{
60           case 'D' :			// Define variable
61 	      i ++;
62 	      if (i >= argc)
63 	        usage();
64 
65               if ((value = strchr(argv[i], '=')) != NULL)
66 	      {
67 	        *value++ = '\0';
68 
69 	        src->set_variable(argv[i], value);
70 	      }
71 	      else
72 	        src->set_variable(argv[i], "1");
73               break;
74 
75           case 'I' :			// Include directory...
76 	      i ++;
77 	      if (i >= argc)
78         	usage();
79 
80               if (verbose > 1)
81 	        _cupsLangPrintf(stdout,
82 		                _("ppdc: Adding include directory \"%s\"."),
83 				argv[i]);
84 
85 	      ppdcSource::add_include(argv[i]);
86 	      break;
87 
88           case 'o' :			// Output file...
89 	      i ++;
90 	      if (i >= argc || outfile)
91         	usage();
92 
93               outfile = argv[i];
94 
95 	      catalog->load_messages(outfile);
96 	      break;
97 
98           case 'v' :			// Be verbose...
99 	      verbose ++;
100 	      break;
101 
102 	  default :			// Unknown
103 	      usage();
104 	}
105     }
106     else
107     {
108       // Open and load the driver info file...
109       if (verbose > 1)
110         _cupsLangPrintf(stdout,
111 	                _("ppdc: Loading driver information file \"%s\"."),
112 			argv[i]);
113 
114       src->read_file(argv[i]);
115     }
116 
117   // If no drivers have been loaded, display the program usage message.
118   if ((d = (ppdcDriver *)src->drivers->first()) != NULL)
119   {
120     // Add UI strings...
121     while (d != NULL)
122     {
123       if (verbose)
124 	_cupsLangPrintf(stderr, _("ppdc: Adding/updating UI text from %s."), argv[i]);
125 
126       add_ui_strings(d, catalog);
127 
128       d = (ppdcDriver *)src->drivers->next();
129     }
130   }
131   else
132     usage();
133 
134   // Delete the printer driver information...
135   src->release();
136 
137   // Write the message catalog...
138   if (!outfile)
139     usage();
140   else
141     catalog->save_messages(outfile);
142 
143   catalog->release();
144 
145   // Return with no errors.
146   return (0);
147 }
148 
149 
150 //
151 // 'add_ui_strings()' - Add all UI strings from the driver.
152 //
153 
154 static void
add_ui_strings(ppdcDriver * d,ppdcCatalog * catalog)155 add_ui_strings(ppdcDriver  *d,		// I - Driver data
156                ppdcCatalog *catalog)	// I - Message catalog
157 {
158   // Add the make/model/language strings...
159   catalog->add_message(d->manufacturer->value);
160   catalog->add_message(d->model_name->value);
161 
162   // Add the media size strings...
163   ppdcMediaSize	*m;			// Current media size
164 
165   for (m = (ppdcMediaSize *)d->sizes->first();
166        m;
167        m = (ppdcMediaSize *)d->sizes->next())
168     catalog->add_message(m->text->value);
169 
170   // Add the group/option/choice strings...
171   ppdcGroup	*g;			// Current group
172   ppdcOption	*o;			// Current option
173   ppdcChoice	*c;			// Current choice
174 
175   for (g = (ppdcGroup *)d->groups->first();
176        g;
177        g = (ppdcGroup *)d->groups->next())
178   {
179     if (!g->options->count)
180       continue;
181 
182     if (_cups_strcasecmp(g->name->value, "General"))
183       catalog->add_message(g->text->value);
184 
185     for (o = (ppdcOption *)g->options->first();
186          o;
187 	 o = (ppdcOption *)g->options->next())
188     {
189       if (!o->choices->count)
190         continue;
191 
192       if (o->text->value)
193         catalog->add_message(o->text->value);
194       else
195         catalog->add_message(o->name->value);
196 
197       for (c = (ppdcChoice *)o->choices->first();
198            c;
199 	   c = (ppdcChoice *)o->choices->next())
200 	if (c->text->value)
201           catalog->add_message(c->text->value);
202         else
203           catalog->add_message(c->name->value);
204     }
205   }
206 
207   // Add profile and preset strings...
208   ppdcAttr *a;				// Current attribute
209   for (a = (ppdcAttr *)d->attrs->first();
210        a;
211        a = (ppdcAttr *)d->attrs->next())
212     if (a->text->value && a->text->value[0] &&
213         (a->localizable ||
214 	 !strncmp(a->name->value, "Custom", 6) ||
215          !strncmp(a->name->value, "ParamCustom", 11) ||
216          !strcmp(a->name->value, "APCustomColorMatchingName") ||
217          !strcmp(a->name->value, "APPrinterPreset") ||
218          !strcmp(a->name->value, "cupsICCProfile") ||
219          !strcmp(a->name->value, "cupsIPPReason") ||
220          !strcmp(a->name->value, "cupsMarkerName")))
221     {
222       catalog->add_message(a->text->value);
223 
224       if ((a->localizable && a->value->value[0]) ||
225           !strcmp(a->name->value, "cupsIPPReason"))
226         catalog->add_message(a->value->value);
227     }
228     else if (!strncmp(a->name->value, "Custom", 6) ||
229              !strncmp(a->name->value, "ParamCustom", 11))
230       catalog->add_message(a->name->value);
231 }
232 
233 
234 //
235 // 'usage()' - Show usage and exit.
236 //
237 
238 static void
usage(void)239 usage(void)
240 {
241   _cupsLangPuts(stdout, _("Usage: ppdpo [options] -o filename.po filename.drv "
242                           "[ ... filenameN.drv ]"));
243   _cupsLangPuts(stdout, _("Options:"));
244   _cupsLangPuts(stdout, _("  -D name=value           Set named variable to "
245                           "value."));
246   _cupsLangPuts(stdout, _("  -I include-dir          Add include directory to "
247                           "search path."));
248   _cupsLangPuts(stdout, _("  -v                      Be verbose."));
249 
250   exit(1);
251 }
252