1 //
2 // GNU gettext message generator for the CUPS PPD Compiler.
3 //
4 // This program is used to generate a dummy source file containing all of
5 // the standard media and sample driver strings.  The results are picked up
6 // by GNU gettext and placed in the CUPS message catalog.
7 //
8 // Copyright 2008-2014 by Apple Inc.
9 //
10 // Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
11 //
12 // Usage:
13 //
14 //   ./genstrings >sample.c
15 //
16 
17 //
18 // Include necessary headers...
19 //
20 
21 #include "ppdc-private.h"
22 #include <unistd.h>
23 
24 
25 //
26 // Local functions...
27 //
28 
29 static void	add_ui_strings(ppdcDriver *d, ppdcCatalog *catalog);
30 static void	write_cstring(const char *s);
31 
32 
33 //
34 // 'main()' - Main entry for the PPD compiler.
35 //
36 
37 int					// O - Exit status
main(void)38 main(void)
39 {
40   ppdcSource	*src;			// PPD source file data
41   ppdcCatalog	*catalog;		// Catalog to hold all of the UI strings
42 
43 
44   // Make sure we are in the right place...
45   if (access("../data", 0) || access("sample.drv", 0))
46   {
47     puts("You must run genstrings from the ppdc directory.");
48     return (1);
49   }
50 
51   // Load the sample drivers...
52   ppdcSource::add_include("../data");
53 
54   src     = new ppdcSource("sample.drv");
55   catalog = new ppdcCatalog(NULL);
56 
57   catalog->add_message("ISOLatin1");
58   catalog->add_message("English");
59 
60   // Add the media size strings...
61   ppdcMediaSize	*size;			// Current media size
62 
63   for (size = (ppdcMediaSize *)src->sizes->first();
64        size;
65        size = (ppdcMediaSize *)src->sizes->next())
66     catalog->add_message(size->text->value);
67 
68   // Then collect all of the UI strings from the sample drivers...
69   ppdcDriver	*d;			// Current driver
70 
71   for (d = (ppdcDriver *)src->drivers->first();
72        d;
73        d = (ppdcDriver *)src->drivers->next())
74     add_ui_strings(d, catalog);
75 
76   // Finally, write all of the strings...
77   ppdcMessage *message;
78 
79   for (message = (ppdcMessage *)catalog->messages->first();
80        message;
81        message = (ppdcMessage *)catalog->messages->next())
82     write_cstring(message->id->value);
83 
84   src->release();
85   catalog->release();
86 
87   // Return with no errors.
88   return (0);
89 }
90 
91 
92 //
93 // 'add_ui_strings()' - Add all UI strings from the driver.
94 //
95 
96 static void
add_ui_strings(ppdcDriver * d,ppdcCatalog * catalog)97 add_ui_strings(ppdcDriver  *d,		// I - Driver data
98                ppdcCatalog *catalog)	// I - Message catalog
99 {
100   // Add the make/model/language strings...
101   catalog->add_message(d->manufacturer->value);
102   catalog->add_message(d->model_name->value);
103 
104   // Add the group/option/choice strings...
105   ppdcGroup	*g;			// Current group
106   ppdcOption	*o;			// Current option
107   ppdcChoice	*c;			// Current choice
108 
109   for (g = (ppdcGroup *)d->groups->first();
110        g;
111        g = (ppdcGroup *)d->groups->next())
112   {
113     if (!g->options->count)
114       continue;
115 
116     if (_cups_strcasecmp(g->name->value, "General"))
117       catalog->add_message(g->text->value);
118 
119     for (o = (ppdcOption *)g->options->first();
120          o;
121 	 o = (ppdcOption *)g->options->next())
122     {
123       if (!o->choices->count)
124         continue;
125 
126       if (o->text->value && strcmp(o->name->value, o->text->value))
127         catalog->add_message(o->text->value);
128       else
129         catalog->add_message(o->name->value);
130 
131       for (c = (ppdcChoice *)o->choices->first();
132            c;
133 	   c = (ppdcChoice *)o->choices->next())
134 	if (c->text->value && strcmp(c->name->value, c->text->value))
135           catalog->add_message(c->text->value);
136         else
137           catalog->add_message(c->name->value);
138     }
139   }
140 
141   // Add profile and preset strings...
142   ppdcAttr *a;				// Current attribute
143   for (a = (ppdcAttr *)d->attrs->first();
144        a;
145        a = (ppdcAttr *)d->attrs->next())
146   {
147     if (a->text->value && a->text->value[0] &&
148         (a->localizable ||
149 	 !strncmp(a->name->value, "Custom", 6) ||
150          !strncmp(a->name->value, "ParamCustom", 11) ||
151          !strcmp(a->name->value, "APCustomColorMatchingName") ||
152          !strcmp(a->name->value, "APPrinterPreset") ||
153          !strcmp(a->name->value, "cupsICCProfile") ||
154          !strcmp(a->name->value, "cupsIPPReason") ||
155          !strcmp(a->name->value, "cupsMarkerName")))
156     {
157       catalog->add_message(a->text->value);
158 
159       if ((a->localizable && a->value->value[0]) ||
160           !strcmp(a->name->value, "cupsIPPReason"))
161         catalog->add_message(a->value->value);
162     }
163     else if (!strncmp(a->name->value, "Custom", 6) ||
164              !strncmp(a->name->value, "ParamCustom", 11))
165       catalog->add_message(a->name->value);
166   }
167 }
168 
169 
170 //
171 // 'write_cstring()' - Write a translation string as a valid C string to stdout.
172 //
173 
174 static void
write_cstring(const char * s)175 write_cstring(const char *s)		/* I - String to write */
176 {
177   fputs("_(\"", stdout);
178   if (s)
179   {
180     while (*s)
181     {
182       if (*s == '\\')
183         fputs("\\\\", stdout);
184       else if (*s == '\"')
185         fputs("\\\"", stdout);
186       else if (*s == '\t')
187         fputs("\\t", stdout);
188       else if (*s == '\n')
189         fputs("\\n", stdout);
190       else
191         putchar(*s);
192 
193       s ++;
194     }
195   }
196   puts("\");");
197 }
198