From: Andre Noll Date: Sun, 30 Nov 2008 20:15:29 +0000 (+0100) Subject: Merge branch 'master' into next X-Git-Tag: v0.3.4~98 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=89a0e510df07bc7210ca9e73381763fdd183df75;hp=45b1c38b491cfadfdba6d3567a73458f38991011 Merge branch 'master' into next --- diff --git a/aacdec.c b/aacdec.c index 4c256946..38f69e88 100644 --- a/aacdec.c +++ b/aacdec.c @@ -183,7 +183,7 @@ static void aacdec_close(struct filter_node *fn) * * \sa filter::init */ -void aacdec_init(struct filter *f) +void aacdec_filter_init(struct filter *f) { f->open = aacdec_open; f->convert = aacdec; diff --git a/amp_filter.c b/amp_filter.c index 750205ba..2f052601 100644 --- a/amp_filter.c +++ b/amp_filter.c @@ -50,20 +50,23 @@ static void amp_close(struct filter_node *fn) free(fn->buf); } -static void *amp_parse_config(int argc, char **argv) +static int amp_parse_config(int argc, char **argv, void **config) { - struct amp_filter_args_info *conf = para_calloc(sizeof(*conf)); + struct amp_filter_args_info *amp_conf = para_calloc(sizeof(*amp_conf)); + int ret = -E_AMP_SYNTAX; - if (amp_cmdline_parser(argc, argv, conf)) + if (amp_cmdline_parser(argc, argv, amp_conf)) goto err; - if (conf->amp_arg < 0) + ret = -ERRNO_TO_PARA_ERROR(EINVAL); + if (amp_conf->amp_arg < 0) goto err; - PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n", conf->amp_arg, - conf->amp_arg / 64.0 + 1.0); - return conf; + PARA_NOTICE_LOG("amplification: %u (scaling factor: %1.2f)\n", + amp_conf->amp_arg, amp_conf->amp_arg / 64.0 + 1.0); + *config = amp_conf; + return 1; err: - free(conf); - return NULL; + free(amp_conf); + return ret; } static void amp_open(struct filter_node *fn) @@ -87,7 +90,7 @@ static void amp_open(struct filter_node *fn) * * \param f Pointer to the struct to initialize. */ -void amp_init(struct filter *f) +void amp_filter_init(struct filter *f) { f->open = amp_open; f->close = amp_close; diff --git a/compress.c b/compress.c index c30c998a..d6f7520d 100644 --- a/compress.c +++ b/compress.c @@ -16,6 +16,7 @@ #include "sched.h" #include "filter.h" #include "string.h" +#include "error.h" /** The size of the output data buffer. */ #define COMPRESS_CHUNK_SIZE 40960 @@ -83,13 +84,21 @@ static void close_compress(struct filter_node *fn) free(fn->buf); } -static void *compress_parse_config(int argc, char **argv) +/** TODO: Add sanity checks */ +static int compress_parse_config(int argc, char **argv, void **config) { - struct compress_filter_args_info *ret = para_calloc(sizeof(struct compress_filter_args_info)); - if (!compress_cmdline_parser(argc, argv, ret)) - return ret; - free(ret); - return NULL; + int ret; + struct compress_filter_args_info *compress_conf + = para_calloc(sizeof(*compress_conf)); + + ret = -E_COMPRESS_SYNTAX; + if (compress_cmdline_parser(argc, argv, compress_conf)) + goto err; + *config = compress_conf; + return 1; +err: + free(compress_conf); + return ret; } static void open_compress(struct filter_node *fn) @@ -109,7 +118,7 @@ static void open_compress(struct filter_node *fn) * * \param f Pointer to the struct to initialize. */ -void compress_init(struct filter *f) +void compress_filter_init(struct filter *f) { f->open = open_compress; f->close = close_compress; diff --git a/configure.ac b/configure.ac index 44924645..cb6ecd65 100644 --- a/configure.ac +++ b/configure.ac @@ -705,6 +705,15 @@ AC_SUBST(fade_objs, add_dot_o($fade_objs)) AC_DEFINE_UNQUOTED(INIT_FADE_ERRLISTS, objlist_to_errlist($fade_errlist_objs), errors used by para_fade) + +enum="$(for i in $filters; do printf "${i}_FILTER, " | tr '[a-z]' '[A-Z]'; done)" +AC_DEFINE_UNQUOTED(FILTER_ENUM, $enum NUM_SUPPORTED_FILTERS, + enum of supported filters) +inits="$(for i in $filters; do printf 'extern void '$i'_filter_init(struct filter *f); '; done)" +AC_DEFINE_UNQUOTED(DECLARE_FILTER_INITS, $inits, init functions of the supported filters) +array="$(for i in $filters; do printf '{.name = \"'$i'\", .init = '$i'_filter_init},'; done)" +AC_DEFINE_UNQUOTED(FILTER_ARRAY, $array, array of supported filters) + enum="$(for i in $writers; do printf "${i}_WRITE, " | tr '[a-z]' '[A-Z]'; done)" AC_DEFINE_UNQUOTED(WRITER_ENUM, $enum NUM_SUPPORTED_WRITERS, enum of supported writers) @@ -715,6 +724,7 @@ inits="$(for i in $writers; do printf 'extern void '$i'_write_init(struct writer AC_DEFINE_UNQUOTED(DECLARE_WRITER_INITS, $inits, init functions of the supported writers) array="$(for i in $writers; do printf '{.init = '$i'_write_init},'; done)" AC_DEFINE_UNQUOTED(WRITER_ARRAY, $array, array of supported writers) + enum="$(for i in $audiod_audio_formats; do printf "AUDIO_FORMAT_${i}, " | tr '[a-z]' '[A-Z]'; done)" AC_DEFINE_UNQUOTED(AUDIOD_AUDIO_FORMATS_ENUM, $enum NUM_AUDIO_FORMATS, enum of audio formats supported by audiod) diff --git a/error.h b/error.h index f0a2510d..cacc83e9 100644 --- a/error.h +++ b/error.h @@ -14,7 +14,6 @@ DEFINE_ERRLIST_OBJECT_ENUM; /* these do not need error handling (yet) */ #define SERVER_ERRORS #define WAV_ERRORS -#define COMPRESS_ERRORS #define TIME_ERRORS #define CLOSE_ON_FORK_ERRORS #define DAEMON_ERRORS @@ -27,13 +26,20 @@ DEFINE_ERRLIST_OBJECT_ENUM; #define RECV_ERRORS #define STDOUT_ERRORS #define IPC_ERRORS -#define AMP_FILTER_ERRORS #define DCCP_SEND_ERRORS #define HTTP_SEND_ERRORS extern const char **para_errlist[]; +#define COMPRESS_ERRORS \ + PARA_ERROR(COMPRESS_SYNTAX, "syntax error in compress filter config"), \ + + +#define AMP_FILTER_ERRORS \ + PARA_ERROR(AMP_SYNTAX, "syntax error in amp filter config"), \ + + #define SEND_COMMON_ERRORS \ PARA_ERROR(MAX_CLIENTS, "maximal number of clients exceeded"), \ @@ -252,6 +258,7 @@ extern const char **para_errlist[]; PARA_ERROR(OGGDEC_BADHEADER, "invalid vorbis bitstream header"), \ PARA_ERROR(OGGDEC_FAULT, "bug or heap/stack corruption"), \ PARA_ERROR(OGGDEC_BADLINK, "invalid stream section or requested link corrupt"), \ + PARA_ERROR(OGGDEC_SYNTAX, "syntax error in oggdec config"), \ #define GRAB_CLIENT_ERRORS \ diff --git a/filter.c b/filter.c index adfadea7..b97bdaaa 100644 --- a/filter.c +++ b/filter.c @@ -121,7 +121,7 @@ static int parse_config(int argc, char *argv[]) if (!conf.list_filters_given) return 1; printf("available filters: "); - for (i = 0; filters[i].name; i++) + 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" diff --git a/filter.h b/filter.h index 8c1c9e0d..2a75b186 100644 --- a/filter.h +++ b/filter.h @@ -6,6 +6,8 @@ /** \file filter.h Filter-related structures and exported symbols from filter_chain.c. */ +/** The list of supported filters. */ +enum filter_enum {FILTER_ENUM}; /** * Describes one running instance of a filter. @@ -191,14 +193,16 @@ struct filter { /** * A pointer to the filter's command line parser. * - * If this optional function pointer is not NULL, any filter options are passed - * from the main program to this command line parser once at application - * startup. The command line parser should check its command line options given - * by \a argc and \a argv and abort on errors. On success, it should return a - * pointer to the filter-specific configuration data determined by \a argc and - * \a argv. + * If this optional function pointer is not NULL, any filter options + * are passed from the main program to this command line parser once at + * application startup. The command line parser should check its + * command line options given by \a argc and \a argv and abort on + * errors. Success must be indicated by a non-negative return value. In + * this case the function should return a pointer to the + * filter-specific configuration data determined by \a argc and \a + * argv. On failure, a negative paraslash error code must be returned. */ - void *(*parse_config)(int argc, char **argv); + int (*parse_config)(int argc, char **argv, void **config); }; void close_filters(struct filter_chain *fc); @@ -218,55 +222,9 @@ static inline void write_int16_host_endian(char *buf, int val) #endif } +DECLARE_FILTER_INITS -/** \cond */ -extern struct filter filters[]; -#define DECLARE_EXTERN_FILTER_INIT(name) \ - extern void name ## _init(struct filter *f) - -#define FILTER_INIT(filter) { \ - .name = #filter, \ - .init = filter ## _init, \ - .parse_config = NULL, \ - .print_help = NULL \ -}, - -/* filters that are always present */ -DECLARE_EXTERN_FILTER_INIT(wav); -DECLARE_EXTERN_FILTER_INIT(compress); -DECLARE_EXTERN_FILTER_INIT(amp); - -/* next the optional filters */ -#ifdef HAVE_MAD -DECLARE_EXTERN_FILTER_INIT(mp3dec); -#define MP3DEC_FILTER FILTER_INIT(mp3dec) -#else -#define MP3DEC_FILTER -#endif - -#ifdef HAVE_FAAD -DECLARE_EXTERN_FILTER_INIT(aacdec); -#define AACDEC_FILTER FILTER_INIT(aacdec) -#else -#define AACDEC_FILTER -#endif - -#ifdef HAVE_OGGVORBIS -DECLARE_EXTERN_FILTER_INIT(oggdec); -#define OGGDEC_FILTER FILTER_INIT(oggdec) -#else -#define OGGDEC_FILTER -#endif -/** \endcond */ - -/** define an array of all available filters */ -#define DEFINE_FILTER_ARRAY(filters) struct filter filters[] = { \ - FILTER_INIT(wav) \ - FILTER_INIT(compress) \ - FILTER_INIT(amp) \ - MP3DEC_FILTER \ - AACDEC_FILTER \ - OGGDEC_FILTER \ - { .name = NULL } }; - +#define FOR_EACH_SUPPORTED_FILTER(j) for (j = 0; j < NUM_SUPPORTED_FILTERS; j++) +/** The filter array, one structure for each supported filter. */ +extern struct filter filters[NUM_SUPPORTED_FILTERS]; diff --git a/filter_chain.c b/filter_chain.c index fa8637ef..0da4533f 100644 --- a/filter_chain.c +++ b/filter_chain.c @@ -17,7 +17,8 @@ #include "error.h" #include "string.h" -DEFINE_FILTER_ARRAY(filters); +/** The array of supported filters. */ +struct filter filters[NUM_SUPPORTED_FILTERS] = {FILTER_ARRAY}; /** * Call the init function of each supported filter. @@ -28,10 +29,10 @@ DEFINE_FILTER_ARRAY(filters); */ void filter_init(struct filter *all_filters) { - struct filter *f; + int i; - for (f = all_filters; f->name; f++) - f->init(f); + FOR_EACH_SUPPORTED_FILTER(i) + all_filters[i].init(all_filters + i); } /** @@ -198,7 +199,7 @@ void close_filters(struct filter_chain *fc) static int parse_filter_args(int filter_num, char *options, void **conf) { struct filter *f = &filters[filter_num]; - int i, argc = 2; + int ret, i, argc = 2; char **argv; // PARA_DEBUG_LOG("%s, options: %s, parser: %p\n", f->name, @@ -212,10 +213,10 @@ static int parse_filter_args(int filter_num, char *options, void **conf) argv[i + 1] = argv[i]; argv[0] = para_strdup(f->name); argc += 1; - *conf = f->parse_config(argc, argv); + ret = f->parse_config(argc, argv, conf); free(argv[0]); free(argv); - return *conf? filter_num : -E_BAD_FILTER_OPTIONS; + return ret < 0? ret : filter_num; } /** @@ -242,7 +243,7 @@ int check_filter_arg(char *fa, void **conf) *conf = NULL; // PARA_DEBUG_LOG("arg: %s\n", fa); - for (j = 0; filters[j].name; j++) { + FOR_EACH_SUPPORTED_FILTER(j) { const char *name = filters[j].name; size_t len = strlen(name); char c; diff --git a/mp3dec.c b/mp3dec.c index 0006a181..599d8a90 100644 --- a/mp3dec.c +++ b/mp3dec.c @@ -126,7 +126,7 @@ static void mp3dec_open(struct filter_node *fn) * * \sa filter::init. */ -void mp3dec_init(struct filter *f) +void mp3dec_filter_init(struct filter *f) { f->open = mp3dec_open; f->convert = mp3dec; diff --git a/oggdec.c b/oggdec.c index e22ea1e4..b4befd01 100644 --- a/oggdec.c +++ b/oggdec.c @@ -163,15 +163,16 @@ static ssize_t ogg_convert(char *inbuffer, size_t len, struct filter_node *fn) return pod->converted; } -static void *oggdec_parse_config(int argc, char **argv) +static int oggdec_parse_config(int argc, char **argv, void **config) { int ret; struct oggdec_filter_args_info *ogg_conf; ogg_conf = para_calloc(sizeof(*ogg_conf)); - ret = oggdec_cmdline_parser(argc, argv, ogg_conf); - if (ret) + ret = -E_OGGDEC_SYNTAX; + if (oggdec_cmdline_parser(argc, argv, ogg_conf)) goto err; + ret = -ERRNO_TO_PARA_ERROR(EINVAL); if (ogg_conf->bufsize_arg < 0) goto err; if (ogg_conf->bufsize_arg >= INT_MAX / 1024) @@ -180,10 +181,11 @@ static void *oggdec_parse_config(int argc, char **argv) goto err; if (ogg_conf->initial_buffer_arg >= INT_MAX / 1024) goto err; - return ogg_conf; + *config = ogg_conf; + return 1; err: free(ogg_conf); - return NULL; + return ret; } /** @@ -191,7 +193,7 @@ err: * * \param f Its fields are filled in by the function. */ -void oggdec_init(struct filter *f) +void oggdec_filter_init(struct filter *f) { f->open = ogg_open; f->close = ogg_close; diff --git a/wav.c b/wav.c index c03c21dc..ad3458d1 100644 --- a/wav.c +++ b/wav.c @@ -113,7 +113,7 @@ static void wav_open(struct filter_node *fn) * * \param f struct to initialize */ -void wav_init(struct filter *f) +void wav_filter_init(struct filter *f) { f->convert = wav_convert; f->close = wav_close;