File Coverage

third_party/modest/source/modest/finder/finder.c
Criterion Covered Total %
statement 31 186 16.6
branch 20 140 14.2
condition n/a
subroutine n/a
pod n/a
total 51 326 15.6


line stmt bran cond sub pod time code
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 "modest/finder/finder.h"
22             #include "modest/finder/resource.h"
23              
24 0           modest_finder_t * modest_finder_create(void)
25             {
26 0           return (modest_finder_t*)mycore_calloc(1, sizeof(modest_finder_t));
27             }
28              
29 0           mystatus_t modest_finder_init(modest_finder_t* finder)
30             {
31 0           return MODEST_STATUS_OK;
32             }
33              
34 0           void modest_finder_clean(modest_finder_t* finder)
35             {
36            
37 0           }
38              
39 0           modest_finder_t * modest_finder_destroy(modest_finder_t* finder, bool self_destroy)
40             {
41 0 0         if(finder == NULL)
42 0           return NULL;
43            
44 0 0         if(self_destroy) {
45 0           mycore_free(finder);
46 0           return NULL;
47             }
48            
49 0           return finder;
50             }
51              
52 0           modest_finder_t * modest_finder_create_simple(void)
53             {
54 0           modest_finder_t *finder = modest_finder_create();
55            
56 0 0         if(finder == NULL)
57 0           return NULL;
58            
59 0 0         if(modest_finder_init(finder) != MODEST_STATUS_OK)
60 0           return modest_finder_destroy(finder, true);
61            
62 0           return finder;
63             }
64              
65 89           void modest_finder_callback_found_with_collection(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec, void* ctx)
66             {
67 89           myhtml_collection_t* collection = (myhtml_collection_t*)ctx;
68            
69 89 50         if(myhtml_collection_check_size(collection, 1, 1024) == MyHTML_STATUS_OK) {
70 89           collection->list[ collection->length ] = node;
71 89           collection->length++;
72             }
73 89           }
74              
75 0           void modest_finder_callback_found_with_bool(modest_finder_t* finder, myhtml_tree_node_t* node, mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec, void* ctx)
76             {
77 0           bool *is = (bool*)ctx;
78            
79 0 0         if(*is == false)
80 0           *is = true;
81 0           }
82              
83 0           void modest_finder_specificity_inc(mycss_selectors_entry_t* selector, mycss_selectors_specificity_t* spec)
84             {
85 0           switch (selector->type) {
86             case MyCSS_SELECTORS_TYPE_ID:
87 0           spec->a++;
88 0           break;
89            
90             case MyCSS_SELECTORS_TYPE_CLASS:
91             case MyCSS_SELECTORS_TYPE_ATTRIBUTE:
92             case MyCSS_SELECTORS_TYPE_PSEUDO_CLASS_FUNCTION:
93             case MyCSS_SELECTORS_TYPE_PSEUDO_CLASS:
94 0           spec->b++;
95 0           break;
96            
97             case MyCSS_SELECTORS_TYPE_ELEMENT:
98             case MyCSS_SELECTORS_TYPE_PSEUDO_ELEMENT_FUNCTION:
99             case MyCSS_SELECTORS_TYPE_PSEUDO_ELEMENT:
100 0           spec->c++;
101 0           break;
102             default:
103 0           break;
104             }
105 0           }
106              
107 0           modest_finder_t * modest_finder_by_stylesheet(mycss_stylesheet_t *stylesheet, myhtml_collection_t** collection, myhtml_tree_node_t* base_node)
108             {
109 0 0         if(collection == NULL || base_node == NULL || stylesheet == NULL)
    0          
    0          
110 0           return NULL;
111            
112 0           modest_finder_t *finder = modest_finder_create();
113            
114 0 0         if(finder == NULL)
115 0           return NULL;
116            
117 0           mystatus_t status = modest_finder_init(finder);
118            
119 0 0         if(status != MODEST_STATUS_OK) {
120 0           modest_finder_destroy(finder, true);
121 0           return NULL;
122             }
123            
124 0 0         if(*collection == NULL) {
125             mystatus_t status;
126 0           *collection = myhtml_collection_create(4096, &status);
127            
128 0 0         if(status) {
129 0           modest_finder_destroy(finder, true);
130 0           return NULL;
131             }
132             }
133             else
134 0           myhtml_collection_clean(*collection);
135            
136 0           mycss_selectors_list_t *selector_list = stylesheet->sel_list_first;
137            
138 0 0         while(selector_list) {
139 0 0         for(size_t i = 0; i < selector_list->entries_list_length; i++) {
140 0           mycss_selectors_specificity_t spec = selector_list->entries_list[i].specificity;
141            
142 0           modest_finder_node_combinator_begin(finder, base_node, selector_list, selector_list->entries_list[i].entry, &spec, modest_finder_callback_found_with_collection, *collection);
143             }
144            
145 0           selector_list = selector_list->next;
146             }
147            
148 0           return finder;
149             }
150              
151 0           mystatus_t modest_finder_by_selectors_list(modest_finder_t* finder, myhtml_tree_node_t* scope_node,
152             mycss_selectors_list_t* selector_list, myhtml_collection_t** collection)
153             {
154 0 0         if(finder == NULL || selector_list == NULL || scope_node == NULL || collection == NULL)
    0          
    0          
    0          
155 0           return MODEST_STATUS_ERROR;
156            
157 0 0         if(*collection == NULL) {
158             mystatus_t status;
159 0           *collection = myhtml_collection_create(4096, &status);
160            
161 0 0         if(status)
162 0           return MODEST_STATUS_ERROR_MEMORY_ALLOCATION;
163             }
164              
165 0 0         for(size_t i = 0; i < selector_list->entries_list_length; i++) {
166 0           mycss_selectors_specificity_t spec = selector_list->entries_list[i].specificity;
167            
168 0           modest_finder_node_combinator_begin(finder, scope_node, selector_list, selector_list->entries_list[i].entry, &spec,
169             modest_finder_callback_found_with_collection, *collection);
170             }
171            
172 0           return MODEST_STATUS_OK;
173             }
174              
175 0           myhtml_tree_node_t * modest_finder_node_combinator_begin(modest_finder_t* finder, myhtml_tree_node_t* base_node,
176             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
177             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
178             {
179 0 0         if(selector == NULL)
180 0           return NULL;
181            
182            
183 0           myhtml_tree_node_t *node = base_node;
184            
185 0 0         while(node) {
186 0 0         if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT &&
187 0           modest_finder_static_selector_type_map[selector->type](finder, node, selector, spec))
188             {
189 0 0         if(selector->next == NULL) {
190 0 0         if(callback_found)
191 0           callback_found(finder, node, selector_list, selector, spec, ctx);
192             }
193             else {
194 0           myhtml_tree_node_t *find_node = modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, spec, callback_found, ctx);
195              
196 0 0         if(find_node == NULL) {
197 0 0         while(node != base_node && node->next == NULL)
    0          
198 0           node = node->parent;
199            
200 0 0         if(node == base_node)
201 0           break;
202            
203 0           node = node->next;
204 0           continue;
205             }
206             }
207             }
208            
209 0 0         if(node->child)
210 0           node = node->child;
211             else {
212 0 0         while(node != base_node && node->next == NULL)
    0          
213 0           node = node->parent;
214            
215 0 0         if(node == base_node)
216 0           break;
217            
218 0           node = node->next;
219             }
220             }
221              
222 0           return NULL;
223             }
224              
225             /* some */
226 0           myhtml_tree_node_t * modest_finder_node_combinator_undef(modest_finder_t* finder, myhtml_tree_node_t* base_node,
227             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
228             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
229             {
230 0 0         if(selector == NULL)
231 0           return NULL;
232            
233 0           mycss_selectors_specificity_t match_spec = *spec;
234            
235 0 0         if(base_node->tag_id != MyHTML_TAG__TEXT && base_node->tag_id != MyHTML_TAG__COMMENT &&
236 0           modest_finder_static_selector_type_map[selector->type](finder, base_node, selector, &match_spec)) {
237 0 0         if(selector->next == NULL) {
238 0 0         if(callback_found)
239 0           callback_found(finder, base_node, selector_list, selector, &match_spec, ctx);
240             }
241             else {
242 0           modest_finder_static_selector_combinator_map[selector->next->combinator](finder, base_node, selector_list, selector->next, &match_spec, callback_found, ctx);
243             }
244             }
245            
246 0           return base_node;
247             }
248              
249             /* E F or E >> F */
250 120           myhtml_tree_node_t * modest_finder_node_combinator_descendant(modest_finder_t* finder, myhtml_tree_node_t* base_node,
251             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
252             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
253             {
254 120 50         if(selector == NULL)
255 0           return NULL;
256            
257 120           myhtml_tree_node_t *node = base_node->child;
258            
259 2316 50         while(node) {
260 2316           mycss_selectors_specificity_t match_spec = *spec;
261            
262 3419 100         if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT &&
263 1103           modest_finder_static_selector_type_map[selector->type](finder, node, selector, &match_spec))
264             {
265 192 100         if(selector->next == NULL) {
266 180 50         if(callback_found)
267 180           callback_found(finder, node, selector_list, selector, &match_spec, ctx);
268             }
269             else {
270 12           myhtml_tree_node_t *find_node = modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, &match_spec, callback_found, ctx);
271            
272 12 50         if(find_node == NULL) {
273 12 50         while(node != base_node && node->next == NULL)
    50          
274 0           node = node->parent;
275            
276 12 50         if(node == base_node)
277 120           break;
278            
279 12           node = node->next;
280 12           continue;
281             }
282             }
283             }
284            
285 2304 100         if(node->child)
286 584           node = node->child;
287             else {
288 2424 100         while(node != base_node && node->next == NULL)
    100          
289 704           node = node->parent;
290            
291 1720 100         if(node == base_node)
292 120           break;
293            
294 2184           node = node->next;
295             }
296             }
297            
298 120           return NULL;
299             }
300              
301             /* E > F */
302 0           myhtml_tree_node_t * modest_finder_node_combinator_child(modest_finder_t* finder, myhtml_tree_node_t* base_node,
303             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
304             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
305             {
306 0 0         if(selector == NULL)
307 0           return NULL;
308            
309 0           myhtml_tree_node_t *node = base_node->child;
310            
311 0 0         while(node) {
312 0           mycss_selectors_specificity_t match_spec = *spec;
313            
314 0 0         if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT &&
315 0           modest_finder_static_selector_type_map[selector->type](finder, node, selector, &match_spec))
316             {
317 0 0         if(selector->next == NULL) {
318 0 0         if(callback_found)
319 0           callback_found(finder, node, selector_list ,selector, &match_spec, ctx);
320             }
321             else {
322 0           modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, &match_spec, callback_found, ctx);
323             }
324             }
325            
326 0           node = node->next;
327             }
328            
329 0           return base_node;
330             }
331              
332             /* E + F */
333 0           myhtml_tree_node_t * modest_finder_node_combinator_next_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node,
334             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
335             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
336             {
337 0 0         if(selector == NULL)
338 0           return NULL;
339            
340 0           myhtml_tree_node_t *node = base_node->next;
341            
342 0 0         while(node) {
343 0 0         if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT)
    0          
344             {
345 0           mycss_selectors_specificity_t match_spec = *spec;
346            
347 0 0         if(modest_finder_static_selector_type_map[selector->type](finder, node, selector, &match_spec)) {
348 0 0         if(selector->next == NULL) {
349 0 0         if(callback_found)
350 0           callback_found(finder, node, selector_list, selector, &match_spec, ctx);
351             }
352             else {
353 0           modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, &match_spec, callback_found, ctx);
354             }
355             }
356            
357 0           break;
358             }
359            
360 0           node = node->next;
361             }
362            
363 0           return base_node;
364             }
365              
366             /* E ~ F */
367 0           myhtml_tree_node_t * modest_finder_node_combinator_following_sibling(modest_finder_t* finder, myhtml_tree_node_t* base_node,
368             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
369             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
370             {
371 0 0         if(selector == NULL)
372 0           return NULL;
373            
374 0           myhtml_tree_node_t *node = base_node->next;
375            
376 0 0         while(node) {
377 0           mycss_selectors_specificity_t match_spec = *spec;
378            
379 0 0         if(node->tag_id != MyHTML_TAG__TEXT && node->tag_id != MyHTML_TAG__COMMENT &&
380 0           modest_finder_static_selector_type_map[selector->type](finder, node, selector, &match_spec))
381             {
382 0 0         if(selector->next == NULL) {
383 0 0         if(callback_found)
384 0           callback_found(finder, node, selector_list, selector, &match_spec, ctx);
385             }
386             else {
387 0           modest_finder_static_selector_combinator_map[selector->next->combinator](finder, node, selector_list, selector->next, &match_spec, callback_found, ctx);
388             }
389             }
390            
391 0           node = node->next;
392             }
393            
394 0           return base_node;
395             }
396              
397             /* E || F */
398 0           myhtml_tree_node_t * modest_finder_node_combinator_column(modest_finder_t* finder, myhtml_tree_node_t* base_node,
399             mycss_selectors_list_t* selector_list, mycss_selectors_entry_t* selector,
400             mycss_selectors_specificity_t* spec, modest_finder_callback_f callback_found, void* ctx)
401             {
402 0 0         if(selector == NULL)
403 0           return NULL;
404            
405 0           return base_node;
406             }
407              
408