summaryrefslogtreecommitdiffstats
path: root/src/bfstd.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-12-02 09:23:45 -0500
committerTavian Barnes <tavianator@tavianator.com>2024-12-02 16:34:26 -0500
commit9606eabd82e6523ffb8ab8b3eeb405f24e3e2346 (patch)
treefc7e21688361bc15f8492b30cd7b381a07ba0fec /src/bfstd.c
parent46e0c0bccbee21903efc9c924874970e251dde48 (diff)
downloadbfs-9606eabd82e6523ffb8ab8b3eeb405f24e3e2346.tar.xz
bfstd: Add more strto*() wrappers
Diffstat (limited to 'src/bfstd.c')
-rw-r--r--src/bfstd.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/src/bfstd.c b/src/bfstd.c
index b58d69e..738c956 100644
--- a/src/bfstd.c
+++ b/src/bfstd.c
@@ -211,35 +211,77 @@ const char *xgetprogname(void) {
return cmd;
}
-int xstrtoll(const char *str, char **end, int base, long long *value) {
- // strtoll() skips leading spaces, but we want to reject them
+/** Common prologue for xstrto*() wrappers. */
+static int xstrtox_prologue(const char *str) {
+ // strto*() skips leading spaces, but we want to reject them
if (xisspace(str[0])) {
errno = EINVAL;
return -1;
}
- // If end is NULL, make sure the entire string is valid
- bool entire = !end;
- char *endp;
- if (!end) {
- end = &endp;
- }
-
errno = 0;
- long long result = strtoll(str, end, base);
+ return 0;
+}
+
+/** Common epilogue for xstrto*() wrappers. */
+static int xstrtox_epilogue(const char *str, char **end, char *endp) {
if (errno != 0) {
return -1;
}
- if (*end == str || (entire && **end != '\0')) {
+ if (end) {
+ *end = endp;
+ }
+
+ // If end is NULL, make sure the entire string is valid
+ if (endp == str || (!end && *endp != '\0')) {
errno = EINVAL;
return -1;
}
- *value = result;
return 0;
}
+int xstrtol(const char *str, char **end, int base, long *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtol(str, &endp, base);
+ return xstrtox_epilogue(str, end, endp);
+}
+
+int xstrtoll(const char *str, char **end, int base, long long *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtoll(str, &endp, base);
+ return xstrtox_epilogue(str, end, endp);
+}
+
+int xstrtof(const char *str, char **end, float *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtof(str, &endp);
+ return xstrtox_epilogue(str, end, endp);
+}
+
+int xstrtod(const char *str, char **end, double *value) {
+ if (xstrtox_prologue(str) != 0) {
+ return -1;
+ }
+
+ char *endp;
+ *value = strtod(str, &endp);
+ return xstrtox_epilogue(str, end, endp);
+}
+
/** Compile and execute a regular expression for xrpmatch(). */
static int xrpregex(nl_item item, const char *response) {
const char *pattern = nl_langinfo(item);