From: Bruno Haible Date: Mon, 22 Oct 2001 12:02:01 +0000 (+0000) Subject: Major Java scanner improvements, by Tommy Johansson. X-Git-Tag: v0.11~432 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=571ee8ea68576a20a071bc4016b75e66801be4cb;p=thirdparty%2Fgettext.git Major Java scanner improvements, by Tommy Johansson. --- diff --git a/src/ChangeLog b/src/ChangeLog index f2d024af7..37ce20a07 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,19 @@ +2001-10-04 Tommy Johansson + + * 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 * xgettext.h (omit_header): New declaration. diff --git a/src/x-java.l b/src/x-java.l index dd317e501..833bbc56d 100644 --- a/src/x-java.l +++ b/src/x-java.l @@ -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;