get_alt_number (1, 31);
get_alt_number (1, 31, 2);
strptime_internal (buf, format, tm, decided)     const char *buf;     const char *format;     struct tm *tm;     enum locale_status *decided;{  const char *rp;  const char *fmt;  int cnt;  size_t val;  int have_I, is_pm;  int century, want_century;  int have_wday, want_xday;  int have_yday;  int have_mon, have_mday;    rp = buf;  fmt = format;  have_I = is_pm = 0;  century = -1;  want_century = 0;  have_wday = want_xday = have_yday = have_mon = have_mday = 0;  while (*fmt != '\0')    {      /* A white space in the format string matches 0 more or white	 space in the input string.  */      if (isspace (*fmt))	{	  while (isspace (*rp))	    ++rp;	  ++fmt;	  continue;	}      /* Any character but `%' must be matched by the same character	 in the iput string.  */      if (*fmt != '%')	{	  match_char (*fmt++, *rp++);	  continue;	}      ++fmt;#ifndef _NL_CURRENT      /* We need this for handling the `E' modifier.  */    start_over:#endif      switch (*fmt++)	{	case '%':	  /* Match the `%' character itself.  */	  match_char ('%', *rp++);	  break;	case 'a':	case 'A':	  /* Match day of week.  */	  for (cnt = 0; cnt < 7; ++cnt)	    {#ifdef _NL_CURRENT	      if (*decided !=raw)		{		  if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))		    {		      if (*decided == not			  && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),				     weekday_name[cnt]))			*decided = loc;		      break;		    }		  if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))		    {		      if (*decided == not			  && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),				     ab_weekday_name[cnt]))			*decided = loc;		      break;		    }		}#endif	      if (*decided != loc		  && (match_string (weekday_name[cnt], rp)		      || match_string (ab_weekday_name[cnt], rp)))		{		  *decided = raw;		  break;		}	    }	  if (cnt == 7)	    /* Does not match a weekday name.  */	    return NULL;	  tm->tm_wday = cnt;	  have_wday = 1;	  break;	case 'b':	case 'B':	case 'h':	  /* Match month name.  */	  for (cnt = 0; cnt < 12; ++cnt)	    {#ifdef _NL_CURRENT	      if (*decided !=raw)		{		  if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))		    {		      if (*decided == not			  && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),				     month_name[cnt]))			*decided = loc;		      break;		    }		  if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))		    {		      if (*decided == not			  && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),				     ab_month_name[cnt]))			*decided = loc;		      break;		    }		}#endif	      if (match_string (month_name[cnt], rp)		  || match_string (ab_month_name[cnt], rp))		{		  *decided = raw;		  break;		}	    }	  if (cnt == 12)	    /* Does not match a month name.  */	    return NULL;	  tm->tm_mon = cnt;	  want_xday = 1;	  break;	case 'c':	  /* Match locale's date and time format.  */#ifdef _NL_CURRENT	  if (*decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))		{		  if (*decided == loc)		    return NULL;		}	      else		{		  if (*decided == not &&		      strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))		    *decided = loc;		  want_xday = 1;		  break;		}	      *decided = raw;	    }#endif	  if (!recursive (HERE_D_T_FMT))	    return NULL;	  want_xday = 1;	  break;	case 'C':	  /* Match century number.  */	  get_number (0, 99);	  century = val;	  want_xday = 1;	  break;	case 'd':	case 'e':	  /* Match day of month.  */	  get_number (1, 31);	  tm->tm_mday = val;	  have_mday = 1;	  want_xday = 1;	  break;	case 'F':	  if (!recursive ("%Y-%m-%d"))	    return NULL;	  want_xday = 1;	  break;	case 'x':#ifdef _NL_CURRENT	  if (*decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))		{		  if (*decided == loc)		    return NULL;		}	      else		{		  if (decided == not		      && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))		    *decided = loc;		  want_xday = 1;		  break;		}	      *decided = raw;	    }#endif	  /* Fall through.  */	case 'D':	  /* Match standard day format.  */	  if (!recursive (HERE_D_FMT))	    return NULL;	  want_xday = 1;	  break;	case 'k':	case 'H':	  /* Match hour in 24-hour clock.  */	  get_number (0, 23);	  tm->tm_hour = val;	  have_I = 0;	  break;	case 'I':	  /* Match hour in 12-hour clock.  */	  get_number (1, 12);	  tm->tm_hour = val % 12;	  have_I = 1;	  break;	case 'j':	  /* Match day number of year.  */	  get_number (1, 366);	  tm->tm_yday = val - 1;	  have_yday = 1;	  break;	case 'm':	  /* Match number of month.  */	  get_number (1, 12);	  tm->tm_mon = val - 1;	  have_mon = 1;	  want_xday = 1;	  break;	case 'M':	  /* Match minute.  */	  get_number (0, 59);	  tm->tm_min = val;	  break;	case 'n':	case 't':	  /* Match any white space.  */	  while (isspace (*rp))	    ++rp;	  break;	case 'p':	  /* Match locale's equivalent of AM/PM.  */#ifdef _NL_CURRENT	  if (*decided != raw)	    {	      if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))		{		  if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))		    *decided = loc;		  break;		}	      if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))		{		  if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))		    *decided = loc;		  is_pm = 1;		  break;		}	      *decided = raw;	    }#endif	  if (!match_string (HERE_AM_STR, rp))	    if (match_string (HERE_PM_STR, rp))	      is_pm = 1;	    else	      return NULL;	  break;	case 'r':#ifdef _NL_CURRENT	  if (*decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))		{		  if (*decided == loc)		    return NULL;		}	      else		{		  if (*decided == not &&		      strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),			      HERE_T_FMT_AMPM))		    *decided = loc;		  break;		}	      *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);	  tm->tm_sec = val;	  break;	case 'X':#ifdef _NL_CURRENT	  if (*decided != raw)	    {	      if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))		{		  if (*decided == loc)		    return NULL;		}	      else		{		  if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))		    *decided = loc;		  break;		}	      *decided = raw;	    }#endif	  /* Fall through.  */	case 'T':	  if (!recursive (HERE_T_FMT))	    return NULL;	  break;	case 'u':	  get_number (1, 7);	  tm->tm_wday = val % 7;	  have_wday = 1;	  break;	case 'g':	  get_number (0, 99);	  /* 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':	case 'V':	case 'W':	  get_number (0, 53);	  /* XXX This cannot determine any field in TM without some	     information.  */	  break;	case 'w':	  /* Match number of weekday.  */	  get_number (0, 6);	  tm->tm_wday = val;	  have_wday = 1;	  break;	case 'y':	  /* Match year within century.  */	  get_number (0, 99);	  /* 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.  */	  want_century = 1;	  want_xday = 1;	  break;	case 'Y':	  /* Match year including century number.  */	  get_number (0, 9999);	  tm->tm_year = val - 1900;	  want_century = 0;	  want_xday = 1;	  break;	case 'Z':	  /* XXX How to handle this?  */	  break;	case 'E':#ifdef _NL_CURRENT	  switch (*fmt++)	    {	    case 'c':	      /* Match locale's alternate date and time format.  */	      if (*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 (*decided == loc)			return NULL;		    }		  else		    {		      if (strcmp (fmt, HERE_D_T_FMT))			*decided = loc;		      want_xday = 1;		      break;		    }		  *decided = raw;		}	      /* The C locale has no era information, so use the		 normal representation.  */	      if (!recursive (HERE_D_T_FMT))		return NULL;	      want_xday = 1;	      break;	    case 'C':	    case 'y':	    case 'Y':	      /* Match name of base year in locale's alternate		 representation.  */	      /* XXX This is currently not implemented.  It should		 use the value _NL_CURRENT (LC_TIME, ERA).  */	      break;	    case 'x':	      if (*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 (*decided == loc)			return NULL;		    }		  else		    {		      if (strcmp (fmt, HERE_D_FMT))			*decided = loc;		      break;		    }		  *decided = raw;		}	      if (!recursive (HERE_D_FMT))		return NULL;	      break;	    case 'X':	      if (*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 (*decided == loc)			return NULL;		    }		  else		    {		      if (strcmp (fmt, HERE_T_FMT))			*decided = loc;		      break;		    }		  *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);	      tm->tm_mday = val;	      have_mday = 1;	      want_xday = 1;	      break;	    case 'H':	      /* Match hour in 24-hour clock using alternate numeric		 symbols.  */	      get_alt_number (0, 23);	      tm->tm_hour = val;	      have_I = 0;	      break;	    case 'I':	      /* Match hour in 12-hour clock using alternate numeric		 symbols.  */	      get_alt_number (1, 12);	      tm->tm_hour = val - 1;	      have_I = 1;	      break;	    case 'm':	      /* Match month using alternate numeric symbols.  */	      get_alt_number (1, 12);	      tm->tm_mon = val - 1;	      have_mon = 1;	      want_xday = 1;	      break;	    case 'M':	      /* Match minutes using alternate numeric symbols.  */	      get_alt_number (0, 59);	      tm->tm_min = val;	      break;	    case 'S':	      /* Match seconds using alternate numeric symbols.  */	      get_alt_number (0, 61);	      tm->tm_sec = val;	      break;	    case 'U':	    case 'V':	    case 'W':	      get_alt_number (0, 53);	      /* 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);	      tm->tm_wday = val;	      have_wday = 1;	      break;	    case 'y':	      /* Match year within century using alternate numeric symbols.  */	      get_alt_number (0, 99);	      tm->tm_year = val >= 69 ? val : val + 100;	      want_xday = 1;	      break;	    default:	      return NULL;	    }	  break;	default:	  return NULL;	}    }  if (have_I && is_pm)    tm->tm_hour += 12;  if (want_century && century != -1)    tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;  if (want_xday && !have_wday) {      if ( !(have_mon && have_mday) && 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 (!have_mon)	      tm->tm_mon = t_mon - 1;	  if (!have_mday)	      tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;      }       day_of_the_week (tm);  }    if (want_xday && !have_yday)    day_of_the_year (tm);  return (char *) rp;}