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/check.h"
22 #include "mycss/tokenizer_resource.h"
23 
24 #define MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED          \
25     if(css_offset >= buffer->size) {                        \
26         buffer = buffer->next;                              \
27         css_offset = 0;                                     \
28     }
29 
30 /////////////////////////////////////////////////////////
31 //// For chunk
32 ////
33 /////////////////////////////////////////////////////////
mycss_check_two_code_points_valid_escape_chunk(mycss_entry_t * entry,size_t css_offset)34 bool mycss_check_two_code_points_valid_escape_chunk(mycss_entry_t* entry, size_t css_offset)
35 {
36     mycore_incoming_buffer_t* buffer = entry->current_buffer;
37 
38     MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
39 
40     if(buffer->data[css_offset] == '\\') {
41         ++css_offset;
42 
43         MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
44 
45         if(buffer->data[css_offset] != '\n')
46             return true;
47     }
48 
49     return false;
50 }
51 
mycss_check_three_code_points_would_start_identifier_chunk(mycss_entry_t * entry,size_t css_offset)52 bool mycss_check_three_code_points_would_start_identifier_chunk(mycss_entry_t* entry, size_t css_offset)
53 {
54     mycore_incoming_buffer_t* buffer = entry->current_buffer;
55 
56     MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
57     const unsigned char *u_css = (const unsigned char*)buffer->data;
58 
59     if(buffer->data[css_offset] == '-')
60     {
61         ++css_offset;
62 
63         MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
64         u_css = (const unsigned char*)buffer->data;
65 
66         if(buffer->data[css_offset] == '-' ||
67            mycss_begin_chars_state_map[ u_css[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT ||
68            mycss_check_two_code_points_valid_escape_chunk(entry, css_offset))
69         {
70             return true;
71         }
72     }
73     else if(mycss_begin_chars_state_map[ u_css[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
74         return true;
75     }
76     else if(buffer->data[css_offset] == '\\' && mycss_check_two_code_points_valid_escape_chunk(entry, css_offset)) {
77         return true;
78     }
79 
80     return false;
81 }
82 
mycss_check_three_code_points_would_start_number_chunk(mycss_entry_t * entry,size_t css_offset)83 bool mycss_check_three_code_points_would_start_number_chunk(mycss_entry_t* entry, size_t css_offset)
84 {
85     mycore_incoming_buffer_t* buffer = entry->current_buffer;
86 
87     MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
88 
89     if(buffer->data[css_offset] == '-' || buffer->data[css_offset] == '+')
90     {
91         ++css_offset;
92 
93         MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
94 
95         if(buffer->data[css_offset] >= '0' && buffer->data[css_offset] <= '9')
96             return true;
97 
98         if(buffer->data[css_offset] == '.') {
99             ++css_offset;
100 
101             MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
102 
103             if(buffer->data[css_offset] >= '0' && buffer->data[css_offset] <= '9')
104                 return true;
105         }
106     }
107     else if(buffer->data[css_offset] == '.') {
108         ++css_offset;
109 
110         MyCSS_CHECK_CHUNK_POSITION_AND_SET_IF_NEED
111 
112         if(buffer->data[css_offset] >= '0' && buffer->data[css_offset] <= '9')
113             return true;
114     }
115     else if(buffer->data[css_offset] >= '0' && buffer->data[css_offset] <= '9')
116         return true;
117 
118     return false;
119 }
120 
121 /////////////////////////////////////////////////////////
122 //// basic checks
123 ////
124 /////////////////////////////////////////////////////////
mycss_check_three_code_points_would_start_identifier(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)125 bool mycss_check_three_code_points_would_start_identifier(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
126 {
127     if(css_offset >= css_size)
128         return mycss_check_three_code_points_would_start_identifier_chunk(entry, css_offset);
129 
130     const unsigned char *u_css = (const unsigned char*)css;
131 
132     if(css[css_offset] == '-')
133     {
134         ++css_offset;
135 
136         if(css[css_offset] == '-' ||
137            mycss_begin_chars_state_map[ u_css[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT ||
138            mycss_check_two_code_points_valid_escape(entry, token, css, css_offset, css_size))
139         {
140             return true;
141         }
142     }
143     else if(mycss_begin_chars_state_map[ u_css[css_offset] ] == MyCSS_TOKENIZER_STATE_NAME_START_CODE_POINT) {
144         return true;
145     }
146     else if(css[css_offset] == '\\' && mycss_check_two_code_points_valid_escape(entry, token, css, css_offset, css_size)) {
147         return true;
148     }
149 
150     return false;
151 }
152 
mycss_check_two_code_points_valid_escape(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)153 bool mycss_check_two_code_points_valid_escape(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
154 {
155     if(css_offset >= css_size)
156         return mycss_check_two_code_points_valid_escape_chunk(entry, css_offset);
157 
158     if(css[css_offset] == '\\' && css[(css_offset + 1)] != '\n')
159         return true;
160 
161     return false;
162 }
163 
mycss_check_three_code_points_would_start_number(mycss_entry_t * entry,mycss_token_t * token,const char * css,size_t css_offset,size_t css_size)164 bool mycss_check_three_code_points_would_start_number(mycss_entry_t* entry, mycss_token_t* token, const char* css, size_t css_offset, size_t css_size)
165 {
166     if(css_offset >= css_size)
167         return mycss_check_three_code_points_would_start_number_chunk(entry, css_offset);
168 
169     if(css[css_offset] == '-' || css[css_offset] == '+')
170     {
171         ++css_offset;
172 
173         if(css[css_offset] >= '0' && css[css_offset] <= '9')
174             return true;
175 
176         if(css[css_offset] == '.') {
177             ++css_offset;
178 
179             if(css[css_offset] >= '0' && css[css_offset] <= '9')
180                 return true;
181         }
182     }
183     else if(css[css_offset] == '.') {
184         ++css_offset;
185 
186         if(css[css_offset] >= '0' && css[css_offset] <= '9')
187             return true;
188     }
189     else if(css[css_offset] >= '0' && css[css_offset] <= '9')
190         return true;
191 
192     return false;
193 }
194 
195 
196