diff --git a/libs/libc/time/CMakeLists.txt b/libs/libc/time/CMakeLists.txt index 611dadfa93783..5d99f5c0e54a2 100644 --- a/libs/libc/time/CMakeLists.txt +++ b/libs/libc/time/CMakeLists.txt @@ -21,7 +21,6 @@ set(SRCS lib_strftime.c - lib_strptime.c lib_calendar2utc.c lib_daysbeforemonth.c lib_gettimeofday.c diff --git a/libs/libc/time/Make.defs b/libs/libc/time/Make.defs index e4fbbf16bb0aa..65553c6c1cd31 100644 --- a/libs/libc/time/Make.defs +++ b/libs/libc/time/Make.defs @@ -20,7 +20,7 @@ # Add the time C files to the build -CSRCS += lib_strftime.c lib_strptime.c lib_calendar2utc.c lib_daysbeforemonth.c +CSRCS += lib_strftime.c lib_calendar2utc.c lib_daysbeforemonth.c CSRCS += lib_gettimeofday.c lib_isleapyear.c lib_settimeofday.c lib_time.c CSRCS += lib_timespec_get.c lib_nanosleep.c lib_difftime.c lib_dayofweek.c CSRCS += lib_asctime.c lib_asctimer.c lib_ctime.c lib_ctimer.c diff --git a/libs/libc/time/lib_strptime.c b/libs/libc/time/lib_strptime.c deleted file mode 100644 index 93a011eb9a346..0000000000000 --- a/libs/libc/time/lib_strptime.c +++ /dev/null @@ -1,624 +0,0 @@ -/**************************************************************************** - * libs/libc/time/lib_strptime.c - * - * $OpenBSD: strptime.c,v 1.11 2005/08/08 08:05:38 espie Exp $ - * $NetBSD: strptime.c,v 1.12 1998/01/20 21:39:40 mycroft Exp $ - * - * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code was contributed to The NetBSD Foundation by Klaus Klein. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ -#include - -#include -#include -#include - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#define _ctloc(x) (g_defaulttimelocale.x) - -/* We do not implement alternate representations. However, we always - * check whether a given modifier is allowed for a certain conversion. - */ - -#define _ALT_E 0x01 -#define _ALT_O 0x02 -#define _LEGAL_ALT(x) { if (alt_format & ~(x)) return (NULL); } - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static const struct -{ - const char *abday[7]; - const char *day[7]; - const char *abmon[12]; - const char *mon[12]; - const char *am_pm[2]; - const char *d_t_fmt; - const char *d_fmt; - const char *t_fmt; - const char *t_fmt_ampm; -} g_defaulttimelocale = -{ - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", - }, - { - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday" - }, - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }, - { - "January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December" - }, - { - "AM", "PM" - }, - "%a %b %d %H:%M:%S %Y", - "%m/%d/%y", - "%H:%M:%S", - "%I:%M:%S %p" -}; - -struct century_relyear -{ - int century; - int relyear; -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int _conv_num(FAR const unsigned char **buf, FAR int *dest, - int llim, int ulim) -{ - int result = 0; - int rulim = ulim; - - while (isspace(**buf)) - { - (*buf)++; - } - - if (**buf < '0' || **buf > '9') - { - return 0; - } - - /* we use rulim to break out of the loop when we run out of digits */ - - do - { - result *= 10; - result += *(*buf)++ - '0'; - rulim /= 10; - } - while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9'); - - if (result < llim || result > ulim) - { - return 0; - } - - *dest = result; - return 1; -} - -static FAR const unsigned char *_strptime(FAR const unsigned char *buf, - FAR const char *fmt, - FAR struct tm *tm, - FAR struct century_relyear *cr) -{ - unsigned char c; - FAR const unsigned char *bp; - size_t len = 0; - int alt_format; - int i; - - bp = buf; - while ((c = *fmt) != '\0') - { - /* Clear `alternate' modifier prior to new conversion. */ - - alt_format = 0; - - /* Eat up white-space. */ - - if (isspace(c)) - { - while (isspace(*bp)) - bp++; - - fmt++; - continue; - } - - if ((c = *fmt++) != '%') - { - goto literal; - } - -again: - switch (c = *fmt++) - { - case '%': /* "%%" is converted to "%". */ -literal: - if (c != *bp++) - { - return NULL; - } - - break; - - /* "Alternative" modifiers. Just set the appropriate flag - * and start over again. - */ - - case 'E': /* "%E?" alternative conversion modifier. */ - _LEGAL_ALT(0); - alt_format |= _ALT_E; - goto again; - - case 'O': /* "%O?" alternative conversion modifier. */ - _LEGAL_ALT(0); - alt_format |= _ALT_O; - goto again; - - /* "Complex" conversion rules, implemented through recursion. */ - - case 'c': /* Date and time, using the locale's format. */ - _LEGAL_ALT(_ALT_E); - if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, cr))) - { - return NULL; - } - - break; - - case 'D': /* The date as "%m/%d/%y". */ - _LEGAL_ALT(0); - if (!(bp = _strptime(bp, "%m/%d/%y", tm, cr))) - { - return NULL; - } - - break; - - case 'R': /* The time as "%H:%M". */ - _LEGAL_ALT(0); - if (!(bp = _strptime(bp, "%H:%M", tm, cr))) - { - return NULL; - } - - break; - - case 'r': /* The time as "%I:%M:%S %p". */ - _LEGAL_ALT(0); - if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, cr))) - { - return NULL; - } - - break; - - case 'T': /* The time as "%H:%M:%S". */ - _LEGAL_ALT(0); - if (!(bp = _strptime(bp, "%H:%M:%S", tm, cr))) - { - return NULL; - } - - break; - - case 'X': /* The time, using the locale's format. */ - _LEGAL_ALT(_ALT_E); - if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, cr))) - { - return NULL; - } - - break; - - case 'x': /* The date, using the locale's format. */ - _LEGAL_ALT(_ALT_E); - if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, cr))) - { - return NULL; - } - - break; - - /* "Elementary" conversion rules. */ - - case 'A': /* The day of week, using the locale's form. */ - case 'a': - _LEGAL_ALT(0); - for (i = 0; i < 7; i++) - { - /* Full name. */ - - len = strlen(_ctloc(day[i])); - if (strncasecmp(_ctloc(day[i]), - (const char *)bp, len) == 0) - break; - - /* Abbreviated name. */ - - len = strlen(_ctloc(abday[i])); - if (strncasecmp(_ctloc(abday[i]), - (const char *)bp, len) == 0) - break; - } - - /* Nothing matched. */ - - if (i == 7) - { - return NULL; - } - - tm->tm_wday = i; - bp += len; - break; - - case 'B': /* The month, using the locale's form. */ - case 'b': - case 'h': - _LEGAL_ALT(0); - for (i = 0; i < 12; i++) - { - /* Full name. */ - - len = strlen(_ctloc(mon[i])); - if (strncasecmp(_ctloc(mon[i]), - (const char *)bp, len) == 0) - { - break; - } - - /* Abbreviated name. */ - - len = strlen(_ctloc(abmon[i])); - if (strncasecmp(_ctloc(abmon[i]), - (const char *)bp, len) == 0) - { - break; - } - } - - /* Nothing matched. */ - - if (i == 12) - { - return NULL; - } - - tm->tm_mon = i; - bp += len; - break; - - case 'C': /* The century number. */ - _LEGAL_ALT(_ALT_E); - if (!(_conv_num(&bp, &i, 0, 99))) - { - return (NULL); - } - - cr->century = i * 100; - break; - - case 'd': /* The day of month. */ - case 'e': - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_mday, 1, 31))) - { - return (NULL); - } - - break; - - case 'k': /* The hour (24-hour clock representation). */ - _LEGAL_ALT(0); - - /* FALLTHROUGH */ - - case 'H': - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_hour, 0, 23))) - { - return NULL; - } - - break; - - case 'l': /* The hour (12-hour clock representation). */ - _LEGAL_ALT(0); - - /* FALLTHROUGH */ - - case 'I': - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_hour, 1, 12))) - { - return (NULL); - } - - break; - - case 'j': /* The day of year. */ - _LEGAL_ALT(0); - if (!(_conv_num(&bp, &tm->tm_yday, 1, 366))) - { - return NULL; - } - - tm->tm_yday--; - break; - - case 'M': /* The minute. */ - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_min, 0, 59))) - { - return NULL; - } - - break; - - case 'm': /* The month. */ - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_mon, 1, 12))) - { - return NULL; - } - - tm->tm_mon--; - break; - - case 'p': /* The locale's equivalent of AM/PM. */ - _LEGAL_ALT(0); - - /* AM? */ - - len = strlen(_ctloc(am_pm[0])); - if (strncasecmp(_ctloc(am_pm[0]), (const char *)bp, len) == 0) - { - if (tm->tm_hour > 12) /* i.e., 13:00 AM ?! */ - { - return NULL; - } - else if (tm->tm_hour == 12) - { - tm->tm_hour = 0; - } - - bp += len; - break; - } - - /* PM? */ - - len = strlen(_ctloc(am_pm[1])); - if (strncasecmp(_ctloc(am_pm[1]), (const char *)bp, len) == 0) - { - if (tm->tm_hour > 12) /* i.e., 13:00 PM ?! */ - { - return NULL; - } - else if (tm->tm_hour < 12) - { - tm->tm_hour += 12; - } - - bp += len; - break; - } - - /* Nothing matched. */ - - return NULL; - - case 'S': /* The seconds. */ - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_sec, 0, 61))) - { - return NULL; - } - - break; - - case 'U': /* The week of year, beginning on sunday. */ - case 'W': /* The week of year, beginning on monday. */ - _LEGAL_ALT(_ALT_O); - /* XXX This is bogus, as we can not assume any valid - * information present in the tm structure at this - * point to calculate a real value, so just check the - * range for now. - */ - - if (!(_conv_num(&bp, &i, 0, 53))) - { - return NULL; - } - - break; - - case 'w': /* The day of week, beginning on sunday. */ - _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_wday, 0, 6))) - { - return NULL; - } - - break; - - case 'Y': /* The year. */ - _LEGAL_ALT(_ALT_E); - if (!(_conv_num(&bp, &i, 0, 9999))) - { - return NULL; - } - - cr->relyear = -1; - tm->tm_year = i - TM_YEAR_BASE; - break; - - case 'y': /* The year within the century (2 digits). */ - _LEGAL_ALT(_ALT_E | _ALT_O); - if (!(_conv_num(&bp, &cr->relyear, 0, 99))) - { - return NULL; - } - - break; - - /* Miscellaneous conversions. */ - - case 'n': /* Any kind of white-space. */ - case 't': - _LEGAL_ALT(0); - while (isspace(*bp)) - { - bp++; - } - - break; - - default: /* Unknown/unsupported conversion. */ - return NULL; - } - } - - /* We need to evaluate the two digit year spec (%y) - * last as we can get a century spec (%C) at any time. - */ - - if (cr->relyear != -1) - { - if (cr->century == TM_YEAR_BASE) - { - if (cr->relyear <= 68) - { - tm->tm_year = cr->relyear + 2000 - TM_YEAR_BASE; - } - else - { - tm->tm_year = cr->relyear + 1900 - TM_YEAR_BASE; - } - } - else - { - tm->tm_year = cr->relyear + cr->century - TM_YEAR_BASE; - } - } - - return bp; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: strptime - * - * Description: - * Convert a string to a time type according to a specific time format - * The strptime() function processes the input string from left to - * right. Each of the three possible input elements (whitespace, - * literal, or format) are handled one after the other. If the - * input cannot be matched to the format string, the function stops. - * The remainder of the format and input strings are not processed. - * The supported input field descriptors are listed below. In case - * a text string (such as the name of a day of the week or a month - * name) is to be matched, the comparison is case insensitive. In - * case a number is to be matched, leading zeros are permitted but - * not required. - * %a The abbreviated weekday name according to the current locale. - * %A The full weekday name according to the current locale. - * %b The abbreviated month name according to the current locale. - * %B The full month name according to the current locale. - * %C The century number (year/100) as a 2-digit integer. (SU) - * %d The day of the month as a decimal number (range 01 to 31). - * %e Like %d, the day of the month as a decimal number, but a leading - * zero is replaced by a space. - * %h Equivalent to %b. (SU) - * %H The hour as a decimal number using a 24-hour clock - * (range 00 to 23). - * %I The hour as a decimal number using a 12-hour clock - * (range 01 to 12). - * %j The day of the year as a decimal number (range 001 to 366). - * %k The hour (24-hour clock) as a decimal number (range 0 to 23); - * single digits are preceded by a blank. (See also %H.) (TZ) - * %l The hour (12-hour clock) as a decimal number (range 1 to 12); - * single digits are preceded by a blank. (See also %I.) (TZ) - * %m The month as a decimal number (range 01 to 12). - * %M The minute as a decimal number (range 00 to 59). - * %n A newline character. (SU) - * %p Either "AM" or "PM" according to the given time value, or the - * corresponding strings for the current locale. Noon is treated - * as "PM" and midnight as "AM". - * %P Like %p but in lowercase: "am" or "pm" or a corresponding string - * for the current locale. (GNU) - * %S The second as a decimal number (range 00 to 60). (The range is - * up to 60 to allow for occasional leap seconds.) - * %t A tab character. (SU) - * %y The year as a decimal number without a century (range 00 to 99). - * %Y The year as a decimal number including the century. - * %% A literal '%' character. - * - * Returned Value: - * The return value of the function is a pointer to the first - * character not processed in this function call. In case the input - * string contains more characters than required by the format - * string, the return value points right after the last consumed - * input character. In case the whole input string is consumed, the - * return value points to the null byte at the end of the string. - * If strptime() fails to match all of the format string and - * therefore an error occurred, the function returns NULL. - * - ****************************************************************************/ - -FAR char *strptime(FAR const char *buf, FAR const char *fmt, - FAR struct tm *tm) -{ - struct century_relyear cr; - cr.century = TM_YEAR_BASE; - cr.relyear = -1; - return (FAR char *)(_strptime((FAR const unsigned char *)buf, - fmt, tm, &cr)); -}