From: Robert Kessl Date: Tue, 1 Jul 2014 14:58:20 +0000 (+0200) Subject: tableprinter: added parsing of column arg; bugfixes X-Git-Tag: v6.1~3^2~130 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=7a9e8666e80ddf97a9e24738f3d89cf0cd4c2724;p=libucw.git tableprinter: added parsing of column arg; bugfixes - added parsing of column args. Now it is possible to specify column using the following format: ['['']'] - fix of printing of timestamp and size: single value was set for all instances of a column. Now each column instance has value in its format. --- diff --git a/ucw/table-types.c b/ucw/table-types.c index 902e2829..c5aa96fa 100644 --- a/ucw/table-types.c +++ b/ucw/table-types.c @@ -8,6 +8,51 @@ #include #include +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); @@ -38,17 +83,23 @@ void table_col_size(struct table *tbl, int col, u64 val) [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 @@ -69,19 +120,24 @@ void table_col_timestamp(struct table *tbl, int col, u64 val) 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; + } } diff --git a/ucw/table-types.h b/ucw/table-types.h index 763d2098..5b264e11 100644 --- a/ucw/table-types.h +++ b/ucw/table-types.h @@ -54,6 +54,8 @@ void table_col_timestamp_name(struct table *tbl, const char * col_name, u64 val) 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) diff --git a/ucw/table.c b/ucw/table.c index 34590de6..823f7e75 100644 --- a/ucw/table.c +++ b/ucw/table.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -72,7 +73,7 @@ void table_start(struct table *tbl, struct fastbuf *out) 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); @@ -168,6 +169,37 @@ bool table_col_is_printed(struct table *tbl, uint col_idx) 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. @@ -199,25 +231,50 @@ const char * table_set_col_order_by_name(struct table *tbl, const char *col_orde } } - 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; } @@ -448,7 +505,7 @@ const char *table_set_option_value(struct table *tbl, const char *key, const cha // 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; } } diff --git a/ucw/table.h b/ucw/table.h index 1e79c587..afdd0bef 100644 --- a/ucw/table.h +++ b/ucw/table.h @@ -307,6 +307,12 @@ void table_reset_row(struct table *tbl); **/ 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. @@ -390,6 +396,8 @@ struct table_formatter { 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[]; };