]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Improved ObjectiveC support.
authorBruno Haible <bruno@clisp.org>
Tue, 21 Oct 2003 10:37:08 +0000 (10:37 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:11:05 +0000 (12:11 +0200)
gettext-tools/src/ChangeLog
gettext-tools/src/x-c.c
gettext-tools/src/x-c.h
gettext-tools/tests/ChangeLog
gettext-tools/tests/Makefile.am
gettext-tools/tests/xgettext-32 [new file with mode: 0755]

index 8d8fd0320da827c16cd305fd57c5cb9be6565997..0808b490e34a29b1eecef1c07de43ccc0a218b85 100644 (file)
@@ -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.
index 434d7434f14c0abaff8ce7bf04692d8482e909f6..368cabab76c9a3f1fbab47722aeb6e99e9cc37a6 100644 (file)
@@ -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);
+}
index df6ff9a62844fd6dd4f9bdcdaa5111d0cf7278c2..90c9c42b7a0a333ffe3d32c08d05556eb4b61d7f 100644 (file)
                        &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.  */
index 444a9f74146c2c5f7745a06f7cca9828b7db19c2..2d66349e20adc6698eb20b0cae96cecfd3754edb 100644 (file)
@@ -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.
index fa7e3986dbc4f041b55cabb20406952b32a7ea5c..f960b9a80ec32c2a488e17bc1a339f0433e03085 100644 (file)
@@ -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 (executable)
index 0000000..1ea3d28
--- /dev/null
@@ -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