dynamiC  0.1
dynamic.c
Go to the documentation of this file.
1 
15 #include "dynamic.h"
16 #include <stdio.h>
17 
18 
30 void dyn_free (dyn_c* dyn)
31 {
32  switch (DYN_TYPE(dyn)) {
33  case STRING: free(dyn->data.str);
34  break;
35 #ifdef S2_SET
36  case SET:
37 #endif
38  case LIST: dyn_list_free(dyn);
39  break;
40  case DICT: dyn_dict_free(dyn);
41  break;
42  case FUNCTION: dyn_fct_free(dyn);
43  }
44  dyn->type=NONE;
45 }
46 
56 TYPE dyn_type (const dyn_c* dyn)
57 {
58  return (TYPE)DYN_TYPE(dyn);
59 }
60 
67 void dyn_set_none (dyn_c* dyn)
68 {
69  dyn_free(dyn);
70  dyn->data.i = 0;
71 }
72 
77 void dyn_set_bool (dyn_c* dyn, const dyn_char v)
78 {
79  dyn_free(dyn);
80  dyn->type = BOOL;
81  dyn->data.b = v;
82 }
83 
88 void dyn_set_int (dyn_c* dyn, const dyn_int v)
89 {
90  dyn_free(dyn);
91  dyn->type = INTEGER;
92  dyn->data.i = v;
93 }
94 
99 void dyn_set_float (dyn_c* dyn, const dyn_float v)
100 {
101  dyn_free(dyn);
102  dyn->type = FLOAT;
103  dyn->data.f = v;
104 }
105 
112 void dyn_set_extern (dyn_c* dyn, const void * v)
113 {
114  dyn_free(dyn);
115  dyn->type = EXTERN;
116  dyn->data.ex = v;
117 }
118 
129 {
130  dyn_free(dyn);
131 
132  dyn->data.str = (dyn_str) malloc(dyn_strlen((dyn_str)v)+1);
133 
134  if (dyn->data.str) {
135  dyn->type = STRING;
136  dyn_strcpy(dyn->data.str, (dyn_str)v);
137  return DYN_TRUE;
138  }
139  return DYN_FALSE;
140 }
141 
149 void dyn_set_ref (dyn_c* ref, dyn_c* orig)
150 {
151  dyn_free(ref);
152 
153  ref->type = REFERENCE;
154  ref->data.ref = DYN_IS_REFERENCE(orig) ? orig->data.ref : orig;
155 }
156 
164 dyn_uint dyn_size (const dyn_c* dyn)
165 {
166  dyn_uint bytes = sizeof(dyn_c);
167 
168  dyn_ushort len, i = 0;
169 
170  switch (DYN_TYPE(dyn)) {
171  case STRING:
172  bytes += dyn_strlen(dyn->data.str)+1;
173  break;
174 #ifdef S2_SET
175  case SET:
176 #endif
177  case LIST: {
178  bytes += sizeof(dyn_list);
179 
180  len = dyn->data.list->space;
181  for (; i<len; ++i)
182  bytes += dyn_size( DYN_LIST_GET_REF(dyn, i) );
183 
184  break;
185  }
186  case DICT: {
187  bytes += sizeof(dyn_dict);
188  bytes += dyn_size(&dyn->data.dict->value);
189 
190  len = dyn->data.dict->value.data.list->space;
191  for (; i<len; ++i) {
192  if (dyn->data.dict->key[i])
193  bytes += dyn_strlen(dyn->data.dict->key[i]);
194  bytes++;
195  }
196 
197  break;
198  }
199  case FUNCTION: {
200  bytes += sizeof(dyn_fct);
201  bytes += dyn_strlen(dyn->data.fct->info) + 1;
202  break;
203  }
204  }
205 
206  return bytes;
207 }
208 
242 {
243 START:
244  switch (DYN_TYPE(dyn)) {
245  case BOOL: return dyn->data.b ? DYN_TRUE : DYN_FALSE;
246  case INTEGER: return dyn->data.i ? DYN_TRUE : DYN_FALSE;
247  case FLOAT: return dyn->data.f ? DYN_TRUE : DYN_FALSE;
248 
249  case STRING:
250 #ifdef S2_SET
251  case SET:
252 #endif
253  case LIST:
254  case DICT:
255  return dyn_length(dyn);// ? DYN_TRUE : DYN_FALSE;
256  case REFERENCE2:
257  case REFERENCE: dyn=dyn->data.ref;
258  goto START;
259  }
260 
261  return DYN_FALSE;
262 }
263 
279 dyn_int dyn_get_int (const dyn_c* dyn)
280 {
281 START:
282  switch (DYN_TYPE(dyn)) {
283  case BOOL: return (dyn_int)dyn->data.b;
284  case INTEGER: return dyn->data.i;
285  case FLOAT: return (dyn_int)dyn->data.f;
286  case REFERENCE2:
287  case REFERENCE: dyn=dyn->data.ref;
288  goto START;
289  }
290  return DYN_FALSE;
291 }
292 
304 dyn_float dyn_get_float (const dyn_c* dyn)
305 {
306 START:
307  switch (DYN_TYPE(dyn)) {
308  case BOOL: return (dyn_float)dyn->data.b;
309  case INTEGER: return (dyn_float)dyn->data.i;
310  case FLOAT: return dyn->data.f;
311  case REFERENCE2:
312  case REFERENCE: dyn=dyn->data.ref;
313  goto START;
314  }
315  return 0.0/0.0; // Not a Number
316 }
317 
323 const void* dyn_get_extern (const dyn_c* dyn)
324 {
325  if (DYN_IS_REFERENCE(dyn))
326  dyn = dyn->data.ref;
327 
328  if(DYN_TYPE(dyn) == EXTERN)
329  return dyn->data.ex;
330 
331  return NULL;
332 }
333 
345 dyn_str dyn_get_string (const dyn_c* dyn)
346 {
347  if (DYN_IS_REFERENCE(dyn))
348  dyn = dyn->data.ref;
349 
350  dyn_str string = (dyn_str) malloc(dyn_string_len(dyn) + 1);
351  if (string) {
352  string[0] = '\0';
353  /*if (DYN_TYPE(dyn) == STRING)
354  dyn_strcpy(string, dyn->data.str);
355  else*/
356  dyn_string_add(dyn, string);
357  }
358 
359  return string;
360 }
361 
371 void dyn_string_add (const dyn_c* dyn, dyn_str string)
372 {
373 START:
374  switch (DYN_TYPE(dyn)) {
375  case BOOL:
376  dyn_strcat(string, dyn->data.b ? "1": "0");
377  return;
378  case INTEGER:
379  dyn_itoa(&string[dyn_strlen(string)], dyn->data.i);
380  return;
381  case FLOAT:
382  dyn_ftoa(&string[dyn_strlen(string)], dyn->data.f);
383  return;
384  case STRING:
385  dyn_strcat(string, dyn->data.str);
386  return;
387  case EXTERN:
388  dyn_strcat(string, "ex");
389  return;
390  case FUNCTION:
391  dyn_strcat(string, "FCT");
392  return;
393  case LIST:
394  dyn_list_string_add(dyn, string);
395  return;
396 #ifdef S2_SET
397  case SET: {
398  dyn_uint i = dyn_strlen(string);
399  dyn_list_string_add(dyn, string);
400  string[i] = '{';
401  string[dyn_strlen(string)-1] = '}';
402  return;
403  }
404 #endif
405  case DICT:
406  dyn_dict_string_add (dyn, string);
407  return;
408  case REFERENCE2:
409  case REFERENCE:
410  dyn=dyn->data.ref;
411  goto START;
412  case MISCELLANEOUS:
413  dyn_strcat(string, "$");
414  }
415 }
416 
422 dyn_ushort dyn_string_len (const dyn_c* dyn)
423 {
424 START:
425  switch (DYN_TYPE(dyn)) {
426  case REFERENCE2:
427  case REFERENCE: dyn=dyn->data.ref;
428  goto START;
429  case MISCELLANEOUS:
430  case BOOL: return 1;
431  case INTEGER: return dyn_itoa_len(dyn->data.i);
432  case FLOAT: return dyn_ftoa_len(dyn->data.f);
433  case EXTERN: return 2;
434  case FUNCTION: return 3;
435  case STRING: return dyn_strlen(dyn->data.str);
436 #ifdef S2_SET
437  case SET:
438 #endif
439  case LIST: return dyn_list_string_len(dyn);
440  case DICT: return dyn_dict_string_len(dyn);
441  }
442  return 0;
443 }
444 
454 trilean dyn_copy (const dyn_c* dyn, dyn_c* copy)
455 {
456  switch (DYN_TYPE(dyn)) {
457  case STRING: return dyn_set_string( copy, dyn->data.str );
458  case LIST: return dyn_list_copy ( dyn, copy );
459 #ifdef S2_SET
460  case SET: if ( !dyn_list_copy(dyn, copy) )
461  return DYN_FALSE;
462  copy->type = SET;
463  break;
464 #endif
465  case DICT: return dyn_dict_copy( dyn, copy );
466  case FUNCTION: return dyn_fct_copy ( dyn, copy );
467  case REFERENCE: return dyn_copy ( dyn->data.ref, copy );
468  default: *copy = *dyn;
469  }
470 
471  return DYN_TRUE;
472 }
473 
483 void dyn_move (dyn_c* from, dyn_c* to)
484 {
485  dyn_free(to);
486 
487  if (DYN_TYPE(from) == REFERENCE)
488  dyn_copy(from->data.ref, to);
489  else
490  *to = *from;
491 
492  DYN_INIT(from);
493 }
494 
504 dyn_ushort dyn_length (const dyn_c* dyn)
505 {
506 START:
507  switch (DYN_TYPE(dyn)) {
508  case STRING: return dyn_strlen(dyn->data.str);
509 #ifdef S2_SET
510  case SET:
511 #endif
512  case LIST: return DYN_LIST_LEN(dyn);
513  case DICT: return DYN_DICT_LEN(dyn);
514  case REFERENCE2:
515  case REFERENCE: dyn=dyn->data.ref;
516  goto START;
517  }
518 
519  return 0;
520 }
dyn_c * ref
reference pointer to dynamic elements
float 32 bit
Definition: dynamic_types.h:65
represents boolean false
Definition: dynamic_types.h:23
dyn_ushort dyn_itoa_len(dyn_int i)
Calculates the number of required characters for integer to string (decimal) conversion, minus increases the value by one.
const char * dyn_const_str
Standard dynamic C const string.
Definition: dynamic_types.h:39
represents boolean true
Definition: dynamic_types.h:24
dyn_list * list
pointer to dynamic list
int32_t dyn_int
32bit signed integer, standard Integer type.
Definition: dynamic_types.h:49
dyn_float dyn_get_float(const dyn_c *dyn)
Return float value of a dynamic element.
dictionary of type dyn_dict
Definition: dynamic_types.h:69
dyn_ushort dyn_strlen(dyn_const_str str)
Returns the length of an string.
void dyn_set_extern(dyn_c *dyn, const void *v)
Set dynamic element to point to an arbitrary value.
Definition: dynamic.c:112
void dyn_strcpy(dyn_str destination, dyn_const_str source)
Copy string.
void dyn_set_none(dyn_c *dyn)
Set dynamic element to NONE.
Definition: dynamic.c:67
void dyn_ftoa(dyn_str str, const dyn_float f)
Float to ASCII-string conversion (decimal).
uint32_t dyn_uint
32bit unsigned integer
Definition: dynamic_types.h:52
#define DYN_IS_REFERENCE(dyn)
Check if dynamic element is of type REFERENCE.
Definition: dynamic.h:46
dyn_char b
boolean value
struct dynamic_function dyn_fct
common dynamic procedure/bytecode data type
Definition: dynamic_types.h:89
dyn_c* for internal usage only
Definition: dynamic_types.h:73
void dyn_dict_string_add(const dyn_c *dict, dyn_str string)
Add the dict-string representation to string.
Definition: dynamic_dict.c:311
#define DYN_LIST_LEN(dyn)
Return list length.
Definition: dynamic.h:123
dyn_float f
float value
dyn_int dyn_get_int(const dyn_c *dyn)
Return integer value of a dynamic element.
const void * dyn_get_extern(const dyn_c *dyn)
Return pointer, stored in dyn->data.ex.
trilean dyn_set_string(dyn_c *dyn, dyn_const_str v)
Set dynamic element to STRING.
Definition: dynamic.c:128
dyn_int i
basic integer
Definition: dynamic_types.h:59
trilean dyn_copy(const dyn_c *dyn, dyn_c *copy)
Deep copy dynamic element.
Dynamic data types as part of the SelectScript-VM implementation.
dyn_ushort space
elements available
set of type dyn_list
Definition: dynamic_types.h:68
can be used for different purposes
Definition: dynamic_types.h:75
void*
Definition: dynamic_types.h:72
#define DYN_INIT(dyn)
Mandatory initialization for dynamic elements (NONE)
Definition: dynamic.h:38
function pointer of type dyn_fct
Definition: dynamic_types.h:71
#define DYN_LIST_GET_REF(dyn, i)
Return the reference to the ith element within a dynamic list.
Definition: dynamic.h:125
struct dynamic_list dyn_list
common dynamic list data type
Definition: dynamic_types.h:83
Boolean 0==False, 1==True.
Definition: dynamic_types.h:62
dyn_ushort dyn_ftoa_len(const dyn_float f)
Calculates the number of required characters for float to string (decimal) conversion, minus increases the value by one.
dyn_ushort dyn_dict_string_len(const dyn_c *dict)
Calculate the required string length.
Definition: dynamic_dict.c:293
dyn_uint dyn_size(const dyn_c *dyn)
Return the number of allocated bytes.
Definition: dynamic.c:164
dyn_str dyn_get_string(const dyn_c *dyn)
Return string representation value of a dynamic element.
trilean dyn_get_bool(const dyn_c *dyn)
Return boolean value of an dynamic element.
Definition: dynamic.c:241
list of type dyn_list
Definition: dynamic_types.h:67
char dyn_char
Basic 8bit signed integer.
Definition: dynamic_types.h:30
dyn_fct * fct
pointer to function
#define DYN_TYPE(dyn)
Return type value of a dynamic element.
Definition: dynamic.h:40
#define DYN_DICT_LEN(dyn)
Return number of elements within a dictionary.
Definition: dynamic.h:188
signed integer 32 bit
Definition: dynamic_types.h:64
char*
Definition: dynamic_types.h:66
uint16_t dyn_ushort
16bit unsigned integer
Definition: dynamic_types.h:43
void dyn_string_add(const dyn_c *dyn, dyn_str string)
Add string representation of dynamic element to string.
void dyn_move(dyn_c *from, dyn_c *to)
Move dynamic element to new reference, from is of type NONE afterwards.
void dyn_itoa(dyn_str str, dyn_int i)
Integer to ASCII-string conversion.
None type without any value.
Definition: dynamic_types.h:61
void dyn_set_bool(dyn_c *dyn, const dyn_char v)
Set dynamic element to BOOL (DYN_TRUE or DYN_FALSE)
Definition: dynamic.c:77
dyn_c*, explicite reference
Definition: dynamic_types.h:74
TYPE
Basic data type definitions.
Definition: dynamic_types.h:60
void dyn_set_float(dyn_c *dyn, const dyn_float v)
Set dynamic element to FLOAT.
Definition: dynamic.c:99
dyn_ushort dyn_string_len(const dyn_c *dyn)
Calculate length of string representation of dynamic element.
dyn_dict * dict
pointer to dynamic dictionary
dyn_c value
dynamic element of type dyn_list
dyn_int i
basic integer
trilean dyn_dict_copy(const dyn_c *dict, dyn_c *copy)
Copy the entire dict.
Definition: dynamic_dict.c:274
void dyn_strcat(dyn_str destination, dyn_const_str source)
Concatenate strings.
dyn_str * key
array to C strings used as identifiers
dyn_c * ref
reference pointer to dynamic elements
Definition: dynamic_types.h:66
dyn_str info
info string
trilean
basic return type for truth values
Definition: dynamic_types.h:22
trilean dyn_list_copy(const dyn_c *list, dyn_c *copy)
Make a deep copy of the entire list.
Definition: dynamic_list.c:308
dyn_ushort dyn_length(const dyn_c *dyn)
Reterns the length of an element.
void dyn_set_ref(dyn_c *ref, dyn_c *orig)
Set dynamic element as reference to another dynamic element.
Definition: dynamic.c:149
struct dynamic_dict dyn_dict
common dynamic dictionary data type
Definition: dynamic_types.h:86
void dyn_dict_free(dyn_c *dict)
Free all allocated memory.
Definition: dynamic_dict.c:245
void dyn_list_string_add(const dyn_c *list, dyn_str str)
Add string representation of a list to str.
Definition: dynamic_list.c:351
float dyn_float
basic float definition (32 bit)
Definition: dynamic_types.h:55
void dyn_free(dyn_c *dyn)
free allocated memory
Definition: dynamic.c:30
const void * ex
external (pointer to everything)
void dyn_list_free(dyn_c *list)
Free the allocated memory of the entire list and set it to NONE.
Definition: dynamic_list.c:67
char * dyn_str
Standard dynamic C string.
Definition: dynamic_types.h:36
char type
type definition
void dyn_set_int(dyn_c *dyn, const dyn_int v)
Set dynamic element to INTEGER.
Definition: dynamic.c:88
TYPE dyn_type(const dyn_c *dyn)
Return type value of a dynamic element.
Definition: dynamic.c:56
dyn_ushort dyn_list_string_len(const dyn_c *list)
Return the length of the string representation of a list.
Definition: dynamic_list.c:333
dyn_str str
pointer to character-array
struct dynamic dyn_c
common dynamic data type
Definition: dynamic_types.h:80
Basic container for dynamic data types.
Definition: dynamic_types.h:98