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