commit bash-20070111 snapshot

This commit is contained in:
Chet Ramey
2011-12-07 09:02:33 -05:00
parent 9d6e5e3017
commit 1384c96f19
41 changed files with 51387 additions and 539 deletions
+96
View File
@@ -14183,3 +14183,99 @@ lib/intl/Makefile.in
lib/builtins/Makefile
- fixes to build LIBINTL_H if necessary, dependency on this for
mkbuiltins.o prevented `make -j 6' from working correctly
1/8
---
subst.c
- new function, fifos_pending(), returns the count of FIFOs in
fifo_list (process substitution)
subst.h
- extern declaration for fifos_pending()
execute_cmd.c
- in execute_simple_command, if CMD_NO_FORK is set before we call
execute_disk_command, make sure there are no FIFOs in the expanded
words (from process substitution) and turn off CMD_NO_FORK if there
are, so they can get unlinked when the command finishes
1/10
----
subst.c
- read_comsub now takes a flags parameter and returns appropriate W_*
flags in it
- command_substitute now returns a WORD_DESC *, with the string it used
to return as the `word' and `flags' filled in appropriately
subst.h
- changed extern declaration for command_substitute
{pcomplete,subst}.c
- changed callers of command_substitute appropriately
subst.c
- string_extract_verbatim now takes an additional int flags argument;
changed callers
1/11
----
support/texi2html
- fix problem that caused index links to not be generated if the first
index node had a name different than the node name
doc/bashref.texi
- encapsulated all indexes into a single `Indexes' appendix; works
around bug fixed in texi2html
1/12
----
subst.c
- add call to sv_histtimefmt in initialize_variables so HISTTIMEFORMAT
rom the environment is honored. Fix from Ark Submedes (heh)
<archimerged@gmail.com>
lib/readline/histfile.c
- make sure that the first character following the history comment
character at the beginning of a line is a digit before interpreting
it as a timestamp for the previous line
doc/{bash.1,bashref.texi},lib/readline/doc/hsuser.texi
- added detail to make it clear exactly how history timestamps are
saved to and read from the history file
subst.c
- change quote_escapes to add CTLESC before spaces if IFS is null,
just in case we have to split on literal spaces later on (e.g., in
case of unquoted $@). Corresponding changes to dequote_escapes.
Fixes a couple of problems reported by Brett Stahlman
<brettstahlman@comcast.net>
1/14
----
subst.c
- make same change to read_comsub to add CTLESC before ' ' if $IFS is
null, since we will split on literal spaces later
1/15
----
array.c
- new function, array_quote_escapes (ARRAY *a), calls quote_escapes
on each element of the array in the same way array_quote calls
quote_string
- call array_quote_escapes if match is not quoted in array_patsub
- array_slice is now used, so remove the #ifdef INCLUDE_UNUSED define
- change structure of array_subrange to call array_slice to create a
new array with the desired subset of elements, then call array_quote
or array_quote_escapes as necessary, like array_patsub. Convert to
a string by calling array_to_string on the sliced-out array
array.h
- new extern declaration for array_quote_escapes
subst.c
- since array_patsub now calls quote_escapes as necessary, callers
don't need to call it after array_patsub returns. Fixes first bug
reported by Brett Stahlman <brettstahlman@comcast.net>
- since array_subrange now calls quote_escapes as necessary, callers
don't need to call it after array_patsub returns. Same fix as
for array_patsub
+99 -1
View File
@@ -14171,5 +14171,103 @@ doc/{bash.1,bashref.texi},lib/readline/doc/rluser.texi
[many files]
- changes to make variables and function parameters `const' for better
text sharing
text sharing. Changes originally from Andreas Mohr
<andi@rhlx01.fht-esslingen.de>
1/4/2007
--------
lib/intl/Makefile.in
- use cmp before copying libgnuintl.h to libintl.h -- maybe save a few
rebuilds
lib/builtins/Makefile
- fixes to build LIBINTL_H if necessary, dependency on this for
mkbuiltins.o prevented `make -j 6' from working correctly
1/8
---
subst.c
- new function, fifos_pending(), returns the count of FIFOs in
fifo_list (process substitution)
subst.h
- extern declaration for fifos_pending()
execute_cmd.c
- in execute_simple_command, if CMD_NO_FORK is set before we call
execute_disk_command, make sure there are no FIFOs in the expanded
words (from process substitution) and turn off CMD_NO_FORK if there
are, so they can get unlinked when the command finishes
1/10
----
subst.c
- read_comsub now takes a flags parameter and returns appropriate W_*
flags in it
- command_substitute now returns a WORD_DESC *, with the string it used
to return as the `word' and `flags' filled in appropriately
subst.h
- changed extern declaration for command_substitute
{pcomplete,subst}.c
- changed callers of command_substitute appropriately
subst.c
- string_extract_verbatim now takes an additional int flags argument;
changed callers
1/11
----
support/texi2html
- fix problem that caused index links to not be generated if the first
index node had a name different than the node name
doc/bashref.texi
- encapsulated all indexes into a single `Indexes' appendix; works
around bug fixed in texi2html
1/12
----
subst.c
- add call to sv_histtimefmt in initialize_variables so HISTTIMEFORMAT
rom the environment is honored. Fix from Ark Submedes (heh)
<archimerged@gmail.com>
lib/readline/histfile.c
- make sure that the first character following the history comment
character at the beginning of a line is a digit before interpreting
it as a timestamp for the previous line
doc/{bash.1,bashref.texi},lib/readline/doc/hsuser.texi
- added detail to make it clear exactly how history timestamps are
saved to and read from the history file
subst.c
- change quote_escapes to add CTLESC before spaces if IFS is null,
just in case we have to split on literal spaces later on (e.g., in
case of unquoted $@). Corresponding changes to dequote_escapes.
Fixes a couple of problems reported by Brett Stahlman
<brettstahlman@comcast.net>
1/14
----
subst.c
- make same change to read_comsub to add CTLESC before ' ' if $IFS is
null, since we will split on literal spaces later
1/15
----
array.c
- new function, array_quote_escapes (ARRAY *a), calls quote_escapes
on each element of the array in the same way array_quote calls
quote_string
- call array_quote_escapes if match is not quoted in array_patsub
array.h
- new extern declaration for array_quote_escapes
subst.c
- since array_patsub now calls quote_escapes as necessary, callers
don't need to call it after array_patsub returns. Fixes first bug
reported by Brett Stahlman <brettstahlman@comcast.net>
+34 -6
View File
@@ -120,7 +120,6 @@ ARRAY *a;
return(a1);
}
#ifdef INCLUDE_UNUSED
/*
* Make and return a new array composed of the elements in array A from
* S to E, inclusive.
@@ -141,13 +140,12 @@ ARRAY_ELEMENT *s, *e;
for (p = s, i = 0; p != e; p = element_forw(p), i++) {
n = array_create_element (element_index(p), element_value(p));
ADD_BEFORE(a->head, n);
mi = element_index(ae);
mi = element_index(n);
}
a->num_elements = i;
a->max_index = mi;
return a;
}
#endif
/*
* Walk the array, calling FUNC once for each element, with the array
@@ -300,6 +298,23 @@ ARRAY *array;
return array;
}
ARRAY *
array_quote_escapes(array)
ARRAY *array;
{
ARRAY_ELEMENT *a;
char *t;
if (array == 0 || array_head(array) == 0 || array_empty(array))
return (ARRAY *)NULL;
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
t = quote_escapes (a->value);
FREE(a->value);
a->value = t;
}
return array;
}
/*
* Return a string whose elements are the members of array A beginning at
* index START and spanning NELEM members. Null elements are counted.
@@ -311,9 +326,10 @@ ARRAY *a;
arrayind_t start, nelem;
int starsub, quoted;
{
ARRAY *a2;
ARRAY_ELEMENT *h, *p;
arrayind_t i;
char *ifs, sep[2];
char *ifs, sep[2], *t;
p = a ? array_head (a) : 0;
if (p == 0 || array_empty (a) || start > array_max_index(a))
@@ -336,6 +352,13 @@ int starsub, quoted;
for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
;
a2 = array_slice(a, h, p);
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
array_quote(a2);
else
array_quote_escapes(a2);
if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
ifs = getifs();
sep[0] = ifs ? *ifs : '\0';
@@ -343,7 +366,10 @@ int starsub, quoted;
sep[0] = ' ';
sep[1] = '\0';
return (array_to_string_internal (h, p, sep, quoted));
t = array_to_string (a2, sep, 0);
array_dispose(a2);
return t;
}
char *
@@ -367,7 +393,9 @@ int mflags;
}
if (mflags & MATCH_QUOTED)
array_quote (a2);
array_quote(a2);
else
array_quote_escapes(a2);
if (mflags & MATCH_STARSUB) {
ifs = getifs();
sifs[0] = ifs ? *ifs : '\0';
+960
View File
@@ -0,0 +1,960 @@
/*
* array.c - functions to create, destroy, access, and manipulate arrays
* of strings.
*
* Arrays are sparse doubly-linked lists. An element's index is stored
* with it.
*
* Chet Ramey
* chet@ins.cwru.edu
*/
/* Copyright (C) 1997-2004 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "config.h"
#if defined (ARRAY_VARS)
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "bashansi.h"
#include "shell.h"
#include "array.h"
#include "builtins/common.h"
#define ADD_BEFORE(ae, new) \
do { \
ae->prev->next = new; \
new->prev = ae->prev; \
ae->prev = new; \
new->next = ae; \
} while(0)
static char *array_to_string_internal __P((ARRAY_ELEMENT *, ARRAY_ELEMENT *, char *, int));
ARRAY *
array_create()
{
ARRAY *r;
ARRAY_ELEMENT *head;
r =(ARRAY *)xmalloc(sizeof(ARRAY));
r->type = array_indexed;
r->max_index = -1;
r->num_elements = 0;
head = array_create_element(-1, (char *)NULL); /* dummy head */
head->prev = head->next = head;
r->head = head;
return(r);
}
void
array_flush (a)
ARRAY *a;
{
register ARRAY_ELEMENT *r, *r1;
if (a == 0)
return;
for (r = element_forw(a->head); r != a->head; ) {
r1 = element_forw(r);
array_dispose_element(r);
r = r1;
}
a->head->next = a->head->prev = a->head;
a->max_index = -1;
a->num_elements = 0;
}
void
array_dispose(a)
ARRAY *a;
{
if (a == 0)
return;
array_flush (a);
array_dispose_element(a->head);
free(a);
}
ARRAY *
array_copy(a)
ARRAY *a;
{
ARRAY *a1;
ARRAY_ELEMENT *ae, *new;
if (a == 0)
return((ARRAY *) NULL);
a1 = array_create();
a1->type = a->type;
a1->max_index = a->max_index;
a1->num_elements = a->num_elements;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
new = array_create_element(element_index(ae), element_value(ae));
ADD_BEFORE(a1->head, new);
}
return(a1);
}
/*
* Make and return a new array composed of the elements in array A from
* S to E, inclusive.
*/
ARRAY *
array_slice(array, s, e)
ARRAY *array;
ARRAY_ELEMENT *s, *e;
{
ARRAY *a;
ARRAY_ELEMENT *p, *n;
int i;
arrayind_t mi;
a = array_create ();
a->type = array->type;
for (p = s, i = 0; p != e; p = element_forw(p), i++) {
n = array_create_element (element_index(p), element_value(p));
ADD_BEFORE(a->head, n);
mi = element_index(n);
}
a->num_elements = i;
a->max_index = mi;
return a;
}
/*
* Walk the array, calling FUNC once for each element, with the array
* element as the argument.
*/
void
array_walk(a, func, udata)
ARRAY *a;
sh_ae_map_func_t *func;
void *udata;
{
register ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
return;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
if ((*func)(ae, udata) < 0)
return;
}
/*
* Shift the array A N elements to the left. Delete the first N elements
* and subtract N from the indices of the remaining elements. If FLAGS
* does not include AS_DISPOSE, this returns a singly-linked null-terminated
* list of elements so the caller can dispose of the chain. If FLAGS
* includes AS_DISPOSE, this function disposes of the shifted-out elements
* and returns NULL.
*/
ARRAY_ELEMENT *
array_shift(a, n, flags)
ARRAY *a;
int n, flags;
{
register ARRAY_ELEMENT *ae, *ret;
register int i;
if (a == 0 || array_empty(a) || n <= 0)
return ((ARRAY_ELEMENT *)NULL);
for (i = 0, ret = ae = element_forw(a->head); ae != a->head && i < n; ae = element_forw(ae), i++)
;
if (ae == a->head) {
/* Easy case; shifting out all of the elements */
if (flags & AS_DISPOSE) {
array_flush (a);
return ((ARRAY_ELEMENT *)NULL);
}
for (ae = ret; element_forw(ae) != a->head; ae = element_forw(ae))
;
element_forw(ae) = (ARRAY_ELEMENT *)NULL;
a->head->next = a->head->prev = a->head;
a->max_index = -1;
a->num_elements = 0;
return ret;
}
/*
* ae now points to the list of elements we want to retain.
* ret points to the list we want to either destroy or return.
*/
ae->prev->next = (ARRAY_ELEMENT *)NULL; /* null-terminate RET */
a->head->next = ae; /* slice RET out of the array */
ae->prev = a->head;
for ( ; ae != a->head; ae = element_forw(ae))
element_index(ae) -= n; /* renumber retained indices */
a->num_elements -= n; /* modify bookkeeping information */
a->max_index -= n;
if (flags & AS_DISPOSE) {
for (ae = ret; ae; ) {
ret = element_forw(ae);
array_dispose_element(ae);
ae = ret;
}
return ((ARRAY_ELEMENT *)NULL);
}
return ret;
}
/*
* Shift array A right N indices. If S is non-null, it becomes the value of
* the new element 0. Returns the number of elements in the array after the
* shift.
*/
int
array_rshift (a, n, s)
ARRAY *a;
int n;
char *s;
{
register ARRAY_ELEMENT *ae, *new;
if (a == 0 || (array_empty(a) && s == 0))
return 0;
else if (n <= 0)
return (a->num_elements);
ae = element_forw(a->head);
if (s) {
new = array_create_element(0, s);
ADD_BEFORE(ae, new);
a->num_elements++;
if (array_num_elements(a) == 1) /* array was empty */
return 1;
}
/*
* Renumber all elements in the array except the one we just added.
*/
for ( ; ae != a->head; ae = element_forw(ae))
element_index(ae) += n;
a->max_index = element_index(a->head->prev);
return (a->num_elements);
}
ARRAY_ELEMENT *
array_unshift_element(a)
ARRAY *a;
{
return (array_shift (a, 1, 0));
}
int
array_shift_element(a, v)
ARRAY *a;
char *v;
{
return (array_rshift (a, 1, v));
}
ARRAY *
array_quote(array)
ARRAY *array;
{
ARRAY_ELEMENT *a;
char *t;
if (array == 0 || array_head(array) == 0 || array_empty(array))
return (ARRAY *)NULL;
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
t = quote_string (a->value);
FREE(a->value);
a->value = t;
}
return array;
}
ARRAY *
array_quote_escapes(array)
ARRAY *array;
{
ARRAY_ELEMENT *a;
char *t;
if (array == 0 || array_head(array) == 0 || array_empty(array))
return (ARRAY *)NULL;
for (a = element_forw(array->head); a != array->head; a = element_forw(a)) {
t = quote_escapes (a->value);
FREE(a->value);
a->value = t;
}
return array;
}
/*
* Return a string whose elements are the members of array A beginning at
* index START and spanning NELEM members. Null elements are counted.
* Since arrays are sparse, unset array elements are not counted.
*/
char *
array_subrange (a, start, nelem, starsub, quoted)
ARRAY *a;
arrayind_t start, nelem;
int starsub, quoted;
{
ARRAY *a2;
ARRAY_ELEMENT *h, *p;
arrayind_t i;
char *ifs, sep[2], *t;
p = a ? array_head (a) : 0;
if (p == 0 || array_empty (a) || start > array_max_index(a))
return ((char *)NULL);
/*
* Find element with index START. If START corresponds to an unset
* element (arrays can be sparse), use the first element whose index
* is >= START. If START is < 0, we count START indices back from
* the end of A (not elements, even with sparse arrays -- START is an
* index).
*/
for (p = element_forw(p); p != array_head(a) && start > element_index(p); p = element_forw(p))
;
if (p == a->head)
return ((char *)NULL);
/* Starting at P, take NELEM elements, inclusive. */
for (i = 0, h = p; p != a->head && i < nelem; i++, p = element_forw(p))
;
a2 = array_slice(a, h, p);
if (mflags & MATCH_QUOTED)
array_quote (a2);
else
array_quote_escapes (a2);
if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
ifs = getifs();
sep[0] = ifs ? *ifs : '\0';
} else
sep[0] = ' ';
sep[1] = '\0';
t = array_to_string (a2, sep, 0);
array_dispose(a2);
return t;
}
char *
array_patsub (a, pat, rep, mflags)
ARRAY *a;
char *pat, *rep;
int mflags;
{
ARRAY *a2;
ARRAY_ELEMENT *e;
char *t, *ifs, sifs[2];
if (a == 0 || array_head(a) == 0 || array_empty(a))
return ((char *)NULL);
a2 = array_copy(a);
for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
t = pat_subst(element_value(e), pat, rep, mflags);
FREE(element_value(e));
e->value = t;
}
if (mflags & MATCH_QUOTED)
array_quote (a2);
else
array_quote_escapes (a2);
if (mflags & MATCH_STARSUB) {
ifs = getifs();
sifs[0] = ifs ? *ifs : '\0';
sifs[1] = '\0';
t = array_to_string (a2, sifs, 0);
} else
t = array_to_string (a2, " ", 0);
array_dispose (a2);
return t;
}
/*
* Allocate and return a new array element with index INDEX and value
* VALUE.
*/
ARRAY_ELEMENT *
array_create_element(indx, value)
arrayind_t indx;
char *value;
{
ARRAY_ELEMENT *r;
r = (ARRAY_ELEMENT *)xmalloc(sizeof(ARRAY_ELEMENT));
r->ind = indx;
r->value = value ? savestring(value) : (char *)NULL;
r->next = r->prev = (ARRAY_ELEMENT *) NULL;
return(r);
}
#ifdef INCLUDE_UNUSED
ARRAY_ELEMENT *
array_copy_element(ae)
ARRAY_ELEMENT *ae;
{
return(ae ? array_create_element(element_index(ae), element_value(ae))
: (ARRAY_ELEMENT *) NULL);
}
#endif
void
array_dispose_element(ae)
ARRAY_ELEMENT *ae;
{
if (ae) {
FREE(ae->value);
free(ae);
}
}
/*
* Add a new element with index I and value V to array A (a[i] = v).
*/
int
array_insert(a, i, v)
ARRAY *a;
arrayind_t i;
char *v;
{
register ARRAY_ELEMENT *new, *ae;
if (a == 0)
return(-1);
new = array_create_element(i, v);
if (i > array_max_index(a)) {
/*
* Hook onto the end. This also works for an empty array.
* Fast path for the common case of allocating arrays
* sequentially.
*/
ADD_BEFORE(a->head, new);
a->max_index = i;
a->num_elements++;
return(0);
}
/*
* Otherwise we search for the spot to insert it.
*/
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
if (element_index(ae) == i) {
/*
* Replacing an existing element.
*/
array_dispose_element(new);
free(element_value(ae));
ae->value = v ? savestring(v) : (char *)NULL;
return(0);
} else if (element_index(ae) > i) {
ADD_BEFORE(ae, new);
a->num_elements++;
return(0);
}
}
return (-1); /* problem */
}
/*
* Delete the element with index I from array A and return it so the
* caller can dispose of it.
*/
ARRAY_ELEMENT *
array_remove(a, i)
ARRAY *a;
arrayind_t i;
{
register ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
return((ARRAY_ELEMENT *) NULL);
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
if (element_index(ae) == i) {
ae->next->prev = ae->prev;
ae->prev->next = ae->next;
a->num_elements--;
if (i == array_max_index(a))
a->max_index = element_index(ae->prev);
return(ae);
}
return((ARRAY_ELEMENT *) NULL);
}
/*
* Return the value of a[i].
*/
char *
array_reference(a, i)
ARRAY *a;
arrayind_t i;
{
register ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
return((char *) NULL);
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
if (element_index(ae) == i)
return(element_value(ae));
return((char *) NULL);
}
/* Convenience routines for the shell to translate to and from the form used
by the rest of the code. */
WORD_LIST *
array_to_word_list(a)
ARRAY *a;
{
WORD_LIST *list;
ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
return((WORD_LIST *)NULL);
list = (WORD_LIST *)NULL;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae))
list = make_word_list (make_bare_word(element_value(ae)), list);
return (REVERSE_LIST(list, WORD_LIST *));
}
ARRAY *
array_from_word_list (list)
WORD_LIST *list;
{
ARRAY *a;
if (list == 0)
return((ARRAY *)NULL);
a = array_create();
return (array_assign_list (a, list));
}
WORD_LIST *
array_keys_to_word_list(a)
ARRAY *a;
{
WORD_LIST *list;
ARRAY_ELEMENT *ae;
char *t;
if (a == 0 || array_empty(a))
return((WORD_LIST *)NULL);
list = (WORD_LIST *)NULL;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
t = itos(element_index(ae));
list = make_word_list (make_bare_word(t), list);
free(t);
}
return (REVERSE_LIST(list, WORD_LIST *));
}
ARRAY *
array_assign_list (array, list)
ARRAY *array;
WORD_LIST *list;
{
register WORD_LIST *l;
register arrayind_t i;
for (l = list, i = 0; l; l = l->next, i++)
array_insert(array, i, l->word->word);
return array;
}
char **
array_to_argv (a)
ARRAY *a;
{
char **ret, *t;
int i;
ARRAY_ELEMENT *ae;
if (a == 0 || array_empty(a))
return ((char **)NULL);
ret = strvec_create (array_num_elements (a) + 1);
i = 0;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
t = element_value (ae);
ret[i++] = t ? savestring (t) : (char *)NULL;
}
ret[i] = (char *)NULL;
return (ret);
}
/*
* Return a string that is the concatenation of all the elements in A,
* separated by SEP.
*/
static char *
array_to_string_internal (start, end, sep, quoted)
ARRAY_ELEMENT *start, *end;
char *sep;
int quoted;
{
char *result, *t;
ARRAY_ELEMENT *ae;
int slen, rsize, rlen, reg;
if (start == end) /* XXX - should not happen */
return ((char *)NULL);
slen = strlen(sep);
result = NULL;
for (rsize = rlen = 0, ae = start; ae != end; ae = element_forw(ae)) {
if (rsize == 0)
result = (char *)xmalloc (rsize = 64);
if (element_value(ae)) {
t = quoted ? quote_string(element_value(ae)) : element_value(ae);
reg = strlen(t);
RESIZE_MALLOCED_BUFFER (result, rlen, (reg + slen + 2),
rsize, rsize);
strcpy(result + rlen, t);
rlen += reg;
if (quoted && t)
free(t);
/*
* Add a separator only after non-null elements.
*/
if (element_forw(ae) != end) {
strcpy(result + rlen, sep);
rlen += slen;
}
}
}
if (result)
result[rlen] = '\0'; /* XXX */
return(result);
}
char *
array_to_assign (a, quoted)
ARRAY *a;
int quoted;
{
char *result, *valstr, *is;
char indstr[INT_STRLEN_BOUND(intmax_t) + 1];
ARRAY_ELEMENT *ae;
int rsize, rlen, elen;
if (a == 0 || array_empty (a))
return((char *)NULL);
result = (char *)xmalloc (rsize = 128);
result[0] = '(';
rlen = 1;
for (ae = element_forw(a->head); ae != a->head; ae = element_forw(ae)) {
is = inttostr (element_index(ae), indstr, sizeof(indstr));
valstr = element_value (ae) ? sh_double_quote (element_value(ae))
: (char *)NULL;
elen = STRLEN (indstr) + 8 + STRLEN (valstr);
RESIZE_MALLOCED_BUFFER (result, rlen, (elen + 1), rsize, rsize);
result[rlen++] = '[';
strcpy (result + rlen, is);
rlen += STRLEN (is);
result[rlen++] = ']';
result[rlen++] = '=';
if (valstr) {
strcpy (result + rlen, valstr);
rlen += STRLEN (valstr);
}
if (element_forw(ae) != a->head)
result[rlen++] = ' ';
FREE (valstr);
}
RESIZE_MALLOCED_BUFFER (result, rlen, 1, rsize, 8);
result[rlen++] = ')';
result[rlen] = '\0';
if (quoted) {
/* This is not as efficient as it could be... */
valstr = sh_single_quote (result);
free (result);
result = valstr;
}
return(result);
}
char *
array_to_string (a, sep, quoted)
ARRAY *a;
char *sep;
int quoted;
{
if (a == 0)
return((char *)NULL);
if (array_empty(a))
return(savestring(""));
return (array_to_string_internal (element_forw(a->head), a->head, sep, quoted));
}
#if defined (INCLUDE_UNUSED) || defined (TEST_ARRAY)
/*
* Return an array consisting of elements in S, separated by SEP
*/
ARRAY *
array_from_string(s, sep)
char *s, *sep;
{
ARRAY *a;
WORD_LIST *w;
if (s == 0)
return((ARRAY *)NULL);
w = list_string (s, sep, 0);
if (w == 0)
return((ARRAY *)NULL);
a = array_from_word_list (w);
return (a);
}
#endif
#if defined (TEST_ARRAY)
/*
* To make a running version, compile -DTEST_ARRAY and link with:
* xmalloc.o syntax.o lib/malloc/libmalloc.a lib/sh/libsh.a
*/
int interrupt_immediately = 0;
int
signal_is_trapped(s)
int s;
{
return 0;
}
void
fatal_error(const char *s, ...)
{
fprintf(stderr, "array_test: fatal memory error\n");
abort();
}
void
programming_error(const char *s, ...)
{
fprintf(stderr, "array_test: fatal programming error\n");
abort();
}
WORD_DESC *
make_bare_word (s)
const char *s;
{
WORD_DESC *w;
w = (WORD_DESC *)xmalloc(sizeof(WORD_DESC));
w->word = s ? savestring(s) : savestring ("");
w->flags = 0;
return w;
}
WORD_LIST *
make_word_list(x, l)
WORD_DESC *x;
WORD_LIST *l;
{
WORD_LIST *w;
w = (WORD_LIST *)xmalloc(sizeof(WORD_LIST));
w->word = x;
w->next = l;
return w;
}
WORD_LIST *
list_string(s, t, i)
char *s, *t;
int i;
{
char *r, *a;
WORD_LIST *wl;
if (s == 0)
return (WORD_LIST *)NULL;
r = savestring(s);
wl = (WORD_LIST *)NULL;
a = strtok(r, t);
while (a) {
wl = make_word_list (make_bare_word(a), wl);
a = strtok((char *)NULL, t);
}
return (REVERSE_LIST (wl, WORD_LIST *));
}
GENERIC_LIST *
list_reverse (list)
GENERIC_LIST *list;
{
register GENERIC_LIST *next, *prev;
for (prev = 0; list; ) {
next = list->next;
list->next = prev;
prev = list;
list = next;
}
return prev;
}
char *
pat_subst(s, t, u, i)
char *s, *t, *u;
int i;
{
return ((char *)NULL);
}
char *
quote_string(s)
char *s;
{
return savestring(s);
}
print_element(ae)
ARRAY_ELEMENT *ae;
{
char lbuf[INT_STRLEN_BOUND (intmax_t) + 1];
printf("array[%s] = %s\n",
inttostr (element_index(ae), lbuf, sizeof (lbuf)),
element_value(ae));
}
print_array(a)
ARRAY *a;
{
printf("\n");
array_walk(a, print_element, (void *)NULL);
}
main()
{
ARRAY *a, *new_a, *copy_of_a;
ARRAY_ELEMENT *ae, *aew;
char *s;
a = array_create();
array_insert(a, 1, "one");
array_insert(a, 7, "seven");
array_insert(a, 4, "four");
array_insert(a, 1029, "one thousand twenty-nine");
array_insert(a, 12, "twelve");
array_insert(a, 42, "forty-two");
print_array(a);
s = array_to_string (a, " ", 0);
printf("s = %s\n", s);
copy_of_a = array_from_string(s, " ");
printf("copy_of_a:");
print_array(copy_of_a);
array_dispose(copy_of_a);
printf("\n");
free(s);
ae = array_remove(a, 4);
array_dispose_element(ae);
ae = array_remove(a, 1029);
array_dispose_element(ae);
array_insert(a, 16, "sixteen");
print_array(a);
s = array_to_string (a, " ", 0);
printf("s = %s\n", s);
copy_of_a = array_from_string(s, " ");
printf("copy_of_a:");
print_array(copy_of_a);
array_dispose(copy_of_a);
printf("\n");
free(s);
array_insert(a, 2, "two");
array_insert(a, 1029, "new one thousand twenty-nine");
array_insert(a, 0, "zero");
array_insert(a, 134, "");
print_array(a);
s = array_to_string (a, ":", 0);
printf("s = %s\n", s);
copy_of_a = array_from_string(s, ":");
printf("copy_of_a:");
print_array(copy_of_a);
array_dispose(copy_of_a);
printf("\n");
free(s);
new_a = array_copy(a);
print_array(new_a);
s = array_to_string (new_a, ":", 0);
printf("s = %s\n", s);
copy_of_a = array_from_string(s, ":");
free(s);
printf("copy_of_a:");
print_array(copy_of_a);
array_shift(copy_of_a, 2, AS_DISPOSE);
printf("copy_of_a shifted by two:");
print_array(copy_of_a);
ae = array_shift(copy_of_a, 2, 0);
printf("copy_of_a shifted by two:");
print_array(copy_of_a);
for ( ; ae; ) {
aew = element_forw(ae);
array_dispose_element(ae);
ae = aew;
}
array_rshift(copy_of_a, 1, (char *)0);
printf("copy_of_a rshift by 1:");
print_array(copy_of_a);
array_rshift(copy_of_a, 2, "new element zero");
printf("copy_of_a rshift again by 2 with new element zero:");
print_array(copy_of_a);
s = array_to_assign(copy_of_a, 0);
printf("copy_of_a=%s\n", s);
free(s);
ae = array_shift(copy_of_a, array_num_elements(copy_of_a), 0);
for ( ; ae; ) {
aew = element_forw(ae);
array_dispose_element(ae);
ae = aew;
}
array_dispose(copy_of_a);
printf("\n");
array_dispose(a);
array_dispose(new_a);
}
#endif /* TEST_ARRAY */
#endif /* ARRAY_VARS */
+1
View File
@@ -55,6 +55,7 @@ extern int array_rshift __P((ARRAY *, int, char *));
extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
extern int array_shift_element __P((ARRAY *, char *));
extern ARRAY *array_quote __P((ARRAY *));
extern ARRAY *array_quote_escapes __P((ARRAY *));
extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
extern char *array_patsub __P((ARRAY *, char *, char *, int));
+111
View File
@@ -0,0 +1,111 @@
/* array.h -- definitions for the interface exported by array.c that allows
the rest of the shell to manipulate array variables. */
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include "stdc.h"
typedef intmax_t arrayind_t;
enum atype {array_indexed, array_assoc};
typedef struct array {
enum atype type;
arrayind_t max_index, num_elements;
struct array_element *head;
} ARRAY;
typedef struct array_element {
arrayind_t ind;
char *value;
struct array_element *next, *prev;
} ARRAY_ELEMENT;
typedef int sh_ae_map_func_t __P((ARRAY_ELEMENT *, void *));
/* Basic operations on entire arrays */
extern ARRAY *array_create __P((void));
extern void array_flush __P((ARRAY *));
extern void array_dispose __P((ARRAY *));
extern ARRAY *array_copy __P((ARRAY *));
extern ARRAY *array_slice __P((ARRAY *, ARRAY_ELEMENT *, ARRAY_ELEMENT *));
extern void array_walk __P((ARRAY *, sh_ae_map_func_t *, void *));
extern ARRAY_ELEMENT *array_shift __P((ARRAY *, int, int));
extern int array_rshift __P((ARRAY *, int, char *));
extern ARRAY_ELEMENT *array_unshift_element __P((ARRAY *));
extern int array_shift_element __P((ARRAY *, char *));
extern ARRAY *array_quote __P((ARRAY *));
extern char *array_subrange __P((ARRAY *, arrayind_t, arrayind_t, int, int));
extern char *array_patsub __P((ARRAY *, char *, char *, int));
/* Basic operations on array elements. */
extern ARRAY_ELEMENT *array_create_element __P((arrayind_t, char *));
extern ARRAY_ELEMENT *array_copy_element __P((ARRAY_ELEMENT *));
extern void array_dispose_element __P((ARRAY_ELEMENT *));
extern int array_insert __P((ARRAY *, arrayind_t, char *));
extern ARRAY_ELEMENT *array_remove __P((ARRAY *, arrayind_t));
extern char *array_reference __P((ARRAY *, arrayind_t));
/* Converting to and from arrays */
extern WORD_LIST *array_to_word_list __P((ARRAY *));
extern ARRAY *array_from_word_list __P((WORD_LIST *));
extern WORD_LIST *array_keys_to_word_list __P((ARRAY *));
extern ARRAY *array_assign_list __P((ARRAY *, WORD_LIST *));
extern char **array_to_argv __P((ARRAY *));
extern char *array_to_assign __P((ARRAY *, int));
extern char *array_to_string __P((ARRAY *, char *, int));
extern ARRAY *array_from_string __P((char *, char *));
/* Flags for array_shift */
#define AS_DISPOSE 0x01
#define array_num_elements(a) ((a)->num_elements)
#define array_max_index(a) ((a)->max_index)
#define array_head(a) ((a)->head)
#define array_empty(a) ((a)->num_elements == 0)
#define element_value(ae) ((ae)->value)
#define element_index(ae) ((ae)->ind)
#define element_forw(ae) ((ae)->next)
#define element_back(ae) ((ae)->prev)
/* Convenience */
#define array_push(a,v) \
do { array_rshift ((a), 1, (v)); } while (0)
#define array_pop(a) \
do { array_dispose_element (array_shift ((a), 1, 0)); } while (0)
#define GET_ARRAY_FROM_VAR(n, v, a) \
do { \
(v) = find_variable (n); \
(a) = ((v) && array_p ((v))) ? array_cell (v) : (ARRAY *)0; \
} while (0)
#define ALL_ELEMENT_SUB(c) ((c) == '@' || (c) == '*')
#endif /* _ARRAY_H_ */
+1 -1
View File
@@ -55,7 +55,7 @@
*/
/* The character which is used to separate arguments. */
int brace_arg_separator = ',';
static const int brace_arg_separator = ',';
#if defined (__P)
static int brace_gobbler __P((char *, size_t, int *, int));
+1
View File
@@ -88,6 +88,7 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
#define W_HASQUOTEDNULL 0x040000 /* word contains a quoted null character */
#define W_DQUOTE 0x080000 /* word should be treated as if double-quoted */
#define W_NOPROCSUB 0x100000 /* don't perform process substitution */
#define W_HASCTLESC 0x200000 /* word contains literal CTLESC characters */
/* Possible values for subshell_environment */
#define SUBSHELL_ASYNC 0x01 /* subshell caused by `command &' */
+3 -1
View File
@@ -908,7 +908,9 @@ D1) Why does bash run a different version of `command' than
On many systems, `which' is actually a csh script that assumes
you're running csh. In tcsh, `which' and its cousin `where'
are builtins. On other Unix systems, `which' is a perl script
that uses the PATH environment variable.
that uses the PATH environment variable. Many Linux distributions
use GNU `which', which is a C program that can understand shell
aliases.
The csh script version reads the csh startup files from your
home directory and uses those to determine which `command' will
+1841
View File
File diff suppressed because it is too large Load Diff
+294
View File
@@ -0,0 +1,294 @@
# This Makefile is for the Bash/documentation directory -*- text -*-.
#
# Copyright (C) 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
PACKAGE = bash
VERSION = 3.2-maint
PACKAGE_BUGREPORT = bug-bash@gnu.org
PACKAGE_NAME = bash
PACKAGE_STRING = bash 3.2-maint
PACKAGE_VERSION = 3.2-maint
#
SHELL = /bin/sh
RM = rm -f
topdir = /Users/chet/src/bash/src
srcdir = /Users/chet/src/bash/src/doc
VPATH = .:/Users/chet/src/bash/src/doc
prefix = /usr/local
exec_prefix = ${prefix}
infodir = ${prefix}/share/info
# set this to a directory name to have the HTML files installed
htmldir = ${docdir}
# Support an alternate destination root directory for package building
DESTDIR =
mandir = ${prefix}/share/man
manpfx = man
man1ext = .1
man1dir = $(mandir)/$(manpfx)1
man3ext = .3
man3dir = $(mandir)/$(manpfx)3
INSTALL = /usr/bin/install -c
INSTALL_DATA = ${INSTALL} -m 644
BUILD_DIR = /usr/local/build/chet/bash/bash-current
SUPPORT_SRCDIR = $(topdir)/support
# bad style
RL_LIBDIR = $(topdir)/lib/readline
# unused
TEXINDEX = texindex
TEX = tex
MAKEINFO = makeinfo
TEXI2DVI = ${SUPPORT_SRCDIR}/texi2dvi
TEXI2HTML = ${SUPPORT_SRCDIR}/texi2html
MAN2HTML = ${BUILD_DIR}/support/man2html
HTMLPOST = ${srcdir}/htmlpost.sh
INFOPOST = ${srcdir}/infopost.sh
QUIETPS = #set this to -q to shut up dvips
PAPERSIZE = letter # change to a4 for A4-size paper
PSDPI = 600 # could be 300 if you like
DVIPS = dvips -D ${PSDPI} $(QUIETPS) -t ${PAPERSIZE} -o $@ # tricky
TEXINPUTDIR = $(RL_LIBDIR)/doc
SET_TEXINPUTS = TEXINPUTS=.:$(TEXINPUTDIR):$$TEXINPUTS
# These tools might not be available; they're not required
DVIPDF = dvipdfm -o $@ -p ${PAPERSIZE}
PSPDF = gs -sPAPERSIZE=${PAPERSIZE} -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -sOutputFile=$@
MKDIRS = ${SUPPORT_SRCDIR}/mkdirs
# This should be a program that converts troff to an ascii-readable format
NROFF = groff -Tascii
# This should be a program that converts troff to postscript
GROFF = groff
HSUSER = $(RL_LIBDIR)/doc/hsuser.texi
RLUSER = $(RL_LIBDIR)/doc/rluser.texi
BASHREF_FILES = $(srcdir)/bashref.texi $(srcdir)/version.texi
.SUFFIXES: .0 .1 .3 .ms .ps .txt .dvi .html .pdf
.1.ps:
$(RM) $@
-${GROFF} -man $< > $@
.1.0:
$(RM) $@
-${NROFF} -man $< > $@
.1.html:
$(RM) $@
-${MAN2HTML} $< | ${HTMLPOST} > $@
.ms.ps:
$(RM) $@
-${GROFF} -ms $< > $@
.ms.txt:
$(RM) $@
-${NROFF} -ms $< > $@
.3.ps:
$(RM) $@
-${GROFF} -man $< > $@
.3.0:
$(RM) $@
-${NROFF} -man $< > $@
.3.html:
$(RM) $@
-${MAN2HTML} $< > $@
.ps.pdf:
$(RM) $@
-${PSPDF} $<
.dvi.pdf:
$(RM) $@
-${DVIPDF} $<
.dvi.ps:
${RM} $@
-${DVIPS} $<
all: ps info dvi text html
nodvi: ps info text html
PSFILES = bash.ps bashbug.ps article.ps builtins.ps rbash.ps
DVIFILES = bashref.dvi bashref.ps
INFOFILES = bashref.info
MAN0FILES = bash.0 bashbug.0 builtins.0 rbash.0
HTMLFILES = bashref.html bash.html
PDFFILES = bash.pdf bashref.pdf article.pdf rose94.pdf
ps: ${PSFILES}
dvi: ${DVIFILES}
info: ${INFOFILES}
text: ${MAN0FILES}
html: ${HTMLFILES}
pdf: ${PDFFILES}
bashref.dvi: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
${SET_TEXINPUTS} $(TEXI2DVI) $(srcdir)/bashref.texi
bashref.info: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
$(MAKEINFO) --no-split -I$(TEXINPUTDIR) $(srcdir)/bashref.texi
bashref.html: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
$(TEXI2HTML) -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi
b.html: $(BASHREF_FILES) $(HSUSER) $(RLUSER)
./texi2html.debug -o $@ -verbose -menu -monolithic -I $(TEXINPUTDIR) $(srcdir)/bashref.texi
bash.info: bashref.info
${SHELL} ${INFOPOST} < $(srcdir)/bashref.info > $@ ; \
bash.txt: bash.1
bash.ps: bash.1
bash.html: bash.1 $(MAN2HTML)
bashbug.ps: bashbug.1
builtins.ps: builtins.1 bash.1
rbash.ps: rbash.1 bash.1
bash.0: bash.1
bashbug.0: bashbug.1
builtins.0: builtins.1 bash.1
rbash.0: rbash.1 bash.1
article.ps: article.ms
bashref.ps: bashref.dvi
article.pdf: article.ps
bashref.pdf: bashref.dvi
bash.pdf: bash.ps
rose94.pdf: rose94.ps
$(MAN2HTML): ${topdir}/support/man2html.c
-( cd ${BUILD_DIR}/support ; ${MAKE} ${MFLAGS} man2html)
clean:
$(RM) *.aux *.bak *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps \
*.pgs *.bt *.bts *.rw *.rws *.fns *.kys *.tps *.vrs *.o
${RM} core *.core
mostlyclean: clean
$(RM) Makefile
distclean: clean maybe-clean
$(RM) Makefile
maintainer-clean: clean
${RM} ${PSFILES} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES}
${RM} ${CREATED_FAQ}
$(RM) Makefile
maybe-clean:
-if test "X$(topdir)" != "X$(BUILD_DIR)"; then \
$(RM) ${PSFILES} ${DVIFILES} ${INFOFILES} ${MAN0FILES} ${HTMLFILES}; \
fi
installdirs:
-$(SHELL) $(SUPPORT_SRCDIR)/mkinstalldirs $(DESTDIR)$(man1dir)
-$(SHELL) $(SUPPORT_SRCDIR)/mkinstalldirs $(DESTDIR)$(infodir)
-if test -n "$(htmldir)" ; then \
$(SHELL) $(SUPPORT_SRCDIR)/mkinstalldirs $(DESTDIR)$(htmldir) ; \
fi
install: info installdirs bash.info
-$(INSTALL_DATA) $(srcdir)/bash.1 $(DESTDIR)$(man1dir)/bash${man1ext}
-$(INSTALL_DATA) $(srcdir)/bashbug.1 $(DESTDIR)$(man1dir)/bashbug${man1ext}
# uncomment the next line to install the builtins man page
# -$(INSTALL_DATA) $(srcdir)/builtins.1 $(DESTDIR)$(man1dir)/bash_builtins${man1ext}
-$(INSTALL_DATA) $(srcdir)/bash.info $(DESTDIR)$(infodir)/bash.info
# run install-info if it is present to update the info directory
if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \
install-info --dir-file=$(DESTDIR)$(infodir)/dir $(DESTDIR)$(infodir)/bash.info; \
else true; fi
# if htmldir is set, install the html files into that directory
-if test -n "${htmldir}" ; then \
$(INSTALL_DATA) $(srcdir)/bash.html $(DESTDIR)$(htmldir) ; \
$(INSTALL_DATA) $(srcdir)/bashref.html $(DESTDIR)$(htmldir) ; \
fi
uninstall:
-$(RM) $(DESTDIR)$(man1dir)/bash${man1ext} $(DESTDIR)$(man1dir)/bashbug${man1ext}
$(RM) $(DESTDIR)$(infodir)/bash.info
-if test -n "$(htmldir)" ; then \
$(RM) $(DESTDIR)$(htmldir)/bash.html ; \
$(RM) $(DESTDIR)$(htmldir)/bashref.html ; \
fi
# for use by chet
CREATED_FAQ = faq.news faq.news2 faq.mail faq.version
faq: ${CREATED_FAQ}
faq.version: FAQ.version FAQ
sh mkfaqvers FAQ.version > $@
faq.headers.mail: FAQ.headers.mail FAQ
sh mkfaqvers FAQ.headers.mail > $@
faq.headers.news: FAQ.headers.news FAQ
sh mkfaqvers FAQ.headers.news > $@
faq.headers.news2: FAQ.headers.news2 FAQ
sh mkfaqvers FAQ.headers.news2 > $@
faq.news: FAQ faq.headers.news faq.version
$(RM) $@
cat faq.headers.news faq.version FAQ > $@
faq.news2: FAQ faq.headers.news2 faq.version
$(RM) $@
cat faq.headers.news2 faq.version FAQ > $@
faq.mail: FAQ faq.headers.mail faq.version
$(RM) $@
cat faq.headers.mail faq.version FAQ > $@
inst: bashref.texi
$(SHELL) ./mkinstall
cmp -s INSTALL ../INSTALL || mv INSTALL ../INSTALL
$(RM) INSTALL
posix: bashref.texi
$(SHELL) ./mkposix
cmp -s POSIX ../POSIX || mv POSIX ../POSIX
$(RM) POSIX
rbash: bashref.texi
$(SH) ./mkrbash
cmp -s RBASH ../RBASH || mv RBASH ../RBASH
$(RM) RBASH
xdist: pdf inst posix rbash
+15448
View File
File diff suppressed because it is too large Load Diff
+31 -6
View File
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Tue Dec 26 19:01:54 EST 2006
.\" Last Change: Fri Jan 12 16:29:22 EST 2007
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2006 December 26" "GNU Bash-3.2"
.TH BASH 1 "2007 January 12" "GNU Bash-3.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -51,8 +51,8 @@ bash \- GNU Bourne-Again SHell
[options]
[file]
.SH COPYRIGHT
.if n Bash is Copyright (C) 1989-2005 by the Free Software Foundation, Inc.
.if t Bash is Copyright \(co 1989-2005 by the Free Software Foundation, Inc.
.if n Bash is Copyright (C) 1989-2007 by the Free Software Foundation, Inc.
.if t Bash is Copyright \(co 1989-2007 by the Free Software Foundation, Inc.
.SH DESCRIPTION
.B Bash
is an \fBsh\fR-compatible command language interpreter that
@@ -1752,6 +1752,8 @@ for \fIstrftime\fP(3) to print the time stamp associated with each history
entry displayed by the \fBhistory\fP builtin.
If this variable is set, time stamps are written to the history file so
they may be preserved across shell sessions.
This uses the history comment character to distinguish timestamps from
other history lines.
.TP
.B HOME
The home directory of the current user; the default argument for the
@@ -5611,6 +5613,13 @@ is truncated, if necessary, to contain no more than
the number of lines specified by the value of
.SM
.BR HISTFILESIZE .
When the history file is read,
lines beginning with the history comment character followed immediately
by a digit are interpreted as timestamps for the preceding history line.
These timestamps are optionally displayed depending on the value of the
.SM
.B HISTTIMEFORMAT
variable.
When an interactive shell exits, the last
.SM
.B $HISTSIZE
@@ -5631,7 +5640,16 @@ If
.SM
.B HISTFILE
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
not saved.
If the
.SM
.HISTTIMEFORMAT
variable is set, time stamps are written to the history file, marked
with the history comment character, so
they may be preserved across shell sessions.
This uses the history comment character to distinguish timestamps from
other history lines.
After saving the history, the history file is truncated
to contain no more than
.SM
.B HISTFILESIZE
@@ -5765,6 +5783,9 @@ history expansion mechanism (see the description of
.B histchars
above under
.BR "Shell Variables" ).
The shell uses
the history comment character to mark history timestamps when
writing the history file.
.SS Event Designators
.PP
An event designator is a reference to a command line entry in the
@@ -7169,7 +7190,11 @@ are added.
.PD
.PP
If the \fBHISTTIMEFORMAT\fP is set, the time stamp information
associated with each history entry is written to the history file.
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
The return value is 0 unless an invalid option is encountered, an
error occurs while reading or writing the history file, an invalid
\fIoffset\fP is supplied as an argument to \fB\-d\fP, or the
+574 -200
View File
File diff suppressed because it is too large Load Diff
+36 -4
View File
@@ -6,12 +6,12 @@
.\" Case Western Reserve University
.\" chet@po.cwru.edu
.\"
.\" Last Change: Tue Dec 26 19:01:54 EST 2006
.\" Last Change: Fri Jan 12 16:29:22 EST 2007
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2006 December 26" "GNU Bash-3.2"
.TH BASH 1 "2007 January 12" "GNU Bash-3.2"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -1351,6 +1351,10 @@ This variable is available only in shell functions invoked by the
programmable completion facilities (see \fBProgrammable Completion\fP
below).
.TP
.B COMP_KEY
The key (or final key of a key sequence) used to invoke the current
completion function.
.TP
.B COMP_LINE
The current command line.
This variable is available only in shell functions and external
@@ -1748,6 +1752,8 @@ for \fIstrftime\fP(3) to print the time stamp associated with each history
entry displayed by the \fBhistory\fP builtin.
If this variable is set, time stamps are written to the history file so
they may be preserved across shell sessions.
This uses the history comment character to distinguish timestamps from
other history lines.
.TP
.B HOME
The home directory of the current user; the default argument for the
@@ -5493,7 +5499,10 @@ When the command or function is invoked, the
.BR COMP_LINE ,
.SM
.BR COMP_POINT ,
.SM
.BR COMP_KEY ,
and
.SM
.B COMP_TYPE
variables are assigned values as described above under
\fBShell Variables\fP.
@@ -5604,6 +5613,13 @@ is truncated, if necessary, to contain no more than
the number of lines specified by the value of
.SM
.BR HISTFILESIZE .
When the history file is read,
lines beginning with the history comment character followed immediately
by a digit are interpreted as timestamps for the preceding history line.
These timestamps are optionally displayed depending on the value of the
.SM
.B HISTTIMEFORMAT
variable.
When an interactive shell exits, the last
.SM
.B $HISTSIZE
@@ -5624,7 +5640,16 @@ If
.SM
.B HISTFILE
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
not saved.
If the
.SM
.HISTTIMEFORMAT
variable is set, time stamps are written to the history file, marked
with the history comment character, so
they may be preserved across shell sessions.
This uses the history comment character to distinguish timestamps from
other history lines.
After saving the history, the history file is truncated
to contain no more than
.SM
.B HISTFILESIZE
@@ -5758,6 +5783,9 @@ history expansion mechanism (see the description of
.B histchars
above under
.BR "Shell Variables" ).
The shell uses
the history comment character to mark history timestamps when
writing the history file.
.SS Event Designators
.PP
An event designator is a reference to a command line entry in the
@@ -7162,7 +7190,11 @@ are added.
.PD
.PP
If the \fBHISTTIMEFORMAT\fP is set, the time stamp information
associated with each history entry is written to the history file.
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
The return value is 0 unless an invalid option is encountered, an
error occurs while reading or writing the history file, an invalid
\fIoffset\fP is supplied as an argument to \fB\-d\fP, or the
+1 -1
View File
@@ -11619,6 +11619,6 @@ Array variables may not (yet) be exported.
</DL>
<HR>
This document was created by man2html from bash.1.<BR>
Time: 02 January 2007 10:25:26 EST
Time: 09 January 2007 09:51:43 EST
</BODY>
</HTML>
+217 -198
View File
File diff suppressed because it is too large Load Diff
+21 -12
View File
@@ -111,13 +111,7 @@ reference on shell behavior.
between Bash and historical
versions of /bin/sh.
* Copying This Manual:: Copying this manual.
* Builtin Index:: Index of Bash builtin commands.
* Reserved Word Index:: Index of Bash reserved words.
* Variable Index:: Quick reference helps you find the
variable you want.
* Function Index:: Index of bindable Readline functions.
* Concept Index:: General index for concepts described in
this manual.
* Indexes:: Various indexes for this manual.
@end menu
@end ifnottex
@@ -4644,6 +4638,8 @@ for @var{strftime} to print the time stamp associated with each history
entry displayed by the @code{history} builtin.
If this variable is set, time stamps are written to the history file so
they may be preserved across shell sessions.
This uses the history comment character to distinguish timestamps from
other history lines.
@item HOSTFILE
Contains the name of a file in the same format as @file{/etc/hosts} that
@@ -7467,24 +7463,37 @@ The SVR4.2 shell behaves differently when invoked as @code{jsh}
@include fdl.texi
@node Indexes
@appendix Indexes
@menu
* Builtin Index:: Index of Bash builtin commands.
* Reserved Word Index:: Index of Bash reserved words.
* Variable Index:: Quick reference helps you find the
variable you want.
* Function Index:: Index of bindable Readline functions.
* Concept Index:: General index for concepts described in
this manual.
@end menu
@node Builtin Index
@unnumbered Index of Shell Builtin Commands
@appendixsec Index of Shell Builtin Commands
@printindex bt
@node Reserved Word Index
@unnumbered Index of Shell Reserved Words
@appendixsec Index of Shell Reserved Words
@printindex rw
@node Variable Index
@unnumbered Parameter and Variable Index
@appendixsec Parameter and Variable Index
@printindex vr
@node Function Index
@unnumbered Function Index
@appendixsec Function Index
@printindex fn
@node Concept Index
@unnumbered Concept Index
@appendixsec Concept Index
@printindex cp
@bye
File diff suppressed because it is too large Load Diff
+23 -12
View File
@@ -111,13 +111,7 @@ reference on shell behavior.
between Bash and historical
versions of /bin/sh.
* Copying This Manual:: Copying this manual.
* Builtin Index:: Index of Bash builtin commands.
* Reserved Word Index:: Index of Bash reserved words.
* Variable Index:: Quick reference helps you find the
variable you want.
* Function Index:: Index of bindable Readline functions.
* Concept Index:: General index for concepts described in
this manual.
* Indexes:: Various indexes for this manual.
@end menu
@end ifnottex
@@ -4482,6 +4476,10 @@ This variable is available only in shell functions and external
commands invoked by the
programmable completion facilities (@pxref{Programmable Completion}).
@item COMP_KEY
The key (or final key of a key sequence) used to invoke the current
completion function.
@item COMP_WORDBREAKS
The set of characters that the Readline library treats as word
separators when performing word completion.
@@ -7463,24 +7461,37 @@ The SVR4.2 shell behaves differently when invoked as @code{jsh}
@include fdl.texi
@node Indexes
@appendix Indexes
@menu
* Builtin Index:: Index of Bash builtin commands.
* Reserved Word Index:: Index of Bash reserved words.
* Variable Index:: Quick reference helps you find the
variable you want.
* Function Index:: Index of bindable Readline functions.
* Concept Index:: General index for concepts described in
this manual.
@end menu
@node Builtin Index
@unnumbered Index of Shell Builtin Commands
@appendixsec Index of Shell Builtin Commands
@printindex bt
@node Reserved Word Index
@unnumbered Index of Shell Reserved Words
@appendixsec Index of Shell Reserved Words
@printindex rw
@node Variable Index
@unnumbered Parameter and Variable Index
@appendixsec Parameter and Variable Index
@printindex vr
@node Function Index
@unnumbered Function Index
@appendixsec Function Index
@printindex fn
@node Concept Index
@unnumbered Concept Index
@appendixsec Concept Index
@printindex cp
@bye
+3 -3
View File
@@ -1,5 +1,5 @@
From: chet@po.cwru.edu (Chet Ramey)
From: chet.ramey@case.edu (Chet Ramey)
To: bug-bash@gnu.org
Subject: BASH Frequently-Asked Questions (FAQ version 3.35)
Reply-To: chet@po.cwru.edu
Cc: chet.ramey@case.edu
Reply-To: chet.ramey@case.edu
+3 -3
View File
@@ -1,8 +1,8 @@
From: chet@po.cwru.edu (Chet Ramey)
From: chet.ramey@case.edu (Chet Ramey)
To: bug-bash@gnu.org
Subject: BASH Frequently-Asked Questions (FAQ version 3.35)
Reply-To: chet@po.cwru.edu
Cc: chet.ramey@case.edu
Reply-To: chet.ramey@case.edu
Archive-name: unix-faq/shell/bash
Posting-Frequency: monthly
Submitted-By: chet@po.cwru.edu (Chet Ramey)
+10220
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -1,10 +1,10 @@
@ignore
Copyright (C) 1988-2006 Free Software Foundation, Inc.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sat Dec 30 19:31:54 EST 2006
@set LASTCHANGE Fri Jan 12 16:29:58 EST 2007
@set EDITION 3.2
@set VERSION 3.2
@set UPDATED 30 December 2006
@set UPDATED-MONTH December 2006
@set UPDATED 12 January 2007
@set UPDATED-MONTH January 2007
+2 -2
View File
@@ -2,9 +2,9 @@
Copyright (C) 1988-2006 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Tue Dec 26 16:58:41 EST 2006
@set LASTCHANGE Sat Dec 30 19:31:54 EST 2006
@set EDITION 3.2
@set VERSION 3.2
@set UPDATED 26 December 2006
@set UPDATED 30 December 2006
@set UPDATED-MONTH December 2006
+5
View File
@@ -3071,6 +3071,11 @@ run_builtin:
if (command_line == 0)
command_line = savestring (the_printed_command_except_trap);
#if defined (PROCESS_SUBSTITUTION)
if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0)
simple_command->flags &= ~CMD_NO_FORK;
#endif
execute_disk_command (words, simple_command->redirects, command_line,
pipe_in, pipe_out, async, fds_to_close,
simple_command->flags);
+10 -3
View File
@@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2006 Free Software Foundation, Inc.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@@ -97,7 +97,11 @@ to contain no more than @env{$HISTFILESIZE}
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
If the @env{HISTTIMEFORMAT} is set, the time stamp information
associated with each history entry is written to the history file.
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
@@ -277,7 +281,10 @@ them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable.
history expansion mechanism with the @code{histchars} variable,
as explained above (@pxref{Bash Variables}). The shell uses
the history comment character to mark history timestamps when
writing the history file.
@end ifset
@menu
+10 -3
View File
@@ -97,7 +97,11 @@ to contain no more than @env{$HISTFILESIZE}
lines. If @env{HISTFILESIZE} is not set, no truncation is performed.
If the @env{HISTTIMEFORMAT} is set, the time stamp information
associated with each history entry is written to the history file.
associated with each history entry is written to the history file,
marked with the history comment character.
When the history file is read, lines beginning with the history
comment character followed immediately by a digit are interpreted
as timestamps for the previous history line.
The builtin command @code{fc} may be used to list or edit and re-execute
a portion of the history list.
@@ -133,7 +137,7 @@ history list and history file.
@item fc
@btindex fc
@example
@code{fc [-e @var{ename}] [-nlr] [@var{first}] [@var{last}]}
@code{fc [-e @var{ename}] [-lnr] [@var{first}] [@var{last}]}
@code{fc -s [@var{pat}=@var{rep}] [@var{command}]}
@end example
@@ -277,7 +281,10 @@ them, so that they are available for subsequent recall.
This is most useful in conjunction with Readline.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable.
history expansion mechanism with the @code{histchars} variable,
as explained above (@pxref{Bash Variables}). The shell uses
the history comment character to mark history timestamps when
writing the history file.
@end ifset
@menu
+4 -4
View File
@@ -1,10 +1,10 @@
@ignore
Copyright (C) 1988-2006 Free Software Foundation, Inc.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
@end ignore
@set EDITION 5.2
@set VERSION 5.2
@set UPDATED 30 December 2006
@set UPDATED-MONTH December 2006
@set UPDATED 12 January 2007
@set UPDATED-MONTH January 2007
@set LASTCHANGE Sat Dec 30 19:17:22 EST 2006
@set LASTCHANGE Fri Jan 12 16:31:33 EST 2007
+3 -3
View File
@@ -4,7 +4,7 @@ Copyright (C) 1988-2006 Free Software Foundation, Inc.
@set EDITION 5.2
@set VERSION 5.2
@set UPDATED 26 April 2006
@set UPDATED-MONTH April 2006
@set UPDATED 30 December 2006
@set UPDATED-MONTH December 2006
@set LASTCHANGE Wed Apr 26 09:22:57 EDT 2006
@set LASTCHANGE Sat Dec 30 19:17:22 EST 2006
+3 -1
View File
@@ -53,6 +53,8 @@
# include <unistd.h>
#endif
#include <ctype.h>
#if defined (__EMX__)
# undef HAVE_MMAP
#endif
@@ -103,7 +105,7 @@ int history_write_timestamps = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char)
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char && isdigit ((s)[1]) )
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
+1 -1
View File
@@ -53,7 +53,7 @@
# include <unistd.h>
#endif
#if defined (__EMX__) || defined (__CYGWIN__)
#if defined (__EMX__)
# undef HAVE_MMAP
#endif
+4 -1
View File
@@ -1084,6 +1084,7 @@ gen_command_matches (cs, text, line, ind, lwords, nw, cw)
char *csbuf, *cscmd, *t;
int cmdlen, cmdsize, n, ws, we;
WORD_LIST *cmdlist, *cl;
WORD_DESC *tw;
STRINGLIST *sl;
bind_compfunc_variables (line, ind, lwords, cw, 1);
@@ -1115,7 +1116,9 @@ gen_command_matches (cs, text, line, ind, lwords, nw, cw)
}
cscmd[cmdlen] = '\0';
csbuf = command_substitute (cscmd, 0);
tw = command_substitute (cscmd, 0);
csbuf = tw ? tw->word : (char *)NULL;
dispose_word_desc (tw);
/* Now clean up and destroy everything. */
dispose_words (cmdlist);
+92 -32
View File
@@ -216,7 +216,7 @@ static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
#endif
static int do_assignment_internal __P((const WORD_DESC *, int));
static char *string_extract_verbatim __P((char *, size_t, int *, char *));
static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
static char *string_extract __P((char *, int *, char *, int));
static char *string_extract_double_quoted __P((char *, int *, int));
static inline char *string_extract_single_quoted __P((char *, int *));
@@ -254,7 +254,7 @@ static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, in
static char *process_substitute __P((char *, int));
static char *read_comsub __P((int, int));
static char *read_comsub __P((int, int, int *));
#ifdef ARRAY_VARS
static arrayind_t array_length_reference __P((char *));
@@ -886,11 +886,12 @@ skip_single_quoted (string, slen, sind)
/* Just like string_extract, but doesn't hack backslashes or any of
that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
static char *
string_extract_verbatim (string, slen, sindex, charlist)
string_extract_verbatim (string, slen, sindex, charlist, flags)
char *string;
size_t slen;
int *sindex;
char *charlist;
int flags;
{
register int i = *sindex;
#if defined (HANDLE_MULTIBYTE)
@@ -1887,7 +1888,13 @@ string_list_dollar_at (list, quoted)
sep[1] = '\0';
#endif
/* XXX -- why call quote_list if ifs == 0? we can get away without doing
it now that quote_escapes quotes spaces */
#if 0
tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
#else
tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
#endif
? quote_list (list)
: list_quote_escapes (list);
@@ -1973,7 +1980,7 @@ list_string (string, separators, quoted)
{
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
unless multibyte chars are possible. */
current_word = string_extract_verbatim (string, slen, &sindex, separators);
current_word = string_extract_verbatim (string, slen, &sindex, separators, 0);
if (current_word == 0)
break;
@@ -2096,7 +2103,7 @@ get_word_from_string (stringp, separators, endptr)
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
unless multibyte chars are possible. */
slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
current_word = string_extract_verbatim (s, slen, &sindex, separators);
current_word = string_extract_verbatim (s, slen, &sindex, separators, 0);
/* Set ENDPTR to the first character after the end of the word. */
if (endptr)
@@ -2922,7 +2929,12 @@ expand_string (string, quoted)
/* Quote escape characters in string s, but no other characters. This is
used to protect CTLESC and CTLNUL in variable values from the rest of
the word expansion process after the variable is expanded. */
the word expansion process after the variable is expanded. If IFS is
null, we quote spaces as well, just in case we split on spaces later
(in the case of unquoted $@, we will eventually attempt to split the
entire word on spaces). Corresponding code exists in dequote_escapes.
Even if we don't end up splitting on spaces, quoting spaces is not a
problem. */
char *
quote_escapes (string)
char *string;
@@ -2930,17 +2942,19 @@ quote_escapes (string)
register char *s, *t;
size_t slen;
char *result, *send;
int quote_spaces;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
quote_spaces = (ifs_value && *ifs_value == 0);
t = result = (char *)xmalloc ((slen * 2) + 1);
s = string;
while (*s)
{
if (*s == CTLESC || *s == CTLNUL)
if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
*t++ = CTLESC;
COPY_CHAR_P (t, s, send);
}
@@ -2982,6 +2996,7 @@ dequote_escapes (string)
register char *s, *t;
size_t slen;
char *result, *send;
int quote_spaces;
DECLARE_MBSTATE;
if (string == 0)
@@ -2996,9 +3011,10 @@ dequote_escapes (string)
if (strchr (string, CTLESC) == 0)
return (strcpy (result, s));
quote_spaces = (ifs_value && *ifs_value == 0);
while (*s)
{
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
{
s++;
if (*s == '\0')
@@ -4129,6 +4145,12 @@ unlink_fifo_list ()
nfifo = 0;
}
int
fifos_pending ()
{
return nfifo;
}
static char *
make_named_pipe ()
{
@@ -4178,6 +4200,12 @@ add_fifo_list (fd)
nfds++;
}
int
fifos_pending ()
{
return 0; /* used for cleanup; not needed with /dev/fd */
}
void
unlink_fifo_list ()
{
@@ -4423,21 +4451,23 @@ process_substitute (string, open_for_read_in_child)
/***********************************/
static char *
read_comsub (fd, quoted)
read_comsub (fd, quoted, rflag)
int fd, quoted;
int *rflag;
{
char *istring, buf[128], *bufp;
int istring_index, istring_size, c;
int istring_index, istring_size, c, tflag;
ssize_t bufn;
istring = (char *)NULL;
istring_index = istring_size = bufn = 0;
istring_index = istring_size = bufn = tflag = 0;
#ifdef __CYGWIN__
setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
#endif
/* Read the output of the command through the pipe. */
/* Read the output of the command through the pipe. This may need to be
changed to understand multibyte characters in the future. */
while (1)
{
if (fd < 0)
@@ -4462,7 +4492,18 @@ read_comsub (fd, quoted)
/* Add the character to ISTRING, possibly after resizing it. */
RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
/* This is essentially quote_string inline */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
istring[istring_index++] = CTLESC;
/* Escape CTLESC and CTLNUL in the output to protect those characters
from the rest of the word expansions (word splitting and globbing.)
This is essentially quote_escapes inline. */
else if (c == CTLESC)
{
tflag |= W_HASCTLESC;
istring[istring_index++] = CTLESC;
}
else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
istring[istring_index++] = CTLESC;
istring[istring_index++] = c;
@@ -4486,6 +4527,8 @@ read_comsub (fd, quoted)
if (istring_index == 0)
{
FREE (istring);
if (rflag)
*rflag = tflag;
return (char *)NULL;
}
@@ -4510,26 +4553,29 @@ read_comsub (fd, quoted)
else
strip_trailing (istring, istring_index - 1, 1);
if (rflag)
*rflag = tflag;
return istring;
}
/* Perform command substitution on STRING. This returns a string,
possibly quoted. */
char *
/* Perform command substitution on STRING. This returns a WORD_DESC * with the
contained string possibly quoted. */
WORD_DESC *
command_substitute (string, quoted)
char *string;
int quoted;
{
pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
char *istring;
int result, fildes[2], function_value, pflags, rc;
int result, fildes[2], function_value, pflags, rc, tflag;
WORD_DESC *ret;
istring = (char *)NULL;
/* Don't fork () if there is no need to. In the case of no command to
run, just return NULL. */
if (!string || !*string || (string[0] == '\n' && !string[1]))
return ((char *)NULL);
return ((WORD_DESC *)NULL);
if (wordexp_only && read_but_dont_execute)
{
@@ -4569,11 +4615,7 @@ command_substitute (string, quoted)
#endif /* JOB_CONTROL */
old_async_pid = last_asynchronous_pid;
#if 0
pid = make_child ((char *)NULL, 0);
#else
pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
#endif
last_asynchronous_pid = old_async_pid;
if (pid == 0)
@@ -4597,7 +4639,7 @@ command_substitute (string, quoted)
FREE (istring);
close (fildes[0]);
close (fildes[1]);
return ((char *)NULL);
return ((WORD_DESC *)NULL);
}
if (pid == 0)
@@ -4671,6 +4713,9 @@ command_substitute (string, quoted)
last_command_exit_value = rc;
rc = run_exit_trap ();
#if defined (PROCESS_SUBSTITUTION)
unlink_fifo_list ();
#endif
exit (rc);
}
else
@@ -4681,7 +4726,8 @@ command_substitute (string, quoted)
close (fildes[1]);
istring = read_comsub (fildes[0], quoted);
tflag = 0;
istring = read_comsub (fildes[0], quoted, &tflag);
close (fildes[0]);
@@ -4711,7 +4757,11 @@ command_substitute (string, quoted)
give_terminal_to (pipeline_pgrp, 0);
#endif /* JOB_CONTROL */
return (istring);
ret = alloc_word_desc ();
ret->word = istring;
ret->flags = tflag;
return ret;
}
}
@@ -4983,7 +5033,7 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
/* If the entire expression is between double quotes, we want to treat
the value as a double-quoted string, with the exception that we strip
embedded unescaped double quotes. */
embedded unescaped double quotes (for sh backwards compatibility). */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
{
hasdol = 0;
@@ -5554,12 +5604,16 @@ parameter_brace_substring (varname, value, substr, quoted)
so verify_substring_values just returns the numbers specified and we
rely on array_subrange to understand how to deal with them). */
tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
#if 0
/* array_subrange now calls array_quote_escapes as appropriate, so the
caller no longer needs to. */
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
{
temp = tt ? quote_escapes (tt) : (char *)NULL;
FREE (tt);
}
else
#endif
temp = tt;
break;
#endif
@@ -5810,12 +5864,16 @@ parameter_brace_patsub (varname, value, patsub, quoted)
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
temp = array_patsub (array_cell (v), p, rep, mflags);
#if 0
/* Don't need to do this anymore; array_patsub calls array_quote_escapes
as appropriate before adding the space separators. */
if (temp && (mflags & MATCH_QUOTED) == 0)
{
tt = quote_escapes (temp);
free (temp);
temp = tt;
}
#endif
break;
#endif
}
@@ -6578,7 +6636,11 @@ comsub:
/* we need zindex+1 because string[zindex] == RPAREN */
temp1 = substring (string, *sindex, zindex+1);
else
temp1 = command_substitute (temp, quoted);
{
tdesc = command_substitute (temp, quoted);
temp1 = tdesc ? tdesc->word : (char *)NULL;
dispose_word_desc (tdesc);
}
FREE (temp);
temp = temp1;
break;
@@ -6986,7 +7048,9 @@ add_string:
else
{
de_backslash (temp);
temp1 = command_substitute (temp, quoted);
tword = command_substitute (temp, quoted);
temp1 = tword ? tword->word : (char *)NULL;
dispose_word_desc (tword);
}
FREE (temp);
temp = temp1;
@@ -7512,11 +7576,7 @@ setifs (v)
unsigned char uc;
ifs_var = v;
#if 0
ifs_value = v ? value_cell (v) : " \t\n";
#else
ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
#endif
/* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
handle multibyte chars in IFS */
+8186
View File
File diff suppressed because it is too large Load Diff
+89 -33
View File
@@ -216,7 +216,7 @@ static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
#endif
static int do_assignment_internal __P((const WORD_DESC *, int));
static char *string_extract_verbatim __P((char *, size_t, int *, char *));
static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
static char *string_extract __P((char *, int *, char *, int));
static char *string_extract_double_quoted __P((char *, int *, int));
static inline char *string_extract_single_quoted __P((char *, int *));
@@ -254,7 +254,7 @@ static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, in
static char *process_substitute __P((char *, int));
static char *read_comsub __P((int, int));
static char *read_comsub __P((int, int, int *));
#ifdef ARRAY_VARS
static arrayind_t array_length_reference __P((char *));
@@ -886,11 +886,12 @@ skip_single_quoted (string, slen, sind)
/* Just like string_extract, but doesn't hack backslashes or any of
that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
static char *
string_extract_verbatim (string, slen, sindex, charlist)
string_extract_verbatim (string, slen, sindex, charlist, flags)
char *string;
size_t slen;
int *sindex;
char *charlist;
int flags;
{
register int i = *sindex;
#if defined (HANDLE_MULTIBYTE)
@@ -1887,7 +1888,13 @@ string_list_dollar_at (list, quoted)
sep[1] = '\0';
#endif
/* XXX -- why call quote_list if ifs == 0? we can get away without doing
it now that quote_escapes quotes spaces */
#if 0
tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
#else
tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
#endif
? quote_list (list)
: list_quote_escapes (list);
@@ -1973,7 +1980,7 @@ list_string (string, separators, quoted)
{
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
unless multibyte chars are possible. */
current_word = string_extract_verbatim (string, slen, &sindex, separators);
current_word = string_extract_verbatim (string, slen, &sindex, separators, 0);
if (current_word == 0)
break;
@@ -2096,7 +2103,7 @@ get_word_from_string (stringp, separators, endptr)
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
unless multibyte chars are possible. */
slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
current_word = string_extract_verbatim (s, slen, &sindex, separators);
current_word = string_extract_verbatim (s, slen, &sindex, separators, 0);
/* Set ENDPTR to the first character after the end of the word. */
if (endptr)
@@ -2922,7 +2929,12 @@ expand_string (string, quoted)
/* Quote escape characters in string s, but no other characters. This is
used to protect CTLESC and CTLNUL in variable values from the rest of
the word expansion process after the variable is expanded. */
the word expansion process after the variable is expanded. If IFS is
null, we quote spaces as well, just in case we split on spaces later
(in the case of unquoted $@, we will eventually attempt to split the
entire word on spaces). Corresponding code exists in dequote_escapes.
Even if we don't end up splitting on spaces, quoting spaces is not a
problem. */
char *
quote_escapes (string)
char *string;
@@ -2930,17 +2942,19 @@ quote_escapes (string)
register char *s, *t;
size_t slen;
char *result, *send;
int quote_spaces;
DECLARE_MBSTATE;
slen = strlen (string);
send = string + slen;
quote_spaces = (ifs_value && *ifs_value == 0);
t = result = (char *)xmalloc ((slen * 2) + 1);
s = string;
while (*s)
{
if (*s == CTLESC || *s == CTLNUL)
if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
*t++ = CTLESC;
COPY_CHAR_P (t, s, send);
}
@@ -2982,6 +2996,7 @@ dequote_escapes (string)
register char *s, *t;
size_t slen;
char *result, *send;
int quote_spaces;
DECLARE_MBSTATE;
if (string == 0)
@@ -2996,9 +3011,10 @@ dequote_escapes (string)
if (strchr (string, CTLESC) == 0)
return (strcpy (result, s));
quote_spaces = (ifs_value && *ifs_value == 0);
while (*s)
{
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
{
s++;
if (*s == '\0')
@@ -4129,12 +4145,18 @@ unlink_fifo_list ()
nfifo = 0;
}
int
fifos_pending ()
{
return nfifo;
}
static char *
make_named_pipe ()
{
char *tname;
tname = sh_mktmpname ("sh-np", MT_USERANDOM);
tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
if (mkfifo (tname, 0600) < 0)
{
free (tname);
@@ -4178,6 +4200,12 @@ add_fifo_list (fd)
nfds++;
}
int
fifos_pending ()
{
return 0; /* used for cleanup; not needed with /dev/fd */
}
void
unlink_fifo_list ()
{
@@ -4423,21 +4451,23 @@ process_substitute (string, open_for_read_in_child)
/***********************************/
static char *
read_comsub (fd, quoted)
read_comsub (fd, quoted, rflag)
int fd, quoted;
int *rflag;
{
char *istring, buf[128], *bufp;
int istring_index, istring_size, c;
int istring_index, istring_size, c, tflag;
ssize_t bufn;
istring = (char *)NULL;
istring_index = istring_size = bufn = 0;
istring_index = istring_size = bufn = tflag = 0;
#ifdef __CYGWIN__
setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
#endif
/* Read the output of the command through the pipe. */
/* Read the output of the command through the pipe. This may need to be
changed to understand multibyte characters in the future. */
while (1)
{
if (fd < 0)
@@ -4462,7 +4492,18 @@ read_comsub (fd, quoted)
/* Add the character to ISTRING, possibly after resizing it. */
RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
/* This is essentially quote_string inline */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
istring[istring_index++] = CTLESC;
/* Escape CTLESC and CTLNUL in the output to protect those characters
from the rest of the word expansions (word splitting and globbing.)
This is essentially quote_escapes inline. */
else if (c == CTLESC)
{
tflag |= W_HASCTLESC;
istring[istring_index++] = CTLESC;
}
else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
istring[istring_index++] = CTLESC;
istring[istring_index++] = c;
@@ -4486,6 +4527,8 @@ read_comsub (fd, quoted)
if (istring_index == 0)
{
FREE (istring);
if (rflag)
*rflag = tflag;
return (char *)NULL;
}
@@ -4510,26 +4553,29 @@ read_comsub (fd, quoted)
else
strip_trailing (istring, istring_index - 1, 1);
if (rflag)
*rflag = tflag;
return istring;
}
/* Perform command substitution on STRING. This returns a string,
possibly quoted. */
char *
/* Perform command substitution on STRING. This returns a WORD_DESC * with the
contained string possibly quoted. */
WORD_DESC *
command_substitute (string, quoted)
char *string;
int quoted;
{
pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
char *istring;
int result, fildes[2], function_value, pflags, rc;
int result, fildes[2], function_value, pflags, rc, tflag;
WORD_DESC *ret;
istring = (char *)NULL;
/* Don't fork () if there is no need to. In the case of no command to
run, just return NULL. */
if (!string || !*string || (string[0] == '\n' && !string[1]))
return ((char *)NULL);
return ((WORD_DESC *)NULL);
if (wordexp_only && read_but_dont_execute)
{
@@ -4569,11 +4615,7 @@ command_substitute (string, quoted)
#endif /* JOB_CONTROL */
old_async_pid = last_asynchronous_pid;
#if 0
pid = make_child ((char *)NULL, 0);
#else
pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
#endif
last_asynchronous_pid = old_async_pid;
if (pid == 0)
@@ -4597,7 +4639,7 @@ command_substitute (string, quoted)
FREE (istring);
close (fildes[0]);
close (fildes[1]);
return ((char *)NULL);
return ((WORD_DESC *)NULL);
}
if (pid == 0)
@@ -4671,6 +4713,9 @@ command_substitute (string, quoted)
last_command_exit_value = rc;
rc = run_exit_trap ();
#if defined (PROCESS_SUBSTITUTION)
unlink_fifo_list ();
#endif
exit (rc);
}
else
@@ -4681,7 +4726,8 @@ command_substitute (string, quoted)
close (fildes[1]);
istring = read_comsub (fildes[0], quoted);
tflag = 0;
istring = read_comsub (fildes[0], quoted, &tflag);
close (fildes[0]);
@@ -4711,7 +4757,11 @@ command_substitute (string, quoted)
give_terminal_to (pipeline_pgrp, 0);
#endif /* JOB_CONTROL */
return (istring);
ret = alloc_word_desc ();
ret->word = istring;
ret->flags = tflag;
return ret;
}
}
@@ -4983,7 +5033,7 @@ parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
/* If the entire expression is between double quotes, we want to treat
the value as a double-quoted string, with the exception that we strip
embedded unescaped double quotes. */
embedded unescaped double quotes (for sh backwards compatibility). */
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
{
hasdol = 0;
@@ -5810,12 +5860,16 @@ parameter_brace_patsub (varname, value, patsub, quoted)
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
temp = array_patsub (array_cell (v), p, rep, mflags);
#if 0
/* Don't need to do this anymore; array_patsub calls array_quote_escapes
as appropriate before adding the space separators. */
if (temp && (mflags & MATCH_QUOTED) == 0)
{
tt = quote_escapes (temp);
free (temp);
temp = tt;
}
#endif
break;
#endif
}
@@ -6578,7 +6632,11 @@ comsub:
/* we need zindex+1 because string[zindex] == RPAREN */
temp1 = substring (string, *sindex, zindex+1);
else
temp1 = command_substitute (temp, quoted);
{
tdesc = command_substitute (temp, quoted);
temp1 = tdesc ? tdesc->word : (char *)NULL;
dispose_word_desc (tdesc);
}
FREE (temp);
temp = temp1;
break;
@@ -6986,7 +7044,9 @@ add_string:
else
{
de_backslash (temp);
temp1 = command_substitute (temp, quoted);
tword = command_substitute (temp, quoted);
temp1 = tword ? tword->word : (char *)NULL;
dispose_word_desc (tword);
}
FREE (temp);
temp = temp1;
@@ -7512,11 +7572,7 @@ setifs (v)
unsigned char uc;
ifs_var = v;
#if 0
ifs_value = v ? value_cell (v) : " \t\n";
#else
ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
#endif
/* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
handle multibyte chars in IFS */
+2 -1
View File
@@ -219,9 +219,10 @@ extern WORD_LIST *expand_words_no_vars __P((WORD_LIST *));
command substitution, arithmetic expansion, and word splitting. */
extern WORD_LIST *expand_words_shellexp __P((WORD_LIST *));
extern char *command_substitute __P((char *, int));
extern WORD_DESC *command_substitute __P((char *, int));
extern char *pat_subst __P((char *, char *, char *, int));
extern int fifos_pending __P((void));
extern void unlink_fifo_list __P((void));
extern WORD_LIST *list_string_with_quotes __P((char *));
+1 -1
View File
@@ -3564,7 +3564,7 @@ INPUT_LINE: while ($_ = &next_line) {
$name = &normalise_node($name);
$level = $sec2level{$tag};
# check for index
$first_index_chapter = $name
$first_index_chapter = $node
if ($level == 1 && !$first_index_chapter &&
$name =~ /index/i);
if ($in_top && /heading/){
+5439
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -26,7 +26,7 @@
#if defined (qnx)
# if defined (qnx6)
# include <sy/netmgr.h>
# include <sys/netmgr.h>
# else
# include <sys/vc.h>
# endif /* !qnx6 */
@@ -515,6 +515,7 @@ initialize_shell_variables (env, privmode)
{
sv_history_control ("HISTCONTROL");
sv_histignore ("HISTIGNORE");
sv_histtimefmt ("HISTTIMEFORMAT");
}
#endif /* HISTORY */
+22 -1
View File
@@ -26,7 +26,7 @@
#if defined (qnx)
# if defined (qnx6)
# include <sy/netmgr.h>
# include <sys/netmgr.h>
# else
# include <sys/vc.h>
# endif /* !qnx6 */
@@ -192,6 +192,8 @@ static SHELL_VAR *get_lineno __P((SHELL_VAR *));
static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t));
static SHELL_VAR *get_subshell __P((SHELL_VAR *));
static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
#if defined (HISTORY)
static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
#endif
@@ -1271,6 +1273,22 @@ get_subshell (var)
return (var);
}
static SHELL_VAR *
get_bashpid (var)
SHELL_VAR *var;
{
int pid;
char *p;
pid = getpid ();
p = itos (pid);
FREE (value_cell (var));
VSETATTR (var, att_integer|att_readonly);
var_setvalue (var, p);
return (var);
}
static SHELL_VAR *
get_bash_command (var)
SHELL_VAR *var;
@@ -1452,6 +1470,9 @@ initialize_dynamic_variables ()
INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
VSETATTR (v, att_integer);
INIT_DYNAMIC_VAR ("BASHPID", (char *)NULL, get_bashpid, null_assign);
VSETATTR (v, att_integer|att_readonly);
#if defined (HISTORY)
INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (sh_var_assign_func_t *)NULL);
VSETATTR (v, att_integer);