home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 6 File
/
06-File.zip
/
colorls2.zip
/
color-ls.dif
next >
Wrap
Text File
|
1996-03-04
|
46KB
|
1,634 lines
*** /tmp/fu/man/ls.1 Tue Apr 26 22:08:54 1994
--- man/ls.1 Thu Feb 29 03:36:20 1996
***************
*** 1,9 ****
! .TH LS 1L "GNU File Utilities" "FSF" \" -*- nroff -*-
.SH NAME
ls, dir, vdir \- list contents of directories
.SH SYNOPSIS
.B ls
! [\-abcdfgiklmnpqrstuxABCFGLNQRSUX1] [\-w cols] [\-T cols] [\-I pattern]
[\-\-all] [\-\-escape] [\-\-directory] [\-\-inode] [\-\-kilobytes]
[\-\-numeric-uid-gid] [--no-group] [\-\-hide-control-chars] [\-\-reverse]
[\-\-size] [\-\-width=cols] [\-\-tabsize=cols] [\-\-almost-all]
--- 1,9 ----
! .TH LS 1L "GNU File Utilities" "FSF" \" -*- nroff -*- "
.SH NAME
ls, dir, vdir \- list contents of directories
.SH SYNOPSIS
.B ls
! [\-abcdefgiklmnopqrstuxABCFGLNQRSUX178] [\-w cols] [\-T cols] [\-I pattern]
[\-\-all] [\-\-escape] [\-\-directory] [\-\-inode] [\-\-kilobytes]
[\-\-numeric-uid-gid] [--no-group] [\-\-hide-control-chars] [\-\-reverse]
[\-\-size] [\-\-width=cols] [\-\-tabsize=cols] [\-\-almost-all]
***************
*** 11,21 ****
[\-\-ignore=pattern] [\-\-dereference] [\-\-literal] [\-\-quote-name]
[\-\-recursive] [\-\-sort={none,time,size,extension}]
[\-\-format={long,verbose,commas,across,vertical,single-column}]
! [\-\-time={atime,access,use,ctime,status}] [\-\-help] [\-\-version] [name...]
.SH DESCRIPTION
This manual page
documents the GNU version of
! .BR ls .
.B dir
and
.B vdir
--- 11,24 ----
[\-\-ignore=pattern] [\-\-dereference] [\-\-literal] [\-\-quote-name]
[\-\-recursive] [\-\-sort={none,time,size,extension}]
[\-\-format={long,verbose,commas,across,vertical,single-column}]
! [\-\-time={atime,access,use,ctime,status}]
! [\-\-color[={yes,no,tty}]] [\-\-colour[={yes,no,tty}]]
! [\-\-unix] [\-\-help] [\-\-version] [name...]
.SH DESCRIPTION
This manual page
documents the GNU version of
! .BR ls ,
! with color extensions.
.B dir
and
.B vdir
***************
*** 49,54 ****
--- 52,61 ----
.I "\-d, \-\-directory"
List directories like other files, rather than listing their contents.
.TP
+ .I "\-e, \-\-full-time"
+ List times in full, rather than using the standard abbreviation
+ heuristics.
+ .TP
.I "\-f"
Do not sort directory contents; list them in whatever order they are
stored on the disk.
***************
*** 58,71 ****
.I \-U
and disabling
.I \-l,
.I \-s,
and
.I \-t.
.TP
- .I "\-\-full-time"
- List times in full, rather than using the standard abbreviation
- heuristics.
- .TP
.I \-g
Ignored; for Unix compatibility.
.TP
--- 65,75 ----
.I \-U
and disabling
.I \-l,
+ .I \-o,
.I \-s,
and
.I \-t.
.TP
.I \-g
Ignored; for Unix compatibility.
.TP
***************
*** 74,80 ****
.TP
.I "\-k, \-\-kilobytes"
If file sizes are being listed, print them in kilobytes. This
! overrides the environment variable POSIXLY_CORRECT.
.TP
.I "\-l, \-\-format=long, \-\-format=verbose"
In addition to the name of each file, print the file type,
--- 78,85 ----
.TP
.I "\-k, \-\-kilobytes"
If file sizes are being listed, print them in kilobytes. This
! overrides the environment variable
! .BR POSIXLY_CORRECT .
.TP
.I "\-l, \-\-format=long, \-\-format=verbose"
In addition to the name of each file, print the file type,
***************
*** 91,96 ****
--- 96,109 ----
.I "\-n, \-\-numeric-uid-gid"
List the numeric UID and GID instead of the names.
.TP
+ .I "\-o, \-\-color, \-\-colour, \-\-color=yes, \-\-colour=yes"
+ Colorize the names of files depending on the type of file.
+ See `DISPLAY COLORIZATION' below. Note that
+ .I \-o
+ unlike
+ .I \-\-color
+ is a toggle.
+ .TP
.I \-p
Append a character to each file name indicating the file type.
.TP
***************
*** 102,108 ****
.TP
.I "\-s, \-\-size"
Print the size of each file in 1K blocks to the left of the file name.
! If the environment variable POSIXLY_CORRECT is set, 512-byte blocks
are used instead.
.TP
.I "\-t, \-\-sort=time"
--- 115,123 ----
.TP
.I "\-s, \-\-size"
Print the size of each file in 1K blocks to the left of the file name.
! If the environment variable
! .B POSIXLY_CORRECT
! is set, 512-byte blocks
are used instead.
.TP
.I "\-t, \-\-sort=time"
***************
*** 190,196 ****
.I "\-T, \-\-tabsize cols"
Assume that each tabstop is
.I cols
! columns wide. The default is 8.
.TP
.I "\-I, \-\-ignore pattern"
Do not list files whose names match the shell pattern
--- 205,214 ----
.I "\-T, \-\-tabsize cols"
Assume that each tabstop is
.I cols
! columns wide. The default is 8, or whatever the
! .B TABSIZE
! environment variable says. Setting the tabsize to 0 disables
! the use of tab characters completely.
.TP
.I "\-I, \-\-ignore pattern"
Do not list files whose names match the shell pattern
***************
*** 199,209 ****
--- 217,356 ----
initial `.' in a filename does not match a wildcard at the start of
.I pattern.
.TP
+ .I "\-\-color=tty, \-\-colour=tty"
+ Same as
+ .I \-o
+ but only if standard output is a terminal. This is very useful for
+ shell scripts and command aliases, especially if your favorite pager
+ does not support color control codes.
+ .TP
+ .I "\-\-color=no, \-\-colour=no"
+ Disables colorization. This is the default. Provided to override a
+ previous color option.
+ .TP
.I "\-\-help"
Print a usage message on standard output and exit successfully.
.TP
.I "\-\-version"
Print version information on standard output then exit successfully.
+ .TP
+ .I "\-\-unix"
+ Print plain UNIX long format instead of OS/2 format.
+ .SS DISPLAY COLORIZATION
+ When using the
+ .I "\-o"
+ or
+ .I "\-\-color"
+ options, this version of
+ .B ls
+ will colorize the file names printed according to the name and type of
+ file. By default, this colorization is by type only, and the codes
+ used are ISO 6429 (ANSI) compliant.
+ .PP
+ You can override the default colors by defining the environment
+ variable
+ .B LS_COLORS
+ (or
+ .BR LS_COLOURS ).
+ The format of this variable is reminicent of the termcap(5) file
+ format; a colon-separated list of expressions of the form "xx=string",
+ where "xx" is a two-character variable name. The variables with their
+ associated defaults are:
+ .sp
+ .RS +.2i
+ .ta 1.0i 2.5i
+ .nf
+ \fBno\fR 0 Normal (non-filename) text
+ \fBfi\fR 1 Regular file
+ \fBdi\fR 32;1 Directory
+ .\"" \fBln\fR 36 Symbolic link
+ .\"" \fBpi\fR 31 Named pipe (FIFO)
+ .\"" \fBso\fR 33 Socket
+ .\"" \fBbd\fR 44;37 Block device
+ .\"" \fBcd\fR 44;37 Character device
+ \fBex\fR 35;1 Executable file
+ \fBsy\fR 31;1 System file
+ \fBro\fR 33;1 Read-only file
+ \fBhi\fR 44;37;1 Hidden file
+ .\"" \fBmi\fR (none) Missing file (defaults to fi)
+ .\"" \fBor\fR (none) Orphanned symbolic link (defaults to ln)
+ \fBlc\fR \ee[ Left code
+ \fBrc\fR m Right code
+ \fBec\fR (none) End code (replaces lc+no+rc)
+ .fi
+ .RE
+ .sp
+ You only need to include the variables you want to change from the
+ default.
+ .PP
+ File names can also be colorized based on filename extension. This is
+ specified in the LS_COLORS variable using the syntax "*ext=string".
+ For example, using ISO 6429 codes, to color all C-language source
+ files blue you would specify "*.c=34". This would color all files
+ ending in .c in blue (34) color.
+ .PP
+ Control characters can be written either in C-style \e-escaped
+ notation, or in
+ .BR stty -like
+ ^-notation. The C-style notation adds \ee for Escape, \e_ for a
+ normal space characer, and \e? for Delete. In addition, the \e escape
+ character can be used to override the default interpretation of \e, ^,
+ : and =.
+ .PP
+ Each file will be written as <lc> <color\ code> <rc> <filename> <ec>.
+ If the <ec> code is undefined, the sequence <lc> <no> <rc> will be
+ used instead. This is generally more convenient to use, but less
+ general. The left, right and end codes are provided so you don't have
+ to type common parts over and over again and to support weird
+ terminals; you will generally not need to change them at all unless
+ your terminal does not use ISO 6429 color sequences but a different
+ system.
+ .PP
+ If your terminal does use ISO 6429 color codes, you can compose the type
+ codes (i.e. all except the
+ .BR lc ,
+ .BR rc ,
+ and
+ .B ec
+ codes) from numerical commands separated by semicolons. The most
+ common commands are:
+ .sp
+ .RS +.2i
+ .ta 1.0i
+ .nf
+ 0 to restore default color
+ 1 for brighter colors
+ 4 for underlined text
+ 5 for flashing text
+ 30 for black foreground
+ 31 for red foreground
+ 32 for green foreground
+ 33 for yellow (or brown) foreground
+ 34 for blue foreground
+ 35 for purple foreground
+ 36 for cyan foreground
+ 37 for white (or gray) foreground
+ 40 for black background
+ 41 for red background
+ 42 for green background
+ 43 for yellow (or brown) background
+ 44 for blue background
+ 45 for purple background
+ 46 for cyan background
+ 47 for white (or gray) background
+ .fi
+ .RE
+ .sp
+ Not all commands will work on all systems or display devices.
+ .PP
+ A few terminal programs do not recognize the default end code
+ properly. If all text gets colorized after you do a directory
+ listing, try changing the
+ .B no
+ and
+ .B fi
+ codes from 0 to the numerical codes for your standard fore- and
+ background colors.
.SH BUGS
On BSD systems, the
.I \-s
***************
*** 214,216 ****
--- 361,374 ----
HP-UX
.B ls
program.
+ .PP
+ Character set selection should be more system independent.
+ .PP
+ Using the colorization options disables the use of the tab character for
+ column spacing unless the
+ .I \-T
+ option is used; apparently some systems do not like tabs and color
+ codes in conjunction.
+ .PP
+ If there was a single standard for the English language it would not
+ be necessary to support redundant spellings.
*** /tmp/fu/src/ls.c Fri Dec 16 22:13:16 1994
--- src/ls.c Mon Mar 04 00:00:48 1996
***************
*** 15,37 ****
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
! /* If the macro MULTI_COL is defined,
the multi-column format is the default regardless
of the type of output device.
This is for the `dir' program.
! If the macro LONG_FORMAT is defined,
the long format is the default regardless of the
type of output device.
This is for the `vdir' program.
! If neither is defined,
the output format depends on whether the output
device is a terminal.
! This is for the `ls' program. */
/* Written by Richard Stallman and David MacKenzie. */
#ifdef _AIX
#pragma alloca
#endif
--- 15,48 ----
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
! /* If the first character after the last slash in argv[0] is 'd',
the multi-column format is the default regardless
of the type of output device.
This is for the `dir' program.
! If the first character after the last slash in argv[0] is 'v',
the long format is the default regardless of the
type of output device.
This is for the `vdir' program.
! If the first character after the last slash in argv[0] is 'l',
the output format depends on whether the output
device is a terminal.
! This is for the `ls' program.
!
! If it is anything else, the default will depend on if this program
! is linked with ls-ls.c, ls-dir.c or ls-vdir.c.
!
! This behaviour can be overridden by defining NO_NAME_DEPENDENCE
! at compile time. */
/* Written by Richard Stallman and David MacKenzie. */
+ /* Colour and 8-bit support by Peter Anvin <hpa@nwu.edu> and
+ Dennis Flaherty <dennisf@denix.elk.miles.com> based on original
+ patches by Greg Lee <lee@uhunix.uhcc.hawaii.edu>. See file
+ color-ls.log for revision history. */
+
#ifdef _AIX
#pragma alloca
#endif
***************
*** 114,119 ****
--- 125,131 ----
static int compare_extension ();
static int rev_cmp_extension ();
static int decode_switches ();
+ static void parse_ls_color ();
static int file_interesting ();
static int gobble_file ();
static int is_not_dot_or_dotdot ();
***************
*** 130,137 ****
--- 142,152 ----
static void print_horizontal ();
static void print_long_format ();
static void print_many_per_line ();
+ static void print_fancy_name ();
static void print_name_with_quoting ();
static void print_type_indicator ();
+ static void print_color_indicator ();
+ static void put_indicator ();
static void print_with_commas ();
static void queue_directory ();
static void sort_files ();
***************
*** 162,167 ****
--- 177,186 ----
/* For symbolic link and long listing, st_mode of file linked to, otherwise
zero. */
unsigned int linkmode;
+
+ /* For symbolic link and color printing, 1 if linked-to file exits,
+ otherwise 0 */
+ int linkok;
enum filetype filetype;
};
***************
*** 214,220 ****
one_per_line for just names, one per line.
many_per_line for just names, many per line, sorted vertically.
horizontal for just names, many per line, sorted horizontally.
! with_commas for just names, many per line, separated by commas.
-l, -1, -C, -x and -m control this parameter. */
--- 233,239 ----
one_per_line for just names, one per line.
many_per_line for just names, many per line, sorted vertically.
horizontal for just names, many per line, sorted horizontally.
! with_commas for just names, many per line, separated by commas
-l, -1, -C, -x and -m control this parameter. */
***************
*** 240,246 ****
static enum time_type time_type;
! /* print the full time, otherwise the standard unix heuristics. */
int full_time;
--- 259,265 ----
static enum time_type time_type;
! /* print the full time, otherwise the standard unix heuristics. -e */
int full_time;
***************
*** 305,310 ****
--- 324,439 ----
static enum indicator_style indicator_style;
+ /* Nonzero means use colors to mark types. Also define the different
+ colors as well as the stuff for the LS_COLORS environment variable.
+ The LS_COLORS variable is now in a termcap-like format. -o */
+
+ int print_with_color;
+
+ enum color_type
+ {
+ color_no, /* 0: default or --color=no */
+ color_yes, /* 1: -o or --color=yes */
+ color_if_tty /* 2: --color=tty */
+ };
+
+ /* Note that color_no and color_yes equals boolean values; they will
+ be assigned to print_with_color which is a boolean variable */
+
+ #ifndef OS2
+ enum indicator_no
+ { C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
+ C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC };
+
+ char *indicator_name[]=
+ {
+ "lc","rc","ec","no","fi","di","ln","pi","so","bd","cd","mi","or",
+ "ex",NULL
+ };
+ #else
+ enum indicator_no
+ { C_LEFT, C_RIGHT, C_END, C_NORM, C_FILE, C_DIR, C_LINK, C_FIFO, C_SOCK,
+ C_BLK, C_CHR, C_MISSING, C_ORPHAN, C_EXEC, C_SYSTEM, C_RDONLY, C_HIDDEN, };
+
+ char *indicator_name[]=
+ {
+ "lc","rc","ec","no","fi","di","ln","pi","so","bd","cd","mi","or",
+ "ex","sy","ro","hi",NULL
+ };
+ #define S_IFRDONLY 01000000
+ #define S_IFHIDDEN 02000000
+ #define S_IFSYSTEM 04000000
+ #define S_ISRDONLY(mode) (((mode) & S_IFRDONLY) == S_IFRDONLY)
+ #define S_ISHIDDEN(mode) (((mode) & S_IFHIDDEN) == S_IFHIDDEN)
+ #define S_ISSYSTEM(mode) (((mode) & S_IFSYSTEM) == S_IFSYSTEM)
+ static __inline void os2_modify_stat( struct stat* buf ) {
+ buf->st_mode |= (buf->st_attr&7)<<18;
+ return;
+ }
+ #endif
+
+ /* Null is a valid character in a color indicator (think about Epson
+ printers, for example) so we have to use a length/buffer string
+ type. */
+
+ struct bin_str
+ {
+ unsigned int len; /* Number of bytes */
+ char *string; /* Pointer to the same */
+ };
+
+ struct bin_str color_indicator[] =
+ {
+ { 2, "\033[" }, /* lc: Left of color sequence */
+ { 1, "m" }, /* rc: Right of color sequence */
+ { 0, NULL }, /* ec: End color (replaces lc+no+rc) */
+ { 1, "0" }, /* no: Normal */
+ #ifndef OS2
+ { 1, "0" }, /* fi: File: default */
+ { 2, "32" }, /* di: Directory: green */
+ { 2, "36" }, /* ln: Symlink: cyan */
+ { 2, "31" }, /* pi: Pipe: red */
+ { 2, "33" }, /* so: Socket: yellow/brown */
+ { 5, "44;37" }, /* bd: Block device: white on blue */
+ { 5, "44;37" }, /* cd: Char device: white on blue */
+ { 0, NULL }, /* mi: Missing file: undefined */
+ { 0, NULL }, /* or: Orphanned symlink: undefined */
+ { 2, "35" } /* ex: Executable: purple */
+ #else
+ { 1, "1" }, /* fi: File: default+ */
+ { 4, "32;1" }, /* di: Directory: green+ */
+ { 2, "36" }, /* ln: Symlink: cyan */
+ { 2, "31" }, /* pi: Pipe: red */
+ { 2, "33" }, /* so: Socket: yellow/brown */
+ { 5, "44;37" }, /* bd: Block device: white on blue */
+ { 5, "44;37" }, /* cd: Char device: white on blue */
+ { 0, NULL }, /* mi: Missing file: undefined */
+ { 0, NULL }, /* or: Orphanned symlink: undefined */
+ { 4, "35;1" }, /* ex: Executable: purple+ */
+ { 4, "31;1" }, /* sy: System: red+ */
+ { 4, "33;1" }, /* ro: Read-only: yellow+ */
+ { 7, "44;37;1" }, /* hi: Hidden: white on blue + */
+ #endif
+ };
+
+ struct col_ext_type
+ {
+ struct bin_str ext; /* The extension we're looking for */
+ struct bin_str seq; /* The sequence to output when we do */
+ struct col_ext_type *next; /* Next in list */
+ };
+
+ struct col_ext_type *col_ext_list = NULL;
+ char *color_buf; /* Buffer for color sequences */
+
+ /* Nonzero means print using ISO 8859 characters. The default is specified
+ here as well. -8 enables, -7 disables. */
+
+ int print_iso8859;
+ #ifndef DEFAULT_ISO8859
+ #define DEFAULT_ISO8859 1
+ #endif
+
/* Nonzero means mention the inode number of each file. -i */
static int print_inode;
***************
*** 407,413 ****
{"escape", no_argument, 0, 'b'},
{"directory", no_argument, 0, 'd'},
{"dired", no_argument, 0, 'D'},
! {"full-time", no_argument, &full_time, 1},
{"inode", no_argument, 0, 'i'},
{"kilobytes", no_argument, 0, 'k'},
{"numeric-uid-gid", no_argument, 0, 'n'},
--- 536,542 ----
{"escape", no_argument, 0, 'b'},
{"directory", no_argument, 0, 'd'},
{"dired", no_argument, 0, 'D'},
! {"full-time", no_argument, 0, 'e'},
{"inode", no_argument, 0, 'i'},
{"kilobytes", no_argument, 0, 'k'},
{"numeric-uid-gid", no_argument, 0, 'n'},
***************
*** 434,439 ****
--- 563,572 ----
#endif
{"help", no_argument, &show_help, 1},
{"version", no_argument, &show_version, 1},
+ {"color", optional_argument, 0, 13},
+ {"colour", optional_argument, 0, 13},
+ {"7bit", no_argument, 0, '7'},
+ {"8bit", no_argument, 0, '8'},
{0, 0, 0, 0}
};
***************
*** 512,517 ****
--- 645,662 ----
time_atime, time_atime, time_atime, time_ctime, time_ctime
};
+ static char const* color_args[] =
+ {
+ /* Note: "no" is a prefix of "none" so we don't include it */
+ /* force and none are for compatibility with another color-ls version */
+ "yes", "force", "none", "tty", "if-tty"
+ };
+
+ static enum color_type const color_types[] =
+ {
+ color_yes, color_yes, color_no, color_if_tty, color_if_tty
+ };
+
/* Write to standard output the string PREFIX followed by a space-separated
list of the integers stored in OS all on one line. */
***************
*** 551,567 ****
if (show_version)
{
! printf ("%s\n", version_string);
exit (0);
}
if (show_help)
usage (0);
format_needs_stat = sort_type == sort_time || sort_type == sort_size
|| format == long_format
|| trace_links || trace_dirs || indicator_style != none
! || print_block_size || print_inode;
if (dired && format == long_format)
{
--- 696,715 ----
if (show_version)
{
! printf ("%s with color-ls patch %s\n", version_string, color_ls_version);
exit (0);
}
if (show_help)
usage (0);
+ if ( print_with_color )
+ parse_ls_color();
+
format_needs_stat = sort_type == sort_time || sort_type == sort_size
|| format == long_format
|| trace_links || trace_dirs || indicator_style != none
! || print_block_size || print_inode || print_with_color;
if (dired && format == long_format)
{
***************
*** 653,658 ****
--- 801,819 ----
dired_dump_obstack ("//SUBDIRED//", &subdired_obstack);
}
+ if (print_with_color)
+ {
+ struct col_ext_type *ext;
+
+ free(color_buf);
+ while ( col_ext_list )
+ {
+ ext = col_ext_list;
+ col_ext_list = col_ext_list->next;
+ free(ext);
+ }
+ }
+
exit (exit_status);
}
***************
*** 673,678 ****
--- 834,893 ----
/* initialize all switches to default settings */
+ /* program_name is advertised as being the program name without
+ any leading path, but that doesn't seem to be the case. Get the
+ first character of the actual program name. */
+
+ #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
+ p = strrchr(program_name,'/');
+ #else
+ {
+ /* Lame version of strrchr() for lame systems */
+
+ register char *q;
+
+ p = NULL;
+ for ( q = program_name ; *q ; q++ )
+ {
+ if ( *q == '/' )
+ p = q;
+ }
+ }
+ #endif
+
+ #ifndef NO_NAME_DEPENDENCE
+ if ( p )
+ p++; /* Get character after last / */
+ else
+ p = program_name; /* Get first character */
+
+ switch(*p)
+ {
+ case 'D':
+ case 'd':
+ /* This is for the 'dir' program. */
+ ls_mode = LS_MULTI_COL;
+ break;
+
+ case 'V':
+ case 'v':
+ /* This is for the 'vdir' program. */
+ ls_mode = LS_LONG_FORMAT;
+ break;
+
+ case 'L':
+ case 'l':
+ /* This is for the `ls' program. */
+ ls_mode = LS_LS;
+ break;
+
+ default:
+ /* Use default, depending on whenether linked with ls-ls.o,
+ ls-dir.o or ls-vdir.o */
+ break;
+ }
+ #endif
+
switch (ls_mode)
{
case LS_MULTI_COL:
***************
*** 721,726 ****
--- 936,943 ----
really_all_files = 0;
ignore_patterns = 0;
quote_as_string = 0;
+ print_with_color = 0;
+ print_iso8859 = DEFAULT_ISO8859;
p = getenv ("COLUMNS");
line_length = p ? atoi (p) : 80;
***************
*** 737,743 ****
p = getenv ("TABSIZE");
tabsize = p ? atoi (p) : 8;
! while ((c = getopt_long (argc, argv, "abcdfgiklmnpqrstuw:xABCDFGI:LNQRST:UX1?h",
long_options, (int *) 0)) != EOF)
{
switch (c)
--- 954,961 ----
p = getenv ("TABSIZE");
tabsize = p ? atoi (p) : 8;
! if ( tabsize == 0 ) tabsize = line_length;
! while ((c = getopt_long (argc, argv, "abcdefgiklmnopqrstuw:xABCDFGI:LNQRST:UX178?h",
long_options, (int *) 0)) != EOF)
{
switch (c)
***************
*** 763,770 ****
immediate_dirs = 1;
break;
case 'f':
! /* Same as enabling -a -U and disabling -l -s. */
all_files = 1;
really_all_files = 1;
sort_type = sort_none;
--- 981,992 ----
immediate_dirs = 1;
break;
+ case 'e':
+ full_time = 1;
+ break;
+
case 'f':
! /* Same as enabling -a -U and disabling -l -s -o. */
all_files = 1;
really_all_files = 1;
sort_type = sort_none;
***************
*** 772,777 ****
--- 994,1000 ----
if (format == long_format)
format = (isatty (1) ? many_per_line : one_per_line);
print_block_size = 0; /* disable -s */
+ print_with_color = 0; /* disable -o */
break;
case 'g':
***************
*** 798,803 ****
--- 1021,1034 ----
numeric_users = 1;
break;
+ case 'o':
+ print_with_color = !print_with_color;
+
+ if ( print_with_color )
+ tabsize = line_length; /* Some systems don't like tabs and
+ color codes in combination */
+ break;
+
case 'p':
indicator_style = not_programs;
break;
***************
*** 887,894 ****
case 'T':
tabsize = atoi (optarg);
! if (tabsize < 1)
error (1, 0, "invalid tab size: %s", optarg);
break;
case 'U':
--- 1118,1127 ----
case 'T':
tabsize = atoi (optarg);
! if (tabsize < 0)
error (1, 0, "invalid tab size: %s", optarg);
+ else if (tabsize == 0)
+ tabsize = line_length;
break;
case 'U':
***************
*** 903,909 ****
format = one_per_line;
break;
! case 10: /* +sort */
i = argmatch (optarg, sort_args);
if (i < 0)
{
--- 1136,1150 ----
format = one_per_line;
break;
! case '7':
! print_iso8859 = 0;
! break;
!
! case '8':
! print_iso8859 = 1;
! break;
!
! case 10: /* --sort */
i = argmatch (optarg, sort_args);
if (i < 0)
{
***************
*** 913,919 ****
sort_type = sort_types[i];
break;
! case 11: /* +time */
i = argmatch (optarg, time_args);
if (i < 0)
{
--- 1154,1160 ----
sort_type = sort_types[i];
break;
! case 11: /* --time */
i = argmatch (optarg, time_args);
if (i < 0)
{
***************
*** 923,929 ****
time_type = time_types[i];
break;
! case 12: /* +format */
i = argmatch (optarg, format_args);
if (i < 0)
{
--- 1164,1170 ----
time_type = time_types[i];
break;
! case 12: /* --format */
i = argmatch (optarg, format_args);
if (i < 0)
{
***************
*** 933,938 ****
--- 1174,1203 ----
format = formats[i];
break;
+ case 13: /* --color */
+ if (optarg)
+ {
+ i = argmatch(optarg, color_args);
+ if (i < 0)
+ {
+ invalid_arg("colorization criterion", optarg, i);
+ usage(1);
+ }
+ i = color_types[i];
+ }
+ else
+ i = color_yes; /* Only --color -> --color=yes */
+
+ if ( i == color_if_tty )
+ print_with_color = isatty(1) ? 1 : 0;
+ else
+ print_with_color = i;
+
+ if ( print_with_color )
+ tabsize = line_length; /* Some systems don't like tabs and
+ color codes in combination */
+ break;
+
default:
usage (0);
}
***************
*** 941,946 ****
--- 1206,1537 ----
return optind;
}
+ /* Parse the LS_COLORS/LS_COLOURS variable */
+
+ static void
+ parse_ls_color ()
+ {
+ char *p; /* Pointer to character being parsed */
+ char *whichvar; /* LS_COLORS or LS_COLOURS? */
+ char *buf; /* color_buf buffer pointer */
+ int state; /* State of parser */
+ int ind_no; /* Indicator number */
+ char label[3] = "??"; /* Indicator label */
+ struct col_ext_type *ext; /* Extension we are working on */
+ struct col_ext_type *ext2; /* Extra pointer */
+
+ if ( (p = getenv(whichvar = "LS_COLORS")) ||
+ (p = getenv(whichvar = "LS_COLOURS")) )
+ {
+ buf = color_buf = xmalloc(strlen(p));
+ /* This is an overly conservative estimate, but any possible
+ LS_COLORS string will *not* generate a color_buf longer than
+ itself, so it is a safe way of allocating a buffer in
+ advance. */
+
+ state = 1;
+ while ( state > 0 )
+ {
+ switch(state)
+ {
+ case 1: /* First label character */
+ switch ( *p )
+ {
+ case ':':
+ p++;
+ break;
+
+ case '*':
+ /* Allocate new extension block and add to head
+ of linked list (this way a later definition will
+ override an earlier one, which can be useful for
+ having terminal-specific defs override global) */
+
+ ext = (struct col_ext_type *)
+ xmalloc(sizeof(struct col_ext_type));
+ ext->next = col_ext_list;
+ col_ext_list = ext;
+
+ p++;
+ ext->ext.string = buf;
+
+ state = (ext->ext.len =
+ get_funky_string(&buf,&p,1)) < 0 ? -1 : 4;
+ break;
+
+ case '\0':
+ state = 0; /* Done! */
+ break;
+
+ default: /* Assume it is file type label */
+ label[0] = *(p++);
+ state = 2;
+ break;
+ }
+ break;
+
+ case 2: /* Second label character */
+ if ( *p )
+ {
+ label[1] = *(p++);
+ state = 3;
+ }
+ else
+ state = -1; /* Error */
+ break;
+
+ case 3: /* Equal sign after indicator label */
+ state = -1; /* Assume failure... */
+ if ( *(p++) == '=' ) /* It *should* be... */
+ {
+ for ( ind_no = 0 ; indicator_name[ind_no] != NULL ;
+ ind_no++ )
+ {
+ if ( strcmp(label,indicator_name[ind_no]) == 0 )
+ {
+ color_indicator[ind_no].string = buf;
+ state = (color_indicator[ind_no].len =
+ get_funky_string(&buf,&p,0)) < 0 ?
+ -1 : 1;
+ break;
+ }
+ }
+ if ( state == -1 )
+ fprintf(stderr, "Unknown prefix: %s\n", label);
+ }
+ break;
+
+ case 4: /* Equal sign after *.ext */
+ if ( *(p++) == '=' )
+ {
+ ext->seq.string = buf;
+ state = (ext->seq.len =
+ get_funky_string(&buf,&p,0)) < 0 ?
+ -1 : 1;
+ }
+ else
+ state = -1;
+ break;
+ }
+ }
+
+ if ( state < 0 )
+ {
+ fprintf(stderr, "Bad %s variable\n", whichvar);
+ free(color_buf);
+ for ( ext = col_ext_list ; ext != NULL ; )
+ {
+ ext2 = ext;
+ ext = ext->next;
+ free (ext2);
+ }
+ print_with_color = 0;
+ }
+ }
+ }
+
+ /* Parse a string as part of the LS_COLO(U)RS variable; this may involve
+ decoding all kinds of escape characters. If equals_end is set an
+ unescaped equal sign ends the string, otherwise only a : or \0
+ does. Returns the number of characters output, or -1 on failure.
+
+ The resulting string is *not* null-terminated, but may contain
+ embedded nulls.
+
+ Note that both dest and src are char **; on return they point to
+ the first free byte after the array and the character that ended
+ the input string, respectively. */
+
+ int
+ get_funky_string (dest, src, equals_end)
+ char **dest;
+ char **src;
+ int equals_end;
+ {
+ int num; /* For numerical codes */
+ int count; /* Something to count with */
+ enum { st_gnd, st_backslash, st_octal, st_hex, st_caret,
+ st_end, st_error } state;
+ char *p, *q;
+
+ p = *src; q = *dest; /* We don't want to double-indirect
+ the whole darn time */
+
+ count = 0; /* No characters counted in yet */
+
+ state = st_gnd; /* Start in ground state */
+ while ( state < st_end )
+ {
+ switch ( state )
+ {
+ case st_gnd: /* Ground state (no escapes) */
+ switch ( *p )
+ {
+ case ':':
+ case '\0':
+ state = st_end; /* End of string */
+ break;
+ case '\\':
+ state = st_backslash; /* Backslash scape sequence */
+ p++;
+ break;
+ case '^':
+ state = st_caret; /* Caret escape */
+ p++;
+ break;
+ case '=':
+ if ( equals_end )
+ {
+ state = st_end; /* End */
+ break;
+ }
+ /* else fall through */
+ default:
+ *(q++) = *(p++);
+ count++;
+ break;
+ }
+ break;
+
+ case st_backslash: /* Backslash escaped character */
+ switch ( *p )
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ state = st_octal; /* Octal sequence */
+ num = *p - '0';
+ break;
+ case 'x':
+ case 'X':
+ state = st_hex; /* Hex sequence */
+ num = 0;
+ break;
+ case 'a': /* Bell */
+ num = 7; /* Not all C compilers know what \a means */
+ break;
+ case 'b': /* Backspace */
+ num = '\b';
+ break;
+ case 'e': /* Escape */
+ num = 27;
+ break;
+ case 'f': /* Form feed */
+ num = '\f';
+ break;
+ case 'n': /* Newline */
+ num = '\n';
+ break;
+ case 'r': /* Carriage return */
+ num = '\r';
+ break;
+ case 't': /* Tab */
+ num = '\t';
+ break;
+ case 'v': /* Vtab */
+ num = '\v';
+ break;
+ case '?': /* Delete */
+ num = 127;
+ break;
+ case '_': /* Space */
+ num = ' ';
+ break;
+ case '\0': /* End of string */
+ state = st_error; /* Error! */
+ break;
+ default: /* Escaped character like \ ^ : = */
+ num = *p;
+ break;
+ }
+ if ( state == st_backslash )
+ {
+ *(q++) = num;
+ count++;
+ state = st_gnd;
+ }
+ p++;
+ break;
+
+ case st_octal: /* Octal sequence */
+ if ( *p < '0' || *p > '7' )
+ {
+ *(q++) = num;
+ count++;
+ state = st_gnd;
+ }
+ else
+ num = ( num << 3 ) + ( *(p++) - '0' );
+ break;
+
+ case st_hex: /* Hex sequence */
+ switch ( *p )
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ num = ( num << 4 ) + ( *(p++) - '0' );
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ num = ( num << 4 ) + ( *(p++) - 'a' ) + 10;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ num = ( num << 4 ) + ( *(p++) - 'A' ) + 10;
+ break;
+ default:
+ *(q++) = num;
+ count++;
+ state = st_gnd;
+ break;
+ }
+ break;
+
+ case st_caret: /* Caret escape */
+ state = st_gnd; /* Should be the next state... */
+ if ( *p >= '@' && *p <= '~' )
+ {
+ *(q++) = *(p++) & 037;
+ count++;
+ }
+ else if ( *p == '?' )
+ {
+ *(q++) = 127;
+ count++;
+ }
+ else
+ state = st_error;
+ break;
+ }
+ }
+
+ *dest = q; *src = p;
+
+ return ( state == st_error ) ? -1 : count;
+ }
+
+
/* Request that the directory named `name' have its contents listed later.
If `realname' is nonzero, it will be used instead of `name' when the
directory name is printed. This allows symbolic links to directories
***************
*** 1166,1172 ****
#ifdef S_ISLNK
if (S_ISLNK (files[files_index].stat.st_mode)
! && (explicit_arg || format == long_format))
{
char *linkpath;
struct stat linkstats;
--- 1757,1763 ----
#ifdef S_ISLNK
if (S_ISLNK (files[files_index].stat.st_mode)
! && (explicit_arg || format == long_format || print_with_color))
{
char *linkpath;
struct stat linkstats;
***************
*** 1178,1185 ****
they won't be traced and when no indicator is needed. */
if (linkpath
&& ((explicit_arg && format != long_format)
! || indicator_style != none)
! && SAFE_STAT (linkpath, &linkstats) == 0)
{
/* Symbolic links to directories that are mentioned on the
command line are automatically traced if not being
--- 1769,1777 ----
they won't be traced and when no indicator is needed. */
if (linkpath
&& ((explicit_arg && format != long_format)
! || indicator_style != none || print_with_color)
! && ( files[files_index].linkok =
! (SAFE_STAT (linkpath, &linkstats) == 0) ) )
{
/* Symbolic links to directories that are mentioned on the
command line are automatically traced if not being
***************
*** 1207,1213 ****
free (linkpath);
}
#endif
!
#ifdef S_ISLNK
if (S_ISLNK (files[files_index].stat.st_mode))
files[files_index].filetype = symbolic_link;
--- 1799,1805 ----
free (linkpath);
}
#endif
!
#ifdef S_ISLNK
if (S_ISLNK (files[files_index].stat.st_mode))
files[files_index].filetype = symbolic_link;
***************
*** 1690,1696 ****
DIRED_INDENT ();
FPUTS (bigbuf, stdout, p - bigbuf);
PUSH_CURRENT_DIRED_POS (&dired_obstack);
! print_name_with_quoting (f->name);
PUSH_CURRENT_DIRED_POS (&dired_obstack);
if (f->filetype == symbolic_link)
--- 2282,2291 ----
DIRED_INDENT ();
FPUTS (bigbuf, stdout, p - bigbuf);
PUSH_CURRENT_DIRED_POS (&dired_obstack);
! #ifdef OS2
! os2_modify_stat( &f->stat );
! #endif
! print_fancy_name (f->name, f->stat.st_mode, f->linkok);
PUSH_CURRENT_DIRED_POS (&dired_obstack);
if (f->filetype == symbolic_link)
***************
*** 1698,1704 ****
if (f->linkname)
{
FPUTS_LITERAL (" -> ", stdout);
! print_name_with_quoting (f->linkname);
if (indicator_style != none)
print_type_indicator (f->linkmode);
}
--- 2293,2299 ----
if (f->linkname)
{
FPUTS_LITERAL (" -> ", stdout);
! print_fancy_name (f->linkname, f->linkmode, f->linkok-1);
if (indicator_style != none)
print_type_indicator (f->linkmode);
}
***************
*** 1717,1723 ****
register const char *p;
size_t *quoted_length;
{
! register unsigned char c;
const char *p0 = p;
char *quoted, *q;
int found_quotable;
--- 2312,2318 ----
register const char *p;
size_t *quoted_length;
{
! register unsigned char c; /* Unsigned for ISO 8859 test */
const char *p0 = p;
char *quoted, *q;
int found_quotable;
***************
*** 1887,1899 ****
(unsigned) convert_blocks (ST_NBLOCKS (f->stat),
kilobyte_blocks));
! print_name_with_quoting (f->name);
if (indicator_style != none)
print_type_indicator (f->stat.st_mode);
}
static void
print_type_indicator (mode)
unsigned int mode;
{
--- 2482,2522 ----
(unsigned) convert_blocks (ST_NBLOCKS (f->stat),
kilobyte_blocks));
! #ifdef OS2
! os2_modify_stat( &f->stat );
! #endif
! print_fancy_name (f->name, f->stat.st_mode, f->linkok);
if (indicator_style != none)
print_type_indicator (f->stat.st_mode);
}
static void
+ print_fancy_name (name, mode, linkok)
+ char *name;
+ unsigned int mode;
+ int linkok;
+ {
+ if (print_with_color)
+ {
+ print_color_indicator(name, mode, linkok);
+ print_name_with_quoting(name);
+ if ( color_indicator[C_END].string )
+ {
+ put_indicator(&color_indicator[C_END]);
+ }
+ else
+ {
+ put_indicator(&color_indicator[C_LEFT]);
+ put_indicator(&color_indicator[C_NORM]);
+ put_indicator(&color_indicator[C_RIGHT]);
+ }
+ }
+ else
+ print_name_with_quoting(name);
+ }
+
+ static void
print_type_indicator (mode)
unsigned int mode;
{
***************
*** 1920,1931 ****
PUTCHAR ('*');
}
static int
length_of_file_name_and_frills (f)
struct fileinfo *f;
{
register char *p = f->name;
! register char c;
register int len = 0;
if (print_inode)
--- 2543,2660 ----
PUTCHAR ('*');
}
+ static void
+ print_color_indicator (name, mode, linkok)
+ char *name;
+ unsigned int mode;
+ int linkok;
+ {
+ int i;
+ int shi; /* Bits to shift mode */
+ int type = C_FILE;
+ struct col_ext_type *ext; /* Color extension */
+ int len; /* Length of name */
+
+ /* Is this a nonexistent file? If so, linkok == -1 */
+
+ if ( linkok == -1 && color_indicator[C_MISSING].string )
+ {
+ ext = NULL;
+ type = C_MISSING;
+ }
+ else
+ {
+ /* Test if is is a recognized extension */
+
+ len = strlen(name);
+ name += len; /* Pointer to final \0 */
+ for ( ext = col_ext_list ; ext != NULL ; ext = ext->next )
+ {
+ if ( ext->ext.len <= len &&
+ #ifdef OS2
+ strnicmp(name-ext->ext.len,ext->ext.string,ext->ext.len) == 0 )
+ #else
+ strncmp(name-ext->ext.len,ext->ext.string,ext->ext.len) == 0 )
+ #endif
+ break;
+ }
+
+ if ( !ext )
+ {
+ if (S_ISDIR (mode))
+ type = C_DIR;
+
+ #ifdef S_ISSYSTEM
+ else if (S_ISSYSTEM (mode))
+ type = C_SYSTEM;
+ #endif
+
+ #ifdef S_ISHIDDEN
+ else if (S_ISHIDDEN (mode))
+ type = C_HIDDEN;
+ #endif
+
+ #ifdef S_ISRDONLY
+ else if (S_ISRDONLY (mode))
+ type = C_RDONLY;
+ #endif
+
+ #ifdef S_ISLNK
+ else if (S_ISLNK (mode))
+ type = (!linkok && color_indicator[C_ORPHAN].string) ?
+ C_ORPHAN : C_LINK;
+ #endif
+
+ #ifdef S_ISFIFO
+ else if (S_ISFIFO (mode))
+ type = C_FIFO;
+ #endif
+
+ #ifdef S_ISSOCK
+ else if (S_ISSOCK (mode))
+ type = C_SOCK;
+ #endif
+
+ #ifdef S_ISBLK
+ else if (S_ISBLK (mode))
+ type = C_BLK;
+ #endif
+
+ #ifdef S_ISCHR
+ else if (S_ISCHR (mode))
+ type = C_CHR;
+ #endif
+
+ if ( type == C_FILE && (mode & (S_IEXEC|S_IEXEC>>3|S_IEXEC>>6)) )
+ type = C_EXEC;
+ }
+ }
+
+ put_indicator(&color_indicator[C_LEFT]);
+ put_indicator(ext ? &(ext->seq) : &color_indicator[type]);
+ put_indicator(&color_indicator[C_RIGHT]);
+ }
+
+ /* Output a color indicator (which may contain nulls) */
+ static void
+ put_indicator(ind)
+ struct bin_str *ind;
+ {
+ register int i;
+ register char *p;
+
+ p = ind->string;
+
+ for ( i = ind->len ; i ; i-- )
+ putchar(*(p++));
+ }
+
static int
length_of_file_name_and_frills (f)
struct fileinfo *f;
{
register char *p = f->name;
! register unsigned char c; /* Unsigned for ISO 8859 test */
register int len = 0;
if (print_inode)
***************
*** 1961,1967 ****
break;
default:
! if (c >= 040 && c < 0177)
len += 1;
else
len += 4;
--- 2690,2697 ----
break;
default:
! if ( (c >= 0x20 && c <= 0x7E) ||
! (print_iso8859 && c >= 0xA1 && c <= 0xFF) )
len += 1;
else
len += 4;
***************
*** 2209,2219 ****
-c sort by change time; with -l: show ctime\n\
-D, --dired generate output well suited to Emacs' dired mode\n\
-d, --directory list directory entries instead of contents\n\
-F, --classify append a character for typing each entry\n\
! -f do not sort, enable -aU, disable -lst\n\
--format=WORD across -x, commas -m, horizontal -x, long -l,\n\
! single-column -1, verbose -l, vertical -C\n\
! --full-time list both full date and full time\n");
printf ("\
-G, --no-group inhibit display of group information\n\
--- 2939,2949 ----
-c sort by change time; with -l: show ctime\n\
-D, --dired generate output well suited to Emacs' dired mode\n\
-d, --directory list directory entries instead of contents\n\
+ -e, --full-time list both date and full time\n\
-F, --classify append a character for typing each entry\n\
! -f do not sort, enable -aU, disable -lsto\n\
--format=WORD across -x, commas -m, horizontal -x, long -l,\n\
! single-column -1, verbose -l, vertical -C\n");
printf ("\
-G, --no-group inhibit display of group information\n\
***************
*** 2226,2231 ****
--- 2956,2963 ----
-m fill width with a comma separated list of entries\n\
-N, --literal do not quote entry names\n\
-n, --numeric-uid-gid list numeric UIDs and GIDs instead of names\n\
+ -o, --color, --colour colorize entries according to type\n\
+ --colo(u)r=WORD yes -o, no, tty (if output is a terminal)\n\
-p append a character for typing each entry\n\
-Q, --quote-name enclose entry names in double quotes\n\
-q, --hide-control-chars print ? instead of non graphic characters\n\