Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4225 → Rev 4226

/trunk/kernel/generic/src/console/console.c
53,10 → 53,11
#include <string.h>
 
#define KLOG_SIZE PAGE_SIZE
#define KLOG_LENGTH (KLOG_SIZE / sizeof(wchar_t))
#define KLOG_LATENCY 8
 
/** Kernel log cyclic buffer */
static wchar_t klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
static wchar_t klog[KLOG_LENGTH] __attribute__ ((aligned (PAGE_SIZE)));
 
/** Kernel log initialized */
static bool klog_inited = false;
257,16 → 258,16
/* Print charaters stored in kernel log */
index_t i;
for (i = klog_len - klog_stored; i < klog_len; i++)
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE], silent);
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
klog_stored = 0;
}
/* Store character in the cyclic kernel log */
klog[(klog_start + klog_len) % KLOG_SIZE] = ch;
if (klog_len < KLOG_SIZE)
klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
if (klog_len < KLOG_LENGTH)
klog_len++;
else
klog_start = (klog_start + 1) % KLOG_SIZE;
klog_start = (klog_start + 1) % KLOG_LENGTH;
if ((stdout) && (stdout->op->write))
stdout->op->write(stdout, ch, silent);
/trunk/uspace/app/klog/klog.c
47,10 → 47,11
 
#define NAME "klog"
 
#define KLOG_SIZE PAGE_SIZE
#define KLOG_SIZE PAGE_SIZE
#define KLOG_LENGTH (KLOG_SIZE / sizeof(wchar_t))
 
/* Pointer to klog area */
static char *klog;
static wchar_t *klog;
 
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
{
61,7 → 62,7
size_t klog_stored = (size_t) IPC_GET_ARG3(*call);
size_t i;
for (i = klog_len - klog_stored; i < klog_len; i++)
putchar(klog[(klog_start + i) % KLOG_SIZE]);
putchar(klog[(klog_start + i) % KLOG_LENGTH]);
async_serialize_end();
}
/trunk/uspace/lib/libc/include/string.h
37,7 → 37,15
 
#include <mem.h>
#include <sys/types.h>
#include <bool.h>
 
#define U_SPECIAL '?'
 
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz);
 
extern bool chr_check(const wchar_t ch);
 
extern int strcmp(const char *, const char *);
extern int strncmp(const char *, const char *, size_t);
extern int stricmp(const char *, const char *);
/trunk/uspace/lib/libc/generic/console.c
61,7 → 61,7
 
static void cbuffer_flush(void);
static void cbuffer_drain(void);
static void cbuffer_putc(int c);
static inline void cbuffer_putc(int c);
 
 
void console_open(bool blocking)
/trunk/uspace/lib/libc/generic/string.c
38,7 → 38,173
#include <limits.h>
#include <ctype.h>
#include <malloc.h>
#include <errno.h>
#include <string.h>
 
/** Byte mask consisting of lowest @n bits (out of 8) */
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of lowest @n bits (out of 32) */
#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of highest @n bits (out of 8) */
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
 
/** Number of data bits in a UTF-8 continuation byte */
#define CONT_BITS 6
 
/** Decode a single character from a string.
*
* Decode a single character from a string of size @a size. Decoding starts
* at @a offset and this offset is moved to the beginning of the next
* character. In case of decoding error, offset generally advances at least
* by one. However, offset is never moved beyond size.
*
* @param str String (not necessarily NULL-terminated).
* @param offset Byte offset in string where to start decoding.
* @param size Size of the string (in bytes).
*
* @return Value of decoded character, U_SPECIAL on decoding error or
* NULL if attempt to decode beyond @a size.
*
*/
wchar_t str_decode(const char *str, size_t *offset, size_t size)
{
if (*offset + 1 > size)
return 0;
/* First byte read from string */
uint8_t b0 = (uint8_t) str[(*offset)++];
/* Determine code length */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((b0 & 0x80) == 0) {
/* 0xxxxxxx (Plain ASCII) */
b0_bits = 7;
cbytes = 0;
} else if ((b0 & 0xe0) == 0xc0) {
/* 110xxxxx 10xxxxxx */
b0_bits = 5;
cbytes = 1;
} else if ((b0 & 0xf0) == 0xe0) {
/* 1110xxxx 10xxxxxx 10xxxxxx */
b0_bits = 4;
cbytes = 2;
} else if ((b0 & 0xf8) == 0xf0) {
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
b0_bits = 3;
cbytes = 3;
} else {
/* 10xxxxxx -- unexpected continuation byte */
return U_SPECIAL;
}
if (*offset + cbytes > size)
return U_SPECIAL;
wchar_t ch = b0 & LO_MASK_8(b0_bits);
/* Decode continuation bytes */
while (cbytes > 0) {
uint8_t b = (uint8_t) str[(*offset)++];
/* Must be 10xxxxxx */
if ((b & 0xc0) != 0x80)
return U_SPECIAL;
/* Shift data bits to ch */
ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
cbytes--;
}
return ch;
}
 
/** Encode a single character to string representation.
*
* Encode a single character to string representation (i.e. UTF-8) and store
* it into a buffer at @a offset. Encoding starts at @a offset and this offset
* is moved to the position where the next character can be written to.
*
* @param ch Input character.
* @param str Output buffer.
* @param offset Byte offset where to start writing.
* @param size Size of the output buffer (in bytes).
*
* @return EOK if the character was encoded successfully, EOVERFLOW if there
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
*/
int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size)
{
if (*offset >= size)
return EOVERFLOW;
if (!chr_check(ch))
return EINVAL;
/* Unsigned version of ch (bit operations should only be done
on unsigned types). */
uint32_t cc = (uint32_t) ch;
/* Determine how many continuation bytes are needed */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((cc & ~LO_MASK_32(7)) == 0) {
b0_bits = 7;
cbytes = 0;
} else if ((cc & ~LO_MASK_32(11)) == 0) {
b0_bits = 5;
cbytes = 1;
} else if ((cc & ~LO_MASK_32(16)) == 0) {
b0_bits = 4;
cbytes = 2;
} else if ((cc & ~LO_MASK_32(21)) == 0) {
b0_bits = 3;
cbytes = 3;
} else {
/* Codes longer than 21 bits are not supported */
return EINVAL;
}
/* Check for available space in buffer */
if (*offset + cbytes >= size)
return EOVERFLOW;
/* Encode continuation bytes */
unsigned int i;
for (i = cbytes; i > 0; i--) {
str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
cc = cc >> CONT_BITS;
}
/* Encode first byte */
str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
/* Advance offset */
*offset += cbytes + 1;
return EOK;
}
 
/** Check whether character is valid
*
* @return True if character is a valid Unicode code point.
*
*/
bool chr_check(const wchar_t ch)
{
if ((ch >= 0) && (ch <= 1114111))
return true;
return false;
}
 
/** Count the number of characters in the string, not including terminating 0.
*
* @param str String.
/trunk/uspace/srv/console/console.c
48,6 → 48,7
#include <screenbuffer.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <sysinfo.h>
#include <event.h>
 
465,25 → 466,28
static void cons_write(int consnum, ipc_callid_t rid, ipc_call_t *request)
{
ipc_callid_t callid;
size_t len;
size_t i;
size_t size;
wchar_t ch;
size_t off;
 
if (!ipc_data_write_receive(&callid, &len)) {
if (!ipc_data_write_receive(&callid, &size)) {
ipc_answer_0(callid, EINVAL);
ipc_answer_0(rid, EINVAL);
}
 
if (len > CWRITE_BUF_SIZE)
len = CWRITE_BUF_SIZE;
if (size > CWRITE_BUF_SIZE)
size = CWRITE_BUF_SIZE;
 
(void) ipc_data_write_finalize(callid, cwrite_buf, len);
(void) ipc_data_write_finalize(callid, cwrite_buf, size);
 
for (i = 0; i < len; i++) {
write_char(consnum, cwrite_buf[i]);
off = 0;
while (off < size) {
ch = str_decode(cwrite_buf, &off, size);
write_char(consnum, ch);
}
 
gcons_notify_char(consnum);
ipc_answer_1(rid, EOK, len);
ipc_answer_1(rid, EOK, size);
}
 
/** Default thread for new connections */
/trunk/uspace/srv/fb/fb.c
68,6 → 68,8
#define DEFAULT_BGCOLOR 0xf0f0f0
#define DEFAULT_FGCOLOR 0x000000
 
#define GLYPH_UNAVAIL '?'
 
#define MAX_ANIM_LEN 8
#define MAX_ANIMATIONS 4
#define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */
78,7 → 80,7
 
/** Function to draw a glyph. */
typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor,
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color);
uint8_t *glyphs, uint32_t glyph, uint32_t fg_color, uint32_t bg_color);
 
struct {
uint8_t *fb_addr;
669,7 → 671,7
 
/* Check glyph range. */
if (glyph >= FONT_GLYPHS)
return;
glyph = GLYPH_UNAVAIL;
 
/*
* Prepare a pair of words, one filled with foreground-color
733,7 → 735,7
 
/* Check glyph range. */
if (glyph >= FONT_GLYPHS)
return;
glyph = GLYPH_UNAVAIL;
 
/* Pre-render 1x the foreground and background color pixels. */
if (cursor) {