message_ty * message_list_search (message_list_ty *mlp, const char *msgctxt, const char *msgid) { if (mlp->use_hashtable) { char *alloced_key; const char *key; size_t keylen; if (msgctxt != NULL) { /* Concatenate the msgctxt and msgid, to form the hash table key. */ size_t msgctxt_len = strlen (msgctxt); size_t msgid_len = strlen (msgid); keylen = msgctxt_len + 1 + msgid_len + 1; alloced_key = (char *) xmalloca (keylen); memcpy (alloced_key, msgctxt, msgctxt_len); alloced_key[msgctxt_len] = MSGCTXT_SEPARATOR; memcpy (alloced_key + msgctxt_len + 1, msgid, msgid_len + 1); key = alloced_key; } else { alloced_key = NULL; key = msgid; keylen = strlen (msgid) + 1; } { void *htable_value; int found = !hash_find_entry (&mlp->htable, key, keylen, &htable_value); if (msgctxt != NULL) freea (alloced_key); if (found) return (message_ty *) htable_value; else return NULL; } } else { size_t j; for (j = 0; j < mlp->nitems; ++j) { message_ty *mp; mp = mlp->item[j]; if ((msgctxt != NULL ? mp->msgctxt != NULL && strcmp (msgctxt, mp->msgctxt) == 0 : mp->msgctxt == NULL) && strcmp (msgid, mp->msgid) == 0) return mp; } return NULL; } }
void testTortureExecute (void) { size_t nitems = 0; for (;;) { size_t list; hash_find_entry (&list); { size_t len2 = list; struct mult_index *destptr; struct mult_index *dest; size_t new_max = nitems + len2; if (new_max != len2) break; dest = foo (new_max); destptr = dest; while (len2--) destptr++; nitems = destptr - dest; } } return; }
/* Extract messages until the next balanced closing parenthesis. Extracted messages are added to MLP. Return true upon eof, false upon closing parenthesis. */ static bool extract_parenthesized (message_list_ty *mlp, flag_context_ty outer_context, flag_context_list_iterator_ty context_iter, struct arglist_parser *argparser) { /* Current argument number. */ int arg = 1; /* 0 when no keyword has been seen. 1 right after a keyword is seen. */ int state; /* Parameters of the keyword just seen. Defined only in state 1. */ const struct callshapes *next_shapes = NULL; /* Whether to implicitly assume the next tokens are arguments even without a '('. */ bool next_is_argument = false; /* Context iterator that will be used if the next token is a '('. */ flag_context_list_iterator_ty next_context_iter = passthrough_context_list_iterator; /* Current context. */ flag_context_ty inner_context = inherited_context (outer_context, flag_context_list_iterator_advance (&context_iter)); /* Start state is 0. */ state = 0; for (;;) { token_ty token; x_awk_lex (&token); if (next_is_argument && token.type != token_type_lparen) { /* An argument list starts, even though there is no '('. */ context_iter = next_context_iter; outer_context = inner_context; inner_context = inherited_context (outer_context, flag_context_list_iterator_advance ( &context_iter)); } switch (token.type) { case token_type_symbol: { void *keyword_value; if (hash_find_entry (&keywords, token.string, strlen (token.string), &keyword_value) == 0) { next_shapes = (const struct callshapes *) keyword_value; state = 1; } else state = 0; } next_is_argument = (strcmp (token.string, "print") == 0 || strcmp (token.string, "printf") == 0); next_context_iter = flag_context_list_iterator ( flag_context_list_table_lookup ( flag_context_list_table, token.string, strlen (token.string))); free (token.string); continue; case token_type_lparen: if (extract_parenthesized (mlp, inner_context, next_context_iter, arglist_parser_alloc (mlp, state ? next_shapes : NULL))) { arglist_parser_done (argparser, arg); return true; } next_is_argument = false; next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_rparen: arglist_parser_done (argparser, arg); return false; case token_type_comma: arg++; inner_context = inherited_context (outer_context, flag_context_list_iterator_advance ( &context_iter)); next_is_argument = false; next_context_iter = passthrough_context_list_iterator; state = 0; continue; case token_type_string: { lex_pos_ty pos; pos.file_name = logical_file_name; pos.line_number = token.line_number; if (extract_all) remember_a_message (mlp, NULL, token.string, inner_context, &pos, NULL, savable_comment); else arglist_parser_remember (argparser, arg, token.string, inner_context, pos.file_name, pos.line_number, savable_comment); } next_is_argument = false; next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_i18nstring: { lex_pos_ty pos; pos.file_name = logical_file_name; pos.line_number = token.line_number; remember_a_message (mlp, NULL, token.string, inner_context, &pos, NULL, savable_comment); } next_is_argument = false; next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_semicolon: /* An argument list ends, and a new statement begins. */ /* FIXME: Should handle newline that acts as statement separator in the same way. */ /* FIXME: Instead of resetting outer_context here, it may be better to recurse in the next_is_argument handling above, waiting for the next semicolon or other statement terminator. */ outer_context = null_context; context_iter = null_context_list_iterator; next_is_argument = false; next_context_iter = passthrough_context_list_iterator; inner_context = inherited_context (outer_context, flag_context_list_iterator_advance ( &context_iter)); state = 0; continue; case token_type_eof: arglist_parser_done (argparser, arg); return true; case token_type_other: next_is_argument = false; next_context_iter = null_context_list_iterator; state = 0; continue; default: abort (); } } }
/* Extract messages until the next balanced closing parenthesis or bracket. Extracted messages are added to MLP. DELIM can be either token_type_rparen or token_type_rbracket, or token_type_eof to accept both. Return true upon eof, false upon closing parenthesis. */ static bool extract_balanced (message_list_ty *mlp, token_type_ty delim, flag_context_ty outer_context, flag_context_list_iterator_ty context_iter, struct arglist_parser *argparser) { /* Current argument number. */ int arg = 1; /* 0 when no keyword has been seen. 1 right after a keyword is seen. */ int state; /* Parameters of the keyword just seen. Defined only in state 1. */ const struct callshapes *next_shapes = NULL; /* Context iterator that will be used if the next token is a '('. */ flag_context_list_iterator_ty next_context_iter = passthrough_context_list_iterator; /* Current context. */ flag_context_ty inner_context = inherited_context (outer_context, flag_context_list_iterator_advance (&context_iter)); /* Start state is 0. */ state = 0; for (;;) { token_ty token; x_php_lex (&token); switch (token.type) { case token_type_symbol: { void *keyword_value; if (hash_find_entry (&keywords, token.string, strlen (token.string), &keyword_value) == 0) { next_shapes = (const struct callshapes *) keyword_value; state = 1; } else state = 0; } next_context_iter = flag_context_list_iterator ( flag_context_list_table_lookup ( flag_context_list_table, token.string, strlen (token.string))); free (token.string); continue; case token_type_lparen: if (extract_balanced (mlp, token_type_rparen, inner_context, next_context_iter, arglist_parser_alloc (mlp, state ? next_shapes : NULL))) { arglist_parser_done (argparser, arg); return true; } next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_rparen: if (delim == token_type_rparen || delim == token_type_eof) { arglist_parser_done (argparser, arg); return false; } next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_comma: arg++; inner_context = inherited_context (outer_context, flag_context_list_iterator_advance ( &context_iter)); next_context_iter = passthrough_context_list_iterator; state = 0; continue; case token_type_lbracket: if (extract_balanced (mlp, token_type_rbracket, null_context, null_context_list_iterator, arglist_parser_alloc (mlp, NULL))) { arglist_parser_done (argparser, arg); return true; } case token_type_rbracket: if (delim == token_type_rbracket || delim == token_type_eof) { arglist_parser_done (argparser, arg); return false; } next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_string_literal: { lex_pos_ty pos; pos.file_name = logical_file_name; pos.line_number = token.line_number; if (extract_all) remember_a_message (mlp, NULL, token.string, inner_context, &pos, token.comment); else arglist_parser_remember (argparser, arg, token.string, inner_context, pos.file_name, pos.line_number, token.comment); drop_reference (token.comment); } next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_dot: case token_type_operator1: case token_type_operator2: case token_type_other: next_context_iter = null_context_list_iterator; state = 0; continue; case token_type_eof: arglist_parser_done (argparser, arg); return true; default: abort (); } } }