diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index cf6b2f11..636776ea 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -3,22 +3,83 @@ name: windows on: push: branches: [ "develop", "release/*" ] + tags: + - '[0-9]+.[0-9]+.[0-9]+*' pull_request: branches: [ "develop", "release/*" ] + workflow_dispatch: env: BUILD_TYPE: Release jobs: - build: + setup: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.read_version.outputs.version }} + short_hash: ${{ steps.read_version.outputs.short_hash }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Read version from file + id: read_version + run: | + if [ "${{ github.ref_type }}" == "tag" ]; then + VERSION=${{ github.ref_name }} + SHORT_HASH="" + else + MAJOR_MINOR=$(cut -d. -f1-2 VERSION) + VERSION="${MAJOR_MINOR}.99" + # Get the short hash of the current commit + COMMIT_HASH=$(echo ${{ github.sha }} | cut -c1-7) + SHORT_HASH="-$COMMIT_HASH" + fi + + echo "VERSION=$VERSION" >> $GITHUB_ENV + echo "version=$VERSION" >> $GITHUB_OUTPUT + + echo "SHORT_HASH=$SHORT_HASH" >> $GITHUB_ENV + echo "short_hash=$SHORT_HASH" >> $GITHUB_OUTPUT + + - name: Print version and hash + run: | + echo "Qucs-S version is ${{ env.VERSION }}" + echo "Qucs-S short hash is ${{ env.SHORT_HASH }}" + + build-windows: + runs-on: windows-latest + needs: setup + strategy: + fail-fast: false + steps: + - name: Disable autocrlf + shell: pwsh + run: | + git config --global core.autocrlf false + git config --global core.eol lf + + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install gperf using Chocolatey + shell: pwsh + run: | + choco install gperf winflexbison3 -y + + - name: '⚙️ Install CMake' + uses: lukka/get-cmake@latest + + - name: Build with cmake + shell: pwsh + run: | + cmake.exe -B build/ -G "Ninja" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + cmake.exe --build build/ --parallel --config ${{env.BUILD_TYPE}} + + build-windows-msys2: runs-on: windows-latest + needs: setup strategy: fail-fast: false - matrix: - sys: - - mingw64 - - clang64 - - ucrt64 defaults: run: shell: msys2 {0} @@ -28,29 +89,21 @@ jobs: run: | git config --global core.autocrlf false git config --global core.eol lf + - name: Checkout repository uses: actions/checkout@v4 - name: Set up MSYS2 uses: msys2/setup-msys2@v2 with: - msystem: ${{ matrix.sys }} + msystem: ucrt64 cache: true update: true - install: >- - bison - flex - dos2unix - pacboy: >- - cmake:p - gcc:p - make:p - python:p - gperf:p + install: bison flex dos2unix zip p7zip + pacboy: cmake:p gcc:p make:p ninja:p gperf:p - name: Build with cmake run: | - ls -la - cmake.exe -B build/ -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - cmake.exe --build build/ -j`nproc` --config ${{env.BUILD_TYPE}} + cmake.exe -B build/ -G "Ninja" -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} + cmake.exe --build build/ --parallel --config ${{env.BUILD_TYPE}} diff --git a/CMakeLists.txt b/CMakeLists.txt index b9b77384..3f35e1de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,16 +184,6 @@ else() # Linux, OSX endif() -# -# Check for sed -# -find_program(SED_TOOL NAMES sed) -if(NOT SED_TOOL) - message(FATAL_ERROR "Unable to find sed") -else() - message(STATUS "Found sed: " ${SED_TOOL}) -endif() - # # Check for gperf # diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 687f5bd3..8a7f8ad9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -212,6 +212,12 @@ include_directories( ${qucs-core_BINARY_DIR}/src/components # generated verilog/[].core.h ) +add_executable(repl_reg repl_reg.cpp) +IF(WIN32) + SET(repl_reg_exe repl_reg.exe) +ELSE() # Unix + SET(repl_reg_exe repl_reg) +ENDIF() # # Replace 'evaluate::[whatever]' by NULL # @@ -220,22 +226,16 @@ include_directories( # add_custom_command( OUTPUT gperfappgen.h - COMMAND - ${SED_TOOL} -e 's/evaluate::[a-zA-Z0-9_]*/NULL/g' < - ${CMAKE_CURRENT_SOURCE_DIR}/applications.h > - ${CMAKE_CURRENT_BINARY_DIR}/gperfappgen.h - DEPENDS ${applications.h}) + COMMAND ${repl_reg_exe} ${CMAKE_CURRENT_SOURCE_DIR}/applications.h ${CMAKE_CURRENT_BINARY_DIR}/gperfappgen.h 0 + DEPENDS ${repl_reg_exe} ${applications.h} ) # # Compile gperfappgen * used to generate gperf input file (used in qucsator) # set(gperf_SRC gperfappgen.cpp gperfappgen.h) -IF(WIN32) - add_executable(gperfappgen.exe ${gperf_SRC}) -ELSE() # Unix - add_executable(gperfappgen ${gperf_SRC}) -ENDIF() +add_executable(gperfappgen ${gperf_SRC}) + # # Run gperfappgen, pipe to gperf input to gperfapphash.gph # @@ -244,10 +244,11 @@ IF(WIN32) ELSE() # Unix SET(gperfappgen_exe gperfappgen) ENDIF() + add_custom_command( OUTPUT gperfapphash.gph COMMAND ${gperfappgen_exe} > ${CMAKE_CURRENT_BINARY_DIR}/gperfapphash.gph && dos2unix ${CMAKE_CURRENT_BINARY_DIR}/gperfapphash.gph - DEPENDS ${gperfappgen}) + DEPENDS ${gperfappgen_exe}) # # Run gperf, create hash table. * -I, Include the necessary system include files @@ -258,9 +259,8 @@ add_custom_command( OUTPUT gperfapphash.cpp COMMAND ${GPERF_TOOL} -I -m 8 ${CMAKE_CURRENT_BINARY_DIR}/gperfapphash.gph > temp.gperf - COMMAND ${SED_TOOL} -e 's/{""},/{"",0},/g' < temp.gperf > - ${CMAKE_CURRENT_BINARY_DIR}/gperfapphash.cpp - DEPENDS gperfapphash.gph) + COMMAND ${repl_reg_exe} temp.gperf ${CMAKE_CURRENT_BINARY_DIR}/gperfapphash.cpp 1 + DEPENDS gperfapphash.gph ${repl_reg_exe}) # target <- source (includea) equation.cpp: gperfapphash.cpp # diff --git a/src/compat.h b/src/compat.h index 4e134483..2a90c1db 100644 --- a/src/compat.h +++ b/src/compat.h @@ -30,7 +30,7 @@ #endif -#if defined(_WIN32) & not defined(__MINGW32__) +#if defined(_WIN32) && defined(_MSC_VER) #define strcasecmp stricmp #endif diff --git a/src/converter/check_spice.cpp b/src/converter/check_spice.cpp index 2a8dce0c..2eecd156 100644 --- a/src/converter/check_spice.cpp +++ b/src/converter/check_spice.cpp @@ -34,7 +34,7 @@ #include #include -#if defined(_WIN32) & not defined(__MINGW32__) +#if defined(_WIN32) && defined(_MSC_VER) #define strcasecmp stricmp #endif diff --git a/src/converter/csv_producer.cpp b/src/converter/csv_producer.cpp index 0cfa3a5e..014b2337 100644 --- a/src/converter/csv_producer.cpp +++ b/src/converter/csv_producer.cpp @@ -49,7 +49,7 @@ struct csv_data { }; /* Definition of line separator. */ -#ifdef __MINGW32__ +#ifdef _WIN32 #define csv_crlf "\n" #else #define csv_crlf "\r\n" diff --git a/src/converter/parse_spice.ypp b/src/converter/parse_spice.ypp index b9948dc9..1f7c9b39 100644 --- a/src/converter/parse_spice.ypp +++ b/src/converter/parse_spice.ypp @@ -34,7 +34,7 @@ #include #include -#if defined(_WIN32) & not defined(__MINGW32__) +#if defined(_WIN32) && defined(_MSC_VER) #define strcasecmp stricmp #endif @@ -128,7 +128,7 @@ static struct value_t * spice_append_val_values (struct value_t * values, %} -%name-prefix "spice_" +%define api.prefix {spice_} %token TitleLine InvalidCharacter End Eol %token Identifier Digits Floats Nodes Options Function diff --git a/src/converter/parse_vcd.ypp b/src/converter/parse_vcd.ypp index 29dc63dd..301d9c01 100644 --- a/src/converter/parse_vcd.ypp +++ b/src/converter/parse_vcd.ypp @@ -43,7 +43,7 @@ %} -%name-prefix "vcd_" +%define api.prefix {vcd_} %token t_END %token t_COMMENT diff --git a/src/converter/scan_spice.lpp b/src/converter/scan_spice.lpp index af6566ae..142b9739 100644 --- a/src/converter/scan_spice.lpp +++ b/src/converter/scan_spice.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/converter/scan_vcd.lpp b/src/converter/scan_vcd.lpp index 49e42242..a72d0de1 100644 --- a/src/converter/scan_vcd.lpp +++ b/src/converter/scan_vcd.lpp @@ -40,7 +40,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/converter/touchstone_producer.cpp b/src/converter/touchstone_producer.cpp index 2a41f06b..8f70e6e3 100644 --- a/src/converter/touchstone_producer.cpp +++ b/src/converter/touchstone_producer.cpp @@ -58,7 +58,7 @@ struct touchstone_data_t { touchstone_data; /* Definition of line separator. */ -#ifdef __MINGW32__ +#ifdef _WIN32 #define touchstone_crlf "\n" #else #define touchstone_crlf "\r\n" diff --git a/src/math/real.h b/src/math/real.h index 88ef515c..701382aa 100644 --- a/src/math/real.h +++ b/src/math/real.h @@ -421,7 +421,8 @@ nr_double_t inline real (const nr_double_t r) { \param[in] r Real number \return Imaginary part of r */ -nr_double_t inline imag ([[maybe_unused]] const nr_double_t r) { +nr_double_t inline imag (const nr_double_t r) { + (void) r; return 0.0; } diff --git a/src/module.cpp b/src/module.cpp index e09465d7..82db09b6 100644 --- a/src/module.cpp +++ b/src/module.cpp @@ -39,7 +39,7 @@ #include "netdefs.h" #include "module.h" -#ifdef __MINGW32__ +#ifdef _WIN32 #include #else #include @@ -57,7 +57,7 @@ std::map< std::string, creator_t *, std::less > factorycreate; // factorydef hold the loaded modules definitions std::map< std::string, defs_t *, std::less > factorydef; -#if __MINGW32__ +#if _WIN32 std::list dl_list; // list to hold handles for dynamic libs std::list::iterator itr; #else @@ -467,14 +467,14 @@ void module::registerDynamicModules (char *proj, std::list modlist) #ifdef __linux__ absPathLib = absPathLib + "/" + *it + ".so"; #endif -#ifdef __MINGW32__ +#ifdef _WIN32 absPathLib = absPathLib + "\\" + *it + ".dll"; #endif // which lib is going to be loaded fprintf( stdout, "try loading %s\n", absPathLib.c_str() ); -#if __MINGW32__ +#if _WIN32 // Load the DLL HINSTANCE dlib = ::LoadLibrary(TEXT(absPathLib.c_str())); if (!dlib) { @@ -551,7 +551,7 @@ void module::registerDynamicModules (char *proj, std::list modlist) void module::closeDynamicLibs() { for(itr=dl_list.begin(); itr!=dl_list.end(); itr++){ -#if __MINGW32__ +#if _WIN32 FreeLibrary(*itr); #else dlclose(*itr); diff --git a/src/parse_citi.ypp b/src/parse_citi.ypp index 1fe08094..f25d05fc 100644 --- a/src/parse_citi.ypp +++ b/src/parse_citi.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "citi_" +%define api.prefix {citi_} %token InvalidCharacter %token Float diff --git a/src/parse_csv.ypp b/src/parse_csv.ypp index 08584578..7fec320f 100644 --- a/src/parse_csv.ypp +++ b/src/parse_csv.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "csv_" +%define api.prefix {csv_} %token InvalidCharacter %token Float diff --git a/src/parse_dataset.ypp b/src/parse_dataset.ypp index 5b46defa..c4c57d60 100644 --- a/src/parse_dataset.ypp +++ b/src/parse_dataset.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "dataset_" +%define api.prefix {dataset_} %token InvalidCharacter %token Identifier diff --git a/src/parse_mdl.ypp b/src/parse_mdl.ypp index e5005f4b..ea3115ef 100644 --- a/src/parse_mdl.ypp +++ b/src/parse_mdl.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "mdl_" +%define api.prefix {mdl_} %token LINK %token Identifier diff --git a/src/parse_netlist.ypp b/src/parse_netlist.ypp index e8a3bdd9..bb1fc08d 100644 --- a/src/parse_netlist.ypp +++ b/src/parse_netlist.ypp @@ -46,7 +46,7 @@ using namespace qucs; %} -%name-prefix "netlist_" +%define api.prefix {netlist_} %token InvalidCharacter %token Identifier diff --git a/src/parse_touchstone.ypp b/src/parse_touchstone.ypp index 48edc534..31a8c9a2 100644 --- a/src/parse_touchstone.ypp +++ b/src/parse_touchstone.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "touchstone_" +%define api.prefix {touchstone_} %token InvalidCharacter %token Float diff --git a/src/parse_zvr.ypp b/src/parse_zvr.ypp index 12901c16..441c2285 100644 --- a/src/parse_zvr.ypp +++ b/src/parse_zvr.ypp @@ -49,7 +49,7 @@ using namespace qucs; %} -%name-prefix "zvr_" +%define api.prefix {zvr_} %token ZVR %token Version diff --git a/src/repl_reg.cpp b/src/repl_reg.cpp new file mode 100644 index 00000000..52228741 --- /dev/null +++ b/src/repl_reg.cpp @@ -0,0 +1,76 @@ +#include +#include +#include +#include + + +#if DEBUG +#define DEBUG_PRINT(x) /*std::cout << x << std::endl;*/ +#else +#define DEBUG_PRINT(x) +#endif + +int main(int argc, char* argv[]) { + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " \n"; + return 1; + } + + DEBUG_PRINT("Debug: Starting program with arguments:"); + DEBUG_PRINT(" Input file: " << argv[1]); + DEBUG_PRINT(" Output file: " << argv[2]); + DEBUG_PRINT(" Regex option: " << argv[3]); + + std::ifstream inputFile(argv[1]); + if (!inputFile) { + std::cerr << "Error: Could not open input file " << argv[1] << "\n"; + return 1; + } else { + DEBUG_PRINT("Debug: Successfully opened input file " << argv[1]); + } + + std::ofstream outputFile(argv[2]); + if (!outputFile) { + std::cerr << "Error: Could not open output file " << argv[2] << "\n"; + return 1; + } else { + DEBUG_PRINT("Debug: Successfully opened output file " << argv[2]); + } + + int regexOption = std::stoi(argv[3]); + if (regexOption != 0 && regexOption != 1) { + std::cerr << "Error: Invalid regex option. Must be 0 or 1.\n"; + return 1; + } else { + DEBUG_PRINT("Debug: Regex option is valid: " << regexOption); + } + + std::string line; + try { + std::regex evaluateRegex(R"(evaluate::[a-zA-Z0-9_]+)"); + std::regex emptyBraceRegex(R"(\{""\})"); + + while (std::getline(inputFile, line)) { + DEBUG_PRINT("Debug: Read line: " << line); + if (regexOption == 0) { + line = std::regex_replace(line, evaluateRegex, "NULL"); + DEBUG_PRINT("Debug: Applied evaluateRegex, resulting line: " << line); + } else if (regexOption == 1) { + line = std::regex_replace(line, emptyBraceRegex, "{\"\",0}"); + DEBUG_PRINT("Debug: Applied emptyBraceRegex, resulting line: " << line); + } + outputFile << line << "\n"; + DEBUG_PRINT("Debug: Wrote line to output file: " << line); + } + } catch (const std::regex_error& e) { + std::cerr << "Regex error: " << e.what() << "\n"; + return 1; + } + + inputFile.close(); + DEBUG_PRINT("Debug: Closed input file " << argv[1]); + outputFile.close(); + DEBUG_PRINT("Debug: Closed output file " << argv[2]); + + return 0; +} diff --git a/src/scan_citi.lpp b/src/scan_citi.lpp index 9e4f24bd..c712e88d 100644 --- a/src/scan_citi.lpp +++ b/src/scan_citi.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_csv.lpp b/src/scan_csv.lpp index cc6d8145..f40fcf20 100644 --- a/src/scan_csv.lpp +++ b/src/scan_csv.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_dataset.lpp b/src/scan_dataset.lpp index e2607a16..93a321a0 100644 --- a/src/scan_dataset.lpp +++ b/src/scan_dataset.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_mdl.lpp b/src/scan_mdl.lpp index 767d5c9c..6fed87d9 100644 --- a/src/scan_mdl.lpp +++ b/src/scan_mdl.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_netlist.lpp b/src/scan_netlist.lpp index 1c8c59c8..b59b57b5 100644 --- a/src/scan_netlist.lpp +++ b/src/scan_netlist.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_touchstone.lpp b/src/scan_touchstone.lpp index e3921372..6e4407bd 100644 --- a/src/scan_touchstone.lpp +++ b/src/scan_touchstone.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/scan_zvr.lpp b/src/scan_zvr.lpp index e26b68f1..316f32ee 100644 --- a/src/scan_zvr.lpp +++ b/src/scan_zvr.lpp @@ -39,7 +39,7 @@ #include #include -#ifdef __MINGW32__ +#ifdef _WIN32 #include #endif diff --git a/src/tvector.cpp b/src/tvector.cpp index a21a317e..34177f04 100644 --- a/src/tvector.cpp +++ b/src/tvector.cpp @@ -108,7 +108,7 @@ tvector operator + (tvector a, tvector b) { // Intrinsic vector addition. template tvector tvector::operator += (tvector a) { - assert (a.getSize () == (int)data.size ()); + assert (a.size () == (int)data.size ()); std::vector * src = a.getData (); std::vector * dst = data; for (int i = 0; i < (int)data.size (); i++) (*dst)[i] += (*src)[i];