From 36b934d241d2560be6693f90c9aba501a1ec0ae7 Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Thu, 17 Jun 2010 06:52:02 +0000 Subject: Move the skin parser to a seperate library git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26877 a1c6a512-1295-4272-9138-f99709370657 --- lib/skin_parser/Makefile | 28 + lib/skin_parser/skin_debug.c | 262 ++++++++++ lib/skin_parser/skin_debug.h | 48 ++ lib/skin_parser/skin_parser.c | 923 +++++++++++++++++++++++++++++++++ lib/skin_parser/skin_parser.h | 138 +++++ lib/skin_parser/skin_scan.c | 218 ++++++++ lib/skin_parser/skin_scan.h | 44 ++ lib/skin_parser/symbols.h | 49 ++ lib/skin_parser/tag_table.c | 256 +++++++++ lib/skin_parser/tag_table.h | 307 +++++++++++ utils/themeeditor/parser/skin_debug.c | 262 ---------- utils/themeeditor/parser/skin_debug.h | 48 -- utils/themeeditor/parser/skin_parser.c | 923 --------------------------------- utils/themeeditor/parser/skin_parser.h | 138 ----- utils/themeeditor/parser/skin_scan.c | 218 -------- utils/themeeditor/parser/skin_scan.h | 44 -- utils/themeeditor/parser/symbols.h | 49 -- utils/themeeditor/parser/tag_table.c | 256 --------- utils/themeeditor/parser/tag_table.h | 307 ----------- utils/themeeditor/themeeditor.pro | 29 +- 20 files changed, 2290 insertions(+), 2257 deletions(-) create mode 100644 lib/skin_parser/Makefile create mode 100644 lib/skin_parser/skin_debug.c create mode 100644 lib/skin_parser/skin_debug.h create mode 100644 lib/skin_parser/skin_parser.c create mode 100644 lib/skin_parser/skin_parser.h create mode 100644 lib/skin_parser/skin_scan.c create mode 100644 lib/skin_parser/skin_scan.h create mode 100644 lib/skin_parser/symbols.h create mode 100644 lib/skin_parser/tag_table.c create mode 100644 lib/skin_parser/tag_table.h delete mode 100644 utils/themeeditor/parser/skin_debug.c delete mode 100644 utils/themeeditor/parser/skin_debug.h delete mode 100644 utils/themeeditor/parser/skin_parser.c delete mode 100644 utils/themeeditor/parser/skin_parser.h delete mode 100644 utils/themeeditor/parser/skin_scan.c delete mode 100644 utils/themeeditor/parser/skin_scan.h delete mode 100644 utils/themeeditor/parser/symbols.h delete mode 100644 utils/themeeditor/parser/tag_table.c delete mode 100644 utils/themeeditor/parser/tag_table.h diff --git a/lib/skin_parser/Makefile b/lib/skin_parser/Makefile new file mode 100644 index 0000000000..5c1be67578 --- /dev/null +++ b/lib/skin_parser/Makefile @@ -0,0 +1,28 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +BUILDDIR ?= . + +SRC = skin_parser.c skin_debug.c skin_scan.c tag_table.c +OBJ := $(patsubst %.c,$(BUILDDIR)/%.o,$(SRC)) +OUT = $(BUILDDIR)/libskin_parser.a +CC = gcc +AR = ar +INCLUDES = -I. + +default: $(OUT) + +$(BUILDDIR)/%.o: %.c + $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ + +$(OUT): $(OBJ) + $(AR) rcs $(OUT) $(OBJ) + +clean: + rm -f $(OBJ) $(OUT) diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c new file mode 100644 index 0000000000..549f7b9e6c --- /dev/null +++ b/lib/skin_parser/skin_debug.c @@ -0,0 +1,262 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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 "skin_parser.h" +#include "skin_debug.h" +#include "tag_table.h" + +/* Global variables for debug output */ +int debug_indent_level = 0; +extern int skin_line; + +/* Global error variables */ +int error_line; +char* error_message; + +/* Debugging functions */ +void skin_error(enum skin_errorcode error) +{ + + error_line = skin_line; + + switch(error) + { + case MEMORY_LIMIT_EXCEEDED: + error_message = "Memory limit exceeded"; + break; + case NEWLINE_EXPECTED: + error_message = "Newline expected"; + break; + case ILLEGAL_TAG: + error_message = "Illegal tag"; + break; + case ARGLIST_EXPECTED: + error_message = "Argument list expected"; + break; + case TOO_MANY_ARGS: + error_message = "Too many arguments given"; + break; + case DEFAULT_NOT_ALLOWED: + error_message = "Argument can not be set to default"; + break; + case UNEXPECTED_NEWLINE: + error_message = "Unexpected newline"; + break; + case INSUFFICIENT_ARGS: + error_message = "Not enough arguments"; + break; + case INT_EXPECTED: + error_message = "Expected integer"; + break; + case SEPERATOR_EXPECTED: + error_message = "Expected argument seperator"; + break; + case CLOSE_EXPECTED: + error_message = "Expected list close"; + break; + case MULTILINE_EXPECTED: + error_message = "Expected subline seperator"; + break; + }; + +} + +int skin_error_line() +{ + return error_line; +} + +char* skin_error_message() +{ + return error_message; +} + +void skin_clear_errors() +{ + error_line = 0; + error_message = NULL; +} + +void skin_debug_tree(struct skin_element* root) +{ + int i; + char *text; + + struct skin_element* current = root; + + while(current) + { + skin_debug_indent(); + + switch(current->type) + { + case UNKNOWN: + printf("[ Unknown element.. error\n]"); + break; + + case VIEWPORT: + printf("[ Viewport \n"); + + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + + printf("]"); + break; + + case TEXT: + text = current->data; + printf("[ Plain text on line %d : %s ]\n", current->line, text); + break; + + case COMMENT: + text = current->data; + printf("[ Comment on line %d: ", current->line); + for(i = 0; i < (int)strlen(text); i++) + { + if(text[i] == '\n') + printf("\\n"); + else + printf("%c", text[i]); + } + printf(" ]\n"); + break; + + case TAG: + printf("[ %s tag on line %d with %d arguments\n", + current->tag->name, + current->line, current->params_count); + debug_indent_level++; + skin_debug_params(current->params_count, current->params); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + break; + + case SUBLINES: + printf("[ Alternator on line %d with %d sublines \n", current->line, + current->children_count); + debug_indent_level++; + for(i = 0; i < current->children_count; i++) + { + skin_debug_tree(current->children[i]); + } + debug_indent_level--; + + skin_debug_indent(); + printf("]\n"); + break; + + case CONDITIONAL: + printf("[ Conditional tag on line %d with %d enumerations \n", + current->line, current->children_count - 1); + debug_indent_level++; + + skin_debug_indent(); + printf("[ Condition tag \n"); + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + for(i = 1; i < current->children_count; i++) + { + skin_debug_indent(); + printf("[ Enumeration %d\n", i - 1); + debug_indent_level++; + skin_debug_tree(current->children[i]); + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + } + + debug_indent_level--; + skin_debug_indent(); + printf("]\n"); + + + break; + + case LINE: + printf("[ Logical line on line %d\n", current->line); + + debug_indent_level++; + skin_debug_tree(current->children[0]); + debug_indent_level--; + + skin_debug_indent(); + printf("]\n"); + break; + } + + current = current->next; + } + +} + +void skin_debug_params(int count, struct skin_tag_parameter params[]) +{ + int i; + for(i = 0; i < count; i++) + { + + skin_debug_indent(); + switch(params[i].type) + { + case DEFAULT: + printf("[-]"); + break; + + case STRING: + printf("[%s]", params[i].data.text); + break; + + case NUMERIC: + printf("[%d]", params[i].data.numeric); + break; + + case CODE: + printf("[ WPS Code: \n"); + debug_indent_level++; + skin_debug_tree(params[i].data.code); + debug_indent_level--; + skin_debug_indent(); + printf("]"); + break; + } + + printf("\n"); + + } +} + +void skin_debug_indent() +{ + int i; + for(i = 0; i < debug_indent_level; i++) + printf(" "); +} diff --git a/lib/skin_parser/skin_debug.h b/lib/skin_parser/skin_debug.h new file mode 100644 index 0000000000..a550dc4c7b --- /dev/null +++ b/lib/skin_parser/skin_debug.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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. + * + ****************************************************************************/ + + +#ifndef SKIN_DEBUG_H +#define SKIN_DEBUG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "skin_parser.h" + +/* Debugging functions */ +void skin_error(enum skin_errorcode error); +int skin_error_line(); +char* skin_error_message(); +void skin_clear_errors(); +void skin_debug_tree(struct skin_element* root); + +/* Auxiliary debug functions */ +void skin_debug_params(int count, struct skin_tag_parameter params[]); +void skin_debug_indent(); + +#ifdef __cplusplus +} +#endif + +#endif // SKIN_DEBUG_H diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c new file mode 100644 index 0000000000..93a71919bf --- /dev/null +++ b/lib/skin_parser/skin_parser.c @@ -0,0 +1,923 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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" + +#ifdef ROCKBOX +/* Declaration of parse tree buffer */ +#define SKIN_MAX_MEMORY (30*1024) +static char skin_parse_tree[SKIN_MAX_MEMORY]; +static char *skin_buffer; +#endif + +/* Global variables for the parser */ +int skin_line = 0; + +/* Auxiliary parsing functions (not visible at global scope) */ +static struct skin_element* skin_parse_viewport(char** document); +static struct skin_element* skin_parse_line(char** document); +static struct skin_element* skin_parse_line_optional(char** document, + int conditional); +static struct skin_element* skin_parse_sublines(char** document); +static struct skin_element* skin_parse_sublines_optional(char** document, + int conditional); + +static int skin_parse_tag(struct skin_element* element, char** document); +static int skin_parse_text(struct skin_element* element, char** document, + int conditional); +static int skin_parse_conditional(struct skin_element* element, + char** document); +static int skin_parse_comment(struct skin_element* element, char** document); +static struct skin_element* skin_parse_code_as_arg(char** document); + +struct skin_element* skin_parse(const char* document) +{ + + struct skin_element* root = NULL; + struct skin_element* last = NULL; + + struct skin_element** to_write = 0; + + char* cursor = (char*)document; /*Keeps track of location in the document*/ +#ifdef ROCKBOX + /* FIXME */ + skin_buffer = &skin_parse_tree[0]; +#endif + + skin_line = 1; + + skin_clear_errors(); + + while(*cursor != '\0') + { + + if(!root) + to_write = &root; + else + to_write = &(last->next); + + + *to_write = skin_parse_viewport(&cursor); + last = *to_write; + if(!last) + { + skin_free_tree(root); /* Clearing any memory already used */ + return NULL; + } + + /* Making sure last is at the end */ + while(last->next) + last = last->next; + + } + + return root; + +} + +static struct skin_element* skin_parse_viewport(char** document) +{ + + struct skin_element* root = NULL; + struct skin_element* last = NULL; + struct skin_element* retval = NULL; + + retval = skin_alloc_element(); + retval->type = VIEWPORT; + retval->children_count = 1; + retval->line = skin_line; + + struct skin_element** to_write = 0; + + char* cursor = *document; /* Keeps track of location in the document */ + char* bookmark; /* Used when we need to look ahead */ + + int sublines = 0; /* Flag for parsing sublines */ + + /* Parsing out the viewport tag if there is one */ + if(check_viewport(cursor)) + { + skin_parse_tag(retval, &cursor); + if(*cursor == '\n') + { + cursor++; + skin_line++; + } + } + + retval->children_count = 1; + retval->children = skin_alloc_children(1); + + + do + { + + /* First, we check to see if this line will contain sublines */ + bookmark = cursor; + sublines = 0; + while(*cursor != '\n' && *cursor != '\0' + && !(check_viewport(cursor) && cursor != *document)) + { + if(*cursor == MULTILINESYM) + { + sublines = 1; + break; + } + else if(*cursor == TAGSYM) + { + /* A ';' directly after a '%' doesn't count */ + cursor ++; + + if(*cursor == '\0') + break; + + cursor++; + } + else if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else + { + /* Advancing the cursor as normal */ + cursor++; + } + } + cursor = bookmark; + + if(!root) + to_write = &root; + else + to_write = &(last->next); + + if(sublines) + { + *to_write = skin_parse_sublines(&cursor); + last = *to_write; + if(!last) + return NULL; + } + else + { + + *to_write = skin_parse_line(&cursor); + last = *to_write; + if(!last) + return NULL; + + } + + /* Making sure last is at the end */ + while(last->next) + last = last->next; + + if(*cursor == '\n') + { + cursor++; + skin_line++; + } + } + while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document)); + + *document = cursor; + + retval->children[0] = root; + return retval; + +} + +/* Auxiliary Parsing Functions */ + +static struct skin_element* skin_parse_line(char**document) +{ + + return skin_parse_line_optional(document, 0); + +} + + +/* + * If conditional is set to true, then this will break upon encountering + * SEPERATESYM. This should only be used when parsing a line inside a + * conditional, otherwise just use the wrapper function skin_parse_line() + */ +static struct skin_element* skin_parse_line_optional(char** document, + int conditional) +{ + char* cursor = *document; + + struct skin_element* root = NULL; + struct skin_element* current = NULL; + struct skin_element* retval = NULL; + + /* A wrapper for the line */ + retval = skin_alloc_element(); + retval->type = LINE; + retval->line = skin_line; + if(*cursor != '\0' && *cursor != '\n' + && !(conditional && (*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM))) + { + retval->children_count = 1; + } + else + { + retval->children_count = 0; + } + + if(retval->children_count > 0) + retval->children = skin_alloc_children(1); + + while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional) + && !(check_viewport(cursor) && cursor != *document)) + { + /* Allocating memory if necessary */ + if(root) + { + current->next = skin_alloc_element(); + current = current->next; + } + else + { + current = skin_alloc_element(); + root = current; + } + + /* Parsing the current element */ + if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM) + { + if(!skin_parse_conditional(current, &cursor)) + return NULL; + } + else if(*cursor == TAGSYM && !find_escape_character(cursor[1])) + { + if(!skin_parse_tag(current, &cursor)) + return NULL; + } + else if(*cursor == COMMENTSYM) + { + if(!skin_parse_comment(current, &cursor)) + return NULL; + } + else + { + if(!skin_parse_text(current, &cursor, conditional)) + return NULL; + } + } + + /* Moving up the calling function's pointer */ + *document = cursor; + + if(root) + retval->children[0] = root; + return retval; +} + +static struct skin_element* skin_parse_sublines(char** document) +{ + return skin_parse_sublines_optional(document, 0); +} + +static struct skin_element* skin_parse_sublines_optional(char** document, + int conditional) +{ + struct skin_element* retval; + char* cursor = *document; + int sublines = 1; + int i; + + retval = skin_alloc_element(); + retval->type = SUBLINES; + retval->next = NULL; + retval->line = skin_line; + + /* First we count the sublines */ + while(*cursor != '\0' && *cursor != '\n' + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional) + && !(check_viewport(cursor) && cursor != *document)) + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0' || *cursor == '\n') + break; + cursor++; + } + else if(*cursor == MULTILINESYM) + { + sublines++; + cursor++; + } + else + { + cursor++; + } + } + + /* ...and then we parse them */ + retval->children_count = sublines; + retval->children = skin_alloc_children(sublines); + + cursor = *document; + for(i = 0; i < sublines; i++) + { + retval->children[i] = skin_parse_line_optional(&cursor, conditional); + skip_whitespace(&cursor); + + if(*cursor != MULTILINESYM && i != sublines - 1) + { + skin_error(MULTILINE_EXPECTED); + return NULL; + } + else if(i != sublines - 1) + { + cursor++; + } + } + + *document = cursor; + + return retval; +} + +static int skin_parse_tag(struct skin_element* element, char** document) +{ + + char* cursor = *document + 1; + char* bookmark; + + char tag_name[3]; + char* tag_args; + struct tag_info *tag; + + int num_args = 1; + int i; + int star = 0; /* Flag for the all-or-none option */ + int req_args; /* To mark when we enter optional arguments */ + + int optional = 0; + + /* Checking the tag name */ + tag_name[0] = cursor[0]; + tag_name[1] = cursor[1]; + tag_name[2] = '\0'; + + /* First we check the two characters after the '%', then a single char */ + tag = find_tag(tag_name); + + if(!tag) + { + tag_name[1] = '\0'; + tag = find_tag(tag_name); + cursor++; + } + else + { + cursor += 2; + } + + if(!tag) + { + skin_error(ILLEGAL_TAG); + return 0; + } + + /* Copying basic tag info */ + if(element->type != CONDITIONAL && element->type != VIEWPORT) + element->type = TAG; + element->tag = tag; + tag_args = tag->params; + element->line = skin_line; + + /* Checking for the * flag */ + if(tag_args[0] == '*') + { + star = 1; + tag_args++; + } + + /* If this tag has no arguments, we can bail out now */ + if(strlen(tag_args) == 0 + || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) + || (star && *cursor != ARGLISTOPENSYM)) + { + *document = cursor; + return 1; + } + + /* Checking the number of arguments and allocating args */ + if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|') + { + skin_error(ARGLIST_EXPECTED); + return 0; + } + else + { + cursor++; + } + + bookmark = cursor; + while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) + { + /* Skipping over escaped characters */ + if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0') + break; + cursor++; + } + else if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ARGLISTSEPERATESYM) + { + num_args++; + cursor++; + } + else + { + cursor++; + } + } + + cursor = bookmark; /* Restoring the cursor */ + element->params_count = num_args; + element->params = skin_alloc_params(num_args); + + /* Now we have to actually parse each argument */ + for(i = 0; i < num_args; i++) + { + /* Making sure we haven't run out of arguments */ + if(*tag_args == '\0') + { + skin_error(TOO_MANY_ARGS); + return 0; + } + + /* Checking for the optional bar */ + if(*tag_args == '|') + { + optional = 1; + req_args = i; + tag_args++; + } + + /* Scanning the arguments */ + skip_whitespace(&cursor); + + + /* Checking for comments */ + if(*cursor == COMMENTSYM) + skip_comment(&cursor); + + /* Storing the type code */ + element->params[i].type_code = *tag_args; + + /* Checking a nullable argument for null */ + if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) + { + if(islower(*tag_args)) + { + element->params[i].type = DEFAULT; + cursor++; + } + else + { + skin_error(DEFAULT_NOT_ALLOWED); + return 0; + } + } + else if(tolower(*tag_args) == 'i') + { + /* Scanning an int argument */ + if(!isdigit(*cursor) && *cursor != '-') + { + skin_error(INT_EXPECTED); + return 0; + } + + element->params[i].type = NUMERIC; + element->params[i].data.numeric = scan_int(&cursor); + } + else if(tolower(*tag_args) == 'n' || + tolower(*tag_args) == 's' || tolower(*tag_args) == 'f') + { + /* Scanning a string argument */ + element->params[i].type = STRING; + element->params[i].data.text = scan_string(&cursor); + + } + else if(tolower(*tag_args) == 'c') + { + /* Recursively parsing a code argument */ + element->params[i].type = CODE; + element->params[i].data.code = skin_parse_code_as_arg(&cursor); + if(!element->params[i].data.code) + return 0; + } + + skip_whitespace(&cursor); + + if(*cursor != ARGLISTSEPERATESYM && i < num_args - 1) + { + skin_error(SEPERATOR_EXPECTED); + return 0; + } + else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1) + { + skin_error(CLOSE_EXPECTED); + return 0; + } + else + { + cursor++; + } + + if (*tag_args != 'N') + tag_args++; + + /* Checking for the optional bar */ + if(*tag_args == '|') + { + optional = 1; + req_args = i + 1; + tag_args++; + } + + } + + /* Checking for a premature end */ + if(*tag_args != '\0' && !optional) + { + skin_error(INSUFFICIENT_ARGS); + return 0; + } + + *document = cursor; + + return 1; +} + +/* + * If the conditional flag is set true, then parsing text will stop at an + * ARGLISTSEPERATESYM. Only set that flag when parsing within a conditional + */ +static int skin_parse_text(struct skin_element* element, char** document, + int conditional) +{ + char* cursor = *document; + int length = 0; + int dest; + char *text = NULL; + + /* First figure out how much text we're copying */ + while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM + && *cursor != COMMENTSYM + && !((*cursor == ARGLISTSEPERATESYM + || *cursor == ARGLISTCLOSESYM + || *cursor == ENUMLISTSEPERATESYM + || *cursor == ENUMLISTCLOSESYM) + && conditional)) + { + /* Dealing with possibility of escaped characters */ + if(*cursor == TAGSYM) + { + if(find_escape_character(cursor[1])) + cursor++; + else + break; + } + + length++; + cursor++; + } + + cursor = *document; + + /* Copying the text into the element struct */ + element->type = TEXT; + element->line = skin_line; + element->next = NULL; + element->data = text = skin_alloc_string(length); + + for(dest = 0; dest < length; dest++) + { + /* Advancing cursor if we've encountered an escaped character */ + if(*cursor == TAGSYM) + cursor++; + + text[dest] = *cursor; + cursor++; + } + text[length] = '\0'; + + *document = cursor; + + return 1; +} + +static int skin_parse_conditional(struct skin_element* element, char** document) +{ + + char* cursor = *document + 1; /* Starting past the "%" */ + char* bookmark; + int children = 1; + int i; + + element->type = CONDITIONAL; + element->line = skin_line; + + /* Parsing the tag first */ + if(!skin_parse_tag(element, &cursor)) + return 0; + + /* Counting the children */ + if(*(cursor++) != ENUMLISTOPENSYM) + { + skin_error(ARGLIST_EXPECTED); + return 0; + } + bookmark = cursor; + while(*cursor != ENUMLISTCLOSESYM && *cursor != '\n' && *cursor != '\0') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else if(*cursor == TAGSYM) + { + cursor++; + if(*cursor == '\0' || *cursor == '\n') + break; + cursor++; + } + else if(*cursor == ENUMLISTSEPERATESYM) + { + children++; + cursor++; + } + else + { + cursor++; + } + } + cursor = bookmark; + + /* Parsing the children */ + element->children = skin_alloc_children(children); + element->children_count = children; + + for(i = 0; i < children; i++) + { + element->children[i] = skin_parse_code_as_arg(&cursor); + skip_whitespace(&cursor); + + if(i < children - 1 && *cursor != ENUMLISTSEPERATESYM) + { + skin_error(SEPERATOR_EXPECTED); + return 0; + } + else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) + { + skin_error(CLOSE_EXPECTED); + return 0; + } + else + { + cursor++; + } + } + + *document = cursor; + + return 1; +} + +static int skin_parse_comment(struct skin_element* element, char** document) +{ + char* cursor = *document; + char* text = NULL; + + int length; + /* + * Finding the index of the ending newline or null-terminator + * The length of the string of interest doesn't include the leading #, the + * length we need to reserve is the same as the index of the last character + */ + for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++); + + element->type = COMMENT; + element->line = skin_line; +#ifdef ROCKBOX + element->data = NULL; +#else + element->data = text = skin_alloc_string(length); + /* We copy from one char past cursor to leave out the # */ + memcpy((void*)text, (void*)(cursor + 1), + sizeof(char) * (length-1)); + text[length - 1] = '\0'; +#endif + if(cursor[length] == '\n') + skin_line++; + + *document += (length); /* Move cursor up past # and all text */ + if(**document == '\n') + (*document)++; + + return 1; +} + +static struct skin_element* skin_parse_code_as_arg(char** document) +{ + + int sublines = 0; + char* cursor = *document; + + /* Checking for sublines */ + while(*cursor != '\n' && *cursor != '\0' + && *cursor != ENUMLISTSEPERATESYM && *cursor != ARGLISTSEPERATESYM + && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM) + { + if(*cursor == MULTILINESYM) + { + sublines = 1; + break; + } + else if(*cursor == TAGSYM) + { + /* A ';' directly after a '%' doesn't count */ + cursor ++; + + if(*cursor == '\0') + break; + + cursor++; + } + else if(*cursor == ARGLISTOPENSYM) + { + skip_arglist(&cursor); + } + else if(*cursor == ENUMLISTOPENSYM) + { + skip_enumlist(&cursor); + } + else + { + /* Advancing the cursor as normal */ + cursor++; + } + } + + if(sublines) + return skin_parse_sublines_optional(document, 1); + else + return skin_parse_line_optional(document, 1); +} + + +/* Memory management */ +char* skin_alloc(size_t size) +{ +#ifdef ROCKBOX + char *retval = skin_buffer; + skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3); + return retval; +#else + return malloc(size); +#endif +} + +struct skin_element* skin_alloc_element() +{ + struct skin_element* retval = (struct skin_element*) + skin_alloc(sizeof(struct skin_element)); + retval->type = UNKNOWN; + retval->next = NULL; + retval->tag = NULL; + retval->params_count = 0; + retval->children_count = 0; + + return retval; + +} + +struct skin_tag_parameter* skin_alloc_params(int count) +{ + size_t size = sizeof(struct skin_tag_parameter) * count; + return (struct skin_tag_parameter*)skin_alloc(size); + +} + +char* skin_alloc_string(int length) +{ + return (char*)skin_alloc(sizeof(char) * (length + 1)); +} + +struct skin_element** skin_alloc_children(int count) +{ + return (struct skin_element**) + skin_alloc(sizeof(struct skin_element*) * count); +} + +void skin_free_tree(struct skin_element* root) +{ +#ifndef ROCKBOX + int i; + + /* First make the recursive call */ + if(!root) + return; + skin_free_tree(root->next); + + /* Free any text */ + if(root->type == TEXT || root->type == COMMENT) + free(root->data); + + /* Then recursively free any children, before freeing their pointers */ + for(i = 0; i < root->children_count; i++) + skin_free_tree(root->children[i]); + if(root->children_count > 0) + free(root->children); + + /* Free any parameters, making sure to deallocate strings */ + for(i = 0; i < root->params_count; i++) + if(root->params[i].type == STRING) + free(root->params[i].data.text); + if(root->params_count > 0) + free(root->params); + + /* Finally, delete root's memory */ + free(root); +#else + (void)root; +#endif +} diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h new file mode 100644 index 0000000000..1fc4a7ae6b --- /dev/null +++ b/lib/skin_parser/skin_parser.h @@ -0,0 +1,138 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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. + * + ****************************************************************************/ + +#ifndef GENERIC_PARSER_H +#define GENERIC_PARSER_H + +#ifdef __cplusplus +extern "C" +{ +#endif +#include + +/******************************************************************** + ****** Data Structures ********************************************* + *******************************************************************/ + +/* Possible types of element in a WPS file */ +enum skin_element_type +{ + UNKNOWN = -1, + VIEWPORT, + LINE, + SUBLINES, + CONDITIONAL, + TAG, + TEXT, + COMMENT, +}; + +enum skin_errorcode +{ + MEMORY_LIMIT_EXCEEDED, + NEWLINE_EXPECTED, + ILLEGAL_TAG, + ARGLIST_EXPECTED, + TOO_MANY_ARGS, + DEFAULT_NOT_ALLOWED, + UNEXPECTED_NEWLINE, + INSUFFICIENT_ARGS, + INT_EXPECTED, + SEPERATOR_EXPECTED, + CLOSE_EXPECTED, + MULTILINE_EXPECTED +}; + +/* Holds a tag parameter, either numeric or text */ +struct skin_tag_parameter +{ + enum + { + NUMERIC, + STRING, + CODE, + DEFAULT + } type; + + union + { + int numeric; + char* text; + struct skin_element* code; + } data; + + char type_code; + +}; + +/* Defines an element of a SKIN file */ +struct skin_element +{ + /* Defines what type of element it is */ + enum skin_element_type type; + + /* The line on which it's defined in the source file */ + int line; + + /* Placeholder for element data + * TEXT and COMMENT uses it for the text string + * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage + */ + void* data; + + /* The tag or conditional name */ + struct tag_info *tag; + + /* Pointer to and size of an array of parameters */ + int params_count; + struct skin_tag_parameter* params; + + /* Pointer to and size of an array of children */ + int children_count; + struct skin_element** children; + + /* Link to the next element */ + struct skin_element* next; +}; + +/*********************************************************************** + ***** Functions ******************************************************* + **********************************************************************/ + +/* Parses a WPS document and returns a list of skin_element + structures. */ +struct skin_element* skin_parse(const char* document); + +/* Memory management functions */ +char *skin_alloc(size_t size); +struct skin_element* skin_alloc_element(); +struct skin_element** skin_alloc_children(int count); +struct skin_tag_parameter* skin_alloc_params(int count); +char* skin_alloc_string(int length); + +void skin_free_tree(struct skin_element* root); + + +#ifdef __cplusplus +} +#endif + +#endif /* GENERIC_PARSER_H */ diff --git a/lib/skin_parser/skin_scan.c b/lib/skin_parser/skin_scan.c new file mode 100644 index 0000000000..79f7162aab --- /dev/null +++ b/lib/skin_parser/skin_scan.c @@ -0,0 +1,218 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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_scan.h" +#include "skin_debug.h" +#include "symbols.h" +#include "skin_parser.h" + +/* Scanning Functions */ + +/* Simple function to advance a char* past a comment */ +void skip_comment(char** document) +{ + while(**document != '\n' && **document != '\0') + (*document)++; + if(**document == '\n') + (*document)++; +} + +void skip_whitespace(char** document) +{ + while(**document == ' ' || **document == '\t') + (*document)++; +} + +void skip_arglist(char** document) +{ + if(**document == ARGLISTOPENSYM) + (*document)++; + while(**document && **document != ARGLISTCLOSESYM) + { + if(**document == TAGSYM) + { + (*document)++; + if(**document == '\0') + break; + (*document)++; + } + else if(**document == ARGLISTOPENSYM) + skip_arglist(document); + else if(**document == ENUMLISTOPENSYM) + skip_enumlist(document); + else if(**document == COMMENTSYM) + skip_comment(document); + else + (*document)++; + } + if(**document == ARGLISTCLOSESYM) + (*document)++; +} + +void skip_enumlist(char** document) +{ + if(**document == ENUMLISTOPENSYM) + (*document)++; + while(**document && **document != ENUMLISTCLOSESYM) + { + if(**document == TAGSYM) + { + (*document)++; + if(**document == '\0') + break; + (*document)++; + } + else if(**document == ARGLISTOPENSYM) + skip_arglist(document); + else if(**document == ENUMLISTOPENSYM) + skip_enumlist(document); + else if(**document == COMMENTSYM) + skip_comment(document); + else + (*document)++; + } + + if(**document == ENUMLISTCLOSESYM) + (*document)++; +} + +char* scan_string(char** document) +{ + + char* cursor = *document; + int length = 0; + char* buffer = NULL; + int i; + + while(*cursor != ARGLISTSEPERATESYM && *cursor != ARGLISTCLOSESYM && + *cursor != '\0') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + continue; + } + + if(*cursor == TAGSYM) + cursor++; + + if(*cursor == '\n') + { + skin_error(UNEXPECTED_NEWLINE); + return NULL; + } + + length++; + cursor++; + } + + /* Copying the string */ + cursor = *document; + buffer = skin_alloc_string(length); + buffer[length] = '\0'; + for(i = 0; i < length; i++) + { + if(*cursor == TAGSYM) + cursor++; + + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + i--; + continue; + } + + buffer[i] = *cursor; + cursor++; + } + + *document = cursor; + return buffer; +} + +int scan_int(char** document) +{ + + char* cursor = *document, *end; + int length = 0; + char buffer[16]; + int retval; + int i; + + while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-') + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + continue; + } + + length++; + cursor++; + } + if (length > 15) + length = 15; + end = cursor; + /* Copying to the buffer while avoiding comments */ + cursor = *document; + buffer[length] = '\0'; + for(i = 0; i < length; i++) + { + if(*cursor == COMMENTSYM) + { + skip_comment(&cursor); + i--; + continue; + } + + buffer[i] = *cursor; + cursor++; + + } + retval = atoi(buffer); + + *document = end; + return retval; +} + +int check_viewport(char* document) +{ + if(strlen(document) < 3) + return 0; + + if(document[0] != TAGSYM) + return 0; + + if(document[1] != 'V') + return 0; + + if(document[2] != ARGLISTOPENSYM + && document[2] != 'l' + && document[2] != 'i') + return 0; + + return 1; +} diff --git a/lib/skin_parser/skin_scan.h b/lib/skin_parser/skin_scan.h new file mode 100644 index 0000000000..b1d04a6e34 --- /dev/null +++ b/lib/skin_parser/skin_scan.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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. + * + ****************************************************************************/ + +#ifndef SCANNING_H +#define SCANNING_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Scanning functions */ +void skip_comment(char** document); +void skip_whitespace(char** document); +void skip_arglist(char** document); +void skip_enumlist(char** document); +char* scan_string(char** document); +int scan_int(char** document); +int check_viewport(char* document); /* Checks for a viewport declaration */ + +#ifdef __cplusplus +} +#endif + +#endif // SCANNING_H diff --git a/lib/skin_parser/symbols.h b/lib/skin_parser/symbols.h new file mode 100644 index 0000000000..b4f31289ef --- /dev/null +++ b/lib/skin_parser/symbols.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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. + * + ****************************************************************************/ + +#ifndef SYMBOLS_H +#define SYMBOLS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/* Symbol definitions for WPS parsing */ + +#define TAGSYM '%' +#define COMMENTSYM '#' +#define CONDITIONSYM '?' +#define MULTILINESYM ';' +#define ARGLISTOPENSYM '(' +#define ARGLISTCLOSESYM ')' +#define ARGLISTSEPERATESYM ',' +#define ENUMLISTSEPERATESYM '|' +#define ENUMLISTOPENSYM '<' +#define ENUMLISTCLOSESYM '>' +#define DEFAULTSYM '-' + +#ifdef __cplusplus +} +#endif + +#endif /* SYMBOLS_H */ diff --git a/lib/skin_parser/tag_table.c b/lib/skin_parser/tag_table.c new file mode 100644 index 0000000000..6d82b47cc3 --- /dev/null +++ b/lib/skin_parser/tag_table.c @@ -0,0 +1,256 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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 "tag_table.h" + +#include +#define BAR_PARAMS "*|iiiiN" +/* The tag definition table */ +struct tag_info legal_tags[] = +{ + { SKIN_TOKEN_ALIGN_CENTER, "ac", "" }, + { SKIN_TOKEN_ALIGN_LEFT, "al", "" }, + { SKIN_TOKEN_ALIGN_LEFT_RTL, "aL", "" }, + { SKIN_TOKEN_ALIGN_RIGHT, "ar", "" }, + { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "" }, + { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "" }, + + { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS }, + { SKIN_TOKEN_BATTERY_VOLTS, "bv", "" }, + { SKIN_TOKEN_BATTERY_TIME, "bt", "" }, + { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "" }, + { SKIN_TOKEN_BATTERY_CHARGING, "bc", "" }, + { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "" }, + { SKIN_TOKEN_USB_POWERED, "bu", "" }, + + + { SKIN_TOKEN_RTC_PRESENT, "cc", "" }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "" }, + { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "" }, + { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "" }, + { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "" }, + { SKIN_TOKEN_RTC_HOUR_24, "ck", "" }, + { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "" }, + { SKIN_TOKEN_RTC_HOUR_12, "cl", "" }, + { SKIN_TOKEN_RTC_MONTH, "cm", "" }, + { SKIN_TOKEN_RTC_MINUTE, "cM", "" }, + { SKIN_TOKEN_RTC_SECOND, "cS", "" }, + { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "" }, + { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "" }, + { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "" }, + { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "" }, + { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "" }, + { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "" }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "" }, + { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "" }, + + { SKIN_TOKEN_FILE_BITRATE, "fb", "" }, + { SKIN_TOKEN_FILE_CODEC, "fc", "" }, + { SKIN_TOKEN_FILE_FREQUENCY, "ff", "" }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "" }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "" }, + { SKIN_TOKEN_FILE_NAME, "fn", "" }, + { SKIN_TOKEN_FILE_PATH, "fp", "" }, + { SKIN_TOKEN_FILE_SIZE, "fs", "" }, + { SKIN_TOKEN_FILE_VBR, "fv", "" }, + { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I" }, + + { SKIN_TOKEN_FILE_BITRATE, "Fb", "" }, + { SKIN_TOKEN_FILE_CODEC, "Fc", "" }, + { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "" }, + { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "" }, + { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "" }, + { SKIN_TOKEN_FILE_NAME, "Fn", "" }, + { SKIN_TOKEN_FILE_PATH, "Fp", "" }, + { SKIN_TOKEN_FILE_SIZE, "Fs", "" }, + { SKIN_TOKEN_FILE_VBR, "Fv", "" }, + { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I" }, + + + { SKIN_TOKEN_METADATA_ARTIST, "ia", "" }, + { SKIN_TOKEN_METADATA_COMPOSER, "ic", "" }, + { SKIN_TOKEN_METADATA_ALBUM, "id", "" }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "" }, + { SKIN_TOKEN_METADATA_GROUPING, "iG", "" }, + { SKIN_TOKEN_METADATA_GENRE, "ig", "" }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "" }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "" }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "" }, + { SKIN_TOKEN_METADATA_VERSION, "iv", "" }, + { SKIN_TOKEN_METADATA_YEAR, "iy", "" }, + { SKIN_TOKEN_METADATA_COMMENT, "iC", "" }, + + { SKIN_TOKEN_METADATA_ARTIST, "Ia", "" }, + { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "" }, + { SKIN_TOKEN_METADATA_ALBUM, "Id", "" }, + { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "" }, + { SKIN_TOKEN_METADATA_GROUPING, "IG", "" }, + { SKIN_TOKEN_METADATA_GENRE, "Ig", "" }, + { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "" }, + { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "" }, + { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "" }, + { SKIN_TOKEN_METADATA_VERSION, "Iv", "" }, + { SKIN_TOKEN_METADATA_YEAR, "Iy", "" }, + { SKIN_TOKEN_METADATA_COMMENT, "IC", "" }, + + { SKIN_TOKEN_SOUND_PITCH, "Sp", "" }, + { SKIN_TOKEN_SOUND_SPEED, "Ss", "" }, + + { SKIN_TOKEN_VLED_HDD, "lh", "" }, + + { SKIN_TOKEN_MAIN_HOLD, "mh", "" }, + { SKIN_TOKEN_REMOTE_HOLD, "mr", "" }, + { SKIN_TOKEN_REPEAT_MODE, "mm", "" }, + { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "" }, + { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|S" }, + + { SKIN_TOKEN_PEAKMETER, "pm", "" }, + { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "" }, + { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS }, + { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS }, + + { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "" }, + { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "" }, + { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "" }, + { SKIN_TOKEN_TRACK_LENGTH, "pt", "" }, + { SKIN_TOKEN_TRACK_STARTING, "pS" , "|S"}, + { SKIN_TOKEN_TRACK_ENDING, "pE" , "|S"}, + { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "" }, + { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "" }, + { SKIN_TOKEN_PLAYLIST_NAME, "pn", "" }, + { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "" }, + + { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "" }, + { SKIN_TOKEN_DATABASE_RATING, "rr", "" }, + { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "" }, + + { SKIN_TOKEN_REPLAYGAIN, "rg", "" }, + { SKIN_TOKEN_CROSSFADE, "xf", "" }, + + { SKIN_TOKEN_HAVE_TUNER, "tp", "" }, + { SKIN_TOKEN_TUNER_TUNED, "tt", "" }, + { SKIN_TOKEN_TUNER_SCANMODE, "tm", "" }, + { SKIN_TOKEN_TUNER_STEREO, "ts", "" }, + { SKIN_TOKEN_TUNER_MINFREQ, "ta", "" }, + { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "" }, + { SKIN_TOKEN_TUNER_CURFREQ, "tf", "" }, + { SKIN_TOKEN_PRESET_ID, "Ti", "" }, + { SKIN_TOKEN_PRESET_NAME, "Tn", "" }, + { SKIN_TOKEN_PRESET_FREQ, "Tf", "" }, + { SKIN_TOKEN_PRESET_COUNT, "Tc", "" }, + { SKIN_TOKEN_HAVE_RDS, "tx", "" }, + { SKIN_TOKEN_RDS_NAME, "ty", "" }, + { SKIN_TOKEN_RDS_TEXT, "tz", "" }, + + { SKIN_TOKEN_SUBLINE_SCROLL, "s", "" }, + { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "S" }, + + { SKIN_TOKEN_ENABLE_THEME, "we", "" }, + { SKIN_TOKEN_DISABLE_THEME, "wd", "" }, + { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "" }, + + { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I" }, + { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S" }, + { SKIN_TOKEN_IMAGE_PRELOAD, "x", "SFII" }, + + { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF"}, + { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss"}, + { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , ""}, + { SKIN_TOKEN_ALBUMART_FOUND, "C" , ""}, + + { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S"}, + { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S"}, + + { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC"}, + { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , ""}, + { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , ""}, + + { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "S"}, + { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "S"}, + + { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii|ii"}, + { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii|ii"}, + { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii|ii"}, + + { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f"}, + + { SKIN_TOKEN_SETTING, "St" , "S"}, + { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S"}, + { SKIN_TOKEN_LANG_IS_RTL, "Sr" , ""}, + + { SKIN_TOKEN_LASTTOUCH, "Tl" , "|S"}, + { SKIN_TOKEN_CURRENT_SCREEN, "cs", "" }, + { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS"}, + + { SKIN_TOKEN_HAVE_RECORDING, "Rp" , ""}, + { SKIN_TOKEN_IS_RECORDING, "Rr" , ""}, + { SKIN_TOKEN_REC_FREQ, "Rf" , ""}, + { SKIN_TOKEN_REC_ENCODER, "Re" , ""}, + { SKIN_TOKEN_REC_BITRATE, "Rb" , ""}, + { SKIN_TOKEN_REC_MONO, "Rm" , ""}, + { SKIN_TOKEN_REC_SECONDS, "Rs" , ""}, + { SKIN_TOKEN_REC_MINUTES, "Rn" , ""}, + { SKIN_TOKEN_REC_HOURS, "Rh" , ""}, + + { SKIN_TOKEN_UNKNOWN, "" , ""} + /* Keep this here to mark the end of the table */ +}; + +/* A table of legal escapable characters */ +char legal_escape_characters[] = "%(,);#<|>"; + +/* + * Just does a straight search through the tag table to find one by + * the given name + */ +struct tag_info* find_tag(char* name) +{ + + struct tag_info* current = legal_tags; + + /* + * Continue searching so long as we have a non-empty name string + * and the name of the current element doesn't match the name + * we're searching for + */ + + while(strcmp(current->name, name) && current->name[0] != '\0') + current++; + + if(current->name[0] == '\0') + return NULL; + else + return current; + +} + +/* Searches through the legal escape characters string */ +int find_escape_character(char lookup) +{ + char* current = legal_escape_characters; + while(*current != lookup && *current != '\0') + current++; + + if(*current == lookup && *current) + return 1; + else + return 0; +} diff --git a/lib/skin_parser/tag_table.h b/lib/skin_parser/tag_table.h new file mode 100644 index 0000000000..ec9a1021ab --- /dev/null +++ b/lib/skin_parser/tag_table.h @@ -0,0 +1,307 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * 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. + * + ****************************************************************************/ + +#ifndef TAG_TABLE_H +#define TAG_TABLE_H + +#ifdef __cplusplus +extern "C" +{ +#endif + + +enum skin_token_type { + + TOKEN_MARKER_CONTROL_TOKENS = -1, + SKIN_TOKEN_UNKNOWN, + + /* Markers */ + SKIN_TOKEN_CHARACTER, + SKIN_TOKEN_STRING, + SKIN_TOKEN_TRANSLATEDSTRING, + + /* Alignment */ + SKIN_TOKEN_ALIGN_LEFT, + SKIN_TOKEN_ALIGN_LEFT_RTL, + SKIN_TOKEN_ALIGN_CENTER, + SKIN_TOKEN_ALIGN_RIGHT, + SKIN_TOKEN_ALIGN_RIGHT_RTL, + SKIN_TOKEN_ALIGN_LANGDIRECTION, + + + /* Sublines */ + SKIN_TOKEN_SUBLINE_TIMEOUT, + SKIN_TOKEN_SUBLINE_SCROLL, + + /* Conditional */ + SKIN_TOKEN_CONDITIONAL, + SKIN_TOKEN_CONDITIONAL_START, + SKIN_TOKEN_CONDITIONAL_OPTION, + SKIN_TOKEN_CONDITIONAL_END, + + /* Viewport display */ + SKIN_TOKEN_VIEWPORT_LOAD, + SKIN_TOKEN_VIEWPORT_CONDITIONAL, + SKIN_TOKEN_VIEWPORT_ENABLE, + SKIN_TOKEN_VIEWPORT_CUSTOMLIST, + SKIN_TOKEN_UIVIEWPORT_ENABLE, + SKIN_TOKEN_UIVIEWPORT_LOAD, + SKIN_TOKEN_VIEWPORT_FGCOLOUR, + SKIN_TOKEN_VIEWPORT_BGCOLOUR, + + /* Battery */ + TOKEN_MARKER_BATTERY, + SKIN_TOKEN_BATTERY_PERCENT, + SKIN_TOKEN_BATTERY_PERCENTBAR, + SKIN_TOKEN_BATTERY_VOLTS, + SKIN_TOKEN_BATTERY_TIME, + SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, + SKIN_TOKEN_BATTERY_CHARGING, + SKIN_TOKEN_BATTERY_SLEEPTIME, + SKIN_TOKEN_USB_POWERED, + + /* Sound */ + TOKEN_MARKER_SOUND, + SKIN_TOKEN_SOUND_PITCH, + SKIN_TOKEN_SOUND_SPEED, + SKIN_TOKEN_REPLAYGAIN, + SKIN_TOKEN_CROSSFADE, + + /* Time */ + TOKEN_MARKER_RTC, + SKIN_TOKEN_RTC_PRESENT, + + /* The begin/end values allow us to know if a token is an RTC one. + New RTC tokens should be added between the markers. */ + + SKIN_TOKENs_RTC_BEGIN, /* just the start marker, not an actual token */ + + SKIN_TOKEN_RTC_DAY_OF_MONTH, + SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, + SKIN_TOKEN_RTC_12HOUR_CFG, + SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, + SKIN_TOKEN_RTC_HOUR_24, + SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, + SKIN_TOKEN_RTC_HOUR_12, + SKIN_TOKEN_RTC_MONTH, + SKIN_TOKEN_RTC_MINUTE, + SKIN_TOKEN_RTC_SECOND, + SKIN_TOKEN_RTC_YEAR_2_DIGITS, + SKIN_TOKEN_RTC_YEAR_4_DIGITS, + SKIN_TOKEN_RTC_AM_PM_UPPER, + SKIN_TOKEN_RTC_AM_PM_LOWER, + SKIN_TOKEN_RTC_WEEKDAY_NAME, + SKIN_TOKEN_RTC_MONTH_NAME, + SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, + SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, + + SKIN_TOKENS_RTC_END, /* just the end marker, not an actual token */ + + /* Database */ + TOKEN_MARKER_DATABASE, + SKIN_TOKEN_DATABASE_PLAYCOUNT, + SKIN_TOKEN_DATABASE_RATING, + SKIN_TOKEN_DATABASE_AUTOSCORE, + + /* File */ + TOKEN_MARKER_FILE, + SKIN_TOKEN_FILE_BITRATE, + SKIN_TOKEN_FILE_CODEC, + SKIN_TOKEN_FILE_FREQUENCY, + SKIN_TOKEN_FILE_FREQUENCY_KHZ, + SKIN_TOKEN_FILE_NAME, + SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, + SKIN_TOKEN_FILE_PATH, + SKIN_TOKEN_FILE_SIZE, + SKIN_TOKEN_FILE_VBR, + SKIN_TOKEN_FILE_DIRECTORY, + + /* Image */ + TOKEN_MARKER_IMAGES, + SKIN_TOKEN_IMAGE_BACKDROP, + SKIN_TOKEN_IMAGE_PROGRESS_BAR, + SKIN_TOKEN_IMAGE_PRELOAD, + SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, + SKIN_TOKEN_IMAGE_DISPLAY, + + /* Albumart */ + SKIN_TOKEN_ALBUMART_LOAD, + SKIN_TOKEN_ALBUMART_DISPLAY, + SKIN_TOKEN_ALBUMART_FOUND, + + /* Metadata */ + TOKEN_MARKER_METADATA, + SKIN_TOKEN_METADATA_ARTIST, + SKIN_TOKEN_METADATA_COMPOSER, + SKIN_TOKEN_METADATA_ALBUM_ARTIST, + SKIN_TOKEN_METADATA_GROUPING, + SKIN_TOKEN_METADATA_ALBUM, + SKIN_TOKEN_METADATA_GENRE, + SKIN_TOKEN_METADATA_DISC_NUMBER, + SKIN_TOKEN_METADATA_TRACK_NUMBER, + SKIN_TOKEN_METADATA_TRACK_TITLE, + SKIN_TOKEN_METADATA_VERSION, + SKIN_TOKEN_METADATA_YEAR, + SKIN_TOKEN_METADATA_COMMENT, + + TOKEN_MARKER_PLAYBACK_INFO, + /* Mode */ + SKIN_TOKEN_REPEAT_MODE, + SKIN_TOKEN_PLAYBACK_STATUS, + /* Progressbar */ + SKIN_TOKEN_PROGRESSBAR, + SKIN_TOKEN_PLAYER_PROGRESSBAR, + /* Peakmeter */ + SKIN_TOKEN_PEAKMETER, + + /* Current track */ + SKIN_TOKEN_TRACK_ELAPSED_PERCENT, + SKIN_TOKEN_TRACK_TIME_ELAPSED, + SKIN_TOKEN_TRACK_TIME_REMAINING, + SKIN_TOKEN_TRACK_LENGTH, + SKIN_TOKEN_TRACK_STARTING, + SKIN_TOKEN_TRACK_ENDING, + + /* Playlist */ + TOKEN_MARKER_PLAYLIST, + SKIN_TOKEN_PLAYLIST_ENTRIES, + SKIN_TOKEN_PLAYLIST_NAME, + SKIN_TOKEN_PLAYLIST_POSITION, + SKIN_TOKEN_PLAYLIST_SHUFFLE, + + + TOKEN_MARKER_MISC, + SKIN_TOKEN_ENABLE_THEME, + SKIN_TOKEN_DISABLE_THEME, + SKIN_TOKEN_DRAW_INBUILTBAR, + SKIN_TOKEN_LIST_TITLE_TEXT, + SKIN_TOKEN_LIST_TITLE_ICON, + + SKIN_TOKEN_LOAD_FONT, + + /* buttons */ + SKIN_TOKEN_BUTTON_VOLUME, + SKIN_TOKEN_LASTTOUCH, + SKIN_TOKEN_TOUCHREGION, + /* Virtual LED */ + SKIN_TOKEN_VLED_HDD, + /* Volume level */ + SKIN_TOKEN_VOLUME, + SKIN_TOKEN_VOLUMEBAR, + /* hold */ + SKIN_TOKEN_MAIN_HOLD, + SKIN_TOKEN_REMOTE_HOLD, + + /* Setting option */ + SKIN_TOKEN_SETTING, + SKIN_TOKEN_CURRENT_SCREEN, + SKIN_TOKEN_LANG_IS_RTL, + + /* Recording Tokens */ + TOKEN_MARKER_RECORDING, + SKIN_TOKEN_HAVE_RECORDING, + SKIN_TOKEN_IS_RECORDING, + SKIN_TOKEN_REC_FREQ, + SKIN_TOKEN_REC_ENCODER, + SKIN_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ + SKIN_TOKEN_REC_MONO, + SKIN_TOKEN_REC_SECONDS, + SKIN_TOKEN_REC_MINUTES, + SKIN_TOKEN_REC_HOURS, + + + /* Radio Tokens */ + TOKEN_MARKER_TUNER, + SKIN_TOKEN_HAVE_TUNER, + SKIN_TOKEN_TUNER_TUNED, + SKIN_TOKEN_TUNER_SCANMODE, + SKIN_TOKEN_TUNER_STEREO, + SKIN_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ + SKIN_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ + SKIN_TOKEN_TUNER_CURFREQ, + SKIN_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ + SKIN_TOKEN_PRESET_NAME, + SKIN_TOKEN_PRESET_FREQ, + SKIN_TOKEN_PRESET_COUNT, + /* RDS tokens */ + SKIN_TOKEN_HAVE_RDS, + SKIN_TOKEN_RDS_NAME, + SKIN_TOKEN_RDS_TEXT, + + + TOKEN_MARKER_END, /* this needs to be the last value in this enum */ +}; + +/* + * Struct for tag parsing information + * name - The name of the tag, i.e. V for %V + * params - A string specifying all of the tags parameters, each + * character representing a single parameter. Valid + * characters for parameters are: + * I - Required integer + * i - Nullable integer + * S - Required string + * s - Nullable string + * F - Required file name + * f - Nullable file name + * C - Required skin code + * N - any amount of strings.. must be the last param in the list + * Any nullable parameter may be replaced in the WPS file + * with a '-'. To specify that parameters may be left off + * altogether, place a '|' in the parameter string. For + * instance, with the parameter string... + * Ii|Ss + * one integer must be specified, one integer can be + * specified or set to default with '-', and the user can + * stop providing parameters at any time after that. + * To specify multiple instances of the same type, put a + * number before the character. For instance, the string... + * 2s + * will specify two strings. An asterisk (*) at the beginning of the + * string will specify that you may choose to omit all arguments + * + */ +struct tag_info +{ + enum skin_token_type type; + char* name; + char* params; + +}; + +/* + * Finds a tag by name and returns its parameter list, or an empty + * string if the tag is not found in the table + */ +struct tag_info* find_tag(char* name); + +/* + * Determines whether a character is legal to escape or not. If + * lookup is not found in the legal escape characters string, returns + * false, otherwise returns true + */ +int find_escape_character(char lookup); + +#ifdef __cplusplus +} +#endif + +#endif /* TAG_TABLE_H */ diff --git a/utils/themeeditor/parser/skin_debug.c b/utils/themeeditor/parser/skin_debug.c deleted file mode 100644 index 549f7b9e6c..0000000000 --- a/utils/themeeditor/parser/skin_debug.c +++ /dev/null @@ -1,262 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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 "skin_parser.h" -#include "skin_debug.h" -#include "tag_table.h" - -/* Global variables for debug output */ -int debug_indent_level = 0; -extern int skin_line; - -/* Global error variables */ -int error_line; -char* error_message; - -/* Debugging functions */ -void skin_error(enum skin_errorcode error) -{ - - error_line = skin_line; - - switch(error) - { - case MEMORY_LIMIT_EXCEEDED: - error_message = "Memory limit exceeded"; - break; - case NEWLINE_EXPECTED: - error_message = "Newline expected"; - break; - case ILLEGAL_TAG: - error_message = "Illegal tag"; - break; - case ARGLIST_EXPECTED: - error_message = "Argument list expected"; - break; - case TOO_MANY_ARGS: - error_message = "Too many arguments given"; - break; - case DEFAULT_NOT_ALLOWED: - error_message = "Argument can not be set to default"; - break; - case UNEXPECTED_NEWLINE: - error_message = "Unexpected newline"; - break; - case INSUFFICIENT_ARGS: - error_message = "Not enough arguments"; - break; - case INT_EXPECTED: - error_message = "Expected integer"; - break; - case SEPERATOR_EXPECTED: - error_message = "Expected argument seperator"; - break; - case CLOSE_EXPECTED: - error_message = "Expected list close"; - break; - case MULTILINE_EXPECTED: - error_message = "Expected subline seperator"; - break; - }; - -} - -int skin_error_line() -{ - return error_line; -} - -char* skin_error_message() -{ - return error_message; -} - -void skin_clear_errors() -{ - error_line = 0; - error_message = NULL; -} - -void skin_debug_tree(struct skin_element* root) -{ - int i; - char *text; - - struct skin_element* current = root; - - while(current) - { - skin_debug_indent(); - - switch(current->type) - { - case UNKNOWN: - printf("[ Unknown element.. error\n]"); - break; - - case VIEWPORT: - printf("[ Viewport \n"); - - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - - printf("]"); - break; - - case TEXT: - text = current->data; - printf("[ Plain text on line %d : %s ]\n", current->line, text); - break; - - case COMMENT: - text = current->data; - printf("[ Comment on line %d: ", current->line); - for(i = 0; i < (int)strlen(text); i++) - { - if(text[i] == '\n') - printf("\\n"); - else - printf("%c", text[i]); - } - printf(" ]\n"); - break; - - case TAG: - printf("[ %s tag on line %d with %d arguments\n", - current->tag->name, - current->line, current->params_count); - debug_indent_level++; - skin_debug_params(current->params_count, current->params); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - break; - - case SUBLINES: - printf("[ Alternator on line %d with %d sublines \n", current->line, - current->children_count); - debug_indent_level++; - for(i = 0; i < current->children_count; i++) - { - skin_debug_tree(current->children[i]); - } - debug_indent_level--; - - skin_debug_indent(); - printf("]\n"); - break; - - case CONDITIONAL: - printf("[ Conditional tag on line %d with %d enumerations \n", - current->line, current->children_count - 1); - debug_indent_level++; - - skin_debug_indent(); - printf("[ Condition tag \n"); - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - for(i = 1; i < current->children_count; i++) - { - skin_debug_indent(); - printf("[ Enumeration %d\n", i - 1); - debug_indent_level++; - skin_debug_tree(current->children[i]); - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - } - - debug_indent_level--; - skin_debug_indent(); - printf("]\n"); - - - break; - - case LINE: - printf("[ Logical line on line %d\n", current->line); - - debug_indent_level++; - skin_debug_tree(current->children[0]); - debug_indent_level--; - - skin_debug_indent(); - printf("]\n"); - break; - } - - current = current->next; - } - -} - -void skin_debug_params(int count, struct skin_tag_parameter params[]) -{ - int i; - for(i = 0; i < count; i++) - { - - skin_debug_indent(); - switch(params[i].type) - { - case DEFAULT: - printf("[-]"); - break; - - case STRING: - printf("[%s]", params[i].data.text); - break; - - case NUMERIC: - printf("[%d]", params[i].data.numeric); - break; - - case CODE: - printf("[ WPS Code: \n"); - debug_indent_level++; - skin_debug_tree(params[i].data.code); - debug_indent_level--; - skin_debug_indent(); - printf("]"); - break; - } - - printf("\n"); - - } -} - -void skin_debug_indent() -{ - int i; - for(i = 0; i < debug_indent_level; i++) - printf(" "); -} diff --git a/utils/themeeditor/parser/skin_debug.h b/utils/themeeditor/parser/skin_debug.h deleted file mode 100644 index a550dc4c7b..0000000000 --- a/utils/themeeditor/parser/skin_debug.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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. - * - ****************************************************************************/ - - -#ifndef SKIN_DEBUG_H -#define SKIN_DEBUG_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "skin_parser.h" - -/* Debugging functions */ -void skin_error(enum skin_errorcode error); -int skin_error_line(); -char* skin_error_message(); -void skin_clear_errors(); -void skin_debug_tree(struct skin_element* root); - -/* Auxiliary debug functions */ -void skin_debug_params(int count, struct skin_tag_parameter params[]); -void skin_debug_indent(); - -#ifdef __cplusplus -} -#endif - -#endif // SKIN_DEBUG_H diff --git a/utils/themeeditor/parser/skin_parser.c b/utils/themeeditor/parser/skin_parser.c deleted file mode 100644 index 93a71919bf..0000000000 --- a/utils/themeeditor/parser/skin_parser.c +++ /dev/null @@ -1,923 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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" - -#ifdef ROCKBOX -/* Declaration of parse tree buffer */ -#define SKIN_MAX_MEMORY (30*1024) -static char skin_parse_tree[SKIN_MAX_MEMORY]; -static char *skin_buffer; -#endif - -/* Global variables for the parser */ -int skin_line = 0; - -/* Auxiliary parsing functions (not visible at global scope) */ -static struct skin_element* skin_parse_viewport(char** document); -static struct skin_element* skin_parse_line(char** document); -static struct skin_element* skin_parse_line_optional(char** document, - int conditional); -static struct skin_element* skin_parse_sublines(char** document); -static struct skin_element* skin_parse_sublines_optional(char** document, - int conditional); - -static int skin_parse_tag(struct skin_element* element, char** document); -static int skin_parse_text(struct skin_element* element, char** document, - int conditional); -static int skin_parse_conditional(struct skin_element* element, - char** document); -static int skin_parse_comment(struct skin_element* element, char** document); -static struct skin_element* skin_parse_code_as_arg(char** document); - -struct skin_element* skin_parse(const char* document) -{ - - struct skin_element* root = NULL; - struct skin_element* last = NULL; - - struct skin_element** to_write = 0; - - char* cursor = (char*)document; /*Keeps track of location in the document*/ -#ifdef ROCKBOX - /* FIXME */ - skin_buffer = &skin_parse_tree[0]; -#endif - - skin_line = 1; - - skin_clear_errors(); - - while(*cursor != '\0') - { - - if(!root) - to_write = &root; - else - to_write = &(last->next); - - - *to_write = skin_parse_viewport(&cursor); - last = *to_write; - if(!last) - { - skin_free_tree(root); /* Clearing any memory already used */ - return NULL; - } - - /* Making sure last is at the end */ - while(last->next) - last = last->next; - - } - - return root; - -} - -static struct skin_element* skin_parse_viewport(char** document) -{ - - struct skin_element* root = NULL; - struct skin_element* last = NULL; - struct skin_element* retval = NULL; - - retval = skin_alloc_element(); - retval->type = VIEWPORT; - retval->children_count = 1; - retval->line = skin_line; - - struct skin_element** to_write = 0; - - char* cursor = *document; /* Keeps track of location in the document */ - char* bookmark; /* Used when we need to look ahead */ - - int sublines = 0; /* Flag for parsing sublines */ - - /* Parsing out the viewport tag if there is one */ - if(check_viewport(cursor)) - { - skin_parse_tag(retval, &cursor); - if(*cursor == '\n') - { - cursor++; - skin_line++; - } - } - - retval->children_count = 1; - retval->children = skin_alloc_children(1); - - - do - { - - /* First, we check to see if this line will contain sublines */ - bookmark = cursor; - sublines = 0; - while(*cursor != '\n' && *cursor != '\0' - && !(check_viewport(cursor) && cursor != *document)) - { - if(*cursor == MULTILINESYM) - { - sublines = 1; - break; - } - else if(*cursor == TAGSYM) - { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; - } - else if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else - { - /* Advancing the cursor as normal */ - cursor++; - } - } - cursor = bookmark; - - if(!root) - to_write = &root; - else - to_write = &(last->next); - - if(sublines) - { - *to_write = skin_parse_sublines(&cursor); - last = *to_write; - if(!last) - return NULL; - } - else - { - - *to_write = skin_parse_line(&cursor); - last = *to_write; - if(!last) - return NULL; - - } - - /* Making sure last is at the end */ - while(last->next) - last = last->next; - - if(*cursor == '\n') - { - cursor++; - skin_line++; - } - } - while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document)); - - *document = cursor; - - retval->children[0] = root; - return retval; - -} - -/* Auxiliary Parsing Functions */ - -static struct skin_element* skin_parse_line(char**document) -{ - - return skin_parse_line_optional(document, 0); - -} - - -/* - * If conditional is set to true, then this will break upon encountering - * SEPERATESYM. This should only be used when parsing a line inside a - * conditional, otherwise just use the wrapper function skin_parse_line() - */ -static struct skin_element* skin_parse_line_optional(char** document, - int conditional) -{ - char* cursor = *document; - - struct skin_element* root = NULL; - struct skin_element* current = NULL; - struct skin_element* retval = NULL; - - /* A wrapper for the line */ - retval = skin_alloc_element(); - retval->type = LINE; - retval->line = skin_line; - if(*cursor != '\0' && *cursor != '\n' - && !(conditional && (*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM))) - { - retval->children_count = 1; - } - else - { - retval->children_count = 0; - } - - if(retval->children_count > 0) - retval->children = skin_alloc_children(1); - - while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional) - && !(check_viewport(cursor) && cursor != *document)) - { - /* Allocating memory if necessary */ - if(root) - { - current->next = skin_alloc_element(); - current = current->next; - } - else - { - current = skin_alloc_element(); - root = current; - } - - /* Parsing the current element */ - if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM) - { - if(!skin_parse_conditional(current, &cursor)) - return NULL; - } - else if(*cursor == TAGSYM && !find_escape_character(cursor[1])) - { - if(!skin_parse_tag(current, &cursor)) - return NULL; - } - else if(*cursor == COMMENTSYM) - { - if(!skin_parse_comment(current, &cursor)) - return NULL; - } - else - { - if(!skin_parse_text(current, &cursor, conditional)) - return NULL; - } - } - - /* Moving up the calling function's pointer */ - *document = cursor; - - if(root) - retval->children[0] = root; - return retval; -} - -static struct skin_element* skin_parse_sublines(char** document) -{ - return skin_parse_sublines_optional(document, 0); -} - -static struct skin_element* skin_parse_sublines_optional(char** document, - int conditional) -{ - struct skin_element* retval; - char* cursor = *document; - int sublines = 1; - int i; - - retval = skin_alloc_element(); - retval->type = SUBLINES; - retval->next = NULL; - retval->line = skin_line; - - /* First we count the sublines */ - while(*cursor != '\0' && *cursor != '\n' - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional) - && !(check_viewport(cursor) && cursor != *document)) - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; - } - else if(*cursor == MULTILINESYM) - { - sublines++; - cursor++; - } - else - { - cursor++; - } - } - - /* ...and then we parse them */ - retval->children_count = sublines; - retval->children = skin_alloc_children(sublines); - - cursor = *document; - for(i = 0; i < sublines; i++) - { - retval->children[i] = skin_parse_line_optional(&cursor, conditional); - skip_whitespace(&cursor); - - if(*cursor != MULTILINESYM && i != sublines - 1) - { - skin_error(MULTILINE_EXPECTED); - return NULL; - } - else if(i != sublines - 1) - { - cursor++; - } - } - - *document = cursor; - - return retval; -} - -static int skin_parse_tag(struct skin_element* element, char** document) -{ - - char* cursor = *document + 1; - char* bookmark; - - char tag_name[3]; - char* tag_args; - struct tag_info *tag; - - int num_args = 1; - int i; - int star = 0; /* Flag for the all-or-none option */ - int req_args; /* To mark when we enter optional arguments */ - - int optional = 0; - - /* Checking the tag name */ - tag_name[0] = cursor[0]; - tag_name[1] = cursor[1]; - tag_name[2] = '\0'; - - /* First we check the two characters after the '%', then a single char */ - tag = find_tag(tag_name); - - if(!tag) - { - tag_name[1] = '\0'; - tag = find_tag(tag_name); - cursor++; - } - else - { - cursor += 2; - } - - if(!tag) - { - skin_error(ILLEGAL_TAG); - return 0; - } - - /* Copying basic tag info */ - if(element->type != CONDITIONAL && element->type != VIEWPORT) - element->type = TAG; - element->tag = tag; - tag_args = tag->params; - element->line = skin_line; - - /* Checking for the * flag */ - if(tag_args[0] == '*') - { - star = 1; - tag_args++; - } - - /* If this tag has no arguments, we can bail out now */ - if(strlen(tag_args) == 0 - || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) - || (star && *cursor != ARGLISTOPENSYM)) - { - *document = cursor; - return 1; - } - - /* Checking the number of arguments and allocating args */ - if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|') - { - skin_error(ARGLIST_EXPECTED); - return 0; - } - else - { - cursor++; - } - - bookmark = cursor; - while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) - { - /* Skipping over escaped characters */ - if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0') - break; - cursor++; - } - else if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ARGLISTSEPERATESYM) - { - num_args++; - cursor++; - } - else - { - cursor++; - } - } - - cursor = bookmark; /* Restoring the cursor */ - element->params_count = num_args; - element->params = skin_alloc_params(num_args); - - /* Now we have to actually parse each argument */ - for(i = 0; i < num_args; i++) - { - /* Making sure we haven't run out of arguments */ - if(*tag_args == '\0') - { - skin_error(TOO_MANY_ARGS); - return 0; - } - - /* Checking for the optional bar */ - if(*tag_args == '|') - { - optional = 1; - req_args = i; - tag_args++; - } - - /* Scanning the arguments */ - skip_whitespace(&cursor); - - - /* Checking for comments */ - if(*cursor == COMMENTSYM) - skip_comment(&cursor); - - /* Storing the type code */ - element->params[i].type_code = *tag_args; - - /* Checking a nullable argument for null */ - if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) - { - if(islower(*tag_args)) - { - element->params[i].type = DEFAULT; - cursor++; - } - else - { - skin_error(DEFAULT_NOT_ALLOWED); - return 0; - } - } - else if(tolower(*tag_args) == 'i') - { - /* Scanning an int argument */ - if(!isdigit(*cursor) && *cursor != '-') - { - skin_error(INT_EXPECTED); - return 0; - } - - element->params[i].type = NUMERIC; - element->params[i].data.numeric = scan_int(&cursor); - } - else if(tolower(*tag_args) == 'n' || - tolower(*tag_args) == 's' || tolower(*tag_args) == 'f') - { - /* Scanning a string argument */ - element->params[i].type = STRING; - element->params[i].data.text = scan_string(&cursor); - - } - else if(tolower(*tag_args) == 'c') - { - /* Recursively parsing a code argument */ - element->params[i].type = CODE; - element->params[i].data.code = skin_parse_code_as_arg(&cursor); - if(!element->params[i].data.code) - return 0; - } - - skip_whitespace(&cursor); - - if(*cursor != ARGLISTSEPERATESYM && i < num_args - 1) - { - skin_error(SEPERATOR_EXPECTED); - return 0; - } - else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1) - { - skin_error(CLOSE_EXPECTED); - return 0; - } - else - { - cursor++; - } - - if (*tag_args != 'N') - tag_args++; - - /* Checking for the optional bar */ - if(*tag_args == '|') - { - optional = 1; - req_args = i + 1; - tag_args++; - } - - } - - /* Checking for a premature end */ - if(*tag_args != '\0' && !optional) - { - skin_error(INSUFFICIENT_ARGS); - return 0; - } - - *document = cursor; - - return 1; -} - -/* - * If the conditional flag is set true, then parsing text will stop at an - * ARGLISTSEPERATESYM. Only set that flag when parsing within a conditional - */ -static int skin_parse_text(struct skin_element* element, char** document, - int conditional) -{ - char* cursor = *document; - int length = 0; - int dest; - char *text = NULL; - - /* First figure out how much text we're copying */ - while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM - && *cursor != COMMENTSYM - && !((*cursor == ARGLISTSEPERATESYM - || *cursor == ARGLISTCLOSESYM - || *cursor == ENUMLISTSEPERATESYM - || *cursor == ENUMLISTCLOSESYM) - && conditional)) - { - /* Dealing with possibility of escaped characters */ - if(*cursor == TAGSYM) - { - if(find_escape_character(cursor[1])) - cursor++; - else - break; - } - - length++; - cursor++; - } - - cursor = *document; - - /* Copying the text into the element struct */ - element->type = TEXT; - element->line = skin_line; - element->next = NULL; - element->data = text = skin_alloc_string(length); - - for(dest = 0; dest < length; dest++) - { - /* Advancing cursor if we've encountered an escaped character */ - if(*cursor == TAGSYM) - cursor++; - - text[dest] = *cursor; - cursor++; - } - text[length] = '\0'; - - *document = cursor; - - return 1; -} - -static int skin_parse_conditional(struct skin_element* element, char** document) -{ - - char* cursor = *document + 1; /* Starting past the "%" */ - char* bookmark; - int children = 1; - int i; - - element->type = CONDITIONAL; - element->line = skin_line; - - /* Parsing the tag first */ - if(!skin_parse_tag(element, &cursor)) - return 0; - - /* Counting the children */ - if(*(cursor++) != ENUMLISTOPENSYM) - { - skin_error(ARGLIST_EXPECTED); - return 0; - } - bookmark = cursor; - while(*cursor != ENUMLISTCLOSESYM && *cursor != '\n' && *cursor != '\0') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else if(*cursor == TAGSYM) - { - cursor++; - if(*cursor == '\0' || *cursor == '\n') - break; - cursor++; - } - else if(*cursor == ENUMLISTSEPERATESYM) - { - children++; - cursor++; - } - else - { - cursor++; - } - } - cursor = bookmark; - - /* Parsing the children */ - element->children = skin_alloc_children(children); - element->children_count = children; - - for(i = 0; i < children; i++) - { - element->children[i] = skin_parse_code_as_arg(&cursor); - skip_whitespace(&cursor); - - if(i < children - 1 && *cursor != ENUMLISTSEPERATESYM) - { - skin_error(SEPERATOR_EXPECTED); - return 0; - } - else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) - { - skin_error(CLOSE_EXPECTED); - return 0; - } - else - { - cursor++; - } - } - - *document = cursor; - - return 1; -} - -static int skin_parse_comment(struct skin_element* element, char** document) -{ - char* cursor = *document; - char* text = NULL; - - int length; - /* - * Finding the index of the ending newline or null-terminator - * The length of the string of interest doesn't include the leading #, the - * length we need to reserve is the same as the index of the last character - */ - for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++); - - element->type = COMMENT; - element->line = skin_line; -#ifdef ROCKBOX - element->data = NULL; -#else - element->data = text = skin_alloc_string(length); - /* We copy from one char past cursor to leave out the # */ - memcpy((void*)text, (void*)(cursor + 1), - sizeof(char) * (length-1)); - text[length - 1] = '\0'; -#endif - if(cursor[length] == '\n') - skin_line++; - - *document += (length); /* Move cursor up past # and all text */ - if(**document == '\n') - (*document)++; - - return 1; -} - -static struct skin_element* skin_parse_code_as_arg(char** document) -{ - - int sublines = 0; - char* cursor = *document; - - /* Checking for sublines */ - while(*cursor != '\n' && *cursor != '\0' - && *cursor != ENUMLISTSEPERATESYM && *cursor != ARGLISTSEPERATESYM - && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM) - { - if(*cursor == MULTILINESYM) - { - sublines = 1; - break; - } - else if(*cursor == TAGSYM) - { - /* A ';' directly after a '%' doesn't count */ - cursor ++; - - if(*cursor == '\0') - break; - - cursor++; - } - else if(*cursor == ARGLISTOPENSYM) - { - skip_arglist(&cursor); - } - else if(*cursor == ENUMLISTOPENSYM) - { - skip_enumlist(&cursor); - } - else - { - /* Advancing the cursor as normal */ - cursor++; - } - } - - if(sublines) - return skin_parse_sublines_optional(document, 1); - else - return skin_parse_line_optional(document, 1); -} - - -/* Memory management */ -char* skin_alloc(size_t size) -{ -#ifdef ROCKBOX - char *retval = skin_buffer; - skin_buffer = (void *)(((unsigned long)skin_buffer + 3) & ~3); - return retval; -#else - return malloc(size); -#endif -} - -struct skin_element* skin_alloc_element() -{ - struct skin_element* retval = (struct skin_element*) - skin_alloc(sizeof(struct skin_element)); - retval->type = UNKNOWN; - retval->next = NULL; - retval->tag = NULL; - retval->params_count = 0; - retval->children_count = 0; - - return retval; - -} - -struct skin_tag_parameter* skin_alloc_params(int count) -{ - size_t size = sizeof(struct skin_tag_parameter) * count; - return (struct skin_tag_parameter*)skin_alloc(size); - -} - -char* skin_alloc_string(int length) -{ - return (char*)skin_alloc(sizeof(char) * (length + 1)); -} - -struct skin_element** skin_alloc_children(int count) -{ - return (struct skin_element**) - skin_alloc(sizeof(struct skin_element*) * count); -} - -void skin_free_tree(struct skin_element* root) -{ -#ifndef ROCKBOX - int i; - - /* First make the recursive call */ - if(!root) - return; - skin_free_tree(root->next); - - /* Free any text */ - if(root->type == TEXT || root->type == COMMENT) - free(root->data); - - /* Then recursively free any children, before freeing their pointers */ - for(i = 0; i < root->children_count; i++) - skin_free_tree(root->children[i]); - if(root->children_count > 0) - free(root->children); - - /* Free any parameters, making sure to deallocate strings */ - for(i = 0; i < root->params_count; i++) - if(root->params[i].type == STRING) - free(root->params[i].data.text); - if(root->params_count > 0) - free(root->params); - - /* Finally, delete root's memory */ - free(root); -#else - (void)root; -#endif -} diff --git a/utils/themeeditor/parser/skin_parser.h b/utils/themeeditor/parser/skin_parser.h deleted file mode 100644 index 1fc4a7ae6b..0000000000 --- a/utils/themeeditor/parser/skin_parser.h +++ /dev/null @@ -1,138 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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. - * - ****************************************************************************/ - -#ifndef GENERIC_PARSER_H -#define GENERIC_PARSER_H - -#ifdef __cplusplus -extern "C" -{ -#endif -#include - -/******************************************************************** - ****** Data Structures ********************************************* - *******************************************************************/ - -/* Possible types of element in a WPS file */ -enum skin_element_type -{ - UNKNOWN = -1, - VIEWPORT, - LINE, - SUBLINES, - CONDITIONAL, - TAG, - TEXT, - COMMENT, -}; - -enum skin_errorcode -{ - MEMORY_LIMIT_EXCEEDED, - NEWLINE_EXPECTED, - ILLEGAL_TAG, - ARGLIST_EXPECTED, - TOO_MANY_ARGS, - DEFAULT_NOT_ALLOWED, - UNEXPECTED_NEWLINE, - INSUFFICIENT_ARGS, - INT_EXPECTED, - SEPERATOR_EXPECTED, - CLOSE_EXPECTED, - MULTILINE_EXPECTED -}; - -/* Holds a tag parameter, either numeric or text */ -struct skin_tag_parameter -{ - enum - { - NUMERIC, - STRING, - CODE, - DEFAULT - } type; - - union - { - int numeric; - char* text; - struct skin_element* code; - } data; - - char type_code; - -}; - -/* Defines an element of a SKIN file */ -struct skin_element -{ - /* Defines what type of element it is */ - enum skin_element_type type; - - /* The line on which it's defined in the source file */ - int line; - - /* Placeholder for element data - * TEXT and COMMENT uses it for the text string - * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage - */ - void* data; - - /* The tag or conditional name */ - struct tag_info *tag; - - /* Pointer to and size of an array of parameters */ - int params_count; - struct skin_tag_parameter* params; - - /* Pointer to and size of an array of children */ - int children_count; - struct skin_element** children; - - /* Link to the next element */ - struct skin_element* next; -}; - -/*********************************************************************** - ***** Functions ******************************************************* - **********************************************************************/ - -/* Parses a WPS document and returns a list of skin_element - structures. */ -struct skin_element* skin_parse(const char* document); - -/* Memory management functions */ -char *skin_alloc(size_t size); -struct skin_element* skin_alloc_element(); -struct skin_element** skin_alloc_children(int count); -struct skin_tag_parameter* skin_alloc_params(int count); -char* skin_alloc_string(int length); - -void skin_free_tree(struct skin_element* root); - - -#ifdef __cplusplus -} -#endif - -#endif /* GENERIC_PARSER_H */ diff --git a/utils/themeeditor/parser/skin_scan.c b/utils/themeeditor/parser/skin_scan.c deleted file mode 100644 index 79f7162aab..0000000000 --- a/utils/themeeditor/parser/skin_scan.c +++ /dev/null @@ -1,218 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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_scan.h" -#include "skin_debug.h" -#include "symbols.h" -#include "skin_parser.h" - -/* Scanning Functions */ - -/* Simple function to advance a char* past a comment */ -void skip_comment(char** document) -{ - while(**document != '\n' && **document != '\0') - (*document)++; - if(**document == '\n') - (*document)++; -} - -void skip_whitespace(char** document) -{ - while(**document == ' ' || **document == '\t') - (*document)++; -} - -void skip_arglist(char** document) -{ - if(**document == ARGLISTOPENSYM) - (*document)++; - while(**document && **document != ARGLISTCLOSESYM) - { - if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); - else if(**document == COMMENTSYM) - skip_comment(document); - else - (*document)++; - } - if(**document == ARGLISTCLOSESYM) - (*document)++; -} - -void skip_enumlist(char** document) -{ - if(**document == ENUMLISTOPENSYM) - (*document)++; - while(**document && **document != ENUMLISTCLOSESYM) - { - if(**document == TAGSYM) - { - (*document)++; - if(**document == '\0') - break; - (*document)++; - } - else if(**document == ARGLISTOPENSYM) - skip_arglist(document); - else if(**document == ENUMLISTOPENSYM) - skip_enumlist(document); - else if(**document == COMMENTSYM) - skip_comment(document); - else - (*document)++; - } - - if(**document == ENUMLISTCLOSESYM) - (*document)++; -} - -char* scan_string(char** document) -{ - - char* cursor = *document; - int length = 0; - char* buffer = NULL; - int i; - - while(*cursor != ARGLISTSEPERATESYM && *cursor != ARGLISTCLOSESYM && - *cursor != '\0') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - continue; - } - - if(*cursor == TAGSYM) - cursor++; - - if(*cursor == '\n') - { - skin_error(UNEXPECTED_NEWLINE); - return NULL; - } - - length++; - cursor++; - } - - /* Copying the string */ - cursor = *document; - buffer = skin_alloc_string(length); - buffer[length] = '\0'; - for(i = 0; i < length; i++) - { - if(*cursor == TAGSYM) - cursor++; - - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - i--; - continue; - } - - buffer[i] = *cursor; - cursor++; - } - - *document = cursor; - return buffer; -} - -int scan_int(char** document) -{ - - char* cursor = *document, *end; - int length = 0; - char buffer[16]; - int retval; - int i; - - while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-') - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - continue; - } - - length++; - cursor++; - } - if (length > 15) - length = 15; - end = cursor; - /* Copying to the buffer while avoiding comments */ - cursor = *document; - buffer[length] = '\0'; - for(i = 0; i < length; i++) - { - if(*cursor == COMMENTSYM) - { - skip_comment(&cursor); - i--; - continue; - } - - buffer[i] = *cursor; - cursor++; - - } - retval = atoi(buffer); - - *document = end; - return retval; -} - -int check_viewport(char* document) -{ - if(strlen(document) < 3) - return 0; - - if(document[0] != TAGSYM) - return 0; - - if(document[1] != 'V') - return 0; - - if(document[2] != ARGLISTOPENSYM - && document[2] != 'l' - && document[2] != 'i') - return 0; - - return 1; -} diff --git a/utils/themeeditor/parser/skin_scan.h b/utils/themeeditor/parser/skin_scan.h deleted file mode 100644 index b1d04a6e34..0000000000 --- a/utils/themeeditor/parser/skin_scan.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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. - * - ****************************************************************************/ - -#ifndef SCANNING_H -#define SCANNING_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/* Scanning functions */ -void skip_comment(char** document); -void skip_whitespace(char** document); -void skip_arglist(char** document); -void skip_enumlist(char** document); -char* scan_string(char** document); -int scan_int(char** document); -int check_viewport(char* document); /* Checks for a viewport declaration */ - -#ifdef __cplusplus -} -#endif - -#endif // SCANNING_H diff --git a/utils/themeeditor/parser/symbols.h b/utils/themeeditor/parser/symbols.h deleted file mode 100644 index b4f31289ef..0000000000 --- a/utils/themeeditor/parser/symbols.h +++ /dev/null @@ -1,49 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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. - * - ****************************************************************************/ - -#ifndef SYMBOLS_H -#define SYMBOLS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -/* Symbol definitions for WPS parsing */ - -#define TAGSYM '%' -#define COMMENTSYM '#' -#define CONDITIONSYM '?' -#define MULTILINESYM ';' -#define ARGLISTOPENSYM '(' -#define ARGLISTCLOSESYM ')' -#define ARGLISTSEPERATESYM ',' -#define ENUMLISTSEPERATESYM '|' -#define ENUMLISTOPENSYM '<' -#define ENUMLISTCLOSESYM '>' -#define DEFAULTSYM '-' - -#ifdef __cplusplus -} -#endif - -#endif /* SYMBOLS_H */ diff --git a/utils/themeeditor/parser/tag_table.c b/utils/themeeditor/parser/tag_table.c deleted file mode 100644 index 6d82b47cc3..0000000000 --- a/utils/themeeditor/parser/tag_table.c +++ /dev/null @@ -1,256 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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 "tag_table.h" - -#include -#define BAR_PARAMS "*|iiiiN" -/* The tag definition table */ -struct tag_info legal_tags[] = -{ - { SKIN_TOKEN_ALIGN_CENTER, "ac", "" }, - { SKIN_TOKEN_ALIGN_LEFT, "al", "" }, - { SKIN_TOKEN_ALIGN_LEFT_RTL, "aL", "" }, - { SKIN_TOKEN_ALIGN_RIGHT, "ar", "" }, - { SKIN_TOKEN_ALIGN_RIGHT_RTL, "aR", "" }, - { SKIN_TOKEN_ALIGN_LANGDIRECTION, "ax", "" }, - - { SKIN_TOKEN_BATTERY_PERCENT, "bl" , BAR_PARAMS }, - { SKIN_TOKEN_BATTERY_VOLTS, "bv", "" }, - { SKIN_TOKEN_BATTERY_TIME, "bt", "" }, - { SKIN_TOKEN_BATTERY_SLEEPTIME, "bs", "" }, - { SKIN_TOKEN_BATTERY_CHARGING, "bc", "" }, - { SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, "bp", "" }, - { SKIN_TOKEN_USB_POWERED, "bu", "" }, - - - { SKIN_TOKEN_RTC_PRESENT, "cc", "" }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH, "cd", "" }, - { SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, "ce", "" }, - { SKIN_TOKEN_RTC_12HOUR_CFG, "cf", "" }, - { SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, "cH", "" }, - { SKIN_TOKEN_RTC_HOUR_24, "ck", "" }, - { SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, "cI", "" }, - { SKIN_TOKEN_RTC_HOUR_12, "cl", "" }, - { SKIN_TOKEN_RTC_MONTH, "cm", "" }, - { SKIN_TOKEN_RTC_MINUTE, "cM", "" }, - { SKIN_TOKEN_RTC_SECOND, "cS", "" }, - { SKIN_TOKEN_RTC_YEAR_2_DIGITS, "cy", "" }, - { SKIN_TOKEN_RTC_YEAR_4_DIGITS, "cY", "" }, - { SKIN_TOKEN_RTC_AM_PM_UPPER, "cP", "" }, - { SKIN_TOKEN_RTC_AM_PM_LOWER, "cp", "" }, - { SKIN_TOKEN_RTC_WEEKDAY_NAME, "ca", "" }, - { SKIN_TOKEN_RTC_MONTH_NAME, "cb", "" }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, "cu", "" }, - { SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, "cw", "" }, - - { SKIN_TOKEN_FILE_BITRATE, "fb", "" }, - { SKIN_TOKEN_FILE_CODEC, "fc", "" }, - { SKIN_TOKEN_FILE_FREQUENCY, "ff", "" }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "fk", "" }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "fm", "" }, - { SKIN_TOKEN_FILE_NAME, "fn", "" }, - { SKIN_TOKEN_FILE_PATH, "fp", "" }, - { SKIN_TOKEN_FILE_SIZE, "fs", "" }, - { SKIN_TOKEN_FILE_VBR, "fv", "" }, - { SKIN_TOKEN_FILE_DIRECTORY, "d" , "I" }, - - { SKIN_TOKEN_FILE_BITRATE, "Fb", "" }, - { SKIN_TOKEN_FILE_CODEC, "Fc", "" }, - { SKIN_TOKEN_FILE_FREQUENCY, "Ff", "" }, - { SKIN_TOKEN_FILE_FREQUENCY_KHZ, "Fk", "" }, - { SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, "Fm", "" }, - { SKIN_TOKEN_FILE_NAME, "Fn", "" }, - { SKIN_TOKEN_FILE_PATH, "Fp", "" }, - { SKIN_TOKEN_FILE_SIZE, "Fs", "" }, - { SKIN_TOKEN_FILE_VBR, "Fv", "" }, - { SKIN_TOKEN_FILE_DIRECTORY, "D" , "I" }, - - - { SKIN_TOKEN_METADATA_ARTIST, "ia", "" }, - { SKIN_TOKEN_METADATA_COMPOSER, "ic", "" }, - { SKIN_TOKEN_METADATA_ALBUM, "id", "" }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "iA", "" }, - { SKIN_TOKEN_METADATA_GROUPING, "iG", "" }, - { SKIN_TOKEN_METADATA_GENRE, "ig", "" }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "ik", "" }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "in", "" }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "it", "" }, - { SKIN_TOKEN_METADATA_VERSION, "iv", "" }, - { SKIN_TOKEN_METADATA_YEAR, "iy", "" }, - { SKIN_TOKEN_METADATA_COMMENT, "iC", "" }, - - { SKIN_TOKEN_METADATA_ARTIST, "Ia", "" }, - { SKIN_TOKEN_METADATA_COMPOSER, "Ic", "" }, - { SKIN_TOKEN_METADATA_ALBUM, "Id", "" }, - { SKIN_TOKEN_METADATA_ALBUM_ARTIST, "IA", "" }, - { SKIN_TOKEN_METADATA_GROUPING, "IG", "" }, - { SKIN_TOKEN_METADATA_GENRE, "Ig", "" }, - { SKIN_TOKEN_METADATA_DISC_NUMBER, "Ik", "" }, - { SKIN_TOKEN_METADATA_TRACK_NUMBER, "In", "" }, - { SKIN_TOKEN_METADATA_TRACK_TITLE, "It", "" }, - { SKIN_TOKEN_METADATA_VERSION, "Iv", "" }, - { SKIN_TOKEN_METADATA_YEAR, "Iy", "" }, - { SKIN_TOKEN_METADATA_COMMENT, "IC", "" }, - - { SKIN_TOKEN_SOUND_PITCH, "Sp", "" }, - { SKIN_TOKEN_SOUND_SPEED, "Ss", "" }, - - { SKIN_TOKEN_VLED_HDD, "lh", "" }, - - { SKIN_TOKEN_MAIN_HOLD, "mh", "" }, - { SKIN_TOKEN_REMOTE_HOLD, "mr", "" }, - { SKIN_TOKEN_REPEAT_MODE, "mm", "" }, - { SKIN_TOKEN_PLAYBACK_STATUS, "mp", "" }, - { SKIN_TOKEN_BUTTON_VOLUME, "mv", "|S" }, - - { SKIN_TOKEN_PEAKMETER, "pm", "" }, - { SKIN_TOKEN_PLAYER_PROGRESSBAR, "pf", "" }, - { SKIN_TOKEN_PROGRESSBAR, "pb" , BAR_PARAMS }, - { SKIN_TOKEN_VOLUME, "pv" , BAR_PARAMS }, - - { SKIN_TOKEN_TRACK_ELAPSED_PERCENT, "px", "" }, - { SKIN_TOKEN_TRACK_TIME_ELAPSED, "pc", "" }, - { SKIN_TOKEN_TRACK_TIME_REMAINING, "pr", "" }, - { SKIN_TOKEN_TRACK_LENGTH, "pt", "" }, - { SKIN_TOKEN_TRACK_STARTING, "pS" , "|S"}, - { SKIN_TOKEN_TRACK_ENDING, "pE" , "|S"}, - { SKIN_TOKEN_PLAYLIST_POSITION, "pp", "" }, - { SKIN_TOKEN_PLAYLIST_ENTRIES, "pe", "" }, - { SKIN_TOKEN_PLAYLIST_NAME, "pn", "" }, - { SKIN_TOKEN_PLAYLIST_SHUFFLE, "ps", "" }, - - { SKIN_TOKEN_DATABASE_PLAYCOUNT, "rp", "" }, - { SKIN_TOKEN_DATABASE_RATING, "rr", "" }, - { SKIN_TOKEN_DATABASE_AUTOSCORE, "ra", "" }, - - { SKIN_TOKEN_REPLAYGAIN, "rg", "" }, - { SKIN_TOKEN_CROSSFADE, "xf", "" }, - - { SKIN_TOKEN_HAVE_TUNER, "tp", "" }, - { SKIN_TOKEN_TUNER_TUNED, "tt", "" }, - { SKIN_TOKEN_TUNER_SCANMODE, "tm", "" }, - { SKIN_TOKEN_TUNER_STEREO, "ts", "" }, - { SKIN_TOKEN_TUNER_MINFREQ, "ta", "" }, - { SKIN_TOKEN_TUNER_MAXFREQ, "tb", "" }, - { SKIN_TOKEN_TUNER_CURFREQ, "tf", "" }, - { SKIN_TOKEN_PRESET_ID, "Ti", "" }, - { SKIN_TOKEN_PRESET_NAME, "Tn", "" }, - { SKIN_TOKEN_PRESET_FREQ, "Tf", "" }, - { SKIN_TOKEN_PRESET_COUNT, "Tc", "" }, - { SKIN_TOKEN_HAVE_RDS, "tx", "" }, - { SKIN_TOKEN_RDS_NAME, "ty", "" }, - { SKIN_TOKEN_RDS_TEXT, "tz", "" }, - - { SKIN_TOKEN_SUBLINE_SCROLL, "s", "" }, - { SKIN_TOKEN_SUBLINE_TIMEOUT, "t" , "S" }, - - { SKIN_TOKEN_ENABLE_THEME, "we", "" }, - { SKIN_TOKEN_DISABLE_THEME, "wd", "" }, - { SKIN_TOKEN_DRAW_INBUILTBAR, "wi", "" }, - - { SKIN_TOKEN_IMAGE_PRELOAD, "xl", "SFII|I" }, - { SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, "xd", "S" }, - { SKIN_TOKEN_IMAGE_PRELOAD, "x", "SFII" }, - - { SKIN_TOKEN_LOAD_FONT, "Fl" , "IF"}, - { SKIN_TOKEN_ALBUMART_LOAD, "Cl" , "IIII|ss"}, - { SKIN_TOKEN_ALBUMART_DISPLAY, "Cd" , ""}, - { SKIN_TOKEN_ALBUMART_FOUND, "C" , ""}, - - { SKIN_TOKEN_VIEWPORT_ENABLE, "Vd" , "S"}, - { SKIN_TOKEN_UIVIEWPORT_ENABLE, "VI" , "S"}, - - { SKIN_TOKEN_VIEWPORT_CUSTOMLIST, "Vp" , "ICC"}, - { SKIN_TOKEN_LIST_TITLE_TEXT, "Lt" , ""}, - { SKIN_TOKEN_LIST_TITLE_ICON, "Li" , ""}, - - { SKIN_TOKEN_VIEWPORT_FGCOLOUR, "Vf" , "S"}, - { SKIN_TOKEN_VIEWPORT_BGCOLOUR, "Vb" , "S"}, - - { SKIN_TOKEN_VIEWPORT_CONDITIONAL, "Vl" , "SIIiii|ii"}, - { SKIN_TOKEN_UIVIEWPORT_LOAD, "Vi" , "sIIiii|ii"}, - { SKIN_TOKEN_VIEWPORT_LOAD, "V" , "IIiii|ii"}, - - { SKIN_TOKEN_IMAGE_BACKDROP, "X" , "f"}, - - { SKIN_TOKEN_SETTING, "St" , "S"}, - { SKIN_TOKEN_TRANSLATEDSTRING, "Sx" , "S"}, - { SKIN_TOKEN_LANG_IS_RTL, "Sr" , ""}, - - { SKIN_TOKEN_LASTTOUCH, "Tl" , "|S"}, - { SKIN_TOKEN_CURRENT_SCREEN, "cs", "" }, - { SKIN_TOKEN_TOUCHREGION, "T" , "IIiiS"}, - - { SKIN_TOKEN_HAVE_RECORDING, "Rp" , ""}, - { SKIN_TOKEN_IS_RECORDING, "Rr" , ""}, - { SKIN_TOKEN_REC_FREQ, "Rf" , ""}, - { SKIN_TOKEN_REC_ENCODER, "Re" , ""}, - { SKIN_TOKEN_REC_BITRATE, "Rb" , ""}, - { SKIN_TOKEN_REC_MONO, "Rm" , ""}, - { SKIN_TOKEN_REC_SECONDS, "Rs" , ""}, - { SKIN_TOKEN_REC_MINUTES, "Rn" , ""}, - { SKIN_TOKEN_REC_HOURS, "Rh" , ""}, - - { SKIN_TOKEN_UNKNOWN, "" , ""} - /* Keep this here to mark the end of the table */ -}; - -/* A table of legal escapable characters */ -char legal_escape_characters[] = "%(,);#<|>"; - -/* - * Just does a straight search through the tag table to find one by - * the given name - */ -struct tag_info* find_tag(char* name) -{ - - struct tag_info* current = legal_tags; - - /* - * Continue searching so long as we have a non-empty name string - * and the name of the current element doesn't match the name - * we're searching for - */ - - while(strcmp(current->name, name) && current->name[0] != '\0') - current++; - - if(current->name[0] == '\0') - return NULL; - else - return current; - -} - -/* Searches through the legal escape characters string */ -int find_escape_character(char lookup) -{ - char* current = legal_escape_characters; - while(*current != lookup && *current != '\0') - current++; - - if(*current == lookup && *current) - return 1; - else - return 0; -} diff --git a/utils/themeeditor/parser/tag_table.h b/utils/themeeditor/parser/tag_table.h deleted file mode 100644 index ec9a1021ab..0000000000 --- a/utils/themeeditor/parser/tag_table.h +++ /dev/null @@ -1,307 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Robert Bieber - * - * 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. - * - ****************************************************************************/ - -#ifndef TAG_TABLE_H -#define TAG_TABLE_H - -#ifdef __cplusplus -extern "C" -{ -#endif - - -enum skin_token_type { - - TOKEN_MARKER_CONTROL_TOKENS = -1, - SKIN_TOKEN_UNKNOWN, - - /* Markers */ - SKIN_TOKEN_CHARACTER, - SKIN_TOKEN_STRING, - SKIN_TOKEN_TRANSLATEDSTRING, - - /* Alignment */ - SKIN_TOKEN_ALIGN_LEFT, - SKIN_TOKEN_ALIGN_LEFT_RTL, - SKIN_TOKEN_ALIGN_CENTER, - SKIN_TOKEN_ALIGN_RIGHT, - SKIN_TOKEN_ALIGN_RIGHT_RTL, - SKIN_TOKEN_ALIGN_LANGDIRECTION, - - - /* Sublines */ - SKIN_TOKEN_SUBLINE_TIMEOUT, - SKIN_TOKEN_SUBLINE_SCROLL, - - /* Conditional */ - SKIN_TOKEN_CONDITIONAL, - SKIN_TOKEN_CONDITIONAL_START, - SKIN_TOKEN_CONDITIONAL_OPTION, - SKIN_TOKEN_CONDITIONAL_END, - - /* Viewport display */ - SKIN_TOKEN_VIEWPORT_LOAD, - SKIN_TOKEN_VIEWPORT_CONDITIONAL, - SKIN_TOKEN_VIEWPORT_ENABLE, - SKIN_TOKEN_VIEWPORT_CUSTOMLIST, - SKIN_TOKEN_UIVIEWPORT_ENABLE, - SKIN_TOKEN_UIVIEWPORT_LOAD, - SKIN_TOKEN_VIEWPORT_FGCOLOUR, - SKIN_TOKEN_VIEWPORT_BGCOLOUR, - - /* Battery */ - TOKEN_MARKER_BATTERY, - SKIN_TOKEN_BATTERY_PERCENT, - SKIN_TOKEN_BATTERY_PERCENTBAR, - SKIN_TOKEN_BATTERY_VOLTS, - SKIN_TOKEN_BATTERY_TIME, - SKIN_TOKEN_BATTERY_CHARGER_CONNECTED, - SKIN_TOKEN_BATTERY_CHARGING, - SKIN_TOKEN_BATTERY_SLEEPTIME, - SKIN_TOKEN_USB_POWERED, - - /* Sound */ - TOKEN_MARKER_SOUND, - SKIN_TOKEN_SOUND_PITCH, - SKIN_TOKEN_SOUND_SPEED, - SKIN_TOKEN_REPLAYGAIN, - SKIN_TOKEN_CROSSFADE, - - /* Time */ - TOKEN_MARKER_RTC, - SKIN_TOKEN_RTC_PRESENT, - - /* The begin/end values allow us to know if a token is an RTC one. - New RTC tokens should be added between the markers. */ - - SKIN_TOKENs_RTC_BEGIN, /* just the start marker, not an actual token */ - - SKIN_TOKEN_RTC_DAY_OF_MONTH, - SKIN_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED, - SKIN_TOKEN_RTC_12HOUR_CFG, - SKIN_TOKEN_RTC_HOUR_24_ZERO_PADDED, - SKIN_TOKEN_RTC_HOUR_24, - SKIN_TOKEN_RTC_HOUR_12_ZERO_PADDED, - SKIN_TOKEN_RTC_HOUR_12, - SKIN_TOKEN_RTC_MONTH, - SKIN_TOKEN_RTC_MINUTE, - SKIN_TOKEN_RTC_SECOND, - SKIN_TOKEN_RTC_YEAR_2_DIGITS, - SKIN_TOKEN_RTC_YEAR_4_DIGITS, - SKIN_TOKEN_RTC_AM_PM_UPPER, - SKIN_TOKEN_RTC_AM_PM_LOWER, - SKIN_TOKEN_RTC_WEEKDAY_NAME, - SKIN_TOKEN_RTC_MONTH_NAME, - SKIN_TOKEN_RTC_DAY_OF_WEEK_START_MON, - SKIN_TOKEN_RTC_DAY_OF_WEEK_START_SUN, - - SKIN_TOKENS_RTC_END, /* just the end marker, not an actual token */ - - /* Database */ - TOKEN_MARKER_DATABASE, - SKIN_TOKEN_DATABASE_PLAYCOUNT, - SKIN_TOKEN_DATABASE_RATING, - SKIN_TOKEN_DATABASE_AUTOSCORE, - - /* File */ - TOKEN_MARKER_FILE, - SKIN_TOKEN_FILE_BITRATE, - SKIN_TOKEN_FILE_CODEC, - SKIN_TOKEN_FILE_FREQUENCY, - SKIN_TOKEN_FILE_FREQUENCY_KHZ, - SKIN_TOKEN_FILE_NAME, - SKIN_TOKEN_FILE_NAME_WITH_EXTENSION, - SKIN_TOKEN_FILE_PATH, - SKIN_TOKEN_FILE_SIZE, - SKIN_TOKEN_FILE_VBR, - SKIN_TOKEN_FILE_DIRECTORY, - - /* Image */ - TOKEN_MARKER_IMAGES, - SKIN_TOKEN_IMAGE_BACKDROP, - SKIN_TOKEN_IMAGE_PROGRESS_BAR, - SKIN_TOKEN_IMAGE_PRELOAD, - SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY, - SKIN_TOKEN_IMAGE_DISPLAY, - - /* Albumart */ - SKIN_TOKEN_ALBUMART_LOAD, - SKIN_TOKEN_ALBUMART_DISPLAY, - SKIN_TOKEN_ALBUMART_FOUND, - - /* Metadata */ - TOKEN_MARKER_METADATA, - SKIN_TOKEN_METADATA_ARTIST, - SKIN_TOKEN_METADATA_COMPOSER, - SKIN_TOKEN_METADATA_ALBUM_ARTIST, - SKIN_TOKEN_METADATA_GROUPING, - SKIN_TOKEN_METADATA_ALBUM, - SKIN_TOKEN_METADATA_GENRE, - SKIN_TOKEN_METADATA_DISC_NUMBER, - SKIN_TOKEN_METADATA_TRACK_NUMBER, - SKIN_TOKEN_METADATA_TRACK_TITLE, - SKIN_TOKEN_METADATA_VERSION, - SKIN_TOKEN_METADATA_YEAR, - SKIN_TOKEN_METADATA_COMMENT, - - TOKEN_MARKER_PLAYBACK_INFO, - /* Mode */ - SKIN_TOKEN_REPEAT_MODE, - SKIN_TOKEN_PLAYBACK_STATUS, - /* Progressbar */ - SKIN_TOKEN_PROGRESSBAR, - SKIN_TOKEN_PLAYER_PROGRESSBAR, - /* Peakmeter */ - SKIN_TOKEN_PEAKMETER, - - /* Current track */ - SKIN_TOKEN_TRACK_ELAPSED_PERCENT, - SKIN_TOKEN_TRACK_TIME_ELAPSED, - SKIN_TOKEN_TRACK_TIME_REMAINING, - SKIN_TOKEN_TRACK_LENGTH, - SKIN_TOKEN_TRACK_STARTING, - SKIN_TOKEN_TRACK_ENDING, - - /* Playlist */ - TOKEN_MARKER_PLAYLIST, - SKIN_TOKEN_PLAYLIST_ENTRIES, - SKIN_TOKEN_PLAYLIST_NAME, - SKIN_TOKEN_PLAYLIST_POSITION, - SKIN_TOKEN_PLAYLIST_SHUFFLE, - - - TOKEN_MARKER_MISC, - SKIN_TOKEN_ENABLE_THEME, - SKIN_TOKEN_DISABLE_THEME, - SKIN_TOKEN_DRAW_INBUILTBAR, - SKIN_TOKEN_LIST_TITLE_TEXT, - SKIN_TOKEN_LIST_TITLE_ICON, - - SKIN_TOKEN_LOAD_FONT, - - /* buttons */ - SKIN_TOKEN_BUTTON_VOLUME, - SKIN_TOKEN_LASTTOUCH, - SKIN_TOKEN_TOUCHREGION, - /* Virtual LED */ - SKIN_TOKEN_VLED_HDD, - /* Volume level */ - SKIN_TOKEN_VOLUME, - SKIN_TOKEN_VOLUMEBAR, - /* hold */ - SKIN_TOKEN_MAIN_HOLD, - SKIN_TOKEN_REMOTE_HOLD, - - /* Setting option */ - SKIN_TOKEN_SETTING, - SKIN_TOKEN_CURRENT_SCREEN, - SKIN_TOKEN_LANG_IS_RTL, - - /* Recording Tokens */ - TOKEN_MARKER_RECORDING, - SKIN_TOKEN_HAVE_RECORDING, - SKIN_TOKEN_IS_RECORDING, - SKIN_TOKEN_REC_FREQ, - SKIN_TOKEN_REC_ENCODER, - SKIN_TOKEN_REC_BITRATE, /* SWCODEC: MP3 bitrate, HWCODEC: MP3 "quality" */ - SKIN_TOKEN_REC_MONO, - SKIN_TOKEN_REC_SECONDS, - SKIN_TOKEN_REC_MINUTES, - SKIN_TOKEN_REC_HOURS, - - - /* Radio Tokens */ - TOKEN_MARKER_TUNER, - SKIN_TOKEN_HAVE_TUNER, - SKIN_TOKEN_TUNER_TUNED, - SKIN_TOKEN_TUNER_SCANMODE, - SKIN_TOKEN_TUNER_STEREO, - SKIN_TOKEN_TUNER_MINFREQ, /* changes based on "region" */ - SKIN_TOKEN_TUNER_MAXFREQ, /* changes based on "region" */ - SKIN_TOKEN_TUNER_CURFREQ, - SKIN_TOKEN_PRESET_ID, /* "id" of this preset.. really the array element number */ - SKIN_TOKEN_PRESET_NAME, - SKIN_TOKEN_PRESET_FREQ, - SKIN_TOKEN_PRESET_COUNT, - /* RDS tokens */ - SKIN_TOKEN_HAVE_RDS, - SKIN_TOKEN_RDS_NAME, - SKIN_TOKEN_RDS_TEXT, - - - TOKEN_MARKER_END, /* this needs to be the last value in this enum */ -}; - -/* - * Struct for tag parsing information - * name - The name of the tag, i.e. V for %V - * params - A string specifying all of the tags parameters, each - * character representing a single parameter. Valid - * characters for parameters are: - * I - Required integer - * i - Nullable integer - * S - Required string - * s - Nullable string - * F - Required file name - * f - Nullable file name - * C - Required skin code - * N - any amount of strings.. must be the last param in the list - * Any nullable parameter may be replaced in the WPS file - * with a '-'. To specify that parameters may be left off - * altogether, place a '|' in the parameter string. For - * instance, with the parameter string... - * Ii|Ss - * one integer must be specified, one integer can be - * specified or set to default with '-', and the user can - * stop providing parameters at any time after that. - * To specify multiple instances of the same type, put a - * number before the character. For instance, the string... - * 2s - * will specify two strings. An asterisk (*) at the beginning of the - * string will specify that you may choose to omit all arguments - * - */ -struct tag_info -{ - enum skin_token_type type; - char* name; - char* params; - -}; - -/* - * Finds a tag by name and returns its parameter list, or an empty - * string if the tag is not found in the table - */ -struct tag_info* find_tag(char* name); - -/* - * Determines whether a character is legal to escape or not. If - * lookup is not found in the legal escape characters string, returns - * false, otherwise returns true - */ -int find_escape_character(char lookup); - -#ifdef __cplusplus -} -#endif - -#endif /* TAG_TABLE_H */ diff --git a/utils/themeeditor/themeeditor.pro b/utils/themeeditor/themeeditor.pro index 213bcd82d3..bf48bda7f2 100644 --- a/utils/themeeditor/themeeditor.pro +++ b/utils/themeeditor/themeeditor.pro @@ -5,17 +5,26 @@ UI_DIR = $$MYBUILDDIR/ui MOC_DIR = $$MYBUILDDIR/moc RCC_DIR = $$MYBUILDDIR/rcc +RBBASE_DIR = $$_PRO_FILE_PWD_ +RBBASE_DIR = $$replace(RBBASE_DIR,/utils/themeeditor,) + #Include directories INCLUDEPATH += gui -INCLUDEPATH += parser INCLUDEPATH += models -HEADERS += parser/tag_table.h \ - parser/symbols.h \ - parser/skin_parser.h \ - parser/skin_scan.h \ - parser/skin_debug.h \ - models/parsetreemodel.h \ + +# Stuff for the parse lib +libskin_parser.commands = @$(MAKE) \ + BUILDDIR=$$OBJECTS_DIR -C $$RBBASE_DIR/lib/skin_parser CC=\"$$QMAKE_CC\" +QMAKE_EXTRA_TARGETS += libskin_parser +PRE_TARGETDEPS += libskin_parser +INCLUDEPATH += $$RBBASE_DIR/lib/skin_parser +LIBS += -L$$OBJECTS_DIR -lskin_parser + + +DEPENDPATH = $$INCLUDEPATH + +HEADERS += models/parsetreemodel.h \ models/parsetreenode.h \ gui/editorwindow.h \ gui/skinhighlighter.h \ @@ -26,11 +35,7 @@ HEADERS += parser/tag_table.h \ gui/tabcontent.h \ gui/configdocument.h \ gui/skinviewer.h -SOURCES += parser/tag_table.c \ - parser/skin_parser.c \ - parser/skin_scan.c \ - parser/skin_debug.c \ - main.cpp \ +SOURCES += main.cpp \ models/parsetreemodel.cpp \ models/parsetreenode.cpp \ gui/editorwindow.cpp \ -- cgit v1.2.3