]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
.
authorJim Meyering <jim@meyering.net>
Tue, 18 Oct 1994 23:23:44 +0000 (23:23 +0000)
committerJim Meyering <jim@meyering.net>
Tue, 18 Oct 1994 23:23:44 +0000 (23:23 +0000)
src/ls.c

index ce24d3cff1d5c2cfbf8b51df67fa0f7f27a5643f..4fc77a69227e30423a4daba2fea94f3540636ae0 100644 (file)
--- a/src/ls.c
+++ b/src/ls.c
 #include <limits.h>
 #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
 };
 
 \f
+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; i<n_pos; i++)
+    printf (" %d", pos[i]);
+  fputs ("\n", stdout);
+}
+
 void
 main (argc, argv)
      int argc;
@@ -489,6 +541,13 @@ main (argc, argv)
     || trace_links || trace_dirs || indicator_style != none
     || print_block_size || print_inode;
 
+  if (dired && format == long_format)
+    {
+      obstack_init (&dired_obstack);
+      if (trace_dirs)
+       obstack_init (&subdired_obstack);
+    }
+
   nfiles = 100;
   files = (struct fileinfo *) xmalloc (sizeof (struct fileinfo) * nfiles);
   files_index = 0;
@@ -519,7 +578,7 @@ main (argc, argv)
     {
       print_current_files ();
       if (pending_dirs)
-       putchar ('\n');
+       PUTCHAR ('\n');
     }
   else if (pending_dirs && pending_dirs->next == 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);
 }
 \f
@@ -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');
 }
 \f
 /* 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, &quoted_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)
 }
 \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, &quoted_length);
+  FPUTS (quoted != NULL ? quoted : p, stdout, quoted_length);
+  if (quoted)
+    free (quoted);
 }
 \f
 /* 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