yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
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{ 16String value ;///< The value of the arg 17SourceLoc 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 27SourceManager * getSourceManager () {return & m_sourceManager ; } 28 29CommandLineContext (ISlangFileSystemExt * fileSystemExt = nullptr ) 30 { 31m_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. 36m_sourceManager .allocateSourceRange (~(~SourceLoc ::RawValue (0 ) >>1 )); 37 } 38 39protected : 40SourceManager m_sourceManager ; 41}; 42 43struct CommandLineArgs 44{ 45typedef CommandLineArg Arg ; 46 47SLANG_FORCE_INLINE Index getArgCount ()const {return m_args .getCount (); } 48const Arg & operator [](Index i )const {return m_args [i ]; } 49 50const Arg * begin ()const {return m_args .begin (); } 51const Arg * end ()const {return m_args .end (); } 52 53/// NOTE! Should NOT include the executable name 54void setArgs (const char * const * args ,size_t argCount ); 55 56/// True if has args in same order 57bool hasArgs (const char * const * args ,Index count )const ; 58 59/// Add an arg 60void add (const Arg & arg ) {m_args .add (arg ); } 61 62/// Ctor with a context 63CommandLineArgs (CommandLineContext * context ) 64 :m_context (context ) 65 { 66 } 67/// Default Ctor 68CommandLineArgs () {} 69 70// String m_executablePath; ///< Can be optionally be set 71List < Arg > m_args ;///< The args 72RefPtr < CommandLineContext > m_context ;///< The context, which mainly has source manager 73 74String serialize (); 75void deserialize (String content ); 76}; 77 78struct CommandLineReader 79{ 80/// Peek the current location 81SourceLoc peekLoc ()const 82 { 83return m_index < m_args -> getArgCount () ? (* m_args )[m_index ].loc :SourceLoc (); 84 } 85/// Peek the current arg 86const CommandLineArg & peekArg ()const 87 { 88SLANG_ASSERT (hasArg ()); 89return (* m_args )[m_index ]; 90 } 91 92/// Peek the string value at that position 93const String & peekValue ()const 94 { 95SLANG_ASSERT (hasArg ()); 96return (* m_args )[m_index ].value ; 97 } 98 99/// Get the arg and advance 100CommandLineArg getArgAndAdvance () 101 { 102CommandLineArg arg (peekArg ()); 103advance (); 104return arg ; 105 } 106 107const String & getValueAndAdvance () 108 { 109const String & value = peekValue (); 110advance (); 111return value ; 112 } 113 114/// True if at end 115bool atEnd ()const {return m_index >=m_args -> getArgCount (); } 116/// True if has a current arg 117bool hasArg ()const {return !atEnd (); } 118 119/// Advance to next arg 120void advance () 121 { 122SLANG_ASSERT (m_index < m_args -> getArgCount ()); 123m_index ++ ; 124 } 125/// Removes arg at current position 126void removeArg () 127 { 128SLANG_ASSERT (hasArg ()); 129m_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. 133String 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 137SlangResult expectArg (String & outArg ); 138SlangResult expectArg (CommandLineArg & outArg ); 139 140/// Get the current index 141Index getIndex ()const {return m_index ; } 142/// Set the current index 143void setIndex (Index index ) 144 { 145SLANG_ASSERT (index >=0 && index <=m_args -> getArgCount ()); 146m_index = index ; 147 } 148 149void init (CommandLineArgs * args ,DiagnosticSink * sink ) 150 { 151m_args = args ; 152m_sink = sink ; 153m_index = 0 ; 154 } 155 156/// Set up reader with args 157CommandLineReader (CommandLineArgs * args ,DiagnosticSink * sink ) {init (args ,sink ); } 158CommandLineReader ()= default ; 159 160DiagnosticSink * m_sink = nullptr ; 161CommandLineArgs * m_args = nullptr ; 162Index m_index = 0 ; 163}; 164 165struct DownstreamArgs 166{ 167typedef uint32_t Flags ; 168struct Flag 169 { 170enum Enum :Flags 171 { 172AllowNewNames = 0x01 , 173 }; 174 }; 175 176struct Entry 177 { 178String name ;///< The name of the 'tool' that these args are associated with 179CommandLineArgs args ;///< The args to be passed to the tool 180 }; 181 182/// Add a name, returns the index 183Index addName (const String & name ); 184/// Find the index of a name. Returns < 0 if not found. 185Index findName (const String & name )const 186 { 187return m_entries .findFirstIndex ( 188 [& ](const Entry & entry )-> bool {return entry .name == name ; }); 189 } 190 191/// Get the args at the nameIndex 192CommandLineArgs & getArgsAt (Index nameIndex ) {return m_entries [nameIndex ].args ; } 193/// Get args by name - will assert if name isn't found 194CommandLineArgs & getArgsByName (const char * name ); 195const CommandLineArgs & getArgsByName (const char * name )const ; 196 197/// Looks for '-X' expressions, removing them from ioArgs and putting in appropriate args 198SlangResult stripDownstreamArgs (CommandLineArgs & ioArgs ,Flags flags ,DiagnosticSink * sink ); 199 200/// Get the context used 201CommandLineContext * getContext ()const {return m_context ; } 202 203/// Ctor 204DownstreamArgs (CommandLineContext * context ); 205 206/// Default ctor - for convenience, should really use with context normally 207DownstreamArgs () {} 208 209List < Entry > m_entries ;///< All of the entries 210 211protected : 212Index _findOrAddName ( 213SourceLoc loc , 214const UnownedStringSlice & name , 215Flags flags , 216DiagnosticSink * sink ); 217 218RefPtr < 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