Android: no need to keep RockboxPCM_class around
[maemo-rb.git] / lib / skin_parser / skin_debug.c
blob52f9127f1f88160f4e4d234a17e802a70b8e9d2f
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;
35 /* Global error variables */
36 int error_line;
37 int error_col;
38 const char *error_line_start;
39 char* error_message;
41 /* Debugging functions */
42 void skin_error(enum skin_errorcode error, const char* cursor)
45 error_col = 0;
47 while(cursor > skin_start && *cursor != '\n')
49 cursor--;
50 error_col++;
52 error_line_start = cursor+1;
54 error_line = skin_line;
56 switch(error)
58 case MEMORY_LIMIT_EXCEEDED:
59 error_line_start = NULL;
60 printf("Error: Memory limit exceeded at Line %d\n", skin_line);
61 error_message = "Memory limit exceeded";
62 break;
63 case NEWLINE_EXPECTED:
64 error_message = "Newline expected";
65 break;
66 case ILLEGAL_TAG:
67 error_message = "Illegal tag";
68 break;
69 case ARGLIST_EXPECTED:
70 error_message = "Argument list expected";
71 break;
72 case TOO_MANY_ARGS:
73 error_message = "Too many arguments given";
74 break;
75 case DEFAULT_NOT_ALLOWED:
76 error_message = "Argument can not be set to default";
77 break;
78 case UNEXPECTED_NEWLINE:
79 error_message = "Unexpected newline";
80 break;
81 case INSUFFICIENT_ARGS:
82 error_message = "Not enough arguments";
83 break;
84 case INT_EXPECTED:
85 error_message = "Expected integer";
86 break;
87 case DECIMAL_EXPECTED:
88 error_message = "Expected decimal";
89 break;
90 case SEPARATOR_EXPECTED:
91 error_message = "Expected argument separator";
92 break;
93 case CLOSE_EXPECTED:
94 error_message = "Expected list close";
95 break;
96 case MULTILINE_EXPECTED:
97 error_message = "Expected subline separator";
98 break;
103 int skin_error_line()
105 return error_line;
108 int skin_error_col()
110 return error_col;
113 char* skin_error_message()
115 return error_message;
118 void skin_clear_errors()
120 error_line = 0;
121 error_col = 0;
122 error_message = NULL;
125 #if !defined(ROCKBOX) || defined(__PCTOOL__)
126 void skin_debug_tree(struct skin_element* root)
128 int i;
129 char *text;
131 struct skin_element* current = root;
133 while(current)
135 skin_debug_indent();
137 switch(current->type)
139 case UNKNOWN:
140 printf("* Unknown element.. error *\n");
141 break;
143 case VIEWPORT:
144 printf("{ Viewport \n");
146 debug_indent_level++;
147 skin_debug_tree(current->children[0]);
148 debug_indent_level--;
150 printf("}");
151 break;
153 case TEXT:
154 text = current->data;
155 printf("* Plain text on line %d: \"%s\"\n", current->line, text);
156 break;
158 case COMMENT:
159 printf("# Comment on line %d\n ", current->line);
160 break;
162 case TAG:
163 if (current->params_count)
165 printf("( %%%s tag on line %d with %d arguments\n",
166 current->tag->name,
167 current->line, current->params_count);
168 debug_indent_level++;
169 skin_debug_params(current->params_count, current->params);
170 debug_indent_level--;
171 skin_debug_indent();
172 printf(")\n");
174 else
176 printf("[ %%%s tag on line %d ]\n",
177 current->tag->name, current->line);
180 break;
182 case LINE_ALTERNATOR:
183 printf("[ Alternator on line %d with %d sublines \n", current->line,
184 current->children_count);
185 debug_indent_level++;
186 for(i = 0; i < current->children_count; i++)
188 skin_debug_tree(current->children[i]);
190 debug_indent_level--;
192 skin_debug_indent();
193 printf("]\n");
194 break;
196 case CONDITIONAL:
197 printf("< Conditional tag %%?%s on line %d with %d enumerations \n",
198 current->tag->name, current->line, current->children_count);
199 debug_indent_level++;
201 for(i = 0; i < current->children_count; i++)
203 skin_debug_indent();
204 printf("[ Enumeration %d\n", i);
205 debug_indent_level++;
206 skin_debug_tree(current->children[i]);
207 debug_indent_level--;
208 skin_debug_indent();
209 printf("]\n");
212 debug_indent_level--;
213 skin_debug_indent();
214 printf(">\n");
217 break;
219 case LINE:
220 printf("[ Logical line on line %d\n", current->line);
222 debug_indent_level++;
223 if (current->children)
224 skin_debug_tree(current->children[0]);
225 debug_indent_level--;
227 skin_debug_indent();
228 printf("]\n");
229 break;
232 current = current->next;
237 void skin_debug_params(int count, struct skin_tag_parameter params[])
239 int i;
240 for(i = 0; i < count; i++)
243 skin_debug_indent();
244 switch(params[i].type)
246 case DEFAULT:
247 printf("-");
248 break;
250 case STRING:
251 printf("string: \"%s\"", params[i].data.text);
252 break;
254 case INTEGER:
255 printf("integer: %d", params[i].data.number);
256 break;
258 case DECIMAL:
259 printf("decimal: %d.%d", params[i].data.number/10,
260 params[i].data.number%10);
261 break;
263 case CODE:
264 printf("Skin Code: \n");
265 debug_indent_level++;
266 skin_debug_tree(params[i].data.code);
267 debug_indent_level--;
268 skin_debug_indent();
269 break;
272 printf("\n");
277 void skin_debug_indent()
279 int i;
280 for(i = 0; i < debug_indent_level; i++)
281 printf(" ");
284 #endif
286 #define MIN(a,b) ((a<b)?(a):(b))
287 void skin_error_format_message()
289 int i;
290 char text[128];
291 if (!error_line_start)
292 return;
293 char* line_end = strchr(error_line_start, '\n');
294 int len = MIN(line_end - error_line_start, 80);
295 if (!line_end)
296 len = strlen(error_line_start);
297 printf("Error on line %d.\n", error_line);
298 error_col--;
299 if (error_col <= 10)
301 strncpy(text, error_line_start, len);
302 text[len] = '\0';
304 else
306 int j;
307 /* make it fit nicely.. "<start few chars>...<10 chars><error>" */
308 strncpy(text, error_line_start, 6);
309 i = 5;
310 text[i++] = '.';
311 text[i++] = '.';
312 text[i++] = '.';
313 for (j=error_col-10; error_line_start[j] && error_line_start[j] != '\n'; j++)
314 text[i++] = error_line_start[j];
315 text[i] = '\0';
316 error_col = 18;
318 printf("%s\n", text);
319 for (i=0; i<error_col; i++)
320 text[i] = ' ';
321 snprintf(&text[i],64, "^ \'%s\' Here", error_message);
322 printf("%s\n", text);