Upload source code of tools

This commit is contained in:
vczh
2023-01-21 04:03:12 -08:00
parent 6c5ec673e1
commit ac23950f3b
23 changed files with 4021 additions and 0 deletions
+3
View File
@@ -1,6 +1,9 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
#Tools
Tools/*.exe
#Vczh Libraries
*.xml.log/
+202
View File
@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{EFF0F387-7C0A-46C5-A544-62A24A6BC978}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CodePack</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\Vlpp.cpp" />
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppReflection.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppRegex.cpp" />
<ClCompile Include="Codepack_CategorizeCodeFiles.cpp" />
<ClCompile Include="Codepack_Combine.cpp" />
<ClCompile Include="Codepack_GetFiles.cpp" />
<ClCompile Include="Codepack_GetIncludeFiles.cpp" />
<ClCompile Include="Main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h" />
<ClInclude Include="..\..\..\Import\VlppGlrParser.h" />
<ClInclude Include="..\..\..\Import\VlppOS.h" />
<ClInclude Include="..\..\..\Import\VlppReflection.h" />
<ClInclude Include="..\..\..\Import\VlppRegex.h" />
<ClInclude Include="Codepack.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Import">
<UniqueIdentifier>{df74faf6-c4d7-49f9-a69c-39430c70787e}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppReflection.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppRegex.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="Codepack_GetFiles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Codepack_CategorizeCodeFiles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Codepack_GetIncludeFiles.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Codepack_Combine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp">
<Filter>Import</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppOS.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppReflection.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppRegex.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="Codepack.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppGlrParser.h">
<Filter>Import</Filter>
</ClInclude>
</ItemGroup>
</Project>
+66
View File
@@ -0,0 +1,66 @@
#include <VlppGlrParser.h>
using namespace vl;
using namespace vl::collections;
using namespace vl::filesystem;
using namespace vl::glr;
using namespace vl::glr::xml;
using namespace vl::regex;
using namespace vl::console;
using namespace vl::stream;
extern Regex regexInclude;
extern Regex regexSystemInclude;
extern Regex regexInstruction;
extern const vint include_path;
extern const vint systemInclude_path;
extern const vint instruction_name;
extern const vint instruction_param;
inline WString ReadFile(const FilePath& path)
{
WString text;
BomEncoder::Encoding encoding;
bool containsBom;
File(path).ReadAllTextWithEncodingTesting(text, encoding, containsBom);
return text;
}
extern LazyList<FilePath> GetCppFiles(
const FilePath& folder,
List<WString>& exceptions
);
extern LazyList<FilePath> GetHeaderFiles(
const FilePath& folder,
List<WString>& exceptions
);
extern void CategorizeCodeFiles(
Ptr<XmlDocument> config,
LazyList<FilePath> files,
Group<WString, FilePath>& categorizedFiles,
Dictionary<FilePath, WString>& inputFileToCategories
);
extern LazyList<FilePath> GetIncludedFiles(
const FilePath& codeFile,
const Dictionary<WString, FilePath>& skippedImportFiles,
Dictionary<FilePath, LazyList<FilePath>>& cachedFileToIncludes,
Group<FilePath, Tuple<WString, FilePath>>& conditionOns,
Group<FilePath, Tuple<WString, FilePath>>& conditionOffs
);
extern void Combine(
const Dictionary<FilePath, WString>& inputFileToOutputFiles,
const Dictionary<WString, FilePath>& skippedImportFiles,
Dictionary<FilePath, LazyList<FilePath>>& cachedFileToIncludes,
Group<FilePath, Tuple<WString, FilePath>>& conditionOns,
Group<FilePath, Tuple<WString, FilePath>>& conditionOffs,
const List<FilePath>& files,
FilePath outputFilePath,
FilePath outputIncludeFilePath,
SortedList<WString>& systemIncludes,
LazyList<WString> externalIncludes
);
@@ -0,0 +1,63 @@
#include "Codepack.h"
void CategorizeCodeFiles(
Ptr<XmlDocument> config,
LazyList<FilePath> files,
Group<WString, FilePath>& categorizedFiles,
Dictionary<FilePath, WString>& inputFileToCategories
)
{
for (auto e : XmlGetElements(XmlGetElement(config->rootElement, L"categories"), L"category"))
{
auto name = XmlGetAttribute(e, L"name")->value.value;
auto pattern = wupper(XmlGetAttribute(e, L"pattern")->value.value);
List<WString> exceptions;
CopyFrom(
exceptions,
XmlGetElements(e,L"except")
.Select([](const Ptr<XmlElement> x)
{
return XmlGetAttribute(x, L"pattern")->value.value;
})
);
List<FilePath> filterFiles;
CopyFrom(
filterFiles,
From(files).Where([&](const FilePath& f)
{
auto path = f.GetFullPath();
return INVLOC.FindFirst(path, pattern, Locale::IgnoreCase).key != -1
&& From(exceptions).All([&](const WString& ex)
{
return INVLOC.FindFirst(path, ex, Locale::IgnoreCase).key == -1;
});
})
);
for (auto file : filterFiles)
{
if (!categorizedFiles.Contains(name, file))
{
categorizedFiles.Add(name, file);
inputFileToCategories.Add(file, name);
}
}
}
for (auto a : categorizedFiles.Keys())
{
for (auto b : categorizedFiles.Keys())
{
if (a != b)
{
const auto& as = categorizedFiles.Get(a);
const auto& bs = categorizedFiles.Get(b);
List<FilePath> cs;
CopyFrom(cs, From(as).Intersect(bs));
CHECK_ERROR(From(cs).IsEmpty(), L"A file should not appear in multiple categories.");
}
}
}
}
@@ -0,0 +1,214 @@
#include "Codepack.h"
FilePath GetCommonFolder(
const List<FilePath>& paths
)
{
auto folder = paths[0].GetFolder();
while (true)
{
if (From(paths).All([&](const FilePath& path)
{
return INVLOC.StartsWith(path.GetFullPath(), folder.GetFullPath() + WString::FromChar(folder.Delimiter), Locale::IgnoreCase);
}))
{
return folder;
}
folder = folder.GetFolder();
}
CHECK_FAIL(L"Cannot process files across multiple drives.");
}
void CollectConditions(
Group<WString, WString>& categorizedConditions,
Group<FilePath, Tuple<WString, FilePath>>& conditions,
const FilePath& file,
const Dictionary<FilePath, WString>& inputFileToOutputFiles
)
{
vint index = conditions.Keys().IndexOf(file);
if (index != -1)
{
const auto& tuples = conditions.GetByIndex(index);
for (vint i = 0; i < tuples.Count(); i++)
{
auto condition = tuples[i].f0;
auto includeFile = inputFileToOutputFiles[tuples[i].f1];
if (!categorizedConditions.Contains(condition, includeFile))
{
categorizedConditions.Add(condition, includeFile);
}
}
}
}
void CombineWriteHeader(
List<WString>& lines,
const Dictionary<FilePath, WString>& inputFileToOutputFiles,
Group<FilePath, Tuple<WString, FilePath>>& conditionOns,
Group<FilePath, Tuple<WString, FilePath>>& conditionOffs,
const List<FilePath>& files,
LazyList<WString> externalIncludes
)
{
lines.Add(L"/***********************************************************************");
lines.Add(L"THIS FILE IS AUTOMATICALLY GENERATED. DO NOT MODIFY");
lines.Add(L"DEVELOPER: Zihan Chen(vczh)");
lines.Add(L"***********************************************************************/");
for (auto path : externalIncludes)
{
lines.Add(L"#include \"" + path + L"\"");
}
{
Group<WString, WString> categorizedConditionOns, categorizedConditionOffs;
for (auto file : files)
{
CollectConditions(categorizedConditionOns, conditionOns, file, inputFileToOutputFiles);
CollectConditions(categorizedConditionOffs, conditionOffs, file, inputFileToOutputFiles);
}
for (vint i = 0; i < categorizedConditionOns.Count(); i++)
{
lines.Add(L"#ifdef " + categorizedConditionOns.Keys()[i]);
const auto& onFiles = categorizedConditionOns.GetByIndex(i);
for (auto onFile : onFiles)
{
lines.Add(L"#include \"" + inputFileToOutputFiles[onFile] + L"\"");
}
lines.Add(L"#endif");
}
for (vint i = 0; i < categorizedConditionOffs.Count(); i++)
{
lines.Add(L"#ifndef " + categorizedConditionOffs.Keys()[i]);
const auto& offFiles = categorizedConditionOffs.GetByIndex(i);
for (auto offFile : offFiles)
{
lines.Add(L"#include \"" + offFile + L".h\"");
}
lines.Add(L"#endif");
}
}
}
void Combine(
const Dictionary<FilePath, WString>& inputFileToOutputFiles, // (in)
const Dictionary<WString, FilePath>& skippedImportFiles, // (in)
Dictionary<FilePath, LazyList<FilePath>>& cachedFileToIncludes, // (cache)
Group<FilePath, Tuple<WString, FilePath>>& conditionOns, // (out)
Group<FilePath, Tuple<WString, FilePath>>& conditionOffs, // (out)
const List<FilePath>& files, // (in)
FilePath outputFilePath, //
FilePath outputIncludeFilePath, //
SortedList<WString>& systemIncludes, //
LazyList<WString> externalIncludes //
)
{
auto workingDir = outputFilePath.GetFolder();
List<FilePath> sortedFiles;
{
PartialOrderingProcessor popFiles;
Group<FilePath, FilePath> depGroup;
for (auto file : files)
{
for (auto dep : GetIncludedFiles(file, skippedImportFiles, cachedFileToIncludes, conditionOns, conditionOffs))
{
if (files.Contains(dep))
{
depGroup.Add(file, dep);
}
}
}
popFiles.InitWithGroup(files, depGroup);
popFiles.Sort();
bool needExit = false;
for (vint i = 0; i < popFiles.components.Count(); i++)
{
auto& component = popFiles.components[i];
sortedFiles.Add(files[component.firstNode[0]]);
if (component.nodeCount > 1)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(
L"Error: Cycle dependency found in categories: "
+ From(component.firstNode, component.firstNode + component.nodeCount)
.Select([&](vint nodeIndex) { return L"\r\n" + files[nodeIndex].GetFullPath(); })
.Aggregate([](const WString& a, const WString& b) {return a + b; })
+ L"\r\n.");
Console::SetColor(true, true, true, false);
needExit = true;
}
}
CHECK_ERROR(!needExit, L"Cycle dependency is not allowed");
}
{
List<WString> lines;
CombineWriteHeader(lines, inputFileToOutputFiles, conditionOns, conditionOffs, files, externalIncludes);
{
auto prefix = GetCommonFolder(files);
for (auto file : From(sortedFiles).Intersect(files))
{
lines.Add(L"");
lines.Add(L"/***********************************************************************");
lines.Add(wupper(prefix.GetRelativePathFor(file)));
lines.Add(L"***********************************************************************/");
StringReader reader(ReadFile(file));
bool skip = false;
while (!reader.IsEnd())
{
auto line = reader.ReadLine();
Ptr<RegexMatch> match;
if ((match = regexInstruction.MatchHead(line)))
{
auto name = match->Groups()[instruction_name][0].Value();
if (name == L"BeginIgnore")
{
skip = true;
}
else if (name == L"EndIgnore")
{
skip = false;
}
}
else if (!skip)
{
if ((match = regexSystemInclude.MatchHead(line)))
{
auto systemFile = match->Groups()[systemInclude_path][0].Value();
if (skippedImportFiles.Keys().Contains(systemFile)) continue;
if (systemIncludes.Contains(systemFile)) continue;
systemIncludes.Add(systemFile);
lines.Add(line);
}
else if (!regexInclude.MatchHead(line))
{
lines.Add(line);
}
}
}
}
}
File(outputFilePath).WriteAllLines(lines, true, BomEncoder::Utf8);
}
{
List<WString> lines;
CombineWriteHeader(lines, inputFileToOutputFiles, conditionOns, conditionOffs, files, externalIncludes);
lines.Add(L"");
{
auto prefix = outputIncludeFilePath.GetFolder();
for (auto file : From(sortedFiles).Intersect(files))
{
lines.Add(L"#include \"" + prefix.GetRelativePathFor(file) + L"\"");
}
}
File(outputIncludeFilePath).WriteAllLines(lines, true, BomEncoder::Utf8);
}
Console::SetColor(false, true, false, true);
Console::WriteLine(L"Succeeded to write: " + outputFilePath.GetFullPath());
Console::SetColor(true, true, true, false);
}
@@ -0,0 +1,54 @@
#include "Codepack.h"
LazyList<FilePath> SearchFiles(
const Folder& folder,
const WString& extension,
List<WString>& exceptions
)
{
auto files = Ptr(new List<File>);
auto folders = Ptr(new List<Folder>);
folder.GetFiles(*files.Obj());
folder.GetFolders(*folders.Obj());
return LazyList<File>(files)
.Select([](const File& file)
{
return file.GetFilePath();
})
.Where([&](const FilePath& filePath)
{
return From(exceptions)
.All([&](const WString& except)
{
return INVLOC.FindFirst(filePath.GetFullPath(), except, Locale::IgnoreCase).key == -1;
});
})
.Where([=](const FilePath& path)
{
return INVLOC.EndsWith(path.GetName(), extension, Locale::IgnoreCase);
})
.Concat(
LazyList<Folder>(folders)
.SelectMany([&](const Folder& folder)
{
return SearchFiles(folder, extension, exceptions);
})
);
}
LazyList<FilePath> GetCppFiles(
const FilePath& folder,
List<WString>& exceptions
)
{
return SearchFiles(folder, L".cpp", exceptions);
}
LazyList<FilePath> GetHeaderFiles(
const FilePath& folder,
List<WString>& exceptions
)
{
return SearchFiles(folder, L".h", exceptions);
}
@@ -0,0 +1,130 @@
#include "Codepack.h"
Regex regexInclude(LR"/(^\s*#include\s*"(<path>[^"]+)"\s*$)/");
Regex regexSystemInclude(LR"/(^\s*#include\s*<(<path>[^"]+)>\s*$)/");
Regex regexInstruction(LR"/(^\s*\/\*\s*CodePack:(<name>\w+)\(((<param>[^,)]+)(,\s*(<param>[^,)]+))*)?\)\s*\*\/\s*$)/");
const vint include_path = regexInclude.CaptureNames().IndexOf(L"path");
const vint systemInclude_path = regexSystemInclude.CaptureNames().IndexOf(L"path");
const vint instruction_name = regexInstruction.CaptureNames().IndexOf(L"name");
const vint instruction_param = regexInstruction.CaptureNames().IndexOf(L"param");
LazyList<FilePath> GetIncludedFiles(
const FilePath& codeFile, // (in)
const Dictionary<WString, FilePath>& skippedImportFiles, // (in)
Dictionary<FilePath, LazyList<FilePath>>& cachedFileToIncludes, // (cache)
Group<FilePath, Tuple<WString, FilePath>>& conditionOns, // (out)
Group<FilePath, Tuple<WString, FilePath>>& conditionOffs // (out)
)
{
{
vint index = cachedFileToIncludes.Keys().IndexOf(codeFile);
if (index != -1)
{
return cachedFileToIncludes.Values()[index];
}
}
Console::SetColor(true, true, false, true);
Console::WriteLine(L"Scanning file: " + codeFile.GetFullPath());
Console::SetColor(true, true, true, false);
List<FilePath> includes;
StringReader reader(ReadFile(codeFile));
bool skip = false;
vint lineIndex = 0;
while (!reader.IsEnd())
{
lineIndex++;
auto line = reader.ReadLine();
Ptr<RegexMatch> match;
if ((match = regexInstruction.MatchHead(line)))
{
auto name = match->Groups()[instruction_name][0].Value();
const List<RegexString>* params = nullptr;
{
vint index = match->Groups().Keys().IndexOf(instruction_param);
if (index != -1)
{
params = &match->Groups().GetByIndex(index);
}
}
if (name == L"BeginIgnore")
{
if (params == nullptr)
{
skip = true;
continue;
}
}
else if (name == L"EndIgnore")
{
if (params == nullptr)
{
skip = false;
continue;
}
}
else if (name == L"ConditionOn")
{
if (params && params->Count() == 2)
{
conditionOns.Add(codeFile, { params->Get(0).Value(),codeFile.GetFolder() / params->Get(1).Value() });
continue;
}
}
else if (name == L"ConditionOff")
{
if (params && params->Count() == 2)
{
conditionOffs.Add(codeFile, { params->Get(0).Value(),codeFile.GetFolder() / params->Get(1).Value() });
continue;
}
}
Console::SetColor(true, false, false, true);
Console::WriteLine(L"Error: Unrecognizable CodePack instruction: \"" + line + L"\" in file: " + codeFile.GetFullPath() + L" (" + itow(lineIndex) + L")");
Console::SetColor(true, true, true, false);
}
else if ((match = regexInclude.MatchHead(line)))
{
if (!skip)
{
auto path = codeFile.GetFolder() / match->Groups()[include_path][0].Value();
if (!includes.Contains(path))
{
includes.Add(path);
}
}
}
else if ((match = regexSystemInclude.MatchHead(line)))
{
if (!skip)
{
auto systemFile = match->Groups()[systemInclude_path][0].Value();
vint index = skippedImportFiles.Keys().IndexOf(systemFile);
if (index != -1)
{
auto path = skippedImportFiles.Values()[index];
if (!includes.Contains(path))
{
includes.Add(path);
}
}
}
}
}
auto result = Ptr(new List<FilePath>);
CopyFrom(
*result.Obj(),
From(includes)
.Concat(From(includes).SelectMany([&](const FilePath& includedFile)
{
return GetIncludedFiles(includedFile, skippedImportFiles, cachedFileToIncludes, conditionOns, conditionOffs);
}))
.Distinct()
);
cachedFileToIncludes.Add(codeFile, result);
return result;
}
+298
View File
@@ -0,0 +1,298 @@
#include "Codepack.h"
int main(int argc, char* argv[])
{
Console::SetTitle(L"Vczh CodePack for C++");
if (argc != 2)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(L"CodePack.exe <config-xml>");
Console::SetColor(true, true, true, false);
return 0;
}
// load configuration
auto workingDir = FilePath(atow(argv[1])).GetFolder();
Ptr<XmlDocument> config;
{
Parser parser;
List<ParsingError> errors;
InstallDefaultErrorMessageGenerator(parser, errors);
auto text = ReadFile(atow(argv[1]));
config = XmlParseDocument(text, parser);
if (errors.Count() > 0)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(L"Failed to read the input XML file.");
for (auto error : errors)
{
Console::WriteLine(L"[row:" + itow(error.codeRange.start.row + 1) + L"][column:" + itow(error.codeRange.start.column + 1) + L"]: " + error.message);
}
Console::SetColor(true, true, true, false);
return 1;
}
}
Dictionary<WString, Tuple<WString, bool>> categorizedOutput; // category -> {output file, generate?}
{
// get configuration for all categories
CopyFrom(
categorizedOutput,
XmlGetElements(XmlGetElement(config->rootElement, L"output"), L"codepair")
.Select([&](Ptr<XmlElement> e)->Pair<WString, Tuple<WString, bool>>
{
return {
XmlGetAttribute(e, L"category")->value.value,
{
XmlGetAttribute(e, L"filename")->value.value,
XmlGetAttribute(e, L"generate")->value.value == L"true"
}
};
})
);
}
// collect code files
List<FilePath> unprocessedCppFiles; // all cpp files need to combine
List<FilePath> unprocessedHeaderFiles; // all header files need to combine
Dictionary<FilePath, LazyList<FilePath>> cachedFileToIncludes; // file -> directly/indirectly included files
Group<FilePath, Tuple<WString, FilePath>> conditionOns; // #ifdef -> files to include
Group<FilePath, Tuple<WString, FilePath>> conditionOffs; // #ifndef -> files to include
{
// get included folders
List<FilePath> folders;
CopyFrom(
folders,
XmlGetElements(XmlGetElement(config->rootElement,L"folders"), L"folder")
.Select([&](Ptr<XmlElement> e)
{
return workingDir / XmlGetAttribute(e, L"path")->value.value;
})
);
// get excluded folders
List<WString> exceptions;
CopyFrom(
exceptions,
XmlGetElements(XmlGetElement(config->rootElement,L"folders"), L"except")
.Select([&](Ptr<XmlElement> e)
{
return XmlGetAttribute(e, L"pattern")->value.value;
})
);
// enumerate all *.cpp files in specified folders
CopyFrom(
unprocessedCppFiles,
From(folders)
.SelectMany([&](const FilePath& folder) { return GetCppFiles(folder, exceptions); })
.Distinct()
);
// enumerate all *.h files in specified folders
CopyFrom(
unprocessedHeaderFiles,
From(folders)
.SelectMany([&](const FilePath& folder) { return GetHeaderFiles(folder, exceptions); })
.Distinct()
);
}
// categorize code files
Group<WString, FilePath> categorizedCppFiles; // category -> cpp files
Group<WString, FilePath> categorizedHeaderFiles; // category -> header files
Dictionary<FilePath, WString> inputFileToCategories; // input file -> category
{
// categorize all *.cpp and *.h files
CategorizeCodeFiles(config, unprocessedCppFiles, categorizedCppFiles, inputFileToCategories);
CategorizeCodeFiles(config, unprocessedHeaderFiles, categorizedHeaderFiles, inputFileToCategories);
}
// collect import files as system include
Dictionary<WString, FilePath> skippedImportFiles; // file name -> file path
for (vint i = 0; i < categorizedOutput.Count(); i++)
{
if (!categorizedOutput.Values()[i].f1)
{
auto category = categorizedOutput.Keys()[i];
for (auto skippedImportFile : categorizedHeaderFiles[category])
{
skippedImportFiles.Add(skippedImportFile.GetName(), skippedImportFile);
}
}
}
// check if there any *.h file is included without assigning a category
{
List<FilePath> headerFiles;
CopyFrom(
headerFiles,
From(unprocessedHeaderFiles)
.Concat(unprocessedCppFiles)
.SelectMany([&](const FilePath& includedFile)
{
return GetIncludedFiles(includedFile, skippedImportFiles, cachedFileToIncludes, conditionOns, conditionOffs);
})
.Concat(unprocessedHeaderFiles)
.Distinct()
.Except(unprocessedHeaderFiles)
);
if (headerFiles.Count() > 0)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(L"Error: The following files are not categorized.");
for (auto headerFile : headerFiles)
{
Console::WriteLine(headerFile.GetFullPath());
}
Console::SetColor(true, true, true, false);
CHECK_ERROR(true, L"All included files should be categorized");
}
}
// calculate category dependencies
PartialOrderingProcessor popCategories; // POP for category ordering
Group<vint, WString> componentToCategoryNames; // component index to category names
{
SortedList<FilePath> items;
Group<FilePath, FilePath> depGroup;
CopyFrom(items, From(unprocessedCppFiles).Concat(unprocessedHeaderFiles));
for (auto filePath : items)
{
for (auto includedFile : GetIncludedFiles(filePath, skippedImportFiles, cachedFileToIncludes, conditionOns, conditionOffs))
{
depGroup.Add(filePath, includedFile);
}
}
popCategories.InitWithSubClass(items, depGroup, inputFileToCategories);
popCategories.Sort();
for (vint i = 0; i < popCategories.components.Count(); i++)
{
auto& component = popCategories.components[i];
for (vint j = 0; j < component.nodeCount; j++)
{
auto& firstNode = popCategories.nodes[component.firstNode[j]];
auto firstFile = items[firstNode.firstSubClassItem[0]];
componentToCategoryNames.Add(i, inputFileToCategories[firstFile]);
}
}
bool needExit = false;
for (vint i = 0; i < componentToCategoryNames.Count(); i++)
{
const auto& cycleCategories = componentToCategoryNames.GetByIndex(i);
if (cycleCategories.Count() > 1)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(
L"Error: Cycle dependency found in categories: "
+ From(cycleCategories).Aggregate([](const WString& a, const WString& b) {return a + L", " + b; })
+ L".");
Console::SetColor(true, true, true, false);
needExit = true;
}
}
CHECK_ERROR(!needExit, L"Cycle dependency is not allowed");
}
Dictionary<FilePath, WString> inputFileToOutputFiles; // input file -> output file
{
for (vint i = 0; i < inputFileToCategories.Count(); i++)
{
auto key = inputFileToCategories.Keys()[i];
auto value = inputFileToCategories.Values()[i];
inputFileToOutputFiles.Add(key, categorizedOutput[value].f0);
}
}
// prepare output folder
auto outputFolder = workingDir / (XmlGetAttribute(XmlGetElement(config->rootElement, L"output"), L"path")->value.value);
auto outputIncludeOnlyFolder = outputFolder / L"IncludeOnly";
if (!Folder(outputIncludeOnlyFolder).Exists())
{
Folder(outputIncludeOnlyFolder).Create(true);
}
// generate categorized header dependencies
Dictionary<WString, LazyList<WString>> categorizedHeaderIncludes;
for (vint i = 0; i < popCategories.components.Count(); i++)
{
auto& component = popCategories.components[i];
auto categoryName = componentToCategoryNames[i][0];
categorizedHeaderIncludes.Add(
categoryName,
From(*popCategories.nodes[component.firstNode[0]].ins)
.Where([&](vint nodeIndex)
{
return nodeIndex != component.firstNode[0];
})
.Select([&](vint nodeIndex)
{
return categorizedOutput[componentToCategoryNames[popCategories.nodes[nodeIndex].component][0]].f0 + L".h";
})
);
}
// generate code pair header files
Dictionary<WString, Ptr<SortedList<WString>>> categorizedSystemIncludes;
for (vint i = 0; i < popCategories.components.Count(); i++)
{
auto categoryName = componentToCategoryNames[i][0];
auto outputPath = outputFolder / (categorizedOutput[categoryName].f0 + L".h");
auto outputIncludeOnlyPath = outputIncludeOnlyFolder / (categorizedOutput[categoryName].f0 + L".h");
auto systemIncludes = Ptr(new SortedList<WString>);
categorizedSystemIncludes.Add(categoryName, systemIncludes);
if (categorizedOutput[categoryName].f1)
{
vint headerIndex = categorizedHeaderFiles.Keys().IndexOf(categoryName);
if (headerIndex == -1) continue;
Combine(
inputFileToOutputFiles,
skippedImportFiles,
cachedFileToIncludes,
conditionOns,
conditionOffs,
categorizedHeaderFiles.GetByIndex(headerIndex),
outputPath,
outputIncludeOnlyPath,
*systemIncludes.Obj(),
categorizedHeaderIncludes[categoryName]
);
}
}
// generate code pair cpp files
for (vint i = 0; i < popCategories.components.Count(); i++)
{
auto categoryName = componentToCategoryNames[i][0];
if (categorizedOutput[categoryName].f1)
{
WString outputHeader[] = { categorizedOutput[categoryName].f0 + L".h" };
vint headerIndex = categorizedHeaderFiles.Keys().IndexOf(categoryName);
auto outputPath = outputFolder / (categorizedOutput[categoryName].f0 + L".cpp");
auto outputIncludeOnlyPath = outputIncludeOnlyFolder / (categorizedOutput[categoryName].f0 + L".cpp");
Combine(
inputFileToOutputFiles,
skippedImportFiles,
cachedFileToIncludes,
conditionOns,
conditionOffs,
categorizedCppFiles[categoryName],
outputPath,
outputIncludeOnlyPath,
*categorizedSystemIncludes[categoryName].Obj(),
(headerIndex == -1 ? categorizedHeaderIncludes[categoryName] : From(outputHeader))
);
}
}
return 0;
}
+195
View File
@@ -0,0 +1,195 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6D22025C-1EE0-413B-A212-E53C4F90B39A}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CppMerge</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppRegex.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="WfMergeCpp.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h" />
<ClInclude Include="..\..\..\Import\VlppOS.h" />
<ClInclude Include="..\..\..\Import\VlppRegex.h" />
<ClInclude Include="WfMergeCpp.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Import">
<UniqueIdentifier>{9abafbcb-8b2d-42bd-bf85-93e42b92b969}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppRegex.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="WfMergeCpp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppOS.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppRegex.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="WfMergeCpp.h">
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
+62
View File
@@ -0,0 +1,62 @@
#include "WfMergeCpp.h"
using namespace vl;
using namespace vl::console;
using namespace vl::filesystem;
using namespace vl::stream;
using namespace vl::workflow::cppcodegen;
#if defined VCZH_MSVC
int wmain(int argc, wchar_t* argv[])
#elif defined VCZH_GCC
int main(int argc, char* argv[])
#endif
{
Console::SetTitle(L"Vczh CodeMerge for C++");
if (argc != 4)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(L"Usage: CppMerge <x32-file> <x64-file> <output-file>");
Console::SetColor(true, true, true, false);
return 0;
}
#if defined VCZH_MSVC
FilePath file32 = argv[1];
FilePath file64 = argv[2];
FilePath fileOutput = argv[3];
#elif defined VCZH_GCC
FilePath file32 = atow(argv[1]);
FilePath file64 = atow(argv[2]);
FilePath fileOutput = atow(argv[3]);
#endif
try
{
auto code = MergeCppMultiPlatform(File(file32).ReadAllTextByBom(), File(file64).ReadAllTextByBom());
File file(fileOutput);
if (file.Exists())
{
code = MergeCppFileContent(file.ReadAllTextByBom(), code);
}
if (file.Exists())
{
auto originalCode = file.ReadAllTextByBom();
if (originalCode == code)
{
return 0;
}
}
file.WriteAllText(code, true, BomEncoder::Utf8);
return 0;
}
catch (const MergeCppMultiPlatformException& ex)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(ex.Message());
Console::SetColor(true, true, true, false);
throw;
}
}
+441
View File
@@ -0,0 +1,441 @@
#include "WfMergeCpp.h"
#include <VlppRegex.h>
namespace vl
{
namespace workflow
{
namespace cppcodegen
{
using namespace collections;
using namespace stream;
using namespace regex;
/***********************************************************************
MergeCpp
***********************************************************************/
WString RemoveSpacePrefix(const WString& s)
{
for (vint i = 0; i < s.Length(); i++)
{
if (s[i] != L' '&&s[i] != L'\t')
{
return s.Sub(i, s.Length() - i);
}
}
return WString::Empty;
}
const vint NORMAL = 0;
const vint WAIT_HEADER = 1;
const vint WAIT_OPEN = 2;
const vint WAIT_CLOSE = 3;
const vint USER_CONTENT = 4;
const vint UNUSED_USER_CONTENT = 5;
template<typename TCallback>
void ProcessCppContent(const WString& code, const TCallback& callback)
{
Regex regexUserContentBegin(L"/.*?(?/{)?///* USER_CONTENT_BEGIN/((<name>[^)]*?)/) /*//");
vint _name = regexUserContentBegin.CaptureNames().IndexOf(L"name");
vint state = NORMAL;
vint counter = 0;
WString previousContent;
StringReader reader(code);
while (!reader.IsEnd())
{
auto line = reader.ReadLine();
if (reader.IsEnd() && line == L"")
{
break;
}
if (line == L"// UNUSED_USER_CONTENT:")
{
state = UNUSED_USER_CONTENT;
}
if (state == UNUSED_USER_CONTENT)
{
callback(state, state, line, line);
}
else
{
auto content = RemoveSpacePrefix(line);
auto previousState = state;
switch (state)
{
case NORMAL:
if (auto match = regexUserContentBegin.MatchHead(content))
{
content = L"USERIMPL(/* " + match->Groups()[_name][0].Value() + L" */)";
if (match->Captures().Count() > 0)
{
content += previousContent;
}
state = USER_CONTENT;
}
else if (INVLOC.StartsWith(content, L"USERIMPL(",Locale::None))
{
state = WAIT_HEADER;
}
break;
case WAIT_HEADER:
state = WAIT_OPEN;
break;
case WAIT_OPEN:
if (INVLOC.StartsWith(content, L"{", Locale::None))
{
state = WAIT_CLOSE;
}
break;
case WAIT_CLOSE:
if (INVLOC.StartsWith(content, L"{", Locale::None))
{
counter++;
}
else if (INVLOC.StartsWith(content, L"}", Locale::None))
{
if (counter == 0)
{
state = NORMAL;
}
else
{
counter--;
}
}
break;
case USER_CONTENT:
if (INVLOC.EndsWith(content, L"/* USER_CONTENT_END() */", Locale::None))
{
state = NORMAL;
}
break;
}
callback(previousState, state, line, content);
}
previousContent = RemoveSpacePrefix(line);
}
}
template<typename TCallback>
void SplitCppContent(const WString& code, Dictionary<WString, WString>& userContents, Dictionary<WString, WString>& userContentsFull, const TCallback& callback)
{
WString name;
WString userImpl;
WString userImplFull;
ProcessCppContent(code, [&](vint previousState, vint state, const WString& line, const WString& content)
{
if (state == UNUSED_USER_CONTENT)
{
callback(line);
}
else
{
switch (previousState)
{
case NORMAL:
switch (state)
{
case WAIT_HEADER:
case USER_CONTENT:
name = content;
userImpl = L"";
userImplFull = L"";
break;
}
break;
case WAIT_HEADER:
name += content;
break;
case WAIT_CLOSE:
case USER_CONTENT:
switch (state)
{
case WAIT_CLOSE:
case USER_CONTENT:
userImpl += line + L"\r\n";
break;
case NORMAL:
userImplFull += L"//" + line + L"\r\n";
userContents.Add(name, userImpl);
userContentsFull.Add(name, userImplFull);
name = L"";
break;
}
break;
}
if (name != L"")
{
userImplFull += L"//" + line + L"\r\n";
}
}
});
}
MergeCppMultiPlatformException::MergeCppMultiPlatformException(vint _row32, vint _column32, vint _row64, vint _column64)
:Exception(L"The difference at "
L"x86 file(row:" + itow(_row32 + 1) + L", column:" + itow(_column32 + 1) + L") and "
L"x64 file(row:" + itow(_row64 + 1) + L", column:" + itow(_column64 + 1) + L") are not "
L"\"vint32_t\" and \"vint64_t\", "
L"\"vuint32_t\" and \"vuint64_t\", "
L"\"<number>\" and \"<number>L\", "
L"\"<number>\" and \"<number>UL\".")
, row32(_row32)
, column32(_column32)
, row64(_row64)
, column64(_column64)
{
}
void CountRowAndColumn(const wchar_t* start, const wchar_t* reading, vint& row, vint& column)
{
row = 0;
column = 0;
while (start < reading)
{
if (*start++ == L'\n')
{
row++;
column = 0;
}
else
{
column++;
}
}
}
WString MergeCppMultiPlatform(const WString& code32, const WString& code64)
{
static wchar_t stringCast32[] = L"static_cast<::vl::vint32_t>(";
const vint lengthCast32 = sizeof(stringCast32) / sizeof(*stringCast32) - 1;
static wchar_t stringCast64[] = L"static_cast<::vl::vint64_t>(";
const vint lengthCast64 = sizeof(stringCast64) / sizeof(*stringCast64) - 1;
return GenerateToStream([&](StreamWriter& writer)
{
const wchar_t* reading32 = code32.Buffer();
const wchar_t* reading64 = code64.Buffer();
const wchar_t* start32 = reading32;
const wchar_t* start64 = reading64;
while (true)
{
vint length = 0;
while (reading32[length] && reading64[length])
{
if (reading32[length] == reading64[length])
{
length++;
}
else
{
break;
}
}
writer.WriteString(reading32, length);
reading32 += length;
reading64 += length;
if (*reading32 == 0 && *reading64 == 0)
{
break;
}
#define IS_DIGIT(C) (L'0' <= C && C <= L'9')
if (reading32[0] == L'3' && reading32[1] == L'2' && reading64[0] == L'6' && reading64[1] == L'4')
{
if (length >= 4)
{
if (wcsncmp(reading32 - 4, L"vint32_t", 8) == 0 && wcsncmp(reading64 - 4, L"vint64_t", 8) == 0)
{
reading32 += 4;
reading64 += 4;
goto NEXT_ROUND;
}
}
if (length >= 5)
{
if (wcsncmp(reading32 - 5, L"vuint32_t", 9) == 0 && wcsncmp(reading64 - 5, L"vuint64_t", 9) == 0)
{
reading32 += 4;
reading64 += 4;
goto NEXT_ROUND;
}
}
}
else if (reading64[0] == L'L')
{
if (reading32[0] == reading64[1] && length >= 1)
{
if (IS_DIGIT(reading32[-1]) && !IS_DIGIT(reading32[0]))
{
if (IS_DIGIT(reading64[-1]) && !IS_DIGIT(reading64[1]))
{
reading64 += 1;
goto NEXT_ROUND;
}
}
}
}
else if (reading64[0] == L'U' && reading64[1] == L'L')
{
if (reading32[0] == reading64[2] && length >= 1)
{
if (IS_DIGIT(reading32[-1]) && !IS_DIGIT(reading32[0]))
{
if (IS_DIGIT(reading64[-1]) && !IS_DIGIT(reading64[2]))
{
reading64 += 2;
goto NEXT_ROUND;
}
}
}
}
else if (wcsncmp(reading32, stringCast32, lengthCast32) == 0 && IS_DIGIT(reading32[lengthCast32]) && IS_DIGIT(reading64[0]))
{
reading32 += lengthCast32;
vint digitCount = 0;
while (IS_DIGIT(reading32[digitCount])) digitCount++;
if (wcsncmp(reading32, reading64, digitCount) == 0 && reading64[digitCount] == L'L' && reading32[digitCount] == L')')
{
writer.WriteString(L"static_cast<::vl::vint>(");
writer.WriteString(WString::CopyFrom(reading32, digitCount));
writer.WriteChar(L')');
reading64 += digitCount + 1;
reading32 += digitCount + 1;
goto NEXT_ROUND;
}
}
else if (wcsncmp(reading64, stringCast64, lengthCast64) == 0 && IS_DIGIT(reading64[lengthCast64]) && IS_DIGIT(reading32[0]))
{
reading64 += lengthCast64;
vint digitCount = 0;
while (IS_DIGIT(reading64[digitCount])) digitCount++;
if (wcsncmp(reading64, reading32, digitCount) == 0 && reading64[digitCount] == L'L' && reading64[digitCount + 1] == L')')
{
writer.WriteString(L"static_cast<::vl::vint>(");
writer.WriteString(WString::CopyFrom(reading64, digitCount));
writer.WriteChar(L')');
reading64 += digitCount + 2;
reading32 += digitCount;
goto NEXT_ROUND;
}
}
{
vint row32 = 0;
vint column32 = 0;
vint row64 = 0;
vint column64 = 0;
CountRowAndColumn(start32, reading32, row32, column32);
CountRowAndColumn(start64, reading64, row64, column64);
throw MergeCppMultiPlatformException(row32, column32, row64, column64);
}
NEXT_ROUND:;
#undef IS_DIGIT
}
});
}
WString MergeCppFileContent(const WString& dst, const WString& src)
{
Dictionary<WString, WString> userContents, userContentsFull;
WString unusedUserContent = GenerateToStream([&](StreamWriter& writer)
{
SplitCppContent(dst, userContents, userContentsFull, [&](const WString& line)
{
writer.WriteLine(line);
});
});
WString processedUnusedUserContent = GenerateToStream([&](StreamWriter& writer)
{
StringReader reader(unusedUserContent);
while (!reader.IsEnd())
{
auto line = reader.ReadLine();
if (line != L"// UNUSED_USER_CONTENT:")
{
if (INVLOC.StartsWith(line, L"//", Locale::None))
{
line = line.Right(line.Length() - 2);
}
writer.WriteLine(line);
}
}
});
SplitCppContent(processedUnusedUserContent, userContents, userContentsFull, [&](const WString& line) {});
return GenerateToStream([&](StreamWriter& writer)
{
WString name;
WString userImpl;
ProcessCppContent(src, [&](vint previousState, vint state, const WString& line, const WString& content)
{
switch (previousState)
{
case NORMAL:
switch (state)
{
case WAIT_HEADER:
case USER_CONTENT:
name = content;
userImpl = L"";
break;
}
break;
case WAIT_HEADER:
name += content;
break;
case WAIT_CLOSE:
case USER_CONTENT:
switch (state)
{
case WAIT_CLOSE:
case USER_CONTENT:
userImpl += line + L"\r\n";
return;
case NORMAL:
{
vint index = userContents.Keys().IndexOf(name);
if (index == -1)
{
writer.WriteString(userImpl);
}
else
{
writer.WriteString(userContents.Values()[index]);
userContentsFull.Remove(name);
}
}
break;
}
break;
}
writer.WriteLine(line);
});
if (userContentsFull.Count() > 0)
{
writer.WriteLine(L"// UNUSED_USER_CONTENT:");
for (auto content : userContentsFull.Values())
{
writer.WriteString(content);
}
}
});
}
}
}
}
+42
View File
@@ -0,0 +1,42 @@
/***********************************************************************
Vczh Library++ 3.0
Developer: Zihan Chen(vczh)
Workflow::C++ Code Generator
Interfaces:
**********************************************************************/
#ifndef VCZH_WORKFLOW_CPP_WFMERGECPP
#define VCZH_WORKFLOW_CPP_WFMERGECPP
#include <VlppOS.h>
namespace vl
{
namespace workflow
{
namespace cppcodegen
{
/***********************************************************************
MergeCpp
***********************************************************************/
class MergeCppMultiPlatformException : public Exception
{
public:
vint row32;
vint column32;
vint row64;
vint column64;
MergeCppMultiPlatformException(vint _row32, vint _column32, vint _row64, vint _column64);
};
extern WString MergeCppMultiPlatform(const WString& code32, const WString& code64);
extern WString MergeCppFileContent(const WString& dst, const WString& src);
}
}
}
#endif
+61
View File
@@ -0,0 +1,61 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodePack", "CodePack\CodePack.vcxproj", "{EFF0F387-7C0A-46C5-A544-62A24A6BC978}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppMerge", "CppMerge\CppMerge.vcxproj", "{6D22025C-1EE0-413B-A212-E53C4F90B39A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GacGen", "GacGen\GacGen.vcxproj", "{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GlrParserGen", "GlrParserGen\GlrParserGen.vcxproj", "{F5A36ED2-78E7-4776-B1AB-63DE18376F30}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Debug|x64.ActiveCfg = Debug|x64
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Debug|x64.Build.0 = Debug|x64
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Debug|x86.ActiveCfg = Debug|Win32
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Debug|x86.Build.0 = Debug|Win32
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Release|x64.ActiveCfg = Release|x64
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Release|x64.Build.0 = Release|x64
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Release|x86.ActiveCfg = Release|Win32
{EFF0F387-7C0A-46C5-A544-62A24A6BC978}.Release|x86.Build.0 = Release|Win32
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Debug|x64.ActiveCfg = Debug|x64
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Debug|x64.Build.0 = Debug|x64
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Debug|x86.ActiveCfg = Debug|Win32
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Debug|x86.Build.0 = Debug|Win32
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Release|x64.ActiveCfg = Release|x64
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Release|x64.Build.0 = Release|x64
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Release|x86.ActiveCfg = Release|Win32
{6D22025C-1EE0-413B-A212-E53C4F90B39A}.Release|x86.Build.0 = Release|Win32
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Debug|x64.ActiveCfg = Debug|x64
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Debug|x64.Build.0 = Debug|x64
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Debug|x86.ActiveCfg = Debug|Win32
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Debug|x86.Build.0 = Debug|Win32
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Release|x64.ActiveCfg = Release|x64
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Release|x64.Build.0 = Release|x64
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Release|x86.ActiveCfg = Release|Win32
{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}.Release|x86.Build.0 = Release|Win32
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Debug|x64.ActiveCfg = Debug|x64
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Debug|x64.Build.0 = Debug|x64
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Debug|x86.ActiveCfg = Debug|Win32
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Debug|x86.Build.0 = Debug|Win32
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Release|x64.ActiveCfg = Release|x64
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Release|x64.Build.0 = Release|x64
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Release|x86.ActiveCfg = Release|Win32
{F5A36ED2-78E7-4776-B1AB-63DE18376F30}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CD9CCEAC-DFF5-43CF-9415-3F5D36CAB308}
EndGlobalSection
EndGlobal
+128
View File
@@ -0,0 +1,128 @@
#include "GacGen.h"
void PrintErrorMessage(const WString& message)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(message);
Console::SetColor(true, true, true, false);
}
void PrintSuccessMessage(const WString& message)
{
Console::SetColor(false, true, false, true);
Console::WriteLine(message);
Console::SetColor(true, true, true, false);
}
void PrintInformationMessage(const WString& message)
{
Console::SetColor(true, true, false, true);
Console::WriteLine(message);
Console::SetColor(true, true, true, false);
}
/***********************************************************************
CodegenConfig
***********************************************************************/
WString CodegenConfig::NormalizeFolder(const WString& folder)
{
if (folder.Length() == 0)
{
return L".\\";
}
else if (folder[folder.Length() - 1] != L'\\')
{
return folder + L"\\";
}
else
{
return folder;
}
}
bool CodegenConfig::LoadConfigString(Ptr<GuiResourceFolder> folder, const WString& path, WString& value, bool optional)
{
if (auto includeItem = folder->GetValueByPath(path).Cast<GuiTextData>())
{
value = includeItem->GetText();
return true;
}
else if (!optional)
{
PrintErrorMessage(L"error> Cannot find configuration in resource \"" + folder->GetName() + L"/" + path + L"\".");
return false;
}
else
{
return true;
}
}
bool CodegenConfig::LoadConfigString(Ptr<GuiResourceFolder> folder, const WString& path, List<WString>& value, bool optional)
{
WString text;
if (LoadConfigString(folder, path, text, optional))
{
SplitBySemicolon(text, value);
return true;
}
return false;
}
Ptr<CodegenConfig> CodegenConfig::LoadConfig(Ptr<GuiResource> resource, GuiResourceError::List& errors)
{
auto config = Ptr(new CodegenConfig);
config->resource = resource;
config->metadata = resource->GetMetadata();
if (auto folder = resource->GetFolderByPath(L"GacGenConfig/Cpp/"))
{
auto out = Ptr(new CodegenConfig::CppOutput);
LoadConfigString(folder, L"Resource", out->resource);
LoadConfigString(folder, L"Compressed", out->compressed);
LoadConfigString(folder, L"SourceFolder", out->sourceFolder, false);
LoadConfigString(folder, L"NormalInclude", out->normalIncludes, false);
LoadConfigString(folder, L"ReflectionInclude", out->reflectionIncludes);
LoadConfigString(folder, L"Name", out->name);
LoadConfigString(folder, L"CppResource", out->cppResource);
LoadConfigString(folder, L"CppCompressed", out->cppCompressed);
NormalizeFolder(out->sourceFolder);
if (out->name == L"")
{
out->name = L"GacUIApplication";
}
config->cppOutput = out;
}
if (auto folder = resource->GetFolderByPath(L"GacGenConfig/ResX86/"))
{
auto out = Ptr(new CodegenConfig::ResOutput);
LoadConfigString(folder, L"Resource", out->resource);
LoadConfigString(folder, L"Compressed", out->compressed);
LoadConfigString(folder, L"Assembly", out->assembly);
config->resOutputx32 = out;
}
if (auto folder = resource->GetFolderByPath(L"GacGenConfig/ResX64/"))
{
auto out = Ptr(new CodegenConfig::ResOutput);
LoadConfigString(folder, L"Resource", out->resource);
LoadConfigString(folder, L"Compressed", out->compressed);
LoadConfigString(folder, L"Assembly", out->assembly);
config->resOutputx64 = out;
}
if (auto item = resource->GetValueByPath(L"GacGenConfig/Metadata"))
{
if (auto xml = item.Cast<XmlDocument>())
{
resource->GetMetadata()->LoadFromXml(xml, { resource }, errors);
}
}
return config;
}
+69
View File
@@ -0,0 +1,69 @@
#ifndef VCZH_GACGEN
#define VCZH_GACGEN
#include "GacUICompiler.h"
using namespace vl;
using namespace vl::console;
using namespace vl::collections;
using namespace vl::regex;
using namespace vl::stream;
using namespace vl::reflection::description;
using namespace vl::glr::xml;
using namespace vl::workflow;
using namespace vl::workflow::analyzer;
using namespace vl::workflow::runtime;
using namespace vl::workflow::cppcodegen;
using namespace vl::presentation;
using namespace vl::presentation::templates;
/***********************************************************************
Console
***********************************************************************/
extern void PrintErrorMessage(const WString& message);
extern void PrintSuccessMessage(const WString& message);
extern void PrintInformationMessage(const WString& message);
/***********************************************************************
Object Model
***********************************************************************/
class CodegenConfig
{
public:
class ResOutput : public Object
{
public:
WString resource;
WString compressed;
WString assembly;
};
class CppOutput : public Object
{
public:
WString sourceFolder;
List<WString> normalIncludes;
List<WString> reflectionIncludes;
WString name;
WString resource;
WString compressed;
WString cppResource;
WString cppCompressed;
};
Ptr<GuiResource> resource;
Ptr<GuiResourceMetadata> metadata;
Ptr<CppOutput> cppOutput;
Ptr<ResOutput> resOutputx32;
Ptr<ResOutput> resOutputx64;
static WString NormalizeFolder(const WString& folder);
static bool LoadConfigString(Ptr<GuiResourceFolder> folder, const WString& path, WString& value, bool optional = true);
static bool LoadConfigString(Ptr<GuiResourceFolder> folder, const WString& path, List<WString>& value, bool optional = true);
static Ptr<CodegenConfig> LoadConfig(Ptr<GuiResource> resource, GuiResourceError::List& errors);
};
#endif
+239
View File
@@ -0,0 +1,239 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{07328A1E-E71E-4F90-9BD7-7F0FD7B73053}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>GacGen</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)Bin\</OutDir>
<TargetName>$(ProjectName)D</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(SolutionDir)Bin\</OutDir>
<TargetName>$(ProjectName)D</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)Bin\</OutDir>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)Bin\</OutDir>
<TargetName>$(ProjectName)</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>VCZH_DEBUG_METAONLY_REFLECTION;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import\;$(ProjectDir)..\..\..\Release\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>VCZH_DEBUG_METAONLY_REFLECTION;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import\;$(ProjectDir)..\..\..\Release\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>VCZH_DEBUG_METAONLY_REFLECTION;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import\;$(ProjectDir)..\..\..\Release\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>VCZH_DEBUG_METAONLY_REFLECTION;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\Import\;$(ProjectDir)..\..\..\Release\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\GacUI.h" />
<ClInclude Include="..\..\..\Import\GacUICompiler.h" />
<ClInclude Include="..\..\..\Import\GacUIReflection.h" />
<ClInclude Include="..\..\..\Import\Vlpp.h" />
<ClInclude Include="..\..\..\Import\VlppGlrParser.h" />
<ClInclude Include="..\..\..\Import\VlppOS.h" />
<ClInclude Include="..\..\..\Import\VlppParser.h" />
<ClInclude Include="..\..\..\Import\VlppReflection.h" />
<ClInclude Include="..\..\..\Import\VlppRegex.h" />
<ClInclude Include="..\..\..\Import\VlppWorkflowCompiler.h" />
<ClInclude Include="..\..\..\Import\VlppWorkflowLibrary.h" />
<ClInclude Include="..\..\..\Import\VlppWorkflowRuntime.h" />
<ClInclude Include="GacGen.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\GacUI.cpp" />
<ClCompile Include="..\..\..\Import\GacUICompiler.cpp" />
<ClCompile Include="..\..\..\Import\GacUIReflection.cpp" />
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppParser.cpp" />
<ClCompile Include="..\..\..\Import\VlppReflection.cpp" />
<ClCompile Include="..\..\..\Import\VlppRegex.cpp" />
<ClCompile Include="..\..\..\Import\VlppWorkflowCompiler.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppWorkflowLibrary.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppWorkflowRuntime.cpp">
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<ClCompile Include="GacGen.cpp" />
<ClCompile Include="Main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Import">
<UniqueIdentifier>{8632b5b4-2334-4f34-96fa-fc76cb48960d}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="GacGen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppWorkflowCompiler.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppWorkflowLibrary.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppWorkflowRuntime.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppParser.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppReflection.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppRegex.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppOS.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppGlrParser.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\GacUI.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\GacUICompiler.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\GacUIReflection.h">
<Filter>Import</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GacGen.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppWorkflowCompiler.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppWorkflowLibrary.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppWorkflowRuntime.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppReflection.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppRegex.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppParser.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\GacUI.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\GacUICompiler.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\GacUIReflection.cpp">
<Filter>Import</Filter>
</ClCompile>
</ItemGroup>
</Project>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{f5a36ed2-78e7-4776-b1ab-63de18376f30}</ProjectGuid>
<RootNamespace>GlrParserGen</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)..\..\..\Import;$(ProjectDir)..\..\..\Release;$(IncludePath)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\..\Import\Vlpp.cpp" />
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp" />
<ClCompile Include="..\..\..\Import\VlppGlrParserCompiler.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.cpp" />
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp" />
<ClCompile Include="..\..\..\Import\VlppReflection.cpp" />
<ClCompile Include="..\..\..\Import\VlppRegex.cpp" />
<ClCompile Include="Main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h" />
<ClInclude Include="..\..\..\Import\VlppGlrParser.h" />
<ClInclude Include="..\..\..\Import\VlppGlrParserCompiler.h" />
<ClInclude Include="..\..\..\Import\VlppOS.h" />
<ClInclude Include="..\..\..\Import\VlppReflection.h" />
<ClInclude Include="..\..\..\Import\VlppRegex.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Import">
<UniqueIdentifier>{75a6cb7c-b54a-4fdd-9697-0f429173e83a}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Linux.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppOS.Windows.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppReflection.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppRegex.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\Vlpp.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppGlrParser.cpp">
<Filter>Import</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Import\VlppGlrParserCompiler.cpp">
<Filter>Import</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Import\Vlpp.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppOS.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppReflection.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppRegex.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppGlrParser.h">
<Filter>Import</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Import\VlppGlrParserCompiler.h">
<Filter>Import</Filter>
</ClInclude>
</ItemGroup>
</Project>
+440
View File
@@ -0,0 +1,440 @@
#include <VlppGlrParserCompiler.h>
using namespace vl;
using namespace vl::console;
using namespace vl::collections;
using namespace vl::stream;
using namespace vl::filesystem;
using namespace vl::regex;
using namespace vl::glr;
using namespace vl::glr::automaton;
using namespace vl::glr::parsergen;
using namespace vl::glr::xml;
#define EXIT_ERROR(MESSAGE)\
do\
{\
Console::SetColor(true, false, false, true);\
Console::WriteLine(MESSAGE);\
Console::SetColor(true, true, true, false);\
return 1;\
} while(false)
#define EXIT_IF_PARSER_FAIL(ERRORS, TITLE)\
do\
{\
if (ERRORS.Count() > 0)\
{\
Console::SetColor(true, false, false, true);\
Console::WriteLine(TITLE);\
PrintParsingErrors(ERRORS);\
Console::SetColor(true, true, true, false);\
return 1;\
}\
} while(false)
#define EXIT_IF_COMPILE_FAIL(GLOBAL)\
do\
{\
if (GLOBAL.Errors().Count() > 0)\
{\
Console::SetColor(true, false, false, true);\
Console::WriteLine(L"Failed to compile the syntax:");\
PrintCompileErrors(GLOBAL);\
Console::SetColor(true, true, true, false);\
return 1;\
}\
} while(false)
#define READ_ATTRIBUTE(STORAGE, ELEMENT, NAME, PATH)\
do\
{\
if (auto attributeToRead = XmlGetAttribute(ELEMENT, NAME))\
{\
STORAGE = attributeToRead->value.value;\
}\
else\
{\
EXIT_ERROR(L"Missing " PATH L".");\
}\
} while(false)\
#define READ_ELEMENT(STORAGE, ELEMENT, NAME, PATH)\
do\
{\
if (auto elementToRead = XmlGetElement(ELEMENT, NAME))\
{\
STORAGE = XmlGetValue(elementToRead);\
}\
else\
{\
EXIT_ERROR(L"Missing " PATH L".");\
}\
} while(false)\
#define READ_ELEMENT_ITEMS(STORAGE, REGEX, ELEMENT, NAME, PATH)\
do\
{\
if (auto elementToRead = XmlGetElement(ELEMENT, NAME))\
{\
auto value = XmlGetValue(elementToRead);\
if (auto match = REGEX.MatchHead(value))\
{\
for (auto item : match->Groups()[REGEX.CaptureNames().IndexOf(L"item")])\
{\
STORAGE.Add(item.Value());\
}\
}\
else\
{\
EXIT_ERROR(L"Incorrect namespace format in: " PATH L".");\
}\
}\
else\
{\
EXIT_ERROR(L"Missing " PATH L".");\
}\
} while(false)\
void PrintParsingErrors(List<ParsingError>& errors)
{
for (auto error : errors)
{
Console::WriteLine(
L"[row:" + itow(error.codeRange.start.row + 1) + L"]"
L"[column:" + itow(error.codeRange.start.column + 1) + L"]"
L": " + error.message);
}
}
void PrintCompileErrors(ParserSymbolManager& global)
{
for (auto error : global.Errors())
{
switch (error.location.type)
{
case ParserDefFileType::Ast:
Console::Write(L"[Ast:" + error.location.name + L"]");
break;
case ParserDefFileType::Lexer:
Console::Write(L"[Lexer]");
break;
case ParserDefFileType::Syntax:
Console::Write(L"[Syntax:" + error.location.name + L"]");
break;
}
Console::Write(
L"[row:" + itow(error.location.codeRange.start.row + 1) + L"]"
L"[column:" + itow(error.location.codeRange.start.column + 1) + L"]");
#define CASE_1(LABEL, P1, ...)\
Console::WriteLine(\
L"[" L ## #LABEL L"]"\
L"[" L ## #P1 L":" + error.arg1 + L"]"\
);\
#define CASE_2(LABEL, P1, P2, ...)\
Console::WriteLine(\
L"[" L ## #LABEL L"]"\
L"[" L ## #P1 L":" + error.arg1 + L"]"\
L"[" L ## #P2 L":" + error.arg2 + L"]"\
);\
#define CASE_3(LABEL, P1, P2, P3, ...)\
Console::WriteLine(\
L"[" L ## #LABEL L"]"\
L"[" L ## #P1 L":" + error.arg1 + L"]"\
L"[" L ## #P2 L":" + error.arg2 + L"]"\
L"[" L ## #P3 L":" + error.arg3 + L"]"\
);\
#define CASE_4(LABEL, P1, P2, P3, P4, ...)\
Console::WriteLine(\
L"[" L ## #LABEL L"]"\
L"[" L ## #P1 L":" + error.arg1 + L"]"\
L"[" L ## #P2 L":" + error.arg2 + L"]"\
L"[" L ## #P3 L":" + error.arg3 + L"]"\
L"[" L ## #P4 L":" + error.arg4 + L"]"\
);\
#define CASE_CALL2(ARG1, ARG2, ARG3, ARG4, ARG5, FUNC, ...)\
FUNC(ARG1, ARG2, ARG3, ARG4, ARG5)
#define CASE_CALL(ARGS)\
CASE_CALL2 ARGS
#define CASE(LABEL, ...)\
case ParserErrorType::LABEL:\
CASE_CALL((LABEL, __VA_ARGS__, CASE_4, CASE_3, CASE_2, CASE_1))\
break;\
switch (error.type)
{
GLR_PARSER_ERROR_LIST(CASE)
default:
Console::WriteLine(L"<UNKNOWN-ERROR>");
}
#undef CASE
#undef CASE_CALL
#undef CASE_CALL2
#undef CASE_4
#undef CASE_3
#undef CASE_2
#undef CASE_1
}
}
int main(int argc, char* argv[])
{
Console::SetTitle(L"Vczh GLR ParserGen for C++");
if (argc != 2)
{
Console::SetColor(true, false, false, true);
Console::WriteLine(L"GlrParserGen.exe <config-xml>");
Console::SetColor(true, true, true, false);
return 0;
}
auto workingDir = FilePath(atow(argv[1])).GetFolder();
Ptr<XmlDocument> config;
{
Parser parser;
List<ParsingError> errors;
InstallDefaultErrorMessageGenerator(parser, errors);
auto text = File(atow(argv[1])).ReadAllTextByBom();
config = XmlParseDocument(text, parser);
EXIT_IF_PARSER_FAIL(errors, L"Failed to read the input XML file.");
}
if (config->rootElement->name.value != L"Parser") EXIT_ERROR(L"Missing /Parser.");
ParserSymbolManager global;
AstSymbolManager astManager(global);
LexerSymbolManager lexerManager(global);
SyntaxSymbolManager syntaxManager(global);
Executable executable;
Metadata metadata;
FilePath generatedDir;
Dictionary<WString, WString> files;
Regex regexNamespace(L"^(<item>[^:]+)(::(<item>[^:]+))*$");
Regex regexIncludes(L"^(<item>[^;]+)(;(<item>[^;]+))*$");
auto indexItem = regexNamespace.CaptureNames().IndexOf(L"item");
READ_ATTRIBUTE(global.name, config->rootElement, L"name", L"/Parser@name");
READ_ELEMENT_ITEMS(global.includes, regexIncludes, config->rootElement, L"Includes", L"/Parser/Includes");
READ_ELEMENT_ITEMS(global.cppNss, regexNamespace, config->rootElement, L"CppNamespace", L"/Parser/CppNamespace");
READ_ELEMENT(global.headerGuard, config->rootElement, L"HeaderGuard", L"/Parser/HeaderGuard");
{
WString outputDir;
READ_ELEMENT(outputDir, config->rootElement, L"OutputDir", L"/Parser/OutputDir");
generatedDir = workingDir / outputDir;
}
auto output = GenerateParserFileNames(global);
TypeParser typeParser;
RuleParser ruleParser;
List<ParsingError> errors;
InstallDefaultErrorMessageGenerator(typeParser, errors);
InstallDefaultErrorMessageGenerator(ruleParser, errors);
if (auto elementAsts = XmlGetElement(config->rootElement, L"Asts"))
{
List<Ptr<XmlElement>> asts;
CopyFrom(asts, XmlGetElements(elementAsts, L"Ast"));
if (asts.Count() == 0) EXIT_ERROR(L"Missing /Parser/Asts/Ast");
for (auto elementAst : asts)
{
WString name, file;
READ_ATTRIBUTE(name, elementAst, L"name", L"/Parser/Asts/Ast@name");
READ_ATTRIBUTE(file, elementAst, L"file", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]");
Console::WriteLine(L"Processing " + file + L" ...");
File astFile = workingDir / file;
if (!astFile.Exists()) EXIT_ERROR(L"Missing ast definition file: " + astFile.GetFilePath().GetFullPath());
auto astInput = astFile.ReadAllTextByBom();
auto ast = typeParser.ParseFile(astInput);
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + astFile.GetFilePath().GetFullPath());
auto astDefFile = astManager.CreateFile(name);
READ_ELEMENT_ITEMS(astDefFile->cppNss, regexNamespace, elementAst, L"CppNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/CppNamespace");
READ_ELEMENT_ITEMS(astDefFile->refNss, regexNamespace, elementAst, L"ReflectionNamespace", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ReflectionNamespace");
READ_ELEMENT(astDefFile->classPrefix, elementAst, L"ClassPrefix", L"/Parser/Asts/Ast@file[@name=\"" + name + L"\"]/ClassPrefix");
CompileAst(astManager, astDefFile, ast);
}
EXIT_IF_COMPILE_FAIL(global);
GenerateAstFileNames(astManager, output);
WriteAstFiles(astManager, output, files);
}
else
{
EXIT_ERROR(L"Missing /Parser/Asts");
}
if (auto elementLexer = XmlGetElement(config->rootElement, L"Lexer"))
{
WString file;
READ_ATTRIBUTE(file, elementLexer, L"file", L"/Parser/Lexer@file");
Console::WriteLine(L"Processing " + file + L" ...");
File lexerFile = workingDir / file;
auto lexerInput = lexerFile.ReadAllTextByBom();
CompileLexer(lexerManager, lexerInput);
EXIT_IF_COMPILE_FAIL(global);
WriteLexerFiles(lexerManager, output, files);
}
else
{
EXIT_ERROR(L"Missing /Parser/Asts");
}
if (auto elementSyntax = XmlGetElement(config->rootElement, L"Syntax"))
{
WString name, file;
READ_ATTRIBUTE(name, elementSyntax, L"name", L"/Parser/Syntax@name");
READ_ATTRIBUTE(file, elementSyntax, L"file", L"/Parser/Syntax@file[@name=\"" + name + L"\"]");
Console::WriteLine(L"Processing " + file + L" ...");
File syntaxFile = workingDir / file;
auto syntaxInput = syntaxFile.ReadAllTextByBom();
auto syntax = ruleParser.ParseFile(syntaxInput);
EXIT_IF_PARSER_FAIL(errors, L"Syntax errors found in file: " + syntaxFile.GetFilePath().GetFullPath());
List<Ptr<GlrSyntaxFile>> syntaxFiles;
syntaxFiles.Add(syntax);
syntaxManager.name = name;
CompileSyntax(astManager, lexerManager, syntaxManager, output, syntaxFiles);
EXIT_IF_COMPILE_FAIL(global);
syntaxManager.BuildCompactNFA();
EXIT_IF_COMPILE_FAIL(global);
syntaxManager.BuildCrossReferencedNFA();
EXIT_IF_COMPILE_FAIL(global);
syntaxManager.BuildAutomaton(lexerManager.Tokens().Count(), executable, metadata);
EXIT_IF_COMPILE_FAIL(global);
for (auto elementExport : XmlGetElements(elementSyntax, L"Export"))
{
WString rule;
READ_ATTRIBUTE(rule, elementExport, L"rule", L"/Parser/Syntax@file[@name=\"" + name + L"\"]/Export@rule");
vint index = syntaxManager.Rules().Keys().IndexOf(rule);
if (index == -1)
{
EXIT_ERROR(L"Rule \"" + rule + L"\" is not defined in the syntax.");
}
auto ruleSymbol = syntaxManager.Rules().Values()[index];
syntaxManager.parsableRules.Add(ruleSymbol);
if (auto attType = XmlGetAttribute(elementExport, L"type"))
{
syntaxManager.ruleTypes.Add(ruleSymbol, attType->value.value);
}
else
{
auto classSymbol = ruleSymbol->ruleType;
auto classFile = classSymbol->Owner();
auto type =
From(classFile->cppNss)
.Reverse()
.Aggregate(
classFile->classPrefix + classSymbol->Name(),
[](auto&& a, auto&& b) { return b + L"::" + a; }
);
syntaxManager.ruleTypes.Add(ruleSymbol, type);
}
}
GenerateSyntaxFileNames(syntaxManager, output);
WriteSyntaxFiles(syntaxManager, executable, metadata, output, files);
}
else
{
EXIT_ERROR(L"Missing /Parser/Asts");
}
{
auto elementAsts = XmlGetElement(config->rootElement, L"Asts");
for (auto elementAst : XmlGetElements(elementAsts, L"Ast"))
{
auto name = XmlGetAttribute(elementAst, L"name")->value.value;
auto astOutput = output->astOutputs[astManager.Files()[name]];
if (auto elementBlocked = XmlGetElement(elementAst, L"BlockedUtilities"))
{
for (auto elementUtility : XmlGetElements(elementBlocked))
{
auto utility = elementUtility->name.value;
if (utility == L"Empty")
{
files.Remove(astOutput->emptyH);
files.Remove(astOutput->emptyCpp);
}
else if (utility == L"Copy")
{
files.Remove(astOutput->copyH);
files.Remove(astOutput->copyCpp);
}
else if (utility == L"Traverse")
{
files.Remove(astOutput->traverseH);
files.Remove(astOutput->traverseCpp);
}
else if (utility == L"Json")
{
files.Remove(astOutput->jsonH);
files.Remove(astOutput->jsonCpp);
}
else if (utility == L"Builder")
{
files.Remove(astOutput->builderH);
files.Remove(astOutput->builderCpp);
}
else
{
EXIT_ERROR(L"Unknown utility \"" + utility + L"\" in /Parser/Asts/Ast[@name=\"" + name + L"\"]/BlockedUtilities/*");
}
}
}
}
}
{
if (!Folder(generatedDir).Exists())
{
Folder(generatedDir).Create(true);
}
for (auto [key, index] : indexed(files.Keys()))
{
File outputFile = generatedDir / key;
auto content = files.Values()[index];
if (outputFile.Exists())
{
auto existing = outputFile.ReadAllTextByBom();
if (content == existing)
{
Console::SetColor(true, true, false, true);
Console::WriteLine(outputFile.GetFilePath().GetFullPath());
Console::SetColor(true, true, true, false);
continue;
}
}
Console::SetColor(false, true, false, true);
Console::WriteLine(outputFile.GetFilePath().GetFullPath());
Console::SetColor(true, true, true, false);
outputFile.WriteAllText(content, false, BomEncoder::Utf8);
}
}
return 0;
}