diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-05-21 18:41:54 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-21 15:41:54 -0700 |
| commit | 172538fdb418f7a2faab1f5a410f3b2cb8e18ba5 (patch) | |
| tree | b17fd1cae7ace4bb3f2dbdd4ad29f4f57df0b286 /source/compiler-core/slang-command-line-args.cpp | |
| parent | 0389546b0b065303d3c6874891a9fab4428910b9 (diff) | |
Downstream option handling (#1850)
* #include an absolute path didn't work - because paths were taken to always be relative.
* Added SourceLoc handling for command line parsing.
* Fix typo in debug.
* Fix issue around the DiagnosticSink used in options parsing not having a writer available - by having DiagnosticSink parenting.
* Small rename for clarity.
* WIP extracting command line args for downstream tools.
* Unit tests/bug fixes around extracting args.
* Use DownstreamArgs in the EndToEndCompileRequest
* Passing downstream compiler options downstream.
* Fix issue with endToEndReq being nullptr.
* Fix issue with diagnostics number change.
* Small improvements to how the source line is displayed if it's too long.
Default to 120, as suggested in previous review.
Co-authored-by: T. Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/compiler-core/slang-command-line-args.cpp')
| -rw-r--r-- | source/compiler-core/slang-command-line-args.cpp | 187 |
1 files changed, 183 insertions, 4 deletions
diff --git a/source/compiler-core/slang-command-line-args.cpp b/source/compiler-core/slang-command-line-args.cpp index da262e9bb..1d452bb10 100644 --- a/source/compiler-core/slang-command-line-args.cpp +++ b/source/compiler-core/slang-command-line-args.cpp @@ -11,7 +11,9 @@ void CommandLineArgs::setArgs(const char*const* args, size_t argCount) { m_args.clear(); - const SourceLoc startLoc = m_sourceManager->getNextRangeStart(); + SourceManager* sourceManager = m_context->getSourceManager(); + + const SourceLoc startLoc = sourceManager->getNextRangeStart(); StringBuilder buf; @@ -36,12 +38,32 @@ void CommandLineArgs::setArgs(const char*const* args, size_t argCount) buf << " "; } - SourceFile* sourceFile = m_sourceManager->createSourceFileWithString(PathInfo::makeUnknown(), buf.ProduceString()); - m_sourceView = m_sourceManager->createSourceView(sourceFile, nullptr, SourceLoc::fromRaw(0)); + SourceFile* sourceFile = sourceManager->createSourceFileWithString(PathInfo::makeUnknown(), buf.ProduceString()); + SourceView* sourceView = sourceManager->createSourceView(sourceFile, nullptr, SourceLoc::fromRaw(0)); - SLANG_ASSERT(m_sourceView->getRange().begin == startLoc); + SLANG_UNUSED(sourceView); + SLANG_ASSERT(sourceView->getRange().begin == startLoc); } +bool CommandLineArgs::hasArgs(const char*const* args, Index count) const +{ + if (m_args.getCount() != count) + { + return false; + } + + for (Index i = 0; i < count; ++i) + { + if (m_args[i].value != args[i]) + { + return false; + } + } + + return true; +} + + /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! CommandLineReader @@ -91,5 +113,162 @@ SlangResult CommandLineReader::expectArg(CommandLineArg& outArg) } } +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + DownstreamArgs + +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +Index DownstreamArgs::addName(const String& name) +{ + Index index = m_names.indexOf(name); + if (index < 0) + { + index = m_names.getCount(); + m_names.add(name); + + CommandLineArgs args(m_context); + m_args.add(args); + } + return index; +} + +Index DownstreamArgs::_findOrAddName(SourceLoc loc, const UnownedStringSlice& name, Flags flags, DiagnosticSink* sink) +{ + if (name.getLength() <= 0) + { + sink->diagnose(loc, MiscDiagnostics::downstreamToolNameNotDefined); + return -1; + } + + if (flags & Flag::AllowNewNames) + { + return addName(name); + } + + Index index = findName(name); + if (index >= 0) + { + return index; + } + + sink->diagnose(loc, MiscDiagnostics::downstreamNameNotKnown); + return -1; +} + +CommandLineArgs& DownstreamArgs::getArgsByName(char* name) +{ + Index index = findName(name); + SLANG_ASSERT(index >= 0); + return m_args[index]; +} + +SlangResult DownstreamArgs::stripDownstreamArgs(CommandLineArgs& ioArgs, Flags flags, DiagnosticSink* sink) +{ + CommandLineReader reader(&ioArgs, sink); + + while (reader.hasArg()) + { + const CommandLineArg& arg = reader.peekArg(); + + if (arg.value.startsWith("-X")) + { + if (arg.value.endsWith("...")) + { + const UnownedStringSlice name = arg.value.getUnownedSlice().subString(2, arg.value.getLength() - 5); + const Index nameIndex = _findOrAddName(arg.loc, name, flags, sink); + if (nameIndex < 0) + { + return SLANG_FAIL; + } + + Index depth = 1; + const Index startIndex = reader.getIndex(); + + Int index = startIndex + 1; + const Int count = ioArgs.m_args.getCount(); + + for (; index < count; ++index) + { + const auto& curArg = ioArgs.m_args[index]; + + if (curArg.value == "-X.") + { + depth--; + // If we are at end of scope we are done + if (depth <= 0) + { + break; + } + } + else if (curArg.value.startsWith("-X") && curArg.value.endsWith("...")) + { + depth++; + } + } + + // We don't care if its 1, as we allow the main scope to be left open + if (depth > 1) + { + sink->diagnose(arg.loc, MiscDiagnostics::unbalancedDownstreamArguments); + return SLANG_FAIL; + } + + // We are either at end of scope or at end of list + SLANG_ASSERT(depth <= 0 || index >= count); + + // Add all of these args + CommandLineArgs& args = getArgsAt(nameIndex); + + // Copy the values in the range + args.m_args.addRange(ioArgs.m_args.getBuffer() + startIndex + 1, index - (startIndex + 1)); + + // If we aren't at the end, we must be pointing to -X., so skip that + index += Index(index < count); + // Remove the range. The readers position, needs to be fixed though + ioArgs.m_args.removeRange(startIndex, index - startIndex); + + // The reader should be at startIndex, and so doesn't need fixing + SLANG_ASSERT(reader.getIndex() == startIndex); + } + else if (arg.value == "-X.") + { + sink->diagnose(arg.loc, MiscDiagnostics::closeOfUnopenDownstreamArgs); + return SLANG_FAIL; + } + else + { + const Index startIndex = reader.getIndex(); + + // Extract the name + UnownedStringSlice name = arg.value.getUnownedSlice().tail(2); + const Index nameIndex = _findOrAddName(arg.loc, name, flags, sink); + if (nameIndex < 0) + { + return SLANG_FAIL; + } + + reader.advance(); + + CommandLineArg nextArg; + SLANG_RETURN_ON_FAIL(reader.expectArg(nextArg)); + + getArgsAt(nameIndex).add(nextArg); + + // Rewind to the start index + reader.setIndex(startIndex); + // Remove the args + ioArgs.m_args.removeRange(startIndex, 2); + } + } + else + { + // Advance and leave + reader.advance(); + } + } + + return SLANG_OK; +} } // namespace Slang |
