From 6cc9cae2d6fb9bbfd340243dfa735e1a08fe75cc Mon Sep 17 00:00:00 2001 From: Steven Schubiger Date: Sat, 25 Jan 2014 22:00:57 +0100 Subject: Display type and name of file in error messages --- colorize.c | 48 +++++++++++++++++++++++++++++++++++++++++------- test.pl | 8 +++++--- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/colorize.c b/colorize.c index d174a11..69aca35 100644 --- a/colorize.c +++ b/colorize.c @@ -68,6 +68,8 @@ #define SKIP_LINE_ENDINGS(flags) (((flags) & CR) && ((flags) & LF) ? 2 : 1) +#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); \ } while (false) @@ -139,17 +141,21 @@ static const struct color bg_colors[] = { enum fmts { FMT_GENERIC, + FMT_QUOTE, FMT_COLOR, FMT_RANDOM, FMT_ERROR, - FMT_FILE + FMT_FILE, + FMT_TYPE }; static const char *formats[] = { "%s", /* generic */ + "%s `%s' %s", /* quote */ "%s color '%s' %s", /* color */ "%s color '%s' %s '%s'", /* random */ "less than %u bytes %s", /* error */ "%s: %s", /* file */ + "%s: %s: %s", /* type */ }; enum { FOREGROUND, BACKGROUND }; @@ -197,6 +203,7 @@ static void *realloc_wrap_debug (void *, size_t, const char *, unsigned int); static void free_wrap (void **); static char *strdup_wrap (const char *); static char *str_concat (const char *, const char *); +static char *get_file_type (mode_t); static bool has_color_name (const char *, const char *); static void vfprintf_diag (const char *, ...); static void vfprintf_fail (const char *, ...); @@ -451,7 +458,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, bool *bold, const struct vfprintf_fail (formats[FMT_GENERIC], "hyphen must be preceeded by color string"); } - ret = stat (color_string, &sb); + ret = lstat (color_string, &sb); /* Ensure that we don't fail if there's a file with one or more color names in its path. */ @@ -460,6 +467,7 @@ process_args (unsigned int arg_cnt, char **arg_strings, bool *bold, const struct bool have_file; unsigned int c; const char *color = color_string; + const mode_t mode = sb.st_mode; for (c = 1; c <= 2 && *color; c++) { @@ -491,9 +499,14 @@ process_args (unsigned int arg_cnt, char **arg_strings, bool *bold, const struct if (have_file) { if (file_string) - vfprintf_fail (formats[FMT_GENERIC], "file cannot be used as color string"); + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), color_string, "cannot be used as color string"); else - vfprintf_fail (formats[FMT_GENERIC], "file must be preceeded by color string"); + { + if (VALID_FILE_TYPE (mode)) + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), color_string, "must be preceeded by color string"); + else + vfprintf_fail (formats[FMT_QUOTE], get_file_type (mode), color_string, "is not a valid file type"); + } } } @@ -606,13 +619,13 @@ process_file_arg (const char *file_string, const char **file, FILE **stream) int errno, ret; errno = 0; - ret = stat (file, &sb); + ret = lstat (file, &sb); if (ret == -1) vfprintf_fail (formats[FMT_FILE], file, strerror (errno)); - if (!(S_ISREG (sb.st_mode) || S_ISLNK (sb.st_mode) || S_ISFIFO (sb.st_mode))) - vfprintf_fail (formats[FMT_FILE], file, "unrecognized file type"); + if (!VALID_FILE_TYPE (sb.st_mode)) + vfprintf_fail (formats[FMT_TYPE], file, "unrecognized type", get_file_type (sb.st_mode)); errno = 0; @@ -1011,6 +1024,27 @@ str_concat (const char *str1, const char *str2) return str; } +static char * +get_file_type (mode_t mode) +{ + if (S_ISREG (mode)) + return "file"; + else if (S_ISDIR (mode)) + return "directory"; + else if (S_ISCHR (mode)) + return "character device"; + else if (S_ISBLK (mode)) + return "block device"; + else if (S_ISFIFO (mode)) + return "named pipe"; + else if (S_ISLNK (mode)) + return "symbolic link"; + else if (S_ISSOCK (mode)) + return "socket"; + else + return "file"; +} + static bool has_color_name (const char *str, const char *name) { diff --git a/test.pl b/test.pl index 5dc3bf3..8d8b592 100755 --- a/test.pl +++ b/test.pl @@ -5,7 +5,7 @@ use warnings; use constant true => 1; use constant false => 0; -use File::Temp qw(tempfile tmpnam); +use File::Temp qw(tempfile tempdir tmpnam); use IPC::Open3 qw(open3); use Symbol qw(gensym); use Test::More; @@ -64,6 +64,7 @@ SKIP: { my $ok = true; my $file = $write_to_tmpfile->('abc'); + my $dir = tempdir(CLEANUP => true); $ok &= $run_program_fail->($program, '--exclude-random=random', 'must be provided a plain color'); $ok &= $run_program_fail->($program, '--clean --clean-all', 'mutually exclusive'); @@ -71,8 +72,9 @@ SKIP: { $ok &= $run_program_fail->($program, '--clean-all file1 file2', 'more than one file'); $ok &= $run_program_fail->($program, '- file', 'hyphen cannot be used as color string'); $ok &= $run_program_fail->($program, '-', 'hyphen must be preceeded by color string'); - $ok &= $run_program_fail->($program, "$file file", 'file cannot be used as color string'); - $ok &= $run_program_fail->($program, "$file", 'file must be preceeded by color string'); + $ok &= $run_program_fail->($program, "$file file", 'cannot be used as color string'); + $ok &= $run_program_fail->($program, "$file", 'must be preceeded by color string'); + $ok &= $run_program_fail->($program, "$dir", 'is not a valid file type'); $ok &= $run_program_fail->($program, '/black', 'foreground color missing'); $ok &= $run_program_fail->($program, 'white/', 'background color missing'); $ok &= $run_program_fail->($program, 'white/black/yellow', 'one color pair allowed only'); -- cgit v1.2.3