Revert manifest to default one
[external/cups.git] / locale / po2strings.c
1 /*
2  * "$Id: po2strings.c 10379 2012-03-23 22:16:22Z mike $"
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         length = (int)strlen(msgstr ? msgstr : msgid);
217
218         if ((temp = realloc(msgstr ? msgstr : msgid,
219                             length + strlen(ptr) + 1)) == NULL)
220         {
221           free(msgid);
222           if (msgstr)
223             free(msgstr);
224           perror("Unable to allocate string");
225           return (1);
226         }
227
228         if (msgstr)
229         {
230          /*
231           * Copy the new portion to the end of the msgstr string - safe
232           * to use strcpy because the buffer is allocated to the correct
233           * size...
234           */
235
236           msgstr = temp;
237
238           strcpy(msgstr + length, ptr);
239         }
240         else
241         {
242          /*
243           * Copy the new portion to the end of the msgid string - safe
244           * to use strcpy because the buffer is allocated to the correct
245           * size...
246           */
247
248           msgid = temp;
249
250           strcpy(msgid + length, ptr);
251         }
252       }
253       else if (!strncmp(s, "msgstr", 6) && msgid)
254       {
255        /*
256         * Set the string...
257         */
258
259         if (msgstr)
260           free(msgstr);
261
262         if ((msgstr = strdup(ptr)) == NULL)
263         {
264           free(msgid);
265           perror("Unable to allocate msgstr");
266           return (1);
267         }
268       }
269     }
270   }
271
272   if (msgid && msgstr)
273   {
274     if (*msgid)
275       cupsFilePrintf(strings, "\"%s\" = \"%s\";\n", msgid,
276                      (use_msgid || !*msgstr) ? msgid : msgstr);
277   }
278
279   if (msgid)
280     free(msgid);
281
282   if (msgstr)
283     free(msgstr);
284
285   cupsFileClose(po);
286   cupsFileClose(strings);
287
288   return (0);
289 }
290
291
292 /*
293  * End of "$Id: po2strings.c 10379 2012-03-23 22:16:22Z mike $".
294  */