Code View

mstring / mstring-1.3.1.2 / README.md
Preview
# mstring

**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}!"
```

```sh
mstring hello.msg        # → hello.hh, hello.cpp
```

```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.

- **[mstring.fedem.eu](https://mstring.fedem.eu)** — the documentation
  site: user guide, the language with railroad diagrams, reference manual,
  annotated examples.
- **[docs/syntax.md](docs/syntax.md)** — the message file language, what is
  generated, the command line.
- **[examples/](examples)** — `hello` (languages, formats, string and
  streamable) and `errors` (exception, throw, fatal error, syslog), each
  built and smoke-tested with the project.

## Building

The parser is built on [cparse](https://cparse.fedem.eu); the build takes it
from Conan.

```sh
conan build .                      # configure, build, run the tests
conan create .                     # package it into the local Conan cache
```

or, for development:

```sh
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.

## Using mstring from CMake

`mstring_generate()` (cmake/mstring-generate.cmake, installed to
`lib/cmake/mstring/`) runs mstring at build time:

```cmake
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 `$IMPORT`ed 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:

```python
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()
```

```cmake
find_package(mstring REQUIRED)   # defines mstring_generate()
```

## Layout

| 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`) |

## License

MIT — see [LICENSE](LICENSE), [CONTRIBUTING.md](CONTRIBUTING.md) and
[TRADEMARKS.md](TRADEMARKS.md).