mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-09 05:00:49 +02:00
commit bash-20120224 snapshot
This commit is contained in:
+61
-5
@@ -13196,6 +13196,16 @@ trap.c
|
||||
- use BLOCK_SIGNAL/UNBLOCK_SIGNAL instead of code dependent on
|
||||
HAVE_POSIX_SIGNALS and BSD signals
|
||||
|
||||
1/24
|
||||
----
|
||||
|
||||
print_cmd.c
|
||||
- print_redirection_list: change the conditions under which
|
||||
r_duplicating_output_word is mapped to r_err_and_out to more or
|
||||
less match those used in redir.c. Fixes bug pointed out by
|
||||
Dan Douglas <ormaaj@gmail.com>
|
||||
|
||||
|
||||
1/29
|
||||
----
|
||||
lib/readline/signals.c
|
||||
@@ -13386,12 +13396,58 @@ lib/sh/unicode.c
|
||||
- u32reset: new function, resets local static state to uninitialized
|
||||
(locale information, currently)
|
||||
|
||||
lib/sh/strtrans.c
|
||||
- ansicstr: allocate a new string 6 times longer than the original
|
||||
if the \U escape sequence appears, to accommodate UTF-8 chars
|
||||
of maximum theoretical length
|
||||
|
||||
locale.c
|
||||
- call u32reset whenever LC_CTYPE/LC_ALL/LANG is changed to reset the
|
||||
cached locale information used by u32cconv. From a report from
|
||||
John Kearney <dethrophes@web.de>
|
||||
|
||||
2/21
|
||||
----
|
||||
doc/{bash,builtins}.1
|
||||
- minor changes from Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
|
||||
|
||||
lib/sh/unicode.c
|
||||
- u32cconv: only assume you can directly call wctomb on the passed
|
||||
value if __STDC_ISO_10646__ is defined and the value is <=
|
||||
0x7fffffff
|
||||
- stub_charset: return locale as default instead of "ASCII", let
|
||||
rest of code decide what to do with it
|
||||
|
||||
lib/readline/parens.c
|
||||
- _rl_enable_paren_matching: make paren matching work in vi insert
|
||||
mode. Bug report from <derflob@derflob.de>
|
||||
|
||||
2/22
|
||||
----
|
||||
lib/sh/shquote.c
|
||||
- sh_backslash_quote: quote tilde in places where it would be
|
||||
expanded. From a report from John Kearney <dethrophes@web.de>
|
||||
|
||||
2/23
|
||||
----
|
||||
execute_cmd.c
|
||||
- execute_pipeline: wrap the discard_unwind_frame call in #ifdef
|
||||
JOB_CONTROL, since the frame is only created if JOB_CONTROL is
|
||||
defined. Bug and fix from Doug Kehn <rdkehn@yahoo.com>
|
||||
|
||||
2/25
|
||||
----
|
||||
error.c
|
||||
- report_error: make sure last_command_exit_value is non-zero before
|
||||
we call exit_shell, since the exit trap may reference it. Call
|
||||
exit_shell with last_command_exit_value to allow exit statuses
|
||||
other than 1
|
||||
|
||||
unicode.c
|
||||
- stub_charset: use local static buffer to hold charset, don't change
|
||||
value returned by get_locale_var. Based on idea and code from
|
||||
John Kearney <dethrophes@web.de>
|
||||
- u32toutf16: function to convert unsigned 32-bit value (unicode) to
|
||||
UTF-16. From John Kearney <dethrophes@web.de>
|
||||
- u32cconv: call u32toutf16 if __STDC_ISO_10646__ defined and wchar_t
|
||||
is two bytes, send result to wcstombs, return if not encoding error.
|
||||
From John Kearney <dethrophes@web.de>
|
||||
- u32cconv: return UTF-8 conversion if iconv conversion to local
|
||||
charset is unsupported
|
||||
|
||||
|
||||
|
||||
+61
-6
@@ -13196,6 +13196,16 @@ trap.c
|
||||
- use BLOCK_SIGNAL/UNBLOCK_SIGNAL instead of code dependent on
|
||||
HAVE_POSIX_SIGNALS and BSD signals
|
||||
|
||||
1/24
|
||||
----
|
||||
|
||||
print_cmd.c
|
||||
- print_redirection_list: change the conditions under which
|
||||
r_duplicating_output_word is mapped to r_err_and_out to more or
|
||||
less match those used in redir.c. Fixes bug pointed out by
|
||||
Dan Douglas <ormaaj@gmail.com>
|
||||
|
||||
|
||||
1/29
|
||||
----
|
||||
lib/readline/signals.c
|
||||
@@ -13386,11 +13396,56 @@ lib/sh/unicode.c
|
||||
- u32reset: new function, resets local static state to uninitialized
|
||||
(locale information, currently)
|
||||
|
||||
lib/sh/strtrans.c
|
||||
- ansicstr: allocate a new string 6 times longer than the original
|
||||
if the \U escape sequence appears, to accommodate UTF-8 chars
|
||||
of maximum theoretical length
|
||||
|
||||
locale.c
|
||||
- call u32reset whenever LC_CTYPE/LC_ALL/LANG is changed to reset the
|
||||
cached locale information used by u32cconv
|
||||
cached locale information used by u32cconv. From a report from
|
||||
John Kearney <dethrophes@web.de>
|
||||
|
||||
2/21
|
||||
----
|
||||
doc/{bash,builtins}.1
|
||||
- minor changes from Bjarni Ingi Gislason <bjarniig@rhi.hi.is>
|
||||
|
||||
lib/sh/unicode.c
|
||||
- u32cconv: only assume you can directly call wctomb on the passed
|
||||
value if __STDC_ISO_10646__ is defined and the value is <=
|
||||
0x7fffffff
|
||||
- stub_charset: return locale as default instead of "ASCII", let
|
||||
rest of code decide what to do with it
|
||||
|
||||
lib/readline/parens.c
|
||||
- _rl_enable_paren_matching: make paren matching work in vi insert
|
||||
mode. Bug report from <derflob@derflob.de>
|
||||
|
||||
2/22
|
||||
----
|
||||
lib/sh/shquote.c
|
||||
- sh_backslash_quote: quote tilde in places where it would be
|
||||
expanded. From a report from John Kearney <dethrophes@web.de>
|
||||
|
||||
2/23
|
||||
----
|
||||
execute_cmd.c
|
||||
- execute_pipeline: wrap the discard_unwind_frame call in #ifdef
|
||||
JOB_CONTROL, since the frame is only created if JOB_CONTROL is
|
||||
defined. Bug and fix from Doug Kehn <rdkehn@yahoo.com>
|
||||
|
||||
2/25
|
||||
----
|
||||
error.c
|
||||
- report_error: make sure last_command_exit_value is non-zero before
|
||||
we call exit_shell, since the exit trap may reference it. Call
|
||||
exit_shell with last_command_exit_value to allow exit statuses
|
||||
other than 1
|
||||
|
||||
unicode.c
|
||||
- stub_charset: use local static buffer to hold charset, don't change
|
||||
value returned by get_locale_var. Based on idea and code from
|
||||
John Kearney <dethrophes@web.de>
|
||||
- u32toutf16: function to convert unsigned 32-bit value (unicode) to
|
||||
UTF-16. From John Kearney <dethrophes@web.de>
|
||||
- u32cconv: call u32toutf16 if __STDC_ISO_10646__ defined and wchar_t
|
||||
is two bytes, send result to wcstombs, return if not encoding error.
|
||||
From John Kearney <dethrophes@web.de>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
union {
|
||||
long int l;
|
||||
char c[sizeof(long int)];
|
||||
} u;
|
||||
int x0, x1, x2, x3;
|
||||
|
||||
u.l = 1;
|
||||
x0 = u.c[0];
|
||||
x3 = u.c[sizeof (long int) - 1];
|
||||
printf ("x0 = %d x3 = %d (%s)\n", x0, x3, x3 == 1 ? "bigendian" : "littleendian");
|
||||
x0 = u.l >> 24;
|
||||
x1 = u.l >> 16;
|
||||
x2 = u.l >> 8;
|
||||
x3 = u.l & 0xff;
|
||||
printf ("x0:x3: %d %d %d %d\n", x0, x1, x2, x3);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
int i = 0x12345678;
|
||||
char *x;
|
||||
|
||||
x = (char *)&i;
|
||||
printf ("0x%x\n", *x);
|
||||
printf ((*x == 0x78) ? "little endian\n" : "big endian\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <stdio.h>
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
union {
|
||||
int l;
|
||||
char c[sizeof(int)];
|
||||
} u;
|
||||
int x0, x1, x2, x3;
|
||||
|
||||
u.l = 0x012345678;
|
||||
x0 = u.c[0];
|
||||
x3 = u.c[sizeof (int) - 1];
|
||||
printf ("x0 = 0x%x x3 = 0x%x (%s)\n", x0, x3, x3 == 0x78 ? "bigendian" : "littleendian");
|
||||
x0 = (u.l >> 24) & 0xff;
|
||||
x1 = (u.l >> 16) & 0xff;
|
||||
x2 = (u.l >> 8) & 0xff;
|
||||
x3 = u.l & 0xff;
|
||||
printf ("big endian x0:x3: %x %x %x %x\n", x0, x1, x2, x3);
|
||||
}
|
||||
@@ -505,10 +505,14 @@ po/fr.gmo f
|
||||
po/fr.po f
|
||||
po/ga.gmo f
|
||||
po/ga.po f
|
||||
po/gl.gmo f
|
||||
po/gl.po f
|
||||
po/hu.gmo f
|
||||
po/hu.po f
|
||||
po/id.gmo f
|
||||
po/id.po f
|
||||
po/it.gmo f
|
||||
po/it.po f
|
||||
po/ja.gmo f
|
||||
po/ja.po f
|
||||
po/lt.gmo f
|
||||
|
||||
+1
-1
@@ -6377,7 +6377,7 @@ is similar to the history expansion in
|
||||
This section describes what syntax features are available. This
|
||||
feature is enabled by default for interactive shells, and can be
|
||||
disabled using the
|
||||
.B \+H
|
||||
.B +H
|
||||
option to the
|
||||
.B set
|
||||
builtin command (see
|
||||
|
||||
+8
-1
@@ -1,6 +1,13 @@
|
||||
.\" This is a hack to force bash builtins into the whatis database
|
||||
.\" and to get the list of builtins to come up with the man command.
|
||||
.TH BASH_BUILTINS 1 "2004 Apr 20" "GNU Bash-4.0"
|
||||
.\"
|
||||
.\" File Name macro. This used to be `.PN', for Path Name,
|
||||
.\" but Sun doesn't seem to like that very much.
|
||||
.\"
|
||||
.de FN
|
||||
\fI\|\\$1\|\fP
|
||||
..
|
||||
.TH BASH_BUILTINS 1 "2004 Apr 20" "GNU Bash-4.2"
|
||||
.SH NAME
|
||||
bash, :, ., [, alias, bg, bind, break, builtin, caller,
|
||||
cd, command, compgen, complete,
|
||||
|
||||
@@ -200,7 +200,11 @@ report_error (format, va_alist)
|
||||
|
||||
va_end (args);
|
||||
if (exit_immediately_on_error)
|
||||
exit_shell (1);
|
||||
{
|
||||
if (last_command_exit_value == 0)
|
||||
last_command_exit_value = 1;
|
||||
exit_shell (last_command_exit_value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -0,0 +1,455 @@
|
||||
/* error.c -- Functions for handling errors. */
|
||||
|
||||
/* Copyright (C) 1993-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "bashtypes.h"
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "flags.h"
|
||||
#include "input.h"
|
||||
|
||||
#if defined (HISTORY)
|
||||
# include "bashhist.h"
|
||||
#endif
|
||||
|
||||
extern int executing_line_number __P((void));
|
||||
|
||||
extern int last_command_exit_value;
|
||||
extern char *shell_name;
|
||||
#if defined (JOB_CONTROL)
|
||||
extern pid_t shell_pgrp;
|
||||
extern int give_terminal_to __P((pid_t, int));
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
extern const char * const bash_badsub_errmsg;
|
||||
#endif
|
||||
|
||||
static void error_prolog __P((int));
|
||||
|
||||
/* The current maintainer of the shell. You change this in the
|
||||
Makefile. */
|
||||
#if !defined (MAINTAINER)
|
||||
#define MAINTAINER "bash-maintainers@gnu.org"
|
||||
#endif
|
||||
|
||||
const char * const the_current_maintainer = MAINTAINER;
|
||||
|
||||
int gnu_error_format = 0;
|
||||
|
||||
static void
|
||||
error_prolog (print_lineno)
|
||||
int print_lineno;
|
||||
{
|
||||
char *ename;
|
||||
int line;
|
||||
|
||||
ename = get_name_for_error ();
|
||||
line = (print_lineno && interactive_shell == 0) ? executing_line_number () : -1;
|
||||
|
||||
if (line > 0)
|
||||
fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), line);
|
||||
else
|
||||
fprintf (stderr, "%s: ", ename);
|
||||
}
|
||||
|
||||
/* Return the name of the shell or the shell script for error reporting. */
|
||||
char *
|
||||
get_name_for_error ()
|
||||
{
|
||||
char *name;
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *bash_source_v;
|
||||
ARRAY *bash_source_a;
|
||||
#endif
|
||||
|
||||
name = (char *)NULL;
|
||||
if (interactive_shell == 0)
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
bash_source_v = find_variable ("BASH_SOURCE");
|
||||
if (bash_source_v && array_p (bash_source_v) &&
|
||||
(bash_source_a = array_cell (bash_source_v)))
|
||||
name = array_reference (bash_source_a, 0);
|
||||
if (name == 0 || *name == '\0') /* XXX - was just name == 0 */
|
||||
#endif
|
||||
name = dollar_vars[0];
|
||||
}
|
||||
if (name == 0 && shell_name && *shell_name)
|
||||
name = base_pathname (shell_name);
|
||||
if (name == 0)
|
||||
#if defined (PROGRAM)
|
||||
name = PROGRAM;
|
||||
#else
|
||||
name = "bash";
|
||||
#endif
|
||||
|
||||
return (name);
|
||||
}
|
||||
|
||||
/* Report an error having to do with FILENAME. This does not use
|
||||
sys_error so the filename is not interpreted as a printf-style
|
||||
format string. */
|
||||
void
|
||||
file_error (filename)
|
||||
const char *filename;
|
||||
{
|
||||
report_error ("%s: %s", filename, strerror (errno));
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
programming_error (const char *format, ...)
|
||||
#else
|
||||
programming_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char *h;
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
give_terminal_to (shell_pgrp, 0);
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
va_end (args);
|
||||
|
||||
#if defined (HISTORY)
|
||||
if (remember_on_history)
|
||||
{
|
||||
h = last_history_line ();
|
||||
fprintf (stderr, _("last command: %s\n"), h ? h : "(null)");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
fprintf (stderr, "Report this to %s\n", the_current_maintainer);
|
||||
#endif
|
||||
|
||||
fprintf (stderr, _("Aborting..."));
|
||||
fflush (stderr);
|
||||
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Print an error message and, if `set -e' has been executed, exit the
|
||||
shell. Used in this file by file_error and programming_error. Used
|
||||
outside this file mostly to report substitution and expansion errors,
|
||||
and for bad invocation options. */
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
report_error (const char *format, ...)
|
||||
#else
|
||||
report_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
error_prolog (1);
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
if (exit_immediately_on_error)
|
||||
exit_shell (1);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
fatal_error (const char *format, ...)
|
||||
#else
|
||||
fatal_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
error_prolog (0);
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
sh_exit (2);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
internal_error (const char *format, ...)
|
||||
#else
|
||||
internal_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
error_prolog (1);
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
internal_warning (const char *format, ...)
|
||||
#else
|
||||
internal_warning (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
error_prolog (1);
|
||||
fprintf (stderr, _("warning: "));
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
sys_error (const char *format, ...)
|
||||
#else
|
||||
sys_error (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
int e;
|
||||
va_list args;
|
||||
|
||||
e = errno;
|
||||
error_prolog (0);
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, ": %s\n", strerror (e));
|
||||
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
/* An error from the parser takes the general form
|
||||
|
||||
shell_name: input file name: line number: message
|
||||
|
||||
The input file name and line number are omitted if the shell is
|
||||
currently interactive. If the shell is not currently interactive,
|
||||
the input file name is inserted only if it is different from the
|
||||
shell name. */
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
parser_error (int lineno, const char *format, ...)
|
||||
#else
|
||||
parser_error (lineno, format, va_alist)
|
||||
int lineno;
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
char *ename, *iname;
|
||||
|
||||
ename = get_name_for_error ();
|
||||
iname = yy_input_name ();
|
||||
|
||||
if (interactive)
|
||||
fprintf (stderr, "%s: ", ename);
|
||||
else if (interactive_shell)
|
||||
fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
|
||||
else if (STREQ (ename, iname))
|
||||
fprintf (stderr, "%s:%s%d: ", ename, gnu_error_format ? "" : _(" line "), lineno);
|
||||
else
|
||||
fprintf (stderr, "%s: %s:%s%d: ", ename, iname, gnu_error_format ? "" : _(" line "), lineno);
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
|
||||
if (exit_immediately_on_error)
|
||||
exit_shell (last_command_exit_value = 2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
itrace (const char *format, ...)
|
||||
#else
|
||||
itrace (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
fprintf(stderr, "TRACE: pid %ld: ", (long)getpid());
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (stderr, format, args);
|
||||
fprintf (stderr, "\n");
|
||||
|
||||
va_end (args);
|
||||
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
/* A trace function for silent debugging -- doesn't require a control
|
||||
terminal. */
|
||||
void
|
||||
#if defined (PREFER_STDARG)
|
||||
trace (const char *format, ...)
|
||||
#else
|
||||
trace (format, va_alist)
|
||||
const char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
static FILE *tracefp = (FILE *)NULL;
|
||||
|
||||
if (tracefp == NULL)
|
||||
tracefp = fopen("/tmp/bash-trace.log", "a+");
|
||||
|
||||
if (tracefp == NULL)
|
||||
tracefp = stderr;
|
||||
else
|
||||
fcntl (fileno (tracefp), F_SETFD, 1); /* close-on-exec */
|
||||
|
||||
fprintf(tracefp, "TRACE: pid %ld: ", (long)getpid());
|
||||
|
||||
SH_VA_START (args, format);
|
||||
|
||||
vfprintf (tracefp, format, args);
|
||||
fprintf (tracefp, "\n");
|
||||
|
||||
va_end (args);
|
||||
|
||||
fflush(tracefp);
|
||||
}
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Common error reporting */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
|
||||
static const char * const cmd_error_table[] = {
|
||||
N_("unknown command error"), /* CMDERR_DEFAULT */
|
||||
N_("bad command type"), /* CMDERR_BADTYPE */
|
||||
N_("bad connector"), /* CMDERR_BADCONN */
|
||||
N_("bad jump"), /* CMDERR_BADJUMP */
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
command_error (func, code, e, flags)
|
||||
const char *func;
|
||||
int code, e, flags; /* flags currently unused */
|
||||
{
|
||||
if (code > CMDERR_LAST)
|
||||
code = CMDERR_DEFAULT;
|
||||
|
||||
programming_error ("%s: %s: %d", func, _(cmd_error_table[code]), e);
|
||||
}
|
||||
|
||||
char *
|
||||
command_errstr (code)
|
||||
int code;
|
||||
{
|
||||
if (code > CMDERR_LAST)
|
||||
code = CMDERR_DEFAULT;
|
||||
|
||||
return (_(cmd_error_table[code]));
|
||||
}
|
||||
|
||||
#ifdef ARRAY_VARS
|
||||
void
|
||||
err_badarraysub (s)
|
||||
const char *s;
|
||||
{
|
||||
report_error ("%s: %s", s, _(bash_badsub_errmsg));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
err_unboundvar (s)
|
||||
const char *s;
|
||||
{
|
||||
report_error (_("%s: unbound variable"), s);
|
||||
}
|
||||
|
||||
void
|
||||
err_readonly (s)
|
||||
const char *s;
|
||||
{
|
||||
report_error (_("%s: readonly variable"), s);
|
||||
}
|
||||
@@ -2370,7 +2370,9 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close)
|
||||
unfreeze_jobs_list ();
|
||||
}
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
discard_unwind_frame ("lastpipe-exec");
|
||||
#endif
|
||||
|
||||
return (exec_result);
|
||||
}
|
||||
|
||||
@@ -226,6 +226,10 @@ sh_backslash_quote (string, table)
|
||||
*r++ = '\\';
|
||||
else if (c == '#' && s == string) /* comment char */
|
||||
*r++ = '\\';
|
||||
else if (c == '~' && (s == string || s[-1] == ':' || s[-1] == '='))
|
||||
/* Tildes are special at the start of a word or after a `:' or `='
|
||||
(technically unquoted, but it doesn't make a difference in practice) */
|
||||
*r++ = '\\';
|
||||
*r++ = c;
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -60,10 +60,7 @@ ansicstr (string, len, flags, sawc, rlen)
|
||||
return ((char *)NULL);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (strstr (string, "\\U") != 0)
|
||||
ret = (char *)xmalloc (6*len + 1);
|
||||
else
|
||||
ret = (char *)xmalloc (4*len + 1);
|
||||
ret = (char *)xmalloc (4*len + 1);
|
||||
#else
|
||||
ret = (char *)xmalloc (2*len + 1); /* 2*len for possible CTLESC */
|
||||
#endif
|
||||
|
||||
+61
-34
@@ -1,6 +1,6 @@
|
||||
/* unicode.c - functions to convert unicode characters */
|
||||
|
||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -61,6 +61,8 @@ static iconv_t localconv;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LOCALE_CHARSET
|
||||
static char charsetbuf[40];
|
||||
|
||||
static char *
|
||||
stub_charset ()
|
||||
{
|
||||
@@ -68,19 +70,21 @@ stub_charset ()
|
||||
|
||||
locale = get_locale_var ("LC_CTYPE");
|
||||
if (locale == 0 || *locale == 0)
|
||||
return "ASCII";
|
||||
{
|
||||
strcpy (charsetbuf, "ASCII");
|
||||
return charsetbuf;
|
||||
}
|
||||
s = strrchr (locale, '.');
|
||||
if (s)
|
||||
{
|
||||
t = strchr (s, '@');
|
||||
strcpy (charsetbuf, s+1);
|
||||
t = strchr (charsetbuf, '@');
|
||||
if (t)
|
||||
*t = 0;
|
||||
return ++s;
|
||||
return charsetbuf;
|
||||
}
|
||||
else if (STREQ (locale, "UTF-8"))
|
||||
return "UTF-8";
|
||||
else
|
||||
return "ASCII";
|
||||
strcpy (charsetbuf, locale);
|
||||
return charsetbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -93,14 +97,12 @@ u32reset ()
|
||||
|
||||
/* u32toascii ? */
|
||||
int
|
||||
u32tochar (wc, s)
|
||||
wchar_t wc;
|
||||
u32tochar (x, s)
|
||||
unsigned long x;
|
||||
char *s;
|
||||
{
|
||||
unsigned long x;
|
||||
int l;
|
||||
|
||||
x = wc;
|
||||
l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4);
|
||||
|
||||
if (x <= UCHAR_MAX)
|
||||
@@ -165,7 +167,7 @@ u32toutf8 (wc, s)
|
||||
s[4] = (wc & 0x3f) | 0x80;
|
||||
l = 5;
|
||||
}
|
||||
else
|
||||
else if (wc < 0x080000000)
|
||||
{
|
||||
s[0] = (wc >> 30) | 0xf8;
|
||||
s[1] = ((wc >> 24) & 0x3f) | 0x80;
|
||||
@@ -175,11 +177,39 @@ u32toutf8 (wc, s)
|
||||
s[5] = (wc & 0x3f) | 0x80;
|
||||
l = 6;
|
||||
}
|
||||
else
|
||||
l = 0;
|
||||
|
||||
s[l] = '\0';
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Convert a 32-bit unsigned int (unicode) to a UTF-16 string. Rarely used,
|
||||
only if sizeof(wchar_t) == 2. */
|
||||
int
|
||||
u32toutf16 (c, s)
|
||||
u_bits32_t c;
|
||||
unsigned short *s;
|
||||
{
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
if (c < 0x0d800)
|
||||
{
|
||||
s[0] = (unsigned short) (c & 0xFFFF);
|
||||
l = 1;
|
||||
}
|
||||
else if (c >= 0x0e000 && c <= 0x010ffff)
|
||||
{
|
||||
c -= 0x010000;
|
||||
s[0] = (unsigned short)((c >> 10) + 0xd800);
|
||||
s[1] = (unsigned short)((c & 0x3ff) + 0xdc00);
|
||||
l = 2;
|
||||
}
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
/* convert a single unicode-32 character into a multibyte string and put the
|
||||
result in S, which must be large enough (at least MB_LEN_MAX bytes) */
|
||||
int
|
||||
@@ -188,6 +218,7 @@ u32cconv (c, s)
|
||||
char *s;
|
||||
{
|
||||
wchar_t wc;
|
||||
wchar_t ws[3];
|
||||
int n;
|
||||
#if HAVE_ICONV
|
||||
const char *charset;
|
||||
@@ -197,14 +228,16 @@ u32cconv (c, s)
|
||||
size_t sn;
|
||||
#endif
|
||||
|
||||
wc = c;
|
||||
|
||||
#if __STDC_ISO_10646__
|
||||
if (sizeof (wchar_t) == 4)
|
||||
{
|
||||
n = wctomb (s, wc);
|
||||
return n;
|
||||
}
|
||||
wc = c;
|
||||
if (sizeof (wchar_t) == 4 && c <= 0x7fffffff)
|
||||
n = wctomb (s, wc);
|
||||
else if (sizeof (wchar_t) == 2 && c <= 0x10ffff && u32toutf16 (c, ws))
|
||||
n = wcstombs (s, ws, MB_LEN_MAX);
|
||||
else
|
||||
n = -1;
|
||||
if (n != -1)
|
||||
return n;
|
||||
#endif
|
||||
|
||||
#if HAVE_NL_LANGINFO
|
||||
@@ -236,19 +269,9 @@ u32cconv (c, s)
|
||||
u32init = 1;
|
||||
}
|
||||
|
||||
if (utf8locale)
|
||||
{
|
||||
n = u32toutf8 (c, s);
|
||||
return n;
|
||||
}
|
||||
|
||||
if (localconv == (iconv_t)-1)
|
||||
{
|
||||
n = u32tochar (wc, s);
|
||||
return n;
|
||||
}
|
||||
|
||||
n = u32toutf8 (c, s);
|
||||
if (utf8locale || localconv == (iconv_t)-1)
|
||||
return n;
|
||||
|
||||
optr = obuf;
|
||||
obytesleft = sizeof (obuf);
|
||||
@@ -268,8 +291,12 @@ u32cconv (c, s)
|
||||
return (optr - obuf);
|
||||
#endif
|
||||
|
||||
n = u32tochar (wc, s); /* fallback */
|
||||
n = u32tochar (c, s); /* fallback */
|
||||
return n;
|
||||
}
|
||||
|
||||
#else
|
||||
void
|
||||
u32reset ()
|
||||
{
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
/* unicode.c - functions to convert unicode characters */
|
||||
|
||||
/* Copyright (C) 2010-2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
|
||||
#include <stdc.h>
|
||||
#include <wchar.h>
|
||||
#include <bashansi.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
#if HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include <xmalloc.h>
|
||||
|
||||
#ifndef USHORT_MAX
|
||||
# ifdef USHRT_MAX
|
||||
# define USHORT_MAX USHRT_MAX
|
||||
# else
|
||||
# define USHORT_MAX ((unsigned short) ~(unsigned short)0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined (STREQ)
|
||||
# define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0)
|
||||
#endif /* !STREQ */
|
||||
|
||||
#if defined (HAVE_LOCALE_CHARSET)
|
||||
extern const char *locale_charset __P((void));
|
||||
#else
|
||||
extern char *get_locale_var __P((char *));
|
||||
#endif
|
||||
|
||||
static int u32init = 0;
|
||||
static int utf8locale = 0;
|
||||
#if defined (HAVE_ICONV)
|
||||
static iconv_t localconv;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LOCALE_CHARSET
|
||||
static char charsetbuf[40];
|
||||
|
||||
static char *
|
||||
stub_charset ()
|
||||
{
|
||||
char *locale, *s, *t;
|
||||
|
||||
locale = get_locale_var ("LC_CTYPE");
|
||||
if (locale == 0 || *locale == 0)
|
||||
{
|
||||
strcpy (charsetbuf, "ASCII");
|
||||
return charsetbuf;
|
||||
}
|
||||
s = strrchr (locale, '.');
|
||||
if (s)
|
||||
{
|
||||
strcpy (charsetbuf, s+1);
|
||||
t = strchr (charsetbuf, '@');
|
||||
if (t)
|
||||
*t = 0;
|
||||
return charsetbuf;
|
||||
}
|
||||
strcpy (charsetbuf, locale);
|
||||
return charsetbuf;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
u32reset ()
|
||||
{
|
||||
u32init = 0;
|
||||
utf8locale = 0;
|
||||
}
|
||||
|
||||
/* u32toascii ? */
|
||||
int
|
||||
u32tochar (x, s)
|
||||
unsigned long x;
|
||||
char *s;
|
||||
{
|
||||
int l;
|
||||
|
||||
l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4);
|
||||
|
||||
if (x <= UCHAR_MAX)
|
||||
s[0] = x & 0xFF;
|
||||
else if (x <= USHORT_MAX) /* assume unsigned short = 16 bits */
|
||||
{
|
||||
s[0] = (x >> 8) & 0xFF;
|
||||
s[1] = x & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
s[0] = (x >> 24) & 0xFF;
|
||||
s[1] = (x >> 16) & 0xFF;
|
||||
s[2] = (x >> 8) & 0xFF;
|
||||
s[3] = x & 0xFF;
|
||||
}
|
||||
s[l] = '\0';
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Convert unsigned 32-bit int to utf-8 character string */
|
||||
int
|
||||
u32toutf8 (wc, s)
|
||||
u_bits32_t wc;
|
||||
char *s;
|
||||
{
|
||||
int l;
|
||||
|
||||
if (wc < 0x0080)
|
||||
{
|
||||
s[0] = (char)wc;
|
||||
l = 1;
|
||||
}
|
||||
else if (wc < 0x0800)
|
||||
{
|
||||
s[0] = (wc >> 6) | 0xc0;
|
||||
s[1] = (wc & 0x3f) | 0x80;
|
||||
l = 2;
|
||||
}
|
||||
else if (wc < 0x10000)
|
||||
{
|
||||
s[0] = (wc >> 12) | 0xe0;
|
||||
s[1] = ((wc >> 6) & 0x3f) | 0x80;
|
||||
s[2] = (wc & 0x3f) | 0x80;
|
||||
l = 3;
|
||||
}
|
||||
else if (wc < 0x200000)
|
||||
{
|
||||
s[0] = (wc >> 18) | 0xf0;
|
||||
s[1] = ((wc >> 12) & 0x3f) | 0x80;
|
||||
s[2] = ((wc >> 6) & 0x3f) | 0x80;
|
||||
s[3] = (wc & 0x3f) | 0x80;
|
||||
l = 4;
|
||||
}
|
||||
/* Strictly speaking, UTF-8 doesn't have characters longer than 4 bytes */
|
||||
else if (wc < 0x04000000)
|
||||
{
|
||||
s[0] = (wc >> 24) | 0xf8;
|
||||
s[1] = ((wc >> 18) & 0x3f) | 0x80;
|
||||
s[2] = ((wc >> 12) & 0x3f) | 0x80;
|
||||
s[3] = ((wc >> 6) & 0x3f) | 0x80;
|
||||
s[4] = (wc & 0x3f) | 0x80;
|
||||
l = 5;
|
||||
}
|
||||
else if (wc < 0x080000000)
|
||||
{
|
||||
s[0] = (wc >> 30) | 0xf8;
|
||||
s[1] = ((wc >> 24) & 0x3f) | 0x80;
|
||||
s[2] = ((wc >> 18) & 0x3f) | 0x80;
|
||||
s[3] = ((wc >> 12) & 0x3f) | 0x80;
|
||||
s[4] = ((wc >> 6) & 0x3f) | 0x80;
|
||||
s[5] = (wc & 0x3f) | 0x80;
|
||||
l = 6;
|
||||
}
|
||||
else
|
||||
l = 0;
|
||||
|
||||
s[l] = '\0';
|
||||
return l;
|
||||
}
|
||||
|
||||
/* Convert a 32-bit unsigned int (unicode) to a UTF-16 string. Rarely used,
|
||||
only if sizeof(wchar_t) == 2. */
|
||||
int
|
||||
u32toutf16 (c, s)
|
||||
u_bits32_t c;
|
||||
unsigned short *s;
|
||||
{
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
if (c < 0x0d800)
|
||||
{
|
||||
s[0] = (unsigned short) (c & 0xFFFF);
|
||||
l = 1;
|
||||
}
|
||||
else if (c >= 0x0e000 && c <= 0x010ffff)
|
||||
{
|
||||
c -= 0x010000;
|
||||
s[0] = (unsigned short)((c >> 10) + 0xd800);
|
||||
s[1] = (unsigned short)((c & 0x3ff) + 0xdc00);
|
||||
l = 2;
|
||||
}
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
/* convert a single unicode-32 character into a multibyte string and put the
|
||||
result in S, which must be large enough (at least MB_LEN_MAX bytes) */
|
||||
int
|
||||
u32cconv (c, s)
|
||||
unsigned long c;
|
||||
char *s;
|
||||
{
|
||||
wchar_t wc;
|
||||
wchar_t ws[3];
|
||||
int n;
|
||||
#if HAVE_ICONV
|
||||
const char *charset;
|
||||
char obuf[25], *optr;
|
||||
size_t obytesleft;
|
||||
const char *iptr;
|
||||
size_t sn;
|
||||
#endif
|
||||
|
||||
#if __STDC_ISO_10646__
|
||||
wc = c;
|
||||
if (sizeof (wchar_t) == 4 && c <= 0x7fffffff)
|
||||
{
|
||||
n = wctomb (s, wc);
|
||||
if (n != -1)
|
||||
return n;
|
||||
}
|
||||
else if (sizeof (wchar_t) == 2)
|
||||
{
|
||||
if (u32toutf16 (c, ws))
|
||||
{
|
||||
n = wcstombs (s, ws, MB_LEN_MAX);
|
||||
if (n != -1)
|
||||
return n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_NL_LANGINFO
|
||||
codeset = nl_langinfo (CODESET);
|
||||
if (STREQ (codeset, "UTF-8"))
|
||||
{
|
||||
n = u32toutf8 (c, s);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_ICONV
|
||||
/* this is mostly from coreutils-8.5/lib/unicodeio.c */
|
||||
if (u32init == 0)
|
||||
{
|
||||
# if HAVE_LOCALE_CHARSET
|
||||
charset = locale_charset (); /* XXX - fix later */
|
||||
# else
|
||||
charset = stub_charset ();
|
||||
# endif
|
||||
if (STREQ (charset, "UTF-8"))
|
||||
utf8locale = 1;
|
||||
else
|
||||
{
|
||||
localconv = iconv_open (charset, "UTF-8");
|
||||
if (localconv == (iconv_t)-1)
|
||||
localconv = iconv_open (charset, "ASCII");
|
||||
}
|
||||
u32init = 1;
|
||||
}
|
||||
|
||||
if (utf8locale)
|
||||
{
|
||||
n = u32toutf8 (c, s);
|
||||
return n;
|
||||
}
|
||||
|
||||
if (localconv == (iconv_t)-1)
|
||||
{
|
||||
n = u32tochar (c, s);
|
||||
return n;
|
||||
}
|
||||
|
||||
n = u32toutf8 (c, s);
|
||||
|
||||
optr = obuf;
|
||||
obytesleft = sizeof (obuf);
|
||||
iptr = s;
|
||||
sn = n;
|
||||
|
||||
iconv (localconv, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1)
|
||||
return n; /* You get utf-8 if iconv fails */
|
||||
|
||||
*optr = '\0';
|
||||
|
||||
/* number of chars to be copied is optr - obuf if we want to do bounds
|
||||
checking */
|
||||
strcpy (s, obuf);
|
||||
return (optr - obuf);
|
||||
#endif
|
||||
|
||||
n = u32tochar (c, s); /* fallback */
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
void
|
||||
u32reset ()
|
||||
{
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
@@ -1,6 +1,6 @@
|
||||
/* locale.c - Miscellaneous internationalization functions. */
|
||||
|
||||
/* Copyright (C) 1996-2009 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996-2009,2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
||||
+8
-2
@@ -4666,12 +4666,18 @@ sv_locale (name)
|
||||
char *name;
|
||||
{
|
||||
char *v;
|
||||
int r;
|
||||
|
||||
v = get_string_value (name);
|
||||
if (name[0] == 'L' && name[1] == 'A') /* LANG */
|
||||
set_lang (name, v);
|
||||
r = set_lang (name, v);
|
||||
else
|
||||
set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
|
||||
r = set_locale_var (name, v); /* LC_*, TEXTDOMAIN* */
|
||||
|
||||
#if 1
|
||||
if (r == 0 && posixly_correct)
|
||||
last_command_exit_value = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
|
||||
Reference in New Issue
Block a user