diff options
-rw-r--r-- | gettext-tools/src/ChangeLog | 17 | ||||
-rw-r--r-- | gettext-tools/src/x-c.c | 153 | ||||
-rw-r--r-- | gettext-tools/src/x-c.h | 9 | ||||
-rw-r--r-- | gettext-tools/tests/ChangeLog | 5 | ||||
-rw-r--r-- | gettext-tools/tests/Makefile.am | 2 | ||||
-rwxr-xr-x | gettext-tools/tests/xgettext-32 | 65 |
6 files changed, 209 insertions, 42 deletions
diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 8d8fd03..0808b49 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,20 @@ +2003-10-12 Bruno Haible <bruno@clisp.org> + + Improved ObjectiveC support. + * x-c.h (extract_objc): New declaration. + (SCANNERS_C): For ObjectiveC, use extract_objc. + * x-c.c (objc_extensions): New variable. + (enum token_type_ty): New item token_type_objc_special. + (phase5_get): Recognize '@' for ObjectiveC. + (phase8b_get, phase8b_unget): New functions. Handle + token_type_white_space and token_type_eoln here instead of in x_c_lex. + (phase8c_get, phase8c_unget): New functions. + (phase8_get): Rely on phase8c, not phase8a. No more need to care about + token_type_white_space and token_type_eoln. + (x_c_lex): Drop handling of token_type_white_space and token_type_eoln. + (extract_whole_file): Renamed from extract_c. + (extract_c, extract_objc): New functions. + 2003-10-20 Bruno Haible <bruno@clisp.org> * x-java.c (phase3_getc): Fix typo: Use phase2_ungetc, not phase2_getc. diff --git a/gettext-tools/src/x-c.c b/gettext-tools/src/x-c.c index 434d743..368caba 100644 --- a/gettext-tools/src/x-c.c +++ b/gettext-tools/src/x-c.c @@ -602,19 +602,23 @@ phase4_ungetc (int c) /* ========================== Reading of tokens. ========================== */ +/* True if ObjectiveC extensions are recognized. */ +static bool objc_extensions; + enum token_type_ty { - token_type_character_constant, + token_type_character_constant, /* 'x' */ token_type_eof, token_type_eoln, - token_type_hash, - token_type_lparen, - token_type_rparen, - token_type_comma, - token_type_name, - token_type_number, - token_type_string_literal, - token_type_symbol, + token_type_hash, /* # */ + token_type_lparen, /* ( */ + token_type_rparen, /* ) */ + token_type_comma, /* , */ + token_type_name, /* abc */ + token_type_number, /* 2.7 */ + token_type_string_literal, /* "abc" */ + token_type_symbol, /* < > = etc. */ + token_type_objc_special, /* @ */ token_type_white_space }; typedef enum token_type_ty token_type_ty; @@ -1057,6 +1061,14 @@ phase5_get (token_ty *tp) tp->type = token_type_hash; return; + case '@': + if (objc_extensions) + { + tp->type = token_type_objc_special; + return; + } + /* FALLTHROUGH */ + default: /* We could carefully recognize each of the 2 and 3 character operators, but it is not necessary, as we only need to recognize @@ -1275,13 +1287,76 @@ phase8a_get (token_ty *tp) } } -static void +static inline void phase8a_unget (token_ty *tp) { phase6_unget (tp); } +/* 8b. Drop whitespace. */ +static void +phase8b_get (token_ty *tp) +{ + for (;;) + { + phase8a_get (tp); + + if (tp->type == token_type_white_space) + continue; + if (tp->type == token_type_eoln) + { + /* We have to track the last occurrence of a string. One + mode of xgettext allows to group an extracted message + with a comment for documentation. The rule which states + which comment is assumed to be grouped with the message + says it should immediately precede it. Our + interpretation: between the last line of the comment and + the line in which the keyword is found must be no line + with non-white space tokens. */ + ++newline_count; + if (last_non_comment_line > last_comment_line) + xgettext_comment_reset (); + continue; + } + break; + } +} + +static inline void +phase8b_unget (token_ty *tp) +{ + phase8a_unget (tp); +} + + +/* 8c. In ObjectiveC mode, drop '@' before a literal string. We need to + do this before performing concatenation of adjacent string literals. */ +static void +phase8c_get (token_ty *tp) +{ + token_ty tmp; + + phase8b_get (tp); + if (tp->type != token_type_objc_special) + return; + phase8b_get (&tmp); + if (tmp.type != token_type_string_literal) + { + phase8b_unget (&tmp); + return; + } + /* Drop the '@' token and return immediately the following string. */ + *tp = tmp; +} + +static inline void +phase8c_unget (token_ty *tp) +{ + phase8b_unget (tp); +} + + /* 8. Concatenate adjacent string literals to form single string literals (because we don't expand macros, there are a few things we will miss). */ @@ -1289,7 +1364,7 @@ phase8a_unget (token_ty *tp) static void phase8_get (token_ty *tp) { - phase8a_get (tp); + phase8c_get (tp); if (tp->type != token_type_string_literal) return; for (;;) @@ -1297,14 +1372,10 @@ phase8_get (token_ty *tp) token_ty tmp; size_t len; - phase8a_get (&tmp); - if (tmp.type == token_type_white_space) - continue; - if (tmp.type == token_type_eoln) - continue; + phase8c_get (&tmp); if (tmp.type != token_type_string_literal) { - phase8a_unget (&tmp); + phase8c_unget (&tmp); return; } len = strlen (tp->string); @@ -1369,23 +1440,6 @@ x_c_lex (xgettext_token_ty *tp) tp->type = xgettext_token_type_eof; return; - case token_type_white_space: - break; - - case token_type_eoln: - /* We have to track the last occurrence of a string. One - mode of xgettext allows to group an extracted message - with a comment for documentation. The rule which states - which comment is assumed to be grouped with the message - says it should immediately precede it. Our - interpretation: between the last line of the comment and - the line in which the keyword is found must be no line - with non-white space tokens. */ - ++newline_count; - if (last_non_comment_line > last_comment_line) - xgettext_comment_reset (); - break; - case token_type_name: last_non_comment_line = newline_count; @@ -1605,11 +1659,11 @@ extract_parenthesized (message_list_ty *mlp, } -void -extract_c (FILE *f, - const char *real_filename, const char *logical_filename, - flag_context_list_table_ty *flag_table, - msgdomain_list_ty *mdlp) +static void +extract_whole_file (FILE *f, + const char *real_filename, const char *logical_filename, + flag_context_list_table_ty *flag_table, + msgdomain_list_ty *mdlp) { message_list_ty *mlp = mdlp->item[0]->messages; @@ -1638,3 +1692,24 @@ extract_c (FILE *f, logical_file_name = NULL; line_number = 0; } + + +void +extract_c (FILE *f, + const char *real_filename, const char *logical_filename, + flag_context_list_table_ty *flag_table, + msgdomain_list_ty *mdlp) +{ + objc_extensions = false; + extract_whole_file (f, real_filename, logical_filename, flag_table, mdlp); +} + +void +extract_objc (FILE *f, + const char *real_filename, const char *logical_filename, + flag_context_list_table_ty *flag_table, + msgdomain_list_ty *mdlp) +{ + objc_extensions = true; + extract_whole_file (f, real_filename, logical_filename, flag_table, mdlp); +} diff --git a/gettext-tools/src/x-c.h b/gettext-tools/src/x-c.h index df6ff9a..90c9c42 100644 --- a/gettext-tools/src/x-c.h +++ b/gettext-tools/src/x-c.h @@ -35,16 +35,21 @@ &flag_table_c, &formatstring_c, NULL }, \ { "C++", extract_c, \ &flag_table_c, &formatstring_c, NULL }, \ - { "ObjectiveC", extract_c, \ + { "ObjectiveC", extract_objc, \ &flag_table_c, &formatstring_c, NULL }, \ { "GCC-source", extract_c, \ &flag_table_gcc_internal, &formatstring_gcc_internal, NULL }, \ -/* Scan a C/C++/ObjectiveC file and add its translatable strings to mdlp. */ +/* Scan a C/C++ file and add its translatable strings to mdlp. */ extern void extract_c (FILE *fp, const char *real_filename, const char *logical_filename, flag_context_list_table_ty *flag_table, msgdomain_list_ty *mdlp); +/* Scan an ObjectiveC file and add its translatable strings to mdlp. */ +extern void extract_objc (FILE *fp, const char *real_filename, + const char *logical_filename, + flag_context_list_table_ty *flag_table, + msgdomain_list_ty *mdlp); /* Handling of options specific to this language. */ diff --git a/gettext-tools/tests/ChangeLog b/gettext-tools/tests/ChangeLog index 444a9f7..2d66349 100644 --- a/gettext-tools/tests/ChangeLog +++ b/gettext-tools/tests/ChangeLog @@ -1,3 +1,8 @@ +2003-10-12 Bruno Haible <bruno@clisp.org> + + * xgettext-32: New file. + * Makefile.am (TESTS): Add xgettext-32. + 2003-10-09 Bruno Haible <bruno@clisp.org> * tstgettext.c: Include xalloc.h instead of xmalloc.h. diff --git a/gettext-tools/tests/Makefile.am b/gettext-tools/tests/Makefile.am index fa7e398..f960b9a 100644 --- a/gettext-tools/tests/Makefile.am +++ b/gettext-tools/tests/Makefile.am @@ -50,7 +50,7 @@ TESTS = gettext-1 gettext-2 \ xgettext-13 xgettext-14 xgettext-15 xgettext-16 xgettext-17 \ xgettext-18 xgettext-19 xgettext-20 xgettext-21 xgettext-22 \ xgettext-23 xgettext-24 xgettext-25 xgettext-26 xgettext-27 \ - xgettext-28 xgettext-29 xgettext-30 xgettext-31 \ + xgettext-28 xgettext-29 xgettext-30 xgettext-31 xgettext-32 \ format-awk-1 format-awk-2 \ format-c-1 format-c-2 format-c-3 format-c-4 \ format-elisp-1 format-elisp-2 \ diff --git a/gettext-tools/tests/xgettext-32 b/gettext-tools/tests/xgettext-32 new file mode 100755 index 0000000..1ea3d28 --- /dev/null +++ b/gettext-tools/tests/xgettext-32 @@ -0,0 +1,65 @@ +#! /bin/sh + +# Test ObjectiveC extractor. + +tmpfiles="" +trap 'rm -fr $tmpfiles' 1 2 3 15 + +tmpfiles="$tmpfiles xg-test32.m" +cat <<\EOF > xg-test32.m +id str = _(@ +"conca" /* comment */ +@ +// another comment + "tenated"); + +_(@"foo") _ ( @"foo2" /* test */ ) + +"_()" + +" \" _(foo) \" /* comment " + +_ // test +(@ /* comment " */ "test" +@ +" test2" +) + +NSLocalizedString(@"Information", @"") +EOF + +tmpfiles="$tmpfiles xg-test32.po" +: ${XGETTEXT=xgettext} +${XGETTEXT} --omit-header -k_ -kNSLocalizedString xg-test32.m -d xg-test32 +test $? = 0 || { rm -fr $tmpfiles; exit 1; } + +tmpfiles="$tmpfiles xg-test32.ok" +cat <<\EOF > xg-test32.ok +#: xg-test32.m:2 +msgid "concatenated" +msgstr "" + +#: xg-test32.m:7 +msgid "foo" +msgstr "" + +#: xg-test32.m:7 +msgid "foo2" +msgstr "" + +#: xg-test32.m:14 +msgid "test test2" +msgstr "" + +#: xg-test32.m:19 +msgid "Information" +msgstr "" +EOF + +: ${DIFF=diff} +${DIFF} xg-test32.ok xg-test32.po +result=$? + +rm -fr $tmpfiles + +exit $result |