Previous bindings for C++ and other languages lacked support for the
uint32_t data type for config keys. Which terminated the program with
the message:
Exception: internal error
The following PulseView commands reproduced the issue:
$ pulseview -i /dev/null -I csv:single_column=1
$ pulseview -i /dev/null -I csv:first_column=1
$ pulseview -i /dev/null -I csv:logic_channels=1
$ pulseview -i /dev/null -I csv:start_line=1
$ pulseview -i /dev/null -I saleae:wordsize=1
$ pulseview -i /dev/null -I saleae:logic_channels=1
$ pulseview -i /dev/null -I vcd:numchannels=1
Add support for uint32_t data types in the C++, Python, and Ruby
language bindings.
[ gsi: separate stou32() helper ]
+// Conversion from text to uint32_t, including a range check.
+// This is sigrok specific, _not_ part of any C++ standard library.
+static uint32_t stou32(const std::string &str)
+{
+ unsigned long ret;
+ errno = 0;
+ ret = stoul(str);
+ if (errno == ERANGE)
+ throw std::out_of_range("stou32");
+ if (ret > std::numeric_limits<uint32_t>::max())
+ throw std::out_of_range("stou32");
+ return ret;
+}
+
Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt)
{
GVariant *variant;
Glib::VariantBase ConfigKey::parse_string(std::string value, enum sr_datatype dt)
{
GVariant *variant;
throw Error(SR_ERR_ARG);
}
break;
throw Error(SR_ERR_ARG);
}
break;
+ case SR_T_UINT32:
+ try {
+ variant = g_variant_new_uint32(stou32(value));
+ } catch (invalid_argument&) {
+ throw Error(SR_ERR_ARG);
+ }
+ break;
default:
throw Error(SR_ERR_BUG);
}
default:
throw Error(SR_ERR_BUG);
}
dt = SR_T_FLOAT;
} else if (g_variant_is_of_type(tmpl, G_VARIANT_TYPE_INT32)) {
dt = SR_T_INT32;
dt = SR_T_FLOAT;
} else if (g_variant_is_of_type(tmpl, G_VARIANT_TYPE_INT32)) {
dt = SR_T_INT32;
+ } else if (g_variant_is_of_type(tmpl, G_VARIANT_TYPE_UINT32)) {
+ dt = SR_T_UINT32;
} else {
throw Error(SR_ERR_BUG);
}
} else {
throw Error(SR_ERR_BUG);
}
return Glib::Variant<double>::create(PyFloat_AsDouble(input));
else if (type == SR_T_INT32 && PyInt_Check(input))
return Glib::Variant<gint32>::create(PyInt_AsLong(input));
return Glib::Variant<double>::create(PyFloat_AsDouble(input));
else if (type == SR_T_INT32 && PyInt_Check(input))
return Glib::Variant<gint32>::create(PyInt_AsLong(input));
+ else if (type == SR_T_UINT32 && PyInt_Check(input))
+ return Glib::Variant<guint32>::create(PyInt_AsLong(input));
else if ((type == SR_T_RATIONAL_VOLT) && PyTuple_Check(input) && (PyTuple_Size(input) == 2)) {
PyObject *numObj = PyTuple_GetItem(input, 0);
PyObject *denomObj = PyTuple_GetItem(input, 1);
else if ((type == SR_T_RATIONAL_VOLT) && PyTuple_Check(input) && (PyTuple_Size(input) == 2)) {
PyObject *numObj = PyTuple_GetItem(input, 0);
PyObject *denomObj = PyTuple_GetItem(input, 1);
return Glib::Variant<double>::create(PyFloat_AsDouble(input));
else if (type == G_VARIANT_TYPE_INT32 && PyInt_Check(input))
return Glib::Variant<gint32>::create(PyInt_AsLong(input));
return Glib::Variant<double>::create(PyFloat_AsDouble(input));
else if (type == G_VARIANT_TYPE_INT32 && PyInt_Check(input))
return Glib::Variant<gint32>::create(PyInt_AsLong(input));
+ else if (type == G_VARIANT_TYPE_UINT32 && PyInt_Check(input))
+ return Glib::Variant<guint32>::create(PyInt_AsLong(input));
else
throw sigrok::Error(SR_ERR_ARG);
}
else
throw sigrok::Error(SR_ERR_ARG);
}
return Glib::Variant<double>::create(RFLOAT_VALUE(input));
else if (type == SR_T_INT32 && RB_TYPE_P(input, T_FIXNUM))
return Glib::Variant<gint32>::create(NUM2INT(input));
return Glib::Variant<double>::create(RFLOAT_VALUE(input));
else if (type == SR_T_INT32 && RB_TYPE_P(input, T_FIXNUM))
return Glib::Variant<gint32>::create(NUM2INT(input));
+ else if (type == SR_T_UINT32 && RB_TYPE_P(input, T_FIXNUM))
+ return Glib::Variant<guint32>::create(NUM2UINT(input));
else
throw sigrok::Error(SR_ERR_ARG);
}
else
throw sigrok::Error(SR_ERR_ARG);
}
return Glib::Variant<double>::create(RFLOAT_VALUE(input));
else if (variant.is_of_type(Glib::VARIANT_TYPE_INT32) && RB_TYPE_P(input, T_FIXNUM))
return Glib::Variant<gint32>::create(NUM2INT(input));
return Glib::Variant<double>::create(RFLOAT_VALUE(input));
else if (variant.is_of_type(Glib::VARIANT_TYPE_INT32) && RB_TYPE_P(input, T_FIXNUM))
return Glib::Variant<gint32>::create(NUM2INT(input));
+ else if (variant.is_of_type(Glib::VARIANT_TYPE_UINT32) && RB_TYPE_P(input, T_FIXNUM))
+ return Glib::Variant<guint32>::create(NUM2UINT(input));
else
throw sigrok::Error(SR_ERR_ARG);
}
else
throw sigrok::Error(SR_ERR_ARG);
}
SR_T_DOUBLE_RANGE,
SR_T_INT32,
SR_T_MQ,
SR_T_DOUBLE_RANGE,
SR_T_INT32,
SR_T_MQ,
/* Update sr_variant_type_get() (hwdriver.c) upon changes! */
};
/* Update sr_variant_type_get() (hwdriver.c) upon changes! */
};
switch (datatype) {
case SR_T_INT32:
return G_VARIANT_TYPE_INT32;
switch (datatype) {
case SR_T_INT32:
return G_VARIANT_TYPE_INT32;
+ case SR_T_UINT32:
+ return G_VARIANT_TYPE_UINT32;
case SR_T_UINT64:
return G_VARIANT_TYPE_UINT64;
case SR_T_STRING:
case SR_T_UINT64:
return G_VARIANT_TYPE_UINT64;
case SR_T_STRING: