summaryrefslogblamecommitdiffstats
path: root/lib/colors.c
blob: a197823b46c24f24bd5fbabc33fab030cd0a77e5 (plain) (tree)
1
2
3
4
5
6
7
8





                                                        

                   




                            
                         
 










                                                         


                                





                                                     
 
                                             
                                       

 
                            

                             
                                         
 






















                                                      











                                                           







































                                                                     
 

                    



                                                        
                                                        


                                                             
                                   
 
                                                                              


                                                 

                                                                                          
                              


                                        



                          
                                                      





                               
/*
 * Copyright (C) 2012 Ondrej Oprala <ooprala@redhat.com>
 *
 * This file may be distributed under the terms of the
 * GNU Lesser General Public License.
 */
#include <c.h>
#include <assert.h>

#include "colors.h"

static int ul_color_term_ok;

int colors_init(int mode)
{
	switch (mode) {
	case UL_COLORMODE_AUTO:
		ul_color_term_ok = isatty(STDOUT_FILENO);
		break;
	case UL_COLORMODE_ALWAYS:
		ul_color_term_ok = 1;
		break;
	case UL_COLORMODE_NEVER:
	default:
		ul_color_term_ok = 0;
	}
	return ul_color_term_ok;
}

int colors_wanted(void)
{
	return ul_color_term_ok;
}

void color_fenable(const char *color_scheme, FILE *f)
{
	if (ul_color_term_ok && color_scheme)
		fputs(color_scheme, f);
}

void color_fdisable(FILE *f)
{
	if (ul_color_term_ok)
		fputs(UL_COLOR_RESET, f);
}

int colormode_from_string(const char *str)
{
	size_t i;
	static const char *modes[] = {
		[UL_COLORMODE_AUTO]   = "auto",
		[UL_COLORMODE_NEVER]  = "never",
		[UL_COLORMODE_ALWAYS] = "always"
	};

	if (!str || !*str)
		return -EINVAL;

	assert(ARRAY_SIZE(modes) == __UL_NCOLORMODES);

	for (i = 0; i < ARRAY_SIZE(modes); i++) {
		if (strcasecmp(str, modes[i]) == 0)
			return i;
	}

	return -EINVAL;
}

int colormode_or_err(const char *str, const char *errmsg)
{
	const char *p = str && *str == '=' ? str + 1 : str;
	int colormode;

	colormode = colormode_from_string(p);
	if (colormode < 0)
		errx(EXIT_FAILURE, "%s: '%s'", errmsg, p);

	return colormode;
}

struct colorscheme {
	const char *name, *scheme;
};

static int cmp_colorscheme_name(const void *a0, const void *b0)
{
	struct colorscheme *a = (struct colorscheme *) a0,
			   *b = (struct colorscheme *) b0;
	return strcmp(a->name, b->name);
}

const char *colorscheme_from_string(const char *str)
{
	static const struct colorscheme basic_schemes[] = {
		{ "black",	UL_COLOR_BLACK           },
		{ "blue",	UL_COLOR_BLUE            },
		{ "brown",	UL_COLOR_BROWN           },
		{ "cyan",	UL_COLOR_CYAN            },
		{ "darkgray",	UL_COLOR_DARK_GRAY       },
		{ "gray",	UL_COLOR_GRAY            },
		{ "green",	UL_COLOR_GREEN           },
		{ "lightblue",	UL_COLOR_BOLD_BLUE       },
		{ "lightcyan",	UL_COLOR_BOLD_CYAN       },
		{ "lightgray,",	UL_COLOR_GRAY            },
		{ "lightgreen", UL_COLOR_BOLD_GREEN      },
		{ "lightmagenta", UL_COLOR_BOLD_MAGENTA  },
		{ "lightred",	UL_COLOR_BOLD_RED        },
		{ "magenta",	UL_COLOR_MAGENTA         },
		{ "red",	UL_COLOR_RED             },
		{ "yellow",	UL_COLOR_BOLD_YELLOW     },
	};
	struct colorscheme key = { .name = str }, *res;
	if (!str)
		return NULL;

	res = bsearch(&key, basic_schemes, ARRAY_SIZE(basic_schemes),
				sizeof(struct colorscheme),
				cmp_colorscheme_name);
	return res ? res->scheme : NULL;
}

#ifdef TEST_PROGRAM
# include <getopt.h>
int main(int argc, char *argv[])
{
	static const struct option longopts[] = {
		{ "colors", optional_argument, 0, 'c' },
		{ "scheme", required_argument, 0, 's' },
		{ NULL, 0, 0, 0 }
	};
	int c, mode = UL_COLORMODE_NEVER;	/* default */
	const char *scheme = "red";

	while ((c = getopt_long(argc, argv, "c::s:", longopts, NULL)) != -1) {
		switch (c) {
		case 'c':
			mode = UL_COLORMODE_AUTO;
			if (optarg)
				mode = colormode_or_err(optarg, "unsupported color mode");
			break;
		case 's':
			scheme = optarg;
			break;
		}
	}

	colors_init(mode);
	color_enable(colorscheme_from_string(scheme));
	printf("Hello World!");
	color_disable();
	return EXIT_SUCCESS;
}
#endif