X-Git-Url: http://git.refcnt.org/?p=colorize.git;a=blobdiff_plain;f=colorize.c;h=1d83781d6df5ff3fb636312aca4fd24f81753bd5;hp=7683e1c70c6137f0ecf316fe3fd31f14e2fbff4c;hb=aa263791f3e5e06ffd46621fdf9132921f8911a5;hpb=4848afa27f5788eba267c7e8508efdcb1fec41b3 diff --git a/colorize.c b/colorize.c index 7683e1c..1d83781 100644 --- a/colorize.c +++ b/colorize.c @@ -73,7 +73,7 @@ #define LF 0x01 #define CR 0x02 -#define SKIP_LINE_ENDINGS(flags) (((flags) & CR) && ((flags) & LF) ? 2 : 1) +#define SKIP_LINE_ENDINGS(flags) ((flags) == (CR|LF) ? 2 : 1) #define VALID_FILE_TYPE(mode) (S_ISREG (mode) || S_ISLNK (mode) || S_ISFIFO (mode)) @@ -116,11 +116,13 @@ # define COLOR_SEP_CHAR '/' #endif -#define DEBUG_FILE "debug.txt" +#if DEBUG +# define DEBUG_FILE "debug.txt" +#endif -#define MAX_ATTRIBUTE_CHARS (5 * 2) +#define MAX_ATTRIBUTE_CHARS (6 * 2) -#define VERSION "0.60" +#define VERSION "0.63" typedef enum { false, true } bool; @@ -164,7 +166,7 @@ struct bytes_size { char unit; }; -enum fmts { +enum { FMT_GENERIC, FMT_STRING, FMT_QUOTE, @@ -188,7 +190,7 @@ static const char *formats[] = { enum { GENERIC, FOREGROUND = 0, BACKGROUND }; static const struct { - struct color const *entries; + const struct color *entries; unsigned int count; const char *desc; } tables[] = { @@ -215,6 +217,19 @@ static const struct option long_opts[] = { { NULL, 0, NULL, 0 }, }; +enum attr_type { + ATTR_BOLD = 0x01, + ATTR_UNDERSCORE = 0x02, + ATTR_BLINK = 0x04, + ATTR_REVERSE = 0x08, + ATTR_CONCEALED = 0x10 +}; +struct attr { + const char *name; + unsigned int val; + enum attr_type type; +}; + static FILE *stream; #if DEBUG static FILE *log; @@ -233,7 +248,7 @@ static const char *program_name; static void process_opts (int, char **); static void process_opt_attr (const char *); -static void write_attr (unsigned int); +static void write_attr (const struct attr *, unsigned int *); static void print_hint (void); static void print_help (void); static void print_version (void); @@ -420,6 +435,16 @@ process_opts (int argc, char **argv) static void process_opt_attr (const char *p) { + /* If attributes are added to this "list", also increase MAX_ATTRIBUTE_CHARS! */ + const struct attr attrs[] = { + { "bold", 1, ATTR_BOLD }, + { "underscore", 4, ATTR_UNDERSCORE }, + { "blink", 5, ATTR_BLINK }, + { "reverse", 7, ATTR_REVERSE }, + { "concealed", 8, ATTR_CONCEALED }, + }; + unsigned int attr_types = 0; + while (*p) { const char *s; @@ -432,19 +457,27 @@ process_opt_attr (const char *p) vfprintf_fail (formats[FMT_GENERIC], "--attr switch must have strings separated by ,"); else { - /* If attributes are added to this "list", also increase MAX_ATTRIBUTE_CHARS! */ - if (p - s == 4 && strneq (s, "bold", 4)) - write_attr (1); - else if (p - s == 10 && strneq (s, "underscore", 10)) - write_attr (4); - else if (p - s == 5 && strneq (s, "blink", 5)) - write_attr (5); - else if (p - s == 7 && strneq (s, "reverse", 7)) - write_attr (7); - else if (p - s == 9 && strneq (s, "concealed", 9)) - write_attr (8); - else - vfprintf_fail (formats[FMT_GENERIC], "--attr switch must be provided valid attribute names"); + bool valid_attr = false; + unsigned int i; + for (i = 0; i < sizeof (attrs) / sizeof (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)) + { + write_attr (&attrs[i], &attr_types); + valid_attr = true; + break; + } + } + if (!valid_attr) + { + char *attr_invalid = xmalloc ((p - s) + 1); + STACK_VAR (attr_invalid); + strncpy (attr_invalid, s, p - s); + attr_invalid[p - s] = '\0'; + vfprintf_fail ("--attr switch attribute '%s' is not valid", attr_invalid); + RELEASE_VAR (attr_invalid); /* never reached */ + } } if (*p) p++; @@ -452,9 +485,16 @@ process_opt_attr (const char *p) } static void -write_attr (unsigned int val) +write_attr (const struct attr *attr_i, unsigned int *attr_types) { + const unsigned int val = attr_i->val; + const enum attr_type attr_type = attr_i->type; + const char *attr_name = attr_i->name; + + if (*attr_types & attr_type) + vfprintf_fail ("--attr switch has attribute '%s' twice or more", attr_name); snprintf (attr + strlen (attr), 3, "%u;", val); + *attr_types |= attr_type; } static void @@ -466,13 +506,16 @@ print_hint (void) static void print_help (void) { - struct short_opt { + struct opt_data { const char *name; const char *short_opt; + const char *arg; }; - const struct short_opt short_opts[] = { - { "help", "h" }, - { "version", "V" }, + const struct opt_data opts_data[] = { + { "attr", NULL, "=ATTR1,ATTR2,..." }, + { "exclude-random", NULL, "=COLOR" }, + { "help", "h", NULL }, + { "version", "V", NULL }, }; const struct option *opt = long_opts; unsigned int i; @@ -498,18 +541,21 @@ print_help (void) printf ("\n\tOptions\n"); for (; opt->name; opt++) { - const char *short_opt = NULL; + const struct opt_data *opt_data = NULL; unsigned int i; - for (i = 0; i < sizeof (short_opts) / sizeof (struct short_opt); i++) + for (i = 0; i < sizeof (opts_data) / sizeof (struct opt_data); i++) + if (streq (opt->name, opts_data[i].name)) + { + opt_data = &opts_data[i]; + break; + } + if (opt_data) { - if (streq (opt->name, short_opts[i].name)) - { - short_opt = short_opts[i].short_opt; - break; - } + if (opt_data->short_opt) + printf ("\t\t-%s, --%s\n", opt_data->short_opt, opt->name); + else + printf ("\t\t --%s%s\n", opt->name, opt_data->arg); } - if (short_opt) - printf ("\t\t-%s, --%s\n", short_opt, opt->name); else printf ("\t\t --%s\n", opt->name); } @@ -526,22 +572,23 @@ print_version (void) #endif const char *version_prefix, *version_string; const char *c_flags, *ld_flags, *cpp_flags; + const char *const desc_flags_unknown = "unknown"; struct bytes_size bytes_size; bool debug; #ifdef CFLAGS c_flags = to_str (CFLAGS); #else - c_flags = "unknown"; + c_flags = desc_flags_unknown; #endif #ifdef LDFLAGS ld_flags = to_str (LDFLAGS); #else - ld_flags = "unknown"; + ld_flags = desc_flags_unknown; #endif #ifdef CPPFLAGS cpp_flags = to_str (CPPFLAGS); #else - cpp_flags = "unknown"; + cpp_flags = desc_flags_unknown; #endif #if DEBUG debug = true; @@ -611,7 +658,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, char *attr, const struct const char *color_string = arg_cnt >= 1 ? arg_strings[0] : NULL; const char *file_string = arg_cnt == 2 ? arg_strings[1] : NULL; - assert (color_string); + assert (color_string != NULL); if (streq (color_string, "-")) { @@ -640,7 +687,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, char *attr, const struct gather_color_names (color_string, attr, color_names); - assert (color_names[FOREGROUND]); + assert (color_names[FOREGROUND] != NULL); if (color_names[BACKGROUND]) { @@ -656,6 +703,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, char *attr, const struct } find_color_entries (color_names, colors); + assert (colors[FOREGROUND] != NULL); free_color_names (color_names); if (!colors[FOREGROUND]->code && colors[BACKGROUND] && colors[BACKGROUND]->code) @@ -664,6 +712,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, char *attr, const struct color_name.name = color_name.orig = "default"; find_color_entry (&color_name, FOREGROUND, colors); + assert (colors[FOREGROUND]->code != NULL); } process_file_arg (file_string, file, stream); @@ -701,8 +750,8 @@ process_file_arg (const char *file_string, const char **file, FILE **stream) *file = "stdin"; } - assert (*stream); - assert (*file); + assert (*stream != NULL); + assert (*file != NULL); } static void @@ -742,15 +791,15 @@ skip_path_colors (const char *color_string, const char *file_string, const struc if (have_file) { - const char *file_exists = color_string; + const char *file_existing = color_string; if (file_string) - vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_exists, "cannot be used as color string"); + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_existing, "cannot be used as color string"); else { if (VALID_FILE_TYPE (mode)) - vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_exists, "must be preceded by color string"); + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_existing, "must be preceded by color string"); else - vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_exists, "is not a valid file type"); + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), file_existing, "is not a valid file type"); } } } @@ -776,7 +825,7 @@ gather_color_names (const char *color_string, char *attr, struct color_name **co } else p = color + strlen (color); - assert (p); + assert (p != NULL); for (ch = color; *ch; ch++) if (!isalpha (*ch)) @@ -932,7 +981,7 @@ complete_part_line (const char *p, char **buf, FILE *stream) if (read_from_stream) save_char (ch, buf, &i, &size); } - else /* read next character */ + else /* got next character */ { got_next_char = true; break; @@ -1399,8 +1448,8 @@ 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;