#include #include #include #include #include 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 bool string_has_trailing_newline(const char *s) { long len = strlen(s); if (len == 0) { return false; } return s[len - 1] == '\n'; } 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); if (!string_has_trailing_newline(str)) { 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; }