[pacman-dev] [PATCH 1/4] pm_asprintf logs 'failed to allocate' already
Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> --- src/pacman/util.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pacman/util.c b/src/pacman/util.c index ef66638..862c8e8 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -749,7 +749,6 @@ void signature_display(const char *title, alpm_siglist_t *siglist, ret = pm_asprintf(&sigline, _("%s, %s from \"%s\""), status, validity, name); if(ret == -1) { - pm_printf(ALPM_LOG_ERROR, _("failed to allocate string\n")); continue; } indentprint(sigline, len, maxcols); -- 1.8.2
Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> --- src/pacman/package.c | 8 ++++---- src/pacman/util.c | 34 ++++++++++++++++------------------ src/pacman/util.h | 3 ++- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/pacman/package.c b/src/pacman/package.c index 42a8635..3d1b108 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -40,21 +40,21 @@ * @param deps a list with items of type alpm_depend_t */ static void deplist_display(const char *title, - alpm_list_t *deps, unsigned short cols) + alpm_list_t *deps, unsigned short maxcols) { alpm_list_t *i, *text = NULL; for(i = deps; i; i = alpm_list_next(i)) { alpm_depend_t *dep = i->data; text = alpm_list_add(text, alpm_dep_compute_string(dep)); } - list_display(title, text, cols); + list_display(title, text, maxcols); FREELIST(text); } /** Turn a optdepends list into a text list. * @param optdeps a list with items of type alpm_depend_t */ -static void optdeplist_display(alpm_pkg_t *pkg, unsigned short cols) +static void optdeplist_display(alpm_pkg_t *pkg, unsigned short maxcols) { alpm_list_t *i, *text = NULL; for(i = alpm_pkg_get_optdepends(pkg); i; i = alpm_list_next(i)) { @@ -69,7 +69,7 @@ static void optdeplist_display(alpm_pkg_t *pkg, unsigned short cols) } text = alpm_list_add(text, depstring); } - list_display_linebreak(_("Optional Deps :"), text, cols); + list_display_linebreak(_("Optional Deps :"), text, maxcols); FREELIST(text); } diff --git a/src/pacman/util.c b/src/pacman/util.c index 862c8e8..daffffd 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -424,17 +424,20 @@ static size_t string_length(const char *s) return len; } -void string_display(const char *title, const char *string, unsigned short cols) +void string_display(const char *title, const char *string, + unsigned short maxcols) { + unsigned short len = 0; + if(title) { + len = (unsigned short)string_length(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } + if(string == NULL || string[0] == '\0') { printf(_("None")); } else { - /* compute the length of title + a space */ - size_t len = string_length(title) + 1; - indentprint(string, (unsigned short)len, cols); + indentprint(string, (unsigned short)len, maxcols); } printf("\n"); } @@ -486,8 +489,6 @@ static void table_print_line(const alpm_list_t *line, short col_padding, printf("\n"); } - - /** * Find the max string width of each column. Also determines whether values * exist in the column and sets the value in has_data accordingly. @@ -615,19 +616,20 @@ static int table_display(const char *title, const alpm_list_t *header, void list_display(const char *title, const alpm_list_t *list, unsigned short maxcols) { - const alpm_list_t *i; - size_t len = 0; + unsigned short len = 0; if(title) { - len = string_length(title) + 1; + len = (unsigned short)string_length(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } if(!list) { printf("%s\n", _("None")); } else { - size_t cols = len; + const alpm_list_t *i; const char *str = list->data; + size_t cols = len; + fputs(str, stdout); cols += string_length(str); for(i = alpm_list_next(list); i; i = alpm_list_next(i)) { @@ -667,15 +669,13 @@ void list_display_linebreak(const char *title, const alpm_list_t *list, printf("%s\n", _("None")); } else { const alpm_list_t *i; + /* Print the first element */ indentprint((const char *)list->data, len, maxcols); printf("\n"); /* Print the rest */ for(i = alpm_list_next(list); i; i = alpm_list_next(i)) { - size_t j; - for(j = 1; j <= len; j++) { - printf(" "); - } + printf("%-*s", (int)len, ""); indentprint((const char *)i->data, len, maxcols); printf("\n"); } @@ -691,6 +691,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist, len = (unsigned short)string_length(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } + if(siglist->count == 0) { printf(_("None")); } else { @@ -702,10 +703,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist, alpm_sigresult_t *result = siglist->results + i; /* Don't re-indent the first result */ if(i != 0) { - size_t j; - for(j = 1; j <= len; j++) { - printf(" "); - } + printf("%-*s", (int)len, ""); } switch(result->status) { case ALPM_SIGSTATUS_VALID: diff --git a/src/pacman/util.h b/src/pacman/util.h index 0a2a6f7..690bc1d 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -55,7 +55,8 @@ void indentprint(const char *str, unsigned short indent, unsigned short cols); size_t strtrim(char *str); char *strreplace(const char *str, const char *needle, const char *replace); alpm_list_t *strsplit(const char *str, const char splitchar); -void string_display(const char *title, const char *string, unsigned short cols); +void string_display(const char *title, const char *string, + unsigned short maxcols); double humanize_size(off_t bytes, const char target_unit, int precision, const char **label); void list_display(const char *title, const alpm_list_t *list, -- 1.8.2
Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> --- src/pacman/package.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/util.c | 95 +--------------------------------------------------- src/pacman/util.h | 5 +-- 3 files changed, 94 insertions(+), 98 deletions(-) diff --git a/src/pacman/package.c b/src/pacman/package.c index 3d1b108..403896a 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -36,6 +36,24 @@ #define CLBUF_SIZE 4096 +static void string_display(const char *title, const char *string, + unsigned short maxcols) +{ + unsigned short len = 0; + + if(title) { + len = (unsigned short)string_length(title) + 1; + printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); + } + + if(string == NULL || string[0] == '\0') { + printf(_("None")); + } else { + indentprint(string, (unsigned short)len, maxcols); + } + printf("\n"); +} + /** Turn a depends list into a text list. * @param deps a list with items of type alpm_depend_t */ @@ -73,6 +91,80 @@ static void optdeplist_display(alpm_pkg_t *pkg, unsigned short maxcols) FREELIST(text); } +void signature_display(const char *title, alpm_siglist_t *siglist, + unsigned short maxcols) +{ + unsigned short len = 0; + + if(title) { + len = (unsigned short)string_length(title) + 1; + printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); + } + + if(siglist->count == 0) { + printf(_("None")); + } else { + size_t i; + for(i = 0; i < siglist->count; i++) { + char *sigline; + const char *status, *validity, *name; + int ret; + alpm_sigresult_t *result = siglist->results + i; + /* Don't re-indent the first result */ + if(i != 0) { + printf("%-*s", (int)len, ""); + } + switch(result->status) { + case ALPM_SIGSTATUS_VALID: + status = _("Valid"); + break; + case ALPM_SIGSTATUS_KEY_EXPIRED: + status = _("Key expired"); + break; + case ALPM_SIGSTATUS_SIG_EXPIRED: + status = _("Expired"); + break; + case ALPM_SIGSTATUS_INVALID: + status = _("Invalid"); + break; + case ALPM_SIGSTATUS_KEY_UNKNOWN: + status = _("Key unknown"); + break; + case ALPM_SIGSTATUS_KEY_DISABLED: + status = _("Key disabled"); + break; + default: + status = _("Signature error"); + break; + } + switch(result->validity) { + case ALPM_SIGVALIDITY_FULL: + validity = _("full trust"); + break; + case ALPM_SIGVALIDITY_MARGINAL: + validity = _("marginal trust"); + break; + case ALPM_SIGVALIDITY_NEVER: + validity = _("never trust"); + break; + case ALPM_SIGVALIDITY_UNKNOWN: + default: + validity = _("unknown trust"); + break; + } + name = result->key.uid ? result->key.uid : result->key.fingerprint; + ret = pm_asprintf(&sigline, _("%s, %s from \"%s\""), + status, validity, name); + if(ret == -1) { + continue; + } + indentprint(sigline, len, maxcols); + printf("\n"); + free(sigline); + } + } +} + /** * Display the details of a package. * Extra information entails 'required by' info for sync packages and backup diff --git a/src/pacman/util.c b/src/pacman/util.c index daffffd..c2f0669 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -406,7 +406,7 @@ alpm_list_t *strsplit(const char *str, const char splitchar) return list; } -static size_t string_length(const char *s) +size_t string_length(const char *s) { int len; wchar_t *wcstr; @@ -424,24 +424,6 @@ static size_t string_length(const char *s) return len; } -void string_display(const char *title, const char *string, - unsigned short maxcols) -{ - unsigned short len = 0; - - if(title) { - len = (unsigned short)string_length(title) + 1; - printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); - } - - if(string == NULL || string[0] == '\0') { - printf(_("None")); - } else { - indentprint(string, (unsigned short)len, maxcols); - } - printf("\n"); -} - static void table_print_line(const alpm_list_t *line, short col_padding, size_t colcount, size_t *widths, int *has_data) { @@ -682,81 +664,6 @@ void list_display_linebreak(const char *title, const alpm_list_t *list, } } -void signature_display(const char *title, alpm_siglist_t *siglist, - unsigned short maxcols) -{ - unsigned short len = 0; - - if(title) { - len = (unsigned short)string_length(title) + 1; - printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); - } - - if(siglist->count == 0) { - printf(_("None")); - } else { - size_t i; - for(i = 0; i < siglist->count; i++) { - char *sigline; - const char *status, *validity, *name; - int ret; - alpm_sigresult_t *result = siglist->results + i; - /* Don't re-indent the first result */ - if(i != 0) { - printf("%-*s", (int)len, ""); - } - switch(result->status) { - case ALPM_SIGSTATUS_VALID: - status = _("Valid"); - break; - case ALPM_SIGSTATUS_KEY_EXPIRED: - status = _("Key expired"); - break; - case ALPM_SIGSTATUS_SIG_EXPIRED: - status = _("Expired"); - break; - case ALPM_SIGSTATUS_INVALID: - status = _("Invalid"); - break; - case ALPM_SIGSTATUS_KEY_UNKNOWN: - status = _("Key unknown"); - break; - case ALPM_SIGSTATUS_KEY_DISABLED: - status = _("Key disabled"); - break; - default: - status = _("Signature error"); - break; - } - switch(result->validity) { - case ALPM_SIGVALIDITY_FULL: - validity = _("full trust"); - break; - case ALPM_SIGVALIDITY_MARGINAL: - validity = _("marginal trust"); - break; - case ALPM_SIGVALIDITY_NEVER: - validity = _("never trust"); - break; - case ALPM_SIGVALIDITY_UNKNOWN: - default: - validity = _("unknown trust"); - break; - } - name = result->key.uid ? result->key.uid : result->key.fingerprint; - ret = pm_asprintf(&sigline, _("%s, %s from \"%s\""), - status, validity, name); - if(ret == -1) { - continue; - } - indentprint(sigline, len, maxcols); - printf("\n"); - free(sigline); - } - } -} - -/* creates a header row for use with table_display */ static alpm_list_t *create_verbose_header(void) { alpm_list_t *res = NULL; diff --git a/src/pacman/util.h b/src/pacman/util.h index 690bc1d..2566913 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -55,16 +55,13 @@ void indentprint(const char *str, unsigned short indent, unsigned short cols); size_t strtrim(char *str); char *strreplace(const char *str, const char *needle, const char *replace); alpm_list_t *strsplit(const char *str, const char splitchar); -void string_display(const char *title, const char *string, - unsigned short maxcols); +size_t string_length(const char *s); double humanize_size(off_t bytes, const char target_unit, int precision, const char **label); void list_display(const char *title, const alpm_list_t *list, unsigned short maxcols); void list_display_linebreak(const char *title, const alpm_list_t *list, unsigned short maxcols); -void signature_display(const char *title, alpm_siglist_t *siglist, - unsigned short maxcols); void display_targets(void); int str_cmp(const void *s1, const void *s2); void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg); -- 1.8.2
Use termio.c/h as a new base for pretty printing in pacman. It collects a lot of the low-level code that pacman uses to output tables. Some key changes: - string_length -> grapheme_count This better reflects the intent of the function: to return the number of grapheme's that'll be printed, its not returning the actual string's length. - indentprint -> indentprint_r indentprint_r is a renterant version of indentprint. This allows for indentprint_r to be used in a loop easily to output the contents of a alpm_list_t without special duplicated logic. This version of indentprint should also be a bit cleaner to read and maintain. - Add indent_string/indent_list/indent_list_linebreak These functions print either a string or a list of strings out on the terminal correctly with no fuss. These are intended to be used by pacman to aid in correctly formatting a table. These new functions should replace string_display/list_display/etc eventually. How pacman prints tables needs to be overhauled first. In the meanwhile, however, they still offer some value as they improve and unify unicode support. Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> --- src/pacman/Makefile.am | 1 + src/pacman/callback.c | 1 + src/pacman/package.c | 11 +-- src/pacman/termio.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/termio.h | 17 +++++ src/pacman/util.c | 158 +++----------------------------------- src/pacman/util.h | 2 - 7 files changed, 240 insertions(+), 154 deletions(-) create mode 100644 src/pacman/termio.c create mode 100644 src/pacman/termio.h diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index ed51573..b94e578 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -38,6 +38,7 @@ pacman_SOURCES = \ sync.c \ callback.h callback.c \ upgrade.c \ + termio.h termio.c \ util.h util.c \ util-common.h util-common.c diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 71d9d04..e93ccd2 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -32,6 +32,7 @@ /* pacman */ #include "pacman.h" +#include "termio.h" #include "callback.h" #include "util.h" #include "conf.h" diff --git a/src/pacman/package.c b/src/pacman/package.c index 403896a..5af7586 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -31,6 +31,7 @@ /* pacman */ #include "package.h" +#include "termio.h" #include "util.h" #include "conf.h" @@ -42,14 +43,14 @@ static void string_display(const char *title, const char *string, unsigned short len = 0; if(title) { - len = (unsigned short)string_length(title) + 1; + len = (unsigned short)grapheme_count(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } if(string == NULL || string[0] == '\0') { printf(_("None")); } else { - indentprint(string, (unsigned short)len, maxcols); + indent_string(string, (unsigned short)len, maxcols); } printf("\n"); } @@ -97,7 +98,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist, unsigned short len = 0; if(title) { - len = (unsigned short)string_length(title) + 1; + len = (unsigned short)grapheme_count(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } @@ -158,7 +159,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist, if(ret == -1) { continue; } - indentprint(sigline, len, maxcols); + indent_string(sigline, len, maxcols); printf("\n"); free(sigline); } @@ -513,7 +514,7 @@ int dump_pkg_search(alpm_db_t *db, alpm_list_t *targets, int show_status) /* we need a newline and initial indent first */ fputs("\n ", stdout); - indentprint(alpm_pkg_get_desc(pkg), 4, cols); + indent_string(alpm_pkg_get_desc(pkg), 4, cols); } fputc('\n', stdout); } diff --git a/src/pacman/termio.c b/src/pacman/termio.c new file mode 100644 index 0000000..11d564d --- /dev/null +++ b/src/pacman/termio.c @@ -0,0 +1,204 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <wchar.h> +#include <unistd.h> +#include <sys/ioctl.h> + +/* pacman */ +#include "termio.h" + +/* gets the current screen column width */ +unsigned short getcols(int fd) +{ + const unsigned short default_tty = 80; + const unsigned short default_notty = 0; + unsigned short termwidth = 0; + + if(!isatty(fd)) { + return default_notty; + } + +#if defined(TIOCGSIZE) + struct ttysize win; + if(ioctl(fd, TIOCGSIZE, &win) == 0) { + termwidth = win.ts_cols; + } +#elif defined(TIOCGWINSZ) + struct winsize win; + if(ioctl(fd, TIOCGWINSZ, &win) == 0) { + termwidth = win.ws_col; + } +#endif + return termwidth == 0 ? default_tty : termwidth; +} + +static wchar_t *wide_string(const char *str, size_t *wclen, size_t *graphemes) +{ + wchar_t *wcstr = NULL; + size_t len = 0; + + if(str && str[0] != '\0') { + len = strlen(str) + 1; + wcstr = calloc(len, sizeof(wchar_t)); + len = mbstowcs(wcstr, str, len); + } + + if(wclen) { + *wclen = wcstr ? len : 0; + } + + if(graphemes) { + *graphemes = len ? wcswidth(wcstr, len) : 0; + } + + return wcstr; +} + +size_t grapheme_count(const char *str) +{ + wchar_t *wcstr; + size_t graphemes; + + wcstr = wide_string(str, NULL, &graphemes); + + free(wcstr); + return graphemes; +} + +static wchar_t *indentword_r(wchar_t *wcstr, unsigned short indent, + unsigned short maxcols, unsigned short *cidx) +{ + size_t len; + wchar_t *next; + + /* find the first space, set it to \0 */ + next = wcschr(wcstr, L' '); + if(next != NULL) { + *next++ = L'\0'; + } + + /* calculate the number of columns needed to print the current word */ + len = wcslen(wcstr); + len = wcswidth(wcstr, len); + + /* line is going to be too long, don't even bother trying to wrap it */ + if(len + 1 > maxcols - indent) { + if(*cidx > indent) + printf("\n%-*s", (int)indent, ""); + + printf("%ls", wcstr); + *cidx = maxcols - 1; + return next; + } + + /* if the message is long enough, wrap to a newline and re-indent */ + if(len + 1 > maxcols - *cidx) { + printf("\n%-*s", (int)indent, ""); + *cidx = indent; + } + + /* print the word */ + if(next) { + printf("%ls ", wcstr); + *cidx += len + 1; + } else { + printf("%ls" , wcstr); + *cidx += len; + } + + return next; +} + +static unsigned short indentprint_r(const char *str, unsigned short indent, + unsigned short maxcols, unsigned short cidx) +{ + wchar_t *wcstr; + size_t len; + + if(!str) { + return cidx; + } + + if(cidx < indent) { + cidx = indent; + } + + /* if we're not a tty, or our tty is not wide enough that wrapping even makes + * sense, print without indenting */ + if(maxcols == 0 || indent > maxcols) { + fputs(str, stdout); + return cidx; + } + + /* convert to a wide string */ + wcstr = wide_string(str, NULL, &len); + + /* if it turns out the string will fit, just print it */ + if(len < maxcols - cidx) { + printf("%s", str); + cidx += len; + } else { + wchar_t *buf = wcstr; + while(buf) { + buf = indentword_r(buf, indent, maxcols, &cidx); + } + } + + free(wcstr); + return cidx; +} + +static unsigned short indentpad_r(int pad, unsigned short maxcols, unsigned short cidx) +{ + /* add as many spaces as we can until we hit the right edge of the + * screen */ + if(maxcols) { + while(pad-- && cidx++ < maxcols - 1) { + putchar(' '); + } + } else { + printf("%-*s", pad, ""); + cidx += pad; + } + + return cidx; +} + +void indent_string(const char *str, unsigned short indent, unsigned short maxcols) +{ + indentprint_r(str, indent, maxcols, 0); +} + +void indent_list(const alpm_list_t *list, unsigned short indent, + unsigned short maxcols) +{ + const alpm_list_t *i; + unsigned short cidx = 0; + + for(i = list; i; i = alpm_list_next(i)) { + const char *entry = i->data; + cidx = indentprint_r(entry, indent, maxcols, cidx); + + if(i->next) { + cidx = indentpad_r(2, maxcols, cidx); + } + } +} + +void indent_list_linebreak(const alpm_list_t *list, unsigned short indent, + unsigned short maxcols) +{ + const alpm_list_t *i; + + for(i = list; i; i = alpm_list_next(i)) { + const char *entry = i->data; + indent_string(entry, indent, maxcols); + + if(i->next) { + printf("\n%-*s", (int)indent, ""); + } + } +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/termio.h b/src/pacman/termio.h new file mode 100644 index 0000000..6d0490a --- /dev/null +++ b/src/pacman/termio.h @@ -0,0 +1,17 @@ +#ifndef _PM_TERMIO_H +#define _PM_TERMIO_H + +#include <stddef.h> +#include <alpm_list.h> + +unsigned short getcols(int fd); + +size_t grapheme_count(const char *s); + +void indent_string(const char *str, unsigned short indent, unsigned short maxcols); +void indent_list(const alpm_list_t *list, unsigned short indent, unsigned short maxcols); +void indent_list_linebreak(const alpm_list_t *list, unsigned short indent, unsigned short maxcols); + +#endif /* _PM_TERMIO_H */ + +/* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/util.c b/src/pacman/util.c index c2f0669..062c019 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -43,10 +43,10 @@ /* pacman */ #include "util.h" +#include "termio.h" #include "conf.h" #include "callback.h" - struct table_row_t { const char *label; int size; @@ -147,31 +147,6 @@ static int flush_term_input(int fd) return 0; } -/* gets the current screen column width */ -unsigned short getcols(int fd) -{ - const unsigned short default_tty = 80; - const unsigned short default_notty = 0; - unsigned short termwidth = 0; - - if(!isatty(fd)) { - return default_notty; - } - -#if defined(TIOCGSIZE) - struct ttysize win; - if(ioctl(fd, TIOCGSIZE, &win) == 0) { - termwidth = win.ts_cols; - } -#elif defined(TIOCGWINSZ) - struct winsize win; - if(ioctl(fd, TIOCGWINSZ, &win) == 0) { - termwidth = win.ws_col; - } -#endif - return termwidth == 0 ? default_tty : termwidth; -} - /* does the same thing as 'rm -rf' */ int rmrf(const char *path) { @@ -216,67 +191,6 @@ int rmrf(const char *path) } } -/* output a string, but wrap words properly with a specified indentation - */ -void indentprint(const char *str, unsigned short indent, unsigned short cols) -{ - wchar_t *wcstr; - const wchar_t *p; - size_t len, cidx; - - if(!str) { - return; - } - - /* if we're not a tty, or our tty is not wide enough that wrapping even makes - * sense, print without indenting */ - if(cols == 0 || indent > cols) { - fputs(str, stdout); - return; - } - - len = strlen(str) + 1; - wcstr = calloc(len, sizeof(wchar_t)); - len = mbstowcs(wcstr, str, len); - p = wcstr; - cidx = indent; - - if(!p || !len) { - return; - } - - while(*p) { - if(*p == L' ') { - const wchar_t *q, *next; - p++; - if(p == NULL || *p == L' ') continue; - next = wcschr(p, L' '); - if(next == NULL) { - next = p + wcslen(p); - } - /* len captures # cols */ - len = 0; - q = p; - while(q < next) { - len += wcwidth(*q++); - } - if((len + 1) > (cols - cidx)) { - /* wrap to a newline and reindent */ - printf("\n%-*s", (int)indent, ""); - cidx = indent; - } else { - printf(" "); - cidx++; - } - continue; - } - printf("%lc", (wint_t)*p); - cidx += wcwidth(*p); - p++; - } - free(wcstr); -} - /* Trim whitespace and newlines from a string */ size_t strtrim(char *str) @@ -406,24 +320,6 @@ alpm_list_t *strsplit(const char *str, const char splitchar) return list; } -size_t string_length(const char *s) -{ - int len; - wchar_t *wcstr; - - if(!s || s[0] == '\0') { - return 0; - } - /* len goes from # bytes -> # chars -> # cols */ - len = strlen(s) + 1; - wcstr = calloc(len, sizeof(wchar_t)); - len = mbstowcs(wcstr, s, len); - len = wcswidth(wcstr, len); - free(wcstr); - - return len; -} - static void table_print_line(const alpm_list_t *line, short col_padding, size_t colcount, size_t *widths, int *has_data) { @@ -452,7 +348,7 @@ static void table_print_line(const alpm_list_t *line, short col_padding, value = ""; } /* silly printf requires padding size to be an int */ - cell_padding = (int)widths[i] - (int)string_length(value); + cell_padding = (int)widths[i] - (int)grapheme_count(value); if(cell_padding < 0) { cell_padding = 0; } @@ -505,7 +401,7 @@ static size_t table_calc_widths(const alpm_list_t *header, } /* header determines column count and initial values of longest_strs */ for(i = header, curcol = 0; i; i = alpm_list_next(i), curcol++) { - colwidths[curcol] = string_length(i->data); + colwidths[curcol] = grapheme_count(i->data); /* note: header does not determine whether column has data */ } @@ -515,7 +411,7 @@ static size_t table_calc_widths(const alpm_list_t *header, const alpm_list_t *j = i->data; for(curcol = 0; j; j = alpm_list_next(j), curcol++) { const char *str = j->data; - size_t str_len = string_length(str); + size_t str_len = grapheme_count(str); if(str_len > colwidths[curcol]) { colwidths[curcol] = str_len; @@ -601,38 +497,14 @@ void list_display(const char *title, const alpm_list_t *list, unsigned short len = 0; if(title) { - len = (unsigned short)string_length(title) + 1; + len = (unsigned short)grapheme_count(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } if(!list) { printf("%s\n", _("None")); } else { - const alpm_list_t *i; - const char *str = list->data; - size_t cols = len; - - fputs(str, stdout); - cols += string_length(str); - for(i = alpm_list_next(list); i; i = alpm_list_next(i)) { - str = i->data; - size_t s = string_length(str); - /* wrap only if we have enough usable column space */ - if(maxcols > len && cols + s + 2 >= maxcols) { - size_t j; - cols = len; - printf("\n"); - for(j = 1; j <= len; j++) { - printf(" "); - } - } else if(cols != len) { - /* 2 spaces are added if this is not the first element on a line. */ - printf(" "); - cols += 2; - } - fputs(str, stdout); - cols += s; - } + indent_list(list, len, maxcols); putchar('\n'); } } @@ -643,25 +515,17 @@ void list_display_linebreak(const char *title, const alpm_list_t *list, unsigned short len = 0; if(title) { - len = (unsigned short)string_length(title) + 1; + len = (unsigned short)grapheme_count(title) + 1; printf("%s%s%s ", config->colstr.title, title, config->colstr.nocolor); } if(!list) { printf("%s\n", _("None")); } else { - const alpm_list_t *i; - - /* Print the first element */ - indentprint((const char *)list->data, len, maxcols); - printf("\n"); - /* Print the rest */ - for(i = alpm_list_next(list); i; i = alpm_list_next(i)) { - printf("%-*s", (int)len, ""); - indentprint((const char *)i->data, len, maxcols); - printf("\n"); - } + indent_list_linebreak(list, len, maxcols); + putchar('\n'); } + } static alpm_list_t *create_verbose_header(void) @@ -750,7 +614,7 @@ static void display_transaction_sizes(alpm_list_t *table) for(i = table; i; i = alpm_list_next(i)) { struct table_row_t *row = i->data; - int len = string_length(row->label); + int len = grapheme_count(row->label); if(len > max_len) max_len = len; diff --git a/src/pacman/util.h b/src/pacman/util.h index 2566913..ff405c4 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -49,9 +49,7 @@ int trans_init(alpm_transflag_t flags, int check_valid); int trans_release(void); int needs_root(void); int check_syncdbs(size_t need_repos, int check_valid); -unsigned short getcols(int fd); int rmrf(const char *path); -void indentprint(const char *str, unsigned short indent, unsigned short cols); size_t strtrim(char *str); char *strreplace(const char *str, const char *needle, const char *replace); alpm_list_t *strsplit(const char *str, const char splitchar); -- 1.8.2
On 27/03/13 03:39, Simon Gomizelj wrote:
Signed-off-by: Simon Gomizelj <simongmzlj@gmail.com> ---
Ack-by: Allan
participants (2)
-
Allan McRae
-
Simon Gomizelj