diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt index e72637add..974123540 100644 --- a/libsmartcols/docs/libsmartcols-sections.txt +++ b/libsmartcols/docs/libsmartcols-sections.txt @@ -112,6 +112,7 @@ scols_table_add_line scols_table_colors_wanted scols_table_enable_ascii scols_table_enable_colors +scols_table_enable_noencoding scols_table_enable_export scols_table_enable_header_repeat scols_table_enable_json @@ -140,6 +141,7 @@ scols_table_is_header_repeat scols_table_is_json scols_table_is_maxout scols_table_is_noheadings +scols_table_is_noencoding scols_table_is_nolinesep scols_table_is_nowrap scols_table_is_raw diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in index bce2cc725..d99d52ba0 100644 --- a/libsmartcols/src/libsmartcols.h.in +++ b/libsmartcols/src/libsmartcols.h.in @@ -226,6 +226,7 @@ extern int scols_table_is_maxout(const struct libscols_table *tb); extern int scols_table_is_nowrap(const struct libscols_table *tb); extern int scols_table_is_nolinesep(const struct libscols_table *tb); extern int scols_table_is_tree(const struct libscols_table *tb); +extern int scols_table_is_noencoding(const struct libscols_table *tb); extern int scols_table_enable_colors(struct libscols_table *tb, int enable); extern int scols_table_enable_raw(struct libscols_table *tb, int enable); @@ -237,6 +238,7 @@ extern int scols_table_enable_export(struct libscols_table *tb, int enable); extern int scols_table_enable_maxout(struct libscols_table *tb, int enable); extern int scols_table_enable_nowrap(struct libscols_table *tb, int enable); extern int scols_table_enable_nolinesep(struct libscols_table *tb, int enable); +extern int scols_table_enable_noencoding(struct libscols_table *tb, int enable); extern int scols_table_set_column_separator(struct libscols_table *tb, const char *sep); extern int scols_table_set_line_separator(struct libscols_table *tb, const char *sep); diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym index fec33cbfd..a4ac39cc9 100644 --- a/libsmartcols/src/libsmartcols.sym +++ b/libsmartcols/src/libsmartcols.sym @@ -173,4 +173,6 @@ SMARTCOLS_2.31 { scols_table_get_termheight; scols_table_is_header_repeat; scols_table_enable_header_repeat; + scols_table_enable_noencoding; + scols_table_is_noencoding; } SMARTCOLS_2.30; diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h index 65009779a..b3b54cddd 100644 --- a/libsmartcols/src/smartcolsP.h +++ b/libsmartcols/src/smartcolsP.h @@ -177,6 +177,7 @@ struct libscols_table { header_printed :1, /* header already printed */ priv_symbols :1, /* default private symbols */ no_headings :1, /* don't print header */ + no_encode :1, /* don't care about control and non-printable chars */ no_linesep :1, /* don't print line separator */ no_wrap :1; /* never wrap lines */ }; diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c index 3306ff57c..81f4b8f2b 100644 --- a/libsmartcols/src/table.c +++ b/libsmartcols/src/table.c @@ -1106,6 +1106,39 @@ int scols_table_is_nowrap(const struct libscols_table *tb) return tb->no_wrap; } +/** + * scols_table_enable_noencoding: + * @tb: table + * @enable: 1 or 0 + * + * The library encode non-printable and control chars by \x by default. + * + * Returns: 0 on success, negative number in case of an error. + * + * Since: 2.31 + */ +int scols_table_enable_noencoding(struct libscols_table *tb, int enable) +{ + if (!tb) + return -EINVAL; + DBG(TAB, ul_debugobj(tb, "encoding: %s", enable ? "ENABLE" : "DISABLE")); + tb->no_encode = enable ? 1 : 0; + return 0; +} + +/** + * scols_table_is_noencoding: + * @tb: a pointer to a struct libscols_table instance + * + * Returns: 1 if encoding is disabled. + * + * Since: 2.31 + */ +int scols_table_is_noencoding(const struct libscols_table *tb) +{ + return tb->no_encode; +} + /** * scols_table_colors_wanted: * @tb: table diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c index 115212101..472c3616c 100644 --- a/libsmartcols/src/table_print.c +++ b/libsmartcols/src/table_print.c @@ -132,7 +132,9 @@ static char *buffer_get_data(struct libscols_buffer *buf) } /* encode data by mbs_safe_encode() to avoid control and non-printable chars */ -static char *buffer_get_safe_data(struct libscols_buffer *buf, size_t *cells, +static char *buffer_get_safe_data(struct libscols_table *tb, + struct libscols_buffer *buf, + size_t *cells, const char *safechars) { char *data = buffer_get_data(buf); @@ -147,7 +149,14 @@ static char *buffer_get_safe_data(struct libscols_buffer *buf, size_t *cells, goto nothing; } - res = mbs_safe_encode_to_buffer(data, cells, buf->encdata, safechars); + if (tb->no_encode) { + *cells = mbs_safe_width(data); + strcpy(buf->encdata, data); + res = buf->encdata; + } else { + res = mbs_safe_encode_to_buffer(data, cells, buf->encdata, safechars); + } + if (!res || !*cells || *cells == (size_t) -1) goto nothing; return res; @@ -251,7 +260,7 @@ static void print_empty_cell(struct libscols_table *tb, line_ascii_art_to_buffer(tb, ln, art); if (!list_empty(&ln->ln_branch) && has_pending_data(tb)) buffer_append_data(art, vertical_symbol(tb)); - data = buffer_get_safe_data(art, &len_pad, NULL); + data = buffer_get_safe_data(tb, art, &len_pad, NULL); if (data && len_pad) fputs(data, tb->out); free_buffer(art); @@ -475,7 +484,7 @@ static int print_data(struct libscols_table *tb, /* Encode. Note that 'len' and 'width' are number of cells, not bytes. */ - data = buffer_get_safe_data(buf, &len, scols_column_get_safechars(cl)); + data = buffer_get_safe_data(tb, buf, &len, scols_column_get_safechars(cl)); if (!data) data = ""; bytes = strlen(data); @@ -763,21 +772,30 @@ static int print_title(struct libscols_table *tb) DBG(TAB, ul_debugobj(tb, "printing title")); /* encode data */ - bufsz = mbs_safe_encode_size(strlen(tb->title.data)) + 1; - if (bufsz == 1) { - DBG(TAB, ul_debugobj(tb, "title is empty string -- ignore")); - return 0; - } - buf = malloc(bufsz); - if (!buf) { - rc = -ENOMEM; - goto done; - } + if (tb->no_encode) { + bufsz = strlen(tb->title.data) + 1; + buf = strdup(tb->title.data); + if (!buf) { + rc = -ENOMEM; + goto done; + } + } else { + bufsz = mbs_safe_encode_size(strlen(tb->title.data)) + 1; + if (bufsz == 1) { + DBG(TAB, ul_debugobj(tb, "title is empty string -- ignore")); + return 0; + } + buf = malloc(bufsz); + if (!buf) { + rc = -ENOMEM; + goto done; + } - if (!mbs_safe_encode_to_buffer(tb->title.data, &bufsz, buf, NULL) || - !bufsz || bufsz == (size_t) -1) { - rc = -EINVAL; - goto done; + if (!mbs_safe_encode_to_buffer(tb->title.data, &bufsz, buf, NULL) || + !bufsz || bufsz == (size_t) -1) { + rc = -EINVAL; + goto done; + } } /* truncate and align */