OpenCoverage

exclude.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/exclude.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* exclude.c -- exclude file names-
2-
3 Copyright (C) 1992-1994, 1997, 1999-2007, 2009-2018 Free Software-
4 Foundation, Inc.-
5-
6 This program is free software: you can redistribute it and/or modify-
7 it under the terms of the GNU General Public License as published by-
8 the Free Software Foundation; either version 3 of the License, or-
9 (at your option) any later version.-
10-
11 This program is distributed in the hope that it will be useful,-
12 but WITHOUT ANY WARRANTY; without even the implied warranty of-
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
14 GNU General Public License for more details.-
15-
16 You should have received a copy of the GNU General Public License-
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
18-
19/* Written by Paul Eggert <eggert@twinsun.com>-
20 and Sergey Poznyakoff <gray@gnu.org>.-
21 Thanks to Phil Proudman <phil@proudman51.freeserve.co.uk>-
22 for improvement suggestions. */-
23-
24#include <config.h>-
25-
26#include <stdbool.h>-
27-
28#include <ctype.h>-
29#include <errno.h>-
30#include <stddef.h>-
31#include <stdio.h>-
32#include <stdlib.h>-
33#include <string.h>-
34#include <wctype.h>-
35#include <regex.h>-
36-
37#include "exclude.h"-
38#include "hash.h"-
39#include "mbuiter.h"-
40#include "fnmatch.h"-
41#include "xalloc.h"-
42#include "verify.h"-
43#include "filename.h"-
44-
45#if USE_UNLOCKED_IO-
46# include "unlocked-io.h"-
47#endif-
48-
49/* Non-GNU systems lack these options, so we don't need to check them. */-
50#ifndef FNM_CASEFOLD-
51# define FNM_CASEFOLD 0-
52#endif-
53#ifndef FNM_EXTMATCH-
54# define FNM_EXTMATCH 0-
55#endif-
56#ifndef FNM_LEADING_DIR-
57# define FNM_LEADING_DIR 0-
58#endif-
59-
60verify (((EXCLUDE_ANCHORED | EXCLUDE_INCLUDE | EXCLUDE_WILDCARDS)-
61 & (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD | FNM_LEADING_DIR-
62 | FNM_CASEFOLD | FNM_EXTMATCH))-
63 == 0);-
64-
65-
66/* Exclusion patterns are grouped into a singly-linked list of-
67 "exclusion segments". Each segment represents a set of patterns-
68 that can be matches using the same algorithm. Non-wildcard-
69 patterns are kept in hash tables, to speed up searches. Wildcard-
70 patterns are stored as arrays of patterns. */-
71-
72-
73/* An exclude pattern-options pair. The options are fnmatch options-
74 ORed with EXCLUDE_* options. */-
75-
76struct patopts-
77 {-
78 int options;-
79 union-
80 {-
81 char const *pattern;-
82 regex_t re;-
83 } v;-
84 };-
85-
86/* An array of pattern-options pairs. */-
87-
88struct exclude_pattern-
89 {-
90 struct patopts *exclude;-
91 size_t exclude_alloc;-
92 size_t exclude_count;-
93 };-
94-
95enum exclude_type-
96 {-
97 exclude_hash, /* a hash table of excluded names */-
98 exclude_pattern /* an array of exclude patterns */-
99 };-
100-
101struct exclude_segment-
102 {-
103 struct exclude_segment *next; /* next segment in list */-
104 enum exclude_type type; /* type of this segment */-
105 int options; /* common options for this segment */-
106 union-
107 {-
108 Hash_table *table; /* for type == exclude_hash */-
109 struct exclude_pattern pat; /* for type == exclude_pattern */-
110 } v;-
111 };-
112-
113struct pattern_buffer-
114 {-
115 struct pattern_buffer *next;-
116 char *base;-
117 };-
118-
119/* The exclude structure keeps a singly-linked list of exclude segments,-
120 maintained in reverse order. */-
121struct exclude-
122 {-
123 struct exclude_segment *head;-
124 struct pattern_buffer *patbuf;-
125 };-
126-
127/* Register BUF in the pattern buffer list of EX. ADD_FUNC (see-
128 add_exclude_file and add_exclude_fp below) can use this function-
129 if it modifies the pattern, to ensure the allocated memory will be-
130 properly reclaimed upon calling free_exclude. */-
131void-
132exclude_add_pattern_buffer (struct exclude *ex, char *buf)-
133{-
134 struct pattern_buffer *pbuf = xmalloc (sizeof *pbuf);-
135 pbuf->base = buf;-
136 pbuf->next = ex->patbuf;-
137 ex->patbuf = pbuf;-
138}
executed 1 time by 1 test: end of block
Executed by:
  • du
1
139-
140/* Return true if STR has or may have wildcards, when matched with OPTIONS.-
141 Return false if STR definitely does not have wildcards. */-
142bool-
143fnmatch_pattern_has_wildcards (const char *str, int options)-
144{-
145 while (1)-
146 {-
147 switch (*str++)-
148 {-
149 case '.':
never executed: case '.':
0
150 case '{':
never executed: case '{':
0
151 case '}':
never executed: case '}':
0
152 case '(':
never executed: case '(':
0
153 case ')':
never executed: case ')':
0
154 if (options & EXCLUDE_REGEX)
options & (1 << 27)Description
TRUEnever evaluated
FALSEnever evaluated
0
155 return true;
never executed: return 1 ;
0
156 break;
never executed: break;
0
157-
158 case '\\':
never executed: case '\\':
0
159 if (options & EXCLUDE_REGEX)
options & (1 << 27)Description
TRUEnever evaluated
FALSEnever evaluated
0
160 continue;
never executed: continue;
0
161 else-
162 str += ! (options & FNM_NOESCAPE) && *str;
never executed: str += ! (options & (1 << 1) ) && *str;
! (options & (1 << 1) )Description
TRUEnever evaluated
FALSEnever evaluated
*strDescription
TRUEnever evaluated
FALSEnever evaluated
0
163 break;
never executed: break;
0
164-
165 case '+': case '@': case '!':
never executed: case '+':
never executed: case '@':
never executed: case '!':
0
166 if (options & FNM_EXTMATCH && *str == '(')
options & (1 << 5)Description
TRUEnever evaluated
FALSEnever evaluated
*str == '('Description
TRUEnever evaluated
FALSEnever evaluated
0
167 return true;
never executed: return 1 ;
0
168 break;
never executed: break;
0
169-
170 case '?': case '*': case '[':
never executed: case '?':
never executed: case '*':
executed 1 time by 1 test: case '[':
Executed by:
  • du
0-1
171 return true;
executed 1 time by 1 test: return 1 ;
Executed by:
  • du
1
172-
173 case '\0':
executed 11 times by 1 test: case '\0':
Executed by:
  • du
11
174 return false;
executed 11 times by 1 test: return 0 ;
Executed by:
  • du
11
175 }-
176 }
executed 33 times by 1 test: end of block
Executed by:
  • du
33
177}
never executed: end of block
0
178-
179static void-
180unescape_pattern (char *str)-
181{-
182 char const *q = str;-
183 do-
184 q += *q == '\\' && q[1];
executed 44 times by 1 test: q += *q == '\\' && q[1];
Executed by:
  • du
*q == '\\'Description
TRUEnever evaluated
FALSEevaluated 44 times by 1 test
Evaluated by:
  • du
q[1]Description
TRUEnever evaluated
FALSEnever evaluated
0-44
185 while ((*str++ = *q++));
(*str++ = *q++)Description
TRUEevaluated 33 times by 1 test
Evaluated by:
  • du
FALSEevaluated 11 times by 1 test
Evaluated by:
  • du
11-33
186}
executed 11 times by 1 test: end of block
Executed by:
  • du
11
187-
188/* Return a newly allocated and empty exclude list. */-
189-
190struct exclude *-
191new_exclude (void)-
192{-
193 return xzalloc (sizeof *new_exclude ());
executed 374 times by 1 test: return xzalloc (sizeof *new_exclude ());
Executed by:
  • du
374
194}-
195-
196/* Calculate the hash of string. */-
197static size_t-
198string_hasher (void const *data, size_t n_buckets)-
199{-
200 char const *p = data;-
201 return hash_string (p, n_buckets);
executed 90 times by 1 test: return hash_string (p, n_buckets);
Executed by:
  • du
90
202}-
203-
204/* Ditto, for case-insensitive hashes */-
205static size_t-
206string_hasher_ci (void const *data, size_t n_buckets)-
207{-
208 char const *p = data;-
209 mbui_iterator_t iter;-
210 size_t value = 0;-
211-
212 for (mbui_init (iter, p); mbui_avail (iter); mbui_advance (iter))
((iter).cur).wc_validDescription
TRUEnever evaluated
FALSEnever evaluated
((iter).cur).wc == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
213 {-
214 mbchar_t m = mbui_cur (iter);-
215 wchar_t wc;-
216-
217 if (m.wc_valid)
m.wc_validDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 wc = towlower (m.wc);
never executed: wc = towlower (m.wc);
0
219 else-
220 wc = *m.ptr;
never executed: wc = *m.ptr;
0
221-
222 value = (value * 31 + wc) % n_buckets;-
223 }
never executed: end of block
0
224-
225 return value;
never executed: return value;
0
226}-
227-
228/* compare two strings for equality */-
229static bool-
230string_compare (void const *data1, void const *data2)-
231{-
232 char const *p1 = data1;-
233 char const *p2 = data2;-
234 return strcmp (p1, p2) == 0;
executed 17 times by 1 test: return __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( p1 ) && __builtin_constant_p ( p2 ) && (__s1_len = __builtin_strlen ( p1 ), __s2_len = __builtin_strlen ( p2 ), (!((size_t)(const void *)(( p1 ) + 1) - (size_t)(const void *)( p1 )...== 0) { __result = (((const unsigned char *) (const char *) ( p2 ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( p2 ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( p1 , p2 )))); }) == 0;
Executed by:
  • du
never executed: __result = (((const unsigned char *) (const char *) ( p1 ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( p2 ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-17
235}-
236-
237/* compare two strings for equality, case-insensitive */-
238static bool-
239string_compare_ci (void const *data1, void const *data2)-
240{-
241 char const *p1 = data1;-
242 char const *p2 = data2;-
243 return mbscasecmp (p1, p2) == 0;
never executed: return mbscasecmp (p1, p2) == 0;
0
244}-
245-
246static void-
247string_free (void *data)-
248{-
249 free (data);-
250}
never executed: end of block
0
251-
252/* Create new exclude segment of given TYPE and OPTIONS, and attach it-
253 to the head of EX. */-
254static void-
255new_exclude_segment (struct exclude *ex, enum exclude_type type, int options)-
256{-
257 struct exclude_segment *sp = xzalloc (sizeof (struct exclude_segment));-
258 sp->type = type;-
259 sp->options = options;-
260 switch (type)-
261 {-
262 case exclude_pattern:
executed 1 time by 1 test: case exclude_pattern:
Executed by:
  • du
1
263 break;
executed 1 time by 1 test: break;
Executed by:
  • du
1
264-
265 case exclude_hash:
executed 10 times by 1 test: case exclude_hash:
Executed by:
  • du
10
266 sp->v.table = hash_initialize (0, NULL,-
267 (options & FNM_CASEFOLD) ?-
268 string_hasher_ci-
269 : string_hasher,-
270 (options & FNM_CASEFOLD) ?-
271 string_compare_ci-
272 : string_compare,-
273 string_free);-
274 break;
executed 10 times by 1 test: break;
Executed by:
  • du
10
275 }-
276 sp->next = ex->head;-
277 ex->head = sp;-
278}
executed 11 times by 1 test: end of block
Executed by:
  • du
11
279-
280/* Free a single exclude segment */-
281static void-
282free_exclude_segment (struct exclude_segment *seg)-
283{-
284 size_t i;-
285-
286 switch (seg->type)-
287 {-
288 case exclude_pattern:
never executed: case exclude_pattern:
0
289 for (i = 0; i < seg->v.pat.exclude_count; i++)
i < seg->v.pat.exclude_countDescription
TRUEnever evaluated
FALSEnever evaluated
0
290 {-
291 if (seg->v.pat.exclude[i].options & EXCLUDE_REGEX)
seg->v.pat.exc...ns & (1 << 27)Description
TRUEnever evaluated
FALSEnever evaluated
0
292 regfree (&seg->v.pat.exclude[i].v.re);
never executed: regfree (&seg->v.pat.exclude[i].v.re);
0
293 }
never executed: end of block
0
294 free (seg->v.pat.exclude);-
295 break;
never executed: break;
0
296-
297 case exclude_hash:
never executed: case exclude_hash:
0
298 hash_free (seg->v.table);-
299 break;
never executed: break;
0
300 }-
301 free (seg);-
302}
never executed: end of block
0
303-
304/* Free the storage associated with an exclude list. */-
305void-
306free_exclude (struct exclude *ex)-
307{-
308 struct exclude_segment *seg;-
309 struct pattern_buffer *pbuf;-
310-
311 for (seg = ex->head; seg; )
segDescription
TRUEnever evaluated
FALSEnever evaluated
0
312 {-
313 struct exclude_segment *next = seg->next;-
314 free_exclude_segment (seg);-
315 seg = next;-
316 }
never executed: end of block
0
317-
318 for (pbuf = ex->patbuf; pbuf; )
pbufDescription
TRUEnever evaluated
FALSEnever evaluated
0
319 {-
320 struct pattern_buffer *next = pbuf->next;-
321 free (pbuf->base);-
322 free (pbuf);-
323 pbuf = next;-
324 }
never executed: end of block
0
325-
326 free (ex);-
327}
never executed: end of block
0
328-
329/* Return zero if PATTERN matches F, obeying OPTIONS, except that-
330 (unlike fnmatch) wildcards are disabled in PATTERN. */-
331-
332static int-
333fnmatch_no_wildcards (char const *pattern, char const *f, int options)-
334{-
335 if (! (options & FNM_LEADING_DIR))
! (options & (1 << 3) )Description
TRUEnever evaluated
FALSEnever evaluated
0
336 return ((options & FNM_CASEFOLD)
never executed: return ((options & (1 << 4) ) ? mbscasecmp (pattern, f) : __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( pattern ) && __builtin_constant_p ( f ) && (__s1_len = __builtin_strlen ( pattern ), __s2_len = __builtin_strlen ( f ), (!((size_... == 0) { __result = (((const unsigned char *) (const char *) ( f ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( f ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( pattern , f )))); }) );
0
337 ? mbscasecmp (pattern, f)
never executed: return ((options & (1 << 4) ) ? mbscasecmp (pattern, f) : __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( pattern ) && __builtin_constant_p ( f ) && (__s1_len = __builtin_strlen ( pattern ), __s2_len = __builtin_strlen ( f ), (!((size_... == 0) { __result = (((const unsigned char *) (const char *) ( f ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( f ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( pattern , f )))); }) );
0
338 : strcmp (pattern, f));
never executed: return ((options & (1 << 4) ) ? mbscasecmp (pattern, f) : __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( pattern ) && __builtin_constant_p ( f ) && (__s1_len = __builtin_strlen ( pattern ), __s2_len = __builtin_strlen ( f ), (!((size_... == 0) { __result = (((const unsigned char *) (const char *) ( f ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( f ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( pattern , f )))); }) );
never executed: __result = (((const unsigned char *) (const char *) ( pattern ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( f ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
339 else if (! (options & FNM_CASEFOLD))
! (options & (1 << 4) )Description
TRUEnever evaluated
FALSEnever evaluated
0
340 {-
341 size_t patlen = strlen (pattern);-
342 int r = strncmp (pattern, f, patlen);
never executed: __result = (((const unsigned char *) (const char *) ( pattern ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( f ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__builtin_cons...t_p ( patlen )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_cons..._p ( pattern )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( patte...t) ( patlen ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( f )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( f ) <...t) ( patlen ))Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
343 if (! r)
! rDescription
TRUEnever evaluated
FALSEnever evaluated
0
344 {-
345 r = f[patlen];-
346 if (r == '/')
r == '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
347 r = 0;
never executed: r = 0;
0
348 }
never executed: end of block
0
349 return r;
never executed: return r;
0
350 }-
351 else-
352 {-
353 /* Walk through a copy of F, seeing whether P matches any prefix-
354 of F.-
355-
356 FIXME: This is an O(N**2) algorithm; it should be O(N).-
357 Also, the copy should not be necessary. However, fixing this-
358 will probably involve a change to the mbs* API. */-
359-
360 char *fcopy = xstrdup (f);-
361 char *p;-
362 int r;-
363 for (p = fcopy; ; *p++ = '/')-
364 {-
365 p = strchr (p, '/');
__builtin_constant_p ( '/' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_constant_p ( p )Description
TRUEnever evaluated
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
366 if (p)
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
367 *p = '\0';
never executed: *p = '\0';
0
368 r = mbscasecmp (pattern, fcopy);-
369 if (!p || r <= 0)
!pDescription
TRUEnever evaluated
FALSEnever evaluated
r <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
370 break;
never executed: break;
0
371 }
never executed: end of block
0
372 free (fcopy);-
373 return r;
never executed: return r;
0
374 }-
375}-
376-
377bool-
378exclude_fnmatch (char const *pattern, char const *f, int options)-
379{-
380 int (*matcher) (char const *, char const *, int) =-
381 (options & EXCLUDE_WILDCARDS
options & (1 << 28)Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-25
382 ? fnmatch-
383 : fnmatch_no_wildcards);-
384 bool matched = ((*matcher) (pattern, f, options) == 0);-
385 char const *p;-
386-
387 if (! (options & EXCLUDE_ANCHORED))
! (options & (1 << 30))Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-25
388 for (p = f; *p && ! matched; p++)
*pDescription
TRUEevaluated 49 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
! matchedDescription
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEevaluated 24 times by 1 test
Evaluated by:
  • du
1-49
389 if (*p == '/' && p[1] != '/')
*p == '/'Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
p[1] != '/'Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-25
390 matched = ((*matcher) (pattern, p + 1, options) == 0);
executed 25 times by 1 test: matched = ((*matcher) (pattern, p + 1, options) == 0);
Executed by:
  • du
25
391-
392 return matched;
executed 25 times by 1 test: return matched;
Executed by:
  • du
25
393}-
394-
395static bool-
396exclude_patopts (struct patopts const *opts, char const *f)-
397{-
398 int options = opts->options;-
399-
400 return (options & EXCLUDE_REGEX)
executed 25 times by 1 test: return (options & (1 << 27)) ? regexec (&opts->v.re, f, 0, ((void *)0) , 0) == 0 : exclude_fnmatch (opts->v.pattern, f, options);
Executed by:
  • du
25
401 ? regexec (&opts->v.re, f, 0, NULL, 0) == 0
executed 25 times by 1 test: return (options & (1 << 27)) ? regexec (&opts->v.re, f, 0, ((void *)0) , 0) == 0 : exclude_fnmatch (opts->v.pattern, f, options);
Executed by:
  • du
25
402 : exclude_fnmatch (opts->v.pattern, f, options);
executed 25 times by 1 test: return (options & (1 << 27)) ? regexec (&opts->v.re, f, 0, ((void *)0) , 0) == 0 : exclude_fnmatch (opts->v.pattern, f, options);
Executed by:
  • du
25
403}-
404-
405/* Return true if the exclude_pattern segment SEG matches F. */-
406-
407static bool-
408file_pattern_matches (struct exclude_segment const *seg, char const *f)-
409{-
410 size_t exclude_count = seg->v.pat.exclude_count;-
411 struct patopts const *exclude = seg->v.pat.exclude;-
412 size_t i;-
413-
414 for (i = 0; i < exclude_count; i++)
i < exclude_countDescription
TRUEevaluated 25 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-25
415 {-
416 if (exclude_patopts (exclude + i, f))
exclude_patopt...xclude + i, f)Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-24
417 return true;
executed 24 times by 1 test: return 1 ;
Executed by:
  • du
24
418 }
executed 1 time by 1 test: end of block
Executed by:
  • du
1
419 return false;
executed 1 time by 1 test: return 0 ;
Executed by:
  • du
1
420}-
421-
422/* Return true if the exclude_hash segment SEG matches F.-
423 BUFFER is an auxiliary storage of the same length as F (with nul-
424 terminator included) */-
425static bool-
426file_name_matches (struct exclude_segment const *seg, char const *f,-
427 char *buffer)-
428{-
429 int options = seg->options;-
430 Hash_table *table = seg->v.table;-
431-
432 do-
433 {-
434 /* initialize the pattern */-
435 strcpy (buffer, f);-
436-
437 while (1)-
438 {-
439 if (hash_lookup (table, buffer))
hash_lookup (table, buffer)Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • du
FALSEevaluated 69 times by 1 test
Evaluated by:
  • du
10-69
440 return true;
executed 10 times by 1 test: return 1 ;
Executed by:
  • du
10
441 if (options & FNM_LEADING_DIR)
options & (1 << 3)Description
TRUEnever evaluated
FALSEevaluated 69 times by 1 test
Evaluated by:
  • du
0-69
442 {-
443 char *p = strrchr (buffer, '/');-
444 if (p)
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
445 {-
446 *p = 0;-
447 continue;
never executed: continue;
0
448 }-
449 }
never executed: end of block
0
450 break;
executed 69 times by 1 test: break;
Executed by:
  • du
69
451 }-
452-
453 if (!(options & EXCLUDE_ANCHORED))
!(options & (1 << 30))Description
TRUEevaluated 69 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-69
454 {-
455 f = strchr (f, '/');
__builtin_constant_p ( '/' )Description
TRUEevaluated 69 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
!__builtin_constant_p ( f )Description
TRUEevaluated 69 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEevaluated 69 times by 1 test
Evaluated by:
  • du
0-69
456 if (f)
fDescription
TRUEevaluated 36 times by 1 test
Evaluated by:
  • du
FALSEevaluated 33 times by 1 test
Evaluated by:
  • du
33-36
457 f++;
executed 36 times by 1 test: f++;
Executed by:
  • du
36
458 }
executed 69 times by 1 test: end of block
Executed by:
  • du
69
459 else-
460 break;
never executed: break;
0
461 }-
462 while (f);
fDescription
TRUEevaluated 36 times by 1 test
Evaluated by:
  • du
FALSEevaluated 33 times by 1 test
Evaluated by:
  • du
33-36
463-
464 return false;
executed 33 times by 1 test: return 0 ;
Executed by:
  • du
33
465}-
466-
467/* Return true if EX excludes F. */-
468-
469bool-
470excluded_file_name (struct exclude const *ex, char const *f)-
471{-
472 struct exclude_segment *seg;-
473 bool invert = false;-
474 char *filename = NULL;-
475-
476 /* If no patterns are given, the default is to include. */-
477 if (!ex->head)
!ex->headDescription
TRUEevaluated 211128 times by 1 test
Evaluated by:
  • du
FALSEevaluated 68 times by 1 test
Evaluated by:
  • du
68-211128
478 return false;
executed 211128 times by 1 test: return 0 ;
Executed by:
  • du
211128
479-
480 /* Scan through the segments, reporting the status of the first match.-
481 The segments are in reverse order, so this reports the status of-
482 the last match in the original option list. */-
483 for (seg = ex->head; ; seg = seg->next)-
484 {-
485 if (seg->type == exclude_hash)
seg->type == exclude_hashDescription
TRUEevaluated 43 times by 1 test
Evaluated by:
  • du
FALSEevaluated 25 times by 1 test
Evaluated by:
  • du
25-43
486 {-
487 if (!filename)
!filenameDescription
TRUEevaluated 43 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-43
488 filename = xmalloc (strlen (f) + 1);
executed 43 times by 1 test: filename = xmalloc (strlen (f) + 1);
Executed by:
  • du
43
489 if (file_name_matches (seg, f, filename))
file_name_matc..., f, filename)Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • du
FALSEevaluated 33 times by 1 test
Evaluated by:
  • du
10-33
490 break;
executed 10 times by 1 test: break;
Executed by:
  • du
10
491 }
executed 33 times by 1 test: end of block
Executed by:
  • du
33
492 else-
493 {-
494 if (file_pattern_matches (seg, f))
file_pattern_matches (seg, f)Description
TRUEevaluated 24 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-24
495 break;
executed 24 times by 1 test: break;
Executed by:
  • du
24
496 }
executed 1 time by 1 test: end of block
Executed by:
  • du
1
497-
498 if (! seg->next)
! seg->nextDescription
TRUEevaluated 34 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-34
499 {-
500 /* If patterns are given but none match, the default is the-
501 opposite of the last segment (i.e., the first in the-
502 original option list). For example, in the command-
503 'grep -r --exclude="a*" --include="*b" pat dir', the-
504 first option is --exclude so any file name matching-
505 neither a* nor *b is included. */-
506 invert = true;-
507 break;
executed 34 times by 1 test: break;
Executed by:
  • du
34
508 }-
509 }
never executed: end of block
0
510-
511 free (filename);-
512 return invert ^ ! (seg->options & EXCLUDE_INCLUDE);
executed 68 times by 1 test: return invert ^ ! (seg->options & (1 << 29));
Executed by:
  • du
68
513}-
514-
515/* Append to EX the exclusion PATTERN with OPTIONS. */-
516-
517void-
518add_exclude (struct exclude *ex, char const *pattern, int options)-
519{-
520 struct exclude_segment *seg;-
521 struct exclude_pattern *pat;-
522 struct patopts *patopts;-
523-
524 if ((options & (EXCLUDE_REGEX|EXCLUDE_WILDCARDS))
(options & ((1...7)|(1 << 28)))Description
TRUEevaluated 12 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-12
525 && fnmatch_pattern_has_wildcards (pattern, options))
fnmatch_patter...tern, options)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEevaluated 11 times by 1 test
Evaluated by:
  • du
1-11
526 {-
527 if (! (ex->head && ex->head->type == exclude_pattern
ex->headDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
ex->head->type...xclude_patternDescription
TRUEnever evaluated
FALSEnever evaluated
0-1
528 && ((ex->head->options & EXCLUDE_INCLUDE)
((ex->head->op... & (1 << 29)))Description
TRUEnever evaluated
FALSEnever evaluated
0
529 == (options & EXCLUDE_INCLUDE))))
((ex->head->op... & (1 << 29)))Description
TRUEnever evaluated
FALSEnever evaluated
0
530 new_exclude_segment (ex, exclude_pattern, options);
executed 1 time by 1 test: new_exclude_segment (ex, exclude_pattern, options);
Executed by:
  • du
1
531-
532 seg = ex->head;-
533-
534 pat = &seg->v.pat;-
535 if (pat->exclude_count == pat->exclude_alloc)
pat->exclude_c...>exclude_allocDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
536 pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc,
executed 1 time by 1 test: pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc, sizeof *pat->exclude);
Executed by:
  • du
1
537 sizeof *pat->exclude);
executed 1 time by 1 test: pat->exclude = x2nrealloc (pat->exclude, &pat->exclude_alloc, sizeof *pat->exclude);
Executed by:
  • du
1
538 patopts = &pat->exclude[pat->exclude_count++];-
539-
540 patopts->options = options;-
541 if (options & EXCLUDE_REGEX)
options & (1 << 27)Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
0-1
542 {-
543 int rc;-
544 int cflags = REG_NOSUB|REG_EXTENDED|-
545 ((options & FNM_CASEFOLD) ? REG_ICASE : 0);-
546-
547 if (options & FNM_LEADING_DIR)
options & (1 << 3)Description
TRUEnever evaluated
FALSEnever evaluated
0
548 {-
549 char *tmp;-
550 size_t len = strlen (pattern);-
551-
552 while (len > 0 && ISSLASH (pattern[len-1]))
len > 0Description
TRUEnever evaluated
FALSEnever evaluated
((pattern[len-1]) == '/')Description
TRUEnever evaluated
FALSEnever evaluated
0
553 --len;
never executed: --len;
0
554-
555 if (len == 0)
len == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
556 rc = 1;
never executed: rc = 1;
0
557 else-
558 {-
559 tmp = xmalloc (len + 7);-
560 memcpy (tmp, pattern, len);-
561 strcpy (tmp + len, "(/.*)?");-
562 rc = regcomp (&patopts->v.re, tmp, cflags);-
563 free (tmp);-
564 }
never executed: end of block
0
565 }-
566 else-
567 rc = regcomp (&patopts->v.re, pattern, cflags);
never executed: rc = regcomp (&patopts->v.re, pattern, cflags);
0
568-
569 if (rc)
rcDescription
TRUEnever evaluated
FALSEnever evaluated
0
570 {-
571 pat->exclude_count--;-
572 return;
never executed: return;
0
573 }-
574 }
never executed: end of block
0
575 else-
576 {-
577 if (options & EXCLUDE_ALLOC)
options & (1 << 26)Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
0-1
578 {-
579 pattern = xstrdup (pattern);-
580 exclude_add_pattern_buffer (ex, (char*) pattern);-
581 }
never executed: end of block
0
582 patopts->v.pattern = pattern;-
583 }
executed 1 time by 1 test: end of block
Executed by:
  • du
1
584 }-
585 else-
586 {-
587 char *str, *p;-
588 int exclude_hash_flags = (EXCLUDE_INCLUDE | EXCLUDE_ANCHORED-
589 | FNM_LEADING_DIR | FNM_CASEFOLD);-
590 if (! (ex->head && ex->head->type == exclude_hash
ex->headDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEevaluated 10 times by 1 test
Evaluated by:
  • du
ex->head->type == exclude_hashDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-10
591 && ((ex->head->options & exclude_hash_flags)
((ex->head->op...e_hash_flags))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
592 == (options & exclude_hash_flags))))
((ex->head->op...e_hash_flags))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
593 new_exclude_segment (ex, exclude_hash, options);
executed 10 times by 1 test: new_exclude_segment (ex, exclude_hash, options);
Executed by:
  • du
10
594 seg = ex->head;-
595-
596 str = xstrdup (pattern);-
597 if ((options & (EXCLUDE_WILDCARDS | FNM_NOESCAPE)) == EXCLUDE_WILDCARDS)
(options & ((1...) == (1 << 28)Description
TRUEevaluated 11 times by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-11
598 unescape_pattern (str);
executed 11 times by 1 test: unescape_pattern (str);
Executed by:
  • du
11
599 p = hash_insert (seg->v.table, str);-
600 if (p != str)
p != strDescription
TRUEnever evaluated
FALSEevaluated 11 times by 1 test
Evaluated by:
  • du
0-11
601 free (str);
never executed: free (str);
0
602 }
executed 11 times by 1 test: end of block
Executed by:
  • du
11
603}-
604-
605/* Use ADD_FUNC to append to EX the patterns in FILE_NAME, each with-
606 OPTIONS. LINE_END terminates each pattern in the file. If-
607 LINE_END is a space character, ignore trailing spaces and empty-
608 lines in FP. Return -1 on failure, 0 on success. */-
609-
610int-
611add_exclude_fp (void (*add_func) (struct exclude *, char const *, int, void *),-
612 struct exclude *ex, FILE *fp, int options,-
613 char line_end,-
614 void *data)-
615{-
616 char *buf = NULL;-
617 char *p;-
618 char *pattern;-
619 char const *lim;-
620 size_t buf_alloc = 0;-
621 size_t buf_count = 0;-
622 int c;-
623 int e = 0;-
624-
625 while ((c = getc (fp)) != EOF)
(c = getc_unlo... (fp)) != (-1)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-2
626 {-
627 if (buf_count == buf_alloc)
buf_count == buf_allocDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1
628 buf = x2realloc (buf, &buf_alloc);
executed 1 time by 1 test: buf = x2realloc (buf, &buf_alloc);
Executed by:
  • du
1
629 buf[buf_count++] = c;-
630 }
executed 2 times by 1 test: end of block
Executed by:
  • du
2
631-
632 if (ferror (fp))
ferror_unlocked (fp)Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
0-1
633 e = errno;
never executed: e = (*__errno_location ()) ;
0
634-
635 buf = xrealloc (buf, buf_count + 1);-
636 buf[buf_count] = line_end;-
637 lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end);
buf_count == 0Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
buf[buf_count - 1] == line_endDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
638-
639 exclude_add_pattern_buffer (ex, buf);-
640-
641 pattern = buf;-
642-
643 for (p = buf; p < lim; p++)
p < limDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-2
644 if (*p == line_end)
*p == line_endDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1
645 {-
646 char *pattern_end = p;-
647-
648 if (isspace ((unsigned char) line_end))
((*__ctype_b_l...int) _ISspace)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
649 {-
650 for (; ; pattern_end--)-
651 if (pattern_end == pattern)
pattern_end == patternDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
0-1
652 goto next_pattern;
never executed: goto next_pattern;
0
653 else if (! isspace ((unsigned char) pattern_end[-1]))
! ((*__ctype_b...int) _ISspace)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
0-1
654 break;
executed 1 time by 1 test: break;
Executed by:
  • du
1
655 }
executed 1 time by 1 test: end of block
Executed by:
  • du
1
656-
657 *pattern_end = '\0';-
658 (*add_func) (ex, pattern, options, data);-
659-
660 next_pattern:
code before this statement executed 1 time by 1 test: next_pattern:
Executed by:
  • du
1
661 pattern = p + 1;-
662 }
executed 1 time by 1 test: end of block
Executed by:
  • du
1
663-
664 errno = e;-
665 return e ? -1 : 0;
executed 1 time by 1 test: return e ? -1 : 0;
Executed by:
  • du
1
666}-
667-
668static void-
669call_addfn (struct exclude *ex, char const *pattern, int options, void *data)-
670{-
671 void (**addfnptr) (struct exclude *, char const *, int) = data;-
672 (*addfnptr) (ex, pattern, options);-
673}
executed 1 time by 1 test: end of block
Executed by:
  • du
1
674-
675int-
676add_exclude_file (void (*add_func) (struct exclude *, char const *, int),-
677 struct exclude *ex, char const *file_name, int options,-
678 char line_end)-
679{-
680 bool use_stdin = file_name[0] == '-' && !file_name[1];
file_name[0] == '-'Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
!file_name[1]Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • du
0-2
681 FILE *in;-
682 int rc = 0;-
683-
684 if (use_stdin)
use_stdinDescription
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • du
0-3
685 in = stdin;
never executed: in = stdin ;
0
686 else if (! (in = fopen (file_name, "r")))
! (in = fopen ...le_name, "r"))Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • du
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
1-2
687 return -1;
executed 2 times by 1 test: return -1;
Executed by:
  • du
2
688-
689 rc = add_exclude_fp (call_addfn, ex, in, options, line_end, &add_func);-
690-
691 if (!use_stdin && fclose (in) != 0)
!use_stdinDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • du
FALSEnever evaluated
rpl_fclose (in) != 0Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • du
0-1
692 rc = -1;
never executed: rc = -1;
0
693-
694 return rc;
executed 1 time by 1 test: return rc;
Executed by:
  • du
1
695}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2