diff options
Diffstat (limited to 'usr/src/lib/libbc/libc/gen/common/strptime.c')
-rw-r--r-- | usr/src/lib/libbc/libc/gen/common/strptime.c | 483 |
1 files changed, 0 insertions, 483 deletions
diff --git a/usr/src/lib/libbc/libc/gen/common/strptime.c b/usr/src/lib/libbc/libc/gen/common/strptime.c deleted file mode 100644 index bfd7aef821..0000000000 --- a/usr/src/lib/libbc/libc/gen/common/strptime.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1997 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#if !defined(lint) && defined(SCCSIDS) -static char *sccsid = "%Z%%M% %I% %E% SMI"; -#endif - -#include <ctype.h> -#include <locale.h> -#include <time.h> - -static char *strmatch(/*char *cp, char *string*/); -static char *yearmatch(/*char *cp, char *format, struct tm *tm, - int *hadyearp*/); -static char *cvtnum(/*char *cp, int *nump*/); -static char *skipnws(/*char *format*/); - -extern char *getlocale_time(); -#define NULL 0 - -char * -strptime(buf, format, tm) - char *buf; - char *format; - struct tm *tm; -{ - register char *cp, *p; - register int c, ch; - register int i; - register struct dtconv *dtcp; - int hadyear; - - (void) getlocale_time(); - dtcp = localdtconv(); /* get locale's strings */ - - cp = buf; - while ((c = *format++) != '\0') { - if (c == '%') { - switch (*format++) { - - case '%': /* Percent sign */ - if (*cp++ != '%') - return (NULL); - break; - - case 'a': /* Abbreviated weekday name */ - case 'A': /* Weekday name */ - for (i = 0; i < 7; i++) { - if ((p = strmatch(cp, - dtcp->weekday_names[i], - *format)) != NULL - || (p = strmatch(cp, - dtcp->abbrev_weekday_names[i], - *format)) != NULL) - goto match_wday; - } - return (NULL); /* no match */ - - match_wday: - tm->tm_wday = i; - cp = p; - break; - - case 'h': - case 'b': /* Abbreviated month name */ - case 'B': /* Month name */ - for (i = 0; i < 12; i++) { - if ((p = strmatch(cp, - dtcp->month_names[i], - *format)) != NULL - || (p = strmatch(cp, - dtcp->abbrev_month_names[i], - *format)) != NULL) - goto match_month; - } - return (NULL); /* no match */ - - match_month: - tm->tm_mon = i; - cp = p; - break; - - case 'c': /* date and time representation */ - cp = strptime(cp, "%x %X", tm); - if (cp == NULL) - return (NULL); - break; - - case 'C': /* long date and time representation */ - cp = strptime(cp, dtcp->ldate_format, tm); - if (cp == NULL) - return (NULL); - break; - - case 'd': /* Day of month, with leading zero */ - case 'e': /* Day of month without leading zero */ - cp = cvtnum(cp, &tm->tm_mday); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_mday > 31) - return (NULL); - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'D': /* Shorthand for %m/%d/%y */ - cp = strptime(cp, "%m/%d/%y", tm); - if (cp == NULL) - return (NULL); - break; - - case 'H': /* Hour (24 hour version) */ - case 'k': /* Hour (24 hour version) */ - cp = cvtnum(cp, &tm->tm_hour); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_hour > 23) - return (NULL); - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'I': /* Hour (12 hour version) */ - case 'l': /* Hour (12 hour version) */ - cp = cvtnum(cp, &tm->tm_hour); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_hour == 12) - tm->tm_hour = 0; - else if (tm->tm_hour > 11) - return (NULL); - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'j': /* Julian date */ - cp = cvtnum(cp, &tm->tm_yday); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_yday > 365) - return (NULL); - break; - - case 'm': /* Month number */ - cp = cvtnum(cp, &tm->tm_mon); - if (cp == NULL) - return (NULL); /* no digits */ - tm->tm_mon--; - if (tm->tm_mon < 0 || tm->tm_mon > 11) - return (NULL); - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'M': /* Minute */ - /* - * This is optional; if we're at the end of the - * string, or the next character is white - * space, don't try to match it. - */ - if ((c = *cp) != '\0' - && !isspace((unsigned char)c)) { - cp = cvtnum(cp, &tm->tm_min); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_min > 59) - return (NULL); - } - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'p': /* AM or PM */ - if ((p = strmatch(cp, dtcp->am_string, - *format)) != NULL) { - /* - * AM. - */ - if (tm->tm_hour == 12) - tm->tm_hour = 0; - cp = p; - } else if ((p = strmatch(cp, dtcp->pm_string, - *format)) != NULL) { - /* - * PM. - */ - if (tm->tm_hour > 12) - return (NULL); /* error */ - else if (tm->tm_hour != 12) - tm->tm_hour += 12; - cp = p; - } - break; - - case 'r': /* Shorthand for %I:%M:%S AM or PM */ - cp = strptime(cp, "%I:%M:%S %p", tm); - if (cp == NULL) - return (NULL); - break; - - case 'R': /* Time as %H:%M */ - cp = strptime(cp, "%H:%M", tm); - if (cp == NULL) - return (NULL); - break; - - case 'S': /* Seconds */ - /* - * This is optional; if we're at the end of the - * string, or the next character is white - * space, don't try to match it. - */ - if ((c = *cp) != '\0' - && !isspace((unsigned char)c)) { - cp = cvtnum(cp, &tm->tm_sec); - if (cp == NULL) - return (NULL); /* no digits */ - if (tm->tm_sec > 59) - return (NULL); - } - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - break; - - case 'T': /* Shorthand for %H:%M:%S */ - cp = strptime(cp, "%H:%M:%S", tm); - if (cp == NULL) - return (NULL); - break; - - case 'x': /* Localized date format */ - cp = strptime(cp, dtcp->sdate_format, tm); - if (cp == NULL) - return (NULL); - break; - - case 'X': /* Localized time format */ - cp = strptime(cp, dtcp->time_format, tm); - if (cp == NULL) - return (NULL); - break; - - case 'y': /* Year in the form yy */ - cp = yearmatch(cp, format, tm, &hadyear); - if (cp == NULL) - return (NULL); - if (hadyear) { - if (tm->tm_year < 69) - tm->tm_year += 100; - } - return (cp); /* match is complete */ - - case 'Y': /* Year in the form ccyy */ - cp = yearmatch(cp, format, tm, &hadyear); - if (cp == NULL) - return (NULL); - if (hadyear) { - tm->tm_year -= 1900; - if (tm->tm_year < 0) - return (NULL); - } - return (cp); /* match is complete */ - - default: - return (NULL); /* unknown conversion */ - } - } else { - if (isspace((unsigned char)c)) { - while ((ch = *cp++) != '\0' - && isspace((unsigned char)ch)) - ; - cp--; - } else { - if (*cp++ != c) - return (NULL); - } - } - } - return (cp); -} - -/* - * Try to match the beginning of the string pointed to by "cp" with the string - * pointed to by "string". The match is independent of the case of either - * string. - * - * "termc" is the next character in the format string following the one for - * which this match is being done. If the match succeeds, make sure the next - * character after the match is either '\0', or that it would match "termc". - * - * If both matches succeed, return a pointer to the next character after the - * first match. Otherwise, return NULL. - */ -static char * -strmatch(cp, string, termc) - register char *cp; - register char *string; - char termc; -{ - register unsigned char c, strc; - - /* - * Match the beginning portion of "cp" with "string". - */ - while ((strc = *string++) != '\0') { - c = *cp++; - if (isupper(c)) - c = tolower(c); - if (isupper(strc)) - strc = tolower(strc); - if (c != strc) - return (NULL); - } - - if ((c = *cp) != '\0') { - if (isspace((unsigned char)termc)) { - if (!isspace(c)) - return (NULL); - } else { - if (c != (unsigned char)termc) - return (NULL); - } - } - return (cp); -} - -/* - * Try to match a %y or %Y specification. - * If it matches, try matching the rest of the format. If it succeeds, just - * return. Otherwise, try backing the scan up, ignoring the %y/%Y and any - * following non-white-space string. If that succeeds, just return. (This - * permits a missing year to be detected if it's at the beginning of a date, as - * well as if it's at the end of a date, so that formats such as "%Y/%m/%d" can - * match "3/14" and default the year.) - * - * Set "*hadyearp" to indicate whether a year was specified or not. - */ -static char * -yearmatch(cp, format, tm, hadyearp) - register char *cp; - char *format; - struct tm *tm; - int *hadyearp; -{ - register int c; - char *savecp; - int saveyear; - - /* - * This is optional; if we're at the end of the - * string, or the next character is white - * space, don't try to match it. - */ - if ((c = *cp) != '\0' && !isspace((unsigned char)c)) { - savecp = cp; - saveyear = tm->tm_year; - cp = cvtnum(cp, &tm->tm_year); - if (cp == NULL) - return (NULL); /* no digits */ - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - - /* - * Year can also be optional if it's at - * the *beginning* of a date. We check - * this by trying to parse the rest of - * the date here. If we succeed, OK; - * otherwise, we skip over the %y and - * try again. - */ - cp = strptime(cp, format, tm); - if (cp != NULL) - *hadyearp = 1; - else { - *hadyearp = 0; - cp = savecp; - format = skipnws(format); - tm->tm_year = saveyear; - cp = strptime(cp, format, tm); - } - } else { - *hadyearp = 0; - if ((c = *cp) == '\0' - || isspace((unsigned char)c)) - format = skipnws(format); - cp = strptime(cp, format, tm); - } - - return (cp); -} - -/* - * Try to match a (decimal) number in the string pointed to by "cp". - * If the match succeeds, store the result in the "int" pointed to by "nump" - * and return a pointer to the character following the number in the string. - * If it fails, return NULL. - */ -static char * -cvtnum(cp, nump) - register char *cp; - int *nump; -{ - register int c; - register int i; - - c = (unsigned char)*cp++; - if (!isdigit(c)) - return (NULL); /* no digits */ - i = 0; - do { - i = i*10 + c - '0'; - c = (unsigned char)*cp++; - } while (isdigit(c)); - *nump = i; - return (cp - 1); -} - -/* - * If a format item (such as %H, hours) is followed by a non-white-space - * character other than "%", and the part of the string that matched the format - * item is followed by white space, the string of non-white-space, - * non-format-item characters following that format item may be omitted. - */ -static char * -skipnws(format) - register char *format; -{ - register char c; - - /* - * Skip over non-white-space, non-digit characters. "%" is special. - */ - while ((c = *format) != '\0' && !isspace((unsigned char)c)) { - if (c == '%') { - /* - * This is a format item. If it's %%, skip it as - * that's a non-white space, non-digit character. - */ - if (*(format + 1) == '%') - format++; /* skip % */ - else - break; - } - format++; - } - - return (format); -} |