2 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
3 * Copyright (c) 2007 Mans Rullgard
5 * This file is part of FFmpeg.
7 * FFmpeg 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.
12 * FFmpeg 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36 int av_strstart(const char *str
, const char *pfx
, const char **ptr
)
38 while (*pfx
&& *pfx
== *str
) {
47 int av_stristart(const char *str
, const char *pfx
, const char **ptr
)
49 while (*pfx
&& av_toupper((unsigned)*pfx
) == av_toupper((unsigned)*str
)) {
58 char *av_stristr(const char *s1
, const char *s2
)
61 return (char*)(intptr_t)s1
;
64 if (av_stristart(s1
, s2
, NULL
))
65 return (char*)(intptr_t)s1
;
71 char *av_strnstr(const char *haystack
, const char *needle
, size_t hay_length
)
73 size_t needle_len
= strlen(needle
);
75 return (char*)haystack
;
76 while (hay_length
>= needle_len
) {
78 if (!memcmp(haystack
, needle
, needle_len
))
79 return (char*)haystack
;
85 size_t av_strlcpy(char *dst
, const char *src
, size_t size
)
88 while (++len
< size
&& *src
)
92 return len
+ strlen(src
) - 1;
95 size_t av_strlcat(char *dst
, const char *src
, size_t size
)
97 size_t len
= strlen(dst
);
99 return len
+ strlen(src
);
100 return len
+ av_strlcpy(dst
+ len
, src
, size
- len
);
103 size_t av_strlcatf(char *dst
, size_t size
, const char *fmt
, ...)
105 size_t len
= strlen(dst
);
109 len
+= vsnprintf(dst
+ len
, size
> len
? size
- len
: 0, fmt
, vl
);
115 char *av_asprintf(const char *fmt
, ...)
122 len
= vsnprintf(NULL
, 0, fmt
, va
);
127 p
= av_malloc(len
+ 1);
132 len
= vsnprintf(p
, len
+ 1, fmt
, va
);
141 #define WHITESPACES " \n\t\r"
143 char *av_get_token(const char **buf
, const char *term
)
145 char *out
= av_realloc(NULL
, strlen(*buf
) + 1);
146 char *ret
= out
, *end
= out
;
147 const char *p
= *buf
;
150 p
+= strspn(p
, WHITESPACES
);
152 while (*p
&& !strspn(p
, term
)) {
154 if (c
== '\\' && *p
) {
157 } else if (c
== '\'') {
158 while (*p
&& *p
!= '\'')
171 while (out
>= end
&& strspn(out
, WHITESPACES
));
175 char *small_ret
= av_realloc(ret
, out
- ret
+ 2);
176 return small_ret
? small_ret
: ret
;
179 char *av_strtok(char *s
, const char *delim
, char **saveptr
)
183 if (!s
&& !(s
= *saveptr
))
186 /* skip leading delimiters */
187 s
+= strspn(s
, delim
);
189 /* s now points to the first non delimiter char, or to the end of the string */
196 /* skip non delimiters */
197 s
+= strcspn(s
, delim
);
208 int av_strcasecmp(const char *a
, const char *b
)
212 c1
= av_tolower(*a
++);
213 c2
= av_tolower(*b
++);
214 } while (c1
&& c1
== c2
);
218 int av_strncasecmp(const char *a
, const char *b
, size_t n
)
224 c1
= av_tolower(*a
++);
225 c2
= av_tolower(*b
++);
226 } while (--n
&& c1
&& c1
== c2
);
230 char *av_strireplace(const char *str
, const char *from
, const char *to
)
233 const char *pstr2
, *pstr
= str
;
234 size_t tolen
= strlen(to
), fromlen
= strlen(from
);
237 av_bprint_init(&pbuf
, 1, AV_BPRINT_SIZE_UNLIMITED
);
238 while ((pstr2
= av_stristr(pstr
, from
))) {
239 av_bprint_append_data(&pbuf
, pstr
, pstr2
- pstr
);
240 pstr
= pstr2
+ fromlen
;
241 av_bprint_append_data(&pbuf
, to
, tolen
);
243 av_bprint_append_data(&pbuf
, pstr
, strlen(pstr
));
244 if (!av_bprint_is_complete(&pbuf
)) {
245 av_bprint_finalize(&pbuf
, NULL
);
247 av_bprint_finalize(&pbuf
, &ret
);
253 const char *av_basename(const char *path
)
260 if (!path
|| *path
== '\0')
263 p
= strrchr(path
, '/');
265 q
= strrchr(path
, '\\');
266 d
= strchr(path
, ':');
276 const char *av_dirname(char *path
)
278 char *p
= path
? strrchr(path
, '/') : NULL
;
281 char *q
= path
? strrchr(path
, '\\') : NULL
;
282 char *d
= path
? strchr(path
, ':') : NULL
;
297 char *av_append_path_component(const char *path
, const char *component
)
303 return av_strdup(component
);
305 return av_strdup(path
);
307 p_len
= strlen(path
);
308 c_len
= strlen(component
);
309 if (p_len
> SIZE_MAX
- c_len
|| p_len
+ c_len
> SIZE_MAX
- 2)
311 fullpath
= av_malloc(p_len
+ c_len
+ 2);
314 av_strlcpy(fullpath
, path
, p_len
+ 1);
316 if (fullpath
[p_len
- 1] != '/' && component
[0] != '/')
317 fullpath
[p_len
++] = '/';
318 else if (fullpath
[p_len
- 1] == '/' && component
[0] == '/')
322 av_strlcpy(&fullpath
[p_len
], component
, c_len
+ 1);
323 fullpath
[p_len
+ c_len
] = 0;
328 int av_escape(char **dst
, const char *src
, const char *special_chars
,
329 enum AVEscapeMode mode
, int flags
)
334 av_bprint_init(&dstbuf
, 1, INT_MAX
); /* (int)dstbuf.len must be >= 0 */
335 av_bprint_escape(&dstbuf
, src
, special_chars
, mode
, flags
);
337 if (!av_bprint_is_complete(&dstbuf
)) {
338 av_bprint_finalize(&dstbuf
, NULL
);
339 return AVERROR(ENOMEM
);
341 if ((ret
= av_bprint_finalize(&dstbuf
, dst
)) < 0)
346 int av_match_name(const char *name
, const char *names
)
354 namelen
= strlen(name
);
356 int negate
= '-' == *names
;
357 p
= strchr(names
, ',');
359 p
= names
+ strlen(names
);
361 len
= FFMAX(p
- names
, namelen
);
362 if (!av_strncasecmp(name
, names
, len
) || !strncmp("ALL", names
, FFMAX(3, p
- names
)))
364 names
= p
+ (*p
== ',');
369 int av_utf8_decode(int32_t *codep
, const uint8_t **bufp
, const uint8_t *buf_end
,
372 const uint8_t *p
= *bufp
;
375 int ret
= 0, tail_len
;
376 uint32_t overlong_encoding_mins
[6] = {
377 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000,
385 /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
386 which is not admitted */
387 if ((code
& 0xc0) == 0x80 || code
>= 0xFE) {
388 ret
= AVERROR(EILSEQ
);
391 top
= (code
& 128) >> 1;
399 return AVERROR(EILSEQ
); /* incomplete sequence */
402 /* we assume the byte to be in the form 10xx-xxxx */
403 tmp
= *p
++ - 128; /* strip leading 1 */
406 return AVERROR(EILSEQ
);
408 code
= (code
<<6) + tmp
;
411 code
&= (top
<< 1) - 1;
413 /* check for overlong encodings */
414 av_assert0(tail_len
<= 5);
415 if (code
< overlong_encoding_mins
[tail_len
]) {
416 ret
= AVERROR(EILSEQ
);
420 if (code
>= 1U<<31) {
421 ret
= AVERROR(EILSEQ
); /* out-of-range value */
427 if (code
> 0x10FFFF &&
428 !(flags
& AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES
))
429 ret
= AVERROR(EILSEQ
);
430 if (code
< 0x20 && code
!= 0x9 && code
!= 0xA && code
!= 0xD &&
431 flags
& AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES
)
432 ret
= AVERROR(EILSEQ
);
433 if (code
>= 0xD800 && code
<= 0xDFFF &&
434 !(flags
& AV_UTF8_FLAG_ACCEPT_SURROGATES
))
435 ret
= AVERROR(EILSEQ
);
436 if ((code
== 0xFFFE || code
== 0xFFFF) &&
437 !(flags
& AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS
))
438 ret
= AVERROR(EILSEQ
);
445 int av_match_list(const char *name
, const char *list
, char separator
)
449 for (p
= name
; p
&& *p
; ) {
450 for (q
= list
; q
&& *q
; ) {
452 for (k
= 0; p
[k
] == q
[k
] || (p
[k
]*q
[k
] == 0 && p
[k
]+q
[k
] == separator
); k
++)
453 if (k
&& (!p
[k
] || p
[k
] == separator
))
455 q
= strchr(q
, separator
);
459 p
= strchr(p
, separator
);