audioc.ggo) O="--unamed-opts=command";; \
fsck.ggo) O="--unamed-opts=table";; \
afh.ggo) O="--unamed-opts=audio_file";; \
+ filter.ggo) O="--no-handle-help";; \
+ write.ggo) O="--no-handle-help";; \
esac; \
if test $< != fsck.ggo; then O="$$O --conf-parser "; fi; \
gengetopt $$O \
mkdir -p man/man1
help2man -h --detailed-help -N -i audiod_command_list.man ./para_audiod > $@
+man/man1/para_filter.1: para_filter
+ mkdir -p man/man1
+ help2man -h --detailed-help -N ./$< > $@
+
+man/man1/para_write.1: para_write
+ mkdir -p man/man1
+ help2man -h --detailed-help -N ./$< > $@
+
man/man1/%.1: %
mkdir -p man/man1
help2man -N ./$< > $@
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "error.h"
#include "string.h"
#include "string.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "write.h"
#include "alsa_write.cmdline.h"
#include "error.h"
*/
void alsa_write_init(struct writer *w)
{
+ struct alsa_write_args_info dummy;
+
+ alsa_cmdline_parser_init(&dummy);
w->open = alsa_open;
w->close = alsa_close;
w->pre_select = alsa_write_pre_select;
w->post_select = alsa_write_post_select;
w->parse_config = alsa_parse_config;
w->shutdown = NULL; /* nothing to do */
+ w->help = (struct ggo_help) {
+ .short_help = alsa_write_args_info_help,
+ .detailed_help = alsa_write_args_info_detailed_help
+ };
}
-section "alsa options"
-######################
-
option "device" d
#~~~~~~~~~~~~~~~~
"set PCM device"
- string typestr="device"
- default="default"
- optional
+string typestr="device"
+default="default"
+optional
+details="
+ On systems with dmix, a better choice than the default
+ value might be to use \"plug:swmix\".
+"
option "channels" c
#~~~~~~~~~~~~~~~~~~
-"number of channels (only necessary for raw
-audio)"
-
- int typestr="num"
- default="2"
- optional
+"specify number of channels"
+int typestr="num"
+default="2"
+optional
+details="
+ This option is only necessary for playing raw audio with
+ para_write. In all other cases (plaing wav files with
+ para_write or using this writer with para_audiod), the number
+ of channels will be obtained from other resources.
+"
option "samplerate" s
#~~~~~~~~~~~~~~~~~~~~~
-
-"force given sample rate (only necessary for
-raw audio)"
-
- int typestr="num"
- default="44100"
- optional
+"force given sample rate"
+int typestr="num"
+default="44100"
+optional
+details="
+ Again, it is only necessary to specify this when playing raw
+ audio with para_write.
+"
#include "amp_filter.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "string.h"
#include "error.h"
*/
void amp_filter_init(struct filter *f)
{
+ struct amp_filter_args_info dummy;
+
+ amp_cmdline_parser_init(&dummy);
f->open = amp_open;
f->close = amp_close;
f->convert = amp_convert;
- f->print_help = amp_cmdline_parser_print_help;
f->parse_config = amp_parse_config;
+ f->help = (struct ggo_help) {
+ .short_help = amp_filter_args_info_help,
+ .detailed_help = amp_filter_args_info_detailed_help
+ };
}
-section "The amplify filter"
-
option "amp" a
+#~~~~~~~~~~~~~
"amplification value"
int typestr="number"
default="32"
which the amplitude of the audio stream is multiplied. The
formula for the scaling factor is
- factor = 1 + amp / 64
+ factor = 1 + amp / 64.
- amp value scaling factor
- ~~~~~~~~~ ~~~~~~~~~~~~~~
- 0 1
- 32 1.5
- 64 2
- 128 3
+ For example, an amplifiction value of zero results in a
+ scaling factor of one while an amplification value of 64
+ means to double the volume.
"
#include "list.h"
#include "sched.h"
#include "recv.h"
+#include "ggo.h"
#include "filter.h"
#include "grab_client.cmdline.h"
#include "grab_client.h"
* \param ll loglevel
* \param fmt the format string
*/
-void para_log(int ll, const char* fmt,...)
+__printf_2_3 void para_log(int ll, const char* fmt,...)
{
va_list argp;
FILE *outfd;
#include "list.h"
#include "close_on_fork.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "grab_client.cmdline.h"
#include "grab_client.h"
#include "compress_filter.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "string.h"
#include "error.h"
*/
void compress_filter_init(struct filter *f)
{
+ struct compress_filter_args_info dummy;
+
+ compress_cmdline_parser_init(&dummy);
f->open = open_compress;
f->close = close_compress;
f->convert = compress;
- f->print_help = compress_cmdline_parser_print_help;
f->parse_config = compress_parse_config;
+ f->help = (struct ggo_help) {
+ .short_help = compress_filter_args_info_help,
+ .detailed_help = compress_filter_args_info_detailed_help
+ };
}
-section "The dynamic audio range compressor"
+option "blocksize" b
+#~~~~~~~~~~~~~~~~~~~
+"adjust block size"
+int typestr="number"
+default="15"
+optional
+details = "
+ Larger blocksize means fewer volume adjustments per time unit.
+"
-option "blocksize" b "larger blocksize means fewer volume adjustments per time unit" int typestr="number" default="15" optional
-option "aggressiveness" a "controls the maximum amount to amplify by" int typestr="number" default="4" optional
-option "inertia" i "how much inertia ramping has" int typestr="number" default="6" optional
-option "target_level" t "target signal level (0-32768)" int typestr="number" default="20000" optional
-option "damp" d "if non-zero, scale down after normalizing" int typestr="number" default="0" optional
+option "aggressiveness" a
+#~~~~~~~~~~~~~~~~~~~~~~~~
+ "controls the maximum amount to amplify by"
+int typestr="number"
+default="4"
+optional
+
+option "inertia" i
+#~~~~~~~~~~~~~~~~~
+ "how much inertia ramping has"
+ int typestr="number"
+default="6"
+optional
+
+option "target_level" t
+#~~~~~~~~~~~~~~~~~~~~~~
+"target signal level (0-32768)"
+int typestr="number"
+default="20000"
+optional
+
+option "damp" d
+#~~~~~~~~~~~~~~
+"if non-zero, scale down after normalizing"
+int typestr="number"
+default="0"
+optional
dccp_send fd user_list chunk_queue afs osl aft mood score attribute blob ringbuffer
playlist sha1 rbtree sched audiod grab_client filter_common wav_filter compress_filter
http_recv dccp_recv recv_common write_common file_write audiod_command
-client_common recv stdout filter stdin audioc write client fsck exec send_common"
+client_common recv stdout filter stdin audioc write client fsck exec send_common ggo"
all_executables="server recv filter audioc write client fsck afh"
senders=" http dccp"
filter_cmdline_objs="filter.cmdline compress_filter.cmdline amp_filter.cmdline"
-filter_errlist_objs="filter_common wav_filter compress_filter filter string stdin stdout sched fd amp_filter"
+filter_errlist_objs="filter_common wav_filter compress_filter filter string stdin stdout sched fd amp_filter ggo"
filter_ldflags=""
filters=" compress wav amp"
audiod_errlist_objs="audiod signal string daemon stat net
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 crypt
- client_common"
+ client_common ggo"
audiod_ldflags=""
audiod_audio_formats=""
server_audio_formats=" mp3"
write_cmdline_objs="write.cmdline file_write.cmdline"
-write_errlist_objs="write write_common file_write time fd string sched stdin"
+write_errlist_objs="write write_common file_write time fd string sched stdin ggo"
write_ldflags=""
writers=" file"
default_writer="FILE_WRITE"
#define IPC_ERRORS
#define DCCP_SEND_ERRORS
#define HTTP_SEND_ERRORS
+#define GGO_ERRORS
extern const char **para_errlist[];
INIT_FADE_ERRLISTS;
struct fade_args_info conf;
-void para_log(__a_unused int ll, const char *fmt,...)
+__printf_2_3 void para_log(__a_unused int ll, const char *fmt, ...)
{
va_list argp;
time_t t1;
#include "para.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "write.h"
#include "string.h"
#include "fd.h"
/** the init function of the file writer */
void file_write_init(struct writer *w)
{
+ struct file_write_args_info dummy;
+
+ file_cmdline_parser_init(&dummy);
w->open = file_write_open;
w->pre_select = file_write_pre_select;
w->post_select = file_write_post_select;
w->parse_config = file_write_parse_config;
w->close = file_write_close;
w->shutdown = NULL; /* nothing to do */
+ w->help = (struct ggo_help) {
+ .short_help = file_write_args_info_help,
+ .detailed_help = file_write_args_info_detailed_help
+ };
}
-section "file writer options"
-
option "filename" f
#~~~~~~~~~~~~~~~~~~
-
-"select output file name. Defaults to a
-random filename in ~/.paraslash."
-
- string typestr="filename"
- optional
+"specify output file name"
+string typestr="filename"
+optional
+details="
+ Defaults to a random filename in ~/.paraslash.
+"
#include "filter.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "string.h"
#include "stdin.h"
return ret;
}
+__noreturn static void print_help_and_die(void)
+{
+ int i, 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);
+
+ 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");
+
+ 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, d);
+ }
+ exit(0);
+}
+
static int parse_config(int argc, char *argv[])
{
static char *cf; /* config file */
struct stat statbuf;
- int i;
if (filter_cmdline_parser(argc, argv, &conf))
return -E_FILTER_SYNTAX;
HANDLE_VERSION_FLAG("filter", conf);
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
if (!cf) {
char *home = para_homedir();
cf = make_message("%s/.paraslash/filter.conf", home);
if (filter_cmdline_parser_config_file(cf, &conf, ¶ms))
return -E_FILTER_SYNTAX;
}
- if (!conf.list_filters_given)
- return 1;
- printf("available filters: ");
- FOR_EACH_SUPPORTED_FILTER(i)
- printf("%s%s%s", i? " " : "", filters[i].name,
- filters[i].parse_config? "*": "");
- printf("\nFilters marked with \"*\" have further command line options. Try\n"
- "\tpara_filter -f '<filtername> -h'\nfor more information.\n");
- exit(EXIT_SUCCESS);
+ return 1;
}
/**
-option "loglevel" l "set loglevel (0-6)" int typestr="level" default="4" optional
-option "filter" f "Specify filter.
+option "loglevel" l
+#~~~~~~~~~~~~~~~~~~
+ "set loglevel (0-6)"
+int typestr="level"
+default="4"
+optional
-May be given multiple times to 'pipe' the stream
-through arbitrary many filters in an efficient
-way. The same filter may appear more than once,
-order matters.
+option "filter" f
+#~~~~~~~~~~~~~~~~
+"Specify filter."
+string typestr="filter_spec"
+optional
+multiple
+details="
+ May be given multiple times to 'pipe' the stream through
+ arbitrary many filters in an efficient way. The same filter
+ may appear more than once, order matters.
-Filter options may be specified for each '-f'
-option separately. Note that you will have to
-quote these options like this:
+ Filter options may be specified for each '-f' option
+ separately. Note that you will have to quote these options
+ like this:
- -f 'compress --inertia 5 --damp 2'
+ -f 'compress --inertia 5 --damp 2'
"
-string typestr="filter_spec" optional multiple
-
-option "list_filters" L "print list of available filters and exit" flag off
* by the open() function.
*/
void (*close)(struct filter_node *fn);
- /**
- * Print the help text for this filter and exit.
- *
- * This is optional and it is not necessary to initialize this pointer if
- * the filter does not have a help text.
- */
- void (*print_help)(void);
/**
* A pointer to the filter's command line parser.
*
* argv. On failure, a negative paraslash error code must be returned.
*/
int (*parse_config)(int argc, char **argv, void **config);
+
+ struct ggo_help help;
};
void close_filters(struct filter_chain *fc);
#include "list.h"
#include "sched.h"
#include "fd.h"
+#include "ggo.h"
#include "filter.h"
#include "error.h"
#include "string.h"
--- /dev/null
+/*
+ * Copyright (C) 2008 Andre Noll <maan@systemlinux.org>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/** \file ggo.c Function for printing help. */
+
+
+#include "para.h"
+#include "ggo.h"
+
+__printf_1_2 void printf_or_die(const char *fmt, ...)
+{
+ va_list argp;
+ int ret;
+
+ va_start(argp, fmt);
+ ret = vprintf(fmt, argp);
+ va_end(argp);
+ if (ret >= 0)
+ return;
+ fprintf(stderr, "%s: %s\n", __FUNCTION__, strerror(errno));
+}
+
+void ggo_print_help(struct ggo_help *help, int detailed_help)
+{
+ const char **p;
+
+ if (!help)
+ return;
+ if (detailed_help)
+ 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);
+}
--- /dev/null
+struct ggo_help {
+ const char **short_help;
+ const char **detailed_help;
+};
+
+void ggo_print_help(struct ggo_help *help, int detailed_help);
+void printf_or_die(const char *fmt, ...);
#include "grab_client.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "grab_client.h"
#include "audiod.h"
return 1;
}
-void para_log(int ll, const char *fmt,...)
+__printf_2_3 void para_log(int ll, const char *fmt,...)
{
int color;
char *msg;
#include "mp3dec_filter.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "error.h"
#include <mad.h>
*/
void mp3dec_filter_init(struct filter *f)
{
+ struct mp3dec_filter_args_info dummy;
+
+ mp3dec_cmdline_parser_init(&dummy);
f->open = mp3dec_open;
f->convert = mp3dec;
f->close = mp3dec_close;
f->parse_config = mp3dec_parse_config;
+ f->help = (struct ggo_help) {
+ .short_help = mp3dec_filter_args_info_help,
+ .detailed_help = mp3dec_filter_args_info_detailed_help
+ };
}
#include "oggdec_filter.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "error.h"
#include "string.h"
*/
void oggdec_filter_init(struct filter *f)
{
+ struct oggdec_filter_args_info dummy;
+
+ oggdec_cmdline_parser_init(&dummy);
f->open = ogg_open;
f->close = ogg_close;
f->convert = ogg_convert;
- f->print_help = oggdec_cmdline_parser_print_help;
f->parse_config = oggdec_parse_config;
+ f->help = (struct ggo_help) {
+ .short_help = oggdec_filter_args_info_help,
+ .detailed_help = oggdec_filter_args_info_detailed_help
+ };
}
default="16"
optional
details="
- The oggdec filter waits until at least that many bytes are available
- in the input buffer.
+ On startup, defer decoding until that many kilobytes are
+ available in the input buffer.
"
* \param ll The log level.
* \param fmt The format string describing the log message.
*/
-void para_log(int ll, const char* fmt,...)
+__printf_2_3 void para_log(int ll, const char* fmt,...)
{
va_list argp;
FILE *outfd;
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "filter.h"
#include "string.h"
#include "portable_io.h"
#include "write.cmdline.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "stdin.h"
#include "write.h"
#include "write_common.h"
struct writer_node_group *g = NULL;
struct initial_delay_task *idt = &the_initial_delay_task;
- if (conf.list_writers_given) {
- char *msg = NULL;
- FOR_EACH_WRITER(i) {
- char *tmp = make_message("%s%s%s",
- i? msg : "",
- i? " " : "",
- writer_names[i]);
- free(msg);
- msg = tmp;
- }
- fprintf(stderr, "%s\n", msg);
- free(msg);
- exit(EXIT_SUCCESS);
- }
if (conf.start_time_given) {
long unsigned sec, usec;
if (sscanf(conf.start_time_arg, "%lu:%lu",
return NULL;
}
+__noreturn static void print_help_and_die(void)
+{
+ int i, 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);
+
+ printf_or_die("\nAvailable writers: \n\t");
+ FOR_EACH_WRITER(i)
+ printf_or_die("%s%s", i? " " : "", writer_names[i]);
+ printf_or_die("\n\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, d);
+ }
+ exit(0);
+}
+
/**
* Para_write's main function.
*
struct check_wav_task *cwt = &the_check_wav_task;
struct initial_delay_task *idt = &the_initial_delay_task;
+ init_supported_writers();
write_cmdline_parser(argc, argv, &conf);
HANDLE_VERSION_FLAG("write", conf);
- init_supported_writers();
+ if (conf.help_given || conf.detailed_help_given)
+ print_help_and_die();
wng = check_args();
if (!wng)
-section "general options"
-#########################
-
-option "list_writers" L
-#~~~~~~~~~~~~~~~~~~~~~~
-"print available writers and exit"
-
- flag off
-
option "loglevel" l
#~~~~~~~~~~~~~~~~~~
"set loglevel (0-6)"
-
- int typestr="level"
- default="4"
- optional
+int typestr="level"
+default="4"
+optional
option "bufsize" b
#~~~~~~~~~~~~~~~~~
"input buffer size"
-
- int typestr="kilobytes"
- default="64"
- optional
+int typestr="kilobytes"
+default="64"
+optional
option "writer" w
#~~~~~~~~~~~~~~~~
-
-"select stream writer
-may be give multiple times. The same writer
-may be specified more than once"
-
- string typestr="name"
- default="alsa (file if alsa is unsupported)"
- optional
- multiple
+"select stream writer"
+string typestr="name"
+default="alsa (file if alsa is unsupported)"
+optional
+multiple
+details="
+ May be give multiple times. The same writer may be specified
+ more than once.
+"
option "start_time" t
#~~~~~~~~~~~~~~~~~~~~
-"start playback at given time which must be
-in a:b format where a denotes seconds and b
-denotes microseconds since the epoch"
-
- string typestr="timeval"
- optional
+"defer playback"
+string typestr="timeval"
+optional
+details="
+ Start playback at given time which must be in a:b format where
+ a denotes seconds and b denotes microseconds since the epoch.
+"
* This is a optional function pointer used for cleaning up.
*/
void (*shutdown)(struct writer_node *);
+ struct ggo_help help;
};
/**
#include "string.h"
#include "list.h"
#include "sched.h"
+#include "ggo.h"
#include "write.h"
#include "error.h"