// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IncludeTool { /// /// Flags for a single token /// [Flags] enum TokenFlags { /// /// No flags /// None = 0x00, /// /// The token has space before it /// HasLeadingSpace = 0x01, /// /// Do not replace any instances of this token with the corresponding macro. /// DisableExpansion = 0x02, } /// /// Enumeration for token types /// enum TokenType { LeftParen, RightParen, Comma, Identifier, NumericLiteral, StringLiteral, CharacterLiteral, Symbol, StringOfTokens, SystemInclude, Placemarker, Unknown } /// /// Single lexical token /// [DebuggerDisplay("{Text}")] struct Token { /// /// Contents of this token /// public readonly string Text; /// /// The type of this token /// public readonly TokenType Type; /// /// Properties of this token /// public readonly TokenFlags Flags; /// /// Constructor /// public Token(string InText, TokenType InType, TokenFlags InFlags) { Text = InText; Type = InType; Flags = InFlags; } /// /// Accessor for whether this token has leading whitespace /// public bool HasLeadingSpace { get { return (Flags & TokenFlags.HasLeadingSpace) != 0; } } /// /// Tests whether this token matches the given string /// /// Token to compare against /// True if the token matches, false otherwise public bool Is(string Token) { return Text == Token; } /// /// Tests whether this token is a string /// /// True if this token is a string public bool IsString() { return Text.Length >= 2 && Text.StartsWith("\"") && Text.EndsWith("\""); } /// /// Tests whether this token represents a system includes, in angle brackets /// /// True if this token is a system include public bool IsSystemInclude() { return Text.StartsWith("<") && Text.EndsWith(">"); } /// /// Concatenate a sequence of tokens into a string /// /// The sequence of tokens to concatenate /// String containing the concatenated tokens public static string Format(IEnumerable Tokens) { StringBuilder Result = new StringBuilder(); IEnumerator Enumerator = Tokens.GetEnumerator(); if(Enumerator.MoveNext()) { Result.Append(Enumerator.Current.Text); Token LastToken = Enumerator.Current; while(Enumerator.MoveNext()) { Token Token = Enumerator.Current; if(Token.HasLeadingSpace && (Token.Type != TokenType.LeftParen || LastToken.Type != TokenType.Identifier || LastToken.Text != "__pragma")) { Result.Append(" "); } Result.Append(Token.Text); LastToken = Token; } } return Result.ToString(); } /// /// Concatenate two tokens together /// /// The first token /// The second token /// The combined token public static Token Concatenate(Token FirstToken, Token SecondToken) { string Text = FirstToken.Text + SecondToken.Text; TokenReader Reader = new TokenReader(Text); if(Reader.MoveNext()) { TokenType Type = Reader.Current.Type; return new Token(Text, Type, FirstToken.Flags & TokenFlags.HasLeadingSpace); } return new Token(Text, TokenType.Unknown, FirstToken.Flags & TokenFlags.HasLeadingSpace); } } }