#include <stdio.h>
#include <stdlib.h>
+bool table_set_col_opt_ucw_types(struct table *tbl, int col_copy_idx, const char *col_arg, char **err)
+{
+ fprintf(stdout, "col_copy_idx: %d, col_arg: %s\n", col_copy_idx, col_arg);
+ fflush(stdout);
+
+ int col_type_idx = tbl->column_order[col_copy_idx].idx;
+ if(tbl->columns[col_type_idx].type == COL_TYPE_SIZE) {
+ if(strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
+ tbl->column_order[col_copy_idx].output_type = UNIT_BYTE;
+ } else if(strcasecmp(col_arg, "kb") == 0) {
+ tbl->column_order[col_copy_idx].output_type = UNIT_KILOBYTE;
+ } else if(strcasecmp(col_arg, "mb") == 0) {
+ tbl->column_order[col_copy_idx].output_type = UNIT_MEGABYTE;
+ } else if(strcasecmp(col_arg, "gb") == 0) {
+ tbl->column_order[col_copy_idx].output_type = UNIT_GIGABYTE;
+ } else if(strcasecmp(col_arg, "tb") == 0) {
+ tbl->column_order[col_copy_idx].output_type = UNIT_TERABYTE;
+ } else {
+ *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d.", col_arg, col_copy_idx);
+ return true;
+ }
+ *err = NULL;
+ return true;
+ }
+
+ if(tbl->columns[col_type_idx].type == COL_TYPE_TIMESTAMP) {
+ fprintf(stdout, "setting timestamp format, col_arg: '%s'\n", col_arg);
+ fflush(stdout);
+ if(strcasecmp(col_arg, "timestamp") == 0 || strcasecmp(col_arg, "epoch") == 0) {
+ tbl->column_order[col_copy_idx].output_type = TIMESTAMP_EPOCH;
+ } else if(strcasecmp(col_arg, "datetime") == 0) {
+ tbl->column_order[col_copy_idx].output_type = TIMESTAMP_DATETIME;
+ } else {
+ *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d.", col_arg, col_copy_idx);
+ return true;
+ }
+ *err = NULL;
+ return true;
+ }
+
+ *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d.", col_arg, col_copy_idx);
+ return false;
+}
+
+
void table_col_size_name(struct table *tbl, const char *col_name, u64 val)
{
int col = table_get_col_idx(tbl, col_name);
[UNIT_TERABYTE] = "TB"
};
- // FIXME: do some rounding?
- 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;
+ int curr_col = tbl->columns[col].first_column;
+ while(curr_col != -1) {
+
+ // FIXME: do some rounding?
+ uint out_type = 0;
+ if(tbl->column_order[curr_col].output_type == CELL_OUT_UNINITIALIZED) {
+ val = val / unit_div[UNIT_BYTE];
+ out_type = 0;
+ } else {
+ val = val / unit_div[tbl->column_order[curr_col].output_type];
+ out_type = tbl->column_order[curr_col].output_type;
+ }
+
+ tbl->column_order[curr_col].cell_content = mp_printf(tbl->pool, "%lu%s", val, unit_suffix[out_type]);
+ curr_col = tbl->column_order[curr_col].next_column;
}
- table_col_printf(tbl, col, "%lu%s", val, unit_suffix[out_type]);
}
#define FORMAT_TIME_SIZE 20 // Minimum buffer size
time_t tmp_time = (time_t)val;
struct tm t = *gmtime(&tmp_time);
- switch (tbl->column_order[col].output_type) {
- case TIMESTAMP_EPOCH:
- case CELL_OUT_UNINITIALIZED:
- sprintf(formatted_time_buf, "%lu", val);
- break;
- case TIMESTAMP_DATETIME:
- strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
+ int curr_col = tbl->columns[col].first_column;
+ while(curr_col != -1) {
+ switch (tbl->column_order[curr_col].output_type) {
+ case TIMESTAMP_EPOCH:
+ 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;
- }
+ default:
+ abort();
+ break;
+ }
- table_col_printf(tbl, col, "%s", formatted_time_buf);
+ //table_col_printf(tbl, col, "%s", formatted_time_buf);
+ tbl->column_order[curr_col].cell_content = mp_printf(tbl->pool, "%s", formatted_time_buf);
+ curr_col = tbl->column_order[curr_col].next_column;
+ }
}
void table_col_size(struct table *tbl, int col, u64 val);
void table_col_timestamp(struct table *tbl, int col, u64 val);
+bool table_set_col_opt_ucw_types(struct table *tbl, int col_copy_idx, const char *col_arg, char **err);
+
//TABLE_COL(size, u64, COL_TYPE_SIZE)
//TABLE_COL_STR(size, u64, COL_TYPE_SIZE)
#include <ucw/stkstring.h>
#include <ucw/gary.h>
#include <ucw/table.h>
+#include <ucw/strtonum.h>
#include <stdlib.h>
#include <stdio.h>
if(tbl->column_order == NULL) table_make_default_column_order(tbl);
else {
- // update linked lists in case that the lists were initialized in static parts
+ // update linked lists
table_update_ll(tbl);
}
if(tbl->formatter->table_start != NULL) tbl->formatter->table_start(tbl);
return 1;
}
+static char * table_parse_col_arg(char *col_def)
+{
+ // FIXME: should be switched to str_sepsplit
+ char * left_br = strchr(col_def, '[');
+ if(left_br == NULL) return NULL;
+ *left_br = 0;
+ left_br++;
+ char *right_br = strchr(left_br, ']');
+ *right_br = 0;
+ //*left_br = 0;
+ return left_br;
+}
+
+/**
+ *
+ **/
+bool table_set_col_opt_default(struct table *tbl, int col_copy_idx, const char *col_arg, char **err)
+{
+ int col_type_idx = tbl->column_order[col_copy_idx].idx;
+
+ if(tbl->columns[col_type_idx].type == COL_TYPE_DOUBLE) {
+ uint precision = 0;
+ str_to_uint(&precision, col_arg, NULL, 0);
+ tbl->column_order[col_type_idx].output_type = precision;
+ return true;
+ }
+
+ *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d.", col_arg, col_copy_idx);
+ return false;
+}
+
/**
* TODO: This function deliberately leaks memory. When it is called multiple times,
* previous column orders still remain allocated in the table's memory pool.
}
}
- int *col_order_int = alloca(sizeof(int) * col_count);
- int curr_col_order_int = 0;
- const char *name_start = tmp_col_order;
+ tbl->cols_to_output = col_count;
+ tbl->column_order = mp_alloc_zero(tbl->pool, sizeof(struct table_col_info) * col_count);
+
+ //int *col_order_int = alloca(sizeof(int) * col_count);
+ int curr_col_idx = 0;
+ char *name_start = tmp_col_order;
+ //int curr_col_instance = 0;
while(name_start) {
char *next = strchr(name_start, ',');
if(next) {
*next++ = 0;
}
- int idx = table_get_col_idx(tbl, name_start);
- if(idx == -1) {
+ char *arg = table_parse_col_arg(name_start); // this sets 0 on the '['
+ int col_idx = table_get_col_idx(tbl, name_start);
+ if(col_idx == -1) {
return mp_printf(tbl->pool, "Unknown table column '%s'", name_start);
}
- col_order_int[curr_col_order_int++] = idx;
+ tbl->column_order[curr_col_idx].idx = col_idx;
+ tbl->column_order[curr_col_idx].cell_content = NULL;
+ tbl->column_order[curr_col_idx].output_type = CELL_OUT_UNINITIALIZED;
+ fprintf(stdout, "formatter: %p, set_col_instance_option: %p\n", tbl->formatter, tbl->formatter->set_col_instance_option);
+ if(tbl->formatter && tbl->formatter->set_col_instance_option) {
+ char *err = NULL;
+ fprintf(stdout, "calling: %p\n", tbl->formatter->set_col_instance_option);
+ tbl->formatter->set_col_instance_option(tbl, curr_col_idx, arg, &err);
+ if(err) return err;
+ }
name_start = next;
- }
+ curr_col_idx++;
+ }
+
+ //table_set_col_order(tbl, col_order_int, curr_col_order_int);
+ //tbl->cols_to_output = cols_to_output;
+ //tbl->column_order = mp_alloc_zero(tbl->pool, sizeof(struct table_col_info) * cols_to_output);
+ //for(int i = 0; i < cols_to_output; i++) {
+ //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);
- table_set_col_order(tbl, col_order_int, curr_col_order_int);
return NULL;
}
// Formatter options
if(tbl->formatter && tbl->formatter->process_option) {
const char *err = NULL;
- if (tbl->formatter->process_option(tbl, key, value, &err)) {
+ if(tbl->formatter->process_option(tbl, key, value, &err)) {
return err;
}
}
**/
int table_get_col_idx(struct table *tbl, const char *col_name);
+
+/**
+ * Sets a string argument to a column realization
+ **/
+bool table_set_col_opt_default(struct table *tbl, int col_copy_idx, const char *col_arg, char ** err);
+
/**
* Returns a comma-and-space-separated list of column names, allocated from table's internal
* memory pool.
void (*table_end)(struct table *tbl); // [*] table_end callback (optional)
bool (*process_option)(struct table *tbl, const char *key, const char *value, const char **err);
// [*] Process table option and possibly return an error message (optional)
+ bool (*set_col_instance_option)(struct table *tbl, uint col, const char *value, char **err);
+ // [*] process table option for a column instance
const char *formats[];
};