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

String manipulation dialplan functions. More...

#include "asterisk.h"
#include <ctype.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
Include dependency graph for func_sprintf.c:

Go to the source code of this file.

Macros

#define SPRINTF_CONVERSION   4
 
#define SPRINTF_FLAG   0
 
#define SPRINTF_LENGTH   3
 
#define SPRINTF_PRECISION   2
 
#define SPRINTF_WIDTH   1
 

Functions

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

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SPRINTF dialplan function" , .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_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , }
 
static struct ast_custom_function sprintf_function
 

Detailed Description

String manipulation dialplan functions.

Author
Tilghman Lesher
Anothony Minessale II

Definition in file func_sprintf.c.

Macro Definition Documentation

◆ SPRINTF_CONVERSION

#define SPRINTF_CONVERSION   4

Referenced by acf_sprintf().

◆ SPRINTF_FLAG

#define SPRINTF_FLAG   0

Referenced by acf_sprintf().

◆ SPRINTF_LENGTH

#define SPRINTF_LENGTH   3

Referenced by acf_sprintf().

◆ SPRINTF_PRECISION

#define SPRINTF_PRECISION   2

Referenced by acf_sprintf().

◆ SPRINTF_WIDTH

#define SPRINTF_WIDTH   1

Referenced by acf_sprintf().

Function Documentation

◆ __init_result_buf()

static void __init_result_buf ( void  )
static

Definition at line 42 of file func_sprintf.c.

66 {

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 232 of file func_sprintf.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 232 of file func_sprintf.c.

◆ acf_sprintf()

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

Definition at line 65 of file func_sprintf.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log, AST_STANDARD_APP_ARGS, buf, format, LOG_ERROR, NULL, SPRINTF_CONVERSION, SPRINTF_FLAG, SPRINTF_LENGTH, SPRINTF_PRECISION, SPRINTF_WIDTH, and var.

66 {
67 #define SPRINTF_FLAG 0
68 #define SPRINTF_WIDTH 1
69 #define SPRINTF_PRECISION 2
70 #define SPRINTF_LENGTH 3
71 #define SPRINTF_CONVERSION 4
72  int i, state = -1, argcount = 0;
73  char *formatstart = NULL, *bufptr = buf;
74  char formatbuf[256] = "";
75  int tmpi;
76  double tmpd;
79  AST_APP_ARG(var)[100];
80  );
81 
82  AST_STANDARD_APP_ARGS(arg, data);
83 
84  /* Scan the format, converting each argument into the requisite format type. */
85  for (i = 0; arg.format[i]; i++) {
86  switch (state) {
87  case SPRINTF_FLAG:
88  if (strchr("#0- +'I", arg.format[i]))
89  break;
90  state = SPRINTF_WIDTH;
91  case SPRINTF_WIDTH:
92  if (arg.format[i] >= '0' && arg.format[i] <= '9')
93  break;
94 
95  /* Next character must be a period to go into a precision */
96  if (arg.format[i] == '.') {
97  state = SPRINTF_PRECISION;
98  } else {
99  state = SPRINTF_LENGTH;
100  i--;
101  }
102  break;
103  case SPRINTF_PRECISION:
104  if (arg.format[i] >= '0' && arg.format[i] <= '9')
105  break;
106  state = SPRINTF_LENGTH;
107  case SPRINTF_LENGTH:
108  if (strchr("hl", arg.format[i])) {
109  if (arg.format[i + 1] == arg.format[i])
110  i++;
111  state = SPRINTF_CONVERSION;
112  break;
113  } else if (strchr("Lqjzt", arg.format[i])) {
114  state = SPRINTF_CONVERSION;
115  break;
116  }
117  state = SPRINTF_CONVERSION;
118  case SPRINTF_CONVERSION:
119  if (strchr("diouxXc", arg.format[i])) {
120  /* Integer */
121 
122  /* Isolate this format alone */
123  ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
124  formatbuf[&arg.format[i] - formatstart + 1] = '\0';
125 
126  /* Convert the argument into the required type */
127  if (arg.var[argcount]) {
128  if (sscanf(arg.var[argcount++], "%30d", &tmpi) != 1) {
129  ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf);
130  goto sprintf_fail;
131  }
132  } else {
133  ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
134  goto sprintf_fail;
135  }
136 
137  /* Format the argument */
138  snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi);
139 
140  /* Update the position of the next parameter to print */
141  bufptr = strchr(buf, '\0');
142  } else if (strchr("eEfFgGaA", arg.format[i])) {
143  /* Double */
144 
145  /* Isolate this format alone */
146  ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
147  formatbuf[&arg.format[i] - formatstart + 1] = '\0';
148 
149  /* Convert the argument into the required type */
150  if (arg.var[argcount]) {
151  if (sscanf(arg.var[argcount++], "%30lf", &tmpd) != 1) {
152  ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf);
153  goto sprintf_fail;
154  }
155  } else {
156  ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
157  goto sprintf_fail;
158  }
159 
160  /* Format the argument */
161  snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd);
162 
163  /* Update the position of the next parameter to print */
164  bufptr = strchr(buf, '\0');
165  } else if (arg.format[i] == 's') {
166  /* String */
167 
168  /* Isolate this format alone */
169  ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
170  formatbuf[&arg.format[i] - formatstart + 1] = '\0';
171 
172  /* Format the argument */
173  snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]);
174 
175  /* Update the position of the next parameter to print */
176  bufptr = strchr(buf, '\0');
177  } else if (arg.format[i] == '%') {
178  /* Literal data to copy */
179  *bufptr++ = arg.format[i];
180  } else {
181  /* Not supported */
182 
183  /* Isolate this format alone */
184  ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
185  formatbuf[&arg.format[i] - formatstart + 1] = '\0';
186 
187  ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]);
188  goto sprintf_fail;
189  }
190  state = -1;
191  break;
192  default:
193  if (arg.format[i] == '%') {
194  state = SPRINTF_FLAG;
195  formatstart = &arg.format[i];
196  break;
197  } else {
198  /* Literal data to copy */
199  *bufptr++ = arg.format[i];
200  }
201  }
202  }
203  *bufptr = '\0';
204  return 0;
205 sprintf_fail:
206  return -1;
207 }
#define SPRINTF_WIDTH
#define SPRINTF_PRECISION
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
#define SPRINTF_CONVERSION
#define var
Definition: ast_expr2f.c:614
#define NULL
Definition: resample.c:96
#define SPRINTF_LENGTH
#define SPRINTF_FLAG
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static snd_pcm_format_t format
Definition: chan_alsa.c:102
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
#define AST_APP_ARG(name)
Define an application argument.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 232 of file func_sprintf.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 223 of file func_sprintf.c.

References ast_custom_function_register.

224 {
225  int res = 0;
226 
228 
229  return res;
230 }
static struct ast_custom_function sprintf_function
Definition: func_sprintf.c:209
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1508

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 214 of file func_sprintf.c.

References ast_custom_function_unregister().

215 {
216  int res = 0;
217 
219 
220  return res;
221 }
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
static struct ast_custom_function sprintf_function
Definition: func_sprintf.c:209

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "SPRINTF dialplan function" , .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 232 of file func_sprintf.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 232 of file func_sprintf.c.

◆ result_buf

struct ast_threadstorage result_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_result_buf , .custom_init = NULL , }
static

Definition at line 42 of file func_sprintf.c.

Referenced by test_cli_show_results(), and test_execute_multiple().

◆ sprintf_function

struct ast_custom_function sprintf_function
static
Initial value:
= {
.name = "SPRINTF",
.read = acf_sprintf,
}
static int acf_sprintf(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
Definition: func_sprintf.c:65

Definition at line 209 of file func_sprintf.c.