diff options
Diffstat (limited to 'lib/skin_parser')
-rw-r--r-- | lib/skin_parser/skin_buffer.c | 73 | ||||
-rw-r--r-- | lib/skin_parser/skin_buffer.h | 15 | ||||
-rw-r--r-- | lib/skin_parser/skin_debug.c | 27 | ||||
-rw-r--r-- | lib/skin_parser/skin_parser.c | 178 | ||||
-rw-r--r-- | lib/skin_parser/skin_parser.h | 35 |
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 @@ | |||
47 | #ifdef ROCKBOX | 47 | #ifdef ROCKBOX |
48 | #include "config.h" | 48 | #include "config.h" |
49 | #include "skin_debug.h" | 49 | #include "skin_debug.h" |
50 | |||
51 | #ifdef APPLICATION | ||
52 | # define USE_HOST_MALLOC | ||
53 | #else | ||
54 | # define USE_ROCKBOX_ALLOC | ||
55 | #endif | ||
56 | |||
57 | #endif | ||
58 | |||
59 | #ifdef USE_ROCKBOX_ALLOC | ||
60 | static size_t buf_size; | 50 | static size_t buf_size; |
61 | static unsigned char *buffer_start = NULL; | 51 | static unsigned char *buffer_start = NULL; |
62 | static unsigned char *buffer_front = NULL; | 52 | static unsigned char *buffer_front = NULL; |
63 | #endif | ||
64 | |||
65 | #ifdef USE_HOST_MALLOC | ||
66 | |||
67 | struct malloc_object { | ||
68 | struct malloc_object *next; | ||
69 | char buf[0]; | ||
70 | }; | ||
71 | static struct malloc_object *malloced_head = NULL, *malloced_tail = NULL; | ||
72 | 53 | ||
73 | static void skin_free_malloced(void) | 54 | #ifndef __PCTOOL__ |
55 | long skin_buffer_to_offset(void *pointer) | ||
74 | { | 56 | { |
75 | struct malloc_object *obj = malloced_head; | 57 | return pointer == NULL ? -1 : (void*)pointer - (void*)buffer_start; |
76 | struct malloc_object *this; | ||
77 | while (obj) | ||
78 | { | ||
79 | this = obj; | ||
80 | obj = this->next; | ||
81 | free(this); | ||
82 | } | ||
83 | malloced_head = NULL; | ||
84 | malloced_tail = NULL; | ||
85 | } | 58 | } |
86 | 59 | ||
60 | void* skin_buffer_from_offset(long offset) | ||
61 | { | ||
62 | return offset < 0 ? NULL : buffer_start + offset; | ||
63 | } | ||
87 | #endif | 64 | #endif |
88 | 65 | ||
89 | void skin_buffer_init(char* buffer, size_t size) | 66 | void skin_buffer_init(char* buffer, size_t size) |
90 | { | 67 | { |
91 | #ifdef USE_ROCKBOX_ALLOC | ||
92 | buffer_start = buffer_front = buffer; | 68 | buffer_start = buffer_front = buffer; |
93 | buf_size = size; | 69 | buf_size = size; |
94 | #elif defined(USE_HOST_MALLOC) | ||
95 | (void)buffer; (void)size; | ||
96 | skin_free_malloced(); | ||
97 | #endif | ||
98 | } | 70 | } |
99 | 71 | ||
100 | /* Allocate size bytes from the buffer */ | 72 | /* Allocate size bytes from the buffer */ |
@@ -108,8 +80,6 @@ void* skin_buffer_alloc(size_t size) | |||
108 | { | 80 | { |
109 | void *retval = NULL; | 81 | void *retval = NULL; |
110 | #endif | 82 | #endif |
111 | |||
112 | #ifdef USE_ROCKBOX_ALLOC | ||
113 | /* 32-bit aligned */ | 83 | /* 32-bit aligned */ |
114 | size = (size + 3) & ~3; | 84 | size = (size + 3) & ~3; |
115 | if (size > skin_buffer_freespace()) | 85 | if (size > skin_buffer_freespace()) |
@@ -119,25 +89,9 @@ void* skin_buffer_alloc(size_t size) | |||
119 | } | 89 | } |
120 | retval = buffer_front; | 90 | retval = buffer_front; |
121 | buffer_front += size; | 91 | buffer_front += size; |
122 | #elif defined(USE_HOST_MALLOC) | ||
123 | size_t malloc_size = sizeof(struct malloc_object) + size; | ||
124 | struct malloc_object *obj = malloc(malloc_size); | ||
125 | retval = &obj->buf; | ||
126 | obj->next = NULL; | ||
127 | if (malloced_tail == NULL) | ||
128 | malloced_head = malloced_tail = obj; | ||
129 | else | ||
130 | malloced_tail->next = obj; | ||
131 | malloced_tail = obj; | ||
132 | |||
133 | #else | ||
134 | retval = malloc(size); | ||
135 | #endif | ||
136 | return retval; | 92 | return retval; |
137 | } | 93 | } |
138 | 94 | ||
139 | |||
140 | #ifdef USE_ROCKBOX_ALLOC | ||
141 | /* get the number of bytes currently being used */ | 95 | /* get the number of bytes currently being used */ |
142 | size_t skin_buffer_usage(void) | 96 | size_t skin_buffer_usage(void) |
143 | { | 97 | { |
@@ -147,16 +101,9 @@ size_t skin_buffer_freespace(void) | |||
147 | { | 101 | { |
148 | return buf_size - skin_buffer_usage(); | 102 | return buf_size - skin_buffer_usage(); |
149 | } | 103 | } |
150 | 104 | #else | |
151 | static unsigned char *saved_buffer_pos = NULL; | 105 | void* skin_buffer_alloc(size_t size) |
152 | void skin_buffer_save_position(void) | ||
153 | { | ||
154 | saved_buffer_pos = buffer_front; | ||
155 | } | ||
156 | |||
157 | void skin_buffer_restore_position(void) | ||
158 | { | 106 | { |
159 | if (saved_buffer_pos) | 107 | return malloc(size); |
160 | buffer_front = saved_buffer_pos; | ||
161 | } | 108 | } |
162 | #endif | 109 | #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 @@ | |||
28 | void skin_buffer_init(char* buffer, size_t size); | 28 | void skin_buffer_init(char* buffer, size_t size); |
29 | /* Allocate size bytes from the buffer */ | 29 | /* Allocate size bytes from the buffer */ |
30 | 30 | ||
31 | #ifndef __PCTOOL__ | ||
32 | #define INVALID_OFFSET (-1) | ||
33 | #define IS_VALID_OFFSET(o) ((o) >= 0) | ||
34 | long skin_buffer_to_offset(void *pointer); | ||
35 | void* skin_buffer_from_offset(long offset); | ||
36 | #else | ||
37 | #define INVALID_OFFSET (NULL) | ||
38 | #define IS_VALID_OFFSET(o) ((o) != NULL) | ||
39 | #define skin_buffer_to_offset(p) p | ||
40 | #define skin_buffer_from_offset(o) o | ||
41 | #endif | ||
42 | |||
31 | /* #define DEBUG_SKIN_ALLOCATIONS */ | 43 | /* #define DEBUG_SKIN_ALLOCATIONS */ |
32 | 44 | ||
33 | #ifdef DEBUG_SKIN_ALLOCATIONS | 45 | #ifdef DEBUG_SKIN_ALLOCATIONS |
@@ -44,7 +56,4 @@ void* skin_buffer_alloc(size_t size); | |||
44 | size_t skin_buffer_usage(void); | 56 | size_t skin_buffer_usage(void); |
45 | size_t skin_buffer_freespace(void); | 57 | size_t skin_buffer_freespace(void); |
46 | 58 | ||
47 | /* save and restore a buffer position incase a skin fails to load */ | ||
48 | void skin_buffer_save_position(void); | ||
49 | void skin_buffer_restore_position(void); | ||
50 | #endif | 59 | #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 @@ | |||
31 | int debug_indent_level = 0; | 31 | int debug_indent_level = 0; |
32 | extern int skin_line; | 32 | extern int skin_line; |
33 | extern char* skin_start; | 33 | extern char* skin_start; |
34 | extern char* skin_buffer; | ||
34 | 35 | ||
35 | /* Global error variables */ | 36 | /* Global error variables */ |
36 | int error_line; | 37 | int error_line; |
@@ -38,6 +39,14 @@ int error_col; | |||
38 | const char *error_line_start; | 39 | const char *error_line_start; |
39 | char* error_message; | 40 | char* error_message; |
40 | 41 | ||
42 | |||
43 | static inline struct skin_element* | ||
44 | get_child(OFFSETTYPE(struct skin_element**) children, int child) | ||
45 | { | ||
46 | struct skin_element **kids = SKINOFFSETTOPTR(skin_buffer, children); | ||
47 | return kids[child]; | ||
48 | } | ||
49 | |||
41 | /* Debugging functions */ | 50 | /* Debugging functions */ |
42 | void skin_error(enum skin_errorcode error, const char* cursor) | 51 | void skin_error(enum skin_errorcode error, const char* cursor) |
43 | { | 52 | { |
@@ -144,14 +153,14 @@ void skin_debug_tree(struct skin_element* root) | |||
144 | printf("{ Viewport \n"); | 153 | printf("{ Viewport \n"); |
145 | 154 | ||
146 | debug_indent_level++; | 155 | debug_indent_level++; |
147 | skin_debug_tree(current->children[0]); | 156 | skin_debug_tree(get_child(current->children, 0)); |
148 | debug_indent_level--; | 157 | debug_indent_level--; |
149 | 158 | ||
150 | printf("}"); | 159 | printf("}"); |
151 | break; | 160 | break; |
152 | 161 | ||
153 | case TEXT: | 162 | case TEXT: |
154 | text = current->data; | 163 | text = SKINOFFSETTOPTR(skin_buffer, current->data); |
155 | printf("* Plain text on line %d: \"%s\"\n", current->line, text); | 164 | printf("* Plain text on line %d: \"%s\"\n", current->line, text); |
156 | break; | 165 | break; |
157 | 166 | ||
@@ -166,7 +175,7 @@ void skin_debug_tree(struct skin_element* root) | |||
166 | current->tag->name, | 175 | current->tag->name, |
167 | current->line, current->params_count); | 176 | current->line, current->params_count); |
168 | debug_indent_level++; | 177 | debug_indent_level++; |
169 | skin_debug_params(current->params_count, current->params); | 178 | skin_debug_params(current->params_count, SKINOFFSETTOPTR(skin_buffer, current->params)); |
170 | debug_indent_level--; | 179 | debug_indent_level--; |
171 | skin_debug_indent(); | 180 | skin_debug_indent(); |
172 | printf(")\n"); | 181 | printf(")\n"); |
@@ -185,7 +194,7 @@ void skin_debug_tree(struct skin_element* root) | |||
185 | debug_indent_level++; | 194 | debug_indent_level++; |
186 | for(i = 0; i < current->children_count; i++) | 195 | for(i = 0; i < current->children_count; i++) |
187 | { | 196 | { |
188 | skin_debug_tree(current->children[i]); | 197 | skin_debug_tree(get_child(current->children, i)); |
189 | } | 198 | } |
190 | debug_indent_level--; | 199 | debug_indent_level--; |
191 | 200 | ||
@@ -203,7 +212,7 @@ void skin_debug_tree(struct skin_element* root) | |||
203 | skin_debug_indent(); | 212 | skin_debug_indent(); |
204 | printf("[ Enumeration %d\n", i); | 213 | printf("[ Enumeration %d\n", i); |
205 | debug_indent_level++; | 214 | debug_indent_level++; |
206 | skin_debug_tree(current->children[i]); | 215 | skin_debug_tree(get_child(current->children, i)); |
207 | debug_indent_level--; | 216 | debug_indent_level--; |
208 | skin_debug_indent(); | 217 | skin_debug_indent(); |
209 | printf("]\n"); | 218 | printf("]\n"); |
@@ -221,7 +230,7 @@ void skin_debug_tree(struct skin_element* root) | |||
221 | 230 | ||
222 | debug_indent_level++; | 231 | debug_indent_level++; |
223 | if (current->children) | 232 | if (current->children) |
224 | skin_debug_tree(current->children[0]); | 233 | skin_debug_tree(get_child(current->children, 0)); |
225 | debug_indent_level--; | 234 | debug_indent_level--; |
226 | 235 | ||
227 | skin_debug_indent(); | 236 | skin_debug_indent(); |
@@ -229,7 +238,7 @@ void skin_debug_tree(struct skin_element* root) | |||
229 | break; | 238 | break; |
230 | } | 239 | } |
231 | 240 | ||
232 | current = current->next; | 241 | current = SKINOFFSETTOPTR(skin_buffer, current->next); |
233 | } | 242 | } |
234 | 243 | ||
235 | } | 244 | } |
@@ -248,7 +257,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[]) | |||
248 | break; | 257 | break; |
249 | 258 | ||
250 | case STRING: | 259 | case STRING: |
251 | printf("string: \"%s\"", params[i].data.text); | 260 | printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text)); |
252 | break; | 261 | break; |
253 | 262 | ||
254 | case INTEGER: | 263 | case INTEGER: |
@@ -263,7 +272,7 @@ void skin_debug_params(int count, struct skin_tag_parameter params[]) | |||
263 | case CODE: | 272 | case CODE: |
264 | printf("Skin Code: \n"); | 273 | printf("Skin Code: \n"); |
265 | debug_indent_level++; | 274 | debug_indent_level++; |
266 | skin_debug_tree(params[i].data.code); | 275 | skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code)); |
267 | debug_indent_level--; | 276 | debug_indent_level--; |
268 | skin_debug_indent(); | 277 | skin_debug_indent(); |
269 | break; | 278 | 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; | |||
37 | char* skin_start = 0; | 37 | char* skin_start = 0; |
38 | int viewport_line = 0; | 38 | int viewport_line = 0; |
39 | 39 | ||
40 | static int tag_recursion_level = 0; | ||
41 | |||
42 | #ifdef ROCKBOX | 40 | #ifdef ROCKBOX |
43 | static skin_callback callback = NULL; | 41 | static skin_callback callback = NULL; |
44 | static void* callback_data; | 42 | static void* callback_data; |
@@ -81,8 +79,6 @@ struct skin_element* skin_parse(const char* document) | |||
81 | struct skin_element* root = NULL; | 79 | struct skin_element* root = NULL; |
82 | struct skin_element* last = NULL; | 80 | struct skin_element* last = NULL; |
83 | 81 | ||
84 | struct skin_element** to_write = 0; | ||
85 | |||
86 | const char* cursor = document; /*Keeps track of location in the document*/ | 82 | const char* cursor = document; /*Keeps track of location in the document*/ |
87 | 83 | ||
88 | skin_line = 1; | 84 | skin_line = 1; |
@@ -93,14 +89,18 @@ struct skin_element* skin_parse(const char* document) | |||
93 | 89 | ||
94 | while(*cursor != '\0') | 90 | while(*cursor != '\0') |
95 | { | 91 | { |
92 | struct skin_element* tree = skin_parse_viewport(&cursor); | ||
96 | if(!root) | 93 | if(!root) |
97 | to_write = &root; | 94 | { |
95 | root = tree; | ||
96 | last = root; | ||
97 | } | ||
98 | else | 98 | else |
99 | to_write = &(last->next); | 99 | { |
100 | 100 | last->next = skin_buffer_to_offset(tree); | |
101 | last = tree; | ||
102 | } | ||
101 | 103 | ||
102 | *to_write = skin_parse_viewport(&cursor); | ||
103 | last = *to_write; | ||
104 | if(!last) | 104 | if(!last) |
105 | { | 105 | { |
106 | skin_free_tree(root); /* Clearing any memory already used */ | 106 | skin_free_tree(root); /* Clearing any memory already used */ |
@@ -108,8 +108,8 @@ struct skin_element* skin_parse(const char* document) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /* Making sure last is at the end */ | 110 | /* Making sure last is at the end */ |
111 | while(last->next) | 111 | while(IS_VALID_OFFSET(last->next)) |
112 | last = last->next; | 112 | last = skin_buffer_from_offset(last->next); |
113 | 113 | ||
114 | } | 114 | } |
115 | return root; | 115 | return root; |
@@ -121,8 +121,6 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
121 | struct skin_element* root = NULL; | 121 | struct skin_element* root = NULL; |
122 | struct skin_element* last = NULL; | 122 | struct skin_element* last = NULL; |
123 | struct skin_element* retval = NULL; | 123 | struct skin_element* retval = NULL; |
124 | |||
125 | tag_recursion_level = 0; | ||
126 | 124 | ||
127 | retval = skin_alloc_element(); | 125 | retval = skin_alloc_element(); |
128 | if (!retval) | 126 | if (!retval) |
@@ -132,7 +130,7 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
132 | retval->line = skin_line; | 130 | retval->line = skin_line; |
133 | viewport_line = skin_line; | 131 | viewport_line = skin_line; |
134 | 132 | ||
135 | struct skin_element** to_write = 0; | 133 | OFFSETTYPE(struct skin_element*)* children; |
136 | 134 | ||
137 | const char* cursor = *document; /* Keeps track of location in the document */ | 135 | const char* cursor = *document; /* Keeps track of location in the document */ |
138 | const char* bookmark; /* Used when we need to look ahead */ | 136 | const char* bookmark; /* Used when we need to look ahead */ |
@@ -165,8 +163,8 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
165 | return retval; | 163 | return retval; |
166 | } | 164 | } |
167 | retval->children_count = 1; | 165 | retval->children_count = 1; |
168 | retval->children = skin_alloc_children(1); | 166 | children = skin_alloc_children(1); |
169 | if (!retval->children) | 167 | if (!children) |
170 | return NULL; | 168 | return NULL; |
171 | do | 169 | do |
172 | { | 170 | { |
@@ -212,15 +210,19 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
212 | } | 210 | } |
213 | cursor = bookmark; | 211 | cursor = bookmark; |
214 | 212 | ||
215 | if(!root) | ||
216 | to_write = &root; | ||
217 | else | ||
218 | to_write = &(last->next); | ||
219 | |||
220 | if(sublines) | 213 | if(sublines) |
221 | { | 214 | { |
222 | *to_write = skin_parse_sublines(&cursor); | 215 | struct skin_element* out = skin_parse_sublines(&cursor); |
223 | last = *to_write; | 216 | if (!root) |
217 | { | ||
218 | root = out; | ||
219 | last = root; | ||
220 | } | ||
221 | else | ||
222 | { | ||
223 | last->next = skin_buffer_to_offset(out); | ||
224 | last = out; | ||
225 | } | ||
224 | if(!last) | 226 | if(!last) |
225 | return NULL; | 227 | return NULL; |
226 | } | 228 | } |
@@ -237,15 +239,25 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
237 | if (check_viewport(cursor)) | 239 | if (check_viewport(cursor)) |
238 | break; | 240 | break; |
239 | #endif | 241 | #endif |
240 | *to_write = skin_parse_line(&cursor); | 242 | |
241 | last = *to_write; | 243 | struct skin_element* out = skin_parse_line(&cursor); |
244 | if (!root) | ||
245 | { | ||
246 | root = out; | ||
247 | last = root; | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | last->next = skin_buffer_to_offset(out); | ||
252 | last = out; | ||
253 | } | ||
242 | if(!last) | 254 | if(!last) |
243 | return NULL; | 255 | return NULL; |
244 | 256 | ||
245 | } | 257 | } |
246 | /* Making sure last is at the end */ | 258 | /* Making sure last is at the end */ |
247 | while(last->next) | 259 | while(IS_VALID_OFFSET(last->next)) |
248 | last = last->next; | 260 | last = skin_buffer_from_offset(last->next); |
249 | 261 | ||
250 | if(*cursor == '\n') | 262 | if(*cursor == '\n') |
251 | { | 263 | { |
@@ -269,7 +281,8 @@ static struct skin_element* skin_parse_viewport(const char** document) | |||
269 | 281 | ||
270 | *document = cursor; | 282 | *document = cursor; |
271 | 283 | ||
272 | retval->children[0] = root; | 284 | children[0] = skin_buffer_to_offset(root); |
285 | retval->children = skin_buffer_to_offset(children); | ||
273 | return retval; | 286 | return retval; |
274 | } | 287 | } |
275 | 288 | ||
@@ -293,6 +306,7 @@ static struct skin_element* skin_parse_line_optional(const char** document, | |||
293 | struct skin_element* root = NULL; | 306 | struct skin_element* root = NULL; |
294 | struct skin_element* current = NULL; | 307 | struct skin_element* current = NULL; |
295 | struct skin_element* retval = NULL; | 308 | struct skin_element* retval = NULL; |
309 | OFFSETTYPE(struct skin_element*)* children = NULL; | ||
296 | 310 | ||
297 | /* A wrapper for the line */ | 311 | /* A wrapper for the line */ |
298 | retval = skin_alloc_element(); | 312 | retval = skin_alloc_element(); |
@@ -315,8 +329,8 @@ static struct skin_element* skin_parse_line_optional(const char** document, | |||
315 | 329 | ||
316 | if(retval->children_count > 0) | 330 | if(retval->children_count > 0) |
317 | { | 331 | { |
318 | retval->children = skin_alloc_children(1); | 332 | children = skin_alloc_children(1); |
319 | if (!retval->children) | 333 | if (!children) |
320 | return NULL; | 334 | return NULL; |
321 | } | 335 | } |
322 | 336 | ||
@@ -344,10 +358,11 @@ static struct skin_element* skin_parse_line_optional(const char** document, | |||
344 | /* Allocating memory if necessary */ | 358 | /* Allocating memory if necessary */ |
345 | if(root) | 359 | if(root) |
346 | { | 360 | { |
347 | current->next = skin_alloc_element(); | 361 | struct skin_element *next = skin_alloc_element(); |
348 | if (!current->next) | 362 | if (!next) |
349 | return NULL; | 363 | return NULL; |
350 | current = current->next; | 364 | current->next = skin_buffer_to_offset(next); |
365 | current = next; | ||
351 | } | 366 | } |
352 | else | 367 | else |
353 | { | 368 | { |
@@ -384,7 +399,10 @@ static struct skin_element* skin_parse_line_optional(const char** document, | |||
384 | *document = cursor; | 399 | *document = cursor; |
385 | 400 | ||
386 | if(root) | 401 | if(root) |
387 | retval->children[0] = root; | 402 | { |
403 | children[0] = skin_buffer_to_offset(root); | ||
404 | retval->children = skin_buffer_to_offset(children); | ||
405 | } | ||
388 | return retval; | 406 | return retval; |
389 | } | 407 | } |
390 | 408 | ||
@@ -397,6 +415,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, | |||
397 | int conditional) | 415 | int conditional) |
398 | { | 416 | { |
399 | struct skin_element* retval; | 417 | struct skin_element* retval; |
418 | OFFSETTYPE(struct skin_element*)* children; | ||
400 | const char* cursor = *document; | 419 | const char* cursor = *document; |
401 | int sublines = 1; | 420 | int sublines = 1; |
402 | int i; | 421 | int i; |
@@ -405,7 +424,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, | |||
405 | if (!retval) | 424 | if (!retval) |
406 | return NULL; | 425 | return NULL; |
407 | retval->type = LINE_ALTERNATOR; | 426 | retval->type = LINE_ALTERNATOR; |
408 | retval->next = NULL; | 427 | retval->next = skin_buffer_to_offset(NULL); |
409 | retval->line = skin_line; | 428 | retval->line = skin_line; |
410 | 429 | ||
411 | /* First we count the sublines */ | 430 | /* First we count the sublines */ |
@@ -449,14 +468,16 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, | |||
449 | 468 | ||
450 | /* ...and then we parse them */ | 469 | /* ...and then we parse them */ |
451 | retval->children_count = sublines; | 470 | retval->children_count = sublines; |
452 | retval->children = skin_alloc_children(sublines); | 471 | children = skin_alloc_children(sublines); |
453 | if (!retval->children) | 472 | if (!children) |
454 | return NULL; | 473 | return NULL; |
455 | 474 | ||
456 | cursor = *document; | 475 | cursor = *document; |
457 | for(i = 0; i < sublines; i++) | 476 | for(i = 0; i < sublines; i++) |
458 | { | 477 | { |
459 | retval->children[i] = skin_parse_line_optional(&cursor, conditional); | 478 | children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional)); |
479 | if (children[i] < 0) | ||
480 | return NULL; | ||
460 | skip_whitespace(&cursor); | 481 | skip_whitespace(&cursor); |
461 | 482 | ||
462 | if(*cursor != MULTILINESYM && i != sublines - 1) | 483 | if(*cursor != MULTILINESYM && i != sublines - 1) |
@@ -478,6 +499,7 @@ static struct skin_element* skin_parse_sublines_optional(const char** document, | |||
478 | } | 499 | } |
479 | #endif | 500 | #endif |
480 | *document = cursor; | 501 | *document = cursor; |
502 | retval->children = skin_buffer_to_offset(children); | ||
481 | 503 | ||
482 | return retval; | 504 | return retval; |
483 | } | 505 | } |
@@ -490,13 +512,13 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
490 | char tag_name[3]; | 512 | char tag_name[3]; |
491 | char* tag_args; | 513 | char* tag_args; |
492 | const struct tag_info *tag; | 514 | const struct tag_info *tag; |
515 | struct skin_tag_parameter* params = NULL; | ||
493 | 516 | ||
494 | int num_args = 1; | 517 | int num_args = 1; |
495 | int i; | 518 | int i; |
496 | int star = 0; /* Flag for the all-or-none option */ | 519 | int star = 0; /* Flag for the all-or-none option */ |
497 | 520 | ||
498 | int optional = 0; | 521 | int optional = 0; |
499 | tag_recursion_level++; | ||
500 | 522 | ||
501 | /* Checking the tag name */ | 523 | /* Checking the tag name */ |
502 | tag_name[0] = cursor[0]; | 524 | tag_name[0] = cursor[0]; |
@@ -597,8 +619,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
597 | 619 | ||
598 | cursor = bookmark; /* Restoring the cursor */ | 620 | cursor = bookmark; /* Restoring the cursor */ |
599 | element->params_count = num_args; | 621 | element->params_count = num_args; |
600 | element->params = skin_alloc_params(num_args, tag_recursion_level<=1); | 622 | params = skin_alloc_params(num_args); |
601 | if (!element->params) | 623 | if (!params) |
602 | return 0; | 624 | return 0; |
603 | 625 | ||
604 | /* Now we have to actually parse each argument */ | 626 | /* Now we have to actually parse each argument */ |
@@ -686,14 +708,14 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
686 | else | 708 | else |
687 | type_code = *tag_args; | 709 | type_code = *tag_args; |
688 | /* Storing the type code */ | 710 | /* Storing the type code */ |
689 | element->params[i].type_code = type_code; | 711 | params[i].type_code = type_code; |
690 | 712 | ||
691 | /* Checking a nullable argument for null. */ | 713 | /* Checking a nullable argument for null. */ |
692 | if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) | 714 | if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) |
693 | { | 715 | { |
694 | if(islower(type_code)) | 716 | if(islower(type_code)) |
695 | { | 717 | { |
696 | element->params[i].type = DEFAULT; | 718 | params[i].type = DEFAULT; |
697 | cursor++; | 719 | cursor++; |
698 | } | 720 | } |
699 | else | 721 | else |
@@ -711,8 +733,8 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
711 | return 0; | 733 | return 0; |
712 | } | 734 | } |
713 | 735 | ||
714 | element->params[i].type = INTEGER; | 736 | params[i].type = INTEGER; |
715 | element->params[i].data.number = scan_int(&cursor); | 737 | params[i].data.number = scan_int(&cursor); |
716 | } | 738 | } |
717 | else if(tolower(type_code) == 'd') | 739 | else if(tolower(type_code) == 'd') |
718 | { | 740 | { |
@@ -738,23 +760,23 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
738 | } | 760 | } |
739 | if (have_tenth == false) | 761 | if (have_tenth == false) |
740 | val *= 10; | 762 | val *= 10; |
741 | element->params[i].type = DECIMAL; | 763 | params[i].type = DECIMAL; |
742 | element->params[i].data.number = val; | 764 | params[i].data.number = val; |
743 | } | 765 | } |
744 | else if(tolower(type_code) == 'n' || | 766 | else if(tolower(type_code) == 'n' || |
745 | tolower(type_code) == 's' || tolower(type_code) == 'f') | 767 | tolower(type_code) == 's' || tolower(type_code) == 'f') |
746 | { | 768 | { |
747 | /* Scanning a string argument */ | 769 | /* Scanning a string argument */ |
748 | element->params[i].type = STRING; | 770 | params[i].type = STRING; |
749 | element->params[i].data.text = scan_string(&cursor); | 771 | params[i].data.text = skin_buffer_to_offset(scan_string(&cursor)); |
750 | 772 | ||
751 | } | 773 | } |
752 | else if(tolower(type_code) == 'c') | 774 | else if(tolower(type_code) == 'c') |
753 | { | 775 | { |
754 | /* Recursively parsing a code argument */ | 776 | /* Recursively parsing a code argument */ |
755 | element->params[i].type = CODE; | 777 | params[i].type = CODE; |
756 | element->params[i].data.code = skin_parse_code_as_arg(&cursor); | 778 | params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); |
757 | if(!element->params[i].data.code) | 779 | if(params[i].data.code < 0) |
758 | return 0; | 780 | return 0; |
759 | } | 781 | } |
760 | else if (tolower(type_code) == 't') | 782 | else if (tolower(type_code) == 't') |
@@ -763,9 +785,9 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
763 | child->type = TAG; | 785 | child->type = TAG; |
764 | if (!skin_parse_tag(child, &cursor)) | 786 | if (!skin_parse_tag(child, &cursor)) |
765 | return 0; | 787 | return 0; |
766 | child->next = NULL; | 788 | child->next = skin_buffer_to_offset(NULL); |
767 | element->params[i].type = CODE; | 789 | params[i].type = CODE; |
768 | element->params[i].data.code = child; | 790 | params[i].data.code = skin_buffer_to_offset(child); |
769 | } | 791 | } |
770 | 792 | ||
771 | 793 | ||
@@ -796,6 +818,7 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
796 | tag_args++; | 818 | tag_args++; |
797 | } | 819 | } |
798 | } | 820 | } |
821 | element->params = skin_buffer_to_offset(params); | ||
799 | 822 | ||
800 | /* Checking for a premature end */ | 823 | /* Checking for a premature end */ |
801 | if(*tag_args != '\0' && !optional) | 824 | if(*tag_args != '\0' && !optional) |
@@ -811,7 +834,6 @@ static int skin_parse_tag(struct skin_element* element, const char** document) | |||
811 | } | 834 | } |
812 | #endif | 835 | #endif |
813 | *document = cursor; | 836 | *document = cursor; |
814 | tag_recursion_level--; | ||
815 | 837 | ||
816 | return 1; | 838 | return 1; |
817 | } | 839 | } |
@@ -855,9 +877,10 @@ static int skin_parse_text(struct skin_element* element, const char** document, | |||
855 | /* Copying the text into the element struct */ | 877 | /* Copying the text into the element struct */ |
856 | element->type = TEXT; | 878 | element->type = TEXT; |
857 | element->line = skin_line; | 879 | element->line = skin_line; |
858 | element->next = NULL; | 880 | element->next = skin_buffer_to_offset(NULL); |
859 | element->data = text = skin_alloc_string(length); | 881 | text = skin_alloc_string(length); |
860 | if (!element->data) | 882 | element->data = skin_buffer_to_offset(text); |
883 | if (element->data < 0) | ||
861 | return 0; | 884 | return 0; |
862 | 885 | ||
863 | for(dest = 0; dest < length; dest++) | 886 | for(dest = 0; dest < length; dest++) |
@@ -896,6 +919,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc | |||
896 | const char *false_branch = NULL; | 919 | const char *false_branch = NULL; |
897 | const char *conditional_end = NULL; | 920 | const char *conditional_end = NULL; |
898 | #endif | 921 | #endif |
922 | OFFSETTYPE(struct skin_element*)* children_array = NULL; | ||
899 | 923 | ||
900 | /* Some conditional tags allow for target feature checking, | 924 | /* Some conditional tags allow for target feature checking, |
901 | * so to handle that call the callback as usual with type == TAG | 925 | * 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 | |||
994 | { | 1018 | { |
995 | const char* emptyline= ""; | 1019 | const char* emptyline= ""; |
996 | children = 1; | 1020 | children = 1; |
997 | element->children = skin_alloc_children(children); | 1021 | children_array = skin_alloc_children(children); |
998 | if (!element->children) | 1022 | if (!children_array) |
999 | return 0; | 1023 | return 0; |
1000 | element->children_count = children; | 1024 | element->children_count = children; |
1001 | element->children[0] = skin_parse_code_as_arg(&emptyline); | 1025 | children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline)); |
1002 | } | 1026 | } |
1003 | else | 1027 | else |
1004 | { | 1028 | { |
1005 | element->children = skin_alloc_children(children); | 1029 | children_array = skin_alloc_children(children); |
1006 | if (!element->children) | 1030 | if (!children_array) |
1007 | return 0; | 1031 | return 0; |
1008 | element->children_count = children; | 1032 | element->children_count = children; |
1009 | 1033 | ||
1010 | for(i = 0; i < children; i++) | 1034 | for(i = 0; i < children; i++) |
1011 | { | 1035 | { |
1012 | element->children[i] = skin_parse_code_as_arg(&cursor); | 1036 | children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); |
1013 | if (element->children[i] == NULL) | 1037 | if (children_array[i] < 0) |
1014 | return 0; | 1038 | return 0; |
1015 | skip_whitespace(&cursor); | 1039 | skip_whitespace(&cursor); |
1016 | #ifdef ROCKBOX | 1040 | #ifdef ROCKBOX |
@@ -1035,6 +1059,7 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc | |||
1035 | } | 1059 | } |
1036 | } | 1060 | } |
1037 | *document = cursor; | 1061 | *document = cursor; |
1062 | element->children = skin_buffer_to_offset(children_array); | ||
1038 | 1063 | ||
1039 | return 1; | 1064 | return 1; |
1040 | } | 1065 | } |
@@ -1056,7 +1081,7 @@ static int skin_parse_comment(struct skin_element* element, const char** documen | |||
1056 | element->type = COMMENT; | 1081 | element->type = COMMENT; |
1057 | element->line = skin_line; | 1082 | element->line = skin_line; |
1058 | #ifdef ROCKBOX | 1083 | #ifdef ROCKBOX |
1059 | element->data = NULL; | 1084 | element->data = INVALID_OFFSET; |
1060 | #else | 1085 | #else |
1061 | element->data = text = skin_alloc_string(length); | 1086 | element->data = text = skin_alloc_string(length); |
1062 | if (!element->data) | 1087 | if (!element->data) |
@@ -1122,7 +1147,6 @@ static struct skin_element* skin_parse_code_as_arg(const char** document) | |||
1122 | return skin_parse_line_optional(document, 1); | 1147 | return skin_parse_line_optional(document, 1); |
1123 | } | 1148 | } |
1124 | 1149 | ||
1125 | |||
1126 | /* Memory management */ | 1150 | /* Memory management */ |
1127 | struct skin_element* skin_alloc_element() | 1151 | struct skin_element* skin_alloc_element() |
1128 | { | 1152 | { |
@@ -1131,10 +1155,12 @@ struct skin_element* skin_alloc_element() | |||
1131 | if (!retval) | 1155 | if (!retval) |
1132 | return NULL; | 1156 | return NULL; |
1133 | retval->type = UNKNOWN; | 1157 | retval->type = UNKNOWN; |
1134 | retval->next = NULL; | 1158 | retval->next = skin_buffer_to_offset(NULL); |
1159 | retval->params = skin_buffer_to_offset(NULL); | ||
1135 | retval->tag = NULL; | 1160 | retval->tag = NULL; |
1136 | retval->params_count = 0; | 1161 | retval->params_count = 0; |
1137 | retval->children_count = 0; | 1162 | retval->children_count = 0; |
1163 | retval->data = INVALID_OFFSET; | ||
1138 | 1164 | ||
1139 | return retval; | 1165 | return retval; |
1140 | 1166 | ||
@@ -1144,16 +1170,8 @@ struct skin_element* skin_alloc_element() | |||
1144 | * enough for any tag. params should be used straight away by the callback | 1170 | * enough for any tag. params should be used straight away by the callback |
1145 | * so this is safe. | 1171 | * so this is safe. |
1146 | */ | 1172 | */ |
1147 | struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params) | 1173 | struct skin_tag_parameter* skin_alloc_params(int count) |
1148 | { | 1174 | { |
1149 | #ifdef ROCKBOX | ||
1150 | static struct skin_tag_parameter params[MAX_TAG_PARAMS]; | ||
1151 | if (use_shared_params && count <= MAX_TAG_PARAMS) | ||
1152 | { | ||
1153 | memset(params, 0, sizeof(params)); | ||
1154 | return params; | ||
1155 | } | ||
1156 | #endif | ||
1157 | size_t size = sizeof(struct skin_tag_parameter) * count; | 1175 | size_t size = sizeof(struct skin_tag_parameter) * count; |
1158 | return (struct skin_tag_parameter*)skin_buffer_alloc(size); | 1176 | return (struct skin_tag_parameter*)skin_buffer_alloc(size); |
1159 | 1177 | ||
@@ -1164,9 +1182,9 @@ char* skin_alloc_string(int length) | |||
1164 | return (char*)skin_buffer_alloc(sizeof(char) * (length + 1)); | 1182 | return (char*)skin_buffer_alloc(sizeof(char) * (length + 1)); |
1165 | } | 1183 | } |
1166 | 1184 | ||
1167 | struct skin_element** skin_alloc_children(int count) | 1185 | OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count) |
1168 | { | 1186 | { |
1169 | return (struct skin_element**) | 1187 | return (OFFSETTYPE(struct skin_element*)*) |
1170 | skin_buffer_alloc(sizeof(struct skin_element*) * count); | 1188 | skin_buffer_alloc(sizeof(struct skin_element*) * count); |
1171 | } | 1189 | } |
1172 | 1190 | ||
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" | |||
29 | #include <stdlib.h> | 29 | #include <stdlib.h> |
30 | #include <stdbool.h> | 30 | #include <stdbool.h> |
31 | 31 | ||
32 | #if defined(ROCKBOX) && !defined(__PCTOOL__) | ||
33 | /* Use this type and macro to convert a pointer from the | ||
34 | * skin buffer to a useable pointer */ | ||
35 | typedef long skinoffset_t; | ||
36 | #define SKINOFFSETTOPTR(base, offset) ((offset) < 0 ? NULL : ((void*)&base[offset])) | ||
37 | #define PTRTOSKINOFFSET(base, pointer) ((pointer) ? ((void*)pointer-(void*)base) : -1) | ||
38 | /* Use this macro when declaring a variable to self-document the code. | ||
39 | * type is the actual type being pointed to (i.e OFFSETTYPE(char*) foo ) | ||
40 | * | ||
41 | * WARNING: Don't use the PTRTOSKINOFFSET() around a function call as it wont | ||
42 | * do what you expect. | ||
43 | */ | ||
44 | #define OFFSETTYPE(type) skinoffset_t | ||
45 | #else | ||
46 | #define SKINOFFSETTOPTR(base, offset) offset | ||
47 | #define PTRTOSKINOFFSET(base, pointer) pointer | ||
48 | #define OFFSETTYPE(type) type | ||
49 | #endif | ||
50 | |||
32 | /******************************************************************** | 51 | /******************************************************************** |
33 | ****** Data Structures ********************************************* | 52 | ****** Data Structures ********************************************* |
34 | *******************************************************************/ | 53 | *******************************************************************/ |
@@ -78,8 +97,8 @@ struct skin_tag_parameter | |||
78 | union | 97 | union |
79 | { | 98 | { |
80 | int number; | 99 | int number; |
81 | char* text; | 100 | OFFSETTYPE(char*) text; |
82 | struct skin_element* code; | 101 | OFFSETTYPE(struct skin_element*) code; |
83 | } data; | 102 | } data; |
84 | 103 | ||
85 | char type_code; | 104 | char type_code; |
@@ -92,20 +111,20 @@ struct skin_tag_parameter | |||
92 | struct skin_element | 111 | struct skin_element |
93 | { | 112 | { |
94 | /* Link to the next element */ | 113 | /* Link to the next element */ |
95 | struct skin_element* next; | 114 | OFFSETTYPE(struct skin_element*) next; |
96 | /* Pointer to an array of children */ | 115 | /* Pointer to an array of children */ |
97 | struct skin_element** children; | 116 | OFFSETTYPE(struct skin_element**) children; |
98 | /* Placeholder for element data | 117 | /* Placeholder for element data |
99 | * TEXT and COMMENT uses it for the text string | 118 | * TEXT and COMMENT uses it for the text string |
100 | * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage | 119 | * TAG, VIEWPORT, LINE, etc may use it for post parse extra storage |
101 | */ | 120 | */ |
102 | void* data; | 121 | OFFSETTYPE(void*) data; |
103 | 122 | ||
104 | /* The tag or conditional name */ | 123 | /* The tag or conditional name */ |
105 | const struct tag_info *tag; | 124 | const struct tag_info *tag; |
106 | 125 | ||
107 | /* Pointer to an array of parameters */ | 126 | /* Pointer to an array of parameters */ |
108 | struct skin_tag_parameter* params; | 127 | OFFSETTYPE(struct skin_tag_parameter*) params; |
109 | 128 | ||
110 | /* Number of elements in the children array */ | 129 | /* Number of elements in the children array */ |
111 | short children_count; | 130 | short children_count; |
@@ -140,8 +159,8 @@ struct skin_element* skin_parse(const char* document); | |||
140 | #endif | 159 | #endif |
141 | /* Memory management functions */ | 160 | /* Memory management functions */ |
142 | struct skin_element* skin_alloc_element(void); | 161 | struct skin_element* skin_alloc_element(void); |
143 | struct skin_element** skin_alloc_children(int count); | 162 | OFFSETTYPE(struct skin_element*)* skin_alloc_children(int count); |
144 | struct skin_tag_parameter* skin_alloc_params(int count, bool use_shared_params); | 163 | struct skin_tag_parameter* skin_alloc_params(int count); |
145 | char* skin_alloc_string(int length); | 164 | char* skin_alloc_string(int length); |
146 | 165 | ||
147 | void skin_free_tree(struct skin_element* root); | 166 | void skin_free_tree(struct skin_element* root); |