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
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 */
*/
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
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;
+}
+
*/
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;
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;
}
}
/* 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) {