Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8ddb0b75f | |||
| 97a83addc8 | |||
| 8c926acd9d | |||
| fba7987d78 | |||
| 2332d48b0c | |||
| 73519eb7aa | |||
| 4c04ca6de8 | |||
| de5058e045 |
+1
-1
@@ -15,7 +15,7 @@ if (NOT DEFINED bshell_enable_floating_point)
|
|||||||
set(bshell_enable_floating_point 1)
|
set(bshell_enable_floating_point 1)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
set(required_fx_assemblies fx.runtime fx.collections)
|
set(required_fx_assemblies fx.runtime fx.collections fx.io fx.diagnostics)
|
||||||
|
|
||||||
if (bshell_interactive)
|
if (bshell_interactive)
|
||||||
set(required_fx_assemblies ${required_fx_assemblies} fx.term)
|
set(required_fx_assemblies ${required_fx_assemblies} fx.term)
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ struct bshell_foreach_object_p {
|
|||||||
bshell_scriptblock *f_block;
|
bshell_scriptblock *f_block;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
static enum bshell_status begin_processing(
|
||||||
|
bshell_cmdlet *cmdlet,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
struct bshell_foreach_object_p *p
|
struct bshell_foreach_object_p *p
|
||||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_FOREACH_OBJECT);
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_FOREACH_OBJECT);
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ struct bshell_get_command_p {
|
|||||||
bool c_eof;
|
bool c_eof;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
static enum bshell_status begin_processing(
|
||||||
|
bshell_cmdlet *cmdlet,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
struct bshell_get_command_p *p
|
struct bshell_get_command_p *p
|
||||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_COMMAND);
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_COMMAND);
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ struct bshell_get_verb_p {
|
|||||||
const fx_iterator *c_it;
|
const fx_iterator *c_it;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
static enum bshell_status begin_processing(
|
||||||
|
bshell_cmdlet *cmdlet,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
struct bshell_get_verb_p *p
|
struct bshell_get_verb_p *p
|
||||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_VERB);
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_GET_VERB);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include <bshell/command/cmdlet.h>
|
#include <bshell/command/cmdlet.h>
|
||||||
#include <bshell/command/command.h>
|
#include <bshell/command/command.h>
|
||||||
#include <bshell/format.h>
|
|
||||||
#include <bshell/runtime/pipeline.h>
|
#include <bshell/runtime/pipeline.h>
|
||||||
#include <bshell/status.h>
|
#include <bshell/status.h>
|
||||||
#include <fx/collections/array.h>
|
#include <fx/collections/array.h>
|
||||||
@@ -19,67 +18,18 @@ FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_write_output)
|
|||||||
FX_TYPE_CLASS_DECLARATION_END(bshell_write_output)
|
FX_TYPE_CLASS_DECLARATION_END(bshell_write_output)
|
||||||
|
|
||||||
struct bshell_write_output_p {
|
struct bshell_write_output_p {
|
||||||
struct bshell_table_ctx w_table_ctx;
|
size_t w_arg_count;
|
||||||
bool w_table_initialised;
|
size_t w_arg_index;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void initialise_table(
|
static enum bshell_status begin_processing(
|
||||||
struct bshell_write_output_p *cmd,
|
bshell_cmdlet *cmdlet,
|
||||||
const fx_value *first_record)
|
enum bshell_command_position position)
|
||||||
{
|
|
||||||
bshell_table_ctx_init(&cmd->w_table_ctx, fx_stdout);
|
|
||||||
const fx_type *ty = fx_type_get_by_id(first_record->v_type);
|
|
||||||
bshell_table_ctx_prepare_columns_from_format(
|
|
||||||
&cmd->w_table_ctx,
|
|
||||||
ty,
|
|
||||||
NULL);
|
|
||||||
bshell_table_ctx_print_headers(&cmd->w_table_ctx);
|
|
||||||
cmd->w_table_initialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool value_requires_table(const fx_value *value)
|
|
||||||
{
|
|
||||||
if (fx_type_is_value_type(value->v_type)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fx_value_is_type(value, FX_TYPE_STRING)
|
|
||||||
|| fx_value_is_type(value, FX_TYPE_ARRAY)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_value(
|
|
||||||
struct bshell_write_output_p *cmd,
|
|
||||||
const fx_value *value)
|
|
||||||
{
|
|
||||||
if (!value_requires_table(value)) {
|
|
||||||
fx_value_to_string(value, fx_stdout, NULL);
|
|
||||||
fx_stream_write_char(fx_stdout, '\n');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmd->w_table_initialised) {
|
|
||||||
initialise_table(cmd, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bshell_table_ctx_print_record(&cmd->w_table_ctx, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
|
||||||
{
|
{
|
||||||
struct bshell_write_output_p *p
|
struct bshell_write_output_p *p
|
||||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_WRITE_OUTPUT);
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_WRITE_OUTPUT);
|
||||||
for (size_t i = 1;; i++) {
|
p->w_arg_index = 1;
|
||||||
const fx_value *v = bshell_command_get_arg(cmdlet, i);
|
p->w_arg_count = bshell_command_get_arg_count(cmdlet);
|
||||||
if (!v) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_value(p, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BSHELL_SUCCESS;
|
return BSHELL_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -92,9 +42,16 @@ static enum bshell_status process_record(
|
|||||||
struct bshell_write_output_p *p
|
struct bshell_write_output_p *p
|
||||||
= fx_object_get_private(cmdlet, BSHELL_TYPE_WRITE_OUTPUT);
|
= fx_object_get_private(cmdlet, BSHELL_TYPE_WRITE_OUTPUT);
|
||||||
|
|
||||||
|
if (p->w_arg_index < p->w_arg_count) {
|
||||||
|
const fx_value *arg
|
||||||
|
= bshell_command_get_arg(cmdlet, p->w_arg_index++);
|
||||||
|
bshell_pipeline_write_value(pipeline, *arg, false);
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
fx_value in = bshell_pipeline_read_value(pipeline);
|
fx_value in = bshell_pipeline_read_value(pipeline);
|
||||||
if (fx_value_is_set(&in)) {
|
if (fx_value_is_set(&in)) {
|
||||||
write_value(p, &in);
|
bshell_pipeline_write_value(pipeline, in, false);
|
||||||
fx_value_unset(&in);
|
fx_value_unset(&in);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ endforeach (d)
|
|||||||
|
|
||||||
add_library(bshell.runtime SHARED ${sources})
|
add_library(bshell.runtime SHARED ${sources})
|
||||||
|
|
||||||
target_link_libraries(bshell.runtime FX::Runtime FX::Collections)
|
target_link_libraries(bshell.runtime FX::Runtime FX::Collections FX::Io FX::Diagnostics)
|
||||||
|
|
||||||
if (bshell_interactive)
|
if (bshell_interactive)
|
||||||
target_link_libraries(bshell.runtime FX::Term)
|
target_link_libraries(bshell.runtime FX::Term)
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ static enum bshell_status get_callable_name_static(
|
|||||||
const fx_type *ty,
|
const fx_type *ty,
|
||||||
fx_string *out)
|
fx_string *out)
|
||||||
{
|
{
|
||||||
bshell_cmdlet_class *class = fx_type_get_interface(
|
bshell_cmdlet_class *class
|
||||||
ty,
|
= fx_type_get_interface(ty, BSHELL_TYPE_CMDLET);
|
||||||
BSHELL_TYPE_CMDLET);
|
|
||||||
if (!class) {
|
if (!class) {
|
||||||
return BSHELL_ERR_NOT_SUPPORTED;
|
return BSHELL_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ static const fx_value *command_get_arg(
|
|||||||
return &cmd->cmd_args[index];
|
return &cmd->cmd_args[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t command_get_arg_count(struct bshell_command_p *cmd)
|
||||||
|
{
|
||||||
|
return cmd->cmd_nr_args;
|
||||||
|
}
|
||||||
|
|
||||||
static fx_status get_command_type(
|
static fx_status get_command_type(
|
||||||
const fx_value *cmd_v,
|
const fx_value *cmd_v,
|
||||||
const fx_property *prop,
|
const fx_property *prop,
|
||||||
@@ -236,14 +241,25 @@ const fx_value *bshell_command_get_arg(bshell_command *cmd, size_t index)
|
|||||||
index);
|
index);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum bshell_status bshell_command_begin_processing(bshell_command *command)
|
size_t bshell_command_get_arg_count(const bshell_command *cmd)
|
||||||
{
|
{
|
||||||
FX_CLASS_DISPATCH_VIRTUAL_0(
|
FX_CLASS_DISPATCH_STATIC_0(
|
||||||
|
BSHELL_TYPE_COMMAND,
|
||||||
|
command_get_arg_count,
|
||||||
|
cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum bshell_status bshell_command_begin_processing(
|
||||||
|
bshell_command *command,
|
||||||
|
enum bshell_command_position position)
|
||||||
|
{
|
||||||
|
FX_CLASS_DISPATCH_VIRTUAL(
|
||||||
bshell_command,
|
bshell_command,
|
||||||
BSHELL_TYPE_COMMAND,
|
BSHELL_TYPE_COMMAND,
|
||||||
BSHELL_ERR_NOT_SUPPORTED,
|
BSHELL_ERR_NOT_SUPPORTED,
|
||||||
c_begin_processing,
|
c_begin_processing,
|
||||||
command);
|
command,
|
||||||
|
position);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum bshell_status bshell_command_process_record(
|
enum bshell_status bshell_command_process_record(
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ static enum bshell_status get_callable_name(
|
|||||||
return BSHELL_SUCCESS;
|
return BSHELL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum bshell_status begin_processing(bshell_command *cmd)
|
static enum bshell_status begin_processing(
|
||||||
|
bshell_command *cmd,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
return BSHELL_SUCCESS;
|
return BSHELL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,232 @@
|
|||||||
|
#include <bshell/command/command.h>
|
||||||
|
#include <bshell/command/native-command.h>
|
||||||
|
#include <bshell/format.h>
|
||||||
|
#include <bshell/runtime/pipeline.h>
|
||||||
|
#include <bshell/status.h>
|
||||||
|
#include <fx/diagnostics/process.h>
|
||||||
|
#include <fx/reflection/function.h>
|
||||||
|
#include <fx/string.h>
|
||||||
|
#include <fx/vector.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
F_REDIRECT_STDIN = 0x01u,
|
||||||
|
F_REDIRECT_STDOUT = 0x02u,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bshell_native_command_p {
|
||||||
|
int cmd_flags;
|
||||||
|
fx_string *cmd_path;
|
||||||
|
fx_stringstream *cmd_tmp;
|
||||||
|
fx_process *cmd_proc;
|
||||||
|
struct bshell_value_writer cmd_writer;
|
||||||
|
bool cmd_writer_init;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void init(fx_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p = priv;
|
||||||
|
cmd_p->cmd_tmp = fx_stringstream_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fini(fx_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p = priv;
|
||||||
|
fx_stringstream_unref(cmd_p->cmd_tmp);
|
||||||
|
fx_string_unref(cmd_p->cmd_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum bshell_status start_process(bshell_native_command *cmd, int flags)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p
|
||||||
|
= fx_object_get_private(cmd, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
fx_stringstream *tmp = fx_stringstream_create();
|
||||||
|
size_t argc = bshell_command_get_arg_count(cmd);
|
||||||
|
char **argv = calloc(argc, sizeof *argv);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < argc; i++) {
|
||||||
|
const fx_value *arg = bshell_command_get_arg(cmd, i);
|
||||||
|
|
||||||
|
fx_stringstream_reset(tmp);
|
||||||
|
fx_value_to_string(arg, tmp, NULL);
|
||||||
|
argv[i] = fx_stringstream_steal(tmp);
|
||||||
|
}
|
||||||
|
fx_stringstream_unref(tmp);
|
||||||
|
|
||||||
|
fx_process *self = fx_process_get_self();
|
||||||
|
|
||||||
|
fx_process_start_info info = {
|
||||||
|
.proc_args = (const char **)argv,
|
||||||
|
.proc_args_count = argc,
|
||||||
|
.proc_file_name = fx_string_get_cstr(cmd_p->cmd_path),
|
||||||
|
.proc_environment = fx_process_get_environment(self),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (flags & F_REDIRECT_STDIN) {
|
||||||
|
info.proc_redirect_stdin = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & F_REDIRECT_STDOUT) {
|
||||||
|
info.proc_redirect_stdout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_p->cmd_flags = flags;
|
||||||
|
cmd_p->cmd_proc = fx_process_create(&info);
|
||||||
|
|
||||||
|
fx_status status = fx_process_start(cmd_p->cmd_proc);
|
||||||
|
for (size_t i = 0; i < argc; i++) {
|
||||||
|
free(argv[i]);
|
||||||
|
}
|
||||||
|
free(argv);
|
||||||
|
|
||||||
|
if (!FX_OK(status)) {
|
||||||
|
return BSHELL_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum bshell_status begin_processing(
|
||||||
|
bshell_command *cmd,
|
||||||
|
enum bshell_command_position position)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p
|
||||||
|
= fx_object_get_private(cmd, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
printf("begin processing '%s'\n", fx_string_get_cstr(cmd_p->cmd_path));
|
||||||
|
int flags = 0;
|
||||||
|
switch (position) {
|
||||||
|
case BSHELL_COMMAND_POSITION_BEGINNING:
|
||||||
|
flags = F_REDIRECT_STDOUT;
|
||||||
|
break;
|
||||||
|
case BSHELL_COMMAND_POSITION_MIDDLE:
|
||||||
|
flags = F_REDIRECT_STDIN | F_REDIRECT_STDOUT;
|
||||||
|
break;
|
||||||
|
case BSHELL_COMMAND_POSITION_END:
|
||||||
|
flags = F_REDIRECT_STDIN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return start_process(cmd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum bshell_status process_record(
|
||||||
|
bshell_command *cmd,
|
||||||
|
bshell_pipeline *pipeline,
|
||||||
|
struct bshell_runtime *rt)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p
|
||||||
|
= fx_object_get_private(cmd, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
printf("process record '%s'\n", fx_string_get_cstr(cmd_p->cmd_path));
|
||||||
|
|
||||||
|
if (cmd_p->cmd_flags & F_REDIRECT_STDIN) {
|
||||||
|
fx_value in = bshell_pipeline_read_value(pipeline);
|
||||||
|
if (!fx_value_is_set(&in)) {
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_stream *in_stream = fx_process_get_stdin(cmd_p->cmd_proc);
|
||||||
|
if (!cmd_p->cmd_writer_init) {
|
||||||
|
bshell_value_writer_init(&cmd_p->cmd_writer, in_stream);
|
||||||
|
cmd_p->cmd_writer_init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bshell_value_writer_write(&cmd_p->cmd_writer, &in);
|
||||||
|
fx_value_unset(&in);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_p->cmd_flags & F_REDIRECT_STDOUT) {
|
||||||
|
fx_stream *out_stream = fx_process_get_stdout(cmd_p->cmd_proc);
|
||||||
|
fx_stringstream_reset(cmd_p->cmd_tmp);
|
||||||
|
fx_status status
|
||||||
|
= fx_stream_read_line_s(out_stream, cmd_p->cmd_tmp);
|
||||||
|
if (!FX_OK(status)) {
|
||||||
|
/* no more data available */
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
fx_string *record = fx_string_create_from_cstr(
|
||||||
|
fx_stringstream_ptr(cmd_p->cmd_tmp));
|
||||||
|
bshell_pipeline_write_value(
|
||||||
|
pipeline,
|
||||||
|
FX_VALUE_OBJECT(record),
|
||||||
|
false);
|
||||||
|
fx_string_unref(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum bshell_status end_processing(bshell_command *cmd)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p
|
||||||
|
= fx_object_get_private(cmd, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
printf("end processing '%s'\n", fx_string_get_cstr(cmd_p->cmd_path));
|
||||||
|
if (cmd_p->cmd_writer_init) {
|
||||||
|
bshell_value_writer_cleanup(&cmd_p->cmd_writer);
|
||||||
|
cmd_p->cmd_writer_init = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_p->cmd_proc) {
|
||||||
|
fx_process_close_stdin(cmd_p->cmd_proc);
|
||||||
|
fx_process_close_stdout(cmd_p->cmd_proc);
|
||||||
|
fx_process_close_stderr(cmd_p->cmd_proc);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
fx_process_wait(cmd_p->cmd_proc, &result);
|
||||||
|
fx_process_unref(cmd_p->cmd_proc);
|
||||||
|
cmd_p->cmd_proc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum bshell_status get_callable_name(
|
||||||
|
const bshell_native_command *cmd,
|
||||||
|
fx_string *out)
|
||||||
|
{
|
||||||
|
struct bshell_native_command_p *cmd_p
|
||||||
|
= fx_object_get_private(cmd, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
fx_string_append_s(out, cmd_p->cmd_path);
|
||||||
|
return BSHELL_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bshell_native_command *bshell_native_command_create(const char *path)
|
||||||
|
{
|
||||||
|
bshell_native_command *out
|
||||||
|
= fx_object_create(BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
if (!out) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bshell_native_command_p *cmd
|
||||||
|
= fx_object_get_private(out, BSHELL_TYPE_NATIVE_COMMAND);
|
||||||
|
cmd->cmd_path = fx_string_create_from_cstr(path);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_BEGIN(bshell_native_command)
|
||||||
|
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) = "Native-Command";
|
||||||
|
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_native_command)
|
||||||
|
|
||||||
|
FX_TYPE_DEFINITION_BEGIN(bshell_native_command)
|
||||||
|
FX_TYPE_ID(0x720ede87, 0xe586, 0x495a, 0xa229, 0x1505c01b5714);
|
||||||
|
FX_TYPE_FLAGS(FX_TYPE_F_ABSTRACT);
|
||||||
|
FX_TYPE_NAME("bshell.runtime.native_command");
|
||||||
|
FX_TYPE_EXTENDS(BSHELL_TYPE_COMMAND);
|
||||||
|
FX_TYPE_CLASS(bshell_native_command_class);
|
||||||
|
FX_TYPE_INSTANCE_INIT(init);
|
||||||
|
FX_TYPE_INSTANCE_FINI(fini);
|
||||||
|
FX_TYPE_INSTANCE_PRIVATE(struct bshell_native_command_p);
|
||||||
|
FX_TYPE_DEFINITION_END(bshell_native_command)
|
||||||
@@ -6,7 +6,10 @@ enum bshell_status cmdcall_load(
|
|||||||
{
|
{
|
||||||
struct bshell_cmdcall_ast_node *cmdcall;
|
struct bshell_cmdcall_ast_node *cmdcall;
|
||||||
cmdcall = (struct bshell_cmdcall_ast_node *)value->v_node;
|
cmdcall = (struct bshell_cmdcall_ast_node *)value->v_node;
|
||||||
bshell_scriptblock_push_instruction(ctx->c_block, BSHELL_OPCODE_PEXEC, 1);
|
bshell_scriptblock_push_instruction(
|
||||||
|
ctx->c_block,
|
||||||
|
BSHELL_OPCODE_PEXEC,
|
||||||
|
1);
|
||||||
return BSHELL_SUCCESS;
|
return BSHELL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,17 +21,10 @@ static void format_value_fallback(const fx_value *value, fx_stream *dest)
|
|||||||
|
|
||||||
enum bshell_status format_value_default(const fx_value *value, fx_stream *dest)
|
enum bshell_status format_value_default(const fx_value *value, fx_stream *dest)
|
||||||
{
|
{
|
||||||
if (fx_type_is_value_type(value->v_type)) {
|
struct bshell_value_writer writer;
|
||||||
format_value_fallback(value, dest);
|
bshell_value_writer_init(&writer, dest);
|
||||||
return BSHELL_SUCCESS;
|
bshell_value_writer_write(&writer, value);
|
||||||
}
|
bshell_value_writer_cleanup(&writer);
|
||||||
|
|
||||||
fx_object *object = NULL;
|
|
||||||
fx_value_get_object(value, &object);
|
|
||||||
enum bshell_status status = format_object_table(object, dest);
|
|
||||||
if (status != BSHELL_SUCCESS) {
|
|
||||||
format_value_fallback(value, dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BSHELL_SUCCESS;
|
return BSHELL_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#include <bshell/format.h>
|
||||||
|
#include <fx/collections/array.h>
|
||||||
|
#include <fx/string.h>
|
||||||
|
#include <fx/type.h>
|
||||||
|
#include <fx/value-type.h>
|
||||||
|
|
||||||
|
static void initialise_table(
|
||||||
|
struct bshell_value_writer *w,
|
||||||
|
const fx_value *first_record)
|
||||||
|
{
|
||||||
|
bshell_table_ctx_init(&w->w_table_ctx, w->w_dest);
|
||||||
|
const fx_type *ty = fx_type_get_by_id(first_record->v_type);
|
||||||
|
bshell_table_ctx_prepare_columns_from_format(&w->w_table_ctx, ty, NULL);
|
||||||
|
bshell_table_ctx_print_headers(&w->w_table_ctx);
|
||||||
|
w->w_table_initialised = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_iterable(struct bshell_value_writer *w, const fx_value *value)
|
||||||
|
{
|
||||||
|
fx_array *array = NULL;
|
||||||
|
fx_value_get_object(value, &array);
|
||||||
|
|
||||||
|
const fx_iterator *it = fx_iterator_begin(array);
|
||||||
|
fx_foreach(v, it)
|
||||||
|
{
|
||||||
|
bshell_value_writer_write(w, v);
|
||||||
|
}
|
||||||
|
fx_iterator_unref(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_string(struct bshell_value_writer *w, const fx_value *value)
|
||||||
|
{
|
||||||
|
const char *str = NULL;
|
||||||
|
fx_value_get_cstr(value, &str);
|
||||||
|
fx_stream_write_cstr(w->w_dest, str, NULL);
|
||||||
|
fx_stream_write_char(w->w_dest, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_value(struct bshell_value_writer *w, const fx_value *value)
|
||||||
|
{
|
||||||
|
const fx_type *ty = fx_type_get_by_id(value->v_type);
|
||||||
|
if (fx_value_is_type(value, FX_TYPE_STRING)) {
|
||||||
|
write_string(w, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx_type_get_interface(ty, FX_TYPE_ITERABLE)) {
|
||||||
|
write_iterable(w, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx_type_is_value_type(value->v_type)) {
|
||||||
|
fx_value_to_string(value, w->w_dest, NULL);
|
||||||
|
fx_stream_write_char(w->w_dest, '\n');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!w->w_table_initialised) {
|
||||||
|
initialise_table(w, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bshell_table_ctx_print_record(&w->w_table_ctx, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bshell_value_writer_init(struct bshell_value_writer *w, fx_stream *dest)
|
||||||
|
{
|
||||||
|
memset(w, 0x00, sizeof *w);
|
||||||
|
w->w_dest = dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bshell_value_writer_write(
|
||||||
|
struct bshell_value_writer *w,
|
||||||
|
const fx_value *value)
|
||||||
|
{
|
||||||
|
write_value(w, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bshell_value_writer_cleanup(struct bshell_value_writer *w)
|
||||||
|
{
|
||||||
|
if (w->w_table_initialised) {
|
||||||
|
bshell_table_ctx_cleanup(&w->w_table_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
w->w_table_initialised = false;
|
||||||
|
}
|
||||||
@@ -8,6 +8,13 @@
|
|||||||
|
|
||||||
FX_DECLS_BEGIN;
|
FX_DECLS_BEGIN;
|
||||||
|
|
||||||
|
enum bshell_command_position {
|
||||||
|
BSHELL_COMMAND_POSITION_SINGLE = 0,
|
||||||
|
BSHELL_COMMAND_POSITION_BEGINNING,
|
||||||
|
BSHELL_COMMAND_POSITION_MIDDLE,
|
||||||
|
BSHELL_COMMAND_POSITION_END,
|
||||||
|
};
|
||||||
|
|
||||||
struct bshell_runtime;
|
struct bshell_runtime;
|
||||||
|
|
||||||
#define BSHELL_TYPE_COMMAND (bshell_command_get_type())
|
#define BSHELL_TYPE_COMMAND (bshell_command_get_type())
|
||||||
@@ -24,7 +31,9 @@ FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_command)
|
|||||||
*c_get_description)(const bshell_command *, fx_string *);
|
*c_get_description)(const bshell_command *, fx_string *);
|
||||||
enum bshell_status (
|
enum bshell_status (
|
||||||
*c_get_description_static)(const fx_type *, fx_string *);
|
*c_get_description_static)(const fx_type *, fx_string *);
|
||||||
enum bshell_status (*c_begin_processing)(bshell_command *);
|
enum bshell_status (*c_begin_processing)(
|
||||||
|
bshell_command *,
|
||||||
|
enum bshell_command_position);
|
||||||
enum bshell_status (*c_process_record)(
|
enum bshell_status (*c_process_record)(
|
||||||
bshell_command *,
|
bshell_command *,
|
||||||
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
||||||
@@ -47,9 +56,11 @@ extern void bshell_command_set_args_reverse(
|
|||||||
extern const fx_value *bshell_command_get_arg(
|
extern const fx_value *bshell_command_get_arg(
|
||||||
bshell_command *cmd,
|
bshell_command *cmd,
|
||||||
size_t index);
|
size_t index);
|
||||||
|
extern size_t bshell_command_get_arg_count(const bshell_command *cmd);
|
||||||
|
|
||||||
extern enum bshell_status bshell_command_begin_processing(
|
extern enum bshell_status bshell_command_begin_processing(
|
||||||
bshell_command *command);
|
bshell_command *command,
|
||||||
|
enum bshell_command_position position);
|
||||||
extern enum bshell_status bshell_command_process_record(
|
extern enum bshell_status bshell_command_process_record(
|
||||||
bshell_command *command,
|
bshell_command *command,
|
||||||
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef BSHELL_COMMAND_NATIVE_COMMAND_H_
|
||||||
|
#define BSHELL_COMMAND_NATIVE_COMMAND_H_
|
||||||
|
|
||||||
|
#include <fx/macros.h>
|
||||||
|
|
||||||
|
FX_DECLS_BEGIN;
|
||||||
|
|
||||||
|
struct bshell_runtime;
|
||||||
|
|
||||||
|
#define BSHELL_TYPE_NATIVE_COMMAND (bshell_native_command_get_type())
|
||||||
|
|
||||||
|
FX_DECLARE_TYPE(bshell_native_command);
|
||||||
|
|
||||||
|
FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_native_command)
|
||||||
|
FX_TYPE_CLASS_DECLARATION_END(bshell_native_command)
|
||||||
|
|
||||||
|
extern fx_type_id bshell_native_command_get_type(void);
|
||||||
|
|
||||||
|
extern bshell_native_command *bshell_native_command_create(const char *path);
|
||||||
|
|
||||||
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -47,6 +47,12 @@ struct bshell_table_ctx {
|
|||||||
fx_stream *ctx_out;
|
fx_stream *ctx_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct bshell_value_writer {
|
||||||
|
struct bshell_table_ctx w_table_ctx;
|
||||||
|
bool w_table_initialised;
|
||||||
|
fx_stream *w_dest;
|
||||||
|
};
|
||||||
|
|
||||||
extern enum bshell_status bshell_table_init(void);
|
extern enum bshell_status bshell_table_init(void);
|
||||||
extern const struct bshell_table *bshell_table_get_for_type(const fx_type *ty);
|
extern const struct bshell_table *bshell_table_get_for_type(const fx_type *ty);
|
||||||
extern enum bshell_status format_object_table(
|
extern enum bshell_status format_object_table(
|
||||||
@@ -74,4 +80,12 @@ extern enum bshell_status bshell_table_ctx_print_record(
|
|||||||
struct bshell_table_ctx *ctx,
|
struct bshell_table_ctx *ctx,
|
||||||
const fx_value *record);
|
const fx_value *record);
|
||||||
|
|
||||||
|
extern void bshell_value_writer_init(
|
||||||
|
struct bshell_value_writer *w,
|
||||||
|
fx_stream *dest);
|
||||||
|
extern void bshell_value_writer_write(
|
||||||
|
struct bshell_value_writer *w,
|
||||||
|
const fx_value *value);
|
||||||
|
extern void bshell_value_writer_cleanup(struct bshell_value_writer *w);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ FX_DECLS_BEGIN;
|
|||||||
|
|
||||||
struct bshell_runtime;
|
struct bshell_runtime;
|
||||||
|
|
||||||
|
enum bshell_command_position;
|
||||||
|
|
||||||
|
enum bshell_cmdcall_type {
|
||||||
|
BSHELL_CMDCALL_NONE = 0,
|
||||||
|
BSHELL_CMDCALL_CMDLET,
|
||||||
|
BSHELL_CMDCALL_NATIVE,
|
||||||
|
};
|
||||||
|
|
||||||
#define BSHELL_TYPE_CMDCALL (bshell_cmdcall_get_type())
|
#define BSHELL_TYPE_CMDCALL (bshell_cmdcall_get_type())
|
||||||
|
|
||||||
FX_DECLARE_TYPE(bshell_cmdcall);
|
FX_DECLARE_TYPE(bshell_cmdcall);
|
||||||
@@ -19,6 +27,9 @@ extern fx_type_id bshell_cmdcall_get_type(void);
|
|||||||
|
|
||||||
FX_TYPE_DEFAULT_CONSTRUCTOR(bshell_cmdcall, BSHELL_TYPE_CMDCALL);
|
FX_TYPE_DEFAULT_CONSTRUCTOR(bshell_cmdcall, BSHELL_TYPE_CMDCALL);
|
||||||
|
|
||||||
|
extern enum bshell_cmdcall_type bshell_cmdcall_get_target_type(
|
||||||
|
const bshell_cmdcall *cmdcall);
|
||||||
|
|
||||||
extern enum bshell_status bshell_cmdcall_push_arg(
|
extern enum bshell_status bshell_cmdcall_push_arg(
|
||||||
bshell_cmdcall *cmdcall,
|
bshell_cmdcall *cmdcall,
|
||||||
fx_value arg);
|
fx_value arg);
|
||||||
@@ -29,7 +40,8 @@ extern enum bshell_status bshell_cmdcall_resolve(
|
|||||||
extern enum bshell_status bshell_cmdcall_process_record(
|
extern enum bshell_status bshell_cmdcall_process_record(
|
||||||
bshell_cmdcall *cmdcall,
|
bshell_cmdcall *cmdcall,
|
||||||
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
FX_TYPE_FWDREF(bshell_pipeline) * pipeline,
|
||||||
struct bshell_runtime *rt);
|
struct bshell_runtime *rt,
|
||||||
|
enum bshell_command_position position);
|
||||||
|
|
||||||
FX_DECLS_END;
|
FX_DECLS_END;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <bshell/command/command.h>
|
#include <bshell/command/command.h>
|
||||||
#include <bshell/command/function.h>
|
#include <bshell/command/function.h>
|
||||||
|
#include <bshell/format.h>
|
||||||
#include <bshell/runtime/script-block.h>
|
#include <bshell/runtime/script-block.h>
|
||||||
#include <bshell/runtime/var.h>
|
#include <bshell/runtime/var.h>
|
||||||
#include <fx/collections/hashtable.h>
|
#include <fx/collections/hashtable.h>
|
||||||
@@ -15,6 +16,7 @@ struct bshell_runtime {
|
|||||||
struct bshell_runtime_scope *rt_global;
|
struct bshell_runtime_scope *rt_global;
|
||||||
fx_hashtable *rt_aliases;
|
fx_hashtable *rt_aliases;
|
||||||
fx_queue rt_scope;
|
fx_queue rt_scope;
|
||||||
|
struct bshell_value_writer rt_writer;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct bshell_runtime *bshell_runtime_create(void);
|
extern struct bshell_runtime *bshell_runtime_create(void);
|
||||||
@@ -53,4 +55,10 @@ extern struct bshell_runtime_scope *bshell_runtime_get_parent_scope(
|
|||||||
struct bshell_runtime *rt,
|
struct bshell_runtime *rt,
|
||||||
struct bshell_runtime_scope *scope);
|
struct bshell_runtime_scope *scope);
|
||||||
|
|
||||||
|
extern void bshell_runtime_begin_output(struct bshell_runtime *rt);
|
||||||
|
extern void bshell_runtime_output_value(
|
||||||
|
struct bshell_runtime *rt,
|
||||||
|
const fx_value *value);
|
||||||
|
extern void bshell_runtime_end_output(struct bshell_runtime *rt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#include <bshell/command/alias.h>
|
#include <bshell/command/alias.h>
|
||||||
#include <bshell/command/command.h>
|
#include <bshell/command/command.h>
|
||||||
|
#include <bshell/command/native-command.h>
|
||||||
#include <bshell/runtime/cmdcall.h>
|
#include <bshell/runtime/cmdcall.h>
|
||||||
#include <bshell/runtime/pipeline.h>
|
#include <bshell/runtime/pipeline.h>
|
||||||
#include <bshell/runtime/runtime.h>
|
#include <bshell/runtime/runtime.h>
|
||||||
#include <bshell/status.h>
|
#include <bshell/status.h>
|
||||||
#include <fx/collections/array.h>
|
#include <fx/collections/array.h>
|
||||||
|
#include <fx/collections/hashtable.h>
|
||||||
|
#include <fx/diagnostics/process.h>
|
||||||
|
#include <fx/io/path.h>
|
||||||
#include <fx/reflection/assembly.h>
|
#include <fx/reflection/assembly.h>
|
||||||
#include <fx/reflection/function.h>
|
#include <fx/reflection/function.h>
|
||||||
#include <fx/reflection/type.h>
|
#include <fx/reflection/type.h>
|
||||||
@@ -195,14 +199,15 @@ static enum bshell_status cmdcall_execute(struct bshell_cmdcall_p *cmdcall)
|
|||||||
static enum bshell_status cmdcall_process_record(
|
static enum bshell_status cmdcall_process_record(
|
||||||
struct bshell_cmdcall_p *cmdcall,
|
struct bshell_cmdcall_p *cmdcall,
|
||||||
bshell_pipeline *pipeline,
|
bshell_pipeline *pipeline,
|
||||||
struct bshell_runtime *rt)
|
struct bshell_runtime *rt,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
if (!cmdcall->cmd_target) {
|
if (!cmdcall->cmd_target) {
|
||||||
return BSHELL_ERR_NOT_SUPPORTED;
|
return BSHELL_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cmdcall->cmd_initialised) {
|
if (!cmdcall->cmd_initialised) {
|
||||||
bshell_command_begin_processing(cmdcall->cmd_target);
|
bshell_command_begin_processing(cmdcall->cmd_target, position);
|
||||||
cmdcall->cmd_initialised = true;
|
cmdcall->cmd_initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,25 +236,19 @@ enum bshell_status bshell_cmdcall_resolve(
|
|||||||
rt);
|
rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum bshell_status bshell_cmdcall_execute(bshell_cmdcall *cmdcall)
|
|
||||||
{
|
|
||||||
FX_CLASS_DISPATCH_STATIC_0(
|
|
||||||
BSHELL_TYPE_CMDCALL,
|
|
||||||
cmdcall_execute,
|
|
||||||
cmdcall);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum bshell_status bshell_cmdcall_process_record(
|
enum bshell_status bshell_cmdcall_process_record(
|
||||||
bshell_cmdcall *cmdcall,
|
bshell_cmdcall *cmdcall,
|
||||||
bshell_pipeline *pipeline,
|
bshell_pipeline *pipeline,
|
||||||
struct bshell_runtime *rt)
|
struct bshell_runtime *rt,
|
||||||
|
enum bshell_command_position position)
|
||||||
{
|
{
|
||||||
FX_CLASS_DISPATCH_STATIC(
|
FX_CLASS_DISPATCH_STATIC(
|
||||||
BSHELL_TYPE_CMDCALL,
|
BSHELL_TYPE_CMDCALL,
|
||||||
cmdcall_process_record,
|
cmdcall_process_record,
|
||||||
cmdcall,
|
cmdcall,
|
||||||
pipeline,
|
pipeline,
|
||||||
rt);
|
rt,
|
||||||
|
position);
|
||||||
}
|
}
|
||||||
|
|
||||||
FX_TYPE_CLASS_BEGIN(bshell_cmdcall)
|
FX_TYPE_CLASS_BEGIN(bshell_cmdcall)
|
||||||
|
|||||||
@@ -353,10 +353,8 @@ static enum bshell_status eval_instruction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int end_of_data = 0;
|
int end_of_data = 0;
|
||||||
bool columns_initialised = false;
|
|
||||||
fx_value record = FX_VALUE_EMPTY;
|
fx_value record = FX_VALUE_EMPTY;
|
||||||
struct bshell_table_ctx table_ctx;
|
bshell_runtime_begin_output(rt);
|
||||||
bshell_table_ctx_init(&table_ctx, fx_stdout);
|
|
||||||
while (1) {
|
while (1) {
|
||||||
bstatus = bshell_pipeline_pump_record(
|
bstatus = bshell_pipeline_pump_record(
|
||||||
pipeline,
|
pipeline,
|
||||||
@@ -371,22 +369,11 @@ static enum bshell_status eval_instruction(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!columns_initialised) {
|
bshell_runtime_output_value(rt, &record);
|
||||||
const fx_type *ty
|
|
||||||
= fx_type_get_by_id(record.v_type);
|
|
||||||
bshell_table_ctx_prepare_columns_from_format(
|
|
||||||
&table_ctx,
|
|
||||||
ty,
|
|
||||||
NULL);
|
|
||||||
bshell_table_ctx_print_headers(&table_ctx);
|
|
||||||
columns_initialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bshell_table_ctx_print_record(&table_ctx, &record);
|
|
||||||
fx_value_unset(&record);
|
fx_value_unset(&record);
|
||||||
}
|
}
|
||||||
|
|
||||||
bshell_table_ctx_cleanup(&table_ctx);
|
bshell_runtime_end_output(rt);
|
||||||
bshell_pipeline_unref(pipeline);
|
bshell_pipeline_unref(pipeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#include <bshell/runtime/runtime.h>
|
||||||
|
#include <fx/type.h>
|
||||||
|
#include <fx/value-type.h>
|
||||||
|
|
||||||
|
void bshell_runtime_begin_output(struct bshell_runtime *rt)
|
||||||
|
{
|
||||||
|
bshell_value_writer_init(&rt->rt_writer, fx_stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bshell_runtime_output_value(
|
||||||
|
struct bshell_runtime *rt,
|
||||||
|
const fx_value *value)
|
||||||
|
{
|
||||||
|
bshell_value_writer_write(&rt->rt_writer, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bshell_runtime_end_output(struct bshell_runtime *rt)
|
||||||
|
{
|
||||||
|
bshell_value_writer_cleanup(&rt->rt_writer);
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <fx/vector.h>
|
#include <fx/vector.h>
|
||||||
|
|
||||||
struct bshell_pipeline_p {
|
struct bshell_pipeline_p {
|
||||||
|
bool p_input_values_provided;
|
||||||
bshell_pipeline *p_self;
|
bshell_pipeline *p_self;
|
||||||
fx_array *p_in, *p_out;
|
fx_array *p_in, *p_out;
|
||||||
FX_VECTOR_DECLARE(bshell_cmdcall *, p_cmds);
|
FX_VECTOR_DECLARE(bshell_cmdcall *, p_cmds);
|
||||||
@@ -72,6 +73,7 @@ static enum bshell_status pipeline_add_input_value(
|
|||||||
fx_value value,
|
fx_value value,
|
||||||
bool enumerate)
|
bool enumerate)
|
||||||
{
|
{
|
||||||
|
pipeline->p_input_values_provided = true;
|
||||||
return write_value(pipeline, pipeline->p_in, value, enumerate);
|
return write_value(pipeline, pipeline->p_in, value, enumerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,10 +120,26 @@ static enum bshell_status pipeline_pump_record(
|
|||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (i = 0; i < pipeline->p_cmds.count;) {
|
for (i = 0; i < pipeline->p_cmds.count;) {
|
||||||
|
enum bshell_command_position position;
|
||||||
|
if (pipeline->p_cmds.count == 1) {
|
||||||
|
position = pipeline->p_input_values_provided
|
||||||
|
? BSHELL_COMMAND_POSITION_END
|
||||||
|
: BSHELL_COMMAND_POSITION_SINGLE;
|
||||||
|
} else if (i == 0) {
|
||||||
|
position = pipeline->p_input_values_provided
|
||||||
|
? BSHELL_COMMAND_POSITION_END
|
||||||
|
: BSHELL_COMMAND_POSITION_BEGINNING;
|
||||||
|
} else if (i == pipeline->p_cmds.count - 1) {
|
||||||
|
position = BSHELL_COMMAND_POSITION_END;
|
||||||
|
} else {
|
||||||
|
position = BSHELL_COMMAND_POSITION_MIDDLE;
|
||||||
|
}
|
||||||
|
|
||||||
status = bshell_cmdcall_process_record(
|
status = bshell_cmdcall_process_record(
|
||||||
pipeline->p_cmds.items[i],
|
pipeline->p_cmds.items[i],
|
||||||
pipeline->p_self,
|
pipeline->p_self,
|
||||||
rt);
|
rt,
|
||||||
|
position);
|
||||||
|
|
||||||
if (status != BSHELL_SUCCESS) {
|
if (status != BSHELL_SUCCESS) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user