• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // PPD file message catalog program for the CUPS PPD Compiler.
3 //
4 // Copyright 2007-2015 by Apple Inc.
5 // Copyright 2002-2005 by Easy Software Products.
6 //
7 // Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8 //
9 
10 //
11 // Include necessary headers...
12 //
13 
14 #include "ppdc-private.h"
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 
18 
19 //
20 // Local functions...
21 //
22 
23 static void	add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog);
24 static void	usage(void);
25 
26 
27 //
28 // 'main()' - Main entry for the PPD compiler.
29 //
30 
31 int					// O - Exit status
main(int argc,char * argv[])32 main(int  argc,				// I - Number of command-line arguments
33      char *argv[])			// I - Command-line arguments
34 {
35   int		i;			// Looping var
36   ppdcCatalog	*catalog;		// Message catalog
37   ppdcSource	*src;			// PPD source file data
38   ppdcDriver	*d;			// Current driver
39   char		*opt;			// Current option
40   int		verbose;		// Verbosity
41   const char	*outfile;		// Output file
42   char		*value;			// Value in option
43 
44 
45   _cupsSetLocale(argv);
46 
47   // Scan the command-line...
48   catalog = new ppdcCatalog("en");
49   src     = new ppdcSource();
50   verbose = 0;
51   outfile = 0;
52 
53   for (i = 1; i < argc; i ++)
54     if (argv[i][0] == '-')
55     {
56       for (opt = argv[i] + 1; *opt; opt ++)
57         switch (*opt)
58 	{
59           case 'D' :			// Define variable
60 	      i ++;
61 	      if (i >= argc)
62 	        usage();
63 
64               if ((value = strchr(argv[i], '=')) != NULL)
65 	      {
66 	        *value++ = '\0';
67 
68 	        src->set_variable(argv[i], value);
69 	      }
70 	      else
71 	        src->set_variable(argv[i], "1");
72               break;
73 
74           case 'I' :			// Include directory...
75 	      i ++;
76 	      if (i >= argc)
77         	usage();
78 
79               if (verbose > 1)
80 	        _cupsLangPrintf(stdout,
81 		                _("ppdc: Adding include directory \"%s\"."),
82 				argv[i]);
83 
84 	      ppdcSource::add_include(argv[i]);
85 	      break;
86 
87           case 'o' :			// Output file...
88 	      i ++;
89 	      if (i >= argc || outfile)
90         	usage();
91 
92               outfile = argv[i];
93 
94 	      catalog->load_messages(outfile);
95 	      break;
96 
97           case 'v' :			// Be verbose...
98 	      verbose ++;
99 	      break;
100 
101 	  default :			// Unknown
102 	      usage();
103 	      break;
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