[asterisk-commits] tilghman: branch tilghman/str_substitution r175016 - in /team/tilghman/str_su...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 11 18:25:13 CST 2009
Author: tilghman
Date: Wed Feb 11 18:25:13 2009
New Revision: 175016
URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=175016
Log:
A few more conversions, making some of these more efficient in the process
Modified:
team/tilghman/str_substitution/funcs/func_cut.c
team/tilghman/str_substitution/funcs/func_strings.c
team/tilghman/str_substitution/main/pbx.c
Modified: team/tilghman/str_substitution/funcs/func_cut.c
URL: http://svn.digium.com/svn-view/asterisk/team/tilghman/str_substitution/funcs/func_cut.c?view=diff&rev=175016&r1=175015&r2=175016
==============================================================================
--- team/tilghman/str_substitution/funcs/func_cut.c (original)
+++ team/tilghman/str_substitution/funcs/func_cut.c Wed Feb 11 18:25:13 2009
@@ -77,9 +77,6 @@
</function>
***/
-/* Maximum length of any variable */
-#define MAXRESULT 1024
-
struct sortable_keys {
char *key;
float value;
@@ -151,7 +148,7 @@
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, int buflen)
{
char *parse;
size_t delim_consumed;
@@ -160,8 +157,7 @@
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 @@
/* 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);
-
- if (tmp2) {
+ ast_str_substitute_variables(&str, 0, chan, tmp);
+
+ 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 @@
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 @@
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;
}
@@ -267,6 +254,32 @@
}
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, int len)
{
int ret = -1;
@@ -298,6 +311,7 @@
struct ast_custom_function acf_cut = {
.name = "CUT",
.read = acf_cut_exec,
+ .read2 = acf_cut_exec2,
};
static int unload_module(void)
Modified: team/tilghman/str_substitution/funcs/func_strings.c
URL: http://svn.digium.com/svn-view/asterisk/team/tilghman/str_substitution/funcs/func_strings.c?view=diff&rev=175016&r1=175015&r2=175016
==============================================================================
--- team/tilghman/str_substitution/funcs/func_strings.c (original)
+++ team/tilghman/str_substitution/funcs/func_strings.c Wed Feb 11 18:25:13 2009
@@ -337,7 +337,7 @@
.read2 = function_fieldqty_str,
};
-static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
+static int listfilter(struct ast_channel *chan, const char *cmd, char *parse, char *buf, struct ast_str **bufstr, int len)
{
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(listname);
@@ -347,10 +347,17 @@
const char *orig_list, *ptr;
const char *begin, *cur, *next;
int dlen, flen, first = 1;
- struct ast_str *result = ast_str_thread_get(&result_buf, 16);
+ struct ast_str *result, **result_ptr = &result;
char *delim;
AST_STANDARD_APP_ARGS(args, parse);
+
+ if (buf) {
+ result = ast_str_thread_get(&result_buf, 16);
+ } else {
+ /* Place the result directly into the output buffer */
+ result_ptr = bufstr;
+ }
if (args.argc < 3) {
ast_log(LOG_ERROR, "Usage: LISTFILTER(<listname>,<delimiter>,<fieldvalue>)\n");
@@ -371,7 +378,11 @@
/* If the string isn't there, just copy out the string and be done with it. */
if (!(ptr = strstr(orig_list, args.fieldvalue))) {
- ast_copy_string(buf, orig_list, len);
+ if (buf) {
+ ast_copy_string(buf, orig_list, len);
+ } else {
+ ast_str_set(result_ptr, len, "%s", orig_list);
+ }
if (chan) {
ast_channel_unlock(chan);
}
@@ -391,7 +402,9 @@
ast_str_reset(result);
/* Enough space for any result */
- ast_str_make_space(&result, strlen(orig_list) + 1);
+ if (len > -1) {
+ ast_str_make_space(result_ptr, len ? len : strlen(orig_list) + 1);
+ }
begin = orig_list;
next = strstr(begin, delim);
@@ -411,10 +424,10 @@
} else {
/* Copy field to output */
if (!first) {
- ast_str_append(&result, 0, "%s", delim);
+ ast_str_append(result_ptr, len, "%s", delim);
}
- ast_str_append_substr(&result, 0, begin, cur - begin + 1);
+ ast_str_append_substr(result_ptr, len, begin, cur - begin + 1);
first = 0;
begin = cur + dlen;
}
@@ -423,14 +436,27 @@
ast_channel_unlock(chan);
}
- ast_copy_string(buf, ast_str_buffer(result), len);
-
- return 0;
+ if (buf) {
+ ast_copy_string(buf, ast_str_buffer(result), len);
+ }
+
+ return 0;
+}
+
+static int listfilter_read(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
+{
+ return listfilter(chan, cmd, parse, buf, NULL, len);
+}
+
+static int listfilter_read2(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **buf, int len)
+{
+ return listfilter(chan, cmd, parse, NULL, buf, len);
}
static struct ast_custom_function listfilter_function = {
.name = "LISTFILTER",
- .read = listfilter,
+ .read = listfilter_read,
+ .read2 = listfilter_read2,
};
static int filter(struct ast_channel *chan, const char *cmd, char *parse, char *buf,
@@ -961,9 +987,24 @@
return 0;
}
+static int string_toupper2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, int buflen)
+{
+ char *bufptr, *dataptr = data;
+
+ if (buflen > -1) {
+ ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
+ }
+ bufptr = ast_str_buffer(*buf);
+ while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = toupper(*dataptr++)));
+ ast_str_update(*buf);
+
+ return 0;
+}
+
static struct ast_custom_function toupper_function = {
.name = "TOUPPER",
.read = string_toupper,
+ .read2 = string_toupper2,
};
static int string_tolower(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
@@ -971,6 +1012,20 @@
char *bufptr = buf, *dataptr = data;
while ((bufptr < buf + buflen - 1) && (*bufptr++ = tolower(*dataptr++)));
+
+ return 0;
+}
+
+static int string_tolower2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, int buflen)
+{
+ char *bufptr, *dataptr = data;
+
+ if (buflen > -1) {
+ ast_str_make_space(buf, buflen > 0 ? buflen : strlen(data) + 1);
+ }
+ bufptr = ast_str_buffer(*buf);
+ while ((bufptr < ast_str_buffer(*buf) + ast_str_size(*buf) - 1) && (*bufptr++ = tolower(*dataptr++)));
+ ast_str_update(*buf);
return 0;
}
@@ -978,6 +1033,7 @@
static struct ast_custom_function tolower_function = {
.name = "TOLOWER",
.read = string_tolower,
+ .read2 = string_tolower2,
};
static int unload_module(void)
Modified: team/tilghman/str_substitution/main/pbx.c
URL: http://svn.digium.com/svn-view/asterisk/team/tilghman/str_substitution/main/pbx.c?view=diff&rev=175016&r1=175015&r2=175016
==============================================================================
--- team/tilghman/str_substitution/main/pbx.c (original)
+++ team/tilghman/str_substitution/main/pbx.c Wed Feb 11 18:25:13 2009
@@ -3446,13 +3446,14 @@
/* Substitutes variables into buf, based on string templ */
char *cp4;
const char *tmp, *whereweare;
- int orig_size = ast_str_strlen(*buf);
+ int orig_size = 0;
int offset, offset2, isfunction;
char *nextvar, *nextexp, *nextthing;
char *vars, *vare;
int pos, brackets, needsub, len;
struct ast_str *substr1 = ast_str_create(16), *substr2 = NULL, *substr3 = ast_str_create(16);
+ ast_str_reset(*buf);
whereweare = tmp = templ;
while (!ast_strlen_zero(whereweare)) {
/* Assume we're copying the whole remaining string */
More information about the asterisk-commits
mailing list