]>
Commit | Line | Data |
---|---|---|
5b7874aa | 1 | #! /bin/sh |
1a7b32a3 | 2 | # Wrapper around gettext for programs using the msgid convention. |
a5544970 | 3 | # Copyright (C) 1998-2019 Free Software Foundation, Inc. |
5b7874aa ZW |
4 | |
5 | # Written by Paul Eggert <eggert@twinsun.com>. | |
6 | # Revised by Zack Weinberg <zackw@stanford.edu> for no-POTFILES operation. | |
7 | ||
3014d221 NN |
8 | # This file is part of GCC. |
9 | ||
4b165558 | 10 | # GCC is free software; you can redistribute it and/or modify |
5b7874aa | 11 | # it under the terms of the GNU General Public License as published by |
748086b7 | 12 | # the Free Software Foundation; either version 3, or (at your option) |
5b7874aa ZW |
13 | # any later version. |
14 | ||
4b165558 | 15 | # GCC is distributed in the hope that it will be useful, |
5b7874aa ZW |
16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | # GNU General Public License for more details. | |
19 | ||
20 | # You should have received a copy of the GNU General Public License | |
748086b7 JJ |
21 | # along with GCC; see the file COPYING3. If not see |
22 | # <http://www.gnu.org/licenses/>. | |
5b7874aa | 23 | |
68be8f73 GP |
24 | BUGURL="https://gcc.gnu.org/bugs/" |
25 | ||
1a7b32a3 ZW |
26 | # Always operate in the C locale. |
27 | LANG=C | |
28 | LANGUAGE=C | |
29 | LC_ALL=C | |
30 | export LANG LANGUAGE LC_ALL | |
31 | ||
32 | # Set AWK if environment has not already set it. | |
33 | AWK=${AWK-awk} | |
5b7874aa ZW |
34 | |
35 | # The arguments to this wrapper are: the program to execute, the | |
36 | # name of the "package", and the path to the source directory. | |
37 | ||
38 | if [ $# -ne 3 ] | |
39 | then echo "usage: $0 <xgettext> <package> <srcdir>" | |
40 | exit 1 | |
41 | fi | |
42 | ||
43 | xgettext=$1 | |
44 | package=$2 | |
45 | srcdir=$3 | |
46 | ||
4b794eaf JJ |
47 | case `$xgettext --version | sed -e 1q | sed -e 's/^\([^0-9]*\)//'` in |
48 | 0.14.[5-9]* | 0.14.[1-9][0-9]* | 0.1[5-9]* | 0.[2-9][0-9]* | [1-9].*) : ;; | |
49 | *) echo "$xgettext is too old. GNU xgettext 0.14.5 is required" | |
50 | exit 1 ;; | |
51 | esac | |
52 | ||
5b7874aa ZW |
53 | nl=' |
54 | ' | |
55 | ||
56 | set -e | |
57 | ||
58 | # Create temporary directory for scratch files. | |
59 | T=exg$$.d | |
60 | mkdir $T | |
61 | trap "rm -r $T" 0 | |
62 | ||
1e6347d8 | 63 | pwd=`${PWDCMD-pwd}` |
5b7874aa | 64 | kopt=$pwd/$T/keyword-options |
4b794eaf | 65 | kopt2=$pwd/$T/keyword2-options |
5b7874aa ZW |
66 | emsg=$pwd/$T/emsgids.c |
67 | posr=$pwd/$T/po-sources | |
7f904ad1 | 68 | posrcxx=$pwd/$T/po-cxx-sources |
4b794eaf JJ |
69 | pottmp1=$pwd/$T/tmp1.pot |
70 | pottmp2=$pwd/$T/tmp2.pot | |
7f904ad1 | 71 | pottmp3=$pwd/$T/tmp3.pot |
4b794eaf | 72 | pottmp=$pwd/$T/tmp.pot |
5b7874aa | 73 | |
7f904ad1 ILT |
74 | # Locate files to scan. We scan the following directories: |
75 | # $srcdir | |
76 | # $srcdir/c-family | |
677f3fa8 JM |
77 | # $srcdir/common |
78 | # $srcdir/common/config | |
79 | # $srcdir/common/config/* | |
7f904ad1 ILT |
80 | # $srcdir/config |
81 | # $srcdir/config/* | |
82 | # all subdirectories of $srcdir containing a config-lang.in file, and | |
83 | # all subdirectories of those directories. | |
84 | # Within those directories, we examine all .c, .cc, .h, and .def files. | |
85 | # However, any files listed in $srcdir/po/EXCLUDE are not examined. | |
5b7874aa ZW |
86 | # |
87 | # Then generate keyword options for xgettext, by scanning for declarations | |
88 | # of functions whose parameter names end in "msgid". | |
89 | # | |
5bc69b92 | 90 | # Finally, generate a source file containing all %e and %n strings from |
5b7874aa ZW |
91 | # driver specs, so those can be translated too. |
92 | # | |
93 | # All in one huge awk script. | |
94 | ||
5bc69b92 | 95 | echo "scanning for keywords, %e and %n strings..." >&2 |
5b7874aa ZW |
96 | |
97 | ( cd $srcdir | |
7f904ad1 | 98 | lang_subdirs=`echo */config-lang.in */*/config-lang.in | sed -e 's|/config-lang\.in||g'` |
677f3fa8 JM |
99 | { for dir in "" c-family/ common/ common/config/ common/config/*/ \ |
100 | config/ config/*/ \ | |
7f904ad1 ILT |
101 | `find $lang_subdirs -type d -print | fgrep -v .svn | sort | sed -e 's|$|/|'` |
102 | do for glob in '*.c' '*.cc' '*.h' '*.def' | |
6ec3f553 NB |
103 | do eval echo $dir$glob |
104 | done | |
105 | done; | |
6ec3f553 | 106 | } | tr ' ' "$nl" | grep -v '\*' | |
7f904ad1 | 107 | $AWK -v excl=po/EXCLUDES -v posr=$posr -v posrcxx=$posrcxx -v kopt=$kopt -v kopt2=$kopt2 -v emsg=$emsg ' |
5b7874aa ZW |
108 | function keyword_option(line) { |
109 | paren_index = index(line, "(") | |
110 | name = substr(line, 1, paren_index - 1) | |
111 | sub(/[^0-9A-Z_a-z]*$/, "", name) | |
112 | sub(/[ ]+PARAMS/, "", name) | |
113 | sub(/[ ]+VPARAMS/, "", name) | |
114 | sub(/.*[^0-9A-Z_a-z]/, "", name) | |
115 | ||
116 | args = substr(line, paren_index) | |
117 | sub(/msgid[,\)].*/, "", args) | |
118 | for (n = 1; sub(/^[^,]*,/, "", args); n++) { | |
119 | continue | |
120 | } | |
4b794eaf JJ |
121 | format="" |
122 | if (args ~ /g$/) | |
123 | format="gcc-internal-format" | |
31043f6c FXC |
124 | else if (args ~ /noc$/) |
125 | format="no-c-format" | |
4b794eaf JJ |
126 | else if (args ~ /c$/) |
127 | format="c-format" | |
128 | ||
129 | if (n == 1) { keyword = "--keyword=" name } | |
894e2652 SZ |
130 | else { |
131 | keyword = "--keyword=" name ":" n | |
132 | if (name ~ /_n$/) | |
133 | keyword = keyword "," (n + 1) | |
134 | } | |
4b794eaf JJ |
135 | if (format) { |
136 | keyword=keyword "\n--flag=" name ":" n ":" format | |
894e2652 SZ |
137 | if (name ~ /_n$/) |
138 | keyword = keyword "\n--flag=" name ":" (n + 1) ":" format | |
4b794eaf | 139 | } |
5b7874aa | 140 | |
4b794eaf JJ |
141 | if (! keyword_seen[name]) { |
142 | if (format == "gcc-internal-format") | |
143 | print keyword > kopt2 | |
144 | else | |
145 | print keyword > kopt | |
146 | keyword_seen[name] = keyword | |
147 | } else if (keyword_seen[name] != keyword) { | |
148 | printf("%s used incompatibly as both %s and %s\n", | |
149 | name, keyword_seen[name], keyword) | |
150 | exit (1) | |
5b7874aa ZW |
151 | } |
152 | } | |
153 | ||
154 | function spec_error_string (line) { | |
5bc69b92 SZ |
155 | if (index(line, "%e") != 0 && index(line, "%n") != 0) return |
156 | while ((percent_index = index(line, "%e")) != 0 || | |
157 | (percent_index = index(line, "%n")) != 0) { | |
5b7874aa | 158 | line = substr(line, percent_index + 2) |
5b7874aa ZW |
159 | |
160 | bracket_index = index(line, "}") | |
5bc69b92 SZ |
161 | newline_index = index(line, "\\n") |
162 | ||
b4117c30 | 163 | quote_index = index(line, "\"") |
5bc69b92 | 164 | if (bracket_index == 0 && newline_index == 0) return |
5b7874aa | 165 | |
5bc69b92 SZ |
166 | if (bracket_index != 0) { |
167 | if (quote_index != 0 && bracket_index > quote_index) return | |
168 | msgid = substr(line, 1, bracket_index - 1) | |
169 | line = substr(line, bracket_index + 1) | |
170 | } | |
171 | else if (newline_index != 0) { | |
172 | if (quote_index != 0 && quote_index > newline_index) return | |
173 | msgid = substr(line, 1, newline_index - 1) | |
174 | line = substr(line, newline_index + 1) | |
175 | } | |
b4117c30 ZW |
176 | |
177 | if (index(msgid, "%") != 0) continue | |
5b7874aa | 178 | |
5bc69b92 SZ |
179 | if ((newline_index = index(msgid, "\\n")) != 0) |
180 | msgid = substr(msgid, 1, newline_index - 1) | |
5b7874aa ZW |
181 | printf("#line %d \"%s\"\n", lineno, file) > emsg |
182 | printf("_(\"%s\")\n", msgid) > emsg | |
5b7874aa ZW |
183 | } |
184 | } | |
185 | ||
186 | BEGIN { | |
187 | while ((getline < excl) > 0) { | |
188 | if ($0 ~ /^#/ || $0 ~ /^[ ]*$/) | |
189 | continue | |
190 | excludes[$1] = 1 | |
191 | } | |
192 | } | |
193 | ||
194 | { if (!($0 in excludes)) { | |
7f904ad1 ILT |
195 | if ($0 ~ /.cc$/) { |
196 | print > posrcxx | |
197 | } else { | |
198 | print > posr | |
199 | } | |
5b7874aa ZW |
200 | files[NR] = $0 |
201 | } | |
202 | } | |
203 | ||
204 | END { | |
205 | for (f in files) { | |
206 | file = files[f] | |
207 | lineno = 1 | |
208 | while (getline < file) { | |
209 | if (/^(#[ ]*define[ ]*)?[A-Za-z_].*\(.*msgid[,\)]/) { | |
210 | keyword_option($0) | |
d3c375f5 SZ |
211 | } else if (/^(#[ ]*define[ ]*)?[A-Za-z_].*(\(|\(.*,)$/) { |
212 | name_line = $0 | |
213 | while (getline < file) { | |
214 | lineno++ | |
215 | if (/msgid[,\)]/){ | |
216 | keyword_option(name_line $0) | |
217 | break | |
218 | } else if (/,$/) { | |
219 | name_line = name_line $0 | |
220 | continue | |
221 | } else break | |
222 | } | |
5bc69b92 | 223 | } else if (/%e/ || /%n/) { |
5b7874aa ZW |
224 | spec_error_string($0) |
225 | } | |
226 | lineno++ | |
227 | } | |
228 | } | |
229 | print emsg > posr | |
230 | }' | |
4b794eaf | 231 | ) || exit |
5b7874aa | 232 | |
fb72a0a3 RS |
233 | echo "scanning option files..." >&2 |
234 | ||
235 | ( cd $srcdir; find . -name '*.opt' -print | | |
236 | $AWK '{ | |
237 | file = $1 | |
238 | lineno = 1 | |
239 | field = 0 | |
240 | while (getline < file) { | |
241 | if (/^[ \t]*(;|$)/ || !/^[^ \t]/) { | |
38381536 JJ |
242 | if (field > 2) |
243 | printf("_(\"%s\")\n", line) | |
fb72a0a3 RS |
244 | field = 0 |
245 | } else { | |
61ff2bdc JM |
246 | if ((field == 1) && /MissingArgError/) { |
247 | line = $0 | |
248 | sub(".*MissingArgError\\(", "", line) | |
2d2bd949 JM |
249 | if (line ~ "^{") { |
250 | sub("^{", "", line) | |
251 | sub("}\\).*", "", line) | |
252 | } else | |
253 | sub("\\).*", "", line) | |
254 | printf("#line %d \"%s\"\n", lineno, file) | |
255 | printf("_(\"%s\")\n", line) | |
256 | } | |
e6d4b984 JM |
257 | if ((field == 1) && /UnknownError/) { |
258 | line = $0 | |
259 | sub(".*UnknownError\\(", "", line) | |
260 | if (line ~ "^{") { | |
261 | sub("^{", "", line) | |
262 | sub("}\\).*", "", line) | |
263 | } else | |
264 | sub("\\).*", "", line) | |
265 | printf("#line %d \"%s\"\n", lineno, file) | |
266 | printf("_(\"%s\")\n", line) | |
267 | } | |
965e7f22 | 268 | if ((field == 1) && /Warn\(/) { |
2d2bd949 JM |
269 | line = $0 |
270 | sub(".*Warn\\(", "", line) | |
271 | if (line ~ "^{") { | |
272 | sub("^{", "", line) | |
273 | sub("}\\).*", "", line) | |
274 | } else | |
275 | sub("\\).*", "", line) | |
61ff2bdc JM |
276 | printf("#line %d \"%s\"\n", lineno, file) |
277 | printf("_(\"%s\")\n", line) | |
278 | } | |
fb72a0a3 RS |
279 | if (field == 2) { |
280 | line = $0 | |
fb72a0a3 | 281 | printf("#line %d \"%s\"\n", lineno, file) |
38381536 JJ |
282 | } else if (field > 2) { |
283 | line = line " " $0 | |
fb72a0a3 RS |
284 | } |
285 | field++; | |
286 | } | |
287 | lineno++; | |
288 | } | |
38381536 JJ |
289 | if (field > 2) |
290 | printf("_(\"%s\")\n", line) | |
fb72a0a3 RS |
291 | }') >> $emsg |
292 | ||
7f904ad1 | 293 | # Run the xgettext commands, with temporary added as a file to scan. |
5b7874aa ZW |
294 | echo "running xgettext..." >&2 |
295 | $xgettext --default-domain=$package --directory=$srcdir \ | |
296 | --add-comments `cat $kopt` --files-from=$posr \ | |
8d98c44c | 297 | --copyright-holder="Free Software Foundation, Inc." \ |
68be8f73 | 298 | --msgid-bugs-address="$BUGURL" \ |
4b794eaf | 299 | --language=c -o $pottmp1 |
7f904ad1 ILT |
300 | if test -s $posrcxx; then |
301 | $xgettext --default-domain=$package --directory=$srcdir \ | |
302 | --add-comments `cat $kopt` --files-from=$posrcxx \ | |
303 | --copyright-holder="Free Software Foundation, Inc." \ | |
68be8f73 | 304 | --msgid-bugs-address="$BUGURL" \ |
7f904ad1 ILT |
305 | --language=c++ -o $pottmp2 |
306 | else | |
307 | echo > $pottmp2 | |
308 | fi | |
4b794eaf JJ |
309 | $xgettext --default-domain=$package --directory=$srcdir \ |
310 | --add-comments --keyword= `cat $kopt2` --files-from=$posr \ | |
311 | --copyright-holder="Free Software Foundation, Inc." \ | |
68be8f73 | 312 | --msgid-bugs-address="$BUGURL" \ |
7f904ad1 | 313 | --language=GCC-source -o $pottmp3 |
4b794eaf | 314 | $xgettext --default-domain=$package \ |
7f904ad1 | 315 | --add-comments $pottmp1 $pottmp2 $pottmp3 \ |
4b794eaf | 316 | --copyright-holder="Free Software Foundation, Inc." \ |
68be8f73 | 317 | --msgid-bugs-address="$BUGURL" \ |
4b794eaf | 318 | --language=PO -o $pottmp |
c043fab8 | 319 | # Remove local paths from .pot file. |
4b794eaf | 320 | sed "s:$srcdir/::g;s:$pwd/::g;" <$pottmp >po/$package.pot |