aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Uoti Urpala <uau@mplayer2.org>2011-07-28 11:07:47 +0300
committerGravatar Uoti Urpala <uau@mplayer2.org>2011-07-29 05:50:38 +0300
commite873d703e956d3e2e68b9e18562983b029b5c7a8 (patch)
tree44a2c48ae4e94bd580ffd5833cd71a037af36043
parentd8374376c0d46ffab88b96eb32b52621c34f562c (diff)
options: change option parsing to use bstr
Using bstr allows simpler parsing code, especially because it avoids the need to modify or copy strings just to terminate extracted substrings.
-rw-r--r--bstr.c49
-rw-r--r--bstr.h57
-rw-r--r--command.c3
-rw-r--r--libmenu/menu.c3
-rw-r--r--libmpcodecs/vf.c2
-rw-r--r--m_config.c75
-rw-r--r--m_config.h29
-rw-r--r--m_option.c1093
-rw-r--r--m_option.h18
-rw-r--r--m_property.c3
-rw-r--r--m_struct.c11
-rw-r--r--m_struct.h6
-rw-r--r--osdep/macosx_finder_args.c2
-rw-r--r--parser-cfg.c2
-rw-r--r--parser-mpcmd.c16
-rw-r--r--playtree.c4
-rw-r--r--stream/stream.c2
17 files changed, 685 insertions, 690 deletions
diff --git a/bstr.c b/bstr.c
index 2b40be399c..a2a49cc371 100644
--- a/bstr.c
+++ b/bstr.c
@@ -20,6 +20,7 @@
#include <libavutil/avutil.h>
#include <assert.h>
#include <ctype.h>
+#include <stdarg.h>
#include "talloc.h"
@@ -71,6 +72,15 @@ int bstrrchr(struct bstr str, int c)
return -1;
}
+int bstrcspn(struct bstr str, const char *reject)
+{
+ int i;
+ for (i = 0; i < str.len; i++)
+ if (strchr(reject, str.start[i]))
+ break;
+ return i;
+}
+
int bstr_find(struct bstr haystack, struct bstr needle)
{
for (int i = 0; i < haystack.len; i++)
@@ -96,21 +106,18 @@ struct bstr bstr_strip(struct bstr str)
return str;
}
-struct bstr bstr_split(struct bstr str, char *sep, struct bstr *rest)
+struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest)
{
- int start, end;
+ int start;
for (start = 0; start < str.len; start++)
if (!strchr(sep, str.start[start]))
break;
- for (end = start; end < str.len; end++)
- if (strchr(sep, str.start[end]))
- break;
+ str = bstr_cut(str, start);
+ int end = bstrcspn(str, sep);
if (rest) {
*rest = bstr_cut(str, end);
}
- str.start += start;
- str.len = end - start;
- return str;
+ return bstr_splice(str, 0, end);
}
@@ -131,6 +138,7 @@ struct bstr bstr_splice(struct bstr str, int start, int end)
long long bstrtoll(struct bstr str, struct bstr *rest, int base)
{
+ str = bstr_lstrip(str);
char buf[51];
int len = FFMIN(str.len, 50);
memcpy(buf, str.start, len);
@@ -142,6 +150,20 @@ long long bstrtoll(struct bstr str, struct bstr *rest, int base)
return r;
}
+double bstrtod(struct bstr str, struct bstr *rest)
+{
+ str = bstr_lstrip(str);
+ char buf[101];
+ int len = FFMIN(str.len, 100);
+ memcpy(buf, str.start, len);
+ buf[len] = 0;
+ char *endptr;
+ double r = strtod(buf, &endptr);
+ if (rest)
+ *rest = bstr_cut(str, endptr - buf);
+ return r;
+}
+
struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str)
{
if (str.len == 0)
@@ -169,3 +191,14 @@ void bstr_lower(struct bstr str)
for (int i = 0; i < str.len; i++)
str.start[i] = tolower(str.start[i]);
}
+
+int bstr_sscanf(struct bstr str, const char *format, ...)
+{
+ char *ptr = bstrdup0(NULL, str);
+ va_list va;
+ va_start(va, format);
+ int ret = vsscanf(ptr, format, va);
+ va_end(va);
+ talloc_free(ptr);
+ return ret;
+}
diff --git a/bstr.h b/bstr.h
index 1d26cb2728..1344f0d443 100644
--- a/bstr.h
+++ b/bstr.h
@@ -34,22 +34,45 @@ struct bstr {
size_t len;
};
+// demux_rtp.cpp (live555) C++ compilation workaround
+#ifndef __cplusplus
+static inline char *bstrdup0(void *talloc_ctx, struct bstr str)
+{
+ return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
+}
+
+static inline struct bstr bstrdup(void *talloc_ctx, struct bstr str)
+{
+ struct bstr r = { talloc_strndup(talloc_ctx, str.start, str.len), str.len };
+ return r;
+}
+
+static inline struct bstr bstr(const unsigned char *s)
+{
+ return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
+}
+
int bstrcmp(struct bstr str1, struct bstr str2);
int bstrcasecmp(struct bstr str1, struct bstr str2);
int bstrchr(struct bstr str, int c);
int bstrrchr(struct bstr str, int c);
+int bstrcspn(struct bstr str, const char *reject);
int bstr_find(struct bstr haystack, struct bstr needle);
struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str);
struct bstr bstr_lstrip(struct bstr str);
struct bstr bstr_strip(struct bstr str);
-struct bstr bstr_split(struct bstr str, char *sep, struct bstr *rest);
+struct bstr bstr_split(struct bstr str, const char *sep, struct bstr *rest);
struct bstr bstr_splice(struct bstr str, int start, int end);
long long bstrtoll(struct bstr str, struct bstr *rest, int base);
+double bstrtod(struct bstr str, struct bstr *rest);
void bstr_lower(struct bstr str);
+int bstr_sscanf(struct bstr str, const char *format, ...);
static inline struct bstr bstr_cut(struct bstr str, int n)
{
+ if (n > str.len)
+ n = str.len;
return (struct bstr){str.start + n, str.len - n};
}
@@ -60,22 +83,36 @@ static inline bool bstr_startswith(struct bstr str, struct bstr prefix)
return !memcmp(str.start, prefix.start, prefix.len);
}
-// demux_rtp.cpp (live555) C++ compilation workaround
-#ifndef __cplusplus
-static inline char *bstrdup0(void *talloc_ctx, struct bstr str)
+static inline bool bstr_startswith0(struct bstr str, const char *prefix)
{
- return talloc_strndup(talloc_ctx, (char *)str.start, str.len);
+ return bstr_startswith(str, bstr(prefix));
}
-static inline struct bstr bstrdup(void *talloc_ctx, struct bstr str)
+static inline bool bstr_endswith(struct bstr str, struct bstr suffix)
{
- struct bstr r = { talloc_strndup(talloc_ctx, str.start, str.len), str.len };
- return r;
+ if (str.len < suffix.len)
+ return false;
+ return !memcmp(str.start + str.len - suffix.len, suffix.start, suffix.len);
}
-static inline struct bstr bstr(const unsigned char *s)
+static inline bool bstr_endswith0(struct bstr str, const char *suffix)
{
- return (struct bstr){(unsigned char *)s, s ? strlen(s) : 0};
+ return bstr_endswith(str, bstr(suffix));
+}
+
+static inline int bstrcmp0(struct bstr str1, const char *str2)
+{
+ return bstrcmp(str1, bstr(str2));
+}
+
+static inline int bstrcasecmp0(struct bstr str1, const char *str2)
+{
+ return bstrcasecmp(str1, bstr(str2));
+}
+
+static inline int bstr_find0(struct bstr haystack, const char *needle)
+{
+ return bstr_find(haystack, bstr(needle));
}
#endif
diff --git a/command.c b/command.c
index fda7c25626..4b502b3cc9 100644
--- a/command.c
+++ b/command.c
@@ -232,7 +232,8 @@ static int mp_property_generic_option(struct m_option *prop, int action,
void *arg, MPContext *mpctx)
{
char *optname = prop->priv;
- const struct m_option *opt = m_config_get_option(mpctx->mconfig, optname);
+ const struct m_option *opt = m_config_get_option(mpctx->mconfig,
+ bstr(optname));
void *valptr = m_option_get_ptr(opt, &mpctx->opts);
switch (action) {
diff --git a/libmenu/menu.c b/libmenu/menu.c
index 0f920825b0..3e003900ce 100644
--- a/libmenu/menu.c
+++ b/libmenu/menu.c
@@ -208,7 +208,8 @@ static int menu_parse_config(char* buffer, struct m_config *mconfig)
// Setup the attribs
for(i = 0 ; attribs[2*i] ; i++) {
if(strcasecmp(attribs[2*i],"name") == 0) continue;
- if(!m_struct_set(&minfo->priv_st,menu_list[menu_count].cfg,attribs[2*i], attribs[2*i+1]))
+ if (!m_struct_set(&minfo->priv_st, menu_list[menu_count].cfg,
+ attribs[2*i], bstr(attribs[2*i+1])))
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] bad attribute %s=%s in menu '%s' at line %d\n",attribs[2*i],attribs[2*i+1],
name,parser->line);
}
diff --git a/libmpcodecs/vf.c b/libmpcodecs/vf.c
index bb9ebff7b4..7c84a49ef0 100644
--- a/libmpcodecs/vf.c
+++ b/libmpcodecs/vf.c
@@ -455,7 +455,7 @@ struct vf_instance *vf_open_plugin_noerr(struct MPOpts *opts,
void* vf_priv = m_struct_alloc(st);
int n;
for(n = 0 ; args && args[2*n] ; n++)
- m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
+ m_struct_set(st, vf_priv, args[2*n], bstr(args[2*n+1]));
vf->priv = vf_priv;
args = NULL;
} else // Otherwise we should have the '_oldargs_'
diff --git a/m_config.c b/m_config.c
index b278877c3c..3cf8c721ac 100644
--- a/m_config.c
+++ b/m_config.c
@@ -36,13 +36,13 @@
#define MAX_PROFILE_DEPTH 20
-static int parse_profile(const struct m_option *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_profile(const struct m_option *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
struct m_config *config = opt->priv;
char **list = NULL;
int i, r;
- if (param && !strcmp(param, "help")) {
+ if (!bstrcmp0(param, "help")) {
struct m_profile *p;
if (!config->profiles) {
mp_tmsg(MSGT_CFGPARSER, MSGL_INFO,
@@ -387,36 +387,37 @@ int m_config_register_options(struct m_config *config,
}
static struct m_config_option *m_config_get_co(const struct m_config *config,
- char *arg)
+ struct bstr name)
{
struct m_config_option *co;
for (co = config->opts; co; co = co->next) {
- int l = strlen(co->name) - 1;
- if ((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) &&
- (co->name[l] == '*')) {
- if (strncasecmp(co->name, arg, l) == 0)
+ struct bstr coname = bstr(co->name);
+ if ((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD)
+ && bstr_endswith0(coname, "*")) {
+ coname.len--;
+ if (bstrcasecmp(bstr_splice(name, 0, coname.len), coname) == 0)
return co;
- } else if (strcasecmp(co->name, arg) == 0)
+ } else if (bstrcasecmp(coname, name) == 0)
return co;
}
return NULL;
}
-static int m_config_parse_option(const struct m_config *config, char *arg,
- char *param, bool ambiguous_param, bool set)
+static int m_config_parse_option(const struct m_config *config,
+ struct bstr name, struct bstr param,
+ bool ambiguous_param, bool set)
{
struct m_config_option *co;
int r = 0;
assert(config != NULL);
assert(config->lvl > 0);
- assert(arg != NULL);
+ assert(name.len != 0);
- co = m_config_get_co(config, arg);
- if (!co) {
+ co = m_config_get_co(config, name);
+ if (!co)
return M_OPT_UNKNOWN;
- }
// This is the only mandatory function
assert(co->opt->type->parse);
@@ -424,12 +425,14 @@ static int m_config_parse_option(const struct m_config *config, char *arg,
// Check if this option isn't forbidden in the current mode
if ((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option can't be used in a config file.\n", arg);
+ "The %.*s option can't be used in a config file.\n",
+ BSTR_P(name));
return M_OPT_INVALID;
}
if ((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option can't be used on the command line.\n", arg);
+ "The %.*s option can't be used on the command line.\n",
+ BSTR_P(name));
return M_OPT_INVALID;
}
// During command line preparse set only pre-parse options
@@ -445,7 +448,7 @@ static int m_config_parse_option(const struct m_config *config, char *arg,
char **lst = NULL;
int i, sr;
// Parse the child options
- r = m_option_parse(co->opt, arg, param, false, &lst);
+ r = m_option_parse(co->opt, name, param, false, &lst);
// Set them now
if (r >= 0)
for (i = 0; lst && lst[2 * i]; i++) {
@@ -454,8 +457,9 @@ static int m_config_parse_option(const struct m_config *config, char *arg,
// Build the full name
char n[l];
sprintf(n, "%s:%s", co->name, lst[2 * i]);
- sr = m_config_parse_option(config, n, lst[2 * i + 1],
- false, set);
+ sr = m_config_parse_option(config, bstr(n),
+ bstr(lst[2 * i + 1]), false,
+ set);
if (sr < 0) {
if (sr == M_OPT_UNKNOWN) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
@@ -476,7 +480,7 @@ static int m_config_parse_option(const struct m_config *config, char *arg,
}
talloc_free(lst);
} else
- r = m_option_parse(co->opt, arg, param, ambiguous_param,
+ r = m_option_parse(co->opt, name, param, ambiguous_param,
set ? co->slots->data : NULL);
// Parsing failed ?
@@ -491,22 +495,24 @@ static int m_config_parse_option(const struct m_config *config, char *arg,
return r;
}
-int m_config_set_option(struct m_config *config, char *arg,
- char *param, bool ambiguous_param)
+int m_config_set_option(struct m_config *config, struct bstr name,
+ struct bstr param, bool ambiguous_param)
{
- mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting %s=%s\n", arg, param);
- return m_config_parse_option(config, arg, param, ambiguous_param, 1);
+ mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting %.*s=%.*s\n", BSTR_P(name),
+ BSTR_P(param));
+ return m_config_parse_option(config, name, param, ambiguous_param, 1);
}
-int m_config_check_option(const struct m_config *config, char *arg,
- char *param, bool ambiguous_param)
+int m_config_check_option(const struct m_config *config, struct bstr name,
+ struct bstr param, bool ambiguous_param)
{
int r;
- mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Checking %s=%s\n", arg, param);
- r = m_config_parse_option(config, arg, param, ambiguous_param, 0);
+ mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Checking %.*s=%.*s\n", BSTR_P(name),
+ BSTR_P(param));
+ r = m_config_parse_option(config, name, param, ambiguous_param, 0);
if (r == M_OPT_MISSING_PARAM) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "Error: option '%s' must have a parameter!\n", arg);
+ "Error: option '%.*s' must have a parameter!\n", BSTR_P(name));
return M_OPT_INVALID;
}
return r;
@@ -514,15 +520,14 @@ int m_config_check_option(const struct m_config *config, char *arg,
const struct m_option *m_config_get_option(const struct m_config *config,
- char *arg)
+ struct bstr name)
{
struct m_config_option *co;
assert(config != NULL);
assert(config->lvl > 0);
- assert(arg != NULL);
- co = m_config_get_co(config, arg);
+ co = m_config_get_co(config, name);
if (co)
return co->opt;
else
@@ -597,7 +602,7 @@ void m_profile_set_desc(struct m_profile *p, char *desc)
int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
char *name, char *val)
{
- int i = m_config_check_option(config, name, val, false);
+ int i = m_config_check_option0(config, name, val, false);
if (i < 0)
return i;
p->opts = talloc_realloc(p, p->opts, char *, 2 * (p->num_opts + 2));
@@ -620,7 +625,7 @@ void m_config_set_profile(struct m_config *config, struct m_profile *p)
config->mode = M_CONFIG_FILE;
config->profile_depth++;
for (i = 0; i < p->num_opts; i++)
- m_config_set_option(config, p->opts[2 * i], p->opts[2 * i + 1], false);
+ m_config_set_option0(config, p->opts[2 * i], p->opts[2 * i + 1], false);
config->profile_depth--;
config->mode = prev_mode;
}
diff --git a/m_config.h b/m_config.h
index d2c3b9ee4e..75dd85ac14 100644
--- a/m_config.h
+++ b/m_config.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
+#include "bstr.h"
// m_config provides an API to manipulate the config variables in MPlayer.
// It makes use of the Options API to provide a context stack that
@@ -129,28 +130,42 @@ int m_config_register_options(struct m_config *config,
/* Set an option.
* \param config The config object.
- * \param arg The option's name.
+ * \param name The option's name.
* \param param The value of the option, can be NULL.
* \param ambiguous_param: old style cmdline option, "param" may be a
parameter to this option or something entirely unrelated
* \return See \ref OptionParserReturn.
*/
-int m_config_set_option(struct m_config *config, char *arg,
- char *param, bool ambiguous_param);
+int m_config_set_option(struct m_config *config, struct bstr name,
+ struct bstr param, bool ambiguous_param);
+
+static inline int m_config_set_option0(struct m_config *config,
+ const char *name, const char *param,
+ bool ambiguous)
+{
+ return m_config_set_option(config, bstr(name), bstr(param), ambiguous);
+}
/* Check if an option setting is valid.
* Same as above m_config_set_option() but doesn't actually set anything.
*/
-int m_config_check_option(const struct m_config *config, char *arg,
- char *param, bool ambiguous_param);
+int m_config_check_option(const struct m_config *config, struct bstr name,
+ struct bstr param, bool ambiguous_param);
+
+static inline int m_config_check_option0(struct m_config *config,
+ const char *name, const char *param,
+ bool ambiguous)
+{
+ return m_config_check_option(config, bstr(name), bstr(param), ambiguous);
+}
/* Get the option matching the given name.
* \param config The config object.
- * \param arg The option's name.
+ * \param name The option's name.
*/
const struct m_option *m_config_get_option(const struct m_config *config,
- char *arg);
+ struct bstr name);
/* Print a list of all registered options.
* \param config The config object.
diff --git a/m_option.c b/m_option.c
index a1cc139f8d..64a06d8971 100644
--- a/m_option.c
+++ b/m_option.c
@@ -28,6 +28,7 @@
#include <stdarg.h>
#include <inttypes.h>
#include <unistd.h>
+#include <assert.h>
#include "talloc.h"
#include "m_option.h"
@@ -35,22 +36,27 @@
#include "stream/url.h"
#include "libavutil/avstring.h"
-const m_option_t *m_option_list_find(const m_option_t *list, const char *name)
+static const struct m_option *m_option_list_findb(const struct m_option *list,
+ struct bstr name)
{
- int i;
-
- for (i = 0; list[i].name; i++) {
- int l = strlen(list[i].name) - 1;
+ for (int i = 0; list[i].name; i++) {
+ struct bstr lname = bstr(list[i].name);
if ((list[i].type->flags & M_OPT_TYPE_ALLOW_WILDCARD)
- && (l > 0) && (list[i].name[l] == '*')) {
- if (strncasecmp(list[i].name, name, l) == 0)
+ && bstr_endswith0(lname, "*")) {
+ lname.len--;
+ if (bstrcasecmp(bstr_splice(name, 0, lname.len), lname) == 0)
return &list[i];
- } else if (strcasecmp(list[i].name, name) == 0)
+ } else if (bstrcasecmp(lname, name) == 0)
return &list[i];
}
return NULL;
}
+const m_option_t *m_option_list_find(const m_option_t *list, const char *name)
+{
+ return m_option_list_findb(list, bstr(name));
+}
+
// Default function that just does a memcpy
static void copy_opt(const m_option_t *opt, void *dst, const void *src)
@@ -63,42 +69,32 @@ static void copy_opt(const m_option_t *opt, void *dst, const void *src)
#define VAL(x) (*(int *)(x))
-static int parse_flag(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_flag(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- if (param && !ambiguous_param) {
- if (!strcasecmp(param, "yes") || /* any other language? */
- !strcasecmp(param, "on") ||
- !strcasecmp(param, "ja") ||
- !strcasecmp(param, "si") ||
- !strcasecmp(param, "igen") ||
- !strcasecmp(param, "y") ||
- !strcasecmp(param, "j") ||
- !strcasecmp(param, "i") ||
- !strcasecmp(param, "tak") ||
- !strcasecmp(param, "ja") ||
- !strcasecmp(param, "true") ||
- !strcmp(param, "1")) {
- if (dst)
- VAL(dst) = opt->max;
- } else if (!strcasecmp(param, "no") ||
- !strcasecmp(param, "off") ||
- !strcasecmp(param, "nein") ||
- !strcasecmp(param, "nicht") ||
- !strcasecmp(param, "nem") ||
- !strcasecmp(param, "n") ||
- !strcasecmp(param, "nie") ||
- !strcasecmp(param, "nej") ||
- !strcasecmp(param, "false") ||
- !strcmp(param, "0")) {
- if (dst)
- VAL(dst) = opt->min;
- } else {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Invalid parameter for %s flag: %s\n", name, param);
- return M_OPT_INVALID;
+ if (param.len && !ambiguous_param) {
+ char * const enable[] = { "yes", "on", "ja", "si", "igen", "y", "j",
+ "i", "tak", "ja", "true", "1" };
+ for (int i = 0; i < sizeof(enable) / sizeof(enable[0]); i++) {
+ if (!bstrcasecmp0(param, enable[i])) {
+ if (dst)
+ VAL(dst) = opt->max;
+ return 1;
+ }
}
- return 1;
+ char * const disable[] = { "no", "off", "nein", "nicht", "nem", "n",
+ "nie", "nej", "false", "0" };
+ for (int i = 0; i < sizeof(disable) / sizeof(disable[0]); i++) {
+ if (!bstrcasecmp0(param, disable[i])) {
+ if (dst)
+ VAL(dst) = opt->min;
+ return 1;
+ }
+ }
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Invalid parameter for %.*s flag: %.*s\n",
+ BSTR_P(name), BSTR_P(param));
+ return M_OPT_INVALID;
} else {
if (dst)
VAL(dst) = opt->max;
@@ -129,48 +125,64 @@ const m_option_type_t m_option_type_flag = {
// Integer
-static int parse_int(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_longlong(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- long long tmp_int;
- char *endptr;
-
- if (param == NULL)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- tmp_int = strtoll(param, &endptr, 10);
- if (*endptr)
- tmp_int = strtoll(param, &endptr, 0);
- if (*endptr) {
+ struct bstr rest;
+ long long tmp_int = bstrtoll(param, &rest, 10);
+ if (rest.len)
+ tmp_int = bstrtoll(param, &rest, 0);
+ if (rest.len) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be an integer: %s\n", name, param);
+ "The %.*s option must be an integer: %.*s\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
if ((opt->flags & M_OPT_MIN) && (tmp_int < opt->min)) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be >= %d: %s\n",
- name, (int) opt->min, param);
+ "The %.*s option must be >= %d: %.*s\n",
+ BSTR_P(name), (int) opt->min, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if ((opt->flags & M_OPT_MAX) && (tmp_int > opt->max)) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be <= %d: %s\n",
- name, (int) opt->max, param);
+ "The %.*s option must be <= %d: %.*s\n",
+ BSTR_P(name), (int) opt->max, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
- if (dst) {
- if (opt->type->size == sizeof(int64_t))
- *(int64_t *)dst = tmp_int;
- else
- VAL(dst) = tmp_int;
- }
+ if (dst)
+ *(long long *)dst = tmp_int;
return 1;
}
+static int parse_int(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
+{
+ long long tmp;
+ int r = parse_longlong(opt, name, param, false, &tmp);
+ if (r >= 0 && dst)
+ *(int *)dst = tmp;
+ return r;
+}
+
+static int parse_int64(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
+{
+ long long tmp;
+ int r = parse_longlong(opt, name, param, false, &tmp);
+ if (r >= 0 && dst)
+ *(int64_t *)dst = tmp;
+ return r;
+}
+
+
static char *print_int(const m_option_t *opt, const void *val)
{
if (opt->type->size == sizeof(int64_t))
@@ -196,7 +208,7 @@ const m_option_type_t m_option_type_int64 = {
"",
sizeof(int64_t),
0,
- parse_int,
+ parse_int64,
print_int,
copy_opt,
copy_opt,
@@ -204,28 +216,25 @@ const m_option_type_t m_option_type_int64 = {
NULL
};
-static int parse_intpair(const struct m_option *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_intpair(const struct m_option *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- if (param == NULL)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- char *s = (char *)param;
- int start = -1;
+ struct bstr s = param;
int end = -1;
- if (*s) {
- start = strtol(s, &s, 10);
- if (s == param)
- goto bad;
- }
- if (*s) {
- if (*s != '-')
+ int start = bstrtoll(s, &s, 10);
+ if (s.len == param.len)
+ goto bad;
+ if (s.len > 0) {
+ if (!bstr_startswith0(s, "-"))
goto bad;
- s++;
+ s = bstr_cut(s, 1);
}
- if (*s)
- end = strtol(s, &s, 10);
- if (*s)
+ if (s.len > 0)
+ end = bstrtoll(s, &s, 10);
+ if (s.len > 0)
goto bad;
if (dst) {
@@ -238,7 +247,8 @@ static int parse_intpair(const struct m_option *opt, const char *name,
bad:
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid integer range "
- "specification for option %s: %s\n", name, param);
+ "specification for option %.*s: %.*s\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
@@ -250,19 +260,20 @@ const struct m_option_type m_option_type_intpair = {
.set = copy_opt,
};
-static int parse_choice(const struct m_option *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_choice(const struct m_option *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- if (param == NULL)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
struct m_opt_choice_alternatives *alt;
for (alt = opt->priv; alt->name; alt++)
- if (!strcmp(param, alt->name))
+ if (!bstrcmp0(param, alt->name))
break;
if (!alt->name) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Invalid value for option %s: %s\n",
- name, param);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Invalid value for option %.*s: %.*s\n",
+ BSTR_P(name), BSTR_P(param));
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Valid values are:");
for (alt = opt->priv; alt->name; alt++)
mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s", alt->name);
@@ -299,54 +310,54 @@ const struct m_option_type m_option_type_choice = {
#undef VAL
#define VAL(x) (*(double *)(x))
-static int parse_double(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_double(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- double tmp_float;
- char *endptr;
-
- if (param == NULL)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- tmp_float = strtod(param, &endptr);
+ struct bstr rest;
+ double tmp_float = bstrtod(param, &rest);
- switch (*endptr) {
+ switch (rest.len ? rest.start[0] : 0) {
case ':':
case '/':
- tmp_float /= strtod(endptr + 1, &endptr);
+ tmp_float /= bstrtod(bstr_cut(rest, 1), &rest);
break;
case '.':
case ',':
/* we also handle floats specified with
* non-locale decimal point ::atmos
*/
+ rest = bstr_cut(rest, 1);
if (tmp_float < 0)
- tmp_float -= 1.0 / pow(10, strlen(endptr + 1)) *
- strtod(endptr + 1, &endptr);
+ tmp_float -= 1.0 / pow(10, rest.len) * bstrtod(rest, &rest);
else
- tmp_float += 1.0 / pow(10, strlen(endptr + 1)) *
- strtod(endptr + 1, &endptr);
+ tmp_float += 1.0 / pow(10, rest.len) * bstrtod(rest, &rest);
break;
}
- if (*endptr) {
+ if (rest.len) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be a floating point number or a "
- "ratio (numerator[:/]denominator): %s\n", name, param);
+ "The %.*s option must be a floating point number or a "
+ "ratio (numerator[:/]denominator): %.*s\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
if (opt->flags & M_OPT_MIN)
if (tmp_float < opt->min) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be >= %f: %s\n", name, opt->min, param);
+ "The %.*s option must be >= %f: %.*s\n",
+ BSTR_P(name), opt->min, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if (opt->flags & M_OPT_MAX)
if (tmp_float > opt->max) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be <= %f: %s\n", name, opt->max, param);
+ "The %.*s option must be <= %f: %.*s\n",
+ BSTR_P(name), opt->max, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
@@ -377,8 +388,8 @@ const m_option_type_t m_option_type_double = {
#undef VAL
#define VAL(x) (*(float *)(x))
-static int parse_float(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_float(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
double tmp;
int r = parse_double(opt, name, param, false, &tmp);
@@ -410,40 +421,14 @@ const m_option_type_t m_option_type_float = {
#undef VAL
#define VAL(x) (*(off_t *)(x))
-static int parse_position(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_position(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- off_t tmp_off;
- char dummy;
-
- if (param == NULL)
- return M_OPT_MISSING_PARAM;
- if (sscanf(param, sizeof(off_t) == sizeof(int) ?
- "%d%c" : "%"PRId64"%c", &tmp_off, &dummy) != 1) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be an integer: %s\n", opt->name, param);
- return M_OPT_INVALID;
- }
-
- if (opt->flags & M_OPT_MIN)
- if (tmp_off < opt->min) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be >= %"PRId64 ": %s\n",
- name, (int64_t) opt->min, param);
- return M_OPT_OUT_OF_RANGE;
- }
-
- if (opt->flags & M_OPT_MAX)
- if (tmp_off > opt->max) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "The %s option must be <= %"PRId64 ": %s\n",
- name, (int64_t) opt->max, param);
- return M_OPT_OUT_OF_RANGE;
- }
-
- if (dst)
- VAL(dst) = tmp_off;
- return 1;
+ long long tmp;
+ int r = parse_longlong(opt, name, param, false, &tmp);
+ if (r >= 0 && dst)
+ *(off_t *)dst = tmp;
+ return r;
}
static char *print_position(const m_option_t *opt, const void *val)
@@ -470,29 +455,26 @@ const m_option_type_t m_option_type_position = {
#undef VAL
#define VAL(x) (*(char **)(x))
-static int parse_str(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_str(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
-
-
- if (param == NULL)
- return M_OPT_MISSING_PARAM;
-
- if ((opt->flags & M_OPT_MIN) && (strlen(param) < opt->min)) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Parameter must be >= %d chars: %s\n",
- (int) opt->min, param);
+ if ((opt->flags & M_OPT_MIN) && (param.len < opt->min)) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Parameter must be >= %d chars: %.*s\n",
+ (int) opt->min, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
- if ((opt->flags & M_OPT_MAX) && (strlen(param) > opt->max)) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Parameter must be <= %d chars: %s\n",
- (int) opt->max, param);
+ if ((opt->flags & M_OPT_MAX) && (param.len > opt->max)) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Parameter must be <= %d chars: %.*s\n",
+ (int) opt->max, BSTR_P(param));
return M_OPT_OUT_OF_RANGE;
}
if (dst) {
talloc_free(VAL(dst));
- VAL(dst) = talloc_strdup(NULL, param);
+ VAL(dst) = bstrdup0(NULL, param);
}
return 1;
@@ -640,39 +622,43 @@ static int str_list_del(char **del, int n, void *dst)
return 1;
}
-static char *get_nextsep(char *ptr, char sep, int modify)
+static struct bstr get_nextsep(struct bstr *ptr, char sep, bool modify)
{
- char *last_ptr = ptr;
+ struct bstr str = *ptr;
+ struct bstr orig = str;
for (;;) {
- ptr = strchr(ptr, sep);
- if (ptr && ptr > last_ptr && ptr[-1] == '\\') {
- if (modify)
- memmove(ptr - 1, ptr, strlen(ptr) + 1);
- else
- ptr++;
- } else
+ int idx = bstrchr(str, sep);
+ if (idx > 0 && str.start[idx - 1] == '\\') {
+ if (modify) {
+ memmove(str.start + idx - 1, str.start + idx, str.len - idx);
+ str.len--;
+ str = bstr_cut(str, idx);
+ } else
+ str = bstr_cut(str, idx + 1);
+ } else {
+ str = bstr_cut(str, idx < 0 ? str.len : idx);
break;
+ }
}
- return ptr;
+ *ptr = str;
+ return bstr_splice(orig, 0, str.start - orig.start);
}
-static int parse_str_list(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_str_list(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- int n = 0, len = strlen(opt->name);
- char *str;
- char *ptr = (char *)param, *last_ptr, **res;
+ char **res;
int op = OP_NONE;
-
- if (opt->name[len - 1] == '*' && ((int)strlen(name) > len - 1)) {
- const char *n = &name[len - 1];
- if (strcasecmp(n, "-add") == 0)
+ int len = strlen(opt->name);
+ if (opt->name[len - 1] == '*' && (name.len > len - 1)) {
+ struct bstr suffix = bstr_cut(name, len - 1);
+ if (bstrcasecmp0(suffix, "-add") == 0)
op = OP_ADD;
- else if (strcasecmp(n, "-pre") == 0)
+ else if (bstrcasecmp0(suffix, "-pre") == 0)
op = OP_PRE;
- else if (strcasecmp(n, "-del") == 0)
+ else if (bstrcasecmp0(suffix, "-del") == 0)
op = OP_DEL;
- else if (strcasecmp(n, "-clr") == 0)
+ else if (bstrcasecmp0(suffix, "-clr") == 0)
op = OP_CLR;
else
return M_OPT_UNKNOWN;
@@ -686,19 +672,17 @@ static int parse_str_list(const m_option_t *opt, const char *name,
}
// All other ops need a param
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
// custom type for "profile" calls this but uses ->priv for something else
char separator = opt->type == &m_option_type_string_list && opt->priv ?
*(char *)opt->priv : OPTION_LIST_SEPARATOR;
- while (ptr[0] != '\0') {
- ptr = get_nextsep(ptr, separator, 0);
- if (!ptr) {
- n++;
- break;
- }
- ptr++;
+ int n = 0;
+ struct bstr str = param;
+ while (str.len) {
+ get_nextsep(&str, separator, 0);
+ str = bstr_cut(str, 1);
n++;
}
if (n == 0)
@@ -711,24 +695,18 @@ static int parse_str_list(const m_option_t *opt, const char *name,
return 1;
res = talloc_array(NULL, char *, n + 2);
- ptr = str = talloc_strdup(NULL, param);
+ str = bstrdup(NULL, param);
+ char *ptr = str.start;
n = 0;
- while (1) {
- last_ptr = ptr;
- ptr = get_nextsep(ptr, separator, 1);
- if (!ptr) {
- res[n] = talloc_strdup(NULL, last_ptr);
- n++;
- break;
- }
- len = ptr - last_ptr;
- res[n] = talloc_strndup(NULL, last_ptr, len);
- ptr++;
+ while (str.len) {
+ struct bstr el = get_nextsep(&str, separator, 1);
+ res[n] = bstrdup0(NULL, el);
+ str = bstr_cut(str, 1);
n++;
}
res[n] = NULL;
- talloc_free(str);
+ talloc_free(ptr);
switch (op) {
case OP_ADD:
@@ -841,8 +819,8 @@ static void free_func_pf(void *src)
}
// Parser for func_param
-static int parse_func_pf(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_func_pf(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
struct m_func_save *s, *p;
@@ -850,8 +828,8 @@ static int parse_func_pf(const m_option_t *opt, const char *name,
return 1;
s = talloc_zero(NULL, struct m_func_save);
- s->name = talloc_strdup(NULL, name);
- s->param = talloc_strdup(NULL, param);
+ s->name = bstrdup0(NULL, name);
+ s->param = bstrdup0(NULL, param);
p = VAL(dst);
if (p) {
@@ -924,8 +902,8 @@ const m_option_type_t m_option_type_func_param = {
#undef VAL
-static int parse_func(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_func(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
return 0;
}
@@ -950,14 +928,19 @@ const m_option_type_t m_option_type_func = {
/////////////////// Print
-static int parse_print(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_print(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
if (opt->type == CONF_TYPE_PRINT_INDIRECT)
mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s", *(char **) opt->p);
- else if (opt->type == CONF_TYPE_PRINT_FUNC)
- return ((m_opt_func_full_t) opt->p)(opt, name, param);
- else
+ else if (opt->type == CONF_TYPE_PRINT_FUNC) {
+ char *name0 = bstrdup0(NULL, name);
+ char *param0 = bstrdup0(NULL, param);
+ int r = ((m_opt_func_full_t) opt->p)(opt, name0, param0);
+ talloc_free(name0);
+ talloc_free(param0);
+ return r;
+ } else
mp_msg(MSGT_CFGPARSER, MSGL_INFO, "%s", mp_gtext(opt->p));
if (opt->priv == NULL)
@@ -1009,102 +992,84 @@ const m_option_type_t m_option_type_print_func = {
#undef VAL
#define VAL(x) (*(char ***)(x))
-static int parse_subconf(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_subconf(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
- char *subparam;
- char *subopt;
- int nr = 0, i, r;
- const m_option_t *subopts;
- const char *p;
+ int nr = 0, i;
char **lst = NULL;
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- subparam = talloc_size(NULL, strlen(param) + 1);
- subopt = talloc_size(NULL, strlen(param) + 1);
- p = param;
-
- subopts = opt->p;
-
- while (p[0]) {
- int sscanf_ret = 1;
- int optlen = strcspn(p, ":=");
- /* clear out */
- subopt[0] = subparam[0] = 0;
- av_strlcpy(subopt, p, optlen + 1);
- p = &p[optlen];
- if (p[0] == '=') {
- sscanf_ret = 2;
- p = &p[1];
- if (p[0] == '"') {
- p = &p[1];
- optlen = strcspn(p, "\"");
- av_strlcpy(subparam, p, optlen + 1);
- p = &p[optlen];
- if (p[0] != '"') {
+ struct bstr p = param;
+ const struct m_option *subopts = opt->p;
+
+ while (p.len) {
+ int optlen = bstrcspn(p, ":=");
+ struct bstr subopt = bstr_splice(p, 0, optlen);
+ struct bstr subparam = bstr(NULL);
+ p = bstr_cut(p, optlen);
+ if (bstr_startswith0(p, "=")) {
+ p = bstr_cut(p, 1);
+ if (bstr_startswith0(p, "\"")) {
+ p = bstr_cut(p, 1);
+ optlen = bstrcspn(p, "\"");
+ subparam = bstr_splice(p, 0, optlen);
+ p = bstr_cut(p, optlen);
+ if (!bstr_startswith0(p, "\"")) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Terminating '\"' missing for '%s'\n", subopt);
+ "Terminating '\"' missing for '%.*s'\n",
+ BSTR_P(subopt));
return M_OPT_INVALID;
}
- p = &p[1];
- } else if (p[0] == '%') {
- p = &p[1];
- optlen = (int)strtol(p, (char **)&p, 0);
- if (!p || p[0] != '%' || (optlen > strlen(p) - 1)) {
+ p = bstr_cut(p, 1);
+ } else if (bstr_startswith0(p, "%")) {
+ p = bstr_cut(p, 1);
+ optlen = bstrtoll(p, &p, 0);
+ if (!bstr_startswith0(p, "%") || (optlen > p.len - 1)) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Invalid length %i for '%s'\n", optlen, subopt);
+ "Invalid length %d for '%.*s'\n",
+ optlen, BSTR_P(subopt));
return M_OPT_INVALID;
}
- p = &p[1];
- av_strlcpy(subparam, p, optlen + 1);
- p = &p[optlen];
+ subparam = bstr_splice(p, 1, optlen + 1);
+ p = bstr_cut(p, optlen + 1);
} else {
- optlen = strcspn(p, ":");
- av_strlcpy(subparam, p, optlen + 1);
- p = &p[optlen];
+ optlen = bstrcspn(p, ":");
+ subparam = bstr_splice(p, 0, optlen);
+ p = bstr_cut(p, optlen);
}
}
- if (p[0] == ':')
- p = &p[1];
- else if (p[0]) {
+ if (bstr_startswith0(p, ":"))
+ p = bstr_cut(p, 1);
+ else if (p.len > 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Incorrect termination for '%s'\n", subopt);
+ "Incorrect termination for '%.*s'\n", BSTR_P(subopt));
return M_OPT_INVALID;
}
- switch (sscanf_ret) {
- case 1:
- subparam[0] = 0;
- case 2:
- for (i = 0; subopts[i].name; i++)
- if (!strcmp(subopts[i].name, subopt))
- break;
- if (!subopts[i].name) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Unknown suboption %s\n", name, subopt);
- return M_OPT_UNKNOWN;
- }
- r = m_option_parse(&subopts[i], subopt,
- subparam[0] == 0 ? NULL : subparam, false,
- NULL);
- if (r < 0)
- return r;
- if (dst) {
- lst = talloc_realloc(NULL, lst, char *, 2 * (nr + 2));
- lst[2 * nr] = talloc_strdup(NULL, subopt);
- lst[2 * nr + 1] = subparam[0] == 0 ? NULL :
- talloc_strdup(NULL, subparam);
- memset(&lst[2 * (nr + 1)], 0, 2 * sizeof(char *));
- nr++;
- }
- break;
+ for (i = 0; subopts[i].name; i++)
+ if (!bstrcmp0(subopt, subopts[i].name))
+ break;
+ if (!subopts[i].name) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Option %.*s: Unknown suboption %.*s\n",
+ BSTR_P(name), BSTR_P(subopt));
+ return M_OPT_UNKNOWN;
+ }
+ int r = m_option_parse(&subopts[i], subopt, subparam, false, NULL);
+ if (r < 0)
+ return r;
+ if (dst) {
+ lst = talloc_realloc(NULL, lst, char *, 2 * (nr + 2));
+ lst[2 * nr] = bstrdup0(NULL, subopt);
+ lst[2 * nr + 1] = subparam.len == 0 ? NULL :
+ bstrdup0(NULL, subparam);
+ memset(&lst[2 * (nr + 1)], 0, 2 * sizeof(char *));
+ nr++;
}
}
- talloc_free(subparam);
- talloc_free(subopt);
if (dst)
VAL(dst) = lst;
@@ -1204,16 +1169,16 @@ static struct {
{ NULL, 0 }
};
-static int parse_imgfmt(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_imgfmt(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
uint32_t fmt = 0;
int i;
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- if (!strcmp(param, "help")) {
+ if (!bstrcmp0(param, "help")) {
mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available formats:");
for (i = 0; mp_imgfmt_list[i].name; i++)
mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %s", mp_imgfmt_list[i].name);
@@ -1221,16 +1186,19 @@ static int parse_imgfmt(const m_option_t *opt, const char *name,
return M_OPT_EXIT - 1;
}
- if (sscanf(param, "0x%x", &fmt) != 1) {
+ if (bstr_startswith0(param, "0x"))
+ fmt = bstrtoll(param, NULL, 16);
+ else {
for (i = 0; mp_imgfmt_list[i].name; i++) {
- if (!strcasecmp(param, mp_imgfmt_list[i].name)) {
+ if (!bstrcasecmp0(param, mp_imgfmt_list[i].name)) {
fmt = mp_imgfmt_list[i].fmt;
break;
}
}
if (!mp_imgfmt_list[i].name) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: unknown format name: '%s'\n", name, param);
+ "Option %.*s: unknown format name: '%.*s'\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
}
@@ -1296,16 +1264,16 @@ static struct {
{ NULL, 0 }
};
-static int parse_afmt(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_afmt(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
uint32_t fmt = 0;
int i;
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
- if (!strcmp(param, "help")) {
+ if (!bstrcmp0(param, "help")) {
mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available formats:");
for (i = 0; mp_afmt_list[i].name; i++)
mp_msg(MSGT_CFGPARSER, MSGL_INFO, " %s", mp_afmt_list[i].name);
@@ -1313,16 +1281,19 @@ static int parse_afmt(const m_option_t *opt, const char *name,
return M_OPT_EXIT - 1;
}
- if (sscanf(param, "0x%x", &fmt) != 1) {
+ if (bstr_startswith0(param, "0x"))
+ fmt = bstrtoll(param, NULL, 16);
+ else {
for (i = 0; mp_afmt_list[i].name; i++) {
- if (!strcasecmp(param, mp_afmt_list[i].name)) {
+ if (!bstrcasecmp0(param, mp_afmt_list[i].name)) {
fmt = mp_afmt_list[i].fmt;
break;
}
}
if (!mp_afmt_list[i].name) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: unknown format name: '%s'\n", name, param);
+ "Option %.*s: unknown format name: '%.*s'\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
}
@@ -1347,36 +1318,36 @@ const m_option_type_t m_option_type_afmt = {
};
-int parse_timestring(const char *str, double *time, char endchar)
+static int parse_timestring(struct bstr str, double *time, char endchar)
{
int a, b, len;
double d;
*time = 0; /* ensure initialization for error cases */
- if (sscanf(str, "%d:%d:%lf%n", &a, &b, &d, &len) >= 3)
+ if (bstr_sscanf(str, "%d:%d:%lf%n", &a, &b, &d, &len) >= 3)
*time = 3600 * a + 60 * b + d;
- else if (sscanf(str, "%d:%lf%n", &a, &d, &len) >= 2)
+ else if (bstr_sscanf(str, "%d:%lf%n", &a, &d, &len) >= 2)
*time = 60 * a + d;
- else if (sscanf(str, "%lf%n", &d, &len) >= 1)
+ else if (bstr_sscanf(str, "%lf%n", &d, &len) >= 1)
*time = d;
else
return 0; /* unsupported time format */
- if (str[len] && str[len] != endchar)
+ if (len < str.len && str.start[len] != endchar)
return 0; /* invalid extra characters at the end */
return len;
}
-static int parse_time(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_time(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
double time;
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
if (!parse_timestring(param, &time, 0)) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid time: '%s'\n",
- name, param);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: invalid time: '%.*s'\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
@@ -1401,19 +1372,19 @@ const m_option_type_t m_option_type_time = {
// Time or size (-endpos)
-static int parse_time_size(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_time_size(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
m_time_size_t ts;
char unit[4];
double end_at;
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
ts.pos = 0;
/* End at size parsing */
- if (sscanf(param, "%lf%3s", &end_at, unit) == 2) {
+ if (bstr_sscanf(param, "%lf%3s", &end_at, unit) == 2) {
ts.type = END_AT_SIZE;
if (!strcasecmp(unit, "b"))
;
@@ -1436,8 +1407,8 @@ static int parse_time_size(const m_option_t *opt, const char *name,
* even a number followed by garbage */
if (!parse_timestring(param, &end_at, 0)) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: invalid time or size: '%s'\n",
- name, param);
+ "Option %.*s: invalid time or size: '%.*s'\n",
+ BSTR_P(name), BSTR_P(param));
return M_OPT_INVALID;
}
@@ -1470,7 +1441,7 @@ const m_option_type_t m_option_type_time_size = {
#undef VAL
#define VAL(x) (*(m_obj_settings_t **)(x))
-static int find_obj_desc(const char *name, const m_obj_list_t *l,
+static int find_obj_desc(struct bstr name, const m_obj_list_t *l,
const m_struct_t **ret)
{
int i;
@@ -1478,7 +1449,7 @@ static int find_obj_desc(const char *name, const m_obj_list_t *l,
for (i = 0; l->list[i]; i++) {
n = M_ST_MB(char *, l->list[i], l->name_off);
- if (!strcmp(n, name)) {
+ if (!bstrcmp0(name, n)) {
*ret = M_ST_MB(m_struct_t *, l->list[i], l->desc_off);
return 1;
}
@@ -1486,79 +1457,74 @@ static int find_obj_desc(const char *name, const m_obj_list_t *l,
return 0;
}
-static int get_obj_param(const char *opt_name, const char *obj_name,
- const m_struct_t *desc, char *str, int *nold,
+static int get_obj_param(struct bstr opt_name, struct bstr obj_name,
+ const m_struct_t *desc, struct bstr str, int *nold,
int oldmax, char **dst)
{
- char *eq;
const m_option_t *opt;
int r;
- eq = strchr(str, '=');
- if (eq && eq == str)
- eq = NULL;
+ int eq = bstrchr(str, '=');
- if (eq) {
- char *p = eq + 1;
- if (p[0] == '\0')
- p = NULL;
- eq[0] = '\0';
- opt = m_option_list_find(desc->fields, str);
+ if (eq > 0) { // eq == 0 ignored
+ struct bstr p = bstr_cut(str, eq + 1);
+ str = bstr_splice(str, 0, eq);
+ opt = m_option_list_findb(desc->fields, str);
if (!opt) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: %s doesn't have a %s parameter.\n",
- opt_name, obj_name, str);
+ "Option %.*s: %.*s doesn't have a %.*s parameter.\n",
+ BSTR_P(opt_name), BSTR_P(obj_name), BSTR_P(str));
return M_OPT_UNKNOWN;
}
r = m_option_parse(opt, str, p, false, NULL);
if (r < 0) {
if (r > M_OPT_EXIT)
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while parsing %s parameter %s (%s)\n",
- opt_name, obj_name, str, p);
- eq[0] = '=';
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: "
+ "Error while parsing %.*s parameter %.*s (%.*s)\n",
+ BSTR_P(opt_name), BSTR_P(obj_name), BSTR_P(str),
+ BSTR_P(p));
return r;
}
if (dst) {
- dst[0] = talloc_strdup(NULL, str);
- dst[1] = talloc_strdup(NULL, p);
+ dst[0] = bstrdup0(NULL, str);
+ dst[1] = bstrdup0(NULL, p);
}
- eq[0] = '=';
} else {
if ((*nold) >= oldmax) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s has only %d params, so you can't give more than %d unnamed params.\n",
- opt_name, obj_name, oldmax, oldmax);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: %.*s has only %d params, so you can't give more than %d unnamed params.\n",
+ BSTR_P(opt_name), BSTR_P(obj_name), oldmax, oldmax);
return M_OPT_OUT_OF_RANGE;
}
opt = &desc->fields[(*nold)];
- r = m_option_parse(opt, opt->name, str, false, NULL);
+ r = m_option_parse(opt, bstr(opt->name), str, false, NULL);
if (r < 0) {
if (r > M_OPT_EXIT)
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while parsing %s parameter %s (%s)\n",
- opt_name, obj_name, opt->name, str);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: "
+ "Error while parsing %.*s parameter %s (%.*s)\n",
+ BSTR_P(opt_name), BSTR_P(obj_name), opt->name,
+ BSTR_P(str));
return r;
}
if (dst) {
dst[0] = talloc_strdup(NULL, opt->name);
- dst[1] = talloc_strdup(NULL, str);
+ dst[1] = bstrdup0(NULL, str);
}
(*nold)++;
}
return 1;
}
-static int get_obj_params(const char *opt_name, const char *name, char *params,
- const m_struct_t *desc, char separator, char ***_ret)
+static int get_obj_params(struct bstr opt_name, struct bstr name,
+ struct bstr params, const m_struct_t *desc,
+ char separator, char ***_ret)
{
- int n = 0, nold = 0, nopts, r;
- char *ptr, *last_ptr = params;
+ int n = 0, nold = 0, nopts;
char **ret;
- if (!strcmp(params, "help")) { // Help
+ if (!bstrcmp0(params, "help")) { // Help
char min[50], max[50];
if (!desc->fields) {
- printf("%s doesn't have any options.\n\n", name);
+ printf("%.*s doesn't have any options.\n\n", BSTR_P(name));
return M_OPT_EXIT - 1;
}
printf("\n Name Type Min Max\n\n");
@@ -1588,34 +1554,31 @@ static int get_obj_params(const char *opt_name, const char *name, char *params,
/* NOP */;
// TODO : Check that each opt can be parsed
- r = 1;
- while (last_ptr && last_ptr[0] != '\0') {
- ptr = strchr(last_ptr, separator);
- if (!ptr) {
- r = get_obj_param(opt_name, name, desc, last_ptr, &nold, nopts,
- NULL);
- n++;
- break;
+ struct bstr s = params;
+ while (1) {
+ bool end = false;
+ int idx = bstrchr(s, separator);
+ if (idx < 0) {
+ idx = s.len;
+ end = true;
}
- if (ptr == last_ptr) { // Empty field, count it and go on
+ struct bstr field = bstr_splice(s, 0, idx);
+ s = bstr_cut(s, idx + 1);
+ if (field.len == 0) { // Empty field, count it and go on
nold++;
- last_ptr = ptr + 1;
- continue;
+ } else {
+ int r = get_obj_param(opt_name, name, desc, field, &nold, nopts,
+ NULL);
+ if (r < 0)
+ return r;
+ n++;
}
- ptr[0] = '\0';
- r = get_obj_param(opt_name, name, desc, last_ptr, &nold, nopts, NULL);
- ptr[0] = separator;
- if (r < 0)
+ if (end)
break;
- n++;
- last_ptr = ptr + 1;
}
- if (r < 0)
- return r;
- if (!last_ptr[0]) // count an empty field at the end, too
- nold++;
if (nold > nopts) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Too many options for %s\n", name);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Too many options for %.*s\n",
+ BSTR_P(name));
return M_OPT_OUT_OF_RANGE;
}
if (!_ret) // Just test
@@ -1625,26 +1588,21 @@ static int get_obj_params(const char *opt_name, const char *name, char *params,
ret = talloc_array(NULL, char *, (n + 2) * 2);
n = nold = 0;
- last_ptr = params;
-
- while (last_ptr && last_ptr[0] != '\0') {
- ptr = strchr(last_ptr, separator);
- if (!ptr) {
- get_obj_param(opt_name, name, desc, last_ptr, &nold, nopts,
+ s = params;
+
+ while (s.len > 0) {
+ int idx = bstrchr(s, separator);
+ if (idx < 0)
+ idx = s.len;
+ struct bstr field = bstr_splice(s, 0, idx);
+ s = bstr_cut(s, idx + 1);
+ if (field.len == 0) { // Empty field, count it and go on
+ nold++;
+ } else {
+ get_obj_param(opt_name, name, desc, field, &nold, nopts,
&ret[n * 2]);
n++;
- break;
- }
- if (ptr == last_ptr) { // Empty field, count it and go on
- last_ptr = ptr + 1;
- nold++;
- continue;
}
- ptr[0] = '\0';
- get_obj_param(opt_name, name, desc, last_ptr, &nold, nopts,
- &ret[n * 2]);
- n++;
- last_ptr = ptr + 1;
}
ret[n * 2] = ret[n * 2 + 1] = NULL;
*_ret = ret;
@@ -1652,24 +1610,21 @@ static int get_obj_params(const char *opt_name, const char *name, char *params,
return 1;
}
-static int parse_obj_params(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param, void *dst)
+static int parse_obj_params(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param, void *dst)
{
char **opts;
int r;
m_obj_params_t *p = opt->priv;
const m_struct_t *desc;
- char *cpy;
// We need the object desc
if (!p)
return M_OPT_INVALID;
desc = p->desc;
- cpy = talloc_strdup(NULL, param);
- r = get_obj_params(name, desc->name, cpy, desc, p->separator,
+ r = get_obj_params(name, bstr(desc->name), param, desc, p->separator,
dst ? &opts : NULL);
- talloc_free(cpy);
if (r < 0)
return r;
if (!dst)
@@ -1678,7 +1633,7 @@ static int parse_obj_params(const m_option_t *opt, const char *name,
return 1;
for (r = 0; opts[r]; r += 2)
- m_struct_set(desc, dst, opts[r], opts[r + 1]);
+ m_struct_set(desc, dst, opts[r], bstr(opts[r + 1]));
return 1;
}
@@ -1719,42 +1674,39 @@ const m_obj_params_t m_span_params_def = {
'-'
};
-static int parse_obj_settings(const char *opt, char *str,
+static int parse_obj_settings(struct bstr opt, struct bstr str,
const m_obj_list_t *list,
m_obj_settings_t **_ret, int ret_n)
{
int r;
- char *param, **plist = NULL;
+ char **plist = NULL;
const m_struct_t *desc;
m_obj_settings_t *ret = _ret ? *_ret : NULL;
-
- // Now check that the object exists
- param = strchr(str, '=');
- if (param) {
- param[0] = '\0';
- param++;
- if (strlen(param) <= 0)
- param = NULL;
+ struct bstr param = bstr(NULL);
+ int idx = bstrchr(str, '=');
+ if (idx >= 0) {
+ param = bstr_cut(str, idx + 1);
+ str = bstr_splice(str, 0, idx);
}
-
if (!find_obj_desc(str, list, &desc)) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s doesn't exist.\n",
- opt, str);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: %.*s doesn't exist.\n",
+ BSTR_P(opt), BSTR_P(str));
return M_OPT_INVALID;
}
- if (param) {
+ if (param.start) {
if (!desc && _ret) {
- if (!strcmp(param, "help")) {
+ if (!bstrcmp0(param, "help")) {
mp_msg(MSGT_CFGPARSER, MSGL_INFO,
- "Option %s: %s have no option description.\n", opt, str);
+ "Option %.*s: %.*s have no option description.\n",
+ BSTR_P(opt), BSTR_P(str));
return M_OPT_EXIT - 1;
}
plist = talloc_zero_array(NULL, char *, 4);
plist[0] = talloc_strdup(NULL, "_oldargs_");
- plist[1] = talloc_strdup(NULL, param);
+ plist[1] = bstrdup0(NULL, param);
} else if (desc) {
r = get_obj_params(opt, str, param, desc, ':',
_ret ? &plist : NULL);
@@ -1767,28 +1719,32 @@ static int parse_obj_settings(const char *opt, char *str,
ret = talloc_realloc(NULL, ret, struct m_obj_settings, ret_n + 2);
memset(&ret[ret_n], 0, 2 * sizeof(m_obj_settings_t));
- ret[ret_n].name = talloc_strdup(NULL, str);
+ ret[ret_n].name = bstrdup0(NULL, str);
ret[ret_n].attribs = plist;
*_ret = ret;
return 1;
}
-static int obj_settings_list_del(const char *opt_name, const char *param,
+static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
bool ambiguous_param, void *dst)
{
char **str_list = NULL;
int r, i, idx_max = 0;
char *rem_id = "_removed_marker_";
+ char name[100];
+ assert(opt_name.len < 100);
+ memcpy(name, opt_name.start, opt_name.len);
+ name[opt_name.len] = 0;
const m_option_t list_opt = {
- opt_name, NULL, CONF_TYPE_STRING_LIST,
+ name, NULL, CONF_TYPE_STRING_LIST,
0, 0, 0, NULL
};
m_obj_settings_t *obj_list = dst ? VAL(dst) : NULL;
if (dst && !obj_list) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: the list is empty.\n",
- opt_name);
+ mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %.*s: the list is empty.\n",
+ BSTR_P(opt_name));
return 1;
} else if (obj_list) {
for (idx_max = 0; obj_list[idx_max].name != NULL; idx_max++)
@@ -1804,7 +1760,7 @@ static int obj_settings_list_del(const char *opt_name, const char *param,
char *endptr;
id = strtol(str_list[r], &endptr, 0);
if (endptr == str_list[r]) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid parameter. We need a list of integers which are the indices of the elements to remove.\n", opt_name);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: invalid parameter. We need a list of integers which are the indices of the elements to remove.\n", BSTR_P(opt_name));
m_option_free(&list_opt, &str_list);
return M_OPT_INVALID;
}
@@ -1812,7 +1768,8 @@ static int obj_settings_list_del(const char *opt_name, const char *param,
continue;
if (id >= idx_max || id < -idx_max) {
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: Index %d is out of range.\n", opt_name, id);
+ "Option %.*s: Index %d is out of range.\n",
+ BSTR_P(opt_name), id);
continue;
}
if (id < 0)
@@ -1858,13 +1815,11 @@ static void free_obj_settings_list(void *dst)
VAL(dst) = NULL;
}
-static int parse_obj_settings_list(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param,
+static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param,
void *dst)
{
- int n = 0, r, len = strlen(opt->name);
- char *str;
- char *ptr, *last_ptr;
+ int len = strlen(opt->name);
m_obj_settings_t *res = NULL, *queue = NULL, *head = NULL;
int op = OP_NONE;
@@ -1872,21 +1827,21 @@ static int parse_obj_settings_list(const m_option_t *opt, const char *name,
if (!opt->priv)
return M_OPT_INVALID;
- if (opt->name[len - 1] == '*' && ((int)strlen(name) > len - 1)) {
- const char *n = &name[len - 1];
- if (strcasecmp(n, "-add") == 0)
+ if (opt->name[len - 1] == '*' && (name.len > len - 1)) {
+ struct bstr suffix = bstr_cut(name, len - 1);
+ if (bstrcasecmp0(suffix, "-add") == 0)
op = OP_ADD;
- else if (strcasecmp(n, "-pre") == 0)
+ else if (bstrcasecmp0(suffix, "-pre") == 0)
op = OP_PRE;
- else if (strcasecmp(n, "-del") == 0)
+ else if (bstrcasecmp0(suffix, "-del") == 0)
op = OP_DEL;
- else if (strcasecmp(n, "-clr") == 0)
+ else if (bstrcasecmp0(suffix, "-clr") == 0)
op = OP_CLR;
else {
char prefix[len];
strncpy(prefix, opt->name, len - 1);
prefix[len - 1] = '\0';
- mp_msg(MSGT_VFILTER, MSGL_ERR, "Option %s: unknown postfix %s\n"
+ mp_msg(MSGT_VFILTER, MSGL_ERR, "Option %.*s: unknown postfix %.*s\n"
"Supported postfixes are:\n"
" %s-add\n"
" Append the given list to the current list\n\n"
@@ -1897,7 +1852,7 @@ static int parse_obj_settings_list(const m_option_t *opt, const char *name,
" Negative index can be used (i.e. -1 is the last element)\n\n"
" %s-clr\n"
" Clear the current list.\n",
- name, n, prefix, prefix, prefix, prefix);
+ BSTR_P(name), BSTR_P(suffix), prefix, prefix, prefix, prefix);
return M_OPT_UNKNOWN;
}
@@ -1910,7 +1865,7 @@ static int parse_obj_settings_list(const m_option_t *opt, const char *name,
return 0;
}
- if (param == NULL || strlen(param) == 0)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
switch (op) {
@@ -1929,47 +1884,36 @@ static int parse_obj_settings_list(const m_option_t *opt, const char *name,
free_obj_settings_list(dst);
break;
default:
- mp_msg(MSGT_VFILTER, MSGL_ERR, "Option %s: FIXME\n", name);
+ mp_msg(MSGT_VFILTER, MSGL_ERR, "Option %.*s: FIXME\n", BSTR_P(name));
return M_OPT_UNKNOWN;
}
- if (!strcmp(param, "help")) {
+ if (!bstrcmp0(param, "help")) {
m_obj_list_t *ol = opt->priv;
mp_msg(MSGT_VFILTER, MSGL_INFO, "Available video filters:\n");
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_VIDEO_FILTERS\n");
- for (n = 0; ol->list[n]; n++)
+ for (int n = 0; ol->list[n]; n++)
mp_msg(MSGT_VFILTER, MSGL_INFO, " %-15s: %s\n",
M_ST_MB(char *, ol->list[n], ol->name_off),
M_ST_MB(char *, ol->list[n], ol->info_off));
mp_msg(MSGT_VFILTER, MSGL_INFO, "\n");
return M_OPT_EXIT - 1;
}
- ptr = str = talloc_strdup(NULL, param);
-
- while (ptr[0] != '\0') {
- last_ptr = ptr;
- ptr = get_nextsep(ptr, OPTION_LIST_SEPARATOR, 1);
- if (!ptr) {
- r = parse_obj_settings(name, last_ptr, opt->priv,
- dst ? &res : NULL, n);
- if (r < 0) {
- talloc_free(str);
- return r;
- }
- n++;
- break;
- }
- ptr[0] = '\0';
- r = parse_obj_settings(name, last_ptr, opt->priv, dst ? &res : NULL, n);
+ struct bstr s = bstrdup(NULL, param);
+ char *allocptr = s.start;
+ int n = 0;
+ while (s.len > 0) {
+ struct bstr el = get_nextsep(&s, OPTION_LIST_SEPARATOR, 1);
+ int r = parse_obj_settings(name, el, opt->priv, dst ? &res : NULL, n);
if (r < 0) {
- talloc_free(str);
+ talloc_free(allocptr);
return r;
}
- ptr++;
+ s = bstr_cut(s, 1);
n++;
}
- talloc_free(str);
+ talloc_free(allocptr);
if (n == 0)
return M_OPT_INVALID;
@@ -2049,8 +1993,8 @@ const m_option_type_t m_option_type_obj_settings_list = {
-static int parse_obj_presets(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param,
+static int parse_obj_presets(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param,
void *dst)
{
m_obj_presets_t *obj_p = (m_obj_presets_t *)opt->priv;
@@ -2061,12 +2005,13 @@ static int parse_obj_presets(const m_option_t *opt, const char *name,
char *pre_name = NULL;
if (!obj_p) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Presets need a "
- "pointer to a m_obj_presets_t in the priv field.\n", name);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: Presets need a "
+ "pointer to a m_obj_presets_t in the priv field.\n",
+ BSTR_P(name));
return M_OPT_PARSER_ERR;
}
- if (!param)
+ if (param.len == 0)
return M_OPT_MISSING_PARAM;
pre = obj_p->presets;
@@ -2074,9 +2019,9 @@ static int parse_obj_presets(const m_option_t *opt, const char *name,
out_desc = obj_p->out_desc ? obj_p->out_desc : obj_p->in_desc;
s = in_desc->size;
- if (!strcmp(param, "help")) {
- mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available presets for %s->%s:",
- out_desc->name, name);
+ if (!bstrcmp0(param, "help")) {
+ mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available presets for %s->%.*s:",
+ out_desc->name, BSTR_P(name));
for (pre = obj_p->presets;
(pre_name = M_ST_MB(char *, pre, obj_p->name_off)); pre += s)
mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s", pre_name);
@@ -2086,12 +2031,12 @@ static int parse_obj_presets(const m_option_t *opt, const char *name,
for (pre_name = M_ST_MB(char *, pre, obj_p->name_off); pre_name;
pre += s, pre_name = M_ST_MB(char *, pre, obj_p->name_off))
- if (!strcmp(pre_name, param))
+ if (!bstrcmp0(param, pre_name))
break;
if (!pre_name) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: There is no preset named %s\n"
- "Available presets are:", name, param);
+ "Option %.*s: There is no preset named %.*s\n"
+ "Available presets are:", BSTR_P(name), BSTR_P(param));
for (pre = obj_p->presets;
(pre_name = M_ST_MB(char *, pre, obj_p->name_off)); pre += s)
mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s", pre_name);
@@ -2107,9 +2052,9 @@ static int parse_obj_presets(const m_option_t *opt, const char *name,
in_desc->fields[i].name);
if (!out_opt) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Unable to find the target option for field %s.\n"
- "Please report this to the developers.\n",
- name, in_desc->fields[i].name);
+ "Option %.*s: Unable to find the target option for field %s.\n"
+ "Please report this to the developers.\n",
+ BSTR_P(name), in_desc->fields[i].name);
return M_OPT_PARSER_ERR;
}
m_option_copy(out_opt, M_ST_MB_P(dst, out_opt->p),
@@ -2132,218 +2077,182 @@ const m_option_type_t m_option_type_obj_presets = {
NULL
};
-static int parse_custom_url(const m_option_t *opt, const char *name,
- const char *url, bool ambiguous_param, void *dst)
+static int parse_custom_url(const m_option_t *opt, struct bstr name,
+ struct bstr url, bool ambiguous_param, void *dst)
{
- int pos1, pos2, r, v6addr = 0;
- char *ptr1 = NULL, *ptr2 = NULL, *ptr3 = NULL, *ptr4 = NULL;
+ int r;
m_struct_t *desc = opt->priv;
if (!desc) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Custom URL needs "
- "a pointer to a m_struct_t in the priv field.\n", name);
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: Custom URL needs "
+ "a pointer to a m_struct_t in the priv field.\n", BSTR_P(name));
return M_OPT_PARSER_ERR;
}
// extract the protocol
- ptr1 = strstr(url, "://");
- if (ptr1 == NULL) {
+ int idx = bstr_find0(url, "://");
+ if (idx < 0) {
// Filename only
if (m_option_list_find(desc->fields, "filename")) {
m_struct_set(desc, dst, "filename", url);
return 1;
}
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: URL doesn't have a valid protocol!\n", name);
+ "Option %.*s: URL doesn't have a valid protocol!\n",
+ BSTR_P(name));
return M_OPT_INVALID;
}
+ struct bstr ptr1 = bstr_cut(url, idx + 3);
if (m_option_list_find(desc->fields, "string")) {
- if (strlen(ptr1) > 3) {
- m_struct_set(desc, dst, "string", ptr1 + 3);
+ if (ptr1.len > 0) {
+ m_struct_set(desc, dst, "string", ptr1);
return 1;
}
}
- pos1 = ptr1 - url;
if (dst && m_option_list_find(desc->fields, "protocol")) {
- ptr1[0] = '\0';
- r = m_struct_set(desc, dst, "protocol", url);
- ptr1[0] = ':';
+ r = m_struct_set(desc, dst, "protocol", bstr_splice(url, 0, idx));
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting protocol.\n", name);
+ "Option %.*s: Error while setting protocol.\n",
+ BSTR_P(name));
return r;
}
}
- // jump the "://"
- ptr1 += 3;
- pos1 += 3;
-
// check if a username:password is given
- ptr2 = strstr(ptr1, "@");
- ptr3 = strstr(ptr1, "/");
- if (ptr3 != NULL && ptr3 < ptr2) {
- // it isn't really a username but rather a part of the path
- ptr2 = NULL;
- }
- if (ptr2 != NULL) {
-
+ idx = bstrchr(ptr1, '/');
+ if (idx < 0)
+ idx = ptr1.len;
+ struct bstr hostpart = bstr_splice(ptr1, 0, idx);
+ struct bstr path = bstr_cut(ptr1, idx);
+ idx = bstrchr(hostpart, '@');
+ if (idx >= 0) {
// We got something, at least a username...
if (!m_option_list_find(desc->fields, "username")) {
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: This URL doesn't have a username part.\n", name);
+ "Option %.*s: This URL doesn't have a username part.\n",
+ BSTR_P(name));
// skip
} else {
- ptr3 = strstr(ptr1, ":");
- if (ptr3 != NULL && ptr3 < ptr2) {
+ struct bstr userpass = bstr_splice(hostpart, 0, idx);
+ idx = bstrchr(userpass, ':');
+ if (idx >= 0) {
// We also have a password
if (!m_option_list_find(desc->fields, "password")) {
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: This URL doesn't have a password part.\n",
- name);
+ "Option %.*s: This URL doesn't have a password part.\n",
+ BSTR_P(name));
// skip
} else { // Username and password
if (dst) {
- ptr3[0] = '\0';
- r = m_struct_set(desc, dst, "username", ptr1);
- ptr3[0] = ':';
+ r = m_struct_set(desc, dst, "username",
+ bstr_splice(userpass, 0, idx));
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting username.\n",
- name);
+ "Option %.*s: Error while setting username.\n",
+ BSTR_P(name));
return r;
}
- ptr2[0] = '\0';
- r = m_struct_set(desc, dst, "password", ptr3 + 1);
- ptr2[0] = '@';
+ r = m_struct_set(desc, dst, "password",
+ bstr_splice(userpass, idx+1,
+ userpass.len));
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting password.\n",
- name);
+ "Option %.*s: Error while setting password.\n",
+ BSTR_P(name));
return r;
}
}
}
} else { // User name only
- ptr2[0] = '\0';
- r = m_struct_set(desc, dst, "username", ptr1);
- ptr2[0] = '@';
+ r = m_struct_set(desc, dst, "username", userpass);
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting username.\n", name);
+ "Option %.*s: Error while setting username.\n",
+ BSTR_P(name));
return r;
}
}
}
- ptr1 = ptr2 + 1;
- pos1 = ptr1 - url;
+ hostpart = bstr_cut(hostpart, idx + 1);
}
// Before looking for a port number check if we have an IPv6 type
// numeric address.
// In an IPv6 URL the numeric address should be inside square braces.
- ptr2 = strstr(ptr1, "[");
- ptr3 = strstr(ptr1, "]");
- // If the [] is after the first it isn't the hostname
- ptr4 = strstr(ptr1, "/");
- if (ptr2 != NULL && ptr3 != NULL && (ptr2 < ptr3)
- && (!ptr4 || ptr4 > ptr3)) {
+ int idx1 = bstrchr(hostpart, '[');
+ int idx2 = bstrchr(hostpart, ']');
+ struct bstr portstr = hostpart;
+ bool v6addr = false;
+ if (idx1 >= 0 && idx2 >= 0 && idx1 < idx2) {
// we have an IPv6 numeric address
- ptr1++;
- pos1++;
- ptr2 = ptr3;
- v6addr = 1;
- } else
- ptr2 = ptr1;
-
- // look if the port is given
- ptr2 = strstr(ptr2, ":");
- // If the : is after the first / it isn't the port
- ptr3 = strstr(ptr1, "/");
- if (ptr3 && ptr3 - ptr2 < 0)
- ptr2 = NULL;
- if (ptr2 == NULL) {
- // No port is given
- // Look if a path is given
- if (ptr3 == NULL) {
- // No path/filename
- // So we have an URL like http://www.hostname.com
- pos2 = strlen(url);
- } else {
- // We have an URL like http://www.hostname.com/file.txt
- pos2 = ptr3 - url;
- }
- } else {
+ portstr = bstr_cut(hostpart, idx2);
+ hostpart = bstr_splice(hostpart, idx1 + 1, idx2);
+ v6addr = true;
+ }
+
+ idx = bstrchr(portstr, ':');
+ if (idx >= 0) {
+ if (!v6addr)
+ hostpart = bstr_splice(hostpart, 0, idx);
// We have an URL beginning like http://www.hostname.com:1212
// Get the port number
if (!m_option_list_find(desc->fields, "port")) {
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: This URL doesn't have a port part.\n", name);
+ "Option %.*s: This URL doesn't have a port part.\n",
+ BSTR_P(name));
// skip
} else {
if (dst) {
- int p = atoi(ptr2 + 1);
+ int p = bstrtoll(bstr_cut(portstr, idx + 1), NULL, 0);
char tmp[100];
snprintf(tmp, 99, "%d", p);
- r = m_struct_set(desc, dst, "port", tmp);
+ r = m_struct_set(desc, dst, "port", bstr(tmp));
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting port.\n", name);
+ "Option %.*s: Error while setting port.\n",
+ BSTR_P(name));
return r;
}
}
}
- pos2 = ptr2 - url;
}
- if (v6addr)
- pos2--;
// Get the hostname
- if (pos2 - pos1 > 0) {
+ if (hostpart.len > 0) {
if (!m_option_list_find(desc->fields, "hostname")) {
mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: This URL doesn't have a hostname part.\n", name);
+ "Option %.*s: This URL doesn't have a hostname part.\n",
+ BSTR_P(name));
// skip
} else {
- char tmp[pos2 - pos1 + 1];
- strncpy(tmp, ptr1, pos2 - pos1);
- tmp[pos2 - pos1] = '\0';
- r = m_struct_set(desc, dst, "hostname", tmp);
+ r = m_struct_set(desc, dst, "hostname", hostpart);
if (r < 0) {
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting hostname.\n", name);
+ "Option %.*s: Error while setting hostname.\n",
+ BSTR_P(name));
return r;
}
}
}
// Look if a path is given
- ptr2 = strstr(ptr1, "/");
- if (ptr2 != NULL) {
- // A path/filename is given
- // check if it's not a trailing '/'
- if (strlen(ptr2) > 1) {
- // copy the path/filename in the URL container
- if (!m_option_list_find(desc->fields, "filename")) {
- mp_msg(MSGT_CFGPARSER, MSGL_WARN,
- "Option %s: This URL doesn't have a hostname part.\n",
- name);
- // skip
- } else {
- if (dst) {
- int l = strlen(ptr2 + 1) + 1;
- char *fname = ptr2 + 1;
- if (l > 1) {
- fname = talloc_size(NULL, l);
- url_unescape_string(fname, ptr2 + 1);
- }
- r = m_struct_set(desc, dst, "filename", fname);
- if (fname != ptr2 + 1)
- talloc_free(fname);
- if (r < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,
- "Option %s: Error while setting filename.\n",
- name);
- return r;
- }
+ if (path.len > 1) { // not just "/"
+ // copy the path/filename in the URL container
+ if (!m_option_list_find(desc->fields, "filename")) {
+ mp_msg(MSGT_CFGPARSER, MSGL_WARN,
+ "Option %.*s: This URL doesn't have a filename part.\n",
+ BSTR_P(name));
+ // skip
+ } else {
+ if (dst) {
+ char *fname = bstrdup0(NULL, bstr_cut(path, 1));
+ url_unescape_string(fname, fname);
+ r = m_struct_set(desc, dst, "filename", bstr(fname));
+ talloc_free(fname);
+ if (r < 0) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,
+ "Option %.*s: Error while setting filename.\n",
+ BSTR_P(name));
+ return r;
}
}
}
diff --git a/m_option.h b/m_option.h
index 76d3366d18..123e51005c 100644
--- a/m_option.h
+++ b/m_option.h
@@ -24,6 +24,7 @@
#include <stdbool.h>
#include "config.h"
+#include "bstr.h"
// m_option allows to parse, print and copy data of various types.
@@ -217,7 +218,7 @@ struct m_option_type {
* \return On error a negative value is returned, on success the number
* of arguments consumed. For details see \ref OptionParserReturn.
*/
- int (*parse)(const m_option_t *opt, const char *name, const char *param,
+ int (*parse)(const m_option_t *opt, struct bstr name, struct bstr param,
bool ambiguous_param, void *dst);
// Print back a value in string form.
@@ -440,8 +441,8 @@ static inline void *m_option_get_ptr(const struct m_option *opt,
}
// Helper to parse options, see \ref m_option_type::parse.
-static inline int m_option_parse(const m_option_t *opt, const char *name,
- const char *param, bool ambiguous_param,
+static inline int m_option_parse(const m_option_t *opt, struct bstr name,
+ struct bstr param, bool ambiguous_param,
void *dst)
{
return opt->type->parse(opt, name, param, ambiguous_param, dst);
@@ -475,17 +476,6 @@ static inline void m_option_free(const m_option_t *opt, void *dst)
/*@}*/
-/**
- * Parse a string as a timestamp.
- *
- * @param[in] str the string to parse.
- * @param[out] time parsed time.
- * @param[in] endchar return an error of the next character after the
- * timestamp is neither nul nor endchar.
- * @return Number of chars in the timestamp.
- */
-int parse_timestring(const char *str, double *time, char endchar);
-
#define OPTION_LIST_SEPARATOR ','
#if HAVE_DOS_PATHS
diff --git a/m_property.c b/m_property.c
index da0f54e2c1..188d225bad 100644
--- a/m_property.c
+++ b/m_property.c
@@ -108,7 +108,8 @@ int m_property_do(const m_option_t *prop_list, const char *name,
if (!arg)
return M_PROPERTY_ERROR;
val = calloc(1, opt->type->size);
- if ((r = m_option_parse(opt, opt->name, arg, false, val)) <= 0) {
+ if ((r = m_option_parse(opt, bstr(opt->name), bstr(arg), false,
+ val)) <= 0) {
free(val);
return r;
}
diff --git a/m_struct.c b/m_struct.c
index ca7c967ff2..764f616a89 100644
--- a/m_struct.c
+++ b/m_struct.c
@@ -67,8 +67,9 @@ m_struct_alloc(const m_struct_t* st) {
return r;
}
-int
-m_struct_set(const m_struct_t* st, void* obj, const char* field, const char* param) {
+int m_struct_set(const m_struct_t *st, void *obj, const char *field,
+ struct bstr param)
+{
const m_option_t* f = m_struct_get_field(st,field);
if(!f) {
@@ -77,9 +78,9 @@ m_struct_set(const m_struct_t* st, void* obj, const char* field, const char* par
return 0;
}
- if(f->type->parse(f, field, param, false, M_ST_MB_P(obj,f->p)) < 0) {
- mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s, field %s parsing error: %s\n",
- st->name,field,param);
+ if(f->type->parse(f, bstr(field), param, false, M_ST_MB_P(obj,f->p)) < 0) {
+ mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Struct %s, field %s parsing error: %.*s\n",
+ st->name, field, BSTR_P(param));
return 0;
}
diff --git a/m_struct.h b/m_struct.h
index bcf09dc86f..79c7c24f2f 100644
--- a/m_struct.h
+++ b/m_struct.h
@@ -19,6 +19,8 @@
#ifndef MPLAYER_M_STRUCT_H
#define MPLAYER_M_STRUCT_H
+#include "bstr.h"
+
/// \defgroup OptionsStruct Options struct
/// \ingroup Options
/// An API to manipulate structs using m_option.
@@ -87,8 +89,8 @@ m_struct_alloc(const m_struct_t* st);
* \param param New value of the field.
* \return 0 on error, 1 on success.
*/
-int
-m_struct_set(const m_struct_t* st, void* obj, const char* field, const char* param);
+int m_struct_set(const m_struct_t *st, void *obj, const char *field,
+ struct bstr param);
/// Reset a field (or all if field == NULL) to defaults.
/** \param st Struct definition.
diff --git a/osdep/macosx_finder_args.c b/osdep/macosx_finder_args.c
index c3b5f99672..6b5ef321f4 100644
--- a/osdep/macosx_finder_args.c
+++ b/osdep/macosx_finder_args.c
@@ -118,7 +118,7 @@ char myPsnStr[5+10+1+10+1];
myPsnStr[5+10+1+10]=0;
if((argc==2) && !strcmp(myPsnStr, argv[1])) {
- m_config_set_option(config, "quiet", NULL, false);
+ m_config_set_option0(config, "quiet", NULL, false);
InitCursor();
AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(AppleEventHandlerProc), 0, FALSE);
RunApplicationEventLoop();
diff --git a/parser-cfg.c b/parser-cfg.c
index 5b39c32711..720b8e243f 100644
--- a/parser-cfg.c
+++ b/parser-cfg.c
@@ -233,7 +233,7 @@ int m_config_parse_config_file(m_config_t *config, const char *conffile)
tmp = m_config_set_profile_option(config, profile,
opt, param);
} else
- tmp = m_config_set_option(config, opt, param, false);
+ tmp = m_config_set_option0(config, opt, param, false);
if (tmp < 0) {
PRINT_LINENUM;
if (tmp == M_OPT_UNKNOWN) {
diff --git a/parser-mpcmd.c b/parser-mpcmd.c
index 354d4fd7a5..52de313e71 100644
--- a/parser-mpcmd.c
+++ b/parser-mpcmd.c
@@ -183,15 +183,15 @@ play_tree_t *m_config_parse_mp_command_line(m_config_t *config, int argc,
} else if (mode == LOCAL) // Drop params for empty entry
mode = DROP_LOCAL;
} else if (tmp == 0) { // 'normal' options
- mp_opt = m_config_get_option(config, opt);
+ mp_opt = m_config_get_option(config, bstr(opt));
if (mp_opt != NULL) { // Option exist
if (mode == GLOBAL || (mp_opt->flags & M_OPT_GLOBAL))
tmp = (i + 1 < argc)
- ? m_config_set_option(config, opt, argv[i + 1],
+ ? m_config_set_option0(config, opt, argv[i + 1],
true)
- : m_config_set_option(config, opt, NULL, false);
+ : m_config_set_option0(config, opt, NULL, false);
else {
- tmp = m_config_check_option(config, opt,
+ tmp = m_config_check_option0(config, opt,
(i + 1 < argc) ? argv[i + 1] : NULL, true);
if (tmp >= 0 && mode != DROP_LOCAL) {
play_tree_t *pt =
@@ -257,7 +257,7 @@ play_tree_t *m_config_parse_mp_command_line(m_config_t *config, int argc,
// Lock stdin if it will be used as input
if (strcasecmp(argv[i], "-") == 0)
- m_config_set_option(config, "consolecontrols", "no", false);
+ m_config_set_option0(config, "consolecontrols", "no", false);
add_entry(&last_parent, &last_entry, entry);
mode = LOCAL; // We start entry specific options
}
@@ -301,13 +301,13 @@ int m_config_preparse_command_line(m_config_t *config, int argc, char **argv)
break;
arg++;
- opt = m_config_get_option(config, arg);
+ opt = m_config_get_option(config, bstr(arg));
// Ignore invalid option
if (!opt)
continue;
// Set, non-pre-parse options will be ignored
- int r = m_config_set_option(config, arg, i+1 < argc ? argv[i+1] : NULL,
- true);
+ int r = m_config_set_option0(config, arg, i+1 < argc ? argv[i+1] : NULL,
+ true);
if (r < 0)
ret = r;
else
diff --git a/playtree.c b/playtree.c
index 77c1927a8b..c0b5dd2557 100644
--- a/playtree.c
+++ b/playtree.c
@@ -465,8 +465,8 @@ play_tree_iter_push_params(play_tree_iter_t* iter) {
for(n = 0; pt->params[n].name != NULL ; n++) {
int e;
- if((e = m_config_set_option(iter->config, pt->params[n].name,
- pt->params[n].value, false)) < 0) {
+ if((e = m_config_set_option0(iter->config, pt->params[n].name,
+ pt->params[n].value, false)) < 0) {
mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error %d while setting option '%s' with value '%s'\n",e,
pt->params[n].name,pt->params[n].value);
}
diff --git a/stream/stream.c b/stream/stream.c
index 6217fe6283..fc5185827b 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -166,7 +166,7 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
if(sinfo->opts_url) {
m_option_t url_opt =
{ "stream url", arg , CONF_TYPE_CUSTOM_URL, 0, 0 ,0, (void *)sinfo->opts };
- if (m_option_parse(&url_opt, "stream url", filename, false, arg) < 0) {
+ if (m_option_parse(&url_opt, bstr("stream url"), bstr(filename), false, arg) < 0) {
mp_tmsg(MSGT_OPEN,MSGL_ERR, "URL parsing failed on url %s\n",filename);
m_struct_free(desc,arg);
return NULL;