diff --git a/CHANGELOG.md b/CHANGELOG.md index e5476c36..37e86ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,14 @@ In this document, Mod is Ctrl on Windows/Linux and Cmd on Mac. -### 1.2.0 (in development) -- Enable app notarization on Mac, removing the "Apple cannot check for malicious software" message on launch. +### 1.1.2 (2019-07-20) +- Add app notarization on Mac, which removes the "Apple cannot check for malicious software" message on launch. +- Write stack trace to log.txt and display dialog box when Rack crashes. - Re-enable JACK MIDI driver on Linux. - Fix scroll speed for mice and trackpads on Mac. - Fix undo history bug when dragging patch file to the Rack window. +- Fix crash when pasting presets to an empty rack space with Mod-V. +- Fix module expanders being assigned incorrectly when loading presets. - Add check for duplicate port IDs for modules. ### 1.1.1 (2019-07-01) diff --git a/CODE-OF-CONDUCT.md b/CODE-OF-CONDUCT.md new file mode 100644 index 00000000..0fc3e86a --- /dev/null +++ b/CODE-OF-CONDUCT.md @@ -0,0 +1,77 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all project spaces, and it also applies when +an individual is representing the project or its community in public spaces. +Examples of representing a project or community include using an official +project e-mail address, posting via an official social media account, or acting +as an appointed representative at an online or offline event. Representation of +a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at contact@vcvrack.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq + diff --git a/Core.json b/Core.json index 16335039..f9dfb91d 100644 --- a/Core.json +++ b/Core.json @@ -1,7 +1,7 @@ { "slug": "Core", "name": "Core", - "version": "1.0.0", + "version": "1.1.2", "license": "GPL-3.0-only", "author": "VCV", "brand": "VCV", diff --git a/LICENSE.md b/LICENSE.md index fc3fd4cc..ff46e72f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -12,19 +12,19 @@ All VCV Rack **source code** is copyright © 2019 Andrew Belt and licensed under This means that non-commercial plugins do not need to be licensed under the GPLv3 and can be released under any license of your choice (open-source or proprietary freeware). However, plugins that copy a significant portion of non-API source code from Rack must be licensed under GPLv3. -If you wish to release a proprietary commercial plugin, email contact@vcvrack.com for commercial licensing. A commercial license is included for plugins sold in the [VCV Plugin Manager](https://vcvrack.com/plugins.html). +If you wish to release a proprietary commercial plugin, email contact@vcvrack.com for commercial licensing. A commercial license is included for plugins sold in the [VCV Library](https://vcvrack.com/plugins.html). --- Licenses of **third-party libraries** are listed in [LICENSE-dist.txt](LICENSE-dist.txt). The **Component Library graphics** in the `res/ComponentLibrary` directory are copyright © 2019 [Grayscale](http://grayscale.info/) and licensed under [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/). -You may not freely sell plugins using Component Library graphics. -However, a free commercial license is available for plugins sold through the [VCV Plugin Manager](https://vcvrack.com/plugins.html). -Email contact@vcvrack.com for more information about licensing or the VCV Plugin Manager. +This means you may not freely sell plugins using Component Library graphics. +However, a free commercial license is available for plugins sold through the [VCV Library](https://vcvrack.com/plugins.html). +Email contact@vcvrack.com for more information about licensing or the VCV Library. The **Core panel graphics** in the `res/Core` directory are copyright © 2019 [Grayscale](http://grayscale.info/) and licensed under [CC BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/). -You may not distribute modified adaptations of these graphics. +This means you may not distribute modified adaptations of these graphics. The **VCV logo and icon** are copyright © 2017 Andrew Belt and may not be used in derivative works. diff --git a/Makefile b/Makefile index 2bf6f2da..7a4c8a74 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ RACK_DIR ?= . -VERSION := 1.dev.$(shell git rev-parse --short HEAD) -# VERSION := 1.1.1 +# VERSION := 1.dev.$(shell git rev-parse --short HEAD) +VERSION := 1.1.2 FLAGS += -DVERSION=$(VERSION) FLAGS += -Iinclude -Idep/include @@ -38,8 +38,8 @@ endif ifdef ARCH_WIN SOURCES += dep/osdialog/osdialog_win.c LDFLAGS += -Wl,--export-all-symbols,--out-implib,libRack.a -mwindows \ - dep/lib/libglew32.a dep/lib/libglfw3.a dep/lib/libjansson.a dep/lib/libspeexdsp.a dep/lib/libzip.a dep/lib/libz.a dep/lib/libcurl.a dep/lib/libssl.a dep/lib/libcrypto.a dep/lib/librtaudio.a dep/lib/librtmidi.a \ - -lpthread -lopengl32 -lgdi32 -lws2_32 -lcomdlg32 -lole32 -ldsound -lwinmm -lksuser -lshlwapi -lmfplat -lmfuuid -lwmcodecdspuuid -ldbghelp + dep/lib/libglew32.a dep/lib/libglfw3.a dep/lib/libjansson.a dep/lib/libspeexdsp.a dep/lib/libzip.a dep/lib/libz.a dep/lib/libcurl.a dep/lib/librtaudio.a dep/lib/librtmidi.a \ + -lpthread -lopengl32 -lgdi32 -lws2_32 -lcomdlg32 -lole32 -lcrypt32 -ldsound -lwinmm -lksuser -lshlwapi -lmfplat -lmfuuid -lwmcodecdspuuid -ldbghelp TARGET := Rack.exe OBJECTS += Rack.res endif @@ -130,7 +130,6 @@ ifdef ARCH_MAC # This will only work if you have the private key to my certificate codesign --verbose --sign "Developer ID Application: Andrew Belt (VRF26934X5)" --options runtime --entitlements Entitlements.plist --deep dist/$(TARGET).app codesign --verify --deep --strict --verbose=2 dist/$(TARGET).app -# spctl --assess --type execute --ignore-cache --no-cache -vv dist/$(TARGET).app # Make ZIP cd dist && zip -q -9 -r Rack-$(VERSION)-$(ARCH).zip $(TARGET).app endif @@ -171,6 +170,7 @@ ifdef ARCH_MAC xcrun altool --notarize-app -f dist/Rack-$(VERSION)-$(ARCH).zip --primary-bundle-id=com.vcvrack.rack -u "andrewpbelt@gmail.com" -p @keychain:notarize --output-format xml > dist/UploadInfo.plist # Wait for Apple's servers to approve the app while true; do \ + echo "Waiting on Apple servers..." ; \ xcrun altool --notarization-info `/usr/libexec/PlistBuddy -c "Print :notarization-upload:RequestUUID" dist/UploadInfo.plist` -u "andrewpbelt@gmail.com" -p @keychain:notarize --output-format xml > dist/RequestInfo.plist ; \ if [ "`/usr/libexec/PlistBuddy -c "Print :notarization-info:Status" dist/RequestInfo.plist`" != "in progress" ]; then \ break ; \ diff --git a/dep/Makefile b/dep/Makefile index fe35541c..ec2fb482 100755 --- a/dep/Makefile +++ b/dep/Makefile @@ -119,11 +119,24 @@ curl-7.64.1: $(UNTAR) curl-7.64.1.tar.gz rm curl-7.64.1.tar.gz -$(libcurl): $(openssl) curl-7.64.1 - cd curl-7.64.1 && PKG_CONFIG_PATH= $(CONFIGURE) \ - --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-shared --disable-symbol-hiding \ - --without-zlib --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-winidn --without-libidn2 --without-nghttp2 --without-brotli \ - --without-ca-bundle --with-ca-fallback --with-ssl="$(DEP_PATH)" +CURL_FLAGS += --disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual --disable-shared --disable-symbol-hiding +CURL_FLAGS += --without-zlib --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-winidn --without-libidn2 --without-nghttp2 --without-brotli +ifdef ARCH_LIN +CURL_FLAGS += --with-ssl="$(DEP_PATH)" +CURL_DEPS += $(openssl) +endif +ifdef ARCH_MAC +# Since Rack supports Mac 10.7 but Apple's Secure Transport only supports TLS 1.0 on that OS, use OpenSSL instead. +# CURL_FLAGS += --with-secure-transport +CURL_FLAGS += --with-ssl="$(DEP_PATH)" +CURL_DEPS += $(openssl) +endif +ifdef ARCH_WIN +CURL_FLAGS += --with-schannel --without-ssl +endif + +$(libcurl): $(CURL_DEPS) curl-7.64.1 + cd curl-7.64.1 && PKG_CONFIG_PATH= $(CONFIGURE) $(CURL_FLAGS) $(MAKE) -C curl-7.64.1 $(MAKE) -C curl-7.64.1 install @@ -163,15 +176,15 @@ rtmidi-4.0.0: rm rtmidi-4.0.0.tar.gz RTMIDI_FLAGS += --enable-shared=no +ifdef ARCH_LIN +RTMIDI_FLAGS += --with-jack --with-alsa +endif ifdef ARCH_MAC RTMIDI_FLAGS += --with-core --without-jack endif ifdef ARCH_WIN RTMIDI_FLAGS += --with-winmm endif -ifdef ARCH_LIN -RTMIDI_FLAGS += --with-jack --with-alsa -endif $(rtmidi): rtmidi-4.0.0 cd rtmidi-4.0.0 && $(CONFIGURE) $(RTMIDI_FLAGS) @@ -179,15 +192,15 @@ $(rtmidi): rtmidi-4.0.0 $(MAKE) -C rtmidi-4.0.0 install RTAUDIO_FLAGS += -DRTAUDIO_BUILD_STATIC_LIBS=ON +ifdef ARCH_LIN +RTAUDIO_FLAGS += -DRTAUDIO_API_ALSA=ON -DRTAUDIO_API_JACK=ON -DRTAUDIO_API_PULSE=OFF -DRTAUDIO_API_OSS=OFF +endif ifdef ARCH_MAC RTAUDIO_FLAGS += -DRTAUDIO_API_CORE=ON -DRTAUDIO_API_PULSE=OFF -DRTAUDIO_API_JACK=OFF endif ifdef ARCH_WIN RTAUDIO_FLAGS += -DRTAUDIO_API_DS=ON -DRTAUDIO_API_WASAPI=ON -DRTAUDIO_API_ASIO=ON endif -ifdef ARCH_LIN -RTAUDIO_FLAGS += -DRTAUDIO_API_ALSA=ON -DRTAUDIO_API_JACK=ON -DRTAUDIO_API_PULSE=OFF -DRTAUDIO_API_OSS=OFF -endif $(rtaudio): rtaudio cd rtaudio && mkdir -p build diff --git a/include/asset.hpp b/include/asset.hpp index e65cb512..4ee7722f 100644 --- a/include/asset.hpp +++ b/include/asset.hpp @@ -26,6 +26,7 @@ std::string plugin(plugin::Plugin *plugin, std::string filename); extern std::string systemDir; extern std::string userDir; +extern std::string logPath; extern std::string pluginsPath; extern std::string settingsPath; extern std::string autosavePath; diff --git a/include/componentlibrary.hpp b/include/componentlibrary.hpp index 17d97add..684bf6c4 100644 --- a/include/componentlibrary.hpp +++ b/include/componentlibrary.hpp @@ -447,6 +447,12 @@ struct BlueLight : GrayModuleLightWidget { } }; +struct WhiteLight : GrayModuleLightWidget { + WhiteLight() { + addBaseColor(SCHEME_WHITE); + } +}; + /** Reads two adjacent lightIds, so `lightId` and `lightId + 1` must be defined */ struct GreenRedLight : GrayModuleLightWidget { GreenRedLight() { diff --git a/include/network.hpp b/include/network.hpp index eaff1d4a..6e8484be 100644 --- a/include/network.hpp +++ b/include/network.hpp @@ -26,8 +26,6 @@ json_t *requestJson(Method method, std::string url, json_t *dataJ); bool requestDownload(std::string url, const std::string &filename, float *progress); /** URL-encodes `s` */ std::string encodeUrl(const std::string &s); -/** Computes the SHA256 of the file at `filename` */ -std::string computeSHA256File(const std::string &filename); /** Gets the path portion of the URL. */ std::string urlPath(const std::string &url); diff --git a/res/ComponentLibrary/LICENSE.txt b/res/ComponentLibrary/LICENSE.txt deleted file mode 100644 index 253419ff..00000000 --- a/res/ComponentLibrary/LICENSE.txt +++ /dev/null @@ -1,2 +0,0 @@ -Component Library graphics by Grayscale (http://grayscale.info/) -Licensed under CC BY-NC 4.0 (https://creativecommons.org/licenses/by-nc/4.0/) \ No newline at end of file diff --git a/res/Core/LICENSE.txt b/res/Core/LICENSE.txt deleted file mode 100644 index 10b99ce4..00000000 --- a/res/Core/LICENSE.txt +++ /dev/null @@ -1,3 +0,0 @@ -Core panel and VCV logo design © 2018 by Grayscale - -Derivative works may not use Core panel and VCV logo design. diff --git a/res/icons/LICENSE.md b/res/icons/LICENSE.md deleted file mode 100644 index e20f4863..00000000 --- a/res/icons/LICENSE.md +++ /dev/null @@ -1,12 +0,0 @@ -All icons are licensed under CC BY 3.0. -https://creativecommons.org/licenses/by/3.0/ -https://thenounproject.com/ - -Paper by Madeleine Bennett from the Noun Project -Folder by Icon Solid from the Noun Project -Save by Landan Lloyd from the Noun Project -Cat by Nabilauzwa from the Noun Project -Stopwatch by Arthur Shlain from the Noun Project -Sound by Gregor Cresnar from the Noun Project -Refresh by un·delivered from the Noun Project -Lock by Andres Gleixner from the Noun Project diff --git a/res/icons/noun_1084369_cc.svg b/res/icons/noun_1084369_cc.svg deleted file mode 100644 index ed8bd940..00000000 --- a/res/icons/noun_1084369_cc.svg +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - image/svg+xml - - Cycles - - - - - - Cycles - - diff --git a/res/icons/noun_1240789_cc.svg b/res/icons/noun_1240789_cc.svg deleted file mode 100644 index f984277a..00000000 --- a/res/icons/noun_1240789_cc.svg +++ /dev/null @@ -1,47 +0,0 @@ - -image/svg+xml111all111all \ No newline at end of file diff --git a/res/icons/noun_1343811_cc.svg b/res/icons/noun_1343811_cc.svg deleted file mode 100644 index 4765bdeb..00000000 --- a/res/icons/noun_1343811_cc.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - image/svg+xml - - 7.3 - - - - - - 7.3 - Created with Sketch. - - - - - - diff --git a/res/icons/noun_1343816_cc.svg b/res/icons/noun_1343816_cc.svg deleted file mode 100644 index d3aa67c5..00000000 --- a/res/icons/noun_1343816_cc.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - image/svg+xml - - 8.3 - - - - - - 8.3 - Created with Sketch. - - - - - - diff --git a/res/icons/noun_146097_cc.svg b/res/icons/noun_146097_cc.svg deleted file mode 100644 index 749d0c11..00000000 --- a/res/icons/noun_146097_cc.svg +++ /dev/null @@ -1,56 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/res/icons/noun_1745061_cc.svg b/res/icons/noun_1745061_cc.svg deleted file mode 100644 index aa226944..00000000 --- a/res/icons/noun_1745061_cc.svg +++ /dev/null @@ -1,57 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/res/icons/noun_305536_cc.svg b/res/icons/noun_305536_cc.svg deleted file mode 100644 index 1ee24be8..00000000 --- a/res/icons/noun_305536_cc.svg +++ /dev/null @@ -1,62 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/res/icons/noun_31859_cc.svg b/res/icons/noun_31859_cc.svg deleted file mode 100644 index ff873c99..00000000 --- a/res/icons/noun_31859_cc.svg +++ /dev/null @@ -1,47 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/res/icons/noun_468341_cc.svg b/res/icons/noun_468341_cc.svg deleted file mode 100644 index 340ff335..00000000 --- a/res/icons/noun_468341_cc.svg +++ /dev/null @@ -1,56 +0,0 @@ - -image/svg+xml \ No newline at end of file diff --git a/src/app/ModuleBrowser.cpp b/src/app/ModuleBrowser.cpp index dd4d6938..de58ddc5 100644 --- a/src/app/ModuleBrowser.cpp +++ b/src/app/ModuleBrowser.cpp @@ -249,16 +249,16 @@ struct ModelBox : widget::OpaqueWidget { std::string text; text = model->plugin->brand; text += " " + model->name; - if (model->description != "") - text += "\n" + model->description; // Tags - if (!model->tags.empty()) { - text += "\nTags: "; - for (size_t i = 0; i < model->tags.size(); i++) { - if (i > 0) - text += ", "; - text += model->tags[i]; - } + text += "\nTags: "; + for (size_t i = 0; i < model->tags.size(); i++) { + if (i > 0) + text += ", "; + text += model->tags[i]; + } + // Description + if (model->description != "") { + text += "\n" + model->description; } ui::Tooltip *tooltip = new ui::Tooltip; tooltip->text = text; diff --git a/src/asset.cpp b/src/asset.cpp index e833d781..9de69a98 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -112,6 +112,7 @@ void init() { templatePath = userDir + "/template.vcv"; } else { + logPath = userDir + "/log.txt"; pluginsPath = userDir + "/plugins-v" + app::ABI_VERSION; settingsPath = userDir + "/settings-v" + app::ABI_VERSION + ".json"; autosavePath = userDir + "/autosave-v" + app::ABI_VERSION + ".vcv"; @@ -139,6 +140,7 @@ std::string plugin(plugin::Plugin *plugin, std::string filename) { std::string systemDir; std::string userDir; +std::string logPath; std::string pluginsPath; std::string settingsPath; std::string autosavePath; diff --git a/src/logger.cpp b/src/logger.cpp index b923bbb5..85af9252 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -21,10 +21,9 @@ void init() { return; } - std::string logFilename = asset::user("log.txt"); - outputFile = fopen(logFilename.c_str(), "w"); + outputFile = fopen(asset::logPath.c_str(), "w"); if (!outputFile) { - fprintf(stderr, "Could not open log at %s\n", logFilename.c_str()); + fprintf(stderr, "Could not open log at %s\n", asset::logPath.c_str()); } } diff --git a/src/main.cpp b/src/main.cpp index 961e490b..8687640b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,7 +22,6 @@ #include #include // for getopt #include // for signal - #if defined ARCH_WIN #include // for CreateMutex #endif @@ -31,18 +30,19 @@ using namespace rack; static void fatalSignalHandler(int sig) { - // Only catch one signal - static bool caught = false; - bool localCaught = caught; - caught = true; - if (localCaught) - exit(1); + // Ignore this signal to avoid recursion. + signal(sig, NULL); + // Ignore abort() since we call it below. + signal(SIGABRT, NULL); FATAL("Fatal signal %d. Stack trace:\n%s", sig, system::getStackTrace().c_str()); - // osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Rack has crashed. See log.txt for details."); + // This might fail because we might not be in the main thread. + // But oh well, we're crashing anyway. + std::string text = app::APP_NAME + " has crashed. See " + asset::logPath + " for details."; + osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, text.c_str()); - exit(1); + abort(); } @@ -56,6 +56,9 @@ int main(int argc, char *argv[]) { exit(1); } (void) instanceMutex; + + // Don't display "Assertion failed!" dialog message. + _set_error_mode(_OUT_TO_STDERR); #endif std::string patchPath; @@ -98,8 +101,6 @@ int main(int argc, char *argv[]) { logger::init(); // We can now install a signal handler and log the output - // Mac has its own decent crash handler -#if 0 if (!settings::devMode) { signal(SIGABRT, fatalSignalHandler); signal(SIGFPE, fatalSignalHandler); @@ -107,7 +108,6 @@ int main(int argc, char *argv[]) { signal(SIGSEGV, fatalSignalHandler); signal(SIGTERM, fatalSignalHandler); } -#endif // Log environment INFO("%s v%s", app::APP_NAME.c_str(), app::APP_VERSION.c_str()); diff --git a/src/network.cpp b/src/network.cpp index 74240daf..eeef0f07 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -1,7 +1,6 @@ #include #define CURL_STATICLIB #include -#include namespace rack { @@ -79,12 +78,11 @@ json_t *requestJson(Method method, std::string url, json_t *dataJ) { curl_easy_setopt(curl, CURLOPT_POSTFIELDS, reqStr); std::string resText; - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText); // Perform request - // INFO("Requesting %s", url.c_str()); + // DEBUG("Requesting %s", url.c_str()); // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); CURLcode res = curl_easy_perform(curl); @@ -132,7 +130,6 @@ bool requestDownload(std::string url, const std::string &filename, float *progre curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferInfoCallback); curl_easy_setopt(curl, CURLOPT_XFERINFODATA, progress); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); // Fail on 4xx and 5xx HTTP codes curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); @@ -157,37 +154,6 @@ std::string encodeUrl(const std::string &s) { return ret; } -std::string computeSHA256File(const std::string &filename) { - FILE *f = fopen(filename.c_str(), "rb"); - if (!f) - return ""; - - uint8_t hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha256; - SHA256_Init(&sha256); - const int bufferLen = 1 << 15; - uint8_t *buffer = new uint8_t[bufferLen]; - int len = 0; - while ((len = fread(buffer, 1, bufferLen, f))) { - SHA256_Update(&sha256, buffer, len); - } - SHA256_Final(hash, &sha256); - delete[] buffer; - fclose(f); - - // Convert binary hash to hex - char hashHex[64]; - const char hexTable[] = "0123456789abcdef"; - for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { - uint8_t h = hash[i]; - hashHex[2*i + 0] = hexTable[h >> 4]; - hashHex[2*i + 1] = hexTable[h & 0x0f]; - } - - std::string str(hashHex, sizeof(hashHex)); - return str; -} - std::string urlPath(const std::string &url) { CURLU *curl = curl_url(); DEFER({ diff --git a/src/patch.cpp b/src/patch.cpp index f8eb463d..3cfa849b 100644 --- a/src/patch.cpp +++ b/src/patch.cpp @@ -138,8 +138,9 @@ void PatchManager::saveAsDialog() { std::free(pathC); }); + // Append .vcv extension if no extension was given. std::string pathStr = pathC; - if (string::filenameExtension(pathStr).empty()) { + if (string::filenameExtension(string::filename(pathStr)) == "") { pathStr += ".vcv"; } diff --git a/src/plugin.cpp b/src/plugin.cpp index ed6ec303..a307ba96 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -247,7 +247,7 @@ static void extractPackages(std::string path) { std::string message; for (std::string packagePath : system::getEntries(path)) { - if (string::filenameExtension(packagePath) != "zip") + if (string::filenameExtension(string::filename(packagePath)) != "zip") continue; INFO("Extracting package %s", packagePath.c_str()); // Extract package diff --git a/src/system.cpp b/src/system.cpp index 29737277..f3215650 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -2,8 +2,10 @@ #include #include +#include #include #include +#include // for __cxxabiv1::__cxa_demangle #if defined ARCH_LIN || defined ARCH_MAC #include @@ -166,10 +168,36 @@ std::string getStackTrace() { stackLen = backtrace(stack, stackLen); char **strings = backtrace_symbols(stack, stackLen); + // Skip the first line because it's this function. for (int i = 1; i < stackLen; i++) { - s += string::f("%d: %s\n", stackLen - i - 1, strings[i]); + s += string::f("%d: ", stackLen - i - 1); + std::string line = strings[i]; +#if 0 + // Parse line + std::regex r(R"((.*)\((.*)\+(.*)\) (.*))"); + std::smatch match; + if (std::regex_search(line, match, r)) { + s += match[1].str(); + s += "("; + std::string symbol = match[2].str(); + // Demangle symbol + char *symbolD = __cxxabiv1::__cxa_demangle(symbol.c_str(), NULL, NULL, NULL); + if (symbolD) { + symbol = symbolD; + free(symbolD); + } + s += symbol; + s += "+"; + s += match[3].str(); + s += ")"; + } +#else + s += line; +#endif + s += "\n"; } free(strings); + #elif defined ARCH_WIN HANDLE process = GetCurrentProcess(); SymInitialize(process, NULL, true);