1 /*
2 * gretl -- Gnu Regression, Econometrics and Time-series Library
3 * Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
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
20 #include "libgretl.h"
21 #include "gretl_typemap.h"
22
23 struct type_map {
24 GretlType std; /* a "standard" type: non-array, non-reference */
25 GretlType stdref; /* the "reference" form of the standard type, if any */
26 GretlType plural; /* the associated array type, if any */
27 GretlType plref; /* reference form of array type, if any */
28 };
29
30 static struct type_map gretl_type_map[] = {
31 { GRETL_TYPE_MATRIX, GRETL_TYPE_MATRIX_REF,
32 GRETL_TYPE_MATRICES, GRETL_TYPE_MATRICES_REF},
33 { GRETL_TYPE_BUNDLE, GRETL_TYPE_BUNDLE_REF,
34 GRETL_TYPE_BUNDLES, GRETL_TYPE_BUNDLES_REF},
35 { GRETL_TYPE_STRING, GRETL_TYPE_STRING_REF,
36 GRETL_TYPE_STRINGS, GRETL_TYPE_STRINGS_REF},
37 { GRETL_TYPE_ARRAY, GRETL_TYPE_ARRAY_REF,
38 GRETL_TYPE_ARRAYS, GRETL_TYPE_ARRAYS_REF},
39 { GRETL_TYPE_LIST, GRETL_TYPE_LIST_REF,
40 GRETL_TYPE_LISTS, GRETL_TYPE_LISTS_REF},
41 { GRETL_TYPE_SERIES, GRETL_TYPE_SERIES_REF, 0, 0},
42 { GRETL_TYPE_DOUBLE, GRETL_TYPE_SCALAR_REF, 0, 0}
43 };
44
gretl_type_get_plural(GretlType type)45 GretlType gretl_type_get_plural (GretlType type)
46 {
47 int i, n = G_N_ELEMENTS(gretl_type_map);
48
49 if (type == 0) return 0;
50
51 for (i=0; i<n; i++) {
52 if (type == gretl_type_map[i].std) {
53 return gretl_type_map[i].plural;
54 }
55 }
56
57 return 0;
58 }
59
gretl_type_get_singular(GretlType type)60 GretlType gretl_type_get_singular (GretlType type)
61 {
62 int i, n = G_N_ELEMENTS(gretl_type_map);
63
64 if (type == 0) return 0;
65
66 for (i=0; i<n; i++) {
67 if (type == gretl_type_map[i].plural) {
68 return gretl_type_map[i].std;
69 }
70 }
71
72 return 0;
73 }
74
gretl_type_get_ref_type(GretlType type)75 GretlType gretl_type_get_ref_type (GretlType type)
76 {
77 int i, n = G_N_ELEMENTS(gretl_type_map);
78
79 if (type == 0) return 0;
80
81 for (i=0; i<n; i++) {
82 if (type == gretl_type_map[i].std) {
83 return gretl_type_map[i].stdref;
84 }
85 if (type == gretl_type_map[i].plural) {
86 return gretl_type_map[i].plref;
87 }
88 if (type == gretl_type_map[i].stdref ||
89 type == gretl_type_map[i].plref) {
90 /* allow pass-through */
91 return type;
92 }
93 }
94
95 return 0;
96 }
97
gretl_type_get_plain_type(GretlType type)98 GretlType gretl_type_get_plain_type (GretlType type)
99 {
100 int i, n = G_N_ELEMENTS(gretl_type_map);
101
102 if (type == 0) return 0;
103
104 for (i=0; i<n; i++) {
105 if (type == gretl_type_map[i].stdref) {
106 return gretl_type_map[i].std;
107 }
108 if (type == gretl_type_map[i].plref) {
109 return gretl_type_map[i].plural;
110 }
111 if (type == gretl_type_map[i].std ||
112 type == gretl_type_map[i].plural) {
113 /* allow pass-through */
114 return type;
115 }
116 }
117
118 return 0;
119 }
120
121 /**
122 * gretl_type_get_name:
123 * @type: a gretl type.
124 *
125 * Returns: the name of @type, or "invalid" on failure.
126 */
127
gretl_type_get_name(GretlType type)128 const char *gretl_type_get_name (GretlType type)
129 {
130 switch (type) {
131 case GRETL_TYPE_BOOL: return "bool";
132 case GRETL_TYPE_INT: return "int";
133 case GRETL_TYPE_UNSIGNED: return "unsigned";
134 case GRETL_TYPE_OBS: return "obs";
135 case GRETL_TYPE_DOUBLE: return "scalar";
136 case GRETL_TYPE_SERIES: return "series";
137 case GRETL_TYPE_USERIES: return "series";
138 case GRETL_TYPE_MATRIX: return "matrix";
139 case GRETL_TYPE_LIST: return "list";
140 case GRETL_TYPE_BUNDLE: return "bundle";
141 case GRETL_TYPE_ARRAY: return "array";
142 case GRETL_TYPE_STRING: return "string";
143 case GRETL_TYPE_SCALAR_REF: return "scalar *";
144 case GRETL_TYPE_SERIES_REF: return "series *";
145 case GRETL_TYPE_MATRIX_REF: return "matrix *";
146 case GRETL_TYPE_BUNDLE_REF: return "bundle *";
147 case GRETL_TYPE_ARRAY_REF: return "array *";
148 case GRETL_TYPE_STRING_REF: return "string *";
149 case GRETL_TYPE_LIST_REF: return "list *";
150
151 case GRETL_TYPE_STRINGS: return "strings";
152 case GRETL_TYPE_MATRICES: return "matrices";
153 case GRETL_TYPE_BUNDLES: return "bundles";
154 case GRETL_TYPE_LISTS: return "lists";
155 case GRETL_TYPE_ARRAYS: return "arrays";
156
157 case GRETL_TYPE_STRINGS_REF: return "strings *";
158 case GRETL_TYPE_MATRICES_REF: return "matrices *";
159 case GRETL_TYPE_BUNDLES_REF: return "bundles *";
160 case GRETL_TYPE_LISTS_REF: return "lists *";
161 case GRETL_TYPE_ARRAYS_REF: return "arrays *";
162
163 case GRETL_TYPE_DATE: return "date"; /* ODBC special */
164
165 case GRETL_TYPE_VOID: return "void";
166 case GRETL_TYPE_NUMERIC: return "numeric";
167 case GRETL_TYPE_NONE: return "null";
168 case GRETL_TYPE_ANY: return "any";
169 default:
170 return "invalid";
171 }
172 }
173
gretl_type_from_string(const char * s)174 GretlType gretl_type_from_string (const char *s)
175 {
176 const char *p;
177
178 if (!strncmp(s, "matrix", 6)) {
179 p = s + 6;
180 if (*p == '\0') {
181 return GRETL_TYPE_MATRIX;
182 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
183 return GRETL_TYPE_MATRIX_REF;
184 }
185 } else if (!strncmp(s, "series", 6)) {
186 p = s + 6;
187 if (*p == '\0') {
188 return GRETL_TYPE_SERIES;
189 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
190 return GRETL_TYPE_SERIES_REF;
191 }
192 } else if (!strncmp(s, "scalar", 6)) {
193 p = s + 6;
194 if (*p == '\0') {
195 return GRETL_TYPE_DOUBLE;
196 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
197 return GRETL_TYPE_SCALAR_REF;
198 }
199 } else if (!strncmp(s, "bundle", 6)) {
200 p = s + 6;
201 if (*p == 's') {
202 p++;
203 if (*p == '\0') {
204 return GRETL_TYPE_BUNDLES;
205 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
206 return GRETL_TYPE_BUNDLES_REF;
207 }
208 } else if (*p == '\0') {
209 return GRETL_TYPE_BUNDLE;
210 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
211 return GRETL_TYPE_BUNDLE_REF;
212 }
213 } else if (!strncmp(s, "array", 5)) {
214 p = s + 5;
215 if (*p == 's') {
216 p++;
217 if (*p == '\0') {
218 return GRETL_TYPE_ARRAYS;
219 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
220 return GRETL_TYPE_ARRAYS_REF;
221 }
222 } else if (*p == '\0') {
223 return GRETL_TYPE_ARRAY;
224 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
225 return GRETL_TYPE_ARRAY_REF;
226 }
227 } else if (!strncmp(s, "string", 6)) {
228 p = s + 6;
229 if (*p == 's') {
230 p++;
231 if (*p == '\0') {
232 return GRETL_TYPE_STRINGS;
233 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
234 return GRETL_TYPE_STRINGS_REF;
235 }
236 } else if (*p == '\0') {
237 return GRETL_TYPE_STRING;
238 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
239 return GRETL_TYPE_STRING_REF;
240 }
241 } else if (!strncmp(s, "matrices", 8)) {
242 p = s + 8;
243 if (*p == '\0') {
244 return GRETL_TYPE_MATRICES;
245 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
246 return GRETL_TYPE_MATRICES_REF;
247 }
248 } else if (!strncmp(s, "list", 4)) {
249 p = s + 4;
250 if (*p == 's') {
251 p++;
252 if (*p == '\0') {
253 return GRETL_TYPE_LISTS;
254 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
255 return GRETL_TYPE_LISTS_REF;
256 }
257 } else if (*p == '\0') {
258 return GRETL_TYPE_LIST;
259 } else if (!strcmp(p, " *") || !strcmp(p, "ref")) {
260 return GRETL_TYPE_LIST_REF;
261 }
262 } else if (!strncmp(s, "numeric", 7)) {
263 return GRETL_TYPE_NUMERIC;
264 } else {
265 /* aliases */
266 if (!strcmp(s, "bool")) return GRETL_TYPE_BOOL;
267 if (!strcmp(s, "boolean")) return GRETL_TYPE_BOOL;
268 if (!strcmp(s, "int")) return GRETL_TYPE_INT;
269 if (!strcmp(s, "unsigned")) return GRETL_TYPE_UNSIGNED;
270 if (!strcmp(s, "obs")) return GRETL_TYPE_OBS;
271 }
272
273 return GRETL_TYPE_NONE;
274 }
275
276 struct lookup {
277 const char *word;
278 GretlType type;
279 };
280
281 static const struct lookup gentypes[] = {
282 { "series", GRETL_TYPE_SERIES },
283 { "scalar", GRETL_TYPE_DOUBLE },
284 { "matrix", GRETL_TYPE_MATRIX },
285 { "string", GRETL_TYPE_STRING },
286 { "list", GRETL_TYPE_LIST },
287 { "bundle", GRETL_TYPE_BUNDLE },
288 { "strings", GRETL_TYPE_STRINGS },
289 { "matrices", GRETL_TYPE_MATRICES },
290 { "bundles", GRETL_TYPE_BUNDLES },
291 { "lists", GRETL_TYPE_LISTS },
292 { "arrays", GRETL_TYPE_ARRAYS },
293 };
294
gretl_get_gen_type(const char * s)295 GretlType gretl_get_gen_type (const char *s)
296 {
297 static GHashTable *ht;
298 gpointer p;
299 GretlType t = 0;
300
301 if (s == NULL) {
302 /* the clean-up signal */
303 if (ht != NULL) {
304 g_hash_table_destroy(ht);
305 ht = NULL;
306 }
307 return 0;
308 }
309
310 if (ht == NULL) {
311 int i, n = G_N_ELEMENTS(gentypes);
312
313 ht = g_hash_table_new(g_str_hash, g_str_equal);
314 for (i=0; i<n; i++) {
315 g_hash_table_insert(ht, (gpointer) gentypes[i].word,
316 GINT_TO_POINTER(gentypes[i].type));
317 }
318 }
319
320 p = g_hash_table_lookup(ht, s);
321 if (p != NULL) {
322 t = GPOINTER_TO_INT(p);
323 }
324
325 return t;
326 }
327
328 /* Note: this must agree with the doc for the typeof() function */
329
gretl_type_get_order(GretlType type)330 int gretl_type_get_order (GretlType type)
331 {
332 if (gretl_scalar_type(type)) {
333 return 1;
334 } else if (type == GRETL_TYPE_SERIES) {
335 return 2;
336 } else if (type == GRETL_TYPE_MATRIX) {
337 return 3;
338 } else if (type == GRETL_TYPE_STRING) {
339 return 4;
340 } else if (type == GRETL_TYPE_BUNDLE) {
341 return 5;
342 } else if (type == GRETL_TYPE_ARRAY) {
343 return 6;
344 } else if (type == GRETL_TYPE_LIST) {
345 return 7;
346 } else {
347 return 0;
348 }
349 }
350
gretl_is_array_type(GretlType type)351 int gretl_is_array_type (GretlType type)
352 {
353 return type == GRETL_TYPE_STRINGS ||
354 type == GRETL_TYPE_MATRICES ||
355 type == GRETL_TYPE_BUNDLES ||
356 type == GRETL_TYPE_LISTS ||
357 type == GRETL_TYPE_ARRAYS;
358 }
359
gretl_is_arrayable_type(GretlType type)360 int gretl_is_arrayable_type (GretlType type)
361 {
362 return type == GRETL_TYPE_STRING ||
363 type == GRETL_TYPE_MATRIX ||
364 type == GRETL_TYPE_BUNDLE ||
365 type == GRETL_TYPE_LIST ||
366 type == GRETL_TYPE_ARRAY;
367 }
368
gretl_is_scalar_type(GretlType type)369 int gretl_is_scalar_type (GretlType type)
370 {
371 return type == GRETL_TYPE_BOOL ||
372 type == GRETL_TYPE_INT ||
373 type == GRETL_TYPE_UNSIGNED ||
374 type == GRETL_TYPE_DOUBLE;
375 }
376
gretl_is_series_type(GretlType type)377 int gretl_is_series_type (GretlType type)
378 {
379 return type == GRETL_TYPE_SERIES ||
380 type == GRETL_TYPE_USERIES;
381 }
382
gretl_typemap_cleanup(void)383 void gretl_typemap_cleanup (void)
384 {
385 gretl_get_gen_type(NULL);
386 }
387