Separate double parsing functions.
Former-commit-id: 809f28b4b0c4bfba98a2981abf2c17c0ea0a0e65
This commit is contained in:
parent
7218a8ce4b
commit
44b5e4df79
|
@ -15,6 +15,7 @@
|
|||
#include <qpms/lattices.h>
|
||||
#include <qpms/qpms_error.h>
|
||||
#include <gsl/gsl_const_mksa.h>
|
||||
#include <qpms/parsing.h>
|
||||
|
||||
// Command line order:
|
||||
// outfile b1.x b1.y b2.x b2.y lMax scuffomega refindex npart part0.x part0.y [part1.x part1.y [...]]
|
||||
|
@ -25,168 +26,6 @@
|
|||
// 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;
|
||||
if (i == n) QPMS_WARN("Supplied string contains additional numbers"
|
||||
" (expected only %zd numbers): %s\n", n, beg);
|
||||
}
|
||||
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.
|
||||
/** Parse doubles from a string.
|
||||
*
|
||||
* The doubles can be separated by whitespaces, comma or semicolon.
|
||||
* The parsed numbers are saved into an array specified by *target
|
||||
* that has been preallocated with malloc() to contain at least start_index
|
||||
* members. If start_index is nonzero, the newly parsed numbers are
|
||||
* saved to the positions starting from start_index.
|
||||
*
|
||||
* If *target is NULL, the function allocates the necessary space.
|
||||
*
|
||||
* \return Number of newly parsed doubles + start_index.
|
||||
*/
|
||||
size_t qpms_parse_doubles(
|
||||
double **target,
|
||||
size_t start_index,
|
||||
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.");
|
||||
|
||||
size_t capacity = start_index * 2;
|
||||
if (capacity < 128) capacity = 128;
|
||||
|
||||
// Replace commas and semicolons with whitespaces
|
||||
for (char *c = dup; *c; ++c)
|
||||
if (*c == ',' || *c == ';')
|
||||
*c = ' ';
|
||||
|
||||
size_t i = start_index;
|
||||
errno = 0;
|
||||
|
||||
const char *beg = dup;
|
||||
while(*beg) {
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
double parsed = strtod(beg, endptr);
|
||||
if (endptr > beg) {
|
||||
(*target)[i] = parsed;
|
||||
++i;
|
||||
if (i >= capacity) {
|
||||
capacity *= 2;
|
||||
QPMS_CRASHING_REALLOC(*target, capacity * sizeof(double));
|
||||
}
|
||||
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_doubles_cleanup;
|
||||
}
|
||||
++beg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qpms_parse_doubles_cleanup:
|
||||
free(dup);
|
||||
return i;
|
||||
}
|
||||
|
||||
/** Parse doubles from a file.
|
||||
*
|
||||
* The doubles can be separated by whitespaces, comma or semicolon.
|
||||
* The parsed numbers are saved into an array specified by *target
|
||||
* that has been preallocated with malloc() to contain at least start_index
|
||||
* members. If start_index is nonzero, the newly parsed numbers are
|
||||
* saved to the positions starting from start_index.
|
||||
*
|
||||
* If *target is NULL, the function allocates the necessary space.
|
||||
*
|
||||
* If filepath is NULL, "" or "-", read from stdin.
|
||||
*
|
||||
* \return Number of newly parsed doubles + start_index.
|
||||
*/
|
||||
size_t qpms_parse_doubles_fromfile(
|
||||
double **target,
|
||||
size_t start_index, //< Starting index for writing the parsed values.
|
||||
const char *filepath //< File to read from, or NULL, "", "-" to read from stdin.
|
||||
) {
|
||||
QPMS_ENSURE(target, "The target parameter must not be NULL");
|
||||
|
||||
FILE *src;
|
||||
|
||||
if (!filepath || !strcmp(filepath, "-") || filepath[0]=='\0')
|
||||
src = stdin;
|
||||
else
|
||||
QPMS_ENSURE(src = fopen(filepath, "f"),
|
||||
"Could not open file %s: %s", filepath, strerror(errno));
|
||||
|
||||
char buf[1024];
|
||||
int scanresult;
|
||||
while (1 == (scanresult = fscanf(src, "%1023s", buf)))
|
||||
start_index = qpms_parse_doubles(target, start_index, buf);
|
||||
|
||||
if (errno) QPMS_WARN("Problem reading %s: %s",
|
||||
(src==stdin) ? "stdin" : filepath, strerror(errno));
|
||||
|
||||
qpms_parse_doubles_files_cleanup:
|
||||
if (src != stdin)
|
||||
QPMS_ENSURE(!fclose(src),
|
||||
"Could not close file %s: %s", filepath, strerror(errno));
|
||||
|
||||
return start_index;
|
||||
}
|
||||
#define MAXKCOUNT 200 // 200 // serves as klist default buffer size
|
||||
//#define KMINCOEFF 0.783 //0.9783 // 0.783 // not used if KSTDIN defined
|
||||
//#define KMAXCOEFF 1.217 //1.0217 // 1.217 // not used if KSTDIN defined
|
||||
|
|
|
@ -12,7 +12,7 @@ include_directories(${DIRS})
|
|||
|
||||
add_library (qpms translations.c tmatrices.c vecprint.c vswf.c wigner.c
|
||||
lattices2d.c gaunt.c error.c legendre.c symmetries.c vecprint.c
|
||||
bessel.c own_zgemm.c)
|
||||
bessel.c own_zgemm.c parsing.c)
|
||||
use_c99()
|
||||
|
||||
set(LIBS ${LIBS} ${GSL_LIBRARIES} ${GSLCBLAS_LIBRARIES})
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#include "parsing.h"
|
||||
#include "qpms_error.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
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;
|
||||
if (i == n) QPMS_WARN("Supplied string contains additional numbers"
|
||||
" (expected only %zd numbers): %s\n", n, beg);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
size_t qpms_parse_doubles(
|
||||
double **target,
|
||||
size_t start_index,
|
||||
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.");
|
||||
|
||||
size_t capacity = start_index * 2;
|
||||
if (capacity < 128) capacity = 128;
|
||||
|
||||
// Replace commas and semicolons with whitespaces
|
||||
for (char *c = dup; *c; ++c)
|
||||
if (*c == ',' || *c == ';')
|
||||
*c = ' ';
|
||||
|
||||
size_t i = start_index;
|
||||
errno = 0;
|
||||
|
||||
const char *beg = dup;
|
||||
while(*beg) {
|
||||
char *endptr;
|
||||
errno = 0;
|
||||
double parsed = strtod(beg, &endptr);
|
||||
if (endptr > beg) {
|
||||
(*target)[i] = parsed;
|
||||
++i;
|
||||
if (i >= capacity) {
|
||||
capacity *= 2;
|
||||
QPMS_CRASHING_REALLOC(*target, capacity * sizeof(double));
|
||||
}
|
||||
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_doubles_cleanup;
|
||||
}
|
||||
++beg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qpms_parse_doubles_cleanup:
|
||||
free(dup);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
size_t qpms_parse_doubles_fromfile(
|
||||
double **target,
|
||||
size_t start_index, //< Starting index for writing the parsed values.
|
||||
const char *filepath //< File to read from, or NULL, "", "-" to read from stdin.
|
||||
) {
|
||||
QPMS_ENSURE(target, "The target parameter must not be NULL");
|
||||
|
||||
FILE *src;
|
||||
|
||||
if (!filepath || !strcmp(filepath, "-") || filepath[0]=='\0')
|
||||
src = stdin;
|
||||
else
|
||||
QPMS_ENSURE(src = fopen(filepath, "f"),
|
||||
"Could not open file %s: %s", filepath, strerror(errno));
|
||||
|
||||
char buf[1024];
|
||||
int scanresult;
|
||||
while (1 == (scanresult = fscanf(src, "%1023s", buf)))
|
||||
start_index = qpms_parse_doubles(target, start_index, buf);
|
||||
|
||||
if (errno) QPMS_WARN("Problem reading %s: %s",
|
||||
(src==stdin) ? "stdin" : filepath, strerror(errno));
|
||||
|
||||
qpms_parse_doubles_files_cleanup:
|
||||
if (src != stdin)
|
||||
QPMS_ENSURE(!fclose(src),
|
||||
"Could not close file %s: %s", filepath, strerror(errno));
|
||||
|
||||
return start_index;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef QPMS_PARSING_H
|
||||
#define QPMS_PARSING_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/** 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
|
||||
);
|
||||
|
||||
/** Parse doubles from a string.
|
||||
*
|
||||
* The doubles can be separated by whitespaces, comma or semicolon.
|
||||
* The parsed numbers are saved into an array specified by *target
|
||||
* that has been preallocated with malloc() to contain at least start_index
|
||||
* members. If start_index is nonzero, the newly parsed numbers are
|
||||
* saved to the positions starting from start_index.
|
||||
*
|
||||
* If *target is NULL, the function allocates the necessary space.
|
||||
*
|
||||
* \return Number of newly parsed doubles + start_index.
|
||||
*/
|
||||
size_t qpms_parse_doubles(
|
||||
double **target,
|
||||
size_t start_index,
|
||||
const char *orig
|
||||
);
|
||||
|
||||
/** Parse doubles from a file.
|
||||
*
|
||||
* The doubles can be separated by whitespaces, comma or semicolon.
|
||||
* The parsed numbers are saved into an array specified by *target
|
||||
* that has been preallocated with malloc() to contain at least start_index
|
||||
* members. If start_index is nonzero, the newly parsed numbers are
|
||||
* saved to the positions starting from start_index.
|
||||
*
|
||||
* If *target is NULL, the function allocates the necessary space.
|
||||
*
|
||||
* If filepath is NULL, "" or "-", read from stdin.
|
||||
*
|
||||
* \return Number of newly parsed doubles + start_index.
|
||||
*/
|
||||
size_t qpms_parse_doubles_fromfile(
|
||||
double **target,
|
||||
size_t start_index, //< Starting index for writing the parsed values.
|
||||
const char *filepath //< File to read from, or NULL, "", "-" to read from stdin.
|
||||
);
|
||||
|
||||
#endif // QPMS_PARSING_H
|
Loading…
Reference in New Issue