Thu Apr 28 2011 17:16:06

Asterisk developer's documentation


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.

Defines

#define SPRINTF_CONVERSION   4
#define SPRINTF_FLAG   0
#define SPRINTF_LENGTH   3
#define SPRINTF_PRECISION   2
#define SPRINTF_WIDTH   1

Functions

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)
 AST_THREADSTORAGE_CUSTOM_SCOPE (result_buf, NULL, ast_free_ptr, static)
static int load_module (void)
static int unload_module (void)

Variables

static struct ast_module_info
__MODULE_INFO_SECTION 
__mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "SPRINTF dialplan function" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_custom_function sprintf_function

Detailed Description

String manipulation dialplan functions.

Author:
Tilghman Lesher
Anothony Minessale II

Definition in file func_sprintf.c.


Define Documentation

#define SPRINTF_CONVERSION   4

Referenced by acf_sprintf().

#define SPRINTF_FLAG   0

Referenced by acf_sprintf().

#define SPRINTF_LENGTH   3

Referenced by acf_sprintf().

#define SPRINTF_PRECISION   2

Referenced by acf_sprintf().

#define SPRINTF_WIDTH   1

Referenced by acf_sprintf().


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 230 of file func_sprintf.c.

static void __unreg_module ( void  ) [static]

Definition at line 230 of file func_sprintf.c.

static int acf_sprintf ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Definition at line 63 of file func_sprintf.c.

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

{
#define SPRINTF_FLAG 0
#define SPRINTF_WIDTH   1
#define SPRINTF_PRECISION  2
#define SPRINTF_LENGTH  3
#define SPRINTF_CONVERSION 4
   int i, state = -1, argcount = 0;
   char *formatstart = NULL, *bufptr = buf;
   char formatbuf[256] = "";
   int tmpi;
   double tmpd;
   AST_DECLARE_APP_ARGS(arg,
            AST_APP_ARG(format);
            AST_APP_ARG(var)[100];
   );

   AST_STANDARD_APP_ARGS(arg, data);

   /* Scan the format, converting each argument into the requisite format type. */
   for (i = 0; arg.format[i]; i++) {
      switch (state) {
      case SPRINTF_FLAG:
         if (strchr("#0- +'I", arg.format[i]))
            break;
         state = SPRINTF_WIDTH;
      case SPRINTF_WIDTH:
         if (arg.format[i] >= '0' && arg.format[i] <= '9')
            break;

         /* Next character must be a period to go into a precision */
         if (arg.format[i] == '.') {
            state = SPRINTF_PRECISION;
         } else {
            state = SPRINTF_LENGTH;
            i--;
         }
         break;
      case SPRINTF_PRECISION:
         if (arg.format[i] >= '0' && arg.format[i] <= '9')
            break;
         state = SPRINTF_LENGTH;
      case SPRINTF_LENGTH:
         if (strchr("hl", arg.format[i])) {
            if (arg.format[i + 1] == arg.format[i])
               i++;
            state = SPRINTF_CONVERSION;
            break;
         } else if (strchr("Lqjzt", arg.format[i])) {
            state = SPRINTF_CONVERSION;
            break;
         }
         state = SPRINTF_CONVERSION;
      case SPRINTF_CONVERSION:
         if (strchr("diouxXc", arg.format[i])) {
            /* Integer */

            /* Isolate this format alone */
            ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
            formatbuf[&arg.format[i] - formatstart + 1] = '\0';

            /* Convert the argument into the required type */
            if (arg.var[argcount]) {
               if (sscanf(arg.var[argcount++], "%30d", &tmpi) != 1) {
                  ast_log(LOG_ERROR, "Argument '%s' is not an integer number for format '%s'\n", arg.var[argcount - 1], formatbuf);
                  goto sprintf_fail;
               }
            } else {
               ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
               goto sprintf_fail;
            }

            /* Format the argument */
            snprintf(bufptr, buf + len - bufptr, formatbuf, tmpi);

            /* Update the position of the next parameter to print */
            bufptr = strchr(buf, '\0');
         } else if (strchr("eEfFgGaA", arg.format[i])) {
            /* Double */

            /* Isolate this format alone */
            ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
            formatbuf[&arg.format[i] - formatstart + 1] = '\0';

            /* Convert the argument into the required type */
            if (arg.var[argcount]) {
               if (sscanf(arg.var[argcount++], "%30lf", &tmpd) != 1) {
                  ast_log(LOG_ERROR, "Argument '%s' is not a floating point number for format '%s'\n", arg.var[argcount - 1], formatbuf);
                  goto sprintf_fail;
               }
            } else {
               ast_log(LOG_ERROR, "SPRINTF() has more format specifiers than arguments!\n");
               goto sprintf_fail;
            }

            /* Format the argument */
            snprintf(bufptr, buf + len - bufptr, formatbuf, tmpd);

            /* Update the position of the next parameter to print */
            bufptr = strchr(buf, '\0');
         } else if (arg.format[i] == 's') {
            /* String */

            /* Isolate this format alone */
            ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
            formatbuf[&arg.format[i] - formatstart + 1] = '\0';

            /* Format the argument */
            snprintf(bufptr, buf + len - bufptr, formatbuf, arg.var[argcount++]);

            /* Update the position of the next parameter to print */
            bufptr = strchr(buf, '\0');
         } else if (arg.format[i] == '%') {
            /* Literal data to copy */
            *bufptr++ = arg.format[i];
         } else {
            /* Not supported */

            /* Isolate this format alone */
            ast_copy_string(formatbuf, formatstart, sizeof(formatbuf));
            formatbuf[&arg.format[i] - formatstart + 1] = '\0';

            ast_log(LOG_ERROR, "Format type not supported: '%s' with argument '%s'\n", formatbuf, arg.var[argcount++]);
            goto sprintf_fail;
         }
         state = -1;
         break;
      default:
         if (arg.format[i] == '%') {
            state = SPRINTF_FLAG;
            formatstart = &arg.format[i];
            break;
         } else {
            /* Literal data to copy */
            *bufptr++ = arg.format[i];
         }
      }
   }
   *bufptr = '\0';
   return 0;
sprintf_fail:
   return -1;
}
AST_THREADSTORAGE_CUSTOM_SCOPE ( result_buf  ,
NULL  ,
ast_free_ptr  ,
static   
)
static int load_module ( void  ) [static]

Definition at line 221 of file func_sprintf.c.

References ast_custom_function_register.

{
   int res = 0;

   res |= ast_custom_function_register(&sprintf_function);

   return res;
}
static int unload_module ( void  ) [static]

Definition at line 212 of file func_sprintf.c.

References ast_custom_function_unregister().

{
   int res = 0;

   res |= ast_custom_function_unregister(&sprintf_function);

   return res;
}

Variable Documentation

struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "SPRINTF dialplan function" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static]

Definition at line 230 of file func_sprintf.c.

Definition at line 230 of file func_sprintf.c.

Initial value:
 {
   .name = "SPRINTF",
   .read = acf_sprintf,
}

Definition at line 207 of file func_sprintf.c.