/* * Copyright (C) 2016 Karel Zak * * This file may be redistributed under the terms of the * GNU Lesser General Public License. */ #include #include #include #include #include #include #include "c.h" #include "nls.h" #include "strutils.h" #include "xalloc.h" #include "libsmartcols.h" #define TIME_PERIOD 3.0 /* seconds */ enum { COL_NUM, COL_DATA, COL_TIME }; static double time_diff(struct timeval *a, struct timeval *b) { return (a->tv_sec - b->tv_sec) + (a->tv_usec - b->tv_usec) / 1E6; } /* add columns to the @tb */ static void setup_columns(struct libscols_table *tb) { scols_table_enable_maxout(tb, 1); if (!scols_table_new_column(tb, "#NUM", 0.1, SCOLS_FL_RIGHT)) goto fail; if (!scols_table_new_column(tb, "DATA", 0.7, 0)) goto fail; if (!scols_table_new_column(tb, "TIME", 0.2, 0)) goto fail; return; fail: scols_unref_table(tb); err(EXIT_FAILURE, "failed to create output columns"); } static struct libscols_line *add_line(struct libscols_table *tb, size_t i) { char *p; struct libscols_line *ln = scols_table_new_line(tb, NULL); if (!ln) err(EXIT_FAILURE, "failed to create output line"); xasprintf(&p, "%zu", i); if (scols_line_refer_data(ln, COL_NUM, p)) goto fail; xasprintf(&p, "data-%02zu-%02zu-%02zu-end", i + 1, i + 2, i + 3); if (scols_line_refer_data(ln, COL_DATA, p)) goto fail; return ln; fail: scols_unref_table(tb); err(EXIT_FAILURE, "failed to create output line"); } int main(int argc, char *argv[]) { struct libscols_table *tb; size_t i; struct timeval last; scols_init_debug(0); tb = scols_new_table(); if (!tb) err(EXIT_FAILURE, "failed to create output table"); setup_columns(tb); gettimeofday(&last, NULL); for (i = 0; i < 10; i++) { struct libscols_line *line; struct timeval now; int done = 0; char *timecell = xmalloc( sizeof(stringify_value(UINT_MAX)) ); line = add_line(tb, i); /* Make a reference from cell data to the buffer, then we can * update cell data without any interaction with libsmartcols */ scols_line_refer_data(line, COL_TIME, timecell); do { double diff; gettimeofday(&now, NULL); diff = time_diff(&now, &last); if (now.tv_sec == last.tv_sec + (long) TIME_PERIOD) done = 1; else xusleep(100000); /* update "TIME" cell data */ sprintf(timecell, "%f [%3d%%]", diff, done ? 100 : (int)(diff / (TIME_PERIOD / 100.0))); /* Note that libsmartcols don't print \n for last line * in the table, but if you print a line somewhere in * the midle of the table you need * * scols_table_enable_nolinesep(tb, !done); * * to disable line breaks. In this example it's * unnecessary as we print the latest line only. */ /* print the line */ scols_table_print_range(tb, line, NULL); if (!done) { /* terminal is waiting for \n, fflush() to force output */ fflush(scols_table_get_stream(tb)); /* move to the begin of the line */ fputc('\r', scols_table_get_stream(tb)); } else fputc('\n', scols_table_get_stream(tb)); } while (!done); last = now; } scols_unref_table(tb); return EXIT_SUCCESS; }