1 /* gmisc.c -- miscellaneous pattern matching utility functions for Bash.
2 
3    Copyright (C) 2010-2020 Free Software Foundation, Inc.
4 
5    This file is part of GNU Bash, the Bourne-Again SHell.
6 
7    Bash is free software: you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation, either version 3 of the License, or
10    (at your option) any later version.
11 
12    Bash is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include <config.h>
22 
23 #include "bashtypes.h"
24 
25 #if defined (HAVE_UNISTD_H)
26 #  include <unistd.h>
27 #endif
28 
29 #include "bashansi.h"
30 #include "shmbutil.h"
31 #include "chartypes.h"
32 
33 #include "stdc.h"
34 
35 #ifndef FNM_CASEFOLD
36 #  include "strmatch.h"
37 #endif
38 #include "glob.h"
39 
40 /* Make sure these names continue to agree with what's in smatch.c */
41 extern char *glob_patscan PARAMS((char *, char *, int));
42 
43 /* Compile `gm_loop.c' for single-byte characters. */
44 #define CHAR	char
45 #define INT	int
46 #define L(CS)	CS
47 #define EXTGLOB_PATTERN_P extglob_pattern_p
48 #define MATCH_PATTERN_CHAR match_pattern_char
49 #define MATCHLEN umatchlen
50 #define FOLD(c) ((flags & FNM_CASEFOLD) \
51 	? TOLOWER ((unsigned char)c) \
52 	: ((unsigned char)c))
53 #ifndef LPAREN
54 #define LPAREN '('
55 #define RPAREN ')'
56 #endif
57 #include "gm_loop.c"
58 
59 /* Compile `gm_loop.c' again for multibyte characters. */
60 #if HANDLE_MULTIBYTE
61 
62 #define CHAR	wchar_t
63 #define INT	wint_t
64 #define L(CS)	L##CS
65 #define EXTGLOB_PATTERN_P wextglob_pattern_p
66 #define MATCH_PATTERN_CHAR match_pattern_wchar
67 #define MATCHLEN wmatchlen
68 
69 #define FOLD(c) ((flags & FNM_CASEFOLD) && iswupper (c) ? towlower (c) : (c))
70 #define LPAREN L'('
71 #define RPAREN L')'
72 #include "gm_loop.c"
73 
74 #endif /* HANDLE_MULTIBYTE */
75 
76 
77 #if defined (EXTENDED_GLOB)
78 /* Skip characters in PAT and return the final occurrence of DIRSEP.  This
79    is only called when extended_glob is set, so we have to skip over extglob
80    patterns x(...) */
81 char *
glob_dirscan(pat,dirsep)82 glob_dirscan (pat, dirsep)
83      char *pat;
84      int dirsep;
85 {
86   char *p, *d, *pe, *se;
87 
88   d = pe = se = 0;
89   for (p = pat; p && *p; p++)
90     {
91       if (extglob_pattern_p (p))
92 	{
93 	  if (se == 0)
94 	    se = p + strlen (p) - 1;
95 	  pe = glob_patscan (p + 2, se, 0);
96 	  if (pe == 0)
97 	    continue;
98 	  else if (*pe == 0)
99 	    break;
100 	  p = pe - 1;	/* will do increment above */
101 	  continue;
102 	}
103       if (*p ==  dirsep)
104 	d = p;
105     }
106   return d;
107 }
108 #endif /* EXTENDED_GLOB */
109