#include <ucw/table.h>
#include <time.h>
#include <stdio.h>
+#include <stdlib.h>
void table_col_size_name(struct table *tbl, const char *col_name, u64 val)
{
};
// FIXME: do some rounding?
- val = val / unit_div[tbl->column_order[col].output_type];
+ uint out_type = 0;
+ if(tbl->column_order[col].output_type == CELL_OUT_UNINITIALIZED) {
+ val = val / unit_div[UNIT_BYTE];
+ out_type = 0;
+ } else {
+ val = val / unit_div[tbl->column_order[col].output_type];
+ out_type = tbl->column_order[col].output_type;
+ }
- //tbl->col_str_ptrs[col] = mp_printf(tbl->pool, "%lu%s", val, unit_suffix[tbl->column_order[col].output_type]);
- table_col_printf(tbl, col, "%lu%s", val, unit_suffix[tbl->column_order[col].output_type]);
+ table_col_printf(tbl, col, "%lu%s", val, unit_suffix[out_type]);
}
#define FORMAT_TIME_SIZE 20 // Minimum buffer size
{
ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);
ASSERT(tbl->columns[col].type == COL_TYPE_ANY || COL_TYPE_TIMESTAMP == tbl->columns[col].type);
- //ASSERT(fmt != NULL);
- char formatted_time_buf[FORMAT_TIME_SIZE];
+ char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
time_t tmp_time = (time_t)val;
struct tm t = *gmtime(&tmp_time);
switch (tbl->column_order[col].output_type) {
case TIMESTAMP_EPOCH:
- sprintf(formatted_time_buf, "%u", (uint) val);
+ case CELL_OUT_UNINITIALIZED:
+ sprintf(formatted_time_buf, "%lu", val);
break;
case TIMESTAMP_DATETIME:
strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
+ break;
default:
+ abort();
break;
}
- //tbl->col_str_ptrs[col] = mp_printf(tbl->pool, "%s", formatted_time_buf);
table_col_printf(tbl, col, "%s", formatted_time_buf);
}
int col_idx = col_order[i];
tbl->column_order[i].idx = col_idx;
tbl->column_order[i].cell_content = NULL;
+ tbl->column_order[i].output_type = CELL_OUT_UNINITIALIZED;
}
table_update_ll(tbl);
}
{
int curr_col = tbl->columns[col].first_column;
while(curr_col != -1) {
- if(override == 0 && tbl->column_order[curr_col].output_type != 0) {
+ if(override == 0 && tbl->column_order[curr_col].output_type != CELL_OUT_UNINITIALIZED ) {
+ fprintf(stdout, "curr_col: %d\n", curr_col);
+ fflush(stdout);
die("Error while setting content of all cells of a single type column, cell format should not be overriden.");
}
tbl->column_order[curr_col].cell_content = col_content;
table_col_##_name_(tbl, col, val);\
}
-#define TABLE_COL_FMT(_name_, _type_, _typeconst_) void table_col_##_name_##_fmt(struct table *tbl, int col, const char *fmt, _type_ val UNUSED)\
+#define TABLE_COL_FMT(_name_, _type_, _typeconst_) void table_col_##_name_##_fmt(struct table *tbl, int col, const char *fmt, _type_ val)\
{\
ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);\
ASSERT(tbl->columns[col].type == COL_TYPE_ANY || _typeconst_ == tbl->columns[col].type);\
TABLE_COL_BODIES(int, int, COL_TYPE_INT)
TABLE_COL_BODIES(uint, uint, COL_TYPE_UINT)
-TABLE_COL_BODIES(double, double, COL_TYPE_DOUBLE)
TABLE_COL_BODIES(str, const char *, COL_TYPE_STR)
TABLE_COL_BODIES(intmax, intmax_t, COL_TYPE_INTMAX)
TABLE_COL_BODIES(uintmax, uintmax_t, COL_TYPE_UINTMAX)
TABLE_COL_BODIES(s64, s64, COL_TYPE_S64)
TABLE_COL_BODIES(u64, u64, COL_TYPE_U64)
+
+// column type double is a special case
+TABLE_COL(double, double, COL_TYPE_DOUBLE);
+TABLE_COL_STR(double, double, COL_TYPE_DOUBLE);
#undef TABLE_COL
#undef TABLE_COL_FMT
#undef TABLE_COL_STR
#undef TABLE_COL_BODIES
+void table_col_double_fmt(struct table *tbl, int col, const char *fmt, double val)
+{
+ ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);
+ ASSERT(tbl->columns[col].type == COL_TYPE_ANY || COL_TYPE_DOUBLE == tbl->columns[col].type);
+ ASSERT(fmt != NULL);
+ tbl->last_printed_col = col;
+ tbl->row_printing_started = 1;
+ char *cell_content = mp_printf(tbl->pool, fmt, val);
+ int curr_col = tbl->columns[col].first_column;
+ while(curr_col != -1) {
+ if(tbl->column_order[curr_col].output_type < 0) tbl->column_order[curr_col].cell_content = cell_content;
+ else {
+ char *cell_content_tmp = mp_printf(tbl->pool, "%.*lf", tbl->column_order[curr_col].output_type, val);
+ tbl->column_order[curr_col].cell_content = cell_content_tmp;
+ }
+ curr_col = tbl->column_order[curr_col].next_column;
+ }
+}
+
void table_col_bool(struct table *tbl, int col, uint val)
{
table_col_bool_fmt(tbl, col, tbl->columns[col].fmt, val);
while(curr_col != -1) {
switch(tbl->column_order[curr_col].output_type) {
case CELL_OUT_HUMAN_READABLE:
+ case CELL_OUT_UNINITIALIZED:
tbl->column_order[curr_col].cell_content = mp_printf(tbl->pool, fmt, val ? "true" : "false");
break;
case CELL_OUT_MACHINE_READABLE:
#define CELL_FLAG_MASK (CELL_ALIGN_LEFT)
#define CELL_WIDTH_MASK (~CELL_FLAG_MASK)
+#define CELL_OUT_UNINITIALIZED -1
#define CELL_OUT_HUMAN_READABLE 0
#define CELL_OUT_MACHINE_READABLE 1
#define TBL_COLUMNS .columns = (struct table_column [])
#define TBL_COL_ORDER(order) .column_order = (struct table_col_info *) order, .cols_to_output = ARRAY_SIZE(order)
#define TBL_COL_DELIMITER(_delimiter_) .col_delimiter = _delimiter_
-#define TBL_COL(_idx) { .idx = _idx, .output_type = 0, .next_column = -1 }
-#define TBL_COL_FMT(_idx, _fmt) { .idx = _idx, .output_type = 0, .next_column = -1, .fmt = _fmt }
+#define TBL_COL(_idx) { .idx = _idx, .output_type = -1, .next_column = -1 }
+#define TBL_COL_FMT(_idx, _fmt) { .idx = _idx, .output_type = -1, .next_column = -1, .fmt = _fmt }
#define TBL_COL_TYPE(_idx, _type) { .idx = _idx, .output_type = _type, .next_column = -1 }
#define TBL_OUTPUT_HUMAN_READABLE .formatter = &table_fmt_human_readable