Fixed length double array parser
Former-commit-id: b8ca0383db343d217c8eecc30cfdd2d4238da508
This commit is contained in:
parent
8e10f38ab5
commit
51fe6a0b52
|
@ -13,6 +13,7 @@
|
||||||
#define LATTICESUMS32
|
#define LATTICESUMS32
|
||||||
#include <qpms/translations.h>
|
#include <qpms/translations.h>
|
||||||
#include <qpms/lattices.h>
|
#include <qpms/lattices.h>
|
||||||
|
#include <qpms/qpms_error.h>
|
||||||
#include <gsl/gsl_const_mksa.h>
|
#include <gsl/gsl_const_mksa.h>
|
||||||
|
|
||||||
// Command line order:
|
// Command line order:
|
||||||
|
@ -24,6 +25,61 @@
|
||||||
// Output data format (line):
|
// Output data format (line):
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/** Parse a given number of doubles from a string.
|
||||||
|
*
|
||||||
|
* The doubles can be separated by whitespaces, comma or semicolon.
|
||||||
|
*
|
||||||
|
* \return If the string included up to n doubles, number of parsed doubles.
|
||||||
|
* If more, n+1.
|
||||||
|
*/
|
||||||
|
size_t qpms_parse_ndoubles(
|
||||||
|
double *target,
|
||||||
|
size_t n,
|
||||||
|
const char *orig
|
||||||
|
) {
|
||||||
|
QPMS_ENSURE(target, "The target parameter must not be NULL");
|
||||||
|
char * const dup = strdup(orig);
|
||||||
|
QPMS_ENSURE(dup, "Memory error in a strdup() call.");
|
||||||
|
|
||||||
|
// Replace commas and semicolons with whitespaces
|
||||||
|
for (char *c = dup; *c; ++c)
|
||||||
|
if (*c == ',' || *c == ';')
|
||||||
|
*c = ' ';
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
const char *beg = dup;
|
||||||
|
while(*beg) {
|
||||||
|
char *endptr;
|
||||||
|
double parsed = strtod(beg, endptr);
|
||||||
|
if (endptr > beg) {
|
||||||
|
if (i >= n) {
|
||||||
|
errno = EOVERFLOW;
|
||||||
|
QPMS_WARN("Supplied string contains additional numbers"
|
||||||
|
" (expected only %zd numbers): %s\n", n, beg);
|
||||||
|
goto qpms_parse_ndoubles_cleanup;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
target[i] = parsed;
|
||||||
|
++i;
|
||||||
|
beg = endptr;
|
||||||
|
} else {
|
||||||
|
while (*beg) {
|
||||||
|
if (!isspace(*beg)) {
|
||||||
|
QPMS_WARN("Invalid character (expected a double), leaving the rest of the string unprocessed: %s\n", beg);
|
||||||
|
errno = EILSEQ;
|
||||||
|
goto qpms_parse_ndoubles_cleanup;
|
||||||
|
}
|
||||||
|
++beg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qpms_parse_ndoubles_cleanup:
|
||||||
|
free(dup);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO move to qpmslib later.
|
// TODO move to qpmslib later.
|
||||||
/** Parse doubles from a string.
|
/** Parse doubles from a string.
|
||||||
|
@ -56,9 +112,10 @@ size_t qpms_parse_doubles(
|
||||||
*c = ' ';
|
*c = ' ';
|
||||||
|
|
||||||
size_t i = start_index;
|
size_t i = start_index;
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
const char *beg = dup;
|
const char *beg = dup;
|
||||||
do {
|
while(*beg) {
|
||||||
char *endptr;
|
char *endptr;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
double parsed = strtod(beg, endptr);
|
double parsed = strtod(beg, endptr);
|
||||||
|
@ -69,6 +126,7 @@ size_t qpms_parse_doubles(
|
||||||
capacity *= 2;
|
capacity *= 2;
|
||||||
QPMS_CRASHING_REALLOC(*target, capacity * sizeof(double));
|
QPMS_CRASHING_REALLOC(*target, capacity * sizeof(double));
|
||||||
}
|
}
|
||||||
|
beg = endptr;
|
||||||
} else {
|
} else {
|
||||||
while (*beg) {
|
while (*beg) {
|
||||||
if (!isspace(*beg)) {
|
if (!isspace(*beg)) {
|
||||||
|
@ -79,6 +137,7 @@ size_t qpms_parse_doubles(
|
||||||
++beg;
|
++beg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qpms_parse_doubles_cleanup:
|
qpms_parse_doubles_cleanup:
|
||||||
free(dup);
|
free(dup);
|
||||||
|
|
Loading…
Reference in New Issue