blob: c53896ca30839fb89c00839d0ddedc36bc19364f [file] [log] [blame]
/***************************************************************************
* __________ __ ___.
* 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>
#include <stdbool.h>
#if defined(ROCKBOX) && !defined(__PCTOOL__)
/* Use this type and macro to convert a pointer from the
* skin buffer to a useable pointer */
typedef long skinoffset_t;
#define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset]))
#define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1)
/* Use this macro when declaring a variable to self-document the code.
* type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo )
*
* WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont
* do what you expect.
*/
#define OFFSETTYPE(type) skinoffset_t
#else
#define SKINOFFSETTOPTR(base, offset) offset
#define PTRTOSKINOFFSET(base, pointer) pointer
#define OFFSETTYPE(type) type
#endif
/********************************************************************
****** Data Structures *********************************************
*******************************************************************/
/* Possible types of element in a WPS file */
enum skin_element_type
{
UNKNOWN = -1,
VIEWPORT,
LINE_ALTERNATOR,
LINE,
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,
DECIMAL_EXPECTED,
SEPARATOR_EXPECTED,
CLOSE_EXPECTED,
MULTILINE_EXPECTED,
GOT_CALLBACK_ERROR
};
/* Holds a tag parameter, either numeric or text */
struct skin_tag_parameter
{
enum
{
INTEGER,
DECIMAL, /* stored in data.number as (whole*10)+part */
PERCENT, /* stored in data.number as (whole*10)+part */
STRING,
CODE,
DEFAULT
} type;
union
{
int number;
OFFSETTYPE(char*) text;
OFFSETTYPE(struct skin_element*) code;
} data;
char type_code;
};
/* Defines an element of a SKIN file,
*
* This is allocated a lot, so it's optimized for size */
struct skin_element
{
/* Link to the next element */
OFFSETTYPE(struct skin_element*) next;
/* Pointer to an array of children */
OFFSETTYPE(struct skin_element**) children;
/* 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
*/
OFFSETTYPE(void*) data;
/* The tag or conditional name */
const struct tag_info *tag;
/* Pointer to an array of parameters */
OFFSETTYPE(struct skin_tag_parameter*) params;
/* Number of elements in the children array */
short children_count;
/* The line on which it's defined in the source file */
short line;
/* Defines what type of element it is */
enum skin_element_type type;
/* Number of elements in the params array */
char params_count;
};
enum skin_cb_returnvalue
{
CALLBACK_ERROR = -666,
FEATURE_NOT_AVAILABLE,
CALLBACK_OK = 0,
/* > 0 reserved for future use */
};
typedef int (*skin_callback)(struct skin_element* element, void* data);
/***********************************************************************
***** Functions *******************************************************
**********************************************************************/
/* Parses a WPS document and returns a list of skin_element
structures. */
#ifdef ROCKBOX
struct skin_element* skin_parse(const char* document,
skin_callback callback, void* callback_data);
#else
struct skin_element* skin_parse(const char* document);
#endif
/* Memory management functions */
struct skin_element* skin_alloc_element(void);
OFFSETTYPE(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 */