Exemplo n.º 1
0
char *
conv_date_pict (
    long date,
    const char *picture)
{
    static char
        *month_name [] =
          {
            "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "October", "November", "December"
          },
        *day_name [] =
          {
            "Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"
          },
        formatted [FORMAT_MAX + 1];     /*  Formatted return string          */
    int
        century,                        /*  Century component of date        */
        year,                           /*  Year component of date           */
        month,                          /*  Month component of date          */
        day,                            /*  Day component of date            */
        cursize;                        /*  Size of current component        */
    char
       *dest,                           /*  Store formatted data here        */
        ch,                             /*  Next character in picture        */
        lastch = '0';                   /*  Last character we output         */
    long
        full_date = date;

    conv_reason = 0;                    /*  No conversion errors so far      */

    /*  Zero date is returned as empty string                                */
    if (date == 0)
      {
        strclr (formatted);
        return (formatted);
      }

    default_century (&full_date);
    century = GET_CENTURY (full_date);
    year    = GET_YEAR    (full_date);
    month   = GET_MONTH   (full_date);
    day     = GET_DAY     (full_date);

    ASSERT (month > 0 && month <= 12);
    ASSERT (day   > 0 && day   <= 31);

    /*  Scan through picture, converting each component                      */
    dest = formatted;
    *dest = 0;                          /*  string is empty                  */
    while (*picture)
      {
        /*  Get character and count number of occurences                     */
        ch = *picture++;
        for (cursize = 1; *picture == ch; cursize++)
            picture++;

        switch (ch)
          {
            /*  cc        century 2 digits, 01-99                            */
            case 'c':
                if (cursize == 2)
                    sprintf (dest, "%02d", century);
                break;

            /*  y         day of year, 1-366                                 */
            /*  yy        year 2 digits, 00-99                               */
            /*  yyyy      year 4 digits, 0100-9999                           */
            case 'y':                   /*  y = day of year                  */
                if (cursize == 1)
                    sprintf (dest, "%d", julian_date (full_date));
                else
                if (cursize == 2)
                    sprintf (dest, "%02d", year);
                else
                if (cursize == 4)
                    sprintf (dest, "%02d%02d", century, year);
                break;

            /*  m         month, 1-12                                        */
            /*  mm        month, 01-12                                       */
            /*  mmm       month, 3 letters                                   */
            /*  mmmm      month, full name                                   */
            case 'm':
                if (cursize == 1)
                    sprintf (dest, (isdigit (lastch)? "%2d": "%d"), month);
                else
                if (cursize == 2)
                    sprintf (dest, "%02d", month);
                else
                if (cursize == 3)
                  {
                    memcpy (dest, month_name [month - 1], 3);
                    dest [3] = 0;
                  }
                else
                if (cursize == 4)
                    strcpy (dest, month_name [month - 1]);
                break;

            /*  MMM       month, 3-letters, ucase                            */
            /*  MMMM      month, full name, ucase                            */
            case 'M':
                if (cursize == 3)
                  {
                    memcpy (dest, month_name [month - 1], 3);
                    dest [3] = 0;
                    strupc (dest);
                  }
                else
                if (cursize == 4)
                  {
                    strcpy (dest, month_name [month - 1]);
                    strupc (dest);
                  }
                break;

            /*  d         day, 1-31                                          */
            /*  dd        day, 01-31                                         */
            /*  ddd       day of week, Sun-Sat                               */
            /*  dddd      day of week, Sunday-Saturday                       */
            case 'd':
                if (cursize == 1)
                    sprintf (dest, (isdigit (lastch)? "%2d": "%d"), day);
                else
                if (cursize == 2)
                    sprintf (dest, "%02d", day);
                else
                if (cursize == 3)
                  {
                    memcpy (dest, day_name [day_of_week (full_date)], 3);
                    dest [3] = 0;
                  }
                else
                if (cursize == 4)
                    strcpy (dest, day_name [day_of_week (full_date)]);
                break;

            /*  DDD       day of week, SUN-SAT                               */
            /*  DDDD      day of week, SUNDAY-SATURDAY                       */
            case 'D':
                if (cursize == 3)
                  {
                    memcpy (dest, day_name [day_of_week (full_date)], 3);
                    dest [3] = 0;
                    strupc (dest);
                  }
                else
                if (cursize == 4)
                  {
                    strcpy (dest, day_name [day_of_week (full_date)]);
                    strupc (dest);
                  }
                break;

            /*  w         day of week, 1-7 (1=Sunday)                        */
            /*  ww        week of year, 1-53                                 */
            case 'w':
                if (cursize == 1)
                    sprintf (dest, "%d", day_of_week (full_date) + 1);
                else
                if (cursize == 2)
                    sprintf (dest, "%d", week_of_year (full_date));
                break;

            /*  q         year quarter, 1-4                                  */
            case 'q':
                if (cursize == 1)
                    sprintf (dest, "%d", year_quarter (full_date));
                break;

            /*  \x        literal character x                                */
            case '\\':
                ch = *picture++;
        }
        if (*dest)                      /*  If something was output,         */
            while (*dest)               /*    skip to end of string          */
                dest++;
        else
            while (cursize--)           /*  Else output ch once or more      */
                *dest++ = ch;           /*    and bump dest pointer          */

        lastch = *(dest - 1);           /*  Get previous character           */
        *dest = 0;                      /*  Terminate the string nicely      */
    }
    return (formatted);
}
Exemplo n.º 2
0
size_t
strftime(char *buffer, size_t limit, const char *pattern, const struct tm * timeptr)
{
	unsigned int    count, length;
	int             d, w;
	char            c;
	char            _store[26];
	struct week_date wd;

	count = length = 0;
	while (count < limit) {
		c = *pattern++;
		if (c == '%') {
			c = *pattern++;
			if (c == 'E' || c == 'O')
				c = *pattern++;
			switch (c) {
			case ('%'):
				_store[0] = c;
				length = 1;
				break;

			case ('a'):
				length = pgm_copystring(strfwkdays, timeptr->tm_wday, _store, 3);
				break;

			case ('A'):
				length = pgm_copystring(strfwkdays, timeptr->tm_wday, _store, 255);
				break;

			case ('b'):
			case ('h'):
				length = pgm_copystring(strfmonths, timeptr->tm_mon, _store, 3);
				break;

			case ('B'):
				length = pgm_copystring(strfmonths, timeptr->tm_mon, _store, 255);
				break;

			case ('c'):
				asctime_r(timeptr, _store);
				length = 0;
				while (_store[length])
					length++;
				break;

			case ('C'):
				d = timeptr->tm_year + 1900;
				d /= 100;
				length = sprintf(_store, "%.2d", d);
				break;

			case ('d'):
				length = sprintf(_store, "%.2u", timeptr->tm_mday);
				break;

			case ('D'):
				length = sprintf(_store, "%.2u/%.2u/%.2u", \
						 timeptr->tm_mon + 1, \
						 timeptr->tm_mday, \
						 timeptr->tm_year % 100 \
					);
				break;

			case ('e'):
				length = sprintf(_store, "%2d", timeptr->tm_mday);
				break;

			case ('F'):
				length = sprintf(_store, "%d-%.2d-%.2d", \
						 timeptr->tm_year + 1900, \
						 timeptr->tm_mon + 1, \
						 timeptr->tm_mday \
					);
				break;

			case ('g'):
			case ('G'):
				iso_week_date_r(timeptr->tm_year + 1900, timeptr->tm_yday, &wd);
				if (c == 'g') {
					length = sprintf(_store, "%.2d", wd.year % 100);
				} else {
					length = sprintf(_store, "%.4d", wd.year);
				}

				break;

			case ('H'):
				length = sprintf(_store, "%.2u", timeptr->tm_hour);
				break;

			case ('I'):
				d = timeptr->tm_hour % 12;
				if (d == 0)
					d = 12;
				length = sprintf(_store, "%.2u", d);
				break;

			case ('j'):
				length = sprintf(_store, "%.3u", timeptr->tm_yday + 1);
				break;

			case ('m'):
				length = sprintf(_store, "%.2u", timeptr->tm_mon + 1);
				break;

			case ('M'):
				length = sprintf(_store, "%.2u", timeptr->tm_min);
				break;

			case ('n'):
				_store[0] = 10;
				length = 1;
				break;

			case ('p'):
				length = 2;
				_store[0] = 'A';
				if (timeptr->tm_hour > 11)
					_store[0] = 'P';
				_store[1] = 'M';
				_store[2] = 0;
				break;

			case ('r'):
				d = timeptr->tm_hour % 12;
				if (d == 0)
					d = 12;
				length = sprintf(_store, "%2d:%.2d:%.2d AM", \
						 d, \
						 timeptr->tm_min, \
						 timeptr->tm_sec \
					);
				if (timeptr->tm_hour > 11)
					_store[10] = 'P';
				break;

			case ('R'):
				length = sprintf(_store, "%.2d:%.2d", timeptr->tm_hour, timeptr->tm_min);
				break;

			case ('S'):
				length = sprintf(_store, "%.2u", timeptr->tm_sec);
				break;

			case ('t'):
				length = sprintf(_store, "\t");
				break;

			case ('T'):
				length = sprintf(_store, "%.2d:%.2d:%.2d", \
						 timeptr->tm_hour, \
						 timeptr->tm_min, \
						 timeptr->tm_sec \
					);
				break;

			case ('u'):
				w = timeptr->tm_wday;
				if (w == 0)
					w = 7;
				length = sprintf(_store, "%d", w);
				break;

			case ('U'):
				length = sprintf(_store, "%.2u", week_of_year(timeptr, 0));
				break;

			case ('V'):
				iso_week_date_r(timeptr->tm_year + 1900, timeptr->tm_yday, &wd);
				length = sprintf(_store, "%.2u", wd.week);
				break;

			case ('w'):
				length = sprintf(_store, "%u", timeptr->tm_wday);
				break;

			case ('W'):
				w = week_of_year(timeptr, 1);
				length = sprintf(_store, "%.2u", w);
				break;

			case ('x'):
				length = sprintf(_store, "%.2u/%.2u/%.2u", timeptr->tm_mon + 1, timeptr->tm_mday, timeptr->tm_year % 100);
				break;

			case ('X'):
				length = sprintf(_store, "%.2u:%.2u:%.2u", timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec);
				break;

			case ('y'):
				length = sprintf(_store, "%.2u", timeptr->tm_year % 100);
				break;

			case ('Y'):
				length = sprintf(_store, "%u", timeptr->tm_year + 1900);
				break;

			case ('z'):
				d = __utc_offset / 60;
				w = timeptr->tm_isdst / 60;
				if (w > 0)
					d += w;
				w = abs(d % 60);
				d = d / 60;
				length = sprintf(_store, "%+.2d%.2d", d, w);
				break;

			default:
				length = 1;
				_store[0] = '?';
				_store[1] = 0;
				break;
			}

			if ((length + count) < limit) {
				count += length;
				for (d = 0; d < (int) length; d++) {
					*buffer++ = _store[d];
				}
			} else {
				*buffer = 0;
				return count;
			}

		} else {	/* copy a literal */
			*buffer = c;
			buffer++;
			count++;
			if (c == 0)
				return count;
		}
	}

	*buffer = 0;
	return count;
}