GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
Copyright 2018, 2020 - 2024 Joel Svensson svenssonjoel@yahoo.se |
||
3 |
2022 Benjamin Vedder |
||
4 |
|||
5 |
This program is free software: you can redistribute it and/or modify |
||
6 |
it under the terms of the GNU General Public License as published by |
||
7 |
the Free Software Foundation, either version 3 of the License, or |
||
8 |
(at your option) any later version. |
||
9 |
|||
10 |
This program is distributed in the hope that it will be useful, |
||
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
13 |
GNU General Public License for more details. |
||
14 |
|||
15 |
You should have received a copy of the GNU General Public License |
||
16 |
along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
17 |
*/ |
||
18 |
|||
19 |
#include <stdio.h> |
||
20 |
#include <string.h> |
||
21 |
#include <ctype.h> |
||
22 |
#include <inttypes.h> |
||
23 |
#include <lbm_types.h> |
||
24 |
#include <lbm_custom_type.h> |
||
25 |
|||
26 |
#include "print.h" |
||
27 |
#include "heap.h" |
||
28 |
#include "symrepr.h" |
||
29 |
#include "stack.h" |
||
30 |
#include "lbm_channel.h" |
||
31 |
|||
32 |
#define PRINT 1 |
||
33 |
#define PRINT_SPACE 2 |
||
34 |
#define START_LIST 3 |
||
35 |
#define CONTINUE_LIST 4 |
||
36 |
#define END_LIST 5 |
||
37 |
#define PRINT_DOT 6 |
||
38 |
#define START_ARRAY 7 |
||
39 |
#define CONTINUE_ARRAY 8 |
||
40 |
#define END_ARRAY 9 |
||
41 |
|||
42 |
static lbm_stack_t print_stack = { NULL, 0, 0}; |
||
43 |
static bool print_has_stack = false; |
||
44 |
|||
45 |
const char *failed_str = "Error: print failed\n"; |
||
46 |
|||
47 |
549179 |
static int push_n(lbm_stack_t *s, lbm_uint *values, lbm_uint n) { |
|
48 |
✓✗ | 549179 |
if (s->sp + n < s->size) { |
49 |
✓✓ | 1655489 |
for (lbm_uint i = 0; i < n; i ++) { |
50 |
1106310 |
s->data[s->sp+i] = values[i]; |
|
51 |
} |
||
52 |
549179 |
s->sp+=n; |
|
53 |
549179 |
return 1; |
|
54 |
} |
||
55 |
return 0; |
||
56 |
} |
||
57 |
|||
58 |
// is_printable_string is turning out to be a headache. |
||
59 |
// What do we want from this function??? |
||
60 |
// |
||
61 |
// Value | Print as | Condition |
||
62 |
// [0] | [0] | |
||
63 |
// [1] | [1] | |
||
64 |
// "" | [0] | (array->size <= 1) => false |
||
65 |
// "hej" | "hej" | printable characters followed by a 0 |
||
66 |
// [65 66 67 0 65 66 67 0] | [65 66 67 0 65 66 67 0] | position of first 0 after printable characters = array->size-1 |
||
67 |
// [0 65 66 0] | [0 65 66 0] | position of first 0 after printable characters = array->size-1 |
||
68 |
5320 |
bool lbm_value_is_printable_string(lbm_value v, char **str) { |
|
69 |
5320 |
bool is_a_string = false; |
|
70 |
5320 |
lbm_array_header_t *array = lbm_dec_array_r(v); |
|
71 |
✓✓ | 5320 |
if (array) { |
72 |
4424 |
char *c_data = (char *)array->data; |
|
73 |
✓✓ | 4424 |
if (array->size > 1) { // nonzero length |
74 |
3920 |
unsigned int i = 0; |
|
75 |
3920 |
is_a_string = true; |
|
76 |
✓✗ | 7140 |
for (i = 0; i < array->size; i ++) { |
77 |
✓✓ | 7140 |
if (c_data[i] == 0) break; |
78 |
✓✓✓✓ ✗✓ |
4676 |
if (!isprint((unsigned char)c_data[i]) && ((c_data[i] < 8) || c_data[i] > 13)) { |
79 |
1456 |
is_a_string = false; |
|
80 |
1456 |
break; |
|
81 |
} |
||
82 |
} |
||
83 |
✓✓✓✓ ✓✗ |
3920 |
if (i > 0 && i != array->size-1 && c_data[i-1] != 0) is_a_string = false; |
84 |
✓✓ | 3920 |
if (array->size-1 > i) is_a_string = false; |
85 |
✓✓ | 3920 |
if (is_a_string) { |
86 |
784 |
*str = (char*)array->data; |
|
87 |
} |
||
88 |
} |
||
89 |
} |
||
90 |
5320 |
return is_a_string; |
|
91 |
} |
||
92 |
|||
93 |
|||
94 |
21588 |
int lbm_print_init(lbm_uint print_stack_size) { |
|
95 |
|||
96 |
✗✓ | 21588 |
if (print_stack_size == 0) |
97 |
return 0; |
||
98 |
|||
99 |
21588 |
lbm_uint *print_stack_storage = (lbm_uint*)lbm_malloc(print_stack_size * sizeof(lbm_uint)); |
|
100 |
✗✓ | 21588 |
if (!print_stack_storage) return 0; |
101 |
|||
102 |
✓✗ | 21588 |
if (lbm_stack_create(&print_stack, print_stack_storage, print_stack_size)) { |
103 |
21588 |
print_has_stack = true; |
|
104 |
21588 |
return 1; |
|
105 |
} |
||
106 |
return 0; |
||
107 |
} |
||
108 |
|||
109 |
#define EMIT_BUFFER_SIZE 30 |
||
110 |
|||
111 |
#define EMIT_FAILED -1 |
||
112 |
#define EMIT_OK 0 |
||
113 |
|||
114 |
683653 |
static int print_emit_string(lbm_char_channel_t *chan, char* str) { |
|
115 |
✓✓ | 683653 |
if (str == NULL) return EMIT_FAILED; |
116 |
✓✓ | 2377374 |
while (*str != 0) { |
117 |
1940433 |
int r = lbm_channel_write(chan, *str); |
|
118 |
1940433 |
str++; |
|
119 |
✓✓ | 1940433 |
if (r != CHANNEL_SUCCESS) return EMIT_FAILED; |
120 |
} |
||
121 |
436941 |
return EMIT_OK; |
|
122 |
} |
||
123 |
|||
124 |
211784 |
static int print_emit_char(lbm_char_channel_t *chan, char c) { |
|
125 |
|||
126 |
211784 |
int r = lbm_channel_write(chan, c); |
|
127 |
✓✓ | 211784 |
if (r != CHANNEL_SUCCESS) return EMIT_FAILED; |
128 |
211696 |
return EMIT_OK; |
|
129 |
} |
||
130 |
|||
131 |
|||
132 |
1596 |
static int emit_escape(lbm_char_channel_t *chan, char c) { |
|
133 |
✗✗✗✗ ✗✓ |
1596 |
switch(c) { |
134 |
case '"': return print_emit_string(chan, "\\\""); |
||
135 |
case '\n': return print_emit_string(chan, "\\n"); |
||
136 |
case '\r': return print_emit_string(chan, "\\r"); |
||
137 |
case '\t': return print_emit_string(chan, "\\t"); |
||
138 |
case '\\': return print_emit_string(chan, "\\\\"); |
||
139 |
1596 |
default: |
|
140 |
1596 |
return print_emit_char(chan, c); |
|
141 |
} |
||
142 |
} |
||
143 |
|||
144 |
532 |
static int print_emit_string_value(lbm_char_channel_t *chan, char* str) { |
|
145 |
✗✓ | 532 |
if (str == NULL) return EMIT_FAILED; |
146 |
✓✓ | 2128 |
while (*str != 0) { |
147 |
1596 |
int r = emit_escape(chan, *str++); |
|
148 |
✗✓ | 1596 |
if (r != EMIT_OK) return r; |
149 |
} |
||
150 |
532 |
return EMIT_OK; |
|
151 |
} |
||
152 |
|||
153 |
259761 |
static int print_emit_symbol(lbm_char_channel_t *chan, lbm_value sym) { |
|
154 |
259761 |
char *str_ptr = (char*)lbm_get_name_by_symbol(lbm_dec_sym(sym)); |
|
155 |
259761 |
return print_emit_string(chan, str_ptr); |
|
156 |
} |
||
157 |
|||
158 |
41246 |
static int print_emit_i(lbm_char_channel_t *chan, lbm_int v) { |
|
159 |
char buf[EMIT_BUFFER_SIZE]; |
||
160 |
41246 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_INT, v); |
|
161 |
41246 |
return print_emit_string(chan, buf); |
|
162 |
} |
||
163 |
|||
164 |
21288 |
static int print_emit_u(lbm_char_channel_t *chan, lbm_uint v, bool ps) { |
|
165 |
char buf[EMIT_BUFFER_SIZE]; |
||
166 |
✓✗ | 21288 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_UINT"%s", v, ps ? "u" : ""); |
167 |
21288 |
return print_emit_string(chan, buf); |
|
168 |
} |
||
169 |
|||
170 |
293678 |
static int print_emit_byte(lbm_char_channel_t *chan, uint8_t v, bool ps) { |
|
171 |
char buf[EMIT_BUFFER_SIZE]; |
||
172 |
✓✓ | 293678 |
snprintf(buf, EMIT_BUFFER_SIZE, "%u%s", v, ps ? "b" : ""); |
173 |
293678 |
return print_emit_string(chan, buf); |
|
174 |
} |
||
175 |
|||
176 |
420 |
static int print_emit_float(lbm_char_channel_t *chan, float v, bool ps) { |
|
177 |
char buf[EMIT_BUFFER_SIZE]; |
||
178 |
✓✗ | 420 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_FLOAT"%s", (double)v, ps ? "f32" : ""); |
179 |
420 |
return print_emit_string(chan, buf); |
|
180 |
} |
||
181 |
|||
182 |
336 |
static int print_emit_double(lbm_char_channel_t *chan, double v, bool ps) { |
|
183 |
char buf[EMIT_BUFFER_SIZE]; |
||
184 |
✓✗ | 336 |
snprintf(buf, EMIT_BUFFER_SIZE, "%lf%s", v, ps ? "f64" : ""); |
185 |
336 |
return print_emit_string(chan, buf); |
|
186 |
} |
||
187 |
|||
188 |
112 |
static int print_emit_u32(lbm_char_channel_t *chan, uint32_t v, bool ps) { |
|
189 |
char buf[EMIT_BUFFER_SIZE]; |
||
190 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRIu32"%s", v, ps ? "u32" : ""); |
191 |
112 |
return print_emit_string(chan, buf); |
|
192 |
} |
||
193 |
|||
194 |
112 |
static int print_emit_i32(lbm_char_channel_t *chan, int32_t v, bool ps) { |
|
195 |
char buf[EMIT_BUFFER_SIZE]; |
||
196 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRId32"%s", v, ps ? "i32" : ""); |
197 |
112 |
return print_emit_string(chan, buf); |
|
198 |
} |
||
199 |
|||
200 |
112 |
static int print_emit_u64(lbm_char_channel_t *chan, uint64_t v, bool ps) { |
|
201 |
char buf[EMIT_BUFFER_SIZE]; |
||
202 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRIu64"%s", v, ps ? "u64" : ""); |
203 |
112 |
return print_emit_string(chan, buf); |
|
204 |
} |
||
205 |
|||
206 |
112 |
static int print_emit_i64(lbm_char_channel_t *chan, int64_t v, bool ps) { |
|
207 |
char buf[EMIT_BUFFER_SIZE]; |
||
208 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRId64"%s", v, ps ? "i64" : ""); |
209 |
112 |
return print_emit_string(chan, buf); |
|
210 |
} |
||
211 |
|||
212 |
50532 |
static int print_emit_continuation(lbm_char_channel_t *chan, lbm_value v) { |
|
213 |
char buf[EMIT_BUFFER_SIZE]; |
||
214 |
50532 |
lbm_uint cont = (v & ~LBM_CONTINUATION_INTERNAL) >> LBM_ADDRESS_SHIFT; |
|
215 |
50532 |
snprintf(buf, EMIT_BUFFER_SIZE, "CONT[" "%"PRI_UINT"]", cont); |
|
216 |
50532 |
return print_emit_string(chan, buf); |
|
217 |
} |
||
218 |
|||
219 |
static int print_emit_custom(lbm_char_channel_t *chan, lbm_value v) { |
||
220 |
lbm_uint *custom = (lbm_uint*)lbm_car(v); |
||
221 |
int r; // NULL checks works against SYM_NIL. |
||
222 |
if (custom && custom[CUSTOM_TYPE_DESCRIPTOR]) { |
||
223 |
r = print_emit_string(chan, (char*)custom[CUSTOM_TYPE_DESCRIPTOR]); |
||
224 |
} else { |
||
225 |
r = print_emit_string(chan, "INVALID_CUSTOM_TYPE"); |
||
226 |
} |
||
227 |
return r; |
||
228 |
} |
||
229 |
|||
230 |
56 |
static int print_emit_defrag_mem(lbm_char_channel_t *chan, lbm_value v) { |
|
231 |
(void) v; |
||
232 |
56 |
return print_emit_string(chan, "DM"); |
|
233 |
} |
||
234 |
|||
235 |
11940 |
static int print_emit_channel(lbm_char_channel_t *chan, lbm_value v) { |
|
236 |
(void) v; |
||
237 |
11940 |
return print_emit_string(chan, "~CHANNEL~"); |
|
238 |
} |
||
239 |
|||
240 |
3500 |
static int print_emit_array_data(lbm_char_channel_t *chan, lbm_array_header_t *array) { |
|
241 |
|||
242 |
3500 |
int r = print_emit_char(chan, '['); |
|
243 |
|||
244 |
✓✗ | 3500 |
if (r == EMIT_OK) { |
245 |
|||
246 |
✓✓ | 296898 |
for (unsigned int i = 0; i < array->size; i ++) { |
247 |
|||
248 |
293398 |
char *c_data = (char*)array->data; |
|
249 |
293398 |
r = print_emit_byte(chan, (uint8_t)c_data[i], false); |
|
250 |
|||
251 |
✓✓✓✓ |
293398 |
if (r == EMIT_OK && i != array->size - 1) { |
252 |
43988 |
r = print_emit_char(chan, ' '); |
|
253 |
} |
||
254 |
} |
||
255 |
|||
256 |
✓✓ | 3500 |
if (r != EMIT_OK) return r; |
257 |
3220 |
return print_emit_char(chan, ']'); |
|
258 |
} |
||
259 |
return r; |
||
260 |
} |
||
261 |
|||
262 |
4256 |
static int print_emit_bytearray(lbm_char_channel_t *chan, lbm_value v) { |
|
263 |
4256 |
int r = 0; |
|
264 |
char *str; |
||
265 |
4256 |
lbm_array_header_t *array = lbm_dec_array_r(v); |
|
266 |
✓✓ | 4256 |
if (array) { |
267 |
✓✓ | 4032 |
if (lbm_value_is_printable_string(v, &str)) { |
268 |
532 |
r = print_emit_char(chan, '"'); |
|
269 |
✓✗ | 532 |
if (r == EMIT_OK) { |
270 |
532 |
r = print_emit_string_value(chan, str); |
|
271 |
✓✗ | 532 |
if (r == EMIT_OK) { |
272 |
532 |
r = print_emit_char(chan, '"'); |
|
273 |
} |
||
274 |
} |
||
275 |
} else { |
||
276 |
3500 |
r= print_emit_array_data(chan, array); |
|
277 |
} |
||
278 |
} else { |
||
279 |
224 |
r = print_emit_string(chan, "[INVALID_ARRAY]"); |
|
280 |
} |
||
281 |
4256 |
return r; |
|
282 |
} |
||
283 |
|||
284 |
|||
285 |
328843 |
static int lbm_print_internal(lbm_char_channel_t *chan, lbm_value v) { |
|
286 |
|||
287 |
328843 |
lbm_stack_clear(&print_stack); |
|
288 |
328843 |
lbm_value start_print[2] = {v, PRINT}; |
|
289 |
328843 |
push_n(&print_stack, start_print, 2); |
|
290 |
328843 |
bool chan_full = false; |
|
291 |
lbm_value curr; |
||
292 |
lbm_uint instr; |
||
293 |
328843 |
int r = EMIT_FAILED; |
|
294 |
|||
295 |
✓✓✓✗ |
1260609 |
while (!lbm_stack_is_empty(&print_stack) && !chan_full) { |
296 |
603039 |
lbm_pop(&print_stack, &instr); |
|
297 |
✓✓✓✓ ✓✓✗✓ ✓✗ |
603039 |
switch (instr) { |
298 |
56 |
case START_ARRAY: { |
|
299 |
56 |
lbm_pop(&print_stack, &curr); |
|
300 |
56 |
int res = 1; |
|
301 |
56 |
r = print_emit_char(chan, '['); |
|
302 |
56 |
lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(curr); |
|
303 |
56 |
lbm_uint size = arr->size / sizeof(lbm_value); |
|
304 |
56 |
lbm_value *arrdata = (lbm_value*)arr->data; |
|
305 |
✓✗ | 56 |
if (size >= 1) { |
306 |
56 |
lbm_value continuation[5] = |
|
307 |
{1, // next index |
||
308 |
56 |
(lbm_uint) arr, |
|
309 |
CONTINUE_ARRAY, |
||
310 |
56 |
arrdata[0], // first elt |
|
311 |
PRINT}; |
||
312 |
✓✗✓✗ |
56 |
res = res && push_n(&print_stack, continuation, 5); |
313 |
} else { |
||
314 |
res = res && lbm_push(&print_stack, END_LIST); |
||
315 |
} |
||
316 |
✗✓ | 56 |
if (!res) { |
317 |
return EMIT_FAILED; |
||
318 |
} |
||
319 |
56 |
break; |
|
320 |
} |
||
321 |
168 |
case CONTINUE_ARRAY: { |
|
322 |
lbm_uint arr_ptr; |
||
323 |
lbm_array_header_t *arr; |
||
324 |
lbm_uint ix; |
||
325 |
168 |
int res = 1; |
|
326 |
168 |
lbm_pop_2(&print_stack, &arr_ptr, &ix); |
|
327 |
168 |
arr = (lbm_array_header_t *)arr_ptr; |
|
328 |
168 |
lbm_value *arrdata = (lbm_value*)arr->data; |
|
329 |
✓✓ | 168 |
if (ix < (arr->size / sizeof(lbm_value))) { |
330 |
112 |
r = print_emit_char(chan, ' '); |
|
331 |
112 |
lbm_value continuation[5] = |
|
332 |
112 |
{ix + 1, |
|
333 |
112 |
(lbm_uint) arr, |
|
334 |
CONTINUE_ARRAY, |
||
335 |
112 |
arrdata[ix], |
|
336 |
PRINT}; |
||
337 |
✓✗✓✗ |
112 |
res = res && push_n(&print_stack, continuation, 5); |
338 |
} else { |
||
339 |
✓✗✓✗ |
56 |
res = res && lbm_push(&print_stack, END_ARRAY); |
340 |
} |
||
341 |
✗✓ | 168 |
if (!res) { |
342 |
return EMIT_FAILED; |
||
343 |
} |
||
344 |
168 |
break; |
|
345 |
} |
||
346 |
56 |
case END_ARRAY: { |
|
347 |
56 |
r = print_emit_char(chan, ']'); |
|
348 |
56 |
break; |
|
349 |
} |
||
350 |
50224 |
case START_LIST: { |
|
351 |
50224 |
lbm_pop(&print_stack, &curr); |
|
352 |
50224 |
r = print_emit_char(chan, '('); |
|
353 |
✗✓ | 50224 |
if (r != EMIT_OK) return r; |
354 |
50224 |
lbm_value car_val = lbm_car(curr); |
|
355 |
50224 |
lbm_value cdr_val = lbm_cdr(curr); |
|
356 |
50224 |
int res = 1; |
|
357 |
✓✓✗✓ |
58336 |
if (lbm_type_of(cdr_val) == LBM_TYPE_CONS || |
358 |
8112 |
lbm_type_of(cdr_val) == (LBM_TYPE_CONS | LBM_PTR_TO_CONSTANT_BIT)) { |
|
359 |
42112 |
lbm_value cont[2] = {cdr_val, CONTINUE_LIST}; |
|
360 |
✓✗✓✗ |
42112 |
res = res && push_n(&print_stack, cont, 2); |
361 |
✓✓✓✓ |
8112 |
} else if (lbm_type_of(cdr_val) == LBM_TYPE_SYMBOL && |
362 |
cdr_val == ENC_SYM_NIL) { |
||
363 |
✓✗✓✗ |
4388 |
res = res && lbm_push(&print_stack, END_LIST); |
364 |
} else { |
||
365 |
3724 |
lbm_value cont[4] = {END_LIST, cdr_val, PRINT, PRINT_DOT}; |
|
366 |
✓✗✓✗ |
3724 |
res = res && push_n(&print_stack, cont, 4); |
367 |
} |
||
368 |
50224 |
lbm_value cont[2] = {car_val, PRINT}; |
|
369 |
✓✗✓✗ |
50224 |
res = res && push_n(&print_stack, cont,2); |
370 |
✗✓ | 50224 |
if (!res) { |
371 |
return EMIT_FAILED; |
||
372 |
} |
||
373 |
50224 |
break; |
|
374 |
} |
||
375 |
57916 |
case CONTINUE_LIST: { |
|
376 |
57916 |
int res = 1; |
|
377 |
57916 |
lbm_pop(&print_stack, &curr); |
|
378 |
|||
379 |
✗✓ | 57916 |
if (lbm_type_of(curr) == LBM_TYPE_SYMBOL && |
380 |
curr == ENC_SYM_NIL) { |
||
381 |
57912 |
break; |
|
382 |
} |
||
383 |
|||
384 |
57916 |
lbm_value car_val = lbm_car(curr); |
|
385 |
57916 |
lbm_value cdr_val = lbm_cdr(curr); |
|
386 |
|||
387 |
57916 |
r = print_emit_char(chan, ' '); |
|
388 |
✓✓ | 57916 |
if (r != EMIT_OK) { |
389 |
4 |
return r; |
|
390 |
} |
||
391 |
✓✓✗✓ |
99908 |
if (lbm_type_of(cdr_val) == LBM_TYPE_CONS || |
392 |
41996 |
lbm_type_of(cdr_val) == (LBM_TYPE_CONS | LBM_PTR_TO_CONSTANT_BIT)) { |
|
393 |
15916 |
lbm_value cont[2] = {cdr_val, CONTINUE_LIST}; |
|
394 |
✓✗✓✗ |
15916 |
res = res && push_n(&print_stack, cont, 2); |
395 |
✓✗✓✗ |
41996 |
} else if (lbm_type_of(cdr_val) == LBM_TYPE_SYMBOL && |
396 |
cdr_val == ENC_SYM_NIL) { |
||
397 |
✓✗✓✗ |
41996 |
res = res && lbm_push(&print_stack, END_LIST); |
398 |
} else { |
||
399 |
lbm_value cont[4] = {END_LIST, cdr_val, PRINT, PRINT_DOT}; |
||
400 |
res = res && push_n(&print_stack, cont, 4); |
||
401 |
} |
||
402 |
57912 |
lbm_value cont[2] = {car_val, PRINT}; |
|
403 |
✓✗✓✗ |
57912 |
res = res && push_n(&print_stack, cont, 2); |
404 |
✗✓ | 57912 |
if (!res) { |
405 |
return EMIT_FAILED; |
||
406 |
} |
||
407 |
57912 |
break; |
|
408 |
} |
||
409 |
50052 |
case END_LIST: |
|
410 |
50052 |
r = print_emit_char(chan, ')'); |
|
411 |
✓✓ | 50052 |
if (r != EMIT_OK) return r; |
412 |
49968 |
break; |
|
413 |
case PRINT_SPACE: |
||
414 |
r = print_emit_char(chan, ' '); |
||
415 |
if (r != EMIT_OK) return r; |
||
416 |
break; |
||
417 |
3724 |
case PRINT_DOT: |
|
418 |
3724 |
r = print_emit_string(chan, " . "); |
|
419 |
✓✓ | 3724 |
if (r != EMIT_OK) return r; |
420 |
3696 |
break; |
|
421 |
440843 |
case PRINT: |
|
422 |
440843 |
lbm_pop(&print_stack, &curr); |
|
423 |
|||
424 |
440843 |
lbm_type t = lbm_type_of(curr); |
|
425 |
✓✓ | 440843 |
if (lbm_is_ptr(curr)) |
426 |
118268 |
t = t & LBM_PTR_TO_CONSTANT_MASK; // print constants normally |
|
427 |
|||
428 |
switch(t) { |
||
429 |
50224 |
case LBM_TYPE_CONS: { |
|
430 |
50224 |
lbm_value cont[2] = {curr, START_LIST}; |
|
431 |
50224 |
int res = push_n(&print_stack, cont, 2); |
|
432 |
✗✓ | 50224 |
if (!res) { |
433 |
print_emit_string(chan," ..."); |
||
434 |
return EMIT_OK; |
||
435 |
} |
||
436 |
50224 |
break; |
|
437 |
} |
||
438 |
259761 |
case LBM_TYPE_SYMBOL: |
|
439 |
259761 |
r = print_emit_symbol(chan, curr); |
|
440 |
259761 |
break; |
|
441 |
41246 |
case LBM_TYPE_I: |
|
442 |
41246 |
r = print_emit_i(chan, lbm_dec_i(curr)); |
|
443 |
41246 |
break; |
|
444 |
21288 |
case LBM_TYPE_U: |
|
445 |
21288 |
r = print_emit_u(chan, lbm_dec_u(curr), true); |
|
446 |
21288 |
break; |
|
447 |
280 |
case LBM_TYPE_CHAR: |
|
448 |
280 |
r = print_emit_byte(chan, (uint8_t)lbm_dec_char(curr), true); |
|
449 |
280 |
break; |
|
450 |
420 |
case LBM_TYPE_FLOAT: |
|
451 |
420 |
r = print_emit_float(chan, lbm_dec_float(curr), true); |
|
452 |
420 |
break; |
|
453 |
336 |
case LBM_TYPE_DOUBLE: |
|
454 |
336 |
r = print_emit_double(chan, lbm_dec_double(curr), true); |
|
455 |
336 |
break; |
|
456 |
112 |
case LBM_TYPE_U32: |
|
457 |
112 |
r = print_emit_u32(chan, lbm_dec_u32(curr), true); |
|
458 |
112 |
break; |
|
459 |
112 |
case LBM_TYPE_I32: |
|
460 |
112 |
r = print_emit_i32(chan, lbm_dec_i32(curr), true); |
|
461 |
112 |
break; |
|
462 |
112 |
case LBM_TYPE_U64: |
|
463 |
112 |
r = print_emit_u64(chan, lbm_dec_u64(curr), true); |
|
464 |
112 |
break; |
|
465 |
112 |
case LBM_TYPE_I64: |
|
466 |
112 |
r = print_emit_i64(chan, lbm_dec_i64(curr), true); |
|
467 |
112 |
break; |
|
468 |
50532 |
case LBM_CONTINUATION_INTERNAL_TYPE: |
|
469 |
50532 |
r = print_emit_continuation(chan, curr); |
|
470 |
50532 |
break; |
|
471 |
case LBM_TYPE_CUSTOM: |
||
472 |
r = print_emit_custom(chan, curr); |
||
473 |
break; |
||
474 |
11940 |
case LBM_TYPE_CHANNEL: |
|
475 |
11940 |
r = print_emit_channel(chan, curr); |
|
476 |
11940 |
break; |
|
477 |
4256 |
case LBM_TYPE_ARRAY: |
|
478 |
4256 |
r = print_emit_bytearray(chan, curr); |
|
479 |
4256 |
break; |
|
480 |
56 |
case LBM_TYPE_DEFRAG_MEM: |
|
481 |
56 |
r = print_emit_defrag_mem(chan, curr); |
|
482 |
56 |
break; |
|
483 |
56 |
case LBM_TYPE_LISPARRAY: { |
|
484 |
56 |
lbm_value cont[2] = {curr, START_ARRAY}; |
|
485 |
56 |
int res = push_n(&print_stack, cont, 2); |
|
486 |
✗✓ | 56 |
if (!res) { |
487 |
print_emit_string(chan, " ..."); |
||
488 |
return EMIT_OK; |
||
489 |
} |
||
490 |
56 |
break; |
|
491 |
} |
||
492 |
default: |
||
493 |
return EMIT_FAILED; |
||
494 |
} |
||
495 |
931766 |
} |
|
496 |
} |
||
497 |
328727 |
return r; |
|
498 |
} |
||
499 |
|||
500 |
328843 |
int lbm_print_value(char *buf, unsigned int len, lbm_value v) { |
|
501 |
|||
502 |
lbm_string_channel_state_t st; |
||
503 |
lbm_char_channel_t chan; |
||
504 |
|||
505 |
328843 |
memset(buf, 0, len); |
|
506 |
328843 |
lbm_create_string_char_channel_size(&st, &chan, buf, len); |
|
507 |
✓✓ | 328843 |
if (lbm_print_internal(&chan,v) == EMIT_OK) |
508 |
328433 |
return 1; |
|
509 |
410 |
return 0; |
|
510 |
} |
Generated by: GCOVR (Version 4.2) |