[FFmpeg-devel] [PATCH] lavu: add av_strtok_r()

Stefano Sabatini stefasab at gmail.com
Sat Oct 15 12:50:11 CEST 2011


The function strtok_r() is part of the POSIX.1 specification, but is not
available on some platforms. We provide an internal implementation, so we
do not need to rely on a platform implementation.

The code is based on the OpenBSD libc strtok_r() implementation.
---
 configure                  |    9 ++-------
 libavfilter/af_aconvert.c  |    7 ++++---
 libavfilter/af_aformat.c   |    2 +-
 libavfilter/asrc_abuffer.c |    5 +++--
 libavfilter/vf_frei0r.c    |    2 +-
 libavutil/avstring.c       |   42 ++++++++++++++++++++++++++++++++++++++++++
 libavutil/avstring.h       |   18 ++++++++++++++++++
 7 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/configure b/configure
index 0a5b52d..608fd7b 100755
--- a/configure
+++ b/configure
@@ -1184,7 +1184,6 @@ HAVE_LIST="
     setrlimit
     strerror_r
     strptime
-    strtok_r
     struct_addrinfo
     struct_ipv6_mreq
     struct_sockaddr_in6
@@ -1582,17 +1581,14 @@ tcp_protocol_deps="network"
 udp_protocol_deps="network"
 
 # filters
-abuffer_filter_deps="strtok_r"
-aconvert_filter_deps="strtok_r"
-aformat_filter_deps="strtok_r"
 amovie_filter_deps="avcodec avformat"
 blackframe_filter_deps="gpl"
 boxblur_filter_deps="gpl"
 cropdetect_filter_deps="gpl"
 delogo_filter_deps="gpl"
 drawtext_filter_deps="libfreetype"
-frei0r_filter_deps="frei0r dlopen strtok_r"
-frei0r_src_filter_deps="frei0r dlopen strtok_r"
+frei0r_filter_deps="frei0r dlopen"
+frei0r_src_filter_deps="frei0r dlopen"
 hqdn3d_filter_deps="gpl"
 movie_filter_deps="avcodec avformat"
 mp_filter_deps="gpl avcodec"
@@ -2939,7 +2935,6 @@ check_func  ${malloc_prefix}posix_memalign      && enable posix_memalign
 check_func  setrlimit
 check_func  strerror_r
 check_func  strptime
-check_func  strtok_r
 check_func_headers conio.h kbhit
 check_func_headers windows.h PeekNamedPipe
 check_func_headers io.h setmode
diff --git a/libavfilter/af_aconvert.c b/libavfilter/af_aconvert.c
index d794c23..c28d16a 100644
--- a/libavfilter/af_aconvert.c
+++ b/libavfilter/af_aconvert.c
@@ -28,6 +28,7 @@
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
 #include "libavcodec/audioconvert.h"
 #include "avfilter.h"
 #include "internal.h"
@@ -125,15 +126,15 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
     aconvert->out_chlayout    = 0;
     aconvert->out_packing_fmt = -1;
 
-    if ((arg = strtok_r(args, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok_r(args, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_sample_format(&aconvert->out_sample_fmt, arg, ctx)) < 0)
             goto end;
     }
-    if ((arg = strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_channel_layout(&aconvert->out_chlayout, arg, ctx)) < 0)
             goto end;
     }
-    if ((arg = strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
+    if ((arg = av_strtok_r(NULL, ":", &ptr)) && strcmp(arg, "auto")) {
         if ((ret = ff_parse_packing_format((int *)&aconvert->out_packing_fmt, arg, ctx)) < 0)
             goto end;
     }
diff --git a/libavfilter/af_aformat.c b/libavfilter/af_aformat.c
index a7aa45f..28cbd10 100644
--- a/libavfilter/af_aformat.c
+++ b/libavfilter/af_aformat.c
@@ -50,7 +50,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
         aformat->fmts_list = all_formats;                               \
     } else {                                                            \
         for (fmt_str = fmts_str;                                        \
-             fmt_str = strtok_r(fmt_str, ",", &ptr); fmt_str = NULL) {  \
+             fmt_str = av_strtok_r(fmt_str, ",", &ptr); fmt_str = NULL) {  \
             if ((ret = ff_parse_##fmt_name((fmt_type *)&fmt,            \
                                            fmt_str, ctx)) < 0) {        \
                 av_freep(&fmts_str);                                    \
diff --git a/libavfilter/asrc_abuffer.c b/libavfilter/asrc_abuffer.c
index 4a0f08e..28b7fe5 100644
--- a/libavfilter/asrc_abuffer.c
+++ b/libavfilter/asrc_abuffer.c
@@ -25,6 +25,7 @@
  */
 
 #include "libavutil/audioconvert.h"
+#include "libavutil/avstring.h"
 #include "libavutil/fifo.h"
 #include "asrc_abuffer.h"
 #include "internal.h"
@@ -256,7 +257,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
     char *args = av_strdup(args0);
     int ret;
 
-    arg = strtok_r(args, ":", &ptr);
+    arg = av_strtok_r(args, ":", &ptr);
 
 #define ADD_FORMAT(fmt_name)                                            \
     if (!arg)                                                           \
@@ -266,7 +267,7 @@ static av_cold int init(AVFilterContext *ctx, const char *args0, void *opaque)
         return ret;                                                     \
     }                                                                   \
     if (*args)                                                          \
-        arg = strtok_r(NULL, ":", &ptr)
+        arg = av_strtok_r(NULL, ":", &ptr)
 
     ADD_FORMAT(sample_rate);
     ADD_FORMAT(sample_format);
diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c
index f5b7abb..71e386c 100644
--- a/libavfilter/vf_frei0r.c
+++ b/libavfilter/vf_frei0r.c
@@ -216,7 +216,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
     /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
     if ((path = av_strdup(getenv("FREI0R_PATH")))) {
         char *p, *ptr = NULL;
-        for (p = path; p = strtok_r(p, ":", &ptr); p = NULL)
+        for (p = path; p = av_strtok_r(p, ":", &ptr); p = NULL)
             if (frei0r->dl_handle = load_path(ctx, p, dl_name))
                 break;
         av_free(path);
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 4cebbe0..1eb191f 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -160,6 +160,48 @@ char *av_get_token(const char **buf, const char *term)
     return ret;
 }
 
+char *av_strtok_r(char *s, const char *delim, char **last)
+{
+    const char *spanp;
+    int c, sc;
+    char *tok;
+
+    if (!s && !(s = *last))
+        return NULL;
+
+    /* Skip (span) leading delimiters (s += strspn(s, delim), sort of)*/
+cont:
+    c = *s++;
+    for (spanp =  delim; (sc = *spanp++) != 0;) {
+        if (c == sc)
+            goto cont;
+    }
+
+    if (c == 0) {		/* no non-delimiter characters */
+        *last = NULL;
+        return NULL;
+    }
+    tok = s - 1;
+
+    /* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+     * Note that delim must have one NUL; we stop if we see that, too. */
+    while (1) {
+        c = *s++;
+        spanp = delim;
+        do {
+            if ((sc = *spanp++) == c) {
+                if (c == 0)
+                    s = NULL;
+                else
+                    s[-1] = 0;
+                *last = s;
+                return tok;
+            }
+        } while (sc != 0);
+    }
+    /* NOTREACHED */
+}
+
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index 2be84a9..c9fc604 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -141,4 +141,22 @@ char *av_d2str(double d);
  */
 char *av_get_token(const char **buf, const char *term);
 
+/**
+ * Split the string into several tokens which can be accessed by
+ * successive calls to av_strtok_r().
+ *
+ * A token is a sequence of characters not belonging to the set
+ * specified in delim.
+ *
+ * @param s the string to parse, may be NULL
+ * @param delim 0-terminated list of token delimiters
+ * @param last pointer which is updated to point to the next token
+ * found in s, or to NULL if the string does not contain a following
+ * token. The pointed value has to be provided to the next call to
+ * av_strtok_r().
+ * @return the found token, or NULL if the provided string does not
+ * contain any token
+ */
+char *av_strtok_r(char *s, const char *delim, char **last);
+
 #endif /* AVUTIL_AVSTRING_H */
-- 
1.7.4.1



More information about the ffmpeg-devel mailing list