ipodpatcher: replace ipod2c with bin2c.
[maemo-rb.git] / lib / skin_parser / skin_debug.c
blob9537182341cdb400ec17c1f2f1f9c4c0419b9410
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
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;
32 extern int skin_line;
33 extern char* skin_start;
34 extern char* skin_buffer;
36 /* Global error variables */
37 int error_line;
38 int error_col;
39 const char *error_line_start;
40 char* error_message;
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);
47 return kids[child];
50 /* Debugging functions */
51 void skin_error(enum skin_errorcode error, const char* cursor)
54 error_col = 0;
56 while(cursor > skin_start && *cursor != '\n')
58 cursor--;
59 error_col++;
61 error_line_start = cursor+1;
63 error_line = skin_line;
65 switch(error)
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";
71 break;
72 case NEWLINE_EXPECTED:
73 error_message = "Newline expected";
74 break;
75 case ILLEGAL_TAG:
76 error_message = "Illegal tag";
77 break;
78 case ARGLIST_EXPECTED:
79 error_message = "Argument list expected";
80 break;
81 case TOO_MANY_ARGS:
82 error_message = "Too many arguments given";
83 break;
84 case DEFAULT_NOT_ALLOWED:
85 error_message = "Argument can not be set to default";
86 break;
87 case UNEXPECTED_NEWLINE:
88 error_message = "Unexpected newline";
89 break;
90 case INSUFFICIENT_ARGS:
91 error_message = "Not enough arguments";
92 break;
93 case INT_EXPECTED:
94 error_message = "Expected integer";
95 break;
96 case DECIMAL_EXPECTED:
97 error_message = "Expected decimal";
98 break;
99 case SEPARATOR_EXPECTED:
100 error_message = "Expected argument separator";
101 break;
102 case CLOSE_EXPECTED:
103 error_message = "Expected list close";
104 break;
105 case MULTILINE_EXPECTED:
106 error_message = "Expected subline separator";
107 break;
112 int skin_error_line()
114 return error_line;
117 int skin_error_col()
119 return error_col;
122 char* skin_error_message()
124 return error_message;
127 void skin_clear_errors()
129 error_line = 0;
130 error_col = 0;
131 error_message = NULL;
134 #if !defined(ROCKBOX) || defined(__PCTOOL__)
135 void skin_debug_tree(struct skin_element* root)
137 int i;
138 char *text;
140 struct skin_element* current = root;
142 while(current)
144 skin_debug_indent();
146 switch(current->type)
148 case UNKNOWN:
149 printf("* Unknown element.. error *\n");
150 break;
152 case VIEWPORT:
153 printf("{ Viewport \n");
155 debug_indent_level++;
156 skin_debug_tree(get_child(current->children, 0));
157 debug_indent_level--;
159 printf("}");
160 break;
162 case TEXT:
163 text = SKINOFFSETTOPTR(skin_buffer, current->data);
164 printf("* Plain text on line %d: \"%s\"\n", current->line, text);
165 break;
167 case COMMENT:
168 printf("# Comment on line %d\n ", current->line);
169 break;
171 case TAG:
172 if (current->params_count)
174 printf("( %%%s tag on line %d with %d arguments\n",
175 current->tag->name,
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--;
180 skin_debug_indent();
181 printf(")\n");
183 else
185 printf("[ %%%s tag on line %d ]\n",
186 current->tag->name, current->line);
189 break;
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--;
201 skin_debug_indent();
202 printf("]\n");
203 break;
205 case CONDITIONAL:
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++)
212 skin_debug_indent();
213 printf("[ Enumeration %d\n", i);
214 debug_indent_level++;
215 skin_debug_tree(get_child(current->children, i));
216 debug_indent_level--;
217 skin_debug_indent();
218 printf("]\n");
221 debug_indent_level--;
222 skin_debug_indent();
223 printf(">\n");
226 break;
228 case LINE:
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--;
236 skin_debug_indent();
237 printf("]\n");
238 break;
241 current = SKINOFFSETTOPTR(skin_buffer, current->next);
246 void skin_debug_params(int count, struct skin_tag_parameter params[])
248 int i;
249 for(i = 0; i < count; i++)
252 skin_debug_indent();
253 switch(params[i].type)
255 case DEFAULT:
256 printf("-");
257 break;
259 case STRING:
260 printf("string: \"%s\"", SKINOFFSETTOPTR(skin_buffer, params[i].data.text));
261 break;
263 case INTEGER:
264 printf("integer: %d", params[i].data.number);
265 break;
267 case DECIMAL:
268 printf("decimal: %d.%d", params[i].data.number/10,
269 params[i].data.number%10);
270 break;
272 case CODE:
273 printf("Skin Code: \n");
274 debug_indent_level++;
275 skin_debug_tree(SKINOFFSETTOPTR(skin_buffer, params[i].data.code));
276 debug_indent_level--;
277 skin_debug_indent();
278 break;
281 printf("\n");
286 void skin_debug_indent(void)
288 int i;
289 for(i = 0; i < debug_indent_level; i++)
290 printf(" ");
293 #endif
295 #define MIN(a,b) ((a<b)?(a):(b))
296 void skin_error_format_message(void)
298 int i;
299 char text[128];
300 if (!error_line_start)
301 return;
302 char* line_end = strchr(error_line_start, '\n');
303 int len = MIN(line_end - error_line_start, 80);
304 if (!line_end)
305 len = strlen(error_line_start);
306 printf("Error on line %d.\n", error_line);
307 error_col--;
308 if (error_col <= 10)
310 strncpy(text, error_line_start, len);
311 text[len] = '\0';
313 else
315 int j;
316 /* make it fit nicely.. "<start few chars>...<10 chars><error>" */
317 strncpy(text, error_line_start, 6);
318 i = 5;
319 text[i++] = '.';
320 text[i++] = '.';
321 text[i++] = '.';
322 for (j=error_col-10; error_line_start[j] && error_line_start[j] != '\n'; j++)
323 text[i++] = error_line_start[j];
324 text[i] = '\0';
325 error_col = 18;
327 printf("%s\n", text);
328 for (i=0; i<error_col; i++)
329 text[i] = ' ';
330 snprintf(&text[i],64, "^ \'%s\' Here", error_message);
331 printf("%s\n", text);