GCC Code Coverage Report


Directory: ../src/
File: /home/joels/Current/lispbm/src/extensions.c
Date: 2024-11-05 17:11:09
Exec Total Coverage
Lines: 54 76 71.1%
Functions: 10 13 76.9%
Branches: 23 40 57.5%

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 21504 int lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) {
42
2/4
✓ Branch 0 taken 21504 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21504 times.
21504 if (extension_storage == NULL || extension_storage_size == 0) return 0;
43
44 21504 extension_table = extension_storage;
45 21504 memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size);
46
47
2/2
✓ Branch 0 taken 4300800 times.
✓ Branch 1 taken 21504 times.
4322304 for (lbm_uint i = 0; i < extension_storage_size; i ++) {
48 4300800 extension_storage[i].fptr = lbm_extensions_default;
49 }
50
51 21504 ext_num = 0;
52 21504 next_extension_ix = 0;
53 21504 ext_max = (lbm_uint)extension_storage_size;
54
55 21504 return 1;
56 }
57
58 661145999 lbm_uint lbm_get_max_extensions(void) {
59 661145999 return ext_max;
60 }
61
62 21504 lbm_uint lbm_get_num_extensions(void) {
63 21504 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 1498 times.
✗ Branch 1 not taken.
1498 for (lbm_uint i = 0; i < ext_max; i ++) {
86
1/2
✓ Branch 0 taken 1498 times.
✗ Branch 1 not taken.
1498 if(extension_table[i].name) {
87
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1484 times.
1498 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 2279466 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 2279452 times.
2279466 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 2279452 times.
✗ Branch 1 not taken.
2279452 if (next_extension_ix < ext_max) {
113 2279452 lbm_uint sym_ix = next_extension_ix ++;
114 2279452 extension_table[sym_ix].name = sym_str;
115 2279452 extension_table[sym_ix].fptr = ext;
116 2279452 ext_num ++;
117 2279452 return true;
118 }
119 return false;
120 }
121
122 // Helpers for extension developers:
123
124 3360 static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) {
125
2/2
✓ Branch 0 taken 7476 times.
✓ Branch 1 taken 3360 times.
10836 for (lbm_uint i = 0;i < argn;i++) {
126
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7476 times.
7476 if (!lbm_is_number(args[i])) {
127 return false;
128 }
129 }
130 3360 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 2408 bool lbm_check_number_all(lbm_value *args, lbm_uint argn) {
140
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2408 times.
2408 if (!lbm_is_number_all(args, argn)) {
141 lbm_set_error_reason((char*)lbm_error_str_no_number);
142 return false;
143 }
144 2408 return true;
145 }
146
147 84 bool lbm_check_argn(lbm_uint argn, lbm_uint n) {
148
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 56 times.
84 if (argn != n) {
149 28 lbm_set_error_reason((char*)lbm_error_str_num_args);
150 28 return false;
151 } else {
152 56 return true;
153 }
154 }
155
156 952 bool lbm_check_argn_number(lbm_value *args, lbm_uint argn, lbm_uint n) {
157
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 952 times.
952 if (!lbm_is_number_all(args, argn)) {
158 lbm_set_error_reason((char*)lbm_error_str_no_number);
159 return false;
160
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 532 times.
952 } else if (argn != n) {
161 420 lbm_set_error_reason((char*)lbm_error_str_num_args);
162 420 return false;
163 } else {
164 532 return true;
165 }
166 }
167