summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gettext-tools/src/ChangeLog17
-rw-r--r--gettext-tools/src/x-c.c153
-rw-r--r--gettext-tools/src/x-c.h9
-rw-r--r--gettext-tools/tests/ChangeLog5
-rw-r--r--gettext-tools/tests/Makefile.am2
-rwxr-xr-xgettext-tools/tests/xgettext-3265
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