[pacman-dev] [PATCH 00/11] [RFC] Pacman Color
I wanted to fix up the pacman-color patch from the aur, as suggested by Allan. And I decided to put all of the seperate color commands into color.c . Not being very experienced in C, please feel free to be as nitpicky as you want, I did this mostly for the learning experience, as well as to start cleaning up the patch. Thanks Daniel Wallace (11): load color into config Add color commands for stuff in util Load color configs add color to callback add color to package.c Add color to pacman.c add color to query.c Add color to remove.c Add color to sync.c Add empty config file Document color contrib/bash_completion.in | 2 +- contrib/zsh_completion.in | 1 + doc/pacman.8.txt | 3 + etc/Makefile.am | 5 +- etc/color.conf.in | 46 +++ etc/pacman.conf.in | 1 + src/pacman/Makefile.am | 3 + src/pacman/callback.c | 164 ++++++++-- src/pacman/color.c | 796 +++++++++++++++++++++++++++++++++++++++++++++ src/pacman/color.h | 77 +++++ src/pacman/conf.c | 5 + src/pacman/conf.h | 6 +- src/pacman/package.c | 190 ++++++++--- src/pacman/pacman.c | 85 +++-- src/pacman/query.c | 57 +++- src/pacman/remove.c | 7 +- src/pacman/sync.c | 151 +++++++-- src/pacman/util.c | 35 +- src/pacman/util.h | 6 + 19 files changed, 1467 insertions(+), 173 deletions(-) create mode 100644 etc/color.conf.in create mode 100644 src/pacman/color.c create mode 100644 src/pacman/color.h -- 1.7.11.4
Tell pacman to print with colors Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/conf.c | 3 +++ src/pacman/conf.h | 5 ++++- src/pacman/pacman.c | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/pacman/conf.c b/src/pacman/conf.c index f47b92d..3b3d3df 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -404,6 +404,9 @@ static int _parse_options(const char *key, char *value, pm_printf(ALPM_LOG_DEBUG, "config: totaldownload\n"); } else if(strcmp(key, "CheckSpace") == 0) { config->checkspace = 1; + } else if (strcmp(key, "Color") == 0) { + config->color = 1; + pm_printf(ALPM_LOG_DEBUG, "config: color\n"); } else { pm_printf(ALPM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 69c955e..3e17155 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -76,6 +76,8 @@ typedef struct __config_t { /* conf file options */ /* I Love Candy! */ unsigned short chomp; + /* Add color */ + unsigned short color; /* format target pkg lists as table */ unsigned short verbosepkglists; /* When downloading, display the amount downloaded, rate, ETA, and percent @@ -127,7 +129,8 @@ enum { OP_PRINTFORMAT, OP_GPGDIR, OP_DBONLY, - OP_FORCE + OP_FORCE, + OP_COLOR }; /* clean method */ diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 73d5be9..732d7f3 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -196,6 +196,7 @@ static void usage(int op, const char * const myname) addlist(_(" -v, --verbose be verbose\n")); addlist(_(" --arch <arch> set an alternate architecture\n")); addlist(_(" --cachedir <dir> set an alternate package cache location\n")); + addlist(_(" --color add color to output\n")); addlist(_(" --config <path> set an alternate configuration file\n")); addlist(_(" --debug display debug messages\n")); addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n")); @@ -392,6 +393,9 @@ static int parsearg_global(int opt) check_optarg(); config->cachedirs = alpm_list_add(config->cachedirs, strdup(optarg)); break; + case OP_COLOR: + config->color = 1; + break; case OP_CONFIG: check_optarg(); if(config->configfile) { @@ -628,6 +632,7 @@ static int parseargs(int argc, char *argv[]) {"print-format", required_argument, 0, OP_PRINTFORMAT}, {"gpgdir", required_argument, 0, OP_GPGDIR}, {"dbonly", no_argument, 0, OP_DBONLY}, + {"color", no_argument, 0, OP_COLOR}, {0, 0, 0, 0} }; -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/color.c | 728 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/color.h | 70 ++++++ src/pacman/util.c | 35 ++- src/pacman/util.h | 6 + 4 files changed, 830 insertions(+), 9 deletions(-) create mode 100644 src/pacman/color.c create mode 100644 src/pacman/color.h diff --git a/src/pacman/color.c b/src/pacman/color.c new file mode 100644 index 0000000..d1b2d5e --- /dev/null +++ b/src/pacman/color.c @@ -0,0 +1,728 @@ +/* + * util.c + * + * Copyright (c) 2006-2012 Pacman Development Team <pacman-dev@archlinux.org> + * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * 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 <time.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <stdint.h> /* intmax_t */ +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <dirent.h> +#include <unistd.h> +#include <limits.h> +#include <wchar.h> +#ifdef HAVE_TERMIOS_H +#include <termios.h> /* tcflush */ +#endif + +#include <alpm.h> +#include <alpm_list.h> + +/* pacman */ +#include "util.h" +#include "conf.h" +#include "callback.h" +#include "color.h" + +#define COLOR_LEN 8 + +typedef struct __colortab_t { + char red[COLOR_LEN + 1]; + char green[COLOR_LEN + 1]; + char yellow[COLOR_LEN + 1]; + char blue[COLOR_LEN + 1]; + char magenta[COLOR_LEN + 1]; + char cyan[COLOR_LEN + 1]; + char white[COLOR_LEN + 1]; + char none[COLOR_LEN + 1]; +} colortab_t; + +static colortab_t colortab; + + +void color_list_display(const colordata_t *colors_title, const char *title, const alpm_list_t *list, + unsigned short maxcols) +{ + const alpm_list_t *i; + size_t len = 0; + + if(title) { + len = string_length(title) + 1; + color_printf(colors_title, "%s ", title); + } + + if(!list) { + printf("%s\n", _("None")); + } else { + size_t cols = len; + 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 = 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; + } + putchar('\n'); + } +} + +void color_list_display_linebreak(const colordata_t *colors_title, const char *title, const alpm_list_t *list, + unsigned short maxcols) +{ + unsigned short len = 0; + + if(title) { + len = (unsigned short)string_length(title) + 1; + color_printf(colors_title, "%s ", title); + } + + 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)) { + size_t j; + for(j = 1; j <= len; j++) { + printf(" "); + } + indentprint((const char *)i->data, len, maxcols); + printf("\n"); + } + } +} + +/* prepare a list of pkgs to display */ +void _color_display_targets(alpm_list_t *targets, int verbose) +{ + char *str; + const char *label; + double size; + off_t isize = 0, rsize = 0, dlsize = 0; + unsigned short cols; + alpm_list_t *i, *rows = NULL, *names = NULL; + + if(!targets) { + return; + } + + /* gather package info */ + for(i = targets; i; i = alpm_list_next(i)) { + pm_target_t *target = i->data; + + if(target->install) { + dlsize += alpm_pkg_download_size(target->install); + isize += alpm_pkg_get_isize(target->install); + } + if(target->remove) { + /* add up size of all removed packages */ + rsize += alpm_pkg_get_isize(target->remove); + } + } + + /* form data for both verbose and non-verbose display */ + for(i = targets; i; i = alpm_list_next(i)) { + pm_target_t *target = i->data; + + 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)); + } else if(isize == 0) { + pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->remove), + alpm_pkg_get_version(target->remove)); + } else { + pm_asprintf(&str, "%s-%s [removal]", alpm_pkg_get_name(target->remove), + alpm_pkg_get_version(target->remove)); + } + names = alpm_list_add(names, str); + } + + /* print to screen */ + pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets)); + printf("\n"); + + cols = getcols(fileno(stdout)); + if(verbose) { + alpm_list_t *header = create_verbose_header(); + if(table_display(str, header, rows, cols) != 0) { + /* fallback to list display if table wouldn't fit */ + color_list_display(COLOR_YELLOW_ALL, str, names, cols); + } + alpm_list_free(header); + } else { + color_list_display(COLOR_YELLOW_ALL, 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 = i->data; + FREELIST(lp); + } + alpm_list_free(rows); + FREELIST(names); + free(str); + + if(dlsize > 0 || config->op_s_downloadonly) { + size = humanize_size(dlsize, 'M', 2, &label); + color_printf(COLOR_WHITE_COLON, _("Total Download Size: %.2f %s\n"), size, label); + } + if(!config->op_s_downloadonly) { + if(isize > 0) { + size = humanize_size(isize, 'M', 2, &label); + color_printf(COLOR_WHITE_COLON, _("Total Installed Size: %.2f %s\n"), size, label); + } + if(rsize > 0 && isize == 0) { + size = humanize_size(rsize, 'M', 2, &label); + color_printf(COLOR_WHITE_COLON, _("Total Removed Size: %.2f %s\n"), size, label); + } + /* only show this net value if different from raw installed size */ + if(isize > 0 && rsize > 0) { + size = humanize_size(isize - rsize, 'M', 2, &label); + color_printf(COLOR_WHITE_COLON, _("Net Upgrade Size: %.2f %s\n"), size, label); + } + } +} +void color_display_repo_list(const char *dbname, alpm_list_t *list, + unsigned short cols) +{ + const char *prefix= " "; + + color_printf(COLOR_BLUE_ALL, ":: "); + color_printf(COLOR_WHITE_ALL, _("Repository %s\n"), dbname); + color_list_display(NULL, prefix, list, cols); +} + +/* presents a prompt and gets a Y/N answer */ +static int color_question(const colordata_t *colors, short preset, char *fmt, va_list args) +{ + char response[32]; + FILE *stream; + + if(config->noconfirm) { + stream = stdout; + } else { + /* Use stderr so questions are always displayed when redirecting output */ + stream = stderr; + } + + /* ensure all text makes it to the screen before we prompt the user */ + fflush(stdout); + fflush(stderr); + + color_vfprintf(stream, colors, fmt, args); + + if(preset) { + fprintf(stream, " %s ", _("[Y/n]")); + } else { + fprintf(stream, " %s ", _("[y/N]")); + } + + if(config->noconfirm) { + fprintf(stream, "\n"); + return preset; + } + + fflush(stream); + flush_term_input(fileno(stdin)); + + if(fgets(response, sizeof(response), stdin)) { + strtrim(response); + if(strlen(response) == 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))) { + fprintf(stream, "%s\n", response); + } + + if(strcasecmp(response, _("Y")) == 0 || strcasecmp(response, _("YES")) == 0) { + return 1; + } else if(strcasecmp(response, _("N")) == 0 || strcasecmp(response, _("NO")) == 0) { + return 0; + } + } + return 0; +} + +int color_yesno(const colordata_t *colors, char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = color_question(colors, 1, fmt, args); + va_end(args); + + return ret; +} + +int color_noyes(const colordata_t *colors, char *fmt, ...) +{ + int ret; + va_list args; + + va_start(args, fmt); + ret = color_question(colors, 0, fmt, args); + va_end(args); + + return ret; +} + +int color_pm_vasprintf(char **string, alpm_loglevel_t level, const char *format, va_list args) +{ + int ret = 0; + char *msg = NULL; + + /* if current logmask does not overlap with level, do not print msg */ + if(!(config->logmask & level)) { + return ret; + } + + /* print the message using va_arg list */ + ret = vasprintf(&msg, format, args); + + /* print a prefix to the message */ + if(isatty(fileno(stdout))) { + switch(level) { + case ALPM_LOG_ERROR: + pm_asprintf(string, "%s%s%s%s", colortab.red, _("error: "), colortab.none, msg); + break; + case ALPM_LOG_WARNING: + pm_asprintf(string, "%s%s%s%s", colortab.yellow, _("warning: "), colortab.none, msg); + break; + case ALPM_LOG_DEBUG: + pm_asprintf(string, "debug: %s", msg); + break; + case ALPM_LOG_FUNCTION: + pm_asprintf(string, "function: %s", msg); + break; + default: + pm_asprintf(string, "%s", msg); + break; + } + } else { + switch(level) { + case ALPM_LOG_ERROR: + pm_asprintf(string, _("error: %s"), msg); + break; + case ALPM_LOG_WARNING: + pm_asprintf(string, _("warning: %s"), msg); + break; + case ALPM_LOG_DEBUG: + pm_asprintf(string, "debug: %s", msg); + break; + case ALPM_LOG_FUNCTION: + pm_asprintf(string, "function: %s", msg); + break; + default: + pm_asprintf(string, "%s", msg); + break; + } + } + free(msg); + + return ret; +} + +int color_pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, va_list args) +{ + int ret = 0; + + /* if current logmask does not overlap with level, do not print msg */ + if(!(config->logmask & level)) { + return ret; + } + +#if defined(PACMAN_DEBUG) + /* If debug is on, we'll timestamp the output */ + if(config->logmask & ALPM_LOG_DEBUG) { + time_t t; + struct tm *tmp; + char timestr[10] = {0}; + + t = time(NULL); + tmp = localtime(&t); + strftime(timestr, 9, "%H:%M:%S", tmp); + timestr[8] = '\0'; + + fprintf(stream, "[%s] ", timestr); + } +#endif + + /* print a prefix to the message */ + switch(level) { + case ALPM_LOG_ERROR: + color_fprintf(stream, COLOR_RED_ALL, _("error: ")); + break; + case ALPM_LOG_WARNING: + color_fprintf(stream, COLOR_YELLOW_ALL, _("warning: ")); + break; + case ALPM_LOG_DEBUG: + fprintf(stream, "debug: "); + break; + case ALPM_LOG_FUNCTION: + fprintf(stream, "function: "); + break; + default: + break; + } + + /* print the message using va_arg list */ + ret = vfprintf(stream, format, args); + return ret; +} + +/* pacman-color */ + +int _set_color_sequence(const char* name, char* dest) +{ + int ret = 0; + + if(strcmp(name, "black") == 0) { + strncpy(dest, "\033[0;30m", COLOR_LEN); + } else if(strcmp(name, "red") == 0) { + strncpy(dest, "\033[0;31m", COLOR_LEN); + } else if(strcmp(name, "green") == 0) { + strncpy(dest, "\033[0;32m", COLOR_LEN); + } else if(strcmp(name, "yellow") == 0) { + strncpy(dest, "\033[0;33m", COLOR_LEN); + } else if(strcmp(name, "blue") == 0) { + strncpy(dest, "\033[0;34m", COLOR_LEN); + } else if(strcmp(name, "magenta") == 0) { + strncpy(dest, "\033[0;35m", COLOR_LEN); + } else if(strcmp(name, "cyan") == 0) { + strncpy(dest, "\033[0;36m", COLOR_LEN); + } else if(strcmp(name, "white") == 0) { + strncpy(dest, "\033[0;37m", COLOR_LEN); + } else if(strcmp(name, "gray") == 0) { + strncpy(dest, "\033[1;30m", COLOR_LEN); + } else if(strcmp(name, "intensive red") == 0) { + strncpy(dest, "\033[1;31m", COLOR_LEN); + } else if(strcmp(name, "intensive green") == 0) { + strncpy(dest, "\033[1;32m", COLOR_LEN); + } else if(strcmp(name, "intensive yellow") == 0) { + strncpy(dest, "\033[1;33m", COLOR_LEN); + } else if(strcmp(name, "intensive blue") == 0) { + strncpy(dest, "\033[1;34m", COLOR_LEN); + } else if(strcmp(name, "intensive magenta") == 0) { + strncpy(dest, "\033[1;35m", COLOR_LEN); + } else if(strcmp(name, "intensive cyan") == 0) { + strncpy(dest, "\033[1;36m", COLOR_LEN); + } else if(strcmp(name, "intensive white") == 0) { + strncpy(dest, "\033[1;37m", COLOR_LEN); + } else if(strcmp(name, "intensive foreground") == 0) { + strncpy(dest, "\033[m\033[1m", COLOR_LEN); + } else if(strcmp(name, "none") == 0) { + strncpy(dest, "\033[m", COLOR_LEN); + } else { + ret = 1; + } + dest[COLOR_LEN] = '\0'; + return(ret); +} + +void _insert_color(FILE* stream, color_t color) +{ + switch(color) { + case COLOR_RED: + fprintf(stream, colortab.red); + break; + case COLOR_GREEN: + fprintf(stream, colortab.green); + break; + case COLOR_YELLOW: + fprintf(stream, colortab.yellow); + break; + case COLOR_BLUE: + fprintf(stream, colortab.blue); + break; + case COLOR_MAGENTA: + fprintf(stream, colortab.magenta); + break; + case COLOR_CYAN: + fprintf(stream, colortab.cyan); + break; + case COLOR_WHITE: + fprintf(stream, colortab.white); + break; + case COLOR_NONE: + fprintf(stream, colortab.none); + break; + default:; + } +} + +int _parsecolorconfig(colortab_t* colortab, char* file) +{ + _set_color_sequence("intensive red", colortab->red); + _set_color_sequence("intensive green", colortab->green); + _set_color_sequence("intensive yellow", colortab->yellow); + _set_color_sequence("intensive blue", colortab->blue); + _set_color_sequence("intensive magenta", colortab->magenta); + _set_color_sequence("intensive cyan", colortab->cyan); + _set_color_sequence("intensive foreground", colortab->white); + _set_color_sequence("none", colortab->none); + + FILE* fp = NULL; + int linenum = 0; + char line[PATH_MAX+1]; + char* ptr; + + fp = fopen(file, "r"); + if(fp == NULL) { + pm_printf(ALPM_LOG_ERROR, _("config file %s could not be read.\n"), file); + return 1; + } + while(fgets(line, PATH_MAX, fp)) { + linenum++; + strtrim(line); + + if(strlen(line) == 0 || line[0] == '#') { + continue; + } + if((ptr = strchr(line, '#'))) { + *ptr = '\0'; + } + + char* key = line; + ptr = line; + strsep(&ptr, "="); + strtrim(key); + strtrim(ptr); + + if(key == NULL) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: syntax error in config file- missing key.\n"), + file, linenum); + return 1; + } + if(strcmp(key, "Red") == 0) { + if(_set_color_sequence(ptr, colortab->red)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "Green") == 0) { + if(_set_color_sequence(ptr, colortab->green)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "Yellow") == 0) { + if(_set_color_sequence(ptr, colortab->yellow)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "Blue") == 0) { + if(_set_color_sequence(ptr, colortab->blue)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "Magenta") == 0) { + if(_set_color_sequence(ptr, colortab->magenta)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "Cyan") == 0) { + if(_set_color_sequence(ptr, colortab->cyan)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else if(strcmp(key, "White") == 0) { + if(_set_color_sequence(ptr, colortab->white)) { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: color '%s' not recognized.\n"), + file, linenum, ptr); + } + } else { + pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' not recognized.\n"), + file, linenum, key); + return(1); + } + } + return(0); +} + +int parsecolorconfig() +{ + return(_parsecolorconfig(&colortab, config->colorfile)); +} + +int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args) +{ + int ret = 0; + + if(isatty(fileno(stream)) && colors) { + char* msg = NULL; + ret = vasprintf(&msg, format, args); + if(msg == NULL) { + return(ret); + } + + const colordata_t* colorpos = colors; + color_t colorlast = COLOR_NONE; + int len = strlen(msg) + 1; + wchar_t* wcstr = calloc(len, sizeof(wchar_t)); + len = mbstowcs(wcstr, msg, len); + free(msg); + const wchar_t *strpos = wcstr; + + while(*strpos) { + if(colorpos->color != COLOR_END && + ((colorpos->separator == SEP_ANY) || + (colorpos->separator == SEP_LINE && *strpos == L'\n') || + (colorpos->separator == SEP_COLON && (*strpos == L':' || *strpos == L':')))) { + _insert_color(stream, colorpos->color); + colorlast = colorpos->color; + colorpos++; + } + fprintf(stream, "%lc", (wint_t)*strpos); + strpos++; + } + free(wcstr); + + if(colorlast != COLOR_NONE) { + _insert_color(stream, COLOR_NONE); + } + } else { + ret = vfprintf(stream, format, args); + } + return(ret); +} + +int color_fprintf(FILE* stream, const colordata_t* colors, const char* format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = color_vfprintf(stream, colors, format, args); + va_end(args); + return(ret); +} + +int color_printf(const colordata_t* colors, const char* format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = color_vfprintf(stdout, colors, format, args); + va_end(args); + return(ret); +} + +void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string) +{ + if(title) { + color_printf(colors_title, "%s ", title); + } + if(string == NULL || string[0] == '\0') { + printf(_("None")); + } else { + color_printf(colors_string, "%s", string); + } + printf("\n"); +} + +const colordata_t COLOR_WHITE_ALL[] = { + { SEP_ANY, COLOR_WHITE }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_GREEN_ALL[] = { + { SEP_ANY, COLOR_GREEN }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_RED_ALL[] = { + { SEP_ANY, COLOR_RED }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_BLUE_ALL[] = { + { SEP_ANY, COLOR_BLUE }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_YELLOW_ALL[] = { + { SEP_ANY, COLOR_YELLOW }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_MAGENTA_ALL[] = { + { SEP_ANY, COLOR_MAGENTA }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_CYAN_ALL[] = { + { SEP_ANY, COLOR_CYAN }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_DOUBLECOLON[] = { + { SEP_ANY, COLOR_BLUE }, + { SEP_ANY, COLOR_SAME }, + { SEP_ANY, COLOR_WHITE }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_DOUBLECOLON2[] = { + { SEP_ANY, COLOR_BLUE }, + { SEP_ANY, COLOR_SAME }, + { SEP_ANY, COLOR_WHITE }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_BLUE }, + { SEP_ANY, COLOR_SAME }, + { SEP_ANY, COLOR_WHITE }, + { SEP_LINE, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +const colordata_t COLOR_WHITE_COLON[] = { + { SEP_ANY, COLOR_WHITE }, + { SEP_COLON, COLOR_SAME }, + { SEP_ANY, COLOR_NONE }, + { SEP_ANY, COLOR_END } }; + +/* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/color.h b/src/pacman/color.h new file mode 100644 index 0000000..c833e2e --- /dev/null +++ b/src/pacman/color.h @@ -0,0 +1,70 @@ +#ifndef _PM_COLOR_H +#define _PM_COLOR_H + +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#include <alpm_list.h> + +/* pacman-color */ +typedef enum _separator_t { + SEP_ANY = 0, + SEP_LINE, + SEP_COLON, +} separator_t; + +typedef enum _color_t { + COLOR_END = 0, + COLOR_SAME, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, + COLOR_CYAN, + COLOR_WHITE, + COLOR_NONE, +} color_t; + +typedef struct _colordata_t { + separator_t separator; + color_t color; +} colordata_t; + +extern const colordata_t COLOR_WHITE_ALL[]; +extern const colordata_t COLOR_GREEN_ALL[]; +extern const colordata_t COLOR_RED_ALL[]; +extern const colordata_t COLOR_BLUE_ALL[]; +extern const colordata_t COLOR_YELLOW_ALL[]; +extern const colordata_t COLOR_MAGENTA_ALL[]; +extern const colordata_t COLOR_CYAN_ALL[]; +extern const colordata_t COLOR_DOUBLECOLON[]; +extern const colordata_t COLOR_DOUBLECOLON2[]; +extern const colordata_t COLOR_WHITE_COLON[]; + +/* util.c */ + +void color_list_display(const colordata_t *colors_title, const char *title, const alpm_list_t *list, + unsigned short maxcols); +void color_list_display_linebreak(const colordata_t *colors_title, const char *title, const alpm_list_t *list, + unsigned short maxcols); +void _color_display_targets(alpm_list_t *targets, int verbose); +void color_display_repo_list(const char *dbname, alpm_list_t *list, + unsigned short col); +int color_yesno(const colordata_t *colors, char *fmt, ...); +int color_noyes(const colordata_t *colors, char *fmt, ...); +int color_pm_vasprintf(char **string, alpm_loglevel_t level, const char *format, va_list args); +int color_pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, va_list args); +int _set_color_sequence(const char* name, char* dest); +void _insert_color(FILE* stream, color_t color); +int parsecolorconfig(); +int color_fprintf(FILE* stream, const colordata_t* colors, const char* format, ...) __attribute__((format(printf,3,4))); +int color_printf(const colordata_t* colors, const char* format, ...) __attribute__((format(printf,2,3))); + +int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args) __attribute__((format(printf,3,0))); + +void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string); + +#endif +/* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/util.c b/src/pacman/util.c index 7f7f6a7..f750542 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -45,6 +45,7 @@ #include "util.h" #include "conf.h" #include "callback.h" +#include "color.h" int trans_init(alpm_transflag_t flags, int check_valid) @@ -130,7 +131,7 @@ int check_syncdbs(size_t need_repos, int check_valid) } /* discard unhandled input on the terminal's input buffer */ -static int flush_term_input(int fd) { +int flush_term_input(int fd) { #ifdef HAVE_TCFLUSH if(isatty(fd)) { return tcflush(fd, TCIFLUSH); @@ -442,7 +443,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; @@ -605,7 +606,7 @@ static size_t table_calc_widths(const alpm_list_t *header, * @param cols the number of columns available in the terminal * @return -1 if not enough terminal cols available, else 0 */ -static int table_display(const char *title, const alpm_list_t *header, +int table_display(const char *title, const alpm_list_t *header, const alpm_list_t *rows, unsigned short cols) { const unsigned short padding = 2; @@ -794,7 +795,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(void) +alpm_list_t *create_verbose_header(void) { alpm_list_t *res = NULL; char *str; @@ -814,7 +815,7 @@ static alpm_list_t *create_verbose_header(void) } /* returns package info as list of strings */ -static alpm_list_t *create_verbose_row(pm_target_t *target) +alpm_list_t *create_verbose_row(pm_target_t *target) { char *str; off_t size = 0; @@ -1007,7 +1008,11 @@ void display_targets(void) } targets = alpm_list_msort(targets, alpm_list_count(targets), target_cmp); - _display_targets(targets, config->verbosepkglists); + if (config->color) { + _color_display_targets(targets, config->verbosepkglists); + } else { + _display_targets(targets, config->verbosepkglists); + } FREELIST(targets); } @@ -1263,7 +1268,11 @@ void select_display(const alpm_list_t *pkglist) if(!dbname) dbname = alpm_db_get_name(db); if(strcmp(alpm_db_get_name(db), dbname) != 0) { - display_repo_list(dbname, list, cols); + if (config->color) { + color_display_repo_list(dbname, list, cols); + } else { + display_repo_list(dbname, list, cols); + } FREELIST(list); dbname = alpm_db_get_name(db); } @@ -1272,7 +1281,11 @@ void select_display(const alpm_list_t *pkglist) list = alpm_list_add(list, string); nth++; } - display_repo_list(dbname, list, cols); + if (config->color) { + color_display_repo_list(dbname, list, cols); + } else { + display_repo_list(dbname, list, cols); + } FREELIST(list); } @@ -1551,7 +1564,11 @@ int pm_printf(alpm_loglevel_t level, const char *format, ...) /* print the message using va_arg list */ va_start(args, format); - ret = pm_vfprintf(stderr, level, format, args); + if (config->color) { + ret = color_pm_vfprintf(stderr, level, format, args); + } else { + ret = pm_vfprintf(stderr, level, format, args); + } va_end(args); return ret; diff --git a/src/pacman/util.h b/src/pacman/util.h index 0dfdc85..d15164f 100644 --- a/src/pacman/util.h +++ b/src/pacman/util.h @@ -47,6 +47,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); +int flush_term_input(int fd); unsigned short getcols(int fd); int rmrf(const char *path); const char *mbasename(const char *path); @@ -55,15 +56,20 @@ 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); +size_t string_length(const char *s); void string_display(const char *title, const char *string, unsigned short cols); double humanize_size(off_t bytes, const char target_unit, int precision, const char **label); +int table_display(const char *title, const alpm_list_t *header, + const alpm_list_t *rows, unsigned short cols); 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); +alpm_list_t *create_verbose_header(void); +alpm_list_t *create_verbose_row(pm_target_t *target); 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.7.11.4
On 05/08/12 19:46, Daniel Wallace wrote:
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/color.c | 728 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pacman/color.h | 70 ++++++ src/pacman/util.c | 35 ++- src/pacman/util.h | 6 + 4 files changed, 830 insertions(+), 9 deletions(-) create mode 100644 src/pacman/color.c create mode 100644 src/pacman/color.h
BIG patch... so I am going to provide general comments. Firstly, header for color.c is wrong, color.h is missing. And here is the big one. There is a LOT of code "duplication". I say "duplication" because some of the functions have diverged in the time this patch has been around so they are no longer duplicates. That should be an obvious maintenance burden we want to avoid. An example: color_yesno() vs. yesno(): - the only difference is the call to color_question() rather question() then color_question() vs. question(): - calls color_vfprintf() rather than vfprintf() So, lets reduce this a lot. I see that color_vfprintf falls back to just a standard vfprintf when the "colors" variable is NULL. So we can just call this whenever this is needed and pass NULL... in fact... see comment on the test below.
+int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args)
I'd call this vfprintf_color(). Well... I'd call it vfprintf_colour! Anyway, I think teh vfprintf is the more important part so should be read first.
+{ + int ret = 0; + + if(isatty(fileno(stream)) && colors) {
We could do: if(config->color && colors && isatty(fileno(stream))) then this could be a drop in replacement for vfprintf.
+ char* msg = NULL; + ret = vasprintf(&msg, format, args); + if(msg == NULL) { + return(ret); + } + + const colordata_t* colorpos = colors;
Huh?
+ color_t colorlast = COLOR_NONE; + int len = strlen(msg) + 1; + wchar_t* wcstr = calloc(len, sizeof(wchar_t)); + len = mbstowcs(wcstr, msg, len); + free(msg); + const wchar_t *strpos = wcstr; + + while(*strpos) { + if(colorpos->color != COLOR_END && + ((colorpos->separator == SEP_ANY) || + (colorpos->separator == SEP_LINE && *strpos == L'\n') || + (colorpos->separator == SEP_COLON && (*strpos == L':' || *strpos == L':')))) {
What is that second character being tested?
+ _insert_color(stream, colorpos->color); + colorlast = colorpos->color; + colorpos++; + } + fprintf(stream, "%lc", (wint_t)*strpos); + strpos++; + } + free(wcstr); + + if(colorlast != COLOR_NONE) { + _insert_color(stream, COLOR_NONE); + } + } else { + ret = vfprintf(stream, format, args); + } + return(ret); +}
If similar things were done so that printf_color() etc all just fell through to the non-colour version, the whole patchset could just be printf -> printf_color changes. Allan
can use --color or have Color in pacman.conf Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/Makefile.am | 3 +++ src/pacman/conf.c | 2 ++ src/pacman/conf.h | 1 + src/pacman/pacman.c | 5 +++++ 4 files changed, 11 insertions(+) diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index c8ce977..cad67a6 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -2,6 +2,7 @@ SUBDIRS = po # paths set at make time conffile = ${sysconfdir}/pacman.conf +colorfile = ${sysconfdir}/pacman.d/color.conf dbpath = ${localstatedir}/lib/pacman/ gpgdir = ${sysconfdir}/pacman.d/gnupg/ cachedir = ${localstatedir}/cache/pacman/pkg/ @@ -11,6 +12,7 @@ bin_PROGRAMS = pacman DEFS = -DLOCALEDIR=\"@localedir@\" \ -DCONFFILE=\"$(conffile)\" \ + -DCOLORFILE=\"$(colorfile)\" \ -DDBPATH=\"$(dbpath)\" \ -DGPGDIR=\"$(gpgdir)\" \ -DCACHEDIR=\"$(cachedir)\" \ @@ -30,6 +32,7 @@ endif pacman_SOURCES = \ conf.h conf.c \ + color.h color.c \ database.c \ deptest.c \ package.h package.c \ diff --git a/src/pacman/conf.c b/src/pacman/conf.c index 3b3d3df..a0d1be3 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -52,6 +52,7 @@ config_t *config_new(void) newconfig->op = PM_OP_MAIN; newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING; newconfig->configfile = strdup(CONFFILE); + newconfig->colorfile = strdup(COLORFILE); newconfig->deltaratio = 0.0; if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) { newconfig->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL | @@ -76,6 +77,7 @@ int config_free(config_t *oldconfig) FREELIST(oldconfig->noupgrade); FREELIST(oldconfig->noextract); free(oldconfig->configfile); + free(oldconfig->colorfile); free(oldconfig->rootdir); free(oldconfig->dbpath); free(oldconfig->logfile); diff --git a/src/pacman/conf.h b/src/pacman/conf.h index 3e17155..62343cb 100644 --- a/src/pacman/conf.h +++ b/src/pacman/conf.h @@ -41,6 +41,7 @@ typedef struct __config_t { * because they can come from both the command line or config file, and we * need to ensure we get the order of preference right. */ char *configfile; + char *colorfile; char *rootdir; char *dbpath; char *logfile; diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 732d7f3..0708dbf 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -46,6 +46,7 @@ #include "pacman.h" #include "util.h" #include "conf.h" +#include "color.h" /* list of targets specified on command line */ static alpm_list_t *pm_targets; @@ -868,6 +869,10 @@ int main(int argc, char *argv[]) cleanup(ret); } + /* parse colors if specified */ + if (config->color) { + parsecolorconfig(); + } /* noask is meant to be non-interactive */ if(config->noask) { config->noconfirm = 1; -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/callback.c | 164 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 128 insertions(+), 36 deletions(-) diff --git a/src/pacman/callback.c b/src/pacman/callback.c index 01c6b61..1c766e5 100644 --- a/src/pacman/callback.c +++ b/src/pacman/callback.c @@ -33,6 +33,7 @@ /* pacman */ #include "callback.h" #include "util.h" +#include "color.h" #include "conf.h" /* download progress bar */ @@ -223,16 +224,28 @@ void cb_event(alpm_event_t event, void *data1, void *data2) printf(_("generating %s with %s... "), (char *)data1, (char *)data2); break; case ALPM_EVENT_DELTA_PATCH_DONE: - printf(_("success!\n")); + if (config->color) { + color_printf(COLOR_GREEN_ALL, _("success!\n")); + } else { + printf(_("success!\n")); + } break; case ALPM_EVENT_DELTA_PATCH_FAILED: - printf(_("failed.\n")); + if (config->color) { + color_printf(COLOR_RED_ALL, _("failed.\n")); + } else { + printf(_("failed.\n")); + } break; case ALPM_EVENT_SCRIPTLET_INFO: fputs((const char *)data1, stdout); break; case ALPM_EVENT_RETRIEVE_START: - printf(_(":: Retrieving packages ...\n")); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: Retrieving packages ...\n")); + } else { + printf(_(":: Retrieving packages ...\n")); + } break; case ALPM_EVENT_DISKSPACE_START: if(config->noprogressbar) { @@ -266,32 +279,63 @@ void cb_question(alpm_question_t event, void *data1, void *data2, switch(event) { case ALPM_QUESTION_INSTALL_IGNOREPKG: if(!config->op_s_downloadonly) { - *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), + if (config->color) { + *response = color_yesno(COLOR_DOUBLECOLON, _(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), alpm_pkg_get_name(data1)); + + } else { + *response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"), + alpm_pkg_get_name(data1)); + } } else { *response = 1; } break; case ALPM_QUESTION_REPLACE_PKG: - *response = yesno(_(":: Replace %s with %s/%s?"), - alpm_pkg_get_name(data1), - (char *)data3, - alpm_pkg_get_name(data2)); + if (config->color) { + *response = color_yesno(COLOR_DOUBLECOLON, + _(":: Replace %s with %s/%s?"), + alpm_pkg_get_name(data1), + (char *)data3, + alpm_pkg_get_name(data2)); + } else { + *response = yesno(_(":: Replace %s with %s/%s?"), + alpm_pkg_get_name(data1), + (char *)data3, + alpm_pkg_get_name(data2)); + } break; case ALPM_QUESTION_CONFLICT_PKG: /* data parameters: target package, local package, conflict (strings) */ /* print conflict only if it contains new information */ if(strcmp(data1, data3) == 0 || strcmp(data2, data3) == 0) { - *response = noyes(_(":: %s and %s are in conflict. Remove %s?"), - (char *)data1, - (char *)data2, - (char *)data2); + if (config->color) { + *response = color_noyes(COLOR_DOUBLECOLON, + _(":: %s and %s are in conflict. Remove %s?"), + (char *)data1, + (char *)data2, + (char *)data2); + } else { + *response = noyes(_(":: %s and %s are in conflict. Remove %s?"), + (char *)data1, + (char *)data2, + (char *)data2); + } } else { - *response = noyes(_(":: %s and %s are in conflict (%s). Remove %s?"), - (char *)data1, - (char *)data2, - (char *)data3, - (char *)data2); + if (config->color) { + *response = color_noyes(COLOR_DOUBLECOLON, + _(":: %s and %s are in conflict (%s). Remove %s?"), + (char *)data1, + (char *)data2, + (char *)data3, + (char *)data2); + } else { + *response = noyes(_(":: %s and %s are in conflict (%s). Remove %s?"), + (char *)data1, + (char *)data2, + (char *)data3, + (char *)data2); + } } break; case ALPM_QUESTION_REMOVE_PKGS: @@ -304,10 +348,17 @@ void cb_question(alpm_question_t event, void *data1, void *data2, (char *)alpm_pkg_get_name(i->data)); count++; } - printf(_n( - ":: The following package cannot be upgraded due to unresolvable dependencies:\n", - ":: The following packages cannot be upgraded due to unresolvable dependencies:\n", - count)); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _n( + ":: The following package cannot be upgraded due to unresolvable dependencies:\n", + ":: The following packages cannot be upgraded due to unresolvable dependencies:\n", + count)); + } else { + printf(_n( + ":: The following package cannot be upgraded due to unresolvable dependencies:\n", + ":: The following packages cannot be upgraded due to unresolvable dependencies:\n", + count)); + } list_display(" ", namelist, getcols(fileno(stdout))); printf("\n"); *response = noyes(_n( @@ -322,8 +373,13 @@ void cb_question(alpm_question_t event, void *data1, void *data2, alpm_list_t *providers = data1; size_t count = alpm_list_count(providers); char *depstring = alpm_dep_compute_string((alpm_depend_t *)data2); - printf(_(":: There are %zd providers available for %s:\n"), count, - depstring); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: There are %zd providers available for %s:\n"), + count, depstring); + } else { + printf(_(":: There are %zd providers available for %s:\n"), count, + depstring); + } free(depstring); select_display(providers); *response = select_question(count); @@ -331,18 +387,33 @@ void cb_question(alpm_question_t event, void *data1, void *data2, break; case ALPM_QUESTION_LOCAL_NEWER: if(!config->op_s_downloadonly) { - *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), - alpm_pkg_get_name(data1), - alpm_pkg_get_version(data1)); + if (config->color) { + *response = color_yesno(COLOR_DOUBLECOLON, + _(":: %s-%s: local version is newer. Upgrade anyway?"), + alpm_pkg_get_name(data1), + alpm_pkg_get_version(data1)); + } else { + *response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"), + alpm_pkg_get_name(data1), + alpm_pkg_get_version(data1)); + } } else { *response = 1; } break; case ALPM_QUESTION_CORRUPTED_PKG: - *response = yesno(_(":: File %s is corrupted (%s).\n" - "Do you want to delete it?"), - (char *)data1, - alpm_strerror(*(alpm_errno_t *)data2)); + if (config->color) { + *response = color_yesno(COLOR_DOUBLECOLON, + _(":: File %s is corrupted (%s).\n" + "Do you want to delete it?"), + (char *)data1, + alpm_strerror(*(alpm_errno_t *)data2)); + } else { + *response = yesno(_(":: File %s is corrupted (%s).\n" + "Do you want to delete it?"), + (char *)data1, + alpm_strerror(*(alpm_errno_t *)data2)); + } break; case ALPM_QUESTION_IMPORT_KEY: { @@ -356,8 +427,14 @@ void cb_question(alpm_question_t event, void *data1, void *data2, revoked = " (revoked)"; } - *response = yesno(_(":: Import PGP key %d%c/%s, \"%s\", created: %s%s?"), - key->length, key->pubkey_algo, key->fingerprint, key->uid, created, revoked); + if (config->color) { + *response = color_yesno(COLOR_DOUBLECOLON, + _(":: Import PGP key %d%c/%s, \"%s\", created: %s%s?"), + key->length, key->pubkey_algo, key->fingerprint, key->uid, created, revoked); + } else { + *response = yesno(_(":: Import PGP key %d%c/%s, \"%s\", created: %s%s?"), + key->length, key->pubkey_algo, key->fingerprint, key->uid, created, revoked); + } } break; } @@ -490,8 +567,15 @@ void cb_progress(alpm_progress_t event, const char *pkgname, int percent, } - printf("(%*ld/%*ld) %ls%-*s", digits, (unsigned long)current, - digits, (unsigned long)howmany, wcstr, padwid, ""); + if (config->color) { + color_printf(COLOR_BLUE_ALL, + "(%*ld/%*ld)", digits, (unsigned long)current, + digits, (unsigned long)howmany); + } else { + printf("(%*ld/%*ld)", digits, (unsigned long)current, + digits, (unsigned long)howmany); + } + printf(" %ls%-*s", wcstr, padwid, ""); free(wcstr); @@ -747,12 +831,20 @@ void cb_log(alpm_loglevel_t level, const char *fmt, va_list args) if(on_progress) { char *string = NULL; - pm_vasprintf(&string, level, fmt, args); + if (config->color) { + color_pm_vasprintf(&string, level, fmt, args); + } else { + pm_vasprintf(&string, level, fmt, args); + } if(string != NULL) { output = alpm_list_add(output, string); } } else { - pm_vfprintf(stderr, level, fmt, args); + if (config->color) { + color_pm_vfprintf(stderr, level, fmt, args); + } else { + pm_vfprintf(stderr, level, fmt, args); + } } } -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/color.c | 46 ++++++++++++- src/pacman/color.h | 8 ++- src/pacman/package.c | 190 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 188 insertions(+), 56 deletions(-) diff --git a/src/pacman/color.c b/src/pacman/color.c index d1b2d5e..235d47b 100644 --- a/src/pacman/color.c +++ b/src/pacman/color.c @@ -419,6 +419,33 @@ int color_pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, v return ret; } + +/** Turn a depends list into a text list. + * @param deps a list with items of type alpm_depend_t + */ +void color_deplist_display(const colordata_t *colors_title, const char *title, + alpm_list_t *deps, unsigned short cols) +{ + 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)); + } + color_list_display(colors_title, title, text, cols); + FREELIST(text); +} + +void color_optdeplist_display(const colordata_t *color_title, const char *title, + alpm_list_t *optdeps, unsigned short cols) +{ + alpm_list_t *i, *text = NULL; + for(i = optdeps; i; i = alpm_list_next(i)) { + alpm_depend_t *optdep = i->data; + text = alpm_list_add(text, alpm_dep_compute_string(optdep)); + } + color_list_display_linebreak(color_title, title, text, cols); + FREELIST(text); +} /* pacman-color */ int _set_color_sequence(const char* name, char* dest) @@ -653,7 +680,24 @@ int color_printf(const colordata_t* colors, const char* format, ...) return(ret); } -void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string) + +void color_string_display(const colordata_t *colors_title, const char *title, const char *string, + unsigned short cols) +{ + if(title) { + color_printf(colors_title, "%s ", title); + } + 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, len, cols); + } + printf("\n"); +} +void colored_string_display(const colordata_t* colors_title, const char* title, + const colordata_t* colors_string, const char* string) { if(title) { color_printf(colors_title, "%s ", title); diff --git a/src/pacman/color.h b/src/pacman/color.h index c833e2e..057f64b 100644 --- a/src/pacman/color.h +++ b/src/pacman/color.h @@ -56,6 +56,10 @@ int color_yesno(const colordata_t *colors, char *fmt, ...); int color_noyes(const colordata_t *colors, char *fmt, ...); int color_pm_vasprintf(char **string, alpm_loglevel_t level, const char *format, va_list args); int color_pm_vfprintf(FILE *stream, alpm_loglevel_t level, const char *format, va_list args); +void color_deplist_display(const colordata_t *colors_title, const char *title, + alpm_list_t *deps, unsigned short cols); +void color_optdeplist_display(const colordata_t *color_title, const char *title, + alpm_list_t *optdeps, unsigned short cols); int _set_color_sequence(const char* name, char* dest); void _insert_color(FILE* stream, color_t color); int parsecolorconfig(); @@ -64,7 +68,9 @@ int color_printf(const colordata_t* colors, const char* format, ...) __attribute int color_vfprintf(FILE* stream, const colordata_t* colors, const char* format, va_list args) __attribute__((format(printf,3,0))); -void color_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string); +void color_string_display(const colordata_t *colors_title, const char *title, const char *string, + unsigned short cols); +void colored_string_display(const colordata_t* colors_title, const char* title, const colordata_t* colors_string, const char* string); #endif /* vim: set ts=2 sw=2 noet: */ diff --git a/src/pacman/package.c b/src/pacman/package.c index fe04d40..01489b2 100644 --- a/src/pacman/package.c +++ b/src/pacman/package.c @@ -32,6 +32,7 @@ /* pacman */ #include "package.h" #include "util.h" +#include "color.h" #include "conf.h" #define CLBUF_SIZE 4096 @@ -136,69 +137,142 @@ void dump_pkg_full(alpm_pkg_t *pkg, int extra) /* actual output */ if(from == ALPM_PKG_FROM_SYNCDB) { - string_display(_("Repository :"), - alpm_db_get_name(alpm_pkg_get_db(pkg)), cols); - } - string_display(_("Name :"), alpm_pkg_get_name(pkg), cols); - string_display(_("Version :"), alpm_pkg_get_version(pkg), cols); - string_display(_("URL :"), alpm_pkg_get_url(pkg), cols); - list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg), cols); - list_display(_("Groups :"), alpm_pkg_get_groups(pkg), cols); - deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg), cols); - deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg), cols); - optdeplist_display(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg), cols); - if(extra || from == ALPM_PKG_FROM_LOCALDB) { - list_display(_("Required By :"), requiredby, cols); + if (config->color) { + colored_string_display(COLOR_WHITE_ALL, + _("Repository :"), + COLOR_MAGENTA_ALL, + alpm_db_get_name(alpm_pkg_get_db(pkg))); + } else { + string_display(_("Repository :"), + alpm_db_get_name(alpm_pkg_get_db(pkg)), cols); + } } - deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols); - deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg), cols); + if (config->color) { + colored_string_display(COLOR_WHITE_ALL, _("Name :"), + COLOR_WHITE_ALL, alpm_pkg_get_name(pkg)); + colored_string_display(COLOR_WHITE_ALL, _("Version :"), + COLOR_GREEN_ALL, alpm_pkg_get_version(pkg)); + colored_string_display(COLOR_WHITE_ALL, _("URL :"), + COLOR_CYAN_ALL, alpm_pkg_get_url(pkg)); + color_list_display(COLOR_WHITE_ALL, _("Licenses :"), alpm_pkg_get_licenses(pkg), cols); + color_list_display(COLOR_WHITE_ALL, _("Groups :"), alpm_pkg_get_groups(pkg), cols); + color_deplist_display(COLOR_WHITE_ALL, _("Provides :"), alpm_pkg_get_provides(pkg), cols); + color_deplist_display(COLOR_WHITE_ALL, _("Depends On :"), alpm_pkg_get_depends(pkg), cols); + color_optdeplist_display(COLOR_WHITE_ALL, _("Optional Deps :"), alpm_pkg_get_optdepends(pkg), cols); + if(extra || from == ALPM_PKG_FROM_LOCALDB) { + color_list_display(COLOR_WHITE_ALL, _("Required By :"), requiredby, cols); + } + color_deplist_display(COLOR_WHITE_ALL, _("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols); + color_deplist_display(COLOR_WHITE_ALL, _("Replaces :"), alpm_pkg_get_replaces(pkg), cols); + + size = humanize_size(alpm_pkg_get_size(pkg), 'K', 2, &label); + if(from == ALPM_PKG_FROM_SYNCDB) { + color_printf(COLOR_WHITE_COLON, _("Download Size : %6.2f %s\n"), size, label); + } else if(from == ALPM_PKG_FROM_FILE) { + color_printf(COLOR_WHITE_COLON, _("Compressed Size: %6.2f %s\n"), size, label); + } - size = humanize_size(alpm_pkg_get_size(pkg), 'K', 2, &label); - if(from == ALPM_PKG_FROM_SYNCDB) { - printf(_("Download Size : %6.2f %s\n"), size, label); - } else if(from == ALPM_PKG_FROM_FILE) { - printf(_("Compressed Size: %6.2f %s\n"), size, label); - } + size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 2, &label); + color_printf(COLOR_WHITE_COLON, _("Installed Size : %6.2f %s\n"), size, label); - size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 2, &label); - printf(_("Installed Size : %6.2f %s\n"), size, label); + color_string_display(COLOR_WHITE_ALL, _("Packager :"), alpm_pkg_get_packager(pkg), cols); + color_string_display(COLOR_WHITE_ALL, _("Architecture :"), alpm_pkg_get_arch(pkg), cols); + color_string_display(COLOR_WHITE_ALL, _("Build Date :"), bdatestr, cols); + if(from == ALPM_PKG_FROM_LOCALDB) { + color_string_display(COLOR_WHITE_ALL, _("Install Date :"), idatestr, cols); + color_string_display(COLOR_WHITE_ALL, _("Install Reason :"), reason, cols); + } + if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) { + color_string_display(COLOR_WHITE_ALL, _("Install Script :"), + alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"), cols); + } - string_display(_("Packager :"), alpm_pkg_get_packager(pkg), cols); - string_display(_("Architecture :"), alpm_pkg_get_arch(pkg), cols); - string_display(_("Build Date :"), bdatestr, cols); - if(from == ALPM_PKG_FROM_LOCALDB) { - string_display(_("Install Date :"), idatestr, cols); - string_display(_("Install Reason :"), reason, cols); - } - if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) { - string_display(_("Install Script :"), - alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"), cols); - } + if(from == ALPM_PKG_FROM_SYNCDB && extra) { + color_string_display(COLOR_WHITE_ALL, _("MD5 Sum :"), alpm_pkg_get_md5sum(pkg), cols); + color_string_display(COLOR_WHITE_ALL, _("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg), cols); + color_string_display(COLOR_WHITE_ALL, _("Signatures :"), + alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"), cols); + } else { + color_list_display(COLOR_WHITE_ALL, _("Validated By :"), validation, cols); + } + + if(from == ALPM_PKG_FROM_FILE) { + alpm_siglist_t siglist; + int err = alpm_pkg_check_pgp_signature(pkg, &siglist); + if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) { + color_string_display(COLOR_WHITE_ALL, _("Signatures :"), _("None"), cols); + } else if(err) { + color_string_display(COLOR_WHITE_ALL, _("Signatures :"), + alpm_strerror(alpm_errno(config->handle)), cols); + } else { + signature_display(_("Signatures :"), &siglist, cols); + } + alpm_siglist_cleanup(&siglist); + } - if(from == ALPM_PKG_FROM_SYNCDB && extra) { - string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg), cols); - string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg), cols); - string_display(_("Signatures :"), - alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"), cols); + color_string_display(COLOR_WHITE_ALL, _("Description :"), alpm_pkg_get_desc(pkg), cols); } else { - list_display(_("Validated By :"), validation, cols); - } + string_display(_("Name :"), alpm_pkg_get_name(pkg), cols); + string_display(_("Version :"), alpm_pkg_get_version(pkg), cols); + string_display(_("URL :"), alpm_pkg_get_url(pkg), cols); + list_display(_("Licenses :"), alpm_pkg_get_licenses(pkg), cols); + list_display(_("Groups :"), alpm_pkg_get_groups(pkg), cols); + deplist_display(_("Provides :"), alpm_pkg_get_provides(pkg), cols); + deplist_display(_("Depends On :"), alpm_pkg_get_depends(pkg), cols); + optdeplist_display(_("Optional Deps :"), alpm_pkg_get_optdepends(pkg), cols); + if(extra || from == ALPM_PKG_FROM_LOCALDB) { + list_display(_("Required By :"), requiredby, cols); + } + deplist_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg), cols); + deplist_display(_("Replaces :"), alpm_pkg_get_replaces(pkg), cols); + + size = humanize_size(alpm_pkg_get_size(pkg), 'K', 2, &label); + if(from == ALPM_PKG_FROM_SYNCDB) { + printf(_("Download Size : %6.2f %s\n"), size, label); + } else if(from == ALPM_PKG_FROM_FILE) { + printf(_("Compressed Size: %6.2f %s\n"), size, label); + } + + size = humanize_size(alpm_pkg_get_isize(pkg), 'K', 2, &label); + printf(_("Installed Size : %6.2f %s\n"), size, label); + + string_display(_("Packager :"), alpm_pkg_get_packager(pkg), cols); + string_display(_("Architecture :"), alpm_pkg_get_arch(pkg), cols); + string_display(_("Build Date :"), bdatestr, cols); + if(from == ALPM_PKG_FROM_LOCALDB) { + string_display(_("Install Date :"), idatestr, cols); + string_display(_("Install Reason :"), reason, cols); + } + if(from == ALPM_PKG_FROM_FILE || from == ALPM_PKG_FROM_LOCALDB) { + string_display(_("Install Script :"), + alpm_pkg_has_scriptlet(pkg) ? _("Yes") : _("No"), cols); + } - if(from == ALPM_PKG_FROM_FILE) { - alpm_siglist_t siglist; - int err = alpm_pkg_check_pgp_signature(pkg, &siglist); - if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) { - string_display(_("Signatures :"), _("None"), cols); - } else if(err) { + if(from == ALPM_PKG_FROM_SYNCDB && extra) { + string_display(_("MD5 Sum :"), alpm_pkg_get_md5sum(pkg), cols); + string_display(_("SHA256 Sum :"), alpm_pkg_get_sha256sum(pkg), cols); string_display(_("Signatures :"), - alpm_strerror(alpm_errno(config->handle)), cols); + alpm_pkg_get_base64_sig(pkg) ? _("Yes") : _("None"), cols); } else { - signature_display(_("Signatures :"), &siglist, cols); + list_display(_("Validated By :"), validation, cols); + } + + if(from == ALPM_PKG_FROM_FILE) { + alpm_siglist_t siglist; + int err = alpm_pkg_check_pgp_signature(pkg, &siglist); + if(err && alpm_errno(config->handle) == ALPM_ERR_SIG_MISSING) { + string_display(_("Signatures :"), _("None"), cols); + } else if(err) { + string_display(_("Signatures :"), + alpm_strerror(alpm_errno(config->handle)), cols); + } else { + signature_display(_("Signatures :"), &siglist, cols); + } + alpm_siglist_cleanup(&siglist); } - alpm_siglist_cleanup(&siglist); - } - string_display(_("Description :"), alpm_pkg_get_desc(pkg), cols); + string_display(_("Description :"), alpm_pkg_get_desc(pkg), cols); + } /* Print additional package info if info flag passed more than once */ if(from == ALPM_PKG_FROM_LOCALDB && extra) { @@ -258,7 +332,11 @@ void dump_pkg_backups(alpm_pkg_t *pkg) { alpm_list_t *i; const char *root = alpm_option_get_root(config->handle); - printf(_("Backup Files:\n")); + if (config->color) { + color_printf(COLOR_WHITE_ALL, _("Backup Files:\n")); + } else { + printf(_("Backup Files:\n")); + } if(alpm_pkg_get_backup(pkg)) { /* package has backup files, so print them */ for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) { @@ -294,7 +372,11 @@ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) * Quiet : '<root><filepath>\n' */ if(!quiet) { - fputs(pkgname, stdout); + if (config->color) { + color_printf(COLOR_WHITE_ALL, "%s", pkgname); + } else { + fputs(pkgname, stdout); + } putchar(' '); } fputs(root, stdout); -- 1.7.11.4
including special color_version Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/color.c | 24 +++++++++++++++++ src/pacman/color.h | 1 + src/pacman/pacman.c | 75 ++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/src/pacman/color.c b/src/pacman/color.c index 235d47b..588852a 100644 --- a/src/pacman/color.c +++ b/src/pacman/color.c @@ -446,6 +446,30 @@ void color_optdeplist_display(const colordata_t *color_title, const char *title, color_list_display_linebreak(color_title, title, text, cols); FREELIST(text); } + +void color_version(char *package_version) +{ + color_printf(COLOR_YELLOW_ALL, " .--. "); + printf(" "); + color_printf(COLOR_RED_ALL, " .---. "); + printf(" Pacman-color v%s - libalpm v%s\n", package_version, alpm_version()); + color_printf(COLOR_YELLOW_ALL, "/ _.-'"); + color_printf(COLOR_WHITE_ALL, " .-. .-"); + color_printf(COLOR_RED_ALL, "|O O |"); + printf(" Copyright (C) 2006-2012 Pacman Development Team\n"); + color_printf(COLOR_YELLOW_ALL, "\\ '-."); + color_printf(COLOR_WHITE_ALL, " '-' '-"); + color_printf(COLOR_RED_ALL, "|~~~ |"); + printf(" Copyright (C) 2002-2006 Judd Vinet\n"); + color_printf(COLOR_YELLOW_ALL, " '--' "); + printf(" "); + color_printf(COLOR_RED_ALL, "|.-.-.|"); + printf("\n"); + printf(_(" This program may be freely redistributed under\n" + " the terms of the GNU General Public License.\n")); + printf("\n"); +} + /* pacman-color */ int _set_color_sequence(const char* name, char* dest) diff --git a/src/pacman/color.h b/src/pacman/color.h index 057f64b..90f377a 100644 --- a/src/pacman/color.h +++ b/src/pacman/color.h @@ -60,6 +60,7 @@ void color_deplist_display(const colordata_t *colors_title, const char *title, alpm_list_t *deps, unsigned short cols); void color_optdeplist_display(const colordata_t *color_title, const char *title, alpm_list_t *optdeps, unsigned short cols); +void color_version(char *package_version); int _set_color_sequence(const char* name, char* dest); void _insert_color(FILE* stream, color_t color); int parsecolorconfig(); diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index 0708dbf..421c4a3 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -216,14 +216,18 @@ static void usage(int op, const char * const myname) */ static void version(void) { - printf("\n"); - printf(" .--. Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version()); - printf("/ _.-' .-. .-. .-. Copyright (C) 2006-2012 Pacman Development Team\n"); - printf("\\ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet\n"); - printf(" '--'\n"); - printf(_(" This program may be freely redistributed under\n" - " the terms of the GNU General Public License.\n")); - printf("\n"); + if (config->color) { + color_version(PACKAGE_VERSION); + } else { + printf("\n"); + printf(" .--. Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version()); + printf("/ _.-' .-. .-. .-. Copyright (C) 2006-2012 Pacman Development Team\n"); + printf("\\ '-. '-' '-' '-' Copyright (C) 2002-2006 Judd Vinet\n"); + printf(" '--'\n"); + printf(_(" This program may be freely redistributed under\n" + " the terms of the GNU General Public License.\n")); + printf("\n"); + } } /** Sets up gettext localization. Safe to call multiple times. @@ -658,10 +662,6 @@ static int parseargs(int argc, char *argv[]) usage(config->op, mbasename(argv[0])); return 2; } - if(config->version) { - version(); - return 2; - } /* parse all other options */ optind = 1; @@ -873,6 +873,11 @@ int main(int argc, char *argv[]) if (config->color) { parsecolorconfig(); } + + if(config->version) { + version(); + return 2; + } /* noask is meant to be non-interactive */ if(config->noask) { config->noconfirm = 1; @@ -894,21 +899,43 @@ int main(int argc, char *argv[]) cleanup(EXIT_FAILURE); } #endif - + unsigned short cols = getcols(fileno(stdout)); if(config->verbose > 0) { alpm_list_t *j; - printf("Root : %s\n", alpm_option_get_root(config->handle)); - printf("Conf File : %s\n", config->configfile); - printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle)); - printf("Cache Dirs: "); - for(j = alpm_option_get_cachedirs(config->handle); j; j = alpm_list_next(j)) { - printf("%s ", (const char *)j->data); + if (config->color) { + color_string_display(COLOR_WHITE_ALL, + "Root : %s\n", alpm_option_get_root(config->handle), cols); + color_string_display(COLOR_WHITE_ALL, + "Conf File : %s\n", config->configfile, cols); + color_string_display(COLOR_WHITE_ALL, + "DB Path : %s\n", alpm_option_get_dbpath(config->handle), cols); + color_printf(COLOR_WHITE_ALL, "Cache Dirs: "); + for(j = alpm_option_get_cachedirs(config->handle); j; j = alpm_list_next(j)) { + printf("%s ", (const char *)j->data); + } + printf("\n"); + color_string_display(COLOR_WHITE_ALL, + "Lock File : %s\n", alpm_option_get_lockfile(config->handle), cols); + color_string_display(COLOR_WHITE_ALL, + "Log File : %s\n", alpm_option_get_logfile(config->handle), cols); + color_string_display(COLOR_WHITE_ALL, + "GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle), cols); + color_list_display(COLOR_WHITE_ALL, + "Targets :", pm_targets, 0); + } else { + printf("Root : %s\n", alpm_option_get_root(config->handle)); + printf("Conf File : %s\n", config->configfile); + printf("DB Path : %s\n", alpm_option_get_dbpath(config->handle)); + printf("Cache Dirs: "); + for(j = alpm_option_get_cachedirs(config->handle); j; j = alpm_list_next(j)) { + printf("%s ", (const char *)j->data); + } + printf("\n"); + printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle)); + printf("Log File : %s\n", alpm_option_get_logfile(config->handle)); + printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle)); + list_display("Targets :", pm_targets, 0); } - printf("\n"); - printf("Lock File : %s\n", alpm_option_get_lockfile(config->handle)); - printf("Log File : %s\n", alpm_option_get_logfile(config->handle)); - printf("GPG Dir : %s\n", alpm_option_get_gpgdir(config->handle)); - list_display("Targets :", pm_targets, 0); } /* Log command line */ -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/query.c | 57 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/pacman/query.c b/src/pacman/query.c index 9b1ea6f..1155b42 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -35,6 +35,7 @@ #include "package.h" #include "conf.h" #include "util.h" +#include "color.h" #define LOCAL_PREFIX "local/" @@ -270,7 +271,13 @@ static int query_search(alpm_list_t *targets) alpm_pkg_t *pkg = i->data; if(!config->quiet) { - printf(LOCAL_PREFIX "%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + if (config->color) { + color_printf(COLOR_MAGENTA_ALL, LOCAL_PREFIX); + color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg)); + color_printf(COLOR_GREEN_ALL, "%s",alpm_pkg_get_version(pkg)); + } else { + printf(LOCAL_PREFIX "%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + } } else { fputs(alpm_pkg_get_name(pkg), stdout); } @@ -279,16 +286,25 @@ static int query_search(alpm_list_t *targets) if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; - fputs(" (", stdout); - for(k = grp; k; k = alpm_list_next(k)) { - const char *group = k->data; - fputs(group, stdout); - if(alpm_list_next(k)) { - /* only print a spacer if there are more groups */ - putchar(' '); + if (config->color) { + color_printf(COLOR_BLUE_ALL, " ("); + for(k = grp; k; k = alpm_list_next(k)) { + const char *group = k->data; + color_printf(COLOR_BLUE_ALL, "%s%s", group, + (alpm_list_next(k) ? " " : ")")); + } + } else { + fputs(" (", stdout); + for(k = grp; k; k = alpm_list_next(k)) { + const char *group = k->data; + fputs(group, stdout); + if(alpm_list_next(k)) { + /* only print a spacer if there are more groups */ + putchar(' '); + } } + putchar(')'); } - putchar(')'); } /* we need a newline and initial indent first */ @@ -319,7 +335,12 @@ static int query_group(alpm_list_t *targets) for(p = grp->packages; p; p = alpm_list_next(p)) { alpm_pkg_t *pkg = p->data; - printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg)); + if (config->color) { + color_printf(COLOR_BLUE_ALL, "%s ", grp->name); + color_printf(COLOR_WHITE_ALL, "%s\n", alpm_pkg_get_name(pkg)); + } else { + printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg)); + } } } } else { @@ -331,8 +352,13 @@ static int query_group(alpm_list_t *targets) const alpm_list_t *p; for(p = grp->packages; p; p = alpm_list_next(p)) { if(!config->quiet) { - printf("%s %s\n", grpname, - alpm_pkg_get_name(p->data)); + if (config->color) { + color_printf(COLOR_BLUE_ALL, "%s ", grpname); + color_printf(COLOR_WHITE_ALL, "%s", alpm_pkg_get_name(p->data)); + } else { + printf("%s %s\n", grpname, + alpm_pkg_get_name(p->data)); + } } else { printf("%s\n", alpm_pkg_get_name(p->data)); } @@ -482,7 +508,12 @@ static int display(alpm_pkg_t *pkg) if(!config->op_q_info && !config->op_q_list && !config->op_q_changelog && !config->op_q_check) { if(!config->quiet) { - printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + if (config->color) { + color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg)); + color_printf(COLOR_GREEN_ALL, "%s\n", alpm_pkg_get_version(pkg)); + } else { + printf("%s %s\n", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); + } } else { printf("%s\n", alpm_pkg_get_name(pkg)); } -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/remove.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pacman/remove.c b/src/pacman/remove.c index 472adb5..28502f2 100644 --- a/src/pacman/remove.c +++ b/src/pacman/remove.c @@ -28,6 +28,7 @@ /* pacman */ #include "pacman.h" #include "util.h" +#include "color.h" #include "conf.h" static int fnmatch_cmp(const void *pattern, const void *string) @@ -119,7 +120,11 @@ int pacman_remove(alpm_list_t *targets) for(i = data; i; i = alpm_list_next(i)) { alpm_depmissing_t *miss = i->data; char *depstring = alpm_dep_compute_string(miss->depend); - printf(_(":: %s: requires %s\n"), miss->target, depstring); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: %s: requires %s\n"), miss->target, depstring); + } else { + printf(_(":: %s: requires %s\n"), miss->target, depstring); + } free(depstring); } break; -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- src/pacman/sync.c | 151 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 119 insertions(+), 32 deletions(-) diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 532a667..2174a5d 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -36,6 +36,7 @@ #include "util.h" #include "package.h" #include "conf.h" +#include "color.h" static int unlink_verbose(const char *pathname, int ignore_missing) { @@ -144,7 +145,11 @@ static int sync_cleandb_all(void) int ret = 0; dbpath = alpm_option_get_dbpath(config->handle); - printf(_("Database directory: %s\n"), dbpath); + if (config->color) { + color_printf(COLOR_WHITE_COLON, _("Database directory: %s\n"), dbpath); + } else { + printf(_("Database directory: %s\n"), dbpath); + } if(!yesno(_("Do you want to remove unused repositories?"))) { return 0; } @@ -178,7 +183,11 @@ static int sync_cleancache(int level) } if(level == 1) { - printf(_("Packages to keep:\n")); + if (config->color) { + color_printf(COLOR_WHITE_COLON, _("Packages to keep:\n")); + } else { + printf(_("Packages to keep:\n")); + } if(config->cleanmethod & PM_CLEAN_KEEPINST) { printf(_(" All locally installed packages\n")); } @@ -193,7 +202,11 @@ static int sync_cleancache(int level) DIR *dir; struct dirent *ent; - printf(_("Cache directory: %s\n"), (const char *)i->data); + if (config->color) { + color_printf(COLOR_WHITE_COLON, _("Cache directory: %s\n"), (const char *)i->data); + } else { + printf(_("Cache directory: %s\n"), (const char *)i->data); + } if(level == 1) { if(!yesno(_("Do you want to remove all other packages from cache?"))) { @@ -360,9 +373,17 @@ static void print_installed(alpm_db_t *db_local, alpm_pkg_t *pkg) if(lpkg) { const char *lpkgver = alpm_pkg_get_version(lpkg); if(strcmp(lpkgver,pkgver) == 0) { - printf(" [%s]", _("installed")); + if (config->color) { + color_printf(COLOR_CYAN_ALL, " [%s]", _("installed")); + } else { + printf(" [%s]", _("installed")); + } } else { - printf(" [%s: %s]", _("installed"), lpkgver); + if (config->color) { + color_printf(COLOR_CYAN_ALL, " [%s: %s]", _("installed"), lpkgver); + } else { + printf(" [%s: %s]", _("installed"), lpkgver); + } } } } @@ -397,8 +418,14 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) alpm_pkg_t *pkg = j->data; if(!config->quiet) { - printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); + if (config->color) { + color_printf(COLOR_MAGENTA_ALL, "%s/", alpm_db_get_name(db)); + color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg)); + color_printf(COLOR_GREEN_ALL, "%s", alpm_pkg_get_version(pkg)); + } else { + printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg)); + } } else { fputs(alpm_pkg_get_name(pkg), stdout); } @@ -406,16 +433,25 @@ static int sync_search(alpm_list_t *syncs, alpm_list_t *targets) if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; - fputs(" (", stdout); - for(k = grp; k; k = alpm_list_next(k)) { - const char *group = k->data; - fputs(group, stdout); - if(alpm_list_next(k)) { - /* only print a spacer if there are more groups */ - putchar(' '); + if (config->color) { + fputs(" (", stdout); + for(k = grp; k; k = alpm_list_next(k)) { + const char *group = k->data; + color_printf(COLOR_BLUE_ALL, "%s%s", group, + (alpm_list_next(k) ? " " : ")")); } + } else { + fputs(" (", stdout); + for(k = grp; k; k = alpm_list_next(k)) { + const char *group = k->data; + fputs(group, stdout); + if(alpm_list_next(k)) { + /* only print a spacer if there are more groups */ + putchar(' '); + } + } + putchar(')'); } - putchar(')'); } print_installed(db_local, pkg); @@ -450,8 +486,13 @@ static int sync_group(int level, alpm_list_t *syncs, alpm_list_t *targets) /* get names of packages in group */ for(k = grp->packages; k; k = alpm_list_next(k)) { if(!config->quiet) { - printf("%s %s\n", grpname, - alpm_pkg_get_name(k->data)); + if (config->color) { + color_printf(COLOR_BLUE_ALL, "%s ", grpname); + color_printf(COLOR_WHITE_ALL, "%s", alpm_pkg_get_name(k->data)); + } else { + printf("%s %s\n", grpname, + alpm_pkg_get_name(k->data)); + } } else { printf("%s\n", alpm_pkg_get_name(k->data)); } @@ -591,8 +632,14 @@ static int sync_list(alpm_list_t *syncs, alpm_list_t *targets) alpm_pkg_t *pkg = j->data; if(!config->quiet) { - printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), - alpm_pkg_get_version(pkg)); + if (config->color) { + color_printf(COLOR_MAGENTA_ALL, "%s ", alpm_db_get_name(db)); + color_printf(COLOR_WHITE_ALL, "%s ", alpm_pkg_get_name(pkg)); + color_printf(COLOR_GREEN_ALL, "%s ", alpm_pkg_get_version(pkg)); + } else { + printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg), + alpm_pkg_get_version(pkg)); + } print_installed(db_local, pkg); printf("\n"); } else { @@ -661,8 +708,13 @@ static int process_group(alpm_list_t *dbs, const char *group, int error) } if(config->print == 0) { - printf(_(":: There are %d members in group %s:\n"), count, - group); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: There are %d members in group %s:\n"), count, + group); + } else { + printf(_(":: There are %d members in group %s:\n"), count, + group); + } select_display(pkgs); char *array = malloc(count); if(!array) { @@ -786,7 +838,11 @@ static int sync_trans(alpm_list_t *targets) } if(config->op_s_upgrade) { - printf(_(":: Starting full system upgrade...\n")); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: Starting full system upgrade...\n")); + } else { + printf(_(":: Starting full system upgrade...\n")); + } alpm_logaction(config->handle, "starting full system upgrade\n"); if(alpm_sync_sysupgrade(config->handle, config->op_s_upgrade >= 2) == -1) { pm_printf(ALPM_LOG_ERROR, "%s\n", alpm_strerror(alpm_errno(config->handle))); @@ -812,14 +868,22 @@ int sync_prepare_execute(void) case ALPM_ERR_PKG_INVALID_ARCH: for(i = data; i; i = alpm_list_next(i)) { const char *pkg = i->data; - printf(_(":: package %s does not have a valid architecture\n"), pkg); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: package %s does not have a valid architecture\n"), pkg); + } else { + printf(_(":: package %s does not have a valid architecture\n"), pkg); + } } break; case ALPM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { alpm_depmissing_t *miss = i->data; char *depstring = alpm_dep_compute_string(miss->depend); - printf(_(":: %s: requires %s\n"), miss->target, depstring); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: %s: requires %s\n"), miss->target, depstring); + } else { + printf(_(":: %s: requires %s\n"), miss->target, depstring); + } free(depstring); } break; @@ -828,12 +892,22 @@ int sync_prepare_execute(void) alpm_conflict_t *conflict = i->data; /* only print reason if it contains new information */ if(conflict->reason->mod == ALPM_DEP_MOD_ANY) { - printf(_(":: %s and %s are in conflict\n"), - conflict->package1, conflict->package2); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict\n"), + conflict->package1, conflict->package2); + } else { + printf(_(":: %s and %s are in conflict\n"), + conflict->package1, conflict->package2); + } } else { char *reason = alpm_dep_compute_string(conflict->reason); - printf(_(":: %s and %s are in conflict (%s)\n"), - conflict->package1, conflict->package2, reason); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: %s and %s are in conflict (%s)\n"), + conflict->package1, conflict->package2, reason); + } else { + printf(_(":: %s and %s are in conflict (%s)\n"), + conflict->package1, conflict->package2, reason); + } free(reason); } } @@ -887,8 +961,13 @@ int sync_prepare_execute(void) conflict->file, conflict->target, conflict->ctarget); break; case ALPM_FILECONFLICT_FILESYSTEM: - printf(_("%s: %s exists in filesystem\n"), - conflict->target, conflict->file); + if (config->color) { + color_printf(COLOR_WHITE_COLON, _("%s: %s exists in filesystem\n"), + conflict->target, conflict->file); + } else { + printf(_("%s: %s exists in filesystem\n"), + conflict->target, conflict->file); + } break; } } @@ -906,7 +985,11 @@ int sync_prepare_execute(void) break; } /* TODO: stderr? */ - printf(_("Errors occurred, no packages were upgraded.\n")); + if (config->color) { + color_printf(COLOR_RED_ALL, _("Errors occurred, no packages were upgraded.\n")); + } else { + printf(_("Errors occurred, no packages were upgraded.\n")); + } retval = 1; goto cleanup; } @@ -953,7 +1036,11 @@ int pacman_sync(alpm_list_t *targets) if(config->op_s_sync) { /* grab a fresh package list */ - printf(_(":: Synchronizing package databases...\n")); + if (config->color) { + color_printf(COLOR_DOUBLECOLON, _(":: Synchronizing package databases...\n")); + } else { + printf(_(":: Synchronizing package databases...\n")); + } alpm_logaction(config->handle, "synchronizing package lists\n"); if(!sync_synctree(config->op_s_sync, sync_dbs)) { return 1; -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- etc/Makefile.am | 5 +++-- etc/color.conf.in | 46 ++++++++++++++++++++++++++++++++++++++++++++++ etc/pacman.conf.in | 1 + 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 etc/color.conf.in diff --git a/etc/Makefile.am b/etc/Makefile.am index 58a80bd..ff98545 100644 --- a/etc/Makefile.am +++ b/etc/Makefile.am @@ -1,5 +1,5 @@ -dist_sysconf_DATA = makepkg.conf pacman.conf -EXTRA_DIST = makepkg.conf.in pacman.conf.in +dist_sysconf_DATA = makepkg.conf pacman.conf color.conf +EXTRA_DIST = makepkg.conf.in pacman.conf.in color.conf.in # Files that should be removed, but which Automake does not know. MOSTLYCLEANFILES = $(dist_sysconf_DATA) @@ -28,5 +28,6 @@ $(dist_sysconf_DATA): Makefile makepkg.conf: $(srcdir)/makepkg.conf.in pacman.conf: $(srcdir)/pacman.conf.in +color.conf: $(srcdir)/color.conf.in # vim:set ts=2 sw=2 noet: diff --git a/etc/color.conf.in b/etc/color.conf.in new file mode 100644 index 0000000..4978d4e --- /dev/null +++ b/etc/color.conf.in @@ -0,0 +1,46 @@ +# Configuration for pacman-color +# ------------------------------ +# in default are all colors "intensive", +# it looks much better on black backround +# +# valid colors: +# black +# red +# green +# yellow +# blue +# magenta +# cyan +# white +# gray +# intensive red +# intensive green +# intensive yellow +# intensive blue +# intensive magenta +# intensive cyan +# intensive white +# intensive foreground +# none + +# error: prefix, fail, Remove (?):, MISSING +#Red = intensive red + +# done, success, pkg version, Not Modified +#Green = intensive green + +# warning: prefix, Targets (?):, MODIFIED +#Yellow = intensive yellow + +# :: prefix, pkg group, counter in install proces +#Blue = intensive blue + +# repo name, package file name +#Magenta = intensive magenta + +# url, flag installed +#Cyan = intensive cyan + +# messages with :: prefix, titles, etc +#White = intensive foreground + diff --git a/etc/pacman.conf.in b/etc/pacman.conf.in index 4c72724..75561df 100644 --- a/etc/pacman.conf.in +++ b/etc/pacman.conf.in @@ -31,6 +31,7 @@ Architecture = auto # Misc options #UseSyslog #TotalDownload +#Color CheckSpace #VerbosePkgLists -- 1.7.11.4
Signed-off-by: Daniel Wallace <daniel.wallace@gatech.edu> --- contrib/bash_completion.in | 2 +- contrib/zsh_completion.in | 1 + doc/pacman.8.txt | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/bash_completion.in b/contrib/bash_completion.in index b0901af..b20cb5d 100644 --- a/contrib/bash_completion.in +++ b/contrib/bash_completion.in @@ -105,7 +105,7 @@ _pacman() { info list needed nodeps print refresh recursive search sysupgrade' 'c g i l p s u w y') upgrade=('asdeps asexplicit force needed nodeps print recursive' 'p') - common=('arch cachedir config dbpath debug help logfile noconfirm + common=('arch cachedir color config dbpath debug help logfile noconfirm noprogressbar noscriptlet quiet root verbose' 'b d h q r v') core=('database help query remove sync upgrade version' 'D Q R S U V h') diff --git a/contrib/zsh_completion.in b/contrib/zsh_completion.in index 84ee93c..306bbe8 100644 --- a/contrib/zsh_completion.in +++ b/contrib/zsh_completion.in @@ -21,6 +21,7 @@ _pacman_opts_common=( '-r[Set alternate installation root]:installation root:_files -/' '-v[Be more verbose]' '--cachedir[Alternate package cache location]:cache_location:_files -/' + '--color[Colorize pacman's output]' '--config[An alternate configuration file]:config file:_files' '--logfile[An alternate log file]:config file:_files' '--noconfirm[Do not ask for confirmation]' diff --git a/doc/pacman.8.txt b/doc/pacman.8.txt index 0ad8188..8db669d 100644 --- a/doc/pacman.8.txt +++ b/doc/pacman.8.txt @@ -146,6 +146,9 @@ Options and they are tried in the order they are passed to pacman. *NOTE*: this is an absolute path, the root path is not automatically prepended. +*\--color* :: + Colorize pacman's ouput. + *\--config* <file>:: Specify an alternate configuration file. -- 1.7.11.4
participants (2)
-
Allan McRae
-
Daniel Wallace