145 lines
3.7 KiB
C
145 lines
3.7 KiB
C
#include "../command/cmdlet.h"
|
|
#include "../command/command.h"
|
|
#include "../format/format.h"
|
|
#include "../runtime/pipeline.h"
|
|
#include "../status.h"
|
|
|
|
#include <fx/collections/array.h>
|
|
#include <fx/reflection/function.h>
|
|
#include <fx/string.h>
|
|
#include <fx/value-type.h>
|
|
#include <fx/vector.h>
|
|
|
|
#define BSHELL_TYPE_WRITE_OUTPUT (bshell_write_output_get_type())
|
|
|
|
fx_type_id bshell_write_output_get_type(void);
|
|
|
|
FX_DECLARE_TYPE(bshell_write_output);
|
|
|
|
FX_TYPE_CLASS_DECLARATION_BEGIN(bshell_write_output)
|
|
FX_TYPE_CLASS_DECLARATION_END(bshell_write_output)
|
|
|
|
struct bshell_write_output_p {
|
|
struct table_format_ctx w_table_ctx;
|
|
bool w_table_initialised;
|
|
};
|
|
|
|
static void initialise_table(
|
|
struct bshell_write_output_p *cmd,
|
|
const fx_value *first_record)
|
|
{
|
|
table_format_ctx_init(&cmd->w_table_ctx, fx_stdout);
|
|
const fx_type *ty = fx_type_get_by_id(first_record->v_type);
|
|
table_format_ctx_prepare_columns_from_format(
|
|
&cmd->w_table_ctx,
|
|
ty,
|
|
NULL);
|
|
table_format_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);
|
|
}
|
|
|
|
table_format_ctx_print_record(&cmd->w_table_ctx, value);
|
|
}
|
|
|
|
static enum bshell_status begin_processing(bshell_cmdlet *cmdlet)
|
|
{
|
|
struct bshell_write_output_p *p = fx_object_get_private(
|
|
cmdlet,
|
|
BSHELL_TYPE_WRITE_OUTPUT);
|
|
for (size_t i = 1;; i++) {
|
|
const fx_value *v = bshell_command_get_arg(cmdlet, i);
|
|
if (!v) {
|
|
break;
|
|
}
|
|
|
|
write_value(p, v);
|
|
}
|
|
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static enum bshell_status process_record(
|
|
bshell_cmdlet *cmdlet,
|
|
bshell_pipeline *pipeline,
|
|
struct bshell_runtime *rt)
|
|
{
|
|
struct bshell_write_output_p *p = fx_object_get_private(
|
|
cmdlet,
|
|
BSHELL_TYPE_WRITE_OUTPUT);
|
|
|
|
fx_value in = bshell_pipeline_read_value(pipeline);
|
|
if (fx_value_is_set(&in)) {
|
|
write_value(p, &in);
|
|
fx_value_unset(&in);
|
|
}
|
|
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static enum bshell_status end_processing(bshell_cmdlet *cmdlet)
|
|
{
|
|
struct bshell_write_output_p *p = fx_object_get_private(
|
|
cmdlet,
|
|
BSHELL_TYPE_WRITE_OUTPUT);
|
|
|
|
return BSHELL_SUCCESS;
|
|
}
|
|
|
|
static void init(fx_object *obj, void *priv)
|
|
{
|
|
}
|
|
|
|
FX_TYPE_CLASS_BEGIN(bshell_write_output)
|
|
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_cmdlet, BSHELL_TYPE_CMDLET)
|
|
FX_INTERFACE_ENTRY(c_verb) = BSHELL_VERB_WRITE;
|
|
FX_INTERFACE_ENTRY(c_noun) = "Output";
|
|
FX_TYPE_VTABLE_INTERFACE_END(bshell_cmdlet, BSHELL_TYPE_CMDLET)
|
|
|
|
FX_TYPE_VTABLE_INTERFACE_BEGIN(bshell_command, BSHELL_TYPE_COMMAND)
|
|
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_cmdlet, BSHELL_TYPE_CMDLET)
|
|
FX_TYPE_CLASS_END(bshell_write_output)
|
|
|
|
FX_TYPE_DEFINITION_BEGIN(bshell_write_output)
|
|
FX_TYPE_ID(0xf7f9c42d, 0xc053, 0x4ffc, 0xa8ec, 0x78fef4844ac0);
|
|
FX_TYPE_NAME("bshell.core.write_output");
|
|
FX_TYPE_EXTENDS(BSHELL_TYPE_CMDLET);
|
|
FX_TYPE_CLASS(bshell_write_output_class);
|
|
FX_TYPE_INSTANCE_INIT(init);
|
|
FX_TYPE_INSTANCE_PRIVATE(struct bshell_write_output_p);
|
|
FX_TYPE_DEFINITION_END(bshell_write_output)
|