Asterisk - The Open Source Telephony Project  18.5.0
Functions | Variables
func_sayfiles.c File Reference

Returns files played by Say applications. More...

#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/say.h"
#include "asterisk/lock.h"
#include "asterisk/localtime.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/test.h"
#include "asterisk/module.h"
Include dependency graph for func_sayfiles.c:

Go to the source code of this file.

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
 AST_TEST_DEFINE (test_SAYFILES_function)
 
static int load_module (void)
 
static int sayfile_exec (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Say application files" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_custom_function sayfiles
 

Detailed Description

Returns files played by Say applications.

Author
Naveen Albert aster.nosp@m.isk@.nosp@m.phrea.nosp@m.knet.nosp@m..org

Definition in file func_sayfiles.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 302 of file func_sayfiles.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 302 of file func_sayfiles.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 302 of file func_sayfiles.c.

◆ AST_TEST_DEFINE()

AST_TEST_DEFINE ( test_SAYFILES_function  )

Definition at line 152 of file func_sayfiles.c.

References ast_free, ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_substitute_variables(), AST_TEST_FAIL, AST_TEST_NOT_RUN, AST_TEST_PASS, ast_test_status_update, sip_to_pjsip::info(), NULL, result, TEST_EXECUTE, and TEST_INIT.

153 {
155  struct ast_str *expr, *result;
156 
157  switch (cmd) {
158  case TEST_INIT:
159  info->name = "test_SAYFILES_function";
160  info->category = "/funcs/sayfiles/";
161  info->summary = "Test SAYFILES function substitution";
162  info->description =
163  "Executes a series of variable substitutions using the SAYFILES function and ensures that the expected results are received.";
164  return AST_TEST_NOT_RUN;
165  case TEST_EXECUTE:
166  break;
167  }
168 
169  ast_test_status_update(test, "Testing SAYFILES() substitution ...\n");
170 
171  if (!(expr = ast_str_create(16))) {
172  return AST_TEST_FAIL;
173  }
174  if (!(result = ast_str_create(16))) {
175  ast_free(expr);
176  return AST_TEST_FAIL;
177  }
178 
179  ast_str_set(&expr, 0, "${SAYFILES(hi Th3re,alpha)}");
181  if (strcmp(ast_str_buffer(result), "letters/h&letters/i&letters/space&letters/t&letters/h&digits/3&letters/r&letters/e") != 0) {
182  ast_test_status_update(test, "SAYFILES(hi Th3re,alpha) test failed ('%s')\n",
183  ast_str_buffer(result));
184  res = AST_TEST_FAIL;
185  }
186 
187  ast_str_set(&expr, 0, "${SAYFILES(phreak,phonetic)}");
189  if (strcmp(ast_str_buffer(result), "phonetic/p_p&phonetic/h_p&phonetic/r_p&phonetic/e_p&phonetic/a_p&phonetic/k_p") != 0) {
190  ast_test_status_update(test, "SAYFILES(phreak,phonetic) test failed ('%s')\n",
191  ast_str_buffer(result));
192  res = AST_TEST_FAIL;
193  }
194 
195  ast_str_set(&expr, 0, "${SAYFILES(35,digits)}");
197  if (strcmp(ast_str_buffer(result), "digits/3&digits/5") != 0) {
198  ast_test_status_update(test, "SAYFILES(35,digits) test failed ('%s')\n",
199  ast_str_buffer(result));
200  res = AST_TEST_FAIL;
201  }
202 
203  ast_str_set(&expr, 0, "${SAYFILES(35,number)}");
205  if (strcmp(ast_str_buffer(result), "digits/30&digits/5") != 0) {
206  ast_test_status_update(test, "SAYFILES(35,number) test failed ('%s')\n",
207  ast_str_buffer(result));
208  res = AST_TEST_FAIL;
209  }
210 
211  ast_str_set(&expr, 0, "${SAYFILES(1042,number)}");
213  if (strcmp(ast_str_buffer(result), "digits/1&digits/thousand&digits/40&digits/2") != 0) {
214  ast_test_status_update(test, "SAYFILES(1042,number) test failed ('%s')\n",
215  ast_str_buffer(result));
216  res = AST_TEST_FAIL;
217  }
218 
219  ast_str_set(&expr, 0, "${SAYFILES(0,number)}");
221  if (strcmp(ast_str_buffer(result), "digits/0") != 0) {
222  ast_test_status_update(test, "SAYFILES(0,digits) test failed ('%s')\n",
223  ast_str_buffer(result));
224  res = AST_TEST_FAIL;
225  }
226 
227  ast_str_set(&expr, 0, "${SAYFILES(0,money)}");
229  if (strcmp(ast_str_buffer(result), "digits/0&cents") != 0) {
230  ast_test_status_update(test, "SAYFILES(0,money) test failed ('%s')\n",
231  ast_str_buffer(result));
232  res = AST_TEST_FAIL;
233  }
234 
235  ast_str_set(&expr, 0, "${SAYFILES(0.01,money)}");
237  if (strcmp(ast_str_buffer(result), "digits/1&cent") != 0) {
238  ast_test_status_update(test, "SAYFILES(0.01,money) test failed ('%s')\n",
239  ast_str_buffer(result));
240  res = AST_TEST_FAIL;
241  }
242 
243  ast_str_set(&expr, 0, "${SAYFILES(0.42,money)}");
245  if (strcmp(ast_str_buffer(result), "digits/40&digits/2&cents") != 0) {
246  ast_test_status_update(test, "SAYFILES(0.42,money) test failed ('%s')\n",
247  ast_str_buffer(result));
248  res = AST_TEST_FAIL;
249  }
250 
251  ast_str_set(&expr, 0, "${SAYFILES(1.00,money)}");
253  if (strcmp(ast_str_buffer(result), "digits/1&letters/dollar") != 0) {
254  ast_test_status_update(test, "SAYFILES(1.00,money) test failed ('%s')\n",
255  ast_str_buffer(result));
256  res = AST_TEST_FAIL;
257  }
258 
259  ast_str_set(&expr, 0, "${SAYFILES(1.42,money)}");
261  if (strcmp(ast_str_buffer(result), "digits/1&letters/dollar_&and&digits/40&digits/2&cents") != 0) {
262  ast_test_status_update(test, "SAYFILES(1.42,money) test failed ('%s')\n",
263  ast_str_buffer(result));
264  res = AST_TEST_FAIL;
265  }
266 
267  ast_str_set(&expr, 0, "${SAYFILES(2.00,money)}");
269  if (strcmp(ast_str_buffer(result), "digits/2&dollars") != 0) {
270  ast_test_status_update(test, "SAYFILES(2.00,money) test failed ('%s')\n",
271  ast_str_buffer(result));
272  res = AST_TEST_FAIL;
273  }
274 
275  ast_str_set(&expr, 0, "${SAYFILES(2.42,money)}");
277  if (strcmp(ast_str_buffer(result), "digits/2&dollars&and&digits/40&digits/2&cents") != 0) {
278  ast_test_status_update(test, "SAYFILES(2.42,money) test failed ('%s')\n",
279  ast_str_buffer(result));
280  res = AST_TEST_FAIL;
281  }
282 
283  ast_free(expr);
284  ast_free(result);
285 
286  return res;
287 }
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
void ast_str_substitute_variables(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, const char *templ)
#define NULL
Definition: resample.c:96
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
#define ast_test_status_update(a, b, c...)
Definition: test.h:129
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
def info(msg)
#define ast_free(a)
Definition: astmm.h:182
static PGresult * result
Definition: cel_pgsql.c:88
ast_test_result_state
Definition: test.h:200
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:620

◆ load_module()

static int load_module ( void  )
static

Definition at line 296 of file func_sayfiles.c.

References ast_custom_function_register, and AST_TEST_REGISTER.

297 {
298  AST_TEST_REGISTER(test_SAYFILES_function);
300 }
static struct ast_custom_function sayfiles
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ sayfile_exec()

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

Definition at line 89 of file func_sayfiles.c.

References args, AST_APP_ARG, ast_channel_language(), AST_DECLARE_APP_ARGS, ast_free, ast_get_character_str(), ast_get_digit_str(), ast_get_money_str(), ast_get_number_str(), ast_get_phonetic_str(), ast_log, AST_SAY_CASE_NONE, AST_STANDARD_APP_ARGS, ast_str_buffer(), ast_strlen_zero, LOG_WARNING, NULL, type, and value.

90 {
91  char *value, *type, *files;
92  const char *lang;
93  struct ast_str *filenames = NULL;
95  AST_APP_ARG(value);
96  AST_APP_ARG(type);
97  );
98 
99  if (ast_strlen_zero(data)) {
100  ast_log(LOG_WARNING, "SAYFILES requires an argument\n");
101  return 0;
102  }
103 
105 
106  value = args.value;
107  if (ast_strlen_zero(args.type))
108  type = "alpha";
109  else
110  type = args.type;
111 
112  if (chan)
113  lang = ast_channel_language(chan);
114  else
115  lang = "en"; /* No chan for unit tests */
116 
117  if (!strcmp(type, "alpha")) {
118  filenames = ast_get_character_str(value, lang, AST_SAY_CASE_NONE);
119  } else if (!strcmp(type, "phonetic")) {
120  filenames = ast_get_phonetic_str(value, lang);
121  } else if (!strcmp(type, "digits")) {
122  filenames = ast_get_digit_str(value, lang);
123  } else if (!strcmp(type, "number")) {
124  int num;
125  if (sscanf(value, "%d", &num) == 1)
126  filenames = ast_get_number_str(num, lang);
127  else
128  ast_log(LOG_WARNING, "Invalid numeric argument: %s\n", value);
129  } else if (!strcmp(type, "money")) {
130  filenames = ast_get_money_str(value, lang);
131  } else {
132  ast_log(LOG_WARNING, "Invalid say type specified: %s\n", type);
133  }
134 
135  if (!filenames) {
136  return -1;
137  }
138 
139  files = ast_str_buffer(filenames);
140  snprintf(buf, len, "%s", files);
141  ast_free(filenames);
142 
143  return 0;
144 }
static const char type[]
Definition: chan_ooh323.c:109
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_WARNING
Definition: logger.h:274
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
struct ast_str * ast_get_number_str(int num, const char *lang)
Returns an ast_str of files for SayNumber playback.
Definition: say.c:525
struct ast_str * ast_get_phonetic_str(const char *str, const char *lang)
Returns an ast_str of files for SayPhonetic playback.
Definition: say.c:195
const char * args
#define NULL
Definition: resample.c:96
int value
Definition: syslog.c:37
struct ast_str * ast_get_money_str(const char *str, const char *lang)
Returns an ast_str of files for SayMoney playback.
Definition: say.c:419
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
struct ast_str * ast_get_digit_str(const char *str, const char *lang)
Returns an ast_str of files for SayDigits playback.
Definition: say.c:294
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ast_free(a)
Definition: astmm.h:182
struct ast_str * ast_get_character_str(const char *str, const char *lang, enum ast_say_case_sensitivity sensitivity)
Returns an ast_str of files for SayAlpha playback.
Definition: say.c:63
const char * ast_channel_language(const struct ast_channel *chan)
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 290 of file func_sayfiles.c.

References ast_custom_function_unregister(), and AST_TEST_UNREGISTER.

291 {
292  AST_TEST_UNREGISTER(test_SAYFILES_function);
294 }
static struct ast_custom_function sayfiles
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Say application files" , .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 = "30ef0c93b36035ec78c9cfd712d36d9b" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .support_level = AST_MODULE_SUPPORT_CORE, }
static

Definition at line 302 of file func_sayfiles.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 302 of file func_sayfiles.c.

◆ sayfiles

struct ast_custom_function sayfiles
static
Initial value:
= {
.name = "SAYFILES",
.read = sayfile_exec,
}
static int sayfile_exec(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_sayfiles.c:89

Definition at line 146 of file func_sayfiles.c.