1 /*
2  Copyright (C) 2016-2017 Alexander Borisov
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 
18  Author: lex.borisov@gmail.com (Alexander Borisov)
19 */
20 
21 #include "mycss/selectors/function.h"
22 #include "mycss/selectors/function_resource.h"
23 #include "mycore/utils/resources.h"
24 
25 /////////////////////////////////////////////////////////
26 //// Functions for a find Begin Function
27 ////
28 /////////////////////////////////////////////////////////
mycss_function_begin_entry_by_name(const char * name,size_t length)29 const mycss_selectots_function_begin_entry_t * mycss_function_begin_entry_by_name(const char* name, size_t length)
30 {
31     size_t idx = ((mycore_string_chars_lowercase_map[ (const unsigned char)name[0] ] *
32                    mycore_string_chars_lowercase_map[ (const unsigned char)name[(length - 1)] ] *
33                    length)
34                   % MyCSS_SELECTORS_FUNCTION_NAME_STATIC_SIZE) + 1;
35 
36     while (mycss_selectors_function_begin_map_index[idx].name)
37     {
38         if(mycss_selectors_function_begin_map_index[idx].length == length) {
39             if(mycore_strncasecmp(mycss_selectors_function_begin_map_index[idx].name, name, length) == 0)
40                 return &mycss_selectors_function_begin_map_index[idx];
41 
42             if(mycss_selectors_function_begin_map_index[idx].next)
43                 idx = mycss_selectors_function_begin_map_index[idx].next;
44             else
45                 return NULL;
46         }
47         else if(mycss_selectors_function_begin_map_index[idx].length > length) {
48             return NULL;
49         }
50         else {
51             idx = mycss_selectors_function_begin_map_index[idx].next;
52         }
53     }
54 
55     return NULL;
56 }
57 
mycss_function_begin_by_name(const char * name,size_t length)58 mycss_selectors_function_begin_f mycss_function_begin_by_name(const char *name, size_t length)
59 {
60     const mycss_selectots_function_begin_entry_t *entry = mycss_function_begin_entry_by_name(name, length);
61 
62     if(entry) {
63         return entry->func;
64     }
65 
66     return NULL;
67 }
68 
69 /////////////////////////////////////////////////////////
70 //// Unknown, for not exists function
71 ////
72 /////////////////////////////////////////////////////////
mycss_selectors_begin_unknown(mycss_entry_t * entry,mycss_selectors_entry_t * selector)73 void mycss_selectors_begin_unknown(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
74 {
75     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_UNKNOWN;
76 
77     entry->parser = mycss_selectors_unknown_parser;
78 }
79 
80 ///////////////////////////////////////////////////////////
81 ////// Begin functions
82 //////
83 ///////////////////////////////////////////////////////////
mycss_selectors_function_begin_nth_child(mycss_entry_t * entry,mycss_selectors_entry_t * selector)84 void mycss_selectors_function_begin_nth_child(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
85 {
86     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_CHILD;
87 
88     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
89 
90     entry->parser = mycss_an_plus_b_state_anb_begin;
91     entry->parser_switch = mycss_selectors_function_parser_nth_with_selectors;
92 }
93 
mycss_selectors_function_begin_has(mycss_entry_t * entry,mycss_selectors_entry_t * selector)94 void mycss_selectors_function_begin_has(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
95 {
96     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_HAS;
97 
98     mycss_selectors_t *selectors = entry->selectors;
99     mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
100     mycss_selectors_list_t *current_list = selectors->list_last;
101 
102     selectors->list = new_list;
103     selectors->list_last = NULL;
104     selectors->ending_token = entry->parser_ending_token;
105 
106     mycss_selectors_state_relative_selector_list(entry, NULL, true);
107 
108     (*new_list)->parent = current_list;
109 
110     mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_has, entry->parser_switch, entry->parser_ending_token, false);
111 }
112 
mycss_selectors_function_begin_contains(mycss_entry_t * entry,mycss_selectors_entry_t * selector)113 void mycss_selectors_function_begin_contains(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
114 {
115     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CONTAINS;
116 
117     mycss_selectors_t *selectors = entry->selectors;
118     mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
119     mycss_selectors_list_t *current_list = selectors->list_last;
120 
121     selectors->list = new_list;
122     selectors->list_last = NULL;
123     selectors->ending_token = entry->parser_ending_token;
124 
125     mycss_selectors_state_relative_selector_list(entry, NULL, true);
126 
127     (*new_list)->parent = current_list;
128 
129     mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_contains, entry->parser_switch, entry->parser_ending_token, false);
130 }
131 
mycss_selectors_function_begin_nth_last_child(mycss_entry_t * entry,mycss_selectors_entry_t * selector)132 void mycss_selectors_function_begin_nth_last_child(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
133 {
134     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_CHILD;
135 
136     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
137 
138     entry->parser = mycss_an_plus_b_state_anb_begin;
139     entry->parser_switch = mycss_selectors_function_parser_nth_with_selectors;
140 }
141 
mycss_selectors_function_begin_drop(mycss_entry_t * entry,mycss_selectors_entry_t * selector)142 void mycss_selectors_function_begin_drop(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
143 {
144     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DROP;
145 
146     selector->value = NULL;
147     entry->parser = mycss_selectors_function_parser_drop;
148 }
149 
mycss_selectors_function_begin_nth_last_of_type(mycss_entry_t * entry,mycss_selectors_entry_t * selector)150 void mycss_selectors_function_begin_nth_last_of_type(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
151 {
152     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_OF_TYPE;
153 
154     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
155 
156     entry->parser = mycss_an_plus_b_state_anb_begin;
157     entry->parser_switch = mycss_selectors_function_parser_nth_without_selectors;
158 }
159 
mycss_selectors_function_begin_not(mycss_entry_t * entry,mycss_selectors_entry_t * selector)160 void mycss_selectors_function_begin_not(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
161 {
162     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NOT;
163 
164     mycss_selectors_t *selectors = entry->selectors;
165     mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
166     mycss_selectors_list_t *current_list = selectors->list_last;
167 
168     selectors->list = new_list;
169     selectors->list_last = NULL;
170     selectors->ending_token = entry->parser_ending_token;
171 
172     mycss_selectors_state_compound_selector_list(entry, NULL, true);
173 
174     (*new_list)->parent = current_list;
175 
176     mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_not_or_matches_or_current_parser,
177                                  entry->parser_switch, entry->parser_ending_token, false);
178 }
179 
mycss_selectors_function_begin_current(mycss_entry_t * entry,mycss_selectors_entry_t * selector)180 void mycss_selectors_function_begin_current(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
181 {
182     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_CURRENT;
183 
184     mycss_selectors_t *selectors = entry->selectors;
185     mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
186     mycss_selectors_list_t *current_list = selectors->list_last;
187 
188     selectors->list = new_list;
189     selectors->list_last = NULL;
190     selectors->ending_token = entry->parser_ending_token;
191 
192     mycss_selectors_state_compound_selector_list(entry, NULL, true);
193 
194     (*new_list)->parent = current_list;
195 
196     mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_not_or_matches_or_current_parser,
197                                  entry->parser_switch, entry->parser_ending_token, false);
198 }
199 
mycss_selectors_function_begin_nth_of_type(mycss_entry_t * entry,mycss_selectors_entry_t * selector)200 void mycss_selectors_function_begin_nth_of_type(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
201 {
202     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_OF_TYPE;
203 
204     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
205 
206     entry->parser = mycss_an_plus_b_state_anb_begin;
207     entry->parser_switch = mycss_selectors_function_parser_nth_without_selectors;
208 }
209 
mycss_selectors_function_begin_nth_last_column(mycss_entry_t * entry,mycss_selectors_entry_t * selector)210 void mycss_selectors_function_begin_nth_last_column(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
211 {
212     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_LAST_COLUMN;
213 
214     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
215 
216     entry->parser = mycss_an_plus_b_state_anb_begin;
217     entry->parser_switch = mycss_selectors_function_parser_nth_without_selectors;
218 }
219 
mycss_selectors_function_begin_dir(mycss_entry_t * entry,mycss_selectors_entry_t * selector)220 void mycss_selectors_function_begin_dir(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
221 {
222     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_DIR;
223     selector->value    = NULL;
224 
225     entry->parser = mycss_selectors_function_parser_dir;
226 }
227 
mycss_selectors_function_begin_matches(mycss_entry_t * entry,mycss_selectors_entry_t * selector)228 void mycss_selectors_function_begin_matches(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
229 {
230     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_MATCHES;
231 
232     mycss_selectors_t *selectors = entry->selectors;
233     mycss_selectors_list_t **new_list = (mycss_selectors_list_t**)(&selectors->entry_last->value);
234     mycss_selectors_list_t *current_list = selectors->list_last;
235 
236     selectors->list = new_list;
237     selectors->list_last = NULL;
238     selectors->ending_token = entry->parser_ending_token;
239 
240     mycss_selectors_state_compound_selector_list(entry, NULL, true);
241 
242     (*new_list)->parent = current_list;
243 
244     mycss_entry_parser_list_push(entry, mycss_selectors_function_parser_not_or_matches_or_current_parser, entry->parser_switch, entry->parser_ending_token, false);
245 }
246 
mycss_selectors_function_begin_nth_column(mycss_entry_t * entry,mycss_selectors_entry_t * selector)247 void mycss_selectors_function_begin_nth_column(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
248 {
249     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_NTH_COLUMN;
250 
251     entry->anb->entry = (mycss_an_plus_b_entry_t**)(&selector->value);
252 
253     entry->parser = mycss_an_plus_b_state_anb_begin;
254     entry->parser_switch = mycss_selectors_function_parser_nth_without_selectors;
255 }
256 
mycss_selectors_function_begin_lang(mycss_entry_t * entry,mycss_selectors_entry_t * selector)257 void mycss_selectors_function_begin_lang(mycss_entry_t* entry, mycss_selectors_entry_t* selector)
258 {
259     selector->sub_type = MyCSS_SELECTORS_SUB_TYPE_PSEUDO_CLASS_FUNCTION_LANG;
260     selector->value    = NULL;
261 
262     entry->parser = mycss_selectors_function_parser_lang;
263 }
264 
265 
266