1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 /** \file filter.c The stand-alone filter program. */
8 #include "filter.lsg.h"
9 #include "filter_cmd.lsg.h"
14 #include "buffer_tree.h"
23 /** Array of error strings. */
25 static struct lls_parse_result
*lpr
; /* command line options */
27 #define CMD_PTR (lls_cmd(0, filter_suite))
28 #define OPT_RESULT(_name) \
29 (lls_opt_result(LSG_FILTER_PARA_FILTER_OPT_ ## _name, lpr))
30 #define OPT_GIVEN(_name) (lls_opt_given(OPT_RESULT(_name)))
31 #define OPT_UINT32_VAL(_name) (lls_uint32_val(0, OPT_RESULT(_name)))
33 /** The list of all status items used by para_{server,audiod,gui}. */
34 const char *status_item_list
[] = {STATUS_ITEMS
};
37 * Dummy version which only contains NULL pointers.
39 * This is used by the amp filter which first tries to obtain the amplification
40 * value from an element in this array.
42 char *stat_item_values
[NUM_STAT_ITEMS
] = {NULL
};
44 /** The task that reads from stdin. */
45 static struct stdin_task stdin_task_struct
;
46 /** pointer to the stdin task. */
47 static struct stdin_task
*sit
= &stdin_task_struct
;
49 /** The task that writes converted data to stdout. */
50 static struct stdout_task stdout_task_struct
;
51 /** Pointer to the stdout task. */
52 static struct stdout_task
*sot
= &stdout_task_struct
;
55 INIT_STDERR_LOGGING(loglevel
);
57 static void handle_help_flag(void)
61 if (OPT_GIVEN(DETAILED_HELP
))
62 help
= lls_long_help(CMD_PTR
);
63 else if (OPT_GIVEN(HELP
))
64 help
= lls_short_help(CMD_PTR
);
69 print_filter_helps(OPT_GIVEN(DETAILED_HELP
));
73 static int parse_config(void)
77 version_handle_flag("filter", OPT_GIVEN(VERSION
));
79 ret
= lsu_merge_config_file_options(NULL
, "filter.conf",
80 &lpr
, CMD_PTR
, filter_suite
, 0 /* default flags */);
83 loglevel
= OPT_UINT32_VAL(LOGLEVEL
);
84 if (!OPT_GIVEN(FILTER
)) {
92 * The main function of para_filter.
94 * Para_filter reads data from stdin, converts it by using a chain
95 * of filters (specified on the command line) and writes the resulting
98 * \param argc Number of command line options.
99 * \param argv Vector of arguments.
101 * \return \a EXIT_SUCCESS on success, EXIT_FAILURE on errors.
103 int main(int argc
, char *argv
[])
105 static struct sched s
;
107 const struct filter
*f
;
108 struct btr_node
*parent
;
109 struct filter_node
**fns
;
110 struct lls_parse_result
*filter_lpr
; /* per-filter options */
113 ret
= lls(lls_parse(argc
, argv
, CMD_PTR
, &lpr
, &errctx
));
116 ret
= parse_config();
119 sit
->btrn
= btr_new_node(&(struct btr_node_description
)
120 EMBRACE(.name
= "stdin"));
121 stdin_task_register(sit
, &s
);
123 fns
= para_malloc(OPT_GIVEN(FILTER
) * sizeof(*fns
));
124 for (i
= 0, parent
= sit
->btrn
; i
< OPT_GIVEN(FILTER
); i
++) {
125 const char *fa
= lls_string_val(i
, OPT_RESULT(FILTER
));
127 struct filter_node
*fn
;
130 fn
= fns
[i
] = para_calloc(sizeof(*fn
));
131 fn
->filter_num
= filter_setup(fa
, &fn
->conf
, &filter_lpr
);
132 name
= filter_name(fn
->filter_num
);
133 fn
->lpr
= filter_lpr
;
134 PARA_DEBUG_LOG("filter #%d: %s\n", i
, name
);
135 f
= filter_get(fn
->filter_num
);
136 fn
->btrn
= btr_new_node(&(struct btr_node_description
)
137 EMBRACE(.name
= name
, .parent
= parent
,
138 .handler
= f
->execute
, .context
= fn
));
140 ti
.pre_select
= f
->pre_select
;
141 ti
.post_select
= f
->post_select
;
145 fn
->task
= task_register(&ti
, &s
);
148 sot
->btrn
= btr_new_node(&(struct btr_node_description
)
149 EMBRACE(.name
= "stdout", .parent
= parent
));
150 stdout_task_register(sot
, &s
);
152 s
.default_timeout
.tv_sec
= 1;
153 s
.default_timeout
.tv_usec
= 0;
154 btr_log_tree(sit
->btrn
, LL_INFO
);
157 for (i
--; i
>= 0; i
--) {
158 struct filter_node
*fn
= fns
[i
];
160 f
= filter_get(fn
->filter_num
);
163 btr_remove_node(&fn
->btrn
);
165 f
->teardown(fn
->lpr
, fn
->conf
);
169 btr_remove_node(&sit
->btrn
);
170 btr_remove_node(&sot
->btrn
);
172 lls_free_parse_result(lpr
, CMD_PTR
);
176 PARA_ERROR_LOG("%s\n", errctx
);
178 PARA_ERROR_LOG("%s\n", para_strerror(-ret
));
180 exit(ret
< 0? EXIT_FAILURE
: EXIT_SUCCESS
);