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

📄 strptime_l.c

📁 Linux下头文件time.h的实现源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	  break;	case 'r':#ifdef _NL_CURRENT	  if (s.decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))		{		  if (s.decided == loc)		    return NULL;		  else		    rp = rp_backup;		}	      else		{		  if (s.decided == not &&		      strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),			      HERE_T_FMT_AMPM))		    s.decided = loc;		  break;		}	      s.decided = raw;	    }#endif	  if (!recursive (HERE_T_FMT_AMPM))	    return NULL;	  break;	case 'R':	  if (!recursive ("%H:%M"))	    return NULL;	  break;	case 's':	  {	    /* The number of seconds may be very high so we cannot use	       the `get_number' macro.  Instead read the number	       character for character and construct the result while	       doing this.  */	    time_t secs = 0;	    if (*rp < '0' || *rp > '9')	      /* We need at least one digit.  */	      return NULL;	    do	      {		secs *= 10;		secs += *rp++ - '0';	      }	    while (*rp >= '0' && *rp <= '9');	    if (localtime_r (&secs, tm) == NULL)	      /* Error in function.  */	      return NULL;	  }	  break;	case 'S':	  get_number (0, 61, 2);	  tm->tm_sec = val;	  break;	case 'X':#ifdef _NL_CURRENT	  if (s.decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))		{		  if (s.decided == loc)		    return NULL;		  else		    rp = rp_backup;		}	      else		{		  if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))		    s.decided = loc;		  break;		}	      s.decided = raw;	    }#endif	  /* Fall through.  */	case 'T':	  if (!recursive (HERE_T_FMT))	    return NULL;	  break;	case 'u':	  get_number (1, 7, 1);	  tm->tm_wday = val % 7;	  s.have_wday = 1;	  break;	case 'g':	  get_number (0, 99, 2);	  /* XXX This cannot determine any field in TM.  */	  break;	case 'G':	  if (*rp < '0' || *rp > '9')	    return NULL;	  /* XXX Ignore the number since we would need some more	     information to compute a real date.  */	  do	    ++rp;	  while (*rp >= '0' && *rp <= '9');	  break;	case 'U':	  get_number (0, 53, 2);	  s.week_no = val;	  s.have_uweek = 1;	  break;	case 'W':	  get_number (0, 53, 2);	  s.week_no = val;	  s.have_wweek = 1;	  break;	case 'V':	  get_number (0, 53, 2);	  /* XXX This cannot determine any field in TM without some	     information.  */	  break;	case 'w':	  /* Match number of weekday.  */	  get_number (0, 6, 1);	  tm->tm_wday = val;	  s.have_wday = 1;	  break;	case 'y':	match_year_in_century:	  /* Match year within century.  */	  get_number (0, 99, 2);	  /* The "Year 2000: The Millennium Rollover" paper suggests that	     values in the range 69-99 refer to the twentieth century.  */	  tm->tm_year = val >= 69 ? val : val + 100;	  /* Indicate that we want to use the century, if specified.  */	  s.want_century = 1;	  s.want_xday = 1;	  break;	case 'Y':	  /* Match year including century number.  */	  get_number (0, 9999, 4);	  tm->tm_year = val - 1900;	  s.want_century = 0;	  s.want_xday = 1;	  break;	case 'Z':	  /* XXX How to handle this?  */	  break;	case 'z':	  /* We recognize two formats: if two digits are given, these	     specify hours.  If fours digits are used, minutes are	     also specified.  */	  {	    val = 0;	    while (*rp == ' ')	      ++rp;	    if (*rp != '+' && *rp != '-')	      return NULL;	    bool neg = *rp++ == '-';	    int n = 0;	    while (n < 4 && *rp >= '0' && *rp <= '9')	      {		val = val * 10 + *rp++ - '0';		++n;	      }	    if (n == 2)	      val *= 100;	    else if (n != 4)	      /* Only two or four digits recognized.  */	      return NULL;	    else	      {		/* We have to convert the minutes into decimal.  */		if (val % 100 >= 60)		  return NULL;		val = (val / 100) * 100 + ((val % 100) * 50) / 30;	      }	    if (val > 1200)	      return NULL;	    tm->tm_gmtoff = (val * 3600) / 100;	    if (neg)	      tm->tm_gmtoff = -tm->tm_gmtoff;	  }	  break;	case 'E':#ifdef _NL_CURRENT	  switch (*fmt++)	    {	    case 'c':	      /* Match locale's alternate date and time format.  */	      if (s.decided != raw)		{		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);		  if (*fmt == '\0')		    fmt = _NL_CURRENT (LC_TIME, D_T_FMT);		  if (!recursive (fmt))		    {		      if (s.decided == loc)			return NULL;		      else			rp = rp_backup;		    }		  else		    {		      if (strcmp (fmt, HERE_D_T_FMT))			s.decided = loc;		      s.want_xday = 1;		      break;		    }		  s.decided = raw;		}	      /* The C locale has no era information, so use the		 normal representation.  */	      if (!recursive (HERE_D_T_FMT))		return NULL;	      s.want_xday = 1;	      break;	    case 'C':	      if (s.decided != raw)		{		  if (s.era_cnt >= 0)		    {		      era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);		      if (era != NULL && match_string (era->era_name, rp))			{			  s.decided = loc;			  break;			}		      else			return NULL;		    }		  num_eras = _NL_CURRENT_WORD (LC_TIME,					       _NL_TIME_ERA_NUM_ENTRIES);		  for (s.era_cnt = 0; s.era_cnt < (int) num_eras;		       ++s.era_cnt, rp = rp_backup)		    {		      era = _nl_select_era_entry (s.era_cnt						  HELPER_LOCALE_ARG);		      if (era != NULL && match_string (era->era_name, rp))			{			  s.decided = loc;			  break;			}		    }		  if (s.era_cnt != (int) num_eras)		    break;		  s.era_cnt = -1;		  if (s.decided == loc)		    return NULL;		  s.decided = raw;		}	      /* The C locale has no era information, so use the		 normal representation.  */	      goto match_century; 	    case 'y':	      if (s.decided != raw)		{		  get_number(0, 9999, 4);		  tm->tm_year = val;		  s.want_era = 1;		  s.want_xday = 1;		  s.want_century = 1;		  if (s.era_cnt >= 0)		    {		      assert (s.decided == loc);		      era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);		      bool match = false;		      if (era != NULL)			{			  int delta = ((tm->tm_year - era->offset)				       * era->absolute_direction);			  match = (delta >= 0				   && delta < (((int64_t) era->stop_date[0]						- (int64_t) era->start_date[0])					       * era->absolute_direction));			}		      if (! match)			return NULL;		      break;		    }		  num_eras = _NL_CURRENT_WORD (LC_TIME,					       _NL_TIME_ERA_NUM_ENTRIES);		  for (s.era_cnt = 0; s.era_cnt < (int) num_eras; ++s.era_cnt)		    {		      era = _nl_select_era_entry (s.era_cnt						  HELPER_LOCALE_ARG);		      if (era != NULL)			{			  int delta = ((tm->tm_year - era->offset)				       * era->absolute_direction);			  if (delta >= 0			      && delta < (((int64_t) era->stop_date[0]					   - (int64_t) era->start_date[0])					  * era->absolute_direction))			    {			      s.decided = loc;			      break;			    }			}		    }		  if (s.era_cnt != (int) num_eras)		    break;		  s.era_cnt = -1;		  if (s.decided == loc)		    return NULL;		  s.decided = raw;		}	      goto match_year_in_century;	    case 'Y':	      if (s.decided != raw)		{		  num_eras = _NL_CURRENT_WORD (LC_TIME,					       _NL_TIME_ERA_NUM_ENTRIES);		  for (s.era_cnt = 0; s.era_cnt < (int) num_eras;		       ++s.era_cnt, rp = rp_backup)		    {		      era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);		      if (era != NULL && recursive (era->era_format))			break;		    }		  if (s.era_cnt == (int) num_eras)		    {		      s.era_cnt = -1;		      if (s.decided == loc)			return NULL;		      else			rp = rp_backup;		    }		  else		    {		      s.decided = loc;		      s.era_cnt = -1;		      break;		    }		  s.decided = raw;		}	      get_number (0, 9999, 4);	      tm->tm_year = val - 1900;	      s.want_century = 0;	      s.want_xday = 1;	      break;	    case 'x':	      if (s.decided != raw)		{		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);		  if (*fmt == '\0')		    fmt = _NL_CURRENT (LC_TIME, D_FMT);		  if (!recursive (fmt))		    {		      if (s.decided == loc)			return NULL;		      else			rp = rp_backup;		    }		  else		    {		      if (strcmp (fmt, HERE_D_FMT))			s.decided = loc;		      break;		    }		  s.decided = raw;		}	      if (!recursive (HERE_D_FMT))		return NULL;	      break;	    case 'X':	      if (s.decided != raw)		{		  const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);		  if (*fmt == '\0')		    fmt = _NL_CURRENT (LC_TIME, T_FMT);		  if (!recursive (fmt))		    {		      if (s.decided == loc)			return NULL;		      else			rp = rp_backup;		    }		  else		    {		      if (strcmp (fmt, HERE_T_FMT))			s.decided = loc;		      break;		    }		  s.decided = raw;		}	      if (!recursive (HERE_T_FMT))		return NULL;	      break;	    default:	      return NULL;	    }	  break;#else	  /* We have no information about the era format.  Just use	     the normal format.  */	  if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'	      && *fmt != 'x' && *fmt != 'X')	    /* This is an illegal format.  */	    return NULL;	  goto start_over;#endif	case 'O':	  switch (*fmt++)	    {	    case 'd':	    case 'e':	      /* Match day of month using alternate numeric symbols.  */	      get_alt_number (1, 31, 2);	      tm->tm_mday = val;	      s.have_mday = 1;	      s.want_xday = 1;	      break;	    case 'H':	      /* Match hour in 24-hour clock using alternate numeric		 symbols.  */	      get_alt_number (0, 23, 2);	      tm->tm_hour = val;	      s.have_I = 0;	      break;	    case 'I':	      /* Match hour in 12-hour clock using alternate numeric		 symbols.  */	      get_alt_number (1, 12, 2);	      tm->tm_hour = val % 12;	      s.have_I = 1;	      break;	    case 'm':	      /* Match month using alternate numeric symbols.  */	      get_alt_number (1, 12, 2);	      tm->tm_mon = val - 1;	      s.have_mon = 1;	      s.want_xday = 1;	      break;	    case 'M':	      /* Match minutes using alternate numeric symbols.  */	      get_alt_number (0, 59, 2);	      tm->tm_min = val;	      break;	    case 'S':	      /* Match seconds using alternate numeric symbols.  */	      get_alt_number (0, 61, 2);	      tm->tm_sec = val;	      break;	    case 'U':	      get_alt_number (0, 53, 2);	      s.week_no = val;	      s.have_uweek = 1;	      break;	    case 'W':	      get_alt_number (0, 53, 2);	      s.week_no = val;	      s.have_wweek = 1;	      break;	    case 'V':	      get_alt_number (0, 53, 2);	      /* XXX This cannot determine any field in TM without		 further information.  */	      break;	    case 'w':	      /* Match number of weekday using alternate numeric symbols.  */	      get_alt_number (0, 6, 1);	      tm->tm_wday = val;	      s.have_wday = 1;	      break;	    case 'y':	      /* Match year within century using alternate numeric symbols.  */	      get_alt_number (0, 99, 2);	      tm->tm_year = val >= 69 ? val : val + 100;	      s.want_xday = 1;	      break;	    default:	      return NULL;	    }	  break;	default:	  return NULL;	}    }  if (statep != NULL)    {      /* Recursive invocation, returning success, so	 update parent's struct tm and state.  */      *(struct __strptime_state *) statep = s;      *tmp = tmb;      return (char *) rp;    }  if (s.have_I && s.is_pm)    tm->tm_hour += 12;  if (s.century != -1)    {      if (s.want_century)	tm->tm_year = tm->tm_year % 100 + (s.century - 19) * 100;      else	/* Only the century, but not the year.  Strange, but so be it.  */	tm->tm_year = (s.century - 19) * 100;    }  if (s.era_cnt != -1)    {      era = _nl_select_era_entry (s.era_cnt HELPER_LOCALE_ARG);      if (era == NULL)	return NULL;      if (s.want_era)	tm->tm_year = (era->start_date[0]		       + ((tm->tm_year - era->offset)			  * era->absolute_direction));      else	/* Era start year assumed.  */	tm->tm_year = era->start_date[0];    }  else    if (s.want_era)      {	/* No era found but we have seen an E modifier.  Rectify some	   values.  */	if (s.want_century && s.century == -1 && tm->tm_year < 69)	  tm->tm_year += 100;      }  if (s.want_xday && !s.have_wday)    {      if ( !(s.have_mon && s.have_mday) && s.have_yday)	{	  /* We don't have tm_mon and/or tm_mday, compute them.  */	  int t_mon = 0;	  while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)	      t_mon++;	  if (!s.have_mon)	      tm->tm_mon = t_mon - 1;	  if (!s.have_mday)	      tm->tm_mday =		(tm->tm_yday		 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);	  s.have_mon = 1;	  s.have_mday = 1;	}      /* Don't crash in day_of_the_week if tm_mon is uninitialized.  */      if (s.have_mon || (unsigned) tm->tm_mon <= 11)	day_of_the_week (tm);    }  if (s.want_xday && !s.have_yday && (s.have_mon || (unsigned) tm->tm_mon <= 11))    day_of_the_year (tm);  if ((s.have_uweek || s.have_wweek) && s.have_wday)    {      int save_wday = tm->tm_wday;      int save_mday = tm->tm_mday;      int save_mon = tm->tm_mon;      int w_offset = s.have_uweek ? 0 : 1;      tm->tm_mday = 1;      tm->tm_mon = 0;      day_of_the_week (tm);      if (s.have_mday)	tm->tm_mday = save_mday;      if (s.have_mon)	tm->tm_mon = save_mon;      if (!s.have_yday)	tm->tm_yday = ((7 - (tm->tm_wday - w_offset)) % 7		       + (s.week_no - 1) *7		       + save_wday - w_offset);      if (!s.have_mday || !s.have_mon)	{	  int t_mon = 0;	  while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon]		 <= tm->tm_yday)	    t_mon++;	  if (!s.have_mon)	    tm->tm_mon = t_mon - 1;	  if (!s.have_mday)	      tm->tm_mday =		(tm->tm_yday		 - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);	}      tm->tm_wday = save_wday;    }  return (char *) rp;}char *strptime (buf, format, tm LOCALE_PARAM)     const char *buf;     const char *format;     struct tm *tm;     LOCALE_PARAM_DECL{  return __strptime_internal (buf, format, tm, NULL LOCALE_ARG);}#ifdef _LIBCweak_alias (__strptime_l, strptime_l)#endif

⌨️ 快捷键说明

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