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 |
// is_printable_string is turning out to be a headache. |
||
48 |
// What do we want from this function??? |
||
49 |
// |
||
50 |
// Value | Print as | Condition |
||
51 |
// [0] | [0] | |
||
52 |
// [1] | [1] | |
||
53 |
// "" | [0] | (array->size <= 1) => false |
||
54 |
// "hej" | "hej" | printable characters followed by a 0 |
||
55 |
// [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 |
||
56 |
// [0 65 66 0] | [0 65 66 0] | position of first 0 after printable characters = array->size-1 |
||
57 |
5432 |
bool lbm_value_is_printable_string(lbm_value v, char **str) { |
|
58 |
5432 |
bool is_a_string = false; |
|
59 |
5432 |
lbm_array_header_t *array = lbm_dec_array_r(v); |
|
60 |
✓✓ | 5432 |
if (array) { |
61 |
4424 |
char *c_data = (char *)array->data; |
|
62 |
✓✓ | 4424 |
if (array->size > 1) { // nonzero length |
63 |
3920 |
unsigned int i = 0; |
|
64 |
3920 |
is_a_string = true; |
|
65 |
✓✗ | 7140 |
for (i = 0; i < array->size; i ++) { |
66 |
✓✓ | 7140 |
if (c_data[i] == 0) break; |
67 |
✓✓✓✓ ✗✓ |
4676 |
if (!isprint((unsigned char)c_data[i]) && ((c_data[i] < 8) || c_data[i] > 13)) { |
68 |
1456 |
is_a_string = false; |
|
69 |
1456 |
break; |
|
70 |
} |
||
71 |
} |
||
72 |
✓✓✓✓ ✓✗ |
3920 |
if (i > 0 && i != array->size-1 && c_data[i-1] != 0) is_a_string = false; |
73 |
✓✓ | 3920 |
if (array->size-1 > i) is_a_string = false; |
74 |
✓✓ | 3920 |
if (is_a_string) { |
75 |
784 |
*str = (char*)array->data; |
|
76 |
} |
||
77 |
} |
||
78 |
} |
||
79 |
5432 |
return is_a_string; |
|
80 |
} |
||
81 |
|||
82 |
563908 |
static int push_n(lbm_stack_t *s, lbm_uint *values, lbm_uint n) { |
|
83 |
✓✗ | 563908 |
if (s->sp + n < s->size) { |
84 |
✓✓ | 1701248 |
for (lbm_uint i = 0; i < n; i ++) { |
85 |
1137340 |
s->data[s->sp+i] = values[i]; |
|
86 |
} |
||
87 |
563908 |
s->sp+=n; |
|
88 |
563908 |
return 1; |
|
89 |
} |
||
90 |
return 0; |
||
91 |
} |
||
92 |
|||
93 |
21924 |
int lbm_print_init(lbm_uint print_stack_size) { |
|
94 |
|||
95 |
✗✓ | 21924 |
if (print_stack_size == 0) |
96 |
return 0; |
||
97 |
|||
98 |
21924 |
lbm_uint *print_stack_storage = (lbm_uint*)lbm_malloc(print_stack_size * sizeof(lbm_uint)); |
|
99 |
✗✓ | 21924 |
if (!print_stack_storage) return 0; |
100 |
|||
101 |
✓✗ | 21924 |
if (lbm_stack_create(&print_stack, print_stack_storage, print_stack_size)) { |
102 |
21924 |
print_has_stack = true; |
|
103 |
21924 |
return 1; |
|
104 |
} |
||
105 |
return 0; |
||
106 |
} |
||
107 |
|||
108 |
#define EMIT_BUFFER_SIZE 30 |
||
109 |
|||
110 |
#define EMIT_FAILED -1 |
||
111 |
#define EMIT_OK 0 |
||
112 |
|||
113 |
697964 |
static int print_emit_string(lbm_char_channel_t *chan, char* str) { |
|
114 |
✓✓ | 697964 |
if (str == NULL) return EMIT_FAILED; |
115 |
✓✓ | 2413492 |
while (*str != 0) { |
116 |
1969506 |
int r = lbm_channel_write(chan, *str); |
|
117 |
1969506 |
str++; |
|
118 |
✓✓ | 1969506 |
if (r != CHANNEL_SUCCESS) return EMIT_FAILED; |
119 |
} |
||
120 |
443986 |
return EMIT_OK; |
|
121 |
} |
||
122 |
|||
123 |
219704 |
static int print_emit_char(lbm_char_channel_t *chan, char c) { |
|
124 |
|||
125 |
219704 |
int r = lbm_channel_write(chan, c); |
|
126 |
✓✓ | 219704 |
if (r != CHANNEL_SUCCESS) return EMIT_FAILED; |
127 |
219554 |
return EMIT_OK; |
|
128 |
} |
||
129 |
|||
130 |
|||
131 |
1596 |
static int emit_escape(lbm_char_channel_t *chan, char c) { |
|
132 |
✗✗✗✗ ✗✓ |
1596 |
switch(c) { |
133 |
case '"': return print_emit_string(chan, "\\\""); |
||
134 |
case '\n': return print_emit_string(chan, "\\n"); |
||
135 |
case '\r': return print_emit_string(chan, "\\r"); |
||
136 |
case '\t': return print_emit_string(chan, "\\t"); |
||
137 |
case '\\': return print_emit_string(chan, "\\\\"); |
||
138 |
1596 |
default: |
|
139 |
1596 |
return print_emit_char(chan, c); |
|
140 |
} |
||
141 |
} |
||
142 |
|||
143 |
532 |
static int print_emit_string_value(lbm_char_channel_t *chan, char* str) { |
|
144 |
✗✓ | 532 |
if (str == NULL) return EMIT_FAILED; |
145 |
✓✓ | 2128 |
while (*str != 0) { |
146 |
1596 |
int r = emit_escape(chan, *str++); |
|
147 |
✗✓ | 1596 |
if (r != EMIT_OK) return r; |
148 |
} |
||
149 |
532 |
return EMIT_OK; |
|
150 |
} |
||
151 |
|||
152 |
265706 |
static int print_emit_symbol(lbm_char_channel_t *chan, lbm_value sym) { |
|
153 |
265706 |
char *str_ptr = (char*)lbm_get_name_by_symbol(lbm_dec_sym(sym)); |
|
154 |
265706 |
return print_emit_string(chan, str_ptr); |
|
155 |
} |
||
156 |
|||
157 |
41726 |
static int print_emit_i(lbm_char_channel_t *chan, lbm_int v) { |
|
158 |
char buf[EMIT_BUFFER_SIZE]; |
||
159 |
41726 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_INT, v); |
|
160 |
41726 |
return print_emit_string(chan, buf); |
|
161 |
} |
||
162 |
|||
163 |
21274 |
static int print_emit_u(lbm_char_channel_t *chan, lbm_uint v, bool ps) { |
|
164 |
char buf[EMIT_BUFFER_SIZE]; |
||
165 |
✓✗ | 21274 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_UINT"%s", v, ps ? "u" : ""); |
166 |
21274 |
return print_emit_string(chan, buf); |
|
167 |
} |
||
168 |
|||
169 |
300944 |
static int print_emit_byte(lbm_char_channel_t *chan, uint8_t v, bool ps) { |
|
170 |
char buf[EMIT_BUFFER_SIZE]; |
||
171 |
✓✓ | 300944 |
snprintf(buf, EMIT_BUFFER_SIZE, "%u%s", v, ps ? "b" : ""); |
172 |
300944 |
return print_emit_string(chan, buf); |
|
173 |
} |
||
174 |
|||
175 |
420 |
static int print_emit_float(lbm_char_channel_t *chan, float v, bool ps) { |
|
176 |
char buf[EMIT_BUFFER_SIZE]; |
||
177 |
✓✗ | 420 |
snprintf(buf, EMIT_BUFFER_SIZE, "%"PRI_FLOAT"%s", (double)v, ps ? "f32" : ""); |
178 |
420 |
return print_emit_string(chan, buf); |
|
179 |
} |
||
180 |
|||
181 |
336 |
static int print_emit_double(lbm_char_channel_t *chan, double v, bool ps) { |
|
182 |
char buf[EMIT_BUFFER_SIZE]; |
||
183 |
✓✗ | 336 |
snprintf(buf, EMIT_BUFFER_SIZE, "%lf%s", v, ps ? "f64" : ""); |
184 |
336 |
return print_emit_string(chan, buf); |
|
185 |
} |
||
186 |
|||
187 |
112 |
static int print_emit_u32(lbm_char_channel_t *chan, uint32_t v, bool ps) { |
|
188 |
char buf[EMIT_BUFFER_SIZE]; |
||
189 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRIu32"%s", v, ps ? "u32" : ""); |
190 |
112 |
return print_emit_string(chan, buf); |
|
191 |
} |
||
192 |
|||
193 |
112 |
static int print_emit_i32(lbm_char_channel_t *chan, int32_t v, bool ps) { |
|
194 |
char buf[EMIT_BUFFER_SIZE]; |
||
195 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRId32"%s", v, ps ? "i32" : ""); |
196 |
112 |
return print_emit_string(chan, buf); |
|
197 |
} |
||
198 |
|||
199 |
112 |
static int print_emit_u64(lbm_char_channel_t *chan, uint64_t v, bool ps) { |
|
200 |
char buf[EMIT_BUFFER_SIZE]; |
||
201 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRIu64"%s", v, ps ? "u64" : ""); |
202 |
112 |
return print_emit_string(chan, buf); |
|
203 |
} |
||
204 |
|||
205 |
112 |
static int print_emit_i64(lbm_char_channel_t *chan, int64_t v, bool ps) { |
|
206 |
char buf[EMIT_BUFFER_SIZE]; |
||
207 |
✓✗ | 112 |
snprintf(buf,EMIT_BUFFER_SIZE, "%"PRId64"%s", v, ps ? "i64" : ""); |
208 |
112 |
return print_emit_string(chan, buf); |
|
209 |
} |
||
210 |
|||
211 |
50552 |
static int print_emit_continuation(lbm_char_channel_t *chan, lbm_value v) { |
|
212 |
char buf[EMIT_BUFFER_SIZE]; |
||
213 |
50552 |
lbm_uint cont = (v & ~LBM_CONTINUATION_INTERNAL) >> LBM_ADDRESS_SHIFT; |
|
214 |
50552 |
snprintf(buf, EMIT_BUFFER_SIZE, "CONT[" "%"PRI_UINT"]", cont); |
|
215 |
50552 |
return print_emit_string(chan, buf); |
|
216 |
} |
||
217 |
|||
218 |
static int print_emit_custom(lbm_char_channel_t *chan, lbm_value v) { |
||
219 |
lbm_uint *custom = (lbm_uint*)lbm_car(v); |
||
220 |
int r; // NULL checks works against SYM_NIL. |
||
221 |
if (custom && custom[CUSTOM_TYPE_DESCRIPTOR]) { |
||
222 |
r = print_emit_string(chan, (char*)custom[CUSTOM_TYPE_DESCRIPTOR]); |
||
223 |
} else { |
||
224 |
r = print_emit_string(chan, "INVALID_CUSTOM_TYPE"); |
||
225 |
} |
||
226 |
return r; |
||
227 |
} |
||
228 |
|||
229 |
56 |
static int print_emit_defrag_mem(lbm_char_channel_t *chan, lbm_value v) { |
|
230 |
(void) v; |
||
231 |
56 |
return print_emit_string(chan, "DM"); |
|
232 |
} |
||
233 |
|||
234 |
11954 |
static int print_emit_channel(lbm_char_channel_t *chan, lbm_value v) { |
|
235 |
(void) v; |
||
236 |
11954 |
return print_emit_string(chan, "~CHANNEL~"); |
|
237 |
} |
||
238 |
|||
239 |
3500 |
static int print_emit_array_data(lbm_char_channel_t *chan, lbm_array_header_t *array) { |
|
240 |
|||
241 |
3500 |
int r = print_emit_char(chan, '['); |
|
242 |
|||
243 |
✓✗ | 3500 |
if (r == EMIT_OK) { |
244 |
|||
245 |
✓✓ | 304164 |
for (unsigned int i = 0; i < array->size; i ++) { |
246 |
|||
247 |
300664 |
char *c_data = (char*)array->data; |
|
248 |
300664 |
r = print_emit_byte(chan, (uint8_t)c_data[i], false); |
|
249 |
|||
250 |
✓✓✓✓ |
300664 |
if (r == EMIT_OK && i != array->size - 1) { |
251 |
43988 |
r = print_emit_char(chan, ' '); |
|
252 |
} |
||
253 |
} |
||
254 |
|||
255 |
✓✓ | 3500 |
if (r != EMIT_OK) return r; |
256 |
3220 |
return print_emit_char(chan, ']'); |
|
257 |
} |
||
258 |
return r; |
||
259 |
} |
||
260 |
|||
261 |
4256 |
static int print_emit_bytearray(lbm_char_channel_t *chan, lbm_value v) { |
|
262 |
4256 |
int r = 0; |
|
263 |
char *str; |
||
264 |
4256 |
lbm_array_header_t *array = lbm_dec_array_r(v); |
|
265 |
✓✓ | 4256 |
if (array) { |
266 |
✓✓ | 4032 |
if (lbm_value_is_printable_string(v, &str)) { |
267 |
532 |
r = print_emit_char(chan, '"'); |
|
268 |
✓✗ | 532 |
if (r == EMIT_OK) { |
269 |
532 |
r = print_emit_string_value(chan, str); |
|
270 |
✓✗ | 532 |
if (r == EMIT_OK) { |
271 |
532 |
r = print_emit_char(chan, '"'); |
|
272 |
} |
||
273 |
} |
||
274 |
} else { |
||
275 |
3500 |
r= print_emit_array_data(chan, array); |
|
276 |
} |
||
277 |
} else { |
||
278 |
224 |
r = print_emit_string(chan, "[INVALID_ARRAY]"); |
|
279 |
} |
||
280 |
4256 |
return r; |
|
281 |
} |
||
282 |
|||
283 |
|||
284 |
331480 |
static int lbm_print_internal(lbm_char_channel_t *chan, lbm_value v) { |
|
285 |
|||
286 |
331480 |
lbm_stack_clear(&print_stack); |
|
287 |
331480 |
lbm_value start_print[2] = {v, PRINT}; |
|
288 |
331480 |
push_n(&print_stack, start_print, 2); |
|
289 |
331480 |
bool chan_full = false; |
|
290 |
lbm_value curr; |
||
291 |
lbm_uint instr; |
||
292 |
331480 |
int r = EMIT_FAILED; |
|
293 |
|||
294 |
✓✓✓✗ |
1283324 |
while (!lbm_stack_is_empty(&print_stack) && !chan_full) { |
295 |
620542 |
lbm_pop(&print_stack, &instr); |
|
296 |
✓✓✓✓ ✓✓✗✓ ✓✗ |
620542 |
switch (instr) { |
297 |
174 |
case START_ARRAY: { |
|
298 |
174 |
lbm_pop(&print_stack, &curr); |
|
299 |
174 |
int res = 1; |
|
300 |
174 |
r = print_emit_string(chan, "[|"); |
|
301 |
174 |
lbm_array_header_t *arr = (lbm_array_header_t*)lbm_car(curr); |
|
302 |
174 |
lbm_uint size = arr->size / sizeof(lbm_value); |
|
303 |
174 |
lbm_value *arrdata = (lbm_value*)arr->data; |
|
304 |
✓✗ | 174 |
if (size >= 1) { |
305 |
174 |
lbm_value continuation[5] = |
|
306 |
{1, // next index |
||
307 |
174 |
(lbm_uint) arr, |
|
308 |
CONTINUE_ARRAY, |
||
309 |
174 |
arrdata[0], // first elt |
|
310 |
PRINT}; |
||
311 |
✓✗✓✗ |
174 |
res = res && push_n(&print_stack, continuation, 5); |
312 |
} else { |
||
313 |
res = res && lbm_push(&print_stack, END_ARRAY); |
||
314 |
} |
||
315 |
✗✓ | 174 |
if (!res) { |
316 |
return EMIT_FAILED; |
||
317 |
} |
||
318 |
174 |
break; |
|
319 |
} |
||
320 |
524 |
case CONTINUE_ARRAY: { |
|
321 |
lbm_uint arr_ptr; |
||
322 |
lbm_array_header_t *arr; |
||
323 |
lbm_uint ix; |
||
324 |
524 |
int res = 1; |
|
325 |
524 |
lbm_pop_2(&print_stack, &arr_ptr, &ix); |
|
326 |
524 |
arr = (lbm_array_header_t *)arr_ptr; |
|
327 |
524 |
lbm_value *arrdata = (lbm_value*)arr->data; |
|
328 |
✓✓ | 524 |
if (ix < (arr->size / sizeof(lbm_value))) { |
329 |
350 |
r = print_emit_char(chan, ' '); |
|
330 |
350 |
lbm_value continuation[5] = |
|
331 |
350 |
{ix + 1, |
|
332 |
350 |
(lbm_uint) arr, |
|
333 |
CONTINUE_ARRAY, |
||
334 |
350 |
arrdata[ix], |
|
335 |
PRINT}; |
||
336 |
✓✗✓✗ |
350 |
res = res && push_n(&print_stack, continuation, 5); |
337 |
} else { |
||
338 |
✓✗✓✗ |
174 |
res = res && lbm_push(&print_stack, END_ARRAY); |
339 |
} |
||
340 |
✗✓ | 524 |
if (!res) { |
341 |
return EMIT_FAILED; |
||
342 |
} |
||
343 |
524 |
break; |
|
344 |
} |
||
345 |
174 |
case END_ARRAY: { |
|
346 |
174 |
r = print_emit_string(chan, "|]"); |
|
347 |
174 |
break; |
|
348 |
} |
||
349 |
52526 |
case START_LIST: { |
|
350 |
52526 |
lbm_pop(&print_stack, &curr); |
|
351 |
52526 |
r = print_emit_char(chan, '('); |
|
352 |
✗✓ | 52526 |
if (r != EMIT_OK) return r; |
353 |
52526 |
lbm_value car_val = lbm_car(curr); |
|
354 |
52526 |
lbm_value cdr_val = lbm_cdr(curr); |
|
355 |
52526 |
int res = 1; |
|
356 |
✓✓✗✓ |
61084 |
if (lbm_type_of(cdr_val) == LBM_TYPE_CONS || |
357 |
8558 |
lbm_type_of(cdr_val) == (LBM_TYPE_CONS | LBM_PTR_TO_CONSTANT_BIT)) { |
|
358 |
43968 |
lbm_value cont[2] = {cdr_val, CONTINUE_LIST}; |
|
359 |
✓✗✓✗ |
43968 |
res = res && push_n(&print_stack, cont, 2); |
360 |
✓✓✓✓ |
8558 |
} else if (lbm_type_of(cdr_val) == LBM_TYPE_SYMBOL && |
361 |
cdr_val == ENC_SYM_NIL) { |
||
362 |
✓✗✓✗ |
4582 |
res = res && lbm_push(&print_stack, END_LIST); |
363 |
} else { |
||
364 |
3976 |
lbm_value cont[4] = {END_LIST, cdr_val, PRINT, PRINT_DOT}; |
|
365 |
✓✗✓✗ |
3976 |
res = res && push_n(&print_stack, cont, 4); |
366 |
} |
||
367 |
52526 |
lbm_value cont[2] = {car_val, PRINT}; |
|
368 |
✓✗✓✗ |
52526 |
res = res && push_n(&print_stack, cont,2); |
369 |
✗✓ | 52526 |
if (!res) { |
370 |
return EMIT_FAILED; |
||
371 |
} |
||
372 |
52526 |
break; |
|
373 |
} |
||
374 |
61294 |
case CONTINUE_LIST: { |
|
375 |
61294 |
int res = 1; |
|
376 |
61294 |
lbm_pop(&print_stack, &curr); |
|
377 |
|||
378 |
✗✓ | 61294 |
if (lbm_type_of(curr) == LBM_TYPE_SYMBOL && |
379 |
curr == ENC_SYM_NIL) { |
||
380 |
61230 |
break; |
|
381 |
} |
||
382 |
|||
383 |
61294 |
lbm_value car_val = lbm_car(curr); |
|
384 |
61294 |
lbm_value cdr_val = lbm_cdr(curr); |
|
385 |
|||
386 |
61294 |
r = print_emit_char(chan, ' '); |
|
387 |
✓✓ | 61294 |
if (r != EMIT_OK) { |
388 |
64 |
return r; |
|
389 |
} |
||
390 |
✓✓✗✓ |
104956 |
if (lbm_type_of(cdr_val) == LBM_TYPE_CONS || |
391 |
43726 |
lbm_type_of(cdr_val) == (LBM_TYPE_CONS | LBM_PTR_TO_CONSTANT_BIT)) { |
|
392 |
17504 |
lbm_value cont[2] = {cdr_val, CONTINUE_LIST}; |
|
393 |
✓✗✓✗ |
17504 |
res = res && push_n(&print_stack, cont, 2); |
394 |
✓✗✓✗ |
43726 |
} else if (lbm_type_of(cdr_val) == LBM_TYPE_SYMBOL && |
395 |
cdr_val == ENC_SYM_NIL) { |
||
396 |
✓✗✓✗ |
43726 |
res = res && lbm_push(&print_stack, END_LIST); |
397 |
} else { |
||
398 |
lbm_value cont[4] = {END_LIST, cdr_val, PRINT, PRINT_DOT}; |
||
399 |
res = res && push_n(&print_stack, cont, 4); |
||
400 |
} |
||
401 |
61230 |
lbm_value cont[2] = {car_val, PRINT}; |
|
402 |
✓✗✓✗ |
61230 |
res = res && push_n(&print_stack, cont, 2); |
403 |
✗✓ | 61230 |
if (!res) { |
404 |
return EMIT_FAILED; |
||
405 |
} |
||
406 |
61230 |
break; |
|
407 |
} |
||
408 |
52166 |
case END_LIST: |
|
409 |
52166 |
r = print_emit_char(chan, ')'); |
|
410 |
✓✓ | 52166 |
if (r != EMIT_OK) return r; |
411 |
52080 |
break; |
|
412 |
case PRINT_SPACE: |
||
413 |
r = print_emit_char(chan, ' '); |
||
414 |
if (r != EMIT_OK) return r; |
||
415 |
break; |
||
416 |
3976 |
case PRINT_DOT: |
|
417 |
3976 |
r = print_emit_string(chan, " . "); |
|
418 |
✓✓ | 3976 |
if (r != EMIT_OK) return r; |
419 |
3948 |
break; |
|
420 |
449708 |
case PRINT: |
|
421 |
449708 |
lbm_pop(&print_stack, &curr); |
|
422 |
|||
423 |
449708 |
lbm_type t = lbm_type_of(curr); |
|
424 |
✓✓ | 449708 |
if (lbm_is_ptr(curr)) |
425 |
120722 |
t = t & LBM_PTR_TO_CONSTANT_MASK; // print constants normally |
|
426 |
|||
427 |
switch(t) { |
||
428 |
52526 |
case LBM_TYPE_CONS: { |
|
429 |
✗✓ | 52526 |
if (lbm_dec_ptr(curr) == LBM_PTR_NULL) { |
430 |
print_emit_string(chan, " LBM_NULL "); |
||
431 |
} else { |
||
432 |
52526 |
lbm_value cont[2] = {curr, START_LIST}; |
|
433 |
52526 |
int res = push_n(&print_stack, cont, 2); |
|
434 |
✗✓ | 52526 |
if (!res) { |
435 |
print_emit_string(chan," ..."); |
||
436 |
return EMIT_OK; |
||
437 |
} |
||
438 |
} |
||
439 |
52526 |
break; |
|
440 |
} |
||
441 |
265706 |
case LBM_TYPE_SYMBOL: |
|
442 |
265706 |
r = print_emit_symbol(chan, curr); |
|
443 |
265706 |
break; |
|
444 |
41726 |
case LBM_TYPE_I: |
|
445 |
41726 |
r = print_emit_i(chan, lbm_dec_i(curr)); |
|
446 |
41726 |
break; |
|
447 |
21274 |
case LBM_TYPE_U: |
|
448 |
21274 |
r = print_emit_u(chan, lbm_dec_u(curr), true); |
|
449 |
21274 |
break; |
|
450 |
280 |
case LBM_TYPE_CHAR: |
|
451 |
280 |
r = print_emit_byte(chan, (uint8_t)lbm_dec_char(curr), true); |
|
452 |
280 |
break; |
|
453 |
420 |
case LBM_TYPE_FLOAT: |
|
454 |
420 |
r = print_emit_float(chan, lbm_dec_float(curr), true); |
|
455 |
420 |
break; |
|
456 |
336 |
case LBM_TYPE_DOUBLE: |
|
457 |
336 |
r = print_emit_double(chan, lbm_dec_double(curr), true); |
|
458 |
336 |
break; |
|
459 |
112 |
case LBM_TYPE_U32: |
|
460 |
112 |
r = print_emit_u32(chan, lbm_dec_u32(curr), true); |
|
461 |
112 |
break; |
|
462 |
112 |
case LBM_TYPE_I32: |
|
463 |
112 |
r = print_emit_i32(chan, lbm_dec_i32(curr), true); |
|
464 |
112 |
break; |
|
465 |
112 |
case LBM_TYPE_U64: |
|
466 |
112 |
r = print_emit_u64(chan, lbm_dec_u64(curr), true); |
|
467 |
112 |
break; |
|
468 |
112 |
case LBM_TYPE_I64: |
|
469 |
112 |
r = print_emit_i64(chan, lbm_dec_i64(curr), true); |
|
470 |
112 |
break; |
|
471 |
50552 |
case LBM_CONTINUATION_INTERNAL_TYPE: |
|
472 |
50552 |
r = print_emit_continuation(chan, curr); |
|
473 |
50552 |
break; |
|
474 |
case LBM_TYPE_CUSTOM: |
||
475 |
r = print_emit_custom(chan, curr); |
||
476 |
break; |
||
477 |
11954 |
case LBM_TYPE_CHANNEL: |
|
478 |
11954 |
r = print_emit_channel(chan, curr); |
|
479 |
11954 |
break; |
|
480 |
4256 |
case LBM_TYPE_ARRAY: |
|
481 |
4256 |
r = print_emit_bytearray(chan, curr); |
|
482 |
4256 |
break; |
|
483 |
56 |
case LBM_TYPE_DEFRAG_MEM: |
|
484 |
56 |
r = print_emit_defrag_mem(chan, curr); |
|
485 |
56 |
break; |
|
486 |
174 |
case LBM_TYPE_LISPARRAY: { |
|
487 |
174 |
lbm_value cont[2] = {curr, START_ARRAY}; |
|
488 |
174 |
int res = push_n(&print_stack, cont, 2); |
|
489 |
✗✓ | 174 |
if (!res) { |
490 |
print_emit_string(chan, " ..."); |
||
491 |
return EMIT_OK; |
||
492 |
} |
||
493 |
174 |
break; |
|
494 |
} |
||
495 |
default: |
||
496 |
return EMIT_FAILED; |
||
497 |
} |
||
498 |
951844 |
} |
|
499 |
} |
||
500 |
331302 |
return r; |
|
501 |
} |
||
502 |
|||
503 |
331480 |
int lbm_print_value(char *buf, unsigned int len, lbm_value v) { |
|
504 |
|||
505 |
lbm_string_channel_state_t st; |
||
506 |
lbm_char_channel_t chan; |
||
507 |
|||
508 |
331480 |
memset(buf, 0, len); |
|
509 |
331480 |
lbm_create_string_char_channel_size(&st, &chan, buf, len); |
|
510 |
✓✓ | 331480 |
if (lbm_print_internal(&chan,v) == EMIT_OK) |
511 |
331008 |
return 1; |
|
512 |
472 |
return 0; |
|
513 |
} |
Generated by: GCOVR (Version 4.2) |