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

📄 strftime.c

📁 基于LINUX环境下的PPPOE协议源代码
💻 C
字号:
/* Copyright (C) 1991, 92, 93, 94, 95, 96 Free Software Foundation, Inc.This file is part of the GNU C Library.The GNU C Library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.The GNU C Library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with the GNU C Library; see the file COPYING.LIB.  Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA.  */#include <stddef.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <sys/types.h>		/* Some systems define `time_t' here.  */#include <sys/time.h>#include <time.h>#include <ctype.h>#include <limits.h>static unsigned int week (const struct tm *const, int, int);//char tzname[2];#define	add(n, f)							      \  do									      \    {									      \      i += (n);								      \      if (i >= maxsize)							      \	return 0;							      \      else								      \	if (p)								      \	  {								      \	    f;								      \	    p += (n);							      \	  }								      \    } while (0)#define	cpy(n, s)	add((n), memcpy((void *) p, (void *) (s), (n)))#ifdef _LIBC#define	fmt(n, args)	add((n), if (sprintf args != (n)) return 0)#else#define	fmt(n, args)	add((n), sprintf args; if (strlen (p) != (n)) return 0)#endif/* Return the week in the year specified by TP,   with weeks starting on STARTING_DAY.  */static unsigned int week(const struct tm *const tp , int starting_day , int max_preceding ){  int wday, dl, base;  wday = tp->tm_wday - starting_day;  if (wday < 0)    wday += 7;  /* Set DL to the day in the year of the first day of the week     containing the day specified in TP.  */  dl = tp->tm_yday - wday;  /* For the computation following ISO 8601:1988 we set the number of     the week containing January 1st to 1 if this week has more than     MAX_PRECEDING days in the new year.  For ISO 8601 this number is     3, for the other representation it is 7 (i.e., not to be     fulfilled).  */  base = ((dl + 7) % 7) > max_preceding ? 1 : 0;  /* If DL is negative we compute the result as 0 unless we have to     compute it according ISO 8601.  In this case we have to return 53     or 1 if the week containing January 1st has less than 4 days in     the new year or not.  If DL is not negative we calculate the     number of complete weeks for our week (DL / 7) plus 1 (because     only for DL < 0 we are in week 0/53 and plus the number of the     first week computed in the last step.  */  return dl < 0 ? (dl < -max_preceding ? 53 : base)		: base + 1 + dl / 7;}#ifndef _NL_CURRENTstatic char const weekday_name[][10] =  {    "Sunday", "Monday", "Tuesday", "Wednesday",    "Thursday", "Friday", "Saturday"  };static char const month_name[][10] =  {    "January", "February", "March", "April", "May", "June",    "July", "August", "September", "October", "November", "December"  };#endif/* Write information from TP into S according to the format   string FORMAT, writing no more that MAXSIZE characters   (including the terminating '\0') and returning number of   characters written.  If S is NULL, nothing will be written   anywhere, so to determine how many characters would be   written, use NULL for S and (size_t) UINT_MAX for MAXSIZE.  */size_t strftime( char *s , size_t maxsize , const char *format , register const struct tm *tp){  int hour12 = tp->tm_hour;#ifdef _NL_CURRENT  const char *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday);  const char *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday);  const char *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon);  const char *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon);  const char *const ampm = _NL_CURRENT (LC_TIME,					hour12 > 11 ? PM_STR : AM_STR);  size_t aw_len = strlen(a_wkday);  size_t am_len = strlen(a_month);  size_t ap_len = strlen (ampm);#else  const char *const f_wkday = weekday_name[tp->tm_wday];  const char *const f_month = month_name[tp->tm_mon];  const char *const a_wkday = f_wkday;  const char *const a_month = f_month;  const char *const ampm = "AMPM" + 2 * (hour12 > 11);  size_t aw_len = 3;  size_t am_len = 3;  size_t ap_len = 2;#endif  size_t wkday_len = strlen(f_wkday);  size_t month_len = strlen(f_month);  const unsigned int y_week0 = week (tp, 0, 7);  const unsigned int y_week1 = week (tp, 1, 7);  const unsigned int y_week2 = week (tp, 1, 3);  const char *zone;  size_t zonelen;  register size_t i = 0;  register char *p = s;  register const char *f;  char number_fmt[5];  /* Initialize the buffer we will use for the sprintf format for numbers.  */  number_fmt[0] = '%';  zone = 0;#if HAVE_TM_ZONE  zone = (const char *) tp->tm_zone;#endif  if (!(zone && *zone) && tp->tm_isdst >= 0)    zone = tzname[tp->tm_isdst];  if (!(zone && *zone))    zone = "???";  zonelen = strlen (zone);  if (hour12 > 12)    hour12 -= 12;  else    if (hour12 == 0) hour12 = 12;  for (f = format; *f != '\0'; ++f)    {      enum { pad_zero, pad_space, pad_none } pad; /* Padding for number.  */      unsigned int maxdigits;	/* Max digits for numeric format.  */      unsigned int number_value; /* Numeric value to be printed.  */      const char *subfmt;#if HAVE_MBLEN      if (!isascii(*f))	{	  /* Non-ASCII, may be a multibyte.  */	  int len = mblen(f, strlen(f));	  if (len > 0)	    {	      cpy(len, f);	      continue;	    }	}#endif      if (*f != '%')	{	  add(1, *p = *f);	  continue;	}      /* Check for flags that can modify a number format.  */      ++f;      switch (*f)	{	case '_':	  pad = pad_space;	  ++f;	  break;	case '-':	  pad = pad_none;	  ++f;	  break;	default:	  pad = pad_zero;	  break;	}      /* Now do the specified format.  */      switch (*f)	{	case '\0':	case '%':	  add(1, *p = *f);	  break;	case 'a':	  cpy(aw_len, a_wkday);	  break;	case 'A':	  cpy(wkday_len, f_wkday);	  break;	case 'b':	case 'h':		/* GNU extension.  */	  cpy(am_len, a_month);	  break;	case 'B':	  cpy(month_len, f_month);	  break;	case 'c':#ifdef _NL_CURRENT	  subfmt = _NL_CURRENT (LC_TIME, D_T_FMT);#else	  subfmt = "%a %b %d %H:%M:%S %Z %Y";#endif	subformat:	  {	    size_t len = strftime (p, maxsize - i, subfmt, tp);	    if (len == 0 && *subfmt)	      return 0;	    add(len, );	  }	  break;#define DO_NUMBER(digits, value) \	  maxdigits = digits; number_value = value; goto do_number#define DO_NUMBER_NOPAD(digits, value) \	  maxdigits = digits; number_value = value; goto do_number_nopad	case 'C':	  DO_NUMBER (2, (1900 + tp->tm_year) / 100);	case 'x':#ifdef _NL_CURRENT	  subfmt = _NL_CURRENT (LC_TIME, D_FMT);	  goto subformat;#endif	  /* Fall through.  */	case 'D':		/* GNU extension.  */	  subfmt = "%m/%d/%y";	  goto subformat;	case 'd':	  DO_NUMBER (2, tp->tm_mday);	case 'e':		/* GNU extension: %d, but blank-padded.  */#if 0	  DO_NUMBER_NOPAD (2, tp->tm_mday);#else	  DO_NUMBER (2, tp->tm_mday);#endif	  /* All numeric formats set MAXDIGITS and NUMBER_VALUE and then	     jump to one of these two labels.  */	do_number_nopad:	  /* Force `-' flag.  */	  pad = pad_none;	do_number:	  {	    /* Format the number according to the PAD flag.  */	    register char *nf = &number_fmt[1];	    int printed;	    switch (pad)	      {	      case pad_zero:		*nf++ = '0';	      case pad_space:		*nf++ = '0' + maxdigits;	      case pad_none:		*nf++ = 'u';		*nf = '\0';	      }#ifdef _LIBC	    if (i + maxdigits >= maxsize)		return 0;	    printed = sprintf (p, number_fmt, number_value);	    i += printed;	    p += printed;#else	    add (maxdigits, sprintf (p, number_fmt, number_value);		 printed = strlen (p));#endif	    break;	  }	case 'H':	  DO_NUMBER (2, tp->tm_hour);	case 'I':	  DO_NUMBER (2, hour12);	case 'k':		/* GNU extension.  */	  DO_NUMBER_NOPAD (2, tp->tm_hour);	case 'l':		/* GNU extension.  */	  DO_NUMBER_NOPAD (2, hour12);	case 'j':	  DO_NUMBER (3, 1 + tp->tm_yday);	case 'M':	  DO_NUMBER (2, tp->tm_min);	case 'm':	  DO_NUMBER (2, tp->tm_mon + 1);	case 'n':		/* GNU extension.  */	  add (1, *p = '\n');	  break;	case 'p':	  cpy(ap_len, ampm);	  break;	case 'R':		/* GNU extension.  */	  subfmt = "%H:%M";	  goto subformat;	case 'r':		/* GNU extension.  */	  subfmt = "%I:%M:%S %p";	  goto subformat;	case 'S':	  DO_NUMBER (2, tp->tm_sec);	case 'X':#ifdef _NL_CURRENT	  subfmt = _NL_CURRENT (LC_TIME, T_FMT);	  goto subformat;#endif	  /* Fall through.  */	case 'T':		/* GNU extenstion.  */	  subfmt = "%H:%M:%S";	  goto subformat;	case 't':		/* GNU extenstion.  */	  add (1, *p = '\t');	  break;	case 'U':	  DO_NUMBER (2, y_week0);	case 'V':	  DO_NUMBER (2, y_week2);	case 'W':	  DO_NUMBER (2, y_week1);	case 'w':	  DO_NUMBER (1, tp->tm_wday);	case 'Y':	  DO_NUMBER (4, 1900 + tp->tm_year);	case 'y':	  DO_NUMBER (2, tp->tm_year % 100);	case 'Z':	  cpy(zonelen, zone);	  break;	default:	  /* Bad format.  */	  break;	}    }  if (p)    *p = '\0';  return i;}

⌨️ 快捷键说明

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