Create an API for adding an optional time unit onto the ends of time periods.
authorTilghman Lesher <tilghman@meg.abyt.es>
Thu, 15 Oct 2009 22:33:30 +0000 (22:33 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Thu, 15 Oct 2009 22:33:30 +0000 (22:33 +0000)
Two examples of its use are included, and the usage could be expanded in some
cases into certain configuration options where time periods are specified.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@224225 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/app.h
main/app.c
main/pbx.c

index 6d73b77..e2ec863 100644 (file)
@@ -84,6 +84,12 @@ struct ast_ivr_menu {
        static struct ast_ivr_option __options_##holder[] = foo;\
        static struct ast_ivr_menu holder = { title, flags, __options_##holder }
 
+typedef enum {
+       TIMELEN_HOURS,
+       TIMELEN_MINUTES,
+       TIMELEN_SECONDS,
+       TIMELEN_MILLISECONDS,
+} ast_timelen;
 
 /*!    \brief Runs an IVR menu
        \return returns 0 on successful completion, -1 on hangup, or -2 on user error in menu */
@@ -580,6 +586,17 @@ int ast_safe_fork(int stop_reaper);
  */
 void ast_safe_fork_cleanup(void);
 
+/*!
+ * \brief Common routine to parse time lengths, with optional time unit specifier
+ * \param[in] timestr String to parse
+ * \param[in] defunit Default unit type
+ * \param[out] result Resulting value, specified in milliseconds
+ * \retval 0 Success
+ * \retval -1 Failure
+ * \since 1.8
+ */
+int ast_app_parse_timelen(const char *timestr, int *result, ast_timelen defunit);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
index 99dcfa6..580e91b 100644 (file)
@@ -2082,3 +2082,59 @@ void ast_safe_fork_cleanup(void)
        ast_unreplace_sigchld();
 }
 
+int ast_app_parse_timelen(const char *timestr, int *result, ast_timelen unit)
+{
+       int res;
+       char u[10];
+#ifdef HAVE_LONG_DOUBLE_WIDER
+       long double amount;
+       #define FMT "%30Lf%9s"
+#else
+       double amount;
+       #define FMT "%30lf%9s"
+#endif
+       if (!timestr) {
+               return -1;
+       }
+
+       if ((res = sscanf(timestr, FMT, &amount, u)) == 0) {
+#undef FMT
+               return -1;
+       } else if (res == 2) {
+               switch (u[0]) {
+               case 'h':
+               case 'H':
+                       unit = TIMELEN_HOURS;
+                       break;
+               case 's':
+               case 'S':
+                       unit = TIMELEN_SECONDS;
+                       break;
+               case 'm':
+               case 'M':
+                       if (toupper(u[1]) == 'S') {
+                               unit = TIMELEN_MILLISECONDS;
+                       } else if (u[1] == '\0') {
+                               unit = TIMELEN_MINUTES;
+                       }
+                       break;
+               }
+       }
+
+       switch (unit) {
+       case TIMELEN_HOURS:
+               amount *= 60;
+               /* fall-through */
+       case TIMELEN_MINUTES:
+               amount *= 60;
+               /* fall-through */
+       case TIMELEN_SECONDS:
+               amount *= 1000;
+               /* fall-through */
+       case TIMELEN_MILLISECONDS:
+               ;
+       }
+       *result = amount > INT_MAX ? INT_MAX : (int) amount;
+       return 0;
+}
+
index dd2016e..58e689e 100644 (file)
@@ -9001,12 +9001,10 @@ static int pbx_builtin_execiftime(struct ast_channel *chan, const char *data)
  */
 static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
 {
-       double s;
        int ms;
 
        /* Wait for "n" seconds */
-       if (data && (s = atof(data)) > 0.0) {
-               ms = s * 1000.0;
+       if (!ast_app_parse_timelen(data, &ms, TIMELEN_SECONDS) && ms > 0) {
                return ast_safe_sleep(chan, ms);
        }
        return 0;
@@ -9018,7 +9016,6 @@ static int pbx_builtin_wait(struct ast_channel *chan, const char *data)
 static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
 {
        int ms, res;
-       double s;
        struct ast_flags flags = {0};
        char *opts[1] = { NULL };
        char *parse;
@@ -9050,12 +9047,13 @@ static int pbx_builtin_waitexten(struct ast_channel *chan, const char *data)
                }
        }
        /* Wait for "n" seconds */
-       if (args.timeout && (s = atof(args.timeout)) > 0)
-                ms = s * 1000.0;
-       else if (chan->pbx)
+       if (!ast_app_parse_timelen(args.timeout, &ms, TIMELEN_SECONDS) && ms > 0) {
+               /* Yay! */
+       } else if (chan->pbx) {
                ms = chan->pbx->rtimeoutms;
-       else
+       } else {
                ms = 10000;
+       }
 
        res = ast_waitfordigit(chan, ms);
        if (!res) {