Write a new parse_number function that is possible to limit that
amount of numbers used, with this strptime can handle strptime("200505", "%Y%m", &tm); git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15500 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Kungliga Tekniska H<>gskolan
|
||||
* Copyright (c) 1999, 2003, 2005 Kungliga Tekniska H<>gskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -120,7 +120,41 @@ match_string (const char **buf, const char **strs)
|
||||
}
|
||||
|
||||
/*
|
||||
* tm_year is relative this year */
|
||||
* Try to match `*buf' to at the most `n' characters and return the
|
||||
* resulting number in `num'. Returns 0 or an error. Also advance
|
||||
* buf.
|
||||
*/
|
||||
|
||||
static int
|
||||
parse_number (const char **buf, int n, int *num)
|
||||
{
|
||||
char *s, *str;
|
||||
int i;
|
||||
|
||||
str = malloc(n + 1);
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
/* skip whitespace */
|
||||
for (; **buf != '\0' && isspace((unsigned char)(**buf)); (*buf)++)
|
||||
;
|
||||
|
||||
/* parse at least n characters */
|
||||
for (i = 0; **buf != '\0' && i < n && isdigit((unsigned char)(**buf)); i++, (*buf)++)
|
||||
str[i] = **buf;
|
||||
str[i] = '\0';
|
||||
|
||||
*num = strtol (str, &s, 10);
|
||||
free(str);
|
||||
if (s == str)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tm_year is relative this year
|
||||
*/
|
||||
|
||||
const int tm_year_base = 1900;
|
||||
|
||||
@@ -247,11 +281,9 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
||||
timeptr->tm_mon = ret;
|
||||
break;
|
||||
case 'C' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_year = (ret * 100) - tm_year_base;
|
||||
buf = s;
|
||||
break;
|
||||
case 'c' :
|
||||
abort ();
|
||||
@@ -263,51 +295,43 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
||||
break;
|
||||
case 'd' :
|
||||
case 'e' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_mday = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'H' :
|
||||
case 'k' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_hour = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'I' :
|
||||
case 'l' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
if (ret == 12)
|
||||
timeptr->tm_hour = 0;
|
||||
else
|
||||
timeptr->tm_hour = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'j' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 3, &ret))
|
||||
return NULL;
|
||||
if (ret == 0)
|
||||
return NULL;
|
||||
timeptr->tm_yday = ret - 1;
|
||||
buf = s;
|
||||
break;
|
||||
case 'm' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
if (ret == 0)
|
||||
return NULL;
|
||||
timeptr->tm_mon = ret - 1;
|
||||
buf = s;
|
||||
break;
|
||||
case 'M' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_min = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'n' :
|
||||
while (isspace (*buf))
|
||||
@@ -336,11 +360,9 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
||||
buf = s;
|
||||
break;
|
||||
case 'S' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_sec = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 't' :
|
||||
while (isspace (*buf))
|
||||
@@ -354,39 +376,31 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
||||
buf = s;
|
||||
break;
|
||||
case 'u' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 1, &ret))
|
||||
return NULL;
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
timeptr->tm_wday = ret - 1;
|
||||
buf = s;
|
||||
break;
|
||||
case 'w' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 1, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_wday = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'U' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
set_week_number_sun (timeptr, ret);
|
||||
buf = s;
|
||||
break;
|
||||
case 'V' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
set_week_number_mon4 (timeptr, ret);
|
||||
buf = s;
|
||||
break;
|
||||
case 'W' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
set_week_number_mon (timeptr, ret);
|
||||
buf = s;
|
||||
break;
|
||||
case 'x' :
|
||||
s = strptime (buf, "%Y:%m:%d", timeptr);
|
||||
@@ -395,21 +409,17 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
||||
buf = s;
|
||||
break;
|
||||
case 'y' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 2, &ret))
|
||||
return NULL;
|
||||
if (ret < 70)
|
||||
timeptr->tm_year = 100 + ret;
|
||||
else
|
||||
timeptr->tm_year = ret;
|
||||
buf = s;
|
||||
break;
|
||||
case 'Y' :
|
||||
ret = strtol (buf, &s, 10);
|
||||
if (s == buf)
|
||||
if (parse_number(&buf, 4, &ret))
|
||||
return NULL;
|
||||
timeptr->tm_year = ret - tm_year_base;
|
||||
buf = s;
|
||||
break;
|
||||
case 'Z' :
|
||||
abort ();
|
||||
|
Reference in New Issue
Block a user