Convert para_write to lopsub.
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 26 Aug 2016 18:12:01 +0000 (20:12 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Sun, 26 Mar 2017 09:02:28 +0000 (11:02 +0200)
This replaces the gengetopt file write.m4 by write.suite.m4, making use
of the shared macros in m4/lls/include for --channels, --sample-format
and --sample-rate.

The gengetopt files for these options are not needed for the unconverted
executables which still rely on gengetopt, so they can be removed.

In write.c we now use LLS_COPY_WAV_PARMS() rather than
COPY_WAV_PARMS(). The latter macro becomes unused and is removed
as well.

Makefile.real
check_wav.h
configure.ac
m4/gengetopt/channels.m4 [deleted file]
m4/gengetopt/sample_format.m4 [deleted file]
m4/gengetopt/sample_rate.m4 [deleted file]
m4/gengetopt/write.m4 [deleted file]
m4/lls/write.suite.m4 [new file with mode: 0644]
write.c

index 0ecd3f9ae452805a5ac3a4fb39ee08a4dbf09d38..c229a1f0d995c994f36c2a607350947661f6a616 100644 (file)
@@ -43,7 +43,7 @@ all_objs := $(sort $(recv_objs) $(filter_objs) $(client_objs) $(gui_objs) \
        $(audiod_objs) $(audioc_objs) $(fade_objs) $(server_objs) \
        $(write_objs) $(afh_objs) $(play_objs))
 deps := $(addprefix $(dep_dir)/, $(filter-out %.cmdline.d, $(all_objs:.o=.d)))
        $(audiod_objs) $(audioc_objs) $(fade_objs) $(server_objs) \
        $(write_objs) $(afh_objs) $(play_objs))
 deps := $(addprefix $(dep_dir)/, $(filter-out %.cmdline.d, $(all_objs:.o=.d)))
-converted_executables := audioc client fade play recv
+converted_executables := audioc client fade play recv write
 unconverted_executables := $(filter-out $(converted_executables), $(executables))
 
 audioc_objs += audioc.lsg.o
 unconverted_executables := $(filter-out $(converted_executables), $(executables))
 
 audioc_objs += audioc.lsg.o
@@ -54,7 +54,7 @@ filter_objs += filter_cmd.lsg.o
 play_objs += $(addsuffix _cmd.lsg.o, recv filter play write) play.lsg.o
 recv_objs += recv_cmd.lsg.o recv.lsg.o
 server_objs += server_cmd.lsg.o
 play_objs += $(addsuffix _cmd.lsg.o, recv filter play write) play.lsg.o
 recv_objs += recv_cmd.lsg.o recv.lsg.o
 server_objs += server_cmd.lsg.o
-write_objs += write_cmd.lsg.o
+write_objs += write_cmd.lsg.o write.lsg.o
 
 m4_deps := $(addprefix $(m4depdir)/, $(addsuffix .m4d, $(unconverted_executables)))
 m4_lls_deps := \
 
 m4_deps := $(addprefix $(m4depdir)/, $(addsuffix .m4d, $(unconverted_executables)))
 m4_lls_deps := \
index 31417de6e1a4fe9ec2c5b8f996ff6c37ff669398..045158ab2d2d32dd97e000896dce450a2b854496 100644 (file)
@@ -29,23 +29,6 @@ struct wav_params {
        int sample_format_given;
 };
 
        int sample_format_given;
 };
 
-/**
- * Copy the wav parameters.
- *
- * \param dst Usually a pointer to struct wav_params.
- * \param src Usually a pointer to some args_info struct.
- *
- * This can not be implemented as a function since the type of the structure
- * pointed to by \a src depends on the application.
- */
-#define COPY_WAV_PARMS(dst, src) \
-       (dst)->channels_arg = (src)->channels_arg; \
-       (dst)->channels_given = (src)->channels_given; \
-       (dst)->sample_rate_arg = (src)->sample_rate_arg; \
-       (dst)->sample_rate_given = (src)->sample_rate_given; \
-       (dst)->sample_format_arg = (src)->sample_format_arg; \
-       (dst)->sample_format_given = (src)->sample_format_given;
-
 #define LLS_COPY_WAV_PARMS(_dst, _pfx, _lpr) \
        (_dst)->channels_given = lls_opt_given(lls_opt_result( \
                _pfx ## _OPT_CHANNELS, (_lpr))); \
 #define LLS_COPY_WAV_PARMS(_dst, _pfx, _lpr) \
        (_dst)->channels_given = lls_opt_given(lls_opt_result( \
                _pfx ## _OPT_CHANNELS, (_lpr))); \
index 3d43af026392cfc57d888b724bc5afea2a3a95d2..d700323f487250ed86c14117409656c08beb3f9d 100644 (file)
@@ -869,9 +869,6 @@ fi
 play_objs="$play_errlist_objs"
 AC_SUBST(play_objs, add_dot_o($play_objs))
 ######################################################################### write
 play_objs="$play_errlist_objs"
 AC_SUBST(play_objs, add_dot_o($play_objs))
 ######################################################################### write
-write_cmdline_objs="
-       write
-"
 write_errlist_objs="
        write
        write_common
 write_errlist_objs="
        write
        write_common
@@ -882,7 +879,6 @@ write_errlist_objs="
        sched
        stdin
        buffer_tree
        sched
        stdin
        buffer_tree
-       ggo
        check_wav
        version
 "
        check_wav
        version
 "
@@ -899,7 +895,7 @@ fi
 if test $HAVE_ALSA = yes; then
        write_errlist_objs="$write_errlist_objs alsa_write"
 fi
 if test $HAVE_ALSA = yes; then
        write_errlist_objs="$write_errlist_objs alsa_write"
 fi
-write_objs="add_cmdline($write_cmdline_objs) $write_errlist_objs"
+write_objs="$write_errlist_objs"
 AC_SUBST(write_objs, add_dot_o($write_objs))
 ######################################################################## audioc
 audioc_errlist_objs="
 AC_SUBST(write_objs, add_dot_o($write_objs))
 ######################################################################## audioc
 audioc_errlist_objs="
diff --git a/m4/gengetopt/channels.m4 b/m4/gengetopt/channels.m4
deleted file mode 100644 (file)
index 64c2518..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-<qu>
-option "channels" c
-#~~~~~~~~~~~~~~~~~~
-"specify number of channels"
-int typestr = "num"
-default = "2"
-optional
-details = "
-       It is only necessary to specify this option for raw audio. If
-       it is not given, the channel count is queried from the parent
-       buffer tree nodes (e.g. the decoder) or the wav header. Only
-       if this fails, the default value applies.
-"
-</qu>
diff --git a/m4/gengetopt/sample_format.m4 b/m4/gengetopt/sample_format.m4
deleted file mode 100644 (file)
index c998f9d..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<qu>
-option "sample-format" f
-#~~~~~~~~~~~~~~~~~~~~~~~
-"specify sample format"
-# This must match the enum sample_format of para.h
-values = "S8", "U8", "S16_LE", "S16_BE", "U16_LE", "U16_BE" enum
-default = "S16_LE"
-optional
-details = "
-       It is only necessary to specify this for raw audio. See the
-       discussion of the --channels option.
-"
-</qu>
diff --git a/m4/gengetopt/sample_rate.m4 b/m4/gengetopt/sample_rate.m4
deleted file mode 100644 (file)
index a8332a4..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-<qu>
-option "sample-rate" s
-#~~~~~~~~~~~~~~~~~~~~~
-"do not guess the input sample rate"
-int typestr = "num"
-default = "44100"
-optional
-details = "
-       It is only necessary to specify this for raw audio. See the
-       discussion of the --channels option.
-"
-</qu>
diff --git a/m4/gengetopt/write.m4 b/m4/gengetopt/write.m4
deleted file mode 100644 (file)
index 6667cb8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-args "--no-handle-help --no-handle-version"
-
-purpose "Play wav or raw audio"
-
-include(header.m4)
-include(loglevel.m4)
-
-option "writer" w
-#~~~~~~~~~~~~~~~~
-"select stream writer"
-string typestr="name"
-optional
-multiple
-details="
-       May be given multiple times, and the same writer may be specified more
-       than once. If this option is not given, the first supported writer
-       is started. The list of supported writers is shown in the help output.
-"
-
-include(channels.m4)
-include(sample_rate.m4)
-include(sample_format.m4)
diff --git a/m4/lls/write.suite.m4 b/m4/lls/write.suite.m4
new file mode 100644 (file)
index 0000000..a2f50df
--- /dev/null
@@ -0,0 +1,35 @@
+m4_define(PROGRAM, para_write)
+[suite write]
+version-string = GIT_VERSION()
+[supercommand para_write]
+       purpose = play wav or raw audio
+       [description]
+               para_write reads audio data from stdin and starts one supported writer.
+       [/description]
+       m4_include(common-option-section.m4)
+       m4_include(help.m4)
+       m4_include(detailed-help.m4)
+       m4_include(version.m4)
+       m4_include(loglevel.m4)
+       m4_include(per-command-options-section.m4)
+       [option writer]
+               short_opt = w
+               summary = select writer to start
+               arg_info = required_arg
+               arg_type = string
+               flag multiple
+               typestr = 'name [options]'
+               [help]
+                       May be given multiple times, and the same writer may be specified more
+                       than once. If this option is not given, the first supported writer
+                       is started. The list of supported writers is shown in the help output.
+
+                       Options for a particular writer may be specified for each given
+                       '--writer' option separately. You will have to quote these options
+                       like this:
+
+                               --writer 'oss --device /dev/dsp2'
+               [/help]
+       m4_include(channels.m4)
+       m4_include(sample-rate.m4)
+       m4_include(sample-format.m4)
diff --git a/write.c b/write.c
index 98cd3557e0f3e7a60b0019a309cfe61d63fa5824..a1907b6f46a04f966722117e894f9fe0a69edb11 100644 (file)
--- a/write.c
+++ b/write.c
 #include <lopsub.h>
 
 #include "write_cmd.lsg.h"
 #include <lopsub.h>
 
 #include "write_cmd.lsg.h"
+#include "write.lsg.h"
 #include "para.h"
 #include "string.h"
 #include "para.h"
 #include "string.h"
-#include "write.cmdline.h"
 #include "list.h"
 #include "sched.h"
 #include "list.h"
 #include "sched.h"
-#include "ggo.h"
 #include "stdin.h"
 #include "buffer_tree.h"
 #include "write.h"
 #include "stdin.h"
 #include "buffer_tree.h"
 #include "write.h"
 /** Array of error strings. */
 DEFINE_PARA_ERRLIST;
 
 /** Array of error strings. */
 DEFINE_PARA_ERRLIST;
 
-static struct write_args_info conf;
+#define CMD_PTR (lls_cmd(0, write_suite))
+#define OPT_RESULT(_name, _lpr) \
+       (lls_opt_result(LSG_WRITE_PARA_WRITE_OPT_ ## _name, _lpr))
+#define OPT_GIVEN(_name, _lpr) (lls_opt_given(OPT_RESULT(_name, _lpr)))
+#define OPT_UINT32_VAL(_name, _lpr) (lls_uint32_val(0, OPT_RESULT(_name, _lpr)))
 
 static struct stdin_task sit;
 
 static struct stdin_task sit;
-
 static int loglevel;
 INIT_STDERR_LOGGING(loglevel)
 
 static int loglevel;
 INIT_STDERR_LOGGING(loglevel)
 
-__noreturn static void print_help_and_die(void)
+static void handle_help_flag(struct lls_parse_result *lpr)
 {
 {
-       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);
-       exit(0);
+       char *help;
+
+       if (OPT_GIVEN(DETAILED_HELP, lpr))
+               help = lls_long_help(CMD_PTR);
+       else if (OPT_GIVEN(HELP, lpr))
+               help = lls_short_help(CMD_PTR);
+       else
+               return;
+       printf("%s\n", help);
+       free(help);
+       print_writer_helps(OPT_GIVEN(DETAILED_HELP, lpr));
+       exit(EXIT_SUCCESS);
 }
 
 struct write_task {
 }
 
 struct write_task {
@@ -62,9 +70,9 @@ static int write_post_select(__a_unused struct sched *s, void *context)
        return check_wav_post_select(wt->cwc);
 }
 
        return check_wav_post_select(wt->cwc);
 }
 
-static int setup_and_schedule(void)
+static int setup_and_schedule(struct lls_parse_result *lpr)
 {
 {
-       int i, n, ret;
+       int i, n, ret, writer_given = OPT_GIVEN(WRITER, lpr);
        struct btr_node *cw_btrn;
        struct writer_node *wns;
        static struct sched s;
        struct btr_node *cw_btrn;
        struct writer_node *wns;
        static struct sched s;
@@ -75,7 +83,7 @@ static int setup_and_schedule(void)
                EMBRACE(.name = "stdin"));
        stdin_task_register(&sit, &s);
 
                EMBRACE(.name = "stdin"));
        stdin_task_register(&sit, &s);
 
-       COPY_WAV_PARMS(&wp, &conf);
+       LLS_COPY_WAV_PARMS(&wp, LSG_WRITE_PARA_WRITE, lpr);
        wt.cwc = check_wav_init(sit.btrn, NULL, &wp, &cw_btrn);
        wt.task = task_register(&(struct task_info) {
                .name = "write",
        wt.cwc = check_wav_init(sit.btrn, NULL, &wp, &cw_btrn);
        wt.task = task_register(&(struct task_info) {
                .name = "write",
@@ -84,10 +92,11 @@ static int setup_and_schedule(void)
                .context = &wt,
        }, &s);
 
                .context = &wt,
        }, &s);
 
-       n = conf.writer_given > 0? conf.writer_given : 1;
+       n = writer_given? writer_given : 1;
        wns = para_calloc(n * sizeof(*wns));
        for (i = 0; i < n; i++) {
        wns = para_calloc(n * sizeof(*wns));
        for (i = 0; i < n; i++) {
-               char *arg = i < conf.writer_given?  conf.writer_arg[i] : NULL;
+               const char *arg = i < writer_given?
+                       lls_string_val(i, OPT_RESULT(WRITER, lpr)) : NULL;
                wns[i].wid = check_writer_arg_or_die(arg, &wns[i].lpr);
                register_writer_node(wns + i, cw_btrn, &s);
        }
                wns[i].wid = check_writer_arg_or_die(arg, &wns[i].lpr);
                register_writer_node(wns + i, cw_btrn, &s);
        }
@@ -136,17 +145,23 @@ static int setup_and_schedule(void)
 int main(int argc, char *argv[])
 {
        int ret;
 int main(int argc, char *argv[])
 {
        int ret;
-
-       write_cmdline_parser(argc, argv, &conf);
-       loglevel = get_loglevel_by_name(conf.loglevel_arg);
-       version_handle_flag("write", conf.version_given);
-       if (conf.help_given || conf.detailed_help_given)
-               print_help_and_die();
-
-       ret = setup_and_schedule();
+       struct lls_parse_result *lpr;
+       char *errctx;
+
+       ret = lls(lls_parse(argc, argv, CMD_PTR, &lpr, &errctx));
+       if (ret < 0)
+               goto out;
+       loglevel = OPT_UINT32_VAL(LOGLEVEL, lpr);
+       version_handle_flag("write",  OPT_GIVEN(VERSION, lpr));
+       handle_help_flag(lpr);
+       ret = setup_and_schedule(lpr);
+       lls_free_parse_result(lpr, CMD_PTR);
+out:
        if (ret < 0) {
        if (ret < 0) {
+               if (errctx)
+                       PARA_ERROR_LOG("%s\n", errctx);
+               free(errctx);
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
-               exit(EXIT_FAILURE);
        }
        }
-       exit(EXIT_SUCCESS);
+       return ret < 0? EXIT_FAILURE : EXIT_SUCCESS;
 }
 }