]> git.sur5r.net Git - i3/i3status/blobdiff - src/print_ddate.c
Skip a day in the Discordian calendar when St. Tib's Day has passed
[i3/i3status] / src / print_ddate.c
index 6f971471ae354b238bc7704f65d295f7fdf61188..30bdc527a6d5122b8559b62aaf40782e36c239dc 100644 (file)
@@ -3,6 +3,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <yajl/yajl_gen.h>
+#include <yajl/yajl_version.h>
+
+#include "i3status.h"
 
 /* define fixed output-Strings */
 char *season_long[5] = {
@@ -60,76 +64,77 @@ struct disc_time {
 };
 
 /* Print the date *dt in format *format */
-int format_output(char *format, struct disc_time *dt) {
+static int format_output(char *outwalk, char *format, struct disc_time *dt) {
+        char *orig_outwalk = outwalk;
         char *i;
         char *tibs_end = 0;
 
         for (i = format; *i != '\0'; i++) {
                 if (*i != '%') {
-                        putchar(*i);
+                        *(outwalk++) = *i;
                         continue;
                 }
                 switch (*(i+1)) {
                         /* Weekday in long and abbreviation */
                         case 'A':
-                                printf("%s", day_long[dt->week_day]);
+                                outwalk += sprintf(outwalk, "%s", day_long[dt->week_day]);
                                 break;
                         case 'a':
-                                printf("%s", day_short[dt->week_day]);
+                                outwalk += sprintf(outwalk, "%s", day_short[dt->week_day]);
                                 break;
                         /* Season in long and abbreviation */
                         case 'B':
-                                printf("%s", season_long[dt->season]);
+                                outwalk += sprintf(outwalk, "%s", season_long[dt->season]);
                                 break;
                         case 'b':
-                                printf("%s", season_short[dt->season]);
+                                outwalk += sprintf(outwalk, "%s", season_short[dt->season]);
                                 break;
                         /* Day of the season (ordinal and cardinal) */
                         case 'd':
-                                printf("%d", dt->season_day + 1);
+                                outwalk += sprintf(outwalk, "%d", dt->season_day + 1);
                                 break;
                         case 'e':
-                                printf("%d", dt->season_day + 1);
+                                outwalk += sprintf(outwalk, "%d", dt->season_day + 1);
                                 switch (dt->season_day) {
                                         case 0:
-                                                printf("st");
+                                                outwalk += sprintf(outwalk, "st");
                                                 break;
                                         case 1:
-                                                printf("nd");
+                                                outwalk += sprintf(outwalk, "nd");
                                                 break;
                                         case 2:
-                                                printf("rd");
+                                                outwalk += sprintf(outwalk, "rd");
                                                 break;
                                         default:
-                                                printf("th");
+                                                outwalk += sprintf(outwalk, "th");
                                                 break;
                                 }
                                 break;
                         /* YOLD */
                         case 'Y':
-                                printf("%d", dt->year);
+                                outwalk += sprintf(outwalk, "%d", dt->year);
                                 break;
                         /* Holidays */
                         case 'H':
                                 if (dt->season_day == 4) {
-                                        printf(holidays[dt->season]);
+                                        outwalk += sprintf(outwalk, "%s", holidays[dt->season]);
                                 }
                                 if (dt->season_day == 49) {
-                                        printf(holidays[dt->season + 5]);
+                                        outwalk += sprintf(outwalk, "%s", 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;
+                                        return (outwalk - orig_outwalk);
                                 }
                                 break;
                         /* Newline- and Tabbing-characters */
                         case 'n':
-                                printf("\n");
+                                outwalk += sprintf(outwalk, "\n");
                                 break;
                         case 't':
-                                printf("\t");
+                                outwalk += sprintf(outwalk, "\t");
                                 break;
                         /* The St. Tib's Day replacement */
                         case '{':
@@ -140,39 +145,34 @@ int format_output(char *format, struct disc_time *dt) {
                                 }
                                 if (dt->st_tibs_day) {
                                         /* We outpt "St. Tib's Day... */
-                                        printf("St. Tib's Day");
+                                        outwalk += sprintf(outwalk, "St. Tib's Day");
                                 } else {
                                         /* ...or parse the substring between %{ and %} ... */
-                                        *i = '\0';
-                                        if (!format_output(i + 2, dt)) return 0;
-                                        *i = '%';
+                                        *tibs_end = '\0';
+                                        outwalk += format_output(outwalk, i + 2, dt);
+                                        *tibs_end = '%';
                                 }
                                 /* ...and continue with the rest */
-                                i = tibs_end + 2;
+                                i = tibs_end;
                                 break;
                         case '}':
                                 i++;
                                 break;
                         default:
                                 /* No escape-sequence, so we just skip */
-                                printf("%%%c",*(i+1));
+                                outwalk += sprintf(outwalk, "%%%c", *(i+1));
                                 break;
                 }
                 i++;
         }
-        return 1;
+        return (outwalk - orig_outwalk);
 }
 
 /* Get the current date and convert it to discordian */
-struct disc_time *get_ddate() {
-        time_t current_time;
-        struct tm *current_tm;
+struct disc_time *get_ddate(struct tm *current_tm) {
         static struct disc_time dt;
 
-        if ((current_time = time(NULL)) == (time_t)-1)
-                return NULL;
-
-        if ((current_tm = localtime(&current_time)) == NULL)
+        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
@@ -180,31 +180,35 @@ struct disc_time *get_ddate() {
         int is_leap_year = !(current_tm->tm_year % 4) &&
                             (!(current_tm->tm_year % 400) || current_tm->tm_year % 100);
 
-        if (is_leap_year && current_tm->tm_yday == 59) {
+        /* If St. Tib's Day has passed, it will be necessary to skip a day. */
+        int yday = current_tm->tm_yday;
+
+        if (is_leap_year && 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;
-                }
+                if (is_leap_year && yday > 59)
+                        yday -= 1;
+
+                dt.season_day = yday % 73;
+                dt.week_day = yday % 5;
         }
         dt.year = current_tm->tm_year + 3066;
-        dt.season = current_tm->tm_yday / 73;
+        dt.season = yday / 73;
         return &dt;
 }
 
-void print_ddate(const char *format) {
+void print_ddate(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm) {
+        char *outwalk = buffer;
         static char *form = NULL;
         struct disc_time *dt;
-        if ((dt = get_ddate()) == NULL)
+        if ((dt = get_ddate(current_tm)) == NULL)
                 return;
         if (form == NULL)
                 if ((form = malloc(strlen(format) + 1)) == NULL)
                         return;
         strcpy(form, format);
-        format_output(form, dt);
+        outwalk += format_output(outwalk, form, dt);
+        OUTPUT_FULL_TEXT(buffer);
 }