
mstring (message-string) generates C++ code from a file of localized messages. You write each message once — its parameters and its text in every language — and mstring writes the functions and classes that produce it: a string function, a streamable class, an error function, an exception class with a throw function, a syslog function. The generated code needs nothing but the C++17 standard library.
$MODULE hello
$STRING ENABLE
$LANGUAGE en
$MESSAGE Welcome
@ user std::string const &
"Welcome, {$user}!"
[tr]
"Hoş geldin, {$user}!"
mstring hello.msg # → hello.hh, hello.cpp
#include "hello.hh"
std::cout << WelcomeStr( "Ada" ); // Welcome, Ada!
std::cout << WelcomeStr( "Ada", std::locale( "tr_TR.UTF-8" ) ); // Hoş geldin, Ada!
The language is chosen from the locale name at run time ([tr] matches tr_TR.UTF-8); the texts are compiled in, there are no catalog files to ship.
What it is for. mstring is at its best for the messages of C++ libraries and tools: errors, exceptions, log lines and diagnostics in a few languages, with typed parameters (a wrong argument is a compile error, not a garbled message at run time) and no runtime dependency. It is not a general UI translation system: translations are compiled in (a new translation means a rebuild), and there are no plural rules yet — for an application's user interface, gettext, ICU or your framework's catalog system fit better.
hello (languages, formats, string and streamable) and errors (exception, throw, fatal error, syslog), each built and smoke-tested with the project.The parser is built on cparse; the build takes it from Conan.
conan build . # configure, build, run the tests
conan create . # package it into the local Conan cache
or, for development:
conan install . --build=missing
cmake --preset conan-release
cmake --build --preset conan-release
ctest --test-dir build/Release --output-on-failure
CMake options: TESTING (tests/, default ON), EXAMPLE (examples/, default ON). The tests compile the code mstring generates for every feature with -Wall -Wextra -Wpedantic -Werror and run it, and check the diagnostics of broken inputs.
mstring_generate() (cmake/mstring-generate.cmake, installed to lib/cmake/mstring/) runs mstring at build time:
mstring_generate(MESSAGES_GENERATED messages.msg) # → messages.hh / .cpp
add_executable(app main.cpp ${MESSAGES_GENERATED})
target_include_directories(app PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
Options: MODULE, OUTPUT_DIRECTORY, HEADER_EXTENSION, SOURCE_EXTENSION, NOHEADER, NOSOURCE, INLINE, IMPORT_DIRECTORIES, OPTIONS (extra mstring options, e.g. -w), DEPENDS (list the $IMPORTed files there) — see the comment at the top of the file.
From a Conan consumer, take mstring as a tool and let CMakeDeps bring the module in:
def build_requirements(self):
self.tool_requires("mstring/[>=1.1 <2]")
def generate(self):
deps = CMakeDeps(self)
deps.build_context_activated = ["mstring"]
deps.build_context_build_modules = ["mstring"]
deps.generate()
find_package(mstring REQUIRED) # defines mstring_generate()
| Path | |
|---|---|
src/MStringParser.* | the message-file grammar (a cparse Parser) |
src/Settings.*, src/Message.*, src/Module.hh | what the parser builds |
src/MMessage.*, src/MText.*, src/MParameter.*, … | the C++ writers |
src/MString.*, src/main.cpp | output files, command line |
cmake/mstring-generate.cmake | mstring_generate() |
tests/ | feature, import, NOHEADER, INLINE, stdin, warning and diagnostics tests |
examples/ | the examples |
bench/ | ns per call of the generated string functions (-DBENCH=ON) |
MIT — see LICENSE, CONTRIBUTING.md and TRADEMARKS.md.