updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / ctags-css / css.patch
blob76886d7b8c0a0478e0d4efe369b57f361338619f
1 *** parsers.h 2009-07-07 06:40:51.000000000 +0300
2 --- parsers.h 2010-04-22 16:44:03.000000000 +0300
3 ***************
4 *** 26,31 ****
5 --- 26,32 ----
6 CppParser, \
7 CsharpParser, \
8 CobolParser, \
9 + CssParser, \
10 DosBatchParser, \
11 EiffelParser, \
12 ErlangParser, \
13 *** source.mak 2009-07-07 06:55:23.000000000 +0300
14 --- source.mak 2010-04-22 16:44:51.000000000 +0300
15 ***************
16 *** 17,22 ****
17 --- 17,23 ----
18 beta.c \
19 c.c \
20 cobol.c \
21 + css.c \
22 dosbatch.c \
23 eiffel.c \
24 entry.c \
25 ***************
26 *** 79,84 ****
27 --- 80,86 ----
28 beta.$(OBJEXT) \
29 c.$(OBJEXT) \
30 cobol.$(OBJEXT) \
31 + css.$(OBJEXT) \
32 dosbatch.$(OBJEXT) \
33 eiffel.$(OBJEXT) \
34 entry.$(OBJEXT) \
35 +++ css.c 2010-04-22 19:54:47.835081310 +0300
36 @@ -0,0 +1,229 @@
37 +/***************************************************************************
38 + * css.c
39 + * Character-based parser for Css definitions
40 + * Author - Iago Rubio <iagorubio(at)users.sourceforge.net>
41 + **************************************************************************/
42 +#include "general.h"
44 +#include <string.h>
45 +#include <ctype.h>
47 +#include "parse.h"
48 +#include "read.h"
51 +typedef enum eCssKinds {
52 + K_NONE = -1, K_CLASS, K_SELECTOR, K_ID
53 +} cssKind;
55 +static kindOption CssKinds [] = {
56 + { TRUE, 'c', "class", "classes" },
57 + { TRUE, 's', "selector", "selectors" },
58 + { TRUE, 'i', "id", "identities" }
59 +};
61 +typedef enum _CssParserState { // state of parsing
62 + P_STATE_NONE, // default state
63 + P_STATE_IN_COMMENT, // into a comment, only multi line in CSS
64 + P_STATE_IN_SINGLE_STRING, // into a single quoted string
65 + P_STATE_IN_DOUBLE_STRING, // into a double quoted string
66 + P_STATE_IN_DEFINITION, // on the body of the style definition, nothing for us
67 + P_STATE_IN_MEDIA, // on a @media declaration, can be multi-line
68 + P_STATE_IN_IMPORT, // on a @import declaration, can be multi-line
69 + P_STATE_IN_NAMESPACE, // on a @namespace declaration
70 + P_STATE_IN_PAGE, // on a @page declaration
71 + P_STATE_IN_FONTFACE, // on a @font-face declaration
72 + P_STATE_AT_END // end of parsing
73 +} CssParserState;
75 +static void makeCssSimpleTag( vString *name, cssKind kind, boolean delete )
77 + if (kind == K_CLASS) {
78 + vStringStripTrailing(name);
79 + }
80 + vStringTerminate (name);
81 + makeSimpleTag (name, CssKinds, kind);
82 + vStringClear (name);
83 + if( delete )
84 + vStringDelete (name);
87 +static boolean isCssDeclarationAllowedChar( const unsigned char *cp )
89 + return isalnum ((int) *cp) ||
90 + isspace ((int) *cp) ||
91 + *cp == '_' || // allowed char
92 + *cp == '-' || // allowed char
93 + *cp == '+' || // allow all sibling in a single tag
94 + *cp == '>' || // allow all child in a single tag
95 + *cp == '{' || // allow the start of the declaration
96 + *cp == '.' || // allow classes and selectors
97 + *cp == ',' || // allow multiple declarations
98 + *cp == ':' || // allow pseudo classes
99 + *cp == '*' || // allow globs as P + *
100 + *cp == '#'; // allow ids
103 +static CssParserState parseCssDeclaration( const unsigned char **position, cssKind kind )
105 + vString *name = vStringNew ();
106 + const unsigned char *cp = *position;
108 + // pick to the end of line including children and sibling
109 + // if declaration is multiline go for the next line
110 + while ( isCssDeclarationAllowedChar(cp) ||
111 + *cp == '\0' ) // track the end of line into the loop
113 + if( (int) *cp == '\0' )
114 + {
115 + cp = fileReadLine ();
116 + if( cp == NULL ){
117 + makeCssSimpleTag(name, kind, TRUE);
118 + *position = cp;
119 + return P_STATE_AT_END;
122 + else if( *cp == ',' )
124 + makeCssSimpleTag(name, kind, TRUE);
125 + *position = ++cp;
126 + return P_STATE_NONE;
128 + else if( *cp == '{' )
130 + makeCssSimpleTag(name, kind, TRUE);
131 + *position = ++cp;
132 + return P_STATE_IN_DEFINITION;
135 + vStringPut (name, (int) *cp);
136 + ++cp;
139 + makeCssSimpleTag(name, kind, TRUE);
140 + *position = cp;
142 + return P_STATE_NONE;
145 +static CssParserState parseCssLine( const unsigned char *line, CssParserState state )
147 + vString *aux;
149 + while( *line != '\0' ) // fileReadLine returns NULL terminated strings
151 + while (isspace ((int) *line))
152 + ++line;
153 + switch( state )
155 + case P_STATE_NONE:
156 + // pick first char if alphanumeric is a selector
157 + if( isalnum ((int) *line) )
158 + state = parseCssDeclaration( &line, K_SELECTOR );
159 + else if( *line == '.' ) // a class
160 + state = parseCssDeclaration( &line, K_CLASS );
161 + else if( *line == '#' ) // an id
162 + state = parseCssDeclaration( &line, K_ID );
163 + else if( *line == '@' ) // at-rules, we'll ignore them
165 + ++line;
166 + aux = vStringNew();
167 + while( !isspace((int) *line) )
169 + vStringPut (aux, (int) *line);
170 + ++line;
172 + vStringTerminate (aux);
173 + if( strcmp( aux->buffer, "media" ) == 0 )
174 + state = P_STATE_IN_MEDIA;
175 + else if ( strcmp( aux->buffer, "import" ) == 0 )
176 + state = P_STATE_IN_IMPORT;
177 + else if ( strcmp( aux->buffer, "namespace" ) == 0 )
178 + state = P_STATE_IN_NAMESPACE;
179 + else if ( strcmp( aux->buffer, "page" ) == 0 )
180 + state = P_STATE_IN_PAGE;
181 + else if ( strcmp( aux->buffer, "font-face" ) == 0 )
182 + state = P_STATE_IN_FONTFACE;
183 + vStringDelete (aux);
185 + else if( *line == '*' && *(line-1) == '/' ) // multi-line comment
186 + state = P_STATE_IN_COMMENT;
187 + break;
188 + case P_STATE_IN_COMMENT:
189 + if( *line == '/' && *(line-1) == '*')
190 + state = P_STATE_NONE;
191 + break;
192 + case P_STATE_IN_SINGLE_STRING:
193 + if( *line == '\'' && *(line-1) != '\\' )
194 + state = P_STATE_IN_DEFINITION; // PAGE, FONTFACE and DEFINITION are treated the same way
195 + break;
196 + case P_STATE_IN_DOUBLE_STRING:
197 + if( *line=='"' && *(line-1) != '\\' )
198 + state = P_STATE_IN_DEFINITION; // PAGE, FONTFACE and DEFINITION are treated the same way
199 + break;
200 + case P_STATE_IN_MEDIA:
201 + // skip to start of media body or line end
202 + while( *line != '{' )
204 + if( *line == '\0' )
205 + break;
206 + ++line;
208 + if( *line == '{' )
209 + state = P_STATE_NONE;
210 + break;
211 + case P_STATE_IN_IMPORT:
212 + case P_STATE_IN_NAMESPACE:
213 + // skip to end of declaration or line end
214 + while( *line != ';' )
216 + if( *line == '\0' )
217 + break;
218 + ++line;
220 + if( *line == ';' )
221 + state = P_STATE_NONE;
222 + break;
223 + case P_STATE_IN_PAGE:
224 + case P_STATE_IN_FONTFACE:
225 + case P_STATE_IN_DEFINITION:
226 + if( *line == '}' )
227 + state = P_STATE_NONE;
228 + else if( *line == '\'' )
229 + state = P_STATE_IN_SINGLE_STRING;
230 + else if( *line == '"' )
231 + state = P_STATE_IN_DOUBLE_STRING;
232 + break;
233 + case P_STATE_AT_END:
234 + return state;
235 + break;
236 + }
237 + line++;
239 + return state;
242 +static void findCssTags (void)
244 + const unsigned char *line;
245 + CssParserState state = P_STATE_NONE;
247 + while ( (line = fileReadLine ()) != NULL )
249 + state = parseCssLine( line, state );
250 + if( state==P_STATE_AT_END ) return;
251 + }
254 +/* parser definition */
255 +extern parserDefinition* CssParser (void)
257 + static const char *const extensions [] = { "css", NULL };
258 + parserDefinition* def = parserNew ("CSS");
259 + def->kinds = CssKinds;
260 + def->kindCount = KIND_COUNT (CssKinds);
261 + def->extensions = extensions;
262 + def->parser = findCssTags;
263 + return def;