Re-implement string formatting (%s, %d, %x)

This commit is contained in:
Lauri Kenttä
2023-11-20 16:05:33 +02:00
parent 4e50b33636
commit 0dfc49c800
4 changed files with 93 additions and 22 deletions

View File

@@ -74,7 +74,7 @@ static void SetBMPWithRandom(struct HackBGRT_config* config, int weight, enum Ha
config->image_weight_sum += weight;
UINT32 random = Random();
UINT32 limit = 0xfffffffful / config->image_weight_sum * weight;
Log(config->debug, L"HackBGRT: n=%d, action=%d, x=%d, y=%d, o=%d, path=%s, random = %08x, limit = %08x\n", weight, action, x, y, o, path, random, limit);
Log(config->debug, L"HackBGRT: n=%d, action=%d, x=%d, y=%d, o=%d, path=%s, random = %x, limit = %x\n", weight, action, x, y, o, path, random, limit);
if (!config->image_weight_sum || random <= limit) {
config->action = action;
config->image_path = path;

View File

@@ -432,7 +432,7 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
ReadConfigLine(&config, root_dir, argv[i]);
}
if (config.debug) {
Print(L"HackBGRT version: %s\n", version);
Log(-1, L"HackBGRT version: %s\n", version);
}
SetResolution(config.resolution_x, config.resolution_y);
@@ -461,14 +461,14 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
goto ready_to_boot;
}
Log(1, L"HackBGRT: Reverting to %s.\n", config.boot_path);
Print(L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n");
Log(-1, L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n");
if (ReadKey(15000).ScanCode == SCAN_ESC) {
goto fail;
}
} else ready_to_boot: if (config.debug) {
Print(L"HackBGRT: Ready to boot.\n");
Print(L"If all goes well, you can set debug=0 and log=0 in config.txt.\n");
Print(L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n");
Log(-1, L"HackBGRT: Ready to boot.\n");
Log(-1, L"If all goes well, you can set debug=0 and log=0 in config.txt.\n");
Log(-1, L"Press escape to cancel or any other key (or wait 15 seconds) to boot.\n");
if (ReadKey(15000).ScanCode == SCAN_ESC) {
return 0;
}
@@ -481,15 +481,15 @@ EFI_STATUS EFIAPI EfiMain(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *ST_) {
goto fail;
}
Log(1, L"HackBGRT: Started %s. Why are we still here?!\n", config.boot_path);
Print(L"Please check that %s is not actually HackBGRT!\n", config.boot_path);
Log(-1, L"Please check that %s is not actually HackBGRT!\n", config.boot_path);
goto fail;
fail: {
Log(1, L"HackBGRT has failed.\n");
Print(L"Dumping log:\n\n");
Log(-1, L"Dumping log:\n\n");
DumpLog();
Print(L"If you can't boot into Windows, get install/recovery disk to fix your boot.\n");
Print(L"Press any key (or wait 15 seconds) to exit.\n");
Log(-1, L"If you can't boot into Windows, get install/recovery disk to fix your boot.\n");
Log(-1, L"Press any key (or wait 15 seconds) to exit.\n");
ReadKey(15000);
return 1;
}

View File

@@ -14,31 +14,99 @@ const CHAR16* TmpStr(CHAR8 *src, int length) {
return dest;
}
const CHAR16* TmpIntToStr(UINT32 x) {
static CHAR16 buf[20];
int i = 20 - 1;
buf[i] = 0;
if (!x) {
buf[--i] = '0';
}
while (x && i) {
buf[--i] = '0' + (x % 10);
x /= 10;
}
return &buf[i];
}
#define log_buffer_size (65536)
CHAR16 log_buffer[log_buffer_size] = {0};
CHAR16 LogVarName[] = L"HackBGRTLog";
EFI_GUID LogVarGuid = {0x03c64761, 0x075f, 0x4dba, {0xab, 0xfb, 0x2e, 0xd8, 0x9e, 0x18, 0xb2, 0x36}}; // self-made: 03c64761-075f-4dba-abfb-2ed89e18b236
void Log(int print, IN CONST CHAR16 *fmt, ...) {
void Log(int mode, IN CONST CHAR16 *fmt, ...) {
va_list args;
CHAR16 buf[256];
CHAR16 buf[256] = {0};
int buf_i = 0;
#define putchar(c) { if (buf_i < 255) { buf[buf_i++] = c; } }
va_start(args, fmt);
VSPrint(buf, sizeof(buf), fmt, args); // size is in bytes, not CHAR16s
va_end(args);
if (print) {
Print(L"%s", buf);
for (int i = 0; fmt[i]; ++i) {
if (fmt[i] == '\n') {
putchar('\r');
putchar('\n');
continue;
}
if (fmt[i] != '%') {
putchar(fmt[i]);
continue;
}
++i;
switch (fmt[i]) {
case '%': putchar('%'); continue;
case 'd': goto fmt_decimal;
case 'x': goto fmt_hex;
case 's': goto fmt_string;
case 0: goto fmt_end;
}
putchar('%');
putchar(fmt[i]);
continue;
if (0) fmt_decimal: {
INT32 x = va_arg(args, INT32);
if (x < 0) {
putchar('-');
x = -x;
}
const CHAR16* s = TmpIntToStr(x);
while (*s) {
putchar(*s++);
}
}
if (0) fmt_hex: {
UINT32 x = va_arg(args, UINT32);
for (int pos = 8, started = 0; pos--;) {
int d = (x >> (4 * pos)) & 0xf;
if (d || started || pos == 0) {
putchar("0123456789abcdef"[d]);
started = 1;
}
}
}
if (0) fmt_string: {
CHAR16* s = va_arg(args, CHAR16*);
while (*s) {
putchar(*s++);
}
}
}
fmt_end:
va_end(args);
if (mode) {
ST->ConOut->OutputString(ST->ConOut, buf);
}
if (mode != -1) {
StrnCat(log_buffer, buf, log_buffer_size - StrLen(log_buffer) - 1);
RT->SetVariable(LogVarName, &LogVarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, StrLen(log_buffer) * 2, log_buffer);
}
StrnCat(log_buffer, buf, log_buffer_size - StrLen(log_buffer) - 1);
LibSetVariable(LogVarName, &LogVarGuid, StrLen(log_buffer) * 2, log_buffer);
}
void DumpLog(void) {
Print(L"%s", log_buffer);
ST->ConOut->OutputString(ST->ConOut, log_buffer);
}
void ClearLogVariable(void) {
LibDeleteVariable(LogVarName, &LogVarGuid);
RT->SetVariable(LogVarName, &LogVarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, 0);
}
const CHAR16* TrimLeft(const CHAR16* s) {

View File

@@ -12,9 +12,12 @@
extern const CHAR16* TmpStr(CHAR8 *src, int length);
/**
* Empty function that has the same signature as Print.
* Print or log a string.
*
* @param mode -1 = print without logging, 0 = no, 1 = yes.
* @param fmt The format string. Supports %d, %x, %s.
*/
extern void Log(int print, IN CONST CHAR16 *fmt, ...);
extern void Log(int mode, IN CONST CHAR16 *fmt, ...);
/**
* Dump the log buffer to the screen.