1 enum { ID_VAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS };
2 
3 struct identstack
4 {
5     char *action;
6     int context;
7     identstack *next;
8 };
9 
10 struct ident
11 {
12     int type;           // one of ID_* above
13     const char *name;
14     bool isconst;
15     union
16     {
17         int minval;    // ID_VAR
18         float minvalf; // ID_FVAR
19     };
20     union
21     {
22         int maxval;    // ID_VAR
23         float maxvalf; // ID_FVAR
24     };
25     union
26     {
27         int *i;         // ID_VAR
28         float *f;       // ID_FVAR
29         char **s;       // ID_SVAR;
30     } storage;
31     union
32     {
33         void (*fun)();      // ID_VAR, ID_COMMAND
34         identstack *stack;  // ID_ALIAS
35     };
36     const char *sig;        // command signature
37     char *action, *executing; // ID_ALIAS
38     bool persist;
39 
40     int context;
41 
42 
identident43     ident() {}
44 
45     // ID_VAR
identident46     ident(int type, const char *name, int minval, int maxval, int *i, void (*fun)(), bool persist, int context)
47         : type(type), name(name), isconst(false), minval(minval), maxval(maxval), fun(fun),
48           sig(NULL), action(NULL), executing(NULL), persist(persist), context(context)
49     { storage.i = i; }
50 
51     // ID_FVAR
identident52     ident(int type, const char *name, float minval, float maxval, float *f, void (*fun)(), bool persist, int context)
53         : type(type), name(name), isconst(false), minvalf(minval), maxvalf(maxval), fun(fun),
54           sig(NULL), action(NULL), executing(NULL), persist(persist), context(context)
55     { storage.f = f; }
56 
57     // ID_SVAR
identident58     ident(int type, const char *name, char **s, void (*fun)(), bool persist, int context)
59         : type(type), name(name), isconst(false), minval(0), maxval(0), fun(fun),
60           sig(NULL), action(NULL), executing(NULL), persist(persist), context(context)
61     { storage.s = s; }
62 
63     // ID_ALIAS
identident64     ident(int type, const char *name, char *action, bool persist, int context)
65         : type(type), name(name), isconst(false), minval(0), maxval(0), stack(0),
66           sig(NULL), action(action), executing(NULL), persist(persist), context(context)
67     { storage.i = NULL; }
68 
69     // ID_COMMAND
identident70     ident(int type, const char *name, void (*fun)(), const char *sig, int context)
71         : type(type), name(name), isconst(false), minval(0), maxval(0), fun(fun),
72           sig(sig), action(NULL), executing(NULL), persist(false), context(context)
73     { storage.i = NULL; }
74 };
75 
76 enum { IEXC_CORE = 0, IEXC_CFG, IEXC_PROMPT, IEXC_MAPCFG, IEXC_MDLCFG, IEXC_NUM }; // script execution context
77 
78 // nasty macros for registering script functions, abuses globals to avoid excessive infrastructure
79 #define COMMANDN(name, fun, sig) static bool __dummy_##fun = addcommand(#name, (void (*)())fun, sig)
80 #define COMMAND(name, sig) COMMANDN(name, name, sig)
81 #define COMMANDF(name, sig, inlinefunc) static void __dummy_##name inlinefunc ; COMMANDN(name, __dummy_##name, sig)
82 
83 #define VARP(name, min, cur, max) int name = variable(#name, min, cur, max, &name, NULL, true)
84 #define VAR(name, min, cur, max)  int name = variable(#name, min, cur, max, &name, NULL, false)
85 #define VARN(name, global, min, cur, max) int global = variable(#name, min, cur, max, &global, NULL, false)
86 #define VARNP(name, global, min, cur, max) int global = variable(#name, min, cur, max, &global, NULL, true)
87 #define VARF(name, min, cur, max, body)  extern int name; void var_##name() { body; } int name = variable(#name, min, cur, max, &name, var_##name, false)
88 #define VARFP(name, min, cur, max, body) extern int name; void var_##name() { body; } int name = variable(#name, min, cur, max, &name, var_##name, true)
89 #define VARNFP(name, global, min, cur, max, body) extern int global; void var_##name() { body; } int global = variable(#name, min, cur, max, &global, var_##name, true)
90 
91 #define FVARP(name, min, cur, max) float name = fvariable(#name, min, cur, max, &name, NULL, true)
92 #define FVAR(name, min, cur, max)  float name = fvariable(#name, min, cur, max, &name, NULL, false)
93 #define FVARF(name, min, cur, max, body)  extern float name; void var_##name() { body; } float name = fvariable(#name, min, cur, max, &name, var_##name, false)
94 #define FVARFP(name, min, cur, max, body) extern float name; void var_##name() { body; } float name = fvariable(#name, min, cur, max, &name, var_##name, true)
95 
96 #define SVARP(name, cur) char *name = svariable(#name, cur, &name, NULL, true)
97 #define SVAR(name, cur)  char *name = svariable(#name, cur, &name, NULL, false)
98 #define SVARF(name, cur, body)  extern char *name; void var_##name() { body; } char *name = svariable(#name, cur, &name, var_##name, false)
99 #define SVARFP(name, cur, body) extern char *name; void var_##name() { body; } char *name = svariable(#name, cur, &name, var_##name, true)
100 
101 #define ATOI(s) strtol(s, NULL, 0)      // supports hexadecimal numbers
102 
103