8 Commits

22 changed files with 881 additions and 208 deletions
+51
View File
@@ -546,6 +546,56 @@ static fx_status to_string(
return FX_SUCCESS;
}
static fx_status clone(const fx_value *src_v, fx_value *dest_v)
{
fx_hashtable *src_table = NULL, *dest_table = NULL;
fx_value_get_object(src_v, &src_table);
dest_table = fx_hashtable_create();
if (!dest_table) {
return FX_ERR_NO_MEMORY;
}
struct fx_hashtable_p *src_p
= fx_object_get_private(src_table, FX_TYPE_HASHTABLE);
struct fx_hashtable_p *dest_p
= fx_object_get_private(dest_table, FX_TYPE_HASHTABLE);
dest_p->t_count = src_p->t_count;
dest_p->t_max_index = src_p->t_max_index;
size_t capacity = primes[dest_p->t_max_index];
dest_p->t_items = calloc(capacity, sizeof *dest_p->t_items);
if (!dest_p->t_items) {
fx_hashtable_unref(dest_table);
return FX_ERR_NO_MEMORY;
}
for (size_t i = 0; i < capacity; i++) {
if (!src_p->t_items[i].i_item) {
continue;
}
fx_hashtable *new_item
= fx_object_create(FX_TYPE_HASHTABLE_ITEM);
if (!new_item) {
fx_hashtable_unref(dest_table);
return FX_ERR_NO_MEMORY;
}
struct fx_hashtable_item_p *src_item_p = fx_object_get_private(
src_p->t_items[i].i_item,
FX_TYPE_HASHTABLE_ITEM);
struct fx_hashtable_item_p *new_item_p = fx_object_get_private(
new_item,
FX_TYPE_HASHTABLE_ITEM);
new_item_p->i_key = fx_value_copy_return(src_item_p->i_key);
new_item_p->i_value = fx_value_copy_return(src_item_p->i_value);
dest_p->t_items[i].i_item = new_item;
}
*dest_v = FX_VALUE_OBJECT(dest_table);
return FX_SUCCESS;
}
static fx_status get_key(
const fx_value *item_value,
const fx_property *prop,
@@ -655,6 +705,7 @@ static const fx_value *iterator_get_value(const fx_iterator *obj)
FX_TYPE_CLASS_BEGIN(fx_hashtable)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
FX_INTERFACE_ENTRY(to_string) = to_string;
FX_INTERFACE_ENTRY(clone) = clone;
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_iterable, FX_TYPE_ITERABLE)
@@ -1,6 +1,7 @@
#ifndef FX_DIAGNOSTICS_PROCESS_H_
#define FX_DIAGNOSTICS_PROCESS_H_
#include <fx/collections/array.h>
#include <fx/collections/hashtable.h>
#include <fx/macros.h>
#include <fx/stream.h>
@@ -17,8 +18,7 @@ FX_TYPE_CLASS_DECLARATION_END(fx_process)
typedef struct fx_process_start_info {
bool proc_redirect_stdin, proc_redirect_stdout, proc_redirect_stderr;
const char *proc_file_name;
const char **proc_args;
size_t proc_args_count;
const fx_array *proc_args;
const fx_hashtable *proc_environment;
} fx_process_start_info;
+222 -20
View File
@@ -1,13 +1,22 @@
#define _POSIX_C_SOURCE 200809L
#include <fx/collections/array.h>
#include <fx/diagnostics/process.h>
#include <fx/global.h>
#include <fx/io/path.h>
#include <fx/io/pipe.h>
#include <fx/io/stream.h>
#include <fx/iterator.h>
#include <fx/macros.h>
#include <fx/string.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
static fx_process *self = NULL;
extern const char **environ;
FX_API fx_type_id fx_process_iterator_get_type();
FX_DECLARE_TYPE(fx_process_iterator);
@@ -21,6 +30,7 @@ struct fx_process_p {
bool proc_redirect_stdin, proc_redirect_stdout, proc_redirect_stderr;
fx_stream *proc_stdin, *proc_stdout, *proc_stderr;
pid_t proc_id;
fx_hashtable *proc_environment;
};
struct fx_process_iterator_p {
@@ -28,12 +38,109 @@ struct fx_process_iterator_p {
/*** PRIVATE FUNCTIONS ********************************************************/
static bool exec_name_is_path(const char *s)
{
fx_wchar c;
while (*s) {
c = fx_wchar_utf8_codepoint_decode(s);
if (c == FX_WCHAR_INVALID) {
break;
}
if (c == '/') {
return true;
}
s += fx_wchar_utf8_codepoint_stride(s);
}
return false;
}
const fx_string *get_path(void)
{
const char *path_env = NULL;
fx_process *self = fx_process_get_self();
if (!self) {
goto fallback;
}
const fx_hashtable *env = fx_process_get_environment(self);
if (!env) {
goto fallback;
}
const fx_value *path_v = fx_hashtable_get(env, &FX_CSTR("PATH"));
if (!path_v) {
goto fallback;
}
fx_string *result = NULL;
fx_value_get_object(path_v, &result);
return result;
fallback:
path_env = getenv("PATH");
if (!path_env) {
return NULL;
}
return fx_string_create_from_cstr(path_env);
}
static fx_status find_executable(fx_string *exec_path)
{
const char *exec_path_cstr = fx_string_get_cstr(exec_path);
const fx_string *path_env = get_path();
if (!path_env) {
return FX_ERR_NO_ENTRY;
}
const char *delim[] = {":"};
size_t nr_delim = sizeof delim / sizeof delim[0];
fx_path *path = NULL;
fx_iterator *it = fx_string_tokenise(
path_env,
delim,
nr_delim,
FX_STRING_TOK_F_NORMAL);
fx_status status = FX_ERR_NO_ENTRY;
fx_foreach(tok, it)
{
path = fx_path_join_list(2, tok, &FX_VALUE_OBJECT(exec_path));
if (fx_path_is_file(path)) {
fx_string_clear(exec_path);
fx_string_append_cstr(
exec_path,
fx_path_get_cstr(path));
status = FX_SUCCESS;
break;
}
}
fx_iterator_unref(it);
fx_path_unref(path);
return status;
}
static fx_status process_start(struct fx_process_p *proc)
{
fx_iostream *in_r = NULL, *in_w = NULL;
fx_iostream *out_r = NULL, *out_w = NULL;
fx_iostream *err_r = NULL, *err_w = NULL;
fx_status status = FX_SUCCESS;
bool name_is_path
= exec_name_is_path(fx_string_get_cstr(proc->proc_exec_path));
if (!name_is_path) {
status = find_executable(proc->proc_exec_path);
}
if (!FX_OK(status)) {
return status;
}
if (proc->proc_redirect_stdin) {
status = fx_pipe_create(&in_r, &in_w);
@@ -76,7 +183,6 @@ static fx_status process_start(struct fx_process_p *proc)
if (proc->proc_redirect_stdin) {
fx_iostream_unref(in_w);
fd = fx_iostream_steal_os_handle(in_r);
fprintf(stderr, "dup2(%d, %d)\n", fd, 0);
int err = dup2(fd, 0);
close(fd);
}
@@ -96,12 +202,23 @@ static fx_status process_start(struct fx_process_p *proc)
}
const char **argv = NULL;
const char **envp = NULL;
const char *default_argv[] = {
fx_string_get_cstr(proc->proc_exec_path),
NULL,
};
size_t argc = 0;
size_t envc = 0;
if (proc->proc_args) {
argc = fx_array_get_size(proc->proc_args);
}
if (proc->proc_environment) {
envc = fx_hashtable_get_count(proc->proc_environment);
}
if (argc) {
argv = calloc(argc + 1, sizeof(char *));
@@ -110,9 +227,38 @@ static fx_status process_start(struct fx_process_p *proc)
= fx_array_get_ref(proc->proc_args, i);
fx_value_get_cstr(arg_value, &argv[i]);
}
} else {
argv = default_argv;
}
execv(fx_string_get_cstr(proc->proc_exec_path), (char *const *)argv);
if (envc) {
envp = calloc(envc + 1, sizeof(char *));
size_t i = 0;
fx_stringstream *tmp = fx_stringstream_create();
const fx_iterator *it
= fx_iterator_begin(proc->proc_environment);
fx_foreach(v, it)
{
fx_hashtable_item *item = NULL;
fx_value_get_object(v, &item);
const fx_value *name_v
= fx_hashtable_item_get_key(item);
const fx_value *value_v
= fx_hashtable_item_get_value(item);
fx_value_to_string(name_v, tmp, NULL);
fx_stream_write_char(tmp, '=');
fx_value_to_string(value_v, tmp, NULL);
envp[i++] = fx_stringstream_steal(tmp);
}
fx_iterator_unref(it);
fx_string_unref(tmp);
}
execve(fx_string_get_cstr(proc->proc_exec_path),
(char *const *)argv,
(char *const *)envp);
exit(127);
cleanup:
@@ -159,6 +305,12 @@ static fx_status process_kill(struct fx_process_p *proc)
return FX_SUCCESS;
}
static const fx_hashtable *process_get_environment(
const struct fx_process_p *proc)
{
return proc->proc_environment;
}
static fx_stream *process_get_stdin(struct fx_process_p *proc)
{
return proc->proc_stdin;
@@ -210,25 +362,10 @@ fx_process *fx_process_create(const fx_process_start_info *info)
return NULL;
}
if (info->proc_args_count > 0) {
proc->proc_args = fx_array_create();
if (!proc->proc_args) {
fx_process_unref(out);
return NULL;
}
}
for (size_t i = 0; i < info->proc_args_count; i++) {
fx_string *arg = fx_string_create_from_cstr(info->proc_args[i]);
if (!arg) {
fx_process_unref(out);
return NULL;
}
fx_array_push_back(proc->proc_args, FX_VALUE_OBJECT(arg));
fx_string_unref(arg);
}
proc->proc_args = fx_array_ref((fx_array *)info->proc_args);
proc->proc_environment
= fx_hashtable_ref((fx_hashtable *)info->proc_environment);
proc->proc_redirect_stdin = info->proc_redirect_stdin;
proc->proc_redirect_stdout = info->proc_redirect_stdout;
proc->proc_redirect_stderr = info->proc_redirect_stderr;
@@ -236,6 +373,56 @@ fx_process *fx_process_create(const fx_process_start_info *info)
return out;
}
fx_process *fx_process_get_self(void)
{
if (self) {
return self;
}
self = fx_object_create(FX_DIAGNOSTICS_TYPE_PROCESS);
if (!self) {
return NULL;
}
struct fx_process_p *proc
= fx_object_get_private(self, FX_DIAGNOSTICS_TYPE_PROCESS);
proc->proc_id = getpid();
fx_hashtable *env = fx_hashtable_create();
for (size_t i = 0; environ[i]; i++) {
char *envstr = fx_strdup(environ[i]);
const char *name = envstr;
char *sep = strchr(name, '=');
const char *value = NULL;
if (sep) {
*sep = '\0';
value = sep + 1;
}
fx_string *name_str = fx_string_create_from_cstr(name);
fx_string *value_str = fx_string_create();
if (value) {
fx_string_append_cstr(value_str, value);
}
fx_hashtable_put(
env,
&FX_VALUE_OBJECT(name_str),
&FX_VALUE_OBJECT(value_str));
fx_string_unref(name_str);
fx_string_unref(value_str);
free(envstr);
}
proc->proc_environment = env;
fx_register_global(self);
return self;
}
fx_status fx_process_start(fx_process *proc)
{
FX_CLASS_DISPATCH_STATIC_0(
@@ -261,6 +448,14 @@ fx_status fx_process_kill(fx_process *proc)
proc);
}
const fx_hashtable *fx_process_get_environment(const fx_process *proc)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_DIAGNOSTICS_TYPE_PROCESS,
process_get_environment,
proc);
}
fx_stream *fx_process_get_stdin(fx_process *proc)
{
FX_CLASS_DISPATCH_STATIC_0(
@@ -317,6 +512,13 @@ static void process_init(fx_object *obj, void *priv)
static void process_fini(fx_object *obj, void *priv)
{
struct fx_process_p *proc = priv;
fx_array_unref(proc->proc_args);
fx_iostream_unref(proc->proc_stdin);
fx_iostream_unref(proc->proc_stdout);
fx_iostream_unref(proc->proc_stderr);
fx_string_unref(proc->proc_exec_path);
fx_hashtable_unref(proc->proc_environment);
}
/*** ITERATOR DEFINITION ******************************************************/
+6 -4
View File
@@ -9,17 +9,19 @@ int main(int argc, const char **argv)
const char *exec = argv[1];
const char *msg = argv[2];
const char *args[] = {
"hello",
"world",
const fx_value arg_values[] = {
FX_CSTR("hello"),
FX_CSTR("world"),
};
fx_array *args = fx_array_create_with_values(
arg_values,
sizeof arg_values / sizeof arg_values[0]);
fx_process *self = fx_process_get_self();
const fx_hashtable *env = fx_process_get_environment(self);
fx_process_start_info info = {
.proc_args = args,
.proc_args_count = sizeof args / sizeof args[0],
.proc_redirect_stdout = true,
.proc_redirect_stdin = true,
.proc_file_name = exec,
+7 -12
View File
@@ -50,7 +50,7 @@ FX_API fx_type_id fx_directory_iterator_get_type(void);
FX_API fx_result fx_directory_open(
fx_directory *root,
const fx_path *path,
fx_value path,
fx_directory_open_flags flags,
fx_directory **out);
FX_API fx_result fx_directory_open_temp(fx_directory **out);
@@ -60,22 +60,17 @@ FX_API const char *fx_directory_get_path_cstr(const fx_directory *dir);
FX_API const char *fx_directory_get_rel_path_cstr(const fx_directory *dir);
FX_API fx_result fx_directory_delete(fx_directory *dir);
FX_API bool fx_directory_path_exists(
const fx_directory *root,
const fx_path *path);
FX_API bool fx_directory_path_is_file(
const fx_directory *root,
const fx_path *path);
FX_API bool fx_directory_path_exists(const fx_directory *root, fx_value path);
FX_API bool fx_directory_path_is_file(const fx_directory *root, fx_value path);
FX_API bool fx_directory_path_is_directory(
const fx_directory *root,
const fx_path *path);
fx_value path);
FX_API fx_result fx_directory_path_stat(
const fx_directory *root,
const fx_path *path,
fx_value path,
struct fx_file_info *out);
FX_API fx_result fx_directory_path_unlink(
const fx_directory *root,
const fx_path *path);
FX_API fx_result
fx_directory_path_unlink(const fx_directory *root, fx_value path);
FX_API fx_iterator *fx_directory_begin(
fx_directory *dir,
+2 -1
View File
@@ -5,6 +5,7 @@
#include <fx/macros.h>
#include <fx/misc.h>
#include <fx/stream.h>
#include <fx/value.h>
FX_DECLS_BEGIN;
@@ -55,7 +56,7 @@ FX_API fx_type_id fx_file_get_type(void);
FX_API fx_result fx_file_open(
FX_TYPE_FWDREF(fx_directory) * root,
const FX_TYPE_FWDREF(fx_path) * path,
fx_value path,
fx_file_mode mode,
fx_file **out);
FX_API fx_result fx_file_open_temp(fx_file_mode mode, fx_file **out);
+71 -79
View File
@@ -1,3 +1,5 @@
#define _POSIX_C_SOURCE 200809L
#include "misc.h"
#include "posix.h"
@@ -65,9 +67,8 @@ static fx_result directory_delete(
{
enum fx_status status = FX_SUCCESS;
fx_iterator *it = fx_directory_begin(
dir,
FX_DIRECTORY_ITERATE_PARENT_LAST);
fx_iterator *it
= fx_directory_begin(dir, FX_DIRECTORY_ITERATE_PARENT_LAST);
while (FX_OK(fx_iterator_get_status(it))) {
fx_iterator_erase(it);
}
@@ -87,14 +88,12 @@ static fx_result directory_delete(
static bool directory_path_exists(
const struct fx_directory_p *root,
const fx_path *path)
fx_value path)
{
const fx_path *parts[] = {
root ? root->d_path_abs : NULL,
path,
};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path = fx_path_join_list(
2,
&FX_VALUE_OBJECT(root ? root->d_path_abs : NULL),
&path);
if (!abs_path) {
return false;
}
@@ -107,14 +106,14 @@ static bool directory_path_exists(
static bool directory_path_is_file(
const struct fx_directory_p *root,
const fx_path *path)
fx_value path)
{
const fx_path *parts[] = {
root ? root->d_path_abs : NULL,
path,
};
const fx_value *parts[] = {};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path = fx_path_join_list(
2,
&FX_VALUE_OBJECT(root ? root->d_path_abs : NULL),
&path);
if (!abs_path) {
return false;
}
@@ -127,14 +126,14 @@ static bool directory_path_is_file(
static bool directory_path_is_directory(
const struct fx_directory_p *root,
const fx_path *path)
fx_value path)
{
const fx_path *parts[] = {
root ? root->d_path_abs : NULL,
path,
};
const fx_value *parts[] = {};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path = fx_path_join_list(
2,
&FX_VALUE_OBJECT(root ? root->d_path_abs : NULL),
&path);
if (!abs_path) {
return false;
}
@@ -147,15 +146,15 @@ static bool directory_path_is_directory(
static fx_result directory_path_stat(
const struct fx_directory_p *root,
const fx_path *path,
fx_value path,
struct fx_file_info *out)
{
const fx_path *parts[] = {
root ? root->d_path_abs : NULL,
path,
};
const fx_value *parts[] = {};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path = fx_path_join_list(
2,
&FX_VALUE_OBJECT(root ? root->d_path_abs : NULL),
&path);
if (!abs_path) {
return FX_RESULT_ERR(NO_MEMORY);
}
@@ -168,14 +167,14 @@ static fx_result directory_path_stat(
static fx_result directory_path_unlink(
const struct fx_directory_p *root,
const fx_path *path)
fx_value path)
{
const fx_path *parts[] = {
root ? root->d_path_abs : NULL,
path,
};
const fx_value *parts[] = {};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path = fx_path_join_list(
2,
&FX_VALUE_OBJECT(root ? root->d_path_abs : NULL),
&path);
if (!abs_path) {
return FX_RESULT_ERR(NO_MEMORY);
}
@@ -255,7 +254,7 @@ static fx_result create_directory_hierarchy(
static fx_result directory_open(
struct fx_directory_p *root,
const fx_path *path,
fx_value path,
fx_directory_open_flags flags,
fx_directory **out)
{
@@ -263,7 +262,10 @@ static fx_result directory_open(
int root_fd = root ? root->d_fd : AT_FDCWD;
const char *path_cstr = fx_path_get_cstr(path);
fx_stringstream *path_str = fx_stringstream_create();
fx_value_to_string(&path, path_str, NULL);
const char *path_cstr = fx_stringstream_get_cstr(path_str);
if (root) {
while (*path_cstr == '/') {
path_cstr++;
@@ -293,21 +295,22 @@ static fx_result directory_open(
fx_directory *dir = fx_object_create(FX_TYPE_DIRECTORY);
fx_path *cwd = NULL;
struct fx_directory_p *p = fx_object_get_private(
dir,
FX_TYPE_DIRECTORY);
struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
if (!root) {
cwd = fx_path_create_cwd();
cwd = fx_path_get_system(FX_PATH_CWD);
}
const fx_path *parts[] = {
root ? root->d_path_abs : cwd,
path,
const fx_value *parts[] = {
&FX_VALUE_OBJECT(root ? root->d_path_abs : cwd),
&FX_CSTR(path_cstr),
};
fx_path *new_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *new_path
= fx_path_join_array(parts, sizeof parts / sizeof parts[0]);
if (!new_path) {
fx_stringstream_unref(path_str);
return FX_RESULT_ERR(NO_MEMORY);
}
@@ -316,7 +319,7 @@ static fx_result directory_open(
}
p->d_path_abs = new_path;
p->d_path_rel = fx_path_duplicate(path);
p->d_path_rel = fx_path_create_from_cstr(path_cstr);
p->d_fd = fd;
if (flags & FX_DIRECTORY_OPEN_DELETE_ON_CLOSE) {
@@ -324,6 +327,7 @@ static fx_result directory_open(
}
*out = dir;
fx_stringstream_unref(path_str);
return FX_RESULT_SUCCESS;
}
@@ -332,7 +336,7 @@ static fx_result directory_open(
fx_result fx_directory_open(
fx_directory *root,
const fx_path *path,
fx_value path,
fx_directory_open_flags flags,
fx_directory **out)
{
@@ -353,20 +357,17 @@ fx_result fx_directory_open_temp(fx_directory **out)
while (1) {
z__fx_io_generate_tmp_filename(name, sizeof name);
snprintf(path, sizeof path, "/tmp/%s", name);
fx_path *rpath = fx_path_create_from_cstr(path);
fx_directory *dir = NULL;
fx_result status = fx_directory_open(
FX_DIRECTORY_ROOT,
rpath,
FX_CSTR(path),
FX_DIRECTORY_OPEN_CREATE,
&dir);
struct fx_directory_p *p = fx_object_get_private(
dir,
FX_TYPE_DIRECTORY);
struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
if (fx_error_get_status_code(status) == FX_ERR_NAME_EXISTS) {
fx_path_unref(rpath);
continue;
}
@@ -374,8 +375,8 @@ fx_result fx_directory_open_temp(fx_directory **out)
p->d_flags |= DIRECTORY_DELETE_ON_CLOSE;
}
fx_path_unlink(rpath);
fx_path_unref(rpath);
*out = dir;
return status;
}
}
@@ -410,16 +411,15 @@ const char *fx_directory_get_rel_path_cstr(const fx_directory *dir)
fx_result fx_directory_delete(fx_directory *dir)
{
struct fx_directory_p *p = fx_object_get_private(
dir,
FX_TYPE_DIRECTORY);
struct fx_directory_p *p
= fx_object_get_private(dir, FX_TYPE_DIRECTORY);
p->d_flags |= DIRECTORY_DELETE_ON_CLOSE;
/* TODO allow object release functions to return a fx_result value */
fx_directory_unref(dir);
return FX_RESULT_SUCCESS;
}
bool fx_directory_path_exists(const fx_directory *root, const fx_path *path)
bool fx_directory_path_exists(const fx_directory *root, fx_value path)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
@@ -428,7 +428,7 @@ bool fx_directory_path_exists(const fx_directory *root, const fx_path *path)
path);
}
bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path)
bool fx_directory_path_is_file(const fx_directory *root, fx_value path)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
@@ -437,9 +437,7 @@ bool fx_directory_path_is_file(const fx_directory *root, const fx_path *path)
path);
}
bool fx_directory_path_is_directory(
const fx_directory *root,
const fx_path *path)
bool fx_directory_path_is_directory(const fx_directory *root, fx_value path)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
@@ -450,7 +448,7 @@ bool fx_directory_path_is_directory(
fx_result fx_directory_path_stat(
const fx_directory *root,
const fx_path *path,
fx_value path,
struct fx_file_info *out)
{
FX_CLASS_DISPATCH_STATIC(
@@ -461,9 +459,7 @@ fx_result fx_directory_path_stat(
out);
}
fx_result fx_directory_path_unlink(
const fx_directory *root,
const fx_path *path)
fx_result fx_directory_path_unlink(const fx_directory *root, fx_value path)
{
FX_CLASS_DISPATCH_STATIC(
FX_TYPE_DIRECTORY,
@@ -560,9 +556,8 @@ fx_iterator *fx_directory_begin(
enum fx_directory_iterator_flags flags)
{
fx_iterator *it_obj = fx_object_create(FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it = fx_object_get_private(
it_obj,
FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it
= fx_object_get_private(it_obj, FX_TYPE_DIRECTORY_ITERATOR);
it->flags = flags;
it->root = directory;
@@ -629,9 +624,8 @@ static const fx_iterator *iterator_begin(const fx_object *obj)
static enum fx_status iterator_move_next(const fx_iterator *obj)
{
struct fx_directory_iterator_p *it = fx_object_get_private(
obj,
FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR);
if (!it || !it->fts) {
return FX_ERR_NO_DATA;
}
@@ -679,12 +673,11 @@ static enum fx_status iterator_move_next(const fx_iterator *obj)
static enum fx_status iterator_erase(fx_iterator *obj)
{
struct fx_directory_iterator_p *it = fx_object_get_private(
obj,
FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR);
fx_result result = fx_directory_path_unlink(
it->root,
it->entry.filepath);
FX_VALUE_OBJECT(it->entry.filepath));
if (fx_result_is_error(result)) {
enum fx_status status = fx_error_get_status_code(result);
fx_error_discard(result);
@@ -696,9 +689,8 @@ static enum fx_status iterator_erase(fx_iterator *obj)
static const fx_value *iterator_get_value(const fx_iterator *obj)
{
struct fx_directory_iterator_p *it = fx_object_get_private(
obj,
FX_TYPE_DIRECTORY_ITERATOR);
struct fx_directory_iterator_p *it
= fx_object_get_private(obj, FX_TYPE_DIRECTORY_ITERATOR);
return &it->entry_value;
}
+25 -20
View File
@@ -1,3 +1,5 @@
#define _POSIX_C_SOURCE 200809L
#include "misc.h"
#include "posix.h"
@@ -84,13 +86,13 @@ static fx_result file_open_shadow(
= fx_path_create_from_cstr(fx_string_get_cstr(filename));
fx_string_unref(filename);
const fx_path *parts[] = {
dir,
shadow_filename,
const fx_value *parts[] = {
&FX_VALUE_OBJECT(dir),
&FX_VALUE_OBJECT(shadow_filename),
};
fx_path *shadow_filepath
= fx_path_join(parts, sizeof parts / sizeof parts[0]);
= fx_path_join_array(parts, sizeof parts / sizeof parts[0]);
fx_path_unref(dir);
fx_path_unref(shadow_filename);
@@ -101,7 +103,7 @@ static fx_result file_open_shadow(
fx_file *shadow_file;
fx_result status = fx_file_open(
FX_DIRECTORY_ROOT,
shadow_filepath,
FX_VALUE_OBJECT(shadow_filepath),
mode,
&shadow_file);
fx_path_unref(shadow_filepath);
@@ -227,12 +229,14 @@ static enum fx_status file_swap_shadow(
z__fx_io_generate_tmp_filename(tmp_name, sizeof tmp_name);
fx_path *tmp_name_p = fx_path_create_from_cstr(tmp_name);
const fx_path *parts[] = {
dir_path,
tmp_name_p,
const fx_value *parts[] = {
&FX_VALUE_OBJECT(dir_path),
&FX_VALUE_OBJECT(tmp_name_p),
};
tmp_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
tmp_path = fx_path_join_array(
parts,
sizeof parts / sizeof parts[0]);
fx_path_unref(tmp_name_p);
@@ -248,11 +252,15 @@ static enum fx_status file_swap_shadow(
int err;
err = rename(fx_path_get_cstr(main_file->path), fx_path_get_cstr(tmp_path));
err = rename(
fx_path_get_cstr(main_file->path),
fx_path_get_cstr(tmp_path));
err = rename(
fx_path_get_cstr(shadow_file->path),
fx_path_get_cstr(main_file->path));
err = rename(fx_path_get_cstr(tmp_path), fx_path_get_cstr(shadow_file->path));
err = rename(
fx_path_get_cstr(tmp_path),
fx_path_get_cstr(shadow_file->path));
fx_path_unref(tmp_path);
@@ -406,11 +414,10 @@ static enum fx_status stream_tell(const fx_stream *stream, size_t *pos)
fx_result fx_file_open(
fx_directory *root,
const fx_path *path,
fx_value path,
enum fx_file_mode mode,
fx_file **out)
{
const fx_path *file_path = path;
unsigned int flags = fx_mode_to_unix_mode(mode);
if (flags == (unsigned int)-1) {
@@ -422,16 +429,14 @@ fx_result fx_file_open(
if (root) {
root_path = fx_directory_get_path(root);
} else {
root_path = fx_path_create_cwd();
root_path = fx_path_get_system(FX_PATH_CWD);
free_root_path = true;
}
const fx_path *parts[] = {
root_path,
file_path,
};
const fx_value *parts[] = {};
fx_path *abs_path = fx_path_join(parts, sizeof parts / sizeof parts[0]);
fx_path *abs_path
= fx_path_join_list(2, &FX_VALUE_OBJECT(root_path), &path);
if (free_root_path) {
fx_path_unref((fx_path *)root_path);
@@ -492,7 +497,7 @@ fx_result fx_file_open_temp(enum fx_file_mode mode, fx_file **out)
fx_result status = fx_file_open(
FX_DIRECTORY_ROOT,
rpath,
FX_VALUE_OBJECT(rpath),
mode | FX_FILE_CREATE_ONLY,
out);
+60 -20
View File
@@ -6,7 +6,6 @@
#include <fx/io/file.h>
#include <fx/io/path.h>
#include <fx/string.h>
#include <fx/value.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -41,7 +40,7 @@ static bool path_is_absolute(const struct fx_path_p *path)
return s[0] == '/';
}
static const char *path_get_cstr(const struct fx_path_p *path)
static const char *path_ptr(const struct fx_path_p *path)
{
return fx_string_get_cstr(path->p_pathstr);
}
@@ -51,7 +50,7 @@ static enum fx_status path_stat(
struct fx_file_info *out)
{
struct stat st;
int err = stat(path_get_cstr(path), &st);
int err = stat(path_ptr(path), &st);
if (err != 0) {
return fx_status_from_errno(errno, FX_ERR_IO_FAILURE);
@@ -92,22 +91,22 @@ static bool path_is_directory(const struct fx_path_p *path)
return (info.attrib & FX_FILE_ATTRIB_DIRECTORY) != 0;
}
static void append_path(struct fx_path_p *dest, const struct fx_path_p *src)
static void append_path(struct fx_path_p *dest, const fx_string *src)
{
if (path_is_absolute(src)) {
const char *src_cstr = fx_string_get_cstr(src);
if (src_cstr[0] == '/') {
fx_string_clear(dest->p_pathstr);
fx_string_append_s(dest->p_pathstr, src->p_pathstr);
fx_string_append_s(dest->p_pathstr, src);
return;
}
if (fx_string_get_size(dest->p_pathstr, FX_STRLEN_NORMAL) > 0
&& fx_string_get_last_char(dest->p_pathstr) != '/'
&& fx_string_get_first_char(src->p_pathstr) != '/') {
char s[] = {'/', 0};
fx_string_append_cstr(dest->p_pathstr, s);
&& fx_string_get_first_char(src) != '/') {
fx_string_append_c(dest->p_pathstr, '/');
}
fx_string_append_s(dest->p_pathstr, src->p_pathstr);
fx_string_append_s(dest->p_pathstr, src);
}
static enum fx_status path_unlink(const struct fx_path_p *path)
@@ -294,7 +293,7 @@ fx_path *fx_path_duplicate(const fx_path *path)
return new_path;
}
fx_path *fx_path_join(const fx_path *paths[], size_t nr_paths)
fx_path *fx_path_join_array(const fx_value *values[], size_t nr_values)
{
fx_path *result = fx_path_create();
if (!result) {
@@ -304,14 +303,53 @@ fx_path *fx_path_join(const fx_path *paths[], size_t nr_paths)
struct fx_path_p *result_p
= fx_object_get_private(result, FX_TYPE_PATH);
for (size_t i = 0; i < nr_paths; i++) {
if (paths[i]) {
struct fx_path_p *path_p
= fx_object_get_private(paths[i], FX_TYPE_PATH);
append_path(result_p, path_p);
fx_stringstream *tmp = fx_stringstream_create();
fx_string *value_s = fx_string_create();
for (size_t i = 0; i < nr_values; i++) {
if (!values[i]) {
continue;
}
fx_stringstream_reset(tmp);
fx_value_to_string(values[i], tmp, NULL);
fx_string_clear(value_s);
fx_string_append_cstr(value_s, fx_stringstream_get_cstr(tmp));
append_path(result_p, value_s);
}
fx_string_unref(value_s);
fx_stringstream_unref(tmp);
return result;
}
fx_path *fx_path_join_list(size_t count, ...)
{
fx_path *result = fx_path_create();
if (!result) {
return NULL;
}
struct fx_path_p *result_p
= fx_object_get_private(result, FX_TYPE_PATH);
va_list arg;
va_start(arg, count);
fx_stringstream *tmp = fx_stringstream_create();
fx_string *value_s = fx_string_create();
for (size_t i = 0; i < count; i++) {
const fx_value *value = va_arg(arg, const fx_value *);
fx_stringstream_reset(tmp);
fx_value_to_string(value, tmp, NULL);
fx_string_clear(value_s);
fx_string_append_cstr(value_s, fx_stringstream_get_cstr(tmp));
append_path(result_p, value_s);
}
fx_string_unref(value_s);
fx_stringstream_unref(tmp);
return result;
}
@@ -382,7 +420,7 @@ enum fx_status fx_path_get_filename(const fx_path *path, fx_string *out_name)
const char *fx_path_get_cstr(const fx_path *path)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_get_cstr, path);
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_PATH, path_ptr, path);
}
size_t fx_path_length(const fx_path *path)
@@ -402,7 +440,7 @@ static void path_init(fx_object *obj, void *priv)
}
}
static void path_fini(fx_object *obj, void *priv)
void path_fini(fx_object *obj, void *priv)
{
struct fx_path_p *path = priv;
@@ -417,8 +455,10 @@ static fx_status path_to_string(
struct fx_path_p *path
= fx_object_get_private(obj->v_object, FX_TYPE_PATH);
fx_stream_write_cstr(out, fx_string_get_cstr(path->p_pathstr), NULL);
return FX_SUCCESS;
return fx_stream_write_cstr(
out,
fx_string_get_cstr(path->p_pathstr),
NULL);
}
/*** CLASS DEFINITION *********************************************************/
+4 -1
View File
@@ -11,7 +11,10 @@ int main(int argc, const char **argv)
fx_directory *dir;
fx_result result = fx_directory_open(
NULL, FX_RV_PATH(path), FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE, &dir);
NULL,
FX_CSTR(path),
FX_DIRECTORY_OPEN_CREATE_INTERMEDIATE,
&dir);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
+1 -1
View File
@@ -9,7 +9,7 @@ int main(int argc, const char **argv)
const char *path = argv[1];
fx_directory *dir;
fx_result result = fx_directory_open(NULL, FX_RV_PATH(path), 0, &dir);
fx_result result = fx_directory_open(NULL, FX_CSTR(path), 0, &dir);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
+1 -3
View File
@@ -6,10 +6,9 @@
int main(int argc, const char **argv)
{
fx_file *dest;
fx_path *path = fx_path_create_from_cstr("data.txt");
fx_result result = fx_file_open(
NULL,
path,
FX_CSTR("data.txt"),
FX_FILE_WRITE_ONLY | FX_FILE_CREATE,
&dest);
if (fx_result_is_error(result)) {
@@ -23,7 +22,6 @@ int main(int argc, const char **argv)
printf("done. read %zu bytes total.\n", nr_read);
fx_path_unref(path);
fx_file_unref(dest);
return 0;
}
+7 -5
View File
@@ -12,17 +12,19 @@ int main(int argc, const char **argv)
}
fx_directory *dir = NULL;
fx_path *path = fx_path_create_from_cstr(argv[1]);
fx_result result = fx_directory_open(FX_DIRECTORY_ROOT, path, 0, &dir);
fx_result result = fx_directory_open(
FX_DIRECTORY_ROOT,
FX_CSTR(argv[1]),
0,
&dir);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
}
fx_iterator *it = fx_directory_begin(
dir,
FX_DIRECTORY_ITERATE_PARENT_FIRST);
fx_iterator *it
= fx_directory_begin(dir, FX_DIRECTORY_ITERATE_PARENT_FIRST);
fx_foreach(val, it)
{
fx_directory_entry *entry = NULL;
+70 -27
View File
@@ -1,6 +1,8 @@
#define _POSIX_C_SOURCE 200809L
#include "../../tty.h"
#include <fx/encoding.h>
#include <ctype.h>
#include <fx/term/tty.h>
#include <stdio.h>
#include <stdlib.h>
@@ -102,11 +104,11 @@ static void init_tty(struct fx_tty *tty, FILE *in, FILE *out)
tcgetattr(fd, &tty->t_ios_default);
memcpy(&tty->t_ios_raw, &tty->t_ios_default, sizeof tty->t_ios_raw);
setvbuf(out, NULL, _IOLBF, 4096);
tty->t_ios_raw.c_iflag &= ~(BRKINT | INPCK | ISTRIP | ICRNL | IXON);
tty->t_ios_raw.c_iflag &= ~(ICRNL | IXON);
tty->t_ios_raw.c_oflag &= ~(OPOST);
tty->t_ios_raw.c_cflag |= (CS8);
tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
tty->t_ios_raw.c_lflag &= ~(ECHO | ICANON | IEXTEN);
tty->t_flags |= FX_TTY_INIT;
}
@@ -207,6 +209,11 @@ void fx_tty_reset_vmode(struct fx_tty *tty)
tty->t_vmode.v_attrib = FX_TTY_ATTRIB_NORMAL;
}
void fx_tty_flush(struct fx_tty *tty)
{
fflush(tty->t_out);
}
static int compare_colour(
const struct fx_tty_colour *a,
const struct fx_tty_colour *b)
@@ -408,24 +415,6 @@ void fx_tty_set_vmode(struct fx_tty *tty, const struct fx_tty_vmode *vmode)
memcpy(&tty->t_vmode, vmode, sizeof *vmode);
}
static fx_keycode read_utf8(int fd, char header, int len)
{
char s[4] = {header, 0, 0, 0};
for (int i = 1; i < len; i++) {
char c;
int v = read(fd, &c, 1);
if (v != 1) {
return FX_KEY_EOF;
}
s[i] = c;
}
return fx_wchar_utf8_codepoint_decode(s);
}
fx_keycode fx_tty_read_key(struct fx_tty *tty)
{
char c;
@@ -450,11 +439,6 @@ fx_keycode fx_tty_read_key(struct fx_tty *tty)
return FX_TTY_CTRL_KEY(c + 'a' - 1);
}
int utf8_len = fx_wchar_utf8_header_decode(c);
if (utf8_len > 1) {
return read_utf8(fd, c, utf8_len);
}
if (c != 0x1b) {
return c;
}
@@ -590,3 +574,62 @@ enum fx_status fx_tty_get_dimensions(
return 0;
}
enum fx_status fx_tty_get_cursor_position(
struct fx_tty *tty,
unsigned int *w,
unsigned int *h)
{
if (!(tty->t_flags & FX_TTY_INTERACTIVE)) {
return -1;
}
int in_fd = fileno(tty->t_in);
int out_fd = fileno(tty->t_out);
write(out_fd, "\x1b[6n", 4);
char c;
read(in_fd, &c, 1);
read(in_fd, &c, 1);
char s[16] = {0};
for (int i = 0; i < sizeof s - 1; i++) {
read(in_fd, &c, 1);
if (!isdigit(c)) {
break;
}
s[i] = c;
s[i + 1] = 0;
}
if (w) {
if (s[0]) {
*w = atoi(s);
} else {
*w = 0;
}
}
s[0] = 0;
for (int i = 0; i < sizeof s - 1; i++) {
read(in_fd, &c, 1);
if (!isdigit(c)) {
break;
}
s[i] = c;
s[i + 1] = 0;
}
if (h) {
if (s[0]) {
*h = atoi(s);
} else {
*h = 0;
}
}
return 0;
}
+283
View File
@@ -0,0 +1,283 @@
#include <fx/bytestream.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#define DEFAULT_CAPACITY 128
/*** PRIVATE DATA *************************************************************/
struct fx_bytestream_p {
unsigned char *s_buf;
size_t s_ptr;
size_t s_len;
size_t s_max;
unsigned char s_alloc;
};
/*** PRIVATE FUNCTIONS ********************************************************/
static enum fx_status __gets(
struct fx_bytestream_p *s,
unsigned char *buf,
size_t len,
size_t *nr_read)
{
size_t available = s->s_len - s->s_ptr;
size_t to_copy = len;
if (available < to_copy) {
to_copy = available;
}
memcpy(buf, s->s_buf + s->s_ptr, to_copy);
s->s_ptr += to_copy;
if (s->s_ptr == s->s_len) {
s->s_ptr = s->s_len = 0;
}
if (nr_read) {
*nr_read = to_copy;
}
return FX_SUCCESS;
}
static enum fx_status __puts(
struct fx_bytestream_p *s,
const unsigned char *buf,
size_t len,
size_t *nr_written)
{
size_t available = s->s_max - s->s_len;
size_t to_copy = len;
if (to_copy > available && s->s_alloc == 1) {
unsigned char *new_buf
= realloc(s->s_buf, s->s_len + to_copy + 1);
if (!new_buf) {
return FX_ERR_NO_MEMORY;
}
s->s_buf = new_buf;
s->s_max = s->s_len + to_copy;
available = s->s_max - s->s_len;
}
if (available < to_copy) {
to_copy = available;
}
memcpy(s->s_buf + s->s_len, buf, to_copy);
s->s_buf[s->s_len + to_copy] = 0;
/* increment the length by the full byte length, even if only a
* portion was copied */
s->s_len += len;
if (nr_written) {
*nr_written = to_copy;
}
return FX_SUCCESS;
}
static enum fx_status bytestream_reset(struct fx_bytestream_p *s)
{
s->s_len = 0;
if (s->s_buf) {
*s->s_buf = 0;
}
return FX_SUCCESS;
}
static size_t bytestream_get_length(const struct fx_bytestream_p *strv)
{
return strv->s_len;
}
static const unsigned char *bytestream_get_ptr(const struct fx_bytestream_p *s)
{
return s->s_buf;
}
static unsigned char *bytestream_steal(struct fx_bytestream_p *s)
{
unsigned char *out = s->s_buf;
memset(s, 0x0, sizeof *s);
s->s_alloc = 1;
return out;
}
/*** PUBLIC FUNCTIONS *********************************************************/
fx_bytestream *fx_bytestream_create_view(unsigned char *buf, size_t max)
{
fx_bytestream *s = fx_object_create(FX_TYPE_BYTESTREAM);
if (!s) {
return NULL;
}
fx_stream_cfg *cfg = fx_object_get_protected(s, FX_TYPE_STREAM);
struct fx_bytestream_p *p
= fx_object_get_private(s, FX_TYPE_BYTESTREAM);
cfg->s_mode = FX_STREAM_READ | FX_STREAM_WRITE | FX_STREAM_BINARY
| Z__FX_STREAM_STATIC;
p->s_buf = buf;
p->s_max = max;
p->s_len = max;
p->s_alloc = 0;
return s;
}
fx_bytestream *fx_bytestream_create_readonly_view(
const unsigned char *buf,
size_t max)
{
fx_bytestream *s = fx_object_create(FX_TYPE_BYTESTREAM);
if (!s) {
return NULL;
}
fx_stream_cfg *cfg = fx_object_get_protected(s, FX_TYPE_STREAM);
struct fx_bytestream_p *p
= fx_object_get_private(s, FX_TYPE_BYTESTREAM);
cfg->s_mode = FX_STREAM_READ | FX_STREAM_BINARY | Z__FX_STREAM_STATIC;
p->s_buf = (unsigned char *)buf;
p->s_max = max;
p->s_len = max;
p->s_alloc = 0;
return s;
}
fx_bytestream *fx_bytestream_create(void)
{
fx_bytestream *s = fx_object_create(FX_TYPE_BYTESTREAM);
if (!s) {
return NULL;
}
fx_stream_cfg *cfg = fx_object_get_protected(s, FX_TYPE_STREAM);
struct fx_bytestream_p *p
= fx_object_get_private(s, FX_TYPE_BYTESTREAM);
cfg->s_mode = FX_STREAM_READ | FX_STREAM_WRITE | FX_STREAM_BINARY
| Z__FX_STREAM_STATIC;
p->s_buf = malloc(DEFAULT_CAPACITY + 1);
if (!p->s_buf) {
fx_bytestream_unref(s);
return NULL;
}
memset(p->s_buf, 0x0, DEFAULT_CAPACITY + 1);
p->s_max = DEFAULT_CAPACITY;
p->s_len = 0;
p->s_alloc = 1;
return s;
}
size_t fx_bytestream_get_length(const fx_bytestream *strv)
{
FX_CLASS_DISPATCH_STATIC_0(
FX_TYPE_BYTESTREAM,
bytestream_get_length,
strv);
}
enum fx_status fx_bytestream_reset(fx_bytestream *strv)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BYTESTREAM, bytestream_reset, strv);
}
const unsigned char *fx_bytestream_get_ptr(const fx_bytestream *s)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BYTESTREAM, bytestream_get_ptr, s);
}
unsigned char *fx_bytestream_steal(fx_bytestream *s)
{
FX_CLASS_DISPATCH_STATIC_0(FX_TYPE_BYTESTREAM, bytestream_steal, s);
}
/*** VIRTUAL FUNCTIONS ********************************************************/
static void bytestream_init(fx_object *obj, void *priv)
{
struct fx_bytestream_p *stream = priv;
}
static void bytestream_fini(fx_object *obj, void *priv)
{
struct fx_bytestream_p *stream = priv;
if (stream->s_alloc && stream->s_buf) {
free(stream->s_buf);
}
}
static enum fx_status stream_read(
fx_stream *stream,
void *buf,
size_t count,
size_t *nr_read)
{
struct fx_bytestream_p *s
= fx_object_get_private(stream, FX_TYPE_BYTESTREAM);
enum fx_status status = __gets(s, buf, count, nr_read);
return status;
}
static enum fx_status stream_write(
fx_stream *stream,
const void *buf,
size_t count,
size_t *nr_written)
{
struct fx_bytestream_p *s
= fx_object_get_private(stream, FX_TYPE_BYTESTREAM);
enum fx_status status
= __puts(s, (const unsigned char *)buf, count, nr_written);
return status;
}
/*** CLASS DEFINITION *********************************************************/
FX_TYPE_CLASS_BEGIN(fx_bytestream)
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_stream, FX_TYPE_STREAM)
FX_INTERFACE_ENTRY(s_close) = NULL;
FX_INTERFACE_ENTRY(s_seek) = NULL;
FX_INTERFACE_ENTRY(s_tell) = NULL;
FX_INTERFACE_ENTRY(s_getc) = NULL;
FX_INTERFACE_ENTRY(s_read) = stream_read;
FX_INTERFACE_ENTRY(s_write) = stream_write;
FX_INTERFACE_ENTRY(s_reserve) = NULL;
FX_TYPE_VTABLE_INTERFACE_END(fx_stream, FX_TYPE_STREAM)
FX_TYPE_CLASS_END(fx_bytestream)
FX_TYPE_DEFINITION_BEGIN(fx_bytestream)
FX_TYPE_ID(0xdcb7fb3a, 0xc476, 0x4c0b, 0xad5a, 0x039d1190a5b7);
FX_TYPE_EXTENDS(FX_TYPE_STREAM);
FX_TYPE_CLASS(fx_bytestream_class);
FX_TYPE_INSTANCE_PRIVATE(struct fx_bytestream_p);
FX_TYPE_INSTANCE_INIT(bytestream_init);
FX_TYPE_INSTANCE_FINI(bytestream_fini);
FX_TYPE_DEFINITION_END(fx_bytestream)
+37
View File
@@ -0,0 +1,37 @@
#ifndef FX_CORE_BYTESTREAM_H_
#define FX_CORE_BYTESTREAM_H_
#include <fx/macros.h>
#include <fx/misc.h>
#include <fx/status.h>
#include <fx/stream.h>
#include <stddef.h>
FX_DECLS_BEGIN;
#define FX_TYPE_BYTESTREAM (fx_bytestream_get_type())
FX_DECLARE_TYPE(fx_bytestream);
FX_TYPE_CLASS_DECLARATION_BEGIN(fx_bytestream)
FX_TYPE_CLASS_DECLARATION_END(fx_bytestream)
FX_API fx_type_id fx_bytestream_get_type(void);
FX_API fx_bytestream *fx_bytestream_create(void);
FX_API fx_bytestream *fx_bytestream_create_view(unsigned char *buf, size_t max);
FX_API fx_bytestream *fx_bytestream_create_readonly_view(
const unsigned char *buf,
size_t max);
FX_API fx_status fx_bytestream_reset(fx_bytestream *strv);
FX_API const unsigned char *fx_bytestream_get_ptr(const fx_bytestream *strv);
FX_API unsigned char *fx_bytestream_steal(fx_bytestream *strv);
FX_API size_t fx_bytestream_get_length(const fx_bytestream *strv);
FX_API size_t fx_bytestream_get_available(const fx_bytestream *strv);
FX_DECLS_END;
#endif
+2
View File
@@ -22,6 +22,7 @@ typedef struct _fx_object_class {
FX_TYPE_FWDREF(fx_stream) *,
const char *);
fx_status (*hash)(const struct fx_value *, uint64_t *);
fx_status (*clone)(const struct fx_value *, struct fx_value *);
} fx_object_class;
FX_API fx_type_id fx_object_get_type(void);
@@ -46,6 +47,7 @@ FX_API fx_status fx_object_to_string(
const fx_object *p,
FX_TYPE_FWDREF(fx_stream) * out,
const char *format);
FX_API fx_status fx_object_clone(const fx_object *src, fx_object **dest);
FX_API bool fx_object_is_type(const fx_object *p, fx_type_id type);
#endif
+18 -1
View File
@@ -23,7 +23,7 @@ FX_TYPE_DEFINITION_END(fx_object)
fx_type_id fx_object_query_type(const struct _fx_object *obj)
{
return &obj->obj_type->ty_id;
return obj ? &obj->obj_type->ty_id : NULL;
}
fx_result fx_object_instantiate(
@@ -98,6 +98,23 @@ fx_status fx_object_to_string(
return FX_SUCCESS;
}
fx_status fx_object_clone(const fx_object *src, fx_object **dest)
{
fx_object_class *iface = fx_object_get_interface(src, FX_TYPE_OBJECT);
fx_value dest_v = FX_VALUE_EMPTY;
if (!iface || !iface->clone) {
return FX_ERR_NOT_SUPPORTED;
}
fx_status status = iface->clone(&FX_VALUE_OBJECT(src), &dest_v);
if (!FX_OK(status)) {
return status;
}
fx_value_get_object(&dest_v, dest);
return status;
}
bool fx_object_is_type(const struct _fx_object *p, fx_type_id type)
{
if (!p) {
+3 -3
View File
@@ -11,11 +11,11 @@ int main(int argc, const char **argv)
return -1;
}
const char *path_cstr = argv[1];
fx_path *path = fx_path_create_from_cstr(path_cstr);
const char *path = argv[1];
fx_file *src = NULL;
fx_result result = fx_file_open(NULL, path, FX_FILE_READ_ONLY, &src);
fx_result result
= fx_file_open(NULL, FX_CSTR(path), FX_FILE_READ_ONLY, &src);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
+3 -3
View File
@@ -11,11 +11,11 @@ int main(int argc, const char **argv)
return -1;
}
const char *path_cstr = argv[1];
fx_path *path = fx_path_create_from_cstr(path_cstr);
const char *path = argv[1];
fx_file *src = NULL;
fx_result result = fx_file_open(NULL, path, FX_FILE_READ_ONLY, &src);
fx_result result
= fx_file_open(NULL, FX_CSTR(path), FX_FILE_READ_ONLY, &src);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
+3 -3
View File
@@ -9,11 +9,11 @@ int main(int argc, const char **argv)
return -1;
}
const char *path_cstr = argv[1];
fx_path *path = fx_path_create_from_cstr(path_cstr);
const char *path = argv[1];
fx_file *src = NULL;
fx_result result = fx_file_open(NULL, path, FX_FILE_READ_ONLY, &src);
fx_result result
= fx_file_open(NULL, FX_CSTR(path), FX_FILE_READ_ONLY, &src);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;
+3 -3
View File
@@ -10,11 +10,11 @@ int main(int argc, const char **argv)
return -1;
}
const char *path_cstr = argv[1];
fx_path *path = fx_path_create_from_cstr(path_cstr);
const char *path = argv[1];
fx_file *src = NULL;
fx_result result = fx_file_open(NULL, path, FX_FILE_READ_ONLY, &src);
fx_result result
= fx_file_open(NULL, FX_CSTR(path), FX_FILE_READ_ONLY, &src);
if (fx_result_is_error(result)) {
fx_throw(result);
return -1;