2 #include "qpms_error.h"
9 size_t qpms_parse_ndoubles(
14 QPMS_ENSURE(target
, "The target parameter must not be NULL");
15 char * const dup
= strdup(orig
);
16 QPMS_ENSURE(dup
, "Memory error in a strdup() call.");
18 // Replace commas and semicolons with whitespaces
19 for (char *c
= dup
; *c
; ++c
)
20 if (*c
== ',' || *c
== ';')
26 const char *beg
= dup
;
29 double parsed
= strtod(beg
, &endptr
);
33 if (i
== n
) QPMS_WARN("Supplied string contains additional numbers"
34 " (expected only %zd numbers): %s\n", n
, beg
);
43 QPMS_WARN("Invalid character (expected a double), leaving the rest of the string unprocessed: %s\n", beg
);
45 goto qpms_parse_ndoubles_cleanup
;
52 qpms_parse_ndoubles_cleanup
:
58 size_t qpms_parse_doubles(
63 QPMS_ENSURE(target
, "The target parameter must not be NULL");
64 char * const dup
= strdup(orig
);
65 QPMS_ENSURE(dup
, "Memory error in a strdup() call.");
67 size_t capacity
= start_index
* 2;
68 if (capacity
< 128) capacity
= 128;
70 // Replace commas and semicolons with whitespaces
71 for (char *c
= dup
; *c
; ++c
)
72 if (*c
== ',' || *c
== ';')
75 size_t i
= start_index
;
78 const char *beg
= dup
;
82 double parsed
= strtod(beg
, &endptr
);
84 (*target
)[i
] = parsed
;
88 QPMS_CRASHING_REALLOC(*target
, capacity
* sizeof(double));
94 QPMS_WARN("Invalid character (expected a double), leaving the rest of the string unprocessed: %s\n", beg
);
96 goto qpms_parse_doubles_cleanup
;
103 qpms_parse_doubles_cleanup
:
109 size_t qpms_parse_doubles_fromfile(
111 size_t start_index
, //< Starting index for writing the parsed values.
112 const char *filepath
//< File to read from, or NULL, "", "-" to read from stdin.
114 QPMS_ENSURE(target
, "The target parameter must not be NULL");
118 if (!filepath
|| !strcmp(filepath
, "-") || filepath
[0]=='\0')
121 QPMS_ENSURE(src
= fopen(filepath
, "f"),
122 "Could not open file %s: %s", filepath
, strerror(errno
));
126 while (1 == (scanresult
= fscanf(src
, "%1023s", buf
)))
127 start_index
= qpms_parse_doubles(target
, start_index
, buf
);
129 if (errno
) QPMS_WARN("Problem reading %s: %s",
130 (src
==stdin
) ? "stdin" : filepath
, strerror(errno
));
132 qpms_parse_doubles_files_cleanup
:
134 QPMS_ENSURE(!fclose(src
),
135 "Could not close file %s: %s", filepath
, strerror(errno
));