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
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
#if defined (PUSHD_AND_POPD)
#include <stdio.h>
-#include <sys/param.h>
+#ifndef _MINIX
+# include <sys/param.h>
+#endif
#if defined (HAVE_UNISTD_H)
+# ifdef _MINIX
+# include <sys/types.h>
+# endif
# include <unistd.h>
#endif
#include <tilde/tilde.h>
#include "../shell.h"
-#include "../maxpath.h"
+#include "maxpath.h"
#include "common.h"
#include "builtext.h"
+#ifdef LOADABLE_BUILTIN
+# include "builtins.h"
+#endif
+
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* 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
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;
char *which_word;
which_word = (char *)NULL;
- for (flags = 0, which = 0L, direction = '+'; list; list = list->next)
+ for (flags = 0, which = 0, direction = '+'; list; list = list->next)
{
if (ISOPTION (list->word->word, 'n'))
- {
- flags |= NOCD;
- }
+ {
+ flags |= NOCD;
+ }
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)
(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]);
vflag |= 1;
}
else if (ISOPTION (list->word->word, '-'))
- {
- list = list->next;
- break;
- }
+ {
+ list = list->next;
+ break;
+ }
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 ();
static int
get_dirstack_index (ind, sign, indexp)
- int ind, sign, *indexp;
+ long ind;
+ int sign, *indexp;
{
if (indexp)
*indexp = sign > 0 ? 1 : 2;
*indexp = sign > 0 ? 2 : 1;
return 0;
}
- else
+ else if (ind >= 0 && ind <= directory_list_offset)
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)
- int ind, sign;
+ long ind;
+ int sign;
{
int i;
return (i < 0 || i > directory_list_offset) ? (char *)NULL
: pushd_directory_list[i];
}
+#endif
void
set_dirstack_element (ind, sign, value)
- int ind, sign;
+ long ind;
+ int sign;
char *value;
{
int i;
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 */