mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-28 05:00:20 +00:00
parser: remove int_or_float union & other small float-parsing cleanups
Owing to bitrot, this union only contained a float and therefore is pointless. Let's remove it. That makes the function name "integer_or_float()" non-sensical. Call it "parse_float()" instead. Moreover, change the output-arguments of "parse_float()" from pointers to references, as null-pointers are not supported. Finally, remove the "errno" check after "ascii_strtod()". As far as I can tell, errno is not set in "ascii_strtod()" and using a global variable for error-reporting it is an incredibly silly interface anyway. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
38a0050ac3
commit
628e2fe933
1 changed files with 45 additions and 51 deletions
|
@ -10,7 +10,6 @@
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
|
@ -151,16 +150,15 @@ enum number_type {
|
||||||
FLOATVAL
|
FLOATVAL
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum number_type parse_float(const char *buffer, double *res, const char **endp)
|
static enum number_type parse_float(const char *buffer, double &res, const char *&endp)
|
||||||
{
|
{
|
||||||
double val;
|
double val;
|
||||||
static bool first_time = true;
|
static bool first_time = true;
|
||||||
|
|
||||||
errno = 0;
|
val = ascii_strtod(buffer, &endp);
|
||||||
val = ascii_strtod(buffer, endp);
|
if (endp == buffer)
|
||||||
if (errno || *endp == buffer)
|
|
||||||
return NEITHER;
|
return NEITHER;
|
||||||
if (**endp == ',') {
|
if (*endp == ',') {
|
||||||
if (nearly_equal(val, rint(val))) {
|
if (nearly_equal(val, rint(val))) {
|
||||||
/* we really want to send an error if this is a Subsurface native file
|
/* we really want to send an error if this is a Subsurface native file
|
||||||
* as this is likely indication of a bug - but right now we don't have
|
* as this is likely indication of a bug - but right now we don't have
|
||||||
|
@ -170,46 +168,42 @@ static enum number_type parse_float(const char *buffer, double *res, const char
|
||||||
first_time = false;
|
first_time = false;
|
||||||
}
|
}
|
||||||
/* Try again in permissive mode*/
|
/* Try again in permissive mode*/
|
||||||
val = strtod_flags(buffer, endp, 0);
|
val = strtod_flags(buffer, &endp, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*res = val;
|
res = val;
|
||||||
return FLOATVAL;
|
return FLOATVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
union int_or_float {
|
static enum number_type parse_float(const char *buffer, double &res)
|
||||||
double fp;
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum number_type integer_or_float(const char *buffer, union int_or_float *res)
|
|
||||||
{
|
{
|
||||||
const char *end;
|
const char *end;
|
||||||
return parse_float(buffer, &res->fp, &end);
|
return parse_float(buffer, res, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pressure(const char *buffer, pressure_t *pressure, struct parser_state *state)
|
static void pressure(const char *buffer, pressure_t *pressure, struct parser_state *state)
|
||||||
{
|
{
|
||||||
double mbar = 0.0;
|
double mbar = 0.0;
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
/* Just ignore zero values */
|
/* Just ignore zero values */
|
||||||
if (!val.fp)
|
if (!val)
|
||||||
break;
|
break;
|
||||||
switch (state->xml_parsing_units.pressure) {
|
switch (state->xml_parsing_units.pressure) {
|
||||||
case units::PASCALS:
|
case units::PASCALS:
|
||||||
mbar = val.fp / 100;
|
mbar = val / 100;
|
||||||
break;
|
break;
|
||||||
case units::BAR:
|
case units::BAR:
|
||||||
/* Assume mbar, but if it's really small, it's bar */
|
/* Assume mbar, but if it's really small, it's bar */
|
||||||
mbar = val.fp;
|
mbar = val;
|
||||||
if (fabs(mbar) < 5000)
|
if (fabs(mbar) < 5000)
|
||||||
mbar = mbar * 1000;
|
mbar = mbar * 1000;
|
||||||
break;
|
break;
|
||||||
case units::PSI:
|
case units::PSI:
|
||||||
mbar = psi_to_mbar(val.fp);
|
mbar = psi_to_mbar(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (fabs(mbar) > 5 && fabs(mbar) < 5000000) {
|
if (fabs(mbar) > 5 && fabs(mbar) < 5000000) {
|
||||||
|
@ -247,10 +241,10 @@ static void cylinder_use(const char *buffer, enum cylinderuse *cyl_use, struct p
|
||||||
|
|
||||||
static void salinity(const char *buffer, int *salinity)
|
static void salinity(const char *buffer, int *salinity)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
*salinity = lrint(val.fp * 10.0);
|
*salinity = lrint(val * 10.0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
report_info("Strange salinity reading %s", buffer);
|
report_info("Strange salinity reading %s", buffer);
|
||||||
|
@ -259,16 +253,16 @@ static void salinity(const char *buffer, int *salinity)
|
||||||
|
|
||||||
static void depth(const char *buffer, depth_t *depth, struct parser_state *state)
|
static void depth(const char *buffer, depth_t *depth, struct parser_state *state)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
switch (state->xml_parsing_units.length) {
|
switch (state->xml_parsing_units.length) {
|
||||||
case units::METERS:
|
case units::METERS:
|
||||||
depth->mm = lrint(val.fp * 1000);
|
depth->mm = lrint(val * 1000.0);
|
||||||
break;
|
break;
|
||||||
case units::FEET:
|
case units::FEET:
|
||||||
depth->mm = feet_to_mm(val.fp);
|
depth->mm = feet_to_mm(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -292,16 +286,16 @@ static void extra_data_end(struct parser_state *state)
|
||||||
|
|
||||||
static void weight(const char *buffer, weight_t *weight, struct parser_state *state)
|
static void weight(const char *buffer, weight_t *weight, struct parser_state *state)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
switch (state->xml_parsing_units.weight) {
|
switch (state->xml_parsing_units.weight) {
|
||||||
case units::KG:
|
case units::KG:
|
||||||
weight->grams = lrint(val.fp * 1000);
|
weight->grams = lrint(val * 1000.0);
|
||||||
break;
|
break;
|
||||||
case units::LBS:
|
case units::LBS:
|
||||||
weight->grams = lbs_to_grams(val.fp);
|
weight->grams = lbs_to_grams(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -312,19 +306,19 @@ static void weight(const char *buffer, weight_t *weight, struct parser_state *st
|
||||||
|
|
||||||
static void temperature(const char *buffer, temperature_t *temperature, struct parser_state *state)
|
static void temperature(const char *buffer, temperature_t *temperature, struct parser_state *state)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
switch (state->xml_parsing_units.temperature) {
|
switch (state->xml_parsing_units.temperature) {
|
||||||
case units::KELVIN:
|
case units::KELVIN:
|
||||||
temperature->mkelvin = lrint(val.fp * 1000);
|
temperature->mkelvin = lrint(val * 1000.0);
|
||||||
break;
|
break;
|
||||||
case units::CELSIUS:
|
case units::CELSIUS:
|
||||||
temperature->mkelvin = C_to_mkelvin(val.fp);
|
temperature->mkelvin = C_to_mkelvin(val);
|
||||||
break;
|
break;
|
||||||
case units::FAHRENHEIT:
|
case units::FAHRENHEIT:
|
||||||
temperature->mkelvin = F_to_mkelvin(val.fp);
|
temperature->mkelvin = F_to_mkelvin(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -396,7 +390,7 @@ static void percent(const char *buffer, fraction_t *fraction)
|
||||||
double val;
|
double val;
|
||||||
const char *end;
|
const char *end;
|
||||||
|
|
||||||
switch (parse_float(buffer, &val, &end)) {
|
switch (parse_float(buffer, val, end)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
/* Turn fractions into percent unless explicit.. */
|
/* Turn fractions into percent unless explicit.. */
|
||||||
if (val <= 1.0) {
|
if (val <= 1.0) {
|
||||||
|
@ -432,11 +426,11 @@ static void gasmix_nitrogen(const char *, struct gasmix *)
|
||||||
|
|
||||||
static void cylindersize(const char *buffer, volume_t *volume)
|
static void cylindersize(const char *buffer, volume_t *volume)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
volume->mliter = lrint(val.fp * 1000);
|
volume->mliter = lrint(val * 1000.0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -608,16 +602,16 @@ static void get_notrip(const char *buffer, bool *notrip)
|
||||||
*/
|
*/
|
||||||
static void fahrenheit(const char *buffer, temperature_t *temperature)
|
static void fahrenheit(const char *buffer, temperature_t *temperature)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
if (nearly_equal(val.fp, 32.0))
|
if (nearly_equal(val, 32.0))
|
||||||
break;
|
break;
|
||||||
if (val.fp < 32.0)
|
if (val < 32.0)
|
||||||
temperature->mkelvin = C_to_mkelvin(val.fp);
|
temperature->mkelvin = C_to_mkelvin(val);
|
||||||
else
|
else
|
||||||
temperature->mkelvin = F_to_mkelvin(val.fp);
|
temperature->mkelvin = F_to_mkelvin(val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
report_info("Crazy Diving Log temperature reading %s", buffer);
|
report_info("Crazy Diving Log temperature reading %s", buffer);
|
||||||
|
@ -646,14 +640,14 @@ static void fahrenheit(const char *buffer, temperature_t *temperature)
|
||||||
*/
|
*/
|
||||||
static void psi_or_bar(const char *buffer, pressure_t *pressure)
|
static void psi_or_bar(const char *buffer, pressure_t *pressure)
|
||||||
{
|
{
|
||||||
union int_or_float val;
|
double val;
|
||||||
|
|
||||||
switch (integer_or_float(buffer, &val)) {
|
switch (parse_float(buffer, val)) {
|
||||||
case FLOATVAL:
|
case FLOATVAL:
|
||||||
if (val.fp > 400)
|
if (val > 400)
|
||||||
pressure->mbar = psi_to_mbar(val.fp);
|
pressure->mbar = psi_to_mbar(val);
|
||||||
else
|
else
|
||||||
pressure->mbar = lrint(val.fp * 1000);
|
pressure->mbar = lrint(val * 1000);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
report_info("Crazy Diving Log PSI reading %s", buffer);
|
report_info("Crazy Diving Log PSI reading %s", buffer);
|
||||||
|
|
Loading…
Reference in a new issue