1 diff -up ctags-5.8/css.c.me ctags-5.8/css.c
2 --- ctags-5.8/css.c.me 2012-02-08 13:59:35.000000000 +0100
3 +++ ctags-5.8/css.c 2012-02-08 13:55:16.000000000 +0100
5 +/***************************************************************************
7 + * Character-based parser for Css definitions
8 + * Author - Iago Rubio <iagorubio(at)users.sourceforge.net>
9 + **************************************************************************/
19 +typedef enum eCssKinds {
20 + K_NONE = -1, K_CLASS, K_SELECTOR, K_ID
23 +static kindOption CssKinds [] = {
24 + { TRUE, 'c', "class", "classes" },
25 + { TRUE, 's', "selector", "selectors" },
26 + { TRUE, 'i', "id", "identities" }
29 +typedef enum _CssParserState { // state of parsing
30 + P_STATE_NONE, // default state
31 + P_STATE_IN_COMMENT, // into a comment, only multi line in CSS
32 + P_STATE_IN_SINGLE_STRING, // into a single quoted string
33 + P_STATE_IN_DOUBLE_STRING, // into a double quoted string
34 + P_STATE_IN_DEFINITION, // on the body of the style definition, nothing for us
35 + P_STATE_IN_MEDIA, // on a @media declaration, can be multi-line
36 + P_STATE_IN_IMPORT, // on a @import declaration, can be multi-line
37 + P_STATE_IN_NAMESPACE, // on a @namespace declaration
38 + P_STATE_IN_PAGE, // on a @page declaration
39 + P_STATE_IN_FONTFACE, // on a @font-face declaration
40 + P_STATE_AT_END // end of parsing
43 +static void makeCssSimpleTag( vString *name, cssKind kind, boolean delete )
45 + vStringTerminate (name);
46 + makeSimpleTag (name, CssKinds, kind);
47 + vStringClear (name);
49 + vStringDelete (name);
52 +static boolean isCssDeclarationAllowedChar( const unsigned char *cp )
54 + return isalnum ((int) *cp) ||
55 + isspace ((int) *cp) ||
56 + *cp == '_' || // allowed char
57 + *cp == '-' || // allowed char
58 + *cp == '+' || // allow all sibling in a single tag
59 + *cp == '>' || // allow all child in a single tag
60 + *cp == '{' || // allow the start of the declaration
61 + *cp == '.' || // allow classes and selectors
62 + *cp == ',' || // allow multiple declarations
63 + *cp == ':' || // allow pseudo classes
64 + *cp == '*' || // allow globs as P + *
65 + *cp == '#'; // allow ids
68 +static CssParserState parseCssDeclaration( const unsigned char **position, cssKind kind )
70 + vString *name = vStringNew ();
71 + const unsigned char *cp = *position;
73 + // pick to the end of line including children and sibling
74 + // if declaration is multiline go for the next line
75 + while ( isCssDeclarationAllowedChar(cp) ||
76 + *cp == '\0' ) // track the end of line into the loop
78 + if( (int) *cp == '\0' )
80 + cp = fileReadLine ();
82 + makeCssSimpleTag(name, kind, TRUE);
84 + return P_STATE_AT_END;
87 + else if( *cp == ',' )
89 + makeCssSimpleTag(name, kind, TRUE);
91 + return P_STATE_NONE;
93 + else if( *cp == '{' )
95 + makeCssSimpleTag(name, kind, TRUE);
97 + return P_STATE_IN_DEFINITION;
100 + vStringPut (name, (int) *cp);
104 + makeCssSimpleTag(name, kind, TRUE);
107 + return P_STATE_NONE;
110 +static CssParserState parseCssLine( const unsigned char *line, CssParserState state )
114 + while( *line != '\0' ) // fileReadLine returns NULL terminated strings
116 + while (isspace ((int) *line))
121 + // pick first char if alphanumeric is a selector
122 + if( isalnum ((int) *line) )
123 + state = parseCssDeclaration( &line, K_SELECTOR );
124 + else if( *line == '.' ) // a class
125 + state = parseCssDeclaration( &line, K_CLASS );
126 + else if( *line == '#' ) // an id
127 + state = parseCssDeclaration( &line, K_ID );
128 + else if( *line == '@' ) // at-rules, we'll ignore them
131 + aux = vStringNew();
132 + while( !isspace((int) *line) )
134 + vStringPut (aux, (int) *line);
137 + vStringTerminate (aux);
138 + if( strcmp( aux->buffer, "media" ) == 0 )
139 + state = P_STATE_IN_MEDIA;
140 + else if ( strcmp( aux->buffer, "import" ) == 0 )
141 + state = P_STATE_IN_IMPORT;
142 + else if ( strcmp( aux->buffer, "namespace" ) == 0 )
143 + state = P_STATE_IN_NAMESPACE;
144 + else if ( strcmp( aux->buffer, "page" ) == 0 )
145 + state = P_STATE_IN_PAGE;
146 + else if ( strcmp( aux->buffer, "font-face" ) == 0 )
147 + state = P_STATE_IN_FONTFACE;
148 + vStringDelete (aux);
150 + else if( *line == '*' && *(line-1) == '/' ) // multi-line comment
151 + state = P_STATE_IN_COMMENT;
153 + case P_STATE_IN_COMMENT:
154 + if( *line == '/' && *(line-1) == '*')
155 + state = P_STATE_NONE;
157 + case P_STATE_IN_SINGLE_STRING:
158 + if( *line == '\'' && *(line-1) != '\\' )
159 + state = P_STATE_IN_DEFINITION; // PAGE, FONTFACE and DEFINITION are treated the same way
161 + case P_STATE_IN_DOUBLE_STRING:
162 + if( *line=='"' && *(line-1) != '\\' )
163 + state = P_STATE_IN_DEFINITION; // PAGE, FONTFACE and DEFINITION are treated the same way
165 + case P_STATE_IN_MEDIA:
166 + // skip to start of media body or line end
167 + while( *line != '{' )
169 + if( *line == '\0' )
174 + state = P_STATE_NONE;
176 + case P_STATE_IN_IMPORT:
177 + case P_STATE_IN_NAMESPACE:
178 + // skip to end of declaration or line end
179 + while( *line != ';' )
181 + if( *line == '\0' )
186 + state = P_STATE_NONE;
188 + case P_STATE_IN_PAGE:
189 + case P_STATE_IN_FONTFACE:
190 + case P_STATE_IN_DEFINITION:
192 + state = P_STATE_NONE;
193 + else if( *line == '\'' )
194 + state = P_STATE_IN_SINGLE_STRING;
195 + else if( *line == '"' )
196 + state = P_STATE_IN_DOUBLE_STRING;
198 + case P_STATE_AT_END:
207 +static void findCssTags (void)
209 + const unsigned char *line;
210 + CssParserState state = P_STATE_NONE;
212 + while ( (line = fileReadLine ()) != NULL )
214 + state = parseCssLine( line, state );
215 + if( state==P_STATE_AT_END ) return;
219 +/* parser definition */
220 +extern parserDefinition* CssParser (void)
222 + static const char *const extensions [] = { "css", NULL };
223 + parserDefinition* def = parserNew ("CSS");
224 + def->kinds = CssKinds;
225 + def->kindCount = KIND_COUNT (CssKinds);
226 + def->extensions = extensions;
227 + def->parser = findCssTags;
231 diff -up ctags-5.8/parsers.h.me ctags-5.8/parsers.h
232 --- ctags-5.8/parsers.h.me 2012-02-08 13:56:46.000000000 +0100
233 +++ ctags-5.8/parsers.h 2012-02-08 13:57:25.000000000 +0100
242 diff -up ctags-5.8/source.mak.me ctags-5.8/source.mak
243 --- ctags-5.8/source.mak.me 2012-02-08 13:58:02.000000000 +0100
244 +++ ctags-5.8/source.mak 2012-02-08 13:58:42.000000000 +0100
245 @@ -17,6 +17,7 @@ SOURCES = \
253 @@ -79,6 +80,7 @@ OBJECTS = \