diff options
author | Jim Meyering <jim@meyering.net> | 1996-06-22 22:02:37 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 1996-06-22 22:02:37 +0000 |
commit | 98b663a29b5e0982f1c2f4e134d70ce7a453f6af (patch) | |
tree | 615c2eecd39345945923ba1c0243decd02464831 | |
parent | e3c3d0b385565d3d71fee5c7d0d0b4fd69c7a149 (diff) | |
download | coreutils-98b663a29b5e0982f1c2f4e134d70ce7a453f6af.tar.xz |
Major overhaul. No longer read from /etc/DIR_COLORS or from ~/.dircolors.
Defaults are now compiled in. If you specify a file on the command line,
it is used instead of the compiled-in defaults.
-rw-r--r-- | src/dircolors.c | 278 |
1 files changed, 153 insertions, 125 deletions
diff --git a/src/dircolors.c b/src/dircolors.c index 8b197217d..a116d6070 100644 --- a/src/dircolors.c +++ b/src/dircolors.c @@ -1,7 +1,10 @@ /* FIXME: accept, but ignore EIGHTBIT option - FIXME: embed contents of default mapping file FIXME: add option to print that default mapping? + dircolors: use compiled-in defaults, output a string setting LS_COLORS + dircolors -p: output the compiled-in defaults + dircolors FILE: use FILE, output a string setting LS_COLORS + Only distinction necessary: Bourne vs. C-shell Use obstack to accumulate rhs of setenv */ @@ -32,18 +35,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <stdio.h> #include "system.h" +#include "getline.h" #include "long-options.h" #include "error.h" +#include "dircolors.h" char *xmalloc (); +char *basename (); -#define USER_FILE ".dir_colors" /* Versus user's home directory */ -#define SYSTEM_FILE "DIR_COLORS" /* System-wide file in directory SYSTEM_DIR - (defined on the cc command line). */ - -#define STRINGLEN 2048 /* Max length of a string */ +/* Nonzero if any of the files read were the standard input. */ +static int have_read_stdin; -enum modes { SHELLTYPE_BOURNE, SHELLTYPE_C, SHELLTYPE_UNKNOWN }; +enum Shell_syntax +{ + SHELL_SYNTAX_BOURNE, + SHELL_SYNTAX_C, + SHELL_SYNTAX_UNKNOWN +}; /* Parser needs these state variables. */ enum states { ST_TERMNO, ST_TERMYES, ST_TERMSURE, ST_GLOBAL }; @@ -93,28 +101,24 @@ Determine format of output:\n\ exit (status); } -/* If SHELL is csh or tcsh, assume C-shell. Else Bourne shell. */ +/* If the SHELL environment variable is set to `csh' or `tcsh,' + assume C-shell. Else Bourne shell. */ -static int -figure_mode (void) +static enum Shell_syntax +guess_shell_syntax (void) { - char *shell, *shellv; + char *shell; - shellv = getenv ("SHELL"); - if (shellv == NULL || *shellv == '\0') - return SHELLTYPE_UNKNOWN; + shell = getenv ("SHELL"); + if (shell == NULL || *shell == '\0') + return SHELL_SYNTAX_UNKNOWN; - shell = strrchr (shellv, '/'); - if (shell != NULL) - ++shell; - else - shell = shellv; + shell = basename (shell); - if (strcmp (shell, "csh") == 0 - || strcmp (shell, "tcsh") == 0) - return SHELLTYPE_C; + if (STREQ (shell, "csh") || STREQ (shell, "tcsh")) + return SHELL_SYNTAX_C; - return SHELLTYPE_BOURNE; + return SHELL_SYNTAX_BOURNE; } static void @@ -189,108 +193,50 @@ put_seq (const char *str, char follow) putchar (follow); /* The character that ends the sequence. */ } -int -main (int argc, char *argv[]) +/* FIXME: Accumulate settings in obstack and convert to string in *RESULT. */ + +static int +dc_parse_stream (FILE *fp, const char *filename, char **result) { - char *p; - int optc; - int mode = SHELLTYPE_UNKNOWN; - FILE *fp = NULL; - char *term; + size_t line_number = 0; + char *line = NULL; + size_t line_chars_allocated = 0; int state; + char *term; + int err = 0; - char line[STRINGLEN]; - char *keywd, *arg; - - char *input_file; - - program_name = argv[0]; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - parse_long_options (argc, argv, "dircolors", PACKAGE_VERSION, usage); - - while ((optc = getopt_long (argc, argv, "bc", long_options, NULL)) - != EOF) - switch (optc) - { - case 'b': /* Bourne shell mode. */ - mode = SHELLTYPE_BOURNE; - break; - - case 'c': /* Bourne shell mode. */ - mode = SHELLTYPE_C; - break; - - default: - usage (1); - } - - /* Use shell to determine mode, if not already done. */ - if (mode == SHELLTYPE_UNKNOWN) - { - mode = figure_mode (); - if (mode == SHELLTYPE_UNKNOWN) - { - error (1, 0, _("\ -no SHELL environment variable, and no shell type option given")); - } - } - - /* Open dir_colors file */ - if (optind == argc) - { - p = getenv ("HOME"); - if (p != NULL && *p != '\0') - { - /* Note: deliberate leak. It's not worth freeing this. */ - input_file = xmalloc (strlen (p) + 1 + strlen (USER_FILE) + 1); - stpcpy (stpcpy (stpcpy (input_file, p), "/"), USER_FILE); - fp = fopen (input_file, "r"); - } - - if (fp == NULL) - { - /* Note: deliberate leak. It's not worth freeing this. */ - input_file = xmalloc (strlen (SHAREDIR) + 1 - + strlen (USER_FILE) + 1); - stpcpy (stpcpy (stpcpy (input_file, SHAREDIR), "/"), - SYSTEM_FILE); - fp = fopen (input_file, "r"); - } - } - else - { - input_file = argv[optind]; - fp = fopen (input_file, "r"); - } - - if (fp == NULL) - error (1, errno, _("while opening input file `%s'"), input_file); + state = ST_GLOBAL; /* Get terminal type */ term = getenv ("TERM"); if (term == NULL || *term == '\0') term = "none"; - /* Write out common start */ - switch (mode) + while (1) { - case SHELLTYPE_C: - puts ("set noglob;\nsetenv LS_COLORS \':"); - break; + int line_length; + char *keywd, *arg; - case SHELLTYPE_BOURNE: - fputs ("LS_COLORS=\'", stdout); - break; - } + ++line_number; - state = ST_GLOBAL; + if (fp) + { + line_length = getline (&line, &line_chars_allocated, fp); + if (line_length <= 0) + { + if (line) + free (line); + break; + } + } + else + { + line = (char *) (G_line[line_number - 1]); + line_length = G_line_length[line_number - 1]; + if (line_number > G_N_LINES) + break; + } - /* FIXME: use getline */ - while (fgets (line, STRINGLEN, fp) != NULL) - { parse_line (&keywd, &arg, line); if (*keywd != '\0') { @@ -341,29 +287,111 @@ no SHELL environment variable, and no shell type option given")); put_seq (arg, ':'); } else - error (0, 0, _("Unknown keyword %s\n"), keywd); + { + error (0, 0, _("%s:%lu: unrecognized keyword %s\n"), + filename, (long unsigned) line_number, keywd); + err = 1; + } } } } } } - fclose (fp); + return err; +} + +static int +dc_parse_file (const char *filename, char **ls_color_string) +{ + FILE *fp; + int err; - /* Write it out. */ - switch (mode) + if (strcmp (filename, "-") == 0) + { + have_read_stdin = 1; + fp = stdin; + } + else { - case SHELLTYPE_BOURNE: - printf ("\';\nexport LS_COLORS\n"); - break; + /* OPENOPTS is a macro. It varies with the system. + Some systems distinguish between internal and + external text representations. */ - case SHELLTYPE_C: - printf ("\'\nunset noglob\n"); - break; + fp = fopen (filename, "r"); + if (fp == NULL) + { + error (0, errno, "%s", filename); + return 1; + } + } + + err = dc_parse_stream (fp, filename, ls_color_string); + if (err) + { + error (0, errno, "%s", filename); + if (fp != stdin) + fclose (fp); + return 1; + } - default: - abort (); + if (fp != stdin && fclose (fp) == EOF) + { + error (0, errno, "%s", filename); + return 1; } - exit (0); + return 0; +} + +int +main (int argc, char *argv[]) +{ + int err; + int optc; + enum Shell_syntax syntax = SHELL_SYNTAX_UNKNOWN; + char *ls_color_string; + char *file; + + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + parse_long_options (argc, argv, "dircolors", PACKAGE_VERSION, usage); + + while ((optc = getopt_long (argc, argv, "bc", long_options, NULL)) + != EOF) + switch (optc) + { + case 'b': /* Bourne shell syntax. */ + syntax = SHELL_SYNTAX_BOURNE; + break; + + case 'c': /* C-shell syntax. */ + syntax = SHELL_SYNTAX_C; + break; + + default: + usage (1); + } + + /* Use shell to determine mode, if not already done. */ + if (syntax == SHELL_SYNTAX_UNKNOWN) + { + syntax = guess_shell_syntax (); + if (syntax == SHELL_SYNTAX_UNKNOWN) + { + error (1, 0, + _("no SHELL environment variable, and no shell type option given")); + } + } + + file = argv[optind]; + err = dc_parse_file (file, &ls_color_string); + + if (have_read_stdin && fclose (stdin) == EOF) + error (EXIT_FAILURE, errno, _("standard input")); + + exit (err == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } |