shithub: mc

Download patch

ref: bbb28d255caf1b890e4bd5dca79ae6f5d11a360c
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Aug 28 11:11:09 EDT 2014

Initial commit.

    We don't do timezones yet.

--- /dev/null
+++ b/lib/date/Makefile
@@ -1,0 +1,12 @@
+MYRLIB=date
+MYRSRC= \
+	date.myr \
+	zoneinfo.myr \
+
+MYRFLAG=-I .
+
+include config.mk
+include mk/myr.mk
+
+check: all
+	make -C test check
--- /dev/null
+++ b/lib/date/configure
@@ -1,0 +1,52 @@
+#!/bin/sh
+
+prefix="/usr/local"
+
+for i in `seq 300`; do
+    echo "Lots of output to emulate automake... ok"
+    echo "Testing for things you'll never use... fail"
+    echo "Satisfying the fortran77 lobby... ok"
+    echo "Burning CPU time checking for the bloody obvious... ok"
+done
+echo "Automake emulated successfully"
+
+INST_ROOT='/usr/local'
+
+for arg in $*; do
+    shift 1
+    case $arg in
+        "--prefix" | "-p")
+            prefix=shift $*
+            ;;
+        --prefix=*)
+            prefix=`echo $arg | sed 's/^--prefix=//g'`
+            ;;
+        "--help" | "-h")
+            echo "Usage:"
+            echo "      --prefix | -p: The prefix to install to"
+            break;
+            ;;
+        *) echo "Unrecognized argument $arg";;
+    esac
+done
+
+OS=`uname`
+
+echo export INST_ROOT=$prefix > config.mk
+case $OS in
+    *Linux*)
+        echo 'export SYS=linux' >> config.mk
+        ;;
+    *Darwin*)
+        echo 'export SYS=osx' >> config.mk
+        ;;
+    *)
+        echo 'Unknown architecture.'
+        ;;
+esac
+
+cat << EOF
+    Building with:
+        prefix=$prefix
+EOF
+
--- /dev/null
+++ b/lib/date/date.myr
@@ -1,0 +1,118 @@
+use std
+
+pkg date =
+	type date = struct
+		actual	: std.time	/* epoch time in microseconds */
+		tzoff	: diff	/* timezone offset in microseconds */
+		year	: int	/* year, starting at 0 (ie, 1 BCE) */
+		mon	: int	/* month, [1..12] */
+		day	: int	/* day, [1..31] */
+		wday	: int	/* weekday, [0..6] */
+		h	: int	/* hour: [0..23] */
+		m	: int	/* minute: [0..59] */
+		s	: int	/* second: [0..59] */
+		us	: int	/* microsecond: [0..999,999] */
+	;;
+
+	type diff = std.time
+
+	/* date i/o */
+	const parse	: (d : byte[:]	-> date)
+	const parsefmt	: (fmt : byte[:], d : byte[:]	-> date)
+	const parsez	: (d : byte[:], tz : byte[:]	-> date)
+	const fmt	: (d : date	-> byte[:])
+	const bfmt	: (d : date, buf : byte[:]	-> byte[:])
+
+	/* useful constructors */
+	const mkdate	: (tm : std.time, tz : diff -> date)
+	const now	: (-> date)
+	const utcnow	: (-> date)
+	const localoff	: (-> diff)
+	const tzoff	: (tzname : byte[:]	-> diff)
+
+	/* date differences */
+	const add	: (d : date, dt : diff	-> date)
+	const diff	: (a : date, b : date -> diff)
+;;
+
+const monthbound	= [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
+const leapmonthbound	= [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
+const Day400y	= (365*400 + 24*4 + 1)
+const Day100y	= (365*100 + 24)
+const Day4y	= (365*4 + 1)
+
+const now = {
+	-> utcnow()
+}
+
+const utcnow = {
+	var tm
+
+	tm = std.now()
+	std.put("tm = %l\n", tm)
+	-> mkdate(tm, 0)
+}
+
+const mkdate = {tm, off
+	var j, y, m, d
+	var t, e
+	var date
+
+	/* apply time zone offset */
+	tm += off castto(std.time)
+	t = tm % (24*60*60*1_000_000)	/* time */
+	e = tm / (24*60*60*1_000_000)	/* epoch days */
+
+	date.actual = tm
+
+	/* microseconds, seconds, minutes, hours */
+	date.us 	= (t % 1_000_000) castto(int)
+	t /= 1_000_000
+	date.s 	= (t % 60) castto(int)
+	t /= 60
+	date.m	= (t % 60) castto(int)
+	t /= 60
+	date.h  = t castto(int)
+
+	/* weekday */
+	date.wday = ((e + 4) % 7) castto(int)	/* the world started on Thursday */
+	/*
+	year, month, day: 
+
+	Implemented according to algorithm 199, conversions between calendar 
+	date and Julian day number:
+	Robert G. Tantzen
+	Air Force Missile: Development Center, Holloman AFB, New Mex.
+
+	Lots of magic.
+	*/
+	j = e + 719468
+	y = (4 * j - 1) / 146097
+	j = 4 * j - 1 - 146097 * y
+	d = j / 4
+	j = (4 * d + 3) / 1461
+	d = 4 * d + 3 - 1461 * j
+	d = (d + 4) / 4 ;
+	m = (5 * d - 3) / 153
+	d = 5 * d - 3 - 153 * m
+	d = (d + 5) / 5
+	y = 100 * y + j
+	if m < 10
+		m += 3
+	else
+		m -= 9 
+		y++
+	;;
+	date.year = y castto(int)
+	date.mon = m castto(int)
+	date.day = (d + 1) castto(int)
+	-> date
+}
+
+const ndays = {y
+	if y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)
+		-> 366
+	else
+		-> 365
+	;;
+}
--- /dev/null
+++ b/lib/date/mk/myr.mk
@@ -1,0 +1,97 @@
+ifneq ($(MYRLIB),)
+    _LIBNAME=lib$(MYRLIB).a
+endif
+
+all: subdirs $(_LIBNAME) $(MYRBIN) 
+
+subdirs:
+	@for i in $(SUB); do (\
+	    cd $$i && \
+	    $(MAKE) || \
+	    exit 1 \
+	) || exit 1; done
+
+subdirs-clean:
+	@for i in $(SUB); do (\
+	    cd $$i && \
+	    $(MAKE) clean|| \
+	    exit 1 \
+	); done
+
+subdirs-install:
+	@for i in $(SUB); do (\
+	    cd $$i && \
+	    $(MAKE) install|| \
+	    exit 1 \
+	); done
+
+subdirs-uninstall:
+	@for i in $(SUB); do (\
+	    cd $$i && \
+	    $(MAKE) uninstall|| \
+	    exit 1 \
+	); done
+
+$(_LIBNAME): $(MYRSRC) $(ASMSRC)
+	myrbuild -l $(MYRLIB) $(MYRFLAG) $^
+
+$(MYRBIN): $(MYRSRC) $(ASMSRC)
+	myrbuild -b $(MYRBIN) $(MYRFLAG) $^
+
+OBJ=$(MYRSRC:.myr=.o) $(ASMSRC:.s=.o)
+USE=$(MYRSRC:.myr=.use) $(MYRLIB)
+.PHONY: clean
+clean: subdirs-clean
+	rm -f $(OBJ)
+	rm -f $(USE)
+	@if [ ! -z "$(MYRLIB)" ]; then \
+	    echo rm -f $(MYRLIB); \
+	    rm -f $(MYRLIB); \
+	    echo rm -f lib$(MYRLIB).a; \
+	    rm -f lib$(MYRLIB).a; \
+	fi
+	@if [ ! -z "$(MYRBIN)" ]; then \
+	    echo rm -f $(MYRBIN); \
+	    rm -f $(MYRBIN); \
+	    echo rm -f lib$(MYRBIN).a; \
+	    rm -f lib$(MYRBIN).a; \
+	fi
+
+install: subdirs-install $(MYRBIN) $(_LIBNAME) $(MAN)
+	@if [ ! -z "$(MYRBIN)" ]; then \
+	    echo install $(MYRBIN) $(abspath $(DESTDIR)/$(INST_ROOT)/bin); \
+	    mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/bin); \
+	    install $(MYRBIN) $(abspath $(DESTDIR)/$(INST_ROOT)/bin); \
+	fi
+	@if [ ! -z "$(_LIBNAME)" ]; then \
+		echo install -m 644 $(_LIBNAME) $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr); \
+		echo install -m 644 $(MYRLIB) $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr); \
+		mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr); \
+		install -m 644 $(_LIBNAME) $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr); \
+		install -m 644 $(MYRLIB) $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr); \
+	fi
+	@for i in $(MAN); do \
+	    MANSECT=$$(echo $$i | awk -F. '{print $$NF}'); \
+	    echo mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$$MANSECT); \
+	    echo install -m 644 $(MAN) $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${MANSECT}); \
+	    mkdir -p $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$$MANSECT); \
+	    install -m 644 $(MAN) $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${MANSECT}); \
+	done \
+
+uninstall: subdirs-uninstall
+	@for i in $(MYRBIN); do \
+	    echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/bin/$$i); \
+	    rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/bin/$$i); \
+	done
+	@for i in $(_LIBNAME) $(MYRLIB); do \
+	    echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr/$$i); \
+	    rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr/$$i); \
+	done
+	@for i in $(MAN); do \
+	    MANSECT=$$(echo $$i | awk -F. '{print $$NF}'); \
+	    echo rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${MANSECT}/$$i); \
+	    rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/share/man/man$${MANSECT}/$$i); \
+	done
+
+config.mk:
+	./configure
--- /dev/null
+++ b/lib/date/zoneinfo.myr
@@ -1,0 +1,125 @@
+use std
+
+pkg _timezone =
+	type zifile
+	const load	: (file : byte[:] -> zifile#)
+;;
+
+type zifile = struct
+	time	: int32[:]
+	timetype: byte[:]
+	ttinfo 	: ttinfo[:]
+	abbrev	: byte[:]
+	leap	: int32[2][:]
+	isstd	: byte[:]
+	isgmt	: byte[:]
+;;
+
+type ttinfo = struct
+	gmtoff	: int32
+	isdst	: byte
+	abbrind	: byte
+;;
+
+const load = {file
+	var nisgmt
+	var nisstd
+	var nleap
+	var ntime
+	var ntype
+	var nchar
+	var i
+	var f
+	var p
+
+	/* check magic */
+	match std.slurp(file)
+	| `std.Ok d:	p = d
+	| `std.Fail m:	
+		std.put("unable to load zone: %s\n", m)
+		-> std.zalloc()
+	;;
+
+	if !std.sleq(p[:4], "TZif")
+		std.put("%s is not a zone info file\n", file)
+		-> std.zalloc()
+	;;
+
+	/* skip to data */
+	p = p[20:]
+	(nisgmt, p) = fetchbe32(p)
+	(nisstd, p) = fetchbe32(p)
+	(nleap, p) = fetchbe32(p)
+	(ntime, p) = fetchbe32(p)
+	(ntype, p) = fetchbe32(p)
+	(nchar, p) = fetchbe32(p)
+
+
+	f = std.alloc()
+	f.time = std.slalloc(ntime castto(std.size))
+	for i = 0; i < ntime; i++
+		(f.time[i], p) = fetchbe32(p)
+	;;
+
+	f.timetype = std.slalloc(ntime castto(std.size))
+	for i = 0; i < ntime; i++
+		(f.timetype[i], p) = fetchbe8(p)
+	;;
+
+	f.ttinfo = std.slalloc(ntype castto(std.size))
+	for i = 0; i < ntype; i++
+		p = fetchttinfo(p, &f.ttinfo[i])
+	;;
+
+	f.abbrev = std.slalloc(nchar castto(std.size))
+	for i = 0; i < nchar; i++
+		(f.abbrev[i], p) = fetchbe8(p)
+	;;
+
+	f.leap = std.slalloc(nleap castto(std.size))
+	for i = 0; i < nleap; i++
+		(f.leap[i][0], p) = fetchbe32(p)
+		(f.leap[i][1], p) = fetchbe32(p)
+	;;
+
+	f.isstd = std.slalloc(nisstd castto(std.size))
+	for i = 0; i < nisstd; i++
+		(f.isstd[i], p) = fetchbe8(p)
+	;;
+
+	f.isgmt = std.slalloc(nisgmt castto(std.size))
+	for i = 0; i < nisgmt; i++
+		(f.isgmt[i], p) = fetchbe8(p)
+	;;
+
+
+	-> f
+}
+
+const fetchbe32 = {sl
+	var v
+
+	std.assert(sl.len >= 4, "Slice too small to fetch int32 from")
+	v = 	(sl[0] castto(int32)) << 24 | \
+		(sl[1] castto(int32)) << 16 | \
+		(sl[2] castto(int32)) << 8  | \
+		(sl[3] castto(int32)) << 0  
+	-> (v, sl[4:])
+}
+
+const fetchbe8 = {sl
+	var v
+
+	std.assert(sl.len >= 1, "Slice too small to fetch int8 from")
+	v = sl[0]
+	-> (v, sl[1:])
+}
+
+
+const fetchttinfo = {sl, dst : ttinfo#
+	(dst.gmtoff, sl) = fetchbe32(sl)
+	(dst.isdst, sl) = fetchbe8(sl)
+	(dst.abbrind, sl) = fetchbe8(sl)
+	-> sl
+}
+