//roarpluginrunner.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011 * * This file is part of roarclients a part of RoarAudio, * a cross-platform sound system for both, home and professional use. * See README for details. * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 * as published by the Free Software Foundation. * * RoarAudio 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. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ int g_verbose = 0; #define ROAR_DBG_INFOVAR g_verbose #include enum action { RUN, EXPLAIN }; static struct roar_dl_librarypara * g_para = NULL; void usage (const char * progname) { fprintf(stderr, "Usage: %s [OPTIONS]... PLUGIN\n", progname); fprintf(stderr, "\nOptions:\n\n"); fprintf(stderr, " -h --help - This help.\n" " --verbose - Be verbose. Can be used multiple times.\n" " --run - Run plugin.\n" " --explain - Explain plugin.\n"); } static int do_run(const char * name) { struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, g_para); if ( lhandle == NULL ) return -1; roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_INIT); while (roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_WAIT) == 0) roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_UPDATE); roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_UPDATE); roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_FREE); roar_dl_unref(lhandle); return 0; } static const char * _ptr2str(const void * p) { static char buf[24]; if ( p == NULL ) return ""; snprintf(buf, sizeof(buf), "%p", p); return buf; } static const char * _ptrrange2str(const void * p, size_t len) { static char buf[48]; if ( p == NULL ) return ""; if ( len == 0 ) return _ptr2str(p); snprintf(buf, sizeof(buf), "%p-%p", p, p + len); return buf; } static int do_explain(const char * name) { struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 0, NULL); struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para); struct roar_dl_libraryinst * lib; int libok = 0, libnameok = 0; int tmp; int i; if ( lhandle == NULL ) return -1; func = roar_dl_getsym(lhandle, "_roaraudio_library_init", -1); if ( func == NULL ) { fprintf(stderr, "Warning: Not a RA lib: %s\n", name); roar_dl_unref(lhandle); return 0; } lib = func(g_para); if ( lib == NULL ) { fprintf(stderr, "Warning: Can not RA init: %s\n", name); roar_dl_unref(lhandle); return 0; } if ( lib->version == ROAR_DL_LIBINST_VERSION && lib->len == sizeof(*lib) ) { libok = 1; } printf("lib = %s\n", _ptr2str(lib)); printf("|-> version = %i (%smatch)\n", lib->version, lib->version == ROAR_DL_LIBINST_VERSION ? "" : "no "); printf("%c-> len = %zu (%smatch)\n", libok ? '|' : '\\', lib->len, lib->len == sizeof(*lib) ? "" : "no "); if ( libok ) { printf("|-> unload = %s\n", _ptr2str(lib->unload)); printf("|-> func = {"); for (i = 0, tmp = 0; i < ROAR_DL_FN_MAX; i++) { if ( lib->func[i] != NULL ) { tmp = 1; break; } } if ( tmp ) { for (i = 0; i < ROAR_DL_FN_MAX; i++) printf("%s%s", _ptr2str(lib->func[i]), i < (ROAR_DL_FN_MAX-1) ? ", " : ""); } else { printf("%i x ", (int)ROAR_DL_FN_MAX); } printf("}\n"); printf("|-> libname = %s\n", _ptr2str(lib->libname)); if ( lib->libname != NULL ) { if ( lib->libname->version == ROAR_DL_LIBNAME_VERSION && lib->libname->len == sizeof(*(lib->libname)) ) { libnameok = 1; } printf("| |-> version = %i (%smatch)\n", lib->libname->version, lib->libname->version == ROAR_DL_LIBNAME_VERSION ? "" : "no "); printf("| %c-> len = %zu (%smatch)\n", libnameok ? '|' : '\\', lib->libname->len, lib->libname->len == sizeof(*(lib->libname)) ? "" : "no "); if ( libnameok ) { #define _ps(c,name) \ tmp = (lib->libname->name) != NULL; \ printf("| %c-> %-15s = %s%s%s\n", (c), #name, tmp ? "\"" : "", \ tmp ? (lib->libname->name) : "", tmp ? "\"" : ""); _ps('|', name); _ps('|', libname); _ps('|', libversion); _ps('|', abiversion); _ps('|', description); _ps('|', contact); _ps('|', authors); _ps('\\', license); #undef _ps } } printf("|-> global_data_len = %zu\n", lib->global_data_len); printf("|-> global_data_init = %s\n", _ptrrange2str(lib->global_data_init, lib->global_data_len)); printf("|-> global_data_pointer = %s\n", _ptr2str(lib->global_data_pointer)); printf("|-> libdep = %s\n", _ptr2str(lib->libdep)); printf("|-> libdep_len = %zu\n", lib->libdep_len); printf("\\-> appsched = %s\n", _ptr2str(lib->appsched)); if ( lib->appsched != NULL ) { printf(" |-> init = %s\n", _ptr2str(lib->appsched->init)); printf(" |-> free = %s\n", _ptr2str(lib->appsched->free)); printf(" |-> update = %s\n", _ptr2str(lib->appsched->update)); printf(" |-> tick = %s\n", _ptr2str(lib->appsched->tick)); printf(" \\-> wait = %s\n", _ptr2str(lib->appsched->wait)); } } roar_dl_unref(lhandle); return 0; } static int do_plugin(enum action action, const char * name) { switch (action) { case EXPLAIN: return do_explain(name); break; case RUN: return do_run(name); break; default: roar_err_set(ROAR_ERROR_BADRQC); return -1; break; } } static inline void _clear_para(void) { if ( g_para == NULL ) return; roar_dl_para_unref(g_para); g_para = NULL; } int main (int argc, char * argv[]) { const char * appname = "roarpluginrunner"; const char * abiversion = NULL; const char * pluginargs = NULL; enum action action = RUN; int ret = 0; int i; char * k; for (i = 1; i < argc; i++) { k = argv[i]; if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) { usage(argv[0]); return 0; } else if ( !strcmp(k, "--run") ) { action = RUN; } else if ( !strcmp(k, "--explain") ) { action = EXPLAIN; } else if ( !strcmp(k, "--verbose") ) { g_verbose++; } else if ( !strcmp(k, "--appname") ) { appname = argv[++i]; _clear_para(); } else if ( !strcmp(k, "--abiversion") ) { abiversion = argv[++i]; _clear_para(); } else if ( !strcmp(k, "--args") ) { pluginargs = argv[++i]; _clear_para(); } else { if ( g_para == NULL ) g_para = roar_dl_para_new(pluginargs, NULL, appname, abiversion); roar_err_set(ROAR_ERROR_NONE); if ( do_plugin(action, k) == -1 ) { fprintf(stderr, "Error loading plugin: %s\n", roar_error != ROAR_ERROR_NONE ? roar_error2str(roar_error) : roar_dl_errstr(NULL)); ret = 1; } } } _clear_para(); return ret; } //ll