(root)/
util-linux-2.39/
libsmartcols/
src/
print-api.c
       1  #include "smartcolsP.h"
       2  
       3  /**
       4   * scola_table_print_range:
       5   * @tb: table
       6   * @start: first printed line or NULL to print from the begin of the table
       7   * @end: last printed line or NULL to print all from start.
       8   *
       9   * If the start is the first line in the table than prints table header too.
      10   * The header is printed only once. This does not work for trees.
      11   *
      12   * Returns: 0, a negative value in case of an error.
      13   */
      14  int scols_table_print_range(	struct libscols_table *tb,
      15  				struct libscols_line *start,
      16  				struct libscols_line *end)
      17  {
      18  	struct ul_buffer buf = UL_INIT_BUFFER;
      19  	struct libscols_iter itr;
      20  	int rc;
      21  
      22  	if (scols_table_is_tree(tb))
      23  		return -EINVAL;
      24  
      25  	DBG(TAB, ul_debugobj(tb, "printing range from API"));
      26  
      27  	rc = __scols_initialize_printing(tb, &buf);
      28  	if (rc)
      29  		return rc;
      30  
      31  	if (start) {
      32  		itr.direction = SCOLS_ITER_FORWARD;
      33  		itr.head = &tb->tb_lines;
      34  		itr.p = &start->ln_lines;
      35  	} else
      36  		scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
      37  
      38  	if (!start || itr.p == tb->tb_lines.next) {
      39  		rc = __scols_print_header(tb, &buf);
      40  		if (rc)
      41  			goto done;
      42  	}
      43  
      44  	rc = __scols_print_range(tb, &buf, &itr, end);
      45  done:
      46  	__scols_cleanup_printing(tb, &buf);
      47  	return rc;
      48  }
      49  
      50  /**
      51   * scols_table_print_range_to_string:
      52   * @tb: table
      53   * @start: first printed line or NULL to print from the beginning of the table
      54   * @end: last printed line or NULL to print all from start.
      55   * @data: pointer to the beginning of a memory area to print to
      56   *
      57   * The same as scols_table_print_range(), but prints to @data instead of
      58   * stream.
      59   *
      60   * Returns: 0, a negative value in case of an error.
      61   */
      62  #ifdef HAVE_OPEN_MEMSTREAM
      63  int scols_table_print_range_to_string(	struct libscols_table *tb,
      64  					struct libscols_line *start,
      65  					struct libscols_line *end,
      66  					char **data)
      67  {
      68  	FILE *stream, *old_stream;
      69  	size_t sz;
      70  	int rc;
      71  
      72  	if (!tb)
      73  		return -EINVAL;
      74  
      75  	DBG(TAB, ul_debugobj(tb, "printing range to string"));
      76  
      77  	/* create a stream for output */
      78  	stream = open_memstream(data, &sz);
      79  	if (!stream)
      80  		return -ENOMEM;
      81  
      82  	old_stream = scols_table_get_stream(tb);
      83  	scols_table_set_stream(tb, stream);
      84  	rc = scols_table_print_range(tb, start, end);
      85  	fclose(stream);
      86  	scols_table_set_stream(tb, old_stream);
      87  
      88  	return rc;
      89  }
      90  #else
      91  int scols_table_print_range_to_string(
      92  			struct libscols_table *tb __attribute__((__unused__)),
      93  			struct libscols_line *start __attribute__((__unused__)),
      94  			struct libscols_line *end __attribute__((__unused__)),
      95  			char **data __attribute__((__unused__)))
      96  {
      97  	return -ENOSYS;
      98  }
      99  #endif
     100  
     101  static int do_print_table(struct libscols_table *tb, int *is_empty)
     102  {
     103  	int rc = 0;
     104  	struct ul_buffer buf = UL_INIT_BUFFER;
     105  
     106  	if (!tb)
     107  		return -EINVAL;
     108  
     109  	DBG(TAB, ul_debugobj(tb, "printing"));
     110  	if (is_empty)
     111  		*is_empty = 0;
     112  
     113  	if (list_empty(&tb->tb_columns)) {
     114  		DBG(TAB, ul_debugobj(tb, "error -- no columns"));
     115  		return -EINVAL;
     116  	}
     117  	if (list_empty(&tb->tb_lines)) {
     118  		DBG(TAB, ul_debugobj(tb, "ignore -- no lines"));
     119  		if (scols_table_is_json(tb)) {
     120  			ul_jsonwrt_init(&tb->json, tb->out, 0);
     121  			ul_jsonwrt_root_open(&tb->json);
     122  			ul_jsonwrt_array_open(&tb->json, tb->name ? tb->name : "");
     123  			ul_jsonwrt_array_close(&tb->json);
     124  			ul_jsonwrt_root_close(&tb->json);
     125  		} else if (is_empty)
     126  			*is_empty = 1;
     127  		return 0;
     128  	}
     129  
     130  	tb->header_printed = 0;
     131  	rc = __scols_initialize_printing(tb, &buf);
     132  	if (rc)
     133  		return rc;
     134  
     135  	if (scols_table_is_json(tb)) {
     136  		ul_jsonwrt_root_open(&tb->json);
     137  		ul_jsonwrt_array_open(&tb->json, tb->name ? tb->name : "");
     138  	}
     139  
     140  	if (tb->format == SCOLS_FMT_HUMAN)
     141  		__scols_print_title(tb);
     142  
     143  	rc = __scols_print_header(tb, &buf);
     144  	if (rc)
     145  		goto done;
     146  
     147  	if (scols_table_is_tree(tb))
     148  		rc = __scols_print_tree(tb, &buf);
     149  	else
     150  		rc = __scols_print_table(tb, &buf);
     151  
     152  	if (scols_table_is_json(tb)) {
     153  		ul_jsonwrt_array_close(&tb->json);
     154  		ul_jsonwrt_root_close(&tb->json);
     155  	}
     156  done:
     157  	__scols_cleanup_printing(tb, &buf);
     158  	return rc;
     159  }
     160  
     161  /**
     162   * scols_print_table:
     163   * @tb: table
     164   *
     165   * Prints the table to the output stream and terminate by \n.
     166   *
     167   * Returns: 0, a negative value in case of an error.
     168   */
     169  int scols_print_table(struct libscols_table *tb)
     170  {
     171  	int empty = 0;
     172  	int rc = do_print_table(tb, &empty);
     173  
     174  	if (rc == 0 && !empty && !scols_table_is_json(tb))
     175  		fputc('\n', tb->out);
     176  	return rc;
     177  }
     178  
     179  /**
     180   * scols_print_table_to_string:
     181   * @tb: table
     182   * @data: pointer to the beginning of a memory area to print to
     183   *
     184   * Prints the table to @data.
     185   *
     186   * Returns: 0, a negative value in case of an error.
     187   */
     188  #ifdef HAVE_OPEN_MEMSTREAM
     189  int scols_print_table_to_string(struct libscols_table *tb, char **data)
     190  {
     191  	FILE *stream, *old_stream;
     192  	size_t sz;
     193  	int rc;
     194  
     195  	if (!tb)
     196  		return -EINVAL;
     197  
     198  	DBG(TAB, ul_debugobj(tb, "printing to string"));
     199  
     200  	/* create a stream for output */
     201  	stream = open_memstream(data, &sz);
     202  	if (!stream)
     203  		return -ENOMEM;
     204  
     205  	old_stream = scols_table_get_stream(tb);
     206  	scols_table_set_stream(tb, stream);
     207  	rc = do_print_table(tb, NULL);
     208  	fclose(stream);
     209  	scols_table_set_stream(tb, old_stream);
     210  
     211  	return rc;
     212  }
     213  #else
     214  int scols_print_table_to_string(
     215  		struct libscols_table *tb __attribute__((__unused__)),
     216  		char **data  __attribute__((__unused__)))
     217  {
     218  	return -ENOSYS;
     219  }
     220  #endif