Asterisk - The Open Source Telephony Project GIT-master-a358458
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 = AST_BUILDOPT_SUM, .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
Anthony Minessale II

Definition in file func_sprintf.c.

Macro Definition Documentation

◆ SPRINTF_CONVERSION

#define SPRINTF_CONVERSION   4

◆ SPRINTF_FLAG

#define SPRINTF_FLAG   0

◆ SPRINTF_LENGTH

#define SPRINTF_LENGTH   3

◆ SPRINTF_PRECISION

#define SPRINTF_PRECISION   2

◆ SPRINTF_WIDTH

#define SPRINTF_WIDTH   1

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.

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;
78 AST_APP_ARG(format);
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;
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] == '.') {
98 } else {
100 i--;
101 }
102 break;
104 if (arg.format[i] >= '0' && arg.format[i] <= '9')
105 break;
107 case SPRINTF_LENGTH:
108 if (strchr("hl", arg.format[i])) {
109 if (arg.format[i + 1] == arg.format[i])
110 i++;
112 break;
113 } else if (strchr("Lqjzt", arg.format[i])) {
115 break;
116 }
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] == '%') {
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;
205sprintf_fail:
206 return -1;
207}
#define var
Definition: ast_expr2f.c:605
#define ast_log
Definition: astobj2.c:42
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
#define SPRINTF_CONVERSION
#define SPRINTF_WIDTH
#define SPRINTF_LENGTH
#define SPRINTF_PRECISION
#define SPRINTF_FLAG
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define LOG_ERROR
#define NULL
Definition: resample.c:96
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425

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

◆ 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.

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:1558

References ast_custom_function_register, and sprintf_function.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 214 of file func_sprintf.c.

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.

References ast_custom_function_unregister(), and sprintf_function.

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 = AST_BUILDOPT_SUM, .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.

◆ 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.

Referenced by load_module(), and unload_module().