2 #include <ucw/config.h>
3 #include <ucw/table-types.h>
4 #include <ucw/fastbuf.h>
5 #include <ucw/config.h>
11 static const char *unit_suffix[] = {
13 [UNIT_KILOBYTE] = "KB",
14 [UNIT_MEGABYTE] = "MB",
15 [UNIT_GIGABYTE] = "GB",
16 [UNIT_TERABYTE] = "TB"
19 static bool table_set_col_opt_size(struct table *tbl, uint col_copy_idx, const char *col_arg, char **err)
21 int col_type_idx = tbl->column_order[col_copy_idx].idx;
22 if(tbl->columns[col_type_idx].type != COL_TYPE_SIZE) {
32 if(strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
33 tbl->column_order[col_copy_idx].output_type = UNIT_BYTE;
36 tbl->column_order[col_copy_idx].output_type = CELL_OUT_UNINITIALIZED;
37 for(uint i = 0; i < ARRAY_SIZE(unit_suffix); i++) {
38 if(strcasecmp(col_arg, unit_suffix[i]) == 0) {
39 tbl->column_order[col_copy_idx].output_type = i;
43 if(tbl->column_order[col_copy_idx].output_type == CELL_OUT_UNINITIALIZED) {
44 *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d (counted from 0)", col_arg, col_copy_idx);
52 struct table_user_type table_type_size = {
53 .set_col_instance_option = table_set_col_opt_size,
54 .type = COL_TYPE_SIZE,
57 static bool table_set_col_opt_timestamp(struct table *tbl, uint col_copy_idx, const char *col_arg, char **err)
59 int col_type_idx = tbl->column_order[col_copy_idx].idx;
60 if(tbl->columns[col_type_idx].type != COL_TYPE_TIMESTAMP) {
70 if(strcasecmp(col_arg, "timestamp") == 0 || strcasecmp(col_arg, "epoch") == 0) {
71 tbl->column_order[col_copy_idx].output_type = TIMESTAMP_EPOCH;
72 } else if(strcasecmp(col_arg, "datetime") == 0) {
73 tbl->column_order[col_copy_idx].output_type = TIMESTAMP_DATETIME;
75 *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d.", col_arg, col_copy_idx);
83 struct table_user_type table_type_timestamp = {
84 .set_col_instance_option = table_set_col_opt_timestamp,
85 .type = COL_TYPE_TIMESTAMP,
88 void table_col_size_name(struct table *tbl, const char *col_name, u64 val)
90 int col = table_get_col_idx(tbl, col_name);
91 table_col_size(tbl, col, val);
94 void table_col_size(struct table *tbl, int col, u64 val)
96 ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);
97 ASSERT(tbl->columns[col].type == COL_TYPE_ANY || COL_TYPE_SIZE == tbl->columns[col].type);
99 tbl->last_printed_col = col;
100 tbl->row_printing_started = 1;
102 static u64 unit_div[] = {
103 [UNIT_BYTE] = (u64) 1,
104 [UNIT_KILOBYTE] = (u64) 1024LLU,
105 [UNIT_MEGABYTE] = (u64) (1024LLU * 1024LLU),
106 [UNIT_GIGABYTE] = (u64) (1024LLU * 1024LLU * 1024LLU),
107 [UNIT_TERABYTE] = (u64) (1024LLU * 1024LLU * 1024LLU * 1024LLU)
110 TBL_COL_ITER(tbl, col, curr_col, curr_col_idx) {
111 // FIXME: do some rounding?
113 if(curr_col->output_type == CELL_OUT_UNINITIALIZED) {
114 val = val / unit_div[UNIT_BYTE];
117 val = val / unit_div[curr_col->output_type];
118 out_type = curr_col->output_type;
121 curr_col->cell_content = mp_printf(tbl->pool, "%lu%s", val, unit_suffix[out_type]);
125 #define FORMAT_TIME_SIZE 20 // Minimum buffer size
127 void table_col_timestamp_name(struct table *tbl, const char * col_name, u64 val)
129 int col = table_get_col_idx(tbl, col_name);
130 table_col_size(tbl, col, val);
133 void table_col_timestamp(struct table *tbl, int col, u64 val)
135 ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);
136 ASSERT(tbl->columns[col].type == COL_TYPE_ANY || COL_TYPE_TIMESTAMP == tbl->columns[col].type);
138 char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
140 time_t tmp_time = (time_t)val;
141 struct tm t = *gmtime(&tmp_time);
142 TBL_COL_ITER(tbl, col, curr_col, curr_col_idx) {
143 switch (curr_col->output_type) {
144 case TIMESTAMP_EPOCH:
145 case CELL_OUT_UNINITIALIZED:
146 sprintf(formatted_time_buf, "%lu", val);
148 case TIMESTAMP_DATETIME:
149 strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
156 curr_col->cell_content = mp_printf(tbl->pool, "%s", formatted_time_buf);