]> git.refcnt.org Git - colorize.git/blobdiff - colorize.c
*alloc_wrap_debug(): improve aligning of debug output
[colorize.git] / colorize.c
index 49879c5db6de0c2450af5b6b0179b4cf3c3fd4f7..f91af67ce30ad1cce06f2553c0d0588969f75274 100644 (file)
@@ -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-2017 Steven Schubiger
+ * Copyright (c) 2011-2018 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
@@ -73,6 +73,8 @@
 #define LF 0x01
 #define CR 0x02
 
+#define COUNT_OF(obj, type) (sizeof (obj) / sizeof (type))
+
 #define SKIP_LINE_ENDINGS(flags) ((flags) == (CR|LF) ? 2 : 1)
 
 #define VALID_FILE_TYPE(mode) (S_ISREG (mode) || S_ISLNK (mode) || S_ISFIFO (mode))
 
 #define ABORT_TRACE()                                                              \
     fprintf (stderr, "Aborting in source file %s, line %u\n", __FILE__, __LINE__); \
-    abort ();                                                                      \
+    abort ();
 
 #define CHECK_COLORS_RANDOM(color1, color2)        \
      streq (color_names[color1]->name, "random")   \
  && (streq (color_names[color2]->name, "none")     \
-  || streq (color_names[color2]->name, "default")) \
+  || streq (color_names[color2]->name, "default"))
 
 #define ALLOC_COMPLETE_PART_LINE 8
 
 
 #define MAX_ATTRIBUTE_CHARS (6 * 2)
 
-#define VERSION "0.62"
+#define PROGRAM_NAME "colorize"
+
+#define VERSION "0.64"
 
 typedef enum { false, true } bool;
 
@@ -194,8 +198,8 @@ static const struct {
     unsigned int count;
     const char *desc;
 } tables[] = {
-    { fg_colors, sizeof (fg_colors) / sizeof (struct color), "foreground" },
-    { bg_colors, sizeof (bg_colors) / sizeof (struct color), "background" },
+    { fg_colors, COUNT_OF (fg_colors, struct color), "foreground" },
+    { bg_colors, COUNT_OF (bg_colors, struct color), "background" },
 };
 
 enum {
@@ -203,18 +207,20 @@ enum {
     OPT_CLEAN,
     OPT_CLEAN_ALL,
     OPT_EXCLUDE_RANDOM,
+    OPT_OMIT_COLOR_EMPTY,
     OPT_HELP,
     OPT_VERSION
 };
 static int opt_type;
 static const struct option long_opts[] = {
-    { "attr",           required_argument, &opt_type, OPT_ATTR           },
-    { "clean",          no_argument,       &opt_type, OPT_CLEAN          },
-    { "clean-all",      no_argument,       &opt_type, OPT_CLEAN_ALL      },
-    { "exclude-random", required_argument, &opt_type, OPT_EXCLUDE_RANDOM },
-    { "help",           no_argument,       &opt_type, OPT_HELP           },
-    { "version",        no_argument,       &opt_type, OPT_VERSION        },
-    {  NULL,            0,                 NULL,      0                  },
+    { "attr",             required_argument, &opt_type, OPT_ATTR             },
+    { "clean",            no_argument,       &opt_type, OPT_CLEAN            },
+    { "clean-all",        no_argument,       &opt_type, OPT_CLEAN_ALL        },
+    { "exclude-random",   required_argument, &opt_type, OPT_EXCLUDE_RANDOM   },
+    { "omit-color-empty", no_argument,       &opt_type, OPT_OMIT_COLOR_EMPTY },
+    { "help",             no_argument,       &opt_type, OPT_HELP             },
+    { "version",          no_argument,       &opt_type, OPT_VERSION          },
+    {  NULL,              0,                 NULL,      0                    },
 };
 
 enum attr_type {
@@ -240,6 +246,7 @@ static void **vars_list;
 
 static bool clean;
 static bool clean_all;
+static bool omit_color_empty;
 
 static char attr[MAX_ATTRIBUTE_CHARS + 1];
 static char *exclude;
@@ -265,7 +272,7 @@ static bool get_next_char (char *, const char **, FILE *, bool *);
 static void save_char (char, char **, size_t *, size_t *);
 static void find_color_entries (struct color_name **, const struct color **);
 static void find_color_entry (const struct color_name *, unsigned int, const struct color **);
-static void print_line (const char *, const struct color **, const char * const, unsigned int);
+static void print_line (const char *, const struct color **, const char * const, unsigned int, bool);
 static void print_clean (const char *);
 static bool is_esc (const char *);
 static const char *get_end_of_esc (const char *);
@@ -334,8 +341,8 @@ main (int argc, char **argv)
           vfprintf_fail (formats[FMT_GENERIC], "--clean and --clean-all switch are mutually exclusive");
         if (arg_cnt > 1)
           {
-            const char *format = "%s %s";
-            const char *message = "switch cannot be used with more than one file";
+            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)
@@ -365,11 +372,11 @@ main (int argc, char **argv)
 
 #define PRINT_HELP_EXIT() \
     print_help ();        \
-    exit (EXIT_SUCCESS);  \
+    exit (EXIT_SUCCESS);
 
 #define PRINT_VERSION_EXIT() \
     print_version ();        \
-    exit (EXIT_SUCCESS);     \
+    exit (EXIT_SUCCESS);
 
 extern char *optarg;
 
@@ -411,6 +418,9 @@ process_opts (int argc, char **argv)
                       vfprintf_fail (formats[FMT_GENERIC], "--exclude-random switch must be provided a plain color");
                     break;
                   }
+                  case OPT_OMIT_COLOR_EMPTY:
+                    omit_color_empty = true;
+                    break;
                   case OPT_HELP:
                     PRINT_HELP_EXIT ();
                   case OPT_VERSION:
@@ -459,7 +469,7 @@ process_opt_attr (const char *p)
           {
             bool valid_attr = false;
             unsigned int i;
-            for (i = 0; i < sizeof (attrs) / sizeof (struct attr); i++)
+            for (i = 0; i < COUNT_OF (attrs, struct attr); i++)
               {
                 const size_t name_len = strlen (attrs[i].name);
                 if ((size_t)(p - s) == name_len && strneq (s, attrs[i].name, name_len))
@@ -543,7 +553,7 @@ print_help (void)
       {
         const struct opt_data *opt_data = NULL;
         unsigned int i;
-        for (i = 0; i < sizeof (opts_data) / sizeof (struct opt_data); i++)
+        for (i = 0; i < COUNT_OF (opts_data, struct opt_data); i++)
           if (streq (opt->name, opts_data[i].name))
             {
               opt_data = &opts_data[i];
@@ -568,7 +578,7 @@ print_version (void)
 #ifdef HAVE_VERSION
 # include "version.h"
 #else
-    const char *version = NULL;
+    const char *const version = NULL;
 #endif
     const char *version_prefix, *version_string;
     const char *c_flags, *ld_flags, *cpp_flags;
@@ -597,7 +607,7 @@ print_version (void)
 #endif
     version_prefix = version ? "" : "v";
     version_string = version ? version : VERSION;
-    printf ("colorize %s%s (compiled at %s, %s)\n", version_prefix, version_string, __DATE__, __TIME__);
+    printf ("%s %s%s (compiled at %s, %s)\n", PROGRAM_NAME, version_prefix, version_string, __DATE__, __TIME__);
 
     printf ("Compiler flags: %s\n", c_flags);
     printf ("Linker flags: %s\n", ld_flags);
@@ -653,7 +663,11 @@ process_args (unsigned int arg_cnt, char **arg_strings, char *attr, const struct
     int ret;
     char *p;
     struct stat sb;
-    struct color_name *color_names[3] = { NULL, NULL, NULL };
+    struct color_name *color_names[3] = {
+        NULL, /* foreground */
+        NULL, /* background */
+        NULL, /* sentinel value */
+    };
 
     const char *color_string = arg_cnt >= 1 ? arg_strings[0] : NULL;
     const char *file_string  = arg_cnt == 2 ? arg_strings[1] : NULL;
@@ -886,6 +900,7 @@ read_print_stream (const char *attr, const struct color **colors, const char *fi
         line = buf;
         while ((eol = strpbrk (line, "\n\r")))
           {
+            const bool has_text = (eol > line);
             const char *p;
             flags &= ~(CR|LF);
             if (*eol == '\r')
@@ -896,17 +911,18 @@ read_print_stream (const char *attr, const struct color **colors, const char *fi
               }
             else if (*eol == '\n')
               flags |= LF;
-            else
+            else /* never reached */
               vfprintf_fail (formats[FMT_FILE], file, "unrecognized line ending");
             p = eol + SKIP_LINE_ENDINGS (flags);
             *eol = '\0';
-            print_line (attr, colors, line, flags);
+            print_line (attr, colors, line, flags,
+                        omit_color_empty ? has_text : true);
             line = p;
           }
         if (feof (stream))
           {
             if (*line != '\0')
-              print_line (attr, colors, line, 0);
+              print_line (attr, colors, line, 0, true);
           }
         else if (*line != '\0')
           {
@@ -914,7 +930,7 @@ read_print_stream (const char *attr, const struct color **colors, const char *fi
             if ((clean || clean_all) && (p = strrchr (line, '\033')))
               merge_print_line (line, p, stream);
             else
-              print_line (attr, colors, line, 0);
+              print_line (attr, colors, line, 0, true);
           }
       }
 }
@@ -1121,12 +1137,13 @@ find_color_entry (const struct color_name *color_name, unsigned int index, const
 }
 
 static void
-print_line (const char *attr, const struct color **colors, const char *const line, unsigned int flags)
+print_line (const char *attr, const struct color **colors, const char *const line, unsigned int flags, bool emit_colors)
 {
     /* --clean[-all] */
     if (clean || clean_all)
       print_clean (line);
-    else
+    /* skip for --omit-color-empty? */
+    else if (emit_colors)
       {
         /* Foreground color code is guaranteed to be set when background color code is present.  */
         if (colors[BACKGROUND] && colors[BACKGROUND]->code)
@@ -1335,13 +1352,14 @@ realloc_wrap (void *ptr, size_t size)
     return p;
 }
 #else
+static const char *const format_debug = "%s: %10s %7lu bytes [source file %s, line %5u]\n";
 static void *
 malloc_wrap_debug (size_t size, const char *file, unsigned int line)
 {
     void *p = malloc (size);
     if (!p)
       MEM_ALLOC_FAIL_DEBUG (file, line);
-    fprintf (log, "%s: malloc'ed %lu bytes [source file %s, line %u]\n", program_name, (unsigned long)size, file, line);
+    fprintf (log, format_debug, program_name, "malloc'ed", (unsigned long)size, file, line);
     return p;
 }
 
@@ -1351,7 +1369,7 @@ calloc_wrap_debug (size_t nmemb, size_t size, const char *file, unsigned int lin
     void *p = calloc (nmemb, size);
     if (!p)
       MEM_ALLOC_FAIL_DEBUG (file, line);
-    fprintf (log, "%s: calloc'ed %lu bytes [source file %s, line %u]\n", program_name, (unsigned long)(nmemb * size), file, line);
+    fprintf (log, format_debug, program_name, "calloc'ed", (unsigned long)(nmemb * size), file, line);
     return p;
 }
 
@@ -1361,7 +1379,7 @@ realloc_wrap_debug (void *ptr, size_t size, const char *file, unsigned int line)
     void *p = realloc (ptr, size);
     if (!p)
       MEM_ALLOC_FAIL_DEBUG (file, line);
-    fprintf (log, "%s: realloc'ed %lu bytes [source file %s, line %u]\n", program_name, (unsigned long)size, file, line);
+    fprintf (log, format_debug, program_name, "realloc'ed", (unsigned long)size, file, line);
     return p;
 }
 #endif /* !DEBUG */
@@ -1448,16 +1466,16 @@ has_color_name (const char *str, const char *name)
 {
     char *p;
 
-    assert (strlen (str));
-    assert (strlen (name));
+    assert (strlen (str) > 0);
+    assert (strlen (name) > 0);
 
     if (!(*str == *name || *str == toupper (*name)))
       return false;
     else if (*(name + 1) != '\0'
      && !((p = strstr (str + 1, name + 1)) && p == str + 1))
       return false;
-
-    return true;
+    else
+      return true;
 }
 
 static FILE *
@@ -1479,7 +1497,7 @@ open_file (const char *file, const char *mode)
     va_start (ap, fmt);                     \
     vfprintf (stderr, fmt, ap);             \
     va_end (ap);                            \
-    fprintf (stderr, "\n");                 \
+    fprintf (stderr, "\n");
 
 static void
 vfprintf_diag (const char *fmt, ...)