1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2021, The LegacyClonk Team and contributors
6 *
7 * Distributed under the terms of the ISC license; see accompanying file
8 * "COPYING" for details.
9 *
10 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11 * See accompanying file "TRADEMARK" for details.
12 *
13 * To redistribute this file separately, substitute the full license texts
14 * for the above references.
15 */
16
17#include "C4Application.h"
18#include "C4ResStrTable.h"
19
20#include <Standard.h>
21
22#include <format>
23#include <optional>
24
25C4ResStrTable::C4ResStrTable(const std::string_view code, std::string_view table)
26{
27 auto keyStringMap = GetKeyStringMap();
28
29 for (auto pos = table.find_first_of(c: '='); pos != std::string_view::npos; pos = table.find_first_of(c: '='))
30 {
31 const auto key = table.substr(pos: 0, n: pos);
32 table.remove_prefix(n: pos + 1);
33
34 const auto endPos = table.find_first_not_of(str: "\r\n", pos: table.find_first_of(str: "\r\n"));
35 auto value = table.substr(pos: 0, n: endPos);
36 table.remove_prefix(n: value.size());
37 value = value.substr(pos: 0, n: value.find_last_not_of(str: "\r\n") + 1);
38
39 if (const auto it = keyStringMap.find(x: key); it != keyStringMap.end())
40 {
41 std::string &valueStr{entries[static_cast<std::size_t>(it->second)] = value};
42 keyStringMap.erase(position: it);
43
44 for (auto backslashPos = valueStr.find_first_of(c: '\\'); backslashPos < valueStr.size() - 1; backslashPos = valueStr.find_first_of(c: '\\', pos: backslashPos + 1))
45 {
46 if (valueStr[backslashPos + 1] == 'n')
47 {
48 valueStr.replace(pos: backslashPos, n1: 2, s: "\r\n");
49 }
50 }
51 }
52 }
53
54 for (const auto &[key, value] : keyStringMap)
55 {
56 if (!code.empty())
57 {
58 spdlog::warn(fmt: "Missing entry in string table {} for key {}", args: code, args: key);
59 }
60
61 entries[static_cast<std::size_t>(value)] = std::format(fmt: "[Undefined: {}]", args: key);
62 }
63}
64
65std::string_view C4ResStrTable::GetEntry(const C4ResStrTableKey key) const
66{
67 return entries[static_cast<std::size_t>(key)];
68}
69
70const char *LoadResStrV(const C4ResStrTableKey id)
71{
72 if (!Application.ResStrTable.has_value()) return "Language string table not loaded.";
73 return Application.ResStrTable->GetEntry(key: id).data();
74}
75
76std::string LoadResStrNoAmpV(const C4ResStrTableKey id)
77{
78 std::string result{LoadResStrV(id)};
79 result.erase(first: std::remove(first: result.begin(), last: result.end(), value: '&'), last: result.end());
80 return result;
81}
82