Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
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.

69{

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 235 of file func_sprintf.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 235 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 68 of file func_sprintf.c.

69{
70#define SPRINTF_FLAG 0
71#define SPRINTF_WIDTH 1
72#define SPRINTF_PRECISION 2
73#define SPRINTF_LENGTH 3
74#define SPRINTF_CONVERSION 4
75 int i, state = -1, argcount = 0;
76 char *formatstart = NULL, *bufptr = buf;
77 char formatbuf[256] = "";
78 int tmpi;
79 double tmpd;
81 AST_APP_ARG(format);
82 AST_APP_ARG(var)[100];
83 );
84
85 AST_STANDARD_APP_ARGS(arg, data);
86
87 /* Scan the format, converting each argument into the requisite format type. */
88 for (i = 0; arg.format[i]; i++) {
89 switch (state) {
90 case SPRINTF_FLAG:
91 if (strchr("#0- +'I", arg.format[i]))
92 break;
94 case SPRINTF_WIDTH:
95 if (arg.format[i] >= '0' && arg.format[i] <= '9')
96 break;
97
98 /* Next character must be a period to go into a precision */
99 if (arg.format[i] == '.') {
101 } else {
103 i--;
104 }
105 break;
107 if (arg.format[i] >= '0' && arg.format[i] <= '9')
108 break;
110 case SPRINTF_LENGTH:
111 if (strchr("hl", arg.format[i])) {
112 if (arg.format[i + 1] == arg.format[i])
113 i++;
115 break;
116 } else if (strchr("Lqjzt", arg.format[i])) {
118 break;
119 }
122 if (strchr("diouxXc", arg.format[i])) {
123 /* Integer */
124
125 /* Isolate this format alone */
126 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
127 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
128
129 /* Convert the argument into the required type */
130 if (arg.var[argcount]) {
131 if (sscanf(arg.var[argcount++], "%30d", &tmpi) != 1) {
132 ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf);
133 goto sprintf_fail;
134 }
135 } else {
136 ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
137 goto sprintf_fail;
138 }
139
140 /* Format the argument */
141 snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi);
142
143 /* Update the position of the next parameter to print */
144 bufptr = strchr(buf, '\0');
145 } else if (strchr("eEfFgGaA", arg.format[i])) {
146 /* Double */
147
148 /* Isolate this format alone */
149 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
150 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
151
152 /* Convert the argument into the required type */
153 if (arg.var[argcount]) {
154 if (sscanf(arg.var[argcount++], "%30lf", &tmpd) != 1) {
155 ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf);
156 goto sprintf_fail;
157 }
158 } else {
159 ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
160 goto sprintf_fail;
161 }
162
163 /* Format the argument */
164 snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd);
165
166 /* Update the position of the next parameter to print */
167 bufptr = strchr(buf, '\0');
168 } else if (arg.format[i] == 's') {
169 /* String */
170
171 /* Isolate this format alone */
172 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
173 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
174
175 /* Format the argument */
176 snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]);
177
178 /* Update the position of the next parameter to print */
179 bufptr = strchr(buf, '\0');
180 } else if (arg.format[i] == '%') {
181 /* Literal data to copy */
182 *bufptr++ = arg.format[i];
183 } else {
184 /* Not supported */
185
186 /* Isolate this format alone */
187 ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
188 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
189
190 ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]);
191 goto sprintf_fail;
192 }
193 state = -1;
194 break;
195 default:
196 if (arg.format[i] == '%') {
198 formatstart = &arg.format[i];
199 break;
200 } else {
201 /* Literal data to copy */
202 *bufptr++ = arg.format[i];
203 }
204 }
205 }
206 *bufptr = '\0';
207 return 0;
208sprintf_fail:
209 return -1;
210}
#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 235 of file func_sprintf.c.

◆ load_module()

static int load_module ( void  )
static

Definition at line 226 of file func_sprintf.c.

227{
228 int res = 0;
229
231
232 return res;
233}
static struct ast_custom_function sprintf_function
Definition: func_sprintf.c:212
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1559

References ast_custom_function_register, and sprintf_function.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 217 of file func_sprintf.c.

218{
219 int res = 0;
220
222
223 return res;
224}
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 235 of file func_sprintf.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 235 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:68

Definition at line 212 of file func_sprintf.c.

Referenced by load_module(), and unload_module().