File Coverage

third_party/modest/source/mycss/an_plus_b.c
Criterion Covered Total %
statement 57 235 24.2
branch 12 92 13.0
condition n/a
subroutine n/a
pod n/a
total 69 327 21.1


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 "mycss/an_plus_b.h"
22             #include "mycore/utils/resources.h"
23              
24 74           mycss_an_plus_b_t * mycss_an_plus_b_create(void)
25             {
26 74           return (mycss_an_plus_b_t*)mycore_calloc(1, sizeof(mycss_an_plus_b_t));
27             }
28              
29 74           mystatus_t mycss_an_plus_b_init(mycss_entry_t* entry, mycss_an_plus_b_t* anb)
30             {
31 74           return MyCSS_STATUS_OK;
32             }
33              
34 0           mystatus_t mycss_an_plus_b_clean_all(mycss_an_plus_b_t* anb)
35             {
36 0           return MyCSS_STATUS_OK;
37             }
38              
39 74           mycss_an_plus_b_t * mycss_an_plus_b_destroy(mycss_an_plus_b_t* anb, bool self_destroy)
40             {
41 74 50         if(anb == NULL)
42 0           return NULL;
43            
44 74 50         if(self_destroy) {
45 74           mycore_free(anb);
46 74           return NULL;
47             }
48            
49 0           return anb;
50             }
51              
52             /////////////////////////////////////////////////////////
53             //// An+B Entry
54             ////
55             /////////////////////////////////////////////////////////
56 1           mycss_an_plus_b_entry_t * mycss_an_plus_b_entry_create(mycss_entry_t* entry)
57             {
58 1           return (mycss_an_plus_b_entry_t*)mchar_async_malloc(entry->mchar,
59             entry->mchar_value_node_id,
60             sizeof(mycss_an_plus_b_entry_t));
61             }
62              
63 1           void mycss_an_plus_b_entry_clean_all(mycss_an_plus_b_entry_t* anb_entry)
64             {
65 1           memset(anb_entry, 0, sizeof(mycss_an_plus_b_entry_t));
66 1           }
67              
68 0           mycss_an_plus_b_entry_t * mycss_an_plus_b_entry_destroy(mycss_entry_t* entry, mycss_an_plus_b_entry_t* anb_entry, bool self_destroy)
69             {
70 0 0         if(anb_entry == NULL)
71 0           return NULL;
72            
73 0 0         if(self_destroy) {
74 0           mchar_async_free(entry->mchar, entry->mchar_value_node_id, (char*)anb_entry);
75 0           return NULL;
76             }
77            
78 0           return anb_entry;
79             }
80              
81             /////////////////////////////////////////////////////////
82             //// An+B Parser
83             ////
84             /////////////////////////////////////////////////////////
85 0           void mycss_an_plus_b_parser_expectations_error(mycss_entry_t* entry)
86             {
87 0           mycss_an_plus_b_current_entry(entry)->is_broken = true;
88 0           }
89              
90             /////////////////////////////////////////////////////////
91             //// An+B Serialization
92             ////
93             /////////////////////////////////////////////////////////
94 1           void mycss_an_plus_b_serialization(mycss_an_plus_b_entry_t* anb_entry, mycore_callback_serialize_f callback, void* context)
95             {
96             char data[512];
97            
98 1 50         if(anb_entry->a != 0) {
99 1           int len = snprintf(data, 512, "%ld", anb_entry->a);
100            
101 1 50         if(len > 0)
102 1           callback(data, (size_t)len, context);
103             }
104            
105 1           callback("n", 1, context);
106            
107 1 50         if(anb_entry->b != 0) {
108 1 50         if(anb_entry->b >= 0)
109 1           callback("+", 1, context);
110            
111 1           int len = snprintf(data, 512, "%ld", anb_entry->b);
112            
113 1 50         if(len > 0)
114 1           callback(data, (size_t)len, context);
115             }
116 1           }
117              
118             /////////////////////////////////////////////////////////
119             //// An+B State
120             ////
121             /////////////////////////////////////////////////////////
122 1           bool mycss_an_plus_b_state_anb_begin(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
123             {
124 1           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_entry_create(entry);
125 1           mycss_an_plus_b_entry_clean_all(anb_entry);
126            
127 1           *entry->anb->entry = anb_entry;
128            
129 1           return mycss_an_plus_b_state_anb(entry, token, true);
130             }
131              
132 1           bool mycss_an_plus_b_state_anb(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
133             {
134 1           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_current_entry(entry);
135            
136 1           switch (token->type) {
137             case MyCSS_TOKEN_TYPE_WHITESPACE:
138 0           break;
139             case MyCSS_TOKEN_TYPE_IDENT: {
140             mycore_string_t str;
141 0           mycss_token_data_to_string(entry, token, &str, true, false);
142            
143 0 0         if(mycore_strncasecmp(str.data, "-n-", 3) == 0)
144             {
145 0           anb_entry->a = -1;
146            
147 0 0         if(str.length == 3) {
148 0           anb_entry->b = -1;
149            
150 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_hyphen;
151            
152 0           mycore_string_destroy(&str, false);
153 0           return true;
154             }
155             /* -n-* */
156 0           size_t len = str.length - 2;
157 0 0         if(mycss_convert_data_to_integer(&str.data[2], len, &anb_entry->b) != len) {
158             /* parse error */
159 0           anb_entry->is_broken = true;
160             }
161            
162             MyCORE_DEBUG("mycss_an_plus_b_state_anb_hyphen_n_hyphen_asterisk_end");
163 0           entry->parser = entry->parser_switch;
164             }
165 0 0         else if(mycore_strncasecmp(str.data, "-n", 2) == 0) {
166             MyCORE_DEBUG("mycss_an_plus_b_state_anb_hyphen_n_end");
167            
168 0           anb_entry->a = -1;
169            
170 0 0         if(str.length == 2) {
171 0           entry->parser = mycss_an_plus_b_state_anb_plus_n;
172            
173 0           mycore_string_destroy(&str, false);
174 0           return true;
175             }
176            
177 0           size_t len = str.length - 2;
178 0 0         if(mycss_convert_data_to_integer(&str.data[2], len, &anb_entry->b) != len) {
179             /* parse error */
180 0           anb_entry->is_broken = true;
181             }
182            
183 0           entry->parser = entry->parser_switch;
184             }
185 0 0         else if(mycore_strncasecmp(str.data, "n-", 2) == 0)
186             {
187 0           anb_entry->a = 1;
188            
189 0 0         if(str.length == 2) {
190 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_hyphen;
191            
192 0           mycore_string_destroy(&str, false);
193 0           return true;
194             }
195            
196 0           size_t len = str.length - 1;
197 0 0         if(mycss_convert_data_to_integer(&str.data[1], len, &anb_entry->b) != len) {
198             /* parse error */
199 0           anb_entry->is_broken = true;
200             }
201            
202             MyCORE_DEBUG("mycss_an_plus_b_state_anb_n");
203 0           entry->parser = entry->parser_switch;
204             }
205 0 0         else if(mycore_strncasecmp(str.data, "n", 1) == 0)
206             {
207 0           anb_entry->a = 1;
208            
209 0 0         if(str.length == 1) {
210 0           entry->parser = mycss_an_plus_b_state_anb_plus_n;
211            
212 0           mycore_string_destroy(&str, false);
213 0           return true;
214             }
215            
216 0           size_t len = str.length - 1;
217 0 0         if(mycss_convert_data_to_integer(&str.data[1], len, &anb_entry->b) != len) {
218             /* parse error */
219 0           anb_entry->is_broken = true;
220             }
221            
222             MyCORE_DEBUG("mycss_an_plus_b_state_anb_n");
223 0           entry->parser = entry->parser_switch;
224             }
225 0 0         else if(mycore_strcasecmp(str.data, "even") == 0) {
226 0           anb_entry->a = 2;
227 0           anb_entry->b = 0;
228            
229             MyCORE_DEBUG("mycss_an_plus_b_state_anb_e_v_e_n");
230 0           entry->parser = entry->parser_switch;
231             }
232 0 0         else if(mycore_strcasecmp(str.data, "odd") == 0) {
233 0           anb_entry->a = 2;
234 0           anb_entry->b = 1;
235            
236             MyCORE_DEBUG("mycss_an_plus_b_state_anb_o_d_d");
237 0           entry->parser = entry->parser_switch;
238             }
239             else {
240 0           mycore_string_destroy(&str, false);
241            
242 0           mycss_an_plus_b_parser_expectations_error(entry);
243 0           entry->parser = entry->parser_switch;
244 0           return false;
245             }
246            
247 0           mycore_string_destroy(&str, false);
248 0           break;
249             }
250             case MyCSS_TOKEN_TYPE_DELIM: {
251 0 0         if(*token->data == '+') {
252 0           anb_entry->a = 1;
253            
254 0           entry->parser = mycss_an_plus_b_state_anb_plus;
255             }
256             else {
257 0           mycss_an_plus_b_parser_expectations_error(entry);
258 0           entry->parser = entry->parser_switch;
259 0           return false;
260             }
261 0           break;
262             }
263             case MyCSS_TOKEN_TYPE_NUMBER: {
264             mycore_string_t str;
265 0           mycss_token_data_to_string(entry, token, &str, true, false);
266            
267 0           mycss_convert_data_to_integer(str.data, str.length, &anb_entry->b);
268            
269 0           mycore_string_destroy(&str, false);
270            
271             MyCORE_DEBUG("mycss_an_plus_b_state_anb_number");
272 0           entry->parser = entry->parser_switch;
273 0           break;
274             }
275             case MyCSS_TOKEN_TYPE_DIMENSION: {
276             mycore_string_t str;
277 1           mycss_token_data_to_string(entry, token, &str, true, false);
278            
279 1           size_t consumed_len = mycss_convert_data_to_integer(str.data, str.length, &anb_entry->a);
280            
281 1 50         if(mycore_strncasecmp(&str.data[consumed_len], "n-", 2) == 0)
282             {
283 0           size_t rem = str.length - consumed_len;
284            
285 0 0         if(rem == 2) {
286 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_hyphen;
287            
288 0           mycore_string_destroy(&str, false);
289 1           return true;
290             }
291            
292 0           rem -= 1;
293 0 0         if(mycss_convert_data_to_integer(&str.data[(consumed_len + 1)], rem, &anb_entry->b) != rem) {
294             /* parse error */
295 0           anb_entry->is_broken = true;
296             }
297            
298             MyCORE_DEBUG("mycss_an_plus_b_state_anb_n_hyphen_asterisk_end");
299 0           entry->parser = entry->parser_switch;
300             }
301 1 50         else if(mycore_strncasecmp(&str.data[consumed_len], "n", 1) == 0)
302             {
303 1           size_t rem = (str.length - consumed_len) - 1;
304            
305 1 50         if(rem == 0) {
306 1           entry->parser = mycss_an_plus_b_state_anb_plus_n;
307            
308 1           mycore_string_destroy(&str, false);
309 1           return true;
310             }
311            
312 0 0         if(mycss_convert_data_to_integer(&str.data[(consumed_len + 1)], rem, &anb_entry->b) != rem) {
313             /* parse error */
314 0           anb_entry->is_broken = true;
315             }
316            
317             MyCORE_DEBUG("mycss_an_plus_b_state_anb_n_end");
318 0           entry->parser = entry->parser_switch;
319             }
320             else {
321 0           mycore_string_destroy(&str, false);
322            
323 0           mycss_an_plus_b_parser_expectations_error(entry);
324 0           entry->parser = entry->parser_switch;
325 0           return false;
326             }
327            
328 0           mycore_string_destroy(&str, false);
329 0           break;
330             }
331             default: {
332 0           mycss_an_plus_b_parser_expectations_error(entry);
333 0           entry->parser = entry->parser_switch;
334 0           return false;
335             }
336             }
337            
338 0           return true;
339             }
340              
341 0           bool mycss_an_plus_b_state_anb_plus(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
342             {
343 0           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_current_entry(entry);
344            
345 0 0         switch (token->type) {
346             case MyCSS_TOKEN_TYPE_IDENT: {
347             mycore_string_t str;
348 0           mycss_token_data_to_string(entry, token, &str, true, false);
349            
350 0 0         if(mycore_strncasecmp(str.data, "n-", 2) == 0)
351             {
352 0 0         if(str.length == 2) {
353 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_hyphen;
354            
355 0           mycore_string_destroy(&str, false);
356 0           return true;
357             }
358            
359 0           size_t len = str.length - 1;
360 0 0         if(mycss_convert_data_to_integer(&str.data[1], len, &anb_entry->b) != len) {
361             /* parse error */
362 0           anb_entry->is_broken = true;
363             }
364            
365             MyCORE_DEBUG("mycss_an_plus_b_state_anb_plus_n_hyphen_asterisk_end");
366 0           entry->parser = entry->parser_switch;
367             }
368 0 0         else if(mycore_strncasecmp(str.data, "n", 1) == 0) {
369             MyCORE_DEBUG("mycss_an_plus_b_state_anb_plus_n");
370 0           entry->parser = mycss_an_plus_b_state_anb_plus_n;
371             }
372             else {
373 0           mycore_string_destroy(&str, false);
374            
375 0           mycss_an_plus_b_parser_expectations_error(entry);
376 0           entry->parser = entry->parser_switch;
377 0           return false;
378             }
379            
380 0           mycore_string_destroy(&str, false);
381 0           break;
382             }
383             default: {
384 0           mycss_an_plus_b_parser_expectations_error(entry);
385 0           entry->parser = entry->parser_switch;
386 0           return false;
387             }
388             }
389            
390 0           return true;
391             }
392              
393 0           bool mycss_an_plus_b_state_anb_plus_n_hyphen(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
394             {
395 0 0         if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
396 0           return true;
397            
398 0           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_current_entry(entry);
399            
400 0 0         if(token->type == MyCSS_TOKEN_TYPE_NUMBER) {
401             /* begin from 0-9 */
402 0 0         if(mycore_string_chars_num_map[ (const unsigned char)(*token->data) ] != 0xff)
403             {
404             mycore_string_t str;
405 0           mycss_token_data_to_string(entry, token, &str, true, false);
406            
407             long res;
408 0           mycss_convert_data_to_integer(str.data, str.length, &res);
409            
410 0           anb_entry->b = -res;
411            
412             MyCORE_DEBUG("mycss_an_plus_b_state_anb_plus_n_hyphen_zero_hyphen_nine_end");
413 0           entry->parser = entry->parser_switch;
414            
415 0           mycore_string_destroy(&str, false);
416             }
417             else {
418 0           mycss_an_plus_b_parser_expectations_error(entry);
419 0           entry->parser = entry->parser_switch;
420 0           return false;
421             }
422             }
423             else {
424 0           mycss_an_plus_b_parser_expectations_error(entry);
425 0           entry->parser = entry->parser_switch;
426 0           return false;
427             }
428            
429 0           return true;
430             }
431              
432 1           bool mycss_an_plus_b_state_anb_plus_n(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
433             {
434 1 50         if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
435 0           return true;
436            
437 1           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_current_entry(entry);
438            
439 1           switch (token->type) {
440             case MyCSS_TOKEN_TYPE_DELIM: {
441 0 0         if(*token->data == '+') {
442 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_plus;
443             }
444 0 0         else if(*token->data == '-') {
445 0           entry->parser = mycss_an_plus_b_state_anb_plus_n_hyphen;
446             }
447             else {
448 0           mycss_an_plus_b_parser_expectations_error(entry);
449 0           entry->parser = entry->parser_switch;
450 0           return false;
451             }
452 0           break;
453             }
454             case MyCSS_TOKEN_TYPE_NUMBER: {
455 1 50         if(*token->data == '+' || *token->data == '-')
    0          
456 1           {
457             mycore_string_t str;
458 1           mycss_token_data_to_string(entry, token, &str, true, false);
459            
460 1           mycss_convert_data_to_integer(str.data, str.length, &anb_entry->b);
461            
462             MyCORE_DEBUG("mycss_an_plus_b_state_anb_plus_n_begin_plus_vertical_bar_hyphen");
463 1           entry->parser = entry->parser_switch;
464            
465 1           mycore_string_destroy(&str, false);
466             }
467             else {
468 0           mycss_an_plus_b_parser_expectations_error(entry);
469 0           entry->parser = entry->parser_switch;
470 0           return false;
471             }
472 1           break;
473             }
474             default: {
475 0           entry->parser = entry->parser_switch;
476 0           return false;
477             }
478             }
479            
480 1           return true;
481             }
482              
483 0           bool mycss_an_plus_b_state_anb_plus_n_plus(mycss_entry_t* entry, mycss_token_t* token, bool last_response)
484             {
485 0 0         if(token->type == MyCSS_TOKEN_TYPE_WHITESPACE)
486 0           return true;
487            
488 0           mycss_an_plus_b_entry_t *anb_entry = mycss_an_plus_b_current_entry(entry);
489            
490 0 0         if(token->type == MyCSS_TOKEN_TYPE_NUMBER) {
491             /* begin from 0-9 */
492 0 0         if(mycore_string_chars_num_map[ (const unsigned char)(*token->data) ] != 0xff)
493             {
494             mycore_string_t str;
495 0           mycss_token_data_to_string(entry, token, &str, true, false);
496            
497 0           mycss_convert_data_to_integer(str.data, str.length, &anb_entry->b);
498            
499             MyCORE_DEBUG("mycss_an_plus_b_state_anb_plus_n_plus_zero_hyphen_nine_end");
500 0           entry->parser = entry->parser_switch;
501            
502 0           mycore_string_destroy(&str, false);
503             }
504             else {
505 0           mycss_an_plus_b_parser_expectations_error(entry);
506 0           entry->parser = entry->parser_switch;
507 0           return false;
508             }
509             }
510             else {
511 0           mycss_an_plus_b_parser_expectations_error(entry);
512 0           entry->parser = entry->parser_switch;
513 0           return false;
514             }
515            
516 0           return true;
517             }
518              
519              
520