#include #include #include #include #include #define DATEFMT "%a %d %b %Y" #define SEP " ~> " typedef struct event { char *name; time_t time; } event; static bool cal = true; static const char *days[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }; static const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const int daysinmonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static bool isleap(int year) { if ((year % 4) == 0 && (year % 100) != 0) return true; else if ((year % 400) == 0) return true; return false; } static void print_month(struct tm *t) { printf(" %s %d\n", months[t->tm_mon], t->tm_year + 1900); } static void print_days() { for (int i = 0; i < 7; i++) printf("%s ", days[i]); putchar('\n'); } static void print_padded(int n, int l) { int i = 1; loop: if ((n / i) > 0) { i *= 10; l--; goto loop; } if (l != 0) printf("%*s", l, " "); if (l < 0) return; printf("%d", n); } static void print_month_grid(struct tm *t) { int day = 1; int total = daysinmonth[t->tm_mon]; if (t->tm_mon == 1 && isleap(t->tm_year + 1900)) total += 1; int offset = (t->tm_yday % 7) - 1; for (int i = 0; i < offset; i++) printf(" "); for (; day < total + 1; day++) { if (day == t->tm_mday) { printf("\e[4;34m"); print_padded(day, 2); printf("\e[0m"); } else print_padded(day, 2); putchar(' '); if (((day + offset) % 7) == 0) putchar('\n'); } putchar('\n'); } static void print_cal(struct tm *t) { print_month(t); print_days(); print_month_grid(t); } static event * read_event(FILE *f) { event *e = malloc(sizeof(event)); char buf[256] = {0}; if (!fgets(buf, 256, f)) { free(e); return NULL; } char *time = buf; char *name = strchr(buf, '|'); if (!name) { fprintf(stderr, "invalid event! %s\n", buf); exit(1); } *name = 0; name++; e->name = strdup(name); e->time = atoll(time); return e; } static void print_event(event *e) { struct tm *t = localtime(&e->time); char buf[256]; strftime(buf, 256, DATEFMT, t); printf("%s" SEP "%s", buf, e->name); } static void free_event(event *e) { free(e->name); free(e); } int main(int argc, char **argv) { if (argc > 1) if (strcmp(argv[1], "-h") == 0) cal = false; time_t ulocal = time(NULL); struct tm *local = localtime(&ulocal); if (cal) print_cal(local); bool dirty = false; event *e; while (e = read_event(stdin)) { if (ulocal + (86400 * 30) > e->time) { print_event(e); dirty = true; } free_event(e); } if (!dirty) printf("You have nothing upcoming\n"); return 0; }