#include #include #include #include #include #include #include #include #include #include #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 bshell_table_ctx w_table_ctx; bool w_table_initialised; }; static void initialise_table( struct bshell_write_output_p *cmd, const fx_value *first_record) { 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 = 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)