From a70362ef63839f03ab445213d2cdc8a46aa4a1b6 Mon Sep 17 00:00:00 2001 From: Stephen Dennis Date: Sun, 26 Jul 2026 21:20:02 -0600 Subject: [PATCH] build: remove the 11 UTF-8 BOMs, and stop editors re-adding them (#1499) Every BOM in the tree, and an .editorconfig so Visual Studio does not put them back. All eleven carry no information: none of the files contains a single non-ASCII byte, so the BOM was the only non-ASCII content in each. Visual Studio wrote them when it generated or last touched those project files. Ten are .vcxproj.filters; two are the sqlproxy and sqlslave .vcxproj, which is why the /utf-8 commit had to restore them mid-change. The concern that makes this worth more than tidying: Visual Studio adds a signature when it needs to represent a non-ASCII character in a file that had none. These files are pure ASCII, so removing the BOM should stick -- VS preserves the encoding it finds. But #1499 step 2 converts source prose from \xE2\x80\x99 escapes to characters, which is precisely the condition that starts making VS write signatures, and on .cpp rather than on project files. .editorconfig is the lever for that. charset = utf-8 means UTF-8 WITHOUT a BOM (utf-8-bom is the spelling for with), and Visual Studio honours it, as do VS Code, CLion and Sublime. It is deliberately the only key set: indentation, line endings and trailing whitespace are left to existing practice and CLAUDE.md, so the file cannot reformat anything by surprise. Git cannot do this job, which is worth recording because it is the obvious place to look. core.autocrlf is line endings only, and .gitattributes' working-tree-encoding converts encodings rather than stripping a signature -- pointing it at UTF-16 would ADD one. Stripping a BOM through git needs a custom clean filter that every clone has to configure locally; an .editorconfig needs no setup and acts where the BOM is actually introduced. A BOM is harmless to MSVC and tolerated by gcc and clang, so this is not a correctness fix for compiled sources. It matters for files that are executed rather than compiled -- a shell script or a .mux corpus file with a BOM simply does not work -- and for keeping diffs free of churn that depends on who last opened a file in an IDE. Verified: full rebuild of all eleven projects clean, including the two whose .vcxproj lost its BOM; smoke 316 dispatched, 1487 succeeded, 17 failed (the known build-configuration failures here); format, netaddr and alarm harnesses pass; zero BOMs left in any tracked file. Co-Authored-By: Claude Opus 5 --- .editorconfig | 35 +++++++++++++++++++ mux/libmux.vcxproj.filters | 2 +- mux/lua54/lua54.vcxproj.filters | 2 +- mux/modules/comsys/comsys.vcxproj.filters | 2 +- mux/modules/engine/engine.vcxproj.filters | 2 +- mux/modules/exp3/exp3.vcxproj.filters | 2 +- mux/modules/mail/mail.vcxproj.filters | 2 +- mux/modules/sqlproxy/sqlproxy.vcxproj | 2 +- mux/modules/sqlproxy/sqlproxy.vcxproj.filters | 2 +- mux/modules/sqlslave/sqlslave.vcxproj | 2 +- mux/modules/sqlslave/sqlslave.vcxproj.filters | 2 +- mux/netmux.vcxproj.filters | 2 +- 12 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..eb9f5e706 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,35 @@ +# EditorConfig — https://editorconfig.org +# +# Deliberately minimal. This file exists for ONE reason: to stop editors +# writing a UTF-8 BOM. +# +# Visual Studio saves a file as "UTF-8 with signature" when it needs to +# represent a non-ASCII character and the file had none before. That is +# harmless for MSVC, which accepts a BOM, but it is invisible churn in +# diffs, it varies by who last opened the file, and a BOM is fatal to any +# file that is executed rather than compiled -- a shell script or a .mux +# corpus file with a BOM does not work. +# +# The risk is about to grow: #1499 adds /utf-8 so source prose can be +# written as characters instead of \xE2\x80\x99 escapes, which is exactly +# the condition that makes Visual Studio start adding signatures. +# +# `charset = utf-8` means UTF-8 WITHOUT a BOM; `utf-8-bom` is the spelling +# for with. Visual Studio honours this, as do VS Code, CLion, Sublime and +# most others. +# +# Note for anyone reaching for git instead: git cannot do this. +# core.autocrlf is line endings only, and .gitattributes' +# working-tree-encoding converts encodings rather than stripping a +# signature -- setting it to UTF-16 would ADD one. Stripping a BOM in git +# needs a custom clean filter, which every clone has to configure locally. +# An .editorconfig needs no setup and fixes it at the point it happens. +# +# Nothing else is set here on purpose. Indentation, line endings and +# trailing whitespace are left to existing practice and to the code-style +# rules in CLAUDE.md, so this file cannot reformat anything by surprise. + +root = true + +[*] +charset = utf-8 diff --git a/mux/libmux.vcxproj.filters b/mux/libmux.vcxproj.filters index 6b3dfd49f..a8769a08a 100644 --- a/mux/libmux.vcxproj.filters +++ b/mux/libmux.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/lua54/lua54.vcxproj.filters b/mux/lua54/lua54.vcxproj.filters index bd051dcf8..7204f7adc 100644 --- a/mux/lua54/lua54.vcxproj.filters +++ b/mux/lua54/lua54.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/comsys/comsys.vcxproj.filters b/mux/modules/comsys/comsys.vcxproj.filters index 4f7c956a8..c602bc035 100644 --- a/mux/modules/comsys/comsys.vcxproj.filters +++ b/mux/modules/comsys/comsys.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/engine/engine.vcxproj.filters b/mux/modules/engine/engine.vcxproj.filters index e7fa62da7..7ce8695af 100644 --- a/mux/modules/engine/engine.vcxproj.filters +++ b/mux/modules/engine/engine.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/exp3/exp3.vcxproj.filters b/mux/modules/exp3/exp3.vcxproj.filters index f8dadacc4..123afea43 100644 --- a/mux/modules/exp3/exp3.vcxproj.filters +++ b/mux/modules/exp3/exp3.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/mail/mail.vcxproj.filters b/mux/modules/mail/mail.vcxproj.filters index ce659103a..da797e0ba 100644 --- a/mux/modules/mail/mail.vcxproj.filters +++ b/mux/modules/mail/mail.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/sqlproxy/sqlproxy.vcxproj b/mux/modules/sqlproxy/sqlproxy.vcxproj index b0958a056..b4ba853d7 100644 --- a/mux/modules/sqlproxy/sqlproxy.vcxproj +++ b/mux/modules/sqlproxy/sqlproxy.vcxproj @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/sqlproxy/sqlproxy.vcxproj.filters b/mux/modules/sqlproxy/sqlproxy.vcxproj.filters index b6fc28043..63126f008 100644 --- a/mux/modules/sqlproxy/sqlproxy.vcxproj.filters +++ b/mux/modules/sqlproxy/sqlproxy.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/sqlslave/sqlslave.vcxproj b/mux/modules/sqlslave/sqlslave.vcxproj index 39b46df63..3a9578ed1 100644 --- a/mux/modules/sqlslave/sqlslave.vcxproj +++ b/mux/modules/sqlslave/sqlslave.vcxproj @@ -1,4 +1,4 @@ - + diff --git a/mux/modules/sqlslave/sqlslave.vcxproj.filters b/mux/modules/sqlslave/sqlslave.vcxproj.filters index 71ba64796..fd4b7deda 100644 --- a/mux/modules/sqlslave/sqlslave.vcxproj.filters +++ b/mux/modules/sqlslave/sqlslave.vcxproj.filters @@ -1,4 +1,4 @@ - + diff --git a/mux/netmux.vcxproj.filters b/mux/netmux.vcxproj.filters index a123900ef..a7951cd91 100644 --- a/mux/netmux.vcxproj.filters +++ b/mux/netmux.vcxproj.filters @@ -1,4 +1,4 @@ - +