summaryrefslogtreecommitdiffstats
path: root/src/pacman/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r--src/pacman/util.c188
1 files changed, 120 insertions, 68 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c
index b9ee8c9c..467bedfe 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) {
@@ -266,7 +264,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;
}
@@ -327,13 +325,13 @@ char *strtoupper(char *str)
/* 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)) {
@@ -350,16 +348,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
@@ -400,7 +398,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));
@@ -487,77 +485,120 @@ void string_display(const char *title, const char *string)
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;
/* 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;
}
@@ -574,22 +615,25 @@ static size_t table_calc_widths(const alpm_list_t *header,
int table_display(const char *title, const alpm_list_t *header,
const alpm_list_t *rows)
{
+ 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()) {
pm_printf(ALPM_LOG_WARNING,
_("insufficient columns available for table display\n"));
return -1;
}
- if(!totalwidth || !widths) {
+ if(!totalwidth || !widths || !has_data) {
return -1;
}
@@ -597,14 +641,15 @@ 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;
}
@@ -623,18 +668,18 @@ void list_display(const char *title, const alpm_list_t *list)
} 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) {
@@ -642,10 +687,10 @@ 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');
}
}
@@ -663,7 +708,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);
printf("\n");
/* Print the rest */
for(i = alpm_list_next(list); i; i = alpm_list_next(i)) {
@@ -671,7 +716,7 @@ 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);
printf("\n");
}
}
@@ -786,7 +831,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));
}
@@ -838,7 +888,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);
@@ -882,7 +932,7 @@ static void _display_targets(alpm_list_t *targets, int verbose)
/* 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);
@@ -939,7 +989,7 @@ void display_targets(void)
alpm_db_t *db_local = alpm_option_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;
@@ -950,7 +1000,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;
@@ -985,7 +1035,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;
}
@@ -1040,7 +1090,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 */
@@ -1132,8 +1182,8 @@ void select_display(const alpm_list_t *pkglist)
char *string = NULL;
const char *dbname = NULL;
- 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)
@@ -1175,17 +1225,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);
if(starts == NULL) {
break;
}
- strtrim(starts);
- int len = strlen(starts);
+ len = strtrim(starts);
if(len == 0)
continue;
@@ -1264,6 +1314,7 @@ int multiselect_question(char *array, int count)
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;
@@ -1280,8 +1331,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;
@@ -1324,8 +1376,8 @@ int select_question(int count)
flush_term_input();
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;
@@ -1373,8 +1425,8 @@ static int question(short preset, char *fmt, va_list args)
flush_term_input();
if(fgets(response, sizeof(response), stdin)) {
- strtrim(response);
- if(strlen(response) == 0) {
+ size_t len = strtrim(response);
+ if(len == 0) {
return preset;
}