yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Ellie Hermaszewskaformatf65d756bf

master
6.4 KiB225 linesraw
1#ifndef SLANG_COMMAND_LINE_ARGS_H
2#define SLANG_COMMAND_LINE_ARGS_H
3
4// This file defines the `Name` type, used to represent
5// the name of types, variables, etc. in the AST.
6
7#include "../core/slang-basic.h"
8#include "slang-diagnostic-sink.h"
9#include "slang-source-loc.h"
10
11namespace Slang
12{
13
14struct CommandLineArg
15{
16    String value;  ///< The value of the arg
17    SourceLoc loc; ///< The location of the arg
18};
19
20/* This type ends up being really just a container for the sourceManager that has the CommandLine
21specific SourceLocs. That it would perhaps be better to just have SourceManager derive from
22RefObject, and then we could remove this type. */
23class CommandLineContext : public RefObject
24{
25public:
26    /// Get the source manager
27    SourceManager* getSourceManager() { return &m_sourceManager; }
28
29    CommandLineContext(ISlangFileSystemExt* fileSystemExt = nullptr)
30    {
31        m_sourceManager.initialize(nullptr, fileSystemExt);
32        // Make range start from high value, so can be differentiated from other uses
33        // That this doesn't not assume exclusive use of this range - just that in normal use
34        // scenarios there is no confusion, and using the wrong source manager, will typically
35        // report nothing is found.
36        m_sourceManager.allocateSourceRange(~(~SourceLoc::RawValue(0) >> 1));
37    }
38
39protected:
40    SourceManager m_sourceManager;
41};
42
43struct CommandLineArgs
44{
45    typedef CommandLineArg Arg;
46
47    SLANG_FORCE_INLINE Index getArgCount() const { return m_args.getCount(); }
48    const Arg& operator[](Index i) const { return m_args[i]; }
49
50    const Arg* begin() const { return m_args.begin(); }
51    const Arg* end() const { return m_args.end(); }
52
53    /// NOTE! Should NOT include the executable name
54    void setArgs(const char* const* args, size_t argCount);
55
56    /// True if has args in same order
57    bool hasArgs(const char* const* args, Index count) const;
58
59    /// Add an arg
60    void add(const Arg& arg) { m_args.add(arg); }
61
62    /// Ctor with a context
63    CommandLineArgs(CommandLineContext* context)
64        : m_context(context)
65    {
66    }
67    /// Default Ctor
68    CommandLineArgs() {}
69
70    // String m_executablePath;                ///< Can be optionally be set
71    List<Arg> m_args;                     ///< The args
72    RefPtr<CommandLineContext> m_context; ///< The context, which mainly has source manager
73
74    String serialize();
75    void deserialize(String content);
76};
77
78struct CommandLineReader
79{
80    /// Peek the current location
81    SourceLoc peekLoc() const
82    {
83        return m_index < m_args->getArgCount() ? (*m_args)[m_index].loc : SourceLoc();
84    }
85    /// Peek the current arg
86    const CommandLineArg& peekArg() const
87    {
88        SLANG_ASSERT(hasArg());
89        return (*m_args)[m_index];
90    }
91
92    /// Peek the string value at that position
93    const String& peekValue() const
94    {
95        SLANG_ASSERT(hasArg());
96        return (*m_args)[m_index].value;
97    }
98
99    /// Get the arg and advance
100    CommandLineArg getArgAndAdvance()
101    {
102        CommandLineArg arg(peekArg());
103        advance();
104        return arg;
105    }
106
107    const String& getValueAndAdvance()
108    {
109        const String& value = peekValue();
110        advance();
111        return value;
112    }
113
114    /// True if at end
115    bool atEnd() const { return m_index >= m_args->getArgCount(); }
116    /// True if has a current arg
117    bool hasArg() const { return !atEnd(); }
118
119    /// Advance to next arg
120    void advance()
121    {
122        SLANG_ASSERT(m_index < m_args->getArgCount());
123        m_index++;
124    }
125    /// Removes arg at current position
126    void removeArg()
127    {
128        SLANG_ASSERT(hasArg());
129        m_args->m_args.removeAt(m_index);
130    }
131
132    /// Get the value from the arg previous to the current position. Will assert if there isn't one.
133    String getPreviousValue() const;
134
135    /// If there is an arg outArg is set and advanced
136    /// Note, this *assumes* the previous arg is the option that initated this
137    SlangResult expectArg(String& outArg);
138    SlangResult expectArg(CommandLineArg& outArg);
139
140    /// Get the current index
141    Index getIndex() const { return m_index; }
142    /// Set the current index
143    void setIndex(Index index)
144    {
145        SLANG_ASSERT(index >= 0 && index <= m_args->getArgCount());
146        m_index = index;
147    }
148
149    void init(CommandLineArgs* args, DiagnosticSink* sink)
150    {
151        m_args = args;
152        m_sink = sink;
153        m_index = 0;
154    }
155
156    /// Set up reader with args
157    CommandLineReader(CommandLineArgs* args, DiagnosticSink* sink) { init(args, sink); }
158    CommandLineReader() = default;
159
160    DiagnosticSink* m_sink = nullptr;
161    CommandLineArgs* m_args = nullptr;
162    Index m_index = 0;
163};
164
165struct DownstreamArgs
166{
167    typedef uint32_t Flags;
168    struct Flag
169    {
170        enum Enum : Flags
171        {
172            AllowNewNames = 0x01,
173        };
174    };
175
176    struct Entry
177    {
178        String name;          ///< The name of the 'tool' that these args are associated with
179        CommandLineArgs args; ///< The args to be passed to the tool
180    };
181
182    /// Add a name, returns the index
183    Index addName(const String& name);
184    /// Find the index of a name. Returns < 0 if not found.
185    Index findName(const String& name) const
186    {
187        return m_entries.findFirstIndex(
188            [&](const Entry& entry) -> bool { return entry.name == name; });
189    }
190
191    /// Get the args at the nameIndex
192    CommandLineArgs& getArgsAt(Index nameIndex) { return m_entries[nameIndex].args; }
193    /// Get args by name - will assert if name isn't found
194    CommandLineArgs& getArgsByName(const char* name);
195    const CommandLineArgs& getArgsByName(const char* name) const;
196
197    /// Looks for '-X' expressions, removing them from ioArgs and putting in appropriate args
198    SlangResult stripDownstreamArgs(CommandLineArgs& ioArgs, Flags flags, DiagnosticSink* sink);
199
200    /// Get the context used
201    CommandLineContext* getContext() const { return m_context; }
202
203    /// Ctor
204    DownstreamArgs(CommandLineContext* context);
205
206    /// Default ctor - for convenience, should really use with context normally
207    DownstreamArgs() {}
208
209    List<Entry> m_entries; ///< All of the entries
210
211protected:
212    Index _findOrAddName(
213        SourceLoc loc,
214        const UnownedStringSlice& name,
215        Flags flags,
216        DiagnosticSink* sink);
217
218    RefPtr<CommandLineContext> m_context; ///< The context that is being used (primarily for loc
219                                          ///< tracking) across all entries/args
220};
221
222
223} // namespace Slang
224
225#endif