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:
Love Hörnquist Åstrand
2005-06-21 18:52:37 +00:00
parent d7fc1e7826
commit eb738780bf

View File

@@ -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 ();