r->parse_config = afh_recv_parse_config;
r->free_config = afh_recv_free_config;
r->execute = afh_execute;
- r->help = (struct ggo_help) {
- .short_help = afh_recv_args_info_help,
- .detailed_help = afh_recv_args_info_detailed_help
- };
+ r->help = (struct ggo_help)DEFINE_GGO_HELP(afh_recv);
afh_recv_cmdline_parser_free(&dummy);
}
w->post_select = alsa_write_post_select;
w->parse_config_or_die = alsa_parse_config_or_die;
w->free_config = alsa_free_config;
- w->help = (struct ggo_help) {
- .short_help = alsa_write_args_info_help,
- .detailed_help = alsa_write_args_info_detailed_help
- };
+ w->help = (struct ggo_help)DEFINE_GGO_HELP(alsa_write);
alsa_write_cmdline_parser_free(&dummy);
}
f->post_select = amp_post_select;
f->parse_config = amp_parse_config;
f->free_config = amp_free_config;
- f->help = (struct ggo_help) {
- .short_help = amp_filter_args_info_help,
- .detailed_help = amp_filter_args_info_detailed_help
- };
+ f->help = (struct ggo_help)DEFINE_GGO_HELP(amp_filter);
}
w->post_select = aow_post_select;
w->parse_config_or_die = aow_parse_config_or_die;
w->free_config = aow_free_config;
- w->help = (struct ggo_help) {
- .short_help = ao_write_args_info_help,
- };
+ w->help = (struct ggo_help)DEFINE_GGO_HELP(ao_write);
/* create detailed help containing all supported drivers/options */
for (i = 0; ao_write_args_info_detailed_help[i]; i++)
; /* nothing */
__noreturn static void print_help_and_die(void)
{
- int d = conf.detailed_help_given;
- const char **p = d? audiod_args_info_detailed_help
- : audiod_args_info_help;
-
- printf_or_die("%s\n\n", version_single_line("audiod"));
- printf_or_die("%s\n\n", audiod_args_info_usage);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
- print_receiver_helps(d);
- print_filter_helps(d);
- print_writer_helps(d);
+ struct ggo_help h = DEFINE_GGO_HELP(audiod);
+ bool d = conf.detailed_help_given;
+ unsigned flags;
+
+ flags = d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS;
+ ggo_print_help(&h, flags);
+
+ flags = d? GPH_MODULE_FLAGS_DETAILED : GPH_MODULE_FLAGS;
+ print_receiver_helps(flags);
+ print_filter_helps(flags);
+ print_writer_helps(flags);
exit(0);
}
f->post_select = compress_post_select;
f->parse_config = compress_parse_config;
f->free_config = compress_free_config;
- f->help = (struct ggo_help) {
- .short_help = compress_filter_args_info_help,
- .detailed_help = compress_filter_args_info_detailed_help
- };
+ f->help = (struct ggo_help)DEFINE_GGO_HELP(compress_filter);
}
afh_cmdline_objs="add_cmdline(afh)"
afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common
- version"
+ version ggo"
afh_ldflags=""
write_cmdline_objs="add_cmdline(write file_write)"
r->post_select = dccp_recv_post_select;
r->parse_config = dccp_recv_parse_config;
r->free_config = dccp_recv_free_config;
- r->help = (struct ggo_help) {
- .short_help = dccp_recv_args_info_help,
- .detailed_help = dccp_recv_args_info_detailed_help
- };
+ r->help = (struct ggo_help)DEFINE_GGO_HELP(dccp_recv);
dccp_recv_cmdline_parser_free(&dummy);
}
w->parse_config_or_die = file_write_parse_config_or_die;
w->free_config = file_write_free_config;
w->close = file_write_close;
- w->help = (struct ggo_help) {
- .short_help = file_write_args_info_help,
- .detailed_help = file_write_args_info_detailed_help
- };
+ w->help = (struct ggo_help)DEFINE_GGO_HELP(file_write);
file_write_cmdline_parser_free(&dummy);
}
__noreturn static void print_help_and_die(void)
{
- int d = conf.detailed_help_given;
- const char **p = d? filter_args_info_detailed_help
- : filter_args_info_help;
-
- printf_or_die("%s\n\n", version_single_line("filter"));
- printf_or_die("%s\n\n", filter_args_info_usage);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
- print_filter_helps(d);
+ struct ggo_help h = DEFINE_GGO_HELP(filter);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ print_filter_helps(d? GPH_MODULE_FLAGS_DETAILED : GPH_MODULE_FLAGS);
exit(0);
}
void filter_init(void);
int check_filter_arg(char *filter_arg, void **conf);
-void print_filter_helps(int detailed);
+void print_filter_helps(unsigned flags);
void generic_filter_pre_select(struct sched *s, struct task *t);
int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels,
char **result);
/**
* Print help text of each filter to stdout.
*
- * \param detailed If non-zero, print detailed help.
+ * \param flags Passed to \ref ggo_print_help().
*/
-void print_filter_helps(int detailed)
+void print_filter_helps(unsigned flags)
{
int i, num = 0;
if (!f->help.short_help)
continue;
- printf_or_die("Options for %s:\n", f->name);
- ggo_print_help(&f->help, detailed);
+ printf_or_die("\nOptions for %s:", f->name);
+ ggo_print_help(&f->help, flags);
}
}
#include "para.h"
#include "ggo.h"
+#include "version.h"
/**
* Wrapper for printf() that exits on errors.
* Print one of the two given help texts.
*
* \param help contains the help texts.
- * \param detailed_help Whether to print the detailed help text.
+ * \param flags What to print, see \ref ggo_print_help_flags.
*/
-void ggo_print_help(struct ggo_help *help, int detailed_help)
+void ggo_print_help(struct ggo_help *help, unsigned flags)
{
const char **p;
- if (!help)
- return;
- if (detailed_help)
+ if (flags & GPH_PRINT_NAME_VERSION)
+ printf_or_die("%s\n", version_single_line(help->prefix));
+ if (help->usage && (flags & GPH_PRINT_USAGE))
+ printf_or_die("\n%s\n", help->usage);
+ if (help->description && (flags & GPH_PRINT_DESCRIPTION))
+ printf_or_die("\n%s\n", help->description);
+ printf_or_die("\n");
+ if (flags & GPH_DETAILED)
p = help->detailed_help;
else
p = help->short_help;
if (!p)
return;
for (; *p; p++)
- printf_or_die("\t%s\n", *p);
+ printf_or_die("%s\n", *p);
}
/** \file ggo.h Functions and structures for help text handling. */
/**
- * Used by executables that can not use gengetopt's generated help function.
+ * Information extracted from the .cmdline.h header files.
*/
struct ggo_help {
- /** The lines of the short help text. */
+ /** Program or module (receiver, filter, writer) name. */
+ const char *prefix;
+ /** Generated by gengetopt from the options in the .ggo file. */
const char **short_help;
- /** The lines of the detailed help text. */
+ /** Like \a short_help, plus the \a details section. */
const char **detailed_help;
+ /** Generated by gengetopt and exported via the *.cmdline.h file. */
+ const char *usage;
+ /** The description text given in the .ggo file. */
+ const char *description;
};
-void ggo_print_help(struct ggo_help *help, int detailed_help);
+/**
+ * Control the output of \ref ggo_print_help().
+ *
+ * Any combination of these flags may be passed to ggo_print_help().
+ * Note that the list of supported options is always printed.
+ */
+enum ggo_print_help_flags {
+ /** Whether to print the short help or the detailed help. */
+ GPH_DETAILED = 1 << 0,
+ /** Print the program or module name, git version and codename. */
+ GPH_PRINT_NAME_VERSION = 1 << 1,
+ /** Print the synopsis. */
+ GPH_PRINT_USAGE = 1 << 2,
+ /** Print the description text. */
+ GPH_PRINT_DESCRIPTION = 1 << 3,
+};
+
+/** Used to print the normal help of programs (--help) */
+#define GPH_STANDARD_FLAGS \
+ (GPH_PRINT_NAME_VERSION | GPH_PRINT_USAGE)
+
+/** Additional information for --detailed-help. */
+#define GPH_STANDARD_FLAGS_DETAILED \
+ (GPH_STANDARD_FLAGS | GPH_DETAILED | GPH_PRINT_DESCRIPTION)
+
+/** For module help embedded in a program help. */
+#define GPH_MODULE_FLAGS 0
+
+/** Modules help with detailed descriptions. */
+#define GPH_MODULE_FLAGS_DETAILED GPH_DETAILED | GPH_PRINT_DESCRIPTION
+
+/** Make a ggo_help structure using information from the .cmdline.h file. */
+#define DEFINE_GGO_HELP(_prefix) \
+ { \
+ .prefix = #_prefix, \
+ .short_help = _prefix ## _args_info_help, \
+ .detailed_help = _prefix ## _args_info_detailed_help, \
+ .usage = _prefix ## _args_info_usage, \
+ .description = _prefix ## _args_info_description, \
+ }
+
+void ggo_print_help(struct ggo_help *help, unsigned flags);
__printf_1_2 int printf_or_die(const char *fmt, ...);
r->post_select = http_recv_post_select;
r->parse_config = http_recv_parse_config;
r->free_config = http_recv_free_config;
- r->help = (struct ggo_help) {
- .short_help = http_recv_args_info_help,
- .detailed_help = http_recv_args_info_detailed_help
- };
+ r->help = (struct ggo_help)DEFINE_GGO_HELP(http_recv);
http_recv_cmdline_parser_free(&dummy);
}
f->pre_select = generic_filter_pre_select;
f->post_select = mp3dec_post_select;
f->execute = mp3dec_execute;
- f->help = (struct ggo_help) {
- .short_help = mp3dec_filter_args_info_help,
- .detailed_help = mp3dec_filter_args_info_detailed_help
- };
+ f->help = (struct ggo_help)DEFINE_GGO_HELP(mp3dec_filter);
}
w->post_select = oss_post_select;
w->parse_config_or_die = oss_parse_config_or_die;
w->free_config = oss_free_config;
- w->help = (struct ggo_help) {
- .short_help = oss_write_args_info_help,
- .detailed_help = oss_write_args_info_detailed_help
- };
+ w->help = (struct ggo_help)DEFINE_GGO_HELP(oss_write);
oss_write_cmdline_parser_free(&dummy);
}
w->post_select = osx_write_post_select;
w->parse_config_or_die = osx_write_parse_config_or_die;
w->free_config = osx_free_config;
- w->help = (struct ggo_help) {
- .short_help = osx_write_args_info_help,
- .detailed_help = osx_write_args_info_detailed_help
- };
+ w->help = (struct ggo_help)DEFINE_GGO_HELP(osx_write);
osx_write_cmdline_parser_free(&dummy);
}
__noreturn static void print_help_and_die(void)
{
- int d = conf.detailed_help_given;
- const char **p = d? play_args_info_detailed_help
- : play_args_info_help;
-
- printf_or_die("%s\n\n", version_single_line("play"));
- printf_or_die("%s\n\n", play_args_info_usage);
- if (d)
- printf_or_die("%s\n", play_args_info_description);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
+ struct ggo_help help = DEFINE_GGO_HELP(play);
+ unsigned flags = conf.detailed_help_given?
+ GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS;
+
+ ggo_print_help(&help, flags);
exit(0);
}
f->free_config = prebuffer_free_config;
f->pre_select = prebuffer_pre_select;
f->post_select = prebuffer_post_select;
- f->help = (struct ggo_help) {
- .short_help = prebuffer_filter_args_info_help,
- .detailed_help = prebuffer_filter_args_info_detailed_help
- };
+ f->help = (struct ggo_help)DEFINE_GGO_HELP(prebuffer_filter);
}
__noreturn static void print_help_and_die(void)
{
- int d = conf.detailed_help_given;
- const char **p = d? recv_args_info_detailed_help
- : recv_args_info_help;
-
- printf_or_die("%s\n\n", version_single_line("recv"));
- printf_or_die("%s\n\n", recv_args_info_usage);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
- print_receiver_helps(d);
+ struct ggo_help h = DEFINE_GGO_HELP(recv);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ print_receiver_helps(d? GPH_MODULE_FLAGS_DETAILED : GPH_MODULE_FLAGS);
exit(0);
}
void recv_init(void);
void *check_receiver_arg(char *ra, int *receiver_num);
-void print_receiver_helps(int detailed);
+void print_receiver_helps(unsigned flags);
int generic_recv_pre_select(struct sched *s, struct task *t);
/** \cond receiver */
/**
* Print out the help texts to all receivers.
*
- * \param detailed Whether the detailed help should be printed.
+ * \param flags Passed to \ref ggo_print_help().
*/
-void print_receiver_helps(int detailed)
+void print_receiver_helps(unsigned flags)
{
int i;
- printf_or_die("\nAvailable receivers: \n\t");
+ printf_or_die("\nAvailable receivers: ");
FOR_EACH_RECEIVER(i)
printf_or_die("%s%s", i? " " : "", receivers[i].name);
- printf_or_die("\n\n");
+ printf_or_die("\n");
FOR_EACH_RECEIVER(i) {
struct receiver *r = receivers + i;
if (!r->help.short_help)
continue;
- printf_or_die("Options for %s:\n", r->name);
- ggo_print_help(&r->help, detailed);
+ printf_or_die("\nOptions for %s:", r->name);
+ ggo_print_help(&r->help, flags);
}
}
f->parse_config = resample_parse_config;
f->free_config = resample_free_config;
f->execute = resample_execute;
- f->help = (struct ggo_help) {
- .short_help = resample_filter_args_info_help,
- .detailed_help = resample_filter_args_info_detailed_help
- };
+ f->help = (struct ggo_help)DEFINE_GGO_HELP(resample_filter);
}
r->post_select = udp_recv_post_select;
r->parse_config = udp_recv_parse_config;
r->free_config = udp_recv_free_config;
- r->help = (struct ggo_help) {
- .short_help = udp_recv_args_info_help,
- .detailed_help = udp_recv_args_info_detailed_help
- };
+ r->help = (struct ggo_help)DEFINE_GGO_HELP(udp_recv);
udp_recv_cmdline_parser_free(&dummy);
}
__noreturn static void print_help_and_die(void)
{
- int d = conf.detailed_help_given;
- const char **p = d? write_args_info_detailed_help
- : write_args_info_help;
-
- printf_or_die("%s\n\n", version_single_line("write"));
- printf_or_die("%s\n\n", write_args_info_usage);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
- print_writer_helps(d);
+ struct ggo_help h = DEFINE_GGO_HELP(write);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ print_writer_helps(d? GPH_MODULE_FLAGS_DETAILED : GPH_MODULE_FLAGS);
exit(0);
}
/**
* Print the help text of all writers to stdout.
*
- * \param detailed Whether to print the detailed help text.
+ * \param flags Passed to \ref ggo_print_help().
*/
-void print_writer_helps(int detailed)
+void print_writer_helps(unsigned flags)
{
int i;
- printf_or_die("\nAvailable writers: \n\t");
+ printf_or_die("\nAvailable writers: ");
FOR_EACH_WRITER(i)
printf_or_die("%s%s", i? " " : "", writer_names[i]);
- printf_or_die("\n\n");
+ printf_or_die("\n");
FOR_EACH_WRITER(i) {
struct writer *w = writers + i;
if (!w->help.short_help)
continue;
- printf_or_die("Options for %s:\n", writer_names[i]);
- ggo_print_help(&w->help, detailed);
+ printf_or_die("\nOptions for %s:", writer_names[i]);
+ ggo_print_help(&w->help, flags);
}
}
void writer_init(void);
void *check_writer_arg_or_die(const char *wa, int *writer_num);
-void print_writer_helps(int detailed);
+void print_writer_helps(unsigned flags);
void register_writer_node(struct writer_node *wn, struct btr_node *parent,
struct sched *s);
void get_btr_sample_rate(struct btr_node *btrn, int32_t *result);