mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 23:53:55 +00:00
@ -17,9 +17,13 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/console.h>
|
||||
#include <base/stdint.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/output.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
@ -138,93 +142,6 @@ class Format_command
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert digit to ASCII value
|
||||
*/
|
||||
static char ascii(int digit, int uppercase = 0)
|
||||
{
|
||||
if (digit > 9)
|
||||
return digit + (uppercase ? 'A' : 'a') - 10;
|
||||
|
||||
return digit + '0';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output signed value with the specified base
|
||||
*/
|
||||
template <typename T>
|
||||
void Console::_out_signed(T value, unsigned base)
|
||||
{
|
||||
/**
|
||||
* for base 8, the number of digits is the number of value bytes times 3
|
||||
* at a max, because 0xff is 0o377 and accumulating this implies a
|
||||
* strictly decreasing factor
|
||||
*/
|
||||
char buf[sizeof(value)*3];
|
||||
|
||||
/* set flag if value is negative */
|
||||
int neg = value < 0 ? 1 : 0;
|
||||
|
||||
/* get absolute value */
|
||||
value = value < 0 ? -value : value;
|
||||
|
||||
int i = 0;
|
||||
|
||||
/* handle zero as special case */
|
||||
if (value == 0)
|
||||
buf[i++] = ascii(0);
|
||||
|
||||
/* fill buffer starting with the least significant digits */
|
||||
else
|
||||
for (; value > 0; value /= base)
|
||||
buf[i++] = ascii(value % base);
|
||||
|
||||
/* add sign to buffer for negative values */
|
||||
if (neg)
|
||||
_out_char('-');
|
||||
|
||||
/* output buffer in reverse order */
|
||||
for (; i--; )
|
||||
_out_char(buf[i]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Output unsigned value with the specified base and padding
|
||||
*/
|
||||
template <typename T>
|
||||
void Console::_out_unsigned(T value, unsigned base, int pad)
|
||||
{
|
||||
/**
|
||||
* for base 8, the number of digits is the number of value bytes times 3
|
||||
* at a max, because 0xff is 0o377 and accumulating this implies a
|
||||
* strictly decreasing factor
|
||||
*/
|
||||
char buf[sizeof(value)*3];
|
||||
|
||||
int i = 0;
|
||||
|
||||
/* handle zero as special case */
|
||||
if (value == 0) {
|
||||
buf[i++] = ascii(0);
|
||||
pad--;
|
||||
}
|
||||
|
||||
/* fill buffer starting with the least significant digits */
|
||||
for (; value > 0; value /= base, pad--)
|
||||
buf[i++] = ascii(value % base);
|
||||
|
||||
/* add padding zeros */
|
||||
for (; pad-- > 0; )
|
||||
_out_char(ascii(0));
|
||||
|
||||
/* output buffer in reverse order */
|
||||
for (; i--; )
|
||||
_out_char(buf[i]);
|
||||
}
|
||||
|
||||
|
||||
void Console::_out_string(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
@ -292,15 +209,18 @@ void Console::vprintf(const char *format, va_list list)
|
||||
case Format_command::INT:
|
||||
|
||||
if (cmd.length == Format_command::LONG_LONG)
|
||||
_out_signed<long long>(numeric_arg, cmd.base);
|
||||
out_signed<long long>(numeric_arg, cmd.base,
|
||||
[&] (char c) { _out_char(c); });
|
||||
else
|
||||
_out_signed<long>(numeric_arg, cmd.base);
|
||||
out_signed<long>(numeric_arg, cmd.base,
|
||||
[&] (char c) { _out_char(c); });
|
||||
break;
|
||||
|
||||
case Format_command::UINT:
|
||||
|
||||
if (cmd.length == Format_command::LONG_LONG) {
|
||||
_out_unsigned<unsigned long long>(numeric_arg, cmd.base, cmd.padding);
|
||||
out_unsigned<unsigned long long>(numeric_arg, cmd.base, cmd.padding,
|
||||
[&] (char c) { _out_char(c); });
|
||||
break;
|
||||
}
|
||||
|
||||
@ -308,7 +228,8 @@ void Console::vprintf(const char *format, va_list list)
|
||||
|
||||
case Format_command::PTR:
|
||||
|
||||
_out_unsigned<unsigned long>(numeric_arg, cmd.base, cmd.padding);
|
||||
out_unsigned<unsigned long>(numeric_arg, cmd.base, cmd.padding,
|
||||
[&] (char c) { _out_char(c); });
|
||||
break;
|
||||
|
||||
case Format_command::CHAR:
|
||||
|
51
repos/base/src/lib/base/default_log.cc
Normal file
51
repos/base/src/lib/base/default_log.cc
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Access to the component's LOG session
|
||||
* \author Norman Feske
|
||||
* \date 2016-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <log_session/log_session.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/globals.h>
|
||||
#include <base/internal/output.h>
|
||||
#include <base/internal/unmanaged_singleton.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static Log *log_ptr;
|
||||
|
||||
|
||||
Log &Log::log() { return *log_ptr; }
|
||||
|
||||
|
||||
extern "C" int stdout_write(const char *s);
|
||||
|
||||
|
||||
void Genode::init_log()
|
||||
{
|
||||
/* ignore subsequent calls */
|
||||
if (log_ptr)
|
||||
return;
|
||||
|
||||
struct Write_fn { void operator () (char const *s) { stdout_write(s); } };
|
||||
|
||||
typedef Buffered_output<Log_session::MAX_STRING_LEN, Write_fn>
|
||||
Buffered_log_output;
|
||||
|
||||
static Buffered_log_output *buffered_log_output =
|
||||
unmanaged_singleton<Buffered_log_output>(Write_fn());
|
||||
|
||||
log_ptr = unmanaged_singleton<Log>(*buffered_log_output);
|
||||
}
|
||||
|
44
repos/base/src/lib/base/log.cc
Normal file
44
repos/base/src/lib/base/log.cc
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Access to the component's LOG session
|
||||
* \author Norman Feske
|
||||
* \date 2016-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Log::_acquire(Type type)
|
||||
{
|
||||
_lock.lock();
|
||||
|
||||
/*
|
||||
* Mark warnings and errors via distinct colors.
|
||||
*/
|
||||
switch (type) {
|
||||
case LOG: break;
|
||||
case WARNING: _output.out_string("\033[34mWarning: "); break;
|
||||
case ERROR: _output.out_string("\033[31mError: "); break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void Log::_release()
|
||||
{
|
||||
/*
|
||||
* Reset color and add newline
|
||||
*/
|
||||
_output.out_string("\033[0m\n");
|
||||
|
||||
_lock.unlock();
|
||||
}
|
||||
|
83
repos/base/src/lib/base/output.cc
Normal file
83
repos/base/src/lib/base/output.cc
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* \brief Textual output functions
|
||||
* \author Norman Feske
|
||||
* \date 2016-05-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/output.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/output.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/************
|
||||
** Output **
|
||||
************/
|
||||
|
||||
void Output::out_string(char const *str, size_t n)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
while (*str && n--) out_char(*str++);
|
||||
}
|
||||
|
||||
|
||||
/******************************
|
||||
** Print function overloads **
|
||||
******************************/
|
||||
|
||||
void Genode::print(Output &output, char const *str)
|
||||
{
|
||||
if (!str)
|
||||
output.out_string("<null-string>");
|
||||
else
|
||||
while (*str) output.out_char(*str++);
|
||||
}
|
||||
|
||||
|
||||
void Genode::print(Output &output, void const *ptr)
|
||||
{
|
||||
print(output, Hex(reinterpret_cast<addr_t>(ptr)));
|
||||
}
|
||||
|
||||
|
||||
void Genode::print(Output &output, unsigned long value)
|
||||
{
|
||||
out_unsigned<unsigned long>(value, 10, 0, [&] (char c) { output.out_char(c); });
|
||||
}
|
||||
|
||||
|
||||
void Genode::print(Output &output, long value)
|
||||
{
|
||||
out_signed<long>(value, 10, [&] (char c) { output.out_char(c); });
|
||||
}
|
||||
|
||||
|
||||
void Genode::print(Output &output, long long value)
|
||||
{
|
||||
out_signed<long long>(value, 10, [&] (char c) { output.out_char(c); });
|
||||
}
|
||||
|
||||
|
||||
void Genode::print(Output &output, Hex const &value)
|
||||
{
|
||||
if (value.prefix == Hex::PREFIX)
|
||||
output.out_string("0x");
|
||||
|
||||
size_t const pad_len = value.pad ? value.digits : 0;
|
||||
|
||||
out_unsigned<unsigned long>(value.value, 16, pad_len,
|
||||
[&] (char c) { output.out_char(c); });
|
||||
}
|
||||
|
@ -19,8 +19,12 @@
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/globals.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
addr_t init_main_thread_result;
|
||||
|
||||
extern void init_exception_handling();
|
||||
@ -89,6 +93,7 @@ extern "C" void init_main_thread()
|
||||
* destructor won't be registered for the atexit routine.
|
||||
*/
|
||||
(void*)env();
|
||||
init_log();
|
||||
|
||||
/* initialize exception handling */
|
||||
init_exception_handling();
|
||||
|
Reference in New Issue
Block a user