summaryrefslogtreecommitdiff
path: root/utils/themeeditor/skin_parser.c
diff options
context:
space:
mode:
authorRobert Bieber <robby@bieberphoto.com>2010-06-17 05:37:01 +0000
committerRobert Bieber <robby@bieberphoto.com>2010-06-17 05:37:01 +0000
commitca564287ee3f48945d45c7d92be7a83452f53745 (patch)
treed6e502bb604f925240a742b3bac2c813a98c447b /utils/themeeditor/skin_parser.c
parentba07b2055c7eb8f2add96f55cb52b40b9ccb3d63 (diff)
downloadrockbox-ca564287ee3f48945d45c7d92be7a83452f53745.zip
rockbox-ca564287ee3f48945d45c7d92be7a83452f53745.tar.gz
rockbox-ca564287ee3f48945d45c7d92be7a83452f53745.tar.bz2
rockbox-ca564287ee3f48945d45c7d92be7a83452f53745.tar.xz
Theme Editor: Moved source files into subdirectories
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26876 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/themeeditor/skin_parser.c')
-rw-r--r--utils/themeeditor/skin_parser.c923
1 files changed, 0 insertions, 923 deletions
diff --git a/utils/themeeditor/skin_parser.c b/utils/themeeditor/skin_parser.c
deleted file mode 100644
index 93a7191..0000000
--- a/utils/themeeditor/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 <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
-}