Line data Source code
1 : /*
2 : * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3 : * Copyright (c) 2007 Mans Rullgard
4 : *
5 : * This file is part of Libav.
6 : *
7 : * Libav is free software; you can redistribute it and/or
8 : * modify it under the terms of the GNU Lesser General Public
9 : * License as published by the Free Software Foundation; either
10 : * version 2.1 of the License, or (at your option) any later version.
11 : *
12 : * Libav is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : * Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public
18 : * License along with Libav; if not, write to the Free Software
19 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 : */
21 :
22 : #include <stdarg.h>
23 : #include <stdint.h>
24 : #include <stdio.h>
25 : #include <string.h>
26 :
27 : #include "config.h"
28 : #include "common.h"
29 : #include "mem.h"
30 : #include "avstring.h"
31 :
32 0 : int av_strstart(const char *str, const char *pfx, const char **ptr)
33 : {
34 0 : while (*pfx && *pfx == *str) {
35 0 : pfx++;
36 0 : str++;
37 : }
38 0 : if (!*pfx && ptr)
39 0 : *ptr = str;
40 0 : return !*pfx;
41 : }
42 :
43 0 : int av_stristart(const char *str, const char *pfx, const char **ptr)
44 : {
45 0 : while (*pfx && av_toupper((unsigned)*pfx) == av_toupper((unsigned)*str)) {
46 0 : pfx++;
47 0 : str++;
48 : }
49 0 : if (!*pfx && ptr)
50 0 : *ptr = str;
51 0 : return !*pfx;
52 : }
53 :
54 0 : char *av_stristr(const char *s1, const char *s2)
55 : {
56 0 : if (!*s2)
57 0 : return s1;
58 :
59 : do
60 0 : if (av_stristart(s1, s2, NULL))
61 0 : return s1;
62 0 : while (*s1++);
63 :
64 0 : return NULL;
65 : }
66 :
67 0 : char *av_strnstr(const char *haystack, const char *needle, size_t hay_length)
68 : {
69 0 : size_t needle_len = strlen(needle);
70 0 : if (!needle_len)
71 0 : return haystack;
72 0 : while (hay_length >= needle_len) {
73 0 : hay_length--;
74 0 : if (!memcmp(haystack, needle, needle_len))
75 0 : return haystack;
76 0 : haystack++;
77 : }
78 0 : return NULL;
79 : }
80 :
81 0 : size_t av_strlcpy(char *dst, const char *src, size_t size)
82 : {
83 0 : size_t len = 0;
84 0 : while (++len < size && *src)
85 0 : *dst++ = *src++;
86 0 : if (len <= size)
87 0 : *dst = 0;
88 0 : return len + strlen(src) - 1;
89 : }
90 :
91 0 : size_t av_strlcat(char *dst, const char *src, size_t size)
92 : {
93 0 : size_t len = strlen(dst);
94 0 : if (size <= len + 1)
95 0 : return len + strlen(src);
96 0 : return len + av_strlcpy(dst + len, src, size - len);
97 : }
98 :
99 0 : size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...)
100 : {
101 0 : int len = strlen(dst);
102 : va_list vl;
103 :
104 0 : va_start(vl, fmt);
105 0 : len += vsnprintf(dst + len, size > len ? size - len : 0, fmt, vl);
106 0 : va_end(vl);
107 :
108 0 : return len;
109 : }
110 :
111 0 : char *av_d2str(double d)
112 : {
113 0 : char *str = av_malloc(16);
114 0 : if (str)
115 0 : snprintf(str, 16, "%f", d);
116 0 : return str;
117 : }
118 :
119 : #define WHITESPACES " \n\t"
120 :
121 0 : char *av_get_token(const char **buf, const char *term)
122 : {
123 0 : char *out = av_malloc(strlen(*buf) + 1);
124 0 : char *ret = out, *end = out;
125 0 : const char *p = *buf;
126 0 : if (!out)
127 0 : return NULL;
128 0 : p += strspn(p, WHITESPACES);
129 :
130 0 : while (*p && !strspn(p, term)) {
131 0 : char c = *p++;
132 0 : if (c == '\\' && *p) {
133 0 : *out++ = *p++;
134 0 : end = out;
135 0 : } else if (c == '\'') {
136 0 : while (*p && *p != '\'')
137 0 : *out++ = *p++;
138 0 : if (*p) {
139 0 : p++;
140 0 : end = out;
141 : }
142 : } else {
143 0 : *out++ = c;
144 : }
145 : }
146 :
147 : do
148 0 : *out-- = 0;
149 0 : while (out >= end && strspn(out, WHITESPACES));
150 :
151 0 : *buf = p;
152 :
153 0 : return ret;
154 : }
155 :
156 0 : int av_strcasecmp(const char *a, const char *b)
157 : {
158 : uint8_t c1, c2;
159 : do {
160 0 : c1 = av_tolower(*a++);
161 0 : c2 = av_tolower(*b++);
162 0 : } while (c1 && c1 == c2);
163 0 : return c1 - c2;
164 : }
165 :
166 0 : int av_strncasecmp(const char *a, const char *b, size_t n)
167 : {
168 0 : const char *end = a + n;
169 : uint8_t c1, c2;
170 : do {
171 0 : c1 = av_tolower(*a++);
172 0 : c2 = av_tolower(*b++);
173 0 : } while (a < end && c1 && c1 == c2);
174 0 : return c1 - c2;
175 : }
176 :
177 0 : const char *av_basename(const char *path)
178 : {
179 0 : char *p = strrchr(path, '/');
180 :
181 : #if HAVE_DOS_PATHS
182 : char *q = strrchr(path, '\\');
183 : char *d = strchr(path, ':');
184 :
185 : p = FFMAX3(p, q, d);
186 : #endif
187 :
188 0 : if (!p)
189 0 : return path;
190 :
191 0 : return p + 1;
192 : }
193 :
194 0 : const char *av_dirname(char *path)
195 : {
196 0 : char *p = strrchr(path, '/');
197 :
198 : #if HAVE_DOS_PATHS
199 : char *q = strrchr(path, '\\');
200 : char *d = strchr(path, ':');
201 :
202 : d = d ? d + 1 : d;
203 :
204 : p = FFMAX3(p, q, d);
205 : #endif
206 :
207 0 : if (!p)
208 0 : return ".";
209 :
210 0 : *p = '\0';
211 :
212 0 : return path;
213 : }
214 :
215 0 : int av_isdigit(int c)
216 : {
217 0 : return c >= '0' && c <= '9';
218 : }
219 :
220 0 : int av_isgraph(int c)
221 : {
222 0 : return c > 32 && c < 127;
223 : }
224 :
225 0 : int av_isspace(int c)
226 : {
227 0 : return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' ||
228 : c == '\v';
229 : }
230 :
231 0 : int av_isxdigit(int c)
232 : {
233 0 : c = av_tolower(c);
234 0 : return av_isdigit(c) || (c >= 'a' && c <= 'f');
235 : }
236 :
237 0 : int av_match_name(const char *name, const char *names)
238 : {
239 : const char *p;
240 : int len, namelen;
241 :
242 0 : if (!name || !names)
243 0 : return 0;
244 :
245 0 : namelen = strlen(name);
246 0 : while ((p = strchr(names, ','))) {
247 0 : len = FFMAX(p - names, namelen);
248 0 : if (!av_strncasecmp(name, names, len))
249 0 : return 1;
250 0 : names = p + 1;
251 : }
252 0 : return !av_strcasecmp(name, names);
253 : }
254 :
255 :
256 :
257 : #ifdef TEST
258 :
259 : int main(void)
260 : {
261 : int i;
262 : const char *strings[] = {
263 : "''",
264 : "",
265 : ":",
266 : "\\",
267 : "'",
268 : " '' :",
269 : " '' '' :",
270 : "foo '' :",
271 : "'foo'",
272 : "foo ",
273 : " ' foo ' ",
274 : "foo\\",
275 : "foo': blah:blah",
276 : "foo\\: blah:blah",
277 : "foo\'",
278 : "'foo : ' :blahblah",
279 : "\\ :blah",
280 : " foo",
281 : " foo ",
282 : " foo \\ ",
283 : "foo ':blah",
284 : " foo bar : blahblah",
285 : "\\f\\o\\o",
286 : "'foo : \\ \\ ' : blahblah",
287 : "'\\fo\\o:': blahblah",
288 : "\\'fo\\o\\:': foo ' :blahblah"
289 : };
290 :
291 : printf("Testing av_get_token()\n");
292 : for (i = 0; i < FF_ARRAY_ELEMS(strings); i++) {
293 : const char *p = strings[i];
294 : char *q;
295 : printf("|%s|", p);
296 : q = av_get_token(&p, ":");
297 : printf(" -> |%s|", q);
298 : printf(" + |%s|\n", p);
299 : av_free(q);
300 : }
301 :
302 : return 0;
303 : }
304 :
305 : #endif /* TEST */
|