ref: 48d4c6c3b9c56f16f5227754fd93d3b1cb004647
parent: f9c7137a5e8469a19b7d81d97d9dbbf9ca3d2b38
author: rrt <rrt>
date: Fri May 4 19:26:36 EDT 2007
Load format modules properly dynamically, by scanning the directory, and remove the compile-time list from handlers.c. Fix copyright notice in sox.c to refer to "program" rather than "library". Especially confusing as it was correct about the GPL rather than the LPGL!
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -9,97 +9,9 @@
#include "sox_i.h"
-/*
- * libSoX file format and effect tables.
- */
-
-#define PLUGIN(module) {#module, NULL}
-
-/* File format handlers. */
-sox_format_tab_t sox_format_fns[] = {
- /* Built-in formats */
- PLUGIN(auto),
-
- /* Raw file formats */
- PLUGIN(raw),
- PLUGIN(s1),
- PLUGIN(s2),
- PLUGIN(s3),
- PLUGIN(s4),
- PLUGIN(u1),
- PLUGIN(u2),
- PLUGIN(u3),
- PLUGIN(u4),
- PLUGIN(al),
- PLUGIN(la),
- PLUGIN(ul),
- PLUGIN(lu),
-
- /* Plugin file formats */
- PLUGIN(aiff),
- PLUGIN(aifc),
-#ifdef HAVE_LIBAMRWB
- PLUGIN(amr_wb),
-#endif
- PLUGIN(au),
- PLUGIN(avr),
- PLUGIN(cdr),
- PLUGIN(cvsd),
- PLUGIN(dvms),
- PLUGIN(dat),
-#ifdef HAVE_LIBAVPLUGIN
- PLUGIN(ffmpeg),
-#endif
-#ifdef HAVE_LIBFLAC
- PLUGIN(flac),
-#endif
- PLUGIN(gsm),
- PLUGIN(hcom),
- PLUGIN(lpc10),
- PLUGIN(maud),
-#if defined(HAVE_LIBMAD) || defined(HAVE_LIBMP3LAME)
- PLUGIN(mp3),
-#endif
- PLUGIN(nul),
- PLUGIN(prc),
- PLUGIN(sf),
- PLUGIN(smp),
- PLUGIN(sndrtool),
- PLUGIN(sphere),
- PLUGIN(svx),
- PLUGIN(txw),
- PLUGIN(voc),
-#if defined HAVE_LIBVORBISENC && defined HAVE_LIBVORBISFILE
- PLUGIN(vorbis),
-#endif
- PLUGIN(vox),
- PLUGIN(ima),
- PLUGIN(wav),
- PLUGIN(wve),
- PLUGIN(xa),
- /* Prefer internal formats over libsndfile by placing sndfile last
- Can be overridden by using -t sndfile. */
-#ifdef HAVE_SNDFILE_H
- PLUGIN(sndfile),
-#endif
-
- /* I/O formats */
-#ifdef HAVE_ALSA
- PLUGIN(alsa),
-#endif
-#ifdef HAVE_LIBAO
- PLUGIN(ao),
-#endif
-#ifdef HAVE_OSS
- PLUGIN(oss),
-#endif
-#ifdef HAVE_SUN_AUDIO
- PLUGIN(sun),
-#endif
-
- /* End marker */
- {NULL, NULL}
-};
+#define MAX_FORMATS 256
+unsigned sox_formats = 0;
+sox_format_tab_t sox_format_fns[MAX_FORMATS];
/* Effects handlers. */
--- a/src/sox.c
+++ b/src/sox.c
@@ -6,12 +6,12 @@
* Copyright 1991 Lance Norskog And Sundry Contributors
* Copyright 1998-2007 Chris Bagnall and SoX contributors
*
- * This library is free software; you can redistribute it and/or
+ * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
@@ -58,7 +58,7 @@
#endif
static sox_bool play = sox_false, rec = sox_false;
-static plugins_initted = sox_false;
+static sox_bool plugins_initted = sox_false;
static enum {sox_sequence, sox_concatenate, sox_mix, sox_merge} combine_method = sox_concatenate;
static sox_size_t mixing_clips = 0;
static sox_bool repeatable_random = sox_false; /* Whether to invoke srand. */
@@ -446,10 +446,32 @@
}
}
-static void init_plugins(void)
+#define MAX_NAME_LEN 1024
+static int init_format(const char *file, lt_ptr data)
{
+ lt_dlhandle lth = lt_dlopenext(file);
+ char *end = file + strlen(file);
+ const char prefix[] = "libsox_fmt_";
+ char fnname[MAX_NAME_LEN];
+ char *start = strstr(file, prefix) + sizeof(prefix) - 1;
+
+ (void)data;
+ if (start < end) {
+ int ret = snprintf(fnname, MAX_NAME_LEN, "sox_%.*s_format_fn", end - start, start);
+ if (ret > 0 && ret < MAX_NAME_LEN) {
+ sox_format_fns[sox_formats].fn = (sox_format_fn_t)lt_dlsym(lth, fnname);
+ sox_debug("opening format plugin `%s': library %p, entry point %p\n", fnname, lth, sox_format_fns[sox_formats].fn);
+ sox_formats++;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void find_formats(void)
+{
int ret;
- size_t i;
if ((ret = lt_dlinit()) != 0) {
sox_fail("lt_dlinit failed with %d error(s): %s", ret, lt_dlerror());
@@ -457,23 +479,7 @@
}
plugins_initted = sox_true;
- for (i = 0; sox_format_fns[i].name || sox_format_fns[i].fn; i++) {
- if (sox_format_fns[i].name) { /* Try to load plugin */
-#define MAX_NAME_LEN 1024
- char name[MAX_NAME_LEN];
- int sn = snprintf(name, MAX_NAME_LEN, PKGLIBDIR "/libsox_fmt_%s.la", sox_format_fns[i].name);
-
- if (sn < MAX_NAME_LEN) {
- char fnname[MAX_NAME_LEN];
- lt_dlhandle lth = lt_dlopen(name);
-
- snprintf(fnname, MAX_NAME_LEN, "sox_%s_format_fn", sox_format_fns[i].name);
- sox_format_fns[i].fn = (sox_format_fn_t)lt_dlsym(lth, fnname);
- sox_debug("opening format plugin `%s': library %p, entry point %p\n", name, lth, sox_format_fns[i].fn);
- }
- } else
- sox_debug("opening builtin format `%s': entry point %p\n", sox_format_fns[i].fn()->names[0], sox_format_fns[i].fn);
- }
+ lt_dlforeachfile(PKGLIBDIR, init_format, NULL);
}
int main(int argc, char **argv)
@@ -500,7 +506,7 @@
/* Load plugins (after options so we can output debugging messages
if desired) */
- init_plugins();
+ find_formats();
/* Allocate buffers, size of which may have been set by --buffer */
ibufl = xcalloc(sox_bufsiz / 2, sizeof(sox_ssample_t));
@@ -1948,7 +1954,7 @@
"\n");
printf("SUPPORTED FILE FORMATS:");
- for (i = 0, formats = 0; sox_format_fns[i].name || sox_format_fns[i].fn; i++) {
+ for (i = 0, formats = 0; i < sox_formats; i++) {
if (sox_format_fns[i].fn) {
char const * const *names = sox_format_fns[i].fn()->names;
while (*names++)
@@ -1957,7 +1963,7 @@
}
formats += 2;
format_list = (const char **)xmalloc(formats * sizeof(char *));
- for (i = 0, formats = 0; sox_format_fns[i].name || sox_format_fns[i].fn; i++) {
+ for (i = 0, formats = 0; i < sox_formats; i++) {
if (sox_format_fns[i].fn) {
char const * const *names = sox_format_fns[i].fn()->names;
while (*names)
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -64,6 +64,11 @@
sox_bool is_uri(char const * text);
FILE * xfopen(char const * identifier, char const * mode);
+/* Function we supply if it's missing from system libc */
+#ifndef HAVE_STRRSTR
+char *strrstr(const char *s, const char *t);
+#endif
+
/* Define fseeko and ftello for platforms lacking them */
#ifndef HAVE_FSEEKO
#define fseeko fseek
@@ -226,6 +231,7 @@
sox_format_fn_t fn;
} sox_format_tab_t;
+extern unsigned sox_formats;
extern sox_format_tab_t sox_format_fns[];
const sox_format_t *sox_auto_format_fn(void);
--- a/src/sunaudio.c
+++ b/src/sunaudio.c
@@ -309,13 +309,13 @@
}
/* Sun /dev/audio player */
-static const char *sunnames[] = {
+static const char *names[] = {
"sunau",
NULL
};
-static sox_format_t sox_sun_format = {
- sunnames,
+static sox_format_t sox_sunau_format = {
+ names,
SOX_FILE_DEVICE,
sox_sunstartread,
sox_rawread,
@@ -326,11 +326,11 @@
sox_format_nothing_seek
};
-const sox_format_t *sox_sun_format_fn(void);
+const sox_format_t *sox_sunau_format_fn(void);
-const sox_format_t *sox_sun_format_fn(void)
+const sox_format_t *sox_sunau_format_fn(void)
{
- return &sox_sun_format;
+ return &sox_sunau_format;
}
#endif
--- a/src/util.c
+++ b/src/util.c
@@ -123,8 +123,8 @@
sox_fail_errno(formp, SOX_EFMT, "Filetype was not specified");
return SOX_EFMT;
}
- for (i = 0; sox_format_fns[i].fn || sox_format_fns[i].name; i++) {
- /* FIXME: make this code easier to write */
+ for (i = 0; i < sox_formats; i++) {
+ /* FIXME: add only non-NULL formats to the list */
if (sox_format_fns[i].fn) {
const sox_format_t *f = sox_format_fns[i].fn();
if (is_file_extension && (f->flags & SOX_FILE_DEVICE))