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