]>
Commit | Line | Data |
---|---|---|
bc44d920 | 1 | /* |
bc44d920 | 2 | * Convert Apple .strings file (UTF-16 BE text file) to GNU gettext .po files. |
3 | * | |
7e86f2f6 MS |
4 | * Copyright 2007-2014 by Apple Inc. |
5 | * | |
e3101897 | 6 | * Licensed under Apache License v2.0. See the file "LICENSE" for more information. |
7e86f2f6 | 7 | * |
bc44d920 | 8 | * Usage: |
9 | * | |
10 | * strings2po filename.strings filename.po | |
11 | * | |
12 | * Compile with: | |
13 | * | |
14 | * gcc -o strings2po strings2po.c | |
bc44d920 | 15 | */ |
16 | ||
17 | #include <stdio.h> | |
18 | #include <stdlib.h> | |
19 | ||
20 | ||
21 | /* | |
22 | * The .strings file format is simple: | |
23 | * | |
24 | * // comment | |
25 | * "id" = "str"; | |
26 | * | |
27 | * Both the id and str strings use standard C quoting for special characters | |
28 | * like newline and the double quote character. | |
29 | */ | |
30 | ||
31 | /* | |
32 | * Local functions... | |
33 | */ | |
34 | ||
35 | static int read_strings(FILE *strings, char *buffer, size_t bufsize, | |
36 | char **id, char **str); | |
37 | static void write_po(FILE *po, const char *what, const char *s); | |
38 | ||
39 | ||
40 | /* | |
41 | * main() - Convert .strings file to .po. | |
42 | */ | |
43 | ||
44 | int /* O - Exit code */ | |
45 | main(int argc, /* I - Number of command-line args */ | |
46 | char *argv[]) /* I - Command-line arguments */ | |
47 | { | |
48 | FILE *strings, /* .strings file */ | |
49 | *po; /* .po file */ | |
50 | char iconv[1024], /* iconv command */ | |
51 | buffer[8192], /* Line buffer */ | |
52 | *id, /* ID string */ | |
53 | *str; /* Translation string */ | |
54 | int count; /* Number of messages converted */ | |
55 | ||
56 | ||
57 | if (argc != 3) | |
58 | { | |
59 | puts("Usage: strings2po filename.strings filename.po"); | |
60 | return (1); | |
61 | } | |
62 | ||
63 | /* | |
64 | * Cheat by using iconv to convert the .strings file from UTF-16 to UTF-8 | |
65 | * which is what we need for the .po file (and it makes things a lot | |
66 | * simpler...) | |
67 | */ | |
68 | ||
69 | snprintf(iconv, sizeof(iconv), "iconv -f utf-16 -t utf-8 '%s'", argv[1]); | |
70 | if ((strings = popen(iconv, "r")) == NULL) | |
71 | { | |
72 | perror(argv[1]); | |
73 | return (1); | |
74 | } | |
75 | ||
76 | if ((po = fopen(argv[2], "w")) == NULL) | |
77 | { | |
78 | perror(argv[2]); | |
79 | pclose(strings); | |
80 | return (1); | |
81 | } | |
82 | ||
83 | count = 0; | |
84 | ||
85 | while (read_strings(strings, buffer, sizeof(buffer), &id, &str)) | |
86 | { | |
87 | count ++; | |
88 | write_po(po, "msgid", id); | |
89 | write_po(po, "msgstr", str); | |
90 | } | |
91 | ||
92 | pclose(strings); | |
93 | fclose(po); | |
94 | ||
95 | printf("%s: %d messages.\n", argv[2], count); | |
96 | ||
97 | return (0); | |
98 | } | |
99 | ||
100 | ||
101 | /* | |
102 | * 'read_strings()' - Read a line from a .strings file. | |
103 | */ | |
104 | ||
105 | static int /* O - 1 on success, 0 on failure */ | |
106 | read_strings(FILE *strings, /* I - .strings file */ | |
107 | char *buffer, /* I - Line buffer */ | |
108 | size_t bufsize, /* I - Size of line buffer */ | |
109 | char **id, /* O - Pointer to ID string */ | |
110 | char **str) /* O - Pointer to translation string */ | |
111 | { | |
112 | char *bufptr; /* Pointer into buffer */ | |
113 | ||
114 | ||
7e86f2f6 | 115 | while (fgets(buffer, (int)bufsize, strings)) |
bc44d920 | 116 | { |
117 | if (buffer[0] != '\"') | |
118 | continue; | |
119 | ||
120 | *id = buffer + 1; | |
121 | ||
122 | for (bufptr = buffer + 1; *bufptr && *bufptr != '\"'; bufptr ++) | |
123 | if (*bufptr == '\\') | |
124 | bufptr ++; | |
125 | ||
126 | if (*bufptr != '\"') | |
127 | continue; | |
128 | ||
129 | *bufptr++ = '\0'; | |
130 | ||
131 | while (*bufptr && *bufptr != '\"') | |
132 | bufptr ++; | |
133 | ||
134 | if (!*bufptr) | |
135 | continue; | |
136 | ||
137 | bufptr ++; | |
138 | *str = bufptr; | |
139 | ||
140 | for (; *bufptr && *bufptr != '\"'; bufptr ++) | |
141 | if (*bufptr == '\\') | |
142 | bufptr ++; | |
143 | ||
144 | if (*bufptr != '\"') | |
145 | continue; | |
146 | ||
1f0275e3 | 147 | *bufptr = '\0'; |
bc44d920 | 148 | |
149 | return (1); | |
150 | } | |
151 | ||
152 | return (0); | |
153 | } | |
154 | ||
155 | ||
156 | /* | |
157 | * 'write_po()' - Write a line to the .po file. | |
158 | */ | |
159 | ||
160 | static void | |
161 | write_po(FILE *po, /* I - .po file */ | |
162 | const char *what, /* I - Type of string */ | |
163 | const char *s) /* I - String to write */ | |
164 | { | |
165 | fprintf(po, "%s \"%s\"\n", what, s); | |
166 | } |