bash-20140425 remove leftover and stray files

This commit is contained in:
Chet Ramey
2014-04-30 16:54:25 -04:00
parent b4a17eba68
commit e38100f49d
26 changed files with 0 additions and 34751 deletions
-6183
View File
File diff suppressed because it is too large Load Diff
-82
View File
@@ -1,82 +0,0 @@
Starting bash with the `--posix' command-line option or executing
`set -o posix' while bash is running will cause bash to conform more
closely to the Posix.2 standard by changing the behavior to match that
specified by Posix.2 in areas where the bash default differs.
The following list is what's changed when `posix mode' is in effect:
1. When a command in the hash table no longer exists, bash will re-search
$PATH to find the new location. This is also available with
`shopt -s checkhash'.
2. The >& redirection does not redirect stdout and stderr.
3. The message printed by the job control code and builtins when a job
exits with a non-zero status is `Done(status)'.
4. Reserved words may not be aliased.
5. The Posix.2 PS1 and PS2 expansions of `!' -> history number and
`!!' -> `!' are enabled, and parameter expansion is performed on
the value regardless of the setting of the `promptvars' option.
6. Interactive comments are enabled by default. (Note that bash has
them on by default anyway.)
7. The Posix.2 startup files are executed ($ENV) rather than the normal
bash files.
8. Tilde expansion is only performed on assignments preceding a command
name, rather than on all assignment statements on the line.
9. The default history file is ~/.sh_history (default value of $HISTFILE).
10. The output of `kill -l' prints all the signal names on a single line,
separated by spaces.
11. Non-interactive shells exit if `file' in `. file' is not found.
12. Redirection operators do not perform pathname expansion on the word
in the redirection unless the shell is interactive
13. Function names must be valid shell identifiers. That is, they may not
contain characters other than letters, digits, and underscores, and
may not start with a digit. Declaring a function with an illegal name
causes a fatal syntax error in non-interactive shells.
14. Posix.2 `special' builtins are found before shell functions during command
lookup.
15. If a Posix.2 special builtin returns an error status, a non-interactive
shell exits. The fatal errors are those listed in the POSIX.2 standard,
and include things like passing incorrect options, redirection errors,
variable assignment errors for assignments preceding the command name,
and so on.
16. The environment passed to executed commands is not sorted. Neither is
the output of `set'. This is not strictly Posix.2 behavior, but sh
does it this way. Ksh does not. It's not necessary to sort the
environment; no program should rely on it being sorted.
17. If the `cd' builtin finds a directory to change to using $CDPATH, the
value it assigns to $PWD does not contain any symbolic links, as if
`cd -P' had been executed.
18. A non-interactive shell exits with an error status if a variable
assignment error occurs when no command name follows the assignment
statements. A variable assignment error occurs, for example, when
trying to assign a value to a read-only variable.
19. A non-interactive shell exits with an error status if the iteration
variable in a for statement or the selection variable in a select
statement is a read-only variable.
20. Process substitution is not available.
21. Assignment statements preceding POSIX.2 `special' builtins persist in
the shell environment after the builtin completes.
There is other Posix.2 behavior that bash does not implement. Specifically:
1. Assignment statements affect the execution environment of all builtins,
not just special ones.
-544
View File
@@ -1,544 +0,0 @@
This file is set.def, from which is created set.c.
It implements the "set" and "unset" builtins in Bash.
Copyright (C) 1987, 1989, 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES set.c
#include <stdio.h>
#include "../shell.h"
#include "../flags.h"
#include "bashgetopt.h"
extern int interactive;
extern int noclobber, posixly_correct;
#if defined (READLINE)
extern int rl_editing_mode, no_line_editing;
#endif /* READLINE */
$BUILTIN set
$FUNCTION set_builtin
$SHORT_DOC set [--abefhkmnptuvxldBCHP] [-o option] [arg ...]
-a Mark variables which are modified or created for export.
-b Notify of job termination immediately.
-e Exit immediately if a command exits with a non-zero status.
-f Disable file name generation (globbing).
-h Locate and remember function commands as functions are
defined. Function commands are normally looked up when
the function is executed.
-i Force the shell to be an "interactive" one. Interactive shells
always read `~/.bashrc' on startup.
-k All keyword arguments are placed in the environment for a
command, not just those that precede the command name.
-m Job control is enabled.
-n Read commands but do not execute them.
-o option-name
Set the variable corresponding to option-name:
allexport same as -a
braceexpand same as -B
#if defined (READLINE)
emacs use an emacs-style line editing interface
#endif /* READLINE */
errexit same as -e
histexpand same as -H
ignoreeof the shell will not exit upon reading EOF
interactive-comments
allow comments to appear in interactive commands
monitor same as -m
noclobber disallow redirection to existing files
noexec same as -n
noglob same as -f
nohash same as -d
notify save as -b
nounset same as -u
physical same as -P
posix change the behavior of bash where the default
operation differs from the 1003.2 standard to
match the standard
privileged same as -p
verbose same as -v
#if defined (READLINE)
vi use a vi-style line editing interface
#endif /* READLINE */
xtrace same as -x
-p Turned on whenever the real and effective user ids do not match.
Disables processing of the $ENV file and importing of shell
functions. Turning this option off causes the effective uid and
gid to be set to the real uid and gid.
-t Exit after reading and executing one command.
-u Treat unset variables as an error when substituting.
-v Print shell input lines as they are read.
-x Print commands and their arguments as they are executed.
-l Save and restore the binding of the NAME in a FOR command.
-d Disable the hashing of commands that are looked up for execution.
Normally, commands are remembered in a hash table, and once
found, do not have to be looked up again.
#if defined (BRACE_EXPANSION)
-B the shell will perform brace expansion
#endif /* BRACE_EXPANSION */
#if defined (BANG_HISTORY)
-H Enable ! style history substitution. This flag is on
by default.
#endif /* BANG_HISTORY */
-C If set, disallow existing regular files to be overwritten
by redirection of output.
-P If set, do not follow symbolic links when executing commands
such as cd which change the current directory.
Using + rather than - causes these flags to be turned off. The
flags can also be used upon invocation of the shell. The current
set of flags may be found in $-. The remaining n ARGs are positional
parameters and are assigned, in order, to $1, $2, .. $n. If no
ARGs are given, all shell variables are printed.
$END
/* An a-list used to match long options for set -o to the corresponding
option letter. */
struct {
char *name;
int letter;
} o_options[] = {
{ "allexport", 'a' },
#if defined (BRACE_EXPANSION)
{ "braceexpand",'B' },
#endif
{ "errexit", 'e' },
{ "histexpand", 'H' },
{ "monitor", 'm' },
{ "noexec", 'n' },
{ "noglob", 'f' },
{ "nohash", 'd' },
#if defined (JOB_CONTROL)
{ "notify", 'b' },
#endif /* JOB_CONTROL */
{"nounset", 'u' },
{"physical", 'P' },
{"privileged", 'p' },
{"verbose", 'v' },
{"xtrace", 'x' },
{(char *)NULL, 0},
};
#define MINUS_O_FORMAT "%-15s\t%s\n"
void
list_minus_o_opts ()
{
register int i;
char *on = "on", *off = "off";
printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
printf (MINUS_O_FORMAT, "ignoreeof", on);
else
printf (MINUS_O_FORMAT, "ignoreeof", off);
printf (MINUS_O_FORMAT, "interactive-comments",
interactive_comments ? on : off);
printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
#if defined (READLINE)
if (no_line_editing)
{
printf (MINUS_O_FORMAT, "emacs", off);
printf (MINUS_O_FORMAT, "vi", off);
}
else
{
/* Magic. This code `knows' how readline handles rl_editing_mode. */
printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
}
#endif /* READLINE */
for (i = 0; o_options[i].name; i++)
{
int *on_or_off, zero = 0;
on_or_off = find_flag (o_options[i].letter);
if (on_or_off == FLAG_UNKNOWN)
on_or_off = &zero;
printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
}
}
set_minus_o_option (on_or_off, option_name)
int on_or_off;
char *option_name;
{
int option_char = -1;
if (STREQ (option_name, "noclobber"))
{
if (on_or_off == FLAG_ON)
bind_variable ("noclobber", "");
else
unbind_variable ("noclobber");
stupidly_hack_special_variables ("noclobber");
}
else if (STREQ (option_name, "ignoreeof"))
{
unbind_variable ("ignoreeof");
unbind_variable ("IGNOREEOF");
if (on_or_off == FLAG_ON)
bind_variable ("IGNOREEOF", "10");
stupidly_hack_special_variables ("IGNOREEOF");
}
#if defined (READLINE)
else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
{
if (on_or_off == FLAG_ON)
{
rl_variable_bind ("editing-mode", option_name);
if (interactive)
with_input_from_stdin ();
no_line_editing = 0;
}
else
{
int isemacs = (rl_editing_mode == 1);
if ((isemacs && STREQ (option_name, "emacs")) ||
(!isemacs && STREQ (option_name, "vi")))
{
if (interactive)
with_input_from_stream (stdin, "stdin");
no_line_editing = 1;
}
else
builtin_error ("not in %s editing mode", option_name);
}
}
#endif /* READLINE */
else if (STREQ (option_name, "interactive-comments"))
interactive_comments = (on_or_off == FLAG_ON);
else if (STREQ (option_name, "posix"))
{
posixly_correct = (on_or_off == FLAG_ON);
unbind_variable ("POSIXLY_CORRECT");
unbind_variable ("POSIX_PEDANTIC");
if (on_or_off == FLAG_ON)
{
bind_variable ("POSIXLY_CORRECT", "");
stupidly_hack_special_variables ("POSIXLY_CORRECT");
}
}
else
{
register int i;
for (i = 0; o_options[i].name; i++)
{
if (STREQ (option_name, o_options[i].name))
{
option_char = o_options[i].letter;
break;
}
}
if (option_char == -1)
{
builtin_error ("%s: unknown option name", option_name);
return (EXECUTION_FAILURE);
}
if (change_flag (option_char, on_or_off) == FLAG_ERROR)
{
bad_option (option_name);
return (EXECUTION_FAILURE);
}
}
return (EXECUTION_SUCCESS);
}
/* Set some flags from the word values in the input list. If LIST is empty,
then print out the values of the variables instead. If LIST contains
non-flags, then set $1 - $9 to the successive words of LIST. */
set_builtin (list)
WORD_LIST *list;
{
int on_or_off, flag_name, force_assignment = 0;
if (!list)
{
SHELL_VAR **vars;
vars = all_shell_variables ();
if (vars)
{
print_var_list (vars);
free (vars);
}
vars = all_shell_functions ();
if (vars)
{
print_var_list (vars);
free (vars);
}
return (EXECUTION_SUCCESS);
}
/* Check validity of flag arguments. */
if (*list->word->word == '-' || *list->word->word == '+')
{
register char *arg;
WORD_LIST *save_list = list;
while (list && (arg = list->word->word))
{
char c;
if (arg[0] != '-' && arg[0] != '+')
break;
/* `-' or `--' signifies end of flag arguments. */
if (arg[0] == '-' &&
(!arg[1] || (arg[1] == '-' && !arg[2])))
break;
while (c = *++arg)
{
if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
{
char s[2];
s[0] = c; s[1] = '\0';
bad_option (s);
if (c == '?')
builtin_usage ();
return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
}
list = list->next;
}
list = save_list;
}
/* Do the set command. While the list consists of words starting with
'-' or '+' treat them as flags, otherwise, start assigning them to
$1 ... $n. */
while (list)
{
char *string = list->word->word;
/* If the argument is `--' or `-' then signal the end of the list
and remember the remaining arguments. */
if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
{
list = list->next;
/* `set --' unsets the positional parameters. */
if (string[1] == '-')
force_assignment = 1;
/* Until told differently, the old shell behaviour of
`set - [arg ...]' being equivalent to `set +xv [arg ...]'
stands. Posix.2 says the behaviour is marked as obsolescent. */
else
{
change_flag ('x', '+');
change_flag ('v', '+');
}
break;
}
if ((on_or_off = *string) &&
(on_or_off == '-' || on_or_off == '+'))
{
int i = 1;
while (flag_name = string[i++])
{
if (flag_name == '?')
{
builtin_usage ();
return (EXECUTION_SUCCESS);
}
else if (flag_name == 'o') /* -+o option-name */
{
char *option_name;
WORD_LIST *opt;
opt = list->next;
if (!opt)
{
list_minus_o_opts ();
continue;
}
option_name = opt->word->word;
if (!option_name || !*option_name || (*option_name == '-'))
{
list_minus_o_opts ();
continue;
}
list = list->next; /* Skip over option name. */
if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
return (EXECUTION_FAILURE);
}
else
{
if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
{
char opt[3];
opt[0] = on_or_off;
opt[1] = flag_name;
opt[2] = '\0';
bad_option (opt);
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
}
}
else
{
break;
}
list = list->next;
}
/* Assigning $1 ... $n */
if (list || force_assignment)
remember_args (list, 1);
return (EXECUTION_SUCCESS);
}
$BUILTIN unset
$FUNCTION unset_builtin
$SHORT_DOC unset [-f] [-v] [name ...]
For each NAME, remove the corresponding variable or function. Given
the `-v', unset will only act on variables. Given the `-f' flag,
unset will only act on functions. With neither flag, unset first
tries to unset a variable, and if that fails, then tries to unset a
function. Some variables (such as PATH and IFS) cannot be unset; also
see readonly.
$END
#define NEXT_VARIABLE() any_failed++; list = list->next; continue;
unset_builtin (list)
WORD_LIST *list;
{
int unset_function, unset_variable, unset_array, opt, any_failed;
char *name;
unset_function = unset_variable = unset_array = any_failed = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "fv")) != -1)
{
switch (opt)
{
case 'f':
unset_function = 1;
break;
case 'v':
unset_variable = 1;
break;
default:
builtin_usage ();
return (EXECUTION_FAILURE);
}
}
list = loptend;
if (unset_function && unset_variable)
{
builtin_error ("cannot simultaneously unset a function and a variable");
return (EXECUTION_FAILURE);
}
while (list)
{
SHELL_VAR *var;
int tem;
#if defined (ARRAY_VARS)
char *t;
#endif
name = list->word->word;
#if defined (ARRAY_VARS)
if (!unset_function && valid_array_reference (name))
{
t = strchr (name, '[');
*t++ = '\0';
unset_array++;
}
#endif
var = unset_function ? find_function (name) : find_variable (name);
if (var && !unset_function && non_unsettable_p (var))
{
builtin_error ("%s: cannot unset", name);
NEXT_VARIABLE ();
}
/* Posix.2 says that unsetting readonly variables is an error. */
if (var && readonly_p (var))
{
builtin_error ("%s: cannot unset: readonly %s",
name, unset_function ? "function" : "variable");
NEXT_VARIABLE ();
}
/* Unless the -f option is supplied, the name refers to a variable. */
#if defined (ARRAY_VARS)
if (var && unset_array)
{
if (array_p (var) == 0)
{
builtin_error ("%s: not an array variable", name);
NEXT_VARIABLE ();
}
else
tem = unbind_array_element (var, t);
}
else
#endif /* ARRAY_VARS */
tem = makunbound (name, unset_function ? shell_functions : shell_variables);
/* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
is specified, the name refers to a variable; if a variable by
that name does not exist, a function by that name, if any,
shall be unset.'' */
if ((tem == -1) && !unset_function && !unset_variable)
tem = makunbound (name, shell_functions);
if (tem == -1)
any_failed++;
else if (!unset_function)
stupidly_hack_special_variables (name);
list = list->next;
}
if (any_failed)
return (EXECUTION_FAILURE);
else
return (EXECUTION_SUCCESS);
}
-50
View File
@@ -1,50 +0,0 @@
/* unwind_prot.h - Macros and functions for hacking unwind protection. */
/* Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_UNWIND_PROT_H)
#define _UNWIND_PROT_H
/* Run a function without interrupts. */
extern void begin_unwind_frame ();
extern void discard_unwind_frame ();
extern void run_unwind_frame ();
extern void add_unwind_protect ();
extern void remove_unwind_protect ();
extern void run_unwind_protects ();
extern void unwind_protect_var ();
/* Define for people who like their code to look a certain way. */
#define end_unwind_frame()
/* How to protect an integer. */
#define unwind_protect_int(X) unwind_protect_var (&(X), (char *)(X), sizeof (int))
/* How to protect a pointer to a string. */
#define unwind_protect_string(X) \
unwind_protect_var ((int *)&(X), (X), sizeof (char *))
/* How to protect any old pointer. */
#define unwind_protect_pointer(X) unwind_protect_string (X)
/* How to protect the contents of a jmp_buf. */
#define unwind_protect_jmp_buf(X) \
unwind_protect_var ((int *)(X), (char *)(X), sizeof (procenv_t))
#endif /* _UNWIND_PROT_H */
-1289
View File
File diff suppressed because it is too large Load Diff
-923
View File
@@ -1,923 +0,0 @@
/* bashhist.c -- bash interface to the GNU history library. */
/* Copyright (C) 1993-2012 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#if defined (HISTORY)
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include "bashtypes.h"
#include <stdio.h>
#include <errno.h>
#include "bashansi.h"
#include "posixstat.h"
#include "filecntl.h"
#include "bashintl.h"
#if defined (SYSLOG_HISTORY)
# include <syslog.h>
#endif
#include "shell.h"
#include "flags.h"
#include "input.h"
#include "parser.h" /* for the struct dstack stuff. */
#include "pathexp.h" /* for the struct ignorevar stuff */
#include "bashhist.h" /* matching prototypes and declarations */
#include "builtins/common.h"
#include <readline/history.h>
#include <glob/glob.h>
#include <glob/strmatch.h>
#if defined (READLINE)
# include "bashline.h"
extern int rl_done, rl_dispatching; /* should really include readline.h */
#endif
#if !defined (errno)
extern int errno;
#endif
static int histignore_item_func __P((struct ign *));
static int check_history_control __P((char *));
static void hc_erasedups __P((char *));
static void really_add_history __P((char *));
static struct ignorevar histignore =
{
"HISTIGNORE",
(struct ign *)0,
0,
(char *)0,
(sh_iv_item_func_t *)histignore_item_func,
};
#define HIGN_EXPAND 0x01
/* Declarations of bash history variables. */
/* Non-zero means to remember lines typed to the shell on the history
list. This is different than the user-controlled behaviour; this
becomes zero when we read lines from a file, for example. */
int remember_on_history = 1;
int enable_history_list = 1; /* value for `set -o history' */
/* The number of lines that Bash has added to this history session. The
difference between the number of the top element in the history list
(offset from history_base) and the number of lines in the history file.
Appending this session's history to the history file resets this to 0. */
int history_lines_this_session;
/* The number of lines that Bash has read from the history file. */
int history_lines_in_file;
#if defined (BANG_HISTORY)
/* Non-zero means do no history expansion on this line, regardless
of what history_expansion says. */
int history_expansion_inhibited;
#endif
/* With the old default, every line was saved in the history individually.
I.e., if the user enters:
bash$ for i in a b c
> do
> echo $i
> done
Each line will be individually saved in the history.
bash$ history
10 for i in a b c
11 do
12 echo $i
13 done
14 history
If the variable command_oriented_history is set, multiple lines
which form one command will be saved as one history entry.
bash$ for i in a b c
> do
> echo $i
> done
bash$ history
10 for i in a b c
do
echo $i
done
11 history
The user can then recall the whole command all at once instead
of just being able to recall one line at a time.
This is now enabled by default.
*/
int command_oriented_history = 1;
/* Set to 1 if the first line of a possibly-multi-line command was saved
in the history list. Managed by maybe_add_history(), but global so
the history-manipluating builtins can see it. */
int current_command_first_line_saved = 0;
/* Non-zero means to store newlines in the history list when using
command_oriented_history rather than trying to use semicolons. */
int literal_history;
/* Non-zero means to append the history to the history file at shell
exit, even if the history has been stifled. */
int force_append_history;
/* A nit for picking at history saving. Flags have the following values:
Value == 0 means save all lines parsed by the shell on the history.
Value & HC_IGNSPACE means save all lines that do not start with a space.
Value & HC_IGNDUPS means save all lines that do not match the last
line saved.
Value & HC_ERASEDUPS means to remove all other matching lines from the
history list before saving the latest line. */
int history_control;
/* Set to 1 if the last command was added to the history list successfully
as a separate history entry; set to 0 if the line was ignored or added
to a previous entry as part of command-oriented-history processing. */
int hist_last_line_added;
/* Set to 1 if builtins/history.def:push_history added the last history
entry. */
int hist_last_line_pushed;
#if defined (READLINE)
/* If non-zero, and readline is being used, the user is offered the
chance to re-edit a failed history expansion. */
int history_reediting;
/* If non-zero, and readline is being used, don't directly execute a
line with history substitution. Reload it into the editing buffer
instead and let the user further edit and confirm with a newline. */
int hist_verify;
#endif /* READLINE */
/* Non-zero means to not save function definitions in the history list. */
int dont_save_function_defs;
/* Variables declared in other files used here. */
extern int current_command_line_count;
extern struct dstack dstack;
extern int parser_state;
static int bash_history_inhibit_expansion __P((char *, int));
#if defined (READLINE)
static void re_edit __P((char *));
#endif
static int history_expansion_p __P((char *));
static int shell_comment __P((char *));
static int should_expand __P((char *));
static HIST_ENTRY *last_history_entry __P((void));
static char *expand_histignore_pattern __P((char *));
static int history_should_ignore __P((char *));
/* Is the history expansion starting at string[i] one that should not
be expanded? */
static int
bash_history_inhibit_expansion (string, i)
char *string;
int i;
{
/* The shell uses ! as a pattern negation character in globbing [...]
expressions, so let those pass without expansion. */
if (i > 0 && (string[i - 1] == '[') && member (']', string + i + 1))
return (1);
/* The shell uses ! as the indirect expansion character, so let those
expansions pass as well. */
else if (i > 1 && string[i - 1] == '{' && string[i - 2] == '$' &&
member ('}', string + i + 1))
return (1);
/* The shell uses $! as a defined parameter expansion. */
else if (i > 1 && string[i - 1] == '$' && string[i] == '!')
return (1);
#if defined (EXTENDED_GLOB)
else if (extended_glob && i > 1 && string[i+1] == '(' && member (')', string + i + 2))
return (1);
#endif
else
return (0);
}
void
bash_initialize_history ()
{
history_quotes_inhibit_expansion = 1;
history_search_delimiter_chars = ";&()|<>";
history_inhibit_expansion_function = bash_history_inhibit_expansion;
#if defined (BANG_HISTORY)
sv_histchars ("histchars");
#endif
}
void
bash_history_reinit (interact)
int interact;
{
#if defined (BANG_HISTORY)
history_expansion = interact != 0;
history_expansion_inhibited = 1;
#endif
remember_on_history = enable_history_list = interact != 0;
history_inhibit_expansion_function = bash_history_inhibit_expansion;
}
void
bash_history_disable ()
{
remember_on_history = 0;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 1;
#endif
}
void
bash_history_enable ()
{
remember_on_history = 1;
#if defined (BANG_HISTORY)
history_expansion_inhibited = 0;
#endif
history_inhibit_expansion_function = bash_history_inhibit_expansion;
sv_history_control ("HISTCONTROL");
sv_histignore ("HISTIGNORE");
}
/* Load the history list from the history file. */
void
load_history ()
{
char *hf;
/* Truncate history file for interactive shells which desire it.
Note that the history file is automatically truncated to the
size of HISTSIZE if the user does not explicitly set the size
differently. */
set_if_not ("HISTSIZE", "500");
sv_histsize ("HISTSIZE");
set_if_not ("HISTFILESIZE", get_string_value ("HISTSIZE"));
sv_histsize ("HISTFILESIZE");
/* Read the history in HISTFILE into the history list. */
hf = get_string_value ("HISTFILE");
if (hf && *hf && file_exists (hf))
{
read_history (hf);
using_history ();
history_lines_in_file = where_history ();
}
}
void
bash_clear_history ()
{
clear_history ();
history_lines_this_session = 0;
}
/* Delete and free the history list entry at offset I. */
int
bash_delete_histent (i)
int i;
{
HIST_ENTRY *discard;
discard = remove_history (i);
if (discard)
free_history_entry (discard);
history_lines_this_session--;
return 1;
}
int
bash_delete_last_history ()
{
register int i;
HIST_ENTRY **hlist, *histent;
int r;
hlist = history_list ();
if (hlist == NULL)
return 0;
for (i = 0; hlist[i]; i++)
;
i--;
/* History_get () takes a parameter that must be offset by history_base. */
histent = history_get (history_base + i); /* Don't free this */
if (histent == NULL)
return 0;
r = bash_delete_histent (i);
if (where_history () > history_length)
history_set_pos (history_length);
return r;
}
#ifdef INCLUDE_UNUSED
/* Write the existing history out to the history file. */
void
save_history ()
{
char *hf;
int r;
hf = get_string_value ("HISTFILE");
if (hf && *hf && file_exists (hf))
{
/* Append only the lines that occurred this session to
the history file. */
using_history ();
if (history_lines_this_session <= where_history () || force_append_history)
r = append_history (history_lines_this_session, hf);
else
r = write_history (hf);
sv_histsize ("HISTFILESIZE");
}
}
#endif
int
maybe_append_history (filename)
char *filename;
{
int fd, result;
struct stat buf;
result = EXECUTION_SUCCESS;
if (history_lines_this_session && (history_lines_this_session <= where_history ()))
{
/* If the filename was supplied, then create it if necessary. */
if (stat (filename, &buf) == -1 && errno == ENOENT)
{
fd = open (filename, O_WRONLY|O_CREAT, 0600);
if (fd < 0)
{
builtin_error (_("%s: cannot create: %s"), filename, strerror (errno));
return (EXECUTION_FAILURE);
}
close (fd);
}
result = append_history (history_lines_this_session, filename);
history_lines_in_file += history_lines_this_session;
history_lines_this_session = 0;
}
return (result);
}
/* If this is an interactive shell, then append the lines executed
this session to the history file. */
int
maybe_save_shell_history ()
{
int result;
char *hf;
result = 0;
if (history_lines_this_session)
{
hf = get_string_value ("HISTFILE");
if (hf && *hf)
{
/* If the file doesn't exist, then create it. */
if (file_exists (hf) == 0)
{
int file;
file = open (hf, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (file != -1)
close (file);
}
/* Now actually append the lines if the history hasn't been
stifled. If the history has been stifled, rewrite the
history file. */
using_history ();
if (history_lines_this_session <= where_history () || force_append_history)
{
result = append_history (history_lines_this_session, hf);
history_lines_in_file += history_lines_this_session;
}
else
{
result = write_history (hf);
history_lines_in_file = history_lines_this_session;
}
history_lines_this_session = 0;
sv_histsize ("HISTFILESIZE");
}
}
return (result);
}
#if defined (READLINE)
/* Tell readline () that we have some text for it to edit. */
static void
re_edit (text)
char *text;
{
if (bash_input.type == st_stdin)
bash_re_edit (text);
}
#endif /* READLINE */
/* Return 1 if this line needs history expansion. */
static int
history_expansion_p (line)
char *line;
{
register char *s;
for (s = line; *s; s++)
if (*s == history_expansion_char || *s == history_subst_char)
return 1;
return 0;
}
/* Do pre-processing on LINE. If PRINT_CHANGES is non-zero, then
print the results of expanding the line if there were any changes.
If there is an error, return NULL, otherwise the expanded line is
returned. If ADDIT is non-zero the line is added to the history
list after history expansion. ADDIT is just a suggestion;
REMEMBER_ON_HISTORY can veto, and does.
Right now this does history expansion. */
char *
pre_process_line (line, print_changes, addit)
char *line;
int print_changes, addit;
{
char *history_value;
char *return_value;
int expanded;
return_value = line;
expanded = 0;
# if defined (BANG_HISTORY)
/* History expand the line. If this results in no errors, then
add that line to the history if ADDIT is non-zero. */
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
{
expanded = history_expand (line, &history_value);
if (expanded)
{
if (print_changes)
{
if (expanded < 0)
internal_error ("%s", history_value);
#if defined (READLINE)
else if (hist_verify == 0 || expanded == 2)
#else
else
#endif
fprintf (stderr, "%s\n", history_value);
}
/* If there was an error, return NULL. */
if (expanded < 0 || expanded == 2) /* 2 == print only */
{
# if defined (READLINE)
if (expanded == 2 && rl_dispatching == 0 && *history_value)
# else
if (expanded == 2 && *history_value)
# endif /* !READLINE */
maybe_add_history (history_value);
free (history_value);
# if defined (READLINE)
/* New hack. We can allow the user to edit the
failed history expansion. */
if (history_reediting && expanded < 0 && rl_done)
re_edit (line);
# endif /* READLINE */
return ((char *)NULL);
}
# if defined (READLINE)
if (hist_verify && expanded == 1)
{
re_edit (history_value);
return ((char *)NULL);
}
# endif
}
/* Let other expansions know that return_value can be free'ed,
and that a line has been added to the history list. Note
that we only add lines that have something in them. */
expanded = 1;
return_value = history_value;
}
# endif /* BANG_HISTORY */
if (addit && remember_on_history && *return_value)
maybe_add_history (return_value);
#if 0
if (expanded == 0)
return_value = savestring (line);
#endif
return (return_value);
}
/* Return 1 if the first non-whitespace character in LINE is a `#', indicating
* that the line is a shell comment. */
static int
shell_comment (line)
char *line;
{
char *p;
for (p = line; p && *p && whitespace (*p); p++)
;
return (p && *p == '#');
}
#ifdef INCLUDE_UNUSED
/* Remove shell comments from LINE. A `#' and anything after it is a comment.
This isn't really useful yet, since it doesn't handle quoting. */
static char *
filter_comments (line)
char *line;
{
char *p;
for (p = line; p && *p && *p != '#'; p++)
;
if (p && *p == '#')
*p = '\0';
return (line);
}
#endif
/* Check LINE against what HISTCONTROL says to do. Returns 1 if the line
should be saved; 0 if it should be discarded. */
static int
check_history_control (line)
char *line;
{
HIST_ENTRY *temp;
int r;
if (history_control == 0)
return 1;
/* ignorespace or ignoreboth */
if ((history_control & HC_IGNSPACE) && *line == ' ')
return 0;
/* ignoredups or ignoreboth */
if (history_control & HC_IGNDUPS)
{
using_history ();
temp = previous_history ();
r = (temp == 0 || STREQ (temp->line, line) == 0);
using_history ();
if (r == 0)
return r;
}
return 1;
}
/* Remove all entries matching LINE from the history list. Triggered when
HISTCONTROL includes `erasedups'. */
static void
hc_erasedups (line)
char *line;
{
HIST_ENTRY *temp;
int r;
using_history ();
while (temp = previous_history ())
{
if (STREQ (temp->line, line))
{
r = where_history ();
remove_history (r);
}
}
using_history ();
}
/* Add LINE to the history list, handling possibly multi-line compound
commands. We note whether or not we save the first line of each command
(which is usually the entire command and history entry), and don't add
the second and subsequent lines of a multi-line compound command if we
didn't save the first line. We don't usually save shell comment lines in
compound commands in the history, because they could have the effect of
commenting out the rest of the command when the entire command is saved as
a single history entry (when COMMAND_ORIENTED_HISTORY is enabled). If
LITERAL_HISTORY is set, we're saving lines in the history with embedded
newlines, so it's OK to save comment lines. If we're collecting the body
of a here-document, we should act as if literal_history is enabled, because
we want to save the entire contents of the here-document as it was
entered. We also make sure to save multiple-line quoted strings or other
constructs. */
void
maybe_add_history (line)
char *line;
{
hist_last_line_added = 0;
/* Don't use the value of history_control to affect the second
and subsequent lines of a multi-line command (old code did
this only when command_oriented_history is enabled). */
if (current_command_line_count > 1)
{
if (current_command_first_line_saved &&
((parser_state & PST_HEREDOC) || literal_history || dstack.delimiter_depth != 0 || shell_comment (line) == 0))
bash_add_history (line);
return;
}
/* This is the first line of a (possible multi-line) command. Note whether
or not we should save the first line and remember it. */
current_command_first_line_saved = check_add_history (line, 0);
}
/* Just check LINE against HISTCONTROL and HISTIGNORE and add it to the
history if it's OK. Used by `history -s' as well as maybe_add_history().
Returns 1 if the line was saved in the history, 0 otherwise. */
int
check_add_history (line, force)
char *line;
int force;
{
if (check_history_control (line) && history_should_ignore (line) == 0)
{
/* We're committed to saving the line. If the user has requested it,
remove other matching lines from the history. */
if (history_control & HC_ERASEDUPS)
hc_erasedups (line);
if (force)
{
really_add_history (line);
using_history ();
}
else
bash_add_history (line);
return 1;
}
return 0;
}
#if defined (SYSLOG_HISTORY)
#define SYSLOG_MAXLEN 600
void
bash_syslog_history (line)
const char *line;
{
char trunc[SYSLOG_MAXLEN];
if (strlen(line) < SYSLOG_MAXLEN)
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY: PID=%d UID=%d %s", getpid(), current_user.uid, line);
else
{
strncpy (trunc, line, SYSLOG_MAXLEN);
trunc[SYSLOG_MAXLEN - 1] = '\0';
syslog (SYSLOG_FACILITY|SYSLOG_LEVEL, "HISTORY (TRUNCATED): PID=%d UID=%d %s", getpid(), current_user.uid, trunc);
}
}
#endif
/* Add a line to the history list.
The variable COMMAND_ORIENTED_HISTORY controls the style of history
remembering; when non-zero, and LINE is not the first line of a
complete parser construct, append LINE to the last history line instead
of adding it as a new line. */
void
bash_add_history (line)
char *line;
{
int add_it, offset, curlen;
HIST_ENTRY *current, *old;
char *chars_to_add, *new_line;
add_it = 1;
if (command_oriented_history && current_command_line_count > 1)
{
/* The second and subsequent lines of a here document have the trailing
newline preserved. We don't want to add extra newlines here, but we
do want to add one after the first line (which is the command that
contains the here-doc specifier). parse.y:history_delimiting_chars()
does the right thing to take care of this for us. We don't want to
add extra newlines if the user chooses to enable literal_history,
so we have to duplicate some of what that function does here. */
if ((parser_state & PST_HEREDOC) && literal_history && current_command_line_count > 2 && line[strlen (line) - 1] == '\n')
chars_to_add = "";
else
chars_to_add = literal_history ? "\n" : history_delimiting_chars (line);
using_history ();
current = previous_history ();
if (current)
{
/* If the previous line ended with an escaped newline (escaped
with backslash, but otherwise unquoted), then remove the quoted
newline, since that is what happens when the line is parsed. */
curlen = strlen (current->line);
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\\' &&
current->line[curlen - 2] != '\\')
{
current->line[curlen - 1] = '\0';
curlen--;
chars_to_add = "";
}
/* If we're not in some kind of quoted construct, the current history
entry ends with a newline, and we're going to add a semicolon,
don't. In some cases, it results in a syntax error (e.g., before
a close brace), and it should not be needed. */
if (dstack.delimiter_depth == 0 && current->line[curlen - 1] == '\n' && *chars_to_add == ';')
chars_to_add++;
new_line = (char *)xmalloc (1
+ curlen
+ strlen (line)
+ strlen (chars_to_add));
sprintf (new_line, "%s%s%s", current->line, chars_to_add, line);
offset = where_history ();
old = replace_history_entry (offset, new_line, current->data);
free (new_line);
if (old)
free_history_entry (old);
add_it = 0;
}
}
if (add_it)
really_add_history (line);
#if defined (SYSLOG_HISTORY)
bash_syslog_history (line);
#endif
using_history ();
}
static void
really_add_history (line)
char *line;
{
hist_last_line_added = 1;
hist_last_line_pushed = 0;
add_history (line);
history_lines_this_session++;
}
int
history_number ()
{
using_history ();
return (remember_on_history ? history_base + where_history () : 1);
}
static int
should_expand (s)
char *s;
{
char *p;
for (p = s; p && *p; p++)
{
if (*p == '\\')
p++;
else if (*p == '&')
return 1;
}
return 0;
}
static int
histignore_item_func (ign)
struct ign *ign;
{
if (should_expand (ign->val))
ign->flags |= HIGN_EXPAND;
return (0);
}
void
setup_history_ignore (varname)
char *varname;
{
setup_ignore_patterns (&histignore);
}
static HIST_ENTRY *
last_history_entry ()
{
HIST_ENTRY *he;
using_history ();
he = previous_history ();
using_history ();
return he;
}
char *
last_history_line ()
{
HIST_ENTRY *he;
he = last_history_entry ();
if (he == 0)
return ((char *)NULL);
return he->line;
}
static char *
expand_histignore_pattern (pat)
char *pat;
{
HIST_ENTRY *phe;
char *ret;
phe = last_history_entry ();
if (phe == (HIST_ENTRY *)0)
return (savestring (pat));
ret = strcreplace (pat, '&', phe->line, 1);
return ret;
}
/* Return 1 if we should not put LINE into the history according to the
patterns in HISTIGNORE. */
static int
history_should_ignore (line)
char *line;
{
register int i, match;
char *npat;
if (histignore.num_ignores == 0)
return 0;
for (i = match = 0; i < histignore.num_ignores; i++)
{
if (histignore.ignores[i].flags & HIGN_EXPAND)
npat = expand_histignore_pattern (histignore.ignores[i].val);
else
npat = histignore.ignores[i].val;
match = strmatch (npat, line, FNMATCH_EXTFLAG) != FNM_NOMATCH;
if (histignore.ignores[i].flags & HIGN_EXPAND)
free (npat);
if (match)
break;
}
return match;
}
#endif /* HISTORY */
-341
View File
@@ -1,341 +0,0 @@
This file is bind.def, from which is created bind.c.
It implements the builtin "bind" in Bash.
Copyright (C) 1987-2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES bind.c
#include <config.h>
$BUILTIN bind
$DEPENDS_ON READLINE
$FUNCTION bind_builtin
$SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
Set Readline key bindings and variables.
Bind a key sequence to a Readline function or a macro, or set a
Readline variable. The non-option argument syntax is equivalent to
that found in ~/.inputrc, but must be passed as a single argument:
e.g., bind '"\C-x\C-r": re-read-init-file'.
Options:
-m keymap Use KEYMAP as the keymap for the duration of this
command. Acceptable keymap names are emacs,
emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
vi-command, and vi-insert.
-l List names of functions.
-P List function names and bindings.
-p List functions and bindings in a form that can be
reused as input.
-S List key sequences that invoke macros and their values
-s List key sequences that invoke macros and their values
in a form that can be reused as input.
-V List variable names and values
-v List variable names and values in a form that can
be reused as input.
-q function-name Query about which keys invoke the named function.
-u function-name Unbind all keys which are bound to the named function.
-r keyseq Remove the binding for KEYSEQ.
-f filename Read key bindings from FILENAME.
-x keyseq:shell-command Cause SHELL-COMMAND to be executed when
KEYSEQ is entered.
-X List key sequences bound with -x and associated commands
in a form that can be reused as input.
Exit Status:
bind returns 0 unless an unrecognized option is given or an error occurs.
$END
#if defined (READLINE)
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include <readline/readline.h>
#include <readline/history.h>
#include "../bashintl.h"
#include "../shell.h"
#include "../bashline.h"
#include "bashgetopt.h"
#include "common.h"
static int query_bindings __P((char *));
static int unbind_command __P((char *));
extern int no_line_editing;
#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
#define LFLAG 0x0001
#define PFLAG 0x0002
#define FFLAG 0x0004
#define VFLAG 0x0008
#define QFLAG 0x0010
#define MFLAG 0x0020
#define RFLAG 0x0040
#define PPFLAG 0x0080
#define VVFLAG 0x0100
#define SFLAG 0x0200
#define SSFLAG 0x0400
#define UFLAG 0x0800
#define XFLAG 0x1000
#define XXFLAG 0x2000
int
bind_builtin (list)
WORD_LIST *list;
{
int return_code;
Keymap kmap, saved_keymap;
int flags, opt;
char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq;
if (no_line_editing)
{
#if 0
builtin_error (_("line editing not enabled"));
return (EXECUTION_FAILURE);
#else
builtin_warning (_("line editing not enabled"));
#endif
}
kmap = saved_keymap = (Keymap) NULL;
flags = 0;
initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL;
return_code = EXECUTION_SUCCESS;
if (bash_readline_initialized == 0)
initialize_readline ();
begin_unwind_frame ("bind_builtin");
unwind_protect_var (rl_outstream);
rl_outstream = stdout;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF)
{
switch (opt)
{
case 'l':
flags |= LFLAG;
break;
case 'v':
flags |= VFLAG;
break;
case 'p':
flags |= PFLAG;
break;
case 'f':
flags |= FFLAG;
initfile = list_optarg;
break;
case 'm':
flags |= MFLAG;
map_name = list_optarg;
break;
case 'q':
flags |= QFLAG;
fun_name = list_optarg;
break;
case 'u':
flags |= UFLAG;
unbind_name = list_optarg;
break;
case 'r':
flags |= RFLAG;
remove_seq = list_optarg;
break;
case 'V':
flags |= VVFLAG;
break;
case 'P':
flags |= PPFLAG;
break;
case 's':
flags |= SFLAG;
break;
case 'S':
flags |= SSFLAG;
break;
case 'x':
flags |= XFLAG;
cmd_seq = list_optarg;
break;
case 'X':
flags |= XXFLAG;
break;
default:
builtin_usage ();
BIND_RETURN (EX_USAGE);
}
}
list = loptend;
/* First, see if we need to install a special keymap for this
command. Then start on the arguments. */
if ((flags & MFLAG) && map_name)
{
kmap = rl_get_keymap_by_name (map_name);
if (kmap == 0)
{
builtin_error (_("`%s': invalid keymap name"), map_name);
BIND_RETURN (EXECUTION_FAILURE);
}
}
if (kmap)
{
saved_keymap = rl_get_keymap ();
rl_set_keymap (kmap);
}
/* XXX - we need to add exclusive use tests here. It doesn't make sense
to use some of these options together. */
/* Now hack the option arguments */
if (flags & LFLAG)
rl_list_funmap_names ();
if (flags & PFLAG)
rl_function_dumper (1);
if (flags & PPFLAG)
rl_function_dumper (0);
if (flags & SFLAG)
rl_macro_dumper (1);
if (flags & SSFLAG)
rl_macro_dumper (0);
if (flags & VFLAG)
rl_variable_dumper (1);
if (flags & VVFLAG)
rl_variable_dumper (0);
if ((flags & FFLAG) && initfile)
{
if (rl_read_init_file (initfile) != 0)
{
builtin_error (_("%s: cannot read: %s"), initfile, strerror (errno));
BIND_RETURN (EXECUTION_FAILURE);
}
}
if ((flags & QFLAG) && fun_name)
return_code = query_bindings (fun_name);
if ((flags & UFLAG) && unbind_name)
return_code = unbind_command (unbind_name);
if ((flags & RFLAG) && remove_seq)
{
if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0)
{
builtin_error (_("`%s': cannot unbind"), remove_seq);
BIND_RETURN (EXECUTION_FAILURE);
}
}
if (flags & XFLAG)
return_code = bind_keyseq_to_unix_command (cmd_seq);
if (flags & XXFLAG)
return_code = print_unix_command_map ();
/* Process the rest of the arguments as binding specifications. */
while (list)
{
rl_parse_and_bind (list->word->word);
list = list->next;
}
bind_exit:
if (saved_keymap)
rl_set_keymap (saved_keymap);
run_unwind_frame ("bind_builtin");
return (sh_chkwrite (return_code));
}
static int
query_bindings (name)
char *name;
{
rl_command_func_t *function;
char **keyseqs;
int j;
function = rl_named_function (name);
if (function == 0)
{
builtin_error (_("`%s': unknown function name"), name);
return EXECUTION_FAILURE;
}
keyseqs = rl_invoking_keyseqs (function);
if (!keyseqs)
{
printf (_("%s is not bound to any keys.\n"), name);
return EXECUTION_FAILURE;
}
printf (_("%s can be invoked via "), name);
for (j = 0; j < 5 && keyseqs[j]; j++)
printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
if (keyseqs[j])
printf ("...\n");
strvec_dispose (keyseqs);
return EXECUTION_SUCCESS;
}
static int
unbind_command (name)
char *name;
{
rl_command_func_t *function;
function = rl_named_function (name);
if (function == 0)
{
builtin_error (_("`%s': unknown function name"), name);
return EXECUTION_FAILURE;
}
rl_unbind_function_in_map (function, rl_get_keymap ());
return EXECUTION_SUCCESS;
}
#endif /* READLINE */
-283
View File
@@ -1,283 +0,0 @@
This file is hash.def, from which is created hash.c.
It implements the builtin "hash" in Bash.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES hash.c
$BUILTIN hash
$FUNCTION hash_builtin
$SHORT_DOC hash [-lr] [-p pathname] [-dt] [name ...]
Remember or display program locations.
Determine and remember the full pathname of each command NAME. If
no arguments are given, information about remembered commands is displayed.
Options:
-d forget the remembered location of each NAME
-l display in a format that may be reused as input
-p pathname use PATHNAME as the full pathname of NAME
-r forget all remembered locations
-t print the remembered location of each NAME, preceding
each location with the corresponding NAME if multiple
NAMEs are given
Arguments:
NAME Each NAME is searched for in $PATH and added to the list
of remembered commands.
Exit Status:
Returns success unless NAME is not found or an invalid option is given.
$END
#include <config.h>
#include <stdio.h>
#include "../bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../builtins.h"
#include "../flags.h"
#include "../findcmd.h"
#include "../hashcmd.h"
#include "common.h"
#include "bashgetopt.h"
extern int posixly_correct;
extern int dot_found_in_search;
extern char *this_command_name;
static int add_hashed_command __P((char *, int));
static int print_hash_info __P((BUCKET_CONTENTS *));
static int print_portable_hash_info __P((BUCKET_CONTENTS *));
static int print_hashed_commands __P((int));
static int list_hashed_filename_targets __P((WORD_LIST *, int));
/* Print statistics on the current state of hashed commands. If LIST is
not empty, then rehash (or hash in the first place) the specified
commands. */
int
hash_builtin (list)
WORD_LIST *list;
{
int expunge_hash_table, list_targets, list_portably, delete, opt;
char *w, *pathname;
if (hashing_enabled == 0)
{
builtin_error (_("hashing disabled"));
return (EXECUTION_FAILURE);
}
expunge_hash_table = list_targets = list_portably = delete = 0;
pathname = (char *)NULL;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "dlp:rt")) != -1)
{
switch (opt)
{
case 'd':
delete = 1;
break;
case 'l':
list_portably = 1;
break;
case 'p':
pathname = list_optarg;
break;
case 'r':
expunge_hash_table = 1;
break;
case 't':
list_targets = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
/* hash -t requires at least one argument. */
if (list == 0 && list_targets)
{
sh_needarg ("-t");
return (EXECUTION_FAILURE);
}
/* We want hash -r to be silent, but hash -- to print hashing info, so
we test expunge_hash_table. */
if (list == 0 && expunge_hash_table == 0)
{
opt = print_hashed_commands (list_portably);
if (opt == 0 && posixly_correct == 0)
printf (_("%s: hash table empty\n"), this_command_name);
return (EXECUTION_SUCCESS);
}
if (expunge_hash_table)
phash_flush ();
/* If someone runs `hash -r -t xyz' he will be disappointed. */
if (list_targets)
return (list_hashed_filename_targets (list, list_portably));
#if defined (RESTRICTED_SHELL)
if (restricted && pathname && strchr (pathname, '/'))
{
sh_restricted (pathname);
return (EXECUTION_FAILURE);
}
#endif
for (opt = EXECUTION_SUCCESS; list; list = list->next)
{
/* Add, remove or rehash the specified commands. */
w = list->word->word;
if (absolute_program (w))
continue;
else if (pathname)
{
if (is_directory (pathname))
{
#ifdef EISDIR
builtin_error ("%s: %s", pathname, strerror (EISDIR));
#else
builtin_error (_("%s: is a directory"), pathname);
#endif
opt = EXECUTION_FAILURE;
}
else
phash_insert (w, pathname, 0, 0);
}
else if (delete)
{
if (phash_remove (w))
{
sh_notfound (w);
opt = EXECUTION_FAILURE;
}
}
else if (add_hashed_command (w, 0))
opt = EXECUTION_FAILURE;
}
fflush (stdout);
return (opt);
}
static int
add_hashed_command (w, quiet)
char *w;
int quiet;
{
int rv;
char *full_path;
rv = 0;
if (find_function (w) == 0 && find_shell_builtin (w) == 0)
{
phash_remove (w);
full_path = find_user_command (w);
if (full_path && executable_file (full_path))
phash_insert (w, full_path, dot_found_in_search, 0);
else
{
if (quiet == 0)
sh_notfound (w);
rv++;
}
FREE (full_path);
}
return (rv);
}
/* Print information about current hashed info. */
static int
print_hash_info (item)
BUCKET_CONTENTS *item;
{
printf ("%4d\t%s\n", item->times_found, pathdata(item)->path);
return 0;
}
static int
print_portable_hash_info (item)
BUCKET_CONTENTS *item;
{
printf ("builtin hash -p %s %s\n", pathdata(item)->path, item->key);
return 0;
}
static int
print_hashed_commands (fmt)
int fmt;
{
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
return (0);
if (fmt == 0)
printf (_("hits\tcommand\n"));
hash_walk (hashed_filenames, fmt ? print_portable_hash_info : print_hash_info);
return (1);
}
static int
list_hashed_filename_targets (list, fmt)
WORD_LIST *list;
int fmt;
{
int all_found, multiple;
char *target;
WORD_LIST *l;
all_found = 1;
multiple = list->next != 0;
for (l = list; l; l = l->next)
{
target = phash_search (l->word->word);
if (target == 0)
{
all_found = 0;
sh_notfound (l->word->word);
continue;
}
if (fmt)
printf ("builtin hash -p %s %s\n", target, l->word->word);
else
{
if (multiple)
printf ("%s\t", l->word->word);
printf ("%s\n", target);
}
free (target);
}
return (all_found ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
-517
View File
@@ -1,517 +0,0 @@
This file is help.def, from which is created help.c.
It implements the builtin "help" in Bash.
Copyright (C) 1987-2013 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES help.c
$BUILTIN help
$FUNCTION help_builtin
$DEPENDS_ON HELP_BUILTIN
$SHORT_DOC help [-dms] [pattern ...]
Display information about builtin commands.
Displays brief summaries of builtin commands. If PATTERN is
specified, gives detailed help on all commands matching PATTERN,
otherwise the list of help topics is printed.
Options:
-d output short description for each topic
-m display usage in pseudo-manpage format
-s output only a short usage synopsis for each topic matching
PATTERN
Arguments:
PATTERN Pattern specifiying a help topic
Exit Status:
Returns success unless PATTERN is not found or an invalid option is given.
$END
#include <config.h>
#if defined (HELP_BUILTIN)
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <errno.h>
#include <filecntl.h>
#include "../bashintl.h"
#include "../shell.h"
#include "../builtins.h"
#include "../pathexp.h"
#include "common.h"
#include "bashgetopt.h"
#include <glob/strmatch.h>
#include <glob/glob.h>
#ifndef errno
extern int errno;
#endif
extern const char * const bash_copyright;
extern const char * const bash_license;
static void show_builtin_command_help __P((void));
static int open_helpfile __P((char *));
static void show_desc __P((char *, int));
static void show_manpage __P((char *, int));
static void show_longdoc __P((int));
/* Print out a list of the known functions in the shell, and what they do.
If LIST is supplied, print out the list which matches for each pattern
specified. */
int
help_builtin (list)
WORD_LIST *list;
{
register int i;
char *pattern, *name;
int plen, match_found, sflag, dflag, mflag, m, pass, this_found;
dflag = sflag = mflag = 0;
reset_internal_getopt ();
while ((i = internal_getopt (list, "dms")) != -1)
{
switch (i)
{
case 'd':
dflag = 1;
break;
case 'm':
mflag = 1;
break;
case 's':
sflag = 1;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list == 0)
{
show_shell_version (0);
show_builtin_command_help ();
return (EXECUTION_SUCCESS);
}
/* We should consider making `help bash' do something. */
if (glob_pattern_p (list->word->word))
{
printf (ngettext ("Shell commands matching keyword `", "Shell commands matching keywords `", (list->next ? 2 : 1)));
print_word_list (list, ", ");
printf ("'\n\n");
}
for (match_found = 0, pattern = ""; list; list = list->next)
{
pattern = list->word->word;
plen = strlen (pattern);
for (pass = 1, this_found = 0; pass < 3; pass++)
{
for (i = 0; name = shell_builtins[i].name; i++)
{
QUIT;
/* First pass: look for exact string or pattern matches.
Second pass: look for prefix matches like bash-4.2 */
if (pass == 1)
m = (strcmp (pattern, name) == 0) ||
(strmatch (pattern, name, FNMATCH_EXTFLAG) != FNM_NOMATCH);
else
m = strncmp (pattern, name, plen) == 0;
if (m)
{
this_found = 1;
match_found++;
if (dflag)
{
show_desc (name, i);
continue;
}
else if (mflag)
{
show_manpage (name, i);
continue;
}
printf ("%s: %s\n", name, _(shell_builtins[i].short_doc));
if (sflag == 0)
show_longdoc (i);
}
}
if (pass == 1 && this_found == 1)
break;
}
}
if (match_found == 0)
{
builtin_error (_("no help topics match `%s'. Try `help help' or `man -k %s' or `info %s'."), pattern, pattern, pattern);
return (EXECUTION_FAILURE);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
static int
open_helpfile (name)
char *name;
{
int fd;
fd = open (name, O_RDONLY);
if (fd == -1)
{
builtin_error (_("%s: cannot open: %s"), name, strerror (errno));
return -1;
}
return fd;
}
/* By convention, enforced by mkbuiltins.c, if separate help files are being
used, the long_doc array contains one string -- the full pathname of the
help file for this builtin. */
static void
show_longdoc (i)
int i;
{
register int j;
char * const *doc;
int fd;
doc = shell_builtins[i].long_doc;
if (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL)
{
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zcatfd (fd, 1, doc[0]);
close (fd);
}
else if (doc)
for (j = 0; doc[j]; j++)
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
static void
show_desc (name, i)
char *name;
int i;
{
register int j;
char **doc, *line;
int fd, usefile;
doc = (char **)shell_builtins[i].long_doc;
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
if (usefile)
{
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zmapfd (fd, &line, doc[0]);
close (fd);
}
else
line = doc ? doc[0] : (char *)NULL;
printf ("%s - ", name);
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
break;
}
fflush (stdout);
if (usefile)
free (line);
}
/* Print builtin help in pseudo-manpage format. */
static void
show_manpage (name, i)
char *name;
int i;
{
register int j;
char **doc, *line;
int fd, usefile;
doc = (char **)shell_builtins[i].long_doc;
usefile = (doc && doc[0] && *doc[0] == '/' && doc[1] == (char *)NULL);
if (usefile)
{
fd = open_helpfile (doc[0]);
if (fd < 0)
return;
zmapfd (fd, &line, doc[0]);
close (fd);
}
else
line = doc ? _(doc[0]) : (char *)NULL;
/* NAME */
printf ("NAME\n");
printf ("%*s%s - ", BASE_INDENT, " ", name);
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
break;
}
printf ("\n");
/* SYNOPSIS */
printf ("SYNOPSIS\n");
printf ("%*s%s\n\n", BASE_INDENT, " ", _(shell_builtins[i].short_doc));
/* DESCRIPTION */
printf ("DESCRIPTION\n");
if (usefile == 0)
{
for (j = 0; doc[j]; j++)
printf ("%*s%s\n", BASE_INDENT, " ", _(doc[j]));
}
else
{
for (j = 0; line && line[j]; j++)
{
putchar (line[j]);
if (line[j] == '\n')
printf ("%*s", BASE_INDENT, " ");
}
}
putchar ('\n');
/* SEE ALSO */
printf ("SEE ALSO\n");
printf ("%*sbash(1)\n\n", BASE_INDENT, " ");
/* IMPLEMENTATION */
printf ("IMPLEMENTATION\n");
printf ("%*s", BASE_INDENT, " ");
show_shell_version (0);
printf ("%*s", BASE_INDENT, " ");
printf ("%s\n", _(bash_copyright));
printf ("%*s", BASE_INDENT, " ");
printf ("%s\n", _(bash_license));
fflush (stdout);
if (usefile)
free (line);
}
static void
dispcolumn (i, buf, bufsize, width, height)
int i;
char *buf;
size_t bufsize;
int width, height;
{
int j;
int displen;
char *helpdoc;
/* first column */
helpdoc = _(shell_builtins[i].short_doc);
buf[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (buf + 1, helpdoc, width - 2);
buf[width - 2] = '>'; /* indicate truncation */
buf[width - 1] = '\0';
printf ("%s", buf);
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
return;
}
displen = strlen (buf);
/* two spaces */
for (j = displen; j < width; j++)
putc (' ', stdout);
/* second column */
helpdoc = _(shell_builtins[i+height].short_doc);
buf[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*';
strncpy (buf + 1, helpdoc, width - 3);
buf[width - 3] = '>'; /* indicate truncation */
buf[width - 2] = '\0';
printf ("%s\n", buf);
}
#if defined (HANDLE_MULTIBYTE)
static void
wdispcolumn (i, buf, bufsize, width, height)
int i;
char *buf;
size_t bufsize;
int width, height;
{
int j;
int displen;
char *helpdoc;
wchar_t *wcstr;
size_t slen, n;
int wclen;
/* first column */
helpdoc = _(shell_builtins[i].short_doc);
wcstr = 0;
slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
if (slen == -1)
{
dispcolumn (i, buf, bufsize, width, height);
return;
}
/* No bigger than the passed max width */
if (slen >= width)
slen = width - 2;
wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (width + 2));
n = mbstowcs (wcstr+1, helpdoc, slen + 1);
wcstr[n+1] = L'\0';
/* Turn tabs and newlines into spaces for column display, since wcwidth
returns -1 for them */
for (j = 1; j < n; j++)
if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
wcstr[j] = L' ';
displen = wcsnwidth (wcstr+1, slen, width - 2) + 1; /* +1 for ' ' or '*' */
wcstr[0] = (shell_builtins[i].flags & BUILTIN_ENABLED) ? L' ' : L'*';
/* This assumes each wide char takes up one column position when displayed */
wcstr[width - 2] = L'>'; /* indicate truncation */
wcstr[width - 1] = L'\0';
printf ("%ls", wcstr);
if (((i << 1) >= num_shell_builtins) || (i+height >= num_shell_builtins))
{
printf ("\n");
return;
}
/* at least one space */
for (j = displen; j < width; j++)
putc (' ', stdout);
/* second column */
helpdoc = _(shell_builtins[i+height].short_doc);
slen = mbstowcs ((wchar_t *)0, helpdoc, 0);
if (slen == -1)
{
/* for now */
printf ("%c%s\n", (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? ' ' : '*', helpdoc);
return;
}
/* Reuse wcstr since it is already width wide chars long */
if (slen >= width)
slen = width - 2;
n = mbstowcs (wcstr+1, helpdoc, slen + 1);
wcstr[n+1] = L'\0'; /* make sure null-terminated */
/* Turn tabs and newlines into spaces for column display */
for (j = 1; j < n; j++)
if (wcstr[j] == L'\n' || wcstr[j] == L'\t')
wcstr[j] = L' ';
displen = wcsnwidth (wcstr+1, slen, width - 2);
wcstr[0] = (shell_builtins[i+height].flags & BUILTIN_ENABLED) ? L' ' : L'*';
/* This assumes each wide char takes up one column position when displayed */
wcstr[width - 3] = L'>'; /* indicate truncation */
wcstr[width - 2] = L'\0';
printf ("%ls\n", wcstr);
free (wcstr);
}
#endif /* HANDLE_MULTIBYTE */
static void
show_builtin_command_help ()
{
int i, j;
int height, width;
char *t, blurb[128];
printf (
_("These shell commands are defined internally. Type `help' to see this list.\n\
Type `help name' to find out more about the function `name'.\n\
Use `info bash' to find out more about the shell in general.\n\
Use `man -k' or `info' to find out more about commands not in this list.\n\
\n\
A star (*) next to a name means that the command is disabled.\n\
\n"));
t = get_string_value ("COLUMNS");
width = (t && *t) ? atoi (t) : 80;
if (width <= 0)
width = 80;
width /= 2;
if (width > sizeof (blurb))
width = sizeof (blurb);
if (width <= 3)
width = 40;
height = (num_shell_builtins + 1) / 2; /* number of rows */
for (i = 0; i < height; i++)
{
QUIT;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1)
wdispcolumn (i, blurb, sizeof (blurb), width, height);
else
#endif
dispcolumn (i, blurb, sizeof (blurb), width, height);
}
}
#endif /* HELP_BUILTIN */
-405
View File
@@ -1,405 +0,0 @@
This file is type.def, from which is created type.c.
It implements the builtin "type" in Bash.
Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
$PRODUCES type.c
$BUILTIN type
$FUNCTION type_builtin
$SHORT_DOC type [-afptP] name [name ...]
Display information about command type.
For each NAME, indicate how it would be interpreted if used as a
command name.
Options:
-a display all locations containing an executable named NAME;
includes aliases, builtins, and functions, if and only if
the `-p' option is not also used
-f suppress shell function lookup
-P force a PATH search for each NAME, even if it is an alias,
builtin, or function, and returns the name of the disk file
that would be executed
-p returns either the name of the disk file that would be executed,
or nothing if `type -t NAME' would not return `file'.
-t output a single word which is one of `alias', `keyword',
`function', `builtin', `file' or `', if NAME is an alias, shell
reserved word, shell function, shell builtin, disk file, or not
found, respectively
Arguments:
NAME Command name to be interpreted.
Exit Status:
Returns success if all of the NAMEs are found; fails if any are not found.
$END
#include <config.h>
#include "../bashtypes.h"
#include "posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../findcmd.h"
#include "../hashcmd.h"
#if defined (ALIAS)
#include "../alias.h"
#endif /* ALIAS */
#include "common.h"
#include "bashgetopt.h"
extern int find_reserved_word __P((char *));
extern char *this_command_name;
extern int expand_aliases, posixly_correct;
/* For each word in LIST, find out what the shell is going to do with
it as a simple command. i.e., which file would this shell use to
execve, or if it is a builtin command, or an alias. Possible flag
arguments:
-t Returns the "type" of the object, one of
`alias', `keyword', `function', `builtin',
or `file'.
-p Returns the pathname of the file if -type is
a file.
-a Returns all occurrences of words, whether they
be a filename in the path, alias, function,
or builtin.
-f Suppress shell function lookup, like `command'.
-P Force a path search even in the presence of other
definitions.
Order of evaluation:
alias
keyword
function
builtin
file
*/
int
type_builtin (list)
WORD_LIST *list;
{
int dflags, any_failed, opt;
WORD_LIST *this;
if (list == 0)
return (EXECUTION_SUCCESS);
dflags = CDESC_SHORTDESC; /* default */
any_failed = 0;
/* Handle the obsolescent `-type', `-path', and `-all' by prescanning
the arguments and converting those options to the form that
internal_getopt recognizes. Converts `--type', `--path', and `--all'
also. THIS SHOULD REALLY GO AWAY. */
for (this = list; this && this->word->word[0] == '-'; this = this->next)
{
char *flag = &(this->word->word[1]);
if (STREQ (flag, "type") || STREQ (flag, "-type"))
{
this->word->word[1] = 't';
this->word->word[2] = '\0';
}
else if (STREQ (flag, "path") || STREQ (flag, "-path"))
{
this->word->word[1] = 'p';
this->word->word[2] = '\0';
}
else if (STREQ (flag, "all") || STREQ (flag, "-all"))
{
this->word->word[1] = 'a';
this->word->word[2] = '\0';
}
}
reset_internal_getopt ();
while ((opt = internal_getopt (list, "afptP")) != -1)
{
switch (opt)
{
case 'a':
dflags |= CDESC_ALL;
break;
case 'f':
dflags |= CDESC_NOFUNCS;
break;
case 'p':
dflags |= CDESC_PATH_ONLY;
dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
break;
case 't':
dflags |= CDESC_TYPE;
dflags &= ~(CDESC_PATH_ONLY|CDESC_SHORTDESC);
break;
case 'P': /* shorthand for type -ap */
dflags |= (CDESC_PATH_ONLY|CDESC_FORCE_PATH);
dflags &= ~(CDESC_TYPE|CDESC_SHORTDESC);
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
while (list)
{
int found;
found = describe_command (list->word->word, dflags);
if (!found && (dflags & (CDESC_PATH_ONLY|CDESC_TYPE)) == 0)
sh_notfound (list->word->word);
any_failed += found == 0;
list = list->next;
}
opt = (any_failed == 0) ? EXECUTION_SUCCESS : EXECUTION_FAILURE;
return (sh_chkwrite (opt));
}
/*
* Describe COMMAND as required by the type and command builtins.
*
* Behavior is controlled by DFLAGS. Flag values are
* CDESC_ALL print all descriptions of a command
* CDESC_SHORTDESC print the description for type and command -V
* CDESC_REUSABLE print in a format that may be reused as input
* CDESC_TYPE print the type for type -t
* CDESC_PATH_ONLY print the path for type -p
* CDESC_FORCE_PATH force a path search for type -P
* CDESC_NOFUNCS skip function lookup for type -f
* CDESC_ABSPATH convert to absolute path, no ./ prefix
*
* CDESC_ALL says whether or not to look for all occurrences of COMMAND, or
* return after finding it once.
*/
int
describe_command (command, dflags)
char *command;
int dflags;
{
int found, i, found_file, f, all;
char *full_path, *x;
SHELL_VAR *func;
#if defined (ALIAS)
alias_t *alias;
#endif
all = (dflags & CDESC_ALL) != 0;
found = found_file = 0;
full_path = (char *)NULL;
#if defined (ALIAS)
/* Command is an alias? */
if (((dflags & CDESC_FORCE_PATH) == 0) && expand_aliases && (alias = find_alias (command)))
{
if (dflags & CDESC_TYPE)
puts ("alias");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is aliased to `%s'\n"), command, alias->value);
else if (dflags & CDESC_REUSABLE)
{
x = sh_single_quote (alias->value);
printf ("alias %s=%s\n", command, x);
free (x);
}
found = 1;
if (all == 0)
return (1);
}
#endif /* ALIAS */
/* Command is a shell reserved word? */
if (((dflags & CDESC_FORCE_PATH) == 0) && (i = find_reserved_word (command)) >= 0)
{
if (dflags & CDESC_TYPE)
puts ("keyword");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is a shell keyword\n"), command);
else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
if (all == 0)
return (1);
}
/* Command is a function? */
if (((dflags & (CDESC_FORCE_PATH|CDESC_NOFUNCS)) == 0) && (func = find_function (command)))
{
if (dflags & CDESC_TYPE)
puts ("function");
else if (dflags & CDESC_SHORTDESC)
{
char *result;
printf (_("%s is a function\n"), command);
/* We're blowing away THE_PRINTED_COMMAND here... */
result = named_function_string (command, function_cell (func), FUNC_MULTILINE|FUNC_EXTERNAL);
printf ("%s\n", result);
}
else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
if (all == 0)
return (1);
}
/* Command is a builtin? */
if (((dflags & CDESC_FORCE_PATH) == 0) && find_shell_builtin (command))
{
if (dflags & CDESC_TYPE)
puts ("builtin");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is a shell builtin\n"), command);
else if (dflags & CDESC_REUSABLE)
printf ("%s\n", command);
found = 1;
if (all == 0)
return (1);
}
/* Command is a disk file? */
/* If the command name given is already an absolute command, just
check to see if it is executable. */
if (absolute_program (command))
{
f = file_status (command);
if (f & FS_EXECABLE)
{
if (dflags & CDESC_TYPE)
puts ("file");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is %s\n"), command, command);
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", command);
/* There's no use looking in the hash table or in $PATH,
because they're not consulted when an absolute program
name is supplied. */
return (1);
}
}
/* If the user isn't doing "-a", then we might care about
whether the file is present in our hash table. */
if (all == 0 || (dflags & CDESC_FORCE_PATH))
{
if (full_path = phash_search (command))
{
if (dflags & CDESC_TYPE)
puts ("file");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is hashed (%s)\n"), command, full_path);
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", full_path);
free (full_path);
return (1);
}
}
/* Now search through $PATH. */
while (1)
{
if (all == 0)
full_path = find_user_command (command);
else
full_path =
user_command_matches (command, FS_EXEC_ONLY, found_file);
/* XXX - should that be FS_EXEC_PREFERRED? */
if (full_path == 0)
break;
/* If we found the command as itself by looking through $PATH, it
probably doesn't exist. Check whether or not the command is an
executable file. If it's not, don't report a match. This is
the default posix mode behavior */
if (STREQ (full_path, command) || posixly_correct)
{
f = file_status (full_path);
if ((f & FS_EXECABLE) == 0)
{
free (full_path);
full_path = (char *)NULL;
if (all == 0)
break;
}
else if (ABSPATH (full_path))
; /* placeholder; don't need to do anything yet */
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY|CDESC_SHORTDESC))
{
f = MP_DOCWD | ((dflags & CDESC_ABSPATH) ? MP_RMDOT : 0);
x = sh_makepath ((char *)NULL, full_path, f);
free (full_path);
full_path = x;
}
}
/* If we require a full path and don't have one, make one */
else if ((dflags & CDESC_ABSPATH) && ABSPATH (full_path) == 0)
full_path = sh_makepath ((char *)NULL, full_path, MP_DOCWD|MP_RMDOT);
found_file++;
found = 1;
if (dflags & CDESC_TYPE)
puts ("file");
else if (dflags & CDESC_SHORTDESC)
printf (_("%s is %s\n"), command, full_path);
else if (dflags & (CDESC_REUSABLE|CDESC_PATH_ONLY))
printf ("%s\n", full_path);
free (full_path);
full_path = (char *)NULL;
if (all == 0)
break;
}
return (found);
}
-42
View File
@@ -1,42 +0,0 @@
# This file is a shell script that caches the results of configure
# tests for CYGWIN32 so they don't need to be done when cross-compiling.
# AC_FUNC_GETPGRP should also define GETPGRP_VOID
ac_cv_func_getpgrp_void=${ac_cv_func_getpgrp_void='yes'}
# AC_FUNC_SETVBUF_REVERSED should not define anything else
ac_cv_func_setvbuf_reversed=${ac_cv_func_setvbuf_reversed='no'}
# on CYGWIN32, system calls do not restart
ac_cv_sys_restartable_syscalls=${ac_cv_sys_restartable_syscalls='no'}
bash_cv_sys_restartable_syscalls=${bash_cv_sys_restartable_syscalls='no'}
# these may be necessary, but they are currently commented out
#ac_cv_c_bigendian=${ac_cv_c_bigendian='no'}
ac_cv_sizeof_char_p=${ac_cv_sizeof_char_p='4'}
ac_cv_sizeof_int=${ac_cv_sizeof_int='4'}
ac_cv_sizeof_long=${ac_cv_sizeof_long='4'}
ac_cv_sizeof_double=${ac_cv_sizeof_double='8'}
bash_cv_dup2_broken=${bash_cv_dup2_broken='no'}
bash_cv_pgrp_pipe=${bash_cv_pgrp_pipe='no'}
bash_cv_type_rlimit=${bash_cv_type_rlimit='long'}
bash_cv_decl_under_sys_siglist=${bash_cv_decl_under_sys_siglist='no'}
bash_cv_under_sys_siglist=${bash_cv_under_sys_siglist='no'}
bash_cv_sys_siglist=${bash_cv_sys_siglist='no'}
bash_cv_opendir_not_robust=${bash_cv_opendir_not_robust='no'}
bash_cv_getenv_redef=${bash_cv_getenv_redef='yes'}
bash_cv_printf_declared=${bash_cv_printf_declared='yes'}
bash_cv_ulimit_maxfds=${bash_cv_ulimit_maxfds='no'}
bash_cv_getcwd_calls_popen=${bash_cv_getcwd_calls_popen='no'}
bash_cv_must_reinstall_sighandlers=${bash_cv_must_reinstall_sighandlers='no'}
bash_cv_job_control_missing=${bash_cv_job_control_missing='present'}
bash_cv_sys_named_pipes=${bash_cv_sys_named_pipes='missing'}
bash_cv_func_sigsetjmp=${bash_cv_func_sigsetjmp='missing'}
bash_cv_mail_dir=${bash_cv_mail_dir='unknown'}
bash_cv_func_strcoll_broken=${bash_cv_func_strcoll_broken='no'}
bash_cv_type_int32_t=${bash_cv_type_int32_t='int'}
bash_cv_type_u_int32_t=${bash_cv_type_u_int32_t='int'}
ac_cv_type_bits64_t=${ac_cv_type_bits64_t='no'}
# end of cross-build/cygwin32.cache
-61
View File
@@ -1,61 +0,0 @@
*** ../bash-4.3-patched/lib/readline/display.c 2014-04-08 18:19:36.000000000 -0400
--- lib/readline/display.c 2014-04-20 18:32:52.000000000 -0400
***************
*** 1036,1040 ****
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
!
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
--- 1036,1040 ----
_rl_last_c_pos > (prompt_last_invisible - _rl_screenwidth - prompt_invis_chars_first_line))
_rl_last_c_pos -= (wrap_offset-prompt_invis_chars_first_line);
!
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
***************
*** 1638,1642 ****
the spot of first difference is before the end of the invisible chars,
lendiff needs to be adjusted. */
! if (current_line == 0 && !_rl_horizontal_scroll_mode &&
current_invis_chars != visible_wrap_offset)
{
--- 1638,1642 ----
the spot of first difference is before the end of the invisible chars,
lendiff needs to be adjusted. */
! if (current_line == 0 && /* !_rl_horizontal_scroll_mode && */
current_invis_chars != visible_wrap_offset)
{
***************
*** 1826,1831 ****
_rl_last_c_pos += bytes_to_insert;
if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
! goto clear_rest_of_line;
}
}
--- 1826,1836 ----
_rl_last_c_pos += bytes_to_insert;
+ /* XXX - we only want to do this if we are at the end of the line
+ so we move there with _rl_move_cursor_relative */
if (_rl_horizontal_scroll_mode && ((oe-old) > (ne-new)))
! {
! _rl_move_cursor_relative (ne-new, new);
! goto clear_rest_of_line;
! }
}
}
***************
*** 2695,2698 ****
--- 2700,2709 ----
}
+ void
+ _rl_ttyflush ()
+ {
+ fflush (rl_outstream);
+ }
+
/* return the `current display line' of the cursor -- the number of lines to
move up to get to the first screen line of the current readline line. */
-1745
View File
File diff suppressed because it is too large Load Diff
-238
View File
@@ -1,238 +0,0 @@
#
# Simple makefile for the sample loadable builtins
#
# Copyright (C) 1996 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.
# Include some boilerplate Gnu makefile definitions.
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
infodir = @infodir@
includedir = @includedir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
srcdir = @srcdir@
VPATH = .:@srcdir@
@SET_MAKE@
CC = @CC@
RM = rm -f
SHELL = @MAKE_SHELL@
host_os = @host_os@
host_cpu = @host_cpu@
host_vendor = @host_vendor@
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
DEFS = @DEFS@
LOCAL_DEFS = @LOCAL_DEFS@
CPPFLAGS = @CPPFLAGS@
BASHINCDIR = ${topdir}/include
LIBBUILD = ${BUILD_DIR}/lib
INTL_LIBSRC = ${topdir}/lib/intl
INTL_BUILDDIR = ${LIBBUILD}/intl
INTL_INC = @INTL_INC@
LIBINTL_H = @LIBINTL_H@
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) $(CFLAGS)
#
# These values are generated for configure by ${topdir}/support/shobj-conf.
# If your system is not supported by that script, but includes facilities for
# dynamic loading of shared objects, please update the script and send the
# changes to bash-maintainers@gnu.org.
#
SHOBJ_CC = @SHOBJ_CC@
SHOBJ_CFLAGS = @SHOBJ_CFLAGS@
SHOBJ_LD = @SHOBJ_LD@
SHOBJ_LDFLAGS = @SHOBJ_LDFLAGS@
SHOBJ_XLDFLAGS = @SHOBJ_XLDFLAGS@
SHOBJ_LIBS = @SHOBJ_LIBS@
SHOBJ_STATUS = @SHOBJ_STATUS@
INC = -I. -I.. -I$(topdir) -I$(topdir)/lib -I$(topdir)/builtins \
-I$(BASHINCDIR) -I$(BUILD_DIR) -I$(LIBBUILD) \
-I$(BUILD_DIR)/builtins $(INTL_INC)
.c.o:
$(SHOBJ_CC) $(SHOBJ_CFLAGS) $(CCFLAGS) $(INC) -c -o $@ $<
ALLPROG = print truefalse sleep pushd finfo logname basename dirname \
tty pathchk tee head mkdir rmdir printenv id whoami \
uname sync push ln unlink cut realpath getconf strftime
OTHERPROG = necho hello cat
all: $(SHOBJ_STATUS)
supported: $(ALLPROG)
others: $(OTHERPROG)
unsupported:
@echo "Your system (${host_os}) is not supported by the"
@echo "${topdir}/support/shobj-conf script."
@echo "If your operating system provides facilities for dynamic"
@echo "loading of shared objects using the dlopen(3) interface,"
@echo "please update the script and re-run configure.
@echo "Please send the changes you made to bash-maintainers@gnu.org"
@echo "for inclusion in future bash releases."
everything: supported others
print: print.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ print.o $(SHOBJ_LIBS)
necho: necho.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ necho.o $(SHOBJ_LIBS)
getconf: getconf.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ getconf.o $(SHOBJ_LIBS)
hello: hello.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ hello.o $(SHOBJ_LIBS)
truefalse: truefalse.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ truefalse.o $(SHOBJ_LIBS)
sleep: sleep.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ sleep.o $(SHOBJ_LIBS)
finfo: finfo.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ finfo.o $(SHOBJ_LIBS)
cat: cat.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cat.o $(SHOBJ_LIBS)
logname: logname.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ logname.o $(SHOBJ_LIBS)
basename: basename.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ basename.o $(SHOBJ_LIBS)
dirname: dirname.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ dirname.o $(SHOBJ_LIBS)
tty: tty.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ tty.o $(SHOBJ_LIBS)
pathchk: pathchk.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ pathchk.o $(SHOBJ_LIBS)
tee: tee.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ tee.o $(SHOBJ_LIBS)
mkdir: mkdir.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ mkdir.o $(SHOBJ_LIBS)
rmdir: rmdir.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ rmdir.o $(SHOBJ_LIBS)
head: head.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ head.o $(SHOBJ_LIBS)
printenv: printenv.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ printenv.o $(SHOBJ_LIBS)
id: id.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ id.o $(SHOBJ_LIBS)
whoami: whoami.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ whoami.o $(SHOBJ_LIBS)
uname: uname.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ uname.o $(SHOBJ_LIBS)
sync: sync.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ sync.o $(SHOBJ_LIBS)
push: push.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ push.o $(SHOBJ_LIBS)
ln: ln.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ ln.o $(SHOBJ_LIBS)
unlink: unlink.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ unlink.o $(SHOBJ_LIBS)
cut: cut.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ cut.o $(SHOBJ_LIBS)
realpath: realpath.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ realpath.o $(SHOBJ_LIBS)
strftime: strftime.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ strftime.o $(SHOBJ_LIBS)
# pushd is a special case. We use the same source that the builtin version
# uses, with special compilation options.
#
pushd.c: ${topdir}/builtins/pushd.def
$(RM) $@
${BUILD_DIR}/builtins/mkbuiltins -D ${topdir}/builtins ${topdir}/builtins/pushd.def
pushd.o: pushd.c
$(RM) $@
$(SHOBJ_CC) -DHAVE_CONFIG_H -DPUSHD_AND_POPD -DLOADABLE_BUILTIN $(SHOBJ_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(INC) -c -o $@ $<
pushd: pushd.o
$(SHOBJ_LD) $(SHOBJ_LDFLAGS) $(SHOBJ_XLDFLAGS) -o $@ pushd.o $(SHOBJ_LIBS)
clean:
$(RM) $(ALLPROG) $(OTHERPROG) *.o
-( cd perl && ${MAKE} ${MFLAGS} $@ )
mostlyclean: clean
-( cd perl && ${MAKE} ${MFLAGS} $@ )
distclean maintainer-clean: clean
$(RM) Makefile pushd.c
-( cd perl && ${MAKE} ${MFLAGS} $@ )
print.o: print.c
truefalse.o: truefalse.c
sleep.o: sleep.c
finfo.o: finfo.c
logname.o: logname.c
basename.o: basename.c
dirname.o: dirname.c
tty.o: tty.c
pathchk.o: pathchk.c
tee.o: tee.c
head.o: head.c
rmdir.o: rmdir.c
necho.o: necho.c
getconf.o: getconf.c
hello.o: hello.c
cat.o: cat.c
printenv.o: printenv.c
id.o: id.c
whoami.o: whoami.c
uname.o: uname.c
sync.o: sync.c
push.o: push.c
mkdir.o: mkdir.c
realpath.o: realpath.c
strftime.o: strftime.c
-5467
View File
File diff suppressed because it is too large Load Diff
-1381
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-424
View File
@@ -1,424 +0,0 @@
/* localealias.c - Handle aliases for locale names. */
/* Copyright (C) 1995-1999, 2000-2001, 2003, 2005-2009 Free Software Foundation, Inc.
This file is part of GNU Bash.
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
This must come before <config.h> because <config.h> may include
<features.h>, and once <features.h> has been included, it's too late. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <ctype.h>
#include <stdio.h>
#if defined _LIBC || defined HAVE___FSETLOCKING
# include <stdio_ext.h>
#endif
#include <sys/types.h>
#ifdef __GNUC__
# undef alloca
# define alloca __builtin_alloca
# define HAVE_ALLOCA 1
#else
# ifdef _MSC_VER
# include <malloc.h>
# define alloca _alloca
# else
# if defined HAVE_ALLOCA_H || defined _LIBC
# include <alloca.h>
# else
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca
char *alloca ();
# endif
# endif
# endif
# endif
#endif
#include <stdlib.h>
#include <string.h>
#include "gettextP.h"
#if ENABLE_RELOCATABLE
# include "relocatable.h"
#else
# define relocate(pathname) (pathname)
#endif
/* @@ end of prolog @@ */
#ifdef _LIBC
/* Rename the non ANSI C functions. This is required by the standard
because some ANSI C functions will require linking with this object
file and the name space must not be polluted. */
# define strcasecmp __strcasecmp
# ifndef mempcpy
# define mempcpy __mempcpy
# endif
# define HAVE_MEMPCPY 1
# define HAVE___FSETLOCKING 1
/* We need locking here since we can be called from different places. */
# include <bits/libc-lock.h>
__libc_lock_define_initialized (static, lock);
#endif
#ifndef internal_function
# define internal_function
#endif
/* Some optimizations for glibc. */
#ifdef _LIBC
# define FEOF(fp) feof_unlocked (fp)
# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp)
#else
# define FEOF(fp) feof (fp)
# define FGETS(buf, n, fp) fgets (buf, n, fp)
#endif
/* For those losing systems which don't have `alloca' we have to add
some additional code emulating it. */
#ifdef HAVE_ALLOCA
# define freea(p) /* nothing */
#else
# define alloca(n) malloc (n)
# define freea(p) free (p)
#endif
#if defined _LIBC_REENTRANT || defined HAVE_FGETS_UNLOCKED
# undef fgets
# define fgets(buf, len, s) fgets_unlocked (buf, len, s)
#endif
#if defined _LIBC_REENTRANT || defined HAVE_FEOF_UNLOCKED
# undef feof
# define feof(s) feof_unlocked (s)
#endif
struct alias_map
{
const char *alias;
const char *value;
};
#ifndef _LIBC
# define libc_freeres_ptr(decl) decl
#endif
libc_freeres_ptr (static char *string_space);
static size_t string_space_act;
static size_t string_space_max;
libc_freeres_ptr (static struct alias_map *map);
static size_t nmap;
static size_t maxmap;
/* Prototypes for local functions. */
static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
internal_function;
static int extend_alias_table PARAMS ((void));
static int alias_compare PARAMS ((const struct alias_map *map1,
const struct alias_map *map2));
const char *
_nl_expand_alias (name)
const char *name;
{
static const char *locale_alias_path;
struct alias_map *retval;
const char *result = NULL;
size_t added;
#ifdef _LIBC
__libc_lock_lock (lock);
#endif
if (locale_alias_path == NULL)
locale_alias_path = LOCALE_ALIAS_PATH;
do
{
struct alias_map item;
item.alias = name;
if (nmap > 0)
retval = (struct alias_map *) bsearch (&item, map, nmap,
sizeof (struct alias_map),
(int (*) PARAMS ((const void *,
const void *))
) alias_compare);
else
retval = NULL;
/* We really found an alias. Return the value. */
if (retval != NULL)
{
result = retval->value;
break;
}
/* Perhaps we can find another alias file. */
added = 0;
while (added == 0 && locale_alias_path[0] != '\0')
{
const char *start;
while (locale_alias_path[0] == PATH_SEPARATOR)
++locale_alias_path;
start = locale_alias_path;
while (locale_alias_path[0] != '\0'
&& locale_alias_path[0] != PATH_SEPARATOR)
++locale_alias_path;
if (start < locale_alias_path)
added = read_alias_file (start, locale_alias_path - start);
}
}
while (added != 0);
#ifdef _LIBC
__libc_lock_unlock (lock);
#endif
return result;
}
static size_t
internal_function
read_alias_file (fname, fname_len)
const char *fname;
int fname_len;
{
FILE *fp;
char *full_fname;
size_t added;
static const char aliasfile[] = "/locale.alias";
full_fname = (char *) alloca (fname_len + sizeof aliasfile);
#ifdef HAVE_MEMPCPY
mempcpy (mempcpy (full_fname, fname, fname_len),
aliasfile, sizeof aliasfile);
#else
memcpy (full_fname, fname, fname_len);
memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
#endif
fp = fopen (relocate (full_fname), "r");
freea (full_fname);
if (fp == NULL)
return 0;
#ifdef HAVE___FSETLOCKING
/* No threads present. */
__fsetlocking (fp, FSETLOCKING_BYCALLER);
#endif
added = 0;
while (!FEOF (fp))
{
/* It is a reasonable approach to use a fix buffer here because
a) we are only interested in the first two fields
b) these fields must be usable as file names and so must not
be that long
We avoid a multi-kilobyte buffer here since this would use up
stack space which we might not have if the program ran out of
memory. */
char buf[400];
char *alias;
char *value;
char *cp;
if (FGETS (buf, sizeof buf, fp) == NULL)
/* EOF reached. */
break;
cp = buf;
/* Ignore leading white space. */
while (isspace ((unsigned char) cp[0]))
++cp;
/* A leading '#' signals a comment line. */
if (cp[0] != '\0' && cp[0] != '#')
{
alias = cp++;
while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
++cp;
/* Terminate alias name. */
if (cp[0] != '\0')
*cp++ = '\0';
/* Now look for the beginning of the value. */
while (isspace ((unsigned char) cp[0]))
++cp;
if (cp[0] != '\0')
{
size_t alias_len;
size_t value_len;
value = cp++;
while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
++cp;
/* Terminate value. */
if (cp[0] == '\n')
{
/* This has to be done to make the following test
for the end of line possible. We are looking for
the terminating '\n' which do not overwrite here. */
*cp++ = '\0';
*cp = '\n';
}
else if (cp[0] != '\0')
*cp++ = '\0';
if (nmap >= maxmap)
if (__builtin_expect (extend_alias_table (), 0))
{
fclose (fp);
return added;
}
alias_len = strlen (alias) + 1;
value_len = strlen (value) + 1;
if (string_space_act + alias_len + value_len > string_space_max)
{
/* Increase size of memory pool. */
size_t new_size = (string_space_max
+ (alias_len + value_len > 1024
? alias_len + value_len : 1024));
char *new_pool = (char *) realloc (string_space, new_size);
if (new_pool == NULL)
return added;
if (__builtin_expect (string_space != new_pool, 0))
{
size_t i;
for (i = 0; i < nmap; i++)
{
map[i].alias += new_pool - string_space;
map[i].value += new_pool - string_space;
}
}
string_space = new_pool;
string_space_max = new_size;
}
map[nmap].alias = memcpy (&string_space[string_space_act],
alias, alias_len);
string_space_act += alias_len;
map[nmap].value = memcpy (&string_space[string_space_act],
value, value_len);
string_space_act += value_len;
++nmap;
++added;
}
}
/* Possibly not the whole line fits into the buffer. Ignore
the rest of the line. */
while (strchr (buf, '\n') == NULL)
if (FGETS (buf, sizeof buf, fp) == NULL)
/* Make sure the inner loop will be left. The outer loop
will exit at the `feof' test. */
break;
}
/* Should we test for ferror()? I think we have to silently ignore
errors. --drepper */
fclose (fp);
if (added > 0)
qsort (map, nmap, sizeof (struct alias_map),
(int (*) PARAMS ((const void *, const void *))) alias_compare);
return added;
}
static int
extend_alias_table ()
{
size_t new_size;
struct alias_map *new_map;
new_size = maxmap == 0 ? 100 : 2 * maxmap;
new_map = (struct alias_map *) realloc (map, (new_size
* sizeof (struct alias_map)));
if (new_map == NULL)
/* Simply don't extend: we don't have any more core. */
return -1;
map = new_map;
maxmap = new_size;
return 0;
}
static int
alias_compare (map1, map2)
const struct alias_map *map1;
const struct alias_map *map2;
{
#if defined _LIBC || defined HAVE_STRCASECMP
return strcasecmp (map1->alias, map2->alias);
#else
const unsigned char *p1 = (const unsigned char *) map1->alias;
const unsigned char *p2 = (const unsigned char *) map2->alias;
unsigned char c1, c2;
if (p1 == p2)
return 0;
do
{
/* I know this seems to be odd but the tolower() function in
some systems libc cannot handle nonalpha characters. */
c1 = isupper (*p1) ? tolower (*p1) : *p1;
c2 = isupper (*p2) ? tolower (*p2) : *p2;
if (c1 == '\0')
break;
++p1;
++p2;
}
while (c1 == c2);
return c1 - c2;
#endif
}
File diff suppressed because it is too large Load Diff
-76
View File
@@ -1,76 +0,0 @@
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
RM = rm -f
MAKEINFO = makeinfo
TEXI2DVI = texi2dvi
TEXI2HTML = texi2html
QUIETPS = #set this to -q to shut up dvips
DVIPS = dvips -D 300 $(QUIETPS) -o $@ # tricky
INSTALL_DATA = cp
infodir = /usr/local/info
RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo
HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
DVIOBJ = readline.dvi history.dvi
INFOOBJ = readline.info history.info
PSOBJ = readline.ps history.ps
HTMLOBJ = readline.html history.html
all: info dvi html ps
nodvi: info html
readline.dvi: $(RLSRC)
$(TEXI2DVI) rlman.texinfo
mv rlman.dvi readline.dvi
readline.info: $(RLSRC)
$(MAKEINFO) --no-split -o $@ rlman.texinfo
history.dvi: ${HISTSRC}
$(TEXI2DVI) hist.texinfo
mv hist.dvi history.dvi
history.info: ${HISTSRC}
$(MAKEINFO) --no-split -o $@ hist.texinfo
readline.ps: readline.dvi
$(RM) $@
$(DVIPS) readline.dvi
history.ps: history.dvi
$(RM) $@
$(DVIPS) history.dvi
readline.html: ${RLSRC}
$(TEXI2HTML) rlman.texinfo
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html
$(RM) rlman.html rlman_toc.html
history.html: ${HISTSRC}
$(TEXI2HTML) hist.texinfo
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html
$(RM) hist.html hist_toc.html
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
clean:
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.fns *.kys *.tps *.vrs *.o core
distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) *.dvi *.info *.info-* *.ps *.html
install: info
${INSTALL_DATA} readline.info $(infodir)/readline.info
${INSTALL_DATA} history.info $(infodir)/history.info
-423
View File
@@ -1,423 +0,0 @@
/* mktime - convert struct tm to a time_t value */
/* Copyright (C) 1993-2002 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Contributed by Paul Eggert (eggert@twinsun.com).
Bash is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Bash is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
/* Define this to have a standalone program to test this implementation of
mktime. */
/* #define DEBUG 1 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef _LIBC
# define HAVE_LIMITS_H 1
# define HAVE_LOCALTIME_R 1
# define STDC_HEADERS 1
#endif
/* Assume that leap seconds are possible, unless told otherwise.
If the host has a `zic' command with a `-L leapsecondfilename' option,
then it supports leap seconds; otherwise it probably doesn't. */
#ifndef LEAP_SECONDS_POSSIBLE
#define LEAP_SECONDS_POSSIBLE 1
#endif
#ifndef VMS
#include <sys/types.h> /* Some systems define `time_t' here. */
#endif
#include <time.h>
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#include "bashansi.h"
#if DEBUG
#include <stdio.h>
/* Make it work even if the system's libc has its own mktime routine. */
#define mktime my_mktime
#endif /* DEBUG */
#ifndef __P
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
#define __P(args) args
#else
#define __P(args) ()
#endif /* GCC. */
#endif /* Not __P. */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
#ifndef INT_MIN
#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
#endif
#ifndef INT_MAX
#define INT_MAX (~0 - INT_MIN)
#endif
#ifndef TIME_T_MIN
#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
#endif
#ifndef TIME_T_MAX
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
#endif
#define TM_YEAR_BASE 1900
#define EPOCH_YEAR 1970
#ifndef __isleap
/* Nonzero if YEAR is a leap year (every 4 years,
except every 100th isn't, and every 400th is). */
#define __isleap(year) \
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
#endif
/* How many days come before each month (0-12). */
const unsigned short int __mon_yday[2][13] =
{
/* Normal years. */
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
/* Leap years. */
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
};
static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
time_t __mktime_internal __P ((struct tm *,
struct tm *(*) (const time_t *, struct tm *),
time_t *));
static struct tm *my_localtime_r __P ((const time_t *, struct tm *));
static struct tm *
my_localtime_r (t, tp)
const time_t *t;
struct tm *tp;
{
struct tm *l = localtime (t);
if (! l)
return 0;
*tp = *l;
return tp;
}
/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
measured in seconds, ignoring leap seconds.
YEAR uses the same numbering as TM->tm_year.
All values are in range, except possibly YEAR.
If overflow occurs, yield the low order bits of the correct answer. */
static time_t
ydhms_tm_diff (year, yday, hour, min, sec, tp)
int year, yday, hour, min, sec;
const struct tm *tp;
{
/* Compute intervening leap days correctly even if year is negative.
Take care to avoid int overflow. time_t overflow is OK, since
only the low order bits of the correct time_t answer are needed.
Don't convert to time_t until after all divisions are done, since
time_t might be unsigned. */
int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
int a100 = a4 / 25 - (a4 % 25 < 0);
int b100 = b4 / 25 - (b4 % 25 < 0);
int a400 = a100 >> 2;
int b400 = b100 >> 2;
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
time_t years = year - (time_t) tp->tm_year;
time_t days = (365 * years + intervening_leap_days
+ (yday - tp->tm_yday));
return (60 * (60 * (24 * days + (hour - tp->tm_hour))
+ (min - tp->tm_min))
+ (sec - tp->tm_sec));
}
static time_t localtime_offset;
/* Convert *TP to a time_t value. */
time_t
mktime (tp)
struct tm *tp;
{
#ifdef _LIBC
/* POSIX.1 8.1.1 requires that whenever mktime() is called, the
time zone names contained in the external variable `tzname' shall
be set as if the tzset() function had been called. */
__tzset ();
#endif
return __mktime_internal (tp, my_localtime_r, &localtime_offset);
}
/* Convert *TP to a time_t value, inverting
the monotonic and mostly-unit-linear conversion function CONVERT.
Use *OFFSET to keep track of a guess at the offset of the result,
compared to what the result would be for UTC without leap seconds.
If *OFFSET's guess is correct, only one CONVERT call is needed. */
time_t
__mktime_internal (tp, convert, offset)
struct tm *tp;
struct tm *(*convert) __P ((const time_t *, struct tm *));
time_t *offset;
{
time_t t, dt, t0;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
to handle any combinations of time zone rule changes, solar time,
and leap seconds. Posix.1 prohibits leap seconds, but some hosts
have them anyway. */
int remaining_probes = 4;
/* Time requested. Copy it in case CONVERT modifies *TP; this can
occur if TP is localtime's returned value and CONVERT is localtime. */
int sec = tp->tm_sec;
int min = tp->tm_min;
int hour = tp->tm_hour;
int mday = tp->tm_mday;
int mon = tp->tm_mon;
int year_requested = tp->tm_year;
int isdst = tp->tm_isdst;
/* Ensure that mon is in range, and set year accordingly. */
int mon_remainder = mon % 12;
int negative_mon_remainder = mon_remainder < 0;
int mon_years = mon / 12 - negative_mon_remainder;
int year = year_requested + mon_years;
/* The other values need not be in range:
the remaining code handles minor overflows correctly,
assuming int and time_t arithmetic wraps around.
Major overflows are caught at the end. */
/* Calculate day of year from year, month, and day of month.
The result need not be in range. */
int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
[mon_remainder + 12 * negative_mon_remainder])
+ mday - 1);
#if LEAP_SECONDS_POSSIBLE
/* Handle out-of-range seconds specially,
since ydhms_tm_diff assumes every minute has 60 seconds. */
int sec_requested = sec;
if (sec < 0)
sec = 0;
if (59 < sec)
sec = 59;
#endif
/* Invert CONVERT by probing. First assume the same offset as last time.
Then repeatedly use the error to improve the guess. */
tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
for (t = t0 + *offset;
(dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
t += dt)
if (--remaining_probes == 0)
return -1;
/* Check whether tm.tm_isdst has the requested value, if any. */
if (0 <= isdst && 0 <= tm.tm_isdst)
{
int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
if (dst_diff)
{
/* Move two hours in the direction indicated by the disagreement,
probe some more, and switch to a new time if found.
The largest known fallback due to daylight savings is two hours:
once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
time_t ot = t - 2 * 60 * 60 * dst_diff;
while (--remaining_probes != 0)
{
struct tm otm;
if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
(*convert) (&ot, &otm))))
{
t = ot;
tm = otm;
break;
}
if ((ot += dt) == t)
break; /* Avoid a redundant probe. */
}
}
}
*offset = t - t0;
#if LEAP_SECONDS_POSSIBLE
if (sec_requested != tm.tm_sec)
{
/* Adjust time to reflect the tm_sec requested, not the normalized value.
Also, repair any damage from a false match due to a leap second. */
t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
(*convert) (&t, &tm);
}
#endif
if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
{
/* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
so check for major overflows. A gross check suffices,
since if t has overflowed, it is off by a multiple of
TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
the difference that is bounded by a small value. */
double dyear = (double) year_requested + mon_years - tm.tm_year;
double dday = 366 * dyear + mday;
double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
return -1;
}
*tp = tm;
return t;
}
#ifdef weak_alias
weak_alias (mktime, timelocal)
#endif
#if DEBUG
static int
not_equal_tm (a, b)
struct tm *a;
struct tm *b;
{
return ((a->tm_sec ^ b->tm_sec)
| (a->tm_min ^ b->tm_min)
| (a->tm_hour ^ b->tm_hour)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_mon ^ b->tm_mon)
| (a->tm_year ^ b->tm_year)
| (a->tm_mday ^ b->tm_mday)
| (a->tm_yday ^ b->tm_yday)
| (a->tm_isdst ^ b->tm_isdst));
}
static void
print_tm (tp)
struct tm *tp;
{
printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
tp->tm_hour, tp->tm_min, tp->tm_sec,
tp->tm_yday, tp->tm_wday, tp->tm_isdst);
}
static int
check_result (tk, tmk, tl, tml)
time_t tk;
struct tm tmk;
time_t tl;
struct tm tml;
{
if (tk != tl || not_equal_tm (&tmk, &tml))
{
printf ("mktime (");
print_tm (&tmk);
printf (")\nyields (");
print_tm (&tml);
printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
return 1;
}
return 0;
}
int
main (argc, argv)
int argc;
char **argv;
{
int status = 0;
struct tm tm, tmk, tml;
time_t tk, tl;
char trailer;
if ((argc == 3 || argc == 4)
&& (sscanf (argv[1], "%d-%d-%d%c",
&tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer)
== 3)
&& (sscanf (argv[2], "%d:%d:%d%c",
&tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer)
== 3))
{
tm.tm_year -= TM_YEAR_BASE;
tm.tm_mon--;
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
tmk = tm;
tl = mktime (&tmk);
tml = *localtime (&tl);
printf ("mktime returns %ld == ", (long) tl);
print_tm (&tmk);
printf ("\n");
status = check_result (tl, tmk, tl, tml);
}
else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
{
time_t from = atol (argv[1]);
time_t by = atol (argv[2]);
time_t to = atol (argv[3]);
if (argc == 4)
for (tl = from; tl <= to; tl += by)
{
tml = *localtime (&tl);
tmk = tml;
tk = mktime (&tmk);
status |= check_result (tk, tmk, tl, tml);
}
else
for (tl = from; tl <= to; tl += by)
{
/* Null benchmark. */
tml = *localtime (&tl);
tmk = tml;
tk = tl;
status |= check_result (tk, tmk, tl, tml);
}
}
else
printf ("Usage:\
\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\
\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\
\t%s FROM BY TO - # Do not test those values (for benchmark).\n",
argv[0], argv[0], argv[0]);
return status;
}
#endif /* DEBUG */
/*
Local Variables:
compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
End:
*/
-9782
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -1,9 +0,0 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
export THIS_SH PATH
rm -f /tmp/xx
/bin/sh "$@"
-260
View File
@@ -1,260 +0,0 @@
# first, let's start with the basics
recho "$@"
recho "$*"
recho $@
recho $*
set a b
recho "$*"
# If IFS is null, the parameters are joined without separators
IFS=''
recho "$*"
# If IFS is unset, the parameters are separated by spaces
unset IFS
recho "${*}"
recho "$@"
recho $@
IFS='/'
set bob 'tom dick harry' joe
set $*
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set ${*}
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set $@
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set ${@}
recho $#
recho $1
recho $2
recho $3
# according to POSIX.2, unquoted $* should expand to multiple words if
# $IFS is null, just like unquoted $@
IFS=''
set bob 'tom dick harry' joe
set $*
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set $@
recho $#
recho $1
recho $2
recho $3
# if IFS is unset, the individual positional parameters are split on
# " \t\n" if $* or $@ are unquoted
unset IFS
set bob 'tom dick harry' joe
set $*
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set $@
recho $#
recho $1
recho $2
recho $3
# but not for "$@" or "$*"
set bob 'tom dick harry' joe
set "$*"
recho $#
recho $1
recho $2
recho $3
set bob 'tom dick harry' joe
set "$@"
recho $#
recho $1
recho $2
recho $3
# POSIX.2 says these should both expand the positional parameters
# to multiple words
set a b c d e
IFS=""
recho $@
recho "$@"
# this example is straight from the POSIX.2 rationale
set foo bar bam
recho "$@"
recho "$*"
unset IFS
recho "$@"
recho $@
recho "$*"
IFS=:
# special variables
set -- 1 2 3 4 5 6 7 8 9 10
bar=${*}
foo=$*
echo foo = "$foo"
echo bar = "$bar"
foo1=$@
bar1=${@}
echo foo1 = "$foo1"
echo bar1 = "$bar1"
foo2="$*"
bar2="${*}"
echo foo2 = "$foo2"
echo bar2 = "$bar2"
eval foo3='$*' bar3='${*}'
echo foo3 = "$foo3"
echo bar3 = "$bar3"
case $* in
*\:*) echo ok 1;;
*) echo bad 1;;
esac
case $@ in
*\:*) echo bad 2;;
*) echo ok 2;;
esac
case "$*" in
*\:*) echo ok 3;;
*) echo bad 3;;
esac
case "$@" in
*\:*) echo bad 4;;
*) echo ok 4;;
esac
IFS=$' \t\n'
bar=${*}
foo=$*
echo foo = "$foo"
echo bar = "$bar"
foo1=$@
bar1=${@}
echo foo1 = "$foo1"
echo bar1 = "$bar1"
foo2="$*"
bar2="${*}"
echo foo2 = "$foo2"
echo bar2 = "$bar2"
eval foo3='$*' bar3='${*}'
echo foo3 = "$foo3"
echo bar3 = "$bar3"
case $* in
*\ *) echo ok 1;;
*) echo bad 1;;
esac
case $@ in
*\ *) echo ok 2;;
*) echo bad 2;;
esac
case "$*" in
*\ *) echo ok 3;;
*) echo bad 3;;
esac
case "$@" in
*\ *) echo ok 4;;
*) echo bad 4;;
esac
# tests for the effect of quoting $* and $@ in an assignment context (plus
# arrays) -- bugs through bash 4.2
${THIS_SH} ./dollar-at-star1.sub
# tests for special expansion of "$*" and "${array[*]}" when used with other
# expansions -- bugs through bash-2.05b
${THIS_SH} ./dollar-star1.sub
# tests for expansion of "$@" on rhs of things like ${param:+word}. Bugs
# though bash-2.05b
${THIS_SH} ./dollar-at1.sub
# tests for expansion of other variables in double-quoted strings containing
# $@. Bugs through bash-2.05b
${THIS_SH} ./dollar-at2.sub
# tests for various expansions of $* in different contexts -- word split,
# no splitting, etc. when $IFS is NUL
${THIS_SH} ./dollar-star2.sub
# tests for expansions of "${array[*]}" and "${array[@]}" when $IFS is not the
# default and the array contains null elements
${THIS_SH} ./dollar-star3.sub
# test for set -u and expansions of $@ when there are no positional parameters
${THIS_SH} ./dollar-at3.sub
# test for set -u and expansions of $* when there are no positional parameters
${THIS_SH} ./dollar-star4.sub
# tests for expansions of $* when IFS is null
${THIS_SH} ./dollar-star5.sub
# tests for inappropriate word splitting through bash-4.2
${THIS_SH} ./dollar-at4.sub
# tests for problems with "$@" preceded and followed by other quoted expansions
# through bash-4.2
${THIS_SH} ./dollar-at5.sub
# tests for problems with "${@:1}" and other expansions with null entries
# in positional parameters
${THIS_SH} ./dollar-at6.sub
# tests for expansions of $* when $1 == ""; problem through bash-4.2
${THIS_SH} ./dollar-star6.sub
# tests for expansions of $* (unquoted) when IFS changes (e.g., ${IFS:=-})
# problem through bash-4.2
${THIS_SH} ./dollar-star7.sub
exit 0
-50
View File
@@ -1,50 +0,0 @@
:; ./shx
sh:
<&$fd ok
nlbq Mon Aug 3 02:45:00 EDT 1992
bang geoff
quote 712824302
setbq defmsgid=<1992Aug3.024502.6176@host>
bgwait sleep done... wait 6187
bash:
<&$fd ok
nlbq Mon Aug 3 02:45:09 EDT 1992
bang geoff
quote 712824311
setbq defmsgid=<1992Aug3.024512.6212@host>
bgwait sleep done... wait 6223
ash:
<&$fd shx1: 4: Syntax error: Bad fd number
nlbq Mon Aug 3 02:45:19 EDT 1992
bang geoff
quote getdate: `"now"' not a valid date
setbq defmsgid=<1992Aug3.` echo 024521
bgwait sleep done... wait 6241
ksh:
<&$fd ok
nlbq ./shx: 6248 Memory fault - core dumped
bang geoff
quote getdate: `"now"' not a valid date
setbq defmsgid=<1992Aug3.024530.6257@host>
bgwait no such job: 6265
wait 6265
sleep done...
zsh:
<&$fd ok
nlbq Mon Aug 3 02:45:36 EDT 1992
bang shx3: event not found: /s/ [4]
quote 712824337
setbq defmsgid=<..6290@host>
bgwait shx7: unmatched " [9]
sleep done...
:;
-10
View File
@@ -1,10 +0,0 @@
#! /bin/sh
for cmd in sh bash ash ksh zsh
do
echo
echo $cmd:
for demo in shx?
do
$cmd $demo
done
done