diff --git a/libc3/array.h b/libc3/array.h
index e7c7756..affc415 100644
--- a/libc3/array.h
+++ b/libc3/array.h
@@ -20,6 +20,7 @@ void array_clean (s_array *a);
s_array * array_init (s_array *a, const s_sym *type,
uw dimension, const uw *dimensions);
s_array * array_init_1 (s_array *a, s8 *p);
+s_array * array_init_cast (s_array *a, const s_tag *tag);
s_array * array_init_copy (s_array *a, const s_array *src);
/* Observers */
diff --git a/libc3/bool.h b/libc3/bool.h
index 0cf2999..210fcf0 100644
--- a/libc3/bool.h
+++ b/libc3/bool.h
@@ -22,7 +22,8 @@
#include "types.h"
/* Stack-allocation compatible functions */
-bool * bool_init_copy (bool *dest, const bool *src);
+bool * bool_init_cast (bool *b, const s_tag *tag);
+bool * bool_init_copy (bool *b, const bool *src);
/* Observers */
s_str * bool_inspect (bool *b, s_str *dest);
diff --git a/libc3/cfn.h b/libc3/cfn.h
index 5f07881..c0c5868 100644
--- a/libc3/cfn.h
+++ b/libc3/cfn.h
@@ -19,6 +19,7 @@
void cfn_clean (s_cfn *cfn);
s_cfn * cfn_init (s_cfn *cfn, const s_sym *name, s_list *arg_types,
const s_sym *result_type);
+s_cfn * cfn_init_cast (s_cfn *cfn, const s_tag *tag);
s_cfn * cfn_init_copy (s_cfn *cfn, const s_cfn *src);
/* Heap-allocation functions, call cfn_delete after use. */
diff --git a/libc3/character.h b/libc3/character.h
index 5805fd2..c52abdd 100644
--- a/libc3/character.h
+++ b/libc3/character.h
@@ -18,6 +18,7 @@
character character_1 (const s8 *p);
void character_hash_update (character c, t_hash *hash);
+character * character_init_cast (character *c, const s_tag *tag);
character * character_init_copy (character *c, const character *src);
bool character_is_digit (character c);
bool character_is_lowercase (character c);
diff --git a/libc3/env.c b/libc3/env.c
index 757de1f..0533d4a 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -50,8 +50,6 @@
s_env g_c3_env;
-static bool env_eval_array_cast (s_env *env, s_array *tmp,
- const s_tag *tag, u8 *data, uw size);
static s_env * env_init_args (s_env *env, int argc, s8 **argv);
void env_clean (s_env *env)
@@ -109,6 +107,7 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
{
u8 *data;
uw i;
+ f_init_cast init_cast;
uw item_size;
s_tag *tag;
s_array tmp;
@@ -122,50 +121,32 @@ bool env_eval_array (s_env *env, const s_array *array, s_array *dest)
return true;
}
assert(array->tags);
- if (! tmp.data &&
- ! (tmp.data = calloc(tmp.dimensions[0].count,
- tmp.dimensions[0].item_size))) {
- assert(! "env_eval_array: out of memory: data");
- errx(1, "env_eval_array: out of memory: data");
+ tmp.data = calloc(tmp.dimensions[0].count,
+ tmp.dimensions[0].item_size);
+ if (! tmp.data) {
+ warn("env_eval_array: failed to allocate memory");
+ assert(! "env_eval_array: failed to allocate memory");
return false;
}
+ init_cast = sym_to_init_cast(tmp.type);
data = tmp.data;
tag = tmp.tags;
i = 0;
while (i < tmp.count) {
- if (! env_eval_array_cast(env, &tmp, tag, data, item_size)) {
- array_clean(&tmp);
- return false;
- }
+ s_tag tag_eval;
+ if (! env_eval_tag(env, tag, &tag_eval))
+ goto ko;
+ if (! init_cast(data, &tag_eval))
+ goto ko;
data += item_size;
tag++;
i++;
}
*dest = tmp;
return true;
-}
-
-bool env_eval_array_cast (s_env *env, s_array *array, const s_tag *tag,
- u8 *data, uw size)
-{
- s_call call;
- s_tag tag_eval;
- const void *data_eval;
- assert(env);
- assert(array);
- assert(tag);
- assert(data);
- assert(size);
- if (! call_init_cast(&call, array->type, tag))
- return false;
- if (! env_eval_call(env, &call, &tag_eval)) {
- call_clean(&call);
- return false;
- }
- data_eval = tag_to_const_pointer(&tag_eval, array->type);
- memcpy(data, data_eval, size);
- call_clean(&call);
- return true;
+ ko:
+ array_clean(&tmp);
+ return false;
}
bool env_eval_array_tag (s_env *env, const s_array *array, s_tag *dest)
@@ -681,10 +662,9 @@ bool env_eval_quote (s_env *env, const s_quote *quote, s_tag *dest)
bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
{
uw i;
+ f_init_cast init_cast;
s_struct *t;
s_tag tag = {0};
- void *tag_data;
- uw tag_size;
s_tag tmp = {0};
assert(env);
assert(s);
@@ -704,24 +684,23 @@ bool env_eval_struct (s_env *env, const s_struct *s, s_tag *dest)
while (i < t->type.map.count) {
if (! env_eval_tag(env, s->tag + i, &tag))
goto ko;
- if (tag.type != t->type.map.value[i].type) {
+ init_cast = tag_type_to_init_cast(tag.type);
+ if (tag.type != t->type.map.value[i].type && ! init_cast) {
warnx("env_eval_struct:"
" invalid type %s for key %s, expected %s.",
tag_type_to_string(tag.type),
t->type.map.key[i].data.sym->str.ptr.ps8,
tag_type_to_string(t->type.map.value[i].type));
- tag_clean(&tag);
- goto ko;
+ goto ko_tag;
}
- tag_data = tag_to_pointer(&tag, tag_type_to_sym(tag.type));
- tag_size = tag_type_size(tag.type);
- if (tag_data && tag_size)
- memcpy((s8 *) t->data + t->type.offset[i],
- tag_data, tag_size);
+ if (! init_cast((s8 *) t->data + t->type.offset[i], &tag))
+ goto ko_tag;
i++;
}
*dest = tmp;
return true;
+ ko_tag:
+ tag_clean(&tag);
ko:
struct_clean(t);
return false;
diff --git a/libc3/f32.c b/libc3/f32.c
index eedbac7..dac366f 100644
--- a/libc3/f32.c
+++ b/libc3/f32.c
@@ -16,46 +16,63 @@
#include "tag.h"
#include "tag_type.h"
#include "f32.h"
+#include "u32.h"
-f32 f32_cast (s_tag *tag)
+f32 * f32_init_cast (f32 *x, const s_tag *tag)
{
switch (tag->type) {
case TAG_BOOL:
- return tag->data.bool ? 1.0f : 0.0f;
+ *x = tag->data.bool ? 1.0f : 0.0f;
+ return x;
case TAG_CHARACTER:
- return (f32) tag->data.character;
+ *x = (f32) tag->data.character;
+ return x;
case TAG_F32:
- return tag->data.f32;
+ *x = tag->data.f32;
+ return x;
case TAG_F64:
- return (f32) tag->data.f64;
+ *x = (f32) tag->data.f64;
+ return x;
case TAG_INTEGER:
- return integer_to_f32(&tag->data.integer);
+ *x = integer_to_f32(&tag->data.integer);
+ return x;
case TAG_SW:
- return (f32) tag->data.sw;
+ *x = (f32) tag->data.sw;
+ return x;
case TAG_S64:
- return (f32) tag->data.s64;
+ *x = (f32) tag->data.s64;
+ return x;
case TAG_S32:
- return (f32) tag->data.s32;
+ *x = (f32) tag->data.s32;
+ return x;
case TAG_S16:
- return (f32) tag->data.s16;
+ *x = (f32) tag->data.s16;
+ return x;
case TAG_S8:
- return (f32) tag->data.s8;
+ *x = (f32) tag->data.s8;
+ return x;
case TAG_U8:
- return (f32) tag->data.u8;
+ *x = (f32) tag->data.u8;
+ return x;
case TAG_U16:
- return (f32) tag->data.u16;
+ *x = (f32) tag->data.u16;
+ return x;
case TAG_U32:
- return (f32) tag->data.u32;
+ *x = (f32) tag->data.u32;
+ return x;
case TAG_U64:
- return (f32) tag->data.u64;
+ *x = (f32) tag->data.u64;
+ return x;
case TAG_UW:
- return (f32) tag->data.uw;
+ *x = (f32) tag->data.uw;
+ return x;
default:
break;
}
- errx(1, "f32_cast: cannot cast %s to f32",
- tag_type_to_string(tag->type));
- return 0;
+ warnx("f32_init_cast: cannot cast %s to f32",
+ tag_type_to_string(tag->type));
+ assert(! "f32_init_cast: cannot cast to f32");
+ return NULL;
}
f32 * f32_init_copy (f32 *x, const f32 *src)
@@ -65,3 +82,12 @@ f32 * f32_init_copy (f32 *x, const f32 *src)
*x = *src;
return x;
}
+
+f32 * f32_random (f32 *x)
+{
+ u32 i;
+ const u32 max = (1 << 24) - 1;
+ u32_random_uniform(max, &i);
+ *x = (f32) i / max;
+ return x;
+}
diff --git a/libc3/f32.h b/libc3/f32.h
index 0235a84..77a7687 100644
--- a/libc3/f32.h
+++ b/libc3/f32.h
@@ -15,7 +15,8 @@
#include "types.h"
-f32 f32_cast (s_tag *tag);
+f32 * f32_init_cast (f32 *x, const s_tag *tag);
f32 * f32_init_copy (f32 *x, const f32 *src);
+f32 * f32_random (f32 *x);
#endif /* LIBC3_F32_H */
diff --git a/libc3/f64.c b/libc3/f64.c
index 7cca28c..5c4f31b 100644
--- a/libc3/f64.c
+++ b/libc3/f64.c
@@ -17,46 +17,65 @@
#include "tag.h"
#include "tag_type.h"
#include "f64.h"
+#include "u64.h"
-f64 f64_cast (s_tag *tag)
+f64 * f64_init_cast (f64 *x, const s_tag *tag)
{
+ assert(tag);
+ assert(x);
switch (tag->type) {
case TAG_BOOL:
- return tag->data.bool ? 1.0 : 0.0;
+ *x = tag->data.bool ? 1.0 : 0.0;
+ return x;
case TAG_CHARACTER:
- return (f64) tag->data.character;
+ *x = (f64) tag->data.character;
+ return x;
case TAG_F32:
- return (f64) tag->data.f32;
+ *x = (f64) tag->data.f32;
+ return x;
case TAG_F64:
- return tag->data.f64;
+ *x = tag->data.f64;
+ return x;
case TAG_INTEGER:
- return integer_to_f64(&tag->data.integer);
+ *x = integer_to_f64(&tag->data.integer);
+ return x;
case TAG_SW:
- return (f64) tag->data.sw;
+ *x = (f64) tag->data.sw;
+ return x;
case TAG_S64:
- return (f64) tag->data.s64;
+ *x = (f64) tag->data.s64;
+ return x;
case TAG_S32:
- return (f64) tag->data.s32;
+ *x = (f64) tag->data.s32;
+ return x;
case TAG_S16:
- return (f64) tag->data.s16;
+ *x = (f64) tag->data.s16;
+ return x;
case TAG_S8:
- return (f64) tag->data.s8;
+ *x = (f64) tag->data.s8;
+ return x;
case TAG_U8:
- return (f64) tag->data.u8;
+ *x = (f64) tag->data.u8;
+ return x;
case TAG_U16:
- return (f64) tag->data.u16;
+ *x = (f64) tag->data.u16;
+ return x;
case TAG_U32:
- return (f64) tag->data.u32;
+ *x = (f64) tag->data.u32;
+ return x;
case TAG_U64:
- return (f64) tag->data.u64;
+ *x = (f64) tag->data.u64;
+ return x;
case TAG_UW:
- return (f64) tag->data.uw;
+ *x = (f64) tag->data.uw;
+ return x;
default:
break;
}
- errx(1, "f64_cast: cannot cast %s to f64",
- tag_type_to_string(tag->type));
- return 0;
+ warnx("f64_init_cast: cannot cast %s to f64",
+ tag_type_to_string(tag->type));
+ assert(! "f64_init_cast: cannot cast to f64");
+ return NULL;
}
f64 * f64_init_copy (f64 *x, const f64 *src)
@@ -67,8 +86,11 @@ f64 * f64_init_copy (f64 *x, const f64 *src)
return x;
}
-f64 * f64_random (f64 *dest)
+f64 * f64_random (f64 *x)
{
- *dest = (f64) arc4random() / U32_MAX;
- return dest;
+ u64 i;
+ const u64 max = ((u64) 1 << 53) - 1;
+ u64_random_uniform(max, &i);
+ *x = (f64) i / max;
+ return x;
}
diff --git a/libc3/f64.h b/libc3/f64.h
index 8d18ebc..d99f010 100644
--- a/libc3/f64.h
+++ b/libc3/f64.h
@@ -15,8 +15,8 @@
#include "types.h"
-f64 f64_cast (s_tag *tag);
+f64 * f64_init_cast (f64 *x, const s_tag *tag);
f64 * f64_init_copy (f64 *x, const f64 *src);
-f64 * f64_random (f64 *dest);
+f64 * f64_random (f64 *x);
#endif /* LIBC3_F64_H */
diff --git a/libc3/fact.h b/libc3/fact.h
index 8e952c3..3a648be 100644
--- a/libc3/fact.h
+++ b/libc3/fact.h
@@ -19,6 +19,7 @@
#define fact_clean(fact) do {} while(0)
s_fact * fact_init (s_fact *fact, const s_tag *subject,
const s_tag *predicate, const s_tag *object);
+s_fact * fact_init_cast (s_fact *fact, const s_tag *tag);
s_fact * fact_init_copy (s_fact *fact, const s_fact *src);
/* Observers */
diff --git a/libc3/fn.h b/libc3/fn.h
index abda44e..fe4328e 100644
--- a/libc3/fn.h
+++ b/libc3/fn.h
@@ -25,6 +25,7 @@
void fn_clean (s_fn *fn);
s_fn * fn_init (s_fn *fn);
s_fn * fn_init_1 (s_fn *fn, s8 *p);
+s_fn * fn_init_cast (s_fn *fn, const s_tag *tag);
s_fn * fn_init_copy (s_fn *fn, const s_fn *src);
/* Heap-allocation functions, call fn_delete after use. */
diff --git a/libc3/ident.h b/libc3/ident.h
index 3c74304..0617721 100644
--- a/libc3/ident.h
+++ b/libc3/ident.h
@@ -23,6 +23,7 @@
s_ident * ident_init (s_ident *ident, const s_sym *module,
const s_sym *sym);
s_ident * ident_init_1 (s_ident *ident, const s8 *p);
+s_ident * ident_init_cast (s_ident *ident, const s_tag *tag);
s_ident * ident_init_copy (s_ident *ident, const s_ident *src);
/* Modifiers */
diff --git a/libc3/integer.c b/libc3/integer.c
index f02cc68..74da7f4 100644
--- a/libc3/integer.c
+++ b/libc3/integer.c
@@ -20,6 +20,8 @@
#include "tag.h"
#include "tag_type.h"
+// TODO: errx -> warnx
+
s_integer * integer_abs (const s_integer *a, s_integer *dest)
{
sw r;
@@ -110,39 +112,39 @@ uw integer_bytes (const s_integer *i)
return (integer_bits(i) + 7) / 8;
}
-s_integer * integer_cast (const s_tag *tag, s_integer *dest)
+s_integer * integer_init_cast (s_integer *a, const s_tag *tag)
{
switch (tag->type) {
case TAG_BOOL:
- return integer_init_u8(dest, tag->data.bool ? 1 : 0);
+ return integer_init_u8(a, tag->data.bool ? 1 : 0);
case TAG_CHARACTER:
- return integer_init_u32(dest, tag->data.character);
+ return integer_init_u32(a, tag->data.character);
case TAG_F32:
- return integer_init_f32(dest, tag->data.f32);
+ return integer_init_f32(a, tag->data.f32);
case TAG_F64:
- return integer_init_f64(dest, tag->data.f64);
+ return integer_init_f64(a, tag->data.f64);
case TAG_INTEGER:
- return integer_copy(&tag->data.integer, dest);
+ return integer_init_copy(a, &tag->data.integer);
case TAG_SW:
- return integer_init_sw(dest, tag->data.sw);
+ return integer_init_sw(a, tag->data.sw);
case TAG_S64:
- return integer_init_s64(dest, tag->data.s64);
+ return integer_init_s64(a, tag->data.s64);
case TAG_S32:
- return integer_init_s32(dest, tag->data.s32);
+ return integer_init_s32(a, tag->data.s32);
case TAG_S16:
- return integer_init_s16(dest, tag->data.s16);
+ return integer_init_s16(a, tag->data.s16);
case TAG_S8:
- return integer_init_s8(dest, tag->data.s8);
+ return integer_init_s8(a, tag->data.s8);
case TAG_U8:
- return integer_init_u8(dest, tag->data.u8);
+ return integer_init_u8(a, tag->data.u8);
case TAG_U16:
- return integer_init_u16(dest, tag->data.u16);
+ return integer_init_u16(a, tag->data.u16);
case TAG_U32:
- return integer_init_u32(dest, tag->data.u32);
+ return integer_init_u32(a, tag->data.u32);
case TAG_U64:
- return integer_init_u64(dest, tag->data.u64);
+ return integer_init_u64(a, tag->data.u64);
case TAG_UW:
- return integer_init_uw(dest, tag->data.uw);
+ return integer_init_uw(a, tag->data.uw);
default:
break;
}
@@ -151,20 +153,10 @@ s_integer * integer_cast (const s_tag *tag, s_integer *dest)
return 0;
}
-void integer_clean (s_integer *dest)
-{
- assert(dest);
- mp_clear(&dest->mp_int);
-}
-
-s_integer * integer_copy (const s_integer *a, s_integer *dest)
+void integer_clean (s_integer *a)
{
- sw r;
assert(a);
- assert(dest);
- if ((r = mp_init_copy(&dest->mp_int, &a->mp_int)) != MP_OKAY)
- errx(1, "integer_copy: %s", mp_error_to_string(r));
- return dest;
+ mp_clear(&a->mp_int);
}
s_integer * integer_div (const s_integer *a, const s_integer *b,
@@ -216,10 +208,13 @@ s_integer * integer_init_1 (s_integer *i, const s8 *p)
s_integer * integer_init_copy (s_integer *a, const s_integer *src)
{
sw r;
- assert(a);
assert(src);
- if ((r = mp_init_copy(&a->mp_int, &src->mp_int)) != MP_OKAY)
- errx(1, "integer_init_copy: %s", mp_error_to_string(r));
+ assert(a);
+ if ((r = mp_init_copy(&a->mp_int, &src->mp_int)) != MP_OKAY) {
+ warnx("integer_init_copy: %s", mp_error_to_string(r));
+ assert(! "integer_init_copy: mp_init_copy");
+ return NULL;
+ }
return a;
}
@@ -397,14 +392,21 @@ s_integer * integer_new (void)
return integer_init(i);
}
-s_integer * integer_new_copy (const s_integer *a)
+s_integer * integer_new_copy (const s_integer *src)
{
- s_integer *dest;
- assert(a);
- dest = malloc(sizeof(s_integer));
- if (!dest)
- errx(1, "integer_new_copy: out of memory");
- return integer_copy(a, dest);
+ s_integer *a;
+ assert(src);
+ a = calloc(1, sizeof(s_integer));
+ if (! a) {
+ warn("integer_new_copy");
+ assert(! "integer_new_copy: failed to allocate memory");
+ return NULL;
+ }
+ if (! integer_init_copy(a, src)) {
+ free(a);
+ return NULL;
+ }
+ return a;
}
s_integer * integer_pow (const s_integer *a, const s_integer *b,
diff --git a/libc3/integer.h b/libc3/integer.h
index 0d01f0b..4f82744 100644
--- a/libc3/integer.h
+++ b/libc3/integer.h
@@ -28,7 +28,8 @@
/* Stack allocation compatible functions */
s_integer * integer_init (s_integer *i);
s_integer * integer_init_1 (s_integer *i, const s8 *p);
-s_integer * integer_init_copy (s_integer *a, const s_integer *x);
+s_integer * integer_init_cast (s_integer *a, const s_tag *tag);
+s_integer * integer_init_copy (s_integer *a, const s_integer *src);
s_integer * integer_init_f32 (s_integer *a, f32 x);
s_integer * integer_init_f64 (s_integer *a, f64 x);
s_integer * integer_init_s8 (s_integer *a, s8 x);
@@ -64,8 +65,6 @@ s_integer * integer_bor (const s_integer *a, const s_integer *b,
s_integer *dest);
s_integer * integer_bxor (const s_integer *a, const s_integer *b,
s_integer *dest);
-s_integer * integer_cast (const s_tag *tag, s_integer *dest);
-s_integer * integer_copy (const s_integer *a, s_integer *dest);
s_integer * integer_div (const s_integer *a, const s_integer *b,
s_integer *dest);
s_integer * integer_gcd (const s_integer *a, const s_integer *b,
diff --git a/libc3/list.h b/libc3/list.h
index 6a6ab09..f7dbab2 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -28,6 +28,7 @@
void list_clean (s_list **list);
s_list * list_init (s_list *list, s_list *next);
s_list * list_init_1 (s_list *list, const s8 *p, s_list *next);
+s_list ** list_init_cast (s_list **list, const s_tag *tag);
s_list ** list_init_copy (s_list **list, const s_list **src);
s_list * list_init_copy_tag (s_list *list, const s_tag *tag,
s_list *next);
diff --git a/libc3/map.c b/libc3/map.c
index f3776cf..b8fda6d 100644
--- a/libc3/map.c
+++ b/libc3/map.c
@@ -34,13 +34,13 @@ s_tag * map_access (const s_map *map, const s_tag *key, s_tag *value)
return map_get(map, key, value);
}
-s_map * map_cast (const s_tag *tag, s_map *map)
+s_map * map_init_cast (s_map *map, const s_tag *tag)
{
assert(tag);
- if (tag->type == TAG_MAP) {
- map_init_copy(map, &tag->data.map);
- return map;
- }
+ if (tag->type == TAG_MAP)
+ return map_init_copy(map, &tag->data.map);
+ warnx("map_init_cast: cannot cast %s to map",
+ tag_type_to_string(tag->type));
return NULL;
}
diff --git a/libc3/map.h b/libc3/map.h
index 8a539bf..2e54be5 100644
--- a/libc3/map.h
+++ b/libc3/map.h
@@ -19,6 +19,7 @@
void map_clean (s_map *map);
s_map * map_init (s_map *map, uw size);
s_map * map_init_1 (s_map *map, const s8 *p);
+s_map * map_init_cast (s_map *map, const s_tag *tag);
s_map * map_init_copy (s_map *map, const s_map *src);
s_map * map_init_from_lists (s_map *map, const s_list *keys,
const s_list *values);
diff --git a/libc3/ptag.h b/libc3/ptag.h
index 9198fef..af639c8 100644
--- a/libc3/ptag.h
+++ b/libc3/ptag.h
@@ -15,6 +15,7 @@
#include "types.h"
+p_tag * ptag_init_cast (p_tag *dest, const s_tag *tag);
p_tag * ptag_init_copy (p_tag *dest, const p_tag *src);
#endif /* LIBC3_PTAG_H */
diff --git a/libc3/ptr.h b/libc3/ptr.h
index 425fac7..f3ffc8a 100644
--- a/libc3/ptr.h
+++ b/libc3/ptr.h
@@ -17,6 +17,7 @@
/* Stack-allocation compatible functions. */
u_ptr_w * ptr_init (u_ptr_w *ptr, void *p);
+u_ptr_w * ptr_init_cast (u_ptr_w *ptr, const s_tag *tag);
u_ptr_w * ptr_init_copy (u_ptr_w *ptr, const u_ptr_w *src);
/* Heap-allocation functions, call ptr_delete after use. */
diff --git a/libc3/ptr_free.h b/libc3/ptr_free.h
index a68e7c0..a4d3ea7 100644
--- a/libc3/ptr_free.h
+++ b/libc3/ptr_free.h
@@ -19,6 +19,7 @@
after use. */
void ptr_free_clean (u_ptr_w *ptr_free);
u_ptr_w * ptr_free_init (u_ptr_w *ptr_free, void *p);
+u_ptr_w * ptr_free_init_cast (u_ptr_w *ptr_free, const s_tag *tag);
u_ptr_w * ptr_free_init_copy (u_ptr_w *ptr_free, const u_ptr_w *src);
/* Heap-allocation functions, call ptr_free_delete after use. */
diff --git a/libc3/quote.h b/libc3/quote.h
index 9ad70fa..177daaa 100644
--- a/libc3/quote.h
+++ b/libc3/quote.h
@@ -19,6 +19,7 @@
void quote_clean (s_quote *quote);
s_quote * quote_init (s_quote *quote, const s_tag *tag);
s_quote * quote_init_1 (s_quote *quote, const s8 *p);
+s_quote * quote_init_cast (s_quote *quote, const s_tag *src);
s_quote * quote_init_copy (s_quote *quote, const s_quote *src);
#endif /* LIBC3_QUOTE_H */
diff --git a/libc3/s.c.in b/libc3/s.c.in
index f851338..65bf0fa 100644
--- a/libc3/s.c.in
+++ b/libc3/s.c.in
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=_BITS$ bits=_bits$ */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ s_bits$ * s_bits$_init_copy (s_bits$ *dest, const s_bits$ *src)
*dest = *src;
return dest;
}
+
+s_bits$ * s_bits$_random (s_bits$ *dest)
+{
+ arc4random_buf(dest, sizeof(s_bits$));
+ return dest;
+}
diff --git a/libc3/s.h.in b/libc3/s.h.in
index e64d08b..6367b2d 100644
--- a/libc3/s.h.in
+++ b/libc3/s.h.in
@@ -16,7 +16,8 @@
#include "types.h"
-s_bits$ * s_bits$_cast (s_tag *tag, s_bits$ *dest);
+s_bits$ * s_bits$_init_cast (s_bits$ *dest, const s_tag *tag);
s_bits$ * s_bits$_init_copy (s_bits$ *dest, const s_bits$ *src);
+s_bits$ * s_bits$_random (s_bits$ *dest);
#endif /* LIBC3_S_BITS$_H */
diff --git a/libc3/s16.c b/libc3/s16.c
index 9fee096..da1e46c 100644
--- a/libc3/s16.c
+++ b/libc3/s16.c
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=16 bits=16 */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ s16 * s16_init_copy (s16 *dest, const s16 *src)
*dest = *src;
return dest;
}
+
+s16 * s16_random (s16 *dest)
+{
+ arc4random_buf(dest, sizeof(s16));
+ return dest;
+}
diff --git a/libc3/s16.h b/libc3/s16.h
index 4becf01..a146866 100644
--- a/libc3/s16.h
+++ b/libc3/s16.h
@@ -16,7 +16,8 @@
#include "types.h"
-s16 * s16_cast (s_tag *tag, s16 *dest);
+s16 * s16_init_cast (s16 *dest, const s_tag *tag);
s16 * s16_init_copy (s16 *dest, const s16 *src);
+s16 * s16_random (s16 *dest);
#endif /* LIBC3_S16_H */
diff --git a/libc3/s32.c b/libc3/s32.c
index 8a94b7d..31bc407 100644
--- a/libc3/s32.c
+++ b/libc3/s32.c
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=32 bits=32 */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ s32 * s32_init_copy (s32 *dest, const s32 *src)
*dest = *src;
return dest;
}
+
+s32 * s32_random (s32 *dest)
+{
+ arc4random_buf(dest, sizeof(s32));
+ return dest;
+}
diff --git a/libc3/s32.h b/libc3/s32.h
index aa3758b..434b2b4 100644
--- a/libc3/s32.h
+++ b/libc3/s32.h
@@ -16,7 +16,8 @@
#include "types.h"
-s32 * s32_cast (s_tag *tag, s32 *dest);
+s32 * s32_init_cast (s32 *dest, const s_tag *tag);
s32 * s32_init_copy (s32 *dest, const s32 *src);
+s32 * s32_random (s32 *dest);
#endif /* LIBC3_S32_H */
diff --git a/libc3/s64.c b/libc3/s64.c
index fa51c49..668d0ac 100644
--- a/libc3/s64.c
+++ b/libc3/s64.c
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=64 bits=64 */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ s64 * s64_init_copy (s64 *dest, const s64 *src)
*dest = *src;
return dest;
}
+
+s64 * s64_random (s64 *dest)
+{
+ arc4random_buf(dest, sizeof(s64));
+ return dest;
+}
diff --git a/libc3/s64.h b/libc3/s64.h
index b3c289c..46ac92c 100644
--- a/libc3/s64.h
+++ b/libc3/s64.h
@@ -16,7 +16,8 @@
#include "types.h"
-s64 * s64_cast (s_tag *tag, s64 *dest);
+s64 * s64_init_cast (s64 *dest, const s_tag *tag);
s64 * s64_init_copy (s64 *dest, const s64 *src);
+s64 * s64_random (s64 *dest);
#endif /* LIBC3_S64_H */
diff --git a/libc3/s8.c b/libc3/s8.c
index d2dd590..eb7ec40 100644
--- a/libc3/s8.c
+++ b/libc3/s8.c
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=8 bits=8 */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ s8 * s8_init_copy (s8 *dest, const s8 *src)
*dest = *src;
return dest;
}
+
+s8 * s8_random (s8 *dest)
+{
+ arc4random_buf(dest, sizeof(s8));
+ return dest;
+}
diff --git a/libc3/s8.h b/libc3/s8.h
index b5a253d..7c84127 100644
--- a/libc3/s8.h
+++ b/libc3/s8.h
@@ -16,7 +16,8 @@
#include "types.h"
-s8 * s8_cast (s_tag *tag, s8 *dest);
+s8 * s8_init_cast (s8 *dest, const s_tag *tag);
s8 * s8_init_copy (s8 *dest, const s8 *src);
+s8 * s8_random (s8 *dest);
#endif /* LIBC3_S8_H */
diff --git a/libc3/str.h b/libc3/str.h
index d98b7c2..e9b6cc2 100644
--- a/libc3/str.h
+++ b/libc3/str.h
@@ -31,6 +31,7 @@ void str_clean (s_str *str);
s_str * str_init (s_str *str, s8 *free, uw size, const s8 *p);
s_str * str_init_1 (s_str *str, s8 *free, const s8 *p);
s_str * str_init_alloc (s_str *str, uw size, const s8 *p);
+s_str * str_init_cast (s_str *str, const s_tag *tag);
s_str * str_init_copy (s_str *str, const s_str *src);
s_str * str_init_copy_1 (s_str *str, const s8 *p);
s_str * str_init_empty (s_str *str);
diff --git a/libc3/struct.c b/libc3/struct.c
index 69e5188..63a7e73 100644
--- a/libc3/struct.c
+++ b/libc3/struct.c
@@ -116,6 +116,17 @@ s_struct * struct_init_1 (s_struct *s, const s8 *p)
return s;
}
+s_struct * struct_init_cast (s_struct *s, const s_tag *tag)
+{
+ assert(s);
+ assert(tag);
+ if (tag->type == TAG_STRUCT)
+ return struct_init_copy(s, &tag->data.struct_);
+ warnx("struct_init_cast: cannot cast %s to struct",
+ tag_type_to_string(tag->type));
+ return NULL;
+}
+
s_struct * struct_init_copy (s_struct *s, const s_struct *src)
{
f_init_copy init_copy;
diff --git a/libc3/struct.h b/libc3/struct.h
index d448d80..495f0c8 100644
--- a/libc3/struct.h
+++ b/libc3/struct.h
@@ -24,6 +24,7 @@
void struct_clean (s_struct *s);
s_struct * struct_init (s_struct *s, const s_sym *module);
s_struct * struct_init_1 (s_struct *s, const s8 *p);
+s_struct * struct_init_cast (s_struct *s, const s_tag *tag);
s_struct * struct_init_copy (s_struct *s, const s_struct *src);
s_struct * struct_init_from_lists (s_struct *s, const s_sym *module,
const s_list *keys,
diff --git a/libc3/sw.c b/libc3/sw.c
index 0ec8bde..ee74817 100644
--- a/libc3/sw.c
+++ b/libc3/sw.c
@@ -13,6 +13,7 @@
/* Gen from s.h.in BITS=W bits=w */
#include <assert.h>
#include <err.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "tag_type.h"
@@ -81,3 +82,9 @@ sw * sw_init_copy (sw *dest, const sw *src)
*dest = *src;
return dest;
}
+
+sw * sw_random (sw *dest)
+{
+ arc4random_buf(dest, sizeof(sw));
+ return dest;
+}
diff --git a/libc3/sw.h b/libc3/sw.h
index b17b069..cb7cb11 100644
--- a/libc3/sw.h
+++ b/libc3/sw.h
@@ -16,7 +16,8 @@
#include "types.h"
-sw * sw_cast (s_tag *tag, sw *dest);
+sw * sw_init_cast (sw *dest, const s_tag *tag);
sw * sw_init_copy (sw *dest, const sw *src);
+sw * sw_random (sw *dest);
#endif /* LIBC3_SW_H */
diff --git a/libc3/sym.c b/libc3/sym.c
index c68618e..fda45ae 100644
--- a/libc3/sym.c
+++ b/libc3/sym.c
@@ -305,6 +305,8 @@ f_buf_inspect_size sym_to_buf_inspect_size (const s_sym *type)
return (f_buf_inspect_size) buf_inspect_tuple_size;
if (type == sym_1("Var"))
return (f_buf_inspect_size) buf_inspect_var_size;
+ if (type == sym_1("Void"))
+ return (f_buf_inspect_size) buf_inspect_void_size;
err_write_1("sym_to_buf_inspect_size: unknown type: ");
err_write_1(type->str.ptr.ps8);
err_write_1("\n");
@@ -446,6 +448,74 @@ ffi_type * sym_to_ffi_type (const s_sym *sym, ffi_type *result_type)
return NULL;
}
+f_init_cast sym_to_init_cast (const s_sym *type)
+{
+ if (type == sym_1("Bool"))
+ return (f_init_cast) bool_init_cast;
+ if (type == sym_1("Call"))
+ return (f_init_cast) call_init_cast;
+ if (type == sym_1("Cfn"))
+ return (f_init_cast) cfn_init_cast;
+ if (type == sym_1("Character"))
+ return (f_init_cast) character_init_cast;
+ if (type == sym_1("F32"))
+ return (f_init_cast) f32_init_cast;
+ if (type == sym_1("F64"))
+ return (f_init_cast) f64_init_cast;
+ if (type == sym_1("Fact"))
+ return (f_init_cast) fact_init_cast;
+ if (type == sym_1("Fn"))
+ return (f_init_cast) fn_init_cast;
+ if (type == sym_1("Ident"))
+ return (f_init_cast) ident_init_cast;
+ if (type == sym_1("Integer"))
+ return (f_init_cast) integer_init_cast;
+ if (type == sym_1("List"))
+ return (f_init_cast) list_init_cast;
+ if (type == sym_1("Sw"))
+ return (f_init_cast) sw_init_cast;
+ if (type == sym_1("S64"))
+ return (f_init_cast) s64_init_cast;
+ if (type == sym_1("S32"))
+ return (f_init_cast) s32_init_cast;
+ if (type == sym_1("S16"))
+ return (f_init_cast) s16_init_cast;
+ if (type == sym_1("S8"))
+ return (f_init_cast) s8_init_cast;
+ if (type == sym_1("U8"))
+ return (f_init_cast) u8_init_cast;
+ if (type == sym_1("U16"))
+ return (f_init_cast) u16_init_cast;
+ if (type == sym_1("U32"))
+ return (f_init_cast) u32_init_cast;
+ if (type == sym_1("U64"))
+ return (f_init_cast) u64_init_cast;
+ if (type == sym_1("Uw"))
+ return (f_init_cast) uw_init_cast;
+ if (type == sym_1("Ptag"))
+ return (f_init_cast) ptag_init_cast;
+ if (type == sym_1("Ptr"))
+ return (f_init_cast) ptr_init_cast;
+ if (type == sym_1("PtrFree"))
+ return (f_init_cast) ptr_free_init_cast;
+ if (type == sym_1("Quote"))
+ return (f_init_cast) quote_init_cast;
+ if (type == sym_1("Str"))
+ return (f_init_cast) str_init_cast;
+ if (type == sym_1("Sym"))
+ return (f_init_cast) sym_init_cast;
+ if (type == sym_1("Tuple"))
+ return (f_init_cast) tuple_init_cast;
+ if (type == sym_1("Var"))
+ return NULL;
+ if (type == sym_1("Void"))
+ return NULL;
+ err_write_1("sym_to_init_cast: unknown type: ");
+ err_puts(type->str.ptr.ps8);
+ assert(! "sym_to_init_cast: unknown type");
+ return NULL;
+}
+
f_init_copy sym_to_init_copy (const s_sym *type)
{
if (type == sym_1("Bool"))
diff --git a/libc3/sym.h b/libc3/sym.h
index 6ca150e..f32f447 100644
--- a/libc3/sym.h
+++ b/libc3/sym.h
@@ -28,6 +28,7 @@
const s_sym * sym_1 (const s8 *p);
const s_sym ** sym_init_1 (const s_sym **sym, const s8 *p);
+const s_sym ** sym_init_cast (const s_sym **sym, const s_tag *src);
const s_sym ** sym_init_copy (const s_sym **sym,
const s_sym * const *src);
@@ -47,6 +48,7 @@ f_buf_inspect_size sym_to_buf_inspect_size (const s_sym *type);
f_clean sym_to_clean (const s_sym *type);
ffi_type * sym_to_ffi_type (const s_sym *sym,
ffi_type *result_type);
+f_init_cast sym_to_init_cast (const s_sym *type);
f_init_copy sym_to_init_copy (const s_sym *type);
bool sym_to_tag_type (const s_sym *sym, e_tag_type *dest);
uw sym_type_size (const s_sym *type);
diff --git a/libc3/tag_type.c b/libc3/tag_type.c
index 2b3d376..4620fbe 100644
--- a/libc3/tag_type.c
+++ b/libc3/tag_type.c
@@ -313,6 +313,81 @@ f_buf_parse tag_type_to_buf_parse (e_tag_type type)
return NULL;
}
+f_init_cast tag_type_to_init_cast (e_tag_type type)
+{
+ switch (type) {
+ case TAG_VOID:
+ return NULL;
+ case TAG_ARRAY:
+ return (f_init_cast) array_init_cast;
+ case TAG_BOOL:
+ return (f_init_cast) bool_init_cast;
+ case TAG_CALL:
+ return (f_init_cast) call_init_cast;
+ case TAG_CFN:
+ return (f_init_cast) cfn_init_cast;
+ case TAG_CHARACTER:
+ return (f_init_cast) character_init_cast;
+ case TAG_F32:
+ return (f_init_cast) f32_init_cast;
+ case TAG_F64:
+ return (f_init_cast) f64_init_cast;
+ case TAG_FACT:
+ return (f_init_cast) fact_init_cast;
+ case TAG_FN:
+ return (f_init_cast) fn_init_cast;
+ case TAG_IDENT:
+ return (f_init_cast) ident_init_cast;
+ case TAG_INTEGER:
+ return (f_init_cast) integer_init_cast;
+ case TAG_SW:
+ return (f_init_cast) sw_init_cast;
+ case TAG_S64:
+ return (f_init_cast) s64_init_cast;
+ case TAG_S32:
+ return (f_init_cast) s32_init_cast;
+ case TAG_S16:
+ return (f_init_cast) s16_init_cast;
+ case TAG_S8:
+ return (f_init_cast) s8_init_cast;
+ case TAG_U8:
+ return (f_init_cast) u8_init_cast;
+ case TAG_U16:
+ return (f_init_cast) u16_init_cast;
+ case TAG_U32:
+ return (f_init_cast) u32_init_cast;
+ case TAG_U64:
+ return (f_init_cast) u64_init_cast;
+ case TAG_UW:
+ return (f_init_cast) uw_init_cast;
+ case TAG_LIST:
+ return (f_init_cast) list_init_cast;
+ case TAG_MAP:
+ return (f_init_cast) map_init_cast;
+ case TAG_PTAG:
+ return (f_init_cast) ptag_init_cast;
+ case TAG_PTR:
+ return (f_init_cast) ptr_init_cast;
+ case TAG_PTR_FREE:
+ return (f_init_cast) ptr_free_init_cast;
+ case TAG_QUOTE:
+ return (f_init_cast) quote_init_cast;
+ case TAG_STR:
+ return (f_init_cast) str_init_cast;
+ case TAG_STRUCT:
+ return (f_init_cast) struct_init_cast;
+ case TAG_SYM:
+ return (f_init_cast) sym_init_cast;
+ case TAG_TUPLE:
+ return (f_init_cast) tuple_init_cast;
+ case TAG_VAR:
+ return NULL;
+ }
+ warnx("tag_type_to_init_cast: invalid tag type: %d", type);
+ assert(! "tag_type_to_init_cast: invalid tag type");
+ return NULL;
+}
+
f_clean tag_type_to_clean (e_tag_type type)
{
switch (type) {
diff --git a/libc3/tag_type.h b/libc3/tag_type.h
index 6b21782..f711693 100644
--- a/libc3/tag_type.h
+++ b/libc3/tag_type.h
@@ -22,12 +22,13 @@
#include "types.h"
sw tag_type_size (e_tag_type type);
-f_clean tag_type_to_clean (e_tag_type type);
f_buf_inspect tag_type_to_buf_inspect (e_tag_type type);
f_buf_inspect_size tag_type_to_buf_inspect_size (e_tag_type type);
f_buf_parse tag_type_to_buf_parse (e_tag_type type);
+f_clean tag_type_to_clean (e_tag_type type);
f_env_eval tag_type_to_env_eval (e_tag_type type);
f_hash_update tag_type_to_hash_update (e_tag_type type);
+f_init_cast tag_type_to_init_cast (e_tag_type type);
f_init_copy tag_type_to_init_copy (e_tag_type type);
const s8 * tag_type_to_string (e_tag_type type);
const s_sym * tag_type_to_sym (e_tag_type tag_type);
diff --git a/libc3/tuple.h b/libc3/tuple.h
index d5b612d..e359608 100644
--- a/libc3/tuple.h
+++ b/libc3/tuple.h
@@ -26,6 +26,7 @@
s_tuple * tuple_init (s_tuple *tuple, uw count);
s_tuple * tuple_init_1 (s_tuple *tuple, const s8 *p);
s_tuple * tuple_init_2 (s_tuple *tuple, const s_tag *a, const s_tag *b);
+s_tuple * tuple_init_cast (s_tuple *tuple, const s_tag *tag);
s_tuple * tuple_init_copy (s_tuple *tuple, const s_tuple *src);
void tuple_clean (s_tuple *tuple);
diff --git a/libc3/types.h b/libc3/types.h
index b256996..3b94aec 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -185,6 +185,7 @@ typedef sw (* f_buf_parse) (s_buf *buf, void *dest);
typedef void (* f_clean) (void *x);
typedef bool (* f_env_eval) (s_env *env, const void *x, s_tag *dest);
typedef void (* f_hash_update) (t_hash *hash, const void *x);
+typedef void * (* f_init_cast) (void *x, const s_tag *tag);
typedef void * (* f_init_copy) (void *x, const void *src);
typedef bool (* f_sequence_load) (s_sequence *seq, void *window);
typedef bool (* f_sequence_render) (s_sequence *seq, void *window,
diff --git a/libc3/u.c.in b/libc3/u.c.in
index c3b5621..fca8f45 100644
--- a/libc3/u.c.in
+++ b/libc3/u.c.in
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=_BITS$ bits=_bits$ */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "u_bits$.h"
@@ -68,8 +70,8 @@ u_bits$ * u_bits$_cast (s_tag *tag, u_bits$ *dest)
default:
break;
}
- errx(1, "u_bits$_cast: cannot cast %s to u_bits$",
- tag_type_to_string(tag->type));
+ warnx("u_bits$_cast: cannot cast %s to u_bits$",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ u_bits$ * u_bits$_init_copy (u_bits$ *dest, const u_bits$ *src)
*dest = *src;
return dest;
}
+
+u_bits$ * u_bits$_random (u_bits$ *dest)
+{
+ arc4random_buf(dest, sizeof(u_bits$));
+ return dest;
+}
+
+u_bits$ * u_bits$_random_uniform (u_bits$ max, u_bits$ *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ u_bits$ rest = (max - ((1 << size) - 1)) >> size;
+ u_bits$ result = 0;
+ u_bits$ tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/u.h.in b/libc3/u.h.in
index e8d7808..753e17d 100644
--- a/libc3/u.h.in
+++ b/libc3/u.h.in
@@ -16,7 +16,9 @@
#include "types.h"
-u_bits$ * u_bits$_cast (s_tag *tag, u_bits$ *dest);
+u_bits$ * u_bits$_init_cast (u_bits$ *u, const s_tag *tag);
u_bits$ * u_bits$_init_copy (u_bits$ *u, const u_bits$ *src);
+u_bits$ * u_bits$_random (u_bits$ *dest);
+u_bits$ * u_bits$_random_uniform (u_bits$ max, u_bits$ *dest);
#endif /* LIBC3_U_BITS$_H */
diff --git a/libc3/u16.c b/libc3/u16.c
index 34c762e..b9ff319 100644
--- a/libc3/u16.c
+++ b/libc3/u16.c
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=16 bits=16 */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "u16.h"
@@ -68,8 +70,8 @@ u16 * u16_cast (s_tag *tag, u16 *dest)
default:
break;
}
- errx(1, "u16_cast: cannot cast %s to u16",
- tag_type_to_string(tag->type));
+ warnx("u16_cast: cannot cast %s to u16",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ u16 * u16_init_copy (u16 *dest, const u16 *src)
*dest = *src;
return dest;
}
+
+u16 * u16_random (u16 *dest)
+{
+ arc4random_buf(dest, sizeof(u16));
+ return dest;
+}
+
+u16 * u16_random_uniform (u16 max, u16 *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ u16 rest = (max - ((1 << size) - 1)) >> size;
+ u16 result = 0;
+ u16 tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/u16.h b/libc3/u16.h
index f3c3038..99b1d42 100644
--- a/libc3/u16.h
+++ b/libc3/u16.h
@@ -16,7 +16,9 @@
#include "types.h"
-u16 * u16_cast (s_tag *tag, u16 *dest);
+u16 * u16_init_cast (u16 *u, const s_tag *tag);
u16 * u16_init_copy (u16 *u, const u16 *src);
+u16 * u16_random (u16 *dest);
+u16 * u16_random_uniform (u16 max, u16 *dest);
#endif /* LIBC3_U16_H */
diff --git a/libc3/u32.c b/libc3/u32.c
index a22a6f6..e015b6f 100644
--- a/libc3/u32.c
+++ b/libc3/u32.c
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=32 bits=32 */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "u32.h"
@@ -68,8 +70,8 @@ u32 * u32_cast (s_tag *tag, u32 *dest)
default:
break;
}
- errx(1, "u32_cast: cannot cast %s to u32",
- tag_type_to_string(tag->type));
+ warnx("u32_cast: cannot cast %s to u32",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ u32 * u32_init_copy (u32 *dest, const u32 *src)
*dest = *src;
return dest;
}
+
+u32 * u32_random (u32 *dest)
+{
+ arc4random_buf(dest, sizeof(u32));
+ return dest;
+}
+
+u32 * u32_random_uniform (u32 max, u32 *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ u32 rest = (max - ((1 << size) - 1)) >> size;
+ u32 result = 0;
+ u32 tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/u32.h b/libc3/u32.h
index 1229100..45398ac 100644
--- a/libc3/u32.h
+++ b/libc3/u32.h
@@ -16,7 +16,9 @@
#include "types.h"
-u32 * u32_cast (s_tag *tag, u32 *dest);
+u32 * u32_init_cast (u32 *u, const s_tag *tag);
u32 * u32_init_copy (u32 *u, const u32 *src);
+u32 * u32_random (u32 *dest);
+u32 * u32_random_uniform (u32 max, u32 *dest);
#endif /* LIBC3_U32_H */
diff --git a/libc3/u64.c b/libc3/u64.c
index 410e765..bf5a47f 100644
--- a/libc3/u64.c
+++ b/libc3/u64.c
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=64 bits=64 */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "u64.h"
@@ -68,8 +70,8 @@ u64 * u64_cast (s_tag *tag, u64 *dest)
default:
break;
}
- errx(1, "u64_cast: cannot cast %s to u64",
- tag_type_to_string(tag->type));
+ warnx("u64_cast: cannot cast %s to u64",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ u64 * u64_init_copy (u64 *dest, const u64 *src)
*dest = *src;
return dest;
}
+
+u64 * u64_random (u64 *dest)
+{
+ arc4random_buf(dest, sizeof(u64));
+ return dest;
+}
+
+u64 * u64_random_uniform (u64 max, u64 *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ u64 rest = (max - ((1 << size) - 1)) >> size;
+ u64 result = 0;
+ u64 tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/u64.h b/libc3/u64.h
index ee8772e..75ffbc3 100644
--- a/libc3/u64.h
+++ b/libc3/u64.h
@@ -16,7 +16,9 @@
#include "types.h"
-u64 * u64_cast (s_tag *tag, u64 *dest);
+u64 * u64_init_cast (u64 *u, const s_tag *tag);
u64 * u64_init_copy (u64 *u, const u64 *src);
+u64 * u64_random (u64 *dest);
+u64 * u64_random_uniform (u64 max, u64 *dest);
#endif /* LIBC3_U64_H */
diff --git a/libc3/u8.c b/libc3/u8.c
index 9a1bb2d..0df8048 100644
--- a/libc3/u8.c
+++ b/libc3/u8.c
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=8 bits=8 */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "u8.h"
@@ -68,8 +70,8 @@ u8 * u8_cast (s_tag *tag, u8 *dest)
default:
break;
}
- errx(1, "u8_cast: cannot cast %s to u8",
- tag_type_to_string(tag->type));
+ warnx("u8_cast: cannot cast %s to u8",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ u8 * u8_init_copy (u8 *dest, const u8 *src)
*dest = *src;
return dest;
}
+
+u8 * u8_random (u8 *dest)
+{
+ arc4random_buf(dest, sizeof(u8));
+ return dest;
+}
+
+u8 * u8_random_uniform (u8 max, u8 *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ u8 rest = (max - ((1 << size) - 1)) >> size;
+ u8 result = 0;
+ u8 tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/u8.h b/libc3/u8.h
index 05c2ae4..4485d43 100644
--- a/libc3/u8.h
+++ b/libc3/u8.h
@@ -16,7 +16,9 @@
#include "types.h"
-u8 * u8_cast (s_tag *tag, u8 *dest);
+u8 * u8_init_cast (u8 *u, const s_tag *tag);
u8 * u8_init_copy (u8 *u, const u8 *src);
+u8 * u8_random (u8 *dest);
+u8 * u8_random_uniform (u8 max, u8 *dest);
#endif /* LIBC3_U8_H */
diff --git a/libc3/uw.c b/libc3/uw.c
index 3a7faaf..c38d09c 100644
--- a/libc3/uw.c
+++ b/libc3/uw.c
@@ -13,6 +13,8 @@
/* Gen from u.h.in BITS=W bits=w */
#include <assert.h>
#include <err.h>
+#include <math.h>
+#include <stdlib.h>
#include "integer.h"
#include "tag.h"
#include "uw.h"
@@ -68,8 +70,8 @@ uw * uw_cast (s_tag *tag, uw *dest)
default:
break;
}
- errx(1, "uw_cast: cannot cast %s to uw",
- tag_type_to_string(tag->type));
+ warnx("uw_cast: cannot cast %s to uw",
+ tag_type_to_string(tag->type));
return 0;
}
@@ -80,3 +82,24 @@ uw * uw_init_copy (uw *dest, const uw *src)
*dest = *src;
return dest;
}
+
+uw * uw_random (uw *dest)
+{
+ arc4random_buf(dest, sizeof(uw));
+ return dest;
+}
+
+uw * uw_random_uniform (uw max, uw *dest)
+{
+ uw size = (uw) log2(max) / 8;
+ uw rest = (max - ((1 << size) - 1)) >> size;
+ uw result = 0;
+ uw tmp;
+ arc4random_buf(&result, size);
+ if (rest) {
+ tmp = arc4random_uniform(rest);
+ result += tmp;
+ }
+ *dest = result;
+ return dest;
+}
diff --git a/libc3/uw.h b/libc3/uw.h
index 20e4b54..cf4826e 100644
--- a/libc3/uw.h
+++ b/libc3/uw.h
@@ -16,7 +16,9 @@
#include "types.h"
-uw * uw_cast (s_tag *tag, uw *dest);
+uw * uw_init_cast (uw *u, const s_tag *tag);
uw * uw_init_copy (uw *u, const uw *src);
+uw * uw_random (uw *dest);
+uw * uw_random_uniform (uw max, uw *dest);
#endif /* LIBC3_UW_H */
diff --git a/libc3/var.c b/libc3/var.c
index 69b8ea8..ff57a74 100644
--- a/libc3/var.c
+++ b/libc3/var.c
@@ -14,13 +14,3 @@
#include <err.h>
#include "tag.h"
#include "var.h"
-
-s_tag * var_init_copy (s_tag *dest, const s_tag *src)
-{
- assert(src);
- assert(dest);
- (void) src;
- /* ?? */
- tag_init_void(dest);
- return dest;
-}