1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
26 #include "skin_parser.h"
27 #include "skin_debug.h"
28 #include "tag_table.h"
30 /* Global variables for debug output */
31 int debug_indent_level
= 0;
33 extern char* skin_start
;
34 extern char* skin_buffer
;
36 /* Global error variables */
39 const char *error_line_start
;
43 static inline struct skin_element
*
44 get_child(OFFSETTYPE(struct skin_element
**) children
, int child
)
46 struct skin_element
**kids
= SKINOFFSETTOPTR(skin_buffer
, children
);
50 /* Debugging functions */
51 void skin_error(enum skin_errorcode error
, const char* cursor
)
56 while(cursor
> skin_start
&& *cursor
!= '\n')
61 error_line_start
= cursor
+1;
63 error_line
= skin_line
;
67 case MEMORY_LIMIT_EXCEEDED
:
68 error_line_start
= NULL
;
69 printf("Error: Memory limit exceeded at Line %d\n", skin_line
);
70 error_message
= "Memory limit exceeded";
72 case NEWLINE_EXPECTED
:
73 error_message
= "Newline expected";
76 error_message
= "Illegal tag";
78 case ARGLIST_EXPECTED
:
79 error_message
= "Argument list expected";
82 error_message
= "Too many arguments given";
84 case DEFAULT_NOT_ALLOWED
:
85 error_message
= "Argument can not be set to default";
87 case UNEXPECTED_NEWLINE
:
88 error_message
= "Unexpected newline";
90 case INSUFFICIENT_ARGS
:
91 error_message
= "Not enough arguments";
94 error_message
= "Expected integer";
96 case DECIMAL_EXPECTED
:
97 error_message
= "Expected decimal";
99 case SEPARATOR_EXPECTED
:
100 error_message
= "Expected argument separator";
103 error_message
= "Expected list close";
105 case MULTILINE_EXPECTED
:
106 error_message
= "Expected subline separator";
112 int skin_error_line()
122 char* skin_error_message()
124 return error_message
;
127 void skin_clear_errors()
131 error_message
= NULL
;
134 #if !defined(ROCKBOX) || defined(__PCTOOL__)
135 void skin_debug_tree(struct skin_element
* root
)
140 struct skin_element
* current
= root
;
146 switch(current
->type
)
149 printf("* Unknown element.. error *\n");
153 printf("{ Viewport \n");
155 debug_indent_level
++;
156 skin_debug_tree(get_child(current
->children
, 0));
157 debug_indent_level
--;
163 text
= SKINOFFSETTOPTR(skin_buffer
, current
->data
);
164 printf("* Plain text on line %d: \"%s\"\n", current
->line
, text
);
168 printf("# Comment on line %d\n ", current
->line
);
172 if (current
->params_count
)
174 printf("( %%%s tag on line %d with %d arguments\n",
176 current
->line
, current
->params_count
);
177 debug_indent_level
++;
178 skin_debug_params(current
->params_count
, SKINOFFSETTOPTR(skin_buffer
, current
->params
));
179 debug_indent_level
--;
185 printf("[ %%%s tag on line %d ]\n",
186 current
->tag
->name
, current
->line
);
191 case LINE_ALTERNATOR
:
192 printf("[ Alternator on line %d with %d sublines \n", current
->line
,
193 current
->children_count
);
194 debug_indent_level
++;
195 for(i
= 0; i
< current
->children_count
; i
++)
197 skin_debug_tree(get_child(current
->children
, i
));
199 debug_indent_level
--;
206 printf("< Conditional tag %%?%s on line %d with %d enumerations \n",
207 current
->tag
->name
, current
->line
, current
->children_count
);
208 debug_indent_level
++;
210 for(i
= 0; i
< current
->children_count
; i
++)
213 printf("[ Enumeration %d\n", i
);
214 debug_indent_level
++;
215 skin_debug_tree(get_child(current
->children
, i
));
216 debug_indent_level
--;
221 debug_indent_level
--;
229 printf("[ Logical line on line %d\n", current
->line
);
231 debug_indent_level
++;
232 if (current
->children
)
233 skin_debug_tree(get_child(current
->children
, 0));
234 debug_indent_level
--;
241 current
= SKINOFFSETTOPTR(skin_buffer
, current
->next
);
246 void skin_debug_params(int count
, struct skin_tag_parameter params
[])
249 for(i
= 0; i
< count
; i
++)
253 switch(params
[i
].type
)
260 printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer
, params
[i
].data
.text
));
264 printf("integer: %d", params
[i
].data
.number
);
268 printf("decimal: %d.%d", params
[i
].data
.number
/10,
269 params
[i
].data
.number
%10);
273 printf("Skin Code: \n");
274 debug_indent_level
++;
275 skin_debug_tree(SKINOFFSETTOPTR(skin_buffer
, params
[i
].data
.code
));
276 debug_indent_level
--;
286 void skin_debug_indent(void)
289 for(i
= 0; i
< debug_indent_level
; i
++)
295 #define MIN(a,b) ((a<b)?(a):(b))
296 void skin_error_format_message(void)
300 if (!error_line_start
)
302 char* line_end
= strchr(error_line_start
, '\n');
303 int len
= MIN(line_end
- error_line_start
, 80);
305 len
= strlen(error_line_start
);
306 printf("Error on line %d.\n", error_line
);
310 strncpy(text
, error_line_start
, len
);
316 /* make it fit nicely.. "<start few chars>...<10 chars><error>" */
317 strncpy(text
, error_line_start
, 6);
322 for (j
=error_col
-10; error_line_start
[j
] && error_line_start
[j
] != '\n'; j
++)
323 text
[i
++] = error_line_start
[j
];
327 printf("%s\n", text
);
328 for (i
=0; i
<error_col
; i
++)
330 snprintf(&text
[i
],64, "^ \'%s\' Here", error_message
);
331 printf("%s\n", text
);