1 /* xgettext C/C++/ObjectiveC backend.
2 Copyright (C) 1995-1998, 2000-2009, 2012 Free Software Foundation, Inc.
4 This file was written by Peter Miller <millerp@canb.auug.org.au>
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
35 #include "error-progname.h"
37 #include "xvasprintf.h"
41 #define _(s) gettext(s)
43 #define SIZEOF(a) (sizeof(a) / sizeof(a[0]))
46 /* The ANSI C standard defines several phases of translation:
48 1. Terminate line by \n, regardless of the external representation
49 of a text line. Stdio does this for us.
51 2. Convert trigraphs to their single character equivalents.
53 3. Concatenate each line ending in backslash (\) with the following
56 4. Replace each comment with a space character.
58 5. Parse each resulting logical line as preprocessing tokens a
61 6. Recognize and carry out directives (it also expands macros on
62 non-directive lines, which we do not do here).
64 7. Replaces escape sequences within character strings with their
65 single character equivalents (we do this in step 5, because we
66 don't have to worry about the #include argument).
68 8. Concatenates adjacent string literals to form single string
69 literals (because we don't expand macros, there are a few things
72 9. Converts the remaining preprocessing tokens to C tokens and
73 discards any white space from the translation unit.
75 This lexer implements the above, and presents the scanner (in
76 xgettext.c) with a stream of C tokens. The comments are
77 accumulated in a buffer, and given to xgettext when asked for. */
80 /* ========================= Lexer customization. ========================= */
82 static bool trigraphs = false;
91 /* ====================== Keyword set customization. ====================== */
93 /* If true extract all strings. */
94 static bool extract_all = false;
96 static hash_table c_keywords;
97 static hash_table objc_keywords;
98 static bool default_keywords = true;
109 add_keyword (const char *name, hash_table *keywords)
112 default_keywords = false;
116 struct callshape shape;
119 if (keywords->table == NULL)
120 hash_init (keywords, 100);
122 split_keywordspec (name, &end, &shape);
124 /* The characters between name and end should form a valid C identifier.
125 A colon means an invalid parse in split_keywordspec(). */
126 colon = strchr (name, ':');
127 if (colon == NULL || colon >= end)
128 insert_keyword_callshape (keywords, name, end - name, &shape);
133 x_c_keyword (const char *name)
135 add_keyword (name, &c_keywords);
139 x_objc_keyword (const char *name)
141 add_keyword (name, &objc_keywords);
144 /* Finish initializing the keywords hash tables.
145 Called after argument processing, before each file is processed. */
149 if (default_keywords)
151 /* When adding new keywords here, also update the documentation in
153 x_c_keyword ("gettext");
154 x_c_keyword ("dgettext:2");
155 x_c_keyword ("dcgettext:2");
156 x_c_keyword ("ngettext:1,2");
157 x_c_keyword ("dngettext:2,3");
158 x_c_keyword ("dcngettext:2,3");
159 x_c_keyword ("gettext_noop");
160 x_c_keyword ("pgettext:1c,2");
161 x_c_keyword ("dpgettext:2c,3");
162 x_c_keyword ("dcpgettext:2c,3");
163 x_c_keyword ("npgettext:1c,2,3");
164 x_c_keyword ("dnpgettext:2c,3,4");
165 x_c_keyword ("dcnpgettext:2c,3,4");
167 x_objc_keyword ("gettext");
168 x_objc_keyword ("dgettext:2");
169 x_objc_keyword ("dcgettext:2");
170 x_objc_keyword ("ngettext:1,2");
171 x_objc_keyword ("dngettext:2,3");
172 x_objc_keyword ("dcngettext:2,3");
173 x_objc_keyword ("gettext_noop");
174 x_objc_keyword ("pgettext:1c,2");
175 x_objc_keyword ("dpgettext:2c,3");
176 x_objc_keyword ("dcpgettext:2c,3");
177 x_objc_keyword ("npgettext:1c,2,3");
178 x_objc_keyword ("dnpgettext:2c,3,4");
179 x_objc_keyword ("dcnpgettext:2c,3,4");
180 x_objc_keyword ("NSLocalizedString"); /* similar to gettext */
181 x_objc_keyword ("_"); /* similar to gettext */
182 x_objc_keyword ("NSLocalizedStaticString"); /* similar to gettext_noop */
183 x_objc_keyword ("__"); /* similar to gettext_noop */
185 default_keywords = false;
192 xgettext_record_flag ("gettext:1:pass-c-format");
193 xgettext_record_flag ("dgettext:2:pass-c-format");
194 xgettext_record_flag ("dcgettext:2:pass-c-format");
195 xgettext_record_flag ("ngettext:1:pass-c-format");
196 xgettext_record_flag ("ngettext:2:pass-c-format");
197 xgettext_record_flag ("dngettext:2:pass-c-format");
198 xgettext_record_flag ("dngettext:3:pass-c-format");
199 xgettext_record_flag ("dcngettext:2:pass-c-format");
200 xgettext_record_flag ("dcngettext:3:pass-c-format");
201 xgettext_record_flag ("gettext_noop:1:pass-c-format");
202 xgettext_record_flag ("pgettext:2:pass-c-format");
203 xgettext_record_flag ("dpgettext:3:pass-c-format");
204 xgettext_record_flag ("dcpgettext:3:pass-c-format");
205 xgettext_record_flag ("npgettext:2:pass-c-format");
206 xgettext_record_flag ("npgettext:3:pass-c-format");
207 xgettext_record_flag ("dnpgettext:3:pass-c-format");
208 xgettext_record_flag ("dnpgettext:4:pass-c-format");
209 xgettext_record_flag ("dcnpgettext:3:pass-c-format");
210 xgettext_record_flag ("dcnpgettext:4:pass-c-format");
213 xgettext_record_flag ("fprintf:2:c-format");
214 xgettext_record_flag ("vfprintf:2:c-format");
215 xgettext_record_flag ("printf:1:c-format");
216 xgettext_record_flag ("vprintf:1:c-format");
217 xgettext_record_flag ("sprintf:2:c-format");
218 xgettext_record_flag ("vsprintf:2:c-format");
219 xgettext_record_flag ("snprintf:3:c-format");
220 xgettext_record_flag ("vsnprintf:3:c-format");
221 #if 0 /* These functions are not standard. */
223 xgettext_record_flag ("asprintf:2:c-format");
224 xgettext_record_flag ("vasprintf:2:c-format");
225 xgettext_record_flag ("dprintf:2:c-format");
226 xgettext_record_flag ("vdprintf:2:c-format");
227 xgettext_record_flag ("obstack_printf:2:c-format");
228 xgettext_record_flag ("obstack_vprintf:2:c-format");
230 xgettext_record_flag ("error:3:c-format");
231 xgettext_record_flag ("error_at_line:5:c-format");
233 xgettext_record_flag ("argp_error:2:c-format");
234 xgettext_record_flag ("argp_failure:2:c-format");
237 xgettext_record_flag ("gettext:1:pass-qt-format");
238 xgettext_record_flag ("dgettext:2:pass-qt-format");
239 xgettext_record_flag ("dcgettext:2:pass-qt-format");
240 xgettext_record_flag ("ngettext:1:pass-qt-format");
241 xgettext_record_flag ("ngettext:2:pass-qt-format");
242 xgettext_record_flag ("dngettext:2:pass-qt-format");
243 xgettext_record_flag ("dngettext:3:pass-qt-format");
244 xgettext_record_flag ("dcngettext:2:pass-qt-format");
245 xgettext_record_flag ("dcngettext:3:pass-qt-format");
246 xgettext_record_flag ("gettext_noop:1:pass-qt-format");
247 xgettext_record_flag ("pgettext:2:pass-qt-format");
248 xgettext_record_flag ("dpgettext:3:pass-qt-format");
249 xgettext_record_flag ("dcpgettext:3:pass-qt-format");
250 xgettext_record_flag ("npgettext:2:pass-qt-format");
251 xgettext_record_flag ("npgettext:3:pass-qt-format");
252 xgettext_record_flag ("dnpgettext:3:pass-qt-format");
253 xgettext_record_flag ("dnpgettext:4:pass-qt-format");
254 xgettext_record_flag ("dcnpgettext:3:pass-qt-format");
255 xgettext_record_flag ("dcnpgettext:4:pass-qt-format");
257 xgettext_record_flag ("gettext:1:pass-kde-format");
258 xgettext_record_flag ("dgettext:2:pass-kde-format");
259 xgettext_record_flag ("dcgettext:2:pass-kde-format");
260 xgettext_record_flag ("ngettext:1:pass-kde-format");
261 xgettext_record_flag ("ngettext:2:pass-kde-format");
262 xgettext_record_flag ("dngettext:2:pass-kde-format");
263 xgettext_record_flag ("dngettext:3:pass-kde-format");
264 xgettext_record_flag ("dcngettext:2:pass-kde-format");
265 xgettext_record_flag ("dcngettext:3:pass-kde-format");
266 xgettext_record_flag ("gettext_noop:1:pass-kde-format");
267 xgettext_record_flag ("pgettext:2:pass-kde-format");
268 xgettext_record_flag ("dpgettext:3:pass-kde-format");
269 xgettext_record_flag ("dcpgettext:3:pass-kde-format");
270 xgettext_record_flag ("npgettext:2:pass-kde-format");
271 xgettext_record_flag ("npgettext:3:pass-kde-format");
272 xgettext_record_flag ("dnpgettext:3:pass-kde-format");
273 xgettext_record_flag ("dnpgettext:4:pass-kde-format");
274 xgettext_record_flag ("dcnpgettext:3:pass-kde-format");
275 xgettext_record_flag ("dcnpgettext:4:pass-kde-format");
277 xgettext_record_flag ("gettext:1:pass-boost-format");
278 xgettext_record_flag ("dgettext:2:pass-boost-format");
279 xgettext_record_flag ("dcgettext:2:pass-boost-format");
280 xgettext_record_flag ("ngettext:1:pass-boost-format");
281 xgettext_record_flag ("ngettext:2:pass-boost-format");
282 xgettext_record_flag ("dngettext:2:pass-boost-format");
283 xgettext_record_flag ("dngettext:3:pass-boost-format");
284 xgettext_record_flag ("dcngettext:2:pass-boost-format");
285 xgettext_record_flag ("dcngettext:3:pass-boost-format");
286 xgettext_record_flag ("gettext_noop:1:pass-boost-format");
287 xgettext_record_flag ("pgettext:2:pass-boost-format");
288 xgettext_record_flag ("dpgettext:3:pass-boost-format");
289 xgettext_record_flag ("dcpgettext:3:pass-boost-format");
290 xgettext_record_flag ("npgettext:2:pass-boost-format");
291 xgettext_record_flag ("npgettext:3:pass-boost-format");
292 xgettext_record_flag ("dnpgettext:3:pass-boost-format");
293 xgettext_record_flag ("dnpgettext:4:pass-boost-format");
294 xgettext_record_flag ("dcnpgettext:3:pass-boost-format");
295 xgettext_record_flag ("dcnpgettext:4:pass-boost-format");
297 /* <boost/format.hpp> */
298 xgettext_record_flag ("format:1:boost-format");
302 init_flag_table_objc ()
304 /* Since the settings done in init_flag_table_c() also have an effect for
305 the ObjectiveC parser, we don't have to repeat them here. */
306 xgettext_record_flag ("gettext:1:pass-objc-format");
307 xgettext_record_flag ("dgettext:2:pass-objc-format");
308 xgettext_record_flag ("dcgettext:2:pass-objc-format");
309 xgettext_record_flag ("ngettext:1:pass-objc-format");
310 xgettext_record_flag ("ngettext:2:pass-objc-format");
311 xgettext_record_flag ("dngettext:2:pass-objc-format");
312 xgettext_record_flag ("dngettext:3:pass-objc-format");
313 xgettext_record_flag ("dcngettext:2:pass-objc-format");
314 xgettext_record_flag ("dcngettext:3:pass-objc-format");
315 xgettext_record_flag ("gettext_noop:1:pass-objc-format");
316 xgettext_record_flag ("pgettext:2:pass-objc-format");
317 xgettext_record_flag ("dpgettext:3:pass-objc-format");
318 xgettext_record_flag ("dcpgettext:3:pass-objc-format");
319 xgettext_record_flag ("npgettext:2:pass-objc-format");
320 xgettext_record_flag ("npgettext:3:pass-objc-format");
321 xgettext_record_flag ("dnpgettext:3:pass-objc-format");
322 xgettext_record_flag ("dnpgettext:4:pass-objc-format");
323 xgettext_record_flag ("dcnpgettext:3:pass-objc-format");
324 xgettext_record_flag ("dcnpgettext:4:pass-objc-format");
325 xgettext_record_flag ("NSLocalizedString:1:pass-c-format");
326 xgettext_record_flag ("NSLocalizedString:1:pass-objc-format");
327 xgettext_record_flag ("_:1:pass-c-format");
328 xgettext_record_flag ("_:1:pass-objc-format");
329 xgettext_record_flag ("stringWithFormat::1:objc-format");
330 xgettext_record_flag ("initWithFormat::1:objc-format");
331 xgettext_record_flag ("stringByAppendingFormat::1:objc-format");
332 xgettext_record_flag ("localizedStringWithFormat::1:objc-format");
333 xgettext_record_flag ("appendFormat::1:objc-format");
337 init_flag_table_gcc_internal ()
339 xgettext_record_flag ("gettext:1:pass-gcc-internal-format");
340 xgettext_record_flag ("dgettext:2:pass-gcc-internal-format");
341 xgettext_record_flag ("dcgettext:2:pass-gcc-internal-format");
342 xgettext_record_flag ("ngettext:1:pass-gcc-internal-format");
343 xgettext_record_flag ("ngettext:2:pass-gcc-internal-format");
344 xgettext_record_flag ("dngettext:2:pass-gcc-internal-format");
345 xgettext_record_flag ("dngettext:3:pass-gcc-internal-format");
346 xgettext_record_flag ("dcngettext:2:pass-gcc-internal-format");
347 xgettext_record_flag ("dcngettext:3:pass-gcc-internal-format");
348 xgettext_record_flag ("gettext_noop:1:pass-gcc-internal-format");
349 xgettext_record_flag ("pgettext:2:pass-gcc-internal-format");
350 xgettext_record_flag ("dpgettext:3:pass-gcc-internal-format");
351 xgettext_record_flag ("dcpgettext:3:pass-gcc-internal-format");
352 xgettext_record_flag ("npgettext:2:pass-gcc-internal-format");
353 xgettext_record_flag ("npgettext:3:pass-gcc-internal-format");
354 xgettext_record_flag ("dnpgettext:3:pass-gcc-internal-format");
355 xgettext_record_flag ("dnpgettext:4:pass-gcc-internal-format");
356 xgettext_record_flag ("dcnpgettext:3:pass-gcc-internal-format");
357 xgettext_record_flag ("dcnpgettext:4:pass-gcc-internal-format");
358 #if 0 /* This should better be done inside GCC. */
359 /* grepping for ATTRIBUTE_PRINTF in gcc-3.3/gcc/?*.h */
361 xgettext_record_flag ("status_warning:2:gcc-internal-format");
363 xgettext_record_flag ("pedwarn_c99:1:pass-gcc-internal-format");
365 //xgettext_record_flag ("error:1:c-format"); // 3 different versions
366 xgettext_record_flag ("notice:1:c-format");
367 //xgettext_record_flag ("fatal:1:c-format"); // 2 different versions
368 xgettext_record_flag ("fatal_perror:1:c-format");
370 xgettext_record_flag ("cpp_error:3:c-format");
371 xgettext_record_flag ("cpp_error_with_line:5:c-format");
373 xgettext_record_flag ("diagnostic_set_info:2:pass-gcc-internal-format");
374 xgettext_record_flag ("output_printf:2:gcc-internal-format");
375 xgettext_record_flag ("output_verbatim:2:pass-gcc-internal-format");
376 xgettext_record_flag ("verbatim:1:gcc-internal-format");
377 xgettext_record_flag ("inform:1:pass-gcc-internal-format");
379 //xgettext_record_flag ("fatal:1:c-format"); // 2 different versions
380 //xgettext_record_flag ("error:1:c-format"); // 3 different versions
382 xgettext_record_flag ("attr_printf:2:pass-c-format");
384 xgettext_record_flag ("error_at_line:2:pass-c-format");
385 xgettext_record_flag ("xvasprintf:2:pass-c-format");
386 xgettext_record_flag ("xasprintf:1:pass-c-format");
387 xgettext_record_flag ("oprintf:2:pass-c-format");
389 xgettext_record_flag ("message_with_line:2:pass-c-format");
391 xgettext_record_flag ("output_operand_lossage:1:c-format");
393 xgettext_record_flag ("ra_debug_msg:2:pass-c-format");
395 xgettext_record_flag ("fnotice:2:c-format");
396 xgettext_record_flag ("fatal_io_error:2:gcc-internal-format");
397 xgettext_record_flag ("error_for_asm:2:pass-gcc-internal-format");
398 xgettext_record_flag ("warning_for_asm:2:pass-gcc-internal-format");
399 xgettext_record_flag ("error_with_file_and_line:3:pass-gcc-internal-format");
400 xgettext_record_flag ("error_with_decl:2:pass-gcc-internal-format");
401 xgettext_record_flag ("pedwarn:1:gcc-internal-format");
402 xgettext_record_flag ("pedwarn_with_file_and_line:3:gcc-internal-format");
403 xgettext_record_flag ("pedwarn_with_decl:2:gcc-internal-format");
404 xgettext_record_flag ("sorry:1:gcc-internal-format");
405 xgettext_record_flag ("error:1:pass-gcc-internal-format");
406 xgettext_record_flag ("fatal_error:1:pass-gcc-internal-format");
407 xgettext_record_flag ("internal_error:1:pass-gcc-internal-format");
408 xgettext_record_flag ("warning:1:pass-gcc-internal-format");
409 xgettext_record_flag ("warning_with_file_and_line:3:pass-gcc-internal-format");
410 xgettext_record_flag ("warning_with_decl:2:pass-gcc-internal-format");
412 xgettext_record_flag ("ffecom_get_invented_identifier:1:pass-c-format");
414 xgettext_record_flag ("ffests_printf:2:pass-c-format");
415 /* java/java-tree.h */
416 xgettext_record_flag ("parse_error_context:2:pass-c-format");
419 xgettext_record_flag ("gettext:1:pass-gfc-internal-format");
420 xgettext_record_flag ("dgettext:2:pass-gfc-internal-format");
421 xgettext_record_flag ("dcgettext:2:pass-gfc-internal-format");
422 xgettext_record_flag ("ngettext:1:pass-gfc-internal-format");
423 xgettext_record_flag ("ngettext:2:pass-gfc-internal-format");
424 xgettext_record_flag ("dngettext:2:pass-gfc-internal-format");
425 xgettext_record_flag ("dngettext:3:pass-gfc-internal-format");
426 xgettext_record_flag ("dcngettext:2:pass-gfc-internal-format");
427 xgettext_record_flag ("dcngettext:3:pass-gfc-internal-format");
428 xgettext_record_flag ("gettext_noop:1:pass-gfc-internal-format");
429 xgettext_record_flag ("pgettext:2:pass-gfc-internal-format");
430 xgettext_record_flag ("dpgettext:3:pass-gfc-internal-format");
431 xgettext_record_flag ("dcpgettext:3:pass-gfc-internal-format");
432 xgettext_record_flag ("npgettext:2:pass-gfc-internal-format");
433 xgettext_record_flag ("npgettext:3:pass-gfc-internal-format");
434 xgettext_record_flag ("dnpgettext:3:pass-gfc-internal-format");
435 xgettext_record_flag ("dnpgettext:4:pass-gfc-internal-format");
436 xgettext_record_flag ("dcnpgettext:3:pass-gfc-internal-format");
437 xgettext_record_flag ("dcnpgettext:4:pass-gfc-internal-format");
438 #if 0 /* This should better be done inside GCC. */
439 /* fortran/error.c */
440 xgettext_record_flag ("gfc_error:1:gfc-internal-format");
441 xgettext_record_flag ("gfc_error_now:1:gfc-internal-format");
442 xgettext_record_flag ("gfc_fatal_error:1:gfc-internal-format");
443 xgettext_record_flag ("gfc_internal_error:1:gfc-internal-format");
444 xgettext_record_flag ("gfc_notify_std:2:gfc-internal-format");
445 xgettext_record_flag ("gfc_warning:1:gfc-internal-format");
446 xgettext_record_flag ("gfc_warning_now:1:gfc-internal-format");
451 /* ======================== Reading of characters. ======================== */
453 /* Real filename, used in error messages about the input file. */
454 static const char *real_file_name;
456 /* Logical filename and line number, used to label the extracted messages. */
457 static char *logical_file_name;
458 static int line_number;
460 /* The input file stream. */
464 /* 0. Terminate line by \n, regardless whether the external representation of
465 a line terminator is LF (Unix), CR (Mac) or CR/LF (DOS/Windows).
466 It is debatable whether supporting CR/LF line terminators in C sources
467 on Unix is ISO C or POSIX compliant, but since GCC 3.3 now supports it
468 unconditionally, it must be OK.
469 The so-called "text mode" in stdio on DOS/Windows translates CR/LF to \n
470 automatically, but here we also need this conversion on Unix. As a side
471 effect, on DOS/Windows we also parse CR/CR/LF into a single \n, but this
484 error (EXIT_FAILURE, errno, _("error while reading \"%s\""),
493 if (c1 != EOF && c1 != '\n')
496 /* Seen line terminator CR or CR/LF. */
504 /* Supports only one pushback character, and not '\n'. */
506 phase0_ungetc (int c)
513 /* 1. line_number handling. Combine backslash-newline to nothing. */
515 static unsigned char phase1_pushback[2];
516 static int phase1_pushback_length;
524 if (phase1_pushback_length)
526 c = phase1_pushback[--phase1_pushback_length];
557 /* Supports 2 characters of pushback. */
559 phase1_ungetc (int c)
571 if (phase1_pushback_length == SIZEOF (phase1_pushback))
573 phase1_pushback[phase1_pushback_length++] = c;
579 /* 2. Convert trigraphs to their single character equivalents. Most
580 sane human beings vomit copiously at the mention of trigraphs, which
581 is why they are an option. */
583 static unsigned char phase2_pushback[1];
584 static int phase2_pushback_length;
592 if (phase2_pushback_length)
593 return phase2_pushback[--phase2_pushback_length];
595 return phase1_getc ();
634 /* Supports only one pushback character. */
636 phase2_ungetc (int c)
640 if (phase2_pushback_length == SIZEOF (phase2_pushback))
642 phase2_pushback[phase2_pushback_length++] = c;
647 /* 3. Concatenate each line ending in backslash (\) with the following
648 line. Basically, all you need to do is elide "\\\n" sequences from
651 static unsigned char phase3_pushback[2];
652 static int phase3_pushback_length;
658 if (phase3_pushback_length)
659 return phase3_pushback[--phase3_pushback_length];
662 int c = phase2_getc ();
675 /* Supports 2 characters of pushback. */
677 phase3_ungetc (int c)
681 if (phase3_pushback_length == SIZEOF (phase3_pushback))
683 phase3_pushback[phase3_pushback_length++] = c;
688 /* Accumulating comments. */
691 static size_t bufmax;
692 static size_t buflen;
703 if (buflen >= bufmax)
705 bufmax = 2 * bufmax + 10;
706 buffer = xrealloc (buffer, bufmax);
708 buffer[buflen++] = c;
712 comment_line_end (size_t chars_to_remove)
714 buflen -= chars_to_remove;
716 && (buffer[buflen - 1] == ' ' || buffer[buflen - 1] == '\t'))
718 if (chars_to_remove == 0 && buflen >= bufmax)
720 bufmax = 2 * bufmax + 10;
721 buffer = xrealloc (buffer, bufmax);
723 buffer[buflen] = '\0';
724 savable_comment_add (buffer);
728 /* These are for tracking whether comments count as immediately before
730 static int last_comment_line;
731 static int last_non_comment_line;
732 static int newline_count;
735 /* 4. Replace each comment that is not inside a character constant or
736 string literal with a space character. We need to remember the
737 comment for later, because it may be attached to a keyword string.
738 We also optionally understand C++ comments. */
759 last_was_star = false;
765 /* We skip all leading white space, but not EOLs. */
766 if (!(buflen == 0 && (c == ' ' || c == '\t')))
771 comment_line_end (1);
773 last_was_star = false;
777 last_was_star = true;
783 comment_line_end (2);
789 last_was_star = false;
794 last_comment_line = newline_count;
798 /* C++ or ISO C 99 comment. */
803 if (c == '\n' || c == EOF)
805 /* We skip all leading white space, but not EOLs. */
806 if (!(buflen == 0 && (c == ' ' || c == '\t')))
809 comment_line_end (0);
810 last_comment_line = newline_count;
816 /* Supports only one pushback character. */
818 phase4_ungetc (int c)
824 /* ========================== Reading of tokens. ========================== */
827 /* True if ObjectiveC extensions are recognized. */
828 static bool objc_extensions;
832 token_type_character_constant, /* 'x' */
835 token_type_hash, /* # */
836 token_type_lparen, /* ( */
837 token_type_rparen, /* ) */
838 token_type_comma, /* , */
839 token_type_colon, /* : */
840 token_type_name, /* abc */
841 token_type_number, /* 2.7 */
842 token_type_string_literal, /* "abc" */
843 token_type_symbol, /* < > = etc. */
844 token_type_objc_special, /* @ */
845 token_type_white_space
847 typedef enum token_type_ty token_type_ty;
849 typedef struct token_ty token_ty;
853 char *string; /* for token_type_name, token_type_string_literal */
854 refcounted_string_list_ty *comment; /* for token_type_string_literal,
855 token_type_objc_special */
861 /* 7. Replace escape sequences within character strings with their
862 single character equivalents. This is called from phase 5, because
863 we don't have to worry about the #include argument. There are
864 pathological cases which could bite us (like the DOS directory
865 separator), but just pretend it can't happen. */
867 #define P7_QUOTES (1000 + '"')
868 #define P7_QUOTE (1000 + '\'')
869 #define P7_NEWLINE (1000 + '\n')
876 /* Use phase 3, because phase 4 elides comments. */
879 /* Return a magic newline indicator, so that we can distinguish
880 between the user requesting a newline in the string (e.g. using
881 "\n" or "\012") from the user failing to terminate the string or
882 character constant. The ANSI C standard says: 3.1.3.4 Character
883 Constants contain "any character except single quote, backslash or
884 newline; or an escape sequence" and 3.1.4 String Literals contain
885 "any character except double quote, backslash or newline; or an
888 Most compilers give a fatal error in this case, however gcc is
889 stupidly silent, even though this is a very common typo. OK, so
890 "gcc --pedantic" will tell me, but that gripes about too much other
891 stuff. Could I have a "gcc -Wnewline-in-string" option, or
892 better yet a "gcc -fno-newline-in-string" option, please? Gcc is
893 also inconsistent between string literals and character constants:
894 you may not embed newlines in character constants; try it, you get
895 a useful diagnostic. --PMiller */
909 /* Unknown escape sequences really should be an error, but just
910 ignore them, and let the real compiler complain. */
925 /* The \e escape is preculiar to gcc, and assumes an ASCII
926 character set (or superset). We don't provide support for it
949 case '0': case '1': case '2': case '3': case '4':
950 case '5': case '6': case '7': case '8': case '9':
951 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
952 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
964 case '0': case '1': case '2': case '3': case '4':
965 case '5': case '6': case '7': case '8': case '9':
966 n = n * 16 + c - '0';
969 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
970 n = n * 16 + 10 + c - 'A';
973 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
974 n = n * 16 + 10 + c - 'a';
981 case '0': case '1': case '2': case '3':
982 case '4': case '5': case '6': case '7':
984 for (j = 0; j < 3; ++j)
993 case '0': case '1': case '2': case '3':
994 case '4': case '5': case '6': case '7':
1006 phase7_ungetc (int c)
1012 /* Free the memory pointed to by a 'struct token_ty'. */
1014 free_token (token_ty *tp)
1016 if (tp->type == token_type_name || tp->type == token_type_string_literal)
1018 if (tp->type == token_type_string_literal
1019 || tp->type == token_type_objc_special)
1020 drop_reference (tp->comment);
1024 /* 5. Parse each resulting logical line as preprocessing tokens and
1025 white space. Preprocessing tokens and C tokens don't always match. */
1027 static token_ty phase5_pushback[1];
1028 static int phase5_pushback_length;
1032 phase5_get (token_ty *tp)
1034 static char *buffer;
1039 if (phase5_pushback_length)
1041 *tp = phase5_pushback[--phase5_pushback_length];
1046 tp->line_number = line_number;
1051 tp->type = token_type_eof;
1055 tp->type = token_type_eoln;
1077 tp->type = token_type_white_space;
1080 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G':
1081 case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
1082 case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U':
1083 case 'V': case 'W': case 'X': case 'Y': case 'Z':
1085 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
1086 case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
1087 case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u':
1088 case 'v': case 'w': case 'x': case 'y': case 'z':
1092 if (bufpos >= bufmax)
1094 bufmax = 2 * bufmax + 10;
1095 buffer = xrealloc (buffer, bufmax);
1097 buffer[bufpos++] = c;
1101 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
1102 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
1103 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
1104 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
1107 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
1108 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1109 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
1110 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
1112 case '0': case '1': case '2': case '3': case '4':
1113 case '5': case '6': case '7': case '8': case '9':
1122 if (bufpos >= bufmax)
1124 bufmax = 2 * bufmax + 10;
1125 buffer = xrealloc (buffer, bufmax);
1128 tp->string = xstrdup (buffer);
1129 tp->type = token_type_name;
1138 tp->type = token_type_symbol;
1141 case '0': case '1': case '2': case '3': case '4':
1142 case '5': case '6': case '7': case '8': case '9':
1148 case '0': case '1': case '2': case '3': case '4':
1149 case '5': case '6': case '7': case '8': case '9':
1150 /* The preprocessing number token is more "generous" than the C
1151 number tokens. This is mostly due to token pasting (another
1152 thing we can ignore here). */
1156 if (bufpos >= bufmax)
1158 bufmax = 2 * bufmax + 10;
1159 buffer = xrealloc (buffer, bufmax);
1161 buffer[bufpos++] = c;
1167 if (bufpos >= bufmax)
1169 bufmax = 2 * bufmax + 10;
1170 buffer = xrealloc (buffer, bufmax);
1172 buffer[bufpos++] = c;
1174 if (c != '+' && c != '-')
1181 case 'A': case 'B': case 'C': case 'D': case 'F':
1182 case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
1183 case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
1184 case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
1186 case 'a': case 'b': case 'c': case 'd': case 'f':
1187 case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
1188 case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
1189 case 's': case 't': case 'u': case 'v': case 'w': case 'x':
1191 case '0': case '1': case '2': case '3': case '4':
1192 case '5': case '6': case '7': case '8': case '9':
1202 if (bufpos >= bufmax)
1204 bufmax = 2 * bufmax + 10;
1205 buffer = xrealloc (buffer, bufmax);
1208 tp->type = token_type_number;
1209 tp->number = atol (buffer);
1213 /* We could worry about the 'L' before wide character constants,
1214 but ignoring it has no effect unless one of the keywords is
1215 "L". Just pretend it won't happen. Also, we don't need to
1216 remember the character constant. */
1220 if (c == P7_NEWLINE)
1222 error_with_progname = false;
1223 error (0, 0, _("%s:%d: warning: unterminated character constant"),
1224 logical_file_name, line_number - 1);
1225 error_with_progname = true;
1226 phase7_ungetc ('\n');
1229 if (c == EOF || c == P7_QUOTE)
1232 tp->type = token_type_character_constant;
1236 /* We could worry about the 'L' before wide string constants,
1237 but since gettext's argument is not a wide character string,
1238 let the compiler complain about the argument not matching the
1239 prototype. Just pretend it won't happen. */
1244 if (c == P7_NEWLINE)
1246 error_with_progname = false;
1247 error (0, 0, _("%s:%d: warning: unterminated string literal"),
1248 logical_file_name, line_number - 1);
1249 error_with_progname = true;
1250 phase7_ungetc ('\n');
1253 if (c == EOF || c == P7_QUOTES)
1257 if (bufpos >= bufmax)
1259 bufmax = 2 * bufmax + 10;
1260 buffer = xrealloc (buffer, bufmax);
1262 buffer[bufpos++] = c;
1264 if (bufpos >= bufmax)
1266 bufmax = 2 * bufmax + 10;
1267 buffer = xrealloc (buffer, bufmax);
1270 tp->type = token_type_string_literal;
1271 tp->string = xstrdup (buffer);
1272 tp->comment = add_reference (savable_comment);
1276 tp->type = token_type_lparen;
1280 tp->type = token_type_rparen;
1284 tp->type = token_type_comma;
1288 tp->type = token_type_hash;
1292 tp->type = token_type_colon;
1296 if (objc_extensions)
1298 tp->type = token_type_objc_special;
1299 tp->comment = add_reference (savable_comment);
1305 /* We could carefully recognize each of the 2 and 3 character
1306 operators, but it is not necessary, as we only need to recognize
1307 gettext invocations. Don't bother. */
1308 tp->type = token_type_symbol;
1314 /* Supports only one pushback token. */
1316 phase5_unget (token_ty *tp)
1318 if (tp->type != token_type_eof)
1320 if (phase5_pushback_length == SIZEOF (phase5_pushback))
1322 phase5_pushback[phase5_pushback_length++] = *tp;
1327 /* X. Recognize a leading # symbol. Leave leading hash as a hash, but
1328 turn hash in the middle of a line into a plain symbol token. This
1329 makes the phase 6 easier. */
1332 phaseX_get (token_ty *tp)
1334 static bool middle; /* false at the beginning of a line, true otherwise. */
1338 if (tp->type == token_type_eoln || tp->type == token_type_eof)
1344 /* Turn hash in the middle of a line into a plain symbol token. */
1345 if (tp->type == token_type_hash)
1346 tp->type = token_type_symbol;
1350 /* When we see leading whitespace followed by a hash sign,
1351 discard the leading white space token. The hash is all
1352 phase 6 is interested in. */
1353 if (tp->type == token_type_white_space)
1358 if (next.type == token_type_hash)
1361 phase5_unget (&next);
1369 /* 6. Recognize and carry out directives (it also expands macros on
1370 non-directive lines, which we do not do here). The only directive
1371 we care about are the #line and #define directive. We throw all the
1374 static token_ty phase6_pushback[2];
1375 static int phase6_pushback_length;
1379 phase6_get (token_ty *tp)
1381 static token_ty *buf;
1386 if (phase6_pushback_length)
1388 *tp = phase6_pushback[--phase6_pushback_length];
1393 /* Get the next token. If it is not a '#' at the beginning of a
1394 line (ignoring whitespace), return immediately. */
1396 if (tp->type != token_type_hash)
1399 /* Accumulate the rest of the directive in a buffer, until the
1400 "define" keyword is seen or until end of line. */
1405 if (tp->type == token_type_eoln || tp->type == token_type_eof)
1408 /* Before the "define" keyword and inside other directives
1409 white space is irrelevant. So just throw it away. */
1410 if (tp->type != token_type_white_space)
1412 /* If it is a #define directive, return immediately,
1413 thus treating the body of the #define directive like
1416 && tp->type == token_type_name
1417 && strcmp (tp->string, "define") == 0)
1421 if (bufpos >= bufmax)
1423 bufmax = 2 * bufmax + 10;
1424 buf = xrealloc (buf, bufmax * sizeof (buf[0]));
1426 buf[bufpos++] = *tp;
1430 /* If it is a #line directive, with no macros to expand, act on
1431 it. Ignore all other directives. */
1432 if (bufpos >= 3 && buf[0].type == token_type_name
1433 && strcmp (buf[0].string, "line") == 0
1434 && buf[1].type == token_type_number
1435 && buf[2].type == token_type_string_literal)
1437 logical_file_name = xstrdup (buf[2].string);
1438 line_number = buf[1].number;
1440 if (bufpos >= 2 && buf[0].type == token_type_number
1441 && buf[1].type == token_type_string_literal)
1443 logical_file_name = xstrdup (buf[1].string);
1444 line_number = buf[0].number;
1447 /* Release the storage held by the directive. */
1448 for (j = 0; j < bufpos; ++j)
1449 free_token (&buf[j]);
1451 /* We must reset the selected comments. */
1452 savable_comment_reset ();
1457 /* Supports 2 tokens of pushback. */
1459 phase6_unget (token_ty *tp)
1461 if (tp->type != token_type_eof)
1463 if (phase6_pushback_length == SIZEOF (phase6_pushback))
1465 phase6_pushback[phase6_pushback_length++] = *tp;
1470 /* 8a. Convert ISO C 99 section 7.8.1 format string directives to string
1471 literal placeholders. */
1473 /* Test for an ISO C 99 section 7.8.1 format string directive. */
1475 is_inttypes_macro (const char *name)
1478 P R I { d | i | o | u | x | X }
1479 { { | LEAST | FAST } { 8 | 16 | 32 | 64 } | MAX | PTR } */
1480 if (name[0] == 'P' && name[1] == 'R' && name[2] == 'I')
1483 if (name[0] == 'd' || name[0] == 'i' || name[0] == 'o' || name[0] == 'u'
1484 || name[0] == 'x' || name[0] == 'X')
1487 if (name[0] == 'M' && name[1] == 'A' && name[2] == 'X'
1490 if (name[0] == 'P' && name[1] == 'T' && name[2] == 'R'
1493 if (name[0] == 'L' && name[1] == 'E' && name[2] == 'A'
1494 && name[3] == 'S' && name[4] == 'T')
1496 else if (name[0] == 'F' && name[1] == 'A' && name[2] == 'S'
1499 if (name[0] == '8' && name[1] == '\0')
1501 if (name[0] == '1' && name[1] == '6' && name[2] == '\0')
1503 if (name[0] == '3' && name[1] == '2' && name[2] == '\0')
1505 if (name[0] == '6' && name[1] == '4' && name[2] == '\0')
1513 phase8a_get (token_ty *tp)
1516 if (tp->type == token_type_name && is_inttypes_macro (tp->string))
1518 /* Turn PRIdXXX into "<PRIdXXX>". */
1519 char *new_string = xasprintf ("<%s>", tp->string);
1521 tp->string = new_string;
1522 tp->comment = add_reference (savable_comment);
1523 tp->type = token_type_string_literal;
1527 /* Supports 2 tokens of pushback. */
1529 phase8a_unget (token_ty *tp)
1535 /* 8b. Drop whitespace. */
1537 phase8b_get (token_ty *tp)
1543 if (tp->type == token_type_white_space)
1545 if (tp->type == token_type_eoln)
1547 /* We have to track the last occurrence of a string. One
1548 mode of xgettext allows to group an extracted message
1549 with a comment for documentation. The rule which states
1550 which comment is assumed to be grouped with the message
1551 says it should immediately precede it. Our
1552 interpretation: between the last line of the comment and
1553 the line in which the keyword is found must be no line
1554 with non-white space tokens. */
1556 if (last_non_comment_line > last_comment_line)
1557 savable_comment_reset ();
1564 /* Supports 2 tokens of pushback. */
1566 phase8b_unget (token_ty *tp)
1572 /* 8c. In ObjectiveC mode, drop '@' before a literal string. We need to
1573 do this before performing concatenation of adjacent string literals. */
1575 phase8c_get (token_ty *tp)
1580 if (tp->type != token_type_objc_special)
1583 if (tmp.type != token_type_string_literal)
1585 phase8b_unget (&tmp);
1588 /* Drop the '@' token and return immediately the following string. */
1589 drop_reference (tmp.comment);
1590 tmp.comment = tp->comment;
1594 /* Supports only one pushback token. */
1596 phase8c_unget (token_ty *tp)
1602 /* 8. Concatenate adjacent string literals to form single string
1603 literals (because we don't expand macros, there are a few things we
1607 phase8_get (token_ty *tp)
1610 if (tp->type != token_type_string_literal)
1618 if (tmp.type != token_type_string_literal)
1620 phase8c_unget (&tmp);
1623 len = strlen (tp->string);
1624 tp->string = xrealloc (tp->string, len + strlen (tmp.string) + 1);
1625 strcpy (tp->string + len, tmp.string);
1631 /* ===================== Reading of high-level tokens. ==================== */
1634 enum xgettext_token_type_ty
1636 xgettext_token_type_eof,
1637 xgettext_token_type_keyword,
1638 xgettext_token_type_symbol,
1639 xgettext_token_type_lparen,
1640 xgettext_token_type_rparen,
1641 xgettext_token_type_comma,
1642 xgettext_token_type_colon,
1643 xgettext_token_type_string_literal,
1644 xgettext_token_type_other
1646 typedef enum xgettext_token_type_ty xgettext_token_type_ty;
1648 typedef struct xgettext_token_ty xgettext_token_ty;
1649 struct xgettext_token_ty
1651 xgettext_token_type_ty type;
1653 /* This field is used only for xgettext_token_type_keyword. */
1654 const struct callshapes *shapes;
1656 /* This field is used only for xgettext_token_type_string_literal,
1657 xgettext_token_type_keyword, xgettext_token_type_symbol. */
1660 /* This field is used only for xgettext_token_type_string_literal. */
1661 refcounted_string_list_ty *comment;
1663 /* These fields are only for
1664 xgettext_token_type_keyword,
1665 xgettext_token_type_string_literal. */
1670 /* 9. Convert the remaining preprocessing tokens to C tokens and
1671 discards any white space from the translation unit. */
1674 x_c_lex (xgettext_token_ty *tp)
1679 void *keyword_value;
1681 phase8_get (&token);
1684 case token_type_eof:
1685 tp->type = xgettext_token_type_eof;
1688 case token_type_name:
1689 last_non_comment_line = newline_count;
1691 if (hash_find_entry (objc_extensions ? &objc_keywords : &c_keywords,
1692 token.string, strlen (token.string),
1696 tp->type = xgettext_token_type_keyword;
1697 tp->shapes = (const struct callshapes *) keyword_value;
1698 tp->pos.file_name = logical_file_name;
1699 tp->pos.line_number = token.line_number;
1702 tp->type = xgettext_token_type_symbol;
1703 tp->string = token.string;
1706 case token_type_lparen:
1707 last_non_comment_line = newline_count;
1709 tp->type = xgettext_token_type_lparen;
1712 case token_type_rparen:
1713 last_non_comment_line = newline_count;
1715 tp->type = xgettext_token_type_rparen;
1718 case token_type_comma:
1719 last_non_comment_line = newline_count;
1721 tp->type = xgettext_token_type_comma;
1724 case token_type_colon:
1725 last_non_comment_line = newline_count;
1727 tp->type = xgettext_token_type_colon;
1730 case token_type_string_literal:
1731 last_non_comment_line = newline_count;
1733 tp->type = xgettext_token_type_string_literal;
1734 tp->string = token.string;
1735 tp->comment = token.comment;
1736 tp->pos.file_name = logical_file_name;
1737 tp->pos.line_number = token.line_number;
1740 case token_type_objc_special:
1741 drop_reference (token.comment);
1745 last_non_comment_line = newline_count;
1747 tp->type = xgettext_token_type_other;
1754 /* ========================= Extracting strings. ========================== */
1757 /* Context lookup table. */
1758 static flag_context_list_table_ty *flag_context_list_table;
1761 /* The file is broken into tokens. Scan the token stream, looking for
1762 a keyword, followed by a left paren, followed by a string. When we
1763 see this sequence, we have something to remember. We assume we are
1764 looking at a valid C or C++ program, and leave the complaints about
1765 the grammar to the compiler.
1767 Normal handling: Look for
1768 keyword ( ... msgid ... )
1769 Plural handling: Look for
1770 keyword ( ... msgid ... msgid_plural ... )
1772 We use recursion because the arguments before msgid or between msgid
1773 and msgid_plural can contain subexpressions of the same form. */
1776 /* Extract messages until the next balanced closing parenthesis.
1777 Extracted messages are added to MLP.
1778 Return true upon eof, false upon closing parenthesis. */
1780 extract_parenthesized (message_list_ty *mlp,
1781 flag_context_ty outer_context,
1782 flag_context_list_iterator_ty context_iter,
1783 struct arglist_parser *argparser)
1785 /* Current argument number. */
1787 /* 0 when no keyword has been seen. 1 right after a keyword is seen. */
1789 /* Parameters of the keyword just seen. Defined only in state 1. */
1790 const struct callshapes *next_shapes = NULL;
1791 /* Context iterator that will be used if the next token is a '('. */
1792 flag_context_list_iterator_ty next_context_iter =
1793 passthrough_context_list_iterator;
1794 /* Context iterator that will be used if the next token is a ':'.
1795 (Objective C selector syntax.) */
1796 flag_context_list_iterator_ty selectorcall_context_iter =
1797 passthrough_context_list_iterator;
1798 /* Current context. */
1799 flag_context_ty inner_context =
1800 inherited_context (outer_context,
1801 flag_context_list_iterator_advance (&context_iter));
1803 /* Start state is 0. */
1808 xgettext_token_ty token;
1813 case xgettext_token_type_keyword:
1814 next_shapes = token.shapes;
1816 goto keyword_or_symbol;
1818 case xgettext_token_type_symbol:
1822 flag_context_list_iterator (
1823 flag_context_list_table_lookup (
1824 flag_context_list_table,
1825 token.string, strlen (token.string)));
1826 if (objc_extensions)
1828 size_t token_string_len = strlen (token.string);
1829 token.string = xrealloc (token.string, token_string_len + 2);
1830 token.string[token_string_len] = ':';
1831 token.string[token_string_len + 1] = '\0';
1832 selectorcall_context_iter =
1833 flag_context_list_iterator (
1834 flag_context_list_table_lookup (
1835 flag_context_list_table,
1836 token.string, token_string_len + 1));
1838 free (token.string);
1841 case xgettext_token_type_lparen:
1842 if (extract_parenthesized (mlp, inner_context, next_context_iter,
1843 arglist_parser_alloc (mlp,
1844 state ? next_shapes : NULL)))
1846 arglist_parser_done (argparser, arg);
1849 next_context_iter = null_context_list_iterator;
1850 selectorcall_context_iter = null_context_list_iterator;
1854 case xgettext_token_type_rparen:
1855 arglist_parser_done (argparser, arg);
1858 case xgettext_token_type_comma:
1861 inherited_context (outer_context,
1862 flag_context_list_iterator_advance (
1864 next_context_iter = passthrough_context_list_iterator;
1865 selectorcall_context_iter = passthrough_context_list_iterator;
1869 case xgettext_token_type_colon:
1870 if (objc_extensions)
1872 context_iter = selectorcall_context_iter;
1874 inherited_context (inner_context,
1875 flag_context_list_iterator_advance (
1877 next_context_iter = passthrough_context_list_iterator;
1878 selectorcall_context_iter = passthrough_context_list_iterator;
1882 next_context_iter = null_context_list_iterator;
1883 selectorcall_context_iter = null_context_list_iterator;
1888 case xgettext_token_type_string_literal:
1890 remember_a_message (mlp, NULL, token.string, inner_context,
1891 &token.pos, NULL, token.comment);
1893 arglist_parser_remember (argparser, arg, token.string,
1895 token.pos.file_name, token.pos.line_number,
1897 drop_reference (token.comment);
1898 next_context_iter = null_context_list_iterator;
1899 selectorcall_context_iter = null_context_list_iterator;
1903 case xgettext_token_type_other:
1904 next_context_iter = null_context_list_iterator;
1905 selectorcall_context_iter = null_context_list_iterator;
1909 case xgettext_token_type_eof:
1910 arglist_parser_done (argparser, arg);
1921 extract_whole_file (FILE *f,
1922 const char *real_filename, const char *logical_filename,
1923 flag_context_list_table_ty *flag_table,
1924 msgdomain_list_ty *mdlp)
1926 message_list_ty *mlp = mdlp->item[0]->messages;
1929 real_file_name = real_filename;
1930 logical_file_name = xstrdup (logical_filename);
1934 last_comment_line = -1;
1935 last_non_comment_line = -1;
1937 flag_context_list_table = flag_table;
1941 /* Eat tokens until eof is seen. When extract_parenthesized returns
1942 due to an unbalanced closing parenthesis, just restart it. */
1943 while (!extract_parenthesized (mlp, null_context, null_context_list_iterator,
1944 arglist_parser_alloc (mlp, NULL)))
1947 /* Close scanner. */
1949 real_file_name = NULL;
1950 logical_file_name = NULL;
1957 const char *real_filename, const char *logical_filename,
1958 flag_context_list_table_ty *flag_table,
1959 msgdomain_list_ty *mdlp)
1961 objc_extensions = false;
1962 extract_whole_file (f, real_filename, logical_filename, flag_table, mdlp);
1966 extract_objc (FILE *f,
1967 const char *real_filename, const char *logical_filename,
1968 flag_context_list_table_ty *flag_table,
1969 msgdomain_list_ty *mdlp)
1971 objc_extensions = true;
1972 extract_whole_file (f, real_filename, logical_filename, flag_table, mdlp);