@@ -19,11 +19,11 @@ void print_help_message() {
1919 " -s, --source <file> sets the path of the source file.\n "
2020 " -h, --header <file> sets the path of the header file.\n "
2121 // " -e, --embed use #embed for embedding files.\n"
22- " -n, --native reduce overhead by optimizing for native endianness.\n "
2322 " -d, --data <type> use type for data (e.g. uint8_t, std::byte, void)\n "
2423 " -t, --type <type> use type for resource (e.g. std::span<const uint8_t>).\n "
2524 " -a, --alias <type> declare an alias for resource type.\n "
2625 " -i, --include <file> add #include to generated header.\n "
26+ " -n, --native optimize for native endianness to improve compile-time.\n "
2727 " \n "
2828 " All Rights Reserved.\n "
2929 " This program comes with absolutely no warranty.\n "
@@ -69,7 +69,11 @@ bool is_space(char c) {
6969}
7070
7171bool is_alnum (char c) {
72- return (std::isalnum (static_cast <unsigned char >(c)) || c == ' _' );
72+ return (std::isalnum (static_cast <unsigned char >(c)));
73+ }
74+
75+ bool is_digit (char c) {
76+ return (std::isdigit (static_cast <unsigned char >(c)));
7377}
7478
7579std::filesystem::path utf8_to_path (std::string_view utf8_string) {
@@ -207,21 +211,42 @@ std::string normalize_path(std::string&& path) {
207211}
208212
209213std::string normalize_id (std::string&& id) {
210- id = replace_all (
214+ return replace_all (
211215 replace_all (std::move (id), " /" , " $" ), " ::" , " /" );
212- for (const auto & c : id)
213- if (!is_alnum (c) && c != ' /' )
214- error (" invalid identifier" );
215- if (!id.empty () && id.back () == ' /' )
216- error (" invalid identifier" );
217- return id;
216+ }
217+
218+ bool is_valid_identifier (std::string_view id) {
219+ if (id.empty ())
220+ return false ;
221+
222+ auto after_slash = true ;
223+ for (const auto & c : id) {
224+ if (!is_alnum (c) && c != ' _' && c != ' /' )
225+ return false ;
226+ if (after_slash && is_digit (c))
227+ return false ;
228+ after_slash = (c == ' /' );
229+ }
230+ if (id.back () == ' /' )
231+ return false ;
232+ return true ;
218233}
219234
220235std::string deduce_id_from_path (bool is_header, const std::string& path) {
221236 auto id = trim (is_header ? path : remove_extension (path));
237+
238+ // replace not allowed characters
222239 for (auto & c : id)
223240 if (!is_alnum (c) && c != ' /' )
224241 c = ' _' ;
242+
243+ // insert _ before initial digits
244+ auto after_slash = true ;
245+ for (auto it = id.begin (); it != id.end (); ++it) {
246+ if (after_slash && is_digit (*it))
247+ it = id.insert (it, ' _' );
248+ after_slash = (*it == ' /' );
249+ }
225250 return id;
226251}
227252
@@ -307,6 +332,9 @@ std::optional<Definition> parse_definition(const std::string& line) {
307332 else if (skip_until (' =' )) {
308333 // first is no string
309334 definition.id = normalize_id (trim ({ begin, it }));
335+ if (!definition.id .empty () &&
336+ !is_valid_identifier (definition.id ))
337+ error (" invalid identifier" );
310338 ++it;
311339 skip_space ();
312340 begin = it;
0 commit comments