Imported from ../bash-2.05a.tar.gz.
[platform/upstream/bash.git] / builtins / pushd.def
index 3eadae0..f47b294 100644 (file)
@@ -7,7 +7,7 @@ This file is part of GNU Bash, the Bourne Again SHell.
 
 Bash 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
 
 Bash 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 1, or (at your option) any later
+Software Foundation; either version 2, or (at your option) any later
 version.
 
 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -17,7 +17,7 @@ for more details.
 
 You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
 
 You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
-Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
 
 $PRODUCES pushd.c
 
 
 $PRODUCES pushd.c
 
@@ -30,10 +30,12 @@ the stack, making the new top of the stack the current working
 directory.  With no arguments, exchanges the top two directories.
 
 +N     Rotates the stack so that the Nth directory (counting
 directory.  With no arguments, exchanges the top two directories.
 
 +N     Rotates the stack so that the Nth directory (counting
-       from the left of the list shown by `dirs') is at the top.
+       from the left of the list shown by `dirs', starting with
+       zero) is at the top.
 
 -N     Rotates the stack so that the Nth directory (counting
 
 -N     Rotates the stack so that the Nth directory (counting
-       from the right) is at the top.
+       from the right of the list shown by `dirs', starting with
+       zero) is at the top.
 
 -n     suppress the normal change of directory when adding directories
        to the stack, so only the stack is manipulated.
 
 -n     suppress the normal change of directory when adding directories
        to the stack, so only the stack is manipulated.
@@ -93,9 +95,14 @@ $END
 
 #if defined (PUSHD_AND_POPD)
 #include <stdio.h>
 
 #if defined (PUSHD_AND_POPD)
 #include <stdio.h>
-#include <sys/param.h>
+#ifndef _MINIX
+#  include <sys/param.h>
+#endif
 
 #if defined (HAVE_UNISTD_H)
 
 #if defined (HAVE_UNISTD_H)
+#  ifdef _MINIX
+#    include <sys/types.h>
+#  endif
 #  include <unistd.h>
 #endif
 
 #  include <unistd.h>
 #endif
 
@@ -106,10 +113,14 @@ $END
 #include <tilde/tilde.h>
 
 #include "../shell.h"
 #include <tilde/tilde.h>
 
 #include "../shell.h"
-#include "../maxpath.h"
+#include "maxpath.h"
 #include "common.h"
 #include "builtext.h"
 
 #include "common.h"
 #include "builtext.h"
 
+#ifdef LOADABLE_BUILTIN
+#  include "builtins.h"
+#endif
+
 #if !defined (errno)
 extern int errno;
 #endif /* !errno */
 #if !defined (errno)
 extern int errno;
 #endif /* !errno */
@@ -125,12 +136,12 @@ static int directory_list_size;
 /* Offset to the end of the list. */
 static int directory_list_offset;
 
 /* Offset to the end of the list. */
 static int directory_list_offset;
 
-static void pushd_error ();
-static void clear_directory_stack ();
-static int cd_to_string ();
-static int change_to_temp ();
-static int get_dirstack_index ();
-static void add_dirstack_element ();
+static void pushd_error __P((int, char *));
+static void clear_directory_stack __P((void));
+static int cd_to_string __P((char *));
+static int change_to_temp __P((char *));
+static void add_dirstack_element __P((char *));
+static int get_dirstack_index __P((long, int, int *));
 
 #define NOCD           0x01
 #define ROTATE         0x02
 
 #define NOCD           0x01
 #define ROTATE         0x02
@@ -175,10 +186,10 @@ pushd_builtin (list)
          flags |= NOCD;
        }
       else if (ISOPTION (list->word->word, '-'))
          flags |= NOCD;
        }
       else if (ISOPTION (list->word->word, '-'))
-        {
-          list = list->next;
-          break;
-        }
+       {
+         list = list->next;
+         break;
+       }
       else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
        /* Let `pushd -' work like it used to. */
        break;
       else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
        /* Let `pushd -' work like it used to. */
        break;
@@ -257,6 +268,8 @@ pushd_builtin (list)
     {
       add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory);
       dirs_builtin ((WORD_LIST *)NULL);
     {
       add_dirstack_element ((flags & NOCD) ? savestring (list->word->word) : current_directory);
       dirs_builtin ((WORD_LIST *)NULL);
+      if (flags & NOCD)
+       free (current_directory);
       return (EXECUTION_SUCCESS);
     }
   else
       return (EXECUTION_SUCCESS);
     }
   else
@@ -277,18 +290,20 @@ popd_builtin (list)
   long which;
   int flags;
   char direction;
   long which;
   int flags;
   char direction;
+  char *which_word;
 
 
-  for (flags = 0, which = 0L, direction = '+'; list; list = list->next)
+  which_word = (char *)NULL;
+  for (flags = 0, which = 0, direction = '+'; list; list = list->next)
     {
       if (ISOPTION (list->word->word, 'n'))
     {
       if (ISOPTION (list->word->word, 'n'))
-        {
-          flags |= NOCD;
-        }
+       {
+         flags |= NOCD;
+       }
       else if (ISOPTION (list->word->word, '-'))
       else if (ISOPTION (list->word->word, '-'))
-        {
-          list = list->next;
-          break;
-        }
+       {
+         list = list->next;
+         break;
+       }
       else if (((direction = list->word->word[0]) == '+') || direction == '-')
        {
          if (legal_number (list->word->word + 1, &which) == 0)
       else if (((direction = list->word->word[0]) == '+') || direction == '-')
        {
          if (legal_number (list->word->word + 1, &which) == 0)
@@ -297,6 +312,7 @@ popd_builtin (list)
              builtin_usage ();
              return (EXECUTION_FAILURE);
            }
              builtin_usage ();
              return (EXECUTION_FAILURE);
            }
+         which_word = list->word->word;
        }
       else if (*list->word->word == '-')
        {
        }
       else if (*list->word->word == '-')
        {
@@ -310,7 +326,7 @@ popd_builtin (list)
 
   if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
     {
 
   if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
     {
-      pushd_error (directory_list_offset, list ? list->word->word : "");
+      pushd_error (directory_list_offset, which_word ? which_word : "");
       return (EXECUTION_FAILURE);
     }
 
       return (EXECUTION_FAILURE);
     }
 
@@ -319,7 +335,7 @@ popd_builtin (list)
       (direction == '-' && which == directory_list_offset))
     {
       i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1])
       (direction == '-' && which == directory_list_offset))
     {
       i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1])
-                               : EXECUTION_SUCCESS;
+                               : EXECUTION_SUCCESS;
       if (i != EXECUTION_SUCCESS)
        return (i);
       free (pushd_directory_list[--directory_list_offset]);
       if (i != EXECUTION_SUCCESS)
        return (i);
       free (pushd_directory_list[--directory_list_offset]);
@@ -370,14 +386,14 @@ dirs_builtin (list)
          vflag |= 1;
        }
       else if (ISOPTION (list->word->word, '-'))
          vflag |= 1;
        }
       else if (ISOPTION (list->word->word, '-'))
-        {
-          list = list->next;
-          break;
-        }
+       {
+         list = list->next;
+         break;
+       }
       else if (*list->word->word == '+' || *list->word->word == '-')
       else if (*list->word->word == '+' || *list->word->word == '-')
-        {
-          int sign;
-          if (legal_number (w = list->word->word + 1, &i) == 0)
+       {
+         int sign;
+         if (legal_number (w = list->word->word + 1, &i) == 0)
            {
              builtin_error (m_badarg, list->word->word);
              builtin_usage ();
            {
              builtin_error (m_badarg, list->word->word);
              builtin_usage ();
@@ -521,7 +537,8 @@ add_dirstack_element (dir)
 
 static int
 get_dirstack_index (ind, sign, indexp)
 
 static int
 get_dirstack_index (ind, sign, indexp)
-     int ind, sign, *indexp;
+     long ind;
+     int sign, *indexp;
 {
   if (indexp)
     *indexp = sign > 0 ? 1 : 2;
 {
   if (indexp)
     *indexp = sign > 0 ? 1 : 2;
@@ -536,13 +553,44 @@ get_dirstack_index (ind, sign, indexp)
        *indexp = sign > 0 ? 2 : 1;
       return 0;
     }
        *indexp = sign > 0 ? 2 : 1;
       return 0;
     }
-  else
+  else if (ind >= 0 && ind <= directory_list_offset)
     return (sign > 0 ? directory_list_offset - ind : ind);
     return (sign > 0 ? directory_list_offset - ind : ind);
+  else
+    return -1;
 }
 
 }
 
+/* Used by the tilde expansion code. */
+char *
+get_dirstack_from_string (string)
+     char *string;
+{
+  int ind, sign, index_flag;
+  long i;
+
+  sign = 1;
+  if (*string == '-' || *string == '+')
+    {
+      sign = (*string == '-') ? -1 : 1;
+      string++;
+    }
+  if (legal_number (string, &i) == 0)
+    return ((char *)NULL);
+
+  index_flag = 0;
+  ind = get_dirstack_index (i, sign, &index_flag);
+  if (index_flag && (ind < 0 || ind > directory_list_offset))
+    return ((char *)NULL);
+  if (index_flag == 0 || (index_flag == 1 && ind == 0))
+    return (get_string_value ("PWD"));
+  else
+    return (pushd_directory_list[ind]);
+}
+
+#ifdef INCLUDE_UNUSED
 char *
 get_dirstack_element (ind, sign)
 char *
 get_dirstack_element (ind, sign)
-     int ind, sign;
+     long ind;
+     int sign;
 {
   int i;
 
 {
   int i;
 
@@ -550,10 +598,12 @@ get_dirstack_element (ind, sign)
   return (i < 0 || i > directory_list_offset) ? (char *)NULL
                                              : pushd_directory_list[i];
 }
   return (i < 0 || i > directory_list_offset) ? (char *)NULL
                                              : pushd_directory_list[i];
 }
+#endif
 
 void
 set_dirstack_element (ind, sign, value)
 
 void
 set_dirstack_element (ind, sign, value)
-     int ind, sign;
+     long ind;
+     int  sign;
      char *value;
 {
   int i;
      char *value;
 {
   int i;
@@ -601,4 +651,98 @@ get_directory_stack ()
     free (d);
   return ret;  /* was (REVERSE_LIST (ret, (WORD_LIST *)); */
 }
     free (d);
   return ret;  /* was (REVERSE_LIST (ret, (WORD_LIST *)); */
 }
+
+#ifdef LOADABLE_BUILTIN
+static char *dirs_doc[] = {
+  "Display the list of currently remembered directories.  Directories",
+  "find their way onto the list with the `pushd' command; you can get",
+  "back up through the list with the `popd' command.",
+  "",
+  "The -l flag specifies that `dirs' should not print shorthand versions",
+  "of directories which are relative to your home directory.  This means",
+  "that `~/bin' might be displayed as `/homes/bfox/bin'.  The -v flag",
+  "causes `dirs' to print the directory stack with one entry per line,",
+  "prepending the directory name with its position in the stack.  The -p",
+  "flag does the same thing, but the stack position is not prepended.",
+  "The -c flag clears the directory stack by deleting all of the elements.",
+  "",
+  "+N   displays the Nth entry counting from the left of the list shown by",
+  "     dirs when invoked without options, starting with zero.",
+  "",
+  "-N   displays the Nth entry counting from the right of the list shown by",
+  "     dirs when invoked without options, starting with zero.",
+  (char *)NULL
+};
+
+static char *pushd_doc[] = {
+  "Adds a directory to the top of the directory stack, or rotates",
+  "the stack, making the new top of the stack the current working",
+  "directory.  With no arguments, exchanges the top two directories.",
+  "",
+  "+N   Rotates the stack so that the Nth directory (counting",
+  "     from the left of the list shown by `dirs', starting with",
+  "     zero) is at the top.",
+  "",
+  "-N   Rotates the stack so that the Nth directory (counting",
+  "     from the right of the list shown by `dirs', starting with",
+  "     zero) is at the top.",
+  "",
+  "-n   suppress the normal change of directory when adding directories",
+  "     to the stack, so only the stack is manipulated.",
+  "",
+  "dir  adds DIR to the directory stack at the top, making it the",
+  "     new current working directory.",
+  "",
+  "You can see the directory stack with the `dirs' command.",
+  (char *)NULL
+};
+
+static char *popd_doc[] = {
+  "Removes entries from the directory stack.  With no arguments,",
+  "removes the top directory from the stack, and cd's to the new",
+  "top directory.",
+  "",
+  "+N   removes the Nth entry counting from the left of the list",
+  "     shown by `dirs', starting with zero.  For example: `popd +0'",
+  "     removes the first directory, `popd +1' the second.",
+  "",
+  "-N   removes the Nth entry counting from the right of the list",
+  "     shown by `dirs', starting with zero.  For example: `popd -0'",
+  "     removes the last directory, `popd -1' the next to last.",
+  "",
+  "-n   suppress the normal change of directory when removing directories",
+  "     from the stack, so only the stack is manipulated.",
+  "",
+  "You can see the directory stack with the `dirs' command.",
+  (char *)NULL
+};
+
+struct builtin pushd_struct = {
+       "pushd",
+       pushd_builtin,
+       BUILTIN_ENABLED,
+       pushd_doc,
+       "pushd [+N | -N] [-n] [dir]",
+       0
+};
+
+struct builtin popd_struct = {
+       "popd",
+       popd_builtin,
+       BUILTIN_ENABLED,
+       popd_doc,
+       "popd [+N | -N] [-n]",
+       0
+};
+
+struct builtin dirs_struct = {
+       "dirs",
+       dirs_builtin,
+       BUILTIN_ENABLED,
+       dirs_doc,
+       "dirs [-clpv] [+N] [-N]",
+       0
+};
+#endif /* LOADABLE_BUILTIN */
+
 #endif /* PUSHD_AND_POPD */
 #endif /* PUSHD_AND_POPD */