Repository navigation
chore: fmtlib sprintf deprecated - #1536
Conversation
There was a problem hiding this comment.
Pull request overview
This PR modernizes formatting usage across the codebase by migrating away from deprecated fmt::sprintf/fmt::fprintf (and related wide-string printf paths) and updates the vendored {fmt} library to a newer release.
Changes:
- Replaced many
fmt::sprintf/fmt::fprintfcall sites withfmt::format/fmt::print, including wide-string formatting updates. - Added
SprintF.hpphelper to support legacy printf-style wide-format strings via UTF-8 conversion where needed (e.g., date/time formatting). - Updated the embedded {fmt} sources/headers and build files to reflect the new version (documented as “fmtlib 12.1”).
Reviewed changes
Copilot reviewed 127 out of 128 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| modules/webtools/src/cpp/WebREST.cpp | Adjust fmt headers for wide support. |
| modules/webtools/src/cpp/RepositoryHelpers.cpp | Replace fmt::sprintf with fmt::format. |
| modules/validators/src/cpp/ValidatorsInternal.cpp | Replace fmt::sprintf with fmt::format. |
| modules/time/src/cpp/DateString.cpp | Switch legacy date formatting to sprintf_w_utf8. |
| modules/time/src/cpp/Calendar.cpp | Replace fmt::sprintf formatting with fmt::format alignment. |
| modules/time/builtin/cpp/tocBuiltin.cpp | Replace formatting; refactor elapsed-time message formatting. |
| modules/tests_manager/src/cpp/ParseTags.cpp | Replace duplicated-tag message formatting. |
| modules/terminal/src/cpp/BasicTerminal.cpp | Replace fmt::fprintf with fmt::print; reorder fmt includes. |
| modules/string/src/cpp/StringJustify.cpp | Remove deprecated fmt printf include. |
| modules/string/src/cpp/MatrixToString.cpp | Move to fmt::format with runtime format strings. |
| modules/string/builtin/cpp/stringsBuiltin.cpp | Replace fmt::sprintf error formatting with fmt::format. |
| modules/string/builtin/cpp/startsWithBuiltin.cpp | Replace fmt::sprintf error formatting with fmt::format. |
| modules/string/builtin/cpp/endsWithBuiltin.cpp | Replace fmt::sprintf error formatting with fmt::format. |
| modules/string/builtin/cpp/countBuiltin.cpp | Replace fmt::sprintf error formatting with fmt::format. |
| modules/string/builtin/cpp/containsBuiltin.cpp | Replace fmt::sprintf error formatting with fmt::format. |
| modules/stream_manager/src/cpp/PrintfFunction.cpp | Switch printf-like formatting to sprintf_w_utf8 helper. |
| modules/spreadsheet/src/cpp/TableWriter.cpp | Remove deprecated fmt printf include. |
| modules/spreadsheet/src/cpp/DelimitedFileReader.cpp | Replace fmt::sprintf with fmt::format. |
| modules/python_engine/src/cpp/PythonObjectHandle_invoke.cpp | Remove deprecated fmt printf include. |
| modules/python_engine/src/cpp/PythonObjectHandle_cast.cpp | Remove deprecated fmt printf include. |
| modules/python_engine/src/cpp/PythonObjectHandle.cpp | Replace fmt::sprintf with fmt::format. |
| modules/python_engine/src/cpp/PyObjectHelpers.cpp | Replace fmt::sprintf with fmt::format. |
| modules/python_engine/src/cpp/PyKeyMatch.cpp | Remove deprecated fmt printf include. |
| modules/parallel/src/cpp/FutureObject.cpp | Replace fmt::sprintf with fmt::format alignment. |
| modules/parallel/src/cpp/DeleteGenericObject.cpp | Remove deprecated fmt printf include. |
| modules/modules_manager/src/cpp/GatewaysManager.cpp | Replace fmt::sprintf with fmt::format. |
| modules/memory_manager/builtin/cpp/persistentBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/memory_manager/builtin/cpp/globalBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/memory_manager/builtin/cpp/clearBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/logical/builtin/cpp/trueBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/logical/builtin/cpp/falseBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/linear_algebra/src/cpp/ReciprocalConditionNumber.cpp | Replace fmt::sprintf with fmt::format. |
| modules/julia_engine/src/cpp/JuliaObjectHandle.cpp | Remove deprecated fmt printf include. |
| modules/julia_engine/src/cpp/JuliaHelpers.cpp | Replace fmt::sprintf with fmt::format. |
| modules/json/src/cpp/JsonEncode.cpp | Replace formatting and refactor integer encoding (now uses swprintf). |
| modules/interpreter/src/grammar/NelsonParserHelpers.cpp | Replace fmt::sprintf with fmt::format. |
| modules/interpreter/src/cpp/operators/VertCatOperator.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/operators/RelationOperatorsHelpers.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/operators/PlusOperator.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/operators/MinusOperator.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/operators/HorzCatOperator.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/operators/ColonOperator.cpp | Replace operator error formatting with fmt::format. |
| modules/interpreter/src/cpp/PathFunctionIndexer.cpp | Remove deprecated fmt printf include. |
| modules/interpreter/src/cpp/NelsonReadyNamedMutex.cpp | Adjust fmt headers for wide support. |
| modules/interpreter/src/cpp/MacroFunctionDef.cpp | Replace multiple fmt::sprintf calls with fmt::format. |
| modules/interpreter/src/cpp/EvaluateBuiltinCatchRuntimeException.cpp | Replace signal error formatting with fmt::format. |
| modules/interpreter/src/cpp/Context.cpp | Remove deprecated fmt printf include. |
| modules/interpreter/src/cpp/AnonymousMacroFunctionDef.cpp | Replace fmt::sprintf with fmt::format. |
| modules/gui/src/cpp/GuiTerminal.cpp | Minor simplification (remove unnecessary copy) related to output path. |
| modules/graphics_io/src/cpp/ImageFormats.cpp | Remove deprecated fmt printf include. |
| modules/graphics/src/cpp/GraphicsObject.cpp | Replace property error formatting with fmt::format. |
| modules/graphics/src/cpp/GOWindow.cpp | Replace window-title formatting with fmt::format and updated macros. |
| modules/graphics/src/cpp/GOScalarDoubleProperty.cpp | Replace range error formatting with fmt::format. |
| modules/graphics/src/cpp/GOScalarAlphaProperty.cpp | Replace range error formatting with fmt::format. |
| modules/graphics/src/cpp/GOAxisHelpers.cpp | Replace numeric tick formatting with fmt::format. |
| modules/functions_manager/builtin/cpp/addpathBuiltin.cpp | Replace fmt::sprintf with fmt::format. |
| modules/files_folders_functions/src/cpp/CopyFile.cpp | Replace path error formatting with fmt::format. |
| modules/files_folders_functions/src/cpp/ChangeDirectory.cpp | Replace error formatting with fmt::format. |
| modules/error_manager/src/include/PredefinedErrorMessages.hpp | Convert printf-style placeholders to {}-style placeholders. |
| modules/error_manager/src/cpp/Exception.cpp | Replace trace formatting with fmt::format. |
| modules/engine/src/cpp/RunStartupScripts.cpp | Replace script failure message formatting with fmt::format. |
| modules/engine/src/cpp/RunFinishScripts.cpp | Replace script failure message formatting with fmt::format. |
| modules/elementary_functions/src/cpp/ComplexConstructor.cpp | Replace undefined-function message formatting with fmt::format. |
| modules/dynamic_link/src/cpp/DynamicLinkSymbolObject.cpp | Replace type error formatting with fmt::format. |
| modules/dynamic_link/src/cpp/CreateDynamicLinkSymbolObject.cpp | Replace symbol/type error formatting with fmt::format. |
| modules/display_format/src/include/ArrayOfFormatInfo.hpp | Update default numeric format strings. |
| modules/display_format/src/cpp/Hexify.cpp | Replace hex formatting with fmt::format. |
| modules/display_format/src/cpp/FormatRational.cpp | Replace width padding formatting with fmt::format. |
| modules/display_format/src/cpp/FormatPlus.cpp | Remove fmt includes (now relies on other formatting paths). |
| modules/display_format/src/cpp/FormatHex.cpp | Remove fmt includes (now relies on other formatting paths). |
| modules/display_format/src/cpp/FormatEngineeringNotation.cpp | Refactor engineering-notation formatting (helpers + fmt::format). |
| modules/display_format/src/cpp/FormatBank.cpp | Refactor bank-format padding using fmt::format. |
| modules/display_format/src/cpp/DisplayVariableHelpers.cpp | Replace multiple fmt::sprintf call sites with fmt::format. |
| modules/display_format/src/cpp/DisplayStruct.cpp | Remove fmt includes (now relies on other formatting paths). |
| modules/display_format/src/cpp/DisplayString.cpp | Replace index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplaySparseDoubleComplex.cpp | Replace sparse index/header formatting with fmt::format. |
| modules/display_format/src/cpp/DisplaySparseDouble.cpp | Replace sparse index/header formatting with fmt::format. |
| modules/display_format/src/cpp/DisplaySingleComplex.cpp | Replace ND header index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplaySingle.cpp | Replace ND header index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplayMissing.cpp | Replace ND header index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplayLogical.cpp | Replace ND header + sparse header formatting with fmt::format. |
| modules/display_format/src/cpp/DisplayIntegerHelpers.cpp | Remove deprecated fmt printf include. |
| modules/display_format/src/cpp/DisplayInteger.cpp | Replace ND header index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplayDoubleComplex.cpp | Replace formatting, plus performance tweaks (buffer reserve, cached config). |
| modules/display_format/src/cpp/DisplayDouble.cpp | Replace formatting, plus performance tweaks (buffer reserve, cached config). |
| modules/display_format/src/cpp/DisplayClass.cpp | Remove fmt includes (now relies on other formatting paths). |
| modules/display_format/src/cpp/DisplayChar.cpp | Replace ND header index formatting with fmt::format. |
| modules/display_format/src/cpp/DisplayCell.cpp | Replace ND header index formatting with fmt::format. |
| modules/dictionary/src/cpp/KeyHash.cpp | Replace unhashable-type message formatting with fmt::format. |
| modules/debugger/builtin/cpp/dbstatusBuitin.cpp | Replace breakpoint status formatting with fmt::format. |
| modules/data_structures/builtin/cpp/rmfieldBuiltin.cpp | Replace missing-field message formatting with fmt::format. |
| modules/data_structures/builtin/cpp/cellfunBuiltin.cpp | Replace error formatting with fmt::format. |
| modules/data_structures/builtin/cpp/cellBuiltin.cpp | Replace error formatting with fmt::format. |
| modules/data_structures/builtin/cpp/arrayfunBuiltin.cpp | Adjust fmt headers for wide support. |
| modules/data_analysis/builtin/cpp/cumulativeFunctionBuiltinHelpers.cpp | Replace error formatting with fmt::format. |
| modules/core/src/cpp/NargOut.cpp | Replace error formatting with fmt::format. |
| modules/core/src/cpp/NargIn.cpp | Replace error formatting with fmt::format. |
| modules/constructors_functions/builtin/cpp/eyeBuiltin.cpp | Replace error formatting with fmt::format. |
| modules/commons/src/include/fast_float/float_common.h | Whitespace/formatting adjustment. |
| modules/commons/src/include/SprintF.hpp | Add UTF-8 bridge helper for printf-style wide formats. |
| modules/commons/src/fmt/src/os.cc | Vendored fmt update changes. |
| modules/commons/src/fmt/src/format.cc | Vendored fmt update changes. |
| modules/commons/src/fmt/include/fmt/xchar.h | Vendored fmt update changes (wide formatting APIs). |
| modules/commons/src/fmt/include/fmt/std.h | Vendored fmt update changes (std formatters). |
| modules/commons/src/fmt/include/fmt/ranges.h | Vendored fmt update changes (ranges/join). |
| modules/commons/src/fmt/include/fmt/printf.h | Vendored fmt update changes (printf API deprecations). |
| modules/commons/src/fmt/include/fmt/ostream.h | Vendored fmt update changes. |
| modules/commons/src/fmt/include/fmt/os.h | Vendored fmt update changes. |
| modules/commons/src/fmt/include/fmt/format-inl.h | Vendored fmt update changes. |
| modules/commons/src/fmt/include/fmt/compile.h | Vendored fmt update changes (compile-time formatting). |
| modules/commons/src/fmt/include/fmt/color.h | Vendored fmt update changes (text_style packing). |
| modules/commons/src/fmt/include/fmt/args.h | Vendored fmt update changes (export store). |
| modules/commons/src/fmt/ChangeLog.md | Add fmt 12.x changelog entries. |
| modules/commons/src/cpp/FileSystemWrapper.cpp | Replace sprintf-based temp-name formatting with fmt format. |
| modules/commons/src/c/nlsCommons.vcxproj.filters | Add new header to VS filters. |
| modules/commons/src/c/nlsCommons.vcxproj | Add new header to VS project. |
| modules/audio/builtin/cpp/audiowriteBuiltin.cpp | Replace manual swprintf error message formatting with fmt::format. |
| modules/audio/builtin/c/nlsAudio_builtin.vcxproj | Add fmt include directory for MSVC build. |
| modules/audio/CMakeLists.txt | Add fmt include directory for CMake build. |
| modules/assert_functions/src/cpp/Assert_IsEqual.cpp | Replace assertion message formatting with fmt::format. |
| locale/nelson-fr_FR.json | Remove unused translation key for old printf index format. |
| locale/nelson-en_US.json | Remove unused translation key for old printf index format. |
| CHANGELOG.md | Note fmtlib 12.1 update. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #define _CRT_SECURE_NO_WARNINGS | ||
| #define FMT_HEADER_ONLY | ||
| #include <fmt/printf.h> | ||
| #include <fmt/format.h> | ||
| #include <fmt/xchar.h> | ||
| #include <iomanip> | ||
| #include <sstream> | ||
| #include <cstring> | ||
| #include <cwchar> | ||
| #include "StringHelpers.hpp" |
There was a problem hiding this comment.
JsonEncode.cpp now uses std::vector in jsonEncodeInteger, but the file doesn't include . This will fail to compile on toolchains where isn't transitively included; add the missing header (or remove the std::vector usage).
| for (ompIndexType i = 0; i < elementCount; i++) { | ||
| json_append_string(jsonString, fmt::sprintf(format, ptr[i])); | ||
| std::vector<wchar_t> buffer(20); | ||
| int len = std::swprintf(buffer.data(), buffer.size(), format.c_str(), ptr[i]); | ||
| jsonString.append(buffer.data(), len); | ||
| } |
There was a problem hiding this comment.
jsonEncodeInteger uses std::swprintf into a fixed 20-wchar buffer and appends using the returned length without checking for truncation or failure. For large 64-bit values plus the trailing comma in the format (e.g. "%lli,"), 20 is too small; swprintf can return -1 or a value >= buffer size, causing incorrect output or undefined behavior when passed to append. Use a sufficiently sized buffer (or fmt::format / fmt::format_to) and handle swprintf return values safely.
| std::string tmp = fmt::format("Duplicated tag detected: {}", tag); | ||
| msg = std::wstring(tmp.begin(), tmp.end()); | ||
| istream.close(); |
There was a problem hiding this comment.
This converts a UTF-8 std::string to std::wstring via a byte-wise constructor, which will corrupt any non-ASCII tag names. Since tags are std::string/UTF-8 elsewhere (previous code used utf8_to_wstring(tag)), convert with utf8_to_wstring(tmp) (or format directly into a std::wstring using fmt's wide APIs) instead.
| std::string narrow_fmt = "Elapsed time is {0:.6f} seconds."; | ||
| std::string tmp_str = fmt::format(narrow_fmt, r); | ||
| std::wstring msg(tmp_str.begin(), tmp_str.end()); | ||
| eval->getInterface()->outputMessage(msg + L"\n"); |
There was a problem hiding this comment.
The second branch formats into a narrow std::string and then constructs a std::wstring via byte widening. This bypasses the existing wide/i18n path and will break if the message ever contains non-ASCII (and it’s inconsistent with the first branch). Format into a std::wstring directly (e.g., fmt::format with _W(...)) or convert via utf8_to_wstring.
| //============================================================================= | ||
| // Copyright (c) 2016-present Allan CORNET (Nelson) | ||
| //============================================================================= | ||
| // This file is part of Nelson. | ||
| //============================================================================= | ||
| // LICENCE_BLOCK_BEGIN | ||
| // SPDX-License-Identifier: LGPL-3.0-or-later | ||
| // LICENCE_BLOCK_END | ||
| //============================================================================= | ||
| #pragma once | ||
| //============================================================================= | ||
| #define FMT_HEADER_ONLY | ||
| #include <fmt/printf.h> | ||
| #include <fmt/format.h> | ||
| //============================================================================= |
There was a problem hiding this comment.
SprintF.hpp is a public header but defines FMT_HEADER_ONLY before including fmt headers. Defining library-configuration macros in a header can create inconsistent compilation across translation units and increases compile times; prefer setting this macro globally in the build or in a single TU. Also, the file appears to start with a UTF-8 BOM, which can cause issues with some compilers/tooling—consider removing it.
5154c53 to
632901d
Compare
No description provided.