mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 05:47:59 +02:00
commit bash-20111028 snapshot
This commit is contained in:
+38
-1
@@ -12369,4 +12369,41 @@ lib/readline/complete.c
|
||||
instead of straight return; add same call at end of function.
|
||||
Placeholder for future work in deinstalling signal handlers when
|
||||
readline is not active
|
||||
|
||||
|
||||
10/25
|
||||
-----
|
||||
expr.c
|
||||
- exp2: catch arithmetic overflow when val1 == INTMAX_MIN and val2 == -1
|
||||
for DIV and MOD and avoid SIGFPE. Bug report and pointer to fix
|
||||
from Jaak Ristioja <jaak.ristioja@cyber.ee>
|
||||
- expassign: same changes for arithmetic overflow for DIV and MOD
|
||||
|
||||
10/28
|
||||
-----
|
||||
subst.c
|
||||
- parameter_brace_expand: allow pattern substitution when there is an
|
||||
expansion of the form ${var/} as a no-op: replacing nothing with
|
||||
nothing
|
||||
- parameter_brace_patsub: don't need to check for PATSUB being NULL;
|
||||
it never is
|
||||
|
||||
flags.c
|
||||
- if STRICT_POSIX is defined, initialize history_expansion to 0, since
|
||||
history expansion (and its treatment of ! within double quotes) is
|
||||
not a conforming posix environment. From austin-group issue 500
|
||||
|
||||
lib/readline/histexpand.c
|
||||
- history_expand: when processing a string within double quotes
|
||||
(DQUOTE == 1), make the closing double quote inhibit history
|
||||
expansion, as if the word were outside double quotes. In effect,
|
||||
we assume that the double quote is followed by a character in
|
||||
history_no_expand_chars. tcsh and csh seem to do this. This
|
||||
answers a persistent complaint about history expansion
|
||||
|
||||
10/29
|
||||
-----
|
||||
make_cmd.c
|
||||
- make_arith_for_command: use skip_to_delim to find the next `;'
|
||||
when breaking the string between the double parens into three
|
||||
separate components instead of a simple character loop. Fixes
|
||||
bug reported by Dan Douglas <ormaaj@gmail.com>
|
||||
|
||||
@@ -12363,3 +12363,39 @@ builtins/history.def
|
||||
try to delete the last history entry -- the `history -s' command
|
||||
might not have been saved. Fixes bug reported by
|
||||
lester@vmw-les.eng.vmware.com
|
||||
|
||||
lib/readline/complete.c
|
||||
- rl_callback_read_char: add calls to a macro CALLBACK_READ_RETURN
|
||||
instead of straight return; add same call at end of function.
|
||||
Placeholder for future work in deinstalling signal handlers when
|
||||
readline is not active
|
||||
|
||||
10/25
|
||||
-----
|
||||
expr.c
|
||||
- exp2: catch arithmetic overflow when val1 == INTMAX_MIN and val2 == -1
|
||||
for DIV and MOD and avoid SIGFPE. Bug report and pointer to fix
|
||||
from Jaak Ristioja <jaak.ristioja@cyber.ee>
|
||||
- expassign: same changes for arithmetic overflow for DIV and MOD
|
||||
|
||||
10/28
|
||||
-----
|
||||
subst.c
|
||||
- parameter_brace_expand: allow pattern substitution when there is an
|
||||
expansion of the form ${var/} as a no-op: replacing nothing with
|
||||
nothing
|
||||
- parameter_brace_patsub: don't need to check for PATSUB being NULL;
|
||||
it never is
|
||||
|
||||
flags.c
|
||||
- if STRICT_POSIX is defined, initialize history_expansion to 0, since
|
||||
history expansion (and its treatment of ! within double quotes) is
|
||||
not a conforming posix environment. From austin-group issue 500
|
||||
|
||||
lib/readline/histexpand.c
|
||||
- history_expand: when processing a string within double quotes
|
||||
(DQUOTE == 1), make the closing double quote inhibit history
|
||||
expansion, as if the word were outside double quotes. In effect,
|
||||
we assume that the double quote is followed by a character in
|
||||
history_no_expand_chars. tcsh and csh seem to do this. This
|
||||
answers a persistent complaint about history expansion
|
||||
|
||||
@@ -760,6 +760,7 @@ tests/arith1.sub f
|
||||
tests/arith2.sub f
|
||||
tests/arith3.sub f
|
||||
tests/arith4.sub f
|
||||
tests/arith5.sub f
|
||||
tests/array.tests f
|
||||
tests/array.right f
|
||||
tests/array1.sub f
|
||||
|
||||
@@ -537,7 +537,7 @@ extract_info (filename, structfile, externfile)
|
||||
{
|
||||
array_add (&buffer[i], defs->lines);
|
||||
|
||||
while (buffer[i] != '\n' && i < file_size)
|
||||
while (i < file_size && buffer[i] != '\n')
|
||||
i++;
|
||||
buffer[i++] = '\0';
|
||||
}
|
||||
|
||||
+1520
-1515
File diff suppressed because it is too large
Load Diff
+19
-3
@@ -4564,7 +4564,10 @@ This is semantically equivalent to
|
||||
|
||||
<P>
|
||||
|
||||
(see <B>Duplicating File Descriptors</B> below).
|
||||
When using the second form, <I>word</I> may not expand to a number or
|
||||
<B>-</B>. If it does, other redirection operators apply
|
||||
(see <B>Duplicating File Descriptors</B> below) for compatibility
|
||||
reasons.
|
||||
<A NAME="lbBN"> </A>
|
||||
<H4>Appending Standard Output and Standard Error</H4>
|
||||
|
||||
@@ -4749,8 +4752,18 @@ If the digits in
|
||||
<I>word</I>
|
||||
|
||||
do not specify a file descriptor open for output, a redirection error occurs.
|
||||
If
|
||||
<I>word</I>
|
||||
|
||||
evaluates to
|
||||
<B>-</B>,
|
||||
|
||||
file descriptor
|
||||
<I>n</I>
|
||||
|
||||
is closed.
|
||||
As a special case, if <I>n</I> is omitted, and <I>word</I> does not
|
||||
expand to one or more digits, the standard output and standard
|
||||
expand to one or more digits or <B>-</B>, the standard output and standard
|
||||
error are redirected as described previously.
|
||||
<A NAME="lbBR"> </A>
|
||||
<H4>Moving File Descriptors</H4>
|
||||
@@ -10831,9 +10844,12 @@ that script and return either
|
||||
|
||||
or the exit status of the last command executed within the
|
||||
script as the exit status of the script.
|
||||
If <I>n</I> is supplied, the return value is its least significant
|
||||
8 bits.
|
||||
The return status is non-zero if
|
||||
<B>return</B>
|
||||
|
||||
is supplied a non-numeric argument, or
|
||||
is used outside a
|
||||
function and not during execution of a script by <B>.</B> or <B>source</B>.
|
||||
Any command associated with the <B>RETURN</B> trap is executed
|
||||
@@ -12938,6 +12954,6 @@ There may be only one active coprocess at a time.
|
||||
</DL>
|
||||
<HR>
|
||||
This document was created by man2html from bash.1.<BR>
|
||||
Time: 26 September 2011 10:56:19 EDT
|
||||
Time: 24 October 2011 08:43:51 EDT
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
Binary file not shown.
+851
-840
File diff suppressed because it is too large
Load Diff
Binary file not shown.
+17
-10
@@ -1,6 +1,6 @@
|
||||
<HTML>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<!-- Created on September, 26 2011 by texi2html 1.64 -->
|
||||
<!-- Created on October, 24 2011 by texi2html 1.64 -->
|
||||
<!--
|
||||
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
|
||||
Karl Berry <karl@freefriends.org>
|
||||
@@ -33,10 +33,10 @@ Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
|
||||
<H1>Bash Reference Manual</H1></P><P>
|
||||
|
||||
This text is a brief description of the features that are present in
|
||||
the Bash shell (version 4.2, 25 September 2011).
|
||||
the Bash shell (version 4.2, 24 October 2011).
|
||||
</P><P>
|
||||
|
||||
This is Edition 4.2, last updated 25 September 2011,
|
||||
This is Edition 4.2, last updated 24 October 2011,
|
||||
of <CITE>The GNU Bash Reference Manual</CITE>,
|
||||
for <CODE>Bash</CODE>, Version 4.2.
|
||||
</P><P>
|
||||
@@ -3125,7 +3125,9 @@ standard error:
|
||||
</pre></td></tr></table>Of the two forms, the first is preferred.
|
||||
This is semantically equivalent to
|
||||
<TABLE><tr><td> </td><td class=example><pre>><VAR>word</VAR> 2>&1
|
||||
</pre></td></tr></table>(see Duplicating File Descriptors below).
|
||||
</pre></td></tr></table>When using the second form, <VAR>word</VAR> may not expand to a number or
|
||||
<SAMP>`-'</SAMP>. If it does, other redirection operators apply
|
||||
(see Duplicating File Descriptors below) for compatibility reasons.
|
||||
</P><P>
|
||||
|
||||
<HR SIZE="6">
|
||||
@@ -3256,8 +3258,8 @@ is made to be a copy of that file descriptor.
|
||||
If the digits in <VAR>word</VAR> do not specify a file descriptor open for
|
||||
input, a redirection error occurs.
|
||||
If <VAR>word</VAR>
|
||||
evaluates to <SAMP>`-'</SAMP>, file descriptor <VAR>n</VAR> is closed. If
|
||||
<VAR>n</VAR> is not specified, the standard input (file descriptor 0) is used.
|
||||
evaluates to <SAMP>`-'</SAMP>, file descriptor <VAR>n</VAR> is closed.
|
||||
If <VAR>n</VAR> is not specified, the standard input (file descriptor 0) is used.
|
||||
<P>
|
||||
|
||||
The operator
|
||||
@@ -3266,8 +3268,10 @@ The operator
|
||||
<VAR>n</VAR> is not specified, the standard output (file descriptor 1) is used.
|
||||
If the digits in <VAR>word</VAR> do not specify a file descriptor open for
|
||||
output, a redirection error occurs.
|
||||
If <VAR>word</VAR>
|
||||
evaluates to <SAMP>`-'</SAMP>, file descriptor <VAR>n</VAR> is closed.
|
||||
As a special case, if <VAR>n</VAR> is omitted, and <VAR>word</VAR> does not
|
||||
expand to one or more digits, the standard output and standard
|
||||
expand to one or more digits or <SAMP>`-'</SAMP>, the standard output and standard
|
||||
error are redirected as described previously.
|
||||
</P><P>
|
||||
|
||||
@@ -4270,9 +4274,12 @@ being executed with the <CODE>.</CODE> (<CODE>source</CODE>) builtin,
|
||||
returning either <VAR>n</VAR> or
|
||||
the exit status of the last command executed within the script as the exit
|
||||
status of the script.
|
||||
If <VAR>n</VAR> is supplied, the return value is its least significant
|
||||
8 bits.
|
||||
Any command associated with the <CODE>RETURN</CODE> trap is executed
|
||||
before execution resumes after the function or script.
|
||||
The return status is non-zero if <CODE>return</CODE> is used outside a function
|
||||
The return status is non-zero if <CODE>return</CODE> is supplied a non-numeric
|
||||
argument or is used outside a function
|
||||
and not during the execution of a script by <CODE>.</CODE> or <CODE>source</CODE>.
|
||||
</P><P>
|
||||
|
||||
@@ -16600,7 +16607,7 @@ to permit their use in free software.
|
||||
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="bashref.html#SEC_About"> ? </A>]</TD>
|
||||
</TR></TABLE>
|
||||
<H1>About this document</H1>
|
||||
This document was generated by <I>Chet Ramey</I> on <I>September, 26 2011</I>
|
||||
This document was generated by <I>Chet Ramey</I> on <I>October, 24 2011</I>
|
||||
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
|
||||
"><I>texi2html</I></A>
|
||||
<P></P>
|
||||
@@ -16762,7 +16769,7 @@ the following structure:
|
||||
<BR>
|
||||
<FONT SIZE="-1">
|
||||
This document was generated
|
||||
by <I>Chet Ramey</I> on <I>September, 26 2011</I>
|
||||
by <I>Chet Ramey</I> on <I>October, 24 2011</I>
|
||||
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
|
||||
"><I>texi2html</I></A>
|
||||
|
||||
|
||||
+153
-149
@@ -2,10 +2,10 @@ This is bashref.info, produced by makeinfo version 4.13 from
|
||||
/Users/chet/src/bash/src/doc/bashref.texi.
|
||||
|
||||
This text is a brief description of the features that are present in
|
||||
the Bash shell (version 4.2, 25 September 2011).
|
||||
the Bash shell (version 4.2, 24 October 2011).
|
||||
|
||||
This is Edition 4.2, last updated 25 September 2011, of `The GNU
|
||||
Bash Reference Manual', for `Bash', Version 4.2.
|
||||
This is Edition 4.2, last updated 24 October 2011, of `The GNU Bash
|
||||
Reference Manual', for `Bash', Version 4.2.
|
||||
|
||||
Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
|
||||
@@ -38,10 +38,10 @@ Bash Features
|
||||
*************
|
||||
|
||||
This text is a brief description of the features that are present in
|
||||
the Bash shell (version 4.2, 25 September 2011).
|
||||
the Bash shell (version 4.2, 24 October 2011).
|
||||
|
||||
This is Edition 4.2, last updated 25 September 2011, of `The GNU
|
||||
Bash Reference Manual', for `Bash', Version 4.2.
|
||||
This is Edition 4.2, last updated 24 October 2011, of `The GNU Bash
|
||||
Reference Manual', for `Bash', Version 4.2.
|
||||
|
||||
Bash contains features that appear in other popular shells, and some
|
||||
features that only appear in Bash. Some of the shells that Bash has
|
||||
@@ -2034,7 +2034,9 @@ error:
|
||||
Of the two forms, the first is preferred. This is semantically
|
||||
equivalent to
|
||||
>WORD 2>&1
|
||||
(see Duplicating File Descriptors below).
|
||||
When using the second form, WORD may not expand to a number or `-'.
|
||||
If it does, other redirection operators apply (see Duplicating File
|
||||
Descriptors below) for compatibility reasons.
|
||||
|
||||
3.6.5 Appending Standard Output and Standard Error
|
||||
--------------------------------------------------
|
||||
@@ -2105,8 +2107,9 @@ the standard input (file descriptor 0) is used.
|
||||
is used similarly to duplicate output file descriptors. If N is not
|
||||
specified, the standard output (file descriptor 1) is used. If the
|
||||
digits in WORD do not specify a file descriptor open for output, a
|
||||
redirection error occurs. As a special case, if N is omitted, and WORD
|
||||
does not expand to one or more digits, the standard output and standard
|
||||
redirection error occurs. If WORD evaluates to `-', file descriptor N
|
||||
is closed. As a special case, if N is omitted, and WORD does not
|
||||
expand to one or more digits or `-', the standard output and standard
|
||||
error are redirected as described previously.
|
||||
|
||||
3.6.9 Moving File Descriptors
|
||||
@@ -2750,11 +2753,12 @@ standard.
|
||||
also be used to terminate execution of a script being executed
|
||||
with the `.' (`source') builtin, returning either N or the exit
|
||||
status of the last command executed within the script as the exit
|
||||
status of the script. Any command associated with the `RETURN'
|
||||
trap is executed before execution resumes after the function or
|
||||
script. The return status is non-zero if `return' is used outside
|
||||
a function and not during the execution of a script by `.' or
|
||||
`source'.
|
||||
status of the script. If N is supplied, the return value is its
|
||||
least significant 8 bits. Any command associated with the
|
||||
`RETURN' trap is executed before execution resumes after the
|
||||
function or script. The return status is non-zero if `return' is
|
||||
supplied a non-numeric argument or is used outside a function and
|
||||
not during the execution of a script by `.' or `source'.
|
||||
|
||||
`shift'
|
||||
shift [N]
|
||||
@@ -10013,7 +10017,7 @@ D.1 Index of Shell Builtin Commands
|
||||
* :: Bourne Shell Builtins.
|
||||
(line 11)
|
||||
* [: Bourne Shell Builtins.
|
||||
(line 240)
|
||||
(line 241)
|
||||
* alias: Bash Builtins. (line 11)
|
||||
* bg: Job Control Builtins.
|
||||
(line 7)
|
||||
@@ -10082,25 +10086,25 @@ D.1 Index of Shell Builtin Commands
|
||||
(line 212)
|
||||
* set: The Set Builtin. (line 11)
|
||||
* shift: Bourne Shell Builtins.
|
||||
(line 227)
|
||||
(line 228)
|
||||
* shopt: The Shopt Builtin. (line 9)
|
||||
* source: Bash Builtins. (line 550)
|
||||
* suspend: Job Control Builtins.
|
||||
(line 99)
|
||||
* test: Bourne Shell Builtins.
|
||||
(line 240)
|
||||
(line 241)
|
||||
* times: Bourne Shell Builtins.
|
||||
(line 316)
|
||||
(line 317)
|
||||
* trap: Bourne Shell Builtins.
|
||||
(line 322)
|
||||
(line 323)
|
||||
* type: Bash Builtins. (line 555)
|
||||
* typeset: Bash Builtins. (line 587)
|
||||
* ulimit: Bash Builtins. (line 593)
|
||||
* umask: Bourne Shell Builtins.
|
||||
(line 369)
|
||||
(line 370)
|
||||
* unalias: Bash Builtins. (line 684)
|
||||
* unset: Bourne Shell Builtins.
|
||||
(line 387)
|
||||
(line 388)
|
||||
* wait: Job Control Builtins.
|
||||
(line 76)
|
||||
|
||||
@@ -10606,133 +10610,133 @@ D.5 Concept Index
|
||||
|
||||
|
||||
Tag Table:
|
||||
Node: Top1348
|
||||
Node: Introduction3190
|
||||
Node: What is Bash?3418
|
||||
Node: What is a shell?4531
|
||||
Node: Definitions7070
|
||||
Node: Basic Shell Features9988
|
||||
Node: Shell Syntax11207
|
||||
Node: Shell Operation12237
|
||||
Node: Quoting13531
|
||||
Node: Escape Character14834
|
||||
Node: Single Quotes15319
|
||||
Node: Double Quotes15667
|
||||
Node: ANSI-C Quoting16792
|
||||
Node: Locale Translation18036
|
||||
Node: Comments18932
|
||||
Node: Shell Commands19550
|
||||
Node: Simple Commands20422
|
||||
Node: Pipelines21053
|
||||
Node: Lists23752
|
||||
Node: Compound Commands25481
|
||||
Node: Looping Constructs26487
|
||||
Node: Conditional Constructs28950
|
||||
Node: Command Grouping37095
|
||||
Node: Coprocesses38574
|
||||
Node: GNU Parallel40248
|
||||
Node: Shell Functions42716
|
||||
Node: Shell Parameters47800
|
||||
Node: Positional Parameters50405
|
||||
Node: Special Parameters51305
|
||||
Node: Shell Expansions54269
|
||||
Node: Brace Expansion56195
|
||||
Node: Tilde Expansion58949
|
||||
Node: Shell Parameter Expansion61298
|
||||
Node: Command Substitution70432
|
||||
Node: Arithmetic Expansion71765
|
||||
Node: Process Substitution72615
|
||||
Node: Word Splitting73665
|
||||
Node: Filename Expansion75288
|
||||
Node: Pattern Matching77453
|
||||
Node: Quote Removal81153
|
||||
Node: Redirections81448
|
||||
Node: Executing Commands90285
|
||||
Node: Simple Command Expansion90955
|
||||
Node: Command Search and Execution92885
|
||||
Node: Command Execution Environment95222
|
||||
Node: Environment98208
|
||||
Node: Exit Status99867
|
||||
Node: Signals101489
|
||||
Node: Shell Scripts103457
|
||||
Node: Shell Builtin Commands105975
|
||||
Node: Bourne Shell Builtins108003
|
||||
Node: Bash Builtins126676
|
||||
Node: Modifying Shell Behavior153054
|
||||
Node: The Set Builtin153399
|
||||
Node: The Shopt Builtin163147
|
||||
Node: Special Builtins176848
|
||||
Node: Shell Variables177827
|
||||
Node: Bourne Shell Variables178267
|
||||
Node: Bash Variables180298
|
||||
Node: Bash Features205299
|
||||
Node: Invoking Bash206198
|
||||
Node: Bash Startup Files211960
|
||||
Node: Interactive Shells216979
|
||||
Node: What is an Interactive Shell?217389
|
||||
Node: Is this Shell Interactive?218038
|
||||
Node: Interactive Shell Behavior218853
|
||||
Node: Bash Conditional Expressions222133
|
||||
Node: Shell Arithmetic225921
|
||||
Node: Aliases228680
|
||||
Node: Arrays231236
|
||||
Node: The Directory Stack235444
|
||||
Node: Directory Stack Builtins236163
|
||||
Node: Controlling the Prompt239119
|
||||
Node: The Restricted Shell241891
|
||||
Node: Bash POSIX Mode243728
|
||||
Node: Job Control252876
|
||||
Node: Job Control Basics253336
|
||||
Node: Job Control Builtins258055
|
||||
Node: Job Control Variables262407
|
||||
Node: Command Line Editing263565
|
||||
Node: Introduction and Notation265132
|
||||
Node: Readline Interaction266754
|
||||
Node: Readline Bare Essentials267945
|
||||
Node: Readline Movement Commands269734
|
||||
Node: Readline Killing Commands270699
|
||||
Node: Readline Arguments272619
|
||||
Node: Searching273663
|
||||
Node: Readline Init File275849
|
||||
Node: Readline Init File Syntax276996
|
||||
Node: Conditional Init Constructs292338
|
||||
Node: Sample Init File294871
|
||||
Node: Bindable Readline Commands297988
|
||||
Node: Commands For Moving299195
|
||||
Node: Commands For History300339
|
||||
Node: Commands For Text304524
|
||||
Node: Commands For Killing307197
|
||||
Node: Numeric Arguments309654
|
||||
Node: Commands For Completion310793
|
||||
Node: Keyboard Macros314985
|
||||
Node: Miscellaneous Commands315556
|
||||
Node: Readline vi Mode321362
|
||||
Node: Programmable Completion322269
|
||||
Node: Programmable Completion Builtins329479
|
||||
Node: Using History Interactively338615
|
||||
Node: Bash History Facilities339299
|
||||
Node: Bash History Builtins342213
|
||||
Node: History Interaction346141
|
||||
Node: Event Designators348846
|
||||
Node: Word Designators350068
|
||||
Node: Modifiers351707
|
||||
Node: Installing Bash353111
|
||||
Node: Basic Installation354248
|
||||
Node: Compilers and Options356940
|
||||
Node: Compiling For Multiple Architectures357681
|
||||
Node: Installation Names359345
|
||||
Node: Specifying the System Type360163
|
||||
Node: Sharing Defaults360879
|
||||
Node: Operation Controls361552
|
||||
Node: Optional Features362510
|
||||
Node: Reporting Bugs372082
|
||||
Node: Major Differences From The Bourne Shell373283
|
||||
Node: GNU Free Documentation License389975
|
||||
Node: Indexes415171
|
||||
Node: Builtin Index415625
|
||||
Node: Reserved Word Index422452
|
||||
Node: Variable Index424900
|
||||
Node: Function Index437995
|
||||
Node: Concept Index445150
|
||||
Node: Top1344
|
||||
Node: Introduction3182
|
||||
Node: What is Bash?3410
|
||||
Node: What is a shell?4523
|
||||
Node: Definitions7062
|
||||
Node: Basic Shell Features9980
|
||||
Node: Shell Syntax11199
|
||||
Node: Shell Operation12229
|
||||
Node: Quoting13523
|
||||
Node: Escape Character14826
|
||||
Node: Single Quotes15311
|
||||
Node: Double Quotes15659
|
||||
Node: ANSI-C Quoting16784
|
||||
Node: Locale Translation18028
|
||||
Node: Comments18924
|
||||
Node: Shell Commands19542
|
||||
Node: Simple Commands20414
|
||||
Node: Pipelines21045
|
||||
Node: Lists23744
|
||||
Node: Compound Commands25473
|
||||
Node: Looping Constructs26479
|
||||
Node: Conditional Constructs28942
|
||||
Node: Command Grouping37087
|
||||
Node: Coprocesses38566
|
||||
Node: GNU Parallel40240
|
||||
Node: Shell Functions42708
|
||||
Node: Shell Parameters47792
|
||||
Node: Positional Parameters50397
|
||||
Node: Special Parameters51297
|
||||
Node: Shell Expansions54261
|
||||
Node: Brace Expansion56187
|
||||
Node: Tilde Expansion58941
|
||||
Node: Shell Parameter Expansion61290
|
||||
Node: Command Substitution70424
|
||||
Node: Arithmetic Expansion71757
|
||||
Node: Process Substitution72607
|
||||
Node: Word Splitting73657
|
||||
Node: Filename Expansion75280
|
||||
Node: Pattern Matching77445
|
||||
Node: Quote Removal81145
|
||||
Node: Redirections81440
|
||||
Node: Executing Commands90480
|
||||
Node: Simple Command Expansion91150
|
||||
Node: Command Search and Execution93080
|
||||
Node: Command Execution Environment95417
|
||||
Node: Environment98403
|
||||
Node: Exit Status100062
|
||||
Node: Signals101684
|
||||
Node: Shell Scripts103652
|
||||
Node: Shell Builtin Commands106170
|
||||
Node: Bourne Shell Builtins108198
|
||||
Node: Bash Builtins126983
|
||||
Node: Modifying Shell Behavior153361
|
||||
Node: The Set Builtin153706
|
||||
Node: The Shopt Builtin163454
|
||||
Node: Special Builtins177155
|
||||
Node: Shell Variables178134
|
||||
Node: Bourne Shell Variables178574
|
||||
Node: Bash Variables180605
|
||||
Node: Bash Features205606
|
||||
Node: Invoking Bash206505
|
||||
Node: Bash Startup Files212267
|
||||
Node: Interactive Shells217286
|
||||
Node: What is an Interactive Shell?217696
|
||||
Node: Is this Shell Interactive?218345
|
||||
Node: Interactive Shell Behavior219160
|
||||
Node: Bash Conditional Expressions222440
|
||||
Node: Shell Arithmetic226228
|
||||
Node: Aliases228987
|
||||
Node: Arrays231543
|
||||
Node: The Directory Stack235751
|
||||
Node: Directory Stack Builtins236470
|
||||
Node: Controlling the Prompt239426
|
||||
Node: The Restricted Shell242198
|
||||
Node: Bash POSIX Mode244035
|
||||
Node: Job Control253183
|
||||
Node: Job Control Basics253643
|
||||
Node: Job Control Builtins258362
|
||||
Node: Job Control Variables262714
|
||||
Node: Command Line Editing263872
|
||||
Node: Introduction and Notation265439
|
||||
Node: Readline Interaction267061
|
||||
Node: Readline Bare Essentials268252
|
||||
Node: Readline Movement Commands270041
|
||||
Node: Readline Killing Commands271006
|
||||
Node: Readline Arguments272926
|
||||
Node: Searching273970
|
||||
Node: Readline Init File276156
|
||||
Node: Readline Init File Syntax277303
|
||||
Node: Conditional Init Constructs292645
|
||||
Node: Sample Init File295178
|
||||
Node: Bindable Readline Commands298295
|
||||
Node: Commands For Moving299502
|
||||
Node: Commands For History300646
|
||||
Node: Commands For Text304831
|
||||
Node: Commands For Killing307504
|
||||
Node: Numeric Arguments309961
|
||||
Node: Commands For Completion311100
|
||||
Node: Keyboard Macros315292
|
||||
Node: Miscellaneous Commands315863
|
||||
Node: Readline vi Mode321669
|
||||
Node: Programmable Completion322576
|
||||
Node: Programmable Completion Builtins329786
|
||||
Node: Using History Interactively338922
|
||||
Node: Bash History Facilities339606
|
||||
Node: Bash History Builtins342520
|
||||
Node: History Interaction346448
|
||||
Node: Event Designators349153
|
||||
Node: Word Designators350375
|
||||
Node: Modifiers352014
|
||||
Node: Installing Bash353418
|
||||
Node: Basic Installation354555
|
||||
Node: Compilers and Options357247
|
||||
Node: Compiling For Multiple Architectures357988
|
||||
Node: Installation Names359652
|
||||
Node: Specifying the System Type360470
|
||||
Node: Sharing Defaults361186
|
||||
Node: Operation Controls361859
|
||||
Node: Optional Features362817
|
||||
Node: Reporting Bugs372389
|
||||
Node: Major Differences From The Bourne Shell373590
|
||||
Node: GNU Free Documentation License390282
|
||||
Node: Indexes415478
|
||||
Node: Builtin Index415932
|
||||
Node: Reserved Word Index422759
|
||||
Node: Variable Index425207
|
||||
Node: Function Index438302
|
||||
Node: Concept Index445457
|
||||
|
||||
End Tag Table
|
||||
|
||||
+11
-11
@@ -1,4 +1,4 @@
|
||||
This is TeX, Version 3.141592 (Web2C 7.5.4) (format=tex 2008.12.11) 26 SEP 2011 10:56
|
||||
This is TeX, Version 3.141592 (Web2C 7.5.4) (format=tex 2008.12.11) 24 OCT 2011 08:43
|
||||
**/Users/chet/src/bash/src/doc/bashref.texi
|
||||
(/Users/chet/src/bash/src/doc/bashref.texi (./texinfo.tex
|
||||
Loading texinfo [version 2009-01-18.17]:
|
||||
@@ -232,7 +232,7 @@ arallel -k traceroute[]
|
||||
[15] [16] [17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29]
|
||||
[30] [31] [32] [33] [34] Chapter 4 [35] [36] [37] [38] [39] [40] [41] [42]
|
||||
[43]
|
||||
Underfull \hbox (badness 5231) in paragraph at lines 3479--3492
|
||||
Underfull \hbox (badness 5231) in paragraph at lines 3486--3499
|
||||
@texttt emacs-meta[]@textrm , @texttt emacs-ctlx[]@textrm , @texttt vi[]@textr
|
||||
m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
|
||||
|
||||
@@ -246,7 +246,7 @@ m , @texttt vi-move[]@textrm , @texttt vi-command[]@textrm , and
|
||||
|
||||
[44] [45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58]
|
||||
[59] [60]
|
||||
Underfull \hbox (badness 5460) in paragraph at lines 4725--4731
|
||||
Underfull \hbox (badness 5460) in paragraph at lines 4732--4738
|
||||
[]@textrm If set, range ex-pres-sions used in pat-tern match-ing (see
|
||||
|
||||
@hbox(8.2125+2.73749)x433.62, glue set 3.79674
|
||||
@@ -259,7 +259,7 @@ Underfull \hbox (badness 5460) in paragraph at lines 4725--4731
|
||||
|
||||
[61] [62] Chapter 5 [63] [64] [65] [66] [67] [68] [69] [70] [71] [72] [73]
|
||||
Chapter 6 [74]
|
||||
Overfull \hbox (51.96864pt too wide) in paragraph at lines 5617--5617
|
||||
Overfull \hbox (51.96864pt too wide) in paragraph at lines 5624--5624
|
||||
[]@texttt bash [long-opt] [-ir] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@t
|
||||
exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
|
||||
|
||||
@@ -272,7 +272,7 @@ exttt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
|
||||
.etc.
|
||||
|
||||
|
||||
Overfull \hbox (76.23077pt too wide) in paragraph at lines 5618--5618
|
||||
Overfull \hbox (76.23077pt too wide) in paragraph at lines 5625--5625
|
||||
[]@texttt bash [long-opt] [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@texttt
|
||||
] [-O @textttsl shopt_option@texttt ] -c @textttsl string @texttt [@textttsl ar
|
||||
-
|
||||
@@ -286,7 +286,7 @@ Overfull \hbox (76.23077pt too wide) in paragraph at lines 5618--5618
|
||||
.etc.
|
||||
|
||||
|
||||
Overfull \hbox (34.72258pt too wide) in paragraph at lines 5619--5619
|
||||
Overfull \hbox (34.72258pt too wide) in paragraph at lines 5626--5626
|
||||
[]@texttt bash [long-opt] -s [-abefhkmnptuvxdBCDHP] [-o @textttsl op-tion@text
|
||||
tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
|
||||
|
||||
@@ -299,7 +299,7 @@ tt ] [-O @textttsl shopt_option@texttt ] [@textttsl ar-
|
||||
.etc.
|
||||
|
||||
[75] [76]
|
||||
Underfull \hbox (badness 2245) in paragraph at lines 5790--5792
|
||||
Underfull \hbox (badness 2245) in paragraph at lines 5797--5799
|
||||
[]@textrm When a lo-gin shell ex-its, Bash reads and ex-e-cutes com-mands from
|
||||
the file
|
||||
|
||||
@@ -312,7 +312,7 @@ the file
|
||||
.etc.
|
||||
|
||||
[77] [78] [79] [80] [81] [82] [83] [84] [85] [86] [87] [88] [89] [90]
|
||||
Underfull \hbox (badness 2521) in paragraph at lines 6980--6983
|
||||
Underfull \hbox (badness 2521) in paragraph at lines 6987--6990
|
||||
@textrm `@texttt --enable-strict-posix-default[]@textrm '[] to @texttt configur
|
||||
e[] @textrm when build-ing (see Sec-tion 10.8
|
||||
|
||||
@@ -381,7 +381,7 @@ Underfull \hbox (badness 2753) in paragraph at lines 1946--1949
|
||||
[123] [124]) (/Users/chet/src/bash/src/lib/readline/doc/hsuser.texi Chapter 9
|
||||
[125] [126] [127] [128] [129] [130]) Chapter 10 [131] [132] [133] [134]
|
||||
[135]
|
||||
Underfull \hbox (badness 2772) in paragraph at lines 7586--7590
|
||||
Underfull \hbox (badness 2772) in paragraph at lines 7593--7597
|
||||
[]@textrm Enable sup-port for large files (@texttt http://www.sas.com/standard
|
||||
s/large_
|
||||
|
||||
@@ -401,10 +401,10 @@ s/large_
|
||||
Here is how much of TeX's memory you used:
|
||||
2081 strings out of 97980
|
||||
28573 string characters out of 1221004
|
||||
65630 words of memory out of 1500000
|
||||
65626 words of memory out of 1500000
|
||||
2897 multiletter control sequences out of 10000+50000
|
||||
32127 words of font info for 112 fonts, out of 1200000 for 2000
|
||||
51 hyphenation exceptions out of 8191
|
||||
16i,6n,14p,315b,702s stack positions out of 5000i,500n,6000p,200000b,5000s
|
||||
|
||||
Output written on bashref.dvi (170 pages, 687040 bytes).
|
||||
Output written on bashref.dvi (170 pages, 687440 bytes).
|
||||
|
||||
Binary file not shown.
+96
-88
@@ -11,7 +11,7 @@
|
||||
%DVIPSWebPage: (www.radicaleye.com)
|
||||
%DVIPSCommandLine: dvips -D 600 -t letter -o bashref.ps bashref.dvi
|
||||
%DVIPSParameters: dpi=600
|
||||
%DVIPSSource: TeX output 2011.09.26:1056
|
||||
%DVIPSSource: TeX output 2011.10.24:0843
|
||||
%%BeginProcSet: tex.pro 0 0
|
||||
%!
|
||||
/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S
|
||||
@@ -4323,30 +4323,29 @@ letter
|
||||
TeXDict begin 1 0 bop 150 1318 a Fu(Bash)64 b(Reference)j(Man)-5
|
||||
b(ual)p 150 1385 3600 34 v 2361 1481 a Ft(Reference)31
|
||||
b(Do)s(cumen)m(tation)i(for)d(Bash)2428 1589 y(Edition)h(4.2,)g(for)f
|
||||
Fs(Bash)g Ft(V)-8 b(ersion)31 b(4.2.)3118 1697 y(Septem)m(b)s(er)f
|
||||
(2011)150 4935 y Fr(Chet)45 b(Ramey)-11 b(,)46 b(Case)g(W)-11
|
||||
b(estern)46 b(Reserv)l(e)g(Univ)l(ersit)l(y)150 5068
|
||||
y(Brian)f(F)-11 b(o)l(x,)45 b(F)-11 b(ree)45 b(Soft)l(w)l(are)h(F)-11
|
||||
Fs(Bash)g Ft(V)-8 b(ersion)31 b(4.2.)3217 1697 y(Octob)s(er)f(2011)150
|
||||
4935 y Fr(Chet)45 b(Ramey)-11 b(,)46 b(Case)g(W)-11 b(estern)46
|
||||
b(Reserv)l(e)g(Univ)l(ersit)l(y)150 5068 y(Brian)f(F)-11
|
||||
b(o)l(x,)45 b(F)-11 b(ree)45 b(Soft)l(w)l(are)h(F)-11
|
||||
b(oundation)p 150 5141 3600 17 v eop end
|
||||
%%Page: 2 2
|
||||
TeXDict begin 2 1 bop 150 2889 a Ft(This)35 b(text)h(is)g(a)g(brief)f
|
||||
(description)h(of)f(the)h(features)g(that)g(are)g(presen)m(t)g(in)f
|
||||
(the)h(Bash)f(shell)h(\(v)m(ersion)150 2999 y(4.2,)c(25)f(Septem)m(b)s
|
||||
(er)f(2011\).)150 3133 y(This)e(is)h(Edition)f(4.2,)j(last)e(up)s
|
||||
(dated)f(25)h(Septem)m(b)s(er)f(2011,)j(of)e Fq(The)f(GNU)i(Bash)e
|
||||
(Reference)i(Man)m(ual)p Ft(,)150 3243 y(for)g Fs(Bash)p
|
||||
Ft(,)g(V)-8 b(ersion)31 b(4.2.)150 3377 y(Cop)m(yrigh)m(t)602
|
||||
3374 y(c)577 3377 y Fp(\015)f Ft(1988{2011)35 b(F)-8
|
||||
b(ree)31 b(Soft)m(w)m(are)h(F)-8 b(oundation,)31 b(Inc.)150
|
||||
3512 y(P)m(ermission)h(is)h(gran)m(ted)g(to)f(mak)m(e)i(and)d
|
||||
(distribute)h(v)m(erbatim)h(copies)g(of)f(this)g(man)m(ual)h(pro)m
|
||||
(vided)f(the)150 3621 y(cop)m(yrigh)m(t)g(notice)f(and)f(this)g(p)s
|
||||
(ermission)g(notice)h(are)g(preserv)m(ed)f(on)h(all)g(copies.)390
|
||||
3756 y(P)m(ermission)k(is)h(gran)m(ted)f(to)h(cop)m(y)-8
|
||||
b(,)38 b(distribute)d(and/or)g(mo)s(dify)f(this)h(do)s(cumen)m(t)g
|
||||
(under)390 3866 y(the)j(terms)g(of)g(the)g(GNU)h(F)-8
|
||||
b(ree)39 b(Do)s(cumen)m(tation)h(License,)g(V)-8 b(ersion)39
|
||||
b(1.3)g(or)f(an)m(y)g(later)390 3975 y(v)m(ersion)28
|
||||
(the)h(Bash)f(shell)h(\(v)m(ersion)150 2999 y(4.2,)c(24)f(Octob)s(er)f
|
||||
(2011\).)150 3133 y(This)35 b(is)g(Edition)h(4.2,)i(last)f(up)s(dated)d
|
||||
(24)i(Octob)s(er)g(2011,)j(of)c Fq(The)h(GNU)g(Bash)f(Reference)i(Man)m
|
||||
(ual)p Ft(,)150 3243 y(for)30 b Fs(Bash)p Ft(,)g(V)-8
|
||||
b(ersion)31 b(4.2.)150 3377 y(Cop)m(yrigh)m(t)602 3374
|
||||
y(c)577 3377 y Fp(\015)f Ft(1988{2011)35 b(F)-8 b(ree)31
|
||||
b(Soft)m(w)m(are)h(F)-8 b(oundation,)31 b(Inc.)150 3512
|
||||
y(P)m(ermission)h(is)h(gran)m(ted)g(to)f(mak)m(e)i(and)d(distribute)h
|
||||
(v)m(erbatim)h(copies)g(of)f(this)g(man)m(ual)h(pro)m(vided)f(the)150
|
||||
3621 y(cop)m(yrigh)m(t)g(notice)f(and)f(this)g(p)s(ermission)g(notice)h
|
||||
(are)g(preserv)m(ed)f(on)h(all)g(copies.)390 3756 y(P)m(ermission)k(is)
|
||||
h(gran)m(ted)f(to)h(cop)m(y)-8 b(,)38 b(distribute)d(and/or)g(mo)s
|
||||
(dify)f(this)h(do)s(cumen)m(t)g(under)390 3866 y(the)j(terms)g(of)g
|
||||
(the)g(GNU)h(F)-8 b(ree)39 b(Do)s(cumen)m(tation)h(License,)g(V)-8
|
||||
b(ersion)39 b(1.3)g(or)f(an)m(y)g(later)390 3975 y(v)m(ersion)28
|
||||
b(published)d(b)m(y)j(the)f(F)-8 b(ree)29 b(Soft)m(w)m(are)f(F)-8
|
||||
b(oundation;)30 b(with)d(no)g(In)m(v)-5 b(arian)m(t)28
|
||||
b(Sections,)390 4085 y(with)i(the)h(F)-8 b(ron)m(t-Co)m(v)m(er)33
|
||||
@@ -6955,52 +6954,56 @@ Fq(n)p Ft(,)g(or)g(the)h(standard)e(output)h(\(\014le)h(descriptor)f
|
||||
(1\))h(if)g Fq(n)e Ft(is)i(not)150 665 y(sp)s(eci\014ed.)40
|
||||
b(If)30 b(the)g(\014le)h(do)s(es)f(not)h(exist)g(it)g(is)f(created;)i
|
||||
(if)e(it)h(do)s(es)f(exist)h(it)g(is)g(truncated)f(to)h(zero)g(size.)
|
||||
275 823 y(The)e(general)j(format)e(for)h(redirecting)g(output)f(is:)390
|
||||
981 y Fs([)p Fi(n)11 b Fs(]>[|])p Fi(word)275 1139 y
|
||||
275 812 y(The)e(general)j(format)e(for)h(redirecting)g(output)f(is:)390
|
||||
959 y Fs([)p Fi(n)11 b Fs(]>[|])p Fi(word)275 1107 y
|
||||
Ft(If)30 b(the)h(redirection)g(op)s(erator)g(is)g(`)p
|
||||
Fs(>)p Ft(',)g(and)f(the)h Fs(noclobber)d Ft(option)j(to)g(the)g
|
||||
Fs(set)f Ft(builtin)g(has)h(b)s(een)150 1249 y(enabled,)i(the)f
|
||||
Fs(set)f Ft(builtin)g(has)h(b)s(een)150 1216 y(enabled,)i(the)f
|
||||
(redirection)h(will)f(fail)h(if)f(the)g(\014le)g(whose)g(name)g
|
||||
(results)g(from)g(the)g(expansion)g(of)g Fq(w)m(ord)150
|
||||
1359 y Ft(exists)f(and)f(is)g(a)h(regular)g(\014le.)41
|
||||
1326 y Ft(exists)f(and)f(is)g(a)h(regular)g(\014le.)41
|
||||
b(If)30 b(the)h(redirection)g(op)s(erator)g(is)f(`)p
|
||||
Fs(>|)p Ft(',)h(or)f(the)h(redirection)g(op)s(erator)g(is)150
|
||||
1468 y(`)p Fs(>)p Ft(')36 b(and)f(the)g Fs(noclobber)e
|
||||
1435 y(`)p Fs(>)p Ft(')36 b(and)f(the)g Fs(noclobber)e
|
||||
Ft(option)j(is)g(not)g(enabled,)h(the)e(redirection)h(is)g(attempted)g
|
||||
(ev)m(en)h(if)e(the)h(\014le)150 1578 y(named)30 b(b)m(y)g
|
||||
Fq(w)m(ord)k Ft(exists.)150 1801 y Fj(3.6.3)63 b(App)s(ending)42
|
||||
b(Redirected)e(Output)150 1948 y Ft(Redirection)23 b(of)e(output)h(in)f
|
||||
(ev)m(en)h(if)e(the)h(\014le)150 1545 y(named)30 b(b)m(y)g
|
||||
Fq(w)m(ord)k Ft(exists.)150 1757 y Fj(3.6.3)63 b(App)s(ending)42
|
||||
b(Redirected)e(Output)150 1904 y Ft(Redirection)23 b(of)e(output)h(in)f
|
||||
(this)h(fashion)f(causes)h(the)g(\014le)g(whose)f(name)h(results)f
|
||||
(from)g(the)h(expansion)g(of)150 2057 y Fq(w)m(ord)28
|
||||
(from)g(the)h(expansion)g(of)150 2013 y Fq(w)m(ord)28
|
||||
b Ft(to)e(b)s(e)e(op)s(ened)g(for)h(app)s(ending)e(on)i(\014le)g
|
||||
(descriptor)g Fq(n)p Ft(,)g(or)g(the)g(standard)f(output)h(\(\014le)g
|
||||
(descriptor)150 2167 y(1\))31 b(if)f Fq(n)g Ft(is)h(not)f(sp)s
|
||||
(descriptor)150 2123 y(1\))31 b(if)f Fq(n)g Ft(is)h(not)f(sp)s
|
||||
(eci\014ed.)40 b(If)30 b(the)h(\014le)f(do)s(es)g(not)h(exist)g(it)g
|
||||
(is)f(created.)275 2325 y(The)f(general)j(format)e(for)h(app)s(ending)e
|
||||
(output)h(is:)390 2483 y Fs([)p Fi(n)11 b Fs(]>>)p Fi(word)150
|
||||
2706 y Fj(3.6.4)63 b(Redirecting)40 b(Standard)h(Output)g(and)g
|
||||
(Standard)g(Error)150 2853 y Ft(This)33 b(construct)i(allo)m(ws)g(b)s
|
||||
(is)f(created.)275 2270 y(The)f(general)j(format)e(for)h(app)s(ending)e
|
||||
(output)h(is:)390 2417 y Fs([)p Fi(n)11 b Fs(]>>)p Fi(word)150
|
||||
2629 y Fj(3.6.4)63 b(Redirecting)40 b(Standard)h(Output)g(and)g
|
||||
(Standard)g(Error)150 2776 y Ft(This)33 b(construct)i(allo)m(ws)g(b)s
|
||||
(oth)f(the)g(standard)g(output)f(\(\014le)i(descriptor)f(1\))h(and)f
|
||||
(the)g(standard)f(error)150 2963 y(output)d(\(\014le)h(descriptor)f
|
||||
(the)g(standard)f(error)150 2886 y(output)d(\(\014le)h(descriptor)f
|
||||
(2\))h(to)g(b)s(e)f(redirected)h(to)g(the)f(\014le)h(whose)f(name)h(is)
|
||||
f(the)g(expansion)h(of)f Fq(w)m(ord)t Ft(.)275 3121 y(There)f(are)i(t)m
|
||||
f(the)g(expansion)h(of)f Fq(w)m(ord)t Ft(.)275 3033 y(There)f(are)i(t)m
|
||||
(w)m(o)h(formats)e(for)h(redirecting)g(standard)e(output)h(and)g
|
||||
(standard)f(error:)390 3279 y Fs(&>)p Fi(word)150 3437
|
||||
y Ft(and)390 3595 y Fs(>&)p Fi(word)150 3753 y Ft(Of)h(the)g(t)m(w)m(o)
|
||||
(standard)f(error:)390 3180 y Fs(&>)p Fi(word)150 3328
|
||||
y Ft(and)390 3475 y Fs(>&)p Fi(word)150 3622 y Ft(Of)h(the)g(t)m(w)m(o)
|
||||
i(forms,)e(the)h(\014rst)e(is)i(preferred.)39 b(This)30
|
||||
b(is)g(seman)m(tically)j(equiv)-5 b(alen)m(t)32 b(to)390
|
||||
3912 y Fs(>)p Fi(word)57 b Fs(2>&1)275 4070 y Ft(\(see)31
|
||||
b(Duplicating)h(File)f(Descriptors)g(b)s(elo)m(w\).)150
|
||||
4293 y Fj(3.6.5)63 b(App)s(ending)42 b(Standard)f(Output)g(and)g
|
||||
(Standard)g(Error)150 4440 y Ft(This)33 b(construct)i(allo)m(ws)g(b)s
|
||||
3769 y Fs(>)p Fi(word)57 b Fs(2>&1)275 3916 y Ft(When)41
|
||||
b(using)g(the)h(second)f(form,)k Fq(w)m(ord)f Ft(ma)m(y)e(not)g(expand)
|
||||
f(to)h(a)g(n)m(um)m(b)s(er)f(or)g(`)p Fs(-)p Ft('.)75
|
||||
b(If)41 b(it)h(do)s(es,)150 4026 y(other)27 b(redirection)g(op)s
|
||||
(erators)f(apply)h(\(see)g(Duplicating)h(File)f(Descriptors)h(b)s(elo)m
|
||||
(w\))f(for)f(compatibilit)m(y)150 4135 y(reasons.)150
|
||||
4347 y Fj(3.6.5)63 b(App)s(ending)42 b(Standard)f(Output)g(and)g
|
||||
(Standard)g(Error)150 4494 y Ft(This)33 b(construct)i(allo)m(ws)g(b)s
|
||||
(oth)f(the)g(standard)g(output)f(\(\014le)i(descriptor)f(1\))h(and)f
|
||||
(the)g(standard)f(error)150 4549 y(output)d(\(\014le)h(descriptor)f
|
||||
(the)g(standard)f(error)150 4604 y(output)d(\(\014le)h(descriptor)f
|
||||
(2\))h(to)g(b)s(e)f(app)s(ended)f(to)i(the)f(\014le)h(whose)f(name)g
|
||||
(is)h(the)f(expansion)h(of)f Fq(w)m(ord)t Ft(.)275 4707
|
||||
(is)h(the)f(expansion)h(of)f Fq(w)m(ord)t Ft(.)275 4751
|
||||
y(The)f(format)i(for)f(app)s(ending)f(standard)h(output)g(and)f
|
||||
(standard)h(error)g(is:)390 4866 y Fs(&>>)p Fi(word)150
|
||||
5024 y Ft(This)g(is)g(seman)m(tically)j(equiv)-5 b(alen)m(t)32
|
||||
b(to)390 5182 y Fs(>>)p Fi(word)57 b Fs(2>&1)275 5340
|
||||
(standard)h(error)g(is:)390 4898 y Fs(&>>)p Fi(word)150
|
||||
5046 y Ft(This)g(is)g(seman)m(tically)j(equiv)-5 b(alen)m(t)32
|
||||
b(to)390 5193 y Fs(>>)p Fi(word)57 b Fs(2>&1)275 5340
|
||||
y Ft(\(see)31 b(Duplicating)h(File)f(Descriptors)g(b)s(elo)m(w\).)p
|
||||
eop end
|
||||
%%Page: 30 36
|
||||
@@ -7067,12 +7070,14 @@ b Fq(n)f Ft(is)i(not)f(sp)s(eci\014ed,)i(the)f(standard)150
|
||||
5011 y(output)30 b(\(\014le)g(descriptor)g(1\))h(is)f(used.)39
|
||||
b(If)30 b(the)g(digits)h(in)e Fq(w)m(ord)34 b Ft(do)29
|
||||
b(not)i(sp)s(ecify)e(a)i(\014le)f(descriptor)g(op)s(en)150
|
||||
5121 y(for)38 b(output,)i(a)e(redirection)h(error)f(o)s(ccurs.)63
|
||||
b(As)38 b(a)h(sp)s(ecial)f(case,)k(if)c Fq(n)f Ft(is)h(omitted,)k(and)
|
||||
37 b Fq(w)m(ord)k Ft(do)s(es)150 5230 y(not)28 b(expand)f(to)i(one)f
|
||||
(or)f(more)h(digits,)i(the)e(standard)e(output)i(and)f(standard)g
|
||||
(error)g(are)i(redirected)f(as)150 5340 y(describ)s(ed)h(previously)-8
|
||||
b(.)p eop end
|
||||
5121 y(for)35 b(output,)h(a)g(redirection)g(error)e(o)s(ccurs.)55
|
||||
b(If)35 b Fq(w)m(ord)j Ft(ev)-5 b(aluates)37 b(to)f(`)p
|
||||
Fs(-)p Ft(',)h(\014le)e(descriptor)g Fq(n)g Ft(is)g(closed.)150
|
||||
5230 y(As)f(a)g(sp)s(ecial)h(case,)h(if)e Fq(n)f Ft(is)h(omitted,)i
|
||||
(and)e Fq(w)m(ord)j Ft(do)s(es)d(not)g(expand)f(to)i(one)f(or)g(more)g
|
||||
(digits)h(or)f(`)p Fs(-)p Ft(',)150 5340 y(the)d(standard)e(output)h
|
||||
(and)g(standard)f(error)h(are)h(redirected)g(as)g(describ)s(ed)e
|
||||
(previously)-8 b(.)p eop end
|
||||
%%Page: 31 37
|
||||
TeXDict begin 31 36 bop 150 -116 a Ft(Chapter)30 b(3:)41
|
||||
b(Basic)32 b(Shell)e(F)-8 b(eatures)2246 b(31)150 299
|
||||
@@ -7818,65 +7823,68 @@ b(in)f(the)h(function.)53 b Fs(return)33 b Ft(ma)m(y)i(also)g(b)s(e)f
|
||||
(used)f(to)j(terminate)f(execution)h(of)630 408 y(a)e(script)g(b)s
|
||||
(eing)g(executed)g(with)g(the)g Fs(.)g Ft(\()p Fs(source)p
|
||||
Ft(\))f(builtin,)h(returning)f(either)i Fq(n)e Ft(or)h(the)630
|
||||
518 y(exit)29 b(status)f(of)g(the)h(last)g(command)e(executed)i(within)
|
||||
f(the)g(script)g(as)g(the)g(exit)h(status)g(of)630 628
|
||||
y(the)34 b(script.)51 b(An)m(y)34 b(command)g(asso)s(ciated)h(with)f
|
||||
(the)g Fs(RETURN)e Ft(trap)i(is)g(executed)g(b)s(efore)630
|
||||
737 y(execution)d(resumes)e(after)i(the)f(function)f(or)h(script.)40
|
||||
b(The)30 b(return)f(status)h(is)g(non-zero)g(if)630 847
|
||||
y Fs(return)c Ft(is)i(used)f(outside)h(a)h(function)e(and)g(not)i
|
||||
(during)d(the)i(execution)h(of)f(a)h(script)e(b)m(y)h
|
||||
Fs(.)630 956 y Ft(or)i Fs(source)p Ft(.)150 1130 y Fs(shift)870
|
||||
1271 y(shift)46 b([)p Fi(n)11 b Fs(])630 1413 y Ft(Shift)41
|
||||
518 y(exit)j(status)f(of)g(the)g(last)h(command)e(executed)i(within)e
|
||||
(the)h(script)g(as)g(the)g(exit)h(status)630 628 y(of)i(the)g(script.)
|
||||
65 b(If)38 b Fq(n)g Ft(is)h(supplied,)h(the)f(return)e(v)-5
|
||||
b(alue)39 b(is)g(its)g(least)h(signi\014can)m(t)g(8)f(bits.)630
|
||||
737 y(An)m(y)g(command)f(asso)s(ciated)j(with)d(the)h
|
||||
Fs(RETURN)e Ft(trap)i(is)g(executed)g(b)s(efore)g(execution)630
|
||||
847 y(resumes)29 b(after)h(the)g(function)g(or)g(script.)40
|
||||
b(The)29 b(return)g(status)h(is)g(non-zero)g(if)g Fs(return)e
|
||||
Ft(is)630 956 y(supplied)h(a)i(non-n)m(umeric)g(argumen)m(t)g(or)f(is)h
|
||||
(used)f(outside)h(a)g(function)f(and)g(not)h(during)630
|
||||
1066 y(the)g(execution)g(of)g(a)f(script)h(b)m(y)f Fs(.)g
|
||||
Ft(or)g Fs(source)p Ft(.)150 1230 y Fs(shift)870 1367
|
||||
y(shift)46 b([)p Fi(n)11 b Fs(])630 1504 y Ft(Shift)41
|
||||
b(the)g(p)s(ositional)h(parameters)g(to)g(the)f(left)h(b)m(y)g
|
||||
Fq(n)p Ft(.)73 b(The)40 b(p)s(ositional)j(parameters)630
|
||||
1523 y(from)34 b Fq(n)p Fs(+)p Ft(1)39 b(.)22 b(.)h(.)45
|
||||
1614 y(from)34 b Fq(n)p Fs(+)p Ft(1)39 b(.)22 b(.)h(.)45
|
||||
b Fs($#)34 b Ft(are)g(renamed)g(to)h Fs($1)k Ft(.)22
|
||||
b(.)g(.)46 b Fs($#)p Ft(-)p Fq(n)p Ft(.)51 b(P)m(arameters)36
|
||||
b(represen)m(ted)e(b)m(y)g(the)630 1632 y(n)m(um)m(b)s(ers)25
|
||||
b(represen)m(ted)e(b)m(y)g(the)630 1724 y(n)m(um)m(b)s(ers)25
|
||||
b Fs($#)i Ft(to)g Fs($#)p Ft(-)p Fq(n)p Fs(+)p Ft(1)g(are)g(unset.)39
|
||||
b Fq(n)26 b Ft(m)m(ust)h(b)s(e)f(a)i(non-negativ)m(e)h(n)m(um)m(b)s(er)
|
||||
c(less)i(than)g(or)630 1742 y(equal)33 b(to)h Fs($#)p
|
||||
c(less)i(than)g(or)630 1833 y(equal)33 b(to)h Fs($#)p
|
||||
Ft(.)47 b(If)33 b Fq(n)f Ft(is)h(zero)g(or)g(greater)h(than)f
|
||||
Fs($#)p Ft(,)g(the)g(p)s(ositional)g(parameters)g(are)h(not)630
|
||||
1851 y(c)m(hanged.)48 b(If)32 b Fq(n)g Ft(is)h(not)f(supplied,)h(it)g
|
||||
1943 y(c)m(hanged.)48 b(If)32 b Fq(n)g Ft(is)h(not)f(supplied,)h(it)g
|
||||
(is)f(assumed)g(to)h(b)s(e)f(1.)48 b(The)32 b(return)g(status)h(is)f
|
||||
(zero)630 1961 y(unless)e Fq(n)f Ft(is)i(greater)g(than)g
|
||||
(zero)630 2052 y(unless)e Fq(n)f Ft(is)i(greater)g(than)g
|
||||
Fs($#)e Ft(or)i(less)f(than)h(zero,)g(non-zero)g(otherwise.)150
|
||||
2134 y Fs(test[B)150 2244 y([)870 2386 y(test)47 b Fi(expr)630
|
||||
2527 y Ft(Ev)-5 b(aluate)43 b(a)f(conditional)h(expression)f
|
||||
2217 y Fs(test[B)150 2326 y([)870 2463 y(test)47 b Fi(expr)630
|
||||
2600 y Ft(Ev)-5 b(aluate)43 b(a)f(conditional)h(expression)f
|
||||
Fq(expr)48 b Ft(and)41 b(return)g(a)h(status)g(of)g(0)g(\(true\))h(or)f
|
||||
(1)630 2637 y(\(false\).)g(Eac)m(h)31 b(op)s(erator)f(and)f(op)s(erand)
|
||||
(1)630 2710 y(\(false\).)g(Eac)m(h)31 b(op)s(erator)f(and)f(op)s(erand)
|
||||
g(m)m(ust)h(b)s(e)f(a)i(separate)g(argumen)m(t.)41 b(Expressions)630
|
||||
2746 y(are)26 b(comp)s(osed)f(of)g(the)h(primaries)f(describ)s(ed)f(b)s
|
||||
2819 y(are)26 b(comp)s(osed)f(of)g(the)h(primaries)f(describ)s(ed)f(b)s
|
||||
(elo)m(w)h(in)g(Section)h(6.4)h([Bash)e(Conditional)630
|
||||
2856 y(Expressions],)39 b(page)g(80.)64 b Fs(test)37
|
||||
2929 y(Expressions],)39 b(page)g(80.)64 b Fs(test)37
|
||||
b Ft(do)s(es)g(not)h(accept)i(an)m(y)e(options,)i(nor)e(do)s(es)f(it)h
|
||||
(accept)630 2966 y(and)30 b(ignore)h(an)f(argumen)m(t)h(of)f(`)p
|
||||
(accept)630 3039 y(and)30 b(ignore)h(an)f(argumen)m(t)h(of)f(`)p
|
||||
Fs(--)p Ft(')h(as)f(signifying)h(the)f(end)g(of)h(options.)630
|
||||
3107 y(When)f(the)h Fs([)f Ft(form)g(is)g(used,)g(the)g(last)i(argumen)
|
||||
3176 y(When)f(the)h Fs([)f Ft(form)g(is)g(used,)g(the)g(last)i(argumen)
|
||||
m(t)e(to)i(the)e(command)g(m)m(ust)h(b)s(e)e(a)i Fs(])p
|
||||
Ft(.)630 3249 y(Expressions)23 b(ma)m(y)h(b)s(e)e(com)m(bined)i(using)f
|
||||
Ft(.)630 3313 y(Expressions)23 b(ma)m(y)h(b)s(e)e(com)m(bined)i(using)f
|
||||
(the)h(follo)m(wing)h(op)s(erators,)g(listed)f(in)f(decreasing)630
|
||||
3358 y(order)30 b(of)h(precedence.)43 b(The)30 b(ev)-5
|
||||
3422 y(order)30 b(of)h(precedence.)43 b(The)30 b(ev)-5
|
||||
b(aluation)33 b(dep)s(ends)28 b(on)j(the)g(n)m(um)m(b)s(er)f(of)h
|
||||
(argumen)m(ts;)g(see)630 3468 y(b)s(elo)m(w.)41 b(Op)s(erator)30
|
||||
(argumen)m(ts;)g(see)630 3532 y(b)s(elo)m(w.)41 b(Op)s(erator)30
|
||||
b(precedence)h(is)f(used)g(when)f(there)i(are)f(\014v)m(e)h(or)f(more)h
|
||||
(argumen)m(ts.)630 3641 y Fs(!)f Fi(expr)210 b Ft(T)-8
|
||||
b(rue)30 b(if)g Fq(expr)37 b Ft(is)30 b(false.)630 3815
|
||||
(argumen)m(ts.)630 3696 y Fs(!)f Fi(expr)210 b Ft(T)-8
|
||||
b(rue)30 b(if)g Fq(expr)37 b Ft(is)30 b(false.)630 3861
|
||||
y Fs(\()g Fi(expr)40 b Fs(\))122 b Ft(Returns)23 b(the)h(v)-5
|
||||
b(alue)24 b(of)g Fq(expr)7 b Ft(.)37 b(This)23 b(ma)m(y)i(b)s(e)e(used)
|
||||
g(to)h(o)m(v)m(erride)h(the)f(normal)1110 3924 y(precedence)31
|
||||
b(of)f(op)s(erators.)630 4098 y Fi(expr1)39 b Fs(-a)30
|
||||
b Fi(expr2)1110 4208 y Ft(T)-8 b(rue)30 b(if)g(b)s(oth)g
|
||||
g(to)h(o)m(v)m(erride)h(the)f(normal)1110 3970 y(precedence)31
|
||||
b(of)f(op)s(erators.)630 4134 y Fi(expr1)39 b Fs(-a)30
|
||||
b Fi(expr2)1110 4244 y Ft(T)-8 b(rue)30 b(if)g(b)s(oth)g
|
||||
Fq(expr1)37 b Ft(and)30 b Fq(expr2)38 b Ft(are)30 b(true.)630
|
||||
4381 y Fi(expr1)39 b Fs(-o)30 b Fi(expr2)1110 4491 y
|
||||
4408 y Fi(expr1)39 b Fs(-o)30 b Fi(expr2)1110 4518 y
|
||||
Ft(T)-8 b(rue)30 b(if)g(either)h Fq(expr1)38 b Ft(or)30
|
||||
b Fq(expr2)37 b Ft(is)31 b(true.)630 4664 y(The)37 b
|
||||
b Fq(expr2)37 b Ft(is)31 b(true.)630 4682 y(The)37 b
|
||||
Fs(test)f Ft(and)g Fs([)h Ft(builtins)g(ev)-5 b(aluate)39
|
||||
b(conditional)f(expressions)f(using)g(a)g(set)h(of)f(rules)630
|
||||
4774 y(based)30 b(on)g(the)h(n)m(um)m(b)s(er)e(of)h(argumen)m(ts.)630
|
||||
4947 y(0)h(argumen)m(ts)1110 5057 y(The)f(expression)g(is)g(false.)630
|
||||
4792 y(based)30 b(on)g(the)h(n)m(um)m(b)s(er)e(of)h(argumen)m(ts.)630
|
||||
4956 y(0)h(argumen)m(ts)1110 5066 y(The)f(expression)g(is)g(false.)630
|
||||
5230 y(1)h(argumen)m(t)1110 5340 y(The)f(expression)g(is)g(true)h(if)f
|
||||
(and)g(only)g(if)h(the)f(argumen)m(t)h(is)f(not)h(n)m(ull.)p
|
||||
eop end
|
||||
|
||||
+6
-4
@@ -985,10 +985,12 @@ BBAASSHH BBUUIILLTTIINN CCOOMMMMAANNDDSS
|
||||
script by the .. (ssoouurrccee) command, it causes the shell to stop
|
||||
executing that script and return either _n or the exit status of
|
||||
the last command executed within the script as the exit status
|
||||
of the script. The return status is non-zero if rreettuurrnn is used
|
||||
outside a function and not during execution of a script by .. or
|
||||
ssoouurrccee. Any command associated with the RREETTUURRNN trap is executed
|
||||
before execution resumes after the function or script.
|
||||
of the script. If _n is supplied, the return value is its least
|
||||
significant 8 bits. The return status is non-zero if rreettuurrnn is
|
||||
supplied a non-numeric argument, or is used outside a function
|
||||
and not during execution of a script by .. or ssoouurrccee. Any com-
|
||||
mand associated with the RREETTUURRNN trap is executed before execu-
|
||||
tion resumes after the function or script.
|
||||
|
||||
sseett [----aabbeeffhhkkmmnnppttuuvvxxBBCCEEHHPPTT] [--oo _o_p_t_i_o_n_-_n_a_m_e] [_a_r_g ...]
|
||||
sseett [++aabbeeffhhkkmmnnppttuuvvxxBBCCEEHHPPTT] [++oo _o_p_t_i_o_n_-_n_a_m_e] [_a_r_g ...]
|
||||
|
||||
+630
-626
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,6 +1,6 @@
|
||||
%!PS-Adobe-3.0
|
||||
%%Creator: groff version 1.19.2
|
||||
%%CreationDate: Mon Sep 26 10:56:08 2011
|
||||
%%CreationDate: Mon Oct 24 08:43:45 2011
|
||||
%%DocumentNeededResources: font Times-Roman
|
||||
%%+ font Times-Bold
|
||||
%%DocumentSuppliedResources: procset grops 1.19 2
|
||||
|
||||
+2
-2
@@ -2,9 +2,9 @@
|
||||
Copyright (C) 1988-2011 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set LASTCHANGE Fri Oct 14 13:18:35 EDT 2011
|
||||
@set LASTCHANGE Mon Oct 24 08:43:33 EDT 2011
|
||||
|
||||
@set EDITION 4.2
|
||||
@set VERSION 4.2
|
||||
@set UPDATED 14 October 2011
|
||||
@set UPDATED 24 October 2011
|
||||
@set UPDATED-MONTH October 2011
|
||||
|
||||
@@ -494,10 +494,16 @@ expassign ()
|
||||
lvalue *= value;
|
||||
break;
|
||||
case DIV:
|
||||
lvalue /= value;
|
||||
if (lvalue == INTMAX_MIN && value == -1)
|
||||
value = 1;
|
||||
else
|
||||
lvalue /= value;
|
||||
break;
|
||||
case MOD:
|
||||
lvalue %= value;
|
||||
if (lvalue == INTMAX_MIN && value == -1)
|
||||
lvalue = 0;
|
||||
else
|
||||
lvalue %= value;
|
||||
break;
|
||||
case PLUS:
|
||||
lvalue += value;
|
||||
@@ -811,6 +817,7 @@ exp2 ()
|
||||
|
||||
val2 = exppower ();
|
||||
|
||||
/* Handle division by 0 and twos-complement arithmetic overflow */
|
||||
if (((op == DIV) || (op == MOD)) && (val2 == 0))
|
||||
{
|
||||
if (noeval == 0)
|
||||
@@ -818,6 +825,13 @@ exp2 ()
|
||||
else
|
||||
val2 = 1;
|
||||
}
|
||||
else if (op == MOD && val1 == INTMAX_MIN && val2 == -1)
|
||||
{
|
||||
val1 = 0;
|
||||
continue;
|
||||
}
|
||||
else if (op == DIV && val1 == INTMAX_MIN && val2 == -1)
|
||||
val2 = 1;
|
||||
|
||||
if (op == MUL)
|
||||
val1 *= val2;
|
||||
|
||||
@@ -126,7 +126,11 @@ int hashing_enabled = 1;
|
||||
#if defined (BANG_HISTORY)
|
||||
/* Non-zero means that we are doing history expansion. The default.
|
||||
This means !22 gets the 22nd line of history. */
|
||||
# if defined (STRICT_POSIX)
|
||||
int history_expansion = 0;
|
||||
# else
|
||||
int history_expansion = 1;
|
||||
# endif
|
||||
#endif /* BANG_HISTORY */
|
||||
|
||||
/* Non-zero means that we allow comments to appear in interactive commands. */
|
||||
|
||||
@@ -1022,6 +1022,13 @@ history_expand (hstring, output)
|
||||
{
|
||||
if (cc == 0 || member (cc, history_no_expand_chars))
|
||||
continue;
|
||||
/* DQUOTE won't be set unless history_quotes_inhibit_expansion
|
||||
is set. The idea here is to treat double-quoted strings the
|
||||
same as the word outside double quotes; in effect making the
|
||||
double quote part of history_no_expand_chars when DQUOTE is
|
||||
set. */
|
||||
else if (dquote && cc == '"')
|
||||
continue;
|
||||
/* If the calling application has set
|
||||
history_inhibit_expansion_function to a function that checks
|
||||
for special cases that should not be history expanded,
|
||||
|
||||
+4
-4
@@ -280,7 +280,7 @@ make_arith_for_command (exprs, action, lineno)
|
||||
ARITH_FOR_COM *temp;
|
||||
WORD_LIST *init, *test, *step;
|
||||
char *s, *t, *start;
|
||||
int nsemi;
|
||||
int nsemi, i;
|
||||
|
||||
init = test = step = (WORD_LIST *)NULL;
|
||||
/* Parse the string into the three component sub-expressions. */
|
||||
@@ -292,10 +292,10 @@ make_arith_for_command (exprs, action, lineno)
|
||||
s++;
|
||||
start = s;
|
||||
/* skip to the semicolon or EOS */
|
||||
while (*s && *s != ';')
|
||||
s++;
|
||||
i = skip_to_delim (start, 0, ";", SD_NOJMP);
|
||||
s = start + i;
|
||||
|
||||
t = (s > start) ? substring (start, 0, s - start) : (char *)NULL;
|
||||
t = (i > 0) ? substring (start, 0, i) : (char *)NULL;
|
||||
|
||||
nsemi++;
|
||||
switch (nsemi)
|
||||
|
||||
@@ -0,0 +1,888 @@
|
||||
/* make_cmd.c -- Functions for making instances of the various
|
||||
parser constructs. */
|
||||
|
||||
/* Copyright (C) 1989-2009 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bashtypes.h"
|
||||
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include "filecntl.h"
|
||||
#include "bashansi.h"
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "parser.h"
|
||||
#include "syntax.h"
|
||||
#include "command.h"
|
||||
#include "general.h"
|
||||
#include "error.h"
|
||||
#include "flags.h"
|
||||
#include "make_cmd.h"
|
||||
#include "dispose_cmd.h"
|
||||
#include "variables.h"
|
||||
#include "subst.h"
|
||||
#include "input.h"
|
||||
#include "ocache.h"
|
||||
#include "externs.h"
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
#include "jobs.h"
|
||||
#endif
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
extern int line_number, current_command_line_count, parser_state;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
/* Object caching */
|
||||
sh_obj_cache_t wdcache = {0, 0, 0};
|
||||
sh_obj_cache_t wlcache = {0, 0, 0};
|
||||
|
||||
#define WDCACHESIZE 60
|
||||
#define WLCACHESIZE 60
|
||||
|
||||
static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *make_arith_for_expr __P((char *));
|
||||
#endif
|
||||
static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
|
||||
|
||||
void
|
||||
cmd_init ()
|
||||
{
|
||||
ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
|
||||
ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
alloc_word_desc ()
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
ocache_alloc (wdcache, WORD_DESC, temp);
|
||||
temp->flags = 0;
|
||||
temp->word = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_bare_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = alloc_word_desc ();
|
||||
|
||||
if (*string)
|
||||
temp->word = savestring (string);
|
||||
else
|
||||
{
|
||||
temp->word = (char *)xmalloc (1);
|
||||
temp->word[0] = '\0';
|
||||
}
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_flags (w, string)
|
||||
WORD_DESC *w;
|
||||
const char *string;
|
||||
{
|
||||
register int i;
|
||||
size_t slen;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
i = 0;
|
||||
slen = strlen (string);
|
||||
while (i < slen)
|
||||
{
|
||||
switch (string[i])
|
||||
{
|
||||
case '$':
|
||||
w->flags |= W_HASDOLLAR;
|
||||
break;
|
||||
case '\\':
|
||||
break; /* continue the loop */
|
||||
case '\'':
|
||||
case '`':
|
||||
case '"':
|
||||
w->flags |= W_QUOTED;
|
||||
break;
|
||||
}
|
||||
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
}
|
||||
|
||||
return (w);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = make_bare_word (string);
|
||||
return (make_word_flags (temp, string));
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_from_token (token)
|
||||
int token;
|
||||
{
|
||||
char tokenizer[2];
|
||||
|
||||
tokenizer[0] = token;
|
||||
tokenizer[1] = '\0';
|
||||
|
||||
return (make_word (tokenizer));
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
make_word_list (word, wlink)
|
||||
WORD_DESC *word;
|
||||
WORD_LIST *wlink;
|
||||
{
|
||||
WORD_LIST *temp;
|
||||
|
||||
ocache_alloc (wlcache, WORD_LIST, temp);
|
||||
|
||||
temp->word = word;
|
||||
temp->next = wlink;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_command (type, pointer)
|
||||
enum command_type type;
|
||||
SIMPLE_COM *pointer;
|
||||
{
|
||||
COMMAND *temp;
|
||||
|
||||
temp = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
temp->type = type;
|
||||
temp->value.Simple = pointer;
|
||||
temp->value.Simple->flags = temp->flags = 0;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
command_connect (com1, com2, connector)
|
||||
COMMAND *com1, *com2;
|
||||
int connector;
|
||||
{
|
||||
CONNECTION *temp;
|
||||
|
||||
temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
|
||||
temp->connector = connector;
|
||||
temp->first = com1;
|
||||
temp->second = com2;
|
||||
return (make_command (cm_connection, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_for_or_select (type, name, map_list, action, lineno)
|
||||
enum command_type type;
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
FOR_COM *temp;
|
||||
|
||||
temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->map_list = map_list;
|
||||
temp->action = action;
|
||||
return (make_command (type, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_for_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
return (make_for_or_select (cm_for, name, map_list, action, lineno));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_select_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (SELECT_COMMAND)
|
||||
return (make_for_or_select (cm_select, name, map_list, action, lineno));
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *
|
||||
make_arith_for_expr (s)
|
||||
char *s;
|
||||
{
|
||||
WORD_LIST *result;
|
||||
WORD_DESC *wd;
|
||||
|
||||
if (s == 0 || *s == '\0')
|
||||
return ((WORD_LIST *)NULL);
|
||||
wd = make_word (s);
|
||||
wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
|
||||
result = make_word_list (wd, (WORD_LIST *)NULL);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note that this function calls dispose_words on EXPRS, since it doesn't
|
||||
use the word list directly. We free it here rather than at the caller
|
||||
because no other function in this file requires that the caller free
|
||||
any arguments. */
|
||||
COMMAND *
|
||||
make_arith_for_command (exprs, action, lineno)
|
||||
WORD_LIST *exprs;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
ARITH_FOR_COM *temp;
|
||||
WORD_LIST *init, *test, *step;
|
||||
char *s, *t, *start;
|
||||
int nsemi, i;
|
||||
|
||||
init = test = step = (WORD_LIST *)NULL;
|
||||
/* Parse the string into the three component sub-expressions. */
|
||||
start = t = s = exprs->word->word;
|
||||
for (nsemi = 0; ;)
|
||||
{
|
||||
/* skip whitespace at the start of each sub-expression. */
|
||||
while (whitespace (*s))
|
||||
s++;
|
||||
start = s;
|
||||
/* skip to the semicolon or EOS */
|
||||
i = skip_to_delim (s, 0, ";", SD_NOJMP);
|
||||
s = start + i;
|
||||
|
||||
t = (i > 0) ? substring (start, 0, i) : (char *)NULL;
|
||||
|
||||
nsemi++;
|
||||
switch (nsemi)
|
||||
{
|
||||
case 1:
|
||||
init = make_arith_for_expr (t);
|
||||
break;
|
||||
case 2:
|
||||
test = make_arith_for_expr (t);
|
||||
break;
|
||||
case 3:
|
||||
step = make_arith_for_expr (t);
|
||||
break;
|
||||
}
|
||||
|
||||
FREE (t);
|
||||
if (*s == '\0')
|
||||
break;
|
||||
s++; /* skip over semicolon */
|
||||
}
|
||||
|
||||
if (nsemi != 3)
|
||||
{
|
||||
if (nsemi < 3)
|
||||
parser_error (lineno, _("syntax error: arithmetic expression required"));
|
||||
else
|
||||
parser_error (lineno, _("syntax error: `;' unexpected"));
|
||||
parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
}
|
||||
|
||||
temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->init = init ? init : make_arith_for_expr ("1");
|
||||
temp->test = test ? test : make_arith_for_expr ("1");
|
||||
temp->step = step ? step : make_arith_for_expr ("1");
|
||||
temp->action = action;
|
||||
|
||||
dispose_words (exprs);
|
||||
return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
|
||||
#else
|
||||
dispose_words (exprs);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif /* ARITH_FOR_COMMAND */
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_group_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
GROUP_COM *temp;
|
||||
|
||||
temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
|
||||
temp->command = command;
|
||||
return (make_command (cm_group, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_case_command (word, clauses, lineno)
|
||||
WORD_DESC *word;
|
||||
PATTERN_LIST *clauses;
|
||||
int lineno;
|
||||
{
|
||||
CASE_COM *temp;
|
||||
|
||||
temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->word = word;
|
||||
temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
|
||||
return (make_command (cm_case, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
PATTERN_LIST *
|
||||
make_pattern_list (patterns, action)
|
||||
WORD_LIST *patterns;
|
||||
COMMAND *action;
|
||||
{
|
||||
PATTERN_LIST *temp;
|
||||
|
||||
temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
|
||||
temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
|
||||
temp->action = action;
|
||||
temp->next = NULL;
|
||||
temp->flags = 0;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_if_command (test, true_case, false_case)
|
||||
COMMAND *test, *true_case, *false_case;
|
||||
{
|
||||
IF_COM *temp;
|
||||
|
||||
temp = (IF_COM *)xmalloc (sizeof (IF_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->true_case = true_case;
|
||||
temp->false_case = false_case;
|
||||
return (make_command (cm_if, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_until_or_while (which, test, action)
|
||||
enum command_type which;
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
WHILE_COM *temp;
|
||||
|
||||
temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->action = action;
|
||||
return (make_command (which, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_while_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_while, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_until_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_until, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_arith_command (exp)
|
||||
WORD_LIST *exp;
|
||||
{
|
||||
#if defined (DPAREN_ARITHMETIC)
|
||||
COMMAND *command;
|
||||
ARITH_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->exp = exp;
|
||||
|
||||
command->type = cm_arith;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (COND_COMMAND)
|
||||
struct cond_com *
|
||||
make_cond_node (type, op, left, right)
|
||||
int type;
|
||||
WORD_DESC *op;
|
||||
struct cond_com *left, *right;
|
||||
{
|
||||
COND_COM *temp;
|
||||
|
||||
temp = (COND_COM *)xmalloc (sizeof (COND_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->type = type;
|
||||
temp->op = op;
|
||||
temp->left = left;
|
||||
temp->right = right;
|
||||
|
||||
return (temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMMAND *
|
||||
make_cond_command (cond_node)
|
||||
COND_COM *cond_node;
|
||||
{
|
||||
#if defined (COND_COMMAND)
|
||||
COMMAND *command;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Cond = cond_node;
|
||||
|
||||
command->type = cm_cond;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
command->line = cond_node ? cond_node->line : 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_bare_simple_command ()
|
||||
{
|
||||
COMMAND *command;
|
||||
SIMPLE_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->words = (WORD_LIST *)NULL;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
|
||||
command->type = cm_simple;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Return a command which is the connection of the word or redirection
|
||||
in ELEMENT, and the command * or NULL in COMMAND. */
|
||||
COMMAND *
|
||||
make_simple_command (element, command)
|
||||
ELEMENT element;
|
||||
COMMAND *command;
|
||||
{
|
||||
/* If we are starting from scratch, then make the initial command
|
||||
structure. Also note that we have to fill in all the slots, since
|
||||
malloc doesn't return zeroed space. */
|
||||
if (command == 0)
|
||||
{
|
||||
command = make_bare_simple_command ();
|
||||
parser_state |= PST_REDIRLIST;
|
||||
}
|
||||
|
||||
if (element.word)
|
||||
{
|
||||
command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
|
||||
parser_state &= ~PST_REDIRLIST;
|
||||
}
|
||||
else if (element.redirect)
|
||||
{
|
||||
REDIRECT *r = element.redirect;
|
||||
/* Due to the way <> is implemented, there may be more than a single
|
||||
redirection in element.redirect. We just follow the chain as far
|
||||
as it goes, and hook onto the end. */
|
||||
while (r->next)
|
||||
r = r->next;
|
||||
r->next = command->value.Simple->redirects;
|
||||
command->value.Simple->redirects = element.redirect;
|
||||
}
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Because we are Bourne compatible, we read the input for this
|
||||
<< or <<- redirection now, from wherever input is coming from.
|
||||
We store the input read into a WORD_DESC. Replace the text of
|
||||
the redirectee.word with the new input text. If <<- is on,
|
||||
then remove leading TABS from each line. */
|
||||
void
|
||||
make_here_document (temp, lineno)
|
||||
REDIRECT *temp;
|
||||
int lineno;
|
||||
{
|
||||
int kill_leading, redir_len;
|
||||
char *redir_word, *document, *full_line;
|
||||
int document_index, document_size, delim_unquoted;
|
||||
|
||||
if (temp->instruction != r_deblank_reading_until &&
|
||||
temp->instruction != r_reading_until)
|
||||
{
|
||||
internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
|
||||
return;
|
||||
}
|
||||
|
||||
kill_leading = temp->instruction == r_deblank_reading_until;
|
||||
|
||||
document = (char *)NULL;
|
||||
document_index = document_size = 0;
|
||||
|
||||
/* Quote removal is the only expansion performed on the delimiter
|
||||
for here documents, making it an extremely special case. */
|
||||
redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
|
||||
|
||||
/* redirection_expand will return NULL if the expansion results in
|
||||
multiple words or no words. Check for that here, and just abort
|
||||
this here document if it does. */
|
||||
if (redir_word)
|
||||
redir_len = strlen (redir_word);
|
||||
else
|
||||
{
|
||||
temp->here_doc_eof = (char *)xmalloc (1);
|
||||
temp->here_doc_eof[0] = '\0';
|
||||
goto document_done;
|
||||
}
|
||||
|
||||
free (temp->redirectee.filename->word);
|
||||
temp->here_doc_eof = redir_word;
|
||||
|
||||
/* Read lines from wherever lines are coming from.
|
||||
For each line read, if kill_leading, then kill the
|
||||
leading tab characters.
|
||||
If the line matches redir_word exactly, then we have
|
||||
manufactured the document. Otherwise, add the line to the
|
||||
list of lines in the document. */
|
||||
|
||||
/* If the here-document delimiter was quoted, the lines should
|
||||
be read verbatim from the input. If it was not quoted, we
|
||||
need to perform backslash-quoted newline removal. */
|
||||
delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
|
||||
while (full_line = read_secondary_line (delim_unquoted))
|
||||
{
|
||||
register char *line;
|
||||
int len;
|
||||
|
||||
line = full_line;
|
||||
line_number++;
|
||||
|
||||
/* If set -v is in effect, echo the line read. read_secondary_line/
|
||||
read_a_line leaves the newline at the end, so don't print another. */
|
||||
if (echo_input_at_read)
|
||||
fprintf (stderr, "%s", line);
|
||||
|
||||
if (kill_leading && *line)
|
||||
{
|
||||
/* Hack: To be compatible with some Bourne shells, we
|
||||
check the word before stripping the whitespace. This
|
||||
is a hack, though. */
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
while (*line == '\t')
|
||||
line++;
|
||||
}
|
||||
|
||||
if (*line == 0)
|
||||
continue;
|
||||
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
len = strlen (line);
|
||||
if (len + document_index >= document_size)
|
||||
{
|
||||
document_size = document_size ? 2 * (document_size + len) : len + 2;
|
||||
document = (char *)xrealloc (document, document_size);
|
||||
}
|
||||
|
||||
/* len is guaranteed to be > 0 because of the check for line
|
||||
being an empty string before the call to strlen. */
|
||||
FASTCOPY (line, document + document_index, len);
|
||||
document_index += len;
|
||||
}
|
||||
|
||||
if (full_line == 0)
|
||||
internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
|
||||
|
||||
document_done:
|
||||
if (document)
|
||||
document[document_index] = '\0';
|
||||
else
|
||||
{
|
||||
document = (char *)xmalloc (1);
|
||||
document[0] = '\0';
|
||||
}
|
||||
temp->redirectee.filename->word = document;
|
||||
}
|
||||
|
||||
/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
|
||||
INSTRUCTION is the instruction type, SOURCE is a file descriptor,
|
||||
and DEST is a file descriptor or a WORD_DESC *. */
|
||||
REDIRECT *
|
||||
make_redirection (source, instruction, dest_and_filename, flags)
|
||||
REDIRECTEE source;
|
||||
enum r_instruction instruction;
|
||||
REDIRECTEE dest_and_filename;
|
||||
int flags;
|
||||
{
|
||||
REDIRECT *temp;
|
||||
WORD_DESC *w;
|
||||
int wlen;
|
||||
intmax_t lfd;
|
||||
|
||||
temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
|
||||
|
||||
/* First do the common cases. */
|
||||
temp->redirector = source;
|
||||
temp->redirectee = dest_and_filename;
|
||||
temp->instruction = instruction;
|
||||
temp->flags = 0;
|
||||
temp->rflags = flags;
|
||||
temp->next = (REDIRECT *)NULL;
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
|
||||
case r_output_direction: /* >foo */
|
||||
case r_output_force: /* >| foo */
|
||||
case r_err_and_out: /* &>filename */
|
||||
temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_appending_to: /* >>foo */
|
||||
case r_append_err_and_out: /* &>> filename */
|
||||
temp->flags = O_APPEND | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_input_direction: /* <foo */
|
||||
case r_inputa_direction: /* foo & makes this. */
|
||||
temp->flags = O_RDONLY;
|
||||
break;
|
||||
|
||||
case r_input_output: /* <>foo */
|
||||
temp->flags = O_RDWR | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_deblank_reading_until: /* <<-foo */
|
||||
case r_reading_until: /* << foo */
|
||||
case r_reading_string: /* <<< foo */
|
||||
case r_close_this: /* <&- */
|
||||
case r_duplicating_input: /* 1<&2 */
|
||||
case r_duplicating_output: /* 1>&2 */
|
||||
break;
|
||||
|
||||
/* the parser doesn't pass these. */
|
||||
case r_move_input: /* 1<&2- */
|
||||
case r_move_output: /* 1>&2- */
|
||||
case r_move_input_word: /* 1<&$foo- */
|
||||
case r_move_output_word: /* 1>&$foo- */
|
||||
break;
|
||||
|
||||
/* The way the lexer works we have to do this here. */
|
||||
case r_duplicating_input_word: /* 1<&$foo */
|
||||
case r_duplicating_output_word: /* 1>&$foo */
|
||||
w = dest_and_filename.filename;
|
||||
wlen = strlen (w->word) - 1;
|
||||
if (w->word[wlen] == '-') /* Yuck */
|
||||
{
|
||||
w->word[wlen] = '\0';
|
||||
if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
|
||||
{
|
||||
dispose_word (w);
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
|
||||
temp->redirectee.dest = lfd;
|
||||
}
|
||||
else
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_function_def (name, command, lineno, lstart)
|
||||
WORD_DESC *name;
|
||||
COMMAND *command;
|
||||
int lineno, lstart;
|
||||
{
|
||||
FUNCTION_DEF *temp;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *bash_source_v;
|
||||
ARRAY *bash_source_a;
|
||||
#endif
|
||||
|
||||
temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
|
||||
temp->command = command;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->flags = 0;
|
||||
command->line = lstart;
|
||||
|
||||
/* Information used primarily for debugging. */
|
||||
temp->source_file = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
if (bash_source_a && array_num_elements (bash_source_a) > 0)
|
||||
temp->source_file = array_reference (bash_source_a, 0);
|
||||
#endif
|
||||
#if defined (DEBUGGER)
|
||||
bind_function_def (name->word, temp);
|
||||
#endif
|
||||
|
||||
temp->source_file = 0;
|
||||
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_subshell_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
SUBSHELL_COM *temp;
|
||||
|
||||
temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
|
||||
temp->command = command;
|
||||
temp->flags = CMD_WANT_SUBSHELL;
|
||||
return (make_command (cm_subshell, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_coproc_command (name, command)
|
||||
char *name;
|
||||
COMMAND *command;
|
||||
{
|
||||
COPROC_COM *temp;
|
||||
|
||||
temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
|
||||
temp->name = savestring (name);
|
||||
temp->command = command;
|
||||
temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
|
||||
return (make_command (cm_coproc, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
/* Reverse the word list and redirection list in the simple command
|
||||
has just been parsed. It seems simpler to do this here the one
|
||||
time then by any other method that I can think of. */
|
||||
COMMAND *
|
||||
clean_simple_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
if (command->type != cm_simple)
|
||||
command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
|
||||
else
|
||||
{
|
||||
command->value.Simple->words =
|
||||
REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
|
||||
command->value.Simple->redirects =
|
||||
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
|
||||
}
|
||||
|
||||
parser_state &= ~PST_REDIRLIST;
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* The Yacc grammar productions have a problem, in that they take a
|
||||
list followed by an ampersand (`&') and do a simple command connection,
|
||||
making the entire list effectively asynchronous, instead of just
|
||||
the last command. This means that when the list is executed, all
|
||||
the commands have stdin set to /dev/null when job control is not
|
||||
active, instead of just the last. This is wrong, and needs fixing
|
||||
up. This function takes the `&' and applies it to the last command
|
||||
in the list. This is done only for lists connected by `;'; it makes
|
||||
`;' bind `tighter' than `&'. */
|
||||
COMMAND *
|
||||
connect_async_list (command, command2, connector)
|
||||
COMMAND *command, *command2;
|
||||
int connector;
|
||||
{
|
||||
COMMAND *t, *t1, *t2;
|
||||
|
||||
t1 = command;
|
||||
t = command->value.Connection->second;
|
||||
|
||||
if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
|
||||
command->value.Connection->connector != ';')
|
||||
{
|
||||
t = command_connect (command, command2, connector);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* This is just defensive programming. The Yacc precedence rules
|
||||
will generally hand this function a command where t points directly
|
||||
to the command we want (e.g. given a ; b ; c ; d &, t1 will point
|
||||
to the `a ; b ; c' list and t will be the `d'). We only want to do
|
||||
this if the list is not being executed as a unit in the background
|
||||
with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
|
||||
the only way to tell. */
|
||||
while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
|
||||
t->value.Connection->connector == ';')
|
||||
{
|
||||
t1 = t;
|
||||
t = t->value.Connection->second;
|
||||
}
|
||||
/* Now we have t pointing to the last command in the list, and
|
||||
t1->value.Connection->second == t. */
|
||||
t2 = command_connect (t, command2, connector);
|
||||
t1->value.Connection->second = t2;
|
||||
return command;
|
||||
}
|
||||
+888
@@ -0,0 +1,888 @@
|
||||
/* make_cmd.c -- Functions for making instances of the various
|
||||
parser constructs. */
|
||||
|
||||
/* Copyright (C) 1989-2009 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bashtypes.h"
|
||||
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include "filecntl.h"
|
||||
#include "bashansi.h"
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "parser.h"
|
||||
#include "syntax.h"
|
||||
#include "command.h"
|
||||
#include "general.h"
|
||||
#include "error.h"
|
||||
#include "flags.h"
|
||||
#include "make_cmd.h"
|
||||
#include "dispose_cmd.h"
|
||||
#include "variables.h"
|
||||
#include "subst.h"
|
||||
#include "input.h"
|
||||
#include "ocache.h"
|
||||
#include "externs.h"
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
#include "jobs.h"
|
||||
#endif
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
extern int line_number, current_command_line_count, parser_state;
|
||||
extern int last_command_exit_value;
|
||||
|
||||
/* Object caching */
|
||||
sh_obj_cache_t wdcache = {0, 0, 0};
|
||||
sh_obj_cache_t wlcache = {0, 0, 0};
|
||||
|
||||
#define WDCACHESIZE 60
|
||||
#define WLCACHESIZE 60
|
||||
|
||||
static COMMAND *make_for_or_select __P((enum command_type, WORD_DESC *, WORD_LIST *, COMMAND *, int));
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *make_arith_for_expr __P((char *));
|
||||
#endif
|
||||
static COMMAND *make_until_or_while __P((enum command_type, COMMAND *, COMMAND *));
|
||||
|
||||
void
|
||||
cmd_init ()
|
||||
{
|
||||
ocache_create (wdcache, WORD_DESC, WDCACHESIZE);
|
||||
ocache_create (wlcache, WORD_LIST, WLCACHESIZE);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
alloc_word_desc ()
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
ocache_alloc (wdcache, WORD_DESC, temp);
|
||||
temp->flags = 0;
|
||||
temp->word = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_bare_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = alloc_word_desc ();
|
||||
|
||||
if (*string)
|
||||
temp->word = savestring (string);
|
||||
else
|
||||
{
|
||||
temp->word = (char *)xmalloc (1);
|
||||
temp->word[0] = '\0';
|
||||
}
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_flags (w, string)
|
||||
WORD_DESC *w;
|
||||
const char *string;
|
||||
{
|
||||
register int i;
|
||||
size_t slen;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
i = 0;
|
||||
slen = strlen (string);
|
||||
while (i < slen)
|
||||
{
|
||||
switch (string[i])
|
||||
{
|
||||
case '$':
|
||||
w->flags |= W_HASDOLLAR;
|
||||
break;
|
||||
case '\\':
|
||||
break; /* continue the loop */
|
||||
case '\'':
|
||||
case '`':
|
||||
case '"':
|
||||
w->flags |= W_QUOTED;
|
||||
break;
|
||||
}
|
||||
|
||||
ADVANCE_CHAR (string, slen, i);
|
||||
}
|
||||
|
||||
return (w);
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word (string)
|
||||
const char *string;
|
||||
{
|
||||
WORD_DESC *temp;
|
||||
|
||||
temp = make_bare_word (string);
|
||||
return (make_word_flags (temp, string));
|
||||
}
|
||||
|
||||
WORD_DESC *
|
||||
make_word_from_token (token)
|
||||
int token;
|
||||
{
|
||||
char tokenizer[2];
|
||||
|
||||
tokenizer[0] = token;
|
||||
tokenizer[1] = '\0';
|
||||
|
||||
return (make_word (tokenizer));
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
make_word_list (word, wlink)
|
||||
WORD_DESC *word;
|
||||
WORD_LIST *wlink;
|
||||
{
|
||||
WORD_LIST *temp;
|
||||
|
||||
ocache_alloc (wlcache, WORD_LIST, temp);
|
||||
|
||||
temp->word = word;
|
||||
temp->next = wlink;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_command (type, pointer)
|
||||
enum command_type type;
|
||||
SIMPLE_COM *pointer;
|
||||
{
|
||||
COMMAND *temp;
|
||||
|
||||
temp = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
temp->type = type;
|
||||
temp->value.Simple = pointer;
|
||||
temp->value.Simple->flags = temp->flags = 0;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
command_connect (com1, com2, connector)
|
||||
COMMAND *com1, *com2;
|
||||
int connector;
|
||||
{
|
||||
CONNECTION *temp;
|
||||
|
||||
temp = (CONNECTION *)xmalloc (sizeof (CONNECTION));
|
||||
temp->connector = connector;
|
||||
temp->first = com1;
|
||||
temp->second = com2;
|
||||
return (make_command (cm_connection, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_for_or_select (type, name, map_list, action, lineno)
|
||||
enum command_type type;
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
FOR_COM *temp;
|
||||
|
||||
temp = (FOR_COM *)xmalloc (sizeof (FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->map_list = map_list;
|
||||
temp->action = action;
|
||||
return (make_command (type, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_for_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
return (make_for_or_select (cm_for, name, map_list, action, lineno));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_select_command (name, map_list, action, lineno)
|
||||
WORD_DESC *name;
|
||||
WORD_LIST *map_list;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (SELECT_COMMAND)
|
||||
return (make_for_or_select (cm_select, name, map_list, action, lineno));
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
static WORD_LIST *
|
||||
make_arith_for_expr (s)
|
||||
char *s;
|
||||
{
|
||||
WORD_LIST *result;
|
||||
WORD_DESC *wd;
|
||||
|
||||
if (s == 0 || *s == '\0')
|
||||
return ((WORD_LIST *)NULL);
|
||||
wd = make_word (s);
|
||||
wd->flags |= W_NOGLOB|W_NOSPLIT|W_QUOTED|W_DQUOTE; /* no word splitting or globbing */
|
||||
result = make_word_list (wd, (WORD_LIST *)NULL);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Note that this function calls dispose_words on EXPRS, since it doesn't
|
||||
use the word list directly. We free it here rather than at the caller
|
||||
because no other function in this file requires that the caller free
|
||||
any arguments. */
|
||||
COMMAND *
|
||||
make_arith_for_command (exprs, action, lineno)
|
||||
WORD_LIST *exprs;
|
||||
COMMAND *action;
|
||||
int lineno;
|
||||
{
|
||||
#if defined (ARITH_FOR_COMMAND)
|
||||
ARITH_FOR_COM *temp;
|
||||
WORD_LIST *init, *test, *step;
|
||||
char *s, *t, *start;
|
||||
int nsemi, i;
|
||||
|
||||
init = test = step = (WORD_LIST *)NULL;
|
||||
/* Parse the string into the three component sub-expressions. */
|
||||
start = t = s = exprs->word->word;
|
||||
for (nsemi = 0; ;)
|
||||
{
|
||||
/* skip whitespace at the start of each sub-expression. */
|
||||
while (whitespace (*s))
|
||||
s++;
|
||||
start = s;
|
||||
/* skip to the semicolon or EOS */
|
||||
i = skip_to_delim (s, 0, ";", SD_NOJMP);
|
||||
s = start + i;
|
||||
|
||||
t = (i > 0) ? substring (start, 0, i) : (char *)NULL;
|
||||
|
||||
nsemi++;
|
||||
switch (nsemi)
|
||||
{
|
||||
case 1:
|
||||
init = make_arith_for_expr (t);
|
||||
break;
|
||||
case 2:
|
||||
test = make_arith_for_expr (t);
|
||||
break;
|
||||
case 3:
|
||||
step = make_arith_for_expr (t);
|
||||
break;
|
||||
}
|
||||
|
||||
FREE (t);
|
||||
if (*s == '\0')
|
||||
break;
|
||||
s++; /* skip over semicolon */
|
||||
}
|
||||
|
||||
if (nsemi != 3)
|
||||
{
|
||||
if (nsemi < 3)
|
||||
parser_error (lineno, _("syntax error: arithmetic expression required"));
|
||||
else
|
||||
parser_error (lineno, _("syntax error: `;' unexpected"));
|
||||
parser_error (lineno, _("syntax error: `((%s))'"), exprs->word->word);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
}
|
||||
|
||||
temp = (ARITH_FOR_COM *)xmalloc (sizeof (ARITH_FOR_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->init = init ? init : make_arith_for_expr ("1");
|
||||
temp->test = test ? test : make_arith_for_expr ("1");
|
||||
temp->step = step ? step : make_arith_for_expr ("1");
|
||||
temp->action = action;
|
||||
|
||||
dispose_words (exprs);
|
||||
return (make_command (cm_arith_for, (SIMPLE_COM *)temp));
|
||||
#else
|
||||
dispose_words (exprs);
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif /* ARITH_FOR_COMMAND */
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_group_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
GROUP_COM *temp;
|
||||
|
||||
temp = (GROUP_COM *)xmalloc (sizeof (GROUP_COM));
|
||||
temp->command = command;
|
||||
return (make_command (cm_group, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_case_command (word, clauses, lineno)
|
||||
WORD_DESC *word;
|
||||
PATTERN_LIST *clauses;
|
||||
int lineno;
|
||||
{
|
||||
CASE_COM *temp;
|
||||
|
||||
temp = (CASE_COM *)xmalloc (sizeof (CASE_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = lineno;
|
||||
temp->word = word;
|
||||
temp->clauses = REVERSE_LIST (clauses, PATTERN_LIST *);
|
||||
return (make_command (cm_case, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
PATTERN_LIST *
|
||||
make_pattern_list (patterns, action)
|
||||
WORD_LIST *patterns;
|
||||
COMMAND *action;
|
||||
{
|
||||
PATTERN_LIST *temp;
|
||||
|
||||
temp = (PATTERN_LIST *)xmalloc (sizeof (PATTERN_LIST));
|
||||
temp->patterns = REVERSE_LIST (patterns, WORD_LIST *);
|
||||
temp->action = action;
|
||||
temp->next = NULL;
|
||||
temp->flags = 0;
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_if_command (test, true_case, false_case)
|
||||
COMMAND *test, *true_case, *false_case;
|
||||
{
|
||||
IF_COM *temp;
|
||||
|
||||
temp = (IF_COM *)xmalloc (sizeof (IF_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->true_case = true_case;
|
||||
temp->false_case = false_case;
|
||||
return (make_command (cm_if, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
static COMMAND *
|
||||
make_until_or_while (which, test, action)
|
||||
enum command_type which;
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
WHILE_COM *temp;
|
||||
|
||||
temp = (WHILE_COM *)xmalloc (sizeof (WHILE_COM));
|
||||
temp->flags = 0;
|
||||
temp->test = test;
|
||||
temp->action = action;
|
||||
return (make_command (which, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_while_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_while, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_until_command (test, action)
|
||||
COMMAND *test, *action;
|
||||
{
|
||||
return (make_until_or_while (cm_until, test, action));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_arith_command (exp)
|
||||
WORD_LIST *exp;
|
||||
{
|
||||
#if defined (DPAREN_ARITHMETIC)
|
||||
COMMAND *command;
|
||||
ARITH_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Arith = temp = (ARITH_COM *)xmalloc (sizeof (ARITH_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->exp = exp;
|
||||
|
||||
command->type = cm_arith;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (COND_COMMAND)
|
||||
struct cond_com *
|
||||
make_cond_node (type, op, left, right)
|
||||
int type;
|
||||
WORD_DESC *op;
|
||||
struct cond_com *left, *right;
|
||||
{
|
||||
COND_COM *temp;
|
||||
|
||||
temp = (COND_COM *)xmalloc (sizeof (COND_COM));
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->type = type;
|
||||
temp->op = op;
|
||||
temp->left = left;
|
||||
temp->right = right;
|
||||
|
||||
return (temp);
|
||||
}
|
||||
#endif
|
||||
|
||||
COMMAND *
|
||||
make_cond_command (cond_node)
|
||||
COND_COM *cond_node;
|
||||
{
|
||||
#if defined (COND_COMMAND)
|
||||
COMMAND *command;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Cond = cond_node;
|
||||
|
||||
command->type = cm_cond;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
command->line = cond_node ? cond_node->line : 0;
|
||||
|
||||
return (command);
|
||||
#else
|
||||
last_command_exit_value = 2;
|
||||
return ((COMMAND *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_bare_simple_command ()
|
||||
{
|
||||
COMMAND *command;
|
||||
SIMPLE_COM *temp;
|
||||
|
||||
command = (COMMAND *)xmalloc (sizeof (COMMAND));
|
||||
command->value.Simple = temp = (SIMPLE_COM *)xmalloc (sizeof (SIMPLE_COM));
|
||||
|
||||
temp->flags = 0;
|
||||
temp->line = line_number;
|
||||
temp->words = (WORD_LIST *)NULL;
|
||||
temp->redirects = (REDIRECT *)NULL;
|
||||
|
||||
command->type = cm_simple;
|
||||
command->redirects = (REDIRECT *)NULL;
|
||||
command->flags = 0;
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Return a command which is the connection of the word or redirection
|
||||
in ELEMENT, and the command * or NULL in COMMAND. */
|
||||
COMMAND *
|
||||
make_simple_command (element, command)
|
||||
ELEMENT element;
|
||||
COMMAND *command;
|
||||
{
|
||||
/* If we are starting from scratch, then make the initial command
|
||||
structure. Also note that we have to fill in all the slots, since
|
||||
malloc doesn't return zeroed space. */
|
||||
if (command == 0)
|
||||
{
|
||||
command = make_bare_simple_command ();
|
||||
parser_state |= PST_REDIRLIST;
|
||||
}
|
||||
|
||||
if (element.word)
|
||||
{
|
||||
command->value.Simple->words = make_word_list (element.word, command->value.Simple->words);
|
||||
parser_state &= ~PST_REDIRLIST;
|
||||
}
|
||||
else if (element.redirect)
|
||||
{
|
||||
REDIRECT *r = element.redirect;
|
||||
/* Due to the way <> is implemented, there may be more than a single
|
||||
redirection in element.redirect. We just follow the chain as far
|
||||
as it goes, and hook onto the end. */
|
||||
while (r->next)
|
||||
r = r->next;
|
||||
r->next = command->value.Simple->redirects;
|
||||
command->value.Simple->redirects = element.redirect;
|
||||
}
|
||||
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* Because we are Bourne compatible, we read the input for this
|
||||
<< or <<- redirection now, from wherever input is coming from.
|
||||
We store the input read into a WORD_DESC. Replace the text of
|
||||
the redirectee.word with the new input text. If <<- is on,
|
||||
then remove leading TABS from each line. */
|
||||
void
|
||||
make_here_document (temp, lineno)
|
||||
REDIRECT *temp;
|
||||
int lineno;
|
||||
{
|
||||
int kill_leading, redir_len;
|
||||
char *redir_word, *document, *full_line;
|
||||
int document_index, document_size, delim_unquoted;
|
||||
|
||||
if (temp->instruction != r_deblank_reading_until &&
|
||||
temp->instruction != r_reading_until)
|
||||
{
|
||||
internal_error (_("make_here_document: bad instruction type %d"), temp->instruction);
|
||||
return;
|
||||
}
|
||||
|
||||
kill_leading = temp->instruction == r_deblank_reading_until;
|
||||
|
||||
document = (char *)NULL;
|
||||
document_index = document_size = 0;
|
||||
|
||||
/* Quote removal is the only expansion performed on the delimiter
|
||||
for here documents, making it an extremely special case. */
|
||||
redir_word = string_quote_removal (temp->redirectee.filename->word, 0);
|
||||
|
||||
/* redirection_expand will return NULL if the expansion results in
|
||||
multiple words or no words. Check for that here, and just abort
|
||||
this here document if it does. */
|
||||
if (redir_word)
|
||||
redir_len = strlen (redir_word);
|
||||
else
|
||||
{
|
||||
temp->here_doc_eof = (char *)xmalloc (1);
|
||||
temp->here_doc_eof[0] = '\0';
|
||||
goto document_done;
|
||||
}
|
||||
|
||||
free (temp->redirectee.filename->word);
|
||||
temp->here_doc_eof = redir_word;
|
||||
|
||||
/* Read lines from wherever lines are coming from.
|
||||
For each line read, if kill_leading, then kill the
|
||||
leading tab characters.
|
||||
If the line matches redir_word exactly, then we have
|
||||
manufactured the document. Otherwise, add the line to the
|
||||
list of lines in the document. */
|
||||
|
||||
/* If the here-document delimiter was quoted, the lines should
|
||||
be read verbatim from the input. If it was not quoted, we
|
||||
need to perform backslash-quoted newline removal. */
|
||||
delim_unquoted = (temp->redirectee.filename->flags & W_QUOTED) == 0;
|
||||
while (full_line = read_secondary_line (delim_unquoted))
|
||||
{
|
||||
register char *line;
|
||||
int len;
|
||||
|
||||
line = full_line;
|
||||
line_number++;
|
||||
|
||||
/* If set -v is in effect, echo the line read. read_secondary_line/
|
||||
read_a_line leaves the newline at the end, so don't print another. */
|
||||
if (echo_input_at_read)
|
||||
fprintf (stderr, "%s", line);
|
||||
|
||||
if (kill_leading && *line)
|
||||
{
|
||||
/* Hack: To be compatible with some Bourne shells, we
|
||||
check the word before stripping the whitespace. This
|
||||
is a hack, though. */
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
while (*line == '\t')
|
||||
line++;
|
||||
}
|
||||
|
||||
if (*line == 0)
|
||||
continue;
|
||||
|
||||
if (STREQN (line, redir_word, redir_len) && line[redir_len] == '\n')
|
||||
goto document_done;
|
||||
|
||||
len = strlen (line);
|
||||
if (len + document_index >= document_size)
|
||||
{
|
||||
document_size = document_size ? 2 * (document_size + len) : len + 2;
|
||||
document = (char *)xrealloc (document, document_size);
|
||||
}
|
||||
|
||||
/* len is guaranteed to be > 0 because of the check for line
|
||||
being an empty string before the call to strlen. */
|
||||
FASTCOPY (line, document + document_index, len);
|
||||
document_index += len;
|
||||
}
|
||||
|
||||
if (full_line == 0)
|
||||
internal_warning (_("here-document at line %d delimited by end-of-file (wanted `%s')"), lineno, redir_word);
|
||||
|
||||
document_done:
|
||||
if (document)
|
||||
document[document_index] = '\0';
|
||||
else
|
||||
{
|
||||
document = (char *)xmalloc (1);
|
||||
document[0] = '\0';
|
||||
}
|
||||
temp->redirectee.filename->word = document;
|
||||
}
|
||||
|
||||
/* Generate a REDIRECT from SOURCE, DEST, and INSTRUCTION.
|
||||
INSTRUCTION is the instruction type, SOURCE is a file descriptor,
|
||||
and DEST is a file descriptor or a WORD_DESC *. */
|
||||
REDIRECT *
|
||||
make_redirection (source, instruction, dest_and_filename, flags)
|
||||
REDIRECTEE source;
|
||||
enum r_instruction instruction;
|
||||
REDIRECTEE dest_and_filename;
|
||||
int flags;
|
||||
{
|
||||
REDIRECT *temp;
|
||||
WORD_DESC *w;
|
||||
int wlen;
|
||||
intmax_t lfd;
|
||||
|
||||
temp = (REDIRECT *)xmalloc (sizeof (REDIRECT));
|
||||
|
||||
/* First do the common cases. */
|
||||
temp->redirector = source;
|
||||
temp->redirectee = dest_and_filename;
|
||||
temp->instruction = instruction;
|
||||
temp->flags = 0;
|
||||
temp->rflags = flags;
|
||||
temp->next = (REDIRECT *)NULL;
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
|
||||
case r_output_direction: /* >foo */
|
||||
case r_output_force: /* >| foo */
|
||||
case r_err_and_out: /* &>filename */
|
||||
temp->flags = O_TRUNC | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_appending_to: /* >>foo */
|
||||
case r_append_err_and_out: /* &>> filename */
|
||||
temp->flags = O_APPEND | O_WRONLY | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_input_direction: /* <foo */
|
||||
case r_inputa_direction: /* foo & makes this. */
|
||||
temp->flags = O_RDONLY;
|
||||
break;
|
||||
|
||||
case r_input_output: /* <>foo */
|
||||
temp->flags = O_RDWR | O_CREAT;
|
||||
break;
|
||||
|
||||
case r_deblank_reading_until: /* <<-foo */
|
||||
case r_reading_until: /* << foo */
|
||||
case r_reading_string: /* <<< foo */
|
||||
case r_close_this: /* <&- */
|
||||
case r_duplicating_input: /* 1<&2 */
|
||||
case r_duplicating_output: /* 1>&2 */
|
||||
break;
|
||||
|
||||
/* the parser doesn't pass these. */
|
||||
case r_move_input: /* 1<&2- */
|
||||
case r_move_output: /* 1>&2- */
|
||||
case r_move_input_word: /* 1<&$foo- */
|
||||
case r_move_output_word: /* 1>&$foo- */
|
||||
break;
|
||||
|
||||
/* The way the lexer works we have to do this here. */
|
||||
case r_duplicating_input_word: /* 1<&$foo */
|
||||
case r_duplicating_output_word: /* 1>&$foo */
|
||||
w = dest_and_filename.filename;
|
||||
wlen = strlen (w->word) - 1;
|
||||
if (w->word[wlen] == '-') /* Yuck */
|
||||
{
|
||||
w->word[wlen] = '\0';
|
||||
if (all_digits (w->word) && legal_number (w->word, &lfd) && lfd == (int)lfd)
|
||||
{
|
||||
dispose_word (w);
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input : r_move_output;
|
||||
temp->redirectee.dest = lfd;
|
||||
}
|
||||
else
|
||||
temp->instruction = (instruction == r_duplicating_input_word) ? r_move_input_word : r_move_output_word;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
programming_error (_("make_redirection: redirection instruction `%d' out of range"), instruction);
|
||||
abort ();
|
||||
break;
|
||||
}
|
||||
return (temp);
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_function_def (name, command, lineno, lstart)
|
||||
WORD_DESC *name;
|
||||
COMMAND *command;
|
||||
int lineno, lstart;
|
||||
{
|
||||
FUNCTION_DEF *temp;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *bash_source_v;
|
||||
ARRAY *bash_source_a;
|
||||
#endif
|
||||
|
||||
temp = (FUNCTION_DEF *)xmalloc (sizeof (FUNCTION_DEF));
|
||||
temp->command = command;
|
||||
temp->name = name;
|
||||
temp->line = lineno;
|
||||
temp->flags = 0;
|
||||
command->line = lstart;
|
||||
|
||||
/* Information used primarily for debugging. */
|
||||
temp->source_file = 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a);
|
||||
if (bash_source_a && array_num_elements (bash_source_a) > 0)
|
||||
temp->source_file = array_reference (bash_source_a, 0);
|
||||
#endif
|
||||
#if defined (DEBUGGER)
|
||||
bind_function_def (name->word, temp);
|
||||
#endif
|
||||
|
||||
temp->source_file = 0;
|
||||
return (make_command (cm_function_def, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_subshell_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
SUBSHELL_COM *temp;
|
||||
|
||||
temp = (SUBSHELL_COM *)xmalloc (sizeof (SUBSHELL_COM));
|
||||
temp->command = command;
|
||||
temp->flags = CMD_WANT_SUBSHELL;
|
||||
return (make_command (cm_subshell, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
COMMAND *
|
||||
make_coproc_command (name, command)
|
||||
char *name;
|
||||
COMMAND *command;
|
||||
{
|
||||
COPROC_COM *temp;
|
||||
|
||||
temp = (COPROC_COM *)xmalloc (sizeof (COPROC_COM));
|
||||
temp->name = savestring (name);
|
||||
temp->command = command;
|
||||
temp->flags = CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL;
|
||||
return (make_command (cm_coproc, (SIMPLE_COM *)temp));
|
||||
}
|
||||
|
||||
/* Reverse the word list and redirection list in the simple command
|
||||
has just been parsed. It seems simpler to do this here the one
|
||||
time then by any other method that I can think of. */
|
||||
COMMAND *
|
||||
clean_simple_command (command)
|
||||
COMMAND *command;
|
||||
{
|
||||
if (command->type != cm_simple)
|
||||
command_error ("clean_simple_command", CMDERR_BADTYPE, command->type, 0);
|
||||
else
|
||||
{
|
||||
command->value.Simple->words =
|
||||
REVERSE_LIST (command->value.Simple->words, WORD_LIST *);
|
||||
command->value.Simple->redirects =
|
||||
REVERSE_LIST (command->value.Simple->redirects, REDIRECT *);
|
||||
}
|
||||
|
||||
parser_state &= ~PST_REDIRLIST;
|
||||
return (command);
|
||||
}
|
||||
|
||||
/* The Yacc grammar productions have a problem, in that they take a
|
||||
list followed by an ampersand (`&') and do a simple command connection,
|
||||
making the entire list effectively asynchronous, instead of just
|
||||
the last command. This means that when the list is executed, all
|
||||
the commands have stdin set to /dev/null when job control is not
|
||||
active, instead of just the last. This is wrong, and needs fixing
|
||||
up. This function takes the `&' and applies it to the last command
|
||||
in the list. This is done only for lists connected by `;'; it makes
|
||||
`;' bind `tighter' than `&'. */
|
||||
COMMAND *
|
||||
connect_async_list (command, command2, connector)
|
||||
COMMAND *command, *command2;
|
||||
int connector;
|
||||
{
|
||||
COMMAND *t, *t1, *t2;
|
||||
|
||||
t1 = command;
|
||||
t = command->value.Connection->second;
|
||||
|
||||
if (!t || (command->flags & CMD_WANT_SUBSHELL) ||
|
||||
command->value.Connection->connector != ';')
|
||||
{
|
||||
t = command_connect (command, command2, connector);
|
||||
return t;
|
||||
}
|
||||
|
||||
/* This is just defensive programming. The Yacc precedence rules
|
||||
will generally hand this function a command where t points directly
|
||||
to the command we want (e.g. given a ; b ; c ; d &, t1 will point
|
||||
to the `a ; b ; c' list and t will be the `d'). We only want to do
|
||||
this if the list is not being executed as a unit in the background
|
||||
with `( ... )', so we have to check for CMD_WANT_SUBSHELL. That's
|
||||
the only way to tell. */
|
||||
while (((t->flags & CMD_WANT_SUBSHELL) == 0) && t->type == cm_connection &&
|
||||
t->value.Connection->connector == ';')
|
||||
{
|
||||
t1 = t;
|
||||
t = t->value.Connection->second;
|
||||
}
|
||||
/* Now we have t pointing to the last command in the list, and
|
||||
t1->value.Connection->second == t. */
|
||||
t2 = command_connect (t, command2, connector);
|
||||
t1->value.Connection->second = t2;
|
||||
return command;
|
||||
}
|
||||
+1
-1
@@ -431,7 +431,7 @@ indirection_level_string ()
|
||||
|
||||
old = change_flag ('x', FLAG_OFF);
|
||||
ps4 = decode_prompt_string (ps4);
|
||||
if (old == FLAG_ON)
|
||||
if (old)
|
||||
change_flag ('x', FLAG_ON);
|
||||
|
||||
if (ps4 == 0 || *ps4 == '\0')
|
||||
|
||||
+1568
File diff suppressed because it is too large
Load Diff
@@ -6593,7 +6593,8 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
|
||||
vtype &= ~VT_STARSUB;
|
||||
|
||||
mflags = 0;
|
||||
if (patsub && *patsub == '/')
|
||||
/* PATSUB is never NULL when this is called. */
|
||||
if (*patsub == '/')
|
||||
{
|
||||
mflags |= MATCH_GLOBREP;
|
||||
patsub++;
|
||||
@@ -6611,12 +6612,6 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
|
||||
|
||||
/* If the pattern starts with a `/', make sure we skip over it when looking
|
||||
for the replacement delimiter. */
|
||||
#if 0
|
||||
if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
|
||||
*rep++ = '\0';
|
||||
else
|
||||
rep = (char *)NULL;
|
||||
#else
|
||||
delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
|
||||
if (lpatsub[delim] == '/')
|
||||
{
|
||||
@@ -6625,7 +6620,6 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
|
||||
}
|
||||
else
|
||||
rep = (char *)NULL;
|
||||
#endif
|
||||
|
||||
if (rep && *rep == '\0')
|
||||
rep = (char *)NULL;
|
||||
@@ -6995,7 +6989,7 @@ parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, conta
|
||||
}
|
||||
else if (c == ':' && string[sindex] != RBRACE)
|
||||
want_substring = 1;
|
||||
else if (c == '/' && string[sindex] != RBRACE)
|
||||
else if (c == '/' /* && string[sindex] != RBRACE */) /* XXX */
|
||||
want_patsub = 1;
|
||||
#if defined (CASEMOD_EXPANSIONS)
|
||||
else if (c == '^' || c == ',' || c == '~')
|
||||
@@ -8136,7 +8130,7 @@ add_string:
|
||||
if (tword && (tword->flags & W_HASQUOTEDNULL))
|
||||
had_quoted_null = 1;
|
||||
|
||||
temp = tword->word;
|
||||
temp = tword ? tword->word : (char *)NULL;
|
||||
dispose_word_desc (tword);
|
||||
|
||||
goto add_string;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -72,3 +72,15 @@ fx ()
|
||||
2
|
||||
20
|
||||
20
|
||||
12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
|
||||
12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
0
|
||||
|
||||
@@ -92,3 +92,22 @@ echo $i
|
||||
|
||||
for ((i=0; i < 20; i++)) { : ; }
|
||||
echo $i
|
||||
|
||||
# added post-bash-4.2
|
||||
for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
|
||||
do
|
||||
printf "$i"
|
||||
done
|
||||
|
||||
echo
|
||||
|
||||
( for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
|
||||
do
|
||||
printf "$i"
|
||||
done )
|
||||
|
||||
echo
|
||||
|
||||
for (( i = 4; ;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
|
||||
|
||||
for (( i = 4;;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
fx()
|
||||
{
|
||||
i=0
|
||||
for (( ; i < 3; i++ ))
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
|
||||
for (( i=0; ; i++ ))
|
||||
do
|
||||
if (( i >= 3 )); then
|
||||
break;
|
||||
fi
|
||||
echo $i
|
||||
done
|
||||
|
||||
for (( i=0; i<3; ))
|
||||
do
|
||||
echo $i
|
||||
(( i++ ))
|
||||
done
|
||||
|
||||
i=0
|
||||
for (( ; ; ))
|
||||
do
|
||||
if (( i > 2 )); then
|
||||
break;
|
||||
fi
|
||||
echo $i;
|
||||
(( i++ ))
|
||||
done
|
||||
|
||||
i=0
|
||||
for ((;;))
|
||||
do
|
||||
if (( i > 2 )); then
|
||||
break;
|
||||
fi
|
||||
echo $i;
|
||||
(( i++ ))
|
||||
done
|
||||
}
|
||||
|
||||
for (( i=0; "i < 3" ; i++ ))
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
|
||||
i=0
|
||||
for (( ; "i < 3"; i++ ))
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
|
||||
for (( i=0; ; i++ ))
|
||||
do
|
||||
if (( i >= 3 )); then
|
||||
break;
|
||||
fi
|
||||
echo $i
|
||||
done
|
||||
|
||||
for ((i = 0; ;i++ ))
|
||||
do
|
||||
echo $i
|
||||
if (( i < 3 )); then
|
||||
(( i++ ))
|
||||
continue;
|
||||
fi
|
||||
break
|
||||
done
|
||||
|
||||
type fx
|
||||
fx
|
||||
|
||||
# errors
|
||||
for (( i=0; "i < 3" ))
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
echo $?
|
||||
|
||||
for (( i=0; i < 3; i++; 7 ))
|
||||
do
|
||||
echo $i
|
||||
done
|
||||
echo $?
|
||||
|
||||
# one-liners added in post-bash-2.04
|
||||
for ((i=0; i < 20; i++)) do : ; done
|
||||
echo $i
|
||||
|
||||
for ((i=0; i < 20; i++)) { : ; }
|
||||
echo $i
|
||||
+20
-4
@@ -205,14 +205,30 @@ ok
|
||||
0
|
||||
1
|
||||
2147483649
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
-9223372036854775808
|
||||
8 12
|
||||
./arith.tests: line 279: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
|
||||
./arith.tests: line 283: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 284: ((: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 283: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
|
||||
./arith.tests: line 287: a b: syntax error in expression (error token is "b")
|
||||
./arith.tests: line 288: ((: a b: syntax error in expression (error token is "b")
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
42
|
||||
./arith.tests: line 295: b[c]d: syntax error in expression (error token is "d")
|
||||
./arith.tests: line 299: b[c]d: syntax error in expression (error token is "d")
|
||||
|
||||
@@ -268,6 +268,10 @@ ${THIS_SH} ./arith4.sub
|
||||
# make sure arithmetic expansion handles ints > 2**31 - 1 using intmax_t
|
||||
echo $(( 2147483645 + 4 ))
|
||||
|
||||
# other tests using INTMAX_MIN and INTMAX_MAX that cause exceptions if not
|
||||
# handled correctly -- problem through bash-4.2
|
||||
${THIS_SH} ./arith5.sub
|
||||
|
||||
x=4
|
||||
y=7
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
intmax_max=$((2**63 - 1))
|
||||
intmax_min1=$((2**63))
|
||||
intmax_min2=$((-2**63))
|
||||
|
||||
case $intmax_max in
|
||||
9223372036854775807) ;;
|
||||
*) echo "warning: your machine does not support 64-bit arithmetic using intmax_t" 2>&1 ;;
|
||||
esac
|
||||
|
||||
# these are actually the same
|
||||
echo $(( $intmax_min1 % -1 ))
|
||||
echo $(( $intmax_min2 % -1 ))
|
||||
|
||||
echo $(( $intmax_max % -1 ))
|
||||
|
||||
lvalue=$intmax_min1
|
||||
(( lvalue%= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
lvalue=$intmax_min2
|
||||
(( lvalue%= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
lvalue=$intmax_max
|
||||
(( lvalue%= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
# and these
|
||||
echo $(( $intmax_min1 / -1 ))
|
||||
echo $(( $intmax_min2 / -1 ))
|
||||
|
||||
lvalue=$intmax_min1
|
||||
(( lvalue /= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
lvalue=$intmax_min2
|
||||
(( lvalue /= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
echo $(( $intmax_min1 * -1 ))
|
||||
echo $(( $intmax_min2 * -1 ))
|
||||
|
||||
lvalue=$intmax_min1
|
||||
(( lvalue *= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
lvalue=$intmax_min2
|
||||
(( lvalue *= -1 ))
|
||||
echo $lvalue
|
||||
|
||||
echo $(( -${intmax_min1} ))
|
||||
echo $(( -${intmax_min2} ))
|
||||
@@ -81,6 +81,10 @@ argv[1] = <bc>
|
||||
argv[1] = <c>
|
||||
argv[1] = <ab>
|
||||
argv[1] = <ab>
|
||||
argv[1] = <aacc>
|
||||
argv[1] = <aacc>
|
||||
argv[1] = <aabbcc>
|
||||
argv[1] = <aabbcc>
|
||||
argv[1] = <Oenophile>
|
||||
argv[1] = <OEnOphIlE>
|
||||
argv[1] = <>
|
||||
|
||||
@@ -14,6 +14,19 @@ recho ${f/""a""b/}
|
||||
recho ${f/""c/}
|
||||
recho ${f/"$v"c/}
|
||||
|
||||
unset foo empty
|
||||
foo=aabbcc
|
||||
|
||||
recho ${foo/bb/}
|
||||
recho ${foo/bb/$empty}
|
||||
|
||||
recho ${foo/}
|
||||
recho ${empty/}
|
||||
|
||||
recho ${foo/ }
|
||||
recho ${empty/ }
|
||||
unset foo empty
|
||||
|
||||
S2=oenophile
|
||||
|
||||
recho ${S2^"$v"[aeiou]}
|
||||
|
||||
Reference in New Issue
Block a user