Coin Logo Coin3D is Free Software,
published under the BSD 3-clause license.
https://coin3d.github.io
https://www.kongsberg.com/en/kogt/
params.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) Kongsberg Oil & Gas Technologies
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif /* HAVE_CONFIG_H */
24 #include <simage.h>
25 #include <string.h>
26 #include <stdarg.h>
27 
29  int type;
30  char * name;
31  union {
33  float floatdata;
34  double doubledata;
35  char * stringdata;
36  void * pointerdata;
37  void (*functiondata)();
38  } data;
40 };
41 
42 typedef void s_generic_func();
43 
46 };
47 
48 s_params *
50 {
51  s_params * par = (s_params*) malloc(sizeof(s_params));
52  par->list = NULL;
53  return par;
54 }
55 
56 void
58 {
59  struct simage_param_data * next, * ptr = params->list;
60  while (ptr) {
61  next = ptr->next;
62  if (ptr->type == S_STRING_PARAM_TYPE &&
63  ptr->data.stringdata) free((void*)ptr->data.stringdata);
64  free((void*)ptr);
65  ptr = next;
66  }
67  free((void*)params);
68 }
69 
70 static struct simage_param_data *
71 find_param(s_params * params, const char * name, int type, int allocnew)
72 {
73  struct simage_param_data * last, * ptr;
74  last = NULL;
75  ptr = params->list;
76  while (ptr) {
77  last = ptr;
78  if (strcmp(ptr->name, name) == 0 && ptr->type == type) return ptr;
79  ptr = ptr->next;
80  }
81  if (allocnew) {
82  ptr = (struct simage_param_data*) malloc(sizeof(struct simage_param_data));
83  ptr->name = (char *) malloc(strlen(name)+1);
84  strcpy(ptr->name, name);
85  ptr->next = NULL;
86  ptr->type = type;
87  if (last) last->next = ptr;
88  else params->list = ptr;
89  }
90  return ptr;
91 }
92 
93 s_params *
95 {
96  struct simage_param_data * data;
97  struct simage_param_data * src;
98  s_params * par;
99 
100  if (params == NULL) return NULL;
101 
102  par = (s_params*) malloc(sizeof(s_params));
103  par->list = NULL;
104 
105  src = params->list;
106  while (src) {
107  data = find_param(par, src->name, src->type, 1);
108  switch (src->type) {
110  data->data.integerdata = src->data.integerdata;
111  break;
112  case S_FLOAT_PARAM_TYPE:
113  data->data.floatdata = src->data.floatdata;
114  break;
115  case S_DOUBLE_PARAM_TYPE:
116  data->data.doubledata = src->data.doubledata;
117  break;
118  case S_STRING_PARAM_TYPE:
119  data->data.stringdata = src->data.stringdata;
120  if (data->data.stringdata != NULL) {
121  data->data.stringdata = (char*) malloc(strlen(src->data.stringdata)+1);
122  strcpy(data->data.stringdata, src->data.stringdata);
123  }
124  break;
126  data->data.pointerdata = src->data.pointerdata;
127  break;
129  data->data.functiondata = src->data.functiondata;
130  break;
131  default:
132  assert(0);
133  break;
134  }
135  src = src->next;
136  }
137  return par;
138 }
139 
140 static void
141 add_integer_param(s_params * params, const char * name, int val)
142 {
143  struct simage_param_data * data = find_param(params, name, S_INTEGER_PARAM_TYPE, 1);
144  data->data.integerdata = val;
145 }
146 
147 static void
148 add_float_param(s_params * params, const char * name, float val)
149 {
150  struct simage_param_data * data = find_param(params, name, S_FLOAT_PARAM_TYPE, 1);
151  data->data.floatdata = val;
152 }
153 
154 static void
155 add_double_param(s_params * params, const char * name, double val)
156 {
157  struct simage_param_data * data = find_param(params, name, S_DOUBLE_PARAM_TYPE, 1);
158  data->data.doubledata = val;
159 }
160 
161 static void
162 add_string_param(s_params * params, const char * name, const char * val)
163 {
164  struct simage_param_data * data = find_param(params, name, S_STRING_PARAM_TYPE, 1);
165  data->data.stringdata = NULL;
166  if (val) {
167  data->data.stringdata = (char*) malloc(strlen(val)+1);
168  strcpy(data->data.stringdata, val);
169  }
170 }
171 
172 static void
173 add_pointer_param(s_params * params, const char * name, void * val)
174 {
175  struct simage_param_data * data = find_param(params, name, S_POINTER_PARAM_TYPE, 1);
176  data->data.pointerdata = val;
177 }
178 
179 static void
180 add_function_param(s_params * params, const char * name, void (*val)())
181 {
182  struct simage_param_data * data = find_param(params, name, S_FUNCTION_PARAM_TYPE, 1);
183  data->data.functiondata = val;
184 }
185 
186 void
187 s_params_set(s_params * params, ...)
188 {
189  int type;
190  int argerr;
191  const char * name;
192 
193  va_list ap;
194  va_start(ap, params);
195 
196  name = va_arg(ap, const char*);
197  while (name) {
198  type = va_arg(ap, int);
199  argerr = 0;
200  switch (type) {
201 
203  add_integer_param(params, name, va_arg(ap, int));
204  break;
205 
206  /* FIXME: one should never use 'float' as a type for va_arg, so
207  this type is bogus. see for instance
208 
209  http://c-faq.com/varargs/float.html
210 
211  -mortene
212  */
213  case S_FLOAT_PARAM_TYPE:
214 #if (__GNUC__ == 2 && __GNUC_MINOR__ == 96) || __GNUC__ >= 3
215  /* fix for silly bug in gcc 2.96 */
216  add_float_param(params, name, va_arg(ap, double));
217 #else /* ! gcc version 2.96 */
218  add_float_param(params, name, va_arg(ap, float));
219 #endif /* gcc version 2.96 */
220  break;
221 
222  case S_DOUBLE_PARAM_TYPE:
223  add_double_param(params, name, va_arg(ap, double));
224  break;
225 
226  case S_STRING_PARAM_TYPE:
227  add_string_param(params, name, va_arg(ap, const char*));
228  break;
229 
231  add_pointer_param(params, name, va_arg(ap, void *));
232  break;
233 
235  add_function_param(params, name, va_arg(ap, s_generic_func*));
236  break;
237 
238  default:
239  argerr = 1;
240  break;
241  }
242  if (argerr) break; /* whoa, get out of here */
243 
244  /* process next token */
245  name = va_arg(ap, const char*);
246  }
247  va_end(ap);
248 }
249 
250 int
251 s_params_get(s_params * params, ...)
252 {
253  int numok;
254  int type;
255  int argerr;
256  const char * name;
257  struct simage_param_data * data;
258 
259  va_list ap;
260  va_start(ap, params);
261 
262  numok = 0;
263 
264  name = va_arg(ap, const char*);
265  while (name) {
266  type = va_arg(ap, int);
267  argerr = 0;
268  switch (type) {
270  data = find_param(params, name, type, 0);
271  if (data) {
272  int * ptr = va_arg(ap, int*);
273  *ptr = data->data.integerdata;
274  numok++;
275  }
276  else argerr = 1;
277  break;
278  case S_FLOAT_PARAM_TYPE:
279  data = find_param(params, name, type, 0);
280  if (data) {
281  float * ptr = va_arg(ap, float*);
282  *ptr = data->data.floatdata;
283  numok++;
284  }
285  else argerr = 1;
286  break;
287  case S_DOUBLE_PARAM_TYPE:
288  data = find_param(params, name, type, 0);
289  if (data) {
290  double * ptr = va_arg(ap, double*);
291  *ptr = data->data.doubledata;
292  numok++;
293  }
294  else argerr = 1;
295  break;
296  case S_STRING_PARAM_TYPE:
297  data = find_param(params, name, type, 0);
298  if (data) {
299  char ** ptr = va_arg(ap, char**);
300  *ptr = data->data.stringdata;
301  numok++;
302  }
303  else argerr = 1;
304  break;
306  data = find_param(params, name, type, 0);
307  if (data) {
308  void ** ptr = va_arg(ap, void**);
309  *ptr = data->data.pointerdata;
310  numok++;
311  }
312  else argerr = 1;
313  break;
315  data = find_param(params, name, type, 0);
316  if (data) {
317  s_generic_func ** ptr = va_arg(ap, s_generic_func**);
318  *ptr = data->data.functiondata;
319  numok++;
320  }
321  else argerr = 1;
322  break;
323  default:
324  argerr = 1;
325  break;
326  }
327  if (argerr) break;
328  /* process next token */
329  name = va_arg(ap, const char*);
330  }
331  va_end(ap);
332  return numok;
333 }
double doubledata
Definition: params.c:34
void s_params_set(s_params *params,...)
Definition: params.c:187
int s_params_get(s_params *params,...)
Definition: params.c:251
void s_params_destroy(s_params *params)
Definition: params.c:57
static struct simage_param_data * find_param(s_params *params, const char *name, int type, int allocnew)
Definition: params.c:71
static void add_function_param(s_params *params, const char *name, void(*val)())
Definition: params.c:180
static void add_pointer_param(s_params *params, const char *name, void *val)
Definition: params.c:173
void * pointerdata
Definition: params.c:36
static void add_double_param(s_params *params, const char *name, double val)
Definition: params.c:155
union simage_param_data::@0 data
void s_generic_func()
Definition: params.c:42
Windows specific information.
struct simage_param_data * list
Definition: params.c:45
s_params * s_params_copy(s_params *params)
Definition: params.c:94
char * name
Definition: params.c:30
void(* functiondata)()
Definition: params.c:37
float floatdata
Definition: params.c:33
static void add_integer_param(s_params *params, const char *name, int val)
Definition: params.c:141
struct simage_param_data * next
Definition: params.c:39
static void add_string_param(s_params *params, const char *name, const char *val)
Definition: params.c:162
char * stringdata
Definition: params.c:35
s_params * s_params_create(void)
Definition: params.c:49
static void add_float_param(s_params *params, const char *name, float val)
Definition: params.c:148