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;
80 );
81
83
84
85 for (i = 0; arg.format[i]; i++) {
88 if (strchr("#0- +'I", arg.format[i]))
89 break;
92 if (arg.format[i] >= '0' && arg.format[i] <= '9')
93 break;
94
95
96 if (arg.format[i] == '.') {
98 } else {
100 i--;
101 }
102 break;
104 if (arg.format[i] >= '0' && arg.format[i] <= '9')
105 break;
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
121
122
124 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
125
126
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
138 snprintf(bufptr,
buf +
len - bufptr, formatbuf, tmpi);
139
140
141 bufptr = strchr(
buf,
'\0');
142 } else if (strchr("eEfFgGaA", arg.format[i])) {
143
144
145
147 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
148
149
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
161 snprintf(bufptr,
buf +
len - bufptr, formatbuf, tmpd);
162
163
164 bufptr = strchr(
buf,
'\0');
165 } else if (arg.format[i] == 's') {
166
167
168
170 formatbuf[&arg.format[i] - formatstart + 1] = '\0';
171
172
173 snprintf(bufptr,
buf +
len - bufptr, formatbuf, arg.var[argcount++]);
174
175
176 bufptr = strchr(
buf,
'\0');
177 } else if (arg.format[i] == '%') {
178
179 *bufptr++ = arg.format[i];
180 } else {
181
182
183
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 }
191 break;
192 default:
193 if (arg.format[i] == '%') {
195 formatstart = &arg.format[i];
196 break;
197 } else {
198
199 *bufptr++ = arg.format[i];
200 }
201 }
202 }
203 *bufptr = '\0';
204 return 0;
205sprintf_fail:
206 return -1;
207}
#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.