GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions.c
Date: 2024-08-06 17:32:21
Exec Total Coverage
Lines: 45 76 59.2%
Functions: 8 13 61.5%
Branches: 20 40 50.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 ext_num = 0;
31 static lbm_uint next_extension_ix = 0;
32
33 lbm_extension_t *extension_table = NULL;
34
35 lbm_value lbm_extensions_default(lbm_value *args, lbm_uint argn) {
36 (void)args;
37 (void)argn;
38 return ENC_SYM_EERROR;
39 }
40
41 17444 int lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) {
42
2/4
✓ Branch 0 taken 17444 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17444 times.
17444 if (extension_storage == NULL || extension_storage_size == 0) return 0;
43
44 17444 extension_table = extension_storage;
45 17444 memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size);
46
47
2/2
✓ Branch 0 taken 1744400 times.
✓ Branch 1 taken 17444 times.
1761844 for (lbm_uint i = 0; i < extension_storage_size; i ++) {
48 1744400 extension_storage[i].fptr = lbm_extensions_default;
49 }
50
51 17444 ext_num = 0;
52 17444 next_extension_ix = 0;
53 17444 ext_max = (lbm_uint)extension_storage_size;
54
55 17444 return 1;
56 }
57
58 230875674 lbm_uint lbm_get_max_extensions(void) {
59 230875674 return ext_max;
60 }
61
62 lbm_uint lbm_get_num_extensions(void) {
63 return ext_num;
64 }
65
66 14 extension_fptr lbm_get_extension(lbm_uint sym) {
67 14 lbm_uint ext_next = sym - EXTENSION_SYMBOLS_START;
68
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ext_next >= ext_max) {
69 return NULL;
70 }
71 14 return extension_table[ext_next].fptr;
72 }
73
74 bool lbm_clr_extension(lbm_uint sym_id) {
75 lbm_uint ext_id = SYMBOL_IX(sym_id);
76 if (ext_id >= ext_max) {
77 return false;
78 }
79 extension_table[ext_id].name = NULL;
80 extension_table[ext_id].fptr = lbm_extensions_default;
81 return true;
82 }
83
84 14 bool lbm_lookup_extension_id(char *sym_str, lbm_uint *ix) {
85
1/2
✓ Branch 0 taken 1386 times.
✗ Branch 1 not taken.
1386 for (lbm_uint i = 0; i < ext_max; i ++) {
86
1/2
✓ Branch 0 taken 1386 times.
✗ Branch 1 not taken.
1386 if(extension_table[i].name) {
87
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1372 times.
1386 if (str_eq(extension_table[i].name, sym_str)) {
88 14 *ix = i + EXTENSION_SYMBOLS_START;
89 14 return true;
90 }
91 }
92 }
93 return false;
94 }
95
96 1709554 bool lbm_add_extension(char *sym_str, extension_fptr ext) {
97 lbm_value symbol;
98
99 // Check if symbol already exists.
100
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1709540 times.
1709554 if (lbm_get_symbol_by_name(sym_str, &symbol)) {
101
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
14 if (lbm_is_extension(lbm_enc_sym(symbol))) {
102 // update the extension entry.
103
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 if (str_eq(extension_table[SYMBOL_IX(symbol)].name, sym_str)) {
104 // Do not replace name ptr.
105 14 extension_table[SYMBOL_IX(symbol)].fptr = ext;
106 14 return true;
107 }
108 }
109 return false;
110 }
111
112
1/2
✓ Branch 0 taken 1709540 times.
✗ Branch 1 not taken.
1709540 if (next_extension_ix < ext_max) {
113 1709540 lbm_uint sym_ix = next_extension_ix ++;
114 1709540 extension_table[sym_ix].name = sym_str;
115 1709540 extension_table[sym_ix].fptr = ext;
116 1709540 ext_num ++;
117 1709540 return true;
118 }
119 return false;
120 }
121
122 // Helpers for extension developers:
123
124 2841 static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) {
125
2/2
✓ Branch 0 taken 8579 times.
✓ Branch 1 taken 2841 times.
11420 for (lbm_uint i = 0;i < argn;i++) {
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8579 times.
8579 if (!lbm_is_number(args[i])) {
127 return false;
128 }
129 }
130 2841 return true;
131 }
132
133 bool lbm_check_true_false(lbm_value v) {
134 bool res = lbm_is_symbol_true(v) || lbm_is_symbol_nil(v);
135 lbm_set_error_reason((char*)lbm_error_str_not_a_boolean);
136 return res;
137 }
138
139 2813 bool lbm_check_number_all(lbm_value *args, lbm_uint argn) {
140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2813 times.
2813 if (!lbm_is_number_all(args, argn)) {
141 lbm_set_error_reason((char*)lbm_error_str_no_number);
142 return false;
143 }
144 2813 return true;
145 }
146
147 bool lbm_check_argn(lbm_uint argn, lbm_uint n) {
148 if (argn != n) {
149 lbm_set_error_reason((char*)lbm_error_str_num_args);
150 return false;
151 } else {
152 return true;
153 }
154 }
155
156 28 bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) {
157
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (!lbm_is_number_all(args, argn)) {
158 lbm_set_error_reason((char*)lbm_error_str_no_number);
159 return false;
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 } else if (argn != n) {
161 lbm_set_error_reason((char*)lbm_error_str_num_args);
162 return false;
163 } else {
164 28 return true;
165 }
166 }
167