#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"
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 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) |
AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Cut out information from a string") | |
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 | |
ast_custom_function | acf_cut |
ast_custom_function | acf_sort |
Definition in file func_cut.c.
#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) |
#define MAXRESULT 1024 |
Definition at line 45 of file func_cut.c.
Referenced by cut_internal(), exec_exec(), and tryexec_exec().
static int acf_cut_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 249 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.
00250 { 00251 int ret = -1; 00252 struct ast_module_user *u; 00253 00254 u = ast_module_user_add(chan); 00255 00256 switch (cut_internal(chan, data, buf, len)) { 00257 case ERROR_NOARG: 00258 ast_log(LOG_ERROR, "Syntax: CUT(<varname>,<char-delim>,<range-spec>) - missing argument!\n"); 00259 break; 00260 case ERROR_NOMEM: 00261 ast_log(LOG_ERROR, "Out of memory\n"); 00262 break; 00263 case ERROR_USAGE: 00264 ast_log(LOG_ERROR, "Usage: CUT(<varname>,<char-delim>,<range-spec>)\n"); 00265 break; 00266 case 0: 00267 ret = 0; 00268 break; 00269 default: 00270 ast_log(LOG_ERROR, "Unknown internal error\n"); 00271 } 00272 00273 ast_module_user_remove(u); 00274 00275 return ret; 00276 }
static int acf_sort_exec | ( | struct ast_channel * | chan, | |
char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 223 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().
00224 { 00225 struct ast_module_user *u; 00226 int ret = -1; 00227 00228 u = ast_module_user_add(chan); 00229 00230 switch (sort_internal(chan, data, buf, len)) { 00231 case ERROR_NOARG: 00232 ast_log(LOG_ERROR, "SORT() requires an argument\n"); 00233 break; 00234 case ERROR_NOMEM: 00235 ast_log(LOG_ERROR, "Out of memory\n"); 00236 break; 00237 case 0: 00238 ret = 0; 00239 break; 00240 default: 00241 ast_log(LOG_ERROR, "Unknown internal error\n"); 00242 } 00243 00244 ast_module_user_remove(u); 00245 00246 return ret; 00247 }
AST_MODULE_INFO_STANDARD | ( | ASTERISK_GPL_KEY | , | |
"Cut out information from a string" | ||||
) |
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(), pbx_substitute_variables_helper(), and strsep().
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]) 00154 d = args.delimiter[1]; 00155 else 00156 d = '-'; 00157 } else if (args.delimiter[0]) 00158 d = args.delimiter[0]; 00159 else 00160 d = '-'; 00161 00162 /* String form of the delimiter, for use with strsep(3) */ 00163 snprintf(ds, sizeof(ds), "%c", d); 00164 00165 pbx_substitute_variables_helper(chan, tmp, tmp2, MAXRESULT - 1); 00166 00167 if (tmp2) { 00168 int curfieldnum = 1; 00169 while (tmp2 != NULL && args.field != NULL) { 00170 char *nextgroup = strsep(&(args.field), "&"); 00171 int num1 = 0, num2 = MAXRESULT; 00172 char trashchar; 00173 00174 if (sscanf(nextgroup, "%d-%d", &num1, &num2) == 2) { 00175 /* range with both start and end */ 00176 } else if (sscanf(nextgroup, "-%d", &num2) == 1) { 00177 /* range with end */ 00178 num1 = 0; 00179 } else if ((sscanf(nextgroup, "%d%c", &num1, &trashchar) == 2) && (trashchar == '-')) { 00180 /* range with start */ 00181 num2 = MAXRESULT; 00182 } else if (sscanf(nextgroup, "%d", &num1) == 1) { 00183 /* single number */ 00184 num2 = num1; 00185 } else { 00186 return ERROR_USAGE; 00187 } 00188 00189 /* Get to start, if any */ 00190 if (num1 > 0) { 00191 while (tmp2 != (char *)NULL + 1 && curfieldnum < num1) { 00192 tmp2 = index(tmp2, d) + 1; 00193 curfieldnum++; 00194 } 00195 } 00196 00197 /* Most frequent problem is the expectation of reordering fields */ 00198 if ((num1 > 0) && (curfieldnum > num1)) 00199 ast_log(LOG_WARNING, "We're already past the field you wanted?\n"); 00200 00201 /* Re-null tmp2 if we added 1 to NULL */ 00202 if (tmp2 == (char *)NULL + 1) 00203 tmp2 = NULL; 00204 00205 /* Output fields until we either run out of fields or num2 is reached */ 00206 while (tmp2 != NULL && curfieldnum <= num2) { 00207 char *tmp3 = strsep(&tmp2, ds); 00208 int curlen = strlen(buffer); 00209 00210 if (curlen) 00211 snprintf(buffer + curlen, buflen - curlen, "%c%s", d, tmp3); 00212 else 00213 snprintf(buffer, buflen, "%s", tmp3); 00214 00215 curfieldnum++; 00216 } 00217 } 00218 } 00219 } 00220 return 0; 00221 }
static int load_module | ( | void | ) | [static] |
Definition at line 314 of file func_cut.c.
References acf_cut, acf_sort, and ast_custom_function_register().
00315 { 00316 int res = 0; 00317 00318 res |= ast_custom_function_register(&acf_cut); 00319 res |= ast_custom_function_register(&acf_sort); 00320 00321 return res; 00322 }
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, key(), sort_subroutine(), strsep(), 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 = index(ptrkey, ':'); 00093 if (!ptrvalue) { 00094 count--; 00095 continue; 00096 } 00097 *ptrvalue++ = '\0'; 00098 sortable_keys[count2].key = ptrkey; 00099 sscanf(ptrvalue, "%f", &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 302 of file func_cut.c.
References acf_cut, acf_sort, ast_custom_function_unregister(), and ast_module_user_hangup_all.
00303 { 00304 int res = 0; 00305 00306 res |= ast_custom_function_unregister(&acf_cut); 00307 res |= ast_custom_function_unregister(&acf_sort); 00308 00309 ast_module_user_hangup_all(); 00310 00311 return res; 00312 }
struct ast_custom_function acf_cut |
struct ast_custom_function acf_sort |