]> mj.ucw.cz Git - libucw.git/commitdiff
tableprinter: added parsing of column arg; bugfixes
authorRobert Kessl <kesslr@centrum.cz>
Tue, 1 Jul 2014 14:58:20 +0000 (16:58 +0200)
committerRobert Kessl <kesslr@centrum.cz>
Tue, 1 Jul 2014 14:58:20 +0000 (16:58 +0200)
- added parsing of column args. Now it is possible to specify column
  using the following format: <col-name>['['<arg>']']
- 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.

ucw/table-types.c
ucw/table-types.h
ucw/table.c
ucw/table.h

index 902e2829b75c057165e0e019eb6771b5ac27d259..c5aa96fa357e07d14a6c97e0bb9f0b0d27e09099 100644 (file)
@@ -8,6 +8,51 @@
 #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);
@@ -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;
+  }
 }
 
index 763d2098b2f408c994bfae4aefcacb1e1cd498d4..5b264e11ced5f70f5bca32966f08f7393951b412 100644 (file)
@@ -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)
 
index 34590de62af9626781cff79e33e42ec2a463e5c2..823f7e75b17bce36b2462d30bacee9d17e0c7191 100644 (file)
@@ -9,6 +9,7 @@
 #include <ucw/stkstring.h>
 #include <ucw/gary.h>
 #include <ucw/table.h>
+#include <ucw/strtonum.h>
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -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;
     }
   }
index 1e79c587c28792f644b9e45d5799d9f20128e63c..afdd0beff8b5a19ab2daa878d743538e75bbc60b 100644 (file)
@@ -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[];
 };