1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 Nicolas Pennequin, Dan Everton, Matthias Mohr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
31 #define PARSE_FAIL_UNCLOSED_COND 1
32 #define PARSE_FAIL_INVALID_CHAR 2
33 #define PARSE_FAIL_COND_SYNTAX_ERROR 3
34 #define PARSE_FAIL_COND_INVALID_PARAM 4
36 #if defined(SIMULATOR) || defined(__PCTOOL__)
37 extern bool debug_wps
;
38 extern int wps_verbose_level
;
41 static char *next_str(bool next
) {
42 return next
? "next " : "";
45 static char *get_token_desc(struct wps_token
*token
, struct wps_data
*data
,
46 char *buf
, int bufsize
)
48 bool next
= token
->next
;
53 snprintf(buf
, bufsize
, "No token");
56 case WPS_TOKEN_UNKNOWN
:
57 snprintf(buf
, bufsize
, "Unknown token");
60 case WPS_TOKEN_CHARACTER
:
61 snprintf(buf
, bufsize
, "Character '%c'",
65 case WPS_TOKEN_STRING
:
66 snprintf(buf
, bufsize
, "String '%s'",
67 data
->strings
[token
->value
.i
]);
70 #ifdef HAVE_LCD_BITMAP
71 case WPS_TOKEN_ALIGN_LEFT
:
72 snprintf(buf
, bufsize
, "align left");
75 case WPS_TOKEN_ALIGN_CENTER
:
76 snprintf(buf
, bufsize
, "align center");
79 case WPS_TOKEN_ALIGN_RIGHT
:
80 snprintf(buf
, bufsize
, "align right");
84 case WPS_TOKEN_SUBLINE_TIMEOUT
:
85 snprintf(buf
, bufsize
, "subline timeout value: %d",
89 case WPS_TOKEN_CONDITIONAL
:
90 snprintf(buf
, bufsize
, "conditional, %d options",
94 case WPS_TOKEN_CONDITIONAL_START
:
95 snprintf(buf
, bufsize
, "conditional start, next cond: %d",
99 case WPS_TOKEN_CONDITIONAL_OPTION
:
100 snprintf(buf
, bufsize
, "conditional option, next cond: %d",
104 case WPS_TOKEN_CONDITIONAL_END
:
105 snprintf(buf
, bufsize
, "conditional end");
108 #ifdef HAVE_LCD_BITMAP
109 case WPS_TOKEN_IMAGE_PRELOAD
:
110 snprintf(buf
, bufsize
, "preload image");
113 case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY
:
114 snprintf(buf
, bufsize
, "display preloaded image %d",
118 case WPS_TOKEN_IMAGE_DISPLAY
:
119 snprintf(buf
, bufsize
, "display image");
123 #ifdef HAS_BUTTON_HOLD
124 case WPS_TOKEN_MAIN_HOLD
:
125 snprintf(buf
, bufsize
, "mode hold");
129 #ifdef HAS_REMOTE_BUTTON_HOLD
130 case WPS_TOKEN_REMOTE_HOLD
:
131 snprintf(buf
, bufsize
, "mode remote hold");
135 case WPS_TOKEN_REPEAT_MODE
:
136 snprintf(buf
, bufsize
, "mode repeat");
139 case WPS_TOKEN_PLAYBACK_STATUS
:
140 snprintf(buf
, bufsize
, "mode playback");
143 case WPS_TOKEN_RTC_DAY_OF_MONTH
:
144 snprintf(buf
, bufsize
, "rtc: day of month (01..31)");
146 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED
:
147 snprintf(buf
, bufsize
,
148 "rtc: day of month, blank padded ( 1..31)");
150 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED
:
151 snprintf(buf
, bufsize
, "rtc: hour (00..23)");
153 case WPS_TOKEN_RTC_HOUR_24
:
154 snprintf(buf
, bufsize
, "rtc: hour ( 0..23)");
156 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED
:
157 snprintf(buf
, bufsize
, "rtc: hour (01..12)");
159 case WPS_TOKEN_RTC_HOUR_12
:
160 snprintf(buf
, bufsize
, "rtc: hour ( 1..12)");
162 case WPS_TOKEN_RTC_MONTH
:
163 snprintf(buf
, bufsize
, "rtc: month (01..12)");
165 case WPS_TOKEN_RTC_MINUTE
:
166 snprintf(buf
, bufsize
, "rtc: minute (00..59)");
168 case WPS_TOKEN_RTC_SECOND
:
169 snprintf(buf
, bufsize
, "rtc: second (00..59)");
171 case WPS_TOKEN_RTC_YEAR_2_DIGITS
:
172 snprintf(buf
, bufsize
,
173 "rtc: last two digits of year (00..99)");
175 case WPS_TOKEN_RTC_YEAR_4_DIGITS
:
176 snprintf(buf
, bufsize
, "rtc: year (1970...)");
178 case WPS_TOKEN_RTC_AM_PM_UPPER
:
179 snprintf(buf
, bufsize
,
180 "rtc: upper case AM or PM indicator");
182 case WPS_TOKEN_RTC_AM_PM_LOWER
:
183 snprintf(buf
, bufsize
,
184 "rtc: lower case am or pm indicator");
186 case WPS_TOKEN_RTC_WEEKDAY_NAME
:
187 snprintf(buf
, bufsize
,
188 "rtc: abbreviated weekday name (Sun..Sat)");
190 case WPS_TOKEN_RTC_MONTH_NAME
:
191 snprintf(buf
, bufsize
,
192 "rtc: abbreviated month name (Jan..Dec)");
194 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON
:
195 snprintf(buf
, bufsize
,
196 "rtc: day of week (1..7); 1 is Monday");
198 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN
:
199 snprintf(buf
, bufsize
,
200 "rtc: day of week (0..6); 0 is Sunday");
203 #if (CONFIG_CODEC == SWCODEC)
204 case WPS_TOKEN_CROSSFADE
:
205 snprintf(buf
, bufsize
, "crossfade");
208 case WPS_TOKEN_REPLAYGAIN
:
209 snprintf(buf
, bufsize
, "replaygain");
214 case WPS_TOKEN_ALBUMART_DISPLAY
:
215 snprintf(buf
, bufsize
, "album art display");
218 case WPS_TOKEN_ALBUMART_FOUND
:
219 snprintf(buf
, bufsize
, "%strack album art conditional",
224 #ifdef HAVE_LCD_BITMAP
225 case WPS_TOKEN_IMAGE_BACKDROP
:
226 snprintf(buf
, bufsize
, "backdrop image");
229 case WPS_TOKEN_IMAGE_PROGRESS_BAR
:
230 snprintf(buf
, bufsize
, "progressbar bitmap");
233 case WPS_TOKEN_PEAKMETER
:
234 snprintf(buf
, bufsize
, "peakmeter");
238 case WPS_TOKEN_PROGRESSBAR
:
239 snprintf(buf
, bufsize
, "progressbar");
242 #ifdef HAVE_LCD_CHARCELLS
243 case WPS_TOKEN_PLAYER_PROGRESSBAR
:
244 snprintf(buf
, bufsize
, "full line progressbar");
248 case WPS_TOKEN_TRACK_TIME_ELAPSED
:
249 snprintf(buf
, bufsize
, "time elapsed in track");
252 case WPS_TOKEN_TRACK_ELAPSED_PERCENT
:
253 snprintf(buf
, bufsize
, "played percentage of track");
256 case WPS_TOKEN_PLAYLIST_ENTRIES
:
257 snprintf(buf
, bufsize
, "number of entries in playlist");
260 case WPS_TOKEN_PLAYLIST_NAME
:
261 snprintf(buf
, bufsize
, "playlist name");
264 case WPS_TOKEN_PLAYLIST_POSITION
:
265 snprintf(buf
, bufsize
, "position in playlist");
268 case WPS_TOKEN_TRACK_TIME_REMAINING
:
269 snprintf(buf
, bufsize
, "time remaining in track");
272 case WPS_TOKEN_PLAYLIST_SHUFFLE
:
273 snprintf(buf
, bufsize
, "playlist shuffle mode");
276 case WPS_TOKEN_TRACK_LENGTH
:
277 snprintf(buf
, bufsize
, "track length");
280 case WPS_TOKEN_VOLUME
:
281 snprintf(buf
, bufsize
, "volume");
284 case WPS_TOKEN_METADATA_ARTIST
:
285 snprintf(buf
, bufsize
, "%strack artist",
289 case WPS_TOKEN_METADATA_COMPOSER
:
290 snprintf(buf
, bufsize
, "%strack composer",
294 case WPS_TOKEN_METADATA_ALBUM
:
295 snprintf(buf
, bufsize
, "%strack album",
299 case WPS_TOKEN_METADATA_GROUPING
:
300 snprintf(buf
, bufsize
, "%strack grouping",
304 case WPS_TOKEN_METADATA_GENRE
:
305 snprintf(buf
, bufsize
, "%strack genre",
309 case WPS_TOKEN_METADATA_DISC_NUMBER
:
310 snprintf(buf
, bufsize
, "%strack disc", next_str(next
));
313 case WPS_TOKEN_METADATA_TRACK_NUMBER
:
314 snprintf(buf
, bufsize
, "%strack number",
318 case WPS_TOKEN_METADATA_TRACK_TITLE
:
319 snprintf(buf
, bufsize
, "%strack title",
323 case WPS_TOKEN_METADATA_VERSION
:
324 snprintf(buf
, bufsize
, "%strack ID3 version",
328 case WPS_TOKEN_METADATA_ALBUM_ARTIST
:
329 snprintf(buf
, bufsize
, "%strack album artist",
333 case WPS_TOKEN_METADATA_COMMENT
:
334 snprintf(buf
, bufsize
, "%strack comment",
338 case WPS_TOKEN_METADATA_YEAR
:
339 snprintf(buf
, bufsize
, "%strack year", next_str(next
));
343 case WPS_TOKEN_DATABASE_PLAYCOUNT
:
344 snprintf(buf
, bufsize
, "track playcount (database)");
347 case WPS_TOKEN_DATABASE_RATING
:
348 snprintf(buf
, bufsize
, "track rating (database)");
351 case WPS_TOKEN_DATABASE_AUTOSCORE
:
352 snprintf(buf
, bufsize
, "track autoscore (database)");
356 case WPS_TOKEN_BATTERY_PERCENT
:
357 snprintf(buf
, bufsize
, "battery percentage");
360 case WPS_TOKEN_BATTERY_VOLTS
:
361 snprintf(buf
, bufsize
, "battery voltage");
364 case WPS_TOKEN_BATTERY_TIME
:
365 snprintf(buf
, bufsize
, "battery time left");
368 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED
:
369 snprintf(buf
, bufsize
, "battery charger connected");
372 case WPS_TOKEN_BATTERY_CHARGING
:
373 snprintf(buf
, bufsize
, "battery charging");
376 case WPS_TOKEN_BATTERY_SLEEPTIME
:
377 snprintf(buf
, bufsize
, "sleep timer");
380 case WPS_TOKEN_FILE_BITRATE
:
381 snprintf(buf
, bufsize
, "%sfile bitrate", next_str(next
));
384 case WPS_TOKEN_FILE_CODEC
:
385 snprintf(buf
, bufsize
, "%sfile codec", next_str(next
));
388 case WPS_TOKEN_FILE_FREQUENCY
:
389 snprintf(buf
, bufsize
, "%sfile audio frequency in Hz",
393 case WPS_TOKEN_FILE_FREQUENCY_KHZ
:
394 snprintf(buf
, bufsize
, "%sfile audio frequency in KHz",
398 case WPS_TOKEN_FILE_NAME
:
399 snprintf(buf
, bufsize
, "%sfile name", next_str(next
));
402 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION
:
403 snprintf(buf
, bufsize
, "%sfile name with extension",
407 case WPS_TOKEN_FILE_PATH
:
408 snprintf(buf
, bufsize
, "%sfile path", next_str(next
));
411 case WPS_TOKEN_FILE_SIZE
:
412 snprintf(buf
, bufsize
, "%sfile size", next_str(next
));
415 case WPS_TOKEN_FILE_VBR
:
416 snprintf(buf
, bufsize
, "%sfile is vbr", next_str(next
));
419 case WPS_TOKEN_FILE_DIRECTORY
:
420 snprintf(buf
, bufsize
, "%sfile directory, level: %d",
421 next_str(next
), token
->value
.i
);
424 #if (CONFIG_CODEC != MAS3507D)
425 case WPS_TOKEN_SOUND_PITCH
:
426 snprintf(buf
, bufsize
, "pitch value");
429 case WPS_VIEWPORT_ENABLE
:
430 snprintf(buf
, bufsize
, "enable VP:%d",
435 snprintf(buf
, bufsize
, "FIXME (code: %d)",
443 #if defined(SIMULATOR) || defined(__PCTOOL__)
444 static void dump_wps_tokens(struct wps_data
*data
)
446 struct wps_token
*token
;
450 int num_string_tokens
= 0;
452 /* Dump parsed WPS */
453 for (i
= 0, token
= data
->tokens
; i
< data
->num_tokens
; i
++, token
++)
455 get_token_desc(token
, data
, buf
, sizeof(buf
));
459 case WPS_TOKEN_STRING
:
463 case WPS_TOKEN_CONDITIONAL_START
:
467 case WPS_TOKEN_CONDITIONAL_END
:
475 if (wps_verbose_level
> 2)
477 for(j
= 0; j
< indent
; j
++) {
481 DEBUGF("[%3d] = (%2d) %s\n", i
, token
->type
, buf
);
485 if (wps_verbose_level
> 0)
488 DEBUGF("Number of string tokens: %d\n", num_string_tokens
);
493 static void print_line_info(struct wps_data
*data
)
496 struct wps_line
*line
;
497 struct wps_subline
*subline
;
499 if (wps_verbose_level
> 0)
501 DEBUGF("Number of viewports : %d\n", data
->num_viewports
);
502 for (v
= 0; v
< data
->num_viewports
; v
++)
504 DEBUGF("vp %d: First line: %d\n", v
, data
->viewports
[v
].first_line
);
505 DEBUGF("vp %d: Last line: %d\n", v
, data
->viewports
[v
].last_line
);
507 DEBUGF("Number of sublines : %d\n", data
->num_sublines
);
508 DEBUGF("Number of tokens : %d\n", data
->num_tokens
);
512 if (wps_verbose_level
> 1)
514 for (v
= 0; v
< data
->num_viewports
; v
++)
516 DEBUGF("Viewport %d - +%d+%d (%dx%d)\n",v
,data
->viewports
[v
].vp
.x
,
517 data
->viewports
[v
].vp
.y
,
518 data
->viewports
[v
].vp
.width
,
519 data
->viewports
[v
].vp
.height
);
520 for (i
= data
->viewports
[v
].first_line
, line
= &data
->lines
[data
->viewports
[v
].first_line
]; i
<= data
->viewports
[v
].last_line
; i
++,line
++)
522 DEBUGF("Line %2d (num_sublines=%d, first_subline=%d)\n",
523 i
, line
->num_sublines
, line
->first_subline_idx
);
525 for (j
= 0, subline
= data
->sublines
+ line
->first_subline_idx
;
526 j
< line
->num_sublines
; j
++, subline
++)
528 DEBUGF(" Subline %d: first_token=%3d, last_token=%3d",
529 j
, subline
->first_token_idx
,
530 wps_last_token_index(data
, i
, j
));
532 if (subline
->line_type
& WPS_REFRESH_SCROLL
)
533 DEBUGF(", scrolled");
534 else if (subline
->line_type
& WPS_REFRESH_PLAYER_PROGRESS
)
535 DEBUGF(", progressbar");
536 else if (subline
->line_type
& WPS_REFRESH_PEAK_METER
)
537 DEBUGF(", peakmeter");
548 static void print_wps_strings(struct wps_data
*data
)
550 int i
, len
, total_len
= 0, buf_used
= 0;
552 if (wps_verbose_level
> 1) DEBUGF("Strings:\n");
553 for (i
= 0; i
< data
->num_strings
; i
++)
555 len
= strlen(data
->strings
[i
]);
558 if (wps_verbose_level
> 1)
559 DEBUGF("%2d: (%2d) '%s'\n", i
, len
, data
->strings
[i
]);
561 if (wps_verbose_level
> 1) DEBUGF("\n");
563 if (wps_verbose_level
> 0)
565 DEBUGF("Number of unique strings: %d (max: %d)\n",
566 data
->num_strings
, WPS_MAX_STRINGS
);
567 DEBUGF("Total string length: %d\n", total_len
);
568 DEBUGF("String buffer used: %d out of %d bytes\n",
569 buf_used
, STRING_BUFFER_SIZE
);
575 void print_debug_info(struct wps_data
*data
, int fail
, int line
)
577 #if defined(SIMULATOR) || defined(__PCTOOL__)
578 if (debug_wps
&& wps_verbose_level
)
580 dump_wps_tokens(data
);
581 print_wps_strings(data
);
582 print_line_info(data
);
584 #endif /* SIMULATOR */
586 if (data
->num_tokens
>= WPS_MAX_TOKENS
- 1) {
587 DEBUGF("Warning: Max number of tokens was reached (%d)\n",
595 DEBUGF("Failed parsing on line %d : ", line
);
598 case PARSE_FAIL_UNCLOSED_COND
:
599 DEBUGF("Unclosed conditional");
602 case PARSE_FAIL_INVALID_CHAR
:
603 DEBUGF("unexpected conditional char after token %d: \"%s\"",
605 get_token_desc(&data
->tokens
[data
->num_tokens
-1], data
,
610 case PARSE_FAIL_COND_SYNTAX_ERROR
:
611 DEBUGF("Conditional syntax error after token %d: \"%s\"",
613 get_token_desc(&data
->tokens
[data
->num_tokens
-1], data
,
618 case PARSE_FAIL_COND_INVALID_PARAM
:
619 DEBUGF("Invalid parameter list for token %d: \"%s\"",
621 get_token_desc(&data
->tokens
[data
->num_tokens
], data
,