From 6298377bd467a241dc1b05ef54f4e6ce02e06de1 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Fri, 18 Jun 2010 01:53:27 +0200 Subject: [PATCH] Implemented a ddate-module --- i3status.c | 10 +++ i3status.h | 1 + man/i3status.man | 10 +++ src/print_ddate.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 233 insertions(+) create mode 100644 src/print_ddate.c diff --git a/i3status.c b/i3status.c index 903ea92..9087d0c 100644 --- a/i3status.c +++ b/i3status.c @@ -5,6 +5,7 @@ * * Copyright © 2008-2009 Michael Stapelberg and contributors * Copyright © 2009 Thorsten Toepper + * Copyright © 2010 Axel Wagner * * See file LICENSE for license information. * @@ -108,6 +109,11 @@ int main(int argc, char *argv[]) { CFG_END() }; + cfg_opt_t ddate_opts[] = { + CFG_STR("format", "%{%a, %b %d%}, %Y%N - %H", CFGF_NONE), + CFG_END() + }; + cfg_opt_t load_opts[] = { CFG_STR("format", "%5min %10min %15min", CFGF_NONE), CFG_END() @@ -134,6 +140,7 @@ int main(int argc, char *argv[]) { CFG_SEC("disk", disk_opts, CFGF_TITLE | CFGF_MULTI), CFG_SEC("ipv6", ipv6_opts, CFGF_NONE), CFG_SEC("time", time_opts, CFGF_NONE), + CFG_SEC("ddate", ddate_opts, CFGF_NONE), CFG_SEC("load", load_opts, CFGF_NONE), CFG_END() }; @@ -222,6 +229,9 @@ int main(int argc, char *argv[]) { CASE_SEC("time") print_time(cfg_getstr(sec, "format")); + CASE_SEC("ddate") + print_ddate(cfg_getstr(sec, "format")); + CASE_SEC_TITLE("cpu_temperature") print_cpu_temperature_info(atoi(title), cfg_getstr(sec, "format")); } diff --git a/i3status.h b/i3status.h index 49bd387..512b4ad 100644 --- a/i3status.h +++ b/i3status.h @@ -62,6 +62,7 @@ void print_ipv6_info(const char *format_up, const char *format_down); void print_disk_info(const char *path, const char *format); void print_battery_info(int number, const char *format, bool last_full_capacity); void print_time(const char *format); +void print_ddate(const char *format); const char *get_ip_addr(); void print_wireless_info(const char *interface, const char *format_up, const char *format_down); void print_run_watch(const char *title, const char *pidfile, const char *format); diff --git a/man/i3status.man b/man/i3status.man index 9fa5767..b7f362e 100644 --- a/man/i3status.man +++ b/man/i3status.man @@ -197,6 +197,16 @@ Formats the current system time. See +strftime(3)+ for the format. *Example format*: +%Y-%m-%d %H:%M:%S+ +=== DDate + +Outputs the current discordian date in user-specified format. See +ddate(1)+ for +details on the format string. +*Note*: Neither *%.* nor *%X* are implemented yet. + +*Example order*: +ddate+ + +*Example format*: +%{%a, %b %d%}, %Y%N - %H+ + == Using i3status with dzen2 After installing dzen2, you can directly use it with i3status: diff --git a/src/print_ddate.c b/src/print_ddate.c new file mode 100644 index 0000000..be6776a --- /dev/null +++ b/src/print_ddate.c @@ -0,0 +1,212 @@ +// vim:ts=8:expandtab +#include +#include +#include +#include + +/* define fixed output-Strings */ +char *season_long[5] = { + "Chaos", + "Discord", + "Confusion", + "Bureaucracy", + "The Aftermath" +}; + +char *season_short[5] = { + "Chs", + "Dsc", + "Cfn", + "Bcy", + "Afm" +}; + +char *day_long[5] = { + "Sweetmorn", + "Boomtime", + "Pungenday", + "Prickle-Prickle", + "Setting Orange" +}; + +char *day_short[5] = { + "SM", + "BT", + "PD", + "PP", + "SO" +}; + +char *holidays[10] = { + "Mungday", + "Mojoday", + "Syaday", + "Zaraday", + "Maladay", + "Chaoflux", + "Discoflux", + "Confuflux", + "Bureflux", + "Afflux" +}; + +/* A helper-struct, taking the discordian date */ +struct disc_time { + int year; + int season; + int week_day; + int season_day; + int st_tibs_day; +}; + +/* Print the date *dt in format *format */ +int format_output(char *format, struct disc_time *dt) { + char *i; + char *tibs_end = 0; + + for (i = format; *i != '\0'; i++) { + if (*i != '%') { + putchar(*i); + continue; + } + switch (*(i+1)) { + /* Weekday in long and abbreviation */ + case 'A': + printf("%s", day_long[dt->week_day]); + break; + case 'a': + printf("%s", day_short[dt->week_day]); + break; + /* Season in long and abbreviation */ + case 'B': + printf("%s", season_long[dt->season]); + break; + case 'b': + printf("%s", season_short[dt->season]); + break; + /* Day of the season (ordinal and cardinal) */ + case 'd': + printf("%d", dt->season_day + 1); + break; + case 'e': + printf("%d", dt->season_day + 1); + switch (dt->season_day) { + case 0: + printf("st"); + break; + case 1: + printf("nd"); + break; + case 2: + printf("rd"); + break; + default: + printf("th"); + break; + } + break; + /* YOLD */ + case 'Y': + printf("%d", dt->year); + break; + /* Holidays */ + case 'H': + if (dt->season_day == 4) { + printf(holidays[dt->season]); + } + if (dt->season_day == 49) { + printf(holidays[dt->season + 5]); + } + break; + /* Stop parsing the format string, except on Holidays */ + case 'N': + if (dt->season_day != 4 && dt->season_day != 49) { + return 0; + } + break; + /* Newline- and Tabbing-characters */ + case 'n': + printf("\n"); + break; + case 't': + printf("\t"); + break; + /* The St. Tib's Day replacement */ + case '{': + tibs_end = strstr(i, "%}"); + if (tibs_end == NULL) { + i++; + break; + } + if (dt->st_tibs_day) { + /* We outpt "St. Tib's Day... */ + printf("St. Tib's Day"); + } else { + /* ...or parse the substring between %{ and %} ... */ + *i = '\0'; + if (!format_output(i + 2, dt)) return 0; + *i = '%'; + } + /* ...and continue with the rest */ + i = tibs_end + 2; + break; + case '}': + i++; + break; + default: + /* No escape-sequence, so we just skip */ + printf("%%%c",*(i+1)); + break; + } + i++; + } + return 1; +} + +/* Get the current date and convert it to discordian */ +struct disc_time *get_ddate() { + time_t current_time = time(NULL); + + if (current_time == (time_t) -1) { + return NULL; + } + + struct tm *current_tm = localtime(¤t_time); + + if (current_tm == NULL) { + return NULL; + } + + /* We have to know, whether we have to insert St. Tib's Day, so whether it's a leap + year in gregorian calendar */ + int is_leap_year = !(current_tm->tm_year % 4) && + (!(current_tm->tm_year % 400) || current_tm->tm_year % 100); + + struct disc_time *dt = malloc(sizeof(dt)); + if (is_leap_year && current_tm->tm_yday == 59) { + /* On St. Tibs Day we don't have to define a date */ + dt->st_tibs_day = 1; + } else { + dt->st_tibs_day = 0; + dt->season_day = current_tm->tm_yday % 73; + if (is_leap_year && current_tm->tm_yday > 59) { + dt->week_day = (current_tm->tm_yday - 1) % 5; + } else { + dt->week_day = current_tm->tm_yday % 5; + } + } + dt->year = current_tm->tm_year + 3066; + dt->season = current_tm->tm_yday / 73; + return dt; +} + +void print_ddate(const char *format) { + struct disc_time *dt = get_ddate(); + if (dt == NULL) { + return; + } + char *form = strdup(format); + format_output(form, dt); + free(dt); + free(form); +}