GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
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 
17 #ifdef HAVE_REGEX_H
18 
19 #include <regex.h>
20 
21 struct buffer
22 {
23  char *buf;
24  size_t len;
25  size_t alloc;
26 };
27 
28 static void init(struct buffer *buf)
29 {
30  buf->buf = NULL;
31  buf->len = 0;
32  buf->alloc = 0;
33 }
34 
35 static void add(struct buffer *buf, char c)
36 {
37  if (buf->len >= buf->alloc) {
38  buf->alloc += 50;
39  buf->buf = G_realloc(buf->buf, buf->alloc);
40  }
41 
42  buf->buf[buf->len++] = c;
43 }
44 
45 static void fini(struct buffer *buf)
46 {
47  G_free(buf->buf);
48 }
49 
50 static const char *do_set(struct buffer *buf, const char *p)
51 {
52  add(buf, '[');
53 
54  if (*p == '!') {
55  add(buf, '^');
56  p++;
57  }
58 
59  if (*p == ']') {
60  add(buf, ']');
61  p++;
62  }
63 
64  for (; *p && *p != ']'; p++)
65  add(buf, *p);
66 
67  if (!*p)
68  return NULL;
69 
70  add(buf, ']');
71 
72  return p;
73 }
74 
75 static int wc2regex(struct buffer *buf, const char *pat)
76 {
77  const char *p;
78  int in_brace = 0;
79 
80  init(buf);
81 
82  add(buf, '^');
83 
84  for (p = pat; p && *p; p++) {
85  switch (*p) {
86  case '\\':
87  add(buf, '\\');
88  if (!*++p)
89  return 0;
90  add(buf, *p);
91  break;
92  case '.':
93  case '|':
94  case '(':
95  case ')':
96  case '+':
97  add(buf, '\\');
98  add(buf, *p);
99  break;
100  case '*':
101  add(buf, '.');
102  add(buf, '*');
103  break;
104  case '?':
105  add(buf, '.');
106  break;
107  case '{':
108  in_brace++;
109  add(buf, '(');
110  break;
111  case '}':
112  if (!in_brace)
113  return 0;
114  in_brace--;
115  add(buf, ')');
116  break;
117  case ',':
118  if (in_brace)
119  add(buf, '|');
120  else
121  add(buf, ',');
122  break;
123  case '[':
124  if (!(p = do_set(buf, p)))
125  return 0;
126  break;
127  default:
128  add(buf, *p);
129  break;
130  }
131  }
132 
133  if (!p)
134  return 0;
135 
136  if (in_brace)
137  return 0;
138 
139  add(buf, '$');
140  add(buf, '\0');
141 
142  return 1;
143 }
144 
145 static int re_filter(const char *filename, void *closure)
146 {
147  regex_t *regex = closure;
148 
149  return filename[0] != '.' && regexec(regex, filename, 0, NULL, 0) == 0;
150 }
151 
152 void *G_ls_regex_filter(const char *pat, int exclude, int extended,
153  int ignorecase)
154 {
155  regex_t *regex = G_malloc(sizeof(regex_t));
156 
157  if (regcomp(regex, pat, REG_NOSUB |
158  (extended ? REG_EXTENDED : 0) |
159  (ignorecase ? REG_ICASE : 0)) != 0) {
160  G_free(regex);
161  return NULL;
162  }
163 
164  if (exclude)
165  G_set_ls_exclude_filter(re_filter, regex);
166  else
167  G_set_ls_filter(re_filter, regex);
168 
169  return regex;
170 }
171 
172 void *G_ls_glob_filter(const char *pat, int exclude, int ignorecase)
173 {
174  struct buffer buf;
175  regex_t *regex;
176 
177  init(&buf);
178 
179  if (!wc2regex(&buf, pat)) {
180  fini(&buf);
181  return NULL;
182  }
183 
184  regex = G_ls_regex_filter(buf.buf, exclude, 1, ignorecase);
185 
186  fini(&buf);
187 
188  return regex;
189 }
190 
191 void G_free_ls_filter(void *regex)
192 {
193  if (!regex)
194  return;
195 
196  regfree(regex);
197  G_free(regex);
198 }
199 
200 #endif
201 
#define G_malloc(n)
Definition: defs/gis.h:112
void G_set_ls_filter(int(*)(const char *, void *), void *)
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
void G_set_ls_exclude_filter(int(*)(const char *, void *), void *)
#define NULL
Definition: ccmath.h:32
void * G_ls_regex_filter(const char *pat, int exclude, int extended, int ignorecase)
Definition: ls_filter.c:152
void * G_ls_glob_filter(const char *pat, int exclude, int ignorecase)
Definition: ls_filter.c:172
#define G_realloc(p, n)
Definition: defs/gis.h:114
void G_free_ls_filter(void *regex)
Definition: ls_filter.c:191
void init(double work[])
Definition: as177.c:65