From f4b417c62a4f272c4cf9a074d0f7a3a97201f9db Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Tue, 17 Apr 2012 11:23:35 +0200 Subject: Update to upstream bash 4.2 This upgrades bash to from 4.1-rc to 4.2-release. See CWRU/changelog for changes. Change-Id: I926269c300cf44fa25964b5b375a148fcf11c4b7 --- lib/glob/gmisc.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 lib/glob/gmisc.c (limited to 'lib/glob/gmisc.c') diff --git a/lib/glob/gmisc.c b/lib/glob/gmisc.c new file mode 100644 index 0000000..84794cd --- /dev/null +++ b/lib/glob/gmisc.c @@ -0,0 +1,314 @@ +/* gmisc.c -- miscellaneous pattern matching utility functions for Bash. + + Copyright (C) 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 . +*/ + +#include + +#include "bashtypes.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#include "bashansi.h" +#include "shmbutil.h" + +#include "stdc.h" + +#ifndef LPAREN +# define LPAREN '(' +#endif +#ifndef RPAREN +# define RPAREN ')' +#endif + +#if defined (HANDLE_MULTIBYTE) +#define WLPAREN L'(' +#define WRPAREN L')' + +/* Return 1 of the first character of WSTRING could match the first + character of pattern WPAT. Wide character version. */ +int +match_pattern_wchar (wpat, wstring) + wchar_t *wpat, *wstring; +{ + wchar_t wc; + + if (*wstring == 0) + return (0); + + switch (wc = *wpat++) + { + default: + return (*wstring == wc); + case L'\\': + return (*wstring == *wpat); + case L'?': + return (*wpat == WLPAREN ? 1 : (*wstring != L'\0')); + case L'*': + return (1); + case L'+': + case L'!': + case L'@': + return (*wpat == WLPAREN ? 1 : (*wstring == wc)); + case L'[': + return (*wstring != L'\0'); + } +} + +int +wmatchlen (wpat, wmax) + wchar_t *wpat; + size_t wmax; +{ + wchar_t wc, *wbrack; + int matlen, t, in_cclass, in_collsym, in_equiv; + + if (*wpat == 0) + return (0); + + matlen = in_cclass = in_collsym = in_equiv = 0; + while (wc = *wpat++) + { + switch (wc) + { + default: + matlen++; + break; + case L'\\': + if (*wpat == 0) + return ++matlen; + else + { + matlen++; + wpat++; + } + break; + case L'?': + if (*wpat == WLPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case L'*': + return (matlen = -1); + case L'+': + case L'!': + case L'@': + if (*wpat == WLPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case L'[': + /* scan for ending `]', skipping over embedded [:...:] */ + wbrack = wpat; + wc = *wpat++; + do + { + if (wc == 0) + { + matlen += wpat - wbrack - 1; /* incremented below */ + break; + } + else if (wc == L'\\') + { + wc = *wpat++; + if (*wpat == 0) + break; + } + else if (wc == L'[' && *wpat == L':') /* character class */ + { + wpat++; + in_cclass = 1; + } + else if (in_cclass && wc == L':' && *wpat == L']') + { + wpat++; + in_cclass = 0; + } + else if (wc == L'[' && *wpat == L'.') /* collating symbol */ + { + wpat++; + if (*wpat == L']') /* right bracket can appear as collating symbol */ + wpat++; + in_collsym = 1; + } + else if (in_collsym && wc == L'.' && *wpat == L']') + { + wpat++; + in_collsym = 0; + } + else if (wc == L'[' && *wpat == L'=') /* equivalence class */ + { + wpat++; + if (*wpat == L']') /* right bracket can appear as equivalence class */ + wpat++; + in_equiv = 1; + } + else if (in_equiv && wc == L'=' && *wpat == L']') + { + wpat++; + in_equiv = 0; + } + } + while ((wc = *wpat++) != L']'); + matlen++; /* bracket expression can only match one char */ + break; + } + } + + return matlen; +} +#endif + +/* Return 1 of the first character of STRING could match the first + character of pattern PAT. Used to avoid n2 calls to strmatch(). */ +int +match_pattern_char (pat, string) + char *pat, *string; +{ + char c; + + if (*string == 0) + return (0); + + switch (c = *pat++) + { + default: + return (*string == c); + case '\\': + return (*string == *pat); + case '?': + return (*pat == LPAREN ? 1 : (*string != '\0')); + case '*': + return (1); + case '+': + case '!': + case '@': + return (*pat == LPAREN ? 1 : (*string == c)); + case '[': + return (*string != '\0'); + } +} + +int +umatchlen (pat, max) + char *pat; + size_t max; +{ + char c, *brack; + int matlen, t, in_cclass, in_collsym, in_equiv; + + if (*pat == 0) + return (0); + + matlen = in_cclass = in_collsym = in_equiv = 0; + while (c = *pat++) + { + switch (c) + { + default: + matlen++; + break; + case '\\': + if (*pat == 0) + return ++matlen; + else + { + matlen++; + pat++; + } + break; + case '?': + if (*pat == LPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case '*': + return (matlen = -1); + case '+': + case '!': + case '@': + if (*pat == LPAREN) + return (matlen = -1); /* XXX for now */ + else + matlen++; + break; + case '[': + /* scan for ending `]', skipping over embedded [:...:] */ + brack = pat; + c = *pat++; + do + { + if (c == 0) + { + matlen += pat - brack - 1; /* incremented below */ + break; + } + else if (c == '\\') + { + c = *pat++; + if (*pat == 0) + break; + } + else if (c == '[' && *pat == ':') /* character class */ + { + pat++; + in_cclass = 1; + } + else if (in_cclass && c == ':' && *pat == ']') + { + pat++; + in_cclass = 0; + } + else if (c == '[' && *pat == '.') /* collating symbol */ + { + pat++; + if (*pat == ']') /* right bracket can appear as collating symbol */ + pat++; + in_collsym = 1; + } + else if (in_collsym && c == '.' && *pat == ']') + { + pat++; + in_collsym = 0; + } + else if (c == '[' && *pat == '=') /* equivalence class */ + { + pat++; + if (*pat == ']') /* right bracket can appear as equivalence class */ + pat++; + in_equiv = 1; + } + else if (in_equiv && c == '=' && *pat == ']') + { + pat++; + in_equiv = 0; + } + } + while ((c = *pat++) != ']'); + matlen++; /* bracket expression can only match one char */ + break; + } + } + + return matlen; +} -- cgit v1.1