aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--doubletotimespec.c12
-rw-r--r--doubletotimeval.c12
-rw-r--r--libsimple.c112
-rw-r--r--libsimple.h13
-rw-r--r--minimise_number_string.c130
-rw-r--r--timespectostr.c4
-rw-r--r--timevaltostr.c4
8 files changed, 276 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 42f7f4d..50b8ca9 100644
--- a/Makefile
+++ b/Makefile
@@ -26,6 +26,7 @@ OBJ =\
memrchr.o\
memrmem.o\
memstarts.o\
+ minimise_number_string.o\
multimespec.o\
multimeval.o\
rawmemchr.o\
@@ -67,6 +68,7 @@ TESTS =\
memrchr.test\
memrmem.test\
memstarts.test\
+ minimise_number_string.test\
rawmemchr.test\
rawmemrchr.test\
strcaseends.test\
diff --git a/doubletotimespec.c b/doubletotimespec.c
index e74f04a..a71d662 100644
--- a/doubletotimespec.c
+++ b/doubletotimespec.c
@@ -3,7 +3,7 @@
void
-libsimple_doubletotimespec(struct timespec *ts, double d) /* TODO test */
+libsimple_doubletotimespec(struct timespec *ts, double d)
{
double ns = (long long int)d;
long int nsi;
@@ -16,7 +16,17 @@ libsimple_doubletotimespec(struct timespec *ts, double d) /* TODO test */
nsi = 0;
d += 1;
}
+ } else if (2 * (ns - (double)nsi) <= -1) {
+ nsi -= 1;
+ if (nsi == -1000000000L) {
+ nsi = 0;
+ d -= 1;
+ }
}
ts->tv_sec = (time_t)d;
ts->tv_nsec = nsi;
+ if (ts->tv_nsec < 0) {
+ ts->tv_sec -= 1;
+ ts->tv_nsec += 1000000000L;
+ }
}
diff --git a/doubletotimeval.c b/doubletotimeval.c
index c86c771..5396897 100644
--- a/doubletotimeval.c
+++ b/doubletotimeval.c
@@ -3,7 +3,7 @@
void
-libsimple_doubletotimeval(struct timeval *tv, double d) /* TODO test */
+libsimple_doubletotimeval(struct timeval *tv, double d)
{
double ns = (long long int)d;
long int nsi;
@@ -16,7 +16,17 @@ libsimple_doubletotimeval(struct timeval *tv, double d) /* TODO test */
nsi = 0;
d += 1;
}
+ } else if (2 * (ns - (double)nsi) <= -1) {
+ nsi -= 1;
+ if (nsi == -1000000L) {
+ nsi = 0;
+ d -= 1;
+ }
}
tv->tv_sec = (time_t)d;
tv->tv_usec = nsi;
+ if (tv->tv_usec < 0) {
+ tv->tv_sec -= 1;
+ tv->tv_usec += 1000000L;
+ }
}
diff --git a/libsimple.c b/libsimple.c
index fd7f779..15326d1 100644
--- a/libsimple.c
+++ b/libsimple.c
@@ -9,6 +9,90 @@ int libsimple_default_failure_exit = 1;
#else
#include "test.h"
+static int
+test_timespec(double d, time_t sec, long int nsec, double rd, const char *s, const char *ss)
+{
+ char buf[1000], *str;
+ struct timespec t;
+ double dt;
+
+ libsimple_doubletotimespec(&t, d);
+ if (t.tv_sec != sec)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (t.tv_nsec != nsec)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ dt = libsimple_timespectodouble(&t);
+ if (dt < rd - 0.0000000001)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (dt > rd + 0.0000000001)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ str = libsimple_timespectostr(buf, &t);
+ if (str != buf)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, s))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ str = libsimple_timespectostr(NULL, &t);
+ if (!str)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, s))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ strcpy(buf, str);
+ free(str);
+ str = libsimple_minimise_number_string(buf);
+ if (str != buf)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, ss))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ return 1;
+}
+
+static int
+test_timeval(double d, time_t sec, long int usec, double rd, const char *s, const char *ss)
+{
+ char buf[1000], *str;
+ struct timeval t;
+ double dt;
+
+ libsimple_doubletotimeval(&t, d);
+ if (t.tv_sec != sec)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (t.tv_usec != usec)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ dt = libsimple_timevaltodouble(&t);
+ if (dt < rd - 0.0000001)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (dt > rd + 0.0000001)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ str = libsimple_timevaltostr(buf, &t);
+ if (str != buf)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, s))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ str = libsimple_timevaltostr(NULL, &t);
+ if (!str)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, s))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ strcpy(buf, str);
+ free(str);
+ str = libsimple_minimise_number_string(buf);
+ if (str != buf)
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+ if (strcmp(str, ss))
+ return fprintf(stderr, "Failed at %s:%i\n", __FILE__, __LINE__ - 1), 0;
+
+ return 1;
+}
+
int
main(void)
{
@@ -632,11 +716,9 @@ main(void)
unsetenv("X");
assert(!getenv("X"));
assert(!libsimple_getenv_ne("X"));
-
putenv("X=xyz");
assert(!strcmpnul(getenv("X"), "xyz"));
assert(!strcmpnul(libsimple_getenv_ne("X"), "xyz"));
-
putenv("X=");
assert(!strcmpnul(getenv("X"), ""));
assert(!libsimple_getenv_ne("X"));
@@ -644,15 +726,37 @@ main(void)
unsetenv("X");
assert(!getenv("X"));
assert(!strcmpnul(libsimple_getenv_e("X"), ""));
-
putenv("X=xyz");
assert(!strcmpnul(getenv("X"), "xyz"));
assert(!strcmpnul(libsimple_getenv_e("X"), "xyz"));
-
putenv("X=");
assert(!strcmpnul(getenv("X"), ""));
assert(!strcmpnul(libsimple_getenv_e("X"), ""));
+ assert(test_timespec(10.3000200010, 10, 300020001L, 10.300020001, "+10.300020001", "10.300020001"));
+ assert(test_timespec(10.3000200014, 10, 300020001L, 10.300020001, "+10.300020001", "10.300020001"));
+ assert(test_timespec(10.3000200015, 10, 300020002L, 10.300020002, "+10.300020002", "10.300020002"));
+ assert(test_timespec(10.9999999999, 11, 0, 11, "+11.000000000", "11"));
+ assert(test_timespec(-10.3000200010, -11, 699979999L, -10.300020001, "-10.300020001", "-10.300020001"));
+ assert(test_timespec(-10.3000200014, -11, 699979999L, -10.300020001, "-10.300020001", "-10.300020001"));
+ assert(test_timespec(-10.3000200015, -11, 699979998L, -10.300020002, "-10.300020002", "-10.300020002"));
+ assert(test_timespec(-10.9999999999, -11, 0, -11, "-11.000000000", "-11"));
+ assert(test_timespec(10, 10, 0, 10, "+10.000000000", "10"));
+ assert(test_timespec(0, 0, 0, 0, "+0.000000000", "0"));
+ assert(test_timespec(-10, -10, 0, -10, "-10.000000000", "-10"));
+
+ assert(test_timeval(10.3000201000, 10, 300020L, 10.300020, "+10.300020", "10.30002"));
+ assert(test_timeval(10.3000204000, 10, 300020L, 10.300020, "+10.300020", "10.30002"));
+ assert(test_timeval(10.3000205000, 10, 300021L, 10.300021, "+10.300021", "10.300021"));
+ assert(test_timeval(10.9999999000, 11, 0, 11, "+11.000000", "11"));
+ assert(test_timeval(-10.3000201000, -11, 699980L, -10.300020, "-10.300020", "-10.30002"));
+ assert(test_timeval(-10.3000204000, -11, 699980L, -10.300020, "-10.300020", "-10.30002"));
+ assert(test_timeval(-10.3000205000, -11, 699979L, -10.300021, "-10.300021", "-10.300021"));
+ assert(test_timeval(-10.9999999000, -11, 0, -11, "-11.000000", "-11"));
+ assert(test_timeval(10, 10, 0, 10, "+10.000000", "10"));
+ assert(test_timeval(0, 0, 0, 0, "+0.000000", "0"));
+ assert(test_timeval(-10, -10, 0, -10, "-10.000000", "-10"));
+
return 0;
}
diff --git a/libsimple.h b/libsimple.h
index e1ecfdb..4619eef 100644
--- a/libsimple.h
+++ b/libsimple.h
@@ -1157,7 +1157,7 @@ libsimple_eputenvf(const char *__fmt, ...) /* TODO test */
{
va_list __ap;
va_start(__ap, __fmt);
- envputenvf(1, __fmt, __ap);
+ envputenvf(libsimple_default_failure_exit, __fmt, __ap);
va_end(__ap);
}
#ifndef eputenvf
@@ -1410,7 +1410,7 @@ char *libsimple_timevaltostr(char *restrict, const struct timeval *restrict);
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline double
-libsimple_timespectodouble(const struct timespec *__ts) /* TODO test */
+libsimple_timespectodouble(const struct timespec *__ts)
{
double __ret = (double)(__ts->tv_nsec);
__ret /= (double)1000000000L;
@@ -1424,7 +1424,7 @@ libsimple_timespectodouble(const struct timespec *__ts) /* TODO test */
_LIBSIMPLE_GCC_ONLY(__attribute__((__nonnull__)))
static inline double
-libsimple_timevaltodouble(const struct timeval *__tv) /* TODO test */
+libsimple_timevaltodouble(const struct timeval *__tv)
{
double __ret = (double)(__tv->tv_usec);
__ret /= (double)1000000L;
@@ -1450,6 +1450,13 @@ void libsimple_doubletotimeval(struct timeval *, double);
#endif
+_LIBSIMPLE_GCC_ONLY(__attribute__((__returns_nonnull__, __nonnull__)))
+char *libsimple_minimise_number_string(char *);
+#ifndef minimise_number_string
+# define minimise_number_string libsimple_minimise_number_string
+#endif
+
+
#define LIBSIMPLE_UNLIST(LIST, I, NP) libsimple_unlist((LIST), (I), (NP), sizeof(*(LIST)))
#ifndef UNLIST
# define UNLIST(LIST, I, NP) LIBSIMPLE_UNLIST((LIST), (I), (NP))
diff --git a/minimise_number_string.c b/minimise_number_string.c
new file mode 100644
index 0000000..5993564
--- /dev/null
+++ b/minimise_number_string.c
@@ -0,0 +1,130 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsimple.h"
+#ifndef TEST
+
+
+char *
+libsimple_minimise_number_string(char *s)
+{
+ char *p, *ret = s;
+ size_t n;
+
+ if (*s == '+')
+ memmove(s, &s[1], strlen(s));
+
+ p = strchr(s, '.');
+ if (p) {
+ p = strchr(p, '\0');
+ while (p[-1] == '0')
+ *--p = '\0';
+ if (p[-1] == '.') {
+ if (s[0] == '.') {
+ s[0] = '0';
+ return ret;
+ } else if (s[0] == '-' && s[1] == '.') {
+ s[1] = '0';
+ return ret;
+ }
+ *--p = '\0';
+ }
+ }
+
+ if (*s == '-')
+ s = &s[1];
+
+ for (p = s; *p == '0'; p++);
+ n = (size_t)(p - s);
+ if (!*p || *p == '.')
+ n -= !!n;
+ memmove(s, &s[n], strlen(&s[n]) + 1);
+
+ return ret;
+}
+
+
+#else
+#include "test.h"
+
+int
+main(void)
+{
+ char buf[1000];
+
+ /* Some aspects are tested in libsimple.c */
+
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.00000")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.1")), "100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.000001")), "100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.1000001")), "100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.0")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "00100.")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.00000")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.1")), "100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.000001")), "100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.1000001")), "100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.0")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "100.")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.00000")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.1")), "0.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.000001")), "0.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.1000001")), "0.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.0")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "0.")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, ".00000")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, ".1")), ".1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, ".000001")), ".000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, ".1000001")), ".1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, ".0")), "0"));
+
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.00000")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.1")), "100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.000001")), "100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.1000001")), "100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.0")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+00100.")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.00000")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.1")), "100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.000001")), "100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.1000001")), "100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.0")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+100.")), "100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.00000")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.1")), "0.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.000001")), "0.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.1000001")), "0.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.0")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+0.")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+.00000")), "0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+.1")), ".1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+.000001")), ".000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+.1000001")), ".1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "+.0")), "0"));
+
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.00000")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.1")), "-100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.000001")), "-100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.1000001")), "-100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.0")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-00100.")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.00000")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.1")), "-100.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.000001")), "-100.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.1000001")), "-100.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.0")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-100.")), "-100"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.00000")), "-0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.1")), "-0.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.000001")), "-0.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.1000001")), "-0.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.0")), "-0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-0.")), "-0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-.00000")), "-0"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-.1")), "-.1"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-.000001")), "-.000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-.1000001")), "-.1000001"));
+ assert(!strcmp(libsimple_minimise_number_string(strcpy(buf, "-.0")), "-0"));
+
+ return 0;
+}
+
+#endif
diff --git a/timespectostr.c b/timespectostr.c
index 3eca1f6..05bcaac 100644
--- a/timespectostr.c
+++ b/timespectostr.c
@@ -3,13 +3,13 @@
char *
-libsimple_timespectostr(char *restrict buf, const struct timespec *restrict ts) /* TODO test */
+libsimple_timespectostr(char *restrict buf, const struct timespec *restrict ts)
{
time_t s = ts->tv_sec;
long int ns = ts->tv_nsec;
char sign[2] = "+";
- if (!s) {
+ if (!buf) {
buf = malloc(INTSTRLEN(time_t) + sizeof("-.999999999"));
if (!buf)
return NULL;
diff --git a/timevaltostr.c b/timevaltostr.c
index 4dd6b9c..5daace5 100644
--- a/timevaltostr.c
+++ b/timevaltostr.c
@@ -3,13 +3,13 @@
char *
-libsimple_timevaltostr(char *restrict buf, const struct timeval *restrict tv) /* TODO test */
+libsimple_timevaltostr(char *restrict buf, const struct timeval *restrict tv)
{
time_t s = tv->tv_sec;
long int us = tv->tv_usec;
char sign[2] = "+";
- if (!s) {
+ if (!buf) {
buf = malloc(INTSTRLEN(time_t) + sizeof("-.999999"));
if (!buf)
return NULL;