From 431f4eee66fab75c758d7c09f04327823fed0099 Mon Sep 17 00:00:00 2001 From: assiduous Date: Tue, 9 Jan 2024 18:58:51 -0800 Subject: [PATCH] Parsing tools: added RefinePreprocessorDirective function --- Common/interface/ParsingTools.hpp | 41 ++++++++++++++++++- .../src/Common/ParsingToolsTest.cpp | 30 +++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Common/interface/ParsingTools.hpp b/Common/interface/ParsingTools.hpp index 2c5459ad1..8a59d1851 100644 --- a/Common/interface/ParsingTools.hpp +++ b/Common/interface/ParsingTools.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1084,6 +1084,45 @@ std::string GetTokenContext(const TokenIterType& Start, return Ctx.str(); } +/// Extracts the preprocessor directive from the given range +template +std::string RefinePreprocessorDirective(const InteratorType& Start, const InteratorType& End) noexcept +{ + // # /* Comment */ define + // ^ + // Pos + if (Start == End || *Start != '#') + return ""; + + const auto DirectiveStart = SkipDelimitersAndComments(Start + 1, End, " \t", SKIP_COMMENT_FLAG_MULTILINE); + // # /* Comment */ define + // ^ + // DirectiveStart + + const auto DirectiveEnd = SkipIdentifier(DirectiveStart, End); + // # /* Comment */ define + // ^ + // Pos + + return std::string{DirectiveStart, DirectiveEnd}; +} + +inline std::string RefinePreprocessorDirective(const std::string& Str) noexcept +{ + return RefinePreprocessorDirective(Str.begin(), Str.end()); +} + +inline std::string RefinePreprocessorDirective(const char* Str, size_t Len = 0) noexcept +{ + if (Str == nullptr) + return ""; + + if (Len == 0) + Len = strlen(Str); + + return RefinePreprocessorDirective(Str, Str + Len); +} + } // namespace Parsing } // namespace Diligent diff --git a/Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp b/Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp index a43d88682..02493d04b 100644 --- a/Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp +++ b/Tests/DiligentCoreTest/src/Common/ParsingToolsTest.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 Diligent Graphics LLC + * Copyright 2019-2024 Diligent Graphics LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1341,4 +1341,32 @@ TEST(Common_ParsingTools, GetTokenContext) } } + +TEST(Common_ParsingTools, RefinePreprocessorDirective) +{ + auto TestRefine = [](const std::string& Str, const char* RefStr) { + EXPECT_STREQ(RefinePreprocessorDirective(Str).c_str(), RefStr); + EXPECT_STREQ(RefinePreprocessorDirective(Str.c_str()).c_str(), RefStr); + EXPECT_STREQ(RefinePreprocessorDirective(Str.c_str(), Str.length()).c_str(), RefStr); + }; + + TestRefine("", ""); + TestRefine(" ", ""); + TestRefine("#", ""); + TestRefine("# ", ""); + TestRefine("# \t", ""); + TestRefine("# \n", ""); + TestRefine("# /*Comment*/", ""); + + TestRefine("define", ""); + TestRefine("#\ndefine", ""); + TestRefine("# // define", ""); + TestRefine(",define", ""); + + TestRefine("#define", "define"); + TestRefine("# define", "define"); + TestRefine("# \t define", "define"); + TestRefine("# \t /* Comment*/ define", "define"); +} + } // namespace