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).
|
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||||
* All rights reserved.
|
* 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;
|
const int tm_year_base = 1900;
|
||||||
|
|
||||||
@@ -247,11 +281,9 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
|||||||
timeptr->tm_mon = ret;
|
timeptr->tm_mon = ret;
|
||||||
break;
|
break;
|
||||||
case 'C' :
|
case 'C' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_year = (ret * 100) - tm_year_base;
|
timeptr->tm_year = (ret * 100) - tm_year_base;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'c' :
|
case 'c' :
|
||||||
abort ();
|
abort ();
|
||||||
@@ -263,51 +295,43 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
|||||||
break;
|
break;
|
||||||
case 'd' :
|
case 'd' :
|
||||||
case 'e' :
|
case 'e' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_mday = ret;
|
timeptr->tm_mday = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'H' :
|
case 'H' :
|
||||||
case 'k' :
|
case 'k' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_hour = ret;
|
timeptr->tm_hour = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'I' :
|
case 'I' :
|
||||||
case 'l' :
|
case 'l' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (ret == 12)
|
if (ret == 12)
|
||||||
timeptr->tm_hour = 0;
|
timeptr->tm_hour = 0;
|
||||||
else
|
else
|
||||||
timeptr->tm_hour = ret;
|
timeptr->tm_hour = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'j' :
|
case 'j' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 3, &ret))
|
||||||
if (s == buf)
|
return NULL;
|
||||||
|
if (ret == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_yday = ret - 1;
|
timeptr->tm_yday = ret - 1;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'm' :
|
case 'm' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
return NULL;
|
||||||
|
if (ret == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_mon = ret - 1;
|
timeptr->tm_mon = ret - 1;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'M' :
|
case 'M' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_min = ret;
|
timeptr->tm_min = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'n' :
|
case 'n' :
|
||||||
while (isspace (*buf))
|
while (isspace (*buf))
|
||||||
@@ -336,11 +360,9 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
|||||||
buf = s;
|
buf = s;
|
||||||
break;
|
break;
|
||||||
case 'S' :
|
case 'S' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_sec = ret;
|
timeptr->tm_sec = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 't' :
|
case 't' :
|
||||||
while (isspace (*buf))
|
while (isspace (*buf))
|
||||||
@@ -354,39 +376,31 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
|||||||
buf = s;
|
buf = s;
|
||||||
break;
|
break;
|
||||||
case 'u' :
|
case 'u' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 1, &ret))
|
||||||
if (s == buf)
|
return NULL;
|
||||||
|
if (ret <= 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_wday = ret - 1;
|
timeptr->tm_wday = ret - 1;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'w' :
|
case 'w' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 1, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_wday = ret;
|
timeptr->tm_wday = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'U' :
|
case 'U' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
set_week_number_sun (timeptr, ret);
|
set_week_number_sun (timeptr, ret);
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'V' :
|
case 'V' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
set_week_number_mon4 (timeptr, ret);
|
set_week_number_mon4 (timeptr, ret);
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'W' :
|
case 'W' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
set_week_number_mon (timeptr, ret);
|
set_week_number_mon (timeptr, ret);
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'x' :
|
case 'x' :
|
||||||
s = strptime (buf, "%Y:%m:%d", timeptr);
|
s = strptime (buf, "%Y:%m:%d", timeptr);
|
||||||
@@ -395,21 +409,17 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
|
|||||||
buf = s;
|
buf = s;
|
||||||
break;
|
break;
|
||||||
case 'y' :
|
case 'y' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 2, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (ret < 70)
|
if (ret < 70)
|
||||||
timeptr->tm_year = 100 + ret;
|
timeptr->tm_year = 100 + ret;
|
||||||
else
|
else
|
||||||
timeptr->tm_year = ret;
|
timeptr->tm_year = ret;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'Y' :
|
case 'Y' :
|
||||||
ret = strtol (buf, &s, 10);
|
if (parse_number(&buf, 4, &ret))
|
||||||
if (s == buf)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
timeptr->tm_year = ret - tm_year_base;
|
timeptr->tm_year = ret - tm_year_base;
|
||||||
buf = s;
|
|
||||||
break;
|
break;
|
||||||
case 'Z' :
|
case 'Z' :
|
||||||
abort ();
|
abort ();
|
||||||
|
Reference in New Issue
Block a user