1 /* Low-level support for variables and properties in Xconq GDL.
2 Copyright (C) 1991-1996, 1998-2000 Stanley T. Shebs.
3
4 Xconq is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version. See the file COPYING. */
8
9 #include "config.h"
10 #include "misc.h"
11 #include "lisp.h"
12 #include "game.h"
13
14 /* The total number of unit/material/terrain/advance types. */
15
16 short numutypes;
17 short nummtypes;
18 short numttypes;
19 short numatypes;
20
21 /* These variables indicate whether new types can still be defined.
22 Once a table or list of types is manipulated, these are turned off. */
23
24 short canaddutype = TRUE;
25 short canaddmtype = TRUE;
26 short canaddttype = TRUE;
27 short canaddatype = TRUE;
28
29 /* This is the number of terrain types that can fill a cell. */
30
31 int numcelltypes = 0;
32
33 /* This is the number of terrain types that can be aux terrain. */
34
35 int numauxttypes = 0;
36
37 /* This is the number of terrain types that can be border terrain. */
38
39 int numbordtypes = 0;
40
41 /* This is the number of types that can be connections. */
42
43 int numconntypes = 0;
44
45 /* This is the number of types that can be coatings. */
46
47 int numcoattypes = 0;
48
49 /* This is an array listing all the aux types in order, typically used
50 to construct menus in interfaces. */
51
52 short *aux_terrain_type_index;
53
54 /* This is true if any terrain type has nonzero thickness. */
55
56 int any_thickness;
57
58 short first_auxt_type;
59 short *next_auxt_type = NULL;
60 short first_bord_type;
61 short *next_bord_type = NULL;
62 short first_conn_type;
63 short *next_conn_type = NULL;
64
65 int *tmp_u_array;
66 int *tmp_u2_array;
67 int *tmp_t_array;
68 int *tmp_m_array;
69 int *tmp_a_array;
70
71 int **tmp_uu_array;
72
73 /* It would be useful for these to mention the slot or table access that
74 resulted in the error, but we don't want to have to pass a bunch of
75 parameters to these routines, since they're referenced a lot. */
76
77 void
utype_error(int u)78 utype_error(int u)
79 {
80 run_warning("Bad utype %d", u);
81 }
82
83 void
mtype_error(int m)84 mtype_error(int m)
85 {
86 run_warning("Bad mtype %d", m);
87 }
88
89 void
ttype_error(int t)90 ttype_error(int t)
91 {
92 run_warning("Bad ttype %d", t);
93 }
94
95 void
atype_error(int a)96 atype_error(int a)
97 {
98 run_warning("Bad atype %d", a);
99 }
100
101 /* Declarations of the type definitions themselves. */
102
103 Utype *utypes;
104
105 Mtype *mtypes;
106
107 Ttype *ttypes;
108
109 Atype *atypes;
110
111 Globals globals;
112
113 /* These variables contain the current size of the type property
114 arrays. The values are arbitrary, since create_unit_type and
115 friend will increase these if necessary; so we pick values that
116 are large enough for most game designs. */
117
118 int curmaxutypes = 100;
119
120 int curmaxmtypes = 20;
121
122 int curmaxttypes = 40;
123
124 int curmaxatypes = 200;
125
126 /* This prepares the type definitions to be filled in, doing initial
127 allocations, etc. */
128
129 void
init_types(void)130 init_types(void)
131 {
132 numutypes = nummtypes = numttypes = numatypes = 0;
133
134 utypes = (Utype *) xmalloc(sizeof(Utype) * curmaxutypes);
135 mtypes = (Mtype *) xmalloc(sizeof(Mtype) * curmaxmtypes);
136 ttypes = (Ttype *) xmalloc(sizeof(Ttype) * curmaxttypes);
137 atypes = (Atype *) xmalloc(sizeof(Atype) * curmaxatypes);
138 }
139
140 VarDefn vardefns[] = {
141
142 #undef DEF_VAR_I
143 #define DEF_VAR_I(NAME,FNAME,SETFNAME,DOC,var,LO,DFLT,HI) \
144 { NAME, FNAME, NULL, NULL, SETFNAME, NULL, NULL, DOC, DFLT, NULL, NULL, LO, HI },
145 #undef DEF_VAR_S
146 #define DEF_VAR_S(NAME,FNAME,SETFNAME,DOC,var,DFLT) \
147 { NAME, NULL, FNAME, NULL, NULL, SETFNAME, NULL, DOC, 0, DFLT, NULL, 0, 0 },
148 #undef DEF_VAR_L
149 #define DEF_VAR_L(NAME,FNAME,SETFNAME,DOC,var,DFLT) \
150 { NAME, NULL, NULL, FNAME, NULL, NULL, SETFNAME, DOC, 0, NULL, DFLT, 0, 0 },
151
152 #include "gvar.def"
153
154 { NULL }
155 };
156
157 /* Define all the global-getting and -setting functions. */
158
159 #undef DEF_VAR_I
160 #define DEF_VAR_I(str,FNAME,SETFNAME,doc,VAR,lo,dflt,hi) \
161 int FNAME(void) { return globals.VAR; } \
162 void SETFNAME(int v) { globals.VAR = v; }
163 #undef DEF_VAR_S
164 #define DEF_VAR_S(str,FNAME,SETFNAME,doc,VAR,dflt) \
165 char *FNAME(void) { return globals.VAR; } \
166 void SETFNAME(char *v) { globals.VAR = v; }
167 #undef DEF_VAR_L
168 #define DEF_VAR_L(str,FNAME,SETFNAME,doc,VAR,DFLT) \
169 Obj *FNAME(void) { return globals.VAR; } \
170 void SETFNAME(Obj *v) { globals.VAR = v; }
171
172 #include "gvar.def"
173
174 /* Set the globals to their default values. For Lisp values, the default
175 is an initialization function rather than a value. */
176
177 void
init_globals(void)178 init_globals(void)
179 {
180 #undef DEF_VAR_I
181 #define DEF_VAR_I(str,fname,SETFNAME,doc,var,lo,DFLT,hi) \
182 SETFNAME(DFLT);
183 #undef DEF_VAR_S
184 #define DEF_VAR_S(str,fname,SETFNAME,doc,var,DFLT) \
185 SETFNAME(DFLT);
186 /* The 0 had been NULL but this was changed along with calls in gvar.def
187 after compile warnings from g++ */
188 #undef DEF_VAR_L
189 #define DEF_VAR_L(str,fname,SETFNAME,doc,var,DFLT) \
190 if ((DFLT) != 0) { \
191 Obj *(*fn)(void) = (DFLT); \
192 if (fn != NULL) SETFNAME((*fn)()); \
193 } else { \
194 SETFNAME(lispnil); \
195 }
196
197 #include "gvar.def"
198
199 }
200
201 /* Return the number of a new unit type, being careful to allocate
202 more space for unit properties if needed. */
203
204 int
create_unit_type(void)205 create_unit_type(void)
206 {
207 int u, newmax;
208 Utype *newutypes;
209
210 if (numutypes >= curmaxutypes) {
211 /* Double in size. This is reasonable because the type
212 structures are smallish, and don't need to grow very
213 often. */
214 newmax = curmaxutypes * 2;
215 /* This is similar to realloc, except that we need to be sure
216 that the new space is all zeros. */
217 newutypes = (Utype *) xmalloc(newmax * sizeof(Utype));
218 memcpy(newutypes, utypes, curmaxutypes * sizeof(Utype));
219 free(utypes);
220 utypes = newutypes;
221 curmaxutypes = newmax;
222 }
223 u = numutypes++;
224 return u;
225 }
226
227 /* Return the number of a new material type. */
228
229 int
create_material_type(void)230 create_material_type(void)
231 {
232 int m, newmax;
233 Mtype *newmtypes;
234
235 if (nummtypes >= curmaxmtypes) {
236 newmax = curmaxmtypes * 2;
237 newmtypes = (Mtype *) xmalloc(newmax * sizeof(Mtype));
238 memcpy(newmtypes, mtypes, curmaxmtypes * sizeof(Mtype));
239 free(mtypes);
240 mtypes = newmtypes;
241 curmaxmtypes = newmax;
242 }
243 m = nummtypes++;
244 return m;
245 }
246
247 /* Return the number of a new terrain type. */
248
249 int
create_terrain_type(void)250 create_terrain_type(void)
251 {
252 int t, newmax;
253 Ttype *newttypes;
254
255 if (numttypes >= curmaxttypes) {
256 newmax = curmaxttypes * 2;
257 newttypes = (Ttype *) xmalloc(newmax * sizeof(Ttype));
258 memcpy(newttypes, ttypes, curmaxttypes * sizeof(Ttype));
259 free(ttypes);
260 ttypes = newttypes;
261 curmaxttypes = newmax;
262 }
263 t = numttypes++;
264 return t;
265 }
266
267 /* Return the number of a new advance type. */
268
269 int
create_advance_type(void)270 create_advance_type(void)
271 {
272 int a, newmax;
273 Atype *newatypes;
274
275 if (numatypes >= curmaxatypes) {
276 newmax = curmaxatypes * 2;
277 newatypes = (Atype *) xmalloc(newmax * sizeof(Atype));
278 memcpy(newatypes, atypes, curmaxatypes * sizeof(Atype));
279 free(atypes);
280 atypes = newatypes;
281 curmaxatypes = newmax;
282 }
283 a = numatypes++;
284 return a;
285 }
286
287 #define TYPEPROP(TYPES, N, DEFNS, I, TYPE) \
288 ((TYPE *) &(((char *) (&(TYPES[N])))[DEFNS[I].offset]))[0]
289
290 /* This sets all the defaults in a unit type definition. Note that all
291 type structures get blasted with zeros initially, so we really only
292 need to do default settings of nonzero values, thus the test. (It
293 helps if the compiler is smart enough to remove dead code.) */
294
295 void
default_unit_type(int u)296 default_unit_type(int u)
297 {
298 int i;
299
300 for (i = 0; utypedefns[i].name != NULL; ++i) {
301 if (utypedefns[i].intgetter) {
302 if (utypedefns[i].dflt != 0)
303 TYPEPROP(utypes, u, utypedefns, i, short) = utypedefns[i].dflt;
304 } else if (utypedefns[i].strgetter) {
305 if (utypedefns[i].dfltstr != NULL)
306 TYPEPROP(utypes, u, utypedefns, i, char *) =
307 (char *) utypedefns[i].dfltstr;
308 } else {
309 TYPEPROP(utypes, u, utypedefns, i, Obj *) = lispnil;
310 }
311 }
312 }
313
314 /* This sets all the defaults in a material type definition. */
315
316 void
default_material_type(int m)317 default_material_type(int m)
318 {
319 int i;
320
321 for (i = 0; mtypedefns[i].name != NULL; ++i) {
322 if (mtypedefns[i].intgetter) {
323 if (mtypedefns[i].dflt != 0)
324 TYPEPROP(mtypes, m, mtypedefns, i, short) = mtypedefns[i].dflt;
325 } else if (mtypedefns[i].strgetter) {
326 if (mtypedefns[i].dfltstr != NULL)
327 TYPEPROP(mtypes, m, mtypedefns, i, char *) = (char *) mtypedefns[i].dfltstr;
328 } else {
329 TYPEPROP(mtypes, m, mtypedefns, i, Obj *) = lispnil;
330 }
331 }
332 }
333
334 /* This sets all the defaults in a terrain type definition. */
335
336 void
default_terrain_type(int t)337 default_terrain_type(int t)
338 {
339 int i;
340
341 for (i = 0; ttypedefns[i].name != NULL; ++i) {
342 if (ttypedefns[i].intgetter) {
343 if (ttypedefns[i].dflt != 0)
344 TYPEPROP(ttypes, t, ttypedefns, i, short) = ttypedefns[i].dflt;
345 } else if (ttypedefns[i].strgetter) {
346 if (ttypedefns[i].dfltstr != 0)
347 TYPEPROP(ttypes, t, ttypedefns, i, char *) = (char *) ttypedefns[i].dfltstr;
348 } else {
349 TYPEPROP(ttypes, t, ttypedefns, i, Obj *) = lispnil;
350 }
351 }
352 }
353
354 /* This sets all the defaults in an advance type definition. */
355
356 void
default_advance_type(int a)357 default_advance_type(int a)
358 {
359 int i;
360
361 for (i = 0; atypedefns[i].name != NULL; ++i) {
362 if (atypedefns[i].intgetter) {
363 if (atypedefns[i].dflt != 0)
364 TYPEPROP(atypes, a, atypedefns, i, short) = atypedefns[i].dflt;
365 } else if (atypedefns[i].strgetter) {
366 if (atypedefns[i].dfltstr != 0)
367 TYPEPROP(atypes, a, atypedefns, i, char *) = (char *) atypedefns[i].dfltstr;
368 } else {
369 TYPEPROP(atypes, a, atypedefns, i, Obj *) = lispnil;
370 }
371 }
372 }
373
374 char *
index_type_name(int x)375 index_type_name(int x)
376 {
377 return (char *)((x) == UTYP ? "unit"
378 : ((x) == MTYP ? "material"
379 : ((x) == TTYP ? "terrain"
380 : "advance")));
381 }
382
383 /* This function allocates a parameter table and fills it with a default. */
384
385 void
allocate_table(int tbl,int reset)386 allocate_table(int tbl, int reset)
387 {
388 int i, lim1, lim2, dflt = tabledefns[tbl].dflt;
389 short *rslt;
390
391 if (reset) *(tabledefns[tbl].table) = NULL;
392 if (*tabledefns[tbl].table == NULL) {
393 lim1 = numtypes_from_index_type(tabledefns[tbl].index1);
394 lim2 = numtypes_from_index_type(tabledefns[tbl].index2);
395 if (lim1 == 0) {
396 run_warning("Can't allocate the %s table, no %s types defined",
397 tabledefns[tbl].name,
398 index_type_name(tabledefns[tbl].index1));
399 return;
400 }
401 if (lim2 == 0) {
402 run_warning("Can't allocate the %s table, no %s types defined",
403 tabledefns[tbl].name,
404 index_type_name(tabledefns[tbl].index2));
405 return;
406 }
407 /* Allocate the table itself. */
408 rslt = (short *) xmalloc(lim1 * lim2 * sizeof(short));
409 /* Put the table's default everywhere in the table. */
410 for (i = 0; i < lim1 * lim2; ++i) rslt[i] = dflt;
411 *(tabledefns[tbl].table) = rslt;
412 /* For each index, flag that no more types of that sort allowed. */
413 switch (tabledefns[tbl].index1) {
414 case UTYP: disallow_more_unit_types(); break;
415 case MTYP: disallow_more_material_types(); break;
416 case TTYP: disallow_more_terrain_types(); break;
417 case ATYP: disallow_more_advance_types(); break;
418 }
419 switch (tabledefns[tbl].index2) {
420 case UTYP: disallow_more_unit_types(); break;
421 case MTYP: disallow_more_material_types(); break;
422 case TTYP: disallow_more_terrain_types(); break;
423 case ATYP: disallow_more_advance_types(); break;
424 }
425 }
426 }
427
428 int
numtypes_from_index_type(int x)429 numtypes_from_index_type(int x)
430 {
431 return ((x) == UTYP ? numutypes
432 : ((x) == MTYP ? nummtypes
433 : ((x) == TTYP ? numttypes
434 : numatypes)));
435 }
436
437 void
disallow_more_unit_types(void)438 disallow_more_unit_types(void)
439 {
440 int u = NONUTYPE;
441
442 canaddutype = FALSE;
443 if (tmp_u_array == NULL)
444 tmp_u_array = (int *) xmalloc(numutypes * sizeof(int));
445 if (!tmp_u2_array)
446 tmp_u2_array = (int *) xmalloc(numutypes * sizeof(int));
447 if (!tmp_uu_array) {
448 tmp_uu_array = (int **) xmalloc(numutypes * sizeof(int *));
449 for_all_unit_types(u)
450 tmp_uu_array[u] = (int *) xmalloc(numutypes * sizeof(int));
451 }
452 }
453
454 void
disallow_more_terrain_types(void)455 disallow_more_terrain_types(void)
456 {
457 canaddttype = FALSE;
458 if (tmp_t_array == NULL)
459 tmp_t_array = (int *) xmalloc(numttypes * sizeof(int));
460 if (next_auxt_type == NULL)
461 next_auxt_type = (short *) xmalloc(numttypes * sizeof(short));
462 if (next_bord_type == NULL)
463 next_bord_type = (short *) xmalloc(numttypes * sizeof(short));
464 if (next_conn_type == NULL)
465 next_conn_type = (short *) xmalloc(numttypes * sizeof(short));
466 if (aux_terrain_type_index == NULL)
467 aux_terrain_type_index = (short *) xmalloc(numttypes * sizeof(short));
468 count_terrain_subtypes();
469 }
470
471 /* Prevent more material types from being added, and prepare some integer
472 scratch space for doing math with materials types. */
473
474 void
disallow_more_material_types(void)475 disallow_more_material_types(void)
476 {
477 canaddmtype = FALSE;
478 if (tmp_m_array == NULL)
479 tmp_m_array = (int *) xmalloc(nummtypes * sizeof(int));
480 }
481
482 /* Prevent more advance types from being added, and prepare some integer
483 scratch space for doing math with advances types. */
484
485 void
disallow_more_advance_types(void)486 disallow_more_advance_types(void)
487 {
488 canaddatype = FALSE;
489 if (tmp_a_array == NULL)
490 tmp_a_array = (int *) xmalloc(numatypes * sizeof(int));
491 }
492
493 /* Calculate and cache some info about terrain types. */
494
495 void
count_terrain_subtypes(void)496 count_terrain_subtypes(void)
497 {
498 int t, i = 0, preva = -1, prevb = -1, prevc = -1;
499
500 /* Note that this function may be called several times. */
501 first_auxt_type = first_bord_type = first_conn_type = -1;
502
503 numcelltypes = numbordtypes = numconntypes = numcoattypes = 0;
504 numauxttypes = 0;
505 any_thickness = FALSE;
506 for_all_terrain_types(t) {
507 switch (t_subtype(t)) {
508 case bordersubtype: case connectionsubtype: case coatingsubtype:
509 ++numauxttypes;
510 if (preva < 0) {
511 first_auxt_type = t;
512 } else {
513 next_auxt_type[preva] = t;
514 }
515 preva = t;
516 aux_terrain_type_index[i++] = t;
517 break;
518 }
519 switch (t_subtype(t)) {
520 case cellsubtype:
521 ++numcelltypes;
522 break;
523 case bordersubtype:
524 ++numbordtypes;
525 if (prevb < 0) {
526 first_bord_type = t;
527 } else {
528 next_bord_type[prevb] = t;
529 }
530 prevb = t;
531 break;
532 case connectionsubtype:
533 ++numconntypes;
534 if (prevc < 0) {
535 first_conn_type = t;
536 } else {
537 next_conn_type[prevc] = t;
538 }
539 prevc = t;
540 break;
541 case coatingsubtype:
542 ++numcoattypes;
543 break;
544 }
545 if (t_thickness(t) > 0)
546 any_thickness = TRUE;
547 }
548 /* Mark the end of the links. */
549 if (preva >= 0)
550 next_auxt_type[preva] = -1;
551 if (prevb >= 0)
552 next_bord_type[prevb] = -1;
553 if (prevc >= 0)
554 next_conn_type[prevc] = -1;
555 }
556
557 //! Default value for table.
558
559 int
table_default(int (* getter)(int,int))560 table_default(int (*getter)(int, int))
561 {
562 int i = 0;
563
564 for (i = 0; tabledefns[i].name != NULL; ++i) {
565 if (tabledefns[i].getter == getter)
566 return tabledefns[i].dflt;
567 }
568 assert_error((tabledefns[i].name != NULL),
569 "Invalid table lookup attempted!");
570 return 0;
571 }
572
573 //! Default value for integer uprop.
574
575 short
uprop_i_default(int (* intgetter)(int))576 uprop_i_default(int (*intgetter)(int))
577 {
578 int i = 0;
579
580 for (i = 0; utypedefns[i].name != NULL; ++i) {
581 if (utypedefns[i].intgetter == intgetter)
582 return utypedefns[i].dflt;
583 }
584 assert_error((utypedefns[i].name != NULL),
585 "Invalid unit property lookup attempted!");
586 return 0;
587 }
588
589 //! Default value for string uprop.
590
591 char *
uprop_s_default(char * (* strgetter)(int))592 uprop_s_default(char *(*strgetter)(int))
593 {
594 int i = 0;
595
596 for (i = 0; utypedefns[i].name != NULL; ++i) {
597 if (utypedefns[i].strgetter == strgetter)
598 return utypedefns[i].dfltstr;
599 }
600 assert_error((utypedefns[i].name != NULL),
601 "Invalid unit property lookup attempted!");
602 return NULL;
603 }
604
605 //! Default value for Lisp uprop.
606
607 Obj *
uprop_l_default(Obj * (* objgetter)(int))608 uprop_l_default(Obj *(*objgetter)(int))
609 {
610 return lispnil;
611 }
612
613 //! Default value for integer tprop.
614
615 short
tprop_i_default(int (* intgetter)(int))616 tprop_i_default(int (*intgetter)(int))
617 {
618 int i = 0;
619
620 for (i = 0; ttypedefns[i].name != NULL; ++i) {
621 if (ttypedefns[i].intgetter == intgetter)
622 return ttypedefns[i].dflt;
623 }
624 assert_error((ttypedefns[i].name != NULL),
625 "Invalid terrain property lookup attempted!");
626 return 0;
627 }
628
629 //! Default value for string tprop.
630
631 char *
tprop_s_default(char * (* strgetter)(int))632 tprop_s_default(char *(*strgetter)(int))
633 {
634 int i = 0;
635
636 for (i = 0; ttypedefns[i].name != NULL; ++i) {
637 if (ttypedefns[i].strgetter == strgetter)
638 return ttypedefns[i].dfltstr;
639 }
640 assert_error((ttypedefns[i].name != NULL),
641 "Invalid terrain property lookup attempted!");
642 return 0;
643 }
644
645 //! Default value for Lisp tprop.
646
647 Obj *
tprop_l_default(Obj * (* objgetter)(int))648 tprop_l_default(Obj *(*objgetter)(int))
649 {
650 return lispnil;
651 }
652
653 //! Default value for integer mprop.
654
655 short
mprop_i_default(int (* intgetter)(int))656 mprop_i_default(int (*intgetter)(int))
657 {
658 int i = 0;
659
660 for (i = 0; mtypedefns[i].name != NULL; ++i) {
661 if (mtypedefns[i].intgetter == intgetter)
662 return mtypedefns[i].dflt;
663 }
664 assert_error((mtypedefns[i].name != NULL),
665 "Invalid material property lookup attempted!");
666 return 0;
667 }
668
669 //! Default value for string mprop.
670
671 char *
mprop_s_default(char * (* strgetter)(int))672 mprop_s_default(char *(*strgetter)(int))
673 {
674 int i = 0;
675
676 for (i = 0; mtypedefns[i].name != NULL; ++i) {
677 if (mtypedefns[i].strgetter == strgetter)
678 return mtypedefns[i].dfltstr;
679 }
680 assert_error((mtypedefns[i].name != NULL),
681 "Invalid material property lookup attempted!");
682 return 0;
683 }
684
685 //! Default value for Lisp mprop.
686
687 Obj *
mprop_l_default(Obj * (* objgetter)(int))688 mprop_l_default(Obj *(*objgetter)(int))
689 {
690 return lispnil;
691 }
692
693 //! Default value for integer aprop.
694
695 short
aprop_i_default(int (* intgetter)(int))696 aprop_i_default(int (*intgetter)(int))
697 {
698 int i = 0;
699
700 for (i = 0; atypedefns[i].name != NULL; ++i) {
701 if (atypedefns[i].intgetter == intgetter)
702 return atypedefns[i].dflt;
703 }
704 assert_error((atypedefns[i].name != NULL),
705 "Invalid advance property lookup attempted!");
706 return 0;
707 }
708
709 //! Default value for string aprop.
710
711 char *
aprop_s_default(char * (* strgetter)(int))712 aprop_s_default(char *(*strgetter)(int))
713 {
714 int i = 0;
715
716 for (i = 0; atypedefns[i].name != NULL; ++i) {
717 if (atypedefns[i].strgetter == strgetter)
718 return atypedefns[i].dfltstr;
719 }
720 assert_error((atypedefns[i].name != NULL),
721 "Invalid advance property lookup attempted!");
722 return 0;
723 }
724
725 //! Default value for Lisp aprop.
726
727 Obj *
aprop_l_default(Obj * (* objgetter)(int))728 aprop_l_default(Obj *(*objgetter)(int))
729 {
730 return lispnil;
731 }
732
733 //! Default value for integer gvar.
734
735 int
gvar_i_default(int (* intgetter)(void))736 gvar_i_default(int (*intgetter)(void))
737 {
738 int i = 0;
739
740 for (i = 0; vardefns[i].name != NULL; ++i) {
741 if (vardefns[i].intgetter == intgetter)
742 return vardefns[i].dflt;
743 }
744 assert_error((vardefns[i].name != NULL),
745 "Invalid global variable lookup attempted!");
746 return 0;
747 }
748
749 //! Default value for string gvar.
750
751 char *
gvar_s_default(char * (* strgetter)(void))752 gvar_s_default(char *(*strgetter)(void))
753 {
754 int i = 0;
755
756 for (i = 0; vardefns[i].name != NULL; ++i) {
757 if (vardefns[i].strgetter == strgetter)
758 return vardefns[i].dfltstr;
759 }
760 assert_error((vardefns[i].name != NULL),
761 "Invalid global variable lookup attempted!");
762 return NULL;
763 }
764
765 //! Default value for Lisp gvar.
766
767 Obj *
gvar_l_default(Obj * (* objgetter)(void))768 gvar_l_default(Obj *(*objgetter)(void))
769 {
770 int i = 0;
771
772 for (i = 0; vardefns[i].name != NULL; ++i) {
773 if (vardefns[i].objgetter == objgetter)
774 return (*(vardefns[i].dfltfn))();
775 }
776 assert_error((vardefns[i].name != NULL),
777 "Invalid global variable lookup attempted!");
778 return NULL;
779 }
780