diff --git a/Cesium.Ast/Cesium.Ast.csproj b/Cesium.Ast/Cesium.Ast.csproj
index 54c67da7..444a7901 100644
--- a/Cesium.Ast/Cesium.Ast.csproj
+++ b/Cesium.Ast/Cesium.Ast.csproj
@@ -6,8 +6,8 @@
-
-
+
+
diff --git a/Cesium.CodeGen.Tests/Cesium.CodeGen.Tests.csproj b/Cesium.CodeGen.Tests/Cesium.CodeGen.Tests.csproj
index 997ce591..1f0ee832 100644
--- a/Cesium.CodeGen.Tests/Cesium.CodeGen.Tests.csproj
+++ b/Cesium.CodeGen.Tests/Cesium.CodeGen.Tests.csproj
@@ -8,15 +8,15 @@
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Cesium.CodeGen/Cesium.CodeGen.csproj b/Cesium.CodeGen/Cesium.CodeGen.csproj
index d992d2ba..f1c067c7 100644
--- a/Cesium.CodeGen/Cesium.CodeGen.csproj
+++ b/Cesium.CodeGen/Cesium.CodeGen.csproj
@@ -7,8 +7,8 @@
-
-
+
+
diff --git a/Cesium.Compiler.Tests/Cesium.Compiler.Tests.csproj b/Cesium.Compiler.Tests/Cesium.Compiler.Tests.csproj
index aa500239..297bb799 100644
--- a/Cesium.Compiler.Tests/Cesium.Compiler.Tests.csproj
+++ b/Cesium.Compiler.Tests/Cesium.Compiler.Tests.csproj
@@ -9,13 +9,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Cesium.Compiler/Cesium.Compiler.csproj b/Cesium.Compiler/Cesium.Compiler.csproj
index e4e6560d..9b78d196 100644
--- a/Cesium.Compiler/Cesium.Compiler.csproj
+++ b/Cesium.Compiler/Cesium.Compiler.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/Cesium.Compiler/Compilation.cs b/Cesium.Compiler/Compilation.cs
index 865db0a5..fb1084d8 100644
--- a/Cesium.Compiler/Compilation.cs
+++ b/Cesium.Compiler/Compilation.cs
@@ -63,7 +63,7 @@ private static Task Preprocess(string compilationSourcePath, string comp
.Concat(compilationOptions.AdditionalIncludeDirectories)
.ToImmutableArray();
var includeContext = new FileSystemIncludeContext(stdLibDirectory, includeDirectories);
- var preprocessorLexer = new CPreprocessorLexer(reader);
+ var preprocessorLexer = new CPreprocessorLexer(new Yoakke.SynKit.Text.SourceFile(compilationSourcePath, reader));
var definesContext = new InMemoryDefinesContext();
var outOfFileRange = new Yoakke.SynKit.Text.Range();
foreach (var define in compilationOptions.DefineConstants)
@@ -73,7 +73,7 @@ private static Task Preprocess(string compilationSourcePath, string comp
macroDefinition: new ObjectMacroDefinition(define),
replacement: new IToken[]
{
- new Token(outOfFileRange, "1", CPreprocessorTokenType.PreprocessingToken)
+ new Token(outOfFileRange, new(), "1", CPreprocessorTokenType.PreprocessingToken)
});
}
diff --git a/Cesium.Core/Cesium.Core.csproj b/Cesium.Core/Cesium.Core.csproj
index c59f7450..254a972e 100644
--- a/Cesium.Core/Cesium.Core.csproj
+++ b/Cesium.Core/Cesium.Core.csproj
@@ -7,7 +7,7 @@
-
+
diff --git a/Cesium.IntegrationTests/Cesium.IntegrationTests.csproj b/Cesium.IntegrationTests/Cesium.IntegrationTests.csproj
index 3f9fdf69..cc15ccec 100644
--- a/Cesium.IntegrationTests/Cesium.IntegrationTests.csproj
+++ b/Cesium.IntegrationTests/Cesium.IntegrationTests.csproj
@@ -12,13 +12,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/Cesium.IntegrationTests/preprocessor.c b/Cesium.IntegrationTests/preprocessor.c
index 81e262a1..f6de527e 100644
--- a/Cesium.IntegrationTests/preprocessor.c
+++ b/Cesium.IntegrationTests/preprocessor.c
@@ -2,6 +2,9 @@
#define Y
#define Z 0
+#define SINGLE_HASH_(x) # x
+#define SINGLE_HASH(x) SINGLE_HASH_(x)
+
int main(void)
{
printf("__TEST_DEFINE %i", __TEST_DEFINE);
@@ -12,5 +15,8 @@ int main(void)
printf("This does exists");
#endif
+ printf(SINGLE_HASH(x));
+ printf("line: %d file: %s ", __LINE__, __FILE__);
+
return 42;
}
diff --git a/Cesium.Parser.Tests/Cesium.Parser.Tests.csproj b/Cesium.Parser.Tests/Cesium.Parser.Tests.csproj
index e9500537..2f9e2903 100644
--- a/Cesium.Parser.Tests/Cesium.Parser.Tests.csproj
+++ b/Cesium.Parser.Tests/Cesium.Parser.Tests.csproj
@@ -8,14 +8,14 @@
-
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Cesium.Parser.Tests/ParserTests/TokenExtensionsTests.cs b/Cesium.Parser.Tests/ParserTests/TokenExtensionsTests.cs
index bc8ff061..59049bed 100644
--- a/Cesium.Parser.Tests/ParserTests/TokenExtensionsTests.cs
+++ b/Cesium.Parser.Tests/ParserTests/TokenExtensionsTests.cs
@@ -17,7 +17,7 @@ public class TokenExtensionsTests
[InlineData("\"\\x\"", "\\x")]
public void Test(string tokenText, string expected)
{
- var token = new Token(new Yoakke.SynKit.Text.Range(), tokenText, CTokenType.StringLiteral);
+ var token = new Token(new Yoakke.SynKit.Text.Range(), new Yoakke.SynKit.Text.Location(), tokenText, CTokenType.StringLiteral);
var actual = token.UnwrapStringLiteral();
diff --git a/Cesium.Parser.Tests/PreprocessorTests/PreprocessorTests.cs b/Cesium.Parser.Tests/PreprocessorTests/PreprocessorTests.cs
index a8a712ed..59ea86a4 100644
--- a/Cesium.Parser.Tests/PreprocessorTests/PreprocessorTests.cs
+++ b/Cesium.Parser.Tests/PreprocessorTests/PreprocessorTests.cs
@@ -15,10 +15,11 @@ private static async Task DoTest(string source, Dictionary? stan
private static async Task DoPreprocess(string source, Dictionary? standardHeaders = null, Dictionary>>? defines = null)
{
- var lexer = new CPreprocessorLexer(source);
+ var filePath = "c:\\a\\b\\c.c";
+ var lexer = new CPreprocessorLexer(filePath, source);
var includeContext = new IncludeContextMock(standardHeaders ?? new Dictionary());
var definesContext = new InMemoryDefinesContext(defines ?? new Dictionary>>());
- var preprocessor = new CPreprocessor(source, lexer, includeContext, definesContext);
+ var preprocessor = new CPreprocessor(filePath, lexer, includeContext, definesContext);
var result = await preprocessor.ProcessSource();
return result;
}
@@ -417,5 +418,26 @@ public Task UnrollNestedDefines() => DoTest(
#define nested_foo foo
#define _(code) nested_foo(code)
_(""test"")
+");
+
+ [Fact]
+ public Task DoubleHashOperator() => DoTest(
+@"
+#define HASHME(x) L ## x
+#define NOHASHME(x) L x
+HASHME(""test"")
+NOHASHME(""test"")
+");
+
+ [Fact]
+ public Task LineDefine() => DoTest(
+@"
+int x = __LINE__;
+");
+
+ [Fact]
+ public Task FileDefine() => DoTest(
+@"
+char* x = __FILE__;
");
}
diff --git a/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.DoubleHashOperator.verified.txt b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.DoubleHashOperator.verified.txt
new file mode 100644
index 00000000..9f4cc70e
--- /dev/null
+++ b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.DoubleHashOperator.verified.txt
@@ -0,0 +1,3 @@
+
+L"test"
+L "test"
diff --git a/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.FileDefine.verified.txt b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.FileDefine.verified.txt
new file mode 100644
index 00000000..e8a7e610
--- /dev/null
+++ b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.FileDefine.verified.txt
@@ -0,0 +1,2 @@
+
+char* x = "c:\\a\\b\\c.c";
diff --git a/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.LineDefine.verified.txt b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.LineDefine.verified.txt
new file mode 100644
index 00000000..8f56463c
--- /dev/null
+++ b/Cesium.Parser.Tests/PreprocessorTests/verified/PreprocessorTests.LineDefine.verified.txt
@@ -0,0 +1,2 @@
+
+int x = 2;
diff --git a/Cesium.Parser/CParser.cs b/Cesium.Parser/CParser.cs
index e484fab3..f4c492a7 100644
--- a/Cesium.Parser/CParser.cs
+++ b/Cesium.Parser/CParser.cs
@@ -1031,5 +1031,5 @@ private static ImmutableArray MakeDeclarationList(
}
private static ICToken MergeTokens(ICToken token1, ICToken token2) =>
- new Token(new Range(token1.Range, token2.Range), token1.Text + token2.Text, token2.Kind);
+ new Token(new Range(token1.Range, token2.Range), token1.Location, token1.Text + token2.Text, token2.Kind);
}
diff --git a/Cesium.Parser/Cesium.Parser.csproj b/Cesium.Parser/Cesium.Parser.csproj
index 54a1419c..cade06f2 100644
--- a/Cesium.Parser/Cesium.Parser.csproj
+++ b/Cesium.Parser/Cesium.Parser.csproj
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/Cesium.Preprocessor/CPreprocessor.cs b/Cesium.Preprocessor/CPreprocessor.cs
index 47c2dfd9..f6f1efec 100644
--- a/Cesium.Preprocessor/CPreprocessor.cs
+++ b/Cesium.Preprocessor/CPreprocessor.cs
@@ -1,9 +1,11 @@
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;
using Cesium.Core;
using Yoakke.Streams;
using Yoakke.SynKit.Lexer;
+using Yoakke.SynKit.Text;
using static Cesium.Preprocessor.CPreprocessorTokenType;
using Range = Yoakke.SynKit.Text.Range;
@@ -180,7 +182,7 @@ private IEnumerable> ReplaceMacro(IToken(token.Range, ",", CPreprocessorTokenType.Separator));
+ va_args.Add(new Token(token.Range, token.Location, ",", CPreprocessorTokenType.Separator));
}
}
else
@@ -242,9 +244,29 @@ private IEnumerable> ReplaceMacro(IToken(token.Range, token.Location, "\"" + token.Location.File?.Path.Replace("\\", "\\\\") + "\"", PreprocessingToken);
+ yield break;
+ }
+ if (token.Text == "__LINE__")
+ {
+ var line = token.Location.Range.Start.Line + 1;
+ yield return new Token(
+ token.Range,
+ token.Location,
+ line.ToString(),
+ PreprocessingToken);
+ yield break;
+ }
+ }
bool performStringReplace = false;
+ bool includeNextVerbatim = false;
var nestedStream = new EnumerableStream>(tokenReplacement);
+ var pendingWhitespaces = new List>();
while (!nestedStream.IsEnd)
{
var subToken = nestedStream.Consume();
@@ -254,40 +276,78 @@ private IEnumerable> ReplaceMacro(IToken(token.Range, token.Location, parameterToken.Text, parameterToken.Kind);
+ }
+ }
+ else if (performStringReplace)
{
var stringValue = string.Join(string.Empty, parameterTokens.Select(t => t.Text));
var escapedStringValue = stringValue.Replace("\\", "\\\\")
.Replace("\"", "\\\"")
;
escapedStringValue = $"\"{escapedStringValue}\"";
- yield return new Token(token.Range, escapedStringValue, token.Kind);
+ yield return new Token(token.Range, token.Location, escapedStringValue, token.Kind);
performStringReplace = false;
}
else
{
foreach (var parameterToken in parameterTokens)
{
- yield return new Token(token.Range, parameterToken.Text, parameterToken.Kind);
+ yield return new Token(token.Range, token.Location, parameterToken.Text, parameterToken.Kind);
}
}
}
else
{
- foreach (var nestedT in ReplaceMacro(subToken, nestedStream))
+ if (includeNextVerbatim)
{
- yield return nestedT;
-
+ yield return subToken;
}
+ else
+ {
+ foreach (var nestedT in ReplaceMacro(subToken, nestedStream))
+ {
+ yield return nestedT;
+ }
+ }
+ }
+
+ includeNextVerbatim = false;
+ }
+ else if (subToken is { Kind: WhiteSpace })
+ {
+ if (!includeNextVerbatim)
+ {
+ pendingWhitespaces.Add(new Token(token.Range, token.Location, subToken.Text, subToken.Kind));
}
}
else
{
- yield return new Token(token.Range, subToken.Text, subToken.Kind);
+ yield return new Token(token.Range, token.Location, subToken.Text, subToken.Kind);
}
}
}
@@ -521,7 +581,7 @@ IEnumerable> ConsumeLineAll()
private bool EvaluateExpression(IList> expressionTokens)
{
var stream = new EnumerableStream>(
- expressionTokens.Union(new[] { new Token(new Range(), "", End) })).ToBuffered();
+ expressionTokens.Union(new[] { new Token(new Range(), new Yoakke.SynKit.Text.Location(), "", End) })).ToBuffered();
var p = new CPreprocessorExpressionParser(stream);
var expression = p.ParseExpression();
if (expression.IsError)
@@ -537,7 +597,7 @@ private bool EvaluateExpression(IList> expression
private static (MacroDefinition, List>) EvaluateMacroDefinition(IEnumerable> expressionTokens)
{
var stream = new EnumerableStream>(
- expressionTokens.Union(new[] { new Token(new Range(), "", End) })).ToBuffered();
+ expressionTokens.Union(new[] { new Token(new Range(), new Yoakke.SynKit.Text.Location(), "", End) })).ToBuffered();
var p = new CPreprocessorMacroDefinitionParser(stream);
var macroDefinition = p.ParseMacro();
var macroReplacement = new List>();
@@ -567,13 +627,13 @@ private static (MacroDefinition, List>) EvaluateM
private async IAsyncEnumerable> ProcessInclude(string compilationUnitPath, TextReader fileReader)
{
- var lexer = new CPreprocessorLexer(fileReader);
+ var lexer = new CPreprocessorLexer(new SourceFile(compilationUnitPath, fileReader));
var subProcessor = new CPreprocessor(compilationUnitPath, lexer, IncludeContext, MacroContext);
await foreach (var item in subProcessor.GetPreprocessingResults())
{
yield return item;
}
- yield return new Token(new Range(), "\n", NewLine);
+ yield return new Token(new Range(), new Yoakke.SynKit.Text.Location(), "\n", NewLine);
}
}
diff --git a/Cesium.Preprocessor/Cesium.Preprocessor.csproj b/Cesium.Preprocessor/Cesium.Preprocessor.csproj
index 33e1ceff..3365ce43 100644
--- a/Cesium.Preprocessor/Cesium.Preprocessor.csproj
+++ b/Cesium.Preprocessor/Cesium.Preprocessor.csproj
@@ -6,10 +6,10 @@
-
-
-
-
+
+
+
+
diff --git a/Cesium.Preprocessor/InMemoryDefinesContext.cs b/Cesium.Preprocessor/InMemoryDefinesContext.cs
index e5d77798..35abc6a0 100644
--- a/Cesium.Preprocessor/InMemoryDefinesContext.cs
+++ b/Cesium.Preprocessor/InMemoryDefinesContext.cs
@@ -13,7 +13,17 @@ public InMemoryDefinesContext(IReadOnlyDictionary>>()
: new Dictionary>>(initialDefines);
- _defineMacros = new();
+ _defineMacros = new();
+
+ this.DefineMacro(
+ "__LINE__",
+ macroDefinition: new ObjectMacroDefinition("__LINE__"),
+ replacement: new IToken[0]);
+
+ this.DefineMacro(
+ "__FILE__",
+ macroDefinition: new ObjectMacroDefinition("__FILE__"),
+ replacement: new IToken[0]);
}
public void DefineMacro(string macro, MacroDefinition macroDefinition, IList> replacement)
diff --git a/Cesium.Runtime.Tests/Cesium.Runtime.Tests.csproj b/Cesium.Runtime.Tests/Cesium.Runtime.Tests.csproj
index 53dd9ac5..17108c41 100644
--- a/Cesium.Runtime.Tests/Cesium.Runtime.Tests.csproj
+++ b/Cesium.Runtime.Tests/Cesium.Runtime.Tests.csproj
@@ -10,13 +10,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Cesium.TestFramework.Tests/Cesium.TestFramework.Tests.csproj b/Cesium.TestFramework.Tests/Cesium.TestFramework.Tests.csproj
index 9a17f158..33440b6f 100644
--- a/Cesium.TestFramework.Tests/Cesium.TestFramework.Tests.csproj
+++ b/Cesium.TestFramework.Tests/Cesium.TestFramework.Tests.csproj
@@ -10,13 +10,13 @@
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/Cesium.TestFramework/Cesium.TestFramework.csproj b/Cesium.TestFramework/Cesium.TestFramework.csproj
index 1d34a677..316c9bc2 100644
--- a/Cesium.TestFramework/Cesium.TestFramework.csproj
+++ b/Cesium.TestFramework/Cesium.TestFramework.csproj
@@ -6,11 +6,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/Cesium.sln b/Cesium.sln
index 59817627..aabd2baf 100644
--- a/Cesium.sln
+++ b/Cesium.sln
@@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
after.Cesium.sln.targets = after.Cesium.sln.targets
CONTRIBUTING.md = CONTRIBUTING.md
Directory.Build.props = Directory.Build.props
+ Directory.Packages.props = Directory.Packages.props
README.md = README.md
EndProjectSection
EndProject
diff --git a/Directory.Packages.props b/Directory.Packages.props
new file mode 100644
index 00000000..847c9879
--- /dev/null
+++ b/Directory.Packages.props
@@ -0,0 +1,24 @@
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+