rc: add ability to define and use float variables
[rofl0r-gnuboy.git] / rcvars.c
blob95a9d27cd684f2f72f8376455a8d123e29bcb1ab
3 #undef _GNU_SOURCE
4 #define _GNU_SOURCE
5 #include <string.h>
6 #include <stdlib.h>
7 #include <ctype.h>
10 #include "defs.h"
11 #include "rc.h"
18 static rcvar_t *rcvars;
20 static int nvars;
26 void rc_export(rcvar_t *v)
28 const rcvar_t end = RCV_END;
30 if (!v) return;
31 nvars++;
32 rcvars = realloc(rcvars, sizeof (rcvar_t) * (nvars+1));
33 if (!rcvars)
34 die("out of memory adding rcvar %s\n", v->name);
35 rcvars[nvars-1] = *v;
36 rcvars[nvars] = end;
39 void rc_exportvars(rcvar_t *vars)
41 while(vars->type)
42 rc_export(vars++);
47 int rc_findvar(char *name)
49 int i;
50 if (!rcvars) return -1;
51 for (i = 0; rcvars[i].name; i++)
52 if (!strcmp(rcvars[i].name, name))
53 break;
54 if (!rcvars[i].name)
55 return -1;
56 return i;
60 int my_atoi(const char *s)
62 int a = 0;
63 if (*s == '0')
65 s++;
66 if (*s == 'x' || *s == 'X')
68 s++;
69 while (*s)
71 if (isdigit(*s))
72 a = (a<<4) + *s - '0';
73 else if (strchr("ABCDEF", *s))
74 a = (a<<4) + *s - 'A' + 10;
75 else if (strchr("abcdef", *s))
76 a = (a<<4) + *s - 'a' + 10;
77 else return a;
78 s++;
80 return a;
82 while (*s)
84 if (strchr("01234567", *s))
85 a = (a<<3) + *s - '0';
86 else return a;
87 s++;
89 return a;
91 if (*s == '-')
93 s++;
94 for (;;)
96 if (isdigit(*s))
97 a = (a*10) + *s - '0';
98 else return -a;
99 s++;
102 while (*s)
104 if (isdigit(*s))
105 a = (a*10) + *s - '0';
106 else return a;
107 s++;
109 return a;
113 /* i - index of variable in rcvars array
114 c - count of values in v string array
115 v - the actual values as string array */
116 int rc_setvar_n(int i, int c, char **v)
118 int j;
119 int *n;
120 float *f;
121 char **s;
123 switch (rcvars[i].type)
125 case rcv_int:
126 if (c < 1) return -1;
127 n = (int *)rcvars[i].mem;
128 *n = my_atoi(v[0]);
129 return 0;
130 case rcv_float:
131 if (c < 1) return -1;
132 f = (float *)rcvars[i].mem;
133 *f = atof(v[0]);
134 return 0;
135 case rcv_string:
136 if (c < 1) return -1;
137 s = (char **)rcvars[i].mem;
138 if (*s) free(*s);
139 *s = strdup(v[0]);
140 if (!*s)
141 die("out of memory setting rcvar %s\n", rcvars[i].name);
142 return 0;
143 case rcv_vector:
144 if (c > rcvars[i].len)
145 c = rcvars[i].len;
146 for (j = 0; j < c ; j++)
147 ((int *)rcvars[i].mem)[j] = my_atoi(v[j]);
148 return 0;
149 case rcv_bool:
150 if (c < 1 || atoi(v[0]) || strchr("yYtT", v[0][0]))
151 *(int *)rcvars[i].mem = 1;
152 else if (strchr("0nNfF", v[0][0]))
153 *(int *)rcvars[i].mem = 0;
154 else
155 return -1;
156 return 0;
158 return -1;
162 int rc_setvar(char *name, int c, char **v)
164 int i;
166 i = rc_findvar(name);
167 if (i < 0) return i;
169 return rc_setvar_n(i, c, v);
173 void *rc_getmem_n(int i)
175 return rcvars[i].mem;
179 void *rc_getmem(char *name)
181 int i;
182 i = rc_findvar(name);
183 if (i < 0) return NULL;
184 return rcvars[i].mem;
187 int rc_getint_n(int i)
189 if (i < 0) return 0;
190 switch (rcvars[i].type)
192 case rcv_int:
193 case rcv_bool:
194 return *(int *)rcvars[i].mem;
196 return 0;
199 float rc_getfloat_n(int i)
201 if (i < 0) return 0.0;
202 switch (rcvars[i].type)
204 case rcv_float:
205 return *(float *)rcvars[i].mem;
207 return 0.0;
210 int *rc_getvec_n(int i)
212 if (i < 0) return NULL;
213 switch (rcvars[i].type)
215 case rcv_int:
216 case rcv_bool:
217 case rcv_vector:
218 return (int *)rcvars[i].mem;
220 return NULL;
223 char *rc_getstr_n(int i)
225 if (i < 0) return 0;
226 switch (rcvars[i].type)
228 case rcv_string:
229 return *(char **)rcvars[i].mem;
231 return 0;
234 int rc_getint(char *name)
236 return rc_getint_n(rc_findvar(name));
239 float rc_getfloat(char *name)
241 return rc_getfloat_n(rc_findvar(name));
244 int *rc_getvec(char *name)
246 return rc_getvec_n(rc_findvar(name));
249 char *rc_getstr(char *name)
251 return rc_getstr_n(rc_findvar(name));
254 const char *rc_type_to_string(rcvtype_t type) {
255 switch (type) {
256 case rcv_int: return "int";
257 case rcv_float: return "float";
258 case rcv_string: return "str";
259 case rcv_vector: return "vec";
260 case rcv_bool: return "bool";
261 default: return "unknown";