133 lines
3.4 KiB
C++
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;
|
|
}
|