From 95a7650b8dcf9ed1565857f6d4fd18d06b52faf6 Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 01:09:15 +0300 Subject: [PATCH 1/7] Switching to argagg for CLI parsing --- .gitmodules | 3 +++ dep/Makefile | 6 +++++- dep/argagg | 1 + src/main.cpp | 39 ++++++++++++++++++++++++++++----------- 4 files changed, 37 insertions(+), 12 deletions(-) create mode 160000 dep/argagg diff --git a/.gitmodules b/.gitmodules index ceed831e..0df71e1f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "dep/rtaudio"] path = dep/rtaudio url = https://github.com/thestk/rtaudio.git +[submodule "dep/argagg"] + path = dep/argagg + url = https://github.com/vietjtnguyen/argagg.git diff --git a/dep/Makefile b/dep/Makefile index 5a9f16c4..05aab98a 100755 --- a/dep/Makefile +++ b/dep/Makefile @@ -50,8 +50,9 @@ nanosvg = include/nanosvg.h oui-blendish = include/blendish.h osdialog = include/osdialog.h pffft = include/pffft.h +argagg = include/argagg.hpp -DEPS += $(glew) $(glfw) $(jansson) $(libspeexdsp) $(libcurl) $(libzip) $(rtmidi) $(rtaudio) $(nanovg) $(nanosvg) $(oui-blendish) $(osdialog) $(pffft) +DEPS += $(glew) $(glfw) $(jansson) $(libspeexdsp) $(libcurl) $(libzip) $(rtmidi) $(rtaudio) $(nanovg) $(nanosvg) $(oui-blendish) $(osdialog) $(pffft) $(argagg) include $(RACK_DIR)/dep.mk @@ -163,6 +164,9 @@ $(pffft): $(WGET) "https://bitbucket.org/jpommier/pffft/get/29e4f76ac53b.zip" $(UNZIP) 29e4f76ac53b.zip cp jpommier-pffft-29e4f76ac53b/*.h include/ + +$(argagg): $(wildcard argagg/include/argagg/*.hpp) + cp argagg/include/argagg/*.hpp include/ clean: git clean -fdx diff --git a/dep/argagg b/dep/argagg new file mode 160000 index 00000000..24f1dd7f --- /dev/null +++ b/dep/argagg @@ -0,0 +1 @@ +Subproject commit 24f1dd7fd222b2c70b1f02109761f6bc698e5f68 diff --git a/src/main.cpp b/src/main.cpp index 68cf3610..ba3a1ea1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,8 @@ #include "util/color.hpp" #include "osdialog.h" +#include "argagg.hpp" + #include @@ -24,18 +26,33 @@ int main(int argc, char* argv[]) { std::string patchFile; // Parse command line arguments - int c; - opterr = 0; - while ((c = getopt(argc, argv, "d")) != -1) { - switch (c) { - case 'd': { - devMode = true; - } break; - default: break; - } + argagg::parser argparser {{ + { "help", {"-h", "--help"}, "shows this help message", 0}, + { "devmod", {"-d", "--devmod"}, "enable dev mode", 0}, + }}; + + argagg::parser_results args; + + try { + args = argparser.parse(argc, argv); + } catch (const std::exception& e) { + std::cerr << "Encountered exception while parsing arguments: " << e.what() << std::endl; + return EXIT_FAILURE; } - if (optind < argc) { - patchFile = argv[optind]; + + if (args["help"]) { + std::cerr << "Usage: program [options] [FILENAME]" << std::endl; + std::cerr << argparser; + return EXIT_SUCCESS; + } + + if (args["devmod"]) { + devMode = true; + } + + // Filename as first positional argument + if (args.pos.size() > 0) { + patchFile = args.as(0); } // Initialize environment From 907ad50b5aaa870565520ba7742174350af897ed Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 01:49:57 +0300 Subject: [PATCH 2/7] CLI: adding option for global/local dir --- include/asset.hpp | 2 +- src/asset.cpp | 91 +++++++++++++++++++++++++++-------------------- src/main.cpp | 16 +++++++-- 3 files changed, 68 insertions(+), 41 deletions(-) diff --git a/include/asset.hpp b/include/asset.hpp index ab4d860b..428f0977 100644 --- a/include/asset.hpp +++ b/include/asset.hpp @@ -7,7 +7,7 @@ namespace rack { -void assetInit(bool devMode); +void assetInit(bool devMode, std::string customGlobalDir = std::string(), std::string customLocalDir = std::string()); /** Returns the path of a global resource. Should only read files from this location. */ std::string assetGlobal(std::string filename); /** Returns the path of a local resource. Can read and write files to this location. */ diff --git a/src/asset.cpp b/src/asset.cpp index f73882b1..51f30f0b 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -27,7 +27,7 @@ static std::string globalDir; static std::string localDir; -void assetInit(bool devMode) { +void assetInit(bool devMode, std::string customGlobalDir, std::string customLocalDir) { if (devMode) { // Use current working directory if running in development mode globalDir = "."; @@ -35,50 +35,65 @@ void assetInit(bool devMode) { return; } + if (customGlobalDir.empty()) { + #if ARCH_MAC - CFBundleRef bundle = CFBundleGetMainBundle(); - assert(bundle); - CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle); - char resourcesBuf[PATH_MAX]; - Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf)); - assert(success); - CFRelease(resourcesUrl); - globalDir = resourcesBuf; - - // Get home directory - struct passwd *pw = getpwuid(getuid()); - assert(pw); - localDir = pw->pw_dir; - localDir += "/Documents/Rack"; + CFBundleRef bundle = CFBundleGetMainBundle(); + assert(bundle); + CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle); + char resourcesBuf[PATH_MAX]; + Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf)); + assert(success); + CFRelease(resourcesUrl); + globalDir = resourcesBuf; #endif #if ARCH_WIN - char moduleBuf[MAX_PATH]; - DWORD length = GetModuleFileName(NULL, moduleBuf, sizeof(moduleBuf)); - assert(length > 0); - PathRemoveFileSpec(moduleBuf); - globalDir = moduleBuf; - - // Get "My Documents" folder - char documentsBuf[MAX_PATH]; - HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBuf); - assert(result == S_OK); - localDir = documentsBuf; - localDir += "/Rack"; + char moduleBuf[MAX_PATH]; + DWORD length = GetModuleFileName(NULL, moduleBuf, sizeof(moduleBuf)); + assert(length > 0); + PathRemoveFileSpec(moduleBuf); + globalDir = moduleBuf; #endif #if ARCH_LIN - // TODO For now, users should launch Rack from their terminal in the global directory - globalDir = "."; - - // Get home directory - const char *homeBuf = getenv("HOME"); - if (!homeBuf) { - struct passwd *pw = getpwuid(getuid()); - assert(pw); - homeBuf = pw->pw_dir; + // TODO For now, users should launch Rack from their terminal in the global directory + globalDir = "."; +#endif + } + else { + globalDir = customGlobalDir; } - localDir = homeBuf; - localDir += "/.Rack"; + + if (customGlobalDir.empty()) { +#if ARCH_MAC + // Get home directory + struct passwd *pw = getpwuid(getuid()); + assert(pw); + localDir = pw->pw_dir; + localDir += "/Documents/Rack"; #endif +#if ARCH_WIN + // Get "My Documents" folder + char documentsBuf[MAX_PATH]; + HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBuf); + assert(result == S_OK); + localDir = documentsBuf; + localDir += "/Rack"; +#endif +#if ARCH_LIN + // Get home directory + const char *homeBuf = getenv("HOME"); + if (!homeBuf) { + struct passwd *pw = getpwuid(getuid()); + assert(pw); + homeBuf = pw->pw_dir; + } + localDir = homeBuf; + localDir += "/.Rack"; +#endif + } + else { + localDir = customLocalDir; + } } diff --git a/src/main.cpp b/src/main.cpp index ba3a1ea1..5945b462 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,11 +24,15 @@ using namespace rack; int main(int argc, char* argv[]) { bool devMode = false; std::string patchFile; + std::string customLocalDir; + std::string customGlobalDir; // Parse command line arguments argagg::parser argparser {{ { "help", {"-h", "--help"}, "shows this help message", 0}, - { "devmod", {"-d", "--devmod"}, "enable dev mode", 0}, + { "devmod", {"-d", "--devmod"}, "enables dev mode (supersedes local/global folders)", 0}, + { "global", {"-g", "--globaldir"}, "set golbalDir", 1}, + { "local", {"-l", "--localdir"}, "set localDir", 1}, }}; argagg::parser_results args; @@ -50,6 +54,14 @@ int main(int argc, char* argv[]) { devMode = true; } + if (args["global"]) { + customGlobalDir = args["global"].as(); + } + + if (args["local"]) { + customLocalDir = args["local"].as(); + } + // Filename as first positional argument if (args.pos.size() > 0) { patchFile = args.as(0); @@ -57,7 +69,7 @@ int main(int argc, char* argv[]) { // Initialize environment randomInit(); - assetInit(devMode); + assetInit(devMode, customGlobalDir, customLocalDir); loggerInit(devMode); // Log environment From 7065b61e3093466099abf325f55c630ca9f87970 Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 02:08:06 +0300 Subject: [PATCH 3/7] CLI: adding option for Brige port --- include/bridge.hpp | 2 +- src/bridge.cpp | 13 +++++++------ src/main.cpp | 13 ++++++++++++- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/include/bridge.hpp b/include/bridge.hpp index 2e97dccd..e06b0b64 100644 --- a/include/bridge.hpp +++ b/include/bridge.hpp @@ -22,7 +22,7 @@ struct BridgeMidiDriver : MidiDriver { }; -void bridgeInit(); +void bridgeInit(int customPort = BRIDGE_PORT); void bridgeDestroy(); void bridgeAudioSubscribe(int channel, AudioIO *audio); void bridgeAudioUnsubscribe(int channel, AudioIO *audio); diff --git a/src/bridge.cpp b/src/bridge.cpp index 8d1385ca..15b7ab88 100644 --- a/src/bridge.cpp +++ b/src/bridge.cpp @@ -282,7 +282,7 @@ static void clientRun(int client) { } -static void serverConnect() { +static void serverConnect(int customPort) { // Initialize sockets #if ARCH_WIN WSADATA wsaData; @@ -299,7 +299,8 @@ static void serverConnect() { struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = htons(BRIDGE_PORT); + warn("Bridge server port: %i", customPort); + addr.sin_port = htons(customPort); #if ARCH_WIN addr.sin_addr.s_addr = inet_addr(BRIDGE_HOST); #else @@ -365,10 +366,10 @@ static void serverConnect() { } } -static void serverRun() { +static void serverRun(int customPort) { while (serverRunning) { std::this_thread::sleep_for(std::chrono::duration(0.1)); - serverConnect(); + serverConnect(customPort); } } @@ -403,9 +404,9 @@ void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput } -void bridgeInit() { +void bridgeInit(int customPort) { serverRunning = true; - serverThread = std::thread(serverRun); + serverThread = std::thread(serverRun, customPort); driver = new BridgeMidiDriver(); midiDriverAdd(BRIDGE_DRIVER, driver); diff --git a/src/main.cpp b/src/main.cpp index 5945b462..a55247b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -26,6 +26,7 @@ int main(int argc, char* argv[]) { std::string patchFile; std::string customLocalDir; std::string customGlobalDir; + int customBridgePort = -1; // Parse command line arguments argagg::parser argparser {{ @@ -33,6 +34,7 @@ int main(int argc, char* argv[]) { { "devmod", {"-d", "--devmod"}, "enables dev mode (supersedes local/global folders)", 0}, { "global", {"-g", "--globaldir"}, "set golbalDir", 1}, { "local", {"-l", "--localdir"}, "set localDir", 1}, + { "port", {"-p", "--port"}, "Bridge port number", 1}, }}; argagg::parser_results args; @@ -62,6 +64,10 @@ int main(int argc, char* argv[]) { customLocalDir = args["local"].as(); } + if (args["port"]) { + customBridgePort = args["port"].as(); + } + // Filename as first positional argument if (args.pos.size() > 0) { patchFile = args.as(0); @@ -83,7 +89,12 @@ int main(int argc, char* argv[]) { pluginInit(devMode); engineInit(); rtmidiInit(); - bridgeInit(); + if (customBridgePort > 0) { + bridgeInit(customBridgePort); + } + else { + bridgeInit(); + } keyboardInit(); gamepadInit(); windowInit(); From 9f8d4ff0ca6d7b206498b96defd41c65bcd9605c Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 03:37:31 +0300 Subject: [PATCH 4/7] CLI: fix localdir option --- src/asset.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/asset.cpp b/src/asset.cpp index 51f30f0b..a5df3c32 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -19,7 +19,6 @@ #include #endif - namespace rack { @@ -63,7 +62,7 @@ void assetInit(bool devMode, std::string customGlobalDir, std::string customLoca globalDir = customGlobalDir; } - if (customGlobalDir.empty()) { + if (customLocalDir.empty()) { #if ARCH_MAC // Get home directory struct passwd *pw = getpwuid(getuid()); From 74c97693217cd20f9c28a5570742884c4655c382 Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 15:22:59 +0300 Subject: [PATCH 5/7] fixing indentation --- src/asset.cpp | 74 +++++++++++++++++++++++++-------------------------- src/main.cpp | 36 ++++++++++++------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/asset.cpp b/src/asset.cpp index a5df3c32..6c19f693 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -37,61 +37,61 @@ void assetInit(bool devMode, std::string customGlobalDir, std::string customLoca if (customGlobalDir.empty()) { #if ARCH_MAC - CFBundleRef bundle = CFBundleGetMainBundle(); - assert(bundle); - CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle); - char resourcesBuf[PATH_MAX]; - Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf)); - assert(success); - CFRelease(resourcesUrl); - globalDir = resourcesBuf; + CFBundleRef bundle = CFBundleGetMainBundle(); + assert(bundle); + CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(bundle); + char resourcesBuf[PATH_MAX]; + Boolean success = CFURLGetFileSystemRepresentation(resourcesUrl, TRUE, (UInt8*) resourcesBuf, sizeof(resourcesBuf)); + assert(success); + CFRelease(resourcesUrl); + globalDir = resourcesBuf; #endif #if ARCH_WIN - char moduleBuf[MAX_PATH]; - DWORD length = GetModuleFileName(NULL, moduleBuf, sizeof(moduleBuf)); - assert(length > 0); - PathRemoveFileSpec(moduleBuf); - globalDir = moduleBuf; + char moduleBuf[MAX_PATH]; + DWORD length = GetModuleFileName(NULL, moduleBuf, sizeof(moduleBuf)); + assert(length > 0); + PathRemoveFileSpec(moduleBuf); + globalDir = moduleBuf; #endif #if ARCH_LIN - // TODO For now, users should launch Rack from their terminal in the global directory - globalDir = "."; + // TODO For now, users should launch Rack from their terminal in the global directory + globalDir = "."; #endif } else { - globalDir = customGlobalDir; + globalDir = customGlobalDir; } if (customLocalDir.empty()) { #if ARCH_MAC - // Get home directory - struct passwd *pw = getpwuid(getuid()); - assert(pw); - localDir = pw->pw_dir; - localDir += "/Documents/Rack"; + // Get home directory + struct passwd *pw = getpwuid(getuid()); + assert(pw); + localDir = pw->pw_dir; + localDir += "/Documents/Rack"; #endif #if ARCH_WIN - // Get "My Documents" folder - char documentsBuf[MAX_PATH]; - HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBuf); - assert(result == S_OK); - localDir = documentsBuf; - localDir += "/Rack"; + // Get "My Documents" folder + char documentsBuf[MAX_PATH]; + HRESULT result = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, documentsBuf); + assert(result == S_OK); + localDir = documentsBuf; + localDir += "/Rack"; #endif #if ARCH_LIN - // Get home directory - const char *homeBuf = getenv("HOME"); - if (!homeBuf) { - struct passwd *pw = getpwuid(getuid()); - assert(pw); - homeBuf = pw->pw_dir; - } - localDir = homeBuf; - localDir += "/.Rack"; + // Get home directory + const char *homeBuf = getenv("HOME"); + if (!homeBuf) { + struct passwd *pw = getpwuid(getuid()); + assert(pw); + homeBuf = pw->pw_dir; + } + localDir = homeBuf; + localDir += "/.Rack"; #endif } else { - localDir = customLocalDir; + localDir = customLocalDir; } } diff --git a/src/main.cpp b/src/main.cpp index a55247b3..6e38d3a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,47 +30,47 @@ int main(int argc, char* argv[]) { // Parse command line arguments argagg::parser argparser {{ - { "help", {"-h", "--help"}, "shows this help message", 0}, - { "devmod", {"-d", "--devmod"}, "enables dev mode (supersedes local/global folders)", 0}, - { "global", {"-g", "--globaldir"}, "set golbalDir", 1}, - { "local", {"-l", "--localdir"}, "set localDir", 1}, - { "port", {"-p", "--port"}, "Bridge port number", 1}, + { "help", {"-h", "--help"}, "shows this help message", 0}, + { "devmod", {"-d", "--devmod"}, "enables dev mode (supersedes local/global folders)", 0}, + { "global", {"-g", "--globaldir"}, "set golbalDir", 1}, + { "local", {"-l", "--localdir"}, "set localDir", 1}, + { "port", {"-p", "--port"}, "Bridge port number", 1}, }}; argagg::parser_results args; try { - args = argparser.parse(argc, argv); + args = argparser.parse(argc, argv); } catch (const std::exception& e) { - std::cerr << "Encountered exception while parsing arguments: " << e.what() << std::endl; - return EXIT_FAILURE; + std::cerr << "Encountered exception while parsing arguments: " << e.what() << std::endl; + return EXIT_FAILURE; } if (args["help"]) { - std::cerr << "Usage: program [options] [FILENAME]" << std::endl; - std::cerr << argparser; - return EXIT_SUCCESS; + std::cerr << "Usage: program [options] [FILENAME]" << std::endl; + std::cerr << argparser; + return EXIT_SUCCESS; } if (args["devmod"]) { - devMode = true; + devMode = true; } if (args["global"]) { - customGlobalDir = args["global"].as(); + customGlobalDir = args["global"].as(); } if (args["local"]) { - customLocalDir = args["local"].as(); + customLocalDir = args["local"].as(); } if (args["port"]) { - customBridgePort = args["port"].as(); + customBridgePort = args["port"].as(); } // Filename as first positional argument if (args.pos.size() > 0) { - patchFile = args.as(0); + patchFile = args.as(0); } // Initialize environment @@ -90,10 +90,10 @@ int main(int argc, char* argv[]) { engineInit(); rtmidiInit(); if (customBridgePort > 0) { - bridgeInit(customBridgePort); + bridgeInit(customBridgePort); } else { - bridgeInit(); + bridgeInit(); } keyboardInit(); gamepadInit(); From 09dc681eb84d3bc8a19071f327cb3ea750b7a816 Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 15:56:27 +0300 Subject: [PATCH 6/7] devmode defaults rather than overwrites folders --- src/asset.cpp | 11 +++++++---- src/main.cpp | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/asset.cpp b/src/asset.cpp index 6c19f693..b3cadc76 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -28,10 +28,13 @@ static std::string localDir; void assetInit(bool devMode, std::string customGlobalDir, std::string customLocalDir) { if (devMode) { - // Use current working directory if running in development mode - globalDir = "."; - localDir = "."; - return; + // Use current working directory by default if running in development mode + if (customGlobalDir.empty()) { + customGlobalDir = "."; + } + if (customLocalDir.empty()) { + customLocalDir = "."; + } } if (customGlobalDir.empty()) { diff --git a/src/main.cpp b/src/main.cpp index 6e38d3a6..71c37955 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ int main(int argc, char* argv[]) { // Parse command line arguments argagg::parser argparser {{ { "help", {"-h", "--help"}, "shows this help message", 0}, - { "devmod", {"-d", "--devmod"}, "enables dev mode (supersedes local/global folders)", 0}, + { "devmod", {"-d", "--devmod"}, "enables dev mode (will default local/global folders to current folder)", 0}, { "global", {"-g", "--globaldir"}, "set golbalDir", 1}, { "local", {"-l", "--localdir"}, "set localDir", 1}, { "port", {"-p", "--port"}, "Bridge port number", 1}, From d96663bd09953b748d18834abd67fac590c4f3ac Mon Sep 17 00:00:00 2001 From: jfrey Date: Fri, 15 Jun 2018 16:30:25 +0300 Subject: [PATCH 7/7] CLI: ensure custom directories exist --- src/asset.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/asset.cpp b/src/asset.cpp index b3cadc76..65d1dd59 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -19,6 +19,8 @@ #include #endif +#include + namespace rack { @@ -62,7 +64,13 @@ void assetInit(bool devMode, std::string customGlobalDir, std::string customLoca #endif } else { - globalDir = customGlobalDir; + if (!systemIsDirectory(customGlobalDir)) { + std::cerr << "Selected global directory \"" << customGlobalDir << "\" does not exist or is not a directory, default to current directory." << std::endl; + globalDir = "."; + } + else { + globalDir = customGlobalDir; + } } if (customLocalDir.empty()) { @@ -94,7 +102,13 @@ void assetInit(bool devMode, std::string customGlobalDir, std::string customLoca #endif } else { - localDir = customLocalDir; + if (!systemIsDirectory(customLocalDir)) { + std::cerr << "Selected local directory \"" << customLocalDir << "\" does not exist or is not a directory, default to current directory." << std::endl; + localDir = "."; + } + else { + localDir = customLocalDir; + } } }