more changes for bracket expressions in patterns

This commit is contained in:
Chet Ramey
2022-12-02 11:41:48 -05:00
parent e8652353ae
commit 198210c58f
20 changed files with 948 additions and 150 deletions
+34
View File
@@ -4579,3 +4579,37 @@ variables.c
find_variable_last_nameref_context: make sure to return
&nameref_maxloop_value consistently and handle getting it as a
return value from other functions
11/29
-----
lib/readline/display.c
- _rl_update_final: if there is only one line (_rl_vis_botlin == 0)
and that line is empty (botline_length == 0), assume there is no
prompt and the line has no contents, so output the CR/LF to indicate
that the newline has been read. From a report from
Kevin Pulo <kev@pulo.com.au>
11/30
-----
builtins/evalstring.c
- parse_and_execute: if we are executing the eval builtin, and the
return status from the command is suppressed (builtin_ignoring_errexit),
set CMD_IGNORE_RETURN in the parsed command's flags. From a report
from Tycho Kirchner <tychokirchner@mail.de>
12/1
----
lib/glob/sm_loop.c
- PARSE_SUBBRACKET: a reworked PARSE_COLLSYM, generalized to handle
[:, [=, and [. special bracket expressions
- BRACKMATCH: change to use PARSE_SUBBRACKET consistently to parse
[:, [=, and [. special bracket expressions
- PATSCAN: takes new FLAGS arg, changed all callers to just pass the
flags they get through to PATSCAN
- PATSCAN: call PARSE_SUBBRACKET for [:, [=, and [. to treat them
consistently (uses FLAGS argument here)
- PATSCAN: handle FNM_NOESCAPE appearing in FLAGS argument
This set of fixes contributed by Koichi Murase <myoga.murase@gmail.com>
lib/glob/{glob,gmisc}.c
- PATSCAN: change all callers to add extra flags arg of 0
+4
View File
@@ -1168,6 +1168,8 @@ tests/globstar.right f
tests/globstar1.sub f
tests/globstar2.sub f
tests/globstar3.sub f
tests/glob-bracket.tests f
tests/glob-bracket.right f
tests/heredoc.tests f
tests/heredoc.right f
tests/heredoc1.sub f
@@ -1414,6 +1416,7 @@ tests/run-extglob3 f
tests/run-func f
tests/run-getopts f
tests/run-glob-test f
tests/run-glob-bracket f
tests/run-globstar f
tests/run-heredoc f
tests/run-herestr f
@@ -1494,6 +1497,7 @@ tests/trap3.sub f
tests/trap4.sub f
tests/trap5.sub f
tests/trap6.sub f
tests/trap7.sub f
tests/type.tests f
tests/type.right f
tests/type1.sub f
+7 -1
View File
@@ -234,6 +234,7 @@ parse_prologue (string, flags, tag)
unwind_protect_int (loop_level);
unwind_protect_int (executing_list);
unwind_protect_int (comsub_ignore_return);
unwind_protect_int (builtin_ignoring_errexit);
if (flags & (SEVAL_NONINT|SEVAL_INTERACT))
unwind_protect_int (interactive);
@@ -299,7 +300,7 @@ parse_and_execute (string, from_file, flags)
const char *from_file;
int flags;
{
int code, lreset;
int code, lreset, ignore_return;
volatile int should_jump_to_top_level, last_result;
COMMAND *volatile command;
volatile sigset_t pe_sigmask;
@@ -309,6 +310,8 @@ parse_and_execute (string, from_file, flags)
parse_and_execute_level++;
lreset = flags & SEVAL_RESETLINE;
ignore_return = (this_shell_builtin == eval_builtin || this_shell_builtin == source_builtin) &&
builtin_ignoring_errexit;
#if defined (HAVE_POSIX_SIGNALS)
/* If we longjmp and are going to go on, use this to restore signal mask */
@@ -476,6 +479,9 @@ parse_and_execute (string, from_file, flags)
if ((subshell_environment & SUBSHELL_COMSUB) && comsub_ignore_return)
command->flags |= CMD_IGNORE_RETURN;
if (ignore_return)
command->flags |= CMD_IGNORE_RETURN;
#if defined (ONESHOT)
/*
* IF
+1 -1
View File
@@ -3984,7 +3984,7 @@ Matches anything except one of the given patterns
.RE
.PD
.PP
The\fBextglob\fP option changes the behavior of the parser, since the
The \fBextglob\fP option changes the behavior of the parser, since the
parentheses are normally treated as operators with syntactic meaning.
To ensure that extended matching patterns are parsed correctly, make sure
that \fBextglob\fP is enabled before parsing constructs containing the
+6 -6
View File
@@ -127,8 +127,8 @@ static int glob_testdir PARAMS((char *, int));
static char **glob_dir_to_array PARAMS((char *, char **, int));
/* Make sure these names continue to agree with what's in smatch.c */
extern char *glob_patscan PARAMS((char *, char *, int));
extern wchar_t *glob_patscan_wc PARAMS((wchar_t *, wchar_t *, int));
extern char *glob_patscan PARAMS((char *, char *, int, int));
extern wchar_t *glob_patscan_wc PARAMS((wchar_t *, wchar_t *, wint_t, int));
/* And this from gmisc.c/gm_loop.c */
extern int wextglob_pattern_p PARAMS((wchar_t *));
@@ -207,7 +207,7 @@ extglob_skipname (pat, dname, flags)
wild = *pat == '*' || *pat == '?';
pp = pat + 2;
se = pp + strlen (pp); /* end of pattern string */
pe = glob_patscan (pp, se, 0); /* end of extglob pattern */
pe = glob_patscan (pp, se, 0, 0); /* end of extglob pattern */
/* if pe == 0, this is an invalid extglob pattern */
if (pe == 0)
@@ -234,7 +234,7 @@ extglob_skipname (pat, dname, flags)
nullpat = pe >= (pat + 2) && pe[-2] == '(' && pe[-1] == ')';
/* check every subpattern */
while (t = glob_patscan (pp, pe, '|'))
while (t = glob_patscan (pp, pe, '|', 0))
{
/* If T == PE and *T == 0 (&& PE[-1] == RPAREN), we have hit the end
of a pattern with no trailing characters. */
@@ -358,7 +358,7 @@ wextglob_skipname (pat, dname, flags)
wild = *pat == L'*' || *pat == L'?';
pp = pat + 2;
se = pp + wcslen (pp);
pe = glob_patscan_wc (pp, se, 0);
pe = glob_patscan_wc (pp, se, 0, 0);
/* if pe == 0, this is an invalid extglob pattern */
if (pe == 0)
@@ -382,7 +382,7 @@ wextglob_skipname (pat, dname, flags)
nullpat = pe >= (pat + 2) && pe[-2] == L'(' && pe[-1] == L')';
/* check every subpattern */
while (t = glob_patscan_wc (pp, pe, '|'))
while (t = glob_patscan_wc (pp, pe, '|', 0))
{
n = t[-1]; /* ( */
if (wextglob_pattern_p (pp) && n == L')') /* nested extglob? */
+2 -2
View File
@@ -38,7 +38,7 @@
#include "glob.h"
/* Make sure these names continue to agree with what's in smatch.c */
extern char *glob_patscan PARAMS((char *, char *, int));
extern char *glob_patscan PARAMS((char *, char *, int, int));
/* Compile `gm_loop.c' for single-byte characters. */
#define CHAR char
@@ -92,7 +92,7 @@ glob_dirscan (pat, dirsep)
{
if (se == 0)
se = p + strlen (p) - 1;
pe = glob_patscan (p + 2, se, 0);
pe = glob_patscan (p + 2, se, 0, 0);
if (pe == 0)
continue;
else if (*pe == 0)
+79 -122
View File
@@ -27,13 +27,13 @@ struct STRUCT
int FCT PARAMS((CHAR *, CHAR *, int));
static int GMATCH PARAMS((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, int));
static CHAR *PARSE_COLLSYM PARAMS((CHAR *, INT *));
static inline CHAR *PARSE_SUBBRACKET PARAMS((CHAR *, int));
static CHAR *BRACKMATCH PARAMS((CHAR *, U_CHAR, int));
static int EXTMATCH PARAMS((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
extern void DEQUOTE_PATHNAME PARAMS((CHAR *));
/*static*/ CHAR *PATSCAN PARAMS((CHAR *, CHAR *, INT));
/*static*/ CHAR *PATSCAN PARAMS((CHAR *, CHAR *, INT, int));
int
FCT (pattern, string, flags)
@@ -192,7 +192,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
that's OK, since we can match 0 or 1 occurrences.
We need to skip the glob pattern and see if we
match the rest of the string. */
newn = PATSCAN (p + 1, pe, 0);
newn = PATSCAN (p + 1, pe, 0, flags);
/* If NEWN is 0, we have an ill-formed pattern. */
p = newn ? newn : pe;
}
@@ -225,7 +225,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
that's OK, since we can match 0 or more occurrences.
We need to skip the glob pattern and see if we
match the rest of the string. */
newn = PATSCAN (p + 1, pe, 0);
newn = PATSCAN (p + 1, pe, 0, flags);
/* If NEWN is 0, we have an ill-formed pattern. */
p = newn ? newn : pe;
}
@@ -380,36 +380,28 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
return (FNM_NOMATCH);
}
/* Parse a bracket expression collating symbol ([.sym.]) starting at P, find
the value of the symbol, and move P past the collating symbol expression.
The value is returned in *VP, if VP is not null. */
static CHAR *
PARSE_COLLSYM (p, vp)
CHAR *p;
INT *vp;
{
register int pc;
INT val;
p++; /* move past the `.' */
for (pc = 0; p[pc]; pc++)
if (p[pc] == L('.') && p[pc+1] == L(']'))
break;
if (p[pc] == 0)
{
if (vp)
*vp = INVALID;
return (p + pc);
}
val = COLLSYM (p, pc);
if (vp)
*vp = val;
return (p + pc + 2);
}
#define SLASH_PATHNAME(c) (c == L('/') && (flags & FNM_PATHNAME))
/* Parse a special bracket expression symbol ([.sym.], [=char=], [:cclass:]),
starting at P, and return the position of the terminating .], =], or :].
P points to the character after the opening bracket. Returns NULL if the
symbol isn't correctly terminated. */
static inline CHAR *
PARSE_SUBBRACKET (p, flags)
CHAR *p;
int flags;
{
CHAR type; /* the type of special bracket expression symbol */
type = *p;
/* POSIX allows a right bracket to appear in a collating symbol. */
while (*++p != L('\0') && SLASH_PATHNAME (*p) == 0 && (type != L('.') && *p == L(']')) == 0)
if (*p == type && p[1] == L(']'))
return p;
return NULL;
}
/* Use prototype definition here because of type promotion. */
static CHAR *
#if defined (PROTOTYPES)
@@ -423,10 +415,10 @@ BRACKMATCH (p, test, flags)
{
register CHAR cstart, cend, c;
register int not; /* Nonzero if the sense of the character class is inverted. */
int brcnt, forcecoll, isrange;
int forcecoll, isrange;
INT pc;
CHAR *savep;
CHAR *brchrp;
CHAR *close;
U_CHAR orig_test;
orig_test = test;
@@ -451,18 +443,13 @@ BRACKMATCH (p, test, flags)
/* POSIX.2 equivalence class: [=c=]. See POSIX.2 2.8.3.2. Find
the end of the equivalence class, move the pattern pointer past
it, and check for equivalence. XXX - this handles only
single-character equivalence classes, which is wrong, or at
least incomplete. */
if (c == L('[') && *p == L('=') && p[2] == L('=') && p[3] == L(']'))
it, and check for equivalence. */
if (c == L('[') && *p == L('=') && (close = PARSE_SUBBRACKET (p, flags)) != NULL)
{
pc = FOLD (p[1]);
p += 4;
/* Finding a slash in a bracket expression means you have to
match the bracket as an ordinary character (see below). */
if (pc == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
p++;
pc = COLLSYM (p, close - p);
pc = FOLD (pc);
p = close + 2;
if (COLLEQUIV (test, pc))
{
@@ -486,30 +473,21 @@ BRACKMATCH (p, test, flags)
}
/* POSIX.2 character class expression. See POSIX.2 2.8.3.2. */
if (c == L('[') && *p == L(':'))
if (c == L('[') && *p == L(':') && (close = PARSE_SUBBRACKET (p, flags)) != NULL)
{
CHAR *close, *ccname;
CHAR *ccname;
pc = 0; /* make sure invalid char classes don't match. */
/* Find end of character class name */
for (close = p + 1; *close != '\0' && SLASH_PATHNAME(*close) == 0; close++)
if (*close == L(':') && *(close+1) == L(']'))
break;
if (*close != L('\0') && SLASH_PATHNAME(*close) == 0)
ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR));
if (ccname)
{
ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR));
if (ccname == 0)
pc = 0;
else
{
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
*(ccname + (close - p - 1)) = L('\0');
/* As a result of a POSIX discussion, char class names are
allowed to be quoted (?) */
DEQUOTE_PATHNAME (ccname);
pc = IS_CCLASS (orig_test, (XCHAR *)ccname);
}
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
*(ccname + (close - p - 1)) = L('\0');
/* As a result of a POSIX discussion, char class names are
allowed to be quoted (?) */
DEQUOTE_PATHNAME (ccname);
pc = IS_CCLASS (orig_test, (XCHAR *)ccname);
if (pc == -1)
{
/* CCNAME is not a valid character class in the current
@@ -521,14 +499,12 @@ BRACKMATCH (p, test, flags)
string. If we don't want to do that, take out the update
of P. */
pc = 0;
p = close + 2;
}
else
p = close + 2; /* move past the closing `]' */
free (ccname);
}
free (ccname);
p = close + 2;
if (pc)
{
/*[*/ /* Move past the closing `]', since the first thing we do at
@@ -556,13 +532,11 @@ BRACKMATCH (p, test, flags)
the symbol name, make sure it is terminated by `.]', translate
the name to a character using the external table, and do the
comparison. */
if (c == L('[') && *p == L('.'))
if (c == L('[') && *p == L('.') && (close = PARSE_SUBBRACKET (p, flags)) != NULL)
{
p = PARSE_COLLSYM (p, &pc);
/* An invalid collating symbol cannot be the first point of a
range. If it is, we set cstart to one greater than `test',
so any comparisons later will fail. */
cstart = (pc == INVALID) ? test + 1 : pc;
p++;
cstart = COLLSYM (p, close - p);
p = close + 2;
forcecoll = 1;
}
@@ -616,13 +590,11 @@ BRACKMATCH (p, test, flags)
return ((test == L('[')) ? savep : (CHAR *)0);
else if (cend == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
if (cend == L('[') && *p == L('.'))
if (cend == L('[') && *p == L('.') && (close = PARSE_SUBBRACKET (p, flags)) != NULL)
{
p = PARSE_COLLSYM (p, &pc);
/* An invalid collating symbol cannot be the second part of a
range expression. If we get one, we set cend to one fewer
than the test character to make sure the range test fails. */
cend = (pc == INVALID) ? test - 1 : pc;
p++;
cend = COLLSYM (p, close - p);
p = close + 2;
forcecoll = 1;
}
cend = FOLD (cend);
@@ -658,46 +630,29 @@ BRACKMATCH (p, test, flags)
matched:
/* Skip the rest of the [...] that already matched. */
c = *--p;
brcnt = 1;
brchrp = 0;
while (brcnt > 0)
while (1)
{
int oc;
/* A `[' without a matching `]' is just another character to match. */
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
oc = c;
c = *p++;
if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.')))
{
brcnt++;
brchrp = p++; /* skip over the char after the left bracket */
c = *p;
if (c == L('\0'))
return ((test == L('[')) ? savep : (CHAR *)0);
else if (c == L('/') && (flags & FNM_PATHNAME))
return ((test == L('[')) ? savep : (CHAR *)0);
/* If *brchrp == ':' we should check that the rest of the characters
form a valid character class name. We don't do that yet, but we
keep BRCHRP in case we want to. */
}
/* We only want to check brchrp if we set it above. */
else if (c == L(']') && brcnt > 1 && brchrp != 0 && oc == *brchrp)
{
brcnt--;
brchrp = 0; /* just in case */
if ((close = PARSE_SUBBRACKET (p, flags)) != NULL)
p = close + 2;
}
/* Left bracket loses its special meaning inside a bracket expression.
It is only valid when followed by a `.', `=', or `:', which we check
for above. Technically the right bracket can appear in a collating
symbol, so we check for that here. Otherwise, it terminates the
bracket expression. */
else if (c == L(']') && (brchrp == 0 || *brchrp != L('.')) && brcnt >= 1)
brcnt = 0;
symbol, so we check for that as well. The right brackets terminating
collating symbols, equivalence classes, or character classes are
processed by PARSE_SUBBRACKET. Otherwise, a right bracket terminates
the bracket expression. */
else if (c == L(']'))
break;
else if (!(flags & FNM_NOESCAPE) && c == L('\\'))
{
if (*p == '\0')
@@ -734,16 +689,15 @@ matched:
first character after the matching DELIM or NULL if the pattern is
empty or invalid. */
/*static*/ CHAR *
PATSCAN (string, end, delim)
PATSCAN (string, end, delim, flags)
CHAR *string, *end;
INT delim;
int flags;
{
int pnest, bnest, skip;
INT cchar;
CHAR *s, c, *bfirst;
CHAR *s, c, *bfirst, *t;
pnest = bnest = skip = 0;
cchar = 0;
bfirst = NULL;
if (string == end)
@@ -761,7 +715,8 @@ PATSCAN (string, end, delim)
switch (c)
{
case L('\\'):
skip = 1;
if ((flags & FNM_NOESCAPE) == 0)
skip = 1;
break;
case L('\0'):
@@ -779,7 +734,11 @@ PATSCAN (string, end, delim)
bnest++;
}
else if (s[1] == L(':') || s[1] == L('.') || s[1] == L('='))
cchar = s[1];
{
t = PARSE_SUBBRACKET (s + 1, flags);
if (t)
s = t + 2 - 1; /* -1 to cancel s++ in loop above */
}
break;
/* `]' is not special if it's the first char (after a leading `!'
@@ -788,9 +747,7 @@ PATSCAN (string, end, delim)
case L(']'):
if (bnest)
{
if (cchar && s[-1] == cchar)
cchar = 0;
else if (s != bfirst)
if (s != bfirst)
{
bnest--;
bfirst = 0;
@@ -879,7 +836,7 @@ fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe);
fprintf(stderr, "extmatch: flags = %d\n", flags);
#endif
prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
prest = PATSCAN (p + (*p == L('(')), pe, 0, flags); /* ) */
if (prest == 0)
/* If PREST is 0, we failed to scan a valid pattern. In this
case, we just want to compare the two as strings. */
@@ -902,7 +859,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
string. */
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
pnext = PATSCAN (psub, pe, L('|'), flags);
for (srest = s; srest <= se; srest++)
{
/* Match this substring (S -> SREST) against this
@@ -939,7 +896,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
rest of the string. */
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
pnext = PATSCAN (psub, pe, L('|'), flags);
srest = (prest == pe) ? se : s;
for ( ; srest <= se; srest++)
{
@@ -960,7 +917,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
m1 = 0;
for (psub = p + 1; ; psub = pnext)
{
pnext = PATSCAN (psub, pe, L('|'));
pnext = PATSCAN (psub, pe, L('|'), flags);
/* If one of the patterns matches, just bail immediately. */
if (m1 = (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0))
break;
@@ -1001,7 +958,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
#undef FCT
#undef GMATCH
#undef COLLSYM
#undef PARSE_COLLSYM
#undef PARSE_SUBBRACKET
#undef PATSCAN
#undef STRCOMPARE
#undef EXTMATCH
+2 -2
View File
@@ -322,7 +322,7 @@ is_cclass (c, name)
#define FCT internal_strmatch
#define GMATCH gmatch
#define COLLSYM collsym
#define PARSE_COLLSYM parse_collsym
#define PARSE_SUBBRACKET parse_subbracket
#define BRACKMATCH brackmatch
#define PATSCAN glob_patscan
#define STRCOMPARE strcompare
@@ -578,7 +578,7 @@ posix_cclass_only (pattern)
#define FCT internal_wstrmatch
#define GMATCH gmatch_wc
#define COLLSYM collwcsym
#define PARSE_COLLSYM parse_collwcsym
#define PARSE_SUBBRACKET parse_subbracket_wc
#define BRACKMATCH brackmatch_wc
#define PATSCAN glob_patscan_wc
#define STRCOMPARE wscompare
+2 -2
View File
@@ -3394,9 +3394,9 @@ _rl_update_final (void)
puts_face (&last_line[_rl_screenwidth - 1 + woff],
&last_face[_rl_screenwidth - 1 + woff], 1);
}
_rl_vis_botlin = 0;
if (botline_length > 0 || _rl_last_c_pos > 0)
if ((_rl_vis_botlin == 0 && botline_length == 0) || botline_length > 0 || _rl_last_c_pos > 0)
rl_crlf ();
_rl_vis_botlin = 0;
fflush (rl_outstream);
rl_display_fixed++;
}
+1 -1
View File
@@ -25,6 +25,6 @@
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
looks for to find the patch level (for the sccs version string). */
#define PATCHLEVEL 9
#define PATCHLEVEL 12
#endif /* _PATCHLEVEL_H_ */
BIN
View File
Binary file not shown.
+10 -11
View File
@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: bash-5.2-rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-01-11 14:50-0500\n"
"PO-Revision-Date: 2022-06-25 01:50+0900\n"
"PO-Revision-Date: 2022-11-29 14:23+0900\n"
"Last-Translator: Seong-ho Cho <darkcircle.0426@gmail.com>\n"
"Language-Team: Korean <translation-team-ko@googlegroups.com>\n"
"Language: ko\n"
@@ -566,7 +566,7 @@ msgstr ""
"셸에 대한 일반적인 정보를 더 확인하려면 `info bash'를 사용하십시오.\n"
"이 목록에 없는 명령어에 대해 더 알아보려면 `man -k' 또는 `info'를 사용하십시오.\n"
"\n"
"명령어 이름 다음의 별(*) 표시는 해당 명령어의 비활성 상태을 의미합니다.\n"
"명령어 이름 다음의 별(*) 표시는 해당 명령어를 사용하지 않음을 의미합니다.\n"
"\n"
#: builtins/history.def:159
@@ -1737,7 +1737,7 @@ msgstr "셸 옵션:\n"
#: shell.c:2069
msgid "\t-ilrsD or -c command or -O shopt_option\t\t(invocation only)\n"
msgstr "\t-ilrsD 또는 -c <명령> 또는 -O shopt_option\t\t(invocation 전용)\n"
msgstr "\t-ilrsD 또는 -c <명령> 또는 -O <shopt_옵션>\t\t(실행 전용)\n"
#: shell.c:2088
#, c-format
@@ -2289,7 +2289,7 @@ msgstr "eval [인자 ...]"
#: builtins.c:96
msgid "getopts optstring name [arg ...]"
msgstr "getopts optstring name [<인자> ...]"
msgstr "getopts <옵션문자열> <이름> [<인자> ...]"
#: builtins.c:98
msgid "exec [-cl] [-a name] [command [argument ...]] [redirection ...]"
@@ -2309,11 +2309,11 @@ msgstr "fc [-e <편집기이름>] [-lnr] [<처음>] [<종결>] 또는 fc -s [<
#: builtins.c:109
msgid "fg [job_spec]"
msgstr "fg [<JOBSPEC>]"
msgstr "fg [<작업명세>]"
#: builtins.c:113
msgid "bg [job_spec ...]"
msgstr "bg [<JOBSPEC> ...]"
msgstr "bg [<작업명세> ...]"
#: builtins.c:116
msgid "hash [-lr] [-p pathname] [-dt] [name ...]"
@@ -2329,15 +2329,15 @@ msgstr "history [-c] [-d <오프셋>] [n] 또는 history -anrw [<파일이름>]
#: builtins.c:127
msgid "jobs [-lnprs] [jobspec ...] or jobs -x command [args]"
msgstr "jobs [-lnprs] [jobspec ...] 또는 jobs -x command [args]"
msgstr "jobs [-lnprs] [<작업명세> ...] 또는 jobs -x <명령> [<인자> ...]"
#: builtins.c:131
msgid "disown [-h] [-ar] [jobspec ... | pid ...]"
msgstr "disown [-h] [-ar] [<JOBSPEC> ... | <PID> ...]"
msgstr "disown [-h] [-ar] [<작업명세> ... | <PID> ...]"
#: builtins.c:134
msgid "kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]"
msgstr "kill [-s <시그널명세> | -n <시그널번호> | -<시그널명세>] <PID> | <JOBSPEC> ... 또는 kill -l [<시그널명세>]"
msgstr "kill [-s <시그널명세> | -n <시그널번호> | -<시그널명세>] <PID> | <작업명세> ... 또는 kill -l [<시그널명세>]"
#: builtins.c:136
msgid "let arg [arg ...]"
@@ -5057,8 +5057,7 @@ msgstr ""
" HOME\t로그인 후 접근하는 완전한 경로 이름입니다.\n"
" HOSTNAME\t현재 호스트 이름입니다.\n"
" HOSTTYPE\t이 배시 버전이 실행하고 있는 시스템의 CPU 형식입니다.\n"
" IGNOREEOF\n"
"EOF 문자 입력을 유일한 입력으로 받는 셸의 동작을\n"
" IGNOREEOF\tEOF 문자 입력을 유일한 입력으로 받는 셸의 동작을\n"
" \t\t제어합니다. 설정하면, 이 변수의 값은 셸을 나가기\n"
" \t\t전 빈 줄에 한줄로 나타낼 EOF 문자 수 입니다 (기본 10개).\n"
" \t\t설정을 해제하면, EOF는 입력 끝을 나타냅니다.\n"
+103
View File
@@ -0,0 +1,103 @@
--- $GLOBIGNORE vs fnmatch(3) ---
#1: pat=ab/cd/efg yes/yes
#2: pat=ab[/]cd/efg no/no
#3: pat=ab[/a]cd/efg no/no
#4: pat=ab[a/]cd/efg no/no
#5: pat=ab[!a]cd/efg no/no
#6: pat=ab[.-0]cd/efg no/no
#7: pat=*/*/efg yes/yes
#8: pat=*[/]*/efg no/no
#9: pat=*[/a]*/efg no/no
#10: pat=*[a/]*/efg no/no
#11: pat=*[!a]*/efg no/no
#12: pat=*[.-0]*/efg no/no
#13: pat=*/*/efg yes/yes
#14: pat=*[b]/*/efg yes/yes
#15: pat=*[ab]/*/efg yes/yes
#16: pat=*[ba]/*/efg yes/yes
#17: pat=*[!a]/*/efg yes/yes
#18: pat=*[a-c]/*/efg yes/yes
#19: pat=ab@(/)cd/efg no/no
#20: pat=*@(/)cd/efg no/no
#21: pat=*/cd/efg yes/yes
---Tests for a slash in bracket expressions---
#22: pat=ab[/]ef str=ab[/]ef yes/yes
#23: pat=ab[/]ef str=ab/ef no/no
#24: pat=ab[c/d]ef str=ab[c/d]ef yes/yes
#25: pat=ab[c/d]ef str=abcef no/no
#26: pat=ab[.-/]ef str=ab[.-/]ef yes/yes
#27: pat=ab[.-/]ef str=ab.ef no/no
#28: pat=ab[[=/=]]ef str=ab[[=/=]]ef yes/yes
#29: pat=ab[[=/=]]ef str=ab/ef no/no
#30: pat=ab[[=c=]/]ef str=ab[=/]ef yes/yes
#31: pat=ab[[=c=]/]ef str=abcef no/no
#32: pat=ab[[:alpha:]/]ef str=ab[:/]ef yes/yes
#33: pat=ab[[:alpha:]/]ef str=abxef no/no
#34: pat=ab[/[abc]]ef str=ab[/c]ef yes/yes
#35: pat=ab[/[abc]]ef str=abc]ef no/no
#36: pat=ab[c[=/=]]ef str=ab[c[=/=]]ef yes/yes
#37: pat=ab[c[=/=]]ef str=abc[=/=]ef no/no
#38: pat=ab[c[=/=]]ef str=abcef no/no
#39: pat=a[b\/c] str=a[b/c] yes/yes
#40: pat=a[b\/c] str=ab no/no
#41: pat=a[b\/c] str=ac no/no
---Tests for incomplete bracket expressions---
#42: pat=ab[c str=ab[c yes/yes
#43: pat=ab[c str=abc no/no
#44: pat=ab[c[=d= str=ab[c[=d= yes/yes
#45: pat=ab[c[=d= str=abc no/no
#46: pat=ab[c[.d str=ab[c[.d yes/yes
#47: pat=ab[c[.d str=abc no/no
#48: pat=ab[c[:alpha: str=ab[c[:alpha: yes/yes
#49: pat=ab[c[:alpha: str=abc no/no
#50: pat=ab[c- str=ab[c- yes/yes
#51: pat=ab[c- str=abc no/no
#52: pat=ab[c\ str=ab[c\ yes/yes
#53: pat=ab[c\ str=abc no/no
#54: pat=ab[[\ str=ab[[\ yes/yes
#55: pat=ab[[\ str=ab[ no/no
--- PATSCAN vs BRACKMATCH ---
#56: pat=@([[.].])A]) str=] yes/yes
#57: pat=@([[.].])A]) str===]A]) no/no
#58: pat=@([[.].])A]) str=AA]) no/no
#59: pat=@([[=]=])A]) str=] no/no
#60: pat=@([[=]=])A]) str===]A]) yes/yes
#61: pat=@([[=]=])A]) str=AA]) no/no
--- BRACKMATCH: after match vs before match ---
#62: pat=[[=]=]ab] str=a no/no
#63: pat=[[.[=.]ab] str=a yes/yes
#64: pat=[[.[==].]ab] str=a yes/yes
#65: pat=[a[=]=]b] str=a no/no
#66: pat=[a[.[=.]b] str=a yes/yes
#67: pat=[a[.[==].]b] str=a yes/yes
#68: pat=[a[=]=]b] str=b no/no
#69: pat=[a[=]=]b] str=a=]b] yes/yes
#70: pat=[a[.[=.]b] str=b yes/yes
#71: pat=[a[.[=.]b] str=ab] no/no
#72: pat=[a[.[==].]b] str=b yes/yes
#73: pat=[a[.[==].]b] str=ab] no/no
--- incomplete POSIX brackets ---
#74: pat=x[a[:y] str=x[ yes/yes
#75: pat=x[a[:y] str=x: yes/yes
#76: pat=x[a[:y] str=xy yes/yes
#77: pat=x[a[:y] str=x[ay no/no
#78: pat=x[a[.y] str=x[ yes/yes
#79: pat=x[a[.y] str=x. yes/yes
#80: pat=x[a[.y] str=xy yes/yes
#81: pat=x[a[.y] str=x[ay no/no
#82: pat=x[a[=y] str=x[ yes/yes
#83: pat=x[a[=y] str=x= yes/yes
#84: pat=x[a[=y] str=xy yes/yes
#85: pat=x[a[=y] str=x[ay no/no
--- MISC tests ---
#86: pat=a\ str=a\ yes/yes
+291
View File
@@ -0,0 +1,291 @@
# 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
#
# tests of various aspects of pathname expansion, mostly dealing with bracket
# expressions
LC_COLLATE=C
ORIG_DIR=$PWD
: ${TMPDIR:=/tmp} ${BUILD_DIR:=$ORIG_DIR}
trap 'rm -rf $TESTDIR $WORK_DIR' EXIT
WORK_DIR=${TMPDIR}/globtest-$$
mkdir $WORK_DIR || {
echo "cannot create directory $WORK_DIR" >&2
exit 1
}
cd $WORK_DIR || {
echo "cannot cd to directory $WORK_DIR" >&2
exit 1
}
gcc -O2 -xc -o ./fnmatch - <<-EOF
#include <fnmatch.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv) {
if (2 >= argc) {
fprintf(stderr, "usage: fnmatch string pattern\n");
exit(2);
}
#ifdef FNM_EXTMATCH
int flags = FNM_PATHNAME | FNM_PERIOD | FNM_EXTMATCH;
#else
int flags = FNM_PATHNAME | FNM_PERIOD;
#endif
if (fnmatch(argv[2], argv[1], flags) == 0)
return 0;
return 1;
}
EOF
eval $(grep -E '^(CC |SHOBJ_).*=' $BUILD_DIR/examples/loadables/Makefile | sed -e 's/[ ]*=[ ]*/="/' -e 's/$/"/' )
if [ "$SHOBJ_STATUS" != "supported" ]; then
echo "glob-bracket: shared objects not supported, cannot continue" >&2
exit 2
fi
cat > ./strmatch.c <<-EOF
#define BUILTIN_ENABLED 0x01
struct word_desc { char* word; int flags; };
struct word_list { struct word_list* next; struct word_desc* word; };
struct builtin {
const char* name;
int (*function)(struct word_list*);
int flags;
const char** long_doc;
const char* short_doc;
char* handle;
};
/*#include <glob/strmatch.h>*/
int strmatch(char *pattern, char *string, int flags);
#define FNM_PATHNAME (1 << 0)
#define FNM_NOESCAPE (1 << 1)
#define FNM_PERIOD (1 << 2)
#define FNM_LEADING_DIR (1 << 3)
#define FNM_CASEFOLD (1 << 4)
#define FNM_EXTMATCH (1 << 5)
#define FNM_FIRSTCHAR (1 << 6)
#define FNM_DOTDOT (1 << 7)
static int strmatch_builtin(struct word_list* list) {
char *str, *pat;
if (!list || !list->word) return 2;
str = list->word->word;
if (!list->next || !list->next->word) return 2;
pat = list->next->word->word;
if (strmatch (pat, str, FNM_PATHNAME | FNM_PERIOD | FNM_EXTMATCH) == 0)
return 0;
return 1;
}
static const char* strmatch_doc[] = { "This is a builtin to test the behavior of strmatch", 0 };
struct builtin strmatch_struct = { "strmatch", strmatch_builtin, BUILTIN_ENABLED, strmatch_doc, "strmatch string pattern", 0, };
EOF
${SHOBJ_CC} ${SHOBJ_CFLAGS} -c -o strmatch.o strmatch.c
rm -f strmatch.c
${SHOBJ_LD} ${SHOBJ_LDFLAGS} ${SHOBJ_XLDFLAGS} -o strmatch.so strmatch.o ${SHOBJ_LIBS}
rm -f strmatch.o
if [ ! -f strmatch.so ] ; then
echo "glob-bracket: cannot create strmatch loadable builtin" >&2
exit 2
fi
enable -f ./strmatch.so strmatch || {
echo "glob-bracket: cannot load strmatch builtin" >&2
exit 2
}
check_count=1
if [ -z "$BASH_TSTOUT" ]; then
yes=$(printf '\033[32myes\033[m') no=$(printf '\033[31mno\033[m')
else
yes=yes no=no
fi
function check {
# bash impl
if strmatch "$2" "$1"; then
local strmatch=$yes
else
local strmatch=$no
fi
# fnmatch
local expect=${3-}
if [[ ! $expect ]]; then
if $WORK_DIR/fnmatch "$2" "$1"; then
expect=$yes
else
expect=$no
fi
fi
printf '#%d: pat=%-20s str=%-16s %s/%s\n' "$((check_count++))" "$1" "$2" "$strmatch" "$expect"
}
function pcheck {
local GLOBIGNORE=$1
# bash impl
local -a f=(*/*/efg*)
if [[ $f == '*/*/efg*' ]]; then
local strmatch=$yes
else
local strmatch=$no
fi
# Linux fnmatch
if $WORK_DIR/fnmatch ab/cd/efg "$1"; then
local fnmatch=$yes
else
local fnmatch=$no
fi
printf '#%d: pat=%-16s %s/%s\n' "$((check_count++))" "$1" "$strmatch" "$fnmatch"
}
TESTDIR=${TMPDIR}/pathtest-$$
TESTPATH=${TESTDIR}/ab/cd/efg
mkdir -p $TESTPATH
if [ -d "$TESTPATH" ] && cd "$TESTDIR"; then
echo '--- $GLOBIGNORE vs fnmatch(3) ---'
pcheck 'ab/cd/efg'
pcheck 'ab[/]cd/efg'
pcheck 'ab[/a]cd/efg'
pcheck 'ab[a/]cd/efg'
pcheck 'ab[!a]cd/efg'
pcheck 'ab[.-0]cd/efg'
pcheck '*/*/efg'
pcheck '*[/]*/efg'
pcheck '*[/a]*/efg'
pcheck '*[a/]*/efg'
pcheck '*[!a]*/efg'
pcheck '*[.-0]*/efg'
pcheck '*/*/efg'
pcheck '*[b]/*/efg'
pcheck '*[ab]/*/efg'
pcheck '*[ba]/*/efg'
pcheck '*[!a]/*/efg'
pcheck '*[a-c]/*/efg'
pcheck 'ab@(/)cd/efg'
pcheck '*@(/)cd/efg'
pcheck '*/cd/efg'
cd "$WORK_DIR"
fi
echo
echo '---Tests for a slash in bracket expressions---'
check 'ab[/]ef' 'ab[/]ef' "$yes"
check 'ab[/]ef' 'ab/ef' "$no"
check 'ab[c/d]ef' 'ab[c/d]ef' "$yes"
check 'ab[c/d]ef' 'abcef' "$no"
check 'ab[.-/]ef' 'ab[.-/]ef' "$yes"
check 'ab[.-/]ef' 'ab.ef' "$no"
check 'ab[[=/=]]ef' 'ab[[=/=]]ef' "$yes"
check 'ab[[=/=]]ef' 'ab/ef' "$no"
check 'ab[[=c=]/]ef' 'ab[=/]ef' "$yes"
check 'ab[[=c=]/]ef' 'abcef' "$no"
check 'ab[[:alpha:]/]ef' 'ab[:/]ef' "$yes"
check 'ab[[:alpha:]/]ef' 'abxef' "$no"
check 'ab[/[abc]]ef' 'ab[/c]ef' "$yes"
check 'ab[/[abc]]ef' 'abc]ef' "$no"
check 'ab[c[=/=]]ef' 'ab[c[=/=]]ef' "$yes"
check 'ab[c[=/=]]ef' 'abc[=/=]ef' "$no"
check 'ab[c[=/=]]ef' 'abcef' "$no"
check 'a[b\/c]' 'a[b/c]' "$yes"
check 'a[b\/c]' 'ab' "$no"
check 'a[b\/c]' 'ac' "$no"
echo
echo '---Tests for incomplete bracket expressions---'
check 'ab[c' 'ab[c' "$yes"
check 'ab[c' 'abc' "$no"
check 'ab[c[=d=' 'ab[c[=d=' "$yes"
check 'ab[c[=d=' 'abc' "$no"
check 'ab[c[.d' 'ab[c[.d' "$yes"
check 'ab[c[.d' 'abc' "$no"
check 'ab[c[:alpha:' 'ab[c[:alpha:' "$yes"
check 'ab[c[:alpha:' 'abc' "$no"
check 'ab[c-' 'ab[c-' "$yes"
check 'ab[c-' 'abc' "$no"
check 'ab[c\' 'ab[c\' "$yes"
check 'ab[c\' 'abc' "$no"
check 'ab[[\' 'ab[[\' "$yes"
check 'ab[[\' 'ab[' "$no"
echo
echo '--- PATSCAN vs BRACKMATCH ---'
check '@([[.].])A])' ']' "$yes"
check '@([[.].])A])' '==]A])' "$no"
check '@([[.].])A])' 'AA])' "$no"
check '@([[=]=])A])' ']' "$no"
check '@([[=]=])A])' '==]A])' "$yes"
check '@([[=]=])A])' 'AA])' "$no"
echo
echo '--- BRACKMATCH: after match vs before match ---'
check '[[=]=]ab]' 'a' "$no"
check '[[.[=.]ab]' 'a' "$yes"
check '[[.[==].]ab]' 'a' "$yes"
echo
check '[a[=]=]b]' 'a' "$no"
check '[a[.[=.]b]' 'a' "$yes"
check '[a[.[==].]b]' 'a' "$yes"
echo
check '[a[=]=]b]' 'b' "$no"
check '[a[=]=]b]' 'a=]b]' "$yes"
check '[a[.[=.]b]' 'b' "$yes"
check '[a[.[=.]b]' 'ab]' "$no"
check '[a[.[==].]b]' 'b' "$yes"
check '[a[.[==].]b]' 'ab]' "$no"
echo
echo '--- incomplete POSIX brackets ---'
check 'x[a[:y]' 'x[' "$yes"
check 'x[a[:y]' 'x:' "$yes"
check 'x[a[:y]' 'xy' "$yes"
check 'x[a[:y]' 'x[ay' "$no"
echo
check 'x[a[.y]' 'x[' "$yes"
check 'x[a[.y]' 'x.' "$yes"
check 'x[a[.y]' 'xy' "$yes"
check 'x[a[.y]' 'x[ay' "$no"
echo
check 'x[a[=y]' 'x[' "$yes"
check 'x[a[=y]' 'x=' "$yes"
check 'x[a[=y]' 'xy' "$yes"
check 'x[a[=y]' 'x[ay' "$no"
echo
echo '--- MISC tests ---'
check 'a\' 'a\' "$yes"
cd $ORIG_DIR
exit 0
+388
View File
@@ -0,0 +1,388 @@
export LC_COLLATE=C
#
# test the shell globbing
#
expect()
{
echo expect "$@"
}
# First, a test that bash-2.01.1 fails
${THIS_SH} ./glob1.sub
MYDIR=$PWD # save where we are
TESTDIR=/tmp/glob-test
mkdir $TESTDIR
builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
rm -rf *
touch a b c d abc abd abe bb bcd ca cb dd de Beware
mkdir bdir
# see if `regular' globbing works right
expect '<a> <abc> <abd> <abe> <X*>'
recho a* X*
expect '<a> <abc> <abd> <abe>'
recho \a*
# see if null glob expansion works
shopt -s nullglob
expect '<a> <abc> <abd> <abe>'
recho a* X*
shopt -u nullglob
# see if the failglob option works
mkdir tmp
touch tmp/l1 tmp/l2 tmp/l3
builtin echo tmp/l[12] tmp/*4 tmp/*3
shopt -s failglob
builtin echo tmp/l[12] tmp/*4 tmp/*3
rm -r tmp
shopt -u failglob
# see if the code that expands directories only works
expect '<bdir/>'
recho b*/
# Test quoted and unquoted globbing characters
expect '<*>'
recho \*
expect '<a*>'
recho 'a*'
expect '<a*>'
recho a\*
expect '<c> <ca> <cb> <a*> <*q*>'
recho c* a\* *q*
expect '<**>'
recho "*"*
expect '<**>'
recho \**
expect '<\.\./*/>'
recho "\.\./*/"
expect '<s/\..*//>'
recho 's/\..*//'
# Pattern from Larry Wall's Configure that caused bash to blow up
expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
# Make sure character classes work properly
expect '<abc> <abd> <abe> <bb> <cb>'
recho [a-c]b*
expect '<abd> <abe> <bb> <bcd> <bdir> <ca> <cb> <dd> <de>'
recho [a-y]*[^c]
expect '<abd> <abe>'
recho a*[^c]
touch a-b aXb
expect '<a-b> <aXb>'
recho a[X-]b
touch .x .y
expect '<Beware> <d> <dd> <de>'
recho [^a-c]*
# Make sure that filenames with embedded globbing characters are handled
# properly
mkdir a\*b
> a\*b/ooo
expect '<a*b/ooo>'
recho a\*b/*
expect '<a*b/ooo>'
recho a\*?/*
expect '<no match>'
cmd='echo !7'
case "$cmd" in
*\\!*) echo match ;;
*) echo no match ;;
esac
expect '<not there>'
file='r.*'
case $file in
*.\*) echo not there ;;
*) echo there ;;
esac
# examples from the Posix.2 spec (d11.2, p. 243)
expect '<abc>'
recho a[b]c
expect '<abc>'
recho a["b"]c
expect '<abc>'
recho a[\b]c
expect '<abc>'
recho a?c
expect '<match 1>'
case abc in
a"b"c) echo 'match 1' ;;
*) echo 'BAD match 1' ;;
esac
expect '<match 2>'
case abc in
a*c) echo 'match 2' ;;
*) echo 'BAD match 2' ;;
esac
expect '<ok 1>'
case abc in
"a?c") echo 'bad 1' ;;
*) echo 'ok 1' ;;
esac
expect '<ok 2>'
case abc in
a\*c) echo 'bad 2' ;;
*) echo 'ok 2' ;;
esac
expect '<ok 3>'
case abc in
a\[b]c) echo 'bad 3' ;;
*) echo 'ok 3' ;;
esac
expect '<ok 4>'
case "$nosuchvar" in
"") echo 'ok 4' ;;
*) echo 'bad 4' ;;
esac
# This is very odd, but sh and ksh seem to agree
expect '<ok 5>'
case abc in
a["\b"]c) echo 'ok 5' ;;
*) echo 'bad 5' ;;
esac
mkdir man
mkdir man/man1
touch man/man1/bash.1
expect '<man/man1/bash.1>'
recho */man*/bash.*
expect '<man/man1/bash.1>'
recho $(echo */man*/bash.*)
expect '<man/man1/bash.1>'
recho "$(echo */man*/bash.*)"
# tests with multiple `*'s
case abc in
a***c) echo ok 1;;
esac
case abc in
a*****?c) echo ok 2;;
esac
case abc in
?*****??) echo ok 3;;
esac
case abc in
*****??) echo ok 4;;
esac
case abc in
*****??c) echo ok 5;;
esac
case abc in
?*****?c) echo ok 6;;
esac
case abc in
?***?****c) echo ok 7;;
esac
case abc in
?***?****?) echo ok 8;;
esac
case abc in
?***?****) echo ok 9;;
esac
case abc in
*******c) echo ok 10;;
esac
case abc in
*******?) echo ok 11;;
esac
case abcdecdhjk in
a*cd**?**??k) echo ok 20;;
esac
case abcdecdhjk in
a**?**cd**?**??k) echo ok 21;;
esac
case abcdecdhjk in
a**?**cd**?**??k***) echo ok 22;;
esac
case abcdecdhjk in
a**?**cd**?**??***k) echo ok 23;;
esac
case abcdecdhjk in
a**?**cd**?**??***k**) echo ok 24;;
esac
case abcdecdhjk in
a****c**?**??*****) echo ok 25;;
esac
case '-' in
[-abc]) echo ok 26 ;;
esac
case '-' in
[abc-]) echo ok 27 ;;
esac
case '\' in
\\) echo ok 28 ;;
esac
case '\' in
[\\]) echo ok 29 ;;
esac
case '\' in
'\') echo ok 30 ;;
esac
case '[' in
[[]) echo ok 31 ;;
esac
# a `[' without a closing `]' is just another character to match, in the
# bash implementation
case '[' in
[) echo ok 32 ;;
esac
case '[abc' in
[*) echo 'ok 33';;
esac
# a right bracket shall lose its special meaning and represent itself in
# a bracket expression if it occurs first in the list. -- POSIX.2 2.8.3.2
case ']' in
[]]) echo ok 34 ;;
esac
case '-' in
[]-]) echo ok 35 ;;
esac
# a backslash should just escape the next character in this context
case p in
[a-\z]) echo ok 36 ;;
esac
# this was a bug in all versions up to bash-2.04-release
case "/tmp" in
[/\\]*) echo ok 37 ;;
esac
# none of these should output anything
case abc in
??**********?****?) echo bad 1;;
esac
case abc in
??**********?****c) echo bad 2;;
esac
case abc in
?************c****?****) echo bad 3;;
esac
case abc in
*c*?**) echo bad 4;;
esac
case abc in
a*****c*?**) echo bad 5;;
esac
case abc in
a********???*******) echo bad 6;;
esac
case 'a' in
[]) echo bad 7 ;;
esac
case '[' in
[abc) echo bad 8;;
esac
# let's start testing the case-insensitive globbing code
recho b*
shopt -s nocaseglob
recho b*
recho [b]*
shopt -u nocaseglob
# make sure set -f works right
set -f
recho *
set +f
# test out the GLOBIGNORE code
GLOBIGNORE='.*:*c:*e:?'
recho *
GLOBIGNORE='.*:*b:*d:?'
recho *
# see if GLOBIGNORE can substitute for `set -f'
GLOBIGNORE='.*:*'
recho *
unset GLOBIGNORE
expect '<man/man1/bash.1>'
recho */man*/bash.*
# make sure null values for GLOBIGNORE have no effect
GLOBIGNORE=
expect '<man/man1/bash.1>'
recho */man*/bash.*
# this is for the benefit of pure coverage, so it writes the pcv file
# in the right place, and for gprof
builtin cd $MYDIR
rm -rf $TESTDIR
exit 0
+1 -1
View File
@@ -18,7 +18,7 @@
export TMPDIR
# basic /bin/sh syntax
SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
SUFFIX=$( ${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))' )
BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
export BASH_TSTOUT
+5
View File
@@ -0,0 +1,5 @@
PATH=$PATH:`pwd`
export PATH
${THIS_SH} ./glob-bracket.tests > ${BASH_TSTOUT} 2>&1
diff ${BASH_TSTOUT} glob-bracket.right && rm -f ${BASH_TSTOUT}
+1 -1
View File
@@ -22,7 +22,7 @@
export TMPDIR
# basic /bin/sh syntax
SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
SUFFIX=$( ${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))' )
BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
export BASH_TSTOUT
+3
View File
@@ -90,6 +90,9 @@ ${THIS_SH} ./trap4.sub
# Return trap issues
${THIS_SH} ./trap6.sub
# eval and ERR trap
${THIS_SH} ./trap7.sub
#
# show that setting a trap on SIGCHLD is not disastrous.
#
+8
View File
@@ -0,0 +1,8 @@
func()
{
eval "trap 'return 42' ERR; false"
return 0
}
set -o errtrace
func || echo oops: $?