summaryrefslogtreecommitdiff
path: root/src/dircolors.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dircolors.c')
-rw-r--r--src/dircolors.c368
1 files changed, 182 insertions, 186 deletions
diff --git a/src/dircolors.c b/src/dircolors.c
index 82eb1e0..0ada494 100644
--- a/src/dircolors.c
+++ b/src/dircolors.c
@@ -1,11 +1,11 @@
/* dircolors - output commands to set the LS_COLOR environment variable
- Copyright (C) 1996-2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2016 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000 H. Peter Anvin
- This program is free software; you can redistribute it and/or modify
+ 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
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,28 +13,27 @@
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, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <sys/types.h>
+#include <fnmatch.h>
#include <getopt.h>
-#include <stdio.h>
#include "system.h"
#include "dircolors.h"
#include "c-strcase.h"
#include "error.h"
-#include "getline.h"
#include "obstack.h"
#include "quote.h"
+#include "stdio--.h"
#include "xstrndup.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "dircolors"
-#define AUTHORS "H. Peter Anvin"
+#define AUTHORS proper_name ("H. Peter Anvin")
#define obstack_chunk_alloc malloc
#define obstack_chunk_free free
@@ -61,21 +60,21 @@ static struct obstack lsc_obstack;
static const char *const slack_codes[] =
{
- "NORMAL", "NORM", "FILE", "DIR", "LNK", "LINK",
+ "NORMAL", "NORM", "FILE", "RESET", "DIR", "LNK", "LINK",
"SYMLINK", "ORPHAN", "MISSING", "FIFO", "PIPE", "SOCK", "BLK", "BLOCK",
"CHR", "CHAR", "DOOR", "EXEC", "LEFT", "LEFTCODE", "RIGHT", "RIGHTCODE",
"END", "ENDCODE", "SUID", "SETUID", "SGID", "SETGID", "STICKY",
- "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", NULL
+ "OTHER_WRITABLE", "OWR", "STICKY_OTHER_WRITABLE", "OWT", "CAPABILITY",
+ "MULTIHARDLINK", "CLRTOEOL", NULL
};
static const char *const ls_codes[] =
{
- "no", "no", "fi", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi",
+ "no", "no", "fi", "rs", "di", "ln", "ln", "ln", "or", "mi", "pi", "pi",
"so", "bd", "bd", "cd", "cd", "do", "ex", "lc", "lc", "rc", "rc", "ec", "ec",
- "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", NULL
+ "su", "su", "sg", "sg", "st", "ow", "ow", "tw", "tw", "ca", "mh", "cl", NULL
};
-#define array_len(Array) (sizeof (Array) / sizeof *(Array))
-verify (array_len (slack_codes) == array_len (ls_codes));
+verify (ARRAY_CARDINALITY (slack_codes) == ARRAY_CARDINALITY (ls_codes));
static struct option const long_options[] =
{
@@ -89,14 +88,11 @@ static struct option const long_options[] =
{NULL, 0, NULL, 0}
};
-char *program_name;
-
void
usage (int status)
{
if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
+ emit_try_help ();
else
{
printf (_("Usage: %s [OPTION]... [FILE]\n"), program_name);
@@ -114,15 +110,15 @@ Determine format of output:\n\
\n\
If FILE is specified, read it to determine which colors to use for which\n\
file types and extensions. Otherwise, a precompiled database is used.\n\
-For details on the format of these files, run `dircolors --print-database'.\n\
+For details on the format of these files, run 'dircolors --print-database'.\n\
"), stdout);
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ emit_ancillary_info (PROGRAM_NAME);
}
exit (status);
}
-/* If the SHELL environment variable is set to `csh' or `tcsh,'
+/* If the SHELL environment variable is set to 'csh' or 'tcsh,'
assume C shell. Else Bourne shell. */
static enum Shell_syntax
@@ -202,29 +198,29 @@ append_quoted (const char *str)
while (*str != '\0')
{
switch (*str)
- {
- case '\'':
- APPEND_CHAR ('\'');
- APPEND_CHAR ('\\');
- APPEND_CHAR ('\'');
- need_backslash = true;
- break;
-
- case '\\':
- case '^':
- need_backslash = !need_backslash;
- break;
-
- case ':':
- case '=':
- if (need_backslash)
- APPEND_CHAR ('\\');
- /* Fall through */
-
- default:
- need_backslash = true;
- break;
- }
+ {
+ case '\'':
+ APPEND_CHAR ('\'');
+ APPEND_CHAR ('\\');
+ APPEND_CHAR ('\'');
+ need_backslash = true;
+ break;
+
+ case '\\':
+ case '^':
+ need_backslash = !need_backslash;
+ break;
+
+ case ':':
+ case '=':
+ if (need_backslash)
+ APPEND_CHAR ('\\');
+ /* Fall through */
+
+ default:
+ need_backslash = true;
+ break;
+ }
APPEND_CHAR (*str);
++str;
@@ -232,7 +228,7 @@ append_quoted (const char *str)
}
/* Read the file open on FP (with name FILENAME). First, look for a
- `TERM name' directive where name matches the current terminal type.
+ 'TERM name' directive where name matches the current terminal type.
Once found, translate and accumulate the associated directives onto
the global obstack LSC_OBSTACK. Give a diagnostic
upon failure (unrecognized keyword is the only way to fail here).
@@ -265,106 +261,106 @@ dc_parse_stream (FILE *fp, const char *filename)
++line_number;
if (fp)
- {
- if (getline (&input_line, &input_line_size, fp) <= 0)
- {
- free (input_line);
- break;
- }
- line = input_line;
- }
+ {
+ if (getline (&input_line, &input_line_size, fp) <= 0)
+ {
+ free (input_line);
+ break;
+ }
+ line = input_line;
+ }
else
- {
- if (next_G_line == G_line + sizeof G_line)
- break;
- line = next_G_line;
- next_G_line += strlen (next_G_line) + 1;
- }
+ {
+ if (next_G_line == G_line + sizeof G_line)
+ break;
+ line = next_G_line;
+ next_G_line += strlen (next_G_line) + 1;
+ }
parse_line (line, &keywd, &arg);
if (keywd == NULL)
- continue;
+ continue;
if (arg == NULL)
- {
- error (0, 0, _("%s:%lu: invalid line; missing second token"),
- filename, (unsigned long int) line_number);
- ok = false;
- free (keywd);
- continue;
- }
+ {
+ error (0, 0, _("%s:%lu: invalid line; missing second token"),
+ quotef (filename), (unsigned long int) line_number);
+ ok = false;
+ free (keywd);
+ continue;
+ }
unrecognized = false;
if (c_strcasecmp (keywd, "TERM") == 0)
- {
- if (STREQ (arg, term))
- state = ST_TERMSURE;
- else if (state != ST_TERMSURE)
- state = ST_TERMNO;
- }
+ {
+ if (fnmatch (arg, term, 0) == 0)
+ state = ST_TERMSURE;
+ else if (state != ST_TERMSURE)
+ state = ST_TERMNO;
+ }
else
- {
- if (state == ST_TERMSURE)
- state = ST_TERMYES; /* Another TERM can cancel */
-
- if (state != ST_TERMNO)
- {
- if (keywd[0] == '.')
- {
- APPEND_CHAR ('*');
- append_quoted (keywd);
- APPEND_CHAR ('=');
- append_quoted (arg);
- APPEND_CHAR (':');
- }
- else if (keywd[0] == '*')
- {
- append_quoted (keywd);
- APPEND_CHAR ('=');
- append_quoted (arg);
- APPEND_CHAR (':');
- }
- else if (c_strcasecmp (keywd, "OPTIONS") == 0
- || c_strcasecmp (keywd, "COLOR") == 0
- || c_strcasecmp (keywd, "EIGHTBIT") == 0)
- {
- /* Ignore. */
- }
- else
- {
- int i;
-
- for (i = 0; slack_codes[i] != NULL; ++i)
- if (c_strcasecmp (keywd, slack_codes[i]) == 0)
- break;
-
- if (slack_codes[i] != NULL)
- {
- APPEND_TWO_CHAR_STRING (ls_codes[i]);
- APPEND_CHAR ('=');
- append_quoted (arg);
- APPEND_CHAR (':');
- }
- else
- {
- unrecognized = true;
- }
- }
- }
- else
- {
- unrecognized = true;
- }
- }
+ {
+ if (state == ST_TERMSURE)
+ state = ST_TERMYES; /* Another TERM can cancel */
+
+ if (state != ST_TERMNO)
+ {
+ if (keywd[0] == '.')
+ {
+ APPEND_CHAR ('*');
+ append_quoted (keywd);
+ APPEND_CHAR ('=');
+ append_quoted (arg);
+ APPEND_CHAR (':');
+ }
+ else if (keywd[0] == '*')
+ {
+ append_quoted (keywd);
+ APPEND_CHAR ('=');
+ append_quoted (arg);
+ APPEND_CHAR (':');
+ }
+ else if (c_strcasecmp (keywd, "OPTIONS") == 0
+ || c_strcasecmp (keywd, "COLOR") == 0
+ || c_strcasecmp (keywd, "EIGHTBIT") == 0)
+ {
+ /* Ignore. */
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; slack_codes[i] != NULL; ++i)
+ if (c_strcasecmp (keywd, slack_codes[i]) == 0)
+ break;
+
+ if (slack_codes[i] != NULL)
+ {
+ APPEND_TWO_CHAR_STRING (ls_codes[i]);
+ APPEND_CHAR ('=');
+ append_quoted (arg);
+ APPEND_CHAR (':');
+ }
+ else
+ {
+ unrecognized = true;
+ }
+ }
+ }
+ else
+ {
+ unrecognized = true;
+ }
+ }
if (unrecognized && (state == ST_TERMSURE || state == ST_TERMYES))
- {
- error (0, 0, _("%s:%lu: unrecognized keyword %s"),
- (filename ? quote (filename) : _("<internal>")),
- (unsigned long int) line_number, keywd);
- ok = false;
- }
+ {
+ error (0, 0, _("%s:%lu: unrecognized keyword %s"),
+ (filename ? quotef (filename) : _("<internal>")),
+ (unsigned long int) line_number, keywd);
+ ok = false;
+ }
free (keywd);
free (arg);
@@ -380,7 +376,7 @@ dc_parse_file (const char *filename)
if (! STREQ (filename, "-") && freopen (filename, "r", stdin) == NULL)
{
- error (0, errno, "%s", filename);
+ error (0, errno, "%s", quotef (filename));
return false;
}
@@ -388,7 +384,7 @@ dc_parse_file (const char *filename)
if (fclose (stdin) != 0)
{
- error (0, errno, "%s", quote (filename));
+ error (0, errno, "%s", quotef (filename));
return false;
}
@@ -404,7 +400,7 @@ main (int argc, char **argv)
bool print_database = false;
initialize_main (&argc, &argv);
- program_name = argv[0];
+ set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
@@ -415,23 +411,23 @@ main (int argc, char **argv)
switch (optc)
{
case 'b': /* Bourne shell syntax. */
- syntax = SHELL_SYNTAX_BOURNE;
- break;
+ syntax = SHELL_SYNTAX_BOURNE;
+ break;
case 'c': /* C shell syntax. */
- syntax = SHELL_SYNTAX_C;
- break;
+ syntax = SHELL_SYNTAX_C;
+ break;
case 'p':
- print_database = true;
- break;
+ print_database = true;
+ break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
default:
- usage (EXIT_FAILURE);
+ usage (EXIT_FAILURE);
}
argc -= optind;
@@ -442,71 +438,71 @@ main (int argc, char **argv)
if (print_database && syntax != SHELL_SYNTAX_UNKNOWN)
{
error (0, 0,
- _("the options to output dircolors' internal database and\n\
-to select a shell syntax are mutually exclusive"));
+ _("the options to output dircolors' internal database and\n"
+ "to select a shell syntax are mutually exclusive"));
usage (EXIT_FAILURE);
}
- if (!print_database < argc)
+ if ((!print_database) < argc)
{
error (0, 0, _("extra operand %s"), quote (argv[!print_database]));
if (print_database)
- fprintf (stderr, "%s\n",
- _("File operands cannot be combined with "
- "--print-database (-p)."));
+ fprintf (stderr, "%s\n",
+ _("file operands cannot be combined with "
+ "--print-database (-p)"));
usage (EXIT_FAILURE);
}
if (print_database)
{
char const *p = G_line;
- while (p < G_line + sizeof G_line)
- {
- puts (p);
- p += strlen (p) + 1;
- }
+ while (p - G_line < sizeof G_line)
+ {
+ puts (p);
+ p += strlen (p) + 1;
+ }
}
else
{
/* If shell syntax was not explicitly specified, try to guess it. */
if (syntax == SHELL_SYNTAX_UNKNOWN)
- {
- syntax = guess_shell_syntax ();
- if (syntax == SHELL_SYNTAX_UNKNOWN)
- {
- error (EXIT_FAILURE, 0,
- _("no SHELL environment variable, and no shell type option given"));
- }
- }
+ {
+ syntax = guess_shell_syntax ();
+ if (syntax == SHELL_SYNTAX_UNKNOWN)
+ {
+ error (EXIT_FAILURE, 0,
+ _("no SHELL environment variable, and no shell type option given"));
+ }
+ }
obstack_init (&lsc_obstack);
if (argc == 0)
- ok = dc_parse_stream (NULL, NULL);
+ ok = dc_parse_stream (NULL, NULL);
else
- ok = dc_parse_file (argv[0]);
+ ok = dc_parse_file (argv[0]);
if (ok)
- {
- size_t len = obstack_object_size (&lsc_obstack);
- char *s = obstack_finish (&lsc_obstack);
- const char *prefix;
- const char *suffix;
-
- if (syntax == SHELL_SYNTAX_BOURNE)
- {
- prefix = "LS_COLORS='";
- suffix = "';\nexport LS_COLORS\n";
- }
- else
- {
- prefix = "setenv LS_COLORS '";
- suffix = "'\n";
- }
- fputs (prefix, stdout);
- fwrite (s, 1, len, stdout);
- fputs (suffix, stdout);
- }
+ {
+ size_t len = obstack_object_size (&lsc_obstack);
+ char *s = obstack_finish (&lsc_obstack);
+ const char *prefix;
+ const char *suffix;
+
+ if (syntax == SHELL_SYNTAX_BOURNE)
+ {
+ prefix = "LS_COLORS='";
+ suffix = "';\nexport LS_COLORS\n";
+ }
+ else
+ {
+ prefix = "setenv LS_COLORS '";
+ suffix = "'\n";
+ }
+ fputs (prefix, stdout);
+ fwrite (s, 1, len, stdout);
+ fputs (suffix, stdout);
+ }
}
- exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
+ return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}