1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 /** \file write.c Paraslash's standalone wav/raw player. */
9 #include "write_cmd.lsg.h"
10 #include "write.lsg.h"
16 #include "buffer_tree.h"
21 #include "check_wav.h"
23 /** Array of error strings. */
26 #define CMD_PTR (lls_cmd(0, write_suite))
27 #define OPT_RESULT(_name, _lpr) \
28 (lls_opt_result(LSG_WRITE_PARA_WRITE_OPT_ ## _name, _lpr))
29 #define OPT_GIVEN(_name, _lpr) (lls_opt_given(OPT_RESULT(_name, _lpr)))
30 #define OPT_UINT32_VAL(_name, _lpr) (lls_uint32_val(0, OPT_RESULT(_name, _lpr)))
32 static struct stdin_task sit
;
34 INIT_STDERR_LOGGING(loglevel
)
36 static void handle_help_flag(struct lls_parse_result
*lpr
)
40 if (OPT_GIVEN(DETAILED_HELP
, lpr
))
41 help
= lls_long_help(CMD_PTR
);
42 else if (OPT_GIVEN(HELP
, lpr
))
43 help
= lls_short_help(CMD_PTR
);
48 print_writer_helps(OPT_GIVEN(DETAILED_HELP
, lpr
));
54 struct check_wav_context
*cwc
;
57 static void write_pre_select(struct sched
*s
, void *context
)
59 struct write_task
*wt
= context
;
60 check_wav_pre_select(s
, wt
->cwc
);
63 static int write_post_select(__a_unused
struct sched
*s
, void *context
)
65 struct write_task
*wt
= context
;
66 return check_wav_post_select(wt
->cwc
);
69 static int setup_and_schedule(struct lls_parse_result
*lpr
)
71 int i
, n
, ret
, writer_given
= OPT_GIVEN(WRITER
, lpr
);
72 struct btr_node
*cw_btrn
;
73 struct writer_node
*wns
;
74 static struct sched s
;
78 sit
.btrn
= btr_new_node(&(struct btr_node_description
)
79 EMBRACE(.name
= "stdin"));
80 stdin_task_register(&sit
, &s
);
82 LLS_COPY_WAV_PARMS(&wp
, LSG_WRITE_PARA_WRITE
, lpr
);
83 wt
.cwc
= check_wav_init(sit
.btrn
, NULL
, &wp
, &cw_btrn
);
84 wt
.task
= task_register(&(struct task_info
) {
86 .pre_select
= write_pre_select
,
87 .post_select
= write_post_select
,
91 n
= writer_given
? writer_given
: 1;
92 wns
= para_calloc(n
* sizeof(*wns
));
93 for (i
= 0; i
< n
; i
++) {
94 const char *arg
= i
< writer_given
?
95 lls_string_val(i
, OPT_RESULT(WRITER
, lpr
)) : NULL
;
96 wns
[i
].wid
= check_writer_arg_or_die(arg
, &wns
[i
].lpr
);
97 register_writer_node(wns
+ i
, cw_btrn
, &s
);
99 s
.default_timeout
.tv_sec
= 10;
100 s
.default_timeout
.tv_usec
= 50000;
104 for (j
= 0; j
< n
; j
++) {
105 struct writer_node
*wn
= wns
+ j
;
106 ts
= task_status(wn
->task
);
108 if (ts
!= -E_WRITE_COMMON_EOF
&& ts
!= -E_BTR_EOF
) {
109 const char *name
= writer_name(wn
->wid
);
110 PARA_ERROR_LOG("%s: %s\n", name
,
117 for (i
= n
- 1; i
>= 0; i
--) {
118 struct writer_node
*wn
= wns
+ i
;
119 writer_get(wn
->wid
)->close(wn
);
120 btr_remove_node(&wn
->btrn
);
121 lls_free_parse_result(wns
[i
].lpr
,
122 lls_cmd(wn
->wid
, write_cmd_suite
));
125 check_wav_shutdown(wt
.cwc
);
131 * Para_write's main function.
133 * \param argc The usual argument counter.
134 * \param argv The usual argument vector.
136 * It sets up and starts the tasks and the buffer tree nodes determined by
137 * command line options.
139 * \return \p EXIT_SUCCESS or EXIT_FAILURE
141 int main(int argc
, char *argv
[])
144 struct lls_parse_result
*lpr
;
147 ret
= lls(lls_parse(argc
, argv
, CMD_PTR
, &lpr
, &errctx
));
150 loglevel
= OPT_UINT32_VAL(LOGLEVEL
, lpr
);
151 version_handle_flag("write", OPT_GIVEN(VERSION
, lpr
));
152 handle_help_flag(lpr
);
153 ret
= setup_and_schedule(lpr
);
154 lls_free_parse_result(lpr
, CMD_PTR
);
158 PARA_ERROR_LOG("%s\n", errctx
);
160 PARA_ERROR_LOG("%s\n", para_strerror(-ret
));
162 return ret
< 0? EXIT_FAILURE
: EXIT_SUCCESS
;