From 176fb108a6fb906bfdc03ff05f322ee7e7907737 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sat, 24 Jan 2015 14:40:45 -0500 Subject: [PATCH] Use the $Commands environment variable as a list of directories where commands may be located. --- bin/loader.cpp | 70 ++++++++++++++++++++++++++++++++++++--- mpw/mpw.cpp | 53 +++++++++++++++-------------- mpw/mpw.h | 3 +- verbatim/Environment.text | 4 +++ 4 files changed, 99 insertions(+), 31 deletions(-) diff --git a/bin/loader.cpp b/bin/loader.cpp index 2fbdb48..be425d6 100644 --- a/bin/loader.cpp +++ b/bin/loader.cpp @@ -646,10 +646,8 @@ bool file_exists(const std::string & name) return ::stat(name.c_str(), &st) == 0 && S_ISREG(st.st_mode); } -std::string find_exe(const std::string &name) +std::string old_find_exe(const std::string &name) { - // TODO -- use the environment variable for directories. - if (file_exists(name)) return name; // if name is a path, then it doesn't exist. @@ -670,6 +668,65 @@ std::string find_exe(const std::string &name) } +// this needs to run *after* the MPW environment variables are loaded. +std::string find_exe(const std::string &name) +{ + + // if this is an absolute or relative name, return as-is. + + if (name.find(':') != name.npos) { + std::string path = ToolBox::MacToUnix(name); + if (file_exists(path)) return path; + return ""; + } + + if (name.find('/') != name.npos) { + if (file_exists(name)) return name; + return ""; + } + + + // otherwise, check the Commands variable for locations. + std::string command = MPW::GetEnv("Commands"); + if (command.empty()) return old_find_exe(name); + + + // string is , separated, possibly in MacOS format. + std::string::size_type begin = 0; + std::string::size_type end = 0; + for(;;) + { + std::string path; + end = command.find(',', begin); + + if (end == std::string::npos) { + + if (begin >= command.length()) return ""; + + path = command.substr(begin); + } + else + { + size_t count = end - begin - 1; + path = command.substr(begin, count); + } + + if (!path.empty()) + { + // convert to unix. + path = ToolBox::MacToUnix(path); + // should always have a length... + if (path.length() && path.back() != '/') path.push_back('/'); + path.append(name); + if (file_exists(path)) return path; + } + + if (end == std::string::npos) return ""; + begin = end + 1; + } +} + + void MainLoop() { #if 0 @@ -868,14 +925,17 @@ int main(int argc, char **argv) } - std::string command(argv[0]); // InitMPW updates argv... + MPW::InitEnvironment(defines); + + std::string command(argv[0]); // InitMPW updates argv... command = find_exe(command); if (command.empty()) { std::string mpw = MPW::RootDir(); fprintf(stderr, "Unable to find command %s\n", argv[0]); fprintf(stderr, "$MPW = %s\n", mpw.c_str()); + fprintf(stderr, "$Commands = %s\n", MPW::GetEnv("Commands").c_str()); exit(EX_USAGE); } argv[0] = ::strdup(command.c_str()); // hmm.. could setenv(mpw_command) instead. @@ -893,7 +953,7 @@ int main(int argc, char **argv) MM::Init(Memory, MemorySize, kGlobalSize, Flags.stackSize); OS::Init(); - MPW::Init(argc, argv, defines); + MPW::Init(argc, argv); cpuStartup(); diff --git a/mpw/mpw.cpp b/mpw/mpw.cpp index 7b3cbdc..11c4e1a 100644 --- a/mpw/mpw.cpp +++ b/mpw/mpw.cpp @@ -176,7 +176,33 @@ namespace MPW return path; // unknown. } - uint16_t Init(int argc, char **argv, const std::vector &defines) + uint16_t InitEnvironment(const std::vector &defines) + { + void EnvLoadFile(const std::string &envfile); + void EnvLoadArray(const std::vector &data); + + std::string m(RootDir()); + if (!m.empty()) + { + std::string mm = ToolBox::UnixToMac(m); + if (mm.back() != ':') mm.push_back(':'); + + Environment.emplace(std::string("MPW"), mm); + } + + if (defines.size()) + EnvLoadArray(defines); + + if (!m.empty()) + { + std::string path(RootDirPathForFile("Environment.text")); + EnvLoadFile(path); + } + + return 0; + } + + uint16_t Init(int argc, char **argv) { /* FDTable.resize(16); @@ -274,33 +300,10 @@ namespace MPW } - // environment, - // just use $MPW and synthesize the other ones. + // environment { - void EnvLoadFile(const std::string &envfile); - void EnvLoadArray(const std::vector &data); - - std::string m(RootDir()); - if (!m.empty()) - { - std::string mm = ToolBox::UnixToMac(m); - if (mm.back() != ':') mm.push_back(':'); - - Environment.emplace(std::string("MPW"), mm); - } Environment.emplace(std::string("Command"), command); - - if (defines.size()) - EnvLoadArray(defines); - - if (!m.empty()) - { - - std::string path(RootDirPathForFile("Environment.text")); - EnvLoadFile(path); - } - std::deque e; for (const auto &iter : Environment) diff --git a/mpw/mpw.h b/mpw/mpw.h index 742765a..fe01194 100644 --- a/mpw/mpw.h +++ b/mpw/mpw.h @@ -101,7 +101,8 @@ namespace MPW { // should add argc/argv/envp... - uint16_t Init(int argc, char **argv, const std::vector &defines); + uint16_t InitEnvironment(const std::vector &defines); + uint16_t Init(int argc, char **argv); uint32_t ExitStatus(); diff --git a/verbatim/Environment.text b/verbatim/Environment.text index 627e283..1c387ee 100644 --- a/verbatim/Environment.text +++ b/verbatim/Environment.text @@ -16,6 +16,10 @@ ShellDirectory=$MPW SysTempFolder=/tmp/ TempFolder=/tmp/ +# comma-separated list of directories, like $PATH +# add . to include the current directory. +Commands=${MPW}Tools: + # MPW IIgs 1.1 AIIGSIncludes=${MPW}Interfaces:AIIGSIncludes: RIIGSIncludes=${MPW}Interfaces:RIIGSIncludes: