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;
83 );
84
86
87
88 for (i = 0; arg.format[i]; i++) {
91 if (strchr("#0- +'I", arg.format[i]))
92 break;
95 if (arg.format[i] >= '0' && arg.format[i] <= '9')
96 break;
97
98
99 if (arg.format[i] == '.') {
101 } else {
103 i--;
104 }
105 break;
107 if (arg.format[i] >= '0' && arg.format[i] <= '9')
108 break;
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
124
125
127 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
128
129
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
141 snprintf(bufptr,
buf +
len - bufptr, formatbuf, tmpi);
142
143
144 bufptr = strchr(
buf,
'\0');
145 } else if (strchr("eEfFgGaA", arg.format[i])) {
146
147
148
150 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
151
152
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
164 snprintf(bufptr,
buf +
len - bufptr, formatbuf, tmpd);
165
166
167 bufptr = strchr(
buf,
'\0');
168 } else if (arg.format[i] == 's') {
169
170
171
173 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
174
175
176 snprintf(bufptr,
buf +
len - bufptr, formatbuf, arg.var[argcount++]);
177
178
179 bufptr = strchr(
buf,
'\0');
180 } else if (arg.format[i] == '%') {
181
182 *bufptr++ = arg.format[i];
183 } else {
184
185
186
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 }
194 break;
195 default:
196 if (arg.format[i] == '%') {
198 formatstart = &arg.format[i];
199 break;
200 } else {
201
202 *bufptr++ = arg.format[i];
203 }
204 }
205 }
206 *bufptr = '\0';
207 return 0;
208sprintf_fail:
209 return -1;
210}
#define SPRINTF_CONVERSION
#define SPRINTF_PRECISION
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.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.