bash-20120525 remove leftover and stray files

This commit is contained in:
Chet Ramey
2012-06-05 10:18:28 -04:00
parent 348a457e59
commit 61916bdc60
28 changed files with 0 additions and 57382 deletions
-13892
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 */
-1213
View File
File diff suppressed because it is too large Load Diff
-1115
View File
File diff suppressed because it is too large Load Diff
-514
View File
@@ -1,514 +0,0 @@
This file is setattr.def, from which is created setattr.c.
It implements the builtins "export" and "readonly", in Bash.
Copyright (C) 1987-2010 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 setattr.c
#include <config.h>
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
# include <sys/types.h>
# endif
# include <unistd.h>
#endif
#include <stdio.h>
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "common.h"
#include "bashgetopt.h"
extern int posixly_correct;
extern int array_needs_making;
extern char *this_command_name;
extern sh_builtin_func_t *this_shell_builtin;
#ifdef ARRAY_VARS
extern int declare_builtin __P((WORD_LIST *));
#endif
#define READONLY_OR_EXPORT \
(this_shell_builtin == readonly_builtin || this_shell_builtin == export_builtin)
$BUILTIN export
$FUNCTION export_builtin
$SHORT_DOC export [-fn] [name[=value] ...] or export -p
Set export attribute for shell variables.
Marks each NAME for automatic export to the environment of subsequently
executed commands. If VALUE is supplied, assign VALUE before exporting.
Options:
-f refer to shell functions
-n remove the export property from each NAME
-p display a list of all exported variables and functions
An argument of `--' disables further option processing.
Exit Status:
Returns success unless an invalid option is given or NAME is invalid.
$END
/* For each variable name in LIST, make that variable appear in the
environment passed to simple commands. If there is no LIST, then
print all such variables. An argument of `-n' says to remove the
exported attribute from variables named in LIST. An argument of
-f indicates that the names present in LIST refer to functions. */
int
export_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_exported, 0));
}
$BUILTIN readonly
$FUNCTION readonly_builtin
$SHORT_DOC readonly [-aAf] [name[=value] ...] or readonly -p
Mark shell variables as unchangeable.
Mark each NAME as read-only; the values of these NAMEs may not be
changed by subsequent assignment. If VALUE is supplied, assign VALUE
before marking as read-only.
Options:
-a refer to indexed array variables
-A refer to associative array variables
-f refer to shell functions
-p display a list of all readonly variables and functions
An argument of `--' disables further option processing.
Exit Status:
Returns success unless an invalid option is given or NAME is invalid.
$END
/* For each variable name in LIST, make that variable readonly. Given an
empty LIST, print out all existing readonly variables. */
int
readonly_builtin (list)
register WORD_LIST *list;
{
return (set_or_show_attributes (list, att_readonly, 0));
}
#if defined (ARRAY_VARS)
# define ATTROPTS "aAfnp"
#else
# define ATTROPTS "fnp"
#endif
/* For each variable name in LIST, make that variable have the specified
ATTRIBUTE. An arg of `-n' says to remove the attribute from the the
remaining names in LIST (doesn't work for readonly). */
int
set_or_show_attributes (list, attribute, nodefs)
register WORD_LIST *list;
int attribute, nodefs;
{
register SHELL_VAR *var;
int assign, undo, any_failed, assign_error, opt;
int functions_only, arrays_only, assoc_only;
int aflags;
char *name;
#if defined (ARRAY_VARS)
WORD_LIST *nlist, *tlist;
WORD_DESC *w;
#endif
functions_only = arrays_only = assoc_only = 0;
undo = any_failed = assign_error = 0;
/* Read arguments from the front of the list. */
reset_internal_getopt ();
while ((opt = internal_getopt (list, ATTROPTS)) != -1)
{
switch (opt)
{
case 'n':
undo = 1;
break;
case 'f':
functions_only = 1;
break;
#if defined (ARRAY_VARS)
case 'a':
arrays_only = 1;
break;
case 'A':
assoc_only = 1;
break;
#endif
case 'p':
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
list = loptend;
if (list)
{
if (attribute & att_exported)
array_needs_making = 1;
/* Cannot undo readonly status, silently disallowed. */
if (undo && (attribute & att_readonly))
attribute &= ~att_readonly;
while (list)
{
name = list->word->word;
if (functions_only) /* xxx -f name */
{
var = find_function (name);
if (var == 0)
{
builtin_error (_("%s: not a function"), name);
any_failed++;
}
else
SETVARATTR (var, attribute, undo);
list = list->next;
continue;
}
/* xxx [-np] name[=value] */
assign = assignment (name, 0);
aflags = 0;
if (assign)
{
name[assign] = '\0';
if (name[assign - 1] == '+')
{
aflags |= ASS_APPEND;
name[assign - 1] = '\0';
}
}
if (legal_identifier (name) == 0)
{
sh_invalidid (name);
if (assign)
assign_error++;
else
any_failed++;
list = list->next;
continue;
}
if (assign) /* xxx [-np] name=value */
{
name[assign] = '=';
if (aflags & ASS_APPEND)
name[assign - 1] = '+';
#if defined (ARRAY_VARS)
/* Let's try something here. Turn readonly -a xxx=yyy into
declare -ra xxx=yyy and see what that gets us. */
if (arrays_only || assoc_only)
{
tlist = list->next;
list->next = (WORD_LIST *)NULL;
w = arrays_only ? make_word ("-ra") : make_word ("-rA");
nlist = make_word_list (w, list);
opt = declare_builtin (nlist);
if (opt != EXECUTION_SUCCESS)
assign_error++;
list->next = tlist;
dispose_word (w);
free (nlist);
}
else
#endif
/* This word has already been expanded once with command
and parameter expansion. Call do_assignment_no_expand (),
which does not do command or parameter substitution. If
the assignment is not performed correctly, flag an error. */
if (do_assignment_no_expand (name) == 0)
assign_error++;
name[assign] = '\0';
if (aflags & ASS_APPEND)
name[assign - 1] = '\0';
}
set_var_attribute (name, attribute, undo);
list = list->next;
}
}
else
{
SHELL_VAR **variable_list;
register int i;
if ((attribute & att_function) || functions_only)
{
variable_list = all_shell_functions ();
if (attribute != att_function)
attribute &= ~att_function; /* so declare -xf works, for example */
}
else
variable_list = all_shell_variables ();
#if defined (ARRAY_VARS)
if (attribute & att_array)
{
arrays_only++;
if (attribute != att_array)
attribute &= ~att_array;
}
else if (attribute & att_assoc)
{
assoc_only++;
if (attribute != att_assoc)
attribute &= ~att_assoc;
}
#endif
if (variable_list)
{
for (i = 0; var = variable_list[i]; i++)
{
#if defined (ARRAY_VARS)
if (arrays_only && array_p (var) == 0)
continue;
else if (assoc_only && assoc_p (var) == 0)
continue;
#endif
if ((var->attributes & attribute))
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
}
free (variable_list);
}
}
return (assign_error ? EX_BADASSIGN
: ((any_failed == 0) ? EXECUTION_SUCCESS
: EXECUTION_FAILURE));
}
/* Show all variable variables (v == 1) or functions (v == 0) with
attributes. */
int
show_all_var_attributes (v, nodefs)
int v, nodefs;
{
SHELL_VAR **variable_list, *var;
int any_failed;
register int i;
variable_list = v ? all_shell_variables () : all_shell_functions ();
if (variable_list == 0)
return (EXECUTION_SUCCESS);
for (i = any_failed = 0; var = variable_list[i]; i++)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
free (variable_list);
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Show the attributes for shell variable VAR. If NODEFS is non-zero,
don't show function definitions along with the name. If PATTR is
non-zero, it indicates we're being called from `export' or `readonly'.
In POSIX mode, this prints the name of the calling builtin (`export'
or `readonly') instead of `declare', and doesn't print function defs
when called by `export' or `readonly'. */
int
show_var_attributes (var, pattr, nodefs)
SHELL_VAR *var;
int pattr, nodefs;
{
char flags[16], *x;
int i;
i = 0;
/* pattr == 0 means we are called from `declare'. */
if (pattr == 0 || posixly_correct == 0)
{
#if defined (ARRAY_VARS)
if (array_p (var))
flags[i++] = 'a';
if (assoc_p (var))
flags[i++] = 'A';
#endif
if (function_p (var))
flags[i++] = 'f';
if (integer_p (var))
flags[i++] = 'i';
if (readonly_p (var))
flags[i++] = 'r';
if (trace_p (var))
flags[i++] = 't';
if (exported_p (var))
flags[i++] = 'x';
if (capcase_p (var))
flags[i++] = 'c';
if (lowercase_p (var))
flags[i++] = 'l';
if (uppercase_p (var))
flags[i++] = 'u';
}
else
{
#if defined (ARRAY_VARS)
if (array_p (var))
flags[i++] = 'a';
if (assoc_p (var))
flags[i++] = 'A';
#endif
if (function_p (var))
flags[i++] = 'f';
}
flags[i] = '\0';
/* If we're printing functions with definitions, print the function def
first, then the attributes, instead of printing output that can't be
reused as input to recreate the current state. */
if (function_p (var) && nodefs == 0 && (pattr == 0 || posixly_correct == 0))
{
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
nodefs++;
if (pattr == 0 && i == 1 && flags[0] == 'f')
return 0; /* don't print `declare -f name' */
}
if (pattr == 0 || posixly_correct == 0)
printf ("declare -%s ", i ? flags : "-");
else if (i)
printf ("%s -%s ", this_command_name, flags);
else
printf ("%s ", this_command_name);
#if defined (ARRAY_VARS)
if (array_p (var))
print_array_assignment (var, 1);
else if (assoc_p (var))
print_assoc_assignment (var, 1);
else
#endif
/* force `readonly' and `export' to not print out function definitions
when in POSIX mode. */
if (nodefs || (function_p (var) && pattr != 0 && posixly_correct))
printf ("%s\n", var->name);
else if (function_p (var))
printf ("%s\n", named_function_string (var->name, function_cell (var), FUNC_MULTILINE|FUNC_EXTERNAL));
else if (invisible_p (var) || var_isset (var) == 0)
printf ("%s\n", var->name);
else
{
x = sh_double_quote (value_cell (var));
printf ("%s=%s\n", var->name, x);
free (x);
}
return (0);
}
int
show_name_attributes (name, nodefs)
char *name;
int nodefs;
{
SHELL_VAR *var;
var = find_variable_internal (name, 1);
if (var && invisible_p (var) == 0)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
}
else
return (1);
}
void
set_var_attribute (name, attribute, undo)
char *name;
int attribute, undo;
{
SHELL_VAR *var, *tv;
char *tvalue;
if (undo)
var = find_variable (name);
else
{
tv = find_tempenv_variable (name);
/* XXX -- need to handle case where tv is a temp variable in a
function-scope context, since function_env has been merged into
the local variables table. */
if (tv && tempvar_p (tv))
{
tvalue = var_isset (tv) ? savestring (value_cell (tv)) : savestring ("");
var = bind_variable (tv->name, tvalue, 0);
var->attributes |= tv->attributes & ~att_tempvar;
VSETATTR (tv, att_propagate);
if (var->context != 0)
VSETATTR (var, att_propagate);
SETVARATTR (tv, attribute, undo); /* XXX */
stupidly_hack_special_variables (tv->name);
free (tvalue);
}
else
{
var = find_variable_internal (name, 0);
if (var == 0)
{
var = bind_variable (name, (char *)NULL, 0);
VSETATTR (var, att_invisible);
}
else if (var->context != 0)
VSETATTR (var, att_propagate);
}
}
if (var)
SETVARATTR (var, attribute, undo);
if (var && (exported_p (var) || (attribute & att_exported)))
array_needs_making++; /* XXX */
}
-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
-1745
View File
File diff suppressed because it is too large Load Diff
-10138
View File
File diff suppressed because it is too large Load Diff
-8494
View File
File diff suppressed because it is too large Load Diff
-22
View File
@@ -1,22 +0,0 @@
@ignore
Copyright (C) 1988-2012 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Sat Apr 7 20:02:15 EDT 2012
@set EDITION 4.2
@set VERSION 4.2
@set UPDATED 7 April 2012
@set UPDATED-MONTH April 2012
-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
-549
View File
@@ -1,549 +0,0 @@
#!/bin/bash
# ash -- "Adventure shell"
# last edit: 86/04/21 D A Gwyn
# SCCS ID: @(#)ash.sh 1.4
OPATH=$PATH
ask()
{
echo -n "$@" '[y/n] '
read ans
case "$ans" in
y*|Y*)
return 0
;;
*)
return 1
;;
esac
}
CAT=${PAGER:-more}
ash_inst()
{
cat <<- EOF
Instructions for the Adventure shell
Welcome to the Adventure shell! In this exploration of the UNIX file
system, I will act as your eyes and hands. As you move around, I will
describe whatever is visible and will carry out your commands. The
general form of a command is
Verb Object Extra_stuff.
Most commands pay no attention to the "Extra_stuff", and many do not
need an "Object". A typical command is
get all
which picks up all files in the current "room" (directory). You can
find out what you are carrying by typing the command
inventory
The command "help" results in a full description of all commands that I
understand. To quit the Adventure shell, type
quit
There are UNIX monsters lurking in the background. These are also
known as "commands with arguments".
Good luck!
EOF
}
ash_help()
{
echo "I understand the following commands (synonyms in parentheses):"
echo ""
echo "change OBJECT to NEW_NAME changes the name of the object"
echo "clone OBJECT as NEW_NAME duplicates the object"
echo "drop OBJECTS leaves the objects in the room"
echo "enter (go) PASSAGE takes the labeled passage"
echo "examine OBJECTS describes the objects in detail"
echo "feed OBJECT to MONSTER stuffs the object into a UNIX monster"
echo "get (take) OBJECTS picks up the specified objects"
echo "gripe (bug) report a problem with the Adventure shell"
echo "help prints this summary"
echo "inventory (i) tells what you are carrying"
echo "kill (destroy) OBJECTS destroys the objects"
echo "look (l) describes the room, including hidden objects"
echo "open (read) OBJECT shows the contents of an object"
echo "quit (exit) leaves the Adventure shell"
echo "resurrect OBJECTS attempts to restore dead objects"
echo "steal OBJECT from MONSTER obtains the object from a UNIX monster"
echo "throw OBJECT at daemon feeds the object to the printer daemon"
echo "up takes the overhead passage"
echo "wake MONSTER awakens a UNIX monster"
echo "where (w) tells you where you are"
echo "xyzzy moves you to your home"
}
MAINT=chet@ins.cwru.edu
PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin:.
export PATH
trap 'echo Ouch!' 2 3
#trap '' 18 # disable Berkeley job control
ash_lk(){ echo " $1 " | fgrep " $2 " >&- 2>&-; }
ash_pr(){ echo $* | tr ' ' '\012' | pr -5 -t -w75 -l$[ ( $# + 4 ) / 5 ]; }
ash_rm(){ echo " $1 " | sed -e "s/ $2 / /" -e 's/^ //' -e 's/ $//'; }
# enable history, bang history expansion, and emacs editing
set -o history
set -o histexpand
set -o emacs
cd
LIM=.limbo # $HOME/$LIM contains "destroyed" objects
mkdir $LIM >&- 2>&-
KNAP=.knapsack # $HOME/$KNAP contains objects being "carried"
if [ ! -d $KNAP ]
then mkdir $KNAP >&- 2>&-
if [ $? = 0 ]
then echo 'You found a discarded empty knapsack.'
else echo 'You have no knapsack to carry things in.'
exit 1
fi
else echo 'One moment while I peek in your old knapsack...'
fi
kn=`echo \`ls -a $KNAP | sed -e '/^\.$/d' -e '/^\.\.$/d'\``
if ask 'Welcome to the Adventure shell! Do you need instructions?'
then
ash_inst
echo -n 'Type a newline to continue: '
read
fi
wiz=false
cha=false
prev=$LIM
while :
do room=`pwd`
if [ $room != $prev ]
then if [ $room = $HOME ]
then echo 'You are in your own home.'
else echo "You have entered $room."
fi
exs=
obs=
hexs=
hobs=
f=false
for i in `ls -a`
do case $i in
.|..) ;;
.*) if [ -f $i ]
then hobs="$hobs $i"
elif [ -d $i ]
then hexs="$hexs $i"
else f=true
fi
;;
*) if [ -f $i ]
then obs="$obs $i"
elif [ -d $i ]
then exs="$exs $i"
else f=true
fi
;;
esac
done
if [ "$obs" ]
then echo 'This room contains:'
ash_pr $obs
else echo 'The room looks empty.'
fi
if [ "$exs" ]
then echo 'There are exits labeled:'
ash_pr $exs
echo 'as well as a passage overhead.'
else echo 'There is a passage overhead.'
fi
if sh -c $f
then echo 'There are shadowy figures in the corner.'
fi
prev=$room
fi
read -e -p '-advsh> ' verb obj x # prompt is '-advsh> '
if [ $? != 0 ]
then verb=quit # EOF
fi
case $verb in
change) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then set -- $x
case "$1" in
to) if [ "$2" ]
then if [ -f $2 ]
then echo "You must destroy $2 first."
set --
fi
if [ "$2" ]
then if mv $obj $2 >&- 2>&-
then echo "The $obj shimmers and turns into $2."
obs=`ash_rm "$2 $obs" "$obj"`
else echo "There is a cloud of smoke but the $obj is unchanged."
fi
fi
else echo 'To what?'
fi
;;
*) echo "Change $obj to what?"
;;
esac
else if ash_lk "$kn" "$obj"
then echo 'You must drop it first.'
else echo "I see no $obj here."
fi
fi
else echo 'Change what?'
fi
;;
clone) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then if [ ! -r $obj ]
then echo "The $obj does not wish to be cloned."
else set -- $x
case "$1" in
as) if [ "$2" ]
then if [ -f $2 ]
then echo "You must destroy $2 first."
else if cp $obj $2 >&- 2>&-
then echo "Poof! When the smoke clears, you see the new $2."
obs="$obs $2"
else echo 'You hear a dull thud but no clone appears.'
fi
fi
else echo 'As what?'
fi
;;
*) echo "Clone $obj as what?"
;;
esac
fi
else if ash_lk "$kn" "$obj"
then echo 'You must drop it first.'
else echo "I see no $obj here."
fi
fi
else echo 'Clone what?'
fi
;;
drop) if [ "$obj" ]
then for it in $obj $x
do if ash_lk "$kn" "$it"
then if [ -w $it ]
then echo "You must destroy $it first."
else if mv $HOME/$KNAP/$it $it >&- 2>&-
then echo "$it: dropped."
kn=`ash_rm "$kn" "$it"`
obs=`echo $it $obs`
else echo "The $it is caught in your knapsack."
fi
fi
else echo "You're not carrying the $it!"
fi
done
else echo 'Drop what?'
fi
;;
enter|go) if [ "$obj" ]
then if [ $obj != up ]
then if ash_lk "$exs $hexs" "$obj"
then if [ -x $obj ]
then if cd $obj
then echo 'You squeeze through the passage.'
else echo "You can't go that direction."
fi
else echo 'An invisible force blocks your way.'
fi
else echo 'I see no such passage.'
fi
else if cd ..
then echo 'You struggle upwards.'
else echo "You can't reach that high."
fi
fi
else echo 'Which passage?'
fi
;;
examine) if [ "$obj" ]
then if [ $obj = all ]
then $obj=`echo $obs $exs`
x=
fi
for it in $obj $x
do if ash_lk "$obs $hobs $exs $hexs" "$it"
then echo "Upon close inspection of the $it, you see:"
ls -ld $it 2>&-
if [ $? != 0 ]
then echo "-- when you look directly at the $it, it vanishes."
fi
else if ash_lk "$kn" "$it"
then echo 'You must drop it first.'
else echo "I see no $it here."
fi
fi
done
else echo 'Examine what?'
fi
;;
feed) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then set -- $x
case "$1" in
to) if [ "$2" ]
then shift
if PATH=$OPATH $* <$obj 2>&-
then echo "The $1 monster devours your $obj."
if rm -f $obj >&- 2>&-
then obs=`ash_rm "$obs" "$obj"`
else echo 'But he spits it back up.'
fi
else echo "The $1 monster holds his nose in disdain."
fi
else echo 'To what?'
fi
;;
*) echo "Feed $obj to what?"
;;
esac
else if ash_lk "$kn" "$obj"
then echo 'You must drop it first.'
else echo "I see no $obj here."
fi
fi
else echo 'Feed what?'
fi
;;
get|take) if [ "$obj" ]
then if [ $obj = all ]
then obj="$obs"
x=
fi
for it in $obj $x
do if ash_lk "$obs $hobs" "$it"
then if ash_lk "$kn" "$it"
then echo 'You already have one.'
else if mv $it $HOME/$KNAP/$it >&- 2>&-
then echo "$it: taken."
kn="$it $kn"
obs=`ash_rm "$obs" "$it"`
else echo "The $it is too heavy."
fi
fi
else echo "I see no $it here."
fi
done
else echo 'Get what?'
fi
;;
gripe|bug) echo 'Please describe the problem and your situation at the time it failed.\nEnd the bug report with a line containing just a Ctrl-D.'
cat | mail $MAINT -s 'ash bug'
echo 'Thank you!'
;;
help) ash_help
;;
inventory|i) if [ "$kn" ]
then echo 'Your knapsack contains:'
ash_pr $kn
else echo 'You are poverty-stricken.'
fi
;;
kill|destroy) if [ "$obj" ]
then if [ $obj = all ]
then x=
if ask "Do you really want to attempt to $verb them all?"
then obj=`echo $obs`
else echo 'Chicken!'
obj=
fi
fi
for it in $obj $x
do if ash_lk "$obs $hobs" "$it"
then if mv $it $HOME/$LIM <&- >&- 2>&-
then if [ $verb = kill ]
then echo "The $it cannot defend himself; he dies."
else echo "You have destroyed the $it; it vanishes."
fi
obs=`ash_rm "$obs" "$it"`
else if [ $verb = kill ]
then echo "Your feeble blows are no match for the $it."
else echo "The $it is indestructible."
fi
fi
else if ash_lk "$kn" "$it"
then echo "You must drop the $it first."
found=false
else echo "I see no $it here."
fi
fi
done
else echo 'Kill what?'
fi
;;
look|l) obs=`echo $obs $hobs`
hobs=
if [ "$obs" ]
then echo 'The room contains:'
ash_pr $obs
else echo 'The room is empty.'
fi
exs=`echo $exs $hexs`
hexs=
if [ "$exs" ]
then echo 'There are exits plainly labeled:'
ash_pr $exs
echo 'and a passage directly overhead.'
else echo 'The only exit is directly overhead.'
fi
;;
magic) if [ "$obj" = mode ]
then if sh -c $cha
then echo 'You had your chance and you blew it.'
else if ask 'Are you a wizard?'
then echo -n 'Prove it! Say the magic word: '
read obj
if [ "$obj" = armadillo ]
then echo 'Yes, master!!'
wiz=true
else echo "Homie says: I don't think so"
cha=true
fi
else echo "I didn't think so."
fi
fi
else echo 'Nice try.'
fi
;;
open|read) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then if [ -r $obj ]
then if [ -s $obj ]
then echo "Opening the $obj reveals:"
$CAT < $obj
if [ $? != 0 ]
then echo '-- oops, you lost the contents!'
fi
else echo "There is nothing inside the $obj."
fi
else echo "You do not have the proper tools to open the $obj."
fi
else if ash_lk "$kn" "$obj"
then echo 'You must drop it first.'
found=false
else echo "I see no $obj here."
fi
fi
else echo 'Open what?'
fi
;;
quit|exit) if ask 'Do you really want to quit now?'
then if [ "$kn" ]
then echo 'The contents of your knapsack will still be there next time.'
fi
rm -rf $HOME/$LIM
echo 'See you later!'
exit 0
fi
;;
resurrect) if [ "$obj" ]
then for it in $obj $x
do if ash_lk "$obs $hobs" "$it"
then echo "The $it is already alive and well."
else if mv $HOME/$LIM/$it $it <&- >&- 2>&-
then echo "The $it staggers to his feet."
obs=`echo $it $obs`
else echo "There are sparks but no $it appears."
fi
fi
done
else echo 'Resurrect what?'
fi
;;
steal) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then echo 'There is already one here.'
else set -- $x
case "$1" in
from) if [ "$2" ]
then shift
if PATH=$OPATH $* >$obj 2>&-
then echo "The $1 monster drops the $obj."
obs=`echo $obj $obs`
else echo "The $1 monster runs away as you approach."
rm -f $obj >&- 2>&-
fi
else echo 'From what?'
fi
;;
*) echo "Steal $obj from what?"
;;
esac
fi
else echo 'Steal what?'
fi
;;
throw) if [ "$obj" ]
then if ash_lk "$obs $hobs" "$obj"
then set -- $x
case "$1" in
at) case "$2" in
daemon) if sh -c "lpr -r $obj"
then echo "The daemon catches the $obj, turns it into paper,\nand leaves it in the basket."
obs=`ash_rm "$obs" "$obj"`
else echo "The daemon is nowhere to be found."
fi
;;
*) echo 'At what?'
;;
esac
;;
*) echo "Throw $obj at what?"
;;
esac
else if ash_lk "$kn" "$obj"
then echo 'It is in your knapsack.'
found=false
else echo "I see no $obj here."
fi
fi
else echo 'Throw what?'
fi
;;
u|up) if cd ..
then echo 'You pull yourself up a level.'
else echo "You can't reach that high."
fi
;;
wake) if [ "$obj" ]
then echo "You awaken the $obj monster:"
PATH=$OPATH $obj $x
echo 'The monster slithers back into the darkness.'
else echo 'Wake what?'
fi
;;
w|where) echo "You are in $room."
;;
xyzzy) if cd
then echo 'A strange feeling comes over you.'
else echo 'Your spell fizzles out.'
fi
;;
*) if [ "$verb" ]
then if sh -c $wiz
then PATH=$OPATH $verb $obj $x
else echo "I don't know how to \"$verb\"."
echo 'Type "help" for assistance.'
fi
else echo 'Say something!'
fi
;;
esac
done
-622
View File
@@ -1,622 +0,0 @@
/* findcmd.c -- Functions to search for commands by name. */
/* Copyright (C) 1997-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"
#include <stdio.h>
#include "chartypes.h"
#include "bashtypes.h"
#if !defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "filecntl.h"
#include "posixstat.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include <errno.h>
#include "bashansi.h"
#include "memalloc.h"
#include "shell.h"
#include "flags.h"
#include "hashlib.h"
#include "pathexp.h"
#include "hashcmd.h"
#include "findcmd.h" /* matching prototypes and declarations */
#if !defined (errno)
extern int errno;
#endif
extern int posixly_correct;
/* Static functions defined and used in this file. */
static char *_find_user_command_internal __P((const char *, int));
static char *find_user_command_internal __P((const char *, int));
static char *find_user_command_in_path __P((const char *, char *, int));
static char *find_in_path_element __P((const char *, char *, int, int, struct stat *));
static char *find_absolute_program __P((const char *, int));
static char *get_next_path_element __P((char *, int *));
/* The file name which we would try to execute, except that it isn't
possible to execute it. This is the first file that matches the
name that we are looking for while we are searching $PATH for a
suitable one to execute. If we cannot find a suitable executable
file, then we use this one. */
static char *file_to_lose_on;
/* Non-zero if we should stat every command found in the hash table to
make sure it still exists. */
int check_hashed_filenames;
/* DOT_FOUND_IN_SEARCH becomes non-zero when find_user_command ()
encounters a `.' as the directory pathname while scanning the
list of possible pathnames; i.e., if `.' comes before the directory
containing the file of interest. */
int dot_found_in_search = 0;
/* Return some flags based on information about this file.
The EXISTS bit is non-zero if the file is found.
The EXECABLE bit is non-zero the file is executble.
Zero is returned if the file is not found. */
int
file_status (name)
const char *name;
{
struct stat finfo;
int r;
/* Determine whether this file exists or not. */
if (stat (name, &finfo) < 0)
return (0);
/* If the file is a directory, then it is not "executable" in the
sense of the shell. */
if (S_ISDIR (finfo.st_mode))
return (FS_EXISTS|FS_DIRECTORY);
r = FS_EXISTS;
#if defined (HAVE_EACCESS)
/* Use eaccess(2) if we have it to take things like ACLs and other
file access mechanisms into account. eaccess uses the effective
user and group IDs, not the real ones. We could use sh_eaccess,
but we don't want any special treatment for /dev/fd. */
if (eaccess (name, X_OK) == 0)
r |= FS_EXECABLE;
if (eaccess (name, R_OK) == 0)
r |= FS_READABLE;
return r;
#elif defined (AFS)
/* We have to use access(2) to determine access because AFS does not
support Unix file system semantics. This may produce wrong
answers for non-AFS files when ruid != euid. I hate AFS. */
if (access (name, X_OK) == 0)
r |= FS_EXECABLE;
if (access (name, R_OK) == 0)
r |= FS_READABLE;
return r;
#else /* !HAVE_EACCESS && !AFS */
/* Find out if the file is actually executable. By definition, the
only other criteria is that the file has an execute bit set that
we can use. The same with whether or not a file is readable. */
/* Root only requires execute permission for any of owner, group or
others to be able to exec a file, and can read any file. */
if (current_user.euid == (uid_t)0)
{
r |= FS_READABLE;
if (finfo.st_mode & S_IXUGO)
r |= FS_EXECABLE;
return r;
}
/* If we are the owner of the file, the owner bits apply. */
if (current_user.euid == finfo.st_uid)
{
if (finfo.st_mode & S_IXUSR)
r |= FS_EXECABLE;
if (finfo.st_mode & S_IRUSR)
r |= FS_READABLE;
}
/* If we are in the owning group, the group permissions apply. */
else if (group_member (finfo.st_gid))
{
if (finfo.st_mode & S_IXGRP)
r |= FS_EXECABLE;
if (finfo.st_mode & S_IRGRP)
r |= FS_READABLE;
}
/* Else we check whether `others' have permission to execute the file */
else
{
if (finfo.st_mode & S_IXOTH)
r |= FS_EXECABLE;
if (finfo.st_mode & S_IROTH)
r |= FS_READABLE;
}
return r;
#endif /* !AFS */
}
/* Return non-zero if FILE exists and is executable.
Note that this function is the definition of what an
executable file is; do not change this unless YOU know
what an executable file is. */
int
executable_file (file)
const char *file;
{
int s;
s = file_status (file);
#if defined EISDIR
if (s & FS_DIRECTORY)
errno = EISDIR; /* let's see if we can improve error messages */
#endif
return ((s & FS_EXECABLE) && ((s & FS_DIRECTORY) == 0));
}
int
is_directory (file)
const char *file;
{
return (file_status (file) & FS_DIRECTORY);
}
int
executable_or_directory (file)
const char *file;
{
int s;
s = file_status (file);
return ((s & FS_EXECABLE) || (s & FS_DIRECTORY));
}
/* Locate the executable file referenced by NAME, searching along
the contents of the shell PATH variable. Return a new string
which is the full pathname to the file, or NULL if the file
couldn't be found. If a file is found that isn't executable,
and that is the only match, then return that. */
char *
find_user_command (name)
const char *name;
{
return (find_user_command_internal (name, FS_EXEC_PREFERRED|FS_NODIRS));
}
/* Locate the file referenced by NAME, searching along the contents
of the shell PATH variable. Return a new string which is the full
pathname to the file, or NULL if the file couldn't be found. This
returns the first readable file found; designed to be used to look
for shell scripts or files to source. */
char *
find_path_file (name)
const char *name;
{
return (find_user_command_internal (name, FS_READABLE));
}
static char *
_find_user_command_internal (name, flags)
const char *name;
int flags;
{
char *path_list, *cmd;
SHELL_VAR *var;
/* Search for the value of PATH in both the temporary environments and
in the regular list of variables. */
if (var = find_variable_internal ("PATH", 1)) /* XXX could be array? */
path_list = value_cell (var);
else
path_list = (char *)NULL;
if (path_list == 0 || *path_list == '\0')
return (savestring (name));
cmd = find_user_command_in_path (name, path_list, flags);
return (cmd);
}
static char *
find_user_command_internal (name, flags)
const char *name;
int flags;
{
#ifdef __WIN32__
char *res, *dotexe;
dotexe = (char *)xmalloc (strlen (name) + 5);
strcpy (dotexe, name);
strcat (dotexe, ".exe");
res = _find_user_command_internal (dotexe, flags);
free (dotexe);
if (res == 0)
res = _find_user_command_internal (name, flags);
return res;
#else
return (_find_user_command_internal (name, flags));
#endif
}
/* Return the next element from PATH_LIST, a colon separated list of
paths. PATH_INDEX_POINTER is the address of an index into PATH_LIST;
the index is modified by this function.
Return the next element of PATH_LIST or NULL if there are no more. */
static char *
get_next_path_element (path_list, path_index_pointer)
char *path_list;
int *path_index_pointer;
{
char *path;
path = extract_colon_unit (path_list, path_index_pointer);
if (path == 0)
return (path);
if (*path == '\0')
{
free (path);
path = savestring (".");
}
return (path);
}
/* Look for PATHNAME in $PATH. Returns either the hashed command
corresponding to PATHNAME or the first instance of PATHNAME found
in $PATH. If (FLAGS&1) is non-zero, insert the instance of PATHNAME
found in $PATH into the command hash table. Returns a newly-allocated
string. */
char *
search_for_command (pathname, flags)
const char *pathname;
int flags;
{
char *hashed_file, *command;
int temp_path, st;
SHELL_VAR *path;
hashed_file = command = (char *)NULL;
/* If PATH is in the temporary environment for this command, don't use the
hash table to search for the full pathname. */
path = find_variable_internal ("PATH", 1);
temp_path = path && tempvar_p (path);
if (temp_path == 0 && path)
path = (SHELL_VAR *)NULL;
/* Don't waste time trying to find hashed data for a pathname
that is already completely specified or if we're using a command-
specific value for PATH. */
if (path == 0 && absolute_program (pathname) == 0)
hashed_file = phash_search (pathname);
/* If a command found in the hash table no longer exists, we need to
look for it in $PATH. Thank you Posix.2. This forces us to stat
every command found in the hash table. */
if (hashed_file && (posixly_correct || check_hashed_filenames))
{
st = file_status (hashed_file);
if ((st & (FS_EXISTS|FS_EXECABLE)) != (FS_EXISTS|FS_EXECABLE))
{
phash_remove (pathname);
free (hashed_file);
hashed_file = (char *)NULL;
}
}
if (hashed_file)
command = hashed_file;
else if (absolute_program (pathname))
/* A command containing a slash is not looked up in PATH or saved in
the hash table. */
command = savestring (pathname);
else
{
/* If $PATH is in the temporary environment, we've already retrieved
it, so don't bother trying again. */
if (temp_path)
{
command = find_user_command_in_path (pathname, value_cell (path),
FS_EXEC_PREFERRED|FS_NODIRS);
}
else
command = find_user_command (pathname);
if (command && hashing_enabled && temp_path == 0 && (flags & 1))
phash_insert ((char *)pathname, command, dot_found_in_search, 1); /* XXX fix const later */
}
return (command);
}
char *
user_command_matches (name, flags, state)
const char *name;
int flags, state;
{
register int i;
int path_index, name_len;
char *path_list, *path_element, *match;
struct stat dotinfo;
static char **match_list = NULL;
static int match_list_size = 0;
static int match_index = 0;
if (state == 0)
{
/* Create the list of matches. */
if (match_list == 0)
{
match_list_size = 5;
match_list = strvec_create (match_list_size);
}
/* Clear out the old match list. */
for (i = 0; i < match_list_size; i++)
match_list[i] = 0;
/* We haven't found any files yet. */
match_index = 0;
if (absolute_program (name))
{
match_list[0] = find_absolute_program (name, flags);
match_list[1] = (char *)NULL;
path_list = (char *)NULL;
}
else
{
name_len = strlen (name);
file_to_lose_on = (char *)NULL;
dot_found_in_search = 0;
if (stat (".", &dotinfo) < 0)
dotinfo.st_dev = dotinfo.st_ino = 0; /* so same_file won't match */
path_list = get_string_value ("PATH");
path_index = 0;
}
while (path_list && path_list[path_index])
{
path_element = get_next_path_element (path_list, &path_index);
if (path_element == 0)
break;
match = find_in_path_element (name, path_element, flags, name_len, &dotinfo);
free (path_element);
if (match == 0)
continue;
if (match_index + 1 == match_list_size)
{
match_list_size += 10;
match_list = strvec_resize (match_list, (match_list_size + 1));
}
match_list[match_index++] = match;
match_list[match_index] = (char *)NULL;
FREE (file_to_lose_on);
file_to_lose_on = (char *)NULL;
}
/* We haven't returned any strings yet. */
match_index = 0;
}
match = match_list[match_index];
if (match)
match_index++;
return (match);
}
static char *
find_absolute_program (name, flags)
const char *name;
int flags;
{
int st;
st = file_status (name);
/* If the file doesn't exist, quit now. */
if ((st & FS_EXISTS) == 0)
return ((char *)NULL);
/* If we only care about whether the file exists or not, return
this filename. Otherwise, maybe we care about whether this
file is executable. If it is, and that is what we want, return it. */
if ((flags & FS_EXISTS) || ((flags & FS_EXEC_ONLY) && (st & FS_EXECABLE)))
return (savestring (name));
return (NULL);
}
static char *
find_in_path_element (name, path, flags, name_len, dotinfop)
const char *name;
char *path;
int flags, name_len;
struct stat *dotinfop;
{
int status;
char *full_path, *xpath;
xpath = (*path == '~') ? bash_tilde_expand (path, 0) : path;
/* Remember the location of "." in the path, in all its forms
(as long as they begin with a `.', e.g. `./.') */
if (dot_found_in_search == 0 && *xpath == '.')
dot_found_in_search = same_file (".", xpath, dotinfop, (struct stat *)NULL);
full_path = sh_makepath (xpath, name, 0);
status = file_status (full_path);
if (xpath != path)
free (xpath);
if ((status & FS_EXISTS) == 0)
{
free (full_path);
return ((char *)NULL);
}
/* The file exists. If the caller simply wants the first file, here it is. */
if (flags & FS_EXISTS)
return (full_path);
/* If we have a readable file, and the caller wants a readable file, this
is it. */
if ((flags & FS_READABLE) && (status & FS_READABLE))
return (full_path);
/* If the file is executable, then it satisfies the cases of
EXEC_ONLY and EXEC_PREFERRED. Return this file unconditionally. */
if ((status & FS_EXECABLE) && (flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) &&
(((flags & FS_NODIRS) == 0) || ((status & FS_DIRECTORY) == 0)))
{
FREE (file_to_lose_on);
file_to_lose_on = (char *)NULL;
return (full_path);
}
/* The file is not executable, but it does exist. If we prefer
an executable, then remember this one if it is the first one
we have found. */
if ((flags & FS_EXEC_PREFERRED) && file_to_lose_on == 0)
file_to_lose_on = savestring (full_path);
/* If we want only executable files, or we don't want directories and
this file is a directory, or we want a readable file and this file
isn't readable, fail. */
if ((flags & (FS_EXEC_ONLY|FS_EXEC_PREFERRED)) ||
((flags & FS_NODIRS) && (status & FS_DIRECTORY)) ||
((flags & FS_READABLE) && (status & FS_READABLE) == 0))
{
free (full_path);
return ((char *)NULL);
}
else
return (full_path);
}
/* This does the dirty work for find_user_command_internal () and
user_command_matches ().
NAME is the name of the file to search for.
PATH_LIST is a colon separated list of directories to search.
FLAGS contains bit fields which control the files which are eligible.
Some values are:
FS_EXEC_ONLY: The file must be an executable to be found.
FS_EXEC_PREFERRED: If we can't find an executable, then the
the first file matching NAME will do.
FS_EXISTS: The first file found will do.
FS_NODIRS: Don't find any directories.
*/
static char *
find_user_command_in_path (name, path_list, flags)
const char *name;
char *path_list;
int flags;
{
char *full_path, *path;
int path_index, name_len;
struct stat dotinfo;
/* We haven't started looking, so we certainly haven't seen
a `.' as the directory path yet. */
dot_found_in_search = 0;
if (absolute_program (name))
{
full_path = find_absolute_program (name, flags);
return (full_path);
}
if (path_list == 0 || *path_list == '\0')
return (savestring (name)); /* XXX */
file_to_lose_on = (char *)NULL;
name_len = strlen (name);
if (stat (".", &dotinfo) < 0)
dotinfo.st_dev = dotinfo.st_ino = 0;
path_index = 0;
while (path_list[path_index])
{
/* Allow the user to interrupt out of a lengthy path search. */
QUIT;
path = get_next_path_element (path_list, &path_index);
if (path == 0)
break;
/* Side effects: sets dot_found_in_search, possibly sets
file_to_lose_on. */
full_path = find_in_path_element (name, path, flags, name_len, &dotinfo);
free (path);
/* This should really be in find_in_path_element, but there isn't the
right combination of flags. */
if (full_path && is_directory (full_path))
{
free (full_path);
continue;
}
if (full_path)
{
FREE (file_to_lose_on);
return (full_path);
}
}
/* We didn't find exactly what the user was looking for. Return
the contents of FILE_TO_LOSE_ON which is NULL when the search
required an executable, or non-NULL if a file was found and the
search would accept a non-executable as a last resort. If the
caller specified FS_NODIRS, and file_to_lose_on is a directory,
return NULL. */
if (file_to_lose_on && (flags & FS_NODIRS) && is_directory (file_to_lose_on))
{
free (file_to_lose_on);
file_to_lose_on = (char *)NULL;
}
return (file_to_lose_on);
}
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
-9450
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 "$@"
-241
View File
@@ -1,241 +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 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
exit 0
-113
View File
@@ -1,113 +0,0 @@
trap 'rm /tmp/newhistory' 0
# bad options
history -x
# cannot use -r and -w at the same time
history -r -w /dev/null
# bad option
fc -v
unset HISTFILESIZE
# all of these should result in an empty history list
history -c
history -r /dev/null
history -n /dev/null
history -c
HISTFILE=history.list
HISTCONTROL=ignoreboth
HISTIGNORE='&:history*:fc*'
HISTSIZE=32
shopt -s cmdhist
set -o history
history
fc -l
fc -nl
fc -lr
fc -nlr
history -s "echo line for history"
history
history -p '!!'
fc -nl
HISTFILE=/tmp/newhistory
history -a
echo displaying \$HISTFILE after history -a
cat $HISTFILE
history
history -w
cat $HISTFILE
history -s "echo line 2 for history"
history
history -p '!e'
history -p '!!'
# this should show up as one history entry
for x in one two three
do
:
done
history
# just a basic test. a full test suite for history expansion should be
# created
set -H
!!
!e
unset HISTSIZE
unset HISTFILE
fc -l 4
fc -l 4 8
fc -l one=two three=four 502
history 4
shopt -so history
shopt -s expand_aliases
alias r="fc -s"
echo aa ab ac
r a=x
r x=4 b=8
# this had better fail with `no command found'
r cc
unalias -a
alias
# these two blocks had better both result in the same output
echo aa
echo bb
echo cc
fc -e cat
echo aa
echo bb
echo cc
fc -e cat -1
set +o history
shopt -q -o history
echo $?
${THIS_SH} ./history1.sub
${THIS_SH} ./history2.sub
-143
View File
@@ -1,143 +0,0 @@
# bug in bash up to and including bash-3.0 (including patches)
#
# problem is conflict between CTLNUL used internally to denote quoted null
# characters and its value (0x7f) appearing in the expansion of a variable
#
unset x
recho "xxx${x}yyy"
y=$'\177'
recho "xxx${y}yyy"
unset y
unset undef
set ""
recho ${undef-"x$*y"}
set $'\177'
recho ${undef-"x$*y"}
shift $#
f()
{
recho "-${*-x}-"
}
f ''
f $'\177'
unset -f f
x=12345
recho "${x:6:1}"
x=
recho "${x:0:1}"
y=$'\177'
recho "${y:0:1}"
y=xxx$'\177'yyy
recho "${y:3:3}"
unset x y
eval tmp=`printf "$'\\\\\x%x'\n" 127`
printf "%#1x\n" "'$tmp"
x=$'\177'
printf "%#1x\n" "'$x"
a=127
eval c=\$\'\\$(printf '%o' $a)\'
printf "%#1x\n" "'$c"
recho "$c"
recho "$c"@
recho @"$c"@
recho @"$c"
recho "$c"
recho "$c@"
recho "@$c@"
recho "@$c"
unset tmp x a c
qtest()
{
recho ${#q} "${q}" ${q}
}
q=$'\x7f'
qtest
q=${q}a
qtest
q=$'\x7fa'
qtest
q="${q}a"
qtest
unset -f qtest
unset q
set -- ''
recho "${*:1}"
recho ${*:1}
recho -${*:1}-
recho -"${*:1}"-
set $'\177'
recho "${*:1}"
recho "-${*:1}-"
recho ${*:1}
recho -${*:1}-
shift $#
DEL=`awk 'END{printf("%c", 0+127)}' </dev/null`
T1=a\ $DEL
T2="a $DEL"
set -- x $(echo $T1|wc -c) $(echo $T2|wc -c); shift
L1=$1; L2=$2
case "$L1/$L2" in
4/4) echo ok;;
*) echo CTLNUL bug: L1=$L1, L2=$L2;;
esac
x=$'\177'
recho "aaa${x}bbb"
recho ccc"${x}"ddd
recho eee"$x"fff
recho ggg"$(echo $x)"hhh
x=
recho "aaa${x}bbb"
recho ccc"${x}"ddd
recho eee"$x"fff
recho ggg"$(echo $x)"hhh
set -- $'\177'
recho "aaa${1}bbb"
recho ccc"${1}"ddd
recho eee"$1"fff
recho ggg"$(echo $1)"hhh
set -- ""
recho "aaa${1}bbb"
recho ccc"${1}"ddd
recho eee"$1"fff
recho ggg"$(echo $1)"hhh
recho aaa$'\177'bbb
recho ccc""ddd
recho "eeefff"
recho ggg"$(echo $'\177')"hhh
-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
-61
View File
@@ -1,61 +0,0 @@
LC_ALL=C
LANG=C
SHELLSTART=$(date +%s)
SECS=1275250155
export TZ=EST5EDT
case $SHELLSTART in
*s*) SHELLSTART=$(perl -e 'print time') ;; # take a shot
esac
printf "%()T\n" $SECS
printf "%(abde)Z\n" -1
printf "%(%e-%b-%Y %T)T\n" $SECS
printf -v v1 "%(%e-%b-%Y %T)T\n" $(date +%s)
printf -v v2 "%(%e-%b-%Y %T)T\n" -1
case $v1 in
$v2) ;;
*) echo "current time and -1 possible mismatch|$v1|$v2|" >&2 ;;
esac
unset v1 v2
v1=$(date +%s)
printf -v v2 "%(%s)T" -1
case $v1 in
$v2) ;;
*) echo "current time mismatch:$v1|$v2|" >&2 ;;
esac
unset v1 v2
printf "%(%x %X)T\n" $(( $SECS - 3600 ))
printf -v v1 "%(%F %r)T\n" $SHELLSTART
printf -v v2 "%(%F %r)T\n" -2
case $v1 in
$v2) ;;
*) echo "shell start time and -2 possible mismatch|$v1|$v2|" >&2 ;;
esac
unset v1 v2
printf "current time: %(%F %r)T\n" $SECS
printf "epoch time: %(%F %r %z)T\n" 0
printf "random time: %(%F %r %z)T\n" $SECS
printf "local time: %(%a %b %e %H:%M:%S %Z %Y)T\n" $SECS
# test fieldwidth, justification, precision
printf "%-40.50(%a %b %e %H:%M:%S %Z %Y)T date-style time\n" $SECS
# test fieldwidth, justification, precision, embedded parens
printf "%-40.50(%x (foo) %X)T date-style time\n" $SECS
# problem introduced in bash-4.2 patch 5
unset TZ
printf '%(%Y-%m-%d %H:%M:%S %Z)T\n' >/dev/null
-5
View File
@@ -1,5 +0,0 @@
# See whether or not we can use `diff -a'
( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a
${THIS_SH} ./printf.tests > /tmp/xx 2>&1
diff $AFLAG /tmp/xx printf.right && rm -f /tmp/xx
-4865
View File
File diff suppressed because it is too large Load Diff
-394
View File
@@ -1,394 +0,0 @@
/* variables.h -- data structures for shell variables. */
/* Copyright (C) 1987-2010 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/>.
*/
#if !defined (_VARIABLES_H_)
#define _VARIABLES_H_
#include "stdc.h"
#include "array.h"
#include "assoc.h"
/* Shell variables and functions are stored in hash tables. */
#include "hashlib.h"
#include "conftypes.h"
/* A variable context. */
typedef struct var_context {
char *name; /* empty or NULL means global context */
int scope; /* 0 means global context */
int flags;
struct var_context *up; /* previous function calls */
struct var_context *down; /* down towards global context */
HASH_TABLE *table; /* variables at this scope */
} VAR_CONTEXT;
/* Flags for var_context->flags */
#define VC_HASLOCAL 0x01
#define VC_HASTMPVAR 0x02
#define VC_FUNCENV 0x04 /* also function if name != NULL */
#define VC_BLTNENV 0x08 /* builtin_env */
#define VC_TEMPENV 0x10 /* temporary_env */
#define VC_TEMPFLAGS (VC_FUNCENV|VC_BLTNENV|VC_TEMPENV)
/* Accessing macros */
#define vc_isfuncenv(vc) (((vc)->flags & VC_FUNCENV) != 0)
#define vc_isbltnenv(vc) (((vc)->flags & VC_BLTNENV) != 0)
#define vc_istempenv(vc) (((vc)->flags & (VC_TEMPFLAGS)) == VC_TEMPENV)
#define vc_istempscope(vc) (((vc)->flags & (VC_TEMPENV|VC_BLTNENV)) != 0)
#define vc_haslocals(vc) (((vc)->flags & VC_HASLOCAL) != 0)
#define vc_hastmpvars(vc) (((vc)->flags & VC_HASTMPVAR) != 0)
/* What a shell variable looks like. */
typedef struct variable *sh_var_value_func_t __P((struct variable *));
typedef struct variable *sh_var_assign_func_t __P((struct variable *, char *, arrayind_t, char *));
/* For the future */
union _value {
char *s; /* string value */
intmax_t i; /* int value */
COMMAND *f; /* function */
ARRAY *a; /* array */
HASH_TABLE *h; /* associative array */
double d; /* floating point number */
#if defined (HAVE_LONG_DOUBLE)
long double ld; /* long double */
#endif
struct variable *v; /* possible indirect variable use */
void *opaque; /* opaque data for future use */
};
typedef struct variable {
char *name; /* Symbol that the user types. */
char *value; /* Value that is returned. */
char *exportstr; /* String for the environment. */
sh_var_value_func_t *dynamic_value; /* Function called to return a `dynamic'
value for a variable, like $SECONDS
or $RANDOM. */
sh_var_assign_func_t *assign_func; /* Function called when this `special
variable' is assigned a value in
bind_variable. */
int attributes; /* export, readonly, array, invisible... */
int context; /* Which context this variable belongs to. */
} SHELL_VAR;
typedef struct _vlist {
SHELL_VAR **list;
int list_size; /* allocated size */
int list_len; /* current number of entries */
} VARLIST;
/* The various attributes that a given variable can have. */
/* First, the user-visible attributes */
#define att_exported 0x0000001 /* export to environment */
#define att_readonly 0x0000002 /* cannot change */
#define att_array 0x0000004 /* value is an array */
#define att_function 0x0000008 /* value is a function */
#define att_integer 0x0000010 /* internal representation is int */
#define att_local 0x0000020 /* variable is local to a function */
#define att_assoc 0x0000040 /* variable is an associative array */
#define att_trace 0x0000080 /* function is traced with DEBUG trap */
#define att_uppercase 0x0000100 /* word converted to uppercase on assignment */
#define att_lowercase 0x0000200 /* word converted to lowercase on assignment */
#define att_capcase 0x0000400 /* word capitalized on assignment */
#define att_nameref 0x0000800 /* word is a name reference */
#define user_attrs (att_exported|att_readonly|att_integer|att_local|att_trace|att_uppercase|att_lowercase|att_capcase|att_nameref)
#define attmask_user 0x0000fff
/* Internal attributes used for bookkeeping */
#define att_invisible 0x0001000 /* cannot see */
#define att_nounset 0x0002000 /* cannot unset */
#define att_noassign 0x0004000 /* assignment not allowed */
#define att_imported 0x0008000 /* came from environment */
#define att_special 0x0010000 /* requires special handling */
#define att_nofree 0x0020000 /* do not free value on unset */
#define attmask_int 0x00ff000
/* Internal attributes used for variable scoping. */
#define att_tempvar 0x0100000 /* variable came from the temp environment */
#define att_propagate 0x0200000 /* propagate to previous scope */
#define attmask_scope 0x0f00000
#define exported_p(var) ((((var)->attributes) & (att_exported)))
#define readonly_p(var) ((((var)->attributes) & (att_readonly)))
#define array_p(var) ((((var)->attributes) & (att_array)))
#define function_p(var) ((((var)->attributes) & (att_function)))
#define integer_p(var) ((((var)->attributes) & (att_integer)))
#define local_p(var) ((((var)->attributes) & (att_local)))
#define assoc_p(var) ((((var)->attributes) & (att_assoc)))
#define trace_p(var) ((((var)->attributes) & (att_trace)))
#define uppercase_p(var) ((((var)->attributes) & (att_uppercase)))
#define lowercase_p(var) ((((var)->attributes) & (att_lowercase)))
#define capcase_p(var) ((((var)->attributes) & (att_capcase)))
#define invisible_p(var) ((((var)->attributes) & (att_invisible)))
#define non_unsettable_p(var) ((((var)->attributes) & (att_nounset)))
#define noassign_p(var) ((((var)->attributes) & (att_noassign)))
#define imported_p(var) ((((var)->attributes) & (att_imported)))
#define specialvar_p(var) ((((var)->attributes) & (att_special)))
#define nofree_p(var) ((((var)->attributes) & (att_nofree)))
#define tempvar_p(var) ((((var)->attributes) & (att_tempvar)))
/* Acessing variable values: rvalues */
#define value_cell(var) ((var)->value)
#define function_cell(var) (COMMAND *)((var)->value)
#define array_cell(var) (ARRAY *)((var)->value)
#define assoc_cell(var) (HASH_TABLE *)((var)->value)
#define var_isnull(var) ((var)->value == 0)
#define var_isset(var) ((var)->value != 0)
/* Assigning variable values: lvalues */
#define var_setvalue(var, str) ((var)->value = (str))
#define var_setfunc(var, func) ((var)->value = (char *)(func))
#define var_setarray(var, arr) ((var)->value = (char *)(arr))
#define var_setassoc(var, arr) ((var)->value = (char *)(arr))
/* Make VAR be auto-exported. */
#define set_auto_export(var) \
do { (var)->attributes |= att_exported; array_needs_making = 1; } while (0)
#define SETVARATTR(var, attr, undo) \
((undo == 0) ? ((var)->attributes |= (attr)) \
: ((var)->attributes &= ~(attr)))
#define VSETATTR(var, attr) ((var)->attributes |= (attr))
#define VUNSETATTR(var, attr) ((var)->attributes &= ~(attr))
#define VGETFLAGS(var) ((var)->attributes)
#define VSETFLAGS(var, flags) ((var)->attributes = (flags))
#define VCLRFLAGS(var) ((var)->attributes = 0)
/* Macros to perform various operations on `exportstr' member of a SHELL_VAR. */
#define CLEAR_EXPORTSTR(var) (var)->exportstr = (char *)NULL
#define COPY_EXPORTSTR(var) ((var)->exportstr) ? savestring ((var)->exportstr) : (char *)NULL
#define SET_EXPORTSTR(var, value) (var)->exportstr = (value)
#define SAVE_EXPORTSTR(var, value) (var)->exportstr = (value) ? savestring (value) : (char *)NULL
#define FREE_EXPORTSTR(var) \
do { if ((var)->exportstr) free ((var)->exportstr); } while (0)
#define CACHE_IMPORTSTR(var, value) \
(var)->exportstr = savestring (value)
#define INVALIDATE_EXPORTSTR(var) \
do { \
if ((var)->exportstr) \
{ \
free ((var)->exportstr); \
(var)->exportstr = (char *)NULL; \
} \
} while (0)
/* Stuff for hacking variables. */
typedef int sh_var_map_func_t __P((SHELL_VAR *));
/* Where we keep the variables and functions */
extern VAR_CONTEXT *global_variables;
extern VAR_CONTEXT *shell_variables;
extern HASH_TABLE *shell_functions;
extern HASH_TABLE *temporary_env;
extern int variable_context;
extern char *dollar_vars[];
extern char **export_env;
extern void initialize_shell_variables __P((char **, int));
extern SHELL_VAR *set_if_not __P((char *, char *));
extern void sh_set_lines_and_columns __P((int, int));
extern void set_pwd __P((void));
extern void set_ppid __P((void));
extern void make_funcname_visible __P((int));
extern SHELL_VAR *var_lookup __P((const char *, VAR_CONTEXT *));
extern SHELL_VAR *find_function __P((const char *));
extern FUNCTION_DEF *find_function_def __P((const char *));
extern SHELL_VAR *find_variable __P((const char *));
extern SHELL_VAR *find_variable_internal __P((const char *, int));
extern SHELL_VAR *find_variable_tempenv __P((const char *));
extern SHELL_VAR *find_global_variable __P((const char *));
extern SHELL_VAR *find_shell_variable __P((const char *));
extern SHELL_VAR *find_tempenv_variable __P((const char *));
extern SHELL_VAR *copy_variable __P((SHELL_VAR *));
extern SHELL_VAR *make_local_variable __P((const char *));
extern SHELL_VAR *bind_variable __P((const char *, char *, int));
extern SHELL_VAR *bind_function __P((const char *, COMMAND *));
extern void bind_function_def __P((const char *, FUNCTION_DEF *));
extern SHELL_VAR **map_over __P((sh_var_map_func_t *, VAR_CONTEXT *));
SHELL_VAR **map_over_funcs __P((sh_var_map_func_t *));
extern SHELL_VAR **all_shell_variables __P((void));
extern SHELL_VAR **all_shell_functions __P((void));
extern SHELL_VAR **all_visible_variables __P((void));
extern SHELL_VAR **all_visible_functions __P((void));
extern SHELL_VAR **all_exported_variables __P((void));
extern SHELL_VAR **local_exported_variables __P((void));
extern SHELL_VAR **all_local_variables __P((void));
#if defined (ARRAY_VARS)
extern SHELL_VAR **all_array_variables __P((void));
#endif
extern char **all_variables_matching_prefix __P((const char *));
extern char **make_var_array __P((HASH_TABLE *));
extern char **add_or_supercede_exported_var __P((char *, int));
extern char *get_variable_value __P((SHELL_VAR *));
extern char *get_string_value __P((const char *));
extern char *sh_get_env_value __P((const char *));
extern char *make_variable_value __P((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_variable_value __P((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_int_variable __P((char *, char *));
extern SHELL_VAR *bind_var_to_int __P((char *, intmax_t));
extern int assign_in_env __P((WORD_DESC *, int));
extern int unbind_variable __P((const char *));
extern int unbind_func __P((const char *));
extern int unbind_function_def __P((const char *));
extern int makunbound __P((const char *, VAR_CONTEXT *));
extern int kill_local_variable __P((const char *));
extern void delete_all_variables __P((HASH_TABLE *));
extern void delete_all_contexts __P((VAR_CONTEXT *));
extern VAR_CONTEXT *new_var_context __P((char *, int));
extern void dispose_var_context __P((VAR_CONTEXT *));
extern VAR_CONTEXT *push_var_context __P((char *, int, HASH_TABLE *));
extern void pop_var_context __P((void));
extern VAR_CONTEXT *push_scope __P((int, HASH_TABLE *));
extern void pop_scope __P((int));
extern void push_context __P((char *, int, HASH_TABLE *));
extern void pop_context __P((void));
extern void push_dollar_vars __P((void));
extern void pop_dollar_vars __P((void));
extern void dispose_saved_dollar_vars __P((void));
extern void push_args __P((WORD_LIST *));
extern void pop_args __P((void));
extern void adjust_shell_level __P((int));
extern void non_unsettable __P((char *));
extern void dispose_variable __P((SHELL_VAR *));
extern void dispose_used_env_vars __P((void));
extern void dispose_function_env __P((void));
extern void dispose_builtin_env __P((void));
extern void merge_temporary_env __P((void));
extern void merge_builtin_env __P((void));
extern void kill_all_local_variables __P((void));
extern void set_var_read_only __P((char *));
extern void set_func_read_only __P((const char *));
extern void set_var_auto_export __P((char *));
extern void set_func_auto_export __P((const char *));
extern void sort_variables __P((SHELL_VAR **));
extern int chkexport __P((char *));
extern void maybe_make_export_env __P((void));
extern void update_export_env_inplace __P((char *, int, char *));
extern void put_command_name_into_env __P((char *));
extern void put_gnu_argv_flags_into_env __P((intmax_t, char *));
extern void print_var_list __P((SHELL_VAR **));
extern void print_func_list __P((SHELL_VAR **));
extern void print_assignment __P((SHELL_VAR *));
extern void print_var_value __P((SHELL_VAR *, int));
extern void print_var_function __P((SHELL_VAR *));
#if defined (ARRAY_VARS)
extern SHELL_VAR *make_new_array_variable __P((char *));
extern SHELL_VAR *make_local_array_variable __P((char *, int));
extern SHELL_VAR *make_new_assoc_variable __P((char *));
extern SHELL_VAR *make_local_assoc_variable __P((char *));
extern void set_pipestatus_array __P((int *, int));
extern ARRAY *save_pipestatus_array __P((void));
extern void restore_pipestatus_array __P((ARRAY *));
#endif
extern void set_pipestatus_from_exit __P((int));
/* The variable in NAME has just had its state changed. Check to see if it
is one of the special ones where something special happens. */
extern void stupidly_hack_special_variables __P((char *));
/* Reinitialize some special variables that have external effects upon unset
when the shell reinitializes itself. */
extern void reinit_special_variables __P((void));
extern int get_random_number __P((void));
/* The `special variable' functions that get called when a particular
variable is set. */
extern void sv_ifs __P((char *));
extern void sv_path __P((char *));
extern void sv_mail __P((char *));
extern void sv_funcnest __P((char *));
extern void sv_globignore __P((char *));
extern void sv_ignoreeof __P((char *));
extern void sv_strict_posix __P((char *));
extern void sv_optind __P((char *));
extern void sv_opterr __P((char *));
extern void sv_locale __P((char *));
extern void sv_xtracefd __P((char *));
#if defined (READLINE)
extern void sv_comp_wordbreaks __P((char *));
extern void sv_terminal __P((char *));
extern void sv_hostfile __P((char *));
extern void sv_winsize __P((char *));
#endif
#if defined (__CYGWIN__)
extern void sv_home __P((char *));
#endif
#if defined (HISTORY)
extern void sv_histsize __P((char *));
extern void sv_histignore __P((char *));
extern void sv_history_control __P((char *));
# if defined (BANG_HISTORY)
extern void sv_histchars __P((char *));
# endif
extern void sv_histtimefmt __P((char *));
#endif /* HISTORY */
#if defined (HAVE_TZSET)
extern void sv_tz __P((char *));
#endif
#endif /* !_VARIABLES_H_ */