From fab9febdc3a863c157a56cc4de2418cbb9665844 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Sun, 9 Dec 2012 15:05:21 +0100 Subject: path: add mp_find_config_file and reorganize some of the code Add `mp_find_config_file` to search different known paths and use that in ass_mp to look for the fontconfig configuration file. Some incidental changes spawned by this feature where: * Buffer allocation for the strings containing the paths is now performed with talloc. All of the allocations are done on a NULL context, but it still improves readability of the code. * Move the OSX function for lookup inside of a bundle: this code path was currently not used by the bundle generated with `make osxbundle`. The plan is to use it again in a future commit to get a fontconfig config file. --- Makefile | 1 + audio/filter/af_export.c | 13 ++--- configure | 1 + core/input/input.c | 7 +-- core/mplayer.c | 15 +++--- core/path.c | 130 ++++++++++++++++++++--------------------------- core/path.h | 12 ++++- osdep/macosx_bundle.h | 26 ++++++++++ osdep/macosx_bundle.m | 30 +++++++++++ stream/stream_cddb.c | 6 ++- stream/stream_dvb.c | 63 ++++++++++++----------- sub/ass_mp.c | 19 +++---- sub/find_subfiles.c | 4 +- 13 files changed, 190 insertions(+), 137 deletions(-) create mode 100644 osdep/macosx_bundle.h create mode 100644 osdep/macosx_bundle.m diff --git a/Makefile b/Makefile index db41f6d4e2..9999145c83 100644 --- a/Makefile +++ b/Makefile @@ -46,6 +46,7 @@ SOURCES-$(LIBPOSTPROC) += video/filter/vf_pp.c SOURCES-$(LIBSMBCLIENT) += stream/stream_smb.c SOURCES-$(MACOSX_FINDER) += osdep/macosx_finder_args.m +SOURCES-$(MACOSX_BUNDLE) += osdep/macosx_bundle.m SOURCES-$(COCOA) += video/out/osx_common.m \ video/out/cocoa_common.m \ osdep/cocoa_events.m diff --git a/audio/filter/af_export.c b/audio/filter/af_export.c index 2687904ebd..5e3a1869ee 100644 --- a/audio/filter/af_export.c +++ b/audio/filter/af_export.c @@ -37,6 +37,7 @@ #include #include +#include "talloc.h" #include "af.h" #include "core/path.h" @@ -138,18 +139,18 @@ static int control(struct af_instance* af, int cmd, void* arg) char *str = arg; if (!str){ - free(s->filename); + talloc_free(s->filename); - s->filename = get_path(SHARED_FILE); + s->filename = mp_find_user_config_file(SHARED_FILE); return AF_OK; } while((str[i]) && (str[i] != ':')) i++; - free(s->filename); + talloc_free(s->filename); - s->filename = calloc(i + 1, 1); + s->filename = talloc_array_size(NULL, 1, i + 1); memcpy(s->filename, str, i); s->filename[i] = 0; @@ -192,7 +193,7 @@ static void uninit( struct af_instance* af ) if(s->fd > -1) close(s->fd); - free(s->filename); + talloc_free(s->filename); free(af->setup); af->setup = NULL; @@ -259,7 +260,7 @@ static int af_open( struct af_instance* af ) if((af->data == NULL) || (af->setup == NULL)) return AF_ERROR; - ((af_export_t *)af->setup)->filename = get_path(SHARED_FILE); + ((af_export_t *)af->setup)->filename = mp_find_user_config_file(SHARED_FILE); return AF_OK; } diff --git a/configure b/configure index cfde6d4f2d..4043df9943 100755 --- a/configure +++ b/configure @@ -3187,6 +3187,7 @@ LIBQUVI = $_libquvi LIBTHEORA = $_theora LIRC = $_lirc MACOSX_FINDER = $_macosx_finder +MACOSX_BUNDLE = $_macosx_bundle MNG = $_mng MPG123 = $_mpg123 NETWORKING = $networking diff --git a/core/input/input.c b/core/input/input.c index 6d60211e65..1ee1ff909a 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -1794,7 +1794,8 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf) char *file; char *config_file = input_conf->config_file; - file = config_file[0] != '/' ? get_path(config_file) : config_file; + file = config_file[0] != '/' ? + mp_find_user_config_file(config_file) : config_file; if (!file) return ictx; @@ -1802,7 +1803,7 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf) // free file if it was allocated by get_path(), // before it gets overwritten if (file != config_file) - free(file); + talloc_free(file); // Try global conf dir file = MPLAYER_CONFDIR "/input.conf"; if (!parse_config_file(ictx, file)) @@ -1811,7 +1812,7 @@ struct input_ctx *mp_input_init(struct input_conf *input_conf) } else { // free file if it was allocated by get_path() if (file != config_file) - free(file); + talloc_free(file); } #ifdef CONFIG_JOYSTICK diff --git a/core/mplayer.c b/core/mplayer.c index c68c4f3dc2..c57062517d 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -702,13 +702,14 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf) if (!(opts->noconfig & 2) && m_config_parse_config_file(conf, MPLAYER_CONFDIR "/mpv.conf") < 0) return false; - if ((conffile = get_path("")) == NULL) + if ((conffile = mp_find_user_config_file("")) == NULL) mp_tmsg(MSGT_CPLAYER, MSGL_WARN, "Cannot find HOME directory.\n"); else { mkdir(conffile, 0777); - free(conffile); - if ((conffile = get_path("config")) == NULL) - mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "get_path(\"config\") problem\n"); + talloc_free(conffile); + if ((conffile = mp_find_user_config_file("config")) == NULL) + mp_tmsg(MSGT_CPLAYER, MSGL_ERR, + "mp_find_user_config_file(\"config\") problem\n"); else { if ((conffile_fd = open(conffile, O_CREAT | O_EXCL | O_WRONLY, 0666)) != -1) { @@ -720,7 +721,7 @@ static bool parse_cfgfiles(struct MPContext *mpctx, m_config_t *conf) if (!(opts->noconfig & 1) && m_config_parse_config_file(conf, conffile) < 0) return false; - free(conffile); + talloc_free(conffile); } } return true; @@ -826,10 +827,10 @@ static void load_per_file_config(m_config_t *conf, const char * const file) return; } - if ((confpath = get_path(name)) != NULL) { + if ((confpath = mp_find_user_config_file(name)) != NULL) { try_load_config(conf, confpath); - free(confpath); + talloc_free(confpath); } } diff --git a/core/path.c b/core/path.c index 3a2d4c09ba..ed53d5d465 100644 --- a/core/path.c +++ b/core/path.c @@ -23,6 +23,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include #include @@ -33,51 +34,63 @@ #include "config.h" #include "core/mp_msg.h" #include "core/path.h" +#include "talloc.h" +#include "osdep/io.h" -#ifdef CONFIG_MACOSX_BUNDLE -#include -#include -#elif defined(__MINGW32__) +#if defined(__MINGW32__) #include #elif defined(__CYGWIN__) #include #include #endif -#include "talloc.h" +#ifdef CONFIG_MACOSX_BUNDLE +#include "osdep/macosx_bundle.h" +#endif -#include "osdep/io.h" -char *get_path(const char *filename) +typedef char *(*lookup_fun)(const char *); +static const lookup_fun config_lookup_functions[] = { + mp_find_user_config_file, +#ifdef CONFIG_MACOSX_BUNDLE + get_bundled_path, +#endif + mp_find_global_config_file, + NULL +}; + +char *mp_find_config_file(const char *filename) { - char *homedir; - char *buff; + for (int i = 0; config_lookup_functions[i] != NULL; i++) { + char *path = config_lookup_functions[i](filename); + if (!path) continue; + + if (mp_path_exists(path)) + return path; + + talloc_free(path); + } + return NULL; +} + +char *mp_find_user_config_file(const char *filename) +{ + char *homedir = NULL, *buff = NULL; #ifdef __MINGW32__ - static char *config_dir = "/mpv"; + static char *config_dir = "mpv"; #else - static char *config_dir = "/.mpv"; + static char *config_dir = ".mpv"; #endif #if defined(__MINGW32__) || defined(__CYGWIN__) char exedir[260]; #endif - int len; -#ifdef CONFIG_MACOSX_BUNDLE - struct stat dummy; - CFIndex maxlen = 256; - CFURLRef res_url_ref = NULL; - CFURLRef bdl_url_ref = NULL; - char *res_url_path = NULL; - char *bdl_url_path = NULL; -#endif - - if ((homedir = getenv("MPV_HOME")) != NULL) + if ((homedir = getenv("MPV_HOME")) != NULL) { config_dir = ""; - else if ((homedir = getenv("HOME")) == NULL) + } else if ((homedir = getenv("HOME")) == NULL) { #if defined(__MINGW32__) || defined(__CYGWIN__) /* Hack to get fonts etc. loaded outside of Cygwin environment. */ - { int i, imax = 0; - len = (int)GetModuleFileNameA(NULL, exedir, 260); + int len = (int)GetModuleFileNameA(NULL, exedir, 260); for (i = 0; i < len; i++) if (exedir[i] == '\\') { exedir[i] = '/'; @@ -85,67 +98,32 @@ char *get_path(const char *filename) } exedir[imax] = '\0'; homedir = exedir; - } #else return NULL; #endif - len = strlen(homedir) + strlen(config_dir) + 1; - if (filename == NULL) { - if ((buff = malloc(len)) == NULL) - return NULL; - sprintf(buff, "%s%s", homedir, config_dir); - } else { - len += strlen(filename) + 1; - if ((buff = malloc(len)) == NULL) - return NULL; - sprintf(buff, "%s%s/%s", homedir, config_dir, filename); } -#ifdef CONFIG_MACOSX_BUNDLE - if (stat(buff, &dummy)) { - - res_url_ref = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - bdl_url_ref = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - - if (res_url_ref && bdl_url_ref) { - - res_url_path = malloc(maxlen); - bdl_url_path = malloc(maxlen); - - while (!CFURLGetFileSystemRepresentation(res_url_ref, true, - res_url_path, maxlen)) { - maxlen *= 2; - res_url_path = realloc(res_url_path, maxlen); - } - CFRelease(res_url_ref); - - while (!CFURLGetFileSystemRepresentation(bdl_url_ref, true, - bdl_url_path, maxlen)) { - maxlen *= 2; - bdl_url_path = realloc(bdl_url_path, maxlen); - } - CFRelease(bdl_url_ref); - - if (strcmp(res_url_path, bdl_url_path) == 0) - res_url_path = NULL; - } - - if (res_url_path && filename) { - if ((strlen(filename) + strlen(res_url_path) + 2) > maxlen) - maxlen = strlen(filename) + strlen(res_url_path) + 2; - free(buff); - buff = malloc(maxlen); - strcpy(buff, res_url_path); - - strcat(buff, "/"); - strcat(buff, filename); - } + if (filename) { + char * temp = mp_path_join(NULL, bstr0(homedir), bstr0(config_dir)); + buff = mp_path_join(NULL, bstr0(temp), bstr0(filename)); + talloc_free(temp); + } else { + buff = mp_path_join(NULL, bstr0(homedir), bstr0(config_dir)); } -#endif + mp_msg(MSGT_GLOBAL, MSGL_V, "get_path('%s') -> '%s'\n", filename, buff); return buff; } +char *mp_find_global_config_file(const char *filename) +{ + if (filename) { + return mp_path_join(NULL, bstr0(MPLAYER_CONFDIR), bstr0(filename)); + } else { + return talloc_strdup(NULL, MPLAYER_CONFDIR); + } +} + char *mp_basename(const char *path) { char *s; diff --git a/core/path.h b/core/path.h index 0c7dbcca41..3711be44b9 100644 --- a/core/path.h +++ b/core/path.h @@ -24,7 +24,17 @@ #include #include "core/bstr.h" -char *get_path(const char *filename); + +// Search for the input filename in several paths. These include user and global +// config locations by default. Some platforms may implement additional platform +// related lookups (i.e.: OSX inside an application bundle). +char *mp_find_config_file(const char *filename); + +// Search for the input filename in the global configuration location. +char *mp_find_global_config_file(const char *filename); + +// Search for the input filename in the user configuration location. +char *mp_find_user_config_file(const char *filename); // Return pointer to filename part of path diff --git a/osdep/macosx_bundle.h b/osdep/macosx_bundle.h new file mode 100644 index 0000000000..fbb3383ad5 --- /dev/null +++ b/osdep/macosx_bundle.h @@ -0,0 +1,26 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPV_MACOSX_BUNDLE +#define MPV_MACOSX_BUNDLE + +// Returns absolute path of a resource file in a Mac OS X application bundle. +char *get_bundled_path(const char *filename); + +#endif /* MPV_MACOSX_BUNDLE */ + diff --git a/osdep/macosx_bundle.m b/osdep/macosx_bundle.m new file mode 100644 index 0000000000..cef0fc550a --- /dev/null +++ b/osdep/macosx_bundle.m @@ -0,0 +1,30 @@ +/* + * This file is part of mpv. + * + * mpv 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. + * + * mpv 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 mpv; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#import +#include "osdep/macosx_bundle.h" +#include "core/path.h" + +char *get_bundled_path(const char *file) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSString *path = [[NSBundle mainBundle] resourcePath]; + char *rv = mp_path_join(NULL, bstr0([path UTF8String]), bstr0(file)); + [pool release]; + return rv; +} diff --git a/stream/stream_cddb.c b/stream/stream_cddb.c index 2fc4335b68..f0f8f67155 100644 --- a/stream/stream_cddb.c +++ b/stream/stream_cddb.c @@ -717,6 +717,7 @@ int cddb_resolve(const char *dev, char **xmcd_file) char cddb_cache_dir[] = DEFAULT_CACHE_DIR; char *home_dir = NULL; cddb_data_t cddb_data; + void *talloc_ctx = talloc_new(NULL); if (cdtoc_last_track <= 0) { cdtoc_last_track = read_toc(dev); @@ -747,7 +748,8 @@ int cddb_resolve(const char *dev, char **xmcd_file) home_dir = getenv("HOMEPATH"); // Last resort, store the cddb cache in the mplayer directory if (home_dir == NULL) - home_dir = (char *)get_path(""); + home_dir = (char *)talloc_steal(talloc_ctx, + mp_find_user_config_file("")); #endif if (home_dir == NULL) { cddb_data.cache_dir = NULL; @@ -756,10 +758,12 @@ int cddb_resolve(const char *dev, char **xmcd_file) cddb_data.cache_dir = malloc(len); if (cddb_data.cache_dir == NULL) { mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Memory allocation failed.\n"); + talloc_free(talloc_ctx); return -1; } snprintf(cddb_data.cache_dir, len, "%s%s", home_dir, cddb_cache_dir); } + talloc_free(talloc_ctx); // Check for a cached file if (cddb_read_cache(&cddb_data) < 0) { diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index 6a73e5db42..7cbd690ee6 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -777,36 +777,41 @@ dvb_config_t *dvb_get_config(void) continue; } - conf_file = get_path("channels.conf"); - switch(type) - { - case TUNER_TER: - conf_file = get_path("channels.conf.ter"); - break; - case TUNER_CBL: - conf_file = get_path("channels.conf.cbl"); - break; - case TUNER_SAT: - conf_file = get_path("channels.conf.sat"); - break; - case TUNER_ATSC: - conf_file = get_path("channels.conf.atsc"); - break; - } - - if((access(conf_file, F_OK | R_OK) != 0)) - { - free(conf_file); - conf_file = get_path("channels.conf"); - if((access(conf_file, F_OK | R_OK) != 0)) - { - free(conf_file); - conf_file = strdup(MPLAYER_CONFDIR "/channels.conf"); - } - } + void *talloc_ctx = talloc_new(NULL); + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf")); + switch(type) { + case TUNER_TER: + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf.ter")); + break; + case TUNER_CBL: + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf.cbl")); + break; + case TUNER_SAT: + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf.sat")); + break; + case TUNER_ATSC: + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf.atsc")); + break; + } + + if((access(conf_file, F_OK | R_OK) != 0)) { + conf_file = talloc_steal(talloc_ctx, + mp_find_user_config_file("channels.conf")); + + if((access(conf_file, F_OK | R_OK) != 0)) { + conf_file = talloc_steal(talloc_ctx, + mp_find_global_config_file("channels.conf")); + } + } + + list = dvb_get_channels(conf_file, type); + talloc_free(talloc_ctx); - list = dvb_get_channels(conf_file, type); - free(conf_file); if(list == NULL) continue; diff --git a/sub/ass_mp.c b/sub/ass_mp.c index 36e03fb2d6..c992f017f7 100644 --- a/sub/ass_mp.c +++ b/sub/ass_mp.c @@ -255,23 +255,18 @@ void mp_ass_configure(ASS_Renderer *priv, struct MPOpts *opts, void mp_ass_configure_fonts(ASS_Renderer *priv, struct osd_style_opts *opts) { - char *default_font = get_path("subfont.ttf"); - char *config = get_path("fonts.conf"); + char *default_font = mp_find_user_config_file("subfont.ttf"); + char *config = mp_find_config_file("fonts.conf"); if (!mp_path_exists(default_font)) { - free(default_font); + talloc_free(default_font); default_font = NULL; } - if (!mp_path_exists(config)) { - free(config); - config = NULL; - } - ass_set_fonts(priv, default_font, opts->font, 1, config, 1); - free(default_font); - free(config); + talloc_free(default_font); + talloc_free(config); } void mp_ass_render_frame(ASS_Renderer *renderer, ASS_Track *track, double time, @@ -332,11 +327,11 @@ static void message_callback(int level, const char *format, va_list va, void *ct ASS_Library *mp_ass_init(struct MPOpts *opts) { ASS_Library *priv; - char *path = get_path("fonts"); + char *path = mp_find_user_config_file("fonts"); priv = ass_library_init(); ass_set_message_cb(priv, message_callback, NULL); ass_set_fonts_dir(priv, path); ass_set_extract_fonts(priv, opts->use_embedded_fonts); - free(path); + talloc_free(path); return priv; } diff --git a/sub/find_subfiles.c b/sub/find_subfiles.c index 95004b564f..aa8df2ea49 100644 --- a/sub/find_subfiles.c +++ b/sub/find_subfiles.c @@ -212,10 +212,10 @@ char **find_text_subtitles(struct MPOpts *opts, const char *fname) } // Load subtitles in ~/.mplayer/sub limiting sub fuzziness - char *mp_subdir = get_path("sub/"); + char *mp_subdir = mp_find_user_config_file("sub/"); if (mp_subdir) append_dir_subtitles(opts, &slist, &n, bstr0(mp_subdir), fname, 1); - free(mp_subdir); + talloc_free(mp_subdir); // Sort subs by priority and append them qsort(slist, n, sizeof(*slist), compare_sub_priority); -- cgit v1.2.3