[FFmpeg-devel] [PATCH 2/3] parseutils: make av_parse_time() check for failure.
Stefano Sabatini
stefasab at gmail.com
Mon Apr 23 00:24:25 CEST 2012
On date Tuesday 2012-04-17 12:41:03 +0200, Nicolas George encoded:
> Until now, av_parse_time() would accept "1:00" as "1"
> and silently ignore ":00".
>
> This patch also includes a few cosmetic changes.
>
> Signed-off-by: Nicolas George <nicolas.george at normalesup.org>
> ---
> libavutil/parseutils.c | 90 +++++++++++++++++++++---------------------------
> 1 files changed, 39 insertions(+), 51 deletions(-)
>
>
> Same as the last version posted.
>
>
> diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
> index eae5584..028d0b3 100644
> --- a/libavutil/parseutils.c
> +++ b/libavutil/parseutils.c
> @@ -522,9 +522,11 @@ time_t av_timegm(struct tm *tm)
>
> int av_parse_time(int64_t *timeval, const char *timestr, int duration)
> {
> - const char *p;
> + const char *p, *q;
> int64_t t;
> + time_t now;
> struct tm dt = { 0 };
> + int today = 0, negative = 0, microseconds = 0;
> int i;
> static const char * const date_fmt[] = {
> "%Y-%m-%d",
> @@ -534,25 +536,15 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
> "%H:%M:%S",
> "%H%M%S",
> };
> - const char *q;
> - int is_utc, len;
> - char lastch;
> - int negative = 0;
> -
> -#undef time
> - time_t now = time(0);
> -
> - len = strlen(timestr);
> - if (len > 0)
> - lastch = timestr[len - 1];
> - else
> - lastch = '\0';
> - is_utc = (lastch == 'z' || lastch == 'Z');
>
> p = timestr;
> q = NULL;
> + *timeval = INT64_MIN;
> if (!duration) {
> - if (!av_strncasecmp(timestr, "now", len)) {
> +#undef time
> + now = time(0);
> +
> + if (!av_strcasecmp(timestr, "now")) {
> *timeval = (int64_t) now * 1000000;
> return 0;
> }
> @@ -560,23 +552,17 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
> /* parse the year-month-day part */
> for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
> q = small_strptime(p, date_fmt[i], &dt);
> - if (q) {
> + if (q)
> break;
> - }
> }
>
> /* if the year-month-day part is missing, then take the
> * current year-month-day time */
> if (!q) {
> - if (is_utc) {
> - dt = *gmtime(&now);
> - } else {
> - dt = *localtime(&now);
> - }
> - dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
> - } else {
> - p = q;
> + today = 1;
> + q = p;
> }
> + p = q;
>
> if (*p == 'T' || *p == 't' || *p == ' ')
> p++;
> @@ -584,9 +570,8 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
> /* parse the hour-minute-second part */
> for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
> q = small_strptime(p, time_fmt[i], &dt);
> - if (q) {
> + if (q)
> break;
> - }
> }
> } else {
> /* parse timestr as a duration */
> @@ -599,46 +584,49 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
> if (!q) {
> /* parse timestr as S+ */
> dt.tm_sec = strtol(p, (void *)&q, 10);
> - if (q == p) {
> - /* the parsing didn't succeed */
> - *timeval = INT64_MIN;
> + if (q == p) /* the parsing didn't succeed */
> return AVERROR(EINVAL);
> - }
> dt.tm_min = 0;
> dt.tm_hour = 0;
> }
> }
>
> /* Now we have all the fields that we can get */
> - if (!q) {
> - *timeval = INT64_MIN;
> + if (!q)
> return AVERROR(EINVAL);
> +
> + /* parse the .m... part */
> + if (*q == '.') {
> + int n;
> + q++;
> + for (n = 100000; n >= 1; n /= 10, q++) {
> + if (!isdigit(*q))
> + break;
> + microseconds += n * (*q - '0');
> + }
> }
>
> if (duration) {
> t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
> } else {
> - dt.tm_isdst = -1; /* unknown */
> - if (is_utc) {
> - t = av_timegm(&dt);
> - } else {
> - t = mktime(&dt);
> + int is_utc = *q == 'Z' || *q == 'z';
> + q += is_utc;
> + if (today) { /* fill in today's date */
> + struct tm dt2 = is_utc ? *gmtime(&now) : *localtime(&now);
> + dt2.tm_hour = dt.tm_hour;
> + dt2.tm_min = dt.tm_min;
> + dt2.tm_sec = dt.tm_sec;
> + dt = dt2;
> }
> + t = is_utc ? av_timegm(&dt) : mktime(&dt);
> }
>
> - t *= 1000000;
> + /* Check that we are at the end of the string */
> + if (*q)
> + return AVERROR(EINVAL);
>
> - /* parse the .m... part */
> - if (*q == '.') {
> - int val, n;
> - q++;
> - for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
> - if (!isdigit(*q))
> - break;
> - val += n * (*q - '0');
> - }
> - t += val;
> - }
> + t *= 1000000;
> + t += microseconds;
> *timeval = negative ? -t : t;
> return 0;
> }
Looks good to me, assuming it has been tested, although the changes
could be split to make the patch more readable.
--
FFmpeg = Friendly & Fiendish Marvellous Power Enhancing God
More information about the ffmpeg-devel
mailing list