blob: 42679d4e31ec4bbc9913866d1d3703baa60aaeb1 [file] [log] [blame]
// Copyright 2017-2020 The Verible Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "verilog/transform/strip_comments.h"
#include <sstream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
namespace verilog {
namespace {
struct StripCommentsTestCase {
absl::string_view input;
absl::string_view expect_deleted;
absl::string_view expect_spaced;
absl::string_view expect_otherchar;
};
TEST(StripVerilogCommentsTest, Various) {
constexpr StripCommentsTestCase kTestCases[] = {
{
"",
"",
"",
"",
},
{
// Not even valid Verilog, but still lexes.
"This is not the greatest code in the world,\n"
"This is just a tribute.\n",
// delete
"This is not the greatest code in the world,\n"
"This is just a tribute.\n",
// space-out
"This is not the greatest code in the world,\n"
"This is just a tribute.\n",
// other char
"This is not the greatest code in the world,\n"
"This is just a tribute.\n",
},
{
"//shush\n",
"\n",
" \n",
"//.....\n",
},
{
"//////\n",
"\n",
" \n",
"//////\n",
},
{
"//////sh\n",
"\n",
" \n",
"//////..\n",
},
{
"/*hush*/\n",
" \n",
" \n",
"/*....*/\n",
},
{
"/***hush***/\n",
" \n",
" \n",
"/***....***/\n",
},
{
"key/**/word",
"key word", // one space to prevent accidental joining of tokens
"key word",
"key/**/word",
},
{
// ignore lexcically invalid tokens, and pass them through
"/*yyyy*/123badid/*zzzz*/654anotherbadone//xxxxx\n",
" 123badid 654anotherbadone\n",
" 123badid 654anotherbadone \n",
"/*....*/123badid/*....*/654anotherbadone//.....\n",
},
{
"begin\n"
" /*\n"
"a a\n"
"bb\n"
"c\n"
" */ \n" // trailing spaces
"end\n",
// delete
"begin\n"
" \n"
"end\n",
// space-out
"begin\n"
" \n"
" \n"
" \n"
" \n"
" \n"
"end\n",
// other char
"begin\n"
" /*\n"
"...\n"
"..\n"
".\n"
"..*/ \n" // trailing spaces
"end\n",
},
{
// macro call, no comments
"`MACRO(a, b)\n",
"`MACRO(a, b)\n",
"`MACRO(a, b)\n",
"`MACRO(a, b)\n",
},
{
// macro call, one comment arg
"`MACRO(/*abc*/)\n",
"`MACRO( )\n",
"`MACRO( )\n",
"`MACRO(/*...*/)\n",
},
{
// macro call, comments around args
"`MACRO(/*!*/a/*?*/,/*!*/b/*?*/)\n",
"`MACRO( a , b )\n",
"`MACRO( a , b )\n",
"`MACRO(/*.*/a/*.*/,/*.*/b/*.*/)\n",
},
{
// macro call, where args are themselves macro calls
"`MACRO(/*!*/`INNER(a/*?*/,/*!*/b)/*?*/)\n",
"`MACRO( `INNER(a , b) )\n",
"`MACRO( `INNER(a , b) )\n",
"`MACRO(/*.*/`INNER(a/*.*/,/*.*/b)/*.*/)\n",
},
{
// macro call, EOL comments inside
"`MACRO(//abc\n"
" //defg\n"
")\n",
// delete
"`MACRO(\n"
" \n"
")\n",
// space-out
"`MACRO( \n"
" \n"
")\n",
// other char
"`MACRO(//...\n"
" //....\n"
")\n",
},
{
"`define MACRO //xyzxyz\n",
"`define MACRO \n",
"`define MACRO \n",
"`define MACRO //......\n",
},
{
// same, but missing terminating \n
"`define MACRO //xyzxyz",
"`define MACRO ",
"`define MACRO ",
"`define MACRO //......",
},
{
"`define MACRO /*-*/ab/*+*/\n",
"`define MACRO ab \n",
"`define MACRO ab \n",
"`define MACRO /*.*/ab/*.*/\n",
},
{
// multiline macro definition body using line-continuations
"`define MACRO //---\\\n"
" //--- \\\n"
" //-----\n",
// delete
"`define MACRO \\\n"
" \\\n"
" \n",
// space-out
"`define MACRO \\\n"
" \\\n"
" \n",
// other char
"`define MACRO //...\\\n"
" //.....\\\n"
" //.....\n",
},
{
// multiline macro definition body using line-continuations (no end
// \n)
"`define MACRO //---\\\n"
" //--- \\\n"
" //-----",
// delete
"`define MACRO \\\n"
" \\\n"
" ",
// space-out
"`define MACRO \\\n"
" \\\n"
" ",
// other char
"`define MACRO //...\\\n"
" //.....\\\n"
" //.....",
},
{
// multiline macro definition body using line-continuations
"`define MACRO /*-*/\\\n"
" /*-*/ \\\n"
" /*---*/\n",
// delete
"`define MACRO \\\n"
" \\\n"
" \n",
// space-out
"`define MACRO \\\n"
" \\\n"
" \n",
// other char
"`define MACRO /*.*/\\\n"
" /*.*/ \\\n"
" /*...*/\n",
},
{
// `define inside `define
"`define FOO \\\n"
" // description of BAR \\\n"
"`define BAR \\\n"
" // placeholder1 \\\n"
" // placeholder2\n",
// delete
"`define FOO \\\n"
" \\\n"
"`define BAR \\\n"
" \\\n"
" \n",
// space-out
"`define FOO \\\n"
" \\\n"
"`define BAR \\\n"
" \\\n"
" \n",
// other char
"`define FOO \\\n"
" //....................\\\n"
"`define BAR \\\n"
" //..............\\\n"
" //.............\n",
},
{
// macro call inside `define, one comment arg
"`define DEF `MACRO(/*abc*/)\n",
"`define DEF `MACRO( )\n",
"`define DEF `MACRO( )\n",
"`define DEF `MACRO(/*...*/)\n",
},
};
for (const auto& test : kTestCases) {
{
std::ostringstream stream;
StripVerilogComments(test.input, &stream, '\0');
EXPECT_EQ(stream.str(), test.expect_deleted);
}
{
std::ostringstream stream;
StripVerilogComments(test.input, &stream, ' ');
EXPECT_EQ(stream.str(), test.expect_spaced);
}
{
std::ostringstream stream;
StripVerilogComments(test.input, &stream, '.');
EXPECT_EQ(stream.str(), test.expect_otherchar);
}
}
}
} // namespace
} // namespace verilog