Added proper logging capabilities
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,3 +8,6 @@ out/
|
|||||||
.vs/ProjectSettings.json
|
.vs/ProjectSettings.json
|
||||||
.vs/slnx.sqlite
|
.vs/slnx.sqlite
|
||||||
.vs/VSWorkspaceState.json
|
.vs/VSWorkspaceState.json
|
||||||
|
|
||||||
|
# Ignores the log output file of the .exe #
|
||||||
|
LXC.log
|
||||||
|
|||||||
85
Common/IO.h
85
Common/IO.h
@@ -3,8 +3,20 @@
|
|||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cstdlib>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace LXC::Internal
|
||||||
|
{
|
||||||
|
// Returns a reference to the log file //
|
||||||
|
// To be used only by LXC components //
|
||||||
|
inline std::ofstream& Log()
|
||||||
|
{
|
||||||
|
static std::ofstream sLog;
|
||||||
|
return sLog;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace LXC::Util
|
namespace LXC::Util
|
||||||
{
|
{
|
||||||
// Checks if a type can be outputted to std::ostream //
|
// Checks if a type can be outputted to std::ostream //
|
||||||
@@ -17,6 +29,13 @@ namespace LXC::Util
|
|||||||
// Checks if a list of types can be outputted to std::ostream //
|
// Checks if a list of types can be outputted to std::ostream //
|
||||||
template<typename... Args> concept AllLogable = (Logable<Args> && ...);
|
template<typename... Args> concept AllLogable = (Logable<Args> && ...);
|
||||||
|
|
||||||
|
// Checks if the type has a custom log method //
|
||||||
|
template <typename T> concept HasLogStrFunc = requires(T obj)
|
||||||
|
{
|
||||||
|
// Checks the type has a function LogStr that returns a string //
|
||||||
|
{ obj.LogStr() } -> std::same_as<std::string>;
|
||||||
|
};
|
||||||
|
|
||||||
// Enum to translate to the Win32 code for the colors //
|
// Enum to translate to the Win32 code for the colors //
|
||||||
enum Color : WORD
|
enum Color : WORD
|
||||||
{
|
{
|
||||||
@@ -69,4 +88,70 @@ namespace LXC::Util
|
|||||||
(std::cout << ... << args);
|
(std::cout << ... << args);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Intitalises the log with the given file name //
|
||||||
|
inline void CreateLog(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
// Opens the log file with the given path //
|
||||||
|
std::ofstream& log = Internal::Log();
|
||||||
|
log.open(path);
|
||||||
|
|
||||||
|
// Assigns a function to close the log file on program exit //
|
||||||
|
std::atexit([]()
|
||||||
|
{
|
||||||
|
std::ofstream& log = Internal::Log();
|
||||||
|
log.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logs all the arguments to the file (automatically flushes) //
|
||||||
|
template<typename... Args>
|
||||||
|
requires AllLogable<Args...> && (sizeof...(Args) > 1)
|
||||||
|
inline void Log(Args... args)
|
||||||
|
{
|
||||||
|
std::ofstream& log = Internal::Log();
|
||||||
|
|
||||||
|
// Only attempts to write to an open log //
|
||||||
|
if (log.is_open()) _UNLIKELY
|
||||||
|
{
|
||||||
|
// Opening symbol to make the log look fancy //
|
||||||
|
log << "[LXC-M] \"";
|
||||||
|
|
||||||
|
// Fowards the arguments to the log and flushes //
|
||||||
|
(log << ... << args);
|
||||||
|
log << "\"\n";
|
||||||
|
log.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logs a singular argument to the log, calls Log() if it can on the object //
|
||||||
|
template<typename T>
|
||||||
|
requires HasLogStrFunc<T> || Logable<T>
|
||||||
|
inline void Log(T arg)
|
||||||
|
{
|
||||||
|
std::ofstream& log = Internal::Log();
|
||||||
|
|
||||||
|
// Only attempts to write to an open log //
|
||||||
|
if (log.is_open()) _UNLIKELY
|
||||||
|
{
|
||||||
|
// Opening symbol to make log look fancy //
|
||||||
|
log << "[LXC-S] ";
|
||||||
|
|
||||||
|
// Logic if it can call LogStr() //
|
||||||
|
if constexpr (HasLogStrFunc<T>)
|
||||||
|
{
|
||||||
|
// Prints the generated string //
|
||||||
|
log << '{' << arg.LogStr() << "}\n";
|
||||||
|
log.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default logic //
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Prints the singular arg //
|
||||||
|
log << '"' << arg << "\"\n";
|
||||||
|
log.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
LXC/LXC.cpp
12
LXC/LXC.cpp
@@ -6,6 +6,9 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
using namespace LXC;
|
using namespace LXC;
|
||||||
|
|
||||||
|
// Creates the debug log //
|
||||||
|
Util::CreateLog("LXC.log");
|
||||||
|
|
||||||
// Reads the given file to a string //
|
// Reads the given file to a string //
|
||||||
Util::ReturnVal fileContents = Util::ReadFile("example/example.lx");
|
Util::ReturnVal fileContents = Util::ReadFile("example/example.lx");
|
||||||
if (fileContents.Failed()) _UNLIKELY
|
if (fileContents.Failed()) _UNLIKELY
|
||||||
@@ -18,9 +21,12 @@ int main(int argc, char** argv)
|
|||||||
Util::PrintAs<Util::LIGHT_RED>(" Error: ");
|
Util::PrintAs<Util::LIGHT_RED>(" Error: ");
|
||||||
Util::PrintLn(Util::FileReadError::ReasonStr(err.reason), " [", std::filesystem::absolute(err.path), ']');
|
Util::PrintLn(Util::FileReadError::ReasonStr(err.reason), " [", std::filesystem::absolute(err.path), ']');
|
||||||
|
|
||||||
|
Util::Log("Opening source file failed. Stopping program.");
|
||||||
Util::Stop();
|
Util::Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Util::Log("Succesfully opened source file.");
|
||||||
|
|
||||||
// Turns the file contents into a vector of tokens //
|
// Turns the file contents into a vector of tokens //
|
||||||
Util::ReturnVal tokens = Lexer::TokenizeFile(fileContents);
|
Util::ReturnVal tokens = Lexer::TokenizeFile(fileContents);
|
||||||
if (tokens.Failed()) _UNLIKELY
|
if (tokens.Failed()) _UNLIKELY
|
||||||
@@ -31,5 +37,11 @@ int main(int argc, char** argv)
|
|||||||
Util::Stop();
|
Util::Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prints all of the tokens to the log //
|
||||||
|
for (const auto& token : tokens.Result())
|
||||||
|
{
|
||||||
|
Util::Log(token);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,9 @@ namespace LXC::Lexer
|
|||||||
|
|
||||||
// Getters for the c-string to stop it being reassigned (or deleted) //
|
// Getters for the c-string to stop it being reassigned (or deleted) //
|
||||||
inline const char* const Str() const { return contents; }
|
inline const char* const Str() const { return contents; }
|
||||||
operator const char* const() { return contents; }
|
|
||||||
|
// Outputs all the relevant infomration in a string for logging purposes //
|
||||||
|
std::string LogStr() const;
|
||||||
|
|
||||||
// The type of the token //
|
// The type of the token //
|
||||||
const TokenType type;
|
const TokenType type;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace LXC::Lexer
|
|||||||
|
|
||||||
} trackers;
|
} trackers;
|
||||||
|
|
||||||
while (ctx.index > ctx.len)
|
while (ctx.index < ctx.len)
|
||||||
{
|
{
|
||||||
// The current char within the source that is being lexed //
|
// The current char within the source that is being lexed //
|
||||||
const char current = ctx.source[ctx.index];
|
const char current = ctx.source[ctx.index];
|
||||||
@@ -57,7 +57,7 @@ namespace LXC::Lexer
|
|||||||
|
|
||||||
// Creates the token (if at the end of the string literal) //
|
// Creates the token (if at the end of the string literal) //
|
||||||
if (!trackers.inStrLiteral)
|
if (!trackers.inStrLiteral)
|
||||||
ctx.out.push_back({ ctx, trackers.sectionStart, (USHORT)(ctx.index - trackers.sectionStart), Token::String_Literal });
|
ctx.out.emplace_back(ctx, trackers.sectionStart, (USHORT)(ctx.index - trackers.sectionStart), Token::String_Literal);
|
||||||
|
|
||||||
} else if (trackers.inStrLiteral) {}
|
} else if (trackers.inStrLiteral) {}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ namespace LXC::Lexer
|
|||||||
// Checks for the end of the number literal to create the token //
|
// Checks for the end of the number literal to create the token //
|
||||||
if (!IsNumeric(next)) _UNLIKELY
|
if (!IsNumeric(next)) _UNLIKELY
|
||||||
{
|
{
|
||||||
ctx.out.push_back({ ctx, trackers.sectionStart, (USHORT)(ctx.index - trackers.sectionStart), Token::Num_Literal });
|
ctx.out.emplace_back(ctx, trackers.sectionStart, (USHORT)(ctx.index - trackers.sectionStart), Token::Num_Literal);
|
||||||
trackers.inNumLiteral = false;
|
trackers.inNumLiteral = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ namespace LXC::Lexer
|
|||||||
// Checks for the end of the word to create the token //
|
// Checks for the end of the word to create the token //
|
||||||
if (!IsAlpha(next)) _UNLIKELY
|
if (!IsAlpha(next)) _UNLIKELY
|
||||||
{
|
{
|
||||||
ctx.out.push_back({ ctx, trackers.sectionStart, (USHORT)(ctx.index - trackers.sectionStart), Token::Identifier });
|
ctx.out.emplace_back(ctx, trackers.sectionStart, static_cast<unsigned short>(ctx.index - trackers.sectionStart), Token::Identifier);
|
||||||
trackers.inIdentifier = false;
|
trackers.inIdentifier = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,14 @@ namespace LXC::Lexer
|
|||||||
Token::~Token()
|
Token::~Token()
|
||||||
{
|
{
|
||||||
// Frees any allocated memory //
|
// Frees any allocated memory //
|
||||||
if (contents != nullptr)
|
//if (contents != nullptr)
|
||||||
delete[] contents;
|
// delete[] contents;
|
||||||
|
|
||||||
contents = nullptr;
|
contents = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LXC::Lexer::Token::LogStr() const
|
||||||
|
{
|
||||||
|
return std::string("CALL LogStr() function");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user