From e92d2c51ed455cc0a889fb6d38b4802eee252a6a Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Fri, 21 Mar 2008 13:41:35 +0000 Subject: Add a general-purpose parse_list function to parse a string containing a delimited list of items and adapt the parse_image_load() function in the WPS parser to use it. This function will also be used to parse the upcoming WPS %V viewport tag, but I'm committing it separately as these changes are unrelated to the viewport implementation itself. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16728 a1c6a512-1295-4272-9138-f99709370657 --- apps/filetypes.c | 6 +-- apps/gui/wps_parser.c | 55 ++++++++--------------- apps/misc.c | 108 +++++++++++++++++++++++++++++++++++++++++++-- apps/misc.h | 5 ++- apps/plugins/text_editor.c | 9 ++-- apps/settings.c | 2 +- 6 files changed, 137 insertions(+), 48 deletions(-) (limited to 'apps') diff --git a/apps/filetypes.c b/apps/filetypes.c index 8427bc7450..1ef136d5ce 100644 --- a/apps/filetypes.c +++ b/apps/filetypes.c @@ -164,12 +164,12 @@ void read_color_theme_file(void) { continue; if (!strcasecmp(ext, "folder")) { - custom_colors[0] = hex_to_rgb(color); + hex_to_rgb(color, &custom_colors[0]); continue; } if (!strcasecmp(ext, "???")) { - custom_colors[MAX_FILETYPES] = hex_to_rgb(color); + hex_to_rgb(color, &custom_colors[MAX_FILETYPES]); continue; } for (i=1; i newline) - return 0; + ptr++; + + if (!(ptr = parse_list("ssdd", '|', ptr, &id, &filename, &x, &y))) + return WPS_ERROR_INVALID_PARAM; + + /* Check there is a terminating | */ + if (*ptr != '|') + return WPS_ERROR_INVALID_PARAM; /* get the image ID */ - n = get_image_id(*ptr); + n = get_image_id(*id); /* check the image number and load state */ if(n < 0 || n >= MAX_IMAGES || wps_data->img[n].loaded) @@ -470,34 +476,11 @@ static int parse_image_load(const char *wps_bufptr, return WPS_ERROR_INVALID_PARAM; } - ptr = pos + 1; - - /* get image name */ - bmp_names[n] = ptr; + /* save a pointer to the filename */ + bmp_names[n] = filename; - pos = strchr(ptr, '|'); - ptr = pos + 1; - - /* get x-position */ - pos = strchr(ptr, '|'); - if (pos && pos < newline) - wps_data->img[n].x = atoi(ptr); - else - { - /* weird syntax, bail out */ - return WPS_ERROR_INVALID_PARAM; - } - - /* get y-position */ - ptr = pos + 1; - pos = strchr(ptr, '|'); - if (pos && pos < newline) - wps_data->img[n].y = atoi(ptr); - else - { - /* weird syntax, bail out */ - return WPS_ERROR_INVALID_PARAM; - } + wps_data->img[n].x = x; + wps_data->img[n].y = y; if (token->type == WPS_TOKEN_IMAGE_DISPLAY) wps_data->img[n].always_display = true; diff --git a/apps/misc.c b/apps/misc.c index 6f34e50a54..632b12b9aa 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -1098,7 +1098,7 @@ static int hex2dec(int c) (toupper(c)) - 'A' + 10); } -int hex_to_rgb(const char* hex) +int hex_to_rgb(const char* hex, int* color) { int ok = 1; int i; int red, green, blue; @@ -1115,11 +1115,12 @@ int hex_to_rgb(const char* hex) red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]); green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]); blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]); - return LCD_RGBPACK(red,green,blue); + *color = LCD_RGBPACK(red,green,blue); + return 0; } } - return 0; + return -1; } #endif /* HAVE_LCD_COLOR */ @@ -1200,3 +1201,104 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename) return buffer; } + +#ifdef HAVE_LCD_BITMAP +/* A simplified scanf - used (at time of writing) by wps parsing functions. + + fmt - char array specifying the format of each list option. Valid values + are: d - int + s - string (sets pointer to string, without copying) + c - hex colour (RGB888 - e.g. ff00ff) + g - greyscale "colour" (0-3) + + sep - list separator (e.g. ',' or '|') + str - string to parse, must be terminated by 0 or sep + ... - pointers to store the parsed values + + return value - pointer to char after parsed data, 0 if there was an error. + +*/ + +/* '0'-'3' are ASCII 0x30 to 0x33 */ +#define is0123(x) (((x) & 0xfc) == 0x30) + +const char* parse_list(const char *fmt, const char sep, const char* str, ...) +{ + va_list ap; + const char* p = str; + const char** s; + int* d; + + va_start(ap, str); + + while (*fmt) + { + /* Check for separator, if we're not at the start */ + if (p != str) + { + if (*p != sep) + goto err; + p++; + } + + switch (*fmt++) + { + case 's': /* string - return a pointer to it (not a copy) */ + s = va_arg(ap, const char **); + + *s = p; + while (*p && *p != sep) + p++; + + break; + + case 'd': /* int */ + d = va_arg(ap, int*); + if (!isdigit(*p)) + goto err; + + *d = *p++ - '0'; + + while (isdigit(*p)) + *d = (*d * 10) + (*p++ - '0'); + + break; + +#ifdef HAVE_LCD_COLOR + case 'c': /* colour (rrggbb - e.g. f3c1a8) */ + d = va_arg(ap, int*); + + if (hex_to_rgb(p, d) < 0) + goto err; + + p += 6; + + break; +#endif + +#if LCD_DEPTH == 2 || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH == 2) + case 'g': /* greyscale colour (0-3) */ + d = va_arg(ap, int*); + + if (is0123(*p)) + *d = *p++ - '0'; + else + goto err; + + break; +#endif + + default: /* Unknown format type */ + goto err; + break; + } + } + + va_end(ap); + return p; + +err: + va_end(ap); + return 0; +} +#endif diff --git a/apps/misc.h b/apps/misc.h index 289d952afb..c6a91646b8 100644 --- a/apps/misc.h +++ b/apps/misc.h @@ -110,7 +110,7 @@ void check_bootfile(bool do_rolo); void setvol(void); #ifdef HAVE_LCD_COLOR -int hex_to_rgb(const char* hex); +int hex_to_rgb(const char* hex, int* color); #endif char* strrsplt(char* str, int c); @@ -124,4 +124,7 @@ bool dir_exists(const char *path); */ char *strip_extension(char* buffer, int buffer_size, const char *filename); +/* A simplified scanf */ +const char* parse_list(const char *fmt, const char sep, const char* str, ...); + #endif /* MISC_H */ diff --git a/apps/plugins/text_editor.c b/apps/plugins/text_editor.c index 6b6e449ae9..780516e896 100644 --- a/apps/plugins/text_editor.c +++ b/apps/plugins/text_editor.c @@ -273,7 +273,7 @@ int do_item_menu(int cur_sel, char* copy_buffer) || (c>='0' && c<= '9')) #define hex2dec(c) (((c) >= '0' && ((c) <= '9')) ? (toupper(c)) - '0' : \ (toupper(c)) - 'A' + 10) -int hex_to_rgb(const char* hex) +int hex_to_rgb(const char* hex, int* color) { int ok = 1; int i; int red, green, blue; @@ -290,11 +290,12 @@ int hex_to_rgb(const char* hex) red = (hex2dec(hex[0]) << 4) | hex2dec(hex[1]); green = (hex2dec(hex[2]) << 4) | hex2dec(hex[3]); blue = (hex2dec(hex[4]) << 4) | hex2dec(hex[5]); - return LCD_RGBPACK(red,green,blue); + *color = LCD_RGBPACK(red,green,blue); + return 0; } } - return 0; + return -1; } #endif /* HAVE_LCD_COLOR */ @@ -407,7 +408,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) case 1: edit_text = false; if (value) - color = hex_to_rgb(value); + hex_to_rgb(value, &color); else color = 0; rb->strcpy(extension, name); rb->set_color(rb->screens[SCREEN_MAIN], name, &color, -1); diff --git a/apps/settings.c b/apps/settings.c index 7eec15baf3..6fb5e3ee47 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -290,7 +290,7 @@ bool settings_load_config(const char* file, bool apply) case F_T_UINT: #ifdef HAVE_LCD_COLOR if (settings[i].flags&F_RGB) - *(int*)settings[i].setting = hex_to_rgb(value); + hex_to_rgb(value, (int*)settings[i].setting); else #endif if (settings[i].cfg_vals == NULL) -- cgit v1.2.3