aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neukirchen <chneukirchen@gmail.com>2016-08-08 16:28:25 +0200
committerChristian Neukirchen <chneukirchen@gmail.com>2016-08-08 16:28:25 +0200
commitd458439970caffc3bdebc3c139f29e02b285db55 (patch)
treea0bde4845187c09f37321e66e0aaec27351423ea
parent20dae518c4abaac33226b5e8ae85d0de1a1b226e (diff)
downloadmblaze-d458439970caffc3bdebc3c139f29e02b285db55.tar.gz
import and use timegm from musl
It's ridiculous this function is not in the standards.
-rw-r--r--COPYING2
-rw-r--r--Makefile24
-rw-r--r--blaze822.c2
-rw-r--r--blaze822.h8
-rw-r--r--mytimegm.c86
5 files changed, 107 insertions, 15 deletions
diff --git a/COPYING b/COPYING
index 5486574..caee955 100644
--- a/COPYING
+++ b/COPYING
@@ -6,7 +6,7 @@ has waived all copyright and related or neighboring rights to this work.
http://creativecommons.org/publicdomain/zero/1.0/
-The files mystrverscmp.c and mymemmem.c
+The files mystrverscmp.c and mymemmem.c and mytimegm.c
are MIT-licensed and were written by Rich Felker.
mpick.c is largely based on code by Christian Neukirchen
diff --git a/Makefile b/Makefile
index c1609c3..e286634 100644
--- a/Makefile
+++ b/Makefile
@@ -10,24 +10,24 @@ SCRIPT = mcolor mcom mless mquote
all: $(ALL)
-maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o
-magrep: magrep.o blaze822.o seq.o rfc2045.o rfc2047.o mymemmem.o
+maddr: maddr.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o
+magrep: magrep.o blaze822.o seq.o rfc2045.o rfc2047.o mymemmem.o mytimegm.o
mdate: mdate.o
-mdeliver: mdeliver.o blaze822.o mymemmem.o
+mdeliver: mdeliver.o blaze822.o mymemmem.o mytimegm.o
mdirs: mdirs.o
-mflag: mflag.o blaze822.o seq.o mymemmem.o
-mgenmid: mgenmid.o blaze822.o seq.o mymemmem.o
-mhdr: mhdr.o blaze822.o seq.o rfc2047.o mymemmem.o
+mflag: mflag.o blaze822.o seq.o mymemmem.o mytimegm.o
+mgenmid: mgenmid.o blaze822.o seq.o mymemmem.o mytimegm.o
+mhdr: mhdr.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o
minc: minc.o
mlist: mlist.o
mmime: mmime.o
-mpick: mpick.o blaze822.o seq.o rfc2047.c mymemmem.o
-mscan: mscan.o blaze822.o seq.o rfc2047.o mymemmem.o
-msed: msed.o blaze822.o seq.o mymemmem.o
+mpick: mpick.o blaze822.o seq.o rfc2047.c mymemmem.o mytimegm.o
+mscan: mscan.o blaze822.o seq.o rfc2047.o mymemmem.o mytimegm.o
+msed: msed.o blaze822.o seq.o mymemmem.o mytimegm.o
mseq: mseq.o seq.o
-mshow: mshow.o blaze822.o seq.o rfc2045.o rfc2047.c mymemmem.o filter.o
-msort: msort.o blaze822.o seq.o mystrverscmp.o mymemmem.o
-mthread: mthread.o blaze822.o seq.o mymemmem.o
+mshow: mshow.o blaze822.o seq.o rfc2045.o rfc2047.c mymemmem.o filter.o mytimegm.o
+msort: msort.o blaze822.o seq.o mystrverscmp.o mymemmem.o mytimegm.o
+mthread: mthread.o blaze822.o seq.o mymemmem.o mytimegm.o
README: man/mblaze.7
mandoc -Tutf8 $< | col -bx >$@
diff --git a/blaze822.c b/blaze822.c
index 5a98915..9a596b6 100644
--- a/blaze822.c
+++ b/blaze822.c
@@ -121,7 +121,7 @@ blaze822_date(char *s) {
tm.tm_isdst = -1;
- time_t r = mktime(&tm);
+ time_t r = tm_to_secs(&tm);
return r;
fail:
diff --git a/blaze822.h b/blaze822.h
index 2ffc031..0808239 100644
--- a/blaze822.h
+++ b/blaze822.h
@@ -1,6 +1,8 @@
-#include <stdint.h>
#include <sys/types.h>
+#include <stdint.h>
+#include <time.h>
+
struct message;
// blaze822.c
@@ -71,3 +73,7 @@ char *blaze822_home_file(char *basename);
// filter.c
int filter(char *input, size_t inlen, char *cmd, char **outputo, size_t *outleno);
+
+// mygmtime.c
+
+time_t tm_to_secs(const struct tm *tm);
diff --git a/mytimegm.c b/mytimegm.c
new file mode 100644
index 0000000..3d3fccd
--- /dev/null
+++ b/mytimegm.c
@@ -0,0 +1,86 @@
+#include <time.h>
+
+// from musl@1cc81f5cb, slightly tweaked
+
+static long long
+__year_to_secs(long long year, int *is_leap)
+{
+ if (year-2ULL <= 136) {
+ int y = year;
+ int leaps = (y-68)>>2;
+ if (!((y-68)&3)) {
+ leaps--;
+ if (is_leap) *is_leap = 1;
+ } else if (is_leap) *is_leap = 0;
+ return 31536000*(y-70) + 86400*leaps;
+ }
+
+ int cycles, centuries, leaps, rem;
+
+ cycles = (year-100) / 400;
+ rem = (year-100) % 400;
+ if (rem < 0) {
+ cycles--;
+ rem += 400;
+ }
+ if (!rem) {
+ *is_leap = 1;
+ centuries = 0;
+ leaps = 0;
+ } else {
+ if (rem >= 200) {
+ if (rem >= 300) centuries = 3, rem -= 300;
+ else centuries = 2, rem -= 200;
+ } else {
+ if (rem >= 100) centuries = 1, rem -= 100;
+ else centuries = 0;
+ }
+ if (!rem) {
+ *is_leap = 0;
+ leaps = 0;
+ } else {
+ leaps = rem / 4U;
+ rem %= 4U;
+ *is_leap = !rem;
+ }
+ }
+
+ leaps += 97*cycles + 24*centuries - *is_leap;
+
+ return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
+}
+
+static int
+__month_to_secs(int month, int is_leap)
+{
+ static const int secs_through_month[] = {
+ 0, 31*86400, 59*86400, 90*86400,
+ 120*86400, 151*86400, 181*86400, 212*86400,
+ 243*86400, 273*86400, 304*86400, 334*86400 };
+ int t = secs_through_month[month];
+ if (is_leap && month >= 2) t+=86400;
+ return t;
+}
+
+time_t tm_to_secs(const struct tm *tm)
+{
+ int is_leap;
+ long long year = tm->tm_year;
+ int month = tm->tm_mon;
+ if (month >= 12 || month < 0) {
+ int adj = month / 12;
+ month %= 12;
+ if (month < 0) {
+ adj--;
+ month += 12;
+ }
+ year += adj;
+ }
+ long long t = __year_to_secs(year, &is_leap);
+ t += __month_to_secs(month, is_leap);
+ t += 86400LL * (tm->tm_mday-1);
+ t += 3600LL * tm->tm_hour;
+ t += 60LL * tm->tm_min;
+ t += tm->tm_sec;
+ return t;
+}