⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strptime.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#if !defined(lint) && defined(SCCSIDS)static        char sccsid[] = "@(#)strptime.c 1.1 92/07/30 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	0char *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 > 99)						return (NULL);				}				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);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -