From 07696c10b10a051af3cb680b06c422e13c42aa76 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Sun, 8 Apr 2007 04:01:06 +0000 Subject: FS#6991. Patch by Alexander Levin, modified by me: * Reorganisation of the WPS data structure with line and subline structs. This allows us to use sublines more sparingly, so it should save some memory. Also it removes the need for the "End Of Line" token. Overall, the data structure and the code are simplified and gain in clarity. * Some code improvements and added comments. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13065 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/gwps-common.c | 135 ++++++++++++++++------------ apps/gui/gwps.h | 122 ++++++++++++++++++-------- apps/gui/wps_debug.c | 232 ++++++++++++++++++++++++------------------------- apps/gui/wps_parser.c | 207 ++++++++++++++++++++++++++----------------- 4 files changed, 408 insertions(+), 288 deletions(-) (limited to 'apps') diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index c96b830cf2..078e20ba44 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -81,12 +81,10 @@ void gui_wps_statusbar_draw(struct gui_wps *wps, bool force) { bool draw = global_settings.statusbar; - if(wps->data->wps_sb_tag - && wps->data->show_sb_on_wps) - draw = true; - else if(wps->data->wps_sb_tag) - draw = false; - if(draw) + if (wps->data->wps_sb_tag) + draw = wps->data->show_sb_on_wps; + + if (draw) gui_statusbar_draw(wps->statusbar, force); } #else @@ -1012,15 +1010,13 @@ static char *get_tag(struct gui_wps *gwps, } } #endif - case WPS_TOKEN_BATTERY_SLEEPTIME: { if (get_sleep_timer() == 0) return NULL; else { - format_time(buf, buf_size, \ - get_sleep_timer() * 1000); + format_time(buf, buf_size, get_sleep_timer() * 1000); return buf; } } @@ -1377,6 +1373,7 @@ static bool get_line(struct gui_wps *gwps, char temp_buf[128]; char *buf = linebuf; /* will always point to the writing position */ char *linebuf_end = linebuf + linebuf_size - 1; + int i, last_token_idx; bool update = false; /* alignment-related variables */ @@ -1384,16 +1381,14 @@ static bool get_line(struct gui_wps *gwps, char* cur_align_start; cur_align_start = buf; cur_align = WPS_ALIGN_LEFT; - align->left = 0; - align->center = 0; - align->right = 0; - - /* start at the beginning of the current (sub)line */ - int i = data->format_lines[line][subline]; - - while (data->tokens[i].type != WPS_TOKEN_EOL - && data->tokens[i].type != WPS_TOKEN_SUBLINE_SEPARATOR - && i < data->num_tokens) + align->left = NULL; + align->center = NULL; + align->right = NULL; + + /* Process all tokens of the desired subline */ + last_token_idx = wps_last_token_index(data, line, subline); + for (i = wps_first_token_index(data, line, subline); + i <= last_token_idx; i++) { switch(data->tokens[i].type) { @@ -1460,8 +1455,7 @@ static bool get_line(struct gui_wps *gwps, default: { /* get the value of the tag and copy it to the buffer */ - char *value = get_tag(gwps, i, temp_buf, - sizeof(temp_buf), NULL); + char *value = get_tag(gwps,i,temp_buf,sizeof(temp_buf),NULL); if (value) { update = true; @@ -1471,7 +1465,6 @@ static bool get_line(struct gui_wps *gwps, break; } } - i++; } /* close the current alignment */ @@ -1496,13 +1489,14 @@ static bool get_line(struct gui_wps *gwps, static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) { struct wps_data *data = gwps->data; - int i = data->format_lines[line][subline]; + int i; + int subline_idx = wps_subline_index(data, line, subline); + int last_token_idx = wps_last_token_index(data, line, subline); - data->time_mult[line][subline] = DEFAULT_SUBLINE_TIME_MULTIPLIER; + data->sublines[subline_idx].time_mult = DEFAULT_SUBLINE_TIME_MULTIPLIER; - while (data->tokens[i].type != WPS_TOKEN_EOL - && data->tokens[i].type != WPS_TOKEN_SUBLINE_SEPARATOR - && i < data->num_tokens) + for (i = wps_first_token_index(data, line, subline); + i <= last_token_idx; i++) { switch(data->tokens[i].type) { @@ -1518,32 +1512,33 @@ static void get_subline_timeout(struct gui_wps *gwps, int line, int subline) break; case WPS_TOKEN_SUBLINE_TIMEOUT: - data->time_mult[line][subline] = data->tokens[i].value.i; + data->sublines[subline_idx].time_mult = data->tokens[i].value.i; break; default: break; } - i++; } } -/* Calculate which subline should be displayed for each line */ -static bool get_curr_subline(struct gui_wps *gwps, int line) +/* Calculates which subline should be displayed for the specified line + Returns true iff the subline must be refreshed */ +static bool update_curr_subline(struct gui_wps *gwps, int line) { struct wps_data *data = gwps->data; - int search, search_start; + int search, search_start, num_sublines; bool reset_subline; bool new_subline_refresh; bool only_one_subline; - reset_subline = (data->curr_subline[line] == SUBLINE_RESET); + num_sublines = data->lines[line].num_sublines; + reset_subline = (data->lines[line].curr_subline == SUBLINE_RESET); new_subline_refresh = false; only_one_subline = false; /* if time to advance to next sub-line */ - if (TIME_AFTER(current_tick, data->subline_expire_time[line] - 1) || + if (TIME_AFTER(current_tick, data->lines[line].subline_expire_time - 1) || reset_subline) { /* search all sublines until the next subline with time > 0 @@ -1551,43 +1546,45 @@ static bool get_curr_subline(struct gui_wps *gwps, int line) if (reset_subline) search_start = 0; else - search_start = data->curr_subline[line]; + search_start = data->lines[line].curr_subline; - for (search = 0; search < WPS_MAX_SUBLINES; search++) + for (search = 0; search < num_sublines; search++) { - data->curr_subline[line]++; + data->lines[line].curr_subline++; /* wrap around if beyond last defined subline or WPS_MAX_SUBLINES */ - if ((!data->format_lines[line][data->curr_subline[line]]) || - (data->curr_subline[line] == WPS_MAX_SUBLINES)) + if (data->lines[line].curr_subline == num_sublines) { - if (data->curr_subline[line] == 1) + if (data->lines[line].curr_subline == 1) only_one_subline = true; - data->curr_subline[line] = 0; + data->lines[line].curr_subline = 0; } /* if back where we started after search or only one subline is defined on the line */ - if (((search > 0) && (data->curr_subline[line] == search_start)) || + if (((search > 0) && (data->lines[line].curr_subline == search_start)) || only_one_subline) { /* no other subline with a time > 0 exists */ - data->subline_expire_time[line] = (reset_subline? - current_tick : data->subline_expire_time[line]) + 100 * HZ; + data->lines[line].subline_expire_time = (reset_subline ? + current_tick : data->lines[line].subline_expire_time) + 100 * HZ; break; } else { /* get initial time multiplier for this subline */ - get_subline_timeout(gwps, line, data->curr_subline[line]); + get_subline_timeout(gwps, line, data->lines[line].curr_subline); + + int subline_idx = wps_subline_index(data, line, + data->lines[line].curr_subline); /* only use this subline if subline time > 0 */ - if (data->time_mult[line][data->curr_subline[line]] > 0) + if (data->sublines[subline_idx].time_mult > 0) { new_subline_refresh = true; - data->subline_expire_time[line] = (reset_subline ? - current_tick : data->subline_expire_time[line]) + - BASE_SUBLINE_TIME * data->time_mult[line][data->curr_subline[line]]; + data->lines[line].subline_expire_time = (reset_subline ? + current_tick : data->lines[line].subline_expire_time) + + BASE_SUBLINE_TIME * data->sublines[subline_idx].time_mult; break; } } @@ -1779,7 +1776,7 @@ bool gui_wps_refresh(struct gui_wps *gwps, if(!gwps || !data || !state || !display) return false; - int line, i; + int line, i, subline_idx; unsigned char flags; char linebuf[MAX_PATH]; @@ -1814,7 +1811,7 @@ bool gui_wps_refresh(struct gui_wps *gwps, { for (i = 0; i < data->num_lines; i++) { - data->curr_subline[i] = SUBLINE_RESET; + data->lines[i].curr_subline = SUBLINE_RESET; } } @@ -1840,15 +1837,16 @@ bool gui_wps_refresh(struct gui_wps *gwps, update_line = false; /* get current subline for the line */ - new_subline_refresh = get_curr_subline(gwps, line); + new_subline_refresh = update_curr_subline(gwps, line); - flags = data->line_type[line][data->curr_subline[line]]; + subline_idx = wps_subline_index(data, line, data->lines[line].curr_subline); + flags = data->sublines[subline_idx].line_type; - if (refresh_mode == WPS_REFRESH_ALL || flags & refresh_mode + if (refresh_mode == WPS_REFRESH_ALL || (flags & refresh_mode) || new_subline_refresh) { /* get_line tells us if we need to update the line */ - update_line = get_line(gwps, line, data->curr_subline[line], + update_line = get_line(gwps, line, data->lines[line].curr_subline, &align, linebuf, sizeof(linebuf)); } @@ -1947,3 +1945,30 @@ bool gui_wps_refresh(struct gui_wps *gwps, return true; } + +int wps_subline_index(struct wps_data *data, int line, int subline) +{ + return data->lines[line].first_subline_idx + subline; +} + +int wps_first_token_index(struct wps_data *data, int line, int subline) +{ + int first_subline_idx = data->lines[line].first_subline_idx; + return data->sublines[first_subline_idx + subline].first_token_idx; +} + +int wps_last_token_index(struct wps_data *data, int line, int subline) +{ + int first_subline_idx = data->lines[line].first_subline_idx; + int idx = first_subline_idx + subline; + if (idx < data->num_sublines - 1) + { + /* This subline ends where the next begins */ + return data->sublines[idx+1].first_token_idx - 1; + } + else + { + /* The last subline goes to the end */ + return data->num_tokens - 1; + } +} diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h index 02a83085b9..f012b3b304 100644 --- a/apps/gui/gwps.h +++ b/apps/gui/gwps.h @@ -71,23 +71,25 @@ struct align_pos { #define MAX_IMAGES (26*2) /* a-z and A-Z */ #define IMG_BUFSIZE ((LCD_HEIGHT*LCD_WIDTH*LCD_DEPTH/8) \ + (2*LCD_HEIGHT*LCD_WIDTH/8)) -#define WPS_MAX_LINES (LCD_HEIGHT/5+1) -#define WPS_MAX_TOKENS 1024 -#define WPS_MAX_STRINGS 128 -#define STRING_BUFFER_SIZE 512 -#define WPS_MAX_COND_LEVEL 10 + +#define WPS_MAX_LINES (LCD_HEIGHT/5+1) +#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3) +#define WPS_MAX_TOKENS 1024 +#define WPS_MAX_STRINGS 128 +#define STRING_BUFFER_SIZE 512 +#define WPS_MAX_COND_LEVEL 10 #else -#define WPS_MAX_LINES 2 -#define WPS_MAX_TOKENS 64 -#define WPS_MAX_STRINGS 32 -#define STRING_BUFFER_SIZE 64 -#define WPS_MAX_COND_LEVEL 5 +#define WPS_MAX_LINES 2 +#define WPS_MAX_SUBLINES 12 +#define WPS_MAX_TOKENS 64 +#define WPS_MAX_STRINGS 32 +#define STRING_BUFFER_SIZE 64 +#define WPS_MAX_COND_LEVEL 5 #endif -#define WPS_MAX_SUBLINES 12 #define DEFAULT_SUBLINE_TIME_MULTIPLIER 20 /* (10ths of sec) */ #define BASE_SUBLINE_TIME 10 /* base time that multiplier is applied to (1/HZ sec, or 100ths of sec) */ @@ -100,18 +102,13 @@ enum wps_token_type { /* Markers */ WPS_TOKEN_CHARACTER, WPS_TOKEN_STRING, - WPS_TOKEN_EOL, /* Alignment */ WPS_TOKEN_ALIGN_LEFT, WPS_TOKEN_ALIGN_CENTER, WPS_TOKEN_ALIGN_RIGHT, - /* Scrolling */ - WPS_TOKEN_SCROLL, - - /* Alternating sublines */ - WPS_TOKEN_SUBLINE_SEPARATOR, + /* Sublines */ WPS_TOKEN_SUBLINE_TIMEOUT, /* Battery */ @@ -228,12 +225,6 @@ enum wps_token_type { WPS_TOKEN_PLAYLIST_POSITION, WPS_TOKEN_PLAYLIST_SHUFFLE, -#ifdef HAVE_LCD_BITMAP - /* Statusbar */ - WPS_TOKEN_STATUSBAR_ENABLED, - WPS_TOKEN_STATUSBAR_DISABLED, -#endif - #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD) /* Virtual LED */ WPS_TOKEN_VLED_HDD @@ -242,13 +233,52 @@ enum wps_token_type { struct wps_token { enum wps_token_type type; + + /* Whether the tag (e.g. track name or the album) refers the + current or the next song (false=current, true=next) */ bool next; + union { char c; unsigned short i; } value; }; +/* Description of a subline on the WPS */ +struct wps_subline { + + /* Index of the first token for this subline in the token array. + Tokens of this subline end where tokens for the next subline + begin. */ + unsigned short first_token_idx; + + /* Bit or'ed WPS_REFRESH_xxx */ + unsigned char line_type; + + /* How long the subline should be displayed, in 10ths of sec */ + unsigned char time_mult; +}; + +/* Description of a line on the WPS. A line is a set of sublines. + A subline is displayed for a certain amount of time. After that, + the next subline of the line is displayed. And so on. */ +struct wps_line { + + /* Number of sublines in this line */ + signed char num_sublines; + + /* Number (0-based) of the subline within this line currently being displayed */ + signed char curr_subline; + + /* Index of the first subline of this line in the subline array. + Sublines for this line end where sublines for the next line begin. */ + unsigned short first_subline_idx; + + /* When the next subline of this line should be displayed + (absolute time value in ticks) */ + long subline_expire_time; +}; + /* wps_data this struct holds all necessary data which describes the @@ -273,20 +303,24 @@ struct wps_data unsigned short wps_progress_pat[8]; bool full_line_progressbar; #endif - unsigned short format_lines[WPS_MAX_LINES][WPS_MAX_SUBLINES]; - unsigned char num_lines; - unsigned char line_type[WPS_MAX_LINES][WPS_MAX_SUBLINES]; - unsigned short time_mult[WPS_MAX_LINES][WPS_MAX_SUBLINES]; - long subline_expire_time[WPS_MAX_LINES]; - short curr_subline[WPS_MAX_LINES]; - unsigned char num_sublines[WPS_MAX_LINES]; - + /* Number of lines in the WPS. During WPS parsing, this is + the index of the line being parsed. */ + int num_lines; + struct wps_line lines[WPS_MAX_LINES]; + + /* Total number of sublines in the WPS. During WPS parsing, this is + the index of the subline where the parsed tokens are added to. */ + int num_sublines; + struct wps_subline sublines[WPS_MAX_SUBLINES]; + + /* Total number of tokens in the WPS. During WPS parsing, this is + the index of the token being parsed. */ + int num_tokens; struct wps_token tokens[WPS_MAX_TOKENS]; - unsigned short num_tokens; char string_buffer[STRING_BUFFER_SIZE]; char *strings[WPS_MAX_STRINGS]; - unsigned char num_strings; + int num_strings; bool wps_loaded; }; @@ -300,6 +334,24 @@ bool wps_data_load(struct wps_data *wps_data, const char *buf, bool isfile); +/* Returns the index of the subline in the subline array + line - 0-based line number + subline - 0-based subline number within the line + */ +int wps_subline_index(struct wps_data *wps_data, int line, int subline); + +/* Returns the index of the first subline's token in the token array + line - 0-based line number + subline - 0-based subline number within the line + */ +int wps_first_token_index(struct wps_data *data, int line, int subline); + +/* Returns the index of the last subline's token in the token array. + line - 0-based line number + subline - 0-based subline number within the line + */ +int wps_last_token_index(struct wps_data *data, int line, int subline); + /* wps_data end */ /* wps_state @@ -329,11 +381,11 @@ struct wps_state /* wps_state end*/ /* gui_wps - defines a wps with it's data, state, + defines a wps with its data, state, and the screen on which the wps-content should be drawn */ struct gui_wps { - struct screen * display; + struct screen *display; struct wps_data *data; struct wps_state *state; struct gui_statusbar *statusbar; diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c index bcb05e0902..0e2b151551 100644 --- a/apps/gui/wps_debug.c +++ b/apps/gui/wps_debug.c @@ -24,107 +24,122 @@ #include "gwps.h" #include "debug.h" +static char *next_str(bool next) { + return next ? "next" : ""; +} + void dump_wps_tokens(struct wps_data *data) { + struct wps_token *token; int i, j; int indent = 0; char buf[64]; bool next; - /* Dump parsed WPS */ - for(i = 0; i < data->num_tokens && i < WPS_MAX_TOKENS; i++) { + if (data->num_tokens > WPS_MAX_TOKENS) { + DEBUGF("Number of tokens is too high (%d)!!!\n", data->num_tokens); + return; + } - next = data->tokens[i].next; + /* Dump parsed WPS */ + for (i = 0, token = data->tokens; i < data->num_tokens; i++, token++) { + next = token->next; - switch(data->tokens[i].type) { + switch(token->type) { case WPS_TOKEN_UNKNOWN: snprintf(buf, sizeof(buf), "Unknown token"); break; case WPS_TOKEN_CHARACTER: snprintf(buf, sizeof(buf), "Character '%c'", - data->tokens[i].value.c); + token->value.c); break; case WPS_TOKEN_STRING: snprintf(buf, sizeof(buf), "String '%s'", - data->strings[data->tokens[i].value.i]); - break; - - case WPS_TOKEN_EOL: - snprintf(buf, sizeof(buf), "%s", "EOL"); + data->strings[token->value.i]); break; #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_ALIGN_LEFT: - snprintf(buf, sizeof(buf), "%s", "align left"); + snprintf(buf, sizeof(buf), "align left"); break; case WPS_TOKEN_ALIGN_CENTER: - snprintf(buf, sizeof(buf), "%s", "align center"); + snprintf(buf, sizeof(buf), "align center"); break; case WPS_TOKEN_ALIGN_RIGHT: - snprintf(buf, sizeof(buf), "%s", "align right"); + snprintf(buf, sizeof(buf), "align right"); break; #endif + case WPS_TOKEN_SUBLINE_TIMEOUT: + snprintf(buf, sizeof(buf), "subline timeout value: %d", + token->value.i); + break; + case WPS_TOKEN_CONDITIONAL: - snprintf(buf, sizeof(buf), "%s, %d options", "conditional", - data->tokens[i].value.i); + snprintf(buf, sizeof(buf), "conditional, %d options", + token->value.i); break; case WPS_TOKEN_CONDITIONAL_START: - snprintf(buf, sizeof(buf), "%s, next cond: %d", - "conditional start", data->tokens[i].value.i); + snprintf(buf, sizeof(buf), "conditional start, next cond: %d", + token->value.i); indent++; break; case WPS_TOKEN_CONDITIONAL_OPTION: - snprintf(buf, sizeof(buf), "%s, next cond: %d", - "conditional option", data->tokens[i].value.i); + snprintf(buf, sizeof(buf), "conditional option, next cond: %d", + token->value.i); break; case WPS_TOKEN_CONDITIONAL_END: - snprintf(buf, sizeof(buf), "%s", "conditional end"); + snprintf(buf, sizeof(buf), "conditional end"); indent--; break; #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_IMAGE_PRELOAD: - snprintf(buf, sizeof(buf), "%s", "preload image"); + snprintf(buf, sizeof(buf), "preload image"); break; case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: - snprintf(buf, sizeof(buf), "%s %d", "display preloaded image", - data->tokens[i].value.i); + snprintf(buf, sizeof(buf), "display preloaded image %d", + token->value.i); break; case WPS_TOKEN_IMAGE_DISPLAY: - snprintf(buf, sizeof(buf), "%s", "display image"); + snprintf(buf, sizeof(buf), "display image"); break; #endif #ifdef HAS_BUTTON_HOLD case WPS_TOKEN_MAIN_HOLD: - snprintf(buf, sizeof(buf), "%s", "mode hold"); + snprintf(buf, sizeof(buf), "mode hold"); break; #endif #ifdef HAS_REMOTE_BUTTON_HOLD case WPS_TOKEN_REMOTE_HOLD: - snprintf(buf, sizeof(buf), "%s", "mode remote hold"); + snprintf(buf, sizeof(buf), "mode remote hold"); break; #endif case WPS_TOKEN_REPEAT_MODE: - snprintf(buf, sizeof(buf), "%s", "mode repeat"); + snprintf(buf, sizeof(buf), "mode repeat"); break; case WPS_TOKEN_PLAYBACK_STATUS: - snprintf(buf, sizeof(buf), "%s", "mode playback"); + snprintf(buf, sizeof(buf), "mode playback"); break; #if CONFIG_RTC + case WPS_TOKEN_RTC: + snprintf(buf, sizeof(buf), "real-time clock", + token->value.c); + break; + case WPS_TOKEN_RTC_DAY_OF_MONTH: case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: @@ -142,199 +157,159 @@ void dump_wps_tokens(struct wps_data *data) case WPS_TOKEN_RTC_MONTH_NAME: case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: - case WPS_TOKEN_RTC: - snprintf(buf, sizeof(buf), "%s %c", "real-time clock tag:", - data->tokens[i].value.c); + snprintf(buf, sizeof(buf), "real-time clock tag: %c", + token->value.c); break; #endif #ifdef HAVE_LCD_BITMAP case WPS_TOKEN_IMAGE_BACKDROP: - snprintf(buf, sizeof(buf), "%s", "backdrop image"); + snprintf(buf, sizeof(buf), "backdrop image"); break; case WPS_TOKEN_IMAGE_PROGRESS_BAR: - snprintf(buf, sizeof(buf), "%s", "progressbar bitmap"); - break; - - - case WPS_TOKEN_STATUSBAR_ENABLED: - snprintf(buf, sizeof(buf), "%s", "statusbar enable"); - break; - - case WPS_TOKEN_STATUSBAR_DISABLED: - snprintf(buf, sizeof(buf), "%s", "statusbar disable"); + snprintf(buf, sizeof(buf), "progressbar bitmap"); break; case WPS_TOKEN_PEAKMETER: - snprintf(buf, sizeof(buf), "%s", "peakmeter"); + snprintf(buf, sizeof(buf), "peakmeter"); break; #endif case WPS_TOKEN_PROGRESSBAR: - snprintf(buf, sizeof(buf), "%s", "progressbar"); + snprintf(buf, sizeof(buf), "progressbar"); break; #ifdef HAVE_LCD_CHARCELLS case WPS_TOKEN_PLAYER_PROGRESSBAR: - snprintf(buf, sizeof(buf), "%s", "full line progressbar"); + snprintf(buf, sizeof(buf), "full line progressbar"); break; #endif case WPS_TOKEN_TRACK_TIME_ELAPSED: - snprintf(buf, sizeof(buf), "%s", "time elapsed in track"); + snprintf(buf, sizeof(buf), "time elapsed in track"); break; case WPS_TOKEN_PLAYLIST_ENTRIES: - snprintf(buf, sizeof(buf), "%s", "number of entries in playlist"); + snprintf(buf, sizeof(buf), "number of entries in playlist"); break; case WPS_TOKEN_PLAYLIST_NAME: - snprintf(buf, sizeof(buf), "%s", "playlist name"); + snprintf(buf, sizeof(buf), "playlist name"); break; case WPS_TOKEN_PLAYLIST_POSITION: - snprintf(buf, sizeof(buf), "%s", "position in playlist"); + snprintf(buf, sizeof(buf), "position in playlist"); break; case WPS_TOKEN_TRACK_TIME_REMAINING: - snprintf(buf, sizeof(buf), "%s", "time remaining in track"); + snprintf(buf, sizeof(buf), "time remaining in track"); break; case WPS_TOKEN_PLAYLIST_SHUFFLE: - snprintf(buf, sizeof(buf), "%s", "playlist shuffle mode"); + snprintf(buf, sizeof(buf), "playlist shuffle mode"); break; case WPS_TOKEN_TRACK_LENGTH: - snprintf(buf, sizeof(buf), "%s", "track length"); + snprintf(buf, sizeof(buf), "track length"); break; case WPS_TOKEN_VOLUME: - snprintf(buf, sizeof(buf), "%s", "volume"); + snprintf(buf, sizeof(buf), "volume"); break; case WPS_TOKEN_METADATA_ARTIST: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track artist"); + snprintf(buf, sizeof(buf), "%strack artist", next_str(next)); break; case WPS_TOKEN_METADATA_COMPOSER: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track composer"); + snprintf(buf, sizeof(buf), "%strack composer", next_str(next)); break; case WPS_TOKEN_METADATA_ALBUM: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track album"); + snprintf(buf, sizeof(buf), "%strack album", next_str(next)); break; case WPS_TOKEN_METADATA_GENRE: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track genre"); + snprintf(buf, sizeof(buf), "%strack genre", next_str(next)); break; case WPS_TOKEN_METADATA_TRACK_NUMBER: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track number"); + snprintf(buf, sizeof(buf), "%strack number", next_str(next)); break; case WPS_TOKEN_METADATA_TRACK_TITLE: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track title"); + snprintf(buf, sizeof(buf), "%strack title", next_str(next)); break; case WPS_TOKEN_METADATA_VERSION: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track ID3 version"); + snprintf(buf, sizeof(buf), "%strack ID3 version", next_str(next)); break; case WPS_TOKEN_METADATA_YEAR: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "track year"); + snprintf(buf, sizeof(buf), "%strack year", next_str(next)); break; case WPS_TOKEN_BATTERY_PERCENT: - snprintf(buf, sizeof(buf), "%s", "battery percentage"); + snprintf(buf, sizeof(buf), "battery percentage"); break; case WPS_TOKEN_BATTERY_VOLTS: - snprintf(buf, sizeof(buf), "%s", "battery voltage"); + snprintf(buf, sizeof(buf), "battery voltage"); break; case WPS_TOKEN_BATTERY_TIME: - snprintf(buf, sizeof(buf), "%s", "battery time left"); + snprintf(buf, sizeof(buf), "battery time left"); break; case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: - snprintf(buf, sizeof(buf), "%s", "battery charger connected"); + snprintf(buf, sizeof(buf), "battery charger connected"); break; case WPS_TOKEN_BATTERY_CHARGING: - snprintf(buf, sizeof(buf), "%s", "battery charging"); + snprintf(buf, sizeof(buf), "battery charging"); break; case WPS_TOKEN_FILE_BITRATE: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file bitrate"); + snprintf(buf, sizeof(buf), "%sfile bitrate", next_str(next)); break; case WPS_TOKEN_FILE_CODEC: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file codec"); + snprintf(buf, sizeof(buf), "%sfile codec", next_str(next)); break; case WPS_TOKEN_FILE_FREQUENCY: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file audio frequency"); + snprintf(buf, sizeof(buf), "%sfile audio frequency", next_str(next)); break; case WPS_TOKEN_FILE_NAME: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file name"); + snprintf(buf, sizeof(buf), "%sfile name", next_str(next)); break; case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file name with extension"); + snprintf(buf, sizeof(buf), "%sfile name with extension", next_str(next)); break; case WPS_TOKEN_FILE_PATH: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file path"); + snprintf(buf, sizeof(buf), "%sfile path", next_str(next)); break; case WPS_TOKEN_FILE_SIZE: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file size"); + snprintf(buf, sizeof(buf), "%sfile size", next_str(next)); break; case WPS_TOKEN_FILE_VBR: - snprintf(buf, sizeof(buf), "%s%s", next ? "next " : "", - "file is vbr"); + snprintf(buf, sizeof(buf), "%sfile is vbr", next_str(next)); break; case WPS_TOKEN_FILE_DIRECTORY: - snprintf(buf, sizeof(buf), "%s%s: %d", next ? "next " : "", - "file directory, level", - data->tokens[i].value.i); - break; - - case WPS_TOKEN_SCROLL: - snprintf(buf, sizeof(buf), "%s", "scrolling line"); - break; - - case WPS_TOKEN_SUBLINE_TIMEOUT: - snprintf(buf, sizeof(buf), "%s: %d", "subline timeout value", - data->tokens[i].value.i); - break; - - case WPS_TOKEN_SUBLINE_SEPARATOR: - snprintf(buf, sizeof(buf), "%s", "subline separator"); + snprintf(buf, sizeof(buf), "%sfile directory, level: %d", next_str(next), + token->value.i); break; default: - snprintf(buf, sizeof(buf), "%s (code: %d)", "FIXME", - data->tokens[i].type); + snprintf(buf, sizeof(buf), "FIXME (code: %d)", + token->type); break; } @@ -342,24 +317,43 @@ void dump_wps_tokens(struct wps_data *data) DEBUGF("\t"); } - DEBUGF("[%03d] = %s\n", i, buf); + DEBUGF("[%3d] = (%2d) %s\n", i, token->type, buf); } DEBUGF("\n"); } void print_line_info(struct wps_data *data) { - int line, subline; + int i, j; + struct wps_line *line; + struct wps_subline *subline; - DEBUGF("line/subline start indexes :\n"); - for (line = 0; line < data->num_lines; line++) + DEBUGF("Number of lines : %d\n", data->num_lines); + DEBUGF("Number of sublines: %d\n", data->num_sublines); + DEBUGF("Number of tokens : %d\n", data->num_tokens); + DEBUGF("\n"); + + for (i = 0, line = data->lines; i < data->num_lines; i++,line++) { - DEBUGF("%2d. ", line); - for (subline = 0; subline < data->num_sublines[line]; subline++) + DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n", + i, line->num_sublines, line->first_subline_idx); + + for (j = 0, subline = data->sublines + line->first_subline_idx; + j < line->num_sublines; j++, subline++) { - DEBUGF("%3d ", data->format_lines[line][subline]); + DEBUGF(" Subline %d: first_token=%3d, last_token=%3d", + j, subline->first_token_idx, + wps_last_token_index(data, i, j)); + + if (subline->line_type & WPS_REFRESH_SCROLL) + DEBUGF(", scrolled"); + else if (subline->line_type & WPS_REFRESH_PLAYER_PROGRESS) + DEBUGF(", progressbar"); + else if (subline->line_type & WPS_REFRESH_PEAK_METER) + DEBUGF(", peakmeter"); + + DEBUGF("\n"); } - DEBUGF("\n"); } DEBUGF("\n"); @@ -367,21 +361,21 @@ void print_line_info(struct wps_data *data) void print_wps_strings(struct wps_data *data) { - DEBUGF("strings :\n"); + DEBUGF("Strings:\n"); int i, len = 0; for (i=0; i < data->num_strings; i++) { len += strlen(data->strings[i]); DEBUGF("%2d: '%s'\n", i, data->strings[i]); } - DEBUGF("total length : %d\n", len); + DEBUGF("Total length: %d\n", len); DEBUGF("\n"); } #ifdef HAVE_LCD_BITMAP void print_img_cond_indexes(struct wps_data *data) { - DEBUGF("image conditional indexes :\n"); + DEBUGF("Image conditional indexes:\n"); int i; for (i=0; i < MAX_IMAGES; i++) { diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 2a610bdb8c..65f33447fc 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -69,10 +69,18 @@ extern void print_img_cond_indexes(struct wps_data *data); extern void print_wps_strings(struct wps_data *data); #endif -/* special parsing function. - wps_bufptr points to the char following the tag. - The return value is the number of chars read. */ -typedef int (*wps_tag_parse_func)(const char *wps_bufptr, struct wps_data *wps_data); +/* Function for parsing of details for a token. At the moment the + function is called, the token type has already been set. The + function must fill in the details and possibly add more tokens + to the token array. It should return the number of chars that + has been consumed. + + wps_bufptr points to the char following the tag (i.e. where + details begin). + token is the pointer to the 'main' token being parsed + */ +typedef int (*wps_tag_parse_func)(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); struct wps_tag { enum wps_token_type type; @@ -82,17 +90,27 @@ struct wps_tag { }; /* prototypes of all special parse functions : */ -static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data); -static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data); -static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data); +static int parse_subline_timeout(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_progressbar(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_dir_level(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); #ifdef HAVE_LCD_BITMAP -static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data); -static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data); -static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data); -static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data); +static int parse_image_special(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_statusbar_enable(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_statusbar_disable(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_image_display(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); +static int parse_image_load(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); #endif /*HAVE_LCD_BITMAP */ #if CONFIG_RTC -static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data); +static int parse_rtc_format(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); /* RTC tokens array */ static const struct wps_tag rtc_tags[] = { @@ -113,8 +131,8 @@ static const struct wps_tag rtc_tags[] = { { WPS_TOKEN_RTC_MONTH_NAME, "b", 0, NULL }, { WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON, "u", 0, NULL }, { WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "w", 0, NULL }, - { WPS_TOKEN_CHARACTER, "\0",0, NULL } - /* the array MUST end with a "\0" token */ + { WPS_TOKEN_CHARACTER, "", 0, NULL } + /* the array MUST end with an empty string (first char is \0) */ }; #endif @@ -229,29 +247,30 @@ static const struct wps_tag all_tags[] = { { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, #endif - { WPS_TOKEN_SCROLL, "s", WPS_REFRESH_SCROLL, NULL }, + { WPS_NO_TOKEN, "s", WPS_REFRESH_SCROLL, NULL }, { WPS_TOKEN_SUBLINE_TIMEOUT, "t", 0, parse_subline_timeout }, #ifdef HAVE_LCD_BITMAP - { WPS_TOKEN_STATUSBAR_ENABLED, "we", 0, parse_statusbar }, - { WPS_TOKEN_STATUSBAR_DISABLED, "wd", 0, parse_statusbar }, + { WPS_NO_TOKEN, "we", 0, parse_statusbar_enable }, + { WPS_NO_TOKEN, "wd", 0, parse_statusbar_disable }, { WPS_NO_TOKEN, "xl", 0, parse_image_load }, { WPS_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", WPS_REFRESH_STATIC, parse_image_display }, - { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, - { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, + { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, + { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, #if LCD_DEPTH > 1 - { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, + { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, #endif #endif - { WPS_TOKEN_UNKNOWN, "\0", 0, NULL } - /* the array MUST end with a "\0" token */ + { WPS_TOKEN_UNKNOWN, "", 0, NULL } + /* the array MUST end with an empty string (first char is \0) */ }; - +/* Returns the number of chars that should be skipped to jump + immediately after the first eol, i.e. to the start of the next line */ static int skip_end_of_line(const char *wps_bufptr) { int skip = 0; @@ -260,10 +279,20 @@ static int skip_end_of_line(const char *wps_bufptr) return ++skip; } +/* Starts a new subline in the current line during parsing */ +static void wps_start_new_subline(struct wps_data *data) { + data->num_sublines++; + data->sublines[data->num_sublines].first_token_idx = data->num_tokens; + data->lines[data->num_lines].num_sublines++; +} + #if CONFIG_RTC -static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_rtc_format(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { int skip = 0, i; + (void)token; /* kill the warning */ /* RTC tag format ends with a c or a newline */ while (wps_bufptr && *wps_bufptr != 'c' && *wps_bufptr != '\n') @@ -276,7 +305,7 @@ static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data) wps_data->num_tokens++; wps_data->tokens[wps_data->num_tokens].type = rtc_tags[i].type; wps_data->tokens[wps_data->num_tokens].value.c = *wps_bufptr; - skip ++; + skip++; wps_bufptr++; } @@ -290,16 +319,23 @@ static int parse_rtc_format(const char *wps_bufptr, struct wps_data *wps_data) #ifdef HAVE_LCD_BITMAP -static int parse_statusbar(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_statusbar_enable(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { + (void)token; /* Kill warnings */ wps_data->wps_sb_tag = true; + wps_data->show_sb_on_wps = true; + return skip_end_of_line(wps_bufptr); +} - if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_STATUSBAR_ENABLED) - wps_data->show_sb_on_wps = true; - else - wps_data->show_sb_on_wps = false; - - /* Skip the rest of the line */ +static int parse_statusbar_disable(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)token; /* Kill warnings */ + wps_data->wps_sb_tag = true; + wps_data->show_sb_on_wps = false; return skip_end_of_line(wps_bufptr); } @@ -357,10 +393,12 @@ static char *get_image_filename(const char *start, const char* bmpdir, return buf; } -static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_image_display(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { int n = get_image_id(*wps_bufptr); - wps_data->tokens[wps_data->num_tokens].value.i = n; + token->value.i = n; /* if the image is in a conditional, remember it */ if (level >= 0) @@ -369,7 +407,9 @@ static int parse_image_display(const char *wps_bufptr, struct wps_data *wps_data return 1; } -static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_image_load(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { int n; const char *ptr = wps_bufptr; @@ -421,7 +461,7 @@ static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data) return skip_end_of_line(wps_bufptr); } - if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_DISPLAY) + if (token->type == WPS_TOKEN_IMAGE_DISPLAY) wps_data->img[n].always_display = true; } @@ -429,15 +469,17 @@ static int parse_image_load(const char *wps_bufptr, struct wps_data *wps_data) return skip_end_of_line(wps_bufptr); } -static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_image_special(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { - if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_PROGRESS_BAR) + if (token->type == WPS_TOKEN_IMAGE_PROGRESS_BAR) { /* format: %P|filename.bmp| */ pb_bmp_name = wps_bufptr + 1; } #if LCD_DEPTH > 1 - else if (wps_data->tokens[wps_data->num_tokens].type == WPS_TOKEN_IMAGE_BACKDROP) + else if (token->type == WPS_TOKEN_IMAGE_BACKDROP) { /* format: %X|filename.bmp| */ backdrop_bmp_name = wps_bufptr + 1; @@ -452,20 +494,27 @@ static int parse_image_special(const char *wps_bufptr, struct wps_data *wps_data #endif /* HAVE_LCD_BITMAP */ -static int parse_dir_level(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_dir_level(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { char val[] = { *wps_bufptr, '\0' }; - wps_data->tokens[wps_data->num_tokens].value.i = atoi(val); + token->value.i = atoi(val); + (void)wps_data; /* Kill warnings */ return 1; } -static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_subline_timeout(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { int skip = 0; int val = 0; bool have_point = false; bool have_tenth = false; + (void)wps_data; /* Kill the warning */ + while ( isdigit(*wps_bufptr) || *wps_bufptr == '.' ) { if (*wps_bufptr != '.') @@ -490,13 +539,16 @@ static int parse_subline_timeout(const char *wps_bufptr, struct wps_data *wps_da if (have_tenth == false) val *= 10; - wps_data->tokens[wps_data->num_tokens].value.i = val; + token->value.i = val; return skip; } -static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data) +static int parse_progressbar(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) { + (void)token; /* Kill warnings */ #ifdef HAVE_LCD_BITMAP short *vals[] = { @@ -547,9 +599,8 @@ static int parse_progressbar(const char *wps_bufptr, struct wps_data *wps_data) static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) { int skip = 0, taglen = 0; - int i = 0; - int line = wps_data->num_lines; - int subline = wps_data->num_sublines[line]; + struct wps_token *token = wps_data->tokens + wps_data->num_tokens; + const struct wps_tag *tag; switch(*wps_bufptr) { @@ -560,47 +611,47 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) case '>': case ';': /* escaped characters */ - wps_data->tokens[wps_data->num_tokens].type = WPS_TOKEN_CHARACTER; - wps_data->tokens[wps_data->num_tokens].value.c = *wps_bufptr; + token->type = WPS_TOKEN_CHARACTER; + token->value.c = *wps_bufptr; wps_data->num_tokens++; skip++; break; case '?': /* conditional tag */ - wps_data->tokens[wps_data->num_tokens].type = WPS_TOKEN_CONDITIONAL; + token->type = WPS_TOKEN_CONDITIONAL; level++; condindex[level] = wps_data->num_tokens; numoptions[level] = 1; wps_data->num_tokens++; + token++; wps_bufptr++; skip++; /* no "break" because a '?' is followed by a regular tag */ default: /* find what tag we have */ - while (all_tags[i].name && - strncmp(wps_bufptr, all_tags[i].name, strlen(all_tags[i].name))) - i++; + for (tag = all_tags; + strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0; + tag++) ; - taglen = strlen(all_tags[i].name); + taglen = strlen(tag->name); skip += taglen; - wps_data->tokens[wps_data->num_tokens].type = all_tags[i].type; + token->type = tag->type; + wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_type; /* if the tag has a special parsing function, we call it */ - if (all_tags[i].parse_func) - skip += all_tags[i].parse_func(wps_bufptr + taglen, wps_data); + if (tag->parse_func) + skip += tag->parse_func(wps_bufptr + taglen, token, wps_data); /* Some tags we don't want to save as tokens */ - if (all_tags[i].type == WPS_NO_TOKEN) + if (tag->type == WPS_NO_TOKEN) break; /* tags that start with 'F', 'I' or 'D' are for the next file */ - if ( *(all_tags[i].name) == 'I' || *(all_tags[i].name) == 'F' - || *(all_tags[i].name) == 'D') - wps_data->tokens[wps_data->num_tokens].next = true; + if ( *(tag->name) == 'I' || *(tag->name) == 'F' || *(tag->name) == 'D') + token->next = true; - wps_data->line_type[line][subline] |= all_tags[i].refresh_type; wps_data->num_tokens++; break; } @@ -608,17 +659,19 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) return skip; } +/* Parses the WPS. + data is the pointer to the structure where the parsed WPS should be stored. + It is initialised. + wps_bufptr points to the string containing the WPS tags */ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) { if (!data || !wps_bufptr || !*wps_bufptr) return false; - int subline; - data->num_tokens = 0; char *current_string = data->string_buffer; - while(wps_bufptr && *wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - && data->num_lines < WPS_MAX_LINES) + while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1 + && data->num_lines < WPS_MAX_LINES) { switch(*wps_bufptr++) { @@ -630,12 +683,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) /* Alternating sublines separator */ case ';': - if (data->num_sublines[data->num_lines]+1 < WPS_MAX_SUBLINES) - { - data->tokens[data->num_tokens++].type = WPS_TOKEN_SUBLINE_SEPARATOR; - subline = ++(data->num_sublines[data->num_lines]); - data->format_lines[data->num_lines][subline] = data->num_tokens; - } + if (data->num_sublines+1 < WPS_MAX_SUBLINES) + wps_start_new_subline(data); else wps_bufptr += skip_end_of_line(wps_bufptr); @@ -694,13 +743,14 @@ condlistend: /* close a conditional. sometimes we want to close them even when goto condlistend; break; } - data->tokens[data->num_tokens++].type = WPS_TOKEN_EOL; - (data->num_sublines[data->num_lines])++; - data->num_lines++; + wps_start_new_subline(data); + data->num_lines++; /* Start a new line */ - if (data->num_lines < WPS_MAX_LINES) + if ((data->num_lines < WPS_MAX_LINES) && + (data->num_sublines < WPS_MAX_SUBLINES)) { - data->format_lines[data->num_lines][0] = data->num_tokens; + data->lines[data->num_lines].first_subline_idx = data->num_sublines; + data->sublines[data->num_sublines].first_token_idx = data->num_tokens; } break; @@ -777,8 +827,7 @@ void wps_data_init(struct wps_data *wps_data) wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */ wps_data->peak_meter_enabled = false; #else /* HAVE_LCD_CHARCELLS */ - int i; - for(i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { wps_data->wps_progress_pat[i] = 0; } -- cgit v1.2.3