Sat Aug 6 00:39:56 2011

Asterisk developer's documentation


func_cut.c File Reference

CUT function. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"

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, char *cmd, char *data, char *buf, size_t len)
static int acf_sort_exec (struct ast_channel *chan, 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 | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, }
ast_custom_function acf_cut
ast_custom_function acf_sort
static const 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 63 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 64 of file func_cut.c.

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

#define ERROR_USAGE   (-3)

Definition at line 65 of file func_cut.c.

Referenced by acf_cut_exec(), and cut_internal().

#define MAXRESULT   1024

Definition at line 45 of file func_cut.c.

Referenced by cut_internal(), exec_exec(), and tryexec_exec().


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 331 of file func_cut.c.

static void __unreg_module ( void   )  [static]

Definition at line 331 of file func_cut.c.

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

Definition at line 252 of file func_cut.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, ast_module_user::chan, cut_internal(), ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, and LOG_ERROR.

00253 {
00254    int ret = -1;
00255    struct ast_module_user *u = NULL;
00256 
00257    if (chan) {
00258       u = ast_module_user_add(chan);
00259    }
00260 
00261    switch (cut_internal(chan, data, buf, len)) {
00262    case ERROR_NOARG:
00263       ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n");
00264       break;
00265    case ERROR_NOMEM:
00266       ast_log(LOG_ERROR, "Out of memory\n");
00267       break;
00268    case ERROR_USAGE:
00269       ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n");
00270       break;
00271    case 0:
00272       ret = 0;
00273       break;
00274    default:
00275       ast_log(LOG_ERROR, "Unknown internal error\n");
00276    }
00277 
00278    if (chan) {
00279       ast_module_user_remove(u);
00280    }
00281 
00282    return ret;
00283 }

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

Definition at line 226 of file func_cut.c.

References ast_log(), ast_module_user_add, ast_module_user_remove, ast_module_user::chan, ERROR_NOARG, ERROR_NOMEM, LOG_ERROR, and sort_internal().

00227 {
00228    struct ast_module_user *u;
00229    int ret = -1;
00230 
00231    u = ast_module_user_add(chan);
00232 
00233    switch (sort_internal(chan, data, buf, len)) {
00234    case ERROR_NOARG:
00235       ast_log(LOG_ERROR, "SORT() requires an argument\n");
00236       break;
00237    case ERROR_NOMEM:
00238       ast_log(LOG_ERROR, "Out of memory\n");
00239       break;
00240    case 0:
00241       ret = 0;
00242       break;
00243    default:
00244       ast_log(LOG_ERROR, "Unknown internal error\n");
00245    }
00246 
00247    ast_module_user_remove(u);
00248 
00249    return ret;
00250 }

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

Definition at line 118 of file func_cut.c.

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

Referenced by acf_cut_exec().

00119 {
00120    char *parse;
00121    AST_DECLARE_APP_ARGS(args,
00122       AST_APP_ARG(varname);
00123       AST_APP_ARG(delimiter);
00124       AST_APP_ARG(field);
00125    );
00126 
00127    memset(buffer, 0, buflen); 
00128 
00129    parse = ast_strdupa(data);
00130 
00131    AST_STANDARD_APP_ARGS(args, parse);
00132 
00133    /* Check and parse arguments */
00134    if(args.argc < 3){
00135       return ERROR_NOARG;
00136    } else {
00137       char d, ds[2];
00138       char *tmp = alloca(strlen(args.varname) + 4);
00139       char varvalue[MAXRESULT], *tmp2=varvalue;
00140 
00141       if (tmp) {
00142          snprintf(tmp, strlen(args.varname) + 4, "${%s}", args.varname);
00143          memset(varvalue, 0, sizeof(varvalue));
00144       } else {
00145          return ERROR_NOMEM;
00146       }
00147 
00148       if (args.delimiter[0] == '\\') {
00149          if (args.delimiter[1] == 'n')
00150             d = '\n';
00151          else if (args.delimiter[1] == 't')
00152             d = '\t';
00153          else if (args.delimiter[1] == 'r')
00154             d = '\r';
00155          else if (args.delimiter[1])
00156             d = args.delimiter[1];
00157          else
00158             d = '-';
00159       } else if (args.delimiter[0])
00160          d = args.delimiter[0];
00161       else
00162          d = '-';
00163 
00164       /* String form of the delimiter, for use with strsep(3) */
00165       snprintf(ds, sizeof(ds), "%c", d);
00166 
00167       pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1);
00168 
00169       if (tmp2) {
00170          int curfieldnum = 1, firstfield = 1;
00171          while (tmp2 != NULL && args.field != NULL) {
00172             char *nextgroup = strsep(&(args.field), "&");
00173             int num1 = 0, num2 = MAXRESULT;
00174             char trashchar;
00175 
00176             if (sscanf(nextgroup, "%30d-%30d", &num1, &num2) == 2) {
00177                /* range with both start and end */
00178             } else if (sscanf(nextgroup, "-%30d", &num2) == 1) {
00179                /* range with end */
00180                num1 = 0;
00181             } else if ((sscanf(nextgroup, "%30d%1c", &num1, &trashchar) == 2) && (trashchar == '-')) {
00182                /* range with start */
00183                num2 = MAXRESULT;
00184             } else if (sscanf(nextgroup, "%30d", &num1) == 1) {
00185                /* single number */
00186                num2 = num1;
00187             } else {
00188                return ERROR_USAGE;
00189             }
00190 
00191             /* Get to start, if any */
00192             if (num1 > 0) {
00193                while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) {
00194                   tmp2 = strchr(tmp2, d) + 1;
00195                   curfieldnum++;
00196                }
00197             }
00198 
00199             /* Most frequent problem is the expectation of reordering fields */
00200             if ((num1 > 0) && (curfieldnum > num1))
00201                ast_log(LOG_WARNING, "We're already past the field you wanted?\n");
00202 
00203             /* Re-null tmp2 if we added 1 to NULL */
00204             if (tmp2 == (char *)NULL + 1)
00205                tmp2 = NULL;
00206 
00207             /* Output fields until we either run out of fields or num2 is reached */
00208             while (tmp2 != NULL && curfieldnum <= num2) {
00209                char *tmp3 = strsep(&tmp2, ds);
00210                int curlen = strlen(buffer);
00211 
00212                if (firstfield) {
00213                   snprintf(buffer, buflen, "%s", tmp3);
00214                   firstfield = 0;
00215                } else {
00216                   snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
00217                }
00218                curfieldnum++;
00219             }
00220          }
00221       }
00222    }
00223    return 0;
00224 }

static int load_module ( void   )  [static]

Definition at line 321 of file func_cut.c.

References acf_cut, acf_sort, and ast_custom_function_register().

00322 {
00323    int res = 0;
00324 
00325    res |= ast_custom_function_register(&acf_cut);
00326    res |= ast_custom_function_register(&acf_sort);
00327 
00328    return res;
00329 }

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

Definition at line 67 of file func_cut.c.

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

Referenced by acf_sort_exec().

00068 {
00069    char *strings, *ptrkey, *ptrvalue;
00070    int count=1, count2, element_count=0;
00071    struct sortable_keys *sortable_keys;
00072 
00073    memset(buffer, 0, buflen);
00074 
00075    if (!data)
00076       return ERROR_NOARG;
00077 
00078    strings = ast_strdupa(data);
00079 
00080    for (ptrkey = strings; *ptrkey; ptrkey++) {
00081       if (*ptrkey == '|')
00082          count++;
00083    }
00084 
00085    sortable_keys = alloca(count * sizeof(struct sortable_keys));
00086 
00087    memset(sortable_keys, 0, count * sizeof(struct sortable_keys));
00088 
00089    /* Parse each into a struct */
00090    count2 = 0;
00091    while ((ptrkey = strsep(&strings, "|"))) {
00092       ptrvalue = strchr(ptrkey, ':');
00093       if (!ptrvalue) {
00094          count--;
00095          continue;
00096       }
00097       *ptrvalue++ = '\0';
00098       sortable_keys[count2].key = ptrkey;
00099       sscanf(ptrvalue, "%30f", &sortable_keys[count2].value);
00100       count2++;
00101    }
00102 
00103    /* Sort the structs */
00104    qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine);
00105 
00106    for (count2 = 0; count2 < count; count2++) {
00107       int blen = strlen(buffer);
00108       if (element_count++) {
00109          strncat(buffer + blen, ",", buflen - blen - 1);
00110          blen++;
00111       }
00112       strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1);
00113    }
00114 
00115    return 0;
00116 }

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

Definition at line 52 of file func_cut.c.

References sortable_keys::value.

Referenced by sort_internal().

00053 {
00054    const struct sortable_keys *one=arg1, *two=arg2;
00055    if (one->value < two->value)
00056       return -1;
00057    else if (one->value == two->value)
00058       return 0;
00059    else
00060       return 1;
00061 }

static int unload_module ( void   )  [static]

Definition at line 309 of file func_cut.c.

References acf_cut, acf_sort, ast_custom_function_unregister(), and ast_module_user_hangup_all.

00310 {
00311    int res = 0;
00312 
00313    res |= ast_custom_function_unregister(&acf_cut);
00314    res |= ast_custom_function_unregister(&acf_sort);
00315 
00316    ast_module_user_hangup_all();
00317 
00318    return res;
00319 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT | AST_MODFLAG_BUILDSUM, .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 = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 331 of file func_cut.c.

struct ast_custom_function acf_cut

Definition at line 296 of file func_cut.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function acf_sort

Definition at line 285 of file func_cut.c.

Referenced by load_module(), and unload_module().

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 331 of file func_cut.c.


Generated on Sat Aug 6 00:39:56 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7