GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/tokpar.c
Date: 2024-08-06 17:32:21
Exec Total Coverage
Lines: 249 274 90.9%
Functions: 14 14 100.0%
Branches: 206 287 71.8%

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 char tokpar_sym_str[TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH];
32
33 394103 static void clear_sym_str(void) {
34 394103 memset(tokpar_sym_str,0,TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH);
35 394103 }
36
37 typedef struct {
38 const char *str;
39 uint32_t token;
40 uint32_t len;
41 } matcher;
42
43 /*
44 \#\a -> 7 ; control-g
45 \#\b -> 8 ; backspace, BS
46 \#\t -> 9 ; tab, TAB
47 \#\n -> 10 ; newline
48 \#\v -> 11 ; vertical tab
49 \#\f -> 12 ; formfeed character
50 \#\r -> 13 ; carriage return, RET
51 \#\e -> 27 ; escape character, ESC
52 \#\s -> 32 ; space character, SPC
53 \#\\ -> 92 ; backslash character, \
54 \#\d -> 127 ; delete character, DEL
55 */
56
57 #define NUM_SPECIAL_CHARS 11
58 const char special_chars[NUM_SPECIAL_CHARS][2] =
59 {{'a', '\a'},
60 {'b', '\b'},
61 {'t', '\t'},
62 {'n', '\n'},
63 {'v', '\v'},
64 {'f', '\f'},
65 {'r', '\r'},
66 {'e', 27},
67 {'s', 32},
68 {'\\', '\\'},
69 {'d', 127}};
70
71 #define NUM_FIXED_SIZE_TOKENS 16
72 const matcher fixed_size_tokens[NUM_FIXED_SIZE_TOKENS] = {
73 {"(", TOKOPENPAR, 1},
74 {")", TOKCLOSEPAR, 1},
75 {"[", TOKOPENBRACK, 1},
76 {"]", TOKCLOSEBRACK, 1},
77 {".", TOKDOT, 1},
78 {"_", TOKDONTCARE, 1},
79 {"'", TOKQUOTE, 1},
80 {"`", TOKBACKQUOTE, 1},
81 {",@", TOKCOMMAAT, 2},
82 {",", TOKCOMMA, 1},
83 {"?", TOKMATCHANY, 1},
84 {"{", TOKOPENCURL, 1},
85 {"}", TOKCLOSECURL, 1},
86 {"@const-start", TOKCONSTSTART, 12},
87 {"@const-end", TOKCONSTEND, 10},
88 {"@const-symbol-strings", TOKCONSTSYMSTR, 21},
89 };
90
91 #define NUM_TYPE_QUALIFIERS 9
92 const matcher type_qual_table[NUM_TYPE_QUALIFIERS] = {
93 {"f64", TOKTYPEF64, 3},
94 {"f32", TOKTYPEF32, 3},
95 {"i64", TOKTYPEI64, 3},
96 {"u64", TOKTYPEU64, 3},
97 {"i32", TOKTYPEI32, 3},
98 {"u32", TOKTYPEU32, 3},
99 {"i" , TOKTYPEI, 1},
100 {"u" , TOKTYPEU, 1},
101 {"b" , TOKTYPEBYTE, 1}
102 };
103
104 1933825 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) {
105
106
2/2
✓ Branch 0 taken 19532712 times.
✓ Branch 1 taken 1340701 times.
20873413 for (unsigned int i = 0; i < num; i ++) {
107 19532712 uint32_t tok_len = m[i].len;
108 19532712 const char *match_str = m[i].str;
109 19532712 uint32_t tok = m[i].token;
110 char c;
111 int char_pos;
112 int r;
113
2/2
✓ Branch 0 taken 19585436 times.
✓ Branch 1 taken 593124 times.
20178560 for (char_pos = 0; char_pos < (int)tok_len; char_pos ++) {
114 19585436 r = lbm_channel_peek(chan,(unsigned int)char_pos + start_pos, &c);
115
2/2
✓ Branch 0 taken 19584876 times.
✓ Branch 1 taken 560 times.
19585436 if (r == CHANNEL_SUCCESS) {
116
2/2
✓ Branch 0 taken 18939028 times.
✓ Branch 1 taken 645848 times.
19584876 if (c != match_str[char_pos]) break;
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 560 times.
560 } else if (r == CHANNEL_MORE ) {
118 593124 return TOKENIZER_NEED_MORE;
119 } else {
120 560 break;
121 }
122 }
123
124
2/2
✓ Branch 0 taken 593124 times.
✓ Branch 1 taken 18939588 times.
19532712 if (char_pos == (int)tok_len) { //match
125 593124 *res = tok;
126 593124 return (int)tok_len;
127 }
128 }
129 1340701 return TOKENIZER_NO_TOKEN;
130 }
131
132 1453037 int tok_syntax(lbm_char_channel_t *chan, uint32_t *res) {
133 1453037 return tok_match_fixed_size_tokens(chan, fixed_size_tokens, 0, NUM_FIXED_SIZE_TOKENS, res);
134 }
135
136 1809870 static bool alpha_char(char c) {
137
6/6
✓ Branch 0 taken 1289630 times.
✓ Branch 1 taken 520240 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 1289574 times.
✓ Branch 4 taken 1400 times.
✓ Branch 5 taken 518896 times.
1811270 return ((c >= 'a' && c <= 'z') ||
138
2/2
✓ Branch 0 taken 784 times.
✓ Branch 1 taken 616 times.
1400 (c >= 'A' && c <= 'Z'));
139 }
140
141 483336 static bool num_char(char c) {
142
4/4
✓ Branch 0 taken 65884 times.
✓ Branch 1 taken 417452 times.
✓ Branch 2 taken 64708 times.
✓ Branch 3 taken 1176 times.
483336 return (c >= '0' && c <= '9');
143 }
144
145 394243 static bool symchar0(char c) {
146 394243 const char *allowed = "+-*/=<>#!";
147
148
2/2
✓ Branch 1 taken 358067 times.
✓ Branch 2 taken 36176 times.
394243 if (alpha_char(c)) return true;
149 36176 int i = 0;
150
2/2
✓ Branch 0 taken 127932 times.
✓ Branch 1 taken 140 times.
128072 while (allowed[i] != 0) {
151
2/2
✓ Branch 0 taken 36036 times.
✓ Branch 1 taken 91896 times.
127932 if (c == allowed[i]) return true;
152 91896 i ++;
153 }
154 140 return false;
155 }
156
157 1415627 static bool symchar(char c) {
158 1415627 const char *allowed = "+-*/=<>!?_";
159
160
4/4
✓ Branch 1 taken 483336 times.
✓ Branch 2 taken 932291 times.
✓ Branch 4 taken 64708 times.
✓ Branch 5 taken 418628 times.
1415627 if (alpha_char(c) || num_char(c)) return true;
161 418628 int i = 0;
162
2/2
✓ Branch 0 taken 3902108 times.
✓ Branch 1 taken 382424 times.
4284532 while (allowed[i] != 0) {
163
2/2
✓ Branch 0 taken 36204 times.
✓ Branch 1 taken 3865904 times.
3902108 if (c == allowed[i]) return true;
164 3865904 i++;
165 }
166 382424 return false;
167 }
168
169 394243 int tok_symbol(lbm_char_channel_t *chan) {
170
171 char c;
172 394243 int r = 0;
173
174 394243 r = lbm_channel_peek(chan, 0, &c);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394243 times.
394243 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394243 times.
394243 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
177
3/4
✓ Branch 0 taken 394243 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 140 times.
✓ Branch 4 taken 394103 times.
394243 if (r == CHANNEL_SUCCESS && !symchar0(c)) {
178 140 return TOKENIZER_NO_TOKEN;
179 }
180 394103 clear_sym_str();
181 394103 tokpar_sym_str[0] = (char)tolower(c);
182
183 394103 int len = 1;
184
185 394103 r = lbm_channel_peek(chan,(unsigned int)len, &c);
186
4/4
✓ Branch 0 taken 1415627 times.
✓ Branch 1 taken 11679 times.
✓ Branch 3 taken 1033203 times.
✓ Branch 4 taken 382424 times.
1427306 while (r == CHANNEL_SUCCESS && symchar(c)) {
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1033203 times.
1033203 if (len >= 255) return TOKENIZER_SYMBOL_ERROR;
188 1033203 c = (char)tolower(c);
189
1/2
✓ Branch 0 taken 1033203 times.
✗ Branch 1 not taken.
1033203 if (len < TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH) {
190 1033203 tokpar_sym_str[len] = (char)c;
191 }
192 1033203 len ++;
193 1033203 r = lbm_channel_peek(chan,(unsigned int)len, &c);
194 }
195
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 394100 times.
394103 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
196 394100 tokpar_sym_str[len] = 0;
197 394100 return len;
198 }
199
200 224 static char translate_escape_char(char c) {
201
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) {
202 case '\\': return '\\';
203 56 case 'n': return '\n';
204 case 'r': return '\r';
205 case 't': return '\t';
206 case '0': return '\0';
207 168 case '\"': return '\"';
208 default: return '\\';
209 }
210 }
211
212 877189 int tok_string(lbm_char_channel_t *chan, unsigned int *string_len) {
213
214 877189 unsigned int n = 0;
215 877189 unsigned int len = 0;
216 char c;
217 877189 int r = 0;
218 877189 bool encode = false;
219
220 877189 r = lbm_channel_peek(chan,0,&c);
221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 877189 times.
877189 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 877189 times.
877189 else if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
223
224
2/2
✓ Branch 0 taken 872569 times.
✓ Branch 1 taken 4620 times.
877189 if (c != '\"') return TOKENIZER_NO_TOKEN;;
225 4620 n++;
226
227 4620 memset(tokpar_sym_str, 0 , TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH);
228
229 // read string into buffer
230 4620 r = lbm_channel_peek(chan,n,&c);
231
7/10
✓ Branch 0 taken 32872 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4788 times.
✓ Branch 3 taken 28084 times.
✓ Branch 4 taken 4788 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 168 times.
✓ Branch 7 taken 4620 times.
✓ Branch 8 taken 28252 times.
✗ Branch 9 not taken.
32872 while (r == CHANNEL_SUCCESS && (c != '\"' || (c == '\"' && encode)) &&
232 len < TOKENIZER_MAX_SYMBOL_AND_STRING_LENGTH) {
233
3/4
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 28028 times.
✓ Branch 2 taken 224 times.
✗ Branch 3 not taken.
28252 if (c == '\\' && !encode) {
234 224 encode = true;
235 } else {
236
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 27804 times.
28028 tokpar_sym_str[len] = encode ? translate_escape_char(c) : c ;
237 28028 len++;
238 28028 encode = false;
239 }
240 28252 n ++;
241 28252 r = lbm_channel_peek(chan, n, &c);
242 }
243
244
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4620 times.
4620 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4620 times.
4620 if (c != '\"') return TOKENIZER_STRING_ERROR;
246
247 4620 *string_len = len;
248 4620 n ++;
249 4620 return (int)n;
250 }
251
252 140 int tok_char(lbm_char_channel_t *chan, char *res) {
253
254 char c;
255 int r;
256
257 140 r = lbm_channel_peek(chan, 0, &c);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
259
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
260
261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (c != '\\') return TOKENIZER_NO_TOKEN;
262
263 140 r = lbm_channel_peek(chan, 1, &c);
264
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
266
267
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (c != '#') return TOKENIZER_NO_TOKEN;
268
269 140 r = lbm_channel_peek(chan, 2, &c);
270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
272
273
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 140 times.
140 if (c == '\\') {
274 r = lbm_channel_peek(chan, 3, &c);
275 if (r == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
276 if (r == CHANNEL_END) return TOKENIZER_NO_TOKEN;
277
278 bool ok = false;
279 for (int i = 0; i < NUM_SPECIAL_CHARS; i ++) {
280 if (c == special_chars[i][0]) {
281 *res = special_chars[i][1];
282 ok = true;
283 }
284 }
285 if (ok) {
286 return 4;
287 } else {
288 return TOKENIZER_CHAR_ERROR;
289 }
290 }
291 140 *res = c;
292 140 return 3;
293 }
294
295 872569 int tok_double(lbm_char_channel_t *chan, token_float *result) {
296
297 872569 unsigned int n = 0;
298 char fbuf[128];
299 char c;
300 872569 bool valid_num = false;
301 int res;
302
303 872569 memset(fbuf, 0, 128);
304
305 872569 result->type = TOKTYPEF32;
306 872569 result->negative = false;
307
308 872569 res = lbm_channel_peek(chan, 0, &c);
309
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 872569 times.
872569 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 872569 times.
872569 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
311
2/2
✓ Branch 0 taken 3276 times.
✓ Branch 1 taken 869293 times.
872569 if (c == '-') {
312 3276 n = 1;
313 3276 fbuf[0] = '-';
314 3276 result->negative = true;
315 }
316
317 872569 res = lbm_channel_peek(chan, n, &c);
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 872569 times.
872569 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
319
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 872569 times.
872569 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
320
4/4
✓ Branch 0 taken 1468159 times.
✓ Branch 1 taken 464968 times.
✓ Branch 2 taken 1060616 times.
✓ Branch 3 taken 407543 times.
1933127 while (c >= '0' && c <= '9') {
321 1060616 fbuf[n] = c;
322 1060616 n++;
323 1060616 res = lbm_channel_peek(chan, n, &c);
324
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1060614 times.
1060616 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
325
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1060558 times.
1060614 if (res == CHANNEL_END) break;
326 }
327
328
2/2
✓ Branch 0 taken 6916 times.
✓ Branch 1 taken 865651 times.
872567 if (c == '.') {
329 6916 fbuf[n] = c;
330 6916 n ++;
331 }
332
333 865651 else return TOKENIZER_NO_TOKEN;
334
335 6916 res = lbm_channel_peek(chan,n, &c);
336
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6916 times.
6916 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6916 times.
6916 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
338
2/4
✓ Branch 0 taken 6916 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6916 times.
6916 if (!(c >= '0' && c <= '9')) return TOKENIZER_NO_TOKEN;
339
340
4/4
✓ Branch 0 taken 12096 times.
✓ Branch 1 taken 3444 times.
✓ Branch 2 taken 8624 times.
✓ Branch 3 taken 3472 times.
15540 while (c >= '0' && c <= '9') {
341 8624 fbuf[n] = c;
342 8624 n++;
343 8624 res = lbm_channel_peek(chan, n, &c);
344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8624 times.
8624 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8624 times.
8624 if (res == CHANNEL_END) break;
346 }
347
348
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 6832 times.
6916 if (c == 'e') {
349 84 fbuf[n] = c;
350 84 n++;
351 84 res = lbm_channel_peek(chan,n, &c);
352
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
354
2/6
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 84 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
84 if (!((c >= '0' && c <= '9') || c == '-')) return TOKENIZER_NO_TOKEN;
355
356
5/6
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 56 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 84 times.
168 while ((c >= '0' && c <= '9') || c == '-') {
357 84 fbuf[n] = c;
358 84 n++;
359 84 res = lbm_channel_peek(chan, n, &c);
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 if (res == CHANNEL_END) break;
362 }
363 }
364
365 uint32_t tok_res;
366 6916 int type_len = tok_match_fixed_size_tokens(chan, type_qual_table, n, NUM_TYPE_QUALIFIERS, &tok_res);
367
368
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6916 times.
6916 if (type_len == TOKENIZER_NEED_MORE) return type_len;
369
2/2
✓ Branch 0 taken 3472 times.
✓ Branch 1 taken 3444 times.
6916 if (type_len == TOKENIZER_NO_TOKEN) {
370 3472 result->type = TOKTYPEF32;
371 } else {
372 3444 result->type = tok_res;
373 }
374
375
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 6804 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 112 times.
6916 if ((result->negative && n > 1) ||
376
2/4
✓ Branch 0 taken 6804 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6804 times.
✗ Branch 3 not taken.
6916 (!result->negative && n > 0)) valid_num = true;
377
378
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6916 times.
6916 if (n > 127) {
379 return TOKENIZER_NO_TOKEN;
380 }
381
382
1/2
✓ Branch 0 taken 6916 times.
✗ Branch 1 not taken.
6916 if(valid_num) {
383 6916 result->value = (double)strtod(fbuf,NULL);
384 6916 return (int)n + type_len;
385 }
386 return TOKENIZER_NO_TOKEN;
387 }
388
389 1470969 bool tok_clean_whitespace(lbm_char_channel_t *chan) {
390
391 1470969 bool cleaning_whitespace = true;
392 char c;
393 int r;
394
395
2/2
✓ Branch 0 taken 1474973 times.
✓ Branch 1 taken 1453037 times.
2928010 while (cleaning_whitespace) {
396
397
2/2
✓ Branch 1 taken 4645 times.
✓ Branch 2 taken 1470328 times.
1474973 if (lbm_channel_comment(chan)) {
398 while (true) {
399 611983 r = lbm_channel_peek(chan, 0, &c);
400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 611983 times.
611983 if (r == CHANNEL_END) {
401 lbm_channel_set_comment(chan, false);
402 cleaning_whitespace = false;
403 break;
404 }
405
2/2
✓ Branch 0 taken 645 times.
✓ Branch 1 taken 611338 times.
611983 if (r == CHANNEL_MORE) {
406 645 return false;
407 }
408 611338 lbm_channel_drop(chan,1);
409
2/2
✓ Branch 0 taken 4000 times.
✓ Branch 1 taken 607338 times.
611338 if (c == '\n') {
410 4000 lbm_channel_set_comment(chan, false);
411 4000 break;
412 }
413 }
414 }
415
416 do {
417 2781834 r = lbm_channel_peek(chan, 0, &c);
418
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2781813 times.
2781834 if (r == CHANNEL_MORE) {
419 21 return false;
420
2/2
✓ Branch 0 taken 17266 times.
✓ Branch 1 taken 2764547 times.
2781813 } else if (r == CHANNEL_END) {
421 17266 return true;
422 }
423
2/2
✓ Branch 0 taken 4004 times.
✓ Branch 1 taken 2760543 times.
2764547 if (c == ';') {
424 4004 lbm_channel_set_comment(chan, true);
425 4004 break;
426 }
427
2/2
✓ Branch 0 taken 1307506 times.
✓ Branch 1 taken 1453037 times.
2760543 if (isspace(c)) {
428 1307506 lbm_channel_drop(chan,1);
429 } else {
430 1453037 cleaning_whitespace = false;
431 }
432
433
2/2
✓ Branch 0 taken 1307506 times.
✓ Branch 1 taken 1453037 times.
2760543 } while (cleaning_whitespace);
434 }
435 1453037 return true;
436 }
437
438 865651 int tok_integer(lbm_char_channel_t *chan, token_int *result) {
439 865651 uint64_t acc = 0;
440 865651 unsigned int n = 0;
441 865651 bool valid_num = false;
442 char c;
443 int res;
444
445 865651 result->type = TOKTYPEI;
446 865651 result-> negative = false;
447 865651 res = lbm_channel_peek(chan, 0, &c);
448
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 865651 times.
865651 if (res == CHANNEL_MORE) {
449 return TOKENIZER_NEED_MORE;
450
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 865651 times.
865651 } else if (res == CHANNEL_END) {
451 return TOKENIZER_NO_TOKEN;
452 }
453
2/2
✓ Branch 0 taken 3164 times.
✓ Branch 1 taken 862487 times.
865651 if (c == '-') {
454 3164 n = 1;
455 3164 result->negative = true;
456 }
457
458 865651 bool hex = false;
459 865651 res = lbm_channel_peek(chan, n, &c);
460
3/4
✓ Branch 0 taken 865651 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24612 times.
✓ Branch 3 taken 841039 times.
865651 if (res == CHANNEL_SUCCESS && c == '0') {
461 24612 res = lbm_channel_peek(chan, n + 1, &c);
462
4/6
✓ Branch 0 taken 24612 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9240 times.
✓ Branch 3 taken 15372 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9240 times.
24612 if ( res == CHANNEL_SUCCESS && (c == 'x' || c == 'X')) {
463 15372 hex = true;
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9240 times.
9240 } else if (res == CHANNEL_MORE) {
465 return TOKENIZER_NEED_MORE;
466 }
467
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 841039 times.
841039 } else if (res == CHANNEL_MORE) {
468 return TOKENIZER_NEED_MORE;
469 }
470
471
2/2
✓ Branch 0 taken 15372 times.
✓ Branch 1 taken 850279 times.
865651 if (hex) {
472 15372 n += 2;
473
474 15372 res = lbm_channel_peek(chan,n, &c);
475
476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15372 times.
15372 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15372 times.
15372 else if (res == CHANNEL_END) return TOKENIZER_NO_TOKEN;
478
479
4/4
✓ Branch 0 taken 32732 times.
✓ Branch 1 taken 15204 times.
✓ Branch 2 taken 26096 times.
✓ Branch 3 taken 6636 times.
47936 while ((c >= '0' && c <= '9') ||
480
4/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 21728 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 84 times.
21840 (c >= 'a' && c <= 'f') ||
481
4/4
✓ Branch 0 taken 6608 times.
✓ Branch 1 taken 15204 times.
✓ Branch 2 taken 6440 times.
✓ Branch 3 taken 168 times.
21812 (c >= 'A' && c <= 'F')) {
482 uint32_t val; /* values between 0 and 16 */
483
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 32536 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
32564 if (c >= 'a' && c <= 'f') {
484 28 val = 10 + (uint32_t)c - 'a';
485
3/4
✓ Branch 0 taken 6440 times.
✓ Branch 1 taken 26096 times.
✓ Branch 2 taken 6440 times.
✗ Branch 3 not taken.
32536 } else if (c >= 'A' && c <= 'F') {
486 6440 val = 10 + (uint32_t)(c - 'A');
487 } else {
488 26096 val = (uint32_t)c - '0';
489 }
490 32564 acc = (acc * 0x10) + val;
491 32564 n++;
492 32564 res = lbm_channel_peek(chan, n, &c);
493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32564 times.
32564 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
494
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32564 times.
32564 if (res == CHANNEL_END) break;
495
496 }
497 } else {
498 850279 res = lbm_channel_peek(chan, n, &c);
499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 850279 times.
850279 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
500
4/4
✓ Branch 0 taken 1430215 times.
✓ Branch 1 taken 458052 times.
✓ Branch 2 taken 1038044 times.
✓ Branch 3 taken 392171 times.
1888267 while (c >= '0' && c <= '9') {
501 1038044 acc = (acc*10) + (uint32_t)(c - '0');
502 1038044 n++;
503 1038044 res = lbm_channel_peek(chan, n, &c);
504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1038044 times.
1038044 if (res == CHANNEL_MORE) return TOKENIZER_NEED_MORE;
505
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1037988 times.
1038044 if (res == CHANNEL_END) break;
506 }
507 }
508
509
2/2
✓ Branch 0 taken 391779 times.
✓ Branch 1 taken 473872 times.
865651 if (n == 0) return TOKENIZER_NO_TOKEN;
510
511 uint32_t tok_res;
512 473872 int type_len = tok_match_fixed_size_tokens(chan, type_qual_table, n, NUM_TYPE_QUALIFIERS, &tok_res);
513
514
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 473872 times.
473872 if (type_len == TOKENIZER_NEED_MORE) return type_len;
515
2/2
✓ Branch 0 taken 13832 times.
✓ Branch 1 taken 460040 times.
473872 if (type_len != TOKENIZER_NO_TOKEN) {
516 13832 result->type = tok_res;
517 }
518
519
4/4
✓ Branch 0 taken 3164 times.
✓ Branch 1 taken 470708 times.
✓ Branch 2 taken 2464 times.
✓ Branch 3 taken 700 times.
473872 if ((result->negative && n > 1) ||
520
3/4
✓ Branch 0 taken 470708 times.
✓ Branch 1 taken 2464 times.
✓ Branch 2 taken 470708 times.
✗ Branch 3 not taken.
473872 (!result->negative && n > 0)) valid_num = true;
521
522
2/2
✓ Branch 0 taken 471408 times.
✓ Branch 1 taken 2464 times.
473872 if (valid_num) {
523 //lbm_channel_drop(chan,n + drop_type_str);
524 471408 result->value = acc;
525 471408 return (int)n + type_len;
526 }
527 2464 return TOKENIZER_NO_TOKEN;
528 }
529