add EVAL function, deprecate Eval application (bug #4277)
[asterisk/asterisk.git] / funcs / func_strings.c
index b70fbfe..0385fc5 100755 (executable)
@@ -4,6 +4,8 @@
  * String manipulation dialplan functions
  * 
  * Copyright (C) 2005, Digium, Inc.
+ * Portions Copyright (C) 2005, Tilghman Lesher.  All rights reserved.
+ * Portions Copyright (C) 2005, Anthony Minessale II
  *
  * This program is free software, distributed under the terms of
  * the GNU General Public License
@@ -19,6 +21,7 @@
 #include "asterisk/logger.h"
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
+#include "asterisk/localtime.h"
 
 static char *function_fieldqty(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
 {
@@ -115,3 +118,88 @@ struct ast_custom_function len_function = {
        .syntax = "LEN(<string>)",
        .read = builtin_function_len,
 };
+
+static char *acf_strftime(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+{
+       char *format, *epoch, *timezone;
+       long epochi;
+       struct timeval tv;
+       struct tm time;
+
+       if (data) {
+               format = ast_strdupa(data);
+               if (format) {
+                       epoch = strsep(&format, "|");
+                       timezone = strsep(&format, "|");
+
+                       if (epoch && !ast_strlen_zero(epoch) && sscanf(epoch, "%ld", &epochi) == 1) {
+                       } else if (!gettimeofday(&tv, NULL)) {
+                               epochi = tv.tv_sec;
+                       } else {
+                               ast_log(LOG_ERROR, "Cannot gettimeofday() ?!!\n");
+                               return "";
+                       }
+
+                       ast_localtime(&epochi, &time, timezone);
+
+                       if (!format) {
+                               format = "%c";
+                       }
+
+                       buf[0] = '\0';
+                       if (! strftime(buf, len, format, &time)) {
+                               ast_log(LOG_WARNING, "C function strftime() output nothing?!!\n");
+                       }
+                       buf[len - 1] = '\0';
+
+                       return buf;
+               } else {
+                       ast_log(LOG_ERROR, "Out of memory\n");
+               }
+       } else {
+               ast_log(LOG_ERROR, "Asterisk function STRFTIME() requires an argument.\n");
+       }
+       return "";
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function strftime_function = {
+       .name = "STRFTIME",
+       .synopsis = "Returns the current date/time in a specified format.",
+       .syntax = "STRFTIME([<epoch>][,[timezone][,format]])",
+       .read = acf_strftime,
+};
+
+static char *function_eval(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) 
+{
+       if (!data || ast_strlen_zero(data)) {
+               ast_log(LOG_WARNING, "EVAL requires an argument: EVAL(<variable>)\n");
+               return buf;
+       }
+       
+       pbx_substitute_variables_helper(chan, data, buf, len - 1);
+
+       return buf;
+}
+
+#ifndef BUILTIN_FUNC
+static
+#endif
+struct ast_custom_function eval_function = {
+       .name = "EVAL",
+       .synopsis = "Evaluate stored variables.",
+       .syntax = "EVAL(<variable>)",
+       .desc = "Using EVAL basically causes a string to be evaluated twice.\n"
+               "When a variable or expression is in the dialplan, it will be\n"
+               "evaluated at runtime. However, if the result of the evaluation\n"
+               "is in fact a variable or expression, using EVAL will have it\n"
+               "evaluated a second time. For example, if the variable ${MYVAR}\n"
+               "contains \"${OTHERVAR}\", then the result of putting ${EVAL(${MYVAR})}\n"
+               "in the dialplan will be the contents of the variable, OTHERVAR.\n"
+               "Normally, by just putting ${MYVAR} in the dialplan, you would be\n"
+               "left with \"${OTHERVAR}\".\n", 
+       .read = function_eval,
+};
+