1 extern "C" { 2 #include <stdlib.h> 3 #include <string.h> 4 } 5 #include <libcurv/exception.h> 6 #include <libcurv/progdir.h> 7 namespace fs = boost::filesystem; 8 9 namespace curv { 10 11 /* 12 * Compute the absolute pathname of the directory 13 * containing the program executable. 14 * The storage for the result string is dynamically allocated. 15 * argv0 is argv[0] of the argv passed to main(). 16 */ 17 fs::path progdir(const char * argv0)18progdir(const char *argv0) 19 { 20 fs::path cmd(argv0); 21 #ifdef _WIN32 22 if (!cmd.has_extension()) cmd += ".exe"; 23 #endif 24 25 if (cmd.has_parent_path()) { 26 return fs::canonical(cmd).parent_path(); 27 } 28 29 const char* PATH = getenv("PATH"); 30 if (PATH == NULL) { 31 throw curv::Exception_Base(curv::stringify( 32 "Can't determine directory of program ", argv0, 33 ": PATH not defined")); 34 } 35 36 37 const char* p = PATH; 38 const char* pend = PATH + strlen(PATH); 39 #ifdef _WIN32 40 const char delim = ';'; 41 #else 42 const char delim = ':'; 43 #endif 44 while (p < pend) { 45 const char* q = strchr(p, delim); 46 if (q == nullptr) 47 q = pend; 48 fs::path file(p, q); 49 file /= cmd; 50 if (fs::exists(fs::status(file))) { 51 return fs::canonical(file).parent_path(); 52 } 53 p = (q < pend ? q + 1 : pend); 54 } 55 56 throw curv::Exception_Base(curv::stringify( 57 "Can't determine directory of program ", argv0, 58 ": can't find ", argv0, " in $PATH")); 59 } 60 61 } 62