aboutsummaryrefslogtreecommitdiffstats
path: root/funcs/func_cut.c
diff options
context:
space:
mode:
Diffstat (limited to 'funcs/func_cut.c')
-rw-r--r--funcs/func_cut.c70
1 files changed, 42 insertions, 28 deletions
diff --git a/funcs/func_cut.c b/funcs/func_cut.c
index 3a3c2f309..437ebf621 100644
--- a/funcs/func_cut.c
+++ b/funcs/func_cut.c
@@ -77,9 +77,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</function>
***/
-/* Maximum length of any variable */
-#define MAXRESULT 1024
-
struct sortable_keys {
char *key;
float value;
@@ -151,7 +148,7 @@ static int sort_internal(struct ast_channel *chan, char *data, char *buffer, siz
return 0;
}
-static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size_t buflen)
+static int cut_internal(struct ast_channel *chan, char *data, struct ast_str **buf, ssize_t buflen)
{
char *parse;
size_t delim_consumed;
@@ -160,8 +157,7 @@ static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size
AST_APP_ARG(delimiter);
AST_APP_ARG(field);
);
-
- *buffer = '\0';
+ struct ast_str *str = ast_str_create(16);
parse = ast_strdupa(data);
@@ -169,31 +165,30 @@ static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size
/* Check and parse arguments */
if (args.argc < 3) {
+ ast_free(str);
return ERROR_NOARG;
} else {
- char d, ds[2] = "";
+ char ds[2] = "";
char *tmp = alloca(strlen(args.varname) + 4);
- char varvalue[MAXRESULT], *tmp2=varvalue;
if (tmp) {
snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname);
} else {
+ ast_free(str);
return ERROR_NOMEM;
}
if (ast_get_encoded_char(args.delimiter, ds, &delim_consumed))
ast_copy_string(ds, "-", sizeof(ds));
- /* String form of the delimiter, for use with strsep(3) */
- d = *ds;
-
- pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
+ ast_str_substitute_variables(&str, 0, chan, tmp);
- if (tmp2) {
+ if (ast_str_strlen(str)) {
int curfieldnum = 1;
+ char *tmp2 = ast_str_buffer(str);
while (tmp2 != NULL && args.field != NULL) {
char *nextgroup = strsep(&(args.field), "&");
- int num1 = 0, num2 = MAXRESULT;
+ int num1 = 0, num2 = INT_MAX;
char trashchar;
if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) {
@@ -203,18 +198,19 @@ static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size
num1 = 0;
} else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) {
/* range with start */
- num2 = MAXRESULT;
+ num2 = INT_MAX;
} else if (sscanf(nextgroup, "%d", &num1) == 1) {
/* single number */
num2 = num1;
} else {
+ ast_free(str);
return ERROR_USAGE;
}
/* Get to start, if any */
if (num1 > 0) {
- while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) {
- tmp2 = strchr(tmp2, d) + 1;
+ while (tmp2 != NULL && curfieldnum < num1) {
+ tmp2 = strchr(tmp2 + 1, ds[0]);
curfieldnum++;
}
}
@@ -223,25 +219,16 @@ static int cut_internal(struct ast_channel *chan, char *data, char *buffer, size
if ((num1 > 0) && (curfieldnum > num1))
ast_log(LOG_WARNING, "We're already past the field you wanted?\n");
- /* Re-null tmp2 if we added 1 to NULL */
- if (tmp2 == (char *)NULL + 1)
- tmp2 = NULL;
-
/* Output fields until we either run out of fields or num2 is reached */
while (tmp2 != NULL && curfieldnum <= num2) {
char *tmp3 = strsep(&tmp2, ds);
- int curlen = strlen(buffer);
-
- if (curlen)
- snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
- else
- snprintf(buffer, buflen, "%s", tmp3);
-
+ ast_str_append(buf, buflen, "%s%s", ast_str_strlen(*buf) ? ds : "", tmp3);
curfieldnum++;
}
}
}
}
+ ast_free(str);
return 0;
}
@@ -269,6 +256,32 @@ static int acf_sort_exec(struct ast_channel *chan, const char *cmd, char *data,
static int acf_cut_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
{
int ret = -1;
+ struct ast_str *str = ast_str_create(16);
+
+ switch (cut_internal(chan, data, &str, len)) {
+ case ERROR_NOARG:
+ ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n");
+ break;
+ case ERROR_NOMEM:
+ ast_log(LOG_ERROR, "Out of memory\n");
+ break;
+ case ERROR_USAGE:
+ ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
+ break;
+ case 0:
+ ret = 0;
+ ast_copy_string(buf, ast_str_buffer(str), len);
+ break;
+ default:
+ ast_log(LOG_ERROR, "Unknown internal error\n");
+ }
+ ast_free(str);
+ return ret;
+}
+
+static int acf_cut_exec2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
+{
+ int ret = -1;
switch (cut_internal(chan, data, buf, len)) {
case ERROR_NOARG:
@@ -298,6 +311,7 @@ struct ast_custom_function acf_sort = {
struct ast_custom_function acf_cut = {
.name = "CUT",
.read = acf_cut_exec,
+ .read2 = acf_cut_exec2,
};
static int unload_module(void)