2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file strgen.h Structures related to strgen. */
13 #include "../language.h"
14 #include "../3rdparty/fmt/format.h"
16 #include <unordered_map>
19 /** Container for the different cases of a string. */
21 int caseidx
; ///< The index of the case.
22 std::string string
; ///< The translation of the case.
24 Case(int caseidx
, const std::string
&string
);
27 /** Information about a single string. */
29 std::string name
; ///< Name of the string.
30 std::string english
; ///< English text.
31 std::string translated
; ///< Translated text.
32 size_t index
; ///< The index in the language file.
33 int line
; ///< Line of string in source-file.
34 std::vector
<Case
> translated_cases
; ///< Cases of the translation.
36 LangString(const std::string
&name
, const std::string
&english
, size_t index
, int line
);
37 void FreeTranslation();
40 /** Information about the currently known strings. */
42 std::vector
<std::unique_ptr
<LangString
>> strings
; ///< List of all known strings.
43 std::unordered_map
<std::string_view
, LangString
*> name_to_string
; ///< Lookup table for the strings.
44 size_t tabs
; ///< The number of 'tabs' of strings.
45 size_t max_strings
; ///< The maximum number of strings.
46 size_t next_string_id
;///< The next string ID to allocate.
48 StringData(size_t tabs
);
49 void FreeTranslation();
50 void Add(std::unique_ptr
<LangString
> ls
);
51 LangString
*Find(const std::string_view s
);
52 uint
VersionHashStr(uint hash
, const char *s
) const;
54 uint
CountInUse(uint tab
) const;
57 /** Helper for reading strings. */
59 StringData
&data
; ///< The data to fill during reading.
60 const std::string file
; ///< The file we are reading.
61 bool master
; ///< Are we reading the master file?
62 bool translation
; ///< Are we reading a translation, implies !master. However, the base translation will have this false.
64 StringReader(StringData
&data
, const std::string
&file
, bool master
, bool translation
);
65 virtual ~StringReader() {}
66 void HandleString(char *str
);
69 * Read a single line from the source of strings.
70 * @return The line, or std::nullopt if at the end of the file.
72 virtual std::optional
<std::string
> ReadLine() = 0;
75 * Handle the pragma of the file.
76 * @param str The pragma string to parse.
78 virtual void HandlePragma(char *str
);
81 * Start parsing the file.
83 virtual void ParseFile();
86 /** Base class for writing the header, i.e. the STR_XXX to numeric value. */
89 * Write the string ID.
90 * @param name The name of the string.
91 * @param stringid The ID of the string.
93 virtual void WriteStringID(const std::string
&name
, int stringid
) = 0;
96 * Finalise writing the file.
97 * @param data The data about the string.
99 virtual void Finalise(const StringData
&data
) = 0;
101 /** Especially destroy the subclasses. */
102 virtual ~HeaderWriter() = default;
104 void WriteHeader(const StringData
&data
);
107 /** Base class for all language writers. */
108 struct LanguageWriter
{
110 * Write the header metadata. The multi-byte integers are already converted to
111 * the little endian format.
112 * @param header The header to write.
114 virtual void WriteHeader(const LanguagePackHeader
*header
) = 0;
117 * Write a number of bytes.
118 * @param buffer The buffer to write.
119 * @param length The amount of byte to write.
121 virtual void Write(const uint8_t *buffer
, size_t length
) = 0;
124 * Finalise writing the file.
126 virtual void Finalise() = 0;
128 /** Especially destroy the subclasses. */
129 virtual ~LanguageWriter() = default;
131 virtual void WriteLength(uint length
);
132 virtual void WriteLang(const StringData
&data
);
138 const CmdStruct
*cmd
;
142 struct ParsedCommandStruct
{
143 std::vector
<CmdPair
> non_consuming_commands
;
144 std::array
<const CmdStruct
*, 32> consuming_commands
{ nullptr }; // ordered by param #
147 const CmdStruct
*TranslateCmdForCompare(const CmdStruct
*a
);
148 ParsedCommandStruct
ExtractCommandString(const char *s
, bool warnings
);
150 void StrgenWarningI(const std::string
&msg
);
151 void StrgenErrorI(const std::string
&msg
);
152 [[noreturn
]] void StrgenFatalI(const std::string
&msg
);
153 #define StrgenWarning(format_string, ...) StrgenWarningI(fmt::format(FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__))
154 #define StrgenError(format_string, ...) StrgenErrorI(fmt::format(FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__))
155 #define StrgenFatal(format_string, ...) StrgenFatalI(fmt::format(FMT_STRING(format_string) __VA_OPT__(,) __VA_ARGS__))
156 char *ParseWord(char **buf
);
158 extern const char *_file
;
159 extern int _cur_line
;
160 extern int _errors
, _warnings
, _show_todo
;
161 extern LanguagePackHeader _lang
;
163 #endif /* STRGEN_H */