Charles.Forsyth20060303a828770d19 years agoHistory
295 lines · 4.5 KB · Brainfuck
RawDownload
implement Cal; ## Copyright © 1995-2002 Lucent Technologies Inc.  All rights reserved.# Limbo transliteration 2003 by Vita Nuova# This software is subject to the Plan 9 Open Source Licence.# include "sys.m";	sys: Sys; include "draw.m"; include "bufio.m";	bufio: Bufio;	Iobuf: import bufio; include "daytime.m";	daytime: Daytime;	Tm: import daytime; Cal: module{	init:	fn(nil: ref Draw->Context, nil: list of string);}; dayw :=	" S  M Tu  W Th  F  S";smon := array[] of {	"January", "February", "March", "April",	"May", "June", "July", "August",	"September", "October", "November", "December",}; mon := array[] of {	0,	31, 29, 31, 30,	31, 30, 31, 31,	30, 31, 30, 31,}; bout: ref Iobuf; init(nil: ref Draw->Context, args: list of string){	y, m: int; 	sys = load Sys Sys->PATH;	bufio = load Bufio Bufio->PATH;	daytime = load Daytime Daytime->PATH; 	argc := len args;	if(argc > 3){		sys->fprint(sys->fildes(2), "usage: cal [month] [year]\n");		raise "fail:usage";	}	bout = bufio->fopen(sys->fildes(1), Bufio->OWRITE); ## no arg, print current month#	if(argc <= 1) {		m = curmo();		y = curyr();		return xshort(m, y);	}	args = tl args; ## one arg#	if looks like a month, print month#	else print year#	if(argc == 2) {		y = number(hd args);		if(y < 0)			y = -y;		if(y >= 1 && y <= 12)			return xshort(y, curyr());		return xlong(y);	} ## two arg, month and year#	m = number(hd args);	if(m < 0)		m = -m;	y = number(hd tl args);	return xshort(m, y);} ##	print out just month#xshort(m: int, y: int){	if(m < 1 || m > 12)		badarg();	if(y < 1 || y > 9999)		badarg();	bout.puts(sys->sprint("   %s %ud\n", smon[m-1], y));	bout.puts(sys->sprint("%s\n", dayw));	lines := cal(m, y);	for(i := 0; i < len lines; i++){		bout.puts(lines[i]);		bout.putc('\n');	}	bout.flush();} ##	print out complete year#xlong(y: int){	if(y<1 || y>9999)		badarg();	bout.puts("\n\n\n");	bout.puts(sys->sprint("                                %ud\n", y));	bout.putc('\n');	months := array[3] of array of string;	for(i:=0; i<12; i+=3) {		bout.puts(sys->sprint("         %.3s", smon[i]));		bout.puts(sys->sprint("                    %.3s", smon[i+1]));		bout.puts(sys->sprint("                    %.3s\n", smon[i+2]));		bout.puts(sys->sprint("%s   %s   %s\n", dayw, dayw, dayw));		for(j := 0; j < 3; j++)			months[j] = cal(i+j+1, y);		for(l := 0; l < 6; l++){			s := "";			for(j = 0; j < 3; j++)				s += sys->sprint("%-20.20s   ", months[j][l]);			for(j = len s; j > 0 && s[j-1] == ' ';)				j--;			bout.puts(s[0:j]);			bout.putc('\n');		}	}	bout.flush();} badarg(){	sys->fprint(sys->fildes(2), "cal: bad argument\n");	raise "fail:bad argument";} dict := array[] of {	("january",	1),	("february",	2),	("march",	3),	("april",	4),	("may",		5),	("june",		6),	("july",		7),	("august",	8),	("sept",		9),	("september",	9),	("october",	10),	("november",	11),	("december",	12),}; ## convert to a number.# if its a dictionary word,# return negative  number#number(s: string): int{	if(len s >= 3){		for(n:=0; n < len dict; n++){			(word, val) := dict[n];			if(s == word || s == word[0:3])				return -val;		}	}	n := 0;	for(i := 0; i < len s; i++){		c := s[i];		if(c<'0' || c>'9')			badarg();		n = n*10 + c-'0';	}	return n;} pstr(str: string, n: int){	bout.puts(sys->sprint("%-*.*s\n", n, n, str));} cal(m: int, y: int): array of string{	d := jan1(y);	mon[9] = 30; 	case (jan1(y+1)+7-d)%7 { 	#	#	non-leap year	#	1 =>		mon[2] = 28; 	#	#	leap year	#	2 =>		mon[2] = 29; 	#	#	1752	#	* =>		mon[2] = 29;		mon[9] = 19;	}	for(i:=1; i<m; i++)		d += mon[i];	d %= 7;	lines := array[6] of string;	l := 0;	s := "";	for(i = 0; i < d; i++)		s += "   ";	for(i=1; i<=mon[m]; i++) {		if(i==3 && mon[m]==19) {			i += 11;			mon[m] += 11;		}		s += sys->sprint("%2d", i);		if(++d == 7) {			d = 0;			lines[l++] = s;			s = "";		}else			s[len s] = ' ';	}	if(s != nil){		while(s[len s-1] == ' ')			s = s[:len s-1];		lines[l] = s;	}	return lines;} ##	return day of the week#	of jan 1 of given year#jan1(y: int): int{##	normal gregorian calendar#	one extra day per four years# 	d := 4+y+(y+3)/4; ##	julian calendar#	regular gregorian#	less three days per 400# 	if(y > 1800) {		d -= (y-1701)/100;		d += (y-1601)/400;	} ##	great calendar changeover instant# 	if(y > 1752)		d += 3; 	return d%7;} ## get current month and year#curmo(): int{	tm := daytime->local(daytime->now());	return tm.mon+1;} curyr(): int{	tm := daytime->local(daytime->now());	return tm.year+1900;}