I have a desktop app where I am reading and writing configuration from a toml file.
I have a preferences dialog where a user can toggle the options of the configuration. One of the options stores a directory. Once a user clicks 'OK', I save the options they selected and persist them to the toml file. The particular issue affects how the toml11 library serializes strings that are file/directory paths.
I have created a MRE that reproduces the issue
#include <iostream>
#include <toml.hpp>
#include <string>
#include <Windows.h>
#include <locale>
#include <codecvt>
int main()
{
TCHAR path[MAX_PATH];
GetModuleFileName(NULL, path, ARRAYSIZE(path));
std::wstring exePath(path);
std::wcout << exePath << " \n";
using convert_type = std::codecvt_utf8<TCHAR>;
std::wstring_convert<convert_type, TCHAR> converter;
std::string sExePath = converter.to_bytes(exePath);
auto parsedData = toml::parse("sample.toml");
auto& parsedExePath = toml::find<std::string>(parsedData, "exePath");
std::cout << parsedExePath << " \n";
const toml::value data{ { {"exePath", sExePath} } };
const std::string configString = toml::format(data);
std::cout << configString << " \n";
return 0;
}
The output of this is:
C:\Users\segmentation_fault\source\repos\Toml11FilePathsMre\x64\Debug\Toml11FilePathsMre.exe
C:\Development\cpp
exePath = """
C:\\Users\\segmentation_fault\\source\\repos\\Toml11FilePathsMre\\x64\\Deb\
ug\\Toml11FilePathsMre.exe\
"""
C:\Users\segmentation_fault\source\repos\Toml11FilePathsMre\x64\Debug\Toml11FilePathsMre.exe (process 13700) exited with code 0.
What I expect:
exePath = "C:\\Users\\segmentation_fault\\source\\repos\\Toml11FilePathsMre\\x64\\Debug\\Toml11FilePathsMre.exe"
This seems to only affect string that are file/directory paths. A random as long string serializes fine with toml. Parsing and reading a directory path is fine. This only happens with serialization. I don't see anything special with regards to serializing strings that are paths
I have a feeling I am doing something wrong, this doesn't seem like a bug with toml11 and I can't see what I might be doing wrong...
I have resolved the issue. According to author here, toml11's serializer will use a multi-line version if a (fuzzy) threshold is reached.
You can change the max width by specifying a parameter when serializing your data:
const std::string configString = toml::format(data, 200);
Which gives me the, correct, following output:
exePath = "C:\\Users\\segmentation_fault\\source\\repos\\Toml11FilePathsMre\\x64\\Debug\\Toml11FilePathsMre.exe"
In the issue linked, the author of the library explains another way to achieve the same result, but setting the width worked for me and I didn't try the other method.