/* * Powerdog Industries kindly requests feedback from anyone modifying * this function: * * Date: Thu, 05 Jun 1997 23:17:17 -0400 * From: Kevin Ruddy * To: James FitzGibbon * Subject: Re: Use of your strptime(3) code (fwd) * * The reason for the "no mod" clause was so that modifications would * come back and we could integrate them and reissue so that a wider * audience could use it (thereby spreading the wealth). This has * made it possible to get strptime to work on many operating systems. * I'm not sure why that's "plain unacceptable" to the FreeBSD team. * * Anyway, you can change it to "with or without modification" as * you see fit. Enjoy. * * Kevin Ruddy * Powerdog Industries, Inc. */ /* * Copyright (c) 1994 Powerdog Industries. All rights reserved. * * 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 Powerdog Industries. * 4. The name of Powerdog Industries may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifdef LIBC_RCS static const char rcsid[] = "$Id: strptime.c,v 1.5 1999/04/25 01:42:18 wes Exp $"; #endif #ifndef lint #ifndef NOID static char copyright[] = "@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; static char sccsid[] = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; #endif /* !defined NOID */ #endif /* not lint */ #include #include #include #include "timelocal.h" #define asizeof(a) (sizeof (a) / sizeof ((a)[0])) char * strptime(const char *buf, const char *fmt, struct tm *tm) { char c; const char *ptr; int i, len; ptr = fmt; while (*ptr != 0) { if (*buf == 0) break; c = *ptr++; if (c != '%') { if (isspace((unsigned char)c)) while (*buf != 0 && isspace((unsigned char)*buf)) buf++; else if (c != *buf++) return 0; continue; } c = *ptr++; switch (c) { case 0: case '%': if (*buf++ != '%') return 0; break; case 'C': buf = strptime(buf, Locale->date_fmt, tm); if (buf == 0) return 0; break; case 'c': buf = strptime(buf, "%x %X", tm); if (buf == 0) return 0; break; case 'D': buf = strptime(buf, "%m/%d/%y", tm); if (buf == 0) return 0; break; case 'R': buf = strptime(buf, "%H:%M", tm); if (buf == 0) return 0; break; case 'r': buf = strptime(buf, "%I:%M:%S %p", tm); if (buf == 0) return 0; break; case 'T': buf = strptime(buf, "%H:%M:%S", tm); if (buf == 0) return 0; break; case 'X': buf = strptime(buf, Locale->X_fmt, tm); if (buf == 0) return 0; break; case 'x': buf = strptime(buf, Locale->x_fmt, tm); if (buf == 0) return 0; break; case 'j': if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (i > 365) return 0; tm->tm_yday = i; break; case 'M': case 'S': if (*buf == 0 || isspace((unsigned char)*buf)) break; if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (i > 59) return 0; if (c == 'M') tm->tm_min = i; else tm->tm_sec = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'H': case 'I': case 'k': case 'l': if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (c == 'H' || c == 'k') { if (i > 23) return 0; } else if (i > 11) return 0; tm->tm_hour = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'p': len = strlen(Locale->am); if (strncasecmp(buf, Locale->am, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour == 12) tm->tm_hour = 0; buf += len; break; } len = strlen(Locale->pm); if (strncasecmp(buf, Locale->pm, len) == 0) { if (tm->tm_hour > 12) return 0; if (tm->tm_hour != 12) tm->tm_hour += 12; buf += len; break; } return 0; case 'A': case 'a': for (i = 0; i < asizeof(Locale->weekday); i++) { len = strlen(Locale->weekday[i]); if (strncasecmp(buf, Locale->weekday[i], len) == 0) break; len = strlen(Locale->wday[i]); if (strncasecmp(buf, Locale->wday[i], len) == 0) break; } if (i == asizeof(Locale->weekday)) return 0; tm->tm_wday = i; buf += len; break; case 'd': case 'e': if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (i > 31) return 0; tm->tm_mday = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'B': case 'b': case 'h': for (i = 0; i < asizeof(Locale->month); i++) { len = strlen(Locale->month[i]); if (strncasecmp(buf, Locale->month[i], len) == 0) break; len = strlen(Locale->mon[i]); if (strncasecmp(buf, Locale->mon[i], len) == 0) break; } if (i == asizeof(Locale->month)) return 0; tm->tm_mon = i; buf += len; break; case 'm': if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (i < 1 || i > 12) return 0; tm->tm_mon = i - 1; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; case 'Y': case 'y': if (*buf == 0 || isspace((unsigned char)*buf)) break; if (!isdigit((unsigned char)*buf)) return 0; for (i = 0; *buf != 0 && isdigit((unsigned char)*buf); buf++) { i *= 10; i += *buf - '0'; } if (c == 'Y') i -= 1900; if (c == 'y' && i < 69) i += 100; if (i < 0) return 0; tm->tm_year = i; if (*buf != 0 && isspace((unsigned char)*buf)) while (*ptr != 0 && !isspace((unsigned char)*ptr)) ptr++; break; } } return (char *)buf; }