From 0c071d6e1c52006e1a582ccb1ba5b2c31e6bc1d8 Mon Sep 17 00:00:00 2001 From: Tim Crews Date: Sat, 15 Jun 2013 16:37:04 -0700 Subject: Corrected filename for strptime.cc --- src/strptime.cc | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/strptime.cc (limited to 'src/strptime.cc') diff --git a/src/strptime.cc b/src/strptime.cc new file mode 100644 index 00000000..b64af96b --- /dev/null +++ b/src/strptime.cc @@ -0,0 +1,189 @@ +// Copyright 2009 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#ifdef WIN32 +// Implement strptime under windows + +#include "strptime.h" + +#include +#include +#include + +static const char* kWeekFull[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; + +static const char* kWeekAbbr[] = { + "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" +}; + +static const char* kMonthFull[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; + +static const char* kMonthAbbr[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static const char* _parse_num(const char* s, int low, int high, int* value) { + const char* p = s; + for (*value = 0; *p != NULL && isdigit(*p); ++p) { + *value = (*value) * 10 + static_cast(*p) - static_cast('0'); + } + + if (p == s || *value < low || *value > high) return NULL; + return p; +} + +static char* _strptime(const char *s, const char *format, struct tm *tm) { + while (*format != NULL && *s != NULL) { + if (*format != '%') { + if (*s != *format) return NULL; + + ++format; + ++s; + continue; + } + + ++format; + int len = 0; + switch (*format) { + // weekday name. + case 'a': + case 'A': + tm->tm_wday = -1; + for (int i = 0; i < 7; ++i) { + len = static_cast(strlen(kWeekAbbr[i])); + if (strnicmp(kWeekAbbr[i], s, len) == 0) { + tm->tm_wday = i; + break; + } + + len = static_cast(strlen(kWeekFull[i])); + if (strnicmp(kWeekFull[i], s, len) == 0) { + tm->tm_wday = i; + break; + } + } + if (tm->tm_wday == -1) return NULL; + s += len; + break; + + // month name. + case 'b': + case 'B': + case 'h': + tm->tm_mon = -1; + for (int i = 0; i < 12; ++i) { + len = static_cast(strlen(kMonthAbbr[i])); + if (strnicmp(kMonthAbbr[i], s, len) == 0) { + tm->tm_mon = i; + break; + } + + len = static_cast(strlen(kMonthFull[i])); + if (strnicmp(kMonthFull[i], s, len) == 0) { + tm->tm_mon = i; + break; + } + } + if (tm->tm_mon == -1) return NULL; + s += len; + break; + + // month [1, 12]. + case 'm': + s = _parse_num(s, 1, 12, &tm->tm_mon); + if (s == NULL) return NULL; + --tm->tm_mon; + break; + + // day [1, 31]. + case 'd': + case 'e': + s = _parse_num(s, 1, 31, &tm->tm_mday); + if (s == NULL) return NULL; + break; + + // hour [0, 23]. + case 'H': + s = _parse_num(s, 0, 23, &tm->tm_hour); + if (s == NULL) return NULL; + break; + + // minute [0, 59] + case 'M': + s = _parse_num(s, 0, 59, &tm->tm_min); + if (s == NULL) return NULL; + break; + + // seconds [0, 60]. 60 is for leap year. + case 'S': + s = _parse_num(s, 0, 60, &tm->tm_sec); + if (s == NULL) return NULL; + break; + + // year [1900, 9999]. + case 'Y': + s = _parse_num(s, 1900, 9999, &tm->tm_year); + if (s == NULL) return NULL; + tm->tm_year -= 1900; + break; + + // year [0, 99]. + case 'y': + s = _parse_num(s, 0, 99, &tm->tm_year); + if (s == NULL) return NULL; + if (tm->tm_year <= 68) { + tm->tm_year += 100; + } + break; + + // arbitray whitespace. + case 't': + case 'n': + while (isspace(*s)) ++s; + break; + + // '%'. + case '%': + if (*s != '%') return NULL; + ++s; + break; + + // All the other format are not supported. + default: + return NULL; + } + ++format; + } + + if (*format != NULL) { + return NULL; + } else { + return const_cast(s); + } +} + +char* strptime(const char *buf, const char *fmt, struct tm *tm) { + return _strptime(buf, fmt, tm); +} + +#endif // WIN32 -- cgit v1.2.3