summaryrefslogtreecommitdiff
path: root/src/pacman/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r--src/pacman/util.c393
1 files changed, 253 insertions, 140 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c
index f7f8ecf5..7f7f6a74 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -18,12 +18,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
-#include <sys/time.h>
+#include <time.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,7 +63,7 @@ int trans_init(alpm_transflag_t flags, int check_valid)
void trans_init_error(void)
{
- enum _alpm_errno_t err = alpm_errno(config->handle);
+ alpm_errno_t err = alpm_errno(config->handle);
pm_printf(ALPM_LOG_ERROR, _("failed to init transaction (%s)\n"),
alpm_strerror(err));
if(err == ALPM_ERR_HANDLE_LOCK) {
@@ -110,7 +108,7 @@ int check_syncdbs(size_t need_repos, int check_valid)
{
int ret = 0;
alpm_list_t *i;
- alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle);
+ alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle);
if(need_repos && sync_dbs == NULL) {
pm_printf(ALPM_LOG_ERROR, _("no usable package repositories configured.\n"));
@@ -132,10 +130,10 @@ int check_syncdbs(size_t need_repos, int check_valid)
}
/* discard unhandled input on the terminal's input buffer */
-static int flush_term_input(void) {
+static int flush_term_input(int fd) {
#ifdef HAVE_TCFLUSH
- if(isatty(fileno(stdin))) {
- return tcflush(fileno(stdin), TCIFLUSH);
+ if(isatty(fd)) {
+ return tcflush(fd, TCIFLUSH);
}
#endif
@@ -144,24 +142,24 @@ static int flush_term_input(void) {
}
/* gets the current screen column width */
-unsigned short getcols(void)
+unsigned short getcols(int fd)
{
const unsigned short default_tty = 80;
const unsigned short default_notty = 0;
unsigned short termwidth = 0;
- if(!isatty(fileno(stdout))) {
+ if(!isatty(fd)) {
return default_notty;
}
-#ifdef TIOCGSIZE
+#if defined(TIOCGSIZE)
struct ttysize win;
- if(ioctl(1, TIOCGSIZE, &win) == 0) {
+ if(ioctl(fd, TIOCGSIZE, &win) == 0) {
termwidth = win.ts_cols;
}
#elif defined(TIOCGWINSZ)
struct winsize win;
- if(ioctl(1, TIOCGWINSZ, &win) == 0) {
+ if(ioctl(fd, TIOCGWINSZ, &win) == 0) {
termwidth = win.ws_col;
}
#endif
@@ -256,12 +254,11 @@ char *mdirname(const char *path)
/* output a string, but wrap words properly with a specified indentation
*/
-void indentprint(const char *str, size_t indent)
+void indentprint(const char *str, unsigned short indent, unsigned short cols)
{
wchar_t *wcstr;
const wchar_t *p;
- int len, cidx;
- const unsigned short cols = getcols();
+ size_t len, cidx;
if(!str) {
return;
@@ -270,7 +267,7 @@ void indentprint(const char *str, size_t indent)
/* 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) {
- printf("%s", str);
+ fputs(str, stdout);
return;
}
@@ -318,13 +315,13 @@ void indentprint(const char *str, size_t indent)
/* Trim whitespace and newlines from a string
*/
-char *strtrim(char *str)
+size_t strtrim(char *str)
{
- char *pch = str;
+ char *end, *pch = str;
if(str == NULL || *str == '\0') {
/* string is empty, so we're done. */
- return str;
+ return 0;
}
while(isspace((unsigned char)*pch)) {
@@ -341,16 +338,16 @@ char *strtrim(char *str)
/* check if there wasn't anything but whitespace in the string. */
if(*str == '\0') {
- return str;
+ return 0;
}
- pch = (str + (strlen(str) - 1));
- while(isspace((unsigned char)*pch)) {
- pch--;
+ end = (str + strlen(str) - 1);
+ while(isspace((unsigned char)*end)) {
+ end--;
}
- *++pch = '\0';
+ *++end = '\0';
- return str;
+ return end - pch;
}
/* Replace all occurances of 'needle' with 'replace' in 'str', returning
@@ -391,7 +388,7 @@ char *strreplace(const char *str, const char *needle, const char *replace)
p = str;
newp = newstr;
for(i = list; i; i = alpm_list_next(i)) {
- q = alpm_list_getdata(i);
+ q = i->data;
if(q > p) {
/* add chars between this occurence and last occurence, if any */
memcpy(newp, p, (size_t)(q - p));
@@ -463,7 +460,7 @@ static size_t string_length(const char *s)
return len;
}
-void string_display(const char *title, const char *string)
+void string_display(const char *title, const char *string, unsigned short cols)
{
if(title) {
printf("%s ", title);
@@ -473,82 +470,128 @@ void string_display(const char *title, const char *string)
} else {
/* compute the length of title + a space */
size_t len = string_length(title) + 1;
- indentprint(string, len);
+ indentprint(string, (unsigned short)len, cols);
}
printf("\n");
}
-static void table_print_line(const alpm_list_t *line,
- size_t colcount, size_t *widths)
+static void table_print_line(const alpm_list_t *line, short col_padding,
+ size_t colcount, size_t *widths, int *has_data)
{
- size_t i;
+ size_t i, lastcol = 0;
+ int need_padding = 0;
const alpm_list_t *curcell;
+ for(i = colcount; i > 0; i--) {
+ if(has_data[i - 1]) {
+ lastcol = i - 1;
+ break;
+ }
+ }
+
for(i = 0, curcell = line; curcell && i < colcount;
i++, curcell = alpm_list_next(curcell)) {
- const char *value = curcell->data;
- size_t len = string_length(value);
+ const char *value;
+ int cell_padding;
+
+ if(!has_data[i]) {
+ continue;
+ }
+
+ value = curcell->data;
+ if(!value) {
+ value = "";
+ }
/* silly printf requires padding size to be an int */
- int padding = (int)widths[i] - (int)len;
- if(padding < 0) {
- padding = 0;
+ cell_padding = (int)widths[i] - (int)string_length(value);
+ if(cell_padding < 0) {
+ cell_padding = 0;
+ }
+ if(need_padding) {
+ printf("%*s", col_padding, "");
}
/* left-align all but the last column */
- if(i + 1 < colcount) {
- printf("%s%*s", value, padding, "");
+ if(i != lastcol) {
+ printf("%s%*s", value, cell_padding, "");
} else {
- printf("%*s%s", padding, "", value);
+ printf("%*s%s", cell_padding, "", value);
}
+ need_padding = 1;
}
printf("\n");
}
-/* find the max string width of each column */
+
+
+/**
+ * Find the max string width of each column. Also determines whether values
+ * exist in the column and sets the value in has_data accordingly.
+ * @param header a list of header strings
+ * @param rows a list of lists of rows as strings
+ * @param padding the amount of padding between columns
+ * @param totalcols the total number of columns in the header and each row
+ * @param widths a pointer to store width data
+ * @param has_data a pointer to store whether column has data
+ *
+ * @return the total width of the table; 0 on failure
+ */
static size_t table_calc_widths(const alpm_list_t *header,
- const alpm_list_t *rows, size_t totalcols, size_t **widths)
+ const alpm_list_t *rows, short padding, size_t totalcols,
+ size_t **widths, int **has_data)
{
const alpm_list_t *i;
- const unsigned short padding = 2;
- size_t curcol, totalwidth = 0;
+ size_t curcol, totalwidth = 0, usefulcols = 0;
size_t *colwidths;
+ int *coldata;
if(totalcols <= 0) {
return 0;
}
colwidths = malloc(totalcols * sizeof(size_t));
- if(!colwidths) {
+ coldata = calloc(totalcols, sizeof(int));
+ if(!colwidths || !coldata) {
return 0;
}
/* 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(alpm_list_getdata(i));
+ colwidths[curcol] = string_length(i->data);
+ /* note: header does not determine whether column has data */
}
/* now find the longest string in each column */
for(i = rows; i; i = alpm_list_next(i)) {
/* grab first column of each row and iterate through columns */
- const alpm_list_t *j = alpm_list_getdata(i);
+ const alpm_list_t *j = i->data;
for(curcol = 0; j; j = alpm_list_next(j), curcol++) {
- char *str = alpm_list_getdata(j);
+ const char *str = j->data;
size_t str_len = string_length(str);
if(str_len > colwidths[curcol]) {
colwidths[curcol] = str_len;
}
+ if(str_len > 0) {
+ coldata[curcol] = 1;
+ }
}
}
for(i = header, curcol = 0; i; i = alpm_list_next(i), curcol++) {
- /* pad everything but the last column */
- if(curcol + 1 < totalcols) {
- colwidths[curcol] += padding;
+ /* only include columns that have data */
+ if(coldata[curcol]) {
+ usefulcols++;
+ totalwidth += colwidths[curcol];
}
- totalwidth += colwidths[curcol];
+ }
+
+ /* add padding between columns */
+ if(usefulcols > 0) {
+ totalwidth += padding * (usefulcols - 1);
}
*widths = colwidths;
+ *has_data = coldata;
return totalwidth;
}
@@ -559,28 +602,31 @@ static size_t table_calc_widths(const alpm_list_t *header,
* of headers
* @param rows the rows to display as a list of lists of strings. the outer
* list represents the rows, the inner list the cells (= columns)
- *
+ * @param cols the number of columns available in the terminal
* @return -1 if not enough terminal cols available, else 0
*/
-int table_display(const char *title, const alpm_list_t *header,
- const alpm_list_t *rows)
+static int table_display(const char *title, const alpm_list_t *header,
+ const alpm_list_t *rows, unsigned short cols)
{
+ const unsigned short padding = 2;
const alpm_list_t *i;
size_t *widths = NULL, totalcols, totalwidth;
+ int *has_data = NULL;
if(rows == NULL || header == NULL) {
return 0;
}
totalcols = alpm_list_count(header);
- totalwidth = table_calc_widths(header, rows, totalcols, &widths);
+ totalwidth = table_calc_widths(header, rows, padding, totalcols,
+ &widths, &has_data);
/* return -1 if terminal is not wide enough */
- if(totalwidth > getcols()) {
+ if(totalwidth > cols) {
pm_printf(ALPM_LOG_WARNING,
_("insufficient columns available for table display\n"));
return -1;
}
- if(!totalwidth || !widths) {
+ if(!totalwidth || !widths || !has_data) {
return -1;
}
@@ -588,18 +634,20 @@ int table_display(const char *title, const alpm_list_t *header,
printf("%s\n\n", title);
}
- table_print_line(header, totalcols, widths);
+ table_print_line(header, padding, totalcols, widths, has_data);
printf("\n");
for(i = rows; i; i = alpm_list_next(i)) {
- table_print_line(alpm_list_getdata(i), totalcols, widths);
+ table_print_line(i->data, padding, totalcols, widths, has_data);
}
free(widths);
+ free(has_data);
return 0;
}
-void list_display(const char *title, const alpm_list_t *list)
+void list_display(const char *title, const alpm_list_t *list,
+ unsigned short maxcols)
{
const alpm_list_t *i;
size_t len = 0;
@@ -612,20 +660,19 @@ void list_display(const char *title, const alpm_list_t *list)
if(!list) {
printf("%s\n", _("None"));
} else {
- const unsigned short maxcols = getcols();
size_t cols = len;
- const char *str = alpm_list_getdata(list);
- printf("%s", str);
+ const char *str = list->data;
+ fputs(str, stdout);
cols += string_length(str);
for(i = alpm_list_next(list); i; i = alpm_list_next(i)) {
- str = alpm_list_getdata(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++) {
+ for(j = 1; j <= len; j++) {
printf(" ");
}
} else if(cols != len) {
@@ -633,19 +680,20 @@ void list_display(const char *title, const alpm_list_t *list)
printf(" ");
cols += 2;
}
- printf("%s", str);
+ fputs(str, stdout);
cols += s;
}
- printf("\n");
+ putchar('\n');
}
}
-void list_display_linebreak(const char *title, const alpm_list_t *list)
+void list_display_linebreak(const char *title, const alpm_list_t *list,
+ unsigned short maxcols)
{
- size_t len = 0;
+ unsigned short len = 0;
if(title) {
- len = string_length(title) + 1;
+ len = (unsigned short)string_length(title) + 1;
printf("%s ", title);
}
@@ -654,7 +702,7 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
} else {
const alpm_list_t *i;
/* Print the first element */
- indentprint((const char *) alpm_list_getdata(list), len);
+ indentprint((const char *)list->data, len, maxcols);
printf("\n");
/* Print the rest */
for(i = alpm_list_next(list); i; i = alpm_list_next(i)) {
@@ -662,18 +710,19 @@ void list_display_linebreak(const char *title, const alpm_list_t *list)
for(j = 1; j <= len; j++) {
printf(" ");
}
- indentprint((const char *) alpm_list_getdata(i), len);
+ indentprint((const char *)i->data, len, maxcols);
printf("\n");
}
}
}
-void signature_display(const char *title, alpm_siglist_t *siglist)
+void signature_display(const char *title, alpm_siglist_t *siglist,
+ unsigned short maxcols)
{
- size_t len = 0;
+ unsigned short len = 0;
if(title) {
- len = string_length(title) + 1;
+ len = (unsigned short)string_length(title) + 1;
printf("%s ", title);
}
if(siglist->count == 0) {
@@ -737,7 +786,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist)
pm_printf(ALPM_LOG_ERROR, _("failed to allocate string\n"));
continue;
}
- indentprint(sigline, len);
+ indentprint(sigline, len, maxcols);
printf("\n");
free(sigline);
}
@@ -745,7 +794,7 @@ void signature_display(const char *title, alpm_siglist_t *siglist)
}
/* creates a header row for use with table_display */
-static alpm_list_t *create_verbose_header(int dl_size)
+static alpm_list_t *create_verbose_header(void)
{
alpm_list_t *res = NULL;
char *str;
@@ -758,16 +807,14 @@ static alpm_list_t *create_verbose_header(int dl_size)
res = alpm_list_add(res, str);
str = _("Net Change");
res = alpm_list_add(res, str);
- if(dl_size) {
- str = _("Download Size");
- res = alpm_list_add(res, str);
- }
+ str = _("Download Size");
+ res = alpm_list_add(res, str);
return res;
}
/* returns package info as list of strings */
-static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
+static alpm_list_t *create_verbose_row(pm_target_t *target)
{
char *str;
off_t size = 0;
@@ -777,7 +824,12 @@ static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
/* a row consists of the package name, */
if(target->install) {
- pm_asprintf(&str, "%s", alpm_pkg_get_name(target->install));
+ const alpm_db_t *db = alpm_pkg_get_db(target->install);
+ if(db) {
+ pm_asprintf(&str, "%s/%s", alpm_db_get_name(db), alpm_pkg_get_name(target->install));
+ } else {
+ pm_asprintf(&str, "%s", alpm_pkg_get_name(target->install));
+ }
} else {
pm_asprintf(&str, "%s", alpm_pkg_get_name(target->remove));
}
@@ -799,16 +851,14 @@ static alpm_list_t *create_verbose_row(pm_target_t *target, int dl_size)
pm_asprintf(&str, "%.2f %s", human_size, label);
ret = alpm_list_add(ret, str);
- if(dl_size) {
- size = target->install ? alpm_pkg_download_size(target->install) : 0;
+ size = target->install ? alpm_pkg_download_size(target->install) : 0;
+ if(size != 0) {
human_size = humanize_size(size, 'M', 2, &label);
- if(size != 0) {
- pm_asprintf(&str, "%.2f %s", human_size, label);
- } else {
- str = strdup("");
- }
- ret = alpm_list_add(ret, str);
+ pm_asprintf(&str, "%.2f %s", human_size, label);
+ } else {
+ str = NULL;
}
+ ret = alpm_list_add(ret, str);
return ret;
}
@@ -820,8 +870,8 @@ static void _display_targets(alpm_list_t *targets, int verbose)
const char *label;
double size;
off_t isize = 0, rsize = 0, dlsize = 0;
+ unsigned short cols;
alpm_list_t *i, *rows = NULL, *names = NULL;
- int show_dl_size = config->op == PM_OP_SYNC;
if(!targets) {
return;
@@ -829,7 +879,7 @@ static void _display_targets(alpm_list_t *targets, int verbose)
/* gather package info */
for(i = targets; i; i = alpm_list_next(i)) {
- pm_target_t *target = alpm_list_getdata(i);
+ pm_target_t *target = i->data;
if(target->install) {
dlsize += alpm_pkg_download_size(target->install);
@@ -845,7 +895,7 @@ static void _display_targets(alpm_list_t *targets, int verbose)
for(i = targets; i; i = alpm_list_next(i)) {
pm_target_t *target = i->data;
- rows = alpm_list_add(rows, create_verbose_row(target, show_dl_size));
+ rows = alpm_list_add(rows, create_verbose_row(target));
if(target->install) {
pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
alpm_pkg_get_version(target->install));
@@ -860,24 +910,25 @@ static void _display_targets(alpm_list_t *targets, int verbose)
}
/* print to screen */
- pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets));
-
+ pm_asprintf(&str, _("Packages (%d):"), alpm_list_count(targets));
printf("\n");
+
+ cols = getcols(fileno(stdout));
if(verbose) {
- alpm_list_t *header = create_verbose_header(show_dl_size);
- if(table_display(str, header, rows) != 0) {
+ alpm_list_t *header = create_verbose_header();
+ if(table_display(str, header, rows, cols) != 0) {
/* fallback to list display if table wouldn't fit */
- list_display(str, names);
+ list_display(str, names, cols);
}
alpm_list_free(header);
} else {
- list_display(str, names);
+ list_display(str, names, cols);
}
printf("\n");
/* rows is a list of lists of strings, free inner lists here */
for(i = rows; i; i = alpm_list_next(i)) {
- alpm_list_t *lp = alpm_list_getdata(i);
+ alpm_list_t *lp = i->data;
FREELIST(lp);
}
alpm_list_free(rows);
@@ -931,10 +982,10 @@ static int pkg_cmp(const void *p1, const void *p2)
void display_targets(void)
{
alpm_list_t *i, *targets = NULL;
- alpm_db_t *db_local = alpm_option_get_localdb(config->handle);
+ alpm_db_t *db_local = alpm_get_localdb(config->handle);
for(i = alpm_trans_get_add(config->handle); i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
pm_target_t *targ = calloc(1, sizeof(pm_target_t));
if(!targ) return;
targ->install = pkg;
@@ -945,7 +996,7 @@ void display_targets(void)
targets = alpm_list_add(targets, targ);
}
for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
pm_target_t *targ = calloc(1, sizeof(pm_target_t));
if(!targ) return;
targ->remove = pkg;
@@ -980,7 +1031,7 @@ static char *pkg_get_location(alpm_pkg_t *pkg)
case PM_OP_SYNC:
servers = alpm_db_get_servers(alpm_pkg_get_db(pkg));
if(servers) {
- pm_asprintf(&string, "%s/%s", alpm_list_getdata(servers),
+ pm_asprintf(&string, "%s/%s", servers->data,
alpm_pkg_get_filename(pkg));
return string;
}
@@ -1054,7 +1105,7 @@ void print_packages(const alpm_list_t *packages)
config->print_format = strdup("%l");
}
for(i = packages; i; i = alpm_list_next(i)) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ alpm_pkg_t *pkg = i->data;
char *string = strdup(config->print_format);
char *temp = string;
/* %n : pkgname */
@@ -1096,46 +1147,104 @@ void print_packages(const alpm_list_t *packages)
free(size);
free(temp);
}
- printf("%s\n",string);
+ printf("%s\n", string);
free(string);
}
}
-/* Helper function for comparing strings using the
- * alpm "compare func" signature */
-int str_cmp(const void *s1, const void *s2)
+/**
+ * Helper function for comparing depends using the alpm "compare func"
+ * signature. The function descends through the structure in the following
+ * comparison order: name, modifier (e.g., '>', '='), version, description.
+ * @param d1 the first depend structure
+ * @param d2 the second depend structure
+ * @return -1, 0, or 1 if first is <, ==, or > second
+ */
+static int depend_cmp(const void *d1, const void *d2)
{
- return strcmp(s1, s2);
+ const alpm_depend_t *dep1 = d1;
+ const alpm_depend_t *dep2 = d2;
+ int ret;
+
+ ret = strcmp(dep1->name, dep2->name);
+ if(ret == 0) {
+ ret = dep1->mod - dep2->mod;
+ }
+ if(ret == 0) {
+ if(dep1->version && dep2->version) {
+ ret = strcmp(dep1->version, dep2->version);
+ } else if(!dep1->version && dep2->version) {
+ ret = -1;
+ } else if(dep1->version && !dep2->version) {
+ ret = 1;
+ }
+ }
+ if(ret == 0) {
+ if(dep1->desc && dep2->desc) {
+ ret = strcmp(dep1->desc, dep2->desc);
+ } else if(!dep1->desc && dep2->desc) {
+ ret = -1;
+ } else if(dep1->desc && !dep2->desc) {
+ ret = 1;
+ }
+ }
+
+ return ret;
}
void display_new_optdepends(alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
{
- alpm_list_t *old = alpm_pkg_get_optdepends(oldpkg);
- alpm_list_t *new = alpm_pkg_get_optdepends(newpkg);
- alpm_list_t *optdeps = alpm_list_diff(new,old,str_cmp);
- if(optdeps) {
+ alpm_list_t *i, *old, *new, *optdeps, *optstrings = NULL;
+
+ old = alpm_pkg_get_optdepends(oldpkg);
+ new = alpm_pkg_get_optdepends(newpkg);
+ optdeps = alpm_list_diff(new, old, depend_cmp);
+
+ /* turn optdepends list into a text list */
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *optdep = i->data;
+ optstrings = alpm_list_add(optstrings, alpm_dep_compute_string(optdep));
+ }
+
+ if(optstrings) {
printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
- list_display_linebreak(" ", optdeps);
+ unsigned short cols = getcols(fileno(stdout));
+ list_display_linebreak(" ", optstrings, cols);
}
+
alpm_list_free(optdeps);
+ FREELIST(optstrings);
}
void display_optdepends(alpm_pkg_t *pkg)
{
- alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
- if(optdeps) {
+ alpm_list_t *i, *optdeps, *optstrings = NULL;
+
+ optdeps = alpm_pkg_get_optdepends(pkg);
+
+ /* turn optdepends list into a text list */
+ for(i = optdeps; i; i = alpm_list_next(i)) {
+ alpm_depend_t *optdep = i->data;
+ optstrings = alpm_list_add(optstrings, alpm_dep_compute_string(optdep));
+ }
+
+ if(optstrings) {
printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
- list_display_linebreak(" ", optdeps);
+ unsigned short cols = getcols(fileno(stdout));
+ list_display_linebreak(" ", optstrings, cols);
}
+
+ FREELIST(optstrings);
}
-static void display_repo_list(const char *dbname, alpm_list_t *list)
+static void display_repo_list(const char *dbname, alpm_list_t *list,
+ unsigned short cols)
{
const char *prefix= " ";
printf(":: ");
printf(_("Repository %s\n"), dbname);
- list_display(prefix, list);
+ list_display(prefix, list, cols);
}
void select_display(const alpm_list_t *pkglist)
@@ -1145,15 +1254,16 @@ void select_display(const alpm_list_t *pkglist)
alpm_list_t *list = NULL;
char *string = NULL;
const char *dbname = NULL;
+ unsigned short cols = getcols(fileno(stdout));
- for (i = pkglist; i; i = i->next) {
- alpm_pkg_t *pkg = alpm_list_getdata(i);
+ for(i = pkglist; i; i = i->next) {
+ alpm_pkg_t *pkg = i->data;
alpm_db_t *db = alpm_pkg_get_db(pkg);
if(!dbname)
dbname = alpm_db_get_name(db);
if(strcmp(alpm_db_get_name(db), dbname) != 0) {
- display_repo_list(dbname, list);
+ display_repo_list(dbname, list, cols);
FREELIST(list);
dbname = alpm_db_get_name(db);
}
@@ -1162,7 +1272,7 @@ void select_display(const alpm_list_t *pkglist)
list = alpm_list_add(list, string);
nth++;
}
- display_repo_list(dbname, list);
+ display_repo_list(dbname, list, cols);
FREELIST(list);
}
@@ -1189,17 +1299,17 @@ static int multiselect_parse(char *array, int count, char *response)
{
char *str, *saveptr;
- for (str = response; ; str = NULL) {
+ for(str = response; ; str = NULL) {
int include = 1;
int start, end;
+ size_t len;
char *ends = NULL;
- char *starts = strtok_r(str, " ", &saveptr);
+ char *starts = strtok_r(str, " ,", &saveptr);
if(starts == NULL) {
break;
}
- strtrim(starts);
- int len = strlen(starts);
+ len = strtrim(starts);
if(len == 0)
continue;
@@ -1274,10 +1384,11 @@ int multiselect_question(char *array, int count)
break;
}
- flush_term_input();
+ flush_term_input(fileno(stdin));
if(fgets(response, response_len, stdin)) {
const size_t response_incr = 64;
+ size_t len;
/* handle buffer not being large enough to read full line case */
while(*lastchar == '\0' && lastchar[-1] != '\n') {
response_len += response_incr;
@@ -1294,8 +1405,9 @@ int multiselect_question(char *array, int count)
return -1;
}
}
- strtrim(response);
- if(strlen(response) > 0) {
+
+ len = strtrim(response);
+ if(len > 0) {
if(multiselect_parse(array, count, response) == -1) {
/* only loop if user gave an invalid answer */
continue;
@@ -1335,11 +1447,11 @@ int select_question(int count)
break;
}
- flush_term_input();
+ flush_term_input(fileno(stdin));
if(fgets(response, sizeof(response), stdin)) {
- strtrim(response);
- if(strlen(response) > 0) {
+ size_t len = strtrim(response);
+ if(len > 0) {
int n;
if(parseindex(response, &n, 1, count) != 0)
continue;
@@ -1358,6 +1470,7 @@ static int question(short preset, char *fmt, va_list args)
{
char response[32];
FILE *stream;
+ int fd_in = fileno(stdin);
if(config->noconfirm) {
stream = stdout;
@@ -1384,17 +1497,17 @@ static int question(short preset, char *fmt, va_list args)
}
fflush(stream);
- flush_term_input();
+ flush_term_input(fd_in);
if(fgets(response, sizeof(response), stdin)) {
- strtrim(response);
- if(strlen(response) == 0) {
+ size_t len = strtrim(response);
+ if(len == 0) {
return preset;
}
/* if stdin is piped, response does not get printed out, and as a result
* a \n is missing, resulting in broken output (FS#27909) */
- if(!isatty(fileno(stdin))) {
+ if(!isatty(fd_in)) {
fprintf(stream, "%s\n", response);
}