Move userspace to a templated StrFormat.
This commit is contained in:
parent
d9df1212b7
commit
26b61db021
25 changed files with 263 additions and 217 deletions
|
|
@ -1,6 +1,8 @@
|
|||
add_library(glacier STATIC
|
||||
string/string.cpp
|
||||
string/string_builder.cpp
|
||||
string/string_view.cpp
|
||||
string/str_format.cpp
|
||||
string/str_split.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class Vector {
|
|||
uint64_t size() const { return size_; }
|
||||
uint64_t capacity() const { return capacity_; }
|
||||
|
||||
const T* RawPtr() const { return data_; }
|
||||
|
||||
private:
|
||||
T* data_;
|
||||
uint64_t size_;
|
||||
|
|
|
|||
73
lib/glacier/string/str_format.cpp
Normal file
73
lib/glacier/string/str_format.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include "glacier/string/str_format.h"
|
||||
|
||||
namespace glcr {
|
||||
|
||||
namespace {
|
||||
|
||||
void StrFormatNumber(StringBuilder& builder, uint64_t value, uint64_t base) {
|
||||
const char* kHexCharacters = "0123456789ABCDEF";
|
||||
|
||||
if (value < base) {
|
||||
builder.PushBack(kHexCharacters[value]);
|
||||
return;
|
||||
}
|
||||
|
||||
StrFormatNumber(builder, value / base, base);
|
||||
|
||||
builder.PushBack(kHexCharacters[value % base]);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint8_t value, StringView opts) {
|
||||
StrFormatValue(builder, static_cast<uint64_t>(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint16_t value, StringView opts) {
|
||||
StrFormatValue(builder, static_cast<uint64_t>(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, int32_t value, StringView opts) {
|
||||
StrFormatValue(builder, static_cast<uint64_t>(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint32_t value, StringView opts) {
|
||||
StrFormatValue(builder, static_cast<uint64_t>(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint64_t value, StringView opts) {
|
||||
if (opts.find('x') != opts.npos) {
|
||||
builder.PushBack("0x");
|
||||
StrFormatNumber(builder, value, 16);
|
||||
} else {
|
||||
StrFormatNumber(builder, value, 10);
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, ErrorCode value, StringView opts) {
|
||||
StrFormatValue(builder, static_cast<uint64_t>(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, const char* value,
|
||||
StringView opts) {
|
||||
StrFormatValue(builder, StringView(value), opts);
|
||||
}
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, StringView value, StringView opts) {
|
||||
StrFormatInternal(builder, value);
|
||||
}
|
||||
|
||||
void StrFormatInternal(StringBuilder& builder, StringView format) {
|
||||
// TODO: Consider throwing an error if there are unhandled format
|
||||
builder.PushBack(format);
|
||||
}
|
||||
|
||||
} // namespace glcr
|
||||
62
lib/glacier/string/str_format.h
Normal file
62
lib/glacier/string/str_format.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include "glacier/memory/move.h"
|
||||
#include "glacier/status/error.h"
|
||||
#include "glacier/string/string_builder.h"
|
||||
#include "glacier/string/string_view.h"
|
||||
|
||||
namespace glcr {
|
||||
|
||||
template <typename T>
|
||||
void StrFormatValue(StringBuilder& builder, T value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint8_t value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint16_t value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, int32_t value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint32_t value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, uint64_t value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, ErrorCode value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, const char* value, StringView opts);
|
||||
|
||||
template <>
|
||||
void StrFormatValue(StringBuilder& builder, StringView value, StringView opts);
|
||||
|
||||
void StrFormatInternal(StringBuilder& builder, StringView format);
|
||||
|
||||
template <typename T, typename... Args>
|
||||
void StrFormatInternal(StringBuilder& builder, StringView format, T value,
|
||||
Args... args) {
|
||||
uint64_t posl = format.find('{');
|
||||
uint64_t posr = format.find('}', posl);
|
||||
if (posl == format.npos || posr == format.npos) {
|
||||
// TODO: Consider throwing an error since we still have values to consume.
|
||||
return StrFormatInternal(builder, format);
|
||||
}
|
||||
|
||||
builder.PushBack(format.substr(0, posl));
|
||||
StrFormatValue(builder, value, format.substr(posl + 1, posr - posl - 1));
|
||||
StrFormatInternal(builder, format.substr(posr + 1, format.size() - posr - 1),
|
||||
args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
StringBuilder StrFormat(StringView format, Args... args) {
|
||||
StringBuilder builder;
|
||||
StrFormatInternal(builder, format, args...);
|
||||
return glcr::Move(builder);
|
||||
}
|
||||
|
||||
} // namespace glcr
|
||||
24
lib/glacier/string/string_builder.cpp
Normal file
24
lib/glacier/string/string_builder.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "glacier/string/string_builder.h"
|
||||
|
||||
namespace glcr {
|
||||
|
||||
void StringBuilder::PushBack(const StringView& str) {
|
||||
if (capacity() < size() + str.size()) {
|
||||
uint64_t new_capacity = capacity() == 0 ? 1 : capacity() * 2;
|
||||
while (new_capacity < size() + str.size()) {
|
||||
new_capacity *= 2;
|
||||
}
|
||||
Resize(new_capacity);
|
||||
}
|
||||
for (uint64_t i = 0; i < str.size(); i++) {
|
||||
Vector<char>::PushBack(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
String StringBuilder::ToString() const { return String(RawPtr(), size()); }
|
||||
|
||||
StringBuilder::operator StringView() const {
|
||||
return StringView(RawPtr(), size());
|
||||
}
|
||||
|
||||
} // namespace glcr
|
||||
26
lib/glacier/string/string_builder.h
Normal file
26
lib/glacier/string/string_builder.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "glacier/container/vector.h"
|
||||
#include "glacier/string/string.h"
|
||||
#include "glacier/string/string_view.h"
|
||||
|
||||
namespace glcr {
|
||||
|
||||
class StringBuilder : public Vector<char> {
|
||||
public:
|
||||
StringBuilder() : Vector<char>() {}
|
||||
StringBuilder(const StringBuilder&) = delete;
|
||||
StringBuilder(StringBuilder&& str) : Vector<char>(Move(str)) {}
|
||||
|
||||
void PushBack(const StringView& str);
|
||||
using Vector<char>::PushBack;
|
||||
|
||||
String ToString() const;
|
||||
|
||||
// Note that this could become invalidated
|
||||
// at any time if more characters are pushed
|
||||
// onto the builder.
|
||||
operator StringView() const;
|
||||
};
|
||||
|
||||
} // namespace glcr
|
||||
|
|
@ -25,6 +25,7 @@ uint64_t StringView::size() const { return size_; }
|
|||
bool StringView::empty() const { return size_ == 0; }
|
||||
|
||||
char StringView::at(uint64_t pos) const { return value_[pos]; }
|
||||
char StringView::operator[](uint64_t pos) const { return at(pos); };
|
||||
|
||||
uint64_t StringView::find(char c, uint64_t pos) const {
|
||||
for (uint64_t i = pos; i < size_; i++) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class StringView {
|
|||
bool empty() const;
|
||||
|
||||
char at(uint64_t pos) const;
|
||||
char operator[](uint64_t pos) const;
|
||||
|
||||
uint64_t find(char c, uint64_t pos = 0) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
add_library(c STATIC
|
||||
src/malloc.cpp
|
||||
src/stdio.cpp
|
||||
src/string.cpp
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// int fprintf(FILE *stream, const char *format, ...);
|
||||
int printf(const char *format, ...);
|
||||
int sprintf(char *str, const char *format, ...);
|
||||
// int vfprintf(FILE *stream, const char *format, va_list arg);
|
||||
int vprintf(const char *format, va_list arg);
|
||||
int vsprintf(char *str, const char *format, va_list arg);
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
#include "stdio.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t num_chars(uint64_t num, uint8_t base) {
|
||||
uint32_t width = 0;
|
||||
while (num > 0) {
|
||||
num /= base;
|
||||
width++;
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
int sprint_base(char *str, uint64_t num, uint32_t base) {
|
||||
uint32_t width = num_chars(num, base);
|
||||
if (width == 0) {
|
||||
*str = '0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t place = 1;
|
||||
while (num > 0) {
|
||||
// FIXME: We seem to have an issue with loading globals.
|
||||
const char *kHexChars = "0123456789abcdef";
|
||||
str[width - place] = kHexChars[num % base];
|
||||
place++;
|
||||
num /= base;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int sprintf(char *str, const char *format, ...) {
|
||||
va_list arg;
|
||||
va_start(arg, format);
|
||||
int ret = vsprintf(str, format, arg);
|
||||
va_end(arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int vsprintf(char *str, const char *format, va_list arg) {
|
||||
uint32_t chars = 0;
|
||||
while (*format != '\0') {
|
||||
if (*format != '%') {
|
||||
*str = *format;
|
||||
chars++;
|
||||
str++;
|
||||
format++;
|
||||
continue;
|
||||
}
|
||||
format++;
|
||||
switch (*format) {
|
||||
case '%':
|
||||
*(str++) = *(format++);
|
||||
chars++;
|
||||
break;
|
||||
case 'l': {
|
||||
switch (*(++format)) {
|
||||
case 'x': {
|
||||
int width = sprint_base(str, va_arg(arg, uint64_t), 16);
|
||||
if (width == -1) {
|
||||
return -1;
|
||||
}
|
||||
chars += width;
|
||||
str += width;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
int width = sprint_base(str, va_arg(arg, uint64_t), 10);
|
||||
if (width == -1) {
|
||||
return -1;
|
||||
}
|
||||
chars += width;
|
||||
str += width;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'x': {
|
||||
int width = sprint_base(str, va_arg(arg, uint32_t), 16);
|
||||
if (width == -1) {
|
||||
return -1;
|
||||
}
|
||||
chars += width;
|
||||
str += width;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
int width = sprint_base(str, va_arg(arg, uint32_t), 10);
|
||||
if (width == -1) {
|
||||
return -1;
|
||||
}
|
||||
chars += width;
|
||||
str += width;
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
char *instr = va_arg(arg, char *);
|
||||
int width = 0;
|
||||
while (*instr != '\0') {
|
||||
*(str++) = *(instr++);
|
||||
width++;
|
||||
}
|
||||
format++;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*(str++) = *(format++);
|
||||
chars++;
|
||||
}
|
||||
}
|
||||
*str = '\0';
|
||||
chars++;
|
||||
|
||||
return chars;
|
||||
}
|
||||
|
|
@ -1,9 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include <glacier/string/str_format.h>
|
||||
#include <glacier/string/string_view.h>
|
||||
#include <stdint.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
void dbgln(const char* fmt, ...);
|
||||
// TODO: Take StringView here instead.
|
||||
void dbgln(const glcr::StringBuilder& builder);
|
||||
|
||||
template <typename... Args>
|
||||
void dbgln(const glcr::StringView& fmt, Args... args) {
|
||||
dbgln(StrFormat(fmt, args...));
|
||||
}
|
||||
|
||||
// Checks that the code is ok.
|
||||
// if not exits the process.
|
||||
|
|
|
|||
|
|
@ -1,27 +1,11 @@
|
|||
#include "include/mammoth/debug.h"
|
||||
|
||||
#include <glacier/status/error.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <zcall.h>
|
||||
|
||||
void dbgln_internal(const char* str) { // Safe to ignore the result since right
|
||||
// now this doesn't throw.
|
||||
uint64_t _ = ZDebug(str);
|
||||
}
|
||||
|
||||
void dbgln(const char* fmt, ...) {
|
||||
char str[1024];
|
||||
va_list arg;
|
||||
va_start(arg, fmt);
|
||||
int ret = vsprintf(str, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (ret == -1 || ret > 1024) {
|
||||
crash("Bad vsprintf", 1);
|
||||
}
|
||||
|
||||
dbgln_internal(str);
|
||||
void dbgln(const glcr::StringBuilder& builder) {
|
||||
glcr::String str = builder.ToString();
|
||||
(void)ZDebug(str.cstr());
|
||||
}
|
||||
|
||||
void check(uint64_t code) {
|
||||
|
|
@ -44,10 +28,10 @@ void check(uint64_t code) {
|
|||
dbgln("Unhandled code");
|
||||
break;
|
||||
}
|
||||
ZProcessExit(code);
|
||||
(void)ZProcessExit(code);
|
||||
}
|
||||
|
||||
void crash(const char* str, uint64_t code) {
|
||||
dbgln(str);
|
||||
ZProcessExit(code);
|
||||
(void)ZProcessExit(code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ void EndpointServer::ServerThread() {
|
|||
ZEndpointRecv(endpoint_cap_, &message_size, recieve_buffer_, &num_caps,
|
||||
nullptr, &reply_port_cap));
|
||||
if (err != glcr::OK) {
|
||||
dbgln("Error in receive: %x", err);
|
||||
dbgln("Error in receive: {x}", err);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ void EndpointServer::ServerThread() {
|
|||
// FIXME: Consider pumping these errors into the response as well.
|
||||
check(HandleRequest(request, response));
|
||||
if (!response.HasWritten()) {
|
||||
dbgln("Returning without having written a response. Req type %x",
|
||||
dbgln("Returning without having written a response. Req type {x}",
|
||||
request.request_id());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,30 +23,25 @@ z_err_t ParseInitPort(uint64_t init_port_cap) {
|
|||
RET_ERR(ret);
|
||||
switch (init_sig) {
|
||||
case Z_INIT_SELF_PROC:
|
||||
dbgln("received proc");
|
||||
gSelfProcCap = init_cap;
|
||||
break;
|
||||
case Z_INIT_SELF_VMAS:
|
||||
dbgln("received vmas");
|
||||
gSelfVmasCap = init_cap;
|
||||
break;
|
||||
case Z_INIT_ENDPOINT:
|
||||
gInitEndpointCap = init_cap;
|
||||
break;
|
||||
case Z_BOOT_DENALI_VMMO:
|
||||
dbgln("received denali");
|
||||
gBootDenaliVmmoCap = init_cap;
|
||||
break;
|
||||
case Z_BOOT_VICTORIA_FALLS_VMMO:
|
||||
dbgln("received victoria falls");
|
||||
gBootVictoriaFallsVmmoCap = init_cap;
|
||||
break;
|
||||
case Z_BOOT_PCI_VMMO:
|
||||
dbgln("received pci");
|
||||
gBootPciVmmoCap = init_cap;
|
||||
break;
|
||||
default:
|
||||
dbgln("Unexpected init type %x, continuing.", init_sig);
|
||||
dbgln("Unexpected init type {}, continuing.", init_sig);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue