summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-30 14:08:58 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-30 14:08:58 +0000
commit7e6af1532b29c06da3f527e1dba84e7284d8a42f (patch)
treea00a2f912c5cba0f54969adcc4c63a0fbe08047b
parent3a7760c3e2691d0367f5c0b5585fd885b99c6693 (diff)
downloadrockbox-7e6af1532b29c06da3f527e1dba84e7284d8a42f.tar.gz
rockbox-7e6af1532b29c06da3f527e1dba84e7284d8a42f.zip
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
-rw-r--r--apps/gui/wps_debug.c10
-rw-r--r--apps/gui/wps_parser.c45
2 files changed, 40 insertions, 15 deletions
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)
43 int indent = 0; 43 int indent = 0;
44 char buf[64]; 44 char buf[64];
45 bool next; 45 bool next;
46 int num_string_tokens = 0;
46 47
47 if (data->num_tokens > WPS_MAX_TOKENS) { 48 if (data->num_tokens > WPS_MAX_TOKENS) {
48 DEBUGF("Number of tokens is too high (%d)!!!\n", data->num_tokens); 49 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)
65 case WPS_TOKEN_STRING: 66 case WPS_TOKEN_STRING:
66 snprintf(buf, sizeof(buf), "String '%s'", 67 snprintf(buf, sizeof(buf), "String '%s'",
67 data->strings[token->value.i]); 68 data->strings[token->value.i]);
69 num_string_tokens++;
68 break; 70 break;
69 71
70#ifdef HAVE_LCD_BITMAP 72#ifdef HAVE_LCD_BITMAP
@@ -364,6 +366,9 @@ static void dump_wps_tokens(struct wps_data *data)
364 DEBUGF("[%3d] = (%2d) %s\n", i, token->type, buf); 366 DEBUGF("[%3d] = (%2d) %s\n", i, token->type, buf);
365 } 367 }
366 DEBUGF("\n"); 368 DEBUGF("\n");
369
370 DEBUGF("Number of string tokens: %d\n", num_string_tokens);
371 DEBUGF("\n");
367} 372}
368 373
369static void print_line_info(struct wps_data *data) 374static void print_line_info(struct wps_data *data)
@@ -416,7 +421,8 @@ static void print_wps_strings(struct wps_data *data)
416 DEBUGF("%2d: (%2d) '%s'\n", i, len, data->strings[i]); 421 DEBUGF("%2d: (%2d) '%s'\n", i, len, data->strings[i]);
417 } 422 }
418 DEBUGF("\n"); 423 DEBUGF("\n");
419 DEBUGF("Total string length: %d\n", len); 424 DEBUGF("Number of strings: %d out of an allowed %d\n", data->num_strings, WPS_MAX_STRINGS);
425 DEBUGF("Total string length: %d\n", total_len);
420 DEBUGF("String buffer used: %d out of %d bytes\n", buf_used, STRING_BUFFER_SIZE); 426 DEBUGF("String buffer used: %d out of %d bytes\n", buf_used, STRING_BUFFER_SIZE);
421 DEBUGF("\n"); 427 DEBUGF("\n");
422} 428}
@@ -441,8 +447,8 @@ void print_debug_info(struct wps_data *data, int fail, int line)
441 if (debug_wps) 447 if (debug_wps)
442 { 448 {
443 dump_wps_tokens(data); 449 dump_wps_tokens(data);
444 print_line_info(data);
445 print_wps_strings(data); 450 print_wps_strings(data);
451 print_line_info(data);
446#ifdef HAVE_LCD_BITMAP 452#ifdef HAVE_LCD_BITMAP
447 print_img_cond_indexes(data); 453 print_img_cond_indexes(data);
448#endif 454#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)
653 if (!data || !wps_bufptr || !*wps_bufptr) 653 if (!data || !wps_bufptr || !*wps_bufptr)
654 return false; 654 return false;
655 655
656 char *current_string = data->string_buffer; 656 char *stringbuf = data->string_buffer;
657 int stringbuf_used = 0; 657 int stringbuf_used = 0;
658 int fail = 0; 658 int fail = 0;
659 line = 1; 659 line = 1;
@@ -770,13 +770,9 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
770 && stringbuf_used < STRING_BUFFER_SIZE - 1) 770 && stringbuf_used < STRING_BUFFER_SIZE - 1)
771 { 771 {
772 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING; 772 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING;
773 data->strings[data->num_strings] = current_string;
774 data->tokens[data->num_tokens].value.i = data->num_strings;
775 data->num_tokens++;
776 773
777 /* Copy the first byte */ 774 unsigned int len = 1;
778 *current_string++ = *(wps_bufptr - 1); 775 const char *string_start = wps_bufptr - 1;
779 stringbuf_used++;
780 776
781 /* continue until we hit something that ends the string 777 /* continue until we hit something that ends the string
782 or we run out of memory */ 778 or we run out of memory */
@@ -786,15 +782,38 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
786 *wps_bufptr != '|' && *wps_bufptr != '\n' && 782 *wps_bufptr != '|' && *wps_bufptr != '\n' &&
787 stringbuf_used < STRING_BUFFER_SIZE - 1) 783 stringbuf_used < STRING_BUFFER_SIZE - 1)
788 { 784 {
789 *current_string++ = *wps_bufptr++; 785 wps_bufptr++;
790 stringbuf_used++; 786 len++;
791 } 787 }
792 788
793 /* null terminate the string */ 789 /* look if we already have that string */
794 *current_string++ = '\0'; 790 char **str;
795 stringbuf_used++; 791 int i;
792 bool found;
793 for (i = 0, str = data->strings, found = false;
794 i < data->num_strings
795 && !(found = (strlen(*str) == len && strncmp(string_start, *str, len) == 0));
796 i++, str++) ;
797 /* If a matching string is found, found is true and i is the
798 index of the string. If not, found is false */
799
800 if (!found)
801 {
802 /* new string */
803 strncpy(stringbuf, string_start, len);
804 data->strings[data->num_strings] = stringbuf;
805 stringbuf += len + 1;
806 stringbuf_used += len + 1;
807 data->tokens[data->num_tokens].value.i = data->num_strings;
808 data->num_strings++;
809 }
810 else
811 {
812 /* another ocurrence of an existing string */
813 data->tokens[data->num_tokens].value.i = i;
814 }
796 815
797 data->num_strings++; 816 data->num_tokens++;
798 } 817 }
799 break; 818 break;
800 } 819 }