]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/table-types.c
tableprinter: update of iterator macro; bugfix in table_set_col_opt_size
[libucw.git] / ucw / table-types.c
index a4be42d2dc61c1009a95867557a79288c180b9a9..ab2e5b696ab9f0542b72924f1d4159379d0f7cff 100644 (file)
@@ -6,9 +6,89 @@
 #include <ucw/table.h>
 #include <time.h>
 #include <stdio.h>
+#include <stdlib.h>
 
-void table_col_name(struct table *tbl, const char *col_name, u64 val)
+static const char *unit_suffix[] = {
+  [UNIT_BYTE] = "",
+  [UNIT_KILOBYTE] = "KB",
+  [UNIT_MEGABYTE] = "MB",
+  [UNIT_GIGABYTE] = "GB",
+  [UNIT_TERABYTE] = "TB"
+};
+
+static bool table_set_col_opt_size(struct table *tbl, uint 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_SIZE) {
+    *err = NULL;
+    return false;
+  }
+
+  if(col_arg == NULL) {
+    *err = NULL;
+    return true;
+  }
+
+  if(strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
+    tbl->column_order[col_copy_idx].output_type = UNIT_BYTE;
+  }
+
+  tbl->column_order[col_copy_idx].output_type = CELL_OUT_UNINITIALIZED;
+  for(uint i = 0; i < ARRAY_SIZE(unit_suffix); i++) {
+    if(strcasecmp(col_arg, unit_suffix[i]) == 0) {
+      tbl->column_order[col_copy_idx].output_type = i;
+    }
+  }
+
+  if(tbl->column_order[col_copy_idx].output_type == CELL_OUT_UNINITIALIZED) {
+    *err = mp_printf(tbl->pool, "Tableprinter: invalid column format option: '%s' for column %d (counted from 0)", col_arg, col_copy_idx);
+    return true;
+  }
+
+  *err = NULL;
+  return true;
+}
+
+struct table_user_type table_type_size = {
+  .set_col_instance_option = table_set_col_opt_size,
+  .type = COL_TYPE_SIZE,
+};
+
+static bool table_set_col_opt_timestamp(struct table *tbl, uint 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_TIMESTAMP) {
+    *err = NULL;
+    return false;
+  }
+
+  if(col_arg == NULL) {
+    *err = NULL;
+    return true;
+  }
+
+  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;
+}
+
+struct table_user_type table_type_timestamp = {
+  .set_col_instance_option = table_set_col_opt_timestamp,
+  .type = COL_TYPE_TIMESTAMP,
+};
+
+void table_col_size_name(struct table *tbl, const char *col_name, u64 val)
 {
+  int col = table_get_col_idx(tbl, col_name);
+  table_col_size(tbl, col, val);
 }
 
 void table_col_size(struct table *tbl, int col, u64 val)
@@ -21,49 +101,58 @@ void table_col_size(struct table *tbl, int col, u64 val)
 
   static u64 unit_div[] = {
     [UNIT_BYTE] = (u64) 1,
-    [UNIT_KILOBYTE] = (u64) 1024LU,
-    [UNIT_MEGABYTE] = (u64) (1024LU * 1024LU),
-    [UNIT_GIGABYTE] = (u64) (1024LU * 1024LU * 1024LU),
-    [UNIT_TERABYTE] = (u64) (1024LU * 1024LU * 1024LU * 1024LU)
-  };
-
-  static const char *unit_suffix[] = {
-    [UNIT_BYTE] = "",
-    [UNIT_KILOBYTE] = "KB",
-    [UNIT_MEGABYTE] = "MB",
-    [UNIT_GIGABYTE] = "GB",
-    [UNIT_TERABYTE] = "TB"
+    [UNIT_KILOBYTE] = (u64) 1024LLU,
+    [UNIT_MEGABYTE] = (u64) (1024LLU * 1024LLU),
+    [UNIT_GIGABYTE] = (u64) (1024LLU * 1024LLU * 1024LLU),
+    [UNIT_TERABYTE] = (u64) (1024LLU * 1024LLU * 1024LLU * 1024LLU)
   };
 
-  // FIXME: do some rounding?
-  val = val / unit_div[tbl->column_order[col].output_type];
+  TBL_COL_ITER(tbl, col, curr_col, curr_col_idx) {
+    // FIXME: do some rounding?
+    uint out_type = 0;
+    if(curr_col->output_type == CELL_OUT_UNINITIALIZED) {
+      val = val / unit_div[UNIT_BYTE];
+      out_type = 0;
+    } else {
+      val = val / unit_div[curr_col->output_type];
+      out_type = curr_col->output_type;
+    }
 
-  tbl->col_str_ptrs[col] = mp_printf(tbl->pool, "%lu%s", val, unit_suffix[tbl->column_order[col].output_type]);
+    curr_col->cell_content = mp_printf(tbl->pool, "%lu%s", val, unit_suffix[out_type]);
+  }
 }
 
 #define FORMAT_TIME_SIZE 20    // Minimum buffer size
 
+void table_col_timestamp_name(struct table *tbl, const char * col_name, u64 val)
+{
+  int col = table_get_col_idx(tbl, col_name);
+  table_col_size(tbl, col, val);
+}
+
 void table_col_timestamp(struct table *tbl, int col, u64 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_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);
+  TBL_COL_ITER(tbl, col, curr_col, curr_col_idx) {
+    switch (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;
-  case TIMESTAMP_DATETIME:
-    strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
-  default:
-    break;
-  }
+    default:
+      abort();
+      break;
+    }
 
-  tbl->col_str_ptrs[col] = mp_printf(tbl->pool, "%s", formatted_time_buf);
+    curr_col->cell_content = mp_printf(tbl->pool, "%s", formatted_time_buf);
+  }
 }
-