GRASS 8 Programmer's Manual 8.6.0dev(2026)-ddeab64dbf
Loading...
Searching...
No Matches
ls_filter.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/ls_filter.c
3 *
4 * \brief GIS Library - Filename filter functions
5 *
6 * (C) 2010 by Glynn Clements and the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public License
9 * (>=v2). Read the file COPYING that comes with GRASS for details.
10 *
11 * \author Original author Glynn Clements
12 */
13
14#include <grass/config.h>
15#include <grass/gis.h>
16#ifdef HAVE_REGEX_H
17#include <regex.h>
18#endif
19
20#ifdef HAVE_PCRE_H
21#include <string.h>
22#include <pcre.h>
23#endif
24
25struct buffer {
26 char *buf;
27 size_t len;
28 size_t alloc;
29};
30
31static void init(struct buffer *buf)
32{
33 buf->buf = NULL;
34 buf->len = 0;
35 buf->alloc = 0;
36}
37
38static void add(struct buffer *buf, char c)
39{
40 if (buf->len >= buf->alloc) {
41 buf->alloc += 50;
42 buf->buf = G_realloc(buf->buf, buf->alloc);
43 }
44
45 buf->buf[buf->len++] = c;
46}
47
48static void fini(struct buffer *buf)
49{
50 G_free(buf->buf);
51}
52
53static const char *do_set(struct buffer *buf, const char *p)
54{
55 add(buf, '[');
56
57 if (*p == '!') {
58 add(buf, '^');
59 p++;
60 }
61
62 if (*p == ']') {
63 add(buf, ']');
64 p++;
65 }
66
67 for (; *p && *p != ']'; p++)
68 add(buf, *p);
69
70 if (!*p)
71 return NULL;
72
73 add(buf, ']');
74
75 return p;
76}
77
78static int wc2regex(struct buffer *buf, const char *pat)
79{
80 const char *p;
81 int in_brace = 0;
82
83 init(buf);
84
85 add(buf, '^');
86
87 for (p = pat; p && *p; p++) {
88 switch (*p) {
89 case '\\':
90 add(buf, '\\');
91 if (!*++p)
92 return 0;
93 add(buf, *p);
94 break;
95 case '.':
96 case '|':
97 case '(':
98 case ')':
99 case '+':
100 add(buf, '\\');
101 add(buf, *p);
102 break;
103 case '*':
104 add(buf, '.');
105 add(buf, '*');
106 break;
107 case '?':
108 add(buf, '.');
109 break;
110 case '{':
111 in_brace++;
112 add(buf, '(');
113 break;
114 case '}':
115 if (!in_brace)
116 return 0;
117 in_brace--;
118 add(buf, ')');
119 break;
120 case ',':
121 if (in_brace)
122 add(buf, '|');
123 else
124 add(buf, ',');
125 break;
126 case '[':
127 if (!(p = do_set(buf, p)))
128 return 0;
129 break;
130 default:
131 add(buf, *p);
132 break;
133 }
134 }
135
136 if (!p)
137 return 0;
138
139 if (in_brace)
140 return 0;
141
142 add(buf, '$');
143 add(buf, '\0');
144
145 return 1;
146}
147
148static int re_filter(const char *filename, void *closure)
149{
150#ifdef HAVE_REGEX_H
151 regex_t *regex = closure;
152
153 return filename[0] != '.' && regexec(regex, filename, 0, NULL, 0) == 0;
154#endif
155#ifdef HAVE_PCRE_H
156 const char *pcreErrorStr;
158 int pcreExecRet;
159 pcre *pcre_regex = closure;
160
161 /* Optimize the regex */
164 strlen(filename), /* length of string */
165 0, /* Start looking at this point */
166 0, /* OPTIONS */
167 NULL, 0); /* Length of subStrVec */
168
169 return filename[0] != '.' && pcreExecRet == 0;
170#endif
171}
172
173void *G_ls_regex_filter(const char *pat, int exclude, int extended,
174 int ignorecase)
175{
176#ifdef HAVE_REGEX_H
177 regex_t *regex = G_malloc(sizeof(regex_t));
178
179 if (regcomp(regex, pat,
181 (ignorecase ? REG_ICASE : 0)) != 0) {
182 G_free(regex);
183 return NULL;
184 }
185
186 if (exclude)
187 G_set_ls_exclude_filter(re_filter, regex);
188 else
189 G_set_ls_filter(re_filter, regex);
190
191 return regex;
192#endif
193
194#ifdef HAVE_PCRE_H
196 const char *pcreErrorStr;
197 int pcreErrorOffset;
198
199 /* First, the regex string must be compiled */
201 /*
202 if (regcomp(regex, pat, REG_NOSUB |
203 (extended ? REG_EXTENDED : 0) |
204 (ignorecase ? REG_ICASE : 0)) != 0) {
205 pcre_free(pcre_regex);
206 return NULL;
207 }
208 */
209 if (exclude)
211 else
212 G_set_ls_filter(re_filter, pcre_regex);
213
214 /* First, the regex string must be compiled */
216 /*
217 if (regcomp(regex, pat, REG_NOSUB |
218 (extended ? REG_EXTENDED : 0) |
219 (ignorecase ? REG_ICASE : 0)) != 0) {
220 pcre_free(pcre_regex);
221 return NULL;
222 }
223 */
224 if (exclude)
226 else
227 G_set_ls_filter(re_filter, pcre_regex);
228
229 return pcre_regex;
230#endif
231}
232
233void *G_ls_glob_filter(const char *pat, int exclude, int ignorecase)
234{
235 struct buffer buf;
236
237#ifdef HAVE_REGEX_H
238 regex_t *regex;
239#endif
240#ifdef HAVE_PCRE_H
242#endif
243
244 init(&buf);
245
246 if (!wc2regex(&buf, pat)) {
247 fini(&buf);
248 return NULL;
249 }
250#ifdef HAVE_REGEX_H
252#endif
253#ifdef HAVE_PCRE_H
255#endif
256
257 fini(&buf);
258
259#ifdef HAVE_REGEX_H
260 return regex;
261#endif
262#ifdef HAVE_PCRE_H
263 return pcre_regex;
264#endif
265}
266
268{
269 if (!regex)
270 return;
271#ifdef HAVE_REGEX_H
272 regfree(regex);
273#endif
274#ifdef HAVE_PCRE_H
276#endif
277}
void init(double work[])
Definition as177.c:61
#define NULL
Definition ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition gis/alloc.c:147
#define G_realloc(p, n)
Definition defs/gis.h:141
#define G_malloc(n)
Definition defs/gis.h:139
void G_set_ls_exclude_filter(int(*)(const char *, void *), void *)
void G_set_ls_filter(int(*)(const char *, void *), void *)
void * G_ls_regex_filter(const char *pat, int exclude, int extended, int ignorecase)
Definition ls_filter.c:173
void G_free_ls_filter(void *regex)
Definition ls_filter.c:267
void * G_ls_glob_filter(const char *pat, int exclude, int ignorecase)
Definition ls_filter.c:233