diff --git a/c3s/c3s.c b/c3s/c3s.c
index 4d4215e..5327c21 100644
--- a/c3s/c3s.c
+++ b/c3s/c3s.c
@@ -67,7 +67,8 @@ int main (int argc, char **argv)
s_buf out;
sw r;
s_tag result;
- c3_init(NULL);
+ if (! c3_init(NULL, argc, argv))
+ return 1;
if (argc < 1)
return usage(argv[0]);
buf_init(&in, false, sizeof(i), i);
diff --git a/ic3/ic3.c b/ic3/ic3.c
index 9dd8ef3..97f06d7 100644
--- a/ic3/ic3.c
+++ b/ic3/ic3.c
@@ -91,7 +91,8 @@ int main (int argc, char **argv)
s_buf out;
sw r;
s_tag result;
- c3_init(NULL);
+ if (! c3_init(NULL, argc, argv))
+ return 1;
if (argc < 1)
return usage(argv[0]);
buf_init(&in, false, sizeof(i), i);
diff --git a/img/toast.png b/img/toast.png
new file mode 100644
index 0000000..021511b
Binary files /dev/null and b/img/toast.png differ
diff --git a/libc3/buf_parse.c b/libc3/buf_parse.c
index ecc76b6..939638c 100644
--- a/libc3/buf_parse.c
+++ b/libc3/buf_parse.c
@@ -408,7 +408,7 @@ sw buf_parse_brackets (s_buf *buf, s_call *dest)
assert(dest);
buf_save_init(buf, &save);
call_init(&tmp);
- tmp.arguments = list_new(NULL, list_new(NULL, NULL));
+ tmp.arguments = list_new(list_new(NULL));
arg_addr = &(list_next(tmp.arguments)->tag);
if ((r = buf_parse_tag_primary(buf, &tmp.arguments->tag)) <= 0)
goto restore;
@@ -431,7 +431,7 @@ sw buf_parse_brackets (s_buf *buf, s_call *dest)
if ((r = buf_read_1(buf, "]")) <= 0)
goto restore;
result += r;
- *addr_last = list_new(NULL, NULL);
+ *addr_last = list_new(NULL);
tag_init_uw(&(*addr_last)->tag, d);
addr_last = &(*addr_last)->next.data.list;
address++;
@@ -519,7 +519,7 @@ sw buf_parse_call_args_paren (s_buf *buf, s_call *dest)
if ((r = buf_parse_tag(buf, &tag)) <= 0)
goto restore;
result += r;
- *args = list_new(NULL, NULL);
+ *args = list_new(NULL);
(*args)->tag = tag;
if ((r = buf_parse_comments(buf)) < 0)
goto restore;
@@ -1285,7 +1285,7 @@ sw buf_parse_fn_algo (s_buf *buf, s_list **dest)
if (! r)
break;
result += r;
- *tail = list_new(NULL, NULL);
+ *tail = list_new(NULL);
(*tail)->tag = tag;
tail = &(*tail)->next.data.list;
if ((r = buf_ignore_spaces(buf)) < 0)
@@ -1332,7 +1332,7 @@ sw buf_parse_fn_pattern (s_buf *buf, s_list **dest)
if ((r = buf_parse_tag(buf, &tag)) <= 0)
goto restore;
result += r;
- *tail = list_new(NULL, NULL);
+ *tail = list_new(NULL);
(*tail)->tag = tag;
tail = &(*tail)->next.data.list;
if ((r = buf_ignore_spaces(buf)) < 0)
@@ -1690,7 +1690,7 @@ sw buf_parse_list (s_buf *buf, s_list **list)
}
*i = NULL;
while (1) {
- *i = list_new(NULL, NULL);
+ *i = list_new(NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
result += r;
@@ -1782,7 +1782,7 @@ sw buf_parse_list_paren (s_buf *buf, s_list **list)
}
*i = NULL;
while (1) {
- *i = list_new(NULL, NULL);
+ *i = list_new(NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
result += r;
@@ -1874,7 +1874,7 @@ sw buf_parse_map (s_buf *buf, s_map *dest)
goto restore;
result += r;
while (r == 0) {
- *keys_end = list_new(NULL, NULL);
+ *keys_end = list_new(NULL);
if ((r = buf_parse_map_key(buf, &(*keys_end)->tag)) <= 0)
goto restore;
result += r;
@@ -1885,7 +1885,7 @@ sw buf_parse_map (s_buf *buf, s_map *dest)
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
- *values_end = list_new(NULL, NULL);
+ *values_end = list_new(NULL);
if ((r = buf_parse_tag(buf, &(*values_end)->tag)) <= 0)
goto restore;
result += r;
@@ -2776,7 +2776,7 @@ sw buf_parse_tuple (s_buf *buf, s_tuple *tuple)
if ((r = buf_ignore_spaces(buf)) < 0)
goto restore;
result += r;
- *i = list_new(NULL, NULL);
+ *i = list_new(NULL);
if ((r = buf_parse_tag(buf, &(*i)->tag)) <= 0)
goto restore;
result += r;
diff --git a/libc3/buf_save.c b/libc3/buf_save.c
index 0b3f723..deef623 100644
--- a/libc3/buf_save.c
+++ b/libc3/buf_save.c
@@ -78,6 +78,6 @@ s_buf * buf_save_restore_wpos (s_buf *buf, const s_buf_save *save)
assert(buf);
assert(save);
assert(buf->save == save);
- buf->rpos = save->wpos;
+ buf->wpos = save->wpos;
return buf;
}
diff --git a/libc3/c3.c b/libc3/c3.c
index 7d02020..58d6d84 100644
--- a/libc3/c3.c
+++ b/libc3/c3.c
@@ -47,12 +47,11 @@ void c3_exit (sw code)
exit((int) code);
}
-void c3_init (s_env *env)
+s_env * c3_init (s_env *env, sw argc, s8 **argv)
{
if (! env)
env = &g_c3_env;
- if (! env_init(env))
- exit(1);
+ return env_init(env, argc, argv);
}
void c3_license (void)
diff --git a/libc3/c3.h b/libc3/c3.h
index 9e66e49..43916c9 100644
--- a/libc3/c3.h
+++ b/libc3/c3.h
@@ -58,6 +58,7 @@
#include "facts_cursor.h"
#include "facts_with.h"
#include "facts_with_cursor.h"
+#include "file.h"
#include "fn.h"
#include "fn_clause.h"
#include "hash.h"
diff --git a/libc3/c3_main.h b/libc3/c3_main.h
index bcf03dc..d6c83d3 100644
--- a/libc3/c3_main.h
+++ b/libc3/c3_main.h
@@ -26,7 +26,7 @@ extern const s8 *g_c3_license;
extern sw g_c3_exit_code;
/* stack-allocation compatible functions */
-void c3_init (s_env *env);
+s_env * c3_init (s_env *env, sw argc, s8 **argv);
void c3_clean (s_env *env);
/* debug */
diff --git a/libc3/call.c b/libc3/call.c
index 829305c..3b195bb 100644
--- a/libc3/call.c
+++ b/libc3/call.c
@@ -219,7 +219,7 @@ s_call * call_init_cast (s_call *call, const s_sym *type,
assert(call);
bzero(call, sizeof(s_call));
ident_init(&call->ident, type, sym_1("cast"));
- call->arguments = list_new(tag, NULL);
+ call->arguments = list_new_copy(tag, NULL);
return call;
}
@@ -227,7 +227,7 @@ s_call * call_init_op (s_call *call)
{
assert(call);
bzero(call, sizeof(s_call));
- call->arguments = list_new(NULL, list_new(NULL, NULL));
+ call->arguments = list_new(list_new(NULL));
return call;
}
@@ -235,7 +235,7 @@ s_call * call_init_op_unary (s_call *call)
{
assert(call);
bzero(call, sizeof(s_call));
- call->arguments = list_new(NULL, NULL);
+ call->arguments = list_new(NULL);
return call;
}
diff --git a/libc3/env.c b/libc3/env.c
index 1d21136..1e386e7 100644
--- a/libc3/env.c
+++ b/libc3/env.c
@@ -12,6 +12,7 @@
*/
#include <assert.h>
#include <err.h>
+#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -47,8 +48,9 @@
s_env g_c3_env;
-bool env_eval_array_cast (s_env *env, s_array *tmp, const s_tag *tag,
- u8 *data, uw size);
+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, sw argc, s8 **argv);
void env_clean (s_env *env)
{
@@ -62,6 +64,8 @@ void env_clean (s_env *env)
buf_clean(&env->out);
buf_file_close(&env->err);
buf_clean(&env->err);
+ str_clean(&env->argv0_dir);
+ list_delete_all(env->path);
}
void env_error_f (s_env *env, const char *fmt, ...)
@@ -201,7 +205,7 @@ bool env_eval_call_arguments (s_env *env, const s_list *args,
s_list *tmp;
tail = &tmp;
while (args) {
- *tail = list_new(NULL, NULL);
+ *tail = list_new(NULL);
if (! env_eval_tag(env, &args->tag, &(*tail)->tag)) {
list_delete_all(tmp);
err_puts("env_eval_call_arguments: invalid argument: ");
@@ -293,7 +297,7 @@ bool env_eval_equal_list (s_env *env, const s_list *a, const s_list *b,
goto ko;
if (! b)
goto ko;
- *t = list_new(NULL, NULL);
+ *t = list_new(NULL);
if (! env_eval_equal_tag(env, &a->tag, &b->tag,
&(*t)->tag))
goto ko;
@@ -592,7 +596,7 @@ bool env_eval_list (s_env *env, const s_list *list, s_tag *dest)
assert(env);
assert(dest);
while (list) {
- *tail = list_new(NULL, NULL);
+ *tail = list_new(NULL);
if (! env_eval_tag(env, &list->tag, &(*tail)->tag))
goto ko;
next = list_next(list);
@@ -733,9 +737,12 @@ bool env_eval_tuple (s_env *env, const s_tuple *tuple, s_tag *dest)
return true;
}
-s_env * env_init (s_env *env)
+s_env * env_init (s_env *env, sw argc, s8 **argv)
{
+ s_str path;
assert(env);
+ if (! env_init_args(env, argc, argv))
+ return NULL;
env->error_handler = NULL;
env->frame = frame_new(NULL);
buf_init_alloc(&env->in, BUF_SIZE);
@@ -745,18 +752,20 @@ s_env * env_init (s_env *env)
buf_init_alloc(&env->err, BUF_SIZE);
buf_file_open_w(&env->err, stderr);
facts_init(&env->facts);
- /* TODO: module path */
- if (! access("lib/c3/0.1", X_OK))
- str_init_1(&env->module_path, NULL, "lib/c3/0.1");
- else if (! access("../lib/c3/0.1", X_OK))
- str_init_1(&env->module_path, NULL, "../lib/c3/0.1");
- else if (! access("../../lib/c3/0.1", X_OK))
- str_init_1(&env->module_path, NULL, "../../lib/c3/0.1");
- else if (! access(PREFIX "/lib/c3/0.1", X_OK))
- str_init_1(&env->module_path, NULL, PREFIX "/lib/c3/0.1");
- else {
+ env->path = list_new_str_1
+ (NULL, "./", list_new_str_1
+ (NULL, "../", list_new_str_1
+ (NULL, "../Resources/", list_new_str_1
+ (NULL, "../../", list_new_str_1
+ (NULL, "../../../", list_new_str_1
+ (NULL, "../../../../", list_new_str_1
+ (NULL, "../../../../../", list_new_str_1
+ (NULL, "../../../../../../", NULL))))))));
+ str_init_1(&path, NULL, "lib/c3/0.1");
+ if (! file_search(&path, sym_1("x"), &env->module_path)) {
assert(! "env_init: module path not found");
- err(1, "env_init: module_path not found");
+ warn("env_init: module_path not found");
+ return NULL;
}
env->current_module = sym_1("C3");
if (! module_load(sym_1("C3"), &env->facts)) {
@@ -766,6 +775,30 @@ s_env * env_init (s_env *env)
return env;
}
+s_env * env_init_args (s_env *env, sw argc, s8 **argv)
+{
+ s8 *dir;
+ uw len;
+ assert(env);
+ if (argv) {
+ env->argc = argc;
+ env->argv = argv;
+ dir = malloc(strlen(argv[0]) + 1);
+ dirname_r(argv[0], dir);
+ len = strlen(dir);
+ assert(len);
+ dir[len + 1] = '\0';
+ dir[len] = '/';
+ str_init_1(&env->argv0_dir, dir, dir);
+ }
+ else {
+ env->argc = 0;
+ env->argv = NULL;
+ str_init_1(&env->argv0_dir, NULL, "./");
+ }
+ return env;
+}
+
void env_longjmp (s_env *env, jmp_buf *jmp_buf)
{
if (env->unwind_protect && *jmp_buf > env->unwind_protect->buf) {
diff --git a/libc3/env.h b/libc3/env.h
index a924941..db6fc4b 100644
--- a/libc3/env.h
+++ b/libc3/env.h
@@ -19,7 +19,7 @@ extern s_env g_c3_env;
/* Stack allocation compatible functions, call env_clean after use. */
void env_clean (s_env *env);
-s_env * env_init (s_env *env);
+s_env * env_init (s_env *env, sw argc, s8 **argv);
/* Modifiers. */
bool env_eval_array (s_env *env, const s_array *array,
diff --git a/libc3/facts.c b/libc3/facts.c
index ae842e9..d23d3d3 100644
--- a/libc3/facts.c
+++ b/libc3/facts.c
@@ -573,7 +573,7 @@ s_fact * facts_replace_tags (s_facts *facts, const s_tag *subject,
facts_with_tags(facts, &cursor, (s_tag *) subject,
(s_tag *) predicate, &var);
while ((f = facts_cursor_next(&cursor))) {
- list = list_new(NULL, list);
+ list = list_new(list);
list->tag.data.fact = *f;
}
while (list) {
diff --git a/libc3/file.c b/libc3/file.c
index 036da81..1f53266 100644
--- a/libc3/file.c
+++ b/libc3/file.c
@@ -16,17 +16,49 @@
#include <errno.h>
#include <sys/stat.h>
#include <unistd.h>
+#include "buf.h"
+#include "buf_save.h"
+#include "env.h"
#include "file.h"
+#include "io.h"
+#include "list.h"
+#include "str.h"
+#include "sym.h"
#include "time.h"
-int file_copy (const char *from, const char *to)
+bool * file_access (const s_str *path, const s_sym *mode,
+ bool *dest)
{
- char buf[4096];
- int fd_from = -1;
- int fd_to = -1;
- ssize_t r;
- int saved_errno;
+ sw m;
+ if (mode == sym_1("r"))
+ m = R_OK;
+ else if (mode == sym_1("rw"))
+ m = R_OK | W_OK;
+ else if (mode == sym_1("rwx"))
+ m = R_OK | W_OK | X_OK;
+ else if (mode == sym_1("rx"))
+ m = R_OK | X_OK;
+ else if (mode == sym_1("w"))
+ m = W_OK;
+ else if (mode == sym_1("wx"))
+ m = W_OK | X_OK;
+ else if (mode == sym_1("x"))
+ m = X_OK;
+ else
+ m = F_OK;
+ *dest = access(path->ptr.ps8, m) ? false : true;
+ return dest;
+}
+sw file_copy_1 (const char *from, const char *to)
+{
+ s8 buf[4096];
+ sw fd_from = -1;
+ sw fd_to = -1;
+ s8 *out;
+ sw r;
+ sw saved_errno;
+ sw w;
if ((fd_from = open(from, O_RDONLY)) < 0) {
warn("cp: %s", from);
return -1;
@@ -36,8 +68,7 @@ int file_copy (const char *from, const char *to)
goto error;
}
while ((r = read(fd_from, buf, sizeof buf)) > 0) {
- char *out = buf;
- ssize_t w;
+ out = buf;
do {
if ((w = write(fd_to, out, r)) >= 0) {
r -= w;
@@ -75,3 +106,41 @@ s_tag * file_mtime (const s_str *path, s_tag *dest)
}
return time_to_tag(&sb.st_mtim, dest);
}
+
+s_str * file_search (const s_str *suffix, const s_sym *mode,
+ s_str *dest)
+{
+ bool access;
+ s8 buf_s[PATH_MAX];
+ s_buf buf;
+ const s_list *path;
+ sw r;
+ s_buf_save save;
+ s_str tmp;
+ buf_init(&buf, false, PATH_MAX, buf_s);
+ if ((r = buf_write_str(&buf, &g_c3_env.argv0_dir)) < 0)
+ return NULL;
+ buf_save_init(&buf, &save);
+ path = g_c3_env.path;
+ while (path) {
+ if (path->tag.type == TAG_STR) {
+ buf_save_restore_rpos(&buf, &save);
+ buf_save_restore_wpos(&buf, &save);
+ if ((r = buf_write_str(&buf, &path->tag.data.str)) < 0 ||
+ (buf.ptr.ps8[buf.wpos - 1] != '/' &&
+ (r = buf_write_u8(&buf, '/')) < 0) ||
+ (r = buf_write_str(&buf, suffix)) < 0)
+ return NULL;
+ buf_read_to_str(&buf, &tmp);
+ io_inspect_str(&tmp);
+ file_access(&tmp, mode, &access);
+ if (access) {
+ *dest = tmp;
+ return dest;
+ }
+ str_clean(&tmp);
+ }
+ path = list_next(path);
+ }
+ return NULL;
+}
diff --git a/libc3/file.h b/libc3/file.h
index 1556df0..adffc3b 100644
--- a/libc3/file.h
+++ b/libc3/file.h
@@ -15,6 +15,9 @@
* @brief file operations.
*
* Structure to manipulate files.
+ *
+ * Arguments :
+ * - mode: one of `[:r, :rw, :rwx, :rx, :w, :wx, :x]`
*/
#ifndef LIBC3_FILE_H
#define LIBC3_FILE_H
@@ -22,7 +25,11 @@
#include "types.h"
/* Observers */
-int file_copy (const char *from, const char *to);
+bool * file_access (const s_str *path, const s_sym *mode,
+ bool *dest);
+sw file_copy_1 (const char *from, const char *to);
s_tag * file_mtime (const s_str *path, s_tag *dest);
+s_str * file_search (const s_str *suffix, const s_sym *mode,
+ s_str *dest);
#endif /* LIBC3_FILE_H */
diff --git a/libc3/io.c b/libc3/io.c
index ca8e638..198799f 100644
--- a/libc3/io.c
+++ b/libc3/io.c
@@ -50,9 +50,29 @@ sw err_puts (const s8 *s)
sw io_inspect (const s_tag *tag)
{
sw r;
- r = buf_inspect_tag(&g_c3_env.out, tag);
+ sw result = 0;
+ if ((r = buf_inspect_tag(&g_c3_env.out, tag)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_u8(&g_c3_env.out, '\n')) < 0)
+ return r;
+ result += r;
buf_flush(&g_c3_env.out);
- return r;
+ return result;
+}
+
+sw io_inspect_str (const s_str *str)
+{
+ sw r;
+ sw result = 0;
+ if ((r = buf_inspect_str(&g_c3_env.out, str)) < 0)
+ return r;
+ result += r;
+ if ((r = buf_write_u8(&g_c3_env.out, '\n')) < 0)
+ return r;
+ result += r;
+ buf_flush(&g_c3_env.out);
+ return result;
}
sw io_puts (const s8 *s)
diff --git a/libc3/io.h b/libc3/io.h
index c7017eb..24f671a 100644
--- a/libc3/io.h
+++ b/libc3/io.h
@@ -23,6 +23,7 @@ sw err_puts (const s8 *s);
/* standard output */
sw io_inspect (const s_tag *tag);
+sw io_inspect_str (const s_str *str);
sw io_puts (const s8 *s);
#endif /* LIBC3_IO_H */
diff --git a/libc3/list.c b/libc3/list.c
index 3f1f3c7..712b593 100644
--- a/libc3/list.c
+++ b/libc3/list.c
@@ -73,7 +73,7 @@ s_list ** list_copy (const s_list **src, s_list **dest)
*i = NULL;
s = *src;
while (s) {
- *i = list_new(NULL, NULL);
+ *i = list_new(NULL);
tag_copy(&s->tag, &(*i)->tag);
if ((next = list_next(s))) {
s = next;
@@ -107,17 +107,23 @@ void list_delete_all (s_list *list)
list = list_delete(list);
}
-s_list * list_init (s_list *list, const s_tag *tag, s_list *next)
+s_list * list_init (s_list *list, s_list *next)
{
assert(list);
- if (tag)
- tag_copy(tag, &list->tag);
- else
- tag_init_void(&list->tag);
+ tag_init_void(&list->tag);
tag_init_list(&list->next, next);
return list;
}
+s_list * list_init_copy (s_list *list, const s_tag *tag, s_list *next)
+{
+ assert(list);
+ assert(tag);
+ list_init(list, next);
+ tag_copy(tag, &list->tag);
+ return list;
+}
+
s_str * list_inspect (const s_list *x, s_str *dest)
{
s_buf buf;
@@ -155,13 +161,50 @@ s_list * list_next (const s_list *list)
}
}
-s_list * list_new (const s_tag *tag, s_list *next)
+s_list * list_new (s_list *next)
{
s_list *list;
- list = calloc(1, sizeof(s_list));
- if (! list)
- errx(1, "list_new: out of memory");
- return list_init(list, tag, next);
+ if (! (list = calloc(1, sizeof(s_list)))) {
+ warnx("list_new: out of memory");
+ return NULL;
+ }
+ return list_init(list, next);
+}
+
+s_list * list_new_copy (const s_tag *tag, s_list *next)
+{
+ s_list *list;
+ if ((list = list_new(next))) {
+ if (! tag_copy(tag, &list->tag)) {
+ free(list);
+ return NULL;
+ }
+ }
+ return list;
+}
+
+s_list * list_new_f64 (f64 x, s_list *next)
+{
+ s_list *list;
+ if ((list = list_new(next))) {
+ if (! tag_init_f64(&list->tag, x)) {
+ free(list);
+ return NULL;
+ }
+ }
+ return list;
+}
+
+s_list * list_new_str_1 (s8 *free_, const s8 *p, s_list *next)
+{
+ s_list *list;
+ if ((list = list_new(next))) {
+ if (! tag_init_str_1(&list->tag, free_, p)) {
+ free(list);
+ return NULL;
+ }
+ }
+ return list;
}
s_array * list_to_array (s_list *list, const s_sym *type,
diff --git a/libc3/list.h b/libc3/list.h
index 1bef506..c0f247a 100644
--- a/libc3/list.h
+++ b/libc3/list.h
@@ -25,12 +25,16 @@
#include "types.h"
/* Stack allocation compatible functions, do not use */
-s_list * list_init (s_list *list, const s_tag *tag, s_list *next);
void list_clean (s_list **list);
+s_list * list_init (s_list *list, s_list *next);
+s_list * list_init_copy (s_list *list, const s_tag *tag, s_list *next);
/* Constructors, call list_delete after use */
s_list * list_1 (const s8 *p);
-s_list * list_new (const s_tag *tag, s_list *next);
+s_list * list_new (s_list *next);
+s_list * list_new_f64 (f64 x, s_list *next);
+s_list * list_new_copy (const s_tag *tag, s_list *next);
+s_list * list_new_str_1 (s8 *free, const s8 *p, s_list *next);
/* Destructor */
s_list * list_delete (s_list *list);
diff --git a/libc3/map.c b/libc3/map.c
index 7b9e384..4d65142 100644
--- a/libc3/map.c
+++ b/libc3/map.c
@@ -158,9 +158,9 @@ s_list ** map_map (const s_map *map, const s_fn *fn, s_list **result)
t = &tmp;
*t = NULL;
while (i < map->count) {
- args = list_new(map->keys + i,
- list_new(map->values + i, NULL));
- *t = list_new(NULL, NULL);
+ args = list_new_copy(map->keys + i,
+ list_new_copy(map->values + i, NULL));
+ *t = list_new(NULL);
if (! eval_fn_call(fn, args, &(*t)->tag)) {
list_delete_all(args);
list_delete_all(tmp);
diff --git a/libc3/types.h b/libc3/types.h
index fe101db..e5b12c0 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -181,10 +181,9 @@ typedef sw (* f_buf_inspect) (s_buf *buf, const void *x);
typedef sw (* f_buf_inspect_size) (const void *x);
typedef sw (* f_buf_parse) (s_buf *buf, void *dest);
typedef void * (* f_copy) (const void *a, void *b);
-typedef bool (* f_sequence_load) (s_sequence *seq);
-typedef void (* f_sequence_render) (void *window,
- void *render_context,
- s_sequence *seq);
+typedef bool (* f_sequence_load) (s_sequence *seq, void *window);
+typedef bool (* f_sequence_render) (s_sequence *seq, void *window,
+ void *context);
#define CHARACTER_MAX S32_MAX
#define SKIPLIST_HEIGHT_MAX U64_MAX
@@ -547,6 +546,9 @@ struct facts_cursor {
/* 9 */
struct env {
+ sw argc;
+ s8 **argv;
+ s_str argv0_dir;
s_list *backtrace;
const s_sym *current_module;
s_buf err;
@@ -556,6 +558,7 @@ struct env {
s_buf in;
s_str module_path;
s_buf out;
+ s_list *path;
s_unwind_protect *unwind_protect;
};
diff --git a/libc3/window/cairo/Makefile b/libc3/window/cairo/Makefile
index 6e1f3c7..19f4bc2 100644
--- a/libc3/window/cairo/Makefile
+++ b/libc3/window/cairo/Makefile
@@ -84,7 +84,7 @@ install:
if ${HAVE_XCB}; then ${MAKE} -C xcb install; fi
lldb_demo: debug
- if ${HAVE_COCOA}; then ${MAKE} -C quartz lldb_demo; else if ${HAVE_WIN32}; then ${MAKE} -C win32 lldb_demo; else if ${HAVE_XCB}; then ${MAKE} -C xcb lldb_demo; fi; fi
+ if ${HAVE_COCOA}; then ${MAKE} -C quartz lldb_demo; else if ${HAVE_WIN32}; then ${MAKE} -C win32 lldb_demo; else if ${HAVE_XCB}; then ${MAKE} -C xcb lldb_demo; fi; fi; fi
test:
${MAKE} -C demo test
diff --git a/libc3/window/cairo/cairo_png.c b/libc3/window/cairo/cairo_png.c
new file mode 100644
index 0000000..295f983
--- /dev/null
+++ b/libc3/window/cairo/cairo_png.c
@@ -0,0 +1,29 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <unistd.h>
+#include <cairo.h>
+#include <libc3/c3.h>
+#include "cairo_png.h"
+
+cairo_surface_t * cairo_png_1 (const s8 *path)
+{
+ s_str found_str;
+ s_str path_str;
+ cairo_surface_t *surface = NULL;
+ str_init_1(&path_str, NULL, path);
+ if (file_search(&path_str, sym_1("r"), &found_str)) {
+ surface = cairo_image_surface_create_from_png(found_str.ptr.ps8);
+ str_clean(&found_str);
+ }
+ return surface;
+}
diff --git a/libc3/window/cairo/cairo_png.h b/libc3/window/cairo/cairo_png.h
new file mode 100644
index 0000000..3d0c204
--- /dev/null
+++ b/libc3/window/cairo/cairo_png.h
@@ -0,0 +1,21 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef CAIRO_PNG_H
+#define CAIRO_PNG_H
+
+#include "types.h"
+#include <cairo.h>
+
+cairo_surface_t * cairo_png_1 (const s8 *path);
+
+#endif /* CAIRO_PNG_H */
diff --git a/libc3/window/cairo/cairo_sprite.c b/libc3/window/cairo/cairo_sprite.c
new file mode 100644
index 0000000..331086e
--- /dev/null
+++ b/libc3/window/cairo/cairo_sprite.c
@@ -0,0 +1,55 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include "cairo_sprite.h"
+
+void cairo_sprite_blit (const s_cairo_sprite *sprite, uw frame,
+ cairo_t *cr, uw x, uw y)
+{
+ uw frame_x;
+ uw frame_y;
+ assert(sprite);
+ assert(frame < sprite->frame_count);
+ assert(cr);
+ frame_x = sprite->w * (frame % sprite->dim_x);
+ frame_y = sprite->h * (frame / sprite->dim_x);
+ cairo_set_source_surface(cr, sprite->surface, frame_x, frame_y);
+ cairo_rectangle(cr, x, y, sprite->w, sprite->h);
+ cairo_fill(cr);
+}
+
+void cairo_sprite_clean (s_cairo_sprite *sprite)
+{
+ assert(sprite);
+ cairo_surface_destroy(sprite->surface);
+}
+
+s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
+ cairo_surface_t *surface,
+ uw dim_x, uw dim_y,
+ uw frame_count)
+{
+ assert(sprite);
+ assert(surface);
+ assert(dim_x);
+ assert(dim_y);
+ sprite->surface = surface;
+ sprite->surface_w = cairo_image_surface_get_width(surface);
+ sprite->surface_h = cairo_image_surface_get_height(surface);
+ sprite->dim_x = dim_x;
+ sprite->dim_y = dim_y;
+ sprite->w = sprite->surface_w / dim_x;
+ sprite->h = sprite->surface_h / dim_y;
+ sprite->frame_count = frame_count ? frame_count : dim_x * dim_y;
+ return sprite;
+}
diff --git a/libc3/window/cairo/cairo_sprite.h b/libc3/window/cairo/cairo_sprite.h
new file mode 100644
index 0000000..62a45b4
--- /dev/null
+++ b/libc3/window/cairo/cairo_sprite.h
@@ -0,0 +1,30 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef CAIRO_SPRITE_H
+#define CAIRO_SPRITE_H
+
+#include "types.h"
+#include <cairo.h>
+
+/* stack allocation compatible functions */
+void cairo_sprite_clean (s_cairo_sprite *sprite);
+s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
+ cairo_surface_t *surface,
+ uw dim_x, uw dim_y,
+ uw frame_count);
+
+/* operations */
+void cairo_sprite_blit (const s_cairo_sprite *sprite, uw frame,
+ cairo_t *cr, uw x, uw y);
+
+#endif /* CAIRO_SPRITE_H */
diff --git a/libc3/window/cairo/demo/bg_rect.c b/libc3/window/cairo/demo/bg_rect.c
index 6f7d5ee..4a4dec8 100644
--- a/libc3/window/cairo/demo/bg_rect.c
+++ b/libc3/window/cairo/demo/bg_rect.c
@@ -16,15 +16,15 @@
#include "../types.h"
#include "bg_rect.h"
-bool bg_rect_load (s_sequence *seq)
+bool bg_rect_load (s_sequence *seq, s_window_cairo *window)
{
(void) seq;
+ (void) window;
return true;
}
-void bg_rect_render (s_window_cairo *window,
- cairo_t *cr,
- s_sequence *seq)
+bool bg_rect_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr)
{
#define C3_WINDOW_CAIRO_DEMO_BG_RECT_COLOR_MAX 8
const s_rgb color[C3_WINDOW_CAIRO_DEMO_BG_RECT_COLOR_MAX] = {
@@ -52,4 +52,5 @@ void bg_rect_render (s_window_cairo *window,
cairo_set_source_rgb(cr, rgb.r, rgb.g, rgb.b);
cairo_rectangle(cr, 0, 0, window->w, window->h);
cairo_fill(cr);
+ return true;
}
diff --git a/libc3/window/cairo/demo/bg_rect.h b/libc3/window/cairo/demo/bg_rect.h
index 96f2d3e..cd451fa 100644
--- a/libc3/window/cairo/demo/bg_rect.h
+++ b/libc3/window/cairo/demo/bg_rect.h
@@ -15,9 +15,8 @@
#include "../types.h"
-bool bg_rect_load (s_sequence *seq);
-void bg_rect_render (s_window_cairo *window,
- cairo_t *cr,
- s_sequence *seq);
+bool bg_rect_load (s_sequence *seq, s_window_cairo *window);
+bool bg_rect_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr);
#endif /* BG_RECT_H */
diff --git a/libc3/window/cairo/demo/lightspeed.c b/libc3/window/cairo/demo/lightspeed.c
index 51067d5..1db1a4e 100644
--- a/libc3/window/cairo/demo/lightspeed.c
+++ b/libc3/window/cairo/demo/lightspeed.c
@@ -53,9 +53,10 @@ static void star_render (s_tag *star, s_window_cairo *window,
star_init(star);
}
-bool lightspeed_load (s_sequence *seq)
+bool lightspeed_load (s_sequence *seq, s_window_cairo *window)
{
uw i;
+ (void) window;
tag_clean(&seq->tag);
tag_init_tuple(&seq->tag, LIGHTSPEED_STARS);
i = 0;
@@ -66,9 +67,8 @@ bool lightspeed_load (s_sequence *seq)
return true;
}
-void lightspeed_render (s_window_cairo *window,
- cairo_t *cr,
- s_sequence *seq)
+bool lightspeed_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr)
{
uw i;
cairo_matrix_t matrix;
@@ -84,4 +84,5 @@ void lightspeed_render (s_window_cairo *window,
i++;
}
cairo_set_matrix(cr, &matrix);
+ return true;
}
diff --git a/libc3/window/cairo/demo/lightspeed.h b/libc3/window/cairo/demo/lightspeed.h
index 72d973c..dc95059 100644
--- a/libc3/window/cairo/demo/lightspeed.h
+++ b/libc3/window/cairo/demo/lightspeed.h
@@ -17,9 +17,8 @@
#define LIGHTSPEED_STARS 1000
-bool lightspeed_load (s_sequence *seq);
-void lightspeed_render (s_window_cairo *window,
- cairo_t *cr,
- s_sequence *seq);
+bool lightspeed_load (s_sequence *seq, s_window_cairo *window);
+bool lightspeed_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr);
#endif /* LIGHTSPEED_H */
diff --git a/libc3/window/cairo/demo/sources.mk b/libc3/window/cairo/demo/sources.mk
index 80ba532..d98f3d4 100644
--- a/libc3/window/cairo/demo/sources.mk
+++ b/libc3/window/cairo/demo/sources.mk
@@ -2,10 +2,12 @@
HEADERS = \
bg_rect.h \
lightspeed.h \
+ toasters.h \
window_cairo_demo.h \
SOURCES = \
bg_rect.c \
lightspeed.c \
+ toasters.c \
window_cairo_demo.c \
diff --git a/libc3/window/cairo/demo/sources.sh b/libc3/window/cairo/demo/sources.sh
index 3effa5f..4bff3a2 100644
--- a/libc3/window/cairo/demo/sources.sh
+++ b/libc3/window/cairo/demo/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='bg_rect.h lightspeed.h window_cairo_demo.h '
-SOURCES='bg_rect.c lightspeed.c window_cairo_demo.c '
+HEADERS='bg_rect.h lightspeed.h toasters.h window_cairo_demo.h '
+SOURCES='bg_rect.c lightspeed.c toasters.c window_cairo_demo.c '
diff --git a/libc3/window/cairo/demo/toasters.c b/libc3/window/cairo/demo/toasters.c
new file mode 100644
index 0000000..78284dc
--- /dev/null
+++ b/libc3/window/cairo/demo/toasters.c
@@ -0,0 +1,114 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <libc3/c3.h>
+#include "../cairo_sprite.h"
+#include "toasters.h"
+
+static const f64 g_speed_x = 10.0;
+static const f64 g_speed_y = -2.0;
+s_cairo_sprite g_toast_sprite = {0};
+s_cairo_sprite g_toaster_sprite = {0};
+
+static s_tag * toaster_init (s_tag *toaster, f64 y)
+{
+ tag_init_map(toaster, 4);
+ tag_init_sym(toaster->data.map.keys, sym_1("size"));
+ tag_init_f64(toaster->data.map.values, 0);
+ tag_init_sym(toaster->data.map.keys + 1, sym_1("speed"));
+ tag_init_f64(toaster->data.map.values + 1, 0);
+ tag_init_sym(toaster->data.map.keys + 2, sym_1("x"));
+ tag_init_f64(toaster->data.map.values + 2, 0);
+ tag_init_sym(toaster->data.map.keys + 3, sym_1("y"));
+ tag_init_f64(toaster->data.map.values + 3, y);
+ return toaster;
+}
+
+static void toaster_render (s_tag *toaster, s_window_cairo *window,
+ cairo_t *cr, s_sequence *seq)
+{
+ f64 *size;
+ f64 *speed;
+ f64 *x;
+ f64 *y;
+ if (toaster->type == TAG_MAP) {
+ size = &toaster->data.map.values[0].data.f64;
+ speed = &toaster->data.map.values[1].data.f64;
+ x = &toaster->data.map.values[2].data.f64;
+ y = &toaster->data.map.values[3].data.f64;
+ *speed += seq->dt;
+ *size += *speed * 10.0;
+ *x += *speed * g_speed_x;
+ *y += *speed * g_speed_y;
+ if (*x > window->w || *y < 0.0) {
+ tag_clean(toaster);
+ toaster->type = TAG_VOID;
+ return;
+ }
+ cairo_sprite_blit(&g_toaster_sprite,
+ ((uw) seq->t) % g_toaster_sprite.frame_count,
+ cr, *x, *y);
+ }
+}
+
+bool toasters_load (s_sequence *seq,
+ s_window_cairo *window)
+{
+ f64 y = 0.0;
+ tag_clean(&seq->tag);
+ tag_init_list(&seq->tag, NULL);
+ while (y < window->h - window->w * g_speed_y / g_speed_x) {
+ tag_init_list(&seq->tag, list_new_f64(y, seq->tag.data.list));
+ y += 100.0;
+ }
+ return true;
+}
+
+bool toasters_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr)
+{
+ s_list *first;
+ s_list *i;
+ s_list *j;
+ f64 x;
+ f64 y;
+ cairo_set_source_rgb(cr, 0.7, 0.95, 1.0);
+ cairo_rectangle(cr, 0, 0, window->w, window->h);
+ cairo_fill(cr);
+ io_inspect(&seq->tag);
+ if (seq->tag.type == TAG_LIST) {
+ i = seq->tag.data.list;
+ while (i) {
+ j = NULL;
+ if (i->tag.type == TAG_LIST)
+ j = i->tag.data.list;
+ if (j && j->tag.type == TAG_F64) {
+ y = i->tag.data.list->tag.data.f64;
+ first = list_next(j);
+ x = 1000.0;
+ if (first && first->tag.type == TAG_MAP)
+ x = j->tag.data.map.values[2].data.f64;
+ if (x > 100) {
+ i->tag.data.list = list_new(i->tag.data.list);
+ toaster_init(&i->tag.data.list->tag, y);
+ }
+ j = list_next(j);
+ while (j) {
+ toaster_render(&j->tag, window, cr, seq);
+ j = list_next(j);
+ }
+ }
+ i = list_next(i);
+ }
+ }
+ return true;
+}
diff --git a/libc3/window/cairo/demo/toasters.h b/libc3/window/cairo/demo/toasters.h
new file mode 100644
index 0000000..630d4e9
--- /dev/null
+++ b/libc3/window/cairo/demo/toasters.h
@@ -0,0 +1,25 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef TOASTERS_H
+#define TOASTERS_H
+
+#include "../types.h"
+
+extern s_cairo_sprite g_toast_sprite;
+extern s_cairo_sprite g_toaster_sprite;
+
+bool toasters_load (s_sequence *seq, s_window_cairo *window);
+bool toasters_render (s_sequence *seq, s_window_cairo *window,
+ cairo_t *cr);
+
+#endif /* TOASTERS_H */
diff --git a/libc3/window/cairo/demo/window_cairo_demo.c b/libc3/window/cairo/demo/window_cairo_demo.c
index ed19fde..7a3b181 100644
--- a/libc3/window/cairo/demo/window_cairo_demo.c
+++ b/libc3/window/cairo/demo/window_cairo_demo.c
@@ -18,13 +18,14 @@
#include <xkbcommon/xkbcommon.h>
#include "../../window.h"
#include "../window_cairo.h"
+#include "../cairo_png.h"
#include "window_cairo_demo.h"
-#include "../types.h"
#include "bg_rect.h"
#include "lightspeed.h"
+#include "toasters.h"
bool window_cairo_demo_button (s_window_cairo *window, u8 button,
- sw x, sw y)
+ sw x, sw y)
{
assert(window);
(void) window;
@@ -77,12 +78,17 @@ bool window_cairo_demo_load (s_window_cairo *window)
window_cairo_sequence_init(window->sequence + 1, 30.0,
"02. Lightspeed",
lightspeed_load, lightspeed_render);
+ g_toaster_sprite.surface = cairo_png_1("img/flaps.png");
+ g_toast_sprite.surface = cairo_png_1("img/toast.png");
+ window_cairo_sequence_init(window->sequence + 2, 30.0,
+ "03. Toasters",
+ toasters_load, toasters_render);
window_set_sequence_pos((s_window *) window, 0);
return true;
}
bool window_cairo_demo_render (s_window_cairo *window,
- cairo_t *cr)
+ cairo_t *cr)
{
s_sequence *seq;
cairo_text_extents_t te;
@@ -91,7 +97,7 @@ bool window_cairo_demo_render (s_window_cairo *window,
if (! window_animate((s_window *) window))
return false;
seq = window->sequence + window->sequence_pos;
- seq->render(window, cr, seq);
+ seq->render(seq, window, cr);
/* text */
cairo_set_font_size(cr, 20);
cairo_select_font_face(cr, "Courier New",
diff --git a/libc3/window/cairo/demo/window_cairo_demo.h b/libc3/window/cairo/demo/window_cairo_demo.h
index 3348ea7..81ef80b 100644
--- a/libc3/window/cairo/demo/window_cairo_demo.h
+++ b/libc3/window/cairo/demo/window_cairo_demo.h
@@ -15,7 +15,7 @@
#include "../types.h"
-#define WINDOW_CAIRO_DEMO_SEQUENCE_COUNT 2
+#define WINDOW_CAIRO_DEMO_SEQUENCE_COUNT 3
bool window_cairo_demo_button (s_window_cairo *window, u8 button,
sw x, sw y);
diff --git a/libc3/window/cairo/quartz/demo/Makefile b/libc3/window/cairo/quartz/demo/Makefile
index abafe8e..d1cd6fb 100644
--- a/libc3/window/cairo/quartz/demo/Makefile
+++ b/libc3/window/cairo/quartz/demo/Makefile
@@ -22,6 +22,7 @@ DISTCLEANFILES = ${CLEANFILES} config.mk
build:
${MAKE} ${APP_PROG}
${MAKE} ${APP}/Contents/Frameworks
+ rsync -aP --delete ../../../../../lib ${APP}/Contents/
all:
${MAKE} build
@@ -32,6 +33,7 @@ all:
asan:
${MAKE} ${APP_PROG_ASAN}
${MAKE} ${APP_ASAN}/Contents/Frameworks
+ rsync -aP --delete ../../../../../lib ${APP_ASAN}/Contents/
clean:
rm -rf ${CLEANFILES}
@@ -42,10 +44,12 @@ clean_cov:
cov:
${MAKE} ${APP_PROG_COV}
${MAKE} ${APP_COV}/Contents/Frameworks
+ rsync -aP --delete ../../../../../lib ${APP_COV}/Contents/
debug:
${MAKE} ${APP_PROG_DEBUG}
${MAKE} ${APP_DEBUG}/Contents/Frameworks
+ rsync -aP --delete ../../../../../lib ${APP_DEBUG}/Contents/
demo: build
time ${APP_PROG}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/array.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/array.facts
new file mode 100644
index 0000000..4bcb97c
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/array.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {Array, :is_a, :module}
+add {Array, :symbol, Array.data}
+replace {Array.data, :cfn, cfn :tag "array_data_tag" (:tag, :tag, :&result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/c3.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/c3.facts
new file mode 100644
index 0000000..0bdbba9
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/c3.facts
@@ -0,0 +1,188 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {C3, :is_a, :module}
+replace {C3, :operator, C3.operator00}
+replace {C3.operator00, :is_a, :operator}
+replace {C3.operator00, :symbol, :"()"}
+replace {C3.operator00, :arity, 1}
+replace {C3.operator00, :cfn, cfn Tag "tag_paren" (Tag, Result)}
+replace {C3.operator00, :operator_precedence, 13}
+replace {C3.operator00, :operator_associativity, :left}
+add {C3, :operator, C3.operator01}
+replace {C3.operator01, :is_a, :operator}
+replace {C3.operator01, :symbol, :"[]"}
+replace {C3.operator01, :arity, 2}
+replace {C3.operator01, :cfn, cfn Tag "tag_brackets" (Tag, Tag, Result)}
+replace {C3.operator01, :operator_precedence, 13}
+replace {C3.operator01, :operator_associativity, :left}
+add {C3, :operator, C3.operator02}
+replace {C3.operator02, :is_a, :operator}
+replace {C3.operator02, :symbol, :!}
+replace {C3.operator02, :arity, 1}
+replace {C3.operator02, :cfn, cfn Bool "tag_not" (Tag, Result)}
+replace {C3.operator02, :operator_precedence, 12}
+replace {C3.operator02, :operator_associativity, :right}
+add {C3, :operator, C3.operator03}
+replace {C3.operator03, :is_a, :operator}
+replace {C3.operator03, :symbol, :~}
+replace {C3.operator03, :arity, 1}
+replace {C3.operator03, :cfn, cfn Tag "tag_bnot" (Tag, Result)}
+replace {C3.operator03, :operator_precedence, 12}
+replace {C3.operator03, :operator_associativity, :right}
+add {C3, :operator, C3.operator04}
+replace {C3.operator04, :is_a, :operator}
+replace {C3.operator04, :symbol, :-}
+replace {C3.operator04, :arity, 1}
+replace {C3.operator04, :cfn, cfn Tag "tag_neg" (Tag, Result)}
+replace {C3.operator04, :operator_precedence, 12}
+replace {C3.operator04, :operator_associativity, :right}
+add {C3, :operator, C3.operator05}
+replace {C3.operator05, :is_a, :operator}
+replace {C3.operator05, :symbol, :*}
+replace {C3.operator05, :arity, 2}
+replace {C3.operator05, :cfn, cfn Tag "tag_mul" (Tag, Tag, Result)}
+replace {C3.operator05, :operator_precedence, 11}
+replace {C3.operator05, :operator_associativity, :left}
+add {C3, :operator, C3.operator06}
+replace {C3.operator06, :is_a, :operator}
+replace {C3.operator06, :symbol, :/}
+replace {C3.operator06, :arity, 2}
+replace {C3.operator06, :cfn, cfn Tag "tag_div" (Tag, Tag, Result)}
+replace {C3.operator06, :operator_precedence, 11}
+replace {C3.operator06, :operator_associativity, :left}
+add {C3, :operator, C3.operator07}
+replace {C3.operator07, :is_a, :operator}
+replace {C3.operator07, :symbol, :mod}
+replace {C3.operator07, :arity, 2}
+replace {C3.operator07, :cfn, cfn Tag "tag_mod" (Tag, Tag, Result)}
+replace {C3.operator07, :operator_precedence, 11}
+replace {C3.operator07, :operator_associativity, :left}
+add {C3, :operator, C3.operator08}
+replace {C3.operator08, :is_a, :operator}
+replace {C3.operator08, :symbol, :+}
+replace {C3.operator08, :arity, 2}
+replace {C3.operator08, :cfn, cfn Tag "tag_add" (Tag, Tag, Result)}
+replace {C3.operator08, :operator_precedence, 10}
+replace {C3.operator08, :operator_associativity, :left}
+add {C3, :operator, C3.operator09}
+replace {C3.operator09, :is_a, :operator}
+replace {C3.operator09, :symbol, :-}
+replace {C3.operator09, :arity, 2}
+replace {C3.operator09, :cfn, cfn Tag "tag_sub" (Tag, Tag, Result)}
+replace {C3.operator09, :operator_precedence, 10}
+replace {C3.operator09, :operator_associativity, :left}
+add {C3, :operator, C3.operator10}
+replace {C3.operator10, :is_a, :operator}
+replace {C3.operator10, :symbol, :<<}
+replace {C3.operator10, :arity, 2}
+replace {C3.operator10, :cfn, cfn Tag "tag_shift_left" (Tag, Tag, Result)}
+replace {C3.operator10, :operator_precedence, 9}
+replace {C3.operator10, :operator_associativity, :left}
+add {C3, :operator, C3.operator11}
+replace {C3.operator11, :is_a, :operator}
+replace {C3.operator11, :symbol, :>>}
+replace {C3.operator11, :arity, 2}
+replace {C3.operator11, :cfn, cfn Tag "tag_shift_right" (Tag, Tag, Result)}
+replace {C3.operator11, :operator_precedence, 9}
+replace {C3.operator11, :operator_associativity, :left}
+add {C3, :operator, C3.operator12}
+replace {C3.operator12, :is_a, :operator}
+replace {C3.operator12, :symbol, :<}
+replace {C3.operator12, :arity, 2}
+replace {C3.operator12, :cfn, cfn Bool "tag_lt" (Tag, Tag, Result)}
+replace {C3.operator12, :operator_precedence, 8}
+replace {C3.operator12, :operator_associativity, :left}
+add {C3, :operator, C3.operator13}
+replace {C3.operator13, :symbol, :<=}
+replace {C3.operator13, :is_a, :operator}
+replace {C3.operator13, :arity, 2}
+replace {C3.operator13, :cfn, cfn Bool "tag_lte" (Tag, Tag, Result)}
+replace {C3.operator13, :operator_precedence, 8}
+replace {C3.operator13, :operator_associativity, :left}
+add {C3, :operator, C3.operator14}
+replace {C3.operator14, :symbol, :>}
+replace {C3.operator14, :is_a, :operator}
+replace {C3.operator14, :arity, 2}
+replace {C3.operator14, :cfn, cfn Bool "tag_gt" (Tag, Tag, Result)}
+replace {C3.operator14, :operator_precedence, 8}
+replace {C3.operator14, :operator_associativity, :left}
+add {C3, :operator, C3.operator15}
+replace {C3.operator15, :symbol, :>=}
+replace {C3.operator15, :is_a, :operator}
+replace {C3.operator15, :arity, 2}
+replace {C3.operator15, :cfn, cfn Bool "tag_gte" (Tag, Tag, Result)}
+replace {C3.operator15, :operator_precedence, 8}
+replace {C3.operator15, :operator_associativity, :left}
+add {C3, :operator, C3.operator16}
+replace {C3.operator16, :is_a, :operator}
+replace {C3.operator16, :symbol, :==}
+replace {C3.operator16, :arity, 2}
+replace {C3.operator16, :cfn, cfn Bool "tag_eq" (Tag, Tag, Result)}
+replace {C3.operator16, :operator_precedence, 7}
+replace {C3.operator16, :operator_associativity, :left}
+add {C3, :operator, C3.operator17}
+replace {C3.operator17, :is_a, :operator}
+replace {C3.operator17, :symbol, :!=}
+replace {C3.operator17, :arity, 2}
+replace {C3.operator17, :cfn, cfn Bool "tag_not_eq" (Tag, Tag, Result)}
+replace {C3.operator17, :operator_precedence, 7}
+replace {C3.operator17, :operator_associativity, :left}
+add {C3, :operator, C3.operator18}
+replace {C3.operator18, :is_a, :operator}
+replace {C3.operator18, :symbol, :&}
+replace {C3.operator18, :arity, 2}
+replace {C3.operator18, :cfn, cfn Tag "tag_band" (Tag, Tag, Result)}
+replace {C3.operator18, :operator_precedence, 6}
+replace {C3.operator18, :operator_associativity, :left}
+add {C3, :operator, C3.operator19}
+replace {C3.operator19, :is_a, :operator}
+replace {C3.operator19, :symbol, :^}
+replace {C3.operator19, :arity, 2}
+replace {C3.operator19, :cfn, cfn Tag "tag_bxor" (Tag, Tag, Result)}
+replace {C3.operator19, :operator_precedence, 5}
+replace {C3.operator19, :operator_associativity, :left}
+add {C3, :operator, C3.operator20}
+replace {C3.operator20, :is_a, :operator}
+replace {C3.operator20, :symbol, :bor}
+replace {C3.operator20, :arity, 2}
+replace {C3.operator20, :cfn, cfn Tag "tag_bor" (Tag, Tag, Result)}
+replace {C3.operator20, :operator_precedence, 4}
+replace {C3.operator20, :operator_associativity, :left}
+add {C3, :operator, C3.operator21}
+replace {C3.operator21, :is_a, :operator}
+replace {C3.operator21, :symbol, :&&}
+replace {C3.operator21, :arity, 2}
+replace {C3.operator21, :cfn, cfn Bool "tag_and" (Tag, Tag, Result)}
+replace {C3.operator21, :operator_precedence, 3}
+replace {C3.operator21, :operator_associativity, :left}
+add {C3, :operator, C3.operator22}
+replace {C3.operator22, :is_a, :operator}
+replace {C3.operator22, :symbol, :||}
+replace {C3.operator22, :arity, 2}
+replace {C3.operator22, :cfn, cfn Bool "tag_or" (Tag, Tag, Result)}
+replace {C3.operator22, :operator_precedence, 2}
+replace {C3.operator22, :operator_associativity, :left}
+add {C3, :operator, C3.operator23}
+replace {C3.operator23, :is_a, :operator}
+add {C3.operator23, :is_a, :special_operator}
+replace {C3.operator23, :symbol, :=}
+replace {C3.operator23, :arity, 2}
+replace {C3.operator23, :cfn, cfn Tag "tag_equal" (Tag, Tag, Result)}
+replace {C3.operator23, :operator_precedence, 1}
+replace {C3.operator23, :operator_associativity, :right}
+replace {C3.break, :cfn, cfn Void "c3_break" ()}
+replace {C3, :symbol, C3.first}
+replace {C3.first, :fn, fn {
+ ([a | _b]) { a }
+ ({a, _b}) { a }
+ ({a, _b, _c}) { a }
+ ({a, _b, _c, _d}) { a }
+}}
+add {C3, :symbol, C3.license}
+replace {C3.license, :cfn, cfn Void "c3_license" ()}
+add {C3, :symbol, C3.type}
+replace {C3.type, :cfn, cfn Sym "tag_type" (Tag, Result)}
+add {C3, :symbol, C3.fib}
+replace {C3.fib, :fn, fn { (0) { 1 }
+ (1) { 1 }
+ (x) { fib(x - 1) + fib(x - 2) } }}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/integer.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/integer.facts
new file mode 100644
index 0000000..ff8d8e7
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/integer.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Integer, :is_a, :module}
+replace {Integer, :symbol, Integer.cast}
+replace {Integer.cast, :cfn, cfn Integer "integer_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/list.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/list.facts
new file mode 100644
index 0000000..ea05f14
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/list.facts
@@ -0,0 +1,20 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {List, :is_a, :module}
+add {List, :symbol, List.cast}
+add {List, :symbol, List.map}
+add {List, :symbol, List.reverse}
+replace {List.cast, :cfn, cfn :list "list_cast" (:tag, :&result)}
+replace {List.map, :fn, fn {
+ ([], _) {
+ []
+ }
+ ([a | b], f) {
+ [f(a) | List.map(b, f)]
+ }
+}}
+replace {List.reverse, :fn, fn {
+ (x) { List.reverse(x, []) }
+ ([], acc) { acc }
+ ([a | b], acc) { List.reverse(b, [a | acc]) }
+}}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/map.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/map.facts
new file mode 100644
index 0000000..de43112
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/map.facts
@@ -0,0 +1,11 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {Map, :is_a, :module}
+add {Map, :symbol, Map.cast}
+add {Map, :symbol, Map.map}
+add {Map, :symbol, Map.to_list}
+replace {Map.cast, :cfn, cfn Map "map_cast" (Tag, Result)}
+replace {Map.map, :cfn, cfn List "map_map" (Map, Fn, Result)}
+replace {Map.to_list, :fn, fn (%{} = map) {
+ Map.map(map, fn (k, v) { {k, v} })
+}}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s16.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s16.facts
new file mode 100644
index 0000000..2a202d1
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s16.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S16, :is_a, :module}
+replace {S16, :symbol, S16.cast}
+replace {S16.cast, :cfn, cfn S16 "s16_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s32.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s32.facts
new file mode 100644
index 0000000..fcbce6e
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s32.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S32, :is_a, :module}
+replace {S32, :symbol, S32.cast}
+replace {S32.cast, :cfn, cfn S32 "s32_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s64.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s64.facts
new file mode 100644
index 0000000..0e39a05
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s64.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S64, :is_a, :module}
+replace {S64, :symbol, S64.cast}
+replace {S64.cast, :cfn, cfn S64 "s64_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s8.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s8.facts
new file mode 100644
index 0000000..746d7ff
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/s8.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S8, :is_a, :module}
+replace {S8, :symbol, S8.cast}
+replace {S8.cast, :cfn, cfn S8 "s8_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/sw.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/sw.facts
new file mode 100644
index 0000000..f9ec974
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/sw.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Sw, :is_a, :module}
+replace {Sw, :symbol, Sw.cast}
+replace {Sw.cast, :cfn, cfn Sw "sw_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u16.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u16.facts
new file mode 100644
index 0000000..ee7d50c
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u16.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U16, :is_a, :module}
+replace {U16, :symbol, U16.cast}
+replace {U16.cast, :cfn, cfn U16 "u16_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u32.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u32.facts
new file mode 100644
index 0000000..29e6146
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u32.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U32, :is_a, :module}
+replace {U32, :symbol, U32.cast}
+replace {U32.cast, :cfn, cfn U32 "u32_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u64.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u64.facts
new file mode 100644
index 0000000..7cea2fe
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u64.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U64, :is_a, :module}
+replace {U64, :symbol, U64.cast}
+replace {U64.cast, :cfn, cfn U64 "u64_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u8.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u8.facts
new file mode 100644
index 0000000..39e73d0
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/u8.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U8, :is_a, :module}
+replace {U8, :symbol, U8.cast}
+replace {U8.cast, :cfn, cfn U8 "u8_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/uw.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/uw.facts
new file mode 100644
index 0000000..c4a25a5
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo.app/Contents/lib/c3/0.1/uw.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Uw, :is_a, :module}
+replace {Uw, :symbol, Uw.cast}
+replace {Uw.cast, :cfn, cfn Uw "uw_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/array.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/array.facts
new file mode 100644
index 0000000..4bcb97c
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/array.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {Array, :is_a, :module}
+add {Array, :symbol, Array.data}
+replace {Array.data, :cfn, cfn :tag "array_data_tag" (:tag, :tag, :&result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/c3.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/c3.facts
new file mode 100644
index 0000000..0bdbba9
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/c3.facts
@@ -0,0 +1,188 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {C3, :is_a, :module}
+replace {C3, :operator, C3.operator00}
+replace {C3.operator00, :is_a, :operator}
+replace {C3.operator00, :symbol, :"()"}
+replace {C3.operator00, :arity, 1}
+replace {C3.operator00, :cfn, cfn Tag "tag_paren" (Tag, Result)}
+replace {C3.operator00, :operator_precedence, 13}
+replace {C3.operator00, :operator_associativity, :left}
+add {C3, :operator, C3.operator01}
+replace {C3.operator01, :is_a, :operator}
+replace {C3.operator01, :symbol, :"[]"}
+replace {C3.operator01, :arity, 2}
+replace {C3.operator01, :cfn, cfn Tag "tag_brackets" (Tag, Tag, Result)}
+replace {C3.operator01, :operator_precedence, 13}
+replace {C3.operator01, :operator_associativity, :left}
+add {C3, :operator, C3.operator02}
+replace {C3.operator02, :is_a, :operator}
+replace {C3.operator02, :symbol, :!}
+replace {C3.operator02, :arity, 1}
+replace {C3.operator02, :cfn, cfn Bool "tag_not" (Tag, Result)}
+replace {C3.operator02, :operator_precedence, 12}
+replace {C3.operator02, :operator_associativity, :right}
+add {C3, :operator, C3.operator03}
+replace {C3.operator03, :is_a, :operator}
+replace {C3.operator03, :symbol, :~}
+replace {C3.operator03, :arity, 1}
+replace {C3.operator03, :cfn, cfn Tag "tag_bnot" (Tag, Result)}
+replace {C3.operator03, :operator_precedence, 12}
+replace {C3.operator03, :operator_associativity, :right}
+add {C3, :operator, C3.operator04}
+replace {C3.operator04, :is_a, :operator}
+replace {C3.operator04, :symbol, :-}
+replace {C3.operator04, :arity, 1}
+replace {C3.operator04, :cfn, cfn Tag "tag_neg" (Tag, Result)}
+replace {C3.operator04, :operator_precedence, 12}
+replace {C3.operator04, :operator_associativity, :right}
+add {C3, :operator, C3.operator05}
+replace {C3.operator05, :is_a, :operator}
+replace {C3.operator05, :symbol, :*}
+replace {C3.operator05, :arity, 2}
+replace {C3.operator05, :cfn, cfn Tag "tag_mul" (Tag, Tag, Result)}
+replace {C3.operator05, :operator_precedence, 11}
+replace {C3.operator05, :operator_associativity, :left}
+add {C3, :operator, C3.operator06}
+replace {C3.operator06, :is_a, :operator}
+replace {C3.operator06, :symbol, :/}
+replace {C3.operator06, :arity, 2}
+replace {C3.operator06, :cfn, cfn Tag "tag_div" (Tag, Tag, Result)}
+replace {C3.operator06, :operator_precedence, 11}
+replace {C3.operator06, :operator_associativity, :left}
+add {C3, :operator, C3.operator07}
+replace {C3.operator07, :is_a, :operator}
+replace {C3.operator07, :symbol, :mod}
+replace {C3.operator07, :arity, 2}
+replace {C3.operator07, :cfn, cfn Tag "tag_mod" (Tag, Tag, Result)}
+replace {C3.operator07, :operator_precedence, 11}
+replace {C3.operator07, :operator_associativity, :left}
+add {C3, :operator, C3.operator08}
+replace {C3.operator08, :is_a, :operator}
+replace {C3.operator08, :symbol, :+}
+replace {C3.operator08, :arity, 2}
+replace {C3.operator08, :cfn, cfn Tag "tag_add" (Tag, Tag, Result)}
+replace {C3.operator08, :operator_precedence, 10}
+replace {C3.operator08, :operator_associativity, :left}
+add {C3, :operator, C3.operator09}
+replace {C3.operator09, :is_a, :operator}
+replace {C3.operator09, :symbol, :-}
+replace {C3.operator09, :arity, 2}
+replace {C3.operator09, :cfn, cfn Tag "tag_sub" (Tag, Tag, Result)}
+replace {C3.operator09, :operator_precedence, 10}
+replace {C3.operator09, :operator_associativity, :left}
+add {C3, :operator, C3.operator10}
+replace {C3.operator10, :is_a, :operator}
+replace {C3.operator10, :symbol, :<<}
+replace {C3.operator10, :arity, 2}
+replace {C3.operator10, :cfn, cfn Tag "tag_shift_left" (Tag, Tag, Result)}
+replace {C3.operator10, :operator_precedence, 9}
+replace {C3.operator10, :operator_associativity, :left}
+add {C3, :operator, C3.operator11}
+replace {C3.operator11, :is_a, :operator}
+replace {C3.operator11, :symbol, :>>}
+replace {C3.operator11, :arity, 2}
+replace {C3.operator11, :cfn, cfn Tag "tag_shift_right" (Tag, Tag, Result)}
+replace {C3.operator11, :operator_precedence, 9}
+replace {C3.operator11, :operator_associativity, :left}
+add {C3, :operator, C3.operator12}
+replace {C3.operator12, :is_a, :operator}
+replace {C3.operator12, :symbol, :<}
+replace {C3.operator12, :arity, 2}
+replace {C3.operator12, :cfn, cfn Bool "tag_lt" (Tag, Tag, Result)}
+replace {C3.operator12, :operator_precedence, 8}
+replace {C3.operator12, :operator_associativity, :left}
+add {C3, :operator, C3.operator13}
+replace {C3.operator13, :symbol, :<=}
+replace {C3.operator13, :is_a, :operator}
+replace {C3.operator13, :arity, 2}
+replace {C3.operator13, :cfn, cfn Bool "tag_lte" (Tag, Tag, Result)}
+replace {C3.operator13, :operator_precedence, 8}
+replace {C3.operator13, :operator_associativity, :left}
+add {C3, :operator, C3.operator14}
+replace {C3.operator14, :symbol, :>}
+replace {C3.operator14, :is_a, :operator}
+replace {C3.operator14, :arity, 2}
+replace {C3.operator14, :cfn, cfn Bool "tag_gt" (Tag, Tag, Result)}
+replace {C3.operator14, :operator_precedence, 8}
+replace {C3.operator14, :operator_associativity, :left}
+add {C3, :operator, C3.operator15}
+replace {C3.operator15, :symbol, :>=}
+replace {C3.operator15, :is_a, :operator}
+replace {C3.operator15, :arity, 2}
+replace {C3.operator15, :cfn, cfn Bool "tag_gte" (Tag, Tag, Result)}
+replace {C3.operator15, :operator_precedence, 8}
+replace {C3.operator15, :operator_associativity, :left}
+add {C3, :operator, C3.operator16}
+replace {C3.operator16, :is_a, :operator}
+replace {C3.operator16, :symbol, :==}
+replace {C3.operator16, :arity, 2}
+replace {C3.operator16, :cfn, cfn Bool "tag_eq" (Tag, Tag, Result)}
+replace {C3.operator16, :operator_precedence, 7}
+replace {C3.operator16, :operator_associativity, :left}
+add {C3, :operator, C3.operator17}
+replace {C3.operator17, :is_a, :operator}
+replace {C3.operator17, :symbol, :!=}
+replace {C3.operator17, :arity, 2}
+replace {C3.operator17, :cfn, cfn Bool "tag_not_eq" (Tag, Tag, Result)}
+replace {C3.operator17, :operator_precedence, 7}
+replace {C3.operator17, :operator_associativity, :left}
+add {C3, :operator, C3.operator18}
+replace {C3.operator18, :is_a, :operator}
+replace {C3.operator18, :symbol, :&}
+replace {C3.operator18, :arity, 2}
+replace {C3.operator18, :cfn, cfn Tag "tag_band" (Tag, Tag, Result)}
+replace {C3.operator18, :operator_precedence, 6}
+replace {C3.operator18, :operator_associativity, :left}
+add {C3, :operator, C3.operator19}
+replace {C3.operator19, :is_a, :operator}
+replace {C3.operator19, :symbol, :^}
+replace {C3.operator19, :arity, 2}
+replace {C3.operator19, :cfn, cfn Tag "tag_bxor" (Tag, Tag, Result)}
+replace {C3.operator19, :operator_precedence, 5}
+replace {C3.operator19, :operator_associativity, :left}
+add {C3, :operator, C3.operator20}
+replace {C3.operator20, :is_a, :operator}
+replace {C3.operator20, :symbol, :bor}
+replace {C3.operator20, :arity, 2}
+replace {C3.operator20, :cfn, cfn Tag "tag_bor" (Tag, Tag, Result)}
+replace {C3.operator20, :operator_precedence, 4}
+replace {C3.operator20, :operator_associativity, :left}
+add {C3, :operator, C3.operator21}
+replace {C3.operator21, :is_a, :operator}
+replace {C3.operator21, :symbol, :&&}
+replace {C3.operator21, :arity, 2}
+replace {C3.operator21, :cfn, cfn Bool "tag_and" (Tag, Tag, Result)}
+replace {C3.operator21, :operator_precedence, 3}
+replace {C3.operator21, :operator_associativity, :left}
+add {C3, :operator, C3.operator22}
+replace {C3.operator22, :is_a, :operator}
+replace {C3.operator22, :symbol, :||}
+replace {C3.operator22, :arity, 2}
+replace {C3.operator22, :cfn, cfn Bool "tag_or" (Tag, Tag, Result)}
+replace {C3.operator22, :operator_precedence, 2}
+replace {C3.operator22, :operator_associativity, :left}
+add {C3, :operator, C3.operator23}
+replace {C3.operator23, :is_a, :operator}
+add {C3.operator23, :is_a, :special_operator}
+replace {C3.operator23, :symbol, :=}
+replace {C3.operator23, :arity, 2}
+replace {C3.operator23, :cfn, cfn Tag "tag_equal" (Tag, Tag, Result)}
+replace {C3.operator23, :operator_precedence, 1}
+replace {C3.operator23, :operator_associativity, :right}
+replace {C3.break, :cfn, cfn Void "c3_break" ()}
+replace {C3, :symbol, C3.first}
+replace {C3.first, :fn, fn {
+ ([a | _b]) { a }
+ ({a, _b}) { a }
+ ({a, _b, _c}) { a }
+ ({a, _b, _c, _d}) { a }
+}}
+add {C3, :symbol, C3.license}
+replace {C3.license, :cfn, cfn Void "c3_license" ()}
+add {C3, :symbol, C3.type}
+replace {C3.type, :cfn, cfn Sym "tag_type" (Tag, Result)}
+add {C3, :symbol, C3.fib}
+replace {C3.fib, :fn, fn { (0) { 1 }
+ (1) { 1 }
+ (x) { fib(x - 1) + fib(x - 2) } }}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/integer.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/integer.facts
new file mode 100644
index 0000000..ff8d8e7
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/integer.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Integer, :is_a, :module}
+replace {Integer, :symbol, Integer.cast}
+replace {Integer.cast, :cfn, cfn Integer "integer_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/list.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/list.facts
new file mode 100644
index 0000000..ea05f14
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/list.facts
@@ -0,0 +1,20 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {List, :is_a, :module}
+add {List, :symbol, List.cast}
+add {List, :symbol, List.map}
+add {List, :symbol, List.reverse}
+replace {List.cast, :cfn, cfn :list "list_cast" (:tag, :&result)}
+replace {List.map, :fn, fn {
+ ([], _) {
+ []
+ }
+ ([a | b], f) {
+ [f(a) | List.map(b, f)]
+ }
+}}
+replace {List.reverse, :fn, fn {
+ (x) { List.reverse(x, []) }
+ ([], acc) { acc }
+ ([a | b], acc) { List.reverse(b, [a | acc]) }
+}}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/map.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/map.facts
new file mode 100644
index 0000000..de43112
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/map.facts
@@ -0,0 +1,11 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+add {Map, :is_a, :module}
+add {Map, :symbol, Map.cast}
+add {Map, :symbol, Map.map}
+add {Map, :symbol, Map.to_list}
+replace {Map.cast, :cfn, cfn Map "map_cast" (Tag, Result)}
+replace {Map.map, :cfn, cfn List "map_map" (Map, Fn, Result)}
+replace {Map.to_list, :fn, fn (%{} = map) {
+ Map.map(map, fn (k, v) { {k, v} })
+}}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s16.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s16.facts
new file mode 100644
index 0000000..2a202d1
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s16.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S16, :is_a, :module}
+replace {S16, :symbol, S16.cast}
+replace {S16.cast, :cfn, cfn S16 "s16_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s32.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s32.facts
new file mode 100644
index 0000000..fcbce6e
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s32.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S32, :is_a, :module}
+replace {S32, :symbol, S32.cast}
+replace {S32.cast, :cfn, cfn S32 "s32_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s64.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s64.facts
new file mode 100644
index 0000000..0e39a05
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s64.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S64, :is_a, :module}
+replace {S64, :symbol, S64.cast}
+replace {S64.cast, :cfn, cfn S64 "s64_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s8.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s8.facts
new file mode 100644
index 0000000..746d7ff
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/s8.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {S8, :is_a, :module}
+replace {S8, :symbol, S8.cast}
+replace {S8.cast, :cfn, cfn S8 "s8_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/sw.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/sw.facts
new file mode 100644
index 0000000..f9ec974
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/sw.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Sw, :is_a, :module}
+replace {Sw, :symbol, Sw.cast}
+replace {Sw.cast, :cfn, cfn Sw "sw_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u16.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u16.facts
new file mode 100644
index 0000000..ee7d50c
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u16.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U16, :is_a, :module}
+replace {U16, :symbol, U16.cast}
+replace {U16.cast, :cfn, cfn U16 "u16_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u32.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u32.facts
new file mode 100644
index 0000000..29e6146
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u32.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U32, :is_a, :module}
+replace {U32, :symbol, U32.cast}
+replace {U32.cast, :cfn, cfn U32 "u32_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u64.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u64.facts
new file mode 100644
index 0000000..7cea2fe
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u64.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U64, :is_a, :module}
+replace {U64, :symbol, U64.cast}
+replace {U64.cast, :cfn, cfn U64 "u64_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u8.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u8.facts
new file mode 100644
index 0000000..39e73d0
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/u8.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {U8, :is_a, :module}
+replace {U8, :symbol, U8.cast}
+replace {U8.cast, :cfn, cfn U8 "u8_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/uw.facts b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/uw.facts
new file mode 100644
index 0000000..c4a25a5
--- /dev/null
+++ b/libc3/window/cairo/quartz/demo/c3_window_cairo_quartz_demo_debug.app/Contents/lib/c3/0.1/uw.facts
@@ -0,0 +1,5 @@
+%{module: C3.Facts.Dump,
+ version: 1}
+replace {Uw, :is_a, :module}
+replace {Uw, :symbol, Uw.cast}
+replace {Uw.cast, :cfn, cfn Uw "uw_cast" (Tag, Result)}
diff --git a/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c b/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
index 5b2895f..bc66a73 100644
--- a/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
+++ b/libc3/window/cairo/quartz/demo/window_cairo_quartz_demo.c
@@ -18,9 +18,12 @@
#include "../../demo/window_cairo_demo.h"
#include "../window_cairo_quartz.h"
-int main (void)
+int main (int argc, s8 **argv)
{
+ sw r = 0;
s_window_cairo window;
+ if (! c3_init(NULL, argc, argv))
+ return 1;
window_cairo_init(&window, 0, 0, 800, 600,
"C3.Window.Cairo.Quartz demo",
WINDOW_CAIRO_DEMO_SEQUENCE_COUNT);
@@ -30,6 +33,7 @@ int main (void)
window.render = window_cairo_demo_render;
window.resize = window_cairo_demo_resize;
if (! window_cairo_quartz_run(&window))
- return g_c3_exit_code;
- return 0;
+ r = g_c3_exit_code;
+ c3_clean(NULL);
+ return r;
}
diff --git a/libc3/window/cairo/sources.mk b/libc3/window/cairo/sources.mk
index c3c9eb1..8ca2a45 100644
--- a/libc3/window/cairo/sources.mk
+++ b/libc3/window/cairo/sources.mk
@@ -1,8 +1,12 @@
# sources.mk generated by update_sources
HEADERS = \
+ cairo_png.h \
+ cairo_sprite.h \
types.h \
window_cairo.h \
SOURCES = \
+ cairo_png.c \
+ cairo_sprite.c \
window_cairo.c \
diff --git a/libc3/window/cairo/sources.sh b/libc3/window/cairo/sources.sh
index 3bb9595..baa3a7d 100644
--- a/libc3/window/cairo/sources.sh
+++ b/libc3/window/cairo/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='types.h window_cairo.h '
-SOURCES='window_cairo.c '
+HEADERS='cairo_png.h cairo_sprite.h types.h window_cairo.h '
+SOURCES='cairo_png.c cairo_sprite.c window_cairo.c '
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index 9d35c68..c4a5a44 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -22,6 +22,7 @@
#include <libc3/types.h>
#include "../types.h"
+typedef struct cairo_sprite s_cairo_sprite;
typedef struct rgb s_rgb;
typedef struct rgba s_rgba;
typedef struct window_cairo s_window_cairo;
@@ -48,9 +49,23 @@ typedef bool (*f_window_cairo_render) (s_window_cairo *window,
typedef bool (*f_window_cairo_resize) (s_window_cairo *window,
uw w, uw h);
-typedef void (*f_window_cairo_sequence_render) (s_window_cairo *window,
- cairo_t *cr,
- s_sequence *seq);
+typedef bool (*f_window_cairo_sequence_load) (s_sequence *seq,
+ s_window_cairo *window);
+
+typedef bool (*f_window_cairo_sequence_render) (s_sequence *seq,
+ s_window_cairo *window,
+ cairo_t *cr);
+
+struct cairo_sprite {
+ uw surface_w;
+ uw surface_h;
+ uw dim_x;
+ uw dim_y;
+ uw frame_count;
+ uw w;
+ uw h;
+ cairo_surface_t *surface;
+};
struct rgb {
double r;
diff --git a/libc3/window/cairo/window_cairo.c b/libc3/window/cairo/window_cairo.c
index 31da8d3..6e725c5 100644
--- a/libc3/window/cairo/window_cairo.c
+++ b/libc3/window/cairo/window_cairo.c
@@ -13,6 +13,7 @@
#include <assert.h>
#include <stdlib.h>
#include <xkbcommon/xkbcommon.h>
+#include <libc3/tag.h>
#include "window_cairo.h"
s_window_cairo * window_cairo_init (s_window_cairo *window,
@@ -104,14 +105,16 @@ bool window_cairo_resize_default (s_window_cairo *window, uw w, uw h)
}
s_sequence * window_cairo_sequence_init
-(s_sequence *sequence, f64 duration, const s8 *title,
- f_sequence_load load, f_window_cairo_sequence_render render)
+(s_sequence *seq, f64 duration, const s8 *title,
+ f_window_cairo_sequence_load load,
+ f_window_cairo_sequence_render render)
{
- assert(sequence);
- sequence->t = 0.0;
- sequence->duration = duration;
- sequence->title = title;
- sequence->load = load;
- sequence->render = (f_sequence_render) render;
- return sequence;
+ assert(seq);
+ seq->t = 0.0;
+ seq->duration = duration;
+ seq->title = title;
+ seq->load = (f_sequence_load) load;
+ seq->render = (f_sequence_render) render;
+ tag_init_void(&seq->tag);
+ return seq;
}
diff --git a/libc3/window/cairo/window_cairo.h b/libc3/window/cairo/window_cairo.h
index ebf65e8..9030c6a 100644
--- a/libc3/window/cairo/window_cairo.h
+++ b/libc3/window/cairo/window_cairo.h
@@ -23,7 +23,8 @@ bool window_cairo_run (s_window_cairo *window);
s_sequence * window_cairo_sequence_init
(s_sequence *sequence, f64 duration, const s8 *title,
- f_sequence_load load, f_window_cairo_sequence_render render);
+ f_window_cairo_sequence_load load,
+ f_window_cairo_sequence_render render);
/* callbacks */
bool window_cairo_button_default (s_window_cairo *window, u8 button,
diff --git a/libc3/window/types.h b/libc3/window/types.h
index cbf599b..e321dac 100644
--- a/libc3/window/types.h
+++ b/libc3/window/types.h
@@ -57,7 +57,7 @@ struct window {
f_window_load load;
f_window_motion motion;
f_window_render render;
- void *render_context;
+ void *context;
f_window_resize resize;
s_sequence *sequence;
uw sequence_count;
diff --git a/libc3/window/window.c b/libc3/window/window.c
index c2805d1..1b06bec 100644
--- a/libc3/window/window.c
+++ b/libc3/window/window.c
@@ -58,7 +58,7 @@ bool window_set_sequence_pos (s_window *window, uw sequence_pos)
}
window->sequence_pos = sequence_pos;
printf("%s\n", seq->title);
- if (! seq->load(seq))
+ if (! seq->load(seq, window))
return false;
return true;
}
diff --git a/test/cfn_test.c b/test/cfn_test.c
index eec0d58..58a29a5 100644
--- a/test/cfn_test.c
+++ b/test/cfn_test.c
@@ -54,7 +54,7 @@ TEST_CASE(cfn_apply)
sym_1("bool"));
cfn_link(&a);
cfn_prep_cif(&a);
- args = list_new(NULL, NULL);
+ args = list_new(NULL);
tag_init_bool(&args->tag, false);
TEST_EQ(cfn_apply(&a, args, &result), &result);
TEST_EQ(result.type, TAG_BOOL);
diff --git a/test/env_test.c b/test/env_test.c
index fbe2221..7ea8485 100644
--- a/test/env_test.c
+++ b/test/env_test.c
@@ -39,7 +39,7 @@ TEST_CASE(env_eval_call)
s_call call;
s_tag result;
s_tag expected;
- env_init(&env);
+ env_init(&env, 0, NULL);
test_context("env_eval_call(1 + 2) -> 3");
call_init(&call);
call.ident.module = sym_1("C3");
@@ -63,7 +63,7 @@ TEST_CASE(env_eval_equal_tag)
s_tag x;
s_tag y;
s_tag z;
- env_init(&env);
+ env_init(&env, 0, NULL);
env.frame = frame_init(&frame, env.frame);
test_context("x = 1");
TEST_ASSERT(env_eval_equal_tag(&env, tag_init_1(&x, "x"),
@@ -73,7 +73,7 @@ TEST_CASE(env_eval_equal_tag)
tag_clean(&z);
env.frame = frame_clean(&frame);
env_clean(&env);
- env_init(&env);
+ env_init(&env, 0, NULL);
env.frame = frame_init(&frame, env.frame);
test_context("x = (1, 2]");
TEST_ASSERT(env_eval_equal_tag(&env, tag_init_1(&x, "x"),
@@ -83,7 +83,7 @@ TEST_CASE(env_eval_equal_tag)
tag_clean(&z);
env.frame = frame_clean(&frame);
env_clean(&env);
- env_init(&env);
+ env_init(&env, 0, NULL);
env.frame = frame_init(&frame, env.frame);
test_context("[] = []");
TEST_ASSERT(env_eval_equal_tag(&env, tag_1(&x, "[]"),
@@ -92,7 +92,7 @@ TEST_CASE(env_eval_equal_tag)
tag_clean(&z);
env.frame = frame_clean(&frame);
env_clean(&env);
- env_init(&env);
+ env_init(&env, 0, NULL);
env.frame = frame_init(&frame, env.frame);
test_context("[a, b] = [1, 2]");
TEST_ASSERT(env_eval_equal_tag(&env, tag_1(&x, "[a, b]"),
@@ -103,7 +103,7 @@ TEST_CASE(env_eval_equal_tag)
tag_clean(&z);
env.frame = frame_clean(&frame);
env_clean(&env);
- env_init(&env);
+ env_init(&env, 0, NULL);
env.frame = frame_init(&frame, env.frame);
test_context("x = [1, 2]");
TEST_ASSERT(env_eval_equal_tag(&env, tag_1(&x, "[a | b]"),
@@ -126,7 +126,7 @@ TEST_CASE(env_eval_tag)
s_tag x;
s_tag y;
s_tag expected;
- env_init(&env);
+ env_init(&env, 0, NULL);
test_context("env_eval_tag(1 + 2) -> 3");
TEST_EQ(tag_init_1(&x, "1 + 2"), &x);
TEST_EQ(tag_init_1(&expected, "3"), &expected);
@@ -143,7 +143,7 @@ TEST_CASE_END(env_eval_tag)
TEST_CASE(env_init_clean)
{
s_env env;
- env_init(&env);
+ env_init(&env, 0, NULL);
env_clean(&env);
}
TEST_CASE_END(env_init_clean)
diff --git a/test/facts_test.c b/test/facts_test.c
index 74796c9..1e588b0 100644
--- a/test/facts_test.c
+++ b/test/facts_test.c
@@ -447,9 +447,9 @@ TEST_CASE(facts_open_file)
s_fact fact;
s_facts facts;
s_str path;
- if (file_copy("facts_test_open_file.1.in.facts",
- "facts_test_open_file.1.facts"))
- err(1, "%s:%i: file_copy", __FILE__, __LINE__);
+ if (file_copy_1("facts_test_open_file.1.in.facts",
+ "facts_test_open_file.1.facts"))
+ err(1, "%s:%i: file_copy_1", __FILE__, __LINE__);
facts_init(&facts);
str_init_1(&path, NULL, "facts_test_open_file.1.facts");
TEST_EQ(facts_open_file(&facts, &path), 760);
@@ -477,9 +477,9 @@ TEST_CASE(facts_open_file)
if (g_test_last_ok)
unlink("facts_test_open_file.1.facts");
facts_init(&facts);
- if (file_copy("facts_test_open_file.2.in.facts",
- "facts_test_open_file.2.facts"))
- err(1, "%s:%i: file_copy", __FILE__, __LINE__);
+ if (file_copy_1("facts_test_open_file.2.in.facts",
+ "facts_test_open_file.2.facts"))
+ err(1, "%s:%i: file_copy_1", __FILE__, __LINE__);
str_init_1(&path, NULL, "facts_test_open_file.2.facts");
TEST_EQ(facts_open_file(&facts, &path), 1523);
TEST_EQ(facts_count(&facts), 46);
@@ -504,9 +504,9 @@ TEST_CASE(facts_open_file)
if (g_test_last_ok)
unlink("facts_test_open_file.2.facts");
facts_init(&facts);
- if (file_copy("facts_test_open_file.3.in.facts",
- "facts_test_open_file.3.facts"))
- err(1, "%s:%i: file_copy", __FILE__, __LINE__);
+ if (file_copy_1("facts_test_open_file.3.in.facts",
+ "facts_test_open_file.3.facts"))
+ err(1, "%s:%i: file_copy_1", __FILE__, __LINE__);
str_init_1(&path, NULL, "facts_test_open_file.3.facts");
TEST_EQ(facts_open_file(&facts, &path), 1550);
TEST_EQ(facts_count(&facts), 0);
diff --git a/test/libc3_test.c b/test/libc3_test.c
index 308875c..077eedb 100644
--- a/test/libc3_test.c
+++ b/test/libc3_test.c
@@ -42,7 +42,7 @@ void types_test (void);
int main (int argc, char **argv)
{
test_init(argc, argv);
- c3_init(NULL);
+ c3_init(NULL, argc, argv);
if (test_target("types")) {
fprintf(stderr, "\ntypes\n");
types_test();