Fri Nov 12 12:02:07 2010

Asterisk developer's documentation


func_cut.c File Reference

CUT function. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
Include dependency graph for func_cut.c:

Go to the source code of this file.

Data Structures

struct  sortable_keys

Defines

#define ERROR_NOARG   (-1)
#define ERROR_NOMEM   (-2)
#define ERROR_USAGE   (-3)
#define MAXRESULT   1024

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int acf_cut_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int acf_sort_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int cut_internal (struct ast_channel *chan, char *data, char *buffer, size_t buflen)
static int load_module (void)
static int sort_internal (struct ast_channel *chan, char *data, char *buffer, size_t buflen)
static int sort_subroutine (const void *arg1, const void *arg2)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cut out information from a string" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
struct ast_custom_function acf_cut
struct ast_custom_function acf_sort
static struct ast_module_infoast_module_info = &__mod_info

Detailed Description

CUT function.

Author:
Tilghman Lesher <app_cut__v003@the-tilghman.com>

Definition in file func_cut.c.


Define Documentation

#define ERROR_NOARG   (-1)

Definition at line 99 of file func_cut.c.

Referenced by acf_cut_exec(), acf_sort_exec(), cut_internal(), and sort_internal().

#define ERROR_NOMEM   (-2)

Definition at line 100 of file func_cut.c.

Referenced by acf_cut_exec(), acf_sort_exec(), and cut_internal().

#define ERROR_USAGE   (-3)

Definition at line 101 of file func_cut.c.

Referenced by acf_cut_exec(), and cut_internal().

#define MAXRESULT   1024

Definition at line 81 of file func_cut.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 325 of file func_cut.c.

static void __unreg_module ( void   )  [static]

Definition at line 325 of file func_cut.c.

static int acf_cut_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 271 of file func_cut.c.

References ast_log(), cut_internal(), ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, and LOG_ERROR.

00272 {
00273    int ret = -1;
00274 
00275    switch (cut_internal(chan, data, buf, len)) {
00276    case ERROR_NOARG:
00277       ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n");
00278       break;
00279    case ERROR_NOMEM:
00280       ast_log(LOG_ERROR, "Out of memory\n");
00281       break;
00282    case ERROR_USAGE:
00283       ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
00284       break;
00285    case 0:
00286       ret = 0;
00287       break;
00288    default:
00289       ast_log(LOG_ERROR, "Unknown internal error\n");
00290    }
00291 
00292    return ret;
00293 }

static int acf_sort_exec ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 250 of file func_cut.c.

References ast_log(), ERROR_NOARG, ERROR_NOMEM, LOG_ERROR, and sort_internal().

00251 {
00252    int ret = -1;
00253 
00254    switch (sort_internal(chan, data, buf, len)) {
00255    case ERROR_NOARG:
00256       ast_log(LOG_ERROR, "SORT() requires an argument\n");
00257       break;
00258    case ERROR_NOMEM:
00259       ast_log(LOG_ERROR, "Out of memory\n");
00260       break;
00261    case 0:
00262       ret = 0;
00263       break;
00264    default:
00265       ast_log(LOG_ERROR, "Unknown internal error\n");
00266    }
00267 
00268    return ret;
00269 }

static int cut_internal ( struct ast_channel chan,
char *  data,
char *  buffer,
size_t  buflen 
) [static]

Definition at line 154 of file func_cut.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_get_encoded_char(), ast_log(), AST_STANDARD_APP_ARGS, ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOG_WARNING, MAXRESULT, parse(), and pbx_substitute_variables_helper().

Referenced by acf_cut_exec().

00155 {
00156    char *parse;
00157    size_t delim_consumed;
00158    AST_DECLARE_APP_ARGS(args,
00159       AST_APP_ARG(varname);
00160       AST_APP_ARG(delimiter);
00161       AST_APP_ARG(field);
00162    );
00163 
00164    *buffer = '\0';
00165 
00166    parse = ast_strdupa(data);
00167 
00168    AST_STANDARD_APP_ARGS(args, parse);
00169 
00170    /* Check and parse arguments */
00171    if (args.argc < 3) {
00172       return ERROR_NOARG;
00173    } else {
00174       char d, ds[2] = "";
00175       char *tmp = alloca(strlen(args.varname) + 4);
00176       char varvalue[MAXRESULT], *tmp2=varvalue;
00177 
00178       if (tmp) {
00179          snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname);
00180       } else {
00181          return ERROR_NOMEM;
00182       }
00183 
00184       if (ast_get_encoded_char(args.delimiter, ds, &delim_consumed))
00185          ast_copy_string(ds, "-", sizeof(ds));
00186 
00187       /* String form of the delimiter, for use with strsep(3) */
00188       d = *ds;
00189 
00190       pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
00191 
00192       if (tmp2) {
00193          int curfieldnum = 1, firstfield = 1;
00194          while (tmp2 != NULL && args.field != NULL) {
00195             char *nextgroup = strsep(&(args.field), "&");
00196             int num1 = 0, num2 = MAXRESULT;
00197             char trashchar;
00198 
00199             if (sscanf(nextgroup, "%30d-%30d", &num1, &num2) == 2) {
00200                /* range with both start and end */
00201             } else if (sscanf(nextgroup, "-%30d", &num2) == 1) {
00202                /* range with end */
00203                num1 = 0;
00204             } else if ((sscanf(nextgroup, "%30d%1c", &num1, &trashchar) == 2) && (trashchar == '-')) {
00205                /* range with start */
00206                num2 = MAXRESULT;
00207             } else if (sscanf(nextgroup, "%30d", &num1) == 1) {
00208                /* single number */
00209                num2 = num1;
00210             } else {
00211                return ERROR_USAGE;
00212             }
00213 
00214             /* Get to start, if any */
00215             if (num1 > 0) {
00216                while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) {
00217                   tmp2 = strchr(tmp2, d) + 1;
00218                   curfieldnum++;
00219                }
00220             }
00221 
00222             /* Most frequent problem is the expectation of reordering fields */
00223             if ((num1 > 0) && (curfieldnum > num1))
00224                ast_log(LOG_WARNING, "We're already past the field you wanted?\n");
00225 
00226             /* Re-null tmp2 if we added 1 to NULL */
00227             if (tmp2 == (char *)NULL + 1)
00228                tmp2 = NULL;
00229 
00230             /* Output fields until we either run out of fields or num2 is reached */
00231             while (tmp2 != NULL && curfieldnum <= num2) {
00232                char *tmp3 = strsep(&tmp2, ds);
00233                int curlen = strlen(buffer);
00234 
00235                if (firstfield) {
00236                   snprintf(buffer, buflen, "%s", tmp3);
00237                   firstfield = 0;
00238                } else {
00239                   snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
00240                }
00241 
00242                curfieldnum++;
00243             }
00244          }
00245       }
00246    }
00247    return 0;
00248 }

static int load_module ( void   )  [static]

Definition at line 315 of file func_cut.c.

References ast_custom_function_register.

00316 {
00317    int res = 0;
00318 
00319    res |= ast_custom_function_register(&acf_cut);
00320    res |= ast_custom_function_register(&acf_sort);
00321 
00322    return res;
00323 }

static int sort_internal ( struct ast_channel chan,
char *  data,
char *  buffer,
size_t  buflen 
) [static]

Definition at line 103 of file func_cut.c.

References ERROR_NOARG, sortable_keys::key, sort_subroutine(), and sortable_keys::value.

Referenced by acf_sort_exec().

00104 {
00105    char *strings, *ptrkey, *ptrvalue;
00106    int count=1, count2, element_count=0;
00107    struct sortable_keys *sortable_keys;
00108 
00109    *buffer = '\0';
00110 
00111    if (!data)
00112       return ERROR_NOARG;
00113 
00114    strings = ast_strdupa(data);
00115 
00116    for (ptrkey = strings; *ptrkey; ptrkey++) {
00117       if (*ptrkey == ',')
00118          count++;
00119    }
00120 
00121    sortable_keys = alloca(count * sizeof(struct sortable_keys));
00122 
00123    memset(sortable_keys, 0, count * sizeof(struct sortable_keys));
00124 
00125    /* Parse each into a struct */
00126    count2 = 0;
00127    while ((ptrkey = strsep(&strings, ","))) {
00128       ptrvalue = strchr(ptrkey, ':');
00129       if (!ptrvalue) {
00130          count--;
00131          continue;
00132       }
00133       *ptrvalue++ = '\0';
00134       sortable_keys[count2].key = ptrkey;
00135       sscanf(ptrvalue, "%30f", &sortable_keys[count2].value);
00136       count2++;
00137    }
00138 
00139    /* Sort the structs */
00140    qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine);
00141 
00142    for (count2 = 0; count2 < count; count2++) {
00143       int blen = strlen(buffer);
00144       if (element_count++) {
00145          strncat(buffer + blen, ",", buflen - blen - 1);
00146          blen++;
00147       }
00148       strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1);
00149    }
00150 
00151    return 0;
00152 }

static int sort_subroutine ( const void *  arg1,
const void *  arg2 
) [static]

Definition at line 88 of file func_cut.c.

References sortable_keys::value.

Referenced by sort_internal().

00089 {
00090    const struct sortable_keys *one=arg1, *two=arg2;
00091    if (one->value < two->value)
00092       return -1;
00093    else if (one->value == two->value)
00094       return 0;
00095    else
00096       return 1;
00097 }

static int unload_module ( void   )  [static]

Definition at line 305 of file func_cut.c.

References ast_custom_function_unregister().

00306 {
00307    int res = 0;
00308 
00309    res |= ast_custom_function_unregister(&acf_cut);
00310    res |= ast_custom_function_unregister(&acf_sort);
00311 
00312    return res;
00313 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cut out information from a string" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 325 of file func_cut.c.

Initial value:
 {
   .name = "CUT",
   .read = acf_cut_exec,
}

Definition at line 300 of file func_cut.c.

Initial value:
 {
   .name = "SORT",
   .read = acf_sort_exec,
}

Definition at line 295 of file func_cut.c.

Definition at line 325 of file func_cut.c.


Generated by  doxygen 1.6.2