diff --git a/.github/workflows/dos-djgpp.yml b/.github/workflows/dos-djgpp.yml index e16ee23..d28d938 100644 --- a/.github/workflows/dos-djgpp.yml +++ b/.github/workflows/dos-djgpp.yml @@ -22,31 +22,31 @@ name: C/C++ CI (DOS DJGPP) on: push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + branches: [ "*" ] + paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip + workflow_dispatch: env: - CMAKE_C_COMPILER: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc - CMAKE_CXX_COMPILER: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++ + CC: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-gcc + CXX: ${{ github.workspace }}/djgpp/bin/i586-pc-msdosdjgpp-g++ CMAKE_FIND_ROOT_PATH: ${{ github.workspace }}/djgpp - CMAKE_FIND_ROOT_PATH_MODE_PROGRAM: NEVER - CMAKE_FIND_ROOT_PATH_MODE_LIBRARY: ONLY - CMAKE_FIND_ROOT_PATH_MODE_INCLUDE: ONLY - CMAKE_FIND_ROOT_PATH_MODE_PACKAGE: ONLY WATT_ROOT: ${{ github.workspace }}/djgpp/watt32 jobs: build: runs-on: ubuntu-latest steps: + - name: Checkout Source Tree + uses: actions/checkout@v3 + - name: Setup build environment run: | sudo apt -y update - sudo apt -y install build-essential cmake wget 7zip git flex nasm libslang2-dev pkg-config libslang2-modules gcc-multilib + sudo apt -y install build-essential cmake wget 7zip git flex libfl-dev nasm libslang2-dev pkg-config libslang2-modules gcc-multilib - name: Download and Setup DJGPP Toolchain run: | + pushd ${{ github.workspace }} wget https://github.com/andrewwutw/build-djgpp/releases/download/v3.4/djgpp-linux64-gcc1220.tar.bz2 tar xjf djgpp-linux64-gcc1220.tar.bz2 cd ${{ github.workspace }}/djgpp @@ -54,40 +54,34 @@ jobs: cd watt32/util make clean && make linux cd ../src + source ${{ github.workspace }}/djgpp/setenv ./configur.sh djgpp make -f djgpp.mak - ln -s ${{ github.workspace }}/djgpp/watt32/lib/libwatt.a ${{ github.workspace }}/djgpp/lib + ln -s ${WATT_ROOT}/lib/libwatt.a ${{ github.workspace }}/djgpp/lib - - name: Checkout and Cross Compile OpenSSL 3.1 + - name: Checkout and Cross Compile OpenSSL 3.1.2 run: | git clone https://github.com/UMSKT/openssl.git openssl pushd openssl - git checkout openssl-3.1.1 source ${{ github.workspace }}/djgpp/setenv ./Configure no-threads -DOPENSSL_DEV_NO_ATOMICS --prefix=${{ github.workspace }}/djgpp DJGPP make && make install popd - ls ${{ github.workspace }}/djgpp/i586-pc-msdosdjgpp/bin/ - - - name: Checkout Source Tree - uses: actions/checkout@v3 - name: Build - uses: threeal/cmake-action@v1.2.0 - with: - c-compiler: gcc - cxx-compiler: g++ - options: OPENSSL_ROOT_DIR:string=${{ github.workspace }}/djgpp DJGPP_WATT32=ON - run-build: true - - - name: Test & Move files to correct directory run: | - mkdir -p build/actions_upload - mv build/umskt build/actions_upload/umskt + source ${{ github.workspace }}/djgpp/setenv + pushd build + cmake ../ -D DJGPP_WATT32=${WATT_ROOT}/lib/libwatt.a -D CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} + make + + - name: Move executable to upload directory + run: | + mkdir build/actions_upload + mv build/umskt.exe build/actions_upload/ - name: Upload build artifact uses: actions/upload-artifact@v3.1.2 with: - name: UMSKT-DOS-DJGPP + name: UMSKT-DOS path: build/actions_upload - diff --git a/.github/workflows/freebsd.yml b/.github/workflows/freebsd.yml index 0dab457..bc75a3a 100644 --- a/.github/workflows/freebsd.yml +++ b/.github/workflows/freebsd.yml @@ -21,10 +21,10 @@ name: C/C++ CI (FreeBSD) on: - push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + push: + branches: [ "*" ] + paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip + workflow_dispatch: jobs: build: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index ce884c5..fcb5f00 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -22,9 +22,9 @@ name: C/C++ CI (Linux) on: push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + branches: [ "*" ] + paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip + workflow_dispatch: jobs: build: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 0623445..74a3d68 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -22,9 +22,9 @@ name: C/C++ CI (macOS) on: push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + branches: [ "*" ] + paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip + workflow_dispatch: jobs: build-x86: @@ -56,5 +56,5 @@ jobs: - name: Upload build artifact uses: actions/upload-artifact@v3.1.2 with: - name: UMSKT-macOS-${{ matrix.arch }}-static + name: UMSKT-macOS-${{ matrix.arch }} path: build/actions_upload diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 237485a..50c6cd8 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -22,9 +22,9 @@ name: C/C++ CI (Windows) on: push: - branches: [ "master" ] - pull_request: - branches: [ "master" ] + branches: [ "*" ] + paths-ignore: [ '**.md', 'doc/**', '.idea/**'] # If only these files are edited, skip + workflow_dispatch: jobs: build-32bit: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c80a12..ecff099 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,92 +18,187 @@ # @FileCreated by Andrew on 05/30/2023 # @Maintainer Neo -cmake_minimum_required(VERSION 3.12) +CMAKE_MINIMUM_REQUIRED(VERSION 3.12) +PROJECT(UMSKT) +SET(CMAKE_CXX_STANDARD 17) +SET(CMAKE_POSITION_INDEPENDENT_CODE ON) +SET(CMAKE_OSX_SYSROOT "macosx" CACHE PATH "macOS SDK path") +OPTION(UMSKT_USE_SHARED_OPENSSL "Force linking against the system-wide OpenSSL library" OFF) +OPTION(MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF) +OPTION(DJGPP_WATT32 "Enable compilation and linking with DJGPP/WATT32/OpenSSL" OFF) +OPTION(MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF) -project(UMSKT) -set(CMAKE_OSX_SYSROOT "macosx" CACHE PATH "macOS SDK path") +SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS}) +SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS}) -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_POSITION_INDEPENDENT_CODE ON) - -option(UMSKT_USE_SHARED_OPENSSL "Force linking against the system-wide OpenSSL library" OFF) -option(MUSL_STATIC "Enable fully static builds in a muslc environment (i.e. Alpine Linux)" OFF) -option(DJGPP_WATT32 "Enable compilation and linking with DJGPP/WATT32/OpenSSL" OFF) -option(MSVC_MSDOS_STUB "Specify a custom MS-DOS stub for a 32-bit MSVC compilation" OFF) - -find_package(OpenSSL REQUIRED) - -if(NOT OpenSSL_FOUND) - message(FATAL_ERROR "OpenSSL Development Libraries Not Found. Please install the required OpenSSL development package.") +# macOS does not support static build +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + SET(UMSKT_USE_SHARED_OPENSSL ON) endif() -if(UMSKT_USE_SHARED_OPENSSL) - set(OPENSSL_USE_STATIC_LIBS FALSE) - set(OPENSSL_MSVC_STATIC_RT FALSE) -else() - set(OPENSSL_USE_STATIC_LIBS TRUE) - set(OPENSSL_MSVC_STATIC_RT TRUE) +# neither does dos idk i'm trying random stuff +if (DJGPP_WATT32) + SET(UMSKT_USE_SHARED_OPENSSL ON) endif() -if(MUSL_STATIC AND NOT UMSKT_USE_SHARED_OPENSSL) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") - set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -static-libstdc++") - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") +IF(UMSKT_USE_SHARED_OPENSSL) + SET(OPENSSL_USE_STATIC_LIBS FALSE) + SET(OPENSSL_MSVC_STATIC_RT FALSE) + MESSAGE(WARNING "[UMSKT] Forcing shared OpenSSL runtime") +ELSE() + SET(OPENSSL_USE_STATIC_LIBS TRUE) + SET(OPENSSL_MSVC_STATIC_RT TRUE) +ENDIF() + + + +IF(DJGPP_WATT32) + SET(CMAKE_SYSTEM_NAME MSDOS) + SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + SET(UMSKT_LINK_LIBS ${UMSKT_LINK_LIBS} ${DJGPP_WATT32}) + SET(UMSKT_LINK_DIRS ${UMSKT_LINK_DIRS} ${WATT_ROOT}/lib) +ENDIF() + +# find the system installed OpenSSL development library +FIND_PACKAGE(OpenSSL REQUIRED) +IF(NOT OPENSSL_FOUND) + MESSAGE(SEND_ERROR "OpenSSL Development Libraries Not Found") + MESSAGE(SEND_ERROR "Please consult your package manager of choice to install the prerequisite") + MESSAGE(SEND_ERROR "The package name is commonly called libssl-dev or openssl-dev depending on distribution") + MESSAGE(FATAL_ERROR "Can not continue without OpenSSL") +ENDIF() + +# if we found shared libraries - do the following: +STRING(REGEX MATCH "(\\.so|\\.dll|\\.dylib)$" OPENSSL_CRYPTO_SHARED "${OPENSSL_CRYPTO_LIBRARY}") +IF(OPENSSL_CRYPTO_SHARED) + MESSAGE(STATUS "[UMSKT] Detected Shared library version of OpenSSL") + SET(BUILD_SHARED_LIBS ON) +ELSE() + MESSAGE(STATUS "[UMSKT] Detected Static Library version of OpenSSL") +ENDIF() + +if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + SET(BUILD_SHARED_LIBS ON) + MESSAGE(STATUS "[UMSKT] macOS has no static library - Shared library forced on") endif() -include(cmake/CPM.cmake) +if (DJGPP_WATT32) + SET(BUILD_SHARED_LIBS ON) + MESSAGE(STATUS "[UMSKT] DOS has no static library - Shared library forced on") +endif() +# if we're compiling with MSVC, respect the DEBUG compile option +IF(MSVC) + SET(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + IF(NOT BUILD_SHARED_LIBS) + SET(CMAKE_CXX_FLAGS_RELEASE "/MT") + SET(CMAKE_CXX_FLAGS_DEBUG "/MTd") + ELSE() + SET(CMAKE_CXX_FLAGS_RELEASE "/MD") + SET(CMAKE_CXX_FLAGS_DEBUG "/MDd") + ENDIF() + SET(CMAKE_EXE_LINKER_FLAGS "/INCREMENTAL:NO /NODEFAULTLIB:MSVCRT") + SET(CMAKE_ENABLE_EXPORTS ON) + SET(UMSKT_EXE_WINDOWS_EXTRA src/windows/umskt.rc) + SET(UMSKT_EXE_WINDOWS_DLL src/windows/dllmain.cpp) +ENDIF() + +IF(MUSL_STATIC) + MESSAGE(STATUS "[UMSKT] Performing a fully static build using muslc") + SET(CMAKE_EXE_LINKER_FLAGS "-static -static-libgcc -static-libstdc++") + SET(CMAKE_SHARED_LINKER_FLAGS "-static -static-libgcc -static-libstdc++") + SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc -static-libstdc++") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") +ENDIF() + +# initalize cpm.CMake +INCLUDE(cmake/CPM.cmake) + +# fetch cpm.CMake dependencies +# Include JSON development library CPMAddPackage( - NAME nlohmann_json - GITHUB_REPOSITORY nlohmann/json - VERSION 3.11.2 + NAME nlohmann_json + GITHUB_REPOSITORY nlohmann/json + VERSION 3.11.2 ) +# Include fmt development library CPMAddPackage( - NAME fmt - GITHUB_REPOSITORY fmtlib/fmt - GIT_TAG 10.0.0 - VERSION 10.0.0 + NAME fmt + GITHUB_REPOSITORY fmtlib/fmt + GIT_TAG 10.0.0 + VERSION 10.0.0 ) +# Include cmrc resource compiler CPMAddPackage( - NAME cmrc - GITHUB_REPOSITORY vector-of-bool/cmrc - GIT_TAG 2.0.1 - VERSION 2.0.1 + NAME cmrc + GITHUB_REPOSITORY vector-of-bool/cmrc + GIT_TAG 2.0.1 + VERSION 2.0.1 ) -# For Emscripten builds, set CMAKE_TOOLCHAIN_FILE to the appropriate file -set(EMSCRIPTEN_BUILD OFF CACHE BOOL "Build for Emscripten" FORCE) -if(EMSCRIPTEN_BUILD) - set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/cmake/Emscripten.cmake" CACHE STRING "Emscripten toolchain file") -endif() +# Include Crypto++ development library +#CPMAddPackage( +# NAME cryptopp-cmake +# GITHUB_REPOSITORY abdes/cryptopp-cmake +# GIT_TAG CRYPTOPP_8_8_0 +# VERSION 8.8.0 +# OPTIONS "CRYPTOPP_BUILD_TESTING OFF" +#) +#include googletest unit testing library +#CPMAddPackage( +# NAME googletest +# GITHUB_REPOSITORY google/googletest +# VERSION 1.13.0 +# OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt" +#) + +### Resource compilation CMRC_ADD_RESOURCE_LIBRARY(umskt-rc ALIAS umskt::rc NAMESPACE umskt keys.json) -set(LIBUMSKT_SRC - src/libumskt/libumskt.cpp - src/libumskt/pidgen3/BINK1998.cpp - src/libumskt/pidgen3/BINK2002.cpp - src/libumskt/pidgen3/key.cpp - src/libumskt/pidgen3/util.cpp - src/libumskt/confid/confid.cpp - src/libumskt/pidgen2/PIDGEN2.cpp - src/libumskt/debugoutput.cpp -) +SET(LIBUMSKT_SRC src/libumskt/libumskt.cpp src/libumskt/pidgen3/BINK1998.cpp src/libumskt/pidgen3/BINK2002.cpp src/libumskt/pidgen3/key.cpp src/libumskt/pidgen3/util.cpp src/libumskt/confid/confid.cpp src/libumskt/pidgen2/PIDGEN2.cpp src/libumskt/debugoutput.cpp) -if(UMSKT_USE_SHARED_OPENSSL) - add_library(_umskt SHARED ${LIBUMSKT_SRC}) -else() - add_library(_umskt STATIC ${LIBUMSKT_SRC}) -endif() +#### Separate Build Path for emscripten +IF (EMSCRIPTEN) + ADD_EXECUTABLE(umskt ${LIBUMSKT_SRC}) + TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) + TARGET_LINK_LIBRARIES(umskt -static OpenSSL::Crypto cryptopp::cryptopp fmt) + SET(CMAKE_EXECUTABLE_SUFFIX ".html") -target_include_directories(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) -target_link_libraries(_umskt PRIVATE OpenSSL::Crypto fmt) + SET_TARGET_PROPERTIES(umskt PROPERTIES COMPILE_FLAGS "-Os -sEXPORTED_RUNTIME_METHODS=ccall,cwrap") + SET_TARGET_PROPERTIES(umskt PROPERTIES LINK_FLAGS "-Os -sWASM=1 -sEXPORT_ALL=1 -sEXPORTED_RUNTIME_METHODS=ccall,cwrap --no-entry") +ELSE() + IF(NOT UMSKT_USE_SHARED_OPENSSL) + ### Static library compilation + ADD_LIBRARY(_umskt STATIC ${LIBUMSKT_SRC}) + TARGET_INCLUDE_DIRECTORIES(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) + TARGET_LINK_LIBRARIES(_umskt -static OpenSSL::Crypto fmt ${UMSKT_LINK_LIBS}) + ELSE() + ### Shared library compilation + ADD_LIBRARY(_umskt SHARED ${LIBUMSKT_SRC} ${UMSKT_EXE_WINDOWS_EXTRA} ${UMSKT_EXE_WINDOWS_DLL}) + TARGET_INCLUDE_DIRECTORIES(_umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) + TARGET_LINK_LIBRARIES(_umskt OpenSSL::Crypto fmt ${UMSKT_LINK_LIBS}) + TARGET_LINK_DIRECTORIES(_umskt PUBLIC ${UMSKT_LINK_DIRS}) + ENDIF() -add_executable(umskt src/main.cpp src/cli.cpp ${UMSKT_EXE_WINDOWS_EXTRA}) + ### UMSKT executable compilation + ADD_EXECUTABLE(umskt src/main.cpp src/cli.cpp ${UMSKT_EXE_WINDOWS_EXTRA}) + TARGET_INCLUDE_DIRECTORIES(umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) + TARGET_LINK_LIBRARIES(umskt _umskt OpenSSL::Crypto fmt nlohmann_json::nlohmann_json umskt::rc ${UMSKT_LINK_LIBS}) + TARGET_LINK_DIRECTORIES(umskt PUBLIC ${UMSKT_LINK_DIRS}) + IF(MSVC AND MSVC_MSDOS_STUB) + SET_PROPERTY(TARGET umskt APPEND PROPERTY LINK_FLAGS /STUB:${MSVC_MSDOS_STUB}) + ENDIF() -target_include_directories(umskt PUBLIC ${OPENSSL_INCLUDE_DIR}) -target_link_libraries(umskt PRIVATE _umskt OpenSSL::Crypto fmt nlohmann_json::nlohmann_json umskt::rc) + ### Copy Shared Libraries and dependency files + IF (OPENSSL_CRYPTO_SHARED) + GET_FILENAME_COMPONENT(OPENSSL_CRYPTO_LIBRARY_FILENAME ${OPENSSL_CRYPTO_LIBRARY} NAME) + CONFIGURE_FILE(${OPENSSL_CRYPTO_LIBRARY} "${CMAKE_CURRENT_BINARY_DIR}/${OPENSSL_CRYPTO_LIBRARY_FILENAME}" COPYONLY) + ENDIF() +ENDIF() diff --git a/README.md b/README.md index 408fcc3..69700ed 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ [![C/C++ CI (Linux)](https://github.com/UMSKT/UMSKT/actions/workflows/linux.yml/badge.svg)](../../actions/workflows/linux.yml) -[![C/C++ CI (FreeBSD)](https://github.com/UMSKT/UMSKT/actions/workflows/freebsd.yml/badge.svg)](../../actions/workflows/dos-djgpp.yml) +[![C/C++ CI (FreeBSD)](https://github.com/UMSKT/UMSKT/actions/workflows/freebsd.yml/badge.svg)](../../actions/workflows/freebsd.yml) -[![C/C++ CI (DOS DJGPP)](https://github.com/UMSKT/UMSKT/actions/workflows/dos-djgpp.yml/badge.svg)](../../actions/workflows/freebsd.yml) +[![C/C++ CI (DOS DJGPP)](https://github.com/UMSKT/UMSKT/actions/workflows/dos-djgpp.yml/badge.svg)](../../actions/workflows/dos-djgpp.yml) ------ diff --git a/src/cli.cpp b/src/cli.cpp index 80fe38f..56dbf8e 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -61,6 +61,7 @@ void CLI::showHelp(char *argv[]) { fmt::print("\t-s --serial\tspecifies a serial to use in the product ID (defaults to random, BINK1998 only)\n"); fmt::print("\t-u --upgrade\tspecifies the Product Key will be an \"Upgrade\" version\n"); fmt::print("\t-V --validate\tproduct key to validate signature\n"); + fmt::print("\t-N --nonewlines\tdisables newlines (for easier embedding in other apps)\n"); fmt::print("\n"); } @@ -81,13 +82,13 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) { false, false, false, + false, MODE_BINK1998_GENERATE, WINDOWS }; for (int i = 1; i < argc; i++) { std::string arg = argv[i]; - if (arg == "-v" || arg == "--verbose") { options->verbose = true; UMSKT::setDebugOutput(stderr); @@ -193,7 +194,10 @@ int CLI::parseCommandLine(int argc, char* argv[], Options* options) { options->keyToCheck = argv[i+1]; options->applicationMode = MODE_BINK1998_VALIDATE; i++; - } else { + + } else if (arg == "-N" || arg == "--nonewlines") { + options->nonewlines = true; + } else { options->error = true; } } @@ -446,10 +450,9 @@ int CLI::BINK1998Generate() { if (this->options.verbose) { fmt::print("\nSuccess count: {}/{}", this->count, this->total); } -#ifndef _WIN32 - fmt::print("\n"); -#endif - + if (this->options.nonewlines == false) { + fmt::print("\n"); + } return 0; } @@ -495,9 +498,9 @@ int CLI::BINK2002Generate() { if (this->options.verbose) { fmt::print("\nSuccess count: {}/{}", this->count, this->total); } -#ifndef _WIN32 - fmt::print("\n"); -#endif + if (this->options.nonewlines == false) { + fmt::print("\n"); + } return 0; } @@ -571,9 +574,9 @@ int CLI::ConfirmationID() { case SUCCESS: fmt::print(confirmation_id); -#ifndef _WIN32 - fmt::print("\n"); -#endif + if (this->options.nonewlines == false) { + fmt::print("\n"); + } return 0; default: diff --git a/src/cli.h b/src/cli.h index 43b329d..0c80bf7 100644 --- a/src/cli.h +++ b/src/cli.h @@ -67,6 +67,7 @@ struct Options { bool help; bool error; bool list; + bool nonewlines; MODE applicationMode; ACTIVATION_ALGORITHM activationMode;