From 7e6af1532b29c06da3f527e1dba84e7284d8a42f Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Mon, 30 Apr 2007 14:08:58 +0000 Subject: Better handling of strings in the WPS parser by detecting duplicates to avoid having two copies of the same string in the string buffer. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13295 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/wps_debug.c | 10 ++++++++-- apps/gui/wps_parser.c | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 15 deletions(-) (limited to 'apps') diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c index 335c994881..a5f0e2128d 100644 --- a/apps/gui/wps_debug.c +++ b/apps/gui/wps_debug.c @@ -43,6 +43,7 @@ static void dump_wps_tokens(struct wps_data *data) int indent = 0; char buf[64]; bool next; + int num_string_tokens = 0; if (data->num_tokens > WPS_MAX_TOKENS) { DEBUGF("Number of tokens is too high (%d)!!!\n", data->num_tokens); @@ -65,6 +66,7 @@ static void dump_wps_tokens(struct wps_data *data) case WPS_TOKEN_STRING: snprintf(buf, sizeof(buf), "String '%s'", data->strings[token->value.i]); + num_string_tokens++; break; #ifdef HAVE_LCD_BITMAP @@ -364,6 +366,9 @@ static void dump_wps_tokens(struct wps_data *data) DEBUGF("[%3d] = (%2d) %s\n", i, token->type, buf); } DEBUGF("\n"); + + DEBUGF("Number of string tokens: %d\n", num_string_tokens); + DEBUGF("\n"); } static void print_line_info(struct wps_data *data) @@ -416,7 +421,8 @@ static void print_wps_strings(struct wps_data *data) DEBUGF("%2d: (%2d) '%s'\n", i, len, data->strings[i]); } DEBUGF("\n"); - DEBUGF("Total string length: %d\n", len); + DEBUGF("Number of strings: %d out of an allowed %d\n", data->num_strings, WPS_MAX_STRINGS); + DEBUGF("Total string length: %d\n", total_len); DEBUGF("String buffer used: %d out of %d bytes\n", buf_used, STRING_BUFFER_SIZE); DEBUGF("\n"); } @@ -441,8 +447,8 @@ void print_debug_info(struct wps_data *data, int fail, int line) if (debug_wps) { dump_wps_tokens(data); - print_line_info(data); print_wps_strings(data); + print_line_info(data); #ifdef HAVE_LCD_BITMAP print_img_cond_indexes(data); #endif diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 6d8078aab9..442fd35ba0 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -653,7 +653,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) if (!data || !wps_bufptr || !*wps_bufptr) return false; - char *current_string = data->string_buffer; + char *stringbuf = data->string_buffer; int stringbuf_used = 0; int fail = 0; line = 1; @@ -770,13 +770,9 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) && stringbuf_used < STRING_BUFFER_SIZE - 1) { data->tokens[data->num_tokens].type = WPS_TOKEN_STRING; - data->strings[data->num_strings] = current_string; - data->tokens[data->num_tokens].value.i = data->num_strings; - data->num_tokens++; - /* Copy the first byte */ - *current_string++ = *(wps_bufptr - 1); - stringbuf_used++; + unsigned int len = 1; + const char *string_start = wps_bufptr - 1; /* continue until we hit something that ends the string or we run out of memory */ @@ -786,15 +782,38 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) *wps_bufptr != '|' && *wps_bufptr != '\n' && stringbuf_used < STRING_BUFFER_SIZE - 1) { - *current_string++ = *wps_bufptr++; - stringbuf_used++; + wps_bufptr++; + len++; } - /* null terminate the string */ - *current_string++ = '\0'; - stringbuf_used++; + /* look if we already have that string */ + char **str; + int i; + bool found; + for (i = 0, str = data->strings, found = false; + i < data->num_strings + && !(found = (strlen(*str) == len && strncmp(string_start, *str, len) == 0)); + i++, str++) ; + /* If a matching string is found, found is true and i is the + index of the string. If not, found is false */ + + if (!found) + { + /* new string */ + strncpy(stringbuf, string_start, len); + data->strings[data->num_strings] = stringbuf; + stringbuf += len + 1; + stringbuf_used += len + 1; + data->tokens[data->num_tokens].value.i = data->num_strings; + data->num_strings++; + } + else + { + /* another ocurrence of an existing string */ + data->tokens[data->num_tokens].value.i = i; + } - data->num_strings++; + data->num_tokens++; } break; } -- cgit v1.2.3