GCC Code Coverage Report
Directory: ../src/ Exec Total Coverage
File: /home/joels/Current/lispbm/src/extensions.c Lines: 71 93 76.3 %
Date: 2025-01-19 11:10:47 Branches: 31 48 64.6 %

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
21588
int lbm_extensions_init(lbm_extension_t *extension_storage, lbm_uint extension_storage_size) {
42

21588
  if (extension_storage == NULL || extension_storage_size == 0) return 0;
43
44
21588
  extension_table = extension_storage;
45
21588
  memset(extension_table, 0, sizeof(lbm_extension_t) * extension_storage_size);
46
47
4339188
  for (lbm_uint i = 0; i < extension_storage_size; i ++) {
48
4317600
    extension_storage[i].fptr = lbm_extensions_default;
49
  }
50
51
21588
  ext_num = 0;
52
21588
  next_extension_ix = 0;
53
21588
  ext_max = (lbm_uint)extension_storage_size;
54
55
21588
  return 1;
56
}
57
58
645657804
lbm_uint lbm_get_max_extensions(void) {
59
645657804
  return ext_max;
60
}
61
62
21588
lbm_uint lbm_get_num_extensions(void) {
63
21588
  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
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
1428
  for (lbm_uint i = 0; i < ext_max; i ++) {
86
1428
    if(extension_table[i].name) {
87
1428
      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
2180430
bool lbm_add_extension(char *sym_str, extension_fptr ext) {
97
  lbm_value symbol;
98
99
  // Check if symbol already exists.
100
2180430
  if (lbm_get_symbol_by_name(sym_str, &symbol)) {
101
14
    if (lbm_is_extension(lbm_enc_sym(symbol))) {
102
      // update the extension entry.
103
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
2180416
  if (next_extension_ix < ext_max) {
113
2180416
    lbm_uint sym_ix = next_extension_ix ++;
114
2180416
    extension_table[sym_ix].name = sym_str;
115
2180416
    extension_table[sym_ix].fptr = ext;
116
2180416
    ext_num ++;
117
2180416
    return true;
118
  }
119
  return false;
120
}
121
122
// Helpers for extension developers:
123
124
3164
static bool lbm_is_number_all(lbm_value *args, lbm_uint argn) {
125
9940
  for (lbm_uint i = 0;i < argn;i++) {
126
6776
    if (!lbm_is_number(args[i])) {
127
      return false;
128
    }
129
  }
130
3164
  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
2212
bool lbm_check_number_all(lbm_value *args, lbm_uint argn) {
140
2212
  if (!lbm_is_number_all(args, argn)) {
141
    lbm_set_error_reason((char*)lbm_error_str_no_number);
142
    return false;
143
  }
144
2212
  return true;
145
}
146
147
84
bool lbm_check_argn(lbm_uint argn, lbm_uint n) {
148
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
952
  if (!lbm_is_number_all(args, argn)) {
158
    lbm_set_error_reason((char*)lbm_error_str_no_number);
159
    return false;
160
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
168
1792
lbm_value make_list(int num, ...) {
169
  va_list arguments;
170
1792
  va_start (arguments, num);
171
1792
  lbm_value res = ENC_SYM_NIL;
172
6216
  for (int i = 0; i < num; i++) {
173
4424
    res = lbm_cons(va_arg(arguments, lbm_value), res);
174
  }
175
1792
  va_end (arguments);
176
1792
  return lbm_list_destructive_reverse(res);
177
}
178
179
784
bool strmatch(const char *str1, const char *str2) {
180
784
  size_t len = strlen(str1);
181
182
784
  if (str2[len] != ' ') {
183
560
    return false;
184
  }
185
186
224
  bool same = true;
187
1736
  for (unsigned int i = 0;i < len;i++) {
188
1596
    if (str1[i] != str2[i]) {
189
84
      same = false;
190
84
      break;
191
    }
192
  }
193
194
224
  return same;
195
}