aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--HACKING14
-rw-r--r--Makefile5
-rw-r--r--README.cgit90
-rw-r--r--colorize.12
-rw-r--r--colorize.c306
-rw-r--r--debian/changelog18
-rw-r--r--debian/compat1
-rw-r--r--debian/control7
-rw-r--r--debian/copyright6
-rwxr-xr-xreadme.pl30
-rwxr-xr-xtest.pl10
11 files changed, 361 insertions, 128 deletions
diff --git a/HACKING b/HACKING
index 95d150b..ea2ab12 100644
--- a/HACKING
+++ b/HACKING
@@ -7,3 +7,17 @@ The colorize sources ought to be made available as a Git repository,
otherwise no detailed git version hash may be included in the version
output of colorize. Even versions of older commits will no longer be
accessible. See version.pl for some in depth code.
+
+Debian-Release instruction hints
+--------------------------------
+$ tar cvvzf ../colorize_0.vv.orig.tar.gz --exclude=debian --exclude-vcs .
+$ dpkg-buildpackage -uc -us 2>&1 | tee ../dpkg-buildpackage.log
+$ lintian
+$ lintian --pedantic
+$ duck
+$ hardening-check ./debian/colorize/usr/bin/colorize
+$ blhc ../dpkg-buildpackage.log
+$ bls-standalone check ../dpkg-buildpackage.log
+$ adequate colorize
+/usr/share/doc/debian-policy/upgrading-checklist.txt.gz
+https://people.debian.org/~abe/sponsoring/
diff --git a/Makefile b/Makefile
index 868ec4c..33b66a7 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: check check_valgrind install clean release
+.PHONY: check check_valgrind install clean release readme
.SUFFIXES:
.SUFFIXES: .c .o
@@ -30,3 +30,6 @@ clean:
release:
sh ./release.sh
+
+readme:
+ perl ./readme.pl
diff --git a/README.cgit b/README.cgit
new file mode 100644
index 0000000..6568c1b
--- /dev/null
+++ b/README.cgit
@@ -0,0 +1,90 @@
+<pre>
+colorize
+========
+
+Description
+-----------
+Colorize aims at being a small, independent and handy command-line
+text colorizing tool. It emits ANSI escape sequences in order to
+color lines of text; also, sequences emitted by colorize or foreign
+programs may be cleared.
+
+The main code is written in C (c89 mostly), whereas the test script
+consists of Perl code.
+
+Colorize is known to build and test successfully on Linux and
+Net/Open/MirBSD. Other platforms are untested, so be prepared for
+it to eventually not work as expected there.
+
+Requirements
+------------
+gcc
+make
+perl
+valgrind (optional)
+
+Build instructions
+------------------
+Issue `make' to build colorize.
+
+Once completed, run the tests with `make check'.
+
+Then you should most likely have a working binary.
+
+Next, install it with `make install' (may require elevated
+user permissions).
+
+Finally, clean up the working directory through `make clean'.
+
+Customizing instructions
+------------------------
+The default character ('/') which separates the foreground
+from the background color may be redefined:
+
+`make FLAGS=-DCOLOR_SEP_CHAR_COLON' -&gt; defines as ':'
+`make FLAGS=-DCOLOR_SEP_CHAR_SLASH' -&gt; defines as '/'
+
+Debugging instructions
+----------------------
+For the sake of completeness, colorize can be also built with
+debugging output by issuing `make FLAGS=-DDEBUG'. The intention
+is to provide some memory allocation diagnostics (and might be
+extended in future). Usually, a debugging build is not required.
+
+Furthermore, tests can be run through valgrind by issuing, for
+example, `make check_valgrind 2&gt;&1 | tee valgrind.out'. The
+file provided here for the `tee' invocation will be populated
+with the captured output from both standard output and error
+stream.
+
+Configuration File
+------------------
+A user configuration file may be populated with options and
+according values. See man page source file `colorize.1' for
+details.
+
+Documentation
+-------------
+See man page source file: colorize.1.
+
+Usage example
+-------------
+In ~/.bashrc:
+
+| ls_color() {
+| ls "$@" | colorize green -
+| }
+| alias ls=ls_color
+
+This excerpt defines an alias which will set the color being
+printed for literal ls invocations to green.
+
+Afterword
+---------
+Let me know, if you have ideas, bug reports, patches, etc.
+
+Author
+------
+Steven Schubiger &lt;stsc@refcnt.org&gt;
+
+</pre>
diff --git a/colorize.1 b/colorize.1
index 02ffe2e..5168dac 100644
--- a/colorize.1
+++ b/colorize.1
@@ -1,4 +1,4 @@
-.TH COLORIZE 1 "2019-09-01" "colorize v0.64" "User Commands"
+.TH COLORIZE 1 "2019-09-01" "colorize v0.65" "User Commands"
.SH NAME
colorize \- colorize text on terminal with ANSI escape sequences
.SH SYNOPSIS
diff --git a/colorize.c b/colorize.c
index ac4ee9a..a1e1398 100644
--- a/colorize.c
+++ b/colorize.c
@@ -2,7 +2,7 @@
* 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
@@ -81,12 +81,14 @@
#define VALID_FILE_TYPE(mode) (S_ISREG (mode) || S_ISLNK (mode) || S_ISFIFO (mode))
-#define STACK_VAR(ptr) do { \
- stack_var (&vars_list, &stacked_vars, stacked_vars, ptr); \
+#define STACK_VAR(ptr) do { \
+ stack (&vars_list, &stacked_vars, stacked_vars, ptr, IS_GENERIC); \
} while (false)
-
-#define RELEASE_VAR(ptr) do { \
- release_var (vars_list, stacked_vars, (void **)&ptr); \
+#define STACK_FILE(ptr) do { \
+ stack (&vars_list, &stacked_vars, stacked_vars, ptr, IS_FILE); \
+} while (false)
+#define RELEASE(ptr) do { \
+ release (vars_list, stacked_vars, (void **)&ptr); \
} while (false)
#if !DEBUG
@@ -130,7 +132,7 @@
#define PROGRAM_NAME "colorize"
-#define VERSION "0.64"
+#define VERSION "0.65"
typedef enum { false, true } bool;
@@ -192,18 +194,20 @@ enum {
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 };
@@ -218,7 +222,7 @@ static const struct {
};
static unsigned int opts_set;
-enum {
+enum opt_set {
OPT_ATTR_SET = 0x01,
OPT_EXCLUDE_RANDOM_SET = 0x02,
OPT_OMIT_COLOR_EMPTY_SET = 0x04
@@ -264,13 +268,23 @@ struct attr {
enum attr_type type;
};
+enum var_type {
+ IS_GENERIC,
+ IS_FILE,
+ IS_UNUSED
+};
+struct var_list {
+ void *ptr;
+ enum var_type type;
+};
+
static FILE *stream;
#if DEBUG
static FILE *log;
#endif
static unsigned int stacked_vars;
-static void **vars_list;
+static struct var_list *vars_list;
static bool clean;
static bool clean_all;
@@ -285,6 +299,7 @@ static const char *program_name;
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);
@@ -341,10 +356,8 @@ static bool has_color_name (const char *, const char *);
static FILE *open_file (const char *, const char *);
static void vfprintf_diag (const char *, ...);
static void vfprintf_fail (const char *, ...);
-static void stack_var (void ***, unsigned int *, unsigned int, void *);
-static void release_var (void **, unsigned int, void **);
-
-extern int optind;
+static void stack (struct var_list **, unsigned int *, unsigned int, void *, enum var_type);
+static void release (struct var_list *, unsigned int, void **);
int
main (int argc, char **argv)
@@ -369,6 +382,11 @@ main (int argc, char **argv)
#if DEBUG
log = open_file (DEBUG_FILE, "w");
print_tstamp (log);
+ /* We're in debugging mode, hence we can't invoke STACK_FILE()
+ prior to print_tstamp(), because both cause text to be written
+ to the same logfile which is expected to have the timestamp
+ first. */
+ STACK_FILE (log);
#endif
attr[0] = '\0';
@@ -380,23 +398,8 @@ main (int argc, char **argv)
#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
{
@@ -406,9 +409,10 @@ main (int argc, char **argv)
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)
@@ -416,7 +420,7 @@ main (int argc, char **argv)
parse_conf (conf_file, &config);
#endif
#if !defined(CONF_FILE_TEST) && !defined(TEST)
- free (conf_file);
+ RELEASE (conf_file);
#endif
init_conf_vars (&config);
@@ -429,20 +433,27 @@ main (int argc, char **argv)
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
{
if (arg_cnt == 0 || arg_cnt > 2)
{
- vfprintf_diag ("%u arguments provided, expected 1-2 arguments or clean option", arg_cnt);
+ vfprintf_diag ("%u arguments provided, expected 1-2 arguments or --clean[-all]", arg_cnt);
print_hint ();
exit (EXIT_FAILURE);
}
@@ -456,7 +467,7 @@ main (int argc, char **argv)
free_conf (&config);
- RELEASE_VAR (exclude);
+ RELEASE (exclude);
exit (EXIT_SUCCESS);
}
@@ -500,8 +511,6 @@ print_tstamp (FILE *log)
print_version (); \
exit (EXIT_SUCCESS);
-extern char *optarg;
-
static void
process_opts (int argc, char **argv, char **conf_file)
{
@@ -516,6 +525,7 @@ process_opts (int argc, char **argv, char **conf_file)
case OPT_ATTR:
opts_set |= OPT_ATTR_SET;
opts_arg.attr = xstrdup (optarg);
+ STACK_VAR (opts_arg.attr);
break;
case OPT_CLEAN:
clean = true;
@@ -528,6 +538,7 @@ process_opts (int argc, char **argv, char **conf_file)
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;
@@ -556,6 +567,32 @@ process_opts (int argc, char **argv, char **conf_file)
}
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);
+ }
+ /* getpwuid() leaks memory */
+ 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)
{
/* If attributes are added to this "list", also increase MAX_ATTRIBUTE_CHARS! */
@@ -573,10 +610,10 @@ process_opt_attr (const char *p, const bool is_opt)
while (*p)
{
const char *s;
- if (!isalnum (*p))
+ if (!isalnum ((unsigned char)*p))
vfprintf_fail ("%s must be provided a string", desc_type[DESC_TYPE]);
s = p;
- while (isalnum (*p))
+ while (isalnum ((unsigned char)*p))
p++;
if (*p != '\0' && *p != ',')
vfprintf_fail ("%s must have strings separated by ,", desc_type[DESC_TYPE]);
@@ -601,7 +638,7 @@ process_opt_attr (const char *p, const bool is_opt)
strncpy (attr_invalid, s, p - s);
attr_invalid[p - s] = '\0';
vfprintf_fail ("%s attribute '%s' is not valid", desc_type[DESC_TYPE], attr_invalid);
- RELEASE_VAR (attr_invalid); /* never reached */
+ RELEASE (attr_invalid); /* never reached */
}
}
if (*p)
@@ -628,8 +665,7 @@ process_opt_exclude_random (const char *s, const bool is_opt)
{
bool valid = false;
unsigned int i;
- if (exclude)
- RELEASE_VAR (exclude);
+ RELEASE (exclude);
exclude = xstrdup (s);
STACK_VAR (exclude);
for (i = 1; i < tables[GENERIC].count - 1; i++) /* skip color none and default */
@@ -643,7 +679,7 @@ process_opt_exclude_random (const char *s, const bool is_opt)
}
if (!valid)
vfprintf_fail ("%s must be provided a plain color",
- is_opt ? "--exlude-random switch" : "exclude-random conf option");
+ is_opt ? "--exclude-random switch" : "exclude-random conf option");
}
static void
@@ -659,8 +695,8 @@ init_opts_vars (void)
if (opts_set & OPT_OMIT_COLOR_EMPTY_SET)
omit_color_empty = true;
- free (opts_arg.attr);
- free (opts_arg.exclude_random);
+ RELEASE (opts_arg.attr);
+ RELEASE (opts_arg.exclude_random);
}
#define IS_SPACE(c) ((c) == ' ' || (c) == '\t')
@@ -673,6 +709,7 @@ parse_conf (const char *conf_file, struct conf *config)
FILE *conf;
conf = open_file (conf_file, "r");
+ STACK_FILE (conf);
while (fgets (line, sizeof (line), conf))
{
@@ -711,7 +748,7 @@ parse_conf (const char *conf_file, struct conf *config)
/* NAME PARSING (end) */
/* NAME VALIDATION (start) */
for (p = opt; *p; p++)
- if (!isalnum (*p) && *p != '-')
+ if (!isalnum ((unsigned char)*p) && *p != '-')
vfprintf_fail (formats[FMT_CONF], conf_file, opt, "cannot be made of non-option characters");
/* NAME VALIDATION (end) */
/* VALUE PARSING (start) */
@@ -735,39 +772,34 @@ parse_conf (const char *conf_file, struct conf *config)
/* 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 (cfg);
}
- fclose (conf);
+ RELEASE (conf);
}
+#define ASSIGN_CONF(str,val) do { \
+ RELEASE (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");
}
@@ -786,7 +818,7 @@ init_conf_vars (const struct conf *config)
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");
}
}
@@ -823,7 +855,7 @@ print_help (void)
const char *code = entry->code;
if (code)
printf ("\t\t{\033[%s#\033[0m} [%c%c]%s%*s%s\n",
- code, toupper (*name), *name, name + 1, 10 - (int)strlen (name), " ", name);
+ code, toupper ((unsigned char)*name), *name, name + 1, 10 - (int)strlen (name), " ", name);
else
printf ("\t\t{-} %s%*s%s\n", name, 13 - (int)strlen (name), " ", name);
}
@@ -917,17 +949,32 @@ static void
cleanup (void)
{
if (stream && fileno (stream) != STDIN_FILENO)
- fclose (stream);
+ RELEASE (stream);
#if DEBUG
if (log)
- fclose (log);
+ RELEASE (log);
#endif
if (vars_list)
{
unsigned int i;
for (i = 0; i < stacked_vars; i++)
- free (vars_list[i]);
+ {
+ struct var_list *var = &vars_list[i];
+ switch (var->type)
+ {
+ case IS_GENERIC:
+ free (var->ptr);
+ break;
+ case IS_FILE:
+ fclose (var->ptr);
+ break;
+ case IS_UNUSED:
+ break;
+ default: /* never reached */
+ ABORT_TRACE ();
+ }
+ }
free_null (vars_list);
}
}
@@ -938,19 +985,19 @@ free_color_names (struct color_name **color_names)
unsigned int i;
for (i = 0; color_names[i]; i++)
{
- RELEASE_VAR (color_names[i]->name);
- RELEASE_VAR (color_names[i]->orig);
- RELEASE_VAR (color_names[i]);
+ RELEASE (color_names[i]->name);
+ RELEASE (color_names[i]->orig);
+ RELEASE (color_names[i]);
}
}
static void
free_conf (struct conf *config)
{
- free (config->attr);
- free (config->color);
- free (config->exclude_random);
- free (config->omit_color_empty);
+ RELEASE (config->attr);
+ RELEASE (config->color);
+ RELEASE (config->exclude_random);
+ RELEASE (config->omit_color_empty);
}
static void
@@ -1063,6 +1110,7 @@ process_file_arg (const char *file_string, const char **file, FILE **stream)
vfprintf_fail (formats[FMT_TYPE], file, "unrecognized type", get_file_type (sb.st_mode));
*stream = open_file (file, "r");
+ STACK_FILE (*stream);
}
*file = file_string;
}
@@ -1155,17 +1203,17 @@ gather_color_names (const char *color_string, char *attr, struct color_name **co
assert (p != NULL);
for (ch = color; *ch; ch++)
- if (!isalpha (*ch))
+ if (!isalpha ((unsigned char)*ch))
vfprintf_fail (formats[FMT_COLOR], tables[index].desc, color, "cannot be made of non-alphabetic characters");
for (ch = color + 1; *ch; ch++)
- if (!islower (*ch))
+ if (!islower ((unsigned char)*ch))
vfprintf_fail (formats[FMT_COLOR], tables[index].desc, color, "cannot be in mixed lower/upper case");
if (streq (color, "None"))
vfprintf_fail (formats[FMT_COLOR], tables[index].desc, color, "cannot be bold");
- if (isupper (*color))
+ if (isupper ((unsigned char)*color))
{
switch (index)
{
@@ -1187,13 +1235,13 @@ gather_color_names (const char *color_string, char *attr, struct color_name **co
STACK_VAR (color_names[index]->orig);
for (ch = color; *ch; ch++)
- *ch = tolower (*ch);
+ *ch = tolower ((unsigned char)*ch);
color_names[index]->name = xstrdup (color);
STACK_VAR (color_names[index]->name);
}
- RELEASE_VAR (str);
+ RELEASE (str);
}
static void
@@ -1553,10 +1601,10 @@ gather_esc_offsets (const char *p, const char **start, const char **end)
do {
check_values = false;
iter++;
- if (!isdigit (*p))
+ if (!isdigit ((unsigned char)*p))
break;
digit = p;
- while (isdigit (*p))
+ while (isdigit ((unsigned char)*p))
p++;
if (p - digit > 2)
break;
@@ -1589,7 +1637,7 @@ gather_esc_offsets (const char *p, const char **start, const char **end)
static bool
validate_esc_clean_all (const char **p)
{
- while (isdigit (**p) || **p == ';')
+ while (isdigit ((unsigned char)**p) || **p == ';')
(*p)++;
return (**p == 'm');
}
@@ -1797,7 +1845,7 @@ has_color_name (const char *str, const char *name)
assert (strlen (str) > 0);
assert (strlen (name) > 0);
- if (!(*str == *name || *str == toupper (*name)))
+ if (!(*str == *name || *str == toupper ((unsigned char)*name)))
return false;
else if (*(name + 1) != '\0'
&& !((p = strstr (str + 1, name + 1)) && p == str + 1))
@@ -1841,41 +1889,63 @@ vfprintf_fail (const char *fmt, ...)
}
static void
-stack_var (void ***list, unsigned int *stacked, unsigned int index, void *ptr)
+stack (struct var_list **list, unsigned int *stacked, unsigned int index, void *ptr, enum var_type type)
{
+ struct var_list *var;
/* nothing to stack */
if (ptr == NULL)
return;
if (!*list)
- *list = xmalloc (sizeof (void *));
+ *list = xmalloc (sizeof (struct var_list));
else
{
unsigned int i;
for (i = 0; i < *stacked; i++)
- if (!(*list)[i])
- {
- (*list)[i] = ptr;
- return; /* reused */
- }
- *list = xrealloc (*list, (*stacked + 1) * sizeof (void *));
+ {
+ var = &(*list)[i];
+ if (var->type == IS_UNUSED)
+ {
+ var->ptr = ptr;
+ var->type = type;
+ return; /* reused */
+ }
+ }
+ *list = xrealloc (*list, (*stacked + 1) * sizeof (struct var_list));
}
- (*list)[index] = ptr;
+ var = &(*list)[index];
+ var->ptr = ptr;
+ var->type = type;
(*stacked)++;
}
static void
-release_var (void **list, unsigned int stacked, void **ptr)
+release (struct var_list *list, unsigned int stacked, void **ptr)
{
unsigned int i;
/* nothing to release */
if (*ptr == NULL)
return;
for (i = 0; i < stacked; i++)
- if (list[i] == *ptr)
- {
- free (*ptr);
- *ptr = NULL;
- list[i] = NULL;
- return;
+ {
+ struct var_list *var = &list[i];
+ if (var->type != IS_UNUSED
+ && var->ptr == *ptr)
+ {
+ switch (var->type)
+ {
+ case IS_GENERIC:
+ free (*ptr);
+ break;
+ case IS_FILE:
+ fclose (*ptr);
+ break;
+ default: /* never reached */
+ ABORT_TRACE ();
+ }
+ *ptr = NULL;
+ var->ptr = NULL;
+ var->type = IS_UNUSED;
+ return;
}
+ }
}
diff --git a/debian/changelog b/debian/changelog
index acb96c2..37ca47b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
+colorize (0.65-2) UNRELEASED; urgency=medium
+
+ * debian/control: update Homepage link.
+
+ -- Steven Schubiger <stsc@refcnt.org> Tue, 23 Jun 2020 14:09:26 +0200
+
+colorize (0.65-1) unstable; urgency=low
+
+ * New upstream release.
+ * Declare compliance with Debian Policy 4.5.0.
+ (No changes needed.)
+ * debian/copyright: amend years.
+ * debian/control: use v12 mode of debhelper-compat package.
+ * debian/control: declare "Rules-Requires-Root: no".
+ * debian/copyright: update link to HTTPS, reported by duck(1).
+
+ -- Steven Schubiger <stsc@refcnt.org> Fri, 20 Mar 2020 22:42:04 +0100
+
colorize (0.64-1) unstable; urgency=low
* New upstream release.
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
index 1fd2752..00bfb3d 100644
--- a/debian/control
+++ b/debian/control
@@ -2,9 +2,10 @@ Source: colorize
Section: utils
Priority: optional
Maintainer: Steven Schubiger <stsc@refcnt.org>
-Build-Depends: debhelper (>= 9)
-Standards-Version: 4.1.4
-Homepage: http://cgit.refcnt.org/colorize.git/tree/README
+Build-Depends: debhelper-compat (= 12)
+Standards-Version: 4.5.0
+Rules-Requires-Root: no
+Homepage: http://cgit.refcnt.org/colorize.git/about/
Vcs-Git: git://refcnt.org/colorize.git
Vcs-Browser: http://cgit.refcnt.org/colorize.git/
diff --git a/debian/copyright b/debian/copyright
index ca3078c..e38c26b 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -3,11 +3,11 @@ Upstream-Name: colorize
Source: http://cgit.refcnt.org/colorize.git/
Files: *
-Copyright: 2011-2018 Steven Schubiger <stsc@refcnt.org>
+Copyright: 2011-2020 Steven Schubiger <stsc@refcnt.org>
License: GPL-3.0+
Files: debian/*
-Copyright: 2016-2018 Steven Schubiger <stsc@refcnt.org>
+Copyright: 2016-2020 Steven Schubiger <stsc@refcnt.org>
License: GPL-3.0+
License: GPL-3.0+
@@ -22,7 +22,7 @@ License: GPL-3.0+
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
.
On Debian systems, the complete text of the GNU General
Public License version 3 can be found in "/usr/share/common-licenses/GPL-3".
diff --git a/readme.pl b/readme.pl
new file mode 100755
index 0000000..877364b
--- /dev/null
+++ b/readme.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $readme = 'README';
+my $readme_cgit = 'README.cgit';
+
+die "$0: $readme does not exist\n" unless -e $readme;
+
+open(my $fh, '<', $readme) or die "Cannot open $readme for reading: $!\n";
+my $text = do { local $/; <$fh> };
+close($fh);
+
+$text = do {
+ local $_ = $text;
+ s/</&lt;/g;
+ s/>/&gt;/g;
+ $_
+};
+
+print "Writing $readme_cgit\n";
+
+open($fh, '>', $readme_cgit) or die "Cannot open $readme_cgit for writing: $!\n";
+print {$fh} <<"CGIT";
+<pre>
+$text
+</pre>
+CGIT
+close($fh);
diff --git a/test.pl b/test.pl
index 0ed7436..928c698 100755
--- a/test.pl
+++ b/test.pl
@@ -13,7 +13,7 @@ use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
use Test::Harness qw(runtests);
use Test::More;
-my $tests = 30;
+my $tests = 32;
my $valgrind_cmd = '';
{
@@ -98,6 +98,14 @@ SKIP: {
}
ok(qx(printf %s "\e[\e[33m" | $valgrind_cmd$program $switch) eq "\e[", "$type with invalid sequence");
+
+ {
+ my $ok = true;
+ foreach my $option (qw(--attr=bold --exclude-random=black --omit-color-empty)) {
+ $ok &= qx($valgrind_cmd$program $option $switch $infile1 2>&1 >/dev/null) =~ /switch has no meaning with/;
+ }
+ ok($ok, "$type strict options");
+ }
};
$check_clean->($_) foreach qw(clean clean-all);