lindows/executive/src/logging.hxx

133 lines
3.4 KiB
C++

#pragma once
#include "syscall.hxx"
extern char ExecutiveLogStringBuffer[4096];
/**
* Write formatted data to the executive log buffer with ExecutiveLogFormatOptions
*
* \param Value Value to format
* \param BufferPos Position in ExecutiveLogStringBuffer
* \param Args Specification
*/
template<class _Type>
inline void ExecutiveLogFormatValue(const _Type* Value, int& BufferPos, const char* Args) = delete;
/**
* Type has a format function
*/
template<class _Type>
concept ExecutiveLogCanFormat = requires(const _Type* Value, int& BufferPos, const char* Args) {
ExecutiveLogFormatValue(Value, BufferPos, Args);
};
/**
* Log something.
*
* Format strings use \{\} for substitutions, substitutions can contain a number that
* updates the substitution index and a 127 byte format specification for formatters
*/
template<ExecutiveLogCanFormat... _Type>
inline void ExecutiveLog(const char* Format, const _Type&... Items) {
// Format items and other goodies
const void* FormatItems[sizeof...(_Type)] = { &Items... };
void (*FormatFunctions[sizeof...(_Type)])(const void*, int&, const char*) = {
// !!! VERY UNSAFE STUPID DUMB PIECE OF SHIT HACK !!!
reinterpret_cast<void (*)(const void*, int&, const char*)>(static_cast<void (*)(const _Type*, int&, const char*)>(ExecutiveLogFormatValue))...
};
// Buffer for format spec
char FormatOptions[128] = {};
// Indicies
int bpos = 0;
int fpos = 0;
int apos = 0;
// Fill out the log buffer
while (Format[fpos] != 0 && bpos < 4095) {
// Handle replacements
if (Format[fpos] == '{') {
// Clear format options
FormatOptions[0] = 0;
// Pattern matching cant come soon enough
switch (Format[++fpos]) {
case 0: { // Me when the uh i uh
LnxWrite(1, "BAD FORMAT STRING: ", 19);
LnxWrite(1, Format, fpos);
LnxWrite(1, "\n", 1);
return;
}
case '{': { // Escape
ExecutiveLogStringBuffer[bpos++] = '{';
fpos += 1;
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
volatile auto a = *(char*)(nullptr);
}
case ':':
default: {
volatile auto a = *(char*)(nullptr);
}
case '}': { // Finish the thing
fpos += 1;
// TODO: unsafe
FormatFunctions[apos](FormatItems[apos], bpos, FormatOptions);
apos += 1;
}
}
} else {
ExecutiveLogStringBuffer[bpos++] = Format[fpos++];
}
}
// Add our newline.
ExecutiveLogStringBuffer[bpos++] = '\n';
// Write to stdout.
LnxWrite(1, ExecutiveLogStringBuffer, bpos);
}
// Formatters for builtin types
template<>
inline void ExecutiveLogFormatValue<long>(const long* Value, int& BufferPos, const char* Args) {
// We only work with absolutes here.
long Absolute = *Value < 0 ? -*Value : *Value;
// Find the biggest thing i dont fucking know i hate code comments
long TheBiggest = 1;
while (TheBiggest <= Absolute) TheBiggest *= 10;
// Sign
if (*Value < 0 && BufferPos < 4095) ExecutiveLogStringBuffer[BufferPos++] = '-';
// The number
while (Absolute != 0 && BufferPos < 4095) {
ExecutiveLogStringBuffer[BufferPos++] = '0' + static_cast<char>(Absolute * 10 / TheBiggest);
Absolute %= TheBiggest / 10;
TheBiggest /= 10;
}
return;
}
template<>
inline void ExecutiveLogFormatValue<int>(const int* Value, int& BufferPos, const char* Args) {
long LongValue = *Value;
ExecutiveLogFormatValue(&LongValue, BufferPos, Args);
return;
}