GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions.c
Date: 2025-08-08 18:10:24
Exec Total Coverage
Lines: 90 90 100.0%
Functions: 15 15 100.0%
Branches: 42 42 100.0%

Line Branch Exec Source
1 /*
2 Copyright 2019, 2021, 2022, 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 <lbm_memory.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdbool.h>
23 #include <string.h>
24 #include <eval_cps.h>
25
26 #include "extensions.h"
27 #include "lbm_utils.h"
28
29 static lbm_uint ext_max = 0;
30 static lbm_uint next_extension_ix = 0;
31
32 lbm_extension_t *extension_table = NULL;
33
34 37 void lbm_extensions_set_next(lbm_uint i) {
35 37 next_extension_ix = i;
36 37 }
37
38 1 lbm_value lbm_extensions_default(lbm_value *args, lbm_uint argn) {
39 (void)args;
40 (void)argn;
41 1 return ENC_SYM_EERROR;
42 }
43
44 44381 bool lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) {
45
4/4
✓ Branch 0 taken 44380 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 44379 times.
44381 if (extension_storage == NULL || extension_storage_size == 0) return false;
46
47 44379 extension_table = extension_storage;
48 44379 memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size);
49
50
2/2
✓ Branch 0 taken 9119634 times.
✓ Branch 1 taken 44379 times.
9164013 for (lbm_uint i = 0; i < extension_storage_size; i ++) {
51 9119634 extension_storage[i].fptr = lbm_extensions_default;
52 }
53
54 44379 next_extension_ix = 0;
55 44379 ext_max = (lbm_uint)extension_storage_size;
56
57 44379 return true;
58 }
59
60 1452485815 lbm_uint lbm_get_max_extensions(void) {
61 1452485815 return ext_max;
62 }
63
64 50327 lbm_uint lbm_get_num_extensions(void) {
65 50327 return next_extension_ix;
66 }
67
68 3 extension_fptr lbm_get_extension(lbm_uint sym) {
69 3 lbm_uint ext_id = sym - EXTENSION_SYMBOLS_START;
70 3 extension_fptr res = lbm_extensions_default;
71
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (ext_id < ext_max) {
72 2 res = extension_table[ext_id].fptr;
73 }
74 3 return res;
75 }
76
77 2 bool lbm_clr_extension(lbm_uint sym_id) {
78 2 lbm_uint ext_id = SYMBOL_IX(sym_id);
79
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (ext_id >= ext_max) {
80 1 return false;
81 }
82 1 extension_table[ext_id].name = NULL;
83 1 extension_table[ext_id].fptr = lbm_extensions_default;
84 1 return true;
85 }
86
87 30 bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) {
88
2/2
✓ Branch 0 taken 3007 times.
✓ Branch 1 taken 1 times.
3008 for (lbm_uint i = 0; i < ext_max; i ++) {
89
2/2
✓ Branch 0 taken 2998 times.
✓ Branch 1 taken 9 times.
3007 if(extension_table[i].name) {
90
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2969 times.
2998 if (str_eq(extension_table[i].name, sym_str)) {
91 29 *ix = i + EXTENSION_SYMBOLS_START;
92 29 return true;
93 }
94 }
95 }
96 1 return false;
97 }
98
99 4707281 bool lbm_add_extension(char *sym_str, extension_fptr ext) {
100 lbm_value symbol;
101
102 // symbol_by_name loops through all symbols. It may be enough
103 // to search only the extension table, but unsure what the effect will
104 // be if adding an extension with same str-name as a built-in or special
105 // form. The extension may override built-in...
106 //
107 // Check if symbol already exists.
108
2/2
✓ Branch 0 taken 5804 times.
✓ Branch 1 taken 4701477 times.
4707281 if (lbm_get_symbol_by_name(sym_str, &symbol)) {
109
2/2
✓ Branch 0 taken 5801 times.
✓ Branch 1 taken 3 times.
5804 if (lbm_is_extension(lbm_enc_sym(symbol))) {
110 // update the extension entry.
111 5801 extension_table[SYMBOL_IX(symbol)].fptr = ext;
112 5801 return true;
113 }
114 3 return false;
115 }
116
117
2/2
✓ Branch 0 taken 4701476 times.
✓ Branch 1 taken 1 times.
4701477 if (next_extension_ix < ext_max) {
118 4701476 lbm_uint sym_ix = next_extension_ix ++;
119 4701476 extension_table[sym_ix].name = sym_str;
120 4701476 extension_table[sym_ix].fptr = ext;
121 4701476 return true;
122 }
123 1 return false;
124 }
125
126 // Helpers for extension developers:
127
128 6382 static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) {
129
2/2
✓ Branch 0 taken 13615 times.
✓ Branch 1 taken 6353 times.
19968 for (lbm_uint i = 0;i < argn;i++) {
130
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 13586 times.
13615 if (!lbm_is_number(args[i])) {
131 29 return false;
132 }
133 }
134 6353 return true;
135 }
136
137 4431 bool lbm_check_number_all(lbm_value *args, lbm_uint argn) {
138
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4427 times.
4431 if (!lbm_is_number_all(args, argn)) {
139 4 lbm_set_error_reason((char*)lbm_error_str_no_number);
140 4 return false;
141 }
142 4427 return true;
143 }
144
145 183 bool lbm_check_argn(lbm_uint argn, lbm_uint n) {
146
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 125 times.
183 if (argn != n) {
147 58 lbm_set_error_reason((char*)lbm_error_str_num_args);
148 58 return false;
149 } else {
150 125 return true;
151 }
152 }
153
154 1951 bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) {
155
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 1926 times.
1951 if (!lbm_is_number_all(args, argn)) {
156 25 lbm_set_error_reason((char*)lbm_error_str_no_number);
157 25 return false;
158
2/2
✓ Branch 0 taken 844 times.
✓ Branch 1 taken 1082 times.
1926 } else if (argn != n) {
159 844 lbm_set_error_reason((char*)lbm_error_str_num_args);
160 844 return false;
161 } else {
162 1082 return true;
163 }
164 }
165
166 21032 lbm_value make_list(int num, ...) {
167 va_list arguments;
168 21032 va_start (arguments, num);
169 21032 lbm_value res = ENC_SYM_NIL;
170
2/2
✓ Branch 0 taken 53098 times.
✓ Branch 1 taken 21032 times.
74130 for (int i = 0; i < num; i++) {
171 53098 res = lbm_cons(va_arg(arguments, lbm_value), res);
172 }
173 21032 va_end (arguments);
174 21032 return lbm_list_destructive_reverse(res);
175 }
176
177 25892 bool strmatch(const char *str1, const char *str2) {
178 25892 size_t len = strlen(str1);
179
180
2/2
✓ Branch 0 taken 20312 times.
✓ Branch 1 taken 5580 times.
25892 if (str2[len] != ' ') {
181 20312 return false;
182 }
183
184 5580 bool same = true;
185
2/2
✓ Branch 0 taken 26443 times.
✓ Branch 1 taken 2074 times.
28517 for (unsigned int i = 0;i < len;i++) {
186
2/2
✓ Branch 0 taken 3506 times.
✓ Branch 1 taken 22937 times.
26443 if (str1[i] != str2[i]) {
187 3506 same = false;
188 3506 break;
189 }
190 }
191
192 5580 return same;
193 }
194