mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-29 08:29:54 +02:00
commit bash-20040902 snapshot
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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))
|
||||
@@ -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
@@ -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);
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+21
-8
@@ -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, "<B>$@</B>" is equivalent to
|
||||
"<B>$1</B>" "<B>$2</B>" ...
|
||||
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, "<B>$@</B>" 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>&</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
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+38
-12
@@ -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> </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> </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>`&'</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
File diff suppressed because it is too large
Load Diff
+35
-34
@@ -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
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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_ */
|
||||
|
||||
@@ -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);
|
||||
@@ -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 */
|
||||
@@ -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
@@ -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;
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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}
|
||||
@@ -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
|
||||
@@ -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 },
|
||||
@@ -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);
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user