typedef enum _snd_config_type {
/** Integer number */
SND_CONFIG_TYPE_INTEGER,
+ /** 64 bit Integer number */
+ SND_CONFIG_TYPE_INTEGER64,
/** Real number */
SND_CONFIG_TYPE_REAL,
/** Character string */
int snd_config_make(snd_config_t **config, const char *key,
snd_config_type_t type);
int snd_config_make_integer(snd_config_t **config, const char *key);
+int snd_config_make_integer64(snd_config_t **config, const char *key);
int snd_config_make_real(snd_config_t **config, const char *key);
int snd_config_make_string(snd_config_t **config, const char *key);
int snd_config_make_pointer(snd_config_t **config, const char *key);
int snd_config_make_compound(snd_config_t **config, const char *key, int join);
int snd_config_imake_integer(snd_config_t **config, const char *key, const long value);
+int snd_config_imake_integer64(snd_config_t **config, const char *key, const long long value);
int snd_config_imake_real(snd_config_t **config, const char *key, const double value);
int snd_config_imake_string(snd_config_t **config, const char *key, const char *ascii);
int snd_config_imake_pointer(snd_config_t **config, const char *key, const void *ptr);
int snd_config_set_id(snd_config_t *config, const char *id);
int snd_config_set_integer(snd_config_t *config, long value);
+int snd_config_set_integer64(snd_config_t *config, long long value);
int snd_config_set_real(snd_config_t *config, double value);
int snd_config_set_string(snd_config_t *config, const char *value);
int snd_config_set_ascii(snd_config_t *config, const char *ascii);
int snd_config_set_pointer(snd_config_t *config, const void *ptr);
int snd_config_get_id(const snd_config_t *config, const char **value);
int snd_config_get_integer(const snd_config_t *config, long *value);
+int snd_config_get_integer64(const snd_config_t *config, long long *value);
int snd_config_get_real(const snd_config_t *config, double *value);
int snd_config_get_ireal(const snd_config_t *config, double *value);
int snd_config_get_string(const snd_config_t *config, const char **value);
#include <stdarg.h>
#include <wordexp.h>
#include <dlfcn.h>
+#include <limits.h>
#include <sys/stat.h>
#include <pthread.h>
#include "local.h"
snd_config_type_t type;
union {
long integer;
+ long long integer64;
char *string;
double real;
const void *ptr;
int ch;
} input_t;
+int safe_strtoll(const char *str, long long *val)
+{
+ long long v;
+ if (!*str)
+ return -EINVAL;
+ errno = 0;
+ if (sscanf(str, "%Ld", &v) != 1)
+ return -EINVAL;
+ *val = v;
+ return 0;
+}
+
int safe_strtol(const char *str, long *val)
{
char *end;
return 0;
}
if (err == 0 && ((s[0] >= '0' && s[0] <= '9') || s[0] == '-')) {
- long i;
+ long long i;
errno = 0;
- err = safe_strtol(s, &i);
+ err = safe_strtoll(s, &i);
if (err < 0) {
double r;
err = safe_strtod(s, &r);
} else {
free(s);
if (n) {
- if (n->type != SND_CONFIG_TYPE_INTEGER) {
+ if (n->type != SND_CONFIG_TYPE_INTEGER && n->type != SND_CONFIG_TYPE_INTEGER64) {
SNDERR("%s is not an integer", *id);
return -EINVAL;
}
} else {
- err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father);
+ if (i <= INT_MAX)
+ err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father);
+ else
+ err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER64, father);
if (err < 0)
return err;
}
- n->u.integer = i;
+ if (n->type == SND_CONFIG_TYPE_INTEGER)
+ n->u.integer = (long) i;
+ else
+ n->u.integer64 = i;
*_n = n;
return 0;
}
case SND_CONFIG_TYPE_INTEGER:
snd_output_printf(out, "%ld", n->u.integer);
break;
+ case SND_CONFIG_TYPE_INTEGER64:
+ snd_output_printf(out, "%Ld", n->u.integer64);
+ break;
case SND_CONFIG_TYPE_REAL:
snd_output_printf(out, "%-16g", n->u.real);
break;
*type = SND_CONFIG_TYPE_INTEGER;
return 0;
}
+ if (!strcmp(ascii, "integer64")) {
+ *type = SND_CONFIG_TYPE_INTEGER64;
+ return 0;
+ }
if (!strcmp(ascii, "real")) {
*type = SND_CONFIG_TYPE_REAL;
return 0;
return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
}
+/**
+ * \brief Build an integer64 config node
+ * \param config Returned config node handle pointer
+ * \param id Node id
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_make_integer64(snd_config_t **config, const char *id)
+{
+ return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
+}
+
/**
* \brief Build a real config node
* \param config Returned config node handle pointer
return 0;
}
+/**
+ * \brief Build an integer64 config node and use given initial value
+ * \param config Returned config node handle pointer
+ * \param id Node id
+ * \param value Initial value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_imake_integer64(snd_config_t **config, const char *id, const long long value)
+{
+ int err;
+
+ err = snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER64);
+ if (err < 0)
+ return err;
+ (*config)->u.integer64 = value;
+ return 0;
+}
+
/**
* \brief Build a real config node and use given initial value
* \param config Returned config node handle pointer
return 0;
}
+/**
+ * \brief Change the value of an integer64 config node
+ * \param config Config node handle
+ * \param value Value
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_set_integer64(snd_config_t *config, long long value)
+{
+ assert(config);
+ if (config->type != SND_CONFIG_TYPE_INTEGER64)
+ return -EINVAL;
+ config->u.integer64 = value;
+ return 0;
+}
+
/**
* \brief Change the value of a real config node
* \param config Config node handle
config->u.integer = i;
}
break;
+ case SND_CONFIG_TYPE_INTEGER64:
+ {
+ long long i;
+ int err = safe_strtoll(ascii, &i);
+ if (err < 0)
+ return err;
+ config->u.integer64 = i;
+ }
+ break;
case SND_CONFIG_TYPE_REAL:
{
double d;
return 0;
}
+/**
+ * \brief Get the value of an integer64 config node
+ * \param config Config node handle
+ * \param ptr Returned value pointer
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_get_integer64(const snd_config_t *config, long long *ptr)
+{
+ assert(config && ptr);
+ if (config->type != SND_CONFIG_TYPE_INTEGER64)
+ return -EINVAL;
+ *ptr = config->u.integer64;
+ return 0;
+}
+
/**
* \brief Get the value of a real config node
* \param config Config node handle
* \param ptr Returned value pointer
* \return 0 on success otherwise a negative error code
*
- * Note: If the config type is integer, it is converted
+ * Note: If the config type is integer/integer64, it is converted
* to the double type on the fly.
*/
int snd_config_get_ireal(const snd_config_t *config, double *ptr)
*ptr = config->u.real;
else if (config->type == SND_CONFIG_TYPE_INTEGER)
*ptr = config->u.integer;
+ else if (config->type == SND_CONFIG_TYPE_INTEGER64)
+ *ptr = config->u.integer64;
else
return -EINVAL;
return 0;
*ascii = strdup(res);
}
break;
+ case SND_CONFIG_TYPE_INTEGER64:
+ {
+ char res[32];
+ int err;
+ err = snprintf(res, sizeof(res), "%Li", config->u.integer64);
+ if (err < 0 || err == sizeof(res)) {
+ assert(0);
+ return -ENOMEM;
+ }
+ *ascii = strdup(res);
+ }
+ break;
case SND_CONFIG_TYPE_REAL:
{
char res[32];
snd_config_set_integer(*dst, v);
break;
}
+ case SND_CONFIG_TYPE_INTEGER64:
+ {
+ long long v;
+ err = snd_config_get_integer64(src, &v);
+ assert(err >= 0);
+ snd_config_set_integer64(*dst, v);
+ break;
+ }
case SND_CONFIG_TYPE_REAL:
{
double v;
return err;
break;
}
+ case SND_CONFIG_TYPE_INTEGER64:
+ {
+ long long v;
+ err = snd_config_get_integer64(src, &v);
+ assert(err >= 0);
+ err = snd_config_imake_integer64(dst, id, v);
+ if (err < 0)
+ return err;
+ break;
+ }
case SND_CONFIG_TYPE_REAL:
{
double v;
err = snd_config_set_integer(sub, v);
if (err < 0)
goto _err;
+ } else if (strcmp(tmp, "integer64") == 0) {
+ long long v;
+ err = snd_config_make(&sub, var, SND_CONFIG_TYPE_INTEGER64);
+ if (err < 0)
+ goto _err;
+ err = safe_strtoll(val, &v);
+ if (err < 0) {
+ SNDERR("Parameter %s must be an integer", var);
+ goto _err;
+ }
+ err = snd_config_set_integer64(sub, v);
+ if (err < 0)
+ goto _err;
} else if (strcmp(tmp, "real") == 0) {
double v;
err = snd_config_make(&sub, var, SND_CONFIG_TYPE_REAL);