From 6cb0dc0ffbf6fe4b7fc41256101bd71b1e8c56be Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 23 Jun 2022 12:25:45 +0300 Subject: Add support for comments in dependency clauses block --- libbpkg/manifest.cxx | 68 +++++++++++++++++ libbpkg/manifest.hxx | 6 ++ tests/manifest/testscript | 184 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 258 insertions(+) diff --git a/libbpkg/manifest.cxx b/libbpkg/manifest.cxx index 4555bbc..a5aa728 100644 --- a/libbpkg/manifest.cxx +++ b/libbpkg/manifest.cxx @@ -1280,6 +1280,11 @@ namespace bpkg string (bool diag = true) const; }; + // If true, then comments are allowed and are treated as whitespace + // characters. + // + bool comments = false; + public: // Note that name is stored by shallow reference. // @@ -1549,6 +1554,60 @@ namespace bpkg case ' ': case '\t': break; + case '#': + { + if (!comments) + return; + + get (c); + + // See if this is a multi-line comment in the form: + // + /* + #\ + ... + #\ + */ + auto ml = [&c, this] () -> bool + { + if ((c = peek ()) == '\\') + { + get (c); + if ((c = peek ()) == '\n' || eos (c)) + return true; + } + + return false; + }; + + if (ml ()) + { + // Scan until we see the closing one. + // + for (;;) + { + if (c == '#' && ml ()) + break; + + if (eos (c = peek ())) + throw parsing (name_, + c.line, c.column, + "unterminated multi-line comment"); + + get (c); + } + } + else + { + // Read until newline or eos. + // + for (; !eos (c) && c != '\n'; c = peek ()) + get (c); + } + + continue; + } + case '\n': { // Skip empty lines. @@ -2112,6 +2171,10 @@ namespace bpkg t.column, "multi-line " + what + " form with inline reflect clause"); + // Allow comments. + // + lexer_->comments = true; + next (t, tt); expect_token (type::newline); @@ -2260,6 +2323,11 @@ namespace bpkg } expect_token (type::rcbrace); + + // Disallow comments. + // + lexer_->comments = false; + next (t, tt); } } diff --git a/libbpkg/manifest.hxx b/libbpkg/manifest.hxx index a3415cc..2faf104 100644 --- a/libbpkg/manifest.hxx +++ b/libbpkg/manifest.hxx @@ -516,6 +516,12 @@ namespace bpkg // - buildfile fragment containing dependent package // configuration variables assignments // + // In the multi-line form the block may contain comments besides the + // clauses. The '#' character starts a single-line comment which spans + // until the end of the line. Unless it is followed with '\' followed by + // the newline in which case this is a multi-line comment which spans + // until the closing '#\' is encountered. + // // The dependency alternative is only considered by bpkg if the enable // condition evaluates to true. If the enable clause is not specified, then // it is always considered. diff --git a/tests/manifest/testscript b/tests/manifest/testscript index 760a9de..0398206 100644 --- a/tests/manifest/testscript +++ b/tests/manifest/testscript @@ -953,6 +953,29 @@ stdin:6:14: error: config.foo.* variable assignment expected instead of EOE } + + : comments + : + $* <>EOE != 0 + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + } | + {bar # Error. + \ + EOI + stdin:15:6: error: invalid package name: length is less than two characters + EOE } : multi-line @@ -2560,6 +2583,167 @@ stdin:9:1: error: multi-line dependency form with inline reflect clause EOE } + + : comments + : + { + : single-line-separate + : + $* <>EOO + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + # Configure bar. + # + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + } + \ + EOI + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + } + \ + EOO + + : single-line-trailing + : + $* <>EOO + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + require # Configure bar. + { + config.bar.frame=4016 + config.bar.timeout=10 + } + } + \ + EOI + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + } + \ + EOO + + : multi-line + : + $* <>EOO + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + #\\ + # Configure bar. + # + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + #\\ + + prefer + { + config.bar.frame=4016 + config.bar.timeout=10 + } + + accept ($config.bar.frame >= 1024 && config.bar.timeout < 20) + } + \ + EOI + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + prefer + { + config.bar.frame=4016 + config.bar.timeout=10 + } + + accept ($config.bar.frame >= 1024 && config.bar.timeout < 20) + } + \ + EOO + + : multi-line-unterm + : + $* <>EOE != 0 + : 1 + name: foo + version: 2.0.0 + summary: Modern C++ parser + license: LGPLv2 + depends:\ + bar + { + #\\ + # Configure bar. + # + require + { + config.bar.frame=4016 + config.bar.timeout=10 + } + + prefer + { + config.bar.frame=4016 + config.bar.timeout=10 + } + + accept ($config.bar.frame >= 1024 && config.bar.timeout < 20) + } + \ + EOI + stdin:25:2: error: unterminated multi-line comment + EOE + } } : multiple-alternatives -- cgit v1.1