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.