GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions.c
Date: 2025-10-27 19:12:55
Exec Total Coverage
Lines: 72 90 80.0%
Functions: 12 15 80.0%
Branches: 32 42 76.2%

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 73 void lbm_extensions_set_next(lbm_uint i) {
35 73 next_extension_ix = i;
36 73 }
37
38 lbm_value lbm_extensions_default(lbm_value *args, lbm_uint argn) {
39 (void)args;
40 (void)argn;
41 return ENC_SYM_EERROR;
42 }
43
44 22390 bool lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) {
45
2/4
✓ Branch 0 taken 22390 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 22390 times.
22390 if (extension_storage == NULL || extension_storage_size == 0) return false;
46
47 22390 extension_table = extension_storage;
48 22390 memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size);
49
50
2/2
✓ Branch 0 taken 5857184 times.
✓ Branch 1 taken 22390 times.
5879574 for (lbm_uint i = 0; i < extension_storage_size; i ++) {
51 5857184 extension_storage[i].fptr = lbm_extensions_default;
52 }
53
54 22390 next_extension_ix = 0;
55 22390 ext_max = (lbm_uint)extension_storage_size;
56
57 22390 return true;
58 }
59
60 1702270481 lbm_uint lbm_get_max_extensions(void) {
61 1702270481 return ext_max;
62 }
63
64 32130 lbm_uint lbm_get_num_extensions(void) {
65 32130 return next_extension_ix;
66 }
67
68 extension_fptr lbm_get_extension(lbm_uint sym) {
69 lbm_uint ext_id = sym - EXTENSION_SYMBOLS_START;
70 extension_fptr res = lbm_extensions_default;
71 if (ext_id < ext_max) {
72 res = extension_table[ext_id].fptr;
73 }
74 return res;
75 }
76
77 bool lbm_clr_extension(lbm_uint sym_id) {
78 lbm_uint ext_id = SYMBOL_IX(sym_id);
79 if (ext_id >= ext_max) {
80 return false;
81 }
82 extension_table[ext_id].name = NULL;
83 extension_table[ext_id].fptr = lbm_extensions_default;
84 return true;
85 }
86
87 14 bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) {
88
1/2
✓ Branch 0 taken 1498 times.
✗ Branch 1 not taken.
1498 for (lbm_uint i = 0; i < ext_max; i ++) {
89
1/2
✓ Branch 0 taken 1498 times.
✗ Branch 1 not taken.
1498 if(extension_table[i].name) {
90
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1484 times.
1498 if (str_eq(extension_table[i].name, sym_str)) {
91 14 *ix = i + EXTENSION_SYMBOLS_START;
92 14 return true;
93 }
94 }
95 }
96 return false;
97 }
98
99 2390190 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 9386 times.
✓ Branch 1 taken 2380804 times.
2390190 if (lbm_get_symbol_by_name(sym_str, &symbol)) {
109
1/2
✓ Branch 0 taken 9386 times.
✗ Branch 1 not taken.
9386 if (lbm_is_extension(lbm_enc_sym(symbol))) {
110 // update the extension entry.
111 9386 extension_table[SYMBOL_IX(symbol)].fptr = ext;
112 9386 return true;
113 }
114 return false;
115 }
116
117
1/2
✓ Branch 0 taken 2380804 times.
✗ Branch 1 not taken.
2380804 if (next_extension_ix < ext_max) {
118 2380804 lbm_uint sym_ix = next_extension_ix ++;
119 2380804 extension_table[sym_ix].name = sym_str;
120 2380804 extension_table[sym_ix].fptr = ext;
121 2380804 return true;
122 }
123 return false;
124 }
125
126 // Helpers for extension developers:
127
128 3248 static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) {
129
2/2
✓ Branch 0 taken 6867 times.
✓ Branch 1 taken 3223 times.
10090 for (lbm_uint i = 0;i < argn;i++) {
130
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 6842 times.
6867 if (!lbm_is_number(args[i])) {
131 25 return false;
132 }
133 }
134 3223 return true;
135 }
136
137 2221 bool lbm_check_number_all(lbm_value *args, lbm_uint argn) {
138
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2219 times.
2221 if (!lbm_is_number_all(args, argn)) {
139 2 lbm_set_error_reason((char*)lbm_error_str_no_number);
140 2 return false;
141 }
142 2219 return true;
143 }
144
145 95 bool lbm_check_argn(lbm_uint argn, lbm_uint n) {
146
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 67 times.
95 if (argn != n) {
147 28 lbm_set_error_reason((char*)lbm_error_str_num_args);
148 28 return false;
149 } else {
150 67 return true;
151 }
152 }
153
154 1027 bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) {
155
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1004 times.
1027 if (!lbm_is_number_all(args, argn)) {
156 23 lbm_set_error_reason((char*)lbm_error_str_no_number);
157 23 return false;
158
2/2
✓ Branch 0 taken 423 times.
✓ Branch 1 taken 581 times.
1004 } else if (argn != n) {
159 423 lbm_set_error_reason((char*)lbm_error_str_num_args);
160 423 return false;
161 } else {
162 581 return true;
163 }
164 }
165
166 11054 lbm_value make_list(int num, ...) {
167 va_list arguments;
168 11054 va_start (arguments, num);
169 11054 lbm_value res = ENC_SYM_NIL;
170
2/2
✓ Branch 0 taken 28031 times.
✓ Branch 1 taken 11054 times.
39085 for (int i = 0; i < num; i++) {
171 28031 res = lbm_cons(va_arg(arguments, lbm_value), res);
172 }
173 11054 va_end (arguments);
174 11054 return lbm_list_destructive_reverse(res);
175 }
176
177 13931 bool strmatch(const char *str1, const char *str2) {
178 13931 size_t len = strlen(str1);
179
180
2/2
✓ Branch 0 taken 10934 times.
✓ Branch 1 taken 2997 times.
13931 if (str2[len] != ' ') {
181 10934 return false;
182 }
183
184 2997 bool same = true;
185
2/2
✓ Branch 0 taken 14048 times.
✓ Branch 1 taken 1160 times.
15208 for (unsigned int i = 0;i < len;i++) {
186
2/2
✓ Branch 0 taken 1837 times.
✓ Branch 1 taken 12211 times.
14048 if (str1[i] != str2[i]) {
187 1837 same = false;
188 1837 break;
189 }
190 }
191
192 2997 return same;
193 }
194