(root)/
util-linux-2.39/
libsmartcols/
samples/
continuous.c
       1  /*
       2   * Copyright (C) 2016 Karel Zak <kzak@redhat.com>
       3   *
       4   * This file may be redistributed under the terms of the
       5   * GNU Lesser General Public License.
       6   */
       7  #include <stdlib.h>
       8  #include <unistd.h>
       9  #include <string.h>
      10  #include <errno.h>
      11  #include <sys/types.h>
      12  #include <sys/time.h>
      13  
      14  #include "c.h"
      15  #include "nls.h"
      16  #include "strutils.h"
      17  #include "xalloc.h"
      18  
      19  #include "libsmartcols.h"
      20  
      21  #define TIME_PERIOD	3.0	/* seconds */
      22  
      23  enum { COL_NUM, COL_DATA, COL_TIME };
      24  
      25  static double time_diff(struct timeval *a, struct timeval *b)
      26  {
      27  	return (a->tv_sec - b->tv_sec) + (a->tv_usec - b->tv_usec) / 1E6;
      28  }
      29  
      30  /* add columns to the @tb */
      31  static void setup_columns(struct libscols_table *tb)
      32  {
      33  	scols_table_enable_maxout(tb, 1);
      34  	if (!scols_table_new_column(tb, "#NUM", 0.1, SCOLS_FL_RIGHT))
      35  		goto fail;
      36  	if (!scols_table_new_column(tb, "DATA", 0.7, 0))
      37  		goto fail;
      38  	if (!scols_table_new_column(tb, "TIME", 0.2, 0))
      39  		goto fail;
      40  	return;
      41  fail:
      42  	scols_unref_table(tb);
      43  	err(EXIT_FAILURE, "failed to create output columns");
      44  }
      45  
      46  static struct libscols_line *add_line(struct libscols_table *tb, size_t i)
      47  {
      48  	char *p;
      49  	struct libscols_line *ln = scols_table_new_line(tb, NULL);
      50  
      51  	if (!ln)
      52  		err(EXIT_FAILURE, "failed to create output line");
      53  
      54  	xasprintf(&p, "%zu", i);
      55  	if (scols_line_refer_data(ln, COL_NUM, p))
      56  		goto fail;
      57  
      58  	xasprintf(&p, "data-%02zu-%02zu-%02zu-end", i + 1, i + 2, i + 3);
      59  	if (scols_line_refer_data(ln, COL_DATA, p))
      60  		goto fail;
      61  
      62  	return ln;
      63  fail:
      64  	scols_unref_table(tb);
      65  	err(EXIT_FAILURE, "failed to create output line");
      66  }
      67  
      68  int main(int argc, char *argv[])
      69  {
      70  	struct libscols_table *tb;
      71  	size_t i;
      72  	const size_t timecellsz = sizeof(stringify_value(UINT_MAX));
      73  	struct timeval last;
      74  
      75  	scols_init_debug(0);
      76  
      77  	tb = scols_new_table();
      78  	if (!tb)
      79  		err(EXIT_FAILURE, "failed to create output table");
      80  
      81  	setup_columns(tb);
      82  	gettimeofday(&last, NULL);
      83  
      84  	for (i = 0; i < 10; i++) {
      85  		struct libscols_line *line;
      86  		struct timeval now;
      87  		int done = 0;
      88  		char *timecell = xmalloc( timecellsz );
      89  
      90  		line = add_line(tb, i);
      91  
      92  		/* Make a reference from cell data to the buffer, then we can
      93  		 * update cell data without any interaction with libsmartcols
      94  		 */
      95  		if (scols_line_refer_data(line, COL_TIME, timecell) != 0)
      96  			err(EXIT_FAILURE, "failed to add data to table");
      97  
      98  		do {
      99  			double diff;
     100  
     101  			gettimeofday(&now, NULL);
     102  			diff = time_diff(&now, &last);
     103  
     104  			if (now.tv_sec == last.tv_sec + (long) TIME_PERIOD)
     105  				done = 1;
     106  			else
     107  				xusleep(100000);
     108  
     109  			/* update "TIME" cell data */
     110  			snprintf(timecell, timecellsz, "%f [%3d%%]", diff,
     111  				done ? 100 : (int)(diff / (TIME_PERIOD / 100.0)));
     112  
     113  			/* Note that libsmartcols don't print \n for last line
     114  			 * in the table, but if you print a line somewhere in
     115  			 * the midle of the table you need
     116  			 *
     117  			 *    scols_table_enable_nolinesep(tb, !done);
     118  			 *
     119  			 * to disable line breaks. In this example it's
     120  			 * unnecessary as we print the latest line only.
     121  			 */
     122  
     123  			/* print the line */
     124  			scols_table_print_range(tb, line, NULL);
     125  
     126  			if (!done) {
     127  				/* terminal is waiting for \n, fflush() to force output */
     128  				fflush(scols_table_get_stream(tb));
     129  				/* move to the begin of the line */
     130  				fputc('\r', scols_table_get_stream(tb));
     131  			} else
     132  				fputc('\n', scols_table_get_stream(tb));
     133  		} while (!done);
     134  
     135  		last = now;
     136  	}
     137  
     138  	scols_unref_table(tb);
     139  	return EXIT_SUCCESS;
     140  }