mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-20 18:42:41 -05:00
Move the skin parser to a seperate library
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26877 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ca564287ee
commit
36b934d241
11 changed files with 45 additions and 12 deletions
|
|
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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(" ");
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
|
@ -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 <stdlib.h>
|
||||
|
||||
/********************************************************************
|
||||
****** 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 */
|
||||
|
|
@ -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 <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 <string.h>
|
||||
#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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue