GRASS 8 Programmer's Manual
8.5.0(2026)-8d6ceba290
Toggle main menu visibility
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
25
struct
buffer {
26
char
*buf;
27
size_t
len;
28
size_t
alloc;
29
};
30
31
static
void
init
(
struct
buffer *buf)
32
{
33
buf->buf =
NULL
;
34
buf->len = 0;
35
buf->alloc = 0;
36
}
37
38
static
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
48
static
void
fini(
struct
buffer *buf)
49
{
50
G_free
(buf->buf);
51
}
52
53
static
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
78
static
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
148
static
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;
157
pcre_extra *pcreExtra;
158
int
pcreExecRet;
159
pcre *pcre_regex = closure;
160
161
/* Optimize the regex */
162
pcreExtra = pcre_study(pcre_regex, 0, &pcreErrorStr);
163
pcreExecRet = pcre_exec(pcre_regex, pcreExtra, filename,
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
173
void
*
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,
180
REG_NOSUB | (extended ? REG_EXTENDED : 0) |
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
195
pcre *pcre_regex;
196
const
char
*pcreErrorStr;
197
int
pcreErrorOffset;
198
199
/* First, the regex string must be compiled */
200
pcre_regex = pcre_compile(pat, 0, &pcreErrorStr, &pcreErrorOffset,
NULL
);
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)
210
G_set_ls_exclude_filter
(re_filter, pcre_regex);
211
else
212
G_set_ls_filter
(re_filter, pcre_regex);
213
214
/* First, the regex string must be compiled */
215
pcre_regex = pcre_compile(pat, 0, &pcreErrorStr, &pcreErrorOffset,
NULL
);
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)
225
G_set_ls_exclude_filter
(re_filter, pcre_regex);
226
else
227
G_set_ls_filter
(re_filter, pcre_regex);
228
229
return
pcre_regex;
230
#endif
231
}
232
233
void
*
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
241
pcre *pcre_regex;
242
#endif
243
244
init
(&buf);
245
246
if
(!wc2regex(&buf, pat)) {
247
fini(&buf);
248
return
NULL
;
249
}
250
#ifdef HAVE_REGEX_H
251
regex =
G_ls_regex_filter
(buf.buf, exclude, 1, ignorecase);
252
#endif
253
#ifdef HAVE_PCRE_H
254
pcre_regex =
G_ls_regex_filter
(buf.buf, exclude, 1, ignorecase);
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
267
void
G_free_ls_filter
(
void
*regex)
268
{
269
if
(!regex)
270
return
;
271
#ifdef HAVE_REGEX_H
272
regfree(regex);
273
#endif
274
#ifdef HAVE_PCRE_H
275
pcre_free(regex);
276
#endif
277
}
G_free
void G_free(void *buf)
Free allocated memory.
Definition
alloc.c:147
init
void init(double work[])
Definition
as177.c:61
NULL
#define NULL
Definition
ccmath.h:32
G_set_ls_filter
void G_set_ls_filter(ls_filter_func *func, void *closure)
Sets a function and its complementary data for G_ls2 filtering.
Definition
ls.c:66
G_set_ls_exclude_filter
void G_set_ls_exclude_filter(ls_filter_func *func, void *closure)
Definition
ls.c:72
G_ls_regex_filter
void * G_ls_regex_filter(const char *pat, int exclude, int extended, int ignorecase)
Definition
ls_filter.c:173
G_free_ls_filter
void G_free_ls_filter(void *regex)
Definition
ls_filter.c:267
G_ls_glob_filter
void * G_ls_glob_filter(const char *pat, int exclude, int ignorecase)
Definition
ls_filter.c:233
gis
ls_filter.c
Generated on
for GRASS 8 Programmer's Manual by
1.17.0