|
Packit Service |
97d2fb |
/* Handling of color output.
|
|
Packit Service |
97d2fb |
Copyright (C) 2011 Red Hat, Inc.
|
|
Packit Service |
97d2fb |
This file is part of elfutils.
|
|
Packit Service |
97d2fb |
Written by Ulrich Drepper <drepper@redhat.com>, 2011.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
This file is free software; you can redistribute it and/or modify
|
|
Packit Service |
97d2fb |
it under the terms of either
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
* the GNU Lesser General Public License as published by the Free
|
|
Packit Service |
97d2fb |
Software Foundation; either version 3 of the License, or (at
|
|
Packit Service |
97d2fb |
your option) any later version
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
or
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
* the GNU General Public License as published by the Free
|
|
Packit Service |
97d2fb |
Software Foundation; either version 2 of the License, or (at
|
|
Packit Service |
97d2fb |
your option) any later version
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
or both in parallel, as here.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
elfutils is distributed in the hope that it will be useful, but
|
|
Packit Service |
97d2fb |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
97d2fb |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
97d2fb |
General Public License for more details.
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
You should have received copies of the GNU General Public License and
|
|
Packit Service |
97d2fb |
the GNU Lesser General Public License along with this program. If
|
|
Packit Service |
97d2fb |
not, see <http://www.gnu.org/licenses/>. */
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
#ifdef HAVE_CONFIG_H
|
|
Packit Service |
97d2fb |
# include <config.h>
|
|
Packit Service |
97d2fb |
#endif
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
#include <argp.h>
|
|
Packit Service |
97d2fb |
#include <libintl.h>
|
|
Packit Service |
97d2fb |
#include <stdlib.h>
|
|
Packit Service |
97d2fb |
#include <string.h>
|
|
Packit Service |
97d2fb |
#include <unistd.h>
|
|
Packit Service |
97d2fb |
#include "system.h"
|
|
Packit Service |
97d2fb |
#include "libeu.h"
|
|
Packit Service |
97d2fb |
#include "color.h"
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Prototype for option handler. */
|
|
Packit Service |
97d2fb |
static error_t parse_opt (int key, char *arg, struct argp_state *state);
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Option values. */
|
|
Packit Service |
97d2fb |
#define OPT_COLOR 0x100100
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Definitions of arguments for argp functions. */
|
|
Packit Service |
97d2fb |
static const struct argp_option options[] =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
{ "color", OPT_COLOR, "WHEN", OPTION_ARG_OPTIONAL,
|
|
Packit Service |
97d2fb |
N_("colorize the output. WHEN defaults to 'always' or can be 'auto' or 'never'"), 0 },
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
{ NULL, 0, NULL, 0, NULL, 0 }
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Parser data structure. */
|
|
Packit Service |
97d2fb |
const struct argp color_argp =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
options, parse_opt, NULL, NULL, NULL, NULL, NULL
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Coloring mode. */
|
|
Packit Service |
97d2fb |
enum color_enum color_mode;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Colors to use for the various components. */
|
|
Packit Service |
97d2fb |
char *color_address = "";
|
|
Packit Service |
97d2fb |
char *color_bytes = "";
|
|
Packit Service |
97d2fb |
char *color_mnemonic = "";
|
|
Packit Service |
97d2fb |
char *color_operand = NULL;
|
|
Packit Service |
97d2fb |
char *color_operand1 = "";
|
|
Packit Service |
97d2fb |
char *color_operand2 = "";
|
|
Packit Service |
97d2fb |
char *color_operand3 = "";
|
|
Packit Service |
97d2fb |
char *color_operand4 = "";
|
|
Packit Service |
97d2fb |
char *color_operand5 = "";
|
|
Packit Service |
97d2fb |
char *color_label = "";
|
|
Packit Service |
97d2fb |
char *color_undef = "";
|
|
Packit Service |
97d2fb |
char *color_undef_tls = "";
|
|
Packit Service |
97d2fb |
char *color_undef_weak = "";
|
|
Packit Service |
97d2fb |
char *color_symbol = "";
|
|
Packit Service |
97d2fb |
char *color_tls = "";
|
|
Packit Service |
97d2fb |
char *color_weak = "";
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
const char color_off[] = "\e[0m";
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
/* Handle program arguments. */
|
|
Packit Service |
97d2fb |
static error_t
|
|
Packit Service |
97d2fb |
parse_opt (int key, char *arg,
|
|
Packit Service |
97d2fb |
struct argp_state *state __attribute__ ((unused)))
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
switch (key)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
case OPT_COLOR:
|
|
Packit Service |
97d2fb |
if (arg == NULL)
|
|
Packit Service |
97d2fb |
color_mode = color_always;
|
|
Packit Service |
97d2fb |
else
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
static const struct
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
const char str[7];
|
|
Packit Service |
97d2fb |
enum color_enum mode;
|
|
Packit Service |
97d2fb |
} values[] =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
{ "always", color_always },
|
|
Packit Service |
97d2fb |
{ "yes", color_always },
|
|
Packit Service |
97d2fb |
{ "force", color_always },
|
|
Packit Service |
97d2fb |
{ "never", color_never },
|
|
Packit Service |
97d2fb |
{ "no", color_never },
|
|
Packit Service |
97d2fb |
{ "none", color_never },
|
|
Packit Service |
97d2fb |
{ "auto", color_auto },
|
|
Packit Service |
97d2fb |
{ "tty", color_auto },
|
|
Packit Service |
97d2fb |
{ "if-tty", color_auto }
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
const int nvalues = sizeof (values) / sizeof (values[0]);
|
|
Packit Service |
97d2fb |
int i;
|
|
Packit Service |
97d2fb |
for (i = 0; i < nvalues; ++i)
|
|
Packit Service |
97d2fb |
if (strcmp (arg, values[i].str) == 0)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
color_mode = values[i].mode;
|
|
Packit Service |
97d2fb |
if (color_mode == color_auto)
|
|
Packit Service |
97d2fb |
color_mode
|
|
Packit Service |
97d2fb |
= isatty (STDOUT_FILENO) ? color_always : color_never;
|
|
Packit Service |
97d2fb |
break;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
if (i == nvalues)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
error (0, 0, dgettext ("elfutils", "\
|
|
Packit Service |
97d2fb |
%s: invalid argument '%s' for '--color'\n\
|
|
Packit Service |
97d2fb |
valid arguments are:\n\
|
|
Packit Service |
97d2fb |
- 'always', 'yes', 'force'\n\
|
|
Packit Service |
97d2fb |
- 'never', 'no', 'none'\n\
|
|
Packit Service |
97d2fb |
- 'auto', 'tty', 'if-tty'\n"),
|
|
Packit Service |
97d2fb |
program_invocation_short_name, arg);
|
|
Packit Service |
97d2fb |
argp_help (&color_argp, stderr, ARGP_HELP_SEE,
|
|
Packit Service |
97d2fb |
(char *) program_invocation_short_name);
|
|
Packit Service |
97d2fb |
exit (EXIT_FAILURE);
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (color_mode == color_always)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
const char *env = getenv ("ELFUTILS_COLORS");
|
|
Packit Service |
97d2fb |
if (env != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
do
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
const char *start = env;
|
|
Packit Service |
97d2fb |
while (*env != '=' && *env != '\0')
|
|
Packit Service |
97d2fb |
++env;
|
|
Packit Service |
97d2fb |
if (*env == '=' && env != start)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
size_t name_len = env - start;
|
|
Packit Service |
97d2fb |
const char *val = ++env;
|
|
Packit Service |
97d2fb |
env = strchrnul (env, ':');
|
|
Packit Service |
97d2fb |
if (val != env)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
static const struct
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
unsigned char len;
|
|
Packit Service |
97d2fb |
const char name[sizeof (char *) - 1];
|
|
Packit Service |
97d2fb |
char **varp;
|
|
Packit Service |
97d2fb |
} known[] =
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
#define E(name, var) { sizeof (#name) - 1, #name, &color_##var }
|
|
Packit Service |
97d2fb |
E (a, address),
|
|
Packit Service |
97d2fb |
E (b, bytes),
|
|
Packit Service |
97d2fb |
E (m, mnemonic),
|
|
Packit Service |
97d2fb |
E (o, operand),
|
|
Packit Service |
97d2fb |
E (o1, operand1),
|
|
Packit Service |
97d2fb |
E (o2, operand2),
|
|
Packit Service |
97d2fb |
E (o3, operand3),
|
|
Packit Service |
97d2fb |
E (o4, operand4),
|
|
Packit Service |
97d2fb |
E (o5, operand5),
|
|
Packit Service |
97d2fb |
E (l, label),
|
|
Packit Service |
97d2fb |
E (u, undef),
|
|
Packit Service |
97d2fb |
E (ut, undef_tls),
|
|
Packit Service |
97d2fb |
E (uw, undef_weak),
|
|
Packit Service |
97d2fb |
E (sy, symbol),
|
|
Packit Service |
97d2fb |
E (st, tls),
|
|
Packit Service |
97d2fb |
E (sw, weak),
|
|
Packit Service |
97d2fb |
};
|
|
Packit Service |
97d2fb |
const size_t nknown = (sizeof (known)
|
|
Packit Service |
97d2fb |
/ sizeof (known[0]));
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
for (size_t i = 0; i < nknown; ++i)
|
|
Packit Service |
97d2fb |
if (name_len == known[i].len
|
|
Packit Service |
97d2fb |
&& memcmp (start, known[i].name, name_len) == 0)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
if (asprintf (known[i].varp, "\e[%.*sm",
|
|
Packit Service |
97d2fb |
(int) (env - val), val) < 0)
|
|
Packit Service |
97d2fb |
error (EXIT_FAILURE, errno,
|
|
Packit Service |
97d2fb |
gettext ("cannot allocate memory"));
|
|
Packit Service |
97d2fb |
break;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
if (*env == ':')
|
|
Packit Service |
97d2fb |
++env;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
while (*env != '\0');
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
if (color_operand != NULL)
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
if (color_operand1[0] == '\0')
|
|
Packit Service |
97d2fb |
color_operand1 = color_operand;
|
|
Packit Service |
97d2fb |
if (color_operand2[0] == '\0')
|
|
Packit Service |
97d2fb |
color_operand2 = color_operand;
|
|
Packit Service |
97d2fb |
if (color_operand3[0] == '\0')
|
|
Packit Service |
97d2fb |
color_operand3 = color_operand;
|
|
Packit Service |
97d2fb |
if (color_operand4[0] == '\0')
|
|
Packit Service |
97d2fb |
color_operand4 = color_operand;
|
|
Packit Service |
97d2fb |
if (color_operand5[0] == '\0')
|
|
Packit Service |
97d2fb |
color_operand5 = color_operand;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
#if 0
|
|
Packit Service |
97d2fb |
else
|
|
Packit Service |
97d2fb |
{
|
|
Packit Service |
97d2fb |
// XXX Just for testing.
|
|
Packit Service |
97d2fb |
color_address = xstrdup ("\e[38;5;166;1m");
|
|
Packit Service |
97d2fb |
color_bytes = xstrdup ("\e[38;5;141m");
|
|
Packit Service |
97d2fb |
color_mnemonic = xstrdup ("\e[38;5;202;1m");
|
|
Packit Service |
97d2fb |
color_operand1 = xstrdup ("\e[38;5;220m");
|
|
Packit Service |
97d2fb |
color_operand2 = xstrdup ("\e[38;5;48m");
|
|
Packit Service |
97d2fb |
color_operand = xstrdup ("\e[38;5;112m");
|
|
Packit Service |
97d2fb |
color_label = xstrdup ("\e[38;5;21m");
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
#endif
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
break;
|
|
Packit Service |
97d2fb |
|
|
Packit Service |
97d2fb |
default:
|
|
Packit Service |
97d2fb |
return ARGP_ERR_UNKNOWN;
|
|
Packit Service |
97d2fb |
}
|
|
Packit Service |
97d2fb |
return 0;
|
|
Packit Service |
97d2fb |
}
|