+ switch (ch)
+ {
+ case 'd':
+ if (count < 3)
+ p += sprintf (p, "%02d", day);
+ else
+ p += sprintf (p, "%03d", yday);
+ break;
+ case 'm':
+ if (count < 3)
+ p += sprintf (p, "%02d", month);
+ else
+ {
+ static const char *const months[12] =
+ {
+ "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
+ "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
+ };
+ p = stpcpy (p, months[month - 1]);
+ }
+ break;
+ case 'y':
+ if (count >= 4 || excess_width >= 2)
+ {
+ if (year <= 9999)
+ p += sprintf (p, "%04d", year);
+ else if (format->type == FMT_DATETIME)
+ p = stpcpy (p, "****");
+ else
+ goto overflow;
+ }
+ else
+ {
+ int epoch = settings_get_epoch ();
+ int offset = year - epoch;
+ if (offset < 0 || offset > 99)
+ goto overflow;
+ p += sprintf (p, "%02d", abs (year) % 100);
+ }
+ break;
+ case 'q':
+ p += sprintf (p, "%d", (month - 1) / 3 + 1);
+ break;
+ case 'w':
+ p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
+ break;
+ case 'D':
+ if (number < 0)
+ *p++ = '-';
+ number = fabs (number);
+ p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
+ number = fmod (number, 60. * 60. * 24.);
+ break;
+ case 'H':
+ if (number < 0)
+ *p++ = '-';
+ number = fabs (number);
+ p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
+ number = fmod (number, 60. * 60.);
+ break;
+ case 'M':
+ p += sprintf (p, "%02d", (int) floor (number / 60.));
+ number = fmod (number, 60.);
+ excess_width = format->w - (p - tmp);
+ if (excess_width < 0)
+ goto overflow;
+ if (excess_width == 3 || excess_width == 4
+ || (excess_width >= 5 && format->d == 0))
+ p += sprintf (p, ":%02d", (int) number);
+ else if (excess_width >= 5)
+ {
+ int d = MIN (format->d, excess_width - 4);
+ int w = d + 3;
+ sprintf (p, ":%0*.*f", w, d, number);
+ if (settings_get_decimal_char (FMT_F) != '.')
+ {
+ char *cp = strchr (p, '.');
+ if (cp != NULL)
+ *cp = settings_get_decimal_char (FMT_F);
+ }
+ p += strlen (p);
+ }
+ break;
+ case 'X':
+ *p++ = ' ';
+ break;
+ default:
+ assert (count == 1);
+ *p++ = ch;
+ break;
+ }
+ }