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
34 int av_strstart(const char *str
, const char *pfx
, const char **ptr
)
36 while (*pfx
&& *pfx
== *str
) {
45 int av_stristart(const char *str
, const char *pfx
, const char **ptr
)
47 while (*pfx
&& av_toupper((unsigned)*pfx
) == av_toupper((unsigned)*str
)) {
56 char *av_stristr(const char *s1
, const char *s2
)
59 return (char*)(intptr_t)s1
;
62 if (av_stristart(s1
, s2
, NULL
))
63 return (char*)(intptr_t)s1
;
69 char *av_strnstr(const char *haystack
, const char *needle
, size_t hay_length
)
71 size_t needle_len
= strlen(needle
);
73 return (char*)haystack
;
74 while (hay_length
>= needle_len
) {
76 if (!memcmp(haystack
, needle
, needle_len
))
77 return (char*)haystack
;
83 size_t av_strlcpy(char *dst
, const char *src
, size_t size
)
86 while (++len
< size
&& *src
)
90 return len
+ strlen(src
) - 1;
93 size_t av_strlcat(char *dst
, const char *src
, size_t size
)
95 size_t len
= strlen(dst
);
97 return len
+ strlen(src
);
98 return len
+ av_strlcpy(dst
+ len
, src
, size
- len
);
101 size_t av_strlcatf(char *dst
, size_t size
, const char *fmt
, ...)
103 int len
= strlen(dst
);
107 len
+= vsnprintf(dst
+ len
, size
> len
? size
- len
: 0, fmt
, vl
);
113 char *av_asprintf(const char *fmt
, ...)
120 len
= vsnprintf(NULL
, 0, fmt
, va
);
125 p
= av_malloc(len
+ 1);
130 len
= vsnprintf(p
, len
+ 1, fmt
, va
);
139 char *av_d2str(double d
)
141 char *str
= av_malloc(16);
143 snprintf(str
, 16, "%f", d
);
147 #define WHITESPACES " \n\t"
149 char *av_get_token(const char **buf
, const char *term
)
151 char *out
= av_malloc(strlen(*buf
) + 1);
152 char *ret
= out
, *end
= out
;
153 const char *p
= *buf
;
156 p
+= strspn(p
, WHITESPACES
);
158 while (*p
&& !strspn(p
, term
)) {
160 if (c
== '\\' && *p
) {
163 } else if (c
== '\'') {
164 while (*p
&& *p
!= '\'')
177 while (out
>= end
&& strspn(out
, WHITESPACES
));
184 char *av_strtok(char *s
, const char *delim
, char **saveptr
)
188 if (!s
&& !(s
= *saveptr
))
191 /* skip leading delimiters */
192 s
+= strspn(s
, delim
);
194 /* s now points to the first non delimiter char, or to the end of the string */
201 /* skip non delimiters */
202 s
+= strcspn(s
, delim
);
213 int av_strcasecmp(const char *a
, const char *b
)
217 c1
= av_tolower(*a
++);
218 c2
= av_tolower(*b
++);
219 } while (c1
&& c1
== c2
);
223 int av_strncasecmp(const char *a
, const char *b
, size_t n
)
225 const char *end
= a
+ n
;
228 c1
= av_tolower(*a
++);
229 c2
= av_tolower(*b
++);
230 } while (a
< end
&& c1
&& c1
== c2
);
234 const char *av_basename(const char *path
)
236 char *p
= strrchr(path
, '/');
239 char *q
= strrchr(path
, '\\');
240 char *d
= strchr(path
, ':');
251 const char *av_dirname(char *path
)
253 char *p
= strrchr(path
, '/');
256 char *q
= strrchr(path
, '\\');
257 char *d
= strchr(path
, ':');
272 int av_escape(char **dst
, const char *src
, const char *special_chars
,
273 enum AVEscapeMode mode
, int flags
)
277 av_bprint_init(&dstbuf
, 1, AV_BPRINT_SIZE_UNLIMITED
);
278 av_bprint_escape(&dstbuf
, src
, special_chars
, mode
, flags
);
280 if (!av_bprint_is_complete(&dstbuf
)) {
281 av_bprint_finalize(&dstbuf
, NULL
);
282 return AVERROR(ENOMEM
);
284 av_bprint_finalize(&dstbuf
, dst
);
289 int av_isdigit(int c
)
291 return c
>= '0' && c
<= '9';
294 int av_isgraph(int c
)
296 return c
> 32 && c
< 127;
299 int av_isspace(int c
)
301 return c
== ' ' || c
== '\f' || c
== '\n' || c
== '\r' || c
== '\t' ||
305 int av_isxdigit(int c
)
308 return av_isdigit(c
) || (c
>= 'a' && c
<= 'f');
311 int av_match_name(const char *name
, const char *names
)
319 namelen
= strlen(name
);
320 while ((p
= strchr(names
, ','))) {
321 len
= FFMAX(p
- names
, namelen
);
322 if (!av_strncasecmp(name
, names
, len
))
326 return !av_strcasecmp(name
, names
);
329 int av_utf8_decode(int32_t *codep
, const uint8_t **bufp
, const uint8_t *buf_end
,
332 const uint8_t *p
= *bufp
;
335 int ret
= 0, tail_len
;
336 uint32_t overlong_encoding_mins
[6] = {
337 0x00000000, 0x00000080, 0x00000800, 0x00010000, 0x00200000, 0x04000000,
345 /* first sequence byte starts with 10, or is 1111-1110 or 1111-1111,
346 which is not admitted */
347 if ((code
& 0xc0) == 0x80 || code
>= 0xFE) {
348 ret
= AVERROR(EILSEQ
);
351 top
= (code
& 128) >> 1;
359 return AVERROR(EILSEQ
); /* incomplete sequence */
362 /* we assume the byte to be in the form 10xx-xxxx */
363 tmp
= *p
++ - 128; /* strip leading 1 */
366 return AVERROR(EILSEQ
);
368 code
= (code
<<6) + tmp
;
371 code
&= (top
<< 1) - 1;
373 /* check for overlong encodings */
374 av_assert0(tail_len
<= 5);
375 if (code
< overlong_encoding_mins
[tail_len
]) {
376 ret
= AVERROR(EILSEQ
);
381 ret
= AVERROR(EILSEQ
); /* out-of-range value */
387 if (code
> 0x10FFFF &&
388 !(flags
& AV_UTF8_FLAG_ACCEPT_INVALID_BIG_CODES
))
389 ret
= AVERROR(EILSEQ
);
390 if (code
< 0x20 && code
!= 0x9 && code
!= 0xA && code
!= 0xD &&
391 flags
& AV_UTF8_FLAG_EXCLUDE_XML_INVALID_CONTROL_CODES
)
392 ret
= AVERROR(EILSEQ
);
393 if (code
>= 0xD800 && code
<= 0xDFFF &&
394 !(flags
& AV_UTF8_FLAG_ACCEPT_SURROGATES
))
395 ret
= AVERROR(EILSEQ
);
396 if ((code
== 0xFFFE || code
== 0xFFFF) &&
397 !(flags
& AV_UTF8_FLAG_ACCEPT_NON_CHARACTERS
))
398 ret
= AVERROR(EILSEQ
);
405 int av_match_list(const char *name
, const char *list
, char separator
)
409 for (p
= name
; p
&& *p
; ) {
410 for (q
= list
; q
&& *q
; ) {
412 for (k
= 0; p
[k
] == q
[k
] || (p
[k
]*q
[k
] == 0 && p
[k
]+q
[k
] == separator
); k
++)
413 if (k
&& (!p
[k
] || p
[k
] == separator
))
415 q
= strchr(q
, separator
);
418 p
= strchr(p
, separator
);
430 static const char * const strings
[] = {
446 "'foo : ' :blahblah",
452 " foo bar : blahblah",
454 "'foo : \\ \\ ' : blahblah",
455 "'\\fo\\o:': blahblah",
456 "\\'fo\\o\\:': foo ' :blahblah"
459 printf("Testing av_get_token()\n");
460 for (i
= 0; i
< FF_ARRAY_ELEMS(strings
); i
++) {
461 const char *p
= strings
[i
];
464 q
= av_get_token(&p
, ":");
465 printf(" -> |%s|", q
);
466 printf(" + |%s|\n", p
);