commit bash-20051222 snapshot

This commit is contained in:
Chet Ramey
2011-12-03 22:43:25 -05:00
parent 5e4a95c794
commit dc8fbaf9a1
92 changed files with 48902 additions and 1431 deletions
+66 -35
View File
@@ -1,10 +1,10 @@
This document details the incompatibilites between this version of bash,
bash-3.1, and a previous widely-available version, bash-1.14 (which
is still the `standard' version for a few Linux distributions). These
were discovered by users of bash-2.x and 3.x, so this list is not
comprehensive. Some of these incompatibilities occur between the current
version and versions 2.0 and above. (The differences between bash-1.14
and bash-2.0 were significant.)
This document details the incompatibilities between this version of bash,
bash-3.1, and the previous widely-available versions, bash-1.14 (which is
still the `standard' version for a few Linux distributions) and bash-2.x.
These were discovered by users of bash-2.x and 3.x, so this list is not
comprehensive. Some of these incompatibilities occur between the current
version and versions 2.0 and above. (The differences between bash-1.14 and
bash-2.0 were significant.)
1. Bash uses a new quoting syntax, $"...", to do locale-specific
string translation. Users who have relied on the (undocumented)
@@ -184,42 +184,73 @@ and bash-2.0 were significant.)
with `z' and still allow individual users to change the collation order.
Users may put the above command into their own profiles as well, of course.
14. Bash versions up to 1.14.7 included an undocumented `-l' operator to
the `test/[' builtin. It was a unary operator that expanded to the
length of its string argument. This let you do things like
14. Bash versions up to 1.14.7 included an undocumented `-l' operator to
the `test/[' builtin. It was a unary operator that expanded to the
length of its string argument. This let you do things like
test -l $variable -lt 20
for example.
for example.
This was included for backwards compatibility with old versions of the
Bourne shell, which did not provide an easy way to obtain the length of
the value of a shell variable.
This was included for backwards compatibility with old versions of the
Bourne shell, which did not provide an easy way to obtain the length of
the value of a shell variable.
This operator is not part of the POSIX standard, because one can (and
should) use ${#variable} to get the length of a variable's value.
Bash-2.x does not support it.
This operator is not part of the POSIX standard, because one can (and
should) use ${#variable} to get the length of a variable's value.
Bash-2.x does not support it.
15. Bash no longer auto-exports the HOME, PATH, SHELL, TERM, HOSTNAME,
HOSTTYPE, MACHTYPE, or OSTYPE variables.
15. Bash no longer auto-exports the HOME, PATH, SHELL, TERM, HOSTNAME,
HOSTTYPE, MACHTYPE, or OSTYPE variables.
16. Bash no longer initializes the FUNCNAME, GROUPS, or DIRSTACK variables
to have special behavior if they appear in the initial environment.
16. Bash no longer initializes the FUNCNAME, GROUPS, or DIRSTACK variables
to have special behavior if they appear in the initial environment.
17. Bash no longer removes the export attribute from the SSH_CLIENT or
SSH2_CLIENT variables, and no longer attempts to discover whether or
not it has been invoked by sshd in order to run the startup files.
17. Bash no longer removes the export attribute from the SSH_CLIENT or
SSH2_CLIENT variables, and no longer attempts to discover whether or
not it has been invoked by sshd in order to run the startup files.
18. Bash no longer requires that the body of a function be a group command;
any compound command is accepted.
18. Bash no longer requires that the body of a function be a group command;
any compound command is accepted.
19. As of bash-3.0, the pattern substitution operators no longer perform
quote removal on the pattern before attempting the match. This is the
way the pattern removal functions behave, and is more consistent.
19. As of bash-3.0, the pattern substitution operators no longer perform
quote removal on the pattern before attempting the match. This is the
way the pattern removal functions behave, and is more consistent.
20. After bash-3.0 was released, I reimplemented tilde expansion, incorporating
it into the mainline word expansion code. This fixes the bug that caused
the results of tilde expansion to be re-expanded. There is one
incompatibility: a ${paramOPword} expansion within double quotes will not
perform tilde expansion on WORD. This is consistent with the other
expansions, and what POSIX specifies.
20. After bash-3.0 was released, I reimplemented tilde expansion, incorporating
it into the mainline word expansion code. This fixes the bug that caused
the results of tilde expansion to be re-expanded. There is one
incompatibility: a ${paramOPword} expansion within double quotes will not
perform tilde expansion on WORD. This is consistent with the other
expansions, and what POSIX specifies.
21. A number of variables have the integer attribute by default, so the +=
assignment operator returns expected results: RANDOM, LINENO, MAILCHECK,
HISTCMD, OPTIND.
22. Bash-3.x is much stricter about $LINENO correctly reflecting the line
number in a script; assignments to LINENO have little effect.
23. By default, readline binds the terminal special characters to their
readline equivalents. As of bash-3.1/readline-5.1, this is optional and
controlled by the bind-tty-special-chars readline variable.
24. The \W prompt string expansion abbreviates $HOME as `~'. The previous
behavior is available with ${PWD##/*/}.
25. The arithmetic exponentiation operator is right-associative as of bash-3.1.
26. The rules concerning valid alias names are stricter, as per POSIX.2.
27. The Readline key binding functions now obey the convert-meta setting active
when the binding takes place, as the dispatch code does when characters
are read and processed.
28. The historical behavior of `trap' reverting signal disposition to the
original handling in the absence of a valid first argument is implemented
only if the first argument is a valid signal number.
29. In versions of bash after 3.1, the ${parameter//pattern/replacement}
expansion does not interpret `%' or `#' specially. Those anchors don't
have any real meaning when replacing every match.
+225
View File
@@ -0,0 +1,225 @@
This document details the incompatibilities between this version of bash,
bash-3.1, and a previous widely-available version, bash-1.14 (which
is still the `standard' version for a few Linux distributions). These
were discovered by users of bash-2.x and 3.x, so this list is not
comprehensive. Some of these incompatibilities occur between the current
version and versions 2.0 and above. (The differences between bash-1.14
and bash-2.0 were significant.)
1. Bash uses a new quoting syntax, $"...", to do locale-specific
string translation. Users who have relied on the (undocumented)
behavior of bash-1.14 will have to change their scripts. For
instance, if you are doing something like this to get the value of
a variable whose name is the value of a second variable:
eval var2=$"$var1"
you will have to change to a different syntax.
This capability is directly supported by bash-2.0:
var2=${!var1}
This alternate syntax will work portably between bash-1.14 and bash-2.0:
eval var2=\$${var1}
2. One of the bugs fixed in the YACC grammar tightens up the rules
concerning group commands ( {...} ). The `list' that composes the
body of the group command must be terminated by a newline or
semicolon. That's because the braces are reserved words, and are
recognized as such only when a reserved word is legal. This means
that while bash-1.14 accepted shell function definitions like this:
foo() { : }
bash-2.0 requires this:
foo() { :; }
This is also an issue for commands like this:
mkdir dir || { echo 'could not mkdir' ; exit 1; }
The syntax required by bash-2.0 is also accepted by bash-1.14.
3. The options to `bind' have changed to make them more consistent with
the rest of the bash builtins. If you are using `bind -d' to list
the readline key bindings in a form that can be re-read, use `bind -p'
instead. If you were using `bind -v' to list the key bindings, use
`bind -P' instead.
4. The `long' invocation options must now be prefixed by `--' instead
of `-'. (The old form is still accepted, for the time being.)
5. There was a bug in the version of readline distributed with bash-1.14
that caused it to write badly-formatted key bindings when using
`bind -d'. The only key sequences that were affected are C-\ (which
should appear as \C-\\ in a key binding) and C-" (which should appear
as \C-\"). If these key sequences appear in your inputrc, as, for
example,
"\C-\": self-insert
they will need to be changed to something like the following:
"\C-\\": self-insert
6. A number of people complained about having to use ESC to terminate an
incremental search, and asked for an alternate mechanism. Bash-2.03
uses the value of the settable readline variable `isearch-terminators'
to decide which characters should terminate an incremental search. If
that variable has not been set, ESC and Control-J will terminate a
search.
7. Some variables have been removed: MAIL_WARNING, notify, history_control,
command_oriented_history, glob_dot_filenames, allow_null_glob_expansion,
nolinks, hostname_completion_file, noclobber, no_exit_on_failed_exec, and
cdable_vars. Most of them are now implemented with the new `shopt'
builtin; others were already implemented by `set'. Here is a list of
correspondences:
MAIL_WARNING shopt mailwarn
notify set -o notify
history_control HISTCONTROL
command_oriented_history shopt cmdhist
glob_dot_filenames shopt dotglob
allow_null_glob_expansion shopt nullglob
nolinks set -o physical
hostname_completion_file HOSTFILE
noclobber set -o noclobber
no_exit_on_failed_exec shopt execfail
cdable_vars shopt cdable_vars
8. `ulimit' now sets both hard and soft limits and reports the soft limit
by default (when neither -H nor -S is specified). This is compatible
with versions of sh and ksh that implement `ulimit'. The bash-1.14
behavior of, for example,
ulimit -c 0
can be obtained with
ulimit -S -c 0
It may be useful to define an alias:
alias ulimit="ulimit -S"
9. Bash-2.01 uses a new quoting syntax, $'...' to do ANSI-C string
translation. Backslash-escaped characters in ... are expanded and
replaced as specified by the ANSI C standard.
10. The sourcing of startup files has changed somewhat. This is explained
more completely in the INVOCATION section of the manual page.
A non-interactive shell not named `sh' and not in posix mode reads
and executes commands from the file named by $BASH_ENV. A
non-interactive shell started by `su' and not in posix mode will read
startup files. No other non-interactive shells read any startup files.
An interactive shell started in posix mode reads and executes commands
from the file named by $ENV.
11. The <> redirection operator was changed to conform to the POSIX.2 spec.
In the absence of any file descriptor specification preceding the `<>',
file descriptor 0 is used. In bash-1.14, this was the behavior only
when in POSIX mode. The bash-1.14 behavior may be obtained with
<>filename 1>&0
12. The `alias' builtin now checks for invalid options and takes a `-p'
option to display output in POSIX mode. If you have old aliases beginning
with `-' or `+', you will have to add the `--' to the alias command
that declares them:
alias -x='chmod a-x' --> alias -- -x='chmod a-x'
13. The behavior of range specificiers within bracket matching expressions
in the pattern matcher (e.g., [A-Z]) depends on the current locale,
specifically the value of the LC_COLLATE environment variable. Setting
this variable to C or POSIX will result in the traditional ASCII behavior
for range comparisons. If the locale is set to something else, e.g.,
en_US (specified by the LANG or LC_ALL variables), collation order is
locale-dependent. For example, the en_US locale sorts the upper and
lower case letters like this:
AaBb...Zz
so a range specification like [A-Z] will match every letter except `z'.
Other locales collate like
aAbBcC...zZ
which means that [A-Z] matches every letter except `a'.
The portable way to specify upper case letters is [:upper:] instead of
A-Z; lower case may be specified as [:lower:] instead of a-z.
Look at the manual pages for setlocale(3), strcoll(3), and, if it is
present, locale(1).
You can find your current locale information by running locale(1):
caleb.ins.cwru.edu(2)$ locale
LANG=en_US
LC_CTYPE="en_US"
LC_NUMERIC="en_US"
LC_TIME="en_US"
LC_COLLATE="en_US"
LC_MONETARY="en_US"
LC_MESSAGES="en_US"
LC_ALL=en_US
My advice is to put
export LC_COLLATE=C
into /etc/profile and inspect any shell scripts run from cron for
constructs like [A-Z]. This will prevent things like
rm [A-Z]*
from removing every file in the current directory except those beginning
with `z' and still allow individual users to change the collation order.
Users may put the above command into their own profiles as well, of course.
14. Bash versions up to 1.14.7 included an undocumented `-l' operator to
the `test/[' builtin. It was a unary operator that expanded to the
length of its string argument. This let you do things like
test -l $variable -lt 20
for example.
This was included for backwards compatibility with old versions of the
Bourne shell, which did not provide an easy way to obtain the length of
the value of a shell variable.
This operator is not part of the POSIX standard, because one can (and
should) use ${#variable} to get the length of a variable's value.
Bash-2.x does not support it.
15. Bash no longer auto-exports the HOME, PATH, SHELL, TERM, HOSTNAME,
HOSTTYPE, MACHTYPE, or OSTYPE variables.
16. Bash no longer initializes the FUNCNAME, GROUPS, or DIRSTACK variables
to have special behavior if they appear in the initial environment.
17. Bash no longer removes the export attribute from the SSH_CLIENT or
SSH2_CLIENT variables, and no longer attempts to discover whether or
not it has been invoked by sshd in order to run the startup files.
18. Bash no longer requires that the body of a function be a group command;
any compound command is accepted.
19. As of bash-3.0, the pattern substitution operators no longer perform
quote removal on the pattern before attempting the match. This is the
way the pattern removal functions behave, and is more consistent.
20. After bash-3.0 was released, I reimplemented tilde expansion, incorporating
it into the mainline word expansion code. This fixes the bug that caused
the results of tilde expansion to be re-expanded. There is one
incompatibility: a ${paramOPword} expansion within double quotes will not
perform tilde expansion on WORD. This is consistent with the other
expansions, and what POSIX specifies.
+158
View File
@@ -12552,3 +12552,161 @@ parse.y
- use CTLESC instead of literal '\001' when decode_prompt_string
prefixes RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE
12/20
-----
lib/readline/display.c
- don't treat RL_PROMPT_START_IGNORE specially inside a sequence of
ignored characters
- keep track of the start of the current sequence of ignored
characters; make sure that an empty sequence of such characters
really is an empty sequence, not one that happens to end with '\001'
(RL_PROMPT_START_IGNORE)
12/21
-----
subst.c
- change expand_word_internal to process rest of `tilde-word' as a
regular part of the word if tilde expansion leaves the tilde-word
unchanged. This means that ~$USER expands to ~chet, which seems
more intuitive, and is effectively what bash-3.0 did
12/23
-----
subst.c
- when making a local array variable in do_compound_assignment, make
sure that we don't use a variable of the same name from a previous
context
doc/bash.1
- documented expansions for word and patterns in case statement
builtins/ulimit.def,doc/{bashref.texi,bash.1}
- added new -e and -r (nice and rtprio) options to ulimit; documented
them
12/26
-----
variables.c
- use `hmax' instead of `num' in sv_histsize to avoid integer overflow
problems with intmax_t
builtins/read.def
- add unwind-protect to restore rl_attempted_completion_function in
case of a timeout
{bashline,variables}.c
- move initialization of HISTSIZE from initialization path to
load_history, so it can be overridden by a value assigned in a
startup file
lib/readline/misc.c
- add a missing `return r' so that rl_digit_loop returns a meaningful
value
lib/readline/{bind,callback,display,isearch,rltty,search,text,vi_mode}.c
- minor cleanups to satisfy compiler warnings, mostly removing unused
variables
12/27
-----
support/Makefile.in
- add LIBS_FOR_BUILD support; defaults to ${LIBS}
Makefile.in
- add LIBS_FOR_BUILD with no default value; use when linking programs
using CC_FOR_BUILD (e.g., bashversion)
12/28
-----
lib/readline/bind.c
- fix rl_translate_keyseq bad translation of \M-\C-x sequences
execute_cmd.c
- in execute_arith_command, if the expression expands to more than one
word, make sure we join the words into a single string and pass the
entire thing to evalexp()
expr.c
- new functions: _is_arithop(c), returns true if C is a valid single-
character arithmetic operator; _is_multiop(c), returns true if C is
a token corresponding to a valid multi-character arithmetic operator
- if we encounter a character that isn't a valid arithmetic
operator, throw an error. Try to be intelligent about what type of
error message to print
subst.c
- new function, expand_arith_string, calls expand_string_if_necessary;
used where an arithmetic expression needs to be expanded
subst.h
- new extern declaration for expand_arith_string
arrayfunc.c
- in array_expand_index, call expand_arith_string to expand the
subscript in a fashion consistent with other arithmetic expressions
subst.c
- fix parameter_brace_patsub so that we don't try to anchor the pattern
at the beginning or end of the string if we're doing global
replacement -- that combination doesn't doesn't make sense, and
the changed behavior is compatible with ksh93
doc/{bash.1,bashref.texi}
- changed description of pattern substitution to match the new
semantics
tests/new-exp.tests
- change tests to remove all ${pat//#rep} and ${pat//%rep}
expansions, since they don't mean the same thing anymore
12/29
-----
support/signames.c
- new file, initialize_signames() function from old mksignames.c. This
file builds the signal_names array
support/mksignames.c
- strip out initialize_signames(), move to signames.c. This file only
writes signames.h
- set up to only write a stub signames.h if CROSS_COMPILING is defined,
with extern declaration for initialize_signames
- if not cross compiling, #define initialize_signames to nothing
Makefile.in
- mksignames is now linked from mksignames.o and buildsignames.o
- add rules to build signames.o, assuming we're building it as part
of the shell (cross-compiling)
trap.c
- call initialize_signames from initialize_traps
configure.in
- set SIGNAMES_O to nothing (normal) or signames.o (cross-compiling),
substitute into Makefile
- don't set SIGNAMES_H if cross-compiling any more
12/30
-----
command.h
- new word flag: W_NOPROCSUB, inhibits process substitution on a word
subst.c
- change expand_word_internal to suppress process substitution if the
word has the W_NOPROCSUB flag
shell.c
- --wordexp turns on W_NOPROCSUB in addition to W_NOCOMSUB
subst.c
- change string_list_dollar_at and string_list_dollar_star so that
MB_CUR_MAX is used to size an array only when using gcc, since gcc
can handle non-constant array sizes using a mechanism like alloca.
Other compilers, e.g. Sun's compiler, do not implement that
extension
12/31
-----
builtins/mkbuiltins.c
- when cross-compiling, don't include <config.h>, since it's for the
target rather than the host system. Instead, choose a reasonable
set of default #defines based on a minimal POSIX system
+158
View File
@@ -12545,3 +12545,161 @@ config.h.in
config-bot.h
- add HAVE_WCTYPE to the set of checks for HANDLE_MULTIBYTE. This
should catch the deficient NetBSD multibyte support
12/16
-----
parse.y
- use CTLESC instead of literal '\001' when decode_prompt_string
prefixes RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE
12/20
-----
lib/readline/display.c
- don't treat RL_PROMPT_START_IGNORE specially inside a sequence of
ignored characters
- keep track of the start of the current sequence of ignored
characters; make sure that an empty sequence of such characters
really is an empty sequence, not one that happens to end with '\001'
(RL_PROMPT_START_IGNORE)
12/21
-----
subst.c
- change expand_word_internal to process rest of `tilde-word' as a
regular part of the word if tilde expansion leaves the tilde-word
unchanged. This means that ~$USER expands to ~chet, which seems
more intuitive, and is effectively what bash-3.0 did
12/23
-----
subst.c
- when making a local array variable in do_compound_assignment, make
sure that we don't use a variable of the same name from a previous
context
doc/bash.1
- documented expansions for word and patterns in case statement
builtins/ulimit.def,doc/{bashref.texi,bash.1}
- added new -e and -r (nice and rtprio) options to ulimit; documented
them
12/26
-----
variables.c
- use `hmax' instead of `num' in sv_histsize to avoid integer overflow
problems with intmax_t
builtins/read.def
- add unwind-protect to restore rl_attempted_completion_function in
case of a timeout
{bashline,variables}.c
- move initialization of HISTSIZE from initialization path to
load_history, so it can be overridden by a value assigned in a
startup file
lib/readline/misc.c
- add a missing `return r' so that rl_digit_loop returns a meaningful
value
lib/readline/{bind,callback,display,isearch,rltty,search,text,vi_mode}.c
- minor cleanups to satisfy compiler warnings, mostly removing unused
variables
12/27
-----
support/Makefile.in
- add LIBS_FOR_BUILD support; defaults to ${LIBS}
Makefile.in
- add LIBS_FOR_BUILD with no default value; use when linking programs
using CC_FOR_BUILD (e.g., bashversion)
12/28
-----
lib/readline/bind.c
- fix rl_translate_keyseq bad translation of \M-\C-x sequences
execute_cmd.c
- in execute_arith_command, if the expression expands to more than one
word, make sure we join the words into a single string and pass the
entire thing to evalexp()
expr.c
- new functions: _is_arithop(c), returns true if C is a valid single-
character arithmetic operator; _is_multiop(c), returns true if C is
a token corresponding to a valid multi-character arithmetic operator
- if we encounter a character that isn't a valid arithmetic
operator, throw an error. Try to be intelligent about what type of
error message to print
subst.c
- new function, expand_arith_string, calls expand_string_if_necessary;
used where an arithmetic expression needs to be expanded
subst.h
- new extern declaration for expand_arith_string
arrayfunc.c
- in array_expand_index, call expand_arith_string to expand the
subscript in a fashion consistent with other arithmetic expressions
subst.c
- fix parameter_brace_patsub so that we don't try to anchor the pattern
at the beginning or end of the string if we're doing global
replacement -- that combination doesn't doesn't make sense, and
the changed behavior is compatible with ksh93
doc/{bash.1,bashref.texi}
- changed description of pattern substitution to match the new
semantics
tests/new-exp.tests
- change tests to remove all ${pat//#rep} and ${pat//%rep}
expansions, since they don't mean the same thing anymore
12/29
-----
support/signames.c
- new file, initialize_signames() function from old mksignames.c. This
file builds the signal_names array
support/mksignames.c
- strip out initialize_signames(), move to signames.c. This file only
writes signames.h
- set up to only write a stub signames.h if CROSS_COMPILING is defined,
with extern declaration for initialize_signames
- if not cross compiling, #define initialize_signames to nothing
Makefile.in
- mksignames is now linked from mksignames.o and buildsignames.o
- add rules to build signames.o, assuming we're building it as part
of the shell (cross-compiling)
trap.c
- call initialize_signames from initialize_traps
configure.in
- set SIGNAMES_O to nothing (normal) or signames.o (cross-compiling),
substitute into Makefile
- don't set SIGNAMES_H if cross-compiling any more
12/30
-----
command.h
- new word flag: W_NOPROCSUB, inhibits process substitution on a word
subst.c
- change expand_word_internal to suppress process substitution if the
word has the W_NOPROCSUB flag
shell.c
- --wordexp turns on W_NOPROCSUB in addition to W_NOCOMSUB
subst.c
- change string_list_dollar_at and string_list_dollar_star so that
MB_CUR_MAX is used to size an array only when using gcc, since gcc
can handle non-constant array sizes using a mechanism like alloca.
Other compilers, e.g. Sun's compiler, do not implement that
extension
+1 -2
View File
@@ -203,9 +203,7 @@ builtins/bashgetopt.c f
builtins/common.h f
builtins/bashgetopt.h f
cross-build/cygwin32.cache f
cross-build/win32sig.h f
cross-build/x86-beos.cache f
cross-build/beos-sig.h f
cross-build/opennt.cache f
include/ansi_stdlib.h f
include/chartypes.h f
@@ -514,6 +512,7 @@ support/mkdirs f 755
support/mkinstalldirs f 755
support/mkversion.sh f 755
support/mksignames.c f
support/signames.c f
support/bashbug.sh f
support/man2html.c f
support/recho.c f
+984
View File
@@ -0,0 +1,984 @@
#
# Master distribution manifest for bash
#
#
# Filename type
#
CWRU d
CWRU/misc d
builtins d
cross-build d
doc d
examples d
examples/bashdb d
examples/obashdb d
examples/complete d
examples/functions d
examples/scripts d
examples/scripts.v2 d
examples/scripts.noah d
examples/startup-files d
examples/startup-files/apple d
examples/misc d
examples/loadables d
examples/loadables/perl d
include d
lib d
lib/glob d
lib/glob/doc d
lib/intl d
lib/malloc d
lib/readline d
lib/readline/doc d
lib/readline/examples d
lib/sh d
lib/termcap d
lib/termcap/grot d
lib/tilde d
po d
support d
tests d
tests/misc d
ABOUT-NLS f
CHANGES f
COMPAT f
COPYING f
INSTALL f
MANIFEST f
NEWS f
NOTES f
POSIX f
README f
RBASH f
AUTHORS f
Y2K f
configure.in f
configure f
Makefile.in f
config-top.h f
config-bot.h f
config.h.in f
aclocal.m4 f
array.c f
arrayfunc.c f
eval.c f
print_cmd.c f
general.c f
list.c f
locale.c f
stringlib.c f
variables.c f
make_cmd.c f
copy_cmd.c f
unwind_prot.c f
dispose_cmd.c f
bashhist.c f
hashcmd.c f
hashlib.c f
parse.y f
pathexp.c f
subst.c f
shell.c f
trap.c f
sig.c f
siglist.c f
version.c f
flags.c f
jobs.c f
input.c f
mailcheck.c f
test.c f
expr.c f
alias.c f
execute_cmd.c f
findcmd.c f
redir.c f
bashline.c f
braces.c f
bracecomp.c f
nojobs.c f
error.c f
xmalloc.c f
pcomplete.c f
pcomplib.c f
mksyntax.c f
alias.h f
builtins.h f
bashhist.h f
bashline.h f
conftypes.h f
patchlevel.h f
variables.h f
array.h f
arrayfunc.h f
jobs.h f
findcmd.h f
hashlib.h f
quit.h f
flags.h f
shell.h f
syntax.h f
pathexp.h f
parser.h f
pcomplete.h f
sig.h f
test.h f
trap.h f
general.h f
unwind_prot.h f
input.h f
error.h f
command.h f
externs.h f
siglist.h f
subst.h f
dispose_cmd.h f
hashcmd.h f
bashansi.h f
bashjmp.h f
bashintl.h f
make_cmd.h f
execute_cmd.h f
redir.h f
bashtypes.h f
mailcheck.h f
xmalloc.h f
y.tab.c f
y.tab.h f
parser-built f
pathnames.h.in f
builtins/Makefile.in f
builtins/alias.def f
builtins/bind.def f
builtins/break.def f
builtins/builtin.def f
builtins/caller.def f
builtins/cd.def f
builtins/colon.def f
builtins/command.def f
builtins/complete.def f
builtins/common.c f
builtins/declare.def f
builtins/echo.def f
builtins/enable.def f
builtins/eval.def f
builtins/evalfile.c f
builtins/evalstring.c f
builtins/exec.def f
builtins/exit.def f
builtins/fc.def f
builtins/fg_bg.def f
builtins/getopt.c f
builtins/getopt.h f
builtins/getopts.def f
builtins/hash.def f
builtins/help.def f
builtins/let.def f
builtins/history.def f
builtins/jobs.def f
builtins/kill.def f
builtins/mkbuiltins.c f
builtins/printf.def f
builtins/pushd.def f
builtins/read.def f
builtins/reserved.def f
builtins/return.def f
builtins/set.def f
builtins/setattr.def f
builtins/shift.def f
builtins/shopt.def f
builtins/source.def f
builtins/suspend.def f
builtins/test.def f
builtins/times.def f
builtins/trap.def f
builtins/type.def f
builtins/ulimit.def f
builtins/umask.def f
builtins/wait.def f
builtins/psize.c f
builtins/psize.sh f
builtins/inlib.def f
builtins/bashgetopt.c f
builtins/common.h f
builtins/bashgetopt.h f
cross-build/cygwin32.cache f
cross-build/x86-beos.cache f
cross-build/opennt.cache f
include/ansi_stdlib.h f
include/chartypes.h f
include/filecntl.h f
include/gettext.h f
include/maxpath.h f
include/memalloc.h f
include/ocache.h f
include/posixdir.h f
include/posixjmp.h f
include/posixstat.h f
include/posixtime.h f
include/posixwait.h f
include/shmbutil.h f
include/shtty.h f
include/stdc.h f
include/systimes.h f
include/typemax.h f
include/unionwait.h f
lib/glob/Makefile.in f
lib/glob/sm_loop.c f
lib/glob/smatch.c f
lib/glob/strmatch.c f
lib/glob/strmatch.h f
lib/glob/glob.c f
lib/glob/glob.h f
lib/glob/glob_loop.c f
lib/glob/xmbsrtowcs.c f
lib/glob/collsyms.h f
lib/glob/doc/Makefile f
lib/glob/doc/glob.texi f
lib/glob/ndir.h f
lib/intl/ChangeLog f
lib/intl/Makefile.in f
lib/intl/VERSION f
lib/intl/bindtextdom.c f
lib/intl/config.charset f
lib/intl/dcgettext.c f
lib/intl/dcigettext.c f
lib/intl/dcngettext.c f
lib/intl/dgettext.c f
lib/intl/dngettext.c f
lib/intl/eval-plural.h f
lib/intl/explodename.c f
lib/intl/finddomain.c f
lib/intl/gettext.c f
lib/intl/gettextP.h f
lib/intl/gmo.h f
lib/intl/hash-string.h f
lib/intl/intl-compat.c f
lib/intl/l10nflist.c f
lib/intl/libgnuintl.h.in f
lib/intl/loadinfo.h f
lib/intl/loadmsgcat.c f
lib/intl/localcharset.c f
lib/intl/localcharset.h f
lib/intl/locale.alias f
lib/intl/localealias.c f
lib/intl/localename.c f
lib/intl/log.c f
lib/intl/ngettext.c f
lib/intl/os2compat.c f
lib/intl/os2compat.h f
lib/intl/osdep.c f
lib/intl/plural-exp.c f
lib/intl/plural-exp.h f
lib/intl/plural.c f
lib/intl/plural.y f
lib/intl/ref-add.sin f
lib/intl/ref-del.sin f
lib/intl/relocatable.c f
lib/intl/relocatable.h f
lib/intl/textdomain.c f
lib/malloc/Makefile.in f
lib/malloc/getpagesize.h f
lib/malloc/imalloc.h f
lib/malloc/mstats.h f
lib/malloc/shmalloc.h f
lib/malloc/table.h f
lib/malloc/watch.h f
lib/malloc/alloca.c f
lib/malloc/malloc.c f
lib/malloc/stats.c f
lib/malloc/table.c f
lib/malloc/trace.c f
lib/malloc/watch.c f
lib/malloc/xmalloc.c f
lib/malloc/xleaktrace f 755
lib/malloc/stub.c f
lib/malloc/i386-alloca.s f
lib/malloc/x386-alloca.s f
lib/readline/COPYING f
lib/readline/Makefile.in f
lib/readline/ChangeLog f
lib/readline/README f
lib/readline/STANDALONE f
lib/readline/readline.c f
lib/readline/vi_mode.c f
lib/readline/emacs_keymap.c f
lib/readline/vi_keymap.c f
lib/readline/history.c f
lib/readline/histexpand.c f
lib/readline/histsearch.c f
lib/readline/histfile.c f
lib/readline/funmap.c f
lib/readline/keymaps.c f
lib/readline/util.c f
lib/readline/terminal.c f
lib/readline/xmalloc.c f
lib/readline/search.c f
lib/readline/isearch.c f
lib/readline/parens.c f
lib/readline/rltty.c f
lib/readline/compat.c f
lib/readline/complete.c f
lib/readline/bind.c f
lib/readline/display.c f
lib/readline/signals.c f
lib/readline/kill.c f
lib/readline/text.c f
lib/readline/undo.c f
lib/readline/macro.c f
lib/readline/input.c f
lib/readline/callback.c f
lib/readline/mbutil.c f
lib/readline/misc.c f
lib/readline/nls.c f
lib/readline/shell.c f
lib/readline/savestring.c f
lib/readline/tilde.c f
lib/readline/tilde.h f
lib/readline/rldefs.h f
lib/readline/rlconf.h f
lib/readline/rlmbutil.h f
lib/readline/rlshell.h f
lib/readline/rltty.h f
lib/readline/rltypedefs.h f
lib/readline/rlwinsize.h f
lib/readline/readline.h f
lib/readline/tcap.h f
lib/readline/keymaps.h f
lib/readline/history.h f
lib/readline/histlib.h f
lib/readline/chardefs.h f
lib/readline/posixdir.h f
lib/readline/posixjmp.h f
lib/readline/posixstat.h f
lib/readline/ansi_stdlib.h f
lib/readline/rlstdc.h f
lib/readline/rlprivate.h f
lib/readline/xmalloc.h f
lib/readline/doc/Makefile f
lib/readline/doc/version.texi f
lib/readline/doc/rlman.texi f
lib/readline/doc/rltech.texi f
lib/readline/doc/rluser.texi f
lib/readline/doc/rluserman.texi f
lib/readline/doc/history.texi f
lib/readline/doc/hstech.texi f
lib/readline/doc/hsuser.texi f
lib/readline/doc/fdl.texi f
lib/readline/examples/Makefile f
lib/readline/examples/excallback.c f
lib/readline/examples/fileman.c f
lib/readline/examples/manexamp.c f
lib/readline/examples/histexamp.c f
lib/readline/examples/rltest.c f
lib/readline/examples/rl.c f
lib/readline/examples/rlcat.c f
lib/readline/examples/Inputrc f
lib/sh/Makefile.in f
lib/sh/clktck.c f
lib/sh/clock.c f
lib/sh/fmtullong.c f
lib/sh/fmtulong.c f
lib/sh/fmtumax.c f
lib/sh/getcwd.c f
lib/sh/getenv.c f
lib/sh/inet_aton.c f
lib/sh/itos.c f
lib/sh/mailstat.c f
lib/sh/makepath.c f
lib/sh/memset.c f
lib/sh/mktime.c f
lib/sh/netconn.c f
lib/sh/netopen.c f
lib/sh/oslib.c f
lib/sh/pathcanon.c f
lib/sh/pathphys.c f
lib/sh/rename.c f
lib/sh/setlinebuf.c f
lib/sh/shmatch.c f
lib/sh/shquote.c f
lib/sh/shtty.c f
lib/sh/snprintf.c f
lib/sh/spell.c f
lib/sh/strcasecmp.c f
lib/sh/strerror.c f
lib/sh/strftime.c f
lib/sh/strindex.c f
lib/sh/stringlist.c f
lib/sh/stringvec.c f
lib/sh/strnlen.c f
lib/sh/strpbrk.c f
lib/sh/strstr.c f
lib/sh/strtod.c f
lib/sh/strtoimax.c f
lib/sh/strtol.c f
lib/sh/strtoll.c f
lib/sh/strtoul.c f
lib/sh/strtoull.c f
lib/sh/strtoumax.c f
lib/sh/strtrans.c f
lib/sh/times.c f
lib/sh/timeval.c f
lib/sh/tmpfile.c f
lib/sh/vprint.c f
lib/sh/winsize.c f
lib/sh/xstrchr.c f
lib/sh/zcatfd.c f
lib/sh/zread.c f
lib/sh/zwrite.c f
lib/termcap/Makefile.in f
lib/termcap/ltcap.h f
lib/termcap/termcap.c f
lib/termcap/termcap.h f
lib/termcap/tparam.c f
lib/termcap/version.c f
lib/termcap/grot/termcap.info f
lib/termcap/grot/termcap.info-1 f
lib/termcap/grot/termcap.info-2 f
lib/termcap/grot/termcap.info-3 f
lib/termcap/grot/termcap.info-4 f
lib/termcap/grot/NEWS f
lib/termcap/grot/INSTALL f
lib/termcap/grot/ChangeLog f
lib/termcap/grot/texinfo.tex f
lib/termcap/grot/termcap.texi f
lib/termcap/grot/Makefile.in f
lib/termcap/grot/configure f
lib/termcap/grot/configure.in f
lib/termcap/grot/COPYING f
lib/termcap/grot/README f
lib/tilde/README f
lib/tilde/Makefile.in f
lib/tilde/tilde.c f
lib/tilde/tilde.h f
lib/tilde/shell.c f
po/LINGUAS f
po/Makefile.in.in f
po/Makevars f
po/POTFILES.in f
po/Rules-builtins f
po/Rules-quot f
po/bash.pot f
po/boldquot.sed f
po/en@quot.header f
po/en@boldquot.header f
po/en@quot.po f
po/en@boldquot.po f
po/en@quot.gmo f
po/en@boldquot.gmo f
po/insert-header.sin f
po/quot.sed f
po/remove-potcdate.sin f
CWRU/misc/open-files.c f
CWRU/misc/sigs.c f
CWRU/misc/sigstat.c f
CWRU/misc/bison f
CWRU/misc/errlist.c f
CWRU/misc/hpux10-dlfcn.h f
CWRU/PLATFORMS f
CWRU/README f
CWRU/changelog f
CWRU/sh-redir-hack f
CWRU/mh-folder-comp f
doc/FAQ f
doc/Makefile.in f
doc/bash.1 f
doc/bashbug.1 f
doc/builtins.1 f
doc/rbash.1 f
doc/README f
doc/INTRO f
doc/texinfo.tex f
doc/bashref.texi f
doc/version.texi f
doc/bashref.info f
doc/article.ms f
doc/htmlpost.sh f 755
doc/infopost.sh f 755
doc/fdl.texi f
doc/fdl.txt f
support/Makefile.in f
support/bashversion.c f
support/config.guess f
support/config.rpath f 755
support/config.sub f
support/printenv.sh f 755
support/printenv.c f
support/bash.xbm f
support/missing f 755
support/mkclone f 755
support/mkconffiles f 755
support/mkdirs f 755
support/mkinstalldirs f 755
support/mkversion.sh f 755
support/mksignames.c f
support/signames.c f
support/bashbug.sh f
support/man2html.c f
support/recho.c f
support/zecho.c f
support/SYMLINKS f
support/fixlinks f 755
support/install.sh f 755
support/texi2dvi f 755
support/texi2html f 755
support/xenix-link.sh f 755
support/shobj-conf f 755
support/rlvers.sh f 755
examples/bashdb/PERMISSION f
examples/bashdb/README f
examples/bashdb/bashdb f
examples/bashdb/bashdb.el f
examples/obashdb/PERMISSION f
examples/obashdb/README f
examples/obashdb/bashdb f
examples/obashdb/bashdb.fns f
examples/obashdb/bashdb.pre f
examples/complete/complete-examples f
examples/complete/complete.ianmac f
examples/complete/complete2.ianmac f
examples/complete/complete.freebsd f
examples/complete/complete.gnu-longopt f
examples/complete/bashcc-1.0.1.tar.gz f
examples/loadables/README f
examples/loadables/template.c f
examples/loadables/Makefile.in f
examples/loadables/necho.c f
examples/loadables/hello.c f
examples/loadables/print.c f
examples/loadables/realpath.c f
examples/loadables/sleep.c f
examples/loadables/strftime.c f
examples/loadables/truefalse.c f
examples/loadables/getconf.h f
examples/loadables/getconf.c f
examples/loadables/finfo.c f
examples/loadables/cat.c f
examples/loadables/cut.c f
examples/loadables/logname.c f
examples/loadables/basename.c f
examples/loadables/dirname.c f
examples/loadables/tty.c f
examples/loadables/pathchk.c f
examples/loadables/tee.c f
examples/loadables/rmdir.c f
examples/loadables/head.c f
examples/loadables/printenv.c f
examples/loadables/push.c f
examples/loadables/id.c f
examples/loadables/whoami.c f
examples/loadables/uname.c f
examples/loadables/sync.c f
examples/loadables/mkdir.c f
examples/loadables/ln.c f
examples/loadables/unlink.c f
examples/loadables/perl/Makefile.in f
examples/loadables/perl/README f
examples/loadables/perl/bperl.c f
examples/loadables/perl/iperl.c f
examples/functions/array-stuff f
examples/functions/array-to-string f
examples/functions/autoload f
examples/functions/autoload.v2 f
examples/functions/autoload.v3 f
examples/functions/basename f
examples/functions/basename2 f
examples/functions/coproc.bash f
examples/functions/coshell.README f
examples/functions/coshell.bash f
examples/functions/csh-compat f
examples/functions/dirfuncs f
examples/functions/dirname f
examples/functions/emptydir f
examples/functions/exitstat f
examples/functions/external f
examples/functions/fact f
examples/functions/fstty f
examples/functions/func f
examples/functions/gethtml f
examples/functions/getoptx.bash f
examples/functions/inetaddr f
examples/functions/inpath f
examples/functions/isnum.bash f
examples/functions/isnum2 f
examples/functions/isvalidip f
examples/functions/jdate.bash f
examples/functions/jj.bash f
examples/functions/keep f
examples/functions/ksh-cd f
examples/functions/ksh-compat-test f
examples/functions/kshenv f
examples/functions/login f
examples/functions/lowercase f
examples/functions/manpage f
examples/functions/mhfold f
examples/functions/notify.bash f
examples/functions/pathfuncs f
examples/functions/recurse f
examples/functions/repeat2 f
examples/functions/repeat3 f
examples/functions/seq f
examples/functions/seq2 f
examples/functions/shcat f
examples/functions/shcat2 f
examples/functions/sort-pos-params f
examples/functions/substr f
examples/functions/substr2 f
examples/functions/term f
examples/functions/whatis f
examples/functions/whence f
examples/functions/which f
examples/functions/xalias.bash f
examples/functions/xfind.bash f
examples/scripts/adventure.sh f
examples/scripts/bcsh.sh f
examples/scripts/cat.sh f
examples/scripts/center f
examples/scripts/dd-ex.sh f
examples/scripts/fixfiles.bash f
examples/scripts/hanoi.bash f
examples/scripts/inpath f
examples/scripts/krand.bash f
examples/scripts/line-input.bash f
examples/scripts/nohup.bash f
examples/scripts/precedence f
examples/scripts/randomcard.bash f
examples/scripts/scrollbar f
examples/scripts/scrollbar2 f
examples/scripts/self-repro f
examples/scripts/showperm.bash f
examples/scripts/shprompt f
examples/scripts/spin.bash f
examples/scripts/timeout f
examples/scripts/vtree2 f
examples/scripts/vtree3 f
examples/scripts/vtree3a f
examples/scripts/websrv.sh f
examples/scripts/xterm_title f
examples/scripts/zprintf f
examples/startup-files/README f
examples/startup-files/Bashrc.bfox f
examples/startup-files/Bash_aliases f
examples/startup-files/Bash_profile f
examples/startup-files/bash-profile f
examples/startup-files/bashrc f
examples/startup-files/apple/README f
examples/startup-files/apple/aliases f
examples/startup-files/apple/bash.defaults f
examples/startup-files/apple/environment f
examples/startup-files/apple/login f
examples/startup-files/apple/logout f
examples/startup-files/apple/rc f
examples/misc/suncmd.termcap f
examples/misc/aliasconv.sh f
examples/misc/aliasconv.bash f
examples/misc/cshtobash f
tests/README f
tests/alias.tests f
tests/alias.right f
tests/appendop.tests f
tests/appendop.right f
tests/arith-for.tests f
tests/arith-for.right f
tests/arith.tests f
tests/arith.right f
tests/arith1.sub f
tests/arith2.sub f
tests/array.tests f
tests/array.right f
tests/array1.sub f
tests/array2.sub f
tests/array3.sub f
tests/array4.sub f
tests/array-at-star f
tests/array2.right f
tests/braces.tests f
tests/braces.right f
tests/builtins.tests f
tests/builtins.right f
tests/builtins1.sub f
tests/builtins2.sub f
tests/source1.sub f
tests/source2.sub f
tests/source3.sub f
tests/source4.sub f
tests/source5.sub f
tests/cond.tests f
tests/cond.right f
tests/cprint.tests f
tests/cprint.right f
tests/dbg-support.right f
tests/dbg-support.sub f
tests/dbg-support.tests f
tests/dbg-support2.right f
tests/dbg-support2.tests f
tests/dollar-at-star f
tests/dollar-at1.sub f
tests/dollar-at2.sub f
tests/dollar-star1.sub f
tests/dollar-star2.sub f
tests/dollar.right f
tests/dstack.tests f
tests/dstack.right f
tests/dstack2.tests f
tests/dstack2.right f
tests/errors.tests f
tests/errors.right f
tests/execscript f
tests/exec.right f
tests/exec1.sub f 755
tests/exec2.sub f
tests/exec3.sub f
tests/exec4.sub f
tests/exec5.sub f
tests/exec6.sub f
tests/exec7.sub f
tests/exp-tests f
tests/exp.right f
tests/extglob.tests f
tests/extglob.right f
tests/extglob2.tests f
tests/extglob2.right f
tests/extglob3.tests f
tests/extglob3.right f
tests/func.tests f
tests/func.right f
tests/func1.sub f
tests/func2.sub f
tests/func3.sub f
tests/getopts.tests f
tests/getopts.right f
tests/getopts1.sub f
tests/getopts2.sub f
tests/getopts3.sub f
tests/getopts4.sub f
tests/getopts5.sub f
tests/getopts6.sub f
tests/getopts7.sub f
tests/glob-test f
tests/glob1.sub f
tests/glob.right f
tests/heredoc.tests f
tests/heredoc.right f
tests/herestr.tests f
tests/herestr.right f
tests/histexp.tests f
tests/histexp.right f
tests/history.tests f
tests/history.right f
tests/history.list f 444
tests/ifs.tests f
tests/ifs.right f
tests/ifs-posix.tests f
tests/ifs-posix.right f
tests/input-line.sh f
tests/input-line.sub f
tests/input.right f
tests/intl.tests f
tests/intl.right f
tests/iquote.tests f
tests/iquote.right f
tests/invert.tests f
tests/invert.right f
tests/jobs.tests f
tests/jobs1.sub f
tests/jobs2.sub f
tests/jobs3.sub f
tests/jobs4.sub f
tests/jobs.right f
tests/more-exp.tests f
tests/more-exp.right f
tests/new-exp.tests f
tests/new-exp1.sub f
tests/new-exp2.sub f
tests/new-exp3.sub f
tests/new-exp4.sub f
tests/new-exp5.sub f
tests/new-exp.right f
tests/nquote.tests f
tests/nquote.right f
tests/nquote1.tests f
tests/nquote1.right f
tests/nquote2.tests f
tests/nquote2.right f
tests/nquote3.tests f
tests/nquote3.right f
tests/nquote4.tests f
tests/nquote4.right f
tests/posix2.tests f
tests/posix2.right f
tests/posixpat.tests f
tests/posixpat.right f
tests/prec.right f
tests/precedence f
tests/printf.tests f
tests/printf.right f
tests/quote.tests f
tests/quote.right f
tests/read.tests f
tests/read.right f
tests/read1.sub f
tests/read2.sub f
tests/read3.sub f
tests/read4.sub f
tests/read5.sub f
tests/redir.tests f
tests/redir.right f
tests/redir1.sub f
tests/redir2.sub f
tests/redir3.sub f
tests/redir3.in1 f
tests/redir3.in2 f
tests/redir4.sub f
tests/redir4.in1 f
tests/redir5.sub f
tests/redir6.sub f
tests/redir7.sub f
tests/rhs-exp.tests f
tests/rhs-exp.right f
tests/rsh.tests f
tests/rsh.right f
tests/run-all f
tests/run-minimal f
tests/run-alias f
tests/run-appendop f
tests/run-arith-for f
tests/run-arith f
tests/run-array f
tests/run-array2 f
tests/run-braces f
tests/run-builtins f
tests/run-cond f
tests/run-cprint f
tests/run-dbg-support f
tests/run-dbg-support2 f
tests/run-dirstack f
tests/run-dollars f
tests/run-errors f
tests/run-execscript f
tests/run-exp-tests f
tests/run-extglob f
tests/run-extglob2 f
tests/run-extglob3 f
tests/run-func f
tests/run-getopts f
tests/run-glob-test f
tests/run-heredoc f
tests/run-herestr f
tests/run-histexpand f
tests/run-history f
tests/run-ifs f
tests/run-ifs-posix f
tests/run-input-test f
tests/run-intl f
tests/run-iquote f
tests/run-invert f
tests/run-jobs f
tests/run-more-exp f
tests/run-new-exp f
tests/run-nquote f
tests/run-nquote1 f
tests/run-nquote2 f
tests/run-nquote3 f
tests/run-nquote4 f
tests/run-posix2 f
tests/run-posixpat f
tests/run-precedence f
tests/run-printf f
tests/run-quote f
tests/run-read f
tests/run-redir f
tests/run-rhs-exp f
tests/run-rsh f
tests/run-set-e f
tests/run-set-x f
tests/run-shopt f
tests/run-strip f
tests/run-test f
tests/run-tilde f
tests/run-tilde2 f
tests/run-trap f
tests/run-type f
tests/run-varenv f
tests/set-e-test f
tests/set-e.right f
tests/set-x.tests f
tests/set-x.right f
tests/shopt.tests f
tests/shopt.right f
tests/strip.tests f
tests/strip.right f
tests/test.tests f
tests/test.right f
tests/tilde.tests f
tests/tilde.right f
tests/tilde2.tests f
tests/tilde2.right f
tests/trap.tests f
tests/trap.right f
tests/trap1.sub f 755
tests/trap2.sub f 755
tests/trap2a.sub f 755
tests/type.tests f
tests/type.right f
tests/varenv.right f
tests/varenv.sh f
tests/varenv1.sub f
tests/varenv2.sub f
tests/version f
tests/version.mini f
tests/misc/dev-tcp.tests f
tests/misc/perf-script f
tests/misc/perftest f
tests/misc/read-nchars.tests f
tests/misc/redir-t2.sh f
tests/misc/run-r2.sh f
tests/misc/sigint-1.sh f
tests/misc/sigint-2.sh f
tests/misc/sigint-3.sh f
tests/misc/sigint-4.sh f
tests/misc/test-minus-e.1 f
tests/misc/test-minus-e.2 f
tests/misc/wait-bg.tests f
examples/scripts.v2/PERMISSION f
examples/scripts.v2/README f
examples/scripts.v2/arc2tarz f
examples/scripts.v2/bashrand f
examples/scripts.v2/cal2day.bash f
examples/scripts.v2/cdhist.bash f
examples/scripts.v2/corename f
examples/scripts.v2/fman f
examples/scripts.v2/frcp f
examples/scripts.v2/lowercase f
examples/scripts.v2/ncp f
examples/scripts.v2/newext f
examples/scripts.v2/nmv f
examples/scripts.v2/pages f
examples/scripts.v2/pf f
examples/scripts.v2/ren f
examples/scripts.v2/rename f
examples/scripts.v2/repeat f
examples/scripts.v2/untar f
examples/scripts.v2/uudec f
examples/scripts.v2/uuenc f
examples/scripts.v2/vtree f
examples/scripts.v2/where f
examples/scripts.v2/pmtop f
examples/scripts.v2/shprof f
examples/scripts.noah/PERMISSION f
examples/scripts.noah/README f
examples/scripts.noah/aref.bash f
examples/scripts.noah/bash.sub.bash f
examples/scripts.noah/bash_version.bash f
examples/scripts.noah/meta.bash f
examples/scripts.noah/mktmp.bash f
examples/scripts.noah/number.bash f
examples/scripts.noah/prompt.bash f
examples/scripts.noah/remap_keys.bash f
examples/scripts.noah/require.bash f
examples/scripts.noah/send_mail.bash f
examples/scripts.noah/shcat.bash f
examples/scripts.noah/source.bash f
examples/scripts.noah/string.bash f
examples/scripts.noah/stty.bash f
examples/scripts.noah/y_or_n_p.bash f
+29 -10
View File
@@ -1,4 +1,4 @@
# Makefile for bash-3.1, version 2.157
# Makefile for bash-3.1, version 2.159
#
# Copyright (C) 1996-2005 Free Software Foundation, Inc.
@@ -128,6 +128,8 @@ LOCALE_DEFS = -DLOCALEDIR='"$(localedir)"' -DPACKAGE='"$(PACKAGE)"'
LOCAL_LIBS = @LOCAL_LIBS@
LIBS = $(BUILTINS_LIB) $(LIBRARIES) @LIBS@
LIBS_FOR_BUILD =
STATIC_LD = @STATIC_LD@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
@@ -418,6 +420,7 @@ SIGNAMES_H = @SIGNAMES_H@
# object files chosen based on running of configure
JOBS_O = @JOBS_O@
SIGLIST_O = @SIGLIST_O@
SIGNAMES_O = @SIGNAMES_O@
# Matching object files.
OBJECTS = shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \
@@ -426,7 +429,7 @@ OBJECTS = shell.o eval.o y.tab.o general.o make_cmd.o print_cmd.o $(GLOBO) \
trap.o input.o unwind_prot.o pathexp.o sig.o test.o version.o \
alias.o array.o arrayfunc.o braces.o bracecomp.o bashhist.o \
bashline.o $(SIGLIST_O) list.o stringlib.o locale.o findcmd.o redir.o \
pcomplete.o pcomplib.o syntax.o xmalloc.o
pcomplete.o pcomplib.o syntax.o xmalloc.o $(SIGNAMES_O)
# Where the source code of the shell builtins resides.
BUILTIN_SRCDIR=$(srcdir)/builtins
@@ -495,7 +498,7 @@ CREATED_SUPPORT = signames.h recho$(EXEEXT) zecho$(EXEEXT) printenv$(EXEEXT) \
tests/recho$(EXEEXT) tests/zecho$(EXEEXT) \
tests/printenv$(EXEEXT) mksignames$(EXEEXT) lsignames.h \
mksyntax${EXEEXT} syntax.c $(VERSPROG) $(VERSOBJ) \
buildversion.o
buildversion.o mksignames.o signames.o
CREATED_CONFIGURE = config.h config.cache config.status config.log \
stamp-h po/POTFILES
CREATED_MAKEFILES = Makefile builtins/Makefile doc/Makefile \
@@ -547,7 +550,7 @@ version.h: $(SOURCES) config.h Makefile
&& mv newversion.h version.h
bashversion$(EXEEXT): patchlevel.h conftypes.h version.h buildversion.o $(SUPPORT_SRC)bashversion.c
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)bashversion.c buildversion.o
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)bashversion.c buildversion.o ${LIBS_FOR_BUILD}
buildversion.o: version.h conftypes.h patchlevel.h $(srcdir)/version.c
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -c -o $@ $(srcdir)/version.c
@@ -609,11 +612,25 @@ ${INTL_LIBRARY}: config.h ${INTL_LIBDIR}/Makefile
${LIBINTL_H}: ${INTL_LIBRARY}
mksignames$(EXEEXT): $(SUPPORT_SRC)mksignames.c
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)mksignames.c
signames.o: $(SUPPORT_SRC)signames.c
$(RM) $@
$(CC) $(CCFLAGS) -c $(SUPPORT_SRC)signames.c
buildsignames.o: $(SUPPORT_SRC)signames.c
$(RM) $@
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -o $@ -c $(SUPPORT_SRC)signames.c
mksignames.o: $(SUPPORT_SRC)mksignames.c
$(RM) $@
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -DBUILDTOOL -c $(SUPPORT_SRC)mksignames.c
mksignames$(EXEEXT): mksignames.o buildsignames.o
$(RM) $@
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ mksignames.o buildsignames.o ${LIBS_FOR_BUILD}
mksyntax$(EXEEXT): ${srcdir}/mksyntax.c config.h syntax.h ${BASHINCDIR}/chartypes.h
${CC_FOR_BUILD} ${CCFLAGS_FOR_BUILD} -o $@ ${srcdir}/mksyntax.c
$(RM) $@
${CC_FOR_BUILD} ${CCFLAGS_FOR_BUILD} -o $@ ${srcdir}/mksyntax.c ${LIBS_FOR_BUILD}
# make a list of signals for the local system -- this is done when we're
# *not* cross-compiling
@@ -782,13 +799,13 @@ maybe-clean:
fi
recho$(EXEEXT): $(SUPPORT_SRC)recho.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)recho.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)recho.c ${LIBS_FOR_BUILD}
zecho$(EXEEXT): $(SUPPORT_SRC)zecho.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)zecho.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)zecho.c ${LIBS_FOR_BUILD}
printenv$(EXEEXT): $(SUPPORT_SRC)printenv.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)printenv.c
@$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) -o $@ $(SUPPORT_SRC)printenv.c ${LIBS_FOR_BUILD}
test tests check: force $(Program) $(TESTS_SUPPORT)
@-test -d tests || mkdir tests
@@ -1143,6 +1160,8 @@ variables.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
version.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
xmalloc.o: bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h
signames.o: config.h bashansi.h ${BASHINCDIR}/ansi_stdlib.h
# XXX - dependencies checked through here
# builtin c sources
+1439
View File
File diff suppressed because it is too large Load Diff
+1455
View File
File diff suppressed because it is too large Load Diff
Vendored
+2 -2
View File
@@ -933,7 +933,7 @@ AC_DEFINE(HAVE_STRUCT_STAT_ST_BLOCKS)
fi
])
AC_DEFUN(BASH_CHECK_LIB_TERMCAP,
AC_DEFUN([BASH_CHECK_LIB_TERMCAP],
[
if test "X$bash_cv_termcap_lib" = "X"; then
_bash_needmsg=yes
@@ -1710,7 +1710,7 @@ dnl require:
dnl AC_PROG_CC
dnl BASH_CHECK_LIB_TERMCAP
AC_DEFUN(RL_LIB_READLINE_VERSION,
AC_DEFUN([RL_LIB_READLINE_VERSION],
[
AC_REQUIRE([BASH_CHECK_LIB_TERMCAP])
Vendored
+3962
View File
File diff suppressed because it is too large Load Diff
+2 -8
View File
@@ -438,13 +438,11 @@ skipsubscript (s, i)
#if defined (HANDLE_MULTIBYTE)
mbstate_t state, state_bak;
size_t slength, mblength;
size_t mb_cur_max;
#endif
#if defined (HANDLE_MULTIBYTE)
memset (&state, '\0', sizeof (mbstate_t));
slength = strlen (s + i);
mb_cur_max = MB_CUR_MAX;
#endif
count = 1;
@@ -452,7 +450,7 @@ skipsubscript (s, i)
{
/* Advance one (possibly multibyte) character in S starting at I. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1)
if (MB_CUR_MAX > 1)
{
state_bak = state;
mblength = mbrlen (s + i, slength, &state);
@@ -592,11 +590,7 @@ array_expand_index (s, len)
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
#if 0
t = expand_string_to_string (exp, 0);
#else
t = expand_string_to_string (exp, Q_DOUBLE_QUOTES);
#endif
t = expand_arith_string (exp);
this_command_name = (char *)NULL;
val = evalexp (t, &expok);
free (t);
+819
View File
@@ -0,0 +1,819 @@
/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
/* Copyright (C) 2001-2005 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 (ARRAY_VARS)
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "bashintl.h"
#include "shell.h"
#include "shmbutil.h"
#include "builtins/common.h"
extern char *this_command_name;
extern int last_command_exit_value;
extern int array_needs_making;
static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, int));
static void quote_array_assignment_chars __P((WORD_LIST *));
static char *array_value_internal __P((char *, int, int, int *));
/* Standard error message to use when encountering an invalid array subscript */
char *bash_badsub_errmsg = N_("bad array subscript");
/* **************************************************************** */
/* */
/* Functions to manipulate array variables and perform assignments */
/* */
/* **************************************************************** */
/* Convert a shell variable to an array variable. The original value is
saved as array[0]. */
SHELL_VAR *
convert_var_to_array (var)
SHELL_VAR *var;
{
char *oldval;
ARRAY *array;
oldval = value_cell (var);
array = array_create ();
if (oldval)
array_insert (array, 0, oldval);
FREE (value_cell (var));
var_setarray (var, array);
/* these aren't valid anymore */
var->dynamic_value = (sh_var_value_func_t *)NULL;
var->assign_func = (sh_var_assign_func_t *)NULL;
INVALIDATE_EXPORTSTR (var);
if (exported_p (var))
array_needs_making++;
VSETATTR (var, att_array);
VUNSETATTR (var, att_invisible);
return var;
}
static SHELL_VAR *
bind_array_var_internal (entry, ind, value, flags)
SHELL_VAR *entry;
arrayind_t ind;
char *value;
int flags;
{
SHELL_VAR *dentry;
char *newval;
/* If we're appending, we need the old value of the array reference, so
fake out make_variable_value with a dummy SHELL_VAR */
if (flags & ASS_APPEND)
{
dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
dentry->name = savestring (entry->name);
newval = array_reference (array_cell (entry), ind);
if (newval)
dentry->value = savestring (newval);
else
{
dentry->value = (char *)xmalloc (1);
dentry->value[0] = '\0';
}
dentry->exportstr = 0;
dentry->attributes = entry->attributes & ~(att_array|att_exported);
/* Leave the rest of the members uninitialized; the code doesn't look
at them. */
newval = make_variable_value (dentry, value, flags);
dispose_variable (dentry);
}
else
newval = make_variable_value (entry, value, flags);
if (entry->assign_func)
(*entry->assign_func) (entry, newval, ind);
else
array_insert (array_cell (entry), ind, newval);
FREE (newval);
return (entry);
}
/* Perform an array assignment name[ind]=value. If NAME already exists and
is not an array, and IND is 0, perform name=value instead. If NAME exists
and is not an array, and IND is not 0, convert it into an array with the
existing value as name[0].
If NAME does not exist, just create an array variable, no matter what
IND's value may be. */
SHELL_VAR *
bind_array_variable (name, ind, value, flags)
char *name;
arrayind_t ind;
char *value;
int flags;
{
SHELL_VAR *entry;
entry = var_lookup (name, shell_variables);
if (entry == (SHELL_VAR *) 0)
entry = make_new_array_variable (name);
else if (readonly_p (entry) || noassign_p (entry))
{
if (readonly_p (entry))
err_readonly (name);
return (entry);
}
else if (array_p (entry) == 0)
entry = convert_var_to_array (entry);
/* ENTRY is an array variable, and ARRAY points to the value. */
return (bind_array_var_internal (entry, ind, value, flags));
}
/* Parse NAME, a lhs of an assignment statement of the form v[s], and
assign VALUE to that array element by calling bind_array_variable(). */
SHELL_VAR *
assign_array_element (name, value, flags)
char *name, *value;
int flags;
{
char *sub, *vname;
arrayind_t ind;
int sublen;
SHELL_VAR *entry;
vname = array_variable_name (name, &sub, &sublen);
if (vname == 0)
return ((SHELL_VAR *)NULL);
if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1))
{
free (vname);
err_badarraysub (name);
return ((SHELL_VAR *)NULL);
}
ind = array_expand_index (sub, sublen);
if (ind < 0)
{
free (vname);
err_badarraysub (name);
return ((SHELL_VAR *)NULL);
}
entry = bind_array_variable (vname, ind, value, flags);
free (vname);
return (entry);
}
/* Find the array variable corresponding to NAME. If there is no variable,
create a new array variable. If the variable exists but is not an array,
convert it to an indexed array. If CHECK_FLAGS is non-zero, an existing
variable is checked for the readonly or noassign attribute in preparation
for assignment (e.g., by the `read' builtin). */
SHELL_VAR *
find_or_make_array_variable (name, check_flags)
char *name;
int check_flags;
{
SHELL_VAR *var;
var = find_variable (name);
if (var == 0)
var = make_new_array_variable (name);
else if (check_flags && (readonly_p (var) || noassign_p (var)))
{
if (readonly_p (var))
err_readonly (name);
return ((SHELL_VAR *)NULL);
}
else if (array_p (var) == 0)
var = convert_var_to_array (var);
return (var);
}
/* Perform a compound assignment statement for array NAME, where VALUE is
the text between the parens: NAME=( VALUE ) */
SHELL_VAR *
assign_array_from_string (name, value, flags)
char *name, *value;
int flags;
{
SHELL_VAR *var;
var = find_or_make_array_variable (name, 1);
if (var == 0)
return ((SHELL_VAR *)NULL);
return (assign_array_var_from_string (var, value, flags));
}
/* Sequentially assign the indices of indexed array variable VAR from the
words in LIST. */
SHELL_VAR *
assign_array_var_from_word_list (var, list, flags)
SHELL_VAR *var;
WORD_LIST *list;
int flags;
{
register arrayind_t i;
register WORD_LIST *l;
ARRAY *a;
a = array_cell (var);
i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
for (l = list; l; l = l->next, i++)
if (var->assign_func)
(*var->assign_func) (var, l->word->word, i);
else
array_insert (a, i, l->word->word);
return var;
}
/* Perform a compound array assignment: VAR->name=( VALUE ). The
VALUE has already had the parentheses stripped. */
SHELL_VAR *
assign_array_var_from_string (var, value, flags)
SHELL_VAR *var;
char *value;
int flags;
{
ARRAY *a;
WORD_LIST *list, *nlist;
char *w, *val, *nval;
int ni, len;
arrayind_t ind, last_ind;
if (value == 0)
return var;
/* If this is called from declare_builtin, value[0] == '(' and
xstrchr(value, ')') != 0. In this case, we need to extract
the value from between the parens before going on. */
if (*value == '(') /*)*/
{
ni = 1;
val = extract_array_assignment_list (value, &ni);
if (val == 0)
return var;
}
else
val = value;
/* Expand the value string into a list of words, performing all the
shell expansions including pathname generation and word splitting. */
/* First we split the string on whitespace, using the shell parser
(ksh93 seems to do this). */
list = parse_string_to_word_list (val, 1, "array assign");
/* If we're using [subscript]=value, we need to quote each [ and ] to
prevent unwanted filename expansion. */
if (list)
quote_array_assignment_chars (list);
/* Now that we've split it, perform the shell expansions on each
word in the list. */
nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL;
dispose_words (list);
if (val != value)
free (val);
a = array_cell (var);
/* Now that we are ready to assign values to the array, kill the existing
value. */
if (a && (flags & ASS_APPEND) == 0)
array_flush (a);
last_ind = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
for (list = nlist; list; list = list->next)
{
w = list->word->word;
/* We have a word of the form [ind]=value */
if ((list->word->flags & W_ASSIGNMENT) && w[0] == '[')
{
len = skipsubscript (w, 0);
#if 1
/* XXX - changes for `+=' */
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
#else
if (w[len] != ']' || w[len+1] != '=')
#endif
{
nval = make_variable_value (var, w, flags);
if (var->assign_func)
(*var->assign_func) (var, nval, last_ind);
else
array_insert (a, last_ind, nval);
FREE (nval);
last_ind++;
continue;
}
if (len == 1)
{
err_badarraysub (w);
continue;
}
if (ALL_ELEMENT_SUB (w[1]) && len == 2)
{
report_error (_("%s: cannot assign to non-numeric index"), w);
continue;
}
ind = array_expand_index (w + 1, len);
if (ind < 0)
{
err_badarraysub (w);
continue;
}
last_ind = ind;
/* XXX - changes for `+=' */
if (w[len + 1] == '+' && w[len + 2] == '=')
{
flags |= ASS_APPEND;
val = w + len + 3;
}
else
val = w + len + 2;
}
else /* No [ind]=value, just a stray `=' */
{
ind = last_ind;
val = w;
}
if (integer_p (var))
this_command_name = (char *)NULL; /* no command name for errors */
bind_array_var_internal (var, ind, val, flags);
last_ind++;
}
dispose_words (nlist);
return (var);
}
/* For each word in a compound array assignment, if the word looks like
[ind]=value, quote the `[' and `]' before the `=' to protect them from
unwanted filename expansion. */
static void
quote_array_assignment_chars (list)
WORD_LIST *list;
{
char *s, *t, *nword;
int saw_eq;
WORD_LIST *l;
for (l = list; l; l = l->next)
{
if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
continue; /* should not happen, but just in case... */
/* Don't bother if it doesn't look like [ind]=value */
if (l->word->word[0] != '[' || xstrchr (l->word->word, '=') == 0) /* ] */
continue;
s = nword = (char *)xmalloc (strlen (l->word->word) * 2 + 1);
saw_eq = 0;
for (t = l->word->word; *t; )
{
if (*t == '=')
saw_eq = 1;
if (saw_eq == 0 && (*t == '[' || *t == ']'))
*s++ = '\\';
*s++ = *t++;
}
*s = '\0';
free (l->word->word);
l->word->word = nword;
}
}
/* This function assumes s[i] == '['; returns with s[ret] == ']' if
an array subscript is correctly parsed. */
int
skipsubscript (s, i)
const char *s;
int i;
{
int count, c;
#if defined (HANDLE_MULTIBYTE)
mbstate_t state, state_bak;
size_t slength, mblength;
size_t mb_cur_max;
#endif
#if defined (HANDLE_MULTIBYTE)
memset (&state, '\0', sizeof (mbstate_t));
slength = strlen (s + i);
mb_cur_max = MB_CUR_MAX;
#endif
count = 1;
while (count)
{
/* Advance one (possibly multibyte) character in S starting at I. */
#if defined (HANDLE_MULTIBYTE)
if (mb_cur_max > 1)
{
state_bak = state;
mblength = mbrlen (s + i, slength, &state);
if (MB_INVALIDCH (mblength))
{
state = state_bak;
i++;
slength--;
}
else if (MB_NULLWCH (mblength))
return i;
else
{
i += mblength;
slength -= mblength;
}
}
else
#endif
++i;
c = s[i];
if (c == 0)
break;
else if (c == '[')
count++;
else if (c == ']')
count--;
}
return i;
}
/* This function is called with SUB pointing to just after the beginning
`[' of an array subscript and removes the array element to which SUB
expands from array VAR. A subscript of `*' or `@' unsets the array. */
int
unbind_array_element (var, sub)
SHELL_VAR *var;
char *sub;
{
int len;
arrayind_t ind;
ARRAY_ELEMENT *ae;
len = skipsubscript (sub, 0);
if (sub[len] != ']' || len == 0)
{
builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg));
return -1;
}
sub[len] = '\0';
if (ALL_ELEMENT_SUB (sub[0]) && sub[1] == 0)
{
unbind_variable (var->name);
return (0);
}
ind = array_expand_index (sub, len+1);
if (ind < 0)
{
builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
return -1;
}
ae = array_remove (array_cell (var), ind);
if (ae)
array_dispose_element (ae);
return 0;
}
/* Format and output an array assignment in compound form VAR=(VALUES),
suitable for re-use as input. */
void
print_array_assignment (var, quoted)
SHELL_VAR *var;
int quoted;
{
char *vstr;
vstr = array_to_assign (array_cell (var), quoted);
if (vstr == 0)
printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
else
{
printf ("%s=%s\n", var->name, vstr);
free (vstr);
}
}
/***********************************************************************/
/* */
/* Utility functions to manage arrays and their contents for expansion */
/* */
/***********************************************************************/
/* Return 1 if NAME is a properly-formed array reference v[sub]. */
int
valid_array_reference (name)
char *name;
{
char *t;
int r, len;
t = xstrchr (name, '['); /* ] */
if (t)
{
*t = '\0';
r = legal_identifier (name);
*t = '[';
if (r == 0)
return 0;
/* Check for a properly-terminated non-blank subscript. */
len = skipsubscript (t, 0);
if (t[len] != ']' || len == 1)
return 0;
for (r = 1; r < len; r++)
if (whitespace (t[r]) == 0)
return 1;
return 0;
}
return 0;
}
/* Expand the array index beginning at S and extending LEN characters. */
arrayind_t
array_expand_index (s, len)
char *s;
int len;
{
char *exp, *t;
int expok;
arrayind_t val;
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
t = expand_arith_string (exp);
this_command_name = (char *)NULL;
val = evalexp (t, &expok);
free (t);
free (exp);
if (expok == 0)
{
last_command_exit_value = EXECUTION_FAILURE;
jump_to_top_level (DISCARD);
}
return val;
}
/* Return the name of the variable specified by S without any subscript.
If SUBP is non-null, return a pointer to the start of the subscript
in *SUBP. If LENP is non-null, the length of the subscript is returned
in *LENP. This returns newly-allocated memory. */
char *
array_variable_name (s, subp, lenp)
char *s, **subp;
int *lenp;
{
char *t, *ret;
int ind, ni;
t = xstrchr (s, '[');
if (t == 0)
{
if (subp)
*subp = t;
if (lenp)
*lenp = 0;
return ((char *)NULL);
}
ind = t - s;
ni = skipsubscript (s, ind);
if (ni <= ind + 1 || s[ni] != ']')
{
err_badarraysub (s);
if (subp)
*subp = t;
if (lenp)
*lenp = 0;
return ((char *)NULL);
}
*t = '\0';
ret = savestring (s);
*t++ = '['; /* ] */
if (subp)
*subp = t;
if (lenp)
*lenp = ni - ind;
return ret;
}
/* Return the variable specified by S without any subscript. If SUBP is
non-null, return a pointer to the start of the subscript in *SUBP.
If LENP is non-null, the length of the subscript is returned in *LENP. */
SHELL_VAR *
array_variable_part (s, subp, lenp)
char *s, **subp;
int *lenp;
{
char *t;
SHELL_VAR *var;
t = array_variable_name (s, subp, lenp);
if (t == 0)
return ((SHELL_VAR *)NULL);
var = find_variable (t);
free (t);
return (var == 0 || invisible_p (var)) ? (SHELL_VAR *)0 : var;
}
/* Return a string containing the elements in the array and subscript
described by S. If the subscript is * or @, obeys quoting rules akin
to the expansion of $* and $@ including double quoting. If RTYPE
is non-null it gets 1 if the array reference is name[@] or name[*]
and 0 otherwise. */
static char *
array_value_internal (s, quoted, allow_all, rtype)
char *s;
int quoted, allow_all, *rtype;
{
int len;
arrayind_t ind;
char *retval, *t, *temp;
WORD_LIST *l;
SHELL_VAR *var;
var = array_variable_part (s, &t, &len);
/* Expand the index, even if the variable doesn't exist, in case side
effects are needed, like ${w[i++]} where w is unset. */
#if 0
if (var == 0)
return (char *)NULL;
#endif
if (len == 0)
return ((char *)NULL); /* error message already printed */
/* [ */
if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
{
if (rtype)
*rtype = 1;
if (allow_all == 0)
{
err_badarraysub (s);
return ((char *)NULL);
}
else if (var == 0 || value_cell (var) == 0)
return ((char *)NULL);
else if (array_p (var) == 0)
l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);
else
{
l = array_to_word_list (array_cell (var));
if (l == (WORD_LIST *)NULL)
return ((char *) NULL);
}
if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
{
temp = string_list_dollar_star (l);
retval = quote_string (temp);
free (temp);
}
else /* ${name[@]} or unquoted ${name[*]} */
retval = string_list_dollar_at (l, quoted);
dispose_words (l);
}
else
{
if (rtype)
*rtype = 0;
ind = array_expand_index (t, len);
if (ind < 0)
{
if (var)
err_badarraysub (var->name);
else
{
t[-1] = '\0';
err_badarraysub (s);
t[-1] = '['; /* ] */
}
return ((char *)NULL);
}
if (var == 0)
return ((char *)NULL);
if (array_p (var) == 0)
return (ind == 0 ? value_cell (var) : (char *)NULL);
retval = array_reference (array_cell (var), ind);
}
return retval;
}
/* Return a string containing the elements described by the array and
subscript contained in S, obeying quoting for subscripts * and @. */
char *
array_value (s, quoted, rtype)
char *s;
int quoted, *rtype;
{
return (array_value_internal (s, quoted, 1, rtype));
}
/* Return the value of the array indexing expression S as a single string.
If ALLOW_ALL is 0, do not allow `@' and `*' subscripts. This is used
by other parts of the shell such as the arithmetic expression evaluator
in expr.c. */
char *
get_array_value (s, allow_all, rtype)
char *s;
int allow_all, *rtype;
{
return (array_value_internal (s, 0, allow_all, rtype));
}
char *
array_keys (s, quoted)
char *s;
int quoted;
{
int len;
char *retval, *t, *temp;
WORD_LIST *l;
SHELL_VAR *var;
var = array_variable_part (s, &t, &len);
/* [ */
if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']')
return (char *)NULL;
if (array_p (var) == 0)
l = add_string_to_list ("0", (WORD_LIST *)NULL);
else
{
l = array_keys_to_word_list (array_cell (var));
if (l == (WORD_LIST *)NULL)
return ((char *) NULL);
}
if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
{
temp = string_list_dollar_star (l);
retval = quote_string (temp);
free (temp);
}
else /* ${!name[@]} or unquoted ${!name[*]} */
retval = string_list_dollar_at (l, quoted);
dispose_words (l);
return retval;
}
#endif /* ARRAY_VARS */
+6 -4
View File
@@ -1,5 +1,5 @@
@%:@! /bin/sh
@%:@ From configure.in for Bash 3.1, version 3.183.
@%:@ From configure.in for Bash 3.2, version 3.186.
@%:@ Guess values for system-dependent variables and create Makefiles.
@%:@ Generated by GNU Autoconf 2.59 for bash 3.2-devel.
@%:@
@@ -312,7 +312,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL HELPSTRINGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CROSS_COMPILE SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR TILDE_LIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL SIZE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIB@&t@OBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL HELPSTRINGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CROSS_COMPILE SIGNAMES_H SIGNAMES_O CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR TILDE_LIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL SIZE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIB@&t@OBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -4113,6 +4113,7 @@ fi
SIGNAMES_O=
SIGNAMES_H=lsignames.h
@@ -4121,14 +4122,12 @@ if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
SIGNAMES_H='$(srcdir)/cross-build/win32sig.h'
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
i[3456]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
SIGNAMES_H='${srcdir}/cross-build/beos-sig.h'
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
@@ -4138,11 +4137,13 @@ if test "x$cross_compiling" = "xyes"; then
. ${cross_cache}
fi
unset cross_cache
SIGNAMES_O='signames.o'
CROSS_COMPILE='-DCROSS_COMPILING'
fi
if test -z "$CC_FOR_BUILD"; then
if test "x$cross_compiling" = "xno"; then
CC_FOR_BUILD='$(CC)'
@@ -27626,6 +27627,7 @@ s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@CROSS_COMPILE@,$CROSS_COMPILE,;t t
s,@SIGNAMES_H@,$SIGNAMES_H,;t t
s,@SIGNAMES_O@,$SIGNAMES_O,;t t
s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t
s,@STATIC_LD@,$STATIC_LD,;t t
s,@CFLAGS_FOR_BUILD@,$CFLAGS_FOR_BUILD,;t t
+866 -865
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -270,6 +270,9 @@ load_history ()
Note that the history file is automatically truncated to the
size of HISTSIZE if the user does not explicitly set the size
differently. */
set_if_not ("HISTSIZE", "500");
sv_histsize ("HISTSIZE");
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
sv_histsize ("HISTFILESIZE");
+820
View File
@@ -0,0 +1,820 @@
/* bashhist.c -- bash interface to the GNU history library. */
/* Copyright (C) 1993-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 (HISTORY)
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "bashtypes.h"
#include <stdio.h>
#include <errno.h>
#include "bashansi.h"
#include "posixstat.h"
#include "filecntl.h"
#include "bashintl.h"
#include "shell.h"
#include "flags.h"
#include "input.h"
#include "parser.h" /* for the struct dstack stuff. */
#include "pathexp.h" /* for the struct ignorevar stuff */
#include "bashhist.h" /* matching prototypes and declarations */
#include "builtins/common.h"
#include <readline/history.h>
#include <glob/glob.h>
#include <glob/strmatch.h>
#if defined (READLINE)
# include "bashline.h"
extern int rl_done, rl_dispatching; /* should really include readline.h */
#endif
#if !defined (errno)
extern int errno;
#endif
static int histignore_item_func __P((struct ign *));
static int check_history_control __P((char *));
static void hc_erasedups __P((char *));
static void really_add_history __P((char *));
static struct ignorevar histignore =
{
"HISTIGNORE",
(struct ign *)0,
0,
(char *)0,
(sh_iv_item_func_t *)histignore_item_func,
};
#define HIGN_EXPAND 0x01
/* Declarations of bash history variables. */
/* Non-zero means to remember lines typed to the shell on the history
list. This is different than the user-controlled behaviour; this
becomes zero when we read lines from a file, for example. */
int remember_on_history = 1;
/* The number of lines that Bash has added to this history session. The
difference between the number of the top element in the history list
(offset from history_base) and the number of lines in the history file.
Appending this session's history to the history file resets this to 0. */
int history_lines_this_session;
/* The number of lines that Bash has read from the history file. */
int history_lines_in_file;
#if defined (BANG_HISTORY)
/* Non-zero means do no history expansion on this line, regardless
of what history_expansion says. */
int history_expansion_inhibited;
#endif
/* With the old default, every line was saved in the history individually.
I.e., if the user enters:
bash$ for i in a b c
> do
> echo $i
> done
Each line will be individually saved in the history.
bash$ history
10 for i in a b c
11 do
12 echo $i
13 done
14 history
If the variable command_oriented_history is set, multiple lines
which form one command will be saved as one history entry.
bash$ for i in a b c
> do
> echo $i
> done
bash$ history
10 for i in a b c
do
echo $i
done
11 history
The user can then recall the whole command all at once instead
of just being able to recall one line at a time.
This is now enabled by default.
*/
int command_oriented_history = 1;
/* Set to 1 if the first line of a possibly-multi-line command was saved
in the history list. Managed by maybe_add_history(), but global so
the history-manipluating builtins can see it. */
int current_command_first_line_saved = 0;
/* Non-zero means to store newlines in the history list when using
command_oriented_history rather than trying to use semicolons. */
int literal_history;
/* Non-zero means to append the history to the history file at shell
exit, even if the history has been stifled. */
int force_append_history;
/* A nit for picking at history saving. Flags have the following values:
Value == 0 means save all lines parsed by the shell on the history.
Value & HC_IGNSPACE means save all lines that do not start with a space.
Value & HC_IGNDUPS means save all lines that do not match the last
line saved.
Value & HC_ERASEDUPS means to remove all other matching lines from the
history list before saving the latest line. */
int history_control;
/* Set to 1 if the last command was added to the history list successfully
as a separate history entry; set to 0 if the line was ignored or added
to a previous entry as part of command-oriented-history processing. */
int hist_last_line_added;
/* Set to 1 if builtins/history.def:push_history added the last history
entry. */
int hist_last_line_pushed;
#if defined (READLINE)
/* If non-zero, and readline is being used, the user is offered the
chance to re-edit a failed history expansion. */
int history_reediting;
/* If non-zero, and readline is being used, don't directly execute a
line with history substitution. Reload it into the editing buffer
instead and let the user further edit and confirm with a newline. */
int hist_verify;
#endif /* READLINE */
/* Non-zero means to not save function definitions in the history list. */
int dont_save_function_defs;
/* Variables declared in other files used here. */
extern int current_command_line_count;
extern struct dstack dstack;
static int bash_history_inhibit_expansion __P((char *, int));
#if defined (READLINE)
static void re_edit __P((char *));
#endif
static int history_expansion_p __P((char *));
static int shell_comment __P((char *));
static int should_expand __P((char *));
static HIST_ENTRY *last_history_entry __P((void));
static char *expand_histignore_pattern __P((char *));
static int history_should_ignore __P((char *));
/* Is the history expansion starting at string[i] one that should not
be expanded? */
static int
bash_history_inhibit_expansion (string, i)
char *string;
int i;
{
/* The shell uses ! as a pattern negation character in globbing [...]
expressions, so let those pass without expansion. */
if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
return (1);
/* The shell uses ! as the indirect expansion character, so let those
expansions pass as well. */
else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
member ('}', string + i + 1))
return (1);
#if defined (EXTENDED_GLOB)
else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
return (1);
#endif
else
return (0);
}
void
bash_initialize_history ()
{
history_quotes_inhibit_expansion = 1;
history_search_delimiter_chars = ";&()|<>";
history_inhibit_expansion_function = bash_history_inhibit_expansion;
#if defined (BANG_HISTORY)
sv_histchars ("histchars");
#endif
}
void
bash_history_reinit (interact)
int interact;
{
#if defined (BANG_HISTORY)
history_expansion = interact != 0;
history_expansion_inhibited = 1;
#endif
remember_on_history = interact != 0;
history_inhibit_expansion_function = bash_history_inhibit_expansion;
}
void
bash_history_disable ()
{
remember_on_history = 0;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 1;
#endif
}
void
bash_history_enable ()
{
remember_on_history = 1;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 0;
#endif
history_inhibit_expansion_function = bash_history_inhibit_expansion;
sv_history_control ("HISTCONTROL");
sv_histignore ("HISTIGNORE");
}
/* Load the history list from the history file. */
void
load_history ()
{
char *hf;
struct stat buf;
/* Truncate history file for interactive shells which desire it.
Note that the history file is automatically truncated to the
size of HISTSIZE if the user does not explicitly set the size
differently. */
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
sv_histsize ("HISTFILESIZE");
/* Read the history in HISTFILE into the history list. */
hf = get_string_value ("HISTFILE");
if (hf && *hf && stat (hf, &buf) == 0)
{
read_history (hf);
using_history ();
history_lines_in_file = where_history ();
}
}
#ifdef INCLUDE_UNUSED
/* Write the existing history out to the history file. */
void
save_history ()
{
char *hf;
struct stat buf;
hf = get_string_value ("HISTFILE");
if (hf && *hf && stat (hf, &buf) == 0)
{
/* Append only the lines that occurred this session to
the history file. */
using_history ();
if (history_lines_this_session < where_history () || force_append_history)
append_history (history_lines_this_session, hf);
else
write_history (hf);
sv_histsize ("HISTFILESIZE");
}
}
#endif
int
maybe_append_history (filename)
char *filename;
{
int fd, result;
struct stat buf;
result = EXECUTION_SUCCESS;
if (history_lines_this_session && (history_lines_this_session < where_history ()))
{
/* If the filename was supplied, then create it if necessary. */
if (stat (filename, &buf) == -1 && errno == ENOENT)
{
fd = open (filename, O_WRONLY|O_CREAT, 0600);
if (fd < 0)
{
builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
return (EXECUTION_FAILURE);
}
close (fd);
}
result = append_history (history_lines_this_session, filename);
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
}
return (result);
}
/* If this is an interactive shell, then append the lines executed
this session to the history file. */
int
maybe_save_shell_history ()
{
int result;
char *hf;
struct stat buf;
result = 0;
if (history_lines_this_session)
{
hf = get_string_value ("HISTFILE");
if (hf && *hf)
{
/* If the file doesn't exist, then create it. */
if (stat (hf, &buf) == -1)
{
int file;
file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (file != -1)
close (file);
}
/* Now actually append the lines if the history hasn't been
stifled. If the history has been stifled, rewrite the
history file. */
using_history ();
if (history_lines_this_session <= where_history () || force_append_history)
{
result = append_history (history_lines_this_session, hf);
history_lines_in_file += history_lines_this_session;
}
else
{
result = write_history (hf);
history_lines_in_file = history_lines_this_session;
}
history_lines_this_session = 0;
sv_histsize ("HISTFILESIZE");
}
}
return (result);
}
#if defined (READLINE)
/* Tell readline () that we have some text for it to edit. */
static void
re_edit (text)
char *text;
{
if (bash_input.type == st_stdin)
bash_re_edit (text);
}
#endif /* READLINE */
/* Return 1 if this line needs history expansion. */
static int
history_expansion_p (line)
char *line;
{
register char *s;
for (s = line; *s; s++)
if (*s == history_expansion_char || *s == history_subst_char)
return 1;
return 0;
}
/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
print the results of expanding the line if there were any changes.
If there is an error, return NULL, otherwise the expanded line is
returned. If ADDIT is non-zero the line is added to the history
list after history expansion. ADDIT is just a suggestion;
REMEMBER_ON_HISTORY can veto, and does.
Right now this does history expansion. */
char *
pre_process_line (line, print_changes, addit)
char *line;
int print_changes, addit;
{
char *history_value;
char *return_value;
int expanded;
return_value = line;
expanded = 0;
# if defined (BANG_HISTORY)
/* History expand the line. If this results in no errors, then
add that line to the history if ADDIT is non-zero. */
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
{
expanded = history_expand (line, &history_value);
if (expanded)
{
if (print_changes)
{
if (expanded < 0)
internal_error ("%s", history_value);
#if defined (READLINE)
else if (hist_verify == 0 || expanded == 2)
#else
else
#endif
fprintf (stderr, "%s\n", history_value);
}
/* If there was an error, return NULL. */
if (expanded < 0 || expanded == 2) /* 2 == print only */
{
# if defined (READLINE)
if (expanded == 2 && rl_dispatching == 0 && *history_value)
# else
if (expanded == 2 && *history_value)
# endif /* !READLINE */
maybe_add_history (history_value);
free (history_value);
# if defined (READLINE)
/* New hack. We can allow the user to edit the
failed history expansion. */
if (history_reediting && expanded < 0 && rl_done)
re_edit (line);
# endif /* READLINE */
return ((char *)NULL);
}
# if defined (READLINE)
if (hist_verify && expanded == 1)
{
re_edit (history_value);
return ((char *)NULL);
}
# endif
}
/* Let other expansions know that return_value can be free'ed,
and that a line has been added to the history list. Note
that we only add lines that have something in them. */
expanded = 1;
return_value = history_value;
}
# endif /* BANG_HISTORY */
if (addit && remember_on_history && *return_value)
maybe_add_history (return_value);
#if 0
if (expanded == 0)
return_value = savestring (line);
#endif
return (return_value);
}
/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
* that the line is a shell comment. */
static int
shell_comment (line)
char *line;
{
char *p;
for (p = line; p && *p && whitespace (*p); p++)
;
return (p && *p == '#');
}
#ifdef INCLUDE_UNUSED
/* Remove shell comments from LINE. A `#' and anything after it is a comment.
This isn't really useful yet, since it doesn't handle quoting. */
static char *
filter_comments (line)
char *line;
{
char *p;
for (p = line; p && *p && *p != '#'; p++)
;
if (p && *p == '#')
*p = '\0';
return (line);
}
#endif
/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
should be saved; 0 if it should be discarded. */
static int
check_history_control (line)
char *line;
{
HIST_ENTRY *temp;
int r;
if (history_control == 0)
return 1;
/* ignorespace or ignoreboth */
if ((history_control & HC_IGNSPACE) && *line == ' ')
return 0;
/* ignoredups or ignoreboth */
if (history_control & HC_IGNDUPS)
{
using_history ();
temp = previous_history ();
r = (temp == 0 || STREQ (temp->line, line) == 0);
using_history ();
if (r == 0)
return r;
}
return 1;
}
/* Remove all entries matching LINE from the history list. Triggered when
HISTCONTROL includes `erasedups'. */
static void
hc_erasedups (line)
char *line;
{
HIST_ENTRY *temp;
int r;
using_history ();
while (temp = previous_history ())
{
if (STREQ (temp->line, line))
{
r = where_history ();
remove_history (r);
}
}
using_history ();
}
/* Add LINE to the history list, handling possibly multi-line compound
commands. We note whether or not we save the first line of each command
(which is usually the entire command and history entry), and don't add
the second and subsequent lines of a multi-line compound command if we
didn't save the first line. We don't usually save shell comment lines in
compound commands in the history, because they could have the effect of
commenting out the rest of the command when the entire command is saved as
a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
LITERAL_HISTORY is set, we're saving lines in the history with embedded
newlines, so it's OK to save comment lines. We also make sure to save
multiple-line quoted strings or other constructs. */
void
maybe_add_history (line)
char *line;
{
hist_last_line_added = 0;
/* Don't use the value of history_control to affect the second
and subsequent lines of a multi-line command (old code did
this only when command_oriented_history is enabled). */
if (current_command_line_count > 1)
{
if (current_command_first_line_saved &&
(literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
bash_add_history (line);
return;
}
/* This is the first line of a (possible multi-line) command. Note whether
or not we should save the first line and remember it. */
current_command_first_line_saved = check_add_history (line, 0);
}
/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
history if it's OK. Used by `history -s' as well as maybe_add_history().
Returns 1 if the line was saved in the history, 0 otherwise. */
int
check_add_history (line, force)
char *line;
int force;
{
if (check_history_control (line) && history_should_ignore (line) == 0)
{
/* We're committed to saving the line. If the user has requested it,
remove other matching lines from the history. */
if (history_control & HC_ERASEDUPS)
hc_erasedups (line);
if (force)
{
really_add_history (line);
using_history ();
}
else
bash_add_history (line);
return 1;
}
return 0;
}
/* Add a line to the history list.
The variable COMMAND_ORIENTED_HISTORY controls the style of history
remembering; when non-zero, and LINE is not the first line of a
complete parser construct, append LINE to the last history line instead
of adding it as a new line. */
void
bash_add_history (line)
char *line;
{
int add_it, offset, curlen;
HIST_ENTRY *current, *old;
char *chars_to_add, *new_line;
add_it = 1;
if (command_oriented_history && current_command_line_count > 1)
{
chars_to_add = literal_history ? "\n" : history_delimiting_chars ();
using_history ();
current = previous_history ();
if (current)
{
/* If the previous line ended with an escaped newline (escaped
with backslash, but otherwise unquoted), then remove the quoted
newline, since that is what happens when the line is parsed. */
curlen = strlen (current->line);
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
current->line[curlen - 2] != '\\')
{
current->line[curlen - 1] = '\0';
curlen--;
chars_to_add = "";
}
new_line = (char *)xmalloc (1
+ curlen
+ strlen (line)
+ strlen (chars_to_add));
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
offset = where_history ();
old = replace_history_entry (offset, new_line, current->data);
free (new_line);
if (old)
free_history_entry (old);
add_it = 0;
}
}
if (add_it)
really_add_history (line);
using_history ();
}
static void
really_add_history (line)
char *line;
{
hist_last_line_added = 1;
hist_last_line_pushed = 0;
add_history (line);
history_lines_this_session++;
}
int
history_number ()
{
using_history ();
return (remember_on_history ? history_base + where_history () : 1);
}
static int
should_expand (s)
char *s;
{
char *p;
for (p = s; p && *p; p++)
{
if (*p == '\\')
p++;
else if (*p == '&')
return 1;
}
return 0;
}
static int
histignore_item_func (ign)
struct ign *ign;
{
if (should_expand (ign->val))
ign->flags |= HIGN_EXPAND;
return (0);
}
void
setup_history_ignore (varname)
char *varname;
{
setup_ignore_patterns (&histignore);
}
static HIST_ENTRY *
last_history_entry ()
{
HIST_ENTRY *he;
using_history ();
he = previous_history ();
using_history ();
return he;
}
char *
last_history_line ()
{
HIST_ENTRY *he;
he = last_history_entry ();
if (he == 0)
return ((char *)NULL);
return he->line;
}
static char *
expand_histignore_pattern (pat)
char *pat;
{
HIST_ENTRY *phe;
char *ret;
phe = last_history_entry ();
if (phe == (HIST_ENTRY *)0)
return (savestring (pat));
ret = strcreplace (pat, '&', phe->line, 1);
return ret;
}
/* Return 1 if we should not put LINE into the history according to the
patterns in HISTIGNORE. */
static int
history_should_ignore (line)
char *line;
{
register int i, match;
char *npat;
if (histignore.num_ignores == 0)
return 0;
for (i = match = 0; i < histignore.num_ignores; i++)
{
if (histignore.ignores[i].flags & HIGN_EXPAND)
npat = expand_histignore_pattern (histignore.ignores[i].val);
else
npat = histignore.ignores[i].val;
match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
if (histignore.ignores[i].flags & HIGN_EXPAND)
free (npat);
if (match)
break;
}
return match;
}
#endif /* HISTORY */
+12 -2
View File
@@ -1,7 +1,7 @@
/* mkbuiltins.c - Create builtins.c, builtext.h, and builtdoc.c from
a single source file called builtins.def. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -19,7 +19,17 @@ 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 (CROSS_COMPILING) */
#if 0
# include <config.h>
#else /* CROSS_COMPILING */
/* A conservative set of defines based on POSIX/SUS3/XPG6 */
# define HAVE_UNISTD_H
# define HAVE_STRING_H
# define HAVE_STDLIB_H
# define HAVE_RENAME
#endif /* CROSS_COMPILING */
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
File diff suppressed because it is too large Load Diff
+15 -1
View File
@@ -90,6 +90,7 @@ extern int errno;
extern int interrupt_immediately;
#if defined (READLINE)
static void reset_attempted_completion_function __P((char *));
static char *edit_line __P((char *));
static void set_eol_delim __P((int));
static void reset_eol_delim __P((char *));
@@ -330,6 +331,8 @@ read_builtin (list)
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
if (edit)
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
alarm (tmout);
}
@@ -692,7 +695,15 @@ bind_read_variable (name, value)
}
#if defined (READLINE)
static rl_completion_func_t *old_attempted_completion_function;
static rl_completion_func_t *old_attempted_completion_function = 0;
static void
reset_attempted_completion_function (cp)
char *cp;
{
if (rl_attempted_completion_function == 0 && old_attempted_completion_function)
rl_attempted_completion_function = old_attempted_completion_function;
}
static char *
edit_line (p)
@@ -703,10 +714,13 @@ edit_line (p)
if (bash_readline_initialized == 0)
initialize_readline ();
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;
if (ret == 0)
return ret;
len = strlen (ret);
+20 -2
View File
@@ -90,6 +90,7 @@ extern int errno;
extern int interrupt_immediately;
#if defined (READLINE)
static void reset_attempted_completion_function __P((char *));
static char *edit_line __P((char *));
static void set_eol_delim __P((int));
static void reset_eol_delim __P((char *));
@@ -330,6 +331,8 @@ read_builtin (list)
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
if (edit)
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
alarm (tmout);
}
@@ -472,6 +475,7 @@ add_char:
if (retval < 0)
{
builtin_error (_("read error: %d: %s"), fd, strerror (errno));
run_unwind_frame ("read_builtin");
return (EXECUTION_FAILURE);
}
#endif
@@ -519,7 +523,10 @@ add_char:
var = find_or_make_array_variable (arrayname, 1);
if (var == 0)
return EXECUTION_FAILURE; /* readonly or noassign */
{
xfree (input_string);
return EXECUTION_FAILURE; /* readonly or noassign */
}
array_flush (array_cell (var));
alist = list_string (input_string, ifs_chars, 0);
@@ -688,7 +695,17 @@ bind_read_variable (name, value)
}
#if defined (READLINE)
static rl_completion_func_t *old_attempted_completion_function;
static rl_completion_func_t *old_attempted_completion_function = 0;
static void
reset_attempted_completion_function (cp)
char *cp;
{
if (rl_attempted_completion_function == 0)
rl_attempted_completion_function = old_attempted_completion_function ?
old_attempted_completion_function :
attempt_shell_completion;
}
static char *
edit_line (p)
@@ -703,6 +720,7 @@ edit_line (p)
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = 0;
if (ret == 0)
return ret;
len = strlen (ret);
+8
View File
@@ -34,6 +34,7 @@ option is given, it is interpreted as follows:
-a all current limits are reported
-c the maximum size of core files created
-d the maximum size of a process's data segment
-e the maximum scheduling priority (`nice')
-f the maximum size of files created by the shell
-i the maximum number of pending signals
-l the maximum size a process may lock into memory
@@ -41,6 +42,7 @@ option is given, it is interpreted as follows:
-n the maximum number of open file descriptors
-p the pipe buffer size
-q the maximum number of bytes in POSIX message queues
-r the maximum real-time scheduling priority
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-u the maximum number of user processes
@@ -201,6 +203,9 @@ static RESOURCE_LIMITS limits[] = {
#endif
#ifdef RLIMIT_DATA
{ 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
#endif
#ifdef RLIMIT_NICE
{ 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
#endif
{ 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
#ifdef RLIMIT_SIGPENDING
@@ -217,6 +222,9 @@ static RESOURCE_LIMITS limits[] = {
#ifdef RLIMIT_MSGQUEUE
{ 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
#endif
#ifdef RLIMIT_RTPRIO
{ 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
#endif
#ifdef RLIMIT_STACK
{ 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
#endif
+11 -3
View File
@@ -34,18 +34,20 @@ option is given, it is interpreted as follows:
-a all current limits are reported
-c the maximum size of core files created
-d the maximum size of a process's data segment
-e the maximum scheduling priority (`nice')
-f the maximum size of files created by the shell
-i the maximum number of pending signals
-i the maximum number of pending signals
-l the maximum size a process may lock into memory
-m the maximum resident set size
-n the maximum number of open file descriptors
-p the pipe buffer size
-q the maximum number of bytes in POSIX message queues
-q the maximum number of bytes in POSIX message queues
-r the maximum real-time scheduling priority
-s the maximum stack size
-t the maximum amount of cpu time in seconds
-u the maximum number of user processes
-v the size of virtual memory
-x the maximum number of file locks
-x the maximum number of file locks
If LIMIT is given, it is the new value of the specified resource;
the special LIMIT values `soft', `hard', and `unlimited' stand for
@@ -201,6 +203,9 @@ static RESOURCE_LIMITS limits[] = {
#endif
#ifdef RLIMIT_DATA
{ 'd', RLIMIT_DATA, 1024, "data seg size", "kbytes" },
#endif
#ifdef RLIMIT_NICE
{ 'e', RLIMIT_NICE, 1, "scheduling priority", (char *)NULL },
#endif
{ 'f', RLIMIT_FILESIZE, 1024, "file size", "blocks" },
#ifdef RLIMIT_SIGPENDING
@@ -217,6 +222,9 @@ static RESOURCE_LIMITS limits[] = {
#ifdef RLIMIT_MSGQUEUE
{ 'q', RLIMIT_MSGQUEUE, 1, "POSIX message queues", "bytes" },
#endif
#ifdef RLIMIT_RTPRIO
{ 'r', RLIMIT_RTPRIO, 1, "real-time priority", (char *)NULL },
#endif
#ifdef RLIMIT_STACK
{ 's', RLIMIT_STACK, 1024, "stack size", "kbytes" },
#endif
+21 -20
View File
@@ -67,26 +67,27 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
cm_arith, cm_cond, cm_arith_for, cm_subshell };
/* Possible values for the `flags' field of a WORD_DESC. */
#define W_HASDOLLAR 0x00001 /* Dollar sign present. */
#define W_QUOTED 0x00002 /* Some form of quote character is present. */
#define W_ASSIGNMENT 0x00004 /* This word is a variable assignment. */
#define W_GLOBEXP 0x00008 /* This word is the result of a glob expansion. */
#define W_NOSPLIT 0x00010 /* Do not perform word splitting on this word. */
#define W_NOGLOB 0x00020 /* Do not perform globbing on this word. */
#define W_NOSPLIT2 0x00040 /* Don't split word except for $@ expansion. */
#define W_TILDEEXP 0x00080 /* Tilde expand this assignment word */
#define W_DOLLARAT 0x00100 /* $@ and its special handling */
#define W_DOLLARSTAR 0x00200 /* $* and its special handling */
#define W_NOCOMSUB 0x00400 /* Don't perform command substitution on this word */
#define W_ASSIGNRHS 0x00800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x01000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x02000 /* Internal flag for word expansion */
#define W_NOEXPAND 0x04000 /* Don't expand at all -- do quote removal */
#define W_COMPASSIGN 0x08000 /* Compound assignment */
#define W_ASSNBLTIN 0x10000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x20000 /* word is assignment argument to command */
#define W_HASQUOTEDNULL 0x40000 /* word contains a quoted null character */
#define W_DQUOTE 0x80000 /* word should be treated as if double-quoted */
#define W_HASDOLLAR 0x000001 /* Dollar sign present. */
#define W_QUOTED 0x000002 /* Some form of quote character is present. */
#define W_ASSIGNMENT 0x000004 /* This word is a variable assignment. */
#define W_GLOBEXP 0x000008 /* This word is the result of a glob expansion. */
#define W_NOSPLIT 0x000010 /* Do not perform word splitting on this word. */
#define W_NOGLOB 0x000020 /* Do not perform globbing on this word. */
#define W_NOSPLIT2 0x000040 /* Don't split word except for $@ expansion. */
#define W_TILDEEXP 0x000080 /* Tilde expand this assignment word */
#define W_DOLLARAT 0x000100 /* $@ and its special handling */
#define W_DOLLARSTAR 0x000200 /* $* and its special handling */
#define W_NOCOMSUB 0x000400 /* Don't perform command substitution on this word */
#define W_ASSIGNRHS 0x000800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x001000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x002000 /* Internal flag for word expansion */
#define W_NOEXPAND 0x004000 /* Don't expand at all -- do quote removal */
#define W_COMPASSIGN 0x008000 /* Compound assignment */
#define W_ASSNBLTIN 0x010000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x020000 /* word is assignment argument to command */
#define W_HASQUOTEDNULL 0x040000 /* word contains a quoted null character */
#define W_DQUOTE 0x080000 /* word should be treated as if double-quoted */
#define W_NOPROCSUB 0x100000 /* don't perform process substitution */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
+345
View File
@@ -0,0 +1,345 @@
/* command.h -- The structures used internally to represent commands, and
the extern declarations of the functions used to create them. */
/* Copyright (C) 1993-2005 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. */
#if !defined (_COMMAND_H_)
#define _COMMAND_H_
#include "stdc.h"
/* Instructions describing what kind of thing to do for a redirection. */
enum r_instruction {
r_output_direction, r_input_direction, r_inputa_direction,
r_appending_to, r_reading_until, r_reading_string,
r_duplicating_input, r_duplicating_output, r_deblank_reading_until,
r_close_this, r_err_and_out, r_input_output, r_output_force,
r_duplicating_input_word, r_duplicating_output_word,
r_move_input, r_move_output, r_move_input_word, r_move_output_word
};
/* Redirection errors. */
#define AMBIGUOUS_REDIRECT -1
#define NOCLOBBER_REDIRECT -2
#define RESTRICTED_REDIRECT -3 /* can only happen in restricted shells. */
#define HEREDOC_REDIRECT -4 /* here-doc temp file can't be created */
#define CLOBBERING_REDIRECT(ri) \
(ri == r_output_direction || ri == r_err_and_out)
#define OUTPUT_REDIRECT(ri) \
(ri == r_output_direction || ri == r_input_output || ri == r_err_and_out)
#define INPUT_REDIRECT(ri) \
(ri == r_input_direction || ri == r_inputa_direction || ri == r_input_output)
#define WRITE_REDIRECT(ri) \
(ri == r_output_direction || \
ri == r_input_output || \
ri == r_err_and_out || \
ri == r_appending_to || \
ri == r_output_force)
/* redirection needs translation */
#define TRANSLATE_REDIRECT(ri) \
(ri == r_duplicating_input_word || ri == r_duplicating_output_word || \
ri == r_move_input_word || ri == r_move_output_word)
/* Command Types: */
enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
cm_connection, cm_function_def, cm_until, cm_group,
cm_arith, cm_cond, cm_arith_for, cm_subshell };
/* Possible values for the `flags' field of a WORD_DESC. */
#define W_HASDOLLAR 0x00001 /* Dollar sign present. */
#define W_QUOTED 0x00002 /* Some form of quote character is present. */
#define W_ASSIGNMENT 0x00004 /* This word is a variable assignment. */
#define W_GLOBEXP 0x00008 /* This word is the result of a glob expansion. */
#define W_NOSPLIT 0x00010 /* Do not perform word splitting on this word. */
#define W_NOGLOB 0x00020 /* Do not perform globbing on this word. */
#define W_NOSPLIT2 0x00040 /* Don't split word except for $@ expansion. */
#define W_TILDEEXP 0x00080 /* Tilde expand this assignment word */
#define W_DOLLARAT 0x00100 /* $@ and its special handling */
#define W_DOLLARSTAR 0x00200 /* $* and its special handling */
#define W_NOCOMSUB 0x00400 /* Don't perform command substitution on this word */
#define W_ASSIGNRHS 0x00800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x01000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x02000 /* Internal flag for word expansion */
#define W_NOEXPAND 0x04000 /* Don't expand at all -- do quote removal */
#define W_COMPASSIGN 0x08000 /* Compound assignment */
#define W_ASSNBLTIN 0x10000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x20000 /* word is assignment argument to command */
#define W_HASQUOTEDNULL 0x40000 /* word contains a quoted null character */
#define W_DQUOTE 0x80000 /* word should be treated as if double-quoted */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
#define SUBSHELL_PAREN 0x02 /* subshell caused by ( ... ) */
#define SUBSHELL_COMSUB 0x04 /* subshell caused by `command` or $(command) */
#define SUBSHELL_FORK 0x08 /* subshell caused by executing a disk command */
#define SUBSHELL_PIPE 0x10 /* subshell from a pipeline element */
/* A structure which represents a word. */
typedef struct word_desc {
char *word; /* Zero terminated string. */
int flags; /* Flags associated with this word. */
} WORD_DESC;
/* A linked list of words. */
typedef struct word_list {
struct word_list *next;
WORD_DESC *word;
} WORD_LIST;
/* **************************************************************** */
/* */
/* Shell Command Structs */
/* */
/* **************************************************************** */
/* What a redirection descriptor looks like. If the redirection instruction
is ri_duplicating_input or ri_duplicating_output, use DEST, otherwise
use the file in FILENAME. Out-of-range descriptors are identified by a
negative DEST. */
typedef union {
int dest; /* Place to redirect REDIRECTOR to, or ... */
WORD_DESC *filename; /* filename to redirect to. */
} REDIRECTEE;
/* Structure describing a redirection. If REDIRECTOR is negative, the parser
(or translator in redir.c) encountered an out-of-range file descriptor. */
typedef struct redirect {
struct redirect *next; /* Next element, or NULL. */
int redirector; /* Descriptor to be redirected. */
int flags; /* Flag value for `open'. */
enum r_instruction instruction; /* What to do with the information. */
REDIRECTEE redirectee; /* File descriptor or filename */
char *here_doc_eof; /* The word that appeared in <<foo. */
} REDIRECT;
/* An element used in parsing. A single word or a single redirection.
This is an ephemeral construct. */
typedef struct element {
WORD_DESC *word;
REDIRECT *redirect;
} ELEMENT;
/* Possible values for command->flags. */
#define CMD_WANT_SUBSHELL 0x01 /* User wants a subshell: ( command ) */
#define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */
#define CMD_INVERT_RETURN 0x04 /* Invert the exit value. */
#define CMD_IGNORE_RETURN 0x08 /* Ignore the exit value. For set -e. */
#define CMD_NO_FUNCTIONS 0x10 /* Ignore functions during command lookup. */
#define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
#define CMD_NO_FORK 0x40 /* Don't fork; just call execve */
#define CMD_TIME_PIPELINE 0x80 /* Time a pipeline */
#define CMD_TIME_POSIX 0x100 /* time -p; use POSIX.2 time output spec. */
#define CMD_AMPERSAND 0x200 /* command & */
#define CMD_STDIN_REDIR 0x400 /* async command needs implicit </dev/null */
#define CMD_COMMAND_BUILTIN 0x0800 /* command executed by `command' builtin */
/* What a command looks like. */
typedef struct command {
enum command_type type; /* FOR CASE WHILE IF CONNECTION or SIMPLE. */
int flags; /* Flags controlling execution environment. */
int line; /* line number the command starts on */
REDIRECT *redirects; /* Special redirects for FOR CASE, etc. */
union {
struct for_com *For;
struct case_com *Case;
struct while_com *While;
struct if_com *If;
struct connection *Connection;
struct simple_com *Simple;
struct function_def *Function_def;
struct group_com *Group;
#if defined (SELECT_COMMAND)
struct select_com *Select;
#endif
#if defined (DPAREN_ARITHMETIC)
struct arith_com *Arith;
#endif
#if defined (COND_COMMAND)
struct cond_com *Cond;
#endif
#if defined (ARITH_FOR_COMMAND)
struct arith_for_com *ArithFor;
#endif
struct subshell_com *Subshell;
} value;
} COMMAND;
/* Structure used to represent the CONNECTION type. */
typedef struct connection {
int ignore; /* Unused; simplifies make_command (). */
COMMAND *first; /* Pointer to the first command. */
COMMAND *second; /* Pointer to the second command. */
int connector; /* What separates this command from others. */
} CONNECTION;
/* Structures used to represent the CASE command. */
/* Pattern/action structure for CASE_COM. */
typedef struct pattern_list {
struct pattern_list *next; /* Clause to try in case this one failed. */
WORD_LIST *patterns; /* Linked list of patterns to test. */
COMMAND *action; /* Thing to execute if a pattern matches. */
int flags;
} PATTERN_LIST;
/* The CASE command. */
typedef struct case_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `case' keyword appears on */
WORD_DESC *word; /* The thing to test. */
PATTERN_LIST *clauses; /* The clauses to test against, or NULL. */
} CASE_COM;
/* FOR command. */
typedef struct for_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `for' keyword appears on */
WORD_DESC *name; /* The variable name to get mapped over. */
WORD_LIST *map_list; /* The things to map over. This is never NULL. */
COMMAND *action; /* The action to execute.
During execution, NAME is bound to successive
members of MAP_LIST. */
} FOR_COM;
#if defined (ARITH_FOR_COMMAND)
typedef struct arith_for_com {
int flags;
int line; /* generally used for error messages */
WORD_LIST *init;
WORD_LIST *test;
WORD_LIST *step;
COMMAND *action;
} ARITH_FOR_COM;
#endif
#if defined (SELECT_COMMAND)
/* KSH SELECT command. */
typedef struct select_com {
int flags; /* See description of CMD flags. */
int line; /* line number the `select' keyword appears on */
WORD_DESC *name; /* The variable name to get mapped over. */
WORD_LIST *map_list; /* The things to map over. This is never NULL. */
COMMAND *action; /* The action to execute.
During execution, NAME is bound to the member of
MAP_LIST chosen by the user. */
} SELECT_COM;
#endif /* SELECT_COMMAND */
/* IF command. */
typedef struct if_com {
int flags; /* See description of CMD flags. */
COMMAND *test; /* Thing to test. */
COMMAND *true_case; /* What to do if the test returned non-zero. */
COMMAND *false_case; /* What to do if the test returned zero. */
} IF_COM;
/* WHILE command. */
typedef struct while_com {
int flags; /* See description of CMD flags. */
COMMAND *test; /* Thing to test. */
COMMAND *action; /* Thing to do while test is non-zero. */
} WHILE_COM;
#if defined (DPAREN_ARITHMETIC)
/* The arithmetic evaluation command, ((...)). Just a set of flags and
a WORD_LIST, of which the first element is the only one used, for the
time being. */
typedef struct arith_com {
int flags;
int line;
WORD_LIST *exp;
} ARITH_COM;
#endif /* DPAREN_ARITHMETIC */
/* The conditional command, [[...]]. This is a binary tree -- we slippped
a recursive-descent parser into the YACC grammar to parse it. */
#define COND_AND 1
#define COND_OR 2
#define COND_UNARY 3
#define COND_BINARY 4
#define COND_TERM 5
#define COND_EXPR 6
typedef struct cond_com {
int flags;
int line;
int type;
WORD_DESC *op;
struct cond_com *left, *right;
} COND_COM;
/* The "simple" command. Just a collection of words and redirects. */
typedef struct simple_com {
int flags; /* See description of CMD flags. */
int line; /* line number the command starts on */
WORD_LIST *words; /* The program name, the arguments,
variable assignments, etc. */
REDIRECT *redirects; /* Redirections to perform. */
} SIMPLE_COM;
/* The "function definition" command. */
typedef struct function_def {
int flags; /* See description of CMD flags. */
int line; /* Line number the function def starts on. */
WORD_DESC *name; /* The name of the function. */
COMMAND *command; /* The parsed execution tree. */
char *source_file; /* file in which function was defined, if any */
} FUNCTION_DEF;
/* A command that is `grouped' allows pipes and redirections to affect all
commands in the group. */
typedef struct group_com {
int ignore; /* See description of CMD flags. */
COMMAND *command;
} GROUP_COM;
typedef struct subshell_com {
int flags;
COMMAND *command;
} SUBSHELL_COM;
extern COMMAND *global_command;
/* Possible command errors */
#define CMDERR_DEFAULT 0
#define CMDERR_BADTYPE 1
#define CMDERR_BADCONN 2
#define CMDERR_BADJUMP 3
#define CMDERR_LAST 3
/* Forward declarations of functions declared in copy_cmd.c. */
extern FUNCTION_DEF *copy_function_def_contents __P((FUNCTION_DEF *, FUNCTION_DEF *));
extern FUNCTION_DEF *copy_function_def __P((FUNCTION_DEF *));
extern WORD_DESC *copy_word __P((WORD_DESC *));
extern WORD_LIST *copy_word_list __P((WORD_LIST *));
extern REDIRECT *copy_redirect __P((REDIRECT *));
extern REDIRECT *copy_redirects __P((REDIRECT *));
extern COMMAND *copy_command __P((COMMAND *));
#endif /* _COMMAND_H_ */
Vendored
+6 -4
View File
@@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in for Bash 3.1, version 3.183.
# From configure.in for Bash 3.2, version 3.186.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59 for bash 3.2-devel.
#
@@ -312,7 +312,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL HELPSTRINGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CROSS_COMPILE SIGNAMES_H CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR TILDE_LIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL SIZE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os EMACS lispdir DEBUGGER_START_FILE TESTSCRIPT PURIFY MALLOC_TARGET MALLOC_SRC MALLOC_LIB MALLOC_LIBRARY MALLOC_LDFLAGS MALLOC_DEP htmldir HELPDIR HELPDIRDEFINE HELPINSTALL HELPSTRINGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP CROSS_COMPILE SIGNAMES_H SIGNAMES_O CC_FOR_BUILD STATIC_LD CFLAGS_FOR_BUILD CPPFLAGS_FOR_BUILD LDFLAGS_FOR_BUILD RL_VERSION RL_MAJOR RL_MINOR READLINE_LIB READLINE_DEP RL_LIBDIR RL_INCLUDEDIR RL_INCLUDE HISTORY_LIB HISTORY_DEP HIST_LIBDIR TILDE_LIB INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA AR RANLIB ac_ct_RANLIB YACC SET_MAKE MAKE_SHELL SIZE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE ALLOCA GLIBC21 LIBICONV LTLIBICONV INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX INTLLIBS LIBINTL LTLIBINTL POSUB LIBOBJS INTL_DEP INTL_INC LIBINTL_H SIGLIST_O TERMCAP_LIB TERMCAP_DEP JOBS_O SHOBJ_CC SHOBJ_CFLAGS SHOBJ_LD SHOBJ_LDFLAGS SHOBJ_XLDFLAGS SHOBJ_LIBS SHOBJ_STATUS PROFILE_FLAGS incdir BUILD_DIR ARFLAGS BASHVERS RELSTATUS DEBUG MALLOC_DEBUG LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -4113,6 +4113,7 @@ fi
SIGNAMES_O=
SIGNAMES_H=lsignames.h
@@ -4121,14 +4122,12 @@ if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
SIGNAMES_H='$(srcdir)/cross-build/win32sig.h'
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
i[3456]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
SIGNAMES_H='${srcdir}/cross-build/beos-sig.h'
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
@@ -4138,11 +4137,13 @@ if test "x$cross_compiling" = "xyes"; then
. ${cross_cache}
fi
unset cross_cache
SIGNAMES_O='signames.o'
CROSS_COMPILE='-DCROSS_COMPILING'
fi
if test -z "$CC_FOR_BUILD"; then
if test "x$cross_compiling" = "xno"; then
CC_FOR_BUILD='$(CC)'
@@ -27626,6 +27627,7 @@ s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@CROSS_COMPILE@,$CROSS_COMPILE,;t t
s,@SIGNAMES_H@,$SIGNAMES_H,;t t
s,@SIGNAMES_O@,$SIGNAMES_O,;t t
s,@CC_FOR_BUILD@,$CC_FOR_BUILD,;t t
s,@STATIC_LD@,$STATIC_LD,;t t
s,@CFLAGS_FOR_BUILD@,$CFLAGS_FOR_BUILD,;t t
+5 -4
View File
@@ -1,5 +1,5 @@
dnl
dnl Configure script for bash-3.1
dnl Configure script for bash-3.2
dnl
dnl report bugs to chet@po.cwru.edu
dnl
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script.
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_REVISION([for Bash 3.1, version 3.183])dnl
AC_REVISION([for Bash 3.2, version 3.186])dnl
define(bashvers, 3.2)
define(relstatus, devel)
@@ -373,6 +373,7 @@ AC_SYS_LARGEFILE
dnl BEGIN changes for cross-building (currently cygwin, minGW, and
dnl (obsolete) BeOS)
SIGNAMES_O=
SIGNAMES_H=lsignames.h
dnl load up the cross-building cache file -- add more cases and cache
@@ -386,14 +387,12 @@ if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
SIGNAMES_H='$(srcdir)/cross-build/win32sig.h'
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/cygwin32.cache
;;
i[[3456]]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
SIGNAMES_H='${srcdir}/cross-build/beos-sig.h'
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
@@ -403,10 +402,12 @@ if test "x$cross_compiling" = "xyes"; then
. ${cross_cache}
fi
unset cross_cache
SIGNAMES_O='signames.o'
CROSS_COMPILE='-DCROSS_COMPILING'
AC_SUBST(CROSS_COMPILE)
fi
AC_SUBST(SIGNAMES_H)
AC_SUBST(SIGNAMES_O)
if test -z "$CC_FOR_BUILD"; then
if test "x$cross_compiling" = "xno"; then
+1112
View File
File diff suppressed because it is too large Load Diff
+152
View File
@@ -0,0 +1,152 @@
*** ../bash-3.1/subst.c Mon Oct 24 09:51:13 2005
--- subst.c Fri Dec 30 12:11:53 2005
***************
*** 2188,2192 ****
{
v = find_variable (name);
! if (v == 0 || array_p (v) == 0)
v = make_local_array_variable (name);
v = assign_array_var_from_string (v, value, flags);
--- 2188,2192 ----
{
v = find_variable (name);
! if (v == 0 || array_p (v) == 0 || v->context != variable_context)
v = make_local_array_variable (name);
v = assign_array_var_from_string (v, value, flags);
***************
*** 2576,2579 ****
--- 2576,2586 ----
}
+ char *
+ expand_arith_string (string)
+ char *string;
+ {
+ return (expand_string_if_necessary (string, Q_DOUBLE_QUOTES, expand_string));
+ }
+
#if defined (COND_COMMAND)
/* Just remove backslashes in STRING. Returns a new string. */
***************
*** 5249,5253 ****
--- 5256,5264 ----
t = (char *)0;
+ #if 0
temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string);
+ #else
+ temp1 = expand_arith_string (substr);
+ #endif
*e1p = evalexp (temp1, &expok);
free (temp1);
***************
*** 5294,5298 ****
--- 5305,5313 ----
t++;
temp2 = savestring (t);
+ #if 0
temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
+ #else
+ temp1 = expand_arith_string (temp2);
+ #endif
free (temp2);
t[-1] = ':';
***************
*** 5666,5674 ****
mflags = 0;
- if (*patsub == '/')
- {
- mflags |= MATCH_GLOBREP;
- patsub++;
- }
/* Malloc this because expand_string_if_necessary or one of the expansion
--- 5681,5684 ----
***************
*** 5682,5686 ****
mflags |= MATCH_STARSUB;
! if (rep = quoted_strchr (lpatsub, '/', ST_BACKSL))
*rep++ = '\0';
else
--- 5692,5698 ----
mflags |= MATCH_STARSUB;
! /* If the pattern starts with a `/', make sure we skip over it when looking
! for the replacement delimiter. */
! if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
*rep++ = '\0';
else
***************
*** 5702,5707 ****
}
p = pat;
! if (pat && pat[0] == '#')
{
mflags |= MATCH_BEG;
--- 5714,5726 ----
}
+ /* ksh93 doesn't allow the match specifier to be a part of the expanded
+ pattern. This is an extension. */
p = pat;
! if (pat && pat[0] == '/')
! {
! mflags |= MATCH_GLOBREP|MATCH_ANY;
! p++;
! }
! else if (pat && pat[0] == '#')
{
mflags |= MATCH_BEG;
***************
*** 6436,6440 ****
--- 6455,6463 ----
/* Expand variables found inside the expression. */
+ #if 0
temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
+ #else
+ temp1 = expand_arith_string (temp2);
+ #endif
free (temp2);
***************
*** 6478,6482 ****
--- 6501,6509 ----
/* Do initial variable expansion. */
+ #if 0
temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string);
+ #else
+ temp1 = expand_arith_string (temp);
+ #endif
goto arithsub;
***************
*** 6708,6712 ****
case '>':
{
! if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & W_DQUOTE) || posixly_correct)
{
sindex--; /* add_character: label increments sindex */
--- 6735,6739 ----
case '>':
{
! if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
{
sindex--; /* add_character: label increments sindex */
***************
*** 6796,6799 ****
--- 6823,6832 ----
{
temp1 = bash_tilde_expand (temp, tflag);
+ if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
+ {
+ FREE (temp);
+ FREE (temp1);
+ goto add_character; /* tilde expansion failed */
+ }
free (temp);
temp = temp1;
+20 -11
View File
@@ -1,4 +1,4 @@
This is the Bash FAQ, version 3.32, for Bash version 3.1.
This is the Bash FAQ, version 3.33, for Bash version 3.1.
This document contains a set of frequently-asked questions concerning
Bash, the GNU Bourne-Again Shell. Bash is a freely-available command
@@ -697,7 +697,7 @@ Things bash has that sh does not:
read -e/-p/-a/-t/-n/-d/-s/-u,
readonly -a/-f/name=value, trap -l, set +o,
set -b/-m/-o option/-h/-p/-B/-C/-H/-P,
unset -f/-v, ulimit -m/-p/-u,
unset -f/-v, ulimit -i/-m/-p/-q/-u/-x,
type -a/-p/-t/-f/-P, suspend -f, kill -n,
test -o optname/s1 == s2/s1 < s2/s1 > s2/-nt/-ot/-ef/-O/-G/-S
bash reads ~/.bashrc for interactive shells, $ENV for non-interactive
@@ -793,8 +793,8 @@ Things bash has or uses that ksh88 does not:
set -o braceexpand/-o histexpand/-o interactive-comments/
-o notify/-o physical/-o posix/-o hashall/-o onecmd/
-h/-B/-C/-b/-H/-P, set +o, suspend, trap -l, type,
typeset -a/-F/-p, ulimit -u, umask -S, alias -p, shopt,
disown, printf, complete, compgen
typeset -a/-F/-p, ulimit -i/-q/-u/-x, umask -S, alias -p,
shopt, disown, printf, complete, compgen
`!' csh-style history expansion
POSIX.2-style globbing character classes
POSIX.2-style globbing equivalence classes
@@ -1575,6 +1575,9 @@ this. These variables can be set in your .inputrc or using the bash
The `set' commands between the single quotes may also be placed
in ~/.inputrc.
The script examples/scripts.noah/meta.bash encapsulates the bind
commands in a shell function.
G2) How do I write a function `x' to replace builtin command `x', but
still invoke the command from within the function?
@@ -1748,13 +1751,9 @@ ftp.cwru.edu in the `pub/bash' directory.
Cameron Newham and Bill Rosenblatt have written a book on bash, published
by O'Reilly and Associates. The book is based on Bill Rosenblatt's Korn
Shell book. The title is ``Learning the Bash Shell'', and the ISBN number
is 1-56592-147-X. Look for it in fine bookstores near you. This book
covers bash-1.14, but has an appendix describing some of the new features
in bash-2.0.
A second edition of this book is available, published in January, 1998.
The ISBN number is 1-56592-347-2. Look for it in the same fine bookstores
or on the web.
of the third edition, published in March, 2005, is 0-596-00965-8. Look for
it in fine bookstores near you. This edition of the book has been updated
to cover bash-3.0.
The GNU Bash Reference Manual has been published as a printed book by
Network Theory Ltd (Paperback, ISBN: 0-9541617-7-7, Feb 2003). It covers
@@ -1762,6 +1761,16 @@ bash-2.0 and is available from most online bookstores (see
http://www.network-theory.co.uk/bash/manual/ for details). The publisher
will donate $1 to the Free Software Foundation for each copy sold.
Arnold Robbins and Nelson Beebe have written ``Classic Shell Scripting'',
published by O'Reilly. The first edition, with ISBN number 0-596-00595-4,
was published in May, 2005.
Chris F. A. Johnson, a frequent contributor to comp.unix.shell and
gnu.bash.bug, has written ``Shell Scripting Recipes: A Problem-Solution
Approach,'' a new book on shell scripting, concentrating on features of
the POSIX standard helpful to shell script writers. The first edition from
Apress, with ISBN number 1-59059-471-1, was published in May, 2005.
H3) What's coming in future versions?
These are features I hope to include in a future version of bash.
+1803
View File
File diff suppressed because it is too large Load Diff
+19 -12
View File
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sat Aug 27 13:28:44 EDT 2005
.\" Last Change: Wed Dec 28 19:58:45 EST 2005
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2005 Dec 10" "GNU Bash-3.1"
.TH BASH 1 "2005 Dec 28" "GNU Bash-3.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -677,8 +677,8 @@ If the shell option
.B nocasematch
is enabled, the match is performed without regard to the case
of alphabetic characters.
The return value is 0 if the string matches or does not match
the pattern, respectively, and 1 otherwise.
The return value is 0 if the string matches (\fB==\fP) or does not match
(\fB!=\fP) the pattern, and 1 otherwise.
Any part of the pattern may be quoted to force it to be matched as a
string.
.if t .sp 0.5
@@ -807,6 +807,12 @@ it against each \fIpattern\fP in turn, using the same matching rules
as for pathname expansion (see
.B Pathname Expansion
below).
The \fIword\fP is expanded using tilde
expansion, parameter and variable expansion, arithmetic substituion,
command substitution, process substitution and quote removal.
Each \fIpattern\fP examined is expanded using tilde
expansion, parameter and variable expansion, arithmetic substituion,
command substitution, and process substitution.
If the shell option
.B nocasematch
is enabled, the match is performed without regard to the case
@@ -2525,17 +2531,12 @@ the pattern removal operation is applied to each member of the
array in turn, and the expansion is the resultant list.
.TP
${\fIparameter\fP\fB/\fP\fIpattern\fP\fB/\fP\fIstring\fP}
.PD 0
.TP
${\fIparameter\fP\fB//\fP\fIpattern\fP\fB/\fP\fIstring\fP}
.PD
The \fIpattern\fP is expanded to produce a pattern just as in
pathname expansion.
\fIParameter\fP is expanded and the longest match of \fIpattern\fP
against its value is replaced with \fIstring\fP.
In the first form, only the first match is replaced.
The second form causes all matches of \fIpattern\fP to be
replaced with \fIstring\fP.
If \Ipattern\fP begins with \fB/\fP, all matches of \fIpattern\fP are
replaced with \fIstring\fP. Normally only the first match is replaced.
If \fIpattern\fP begins with \fB#\fP, it must match at the beginning
of the expanded value of \fIparameter\fP.
If \fIpattern\fP begins with \fB%\fP, it must match at the end
@@ -8484,7 +8485,7 @@ option suppresses shell function lookup, as with the \fBcommand\fP builtin.
returns true if any of the arguments are found, false if
none are found.
.TP
\fBulimit\fP [\fB\-SHacdfilmnpqstuvx\fP [\fIlimit\fP]]
\fBulimit\fP [\fB\-SHacdefilmnpqrstuvx\fP [\fIlimit\fP]]
Provides control over the resources available to the shell and to
processes started by it, on systems that allow such control.
The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
@@ -8520,6 +8521,9 @@ The maximum size of core files created
.B \-d
The maximum size of a process's data segment
.TP
.B \-e
The maximum scheduling priority ("nice")
.TP
.B \-f
The maximum size of files created by the shell
.TP
@@ -8542,6 +8546,9 @@ The pipe size in 512-byte blocks (this may not be set)
.B \-q
The maximum number of bytes in POSIX message queues
.TP
.B \-r
The maximum real-time scheduling priority
.TP
.B \-s
The maximum stack size
.TP
+17 -5
View File
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Sat Aug 27 13:28:44 EDT 2005
.\" Last Change: Mon Dec 19 09:04:39 EST 2005
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2005 Aug 27" "GNU Bash-3.1"
.TH BASH 1 "2005 Dec 19" "GNU Bash-3.1"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -677,8 +677,8 @@ If the shell option
.B nocasematch
is enabled, the match is performed without regard to the case
of alphabetic characters.
The return value is 0 if the string matches or does not match
the pattern, respectively, and 1 otherwise.
The return value is 0 if the string matches (\fB==\fP) or does not match
(\fB!=\fP) the pattern, and 1 otherwise.
Any part of the pattern may be quoted to force it to be matched as a
string.
.if t .sp 0.5
@@ -807,6 +807,12 @@ it against each \fIpattern\fP in turn, using the same matching rules
as for pathname expansion (see
.B Pathname Expansion
below).
The \fIword\fP is expanded using tilde
expansion, parameter and variable expansion, arithmetic substituion,
command substitution, process substitution and quote removal.
Each \fIpattern\fP examined is expanded using tilde
expansion, parameter and variable expansion, arithmetic substituion,
command substitution, and process substitution.
If the shell option
.B nocasematch
is enabled, the match is performed without regard to the case
@@ -8484,7 +8490,7 @@ option suppresses shell function lookup, as with the \fBcommand\fP builtin.
returns true if any of the arguments are found, false if
none are found.
.TP
\fBulimit\fP [\fB\-SHacdfilmnpqstuvx\fP [\fIlimit\fP]]
\fBulimit\fP [\fB\-SHacdefilmnpqrstuvx\fP [\fIlimit\fP]]
Provides control over the resources available to the shell and to
processes started by it, on systems that allow such control.
The \fB\-H\fP and \fB\-S\fP options specify that the hard or soft limit is
@@ -8520,6 +8526,9 @@ The maximum size of core files created
.B \-d
The maximum size of a process's data segment
.TP
.B \-e
The maximum scheduling priority ("nice")
.TP
.B \-f
The maximum size of files created by the shell
.TP
@@ -8542,6 +8551,9 @@ The pipe size in 512-byte blocks (this may not be set)
.B \-q
The maximum number of bytes in POSIX message queues
.TP
.B \-r
The maximum real-time scheduling priority
.TP
.B \-s
The maximum stack size
.TP
+14 -10
View File
@@ -961,8 +961,8 @@ If the shell option @code{nocasematch}
(see the description of @code{shopt} in @ref{Bash Builtins})
is enabled, the match is performed without regard to the case
of alphabetic characters.
The return value is 0 if the string matches or does not match
the pattern, respectively, and 1 otherwise.
The return value is 0 if the string matches (@samp{==}) or does not
match (@samp{!=})the pattern, and 1 otherwise.
Any part of the pattern may be quoted to force it to be matched as a
string.
@@ -1652,15 +1652,13 @@ the pattern removal operation is applied to each member of the
array in turn, and the expansion is the resultant list.
@item $@{@var{parameter}/@var{pattern}/@var{string}@}
@itemx $@{@var{parameter}//@var{pattern}/@var{string}@}
The @var{pattern} is expanded to produce a pattern just as in
filename expansion.
@var{Parameter} is expanded and the longest match of @var{pattern}
against its value is replaced with @var{string}.
In the first form, only the first match is replaced.
The second form causes all matches of @var{pattern} to be
replaced with @var{string}.
If @var{pattern} begins with @samp{/}, all matches of @var{pattern} are
replaced with @var{string}. Normally only the first match is replaced.
If @var{pattern} begins with @samp{#}, it must match at the beginning
of the expanded value of @var{parameter}.
If @var{pattern} begins with @samp{%}, it must match at the end
@@ -2598,7 +2596,7 @@ the command directly, without invoking another program.
Builtin commands are necessary to implement functionality impossible
or inconvenient to obtain with separate utilities.
This section briefly the builtins which Bash inherits from
This section briefly describes the builtins which Bash inherits from
the Bourne Shell, as well as the builtin commands which are unique
to or have been extended in Bash.
@@ -3833,7 +3831,7 @@ builtin command.
@item ulimit
@btindex ulimit
@example
ulimit [-acdfilmnpqstuvxSH] [@var{limit}]
ulimit [-acdefilmnpqrstuvxSH] [@var{limit}]
@end example
@code{ulimit} provides control over the resources available to processes
started by the shell, on systems that allow such control. If an
@@ -3854,6 +3852,9 @@ The maximum size of core files created.
@item -d
The maximum size of a process's data segment.
@item -e
The maximum scheduling priority ("nice").
@item -f
The maximum size of files created by the shell.
@@ -3875,6 +3876,9 @@ The pipe buffer size.
@item -q
The maximum number of bytes in POSIX message queues.
@item -r
The maximum real-time scheduling priority.
@item -s
The maximum stack size.
@@ -4098,8 +4102,8 @@ shell will exit.
Print shell input lines as they are read.
@item -x
Print a trace of simple commands, \fBfor\fP commands, \fBcase\fP
commands, \fBselect\fP commands, and arithmetic \fBfor\fP commands
Print a trace of simple commands, @code{for} commands, @code{case}
commands, @code{select} commands, and arithmetic @code{for} commands
and their arguments or associated word lists after they are
expanded and before they are executed. The value of the @env{PS4}
variable is expanded and the resultant value is printed before
+20 -7
View File
@@ -961,8 +961,8 @@ If the shell option @code{nocasematch}
(see the description of @code{shopt} in @ref{Bash Builtins})
is enabled, the match is performed without regard to the case
of alphabetic characters.
The return value is 0 if the string matches or does not match
the pattern, respectively, and 1 otherwise.
The return value is 0 if the string matches (@samp{==}) or does not
match (@samp{!=})the pattern, and 1 otherwise.
Any part of the pattern may be quoted to force it to be matched as a
string.
@@ -1652,15 +1652,13 @@ the pattern removal operation is applied to each member of the
array in turn, and the expansion is the resultant list.
@item $@{@var{parameter}/@var{pattern}/@var{string}@}
@itemx $@{@var{parameter}//@var{pattern}/@var{string}@}
The @var{pattern} is expanded to produce a pattern just as in
filename expansion.
@var{Parameter} is expanded and the longest match of @var{pattern}
against its value is replaced with @var{string}.
In the first form, only the first match is replaced.
The second form causes all matches of @var{pattern} to be
replaced with @var{string}.
If @var{pattern} begins with @samp{/}, all matches of @var{pattern} are
replaced with @var{string}. Normally only the first match is replaced.
If @var{pattern} begins with @samp{#}, it must match at the beginning
of the expanded value of @var{parameter}.
If @var{pattern} begins with @samp{%}, it must match at the end
@@ -3833,7 +3831,7 @@ builtin command.
@item ulimit
@btindex ulimit
@example
ulimit [-acdflmnpstuvSH] [@var{limit}]
ulimit [-acdefilmnpqrstuvxSH] [@var{limit}]
@end example
@code{ulimit} provides control over the resources available to processes
started by the shell, on systems that allow such control. If an
@@ -3854,9 +3852,15 @@ The maximum size of core files created.
@item -d
The maximum size of a process's data segment.
@item -e
The maximum scheduling priority ("nice").
@item -f
The maximum size of files created by the shell.
@item -i
The maximum number of pending signals.
@item -l
The maximum size that may be locked into memory.
@@ -3869,6 +3873,12 @@ The maximum number of open file descriptors.
@item -p
The pipe buffer size.
@item -q
The maximum number of bytes in POSIX message queues.
@item -r
The maximum real-time scheduling priority.
@item -s
The maximum stack size.
@@ -3881,6 +3891,9 @@ The maximum number of processes available to a single user.
@item -v
The maximum amount of virtual memory available to the process.
@item -x
The maximum number of file locks.
@end table
If @var{limit} is given, it is the new value of the specified resource;
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2005 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sat Dec 10 19:58:23 EST 2005
@set LASTCHANGE Fri Dec 30 10:50:51 EST 2005
@set EDITION 3.1
@set VERSION 3.1
@set UPDATED 10 December 2005
@set UPDATED 30 December 2005
@set UPDATED-MONTH December 2005
+3 -3
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2005 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Mon Sep 5 11:47:04 EDT 2005
@set LASTCHANGE Wed Dec 28 19:59:13 EST 2005
@set EDITION 3.1
@set VERSION 3.1
@set UPDATED 5 September 2005
@set UPDATED-MONTH September 2005
@set UPDATED 28 December 2005
@set UPDATED-MONTH December 2005
+5 -1
View File
@@ -2396,6 +2396,7 @@ execute_arith_command (arith_command)
int expok, save_line_number, retval;
intmax_t expresult;
WORD_LIST *new;
char *exp;
expresult = 0;
@@ -2438,8 +2439,11 @@ execute_arith_command (arith_command)
if (new)
{
expresult = evalexp (new->word->word, &expok);
exp = new->next ? string_list (new) : new->word->word;
expresult = evalexp (exp, &expok);
line_number = save_line_number;
if (exp != new->word->word)
free (exp);
dispose_words (new);
}
else
+8 -2
View File
@@ -865,17 +865,23 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
? EXECUTION_FAILURE
: EXECUTION_SUCCESS;
#if defined (DPAREN_ARITHMETIC) || defined (COND_COMMAND)
/* This is where we set PIPESTATUS from the exit status of the appropriate
compound commands (the ones that look enough like simple commands to
cause confusion). We might be able to optimize by not doing this if
subshell_environment != 0. */
switch (command->type)
{
case cm_arith_for:
# if defined (DPAREN_ARITHMETIC)
case cm_arith:
# endif
# if defined (COND_COMMAND)
case cm_cond:
# endif
set_pipestatus_from_exit (exec_result);
break;
}
#endif
last_command_exit_value = exec_result;
run_pending_traps ();
@@ -2192,7 +2198,7 @@ execute_case_command (case_command)
if (echo_command_at_execute)
xtrace_print_case_command_head (case_command);
if (signal_in_progress (DEBUG_TRAP == 0) && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
if (signal_in_progress (DEBUG_TRAP) == 0 && (this_command_name == 0 || (STREQ (this_command_name, "trap") == 0)))
{
FREE (the_printed_command_except_trap);
the_printed_command_except_trap = savestring (the_printed_command);
+73
View File
@@ -148,6 +148,7 @@ static intmax_t tokval; /* current token value */
static int noeval; /* set to 1 if no assignment to be done */
static procenv_t evalbuf;
static int _is_arithop __P((int));
static void readtok __P((void)); /* lexical analyzer */
static intmax_t expr_streval __P((char *, int));
@@ -949,6 +950,64 @@ expr_streval (tok, e)
return (tval);
}
static int
_is_multiop (c)
int c;
{
switch (c)
{
case EQEQ:
case NEQ:
case LEQ:
case GEQ:
case LAND:
case LOR:
case LSH:
case RSH:
case OP_ASSIGN:
case COND:
case POWER:
case PREINC:
case PREDEC:
case POSTINC:
case POSTDEC:
return 1;
default:
return 0;
}
}
static int
_is_arithop (c)
int c;
{
switch (c)
{
case EQ:
case GT:
case LT:
case PLUS:
case MINUS:
case MUL:
case DIV:
case MOD:
case NOT:
case LPAR:
case RPAR:
case BAND:
case BOR:
case BXOR:
case BNOT:
return 1; /* operator tokens */
case QUES:
case COL:
case COMMA:
return 1; /* questionable */
default:
return 0; /* anything else is invalid */
}
}
/* Lexical analyzer/token reader for the expression evaluator. Reads the
next token and puts its value into curtok, while advancing past it.
Updates value of tp. May also set tokval (for number) or tokstr (for
@@ -1104,8 +1163,22 @@ readtok ()
assigntok = c; /* a OP= b */
c = OP_ASSIGN;
}
else if (_is_arithop (c) == 0)
{
cp--;
/* use curtok, since it hasn't been copied to lasttok yet */
if (curtok == 0 || _is_arithop (curtok) || _is_multiop (curtok))
evalerror (_("syntax error: operand expected"));
else
evalerror (_("syntax error: invalid arithmetic operator"));
}
else
cp--; /* `unget' the character */
/* Should check here to make sure that the current character is one
of the recognized operators and flag an error if not. Could create
a character map the first time through and check it on subsequent
calls. */
lasttok = curtok;
curtok = c;
}
+1348
View File
File diff suppressed because it is too large Load Diff
+11 -4
View File
@@ -462,12 +462,21 @@ rl_translate_keyseq (seq, array, len)
}
else if (c == 'M')
{
i++;
/* XXX - should obey convert-meta setting? */
i++; /* seq[i] == '-' */
/* XXX - obey convert-meta setting */
if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
array[l++] = ESC; /* ESC is meta-prefix */
else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
{
i += 4;
temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
array[l++] = META (temp);
}
else
{
/* This doesn't yet handle things like \M-\a, which may
or may not have any reasonable meaning. You're
probably better off using straight octal or hex. */
i++;
array[l++] = META (seq[i]);
}
@@ -1507,7 +1516,6 @@ rl_variable_value (name)
{
register int i;
int v;
char *ret;
/* Check for simple variables first. */
i = find_boolean_var (name);
@@ -2170,7 +2178,6 @@ _rl_get_string_variable_value (name)
{
static char numbuf[32];
char *ret;
int n;
if (_rl_stricmp (name, "bell-style") == 0)
{
+2286
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -43,6 +43,7 @@
#include "rldefs.h"
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
+260
View File
@@ -0,0 +1,260 @@
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
#if defined (READLINE_CALLBACKS)
#include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "readline.h"
#include "rlprivate.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* **************************************************************** */
/* */
/* Callback Readline Functions */
/* */
/* **************************************************************** */
/* Allow using readline in situations where a program may have multiple
things to handle at once, and dispatches them via select(). Call
rl_callback_handler_install() with the prompt and a function to call
whenever a complete line of input is ready. The user must then
call rl_callback_read_char() every time some input is available, and
rl_callback_read_char() will call the user's function with the complete
text read in at each end of line. The terminal is kept prepped and
signals handled all the time, except during calls to the user's function. */
rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */
/* Make sure the terminal is set up, initialize readline, and prompt. */
static void
_rl_callback_newline ()
{
rl_initialize ();
if (in_handler == 0)
{
in_handler = 1;
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
rl_set_signals ();
#endif
}
readline_internal_setup ();
}
/* Install a readline handler, set up the terminal, and issue the prompt. */
void
rl_callback_handler_install (prompt, linefunc)
const char *prompt;
rl_vcpfunc_t *linefunc;
{
rl_set_prompt (prompt);
RL_SETSTATE (RL_STATE_CALLBACK);
rl_linefunc = linefunc;
_rl_callback_newline ();
}
/* Read one character, and dispatch to the handler if it ends the line. */
void
rl_callback_read_char ()
{
char *line;
int eof, jcode;
static procenv_t olevel;
if (rl_linefunc == NULL)
{
fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
abort ();
}
memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t));
jcode = setjmp (readline_top_level);
if (jcode)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t));
return;
}
if (RL_ISSTATE (RL_STATE_ISEARCH))
{
eof = _rl_isearch_callback (_rl_iscxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
return;
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
eof = _rl_nsearch_callback (_rl_nscxt);
return;
}
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
/* XXX - this should handle _rl_last_command_was_kill better */
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
eof = _rl_dispatch_callback (_rl_kscxt);
if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
{
_rl_internal_char_cleanup ();
_rl_want_redisplay = 1;
}
}
else if (_rl_callback_func)
{
/* This allows functions that simply need to read an additional character
(like quoted-insert) to register a function to be called when input is
available. _rl_callback_data is simply a pointer to a struct that has
the argument count originally passed to the registering function and
space for any additional parameters. */
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is cleaned
up. */
if (_rl_callback_func == 0)
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
_rl_internal_char_cleanup ();
}
}
else
eof = readline_internal_char ();
if (rl_done == 0 && _rl_want_redisplay)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
/* We loop in case some function has pushed input back with rl_execute_next. */
for (;;)
{
if (rl_done)
{
line = readline_internal_teardown (eof);
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
in_handler = 0;
(*rl_linefunc) (line);
/* If the user did not clear out the line, do it for him. */
if (rl_line_buffer[0])
_rl_init_line_state ();
/* Redisplay the prompt if readline_handler_{install,remove}
not called. */
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
if (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT))
eof = readline_internal_char ();
else
break;
}
}
/* Remove the handler, and make sure the terminal is in its normal state. */
void
rl_callback_handler_remove ()
{
rl_linefunc = NULL;
RL_UNSETSTATE (RL_STATE_CALLBACK);
if (in_handler)
{
in_handler = 0;
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
#endif
}
}
_rl_callback_generic_arg *
_rl_callback_data_alloc (count)
int count;
{
_rl_callback_generic_arg *arg;
arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
arg->count = count;
arg->i1 = arg->i2 = 0;
return arg;
}
void _rl_callback_data_dispose (arg)
_rl_callback_generic_arg *arg;
{
if (arg)
free (arg);
}
#endif
+4 -4
View File
@@ -244,12 +244,12 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
invfl = 0; /* invisible chars in first line of prompt */
invflset = 0; /* we only want to set invfl once */
igstart = -1;
igstart = 0;
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
if (*p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
{
ignoring = 1;
igstart = p;
@@ -258,7 +258,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
if (p[-1] != RL_PROMPT_START_IGNORE)
if (p != (igstart + 1))
last = r - ret - 1;
continue;
}
@@ -1166,7 +1166,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
int col_lendiff, col_temp;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps_new, ps_old;
int new_offset, old_offset, tmp;
int new_offset, old_offset;
#endif
/* If we're at the right edge of a terminal that supports xn, we're
+6 -4
View File
@@ -220,7 +220,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
char *pmt;
int *lp, *lip, *niflp, *vlp;
{
char *r, *ret, *p;
char *r, *ret, *p, *igstart;
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
/* Short-circuit if we can. */
@@ -244,19 +244,21 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
invfl = 0; /* invisible chars in first line of prompt */
invflset = 0; /* we only want to set invfl once */
igstart = 0;
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
if (*p == RL_PROMPT_START_IGNORE)
if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
{
ignoring++;
ignoring = 1;
igstart = p;
continue;
}
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
if (p[-1] != RL_PROMPT_START_IGNORE)
if (p != (igstart + 1))
last = r - ret - 1;
continue;
}
+2 -2
View File
@@ -68,8 +68,8 @@ static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. */
static char *prev_line_found;
identical lines many times in a row. Now part of isearch context. */
/* static char *prev_line_found; */
/* Last search string and its length. */
static char *last_isearch_string;
+666
View File
@@ -0,0 +1,666 @@
/* **************************************************************** */
/* */
/* I-Search and Searching */
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
for it.
The Library 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.
The Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;
_rl_search_cxt *_rl_iscxt = 0;
/* Variables imported from other files in the readline library. */
extern HIST_ENTRY *_rl_saved_line_for_history;
static int rl_search_history PARAMS((int, int));
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. */
static char *prev_line_found;
/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;
static char *default_isearch_terminators = "\033\012";
_rl_search_cxt *
_rl_scxt_alloc (type, flags)
int type, flags;
{
_rl_search_cxt *cxt;
cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
cxt->type = type;
cxt->sflags = flags;
cxt->search_string = 0;
cxt->search_string_size = cxt->search_string_index = 0;
cxt->lines = 0;
cxt->allocated_line = 0;
cxt->hlen = cxt->hindex = 0;
cxt->save_point = rl_point;
cxt->save_mark = rl_mark;
cxt->save_line = where_history ();
cxt->last_found_line = cxt->save_line;
cxt->prev_line_found = 0;
cxt->save_undo_list = 0;
cxt->history_pos = 0;
cxt->direction = 0;
cxt->lastc = 0;
cxt->sline = 0;
cxt->sline_len = cxt->sline_index = 0;
cxt->search_terminators = 0;
return cxt;
}
void
_rl_scxt_dispose (cxt, flags)
_rl_search_cxt *cxt;
int flags;
{
FREE (cxt->search_string);
FREE (cxt->allocated_line);
FREE (cxt->lines);
free (cxt);
}
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_reverse_search_history (sign, key)
int sign, key;
{
return (rl_search_history (-sign, key));
}
/* Search forwards through the history looking for a string which is typed
interactively. Start with the current line. */
int
rl_forward_search_history (sign, key)
int sign, key;
{
return (rl_search_history (sign, key));
}
/* Display the current state of the search in the echo-area.
SEARCH_STRING contains the string that is being searched for,
DIRECTION is zero for forward, or non-zero for reverse,
WHERE is the history list number of the current line. If it is
-1, then this line is the starting one. */
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where;
{
char *message;
int msglen, searchlen;
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = (char *)xmalloc (searchlen + 33);
msglen = 0;
#if defined (NOTDEF)
if (where != -1)
{
sprintf (message, "[%d]", where + history_base);
msglen = strlen (message);
}
#endif /* NOTDEF */
message[msglen++] = '(';
if (reverse_p)
{
strcpy (message + msglen, "reverse-");
msglen += 8;
}
strcpy (message + msglen, "i-search)`");
msglen += 10;
if (search_string)
{
strcpy (message + msglen, search_string);
msglen += searchlen;
}
strcpy (message + msglen, "': ");
rl_message ("%s", message);
free (message);
(*rl_redisplay_function) ();
}
static _rl_search_cxt *
_rl_isearch_init (direction)
int direction;
{
_rl_search_cxt *cxt;
register int i;
HIST_ENTRY **hlist;
cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
if (direction < 0)
cxt->sflags |= SF_REVERSE;
cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
/* Create an arrary of pointers to the lines that we want to search. */
hlist = history_list ();
rl_maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
for (i = 0; i < cxt->hlen; i++)
cxt->lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
cxt->lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (cxt->allocated_line, &rl_line_buffer[0]);
cxt->lines[i] = cxt->allocated_line;
}
cxt->hlen++;
/* The line where we start the search. */
cxt->history_pos = cxt->save_line;
rl_save_prompt ();
/* Initialize search parameters. */
cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
cxt->search_string[cxt->search_string_index = 0] = '\0';
/* Normalize DIRECTION into 1 or -1. */
cxt->direction = (direction >= 0) ? 1 : -1;
cxt->sline = rl_line_buffer;
cxt->sline_len = strlen (cxt->sline);
cxt->sline_index = rl_point;
_rl_iscxt = cxt; /* save globally */
return cxt;
}
static void
_rl_isearch_fini (cxt)
_rl_search_cxt *cxt;
{
/* First put back the original state. */
strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
else
rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (cxt->sline_index < 0)
{
if (cxt->last_found_line == cxt->save_line)
cxt->sline_index = cxt->save_point;
else
cxt->sline_index = strlen (rl_line_buffer);
rl_mark = cxt->save_mark;
}
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
}
int
_rl_search_getchar (cxt)
_rl_search_cxt *cxt;
{
int c;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = cxt->lastc = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
return c;
}
/* Process just-read character C according to isearch context CXT. Return
-1 if the caller should just free the context and return, 0 if we should
break out of the loop, and 1 if we should continue to read characters. */
int
_rl_isearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
int n, wstart, wlen, limit, cval;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
{
f = _rl_keymap[c].function;
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
else if (f == rl_forward_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
else if (c == CTRL ('G'))
cxt->lastc = -4;
else if (c == CTRL ('W')) /* XXX */
cxt->lastc = -5;
else if (c == CTRL ('Y')) /* XXX */
cxt->lastc = -6;
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended
to allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command.
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (cxt->lastc == ESC && _rl_input_available ())
rl_execute_next (ESC);
return (0);
}
#define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
}
else
#endif
if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (cxt->lastc);
return (0);
}
/* Now dispatch on the character. `Opcodes' affect the search string or
state. Other characters are added to the string. */
switch (cxt->lastc)
{
/* search again */
case -1:
if (cxt->search_string_index == 0)
{
if (last_isearch_string)
{
cxt->search_string_size = 64 + last_isearch_string_len;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
strcpy (cxt->search_string, last_isearch_string);
cxt->search_string_index = last_isearch_string_len;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
break;
}
return (1);
}
else if (cxt->sflags & SF_REVERSE)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
else
rl_ding ();
break;
/* switch directions */
case -2:
cxt->direction = -cxt->direction;
if (cxt->direction < 0)
cxt->sflags |= SF_REVERSE;
else
cxt->sflags &= ~SF_REVERSE;
break;
/* delete character from search string. */
case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (cxt->search_string_index == 0)
rl_ding ();
else
cxt->search_string[--cxt->search_string_index] = '\0';
break;
case -4: /* C-G, abort */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt();
rl_clear_message ();
return -1;
case -5: /* C-W */
/* skip over portion of line we already matched and yank word */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
/* if not in a word, move to one. */
cval = _rl_char_value (rl_line_buffer, wstart);
if (_rl_walphabetic (cval) == 0)
{
rl_ding ();
break;
}
n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
while (n < rl_end)
{
cval = _rl_char_value (rl_line_buffer, n);
if (_rl_walphabetic (cval) == 0)
break;
n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
}
wlen = n - wstart + 1;
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
cxt->search_string_size += wlen + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (; wstart < n; wstart++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched and yank rest */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
{
cxt->search_string_size += n + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (n = wstart; n < rl_end; n++)
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
cxt->search_string[cxt->search_string_index] = '\0';
break;
/* Add character to search string and continue search. */
default:
if (cxt->search_string_index + 2 >= cxt->search_string_size)
{
cxt->search_string_size += 128;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (cxt->mb); j < l; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
cxt->search_string[cxt->search_string_index++] = c;
cxt->search_string[cxt->search_string_index] = '\0';
break;
}
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
{
if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
{
cxt->sflags |= SF_FOUND;
break;
}
else
cxt->sline_index += cxt->direction;
}
if (cxt->sflags & SF_FOUND)
break;
/* Move to the next line, but skip new copies of the line
we just found and lines shorter than the string we're
searching for. */
do
{
/* Move to the next line. */
cxt->history_pos += cxt->direction;
/* At limit for direction? */
if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
{
cxt->sflags |= SF_FAILED;
break;
}
/* We will need these later. */
cxt->sline = cxt->lines[cxt->history_pos];
cxt->sline_len = strlen (cxt->sline);
}
while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
(cxt->search_string_index > cxt->sline_len));
if (cxt->sflags & SF_FAILED)
break;
/* Now set up the line for searching... */
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
}
if (cxt->sflags & SF_FAILED)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
cxt->history_pos = cxt->last_found_line;
return 1;
}
/* We have found the search string. Just display it. But don't
actually move there in the history list until the user accepts
the location. */
if (cxt->sflags & SF_FOUND)
{
cxt->prev_line_found = cxt->lines[cxt->history_pos];
rl_replace_line (cxt->lines[cxt->history_pos], 0);
rl_point = cxt->sline_index;
cxt->last_found_line = cxt->history_pos;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
}
return 1;
}
static int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
RL_UNSETSTATE(RL_STATE_ISEARCH);
return (r != 0);
}
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction, invoking_key;
{
_rl_search_cxt *cxt; /* local for now, but saved globally */
int c, r;
RL_SETSTATE(RL_STATE_ISEARCH);
cxt = _rl_isearch_init (direction);
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
/* If we are using the callback interface, all we do is set up here and
return. The key is that we leave RL_STATE_ISEARCH set. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
r = -1;
for (;;)
{
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here (c == 0) */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
if (r <= 0)
break;
}
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
return (_rl_isearch_cleanup (cxt, r));
}
#if defined (READLINE_CALLBACKS)
/* Called from the callback functions when we are ready to read a key. The
callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
If _rl_isearch_dispatch finishes searching, this function is responsible
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
int
_rl_isearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
}
#endif
+2
View File
@@ -212,6 +212,8 @@ rl_digit_loop ()
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
return r;
}
/* Create a default argument. */
+601
View File
@@ -0,0 +1,601 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
static int rl_digit_loop PARAMS((void));
static void _rl_history_set_point PARAMS((void));
/* Forward declarations used in this file */
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
_rl_arg_cxt _rl_argcxt;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
/* **************************************************************** */
/* */
/* Numeric Arguments */
/* */
/* **************************************************************** */
int
_rl_arg_overflow ()
{
if (rl_numeric_arg > 1000000)
{
_rl_argcxt = 0;
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
return 0;
}
void
_rl_arg_init ()
{
rl_save_prompt ();
_rl_argcxt = 0;
RL_SETSTATE(RL_STATE_NUMERICARG);
}
int
_rl_arg_getchar ()
{
int c;
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
return c;
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
int
_rl_arg_dispatch (cxt, c)
_rl_arg_cxt cxt;
int c;
{
int key, r;
key = c;
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if ((cxt & NUM_SAWDIGITS) == 0)
{
rl_numeric_arg *= 4;
return 1;
}
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_argcxt |= NUM_READONE;
return 0; /* XXX */
}
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
key = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (_rl_dispatch (key, _rl_keymap));
}
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
_rl_argcxt |= NUM_SAWDIGITS;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
r = _rl_dispatch (key, _rl_keymap);
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* At worst, this will cause an extra redisplay. Otherwise,
we have to wait until the next character comes in. */
if (rl_done == 0)
(*rl_redisplay_function) ();
r = 0;
}
return r;
}
return 1;
}
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
int c, r;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_arg_dispatch (_rl_argcxt, c);
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
}
/* Create a default argument. */
void
_rl_reset_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
_rl_argcxt = 0;
}
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (ignore, key)
int ignore, key;
{
_rl_arg_init ();
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_arg_dispatch (_rl_argcxt, key);
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return 0;
}
else
{
rl_execute_next (key);
return (rl_digit_loop ());
}
}
/* C-u, universal argument. Multiply the current argument by 4.
Read a key. If the key has nothing to do with arguments, then
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
int count, key;
{
_rl_arg_init ();
rl_numeric_arg *= 4;
return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
int
_rl_arg_callback (cxt)
_rl_arg_cxt cxt;
{
int c, r;
c = _rl_arg_getchar ();
if (_rl_argcxt & NUM_READONE)
{
_rl_argcxt &= ~NUM_READONE;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_execute_next (c);
return 0;
}
r = _rl_arg_dispatch (cxt, c);
return (r != 1);
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
return 0;
}
/* **************************************************************** */
/* */
/* History Utilities */
/* */
/* **************************************************************** */
/* We already have a history library, and that is what we use to control
the history features of readline. This is our local interface to
the history mechanism. */
/* While we are editing the history, this is the saved
version of the original line. */
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
/* Set the history pointer back to the last entry in the history. */
void
_rl_start_using_history ()
{
using_history ();
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Free the contents (and containing structure) of a HIST_ENTRY. */
void
_rl_free_history_entry (entry)
HIST_ENTRY *entry;
{
if (entry == 0)
return;
FREE (entry->line);
FREE (entry->timestamp);
free (entry);
}
/* Perhaps put back the current line if it has changed. */
int
rl_maybe_replace_line ()
{
HIST_ENTRY *temp;
temp = current_history ();
/* If the current line has changed, save the changes. */
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
free (temp->line);
FREE (temp->timestamp);
free (temp);
}
return 0;
}
/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line ()
{
if (_rl_saved_line_for_history)
{
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
rl_point = rl_end; /* rl_replace_line sets rl_end */
}
else
rl_ding ();
return 0;
}
/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line ()
{
if (_rl_saved_line_for_history == 0)
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->timestamp = (char *)NULL;
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
return 0;
}
int
_rl_free_saved_history_line ()
{
if (_rl_saved_line_for_history)
{
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
return 0;
}
static void
_rl_history_set_point ()
{
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
? _rl_history_saved_point
: rl_end;
if (rl_point > rl_end)
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0;
#endif /* VI_MODE */
if (rl_editing_mode == emacs_mode)
rl_mark = (rl_point == rl_end ? 0 : rl_end);
}
void
rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags; /* currently unused */
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
rl_mark = 0;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
{
rl_point = 0;
rl_mark = rl_end;
}
#endif
}
/* **************************************************************** */
/* */
/* History Commands */
/* */
/* **************************************************************** */
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
int count, key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
int count, key;
{
rl_maybe_replace_line ();
using_history ();
rl_maybe_unsave_line ();
return 0;
}
/* Move down to the next history line. */
int
rl_get_next_history (count, key)
int count, key;
{
HIST_ENTRY *temp;
if (count < 0)
return (rl_get_previous_history (-count, key));
if (count == 0)
return 0;
rl_maybe_replace_line ();
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = next_history ();
if (!temp)
break;
--count;
}
if (temp == 0)
rl_maybe_unsave_line ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* Get the previous item out of our interactive history, making it the current
line. If there is no previous history, just ding. */
int
rl_get_previous_history (count, key)
int count, key;
{
HIST_ENTRY *old_temp, *temp;
if (count < 0)
return (rl_get_next_history (-count, key));
if (count == 0)
return 0;
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
/* If we don't have a line saved, then save this one. */
rl_maybe_save_line ();
/* If the current line has changed, save the changes. */
rl_maybe_replace_line ();
temp = old_temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = previous_history ();
if (temp == 0)
break;
old_temp = temp;
--count;
}
/* If there was a large argument, and we moved back to the start of the
history, that is not an error. So use the last value found. */
if (!temp && old_temp)
temp = old_temp;
if (temp == 0)
rl_ding ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* **************************************************************** */
/* */
/* Editing Modes */
/* */
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
int count, key;
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
rl_editing_mode = vi_mode;
rl_vi_insertion_mode (1, key);
#endif /* VI_MODE */
return 0;
}
int
rl_emacs_editing_mode (count, key)
int count, key;
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
_rl_keymap = emacs_standard_keymap;
return 0;
}
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (im, force)
int im, force;
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
#endif
rl_insert_mode = im;
}
/* Toggle overwrite mode. A positive explicit argument selects overwrite
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (count, key)
int count, key;
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
else if (count > 0)
_rl_set_insert_mode (RL_IM_OVERWRITE, 0);
else
_rl_set_insert_mode (RL_IM_INSERT, 0);
return 0;
}
-1
View File
@@ -933,7 +933,6 @@ rltty_set_default_bindings (kmap)
#if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty;
static int called = 0;
tty = fileno (rl_instream);
File diff suppressed because it is too large Load Diff
-1
View File
@@ -70,7 +70,6 @@ static int rl_history_search_pos;
static char *history_search_string;
static int history_string_size;
static UNDO_LIST *noninc_saved_undo_list;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static int noninc_dosearch PARAMS((char *, int));
+572
View File
@@ -0,0 +1,572 @@
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
This file is part of the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
for it.
The Library 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.
The Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#ifdef abs
# undef abs
#endif
#define abs(x) (((x) >= 0) ? (x) : -(x))
_rl_search_cxt *_rl_nscxt = 0;
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Functions imported from the rest of the library. */
extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos;
static char *prev_line_found = (char *) NULL;
static int rl_history_search_len;
static int rl_history_search_pos;
static char *history_search_string;
static int history_string_size;
static UNDO_LIST *noninc_saved_undo_list;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static int noninc_dosearch PARAMS((char *, int));
static int noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((void));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
command lines to the edit line. We're going to implement that by
making the undo list start after the matching line is copied to the
current editing buffer. */
rl_free_undo_list ();
#endif
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search the history list for STRING starting at absolute history position
POS. If STRING begins with `^', the search must match STRING at the
beginning of a history line, otherwise a full substring match is performed
for STRING. DIR < 0 means to search backwards through the history list,
DIR >= 0 means to search forward. */
static int
noninc_search_from_pos (string, pos, dir)
char *string;
int pos, dir;
{
int ret, old;
if (pos < 0)
return -1;
old = where_history ();
if (history_set_pos (pos) == 0)
return -1;
RL_SETSTATE(RL_STATE_SEARCH);
if (*string == '^')
ret = history_search_prefix (string + 1, dir);
else
ret = history_search (string, dir);
RL_UNSETSTATE(RL_STATE_SEARCH);
if (ret != -1)
ret = where_history ();
history_set_pos (old);
return (ret);
}
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (string, dir)
char *string;
int dir;
{
int oldpos, pos;
HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
rl_ding ();
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
if (pos == -1)
{
/* Search failed, current history position unchanged. */
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = 0;
rl_ding ();
return 0;
}
noninc_history_pos = pos;
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history ();
#if defined (VI_MODE)
if (rl_editing_mode != vi_mode)
#endif
history_set_pos (oldpos);
make_history_line_current (entry);
rl_point = 0;
rl_mark = rl_end;
rl_clear_message ();
return 1;
}
static _rl_search_cxt *
_rl_nsearch_init (dir, pchar)
int dir, pchar;
{
_rl_search_cxt *cxt;
char *p;
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
rl_maybe_save_line ();
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message (p, 0, 0);
free (p);
RL_SETSTATE(RL_STATE_NSEARCH);
_rl_nscxt = cxt;
return cxt;
}
static int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
_rl_scxt_dispose (cxt, 0);
_rl_nscxt = 0;
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (r != 1);
}
static void
_rl_nsearch_abort (cxt)
_rl_search_cxt *cxt;
{
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
}
/* Process just-read character C according to search context CXT. Return -1
if the caller should abort the search, 0 if we should break out of the
loop, and 1 if we should continue to read characters. */
static int
_rl_nsearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
switch (c)
{
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
case CTRL('U'):
rl_unix_line_discard (1, c);
break;
case RETURN:
case NEWLINE:
return 0;
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
_rl_nsearch_abort (cxt);
return -1;
}
_rl_rubout_char (1, c);
break;
case CTRL('C'):
case CTRL('G'):
rl_ding ();
_rl_nsearch_abort (cxt);
return -1;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (cxt->mb);
else
#endif
_rl_insert_char (1, c);
break;
}
(*rl_redisplay_function) ();
return 1;
}
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
static int
_rl_nsearch_dosearch (cxt)
_rl_search_cxt *cxt;
{
rl_mark = cxt->save_mark;
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
if (rl_point == 0)
{
if (noninc_search_string == 0)
{
rl_ding ();
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
return -1;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = cxt->save_line;
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
/* If we don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
we need to clear rl_line_buffer here. For now, we just clear the
undo list generated by reading the search string. (If the search
fails, the old undo list will be restored by rl_maybe_unsave_line.) */
rl_free_undo_list ();
}
rl_restore_prompt ();
return (noninc_dosearch (noninc_search_string, cxt->direction));
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static int
noninc_search (dir, pchar)
int dir;
int pchar;
{
_rl_search_cxt *cxt;
int c, r;
cxt = _rl_nsearch_init (dir, pchar);
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Read the search string. */
r = 0;
while (1)
{
c = _rl_search_getchar (cxt);
if (c == 0)
break;
r = _rl_nsearch_dispatch (cxt, c);
if (r < 0)
return 1;
else if (r == 0)
break;
}
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (count, key)
int count, key;
{
return noninc_search (1, (key == '?') ? '?' : 0);
}
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (count, key)
int count, key;
{
return noninc_search (-1, (key == '/') ? '/' : 0);
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_forward_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
r = noninc_dosearch (noninc_search_string, 1);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_reverse_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
r = noninc_dosearch (noninc_search_string, -1);
return (r != 1);
}
#if defined (READLINE_CALLBACKS)
int
_rl_nsearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
r = _rl_nsearch_dispatch (cxt, c);
if (r != 0)
return 1;
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
static int
rl_history_search_internal (count, dir)
int count, dir;
{
HIST_ENTRY *temp;
int ret, oldpos;
rl_maybe_save_line ();
temp = (HIST_ENTRY *)NULL;
/* Search COUNT times through the history for a line whose prefix
matches history_search_string. When this loop finishes, TEMP,
if non-null, is the history line to copy into the line buffer. */
while (count)
{
ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
if (ret == -1)
break;
/* Get the history entry we found. */
rl_history_search_pos = ret;
oldpos = where_history ();
history_set_pos (rl_history_search_pos);
temp = current_history ();
history_set_pos (oldpos);
/* Don't find multiple instances of the same line. */
if (prev_line_found && STREQ (prev_line_found, temp->line))
continue;
prev_line_found = temp->line;
count--;
}
/* If we didn't find anything at all, return. */
if (temp == 0)
{
rl_maybe_unsave_line ();
rl_ding ();
/* If you don't want the saved history line (last match) to show up
in the line buffer after the search fails, change the #if 0 to
#if 1 */
#if 0
if (rl_point > rl_history_search_len)
{
rl_point = rl_end = rl_history_search_len;
rl_line_buffer[rl_end] = '\0';
rl_mark = 0;
}
#else
rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
rl_mark = rl_end;
#endif
return 1;
}
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
rl_point = rl_history_search_len;
rl_mark = rl_end;
return 0;
}
static void
rl_history_search_reinit ()
{
rl_history_search_pos = where_history ();
rl_history_search_len = rl_point;
prev_line_found = (char *)NULL;
if (rl_point)
{
if (rl_history_search_len >= history_string_size - 2)
{
history_string_size = rl_history_search_len + 2;
history_search_string = (char *)xrealloc (history_search_string, history_string_size);
}
history_search_string[0] = '^';
strncpy (history_search_string + 1, rl_line_buffer, rl_point);
history_search_string[rl_point + 1] = '\0';
}
_rl_free_saved_history_line ();
}
/* Search forward in the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_forward (count, ignore)
int count, ignore;
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_next_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
}
/* Search backward through the history for the string of characters
from the start of the line to rl_point. This is a non-incremental
search. */
int
rl_history_search_backward (count, ignore)
int count, ignore;
{
if (count == 0)
return (0);
if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_previous_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
}
+41 -1
View File
@@ -160,6 +160,7 @@ rl_signal_handler (sig)
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
@@ -288,9 +289,44 @@ rl_set_signals ()
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGINT);
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &bset, &oset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGQUIT)
@@ -324,6 +360,10 @@ rl_set_signals ()
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
}
#if defined (SIGWINCH)
@@ -390,8 +430,8 @@ rl_cleanup_after_signal ()
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_signals ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
+470
View File
@@ -0,0 +1,470 @@
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
#if defined (HANDLE_SIGNALS)
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#if !defined (RETSIGTYPE)
# if defined (VOID_SIGHANDLER)
# define RETSIGTYPE void
# else
# define RETSIGTYPE int
# endif /* !VOID_SIGHANDLER */
#endif /* !RETSIGTYPE */
#if defined (VOID_SIGHANDLER)
# define SIGHANDLER_RETURN return
#else
# define SIGHANDLER_RETURN return (0)
#endif
/* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef RETSIGTYPE SigHandler ();
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
/* Exported variables for use by applications. */
/* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
static int signals_set_flag;
static int sigwinch_set_flag;
/* **************************************************************** */
/* */
/* Signal Handling */
/* */
/* **************************************************************** */
static sighandler_cxt old_int, old_term, old_alrm, old_quit;
#if defined (SIGTSTP)
static sighandler_cxt old_tstp, old_ttou, old_ttin;
#endif
#if defined (SIGWINCH)
static sighandler_cxt old_winch;
#endif
/* Readline signal handler functions. */
static RETSIGTYPE
rl_signal_handler (sig)
int sig;
{
#if defined (HAVE_POSIX_SIGNALS)
sigset_t set, pset;
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
long omask;
# else /* !HAVE_BSD_SIGNALS */
sighandler_cxt dummy_cxt; /* needed for rl_set_sighandler call */
# endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
RL_SETSTATE(RL_STATE_SIGHANDLER);
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&set);
sigemptyset (&pset);
#endif
switch (sig)
{
case SIGINT:
rl_free_line_state ();
/* FALLTHROUGH */
case SIGTERM:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
#endif /* SIGTSTP */
#if defined (SIGALRM)
case SIGALRM:
#endif
#if defined (SIGQUIT)
case SIGQUIT:
#endif
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
omask = sigblock (0);
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
#if defined (__EMX__)
signal (sig, SIG_ACK);
#endif
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig); /* assume we have raise */
#endif
/* Let the signal that we just sent through. */
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &set, (sigset_t *)NULL);
#else /* !HAVE_POSIX_SIGNALS */
# if defined (HAVE_BSD_SIGNALS)
sigsetmask (omask & ~(sigmask (sig)));
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
rl_reset_after_signal ();
}
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#if defined (SIGWINCH)
static RETSIGTYPE
rl_sigwinch_handler (sig)
int sig;
{
SigHandler *oh;
#if defined (MUST_REINSTALL_SIGHANDLERS)
sighandler_cxt dummy_winch;
/* We don't want to change old_winch -- it holds the state of SIGWINCH
disposition set by the calling application. We need this state
because we call the application's SIGWINCH handler after updating
our own idea of the screen size. */
rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
#endif
RL_SETSTATE(RL_STATE_SIGHANDLER);
rl_resize_terminal ();
/* If another sigwinch handler has been installed, call it. */
oh = (SigHandler *)old_winch.sa_handler;
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
(*oh) (sig);
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN;
}
#endif /* SIGWINCH */
/* Functions to manage signal handling. */
#if !defined (HAVE_POSIX_SIGNALS)
static int
rl_sigaction (sig, nh, oh)
int sig;
sighandler_cxt *nh, *oh;
{
oh->sa_handler = signal (sig, nh->sa_handler);
return 0;
}
#endif /* !HAVE_POSIX_SIGNALS */
/* Set up a readline-specific signal handler, saving the old signal
information in OHANDLER. Return the old signal handler, like
signal(). */
static SigHandler *
rl_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt old_handler;
#if defined (HAVE_POSIX_SIGNALS)
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);
#else
old_handler.sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */
/* XXX -- assume we have memcpy */
/* If rl_set_signals is called twice in a row, don't set the old handler to
rl_signal_handler, because that would cause infinite recursion. */
if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
return (ohandler->sa_handler);
}
static void
rl_maybe_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
sighandler_cxt dummy;
SigHandler *oh;
sigemptyset (&dummy.sa_mask);
oh = rl_set_sighandler (sig, handler, ohandler);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (sig, ohandler, &dummy);
}
int
rl_set_signals ()
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGINT);
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &bset, &oset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#if defined (HAVE_POSIX_SIGNALS) && defined (SA_RESTART)
/* If the application using readline has already installed a signal
handler with SA_RESTART, SIGALRM will cause reads to be restarted
automatically, so readline should just get out of the way. Since
we tested for SIG_IGN above, we can just test for SIG_DFL here. */
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif /* HAVE_POSIX_SIGNALS */
#endif /* SIGALRM */
#if defined (SIGTSTP)
rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_maybe_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_maybe_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 0)
{
rl_maybe_set_sighandler (SIGWINCH, rl_sigwinch_handler, &old_winch);
sigwinch_set_flag = 1;
}
#endif /* SIGWINCH */
return 0;
}
int
rl_clear_signals ()
{
sighandler_cxt dummy;
if (rl_catch_signals && signals_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGTERM, &old_term, &dummy);
#if defined (SIGQUIT)
rl_sigaction (SIGQUIT, &old_quit, &dummy);
#endif
#if defined (SIGALRM)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif
#if defined (SIGTSTP)
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
#endif /* SIGTSTP */
#if defined (SIGTTOU)
rl_sigaction (SIGTTOU, &old_ttou, &dummy);
#endif /* SIGTTOU */
#if defined (SIGTTIN)
rl_sigaction (SIGTTIN, &old_ttin, &dummy);
#endif /* SIGTTIN */
signals_set_flag = 0;
}
#if defined (SIGWINCH)
if (rl_catch_sigwinch && sigwinch_set_flag == 1)
{
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGWINCH, &old_winch, &dummy);
sigwinch_set_flag = 0;
}
#endif
return 0;
}
/* Clean up the terminal and readline state after catching a signal, before
resending it to the calling application. */
void
rl_cleanup_after_signal ()
{
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
void
rl_reset_after_signal ()
{
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
/* Free up the readline variable line state for the current line (undo list,
any partial history entry, any keyboard macros in progress, and any
numeric arguments in process) after catching a signal, before calling
rl_cleanup_after_signal(). */
void
rl_free_line_state ()
{
register HIST_ENTRY *entry;
rl_free_undo_list ();
entry = current_history ();
if (entry)
entry->data = (char *)NULL;
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_reset_argument ();
}
#endif /* HANDLE_SIGNALS */
+1 -1
View File
@@ -1237,7 +1237,7 @@ rl_change_case (count, op)
#if defined (HANDLE_MULTIBYTE)
wchar_t wc, nwc;
char mb[MB_LEN_MAX+1];
int mblen, p;
int mblen;
mbstate_t ps;
#endif
+1637
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1111,7 +1111,7 @@ int
rl_vi_rubout (count, key)
int count, key;
{
int p, opoint;
int opoint;
if (count < 0)
return (rl_vi_delete (-count, key));
File diff suppressed because it is too large Load Diff
+1
View File
@@ -4746,6 +4746,7 @@ parse_compound_assignment (retlenp)
}
last_read_token = orig_last_token; /* XXX - was WORD? */
if (wl)
{
rl = REVERSE_LIST (wl, WORD_LIST *);
+5 -1
View File
@@ -4248,7 +4248,7 @@ decode_prompt_string (string)
break;
}
temp = (char *)xmalloc (3);
temp[0] = '\001'; /* CTLESC */
temp[0] = CTLESC;
temp[1] = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE;
temp[2] = '\0';
goto add_string;
@@ -4745,7 +4745,11 @@ parse_compound_assignment (retlenp)
jump_to_top_level (DISCARD);
}
#if 0
last_read_token = orig_last_token; /* XXX - was WORD? */
#else
last_read_token = WORD;
#endif
if (wl)
{
rl = REVERSE_LIST (wl, WORD_LIST *);
+1 -1
View File
@@ -1208,7 +1208,7 @@ run_wordexp (words)
wl = global_command->value.Simple->words;
if (protected_mode)
for (tl = wl; tl; tl = tl->next)
tl->word->flags |= W_NOCOMSUB;
tl->word->flags |= W_NOCOMSUB|W_NOPROCSUB;
result = wl ? expand_words_no_vars (wl) : (WORD_LIST *)0;
}
else
+1793
View File
File diff suppressed because it is too large Load Diff
+72 -16
View File
@@ -946,7 +946,7 @@ string_extract_verbatim (string, slen, sindex, charlist)
len = mbstowcs (wcharlist, charlist, 0);
if (len == -1)
len = 0;
wcharlist = xmalloc ((sizeof (wchar_t) * len) + 1);
wcharlist = (wchar_t *)xmalloc ((sizeof (wchar_t) * len) + 1);
mbstowcs (wcharlist, charlist, len);
}
@@ -1774,14 +1774,21 @@ char *
string_list_dollar_star (list)
WORD_LIST *list;
{
char *ret;
#if defined (HANDLE_MULTIBYTE)
# if defined (__GNUC__)
char sep[MB_CUR_MAX + 1];
# else
char *sep = 0;
# endif
#else
char sep[2];
#endif
#if defined (HANDLE_MULTIBYTE)
# if !defined (__GNUC__)
sep = (char *)xmalloc (MB_CUR_MAX + 1);
# endif /* !__GNUC__ */
if (ifs_firstc_len == 1)
{
sep[0] = ifs_firstc[0];
@@ -1797,7 +1804,11 @@ string_list_dollar_star (list)
sep[1] = '\0';
#endif
return (string_list_internal (list, sep));
ret = string_list_internal (list, sep);
#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
free (sep);
#endif
return ret;
}
/* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
@@ -1816,7 +1827,11 @@ string_list_dollar_at (list, quoted)
{
char *ifs, *ret;
#if defined (HANDLE_MULTIBYTE)
# if defined (__GNUC__)
char sep[MB_CUR_MAX + 1];
# else
char *sep = 0;
# endif /* !__GNUC__ */
#else
char sep[2];
#endif
@@ -1826,6 +1841,9 @@ string_list_dollar_at (list, quoted)
ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
#if defined (HANDLE_MULTIBYTE)
# if !defined (__GNUC__)
sep = (char *)xmalloc (MB_CUR_MAX + 1);
# endif /* !__GNUC__ */
if (ifs && *ifs)
{
if (ifs_firstc_len == 1)
@@ -1852,7 +1870,12 @@ string_list_dollar_at (list, quoted)
tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
? quote_list (list)
: list_quote_escapes (list);
return (string_list_internal (tlist, sep));
ret = string_list_internal (tlist, sep);
#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
free (sep);
#endif
return ret;
}
/* Return the list of words present in STRING. Separate the string into
@@ -2187,7 +2210,7 @@ do_compound_assignment (name, value, flags)
if (mklocal && variable_context)
{
v = find_variable (name);
if (v == 0 || array_p (v) == 0)
if (v == 0 || array_p (v) == 0 || v->context != variable_context)
v = make_local_array_variable (name);
v = assign_array_var_from_string (v, value, flags);
}
@@ -2575,6 +2598,13 @@ expand_assignment_string_to_string (string, quoted)
return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
}
char *
expand_arith_string (string)
char *string;
{
return (expand_string_if_necessary (string, Q_DOUBLE_QUOTES, expand_string));
}
#if defined (COND_COMMAND)
/* Just remove backslashes in STRING. Returns a new string. */
char *
@@ -3408,7 +3438,7 @@ remove_pattern (param, pattern, op)
free (wpattern);
n = strlen (param);
xret = xmalloc (n + 1);
xret = (char *)xmalloc (n + 1);
memset (&ps, '\0', sizeof (mbstate_t));
n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
xret[n] = '\0'; /* just to make sure */
@@ -3477,7 +3507,7 @@ match_upattern (string, pat, mtype, sp, ep)
len = STRLEN (pat);
if (pat[0] != '*' || pat[len - 1] != '*')
{
p = npat = xmalloc (len + 3);
p = npat = (char *)xmalloc (len + 3);
p1 = pat;
if (*p1 != '*')
*p++ = '*';
@@ -3621,7 +3651,7 @@ match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
len = wcslen (wpat);
if (wpat[0] != L'*' || wpat[len - 1] != L'*')
{
wp = nwpat = xmalloc ((len + 3) * sizeof (wchar_t));
wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
wp1 = wpat;
if (*wp1 != L'*')
*wp++ = L'*';
@@ -5248,7 +5278,11 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
else
t = (char *)0;
#if 0
temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string);
#else
temp1 = expand_arith_string (substr);
#endif
*e1p = evalexp (temp1, &expok);
free (temp1);
if (expok == 0)
@@ -5293,7 +5327,11 @@ verify_substring_values (value, substr, vtype, e1p, e2p)
{
t++;
temp2 = savestring (t);
#if 0
temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
#else
temp1 = expand_arith_string (temp2);
#endif
free (temp2);
t[-1] = ':';
*e2p = evalexp (temp1, &expok);
@@ -5665,11 +5703,6 @@ parameter_brace_patsub (varname, value, patsub, quoted)
vtype &= ~VT_STARSUB;
mflags = 0;
if (*patsub == '/')
{
mflags |= MATCH_GLOBREP;
patsub++;
}
/* Malloc this because expand_string_if_necessary or one of the expansion
functions in its call chain may free it on a substitution error. */
@@ -5681,7 +5714,9 @@ parameter_brace_patsub (varname, value, patsub, quoted)
if (starsub)
mflags |= MATCH_STARSUB;
if (rep = quoted_strchr (lpatsub, '/', ST_BACKSL))
/* If the pattern starts with a `/', make sure we skip over it when looking
for the replacement delimiter. */
if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
*rep++ = '\0';
else
rep = (char *)NULL;
@@ -5701,8 +5736,15 @@ parameter_brace_patsub (varname, value, patsub, quoted)
rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
}
/* ksh93 doesn't allow the match specifier to be a part of the expanded
pattern. This is an extension. */
p = pat;
if (pat && pat[0] == '#')
if (pat && pat[0] == '/')
{
mflags |= MATCH_GLOBREP|MATCH_ANY;
p++;
}
else if (pat && pat[0] == '#')
{
mflags |= MATCH_BEG;
p++;
@@ -6435,7 +6477,11 @@ param_expand (string, sindex, quoted, expanded_something,
temp2[t_index] = '\0';
/* Expand variables found inside the expression. */
#if 0
temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
#else
temp1 = expand_arith_string (temp2);
#endif
free (temp2);
arithsub:
@@ -6477,7 +6523,11 @@ comsub:
zindex = t_index;
/* Do initial variable expansion. */
#if 0
temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string);
#else
temp1 = expand_arith_string (temp);
#endif
goto arithsub;
@@ -6707,7 +6757,7 @@ add_string:
case '<':
case '>':
{
if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & W_DQUOTE) || posixly_correct)
if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
{
sindex--; /* add_character: label increments sindex */
goto add_character;
@@ -6795,6 +6845,12 @@ add_string:
if (temp && *temp && t_index > 0)
{
temp1 = bash_tilde_expand (temp, tflag);
if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
{
FREE (temp);
FREE (temp1);
goto add_character; /* tilde expansion failed */
}
free (temp);
temp = temp1;
sindex += t_index;
+8064
View File
File diff suppressed because it is too large Load Diff
+8091
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -151,6 +151,9 @@ extern char *expand_string_to_string __P((char *, int));
extern char *expand_string_unsplit_to_string __P((char *, int));
extern char *expand_assignment_string_to_string __P((char *, int));
/* Expand an arithmetic expression string */
extern char *expand_arith_string __P((char *));
/* De-quoted quoted characters in STRING. */
extern char *dequote_string __P((char *));
+260
View File
@@ -0,0 +1,260 @@
/* subst.h -- Names of externally visible functions in subst.c. */
/* Copyright (C) 1993-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. */
#if !defined (_SUBST_H_)
#define _SUBST_H_
#include "stdc.h"
/* Constants which specify how to handle backslashes and quoting in
expand_word_internal (). Q_DOUBLE_QUOTES means to use the function
slashify_in_quotes () to decide whether the backslash should be
retained. Q_HERE_DOCUMENT means slashify_in_here_document () to
decide whether to retain the backslash. Q_KEEP_BACKSLASH means
to unconditionally retain the backslash. Q_PATQUOTE means that we're
expanding a pattern ${var%#[#%]pattern} in an expansion surrounded
by double quotes. */
#define Q_DOUBLE_QUOTES 0x01
#define Q_HERE_DOCUMENT 0x02
#define Q_KEEP_BACKSLASH 0x04
#define Q_PATQUOTE 0x08
#define Q_QUOTED 0x10
#define Q_ADDEDQUOTES 0x20
#define Q_QUOTEDNULL 0x40
/* Flag values controlling how assignment statements are treated. */
#define ASS_APPEND 0x01
#define ASS_MKLOCAL 0x02
/* Remove backslashes which are quoting backquotes from STRING. Modifies
STRING, and returns a pointer to it. */
extern char * de_backslash __P((char *));
/* Replace instances of \! in a string with !. */
extern void unquote_bang __P((char *));
/* Extract the $( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$(".
Make (SINDEX) get the position just after the matching ")". */
extern char *extract_command_subst __P((char *, int *));
/* Extract the $[ construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "$[".
Make (SINDEX) get the position just after the matching "]". */
extern char *extract_arithmetic_subst __P((char *, int *));
#if defined (PROCESS_SUBSTITUTION)
/* Extract the <( or >( construct in STRING, and return a new string.
Start extracting at (SINDEX) as if we had just seen "<(".
Make (SINDEX) get the position just after the matching ")". */
extern char *extract_process_subst __P((char *, char *, int *));
#endif /* PROCESS_SUBSTITUTION */
/* Extract the name of the variable to bind to from the assignment string. */
extern char *assignment_name __P((char *));
/* Return a single string of all the words present in LIST, separating
each word with SEP. */
extern char *string_list_internal __P((WORD_LIST *, char *));
/* Return a single string of all the words present in LIST, separating
each word with a space. */
extern char *string_list __P((WORD_LIST *));
/* Turn $* into a single string, obeying POSIX rules. */
extern char *string_list_dollar_star __P((WORD_LIST *));
/* Expand $@ into a single string, obeying POSIX rules. */
extern char *string_list_dollar_at __P((WORD_LIST *, int));
/* Perform quoted null character removal on each element of LIST.
This modifies LIST. */
extern void word_list_remove_quoted_nulls __P((WORD_LIST *));
/* This performs word splitting and quoted null character removal on
STRING. */
extern WORD_LIST *list_string __P((char *, char *, int));
extern char *get_word_from_string __P((char **, char *, char **));
extern char *strip_trailing_ifs_whitespace __P((char *, char *, int));
/* Given STRING, an assignment string, get the value of the right side
of the `=', and bind it to the left side. If EXPAND is true, then
perform tilde expansion, parameter expansion, command substitution,
and arithmetic expansion on the right-hand side. Do not perform word
splitting on the result of expansion. */
extern int do_assignment __P((char *));
extern int do_assignment_no_expand __P((char *));
extern int do_word_assignment __P((WORD_DESC *));
/* Append SOURCE to TARGET at INDEX. SIZE is the current amount
of space allocated to TARGET. SOURCE can be NULL, in which
case nothing happens. Gets rid of SOURCE by free ()ing it.
Returns TARGET in case the location has changed. */
extern char *sub_append_string __P((char *, char *, int *, int *));
/* Append the textual representation of NUMBER to TARGET.
INDEX and SIZE are as in SUB_APPEND_STRING. */
extern char *sub_append_number __P((intmax_t, char *, int *, int *));
/* Return the word list that corresponds to `$*'. */
extern WORD_LIST *list_rest_of_args __P((void));
/* Make a single large string out of the dollar digit variables,
and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
case of "$*" with respect to IFS. */
extern char *string_rest_of_args __P((int));
extern int number_of_args __P((void));
/* Expand STRING by performing parameter expansion, command substitution,
and arithmetic expansion. Dequote the resulting WORD_LIST before
returning it, but do not perform word splitting. The call to
remove_quoted_nulls () is made here because word splitting normally
takes care of quote removal. */
extern WORD_LIST *expand_string_unsplit __P((char *, int));
/* Expand the rhs of an assignment statement. */
extern WORD_LIST *expand_string_assignment __P((char *, int));
/* Expand a prompt string. */
extern WORD_LIST *expand_prompt_string __P((char *, int));
/* Expand STRING just as if you were expanding a word. This also returns
a list of words. Note that filename globbing is *NOT* done for word
or string expansion, just when the shell is expanding a command. This
does parameter expansion, command substitution, arithmetic expansion,
and word splitting. Dequote the resultant WORD_LIST before returning. */
extern WORD_LIST *expand_string __P((char *, int));
/* Convenience functions that expand strings to strings, taking care of
converting the WORD_LIST * returned by the expand_string* functions
to a string and deallocating the WORD_LIST *. */
extern char *expand_string_to_string __P((char *, int));
extern char *expand_string_unsplit_to_string __P((char *, int));
extern char *expand_assignment_string_to_string __P((char *, int));
/* De-quoted quoted characters in STRING. */
extern char *dequote_string __P((char *));
/* Expand WORD, performing word splitting on the result. This does
parameter expansion, command substitution, arithmetic expansion,
word splitting, and quote removal. */
extern WORD_LIST *expand_word __P((WORD_DESC *, int));
/* Expand WORD, but do not perform word splitting on the result. This
does parameter expansion, command substitution, arithmetic expansion,
and quote removal. */
extern WORD_LIST *expand_word_unsplit __P((WORD_DESC *, int));
extern WORD_LIST *expand_word_leave_quoted __P((WORD_DESC *, int));
/* Return the value of a positional parameter. This handles values > 10. */
extern char *get_dollar_var_value __P((intmax_t));
/* Quote a string to protect it from word splitting. */
extern char *quote_string __P((char *));
/* Quote escape characters (characters special to interals of expansion)
in a string. */
extern char *quote_escapes __P((char *));
/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
backslash quoting rules for within double quotes. */
extern char *string_quote_removal __P((char *, int));
/* Perform quote removal on word WORD. This allocates and returns a new
WORD_DESC *. */
extern WORD_DESC *word_quote_removal __P((WORD_DESC *, int));
/* Perform quote removal on all words in LIST. If QUOTED is non-zero,
the members of the list are treated as if they are surrounded by
double quotes. Return a new list, or NULL if LIST is NULL. */
extern WORD_LIST *word_list_quote_removal __P((WORD_LIST *, int));
/* Called when IFS is changed to maintain some private variables. */
extern void setifs __P((SHELL_VAR *));
/* Return the value of $IFS, or " \t\n" if IFS is unset. */
extern char *getifs __P((void));
/* This splits a single word into a WORD LIST on $IFS, but only if the word
is not quoted. list_string () performs quote removal for us, even if we
don't do any splitting. */
extern WORD_LIST *word_split __P((WORD_DESC *, char *));
/* Take the list of words in LIST and do the various substitutions. Return
a new list of words which is the expanded list, and without things like
variable assignments. */
extern WORD_LIST *expand_words __P((WORD_LIST *));
/* Same as expand_words (), but doesn't hack variable or environment
variables. */
extern WORD_LIST *expand_words_no_vars __P((WORD_LIST *));
/* Perform the `normal shell expansions' on a WORD_LIST. These are
brace expansion, tilde expansion, parameter and variable substitution,
command substitution, arithmetic expansion, and word splitting. */
extern WORD_LIST *expand_words_shellexp __P((WORD_LIST *));
extern char *command_substitute __P((char *, int));
extern char *pat_subst __P((char *, char *, char *, int));
extern void unlink_fifo_list __P((void));
extern WORD_LIST *list_string_with_quotes __P((char *));
#if defined (ARRAY_VARS)
extern char *extract_array_assignment_list __P((char *, int *));
#endif
#if defined (COND_COMMAND)
extern char *remove_backslashes __P((char *));
extern char *cond_expand_word __P((WORD_DESC *, int));
#endif
#if defined (READLINE)
extern int char_is_quoted __P((char *, int));
extern int unclosed_pair __P((char *, int, char *));
extern int skip_to_delim __P((char *, int, char *));
extern WORD_LIST *split_at_delims __P((char *, int, char *, int, int *, int *));
#endif
/* Variables used to keep track of the characters in IFS. */
extern SHELL_VAR *ifs_var;
extern char *ifs_value;
extern unsigned char ifs_cmap[];
#if defined (HANDLE_MULTIBYTE)
extern unsigned char ifs_firstc[];
extern size_t ifs_firstc_len;
#else
extern unsigned char ifs_firstc;
#endif
/* Evaluates to 1 if C is a character in $IFS. */
#define isifs(c) (ifs_cmap[(unsigned char)(c)] != 0)
/* How to determine the quoted state of the character C. */
#define QUOTED_CHAR(c) ((c) == CTLESC)
/* Is the first character of STRING a quoted NULL character? */
#define QUOTED_NULL(string) ((string)[0] == CTLNUL && (string)[1] == '\0')
#endif /* !_SUBST_H_ */
+4 -2
View File
@@ -53,8 +53,10 @@ LOCAL_CFLAGS = @LOCAL_CFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
LIBS = @LIBS@
LIBS_FOR_BUILD = ${LIBS} # XXX
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS_FOR_BUILD = $(LDFLAGS)
@@ -76,7 +78,7 @@ OBJ1 = man2html.o
all: man2html$(EXEEXT)
man2html$(EXEEXT): $(OBJ1)
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) $(OBJ1) -o $@ ${LIBS}
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) $(OBJ1) -o $@ ${LIBS_FOR_BUILD}
clean:
$(RM) man2html$(EXEEXT)
+87
View File
@@ -0,0 +1,87 @@
#
# Simple Makefile for the support programs.
#
# documentation support: man2html
# testing support: printenv recho zecho
#
# bashbug lives here but is created by the top-level makefile
#
# Currently only man2html is built
#
#
# Copyright (C) 1998 Free Software Foundation, Inc.
# This program 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.
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
#
# Boilerplate
#
topdir = @top_srcdir@
srcdir = @srcdir@
VPATH = .:@srcdir@
BUILD_DIR = @BUILD_DIR@
RM = rm -f
SHELL = @MAKE_SHELL@
CC = @CC@
CC_FOR_BUILD = @CC_FOR_BUILD@
EXEEXT = @EXEEXT@
#
# Compiler options:
#
PROFILE_FLAGS = @PROFILE_FLAGS@
CFLAGS = @CFLAGS@
CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
CPPFLAGS = @CPPFLAGS@
CPPFLAGS_FOR_BUILD = @CPPFLAGS_FOR_BUILD@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
LIBS = @LIBS@
LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
LDFLAGS_FOR_BUILD = $(LDFLAGS)
INCLUDES = -I${BUILD_DIR} -I${topdir}
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
${INCLUDES} $(LOCAL_CFLAGS)
CCFLAGS = $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
SRC1 = man2html.c
OBJ1 = man2html.o
.c.o:
$(RM) $@
$(CC_FOR_BUILD) -c $(CCFLAGS_FOR_BUILD) $<
all: man2html$(EXEEXT)
man2html$(EXEEXT): $(OBJ1)
$(CC_FOR_BUILD) $(CCFLAGS_FOR_BUILD) $(OBJ1) -o $@ ${LIBS}
clean:
$(RM) man2html$(EXEEXT)
distclean maintainer-clean mostlyclean: clean
$(RM) $(OBJ1)
man2html.o: man2html.c
+16 -354
View File
@@ -1,7 +1,7 @@
/* signames.c -- Create and write `signames.h', which contains an array of
/* mksignames.c -- Create and write `signames.h', which contains an array of
signal names. */
/* Copyright (C) 1992-2003 Free Software Foundation, Inc.
/* Copyright (C) 1992-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -22,371 +22,25 @@
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
/* Duplicated from signames.c */
#if !defined (NSIG)
# define NSIG 64
#endif
/*
* Special traps:
* EXIT == 0
* DEBUG == NSIG
* ERR == NSIG+1
* RETURN == NSIG+2
*/
#define LASTSIG NSIG+2
char *signal_names[2 * (LASTSIG)];
#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
/* Imported from signames.c */
extern void initialize_signames ();
extern char *signal_names[];
char *progname;
/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
I don't want to allocate so much unused space for the intervening signal
numbers, so we just punt if SIGRTMAX is past the bounds of the
signal_names array (handled in configure). */
#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
# undef SIGRTMAX
# undef SIGRTMIN
#endif
#if defined (SIGRTMAX) || defined (SIGRTMIN)
# define RTLEN 14
# define RTLIM 256
#endif
void
initialize_signames ()
{
register int i;
#if defined (SIGRTMAX) || defined (SIGRTMIN)
int rtmin, rtmax, rtcnt;
#endif
for (i = 1; i < signal_names_size; i++)
signal_names[i] = (char *)NULL;
/* `signal' 0 is what we do on exit. */
signal_names[0] = "EXIT";
/* Place signal names which can be aliases for more common signal
names first. This allows (for example) SIGABRT to overwrite SIGLOST. */
/* POSIX 1003.1b-1993 real time signals, but take care of incomplete
implementations. Acoording to the standard, both, SIGRTMIN and
SIGRTMAX must be defined, SIGRTMIN must be stricly less than
SIGRTMAX, and the difference must be at least 7, that is, there
must be at least eight distinct real time signals. */
/* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
of RT signals is odd, there is an extra SIGRTMIN+(x+1).
These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
#if defined (SIGRTMIN)
rtmin = SIGRTMIN;
signal_names[rtmin] = "SIGRTMIN";
#endif
#if defined (SIGRTMAX)
rtmax = SIGRTMAX;
signal_names[rtmax] = "SIGRTMAX";
#endif
#if defined (SIGRTMAX) && defined (SIGRTMIN)
if (rtmax > rtmin)
{
rtcnt = (rtmax - rtmin - 1) / 2;
/* croak if there are too many RT signals */
if (rtcnt >= RTLIM/2)
{
rtcnt = RTLIM/2-1;
fprintf(stderr, "%s: error: more than %i real time signals, fix `%s'\n",
progname, RTLIM, progname);
}
for (i = 1; i <= rtcnt; i++)
{
signal_names[rtmin+i] = (char *)malloc(RTLEN);
if (signal_names[rtmin+i])
sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i);
signal_names[rtmax-i] = (char *)malloc(RTLEN);
if (signal_names[rtmax-i])
sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i);
}
if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
{
/* Need an extra RTMIN signal */
signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
if (signal_names[rtmin+rtcnt+1])
sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1);
}
}
#endif /* SIGRTMIN && SIGRTMAX */
#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */
signal_names[SIGLOST] = "SIGLOST";
#endif
/* AIX */
#if defined (SIGMSG) /* HFT input data pending */
signal_names[SIGMSG] = "SIGMSG";
#endif
#if defined (SIGDANGER) /* system crash imminent */
signal_names[SIGDANGER] = "SIGDANGER";
#endif
#if defined (SIGMIGRATE) /* migrate process to another CPU */
signal_names[SIGMIGRATE] = "SIGMIGRATE";
#endif
#if defined (SIGPRE) /* programming error */
signal_names[SIGPRE] = "SIGPRE";
#endif
#if defined (SIGVIRT) /* AIX virtual time alarm */
signal_names[SIGVIRT] = "SIGVIRT";
#endif
#if defined (SIGALRM1) /* m:n condition variables */
signal_names[SIGALRM1] = "SIGALRM1";
#endif
#if defined (SIGWAITING) /* m:n scheduling */
signal_names[SIGWAITING] = "SIGWAITING";
#endif
#if defined (SIGGRANT) /* HFT monitor mode granted */
signal_names[SIGGRANT] = "SIGGRANT";
#endif
#if defined (SIGKAP) /* keep alive poll from native keyboard */
signal_names[SIGKAP] = "SIGKAP";
#endif
#if defined (SIGRETRACT) /* HFT monitor mode retracted */
signal_names[SIGRETRACT] = "SIGRETRACT";
#endif
#if defined (SIGSOUND) /* HFT sound sequence has completed */
signal_names[SIGSOUND] = "SIGSOUND";
#endif
#if defined (SIGSAK) /* Secure Attention Key */
signal_names[SIGSAK] = "SIGSAK";
#endif
/* SunOS5 */
#if defined (SIGLWP) /* special signal used by thread library */
signal_names[SIGLWP] = "SIGLWP";
#endif
#if defined (SIGFREEZE) /* special signal used by CPR */
signal_names[SIGFREEZE] = "SIGFREEZE";
#endif
#if defined (SIGTHAW) /* special signal used by CPR */
signal_names[SIGTHAW] = "SIGTHAW";
#endif
#if defined (SIGCANCEL) /* thread cancellation signal used by libthread */
signal_names[SIGCANCEL] = "SIGCANCEL";
#endif
#if defined (SIGXRES) /* resource control exceeded */
signal_names[SIGXRES] = "SIGXRES";
#endif
/* HP-UX */
#if defined (SIGDIL) /* DIL signal (?) */
signal_names[SIGDIL] = "SIGDIL";
#endif
/* System V */
#if defined (SIGCLD) /* Like SIGCHLD. */
signal_names[SIGCLD] = "SIGCLD";
#endif
#if defined (SIGPWR) /* power state indication */
signal_names[SIGPWR] = "SIGPWR";
#endif
#if defined (SIGPOLL) /* Pollable event (for streams) */
signal_names[SIGPOLL] = "SIGPOLL";
#endif
/* Unknown */
#if defined (SIGWINDOW)
signal_names[SIGWINDOW] = "SIGWINDOW";
#endif
/* Linux */
#if defined (SIGSTKFLT)
signal_names[SIGSTKFLT] = "SIGSTKFLT";
#endif
/* FreeBSD */
#if defined (SIGTHR) /* thread interrupt */
signal_names[SIGTHR] = "SIGTHR";
#endif
/* Common */
#if defined (SIGHUP) /* hangup */
signal_names[SIGHUP] = "SIGHUP";
#endif
#if defined (SIGINT) /* interrupt */
signal_names[SIGINT] = "SIGINT";
#endif
#if defined (SIGQUIT) /* quit */
signal_names[SIGQUIT] = "SIGQUIT";
#endif
#if defined (SIGILL) /* illegal instruction (not reset when caught) */
signal_names[SIGILL] = "SIGILL";
#endif
#if defined (SIGTRAP) /* trace trap (not reset when caught) */
signal_names[SIGTRAP] = "SIGTRAP";
#endif
#if defined (SIGIOT) /* IOT instruction */
signal_names[SIGIOT] = "SIGIOT";
#endif
#if defined (SIGABRT) /* Cause current process to dump core. */
signal_names[SIGABRT] = "SIGABRT";
#endif
#if defined (SIGEMT) /* EMT instruction */
signal_names[SIGEMT] = "SIGEMT";
#endif
#if defined (SIGFPE) /* floating point exception */
signal_names[SIGFPE] = "SIGFPE";
#endif
#if defined (SIGKILL) /* kill (cannot be caught or ignored) */
signal_names[SIGKILL] = "SIGKILL";
#endif
#if defined (SIGBUS) /* bus error */
signal_names[SIGBUS] = "SIGBUS";
#endif
#if defined (SIGSEGV) /* segmentation violation */
signal_names[SIGSEGV] = "SIGSEGV";
#endif
#if defined (SIGSYS) /* bad argument to system call */
signal_names[SIGSYS] = "SIGSYS";
#endif
#if defined (SIGPIPE) /* write on a pipe with no one to read it */
signal_names[SIGPIPE] = "SIGPIPE";
#endif
#if defined (SIGALRM) /* alarm clock */
signal_names[SIGALRM] = "SIGALRM";
#endif
#if defined (SIGTERM) /* software termination signal from kill */
signal_names[SIGTERM] = "SIGTERM";
#endif
#if defined (SIGURG) /* urgent condition on IO channel */
signal_names[SIGURG] = "SIGURG";
#endif
#if defined (SIGSTOP) /* sendable stop signal not from tty */
signal_names[SIGSTOP] = "SIGSTOP";
#endif
#if defined (SIGTSTP) /* stop signal from tty */
signal_names[SIGTSTP] = "SIGTSTP";
#endif
#if defined (SIGCONT) /* continue a stopped process */
signal_names[SIGCONT] = "SIGCONT";
#endif
#if defined (SIGCHLD) /* to parent on child stop or exit */
signal_names[SIGCHLD] = "SIGCHLD";
#endif
#if defined (SIGTTIN) /* to readers pgrp upon background tty read */
signal_names[SIGTTIN] = "SIGTTIN";
#endif
#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local&LTOSTOP) */
signal_names[SIGTTOU] = "SIGTTOU";
#endif
#if defined (SIGIO) /* input/output possible signal */
signal_names[SIGIO] = "SIGIO";
#endif
#if defined (SIGXCPU) /* exceeded CPU time limit */
signal_names[SIGXCPU] = "SIGXCPU";
#endif
#if defined (SIGXFSZ) /* exceeded file size limit */
signal_names[SIGXFSZ] = "SIGXFSZ";
#endif
#if defined (SIGVTALRM) /* virtual time alarm */
signal_names[SIGVTALRM] = "SIGVTALRM";
#endif
#if defined (SIGPROF) /* profiling time alarm */
signal_names[SIGPROF] = "SIGPROF";
#endif
#if defined (SIGWINCH) /* window changed */
signal_names[SIGWINCH] = "SIGWINCH";
#endif
/* 4.4 BSD */
#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */
signal_names[SIGINFO] = "SIGINFO";
#endif
#if defined (SIGUSR1) /* user defined signal 1 */
signal_names[SIGUSR1] = "SIGUSR1";
#endif
#if defined (SIGUSR2) /* user defined signal 2 */
signal_names[SIGUSR2] = "SIGUSR2";
#endif
#if defined (SIGKILLTHR) /* BeOS: Kill Thread */
signal_names[SIGKILLTHR] = "SIGKILLTHR";
#endif
for (i = 0; i < NSIG; i++)
if (signal_names[i] == (char *)NULL)
{
signal_names[i] = (char *)malloc (18);
if (signal_names[i])
sprintf (signal_names[i], "SIGJUNK(%d)", i);
}
signal_names[NSIG] = "DEBUG";
signal_names[NSIG+1] = "ERR";
signal_names[NSIG+2] = "RETURN";
}
void
write_signames (stream)
FILE *stream;
@@ -395,16 +49,22 @@ write_signames (stream)
fprintf (stream, "/* This file was automatically created by %s.\n",
progname);
fprintf (stream, " Do not edit. Edit support/mksignames.c instead. */\n\n");
fprintf (stream, " Do not edit. Edit support/signames.c instead. */\n\n");
fprintf (stream,
"/* A translation list so we can be polite to our users. */\n");
#if defined (CROSS_COMPILING)
fprintf (stream, "extern char *signal_names[];\n\n");
fprintf (stream, "extern void initialize_signames __P((void));\n\n");
#else
fprintf (stream, "char *signal_names[NSIG + 4] = {\n");
for (i = 0; i <= LASTSIG; i++)
fprintf (stream, " \"%s\",\n", signal_names[i]);
fprintf (stream, " (char *)0x0\n");
fprintf (stream, "};\n");
fprintf (stream, "};\n\n");
fprintf (stream, "#define initialize_signames()\n\n");
#endif
}
int
@@ -440,7 +100,9 @@ main (argc, argv)
exit (2);
}
#if !defined (CROSS_COMPILING)
initialize_signames ();
#endif
write_signames (stream);
exit (0);
}
+446
View File
@@ -0,0 +1,446 @@
/* mksignames.c -- Create and write `signames.h', which contains an array of
signal names. */
/* Copyright (C) 1992-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. */
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if !defined (NSIG)
# define NSIG 64
#endif
/*
* Special traps:
* EXIT == 0
* DEBUG == NSIG
* ERR == NSIG+1
* RETURN == NSIG+2
*/
#define LASTSIG NSIG+2
char *signal_names[2 * (LASTSIG)];
#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
char *progname;
/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
I don't want to allocate so much unused space for the intervening signal
numbers, so we just punt if SIGRTMAX is past the bounds of the
signal_names array (handled in configure). */
#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
# undef SIGRTMAX
# undef SIGRTMIN
#endif
#if defined (SIGRTMAX) || defined (SIGRTMIN)
# define RTLEN 14
# define RTLIM 256
#endif
void
initialize_signames ()
{
register int i;
#if defined (SIGRTMAX) || defined (SIGRTMIN)
int rtmin, rtmax, rtcnt;
#endif
for (i = 1; i < signal_names_size; i++)
signal_names[i] = (char *)NULL;
/* `signal' 0 is what we do on exit. */
signal_names[0] = "EXIT";
/* Place signal names which can be aliases for more common signal
names first. This allows (for example) SIGABRT to overwrite SIGLOST. */
/* POSIX 1003.1b-1993 real time signals, but take care of incomplete
implementations. Acoording to the standard, both, SIGRTMIN and
SIGRTMAX must be defined, SIGRTMIN must be stricly less than
SIGRTMAX, and the difference must be at least 7, that is, there
must be at least eight distinct real time signals. */
/* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
of RT signals is odd, there is an extra SIGRTMIN+(x+1).
These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
#if defined (SIGRTMIN)
rtmin = SIGRTMIN;
signal_names[rtmin] = "SIGRTMIN";
#endif
#if defined (SIGRTMAX)
rtmax = SIGRTMAX;
signal_names[rtmax] = "SIGRTMAX";
#endif
#if defined (SIGRTMAX) && defined (SIGRTMIN)
if (rtmax > rtmin)
{
rtcnt = (rtmax - rtmin - 1) / 2;
/* croak if there are too many RT signals */
if (rtcnt >= RTLIM/2)
{
rtcnt = RTLIM/2-1;
fprintf(stderr, "%s: error: more than %d real time signals, fix `%s'\n",
progname, RTLIM, progname);
}
for (i = 1; i <= rtcnt; i++)
{
signal_names[rtmin+i] = (char *)malloc(RTLEN);
if (signal_names[rtmin+i])
sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i);
signal_names[rtmax-i] = (char *)malloc(RTLEN);
if (signal_names[rtmax-i])
sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i);
}
if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
{
/* Need an extra RTMIN signal */
signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
if (signal_names[rtmin+rtcnt+1])
sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1);
}
}
#endif /* SIGRTMIN && SIGRTMAX */
#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */
signal_names[SIGLOST] = "SIGLOST";
#endif
/* AIX */
#if defined (SIGMSG) /* HFT input data pending */
signal_names[SIGMSG] = "SIGMSG";
#endif
#if defined (SIGDANGER) /* system crash imminent */
signal_names[SIGDANGER] = "SIGDANGER";
#endif
#if defined (SIGMIGRATE) /* migrate process to another CPU */
signal_names[SIGMIGRATE] = "SIGMIGRATE";
#endif
#if defined (SIGPRE) /* programming error */
signal_names[SIGPRE] = "SIGPRE";
#endif
#if defined (SIGVIRT) /* AIX virtual time alarm */
signal_names[SIGVIRT] = "SIGVIRT";
#endif
#if defined (SIGALRM1) /* m:n condition variables */
signal_names[SIGALRM1] = "SIGALRM1";
#endif
#if defined (SIGWAITING) /* m:n scheduling */
signal_names[SIGWAITING] = "SIGWAITING";
#endif
#if defined (SIGGRANT) /* HFT monitor mode granted */
signal_names[SIGGRANT] = "SIGGRANT";
#endif
#if defined (SIGKAP) /* keep alive poll from native keyboard */
signal_names[SIGKAP] = "SIGKAP";
#endif
#if defined (SIGRETRACT) /* HFT monitor mode retracted */
signal_names[SIGRETRACT] = "SIGRETRACT";
#endif
#if defined (SIGSOUND) /* HFT sound sequence has completed */
signal_names[SIGSOUND] = "SIGSOUND";
#endif
#if defined (SIGSAK) /* Secure Attention Key */
signal_names[SIGSAK] = "SIGSAK";
#endif
/* SunOS5 */
#if defined (SIGLWP) /* special signal used by thread library */
signal_names[SIGLWP] = "SIGLWP";
#endif
#if defined (SIGFREEZE) /* special signal used by CPR */
signal_names[SIGFREEZE] = "SIGFREEZE";
#endif
#if defined (SIGTHAW) /* special signal used by CPR */
signal_names[SIGTHAW] = "SIGTHAW";
#endif
#if defined (SIGCANCEL) /* thread cancellation signal used by libthread */
signal_names[SIGCANCEL] = "SIGCANCEL";
#endif
#if defined (SIGXRES) /* resource control exceeded */
signal_names[SIGXRES] = "SIGXRES";
#endif
/* HP-UX */
#if defined (SIGDIL) /* DIL signal (?) */
signal_names[SIGDIL] = "SIGDIL";
#endif
/* System V */
#if defined (SIGCLD) /* Like SIGCHLD. */
signal_names[SIGCLD] = "SIGCLD";
#endif
#if defined (SIGPWR) /* power state indication */
signal_names[SIGPWR] = "SIGPWR";
#endif
#if defined (SIGPOLL) /* Pollable event (for streams) */
signal_names[SIGPOLL] = "SIGPOLL";
#endif
/* Unknown */
#if defined (SIGWINDOW)
signal_names[SIGWINDOW] = "SIGWINDOW";
#endif
/* Linux */
#if defined (SIGSTKFLT)
signal_names[SIGSTKFLT] = "SIGSTKFLT";
#endif
/* FreeBSD */
#if defined (SIGTHR) /* thread interrupt */
signal_names[SIGTHR] = "SIGTHR";
#endif
/* Common */
#if defined (SIGHUP) /* hangup */
signal_names[SIGHUP] = "SIGHUP";
#endif
#if defined (SIGINT) /* interrupt */
signal_names[SIGINT] = "SIGINT";
#endif
#if defined (SIGQUIT) /* quit */
signal_names[SIGQUIT] = "SIGQUIT";
#endif
#if defined (SIGILL) /* illegal instruction (not reset when caught) */
signal_names[SIGILL] = "SIGILL";
#endif
#if defined (SIGTRAP) /* trace trap (not reset when caught) */
signal_names[SIGTRAP] = "SIGTRAP";
#endif
#if defined (SIGIOT) /* IOT instruction */
signal_names[SIGIOT] = "SIGIOT";
#endif
#if defined (SIGABRT) /* Cause current process to dump core. */
signal_names[SIGABRT] = "SIGABRT";
#endif
#if defined (SIGEMT) /* EMT instruction */
signal_names[SIGEMT] = "SIGEMT";
#endif
#if defined (SIGFPE) /* floating point exception */
signal_names[SIGFPE] = "SIGFPE";
#endif
#if defined (SIGKILL) /* kill (cannot be caught or ignored) */
signal_names[SIGKILL] = "SIGKILL";
#endif
#if defined (SIGBUS) /* bus error */
signal_names[SIGBUS] = "SIGBUS";
#endif
#if defined (SIGSEGV) /* segmentation violation */
signal_names[SIGSEGV] = "SIGSEGV";
#endif
#if defined (SIGSYS) /* bad argument to system call */
signal_names[SIGSYS] = "SIGSYS";
#endif
#if defined (SIGPIPE) /* write on a pipe with no one to read it */
signal_names[SIGPIPE] = "SIGPIPE";
#endif
#if defined (SIGALRM) /* alarm clock */
signal_names[SIGALRM] = "SIGALRM";
#endif
#if defined (SIGTERM) /* software termination signal from kill */
signal_names[SIGTERM] = "SIGTERM";
#endif
#if defined (SIGURG) /* urgent condition on IO channel */
signal_names[SIGURG] = "SIGURG";
#endif
#if defined (SIGSTOP) /* sendable stop signal not from tty */
signal_names[SIGSTOP] = "SIGSTOP";
#endif
#if defined (SIGTSTP) /* stop signal from tty */
signal_names[SIGTSTP] = "SIGTSTP";
#endif
#if defined (SIGCONT) /* continue a stopped process */
signal_names[SIGCONT] = "SIGCONT";
#endif
#if defined (SIGCHLD) /* to parent on child stop or exit */
signal_names[SIGCHLD] = "SIGCHLD";
#endif
#if defined (SIGTTIN) /* to readers pgrp upon background tty read */
signal_names[SIGTTIN] = "SIGTTIN";
#endif
#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local&LTOSTOP) */
signal_names[SIGTTOU] = "SIGTTOU";
#endif
#if defined (SIGIO) /* input/output possible signal */
signal_names[SIGIO] = "SIGIO";
#endif
#if defined (SIGXCPU) /* exceeded CPU time limit */
signal_names[SIGXCPU] = "SIGXCPU";
#endif
#if defined (SIGXFSZ) /* exceeded file size limit */
signal_names[SIGXFSZ] = "SIGXFSZ";
#endif
#if defined (SIGVTALRM) /* virtual time alarm */
signal_names[SIGVTALRM] = "SIGVTALRM";
#endif
#if defined (SIGPROF) /* profiling time alarm */
signal_names[SIGPROF] = "SIGPROF";
#endif
#if defined (SIGWINCH) /* window changed */
signal_names[SIGWINCH] = "SIGWINCH";
#endif
/* 4.4 BSD */
#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */
signal_names[SIGINFO] = "SIGINFO";
#endif
#if defined (SIGUSR1) /* user defined signal 1 */
signal_names[SIGUSR1] = "SIGUSR1";
#endif
#if defined (SIGUSR2) /* user defined signal 2 */
signal_names[SIGUSR2] = "SIGUSR2";
#endif
#if defined (SIGKILLTHR) /* BeOS: Kill Thread */
signal_names[SIGKILLTHR] = "SIGKILLTHR";
#endif
for (i = 0; i < NSIG; i++)
if (signal_names[i] == (char *)NULL)
{
signal_names[i] = (char *)malloc (18);
if (signal_names[i])
sprintf (signal_names[i], "SIGJUNK(%d)", i);
}
signal_names[NSIG] = "DEBUG";
signal_names[NSIG+1] = "ERR";
signal_names[NSIG+2] = "RETURN";
}
void
write_signames (stream)
FILE *stream;
{
register int i;
fprintf (stream, "/* This file was automatically created by %s.\n",
progname);
fprintf (stream, " Do not edit. Edit support/mksignames.c instead. */\n\n");
fprintf (stream,
"/* A translation list so we can be polite to our users. */\n");
fprintf (stream, "char *signal_names[NSIG + 4] = {\n");
for (i = 0; i <= LASTSIG; i++)
fprintf (stream, " \"%s\",\n", signal_names[i]);
fprintf (stream, " (char *)0x0\n");
fprintf (stream, "};\n");
}
int
main (argc, argv)
int argc;
char **argv;
{
char *stream_name;
FILE *stream;
progname = argv[0];
if (argc == 1)
{
stream_name = "stdout";
stream = stdout;
}
else if (argc == 2)
{
stream_name = argv[1];
stream = fopen (stream_name, "w");
}
else
{
fprintf (stderr, "Usage: %s [output-file]\n", progname);
exit (1);
}
if (!stream)
{
fprintf (stderr, "%s: %s: cannot open for writing\n",
progname, stream_name);
exit (2);
}
initialize_signames ();
write_signames (stream);
exit (0);
}
+110
View File
@@ -0,0 +1,110 @@
/* mksignames.c -- Create and write `signames.h', which contains an array of
signal names. */
/* Copyright (C) 1992-2006 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>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
/* Duplicated from signames.c */
#if !defined (NSIG)
# define NSIG 64
#endif
#define LASTSIG NSIG+2
/* Imported from signames.c */
extern void initialize_signames ();
extern char *signal_names[];
char *progname;
void
write_signames (stream)
FILE *stream;
{
register int i;
fprintf (stream, "/* This file was automatically created by %s.\n",
progname);
fprintf (stream, " Do not edit. Edit support/signames.c instead. */\n\n");
fprintf (stream,
"/* A translation list so we can be polite to our users. */\n");
#if defined (CROSS_COMPILING)
fprintf (stream, "extern char *signal_names[];\n\n");
fprintf (stream, "extern void initialize_signames __P((void))\n\n");
#else
fprintf (stream, "char *signal_names[NSIG + 4] = {\n");
for (i = 0; i <= LASTSIG; i++)
fprintf (stream, " \"%s\",\n", signal_names[i]);
fprintf (stream, " (char *)0x0\n");
fprintf (stream, "};\n\n");
fprintf (stream, "#define initialize_signames()\n\n");
#endif
}
int
main (argc, argv)
int argc;
char **argv;
{
char *stream_name;
FILE *stream;
progname = argv[0];
if (argc == 1)
{
stream_name = "stdout";
stream = stdout;
}
else if (argc == 2)
{
stream_name = argv[1];
stream = fopen (stream_name, "w");
}
else
{
fprintf (stderr, "Usage: %s [output-file]\n", progname);
exit (1);
}
if (!stream)
{
fprintf (stderr, "%s: %s: cannot open for writing\n",
progname, stream_name);
exit (2);
}
#if !defined (CROSS_COMPILING)
initialize_signames ();
#endif
write_signames (stream);
exit (0);
}
+393
View File
@@ -0,0 +1,393 @@
/* signames.c -- Create an array of signal names. */
/* Copyright (C) 2006 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>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if !defined (NSIG)
# define NSIG 64
#endif
/*
* Special traps:
* EXIT == 0
* DEBUG == NSIG
* ERR == NSIG+1
* RETURN == NSIG+2
*/
#define LASTSIG NSIG+2
char *signal_names[2 * (LASTSIG)];
#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
I don't want to allocate so much unused space for the intervening signal
numbers, so we just punt if SIGRTMAX is past the bounds of the
signal_names array (handled in configure). */
#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
# undef SIGRTMAX
# undef SIGRTMIN
#endif
#if defined (SIGRTMAX) || defined (SIGRTMIN)
# define RTLEN 14
# define RTLIM 256
#endif
#if defined (BUILDTOOL)
extern char *progname;
#endif
void
initialize_signames ()
{
register int i;
#if defined (SIGRTMAX) || defined (SIGRTMIN)
int rtmin, rtmax, rtcnt;
#endif
for (i = 1; i < signal_names_size; i++)
signal_names[i] = (char *)NULL;
/* `signal' 0 is what we do on exit. */
signal_names[0] = "EXIT";
/* Place signal names which can be aliases for more common signal
names first. This allows (for example) SIGABRT to overwrite SIGLOST. */
/* POSIX 1003.1b-1993 real time signals, but take care of incomplete
implementations. Acoording to the standard, both, SIGRTMIN and
SIGRTMAX must be defined, SIGRTMIN must be stricly less than
SIGRTMAX, and the difference must be at least 7, that is, there
must be at least eight distinct real time signals. */
/* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
of RT signals is odd, there is an extra SIGRTMIN+(x+1).
These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
#if defined (SIGRTMIN)
rtmin = SIGRTMIN;
signal_names[rtmin] = "SIGRTMIN";
#endif
#if defined (SIGRTMAX)
rtmax = SIGRTMAX;
signal_names[rtmax] = "SIGRTMAX";
#endif
#if defined (SIGRTMAX) && defined (SIGRTMIN)
if (rtmax > rtmin)
{
rtcnt = (rtmax - rtmin - 1) / 2;
/* croak if there are too many RT signals */
if (rtcnt >= RTLIM/2)
{
rtcnt = RTLIM/2-1;
#ifdef BUILDTOOL
fprintf(stderr, "%s: error: more than %d real time signals, fix `%s'\n",
progname, RTLIM, progname);
#endif
}
for (i = 1; i <= rtcnt; i++)
{
signal_names[rtmin+i] = (char *)malloc(RTLEN);
if (signal_names[rtmin+i])
sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i);
signal_names[rtmax-i] = (char *)malloc(RTLEN);
if (signal_names[rtmax-i])
sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i);
}
if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
{
/* Need an extra RTMIN signal */
signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
if (signal_names[rtmin+rtcnt+1])
sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1);
v }
}
#endif /* SIGRTMIN && SIGRTMAX */
#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */
signal_names[SIGLOST] = "SIGLOST";
#endif
/* AIX */
#if defined (SIGMSG) /* HFT input data pending */
signal_names[SIGMSG] = "SIGMSG";
#endif
#if defined (SIGDANGER) /* system crash imminent */
signal_names[SIGDANGER] = "SIGDANGER";
#endif
#if defined (SIGMIGRATE) /* migrate process to another CPU */
signal_names[SIGMIGRATE] = "SIGMIGRATE";
#endif
#if defined (SIGPRE) /* programming error */
signal_names[SIGPRE] = "SIGPRE";
#endif
#if defined (SIGVIRT) /* AIX virtual time alarm */
signal_names[SIGVIRT] = "SIGVIRT";
#endif
#if defined (SIGALRM1) /* m:n condition variables */
signal_names[SIGALRM1] = "SIGALRM1";
#endif
#if defined (SIGWAITING) /* m:n scheduling */
signal_names[SIGWAITING] = "SIGWAITING";
#endif
#if defined (SIGGRANT) /* HFT monitor mode granted */
signal_names[SIGGRANT] = "SIGGRANT";
#endif
#if defined (SIGKAP) /* keep alive poll from native keyboard */
signal_names[SIGKAP] = "SIGKAP";
#endif
#if defined (SIGRETRACT) /* HFT monitor mode retracted */
signal_names[SIGRETRACT] = "SIGRETRACT";
#endif
#if defined (SIGSOUND) /* HFT sound sequence has completed */
signal_names[SIGSOUND] = "SIGSOUND";
#endif
#if defined (SIGSAK) /* Secure Attention Key */
signal_names[SIGSAK] = "SIGSAK";
#endif
/* SunOS5 */
#if defined (SIGLWP) /* special signal used by thread library */
signal_names[SIGLWP] = "SIGLWP";
#endif
#if defined (SIGFREEZE) /* special signal used by CPR */
signal_names[SIGFREEZE] = "SIGFREEZE";
#endif
#if defined (SIGTHAW) /* special signal used by CPR */
signal_names[SIGTHAW] = "SIGTHAW";
#endif
#if defined (SIGCANCEL) /* thread cancellation signal used by libthread */
signal_names[SIGCANCEL] = "SIGCANCEL";
#endif
#if defined (SIGXRES) /* resource control exceeded */
signal_names[SIGXRES] = "SIGXRES";
#endif
/* HP-UX */
#if defined (SIGDIL) /* DIL signal (?) */
signal_names[SIGDIL] = "SIGDIL";
#endif
/* System V */
#if defined (SIGCLD) /* Like SIGCHLD. */
signal_names[SIGCLD] = "SIGCLD";
#endif
#if defined (SIGPWR) /* power state indication */
signal_names[SIGPWR] = "SIGPWR";
#endif
#if defined (SIGPOLL) /* Pollable event (for streams) */
signal_names[SIGPOLL] = "SIGPOLL";
#endif
/* Unknown */
#if defined (SIGWINDOW)
signal_names[SIGWINDOW] = "SIGWINDOW";
#endif
/* Linux */
#if defined (SIGSTKFLT)
signal_names[SIGSTKFLT] = "SIGSTKFLT";
#endif
/* FreeBSD */
#if defined (SIGTHR) /* thread interrupt */
signal_names[SIGTHR] = "SIGTHR";
#endif
/* Common */
#if defined (SIGHUP) /* hangup */
signal_names[SIGHUP] = "SIGHUP";
#endif
#if defined (SIGINT) /* interrupt */
signal_names[SIGINT] = "SIGINT";
#endif
#if defined (SIGQUIT) /* quit */
signal_names[SIGQUIT] = "SIGQUIT";
#endif
#if defined (SIGILL) /* illegal instruction (not reset when caught) */
signal_names[SIGILL] = "SIGILL";
#endif
#if defined (SIGTRAP) /* trace trap (not reset when caught) */
signal_names[SIGTRAP] = "SIGTRAP";
#endif
#if defined (SIGIOT) /* IOT instruction */
signal_names[SIGIOT] = "SIGIOT";
#endif
#if defined (SIGABRT) /* Cause current process to dump core. */
signal_names[SIGABRT] = "SIGABRT";
#endif
#if defined (SIGEMT) /* EMT instruction */
signal_names[SIGEMT] = "SIGEMT";
#endif
#if defined (SIGFPE) /* floating point exception */
signal_names[SIGFPE] = "SIGFPE";
#endif
#if defined (SIGKILL) /* kill (cannot be caught or ignored) */
signal_names[SIGKILL] = "SIGKILL";
#endif
#if defined (SIGBUS) /* bus error */
signal_names[SIGBUS] = "SIGBUS";
#endif
#if defined (SIGSEGV) /* segmentation violation */
signal_names[SIGSEGV] = "SIGSEGV";
#endif
#if defined (SIGSYS) /* bad argument to system call */
signal_names[SIGSYS] = "SIGSYS";
#endif
#if defined (SIGPIPE) /* write on a pipe with no one to read it */
signal_names[SIGPIPE] = "SIGPIPE";
#endif
#if defined (SIGALRM) /* alarm clock */
signal_names[SIGALRM] = "SIGALRM";
#endif
#if defined (SIGTERM) /* software termination signal from kill */
signal_names[SIGTERM] = "SIGTERM";
#endif
#if defined (SIGURG) /* urgent condition on IO channel */
signal_names[SIGURG] = "SIGURG";
#endif
#if defined (SIGSTOP) /* sendable stop signal not from tty */
signal_names[SIGSTOP] = "SIGSTOP";
#endif
#if defined (SIGTSTP) /* stop signal from tty */
signal_names[SIGTSTP] = "SIGTSTP";
#endif
#if defined (SIGCONT) /* continue a stopped process */
signal_names[SIGCONT] = "SIGCONT";
#endif
#if defined (SIGCHLD) /* to parent on child stop or exit */
signal_names[SIGCHLD] = "SIGCHLD";
#endif
#if defined (SIGTTIN) /* to readers pgrp upon background tty read */
signal_names[SIGTTIN] = "SIGTTIN";
#endif
#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local&LTOSTOP) */
signal_names[SIGTTOU] = "SIGTTOU";
#endif
#if defined (SIGIO) /* input/output possible signal */
signal_names[SIGIO] = "SIGIO";
#endif
#if defined (SIGXCPU) /* exceeded CPU time limit */
signal_names[SIGXCPU] = "SIGXCPU";
#endif
#if defined (SIGXFSZ) /* exceeded file size limit */
signal_names[SIGXFSZ] = "SIGXFSZ";
#endif
#if defined (SIGVTALRM) /* virtual time alarm */
signal_names[SIGVTALRM] = "SIGVTALRM";
#endif
#if defined (SIGPROF) /* profiling time alarm */
signal_names[SIGPROF] = "SIGPROF";
#endif
#if defined (SIGWINCH) /* window changed */
signal_names[SIGWINCH] = "SIGWINCH";
#endif
/* 4.4 BSD */
#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */
signal_names[SIGINFO] = "SIGINFO";
#endif
#if defined (SIGUSR1) /* user defined signal 1 */
signal_names[SIGUSR1] = "SIGUSR1";
#endif
#if defined (SIGUSR2) /* user defined signal 2 */
signal_names[SIGUSR2] = "SIGUSR2";
#endif
#if defined (SIGKILLTHR) /* BeOS: Kill Thread */
signal_names[SIGKILLTHR] = "SIGKILLTHR";
#endif
for (i = 0; i < NSIG; i++)
if (signal_names[i] == (char *)NULL)
{
signal_names[i] = (char *)malloc (18);
if (signal_names[i])
sprintf (signal_names[i], "SIGJUNK(%d)", i);
}
signal_names[NSIG] = "DEBUG";
signal_names[NSIG+1] = "ERR";
signal_names[NSIG+2] = "RETURN";
}
+393
View File
@@ -0,0 +1,393 @@
/* signames.c -- Create an array of signal names. */
/* Copyright (C) 2006 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>
#include <stdio.h>
#include <sys/types.h>
#include <signal.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if !defined (NSIG)
# define NSIG 64
#endif
/*
* Special traps:
* EXIT == 0
* DEBUG == NSIG
* ERR == NSIG+1
* RETURN == NSIG+2
*/
#define LASTSIG NSIG+2
char *signal_names[2 * (LASTSIG)];
#define signal_names_size (sizeof(signal_names)/sizeof(signal_names[0]))
/* AIX 4.3 defines SIGRTMIN and SIGRTMAX as 888 and 999 respectively.
I don't want to allocate so much unused space for the intervening signal
numbers, so we just punt if SIGRTMAX is past the bounds of the
signal_names array (handled in configure). */
#if defined (SIGRTMAX) && defined (UNUSABLE_RT_SIGNALS)
# undef SIGRTMAX
# undef SIGRTMIN
#endif
#if defined (SIGRTMAX) || defined (SIGRTMIN)
# define RTLEN 14
# define RTLIM 256
#endif
#if defined (BUILDTOOL)
extern char *progname;
#endif
void
initialize_signames ()
{
register int i;
#if defined (SIGRTMAX) || defined (SIGRTMIN)
int rtmin, rtmax, rtcnt;
#endif
for (i = 1; i < signal_names_size; i++)
signal_names[i] = (char *)NULL;
/* `signal' 0 is what we do on exit. */
signal_names[0] = "EXIT";
/* Place signal names which can be aliases for more common signal
names first. This allows (for example) SIGABRT to overwrite SIGLOST. */
v
/* POSIX 1003.1b-1993 real time signals, but take care of incomplete
implementations. Acoording to the standard, both, SIGRTMIN and
SIGRTMAX must be defined, SIGRTMIN must be stricly less than
SIGRTMAX, and the difference must be at least 7, that is, there
must be at least eight distinct real time signals. */
/* The generated signal names are SIGRTMIN, SIGRTMIN+1, ...,
SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number
of RT signals is odd, there is an extra SIGRTMIN+(x+1).
These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */
#if defined (SIGRTMIN)
rtmin = SIGRTMIN;
signal_names[rtmin] = "SIGRTMIN";
#endif
#if defined (SIGRTMAX)
rtmax = SIGRTMAX;
signal_names[rtmax] = "SIGRTMAX";
#endif
#if defined (SIGRTMAX) && defined (SIGRTMIN)
if (rtmax > rtmin)
{
rtcnt = (rtmax - rtmin - 1) / 2;
/* croak if there are too many RT signals */
if (rtcnt >= RTLIM/2)
{
rtcnt = RTLIM/2-1;
#ifdef BUILDTOOL
fprintf(stderr, "%s: error: more than %d real time signals, fix `%s'\n",
progname, RTLIM, progname);
#endif
}
for (i = 1; i <= rtcnt; i++)
{
signal_names[rtmin+i] = (char *)malloc(RTLEN);
if (signal_names[rtmin+i])
sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i);
signal_names[rtmax-i] = (char *)malloc(RTLEN);
if (signal_names[rtmax-i])
sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i);
}
if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2)
{
/* Need an extra RTMIN signal */
signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN);
if (signal_names[rtmin+rtcnt+1])
sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1);
v }
}
#endif /* SIGRTMIN && SIGRTMAX */
#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */
signal_names[SIGLOST] = "SIGLOST";
#endif
/* AIX */
#if defined (SIGMSG) /* HFT input data pending */
signal_names[SIGMSG] = "SIGMSG";
#endif
#if defined (SIGDANGER) /* system crash imminent */
signal_names[SIGDANGER] = "SIGDANGER";
#endif
#if defined (SIGMIGRATE) /* migrate process to another CPU */
signal_names[SIGMIGRATE] = "SIGMIGRATE";
#endif
#if defined (SIGPRE) /* programming error */
signal_names[SIGPRE] = "SIGPRE";
#endif
#if defined (SIGVIRT) /* AIX virtual time alarm */
signal_names[SIGVIRT] = "SIGVIRT";
#endif
#if defined (SIGALRM1) /* m:n condition variables */
signal_names[SIGALRM1] = "SIGALRM1";
#endif
#if defined (SIGWAITING) /* m:n scheduling */
signal_names[SIGWAITING] = "SIGWAITING";
#endif
#if defined (SIGGRANT) /* HFT monitor mode granted */
signal_names[SIGGRANT] = "SIGGRANT";
#endif
#if defined (SIGKAP) /* keep alive poll from native keyboard */
signal_names[SIGKAP] = "SIGKAP";
#endif
#if defined (SIGRETRACT) /* HFT monitor mode retracted */
signal_names[SIGRETRACT] = "SIGRETRACT";
#endif
#if defined (SIGSOUND) /* HFT sound sequence has completed */
signal_names[SIGSOUND] = "SIGSOUND";
#endif
#if defined (SIGSAK) /* Secure Attention Key */
signal_names[SIGSAK] = "SIGSAK";
#endif
/* SunOS5 */
#if defined (SIGLWP) /* special signal used by thread library */
signal_names[SIGLWP] = "SIGLWP";
#endif
#if defined (SIGFREEZE) /* special signal used by CPR */
signal_names[SIGFREEZE] = "SIGFREEZE";
#endif
#if defined (SIGTHAW) /* special signal used by CPR */
signal_names[SIGTHAW] = "SIGTHAW";
#endif
#if defined (SIGCANCEL) /* thread cancellation signal used by libthread */
signal_names[SIGCANCEL] = "SIGCANCEL";
#endif
#if defined (SIGXRES) /* resource control exceeded */
signal_names[SIGXRES] = "SIGXRES";
#endif
/* HP-UX */
#if defined (SIGDIL) /* DIL signal (?) */
signal_names[SIGDIL] = "SIGDIL";
#endif
/* System V */
#if defined (SIGCLD) /* Like SIGCHLD. */
signal_names[SIGCLD] = "SIGCLD";
#endif
#if defined (SIGPWR) /* power state indication */
signal_names[SIGPWR] = "SIGPWR";
#endif
#if defined (SIGPOLL) /* Pollable event (for streams) */
signal_names[SIGPOLL] = "SIGPOLL";
#endif
/* Unknown */
#if defined (SIGWINDOW)
signal_names[SIGWINDOW] = "SIGWINDOW";
#endif
/* Linux */
#if defined (SIGSTKFLT)
signal_names[SIGSTKFLT] = "SIGSTKFLT";
#endif
/* FreeBSD */
#if defined (SIGTHR) /* thread interrupt */
signal_names[SIGTHR] = "SIGTHR";
#endif
/* Common */
#if defined (SIGHUP) /* hangup */
signal_names[SIGHUP] = "SIGHUP";
#endif
#if defined (SIGINT) /* interrupt */
signal_names[SIGINT] = "SIGINT";
#endif
#if defined (SIGQUIT) /* quit */
signal_names[SIGQUIT] = "SIGQUIT";
#endif
#if defined (SIGILL) /* illegal instruction (not reset when caught) */
signal_names[SIGILL] = "SIGILL";
#endif
#if defined (SIGTRAP) /* trace trap (not reset when caught) */
signal_names[SIGTRAP] = "SIGTRAP";
#endif
#if defined (SIGIOT) /* IOT instruction */
signal_names[SIGIOT] = "SIGIOT";
#endif
#if defined (SIGABRT) /* Cause current process to dump core. */
signal_names[SIGABRT] = "SIGABRT";
#endif
#if defined (SIGEMT) /* EMT instruction */
signal_names[SIGEMT] = "SIGEMT";
#endif
#if defined (SIGFPE) /* floating point exception */
signal_names[SIGFPE] = "SIGFPE";
#endif
#if defined (SIGKILL) /* kill (cannot be caught or ignored) */
signal_names[SIGKILL] = "SIGKILL";
#endif
#if defined (SIGBUS) /* bus error */
signal_names[SIGBUS] = "SIGBUS";
#endif
#if defined (SIGSEGV) /* segmentation violation */
signal_names[SIGSEGV] = "SIGSEGV";
#endif
#if defined (SIGSYS) /* bad argument to system call */
signal_names[SIGSYS] = "SIGSYS";
#endif
#if defined (SIGPIPE) /* write on a pipe with no one to read it */
signal_names[SIGPIPE] = "SIGPIPE";
#endif
#if defined (SIGALRM) /* alarm clock */
signal_names[SIGALRM] = "SIGALRM";
#endif
#if defined (SIGTERM) /* software termination signal from kill */
signal_names[SIGTERM] = "SIGTERM";
#endif
#if defined (SIGURG) /* urgent condition on IO channel */
signal_names[SIGURG] = "SIGURG";
#endif
#if defined (SIGSTOP) /* sendable stop signal not from tty */
signal_names[SIGSTOP] = "SIGSTOP";
#endif
#if defined (SIGTSTP) /* stop signal from tty */
signal_names[SIGTSTP] = "SIGTSTP";
#endif
#if defined (SIGCONT) /* continue a stopped process */
signal_names[SIGCONT] = "SIGCONT";
#endif
#if defined (SIGCHLD) /* to parent on child stop or exit */
signal_names[SIGCHLD] = "SIGCHLD";
#endif
#if defined (SIGTTIN) /* to readers pgrp upon background tty read */
signal_names[SIGTTIN] = "SIGTTIN";
#endif
#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local&LTOSTOP) */
signal_names[SIGTTOU] = "SIGTTOU";
#endif
#if defined (SIGIO) /* input/output possible signal */
signal_names[SIGIO] = "SIGIO";
#endif
#if defined (SIGXCPU) /* exceeded CPU time limit */
signal_names[SIGXCPU] = "SIGXCPU";
#endif
#if defined (SIGXFSZ) /* exceeded file size limit */
signal_names[SIGXFSZ] = "SIGXFSZ";
#endif
#if defined (SIGVTALRM) /* virtual time alarm */
signal_names[SIGVTALRM] = "SIGVTALRM";
#endif
#if defined (SIGPROF) /* profiling time alarm */
signal_names[SIGPROF] = "SIGPROF";
#endif
#if defined (SIGWINCH) /* window changed */
signal_names[SIGWINCH] = "SIGWINCH";
#endif
/* 4.4 BSD */
#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */
signal_names[SIGINFO] = "SIGINFO";
#endif
#if defined (SIGUSR1) /* user defined signal 1 */
signal_names[SIGUSR1] = "SIGUSR1";
#endif
#if defined (SIGUSR2) /* user defined signal 2 */
signal_names[SIGUSR2] = "SIGUSR2";
#endif
#if defined (SIGKILLTHR) /* BeOS: Kill Thread */
signal_names[SIGKILLTHR] = "SIGKILLTHR";
#endif
for (i = 0; i < NSIG; i++)
if (signal_names[i] == (char *)NULL)
{
signal_names[i] = (char *)malloc (18);
if (signal_names[i])
sprintf (signal_names[i], "SIGJUNK(%d)", i);
}
signal_names[NSIG] = "DEBUG";
signal_names[NSIG+1] = "ERR";
signal_names[NSIG+2] = "RETURN";
}
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+9
View File
@@ -0,0 +1,9 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
export THIS_SH PATH
rm -f /tmp/xx
/bin/sh "$@"
+1 -1
View File
@@ -430,7 +430,7 @@ Case05---3---A:B:C---
Case06---1---A B C::---
Case07---3---A:B:C---
Case08---3---A:B:C---
./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
+7 -7
View File
@@ -212,9 +212,9 @@ recho ${av[1]/??/za}
expect '<zaza>'
recho ${av[1]//??/za}
expect '<zagh>'
recho ${av[1]//#??/za}
recho ${av[1]/#??/za}
expect '<efza>'
recho ${av[1]//%??/za}
recho ${av[1]/%??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/*/yyy}
@@ -238,17 +238,17 @@ recho ${@/%??/xx}
expect '<zaza>'
recho ${3//??/za}
expect '<efza>'
recho ${3//%??/za}
recho ${3/%??/za}
expect '<zaza> <zaza> <zaza> <zaza> <zaza> <zaza>'
recho ${@//??/za}
expect '<zacd> <zagh> <zakl> <zaop> <zast> <zawx>'
recho ${@//#??/za}
recho ${@/#??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${@//*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${@//a*/yyy}
expect '<abcd> <efgh> <ijkl> <mnop> <qrst> <uvwyyy>'
recho ${@//%x*/yyy}
recho ${@/%x*/yyy}
expect a newline
echo $abmcde
@@ -548,8 +548,8 @@ var=blah
# these had better agree
echo ${var[@]:3}
echo ${var:3}
echo ${var[@]//#/--}
echo ${var//#/--}
echo ${var[@]/#/--}
echo ${var/#/--}
echo ${var[@]##?}
echo ${var##?}
+558
View File
@@ -0,0 +1,558 @@
# must do this because posix mode causes process substitution to be disabled
# and flagged as a syntax error, which causes the shell to exit
set +o posix
expect()
{
echo expect "$@"
}
HOME=/usr/homes/chet # to make the check against new-exp.right work
expect '<foo bar>'
recho "${undef-"foo bar"}" # should be foo bar
expect '<foo>'
recho "${und="foo"}" # should be foo
expect "<$HOME>"
recho ${HOME-"}"}
expect "<$HOME>"
recho "${HOME-'}'}"
expect "<$HOME>"
recho "${HOME-"}"}"
expect $0: 'HOME: }: syntax error: operand expected (error token is "}")'
recho "${HOME:`echo }`}" # should be a math error -- bad substring substitution
expect unset
_ENV=oops
x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
echo ${x:-unset}
expect "<$HOME>"
recho ${HOME}
expect "<$HOME>"
recho ${HOME:-`echo }`}
expect "<$HOME>"
recho ${HOME:-`echo "}"`}
expect "<$HOME>"
recho "${HOME:-`echo "}"`}"
expect "<$HOME>"
recho "$(echo "${HOME}")"
expect "<$HOME>"
recho "$(echo "$(echo ${HOME})")"
expect "<$HOME>"
recho "$(echo "$(echo "${HOME}")")"
P=*@*
expect '<*@>'
recho "${P%"*"}" #
expect '<*@>'
recho "${P%'*'}" #
expect '<@*>'
recho "${P#\*}" # should be @*
expect '<)>'
recho "$(echo ")")" # should be )
expect '<")">'
recho "$(echo "\")\"")" # should be ")"
foo='abcd '
expect '<-abcd> <->'
recho -${foo}- # should be -abcd -
expect '<-abcd> <->'
recho -${foo% *}- # should be -abcd -
expect '<-abcd->'
recho -${foo%% *}- # should be -abcd-
foo=bar
expect '<bar foo>'
echo -n $foo' ' ; echo foo
expect '<bar foo>'
echo -n $foo" " ; echo foo
expect '<bar foo>'
echo -n "$foo " ; echo foo
expect '<barfoo>'
echo -e "$foo\c " ; echo foo
expect '<barfoo>'
echo -e $foo"\c " ; echo foo
# make sure backslashes are preserved in front of characters that are not
# valid backslash escapes
expect '<\x>'
echo -e '\x'
# substring tests
z=abcdefghijklmnop
expect '<abcd>'
recho ${z:0:4}
expect '<efg> <nop>'
recho ${z:4:3} ${z:${#z}-3:3}
expect '<efg> <nop>'
recho ${z:4:3} ${z: -3:3}
expect '<hijklmnop>'
recho ${z:7:30}
expect '<abcdefghijklmnop>'
recho ${z:0:100}
expect '<abcdefghijklmnop>'
recho ${z:0:${#z}}
set 'ab cd' 'ef' 'gh ij' 'kl mn' 'op'
expect '<ab cd> <ef>'
recho "${@:1:2}"
expect '<gh ij> <kl mn>'
recho "${@:3:2}"
expect '<gh ij> <kl mn> <op>'
recho "${@:3:4}"
expect '<ab cd> <ef> <gh ij> <kl mn> <op>'
recho "${@:1:$#}"
# code to ad-hoc parse arithmetic expressions in substring expansions was
# broken until post-2.04
base=/home/chet/foo//bar
string1=$base/abcabcabc
x=1 j=4
expect '</home/chet/foo//bar/abcabcabc>'
recho ${string1:0}
expect '<home/chet/foo//bar/abcabcabc>'
recho ${string1:1}
expect '<home>'
recho ${string1:(j?1:0):j}
expect '<home>'
recho ${string1:j?1:0:j}
expect '<home>'
recho ${string1:(j?(x?1:0):0):j}
expect '<home>'
recho ${string1:j?(x?1:0):0:j}
unset base string1 x j
# indirect variable references
expect '<abcdefghijklmnop>'
recho ${!9:-$z}
ef=4
expect '<4>'
recho ${!2}
expect '<op>'
recho ${!#}
set a b c d e
a=
expect '<abcdefghijklmnop>'
recho ${a:-$z}
expect '<abcdefghijklmnop>'
recho ${!1:-$z}
expect nothing
recho ${a-$z}
expect nothing
recho ${!1-$z}
set -u
expect $0: ABX: unbound variable
( recho ${ABX} )
set +u
expect $0: '$6: cannot assign in this way'
recho ${6="arg6"}
v=abcde
# sed-like variable substitution
expect '<xxcde>'
recho ${v/a[a-z]/xx}
expect '<axxde>'
recho ${v/a??/axx}
expect '<abxyz>'
recho ${v/c??/xyz}
expect '<abbcde>'
recho ${v/#a/ab}
expect '<abcde>'
recho ${v/#d/ab}
expect '<abcabe>'
recho ${v/d/ab}
expect '<abcdlast>'
recho ${v/%?/last}
expect '<abcde>'
recho ${v/%x/last}
av=(abcd efgh ijkl mnop qrst uvwx)
expect '<xxcd>'
recho ${av/??/xx}
expect '<abxx>'
recho ${av/%??/xx}
expect '<xxgh>'
recho ${av[1]/??/xx}
expect '<efgh>'
recho ${av[1]/%ab/xx}
expect '<xxfgh>'
recho ${av[1]/#?/xx}
expect '<zagh>'
recho ${av[1]/??/za}
expect '<zaza>'
recho ${av[1]//??/za}
expect '<zagh>'
recho ${av[1]//#??/za}
expect '<efza>'
recho ${av[1]//%??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/#*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/%*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${av[@]/a*/yyy}
expect '<abxx> <efxx> <ijxx> <mnxx> <qrxx> <uvxx>'
recho ${av[@]/%??/xx}
set abcd efgh ijkl mnop qrst uvwx
expect '<xxcd>'
recho ${1/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/%??/xx}
expect '<zaza>'
recho ${3//??/za}
expect '<efza>'
recho ${3//%??/za}
expect '<zaza> <zaza> <zaza> <zaza> <zaza> <zaza>'
recho ${@//??/za}
expect '<zacd> <zagh> <zakl> <zaop> <zast> <zawx>'
recho ${@//#??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${@//*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${@//a*/yyy}
expect '<abcd> <efgh> <ijkl> <mnop> <qrst> <uvwyyy>'
recho ${@//%x*/yyy}
expect a newline
echo $abmcde
# sneaky way to replace a newline in a variable value with something else
AVAR=$'This\nstring\nhas\nmultiple\nlines.'
echo "${AVAR}"
eval BVAR=\"\${AVAR//$'\n'/-}\"
echo "$BVAR"
unset AVAR BVAR
# run process substitution tests in a subshell so that syntax errors
# caused by a shell not implementing process substitution (e.g., one
# built on a NeXT) will not cause the whole test to exit prematurely
${THIS_SH} ./new-exp1.sub
# run the tests of $(<filename) in a subshell to avoid cluttering up
# this script
${THIS_SH} ./new-exp2.sub
expect '<6>'
recho ${#:-foo}
expect $0: '${#:}: bad substitution'
echo ${#:}
expect "<'>"
recho "'"
expect '<">'
recho '"'
expect '<"hello">'
recho "\"hello\""
shift $#
unset foo
z=abcdef
z1='abc def'
expect '<>'
recho ${foo:-""}
expect nothing
recho ${foo:-"$@"}
expect '<>'
recho "${foo:-$@}"
# unset var
expect '<>'
recho ${foo:-"$zbcd"}
expect nothing
recho ${foo:-$zbcd}
# set var
expect '<abcdef>'
recho ${foo:-"$z"}
expect '<abc def>'
recho ${foo:-"$z1"}
expect '<abcdef>'
recho ${foo:-$z}
expect '<abc> <def>'
recho ${foo:-$z1}
expect '<abcdef>'
recho "${foo:-$z}"
expect '<abc def>'
recho "${foo:-$z1}"
expect '<abcdef>'
recho "${foo:-"$z"}"
# this disagrees with sh and ksh, but I think it is right according
# to posix.2.
expect '<abc def>'
recho "${foo:-"$z1"}"
set ab cd ef gh
expect '<ab> <cd> <ef> <gh>'
recho ${foo:-"$@"}
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-$@}"
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-"$@"}"
shift $#
expect nothing
recho $xxx"$@"
expect nothing
recho ${foo:-$xxx"$@"}
expect '<>'
recho "${foo:-$xxx$@}"
expect '<>'
recho "${foo:-$xxx"$@"}"
expect nothing
recho $xxx"$@"
expect nothing
recho "$xxx$@"
expect nothing
recho "$@"$xxx
expect '<>'
recho $xxx""
expect '<>'
recho $xxx''
expect '<>'
recho ''$xxx
expect '<>'
recho ""$xxx
AB='abcdefghijklmnopqrstuvwxyz'
recho ${AB:7:15}
recho ${AB:15:7}
recho ${AB:20}
recho ${AB:0}
recho ${AB:0:20}
recho ${AB:10:7}
recho ${AB:10:3+4}
recho ${AB:20/2:3+4}
set 1 2 3 4 5 6
recho \""${*:2:2}"\"
IFS=:
recho \""${*:2:2}"\"
IFS=$' \t\n'
z=123456
recho \""${z:2:2}"\"
recho \""${z:2}"\"
recho \""${z:2:4}"\"
recho \""${z:2:6}"\"
set $'\1' $'\2' $'\177'
recho $*
recho $@
recho ${*}
recho ${@}
xx=one/two/two
recho ${xx%/*}
recho ${xx/\/two}
yy=oneonetwo
recho ${yy//one}
recho ${yy/\/one}
xx=oneonetwo
recho ${xx/one}
recho ${xx//one}
recho ${xx/\/one}
# out-of-range substrings
var=abc
c=${var:3}
expect nothing
recho $c
c=${var:4}
expect nothing
recho $c
expect '<./new-exp.tests: -2: substring expression < 0>'
c=${var:0:-2}
var=abcdefghi
c=${var:3:12}
recho $c
c=${var:4:20}
recho $c
# make sure null patterns work
xxx=endocrine
yyy=n
unset zzz
recho ${xxx/$yyy/*}
recho ${xxx//$yyy/*}
recho ${xxx/$zzz/*}
recho ${xxx//$zzz/*}
recho ${xxx//%${zzz}/}
recho ${xxx//%${zzz}}
recho ${xxx//#${zzz}/}
recho ${xxx//#${zzz}}
# another case that caused a core dump in bash-2.0
XPATH=/usr/bin:/bin:/usr/local/bin:/usr/gnu/bin::/usr/bin/X11:/sbin:/usr/sbin
recho ${XPATH//:/ }
xx=(ar as at au av aw ax ay az)
recho ${xx[@]/a/}
recho ${xx[@]//a/}
recho ${xx[*]/a/}
recho ${xx[*]//a/}
recho ${xx[@]%?}
recho ${xx[*]%?}
recho ${xx[@]#?}
recho ${xx[*]#?}
set -- ar as at au av aw ax ay az
recho ${@/a/}
recho ${@//a/}
recho ${*/a/}
recho ${*//a/}
recho ${@%?}
recho ${*%?}
recho ${@#?}
recho ${*#?}
shift $#
set -u
( recho $9 ; echo after 1)
( recho ${9} ; echo after 2)
( recho $UNSET ; echo after 3)
( recho ${UNSET} ; echo after 4)
( recho "$UNSET" ; echo after 5)
( recho "${UNSET}" ; echo after 6)
( recho "${#UNSET}" ; echo after 7)
set +u
RECEIVED="12345"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="12345#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED=""
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
# tests of new prefix expansion ${!prefix*}
${THIS_SH} ./new-exp3.sub
# bug with indirect expansion through bash-2.05b
${THIS_SH} ./new-exp4.sub
# these caused errors and core dumps in versions before bash-2.04
c=""
echo ${c//${$(($#-1))}/x/}
set a b c d e f g
recho "$@"
set -- ${@:1:$(($# - 2))}
recho "$@"
set a b
recho ${@:1:$(($# - 2))}
recho ${@:1:0}
recho ${@:1:1}
recho ${@:1:2}
recho "${*:1:0}"
# this is an error -- negative expression
set a
recho ${@:1:$(($# - 2))}
XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
set $( IFS=: ; echo $XPATH )
recho ${@##*/}
recho ${@%%[!/]*}
recho ${@#/*}
recho ${@%*/}
set /full/path/to/x16 /another/full/path
recho ${1%/*}
recho ${1%%[!/]*}
recho ${1#*/}
recho ${1##*/}
${THIS_SH} ./new-exp5.sub
unset var
var=blah
# these had better agree
echo ${var[@]:3}
echo ${var:3}
echo ${var[@]//#/--}
echo ${var//#/--}
echo ${var[@]##?}
echo ${var##?}
# this must be last!
expect $0: 'ABXD: parameter unset'
recho ${ABXD:?"parameter unset"}
+558
View File
@@ -0,0 +1,558 @@
# must do this because posix mode causes process substitution to be disabled
# and flagged as a syntax error, which causes the shell to exit
set +o posix
expect()
{
echo expect "$@"
}
HOME=/usr/homes/chet # to make the check against new-exp.right work
expect '<foo bar>'
recho "${undef-"foo bar"}" # should be foo bar
expect '<foo>'
recho "${und="foo"}" # should be foo
expect "<$HOME>"
recho ${HOME-"}"}
expect "<$HOME>"
recho "${HOME-'}'}"
expect "<$HOME>"
recho "${HOME-"}"}"
expect $0: 'HOME: }: syntax error: operand expected (error token is "}")'
recho "${HOME:`echo }`}" # should be a math error -- bad substring substitution
expect unset
_ENV=oops
x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
echo ${x:-unset}
expect "<$HOME>"
recho ${HOME}
expect "<$HOME>"
recho ${HOME:-`echo }`}
expect "<$HOME>"
recho ${HOME:-`echo "}"`}
expect "<$HOME>"
recho "${HOME:-`echo "}"`}"
expect "<$HOME>"
recho "$(echo "${HOME}")"
expect "<$HOME>"
recho "$(echo "$(echo ${HOME})")"
expect "<$HOME>"
recho "$(echo "$(echo "${HOME}")")"
P=*@*
expect '<*@>'
recho "${P%"*"}" #
expect '<*@>'
recho "${P%'*'}" #
expect '<@*>'
recho "${P#\*}" # should be @*
expect '<)>'
recho "$(echo ")")" # should be )
expect '<")">'
recho "$(echo "\")\"")" # should be ")"
foo='abcd '
expect '<-abcd> <->'
recho -${foo}- # should be -abcd -
expect '<-abcd> <->'
recho -${foo% *}- # should be -abcd -
expect '<-abcd->'
recho -${foo%% *}- # should be -abcd-
foo=bar
expect '<bar foo>'
echo -n $foo' ' ; echo foo
expect '<bar foo>'
echo -n $foo" " ; echo foo
expect '<bar foo>'
echo -n "$foo " ; echo foo
expect '<barfoo>'
echo -e "$foo\c " ; echo foo
expect '<barfoo>'
echo -e $foo"\c " ; echo foo
# make sure backslashes are preserved in front of characters that are not
# valid backslash escapes
expect '<\x>'
echo -e '\x'
# substring tests
z=abcdefghijklmnop
expect '<abcd>'
recho ${z:0:4}
expect '<efg> <nop>'
recho ${z:4:3} ${z:${#z}-3:3}
expect '<efg> <nop>'
recho ${z:4:3} ${z: -3:3}
expect '<hijklmnop>'
recho ${z:7:30}
expect '<abcdefghijklmnop>'
recho ${z:0:100}
expect '<abcdefghijklmnop>'
recho ${z:0:${#z}}
set 'ab cd' 'ef' 'gh ij' 'kl mn' 'op'
expect '<ab cd> <ef>'
recho "${@:1:2}"
expect '<gh ij> <kl mn>'
recho "${@:3:2}"
expect '<gh ij> <kl mn> <op>'
recho "${@:3:4}"
expect '<ab cd> <ef> <gh ij> <kl mn> <op>'
recho "${@:1:$#}"
# code to ad-hoc parse arithmetic expressions in substring expansions was
# broken until post-2.04
base=/home/chet/foo//bar
string1=$base/abcabcabc
x=1 j=4
expect '</home/chet/foo//bar/abcabcabc>'
recho ${string1:0}
expect '<home/chet/foo//bar/abcabcabc>'
recho ${string1:1}
expect '<home>'
recho ${string1:(j?1:0):j}
expect '<home>'
recho ${string1:j?1:0:j}
expect '<home>'
recho ${string1:(j?(x?1:0):0):j}
expect '<home>'
recho ${string1:j?(x?1:0):0:j}
unset base string1 x j
# indirect variable references
expect '<abcdefghijklmnop>'
recho ${!9:-$z}
ef=4
expect '<4>'
recho ${!2}
expect '<op>'
recho ${!#}
set a b c d e
a=
expect '<abcdefghijklmnop>'
recho ${a:-$z}
expect '<abcdefghijklmnop>'
recho ${!1:-$z}
expect nothing
recho ${a-$z}
expect nothing
recho ${!1-$z}
set -u
expect $0: ABX: unbound variable
( recho ${ABX} )
set +u
expect $0: '$6: cannot assign in this way'
recho ${6="arg6"}
v=abcde
# sed-like variable substitution
expect '<xxcde>'
recho ${v/a[a-z]/xx}
expect '<axxde>'
recho ${v/a??/axx}
expect '<abxyz>'
recho ${v/c??/xyz}
expect '<abbcde>'
recho ${v/#a/ab}
expect '<abcde>'
recho ${v/#d/ab}
expect '<abcabe>'
recho ${v/d/ab}
expect '<abcdlast>'
recho ${v/%?/last}
expect '<abcde>'
recho ${v/%x/last}
av=(abcd efgh ijkl mnop qrst uvwx)
expect '<xxcd>'
recho ${av/??/xx}
expect '<abxx>'
recho ${av/%??/xx}
expect '<xxgh>'
recho ${av[1]/??/xx}
expect '<efgh>'
recho ${av[1]/%ab/xx}
expect '<xxfgh>'
recho ${av[1]/#?/xx}
expect '<zagh>'
recho ${av[1]/??/za}
expect '<zaza>'
recho ${av[1]//??/za}
expect '<zagh>'
recho ${av[1]/#??/za}
expect '<efza>'
recho ${av[1]/%??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/#*/yyy}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${av[@]/%*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${av[@]/a*/yyy}
expect '<abxx> <efxx> <ijxx> <mnxx> <qrxx> <uvxx>'
recho ${av[@]/%??/xx}
set abcd efgh ijkl mnop qrst uvwx
expect '<xxcd>'
recho ${1/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/??/xx}
expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
recho ${@/%??/xx}
expect '<zaza>'
recho ${3//??/za}
expect '<efza>'
recho ${3/%??/za}
expect '<zaza> <zaza> <zaza> <zaza> <zaza> <zaza>'
recho ${@//??/za}
expect '<zacd> <zagh> <zakl> <zaop> <zast> <zawx>'
recho ${@/#??/za}
expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
recho ${@//*/yyy}
expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
recho ${@//a*/yyy}
expect '<abcd> <efgh> <ijkl> <mnop> <qrst> <uvwyyy>'
recho ${@/%x*/yyy}
expect a newline
echo $abmcde
# sneaky way to replace a newline in a variable value with something else
AVAR=$'This\nstring\nhas\nmultiple\nlines.'
echo "${AVAR}"
eval BVAR=\"\${AVAR//$'\n'/-}\"
echo "$BVAR"
unset AVAR BVAR
# run process substitution tests in a subshell so that syntax errors
# caused by a shell not implementing process substitution (e.g., one
# built on a NeXT) will not cause the whole test to exit prematurely
${THIS_SH} ./new-exp1.sub
# run the tests of $(<filename) in a subshell to avoid cluttering up
# this script
${THIS_SH} ./new-exp2.sub
expect '<6>'
recho ${#:-foo}
expect $0: '${#:}: bad substitution'
echo ${#:}
expect "<'>"
recho "'"
expect '<">'
recho '"'
expect '<"hello">'
recho "\"hello\""
shift $#
unset foo
z=abcdef
z1='abc def'
expect '<>'
recho ${foo:-""}
expect nothing
recho ${foo:-"$@"}
expect '<>'
recho "${foo:-$@}"
# unset var
expect '<>'
recho ${foo:-"$zbcd"}
expect nothing
recho ${foo:-$zbcd}
# set var
expect '<abcdef>'
recho ${foo:-"$z"}
expect '<abc def>'
recho ${foo:-"$z1"}
expect '<abcdef>'
recho ${foo:-$z}
expect '<abc> <def>'
recho ${foo:-$z1}
expect '<abcdef>'
recho "${foo:-$z}"
expect '<abc def>'
recho "${foo:-$z1}"
expect '<abcdef>'
recho "${foo:-"$z"}"
# this disagrees with sh and ksh, but I think it is right according
# to posix.2.
expect '<abc def>'
recho "${foo:-"$z1"}"
set ab cd ef gh
expect '<ab> <cd> <ef> <gh>'
recho ${foo:-"$@"}
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-$@}"
expect '<ab> <cd> <ef> <gh>'
recho "${foo:-"$@"}"
shift $#
expect nothing
recho $xxx"$@"
expect nothing
recho ${foo:-$xxx"$@"}
expect '<>'
recho "${foo:-$xxx$@}"
expect '<>'
recho "${foo:-$xxx"$@"}"
expect nothing
recho $xxx"$@"
expect nothing
recho "$xxx$@"
expect nothing
recho "$@"$xxx
expect '<>'
recho $xxx""
expect '<>'
recho $xxx''
expect '<>'
recho ''$xxx
expect '<>'
recho ""$xxx
AB='abcdefghijklmnopqrstuvwxyz'
recho ${AB:7:15}
recho ${AB:15:7}
recho ${AB:20}
recho ${AB:0}
recho ${AB:0:20}
recho ${AB:10:7}
recho ${AB:10:3+4}
recho ${AB:20/2:3+4}
set 1 2 3 4 5 6
recho \""${*:2:2}"\"
IFS=:
recho \""${*:2:2}"\"
IFS=$' \t\n'
z=123456
recho \""${z:2:2}"\"
recho \""${z:2}"\"
recho \""${z:2:4}"\"
recho \""${z:2:6}"\"
set $'\1' $'\2' $'\177'
recho $*
recho $@
recho ${*}
recho ${@}
xx=one/two/two
recho ${xx%/*}
recho ${xx/\/two}
yy=oneonetwo
recho ${yy//one}
recho ${yy/\/one}
xx=oneonetwo
recho ${xx/one}
recho ${xx//one}
recho ${xx/\/one}
# out-of-range substrings
var=abc
c=${var:3}
expect nothing
recho $c
c=${var:4}
expect nothing
recho $c
expect '<./new-exp.tests: -2: substring expression < 0>'
c=${var:0:-2}
var=abcdefghi
c=${var:3:12}
recho $c
c=${var:4:20}
recho $c
# make sure null patterns work
xxx=endocrine
yyy=n
unset zzz
recho ${xxx/$yyy/*}
recho ${xxx//$yyy/*}
recho ${xxx/$zzz/*}
recho ${xxx//$zzz/*}
recho ${xxx//%${zzz}/}
recho ${xxx//%${zzz}}
recho ${xxx//#${zzz}/}
recho ${xxx//#${zzz}}
# another case that caused a core dump in bash-2.0
XPATH=/usr/bin:/bin:/usr/local/bin:/usr/gnu/bin::/usr/bin/X11:/sbin:/usr/sbin
recho ${XPATH//:/ }
xx=(ar as at au av aw ax ay az)
recho ${xx[@]/a/}
recho ${xx[@]//a/}
recho ${xx[*]/a/}
recho ${xx[*]//a/}
recho ${xx[@]%?}
recho ${xx[*]%?}
recho ${xx[@]#?}
recho ${xx[*]#?}
set -- ar as at au av aw ax ay az
recho ${@/a/}
recho ${@//a/}
recho ${*/a/}
recho ${*//a/}
recho ${@%?}
recho ${*%?}
recho ${@#?}
recho ${*#?}
shift $#
set -u
( recho $9 ; echo after 1)
( recho ${9} ; echo after 2)
( recho $UNSET ; echo after 3)
( recho ${UNSET} ; echo after 4)
( recho "$UNSET" ; echo after 5)
( recho "${UNSET}" ; echo after 6)
( recho "${#UNSET}" ; echo after 7)
set +u
RECEIVED="12345"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="12345#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED="#"
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
RECEIVED=""
recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
# tests of new prefix expansion ${!prefix*}
${THIS_SH} ./new-exp3.sub
# bug with indirect expansion through bash-2.05b
${THIS_SH} ./new-exp4.sub
# these caused errors and core dumps in versions before bash-2.04
c=""
echo ${c//${$(($#-1))}/x/}
set a b c d e f g
recho "$@"
set -- ${@:1:$(($# - 2))}
recho "$@"
set a b
recho ${@:1:$(($# - 2))}
recho ${@:1:0}
recho ${@:1:1}
recho ${@:1:2}
recho "${*:1:0}"
# this is an error -- negative expression
set a
recho ${@:1:$(($# - 2))}
XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
set $( IFS=: ; echo $XPATH )
recho ${@##*/}
recho ${@%%[!/]*}
recho ${@#/*}
recho ${@%*/}
set /full/path/to/x16 /another/full/path
recho ${1%/*}
recho ${1%%[!/]*}
recho ${1#*/}
recho ${1##*/}
${THIS_SH} ./new-exp5.sub
unset var
var=blah
# these had better agree
echo ${var[@]:3}
echo ${var:3}
echo ${var[@]//#/--}
echo ${var//#/--}
echo ${var[@]##?}
echo ${var##?}
# this must be last!
expect $0: 'ABXD: parameter unset'
recho ${ABXD:?"parameter unset"}
+1
View File
@@ -22,3 +22,4 @@ abcd:~chet
ok 1
ok 2
ok 3
~root
+24
View File
@@ -0,0 +1,24 @@
~chet
/usr/xyz/foo
~chet/foo
~chet/foo
~chet/bar
~chet/bar
~chet/bar
:~chet/
abcd~chet
SHELL=~/bash
/usr/xyz/bash
abcd:~chet
/usr/ucb:/bin:/usr/xyz/bin:/usr/xyz/tmp/bin:/usr/bin
/usr
/tmp
/bin:/usr/bin:.:/usr/xyz/bin
/bin:/usr/bin:.:~/bin
/bin:/usr/bin:.:/usr/xyz/bin
/bin:/usr/bin:.:/usr/xyz/bin
/bin:/usr/bin:.:~/bin
/bin:/usr/bin:.:~/bin
ok 1
ok 2
ok 3
+3
View File
@@ -64,3 +64,6 @@ case $unset in
"") echo ok 3 ;;
*) echo bad 3 ;;
esac
USER=root # should exist just about everywhere
echo ~$USER
+66
View File
@@ -0,0 +1,66 @@
# this is needed because posix mode restricts tilde expansion to assignment
# statements preceding a command, instead of the default of expanding all
# assignment statements on the line (e.g., after `export'). Without this,
# the next-to-last test fails
set +o posix
HOME=/usr/xyz
SHELL=~/bash
echo ~ch\et
echo ~/"foo"
echo "~chet"/"foo"
echo \~chet/"foo"
echo \~chet/bar
echo ~\chet/bar
echo ~chet""/bar
echo ":~chet/"
echo abcd~chet
echo "SHELL=~/bash"
echo $SHELL
echo abcd:~chet
path=/usr/ucb:/bin:~/bin:~/tmp/bin:/usr/bin
echo $path
cd /usr
cd /tmp
echo ~-
echo ~+
XPATH=/bin:/usr/bin:.
# yes tilde expansion
PPATH=$XPATH:~/bin
echo "$PPATH"
# no tilde expansion
PPATH="$XPATH:~/bin"
echo "$PPATH"
# yes tilde expansion
export PPATH=$XPATH:~/bin
echo "$PPATH"
declare -x PPATH=$XPATH:~/bin
echo "$PPATH"
# no tilde expansion
export PPATH="$XPATH:~/bin"
echo "$PPATH"
declare -x PPATH="$XPATH:~/bin"
echo "$PPATH"
# more tests of tilde expansion when executing case commands
case ~ in
$HOME) echo ok 1;;
*) echo bad 1 ;;
esac
case ~ in
~) echo ok 2 ;;
\~) echo bad 2a ;;
*) echo bad 2b ;;
esac
case $unset in
"") echo ok 3 ;;
*) echo bad 3 ;;
esac
+2
View File
@@ -119,6 +119,8 @@ initialize_traps ()
{
register int i;
initialize_signames();
trap_list[EXIT_TRAP] = trap_list[DEBUG_TRAP] = trap_list[ERROR_TRAP] = trap_list[RETURN_TRAP] = (char *)NULL;
sigmodes[EXIT_TRAP] = sigmodes[DEBUG_TRAP] = sigmodes[ERROR_TRAP] = sigmodes[RETURN_TRAP] = SIG_INHERITED;
original_signals[EXIT_TRAP] = IMPOSSIBLE_TRAP_HANDLER;
+1002
View File
File diff suppressed because it is too large Load Diff
+9 -7
View File
@@ -483,8 +483,10 @@ initialize_shell_variables (env, privmode)
set_if_not ("HISTFILE", name);
free (name);
#if 0
set_if_not ("HISTSIZE", "500");
sv_histsize ("HISTSIZE");
#endif
}
#endif /* HISTORY */
@@ -4016,19 +4018,19 @@ sv_histsize (name)
{
if (legal_number (temp, &num))
{
hmax = num;
if (name[4] == 'S')
{
hmax = num;
stifle_history (hmax);
num = where_history ();
if (history_lines_this_session > num)
history_lines_this_session = num;
hmax = where_history ();
if (history_lines_this_session > hmax)
history_lines_this_session = hmax;
}
else
{
history_truncate_file (get_string_value ("HISTFILE"), (int)num);
if (num <= history_lines_in_file)
history_lines_in_file = num;
history_truncate_file (get_string_value ("HISTFILE"), hmax);
if (hmax <= history_lines_in_file)
history_lines_in_file = hmax;
}
}
}
+9 -7
View File
@@ -860,9 +860,11 @@ sh_set_lines_and_columns (lines, cols)
{
char val[INT_STRLEN_BOUND(int) + 1], *v;
#if defined (READLINE)
/* If we are currently assigning to LINES or COLUMNS, don't do anything. */
if (winsize_assignment)
return;
#endif
v = inttostr (lines, val, sizeof (val));
bind_variable ("LINES", v, 0);
@@ -4014,19 +4016,19 @@ sv_histsize (name)
{
if (legal_number (temp, &num))
{
hmax = num;
if (name[4] == 'S')
{
hmax = num;
stifle_history (hmax);
num = where_history ();
if (history_lines_this_session > num)
history_lines_this_session = num;
hmax = where_history ();
if (history_lines_this_session > hmax)
history_lines_this_session = hmax;
}
else
{
history_truncate_file (get_string_value ("HISTFILE"), (int)num);
if (num <= history_lines_in_file)
history_lines_in_file = num;
history_truncate_file (get_string_value ("HISTFILE"), hmax);
if (hmax <= history_lines_in_file)
history_lines_in_file = hmax;
}
}
}