1 /* Handling of color output.
2 Copyright (C) 2011 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
4 Written by Ulrich Drepper <drepper@redhat.com>, 2011.
6 Red Hat elfutils is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by the
8 Free Software Foundation; version 2 of the License.
10 Red Hat elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with Red Hat elfutils; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
19 Red Hat elfutils is an included package of the Open Invention Network.
20 An included package of the Open Invention Network is a package for which
21 Open Invention Network licensees cross-license their patents. No patent
22 license is granted, either expressly or impliedly, by designation as an
23 included package. Should you wish to participate in the Open Invention
24 Network licensing program, please visit www.openinventionnetwork.com
25 <http://www.openinventionnetwork.com>. */
40 /* Prototype for option handler. */
41 static error_t parse_opt (int key, char *arg, struct argp_state *state);
44 #define OPT_COLOR 0x100100
46 /* Definitions of arguments for argp functions. */
47 static const struct argp_option options[] =
49 { "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL,
50 N_("colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'"), 0 },
52 { NULL, 0, NULL, 0, NULL, 0 }
55 /* Parser data structure. */
56 const struct argp color_argp =
58 options, parse_opt, NULL, NULL, NULL, NULL, NULL
62 enum color_enum color_mode;
64 /* Colors to use for the various components. */
65 char *color_address = "";
66 char *color_bytes = "";
67 char *color_mnemonic = "";
68 char *color_operand = NULL;
69 char *color_operand1 = "";
70 char *color_operand2 = "";
71 char *color_operand3 = "";
72 char *color_label = "";
73 char *color_undef = "";
74 char *color_undef_tls = "";
75 char *color_undef_weak = "";
76 char *color_symbol = "";
78 char *color_weak = "";
80 const char color_off[] = "\e[0m";
83 /* Handle program arguments. */
85 parse_opt (int key, char *arg,
86 struct argp_state *state __attribute__ ((unused)))
92 color_mode = color_always;
101 { "always", color_always },
102 { "yes", color_always },
103 { "force", color_always },
104 { "never", color_never },
105 { "no", color_never },
106 { "none", color_never },
107 { "auto", color_auto },
108 { "tty", color_auto },
109 { "if-tty", color_auto }
111 const int nvalues = sizeof (values) / sizeof (values[0]);
113 for (i = 0; i < nvalues; ++i)
114 if (strcmp (arg, values[i].str) == 0)
116 color_mode = values[i].mode;
117 if (color_mode == color_auto)
119 = isatty (STDOUT_FILENO) ? color_always : color_never;
124 error (0, 0, dgettext ("elfutils", "\
125 %s: invalid argument '%s' for '--color'\n\
126 valid arguments are:\n\
127 - 'always', 'yes', 'force'\n\
128 - 'never', 'no', 'none'\n\
129 - 'auto', 'tty', 'if-tty'\n"),
130 program_invocation_short_name, arg);
131 argp_help (&color_argp, stderr, ARGP_HELP_SEE,
132 program_invocation_short_name);
137 if (color_mode == color_always)
139 const char *env = getenv ("ELFUTILS_COLORS");
144 const char *start = env;
145 while (*env != '=' && *env != '\0')
147 if (*env == '=' && env != start)
149 size_t name_len = env - start;
150 const char *val = ++env;
151 env = strchrnul (env, ':');
157 const char name[sizeof (char *) - 1];
161 #define E(name, var) { sizeof (#name) - 1, #name, &color_##var }
177 const size_t nknown = (sizeof (known)
178 / sizeof (known[0]));
180 for (size_t i = 0; i < nknown; ++i)
181 if (name_len == known[i].len
182 && memcmp (start, known[i].name, name_len) == 0)
184 if (asprintf (known[i].varp, "\e[%.*sm",
185 (int) (env - val), val) < 0)
186 error (EXIT_FAILURE, errno,
187 gettext ("cannot allocate memory"));
195 while (*env != '\0');
197 if (color_operand != NULL)
199 if (color_operand1[0] == '\0')
200 color_operand1 = color_operand;
201 if (color_operand2[0] == '\0')
202 color_operand2 = color_operand;
203 if (color_operand3[0] == '\0')
204 color_operand3 = color_operand;
210 // XXX Just for testing.
211 color_address = xstrdup ("\e[38;5;166;1m");
212 color_bytes = xstrdup ("\e[38;5;141m");
213 color_mnemonic = xstrdup ("\e[38;5;202;1m");
214 color_operand1 = xstrdup ("\e[38;5;220m");
215 color_operand2 = xstrdup ("\e[38;5;48m");
216 color_operand3 = xstrdup ("\e[38;5;112m");
217 color_label = xstrdup ("\e[38;5;21m");
224 return ARGP_ERR_UNKNOWN;