diff options
author | Tilghman Lesher <tilghman@meg.abyt.es> | 2009-06-18 18:24:23 +0000 |
---|---|---|
committer | Tilghman Lesher <tilghman@meg.abyt.es> | 2009-06-18 18:24:23 +0000 |
commit | e1fa477ba72712465a47b04d8a6603402aae316b (patch) | |
tree | 4c3e7ea7f3c58bf046965ce50e3f754c9c7ff017 /funcs | |
parent | 21ad428d0d8735cda1d0930b38a6719824929af7 (diff) |
Clarify CUT code, and in the process, fix a bug in trunk only
(closes issue #15320)
Reported by: chappell
Patches:
cut_fix.patch uploaded by chappell (license 8)
cut_clarify.patch uploaded by chappell (license 8)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@201745 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'funcs')
-rw-r--r-- | funcs/func_cut.c | 125 |
1 files changed, 61 insertions, 64 deletions
diff --git a/funcs/func_cut.c b/funcs/func_cut.c index bd88fc2e9..c7eb6e5b9 100644 --- a/funcs/func_cut.c +++ b/funcs/func_cut.c @@ -150,87 +150,84 @@ static int sort_internal(struct ast_channel *chan, char *data, char *buffer, siz static int cut_internal(struct ast_channel *chan, char *data, struct ast_str **buf, ssize_t buflen) { - char *parse; + char *parse, ds[2], *var_expr; size_t delim_consumed; + struct ast_str *var_value; AST_DECLARE_APP_ARGS(args, AST_APP_ARG(varname); AST_APP_ARG(delimiter); AST_APP_ARG(field); ); - struct ast_str *str = ast_str_create(16); parse = ast_strdupa(data); AST_STANDARD_APP_ARGS(args, parse); - /* Check and parse arguments */ + /* Check arguments */ if (args.argc < 3) { - ast_free(str); return ERROR_NOARG; - } else { - char ds[2] = ""; - char *tmp = alloca(strlen(args.varname) + 4); - - if (tmp) { - snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname); - } else { - ast_free(str); - return ERROR_NOMEM; - } + } else if (!(var_expr = alloca(strlen(args.varname) + 4))) { + return ERROR_NOMEM; + } + + /* Get the value of the variable named in the 1st argument */ + snprintf(var_expr, strlen(args.varname) + 4, "${%s}", args.varname); + var_value = ast_str_create(16); + ast_str_substitute_variables(&var_value, 0, chan, var_expr); + + /* Copy delimiter from 2nd argument to ds[] possibly decoding backslash escapes */ + if (ast_get_encoded_char(args.delimiter, ds, &delim_consumed)) { + ast_copy_string(ds, "-", sizeof(ds)); + } + ds[1] = '\0'; + + if (ast_str_strlen(var_value)) { + int curfieldnum = 1; + char *curfieldptr = ast_str_buffer(var_value); + int out_field_count = 0; + + while (curfieldptr != NULL && args.field != NULL) { + char *next_range = strsep(&(args.field), "&"); + int start_field, stop_field; + char trashchar; + + if (sscanf(next_range, "%d-%d", &start_field, &stop_field) == 2) { + /* range with both start and end */ + } else if (sscanf(next_range, "-%d", &stop_field) == 1) { + /* range with end only */ + start_field = 1; + } else if ((sscanf(next_range, "%d%c", &start_field, &trashchar) == 2) && (trashchar == '-')) { + /* range with start only */ + stop_field = INT_MAX; + } else if (sscanf(next_range, "%d", &start_field) == 1) { + /* single number */ + stop_field = start_field; + } else { + /* invalid field spec */ + ast_free(var_value); + return ERROR_USAGE; + } + + /* Get to start, if not there already */ + while (curfieldptr != NULL && curfieldnum < start_field) { + strsep(&curfieldptr, ds); + curfieldnum++; + } - if (ast_get_encoded_char(args.delimiter, ds, &delim_consumed)) - ast_copy_string(ds, "-", sizeof(ds)); - - ast_str_substitute_variables(&str, 0, chan, tmp); - - if (ast_str_strlen(str)) { - int curfieldnum = 1; - char *tmp2 = ast_str_buffer(str); - int firstfield = 1; - while (tmp2 != NULL && args.field != NULL) { - char *nextgroup = strsep(&(args.field), "&"); - int num1 = 0, num2 = INT_MAX; - char trashchar; - - if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) { - /* range with both start and end */ - } else if (sscanf(nextgroup, "-%d", &num2) == 1) { - /* range with end */ - num1 = 0; - } else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) { - /* range with start */ - 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 != NULL && curfieldnum < num1) { - tmp2 = strchr(tmp2 + 1, ds[0]); - curfieldnum++; - } - } - - /* Most frequent problem is the expectation of reordering fields */ - if ((num1 > 0) && (curfieldnum > num1)) - ast_log(LOG_WARNING, "We're already past the field you wanted?\n"); - - /* Output fields until we either run out of fields or num2 is reached */ - while (tmp2 != NULL && curfieldnum <= num2) { - char *tmp3 = strsep(&tmp2, ds); - ast_str_append(buf, buflen, "%s%s", firstfield ? "" : ds, tmp3); - firstfield = 0; - curfieldnum++; - } + /* Most frequent problem is the expectation of reordering fields */ + if (curfieldnum > start_field) { + ast_log(LOG_WARNING, "We're already past the field you wanted?\n"); + } + + /* Output fields until we either run out of fields or stop_field is reached */ + while (curfieldptr != NULL && curfieldnum <= stop_field) { + char *field_value = strsep(&curfieldptr, ds); + ast_str_append(buf, buflen, "%s%s", out_field_count++ ? ds : "", field_value); + curfieldnum++; } } } - ast_free(str); + ast_free(var_value); return 0; } |