Convert hello.console to use a namespacing struct

This commit is contained in:
Josh Holtrop 2022-03-28 15:18:31 -04:00
parent bcec23ef89
commit f904ec2b48
2 changed files with 149 additions and 146 deletions

View File

@ -7,172 +7,175 @@ import uefi;
import hello.hello; import hello.hello;
import core.stdc.stdarg; import core.stdc.stdarg;
/** struct console
* Format a hexadecimal value to a string.
*
* @param s String buffer.
* @param v Value to format.
* @param ptr If true, always output all 16 digits, and separate the upper and
* lower halves with an underscore.
*/
private size_t format_hex(CHAR16 * s, ulong v, bool ptr)
{ {
string hex_chars = "0123456789ABCDEF"; /**
bool print = ptr; * Format a hexadecimal value to a string.
size_t si = 0u; *
for (size_t i = 0u; i < 16u; i++) * @param s String buffer.
* @param v Value to format.
* @param ptr If true, always output all 16 digits, and separate the upper and
* lower halves with an underscore.
*/
private static size_t format_hex(CHAR16 * s, ulong v, bool ptr)
{ {
if (ptr && (i == 8u)) string hex_chars = "0123456789ABCDEF";
bool print = ptr;
size_t si = 0u;
for (size_t i = 0u; i < 16u; i++)
{ {
s[si++] = '_'; if (ptr && (i == 8u))
} {
ulong n = (v >> (60u - 4u * i)) & 0xFu; s[si++] = '_';
if (n != 0u) }
{ ulong n = (v >> (60u - 4u * i)) & 0xFu;
print = true; if (n != 0u)
} {
if (print || (i == 15u)) print = true;
{ }
s[si++] = hex_chars[n]; if (print || (i == 15u))
{
s[si++] = hex_chars[n];
}
} }
return si;
} }
return si;
}
/** /**
* Format a decimal value to a string. * Format a decimal value to a string.
* *
* @param s String buffer. * @param s String buffer.
* @param v Value to format. * @param v Value to format.
*/ */
private size_t format_dec(CHAR16 * s, ulong v) private static size_t format_dec(CHAR16 * s, ulong v)
{
string dec_chars = "0123456789";
bool print;
char[20] buf;
size_t buf_i;
while ((buf_i == 0u) || (v != 0u))
{ {
ulong n = v % 10u; string dec_chars = "0123456789";
buf[buf_i++] = dec_chars[n]; bool print;
v /= 10u; char[20] buf;
} size_t buf_i;
for (size_t si = 0u; si < buf_i; si++) while ((buf_i == 0u) || (v != 0u))
{
s[si] = buf[buf_i - si - 1u];
}
return buf_i;
}
/**
* Write a string to the console.
*
* @param s Format string.
* @param args Variable arguments structure.
*/
void write(string s, va_list args)
{
__gshared static CHAR16[256] s16;
size_t i = 0u;
bool escape = false;
foreach (char c; s)
{
if (escape)
{ {
if (c == '%') ulong n = v % 10u;
buf[buf_i++] = dec_chars[n];
v /= 10u;
}
for (size_t si = 0u; si < buf_i; si++)
{
s[si] = buf[buf_i - si - 1u];
}
return buf_i;
}
/**
* Write a string to the console.
*
* @param s Format string.
* @param args Variable arguments structure.
*/
public static void write(string s, va_list args)
{
__gshared static CHAR16[256] s16;
size_t i = 0u;
bool escape = false;
foreach (char c; s)
{
if (escape)
{ {
s16[i++] = '%'; if (c == '%')
}
else if (c == 'x')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, false);
}
else if (c == 'p')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, true);
}
else if (c == 'S')
{
const(CHAR16) * s2;
va_arg(args, s2);
for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++)
{ {
s16[i++] = s2[s2_i]; s16[i++] = '%';
} }
else if (c == 'x')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, false);
}
else if (c == 'p')
{
ulong v;
va_arg(args, v);
i += format_hex(&s16[i], v, true);
}
else if (c == 'S')
{
const(CHAR16) * s2;
va_arg(args, s2);
for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++)
{
s16[i++] = s2[s2_i];
}
}
else if (c == 'u')
{
ulong v;
va_arg(args, v);
i += format_dec(&s16[i], v);
}
else
{
s16[i++] = c;
}
escape = false;
} }
else if (c == 'u') else if (c == '%')
{ {
ulong v; escape = true;
va_arg(args, v);
i += format_dec(&s16[i], v);
} }
else else
{ {
s16[i++] = c; s16[i++] = c;
} }
escape = false;
}
else if (c == '%')
{
escape = true;
}
else
{
s16[i++] = c;
} }
s16[i++] = 0u;
st.ConOut.OutputString(st.ConOut, &s16[0]);
} }
s16[i++] = 0u;
st.ConOut.OutputString(st.ConOut, &s16[0]);
}
/** /**
* Write a string to the console. * Write a string to the console.
* *
* @param s Format string. * @param s Format string.
*/ */
extern (C) void write(string s, ...) public static extern (C) void write(string s, ...)
{
va_list args;
va_start(args, s);
write(s, args);
va_end(args);
}
/**
* Write a string to the console.
*
* @param s Format string.
*/
extern (C) void writeln(string s, ...)
{
va_list args;
va_start(args, s);
write(s, args);
write("\r\n", args);
va_end(args);
}
/**
* Write a message to press any key and wait for a key to be pressed.
*/
void wait_key()
{
writeln("Press any key...");
st.ConIn.Reset(st.ConIn, FALSE);
EFI_INPUT_KEY key;
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
{ {
va_list args;
va_start(args, s);
write(s, args);
va_end(args);
}
/**
* Write a string to the console.
*
* @param s Format string.
*/
public static extern (C) void writeln(string s, ...)
{
va_list args;
va_start(args, s);
write(s, args);
write("\r\n", args);
va_end(args);
}
/**
* Write a message to press any key and wait for a key to be pressed.
*/
public static void wait_key()
{
writeln("Press any key...");
st.ConIn.Reset(st.ConIn, FALSE);
EFI_INPUT_KEY key;
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
{
}
}
/**
* Clear the console.
*/
public static void clear()
{
st.ConOut.ClearScreen(st.ConOut);
} }
} }
/**
* Clear the console.
*/
void clear()
{
st.ConOut.ClearScreen(st.ConOut);
}

View File

@ -4,7 +4,7 @@
module hello.hello; module hello.hello;
import uefi; import uefi;
import console = hello.console; import hello.console;
import hello.scratch; import hello.scratch;
import hulk.bootinfo; import hulk.bootinfo;
import hulk.header; import hulk.header;