Dne 5.1.2011 17:54, Dan McGee napsal(a):
2011/1/5 Vojtěch Gondžala<vojtech.gondz...@gmail.com>:
Dne 5.1.2011 17:01, Sven-Hendrik Haase napsal(a):

Hey,

I'm not vogo but I know he's been trying to get his work upstream since
3 years and was rejected last time in order to wait for pacman 3.1. We
passed that long ago and I think pacman-color should be given another
chance to go upstream.
The AUR package with the patch is here:
http://aur.archlinux.org/packages.php?ID=11827

It is a rather popular package so it might make a fine addition.

-- Sven-Hendrik


Hi,

I'm not sure that the patch is ideal for upstream, it's need little bit
refactor. I'm too busy to do it now, but next release is far. I can do some
changes at the weekend, if other developers want accept this patch.

Oooh, nothing like a hot-button topic to bring traffic to the ML. :)

Thoughts:
1. Vogo- no rush, it's obviously been baking a while, no need to pull
it out of the oven early so take your time.
2. I think we'd (the core and regular pacman devs) support this if all
done right.
3. We need to ensure this doesn't interfere with i18n concerns,
especially non-latin alphabets. I have no idea about the current
state, but generate the zh_CN.utf8 locale on your box and try running
this patch under that as a quick test.
4. git now does color, in C code, in a pretty platform-agnostic way.
They've even managed to add a emulation layer for Windows. I don't
think we need all of that, but using their code as a resource is
probably a smart idea. See color.h, color.c, and compat/winansi.c in
their codebase.
5. Does this handle redirects to non-terminals OK; is the
configuration simple but effective, etc.
6. Do we have people willing to review large patches like this? Allan,
Nagy, Xavier and I get very bogged down when we are the only people
looking over code changes and lose interest because we don't get to
enjoy writing our own code.
7. Do we have people willing to help Vogo make changes to this patch
once it is submitted and reviewed?
8. A patchset rather than a patch is easier to review, and moving some
of this stuff to a color.c/color.h would be helpful (and move the
color definitions to color.h so you don't need the extern junk).

-Dan


Hi all,

there is my first idea how colorize output of pacman. It's simple and function. It's using an ansi escape sequencies, I looked for solution in a GNU coreutils (ls, grep...) and it's same. Diffred solution is used in utility tput but is needed ncurses and ncurses isn't good dependency for pacman, in my opinion.

This patch doesn't support configuration of used colors, but it adding 'nocolor' option in pacman.conf and '--nocolor' argument, for disable colorize output. I tested patch on some locale and works good with all.

Any idea how do it beter?


--
Vojtěch "vogo" Gondžala
diff -Naur a/src/pacman/callback.c b/src/pacman/callback.c
--- a/src/pacman/callback.c	2011-01-09 13:33:08.920000004 +0100
+++ b/src/pacman/callback.c	2011-01-09 15:05:03.000000000 +0100
@@ -226,7 +226,7 @@
 			printf("%s", (char*)data1);
 			break;
 		case PM_TRANS_EVT_RETRIEVE_START:
-			printf(_(":: Retrieving packages from %s...\n"), (char*)data1);
+			pm_printf_info(_("Retrieving packages from %s...\n"), (char*)data1);
 			break;
 		case PM_TRANS_EVT_DISKSPACE_START:
 			if(config->noprogressbar) {
@@ -255,11 +255,11 @@
 {
 	switch(event) {
 		case PM_TRANS_CONV_INSTALL_IGNOREPKG:
-			*response = yesno(_(":: %s is in IgnorePkg/IgnoreGroup. Install anyway?"),
+			*response = yesno(_("%s is in IgnorePkg/IgnoreGroup. Install anyway?"),
 							  alpm_pkg_get_name(data1));
 			break;
 		case PM_TRANS_CONV_REPLACE_PKG:
-			*response = yesno(_(":: Replace %s with %s/%s?"),
+			*response = yesno(_("Replace %s with %s/%s?"),
 					alpm_pkg_get_name(data1),
 					(char *)data3,
 					alpm_pkg_get_name(data2));
@@ -268,12 +268,12 @@
 			/* 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?"),
+				*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?"),
+				*response = noyes(_("%s and %s are in conflict (%s). Remove %s?"),
 						(char *)data1,
 						(char *)data2,
 						(char *)data3,
@@ -288,11 +288,11 @@
 					namelist = alpm_list_add(namelist,
 							(char *)alpm_pkg_get_name(i->data));
 				}
-				printf(_n(
-							":: The following package cannot be upgraded due to unresolvable dependencies:\n",
-							":: The following packages cannot be upgraded due to unresolvable dependencies:\n",
+				pm_printf_info(_n(
+							"The following package cannot be upgraded due to unresolvable dependencies:\n",
+							"The following packages cannot be upgraded due to unresolvable dependencies:\n",
 							alpm_list_count(namelist)));
-				list_display("     ", namelist);
+				list_display(COLOR_NONE, "     ", namelist);
 				printf("\n");
 				*response = noyes(_n(
 							"Do you want to skip the above package for this upgrade?",
@@ -303,7 +303,7 @@
 			break;
 		case PM_TRANS_CONV_LOCAL_NEWER:
 			if(!config->op_s_downloadonly) {
-				*response = yesno(_(":: %s-%s: local version is newer. Upgrade anyway?"),
+				*response = yesno(_("%s-%s: local version is newer. Upgrade anyway?"),
 						alpm_pkg_get_name(data1),
 						alpm_pkg_get_version(data1));
 			} else {
@@ -311,7 +311,7 @@
 			}
 			break;
 		case PM_TRANS_CONV_CORRUPTED_PKG:
-			*response = yesno(_(":: File %s is corrupted. Do you want to delete it?"),
+			*response = yesno(_("File %s is corrupted. Do you want to delete it?"),
 					(char *)data1);
 			break;
 	}
@@ -435,8 +435,9 @@
 
 	}
 
-	printf("(%*ld/%*ld) %ls%-*s", digits, (unsigned long)current,
-			digits, (unsigned long)howmany, wcstr, padwid, "");
+	color_printf(COLOR_BLUE, "(%*ld/%*ld)", digits, (unsigned long)current,
+			digits, (unsigned long)howmany);
+	printf(" %ls%-*s", wcstr, padwid, "");
 
 	free(wcstr);
 
@@ -447,7 +448,8 @@
 		alpm_list_t *i = NULL;
 		on_progress = 0;
 		for(i = output; i; i = i->next) {
-			printf("%s", (char *)i->data);
+			pm_printf(((cb_msg_t *)i->data)->level, "%s", ((cb_msg_t *)i->data)->msg);
+			free(((cb_msg_t *)i->data)->msg);
 		}
 		fflush(stdout);
 		FREELIST(output);
@@ -665,9 +667,15 @@
 
 	if(on_progress) {
 		char *string = NULL;
-		pm_vasprintf(&string, level, fmt, args);
+		vasprintf(&string, fmt, args);
 		if(string != NULL) {
-			output = alpm_list_add(output, string);
+			cb_msg_t *cb_msg = NULL;
+			cb_msg = calloc(1, sizeof(cb_msg_t));
+			if (cb_msg != NULL) {
+				cb_msg->level = level;
+				cb_msg->msg = string;
+				output = alpm_list_add(output, cb_msg);
+			}
 		}
 	} else {
 		pm_vfprintf(stdout, level, fmt, args);
diff -Naur a/src/pacman/callback.h b/src/pacman/callback.h
--- a/src/pacman/callback.h	2011-01-09 13:33:08.920000004 +0100
+++ b/src/pacman/callback.h	2011-01-09 13:46:05.000000000 +0100
@@ -24,6 +24,12 @@
 
 #include <alpm.h>
 
+/* struct for callback messages */
+typedef struct __cb_msg_t {
+	pmloglevel_t level;
+	char *msg;
+} cb_msg_t;
+
 /* callback to handle messages/notifications from libalpm transactions */
 void cb_trans_evt(pmtransevt_t event, void *data1, void *data2);
 
diff -Naur a/src/pacman/conf.c b/src/pacman/conf.c
--- a/src/pacman/conf.c	2011-01-09 13:33:08.920000004 +0100
+++ b/src/pacman/conf.c	2011-01-09 14:30:23.000000000 +0100
@@ -43,6 +43,7 @@
 	/* defaults which may get overridden later */
 	newconfig->op = PM_OP_MAIN;
 	newconfig->logmask = PM_LOG_ERROR | PM_LOG_WARNING;
+	newconfig->nocolor = 0;
 	/* CONFFILE is defined at compile-time */
 	newconfig->configfile = strdup(CONFFILE);
 
diff -Naur a/src/pacman/conf.h b/src/pacman/conf.h
--- a/src/pacman/conf.h	2011-01-09 13:33:08.920000004 +0100
+++ b/src/pacman/conf.h	2011-01-09 14:57:52.000000000 +0100
@@ -29,6 +29,7 @@
 	unsigned short version;
 	unsigned short help;
 	unsigned short noconfirm;
+	unsigned short nocolor;
 	unsigned short noprogressbar;
 	unsigned short logmask;
 	unsigned short print;
@@ -97,6 +98,7 @@
 	OP_IGNORE,
 	OP_DEBUG,
 	OP_NOPROGRESSBAR,
+	OP_NOCOLOR,
 	OP_NOSCRIPTLET,
 	OP_ASK,
 	OP_CACHEDIR,
diff -Naur a/src/pacman/package.c b/src/pacman/package.c
--- a/src/pacman/package.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/package.c	2011-01-09 15:20:59.000000000 +0100
@@ -91,47 +91,50 @@
 	}
 
 	/* actual output */
-	string_display(_("Name           :"), alpm_pkg_get_name(pkg));
-	string_display(_("Version        :"), alpm_pkg_get_version(pkg));
-	string_display(_("URL            :"), alpm_pkg_get_url(pkg));
-	list_display(_("Licenses       :"), alpm_pkg_get_licenses(pkg));
-	list_display(_("Groups         :"), alpm_pkg_get_groups(pkg));
-	list_display(_("Provides       :"), alpm_pkg_get_provides(pkg));
-	list_display(_("Depends On     :"), depstrings);
-	list_display_linebreak(_("Optional Deps  :"), alpm_pkg_get_optdepends(pkg));
+	color_printf(COLOR_WHITE, _("Name           :"));
+	color_printf(COLOR_WHITE, " %s\n", alpm_pkg_get_name(pkg));
+	color_printf(COLOR_WHITE, _("Version        :"));
+	color_printf(COLOR_GREEN, " %s\n", alpm_pkg_get_version(pkg));
+	color_printf(COLOR_WHITE, _("URL            :"));
+	color_printf(COLOR_CYAN, " %s\n", alpm_pkg_get_url(pkg));
+	list_display(COLOR_WHITE, _("Licenses       :"), alpm_pkg_get_licenses(pkg));
+	list_display(COLOR_WHITE, _("Groups         :"), alpm_pkg_get_groups(pkg));
+	list_display(COLOR_WHITE, _("Provides       :"), alpm_pkg_get_provides(pkg));
+	list_display(COLOR_WHITE, _("Depends On     :"), depstrings);
+	list_display_linebreak(COLOR_WHITE, _("Optional Deps  :"), alpm_pkg_get_optdepends(pkg));
 	if(level > 0 || level < -1) {
-		list_display(_("Required By    :"), requiredby);
+		list_display(COLOR_WHITE, _("Required By    :"), requiredby);
 	}
-	list_display(_("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
-	list_display(_("Replaces       :"), alpm_pkg_get_replaces(pkg));
+	list_display(COLOR_WHITE, _("Conflicts With :"), alpm_pkg_get_conflicts(pkg));
+	list_display(COLOR_WHITE, _("Replaces       :"), alpm_pkg_get_replaces(pkg));
 	if(level < 0) {
-		printf(_("Download Size  : %6.2f K\n"),
-			(float)alpm_pkg_get_size(pkg) / 1024.0);
+		color_printf(COLOR_WHITE, _("Download Size  :"));
+		printf(" %6.2f K\n", (float)alpm_pkg_get_size(pkg) / 1024.0);
 	}
 	if(level == 0) {
-		printf(_("Compressed Size: %6.2f K\n"),
-			(float)alpm_pkg_get_size(pkg) / 1024.0);
+		color_printf(COLOR_WHITE, _("Compressed Size:"));
+		printf(" %6.2f K\n", (float)alpm_pkg_get_size(pkg) / 1024.0);
 	}
 
-	printf(_("Installed Size : %6.2f K\n"),
-			(float)alpm_pkg_get_isize(pkg) / 1024.0);
-	string_display(_("Packager       :"), alpm_pkg_get_packager(pkg));
-	string_display(_("Architecture   :"), alpm_pkg_get_arch(pkg));
-	string_display(_("Build Date     :"), bdatestr);
+	color_printf(COLOR_WHITE, _("Installed Size :"));
+	printf(" %6.2f K\n", (float)alpm_pkg_get_isize(pkg) / 1024.0);
+	string_display(COLOR_WHITE, _("Packager       :"), alpm_pkg_get_packager(pkg));
+	string_display(COLOR_WHITE, _("Architecture   :"), alpm_pkg_get_arch(pkg));
+	string_display(COLOR_WHITE, _("Build Date     :"), bdatestr);
 	if(level > 0) {
-		string_display(_("Install Date   :"), idatestr);
-		string_display(_("Install Reason :"), reason);
+		string_display(COLOR_WHITE, _("Install Date   :"), idatestr);
+		string_display(COLOR_WHITE, _("Install Reason :"), reason);
 	}
 	if(level >= 0) {
-		string_display(_("Install Script :"),
+		string_display(COLOR_WHITE, _("Install Script :"),
 				alpm_pkg_has_scriptlet(pkg) ?  _("Yes") : _("No"));
 	}
 
 	/* MD5 Sum for sync package */
 	if(level < 0) {
-		string_display(_("MD5 Sum        :"), alpm_pkg_get_md5sum(pkg));
+		string_display(COLOR_WHITE, _("MD5 Sum        :"), alpm_pkg_get_md5sum(pkg));
 	}
-	string_display(_("Description    :"), alpm_pkg_get_desc(pkg));
+	string_display(COLOR_WHITE, _("Description    :"), alpm_pkg_get_desc(pkg));
 
 	/* Print additional package info if info flag passed more than once */
 	if(level > 1) {
@@ -152,7 +155,8 @@
 	if(pkg == NULL) {
 		return;
 	}
-	string_display(_("Repository     :"), treename);
+	color_printf(COLOR_WHITE, _("Repository     :"));
+	color_printf(COLOR_MAGENTA, " %s\n", treename);
 	/* invert the level since we are a sync package */
 	dump_pkg_full(pkg, -level);
 }
@@ -163,7 +167,7 @@
 {
 	alpm_list_t *i;
 	const char *root = alpm_option_get_root();
-	printf(_("Backup Files:\n"));
+	color_printf(COLOR_WHITE, _("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)) {
@@ -190,13 +194,16 @@
 
 				/* if checksums don't match, file has been modified */
 				if (strcmp(md5sum, ptr) != 0) {
-					printf(_("MODIFIED\t%s\n"), path);
+					color_printf(COLOR_YELLOW, _("MODIFIED\t"));
+					printf("%s\n", path);
 				} else {
-					printf(_("Not Modified\t%s\n"), path);
+					color_printf(COLOR_GREEN, _("Not Modified\t"));
+					printf("%s\n", path);
 				}
 				free(md5sum);
 			} else {
-				printf(_("MISSING\t\t%s\n"), path);
+				color_printf(COLOR_RED, _("MISSING\t\t"));
+				printf("%s\n", path);
 			}
 			free(str);
 		}
diff -Naur a/src/pacman/pacman.c b/src/pacman/pacman.c
--- a/src/pacman/pacman.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/pacman.c	2011-01-09 15:21:25.000000000 +0100
@@ -205,6 +205,7 @@
 		addlist(_("      --debug          display debug messages\n"));
 		addlist(_("      --logfile <path> set an alternate log file\n"));
 		addlist(_("      --noconfirm      do not ask for any confirmation\n"));
+		addlist(_("      --nocolor        disable colorized output messages\n"));
 	}
 	list = alpm_list_msort(list, alpm_list_count(list), options_cmp);
 	for (i = list; i; i = alpm_list_next(i)) {
@@ -218,12 +219,16 @@
  */
 static void version(void)
 {
-	printf("\n");
-	printf(" .--.                  Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version());
-	printf("/ _.-' .-.  .-.  .-.   Copyright (C) 2006-2011 Pacman Development Team\n");
-	printf("\\  '-. '-'  '-'  '-'   Copyright (C) 2002-2006 Judd Vinet\n");
-	printf(" '--'\n");
-	printf(_("                       This program may be freely redistributed under\n"
+	color_printf(COLOR_YELLOW, " .--. ");
+	printf("                 Pacman v%s - libalpm v%s\n", PACKAGE_VERSION, alpm_version());
+	color_printf(COLOR_YELLOW, "/ _.-'");
+	color_printf(COLOR_WHITE, " .-.  .-.  .-.");
+	printf("   Copyright (C) 2006-2011 Pacman Development Team\n");
+	color_printf(COLOR_YELLOW, "\\  '-.");
+	color_printf(COLOR_WHITE, " '-'  '-'  '-'");
+	printf("   Copyright (C) 2002-2006 Judd Vinet\n");
+	color_printf(COLOR_YELLOW, " '--'\n");
+ 	printf(_("                       This program may be freely redistributed under\n"
 	         "                       the terms of the GNU General Public License.\n"));
 	printf("\n");
 }
@@ -506,6 +511,7 @@
 			config->logfile = strndup(optarg, PATH_MAX);
 			break;
 		case OP_NOCONFIRM: config->noconfirm = 1; break;
+		case OP_NOCOLOR: config->nocolor = 1; break;
 		case 'b':
 			check_optarg();
 			config->dbpath = strdup(optarg);
@@ -682,6 +688,7 @@
 		{"downloadonly", no_argument,     0, 'w'},
 		{"refresh",    no_argument,       0, 'y'},
 		{"noconfirm",  no_argument,       0, OP_NOCONFIRM},
+		{"nocolor",    no_argument,       0, OP_NOCOLOR},
 		{"config",     required_argument, 0, OP_CONFIG},
 		{"ignore",     required_argument, 0, OP_IGNORE},
 		{"debug",      optional_argument, 0, OP_DEBUG},
@@ -947,6 +954,9 @@
 		} else if(strcmp(key, "ILoveCandy") == 0) {
 			config->chomp = 1;
 			pm_printf(PM_LOG_DEBUG, "config: chomp\n");
+		} else if(strcmp(key, "NoColor") == 0) {
+			config->nocolor = 1;
+			pm_printf(PM_LOG_DEBUG, "config: nocolor\n");
 		} else if(strcmp(key, "ShowSize") == 0) {
 			config->showsize = 1;
 			pm_printf(PM_LOG_DEBUG, "config: showsize\n");
@@ -1430,7 +1440,7 @@
 		printf("\n");
 		printf("Lock File : %s\n", alpm_option_get_lockfile());
 		printf("Log File  : %s\n", alpm_option_get_logfile());
-		list_display("Targets   :", pm_targets);
+		list_display(COLOR_NONE, "Targets   :", pm_targets);
 	}
 
 	/* Opening local database */
diff -Naur a/src/pacman/query.c b/src/pacman/query.c
--- a/src/pacman/query.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/query.c	2011-01-09 15:28:48.000000000 +0100
@@ -220,7 +220,9 @@
 		pmpkg_t *pkg = alpm_list_getdata(i);
 
 		if (!config->quiet) {
-			printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+			color_printf(COLOR_MAGENTA, "local/");
+			color_printf(COLOR_WHITE, "%s ", alpm_pkg_get_name(pkg));
+			color_printf(COLOR_GREEN, "%s", alpm_pkg_get_version(pkg));
 		} else {
 			printf("%s", alpm_pkg_get_name(pkg));
 		}
@@ -237,16 +239,16 @@
 		if (!config->quiet) {
 			if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
 				alpm_list_t *k;
-				printf(" (");
+				color_printf(COLOR_BLUE, " (");
 				for(k = grp; k; k = alpm_list_next(k)) {
 					const char *group = alpm_list_getdata(k);
-					printf("%s", group);
+					color_printf(COLOR_BLUE, "%s", group);
 					if(alpm_list_next(k)) {
 						/* only print a spacer if there are more groups */
 						printf(" ");
 					}
 				}
-				printf(")");
+				color_printf(COLOR_BLUE, ")");
 			}
 
 			/* we need a newline and initial indent first */
@@ -278,7 +280,8 @@
 			packages = alpm_grp_get_pkgs(grp);
 
 			for(p = packages; p; p = alpm_list_next(p)) {
-				printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p)));
+				color_printf(COLOR_BLUE, "%s ", grpname);
+				color_printf(COLOR_WHITE, "%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
 			}
 		}
 	} else {
@@ -290,8 +293,8 @@
 				const alpm_list_t *p, *packages = alpm_grp_get_pkgs(grp);
 				for(p = packages; p; p = alpm_list_next(p)) {
 					if(!config->quiet) {
-						printf("%s %s\n", grpname,
-								alpm_pkg_get_name(alpm_list_getdata(p)));
+						color_printf(COLOR_BLUE, "%s ", grpname);
+						color_printf(COLOR_WHITE, "%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
 					} else {
 						printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(p)));
 					}
@@ -439,7 +442,8 @@
 	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));
+			color_printf(COLOR_WHITE, "%s ", alpm_pkg_get_name(pkg));
+			color_printf(COLOR_GREEN, "%s\n", alpm_pkg_get_version(pkg));
 		} else {
 			printf("%s\n", alpm_pkg_get_name(pkg));
 		}
diff -Naur a/src/pacman/remove.c b/src/pacman/remove.c
--- a/src/pacman/remove.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/remove.c	2011-01-09 13:59:02.000000000 +0100
@@ -79,7 +79,7 @@
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *pkg = alpm_list_getdata(i);
-					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+					pm_printf_info(_("package %s does not have a valid architecture\n"), pkg);
 				}
 				break;
 			case PM_ERR_UNSATISFIED_DEPS:
@@ -87,7 +87,7 @@
 					pmdepmissing_t *miss = alpm_list_getdata(i);
 					pmdepend_t *dep = alpm_miss_get_dep(miss);
 					char *depstring = alpm_dep_compute_string(dep);
-					printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss),
+					pm_printf_info(_("%s: requires %s\n"), alpm_miss_get_target(miss),
 							depstring);
 					free(depstring);
 				}
diff -Naur a/src/pacman/sync.c b/src/pacman/sync.c
--- a/src/pacman/sync.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/sync.c	2011-01-09 15:24:24.000000000 +0100
@@ -124,7 +124,7 @@
 	int ret = 0;
 
 	dbpath = alpm_option_get_dbpath();
-	printf(_("Database directory: %s\n"), dbpath);
+	string_display(COLOR_WHITE, _("Database directory:"), dbpath);
 	if(!yesno(_("Do you want to remove unused repositories?"))) {
 		return(0);
 	}
@@ -147,7 +147,7 @@
 	int ret = 0;
 
 	for(i = alpm_option_get_cachedirs(); i; i = alpm_list_next(i)) {
-		printf(_("Cache directory: %s\n"), (char*)alpm_list_getdata(i));
+		string_display(COLOR_WHITE, _("Cache directory:"), (char*)alpm_list_getdata(i));
 	}
 
 	if(level == 1) {
@@ -303,9 +303,9 @@
 	if(lpkg) {
 		const char *lpkgver = alpm_pkg_get_version(lpkg);
 		if(strcmp(lpkgver,pkgver) == 0) {
-			printf(" [%s]", _("installed"));
+			color_printf(COLOR_CYAN, " [%s]", _("installed"));
 		} else {
-			printf(" [%s: %s]", _("installed"), lpkgver);
+			color_printf(COLOR_CYAN, " [%s: %s]", _("installed"), lpkgver);
 		}
 	}
 }
@@ -337,8 +337,9 @@
 			pmpkg_t *pkg = alpm_list_getdata(j);
 
 			if (!config->quiet) {
-				printf("%s/%s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
-							 alpm_pkg_get_version(pkg));
+				color_printf(COLOR_MAGENTA, "%s/", alpm_db_get_name(db));
+				color_printf(COLOR_WHITE, "%s ", alpm_pkg_get_name(pkg));
+				color_printf(COLOR_GREEN, "%s", alpm_pkg_get_version(pkg));
 			} else {
 				printf("%s", alpm_pkg_get_name(pkg));
 			}
@@ -354,16 +355,16 @@
 			if (!config->quiet) {
 				if((grp = alpm_pkg_get_groups(pkg)) != NULL) {
 					alpm_list_t *k;
-					printf(" (");
+					color_printf(COLOR_BLUE, " (");
 					for(k = grp; k; k = alpm_list_next(k)) {
 						const char *group = alpm_list_getdata(k);
-						printf("%s", group);
+						color_printf(COLOR_BLUE, "%s", group);
 						if(alpm_list_next(k)) {
 							/* only print a spacer if there are more groups */
 							printf(" ");
 						}
 					}
-					printf(")");
+					color_printf(COLOR_BLUE,")");
 				}
 
 				print_installed(pkg);
@@ -398,8 +399,8 @@
 					/* get names of packages in group */
 					for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
 						if(!config->quiet) {
-							printf("%s %s\n", grpname,
-									alpm_pkg_get_name(alpm_list_getdata(k)));
+							color_printf(COLOR_BLUE, "%s ", grpname);
+							color_printf(COLOR_WHITE, "%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
 						} else {
 							printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
 						}
@@ -417,8 +418,8 @@
 
 				if(level > 1) {
 					for(k = alpm_grp_get_pkgs(grp); k; k = alpm_list_next(k)) {
-						printf("%s %s\n", grpname,
-								alpm_pkg_get_name(alpm_list_getdata(k)));
+						color_printf(COLOR_BLUE, "%s ", grpname);
+						color_printf(COLOR_WHITE, "%s\n", alpm_pkg_get_name(alpm_list_getdata(k)));
 					}
 				} else {
 					/* print grp names only, no package names */
@@ -554,8 +555,9 @@
 			pmpkg_t *pkg = alpm_list_getdata(j);
 
 			if (!config->quiet) {
-				printf("%s %s %s", alpm_db_get_name(db), alpm_pkg_get_name(pkg),
-						alpm_pkg_get_version(pkg));
+				color_printf(COLOR_MAGENTA, "%s ", alpm_db_get_name(db));
+				color_printf(COLOR_WHITE, "%s ", alpm_pkg_get_name(pkg));
+				color_printf(COLOR_GREEN, "%s\n", alpm_pkg_get_version(pkg));
 				print_installed(pkg);
 				printf("\n");
 			} else {
@@ -644,7 +646,7 @@
 	}
 
 	if(config->op_s_upgrade) {
-		printf(_(":: Starting full system upgrade...\n"));
+		pm_printf_info(_("Starting full system upgrade...\n"));
 		alpm_logaction("starting full system upgrade\n");
 		if(alpm_sync_sysupgrade(config->op_s_upgrade >= 2) == -1) {
 			pm_fprintf(stderr, PM_LOG_ERROR, "%s\n", alpm_strerrorlast());
@@ -662,7 +664,7 @@
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *pkg = alpm_list_getdata(i);
-					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+					pm_printf_info(_("package %s does not have a valid architecture\n"), pkg);
 				}
 				break;
 			case PM_ERR_UNSATISFIED_DEPS:
@@ -670,7 +672,7 @@
 					pmdepmissing_t *miss = alpm_list_getdata(i);
 					pmdepend_t *dep = alpm_miss_get_dep(miss);
 					char *depstring = alpm_dep_compute_string(dep);
-					printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss),
+					pm_printf_info(_("%s: requires %s\n"), alpm_miss_get_target(miss),
 							depstring);
 					free(depstring);
 				}
@@ -683,9 +685,9 @@
 					const char *reason = alpm_conflict_get_reason(conflict);
 					/* only print reason if it contains new information */
 					if(strcmp(package1, reason) == 0 || strcmp(package2, reason) == 0) {
-						printf(_(":: %s and %s are in conflict\n"), package1, package2);
+						pm_printf_info(_("%s and %s are in conflict\n"), package1, package2);
 					} else {
-						printf(_(":: %s and %s are in conflict (%s)\n"), package1, package2, reason);
+						pm_printf_info(_("%s and %s are in conflict (%s)\n"), package1, package2, reason);
 					}
 				}
 				break;
@@ -757,7 +759,7 @@
 				break;
 		}
 		/* TODO: stderr? */
-		printf(_("Errors occurred, no packages were upgraded.\n"));
+		color_printf(COLOR_RED, _("Errors occurred, no packages were upgraded.\n"));
 		retval = 1;
 		goto cleanup;
 	}
@@ -806,7 +808,7 @@
 
 	if(config->op_s_sync) {
 		/* grab a fresh package list */
-		printf(_(":: Synchronizing package databases...\n"));
+		pm_printf_info(_("Synchronizing package databases...\n"));
 		alpm_logaction("synchronizing package lists\n");
 		if(!sync_synctree(config->op_s_sync, sync_dbs)) {
 			return(1);
@@ -855,10 +857,10 @@
 			alpm_list_t *tmp = NULL;
 			if(config->op_s_upgrade || (tmp = alpm_list_diff(targets, packages, (alpm_list_fn_cmp)strcmp))) {
 				alpm_list_free(tmp);
-				printf(_(":: The following packages should be upgraded first :\n"));
-				list_display("   ", packages);
-				if(yesno(_(":: Do you want to cancel the current operation\n"
-								":: and upgrade these packages now?"))) {
+				pm_printf_info(_("The following packages should be upgraded first :\n"));
+				list_display(COLOR_NONE, "   ", packages);
+				if(yesno(_("Do you want to cancel the current operation\n"
+								"and upgrade these packages now?"))) {
 					FREELIST(targs);
 					targs = packages;
 					config->flags = 0;
diff -Naur a/src/pacman/upgrade.c b/src/pacman/upgrade.c
--- a/src/pacman/upgrade.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/upgrade.c	2011-01-09 15:22:17.000000000 +0100
@@ -88,7 +88,7 @@
 			case PM_ERR_PKG_INVALID_ARCH:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *pkg = alpm_list_getdata(i);
-					printf(_(":: package %s does not have a valid architecture\n"), pkg);
+					pm_printf_info(_("package %s does not have a valid architecture\n"), pkg);
 				}
 				break;
 			case PM_ERR_UNSATISFIED_DEPS:
@@ -100,7 +100,7 @@
 					/* TODO indicate if the error was a virtual package or not:
 					 *		:: %s: requires %s, provided by %s
 					 */
-					printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss),
+					pm_printf_info(_("%s: requires %s\n"), alpm_miss_get_target(miss),
 							depstring);
 					free(depstring);
 				}
@@ -113,9 +113,9 @@
 					const char *reason = alpm_conflict_get_reason(conflict);
 					/* only print reason if it contains new information */
 					if(strcmp(package1, reason) == 0 || strcmp(package2, reason) == 0) {
-						printf(_(":: %s and %s are in conflict\n"), package1, package2);
+						pm_printf_info(_("%s and %s are in conflict\n"), package1, package2);
 					} else {
-						printf(_(":: %s and %s are in conflict (%s)\n"), package1, package2, reason);
+						pm_printf_info(_("%s and %s are in conflict (%s)\n"), package1, package2, reason);
 					}
 				}
 				break;
@@ -178,7 +178,7 @@
 			case PM_ERR_DLT_INVALID:
 				for(i = data; i; i = alpm_list_next(i)) {
 					char *filename = alpm_list_getdata(i);
-					printf(_("%s is invalid or corrupted\n"), filename);
+				printf(_("%s is invalid or corrupted\n"), filename);
 				}
 				break;
 			default:
diff -Naur a/src/pacman/util.c b/src/pacman/util.c
--- a/src/pacman/util.c	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/util.c	2011-01-09 14:30:55.000000000 +0100
@@ -426,12 +426,12 @@
 	return(len);
 }
 
-void string_display(const char *title, const char *string)
+void string_display(const pmcolor_t color_title, const char *title, const char *string)
 {
 	int len = 0;
 
 	if(title) {
-		printf("%s ", title);
+		color_printf(color_title, "%s ", title);
 	}
 	if(string == NULL || string[0] == '\0') {
 		printf(_("None"));
@@ -443,14 +443,14 @@
 	printf("\n");
 }
 
-void list_display(const char *title, const alpm_list_t *list)
+void list_display(const pmcolor_t color_title, const char *title, const alpm_list_t *list)
 {
 	const alpm_list_t *i;
 	int cols, len = 0;
 
 	if(title) {
 		len = string_length(title) + 1;
-		printf("%s ", title);
+		color_printf(color_title, "%s ", title);
 	}
 
 	if(!list) {
@@ -479,14 +479,14 @@
 	}
 }
 
-void list_display_linebreak(const char *title, const alpm_list_t *list)
+void list_display_linebreak(const pmcolor_t color_title, const char *title, const alpm_list_t *list)
 {
 	const alpm_list_t *i;
 	int len = 0;
 
 	if(title) {
 		len = string_length(title) + 1;
-		printf("%s ", title);
+		color_printf(color_title, "%s ", title);
 	}
 
 	if(!list) {
@@ -545,21 +545,24 @@
 
 	if(install) {
 		pm_asprintf(&str, _("Targets (%d):"), alpm_list_count(targets));
-		list_display(str, targets);
+		list_display(COLOR_YELLOW, str, targets);
 		free(str);
 		printf("\n");
 
-		printf(_("Total Download Size:    %.2f MB\n"), mbdlsize);
+		color_printf(COLOR_WHITE, _("Total Download Size:    "));
+		printf("%.2f MB\n", mbdlsize);
 		if(!(config->flags & PM_TRANS_FLAG_DOWNLOADONLY)) {
-			printf(_("Total Installed Size:   %.2f MB\n"), mbisize);
+			color_printf(COLOR_WHITE, _("Total Installed Size:   "));
+			printf("%.2f MB\n", mbisize);
 		}
 	} else {
 		pm_asprintf(&str, _("Remove (%d):"), alpm_list_count(targets));
-		list_display(str, targets);
+		list_display(COLOR_RED, str, targets);
 		free(str);
 		printf("\n");
 
-		printf(_("Total Removed Size:   %.2f MB\n"), mbisize);
+		color_printf(COLOR_WHITE, _("Total Removed Size:   "));
+		printf("%.2f MB\n", mbisize);
 	}
 
 	FREELIST(targets);
@@ -670,7 +673,7 @@
 	alpm_list_t *optdeps = alpm_list_diff(new,old,str_cmp);
 	if(optdeps) {
 		printf(_("New optional dependencies for %s\n"), alpm_pkg_get_name(newpkg));
-		list_display_linebreak("   ", optdeps);
+		list_display_linebreak(COLOR_NONE, "   ", optdeps);
 	}
 	alpm_list_free(optdeps);
 }
@@ -680,7 +683,7 @@
 	alpm_list_t *optdeps = alpm_pkg_get_optdepends(pkg);
 	if(optdeps) {
 		printf(_("Optional dependencies for %s\n"), alpm_pkg_get_name(pkg));
-		list_display_linebreak("   ", optdeps);
+		list_display_linebreak(COLOR_NONE, "   ", optdeps);
 	}
 }
 
@@ -791,41 +794,6 @@
 	return(ret);
 }
 
-int pm_vasprintf(char **string, pmloglevel_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 */
-	switch(level) {
-		case PM_LOG_DEBUG:
-			pm_asprintf(string, "debug: %s", msg);
-			break;
-		case PM_LOG_ERROR:
-			pm_asprintf(string, _("error: %s"), msg);
-			break;
-		case PM_LOG_WARNING:
-			pm_asprintf(string, _("warning: %s"), msg);
-			break;
-		case PM_LOG_FUNCTION:
-			pm_asprintf(string, _("function: %s"), msg);
-			break;
-		default:
-			break;
-	}
-	free(msg);
-
-	return(ret);
-}
-
 int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args)
 {
 	int ret = 0;
@@ -857,10 +825,10 @@
 			fprintf(stream, "debug: ");
 			break;
 		case PM_LOG_ERROR:
-			fprintf(stream, _("error: "));
+			color_fprintf(stream, COLOR_RED, _("error: "));
 			break;
 		case PM_LOG_WARNING:
-			fprintf(stream, _("warning: "));
+			color_fprintf(stream, COLOR_YELLOW, _("warning: "));
 			break;
 		case PM_LOG_FUNCTION:
 		  /* TODO we should increase the indent level when this occurs so we can see
@@ -876,6 +844,83 @@
 	return(ret);
 }
 
+int pm_printf_info(const char* format, ...)
+{
+	int ret;
+	va_list args;
+	
+	color_printf(COLOR_BLUE, ":: ");
+
+	/* print the message using va_arg list */
+	va_start(args, format);
+	ret = color_vfprintf(stdout, COLOR_WHITE, format, args);
+	va_end(args);
+	
+	return(ret);
+}
+
+int color_printf(const pmcolor_t color, const char* format, ...)
+{
+	int ret;
+	va_list args;
+	va_start(args, format);
+	ret = color_vfprintf(stdout, color, format, args);
+	va_end(args);
+	return(ret);
+}
+
+int color_fprintf(FILE* stream, const pmcolor_t color, const char* format, ...)
+{
+	int ret;
+	va_list args;
+	va_start(args, format);
+	ret = color_vfprintf(stream, color, format, args);
+	va_end(args);
+	return(ret);
+}
+
+int color_vfprintf(FILE* stream, const pmcolor_t color, const char* format, va_list args)
+{
+	int ret = 0;
+		
+	unsigned short colorize = (config->nocolor == 0 && isatty(fileno(stream)) && color != COLOR_NONE);
+	
+	if (colorize) {
+			switch(color) {
+			case COLOR_RED:
+				fprintf(stream, "\033[1;31m");
+				break;
+			case COLOR_GREEN:
+				fprintf(stream, "\033[1;32m");
+				break;
+			case COLOR_YELLOW:
+				fprintf(stream, "\033[1;33m");
+				break;
+			case COLOR_BLUE:
+				fprintf(stream, "\033[1;34m");
+				break;
+			case COLOR_MAGENTA:
+				fprintf(stream, "\033[1;35m");
+				break;
+			case COLOR_CYAN:
+				fprintf(stream, "\033[1;36m");
+				break;
+			case COLOR_WHITE:
+				fprintf(stream, "\033[m\033[1m");
+				break;
+			default:;
+		}
+	}
+	
+	ret = vfprintf(stream, format, args);
+	
+	if (colorize) {
+		fprintf(stream, "\033[m");
+	}
+	
+	return(ret);
+}
+
 #ifndef HAVE_STRNDUP
 /* A quick and dirty implementation derived from glibc */
 static size_t strnlen(const char *s, size_t max)
diff -Naur a/src/pacman/util.h b/src/pacman/util.h
--- a/src/pacman/util.h	2011-01-09 13:33:08.923333337 +0100
+++ b/src/pacman/util.h	2011-01-09 14:21:30.000000000 +0100
@@ -39,6 +39,18 @@
 /* update speed for the fill_progress based functions */
 #define UPDATE_SPEED_SEC 0.2f
 
+/* used colors enum */
+typedef enum _pmcolor_t {
+	COLOR_RED,
+	COLOR_GREEN,
+	COLOR_YELLOW,
+	COLOR_BLUE,
+	COLOR_MAGENTA,
+	COLOR_CYAN,
+	COLOR_WHITE,
+	COLOR_NONE,
+} pmcolor_t;
+
 int trans_init(pmtransflag_t flags);
 int trans_release(void);
 int needs_root(void);
@@ -51,9 +63,9 @@
 char *strtrim(char *str);
 char *strreplace(const char *str, const char *needle, const char *replace);
 alpm_list_t *strsplit(const char *str, const char splitchar);
-void string_display(const char *title, const char *string);
-void list_display(const char *title, const alpm_list_t *list);
-void list_display_linebreak(const char *title, const alpm_list_t *list);
+void string_display(const pmcolor_t color_title, const char *title, const char *string);
+void list_display(const pmcolor_t color_title, const char *title, const alpm_list_t *list);
+void list_display_linebreak(const pmcolor_t color_title, const char *title, const alpm_list_t *list);
 void display_targets(const alpm_list_t *pkgs, int install);
 int str_cmp(const void *s1, const void *s2);
 void display_new_optdepends(pmpkg_t *oldpkg, pmpkg_t *newpkg);
@@ -61,11 +73,14 @@
 void print_packages(const alpm_list_t *packages);
 int yesno(char *fmt, ...);
 int noyes(char *fmt, ...);
+int pm_printf_info(const char* format, ...) __attribute__((format(printf,1,2)));
 int pm_printf(pmloglevel_t level, const char *format, ...) __attribute__((format(printf,2,3)));
 int pm_fprintf(FILE *stream, pmloglevel_t level, const char *format, ...) __attribute__((format(printf,3,4)));
 int pm_asprintf(char **string, const char *format, ...);
 int pm_vfprintf(FILE *stream, pmloglevel_t level, const char *format, va_list args) __attribute__((format(printf,3,0)));
-int pm_vasprintf(char **string, pmloglevel_t level, const char *format, va_list args) __attribute__((format(printf,3,0)));
+int color_printf(const pmcolor_t color, const char* format, ...) __attribute__((format(printf,2,3)));
+int color_fprintf(FILE* stream, const pmcolor_t color, const char* format, ...) __attribute__((format(printf,3,4)));
+int color_vfprintf(FILE* stream, const pmcolor_t color, const char* format, va_list args) __attribute__((format(printf,3,0)));
 
 #ifndef HAVE_STRNDUP
 char *strndup(const char *s, size_t n);


Reply via email to