# HG changeset patch # User Mike Pavone # Date 1383022126 25200 # Node ID 6fc71114d145e47aa6672e740fb13345c151eaf9 # Parent 39cad98d27892008f706ab37d76549db1679721d Extract function to determine executable directory from load_config so it can be used elsewhere diff -r 39cad98d2789 -r 6fc71114d145 blastem.c --- a/blastem.c Mon Oct 28 19:37:30 2013 -0700 +++ b/blastem.c Mon Oct 28 21:48:46 2013 -0700 @@ -11,6 +11,7 @@ #include "render.h" #include "blastem.h" #include "gst.h" +#include "util.h" #include #include #include @@ -1762,7 +1763,8 @@ fputs("Usage: blastem [OPTIONS] ROMFILE [WIDTH] [HEIGHT]\n", stderr); return 1; } - config = load_config(argv[0]); + set_exe_str(argv[0]); + config = load_config(); detect_region(); int width = -1; int height = -1; diff -r 39cad98d2789 -r 6fc71114d145 config.c --- a/config.c Mon Oct 28 19:37:30 2013 -0700 +++ b/config.c Mon Oct 28 21:48:46 2013 -0700 @@ -9,10 +9,6 @@ #include #include -#include -#include -#include - #define MAX_NEST 30 //way more than I'll ever need tern_node * parse_config(char * config_data) @@ -102,32 +98,9 @@ return ret; } -char * readlink_alloc(char * path) +tern_node * load_config() { - char * linktext = NULL; - ssize_t linksize = 512; - ssize_t cursize = 0; - do { - if (linksize > cursize) { - cursize = linksize; - if (linktext) { - free(linktext); - } - } - linktext = malloc(cursize); - linksize = readlink(path, linktext, cursize-1); - if (linksize == -1) { - perror("readlink"); - free(linktext); - linktext = NULL; - } - } while (linksize > cursize); - return linktext; -} - -tern_node * load_config(char * expath) -{ - char * linktext; + char * exe_dir; char * home = getenv("HOME"); if (!home) { goto load_in_app_dir; @@ -139,33 +112,18 @@ } free(path); load_in_app_dir: - - linktext = readlink_alloc("/proc/self/exe"); - if (!linktext) { - goto link_prob; - } - char * cur; - int linksize = strlen(linktext); - for(cur = linktext + linksize - 1; cur != linktext; cur--) - { - if (*cur == '/') { - *cur = 0; - break; - } + exe_dir = get_exe_dir(); + if (!exe_dir) { + goto no_config; } - if (cur == linktext) { - goto link_prob; - } - path = alloc_concat(linktext, "/default.cfg"); + path = alloc_concat(exe_dir, "/default.cfg"); ret = parse_config_file(path); + free(path); success: - return ret; -link_prob: - if (linktext) { - free(linktext); + if (ret) { + return ret; } -no_proc: - //TODO: Fall back to using expath if /proc is not available +no_config: fputs("Failed to find a config file in ~/.config/blastem/blastem.cfg or in the blastem executable directory\n", stderr); exit(1); } diff -r 39cad98d2789 -r 6fc71114d145 config.h --- a/config.h Mon Oct 28 19:37:30 2013 -0700 +++ b/config.h Mon Oct 28 21:48:46 2013 -0700 @@ -1,13 +1,13 @@ /* Copyright 2013 Michael Pavone - This file is part of BlastEm. + This file is part of BlastEm. BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. */ #ifndef CONFIG_H_ #define CONFIG_H_ #include "tern.h" -tern_node * load_config(char * expath); +tern_node * load_config(); #endif //CONFIG_H_ diff -r 39cad98d2789 -r 6fc71114d145 util.c --- a/util.c Mon Oct 28 19:37:30 2013 -0700 +++ b/util.c Mon Oct 28 21:48:46 2013 -0700 @@ -3,6 +3,10 @@ #include #include +#include +#include +#include + char * alloc_concat(char * first, char * second) { int flen = strlen(first); @@ -63,3 +67,73 @@ *text = 0; return text+1; } + +static char * exe_str; + +void set_exe_str(char * str) +{ + exe_str = str; +} + +char * readlink_alloc(char * path) +{ + char * linktext = NULL; + ssize_t linksize = 512; + ssize_t cursize = 0; + do { + if (linksize > cursize) { + cursize = linksize; + if (linktext) { + free(linktext); + } + } + linktext = malloc(cursize); + linksize = readlink(path, linktext, cursize-1); + if (linksize == -1) { + perror("readlink"); + free(linktext); + linktext = NULL; + } + } while (linksize > cursize); + return linktext; +} + +char * get_exe_dir() +{ + static char * exe_dir; + if (!exe_dir) { + char * linktext = readlink_alloc("/proc/self/exe"); + if (!linktext) { + goto fallback; + } + char * cur; + int linksize = strlen(linktext); + for(cur = linktext + linksize - 1; cur != linktext; cur--) + { + if (*cur == '/') { + *cur = 0; + break; + } + } + if (cur == linktext) { + free(linktext); +fallback: + if (!exe_str) { + fputs("/proc/self/exe is not available and set_exe_str was not called!", stderr); + } + int pathsize = strlen(exe_str); + for(cur = exe_str + pathsize - 1; cur != exe_str; cur--) + { + if (*cur == '/') { + exe_dir = malloc(cur-exe_str+1); + memcpy(exe_dir, exe_str, cur-exe_str); + exe_dir[cur-exe_str] = 0; + break; + } + } + } else { + exe_dir = linktext; + } + } + return exe_dir; +} diff -r 39cad98d2789 -r 6fc71114d145 util.h --- a/util.h Mon Oct 28 19:37:30 2013 -0700 +++ b/util.h Mon Oct 28 21:48:46 2013 -0700 @@ -13,6 +13,13 @@ long file_size(FILE * f); //Strips whitespace and non-printable characters from the beginning and end of a string char * strip_ws(char * text); +//Inserts a null after the first word, returns a pointer to the second word char * split_keyval(char * text); +//Should be called by main with the value of argv[0] for use by get_exe_dir +void set_exe_str(char * str); +//Returns the directory the executable is in +char * get_exe_dir(); +//Returns the contents of a symlink in a newly allocated string +char * readlink_alloc(char * path); #endif //UTIL_H_