Browse code

Deprecate parse_date() in favor of av_parse_time().

The new av_parse_time() is created in libavutil/parseutils.h, all the
internal functions used by parse_date are moved to
libavutil/parseutils.c and made static.

Signed-off-by: Mans Rullgard <mans@mansr.com>

Stefano Sabatini authored on 2011/02/16 17:52:36
Showing 8 changed files
... ...
@@ -35,6 +35,7 @@
35 35
 #include "libswscale/swscale.h"
36 36
 #include "libpostproc/postprocess.h"
37 37
 #include "libavutil/avstring.h"
38
+#include "libavutil/parseutils.h"
38 39
 #include "libavutil/pixdesc.h"
39 40
 #include "libavutil/eval.h"
40 41
 #include "libavcodec/opt.h"
... ...
@@ -113,8 +114,8 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
113 113
 
114 114
 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
115 115
 {
116
-    int64_t us = parse_date(timestr, is_duration);
117
-    if (us == INT64_MIN) {
116
+    int64_t us;
117
+    if (av_parse_time(&us, timestr, is_duration) < 0) {
118 118
         fprintf(stderr, "Invalid %s specification for %s: %s\n",
119 119
                 is_duration ? "duration" : "date", context, timestr);
120 120
         exit(1);
... ...
@@ -1478,34 +1478,17 @@ attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base,
1478 1478
                                           const char *arg);
1479 1479
 #endif
1480 1480
 
1481
+#if FF_API_PARSE_DATE
1481 1482
 /**
1482 1483
  * Parse datestr and return a corresponding number of microseconds.
1484
+ *
1483 1485
  * @param datestr String representing a date or a duration.
1484
- * - If a date the syntax is:
1485
- * @code
1486
- *  now|{[{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z|z]}
1487
- * @endcode
1488
- * If the value is "now" it takes the current time.
1489
- * Time is local time unless Z is appended, in which case it is
1490
- * interpreted as UTC.
1491
- * If the year-month-day part is not specified it takes the current
1492
- * year-month-day.
1493
- * @return the number of microseconds since 1st of January, 1970 up to
1494
- * the time of the parsed date or INT64_MIN if datestr cannot be
1495
- * successfully parsed.
1496
- * - If a duration the syntax is:
1497
- * @code
1498
- *  [-]HH[:MM[:SS[.m...]]]
1499
- *  [-]S+[.m...]
1500
- * @endcode
1501
- * @return the number of microseconds contained in a time interval
1502
- * with the specified duration or INT64_MIN if datestr cannot be
1503
- * successfully parsed.
1504
- * @param duration Flag which tells how to interpret datestr, if
1505
- * not zero datestr is interpreted as a duration, otherwise as a
1506
- * date.
1486
+ * See av_parse_time() for the syntax of the provided string.
1487
+ * @deprecated in favor of av_parse_time()
1507 1488
  */
1489
+attribute_deprecated
1508 1490
 int64_t parse_date(const char *datestr, int duration);
1491
+#endif
1509 1492
 
1510 1493
 /**
1511 1494
  * Get the current time in microseconds.
... ...
@@ -42,25 +42,6 @@ void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
42 42
     *nb_ptr = nb;
43 43
 }
44 44
 
45
-time_t mktimegm(struct tm *tm)
46
-{
47
-    time_t t;
48
-
49
-    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
50
-
51
-    if (m < 3) {
52
-        m += 12;
53
-        y--;
54
-    }
55
-
56
-    t = 86400 *
57
-        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
58
-
59
-    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
60
-
61
-    return t;
62
-}
63
-
64 45
 #define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
65 46
 #define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
66 47
 
... ...
@@ -95,94 +76,3 @@ struct tm *brktimegm(time_t secs, struct tm *tm)
95 95
 
96 96
     return tm;
97 97
 }
98
-
99
-/* get a positive number between n_min and n_max, for a maximum length
100
-   of len_max. Return -1 if error. */
101
-static int date_get_num(const char **pp,
102
-                        int n_min, int n_max, int len_max)
103
-{
104
-    int i, val, c;
105
-    const char *p;
106
-
107
-    p = *pp;
108
-    val = 0;
109
-    for(i = 0; i < len_max; i++) {
110
-        c = *p;
111
-        if (!isdigit(c))
112
-            break;
113
-        val = (val * 10) + c - '0';
114
-        p++;
115
-    }
116
-    /* no number read ? */
117
-    if (p == *pp)
118
-        return -1;
119
-    if (val < n_min || val > n_max)
120
-        return -1;
121
-    *pp = p;
122
-    return val;
123
-}
124
-
125
-/* small strptime for ffmpeg */
126
-const char *small_strptime(const char *p, const char *fmt,
127
-                           struct tm *dt)
128
-{
129
-    int c, val;
130
-
131
-    for(;;) {
132
-        c = *fmt++;
133
-        if (c == '\0') {
134
-            return p;
135
-        } else if (c == '%') {
136
-            c = *fmt++;
137
-            switch(c) {
138
-            case 'H':
139
-                val = date_get_num(&p, 0, 23, 2);
140
-                if (val == -1)
141
-                    return NULL;
142
-                dt->tm_hour = val;
143
-                break;
144
-            case 'M':
145
-                val = date_get_num(&p, 0, 59, 2);
146
-                if (val == -1)
147
-                    return NULL;
148
-                dt->tm_min = val;
149
-                break;
150
-            case 'S':
151
-                val = date_get_num(&p, 0, 59, 2);
152
-                if (val == -1)
153
-                    return NULL;
154
-                dt->tm_sec = val;
155
-                break;
156
-            case 'Y':
157
-                val = date_get_num(&p, 0, 9999, 4);
158
-                if (val == -1)
159
-                    return NULL;
160
-                dt->tm_year = val - 1900;
161
-                break;
162
-            case 'm':
163
-                val = date_get_num(&p, 1, 12, 2);
164
-                if (val == -1)
165
-                    return NULL;
166
-                dt->tm_mon = val - 1;
167
-                break;
168
-            case 'd':
169
-                val = date_get_num(&p, 1, 31, 2);
170
-                if (val == -1)
171
-                    return NULL;
172
-                dt->tm_mday = val;
173
-                break;
174
-            case '%':
175
-                goto match;
176
-            default:
177
-                return NULL;
178
-            }
179
-        } else {
180
-        match:
181
-            if (c != *p)
182
-                return NULL;
183
-            p++;
184
-        }
185
-    }
186
-    return p;
187
-}
188
-
... ...
@@ -48,10 +48,7 @@ do {\
48 48
 } while(0)
49 49
 #endif
50 50
 
51
-time_t mktimegm(struct tm *tm);
52 51
 struct tm *brktimegm(time_t secs, struct tm *tm);
53
-const char *small_strptime(const char *p, const char *fmt,
54
-                           struct tm *dt);
55 52
 
56 53
 char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase);
57 54
 
... ...
@@ -3380,124 +3380,16 @@ uint64_t ff_ntp_time(void)
3380 3380
   return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
3381 3381
 }
3382 3382
 
3383
-int64_t parse_date(const char *datestr, int duration)
3384
-{
3385
-    const char *p;
3386
-    int64_t t;
3387
-    struct tm dt;
3388
-    int i;
3389
-    static const char * const date_fmt[] = {
3390
-        "%Y-%m-%d",
3391
-        "%Y%m%d",
3392
-    };
3393
-    static const char * const time_fmt[] = {
3394
-        "%H:%M:%S",
3395
-        "%H%M%S",
3396
-    };
3397
-    const char *q;
3398
-    int is_utc, len;
3399
-    char lastch;
3400
-    int negative = 0;
3401
-
3402
-#undef time
3403
-    time_t now = time(0);
3404
-
3405
-    len = strlen(datestr);
3406
-    if (len > 0)
3407
-        lastch = datestr[len - 1];
3408
-    else
3409
-        lastch = '\0';
3410
-    is_utc = (lastch == 'z' || lastch == 'Z');
3411
-
3412
-    memset(&dt, 0, sizeof(dt));
3413
-
3414
-    p = datestr;
3415
-    q = NULL;
3416
-    if (!duration) {
3417
-        if (!strncasecmp(datestr, "now", len))
3418
-            return (int64_t) now * 1000000;
3419
-
3420
-        /* parse the year-month-day part */
3421
-        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
3422
-            q = small_strptime(p, date_fmt[i], &dt);
3423
-            if (q) {
3424
-                break;
3425
-            }
3426
-        }
3427
-
3428
-        /* if the year-month-day part is missing, then take the
3429
-         * current year-month-day time */
3430
-        if (!q) {
3431
-            if (is_utc) {
3432
-                dt = *gmtime(&now);
3433
-            } else {
3434
-                dt = *localtime(&now);
3435
-            }
3436
-            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
3437
-        } else {
3438
-            p = q;
3439
-        }
3440
-
3441
-        if (*p == 'T' || *p == 't' || *p == ' ')
3442
-            p++;
3443
-
3444
-        /* parse the hour-minute-second part */
3445
-        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
3446
-            q = small_strptime(p, time_fmt[i], &dt);
3447
-            if (q) {
3448
-                break;
3449
-            }
3450
-        }
3451
-    } else {
3452
-        /* parse datestr as a duration */
3453
-        if (p[0] == '-') {
3454
-            negative = 1;
3455
-            ++p;
3456
-        }
3457
-        /* parse datestr as HH:MM:SS */
3458
-        q = small_strptime(p, time_fmt[0], &dt);
3459
-        if (!q) {
3460
-            /* parse datestr as S+ */
3461
-            dt.tm_sec = strtol(p, (char **)&q, 10);
3462
-            if (q == p)
3463
-                /* the parsing didn't succeed */
3464
-                return INT64_MIN;
3465
-            dt.tm_min = 0;
3466
-            dt.tm_hour = 0;
3467
-        }
3468
-    }
3469
-
3470
-    /* Now we have all the fields that we can get */
3471
-    if (!q) {
3472
-        return INT64_MIN;
3473
-    }
3474
-
3475
-    if (duration) {
3476
-        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
3477
-    } else {
3478
-        dt.tm_isdst = -1;       /* unknown */
3479
-        if (is_utc) {
3480
-            t = mktimegm(&dt);
3481
-        } else {
3482
-            t = mktime(&dt);
3483
-        }
3484
-    }
3485
-
3486
-    t *= 1000000;
3383
+#if FF_API_PARSE_DATE
3384
+#include "libavutil/parseutils.h"
3487 3385
 
3488
-    /* parse the .m... part */
3489
-    if (*q == '.') {
3490
-        int val, n;
3491
-        q++;
3492
-        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
3493
-            if (!isdigit(*q))
3494
-                break;
3495
-            val += n * (*q - '0');
3496
-        }
3497
-        t += val;
3498
-    }
3499
-    return negative ? -t : t;
3386
+int64_t parse_date(const char *timestr, int duration)
3387
+{
3388
+    int64_t timeval;
3389
+    av_parse_time(&timeval, timestr, duration);
3390
+    return timeval;
3500 3391
 }
3392
+#endif
3501 3393
 
3502 3394
 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
3503 3395
 {
... ...
@@ -95,5 +95,8 @@
95 95
 #ifndef FF_API_DUMP_FORMAT
96 96
 #define FF_API_DUMP_FORMAT             (LIBAVFORMAT_VERSION_MAJOR < 54)
97 97
 #endif
98
+#ifndef FF_API_PARSE_DATE
99
+#define FF_API_PARSE_DATE              (LIBAVFORMAT_VERSION_MAJOR < 54)
100
+#endif
98 101
 
99 102
 #endif //AVFORMAT_VERSION_H
... ...
@@ -22,6 +22,8 @@
22 22
  */
23 23
 
24 24
 #include <strings.h>
25
+#include <sys/time.h>
26
+#include <time.h>
25 27
 #include "parseutils.h"
26 28
 #include "libavutil/avutil.h"
27 29
 #include "libavutil/eval.h"
... ...
@@ -371,6 +373,241 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
371 371
     return 0;
372 372
 }
373 373
 
374
+/* get a positive number between n_min and n_max, for a maximum length
375
+   of len_max. Return -1 if error. */
376
+static int date_get_num(const char **pp,
377
+                        int n_min, int n_max, int len_max)
378
+{
379
+    int i, val, c;
380
+    const char *p;
381
+
382
+    p = *pp;
383
+    val = 0;
384
+    for(i = 0; i < len_max; i++) {
385
+        c = *p;
386
+        if (!isdigit(c))
387
+            break;
388
+        val = (val * 10) + c - '0';
389
+        p++;
390
+    }
391
+    /* no number read ? */
392
+    if (p == *pp)
393
+        return -1;
394
+    if (val < n_min || val > n_max)
395
+        return -1;
396
+    *pp = p;
397
+    return val;
398
+}
399
+
400
+/* small strptime for ffmpeg */
401
+static
402
+const char *small_strptime(const char *p, const char *fmt,
403
+                           struct tm *dt)
404
+{
405
+    int c, val;
406
+
407
+    for(;;) {
408
+        c = *fmt++;
409
+        if (c == '\0') {
410
+            return p;
411
+        } else if (c == '%') {
412
+            c = *fmt++;
413
+            switch(c) {
414
+            case 'H':
415
+                val = date_get_num(&p, 0, 23, 2);
416
+                if (val == -1)
417
+                    return NULL;
418
+                dt->tm_hour = val;
419
+                break;
420
+            case 'M':
421
+                val = date_get_num(&p, 0, 59, 2);
422
+                if (val == -1)
423
+                    return NULL;
424
+                dt->tm_min = val;
425
+                break;
426
+            case 'S':
427
+                val = date_get_num(&p, 0, 59, 2);
428
+                if (val == -1)
429
+                    return NULL;
430
+                dt->tm_sec = val;
431
+                break;
432
+            case 'Y':
433
+                val = date_get_num(&p, 0, 9999, 4);
434
+                if (val == -1)
435
+                    return NULL;
436
+                dt->tm_year = val - 1900;
437
+                break;
438
+            case 'm':
439
+                val = date_get_num(&p, 1, 12, 2);
440
+                if (val == -1)
441
+                    return NULL;
442
+                dt->tm_mon = val - 1;
443
+                break;
444
+            case 'd':
445
+                val = date_get_num(&p, 1, 31, 2);
446
+                if (val == -1)
447
+                    return NULL;
448
+                dt->tm_mday = val;
449
+                break;
450
+            case '%':
451
+                goto match;
452
+            default:
453
+                return NULL;
454
+            }
455
+        } else {
456
+        match:
457
+            if (c != *p)
458
+                return NULL;
459
+            p++;
460
+        }
461
+    }
462
+    return p;
463
+}
464
+
465
+static time_t mktimegm(struct tm *tm)
466
+{
467
+    time_t t;
468
+
469
+    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
470
+
471
+    if (m < 3) {
472
+        m += 12;
473
+        y--;
474
+    }
475
+
476
+    t = 86400 *
477
+        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
478
+
479
+    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
480
+
481
+    return t;
482
+}
483
+
484
+int av_parse_time(int64_t *timeval, const char *datestr, int duration)
485
+{
486
+    const char *p;
487
+    int64_t t;
488
+    struct tm dt;
489
+    int i;
490
+    static const char * const date_fmt[] = {
491
+        "%Y-%m-%d",
492
+        "%Y%m%d",
493
+    };
494
+    static const char * const time_fmt[] = {
495
+        "%H:%M:%S",
496
+        "%H%M%S",
497
+    };
498
+    const char *q;
499
+    int is_utc, len;
500
+    char lastch;
501
+    int negative = 0;
502
+
503
+#undef time
504
+    time_t now = time(0);
505
+
506
+    len = strlen(datestr);
507
+    if (len > 0)
508
+        lastch = datestr[len - 1];
509
+    else
510
+        lastch = '\0';
511
+    is_utc = (lastch == 'z' || lastch == 'Z');
512
+
513
+    memset(&dt, 0, sizeof(dt));
514
+
515
+    p = datestr;
516
+    q = NULL;
517
+    if (!duration) {
518
+        if (!strncasecmp(datestr, "now", len)) {
519
+            *timeval = (int64_t) now * 1000000;
520
+            return 0;
521
+        }
522
+
523
+        /* parse the year-month-day part */
524
+        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
525
+            q = small_strptime(p, date_fmt[i], &dt);
526
+            if (q) {
527
+                break;
528
+            }
529
+        }
530
+
531
+        /* if the year-month-day part is missing, then take the
532
+         * current year-month-day time */
533
+        if (!q) {
534
+            if (is_utc) {
535
+                dt = *gmtime(&now);
536
+            } else {
537
+                dt = *localtime(&now);
538
+            }
539
+            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
540
+        } else {
541
+            p = q;
542
+        }
543
+
544
+        if (*p == 'T' || *p == 't' || *p == ' ')
545
+            p++;
546
+
547
+        /* parse the hour-minute-second part */
548
+        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
549
+            q = small_strptime(p, time_fmt[i], &dt);
550
+            if (q) {
551
+                break;
552
+            }
553
+        }
554
+    } else {
555
+        /* parse datestr as a duration */
556
+        if (p[0] == '-') {
557
+            negative = 1;
558
+            ++p;
559
+        }
560
+        /* parse datestr as HH:MM:SS */
561
+        q = small_strptime(p, time_fmt[0], &dt);
562
+        if (!q) {
563
+            /* parse datestr as S+ */
564
+            dt.tm_sec = strtol(p, (char **)&q, 10);
565
+            if (q == p) {
566
+                /* the parsing didn't succeed */
567
+                *timeval = INT64_MIN;
568
+                return AVERROR(EINVAL);
569
+            }
570
+            dt.tm_min = 0;
571
+            dt.tm_hour = 0;
572
+        }
573
+    }
574
+
575
+    /* Now we have all the fields that we can get */
576
+    if (!q) {
577
+        *timeval = INT64_MIN;
578
+        return AVERROR(EINVAL);
579
+    }
580
+
581
+    if (duration) {
582
+        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
583
+    } else {
584
+        dt.tm_isdst = -1;       /* unknown */
585
+        if (is_utc) {
586
+            t = mktimegm(&dt);
587
+        } else {
588
+            t = mktime(&dt);
589
+        }
590
+    }
591
+
592
+    t *= 1000000;
593
+
594
+    /* parse the .m... part */
595
+    if (*q == '.') {
596
+        int val, n;
597
+        q++;
598
+        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
599
+            if (!isdigit(*q))
600
+                break;
601
+            val += n * (*q - '0');
602
+        }
603
+        t += val;
604
+    }
605
+    *timeval = negative ? -t : t;
606
+    return 0;
607
+}
608
+
374 609
 #ifdef TEST
375 610
 
376 611
 #undef printf
... ...
@@ -72,4 +72,38 @@ int av_parse_video_rate(AVRational *rate, const char *str);
72 72
 int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
73 73
                    void *log_ctx);
74 74
 
75
+/**
76
+ * Parses timestr and returns in *time a corresponding number of
77
+ * microseconds.
78
+ *
79
+ * @param timeval puts here the number of microseconds corresponding
80
+ * to the string in timestr. If the string represents a duration, it
81
+ * is the number of microseconds contained in the time interval.  If
82
+ * the string is a date, is the number of microseconds since 1st of
83
+ * January, 1970 up to the time of the parsed date.  If timestr cannot
84
+ * be successfully parsed, set *time to INT64_MIN.
85
+
86
+ * @param datestr a string representing a date or a duration.
87
+ * - If a date the syntax is:
88
+ * @code
89
+ * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z]
90
+ * now
91
+ * @endcode
92
+ * If the value is "now" it takes the current time.
93
+ * Time is local time unless Z is appended, in which case it is
94
+ * interpreted as UTC.
95
+ * If the year-month-day part is not specified it takes the current
96
+ * year-month-day.
97
+ * - If a duration the syntax is:
98
+ * @code
99
+ * [-]HH[:MM[:SS[.m...]]]
100
+ * [-]S+[.m...]
101
+ * @endcode
102
+ * @param duration flag which tells how to interpret timestr, if not
103
+ * zero timestr is interpreted as a duration, otherwise as a date
104
+ * @return 0 in case of success, a negative value corresponding to an
105
+ * AVERROR code otherwise
106
+ */
107
+int av_parse_time(int64_t *timeval, const char *timestr, int duration);
108
+
75 109
 #endif /* AVUTIL_PARSEUTILS_H */