GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/tokpar.c
Date: 2024-11-05 17:11:09
Exec Total Coverage
Lines: 246 271 90.8%
Functions: 13 13 100.0%
Branches: 205 287 71.4%

Line Branch Exec Source
1 /*
2 Copyright 2019, 2021, 2022 Joel Svensson svenssonjoel@yahoo.se
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program 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
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdbool.h>
19 #include <ctype.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "lbm_memory.h"
24 #include "lbm_types.h"
25 #include "lbm_channel.h"
26 #include "tokpar.h"
27 #include "symrepr.h"
28 #include "heap.h"
29 #include "env.h"
30
31 // +1 to ensure there is always a zero at last ix
32 char tokpar_sym_str[TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH+1];
33
34 typedef struct {
35 const char *str;
36 uint32_t token;
37 uint32_t len;
38 } matcher;
39
40 /*
41 \#\a -> 7 ; control-g
42 \#\b -> 8 ; backspace, BS
43 \#\t -> 9 ; tab, TAB
44 \#\n -> 10 ; newline
45 \#\v -> 11 ; vertical tab
46 \#\f -> 12 ; formfeed character
47 \#\r -> 13 ; carriage return, RET
48 \#\e -> 27 ; escape character, ESC
49 \#\s -> 32 ; space character, SPC
50 \#\\ -> 92 ; backslash character, \
51 \#\d -> 127 ; delete character, DEL
52 */
53
54 #define NUM_SPECIAL_CHARS 11
55 const char special_chars[NUM_SPECIAL_CHARS][2] =
56 {{'a', '\a'},
57 {'b', '\b'},
58 {'t', '\t'},
59 {'n', '\n'},
60 {'v', '\v'},
61 {'f', '\f'},
62 {'r', '\r'},
63 {'e', 27},
64 {'s', 32},
65 {'\\', '\\'},
66 {'d', 127}};
67
68 #define NUM_FIXED_SIZE_TOKENS 16
69 const matcher fixed_size_tokens[NUM_FIXED_SIZE_TOKENS] = {
70 {"(", TOKOPENPAR, 1},
71 {")", TOKCLOSEPAR, 1},
72 {"[", TOKOPENBRACK, 1},
73 {"]", TOKCLOSEBRACK, 1},
74 {".", TOKDOT, 1},
75 {"_", TOKDONTCARE, 1},
76 {"'", TOKQUOTE, 1},
77 {"`", TOKBACKQUOTE, 1},
78 {",@", TOKCOMMAAT, 2},
79 {",", TOKCOMMA, 1},
80 {"?", TOKMATCHANY, 1},
81 {"{", TOKOPENCURL, 1},
82 {"}", TOKCLOSECURL, 1},
83 {"@const-start", TOKCONSTSTART, 12},
84 {"@const-end", TOKCONSTEND, 10},
85 };
86
87 #define NUM_TYPE_QUALIFIERS 9
88 const matcher type_qual_table[NUM_TYPE_QUALIFIERS] = {
89 {"f64", TOKTYPEF64, 3},
90 {"f32", TOKTYPEF32, 3},
91 {"i64", TOKTYPEI64, 3},
92 {"u64", TOKTYPEU64, 3},
93 {"i32", TOKTYPEI32, 3},
94 {"u32", TOKTYPEU32, 3},
95 {"i" , TOKTYPEI, 1},
96 {"u" , TOKTYPEU, 1},
97 {"b" , TOKTYPEBYTE, 1}
98 };
99
100 9038513 static int tok_match_fixed_size_tokens(lbm_char_channel_t *chan, const matcher *m, unsigned int start_pos, unsigned int num, uint32_t *res) {
101
102
2/2
✓ Branch 0 taken 100996276 times.
✓ Branch 1 taken 3346335 times.
104342611 for (unsigned int i = 0; i < num; i ++) {
103 100996276 uint32_t tok_len = m[i].len;
104 100996276 const char *match_str = m[i].str;
105 100996276 uint32_t tok = m[i].token;
106 char c;
107 int char_pos;
108 int r;
109
2/2
✓ Branch 0 taken 96809712 times.
✓ Branch 1 taken 5692178 times.
102501890 for (char_pos = 0; char_pos < (int)tok_len; char_pos ++) {
110 96809712 r = lbm_channel_peek(chan,(unsigned int)char_pos + start_pos, &c);
111
2/2
✓ Branch 0 taken 96809152 times.
✓ Branch 1 taken 560 times.
96809712 if (r == CHANNEL_SUCCESS) {
112
2/2
✓ Branch 0 taken 95303538 times.
✓ Branch 1 taken 1505614 times.
96809152 if (c != match_str[char_pos]) break;
113
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
560 } else if (r == CHANNEL_MORE ) {
114 5692178 return TOKENIZER_NEED_MORE;
115 } else {
116 560 break;
117 }
118 }
119
120
2/2
✓ Branch 0 taken 5692178 times.
✓ Branch 1 taken 95304098 times.
100996276 if (char_pos == (int)tok_len) { //match
121 5692178 *res = tok;
122 5692178 return (int)tok_len;
123 }
124 }
125 3346335 return TOKENIZER_NO_TOKEN;
126 }
127
128 5665130 int tok_syntax(lbm_char_channel_t *chan, uint32_t *res) {
129 5665130 return tok_match_fixed_size_tokens(chan, fixed_size_tokens, 0, NUM_FIXED_SIZE_TOKENS, res);
130 }
131
132 3417953 static bool alpha_char(char c) {
133
6/6
✓ Branch 0 taken 2298427 times.
✓ Branch 1 taken 1119526 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 2298371 times.
✓ Branch 4 taken 6776 times.
✓ Branch 5 taken 1112806 times.
3424729 return ((c >= 'a' && c <= 'z') ||
134
2/2
✓ Branch 0 taken 1092 times.
✓ Branch 1 taken 5684 times.
6776 (c >= 'A' && c <= 'Z'));
135 }
136
137 1063554 static bool num_char(char c) {
138
4/4
✓ Branch 0 taken 124209 times.
✓ Branch 1 taken 939345 times.
✓ Branch 2 taken 117321 times.
✓ Branch 3 taken 6888 times.
1063554 return (c >= '0' && c <= '9');
139 }
140
141 882677 static bool symchar0(char c) {
142 882677 const char *allowed = "+-*/=<>#!";
143
144
2/2
✓ Branch 1 taken 827741 times.
✓ Branch 2 taken 54936 times.
882677 if (alpha_char(c)) return true;
145 54936 int i = 0;
146
2/2
✓ Branch 0 taken 171780 times.
✓ Branch 1 taken 168 times.
171948 while (allowed[i] != 0) {
147
2/2
✓ Branch 0 taken 54768 times.
✓ Branch 1 taken 117012 times.
171780 if (c == allowed[i]) return true;
148 117012 i ++;
149 }
150 168 return false;
151 }
152
153 2535276 static bool symchar(char c) {
154 2535276 const char *allowed = "+-*/=<>!?_";
155
156
4/4
✓ Branch 1 taken 1063554 times.
✓ Branch 2 taken 1471722 times.
✓ Branch 4 taken 117321 times.
✓ Branch 5 taken 946233 times.
2535276 if (alpha_char(c) || num_char(c)) return true;
157 946233 int i = 0;
158
2/2
✓ Branch 0 taken 8908662 times.
✓ Branch 1 taken 870826 times.
9779488 while (allowed[i] != 0) {
159
2/2
✓ Branch 0 taken 75407 times.
✓ Branch 1 taken 8833255 times.
8908662 if (c == allowed[i]) return true;
160 8833255 i++;
161 }
162 870826 return false;
163 }
164
165 882677 int tok_symbol(lbm_char_channel_t *chan) {
166
167 char c;
168 882677 int r = 0;
169
170 882677 r = lbm_channel_peek(chan, 0, &c);
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 882677 times.
882677 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 882677 times.
882677 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
173
3/4
✓ Branch 0 taken 882677 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 168 times.
✓ Branch 4 taken 882509 times.
882677 if (r == CHANNEL_SUCCESS && !symchar0(c)) {
174 168 return TOKENIZER_NO_TOKEN;
175 }
176 882509 memset(tokpar_sym_str,0,TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH+1);
177 882509 tokpar_sym_str[0] = (char)tolower(c);
178
179 882509 int len = 1;
180
181 882509 r = lbm_channel_peek(chan,(unsigned int)len, &c);
182
4/4
✓ Branch 0 taken 2535276 times.
✓ Branch 1 taken 11683 times.
✓ Branch 3 taken 1664450 times.
✓ Branch 4 taken 870826 times.
2546959 while (r == CHANNEL_SUCCESS && symchar(c)) {
183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1664450 times.
1664450 if (len >= 255) return TOKENIZER_SYMBOL_ERROR;
184 1664450 c = (char)tolower(c);
185
1/2
✓ Branch 0 taken 1664450 times.
✗ Branch 1 not taken.
1664450 if (len < TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH) {
186 1664450 tokpar_sym_str[len] = (char)c;
187 }
188 1664450 len ++;
189 1664450 r = lbm_channel_peek(chan,(unsigned int)len, &c);
190 }
191
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 882502 times.
882509 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
192 882502 tokpar_sym_str[len] = 0;
193 882502 return len;
194 }
195
196 224 static char translate_escape_char(char c) {
197
2/7
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 168 times.
✗ Branch 6 not taken.
224 switch(c) {
198 case '\\': return '\\';
199 56 case 'n': return '\n';
200 case 'r': return '\r';
201 case 't': return '\t';
202 case '0': return '\0';
203 168 case '\"': return '\"';
204 default: return '\\';
205 }
206 }
207
208 4261940 int tok_string(lbm_char_channel_t *chan, unsigned int *string_len) {
209
210 4261940 unsigned int n = 0;
211 4261940 unsigned int len = 0;
212 char c;
213 4261940 int r = 0;
214 4261940 bool encode = false;
215
216 4261940 r = lbm_channel_peek(chan,0,&c);
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4261940 times.
4261940 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4261940 times.
4261940 else if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
219
220
2/2
✓ Branch 0 taken 4252560 times.
✓ Branch 1 taken 9380 times.
4261940 if (c != '\"') return TOKENIZER_NO_TOKEN;;
221 9380 n++;
222
223 9380 memset(tokpar_sym_str,0,TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH+1);
224
225 // read string into buffer
226 9380 r = lbm_channel_peek(chan,n,&c);
227
7/10
✓ Branch 0 taken 61936 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9548 times.
✓ Branch 3 taken 52388 times.
✓ Branch 4 taken 9548 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 9380 times.
✓ Branch 8 taken 52556 times.
✗ Branch 9 not taken.
61936 while (r == CHANNEL_SUCCESS && (c != '\"' || (c == '\"' && encode)) &&
228 len < TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH) {
229
3/4
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 52332 times.
✓ Branch 2 taken 224 times.
✗ Branch 3 not taken.
52556 if (c == '\\' && !encode) {
230 224 encode = true;
231 } else {
232
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 52108 times.
52332 tokpar_sym_str[len] = encode ? translate_escape_char(c) : c ;
233 52332 len++;
234 52332 encode = false;
235 }
236 52556 n ++;
237 52556 r = lbm_channel_peek(chan, n, &c);
238 }
239
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9380 times.
9380 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9380 times.
9380 if (c != '\"') return TOKENIZER_STRING_ERROR;
242
243 9380 *string_len = len;
244 9380 n ++;
245 9380 return (int)n;
246 }
247
248 168 int tok_char(lbm_char_channel_t *chan, char *res) {
249
250 char c;
251 int r;
252
253 168 r = lbm_channel_peek(chan, 0, &c);
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
256
257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (c != '\\') return TOKENIZER_NO_TOKEN;
258
259 168 r = lbm_channel_peek(chan, 1, &c);
260
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
262
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (c != '#') return TOKENIZER_NO_TOKEN;
264
265 168 r = lbm_channel_peek(chan, 2, &c);
266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
268
269
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 168 times.
168 if (c == '\\') {
270 r = lbm_channel_peek(chan, 3, &c);
271 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
272 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
273
274 bool ok = false;
275 for (int i = 0; i < NUM_SPECIAL_CHARS; i ++) {
276 if (c == special_chars[i][0]) {
277 *res = special_chars[i][1];
278 ok = true;
279 }
280 }
281 if (ok) {
282 return 4;
283 } else {
284 return TOKENIZER_CHAR_ERROR;
285 }
286 }
287 168 *res = c;
288 168 return 3;
289 }
290
291 4252560 int tok_double(lbm_char_channel_t *chan, token_float *result) {
292
293 4252560 unsigned int n = 0;
294 char fbuf[128];
295 char c;
296 4252560 bool valid_num = false;
297 int res;
298
299 4252560 memset(fbuf, 0, 128);
300
301 4252560 result->type = TOKTYPEF32;
302 4252560 result->negative = false;
303
304 4252560 res = lbm_channel_peek(chan, 0, &c);
305
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4252560 times.
4252560 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
306
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4252560 times.
4252560 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
307
2/2
✓ Branch 0 taken 5488 times.
✓ Branch 1 taken 4247072 times.
4252560 if (c == '-') {
308 5488 n = 1;
309 5488 fbuf[0] = '-';
310 5488 result->negative = true;
311 }
312
313 4252560 res = lbm_channel_peek(chan, n, &c);
314
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4252560 times.
4252560 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
315
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4252560 times.
4252560 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
316
4/4
✓ Branch 0 taken 5148756 times.
✓ Branch 1 taken 3362435 times.
✓ Branch 2 taken 4258687 times.
✓ Branch 3 taken 890069 times.
8511191 while (c >= '0' && c <= '9') {
317 4258687 fbuf[n] = c;
318 4258687 n++;
319 4258687 res = lbm_channel_peek(chan, n, &c);
320
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4258687 times.
4258687 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
321
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 4258631 times.
4258687 if (res == CHANNEL_END) break;
322 }
323
324
2/2
✓ Branch 0 taken 13076 times.
✓ Branch 1 taken 4239484 times.
4252560 if (c == '.') {
325 13076 fbuf[n] = c;
326 13076 n ++;
327 }
328
329 4239484 else return TOKENIZER_NO_TOKEN;
330
331 13076 res = lbm_channel_peek(chan,n, &c);
332
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13076 times.
13076 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13076 times.
13076 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
334
2/4
✓ Branch 0 taken 13076 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13076 times.
13076 if (!(c >= '0' && c <= '9')) return TOKENIZER_NO_TOKEN;
335
336
4/4
✓ Branch 0 taken 23996 times.
✓ Branch 1 taken 7112 times.
✓ Branch 2 taken 18032 times.
✓ Branch 3 taken 5964 times.
31108 while (c >= '0' && c <= '9') {
337 18032 fbuf[n] = c;
338 18032 n++;
339 18032 res = lbm_channel_peek(chan, n, &c);
340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18032 times.
18032 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18032 times.
18032 if (res == CHANNEL_END) break;
342 }
343
344
2/2
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 12964 times.
13076 if (c == 'e') {
345 112 fbuf[n] = c;
346 112 n++;
347 112 res = lbm_channel_peek(chan,n, &c);
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
349
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
350
2/6
✓ Branch 0 taken 112 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
112 if (!((c >= '0' && c <= '9') || c == '-')) return TOKENIZER_NO_TOKEN;
351
352
5/6
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 56 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 112 times.
224 while ((c >= '0' && c <= '9') || c == '-') {
353 112 fbuf[n] = c;
354 112 n++;
355 112 res = lbm_channel_peek(chan, n, &c);
356
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112 times.
112 if (res == CHANNEL_END) break;
358 }
359 }
360
361 uint32_t tok_res;
362 13076 int type_len = tok_match_fixed_size_tokens(chan, type_qual_table, n, NUM_TYPE_QUALIFIERS, &tok_res);
363
364
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13076 times.
13076 if (type_len == TOKENIZER_NEED_MORE) return type_len;
365
2/2
✓ Branch 0 taken 7168 times.
✓ Branch 1 taken 5908 times.
13076 if (type_len == TOKENIZER_NO_TOKEN) {
366 7168 result->type = TOKTYPEF32;
367 } else {
368 5908 result->type = tok_res;
369 }
370
371
3/4
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 12852 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
13076 if ((result->negative && n > 1) ||
372
2/4
✓ Branch 0 taken 12852 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12852 times.
✗ Branch 3 not taken.
13076 (!result->negative && n > 0)) valid_num = true;
373
374
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13076 times.
13076 if (n > 127) {
375 return TOKENIZER_NO_TOKEN;
376 }
377
378
1/2
✓ Branch 0 taken 13076 times.
✗ Branch 1 not taken.
13076 if(valid_num) {
379 13076 result->value = (double)strtod(fbuf,NULL);
380 13076 return (int)n + type_len;
381 }
382 return TOKENIZER_NO_TOKEN;
383 }
384
385 5687047 bool tok_clean_whitespace(lbm_char_channel_t *chan) {
386
387 5687047 bool cleaning_whitespace = true;
388 char c;
389 int r;
390
391
2/2
✓ Branch 0 taken 5692535 times.
✓ Branch 1 taken 5665130 times.
11357665 while (cleaning_whitespace) {
392
393
2/2
✓ Branch 1 taken 6089 times.
✓ Branch 2 taken 5686446 times.
5692535 if (lbm_channel_comment(chan)) {
394 while (true) {
395 662565 r = lbm_channel_peek(chan, 0, &c);
396
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 662565 times.
662565 if (r == CHANNEL_END) {
397 lbm_channel_set_comment(chan, false);
398 cleaning_whitespace = false;
399 break;
400 }
401
2/2
✓ Branch 0 taken 602 times.
✓ Branch 1 taken 661963 times.
662565 if (r == CHANNEL_MORE) {
402 602 return false;
403 }
404 661963 lbm_channel_drop(chan,1);
405
2/2
✓ Branch 0 taken 5487 times.
✓ Branch 1 taken 656476 times.
661963 if (c == '\n') {
406 5487 lbm_channel_set_comment(chan, false);
407 5487 break;
408 }
409 }
410 }
411
412 do {
413 10210359 r = lbm_channel_peek(chan, 0, &c);
414
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 10210344 times.
10210359 if (r == CHANNEL_MORE) {
415 15 return false;
416
2/2
✓ Branch 0 taken 21300 times.
✓ Branch 1 taken 10189044 times.
10210344 } else if (r == CHANNEL_END) {
417 21300 return true;
418 }
419
2/2
✓ Branch 0 taken 5488 times.
✓ Branch 1 taken 10183556 times.
10189044 if (c == ';') {
420 5488 lbm_channel_set_comment(chan, true);
421 5488 break;
422 }
423
2/2
✓ Branch 0 taken 4518426 times.
✓ Branch 1 taken 5665130 times.
10183556 if (isspace(c)) {
424 4518426 lbm_channel_drop(chan,1);
425 } else {
426 5665130 cleaning_whitespace = false;
427 }
428
429
2/2
✓ Branch 0 taken 4518426 times.
✓ Branch 1 taken 5665130 times.
10183556 } while (cleaning_whitespace);
430 }
431 5665130 return true;
432 }
433
434 4239484 int tok_integer(lbm_char_channel_t *chan, token_int *result) {
435 4239484 uint64_t acc = 0;
436 4239484 unsigned int n = 0;
437 4239484 bool valid_num = false;
438 char c;
439 int res;
440
441 4239484 result->type = TOKTYPEI;
442 4239484 result-> negative = false;
443 4239484 res = lbm_channel_peek(chan, 0, &c);
444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4239484 times.
4239484 if (res == CHANNEL_MORE) {
445 return TOKENIZER_NEED_MORE;
446
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4239484 times.
4239484 } else if (res == CHANNEL_END) {
447 return TOKENIZER_NO_TOKEN;
448 }
449
2/2
✓ Branch 0 taken 5264 times.
✓ Branch 1 taken 4234220 times.
4239484 if (c == '-') {
450 5264 n = 1;
451 5264 result->negative = true;
452 }
453
454 4239484 bool hex = false;
455 4239484 res = lbm_channel_peek(chan, n, &c);
456
3/4
✓ Branch 0 taken 4239484 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28391 times.
✓ Branch 3 taken 4211093 times.
4239484 if (res == CHANNEL_SUCCESS && c == '0') {
457 28391 res = lbm_channel_peek(chan, n + 1, &c);
458
4/6
✓ Branch 0 taken 28391 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12655 times.
✓ Branch 3 taken 15736 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 12655 times.
28391 if ( res == CHANNEL_SUCCESS && (c == 'x' || c == 'X')) {
459 15736 hex = true;
460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12655 times.
12655 } else if (res == CHANNEL_MORE) {
461 return TOKENIZER_NEED_MORE;
462 }
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4211093 times.
4211093 } else if (res == CHANNEL_MORE) {
464 return TOKENIZER_NEED_MORE;
465 }
466
467
2/2
✓ Branch 0 taken 15736 times.
✓ Branch 1 taken 4223748 times.
4239484 if (hex) {
468 15736 n += 2;
469
470 15736 res = lbm_channel_peek(chan,n, &c);
471
472
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15736 times.
15736 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15736 times.
15736 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
474
475
4/4
✓ Branch 0 taken 36288 times.
✓ Branch 1 taken 15400 times.
✓ Branch 2 taken 26096 times.
✓ Branch 3 taken 10192 times.
51688 while ((c >= '0' && c <= '9') ||
476
4/4
✓ Branch 0 taken 280 times.
✓ Branch 1 taken 25312 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 252 times.
25592 (c >= 'a' && c <= 'f') ||
477
4/4
✓ Branch 0 taken 10164 times.
✓ Branch 1 taken 15400 times.
✓ Branch 2 taken 9828 times.
✓ Branch 3 taken 336 times.
25564 (c >= 'A' && c <= 'F')) {
478 uint32_t val; /* values between 0 and 16 */
479
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 35924 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
35952 if (c >= 'a' && c <= 'f') {
480 28 val = 10 + (uint32_t)c - 'a';
481
3/4
✓ Branch 0 taken 9828 times.
✓ Branch 1 taken 26096 times.
✓ Branch 2 taken 9828 times.
✗ Branch 3 not taken.
35924 } else if (c >= 'A' && c <= 'F') {
482 9828 val = 10 + (uint32_t)(c - 'A');
483 } else {
484 26096 val = (uint32_t)c - '0';
485 }
486 35952 acc = (acc * 0x10) + val;
487 35952 n++;
488 35952 res = lbm_channel_peek(chan, n, &c);
489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35952 times.
35952 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35952 times.
35952 if (res == CHANNEL_END) break;
491
492 }
493 } else {
494 4223748 res = lbm_channel_peek(chan, n, &c);
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4223748 times.
4223748 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
496
4/4
✓ Branch 0 taken 5103536 times.
✓ Branch 1 taken 3349359 times.
✓ Branch 2 taken 4229203 times.
✓ Branch 3 taken 874333 times.
8452895 while (c >= '0' && c <= '9') {
497 4229203 acc = (acc*10) + (uint32_t)(c - '0');
498 4229203 n++;
499 4229203 res = lbm_channel_peek(chan, n, &c);
500
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4229203 times.
4229203 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
501
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 4229147 times.
4229203 if (res == CHANNEL_END) break;
502 }
503 }
504
505
2/2
✓ Branch 0 taken 879177 times.
✓ Branch 1 taken 3360307 times.
4239484 if (n == 0) return TOKENIZER_NO_TOKEN;
506
507 uint32_t tok_res;
508 3360307 int type_len = tok_match_fixed_size_tokens(chan, type_qual_table, n, NUM_TYPE_QUALIFIERS, &tok_res);
509
510
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3360307 times.
3360307 if (type_len == TOKENIZER_NEED_MORE) return type_len;
511
2/2
✓ Branch 0 taken 21140 times.
✓ Branch 1 taken 3339167 times.
3360307 if (type_len != TOKENIZER_NO_TOKEN) {
512 21140 result->type = tok_res;
513 }
514
515
4/4
✓ Branch 0 taken 5264 times.
✓ Branch 1 taken 3355043 times.
✓ Branch 2 taken 3500 times.
✓ Branch 3 taken 1764 times.
3360307 if ((result->negative && n > 1) ||
516
3/4
✓ Branch 0 taken 3355043 times.
✓ Branch 1 taken 3500 times.
✓ Branch 2 taken 3355043 times.
✗ Branch 3 not taken.
3360307 (!result->negative && n > 0)) valid_num = true;
517
518
2/2
✓ Branch 0 taken 3356807 times.
✓ Branch 1 taken 3500 times.
3360307 if (valid_num) {
519 3356807 result->value = acc;
520 3356807 return (int)n + type_len;
521 }
522 3500 return TOKENIZER_NO_TOKEN;
523 }
524