From 7269a43df51a085878f0f9860f115b944a4cc206 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Sat, 28 Mar 2020 18:03:53 +0100 Subject: initial commit of wcal --- Makefile | 26 +++++++++++++++ wcal.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 Makefile create mode 100644 wcal.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..746782e --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +ALL=wcal + +CFLAGS=-g -O2 -Wall -Wno-switch -Wextra -Wwrite-strings + +DESTDIR= +PREFIX=/usr/local +BINDIR=$(PREFIX)/bin +MANDIR=$(PREFIX)/share/man + +all: $(ALL) + +clean: FRC + rm -f $(ALL) + +check: FRC all + prove -v + +install: FRC all + mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(MANDIR)/man1 + install -m0755 $(ALL) $(DESTDIR)$(BINDIR) + install -m0644 $(ALL:=.1) $(DESTDIR)$(MANDIR)/man1 + +README: wcal.1 + mandoc -Tutf8 $< | col -bx >$@ + +FRC: diff --git a/wcal.c b/wcal.c new file mode 100644 index 0000000..0d45d27 --- /dev/null +++ b/wcal.c @@ -0,0 +1,115 @@ +/* + * wcal - ISO weekly calendar + * + * To the extent possible under law, Leah Neukirchen + * has waived all copyright and related or neighboring rights to this work. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +/* + * -1 show current month (default) + * -3 show three months + * -y show whole year + * -c show current week only + * -i print infinite calendar + * -d YYYY-MM-DD different value for today + */ + +#define _XOPEN_SOURCE 700 +#include +#include +#include + +int flag1, flag3, flagc, flagi, flagy; + +int +main(int argc, char *argv[]) +{ + time_t now = time(0); + struct tm *tm = localtime(&now); + + int c; + while ((c = getopt(argc, argv, "13cid:y")) != -1) + switch (c) { + case '1': flag1 = 1; break; + case '3': flag3 = 1; break; + case 'c': flagc = 1; break; + case 'y': flagy = 1; break; + case 'i': flagi = 1; break; + // XXX error handling, or write a parser oneself... + case 'd': strptime(optarg, "%Y-%m-%d", tm); break; + } + + tm->tm_hour = 12; /* avoid DST problems */ + tm->tm_min = tm->tm_sec = 0; + + int today_mday = tm->tm_mday; + int today_mon = tm->tm_mon; + int today_year = tm->tm_year; + + int max_weeks = 1; + int max_months = 0; + + if (flagc) { + max_weeks = 1; + } else if (flag3) { + tm->tm_mday = 1; tm->tm_mon--; max_weeks = 14; + } else if (flagy) { + tm->tm_mday = 1; tm->tm_mon = 0; max_months = 12; max_weeks = 53; + } else if (flagi) { + tm->tm_mday = 1; + } else { /* flag1 is default */ + tm->tm_mday = 1; max_months = 1; max_weeks = 6; + } + + mktime(tm); + + while (tm->tm_wday != 1) { + tm->tm_mday--; + mktime(tm); + } + + printf(" Mo Tu We Th Fr Sa Su\n"); + + int color = isatty(1); + + for (int weeks = 0, months = 0; + flagi || (max_months && months < max_months) || (weeks < max_weeks); + weeks++) { + char buf[8]; + strftime(buf, sizeof buf, "%V", tm); + printf("%s ", buf); + + tm->tm_mday += 6; + mktime(tm); + if (tm->tm_mday <= 7 || weeks == 0) { + strftime(buf, sizeof buf, "%b", tm); + printf("%s ", buf); + months++; + } else if ((tm->tm_mon == 0 && tm->tm_yday < 14) || weeks == 1) { + strftime(buf, sizeof buf, "%Y", tm); + printf("%s", buf); + } else { + printf(" "); + } + tm->tm_mday -= 6; + mktime(tm); + + for (int i = 0; i < 7; i++) { + int today = + tm->tm_mday == today_mday && + tm->tm_mon == today_mon && + tm->tm_year == today_year; + + printf(" %s%2d%s", + color && today ? "\e[7m" : "", + tm->tm_mday, + color && today ? "\e[0m" : ""); + + tm->tm_mday++; + mktime(tm); + } + + printf("\n"); + } +} -- cgit 1.4.1