* colorize - Read text from standard input stream or file and print
* it colorized through use of ANSI escape sequences
*
- * Copyright (c) 2011-2018 Steven Schubiger
+ * Copyright (c) 2011-2019 Steven Schubiger
*
* 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
#define PROGRAM_NAME "colorize"
-#define VERSION "0.64"
+#define VERSION "0.65"
typedef enum { false, true } bool;
FMT_ERROR,
FMT_FILE,
FMT_TYPE,
- FMT_CONF
+ FMT_CONF,
+ FMT_CONF_FILE
};
static const char *formats[] = {
- "%s", /* generic */
- "%s '%s'", /* string */
- "%s `%s' %s", /* quote */
- "%s color '%s' %s", /* color */
- "%s color '%s' %s '%s'", /* random */
- "less than %lu bytes %s", /* error */
- "%s: %s", /* file */
- "%s: %s: %s", /* type */
- "%s: option '%s' %s" /* conf */
+ "%s", /* generic */
+ "%s '%s'", /* string */
+ "%s `%s' %s", /* quote */
+ "%s color '%s' %s", /* color */
+ "%s color '%s' %s '%s'", /* random */
+ "less than %lu bytes %s", /* error */
+ "%s: %s", /* file */
+ "%s: %s: %s", /* type */
+ "%s: option '%s' %s", /* conf */
+ "config file %s: %s" /* conf file */
};
enum { GENERIC, FOREGROUND = 0, BACKGROUND };
};
static unsigned int opts_set;
-enum {
+enum opt_set {
OPT_ATTR_SET = 0x01,
OPT_EXCLUDE_RANDOM_SET = 0x02,
OPT_OMIT_COLOR_EMPTY_SET = 0x04
static void print_tstamp (FILE *);
#endif
static void process_opts (int, char **, char **);
+static void conf_file_path (char **);
static void process_opt_attr (const char *, const bool);
static void write_attr (const struct attr *, unsigned int *, const bool);
static void process_opt_exclude_random (const char *, const bool);
#elif !defined(TEST)
if (conf_file == NULL)
{
- uid_t uid;
- struct passwd *passwd;
- size_t size;
-
- uid = getuid ();
- errno = 0;
- if ((passwd = getpwuid (uid)) == NULL)
- {
- if (errno == 0)
- vfprintf_diag ("password file entry for uid %lu not found", (unsigned long)uid);
- else
- perror ("getpwuid");
- exit (EXIT_FAILURE);
- }
- size = strlen (passwd->pw_dir) + 1 + strlen (CONF_FILE) + 1;
- conf_file = xmalloc (size);
- snprintf (conf_file, size, "%s/%s", passwd->pw_dir, CONF_FILE);
+ conf_file_path (&conf_file);
+ STACK_VAR (conf_file);
}
else
{
free (conf_file);
conf_file = s;
}
+ STACK_VAR (conf_file);
errno = 0;
if (access (conf_file, F_OK) == -1)
- vfprintf_fail (formats[FMT_FILE], conf_file, strerror (errno));
+ vfprintf_fail (formats[FMT_CONF_FILE], conf_file, strerror (errno));
}
#endif
#if defined(CONF_FILE_TEST) || !defined(TEST)
parse_conf (conf_file, &config);
#endif
#if !defined(CONF_FILE_TEST) && !defined(TEST)
- free (conf_file);
+ RELEASE_VAR (conf_file);
#endif
init_conf_vars (&config);
if (clean && clean_all)
vfprintf_fail (formats[FMT_GENERIC], "--clean and --clean-all switch are mutually exclusive");
if (arg_cnt > 1)
- {
- const char *const format = "%s %s";
- const char *const message = "switch cannot be used with more than one file";
- if (clean)
- vfprintf_fail (format, "--clean", message);
- else if (clean_all)
- vfprintf_fail (format, "--clean-all", message);
- }
+ vfprintf_fail ("--clean%s switch cannot be used with more than one file", clean_all ? "-all" : "");
+ {
+ unsigned int i;
+ const struct option_set {
+ const char *option;
+ enum opt_set set;
+ } options[] = {
+ { "attr", OPT_ATTR_SET },
+ { "exclude-random", OPT_EXCLUDE_RANDOM_SET },
+ { "omit-color-empty", OPT_OMIT_COLOR_EMPTY_SET },
+ };
+ for (i = 0; i < COUNT_OF (options, struct option_set); i++)
+ if (opts_set & options[i].set)
+ vfprintf_diag ("--%s switch has no meaning with --clean%s", options[i].option, clean_all ? "-all" : "");
+ }
}
else
{
case OPT_ATTR:
opts_set |= OPT_ATTR_SET;
opts_arg.attr = xstrdup (optarg);
+ STACK_VAR (opts_arg.attr);
break;
case OPT_CLEAN:
clean = true;
case OPT_EXCLUDE_RANDOM:
opts_set |= OPT_EXCLUDE_RANDOM_SET;
opts_arg.exclude_random = xstrdup (optarg);
+ STACK_VAR (opts_arg.exclude_random);
break;
case OPT_OMIT_COLOR_EMPTY:
opts_set |= OPT_OMIT_COLOR_EMPTY_SET;
}
}
+static void
+conf_file_path (char **conf_file)
+{
+ char *path;
+ uid_t uid;
+ struct passwd *passwd;
+ size_t size;
+
+ uid = getuid ();
+ errno = 0;
+ if ((passwd = getpwuid (uid)) == NULL)
+ {
+ if (errno == 0)
+ vfprintf_diag ("password file entry for uid %lu not found", (unsigned long)uid);
+ else
+ perror ("getpwuid");
+ exit (EXIT_FAILURE);
+ }
+ size = strlen (passwd->pw_dir) + 1 + strlen (CONF_FILE) + 1;
+ path = xmalloc (size);
+ snprintf (path, size, "%s/%s", passwd->pw_dir, CONF_FILE);
+
+ *conf_file = path;
+}
+
static void
process_opt_attr (const char *p, const bool is_opt)
{
{
bool valid = false;
unsigned int i;
- if (exclude)
- RELEASE_VAR (exclude);
+ RELEASE_VAR (exclude);
exclude = xstrdup (s);
STACK_VAR (exclude);
for (i = 1; i < tables[GENERIC].count - 1; i++) /* skip color none and default */
if (opts_set & OPT_OMIT_COLOR_EMPTY_SET)
omit_color_empty = true;
- free (opts_arg.attr);
- free (opts_arg.exclude_random);
+ RELEASE_VAR (opts_arg.attr);
+ RELEASE_VAR (opts_arg.exclude_random);
}
#define IS_SPACE(c) ((c) == ' ' || (c) == '\t')
/* save option name */
cfg = xstrdup (opt);
+ STACK_VAR (cfg);
/* save option value (allow empty ones) */
val = strlen (value) ? xstrdup (value) : NULL;
+ STACK_VAR (val);
assign_conf (conf_file, config, cfg, val);
- free (cfg);
+ RELEASE_VAR (cfg);
}
fclose (conf);
}
+#define ASSIGN_CONF(str,val) do { \
+ RELEASE_VAR (str); \
+ str = val; \
+} while (false)
+
static void
assign_conf (const char *conf_file, struct conf *config, const char *cfg, char *val)
{
if (streq (cfg, "attr"))
- {
- free (config->attr);
- config->attr = val;
- }
+ ASSIGN_CONF (config->attr, val);
else if (streq (cfg, "color"))
- {
- free (config->color);
- config->color = val;
- }
+ ASSIGN_CONF (config->color, val);
else if (streq (cfg, "exclude-random"))
- {
- free (config->exclude_random);
- config->exclude_random = val;
- }
+ ASSIGN_CONF (config->exclude_random, val);
else if (streq (cfg, "omit-color-empty"))
- {
- free (config->omit_color_empty);
- config->omit_color_empty = val;
- }
+ ASSIGN_CONF (config->omit_color_empty, val);
else
vfprintf_fail (formats[FMT_CONF], conf_file, cfg, "not recognized");
}
else if (streq (config->omit_color_empty, "no"))
omit_color_empty = false;
else
- vfprintf_fail ("omit-color-empty conf option is not valid");
+ vfprintf_fail (formats[FMT_GENERIC], "omit-color-empty conf option is not valid");
}
}
static void
free_conf (struct conf *config)
{
- free (config->attr);
- free (config->color);
- free (config->exclude_random);
- free (config->omit_color_empty);
+ RELEASE_VAR (config->attr);
+ RELEASE_VAR (config->color);
+ RELEASE_VAR (config->exclude_random);
+ RELEASE_VAR (config->omit_color_empty);
}
static void