Thu Apr 28 2011 16:57:10

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
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cut out information from a string" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .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.

Referenced by cut_internal().


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.

{
   int ret = -1;

   switch (cut_internal(chan, data, buf, 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;
      break;
   default:
      ast_log(LOG_ERROR, "Unknown internal error\n");
   }

   return ret;
}
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().

{
   int ret = -1;

   switch (sort_internal(chan, data, buf, len)) {
   case ERROR_NOARG:
      ast_log(LOG_ERROR, "SORT() requires an argument\n");
      break;
   case ERROR_NOMEM:
      ast_log(LOG_ERROR, "Out of memory\n");
      break;
   case 0:
      ret = 0;
      break;
   default:
      ast_log(LOG_ERROR, "Unknown internal error\n");
   }

   return ret;
}
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, ast_strdupa, ERROR_NOARG, ERROR_NOMEM, ERROR_USAGE, LOG_WARNING, MAXRESULT, parse(), pbx_substitute_variables_helper(), and strsep().

Referenced by acf_cut_exec().

{
   char *parse;
   size_t delim_consumed;
   AST_DECLARE_APP_ARGS(args,
      AST_APP_ARG(varname);
      AST_APP_ARG(delimiter);
      AST_APP_ARG(field);
   );

   *buffer = '\0';

   parse = ast_strdupa(data);

   AST_STANDARD_APP_ARGS(args, parse);

   /* Check and parse arguments */
   if (args.argc < 3) {
      return ERROR_NOARG;
   } else {
      char d, 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 {
         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) {
         int curfieldnum = 1, firstfield = 1;
         while (tmp2 != NULL && args.field != NULL) {
            char *nextgroup = strsep(&(args.field), "&");
            int num1 = 0, num2 = MAXRESULT;
            char trashchar;

            if (sscanf(nextgroup, "%30d-%30d", &num1, &num2) == 2) {
               /* range with both start and end */
            } else if (sscanf(nextgroup, "-%30d", &num2) == 1) {
               /* range with end */
               num1 = 0;
            } else if ((sscanf(nextgroup, "%30d%1c", &num1, &trashchar) == 2) && (trashchar == '-')) {
               /* range with start */
               num2 = MAXRESULT;
            } else if (sscanf(nextgroup, "%30d", &num1) == 1) {
               /* single number */
               num2 = num1;
            } else {
               return ERROR_USAGE;
            }

            /* Get to start, if any */
            if (num1 > 0) {
               while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) {
                  tmp2 = strchr(tmp2, d) + 1;
                  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");

            /* 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 (firstfield) {
                  snprintf(buffer, buflen, "%s", tmp3);
                  firstfield = 0;
               } else {
                  snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3);
               }

               curfieldnum++;
            }
         }
      }
   }
   return 0;
}
static int load_module ( void  ) [static]

Definition at line 315 of file func_cut.c.

References ast_custom_function_register.

{
   int res = 0;

   res |= ast_custom_function_register(&acf_cut);
   res |= ast_custom_function_register(&acf_sort);

   return res;
}
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 ast_strdupa, ERROR_NOARG, sortable_keys::key, sort_subroutine(), strsep(), and sortable_keys::value.

Referenced by acf_sort_exec().

{
   char *strings, *ptrkey, *ptrvalue;
   int count=1, count2, element_count=0;
   struct sortable_keys *sortable_keys;

   *buffer = '\0';

   if (!data)
      return ERROR_NOARG;

   strings = ast_strdupa(data);

   for (ptrkey = strings; *ptrkey; ptrkey++) {
      if (*ptrkey == ',')
         count++;
   }

   sortable_keys = alloca(count * sizeof(struct sortable_keys));

   memset(sortable_keys, 0, count * sizeof(struct sortable_keys));

   /* Parse each into a struct */
   count2 = 0;
   while ((ptrkey = strsep(&strings, ","))) {
      ptrvalue = strchr(ptrkey, ':');
      if (!ptrvalue) {
         count--;
         continue;
      }
      *ptrvalue++ = '\0';
      sortable_keys[count2].key = ptrkey;
      sscanf(ptrvalue, "%30f", &sortable_keys[count2].value);
      count2++;
   }

   /* Sort the structs */
   qsort(sortable_keys, count, sizeof(struct sortable_keys), sort_subroutine);

   for (count2 = 0; count2 < count; count2++) {
      int blen = strlen(buffer);
      if (element_count++) {
         strncat(buffer + blen, ",", buflen - blen - 1);
         blen++;
      }
      strncat(buffer + blen, sortable_keys[count2].key, buflen - blen - 1);
   }

   return 0;
}
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().

{
   const struct sortable_keys *one=arg1, *two=arg2;
   if (one->value < two->value)
      return -1;
   else if (one->value == two->value)
      return 0;
   else
      return 1;
}
static int unload_module ( void  ) [static]

Definition at line 305 of file func_cut.c.

References ast_custom_function_unregister().

{
   int res = 0;

   res |= ast_custom_function_unregister(&acf_cut);
   res |= ast_custom_function_unregister(&acf_sort);

   return res;
}

Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Cut out information from a string" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .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.