]> git.ipfire.org Git - thirdparty/cups.git/blob - locale/po2strings.c
Update svn:keyword properties.
[thirdparty/cups.git] / locale / po2strings.c
1 /*
2 * "$Id$"
3 *
4 * Convert a GNU gettext .po file to an Apple .strings file.
5 *
6 * Copyright 2007-2012 by Apple Inc.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Apple Inc. and are protected by Federal copyright
10 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
11 * which should have been included with this file. If this file is
12 * file is missing or damaged, see the license at "http://www.cups.org/".
13 *
14 * Usage:
15 *
16 * po2strings filename.strings filename.po
17 *
18 * Compile with:
19 *
20 * gcc -o po2strings po2strings.c `cups-config --libs`
21 *
22 * Contents:
23 *
24 * main() - Convert .po file to .strings.
25 */
26
27 #include <cups/cups-private.h>
28
29
30 /*
31 * The .strings file format is simple:
32 *
33 * // comment
34 * "msgid" = "msgstr";
35 *
36 * The GNU gettext .po format is also fairly simple:
37 *
38 * #. comment
39 * msgid "some text"
40 * msgstr "localized text"
41 *
42 * The comment, msgid, and msgstr text can span multiple lines using the form:
43 *
44 * #. comment
45 * #. more comments
46 * msgid ""
47 * "some long text"
48 * msgstr ""
49 * "localized text spanning "
50 * "multiple lines"
51 *
52 * Both the msgid and msgstr strings use standard C quoting for special
53 * characters like newline and the double quote character.
54 */
55
56 /*
57 * main() - Convert .po file to .strings.
58 */
59
60 int /* O - Exit code */
61 main(int argc, /* I - Number of command-line args */
62 char *argv[]) /* I - Command-line arguments */
63 {
64 int i; /* Looping var */
65 const char *pofile, /* .po filename */
66 *stringsfile; /* .strings filename */
67 cups_file_t *po, /* .po file */
68 *strings; /* .strings file */
69 char s[4096], /* String buffer */
70 *ptr, /* Pointer into buffer */
71 *temp, /* New string */
72 *msgid, /* msgid string */
73 *msgstr; /* msgstr string */
74 int length; /* Length of combined strings */
75 int use_msgid; /* Use msgid strings for msgstr? */
76
77
78 /*
79 * Process command-line arguments...
80 */
81
82 pofile = NULL;
83 stringsfile = NULL;
84 use_msgid = 0;
85
86 for (i = 1; i < argc; i ++)
87 {
88 if (!strcmp(argv[i], "-m"))
89 use_msgid = 1;
90 else if (argv[i][0] == '-')
91 {
92 puts("Usage: po2strings [-m] filename.po filename.strings");
93 return (1);
94 }
95 else if (!pofile)
96 pofile = argv[i];
97 else if (!stringsfile)
98 stringsfile = argv[i];
99 else
100 {
101 puts("Usage: po2strings [-m] filename.po filename.strings");
102 return (1);
103 }
104 }
105
106 if (!pofile || !stringsfile)
107 {
108 puts("Usage: po2strings [-m] filename.po filename.strings");
109 return (1);
110 }
111
112 /*
113 * Read strings from the .po file and write to the .strings file...
114 */
115
116 if ((po = cupsFileOpen(pofile, "r")) == NULL)
117 {
118 perror(pofile);
119 return (1);
120 }
121
122 if ((strings = cupsFileOpen(stringsfile, "w")) == NULL)
123 {
124 perror(stringsfile);
125 cupsFileClose(po);
126 return (1);
127 }
128
129 msgid = msgstr = NULL;
130
131 while (cupsFileGets(po, s, sizeof(s)) != NULL)
132 {
133 if (s[0] == '#' && s[1] == '.')
134 {
135 /*
136 * Copy comment string...
137 */
138
139 if (msgid && msgstr)
140 {
141 /*
142 * First output the last localization string...
143 */
144
145 if (*msgid)
146 cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
147 (use_msgid || !*msgstr) ? msgid : msgstr);
148
149 free(msgid);
150 free(msgstr);
151 msgid = msgstr = NULL;
152 }
153
154 cupsFilePrintf(strings, "//%s\n", s + 2);
155 }
156 else if (s[0] == '#' || !s[0])
157 {
158 /*
159 * Skip blank and file comment lines...
160 */
161
162 continue;
163 }
164 else
165 {
166 /*
167 * Strip the trailing quote...
168 */
169
170 if ((ptr = strrchr(s, '\"')) == NULL)
171 continue;
172
173 *ptr = '\0';
174
175 /*
176 * Find start of value...
177 */
178
179 if ((ptr = strchr(s, '\"')) == NULL)
180 continue;
181
182 ptr ++;
183
184 /*
185 * Create or add to a message...
186 */
187
188 if (!strncmp(s, "msgid", 5))
189 {
190 /*
191 * Output previous message as needed...
192 */
193
194 if (msgid && msgstr)
195 {
196 if (*msgid)
197 cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
198 (use_msgid || !*msgstr) ? msgid : msgstr);
199 }
200
201 if (msgid)
202 free(msgid);
203
204 if (msgstr)
205 free(msgstr);
206
207 msgid = strdup(ptr);
208 msgstr = NULL;
209 }
210 else if (s[0] == '\"' && (msgid || msgstr))
211 {
212 /*
213 * Append to current string...
214 */
215
216 size_t ptrlen = strlen(ptr); /* Length of string */
217
218 length = (int)strlen(msgstr ? msgstr : msgid);
219
220 if ((temp = realloc(msgstr ? msgstr : msgid,
221 length + ptrlen + 1)) == NULL)
222 {
223 free(msgid);
224 if (msgstr)
225 free(msgstr);
226 perror("Unable to allocate string");
227 return (1);
228 }
229
230 if (msgstr)
231 {
232 /*
233 * Copy the new portion to the end of the msgstr string - safe
234 * to use strcpy because the buffer is allocated to the correct
235 * size...
236 */
237
238 msgstr = temp;
239
240 memcpy(msgstr + length, ptr, ptrlen + 1);
241 }
242 else
243 {
244 /*
245 * Copy the new portion to the end of the msgid string - safe
246 * to use strcpy because the buffer is allocated to the correct
247 * size...
248 */
249
250 msgid = temp;
251
252 memcpy(msgid + length, ptr, ptrlen + 1);
253 }
254 }
255 else if (!strncmp(s, "msgstr", 6) && msgid)
256 {
257 /*
258 * Set the string...
259 */
260
261 if (msgstr)
262 free(msgstr);
263
264 if ((msgstr = strdup(ptr)) == NULL)
265 {
266 free(msgid);
267 perror("Unable to allocate msgstr");
268 return (1);
269 }
270 }
271 }
272 }
273
274 if (msgid && msgstr)
275 {
276 if (*msgid)
277 cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
278 (use_msgid || !*msgstr) ? msgid : msgstr);
279 }
280
281 if (msgid)
282 free(msgid);
283
284 if (msgstr)
285 free(msgstr);
286
287 cupsFileClose(po);
288 cupsFileClose(strings);
289
290 return (0);
291 }
292
293
294 /*
295 * End of "$Id$".
296 */