ps/stacktrace.c \
lib/fileutils.c
+TESTS = lib/test_strtod_nol
+
# lib/test_* binaries
noinst_PROGRAMS = \
lib/test_strutils \
lib/test_fileutils \
lib/test_nsutils \
- lib/test_process
+ lib/test_process \
+ $(TESTS)
lib_test_strutils_SOURCES = lib/test_strutils.c lib/strutils.c
lib_test_strutils_LDADD =
lib_test_process_SOURCES = lib/test_process.c
lib_test_process_LDADD =
+lib_test_strtod_nol_SOURCES = lib/test_strtod_nol.c lib/strutils.c
+lib_test_strtod_nol_LDADD =
+
if EXAMPLE_FILES
sysconf_DATA = sysctl.conf
endif
extern long strtol_or_err(const char *str, const char *errmesg);
extern double strtod_or_err(const char *str, const char *errmesg);
+double strtod_nol_or_err(char *str, const char *errmesg);
#endif
*/
#include <stdlib.h>
+#include <ctype.h>
#include "c.h"
#include "strutils.h"
error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
return 0;
}
+
+/*
+ * Covert a string into a double in a non-locale aware way.
+ * This means the decimal point can be either . or ,
+ * Also means you cannot use the other for thousands separator
+ *
+ * Exits on failure like its other _or_err cousins
+ */
+double strtod_nol_or_err(char *str, const char *errmesg)
+{
+ double num;
+ const char *cp, *radix;
+ double mult;
+ int negative = 0;
+
+ if (str != NULL && *str != '\0') {
+ num = 0.0;
+ cp = str;
+ /* strip leading spaces */
+ while (isspace(*cp))
+ cp++;
+
+ /* get sign */
+ if (*cp == '-') {
+ negative = 1;
+ cp++;
+ } else if (*cp == '+')
+ cp++;
+
+ /* find radix */
+ radix = cp;
+ mult=0.1;
+ while(isdigit(*radix)) {
+ radix++;
+ mult *= 10;
+ }
+ while(isdigit(*cp)) {
+ num += (*cp - '0') * mult;
+ mult /= 10;
+ cp++;
+ }
+ /* got the integers */
+ if (*cp == '\0')
+ return (negative?-num:num);
+ if (*cp != '.' && *cp != ',')
+ error(EXIT_FAILURE, EINVAL, "%s: '%s'", errmesg, str);
+
+ cp++;
+ mult = 0.1;
+ while(isdigit(*cp)) {
+ num += (*cp - '0') * mult;
+ mult /= 10;
+ cp++;
+ }
+ if (*cp == '\0')
+ return (negative?-num:num);
+ }
+ error(EXIT_FAILURE, errno, "%s: '%s'", errmesg, str);
+ return 0;
+}
--- /dev/null
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "strutils.h"
+
+struct strtod_tests {
+ char *string;
+ double result;
+};
+
+struct strtod_tests tests[] = {
+ {"123", 123.0},
+ {"-123", -123.0},
+ {"12.34", 12.34},
+ {"-12.34", -12.34},
+ {".34", 0.34},
+ {"-.34", -0.34},
+ {"12,34", 12.34},
+ {"-12,34", -12.34},
+ {",34", 0.34},
+ {"-,34", -0.34},
+ {"0", 0.0},
+ {".0", 0.0},
+ {"0.0", 0.0},
+ {NULL, 0.0}
+};
+
+
+
+int main(int argc, char *argv[])
+{
+ int i;
+ double val;
+
+ for(i=0; tests[i].string != NULL; i++) {
+ if(strtod_nol_or_err(tests[i].string, "Cannot parse number") !=
+ tests[i].result) {
+ fprintf(stderr, "FAIL: strtod_nol_or_err(\"%s\") != %f\n",
+ tests[i].string, tests[i].result);
+ return EXIT_FAILURE;
+ }
+ //fprintf(stderr, "PASS: strtod_nol for %s\n", tests[i].string);
+ }
+ return EXIT_SUCCESS;
+}