blob: f93606d54d8fa4713b6d906dcb1e2cfa6002b0f0 [file] [log] [blame]
Robert Bieberd5b24dd2010-05-25 15:19:52 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2010 Robert Bieber
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <ctype.h>
24#include <stdlib.h>
Robert Bieberd1659d62010-06-01 07:11:23 +000025#include <string.h>
Robert Bieberd5b24dd2010-05-25 15:19:52 +000026
27#include "skin_scan.h"
28#include "skin_debug.h"
29#include "symbols.h"
30#include "skin_parser.h"
Jonathan Gordon2d3c43d2012-04-21 23:34:42 +100031#include "tag_table.h"
Robert Bieberd5b24dd2010-05-25 15:19:52 +000032
33/* Scanning Functions */
34
35/* Simple function to advance a char* past a comment */
Nils Wallménius597ccdd2010-07-31 16:25:41 +000036void skip_comment(const char** document)
Robert Bieberd5b24dd2010-05-25 15:19:52 +000037{
Robert Bieber06ea93d2010-06-07 23:49:06 +000038 while(**document != '\n' && **document != '\0')
39 (*document)++;
Robert Bieberd5b24dd2010-05-25 15:19:52 +000040 if(**document == '\n')
41 (*document)++;
42}
43
Jonathan Gordon2d3c43d2012-04-21 23:34:42 +100044void skip_tag(const char** document)
45{
46 char tag_name[MAX_TAG_LENGTH];
47 int i;
48 bool qmark;
49 const struct tag_info *tag;
50 const char *cursor;
51
52 if(**document == TAGSYM)
53 (*document)++;
54 qmark = (**document == CONDITIONSYM);
55 if (qmark)
56 (*document)++;
57
58 if (!qmark && find_escape_character(**document))
59 {
60 (*document)++;
61 }
62 else
63 {
64 cursor = *document;
65
66 /* Checking the tag name */
67 for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++)
68 tag_name[i] = cursor[i];
69
70 /* First we check the two characters after the '%', then a single char */
71 tag = NULL;
72 i = MAX_TAG_LENGTH;
73 while (!tag && i > 1)
74 {
75 tag_name[i-1] = '\0';
76 tag = find_tag(tag_name);
77 i--;
78 }
79
80 if (tag)
81 {
82 *document += strlen(tag->name);
83 }
84 }
85 if (**document == ARGLISTOPENSYM)
86 skip_arglist(document);
87
88 if (**document == ENUMLISTOPENSYM)
89 skip_enumlist(document);
90}
91
Nils Wallménius597ccdd2010-07-31 16:25:41 +000092void skip_arglist(const char** document)
Robert Bieber06ea93d2010-06-07 23:49:06 +000093{
94 if(**document == ARGLISTOPENSYM)
95 (*document)++;
96 while(**document && **document != ARGLISTCLOSESYM)
97 {
98 if(**document == TAGSYM)
Jonathan Gordon2d3c43d2012-04-21 23:34:42 +100099 skip_tag(document);
Robert Bieber06ea93d2010-06-07 23:49:06 +0000100 else if(**document == COMMENTSYM)
101 skip_comment(document);
102 else
103 (*document)++;
104 }
105 if(**document == ARGLISTCLOSESYM)
106 (*document)++;
107}
108
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000109void skip_enumlist(const char** document)
Robert Bieber06ea93d2010-06-07 23:49:06 +0000110{
111 if(**document == ENUMLISTOPENSYM)
112 (*document)++;
113 while(**document && **document != ENUMLISTCLOSESYM)
114 {
115 if(**document == TAGSYM)
Jonathan Gordon2d3c43d2012-04-21 23:34:42 +1000116 skip_tag(document);
Robert Bieber06ea93d2010-06-07 23:49:06 +0000117 else if(**document == COMMENTSYM)
118 skip_comment(document);
119 else
120 (*document)++;
121 }
122
123 if(**document == ENUMLISTCLOSESYM)
124 (*document)++;
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000125}
126
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000127char* scan_string(const char** document)
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000128{
129
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000130 const char* cursor = *document;
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000131 int length = 0;
132 char* buffer = NULL;
133 int i;
134
Bertrik Sikkenfffbdcc2010-11-05 09:51:19 +0000135 while(*cursor != ARGLISTSEPARATESYM && *cursor != ARGLISTCLOSESYM &&
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000136 *cursor != '\0')
137 {
138 if(*cursor == COMMENTSYM)
139 {
140 skip_comment(&cursor);
141 continue;
142 }
143
Robert Bieber999990c2010-06-02 05:45:34 +0000144 if(*cursor == TAGSYM)
145 cursor++;
146
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000147 if(*cursor == '\n')
148 {
Dominik Riebeling3cd19682010-07-18 08:58:04 +0000149 skin_error(UNEXPECTED_NEWLINE, cursor);
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000150 return NULL;
151 }
152
153 length++;
154 cursor++;
155 }
156
157 /* Copying the string */
158 cursor = *document;
159 buffer = skin_alloc_string(length);
Jonathan Gordon2d31d772010-07-29 12:37:48 +0000160 if (!buffer)
161 return NULL;
Robert Bieber1937b1b2010-05-25 17:22:39 +0000162 buffer[length] = '\0';
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000163 for(i = 0; i < length; i++)
164 {
Robert Bieber999990c2010-06-02 05:45:34 +0000165 if(*cursor == TAGSYM)
166 cursor++;
167
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000168 if(*cursor == COMMENTSYM)
169 {
170 skip_comment(&cursor);
171 i--;
172 continue;
173 }
174
175 buffer[i] = *cursor;
176 cursor++;
177 }
178
179 *document = cursor;
180 return buffer;
181}
182
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000183int scan_int(const char** document)
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000184{
185
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000186 const char *cursor = *document, *end;
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000187 int length = 0;
Jonathan Gordone8a66242010-06-02 10:35:19 +0000188 char buffer[16];
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000189 int retval;
190 int i;
191
Robert Bieberea864be2010-06-02 06:52:17 +0000192 while(isdigit(*cursor) || *cursor == COMMENTSYM || *cursor == '-')
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000193 {
194 if(*cursor == COMMENTSYM)
195 {
196 skip_comment(&cursor);
197 continue;
198 }
199
200 length++;
201 cursor++;
202 }
Jonathan Gordone8a66242010-06-02 10:35:19 +0000203 if (length > 15)
204 length = 15;
205 end = cursor;
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000206 /* Copying to the buffer while avoiding comments */
207 cursor = *document;
208 buffer[length] = '\0';
209 for(i = 0; i < length; i++)
210 {
211 if(*cursor == COMMENTSYM)
212 {
213 skip_comment(&cursor);
214 i--;
215 continue;
216 }
217
218 buffer[i] = *cursor;
219 cursor++;
220
221 }
222 retval = atoi(buffer);
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000223
Jonathan Gordone8a66242010-06-02 10:35:19 +0000224 *document = end;
Robert Bieberd5b24dd2010-05-25 15:19:52 +0000225 return retval;
226}
Robert Bieberd1659d62010-06-01 07:11:23 +0000227
Nils Wallménius597ccdd2010-07-31 16:25:41 +0000228int check_viewport(const char* document)
Robert Bieberd1659d62010-06-01 07:11:23 +0000229{
230 if(strlen(document) < 3)
231 return 0;
232
233 if(document[0] != TAGSYM)
234 return 0;
235
236 if(document[1] != 'V')
237 return 0;
238
239 if(document[2] != ARGLISTOPENSYM
240 && document[2] != 'l'
241 && document[2] != 'i')
242 return 0;
243
244 return 1;
245}