Compare commits
9 Commits
edfb3e24a3
...
1710f705e9
| Author | SHA1 | Date | |
|---|---|---|---|
| 1710f705e9 | |||
| 96bf76aabc | |||
| 26b368a512 | |||
| a30e76e525 | |||
| 3b39f794f9 | |||
| 5d6f2a5ce8 | |||
| fec3be2140 | |||
| f2e1d89313 | |||
| 6bfe3f0a6e |
@@ -40,13 +40,13 @@ static enum bshell_status process_record(
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
fx_iterator *aliases = fx_iterator_begin(rt->rt_aliases);
|
||||
const fx_iterator *aliases = fx_iterator_begin(rt->rt_aliases);
|
||||
fx_foreach(item_v, aliases)
|
||||
{
|
||||
fx_hashtable_item *item;
|
||||
fx_value_get_object(&item_v, &item);
|
||||
fx_value alias_v = fx_hashtable_item_get_value(item);
|
||||
bshell_pipeline_write_value(pipeline, alias_v, false);
|
||||
fx_value_get_object(item_v, &item);
|
||||
const fx_value *alias_v = fx_hashtable_item_get_value(item);
|
||||
bshell_pipeline_write_value(pipeline, *alias_v, false);
|
||||
}
|
||||
fx_iterator_unref(aliases);
|
||||
|
||||
@@ -55,13 +55,14 @@ static enum bshell_status process_record(
|
||||
while (scope) {
|
||||
fx_hashtable *function_map
|
||||
= bshell_runtime_scope_get_functions(scope);
|
||||
fx_iterator *functions = fx_iterator_begin(function_map);
|
||||
const fx_iterator *functions = fx_iterator_begin(function_map);
|
||||
fx_foreach(item_v, functions)
|
||||
{
|
||||
fx_hashtable_item *item;
|
||||
fx_value_get_object(&item_v, &item);
|
||||
fx_value func_v = fx_hashtable_item_get_value(item);
|
||||
bshell_pipeline_write_value(pipeline, func_v, false);
|
||||
fx_value_get_object(item_v, &item);
|
||||
const fx_value *func_v
|
||||
= fx_hashtable_item_get_value(item);
|
||||
bshell_pipeline_write_value(pipeline, *func_v, false);
|
||||
}
|
||||
fx_iterator_unref(functions);
|
||||
|
||||
@@ -72,12 +73,12 @@ static enum bshell_status process_record(
|
||||
fx_foreach(asm_v, assemblies)
|
||||
{
|
||||
fx_assembly *assembly = NULL;
|
||||
fx_value_get_object(&asm_v, &assembly);
|
||||
fx_value_get_object(asm_v, &assembly);
|
||||
fx_iterator *types = fx_assembly_get_types(assembly);
|
||||
fx_foreach(v, types)
|
||||
{
|
||||
fx_type *ty = NULL;
|
||||
fx_value_get_object(&v, &ty);
|
||||
fx_value_get_object(v, &ty);
|
||||
fx_type_flags ty_flags = fx_type_get_flags(ty);
|
||||
bool is_abstract = (ty_flags & FX_TYPE_F_ABSTRACT) != 0;
|
||||
if (is_abstract) {
|
||||
|
||||
@@ -17,7 +17,7 @@ FX_TYPE_CLASS_DECLARATION_END(bshell_get_verb)
|
||||
|
||||
struct bshell_get_verb_p {
|
||||
fx_hashtable *c_verbs;
|
||||
fx_iterator *c_it;
|
||||
const fx_iterator *c_it;
|
||||
};
|
||||
|
||||
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
||||
@@ -38,18 +38,18 @@ static enum bshell_status process_record(
|
||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_VERB);
|
||||
|
||||
do {
|
||||
fx_value v = fx_iterator_get_value(p->c_it);
|
||||
if (!v.v_type) {
|
||||
const fx_value *v = fx_iterator_get_value(p->c_it);
|
||||
if (!v) {
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
fx_hashtable_item *item = NULL;
|
||||
fx_value_get_object(&v, &item);
|
||||
fx_value_get_object(v, &item);
|
||||
|
||||
v = fx_hashtable_item_get_value(item);
|
||||
|
||||
bshell_verb *verb = NULL;
|
||||
fx_value_get_object(&v, &verb);
|
||||
fx_value_get_object(v, &verb);
|
||||
fx_iterator_move_next(p->c_it);
|
||||
|
||||
if (bshell_verb_is_reserved(verb)) {
|
||||
@@ -59,7 +59,7 @@ static enum bshell_status process_record(
|
||||
bshell_verb_ref(verb);
|
||||
bshell_pipeline_write_value(
|
||||
pipeline,
|
||||
fx_value_copy_return(fx_hashtable_item_get_value(item)),
|
||||
fx_value_ref_copy_return(v),
|
||||
false);
|
||||
break;
|
||||
} while (1);
|
||||
|
||||
@@ -154,10 +154,8 @@ struct bshell_ast_node *bshell_ast_iterator_dequeue(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bshell_ast_node *node = fx_unbox(
|
||||
struct bshell_ast_node,
|
||||
cur,
|
||||
n_it.e_entry);
|
||||
struct bshell_ast_node *node
|
||||
= fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
|
||||
const struct bshell_ast_node_definition *def
|
||||
= bshell_ast_node_definitions[node->n_type];
|
||||
|
||||
@@ -178,10 +176,8 @@ void bshell_ast_iterator_enqueue(
|
||||
|
||||
fx_queue_entry *cur = fx_queue_first(&it->it_queue);
|
||||
if (cur) {
|
||||
struct bshell_ast_node *cur_node = fx_unbox(
|
||||
struct bshell_ast_node,
|
||||
cur,
|
||||
n_it.e_entry);
|
||||
struct bshell_ast_node *cur_node
|
||||
= fx_unbox(struct bshell_ast_node, cur, n_it.e_entry);
|
||||
new_depth = cur_node->n_it.e_depth + 1;
|
||||
}
|
||||
|
||||
@@ -222,11 +218,8 @@ enum bshell_status bshell_ast_node_iterate(
|
||||
return BSHELL_ERR_INTERNAL_FAILURE;
|
||||
}
|
||||
|
||||
struct bshell_ast_iterate_result result = callback(
|
||||
node,
|
||||
BSHELL_AST_ITERATION_PRE,
|
||||
it,
|
||||
arg);
|
||||
struct bshell_ast_iterate_result result
|
||||
= callback(node, BSHELL_AST_ITERATION_PRE, it, arg);
|
||||
if (result.r_status != BSHELL_SUCCESS
|
||||
|| result.r_flags & BSHELL_AST_ITERATE_STOP) {
|
||||
return result.r_status;
|
||||
@@ -258,11 +251,8 @@ enum bshell_status bshell_ast_node_iterate(
|
||||
return BSHELL_ERR_INTERNAL_FAILURE;
|
||||
}
|
||||
|
||||
struct bshell_ast_iterate_result result = callback(
|
||||
node,
|
||||
BSHELL_AST_ITERATION_POST,
|
||||
it,
|
||||
arg);
|
||||
struct bshell_ast_iterate_result result
|
||||
= callback(node, BSHELL_AST_ITERATION_POST, it, arg);
|
||||
if (result.r_status != BSHELL_SUCCESS
|
||||
|| result.r_flags & BSHELL_AST_ITERATE_STOP) {
|
||||
return result.r_status;
|
||||
|
||||
@@ -4,13 +4,22 @@
|
||||
|
||||
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
{
|
||||
struct bshell_double_ast_node *i = (struct bshell_double_ast_node *)
|
||||
node;
|
||||
struct bshell_double_ast_node *i
|
||||
= (struct bshell_double_ast_node *)node;
|
||||
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_double_ast_node *d
|
||||
= (struct bshell_double_ast_node *)node;
|
||||
bshell_lex_token_destroy(d->n_value);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition double_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_DOUBLE,
|
||||
.def_node_size = sizeof(struct bshell_double_ast_node),
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -9,10 +9,8 @@ static enum bshell_status collect_children(
|
||||
|
||||
fx_queue_entry *cur = fx_queue_first(&func->n_params);
|
||||
while (cur) {
|
||||
struct bshell_ast_node *child = fx_unbox(
|
||||
struct bshell_ast_node,
|
||||
cur,
|
||||
n_entry);
|
||||
struct bshell_ast_node *child
|
||||
= fx_unbox(struct bshell_ast_node, cur, n_entry);
|
||||
bshell_ast_iterator_enqueue(it, child);
|
||||
cur = fx_queue_next(cur);
|
||||
}
|
||||
@@ -26,14 +24,22 @@ static enum bshell_status collect_children(
|
||||
|
||||
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
{
|
||||
const struct bshell_func_ast_node *func = (const struct
|
||||
bshell_func_ast_node *)node;
|
||||
const struct bshell_func_ast_node *func
|
||||
= (const struct bshell_func_ast_node *)node;
|
||||
fx_bstr_write_fmt(out, NULL, "%s", func->n_name->tok_str);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_func_ast_node *d = (struct bshell_func_ast_node *)node;
|
||||
bshell_lex_token_destroy(d->n_name);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition func_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_FUNC,
|
||||
.def_node_size = sizeof(struct bshell_func_ast_node),
|
||||
.def_collect_children = collect_children,
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -8,8 +8,16 @@ static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
fx_value_to_string(&i->n_value->tok_number, (fx_stream *)out, NULL);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_int_ast_node *i = (struct bshell_int_ast_node *)node;
|
||||
bshell_lex_token_destroy(i->n_value);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition int_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_INT,
|
||||
.def_node_size = sizeof(struct bshell_int_ast_node),
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <bshell/ast.h>
|
||||
#include <bshell/parse/lex.h>
|
||||
|
||||
static enum bshell_status collect_children(
|
||||
struct bshell_ast_node *node,
|
||||
@@ -41,9 +42,20 @@ static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
}
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_redirection_ast_node *v
|
||||
= (struct bshell_redirection_ast_node *)node;
|
||||
if (v->n_out_tok) {
|
||||
bshell_lex_token_destroy(v->n_out_tok);
|
||||
}
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition redirection_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_REDIRECTION,
|
||||
.def_node_size = sizeof(struct bshell_redirection_ast_node),
|
||||
.def_collect_children = collect_children,
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -3,14 +3,22 @@
|
||||
|
||||
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
{
|
||||
const struct bshell_string_ast_node *string = (const struct
|
||||
bshell_string_ast_node *)
|
||||
node;
|
||||
const struct bshell_string_ast_node *string
|
||||
= (const struct bshell_string_ast_node *)node;
|
||||
fx_bstr_write_fmt(out, NULL, "%s", string->n_value->tok_str);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_string_ast_node *string
|
||||
= (struct bshell_string_ast_node *)node;
|
||||
bshell_lex_token_destroy(string->n_value);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition string_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_STRING,
|
||||
.def_node_size = sizeof(struct bshell_string_ast_node),
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
|
||||
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
{
|
||||
const struct bshell_var_ast_node *var = (const struct
|
||||
bshell_var_ast_node *)node;
|
||||
const struct bshell_var_ast_node *var
|
||||
= (const struct bshell_var_ast_node *)node;
|
||||
fx_bstr_write_fmt(out, NULL, "%s", var->n_ident->tok_str);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_var_ast_node *v = (struct bshell_var_ast_node *)node;
|
||||
bshell_lex_token_destroy(v->n_ident);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition var_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_VAR,
|
||||
.def_node_size = sizeof(struct bshell_var_ast_node),
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -3,13 +3,21 @@
|
||||
|
||||
static void to_string(const struct bshell_ast_node *node, fx_bstr *out)
|
||||
{
|
||||
const struct bshell_word_ast_node *word = (const struct
|
||||
bshell_word_ast_node *)node;
|
||||
const struct bshell_word_ast_node *word
|
||||
= (const struct bshell_word_ast_node *)node;
|
||||
fx_bstr_write_fmt(out, NULL, "%s", word->n_value->tok_str);
|
||||
}
|
||||
|
||||
static enum bshell_status cleanup(struct bshell_ast_node *node)
|
||||
{
|
||||
struct bshell_word_ast_node *w = (struct bshell_word_ast_node *)node;
|
||||
bshell_lex_token_destroy(w->n_value);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
struct bshell_ast_node_definition word_bshell_ast_node = {
|
||||
.def_id = BSHELL_AST_WORD,
|
||||
.def_node_size = sizeof(struct bshell_word_ast_node),
|
||||
.def_to_string = to_string,
|
||||
.def_cleanup = cleanup,
|
||||
};
|
||||
|
||||
@@ -17,6 +17,11 @@ static void init(fx_object *obj, void *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static void fini(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_command_p *cmd = priv;
|
||||
}
|
||||
|
||||
static void command_set_args(
|
||||
struct bshell_command_p *cmd,
|
||||
fx_value *args,
|
||||
@@ -156,12 +161,12 @@ bshell_command *bshell_command_find_static(const char *name)
|
||||
fx_foreach(asm_v, assemblies)
|
||||
{
|
||||
fx_assembly *assembly = NULL;
|
||||
fx_value_get_object(&asm_v, &assembly);
|
||||
fx_value_get_object(asm_v, &assembly);
|
||||
fx_iterator *types = fx_assembly_get_types(assembly);
|
||||
fx_foreach(v, types)
|
||||
{
|
||||
fx_type *ty = NULL;
|
||||
fx_value_get_object(&v, &ty);
|
||||
fx_value_get_object(v, &ty);
|
||||
if (fx_type_id_compare(
|
||||
fx_type_get_id(ty),
|
||||
BSHELL_TYPE_COMMAND)
|
||||
@@ -283,5 +288,6 @@ FX_TYPE_DEFINITION_BEGIN(bshell_command)
|
||||
FX_TYPE_NAME("bshell.runtime.command");
|
||||
FX_TYPE_CLASS(bshell_command_class);
|
||||
FX_TYPE_INSTANCE_INIT(init);
|
||||
FX_TYPE_INSTANCE_FINI(fini);
|
||||
FX_TYPE_INSTANCE_PRIVATE(struct bshell_command_p);
|
||||
FX_TYPE_DEFINITION_END(bshell_command)
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
#include <bshell/command/command.h>
|
||||
#include <bshell/command/function.h>
|
||||
#include <bshell/runtime/pipeline.h>
|
||||
#include <bshell/runtime/runtime.h>
|
||||
#include <bshell/runtime/script-block.h>
|
||||
#include <bshell/status.h>
|
||||
#include <fx/collections/array.h>
|
||||
#include <fx/reflection/function.h>
|
||||
#include <fx/string.h>
|
||||
#include <fx/vector.h>
|
||||
|
||||
struct bshell_function_p {
|
||||
char *func_name;
|
||||
fx_array *func_positional_params;
|
||||
bshell_scriptblock *func_body;
|
||||
};
|
||||
|
||||
static void init(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_function_p *func_p = priv;
|
||||
func_p->func_positional_params = fx_array_create();
|
||||
func_p->func_body = bshell_scriptblock_create();
|
||||
}
|
||||
|
||||
static void fini(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_function_p *func_p = priv;
|
||||
if (func_p->func_name) {
|
||||
free(func_p->func_name);
|
||||
}
|
||||
|
||||
fx_array_unref(func_p->func_positional_params);
|
||||
bshell_scriptblock_unref(func_p->func_body);
|
||||
}
|
||||
|
||||
static enum bshell_status get_callable_name(
|
||||
const bshell_function *func,
|
||||
fx_string *out)
|
||||
{
|
||||
struct bshell_function_p *func_p
|
||||
= fx_object_get_private(func, BSHELL_TYPE_FUNCTION);
|
||||
fx_string_append_cstrf(out, "%s", func_p->func_name);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static enum bshell_status begin_processing(bshell_command *cmd)
|
||||
{
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static enum bshell_status process_record(
|
||||
bshell_command *cmd,
|
||||
bshell_pipeline *pipeline,
|
||||
struct bshell_runtime *rt)
|
||||
{
|
||||
struct bshell_function_p *func_p
|
||||
= fx_object_get_private(cmd, BSHELL_TYPE_FUNCTION);
|
||||
bshell_runtime_push_scope(rt, func_p->func_body);
|
||||
|
||||
const fx_iterator *param_it
|
||||
= fx_iterator_begin(func_p->func_positional_params);
|
||||
size_t i = 1;
|
||||
fx_foreach(v, param_it)
|
||||
{
|
||||
fx_string *param = NULL;
|
||||
fx_value_get_object(v, ¶m);
|
||||
|
||||
const fx_value *arg = bshell_command_get_arg(cmd, i);
|
||||
if (!arg) {
|
||||
break;
|
||||
}
|
||||
|
||||
bshell_variable *var = bshell_runtime_define_var(
|
||||
rt,
|
||||
fx_string_get_cstr(param));
|
||||
bshell_variable_set_value(var, *arg);
|
||||
}
|
||||
fx_iterator_unref(param_it);
|
||||
#if 0
|
||||
bshell_variable *item = bshell_runtime_define_var(rt, "_");
|
||||
bshell_variable_set_value(item, &in);
|
||||
#endif
|
||||
|
||||
fx_value out = bshell_runtime_eval(rt);
|
||||
bshell_runtime_pop_scope(rt);
|
||||
if (fx_value_is_set(&out)) {
|
||||
bshell_pipeline_write_value(pipeline, out, false);
|
||||
fx_value_unset(&out);
|
||||
}
|
||||
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
static enum bshell_status end_processing(bshell_command *cmd)
|
||||
{
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
bshell_function *bshell_function_create(const char *name)
|
||||
{
|
||||
bshell_function *out = fx_object_create(BSHELL_TYPE_FUNCTION);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bshell_function_p *func
|
||||
= fx_object_get_private(out, BSHELL_TYPE_FUNCTION);
|
||||
func->func_name = fx_strdup(name);
|
||||
if (!func->func_name) {
|
||||
bshell_function_unref(out);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void bshell_function_add_positional_parameter(
|
||||
bshell_function *func,
|
||||
const char *name)
|
||||
{
|
||||
fx_string *str = fx_string_create_from_cstr(name);
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct bshell_function_p *func_p
|
||||
= fx_object_get_private(func, BSHELL_TYPE_FUNCTION);
|
||||
fx_array_push_back(
|
||||
func_p->func_positional_params,
|
||||
FX_VALUE_OBJECT(str));
|
||||
fx_string_unref(str);
|
||||
}
|
||||
|
||||
static const char *function_get_name(const struct bshell_function_p *func)
|
||||
{
|
||||
return func->func_name;
|
||||
}
|
||||
|
||||
static const fx_array *function_get_positional_parameters(
|
||||
const struct bshell_function_p *func)
|
||||
{
|
||||
return func->func_positional_params;
|
||||
}
|
||||
|
||||
static bshell_scriptblock *function_get_body(struct bshell_function_p *func)
|
||||
{
|
||||
return func->func_body;
|
||||
}
|
||||
|
||||
const char *bshell_function_get_name(const bshell_function *func)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(
|
||||
BSHELL_TYPE_FUNCTION,
|
||||
function_get_name,
|
||||
func);
|
||||
}
|
||||
|
||||
const fx_array *bshell_function_get_positional_parameters(
|
||||
const bshell_function *func)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(
|
||||
BSHELL_TYPE_FUNCTION,
|
||||
function_get_positional_parameters,
|
||||
func);
|
||||
}
|
||||
|
||||
bshell_scriptblock *bshell_function_get_body(bshell_function *func)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_0(
|
||||
BSHELL_TYPE_FUNCTION,
|
||||
function_get_body,
|
||||
func);
|
||||
}
|
||||
|
||||
FX_TYPE_CLASS_BEGIN(bshell_function)
|
||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||
FX_INTERFACE_ENTRY(to_string) = NULL;
|
||||
FX_TYPE_VTABLE_INTERFACE_END(fx_object, FX_TYPE_OBJECT)
|
||||
|
||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(bshell_command, BSHELL_TYPE_COMMAND)
|
||||
FX_INTERFACE_ENTRY(c_command_type) = "Function";
|
||||
FX_INTERFACE_ENTRY(c_get_callable_name) = get_callable_name;
|
||||
FX_INTERFACE_ENTRY(c_begin_processing) = begin_processing;
|
||||
FX_INTERFACE_ENTRY(c_process_record) = process_record;
|
||||
FX_INTERFACE_ENTRY(c_end_processing) = end_processing;
|
||||
FX_TYPE_VTABLE_INTERFACE_END(bshell_command, BSHELL_TYPE_COMMAND)
|
||||
FX_TYPE_CLASS_END(bshell_function)
|
||||
|
||||
FX_TYPE_DEFINITION_BEGIN(bshell_function)
|
||||
FX_TYPE_ID(0x041f1918, 0x6155, 0x4cee, 0xbb01, 0xfef2d6aa1bcf);
|
||||
FX_TYPE_NAME("bshell.runtime.function");
|
||||
FX_TYPE_EXTENDS(BSHELL_TYPE_COMMAND);
|
||||
FX_TYPE_CLASS(bshell_function_class);
|
||||
FX_TYPE_INSTANCE_INIT(init);
|
||||
FX_TYPE_INSTANCE_FINI(fini);
|
||||
FX_TYPE_INSTANCE_PRIVATE(struct bshell_function_p);
|
||||
FX_TYPE_DEFINITION_END(bshell_function)
|
||||
|
||||
@@ -32,6 +32,16 @@ enum bshell_status bshell_compile(
|
||||
}
|
||||
|
||||
status = compile_resolve_labels(&ctx);
|
||||
|
||||
while (!fx_queue_empty(&ctx.c_state)) {
|
||||
compile_pop_state(&ctx);
|
||||
}
|
||||
|
||||
while (!fx_queue_empty(&ctx.c_stack)) {
|
||||
struct compile_value *value = compile_pop_value(&ctx);
|
||||
compile_value_destroy(value);
|
||||
}
|
||||
|
||||
if (status != BSHELL_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -72,5 +72,6 @@ enum bshell_status compile_expression(
|
||||
compile_value_destroy(result);
|
||||
}
|
||||
|
||||
compile_pop_state(ctx);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#include <bshell/ast.h>
|
||||
#include <bshell/compile.h>
|
||||
#include <bshell/parse/token.h>
|
||||
#include <bshell/status.h>
|
||||
|
||||
enum bshell_status bshell_compile_function(
|
||||
struct bshell_ast_node *src,
|
||||
bshell_function **out)
|
||||
{
|
||||
struct bshell_func_ast_node *func_ast
|
||||
= (struct bshell_func_ast_node *)src;
|
||||
bshell_function *func
|
||||
= bshell_function_create(func_ast->n_name->tok_str);
|
||||
if (!func) {
|
||||
return BSHELL_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
fx_queue_entry *cur = fx_queue_first(&func_ast->n_params);
|
||||
while (cur) {
|
||||
struct bshell_var_ast_node *var_ast = fx_unbox(
|
||||
struct bshell_var_ast_node,
|
||||
cur,
|
||||
n_base.n_entry);
|
||||
bshell_function_add_positional_parameter(
|
||||
func,
|
||||
var_ast->n_ident->tok_str);
|
||||
cur = fx_queue_next(cur);
|
||||
}
|
||||
|
||||
bshell_scriptblock *body = bshell_function_get_body(func);
|
||||
enum bshell_status status = bshell_compile(func_ast->n_body, body);
|
||||
if (status != BSHELL_SUCCESS) {
|
||||
bshell_function_unref(func);
|
||||
return status;
|
||||
}
|
||||
|
||||
*out = func;
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
@@ -14,8 +14,8 @@ struct compile_state *compile_push_state(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct compile_state_type *state_type = state_types
|
||||
[state_type_id];
|
||||
const struct compile_state_type *state_type
|
||||
= state_types[state_type_id];
|
||||
if (!state_type) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -43,10 +43,6 @@ void compile_pop_state(struct compile_ctx *ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fx_queue_prev(&state->s_entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->s_type->s_compile_end) {
|
||||
state->s_type->s_compile_end(ctx);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ enum bshell_status format_object_table(fx_object *object, fx_stream *dest)
|
||||
|
||||
struct bshell_table_ctx ctx;
|
||||
bshell_table_ctx_init(&ctx, dest);
|
||||
fx_iterator *it = fx_iterator_begin(object);
|
||||
const fx_iterator *it = fx_iterator_begin(object);
|
||||
if (!it) {
|
||||
bshell_table_ctx_prepare_columns_from_format(
|
||||
&ctx,
|
||||
@@ -68,17 +68,17 @@ enum bshell_status format_object_table(fx_object *object, fx_stream *dest)
|
||||
bshell_table_ctx_print_headers(&ctx);
|
||||
bshell_table_ctx_print_record(&ctx, &FX_VALUE_OBJECT(object));
|
||||
} else {
|
||||
fx_value first = fx_iterator_get_value(it);
|
||||
if (first.v_type) {
|
||||
const fx_value *first = fx_iterator_get_value(it);
|
||||
if (first) {
|
||||
bshell_table_ctx_prepare_columns_from_format(
|
||||
&ctx,
|
||||
fx_type_get_by_id(first.v_type),
|
||||
fx_type_get_by_id(first->v_type),
|
||||
fmt);
|
||||
}
|
||||
bshell_table_ctx_print_headers(&ctx);
|
||||
fx_foreach(value, it)
|
||||
{
|
||||
bshell_table_ctx_print_record(&ctx, &value);
|
||||
bshell_table_ctx_print_record(&ctx, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ enum bshell_status bshell_table_ctx_prepare_columns_from_object(
|
||||
fx_iterator *it = fx_type_get_properties(record_type);
|
||||
fx_foreach(prop_v, it)
|
||||
{
|
||||
fx_array_push_back(properties, prop_v);
|
||||
fx_array_push_back(properties, *prop_v);
|
||||
}
|
||||
fx_iterator_unref(it);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef BSHELL_COMMAND_FUNCTION_H_
|
||||
#define BSHELL_COMMAND_FUNCTION_H_
|
||||
|
||||
#include <bshell/runtime/script-block.h>
|
||||
#include <fx/collections/array.h>
|
||||
#include <fx/macros.h>
|
||||
|
||||
FX_DECLS_BEGIN;
|
||||
@@ -17,6 +19,14 @@ FX_TYPE_CLASS_DECLARATION_END(bshell_function)
|
||||
extern fx_type_id bshell_function_get_type(void);
|
||||
|
||||
extern bshell_function *bshell_function_create(const char *name);
|
||||
extern void bshell_function_add_positional_parameter(
|
||||
bshell_function *func,
|
||||
const char *name);
|
||||
|
||||
extern const char *bshell_function_get_name(const bshell_function *func);
|
||||
extern const fx_array *bshell_function_get_positional_parameters(
|
||||
const bshell_function *func);
|
||||
extern bshell_scriptblock *bshell_function_get_body(bshell_function *func);
|
||||
|
||||
FX_DECLS_END;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef BSHELL_COMPILE_H_
|
||||
#define BSHELL_COMPILE_H_
|
||||
|
||||
#include <bshell/command/function.h>
|
||||
#include <bshell/runtime/script-block.h>
|
||||
|
||||
struct bshell_ast_node;
|
||||
@@ -8,5 +9,8 @@ struct bshell_ast_node;
|
||||
extern enum bshell_status bshell_compile(
|
||||
struct bshell_ast_node *src,
|
||||
bshell_scriptblock *dest);
|
||||
extern enum bshell_status bshell_compile_function(
|
||||
struct bshell_ast_node *src,
|
||||
bshell_function **out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define BSHELL_RUNTIME_RUNTIME_H_
|
||||
|
||||
#include <bshell/command/command.h>
|
||||
#include <bshell/command/function.h>
|
||||
#include <bshell/runtime/script-block.h>
|
||||
#include <bshell/runtime/var.h>
|
||||
#include <fx/collections/hashtable.h>
|
||||
@@ -32,6 +33,9 @@ extern bshell_variable *bshell_runtime_find_var(
|
||||
extern bshell_variable *bshell_runtime_define_var(
|
||||
struct bshell_runtime *rt,
|
||||
const char *name);
|
||||
extern enum bshell_status bshell_runtime_define_function(
|
||||
struct bshell_runtime *rt,
|
||||
bshell_function *func);
|
||||
|
||||
extern bshell_command *bshell_runtime_find_command(
|
||||
struct bshell_runtime *rt,
|
||||
|
||||
@@ -19,7 +19,7 @@ extern bshell_variable *bshell_variable_create(const char *name);
|
||||
|
||||
extern const char *bshell_variable_get_name(const bshell_variable *var);
|
||||
extern const fx_value *bshell_variable_get_value(const bshell_variable *var);
|
||||
extern void bshell_variable_set_value(bshell_variable *var, fx_value *value);
|
||||
extern void bshell_variable_set_value(bshell_variable *var, fx_value value);
|
||||
|
||||
FX_DECLS_END;
|
||||
|
||||
|
||||
@@ -124,6 +124,8 @@ FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_verb)
|
||||
FX_TYPE_CLASS_DECLARATION_END(bshell_verb)
|
||||
|
||||
extern enum bshell_status bshell_init_all_verbs(void);
|
||||
extern enum bshell_status bshell_cleanup_all_verbs(void);
|
||||
|
||||
extern fx_hashtable *bshell_get_all_verbs(void);
|
||||
extern bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id);
|
||||
extern bshell_verb *bshell_verb_get_by_name(const char *name);
|
||||
|
||||
@@ -107,7 +107,7 @@ extern struct bshell_lex_state *lex_state_push(
|
||||
struct bshell_lex_ctx *ctx,
|
||||
enum bshell_lex_state_id state_type,
|
||||
enum state_flags flags);
|
||||
extern void lex_state_pop(struct bshell_lex_ctx *ctx);
|
||||
extern void lex_state_pop(struct bshell_lex_ctx *ctx, bool no_preserve_root);
|
||||
extern struct bshell_lex_state *lex_state_get(struct bshell_lex_ctx *ctx);
|
||||
extern void lex_state_change(
|
||||
struct bshell_lex_ctx *ctx,
|
||||
|
||||
@@ -198,11 +198,14 @@ struct bshell_lex_state *lex_state_push(
|
||||
return state;
|
||||
}
|
||||
|
||||
void lex_state_pop(struct bshell_lex_ctx *ctx)
|
||||
void lex_state_pop(struct bshell_lex_ctx *ctx, bool no_preserve_root)
|
||||
{
|
||||
fx_queue_entry *entry = fx_queue_last(&ctx->lex_state);
|
||||
if (!entry || !fx_queue_prev(entry)) {
|
||||
/* don't pop if this is the root state */
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!no_preserve_root && !fx_queue_prev(entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -451,6 +454,10 @@ enum bshell_status bshell_lex_ctx_cleanup(struct bshell_lex_ctx *ctx)
|
||||
fx_string_unref(ctx->lex_tmp);
|
||||
}
|
||||
|
||||
while (!fx_queue_empty(&ctx->lex_state)) {
|
||||
lex_state_pop(ctx, true);
|
||||
}
|
||||
|
||||
memset(ctx, 0x0, sizeof *ctx);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
@@ -1228,7 +1235,7 @@ static bool do_lex_state_transition(
|
||||
if (!recursive) {
|
||||
for (unsigned int i = 0; i < state->s_nr_terminators; i++) {
|
||||
if (state->s_terminators[i] == token) {
|
||||
lex_state_pop(ctx);
|
||||
lex_state_pop(ctx, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1275,7 +1282,7 @@ static bool do_lex_state_transition(
|
||||
const struct bshell_lex_state_link *link = best_matches[i];
|
||||
switch (link->l_type) {
|
||||
case BSHELL_LEX_STATE_LINK_POP:
|
||||
lex_state_pop(ctx);
|
||||
lex_state_pop(ctx, false);
|
||||
result = true;
|
||||
break;
|
||||
case BSHELL_LEX_STATE_LINK_PUSH: {
|
||||
|
||||
@@ -21,7 +21,7 @@ static enum bshell_status word_symbol(struct bshell_lex_ctx *ctx)
|
||||
lex_state_push(ctx, BSHELL_LEX_STATE_STATEMENT, 0);
|
||||
return BSHELL_SUCCESS;
|
||||
case BSHELL_SYM_RIGHT_PAREN:
|
||||
lex_state_pop(ctx);
|
||||
lex_state_pop(ctx, false);
|
||||
|
||||
status = push_symbol(ctx, sym->id);
|
||||
if (status != BSHELL_SUCCESS) {
|
||||
@@ -92,7 +92,8 @@ static enum bshell_status word_content(struct bshell_lex_ctx *ctx)
|
||||
|
||||
static enum bshell_status word_begin(struct bshell_lex_ctx *ctx)
|
||||
{
|
||||
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_WORD_START);
|
||||
struct bshell_lex_token *tok
|
||||
= bshell_lex_token_create(BSHELL_TOK_WORD_START);
|
||||
if (!tok) {
|
||||
return BSHELL_ERR_NO_MEMORY;
|
||||
}
|
||||
@@ -107,7 +108,8 @@ static enum bshell_status word_begin(struct bshell_lex_ctx *ctx)
|
||||
|
||||
static enum bshell_status word_end(struct bshell_lex_ctx *ctx)
|
||||
{
|
||||
struct bshell_lex_token *tok = bshell_lex_token_create(BSHELL_TOK_WORD_END);
|
||||
struct bshell_lex_token *tok
|
||||
= bshell_lex_token_create(BSHELL_TOK_WORD_END);
|
||||
if (!tok) {
|
||||
return BSHELL_ERR_NO_MEMORY;
|
||||
}
|
||||
@@ -121,12 +123,12 @@ static enum bshell_status word_pump_token(struct bshell_lex_ctx *ctx)
|
||||
fx_wchar c = peek_char(ctx);
|
||||
|
||||
if (fx_wchar_is_space(c)) {
|
||||
lex_state_pop(ctx);
|
||||
lex_state_pop(ctx, false);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
if (char_has_flags(ctx, c, BSHELL_LEX_TOKEN_TERMINATES_WORD)) {
|
||||
lex_state_pop(ctx);
|
||||
lex_state_pop(ctx, false);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@ void bshell_lex_token_destroy(struct bshell_lex_token *tok)
|
||||
switch (tok->tok_type) {
|
||||
case BSHELL_TOK_WORD:
|
||||
case BSHELL_TOK_FLAG:
|
||||
case BSHELL_TOK_VAR:
|
||||
case BSHELL_TOK_VAR_SPLAT:
|
||||
case BSHELL_TOK_STRING:
|
||||
if (tok->tok_str) {
|
||||
free(tok->tok_str);
|
||||
|
||||
@@ -31,6 +31,11 @@ static void cmdcall_fini(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_cmdcall_p *cmdcall = priv;
|
||||
|
||||
if (cmdcall->cmd_target) {
|
||||
bshell_command_end_processing(cmdcall->cmd_target);
|
||||
bshell_command_unref(cmdcall->cmd_target);
|
||||
}
|
||||
|
||||
if (cmdcall->cmd_native_path) {
|
||||
free(cmdcall->cmd_native_path);
|
||||
}
|
||||
@@ -44,11 +49,6 @@ static void cmdcall_fini(fx_object *obj, void *priv)
|
||||
}
|
||||
|
||||
fx_vector_destroy(cmdcall->cmd_args, NULL);
|
||||
|
||||
if (cmdcall->cmd_target) {
|
||||
bshell_command_end_processing(cmdcall->cmd_target);
|
||||
bshell_command_unref(cmdcall->cmd_target);
|
||||
}
|
||||
}
|
||||
|
||||
static enum bshell_status cmdcall_push_arg(
|
||||
|
||||
@@ -241,7 +241,7 @@ static enum bshell_status eval_instruction(
|
||||
pool_value = bshell_scriptblock_get_pool_value(
|
||||
scope->s_block,
|
||||
arg,
|
||||
FX_TYPE_CSTR);
|
||||
FX_TYPE_STRING);
|
||||
if (!pool_value) {
|
||||
fprintf(stderr, "RUNTIME: invalid stlocal operand\n");
|
||||
return BSHELL_ERR_BAD_SYNTAX;
|
||||
@@ -253,7 +253,7 @@ static enum bshell_status eval_instruction(
|
||||
var = bshell_runtime_define_var(rt, s);
|
||||
}
|
||||
|
||||
bshell_variable_set_value(var, &x);
|
||||
bshell_variable_set_value(var, x);
|
||||
bshell_runtime_scope_push_value(scope, &x);
|
||||
fx_value_unset(&x);
|
||||
break;
|
||||
@@ -314,7 +314,8 @@ static enum bshell_status eval_instruction(
|
||||
bshell_cmdcall *result = bshell_cmdcall_create();
|
||||
|
||||
while (arg > 0) {
|
||||
fx_value cmd_arg = bshell_runtime_scope_pop_value(scope);
|
||||
fx_value cmd_arg
|
||||
= bshell_runtime_scope_pop_value(scope);
|
||||
bshell_cmdcall_push_arg(result, cmd_arg);
|
||||
fx_value_unset(&cmd_arg);
|
||||
arg--;
|
||||
@@ -322,6 +323,7 @@ static enum bshell_status eval_instruction(
|
||||
|
||||
bstatus = bshell_cmdcall_resolve(result, rt);
|
||||
if (bstatus != BSHELL_SUCCESS) {
|
||||
bshell_cmdcall_unref(result);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -422,7 +424,9 @@ fx_value bshell_runtime_eval_global(
|
||||
{
|
||||
enum bshell_status status = BSHELL_SUCCESS;
|
||||
bshell_runtime_scope_set_block(rt->rt_global, block);
|
||||
return runtime_eval(rt);
|
||||
fx_value result = runtime_eval(rt);
|
||||
bshell_runtime_scope_set_block(rt->rt_global, NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
fx_value bshell_runtime_eval_script(
|
||||
|
||||
@@ -26,6 +26,7 @@ static void pipeline_fini(fx_object *obj, void *priv)
|
||||
for (size_t i = 0; i < pipeline->p_cmds.count; i++) {
|
||||
bshell_cmdcall_unref(pipeline->p_cmds.items[i]);
|
||||
}
|
||||
fx_vector_destroy(pipeline->p_cmds, NULL);
|
||||
|
||||
if (pipeline->p_in) {
|
||||
fx_array_unref(pipeline->p_in);
|
||||
@@ -56,10 +57,10 @@ static enum bshell_status write_value(
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
fx_iterator *it = fx_iterator_begin(container);
|
||||
const fx_iterator *it = fx_iterator_begin(container);
|
||||
fx_foreach(v, it)
|
||||
{
|
||||
fx_array_push_back(dest, fx_value_copy_return(v));
|
||||
fx_array_push_back(dest, fx_value_ref_copy_return(v));
|
||||
}
|
||||
fx_iterator_unref(it);
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ struct bshell_runtime *bshell_runtime_create(void)
|
||||
|
||||
void bshell_runtime_destroy(struct bshell_runtime *rt)
|
||||
{
|
||||
while (!fx_queue_empty(&rt->rt_scope)) {
|
||||
runtime_pop_scope(rt);
|
||||
}
|
||||
|
||||
fx_hashtable_unref(rt->rt_aliases);
|
||||
free(rt);
|
||||
}
|
||||
@@ -63,6 +67,31 @@ bshell_variable *bshell_runtime_define_var(
|
||||
return var;
|
||||
}
|
||||
|
||||
enum bshell_status bshell_runtime_define_function(
|
||||
struct bshell_runtime *rt,
|
||||
bshell_function *func)
|
||||
{
|
||||
struct bshell_runtime_scope *scope = runtime_get_scope(rt);
|
||||
if (!scope) {
|
||||
return BSHELL_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
fx_string *name
|
||||
= fx_string_create_from_cstr(bshell_function_get_name(func));
|
||||
if (!name) {
|
||||
return BSHELL_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
fx_string_transform_lowercase(name);
|
||||
fx_hashtable_put(
|
||||
scope->s_functions,
|
||||
&FX_VALUE_OBJECT(name),
|
||||
&FX_VALUE_OBJECT(func));
|
||||
fx_string_unref(name);
|
||||
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
bshell_command *bshell_runtime_find_command(
|
||||
struct bshell_runtime *rt,
|
||||
const char *callable_name)
|
||||
|
||||
@@ -37,7 +37,14 @@ void runtime_pop_scope(struct bshell_runtime *rt)
|
||||
|
||||
struct bshell_runtime_scope *scope
|
||||
= fx_unbox(struct bshell_runtime_scope, entry, s_entry);
|
||||
/* TODO */
|
||||
|
||||
if (scope->s_block) {
|
||||
bshell_scriptblock_unref(scope->s_block);
|
||||
}
|
||||
|
||||
fx_value_unset_array(scope->s_stack.items, scope->s_stack.count);
|
||||
var_map_cleanup(&scope->s_vars);
|
||||
fx_vector_destroy(scope->s_stack, NULL);
|
||||
fx_hashtable_unref(scope->s_functions);
|
||||
free(scope);
|
||||
}
|
||||
@@ -79,7 +86,11 @@ void bshell_runtime_scope_set_block(
|
||||
struct bshell_runtime_scope *scope,
|
||||
bshell_scriptblock *block)
|
||||
{
|
||||
scope->s_block = block;
|
||||
if (scope->s_block) {
|
||||
bshell_scriptblock_unref(scope->s_block);
|
||||
}
|
||||
|
||||
scope->s_block = bshell_scriptblock_ref(block);
|
||||
scope->s_ip = 0;
|
||||
bshell_scriptblock_get_text(block, &scope->s_instr, &scope->s_nr_instr);
|
||||
bshell_scriptblock_get_pool(block, &scope->s_pool, &scope->s_nr_pool);
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
#include "var-map.h"
|
||||
|
||||
static void var_entry_cleanup(fx_namemap_entry *entry)
|
||||
{
|
||||
struct var_map_entry *map_entry
|
||||
= fx_unbox(struct var_map_entry, entry, e_entry);
|
||||
bshell_variable_unref(map_entry->e_var);
|
||||
free(map_entry);
|
||||
}
|
||||
|
||||
void var_map_cleanup(struct var_map *map)
|
||||
{
|
||||
fx_namemap_cleanup(&map->m_vars, var_entry_cleanup);
|
||||
}
|
||||
|
||||
enum bshell_status var_map_put(struct var_map *map, bshell_variable *var)
|
||||
@@ -27,9 +36,7 @@ bshell_variable *var_map_get(struct var_map *map, const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct var_map_entry *entry = fx_unbox(
|
||||
struct var_map_entry,
|
||||
e,
|
||||
e_entry);
|
||||
struct var_map_entry *entry
|
||||
= fx_unbox(struct var_map_entry, e, e_entry);
|
||||
return entry->e_var;
|
||||
}
|
||||
|
||||
@@ -29,10 +29,10 @@ static const fx_value *variable_get_value(const struct bshell_variable_p *var)
|
||||
return &var->var_value;
|
||||
}
|
||||
|
||||
static void variable_set_value(struct bshell_variable_p *var, fx_value *value)
|
||||
static void variable_set_value(struct bshell_variable_p *var, fx_value value)
|
||||
{
|
||||
fx_value_unset(&var->var_value);
|
||||
fx_value_copy(&var->var_value, value);
|
||||
var->var_value = fx_value_copy_return(value);
|
||||
}
|
||||
|
||||
bshell_variable *bshell_variable_create(const char *name)
|
||||
@@ -70,7 +70,7 @@ const fx_value *bshell_variable_get_value(const bshell_variable *var)
|
||||
var);
|
||||
}
|
||||
|
||||
void bshell_variable_set_value(bshell_variable *var, fx_value *value)
|
||||
void bshell_variable_set_value(bshell_variable *var, fx_value value)
|
||||
{
|
||||
FX_CLASS_DISPATCH_STATIC_V(
|
||||
BSHELL_TYPE_VARIABLE,
|
||||
|
||||
@@ -18,21 +18,20 @@ struct bshell_scriptblock_p {
|
||||
fx_namemap b_strings;
|
||||
};
|
||||
|
||||
static fx_status pool_destroy(void *p)
|
||||
static void cache_entry_cleanup(fx_namemap_entry *e)
|
||||
{
|
||||
fx_value_unset(p);
|
||||
return FX_SUCCESS;
|
||||
struct string_cache_entry *entry
|
||||
= fx_unbox(struct string_cache_entry, e, e_entry);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static fx_vector_ops pool_ops = {
|
||||
.v_destroy = pool_destroy,
|
||||
};
|
||||
|
||||
static void scriptblock_fini(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_scriptblock_p *block = priv;
|
||||
|
||||
fx_vector_destroy(block->b_pool, &pool_ops);
|
||||
fx_namemap_cleanup(&block->b_strings, cache_entry_cleanup);
|
||||
fx_value_unset_array(block->b_pool.items, block->b_pool.count);
|
||||
fx_vector_destroy(block->b_pool, NULL);
|
||||
fx_vector_destroy(block->b_text, NULL);
|
||||
}
|
||||
|
||||
@@ -125,7 +124,7 @@ static unsigned long scriptblock_add_pool_value(
|
||||
fx_value *value)
|
||||
{
|
||||
unsigned long id = block->b_pool.count;
|
||||
fx_value *slot = fx_vector_emplace_back(block->b_pool, &pool_ops);
|
||||
fx_value *slot = fx_vector_emplace_back(block->b_pool, NULL);
|
||||
if (!slot) {
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
@@ -176,7 +175,7 @@ static unsigned long scriptblock_get_string(
|
||||
}
|
||||
|
||||
unsigned long index = block->b_pool.count;
|
||||
fx_value *slot = fx_vector_emplace_back(block->b_pool, &pool_ops);
|
||||
fx_value *slot = fx_vector_emplace_back(block->b_pool, NULL);
|
||||
if (!slot) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+34
-24
@@ -25,9 +25,8 @@ bshell_verb *bshell_verb_create(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bshell_verb_p *verb_p = fx_object_get_private(
|
||||
verb,
|
||||
BSHELL_TYPE_VERB);
|
||||
struct bshell_verb_p *verb_p
|
||||
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
|
||||
|
||||
verb_p->v_id = id;
|
||||
verb_p->v_name = name;
|
||||
@@ -75,9 +74,8 @@ static fx_status get_name(
|
||||
{
|
||||
bshell_verb *verb = NULL;
|
||||
fx_value_get_object(verb_v, &verb);
|
||||
struct bshell_verb_p *verb_p = fx_object_get_private(
|
||||
verb,
|
||||
BSHELL_TYPE_VERB);
|
||||
struct bshell_verb_p *verb_p
|
||||
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
|
||||
|
||||
*out = FX_CSTR(verb_p->v_name);
|
||||
return FX_SUCCESS;
|
||||
@@ -90,9 +88,8 @@ static fx_status get_alias_prefix(
|
||||
{
|
||||
bshell_verb *verb = NULL;
|
||||
fx_value_get_object(verb_v, &verb);
|
||||
struct bshell_verb_p *verb_p = fx_object_get_private(
|
||||
verb,
|
||||
BSHELL_TYPE_VERB);
|
||||
struct bshell_verb_p *verb_p
|
||||
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
|
||||
*out = FX_CSTR(verb_p->v_alias_prefix);
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
@@ -104,9 +101,8 @@ static fx_status get_group(
|
||||
{
|
||||
bshell_verb *verb = NULL;
|
||||
fx_value_get_object(verb_v, &verb);
|
||||
struct bshell_verb_p *verb_p = fx_object_get_private(
|
||||
verb,
|
||||
BSHELL_TYPE_VERB);
|
||||
struct bshell_verb_p *verb_p
|
||||
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
|
||||
*out = FX_CSTR(verb_p->v_group);
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
@@ -118,13 +114,17 @@ static fx_status get_description(
|
||||
{
|
||||
bshell_verb *verb = NULL;
|
||||
fx_value_get_object(verb_v, &verb);
|
||||
struct bshell_verb_p *verb_p = fx_object_get_private(
|
||||
verb,
|
||||
BSHELL_TYPE_VERB);
|
||||
struct bshell_verb_p *verb_p
|
||||
= fx_object_get_private(verb, BSHELL_TYPE_VERB);
|
||||
*out = FX_CSTR(verb_p->v_description);
|
||||
return FX_SUCCESS;
|
||||
}
|
||||
|
||||
static void verb_fini(fx_object *obj, void *priv)
|
||||
{
|
||||
struct bshell_verb_p *verb = priv;
|
||||
}
|
||||
|
||||
FX_TYPE_CLASS_BEGIN(bshell_verb)
|
||||
FX_TYPE_VTABLE_INTERFACE_BEGIN(fx_object, FX_TYPE_OBJECT)
|
||||
FX_INTERFACE_ENTRY(to_string) = NULL;
|
||||
@@ -143,6 +143,7 @@ FX_TYPE_DEFINITION_BEGIN(bshell_verb)
|
||||
FX_TYPE_NAME("bshell.verb");
|
||||
FX_TYPE_CLASS(bshell_verb_class);
|
||||
FX_TYPE_INSTANCE_PRIVATE(struct bshell_verb_p);
|
||||
FX_TYPE_INSTANCE_FINI(verb_fini);
|
||||
FX_TYPE_DEFINITION_END(bshell_verb)
|
||||
|
||||
static fx_hashtable *all_verbs_by_name = NULL;
|
||||
@@ -405,18 +406,18 @@ enum bshell_status bshell_init_all_verbs(void)
|
||||
"dc",
|
||||
"Communications",
|
||||
"Breaks the link between a source and a destination");
|
||||
PUT_VERB(
|
||||
READ,
|
||||
"Read",
|
||||
"rd",
|
||||
"Communications",
|
||||
"Acquires information from a source");
|
||||
PUT_VERB(
|
||||
RECEIVE,
|
||||
"Receive",
|
||||
"rc",
|
||||
"Communications",
|
||||
"Accepts information sent from a source");
|
||||
PUT_VERB(
|
||||
READ,
|
||||
"Read",
|
||||
"rd",
|
||||
"Communications",
|
||||
"Acquires information from a source");
|
||||
PUT_VERB(
|
||||
SEND,
|
||||
"Send",
|
||||
@@ -788,6 +789,16 @@ enum bshell_status bshell_init_all_verbs(void)
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
enum bshell_status bshell_cleanup_all_verbs(void)
|
||||
{
|
||||
for (size_t i = 0; i < __BSHELL_VERB_MAX; i++) {
|
||||
all_verbs_by_id[i] = NULL;
|
||||
}
|
||||
|
||||
fx_hashtable_unref(all_verbs_by_name);
|
||||
return BSHELL_SUCCESS;
|
||||
}
|
||||
|
||||
fx_hashtable *bshell_get_all_verbs(void)
|
||||
{
|
||||
return all_verbs_by_name;
|
||||
@@ -804,9 +815,8 @@ bshell_verb *bshell_verb_get_by_id(enum bshell_verb_id id)
|
||||
|
||||
bshell_verb *bshell_verb_get_by_name(const char *name)
|
||||
{
|
||||
const fx_value *val = fx_hashtable_get(
|
||||
all_verbs_by_name,
|
||||
&FX_CSTR(name));
|
||||
const fx_value *val
|
||||
= fx_hashtable_get(all_verbs_by_name, &FX_CSTR(name));
|
||||
if (!val) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user