Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package clpeak for openSUSE:Factory checked 
in at 2026-08-21 16:56:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/clpeak (Old)
 and      /work/SRC/openSUSE:Factory/.clpeak.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "clpeak"

Fri Aug 21 16:56:20 2026 rev:18 rq:1372634 version:2.1.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/clpeak/clpeak.changes    2026-08-19 
18:01:13.860261392 +0200
+++ /work/SRC/openSUSE:Factory/.clpeak.new.1258/clpeak.changes  2026-08-21 
16:57:48.151502138 +0200
@@ -1,0 +2,9 @@
+Thu Aug 20 18:40:38 UTC 2026 - Martin Pluskal <[email protected]>
+
+- Update to 2.1.2:
+  * Keep machine-readable output locale-independent so XML
+    dumps, JSON/CSV exports and parsed values always use '.'
+    as the decimal separator, including under comma-decimal
+    locales (gh#krrishnarraj/clpeak#199).
+
+-------------------------------------------------------------------

Old:
----
  clpeak-2.1.1.tar.gz

New:
----
  clpeak-2.1.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ clpeak.spec ++++++
--- /var/tmp/diff_new_pack.g4YqbB/_old  2026-08-21 16:57:48.930529772 +0200
+++ /var/tmp/diff_new_pack.g4YqbB/_new  2026-08-21 16:57:48.932529843 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           clpeak
-Version:        2.1.1
+Version:        2.1.2
 Release:        0
 Summary:        Find peak OpenCL capacities like bandwidth & compute
 # Legal-Review-Notice: upstream relicensed from the Unlicense to Apache-2.0
@@ -46,7 +46,7 @@
 %prep
 %autosetup -p1
 # GitHub archives have no .git, so git-describe is unavailable and
-# version.cmake's hardcoded fallback is stale (still 2.0.16 in 2.1.1).
+# version.cmake's hardcoded fallback is stale (still 2.0.16 in 2.1.2).
 # gh#krrishnarraj/clpeak#198
 sed -i 's/set(CLPEAK_VERSION_FALLBACK ".*")/set(CLPEAK_VERSION_FALLBACK 
"%{version}")/' \
     src/common/cmake/version.cmake

++++++ clpeak-2.1.1.tar.gz -> clpeak-2.1.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/.github/workflows/build.yml 
new/clpeak-2.1.2/.github/workflows/build.yml
--- old/clpeak-2.1.1/.github/workflows/build.yml        2026-08-18 
19:08:27.000000000 +0200
+++ new/clpeak-2.1.2/.github/workflows/build.yml        2026-08-20 
17:30:08.000000000 +0200
@@ -33,7 +33,6 @@
           - name: Linux x64
             runner: ubuntu-latest
             artifact: clpeak-linux-x86_64
-            gui: true
             binary: build/clpeak
             suffix: ""
             cuda: false
@@ -41,7 +40,6 @@
           - name: Linux arm64
             runner: ubuntu-24.04-arm
             artifact: clpeak-linux-arm64
-            gui: false
             binary: build/clpeak
             suffix: ""
             cuda: false
@@ -49,7 +47,6 @@
           - name: Windows x64
             runner: windows-latest
             artifact: clpeak-windows-x86_64
-            gui: true
             binary: build/Release/clpeak.exe
             suffix: ""
             cuda: false
@@ -57,7 +54,6 @@
           - name: Windows arm64
             runner: windows-11-arm
             artifact: clpeak-windows-arm64
-            gui: false
             binary: build/Release/clpeak.exe
             suffix: ""
             cuda: false
@@ -65,7 +61,6 @@
           - name: macOS arm64
             runner: macos-latest
             artifact: clpeak-macos-arm64
-            gui: true
             binary: build/clpeak
             suffix: ""
             cuda: false
@@ -73,7 +68,6 @@
           - name: Linux x64 CUDA
             runner: ubuntu-latest
             artifact: clpeak-linux-x86_64-cuda
-            gui: true
             binary: build/clpeak
             suffix: cuda
             cuda: true
@@ -81,7 +75,6 @@
           - name: Linux arm64 CUDA
             runner: ubuntu-24.04-arm
             artifact: clpeak-linux-arm64-cuda
-            gui: false
             binary: build/clpeak
             suffix: cuda
             cuda: true
@@ -89,7 +82,6 @@
           - name: Windows x64 CUDA
             runner: windows-latest
             artifact: clpeak-windows-x86_64-cuda
-            gui: true
             binary: build/Release/clpeak.exe
             suffix: cuda
             cuda: true
@@ -97,7 +89,6 @@
           - name: Linux x64 ROCm
             runner: ubuntu-24.04
             artifact: clpeak-linux-x86_64-rocm
-            gui: true
             binary: build/clpeak
             suffix: rocm
             cuda: false
@@ -106,7 +97,6 @@
           - name: Linux x64 oneAPI
             runner: ubuntu-latest
             artifact: clpeak-linux-x86_64-oneapi
-            gui: true
             binary: build/clpeak
             suffix: oneapi
             cuda: false
@@ -129,18 +119,18 @@
           # (GCC<=14 serialises the FMA accumulator chains, ~halving 
fp32/fp64).
           sudo apt-get install -y --no-install-recommends build-essential clang
 
-      # `flutter build linux` toolchain, GUI jobs only.
+      # `flutter build linux` toolchain.
       - name: Install GUI dependencies (Linux)
-        if: runner.os == 'Linux' && matrix.gui
+        if: runner.os == 'Linux'
         run: |
           sudo apt-get install -y --no-install-recommends \
             ninja-build pkg-config libgtk-3-dev liblzma-dev
 
       - name: Set up Flutter
-        if: matrix.gui
         uses: subosito/flutter-action@v2
         with:
-          channel: stable
+          channel: master
+          flutter-version: 3.47.1
           cache: true
 
       - name: Install Vulkan SDK
@@ -247,7 +237,7 @@
       # is ad-hoc signed, so first launch still needs right-click -> Open until
       # a Developer ID identity is wired in here.
       - name: Package DMG (macOS)
-        if: runner.os == 'macOS' && matrix.gui
+        if: runner.os == 'macOS'
         run: cmake --build build --target clpeak-gui-dmg
 
       - name: Upload artifact
@@ -262,7 +252,7 @@
       # each download unpacks straight to the thing you wanted.  (Release
       # assets are unaffected -- the release job attaches the raw files.)
       - name: Upload DMG artifact
-        if: runner.os == 'macOS' && matrix.gui
+        if: runner.os == 'macOS'
         uses: actions/upload-artifact@v4
         with:
           name: ${{ matrix.artifact }}-dmg
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/AGENTS.md new/clpeak-2.1.2/AGENTS.md
--- old/clpeak-2.1.1/AGENTS.md  2026-08-18 19:08:27.000000000 +0200
+++ new/clpeak-2.1.2/AGENTS.md  2026-08-20 17:30:08.000000000 +0200
@@ -60,9 +60,7 @@
 - Each backend: `-DCLPEAK_ENABLE_VULKAN=OFF`, etc.
 - GUI: built automatically as `clpeak-gui` when the Flutter SDK is detected
   (disable with `-DCLPEAK_ENABLE_GUI=OFF`); bundle lands in 
`build/clpeak-gui/`.
-  Flutter's desktop SDK is x64-only on Linux/Windows, so those arm64 CI jobs
-  build CLI-only (`gui: false` in the workflow matrix). Mobile builds: see
-  `app/AGENTS.md`.
+  Mobile builds: see `app/AGENTS.md`.
 - All backend static libs are built PIC (`CMAKE_POSITION_INDEPENDENT_CODE`):
   they link into both `clpeak` and the `clpeak_ffi` shared library.
 - Packaging: `cpack -G ZIP` ships CLI + GUI in one archive — `bin/clpeak`,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/app/pubspec.yaml 
new/clpeak-2.1.2/app/pubspec.yaml
--- old/clpeak-2.1.1/app/pubspec.yaml   2026-08-18 19:08:27.000000000 +0200
+++ new/clpeak-2.1.2/app/pubspec.yaml   2026-08-20 17:30:08.000000000 +0200
@@ -3,7 +3,7 @@
 publish_to: 'none'
 
 # versionName / versionCode
-version: 2.1.0+32
+version: 2.1.2+33
 
 environment:
   sdk: ^3.12.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/src/common/inventory.cpp 
new/clpeak-2.1.2/src/common/inventory.cpp
--- old/clpeak-2.1.1/src/common/inventory.cpp   2026-08-18 19:08:27.000000000 
+0200
+++ new/clpeak-2.1.2/src/common/inventory.cpp   2026-08-20 17:30:08.000000000 
+0200
@@ -1,5 +1,6 @@
 #include <common/inventory.h>
 #include <common/common.h>
+#include <locale>
 #include <ostream>
 #include <sstream>
 #include <string>
@@ -36,6 +37,10 @@
 std::string inventoryToJson(const std::vector<BackendInventory> &inv)
 {
   std::ostringstream os;
+  // Machine-readable interchange: JSON is locale-free, and the GUI decodes
+  // this with the host toolkit's locale already installed (see fmtFloat in
+  // src/ffi/logger_ffi.cpp).
+  os.imbue(std::locale::classic());
   os << "{\"backends\":[";
   for (size_t i = 0; i < inv.size(); ++i)
   {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/src/common/result_store.cpp 
new/clpeak-2.1.2/src/common/result_store.cpp
--- old/clpeak-2.1.1/src/common/result_store.cpp        2026-08-18 
19:08:27.000000000 +0200
+++ new/clpeak-2.1.2/src/common/result_store.cpp        2026-08-20 
17:30:08.000000000 +0200
@@ -5,6 +5,7 @@
 #include <sstream>
 #include <iomanip>
 #include <iostream>
+#include <locale>
 #include <cstring>
 
 // ---- Enum <-> string ------------------------------------------------------
@@ -109,13 +110,37 @@
     return out;
 }
 
+// Every number in every dump format goes through here, and every number read
+// back comes through parseFloatC below.  Both pin the classic locale on
+// purpose: the GUI hosts these writers inside a toolkit that sets the process
+// locale (GTK's gtk_init calls setlocale(LC_ALL, "")), and a comma decimal
+// separator would produce files that are neither valid JSON nor readable by
+// the loaders.  The dump formats are machine-readable interchange, not
+// user-facing text -- they are always '.' regardless of where clpeak runs.
 static std::string fmtValue(float v)
 {
     std::stringstream ss;
+    ss.imbue(std::locale::classic());
     ss << std::fixed << std::setprecision(4) << v;
     return ss.str();
 }
 
+// Read a float written by fmtValue.  Leading whitespace is skipped and
+// trailing text ignored, so the caller can hand over the rest of a JSON line
+// or an XML element body.  Returns false (leaving `out` untouched) when the
+// text does not start with a number -- std::stof's `consumed == 0` case, but
+// without stof's dependence on the C locale's LC_NUMERIC.
+static bool parseFloatC(const std::string &s, float &out)
+{
+    std::istringstream is(s);
+    is.imbue(std::locale::classic());
+    float v = 0.0f;
+    if (!(is >> v))
+        return false;
+    out = v;
+    return true;
+}
+
 // ---- JSON save ------------------------------------------------------------
 // Self-describing wrapper:
 //   {"format_version":2,"clpeak_version":"...","os":"...","entries":[ … ]}
@@ -124,6 +149,7 @@
 static void writeJson(const ResultStore &store, std::ostream &f,
                       const DeviceInfoStore &devices)
 {
+    f.imbue(std::locale::classic());
     f << "{\"format_version\":" << RESULT_FORMAT_VERSION
       << ",\"clpeak_version\":\"" << jsonEscape(CLPEAK_VERSION_STR) << "\""
       << ",\"os\":\"" << jsonEscape(OS_NAME) << "\"";
@@ -234,6 +260,7 @@
         std::cerr << "clpeak: cannot open CSV output file: " << filename << 
"\n";
         return false;
     }
+    f.imbue(std::locale::classic());
     f << 
"format_version,backend,platform,device,driver,category,test,metric,unit,status,value,reason,display,description,metric_description\n";
     for (const ResultEntry &e : store)
     {
@@ -337,6 +364,8 @@
         return false;
     }
 
+    f.imbue(std::locale::classic());
+
     // Rows are streamed in run order; props are looked up per run.
     std::map<std::string, const DeviceInfo *> deviceByKey;
     for (const DeviceInfo &d : devices)
@@ -477,13 +506,8 @@
     pos += needle.size();
     while (pos < line.size() && line[pos] == ' ') pos++;
     if (pos >= line.size() || line[pos] == '"') return 0.0f;
-    try
-    {
-        size_t consumed = 0;
-        float v = std::stof(line.substr(pos), &consumed);
-        return (consumed > 0) ? v : 0.0f;
-    }
-    catch (...) { return 0.0f; }
+    float v = 0.0f;
+    return parseFloatC(line.substr(pos), v) ? v : 0.0f;
 }
 
 static int jsonExtractInt(const std::string &line, const std::string &key)
@@ -726,13 +750,8 @@
         e.status   = statusFromString(fields[9]);
         if (e.status == ResultStatus::Ok)
         {
-            try
-            {
-                size_t consumed = 0;
-                e.value = std::stof(fields[10], &consumed);
-                if (consumed == 0) continue;
-            }
-            catch (...) { continue; }
+            if (!parseFloatC(fields[10], e.value))
+                continue;
         }
         e.reason = fields[11];
         if (fields.size() >= 13)
@@ -908,8 +927,8 @@
                     continue;
                 std::string content = xmlUnescape(
                     t.substr(openEnd + 1, closePos - openEnd - 1));
-                try { e.value = std::stof(content); }
-                catch (...) { continue; }
+                if (!parseFloatC(content, e.value))
+                    continue;
             }
 
             if (!e.backend.empty() && !e.test.empty() && !e.metric.empty())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/src/cpu/cpu_peak.cpp 
new/clpeak-2.1.2/src/cpu/cpu_peak.cpp
--- old/clpeak-2.1.1/src/cpu/cpu_peak.cpp       2026-08-18 19:08:27.000000000 
+0200
+++ new/clpeak-2.1.2/src/cpu/cpu_peak.cpp       2026-08-20 17:30:08.000000000 
+0200
@@ -6,8 +6,10 @@
 
 #include <algorithm>
 #include <chrono>
-#include <cstdio>
+#include <iomanip>
+#include <locale>
 #include <ostream>
+#include <sstream>
 #include <string>
 
 CpuPeak::CpuPeak() {}
@@ -26,14 +28,19 @@
   targetTimeUs = opts.targetTimeUsCpu;
 }
 
-// Human-readable byte size for the device property block.
+// Human-readable byte size for the device property block.  Streams pinned to
+// the classic locale, not printf: this string is persisted in the dump files
+// and the GUI runs with the host toolkit's locale set, which would otherwise
+// write "8,0 GB" there but "8.0 GB" from the CLI on the same machine.
 static std::string fmtBytes(uint64_t b)
 {
-  char buf[64];
-  if (b >= (1ull << 30))      std::snprintf(buf, sizeof(buf), "%.1f GB", b / 
(double)(1ull << 30));
-  else if (b >= (1ull << 20)) std::snprintf(buf, sizeof(buf), "%.0f MB", b / 
(double)(1ull << 20));
-  else                        std::snprintf(buf, sizeof(buf), "%.0f KB", b / 
(double)(1ull << 10));
-  return buf;
+  std::ostringstream ss;
+  ss.imbue(std::locale::classic());
+  ss << std::fixed;
+  if (b >= (1ull << 30))      ss << std::setprecision(1) << b / (double)(1ull 
<< 30) << " GB";
+  else if (b >= (1ull << 20)) ss << std::setprecision(0) << b / (double)(1ull 
<< 20) << " MB";
+  else                        ss << std::setprecision(0) << b / (double)(1ull 
<< 10) << " KB";
+  return ss.str();
 }
 
 double CpuPeak::runWorkload(int nThreads, const Workload &body,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clpeak-2.1.1/src/ffi/logger_ffi.cpp 
new/clpeak-2.1.2/src/ffi/logger_ffi.cpp
--- old/clpeak-2.1.1/src/ffi/logger_ffi.cpp     2026-08-18 19:08:27.000000000 
+0200
+++ new/clpeak-2.1.2/src/ffi/logger_ffi.cpp     2026-08-20 17:30:08.000000000 
+0200
@@ -3,9 +3,10 @@
 #include <common/common.h>
 #include <common/result_store.h>
 
-#include <cstdio>
 #include <cstdlib>
 #include <cstring>
+#include <iomanip>
+#include <locale>
 #include <sstream>
 
 namespace
@@ -33,11 +34,19 @@
     ss << ",\"" << key << "\":\"" << jsonEscape(value) << "\"";
 }
 
+// JSON numbers are '.'-separated by definition, so this must not follow the
+// process locale.  It matters here more than anywhere else in clpeak: the GUI
+// hosts this library inside a toolkit that sets the locale for us (GTK's
+// gtk_init calls setlocale(LC_ALL, "")), so on a comma-decimal desktop a
+// printf("%.4f") emitted `"value":1234,5678` -- malformed JSON that the Dart
+// side dropped, leaving the live results view empty while the XML dump (which
+// never went through the C locale) stayed correct.
 std::string fmtFloat(float v)
 {
-    char buf[32];
-    std::snprintf(buf, sizeof(buf), "%.4f", v);
-    return buf;
+    std::ostringstream ss;
+    ss.imbue(std::locale::classic());
+    ss << std::fixed << std::setprecision(4) << v;
+    return ss.str();
 }
 
 } // namespace
@@ -45,6 +54,7 @@
 std::string ffiEventToJson(const LogEvent &e)
 {
     std::ostringstream ss;
+    ss.imbue(std::locale::classic());  // see fmtFloat -- the indices too
     ss << "{\"t\":\"" << kindTag(e.kind) << "\"";
 
     // Scope context — present on every scoped event.

Reply via email to