fix to make += work with dynamic integer vars like RANDOM

This commit is contained in:
Chet Ramey
2021-12-13 09:37:23 -05:00
parent e93bed95a8
commit 567c0bc2ed
12 changed files with 190 additions and 192 deletions
+18
View File
@@ -2622,3 +2622,21 @@ lib/readline/colors.c
- _rl_custom_readline_prefix: use STREQN to check for the extension
string in $LS_COLORS, since it's not necessarily null-terminated.
From https://savannah.gnu.org/patch/?10158
12/10
-----
variables.c
- set_int_value,set_string_value: broke common code for setting int
and string dynamic variable values out into separate functions;
changed all callers to use them where appropriate. set_int_value
takes a flags argument saying whether or not to force the integer
attribute on
- assign_random: store the value assigned as the variable value so
things like RANDOM=42; RANDOM+=7 generate consistent sequences
like in ksh93
- assign_seconds: store the value assigned as the variable value so
things like SECONDS=42 ; SECONDS+=7 generate what's expected
doc/Makefile.in
- changes to allow man pages that include others (.so FN) to be built
outside the source tree
+4 -4
View File
@@ -107,11 +107,11 @@ BASHREF_FILES = $(srcdir)/bashref.texi $(srcdir)/fdl.texi $(srcdir)/version.texi
.1.ps:
$(RM) $@
-${GROFF} -man $< > $@
-${GROFF} -I${srcdir} -man $< > $@
.1.0:
$(RM) $@
-${NROFF} -man $< > $@
-${NROFF} -I${srcdir} -man $< > $@
.1.html:
$(RM) $@
@@ -127,11 +127,11 @@ BASHREF_FILES = $(srcdir)/bashref.texi $(srcdir)/fdl.texi $(srcdir)/version.texi
.3.ps:
$(RM) $@
-${GROFF} -man $< > $@
-${GROFF} -I${srcdir} -man $< > $@
.3.0:
$(RM) $@
-${NROFF} -man $< > $@
-${NROFF} -I${srcdir} -man $< > $@
.3.html:
$(RM) $@
+3 -3
View File
@@ -1078,12 +1078,12 @@ PPAARRAAMMEETTEERRSS
RREEPPLLYY Set to the line of input read by the rreeaadd builtin command when
no arguments are supplied.
SSEECCOONNDDSS
Each time this parameter is referenced, the number of seconds
since shell invocation is returned. If a value is assigned to
Each time this parameter is referenced, it expands to the number
of seconds since shell invocation. If a value is assigned to
SSEECCOONNDDSS, the value returned upon subsequent references is the
number of seconds since the assignment plus the value assigned.
The number of seconds at shell invocation and the current time
is always determined by querying the system clock. If SSEECCOONNDDSS
are always determined by querying the system clock. If SSEECCOONNDDSS
is unset, it loses its special properties, even if it is subse-
quently reset.
SSHHEELLLLOOPPTTSS
+3 -3
View File
@@ -2014,14 +2014,14 @@ builtin command when no arguments are supplied.
.TP
.B SECONDS
Each time this parameter is
referenced, the number of seconds since shell invocation is returned. If a
value is assigned to
referenced, it expands to the number of seconds since shell invocation.
If a value is assigned to
.SM
.BR SECONDS ,
the value returned upon subsequent
references is
the number of seconds since the assignment plus the value assigned.
The number of seconds at shell invocation and the current time is always
The number of seconds at shell invocation and the current time are always
determined by querying the system clock.
If
.SM
+72 -72
View File
@@ -5754,7 +5754,7 @@ Variables::).
started. Assignment to this variable resets the count to the value
assigned, and the expanded value becomes the value assigned plus
the number of seconds since the assignment. The number of seconds
at shell invocation and the current time is always determined by
at shell invocation and the current time are always determined by
querying the system clock. If 'SECONDS' is unset, it loses its
special properties, even if it is subsequently reset.
@@ -12476,77 +12476,77 @@ Node: Special Builtins216717
Node: Shell Variables217696
Node: Bourne Shell Variables218133
Node: Bash Variables220237
Node: Bash Features253052
Node: Invoking Bash254065
Node: Bash Startup Files260078
Node: Interactive Shells265181
Node: What is an Interactive Shell?265591
Node: Is this Shell Interactive?266240
Node: Interactive Shell Behavior267055
Node: Bash Conditional Expressions270684
Node: Shell Arithmetic275326
Node: Aliases278270
Node: Arrays280883
Node: The Directory Stack287130
Node: Directory Stack Builtins287914
Node: Controlling the Prompt292174
Node: The Restricted Shell295139
Node: Bash POSIX Mode297749
Node: Shell Compatibility Mode309022
Node: Job Control317051
Node: Job Control Basics317511
Node: Job Control Builtins322513
Node: Job Control Variables327913
Node: Command Line Editing329069
Node: Introduction and Notation330740
Node: Readline Interaction332363
Node: Readline Bare Essentials333554
Node: Readline Movement Commands335337
Node: Readline Killing Commands336297
Node: Readline Arguments338215
Node: Searching339259
Node: Readline Init File341445
Node: Readline Init File Syntax342706
Node: Conditional Init Constructs364194
Node: Sample Init File368390
Node: Bindable Readline Commands371514
Node: Commands For Moving372718
Node: Commands For History374769
Node: Commands For Text379763
Node: Commands For Killing383412
Node: Numeric Arguments386445
Node: Commands For Completion387584
Node: Keyboard Macros391775
Node: Miscellaneous Commands392462
Node: Readline vi Mode398401
Node: Programmable Completion399308
Node: Programmable Completion Builtins407088
Node: A Programmable Completion Example417783
Node: Using History Interactively423030
Node: Bash History Facilities423714
Node: Bash History Builtins426719
Node: History Interaction431727
Node: Event Designators435347
Node: Word Designators436701
Node: Modifiers438461
Node: Installing Bash440272
Node: Basic Installation441409
Node: Compilers and Options445131
Node: Compiling For Multiple Architectures445872
Node: Installation Names447565
Node: Specifying the System Type449674
Node: Sharing Defaults450390
Node: Operation Controls451063
Node: Optional Features452021
Node: Reporting Bugs463239
Node: Major Differences From The Bourne Shell464514
Node: GNU Free Documentation License481364
Node: Indexes506541
Node: Builtin Index506995
Node: Reserved Word Index513822
Node: Variable Index516270
Node: Function Index532762
Node: Concept Index546546
Node: Bash Features253053
Node: Invoking Bash254066
Node: Bash Startup Files260079
Node: Interactive Shells265182
Node: What is an Interactive Shell?265592
Node: Is this Shell Interactive?266241
Node: Interactive Shell Behavior267056
Node: Bash Conditional Expressions270685
Node: Shell Arithmetic275327
Node: Aliases278271
Node: Arrays280884
Node: The Directory Stack287131
Node: Directory Stack Builtins287915
Node: Controlling the Prompt292175
Node: The Restricted Shell295140
Node: Bash POSIX Mode297750
Node: Shell Compatibility Mode309023
Node: Job Control317052
Node: Job Control Basics317512
Node: Job Control Builtins322514
Node: Job Control Variables327914
Node: Command Line Editing329070
Node: Introduction and Notation330741
Node: Readline Interaction332364
Node: Readline Bare Essentials333555
Node: Readline Movement Commands335338
Node: Readline Killing Commands336298
Node: Readline Arguments338216
Node: Searching339260
Node: Readline Init File341446
Node: Readline Init File Syntax342707
Node: Conditional Init Constructs364195
Node: Sample Init File368391
Node: Bindable Readline Commands371515
Node: Commands For Moving372719
Node: Commands For History374770
Node: Commands For Text379764
Node: Commands For Killing383413
Node: Numeric Arguments386446
Node: Commands For Completion387585
Node: Keyboard Macros391776
Node: Miscellaneous Commands392463
Node: Readline vi Mode398402
Node: Programmable Completion399309
Node: Programmable Completion Builtins407089
Node: A Programmable Completion Example417784
Node: Using History Interactively423031
Node: Bash History Facilities423715
Node: Bash History Builtins426720
Node: History Interaction431728
Node: Event Designators435348
Node: Word Designators436702
Node: Modifiers438462
Node: Installing Bash440273
Node: Basic Installation441410
Node: Compilers and Options445132
Node: Compiling For Multiple Architectures445873
Node: Installation Names447566
Node: Specifying the System Type449675
Node: Sharing Defaults450391
Node: Operation Controls451064
Node: Optional Features452022
Node: Reporting Bugs463240
Node: Major Differences From The Bourne Shell464515
Node: GNU Free Documentation License481365
Node: Indexes506542
Node: Builtin Index506996
Node: Reserved Word Index513823
Node: Variable Index516271
Node: Function Index532763
Node: Concept Index546547

End Tag Table
+4 -5
View File
@@ -6662,12 +6662,11 @@ with @samp{bind -x} (@pxref{Bash Builtins}).
The default variable for the @code{read} builtin.
@item SECONDS
This variable expands to the number of seconds since the
shell was started. Assignment to this variable resets
the count to the value assigned, and the expanded value
becomes the value assigned plus the number of seconds
This variable expands to the number of seconds since the shell was started.
Assignment to this variable resets the count to the value assigned, and the
expanded value becomes the value assigned plus the number of seconds
since the assignment.
The number of seconds at shell invocation and the current time is always
The number of seconds at shell invocation and the current time are always
determined by querying the system clock.
If @env{SECONDS}
is unset, it loses its special properties,
+1 -1
View File
@@ -2071,4 +2071,4 @@ SSEEEE AALLSSOO
GNU Bash 5.1 2021 September 30 BASH_BUILTINS(1)
GNU Bash 5.2 2021 November 22 BASH_BUILTINS(1)
+1 -1
View File
@@ -7,7 +7,7 @@
.de FN
\fI\|\\$1\|\fP
..
.TH BASH_BUILTINS 1 "2021 September 30" "GNU Bash 5.1"
.TH BASH_BUILTINS 1 "2021 November 22" "GNU Bash 5.2"
.SH NAME
:, ., [, alias, bg, bind, break, builtin, caller,
cd, command, compgen, complete, compopt,
+1 -1
View File
@@ -61,4 +61,4 @@ SSEEEE AALLSSOO
GNU Bash-4.0 2004 Apr 20 RBASH(1)
Bash-5.2 2021 November 22 RBASH(1)
+1 -1
View File
@@ -1,4 +1,4 @@
.TH RBASH 1 "2004 Apr 20" "GNU Bash-4.0"
.TH RBASH 1 "2021 November 22" "Bash-5.2"
.SH NAME
rbash \- restricted bash, see \fBbash\fR(1)
.SH RESTRICTED SHELL
+30 -15
View File
@@ -7,6 +7,7 @@
* variable NAME
* -c check whether or not each resolved path exists
* -s no output, exit status determines whether path is valid
* -S strip . and .. from the pathname only, no symlink resolution
* -v produce verbose output
*
*
@@ -63,11 +64,10 @@ extern int errno;
extern char *sh_realpath();
int
realpath_builtin(list)
WORD_LIST *list;
realpath_builtin(WORD_LIST *list)
{
int opt, cflag, vflag, sflag, aflag, es;
char *r, realbuf[PATH_MAX], *p;
int opt, cflag, vflag, sflag, Sflag, aflag, es;
char *r, realbuf[PATH_MAX], *p, *newpath;
struct stat sb;
#if defined (ARRAY_VARS)
arrayind_t ind;
@@ -80,14 +80,14 @@ WORD_LIST *list;
return (EX_USAGE);
}
vflag = cflag = sflag = aflag = 0;
vflag = cflag = sflag = aflag = Sflag = 0;
#if defined (ARRAY_VARS)
aname = NULL;
v = NULL;
ind = 0;
#endif
reset_internal_getopt();
while ((opt = internal_getopt (list, "a:csv")) != -1) {
while ((opt = internal_getopt (list, "a:Scsv")) != -1) {
switch (opt) {
#if defined (ARRAY_VARS)
case 'a':
@@ -101,6 +101,9 @@ WORD_LIST *list;
case 's':
sflag = 1;
break;
case 'S':
Sflag = 1;
break;
case 'v':
vflag = 1;
break;
@@ -143,14 +146,20 @@ WORD_LIST *list;
for (es = EXECUTION_SUCCESS; list; list = list->next) {
p = list->word->word;
r = sh_realpath(p, realbuf);
if (Sflag) {
/* sh_canonpath doesn't convert to absolute pathnames */
newpath = make_absolute(p, get_string_value("PWD"));
r = sh_canonpath(newpath, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
free(newpath);
} else
r = sh_realpath(p, realbuf);
if (r == 0) {
es = EXECUTION_FAILURE;
if (sflag == 0)
builtin_error("%s: cannot resolve: %s", p, strerror(errno));
continue;
}
if (cflag && (stat(realbuf, &sb) < 0)) {
if (cflag && (stat(r, &sb) < 0)) {
es = EXECUTION_FAILURE;
if (sflag == 0)
builtin_error("%s: %s", p, strerror(errno));
@@ -158,14 +167,16 @@ WORD_LIST *list;
}
if (sflag == 0) {
if (aflag) {
bind_array_element (v, ind, realbuf, 0);
bind_array_element (v, ind, r, 0);
ind++;
} else {
if (vflag)
printf ("%s -> ", p);
printf("%s\n", realbuf);
printf("%s\n", r);
}
}
if (Sflag)
free (r);
}
return es;
}
@@ -174,10 +185,14 @@ char *realpath_doc[] = {
"Display pathname in canonical form.",
"",
"Display the canonicalized version of each PATHNAME argument, resolving",
"symbolic links. The -c option checks whether or not each resolved name",
"exists. The -s option produces no output; the exit status determines the",
"validity of each PATHNAME. The -v option produces verbose output. The",
"exit status is 0 if each PATHNAME was resolved; non-zero otherwise.",
"symbolic links.",
"If the -S option is supplied, canonicalize . and .. pathname components",
"without resolving symbolic links.",
"The -c option checks whether or not each resolved name exists.",
"The -s option produces no output; the exit status determines the",
"validity of each PATHNAME.",
"The -v option produces verbose output.",
"The exit status is 0 if each PATHNAME was resolved; non-zero otherwise.",
(char *)NULL
};
@@ -186,6 +201,6 @@ struct builtin realpath_struct = {
realpath_builtin, /* function implementing the builtin */
BUILTIN_ENABLED, /* initial flags for builtin */
realpath_doc, /* array of long documentation strings */
"realpath [-csv] pathname [pathname...]", /* usage synopsis */
"realpath [-Scsv] pathname [pathname...]", /* usage synopsis */
0 /* reserved for internal use */
};
+52 -86
View File
@@ -199,6 +199,9 @@ static SHELL_VAR *init_dynamic_array_var PARAMS((char *, sh_var_value_func_t *,
static SHELL_VAR *init_dynamic_assoc_var PARAMS((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
#endif
static inline SHELL_VAR *set_int_value (SHELL_VAR *, intmax_t, int);
static inline SHELL_VAR *set_string_value (SHELL_VAR *, const char *, int);
static SHELL_VAR *assign_seconds PARAMS((SHELL_VAR *, char *, arrayind_t, char *));
static SHELL_VAR *get_seconds PARAMS((SHELL_VAR *));
static SHELL_VAR *init_seconds_var PARAMS((void));
@@ -1275,6 +1278,39 @@ init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
}
#endif
/* Set the string value of VAR to the string representation of VALUE.
Right now this takes an INTMAX_T because that's what itos needs. If
FLAGS&1, we force the integer attribute on. */
static inline SHELL_VAR *
set_int_value (SHELL_VAR *var, intmax_t value, int flags)
{
char *p;
p = itos (value);
FREE (value_cell (var));
var_setvalue (var, p);
if (flags & 1)
VSETATTR (var, att_integer);
return (var);
}
static inline SHELL_VAR *
set_string_value (SHELL_VAR *var, const char *value, int flags)
{
char *p;
if (value && *value)
p = savestring (value);
else
{
p = (char *)xmalloc (1);
p[0] = '\0';
}
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
}
/* The value of $SECONDS. This is the number of seconds since shell
invocation, or, the number of seconds since the last assignment + the
value of the last assignment. */
@@ -1297,7 +1333,7 @@ assign_seconds (self, value, unused, key)
seconds_value_assigned = expok ? nval : 0;
gettimeofday (&shellstart, NULL);
shell_start_time = shellstart.tv_sec;
return (self);
return (set_int_value (self, nval, integer_p (self) != 0));
}
static SHELL_VAR *
@@ -1305,18 +1341,11 @@ get_seconds (var)
SHELL_VAR *var;
{
time_t time_since_start;
char *p;
struct timeval tv;
gettimeofday(&tv, NULL);
time_since_start = tv.tv_sec - shell_start_time;
p = itos(seconds_value_assigned + time_since_start);
FREE (value_cell (var));
VSETATTR (var, att_integer);
var_setvalue (var, p);
return (var);
return (set_int_value (var, seconds_value_assigned + time_since_start, 1));
}
static SHELL_VAR *
@@ -1358,7 +1387,7 @@ assign_random (self, value, unused, key)
sbrand (seedval);
if (subshell_environment)
seeded_subshell = getpid ();
return (self);
return (set_int_value (self, seedval, integer_p (self) != 0));
}
int
@@ -1386,16 +1415,9 @@ get_random (var)
SHELL_VAR *var;
{
int rv;
char *p;
rv = get_random_number ();
p = itos (rv);
FREE (value_cell (var));
VSETATTR (var, att_integer);
var_setvalue (var, p);
return (var);
return (set_int_value (var, rv, 1));
}
static SHELL_VAR *
@@ -1403,16 +1425,9 @@ get_urandom (var)
SHELL_VAR *var;
{
u_bits32_t rv;
char *p;
rv = get_urandom32 ();
p = itos (rv);
FREE (value_cell (var));
VSETATTR (var, att_integer);
var_setvalue (var, p);
return (var);
return (set_int_value (var, rv, 1));
}
static SHELL_VAR *
@@ -1435,14 +1450,10 @@ static SHELL_VAR *
get_lineno (var)
SHELL_VAR *var;
{
char *p;
int ln;
ln = executing_line_number ();
p = itos (ln);
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
return (set_int_value (var, ln, 0));
}
static SHELL_VAR *
@@ -1464,12 +1475,7 @@ static SHELL_VAR *
get_subshell (var)
SHELL_VAR *var;
{
char *p;
p = itos (subshell_level);
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
return (set_int_value (var, subshell_level, 0));
}
static SHELL_VAR *
@@ -1477,14 +1483,9 @@ get_epochseconds (var)
SHELL_VAR *var;
{
intmax_t now;
char *p;
now = NOW;
p = itos (now);
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
return (set_int_value (var, now, 0));
}
static SHELL_VAR *
@@ -1492,7 +1493,6 @@ get_epochrealtime (var)
SHELL_VAR *var;
{
char buf[32];
char *p;
struct timeval tv;
gettimeofday (&tv, NULL);
@@ -1500,10 +1500,7 @@ get_epochrealtime (var)
locale_decpoint (),
(unsigned)tv.tv_usec);
p = savestring (buf);
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
return (set_string_value (var, buf, 0));
}
static SHELL_VAR *
@@ -1511,27 +1508,16 @@ get_bashpid (var)
SHELL_VAR *var;
{
int pid;
char *p;
pid = getpid ();
p = itos (pid);
FREE (value_cell (var));
VSETATTR (var, att_integer); /* XXX - was also att_readonly */
var_setvalue (var, p);
return (var);
return (set_int_value (var, pid, 1));
}
static SHELL_VAR *
get_bash_argv0 (var)
SHELL_VAR *var;
{
char *p;
p = savestring (dollar_vars[0]);
FREE (value_cell (var));
var_setvalue (var, p);
return var;
return (set_string_value (var, dollar_vars[0], 0));
}
static char *static_shell_name = 0;
@@ -1576,16 +1562,8 @@ get_bash_command (var)
{
char *p;
if (the_printed_command_except_trap)
p = savestring (the_printed_command_except_trap);
else
{
p = (char *)xmalloc (1);
p[0] = '\0';
}
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
p = the_printed_command_except_trap ? the_printed_command_except_trap : "";
return (set_string_value (var, p, 0));
}
#if defined (HISTORY)
@@ -1593,7 +1571,6 @@ static SHELL_VAR *
get_histcmd (var)
SHELL_VAR *var;
{
char *p;
int n;
/* Do the same adjustment here we do in parse.y:prompt_history_number,
@@ -1604,10 +1581,7 @@ get_histcmd (var)
already been saved to history and the history number incremented.
Right now we use EXECUTING as the determinant. */
n = history_number () - executing;
p = itos (n);
FREE (value_cell (var));
var_setvalue (var, p);
return (var);
return (set_int_value (var, n, 0));
}
#endif
@@ -1621,10 +1595,7 @@ get_comp_wordbreaks (var)
if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
enable_hostname_completion (perform_hostname_completion);
FREE (value_cell (var));
var_setvalue (var, savestring (rl_completer_word_break_characters));
return (var);
return (set_string_value (var, rl_completer_word_break_characters, 0));
}
/* When this function returns, rl_completer_word_break_characters points to
@@ -1860,13 +1831,8 @@ get_funcname (self)
SHELL_VAR *self;
{
#if ! defined (ARRAY_VARS)
char *t;
if (variable_context && this_shell_function)
{
FREE (value_cell (self));
t = savestring (this_shell_function->name);
var_setvalue (self, t);
}
return (set_string_value (self, this_shell_function->name, 0));
#endif
return (self);
}