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