static uintmax_t gobble_file (char const *name, enum filetype type,
ino_t inode, bool command_line_arg,
char const *dirname);
-static void print_color_indicator (const char *name, mode_t mode, int linkok,
+static bool print_color_indicator (const char *name, mode_t mode, int linkok,
bool stat_ok, enum filetype type);
static void put_indicator (const struct bin_str *ind);
static void add_ignore_pattern (const char *pattern);
static bool print_with_color;
+/* Whether we used any colors in the output so far. If so, we will
+ need to restore the default color later. If not, we will need to
+ call prep_non_filename_text before using color for the first time. */
+
+static bool used_color = false;
+
enum color_type
{
color_never, /* 0: default or --color=never */
enum indicator_no
{
- C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
+ C_LEFT, C_RIGHT, C_END, C_RESET, C_NORM, C_FILE, C_DIR, C_LINK,
+ C_FIFO, C_SOCK,
C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_DOOR, C_SETUID, C_SETGID,
C_STICKY, C_OTHER_WRITABLE, C_STICKY_OTHER_WRITABLE
};
static const char *const indicator_name[]=
{
- "lc", "rc", "ec", "no", "fi", "di", "ln", "pi", "so",
+ "lc", "rc", "ec", "rs", "no", "fi", "di", "ln", "pi", "so",
"bd", "cd", "mi", "or", "ex", "do", "su", "sg", "st",
"ow", "tw", NULL
};
{ LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */
{ LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */
{ 0, NULL }, /* ec: End color (replaces lc+no+rc) */
- { LEN_STR_PAIR ("0") }, /* no: Normal */
- { LEN_STR_PAIR ("0") }, /* fi: File: default */
+ { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */
+ { 0, NULL }, /* no: Normal */
+ { 0, NULL }, /* fi: File: default */
{ LEN_STR_PAIR ("01;34") }, /* di: Directory: bright blue */
{ LEN_STR_PAIR ("01;36") }, /* ln: Symlink: bright cyan */
{ LEN_STR_PAIR ("33") }, /* pi: Pipe: yellow/brown */
int stops;
sigset_t oldset;
- restore_default_color ();
+ if (used_color)
+ restore_default_color ();
fflush (stdout);
sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
}
#endif
}
-
- prep_non_filename_text ();
}
if (dereference == DEREF_UNDEFINED)
{
int j;
- restore_default_color ();
+ if (used_color)
+ restore_default_color ();
fflush (stdout);
/* Restore the default signal handling. */
bool stat_ok, enum filetype type,
struct obstack *stack)
{
- if (print_with_color)
- print_color_indicator (p, mode, linkok, stat_ok, type);
+ bool used_color_this_time
+ = (print_with_color
+ && print_color_indicator (p, mode, linkok, stat_ok, type));
if (stack)
PUSH_CURRENT_DIRED_POS (stack);
if (stack)
PUSH_CURRENT_DIRED_POS (stack);
- if (print_with_color)
+ if (used_color_this_time)
{
process_signals ();
prep_non_filename_text ();
else
{
put_indicator (&color_indicator[C_LEFT]);
- put_indicator (&color_indicator[C_NORM]);
+ put_indicator (&color_indicator[C_RESET]);
put_indicator (&color_indicator[C_RIGHT]);
}
}
DIRED_PUTCHAR (c);
}
-static void
+/* Returns whether any color sequence was printed. */
+static bool
print_color_indicator (const char *name, mode_t mode, int linkok,
bool stat_ok, enum filetype filetype)
{
}
}
- put_indicator (&color_indicator[C_LEFT]);
- put_indicator (ext ? &(ext->seq) : &color_indicator[type]);
- put_indicator (&color_indicator[C_RIGHT]);
+ {
+ const struct bin_str *const s
+ = ext ? &(ext->seq) : &color_indicator[type];
+ if (s->string != NULL)
+ {
+ put_indicator (&color_indicator[C_LEFT]);
+ put_indicator (s);
+ put_indicator (&color_indicator[C_RIGHT]);
+ return true;
+ }
+ else
+ return false;
+ }
}
/* Output a color indicator (which may contain nulls). */
size_t i;
const char *p;
+ if (! used_color)
+ {
+ used_color = true;
+ prep_non_filename_text ();
+ }
+
p = ind->string;
for (i = ind->len; i != 0; --i)
#!/bin/sh
# -*- perl -*-
-# Copyright (C) 1998, 2000-2007 Free Software Foundation, Inc.
+# Copyright (C) 1998, 2000-2008 Free Software Foundation, Inc.
# 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
or (warn "$program_name: cannot create setuid/setgid/sticky files,"
. "so can't run this test\n"), exit 77;
-my $mkdir = {PRE => sub {mkdir 'd',0755 or die "d: $!\n"}};
-my $rmdir = {POST => sub {rmdir 'd' or die "d: $!\n"}};
+sub mkdir_d {mkdir 'd',0755 or die "d: $!\n"}
+sub rmdir_d {rmdir 'd' or die "d: $!\n"}
+my $mkdir = {PRE => sub {mkdir_d}};
+my $rmdir = {POST => sub {rmdir_d}};
+my $mkdir_reg = {PRE => sub {mkdir_d; open (FH, '>d/f') && close FH
+ or die "d/f: $!\n" }};
+my $rmdir_reg = {POST => sub {unlink 'd/f' or die "d/f: $!\n";
+ rmdir 'd' or die "d: $!\n"}};
my $mkdir2 = {PRE => sub {mkdir 'd',0755 or die "d: $!\n";
mkdir 'd/e',0755 or die "d/e: $!\n" }};
{OUT => "\e[0m\e[01;36md\e[0m\@\n\e[m"},
$slink_d, $unlink_d],
+ # A listing with no output should have no color sequences at all.
+ ['no-c-empty', '--color=always d', {OUT => ""}, $mkdir, $rmdir],
+ # A listing with only regular files should have no color sequences at all.
+ ['no-c-reg', '--color=always d', {OUT => "f\n"}, $mkdir_reg, $rmdir_reg],
+
# Test for a bug fixed after coreutils-6.9.
['sl-target', '--color=always d',
{OUT => "\e[0m\e[01;34mX\e[0m\n\e[m"}, $target, $target2],