+2005-11-03 Kevin P. Fleming <kpfleming@digium.com>
+
+ * include/asterisk/app.h: re-work application arg/option parsing APIs for consistent naming, add doxygen docs for option API
+ * many files: update to new APIs
+
2005-11-02 Kevin P. Fleming <kpfleming@digium.com>
* apps/app_dial.c (dial_exec_full): convert to use API calls for argument/option parsing
return count;
}
-int ast_separate_app_args(char *buf, char delim, char **array, int arraylen)
+unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
{
int argc;
char *scan;
return output;
}
-int ast_parseoptions(const struct ast_option *options, struct ast_flags *flags, char **args, char *optstr)
+int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
{
char *s;
int curarg;
- int argloc;
+ unsigned int argloc;
char *arg;
int res = 0;
- flags->flags = 0;
+ ast_clear_flag(flags, AST_FLAGS_ALL);
if (!optstr)
return 0;
s = optstr;
while (*s) {
- curarg = *s & 0x7f;
- flags->flags |= options[curarg].flag;
+ curarg = *s++ & 0x7f;
+ ast_set_flag(flags, options[curarg].flag);
argloc = options[curarg].arg_index;
- s++;
if (*s == '(') {
/* Has argument */
- s++;
arg = s;
- while (*s && (*s != ')')) s++;
+ while (*++s && (*s != ')'));
if (*s) {
if (argloc)
args[argloc - 1] = arg;
- *s = '\0';
- s++;
+ *s++ = '\0';
} else {
ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
res = -1;
}
- } else if (argloc)
+ } else if (argloc) {
args[argloc - 1] = NULL;
+ }
}
+
return res;
}
static const char *chanspy_spy_type = "ChanSpy";
-#define OPTION_QUIET (1 << 0) /* Quiet, no announcement */
-#define OPTION_BRIDGED (1 << 1) /* Only look at bridged calls */
-#define OPTION_VOLUME (1 << 2) /* Specify initial volume */
-#define OPTION_GROUP (1 << 3) /* Only look at channels in group */
-#define OPTION_RECORD (1 << 4) /* Record */
-
-AST_DECLARE_OPTIONS(chanspy_opts,{
- ['q'] = { OPTION_QUIET },
- ['b'] = { OPTION_BRIDGED },
- ['v'] = { OPTION_VOLUME, 1 },
- ['g'] = { OPTION_GROUP, 2 },
- ['r'] = { OPTION_RECORD, 3 },
+enum {
+ OPTION_QUIET = (1 << 0), /* Quiet, no announcement */
+ OPTION_BRIDGED = (1 << 1), /* Only look at bridged calls */
+ OPTION_VOLUME = (1 << 2), /* Specify initial volume */
+ OPTION_GROUP = (1 << 3), /* Only look at channels in group */
+ OPTION_RECORD = (1 << 4), /* Record */
+} chanspy_opt_flags;
+
+enum {
+ OPT_ARG_VOLUME = 0,
+ OPT_ARG_GROUP,
+ OPT_ARG_RECORD,
+ OPT_ARG_ARRAY_SIZE,
+} chanspy_opt_args;
+
+AST_APP_OPTIONS(chanspy_opts, {
+ AST_APP_OPTION('q', OPTION_QUIET),
+ AST_APP_OPTION('b', OPTION_BRIDGED),
+ AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
+ AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
+ AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
});
STANDARD_LOCAL_USER;
ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
- if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
+ if ((argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
spec = argv[0];
if ( argc > 1) {
options = argv[1];
}
if (options) {
- char *opts[3];
- ast_parseoptions(chanspy_opts, &flags, opts, options);
+ char *opts[OPT_ARG_ARRAY_SIZE];
+ ast_app_parse_options(chanspy_opts, &flags, opts, options);
if (ast_test_flag(&flags, OPTION_GROUP)) {
mygroup = opts[1];
}
tmp = ast_strdupa(data);
memset(argv, 0, sizeof(argv));
- argc = ast_separate_app_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
if (argc < 1) {
ast_log(LOG_WARNING, "ControlPlayback requires an argument (filename)\n");
if (data) {
s = ast_strdupa((char *)data);
if (s) {
- ast_separate_app_args(s, '|', args, 3);
+ ast_app_separate_args(s, '|', args, 3);
varname = args[0];
delimiter = args[1];
field = args[2];
OPT_ARG_ARRAY_SIZE,
} dial_exec_option_args;
-AST_DECLARE_OPTIONS(dial_exec_options, {
- ['A'] = { .flag = OPT_ANNOUNCE, .arg_index = OPT_ARG_ANNOUNCE + 1, },
- ['C'] = { .flag = OPT_RESETCDR, },
- ['d'] = { .flag = OPT_DTMF_EXIT, },
- ['D'] = { .flag = OPT_SENDDTMF, .arg_index = OPT_ARG_SENDDTMF + 1, },
- ['f'] = { .flag = OPT_FORCECLID, },
- ['g'] = { .flag = OPT_GO_ON, },
- ['G'] = { .flag = OPT_GOTO, .arg_index = OPT_ARG_GOTO + 1, },
- ['h'] = { .flag = OPT_CALLEE_HANGUP, },
- ['H'] = { .flag = OPT_CALLER_HANGUP, },
- ['j'] = { .flag = OPT_PRIORITY_JUMP, },
- ['L'] = { .flag = OPT_DURATION_LIMIT, .arg_index = OPT_ARG_DURATION_LIMIT + 1, },
- ['m'] = { .flag = OPT_MUSICBACK, .arg_index = OPT_ARG_MUSICBACK + 1, },
- ['M'] = { .flag = OPT_CALLEE_MACRO, .arg_index = OPT_ARG_CALLEE_MACRO + 1, },
- ['n'] = { .flag = OPT_SCREEN_NOINTRO, },
- ['N'] = { .flag = OPT_SCREEN_NOCLID, },
- ['o'] = { .flag = OPT_ORIGINAL_CLID, },
- ['p'] = { .flag = OPT_SCREENING, },
- ['P'] = { .flag = OPT_PRIVACY, .arg_index = OPT_ARG_PRIVACY + 1, },
- ['r'] = { .flag = OPT_RINGBACK, },
- ['S'] = { .flag = OPT_DURATION_STOP, .arg_index = OPT_ARG_DURATION_STOP + 1, },
- ['t'] = { .flag = OPT_CALLEE_TRANSFER, },
- ['T'] = { .flag = OPT_CALLER_TRANSFER, },
- ['w'] = { .flag = OPT_CALLEE_MONITOR, },
- ['W'] = { .flag = OPT_CALLER_MONITOR, },
+AST_APP_OPTIONS(dial_exec_options, {
+ AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
+ AST_APP_OPTION('C', OPT_RESETCDR),
+ AST_APP_OPTION('d', OPT_DTMF_EXIT),
+ AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
+ AST_APP_OPTION('f', OPT_FORCECLID),
+ AST_APP_OPTION('g', OPT_GO_ON),
+ AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
+ AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
+ AST_APP_OPTION('H', OPT_CALLER_HANGUP),
+ AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
+ AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
+ AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
+ AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
+ AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
+ AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
+ AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
+ AST_APP_OPTION('p', OPT_SCREENING),
+ AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
+ AST_APP_OPTION('r', OPT_RINGBACK),
+ AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
+ AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
+ AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
+ AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
+ AST_APP_OPTION('W', OPT_CALLER_MONITOR),
});
static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags)
AST_STANDARD_APP_ARGS(args, parse);
if (!ast_strlen_zero(args.options)) {
- if (ast_parseoptions(dial_exec_options, &opts, opt_args, args.options)) {
+ if (ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
LOCAL_USER_REMOVE(u);
return -1;
}
snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
if (!ast_strlen_zero(data) && (mydata = ast_strdupa(data))) {
- argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
}
if (argc) {
#define CONFFLAG_ANNOUNCEUSERCOUNT (1 << 22) /* If set, when user joins the conference, they will be told the number of users that are already in */
-AST_DECLARE_OPTIONS(meetme_opts,{
- ['a'] = { CONFFLAG_ADMIN },
- ['c'] = { CONFFLAG_ANNOUNCEUSERCOUNT },
- ['T'] = { CONFFLAG_MONITORTALKER },
- ['i'] = { CONFFLAG_INTROUSER },
- ['m'] = { CONFFLAG_MONITOR },
- ['p'] = { CONFFLAG_POUNDEXIT },
- ['s'] = { CONFFLAG_STARMENU },
- ['t'] = { CONFFLAG_TALKER },
- ['q'] = { CONFFLAG_QUIET },
- ['M'] = { CONFFLAG_MOH },
- ['x'] = { CONFFLAG_MARKEDEXIT },
- ['X'] = { CONFFLAG_EXIT_CONTEXT },
- ['A'] = { CONFFLAG_MARKEDUSER },
- ['b'] = { CONFFLAG_AGI },
- ['w'] = { CONFFLAG_WAITMARKED },
- ['r'] = { CONFFLAG_RECORDCONF },
- ['d'] = { CONFFLAG_DYNAMIC },
- ['D'] = { CONFFLAG_DYNAMICPIN },
- ['e'] = { CONFFLAG_EMPTY },
- ['E'] = { CONFFLAG_EMPTYNOPIN },
- ['P'] = { CONFFLAG_ALWAYSPROMPT },
+AST_APP_OPTIONS(meetme_opts, {
+ AST_APP_OPTION('a', CONFFLAG_ADMIN ),
+ AST_APP_OPTION('c', CONFFLAG_ANNOUNCEUSERCOUNT ),
+ AST_APP_OPTION('T', CONFFLAG_MONITORTALKER ),
+ AST_APP_OPTION('i', CONFFLAG_INTROUSER ),
+ AST_APP_OPTION('m', CONFFLAG_MONITOR ),
+ AST_APP_OPTION('p', CONFFLAG_POUNDEXIT ),
+ AST_APP_OPTION('s', CONFFLAG_STARMENU ),
+ AST_APP_OPTION('t', CONFFLAG_TALKER ),
+ AST_APP_OPTION('q', CONFFLAG_QUIET ),
+ AST_APP_OPTION('M', CONFFLAG_MOH ),
+ AST_APP_OPTION('x', CONFFLAG_MARKEDEXIT ),
+ AST_APP_OPTION('X', CONFFLAG_EXIT_CONTEXT ),
+ AST_APP_OPTION('A', CONFFLAG_MARKEDUSER ),
+ AST_APP_OPTION('b', CONFFLAG_AGI ),
+ AST_APP_OPTION('w', CONFFLAG_WAITMARKED ),
+ AST_APP_OPTION('r', CONFFLAG_RECORDCONF ),
+ AST_APP_OPTION('d', CONFFLAG_DYNAMIC ),
+ AST_APP_OPTION('D', CONFFLAG_DYNAMICPIN ),
+ AST_APP_OPTION('e', CONFFLAG_EMPTY ),
+ AST_APP_OPTION('E', CONFFLAG_EMPTYNOPIN ),
+ AST_APP_OPTION('P', CONFFLAG_ALWAYSPROMPT ),
});
static char *istalking(int x)
ast_copy_string(the_pin, inpin, sizeof(the_pin));
if (inflags) {
- ast_parseoptions(meetme_opts, &confflags, NULL, inflags);
+ ast_app_parse_options(meetme_opts, &confflags, NULL, inflags);
dynamic = ast_test_flag(&confflags, CONFFLAG_DYNAMIC | CONFFLAG_DYNAMICPIN);
if (ast_test_flag(&confflags, CONFFLAG_DYNAMICPIN) && !inpin)
strcpy(the_pin, "q");
};
enum {
- MUXFLAG_APPEND = (1 << 1),
- MUXFLAG_BRIDGED = (1 << 2),
- MUXFLAG_VOLUME = (1 << 3),
- MUXFLAG_READVOLUME = (1 << 4),
- MUXFLAG_WRITEVOLUME = (1 << 5),
+ MUXFLAG_APPEND = (1 << 1),
+ MUXFLAG_BRIDGED = (1 << 2),
+ MUXFLAG_VOLUME = (1 << 3),
+ MUXFLAG_READVOLUME = (1 << 4),
+ MUXFLAG_WRITEVOLUME = (1 << 5),
} mixmonitor_flags;
-AST_DECLARE_OPTIONS(mixmonitor_opts,{
- ['a'] = { MUXFLAG_APPEND },
- ['b'] = { MUXFLAG_BRIDGED },
- ['v'] = { MUXFLAG_READVOLUME, 1 },
- ['V'] = { MUXFLAG_WRITEVOLUME, 2 },
- ['W'] = { MUXFLAG_VOLUME, 3 },
+enum {
+ OPT_ARG_READVOLUME = 0,
+ OPT_ARG_WRITEVOLUME,
+ OPT_ARG_VOLUME,
+ OPT_ARG_ARRAY_SIZE,
+} mixmonitor_args;
+
+AST_APP_OPTIONS(mixmonitor_opts, {
+ AST_APP_OPTION('a', MUXFLAG_APPEND),
+ AST_APP_OPTION('b', MUXFLAG_BRIDGED),
+ AST_APP_OPTION_ARG('v', MUXFLAG_READVOLUME, OPT_ARG_READVOLUME),
+ AST_APP_OPTION_ARG('V', MUXFLAG_WRITEVOLUME, OPT_ARG_WRITEVOLUME),
+ AST_APP_OPTION_ARG('W', MUXFLAG_VOLUME, OPT_ARG_VOLUME),
});
static void stopmon(struct ast_channel *chan, struct ast_channel_spy *spy)
}
if (args.options) {
- char *opts[3] = { NULL, };
+ char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
- ast_parseoptions(mixmonitor_opts, &flags, opts, args.options);
+ ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
- if (ast_strlen_zero(opts[0])) {
+ if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
- } else if ((sscanf(opts[0], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[0]);
+ } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+ ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
} else {
readvol = get_volfactor(x);
}
}
if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
- if (ast_strlen_zero(opts[1])) {
+ if (ast_strlen_zero(opts[OPT_ARG_WRITEVOLUME])) {
ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
- } else if ((sscanf(opts[1], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[1]);
+ } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+ ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
} else {
writevol = get_volfactor(x);
}
}
if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
- if (ast_strlen_zero(opts[2])) {
+ if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
- } else if ((sscanf(opts[2], "%d", &x) != 1) || (x < -4) || (x > 4)) {
- ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[2]);
+ } else if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
+ ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
} else {
readvol = writevol = get_volfactor(x);
}
LOCAL_USER_DECL;
-#define PAGE_DUPLEX (1 << 0)
-#define PAGE_QUIET (1 << 1)
-
-AST_DECLARE_OPTIONS(page_opts,{
- ['d'] = { PAGE_DUPLEX },
- ['q'] = { PAGE_QUIET },
+enum {
+ PAGE_DUPLEX = (1 << 0),
+ PAGE_QUIET = (1 << 1),
+} page_opt_flags;
+
+AST_APP_OPTIONS(page_opts, {
+ AST_APP_OPTION('d', PAGE_DUPLEX),
+ AST_APP_OPTION('q', PAGE_QUIET),
});
struct calloutdata {
tmp = strsep(&options, "|");
if (options)
- ast_parseoptions(page_opts, &flags, NULL, options);
+ ast_app_parse_options(page_opts, &flags, NULL, options);
snprintf(meetmeopts, sizeof(meetmeopts), "%ud|%sqxdw", confid, ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m");
while ((tech = strsep(&tmp, "&"))) {
return -1;
}
- if (ast_separate_app_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) {
+ if (ast_app_separate_args(argcopy, '|', args, sizeof(args) / sizeof(args[0])) < 1) {
ast_log(LOG_WARNING, "Cannot Parse Arguments.\n");
LOCAL_USER_REMOVE(u);
return -1;
#define ERROR_LOCK_PATH -100
-#define OPT_SILENT (1 << 0)
-#define OPT_BUSY_GREETING (1 << 1)
-#define OPT_UNAVAIL_GREETING (1 << 2)
-#define OPT_RECORDGAIN (1 << 3)
-#define OPT_PREPEND_MAILBOX (1 << 4)
-
-#define OPT_ARG_RECORDGAIN 0
-#define OPT_ARG_ARRAY_SIZE 1
-
-AST_DECLARE_OPTIONS(vm_app_options, {
- ['s'] = { .flag = OPT_SILENT },
- ['b'] = { .flag = OPT_BUSY_GREETING },
- ['u'] = { .flag = OPT_UNAVAIL_GREETING },
- ['g'] = { .flag = OPT_RECORDGAIN, .arg_index = OPT_ARG_RECORDGAIN + 1},
- ['p'] = { .flag = OPT_PREPEND_MAILBOX },
+enum {
+ OPT_SILENT =(1 << 0),
+ OPT_BUSY_GREETING = (1 << 1),
+ OPT_UNAVAIL_GREETING = (1 << 2),
+ OPT_RECORDGAIN = (1 << 3),
+ OPT_PREPEND_MAILBOX = (1 << 4),
+} vm_option_flags;
+
+enum {
+ OPT_ARG_RECORDGAIN = 0,
+ OPT_ARG_ARRAY_SIZE = 1,
+} vm_option_args;
+
+AST_APP_OPTIONS(vm_app_options, {
+ AST_APP_OPTION('s', OPT_SILENT),
+ AST_APP_OPTION('b', OPT_BUSY_GREETING),
+ AST_APP_OPTION('u', OPT_UNAVAIL_GREETING),
+ AST_APP_OPTION_ARG('g', OPT_RECORDGAIN, OPT_ARG_RECORDGAIN),
+ AST_APP_OPTION('p', OPT_PREPEND_MAILBOX),
});
static int load_config(void);
char *opts[OPT_ARG_ARRAY_SIZE];
tmp = ast_strdupa(data);
- argc = ast_separate_app_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
if (argc == 2) {
- if (ast_parseoptions(vm_app_options, &flags, opts, argv[1])) {
+ if (ast_app_parse_options(vm_app_options, &flags, opts, argv[1])) {
LOCAL_USER_REMOVE(u);
return -1;
}
if (!ast_strlen_zero(data)) {
ast_copy_string(tmp, data, sizeof(tmp));
- argc = ast_separate_app_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
if (argc == 2) {
- if (ast_parseoptions(vm_app_options, &flags, opts, argv[1])) {
+ if (ast_app_parse_options(vm_app_options, &flags, opts, argv[1])) {
LOCAL_USER_REMOVE(u);
return -1;
}
args = ast_strdupa(agent);
// Extract username (agt), password and name from agent (args).
- if ((argc = ast_separate_app_args(args, ',', argv, sizeof(argv) / sizeof(argv[0])))) {
+ if ((argc = ast_app_separate_args(args, ',', argv, sizeof(argv) / sizeof(argv[0])))) {
agt = argv[0];
if (argc > 1) {
password = argv[1];
return NULL;
mydata = ast_strdupa(data);
- argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
/* check for a trailing flags argument */
if (argc > 1) {
return;
mydata = ast_strdupa(data);
- argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
/* check for a trailing flags argument */
if (argc > 1) {
}
args = ast_strdupa(data);
- argc = ast_separate_app_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
if (argc > 1) {
family = argv[0];
}
args = ast_strdupa(data);
- argc = ast_separate_app_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
if (argc > 1) {
family = argv[0];
}
args = ast_strdupa(data);
- argc = ast_separate_app_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(args, '/', argv, sizeof(argv) / sizeof(argv[0]));
if (argc > 1) {
family = argv[0];
}
args = ast_strdupa(data);
- argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
if (argc < 1) {
ast_log(LOG_WARNING, "Syntax: Math(<number1><op><number 2>[,<type_of_result>]) - missing argument!\n");
}
args = ast_strdupa(data);
- argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0]));
if (argc < 2) {
ast_log(LOG_WARNING, "Syntax: CHECK_MD5(<digest>,<data>) - missing argument!\n");
#define AST_IVR_FLAG_AUTORESTART (1 << 0)
-struct ast_option {
- unsigned int flag;
- int arg_index;
-};
-
-extern int ast_parseoptions(const struct ast_option *options, struct ast_flags *flags, char **args, char *optstr);
-
-#define AST_DECLARE_OPTIONS(holder,args...) \
- static struct ast_option holder[128] = args
-
-#define AST_IVR_DECLARE_MENU(holder,title,flags,foo...) \
+#define AST_IVR_DECLARE_MENU(holder, title, flags, foo...) \
static struct ast_ivr_option __options_##holder[] = foo;\
static struct ast_ivr_menu holder = { title, flags, __options_##holder }
*/
#define AST_DECLARE_APP_ARGS(name, arglist) \
struct { \
- int argc; \
+ unsigned int argc; \
char *argv[0]; \
arglist \
} name;
the argc argument counter field.
*/
#define AST_STANDARD_APP_ARGS(args, parse) \
- args.argc = ast_separate_app_args(parse, '|', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
+ args.argc = ast_app_separate_args(parse, '|', args.argv, (sizeof(args) - sizeof(args.argc)) / sizeof(args.argv[0]))
/*!
\brief Separate a string into arguments in an array
\return The number of arguments found, or zero if the function arguments are not valid.
*/
-int ast_separate_app_args(char *buf, char delim, char **array, int arraylen);
+unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen);
+
+/*!
+ \brief A structure to hold the description of an application 'option'.
+
+ Application 'options' are single-character flags that can be supplied
+ to the application to affect its behavior; they can also optionally
+ accept arguments enclosed in parenthesis.
+
+ These structures are used by the ast_app_parse_options function, uses
+ this data to fill in a flags structure (to indicate which options were
+ supplied) and array of argument pointers (for those options that had
+ arguments supplied).
+ */
+struct ast_app_option {
+ /*! \brief The flag bit that represents this option. */
+ unsigned int flag;
+ /*! \brief The index of the entry in the arguments array
+ that should be used for this option's argument. */
+ unsigned int arg_index;
+};
+
+/*!
+ \brief Declares an array of options for an application.
+ \param holder The name of the array to be created
+ \param options The actual options to be placed into the array
+ \sa ast_app_parse_options
+
+ This macro declares a 'static const' array of \c struct \c ast_option
+ elements to hold the list of available options for an application.
+ Each option must be declared using either the AST_APP_OPTION()
+ or AST_APP_OPTION_ARG() macros.
+
+ Example usage:
+ \code
+ enum {
+ OPT_JUMP = (1 << 0),
+ OPT_BLAH = (1 << 1),
+ OPT_BLORT = (1 << 2),
+ } my_app_option_flags;
+
+ enum {
+ OPT_ARG_BLAH = 0,
+ OPT_ARG_BLORT,
+ !! this entry tells how many possible arguments there are,
+ and must be the last entry in the list
+ OPT_ARG_ARRAY_SIZE,
+ } my_app_option_args;
+
+ AST_APP_OPTIONS(my_app_options, {
+ AST_APP_OPTION('j', OPT_JUMP),
+ AST_APP_OPTION_ARG('b', OPT_BLAH, OPT_ARG_BLAH),
+ AST_APP_OPTION_BLORT('B', OPT_BLORT, OPT_ARG_BLORT),
+ });
+
+ static int my_app_exec(struct ast_channel *chan, void *data)
+ {
+ char *options;
+ struct ast_flags opts = { 0, };
+ char *opt_args[OPT_ARG_ARRAY_SIZE];
+
+ ... do any argument parsing here ...
+
+ if (ast_parseoptions(my_app_options, &opts, opt_args, options)) {
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+ }
+ \endcode
+ */
+#define AST_APP_OPTIONS(holder, options...) \
+ static const struct ast_app_option holder[128] = options
+
+/*!
+ \brief Declares an application option that does not accept an argument.
+ \param option The single character representing the option
+ \param flagno The flag index to be set if this option is present
+ \sa AST_APP_OPTIONS, ast_app_parse_options
+ */
+#define AST_APP_OPTION(option, flagno) \
+ [option] = { .flag = flagno }
+
+/*!
+ \brief Declares an application option that accepts an argument.
+ \param option The single character representing the option
+ \param flagno The flag index to be set if this option is present
+ \param argno The index into the argument array where the argument should
+ be placed
+ \sa AST_APP_OPTIONS, ast_app_parse_options
+ */
+#define AST_APP_OPTION_ARG(option, flagno, argno) \
+ [option] = { .flag = flagno, .arg_index = argno }
+
+/*!
+ \brief Parses a string containing application options and sets flags/arguments.
+ \param options The array of possible options declared with AST_APP_OPTIONS
+ \param flags The flag structure to have option flags set
+ \param args The array of argument pointers to hold arguments found
+ \param optstr The string containing the options to be parsed
+ \return zero for success, non-zero if an error occurs
+ \sa AST_APP_OPTIONS
+ */
+int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr);
/*! Present a dialtone and collect a certain length extension. Returns 1 on valid extension entered, -1 on hangup, or 0 on invalid extension. Note that if 'collect' holds digits already, new digits will be appended, so be sure it's initialized properly */
int ast_app_dtget(struct ast_channel *chan, const char *context, char *collect, size_t size, int maxlen, int timeout);
#define BACKGROUND_MATCHEXTEN (1 << 2)
#define BACKGROUND_PLAYBACK (1 << 3)
-AST_DECLARE_OPTIONS(background_opts,{
- ['s'] = { BACKGROUND_SKIP },
- ['n'] = { BACKGROUND_NOANSWER },
- ['m'] = { BACKGROUND_MATCHEXTEN },
- ['p'] = { BACKGROUND_PLAYBACK },
+AST_APP_OPTIONS(background_opts, {
+ AST_APP_OPTION('s', BACKGROUND_SKIP),
+ AST_APP_OPTION('n', BACKGROUND_NOANSWER),
+ AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN),
+ AST_APP_OPTION('p', BACKGROUND_PLAYBACK),
});
#define WAITEXTEN_MOH (1 << 0)
-AST_DECLARE_OPTIONS(waitexten_opts,{
- ['m'] = { WAITEXTEN_MOH, 1 },
+AST_APP_OPTIONS(waitexten_opts, {
+ AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 1),
});
struct ast_context;
char *args;
char *argv[2];
char *options = NULL;
- char *mohclass = NULL;
char *timeout = NULL;
struct ast_flags flags = {0};
+ char *opts[1] = { NULL };
args = ast_strdupa(data);
- if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
+ if ((argc = ast_app_separate_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
if (argc > 0) {
timeout = argv[0];
if (argc > 1)
}
}
- if (options) {
- char *opts[1];
- ast_parseoptions(waitexten_opts, &flags, opts, options);
- if (ast_test_flag(&flags, WAITEXTEN_MOH)) {
- mohclass = opts[0];
- }
- }
+ if (options)
+ ast_app_parse_options(waitexten_opts, &flags, opts, options);
if (ast_test_flag(&flags, WAITEXTEN_MOH))
- ast_moh_start(chan, mohclass);
+ ast_moh_start(chan, opts[0]);
/* Wait for "n" seconds */
if (timeout && atof((char *)timeout))
parse = ast_strdupa(data);
- if ((argc = ast_separate_app_args(parse, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
+ if ((argc = ast_app_separate_args(parse, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
switch (argc) {
case 4:
context = argv[3];
else if (!strcasecmp(options, "noanswer"))
flags.flags = BACKGROUND_NOANSWER;
else
- ast_parseoptions(background_opts, &flags, NULL, options);
+ ast_app_parse_options(background_opts, &flags, NULL, options);
}
/* Answer if need be */
}
mydata = ast_strdupa(data);
- argc = ast_separate_app_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
+ argc = ast_app_separate_args(mydata, '|', argv, sizeof(argv) / sizeof(argv[0]));
/* check for a trailing flags argument */
if ((argc > 1) && !strchr(argv[argc-1], '=')) {