6 #include <yajl/yajl_gen.h>
10 /* define fixed output-Strings */
11 char *season_long[5] = {
19 char *season_short[5] = {
35 char *day_short[5] = {
43 char *holidays[10] = {
56 /* A helper-struct, taking the discordian date */
65 /* Print the date *dt in format *format */
66 static int format_output(char *outwalk, char *format, struct disc_time *dt) {
67 char *orig_outwalk = outwalk;
71 for (i = format; *i != '\0'; i++) {
77 /* Weekday in long and abbreviation */
79 outwalk += sprintf(outwalk, "%s", day_long[dt->week_day]);
82 outwalk += sprintf(outwalk, "%s", day_short[dt->week_day]);
84 /* Season in long and abbreviation */
86 outwalk += sprintf(outwalk, "%s", season_long[dt->season]);
89 outwalk += sprintf(outwalk, "%s", season_short[dt->season]);
91 /* Day of the season (ordinal and cardinal) */
93 outwalk += sprintf(outwalk, "%d", dt->season_day + 1);
96 outwalk += sprintf(outwalk, "%d", dt->season_day + 1);
97 switch (dt->season_day) {
99 outwalk += sprintf(outwalk, "st");
102 outwalk += sprintf(outwalk, "nd");
105 outwalk += sprintf(outwalk, "rd");
108 outwalk += sprintf(outwalk, "th");
114 outwalk += sprintf(outwalk, "%d", dt->year);
118 if (dt->season_day == 4) {
119 outwalk += sprintf(outwalk, holidays[dt->season]);
121 if (dt->season_day == 49) {
122 outwalk += sprintf(outwalk, holidays[dt->season + 5]);
125 /* Stop parsing the format string, except on Holidays */
127 if (dt->season_day != 4 && dt->season_day != 49) {
128 return (outwalk - orig_outwalk);
131 /* Newline- and Tabbing-characters */
133 outwalk += sprintf(outwalk, "\n");
136 outwalk += sprintf(outwalk, "\t");
138 /* The St. Tib's Day replacement */
140 tibs_end = strstr(i, "%}");
141 if (tibs_end == NULL) {
145 if (dt->st_tibs_day) {
146 /* We outpt "St. Tib's Day... */
147 outwalk += sprintf(outwalk, "St. Tib's Day");
149 /* ...or parse the substring between %{ and %} ... */
151 outwalk += format_output(outwalk, i + 2, dt);
154 /* ...and continue with the rest */
161 /* No escape-sequence, so we just skip */
162 outwalk += sprintf(outwalk, "%%%c", *(i+1));
167 return (outwalk - orig_outwalk);
170 /* Get the current date and convert it to discordian */
171 struct disc_time *get_ddate(struct tm *current_tm) {
172 static struct disc_time dt;
174 if (current_tm == NULL)
177 /* We have to know, whether we have to insert St. Tib's Day, so whether it's a leap
178 year in gregorian calendar */
179 int is_leap_year = !(current_tm->tm_year % 4) &&
180 (!(current_tm->tm_year % 400) || current_tm->tm_year % 100);
182 if (is_leap_year && current_tm->tm_yday == 59) {
183 /* On St. Tibs Day we don't have to define a date */
187 dt.season_day = current_tm->tm_yday % 73;
188 if (is_leap_year && current_tm->tm_yday > 59) {
189 dt.week_day = (current_tm->tm_yday - 1) % 5;
191 dt.week_day = current_tm->tm_yday % 5;
194 dt.year = current_tm->tm_year + 3066;
195 dt.season = current_tm->tm_yday / 73;
199 void print_ddate(yajl_gen json_gen, char *buffer, const char *format, struct tm *current_tm) {
200 char *outwalk = buffer;
201 static char *form = NULL;
202 struct disc_time *dt;
203 if ((dt = get_ddate(current_tm)) == NULL)
206 if ((form = malloc(strlen(format) + 1)) == NULL)
208 strcpy(form, format);
209 outwalk += format_output(outwalk, form, dt);
210 OUTPUT_FULL_TEXT(buffer);