Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/libc
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2021-09-13 17:54:55 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-09-13 17:54:55 +0300
commitaccf188c783b67aedf703536b25db8187a6ce55b (patch)
treec89b325f813e513c530c87e19aa84d6551b902bc /src/libc
parentae987375ceada66cb9bcccf3a8ee8347ae1e0c5b (diff)
Tidied up strptime
Diffstat (limited to 'src/libc')
-rw-r--r--src/libc/strptime.cpp323
1 files changed, 185 insertions, 138 deletions
diff --git a/src/libc/strptime.cpp b/src/libc/strptime.cpp
index 70835714..9f82940b 100644
--- a/src/libc/strptime.cpp
+++ b/src/libc/strptime.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 Kungliga Tekniska H�gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,7 +31,7 @@
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/*
- * DC 2020/01/10: removged code for those format specifiers that need a locale and others that we don't need,
+ * DC 2020/01/10: removed code for those format specifiers that need a locale and others that we don't need,
* such as GNU-specific format specifiers, AM/PM specifiers, 12-hour clock specifiers, 2-digit year specifiers, and month and day number specifiers.
* The only format specifiers currently used by RepRapFirmware are: YmdHMS
*/
@@ -80,7 +80,9 @@ static int first_day (int year) noexcept
int ret = 4;
while (--year >= 1970)
- ret = (ret + 365 + is_leap_year (year)) % 7;
+ {
+ ret = (ret + 365 + is_leap_year (year)) % 7;
+ }
return ret;
}
@@ -94,148 +96,193 @@ const char *SafeStrptime(const char *buf, const char *format, struct tm *timeptr
char c;
int ymd = 0;
- for (; (c = *format) != '\0'; ++format) {
- const char *s;
- int ret;
-
- if (isspace_l ((unsigned char) c, locale)) {
- while (isspace_l ((unsigned char) *buf, locale))
- ++buf;
- } else if (c == '%' && format[1] != '\0') {
- c = *++format;
- if (c == 'E' || c == 'O')
- c = *++format;
- switch (c) {
- case 'd' :
- case 'e' :
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_mday = ret;
- buf = s;
- ymd |= SET_MDAY;
- break;
- case 'H' :
- case 'k' : /* hour with leading space - GNU extension */
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_hour = ret;
- buf = s;
- break;
- case 'm' :
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_mon = ret - 1;
- buf = s;
- ymd |= SET_MON;
- break;
- case 'M' :
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_min = ret;
- buf = s;
- break;
- case 'n' :
- if (*buf == '\n')
- ++buf;
- else
- return NULL;
- break;
- case 'S' :
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_sec = ret;
- buf = s;
- break;
- case 'Y' :
- ret = strtol_l (buf, &s, 10, locale);
- if (s == buf)
- return NULL;
- timeptr->tm_year = ret - tm_year_base;
- buf = s;
- ymd |= SET_YEAR;
- break;
- case 'Z' :
- /* Unsupported. Just ignore. */
- break;
- case '\0' :
- --format;
- /* FALLTHROUGH */
- /* no break - DC added for Eclipse */
- case '%' :
- if (*buf == '%')
- ++buf;
- else
- return NULL;
- break;
- default :
- if (*buf == '%' || *++buf == c)
- ++buf;
+ for (; (c = *format) != '\0'; ++format)
+ {
+ if (isspace_l ((unsigned char) c, locale))
+ {
+ while (isspace_l ((unsigned char) *buf, locale))
+ ++buf;
+ }
+ else if (c == '%' && format[1] != '\0')
+ {
+ c = *++format;
+ if (c == 'E' || c == 'O')
+ {
+ c = *++format;
+ }
+
+ switch (c)
+ {
+ case 'd' :
+ case 'e' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_mday = ret;
+ buf = s;
+ ymd |= SET_MDAY;
+ }
+ break;
+
+ case 'H' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_hour = ret;
+ buf = s;
+ }
+ break;
+
+ case 'm' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_mon = ret - 1;
+ buf = s;
+ ymd |= SET_MON;
+ }
+ break;
+
+ case 'M' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_min = ret;
+ buf = s;
+ }
+ break;
+
+ case 'n' :
+ if (*buf == '\n')
+ {
+ ++buf;
+ }
+ else
+ {
+ return nullptr;
+ }
+ break;
+
+ case 'S' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_sec = ret;
+ buf = s;
+ }
+ break;
+
+ case 'Y' :
+ {
+ const char *s;
+ const int ret = strtol_l (buf, &s, 10, locale);
+ if (s == buf) { return nullptr; }
+ timeptr->tm_year = ret - tm_year_base;
+ buf = s;
+ ymd |= SET_YEAR;
+ }
+ break;
+
+ case '\0' :
+ --format;
+ /* FALLTHROUGH */
+ /* no break - DC added for Eclipse */
+ case '%' :
+ if (*buf == '%')
+ {
+ ++buf;
+ }
+ else
+ {
+ return nullptr;
+ }
+ break;
+
+ default :
+ if (*buf == '%' || *++buf == c)
+ {
+ ++buf;
+ }
+ else
+ {
+ return nullptr;
+ }
+ break;
+ }
+ }
else
- return NULL;
- break;
- }
- } else {
- if (*buf == c)
- ++buf;
- else
- return NULL;
- }
+ {
+ if (*buf == c)
+ {
+ ++buf;
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
}
- if ((ymd & SET_YMD) == SET_YMD) {
- /* all of tm_year, tm_mon and tm_mday, but... */
-
- if (!(ymd & SET_YDAY)) {
- /* ...not tm_yday, so fill it in */
- timeptr->tm_yday = _DAYS_BEFORE_MONTH[timeptr->tm_mon]
- + timeptr->tm_mday;
- if (!is_leap_year (timeptr->tm_year + tm_year_base)
- || timeptr->tm_mon < 2)
- {
- timeptr->tm_yday--;
- }
- ymd |= SET_YDAY;
- }
+ if ((ymd & SET_YMD) == SET_YMD)
+ {
+ /* all of tm_year, tm_mon and tm_mday, but... */
+ if (!(ymd & SET_YDAY))
+ {
+ /* ...not tm_yday, so fill it in */
+ timeptr->tm_yday = _DAYS_BEFORE_MONTH[timeptr->tm_mon] + timeptr->tm_mday;
+ if (!is_leap_year(timeptr->tm_year + tm_year_base) || timeptr->tm_mon < 2)
+ {
+ timeptr->tm_yday--;
+ }
+ ymd |= SET_YDAY;
+ }
}
- else if ((ymd & (SET_YEAR | SET_YDAY)) == (SET_YEAR | SET_YDAY)) {
- /* both of tm_year and tm_yday, but... */
-
- if (!(ymd & SET_MON)) {
- /* ...not tm_mon, so fill it in, and/or... */
- if (timeptr->tm_yday < _DAYS_BEFORE_MONTH[1])
- timeptr->tm_mon = 0;
- else {
- int leap = is_leap_year (timeptr->tm_year + tm_year_base);
- int i;
- for (i = 2; i < 12; ++i) {
- if (timeptr->tm_yday < _DAYS_BEFORE_MONTH[i] + leap)
- break;
+ else if ((ymd & (SET_YEAR | SET_YDAY)) == (SET_YEAR | SET_YDAY))
+ {
+ /* both of tm_year and tm_yday, but... */
+ if (!(ymd & SET_MON))
+ {
+ /* ...not tm_mon, so fill it in, and/or... */
+ if (timeptr->tm_yday < _DAYS_BEFORE_MONTH[1])
+ {
+ timeptr->tm_mon = 0;
+ }
+ else
+ {
+ int leap = is_leap_year (timeptr->tm_year + tm_year_base);
+ int i;
+ for (i = 2; i < 12; ++i)
+ {
+ if (timeptr->tm_yday < _DAYS_BEFORE_MONTH[i] + leap)
+ {
+ break;
+ }
+ }
+ timeptr->tm_mon = i - 1;
+ }
+ }
+
+ if (!(ymd & SET_MDAY))
+ {
+ /* ...not tm_mday, so fill it in */
+ timeptr->tm_mday = timeptr->tm_yday - _DAYS_BEFORE_MONTH[timeptr->tm_mon];
+ if (!is_leap_year (timeptr->tm_year + tm_year_base) || timeptr->tm_mon < 2)
+ {
+ timeptr->tm_mday++;
+ }
}
- timeptr->tm_mon = i - 1;
- }
- }
-
- if (!(ymd & SET_MDAY)) {
- /* ...not tm_mday, so fill it in */
- timeptr->tm_mday = timeptr->tm_yday
- - _DAYS_BEFORE_MONTH[timeptr->tm_mon];
- if (!is_leap_year (timeptr->tm_year + tm_year_base)
- || timeptr->tm_mon < 2)
- {
- timeptr->tm_mday++;
- }
- }
}
- if ((ymd & (SET_YEAR | SET_YDAY | SET_WDAY)) == (SET_YEAR | SET_YDAY)) {
- /* fill in tm_wday */
- int fday = first_day (timeptr->tm_year + tm_year_base);
- timeptr->tm_wday = (fday + timeptr->tm_yday) % 7;
+ if ((ymd & (SET_YEAR | SET_YDAY | SET_WDAY)) == (SET_YEAR | SET_YDAY))
+ {
+ /* fill in tm_wday */
+ int fday = first_day (timeptr->tm_year + tm_year_base);
+ timeptr->tm_wday = (fday + timeptr->tm_yday) % 7;
}
return buf;