From b4a9564790575c645d855c23f7f2e07ae03c1c19 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Fri, 11 Jun 2010 04:47:46 +0000 Subject: Add my new parser playground to svn. Currently it can load a skin, and walk the parse tree and output the tags as required. It always chooses the first value for a conditional and subline, but a good working start there seems to be a error in the new parser if ROCKBOX is defined... need to fix that git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26757 a1c6a512-1295-4272-9138-f99709370657 --- utils/newparser/Makefile | 3 + utils/newparser/cabbiev2.220x176x16.wps | 42 +++++++++ utils/newparser/handle_tags.c | 157 ++++++++++++++++++++++++++++++++ utils/newparser/newparser.c | 81 ++++++++++++++++ utils/newparser/skin_render.c | 95 +++++++++++++++++++ utils/newparser/skin_structs.h | 68 ++++++++++++++ 6 files changed, 446 insertions(+) create mode 100644 utils/newparser/Makefile create mode 100644 utils/newparser/cabbiev2.220x176x16.wps create mode 100644 utils/newparser/handle_tags.c create mode 100644 utils/newparser/newparser.c create mode 100644 utils/newparser/skin_render.c create mode 100644 utils/newparser/skin_structs.h (limited to 'utils') diff --git a/utils/newparser/Makefile b/utils/newparser/Makefile new file mode 100644 index 0000000000..5a0e76f140 --- /dev/null +++ b/utils/newparser/Makefile @@ -0,0 +1,3 @@ +all: + gcc -I../themeeditor -g -Wall -o newparser newparser.c skin_render.c handle_tags.c ../themeeditor/skin_parser.c ../themeeditor/skin_scan.c ../themeeditor/skin_debug.c ../themeeditor/tag_table.c + diff --git a/utils/newparser/cabbiev2.220x176x16.wps b/utils/newparser/cabbiev2.220x176x16.wps new file mode 100644 index 0000000000..764a506e1f --- /dev/null +++ b/utils/newparser/cabbiev2.220x176x16.wps @@ -0,0 +1,42 @@ +# cabbie 2.0 default +# (C) 2007, Johannes Voggenthaler (Zinc Alloy) +#derived from "cabbie" (C) Yohann Misquitta +%wd +%X(wpsbackdrop-220x176x16.bmp) +%xl(A,lock-220x176x16.bmp,88,152,2) +%xl(B,battery-220x176x16.bmp,110,153,10) +%xl(C,volume-220x176x16.bmp,134,153,10) +%xl(D,shuffle-220x176x16.bmp,155,153) +%xl(E,repeat-220x176x16.bmp,182,151,4) +%xl(F,playmode-220x176x16.bmp,200,152,5) +%ax%Cl(15,32,75,75) +%pb(11,121,199,8,pb-220x176x16.bmp) +%?mh<%xd(Aa)|%xd(Ab)> +%?bp<%?bc<%xd(Ba)|%xd(Bb)>|%?bl<|%xd(Bc)|%xd(Bd)|%xd(Be)|%xd(Bf)|%xd(Bg)|%xd(Bh)|%xd(Bi)|%xd(Bj)>> +%?pv<%xd(Ca)|%xd(Cb)|%xd(Cc)|%xd(Cd)|%xd(Ce)|%xd(Cf)|%xd(Cg)|%xd(Ch)|%xd(Ci)|%xd(Cj)> +%?ps<%xd(D)> +%?mm<|%xd(Ea)|%xd(Eb)|%xd(Ec)|%xd(Ed)> +%?mp<%xd(Fa)|%xd(Fb)|%xd(Fc)|%xd(Fd)|%xd(Fe)> + +#NowPlaying +%?C<%Vd(a)%C|%Vd(b)> + +%ax%Vl(a,105,30,-,90,1) +%s%al%?it<%it|%fn> +%s%al%?ia<%ia|%?d(2)<%d(2)|%(root%)>> +%s%al%?id<%id|%?d(1)<%d(1)|%(root%)>> + +%s%al%Sx(Next Track:) +%s%al%?It<%It|%Fn> + +%Vl(b,0,30,-,90,1) +%s%ac%?it<%it|%fn> +%s%ac%?ia<%ia|%?d(2)<%d(2)|%(root%)>> +%s%ac%?id<%id|%?d(1)<%d(1)|%(root%)>> + +%ac%Sx(Next Track:) +%s%ac%?It<%It|%Fn> + + +%V(11,130,199,20,1) +%al%pc%ac%?Sr<%pe %Sx(of) %pp|%pp %Sx(of) %pe>%ar%pr diff --git a/utils/newparser/handle_tags.c b/utils/newparser/handle_tags.c new file mode 100644 index 0000000000..9047e0bae4 --- /dev/null +++ b/utils/newparser/handle_tags.c @@ -0,0 +1,157 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: tag_table.c 26346 2010-05-28 02:30:27Z jdgordon $ + * + * Copyright (C) 2010 Jonathan Gordon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "skin_parser.h" +#include "tag_table.h" +#include "skin_structs.h" + +typedef int (tag_handler)(struct skin *skin, struct skin_element* element, bool size_only); + + + +int handle_translate_string(struct skin *skin, struct skin_element* element, bool size_only) +{ + struct skin_token *token = &skin->tokens[skin->token_count++]; + token->type = element->tag->type; + token->next = false; + token->value.i = 1; /* actually need to fix this */ + return 0; +} + +int handle_this_or_next_track(struct skin *skin, struct skin_element* element, bool size_only) +{ + struct skin_token *token = &skin->tokens[skin->token_count++]; + token->type = element->tag->type; + token->next = element->tag->name[0] == 'D' + || element->tag->name[0] == 'I' + || element->tag->name[0] == 'F'; + if (element->tag->type == SKIN_TOKEN_FILE_DIRECTORY) + { + if (element->params_count != 1 || element->params[0].type_code != NUMERIC) + return -1; + token->value.i = element->params[0].data.numeric; + } + return 0; +} + +int handle_bar(struct skin *skin, struct skin_element* element, bool size_only) +{ + struct skin_token *token = &skin->tokens[skin->token_count++]; + struct progressbar bar; + /* %bar with no params is different for each one so handle that! */ + if (element->params_count == 0) + { + if (size_only) + { + if (element->tag->type == SKIN_TOKEN_PROGRESSBAR) + return sizeof(struct progressbar); + else + return 0; + } + } + else + { + if (size_only) + return sizeof(struct progressbar); + } + + token->type = element->tag->type; + return 0; +} + +struct tag_handler_table { + enum skin_token_type type; + int flags; + tag_handler *func; +}; + +struct tag_handler_table table[] = { + /* file tags */ + { SKIN_TOKEN_FILE_BITRATE , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_CODEC , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_FREQUENCY , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_NAME , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_PATH , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_SIZE , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_VBR , 0, handle_this_or_next_track }, + { SKIN_TOKEN_FILE_DIRECTORY , 0, handle_this_or_next_track }, + /* track metadata */ + { SKIN_TOKEN_METADATA_ARTIST , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_COMPOSER , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_ALBUM , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_GROUPING , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_GENRE , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_DISC_NUMBER , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_TRACK_TITLE , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_VERSION , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_YEAR , 0, handle_this_or_next_track }, + { SKIN_TOKEN_METADATA_COMMENT , 0, handle_this_or_next_track }, + /* misc */ + { SKIN_TOKEN_TRANSLATEDSTRING, 0, handle_translate_string}, +}; + +int handle_tree(struct skin *skin, struct skin_element* tree) +{ + /* for later.. do this in two steps + * 1) count how much skin buffer is needed + * 2) do the actual tree->skin conversion + */ + struct skin_element* element = tree; + int counter; + while (element) + { + if (element->type == TAG) + { + int i; + for(i=0;itag->type) + { + table[i].func(skin, element, false); + break; + } + } + } + else if (element->type == TEXT) + { + /* handle */ + } + + counter = 0; + while (counter < element->children_count) + { + int ret = handle_tree(skin, element->children[counter]); + counter++; + } + element = element->next; + } + return 0; +} diff --git a/utils/newparser/newparser.c b/utils/newparser/newparser.c new file mode 100644 index 0000000000..2f58b64d15 --- /dev/null +++ b/utils/newparser/newparser.c @@ -0,0 +1,81 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: tag_table.c 26346 2010-05-28 02:30:27Z jdgordon $ + * + * Copyright (C) 2010 Jonathan Gordon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "skin_parser.h" +#include "tag_table.h" +#include "skin_structs.h" + +int handle_tree(struct skin *skin, struct skin_element* tree); +void skin_render(struct skin_element* root); + +int main(int argc, char* argv[]) +{ + char buffer[10*1024], temp[512]; + FILE *in; + int filearg = 1, i=0; + if( (argc < 2) || + strcmp(argv[1],"-h") == 0 || + strcmp(argv[1],"--help") == 0 ) + { + printf("Usage: %s infile \n", argv[0]); + return 0; + } + + while ((argc > filearg) && argv[filearg][0] == '-') + { + i=1; + while (argv[filearg][i]) + { + switch(argv[filearg][i]) + { + } + i++; + } + filearg++; + } + if (argc == filearg) + { + printf("Missing input filename\n"); + return 1; + } + + in = fopen(argv[filearg], "r"); + if (!in) + return 1; + while (fgets(temp, 512, in)) + strcat(buffer, temp); + fclose(in); + filearg++; + + struct skin_element* tree = skin_parse(buffer); + struct skin skin; + skin_render(tree); + //handle_tree(&skin, tree); + + skin_free_tree(tree); + return 0; +} diff --git a/utils/newparser/skin_render.c b/utils/newparser/skin_render.c new file mode 100644 index 0000000000..68dfd78949 --- /dev/null +++ b/utils/newparser/skin_render.c @@ -0,0 +1,95 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: skin_parser.c 26752 2010-06-10 21:22:16Z bieber $ + * + * Copyright (C) 2010 Jonathan Gordon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include + +#include "skin_parser.h" +#include "skin_debug.h" +#include "tag_table.h" +#include "symbols.h" +#include "skin_scan.h" + +void skin_render_alternator(struct skin_element* alternator); + +/* Draw a LINE element onto the display */ +void skin_render_line(struct skin_element* line) +{ + int i=0, value; + struct skin_element *child = line->children[0]; + while (child) + { + switch (child->type) + { + case CONDITIONAL: + value = 0; /* actually get it from the token :p */ + if (value >= child->children_count) + value = child->children_count-1; + if (child->children[value]->type == SUBLINES) + skin_render_alternator(child->children[value]); + else if (child->children[value]->type == LINE) + skin_render_line(child->children[value]); + break; + case TAG: + printf("%%%s", child->tag->name); + break; + case TEXT: + printf("%s", (char*)(child->data)); + break; + case COMMENT: + default: + break; + } + child = child->next; + } + printf("\n"); /* might be incorrect */ +} + +void skin_render_alternator(struct skin_element* alternator) +{ + /*TODO Choose which subline to draw */ + skin_render_line(alternator->children[0]); +} + +void skin_render_viewport(struct skin_element* viewport) +{ + struct skin_element *line = viewport; + while (line) + { + if (line->type == SUBLINES) + skin_render_alternator(line); + else if (line->type == LINE) + skin_render_line(line); + line = line->next; + } +} + +void skin_render(struct skin_element* root) +{ + struct skin_element* viewport = root; + while (viewport) + { + skin_render_viewport(viewport->children[viewport->children_count-1]); + viewport = viewport->next; + } +} diff --git a/utils/newparser/skin_structs.h b/utils/newparser/skin_structs.h new file mode 100644 index 0000000000..c86e683589 --- /dev/null +++ b/utils/newparser/skin_structs.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: tag_table.c 26346 2010-05-28 02:30:27Z jdgordon $ + * + * Copyright (C) 2010 Jonathan Gordon + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "skin_parser.h" +#include "tag_table.h" + +struct skin_token { + enum skin_token_type type; /* enough to store the token 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 int i; + void* data; + } value; +}; + +#define MAX_TOKENS 10000 +struct skin +{ + int token_count; + struct skin_token tokens[MAX_TOKENS]; +}; + + +struct progressbar { + enum skin_token_type type; + struct viewport *vp; + /* regular pb */ + short x; + /* >=0: explicitly set in the tag -> y-coord within the viewport + <0 : not set in the tag -> negated 1-based line number within + the viewport. y-coord will be computed based on the font height */ + short y; + short width; + short height; + bool follow_lang_direction; + /*progressbar image*/ + // struct bitmap bm; + bool have_bitmap_pb; +}; -- cgit v1.2.3