commit bash-20040902 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 13:35:53 -05:00
parent be7d8f2da4
commit 37c41ab12b
42 changed files with 22871 additions and 17142 deletions
+17
View File
@@ -9948,3 +9948,20 @@ doc/{bash.1,bashref.texi}
- explicitly note that conditional primaries that operate on files
operate on the targets of symbolic links rather than the links
themselves
8/30
----
lib/readline/display.c
- fix multibyte calculation of `physchars' in prompt expansion, to
handle double-width multibyte characters correctly
- changes to rl_redisplay to handle prompts longer than the screenwidth
that might contain double-width multibyte characters. Fixes from
Tomohiro Kubota
9/6
---
subst.c
- change word_list_split to avoid really bad behavior caused by calling
list_append for each split word -- as the list gets long, you have
to traverse it every time. Keep a pointer to the end of the list and
and just tack onto it
+13 -2
View File
@@ -9945,5 +9945,16 @@ builtins/hash.def
8/27
----
doc/{bash.1,bashref.texi}
- explicitly note that condition primaries that operate on files operate
on the targets of symbolic links rather than the links themselves
- explicitly note that conditional primaries that operate on files
operate on the targets of symbolic links rather than the links
themselves
8/30
----
lib/readline/display.c
- fix multibyte calculation of `physchars' in prompt expansion, to
handle double-width multibyte characters correctly
- changes to rl_redisplay to handle prompts longer than the screenwidth
that might contain double-width multibyte characters. Fixes from
Tomohiro Kubota
-3
View File
@@ -35,7 +35,6 @@ lib/sh d
lib/termcap d
lib/termcap/grot d
lib/tilde d
lib/tilde/doc d
po d
support d
tests d
@@ -450,8 +449,6 @@ lib/termcap/grot/COPYING f
lib/termcap/grot/README f
lib/tilde/README f
lib/tilde/Makefile.in f
lib/tilde/doc/tilde.texi f
lib/tilde/doc/Makefile f
lib/tilde/tilde.c f
lib/tilde/tilde.h f
lib/tilde/shell.c f
+125
View File
@@ -0,0 +1,125 @@
*** ../bash-3.0/array.c Thu May 6 08:24:13 2004
--- array.c Wed Aug 25 15:50:42 2004
***************
*** 108,112 ****
ARRAY_ELEMENT *ae, *new;
! if (!a)
return((ARRAY *) NULL);
a1 = array_create();
--- 108,112 ----
ARRAY_ELEMENT *ae, *new;
! if (a == 0)
return((ARRAY *) NULL);
a1 = array_create();
***************
*** 244,250 ****
register ARRAY_ELEMENT *ae, *new;
! if (a == 0)
return 0;
! if (n <= 0)
return (a->num_elements);
--- 244,250 ----
register ARRAY_ELEMENT *ae, *new;
! if (a == 0 || (array_empty(a) && s == 0))
return 0;
! else if (n <= 0)
return (a->num_elements);
***************
*** 254,257 ****
--- 254,259 ----
ADD_BEFORE(ae, new);
a->num_elements++;
+ if (array_num_elements(a) == 1) /* array was empty */
+ return 1;
}
***************
*** 289,293 ****
char *t;
! if (array == 0 || array->head == 0 || array_empty (array))
return (ARRAY *)NULL;
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
--- 291,295 ----
char *t;
! if (array == 0 || array_head(array) == 0 || array_empty(array))
return (ARRAY *)NULL;
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
***************
*** 314,318 ****
char *ifs, sep[2];
! p = array_head (a);
if (p == 0 || array_empty (a) || start > array_max_index(a))
return ((char *)NULL);
--- 316,320 ----
char *ifs, sep[2];
! p = a ? array_head (a) : 0;
if (p == 0 || array_empty (a) || start > array_max_index(a))
return ((char *)NULL);
***************
*** 355,362 ****
char *t, *ifs, sifs[2];
! if (array_head (a) == 0 || array_empty (a))
return ((char *)NULL);
! a2 = array_copy (a);
for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
t = pat_subst(element_value(e), pat, rep, mflags);
--- 357,364 ----
char *t, *ifs, sifs[2];
! if (a == 0 || array_head(a) == 0 || array_empty(a))
return ((char *)NULL);
! a2 = array_copy(a);
for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
t = pat_subst(element_value(e), pat, rep, mflags);
***************
*** 428,432 ****
register ARRAY_ELEMENT *new, *ae;
! if (!a)
return(-1);
new = array_create_element(i, v);
--- 430,434 ----
register ARRAY_ELEMENT *new, *ae;
! if (a == 0)
return(-1);
new = array_create_element(i, v);
***************
*** 452,456 ****
array_dispose_element(new);
free(element_value(ae));
! ae->value = savestring(v);
return(0);
} else if (element_index(ae) > i) {
--- 454,458 ----
array_dispose_element(new);
free(element_value(ae));
! ae->value = v ? savestring(v) : (char *)NULL;
return(0);
} else if (element_index(ae) > i) {
***************
*** 474,478 ****
register ARRAY_ELEMENT *ae;
! if (!a || array_empty(a))
return((ARRAY_ELEMENT *) NULL);
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
--- 476,480 ----
register ARRAY_ELEMENT *ae;
! if (a == 0 || array_empty(a))
return((ARRAY_ELEMENT *) NULL);
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
+1
View File
@@ -1418,6 +1418,7 @@ command_word_completion_function (hint_text, state)
bash_directory_expansion (&rd);
dl = strlen (rd);
l = vl - dl; /* # of chars added */
free (rd);
#endif
temp = (char *)xmalloc (l + 2 + tl);
strcpy (temp, hint_text);
+130
View File
@@ -0,0 +1,130 @@
*** ../bash-3.0/bashline.c Mon Jul 5 23:22:12 2004
--- bashline.c Thu Sep 2 16:00:12 2004
***************
*** 101,104 ****
--- 101,105 ----
/* Helper functions for Readline. */
+ static int bash_directory_expansion __P((char **));
static int bash_directory_completion_hook __P((char **));
static int filename_completion_ignore __P((char **));
***************
*** 293,297 ****
at = strchr (rl_completer_word_break_characters, '@');
if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0))
! return;
/* We have something to do. Do it. */
--- 294,298 ----
at = strchr (rl_completer_word_break_characters, '@');
if ((at == 0 && on_or_off == 0) || (at != 0 && on_or_off != 0))
! return old_value;
/* We have something to do. Do it. */
***************
*** 1407,1414 ****
if (*hint_text == '~')
{
! int l, tl, vl;
vl = strlen (val);
tl = strlen (hint_text);
l = vl - hint_len; /* # of chars added */
temp = (char *)xmalloc (l + 2 + tl);
strcpy (temp, hint_text);
--- 1408,1424 ----
if (*hint_text == '~')
{
! int l, tl, vl, dl;
! char *rd;
vl = strlen (val);
tl = strlen (hint_text);
+ #if 0
l = vl - hint_len; /* # of chars added */
+ #else
+ rd = savestring (filename_hint);
+ bash_directory_expansion (&rd);
+ dl = strlen (rd);
+ l = vl - dl; /* # of chars added */
+ free (rd);
+ #endif
temp = (char *)xmalloc (l + 2 + tl);
strcpy (temp, hint_text);
***************
*** 2188,2191 ****
--- 2198,2222 ----
}
+ /* Simulate the expansions that will be performed by
+ rl_filename_completion_function. This must be called with the address of
+ a pointer to malloc'd memory. */
+ static int
+ bash_directory_expansion (dirname)
+ char **dirname;
+ {
+ char *d;
+
+ d = savestring (*dirname);
+
+ if (rl_directory_rewrite_hook)
+ (*rl_directory_rewrite_hook) (&d);
+
+ if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&d))
+ {
+ free (*dirname);
+ *dirname = d;
+ }
+ }
+
/* Handle symbolic link references and other directory name
expansions while hacking completion. */
***************
*** 2514,2518 ****
static int ind;
int glen;
! char *ret;
if (state == 0)
--- 2545,2549 ----
static int ind;
int glen;
! char *ret, *ttext;
if (state == 0)
***************
*** 2524,2538 ****
FREE (globtext);
if (rl_explicit_arg)
{
! globorig = savestring (text);
! glen = strlen (text);
globtext = (char *)xmalloc (glen + 2);
! strcpy (globtext, text);
globtext[glen] = '*';
globtext[glen+1] = '\0';
}
else
! globtext = globorig = savestring (text);
matches = shell_glob_filename (globtext);
--- 2555,2574 ----
FREE (globtext);
+ ttext = bash_tilde_expand (text, 0);
+
if (rl_explicit_arg)
{
! globorig = savestring (ttext);
! glen = strlen (ttext);
globtext = (char *)xmalloc (glen + 2);
! strcpy (globtext, ttext);
globtext[glen] = '*';
globtext[glen+1] = '\0';
}
else
! globtext = globorig = savestring (ttext);
!
! if (ttext != text)
! free (ttext);
matches = shell_glob_filename (globtext);
+120
View File
@@ -0,0 +1,120 @@
*** ../bash-3.0/doc/bashref.texi Sat Jun 26 14:26:07 2004
--- doc/bashref.texi Fri Aug 27 12:33:46 2004
***************
*** 1257,1260 ****
--- 1257,1264 ----
separate word. That is, @code{"$@@"} is equivalent to
@code{"$1" "$2" @dots{}}.
+ If the double-quoted expansion occurs within a word, the expansion of
+ the first parameter is joined with the beginning part of the original
+ word, and the expansion of the last parameter is joined with the last
+ part of the original word.
When there are no positional parameters, @code{"$@@"} and
@code{$@@}
***************
*** 5202,5205 ****
--- 5206,5212 ----
descriptor 0, 1, or 2, respectively, is checked.
+ Unless otherwise specified, primaries that operate on files follow symbolic
+ links and operate on the target of the link, rather than the link itself.
+
@table @code
@item -a @var{file}
***************
*** 5535,5544 ****
@var{subscript} is @samp{@@} or @samp{*}, the word expands to all members
of the array @var{name}. These subscripts differ only when the word
! appears within double quotes. If the word is double-quoted,
@code{$@{name[*]@}} expands to a single word with
the value of each array member separated by the first character of the
@env{IFS} variable, and @code{$@{name[@@]@}} expands each element of
@var{name} to a separate word. When there are no array members,
! @code{$@{name[@@]@}} expands to nothing. This is analogous to the
expansion of the special parameters @samp{@@} and @samp{*}.
@code{$@{#name[}@var{subscript}@code{]@}} expands to the length of
--- 5542,5557 ----
@var{subscript} is @samp{@@} or @samp{*}, the word expands to all members
of the array @var{name}. These subscripts differ only when the word
! appears within double quotes.
! If the word is double-quoted,
@code{$@{name[*]@}} expands to a single word with
the value of each array member separated by the first character of the
@env{IFS} variable, and @code{$@{name[@@]@}} expands each element of
@var{name} to a separate word. When there are no array members,
! @code{$@{name[@@]@}} expands to nothing.
! If the double-quoted expansion occurs within a word, the expansion of
! the first parameter is joined with the beginning part of the original
! word, and the expansion of the last parameter is joined with the last
! part of the original word.
! This is analogous to the
expansion of the special parameters @samp{@@} and @samp{*}.
@code{$@{#name[}@var{subscript}@code{]@}} expands to the length of
***************
*** 5954,5958 ****
The @code{trap} builtin doesn't check the first argument for a possible
signal specification and revert the signal handling to the original
! disposition if it is. If users want to reset the handler for a given
signal to the original disposition, they should use @samp{-} as the
first argument.
--- 5967,5972 ----
The @code{trap} builtin doesn't check the first argument for a possible
signal specification and revert the signal handling to the original
! disposition if it is, unless that argument consists solely of digits and
! is a valid signal number. If users want to reset the handler for a given
signal to the original disposition, they should use @samp{-} as the
first argument.
***************
*** 5989,5992 ****
--- 6003,6024 ----
does not refer to an existing directory, @code{cd} will fail instead of
falling back to @var{physical} mode.
+
+ @item
+ When listing the history, the @code{fc} builtin does not include an
+ indication of whether or not a history entry has been modified.
+
+ @item
+ The default editor used by @code{fc} is @code{ed}.
+
+ @item
+ The @code{type} and @code{command} builtins will not report a non-executable
+ file as having been found, though the shell will attempt to execute such a
+ file if it is the only so-named file found in @code{$PATH}.
+
+ @item
+ When the @code{xpg_echo} option is enabled, Bash does not attempt to interpret
+ any arguments to @code{echo} as options. Each argument is displayed, after
+ escape characters are converted.
+
@end enumerate
***************
*** 6132,6144 ****
@btindex bg
@example
! bg [@var{jobspec}]
@end example
! Resume the suspended job @var{jobspec} in the background, as if it
had been started with @samp{&}.
If @var{jobspec} is not supplied, the current job is used.
The return status is zero unless it is run when job control is not
! enabled, or, when run with job control enabled, if @var{jobspec} was
! not found or @var{jobspec} specifies a job that was started without
! job control.
@item fg
--- 6164,6176 ----
@btindex bg
@example
! bg [@var{jobspec} @dots{}]
@end example
! Resume each suspended job @var{jobspec} in the background, as if it
had been started with @samp{&}.
If @var{jobspec} is not supplied, the current job is used.
The return status is zero unless it is run when job control is not
! enabled, or, when run with job control enabled, if the last
! @var{jobspec} was not found or the last @var{jobspec} specifies a job
! that was started without job control.
@item fg
+25
View File
@@ -0,0 +1,25 @@
*** ../bash-3.0/braces.c Thu Dec 4 11:09:52 2003
--- braces.c Wed Aug 4 14:34:33 2004
***************
*** 341,346 ****
if (lhs_t == ST_CHAR)
{
! lhs_v = lhs[0];
! rhs_v = rhs[0];
}
else
--- 341,346 ----
if (lhs_t == ST_CHAR)
{
! lhs_v = (unsigned char)lhs[0];
! rhs_v = (unsigned char)rhs[0];
}
else
***************
*** 403,406 ****
--- 403,407 ----
pass_next = 1;
i++;
+ level++;
continue;
}
+495
View File
@@ -0,0 +1,495 @@
This file is cd.def, from which is created cd.c. It implements the
builtins "cd" and "pwd" in Bash.
Copyright (C) 1987-2003 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 cd.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "../bashtypes.h"
#include "posixdir.h"
#include "posixstat.h"
#ifndef _MINIX
#include <sys/param.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include <errno.h>
#include <tilde/tilde.h>
#include "../shell.h"
#include "../flags.h"
#include "maxpath.h"
#include "common.h"
#include "bashgetopt.h"
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int posixly_correct;
extern int array_needs_making;
extern char *bash_getcwd_errstr;
static int bindpwd __P((int));
static int change_to_directory __P((char *, int));
static char *cdspell __P((char *));
/* Change this to 1 to get cd spelling correction by default. */
int cdspelling = 0;
int cdable_vars;
$BUILTIN cd
$FUNCTION cd_builtin
$SHORT_DOC cd [-L|-P] [dir]
Change the current directory to DIR. The variable $HOME is the
default DIR. The variable CDPATH defines the search path for
the directory containing DIR. Alternative directory names in CDPATH
are separated by a colon (:). A null directory name is the same as
the current directory, i.e. `.'. If DIR begins with a slash (/),
then CDPATH is not used. If the directory is not found, and the
shell option `cdable_vars' is set, then try the word as a variable
name. If that variable has a value, then cd to the value of that
variable. The -P option says to use the physical directory structure
instead of following symbolic links; the -L option forces symbolic links
to be followed.
$END
static int
bindpwd (no_symlinks)
int no_symlinks;
{
char *dirname, *pwdvar;
int old_anm;
SHELL_VAR *tvar;
#define tcwd the_current_working_directory
dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
: get_working_directory ("cd");
#undef tcwd
old_anm = array_needs_making;
pwdvar = get_string_value ("PWD");
tvar = bind_variable ("OLDPWD", pwdvar);
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("OLDPWD=", 7, pwdvar);
array_needs_making = 0;
}
tvar = bind_variable ("PWD", dirname ? dirname : "");
if (old_anm == 0 && array_needs_making && exported_p (tvar))
{
update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
array_needs_making = 0;
}
if (dirname && dirname != the_current_working_directory)
free (dirname);
return (EXECUTION_SUCCESS);
}
/* Call get_working_directory to reset the value of
the_current_working_directory () */
static char *
resetpwd (caller)
char *caller;
{
char *tdir;
FREE (the_current_working_directory);
the_current_working_directory = (char *)NULL;
tdir = get_working_directory (caller);
return (tdir);
}
#define LCD_DOVARS 0x001
#define LCD_DOSPELL 0x002
#define LCD_PRINTPATH 0x004
#define LCD_FREEDIRNAME 0x010
/* This builtin is ultimately the way that all user-visible commands should
change the current working directory. It is called by cd_to_string (),
so the programming interface is simple, and it handles errors and
restrictions properly. */
int
cd_builtin (list)
WORD_LIST *list;
{
char *dirname, *cdpath, *path, *temp;
int path_index, no_symlinks, opt, lflag;
#if defined (RESTRICTED_SHELL)
if (restricted)
{
sh_restricted ((char *)NULL);
return (EXECUTION_FAILURE);
}
#endif /* RESTRICTED_SHELL */
no_symlinks = no_symbolic_links;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
no_symlinks = 1;
break;
case 'L':
no_symlinks = 0;
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
list = loptend;
lflag = (cdable_vars ? LCD_DOVARS : 0) |
((interactive && cdspelling) ? LCD_DOSPELL : 0);
if (list == 0)
{
/* `cd' without arguments is equivalent to `cd $HOME' */
dirname = get_string_value ("HOME");
if (dirname == 0)
{
builtin_error (_("HOME not set"));
return (EXECUTION_FAILURE);
}
lflag = 0;
}
else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
{
/* This is `cd -', equivalent to `cd $OLDPWD' */
dirname = get_string_value ("OLDPWD");
if (dirname == 0)
{
builtin_error (_("OLDPWD not set"));
return (EXECUTION_FAILURE);
}
#if 0
lflag = interactive ? LCD_PRINTPATH : 0;
#else
lflag = LCD_PRINTPATH; /* According to SUSv3 */
#endif
}
else if (absolute_pathname (list->word->word))
dirname = list->word->word;
else if (cdpath = get_string_value ("CDPATH"))
{
dirname = list->word->word;
/* Find directory in $CDPATH. */
path_index = 0;
while (path = extract_colon_unit (cdpath, &path_index))
{
/* OPT is 1 if the path element is non-empty */
opt = path[0] != '\0';
temp = sh_makepath (path, dirname, MP_DOTILDE);
free (path);
if (change_to_directory (temp, no_symlinks))
{
/* POSIX.2 says that if a nonempty directory from CDPATH
is used to find the directory to change to, the new
directory name is echoed to stdout, whether or not
the shell is interactive. */
if (opt && (path = no_symlinks ? temp : the_current_working_directory))
printf ("%s\n", path);
free (temp);
/* Posix.2 says that after using CDPATH, the resultant
value of $PWD will not contain `.' or `..'. */
return (bindpwd (posixly_correct || no_symlinks));
}
else
free (temp);
}
/* POSIX.2 says that if `.' does not appear in $CDPATH, we don't
try the current directory, so we just punt now with an error
message if POSIXLY_CORRECT is non-zero. The check for cdpath[0]
is so we don't mistakenly treat a CDPATH value of "" as not
specifying the current directory. */
if (posixly_correct && cdpath[0])
{
builtin_error ("%s: %s", dirname, strerror (ENOENT));
return (EXECUTION_FAILURE);
}
}
else
dirname = list->word->word;
/* When we get here, DIRNAME is the directory to change to. If we
chdir successfully, just return. */
if (change_to_directory (dirname, no_symlinks))
{
if (lflag & LCD_PRINTPATH)
printf ("%s\n", dirname);
return (bindpwd (no_symlinks));
}
/* If the user requests it, then perhaps this is the name of
a shell variable, whose value contains the directory to
change to. */
if (lflag & LCD_DOVARS)
{
temp = get_string_value (dirname);
if (temp && change_to_directory (temp, no_symlinks))
{
printf ("%s\n", temp);
return (bindpwd (no_symlinks));
}
}
/* If the user requests it, try to find a directory name similar in
spelling to the one requested, in case the user made a simple
typo. This is similar to the UNIX 8th and 9th Edition shells. */
if (lflag & LCD_DOSPELL)
{
temp = cdspell (dirname);
if (temp && change_to_directory (temp, no_symlinks))
{
printf ("%s\n", temp);
return (bindpwd (no_symlinks));
}
else
FREE (temp);
}
builtin_error ("%s: %s", dirname, strerror (errno));
return (EXECUTION_FAILURE);
}
$BUILTIN pwd
$FUNCTION pwd_builtin
$SHORT_DOC pwd [-PL]
Print the current working directory. With the -P option, pwd prints
the physical directory, without any symbolic links; the -L option
makes pwd follow symbolic links.
$END
/* Non-zero means that pwd always prints the physical directory, without
symbolic links. */
static int verbatim_pwd;
/* Print the name of the current working directory. */
int
pwd_builtin (list)
WORD_LIST *list;
{
char *directory;
int opt;
verbatim_pwd = no_symbolic_links;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "LP")) != -1)
{
switch (opt)
{
case 'P':
verbatim_pwd = 1;
break;
case 'L':
verbatim_pwd = 0;
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
list = loptend;
#define tcwd the_current_working_directory
directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
: get_working_directory ("pwd");
/* Try again using getcwd() if canonicalization fails (for instance, if
the file system has changed state underneath bash). */
if (tcwd && directory == 0)
directory = resetpwd ("pwd");
#undef tcwd
if (directory)
{
printf ("%s\n", directory);
if (directory != the_current_working_directory)
free (directory);
fflush (stdout);
if (ferror (stdout))
{
builtin_error (_("write error: %s"), strerror (errno));
clearerr (stdout);
return (EXECUTION_FAILURE);
}
return (EXECUTION_SUCCESS);
}
else
return (EXECUTION_FAILURE);
}
/* Do the work of changing to the directory NEWDIR. Handle symbolic
link following, etc. This function *must* return with
the_current_working_directory either set to NULL (in which case
getcwd() will eventually be called), or set to a string corresponding
to the working directory. Return 1 on success, 0 on failure. */
static int
change_to_directory (newdir, nolinks)
char *newdir;
int nolinks;
{
char *t, *tdir;
int err, canon_failed, r;
tdir = (char *)NULL;
if (the_current_working_directory == 0)
{
t = get_working_directory ("chdir");
FREE (t);
}
t = make_absolute (newdir, the_current_working_directory);
/* TDIR is either the canonicalized absolute pathname of NEWDIR
(nolinks == 0) or the absolute physical pathname of NEWDIR
(nolinks != 0). */
tdir = nolinks ? sh_physpath (t, 0)
: sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
/* Use the canonicalized version of NEWDIR, or, if canonicalization
failed, use the non-canonical form. */
canon_failed = 0;
if (tdir && *tdir)
free (t);
else
{
FREE (tdir);
tdir = t;
canon_failed = 1;
}
/* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
returns NULL (because it checks the path, it will return NULL if the
resolved path doesn't exist), fail immediately. */
if (posixly_correct && nolinks == 0 && canon_failed)
{
#if defined ENAMETOOLONG
if (errno != ENOENT && errno != ENAMETOOLONG)
#else
if (errno != ENOENT)
#endif
errno = ENOTDIR;
return (0);
}
/* If the chdir succeeds, update the_current_working_directory. */
if (chdir (nolinks ? newdir : tdir) == 0)
{
/* If canonicalization failed, but the chdir succeeded, reset the
shell's idea of the_current_working_directory. */
if (canon_failed)
{
t = resetpwd ("cd");
if (t == 0)
set_working_directory (tdir);
}
else
set_working_directory (tdir);
return (1);
}
/* We failed to change to the appropriate directory name. If we tried
what the user passed (nolinks != 0), punt now. */
if (nolinks)
return (0);
err = errno;
/* We're not in physical mode (nolinks == 0), but we failed to change to
the canonicalized directory name (TDIR). Try what the user passed
verbatim. If we succeed, reinitialize the_current_working_directory. */
if (chdir (newdir) == 0)
{
t = resetpwd ("cd");
if (t == 0)
set_working_directory (tdir);
else
free (t);
r = 1;
}
else
{
errno = err;
r = 0;
}
free (tdir);
return r;
}
/* Code for cd spelling correction. Original patch submitted by
Neil Russel (caret@c-side.com). */
static char *
cdspell (dirname)
char *dirname;
{
int n;
char *guess;
n = (strlen (dirname) * 3 + 1) / 2 + 1;
guess = (char *)xmalloc (n);
switch (spname (dirname, guess))
{
case -1:
default:
free (guess);
return (char *)NULL;
case 0:
case 1:
return guess;
}
}
+804
View File
@@ -0,0 +1,804 @@
/* 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. */
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include <chartypes.h>
#include "../bashtypes.h"
#include "posixstat.h"
#include <signal.h>
#include <errno.h>
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# include <varargs.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "maxpath.h"
#include "../flags.h"
#include "../jobs.h"
#include "../builtins.h"
#include "../input.h"
#include "../execute_cmd.h"
#include "../trap.h"
#include "bashgetopt.h"
#include "common.h"
#include "builtext.h"
#include <tilde/tilde.h>
#if defined (HISTORY)
# include "../bashhist.h"
#endif
#if !defined (errno)
extern int errno;
#endif /* !errno */
extern int indirection_level, subshell_environment;
extern int line_number;
extern int last_command_exit_value;
extern int running_trap;
extern int posixly_correct;
extern char *this_command_name, *shell_name;
extern char *bash_getcwd_errstr;
/* Used by some builtins and the mainline code. */
sh_builtin_func_t *last_shell_builtin = (sh_builtin_func_t *)NULL;
sh_builtin_func_t *this_shell_builtin = (sh_builtin_func_t *)NULL;
/* **************************************************************** */
/* */
/* Error reporting, usage, and option processing */
/* */
/* **************************************************************** */
/* This is a lot like report_error (), but it is for shell builtins
instead of shell control structures, and it won't ever exit the
shell. */
void
#if defined (PREFER_STDARG)
builtin_error (const char *format, ...)
#else
builtin_error (format, va_alist)
const char *format;
va_dcl
#endif
{
va_list args;
char *name;
name = get_name_for_error ();
fprintf (stderr, "%s: ", name);
if (interactive_shell == 0)
fprintf (stderr, "line %d: ", executing_line_number ());
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: ", this_command_name);
SH_VA_START (args, format);
vfprintf (stderr, format, args);
va_end (args);
fprintf (stderr, "\n");
}
/* Print a usage summary for the currently-executing builtin command. */
void
builtin_usage ()
{
if (this_command_name && *this_command_name)
fprintf (stderr, "%s: usage: ", this_command_name);
fprintf (stderr, "%s\n", current_builtin->short_doc);
fflush (stderr);
}
/* Return if LIST is NULL else barf and jump to top_level. Used by some
builtins that do not accept arguments. */
void
no_args (list)
WORD_LIST *list;
{
if (list)
{
builtin_error (_("too many arguments"));
jump_to_top_level (DISCARD);
}
}
/* Check that no options were given to the currently-executing builtin,
and return 0 if there were options. */
int
no_options (list)
WORD_LIST *list;
{
reset_internal_getopt ();
if (internal_getopt (list, "") != -1)
{
builtin_usage ();
return (1);
}
return (0);
}
void
sh_needarg (s)
char *s;
{
builtin_error (_("%s: option requires an argument"), s);
}
void
sh_neednumarg (s)
char *s;
{
builtin_error (_("%s: numeric argument required"), s);
}
void
sh_notfound (s)
char *s;
{
builtin_error (_("%s: not found"), s);
}
/* Function called when one of the builtin commands detects an invalid
option. */
void
sh_invalidopt (s)
char *s;
{
builtin_error (_("%s: invalid option"), s);
}
void
sh_invalidoptname (s)
char *s;
{
builtin_error (_("%s: invalid option name"), s);
}
void
sh_invalidid (s)
char *s;
{
builtin_error (_("`%s': not a valid identifier"), s);
}
void
sh_invalidnum (s)
char *s;
{
builtin_error (_("%s: invalid number"), s);
}
void
sh_invalidsig (s)
char *s;
{
builtin_error (_("%s: invalid signal specification"), s);
}
void
sh_badpid (s)
char *s;
{
builtin_error (_("`%s': not a pid or valid job spec"), s);
}
void
sh_readonly (s)
const char *s;
{
builtin_error (_("%s: readonly variable"), s);
}
void
sh_erange (s, desc)
char *s, *desc;
{
if (s)
builtin_error (_("%s: %s out of range"), s, desc ? desc : _("argument"));
else
builtin_error (_("%s out of range"), desc ? desc : _("argument"));
}
#if defined (JOB_CONTROL)
void
sh_badjob (s)
char *s;
{
builtin_error (_("%s: no such job"), s);
}
void
sh_nojobs (s)
char *s;
{
if (s)
builtin_error (_("%s: no job control"), s);
else
builtin_error (_("no job control"));
}
#endif
#if defined (RESTRICTED_SHELL)
void
sh_restricted (s)
char *s;
{
if (s)
builtin_error (_("%s: restricted"), s);
else
builtin_error (_("restricted"));
}
#endif
void
sh_notbuiltin (s)
char *s;
{
builtin_error (_("%s: not a shell builtin"), s);
}
/* **************************************************************** */
/* */
/* Shell positional parameter manipulation */
/* */
/* **************************************************************** */
/* Convert a WORD_LIST into a C-style argv. Return the number of elements
in the list in *IP, if IP is non-null. A convenience function for
loadable builtins; also used by `test'. */
char **
make_builtin_argv (list, ip)
WORD_LIST *list;
int *ip;
{
char **argv;
argv = strvec_from_word_list (list, 0, 1, ip);
argv[0] = this_command_name;
return argv;
}
/* Remember LIST in $0 ... $9, and REST_OF_ARGS. If DESTRUCTIVE is
non-zero, then discard whatever the existing arguments are, else
only discard the ones that are to be replaced. */
void
remember_args (list, destructive)
WORD_LIST *list;
int destructive;
{
register int i;
for (i = 1; i < 10; i++)
{
if ((destructive || list) && dollar_vars[i])
{
free (dollar_vars[i]);
dollar_vars[i] = (char *)NULL;
}
if (list)
{
dollar_vars[i] = savestring (list->word->word);
list = list->next;
}
}
/* If arguments remain, assign them to REST_OF_ARGS.
Note that copy_word_list (NULL) returns NULL, and
that dispose_words (NULL) does nothing. */
if (destructive || list)
{
dispose_words (rest_of_args);
rest_of_args = copy_word_list (list);
}
if (destructive)
set_dollar_vars_changed ();
}
static int changed_dollar_vars;
/* Have the dollar variables been reset to new values since we last
checked? */
int
dollar_vars_changed ()
{
return (changed_dollar_vars);
}
void
set_dollar_vars_unchanged ()
{
changed_dollar_vars = 0;
}
void
set_dollar_vars_changed ()
{
if (variable_context)
changed_dollar_vars |= ARGS_FUNC;
else if (this_shell_builtin == set_builtin)
changed_dollar_vars |= ARGS_SETBLTIN;
else
changed_dollar_vars |= ARGS_INVOC;
}
/* **************************************************************** */
/* */
/* Validating numeric input and arguments */
/* */
/* **************************************************************** */
/* Read a numeric arg for this_command_name, the name of the shell builtin
that wants it. LIST is the word list that the arg is to come from.
Accept only the numeric argument; report an error if other arguments
follow. If FATAL is true, call throw_to_top_level, which exits the
shell; if not, call jump_to_top_level (DISCARD), which aborts the
current command. */
intmax_t
get_numeric_arg (list, fatal)
WORD_LIST *list;
int fatal;
{
intmax_t count = 1;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list)
{
register char *arg;
arg = list->word->word;
if (arg == 0 || (legal_number (arg, &count) == 0))
{
sh_neednumarg (list->word->word);
if (fatal)
throw_to_top_level ();
else
jump_to_top_level (DISCARD);
}
no_args (list->next);
}
return (count);
}
/* Get an eight-bit status value from LIST */
int
get_exitstat (list)
WORD_LIST *list;
{
int status;
intmax_t sval;
char *arg;
if (list && list->word && ISOPTION (list->word->word, '-'))
list = list->next;
if (list == 0)
return (last_command_exit_value);
arg = list->word->word;
if (arg == 0 || legal_number (arg, &sval) == 0)
{
sh_neednumarg (list->word->word ? list->word->word : "`'");
return 255;
}
no_args (list->next);
status = sval & 255;
return status;
}
/* Return the octal number parsed from STRING, or -1 to indicate
that the string contained a bad number. */
int
read_octal (string)
char *string;
{
int result, digits;
result = digits = 0;
while (*string && ISOCTAL (*string))
{
digits++;
result = (result * 8) + (*string++ - '0');
if (result > 0777)
return -1;
}
if (digits == 0 || *string)
result = -1;
return (result);
}
/* **************************************************************** */
/* */
/* Manipulating the current working directory */
/* */
/* **************************************************************** */
/* Return a consed string which is the current working directory.
FOR_WHOM is the name of the caller for error printing. */
char *the_current_working_directory = (char *)NULL;
char *
get_working_directory (for_whom)
char *for_whom;
{
char *directory;
size_t dsize;
if (no_symbolic_links)
{
FREE (the_current_working_directory);
the_current_working_directory = (char *)NULL;
}
if (the_current_working_directory == 0)
{
the_current_working_directory = getcwd (0, 0);
if (the_current_working_directory == 0)
{
fprintf (stderr, _("%s: error retrieving current directory: %s: %s\n"),
(for_whom && *for_whom) ? for_whom : get_name_for_error (),
_(bash_getcwd_errstr), strerror (errno));
return (char *)NULL;
}
}
return (savestring (the_current_working_directory));
}
/* Make NAME our internal idea of the current working directory. */
void
set_working_directory (name)
char *name;
{
FREE (the_current_working_directory);
the_current_working_directory = savestring (name);
}
/* **************************************************************** */
/* */
/* Job control support functions */
/* */
/* **************************************************************** */
#if defined (JOB_CONTROL)
int
get_job_by_name (name, flags)
const char *name;
int flags;
{
register int i, wl, cl, match, job;
register PROCESS *p;
job = NO_JOB;
wl = strlen (name);
for (i = job_slots - 1; i >= 0; i--)
{
if (jobs[i] == 0 || ((flags & JM_STOPPED) && JOBSTATE(i) != JSTOPPED))
continue;
p = jobs[i]->pipe;
do
{
if (flags & JM_EXACT)
{
cl = strlen (p->command);
match = STREQN (p->command, name, cl);
}
else if (flags & JM_SUBSTRING)
match = strindex (p->command, name) != (char *)0;
else
match = STREQN (p->command, name, wl);
if (match == 0)
{
p = p->next;
continue;
}
else if (flags & JM_FIRSTMATCH)
return i; /* return first match */
else if (job != NO_JOB)
{
if (this_shell_builtin)
builtin_error (_("%s: ambiguous job spec"), name);
else
report_error (_("%s: ambiguous job spec"), name);
return (DUP_JOB);
}
else
job = i;
}
while (p != jobs[i]->pipe);
}
return (job);
}
/* Return the job spec found in LIST. */
int
get_job_spec (list)
WORD_LIST *list;
{
register char *word;
int job, jflags;
if (list == 0)
return (current_job);
word = list->word->word;
if (*word == '\0')
return (NO_JOB);
if (*word == '%')
word++;
if (DIGIT (*word) && all_digits (word))
{
job = atoi (word);
return (job > job_slots ? NO_JOB : job - 1);
}
jflags = 0;
switch (*word)
{
case 0:
return NO_JOB;
case '%':
case '+':
return (current_job);
case '-':
return (previous_job);
case '?': /* Substring search requested. */
jflags |= JM_SUBSTRING;
word++;
/* FALLTHROUGH */
default:
return get_job_by_name (word, jflags);
}
}
#endif /* JOB_CONTROL */
/*
* NOTE: `kill' calls this function with forcecols == 0
*/
int
display_signal_list (list, forcecols)
WORD_LIST *list;
int forcecols;
{
register int i, column;
char *name;
int result, signum, dflags;
intmax_t lsignum;
result = EXECUTION_SUCCESS;
if (!list)
{
for (i = 1, column = 0; i < NSIG; i++)
{
name = signal_name (i);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
continue;
if (posixly_correct && !forcecols)
{
/* This is for the kill builtin. POSIX.2 says the signal names
are displayed without the `SIG' prefix. */
if (STREQN (name, "SIG", 3))
name += 3;
printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
}
else
{
printf ("%2d) %s", i, name);
if (++column < 4)
printf ("\t");
else
{
printf ("\n");
column = 0;
}
}
}
if ((posixly_correct && !forcecols) || column != 0)
printf ("\n");
return result;
}
/* List individual signal names or numbers. */
while (list)
{
if (legal_number (list->word->word, &lsignum))
{
/* This is specified by Posix.2 so that exit statuses can be
mapped into signal numbers. */
if (lsignum > 128)
lsignum -= 128;
if (lsignum < 0 || lsignum >= NSIG)
{
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
signum = lsignum;
name = signal_name (signum);
if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
{
list = list->next;
continue;
}
#if defined (JOB_CONTROL)
/* POSIX.2 says that `kill -l signum' prints the signal name without
the `SIG' prefix. */
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
#else
printf ("%s\n", name);
#endif
}
else
{
dflags = DSIG_NOCASE;
if (posixly_correct == 0 || this_shell_builtin != kill_builtin)
dflags |= DSIG_SIGPREFIX;
signum = decode_signal (list->word->word, dflags);
if (signum == NO_SIG)
{
sh_invalidsig (list->word->word);
result = EXECUTION_FAILURE;
list = list->next;
continue;
}
printf ("%d\n", signum);
}
list = list->next;
}
return (result);
}
/* **************************************************************** */
/* */
/* Finding builtin commands and their functions */
/* */
/* **************************************************************** */
/* Perform a binary search and return the address of the builtin function
whose name is NAME. If the function couldn't be found, or the builtin
is disabled or has no function associated with it, return NULL.
Return the address of the builtin.
DISABLED_OKAY means find it even if the builtin is disabled. */
struct builtin *
builtin_address_internal (name, disabled_okay)
char *name;
int disabled_okay;
{
int hi, lo, mid, j;
hi = num_shell_builtins - 1;
lo = 0;
while (lo <= hi)
{
mid = (lo + hi) / 2;
j = shell_builtins[mid].name[0] - name[0];
if (j == 0)
j = strcmp (shell_builtins[mid].name, name);
if (j == 0)
{
/* It must have a function pointer. It must be enabled, or we
must have explicitly allowed disabled functions to be found,
and it must not have been deleted. */
if (shell_builtins[mid].function &&
((shell_builtins[mid].flags & BUILTIN_DELETED) == 0) &&
((shell_builtins[mid].flags & BUILTIN_ENABLED) || disabled_okay))
return (&shell_builtins[mid]);
else
return ((struct builtin *)NULL);
}
if (j > 0)
hi = mid - 1;
else
lo = mid + 1;
}
return ((struct builtin *)NULL);
}
/* Return the pointer to the function implementing builtin command NAME. */
sh_builtin_func_t *
find_shell_builtin (name)
char *name;
{
current_builtin = builtin_address_internal (name, 0);
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
}
/* Return the address of builtin with NAME, whether it is enabled or not. */
sh_builtin_func_t *
builtin_address (name)
char *name;
{
current_builtin = builtin_address_internal (name, 1);
return (current_builtin ? current_builtin->function : (sh_builtin_func_t *)NULL);
}
/* Return the function implementing the builtin NAME, but only if it is a
POSIX.2 special builtin. */
sh_builtin_func_t *
find_special_builtin (name)
char *name;
{
current_builtin = builtin_address_internal (name, 0);
return ((current_builtin && (current_builtin->flags & SPECIAL_BUILTIN)) ?
current_builtin->function :
(sh_builtin_func_t *)NULL);
}
static int
shell_builtin_compare (sbp1, sbp2)
struct builtin *sbp1, *sbp2;
{
int result;
if ((result = sbp1->name[0] - sbp2->name[0]) == 0)
result = strcmp (sbp1->name, sbp2->name);
return (result);
}
/* Sort the table of shell builtins so that the binary search will work
in find_shell_builtin. */
void
initialize_shell_builtins ()
{
qsort (shell_builtins, num_shell_builtins, sizeof (struct builtin),
(QSFUNC *)shell_builtin_compare);
}
+1
View File
@@ -40,6 +40,7 @@
#define CDESC_PATH_ONLY 0x010 /* type -p */
#define CDESC_FORCE_PATH 0x020 /* type -ap or type -P */
#define CDESC_NOFUNCS 0x040 /* type -f */
#define CDESC_ABSPATH 0x080 /* convert to absolute path, no ./ */
/* Flags for get_job_by_name */
#define JM_PREFIX 0x01 /* prefix of job name */
+8
View File
@@ -31,6 +31,11 @@ $PRODUCES echo.c
#include <stdio.h>
#include "../shell.h"
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif
$BUILTIN echo
$FUNCTION echo_builtin
$DEPENDS_ON V9_ECHO
@@ -78,6 +83,8 @@ int xpg_echo = 1;
int xpg_echo = 0;
#endif /* DEFAULT_ECHO_TO_XPG */
extern int posixly_correct;
/* Print the words in LIST to standard output. If the first word is
`-n', then don't print a trailing newline. We also support the
echo syntax from Version 9 Unix systems. */
@@ -173,6 +180,7 @@ just_echo:
fflush (stdout);
if (ferror (stdout))
{
builtin_error ("write error: %s", strerror (errno));
clearerr (stdout);
return (EXECUTION_FAILURE);
}
+876
View File
@@ -0,0 +1,876 @@
This file is printf.def, from which is created printf.c.
It implements the builtin "printf" in Bash.
Copyright (C) 1997-2003 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
$PRODUCES printf.c
$BUILTIN printf
$FUNCTION printf_builtin
$SHORT_DOC printf format [arguments]
printf formats and prints ARGUMENTS under control of the FORMAT. FORMAT
is a character string which contains three types of objects: plain
characters, which are simply copied to standard output, character escape
sequences which are converted and copied to the standard output, and
format specifications, each of which causes printing of the next successive
argument. In addition to the standard printf(1) formats, %b means to
expand backslash escape sequences in the corresponding argument, and %q
means to quote the argument in a way that can be reused as shell input.
$END
#include <config.h>
#include "../bashtypes.h"
#include <errno.h>
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#else
/* Assume 32-bit ints. */
# define INT_MAX 2147483647
# define INT_MIN (-2147483647-1)
#endif
#include <stdio.h>
#include <chartypes.h>
#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "stdc.h"
#include "bashgetopt.h"
#include "common.h"
#if !defined (PRIdMAX)
# if HAVE_LONG_LONG
# define PRIdMAX "lld"
# else
# define PRIdMAX "ld"
# endif
#endif
#if !defined (errno)
extern int errno;
#endif
#define PF(f, func) \
do { \
if (have_fieldwidth && have_precision) \
tw += printf(f, fieldwidth, precision, func); \
else if (have_fieldwidth) \
tw += printf(f, fieldwidth, func); \
else if (have_precision) \
tw += printf(f, precision, func); \
else \
tw += printf(f, func); \
} while (0)
/* We free the buffer used by mklong() if it's `too big'. */
#define PRETURN(value) \
do \
{ \
if (conv_bufsize > 4096 ) \
{ \
free(conv_buf); \
conv_bufsize = 0; \
conv_buf = 0; \
} \
fflush (stdout); \
return (value); \
} \
while (0)
#define SKIP1 "#'-+ 0"
#define LENMODS "hjlLtz"
static void printf_erange __P((char *));
static int printstr __P((char *, char *, int, int, int));
static int tescape __P((char *, char *, int *));
static char *bexpand __P((char *, int, int *, int *));
static char *mklong __P((char *, char *, size_t));
static int getchr __P((void));
static char *getstr __P((void));
static int getint __P((void));
static intmax_t getintmax __P((void));
static uintmax_t getuintmax __P((void));
#if defined (HAVE_LONG_DOUBLE) && HAVE_DECL_STRTOLD && !defined(STRTOLD_BROKEN)
typedef long double floatmax_t;
# define FLOATMAX_CONV "L"
# define strtofltmax strtold
#else
typedef double floatmax_t;
# define FLOATMAX_CONV ""
# define strtofltmax strtod
#endif
static floatmax_t getfloatmax __P((void));
static int asciicode __P((void));
static WORD_LIST *garglist;
static int retval;
static int conversion_error;
static char *conv_buf;
static size_t conv_bufsize;
int
printf_builtin (list)
WORD_LIST *list;
{
int ch, fieldwidth, precision;
int have_fieldwidth, have_precision;
intmax_t tw;
char convch, thisch, nextch, *format, *modstart, *fmt, *start;
conversion_error = 0;
retval = EXECUTION_SUCCESS;
if (no_options (list))
return (EX_USAGE);
list = loptend; /* skip over possible `--' */
if (list == 0)
{
builtin_usage ();
return (EX_USAGE);
}
if (list->word->word == 0 || list->word->word[0] == '\0')
return (EXECUTION_SUCCESS);
format = list->word->word;
garglist = list->next;
/* If the format string is empty after preprocessing, return immediately. */
if (format == 0 || *format == 0)
return (EXECUTION_SUCCESS);
/* Basic algorithm is to scan the format string for conversion
specifications -- once one is found, find out if the field
width or precision is a '*'; if it is, gather up value. Note,
format strings are reused as necessary to use up the provided
arguments, arguments of zero/null string are provided to use
up the format string. */
do
{
tw = 0;
/* find next format specification */
for (fmt = format; *fmt; fmt++)
{
precision = fieldwidth = 0;
have_fieldwidth = have_precision = 0;
if (*fmt == '\\')
{
fmt++;
/* A NULL third argument to tescape means to bypass the
special processing for arguments to %b. */
fmt += tescape (fmt, &nextch, (int *)NULL);
putchar (nextch);
fmt--; /* for loop will increment it for us again */
continue;
}
if (*fmt != '%')
{
putchar (*fmt);
continue;
}
/* ASSERT(*fmt == '%') */
start = fmt++;
if (*fmt == '%') /* %% prints a % */
{
putchar ('%');
continue;
}
/* found format specification, skip to field width */
for (; *fmt && strchr(SKIP1, *fmt); ++fmt)
;
/* Skip optional field width. */
if (*fmt == '*')
{
fmt++;
have_fieldwidth = 1;
fieldwidth = getint ();
}
else
while (DIGIT (*fmt))
fmt++;
/* Skip optional '.' and precision */
if (*fmt == '.')
{
++fmt;
if (*fmt == '*')
{
fmt++;
have_precision = 1;
precision = getint ();
}
else
while (DIGIT (*fmt))
fmt++;
}
/* skip possible format modifiers */
modstart = fmt;
while (*fmt && strchr (LENMODS, *fmt))
fmt++;
if (*fmt == 0)
{
builtin_error (_("`%s': missing format character"), start);
PRETURN (EXECUTION_FAILURE);
}
convch = *fmt;
thisch = modstart[0];
nextch = modstart[1];
modstart[0] = convch;
modstart[1] = '\0';
switch(convch)
{
case 'c':
{
char p;
p = getchr ();
PF(start, p);
break;
}
case 's':
{
char *p;
p = getstr ();
PF(start, p);
break;
}
case 'n':
{
char *var;
var = getstr ();
if (var && *var)
{
if (legal_identifier (var))
bind_var_to_int (var, tw);
else
{
sh_invalidid (var);
PRETURN (EXECUTION_FAILURE);
}
}
break;
}
case 'b': /* expand escapes in argument */
{
char *p, *xp;
int rlen, r;
p = getstr ();
ch = rlen = 0;
xp = bexpand (p, strlen (p), &ch, &rlen);
if (xp)
{
/* Have to use printstr because of possible NUL bytes
in XP -- printf does not handle that well. */
r = printstr (start, xp, rlen, fieldwidth, precision);
if (r < 0)
{
sh_wrerror ();
retval = EXECUTION_FAILURE;
}
free (xp);
}
if (ch || r < 0)
PRETURN (retval);
break;
}
case 'q': /* print with shell quoting */
{
char *p, *xp;
int r;
p = getstr ();
if (ansic_shouldquote (p))
xp = ansic_quote (p, 0, (int *)0);
else
xp = sh_backslash_quote (p);
if (xp)
{
/* Use printstr to get fieldwidth and precision right. */
r = printstr (start, xp, strlen (xp), fieldwidth, precision);
if (r < 0)
sh_wrerror ();
free (xp);
}
if (r < 0)
PRETURN (EXECUTION_FAILURE);
break;
}
case 'd':
case 'i':
{
char *f;
long p;
intmax_t pp;
p = pp = getintmax ();
if (p != pp)
{
f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
PF (f, pp);
}
else
{
/* Optimize the common case where the integer fits
in "long". This also works around some long
long and/or intmax_t library bugs in the common
case, e.g. glibc 2.2 x86. */
f = mklong (start, "l", 1);
PF (f, p);
}
break;
}
case 'o':
case 'u':
case 'x':
case 'X':
{
char *f;
unsigned long p;
uintmax_t pp;
p = pp = getuintmax ();
if (p != pp)
{
f = mklong (start, PRIdMAX, sizeof (PRIdMAX) - 2);
PF (f, pp);
}
else
{
f = mklong (start, "l", 1);
PF (f, p);
}
break;
}
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
#if defined (HAVE_PRINTF_A_FORMAT)
case 'a':
case 'A':
#endif
{
char *f;
floatmax_t p;
p = getfloatmax ();
f = mklong (start, FLOATMAX_CONV, sizeof(FLOATMAX_CONV) - 1);
PF (f, p);
break;
}
/* We don't output unrecognized format characters; we print an
error message and return a failure exit status. */
default:
builtin_error (_("`%c': invalid format character"), convch);
PRETURN (EXECUTION_FAILURE);
}
modstart[0] = thisch;
modstart[1] = nextch;
}
}
while (garglist && garglist != list->next);
if (conversion_error)
retval = EXECUTION_FAILURE;
PRETURN (retval);
}
static void
printf_erange (s)
char *s;
{
builtin_error ("warning: %s: %s", s, strerror(ERANGE));
}
/* We duplicate a lot of what printf(3) does here. */
static int
printstr (fmt, string, len, fieldwidth, precision)
char *fmt; /* format */
char *string; /* expanded string argument */
int len; /* length of expanded string */
int fieldwidth; /* argument for width of `*' */
int precision; /* argument for precision of `*' */
{
#if 0
char *s;
#endif
int padlen, nc, ljust, i;
int fw, pr; /* fieldwidth and precision */
#if 0
if (string == 0 || *string == '\0')
#else
if (string == 0 || len == 0)
#endif
return;
#if 0
s = fmt;
#endif
if (*fmt == '%')
fmt++;
ljust = fw = 0;
pr = -1;
/* skip flags */
while (strchr (SKIP1, *fmt))
{
if (*fmt == '-')
ljust = 1;
fmt++;
}
/* get fieldwidth, if present */
if (*fmt == '*')
{
fmt++;
fw = fieldwidth;
if (fw < 0)
{
fw = -fw;
ljust = 1;
}
}
else if (DIGIT (*fmt))
{
fw = *fmt++ - '0';
while (DIGIT (*fmt))
fw = (fw * 10) + (*fmt++ - '0');
}
/* get precision, if present */
if (*fmt == '.')
{
fmt++;
if (*fmt == '*')
{
fmt++;
pr = precision;
}
else if (DIGIT (*fmt))
{
pr = *fmt++ - '0';
while (DIGIT (*fmt))
pr = (pr * 10) + (*fmt++ - '0');
}
}
#if 0
/* If we remove this, get rid of `s'. */
if (*fmt != 'b' && *fmt != 'q')
{
internal_error ("format parsing problem: %s", s);
fw = pr = 0;
}
#endif
/* chars from string to print */
nc = (pr >= 0 && pr <= len) ? pr : len;
padlen = fw - nc;
if (padlen < 0)
padlen = 0;
if (ljust)
padlen = -padlen;
/* leading pad characters */
for (; padlen > 0; padlen--)
putchar (' ');
/* output NC characters from STRING */
for (i = 0; i < nc; i++)
putchar (string[i]);
/* output any necessary trailing padding */
for (; padlen < 0; padlen++)
putchar (' ');
return (ferror (stdout) ? -1 : 0);
}
/* Convert STRING by expanding the escape sequences specified by the
POSIX standard for printf's `%b' format string. If SAWC is non-null,
perform the processing appropriate for %b arguments. In particular,
recognize `\c' and use that as a string terminator. If we see \c, set
*SAWC to 1 before returning. LEN is the length of STRING. */
/* Translate a single backslash-escape sequence starting at ESTART (the
character after the backslash) and return the number of characters
consumed by the sequence. CP is the place to return the translated
value. *SAWC is set to 1 if the escape sequence was \c, since that means
to short-circuit the rest of the processing. If SAWC is null, we don't
do the \c short-circuiting, and \c is treated as an unrecognized escape
sequence; we also bypass the other processing specific to %b arguments. */
static int
tescape (estart, cp, sawc)
char *estart;
char *cp;
int *sawc;
{
register char *p;
int temp, c, evalue;
p = estart;
switch (c = *p++)
{
#if defined (__STDC__)
case 'a': *cp = '\a'; break;
#else
case 'a': *cp = '\007'; break;
#endif
case 'b': *cp = '\b'; break;
case 'e':
case 'E': *cp = '\033'; break; /* ESC -- non-ANSI */
case 'f': *cp = '\f'; break;
case 'n': *cp = '\n'; break;
case 'r': *cp = '\r'; break;
case 't': *cp = '\t'; break;
case 'v': *cp = '\v'; break;
/* The octal escape sequences are `\0' followed by up to three octal
digits (if SAWC), or `\' followed by up to three octal digits (if
!SAWC). As an extension, we allow the latter form even if SAWC. */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
evalue = OCTVALUE (c);
for (temp = 2 + (!evalue && !!sawc); ISOCTAL (*p) && temp--; p++)
evalue = (evalue * 8) + OCTVALUE (*p);
*cp = evalue & 0xFF;
break;
/* And, as another extension, we allow \xNNN, where each N is a
hex digit. */
case 'x':
#if 0
for (evalue = 0; ISXDIGIT ((unsigned char)*p); p++)
#else
for (temp = 2, evalue = 0; ISXDIGIT ((unsigned char)*p) && temp--; p++)
#endif
evalue = (evalue * 16) + HEXVALUE (*p);
if (p == estart + 1)
{
builtin_error (_("missing hex digit for \\x"));
*cp = '\\';
return 0;
}
*cp = evalue & 0xFF;
break;
case '\\': /* \\ -> \ */
*cp = c;
break;
/* SAWC == 0 means that \', \", and \? are recognized as escape
sequences, though the only processing performed is backslash
removal. */
case '\'': case '"': case '?':
if (!sawc)
*cp = c;
else
{
*cp = '\\';
return 0;
}
break;
case 'c':
if (sawc)
{
*sawc = 1;
break;
}
/* other backslash escapes are passed through unaltered */
default:
*cp = '\\';
return 0;
}
return (p - estart);
}
static char *
bexpand (string, len, sawc, lenp)
char *string;
int len, *sawc, *lenp;
{
int temp;
char *ret, *r, *s, c;
#if 0
if (string == 0 || *string == '\0')
#else
if (string == 0 || len == 0)
#endif
{
if (sawc)
*sawc = 0;
if (lenp)
*lenp = 0;
return ((char *)NULL);
}
ret = (char *)xmalloc (len + 1);
for (r = ret, s = string; s && *s; )
{
c = *s++;
if (c != '\\' || *s == '\0')
{
*r++ = c;
continue;
}
temp = 0;
s += tescape (s, &c, &temp);
if (temp)
{
if (sawc)
*sawc = 1;
break;
}
*r++ = c;
}
*r = '\0';
if (lenp)
*lenp = r - ret;
return ret;
}
static char *
mklong (str, modifiers, mlen)
char *str;
char *modifiers;
size_t mlen;
{
size_t len, slen;
slen = strlen (str);
len = slen + mlen + 1;
if (len > conv_bufsize)
{
conv_bufsize = (((len + 1023) >> 10) << 10);
conv_buf = (char *)xrealloc (conv_buf, conv_bufsize);
}
FASTCOPY (str, conv_buf, slen - 1);
FASTCOPY (modifiers, conv_buf + slen - 1, mlen);
conv_buf[len - 2] = str[slen - 1];
conv_buf[len - 1] = '\0';
return (conv_buf);
}
static int
getchr ()
{
int ret;
if (garglist == 0)
return ('\0');
ret = (int)garglist->word->word[0];
garglist = garglist->next;
return ret;
}
static char *
getstr ()
{
char *ret;
if (garglist == 0)
return ("");
ret = garglist->word->word;
garglist = garglist->next;
return ret;
}
static int
getint ()
{
intmax_t ret;
ret = getintmax ();
if (ret > INT_MAX)
{
printf_erange (garglist->word->word);
ret = INT_MAX;
}
else if (ret < INT_MIN)
{
printf_erange (garglist->word->word);
ret = INT_MIN;
}
return ((int)ret);
}
static intmax_t
getintmax ()
{
intmax_t ret;
char *ep;
if (garglist == 0)
return (0);
if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
return asciicode ();
errno = 0;
ret = strtoimax (garglist->word->word, &ep, 0);
if (*ep)
{
sh_invalidnum (garglist->word->word);
/* POSIX.2 says ``...a diagnostic message shall be written to standard
error, and the utility shall not exit with a zero exit status, but
shall continue processing any remaining operands and shall write the
value accumulated at the time the error was detected to standard
output.'' Yecch. */
ret = 0;
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
}
static uintmax_t
getuintmax ()
{
uintmax_t ret;
char *ep;
if (garglist == 0)
return (0);
if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
return asciicode ();
errno = 0;
ret = strtoumax (garglist->word->word, &ep, 0);
if (*ep)
{
sh_invalidnum (garglist->word->word);
/* Same POSIX.2 conversion error requirements as getintmax(). */
ret = 0;
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
}
static floatmax_t
getfloatmax ()
{
floatmax_t ret;
char *ep;
if (garglist == 0)
return (0);
if (garglist->word->word[0] == '\'' || garglist->word->word[0] == '"')
return asciicode ();
errno = 0;
ret = strtofltmax (garglist->word->word, &ep);
if (*ep)
{
sh_invalidnum (garglist->word->word);
/* Same thing about POSIX.2 conversion error requirements. */
ret = 0;
conversion_error = 1;
}
else if (errno == ERANGE)
printf_erange (garglist->word->word);
garglist = garglist->next;
return (ret);
}
/* NO check is needed for garglist here. */
static int
asciicode ()
{
register int ch;
ch = garglist->word->word[1];
garglist = garglist->next;
return (ch);
}
+155
View File
@@ -0,0 +1,155 @@
*** ../bash-3.0/lib/readline/display.c Thu May 27 22:57:51 2004
--- lib/readline/display.c Mon Aug 30 11:55:02 2004
***************
*** 202,206 ****
{
char *r, *ret, *p;
! int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
/* Short-circuit if we can. */
--- 202,206 ----
{
char *r, *ret, *p;
! int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
/* Short-circuit if we can. */
***************
*** 223,226 ****
--- 223,227 ----
invfl = 0; /* invisible chars in first line of prompt */
+ invflset = 0; /* we only want to set invfl once */
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
***************
*** 250,254 ****
*r++ = *p++;
if (!ignoring)
! rl += ind - pind;
else
ninvis += ind - pind;
--- 251,258 ----
*r++ = *p++;
if (!ignoring)
! {
! rl += ind - pind;
! physchars += _rl_col_width (pmt, pind, ind);
! }
else
ninvis += ind - pind;
***************
*** 260,273 ****
*r++ = *p;
if (!ignoring)
! rl++; /* visible length byte counter */
else
ninvis++; /* invisible chars byte counter */
}
! if (rl >= _rl_screenwidth)
! invfl = ninvis;
!
! if (ignoring == 0)
! physchars++;
}
}
--- 264,280 ----
*r++ = *p;
if (!ignoring)
! {
! rl++; /* visible length byte counter */
! physchars++;
! }
else
ninvis++; /* invisible chars byte counter */
}
! if (invflset == 0 && rl >= _rl_screenwidth)
! {
! invfl = ninvis;
! invflset = 1;
! }
}
}
***************
*** 352,356 ****
&prompt_last_invisible,
(int *)NULL,
! (int *)NULL);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
--- 359,363 ----
&prompt_last_invisible,
(int *)NULL,
! &prompt_physical_chars);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
***************
*** 359,363 ****
(int *)NULL,
&prompt_invis_chars_first_line,
! &prompt_physical_chars);
*t = c;
return (prompt_prefix_length);
--- 366,370 ----
(int *)NULL,
&prompt_invis_chars_first_line,
! (int *)NULL);
*t = c;
return (prompt_prefix_length);
***************
*** 418,422 ****
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
! int newlines, lpos, temp, modmark;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
--- 425,429 ----
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
! int newlines, lpos, temp, modmark, n0, num;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
***************
*** 574,577 ****
--- 581,585 ----
#if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize);
+ num = 0;
#endif
***************
*** 592,596 ****
--- 600,619 ----
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
+ #if defined (HANDLE_MULTIBYTE)
+ n0 = num;
+ temp = local_prompt ? strlen (local_prompt) : 0;
+ while (num < temp)
+ {
+ if (_rl_col_width (local_prompt, n0, num) > _rl_screenwidth)
+ {
+ num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
+ break;
+ }
+ num++;
+ }
+ temp = num +
+ #else
temp = ((newlines + 1) * _rl_screenwidth) +
+ #endif /* !HANDLE_MULTIBYTE */
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
***************
*** 598,602 ****
--- 621,629 ----
inv_lbreaks[++newlines] = temp;
+ #if defined (HANDLE_MULTIBYTE)
+ lpos -= _rl_col_width (local_prompt, n0, num);
+ #else
lpos -= _rl_screenwidth;
+ #endif
}
+1550 -1539
View File
File diff suppressed because it is too large Load Diff
+21 -8
View File
@@ -1476,6 +1476,10 @@ Expands to the positional parameters, starting from one. When the
expansion occurs within double quotes, each parameter expands to a
separate word. That is, &quot;<B>$@</B>&quot; is equivalent to
&quot;<B>$1</B>&quot; &quot;<B>$2</B>&quot; ...
If the double-quoted expansion occurs within a word, the expansion of
the first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word.
When there are no positional parameters, &quot;<B>$@</B>&quot; and
<B>$@</B>
@@ -1597,7 +1601,7 @@ The command argument to the <B>-c</B> invocation option.
<DD>
An array variable whose members are the line numbers in source files
corresponding to each member of @var{FUNCNAME}.
corresponding to each member of <B>FUNCNAME</B>.
<B>${BASH_LINENO[</B><I>$i</I><B>]}</B> is the line number in the source
file where <B>${FUNCNAME[</B><I>$i + 1</I><B>]}</B> was called.
The corresponding source file name is <B>${BASH_SOURCE[</B><I>$i + 1</I><B>]}.
@@ -2625,7 +2629,12 @@ character of the
</FONT>
special variable, and ${<I>name</I>[@]} expands each element of
<I>name</I> to a separate word. When there are no array members,
${<I>name</I>[@]} expands to nothing. This is analogous to the expansion
${<I>name</I>[@]} expands to nothing.
If the double-quoted expansion occurs within a word, the expansion of
the first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word.
This is analogous to the expansion
of the special parameters <B>*</B> and <B>@</B> (see
<B>Special Parameters</B>
@@ -4497,6 +4506,10 @@ If the <I>file</I> argument to one of the primaries is one of
descriptor 0, 1, or 2, respectively, is checked.
<P>
Unless otherwise specified, primaries that operate on files follow symbolic
links and operate on the target of the link, rather than the link itself.
<P>
<DL COMPACT>
<DT><B>-a </B><I>file</I>
@@ -7645,8 +7658,8 @@ For each <I>name</I> in the argument list for which no <I>value</I>
is supplied, the name and value of the alias is printed.
<B>Alias</B> returns true unless a <I>name</I> is given for which
no alias has been defined.
<DT><B>bg</B> [<I>jobspec</I>]<DD>
Resume the suspended job <I>jobspec</I> in the background, as if it
<DT><B>bg</B> [<I>jobspec</I> ...]<DD>
Resume each suspended job <I>jobspec</I> in the background, as if it
had been started with
<B>&amp;</B>.
@@ -7657,8 +7670,8 @@ If <I>jobspec</I> is not present, the shell's notion of the
<I>jobspec</I>
returns 0 unless run when job control is disabled or, when run with
job control enabled, if <I>jobspec</I> was not found or started without
job control.
job control enabled, if the last <I>jobspec</I> was not found or was
started without job control.
<DT><B>bind</B> [<B>-m</B> <I>keymap</I>] [<B>-lpsvPSV</B>]<DD>
<DT><B>bind</B> [<B>-m</B> <I>keymap</I>] [<B>-q</B> <I>function</I>] [<B>-u</B> <I>function</I>] [<B>-r</B> <I>keyseq</I>]<DD>
@@ -10588,7 +10601,7 @@ command, and before the first command executes in a shell function (see
</FONT>
above).
Refer to the description of the <B>extglob</B> option to the
Refer to the description of the <B>extdebug</B> option to the
<B>shopt</B> builtin for details of its effect on the <B>DEBUG</B> trap.
If a
<I>sigspec</I>
@@ -11354,6 +11367,6 @@ Array variables may not (yet) be exported.
</DL>
<HR>
This document was created by man2html from bash.1.<BR>
Time: 19 July 2004 16:04:22 EDT
Time: 30 August 2004 08:27:20 EDT
</BODY>
</HTML>
+3498 -3484
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+38 -12
View File
@@ -1,6 +1,6 @@
<HTML>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Created on August, 3 2004 by texi2html 1.64 -->
<!-- Created on August, 30 2004 by texi2html 1.64 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
Karl Berry <karl@freefriends.org>
@@ -33,10 +33,10 @@ Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
<H1>Bash Reference Manual</H1></P><P>
This text is a brief description of the features that are present in
the Bash shell (version 3.0, 1 August 2004)..
the Bash shell (version 3.0, 27 August 2004)..
</P><P>
This is Edition 3.0, last updated 1 August 2004,
This is Edition 3.0, last updated 27 August 2004,
of <CITE>The GNU Bash Reference Manual</CITE>,
for <CODE>Bash</CODE>, Version 3.0.
</P><P>
@@ -1750,6 +1750,10 @@ Expands to the positional parameters, starting from one. When the
expansion occurs within double quotes, each parameter expands to a
separate word. That is, <CODE>"$@"</CODE> is equivalent to
<CODE>"$1" "$2" <small>...</small></CODE>.
If the double-quoted expansion occurs within a word, the expansion of
the first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word.
When there are no positional parameters, <CODE>"$@"</CODE> and
<CODE>$@</CODE>
expand to nothing (i.e., they are removed).
@@ -6980,6 +6984,10 @@ If the <VAR>file</VAR> argument to one of the primaries is one of
descriptor 0, 1, or 2, respectively, is checked.
</P><P>
Unless otherwise specified, primaries that operate on files follow symbolic
links and operate on the target of the link, rather than the link itself.
</P><P>
<DL COMPACT>
<DT><CODE>-a <VAR>file</VAR></CODE>
<DD>True if <VAR>file</VAR> exists.
@@ -7406,12 +7414,18 @@ The braces are required to avoid
conflicts with the shell's filename expansion operators. If the
<VAR>subscript</VAR> is <SAMP>`@'</SAMP> or <SAMP>`*'</SAMP>, the word expands to all members
of the array <VAR>name</VAR>. These subscripts differ only when the word
appears within double quotes. If the word is double-quoted,
appears within double quotes.
If the word is double-quoted,
<CODE>${name[*]}</CODE> expands to a single word with
the value of each array member separated by the first character of the
<CODE>IFS</CODE> variable, and <CODE>${name[@]}</CODE> expands each element of
<VAR>name</VAR> to a separate word. When there are no array members,
<CODE>${name[@]}</CODE> expands to nothing. This is analogous to the
<CODE>${name[@]}</CODE> expands to nothing.
If the double-quoted expansion occurs within a word, the expansion of
the first parameter is joined with the beginning part of the original
word, and the expansion of the last parameter is joined with the last
part of the original word.
This is analogous to the
expansion of the special parameters <SAMP>`@'</SAMP> and <SAMP>`*'</SAMP>.
<CODE>${#name[</CODE><VAR>subscript</VAR><CODE>]}</CODE> expands to the length of
<CODE>${name[</CODE><VAR>subscript</VAR><CODE>]}</CODE>.
@@ -7995,6 +8009,18 @@ indication of whether or not a history entry has been modified.
The default editor used by <CODE>fc</CODE> is <CODE>ed</CODE>.
<P>
<LI>
The <CODE>type</CODE> and <CODE>command</CODE> builtins will not report a non-executable
file as having been found, though the shell will attempt to execute such a
file if it is the only so-named file found in <CODE>$PATH</CODE>.
<P>
<LI>
When the <CODE>xpg_echo</CODE> option is enabled, Bash does not attempt to interpret
any arguments to <CODE>echo</CODE> as options. Each argument is displayed, after
escape characters are converted.
<P>
</OL>
<P>
@@ -8193,14 +8219,14 @@ Bash does not print another warning, and the stopped jobs are terminated.
<DT><CODE>bg</CODE>
<DD><A NAME="IDX273"></A>
<TABLE><tr><td>&nbsp;</td><td class=example><pre>bg [<VAR>jobspec</VAR>]
</pre></td></tr></table>Resume the suspended job <VAR>jobspec</VAR> in the background, as if it
<TABLE><tr><td>&nbsp;</td><td class=example><pre>bg [<VAR>jobspec</VAR> <small>...</small>]
</pre></td></tr></table>Resume each suspended job <VAR>jobspec</VAR> in the background, as if it
had been started with <SAMP>`&#38;'</SAMP>.
If <VAR>jobspec</VAR> is not supplied, the current job is used.
The return status is zero unless it is run when job control is not
enabled, or, when run with job control enabled, if <VAR>jobspec</VAR> was
not found or <VAR>jobspec</VAR> specifies a job that was started without
job control.
enabled, or, when run with job control enabled, if the last
<VAR>jobspec</VAR> was not found or the last <VAR>jobspec</VAR> specifies a job
that was started without job control.
<P>
<DT><CODE>fg</CODE>
@@ -15025,7 +15051,7 @@ to permit their use in free software.
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="bashref.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<H1>About this document</H1>
This document was generated by <I>Chet Ramey</I> on <I>August, 3 2004</I>
This document was generated by <I>Chet Ramey</I> on <I>August, 30 2004</I>
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
<P></P>
@@ -15187,7 +15213,7 @@ the following structure:
<BR>
<FONT SIZE="-1">
This document was generated
by <I>Chet Ramey</I> on <I>August, 3 2004</I>
by <I>Chet Ramey</I> on <I>August, 30 2004</I>
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
+1055 -925
View File
File diff suppressed because it is too large Load Diff
+35 -34
View File
@@ -1,6 +1,6 @@
This is TeX, Version 3.14159 (Web2C 7.3.1) (format=tex 2001.2.12) 3 AUG 2004 09:54
**/usr/homes/chet/src/bash/src/doc/bashref.texi
(/usr/homes/chet/src/bash/src/doc/bashref.texi (texinfo.tex
This is TeX, Version 3.14159 (Web2C 7.4.5) (format=tex 2003.12.31) 30 AUG 2004 08:27
**/Users/chet/src/bash/src/doc/bashref.texi
(/Users/chet/src/bash/src/doc/bashref.texi (./texinfo.tex
Loading texinfo [version 2003-02-03.16]: Basics,
\bindingoffset=\dimen16
\normaloffset=\dimen17
@@ -106,7 +106,7 @@ cross references,
\auxfile=\write2
\savesfregister=\count46
\footnoteno=\count47
(/usr/local/share/texmf/tex/plain/dvips/epsf.tex
(/sw/share/texmf/tex/generic/misc/epsf.tex
\epsffilein=\read0
\epsfframemargin=\dimen39
\epsfframethickness=\dimen40
@@ -119,18 +119,18 @@ cross references,
\epsfnoopenhelp=\toks24
)
\noepsfhelp=\toks25
localization,
localization,
\nolanghelp=\toks26
\defaultparindent=\dimen47
and turning on texinfo input format.) (bashref.aux)
and turning on texinfo input format.) (./bashref.aux)
@cpindfile=@write3
@fnindfile=@write4
@vrindfile=@write5
@tpindfile=@write6
@kyindfile=@write7
@pgindfile=@write8
(version.texi)
(./version.texi)
@btindfile=@write9
@rwindfile=@write10
[1
@@ -152,11 +152,12 @@ localization,
\openout10 = `bashref.rw'.
] [2] (bashref.toc [-1] [-2] [-3]) [-4] Chapter 1
]
[2] (./bashref.toc [-1] [-2] [-3]) [-4] Chapter 1
\openout0 = `bashref.toc'.
[1] Chapter 2 [2]
[3] Chapter 3 [4] [5] [6] [7] [8] [9] [10]
[1] Chapter 2 [2] [3]
Chapter 3 [4] [5] [6] [7] [8] [9] [10]
Overfull \hbox (43.33539pt too wide) in paragraph at lines 862--862
[]@texttt case @textttsl word @texttt in [ [(] @textttsl pat-tern @texttt [| @
textttsl pat-tern@texttt ][]) @textttsl command-list @texttt ;;][] esac[][]
@@ -171,7 +172,7 @@ textttsl pat-tern@texttt ][]) @textttsl command-list @texttt ;;][] esac[][]
[11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25]
[26] [27] [28] [29] [30] [31] Chapter 4 [32] [33] [34] [35] [36] [37] [38]
Underfull \hbox (badness 5231) in paragraph at lines 3102--3115
Underfull \hbox (badness 5231) in paragraph at lines 3106--3119
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
@@ -184,7 +185,7 @@ m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
.etc.
[39] [40] [41] [42] [43]
Overfull \hbox (43.33536pt too wide) in paragraph at lines 3439--3439
Overfull \hbox (43.33536pt too wide) in paragraph at lines 3443--3443
[]@texttt read [-ers] [-a @textttsl aname@texttt ] [-d @textttsl de-lim@texttt
] [-n @textttsl nchars@texttt ] [-p @textttsl prompt@texttt ] [-t @textttsl ti
me-
@@ -198,7 +199,7 @@ me-
.etc.
[44] [45] [46] [47] [48] [49] [50] [51]
Underfull \hbox (badness 4036) in paragraph at lines 4048--4055
Underfull \hbox (badness 4036) in paragraph at lines 4052--4059
@texttt -x[]@textrm Print a trace of sim-ple com-mands, @texttt \@textrm fB-fo
r@texttt \@textrm fP com-mands,
@@ -211,7 +212,7 @@ r@texttt \@textrm fP com-mands,
.etc.
[52] [53] Chapter 5 [54] [55] [56] [57] [58] [59] [60] [61] Chapter 6 [62]
Overfull \hbox (51.96864pt too wide) in paragraph at lines 4765--4765
Overfull \hbox (51.96864pt too wide) in paragraph at lines 4769--4769
[]@texttt bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@t
exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -224,7 +225,7 @@ exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
Overfull \hbox (76.23077pt too wide) in paragraph at lines 4766--4766
Overfull \hbox (76.23077pt too wide) in paragraph at lines 4770--4770
[]@texttt bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@texttt
] [-O @textttsl shopt_option@texttt ] -c @textttsl string @texttt [@textttsl ar
-
@@ -238,7 +239,7 @@ Overfull \hbox (76.23077pt too wide) in paragraph at lines 4766--4766
.etc.
Overfull \hbox (34.72258pt too wide) in paragraph at lines 4767--4767
Overfull \hbox (34.72258pt too wide) in paragraph at lines 4771--4771
[]@texttt bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@text
tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
@@ -251,7 +252,7 @@ tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
.etc.
[63] [64]
Underfull \hbox (badness 2245) in paragraph at lines 4941--4943
Underfull \hbox (badness 2245) in paragraph at lines 4945--4947
[]@textrm When a lo-gin shell ex-its, Bash reads and ex-e-cutes com-mands from
the file
@@ -265,8 +266,8 @@ the file
[65] [66] [67] [68] [69] [70] [71] [72] [73] [74] [75] [76] [77] [78]
Chapter 7 [79] [80] [81] [82] [83]
(/usr/homes/chet/src/bash/src/lib/readline/doc/rluser.texi Chapter 8 [84]
[85] [86] [87] [88] [89]
(/Users/chet/src/bash/src/lib/readline/doc/rluser.texi Chapter 8 [84] [85]
[86] [87] [88] [89]
Underfull \hbox (badness 5231) in paragraph at lines 488--504
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
@@ -317,9 +318,9 @@ Underfull \hbox (badness 2753) in paragraph at lines 1742--1745
.@texttt o
.etc.
[109]) (/usr/homes/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
[109]) (/Users/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
[110] [111] [112] [113] [114]) Chapter 10 [115] [116] [117] [118] [119]
Underfull \hbox (badness 2772) in paragraph at lines 6619--6623
Underfull \hbox (badness 2772) in paragraph at lines 6642--6646
[]@textrm Enable sup-port for large files (@texttt http://www.sas.com/standard
s/large_
@@ -332,8 +333,8 @@ s/large_
.etc.
[120] [121] [122] Appendix A [123] [124] Appendix B [125] [126] [127] [128]
[129] [130] Appendix C [131] [132] (fdl.texi [133] [134] [135] [136] [137]
[138]) (Index of Shell Builtin Commands) [139] [140] (bashref.bts)
[129] [130] Appendix C [131] [132] (./fdl.texi [133] [134] [135] [136] [137]
[138]) (Index of Shell Builtin Commands) [139] [140] (./bashref.bts)
(Index of Shell Reserved Words)
Overfull \vbox (42.26959pt too high) has occurred while \output is active
\vbox(643.19986+0.0)x433.62, glue set - 1.0
@@ -352,16 +353,16 @@ Overfull \vbox (42.26959pt too high) has occurred while \output is active
.etc.
[141] [142] (bashref.rws) (Parameter and Variable Index) [143] [144]
(bashref.vrs [145]) (Function Index) [146] (bashref.fns [147]) (Concept Index)
[148] (bashref.cps [149]) [150] )
[141] [142] (./bashref.rws) (Parameter and Variable Index) [143] [144]
(./bashref.vrs [145]) (Function Index) [146] (./bashref.fns [147])
(Concept Index) [148] (./bashref.cps [149]) [150] )
Here is how much of TeX's memory you used:
1713 strings out of 13013
23227 string characters out of 97233
52386 words of memory out of 263001
2577 multiletter control sequences out of 10000+0
31953 words of font info for 111 fonts, out of 400000 for 1000
1726 strings out of 98002
23501 string characters out of 1221986
52369 words of memory out of 1000001
2577 multiletter control sequences out of 10000+50000
31953 words of font info for 111 fonts, out of 500000 for 1000
19 hyphenation exceptions out of 1000
15i,8n,11p,273b,465s stack positions out of 300i,100n,500p,50000b,4000s
15i,8n,11p,269b,465s stack positions out of 1500i,500n,5000p,200000b,5000s
Output written on bashref.dvi (156 pages, 580500 bytes).
Output written on bashref.dvi (156 pages, 581772 bytes).
+12843 -11084
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -48,13 +48,13 @@ BBAASSHH BBUUIILLTTIINN CCOOMMMMAANNDDSS
returns true unless a _n_a_m_e is given for which no alias has been
defined.
bbgg [_j_o_b_s_p_e_c]
Resume the suspended job _j_o_b_s_p_e_c in the background, as if it had
been started with &&. If _j_o_b_s_p_e_c is not present, the shell's
bbgg [_j_o_b_s_p_e_c ...]
Resume each suspended job _j_o_b_s_p_e_c in the background, as if it
had been started with &&. If _j_o_b_s_p_e_c is not present, the shell's
notion of the _c_u_r_r_e_n_t _j_o_b is used. bbgg _j_o_b_s_p_e_c returns 0 unless
run when job control is disabled or, when run with job control
enabled, if _j_o_b_s_p_e_c was not found or started without job con-
trol.
enabled, if the last _j_o_b_s_p_e_c was not found or was started with-
out job control.
bbiinndd [--mm _k_e_y_m_a_p] [--llppssvvPPSSVV]
bbiinndd [--mm _k_e_y_m_a_p] [--qq _f_u_n_c_t_i_o_n] [--uu _f_u_n_c_t_i_o_n] [--rr _k_e_y_s_e_q]
@@ -1253,7 +1253,7 @@ BBAASSHH BBUUIILLTTIINN CCOOMMMMAANNDDSS
_s_i_m_p_l_e _c_o_m_m_a_n_d, _f_o_r command, _c_a_s_e command, _s_e_l_e_c_t command, every
arithmetic _f_o_r command, and before the first command executes in
a shell function (see SSHHEELLLL GGRRAAMMMMAARR above). Refer to the
description of the eexxttgglloobb option to the sshhoopptt builtin for
description of the eexxttddeebbuugg option to the sshhoopptt builtin for
details of its effect on the DDEEBBUUGG trap. If a _s_i_g_s_p_e_c is EERRRR,
the command _a_r_g is executed whenever a simple command has a
non-zero exit status, subject to the following conditions. The
+30 -30
View File
@@ -1,6 +1,6 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.18.1
%%CreationDate: Mon Jul 19 16:04:16 2004
%%CreationDate: Mon Aug 30 08:27:13 2004
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%+ font Times-Italic
@@ -297,30 +297,30 @@ F 1.313(plied, the name and v)144 428.4 R 1.314
(returns true unless a)3.814 F F3(name)3.814 E F0 1.314(is gi)3.814 F
-.15(ve)-.25 G 3.814(nf).15 G(or)-3.814 E
(which no alias has been de\214ned.)144 440.4 Q F2(bg)108 457.2 Q F0([)
2.5 E F3(jobspec)A F0(])A .357(Resume the suspended job)144 469.2 R F3
(jobspec)2.857 E F0 .356
(in the background, as if it had been started with)2.857 F F2(&)2.856 E
F0 5.356(.I)C(f)-5.356 E F3(jobspec)2.856 E F0 .472
(is not present, the shell')144 481.2 R 2.973(sn)-.55 G .473
(otion of the)-2.973 F F3(curr)2.973 E .473(ent job)-.37 F F0 .473
(is used.)2.973 F F2(bg)5.473 E F3(jobspec)4.713 E F0 .473
(returns 0 unless run when)3.283 F .663(job control is disabled or)144
493.2 R 3.163(,w)-.4 G .663(hen run with job control enabled, if)-3.163
F F3(jobspec)3.163 E F0 -.1(wa)3.163 G 3.163(sn).1 G .663
(ot found or started)-3.163 F(without job control.)144 505.2 Q F2(bind)
108 522 Q F0([)2.5 E F2<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0 2.5(][)C F2
(\255lpsvPSV)-2.5 E F0(])A F2(bind)108 534 Q F0([)2.5 E F2<ad6d>A F3 -.1
(ke)2.5 G(ymap)-.2 E F0 2.5(][)C F2<ad71>-2.5 E F3(function)2.5 E F0 2.5
(][)C F2<ad75>-2.5 E F3(function)2.5 E F0 2.5(][)C F2<ad72>-2.5 E F3 -.1
(ke)2.5 G(yseq)-.2 E F0(])A F2(bind)108 546 Q F0([)2.5 E F2<ad6d>A F3
-.1(ke)2.5 G(ymap)-.2 E F0(])A F2<ad66>2.5 E F3(\214lename)2.5 E F2
(bind)108 558 Q F0([)2.5 E F2<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0(])A
F2<ad78>2.5 E F3 -.1(ke)2.5 G(yseq)-.2 E F0(:)A F3(shell\255command)A F2
(bind)108 570 Q F0([)2.5 E F2<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0(])A
F3 -.1(ke)2.5 G(yseq)-.2 E F0(:)A F3(function\255name)A F2(bind)108 582
Q F3 -.37(re)2.5 G(adline\255command).37 E F0 .238(Display current)144
594 R F2 -.18(re)2.738 G(adline).18 E F0 -.1(ke)2.738 G 2.738(ya)-.05 G
.239(nd function bindings, bind a k)-2.738 F .539 -.15(ey s)-.1 H .239
2.5 E F3(jobspec)A F0(...])2.5 E .847(Resume each suspended job)144
469.2 R F3(jobspec)3.347 E F0 .847
(in the background, as if it had been started with)3.347 F F2(&)3.347 E
F0 5.847(.I)C(f)-5.847 E F3(job-)3.347 E(spec)144 481.2 Q F0 .689
(is not present, the shell')3.188 F 3.189(sn)-.55 G .689(otion of the)
-3.189 F F3(curr)3.189 E .689(ent job)-.37 F F0 .689(is used.)3.189 F F2
(bg)5.689 E F3(jobspec)4.929 E F0 .689(returns 0 unless run)3.499 F
1.284(when job control is disabled or)144 493.2 R 3.784(,w)-.4 G 1.283
(hen run with job control enabled, if the last)-3.784 F F3(jobspec)3.783
E F0 -.1(wa)3.783 G 3.783(sn).1 G(ot)-3.783 E(found or w)144 505.2 Q
(as started without job control.)-.1 E F2(bind)108 522 Q F0([)2.5 E F2
<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0 2.5(][)C F2(\255lpsvPSV)-2.5 E F0
(])A F2(bind)108 534 Q F0([)2.5 E F2<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E
F0 2.5(][)C F2<ad71>-2.5 E F3(function)2.5 E F0 2.5(][)C F2<ad75>-2.5 E
F3(function)2.5 E F0 2.5(][)C F2<ad72>-2.5 E F3 -.1(ke)2.5 G(yseq)-.2 E
F0(])A F2(bind)108 546 Q F0([)2.5 E F2<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E
F0(])A F2<ad66>2.5 E F3(\214lename)2.5 E F2(bind)108 558 Q F0([)2.5 E F2
<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0(])A F2<ad78>2.5 E F3 -.1(ke)2.5 G
(yseq)-.2 E F0(:)A F3(shell\255command)A F2(bind)108 570 Q F0([)2.5 E F2
<ad6d>A F3 -.1(ke)2.5 G(ymap)-.2 E F0(])A F3 -.1(ke)2.5 G(yseq)-.2 E F0
(:)A F3(function\255name)A F2(bind)108 582 Q F3 -.37(re)2.5 G
(adline\255command).37 E F0 .238(Display current)144 594 R F2 -.18(re)
2.738 G(adline).18 E F0 -.1(ke)2.738 G 2.738(ya)-.05 G .239
(nd function bindings, bind a k)-2.738 F .539 -.15(ey s)-.1 H .239
(equence to a).15 F F2 -.18(re)2.739 G(adline).18 E F0 .239(function or)
2.739 F .476(macro, or set a)144 606 R F2 -.18(re)2.976 G(adline).18 E
F0 -.25(va)2.976 G 2.976(riable. Each).25 F .476(non-option ar)2.976 F
@@ -2104,11 +2104,11 @@ E F1(case)3.016 E F2(command,)3.016 E F1(select)3.016 E F2 .515
(command, and befor)3.015 F(e)-.18 E 1.001
(the \214rst command executes in a shell function \(see)144 668.4 R F4
1.001(SHELL GRAMMAR)3.501 F F2 3.501(above\). Refer)3.251 F(to)3.501 E
1.199(the description of the)144 680.4 R F3(extglob)3.699 E F2 1.199
(option to the)3.699 F F3(shopt)3.699 E F2 1.199
(builtin for details of its ef)3.699 F 1.198(fect on the)-.18 F F3
(DEBUG)144 692.4 Q F2 3.153(trap. If)3.153 F(a)3.153 E F1(sigspec)3.563
E F2(is)3.473 E F4(ERR)3.153 E F5(,)A F2 .653(the command)2.903 F F1(ar)
.679(the description of the)144 680.4 R F3(extdebug)3.178 E F2 .678
(option to the)3.178 F F3(shopt)3.178 E F2 .678
(builtin for details of its ef)3.178 F .678(fect on the)-.18 F F3(DEBUG)
144 692.4 Q F2 3.153(trap. If)3.153 F(a)3.153 E F1(sigspec)3.563 E F2
(is)3.473 E F4(ERR)3.153 E F5(,)A F2 .653(the command)2.903 F F1(ar)
3.613 E(g)-.18 E F2 .653(is executed whenever a simple com-)3.633 F .241
(mand has a non\255zer)144 704.4 R 2.741(oe)-.18 G .24
(xit status, subject to the following conditions.)-2.741 F(The)5.24 E F4
+1 -1
View File
@@ -1,6 +1,6 @@
%!PS-Adobe-3.0
%%Creator: groff version 1.18.1
%%CreationDate: Mon Jul 19 16:04:16 2004
%%CreationDate: Mon Aug 30 08:27:13 2004
%%DocumentNeededResources: font Times-Roman
%%+ font Times-Bold
%%DocumentSuppliedResources: procset grops 1.18 1
+2 -1
View File
@@ -40,7 +40,8 @@ extern char *xstrchr __P((const char *, int));
#define MB_NULLWCH(x) ((x) == 0)
#endif
#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? mbstrlen (s) : STRLEN (s))
#define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
#define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
#else /* !HANDLE_MULTIBYTE */
+81
View File
@@ -0,0 +1,81 @@
*** ../bash-3.0/jobs.c Fri Apr 23 16:28:25 2004
--- jobs.c Wed Aug 18 11:15:07 2004
***************
*** 998,1002 ****
if (job != NO_JOB)
! printf ("[%d] %ld\n", job + 1, (long)pid);
else
programming_error (_("describe_pid: %ld: no such pid"), (long)pid);
--- 998,1002 ----
if (job != NO_JOB)
! fprintf (stderr, "[%d] %ld\n", job + 1, (long)pid);
else
programming_error (_("describe_pid: %ld: no such pid"), (long)pid);
***************
*** 1779,1784 ****
{
fail = 0;
! for (p = jobs[job]->pipe; p->next != jobs[job]->pipe; p = p->next)
! if (p->status != EXECUTION_SUCCESS) fail = p->status;
return fail;
}
--- 1779,1789 ----
{
fail = 0;
! p = jobs[job]->pipe;
! do
! {
! if (p->status != EXECUTION_SUCCESS) fail = p->status;
! p = p->next;
! }
! while (p != jobs[job]->pipe);
return fail;
}
***************
*** 2312,2321 ****
if (foreground == 0)
! fprintf (stderr, "[%d]%c ", job + 1,
(job == current_job) ? '+': ((job == previous_job) ? '-' : ' '));
do
{
! fprintf (stderr, "%s%s",
p->command ? p->command : "",
p->next != jobs[job]->pipe? " | " : "");
--- 2317,2326 ----
if (foreground == 0)
! printf ("[%d]%c ", job + 1,
(job == current_job) ? '+': ((job == previous_job) ? '-' : ' '));
do
{
! printf ("%s%s",
p->command ? p->command : "",
p->next != jobs[job]->pipe? " | " : "");
***************
*** 2325,2334 ****
if (foreground == 0)
! fprintf (stderr, " &");
if (strcmp (wd, jobs[job]->wd) != 0)
! fprintf (stderr, " (wd: %s)", polite_directory_format (jobs[job]->wd));
! fprintf (stderr, "\n");
/* Run the job. */
--- 2330,2339 ----
if (foreground == 0)
! printf (" &");
if (strcmp (wd, jobs[job]->wd) != 0)
! printf (" (wd: %s)", polite_directory_format (jobs[job]->wd));
! printf ("\n");
/* Run the job. */
+29 -6
View File
@@ -250,7 +250,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
while (l--)
*r++ = *p++;
if (!ignoring)
rl += ind - pind;
{
rl += ind - pind;
physchars += _rl_col_width (pmt, pind, ind);
}
else
ninvis += ind - pind;
p--; /* compensate for later increment */
@@ -260,7 +263,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
{
*r++ = *p;
if (!ignoring)
rl++; /* visible length byte counter */
{
rl++; /* visible length byte counter */
physchars++;
}
else
ninvis++; /* invisible chars byte counter */
}
@@ -270,9 +276,6 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
invfl = ninvis;
invflset = 1;
}
if (ignoring == 0)
physchars++;
}
}
@@ -421,7 +424,7 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum;
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp, modmark;
int newlines, lpos, temp, modmark, n0, num;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
@@ -577,6 +580,7 @@ rl_redisplay ()
#if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize);
num = 0;
#endif
/* prompt_invis_chars_first_line is the number of invisible characters in
@@ -595,13 +599,32 @@ rl_redisplay ()
probably too much work for the benefit gained. How many people have
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
#if defined (HANDLE_MULTIBYTE)
n0 = num;
temp = local_prompt ? strlen (local_prompt) : 0;
while (num < temp)
{
if (_rl_col_width (local_prompt, n0, num) > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
break;
}
num++;
}
temp = num +
#else
temp = ((newlines + 1) * _rl_screenwidth) +
#endif /* !HANDLE_MULTIBYTE */
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
lpos -= _rl_col_width (local_prompt, n0, num);
#else
lpos -= _rl_screenwidth;
#endif
}
prompt_last_screen_line = newlines;
+23
View File
@@ -0,0 +1,23 @@
*** ../bash-3.0/lib/readline/mbutil.c Wed Jan 14 09:44:52 2004
--- lib/readline/mbutil.c Wed Aug 18 22:25:57 2004
***************
*** 127,135 ****
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
! while (wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
! if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
break;
}
--- 127,135 ----
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
! while (tmp > 0 && wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
! if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
break;
}
+1 -1
View File
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 0
#define PATCHLEVEL 1
#endif /* _PATCHLEVEL_H_ */
+20
View File
@@ -0,0 +1,20 @@
*** ../bash-3.0/pcomplete.c Thu Jan 8 10:36:17 2004
--- pcomplete.c Tue Aug 3 23:15:41 2004
***************
*** 864,867 ****
--- 864,869 ----
v = convert_var_to_array (v);
v = assign_array_var_from_word_list (v, lwords);
+
+ VUNSETATTR (v, att_invisible);
return v;
}
***************
*** 1022,1025 ****
--- 1024,1029 ----
if (array_p (v) == 0)
v = convert_var_to_array (v);
+
+ VUNSETATTR (v, att_invisible);
a = array_cell (v);
+30
View File
@@ -0,0 +1,30 @@
*** ../bash-3.0/include/shmbutil.h Mon Apr 19 09:59:42 2004
--- include/shmbutil.h Thu Sep 2 15:20:47 2004
***************
*** 32,35 ****
--- 32,37 ----
extern size_t xdupmbstowcs __P((wchar_t **, char ***, const char *));
+ extern size_t mbstrlen __P((const char *));
+
extern char *xstrchr __P((const char *, int));
***************
*** 39,42 ****
--- 41,47 ----
#endif
+ #define MBSLEN(s) (((s) && (s)[0]) ? ((s)[1] ? mbstrlen (s) : 1) : 0)
+ #define MB_STRLEN(s) ((MB_CUR_MAX > 1) ? MBSLEN (s) : STRLEN (s))
+
#else /* !HANDLE_MULTIBYTE */
***************
*** 54,57 ****
--- 59,64 ----
#define MB_NULLWCH(x) (0)
#endif
+
+ #define MB_STRLEN(s) (STRLEN(s))
#endif /* !HANDLE_MULTIBYTE */
+12 -1
View File
@@ -6854,12 +6854,23 @@ static WORD_LIST *
word_list_split (list)
WORD_LIST *list;
{
WORD_LIST *result, *t, *tresult;
WORD_LIST *result, *t, *tresult, *e;
for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
{
tresult = word_split (t->word, ifs_value);
#if 0
result = (WORD_LIST *) list_append (result, tresult);
#else
if (result == 0)
result = e = tresult;
else
{
e->next = tresult;
while (e->next)
e = e->next;
}
#endif
}
return (result);
}
+108
View File
@@ -0,0 +1,108 @@
*** ../bash-3.0/subst.c Sun Jul 4 13:56:13 2004
--- subst.c Thu Aug 12 13:36:17 2004
***************
*** 4692,4695 ****
--- 4692,4715 ----
}
+ #if defined (HANDLE_MULTIBYTE)
+ size_t
+ mbstrlen (s)
+ const char *s;
+ {
+ size_t clen, nc;
+ mbstate_t mbs;
+
+ nc = 0;
+ memset (&mbs, 0, sizeof (mbs));
+ while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0 && (MB_INVALIDCH(clen) == 0))
+ {
+ s += clen;
+ nc++;
+ }
+ return nc;
+ }
+ #endif
+
+
/* Handle the parameter brace expansion that requires us to return the
length of a parameter. */
***************
*** 4747,4758 ****
{
t = get_dollar_var_value (arg_index);
! number = STRLEN (t);
FREE (t);
}
#if defined (ARRAY_VARS)
! else if ((var = find_variable (name + 1)) && array_p (var))
{
t = array_reference (array_cell (var), 0);
! number = STRLEN (t);
}
#endif
--- 4767,4778 ----
{
t = get_dollar_var_value (arg_index);
! number = MB_STRLEN (t);
FREE (t);
}
#if defined (ARRAY_VARS)
! else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var))
{
t = array_reference (array_cell (var), 0);
! number = MB_STRLEN (t);
}
#endif
***************
*** 4767,4771 ****
dispose_words (list);
! number = STRLEN (t);
FREE (t);
}
--- 4787,4791 ----
dispose_words (list);
! number = MB_STRLEN (t);
FREE (t);
}
***************
*** 4872,4876 ****
case VT_VARIABLE:
case VT_ARRAYMEMBER:
! len = strlen (value);
break;
case VT_POSPARMS:
--- 4892,4896 ----
case VT_VARIABLE:
case VT_ARRAYMEMBER:
! len = MB_STRLEN (value);
break;
case VT_POSPARMS:
***************
*** 4892,4896 ****
*e1p += len;
! if (*e1p >= len || *e1p < 0)
return (-1);
--- 4912,4916 ----
*e1p += len;
! if (*e1p > len || *e1p < 0)
return (-1);
***************
*** 4983,4987 ****
return -1;
}
! else if ((v = find_variable (varname)) && array_p (v))
{
vtype = VT_ARRAYMEMBER;
--- 5003,5007 ----
return -1;
}
! else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v))
{
vtype = VT_ARRAYMEMBER;
-4
View File
@@ -4911,11 +4911,7 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
if (*e1p < 0) /* negative offsets count from end */
*e1p += len;
#if 0
if (*e1p >= len || *e1p < 0)
#else
if (*e1p > len || *e1p < 0)
#endif
return (-1);
#if defined (ARRAY_VARS)
+1 -1
View File
@@ -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
+179
View File
@@ -0,0 +1,179 @@
./array.tests: line 15: syntax error near unexpected token `&'
./array.tests: line 15: `test=(first & second)'
1
abcde
abcde
abcde bdef
abcde bdef
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
declare -a a='([0]="abcde" [1]="" [2]="bdef")'
declare -a b='()'
declare -ar c='()'
abcde bdef
abcde bdef
abcde
abcde
abcde
bdef
hello world
11
3
bdef hello world test expression
./array.tests: line 74: readonly: `a[5]': not a valid identifier
declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
declare -ar c='()'
declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
declare -ar c='()'
readonly -a a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
readonly -a c='()'
a test
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
declare -a b='([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")'
declare -ar c='()'
declare -a d='([1]="" [2]="bdef" [5]="hello world" [6]="test" [9]="ninth element")'
declare -a e='([0]="test")'
declare -a f='([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")'
./array.tests: line 98: a: readonly variable
./array.tests: line 100: b[]: bad array subscript
./array.tests: line 101: b[*]: bad array subscript
./array.tests: line 102: ${b[ ]}: bad substitution
./array.tests: line 104: c[-2]: bad array subscript
./array.tests: line 105: c: bad array subscript
./array.tests: line 107: d[7]: cannot assign list to array member
./array.tests: line 109: []=abcde: bad array subscript
./array.tests: line 109: [*]=last: cannot assign to non-numeric index
./array.tests: line 109: [-65]=negative: bad array subscript
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
declare -a b='([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")'
declare -ar c='()'
declare -a d='([1]="test test")'
declare -a f='([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")'
./array.tests: line 117: unset: ps1: not an array variable
./array.tests: line 121: declare: c: cannot destroy array variables in this way
this of
this is a test of read using arrays
this test
this is a test of arrays
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
declare -a b='([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")'
declare -ar c='()'
declare -a d='([1]="test test")'
declare -a f='([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")'
declare -a rv='([0]="this" [1]="is" [2]="a" [3]="test" [4]="of" [5]="read" [6]="using" [7]="arrays")'
abde
abde
bbb
efgh
wxyz
wxyz
./array.tests
a
b c
d
e f g
h
./array.tests
a
b c
d
e f g
h
/bin /usr/bin /usr/ucb /usr/local/bin . /sbin /usr/sbin
bin bin ucb bin . sbin sbin
bin
/ / / / / /
/
argv[1] = <bin>
argv[1] = </>
argv[1] = <sbin>
argv[1] = </>
\bin \usr/bin \usr/ucb \usr/local/bin . \sbin \usr/sbin
\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
4 -- 4
7 -- 7
55
49
6 -- 6
42 14 44
grep [ 123 ] *
6 7 9
6 7 9 5
length = 3
value = new1 new2 new3
./array.tests: line 237: narray: unbound variable
a b c d e f g
for case if then else
<> < > !
12 14 16 18 20
4414758999202
aaa bbb
./array.tests: line 277: syntax error near unexpected token `<>'
./array.tests: line 277: `metas=( <> < > ! )'
./array.tests: line 278: syntax error near unexpected token `<>'
./array.tests: line 278: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
abc 3
case 4
abc case if then else 5
abc case if then else 5
0
case 4
case if then else 5
case if then else 5
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0 1 4 10>
include null element -- expect one
one
include unset element -- expect three five
three five
start at unset element -- expect five seven
five seven
too many elements -- expect three five seven
three five seven
positive offset - expect five seven
five seven
negative offset to unset element - expect seven
seven
positive offset 2 - expect seven
seven
negative offset 2 - expect seven
seven
out-of-range offset
+334
View File
@@ -0,0 +1,334 @@
# this is needed so that the bad assignments (b[]=bcde, for example) do not
# cause fatal shell errors when in posix mode
set +o posix
set +a
# The calls to egrep -v are to filter out builtin array variables that are
# automatically set and possibly contain values that vary.
# first make sure we handle the basics
x=()
echo ${x[@]}
unset x
# this should be an error
test=(first & second)
echo $?
unset test
# make sure declare -a converts an existing variable to an array
unset a
a=abcde
declare -a a
echo ${a[0]}
unset a
a=abcde
a[2]=bdef
unset b
declare -a b[256]
unset c[2]
unset c[*]
a[1]=
_ENV=/bin/true
x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
declare -r c[100]
echo ${a[0]} ${a[4]}
echo ${a[@]}
echo ${a[*]}
# this should print out values, too
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
unset a[7]
echo ${a[*]}
unset a[4]
echo ${a[*]}
echo ${a}
echo "${a}"
echo $a
unset a[0]
echo ${a}
echo ${a[@]}
a[5]="hello world"
echo ${a[5]}
echo ${#a[5]}
echo ${#a[@]}
a[4+5/2]="test expression"
echo ${a[@]}
readonly a[5]
readonly a
# these two lines should output `declare' commands
readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
declare -ar | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
# this line should output `readonly' commands, even for arrays
set -o posix
readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
set +o posix
declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")'
d[9]="ninth element"
declare -a e[10]=test # this works in post-bash-2.05 versions
declare -a e[10]='(test)'
pass=/etc/passwd
declare -a f='("${d[@]}")'
b=([0]=this [1]=is [2]=a [3]=test [4]="$PS1" [5]=$pass)
echo ${b[@]:2:3}
declare -pa | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
a[3]="this is a test"
b[]=bcde
b[*]=aaa
echo ${b[ ]}
c[-2]=4
echo ${c[-4]}
d[7]=(abdedfegeee)
d=([]=abcde [1]="test test" [*]=last [-65]=negative )
unset d[12]
unset e[*]
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
ps1='hello'
unset ps1[2]
unset ${ps1[2]}
declare +a ps1
declare +a c
# the prompt should not print when using a here doc
read -p "array test: " -a rv <<!
this is a test of read using arrays
!
echo ${rv[0]} ${rv[4]}
echo ${rv[@]}
# the variable should be converted to an array when `read -a' is done
vv=1
read -a vv <<!
this is a test of arrays
!
echo ${vv[0]} ${vv[3]}
echo ${vv[@]}
unset vv
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
export rv
#set
x[4]=bbb
x=abde
echo $x
echo ${x[0]}
echo ${x[4]}
echo efgh | ( read x[1] ; echo ${x[1]} )
echo wxyz | ( declare -a x ; read x ; echo $x ; echo ${x[0]} )
# Make sure that arrays can be used to save the positional paramters verbatim
set -- a 'b c' d 'e f g' h
ARGV=( [0]=$0 "$@" )
for z in "${ARGV[@]}"
do
echo "$z"
done
echo "$0"
for z in "$@"
do
echo "$z"
done
# do various pattern removal and length tests
XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
xpath=( $( IFS=: ; echo $XPATH ) )
echo ${xpath[@]}
echo ${xpath[@]##*/}
echo ${xpath[0]##*/}
echo ${xpath[@]%%[!/]*}
echo ${xpath[0]%%[!/]*}
recho ${xpath##*/}
recho ${xpath%%[!/]*}
recho ${xpath[5]##*/}
recho ${xpath[5]%%[!/]*}
# let's try to make it a DOS-style path
zecho "${xpath[@]/\//\\}"
zecho "${xpath[@]//\//\\}"
zecho "${xpath[@]//[\/]/\\}"
# length of the first element of the array, since array without subscript
# is equivalent to referencing first element
echo ${#xpath} -- ${#xpath[0]}
# number of elements in the array
nelem=${#xpath[@]}
echo ${#xpath[@]} -- $nelem
# total length of all elements in the array, including space separators
xx="${xpath[*]}"
echo ${#xx}
# total length of all elements in the array
xx=$( IFS='' ; echo "${xpath[*]}" )
echo ${#xx}
unset xpath[nelem-1]
nelem=${#xpath[@]}
echo ${#xpath[@]} -- $nelem
# arrays and things that look like index assignments
array=(42 [1]=14 [2]=44)
array2=(grep [ 123 ] \*)
echo ${array[@]}
echo "${array2[@]}"
# arrays and implicit arithmetic evaluation
declare -i -a iarray
iarray=( 2+4 1+6 7+2 )
echo ${iarray[@]}
iarray[4]=4+1
echo ${iarray[@]}
# make sure assignment using the compound assignment syntax removes all
# of the old elements from the array value
barray=(old1 old2 old3 old4 old5)
barray=(new1 new2 new3)
echo "length = ${#barray[@]}"
echo "value = ${barray[*]}"
# make sure the array code behaves correctly with respect to unset variables
set -u
( echo ${#narray[4]} )
# some old bugs and ksh93 compatibility tests
set +u
cd /tmp
touch 1=bar
foo=([10]="bar")
echo ${foo[0]}
rm 1=bar
foo=(a b c d e f g)
echo ${foo[@]}
# quoted reserved words are ok
foo=(\for \case \if \then \else)
echo ${foo[@]}
# quoted metacharacters are ok
foo=( [1]='<>' [2]='<' [3]='>' [4]='!' )
echo ${foo[@]}
# numbers are just words when not in a redirection context
foo=( 12 14 16 18 20 )
echo ${foo[@]}
foo=( 4414758999202 )
echo ${foo[@]}
# this was a bug in all versions of bash 2.x up to and including bash-2.04
declare -a ddd=(aaa
bbb)
echo ${ddd[@]}
# errors until post-bash-2.05a; now reserved words are OK
foo=(a b c for case if then else)
foo=(for case if then else)
# errors
metas=( <> < > ! )
metas=( [1]=<> [2]=< [3]=> [4]=! )
# various expansions that didn't really work right until post-bash-2.04
foo='abc'
echo ${foo[0]} ${#foo[0]}
echo ${foo[1]} ${#foo[1]}
echo ${foo[@]} ${#foo[@]}
echo ${foo[*]} ${#foo[*]}
foo=''
echo ${foo[0]} ${#foo[0]}
echo ${foo[1]} ${#foo[1]}
echo ${foo[@]} ${#foo[@]}
echo ${foo[*]} ${#foo[*]}
# new expansions added after bash-2.05b
x[0]=zero
x[1]=one
x[4]=four
x[10]=ten
recho ${!x[@]}
recho "${!x[@]}"
recho ${!x[*]}
recho "${!x[*]}"
# sparse array tests for code fixed in bash-3.0
unset av
av[1]='one'
av[2]=''
av[3]=three
av[5]=five
av[7]=seven
echo include null element -- expect one
echo ${av[@]:1:2} # what happens when we include a null element?
echo include unset element -- expect three five
echo ${av[@]:3:2} # what happens when we include an unset element?
echo start at unset element -- expect five seven
echo ${av[@]:4:2} # what happens when we start at an unset element?
echo too many elements -- expect three five seven
echo ${av[@]:3:5} # how about too many elements?
echo positive offset - expect five seven
echo ${av[@]:5:2}
echo negative offset to unset element - expect seven
echo ${av[@]: -2:2}
echo positive offset 2 - expect seven
echo ${av[@]: 6:2}
echo negative offset 2 - expect seven
echo ${av[@]: -1:2}
echo out-of-range offset
echo ${av[@]:12}
+4
View File
@@ -0,0 +1,4 @@
echo "warning: all of these tests will fail if arrays have not" >&2
echo "warning: been compiled into the shell" >&2
${THIS_SH} ./array.tests > /tmp/xx 2>&1
diff /tmp/xx array.right && rm -f /tmp/xx
+68
View File
@@ -0,0 +1,68 @@
*** ../bash-3.0/variables.c Sun Jul 4 13:57:26 2004
--- variables.c Wed Aug 4 15:28:04 2004
***************
*** 1420,1428 ****
# if defined (DEBUGGER)
! v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, (att_invisible|att_noassign));
! v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, (att_invisible|att_noassign));
# endif /* DEBUGGER */
! v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, (att_invisible|att_noassign));
! v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, (att_invisible|att_noassign));
#endif
--- 1420,1428 ----
# if defined (DEBUGGER)
! v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign);
! v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign);
# endif /* DEBUGGER */
! v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign);
! v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign);
#endif
***************
*** 1600,1604 ****
old_var = find_variable (name);
if (old_var && local_p (old_var) && old_var->context == variable_context)
! return (old_var);
was_tmpvar = old_var && tempvar_p (old_var);
--- 1600,1607 ----
old_var = find_variable (name);
if (old_var && local_p (old_var) && old_var->context == variable_context)
! {
! VUNSETATTR (old_var, att_invisible);
! return (old_var);
! }
was_tmpvar = old_var && tempvar_p (old_var);
***************
*** 2303,2306 ****
--- 2306,2315 ----
if (old_var && local_p (old_var) && variable_context == old_var->context)
{
+ #if defined (ARRAY_VARS)
+ if (array_p (old_var))
+ array_dispose (array_cell (old_var));
+ else
+ #endif
+ FREE (value_cell (old_var));
/* Reset the attributes. Preserve the export attribute if the variable
came from a temporary environment. Make sure it stays local, and
***************
*** 2309,2313 ****
VSETATTR (old_var, att_local);
VSETATTR (old_var, att_invisible);
- FREE (value_cell (old_var));
var_setvalue (old_var, (char *)NULL);
INVALIDATE_EXPORTSTR (old_var);
--- 2318,2321 ----
***************
*** 3647,3650 ****
--- 3655,3659 ----
{ "LC_MESSAGES", sv_locale },
{ "LC_NUMERIC", sv_locale },
+ { "LC_TIME", sv_locale },
{ "MAIL", sv_mail },
+53
View File
@@ -0,0 +1,53 @@
*** ../bash-3.0/bashline.c Mon Jul 5 23:22:12 2004
--- bashline.c Thu Sep 2 16:00:12 2004
***************
*** 2514,2518 ****
static int ind;
int glen;
! char *ret;
if (state == 0)
--- 2545,2549 ----
static int ind;
int glen;
! char *ret, *ttext;
if (state == 0)
***************
*** 2524,2538 ****
FREE (globtext);
if (rl_explicit_arg)
{
! globorig = savestring (text);
! glen = strlen (text);
globtext = (char *)xmalloc (glen + 2);
! strcpy (globtext, text);
globtext[glen] = '*';
globtext[glen+1] = '\0';
}
else
! globtext = globorig = savestring (text);
matches = shell_glob_filename (globtext);
--- 2555,2574 ----
FREE (globtext);
+ ttext = bash_tilde_expand (text, 0);
+
if (rl_explicit_arg)
{
! globorig = savestring (ttext);
! glen = strlen (ttext);
globtext = (char *)xmalloc (glen + 2);
! strcpy (globtext, ttext);
globtext[glen] = '*';
globtext[glen+1] = '\0';
}
else
! globtext = globorig = savestring (ttext);
!
! if (ttext != text)
! free (ttext);
matches = shell_glob_filename (globtext);
+79
View File
@@ -0,0 +1,79 @@
*** ../bash-3.0/lib/readline/vi_mode.c Tue Jul 13 14:08:27 2004
--- lib/readline/vi_mode.c Tue Aug 17 00:12:09 2004
***************
*** 273,280 ****
--- 273,282 ----
{
case '?':
+ _rl_free_saved_history_line ();
rl_noninc_forward_search (count, key);
break;
case '/':
+ _rl_free_saved_history_line ();
rl_noninc_reverse_search (count, key);
break;
***************
*** 691,695 ****
wchar_t wc;
char mb[MB_LEN_MAX+1];
! int mblen;
mbstate_t ps;
--- 693,697 ----
wchar_t wc;
char mb[MB_LEN_MAX+1];
! int mblen, p;
mbstate_t ps;
***************
*** 714,722 ****
if (wc)
{
mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0)
mb[mblen] = '\0';
rl_begin_undo_group ();
! rl_delete (1, 0);
rl_insert_text (mb);
rl_end_undo_group ();
--- 716,727 ----
if (wc)
{
+ p = rl_point;
mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0)
mb[mblen] = '\0';
rl_begin_undo_group ();
! rl_vi_delete (1, 0);
! if (rl_point < p) /* Did we retreat at EOL? */
! rl_point++; /* XXX - should we advance more than 1 for mbchar? */
rl_insert_text (mb);
rl_end_undo_group ();
***************
*** 1311,1320 ****
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
! while (_rl_insert_char (1, c))
! {
! RL_SETSTATE (RL_STATE_MOREINPUT);
! c = rl_read_key ();
! RL_UNSETSTATE (RL_STATE_MOREINPUT);
! }
else
#endif
--- 1316,1329 ----
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
! {
! if (rl_point < p) /* Did we retreat at EOL? */
! rl_point++;
! while (_rl_insert_char (1, c))
! {
! RL_SETSTATE (RL_STATE_MOREINPUT);
! c = rl_read_key ();
! RL_UNSETSTATE (RL_STATE_MOREINPUT);
! }
! }
else
#endif