Cooking for ~2 weeks.
15e99a version.c: Mark version_git() as const.
9bdebf Remove CODENAME macro.
be2f6b gui: Use version_single_line().
d60dae Improve man page layout.
5dbc9a afh/play: Include supported audio formats in help output.
042767 Use self-made help to avoid recompilations on version changes.
48f1fc Provide "purpose" texts.
aa74a9 Revamp ggo help.
9f7a49 afh_recv: Replace ggo text section by description.
b59e0e Make gengetopt descriptions work.
06b3e7 Introduce version.c to limit recompilation on version changes.
75feac Make all commands print git version and improve version string.
b01605 Avoid unwanted log messages during startup.
625fdb Don't check return value of command line parsers unnecessarily.
533b03 Build receivers, filters and writers without -h and -V support.
b59a3c filter: Wrap lines in the available filter list.
9e56d3 audioc: Print config file errors.
e5264d doc: Rewrite udp sender description
5ec373 client: Fix typo in comment.
6d5159 client: Remove duplicate include.
PACKAGE_STRING := @PACKAGE_STRING@
install_sh := @install_sh@
executables := @executables@
+ggo_descriptions_declared := @ggo_descriptions_declared@
GENGETOPT := @gengetopt@
HELP2MAN := @help2man@
uname_s := $(shell uname -s 2>/dev/null || echo "UNKNOWN_OS")
uname_rs := $(shell uname -rs)
cc_version := $(shell $(CC) --version | head -n 1)
-codename := spectral gravity
GIT_VERSION := $(shell ./GIT-VERSION-GEN git-version.h)
CPPFLAGS += -DBINDIR='"$(BINDIR)"'
CPPFLAGS += -DBUILD_DATE='"$(build_date)"'
CPPFLAGS += -DUNAME_RS='"$(uname_rs)"'
-CPPFLAGS += -DCODENAME='"$(codename)"'
CPPFLAGS += -DCC_VERSION='"$(cc_version)"'
CPPFLAGS += -Werror-implicit-function-declaration
CPPFLAGS += -Wmissing-noreturn
- Speed and usability improvements for para_gui.
- para_client now restores the fd flags of stdin and stdout
on shutdown.
+ - Improved manual pages.
+ - Consistent version strings for all executables.
+ - Reduced depencies on generated files result in fewer
+ recompilations on changes.
- Performance improvements for the compress filter.
- Improved downloads web page.
#include "afh.h"
#include "error.h"
#include "version.h"
+#include "ggo.h"
static struct afh_args_info conf;
INIT_AFH_ERRLISTS;
}
}
+__noreturn static void print_help_and_die(void)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(afh);
+ int d = conf.detailed_help_given;
+ unsigned flags = d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS;
+
+ ggo_print_help(&h, flags);
+ printf("supported audio formats: %s\n", AUDIO_FORMAT_HANDLERS);
+ exit(EXIT_SUCCESS);
+}
+
/**
* The main function of para_afh.
*
struct afh_info afhi;
afh_cmdline_parser(argc, argv, &conf);
- HANDLE_VERSION_FLAG("afh", conf);
loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("afh", conf.version_given);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
+ afh_init();
ret = -E_AFH_SYNTAX;
if (conf.inputs_num == 0)
goto out;
{
struct afh_recv_args_info *tmp = para_calloc(sizeof(*tmp));
- if (!afh_recv_cmdline_parser(argc, argv, tmp))
- return tmp;
- free(tmp);
- return NULL;
+ afh_recv_cmdline_parser(argc, argv, tmp);
+ return tmp;
}
static void afh_recv_free_config(void *conf)
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 */
#include "net.h"
#include "string.h"
#include "fd.h"
+#include "ggo.h"
#include "version.h"
INIT_AUDIOC_ERRLISTS;
.loglevel = loglevel,
.completers = audiod_completers,
};
- PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("audioc"));
+ PARA_NOTICE_LOG("\n%s\n", version_text("audioc"));
if (conf.history_file_given)
history_file = para_strdup(conf.history_file_arg);
else {
return NULL;
}
+__noreturn static void print_help_and_die(void)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(audioc);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ exit(0);
+}
+
/**
* The client program to connect to para_audiod.
*
*/
int main(int argc, char *argv[])
{
- int ret = -E_AUDIOC_SYNTAX, fd;
+ int ret, fd;
char *cf, *buf = NULL, *args = NULL;
size_t bufsize;
- if (audioc_cmdline_parser(argc, argv, &conf))
- goto out;
- HANDLE_VERSION_FLAG("audioc", conf);
+ audioc_cmdline_parser(argc, argv, &conf);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("audioc", conf.version_given);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
cf = configfile_exists();
if (cf) {
struct audioc_cmdline_parser_params params = {
.override = 0,
.initialize = 0,
.check_required = 0,
- .check_ambiguity = 0
+ .check_ambiguity = 0,
+ .print_errors = 1,
+
};
- ret = audioc_cmdline_parser_config_file(cf, &conf, ¶ms);
+ audioc_cmdline_parser_config_file(cf, &conf, ¶ms);
free(cf);
- if (ret) {
- fprintf(stderr, "parse error in config file\n");
- exit(EXIT_FAILURE);
- }
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
if (conf.socket_given)
socket_name = para_strdup(conf.socket_arg);
else {
PARA_EMERG_LOG("can not read config file %s\n", config_file);
goto err;
}
- if (ret)
+ if (ret) {
audiod_cmdline_parser_config_file(config_file, &conf, ¶ms);
+ daemon_set_loglevel(conf.loglevel_arg);
+ }
free(config_file);
- daemon_set_loglevel(conf.loglevel_arg);
return;
err:
free(config_file);
__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", AUDIOD_CMDLINE_PARSER_PACKAGE "-"
- AUDIOD_CMDLINE_PARSER_VERSION);
- 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);
}
};
valid_fd_012();
- if (audiod_cmdline_parser_ext(argc, argv, &conf, ¶ms))
- exit(EXIT_FAILURE);
- HANDLE_VERSION_FLAG("audiod", conf);
+ audiod_cmdline_parser_ext(argc, argv, &conf, ¶ms);
+ daemon_set_loglevel(conf.loglevel_arg);
+ version_handle_flag("audiod", conf.version_given);
/* init receivers/filters/writers early to make help work */
recv_init();
filter_init();
.completers = completers,
};
- PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("client"));
+ PARA_NOTICE_LOG("\n%s\n", version_text("client"));
if (ct->conf.history_file_given)
history_file = para_strdup(ct->conf.history_file_arg);
else {
#include "error.h"
#include "list.h"
#include "sched.h"
-#include "client.cmdline.h"
#include "crypt.h"
#include "net.h"
#include "fd.h"
#include "client.h"
#include "buffer_tree.h"
#include "version.h"
+#include "ggo.h"
/** The size of the receiving buffer. */
#define CLIENT_BUFSIZE 4000
/**
- * Close the connection to para_server and deallocate per-command ressources.
+ * Close the connection to para_server and deallocate per-command resources.
*
* \param ct The client task.
*
- * This frees all ressources of the current command but keeps the configuration
+ * This frees all resources of the current command but keeps the configuration
* in \p ct->conf.
*
* \sa \ref client_close().
return ret;
}
+__noreturn static void print_help_and_die(struct client_task *ct)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(client);
+ bool d = ct->conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ exit(0);
+}
+
/**
* Parse a client configuration.
*
ret = -E_CLIENT_SYNTAX;
if (client_cmdline_parser(argc, argv, &ct->conf))
goto out;
- HANDLE_VERSION_FLAG("client", ct->conf);
+ version_handle_flag("client", ct->conf.version_given);
+ if (ct->conf.help_given || ct->conf.detailed_help_given)
+ print_help_and_die(ct);
ct->config_file = ct->conf.config_file_given?
para_strdup(ct->conf.config_file_arg) :
free(info);
}
ut = get_server_uptime_str(now);
- ret = xasprintf(&msg, "version: " GIT_VERSION "\n"
+ ret = xasprintf(&msg,
+ "version: %s\n"
"up: %s\nplayed: %u\n"
"server_pid: %d\n"
"afs_pid: %d\n"
"current loglevel: %s\n"
"supported audio formats: %s\n"
"%s",
+ version_git(),
ut, mmd->num_played,
(int)getppid(),
(int)mmd->afs_pid,
if (cc->argc != 1)
return -E_COMMAND_SYNTAX;
- msg = VERSION_TEXT("server") "built: " BUILD_DATE "\n" UNAME_RS
- ", " CC_VERSION "\n";
- len = strlen(msg);
+ len = xasprintf(&msg, "%s", version_text("server"));
if (cc->use_sideband)
- return send_sb(&cc->scc, msg, len, SBD_OUTPUT, true);
+ return send_sb(&cc->scc, msg, len, SBD_OUTPUT, false);
return sc_send_bin_buffer(&cc->scc, msg, len);
}
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);
}
exec send_common ggo udp_recv color fec fecdec_filter
prebuffer_filter bitstream imdct check_wav
wma_afh wma_common wmadec_filter buffer_tree crypt_common
- gui gui_theme sideband afh_recv play"
+ gui gui_theme sideband afh_recv play version"
executables="recv filter audioc write client afh audiod play"
recv_errlist_objs="
http_recv recv_common recv time string net dccp_recv fd
sched stdout ggo udp_recv buffer_tree afh_recv afh_common
- wma_afh wma_common mp3_afh
+ wma_afh wma_common mp3_afh version
"
recv_ldflags=""
filter_cmdline_objs="add_cmdline(filter compress_filter amp_filter prebuffer_filter)"
filter_errlist_objs="filter_common wav_filter compress_filter filter string
- stdin stdout sched fd amp_filter ggo fecdec_filter fec
+ stdin stdout sched fd amp_filter ggo fecdec_filter fec version
prebuffer_filter time bitstream imdct wma_common wmadec_filter buffer_tree"
filter_ldflags="-lm"
filters=" compress wav amp fecdec wmadec prebuffer"
audioc_cmdline_objs="add_cmdline(audioc)"
-audioc_errlist_objs="audioc string net fd"
+audioc_errlist_objs="
+ audioc
+ string
+ net
+ fd
+ version
+ ggo
+"
audioc_ldflags=""
audiod_cmdline_objs="add_cmdline(audiod compress_filter http_recv dccp_recv file_write client amp_filter udp_recv prebuffer_filter)"
audiod_errlist_objs="audiod signal string daemon stat net crypt_common sideband
time grab_client filter_common wav_filter compress_filter amp_filter http_recv dccp_recv
recv_common fd sched write_common file_write audiod_command fecdec_filter
- client_common ggo udp_recv color fec prebuffer_filter
+ client_common ggo udp_recv color fec prebuffer_filter version
bitstream imdct wma_common wmadec_filter buffer_tree"
audiod_ldflags="-lm"
audiod_audio_formats="wma"
afh_cmdline_objs="add_cmdline(afh)"
-afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common"
+afh_errlist_objs="afh string fd mp3_afh afh_common time wma_afh wma_common
+ version ggo"
afh_ldflags=""
write_cmdline_objs="add_cmdline(write file_write)"
write_errlist_objs="write write_common file_write time fd string sched stdin
- buffer_tree ggo check_wav"
+ buffer_tree ggo check_wav version"
write_ldflags=""
writers=" file"
default_writer="FILE_WRITE"
client_cmdline_objs="add_cmdline(client)"
-client_errlist_objs="client net string fd sched stdin stdout time sideband
- client_common buffer_tree crypt_common"
+client_errlist_objs="
+ client
+ net
+ string
+ fd
+ sched
+ stdin
+ stdout
+ time
+ sideband
+ client_common
+ buffer_tree
+ crypt_common
+ version
+ ggo
+"
client_ldflags=""
gui_cmdline_objs="add_cmdline(gui)"
-gui_errlist_objs="exec signal string stat ringbuffer fd gui gui_theme time"
+gui_errlist_objs="
+ exec
+ signal
+ string
+ stat
+ ringbuffer
+ fd
+ gui
+ gui_theme
+ time
+ version
+ ggo
+"
gui_objs="$gui_cmdline_objs $gui_errlist_objs"
play_errlist_objs="play fd sched ggo buffer_tree time string net
afh_recv afh_common
wav_filter compress_filter amp_filter prebuffer_filter fecdec_filter
wmadec_filter
write_common file_write
+ version
"
play_cmdline_objs="add_cmdline(http_recv dccp_recv udp_recv afh_recv compress_filter amp_filter prebuffer_filter file_write play)"
play_ldflags="-lm"
extras="$extras server"
executables="$executables server"
server_cmdline_objs="add_cmdline(server)"
- server_errlist_objs="server afh_common mp3_afh vss command net
- string signal time daemon http_send close_on_fork mm
- crypt_common ipc dccp_send fd user_list chunk_queue
- afs aft mood score attribute blob playlist sched acl
- send_common udp_send color fec wma_afh wma_common sideband"
+ server_errlist_objs="
+ server
+ afh_common
+ mp3_afh
+ vss command
+ net
+ string
+ signal
+ time
+ daemon
+ http_send
+ close_on_fork
+ mm
+ crypt_common
+ ipc dccp_send
+ fd
+ user_list
+ chunk_queue
+ afs
+ aft
+ mood
+ score
+ attribute
+ blob
+ playlist
+ sched
+ acl
+ send_common
+ udp_send
+ color
+ fec
+ wma_afh
+ wma_common
+ sideband
+ version
+ ggo
+ "
all_errlist_objs="$all_errlist_objs server vss command
http_send close_on_fork mm ipc dccp_send user_list
chunk_queue afs aft mood score attribute blob playlist
if test ${have_ucred} = yes; then
AC_DEFINE(HAVE_UCRED, 1, define to 1 you have struct ucred)
fi
-
+########################################################################### gengetopt
+echo 'option "z" z "" flag off' | $gengetopt --file-name conftest-ggo &&
+AC_CHECK_DECL(
+ [gengetopt_args_info_description],
+ [ggo_descriptions_declared=yes],
+ [ggo_descriptions_declared=no],
+ [#include "conftest-ggo.h"]
+)
+AC_SUBST(ggo_descriptions_declared)
########################################################################### curses
have_curses="yes"
OLD_CPPFLAGS="$CPPFLAGS"
extras="$extras fade"
executables="$executables fade"
all_errlist_objs="$all_errlist_objs fade"
- fade_errlist_objs="$fade_errlist_objs fade exec string fd"
+ fade_errlist_objs="$fade_errlist_objs fade exec string fd version ggo"
fade_cmdline_objs="add_cmdline(fade)"
fade_objs="$fade_cmdline_objs $fade_errlist_objs"
AC_SUBST(fade_objs, add_dot_o($fade_objs))
{
struct dccp_recv_args_info *tmp = para_calloc(sizeof(*tmp));
- if (!dccp_recv_cmdline_parser(argc, argv, tmp) &&
- dccp_recv_ccid_support_check(tmp))
- return tmp;
- free(tmp);
- return NULL;
+ dccp_recv_cmdline_parser(argc, argv, tmp);
+ if (!dccp_recv_ccid_support_check(tmp))
+ exit(EXIT_FAILURE);
+ return tmp;
}
static void dccp_recv_pre_select(struct sched *s, struct task *t)
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);
}
#define STDIN_ERRORS
#define WRITE_ERRORS
#define CHECK_WAV_ERRORS
+#define VERSION_ERRORS
extern const char **para_errlist[];
#include "string.h"
#include "mix.h"
#include "error.h"
+#include "ggo.h"
#include "version.h"
INIT_FADE_ERRLISTS;
exit(EXIT_FAILURE);
}
+__noreturn static void print_help_and_die(void)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(fade);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ exit(0);
+}
+
int main(int argc, char *argv[])
{
int ret;
struct mixer *m;
struct mixer_handle *h = NULL;
- if (fade_cmdline_parser(argc, argv, &conf))
- exit(EXIT_FAILURE);
- HANDLE_VERSION_FLAG("fade", conf);
+ fade_cmdline_parser(argc, argv, &conf);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("fade", conf.version_given);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
ret = configfile_exists();
if (!ret && conf.config_file_given) {
PARA_EMERG_LOG("can not read config file %s\n",
};
fade_cmdline_parser_config_file(conf.config_file_arg,
&conf, ¶ms);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
init_mixers();
m = get_mixer_or_die();
ret = m->open(conf.mixer_device_arg, &h);
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", FILTER_CMDLINE_PARSER_PACKAGE "-"
- FILTER_CMDLINE_PARSER_VERSION);
- 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);
}
-static int parse_config(int argc, char *argv[])
+static int parse_config(void)
{
static char *cf; /* config file */
struct stat statbuf;
- if (filter_cmdline_parser(argc, argv, &conf))
- return -E_FILTER_SYNTAX;
- HANDLE_VERSION_FLAG("filter", conf);
+ version_handle_flag("filter", conf.version_given);
if (conf.help_given || conf.detailed_help_given)
print_help_and_die();
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
if (!cf) {
char *home = para_homedir();
cf = make_message("%s/.paraslash/filter.conf", home);
.check_ambiguity = 0,
.print_errors = 1
};
- if (filter_cmdline_parser_config_file(cf, &conf, ¶ms))
- return -E_FILTER_SYNTAX;
+ filter_cmdline_parser_config_file(cf, &conf, ¶ms);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
if (!conf.filter_given)
return -E_NO_FILTERS;
struct btr_node *parent;
struct filter_node **fns;
+ filter_cmdline_parser(argc, argv, &conf); /* aborts on errors */
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
filter_init();
- ret = parse_config(argc, argv);
+ ret = parse_config();
if (ret < 0)
goto out;
sit->btrn = btr_new_node(&(struct btr_node_description)
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;
+ int i, num = 0;
- printf_or_die("\nAvailable filters: \n\t");
- FOR_EACH_SUPPORTED_FILTER(i)
- printf_or_die("%s%s", i? " " : "", filters[i].name);
- printf_or_die("\n\n");
+ printf_or_die("\nAvailable filters: ");
+ FOR_EACH_SUPPORTED_FILTER(i) {
+ if (num > 50) {
+ printf_or_die("\n ");
+ num = 0;
+ }
+ num += printf_or_die("%s%s", i? " " : "", filters[i].name);
+ }
+ printf_or_die("\n");
FOR_EACH_SUPPORTED_FILTER(i) {
struct filter *f = filters + i;
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 (%s):", f->name,
+ f->help.purpose);
+ ggo_print_help(&f->help, flags);
}
}
#include "para.h"
#include "ggo.h"
+#include "version.h"
/**
* Wrapper for printf() that exits on errors.
*
* \param fmt Usual format string.
*/
-__printf_1_2 void printf_or_die(const char *fmt, ...)
+__printf_1_2 int printf_or_die(const char *fmt, ...)
{
va_list argp;
int ret;
ret = vprintf(fmt, argp);
va_end(argp);
if (ret >= 0)
- return;
+ return ret;
exit(EXIT_FAILURE);
}
* 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 (help->purpose && (flags & GPH_PRINT_NAME_PURPOSE))
+ printf_or_die("para_%s - %s\n", help->prefix, help->purpose);
+ 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;
- p += 3; /* skip -h and -V */
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;
+ /** The purpose text as specified in the ggo file. */
+ const char *purpose;
+ /** 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);
-__printf_1_2 void printf_or_die(const char *fmt, ...);
+/**
+ * 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 and the purpose text. */
+ GPH_PRINT_NAME_PURPOSE = 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_PURPOSE | 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, \
+ .purpose = _prefix ## _args_info_purpose, \
+ .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, ...);
#include "list.h"
#include "sched.h"
#include "signal.h"
+#include "ggo.h"
#include "version.h"
/** define the array of error lists needed by para_gui */
{
if (loglevel > LL_NOTICE)
return;
- outputf(COLOR_WELCOME, "Welcome to para_gui " PACKAGE_VERSION
- " \"" CODENAME "\". Theme: %s", theme.name);
+ outputf(COLOR_WELCOME, "Welcome to %s. Theme: %s",
+ version_single_line("gui"), theme.name);
wclrtoeol(bot.win);
}
}
PARA_INFO_LOG("rereading command line options and config file");
gui_cmdline_parser_ext(_argc, _argv, &conf, ¶ms);
- if (gui_cmdline_parser_config_file(cf, &conf, ¶ms) != 0) {
- PARA_EMERG_LOG("errors in config file");
- finish(EXIT_FAILURE);
- }
+ gui_cmdline_parser_config_file(cf, &conf, ¶ms);
PARA_NOTICE_LOG("config file reloaded");
if (check_key_map_args() < 0)
finish(EXIT_FAILURE);
static void com_version(void)
{
- print_in_bar(COLOR_MSG, "para_gui " PACKAGE_VERSION " \""
- CODENAME "\"");
+ print_in_bar(COLOR_MSG, "%s", version_single_line("gui"));
}
__noreturn static void com_quit(void)
km_keyname(c));
}
+__noreturn static void print_help_and_die(void)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(gui);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ exit(0);
+}
+
int main(int argc, char *argv[])
{
int ret;
_argv = argv;
gui_cmdline_parser(argc, argv, &conf); /* exits on errors */
- HANDLE_VERSION_FLAG("gui", conf);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("gui", conf.version_given);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
cf = configfile_exists();
if (!cf && conf.config_file_given) {
fprintf(stderr, "can not read config file %s\n",
.check_ambiguity = 0,
.print_errors = 1,
};
- if (gui_cmdline_parser_config_file(cf, &conf, ¶ms) != 0)
- exit(EXIT_FAILURE);
+ gui_cmdline_parser_config_file(cf, &conf, ¶ms);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
if (check_key_map_args() < 0) {
fprintf(stderr, "invalid key map\n");
exit(EXIT_FAILURE);
{
struct http_recv_args_info *tmp = para_calloc(sizeof(*tmp));
- if (!http_recv_cmdline_parser(argc, argv, tmp))
- return tmp;
- free(tmp);
- return NULL;
+ http_recv_cmdline_parser(argc, argv, tmp);
+ return tmp;
}
static int http_recv_open(struct receiver_node *rn)
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);
}
-args "--unamed-opts=audio_file --no-handle-version"
+args "--unamed-opts=audio_file --no-handle-version --no-handle-help"
-include(header.m4)
-<qu>
-text "
-para_afh, the audio format handler tool, is a simple program for analyzing
-audio files. It prints technical information about the given audio file to
-stdout.
-"
-</qu>
+purpose "Print information about audio file(s)."
+include(header.m4)
include(loglevel.m4)
<qu>
-include(header.m4)
-<qu>
-text "
+args "--no-version --no-help"
+
+purpose "Make an audio stream from a local file."
+
+description "
The afh (audio format handler) receiver can be used to write
selected parts of the given audio file without decoding
the data.
The selected parts of the content of the audio file are passed
to the child nodes of the buffer tree. Only complete chunks
with respect of the underlying audio format are passed.
-
"
+include(header.m4)
+<qu>
option "filename" f
#~~~~~~~~~~~~~~~~~~
"file to open"
+args "--no-version --no-help"
+
+purpose "Native ALSA output plugin."
+
include(header.m4)
<qu>
+args "--no-version --no-help"
+
+purpose "Amplify the decoded audio stream."
+
option "amp" a
#~~~~~~~~~~~~~
"amplification value"
+args "--no-version --no-help"
+
+purpose "Output plugin for libao."
+
include(header.m4)
<qu>
-args "--unamed-opts=command --conf-parser --no-handle-version"
+args "--unamed-opts=command --conf-parser --no-handle-version --no-handle-help"
+
+purpose "Communicate with para_audiod through a local socket."
include(header.m4)
<qu>
args "--no-handle-help --no-handle-version --conf-parser"
+purpose "Connect to para_server, receive, decode and play audio streams."
+
include(header.m4)
define(CURRENT_PROGRAM,para_audiod)
define(DEFAULT_CONFIG_FILE,~/.paraslash/audiod.conf)
-args "--unamed-opts=command --no-handle-error --conf-parser --no-handle-version"
+args "--unamed-opts=command --no-handle-error --conf-parser --no-handle-version --no-handle-help"
+
+purpose "Communicate with para_server through the paraslash control port."
include(header.m4)
define(CURRENT_PROGRAM,para_client)
+args "--no-version --no-help"
+
+purpose "Dynamically adjust the volume of an audio stream."
+
option "blocksize" b
#~~~~~~~~~~~~~~~~~~~
"adjust block size"
+args "--no-version --no-help"
+
+purpose "Receive a DCCP audio stream."
+
option "host" i
"ip or host"
string default="localhost"
-args "--conf-parser --no-handle-version"
+args "--conf-parser --no-handle-version --no-handle-help"
+
+purpose "An alarm clock and volume-fader for OSS and ALSA."
include(header.m4)
define(CURRENT_PROGRAM,para_fade)
+args "--no-version --no-help"
+
+purpose "Output plugin that writes to a local file."
+
option "filename" f
#~~~~~~~~~~~~~~~~~~
"specify output file name"
args "--no-handle-help --no-handle-version --conf-parser"
+purpose "Decode or process audio data from STDIN to STDOUT."
+
include(header.m4)
include(loglevel.m4)
<qu>
-args "--conf-parser --no-handle-version"
+args "--conf-parser --no-handle-version --no-handle-help"
+
+purpose "Show para_audiod status in a curses window."
include(header.m4)
define(CURRENT_PROGRAM,para_gui)
+args "--no-version --no-help"
+
+purpose "Receive an HTTP audio stream."
+
include(header.m4)
<qu>
define ggo_opts
--output-dir=$(cmdline_dir) \
- --set-version="$(PACKAGE_VERSION)" \
+ --set-version="$(GIT_VERSION) ($(codename))" \
--arg-struct-name=$(*F)_args_info \
--file-name=$(*F).cmdline \
--func-name=$(*F)_cmdline_parser \
$(cmdline_dir)/%.cmdline.h $(cmdline_dir)/%.cmdline.c: $(ggo_dir)/%.ggo | $(cmdline_dir)
@[ -z "$(Q)" ] || echo 'GGO $<'
$(Q) $(GENGETOPT) $(ggo_opts) < $<
+ifeq ($(ggo_descriptions_declared),no)
+ echo 'extern const char *$(*F)_args_info_description;' >> $(cmdline_dir)/$(*F).cmdline.h
+endif
$(ggo_dir)/server.ggo $(ggo_dir)/audiod.ggo: \
$(m4_ggo_dir)/loglevel.m4 $(m4_ggo_dir)/color.m4 \
+args "--no-version --no-help"
+
+purpose "Decode an mp3 stream."
+
include(header.m4)
<qu>
+args "--no-version --no-help"
+
+purpose "Output plugin for the Open Sound System."
+
option "device" d
#~~~~~~~~~~~~~~~~
"set PCM device"
+args "--no-version --no-help"
+
+purpose "Output plugin for Mac OS coreaudio."
+
section "osx options"
#####################
args "--unamed-opts=audio_file --no-handle-version --conf-parser --no-handle-help"
+
+purpose "Command line audio player."
+
+description "para_play operates either in command mode or in insert
+mode. In insert mode it presents a prompt and allows to enter commands
+like stop, play, pause etc. In command mode the current audio file
+is shown and the program reads single key strokes from stdin. Keys
+may be mapped to commands. Whenever a mapped key is pressed, the
+associated command is executed."
+
include(header.m4)
define(CURRENT_PROGRAM,para_play)
define(DEFAULT_CONFIG_FILE,~/.paraslash/play.conf)
+args "--no-version --no-help"
+
+purpose "Delay processing of an audio stream."
+
option "duration" d
#~~~~~~~~~~~~~~~~~~
"prebuffer time"
args "--no-handle-help --no-handle-version"
+purpose "A command line HTTP/DCCP/UDP stream grabber."
+
include(header.m4)
include(loglevel.m4)
+args "--no-version --no-help"
+
+purpose "Transform raw audio to a different sample rate."
+
include(header.m4)
option "converter" C
-args "--conf-parser --no-handle-version"
+args "--conf-parser --no-handle-version --no-handle-help"
+
+purpose "Manage and stream audio files."
include(header.m4)
define(CURRENT_PROGRAM,para_server)
option "udp_header_interval" H
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"duration for sending header"
-int typestr="ms"
-default="2000"
+int typestr = "ms"
+default = "2000"
optional
-details="
+details = "
As the udp sender has no idea about connected clients it
sends the audio file header periodically if necessary. This
- option is used to specify the duration of the interval between
- sending the header. Shorter values decrease the average time
- clients have to wait before being able to start playback,
- but this also increases the amount network traffic. Note
- that this affects only ogg vorbis streams as this is the only
- audio format that needs an audio file header.
+ option specifies the duration between subsequent headers are
+ sent. Smaller values decrease the average time clients have
+ to wait before starting playback, larger values decrease
+ network traffic.
+
+ Note that this affects only ogg/* and wma streams. Other
+ audio formats, including mp3, don't need an audio file header.
"
option "udp_ttl" t
+args "--no-version --no-help"
+
+purpose "Receive an UDP audio stream."
+
option "host" i
"ip or host to receive udp packets from"
string default="224.0.1.38"
args "--no-handle-help --no-handle-version"
+purpose "Play wav or raw audio."
+
include(header.m4)
include(loglevel.m4)
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);
}
exit(EXIT_FAILURE);
}
-/** Description to be included in the --detailed-help output. */
-#define PP_DESC \
-"para_play is a command line audio player.\n" \
-"\n" \
-"It operates either in command mode or in insert mode. In insert mode it\n" \
-"presents a prompt and allows to enter para_play commands like stop, play, pause\n" \
-"etc. In command mode, the current audio file is shown and the program reads\n" \
-"single key strokes from stdin. Keys may be mapped to para_play commands.\n" \
-"Whenever a mapped key is pressed, the associated command is executed.\n" \
-
__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", PLAY_CMDLINE_PARSER_PACKAGE "-"
-// PLAY_CMDLINE_PARSER_VERSION);
-
- printf_or_die("%s\n\n", play_args_info_usage);
- if (d)
- printf_or_die("%s\n", PP_DESC);
- 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);
+ printf("supported audio formats: %s\n", AUDIO_FORMAT_HANDLERS);
exit(0);
}
.print_errors = 1
};
- if (play_cmdline_parser_ext(argc, argv, &conf, ¶ms))
- exit(EXIT_FAILURE);
- HANDLE_VERSION_FLAG("play", conf);
+ play_cmdline_parser_ext(argc, argv, &conf, ¶ms);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("play", conf.version_given);
if (conf.help_given || conf.detailed_help_given)
print_help_and_die();
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
if (conf.config_file_given)
config_file = para_strdup(conf.config_file_arg);
else {
params.initialize = 0;
params.check_required = 1;
play_cmdline_parser_config_file(config_file, &conf, ¶ms);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
}
for (i = 0; i < conf.key_map_given; i++) {
char *s = strchr(conf.key_map_arg[i] + 1, ':');
char *history_file;
struct sigaction act;
- PARA_NOTICE_LOG("\n%s\n", VERSION_TEXT("play"));
+ PARA_NOTICE_LOG("\n%s\n", version_text("play"));
if (conf.history_file_given)
history_file = para_strdup(conf.history_file_arg);
else {
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", RECV_CMDLINE_PARSER_PACKAGE "-"
- RECV_CMDLINE_PARSER_VERSION);
- printf_or_die("%s\n\n", recv_args_info_usage);
- for (; *p; p++)
- printf_or_die("%s\n", *p);
- print_receiver_helps(d);
- exit(0);
-}
+ struct ggo_help h = DEFINE_GGO_HELP(recv);
+ bool d = conf.detailed_help_given;
-static void *parse_config(int argc, char *argv[], int *receiver_num)
-{
- if (recv_cmdline_parser(argc, argv, &conf))
- return NULL;
- HANDLE_VERSION_FLAG("recv", conf);
- if (conf.help_given || conf.detailed_help_given)
- print_help_and_die();
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
- return check_receiver_arg(conf.receiver_arg, receiver_num);
+ 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);
}
/**
struct stdout_task sot;
static struct sched s;
- s.default_timeout.tv_sec = 1;
- s.default_timeout.tv_usec = 0;
+ recv_cmdline_parser(argc, argv, &conf);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ version_handle_flag("recv", conf.version_given);
+ recv_init();
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
- memset(&sot, 0, sizeof(struct stdout_task));
memset(&rn, 0, sizeof(struct receiver_node));
- recv_init();
- ret = -E_RECV_SYNTAX;
- rn.conf = parse_config(argc, argv, &receiver_num);
+ rn.conf = check_receiver_arg(conf.receiver_arg, &receiver_num);
if (!rn.conf) {
- PARA_EMERG_LOG("parse failed\n");
+ PARA_EMERG_LOG("invalid receiver specifier\n");
+ ret = -E_RECV_SYNTAX;
goto out;
}
r = &receivers[receiver_num];
goto out;
r_opened = 1;
+ memset(&sot, 0, sizeof(struct stdout_task));
sot.btrn = btr_new_node(&(struct btr_node_description)
EMBRACE(.parent = rn.btrn, .name = "stdout"));
stdout_set_defaults(&sot);
sprintf(rn.task.status, "%s", r->name);
register_task(&s, &rn.task);
+ s.default_timeout.tv_sec = 1;
+ s.default_timeout.tv_usec = 0;
ret = schedule(&s);
out:
if (r_opened)
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("\n%s: %s", r->name,
+ r->help.purpose);
+ 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);
}
#include "signal.h"
#include "user_list.h"
#include "color.h"
+#include "ggo.h"
#include "version.h"
__printf_2_3 void (*para_log)(int, const char*, ...) = daemon_log;
.print_errors = !conf.daemon_given
};
server_cmdline_parser_config_file(cf, &conf, ¶ms);
+ daemon_set_loglevel(conf.loglevel_arg);
conf.daemon_given = tmp;
}
if (conf.logfile_given) {
daemon_set_logfile(conf.logfile_arg);
daemon_open_log_or_die();
}
- daemon_set_loglevel(conf.loglevel_arg);
init_colors_or_die();
daemon_set_flag(DF_LOG_PID);
daemon_set_flag(DF_LOG_LL);
return afs_server_socket[0];
}
+__noreturn static void print_help_and_die(void)
+{
+ struct ggo_help h = DEFINE_GGO_HELP(server);
+ bool d = conf.detailed_help_given;
+
+ ggo_print_help(&h, d? GPH_STANDARD_FLAGS_DETAILED : GPH_STANDARD_FLAGS);
+ exit(0);
+}
+
static void server_init(int argc, char **argv)
{
struct server_cmdline_parser_params params = {
init_random_seed_or_die();
/* parse command line options */
server_cmdline_parser_ext(argc, argv, &conf, ¶ms);
- HANDLE_VERSION_FLAG("server", conf);
+ daemon_set_loglevel(conf.loglevel_arg);
+ version_handle_flag("server", conf.version_given);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
drop_privileges_or_die(conf.user_arg, conf.group_arg);
/* parse config file, open log and set defaults */
parse_config_or_die(0);
static void *udp_recv_parse_config(int argc, char **argv)
{
- int ret;
- struct udp_recv_args_info *tmp =
- para_calloc(sizeof(struct udp_recv_args_info));
-
- ret = udp_recv_cmdline_parser(argc, argv, tmp)? -E_UDP_SYNTAX : 1;
- if (ret >= 0)
- return tmp;
- free(tmp);
- return NULL;
+ struct udp_recv_args_info *tmp = para_calloc(sizeof(*tmp));
+ udp_recv_cmdline_parser(argc, argv, tmp);
+ return tmp;
}
/*
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);
}
--- /dev/null
+#include "para.h"
+
+/** \file version.h Macros for printing the version string. */
+
+#include "git-version.h"
+
+/**
+ * Get the raw git version string
+ *
+ * \return The string generated by the GIT-VERSION-GEN script. It is passed
+ * as a preprocessor define during compilation.
+ */
+__a_const const char *version_git(void)
+{
+ return GIT_VERSION;
+}
+
+/**
+ * Get the version string for an executable.
+ *
+ * \param pfx The program name (without the leading "para_").
+ *
+ * \return A statically allocated string which contains the program name, the
+ * git version and the codename. It must not be freed by the caller.
+ */
+const char *version_single_line(const char *pfx)
+{
+ static char buf[100];
+ snprintf(buf, sizeof(buf) - 1,
+ "para_%s " GIT_VERSION, pfx);
+ return buf;
+}
+
+/**
+ * Get the full version text.
+ *
+ * \param pfx See \ref version_single_line().
+ *
+ * \return A string containing the same text as returned by \ref
+ * version_single_line(), augmented by additional build information, a
+ * copyright text and the email address of the author.
+ *
+ * Like \ref version_single_line(), this string is stored in a statically
+ * allocated buffer and must not be freed.
+ */
+const char *version_text(const char *pfx)
+{
+ static char buf[512];
+
+ snprintf(buf, sizeof(buf) - 1, "%s\n"
+ "Copyright (C) 2013 Andre Noll\n"
+ "This is free software with ABSOLUTELY NO WARRANTY."
+ " See COPYING for details.\n"
+ "Report bugs to <maan@systemlinux.org>.\n"
+ "build date: " BUILD_DATE ",\n"
+ "build system: " UNAME_RS ",\n"
+ "compiler: " CC_VERSION ".\n",
+ version_single_line(pfx)
+ );
+ return buf;
+}
+
+/**
+ * Print the version text and exit successfully.
+ *
+ * \param pfx See \ref version_single_line().
+ * \param flag Whether --version was given.
+ *
+ * If \a flag is false, this function does nothing. Otherwise it prints the
+ * full version text as returned by \ref version_text() and exits successfully.
+ */
+void version_handle_flag(const char *pfx, bool flag)
+{
+ if (!flag)
+ return;
+ printf("%s", version_text(pfx));
+ exit(EXIT_SUCCESS);
+}
-/** \file version.h Macros for printing the version string. */
-
-#include "git-version.h"
-
-/** Version text printed by all executables if -V was given. */
-#define VERSION_TEXT(prefix) "para_" prefix " " PACKAGE_VERSION \
- " (" GIT_VERSION ": " CODENAME ")" "\n" \
- "Copyright (C) 2013 Andre Noll\n" \
- "This is free software with ABSOLUTELY NO WARRANTY." \
- " See COPYING for details.\n" \
- "Report bugs to <maan@systemlinux.org>.\n"
-
-/** Print out \p VERSION_TEXT and exit if version flag was given. */
-#define HANDLE_VERSION_FLAG(_prefix, _args_info_struct) \
- if (_args_info_struct.version_given) { \
- printf("%s", VERSION_TEXT(_prefix)); \
- exit(EXIT_SUCCESS); \
- }
+/** \file version.h Functions for printing the version string. */
+const char *version_git(void);
+const char *version_single_line(const char *pfx);
+const char *version_text(const char *pfx);
+void version_handle_flag(const char *pfx, bool flag);
__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", WRITE_CMDLINE_PARSER_PACKAGE "-"
- WRITE_CMDLINE_PARSER_VERSION);
- 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);
}
},
};
- loglevel = get_loglevel_by_name(conf.loglevel_arg);
sit.btrn = btr_new_node(&(struct btr_node_description)
EMBRACE(.name = "stdin"));
stdin_set_defaults(&sit);
{
int ret;
- writer_init();
write_cmdline_parser(argc, argv, &conf);
- HANDLE_VERSION_FLAG("write", conf);
+ loglevel = get_loglevel_by_name(conf.loglevel_arg);
+ writer_init();
+ version_handle_flag("write", conf.version_given);
if (conf.help_given || conf.detailed_help_given)
print_help_and_die();
/**
* 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("\n%s: %s", writer_names[i],
+ w->help.purpose);
+ 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);