]> mj.ucw.cz Git - libucw.git/commitdiff
xtype&tableprinter: first shot on incorporating xtypes to tableprinter
authorRobert Kessl <kesslr@centrum.cz>
Mon, 14 Jul 2014 08:14:43 +0000 (10:14 +0200)
committerRobert Kessl <kesslr@centrum.cz>
Mon, 14 Jul 2014 08:14:43 +0000 (10:14 +0200)
ucw/table-test-2.c
ucw/table-types.c
ucw/table-types.h
ucw/table.c
ucw/table.h
ucw/xtypes-basic.c
ucw/xtypes.h

index 8b58dfa96a5cbe269ede8e02fe7840bf3db4f6d1..b31295d1e208968bcab3f5fef3fcc47387e5692a 100644 (file)
@@ -16,7 +16,7 @@ enum test_table_cols {
 
 static struct table_template test_tbl = {
   TBL_COLUMNS {
-    [TEST_COL0_SIZE] = TBL_COL_SIZE_FMT("size", 15, UNIT_SIZE_BYTE),
+    [TEST_COL0_SIZE] = TBL_COL_SIZE_FMT("size", 15, SIZE_UNITS_FIXED | UNIT_SIZE_BYTE),
     [TEST_COL1_TS] = TBL_COL_TIMESTAMP("ts", 20),
     TBL_COL_END
   },
@@ -37,24 +37,24 @@ static void do_test(void)
   table_col_timestamp(tbl, TEST_COL1_TS, test_time);
   table_end_row(tbl);
 
-  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNIT_KILOBYTE;
+  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNITS_FIXED | SIZE_UNIT_KILOBYTE;
   table_col_size(tbl, TEST_COL0_SIZE, test_size);
   table_col_timestamp(tbl, TEST_COL1_TS, test_time);
   table_end_row(tbl);
 
-  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNIT_MEGABYTE;
+  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNITS_FIXED | SIZE_UNIT_MEGABYTE;
   table_col_size(tbl, TEST_COL0_SIZE, test_size);
   table_col_timestamp(tbl, TEST_COL1_TS, test_time);
   table_end_row(tbl);
 
-  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNIT_GIGABYTE;
+  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNITS_FIXED | SIZE_UNIT_GIGABYTE;
   tbl->column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME;
   table_col_size(tbl, TEST_COL0_SIZE, test_size);
   table_col_timestamp(tbl, TEST_COL1_TS, test_time);
   table_end_row(tbl);
 
   test_size = test_size * 1024LU;
-  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNIT_TERABYTE;
+  tbl->column_order[TEST_COL0_SIZE].output_type = SIZE_UNITS_FIXED | SIZE_UNIT_TERABYTE;
   tbl->column_order[TEST_COL1_TS].output_type = TIMESTAMP_DATETIME;
   table_col_size(tbl, TEST_COL0_SIZE, test_size);
   table_col_timestamp(tbl, TEST_COL1_TS, test_time);
@@ -68,7 +68,7 @@ static void do_test(void)
 
 static struct table_template test_tbl2 = {
   TBL_COLUMNS {
-    [TEST_COL0_SIZE] = TBL_COL_SIZE_FMT("size", 15, SIZE_UNIT_BYTE),
+    [TEST_COL0_SIZE] = TBL_COL_SIZE_FMT("size", 15, SIZE_UNITS_FIXED | SIZE_UNIT_BYTE),
     [TEST_COL1_TS] = TBL_COL_TIMESTAMP("ts", 20),
     TBL_COL_END
   },
index 992ee2080eec9b998461e0137bf711661c0dd064..fc8f6ed811a00e671fc3fb2aee344e238e795953 100644 (file)
@@ -6,6 +6,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+const struct xtype xt_size;
+const struct xtype xt_timestamp;
+
 static const char *unit_suffix[] = {
   [SIZE_UNIT_BYTE] = "",
   [SIZE_UNIT_KILOBYTE] = "KB",
@@ -14,28 +17,28 @@ static const char *unit_suffix[] = {
   [SIZE_UNIT_TERABYTE] = "TB"
 };
 
-static bool table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
+bool table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
 {
   struct table_column *col_def = tbl->column_order[col_inst_idx].col_def;
-  if(col_def->type != COL_TYPE_SIZE) {
+  if(col_def->type_def != COL_TYPE_SIZE) {
     *err = NULL;
     return false;
   }
 
   if(col_arg == NULL || strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
-    tbl->column_order[col_inst_idx].output_type = SIZE_UNIT_BYTE;
+    tbl->column_order[col_inst_idx].output_type = SIZE_UNIT_BYTE | SIZE_UNITS_FIXED;
     *err = NULL;
     return true;
   }
 
-  tbl->column_order[col_inst_idx].output_type = CELL_OUT_UNINITIALIZED;
+  tbl->column_order[col_inst_idx].output_type = XTYPE_FMT_DEFAULT; // CELL_OUT_UNINITIALIZED;
   for(uint i = SIZE_UNIT_BYTE; i <= SIZE_UNIT_TERABYTE; i++) {
     if(strcasecmp(col_arg, unit_suffix[i]) == 0) {
-      tbl->column_order[col_inst_idx].output_type = i;
+      tbl->column_order[col_inst_idx].output_type = i | SIZE_UNITS_FIXED;
     }
   }
 
-  if(tbl->column_order[col_inst_idx].output_type == CELL_OUT_UNINITIALIZED) {
+  if(tbl->column_order[col_inst_idx].output_type == XTYPE_FMT_DEFAULT) {
     *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d (counted from 0)", col_arg, col_inst_idx);
     return true;
   }
@@ -44,15 +47,10 @@ static bool table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const c
   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_inst_idx, const char *col_arg, char **err)
+bool table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
 {
   int col_type_idx = tbl->column_order[col_inst_idx].idx;
-  if(tbl->columns[col_type_idx].type != COL_TYPE_TIMESTAMP) {
+  if(tbl->columns[col_type_idx].type_def != COL_TYPE_TIMESTAMP) {
     *err = NULL;
     return false;
   }
@@ -75,11 +73,6 @@ static bool table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, co
   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);
@@ -89,7 +82,7 @@ void table_col_size_name(struct table *tbl, const char *col_name, u64 val)
 void table_col_size(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_SIZE == tbl->columns[col].type);
+  ASSERT(tbl->columns[col].type_def == COL_TYPE_ANY || COL_TYPE_SIZE == tbl->columns[col].type_def);
 
   tbl->last_printed_col = col;
   tbl->row_printing_started = 1;
@@ -107,12 +100,16 @@ void table_col_size(struct table *tbl, int col, u64 val)
     // FIXME: do some rounding? Or maybe use double and floating-point printing?
     uint out_type = 0;
     u64 curr_val = val;
-    if(curr_col->output_type == CELL_OUT_UNINITIALIZED) {
+
+    if(curr_col->output_type == XTYPE_FMT_DEFAULT || curr_col->output_type == XTYPE_FMT_RAW) {
       curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
       out_type = SIZE_UNIT_BYTE;
-    } else {
-      curr_val = curr_val / unit_div[curr_col->output_type];
-      out_type = curr_col->output_type;
+    } else if(curr_col->output_type == XTYPE_FMT_PRETTY) {
+      curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
+      out_type = SIZE_UNIT_BYTE; // curr_col->output_type;
+    } else if((curr_col->output_type & SIZE_UNITS_FIXED) != 0) {
+      curr_val = curr_val / unit_div[curr_col->output_type & ~SIZE_UNITS_FIXED];
+      out_type = curr_col->output_type & ~SIZE_UNITS_FIXED;
     }
 
     curr_col->cell_content = mp_printf(tbl->pool, "%lu%s", curr_val, unit_suffix[out_type]);
@@ -130,7 +127,7 @@ void table_col_timestamp_name(struct table *tbl, const char * col_name, u64 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(tbl->columns[col].type_def == COL_TYPE_ANY || COL_TYPE_TIMESTAMP == tbl->columns[col].type_def);
 
   char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
 
@@ -138,11 +135,11 @@ void table_col_timestamp(struct table *tbl, int col, u64 val)
   struct tm t = *gmtime(&tmp_time);
   TBL_COL_ITER_START(tbl, col, curr_col, curr_col_idx) {
     switch (curr_col->output_type) {
-    case TIMESTAMP_EPOCH:
-    case CELL_OUT_UNINITIALIZED:
+    case XTYPE_FMT_DEFAULT:
+    case XTYPE_FMT_RAW:
       sprintf(formatted_time_buf, "%lu", val);
       break;
-    case TIMESTAMP_DATETIME:
+    case XTYPE_FMT_PRETTY:
       strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
     break;
     default:
index e6b542a9aaeef21ddfc1c74dad83ddea607e87cc..8ca14f6ee29465439d0332267ed124d9613c302f 100644 (file)
@@ -10,7 +10,7 @@
 #include <ucw/table.h>
 
 enum size_units {
-  SIZE_UNIT_BYTE = CELL_OUT_USER_DEF_START,
+  SIZE_UNIT_BYTE,
   SIZE_UNIT_KILOBYTE,
   SIZE_UNIT_MEGABYTE,
   SIZE_UNIT_GIGABYTE,
@@ -18,22 +18,25 @@ enum size_units {
   SIZE_UNIT_AUTO
 };
 
-enum timestamp_format {
-  TIMESTAMP_EPOCH,
-  TIMESTAMP_DATETIME
-};
+#define COL_TYPE_SIZE       &xt_size
+#define COL_TYPE_TIMESTAMP  &xt_timestamp
+
+#define TIMESTAMP_EPOCH     XTYPE_FMT_RAW
+#define TIMESTAMP_DATETIME  XTYPE_FMT_PRETTY
+
+#define SIZE_UNITS_FIXED    0x40000000
 
-#define COL_TYPE_SIZE       COL_TYPE_UCW
-#define COL_TYPE_TIMESTAMP  (COL_TYPE_UCW+1)
+extern const struct xtype xt_size;
+extern const struct xtype xt_timestamp;
 
-extern struct table_user_type table_type_timestamp;
-extern struct table_user_type table_type_size;
+bool table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err);
+bool table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err);
 
-#define TBL_COL_SIZE(_name, _width)           { .name = _name, .width = _width, .fmt = "%llu", .type = COL_TYPE_SIZE, .type_def = &table_type_size }
-#define TBL_COL_TIMESTAMP(_name, _width)      { .name = _name, .width = _width, .fmt = "%lld", .type = COL_TYPE_TIMESTAMP, .type_def = &table_type_timestamp }
+#define TBL_COL_SIZE(_name, _width)           { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_SIZE, .set_col_instance_option = table_set_col_opt_size }
+#define TBL_COL_TIMESTAMP(_name, _width)      { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_TIMESTAMP, .set_col_instance_option = table_set_col_opt_timestamp }
 
-#define TBL_COL_SIZE_FMT(_name, _width, _units)         { .name = _name, .width = _width, .fmt = "%llu", .type = COL_TYPE_SIZE, .type_def = &table_type_size }
-#define TBL_COL_TIMESTAMP_FMT(_name, _width, _fmt)      { .name = _name, .width = _width, .fmt = "%lld", .type = COL_TYPE_TIMESTAMP, .type_def = &table_type_timestamp }
+#define TBL_COL_SIZE_FMT(_name, _width, _units)         { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_SIZE, .set_col_instance_option = table_set_col_opt_size }
+#define TBL_COL_TIMESTAMP_FMT(_name, _width, _fmt)      { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_TIMESTAMP, .set_col_instance_option = table_set_col_opt_timestamp }
 
 void table_col_size_name(struct table *tbl, const char *col_name, u64 val);
 void table_col_timestamp_name(struct table *tbl, const char * col_name, u64 val);
index 0fc8b57289a42abbe649f77e2d3af687b62365cb..c5d59a5830feba5ce775664861361d3c904f2342 100644 (file)
@@ -22,7 +22,8 @@ static void table_update_ll(struct table *tbl);
 
 static struct table *table_make_instance(const struct table_template *tbl_template)
 {
-  struct table *new_inst = xmalloc_zero(sizeof(struct table)); // FIXME: update allocation to the weird schema made by pchar and mj?
+  struct mempool *pool = mp_new(4096);
+  struct table *new_inst = mp_alloc_zero(pool, sizeof(struct table)); // FIXME: update allocation to the weird schema made by pchar and mj?
 
   new_inst->pool = mp_new(4096);
 
@@ -30,12 +31,10 @@ static struct table *table_make_instance(const struct table_template *tbl_templa
   int col_count = 0; // count the number of columns in the struct table
   for(;;) {
     if(tbl_template->columns[col_count].name == NULL &&
-       tbl_template->columns[col_count].fmt == NULL &&
        tbl_template->columns[col_count].width == 0 &&
-       tbl_template->columns[col_count].type == COL_TYPE_LAST)
+       tbl_template->columns[col_count].type_def == COL_TYPE_ANY)
       break;
     ASSERT(tbl_template->columns[col_count].name != NULL);
-    ASSERT(tbl_template->columns[col_count].type == COL_TYPE_ANY || tbl_template->columns[col_count].fmt != NULL);
     ASSERT(tbl_template->columns[col_count].width != 0);
 
     col_count++;
@@ -51,8 +50,7 @@ static struct table *table_make_instance(const struct table_template *tbl_templa
     memcpy(new_inst->column_order, tbl_template->column_order, sizeof(struct table_col_instance) * tbl_template->cols_to_output);
     for(uint i = 0; i < new_inst->cols_to_output; i++) {
       new_inst->column_order[i].cell_content = NULL;
-      //new_inst->column_order[i].col_def = NULL; // FIXME: col_def should not be touched, probably ...
-      int col_idx = new_inst->column_order[i].idx;//col_order[i];
+      int col_idx = new_inst->column_order[i].idx;
       new_inst->column_order[i].col_def = new_inst->columns + col_idx;
       new_inst->column_order[i].output_type = tbl_template->column_order[i].output_type;
     }
@@ -87,7 +85,6 @@ void table_cleanup(struct table *tbl)
 {
   mp_delete(tbl->pool);
   memset(tbl, 0, sizeof(struct table));
-  xfree(tbl);
 }
 
 // TODO: test default column order
@@ -196,7 +193,7 @@ void table_set_col_order(struct table *tbl, int *col_order, int cols_to_output)
     tbl->column_order[i].idx = col_idx;
     tbl->column_order[i].col_def = tbl->columns + col_idx;
     tbl->column_order[i].cell_content = NULL;
-    tbl->column_order[i].output_type = CELL_OUT_UNINITIALIZED;
+    tbl->column_order[i].output_type = XTYPE_FMT_DEFAULT;
   }
   table_update_ll(tbl);
 }
@@ -227,14 +224,14 @@ bool table_set_col_opt_default(struct table *tbl, int col_idx, const char *col_a
 {
   struct table_column *col_def = tbl->column_order[col_idx].col_def;
 
-  if(col_def->type == COL_TYPE_DOUBLE) {
+  if(col_def->type_def == COL_TYPE_DOUBLE) {
     uint precision = 0;
     const char *tmp_err = str_to_uint(&precision, col_arg, NULL, 0);
     if(tmp_err) {
       *err = mp_printf(tbl->pool, "An error occured while parsing precision: %s", tmp_err);
       return false;
     }
-    tbl->column_order[col_idx].output_type = precision;
+    tbl->column_order[col_idx].output_type = precision; // FIXME: shift the value of precision
     return true;
   }
 
@@ -293,10 +290,10 @@ const char * table_set_col_order_by_name(struct table *tbl, const char *col_orde
     tbl->column_order[curr_col_idx].col_def = tbl->columns + col_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;
-    if(tbl->columns[col_idx].type_def && tbl->columns[col_idx].type_def->set_col_instance_option) {
+    tbl->column_order[curr_col_idx].output_type = XTYPE_FMT_DEFAULT;
+    if(tbl->columns[col_idx].type_def && tbl->columns[col_idx].set_col_instance_option) {
       char *err = NULL;
-      tbl->columns[col_idx].type_def->set_col_instance_option(tbl, curr_col_idx, arg, &err);
+      tbl->columns[col_idx].set_col_instance_option(tbl, curr_col_idx, arg, &err);
       if(err) return mp_printf(tbl->pool, "Error occured while setting column option: %s.", err);
     }
 
@@ -311,12 +308,12 @@ const char * table_set_col_order_by_name(struct table *tbl, const char *col_orde
 
 /*** Table cells ***/
 
-static void table_set_all_inst_content(struct table *tbl, int col_templ, char *col_content, int override)
+static void table_set_all_inst_content(struct table *tbl, int col_templ, const char *col_content)
 {
   TBL_COL_ITER_START(tbl, col_templ, curr_col_ptr, curr_col) {
-    if(override == 0 && curr_col_ptr->output_type != CELL_OUT_UNINITIALIZED ) {
-      die("Error while setting content of all cells of a single type column, cell format should not be overriden.");
-    }
+    //if( override == 0 ) {
+    //die("Error while setting content of all cells of a single type column, cell format should not be overriden.");
+    //}
     curr_col_ptr->cell_content = col_content;
   } TBL_COL_ITER_END
 }
@@ -329,30 +326,13 @@ void table_col_printf(struct table *tbl, int col, const char *fmt, ...)
   va_list args;
   va_start(args, fmt);
   char *cell_content = mp_vprintf(tbl->pool, fmt, args);
-  table_set_all_inst_content(tbl, col, cell_content, 1);
+  table_set_all_inst_content(tbl, col, cell_content);
   va_end(args);
 }
 
-static const char *table_col_default_fmts[] = {
-  [COL_TYPE_STR] = "%s",
-  [COL_TYPE_INT] = "%d",
-  [COL_TYPE_S64] = "%lld",
-  [COL_TYPE_INTMAX] = "%jd",
-  [COL_TYPE_UINT] = "%u",
-  [COL_TYPE_U64] = "%llu",
-  [COL_TYPE_UINTMAX] = "%ju",
-  [COL_TYPE_BOOL] = "%d",
-  [COL_TYPE_DOUBLE] = "%.2lf",
-  [COL_TYPE_ANY] = NULL,
-  [COL_TYPE_LAST] = NULL
-};
-
 #define TABLE_COL(_name_, _type_, _typeconst_) void table_col_##_name_(struct table *tbl, int col, _type_ val)\
   {\
-    const char *fmt = tbl->columns[col].fmt;\
-    if(tbl->columns[col].type == COL_TYPE_ANY) {\
-       fmt = table_col_default_fmts[_typeconst_];\
-    }\
+    enum xtype_fmt fmt = tbl->columns[col].fmt;\
     table_col_##_name_##_fmt(tbl, col, fmt, val);\
   }
 
@@ -362,15 +342,16 @@ static const char *table_col_default_fmts[] = {
     table_col_##_name_(tbl, col, val);\
   }
 
-#define TABLE_COL_FMT(_name_, _type_, _typeconst_, _override) void table_col_##_name_##_fmt(struct table *tbl, int col, const char *fmt, _type_ val) \
+#define TABLE_COL_FMT(_name_, _type_, _typeconst_, _override) void table_col_##_name_##_fmt(struct table *tbl, int col, enum xtype_fmt 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);\
-     ASSERT(fmt != NULL);\
+     ASSERT(tbl->columns[col].type_def == COL_TYPE_ANY || _typeconst_ == tbl->columns[col].type_def);\
      tbl->last_printed_col = col;\
      tbl->row_printing_started = 1;\
-     char *cell_content = mp_printf(tbl->pool, fmt, val);\
-     table_set_all_inst_content(tbl, col, cell_content, _override);\
+     const char *cell_content = NULL;\
+     if(tbl->columns[col].type_def != COL_TYPE_ANY) cell_content = tbl->columns[col].type_def->format(&val, fmt, tbl->pool);\
+     else cell_content = (_typeconst_)->format(&val, fmt, tbl->pool);   \
+     table_set_all_inst_content(tbl, col, cell_content);\
   }
 
 #define TABLE_COL_BODIES(_name_, _type_, _typeconst_, _override) TABLE_COL(_name_, _type_, _typeconst_); \
@@ -384,71 +365,22 @@ TABLE_COL_BODIES(intmax, intmax_t, COL_TYPE_INTMAX, 0)
 TABLE_COL_BODIES(uintmax, uintmax_t, COL_TYPE_UINTMAX, 0)
 TABLE_COL_BODIES(s64, s64, COL_TYPE_S64, 0)
 TABLE_COL_BODIES(u64, u64, COL_TYPE_U64, 0)
+TABLE_COL_BODIES(double, double, COL_TYPE_DOUBLE, 0)
+//TABLE_COL_BODIES(bool, bool, COL_TYPE_BOOL, 0)
 
 // column type double is a special case
-TABLE_COL(double, double, COL_TYPE_DOUBLE);
-TABLE_COL_STR(double, double, COL_TYPE_DOUBLE);
+//TABLE_COL(double, double, COL_TYPE_DOUBLE);
+//TABLE_COL_STR(double, double, COL_TYPE_DOUBLE);
 
-TABLE_COL(bool, bool, COL_TYPE_BOOL);
-TABLE_COL_STR(bool, bool, COL_TYPE_BOOL);
+TABLE_COL(bool, bool, COL_TYPE_BOOL)
+TABLE_COL_STR(bool, bool, COL_TYPE_BOOL)
+TABLE_COL_FMT(bool, bool, COL_TYPE_BOOL, 0)
 
 #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) {
-    char *cell_content_tmp = NULL;
-    switch(tbl->column_order[curr_col].output_type) {
-    case CELL_OUT_UNINITIALIZED:
-      cell_content_tmp = cell_content;
-      break;
-    case CELL_OUT_MACHINE_READABLE:
-      cell_content_tmp = mp_printf(tbl->pool, "%4lf", val);
-      break;
-    default:
-      cell_content_tmp = mp_printf(tbl->pool, "%.*lf", tbl->column_order[curr_col].output_type, val);
-      break;
-    }
-    tbl->column_order[curr_col].cell_content = cell_content_tmp;
-    curr_col = tbl->column_order[curr_col].next_column;
-  }
-}
-
-void table_col_bool_fmt(struct table *tbl, int col, const char *fmt, bool val)
-{
-  ASSERT_MSG(col < tbl->column_count && col >= 0, "Table column %d does not exist.", col);
-  ASSERT(COL_TYPE_BOOL == tbl->columns[col].type);
-
-  tbl->last_printed_col = col;
-  tbl->row_printing_started = 1;
-
-  int curr_col = tbl->columns[col].first_column;
-  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:
-      // FIXME: this is just an example of printing in different formats
-      tbl->column_order[curr_col].cell_content = mp_printf(tbl->pool, fmt, val ? "1" : "0");
-      break;
-    default:
-      die("Unsupported output type.");
-    }
-    curr_col = tbl->column_order[curr_col].next_column;
-  }
-}
 
 void table_reset_row(struct table *tbl)
 {
@@ -481,7 +413,7 @@ struct fastbuf *table_col_fbstart(struct table *tbl, int col)
 void table_col_fbend(struct table *tbl)
 {
   char *cell_content = fbpool_end(&tbl->fb_col_out);
-  table_set_all_inst_content(tbl, tbl->col_out, cell_content, 1);
+  table_set_all_inst_content(tbl, tbl->col_out, cell_content);
   tbl->col_out = -1;
 }
 
index 488c483358856dd686cda56334f7e4310e5c5e63..885d64cd437afbe3e832bb311d2bf2c466ca10ce 100644 (file)
@@ -9,7 +9,9 @@
 
 #include <ucw/fastbuf.h>
 #include <ucw/mempool.h>
+#include <ucw/xtypes.h>
 
+// FIXME: update these macros
 #ifdef CONFIG_UCW_CLEAN_ABI
 #define table_append_bool ucw_table_append_bool
 #define table_append_double ucw_table_append_double
 // FIXME: update documentation according to the changes made in recent commits!
 
 /** Types of columns. These are seldom used explicitly, using a column definition macro is preferred. **/
+
+#define COL_TYPE_STR      &xt_str
+#define COL_TYPE_INT      &xt_int
+#define COL_TYPE_S64      &xt_s64
+#define COL_TYPE_INTMAX   &xt_intmax
+#define COL_TYPE_UINT     &xt_uint
+#define COL_TYPE_U64      &xt_u64
+#define COL_TYPE_UINTMAX  &xt_uintmax
+#define COL_TYPE_BOOL     &xt_bool
+#define COL_TYPE_DOUBLE   &xt_double
+#define COL_TYPE_ANY      NULL
+
+/*
 enum column_type {
   COL_TYPE_STR,                // String
   COL_TYPE_INT,                // int
@@ -89,9 +104,7 @@ enum column_type {
   COL_TYPE_ANY,                // Any type
   COL_TYPE_LAST
 };
-
-#define COL_TYPE_UCW           0x100
-#define COL_TYPE_CUSTOM        0x1000
+*/
 
 /** Justify cell contents to the left. **/
 #define CELL_ALIGN_LEFT     (1U << 31)
@@ -101,20 +114,13 @@ enum column_type {
 #define CELL_FLAG_MASK (CELL_ALIGN_LEFT)
 #define CELL_WIDTH_MASK        (~CELL_FLAG_MASK)
 
-#define CELL_OUT_UNINITIALIZED      -1
-#define CELL_OUT_HUMAN_READABLE     -2
-#define CELL_OUT_MACHINE_READABLE   -3
-#define CELL_OUT_USER_DEF_START     5
+//#define CELL_OUT_UNINITIALIZED      -1
+//#define CELL_OUT_HUMAN_READABLE     -2
+//#define CELL_OUT_MACHINE_READABLE   -3
+//#define CELL_OUT_USER_DEF_START      5
 
 struct table;
 
-struct table_user_type {
-  bool (*set_col_instance_option)(struct table *tbl, uint col, const char *value, char **err);
-       // [*] process table option for a column instance
-  uint type;               // [*] type identifier, should be a number shifted by COL_TYPE_CUSTOM
-  const char *default_fmt; // [*] default format used for printing
-};
-
 /**
  * Definition of a single table column.
  * Usually, this is generated using the `TABLE_COL_`'type' macros.
@@ -123,10 +129,14 @@ struct table_user_type {
 struct table_column {
   const char *name;            // [*] Name of the column displayed in table header
   int width;                   // [*] Width of the column (in characters) OR'ed with column flags
-  const char *fmt;             // [*] Default format of each cell in the column
-  enum column_type type;       // [*] Type of the cells in the column
+  //const char *fmt;           // [*] Default format of each cell in the column
+  //enum column_type type;     // [*] Type of the cells in the column
+  enum xtype_fmt fmt;
   int first_column;             // head of linked list of columns of this type
-  struct table_user_type *type_def;
+  const struct xtype *type_def;
+
+  bool (*set_col_instance_option)(struct table *tbl, uint col, const char *value, char **err);
+       // [*] process table option for a column instance
 };
 
 // FIXME: is it correct to have idx and col_def? idx is sufficient and in fact a duplicity of idx
@@ -134,9 +144,9 @@ struct table_column {
 struct table_col_instance {
   uint idx;                      // idx is a index into struct table::columns
   struct table_column *col_def;  // this is pointer to the column definition, located in the array struct table::columns
-  char *cell_content;            // content of the cell of the current row
+  const char *cell_content;            // content of the cell of the current row
   int next_column;               // index of next column in linked list of columns of the same type
-  int output_type;               // format of this column
+  enum xtype_fmt output_type;               // format of this column
 };
 
 /**
@@ -199,35 +209,35 @@ struct table {
  ***/
 
 #define TBL_COL_LIST_INIT     .first_column = -1
-#define TBL_COL_STR(_name, _width)            { .name = _name, .width = _width, .fmt = "%s", .type = COL_TYPE_STR, TBL_COL_LIST_INIT }
-#define TBL_COL_INT(_name, _width)            { .name = _name, .width = _width, .fmt = "%d", .type = COL_TYPE_INT, TBL_COL_LIST_INIT }
-#define TBL_COL_S64(_name, _width)            { .name = _name, .width = _width, .fmt = "%lld", .type = COL_TYPE_S64, TBL_COL_LIST_INIT }
-#define TBL_COL_UINT(_name, _width)           { .name = _name, .width = _width, .fmt = "%u", .type = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_U64(_name, _width)            { .name = _name, .width = _width, .fmt = "%llu", .type = COL_TYPE_U64, TBL_COL_LIST_INIT }
-#define TBL_COL_INTMAX(_name, _width)         { .name = _name, .width = _width, .fmt = "%jd", .type = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_UINTMAX(_name, _width)        { .name = _name, .width = _width, .fmt = "%ju", .type = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_HEXUINT(_name, _width)        { .name = _name, .width = _width, .fmt = "0x%x", .type = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_DOUBLE(_name, _width, _prec)  { .name = _name, .width = _width, .fmt = "%." #_prec "lf", .type = COL_TYPE_DOUBLE, TBL_COL_LIST_INIT }
-#define TBL_COL_BOOL(_name, _width)           { .name = _name, .width = _width, .fmt = "%s", .type = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
-#define TBL_COL_ANY(_name, _width)            { .name = _name, .width = _width, .fmt = 0, .type = COL_TYPE_ANY, TBL_COL_LIST_INIT }
-
-#define TBL_COL_STR_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_STR, TBL_COL_LIST_INIT }
-#define TBL_COL_INT_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_INT, TBL_COL_LIST_INIT }
-#define TBL_COL_S64_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_S64, TBL_COL_LIST_INIT }
-#define TBL_COL_UINT_FMT(_name, _width, _fmt)           { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_U64_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_U64, TBL_COL_LIST_INIT }
-#define TBL_COL_INTMAX_FMT(_name, _width, _fmt)         { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_UINTMAX_FMT(_name, _width, _fmt)        { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
-#define TBL_COL_HEXUINT_FMT(_name, _width, _fmt)        { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_UINT, TBL_COL_LIST_INIT }
-#define TBL_COL_BOOL_FMT(_name, _width, _fmt)           { .name = _name, .width = _width, .fmt = _fmt, .type = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
-
-#define TBL_COL_END { .name = 0, .width = 0, .fmt = 0, .type = COL_TYPE_LAST }
+#define TBL_COL_STR(_name, _width)            { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_STR, TBL_COL_LIST_INIT }
+#define TBL_COL_INT(_name, _width)            { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INT, TBL_COL_LIST_INIT }
+#define TBL_COL_S64(_name, _width)            { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_S64, TBL_COL_LIST_INIT }
+#define TBL_COL_UINT(_name, _width)           { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
+#define TBL_COL_U64(_name, _width)            { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_U64, TBL_COL_LIST_INIT }
+#define TBL_COL_INTMAX(_name, _width)         { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
+#define TBL_COL_UINTMAX(_name, _width)        { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
+#define TBL_COL_HEXUINT(_name, _width)        { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
+#define TBL_COL_DOUBLE(_name, _width, _prec)  { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_DOUBLE, TBL_COL_LIST_INIT }
+#define TBL_COL_BOOL(_name, _width)           { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
+#define TBL_COL_ANY(_name, _width)            { .name = _name, .width = _width, .fmt = XTYPE_FMT_DEFAULT, .type_def = COL_TYPE_ANY, TBL_COL_LIST_INIT }
+
+#define TBL_COL_STR_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_STR, TBL_COL_LIST_INIT }
+#define TBL_COL_INT_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INT, TBL_COL_LIST_INIT }
+#define TBL_COL_S64_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_S64, TBL_COL_LIST_INIT }
+#define TBL_COL_UINT_FMT(_name, _width, _fmt)           { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
+#define TBL_COL_U64_FMT(_name, _width, _fmt)            { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_U64, TBL_COL_LIST_INIT }
+#define TBL_COL_INTMAX_FMT(_name, _width, _fmt)         { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_INTMAX, TBL_COL_LIST_INIT }
+#define TBL_COL_UINTMAX_FMT(_name, _width, _fmt)        { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINTMAX, TBL_COL_LIST_INIT }
+#define TBL_COL_HEXUINT_FMT(_name, _width, _fmt)        { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_UINT, TBL_COL_LIST_INIT }
+#define TBL_COL_BOOL_FMT(_name, _width, _fmt)           { .name = _name, .width = _width, .fmt = _fmt, .type_def = COL_TYPE_BOOL, TBL_COL_LIST_INIT }
+
+#define TBL_COL_END { .name = 0, .width = 0, .fmt = 0, .type_def = NULL }
 
 #define TBL_COLUMNS  .columns = (struct table_column [])
 #define TBL_COL_ORDER(order) .column_order = (struct table_col_instance *) order, .cols_to_output = ARRAY_SIZE(order)
 #define TBL_COL_DELIMITER(_delimiter_) .col_delimiter = _delimiter_
-#define TBL_COL(_idx) { .idx = _idx, .output_type = CELL_OUT_UNINITIALIZED, .next_column = -1 }
-#define TBL_COL_FMT(_idx, _fmt) { .idx = _idx, .output_type = CELL_OUT_UNINITIALIZED, .next_column = -1, .fmt = _fmt }
+#define TBL_COL(_idx) { .idx = _idx, .output_type = XTYPE_FMT_DEFAULT, .next_column = -1 }
+#define TBL_COL_FMT(_idx, _fmt) { .idx = _idx, .output_type = XTYPE_FMT_DEFAULT, .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
@@ -281,7 +291,7 @@ void table_end(struct table *tbl);
 
 #define TABLE_COL_PROTO(_name_, _type_) void table_col_##_name_(struct table *tbl, int col, _type_ val);\
   void table_col_##_name_##_name(struct table *tbl, const char *col_name, _type_ val);\
-  void table_col_##_name_##_fmt(struct table *tbl, int col, const char *fmt, _type_ val) FORMAT_CHECK(printf, 3, 0);
+  void table_col_##_name_##_fmt(struct table *tbl, int col, enum xtype_fmt fmt, _type_ val);
 
 // table_col_<type>_fmt has one disadvantage: it is not possible to
 // check whether fmt contains format that contains formatting that is
@@ -295,10 +305,11 @@ TABLE_COL_PROTO(intmax, intmax_t);
 TABLE_COL_PROTO(uintmax, uintmax_t);
 TABLE_COL_PROTO(s64, s64);
 TABLE_COL_PROTO(u64, u64);
+TABLE_COL_PROTO(bool, bool);
 
-void table_col_bool(struct table *tbl, int col, bool val);
-void table_col_bool_name(struct table *tbl, const char *col_name, bool val);
-void table_col_bool_fmt(struct table *tbl, int col, const char *fmt, bool val);
+//void table_col_bool(struct table *tbl, int col, bool val);
+//void table_col_bool_name(struct table *tbl, const char *col_name, bool val);
+//void table_col_bool_fmt(struct table *tbl, int col, enum xtype_fmt fmt, bool val);
 #undef TABLE_COL_PROTO
 
 /**
index f17fc4e5ca62807f10d65fa70c8cf98c53e81365..5ddb359d3ff619d8443d8cd8d9090412ab3d32d9 100644 (file)
 #include <ucw/mempool.h>
 #include <ucw/strtonum.h>
 #include <ucw/xtypes.h>
+#include <errno.h>
+#include <stdlib.h>
 
-static const char *xt_int_parse(const char *str, void *dest, struct mempool *pool UNUSED)
+#define XTYPE_NUM_FORMAT(_type, _fmt, _typename) static const char *xt_##_typename##_format(void *src, u32 fmt UNUSED, struct mempool *pool) \
+{\
+  return mp_printf(pool, _fmt, *(_type *)src);\
+}
+
+#define XTYPE_NUM_PARSE(_typename) static const char *xt_##_typename##_parse(const char *str, void *dest, struct mempool *pool UNUSED)\
+{\
+  return str_to_##_typename(dest, str, NULL, 10 | STN_WHOLE | STN_MINUS | STN_PLUS | STN_HEX | STN_BIN | STN_OCT);\
+}
+
+#define XTYPE_NUM_STRUCT(_type, _typename) const struct xtype xt_##_typename = {\
+  .size = sizeof(_type),\
+  .name = #_typename,\
+  .parse = xt_##_typename##_parse,\
+  .format = xt_##_typename##_format,\
+};
+
+
+#define XTYPE_NUM_DEF(_type, _fmt, _typename) XTYPE_NUM_FORMAT(_type, _fmt, _typename) \
+  XTYPE_NUM_PARSE(_typename)\
+  XTYPE_NUM_STRUCT(_type, _typename)
+
+XTYPE_NUM_DEF(int, "%d", int)
+XTYPE_NUM_DEF(s64, "%ld", s64)
+XTYPE_NUM_DEF(intmax_t, "%jd", intmax)
+XTYPE_NUM_DEF(uint, "%u", uint)
+XTYPE_NUM_DEF(u64, "%lu", u64)
+XTYPE_NUM_DEF(uintmax_t, "%ju", uintmax)
+
+/* double */
+
+static const char *xt_double_format(void *src, u32 fmt, struct mempool *pool)
+{
+  switch(fmt) {
+  case XTYPE_FMT_RAW:
+    return mp_printf(pool, "%.2lf", *(double *)src);
+  case XTYPE_FMT_PRETTY:
+    return mp_printf(pool, "%.2lf", *(double *)src);
+
+  case XTYPE_FMT_DEFAULT:
+  default:
+    return mp_printf(pool, "%.2lf", *(double *)src);
+  }
+}
+
+static const char *xt_double_parse(const char *str, void *dest, struct mempool *pool UNUSED)
+{
+  char *endptr = NULL;
+  errno = 0;
+  double result = strtod(str, &endptr);
+  size_t sz = strlen(str);
+  if(endptr != str + sz) return "Could not parse double.";
+  if(errno == ERANGE) return "Could not parse double: overflow happend during parsing";
+
+  *((double *) dest) = result;
+
+  return NULL;
+}
+
+const struct xtype xt_double = {
+  .size = sizeof(double),
+  .name = "double",
+  .parse = xt_double_parse,
+  .format = xt_double_format,
+};
+
+/* bool */
+
+static const char *xt_bool_format(void *src, u32 fmt UNUSED, struct mempool *pool) // (struct table *tbl, int col, enum xtype_fmt fmt, bool val)
+{
+  switch(fmt) {
+    case XTYPE_FMT_DEFAULT:
+    case XTYPE_FMT_PRETTY:
+      return mp_printf(pool, "%s", *((bool *)src) ? "true" : "false");
+    case XTYPE_FMT_RAW:
+      return mp_printf(pool, "%s", *((bool *)src) ? "1" : "0");
+    default:
+      die("Unsupported output type.");
+  }
+}
+
+static const char *xt_bool_parse(const char *str, void *dest, struct mempool *pool UNUSED)
+{
+  if(str[1] == 0) {
+    if(str[0] == '1') {
+      *((bool *)dest) = false;
+      return NULL;
+    }
+    if(str[0] == '1') {
+      *((bool *)dest) = true;
+      return NULL;
+    }
+  }
+
+  if(strcasecmp(str, "false") == 0) {
+    *((bool *)dest) = false;
+    return NULL;
+  }
+
+  if(strcasecmp(str, "true") == 0) {
+    *((bool *)dest) = true;
+    return NULL;
+  }
+
+  return "Could not parse bool.";
+}
+
+const struct xtype xt_bool = {
+  .size = sizeof(bool),
+  .name = "bool",
+  .parse = xt_bool_parse,
+  .format = xt_bool_format,
+};
+
+
+/* str */
+static const char *xt_str_format(void *src, u32 fmt UNUSED, struct mempool *pool) // (struct table *tbl, int col, enum xtype_fmt fmt, bool val)
 {
-  return str_to_int(dest, str, NULL, 10 | STN_WHOLE | STN_MINUS | STN_PLUS | STN_HEX | STN_BIN | STN_OCT);
+  return mp_printf(pool, "%s", *((char **) src));
 }
 
-static const char *xt_int_format(void *src, u32 fmt UNUSED, struct mempool *pool)
+static const char *xt_str_parse(const char *str, void *dest, struct mempool *pool UNUSED)
 {
-  return mp_printf(pool, "%d", *(int *)src);
+  *((const char **) dest) = str;
+  return NULL;
 }
 
-const struct xtype xt_int = {
-  .size = sizeof(int),
-  .name = "int",
-  .parse = xt_int_parse,
-  .format = xt_int_format,
+const struct xtype xt_str = {
+  .size = sizeof(char *),
+  .name = "str",
+  .parse = xt_str_parse,
+  .format = xt_str_format,
 };
index c06b3a226c7f2c587ea671c9a378b3c5d183b634..380524e80d8ae72a64dbd19c8b0159dbf970bbc5 100644 (file)
@@ -88,6 +88,14 @@ const char *xtype_parse_fmt(struct xtype *xt, const char *str, u32 *dest, struct
 const char *xtype_format_fmt(struct xtype *xt, u32 fmt, struct mempool *pool);
 
 // Basic set of extended types
+extern const struct xtype xt_str;
 extern const struct xtype xt_int;
+extern const struct xtype xt_s64;
+extern const struct xtype xt_intmax;
+extern const struct xtype xt_uint;
+extern const struct xtype xt_u64;
+extern const struct xtype xt_uintmax;
+extern const struct xtype xt_bool;
+extern const struct xtype xt_double;
 
 #endif