summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_oss.c62
-rw-r--r--channels/chan_usbradio.c107
-rw-r--r--channels/console_video.c55
-rw-r--r--include/asterisk/config.h40
4 files changed, 109 insertions, 155 deletions
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 94c114f96..14e6cdcce 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -178,34 +178,6 @@ END_CONFIG
*/
/*
- * Helper macros to parse config arguments. They will go in a common
- * header file if their usage is globally accepted. In the meantime,
- * we define them here. Typical usage is as below.
- * Remember to open a block right before M_START (as it declares
- * some variables) and use the M_* macros WITHOUT A SEMICOLON:
- *
- * {
- * M_START(v->name, v->value)
- *
- * M_BOOL("dothis", x->flag1)
- * M_STR("name", x->somestring)
- * M_F("bar", some_c_code)
- * M_END(some_final_statement)
- * ... other code in the block
- * }
- *
- * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
- * Likely we will come up with a better way of doing config file parsing.
- */
-#define M_START(var, val) \
- const char *__s = var; const char *__val = val;
-#define M_END(x) x;
-#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
-#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
-#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
-#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
-
-/*
* The following parameters are used in the driver:
*
* FRAME_SIZE the size of an audio frame, in samples.
@@ -1559,7 +1531,7 @@ static void store_callerid(struct chan_oss_pvt *o, const char *s)
static void store_config_core(struct chan_oss_pvt *o, const char *var, const char *value)
{
- M_START(var, value);
+ CV_START(var, value);
/* handle jb conf */
if (!ast_jb_read_conf(&global_jbconf, (char *)var,(char *) value))
@@ -1567,22 +1539,22 @@ static void store_config_core(struct chan_oss_pvt *o, const char *var, const cha
if (!console_video_config(&o->env, var, value))
return;
- M_BOOL("autoanswer", o->autoanswer)
- M_BOOL("autohangup", o->autohangup)
- M_BOOL("overridecontext", o->overridecontext)
- M_STR("device", o->device)
- M_UINT("frags", o->frags)
- M_UINT("debug", oss_debug)
- M_UINT("queuesize", o->queuesize)
- M_STR("context", o->ctx)
- M_STR("language", o->language)
- M_STR("mohinterpret", o->mohinterpret)
- M_STR("extension", o->ext)
- M_F("mixer", store_mixer(o, value))
- M_F("callerid", store_callerid(o, value))
- M_F("boost", store_boost(o, value))
-
- M_END(/* */);
+ CV_BOOL("autoanswer", o->autoanswer);
+ CV_BOOL("autohangup", o->autohangup);
+ CV_BOOL("overridecontext", o->overridecontext);
+ CV_STR("device", o->device);
+ CV_UINT("frags", o->frags);
+ CV_UINT("debug", oss_debug);
+ CV_UINT("queuesize", o->queuesize);
+ CV_STR("context", o->ctx);
+ CV_STR("language", o->language);
+ CV_STR("mohinterpret", o->mohinterpret);
+ CV_STR("extension", o->ext);
+ CV_F("mixer", store_mixer(o, value));
+ CV_F("callerid", store_callerid(o, value)) ;
+ CV_F("boost", store_boost(o, value));
+
+ CV_END;
}
/*!
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index 8a1d7517e..55a6600c6 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -202,34 +202,6 @@ END_CONFIG
*/
-/*! \brief
- * Helper macros to parse config arguments. They will go in a common
- * header file if their usage is globally accepted. In the meantime,
- * we define them here. Typical usage is as below.
- * Remember to open a block right before M_START (as it declares
- * some variables) and use the M_* macros WITHOUT A SEMICOLON:
- *
- * {
- * M_START(v->name, v->value)
- *
- * M_BOOL("dothis", x->flag1)
- * M_STR("name", x->somestring)
- * M_F("bar", some_c_code)
- * M_END(some_final_statement)
- * ... other code in the block
- * }
- *
- * XXX NOTE these macros should NOT be replicated in other parts of asterisk.
- * Likely we will come up with a better way of doing config file parsing.
- */
-#define M_START(var, val) \
- const char *__s = var; const char *__val = val;
-#define M_END(x) x;
-#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
-#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
-#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
-#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
-
/*!
* The following parameters are used in the driver:
*
@@ -2414,45 +2386,35 @@ static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
o->spkrmax = amixer_max(o->devicenum, MIXER_PARAM_SPKR_PLAYBACK_VOL);
/* fill other fields from configuration */
for (v = ast_variable_browse(cfg, ctg); v; v = v->next) {
- M_START(v->name, v->value);
/* handle jb conf */
if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
continue;
-
-#if 0
- M_BOOL("autoanswer", o->autoanswer)
- M_BOOL("autohangup", o->autohangup)
- M_BOOL("overridecontext", o->overridecontext)
- M_STR("context", o->ctx)
- M_STR("language", o->language)
- M_STR("mohinterpret", o->mohinterpret)
- M_STR("extension", o->ext)
- M_F("callerid", store_callerid(o, v->value))
-#endif
- M_UINT("frags", o->frags)
- M_UINT("queuesize", o->queuesize)
- M_UINT("devicenum", o->devicenum)
- M_UINT("debug", usbradio_debug)
- M_BOOL("rxcpusaver", o->rxcpusaver)
- M_BOOL("txcpusaver", o->txcpusaver)
- M_BOOL("invertptt", o->invertptt)
- M_F("rxdemod", store_rxdemod(o, v->value))
- M_BOOL("txprelim", o->txprelim);
- M_F("txmixa", store_txmixa(o, v->value))
- M_F("txmixb", store_txmixb(o, v->value))
- M_F("carrierfrom", store_rxcdtype(o, v->value))
- M_F("rxsdtype", store_rxsdtype(o, v->value))
- M_F("rxctcssfreq", store_rxctcssfreq(o, v->value))
- M_F("txctcssfreq", store_txctcssfreq(o, v->value))
- M_F("rxgain", store_rxgain(o, v->value))
- M_BOOL("rxboostset", o->rxboostset)
- M_UINT("rxctcssrelax", o->rxctcssrelax)
- M_F("txtoctype", store_txtoctype(o, v->value))
- M_UINT("hdwtype", o->hdwtype)
- M_UINT("duplex", o->radioduplex)
- M_END(;
- );
+ CV_START(v->name, v->value);
+
+ CV_UINT("frags", o->frags);
+ CV_UINT("queuesize", o->queuesize);
+ CV_UINT("devicenum", o->devicenum);
+ CV_UINT("debug", usbradio_debug);
+ CV_BOOL("rxcpusaver", o->rxcpusaver);
+ CV_BOOL("txcpusaver", o->txcpusaver);
+ CV_BOOL("invertptt", o->invertptt);
+ CV_F("rxdemod", store_rxdemod(o, v->value));
+ CV_BOOL("txprelim", o->txprelim);;
+ CV_F("txmixa", store_txmixa(o, v->value));
+ CV_F("txmixb", store_txmixb(o, v->value));
+ CV_F("carrierfrom", store_rxcdtype(o, v->value));
+ CV_F("rxsdtype", store_rxsdtype(o, v->value));
+ CV_F("rxctcssfreq", store_rxctcssfreq(o, v->value));
+ CV_F("txctcssfreq", store_txctcssfreq(o, v->value));
+ CV_F("rxgain", store_rxgain(o, v->value));
+ CV_BOOL("rxboostset", o->rxboostset);
+ CV_UINT("rxctcssrelax", o->rxctcssrelax);
+ CV_F("txtoctype", store_txtoctype(o, v->value));
+ CV_UINT("hdwtype", o->hdwtype);
+ CV_UINT("duplex", o->radioduplex);
+
+ CV_END;
}
cfg1 = ast_config_load(config1, config_flags);
@@ -2468,16 +2430,15 @@ static struct chan_usbradio_pvt *store_config(struct ast_config *cfg, char *ctg)
} else {
for (v = ast_variable_browse(cfg1, ctg); v; v = v->next) {
- M_START(v->name, v->value);
- M_UINT("rxmixerset", o->rxmixerset)
- M_UINT("txmixaset", o->txmixaset)
- M_UINT("txmixbset", o->txmixbset)
- M_F("rxvoiceadj", store_rxvoiceadj(o, v->value))
- M_F("rxctcssadj", store_rxctcssadj(o, v->value))
- M_UINT("txctcssadj", o->txctcssadj);
- M_UINT("rxsquelchadj", o->rxsquelchadj)
- M_END(;
- );
+ CV_START(v->name, v->value);
+ CV_UINT("rxmixerset", o->rxmixerset);
+ CV_UINT("txmixaset", o->txmixaset);
+ CV_UINT("txmixbset", o->txmixbset);
+ CV_F("rxvoiceadj", store_rxvoiceadj(o, v->value));
+ CV_F("rxctcssadj", store_rxctcssadj(o, v->value));
+ CV_UINT("txctcssadj", o->txctcssadj);
+ CV_UINT("rxsquelchadj", o->rxsquelchadj);
+ CV_END;
}
ast_config_destroy(cfg1);
}
diff --git a/channels/console_video.c b/channels/console_video.c
index b7a828e90..d59d3bb77 100644
--- a/channels/console_video.c
+++ b/channels/console_video.c
@@ -2987,18 +2987,6 @@ no_sdl:
cleanup_sdl(env);
}
-/* see chan_oss.c for these macros */
-#ifndef M_START
-#define _UNDO_M_START
-#define M_START(var, val) \
- const char *__s = var; const char *__val = val;
-#define M_END(x) x;
-#define M_F(tag, f) if (!strcasecmp((__s), tag)) { f; } else
-#define M_BOOL(tag, dst) M_F(tag, (dst) = ast_true(__val) )
-#define M_UINT(tag, dst) M_F(tag, (dst) = strtoul(__val, NULL, 0) )
-#define M_STR(tag, dst) M_F(tag, ast_copy_string(dst, __val, sizeof(dst)))
-#endif
-
/*
* Parse a geometry string, accepting also common names for the formats.
* Trick: if we have a leading > or < and a numeric geometry,
@@ -3245,7 +3233,6 @@ static int console_video_config(struct video_desc **penv,
const char *var, const char *val)
{
struct video_desc *env;
- M_START(var, val);
if (penv == NULL) {
ast_log(LOG_WARNING, "bad argument penv=NULL\n");
@@ -3267,31 +3254,25 @@ static int console_video_config(struct video_desc **penv,
env->out.sendvideo = 1;
env->out.qmin = 3;
}
- M_STR("videodevice", env->out.videodevice)
- M_BOOL("sendvideo", env->out.sendvideo)
- M_F("video_size", video_geom(&env->out.enc_in, val))
- M_F("camera_size", video_geom(&env->out.loc_src, val))
- M_F("local_size", video_geom(&env->out.loc_dpy, val))
- M_F("remote_size", video_geom(&env->in.rem_dpy, val))
- M_STR("keypad", env->keypad_file)
- M_F("keypad_entry", keypad_cfg_read(&env->gui, val))
- M_STR("keypad_mask", env->keypad_mask)
- M_STR("keypad_font", env->keypad_font)
- M_UINT("fps", env->out.fps)
- M_UINT("bitrate", env->out.bitrate)
- M_UINT("qmin", env->out.qmin)
- M_STR("videocodec", env->codec_name)
- M_END(return 1;) /* the 'nothing found' case */
+ CV_START(var, val);
+ CV_STR("videodevice", env->out.videodevice);
+ CV_BOOL("sendvideo", env->out.sendvideo);
+ CV_F("video_size", video_geom(&env->out.enc_in, val));
+ CV_F("camera_size", video_geom(&env->out.loc_src, val));
+ CV_F("local_size", video_geom(&env->out.loc_dpy, val));
+ CV_F("remote_size", video_geom(&env->in.rem_dpy, val));
+ CV_STR("keypad", env->keypad_file);
+ CV_F("keypad_entry", keypad_cfg_read(&env->gui, val));
+ CV_STR("keypad_mask", env->keypad_mask);
+ CV_STR("keypad_font", env->keypad_font);
+ CV_UINT("fps", env->out.fps);
+ CV_UINT("bitrate", env->out.bitrate);
+ CV_UINT("qmin", env->out.qmin);
+ CV_STR("videocodec", env->codec_name);
+ return 1; /* nothing found */
+
+ CV_END; /* the 'nothing found' case */
return 0; /* found something */
}
-#ifdef _UNDO_M_START
-#undef M_START
-#undef M_END
-#undef M_F
-#undef M_BOOL
-#undef M_UINT
-#undef M_STR
-#undef _UNDO_M_START
-#endif
#endif /* video support */
diff --git a/include/asterisk/config.h b/include/asterisk/config.h
index ebc71fb8a..7a2d10135 100644
--- a/include/asterisk/config.h
+++ b/include/asterisk/config.h
@@ -271,6 +271,7 @@ int ast_variable_update(struct ast_category *category, const char *variable,
int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file);
+
/*! \brief Support code to parse config file arguments
*
* The function ast_parse_arg() provides a generic interface to parse
@@ -358,6 +359,45 @@ enum ast_parse_flags {
int ast_parse_arg(const char *arg, enum ast_parse_flags flags,
void *result, ...);
+/*
+ * Parsing config file options in C is slightly annoying because we cannot use
+ * string in a switch() statement, yet we need a similar behaviour, with many
+ * branches and a break on a matching one.
+ * The following somehow simplifies the job: we create a block using
+ * the CV_START and CV_END macros, and then within the block we can run
+ * actions such as "if (condition) { body; break; }"
+ * Additional macros are present to run simple functions (e.g. ast_copy_string)
+ * or to pass arguments to ast_parse_arg()
+ *
+ * As an example:
+
+ CV_START(v->name, v->value); // start the block
+ CV_STR("foo", x_foo); // static string
+ CV_DSTR("bar", y_bar); // malloc'ed string
+ CV_F("bar", ...); // call a generic function
+ CV_END; // end the block
+ */
+
+/*! \brief the macro to open a block for variable parsing */
+#define CV_START(__in_var, __in_val) \
+ do { \
+ const char *__var = __in_var; \
+ const char *__val = __in_val;
+
+/*! \brief close a variable parsing block */
+#define CV_END } while (0)
+
+/*! \brief call a generic function if the name matches. */
+#define CV_F(__pattern, __body) if (!strcasecmp((__var), __pattern)) { __body; break; }
+
+/*! \brief helper macros to assign the value to a BOOL, UINT, static string and
+ * dynamic string
+ */
+#define CV_BOOL(__x, __dst) CV_F(__x, (__dst) = ast_true(__val) )
+#define CV_UINT(__x, __dst) CV_F(__x, (__dst) = strtoul(__val, NULL, 0) )
+#define CV_STR(__x, __dst) CV_F(__x, ast_copy_string(__dst, __val, sizeof(__dst)))
+#define CV_DSTR(__x, __dst) CV_F(__x, if (__dst) ast_free(__dst); __dst = ast_strdup(__val))
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif