summaryrefslogtreecommitdiffstats
path: root/lib/skin_parser
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-11-15 14:11:08 +0000
commit9e07ef2b0adb8fca7e5a9e516397e533653f8836 (patch)
tree0a283550421917e52ee04068b84a464976f0c4f2 /lib/skin_parser
parent101693fd3047fb64e766580e80635a424fa25c4d (diff)
downloadrockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.tar.gz
rockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.tar.bz2
rockbox-9e07ef2b0adb8fca7e5a9e516397e533653f8836.zip
Use buflib for all skin engine allocations.
Massive thanks to Michael Chicoine and other testers for finding the early bugs. This removes all skin memory limitations git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30991 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'lib/skin_parser')
-rw-r--r--lib/skin_parser/skin_buffer.c73
-rw-r--r--lib/skin_parser/skin_buffer.h15
-rw-r--r--lib/skin_parser/skin_debug.c27
-rw-r--r--lib/skin_parser/skin_parser.c178
-rw-r--r--lib/skin_parser/skin_parser.h35
5 files changed, 165 insertions, 163 deletions
diff --git a/lib/skin_parser/skin_buffer.c b/lib/skin_parser/skin_buffer.c
index 5a9d4464b8..d18122ef20 100644
--- a/lib/skin_parser/skin_buffer.c
+++ b/lib/skin_parser/skin_buffer.c
@@ -47,54 +47,26 @@
#ifdef ROCKBOX
#include "config.h"
#include "skin_debug.h"
-
-#ifdef APPLICATION
-# define USE_HOST_MALLOC
-#else
-# define USE_ROCKBOX_ALLOC
-#endif
-
-#endif
-
-#ifdef USE_ROCKBOX_ALLOC
static size_t buf_size;
static unsigned char *buffer_start = NULL;
static unsigned char *buffer_front = NULL;
-#endif
-
-#ifdef USE_HOST_MALLOC
-
-struct malloc_object {
- struct malloc_object *next;
- char buf[0];
-};
-static struct malloc_object *malloced_head = NULL, *malloced_tail = NULL;
-static void skin_free_malloced(void)
+#ifndef __PCTOOL__
+long skin_buffer_to_offset(void *pointer)
{
- struct malloc_object *obj = malloced_head;
- struct malloc_object *this;
- while (obj)
- {
- this = obj;
- obj = this->next;
- free(this);
- }
- malloced_head = NULL;
- malloced_tail = NULL;
+ return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start;
}
+void* skin_buffer_from_offset(long offset)
+{
+ return offset < 0 ? NULL : buffer_start + offset;
+}
#endif
void skin_buffer_init(char* buffer, size_t size)
{
-#ifdef USE_ROCKBOX_ALLOC
buffer_start = buffer_front = buffer;
buf_size = size;
-#elif defined(USE_HOST_MALLOC)
- (void)buffer; (void)size;
- skin_free_malloced();
-#endif
}
/* Allocate size bytes from the buffer */
@@ -108,8 +80,6 @@ void* skin_buffer_alloc(size_t size)
{
void *retval = NULL;
#endif
-
-#ifdef USE_ROCKBOX_ALLOC
/* 32-bit aligned */
size = (size + 3) & ~3;
if (size > skin_buffer_freespace())
@@ -119,25 +89,9 @@ void* skin_buffer_alloc(size_t size)
}
retval = buffer_front;
buffer_front += size;
-#elif defined(USE_HOST_MALLOC)
- size_t malloc_size = sizeof(struct malloc_object) + size;
- struct malloc_object *obj = malloc(malloc_size);
- retval = &obj->buf;
- obj->next = NULL;
- if (malloced_tail == NULL)
- malloced_head = malloced_tail = obj;
- else
- malloced_tail->next = obj;
- malloced_tail = obj;
-
-#else
- retval = malloc(size);
-#endif
return retval;
}
-
-#ifdef USE_ROCKBOX_ALLOC
/* get the number of bytes currently being used */
size_t skin_buffer_usage(void)
{
@@ -147,16 +101,9 @@ size_t skin_buffer_freespace(void)
{
return buf_size - skin_buffer_usage();
}
-
-static unsigned char *saved_buffer_pos = NULL;
-void skin_buffer_save_position(void)
-{
- saved_buffer_pos = buffer_front;
-}
-
-void skin_buffer_restore_position(void)
+#else
+void* skin_buffer_alloc(size_t size)
{
- if (saved_buffer_pos)
- buffer_front = saved_buffer_pos;
+ return malloc(size);
}
#endif
diff --git a/lib/skin_parser/skin_buffer.h b/lib/skin_parser/skin_buffer.h
index b2ed34e09f..7c9bb0b9c0 100644
--- a/lib/skin_parser/skin_buffer.h
+++ b/lib/skin_parser/skin_buffer.h
@@ -28,6 +28,18 @@
void skin_buffer_init(char* buffer, size_t size);
/* Allocate size bytes from the buffer */
+#ifndef __PCTOOL__
+#define INVALID_OFFSET (-1)
+#define IS_VALID_OFFSET(o) ((o) >= 0)
+long skin_buffer_to_offset(void *pointer);
+void* skin_buffer_from_offset(long offset);
+#else
+#define INVALID_OFFSET (NULL)
+#define IS_VALID_OFFSET(o) ((o) != NULL)
+#define skin_buffer_to_offset(p) p
+#define skin_buffer_from_offset(o) o
+#endif
+
/* #define DEBUG_SKIN_ALLOCATIONS */
#ifdef DEBUG_SKIN_ALLOCATIONS
@@ -44,7 +56,4 @@ void* skin_buffer_alloc(size_t size);
size_t skin_buffer_usage(void);
size_t skin_buffer_freespace(void);
-/* save and restore a buffer position incase a skin fails to load */
-void skin_buffer_save_position(void);
-void skin_buffer_restore_position(void);
#endif
diff --git a/lib/skin_parser/skin_debug.c b/lib/skin_parser/skin_debug.c
index 52f9127f1f..ecf238f1b1 100644
--- a/lib/skin_parser/skin_debug.c
+++ b/lib/skin_parser/skin_debug.c
@@ -31,6 +31,7 @@
int debug_indent_level = 0;
extern int skin_line;
extern char* skin_start;
+extern char* skin_buffer;
/* Global error variables */
int error_line;
@@ -38,6 +39,14 @@ int error_col;
const char *error_line_start;
char* error_message;
+
+static inline struct skin_element*
+get_child(OFFSETTYPE(struct skin_element**) children, int child)
+{
+ struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children);
+ return kids[child];
+}
+
/* Debugging functions */
void skin_error(enum skin_errorcode error, const char* cursor)
{
@@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root)
printf("{ Viewport \n");
debug_indent_level++;
- skin_debug_tree(current->children[0]);
+ skin_debug_tree(get_child(current->children, 0));
debug_indent_level--;
printf("}");
break;
case TEXT:
- text = current->data;
+ text = SKINOFFSETTOPTR(skin_buffer, current->data);
printf("* Plain text on line %d: \"%s\"\n", current->line, text);
break;
@@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root)
current->tag->name,
current->line, current->params_count);
debug_indent_level++;
- skin_debug_params(current->params_count, current->params);
+ skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params));
debug_indent_level--;
skin_debug_indent();
printf(")\n");
@@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root)
debug_indent_level++;
for(i = 0; i < current->children_count; i++)
{
- skin_debug_tree(current->children[i]);
+ skin_debug_tree(get_child(current->children, i));
}
debug_indent_level--;
@@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root)
skin_debug_indent();
printf("[ Enumeration %d\n", i);
debug_indent_level++;
- skin_debug_tree(current->children[i]);
+ skin_debug_tree(get_child(current->children, i));
debug_indent_level--;
skin_debug_indent();
printf("]\n");
@@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root)
debug_indent_level++;
if (current->children)
- skin_debug_tree(current->children[0]);
+ skin_debug_tree(get_child(current->children, 0));
debug_indent_level--;
skin_debug_indent();
@@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root)
break;
}
- current = current->next;
+ current = SKINOFFSETTOPTR(skin_buffer, current->next);
}
}
@@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
break;
case STRING:
- printf("string: \"%s\"", params[i].data.text);
+ printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text));
break;
case INTEGER:
@@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[])
case CODE:
printf("Skin Code: \n");
debug_indent_level++;
- skin_debug_tree(params[i].data.code);
+ skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code));
debug_indent_level--;
skin_debug_indent();
break;
diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c
index 2612cc8906..c49ac12a59 100644
--- a/lib/skin_parser/skin_parser.c
+++ b/lib/skin_parser/skin_parser.c
@@ -37,8 +37,6 @@ int skin_line = 0;
char* skin_start = 0;
int viewport_line = 0;
-static int tag_recursion_level = 0;
-
#ifdef ROCKBOX
static skin_callback callback = NULL;
static void* callback_data;
@@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document)
struct skin_element* root = NULL;
struct skin_element* last = NULL;
- struct skin_element** to_write = 0;
-
const char* cursor = document; /*Keeps track of location in the document*/
skin_line = 1;
@@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document)
while(*cursor != '\0')
{
+ struct skin_element* tree = skin_parse_viewport(&cursor);
if(!root)
- to_write = &root;
+ {
+ root = tree;
+ last = root;
+ }
else
- to_write = &(last->next);
-
+ {
+ last->next = skin_buffer_to_offset(tree);
+ last = tree;
+ }
- *to_write = skin_parse_viewport(&cursor);
- last = *to_write;
if(!last)
{
skin_free_tree(root); /* Clearing any memory already used */
@@ -108,8 +108,8 @@ struct skin_element* skin_parse(const char* document)
}
/* Making sure last is at the end */
- while(last->next)
- last = last->next;
+ while(IS_VALID_OFFSET(last->next))
+ last = skin_buffer_from_offset(last->next);
}
return root;
@@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document)
struct skin_element* root = NULL;
struct skin_element* last = NULL;
struct skin_element* retval = NULL;
-
- tag_recursion_level = 0;
retval = skin_alloc_element();
if (!retval)
@@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document)
retval->line = skin_line;
viewport_line = skin_line;
- struct skin_element** to_write = 0;
+ OFFSETTYPE(struct skin_element*)* children;
const char* cursor = *document; /* Keeps track of location in the document */
const char* bookmark; /* Used when we need to look ahead */
@@ -165,8 +163,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
return retval;
}
retval->children_count = 1;
- retval->children = skin_alloc_children(1);
- if (!retval->children)
+ children = skin_alloc_children(1);
+ if (!children)
return NULL;
do
{
@@ -212,15 +210,19 @@ static struct skin_element* skin_parse_viewport(const char** document)
}
cursor = bookmark;
- if(!root)
- to_write = &root;
- else
- to_write = &(last->next);
-
if(sublines)
{
- *to_write = skin_parse_sublines(&cursor);
- last = *to_write;
+ struct skin_element* out = skin_parse_sublines(&cursor);
+ if (!root)
+ {
+ root = out;
+ last = root;
+ }
+ else
+ {
+ last->next = skin_buffer_to_offset(out);
+ last = out;
+ }
if(!last)
return NULL;
}
@@ -237,15 +239,25 @@ static struct skin_element* skin_parse_viewport(const char** document)
if (check_viewport(cursor))
break;
#endif
- *to_write = skin_parse_line(&cursor);
- last = *to_write;
+
+ struct skin_element* out = skin_parse_line(&cursor);
+ if (!root)
+ {
+ root = out;
+ last = root;
+ }
+ else
+ {
+ last->next = skin_buffer_to_offset(out);
+ last = out;
+ }
if(!last)
return NULL;
}
/* Making sure last is at the end */
- while(last->next)
- last = last->next;
+ while(IS_VALID_OFFSET(last->next))
+ last = skin_buffer_from_offset(last->next);
if(*cursor == '\n')
{
@@ -269,7 +281,8 @@ static struct skin_element* skin_parse_viewport(const char** document)
*document = cursor;
- retval->children[0] = root;
+ children[0] = skin_buffer_to_offset(root);
+ retval->children = skin_buffer_to_offset(children);
return retval;
}
@@ -293,6 +306,7 @@ static struct skin_element* skin_parse_line_optional(const char** document,
struct skin_element* root = NULL;
struct skin_element* current = NULL;
struct skin_element* retval = NULL;
+ OFFSETTYPE(struct skin_element*)* children = NULL;
/* A wrapper for the line */
retval = skin_alloc_element();
@@ -315,8 +329,8 @@ static struct skin_element* skin_parse_line_optional(const char** document,
if(retval->children_count > 0)
{
- retval->children = skin_alloc_children(1);
- if (!retval->children)
+ children = skin_alloc_children(1);
+ if (!children)
return NULL;
}
@@ -344,10 +358,11 @@ static struct skin_element* skin_parse_line_optional(const char** document,
/* Allocating memory if necessary */
if(root)
{
- current->next = skin_alloc_element();
- if (!current->next)
+ struct skin_element *next = skin_alloc_element();
+ if (!next)
return NULL;
- current = current->next;
+ current->next = skin_buffer_to_offset(next);
+ current = next;
}
else
{
@@ -384,7 +399,10 @@ static struct skin_element* skin_parse_line_optional(const char** document,
*document = cursor;
if(root)
- retval->children[0] = root;
+ {
+ children[0] = skin_buffer_to_offset(root);
+ retval->children = skin_buffer_to_offset(children);
+ }
return retval;
}
@@ -397,6 +415,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
int conditional)
{
struct skin_element* retval;
+ OFFSETTYPE(struct skin_element*)* children;
const char* cursor = *document;
int sublines = 1;
int i;
@@ -405,7 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
if (!retval)
return NULL;
retval->type = LINE_ALTERNATOR;
- retval->next = NULL;
+ retval->next = skin_buffer_to_offset(NULL);
retval->line = skin_line;
/* First we count the sublines */
@@ -449,14 +468,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
/* ...and then we parse them */
retval->children_count = sublines;
- retval->children = skin_alloc_children(sublines);
- if (!retval->children)
+ children = skin_alloc_children(sublines);
+ if (!children)
return NULL;
cursor = *document;
for(i = 0; i < sublines; i++)
{
- retval->children[i] = skin_parse_line_optional(&cursor, conditional);
+ children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional));
+ if (children[i] < 0)
+ return NULL;
skip_whitespace(&cursor);
if(*cursor != MULTILINESYM && i != sublines - 1)
@@ -478,6 +499,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document,
}
#endif
*document = cursor;
+ retval->children = skin_buffer_to_offset(children);
return retval;
}
@@ -490,13 +512,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
char tag_name[3];
char* tag_args;
const struct tag_info *tag;
+ struct skin_tag_parameter* params = NULL;
int num_args = 1;
int i;
int star = 0; /* Flag for the all-or-none option */
int optional = 0;
- tag_recursion_level++;
/* Checking the tag name */
tag_name[0] = cursor[0];
@@ -597,8 +619,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
cursor = bookmark; /* Restoring the cursor */
element->params_count = num_args;
- element->params = skin_alloc_params(num_args, tag_recursion_level<=1);
- if (!element->params)
+ params = skin_alloc_params(num_args);
+ if (!params)
return 0;
/* Now we have to actually parse each argument */
@@ -686,14 +708,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
else
type_code = *tag_args;
/* Storing the type code */
- element->params[i].type_code = type_code;
+ params[i].type_code = type_code;
/* Checking a nullable argument for null. */
if(*cursor == DEFAULTSYM && !isdigit(cursor[1]))
{
if(islower(type_code))
{
- element->params[i].type = DEFAULT;
+ params[i].type = DEFAULT;
cursor++;
}
else
@@ -711,8 +733,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
return 0;
}
- element->params[i].type = INTEGER;
- element->params[i].data.number = scan_int(&cursor);
+ params[i].type = INTEGER;
+ params[i].data.number = scan_int(&cursor);
}
else if(tolower(type_code) == 'd')
{
@@ -738,23 +760,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
}
if (have_tenth == false)
val *= 10;
- element->params[i].type = DECIMAL;
- element->params[i].data.number = val;
+ params[i].type = DECIMAL;
+ params[i].data.number = val;
}
else if(tolower(type_code) == 'n' ||
tolower(type_code) == 's' || tolower(type_code) == 'f')
{
/* Scanning a string argument */
- element->params[i].type = STRING;
- element->params[i].data.text = scan_string(&cursor);
+ params[i].type = STRING;
+ params[i].data.text = skin_buffer_to_offset(scan_string(&cursor));
}
else if(tolower(type_code) == '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)
+ params[i].type = CODE;
+ params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
+ if(params[i].data.code < 0)
return 0;
}
else if (tolower(type_code) == 't')
@@ -763,9 +785,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
child->type = TAG;
if (!skin_parse_tag(child, &cursor))
return 0;
- child->next = NULL;
- element->params[i].type = CODE;
- element->params[i].data.code = child;
+ child->next = skin_buffer_to_offset(NULL);
+ params[i].type = CODE;
+ params[i].data.code = skin_buffer_to_offset(child);
}
@@ -796,6 +818,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
tag_args++;
}
}
+ element->params = skin_buffer_to_offset(params);
/* Checking for a premature end */
if(*tag_args != '\0' && !optional)
@@ -811,7 +834,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document)
}
#endif
*document = cursor;
- tag_recursion_level--;
return 1;
}
@@ -855,9 +877,10 @@ static int skin_parse_text(struct skin_element* element, const char** 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);
- if (!element->data)
+ element->next = skin_buffer_to_offset(NULL);
+ text = skin_alloc_string(length);
+ element->data = skin_buffer_to_offset(text);
+ if (element->data < 0)
return 0;
for(dest = 0; dest < length; dest++)
@@ -896,6 +919,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
const char *false_branch = NULL;
const char *conditional_end = NULL;
#endif
+ OFFSETTYPE(struct skin_element*)* children_array = NULL;
/* Some conditional tags allow for target feature checking,
* so to handle that call the callback as usual with type == TAG
@@ -994,23 +1018,23 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
{
const char* emptyline= "";
children = 1;
- element->children = skin_alloc_children(children);
- if (!element->children)
+ children_array = skin_alloc_children(children);
+ if (!children_array)
return 0;
element->children_count = children;
- element->children[0] = skin_parse_code_as_arg(&emptyline);
+ children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline));
}
else
{
- element->children = skin_alloc_children(children);
- if (!element->children)
+ children_array = skin_alloc_children(children);
+ if (!children_array)
return 0;
element->children_count = children;
for(i = 0; i < children; i++)
{
- element->children[i] = skin_parse_code_as_arg(&cursor);
- if (element->children[i] == NULL)
+ children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor));
+ if (children_array[i] < 0)
return 0;
skip_whitespace(&cursor);
#ifdef ROCKBOX
@@ -1035,6 +1059,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc
}
}
*document = cursor;
+ element->children = skin_buffer_to_offset(children_array);
return 1;
}
@@ -1056,7 +1081,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen
element->type = COMMENT;
element->line = skin_line;
#ifdef ROCKBOX
- element->data = NULL;
+ element->data = INVALID_OFFSET;
#else
element->data = text = skin_alloc_string(length);
if (!element->data)
@@ -1122,7 +1147,6 @@ static struct skin_element* skin_parse_code_as_arg(const char** document)
return skin_parse_line_optional(document, 1);
}
-
/* Memory management */
struct skin_element* skin_alloc_element()
{
@@ -1131,10 +1155,12 @@ struct skin_element* skin_alloc_element()
if (!retval)
return NULL;
retval->type = UNKNOWN;
- retval->next = NULL;
+ retval->next = skin_buffer_to_offset(NULL);
+ retval->params = skin_buffer_to_offset(NULL);
retval->tag = NULL;
retval->params_count = 0;
retval->children_count = 0;
+ retval->data = INVALID_OFFSET;
return retval;
@@ -1144,16 +1170,8 @@ struct skin_element* skin_alloc_element()
* enough for any tag. params should be used straight away by the callback
* so this is safe.
*/
-struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params)
+struct skin_tag_parameter* skin_alloc_params(int count)
{
-#ifdef ROCKBOX
- static struct skin_tag_parameter params[MAX_TAG_PARAMS];
- if (use_shared_params && count <= MAX_TAG_PARAMS)
- {
- memset(params, 0, sizeof(params));
- return params;
- }
-#endif
size_t size = sizeof(struct skin_tag_parameter) * count;
return (struct skin_tag_parameter*)skin_buffer_alloc(size);
@@ -1164,9 +1182,9 @@ char* skin_alloc_string(int length)
return (char*)skin_buffer_alloc(sizeof(char) * (length + 1));
}
-struct skin_element** skin_alloc_children(int count)
+OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count)
{
- return (struct skin_element**)
+ return (OFFSETTYPE(struct skin_element*)*)
skin_buffer_alloc(sizeof(struct skin_element*) * count);
}
diff --git a/lib/skin_parser/skin_parser.h b/lib/skin_parser/skin_parser.h
index 3e0634976c..120112d995 100644
--- a/lib/skin_parser/skin_parser.h
+++ b/lib/skin_parser/skin_parser.h
@@ -29,6 +29,25 @@ extern "C"
#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 *********************************************
*******************************************************************/
@@ -78,8 +97,8 @@ struct skin_tag_parameter
union
{
int number;
- char* text;
- struct skin_element* code;
+ OFFSETTYPE(char*) text;
+ OFFSETTYPE(struct skin_element*) code;
} data;
char type_code;
@@ -92,20 +111,20 @@ struct skin_tag_parameter
struct skin_element
{
/* Link to the next element */
- struct skin_element* next;
+ OFFSETTYPE(struct skin_element*) next;
/* Pointer to an array of children */
- struct skin_element** 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
*/
- void* data;
+ OFFSETTYPE(void*) data;
/* The tag or conditional name */
const struct tag_info *tag;
/* Pointer to an array of parameters */
- struct skin_tag_parameter* params;
+ OFFSETTYPE(struct skin_tag_parameter*) params;
/* Number of elements in the children array */
short children_count;
@@ -140,8 +159,8 @@ struct skin_element* skin_parse(const char* document);
#endif
/* Memory management functions */
struct skin_element* skin_alloc_element(void);
-struct skin_element** skin_alloc_children(int count);
-struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params);
+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);