1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 14:28:12 +00:00

AK: Add out() and warn() streams that forward to stdout and stderr

Our C++ code generator tools have been relying on host-side dbg() being
forwarded to stdout until now. Now they use out() instead.

Hopefully this will make it easier and more enticing to use streams in
userspace programs as well. :^)
This commit is contained in:
Andreas Kling 2020-04-06 10:12:10 +02:00
parent 63b11e094d
commit 0d48fb9a87
6 changed files with 219 additions and 176 deletions

View file

@ -34,6 +34,10 @@
# include <Kernel/Thread.h> # include <Kernel/Thread.h>
#endif #endif
#if !defined(KERNEL) && !defined(BOOTSTRAPPER)
#include <stdio.h>
#endif
namespace AK { namespace AK {
const LogStream& operator<<(const LogStream& stream, const String& value) const LogStream& operator<<(const LogStream& stream, const String& value)
@ -163,4 +167,20 @@ DebugLogStream::~DebugLogStream()
write(&newline, 1); write(&newline, 1);
} }
#if !defined(KERNEL) && !defined(BOOTSTRAPPER)
StdLogStream::~StdLogStream()
{
char newline = '\n';
write(&newline, 1);
}
void StdLogStream::write(const char* characters, int length) const
{
if (::write(m_fd, characters, length) < 0) {
perror("StdLogStream::write");
ASSERT_NOT_REACHED();
}
}
#endif
} }

View file

@ -68,6 +68,24 @@ public:
} }
}; };
#if !defined(KERNEL) && !defined(BOOTSTRAPPER)
class StdLogStream final : public LogStream {
public:
StdLogStream(int fd)
: m_fd(fd)
{
}
virtual ~StdLogStream() override;
virtual void write(const char* characters, int length) const override;
private:
int m_fd { -1 };
};
inline StdLogStream out() { return StdLogStream(STDOUT_FILENO); }
inline StdLogStream warn() { return StdLogStream(STDERR_FILENO); }
#endif
#if !defined(BOOTSTRAPPER) && defined(KERNEL) #if !defined(BOOTSTRAPPER) && defined(KERNEL)
class KernelLogStream final : public LogStream { class KernelLogStream final : public LogStream {
public: public:
@ -128,3 +146,8 @@ DebugLogStream klog();
using AK::dbg; using AK::dbg;
using AK::klog; using AK::klog;
using AK::LogStream; using AK::LogStream;
#if !defined(KERNEL) && !defined(BOOTSTRAPPER)
using AK::out;
using AK::warn;
#endif

View file

@ -61,7 +61,7 @@ int main(int argc, char** argv)
return 1; return 1;
} }
dbg() << "#pragma once"; out() << "#pragma once";
widgets.as_array().for_each([&](auto& value) { widgets.as_array().for_each([&](auto& value) {
const JsonObject& widget_object = value.as_object(); const JsonObject& widget_object = value.as_object();
@ -69,36 +69,36 @@ int main(int argc, char** argv)
StringBuilder builder; StringBuilder builder;
auto parts = class_name.split(':'); auto parts = class_name.split(':');
builder.append(parts.last()); builder.append(parts.last());
dbg() << "#include <LibGUI/" << builder.to_string() << ".h>"; out() << "#include <LibGUI/" << builder.to_string() << ".h>";
}); });
dbg() << "struct UI_" << name << " {"; out() << "struct UI_" << name << " {";
dbg() << " RefPtr<GUI::Widget> main_widget;"; out() << " RefPtr<GUI::Widget> main_widget;";
widgets.as_array().for_each([&](auto& value) { widgets.as_array().for_each([&](auto& value) {
ASSERT(value.is_object()); ASSERT(value.is_object());
const JsonObject& widget_object = value.as_object(); const JsonObject& widget_object = value.as_object();
auto name = widget_object.get("name").to_string(); auto name = widget_object.get("name").to_string();
auto class_name = widget_object.get("class").to_string(); auto class_name = widget_object.get("class").to_string();
dbg() << " RefPtr<" << class_name << "> " << name << ";"; out() << " RefPtr<" << class_name << "> " << name << ";";
}); });
dbg() << " UI_" << name << "();"; out() << " UI_" << name << "();";
dbg() << "};"; out() << "};";
dbg() << "UI_" << name << "::UI_" << name << "()"; out() << "UI_" << name << "::UI_" << name << "()";
dbg() << "{"; out() << "{";
dbg() << " main_widget = GUI::Widget::construct();"; out() << " main_widget = GUI::Widget::construct();";
dbg() << " main_widget->set_fill_with_background_color(true);"; out() << " main_widget->set_fill_with_background_color(true);";
widgets.as_array().for_each([&](auto& value) { widgets.as_array().for_each([&](auto& value) {
ASSERT(value.is_object()); ASSERT(value.is_object());
const JsonObject& widget_object = value.as_object(); const JsonObject& widget_object = value.as_object();
auto name = widget_object.get("name").to_string(); auto name = widget_object.get("name").to_string();
auto class_name = widget_object.get("class").to_string(); auto class_name = widget_object.get("class").to_string();
dbg() << " " << name << " = main_widget->add<" << class_name << ">();"; out() << " " << name << " = main_widget->add<" << class_name << ">();";
widget_object.for_each_member([&](auto& property_name, const JsonValue& property_value) { widget_object.for_each_member([&](auto& property_name, const JsonValue& property_value) {
if (property_name == "class") if (property_name == "class")
@ -111,12 +111,12 @@ int main(int argc, char** argv)
else else
value = property_value.serialized<StringBuilder>(); value = property_value.serialized<StringBuilder>();
dbg() << " " << name << "->set_" << property_name << "(" << value << ");"; out() << " " << name << "->set_" << property_name << "(" << value << ");";
}); });
dbg() << ""; out() << "";
}); });
dbg() << "}"; out() << "}";
return 0; return 0;
} }

View file

@ -100,7 +100,7 @@ int main(int argc, char** argv)
auto consume_specific = [&](char ch) { auto consume_specific = [&](char ch) {
if (peek() != ch) { if (peek() != ch) {
dbg() << "consume_specific: wanted '" << ch << "', but got '" << peek() << "' at index " << index; warn() << "consume_specific: wanted '" << ch << "', but got '" << peek() << "' at index " << index;
} }
ASSERT(peek() == ch); ASSERT(peek() == ch);
++index; ++index;
@ -223,36 +223,36 @@ int main(int argc, char** argv)
while (index < file_contents.size()) while (index < file_contents.size())
parse_endpoint(); parse_endpoint();
dbg() << "#pragma once"; out() << "#pragma once";
dbg() << "#include <AK/BufferStream.h>"; out() << "#include <AK/BufferStream.h>";
dbg() << "#include <AK/OwnPtr.h>"; out() << "#include <AK/OwnPtr.h>";
dbg() << "#include <LibGfx/Color.h>"; out() << "#include <LibGfx/Color.h>";
dbg() << "#include <LibGfx/Rect.h>"; out() << "#include <LibGfx/Rect.h>";
dbg() << "#include <LibGfx/ShareableBitmap.h>"; out() << "#include <LibGfx/ShareableBitmap.h>";
dbg() << "#include <LibIPC/Decoder.h>"; out() << "#include <LibIPC/Decoder.h>";
dbg() << "#include <LibIPC/Encoder.h>"; out() << "#include <LibIPC/Encoder.h>";
dbg() << "#include <LibIPC/Endpoint.h>"; out() << "#include <LibIPC/Endpoint.h>";
dbg() << "#include <LibIPC/Message.h>"; out() << "#include <LibIPC/Message.h>";
dbg(); out();
for (auto& endpoint : endpoints) { for (auto& endpoint : endpoints) {
dbg() << "namespace Messages {"; out() << "namespace Messages {";
dbg() << "namespace " << endpoint.name << " {"; out() << "namespace " << endpoint.name << " {";
dbg(); out();
HashMap<String, int> message_ids; HashMap<String, int> message_ids;
dbg() << "enum class MessageID : i32 {"; out() << "enum class MessageID : i32 {";
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
message_ids.set(message.name, message_ids.size() + 1); message_ids.set(message.name, message_ids.size() + 1);
dbg() << " " << message.name << " = " << message_ids.size() << ","; out() << " " << message.name << " = " << message_ids.size() << ",";
if (message.is_synchronous) { if (message.is_synchronous) {
message_ids.set(message.response_name(), message_ids.size() + 1); message_ids.set(message.response_name(), message_ids.size() + 1);
dbg() << " " << message.response_name() << " = " << message_ids.size() << ","; out() << " " << message.response_name() << " = " << message_ids.size() << ",";
} }
} }
dbg() << "};"; out() << "};";
dbg(); out();
auto constructor_for_message = [&](const String& name, const Vector<Parameter>& parameters) { auto constructor_for_message = [&](const String& name, const Vector<Parameter>& parameters) {
StringBuilder builder; StringBuilder builder;
@ -289,39 +289,39 @@ int main(int argc, char** argv)
}; };
auto do_message = [&](const String& name, const Vector<Parameter>& parameters, const String& response_type = {}) { auto do_message = [&](const String& name, const Vector<Parameter>& parameters, const String& response_type = {}) {
dbg() << "class " << name << " final : public IPC::Message {"; out() << "class " << name << " final : public IPC::Message {";
dbg() << "public:"; out() << "public:";
if (!response_type.is_null()) if (!response_type.is_null())
dbg() << " typedef class " << response_type << " ResponseType;"; out() << " typedef class " << response_type << " ResponseType;";
dbg() << " " << constructor_for_message(name, parameters); out() << " " << constructor_for_message(name, parameters);
dbg() << " virtual ~" << name << "() override {}"; out() << " virtual ~" << name << "() override {}";
dbg() << " virtual i32 endpoint_magic() const override { return " << endpoint.magic << "; }"; out() << " virtual i32 endpoint_magic() const override { return " << endpoint.magic << "; }";
dbg() << " virtual i32 message_id() const override { return (int)MessageID::" << name << "; }"; out() << " virtual i32 message_id() const override { return (int)MessageID::" << name << "; }";
dbg() << " static i32 static_message_id() { return (int)MessageID::" << name << "; }"; out() << " static i32 static_message_id() { return (int)MessageID::" << name << "; }";
dbg() << " virtual const char* message_name() const override { return \"" << endpoint.name << "::" << name << "\"; }"; out() << " virtual const char* message_name() const override { return \"" << endpoint.name << "::" << name << "\"; }";
dbg() << " static OwnPtr<" << name << "> decode(BufferStream& stream, size_t& size_in_bytes)"; out() << " static OwnPtr<" << name << "> decode(BufferStream& stream, size_t& size_in_bytes)";
dbg() << " {"; out() << " {";
dbg() << " IPC::Decoder decoder(stream);"; out() << " IPC::Decoder decoder(stream);";
for (auto& parameter : parameters) { for (auto& parameter : parameters) {
String initial_value = "{}"; String initial_value = "{}";
if (parameter.type == "bool") if (parameter.type == "bool")
initial_value = "false"; initial_value = "false";
dbg() << " " << parameter.type << " " << parameter.name << " = " << initial_value << ";"; out() << " " << parameter.type << " " << parameter.name << " = " << initial_value << ";";
if (parameter.type == "Vector<Gfx::Rect>") { if (parameter.type == "Vector<Gfx::Rect>") {
dbg() << " u64 " << parameter.name << "_size = 0;"; out() << " u64 " << parameter.name << "_size = 0;";
dbg() << " stream >> " << parameter.name << "_size;"; out() << " stream >> " << parameter.name << "_size;";
dbg() << " for (size_t i = 0; i < " << parameter.name << "_size; ++i) {"; out() << " for (size_t i = 0; i < " << parameter.name << "_size; ++i) {";
dbg() << " Gfx::Rect rect;"; out() << " Gfx::Rect rect;";
dbg() << " if (!decoder.decode(rect))"; out() << " if (!decoder.decode(rect))";
dbg() << " return nullptr;"; out() << " return nullptr;";
dbg() << " " << parameter.name << ".append(move(rect));"; out() << " " << parameter.name << ".append(move(rect));";
dbg() << " }"; out() << " }";
} else { } else {
dbg() << " if (!decoder.decode(" << parameter.name << "))"; out() << " if (!decoder.decode(" << parameter.name << "))";
dbg() << " return nullptr;"; out() << " return nullptr;";
} }
} }
@ -332,56 +332,56 @@ int main(int argc, char** argv)
if (i != parameters.size() - 1) if (i != parameters.size() - 1)
builder.append(", "); builder.append(", ");
} }
dbg() << " size_in_bytes = stream.offset();"; out() << " size_in_bytes = stream.offset();";
dbg() << " return make<" << name << ">(" << builder.to_string() << ");"; out() << " return make<" << name << ">(" << builder.to_string() << ");";
dbg() << " }"; out() << " }";
dbg() << " virtual IPC::MessageBuffer encode() const override"; out() << " virtual IPC::MessageBuffer encode() const override";
dbg() << " {"; out() << " {";
dbg() << " IPC::MessageBuffer buffer;"; out() << " IPC::MessageBuffer buffer;";
dbg() << " IPC::Encoder stream(buffer);"; out() << " IPC::Encoder stream(buffer);";
dbg() << " stream << endpoint_magic();"; out() << " stream << endpoint_magic();";
dbg() << " stream << (int)MessageID::" << name << ";"; out() << " stream << (int)MessageID::" << name << ";";
for (auto& parameter : parameters) { for (auto& parameter : parameters) {
if (parameter.type == "Gfx::Color") { if (parameter.type == "Gfx::Color") {
dbg() << " stream << m_" << parameter.name << ".value();"; out() << " stream << m_" << parameter.name << ".value();";
} else if (parameter.type == "Gfx::Size") { } else if (parameter.type == "Gfx::Size") {
dbg() << " stream << m_" << parameter.name << ".width();"; out() << " stream << m_" << parameter.name << ".width();";
dbg() << " stream << m_" << parameter.name << ".height();"; out() << " stream << m_" << parameter.name << ".height();";
} else if (parameter.type == "Gfx::Point") { } else if (parameter.type == "Gfx::Point") {
dbg() << " stream << m_" << parameter.name << ".x();"; out() << " stream << m_" << parameter.name << ".x();";
dbg() << " stream << m_" << parameter.name << ".y();"; out() << " stream << m_" << parameter.name << ".y();";
} else if (parameter.type == "Gfx::Rect") { } else if (parameter.type == "Gfx::Rect") {
dbg() << " stream << m_" << parameter.name << ".x();"; out() << " stream << m_" << parameter.name << ".x();";
dbg() << " stream << m_" << parameter.name << ".y();"; out() << " stream << m_" << parameter.name << ".y();";
dbg() << " stream << m_" << parameter.name << ".width();"; out() << " stream << m_" << parameter.name << ".width();";
dbg() << " stream << m_" << parameter.name << ".height();"; out() << " stream << m_" << parameter.name << ".height();";
} else if (parameter.type == "Vector<Gfx::Rect>") { } else if (parameter.type == "Vector<Gfx::Rect>") {
dbg() << " stream << (u64)m_" << parameter.name << ".size();"; out() << " stream << (u64)m_" << parameter.name << ".size();";
dbg() << " for (auto& rect : m_" << parameter.name << ") {"; out() << " for (auto& rect : m_" << parameter.name << ") {";
dbg() << " stream << rect.x();"; out() << " stream << rect.x();";
dbg() << " stream << rect.y();"; out() << " stream << rect.y();";
dbg() << " stream << rect.width();"; out() << " stream << rect.width();";
dbg() << " stream << rect.height();"; out() << " stream << rect.height();";
dbg() << " }"; out() << " }";
} else if (parameter.type == "Gfx::ShareableBitmap") { } else if (parameter.type == "Gfx::ShareableBitmap") {
dbg() << " stream << m_" << parameter.name << ".shbuf_id();"; out() << " stream << m_" << parameter.name << ".shbuf_id();";
dbg() << " stream << m_" << parameter.name << ".width();"; out() << " stream << m_" << parameter.name << ".width();";
dbg() << " stream << m_" << parameter.name << ".height();"; out() << " stream << m_" << parameter.name << ".height();";
} else { } else {
dbg() << " stream << m_" << parameter.name << ";"; out() << " stream << m_" << parameter.name << ";";
} }
} }
dbg() << " return buffer;"; out() << " return buffer;";
dbg() << " }"; out() << " }";
for (auto& parameter : parameters) { for (auto& parameter : parameters) {
dbg() << " const " << parameter.type << "& " << parameter.name << "() const { return m_" << parameter.name << "; }"; out() << " const " << parameter.type << "& " << parameter.name << "() const { return m_" << parameter.name << "; }";
} }
dbg() << "private:"; out() << "private:";
for (auto& parameter : parameters) { for (auto& parameter : parameters) {
dbg() << " " << parameter.type << " m_" << parameter.name << ";"; out() << " " << parameter.type << " m_" << parameter.name << ";";
} }
dbg() << "};"; out() << "};";
dbg(); out();
}; };
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
String response_name; String response_name;
@ -391,72 +391,72 @@ int main(int argc, char** argv)
} }
do_message(message.name, message.inputs, response_name); do_message(message.name, message.inputs, response_name);
} }
dbg() << "} // namespace " << endpoint.name; out() << "} // namespace " << endpoint.name;
dbg() << "} // namespace Messages"; out() << "} // namespace Messages";
dbg(); out();
dbg() << "class " << endpoint.name << "Endpoint : public IPC::Endpoint {"; out() << "class " << endpoint.name << "Endpoint : public IPC::Endpoint {";
dbg() << "public:"; out() << "public:";
dbg() << " " << endpoint.name << "Endpoint() {}"; out() << " " << endpoint.name << "Endpoint() {}";
dbg() << " virtual ~" << endpoint.name << "Endpoint() override {}"; out() << " virtual ~" << endpoint.name << "Endpoint() override {}";
dbg() << " static int static_magic() { return " << endpoint.magic << "; }"; out() << " static int static_magic() { return " << endpoint.magic << "; }";
dbg() << " virtual int magic() const override { return " << endpoint.magic << "; }"; out() << " virtual int magic() const override { return " << endpoint.magic << "; }";
dbg() << " static String static_name() { return \"" << endpoint.name << "\"; };"; out() << " static String static_name() { return \"" << endpoint.name << "\"; };";
dbg() << " virtual String name() const override { return \"" << endpoint.name << "\"; };"; out() << " virtual String name() const override { return \"" << endpoint.name << "\"; };";
dbg() << " static OwnPtr<IPC::Message> decode_message(const ByteBuffer& buffer, size_t& size_in_bytes)"; out() << " static OwnPtr<IPC::Message> decode_message(const ByteBuffer& buffer, size_t& size_in_bytes)";
dbg() << " {"; out() << " {";
dbg() << " BufferStream stream(const_cast<ByteBuffer&>(buffer));"; out() << " BufferStream stream(const_cast<ByteBuffer&>(buffer));";
dbg() << " i32 message_endpoint_magic = 0;"; out() << " i32 message_endpoint_magic = 0;";
dbg() << " stream >> message_endpoint_magic;"; out() << " stream >> message_endpoint_magic;";
dbg() << " if (message_endpoint_magic != " << endpoint.magic << ") {"; out() << " if (message_endpoint_magic != " << endpoint.magic << ") {";
#ifdef GENERATE_DEBUG_CODE #ifdef GENERATE_DEBUG_CODE
dbg() << " dbg() << \"endpoint magic \" << message_endpoint_magic << \" != " << endpoint.magic << "\";"; sout() << " sout() << \"endpoint magic \" << message_endpoint_magic << \" != " << endpoint.magic << "\";";
#endif #endif
dbg() << " return nullptr;"; out() << " return nullptr;";
dbg() << " }"; out() << " }";
dbg() << " i32 message_id = 0;"; out() << " i32 message_id = 0;";
dbg() << " stream >> message_id;"; out() << " stream >> message_id;";
dbg() << " switch (message_id) {"; out() << " switch (message_id) {";
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
auto do_decode_message = [&](const String& name) { auto do_decode_message = [&](const String& name) {
dbg() << " case (int)Messages::" << endpoint.name << "::MessageID::" << name << ":"; out() << " case (int)Messages::" << endpoint.name << "::MessageID::" << name << ":";
dbg() << " return Messages::" << endpoint.name << "::" << name << "::decode(stream, size_in_bytes);"; out() << " return Messages::" << endpoint.name << "::" << name << "::decode(stream, size_in_bytes);";
}; };
do_decode_message(message.name); do_decode_message(message.name);
if (message.is_synchronous) if (message.is_synchronous)
do_decode_message(message.response_name()); do_decode_message(message.response_name());
} }
dbg() << " default:"; out() << " default:";
#ifdef GENERATE_DEBUG_CODE #ifdef GENERATE_DEBUG_CODE
dbg() << " dbg() << \"Failed to decode " << endpoint.name << ".(\" << message_id << \")\";"; sout() << " sout() << \"Failed to decode " << endpoint.name << ".(\" << message_id << \")\";";
#endif #endif
dbg() << " return nullptr;"; out() << " return nullptr;";
dbg() << " }"; out() << " }";
dbg() << " }"; out() << " }";
dbg(); out();
dbg() << " virtual OwnPtr<IPC::Message> handle(const IPC::Message& message) override"; out() << " virtual OwnPtr<IPC::Message> handle(const IPC::Message& message) override";
dbg() << " {"; out() << " {";
dbg() << " switch (message.message_id()) {"; out() << " switch (message.message_id()) {";
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
auto do_decode_message = [&](const String& name, bool returns_something) { auto do_decode_message = [&](const String& name, bool returns_something) {
dbg() << " case (int)Messages::" << endpoint.name << "::MessageID::" << name << ":"; out() << " case (int)Messages::" << endpoint.name << "::MessageID::" << name << ":";
if (returns_something) { if (returns_something) {
dbg() << " return handle(static_cast<const Messages::" << endpoint.name << "::" << name << "&>(message));"; out() << " return handle(static_cast<const Messages::" << endpoint.name << "::" << name << "&>(message));";
} else { } else {
dbg() << " handle(static_cast<const Messages::" << endpoint.name << "::" << name << "&>(message));"; out() << " handle(static_cast<const Messages::" << endpoint.name << "::" << name << "&>(message));";
dbg() << " return nullptr;"; out() << " return nullptr;";
} }
}; };
do_decode_message(message.name, message.is_synchronous); do_decode_message(message.name, message.is_synchronous);
if (message.is_synchronous) if (message.is_synchronous)
do_decode_message(message.response_name(), false); do_decode_message(message.response_name(), false);
} }
dbg() << " default:"; out() << " default:";
dbg() << " return nullptr;"; out() << " return nullptr;";
dbg() << " }"; out() << " }";
dbg() << " }"; out() << " }";
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
String return_type = "void"; String return_type = "void";
@ -470,30 +470,30 @@ int main(int argc, char** argv)
builder.append(">"); builder.append(">");
return_type = builder.to_string(); return_type = builder.to_string();
} }
dbg() << " virtual " << return_type << " handle(const Messages::" << endpoint.name << "::" << message.name << "&) = 0;"; out() << " virtual " << return_type << " handle(const Messages::" << endpoint.name << "::" << message.name << "&) = 0;";
} }
dbg() << "private:"; out() << "private:";
dbg() << "};"; out() << "};";
} }
#ifdef DEBUG #ifdef DEBUG
for (auto& endpoint : endpoints) { for (auto& endpoint : endpoints) {
dbg() << "Endpoint: '" << endpoint.name << "' (magic: " << endpoint.magic << ")"; warn() << "Endpoint: '" << endpoint.name << "' (magic: " << endpoint.magic << ")";
for (auto& message : endpoint.messages) { for (auto& message : endpoint.messages) {
dbg() << " Message: '" << message.name << "'"; warn() << " Message: '" << message.name << "'";
dbg() << " Sync: " << message.is_synchronous; warn() << " Sync: " << message.is_synchronous;
dbg() << " Inputs:"; warn() << " Inputs:";
for (auto& parameter : message.inputs) for (auto& parameter : message.inputs)
dbg() << " Parameter: " << parameter.name << " (" << parameter.type << ")"; warn() << " Parameter: " << parameter.name << " (" << parameter.type << ")";
if (message.inputs.is_empty()) if (message.inputs.is_empty())
dbg() << " (none)"; warn() << " (none)";
if (message.is_synchronous) { if (message.is_synchronous) {
dbg() << " Outputs:"; warn() << " Outputs:";
for (auto& parameter : message.outputs) for (auto& parameter : message.outputs)
dbg() << " Parameter: " << parameter.name << " (" << parameter.type << ")"; warn() << " Parameter: " << parameter.name << " (" << parameter.type << ")";
if (message.outputs.is_empty()) if (message.outputs.is_empty())
dbg() << " (none)"; warn() << " (none)";
} }
} }
} }

View file

@ -58,36 +58,36 @@ int main(int argc, char** argv)
auto json = JsonValue::from_string(file->read_all()); auto json = JsonValue::from_string(file->read_all());
ASSERT(json.is_object()); ASSERT(json.is_object());
dbg() << "#include <AK/Assertions.h>"; out() << "#include <AK/Assertions.h>";
dbg() << "#include <LibWeb/CSS/PropertyID.h>"; out() << "#include <LibWeb/CSS/PropertyID.h>";
dbg() << "namespace Web {"; out() << "namespace Web {";
dbg() << "namespace CSS {"; out() << "namespace CSS {";
dbg() << "PropertyID property_id_from_string(const StringView& string) {"; out() << "PropertyID property_id_from_string(const StringView& string) {";
json.as_object().for_each_member([&](auto& name, auto& value) { json.as_object().for_each_member([&](auto& name, auto& value) {
ASSERT(value.is_object()); ASSERT(value.is_object());
dbg() << " if (string == \"" << name << "\")"; out() << " if (string == \"" << name << "\")";
dbg() << " return PropertyID::" << title_casify(name) << ";"; out() << " return PropertyID::" << title_casify(name) << ";";
}); });
dbg() << " return PropertyID::Invalid;"; out() << " return PropertyID::Invalid;";
dbg() << "}"; out() << "}";
dbg() << "const char* string_from_property_id(PropertyID property_id) {"; out() << "const char* string_from_property_id(PropertyID property_id) {";
dbg() << " switch (property_id) {"; out() << " switch (property_id) {";
json.as_object().for_each_member([&](auto& name, auto& value) { json.as_object().for_each_member([&](auto& name, auto& value) {
ASSERT(value.is_object()); ASSERT(value.is_object());
dbg() << " case PropertyID::" << title_casify(name) << ":"; out() << " case PropertyID::" << title_casify(name) << ":";
dbg() << " return \"" << name << "\";"; out() << " return \"" << name << "\";";
}); });
dbg() << " default:"; out() << " default:";
dbg() << " return \"(invalid CSS::PropertyID)\";"; out() << " return \"(invalid CSS::PropertyID)\";";
dbg() << " }"; out() << " }";
dbg() << "}"; out() << "}";
dbg() << "}"; out() << "}";
dbg() << "}"; out() << "}";
return 0; return 0;
} }

View file

@ -58,21 +58,21 @@ int main(int argc, char** argv)
auto json = JsonValue::from_string(file->read_all()); auto json = JsonValue::from_string(file->read_all());
ASSERT(json.is_object()); ASSERT(json.is_object());
dbg() << "#pragma once"; out() << "#pragma once";
dbg() << "#include <AK/StringView.h>"; out() << "#include <AK/StringView.h>";
dbg() << "#include <AK/Traits.h>"; out() << "#include <AK/Traits.h>";
dbg() << "namespace Web {"; out() << "namespace Web {";
dbg() << "namespace CSS {"; out() << "namespace CSS {";
dbg() << "enum class PropertyID {"; out() << "enum class PropertyID {";
dbg() << " Invalid,"; out() << " Invalid,";
json.as_object().for_each_member([&](auto& name, auto& value) { json.as_object().for_each_member([&](auto& name, auto& value) {
ASSERT(value.is_object()); ASSERT(value.is_object());
dbg() << " " << title_casify(name) << ","; out() << " " << title_casify(name) << ",";
}); });
dbg() << "};\n\ out() << "};\n\
PropertyID property_id_from_string(const StringView&);\n\ PropertyID property_id_from_string(const StringView&);\n\
const char* string_from_property_id(PropertyID);\n\ const char* string_from_property_id(PropertyID);\n\
}\n\ }\n\