} 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));
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));
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
}
str = get_string (charbuf);
destroy_charbuf (charbuf);
+ strip_ending_spaces (str);
parser_global->comment = str;
return JAVA_COMMENT;
}
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
/**
* 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;
}
/**
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));
}
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 */
}
{
case JAVA_WORD:
+ if (state == STATE_KEYWORD)
+ {
+ last_state = STATE_KEYWORD;
+ argument_counter ++;
+ }
if (state == STATE_INVOCATION)
{
char *k2;
}
/* 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;
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))
case JAVA_COMMENT:
state = STATE_NONE;
+ last_state = STATE_NONE;
xgettext_comment_add (parser_global->comment);
break;