3 * Copyright 2018 Peter Jones <pjones@redhat.com>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see
17 * <http://www.gnu.org/licenses/>.
19 #include "fix_coverity.h"
24 cinpat(const char c, const char *pat)
26 for (unsigned int i = 0; pat[i]; i++)
33 strxcspn(const char *s, const char *pattern)
36 for (i = 0; s[i]; i++) {
37 if (!cinpat(s[i], pattern))
49 * count how many parts of a path there are, with some caveats:
50 * a leading / is one because it's a directory, but all other slashes are
51 * treated as separators, so i.e.:
53 * 2: /foo foo/bar foo/bar/
54 * 3: /foo/bar /foo/bar/ foo/bar/baz
56 * the usage model here is 1 pass to count, one allocation, one pass to
60 count_spans(const char *str, const char *reject, unsigned int *chars)
62 unsigned int s = 0, c = 0, pos = 0;
73 n = strcspn(str + pos, reject);
80 pos += strxcspn(str + pos, reject);
89 fill_spans(const char *str, const char *reject, void *spanbuf)
91 struct span *spans = (struct span *)spanbuf;
92 struct span *span = spans;
105 n = strcspn(str + pos, reject);
107 span->pos = str + pos;
113 pos += strxcspn(str + pos, reject);
119 #define split_spans(str, reject) \
121 struct span *ret_ = NULL; \
122 unsigned int s_, c_; \
124 s_ = count_spans(str, "/", &c_); \
126 ret_ = alloca(sizeof(struct span[s_+1])); \
128 fill_spans(str, reject, ret_); \
136 find_path_segment(const char *path, int segment, const char **pos, size_t *len)
138 struct span *span, *last;
146 span = split_spans(path, "/");
155 for (last = span; last->pos; last++)
159 segment = nspans + segment;
161 if (nspans < 1 || segment < 0 || segment >= nspans) {
166 for (int i = 0; i < segment; i++)
174 // vim:fenc=utf-8:tw=75:et