mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-01 01:20:00 +02:00
commit bash-20061026 snapshot
This commit is contained in:
@@ -13764,3 +13764,57 @@ builtins/ulimit.def
|
||||
|
||||
po/ru.po
|
||||
- fix encoding; Russian text in the file is actually encoded in KOI8-R
|
||||
|
||||
10/23
|
||||
-----
|
||||
shell.c
|
||||
- make sure that the call to move_to_high_fd in open_shell_script
|
||||
passes 1 for the `check_new' parameter so open high file descriptors
|
||||
don't get closed and reused. Bug reported by Mike Stroyan
|
||||
<mike.stroyan@hp.com>
|
||||
|
||||
doc/bashref.texi
|
||||
- fix typos and misspellings sent in by Brian Gough
|
||||
|
||||
10/24
|
||||
-----
|
||||
support/shobj-conf
|
||||
- make netbsd shared library creation like openbsd's until I hear
|
||||
differently (called using `gcc -shared')
|
||||
|
||||
10/26
|
||||
-----
|
||||
subst.c
|
||||
- fix bug in parameter_brace_patsub so if the first character of the
|
||||
expanded pattern is a `/', it is not taken as a global replacement
|
||||
specifier. Bug reported on forums.nekochan.net
|
||||
|
||||
10/27
|
||||
-----
|
||||
builtins/printf.def
|
||||
- if we need an extern declaration for asprintf, make sure we include
|
||||
stdarg.h or varargs.h, whichever is appropriate
|
||||
- if we do not have asprintf, add an extern declaration using
|
||||
stdarg format. This fixes the bugs with %G on IRIX reported by
|
||||
Matthew Woehlke <mwoehlke@tibco.com> and Stuart Shelton
|
||||
<srcshelton@gmail.com>
|
||||
|
||||
|
||||
lib/sh/snprintf.c
|
||||
- add note to not call log_10 with 0 argument -- we don't want to do
|
||||
what real log10 does (-infinity/raise divide-by-zero exception)
|
||||
- make sure numtoa (used by dtoa) takes the precision into account
|
||||
when computing the fractional part with an argument of `0.0'
|
||||
- make sure `g' and `G' formats don't print radix char if there are
|
||||
no characters to be printed after it (change to floating())
|
||||
- change callers of log_10 (exponent, 'g' and 'G' cases in
|
||||
vsnprintf_internal) to not call it with 0 for argument. This fixes
|
||||
the hang reported on IRIX by Matthew Woehlke <mwoehlke@tibco.com>
|
||||
and Stuart Shelton <mwoehlke@tibco.com>
|
||||
|
||||
10/28
|
||||
-----
|
||||
builtins/{caller,pushd}.def
|
||||
- changed longdoc strings in loadable builtin section to be single
|
||||
strings, as put in the build directory builtins.c file, to aid
|
||||
translators
|
||||
|
||||
+73
-4
@@ -8889,8 +8889,8 @@ Makefile.in
|
||||
- descend into `po' and run make recursively for the various clean
|
||||
targets
|
||||
|
||||
1/4
|
||||
---
|
||||
1/4/2004
|
||||
--------
|
||||
include/shmbutil.h
|
||||
- two new macros: BACKUP_CHAR(str, strsize, i), which backs up one
|
||||
multibyte character in STR starting at index I, and
|
||||
@@ -12718,8 +12718,8 @@ jobs.c
|
||||
- in delete_job, if find_last_proc returns NULL, don't try to call
|
||||
bgp_delete
|
||||
|
||||
1/7
|
||||
---
|
||||
1/7/2006
|
||||
--------
|
||||
doc/bash.1
|
||||
- patch from Tim Waugh to replace some literal single quotes with
|
||||
\(aq, the groff special character for it
|
||||
@@ -13744,3 +13744,72 @@ parse.y
|
||||
- change parse_matched_pair to make sure `` command substitution does
|
||||
not check for shell comments while parsing. Bug reported against
|
||||
bash-3.2 by Greg Schaefer <gschafer@zip.com.au>
|
||||
|
||||
10/14
|
||||
-----
|
||||
parse.y
|
||||
- add new parser_state flag: PST_REGEXP; means we are parsing a
|
||||
regular expression following the =~ conditional operator
|
||||
- cond_node sets PST_REGEXP after reading the `=~' operator
|
||||
- change read_token to call read_token_word immediately if the
|
||||
PST_REGEXP bit is set in parser_state
|
||||
- change read_token_word to skip over `(' and `|' if PST_REGEXP is
|
||||
set, since those characters are legitimate regexp chars (but still
|
||||
parse matched pairs of parens)
|
||||
|
||||
10/16
|
||||
-----
|
||||
builtins/ulimit.def
|
||||
- add -e and -r to $SHORT_DOC usage string
|
||||
|
||||
po/ru.po
|
||||
- fix encoding; Russian text in the file is actually encoded in KOI8-R
|
||||
|
||||
10/23
|
||||
-----
|
||||
shell.c
|
||||
- make sure that the call to move_to_high_fd in open_shell_script
|
||||
passes 1 for the `check_new' parameter so open high file descriptors
|
||||
don't get closed and reused. Bug reported by Mike Stroyan
|
||||
<mike.stroyan@hp.com>
|
||||
|
||||
doc/bashref.texi
|
||||
- fix typos and misspellings sent in by Brian Gough
|
||||
|
||||
10/24
|
||||
-----
|
||||
support/shobj-conf
|
||||
- make netbsd shared library creation like openbsd's until I hear
|
||||
differently (called using `gcc -shared')
|
||||
|
||||
10/26
|
||||
-----
|
||||
subst.c
|
||||
- fix bug in parameter_brace_patsub so if the first character of the
|
||||
expanded pattern is a `/', it is not taken as a global replacement
|
||||
specifier. Bug reported on forums.nekochan.net
|
||||
|
||||
10/27
|
||||
-----
|
||||
builtins/printf.def
|
||||
- if we need an extern declaration for asprintf, make sure we include
|
||||
stdarg.h or varargs.h, whichever is appropriate
|
||||
- if we do not have asprintf, add an extern declaration using
|
||||
stdarg format. This fixes the bugs with %G on IRIX reported by
|
||||
Matthew Woehlke <mwoehlke@tibco.com> and Stuart Shelton
|
||||
<srcshelton@gmail.com>
|
||||
|
||||
|
||||
lib/sh/snprintf.c
|
||||
- add note to not call log_10 with 0 argument -- we don't want to do
|
||||
what real log10 does (-infinity/raise divide-by-zero exception)
|
||||
- make sure numtoa (used by dtoa) takes the precision into account
|
||||
when computing the fractional part with an argument of `0.0'
|
||||
- make sure `g' and `G' formats don't print radix char if there are
|
||||
no characters to be printed after it (change to floating())
|
||||
- change callers of log_10 (exponent, 'g' and 'G' cases in
|
||||
vsnprintf_internal) to not call it with 0 for argument. This fixes
|
||||
the hang reported on IRIX by Matthew Woehlke <mwoehlke@tibco.com>
|
||||
and Stuart Shelton <mwoehlke@tibco.com>
|
||||
|
||||
|
||||
|
||||
@@ -470,6 +470,8 @@ po/en@quot.gmo f
|
||||
po/en@boldquot.gmo f
|
||||
po/ru.po f
|
||||
po/ru.gmo f
|
||||
po/sv.po f
|
||||
po/sv.gmo f
|
||||
po/insert-header.sin f
|
||||
po/quot.sed f
|
||||
po/remove-potcdate.sin f
|
||||
|
||||
@@ -335,3 +335,6 @@ Platform-Specific Configuration and Operation Notes
|
||||
17. Do NOT use bison-1.75. It builds a non-working parser. The most
|
||||
obvious effect is that constructs like "for i; do echo $i; done" don't
|
||||
loop over the positional parameters.
|
||||
|
||||
18. I have received reports that using -O2 with the MIPSpro results in a
|
||||
binary that fails in strange ways. Using -O1 seems to work.
|
||||
|
||||
+8
-8
@@ -128,14 +128,14 @@ caller_builtin (list)
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
static char *caller_doc[] = {
|
||||
N_("Returns the context of the current subroutine call."),
|
||||
N_(" "),
|
||||
N_("Without EXPR, returns returns \"$line $filename\". With EXPR,"),
|
||||
N_("returns \"$line $subroutine $filename\"; this extra information"),
|
||||
N_("can be used used to provide a stack trace."),
|
||||
N_(" "),
|
||||
N_("The value of EXPR indicates how many call frames to go back before the"),
|
||||
N_("current one; the top frame is frame 0."),
|
||||
N_("Returns the context of the current subroutine call.\n\
|
||||
\n\
|
||||
Without EXPR, returns \"$line $filename\". With EXPR,\n\
|
||||
returns \"$line $subroutine $filename\"; this extra information\n\
|
||||
can be used used to provide a stack trace.\n\
|
||||
\n\
|
||||
The value of EXPR indicates how many call frames to go back before the\n\
|
||||
current one; the top frame is frame 0."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
This file is caller.def, from which is created caller.c. It implements the
|
||||
builtin "caller" in Bash.
|
||||
|
||||
Copyright (C) 2002-2003 Rocky Bernstein for Free Software Foundation, Inc.
|
||||
|
||||
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
|
||||
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
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
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
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
$PRODUCES caller.c
|
||||
|
||||
$BUILTIN caller
|
||||
$FUNCTION caller_builtin
|
||||
$DEPENDS_ON DEBUGGER
|
||||
$SHORT_DOC caller [EXPR]
|
||||
|
||||
Returns the context of the current subroutine call.
|
||||
|
||||
Without EXPR, returns "$line $filename". With EXPR,
|
||||
returns "$line $subroutine $filename"; this extra information
|
||||
can be used to provide a stack trace.
|
||||
|
||||
The value of EXPR indicates how many call frames to go back before the
|
||||
current one; the top frame is frame 0.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include "chartypes.h"
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# ifdef _MINIX
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include "../shell.h"
|
||||
#include "common.h"
|
||||
#include "builtext.h"
|
||||
#include "bashgetopt.h"
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
# include "builtins.h"
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
int
|
||||
caller_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
#if !defined (ARRAY_VARS)
|
||||
printf ("1 NULL\n");
|
||||
return (EXECUTION_FAILURE);
|
||||
#else
|
||||
SHELL_VAR *funcname_v, *bash_source_v, *bash_lineno_v;
|
||||
ARRAY *funcname_a, *bash_source_a, *bash_lineno_a;
|
||||
char *funcname_s, *source_s, *lineno_s;
|
||||
intmax_t num;
|
||||
|
||||
GET_ARRAY_FROM_VAR ("FUNCNAME", funcname_v, funcname_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a);
|
||||
|
||||
if (bash_lineno_a == 0 || array_empty (bash_lineno_a))
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
if (bash_source_a == 0 || array_empty (bash_source_a))
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
if (no_options (list))
|
||||
return (EX_USAGE);
|
||||
list = loptend; /* skip over possible `--' */
|
||||
|
||||
/* If there is no argument list, then give short form: line filename. */
|
||||
if (list == 0)
|
||||
{
|
||||
lineno_s = array_reference (bash_lineno_a, 0);
|
||||
source_s = array_reference (bash_source_a, 1);
|
||||
printf("%s %s\n", lineno_s ? lineno_s : "NULL", source_s ? source_s : "NULL");
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
if (funcname_a == 0 || array_empty (funcname_a))
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
if (legal_number (list->word->word, &num))
|
||||
{
|
||||
lineno_s = array_reference (bash_lineno_a, num);
|
||||
source_s = array_reference (bash_source_a, num+1);
|
||||
funcname_s = array_reference (funcname_a, num+1);
|
||||
|
||||
if (lineno_s == NULL|| source_s == NULL || funcname_s == NULL)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
printf("%s %s %s\n", lineno_s, funcname_s, source_s);
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
return (EXECUTION_SUCCESS);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
static char *caller_doc[] = {
|
||||
N_("Returns the context of the current subroutine call."),
|
||||
N_(" "),
|
||||
N_("Without EXPR, returns \"$line $filename\". With EXPR,"),
|
||||
N_("returns \"$line $subroutine $filename\"; this extra information"),
|
||||
N_("can be used used to provide a stack trace."),
|
||||
N_(" "),
|
||||
N_("The value of EXPR indicates how many call frames to go back before the"),
|
||||
N_("current one; the top frame is frame 0."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
struct builtin caller_struct = {
|
||||
"caller",
|
||||
caller_builtin,
|
||||
BUILTIN_ENABLED,
|
||||
caller_doc,
|
||||
"caller [EXPR]",
|
||||
0
|
||||
};
|
||||
|
||||
#endif /* LOADABLE_BUILTIN */
|
||||
@@ -49,6 +49,12 @@ $END
|
||||
# define INT_MIN (-2147483647-1)
|
||||
#endif
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <chartypes.h>
|
||||
|
||||
@@ -151,6 +157,14 @@ extern int errno;
|
||||
#define SKIP1 "#'-+ 0"
|
||||
#define LENMODS "hjlLtz"
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
# if defined (PREFER_STDARG)
|
||||
extern int asprintf __P((char **, const char *, ...));
|
||||
# else
|
||||
extern int asprintf __P((char **, const char *, va_alist));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static void printf_erange __P((char *));
|
||||
static int printstr __P((char *, char *, int, int, int));
|
||||
static int tescape __P((char *, char *, int *));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+52
-52
@@ -660,66 +660,66 @@ get_directory_stack (flags)
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
char * const dirs_doc[] = {
|
||||
N_("Display the list of currently remembered directories. Directories"),
|
||||
N_("find their way onto the list with the `pushd' command; you can get"),
|
||||
N_("back up through the list with the `popd' command."),
|
||||
N_(" "),
|
||||
N_("The -l flag specifies that `dirs' should not print shorthand versions"),
|
||||
N_("of directories which are relative to your home directory. This means"),
|
||||
N_("that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag"),
|
||||
N_("causes `dirs' to print the directory stack with one entry per line,"),
|
||||
N_("prepending the directory name with its position in the stack. The -p"),
|
||||
N_("flag does the same thing, but the stack position is not prepended."),
|
||||
N_("The -c flag clears the directory stack by deleting all of the elements."),
|
||||
N_(" "),
|
||||
N_("+N displays the Nth entry counting from the left of the list shown by"),
|
||||
N_(" dirs when invoked without options, starting with zero."),
|
||||
N_(" "),
|
||||
N_("-N displays the Nth entry counting from the right of the list shown by"),
|
||||
N_(" dirs when invoked without options, starting with zero."),
|
||||
N_("Display the list of currently remembered directories. Directories\n\
|
||||
find their way onto the list with the `pushd' command; you can get\n\
|
||||
back up through the list with the `popd' command.\n\
|
||||
\n\
|
||||
The -l flag specifies that `dirs' should not print shorthand versions\n\
|
||||
of directories which are relative to your home directory. This means\n\
|
||||
that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag\n\
|
||||
causes `dirs' to print the directory stack with one entry per line,\n\
|
||||
prepending the directory name with its position in the stack. The -p\n\
|
||||
flag does the same thing, but the stack position is not prepended.\n\
|
||||
The -c flag clears the directory stack by deleting all of the elements.\n\
|
||||
\n\
|
||||
+N displays the Nth entry counting from the left of the list shown by\n\
|
||||
dirs when invoked without options, starting with zero.\n\
|
||||
\n\
|
||||
-N displays the Nth entry counting from the right of the list shown by\n\
|
||||
dirs when invoked without options, starting with zero."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
char * const pushd_doc[] = {
|
||||
N_("Adds a directory to the top of the directory stack, or rotates"),
|
||||
N_("the stack, making the new top of the stack the current working"),
|
||||
N_("directory. With no arguments, exchanges the top two directories."),
|
||||
N_(" "),
|
||||
N_("+N Rotates the stack so that the Nth directory (counting"),
|
||||
N_(" from the left of the list shown by `dirs', starting with"),
|
||||
N_(" zero) is at the top."),
|
||||
N_(" "),
|
||||
N_("-N Rotates the stack so that the Nth directory (counting"),
|
||||
N_(" from the right of the list shown by `dirs', starting with"),
|
||||
N_(" zero) is at the top."),
|
||||
N_(" "),
|
||||
N_("-n suppress the normal change of directory when adding directories"),
|
||||
N_(" to the stack, so only the stack is manipulated."),
|
||||
N_(" "),
|
||||
N_("dir adds DIR to the directory stack at the top, making it the"),
|
||||
N_(" new current working directory."),
|
||||
N_(" "),
|
||||
N_("You can see the directory stack with the `dirs' command."),
|
||||
N_("Adds a directory to the top of the directory stack, or rotates\n\
|
||||
the stack, making the new top of the stack the current working\n\
|
||||
directory. With no arguments, exchanges the top two directories.\n\
|
||||
\n\
|
||||
+N Rotates the stack so that the Nth directory (counting\n\
|
||||
from the left of the list shown by `dirs', starting with\n\
|
||||
zero) is at the top.\n\
|
||||
\n\
|
||||
-N Rotates the stack so that the Nth directory (counting\n\
|
||||
from the right of the list shown by `dirs', starting with\n\
|
||||
zero) is at the top.\n\
|
||||
\n\
|
||||
-n suppress the normal change of directory when adding directories\n\
|
||||
to the stack, so only the stack is manipulated.\n\
|
||||
\n\
|
||||
dir adds DIR to the directory stack at the top, making it the\n\
|
||||
new current working directory.\n\
|
||||
\n\
|
||||
You can see the directory stack with the `dirs' command."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
char * const popd_doc[] = {
|
||||
N_("Removes entries from the directory stack. With no arguments,"),
|
||||
N_("removes the top directory from the stack, and cd's to the new"),
|
||||
N_("top directory."),
|
||||
N_(" "),
|
||||
N_("+N removes the Nth entry counting from the left of the list"),
|
||||
N_(" shown by `dirs', starting with zero. For example: `popd +0'"),
|
||||
N_(" removes the first directory, `popd +1' the second."),
|
||||
N_(" "),
|
||||
N_("-N removes the Nth entry counting from the right of the list"),
|
||||
N_(" shown by `dirs', starting with zero. For example: `popd -0'"),
|
||||
N_(" removes the last directory, `popd -1' the next to last."),
|
||||
N_(" "),
|
||||
N_("-n suppress the normal change of directory when removing directories"),
|
||||
N_(" from the stack, so only the stack is manipulated."),
|
||||
N_(" "),
|
||||
N_("You can see the directory stack with the `dirs' command."),
|
||||
N_("Removes entries from the directory stack. With no arguments,\n\
|
||||
removes the top directory from the stack, and cd's to the new\n\
|
||||
top directory.\n\
|
||||
\n\
|
||||
+N removes the Nth entry counting from the left of the list\n\
|
||||
shown by `dirs', starting with zero. For example: `popd +0'\n\
|
||||
removes the first directory, `popd +1' the second.\n\
|
||||
\n\
|
||||
-N removes the Nth entry counting from the right of the list\n\
|
||||
shown by `dirs', starting with zero. For example: `popd -0'\n\
|
||||
removes the last directory, `popd -1' the next to last.\n\
|
||||
\n\
|
||||
-n suppress the normal change of directory when removing directories\n\
|
||||
from the stack, so only the stack is manipulated.\n\
|
||||
\n\
|
||||
You can see the directory stack with the `dirs' command."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,754 @@
|
||||
This file is pushd.def, from which is created pushd.c. It implements the
|
||||
builtins "pushd", "popd", and "dirs" in Bash.
|
||||
|
||||
Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
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
|
||||
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
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
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
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
$PRODUCES pushd.c
|
||||
|
||||
$BUILTIN pushd
|
||||
$FUNCTION pushd_builtin
|
||||
$DEPENDS_ON PUSHD_AND_POPD
|
||||
$SHORT_DOC pushd [dir | +N | -N] [-n]
|
||||
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.
|
||||
$END
|
||||
|
||||
$BUILTIN popd
|
||||
$FUNCTION popd_builtin
|
||||
$DEPENDS_ON PUSHD_AND_POPD
|
||||
$SHORT_DOC popd [+N | -N] [-n]
|
||||
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.
|
||||
$END
|
||||
|
||||
$BUILTIN dirs
|
||||
$FUNCTION dirs_builtin
|
||||
$DEPENDS_ON PUSHD_AND_POPD
|
||||
$SHORT_DOC dirs [-clpv] [+N] [-N]
|
||||
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.
|
||||
$END
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (PUSHD_AND_POPD)
|
||||
#include <stdio.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 "../bashansi.h"
|
||||
#include "../bashintl.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <tilde/tilde.h>
|
||||
|
||||
#include "../shell.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 */
|
||||
|
||||
/* The list of remembered directories. */
|
||||
static char **pushd_directory_list = (char **)NULL;
|
||||
|
||||
/* Number of existing slots in this list. */
|
||||
static int directory_list_size;
|
||||
|
||||
/* Offset to the end of the list. */
|
||||
static int directory_list_offset;
|
||||
|
||||
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((intmax_t, int, int *));
|
||||
|
||||
#define NOCD 0x01
|
||||
#define ROTATE 0x02
|
||||
#define LONGFORM 0x04
|
||||
#define CLEARSTAK 0x08
|
||||
|
||||
int
|
||||
pushd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
WORD_LIST *orig_list;
|
||||
char *temp, *current_directory, *top;
|
||||
int j, flags, skipopt;
|
||||
intmax_t num;
|
||||
char direction;
|
||||
|
||||
orig_list = list;
|
||||
if (list && list->word && ISOPTION (list->word->word, '-'))
|
||||
{
|
||||
list = list->next;
|
||||
skipopt = 1;
|
||||
}
|
||||
else
|
||||
skipopt = 0;
|
||||
|
||||
/* If there is no argument list then switch current and
|
||||
top of list. */
|
||||
if (list == 0)
|
||||
{
|
||||
if (directory_list_offset == 0)
|
||||
{
|
||||
builtin_error (_("no other directory"));
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
current_directory = get_working_directory ("pushd");
|
||||
if (current_directory == 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
j = directory_list_offset - 1;
|
||||
temp = pushd_directory_list[j];
|
||||
pushd_directory_list[j] = current_directory;
|
||||
j = change_to_temp (temp);
|
||||
free (temp);
|
||||
return j;
|
||||
}
|
||||
|
||||
for (flags = 0; skipopt == 0 && list; list = list->next)
|
||||
{
|
||||
if (ISOPTION (list->word->word, 'n'))
|
||||
{
|
||||
flags |= NOCD;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, '-'))
|
||||
{
|
||||
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 (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||
{
|
||||
if (legal_number (list->word->word + 1, &num) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (direction == '-')
|
||||
num = directory_list_offset - num;
|
||||
|
||||
if (num > directory_list_offset || num < 0)
|
||||
{
|
||||
pushd_error (directory_list_offset, list->word->word);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
flags |= ROTATE;
|
||||
}
|
||||
else if (*list->word->word == '-')
|
||||
{
|
||||
sh_invalidopt (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & ROTATE)
|
||||
{
|
||||
/* Rotate the stack num times. Remember, the current
|
||||
directory acts like it is part of the stack. */
|
||||
temp = get_working_directory ("pushd");
|
||||
|
||||
if (num == 0)
|
||||
{
|
||||
j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS;
|
||||
free (temp);
|
||||
return j;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
top = pushd_directory_list[directory_list_offset - 1];
|
||||
|
||||
for (j = directory_list_offset - 2; j > -1; j--)
|
||||
pushd_directory_list[j + 1] = pushd_directory_list[j];
|
||||
|
||||
pushd_directory_list[j + 1] = temp;
|
||||
|
||||
temp = top;
|
||||
num--;
|
||||
}
|
||||
while (num);
|
||||
|
||||
j = ((flags & NOCD) == 0) ? change_to_temp (temp) : EXECUTION_SUCCESS;
|
||||
free (temp);
|
||||
return j;
|
||||
}
|
||||
|
||||
if (list == 0)
|
||||
return (EXECUTION_SUCCESS);
|
||||
|
||||
/* Change to the directory in list->word->word. Save the current
|
||||
directory on the top of the stack. */
|
||||
current_directory = get_working_directory ("pushd");
|
||||
if (current_directory == 0)
|
||||
return (EXECUTION_FAILURE);
|
||||
|
||||
j = ((flags & NOCD) == 0) ? cd_builtin (skipopt ? orig_list : list) : EXECUTION_SUCCESS;
|
||||
if (j == EXECUTION_SUCCESS)
|
||||
{
|
||||
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
|
||||
{
|
||||
free (current_directory);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pop the directory stack, and then change to the new top of the stack.
|
||||
If LIST is non-null it should consist of a word +N or -N, which says
|
||||
what element to delete from the stack. The default is the top one. */
|
||||
int
|
||||
popd_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
register int i;
|
||||
intmax_t which;
|
||||
int flags;
|
||||
char direction;
|
||||
char *which_word;
|
||||
|
||||
which_word = (char *)NULL;
|
||||
for (flags = 0, which = 0, direction = '+'; list; list = list->next)
|
||||
{
|
||||
if (ISOPTION (list->word->word, 'n'))
|
||||
{
|
||||
flags |= NOCD;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, '-'))
|
||||
{
|
||||
list = list->next;
|
||||
break;
|
||||
}
|
||||
else if (((direction = list->word->word[0]) == '+') || direction == '-')
|
||||
{
|
||||
if (legal_number (list->word->word + 1, &which) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
which_word = list->word->word;
|
||||
}
|
||||
else if (*list->word->word == '-')
|
||||
{
|
||||
sh_invalidopt (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (which > directory_list_offset || (directory_list_offset == 0 && which == 0))
|
||||
{
|
||||
pushd_error (directory_list_offset, which_word ? which_word : "");
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
/* Handle case of no specification, or top of stack specification. */
|
||||
if ((direction == '+' && which == 0) ||
|
||||
(direction == '-' && which == directory_list_offset))
|
||||
{
|
||||
i = ((flags & NOCD) == 0) ? cd_to_string (pushd_directory_list[directory_list_offset - 1])
|
||||
: EXECUTION_SUCCESS;
|
||||
if (i != EXECUTION_SUCCESS)
|
||||
return (i);
|
||||
free (pushd_directory_list[--directory_list_offset]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Since an offset other than the top directory was specified,
|
||||
remove that directory from the list and shift the remainder
|
||||
of the list into place. */
|
||||
i = (direction == '+') ? directory_list_offset - which : which;
|
||||
free (pushd_directory_list[i]);
|
||||
directory_list_offset--;
|
||||
|
||||
/* Shift the remainder of the list into place. */
|
||||
for (; i < directory_list_offset; i++)
|
||||
pushd_directory_list[i] = pushd_directory_list[i + 1];
|
||||
}
|
||||
|
||||
dirs_builtin ((WORD_LIST *)NULL);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
/* Print the current list of directories on the directory stack. */
|
||||
int
|
||||
dirs_builtin (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
int flags, desired_index, index_flag, vflag;
|
||||
intmax_t i;
|
||||
char *temp, *w;
|
||||
|
||||
for (flags = vflag = index_flag = 0, desired_index = -1, w = ""; list; list = list->next)
|
||||
{
|
||||
if (ISOPTION (list->word->word, 'l'))
|
||||
{
|
||||
flags |= LONGFORM;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, 'c'))
|
||||
{
|
||||
flags |= CLEARSTAK;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, 'v'))
|
||||
{
|
||||
vflag |= 2;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, 'p'))
|
||||
{
|
||||
vflag |= 1;
|
||||
}
|
||||
else if (ISOPTION (list->word->word, '-'))
|
||||
{
|
||||
list = list->next;
|
||||
break;
|
||||
}
|
||||
else if (*list->word->word == '+' || *list->word->word == '-')
|
||||
{
|
||||
int sign;
|
||||
if (legal_number (w = list->word->word + 1, &i) == 0)
|
||||
{
|
||||
sh_invalidnum (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
sign = (*list->word->word == '+') ? 1 : -1;
|
||||
desired_index = get_dirstack_index (i, sign, &index_flag);
|
||||
}
|
||||
else
|
||||
{
|
||||
sh_invalidopt (list->word->word);
|
||||
builtin_usage ();
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & CLEARSTAK)
|
||||
{
|
||||
clear_directory_stack ();
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
if (index_flag && (desired_index < 0 || desired_index > directory_list_offset))
|
||||
{
|
||||
pushd_error (directory_list_offset, w);
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
#define DIRSTACK_FORMAT(temp) \
|
||||
(flags & LONGFORM) ? temp : polite_directory_format (temp)
|
||||
|
||||
/* The first directory printed is always the current working directory. */
|
||||
if (index_flag == 0 || (index_flag == 1 && desired_index == 0))
|
||||
{
|
||||
temp = get_working_directory ("dirs");
|
||||
if (temp == 0)
|
||||
temp = savestring (_("<no current directory>"));
|
||||
if (vflag & 2)
|
||||
printf ("%2d %s", 0, DIRSTACK_FORMAT (temp));
|
||||
else
|
||||
printf ("%s", DIRSTACK_FORMAT (temp));
|
||||
free (temp);
|
||||
if (index_flag)
|
||||
{
|
||||
putchar ('\n');
|
||||
return EXECUTION_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
#define DIRSTACK_ENTRY(i) \
|
||||
(flags & LONGFORM) ? pushd_directory_list[i] \
|
||||
: polite_directory_format (pushd_directory_list[i])
|
||||
|
||||
/* Now print the requested directory stack entries. */
|
||||
if (index_flag)
|
||||
{
|
||||
if (vflag & 2)
|
||||
printf ("%2d %s", directory_list_offset - desired_index,
|
||||
DIRSTACK_ENTRY (desired_index));
|
||||
else
|
||||
printf ("%s", DIRSTACK_ENTRY (desired_index));
|
||||
}
|
||||
else
|
||||
for (i = directory_list_offset - 1; i >= 0; i--)
|
||||
if (vflag >= 2)
|
||||
printf ("\n%2d %s", directory_list_offset - (int)i, DIRSTACK_ENTRY (i));
|
||||
else
|
||||
printf ("%s%s", (vflag & 1) ? "\n" : " ", DIRSTACK_ENTRY (i));
|
||||
|
||||
putchar ('\n');
|
||||
fflush (stdout);
|
||||
return (EXECUTION_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
pushd_error (offset, arg)
|
||||
int offset;
|
||||
char *arg;
|
||||
{
|
||||
if (offset == 0)
|
||||
builtin_error ("directory stack empty");
|
||||
else
|
||||
sh_erange (arg, "directory stack index");
|
||||
}
|
||||
|
||||
static void
|
||||
clear_directory_stack ()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < directory_list_offset; i++)
|
||||
free (pushd_directory_list[i]);
|
||||
directory_list_offset = 0;
|
||||
}
|
||||
|
||||
/* Switch to the directory in NAME. This uses the cd_builtin to do the work,
|
||||
so if the result is EXECUTION_FAILURE then an error message has already
|
||||
been printed. */
|
||||
static int
|
||||
cd_to_string (name)
|
||||
char *name;
|
||||
{
|
||||
WORD_LIST *tlist;
|
||||
WORD_LIST *dir;
|
||||
int result;
|
||||
|
||||
dir = make_word_list (make_word (name), NULL);
|
||||
tlist = make_word_list (make_word ("--"), dir);
|
||||
result = cd_builtin (tlist);
|
||||
dispose_words (tlist);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static int
|
||||
change_to_temp (temp)
|
||||
char *temp;
|
||||
{
|
||||
int tt;
|
||||
|
||||
tt = temp ? cd_to_string (temp) : EXECUTION_FAILURE;
|
||||
|
||||
if (tt == EXECUTION_SUCCESS)
|
||||
dirs_builtin ((WORD_LIST *)NULL);
|
||||
|
||||
return (tt);
|
||||
}
|
||||
|
||||
static void
|
||||
add_dirstack_element (dir)
|
||||
char *dir;
|
||||
{
|
||||
if (directory_list_offset == directory_list_size)
|
||||
pushd_directory_list = strvec_resize (pushd_directory_list, directory_list_size += 10);
|
||||
pushd_directory_list[directory_list_offset++] = dir;
|
||||
}
|
||||
|
||||
static int
|
||||
get_dirstack_index (ind, sign, indexp)
|
||||
intmax_t ind;
|
||||
int sign, *indexp;
|
||||
{
|
||||
if (indexp)
|
||||
*indexp = sign > 0 ? 1 : 2;
|
||||
|
||||
/* dirs +0 prints the current working directory. */
|
||||
/* dirs -0 prints last element in directory stack */
|
||||
if (ind == 0 && sign > 0)
|
||||
return 0;
|
||||
else if (ind == directory_list_offset)
|
||||
{
|
||||
if (indexp)
|
||||
*indexp = sign > 0 ? 2 : 1;
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
intmax_t 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)
|
||||
intmax_t ind;
|
||||
int sign;
|
||||
{
|
||||
int i;
|
||||
|
||||
i = get_dirstack_index (ind, sign, (int *)NULL);
|
||||
return (i < 0 || i > directory_list_offset) ? (char *)NULL
|
||||
: pushd_directory_list[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
set_dirstack_element (ind, sign, value)
|
||||
intmax_t ind;
|
||||
int sign;
|
||||
char *value;
|
||||
{
|
||||
int i;
|
||||
|
||||
i = get_dirstack_index (ind, sign, (int *)NULL);
|
||||
if (ind == 0 || i < 0 || i > directory_list_offset)
|
||||
return;
|
||||
free (pushd_directory_list[i]);
|
||||
pushd_directory_list[i] = savestring (value);
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
get_directory_stack (flags)
|
||||
int flags;
|
||||
{
|
||||
register int i;
|
||||
WORD_LIST *ret;
|
||||
char *d, *t;
|
||||
|
||||
for (ret = (WORD_LIST *)NULL, i = 0; i < directory_list_offset; i++)
|
||||
{
|
||||
d = (flags&1) ? polite_directory_format (pushd_directory_list[i])
|
||||
: pushd_directory_list[i];
|
||||
ret = make_word_list (make_word (d), ret);
|
||||
}
|
||||
/* Now the current directory. */
|
||||
d = get_working_directory ("dirstack");
|
||||
i = 0; /* sentinel to decide whether or not to free d */
|
||||
if (d == 0)
|
||||
d = ".";
|
||||
else
|
||||
{
|
||||
t = polite_directory_format (d);
|
||||
/* polite_directory_format sometimes returns its argument unchanged.
|
||||
If it does not, we can free d right away. If it does, we need to
|
||||
mark d to be deleted later. */
|
||||
if (t != d)
|
||||
{
|
||||
free (d);
|
||||
d = t;
|
||||
}
|
||||
else /* t == d, so d is what we want */
|
||||
i = 1;
|
||||
}
|
||||
ret = make_word_list (make_word (d), ret);
|
||||
if (i)
|
||||
free (d);
|
||||
return ret; /* was (REVERSE_LIST (ret, (WORD_LIST *)); */
|
||||
}
|
||||
|
||||
#ifdef LOADABLE_BUILTIN
|
||||
char * const dirs_doc[] = {
|
||||
N_("Display the list of currently remembered directories. Directories"),
|
||||
N_("find their way onto the list with the `pushd' command; you can get"),
|
||||
N_("back up through the list with the `popd' command."),
|
||||
N_(" "),
|
||||
N_("The -l flag specifies that `dirs' should not print shorthand versions"),
|
||||
N_("of directories which are relative to your home directory. This means"),
|
||||
N_("that `~/bin' might be displayed as `/homes/bfox/bin'. The -v flag"),
|
||||
N_("causes `dirs' to print the directory stack with one entry per line,"),
|
||||
N_("prepending the directory name with its position in the stack. The -p"),
|
||||
N_("flag does the same thing, but the stack position is not prepended."),
|
||||
N_("The -c flag clears the directory stack by deleting all of the elements."),
|
||||
N_(" "),
|
||||
N_("+N displays the Nth entry counting from the left of the list shown by"),
|
||||
N_(" dirs when invoked without options, starting with zero."),
|
||||
N_(" "),
|
||||
N_("-N displays the Nth entry counting from the right of the list shown by"),
|
||||
N_(" dirs when invoked without options, starting with zero."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
char * const pushd_doc[] = {
|
||||
N_("Adds a directory to the top of the directory stack, or rotates"),
|
||||
N_("the stack, making the new top of the stack the current working"),
|
||||
N_("directory. With no arguments, exchanges the top two directories."),
|
||||
N_(" "),
|
||||
N_("+N Rotates the stack so that the Nth directory (counting"),
|
||||
N_(" from the left of the list shown by `dirs', starting with"),
|
||||
N_(" zero) is at the top."),
|
||||
N_(" "),
|
||||
N_("-N Rotates the stack so that the Nth directory (counting"),
|
||||
N_(" from the right of the list shown by `dirs', starting with"),
|
||||
N_(" zero) is at the top."),
|
||||
N_(" "),
|
||||
N_("-n suppress the normal change of directory when adding directories"),
|
||||
N_(" to the stack, so only the stack is manipulated."),
|
||||
N_(" "),
|
||||
N_("dir adds DIR to the directory stack at the top, making it the"),
|
||||
N_(" new current working directory."),
|
||||
N_(" "),
|
||||
N_("You can see the directory stack with the `dirs' command."),
|
||||
(char *)NULL
|
||||
};
|
||||
|
||||
char * const popd_doc[] = {
|
||||
N_("Removes entries from the directory stack. With no arguments,"),
|
||||
N_("removes the top directory from the stack, and cd's to the new"),
|
||||
N_("top directory."),
|
||||
N_(" "),
|
||||
N_("+N removes the Nth entry counting from the left of the list"),
|
||||
N_(" shown by `dirs', starting with zero. For example: `popd +0'"),
|
||||
N_(" removes the first directory, `popd +1' the second."),
|
||||
N_(" "),
|
||||
N_("-N removes the Nth entry counting from the right of the list"),
|
||||
N_(" shown by `dirs', starting with zero. For example: `popd -0'"),
|
||||
N_(" removes the last directory, `popd -1' the next to last."),
|
||||
N_(" "),
|
||||
N_("-n suppress the normal change of directory when removing directories"),
|
||||
N_(" from the stack, so only the stack is manipulated."),
|
||||
N_(" "),
|
||||
N_("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 */
|
||||
+4
-2
@@ -1410,7 +1410,9 @@ An array variable containing the names of all shell functions
|
||||
currently in the execution call stack.
|
||||
The element with index 0 is the name of any currently-executing
|
||||
shell function.
|
||||
The bottom-most element is "main".
|
||||
The bottom-most element is
|
||||
.if t \f(CW"main"\fP.
|
||||
.if n "main".
|
||||
This variable exists only when a shell function is executing.
|
||||
Assignments to
|
||||
.SM
|
||||
@@ -6711,7 +6713,7 @@ become the arguments to \fIcommand\fP.
|
||||
If the
|
||||
.B \-l
|
||||
option is supplied,
|
||||
the shell places a dash at the beginning of the zeroth arg passed to
|
||||
the shell places a dash at the beginning of the zeroth argument passed to
|
||||
.IR command .
|
||||
This is what
|
||||
.IR login (1)
|
||||
|
||||
+12
-12
@@ -164,7 +164,7 @@ and symbols are expanded to create larger expressions.
|
||||
A Unix shell is both a command interpreter and a programming
|
||||
language. As a command interpreter, the shell provides the user
|
||||
interface to the rich set of @sc{gnu} utilities. The programming
|
||||
language features allow these utilitites to be combined.
|
||||
language features allow these utilities to be combined.
|
||||
Files containing commands can be created, and become
|
||||
commands themselves. These new commands have the same status as
|
||||
system commands in directories such as @file{/bin}, allowing users
|
||||
@@ -288,7 +288,7 @@ group @sc{id}.
|
||||
|
||||
@item process group ID
|
||||
@cindex process group ID
|
||||
A unique identifer that represents a @code{process group}
|
||||
A unique identifier that represents a @code{process group}
|
||||
during its lifetime.
|
||||
|
||||
@item reserved word
|
||||
@@ -897,7 +897,7 @@ The list of words following @code{in} is expanded, generating a list
|
||||
of items. The set of expanded words is printed on the standard
|
||||
error output stream, each preceded by a number. If the
|
||||
@samp{in @var{words}} is omitted, the positional parameters are printed,
|
||||
as if @samp{in "$@@"} had been specifed.
|
||||
as if @samp{in "$@@"} had been specified.
|
||||
The @env{PS3} prompt is then displayed and a line is read from the
|
||||
standard input.
|
||||
If the line consists of a number corresponding to one of the displayed
|
||||
@@ -1377,7 +1377,7 @@ This mechanism is similar to
|
||||
@var{filename expansion} (@pxref{Filename Expansion}),
|
||||
but the file names generated need not exist.
|
||||
Patterns to be brace expanded take the form of an optional @var{preamble},
|
||||
followed by either a series of comma-separated strings or a sequnce expression
|
||||
followed by either a series of comma-separated strings or a seqeunce expression
|
||||
between a pair of braces,
|
||||
followed by an optional @var{postscript}.
|
||||
The preamble is prefixed to each string contained within the braces, and
|
||||
@@ -2717,7 +2717,7 @@ exec [-cl] [-a @var{name}] [@var{command} [@var{arguments}]]
|
||||
If @var{command}
|
||||
is supplied, it replaces the shell without creating a new process.
|
||||
If the @option{-l} option is supplied, the shell places a dash at the
|
||||
beginning of the zeroth arg passed to @var{command}.
|
||||
beginning of the zeroth argument passed to @var{command}.
|
||||
This is what the @code{login} program does.
|
||||
The @option{-c} option causes @var{command} to be executed with an empty
|
||||
environment.
|
||||
@@ -3110,7 +3110,7 @@ key and function bindings,
|
||||
bind a key sequence to a Readline function or macro,
|
||||
or set a Readline variable.
|
||||
Each non-option argument is a command as it would appear in a
|
||||
a Readline initialization file (@pxref{Readline Init File}),
|
||||
Readline initialization file (@pxref{Readline Init File}),
|
||||
but each binding or command must be passed as a separate argument; e.g.,
|
||||
@samp{"\C-x\C-r":re-read-init-file}.
|
||||
Options, if supplied, have the following meanings:
|
||||
@@ -4476,7 +4476,7 @@ An array variable containing the names of all shell functions
|
||||
currently in the execution call stack.
|
||||
The element with index 0 is the name of any currently-executing
|
||||
shell function.
|
||||
The bottom-most element is "main".
|
||||
The bottom-most element is @code{"main"}.
|
||||
This variable exists only when a shell function is executing.
|
||||
Assignments to @env{FUNCNAME} have no effect and return an error status.
|
||||
If @env{FUNCNAME} is unset, it loses its special properties, even if
|
||||
@@ -4796,7 +4796,7 @@ The @code{select} command (@pxref{Conditional Constructs}) terminates
|
||||
if input does not arrive after @code{TMOUT} seconds when input is coming
|
||||
from a terminal.
|
||||
|
||||
In an interative shell, the value is interpreted as
|
||||
In an interactive shell, the value is interpreted as
|
||||
the number of seconds to wait for input after issuing the primary
|
||||
prompt when the shell is interactive.
|
||||
Bash terminates after that number of seconds if input does
|
||||
@@ -4866,7 +4866,7 @@ Equivalent to @option{-D} except for the output format.
|
||||
Equivalent to @option{-D}.
|
||||
|
||||
@item --help
|
||||
Display a usage message on standard output and exit sucessfully.
|
||||
Display a usage message on standard output and exit successfully.
|
||||
|
||||
@item --init-file @var{filename}
|
||||
@itemx --rcfile @var{filename}
|
||||
@@ -4995,7 +4995,7 @@ in the script. If no commands are executed, the exit status is 0.
|
||||
@section Bash Startup Files
|
||||
@cindex startup files
|
||||
|
||||
This section describs how Bash executes its startup files.
|
||||
This section describes how Bash executes its startup files.
|
||||
If any of the files exist but cannot be read, Bash reports an error.
|
||||
Tildes are expanded in file names as described above under
|
||||
Tilde Expansion (@pxref{Tilde Expansion}).
|
||||
@@ -5120,7 +5120,7 @@ the same, but the effective user id is not reset.
|
||||
|
||||
An interactive shell
|
||||
is one started without non-option arguments, unless @option{-s} is
|
||||
specified, without specifiying the @option{-c} option, and
|
||||
specified, without specifying the @option{-c} option, and
|
||||
whose input and error output are both
|
||||
connected to terminals (as determined by @code{isatty(3)}),
|
||||
or one started with the @option{-i} option.
|
||||
@@ -5213,7 +5213,7 @@ In the absence of any traps, @code{SIGINT} is caught and handled
|
||||
|
||||
@item
|
||||
An interactive login shell sends a @code{SIGHUP} to all jobs on exit
|
||||
if the @code{hupoxexit} shell option has been enabled (@pxref{Signals}).
|
||||
if the @code{huponexit} shell option has been enabled (@pxref{Signals}).
|
||||
|
||||
@item
|
||||
The @option{-n} invocation option is ignored, and @samp{set -n} has
|
||||
|
||||
@@ -1772,7 +1772,7 @@ make_child (command, async_p)
|
||||
#endif /* PGRP_PIPE */
|
||||
|
||||
if (async_p)
|
||||
last_asynchronous_pid = mypid;
|
||||
last_asynchronous_pid = mypid; /* XXX */
|
||||
#if defined (RECYCLES_PIDS)
|
||||
else if (last_asynchronous_pid == mypid)
|
||||
/* Avoid pid aliasing. 1 seems like a safe, unusual pid value. */
|
||||
|
||||
+35
-13
@@ -58,6 +58,11 @@
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
# undef HAVE_SNPRINTF
|
||||
# undef HAVE_ASPRINTF
|
||||
#endif
|
||||
|
||||
#if defined(DRIVER) && !defined(HAVE_CONFIG_H)
|
||||
#define HAVE_LONG_LONG
|
||||
#define HAVE_LONG_DOUBLE
|
||||
@@ -471,6 +476,8 @@ pow_10(n)
|
||||
10^x ~= r
|
||||
* log_10(200) = 2;
|
||||
* log_10(250) = 2;
|
||||
*
|
||||
* NOTE: do not call this with r == 0 -- an infinite loop results.
|
||||
*/
|
||||
static int
|
||||
log_10(r)
|
||||
@@ -576,8 +583,11 @@ numtoa(number, base, precision, fract)
|
||||
{
|
||||
integral_part[0] = '0';
|
||||
integral_part[1] = '\0';
|
||||
fraction_part[0] = '0';
|
||||
fraction_part[1] = '\0';
|
||||
/* The fractional part has to take the precision into account */
|
||||
for (ch = 0; ch < precision-1; ch++)
|
||||
fraction_part[ch] = '0';
|
||||
fraction_part[ch] = '0';
|
||||
fraction_part[ch+1] = '\0';
|
||||
if (fract)
|
||||
*fract = fraction_part;
|
||||
return integral_part;
|
||||
@@ -805,6 +815,7 @@ pointer(p, d)
|
||||
PUT_CHAR(*tmp, p);
|
||||
tmp++;
|
||||
}
|
||||
|
||||
PAD_LEFT(p);
|
||||
}
|
||||
|
||||
@@ -972,11 +983,21 @@ floating(p, d)
|
||||
if ((p->flags & PF_THOUSANDS) && grouping && (t = groupnum (tmp)))
|
||||
tmp = t;
|
||||
|
||||
if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
|
||||
{
|
||||
/* smash the trailing zeros unless altform */
|
||||
for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
|
||||
tmp2[i] = '\0';
|
||||
if (tmp2[0] == '\0')
|
||||
p->precision = 0;
|
||||
}
|
||||
|
||||
/* calculate the padding. 1 for the dot */
|
||||
p->width = p->width -
|
||||
((d > 0. && p->justify == RIGHT) ? 1:0) -
|
||||
((p->flags & PF_SPACE) ? 1:0) -
|
||||
strlen(tmp) - p->precision - 1;
|
||||
strlen(tmp) - p->precision -
|
||||
((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
|
||||
PAD_RIGHT(p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
PUT_SPACE(d, p, 0.);
|
||||
@@ -991,11 +1012,6 @@ floating(p, d)
|
||||
if (p->precision != 0 || (p->flags & PF_ALTFORM))
|
||||
PUT_CHAR(decpoint, p); /* put the '.' */
|
||||
|
||||
if ((*p->pf == 'g' || *p->pf == 'G') && (p->flags & PF_ALTFORM) == 0)
|
||||
/* smash the trailing zeros unless altform */
|
||||
for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--)
|
||||
tmp2[i] = '\0';
|
||||
|
||||
for (; *tmp2; tmp2++)
|
||||
PUT_CHAR(*tmp2, p); /* the fraction */
|
||||
|
||||
@@ -1011,14 +1027,19 @@ exponent(p, d)
|
||||
char *tmp, *tmp2;
|
||||
int j, i;
|
||||
|
||||
if (chkinfnan(p, d, 1) || chkinfnan(p, d, 2))
|
||||
if (d != 0 && (chkinfnan(p, d, 1) || chkinfnan(p, d, 2)))
|
||||
return; /* already printed nan or inf */
|
||||
|
||||
GETLOCALEDATA(decpoint, thoussep, grouping);
|
||||
DEF_PREC(p);
|
||||
j = log_10(d);
|
||||
d = d / pow_10(j); /* get the Mantissa */
|
||||
d = ROUND(d, p);
|
||||
if (d == 0.)
|
||||
j = 0;
|
||||
else
|
||||
{
|
||||
j = log_10(d);
|
||||
d = d / pow_10(j); /* get the Mantissa */
|
||||
d = ROUND(d, p);
|
||||
}
|
||||
tmp = dtoa(d, p->precision, &tmp2);
|
||||
|
||||
/* 1 for unit, 1 for the '.', 1 for 'e|E',
|
||||
@@ -1076,6 +1097,7 @@ exponent(p, d)
|
||||
PUT_CHAR(*tmp, p);
|
||||
tmp++;
|
||||
}
|
||||
|
||||
PAD_LEFT(p);
|
||||
}
|
||||
#endif
|
||||
@@ -1358,7 +1380,7 @@ conv_break:
|
||||
STAR_ARGS(data);
|
||||
DEF_PREC(data);
|
||||
d = GETDOUBLE(data);
|
||||
i = log_10(d);
|
||||
i = (d != 0.) ? log_10(d) : -1;
|
||||
/*
|
||||
* for '%g|%G' ANSI: use f if exponent
|
||||
* is in the range or [-4,p] exclusively
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+2159
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,2 +1,2 @@
|
||||
# Set of available languages.
|
||||
en@quot en@boldquot ru
|
||||
en@quot en@boldquot ru sv
|
||||
|
||||
+2568
File diff suppressed because it is too large
Load Diff
+2578
File diff suppressed because it is too large
Load Diff
+386
-376
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+461
-376
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+461
-376
File diff suppressed because it is too large
Load Diff
@@ -1426,7 +1426,7 @@ open_shell_script (script_name)
|
||||
/* Open the script. But try to move the file descriptor to a randomly
|
||||
large one, in the hopes that any descriptors used by the script will
|
||||
not match with ours. */
|
||||
fd = move_to_high_fd (fd, 0, -1);
|
||||
fd = move_to_high_fd (fd, 1, -1);
|
||||
|
||||
#if defined (__CYGWIN__) && defined (O_TEXT)
|
||||
setmode (fd, O_TEXT);
|
||||
|
||||
@@ -5707,6 +5707,11 @@ parameter_brace_patsub (varname, value, patsub, quoted)
|
||||
vtype &= ~VT_STARSUB;
|
||||
|
||||
mflags = 0;
|
||||
if (patsub && *patsub == '/')
|
||||
{
|
||||
mflags |= MATCH_GLOBREP;
|
||||
patsub++;
|
||||
}
|
||||
|
||||
/* Malloc this because expand_string_if_necessary or one of the expansion
|
||||
functions in its call chain may free it on a substitution error. */
|
||||
@@ -5741,13 +5746,12 @@ parameter_brace_patsub (varname, value, patsub, quoted)
|
||||
}
|
||||
|
||||
/* ksh93 doesn't allow the match specifier to be a part of the expanded
|
||||
pattern. This is an extension. */
|
||||
pattern. This is an extension. Make sure we don't anchor the pattern
|
||||
at the beginning or end of the string if we're doing global replacement,
|
||||
though. */
|
||||
p = pat;
|
||||
if (pat && pat[0] == '/')
|
||||
{
|
||||
mflags |= MATCH_GLOBREP|MATCH_ANY;
|
||||
p++;
|
||||
}
|
||||
if (mflags & MATCH_GLOBREP)
|
||||
mflags |= MATCH_ANY;
|
||||
else if (pat && pat[0] == '#')
|
||||
{
|
||||
mflags |= MATCH_BEG;
|
||||
|
||||
+2
-2
@@ -114,7 +114,7 @@ linux*-*|gnu*-*|k*bsd*-gnu-*)
|
||||
SHLIB_LIBVERSION='$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)'
|
||||
;;
|
||||
|
||||
freebsd2* | netbsd*)
|
||||
freebsd2*)
|
||||
SHOBJ_CFLAGS=-fpic
|
||||
SHOBJ_LD=ld
|
||||
SHOBJ_LDFLAGS='-x -Bshareable'
|
||||
@@ -182,7 +182,7 @@ darwin*|macosx*)
|
||||
SHLIB_LIBS='-lncurses' # see if -lcurses works on MacOS X 10.1
|
||||
;;
|
||||
|
||||
openbsd*)
|
||||
openbsd*|netbsd*)
|
||||
SHOBJ_CFLAGS=-fPIC
|
||||
SHOBJ_LD='${CC}'
|
||||
SHOBJ_LDFLAGS='-shared'
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
export THIS_SH PATH
|
||||
|
||||
rm -f /tmp/xx
|
||||
|
||||
/bin/sh "$@"
|
||||
@@ -33,5 +33,10 @@ returns: 0
|
||||
returns: 1
|
||||
returns: 0
|
||||
ok
|
||||
jbig2dec
|
||||
found 1
|
||||
libc
|
||||
found 2
|
||||
libc
|
||||
ok 42
|
||||
ok 43
|
||||
|
||||
@@ -154,6 +154,24 @@ if [[ $STR = $PAT ]]; then
|
||||
echo ok
|
||||
fi
|
||||
|
||||
# test the regular expression conditional operator
|
||||
[[ jbig2dec-0.9-i586-001.tgz =~ ([^-]+)-([^-]+)-([^-]+)-0*([1-9][0-9]*)\.tgz ]]
|
||||
echo ${BASH_REMATCH[1]}
|
||||
|
||||
LDD_BASH=" linux-gate.so.1 => (0xffffe000)
|
||||
libreadline.so.5 => /lib/libreadline.so.5 (0xb7f91000)
|
||||
libhistory.so.5 => /lib/libhistory.so.5 (0xb7f8a000)
|
||||
libncurses.so.5 => /lib/libncurses.so.5 (0xb7f55000)
|
||||
libdl.so.2 => /lib/libdl.so.2 (0xb7f51000)
|
||||
libc.so.6 => /lib/libc.so.6 (0xb7e34000)
|
||||
/lib/ld-linux.so.2 (0xb7fd0000)"
|
||||
|
||||
[[ "$LDD_BASH" =~ "libc" ]] && echo "found 1"
|
||||
echo ${BASH_REMATCH[@]}
|
||||
|
||||
[[ "$LDD_BASH" =~ libc ]] && echo "found 2"
|
||||
echo ${BASH_REMATCH[@]}
|
||||
|
||||
# bug in all versions up to and including bash-2.05b
|
||||
if [[ "123abc" == *?(a)bc ]]; then echo ok 42; else echo bad 42; fi
|
||||
if [[ "123abc" == *?(a)bc ]]; then echo ok 43; else echo bad 43; fi
|
||||
|
||||
Executable
+163
@@ -0,0 +1,163 @@
|
||||
#
|
||||
# the test/[ code is tested elsewhere, and the [[...]] just uses the same
|
||||
# code. this tests the special features of [[...]]
|
||||
#
|
||||
TDIR=/usr/homes/chet
|
||||
|
||||
# this one is straight out of the ksh88 book
|
||||
[[ foo > bar && $PWD -ef . ]]
|
||||
echo returns: $?
|
||||
|
||||
# [[ x ]] is equivalent to [[ -n x ]]
|
||||
[[ x ]]
|
||||
echo returns: $?
|
||||
|
||||
# [[ ! x ]] is equivalent to [[ ! -n x ]]
|
||||
[[ ! x ]]
|
||||
echo returns: $?
|
||||
|
||||
# ! binds tighter than test/[ -- it binds to a term, not an expression
|
||||
[[ ! x || x ]]
|
||||
echo returns: $?
|
||||
|
||||
# parenthesized terms didn't work right until post-2.04
|
||||
[[ a ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ (a) ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ -n a ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ (-n a) ]]
|
||||
echo returns: $?
|
||||
|
||||
# unset variables don't need to be quoted
|
||||
[[ -n $UNSET ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ -z $UNSET ]]
|
||||
echo returns: $?
|
||||
|
||||
# the ==/= and != operators do pattern matching
|
||||
[[ $TDIR == /usr/homes/* ]]
|
||||
echo returns: $?
|
||||
|
||||
# ...but you can quote any part of the pattern to have it matched as a string
|
||||
[[ $TDIR == /usr/homes/\* ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ $TDIR == '/usr/homes/*' ]]
|
||||
echo returns: $?
|
||||
|
||||
# if the first part of && fails, the second is not executed
|
||||
[[ -n $UNSET && $UNSET == foo ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ -z $UNSET && $UNSET == foo ]]
|
||||
echo returns: $?
|
||||
|
||||
# if the first part of || succeeds, the second is not executed
|
||||
[[ -z $UNSET || -d $PWD ]]
|
||||
echo returns: $?
|
||||
|
||||
# if the rhs were executed, it would be an error
|
||||
[[ -n $TDIR || $HOME -ef ${H*} ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ -n $TDIR && -z $UNSET || $HOME -ef ${H*} ]]
|
||||
echo returns: $?
|
||||
|
||||
# && has a higher parsing precedence than ||
|
||||
[[ -n $TDIR && -n $UNSET || $TDIR -ef . ]]
|
||||
echo returns: $?
|
||||
|
||||
# ...but expressions in parentheses may be used to override precedence rules
|
||||
[[ -n $TDIR || -n $UNSET && $PWD -ef xyz ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ ( -n $TDIR || -n $UNSET ) && $PWD -ef xyz ]]
|
||||
echo returns: $?
|
||||
|
||||
# some arithmetic tests for completeness -- see what happens with missing
|
||||
# operands, bad expressions, makes sure arguments are evaluated as
|
||||
# arithmetic expressions, etc.
|
||||
|
||||
unset IVAR A
|
||||
[[ 7 -gt $IVAR ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ $IVAR -gt 7 ]]
|
||||
echo returns: $?
|
||||
|
||||
IVAR=4
|
||||
[[ $IVAR -gt 7 ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ 7 -eq 4+3 ]]
|
||||
echo returns: $?
|
||||
|
||||
[[ 7 -eq 4+ ]]
|
||||
echo returns: $?
|
||||
|
||||
IVAR=4+3
|
||||
[[ $IVAR -eq 7 ]]
|
||||
echo returns: $?
|
||||
|
||||
A=7
|
||||
[[ $IVAR -eq A ]]
|
||||
echo returns: $?
|
||||
|
||||
unset IVAR A
|
||||
|
||||
# more pattern matching tests
|
||||
|
||||
[[ $filename == *.c ]]
|
||||
echo returns: $?
|
||||
|
||||
filename=patmatch.c
|
||||
|
||||
[[ $filename == *.c ]]
|
||||
echo returns: $?
|
||||
|
||||
# the extended globbing features may be used when matching patterns
|
||||
shopt -s extglob
|
||||
|
||||
arg=-7
|
||||
|
||||
[[ $arg == -+([0-9]) ]]
|
||||
echo returns: $?
|
||||
|
||||
arg=-H
|
||||
|
||||
[[ $arg == -+([0-9]) ]]
|
||||
echo returns: $?
|
||||
|
||||
arg=+4
|
||||
[[ $arg == ++([0-9]) ]]
|
||||
echo returns: $?
|
||||
|
||||
# make sure the null string is never matched if the string is not null
|
||||
STR=file.c
|
||||
PAT=
|
||||
|
||||
if [[ $STR = $PAT ]]; then
|
||||
echo oops
|
||||
fi
|
||||
|
||||
# but that if the string is null, a null pattern is matched correctly
|
||||
STR=
|
||||
PAT=
|
||||
|
||||
if [[ $STR = $PAT ]]; then
|
||||
echo ok
|
||||
fi
|
||||
|
||||
# test the regular expression conditional operator
|
||||
[[ jbig2dec-0.9-i586-001.tgz =~ ([^-]+)-([^-]+)-([^-]+)-0*([1-9][0-9]*)\.tgz ]]
|
||||
echo ${BASH_REMATCH[1]}
|
||||
|
||||
# bug in all versions up to and including bash-2.05b
|
||||
if [[ "123abc" == *?(a)bc ]]; then echo ok 42; else echo bad 42; fi
|
||||
if [[ "123abc" == *?(a)bc ]]; then echo ok 43; else echo bad 43; fi
|
||||
+1
-1
@@ -430,7 +430,7 @@ Case05---3---A:B:C---
|
||||
Case06---1---A B C::---
|
||||
Case07---3---A:B:C---
|
||||
Case08---3---A:B:C---
|
||||
./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
|
||||
./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
|
||||
argv[1] = <a>
|
||||
argv[2] = <b>
|
||||
argv[3] = <c>
|
||||
|
||||
Binary file not shown.
@@ -253,3 +253,35 @@ printf '%0.5d\n' 1
|
||||
printf '%05d\n' 1
|
||||
printf '%5d\n' 1
|
||||
printf '%0d\n' 1
|
||||
|
||||
# failures with various floating point formats and 0 after bash-3.2
|
||||
|
||||
printf "%G\n" 0
|
||||
printf "%g\n" 0
|
||||
printf "%4.2G\n" 0
|
||||
printf "%4.2g\n" 0
|
||||
|
||||
printf "%G\n" 4
|
||||
printf "%g\n" 4
|
||||
printf "%4.2G\n" 4
|
||||
printf "%4.2g\n" 4
|
||||
|
||||
printf "%F\n" 0
|
||||
printf "%f\n" 0
|
||||
printf "%4.2F\n" 0
|
||||
printf "%4.2f\n" 0
|
||||
|
||||
printf "%F\n" 4
|
||||
printf "%f\n" 4
|
||||
printf "%4.2F\n" 4
|
||||
printf "%4.2f\n" 4
|
||||
|
||||
printf "%E\n" 0
|
||||
printf "%e\n" 0
|
||||
printf "%4.2E\n" 0
|
||||
printf "%4.2e\n" 0
|
||||
|
||||
printf "%E\n" 4
|
||||
printf "%e\n" 4
|
||||
printf "%4.2E\n" 4
|
||||
printf "%4.2e\n" 4
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
LC_ALL=C
|
||||
LC_NUMERIC=C
|
||||
|
||||
# these should output error messages -- the format is required
|
||||
printf
|
||||
printf --
|
||||
|
||||
# these should output nothing
|
||||
printf ""
|
||||
printf -- ""
|
||||
|
||||
# in the future this may mean to put the output into VAR, but for
|
||||
# now it is an error
|
||||
# 2005-03-15 no longer an error
|
||||
unset var
|
||||
printf -v var "%10d" $RANDOM
|
||||
echo ${#var}
|
||||
|
||||
# this should expand escape sequences in the format string, nothing else
|
||||
printf "\tone\n"
|
||||
|
||||
# this should not cut off output after the \c
|
||||
printf "one\ctwo\n"
|
||||
|
||||
# and unrecognized backslash escapes should have the backslash preserverd
|
||||
printf "4\.2\n"
|
||||
|
||||
printf "no newline " ; printf "now newline\n"
|
||||
|
||||
# %% -> %
|
||||
printf "%%\n"
|
||||
|
||||
# this was a bug caused by pre-processing the string for backslash escapes
|
||||
# before doing the `%' format processing -- all versions before bash-2.04
|
||||
printf "\045" ; echo
|
||||
printf "\045d\n"
|
||||
|
||||
# simple character output
|
||||
printf "%c\n" ABCD
|
||||
|
||||
# test simple string output
|
||||
printf "%s\n" unquoted
|
||||
|
||||
# test quoted string output
|
||||
printf "%s %q\n" unquoted quoted
|
||||
printf "%s%10q\n" unquoted quoted
|
||||
|
||||
printf "%q\n" 'this&that'
|
||||
|
||||
# make sure the format string is reused to use up arguments
|
||||
printf "%d " 1 2 3 4 5; printf "\n"
|
||||
|
||||
# make sure that extra format characters get null arguments
|
||||
printf "%s %d %d %d\n" onestring
|
||||
|
||||
printf "%s %d %u %4.2f\n" onestring
|
||||
|
||||
printf -- "--%s %s--\n" 4.2 ''
|
||||
printf -- "--%s %s--\n" 4.2
|
||||
|
||||
# test %b escapes
|
||||
|
||||
# 8 is a non-octal digit, so the `81' should be output
|
||||
printf -- "--%b--\n" '\n\081'
|
||||
|
||||
printf -- "--%b--\n" '\t\0101'
|
||||
printf -- "--%b--\n" '\t\101'
|
||||
|
||||
# these should all display `A7'
|
||||
echo -e "\01017"
|
||||
echo -e "\x417"
|
||||
|
||||
printf "%b\n" '\01017'
|
||||
printf "%b\n" '\1017'
|
||||
printf "%b\n" '\x417'
|
||||
|
||||
printf -- "--%b--\n" '\"abcd\"'
|
||||
printf -- "--%b--\n" "\'abcd\'"
|
||||
|
||||
printf -- "--%b--\n" 'a\\x'
|
||||
|
||||
printf -- "--%b--\n" '\x'
|
||||
|
||||
Z1=$(printf -- "%b\n" '\a\b\e\f\r\v')
|
||||
Z2=$'\a\b\e\f\r\v'
|
||||
|
||||
if [ "$Z1" != "$Z2" ]; then
|
||||
echo "whoops: printf %b and $'' differ" >&2
|
||||
fi
|
||||
unset Z1 Z2
|
||||
|
||||
printf -- "--%b--\n" ''
|
||||
printf -- "--%b--\n"
|
||||
|
||||
# the stuff following the \c should be ignored, as well as the rest
|
||||
# of the format string
|
||||
printf -- "--%b--\n" '4.2\c5.4\n'; printf "\n"
|
||||
|
||||
# unrecognized escape sequences should by displayed unchanged
|
||||
printf -- "--%b--\n" '4\.2'
|
||||
|
||||
# a bare \ should not be processed as an escape sequence
|
||||
printf -- "--%b--\n" '\'
|
||||
|
||||
# make sure extra arguments are ignored if the format string doesn't
|
||||
# actually use them
|
||||
printf "\n" 4.4 BSD
|
||||
printf " " 4.4 BSD ; printf "\n"
|
||||
|
||||
# make sure that a fieldwidth and precision of `*' are handled right
|
||||
printf "%10.8s\n" 4.4BSD
|
||||
printf "%*.*s\n" 10 8 4.4BSD
|
||||
|
||||
printf "%10.8q\n" 4.4BSD
|
||||
printf "%*.*q\n" 10 8 4.4BSD
|
||||
|
||||
printf "%6b\n" 4.4BSD
|
||||
printf "%*b\n" 6 4.4BSD
|
||||
|
||||
# we handle this crap with homemade code in printf.def
|
||||
printf "%10b\n" 4.4BSD
|
||||
printf -- "--%-10b--\n" 4.4BSD
|
||||
printf "%4.2b\n" 4.4BSD
|
||||
printf "%.3b\n" 4.4BSD
|
||||
printf -- "--%-8b--\n" 4.4BSD
|
||||
|
||||
# test numeric conversions -- these four lines should echo identically
|
||||
printf "%d %u %i 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
|
||||
printf "%d %u %i %#o %#x %#X\n" 255 255 255 255 255 255
|
||||
|
||||
printf "%ld %lu %li 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
|
||||
printf "%ld %lu %li %#o %#x %#X\n" 255 255 255 255 255 255
|
||||
|
||||
printf "%10d\n" 42
|
||||
printf "%10d\n" -42
|
||||
|
||||
printf "%*d\n" 10 42
|
||||
printf "%*d\n" 10 -42
|
||||
|
||||
# test some simple floating point formats
|
||||
printf "%4.2f\n" 4.2
|
||||
printf "%#4.2f\n" 4.2
|
||||
printf "%#4.1f\n" 4.2
|
||||
|
||||
printf "%*.*f\n" 4 2 4.2
|
||||
printf "%#*.*f\n" 4 2 4.2
|
||||
printf "%#*.*f\n" 4 1 4.2
|
||||
|
||||
printf "%E\n" 4.2
|
||||
printf "%e\n" 4.2
|
||||
printf "%6.1E\n" 4.2
|
||||
printf "%6.1e\n" 4.2
|
||||
|
||||
printf "%G\n" 4.2
|
||||
printf "%g\n" 4.2
|
||||
printf "%6.2G\n" 4.2
|
||||
printf "%6.2g\n" 4.2
|
||||
|
||||
# test some of the more esoteric features of POSIX.1 printf
|
||||
printf "%d\n" "'string'"
|
||||
printf "%d\n" '"string"'
|
||||
|
||||
printf "%#o\n" "'string'"
|
||||
printf "%#o\n" '"string"'
|
||||
|
||||
printf "%#x\n" "'string'"
|
||||
printf "%#X\n" '"string"'
|
||||
|
||||
printf "%6.2f\n" "'string'"
|
||||
printf "%6.2f\n" '"string"'
|
||||
|
||||
# output from these two lines had better be the same
|
||||
printf -- "--%6.4s--\n" abcdefghijklmnopqrstuvwxyz
|
||||
printf -- "--%6.4b--\n" abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
# and these two also
|
||||
printf -- "--%12.10s--\n" abcdefghijklmnopqrstuvwxyz
|
||||
printf -- "--%12.10b--\n" abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
# tests for translating \' to ' and \\ to \
|
||||
# printf translates \' to ' in the format string...
|
||||
printf "\'abcd\'\n"
|
||||
|
||||
# but not when the %b format specification is used
|
||||
printf "%b\n" \\\'abcd\\\'
|
||||
|
||||
# but both translate \\ to \
|
||||
printf '\\abcd\\\n'
|
||||
printf "%b\n" '\\abcd\\'
|
||||
|
||||
# this was reported as a bug in bash-2.03
|
||||
# these three lines should all echo `26'
|
||||
printf "%d\n" 0x1a
|
||||
printf "%d\n" 032
|
||||
printf "%d\n" 26
|
||||
|
||||
# error messages
|
||||
|
||||
# this should be an overflow, but error messages vary between systems
|
||||
# printf "%lu\n" 4294967296
|
||||
|
||||
# ...but we cannot use this because some systems (SunOS4, for example),
|
||||
# happily ignore overflow conditions in strtol(3)
|
||||
#printf "%ld\n" 4294967296
|
||||
|
||||
printf "%10"
|
||||
printf "ab%Mcd\n"
|
||||
|
||||
# this caused an infinite loop in older versions of printf
|
||||
printf "%y" 0
|
||||
|
||||
# these should print a warning and `0', according to POSIX.2
|
||||
printf "%d\n" GNU
|
||||
printf "%o\n" GNU
|
||||
|
||||
# failures in all bash versions through bash-2.05
|
||||
printf "%.0s" foo
|
||||
printf "%.*s" 0 foo
|
||||
|
||||
printf '%.0b-%.0s\n' foo bar
|
||||
printf '(%*b)(%*s)\n' -4 foo -4 bar
|
||||
|
||||
format='%'`printf '%0100384d' 0`'d\n'
|
||||
printf $format 0
|
||||
|
||||
# failures in all bash versions through bash-3.0 - undercounted characters
|
||||
unset vv
|
||||
printf " %s %s %s \n%n" ab cd ef vv
|
||||
echo "$vv"
|
||||
|
||||
# this doesn't work with printf(3) on all systems
|
||||
#printf "%'s\n" foo
|
||||
|
||||
# test cases from an austin-group list discussion
|
||||
# prints ^G as an extension
|
||||
printf '%b\n' '\7'
|
||||
|
||||
# prints ^G
|
||||
printf '%b\n' '\0007'
|
||||
|
||||
# prints NUL then 7
|
||||
printf '\0007\n'
|
||||
|
||||
# prints no more than two hex digits
|
||||
printf '\x07e\n'
|
||||
|
||||
# additional backslash escapes
|
||||
printf '\"\?\n'
|
||||
|
||||
# failures with decimal precisions until after bash-3.1
|
||||
printf '%0.5d\n' 1
|
||||
|
||||
printf '%05d\n' 1
|
||||
printf '%5d\n' 1
|
||||
printf '%0d\n' 1
|
||||
Reference in New Issue
Block a user