]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Major Java scanner improvements, by Tommy Johansson.
authorBruno Haible <bruno@clisp.org>
Mon, 22 Oct 2001 12:02:01 +0000 (12:02 +0000)
committerBruno Haible <bruno@clisp.org>
Mon, 22 Oct 2001 12:02:01 +0000 (12:02 +0000)
src/ChangeLog
src/x-java.l

index f2d024af721bfeb7ecf5f55e9d64e7ff2d60b63d..37ce20a079b01c2834055dd15a767236a9e3a636 100644 (file)
@@ -1,3 +1,19 @@
+2001-10-04  Tommy Johansson  <tommy.johansson@kanalen.org>
+
+       * x-java.l (object_list): New type.
+       (INITIAL_OBJECT_LIST_SIZE, OBJECT_LIST_GROWTH): New macros.
+       (java_keyword): New type.
+       (strip_ending_spaces): New function.
+       (object_list_alloc, object_list_destroy, get_num_objects, get_object,
+       add_object, alloc_keyword): New functions.
+       (java_keywords): Change type.
+       (extract_keyword, extract_msgid_arg, extract_msgid_plural_arg): New
+       functions.
+       (is_keyword): Change return type.
+       (x_java_keyword): Update.
+       (extract_java): Count arguments, and support plural keywords like
+       ngettext.
+
 2001-09-19  Bruno Haible  <haible@clisp.cons.org>
 
        * xgettext.h (omit_header): New declaration.
index dd317e501791ad7c6951b9fe28ab9e27b833863d..833bbc56db4c9a0d6592909a23c78dd3d3132d65 100644 (file)
@@ -72,6 +72,24 @@ typedef struct
 } char_buf;
 
 
+typedef struct _object_list
+{
+  int num_obj;
+  int max_num_obj;
+  void **objects;
+} object_list;
+
+#define INITIAL_OBJECT_LIST_SIZE 10
+#define OBJECT_LIST_GROWTH 10
+
+typedef struct _java_keyword
+{
+  char *keyword;
+  int msgid_arg;
+  int msgid_plural_arg;
+} java_keyword;
+
+
 /* Prototypes for local functions.  Needed to ensure compiler checking of
    function argument counts despite of K&R C function definition syntax.  */
 static char_buf *create_char_buf PARAMS ((void));
@@ -84,7 +102,7 @@ static inline bool isplus PARAMS ((char *s));
 static inline bool isdot PARAMS ((char *s));
 static char *translate_esc PARAMS ((char *s));
 static bool do_compare PARAMS ((const char *s1, const char *s2));
-static bool is_keyword PARAMS ((const char *s));
+static java_keyword *is_keyword PARAMS ((const char *s));
 static void free_global PARAMS ((void));
 
 
@@ -138,6 +156,16 @@ update_line_no (c)
     parser_global->line_no++;
 }
 
+static void
+strip_ending_spaces (str)
+     char *str;
+{
+  int len = strlen (str);
+
+  while (isspace (str[len--]))
+    ;
+  str[len] = '\0';
+}
 %}
 
 %option noyywrap
@@ -165,6 +193,7 @@ ID [a-zA-Z_][a-zA-Z0-9_]*
     }
   str = get_string (charbuf);
   destroy_charbuf (charbuf);
+  strip_ending_spaces (str);
   parser_global->comment = str;
   return JAVA_COMMENT;
 }
@@ -264,18 +293,142 @@ translate_esc (s)
   return n;
 }
 
+static object_list *
+object_list_alloc ()
+{
+  object_list *list = xmalloc (sizeof (object_list));
+  list->max_num_obj = INITIAL_OBJECT_LIST_SIZE;
+  list->num_obj = 0;
+  list->objects = xmalloc (sizeof (void *) * INITIAL_OBJECT_LIST_SIZE);
+  return list;
+}
+
+static void *
+object_list_destroy (list)
+     object_list *list;
+{
+  free (list->objects);
+  free (list);
+}
+
+static int
+get_num_objects (list)
+     const object_list *list;
+{
+  return list->num_obj;
+}
+
+static void *
+get_object (list, i)
+     const object_list *list;
+     int i;
+{
+  return list->objects[i];
+}
+
+static void
+add_object (list, object)
+     object_list *list;
+     void *object;
+{
+  if (list->num_obj + 1 >= list->max_num_obj)
+    {
+      // resize
+      list->max_num_obj += OBJECT_LIST_GROWTH;
+      list->objects =
+       xrealloc (list->objects, list->max_num_obj * sizeof (void *));
+    }
+  list->objects[list->num_obj ++] = object;
+}
+
 
 /* options */
 static bool extract_all_strings = false;
 
 void
-x_java_extract_all () 
+x_java_extract_all ()
 {
   extract_all_strings = true;
 }
 
 
-static string_list_ty *java_keywords = NULL;
+
+static java_keyword *
+alloc_keyword (keyword, arg1, arg2)
+     const char *keyword;
+     int arg1;
+     int arg2;
+{
+  java_keyword *jk = xmalloc (sizeof (java_keyword));
+  jk->keyword = xstrdup (keyword);
+  jk->msgid_arg = arg1;
+  jk->msgid_plural_arg = arg2;
+  return jk;
+}
+
+static object_list *java_keywords = NULL;
+
+
+/**
+ * Extract the keyword from a keyword indata string.
+ */
+static char *
+extract_keyword (key)
+     const char *key;
+{
+  char *s = strchr (key, ':');
+  char *new_string;
+
+  new_string = xstrdup (key);
+  if (s != NULL)
+    new_string[s - key] = '\0';
+  return new_string;
+}
+
+/**
+ * Extract the msgid arg number from a keyword indata string.
+ */
+static int
+extract_msgid_arg (key)
+     const char *key;
+{
+  char *s = strchr (key, ':');
+  int arg;
+
+  if (s != NULL)
+    {
+      s ++;
+      arg = strtol (s, &s, 10);
+    }
+  else
+    {
+      arg = 1;
+    }
+  return arg;
+}
+
+/**
+ * Extract the msgid plural arg number from a keyword indata string,
+ * if any.
+ */
+static int
+extract_msgid_plural_arg (key)
+     const char *key;
+{
+  char *s = strchr (key, ',');
+  int arg;
+  if (s != NULL)
+    {
+      s ++;
+      arg = strtol (s, &s, 10);
+    }
+  else
+    {
+      arg = 0;
+    }
+  return arg;
+}
+
 
 /**
  * Try to match a string against the keyword. If substring_match is
@@ -295,16 +448,23 @@ do_compare (s1, s2)
 /**
  * Check if a string is a keyword or not.
  */
-static bool
+static java_keyword *
 is_keyword (s)
      const char *s;
 {
   int i;
+  int num_keywords = get_num_objects (java_keywords);
+  java_keyword *kw;
+
+  bool match;
+  for (i = 0; i < num_keywords; i++)
+    {
+      kw = (java_keyword *) get_object (java_keywords, i);
 
-  for (i = 0; i < java_keywords->nitems; i++)
-    if (do_compare (s, java_keywords->item[i]))
-      return true;
-  return false;
+      if (do_compare (s, kw->keyword))
+       return kw;
+    }
+  return NULL;
 }
 
 /**
@@ -314,18 +474,29 @@ void
 x_java_keyword (keyword)
      const char *keyword;
 {
-  if (keyword == NULL) {
-    if (java_keywords != NULL) {
-      string_list_destroy (java_keywords);
-      java_keywords = NULL;
+  int arg1;
+  int arg2;
+  char *kw;
+
+  if (keyword == NULL)
+    {
+      if (java_keywords != NULL)
+       {
+         object_list_destroy (java_keywords);
+         java_keywords = NULL;
+       }
+      return;
     }
-    return;
-  }
 
   if (java_keywords == NULL)
-    java_keywords = string_list_alloc ();
+    {
+      java_keywords = object_list_alloc ();
+    }
 
-  string_list_append (java_keywords, keyword);
+  kw = extract_keyword (keyword);
+  arg1 = extract_msgid_arg (keyword);
+  arg2 = extract_msgid_plural_arg (keyword);
+  add_object (java_keywords, alloc_keyword (kw, arg1, arg2));
 }
 
 
@@ -368,13 +539,17 @@ extract_java (f, real_filename, logical_filename, mdlp)
   PARSER_STATE last_state = STATE_NONE;
   char *str;
   char *key;
+  message_ty *plural;
   message_list_ty *mlp = mdlp->item[0]->messages;
+  java_keyword *current_keyword = NULL;
+  java_keyword *keyword;
+  int argument_counter = 0;
 
   if (java_keywords == NULL)
     {
       /* ops, no standard keywords */
       x_java_keyword ("gettext");      /* GettextResource.gettext */
-      x_java_keyword ("ngettext");     /* GettextResource.ngettext */
+      x_java_keyword ("ngettext:1,2"); /* GettextResource.ngettext */
       x_java_keyword ("getString");    /* ResourceBundle.getString */
     }
 
@@ -390,6 +565,11 @@ extract_java (f, real_filename, logical_filename, mdlp)
        {
 
        case JAVA_WORD:
+         if (state == STATE_KEYWORD)
+           {
+             last_state = STATE_KEYWORD;
+             argument_counter ++;
+           }
          if (state == STATE_INVOCATION)
            {
              char *k2;
@@ -405,10 +585,13 @@ extract_java (f, real_filename, logical_filename, mdlp)
            }
          /* For java we try to match both things like object.methodCall()
             and methodCall(). */
-         if (is_keyword (key) || is_keyword (parser_global->word))
+         if ((keyword = is_keyword (key)) != NULL
+             || (keyword = is_keyword (parser_global->word)) != NULL)
            {
+             current_keyword = keyword;
              free (key);
              state = STATE_KEYWORD;
+             argument_counter = 1;
            }
          break;
 
@@ -451,10 +634,43 @@ extract_java (f, real_filename, logical_filename, mdlp)
              lex_pos_ty pos;
              pos.file_name = logical_file_name;
              pos.line_number = parser_global->line_no;
-             state = STATE_NONE;
-             last_state = STATE_NONE;
+             if (extract_all_strings)
+               {
+                 remember_a_message (mlp, str, &pos);
+               }
+             else if (!extract_all_strings
+                      && argument_counter == current_keyword->msgid_arg)
+               {
+                 plural = remember_a_message (mlp, str, &pos);
+                 if (current_keyword->msgid_plural_arg == 0)
+                   {
+                     /**
+                      * we don't expect any plural arg, reset state
+                      */
+                     state = STATE_NONE;
+                     last_state = STATE_NONE;
+                     argument_counter = 0;
+                   }
+                 else
+                   {
+                     argument_counter ++;
+                   }
+
+               }
+             else if (!extract_all_strings &&
+                      argument_counter == current_keyword->msgid_plural_arg)
+               {
+                 remember_a_message_plural (plural, str, &pos);
+                 state = STATE_NONE;
+                 last_state = STATE_NONE;
+                 argument_counter = 0;
+               }
+           }
 
-             remember_a_message (mlp, str, &pos);
+         if (extract_all_strings)
+           {
+               state = STATE_NONE;
+               last_state = STATE_NONE;
            }
 
          if (state == STATE_WORD && isdot (parser_global->flow))
@@ -466,6 +682,7 @@ extract_java (f, real_filename, logical_filename, mdlp)
 
        case JAVA_COMMENT:
          state = STATE_NONE;
+         last_state = STATE_NONE;
          xgettext_comment_add (parser_global->comment);
          break;