From: Jim Meyering Date: Tue, 18 Oct 1994 23:23:44 +0000 (+0000) Subject: . X-Git-Tag: textutils-1_12_1~518 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=131aa77dd9cf1ecc0fb10afead3facf8bdbc0a45;p=thirdparty%2Fcoreutils.git . --- diff --git a/src/ls.c b/src/ls.c index ce24d3cff1..4fc77a6922 100644 --- a/src/ls.c +++ b/src/ls.c @@ -52,19 +52,19 @@ #include #endif +#include "obstack.h" #include "ls.h" #include "version.h" #include "safe-stat.h" #include "safe-lstat.h" +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + #ifndef INT_MAX #define INT_MAX (((unsigned int) ~(unsigned int) 0) >> 1) #endif -#ifndef S_IEXEC -#define S_IEXEC S_IXUSR -#endif - /* Return an int indicating the result of comparing two longs. */ #if (INT_MAX <= 65535) #define longdiff(a, b) ((a) < (b) ? -1 : (a) > (b) ? 1 : 0) @@ -452,12 +452,64 @@ static char const* const time_args[] = "atime", "access", "use", "ctime", "status", 0 }; +/* FIXME comment */ +static size_t dired_pos; + +/* FIXME comment */ +#define PUTCHAR(c) do {putchar ((c)); ++dired_pos;} while (0) + +/* FIXME comment */ +#define FPUTS(s, stream, s_len) \ + do {fputs ((s), (stream)); dired_pos += s_len;} while (0) + +/* FIXME comment */ +static struct obstack dired_obstack; + +/* FIXME comment */ +#define PUSH_CURRENT_DIRED_POS() \ + do \ + { \ + /* FIXME: remove the `&& format == long_format' clause. */ \ + if (dired && format == long_format) \ + obstack_grow (&dired_obstack, &dired_pos, sizeof (dired_pos)); \ + } \ + while (0) + +/* FIXME comment */ +#define PUSH_CURRENT_SUBDIRED_POS() \ + do \ + { \ + /* FIXME: remove the `&& format == long_format' clause. */ \ + if (dired && format == long_format && trace_dirs) \ + obstack_grow (&subdired_obstack, &dired_pos, sizeof (dired_pos));\ + } \ + while (0) + +/* FIXME comment */ +static struct obstack subdired_obstack; + static enum time_type const time_types[] = { time_atime, time_atime, time_atime, time_ctime, time_ctime }; +static void +dired_dump_obstack (prefix, os) + const char *prefix; + struct obstack *os; +{ + int i, n_pos; + size_t *pos; + + fputs (prefix, stdout); + n_pos = obstack_object_size (os) / sizeof (size_t); + pos = obstack_finish (os); + for (i=0; inext == 0) print_dir_name = 0; @@ -536,6 +595,14 @@ main (argc, argv) print_dir_name = 1; } + if (dired && format == long_format) + { + /* No need to free these since we're about to exit. */ + dired_dump_obstack ("//DIRED//", &dired_obstack); + if (trace_dirs) + dired_dump_obstack ("//SUBDIRED//", &subdired_obstack); + } + exit (exit_status); } @@ -853,8 +920,8 @@ queue_directory (name, realname) static void print_dir (name, realname) - char *name; - char *realname; + const char *name; + const char *realname; { register DIR *reading; register struct dirent *next; @@ -896,20 +963,27 @@ print_dir (name, realname) if (print_dir_name) { - if (realname) - printf ("%s:\n", realname); - else - printf ("%s:\n", name); + const char *dir; + + dir = (realname ? realname : name); + PUSH_CURRENT_SUBDIRED_POS (); + FPUTS (dir, stdout, strlen (dir)); + PUSH_CURRENT_SUBDIRED_POS (); + FPUTS (":\n", stdout, 2); } if (format == long_format || print_block_size) - printf ("total %u\n", total_blocks); + { + char buf[6 + 20 + 1 + 1]; + sprintf (buf, "total %u\n", total_blocks); + FPUTS (buf, stdout, strlen (buf)); + } if (files_index) print_current_files (); if (pending_dirs) - putchar ('\n'); + PUTCHAR ('\n'); } /* Add `pattern' to the list of patterns for which files that match are @@ -1422,161 +1496,18 @@ print_current_files () for (i = 0; i < files_index; i++) { print_long_format (files + i); - putchar ('\n'); + PUTCHAR ('\n'); } break; } } -/* Set QUOTED_LENGTH to strlen(P) and return NULL if P == quoted(P). - Otherwise, return xmalloc'd storage containing the quoted version - of P and set QUOTED_LENGTH to the length of the quoted P. */ - -static char * -quote_filename (p, quoted_length) - register const char *p; - int *quoted_length; -{ - register unsigned char c; - const char *p0 = p; - char *quoted, *q; - int found_quotable; - - if (!quote_as_string && !quote_funny_chars && !qmark_funny_chars) - { - *quoted_length = strlen (p); - return NULL; - } - - found_quotable = 0; - for (c = *p; c; c = *++p) - { - if (quote_funny_chars) - { - switch (c) - { - case '\\': - case '\n': - case '\b': - case '\r': - case '\t': - case '\f': - case ' ': - case '"': - found_quotable = 1; - break; - - default: - /* FIXME: why not just use the ISPRINT macro here? */ - if (!(c > 040 && c < 0177)) - found_quotable = 1; - break; - } - } - else - { - if (!(c >= 040 && c < 0177) && qmark_funny_chars) - found_quotable = 1; - } - if (found_quotable) - break; - } - - if (!found_quotable) - { - *quoted_length = p - p0; - return NULL; - } - - p = p0; - quoted = xmalloc (4 * strlen (p) + 1); - q = quoted; - -#define SAVECHAR(c) *q++ = (c) -#define SAVE_2_CHARS(c12) \ - do { *q++ = ((c12)[0]); \ - *q++ = ((c12)[1]); } while (0) - - if (quote_as_string) - SAVECHAR ('"'); - - while ((c = *p++)) - { - if (quote_funny_chars) - { - switch (c) - { - case '\\': - SAVE_2_CHARS ("\\\\"); - break; - - case '\n': - SAVE_2_CHARS ("\\n"); - break; - - case '\b': - SAVE_2_CHARS ("\\b"); - break; - - case '\r': - SAVE_2_CHARS ("\\r"); - break; - - case '\t': - SAVE_2_CHARS ("\\t"); - break; - - case '\f': - SAVE_2_CHARS ("\\f"); - break; - - case ' ': - SAVE_2_CHARS ("\\ "); - break; - - case '"': - SAVE_2_CHARS ("\\\""); - break; - - default: - if (c > 040 && c < 0177) - SAVECHAR (c); - else - { - char buf[5]; - sprintf (buf, "\\%03o", (unsigned int) c); - q = stpcpy (p, buf); - } - } - } - else - { - if (c >= 040 && c < 0177) - SAVECHAR (c); - else if (!qmark_funny_chars) - SAVECHAR (c); - else - SAVECHAR ('?'); - } - } - - if (quote_as_string) - SAVECHAR ('"'); - - *quoted_length = q - quoted; - - SAVECHAR ('\0'); - - return quoted; -} - static void print_long_format (f) struct fileinfo *f; { char modebuf[20]; char timebuf[40]; - char *quoted; int quoted_length; /* 7 fields that may (worst case be 64-bit integral values) require 20 bytes, @@ -1670,21 +1601,19 @@ print_long_format (f) sprintf (p, "%s ", full_time ? timebuf : timebuf + 4); p += strlen (p); - quoted = quote_filename (f->name, "ed_length); - if (dired) - { - printf ("%d,%d:", p - bigbuf, quoted_length); - } + FPUTS (" ", stdout, 2); - fputs (bigbuf, stdout); - fputs (quoted != NULL ? quoted : f->name, stdout); + FPUTS (bigbuf, stdout, p - bigbuf); + PUSH_CURRENT_DIRED_POS (); + print_name_with_quoting (f->name); + PUSH_CURRENT_DIRED_POS (); if (f->filetype == symbolic_link) { if (f->linkname) { - fputs (" -> ", stdout); + FPUTS (" -> ", stdout, 4); print_name_with_quoting (f->linkname); if (indicator_style != none) print_type_indicator (f->linkmode); @@ -1695,14 +1624,77 @@ print_long_format (f) } -static void -print_name_with_quoting (p) - register char *p; +/* Set QUOTED_LENGTH to strlen(P) and return NULL if P == quoted(P). + Otherwise, return xmalloc'd storage containing the quoted version + of P and set QUOTED_LENGTH to the length of the quoted P. */ + +static char * +quote_filename (p, quoted_length) + register const char *p; + size_t *quoted_length; { register unsigned char c; + const char *p0 = p; + char *quoted, *q; + int found_quotable; + + if (!quote_as_string && !quote_funny_chars && !qmark_funny_chars) + { + *quoted_length = strlen (p); + return NULL; + } + + found_quotable = 0; + for (c = *p; c; c = *++p) + { + if (quote_funny_chars) + { + switch (c) + { + case '\\': + case '\n': + case '\b': + case '\r': + case '\t': + case '\f': + case ' ': + case '"': + found_quotable = 1; + break; + + default: + /* FIXME: why not just use the ISPRINT macro here? */ + if (!(c > 040 && c < 0177)) + found_quotable = 1; + break; + } + } + else + { + if (!(c >= 040 && c < 0177) && qmark_funny_chars) + found_quotable = 1; + } + if (found_quotable) + break; + } + + if (!found_quotable) + { + *quoted_length = p - p0; + return NULL; + } + + p = p0; + quoted = xmalloc (4 * strlen (p) + 1); + q = quoted; + +#define SAVECHAR(c) *q++ = (c) +#define SAVE_2_CHARS(c12) \ + do { *q++ = ((c12)[0]); \ + *q++ = ((c12)[1]); } while (0) if (quote_as_string) - putchar ('"'); + SAVECHAR ('"'); while ((c = *p++)) { @@ -1711,57 +1703,80 @@ print_name_with_quoting (p) switch (c) { case '\\': - printf ("\\\\"); + SAVE_2_CHARS ("\\\\"); break; case '\n': - printf ("\\n"); + SAVE_2_CHARS ("\\n"); break; case '\b': - printf ("\\b"); + SAVE_2_CHARS ("\\b"); break; case '\r': - printf ("\\r"); + SAVE_2_CHARS ("\\r"); break; case '\t': - printf ("\\t"); + SAVE_2_CHARS ("\\t"); break; case '\f': - printf ("\\f"); + SAVE_2_CHARS ("\\f"); break; case ' ': - printf ("\\ "); + SAVE_2_CHARS ("\\ "); break; case '"': - printf ("\\\""); + SAVE_2_CHARS ("\\\""); break; default: if (c > 040 && c < 0177) - putchar (c); + SAVECHAR (c); else - printf ("\\%03o", (unsigned int) c); + { + char buf[5]; + sprintf (buf, "\\%03o", (unsigned int) c); + q = stpcpy (p, buf); + } } } else { if (c >= 040 && c < 0177) - putchar (c); + SAVECHAR (c); else if (!qmark_funny_chars) - putchar (c); + SAVECHAR (c); else - putchar ('?'); + SAVECHAR ('?'); } } if (quote_as_string) - putchar ('"'); + SAVECHAR ('"'); + + *quoted_length = q - quoted; + + SAVECHAR ('\0'); + + return quoted; +} + +static void +print_name_with_quoting (p) + register char *p; +{ + char *quoted; + size_t quoted_length; + + quoted = quote_filename (p, "ed_length); + FPUTS (quoted != NULL ? quoted : p, stdout, quoted_length); + if (quoted) + free (quoted); } /* Print the file name of `f' with appropriate quoting. @@ -1791,26 +1806,26 @@ print_type_indicator (mode) unsigned int mode; { if (S_ISDIR (mode)) - putchar ('/'); + PUTCHAR ('/'); #ifdef S_ISLNK if (S_ISLNK (mode)) - putchar ('@'); + PUTCHAR ('@'); #endif #ifdef S_ISFIFO if (S_ISFIFO (mode)) - putchar ('|'); + PUTCHAR ('|'); #endif #ifdef S_ISSOCK if (S_ISSOCK (mode)) - putchar ('='); + PUTCHAR ('='); #endif if (S_ISREG (mode) && indicator_style == all - && (mode & (S_IEXEC | S_IEXEC >> 3 | S_IEXEC >> 6))) - putchar ('*'); + && (mode & (S_IEXEC | S_IXGRP | S_IXOTH))) + PUTCHAR ('*'); } static int