Pushing bugs
This commit is contained in:
parent
a362655af2
commit
241eeb64cb
|
@ -34,15 +34,16 @@
|
||||||
//
|
//
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
BF_LINE = 1, // Line-buffered
|
BF_TERM = 1, // Terminal buffer
|
||||||
BF_FILE = 1<<1, // Linked to a file
|
BF_LINE = 1<<1, // Line-buffered
|
||||||
BF_BALLOC = 1<<2, // Buffer structure was malloc'd
|
BF_FILE = 1<<2, // Linked to a file
|
||||||
BF_SALLOC = 1<<3, // Internal buffer was malloc'd
|
BF_BALLOC = 1<<3, // Buffer structure was malloc'd
|
||||||
BF_FONCLOSE = 1<<4, // Flush on close
|
BF_SALLOC = 1<<4, // Internal buffer was malloc'd
|
||||||
BF_AUTOSCROLL = 1<<5, // Scroll-down automatically
|
BF_FONCLOSE = 1<<5, // Flush on close
|
||||||
|
BF_AUTOSCROLL = 1<<6, // Scroll-down automatically
|
||||||
|
|
||||||
BF_EOF = 1<<6, // End of file reached
|
BF_EOF = 1<<7, // End of file reached
|
||||||
BF_ERR = 1<<7, // An error happened
|
BF_ERR = 1<<8, // An error happened
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -61,7 +62,7 @@ enum
|
||||||
typedef struct Buffer_t Buffer_t;
|
typedef struct Buffer_t Buffer_t;
|
||||||
|
|
||||||
//
|
//
|
||||||
// For line buffers, the flusher by bputc() is called every '\n'
|
// For line/terminal buffers, the flusher by bputc() is called every '\n'
|
||||||
// For pure buffers, the flusher is called by bputc() after it fills
|
// For pure buffers, the flusher is called by bputc() after it fills
|
||||||
// the buffer (unless flush-on-close is enabled)
|
// the buffer (unless flush-on-close is enabled)
|
||||||
//
|
//
|
||||||
|
@ -90,7 +91,7 @@ struct Buffer_t
|
||||||
|
|
||||||
BFlusher_t flusher; // See above
|
BFlusher_t flusher; // See above
|
||||||
|
|
||||||
// The following parameters are only used in line buf mode
|
// The following parameters are only used in terminal buf mode
|
||||||
|
|
||||||
int lastLF; // Characters since beginning of line
|
int lastLF; // Characters since beginning of line
|
||||||
int lineLen; // Line length (for line buffers)
|
int lineLen; // Line length (for line buffers)
|
||||||
|
@ -98,14 +99,16 @@ struct Buffer_t
|
||||||
// size/(lineLen*nLines) - 1 playback buffers
|
// size/(lineLen*nLines) - 1 playback buffers
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Buffer_t *BStdOut, *BStdDbg;
|
extern Buffer_t *BStdIn, *BStdOut, *BStdDbg;
|
||||||
|
|
||||||
error_t BCloseBuf(Buffer_t *);
|
// For pure buffers only
|
||||||
void BFlushOnClose(Buffer_t *);
|
void BEnableLineBuffering(Buffer_t *);
|
||||||
|
void BDisaleLineBuffering(Buffer_t *);
|
||||||
|
|
||||||
|
// For terminal buffers only
|
||||||
|
error_t BScrollDownBuf(Buffer_t *);
|
||||||
void BEnableAutoScroll(Buffer_t *);
|
void BEnableAutoScroll(Buffer_t *);
|
||||||
void BDisableAutoScroll(Buffer_t *);
|
void BDisableAutoScroll(Buffer_t *);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Buffer creation functions
|
// Buffer creation functions
|
||||||
//
|
//
|
||||||
|
@ -116,34 +119,32 @@ void BDisableAutoScroll(Buffer_t *);
|
||||||
// If source==NULL, malloc's the buffer
|
// If source==NULL, malloc's the buffer
|
||||||
// BCloseBuf() handles the de-allocations
|
// BCloseBuf() handles the de-allocations
|
||||||
//
|
//
|
||||||
|
error_t BCloseBuf(Buffer_t *);
|
||||||
|
|
||||||
// Creates a pure buffer of a given size
|
// Creates a pure buffer of a given size
|
||||||
error_t BOpenPureBuf(Buffer_t **pbuf, int mode, size_t size);
|
error_t BOpenPureBuf(Buffer_t **pbuf, int mode, size_t size);
|
||||||
error_t BOpenPureBufEx(Buffer_t **, char *source, int mode, size_t,
|
error_t BOpenPureBufEx(Buffer_t **, char *source, int mode, size_t,
|
||||||
BFlusher_t);
|
BFlusher_t);
|
||||||
|
|
||||||
// Creates a lined buffer of pbCount*nLines lines each
|
// Creates a terminal buffer of pbCount*nLines lines each
|
||||||
// of lineLen length (pb = playback buffer, for scrolling up)
|
// of lineLen length (pb = playback buffer, for scrolling up)
|
||||||
error_t BOpenLineBuf(Buffer_t **pbuf, int mode,
|
error_t BOpenTermBuf(Buffer_t **pbuf, int mode,
|
||||||
int lineLen, int nLines, int pbCount);
|
int lineLen, int nLines, int pbCount);
|
||||||
error_t BOpenLineBufEx(Buffer_t **pbuf, char *source, int mode,
|
error_t BOpenTermBufEx(Buffer_t **pbuf, char *source, int mode,
|
||||||
int lineLen, int nLines, int pbCount, BFlusher_t);
|
int lineLen, int nLines, int pbCount, BFlusher_t);
|
||||||
|
|
||||||
int BGetFlags(Buffer_t *);
|
int BGetFlags(Buffer_t *);
|
||||||
int BGetState(Buffer_t *);
|
int BGetState(Buffer_t *);
|
||||||
int BGetLineLen(Buffer_t *);
|
|
||||||
void BSetLineLen(Buffer_t *, int);
|
error_t BFlushBuf(Buffer_t *);
|
||||||
|
error_t BPutOnBuf(Buffer_t *, uchar);
|
||||||
|
error_t BPrintOnBuf(Buffer_t *, const char *fmt, ...);
|
||||||
|
error_t BPrintOnBufV(Buffer_t *, const char *fmt, va_list);
|
||||||
|
|
||||||
void BLockBuf(Buffer_t *);
|
void BLockBuf(Buffer_t *);
|
||||||
void BUnlockBuf(Buffer_t *);
|
void BUnlockBuf(Buffer_t *);
|
||||||
bool BTrylockBuf(Buffer_t *);
|
bool BTrylockBuf(Buffer_t *);
|
||||||
|
|
||||||
error_t BFlushBuf(Buffer_t *);
|
|
||||||
error_t BScrollDownBuf(Buffer_t *);
|
|
||||||
error_t BPutOnBuf(Buffer_t *, uchar);
|
|
||||||
error_t BPrintOnBuf(Buffer_t *, const char *fmt, ...);
|
|
||||||
error_t BPrintOnBufV(Buffer_t *, const char *fmt, va_list);
|
|
||||||
|
|
||||||
// Internal, non-locking functions; don't use unless you
|
// Internal, non-locking functions; don't use unless you
|
||||||
// have a good reason why
|
// have a good reason why
|
||||||
error_t bputc(Buffer_t *buf, uchar ch);
|
error_t bputc(Buffer_t *buf, uchar ch);
|
||||||
|
|
|
@ -170,6 +170,14 @@ noreturn void KeStartPanic(const char *, ...);
|
||||||
#define BUG() XBUG('B')
|
#define BUG() XBUG('B')
|
||||||
#define BUGON(x) if(x)BUG()
|
#define BUGON(x) if(x)BUG()
|
||||||
|
|
||||||
|
#define __GET_GETRIP() \
|
||||||
|
__attribute__((__noinline__)) \
|
||||||
|
static ulong __getrip() \
|
||||||
|
{ return (size_t)__builtin_return_address(0); }
|
||||||
|
|
||||||
|
#define __PRINT_RIP() \
|
||||||
|
DebugLog("%s.RIP=%p\n",__func__,__getrip())
|
||||||
|
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,9 @@
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
// Address of the heap
|
// Address of the heap
|
||||||
void *_heap_start;
|
extern void *_heap_start;
|
||||||
|
extern void *_heap_end;
|
||||||
|
extern size_t _heap_max;
|
||||||
|
|
||||||
void MmInitHeap(void);
|
void MmInitHeap(void);
|
||||||
|
|
||||||
|
|
|
@ -75,22 +75,22 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
|
||||||
|
|
||||||
// Several inits
|
// Several inits
|
||||||
MmInitHeap();
|
MmInitHeap();
|
||||||
PsInitSched();
|
//PsInitSched();
|
||||||
|
|
||||||
// Interrupts launching
|
// Interrupts launching
|
||||||
IdtSetup();
|
IdtSetup();
|
||||||
KeEnableIRQs();
|
KeEnableIRQs();
|
||||||
|
|
||||||
// Drivers enabling
|
// Drivers enabling
|
||||||
IoEnableRtc();
|
IoEnableRtc();
|
||||||
IoEnableKeyb();
|
IoEnableKeyb();
|
||||||
|
|
||||||
|
IoGetRtcTimeChar();
|
||||||
IoPrintRtcTime();
|
IoPrintRtcTime();
|
||||||
|
// IoDoStarWars();
|
||||||
IoDoStarWars();
|
|
||||||
|
|
||||||
KernLog("Goodbye at %s\n", IoGetRtcTimeChar());
|
KernLog("Goodbye at %s\n", IoGetRtcTimeChar());
|
||||||
|
|
||||||
// End this machine's suffering
|
// End this machine's suffering
|
||||||
BStdOut->flusher(BStdOut);
|
BFlushBuf(BStdOut);
|
||||||
KeCrashSystem();
|
KeCrashSystem();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ char ScanCodes[100] = { 0 };
|
||||||
void KeybPrint(char code)
|
void KeybPrint(char code)
|
||||||
{
|
{
|
||||||
if (code) {
|
if (code) {
|
||||||
bprintf(BStdOut, "%c", ScanCodes[(int)code]);
|
bputc(BStdOut, ScanCodes[(int)code]);
|
||||||
//bprintf(BStdOut, "%x ", code);
|
//bprintf(BStdOut, "%x ", code);
|
||||||
BStdOut->flusher(BStdOut);
|
BStdOut->flusher(BStdOut);
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,8 @@ void ScanCodesInit(void)
|
||||||
ScanCodes[0x0B] = '0';
|
ScanCodes[0x0B] = '0';
|
||||||
ScanCodes[0x0C] = ' ';
|
ScanCodes[0x0C] = ' ';
|
||||||
ScanCodes[0x0D] = '+';
|
ScanCodes[0x0D] = '+';
|
||||||
ScanCodes[0x0E] = ' ';
|
ScanCodes[0x0E] = 0x8;
|
||||||
|
ScanCodes[0x0F] = '\t';
|
||||||
|
|
||||||
ScanCodes[0x10] = 'a';
|
ScanCodes[0x10] = 'a';
|
||||||
ScanCodes[0x11] = 'z';
|
ScanCodes[0x11] = 'z';
|
||||||
|
@ -113,13 +114,29 @@ void KeybHandler(ISRFrame_t *regs)
|
||||||
IoSendEOItoPIC(0x21);
|
IoSendEOItoPIC(0x21);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IoCreateInputBuffer(void)
|
||||||
|
{
|
||||||
|
error_t rc;
|
||||||
|
|
||||||
|
rc = BOpenPureBuf(&BStdIn, BS_RDWR, 4 * KB);
|
||||||
|
|
||||||
|
if (rc) KeStartPanic("Couldn't create BStdIn");
|
||||||
|
|
||||||
|
BEnableLineBuffering(BStdIn);
|
||||||
|
}
|
||||||
|
|
||||||
void IoEnableKeyb(void)
|
void IoEnableKeyb(void)
|
||||||
{
|
{
|
||||||
ulong flags = KePauseIRQs();
|
ulong flags = KePauseIRQs();
|
||||||
|
|
||||||
IdtRegisterIsr(KeybHandler, 0x21);
|
IdtRegisterIsr(KeybHandler, 0x21);
|
||||||
char readedInterruptConfig = IoReadByteFromPort(0x21);
|
char readedInterruptConfig = IoReadByteFromPort(0x21);
|
||||||
IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
|
IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
|
||||||
|
|
||||||
KeRestoreIRQs(flags);
|
KeRestoreIRQs(flags);
|
||||||
|
|
||||||
IoEnableNMI();
|
IoEnableNMI();
|
||||||
ScanCodesInit();
|
ScanCodesInit();
|
||||||
|
|
||||||
|
IoCreateInputBuffer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,7 +164,8 @@ void IoPrintRtcTime(void)
|
||||||
char* IoGetRtcTimeChar(void)
|
char* IoGetRtcTimeChar(void)
|
||||||
{
|
{
|
||||||
Time_t *RtcTime = IoGetRtcTime();
|
Time_t *RtcTime = IoGetRtcTime();
|
||||||
sprintf(IoTimeChar, "%hhd/%hhd/%hd ; %hhd:%hhd:%hhd",
|
snprintf(IoTimeChar, sizeof(IoTimeChar),
|
||||||
|
"%02d/%02d/%02d ; %02d:%02d:%02d",
|
||||||
RtcTime->day,
|
RtcTime->day,
|
||||||
RtcTime->month,
|
RtcTime->month,
|
||||||
RtcTime->year + RtcTime->century*100,
|
RtcTime->year + RtcTime->century*100,
|
||||||
|
|
|
@ -90,7 +90,7 @@ error_t IoInitVGABuffer(void)
|
||||||
|
|
||||||
BStdOut = &bvgabufstruct;
|
BStdOut = &bvgabufstruct;
|
||||||
|
|
||||||
BOpenLineBufEx(&BStdOut,
|
BOpenTermBufEx(&BStdOut,
|
||||||
bvgabufsrc, BS_WRONLY,
|
bvgabufsrc, BS_WRONLY,
|
||||||
BtVideoInfo.framebufferWidth,
|
BtVideoInfo.framebufferWidth,
|
||||||
BtVideoInfo.framebufferHeight,
|
BtVideoInfo.framebufferHeight,
|
||||||
|
|
|
@ -26,11 +26,14 @@
|
||||||
#include <kernel/heap.h>
|
#include <kernel/heap.h>
|
||||||
#include <extras/locks.h>
|
#include <extras/locks.h>
|
||||||
|
|
||||||
// Least address out of the heap
|
// Start address of the heap
|
||||||
static void *_heap_end;
|
void *_heap_start;
|
||||||
|
|
||||||
|
// End of the heap
|
||||||
|
/*static*/ void *_heap_end;
|
||||||
|
|
||||||
// Maximal value of the heap
|
// Maximal value of the heap
|
||||||
static size_t _heap_max;
|
/*static*/ size_t _heap_max;
|
||||||
|
|
||||||
// Lock NOT used internally, but used by KalAllocMemory() & co.
|
// Lock NOT used internally, but used by KalAllocMemory() & co.
|
||||||
static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK);
|
static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK);
|
||||||
|
@ -114,6 +117,7 @@ error_t MmGrowHeap(size_t req)
|
||||||
assert(req % alignof(QWORD) == 0);
|
assert(req % alignof(QWORD) == 0);
|
||||||
|
|
||||||
if ((size_t)_heap_end + req > (size_t)_heap_start + _heap_max) {
|
if ((size_t)_heap_end + req > (size_t)_heap_start + _heap_max) {
|
||||||
|
assert(!"Can't extend heap that much");
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +134,7 @@ error_t MmShrinkHeap(size_t req)
|
||||||
assert(req % alignof(QWORD) == 0);
|
assert(req % alignof(QWORD) == 0);
|
||||||
|
|
||||||
if (req > (size_t)_heap_end - (size_t)_heap_start) {
|
if (req > (size_t)_heap_end - (size_t)_heap_start) {
|
||||||
|
assert(!"Can't shrink heap that much");
|
||||||
return EADDRINUSE;
|
return EADDRINUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ error_t KalAllocMemoryEx(void **ptr, size_t req, int flags, size_t align)
|
||||||
{
|
{
|
||||||
error_t rc;
|
error_t rc;
|
||||||
size_t brk;
|
size_t brk;
|
||||||
extern void *_heap_start;
|
|
||||||
|
|
||||||
if (align == 0) align = M_DEFAULT_ALIGNMENT;
|
if (align == 0) align = M_DEFAULT_ALIGNMENT;
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ static error_t InitMemoryMap(void)
|
||||||
if ((BtMemoryInfo.upMemory / (MB/KB)) <= MINIMUM_RAM_SIZE)
|
if ((BtMemoryInfo.upMemory / (MB/KB)) <= MINIMUM_RAM_SIZE)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
// Ok then we can work ------------------------------------------------------ //
|
// Ok then we can work
|
||||||
|
|
||||||
// the memory map provided by GRUB via the BIOS
|
// the memory map provided by GRUB via the BIOS
|
||||||
currentEntry = (multiboot_memory_map_t*)BtMemoryInfo.mapAddr;
|
currentEntry = (multiboot_memory_map_t*)BtMemoryInfo.mapAddr;
|
||||||
|
|
|
@ -392,7 +392,7 @@ error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap)
|
||||||
// Carry on to next modifier
|
// Carry on to next modifier
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert rc for debugging purposes
|
// Assert !rc for debugging purposes
|
||||||
assert(!rc);
|
assert(!rc);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -34,7 +34,6 @@ error_t BPutOnBuf(Buffer_t *buf, uchar ch)
|
||||||
assert(buf && buf->initDone == INITOK);
|
assert(buf && buf->initDone == INITOK);
|
||||||
|
|
||||||
if (!buf) return EINVAL;
|
if (!buf) return EINVAL;
|
||||||
if (buf->flags & (BF_EOF|BF_ERR)) return EENDF;
|
|
||||||
if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
|
if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
|
||||||
return EBADF;
|
return EBADF;
|
||||||
}
|
}
|
||||||
|
@ -52,10 +51,12 @@ error_t bputc(Buffer_t *buf, uchar ch)
|
||||||
{
|
{
|
||||||
error_t rc = EOK;
|
error_t rc = EOK;
|
||||||
|
|
||||||
// Implements playback / scrolling up when line buffering
|
if (buf->flags & (BF_EOF|BF_ERR)) return EENDF;
|
||||||
|
|
||||||
|
// Implements playback / scrolling up when terminal buffering
|
||||||
// Note that '\n', '\r' and '\t' can never occur in the buffer
|
// Note that '\n', '\r' and '\t' can never occur in the buffer
|
||||||
// That should change; there should be a flag for it
|
// That should change; there should be a flag for it
|
||||||
if (buf->flags & BF_LINE) {
|
if (buf->flags & BF_TERM) {
|
||||||
|
|
||||||
// Deal with line feeds by filling the rest of the line with spaces
|
// Deal with line feeds by filling the rest of the line with spaces
|
||||||
// We need a field for choosing a different filler, e.g. '\0'
|
// We need a field for choosing a different filler, e.g. '\0'
|
||||||
|
@ -93,7 +94,21 @@ error_t bputc(Buffer_t *buf, uchar ch)
|
||||||
while (buf->lastLF % 4 > 0) {
|
while (buf->lastLF % 4 > 0) {
|
||||||
rc = bputc(buf, ' ');
|
rc = bputc(buf, ' ');
|
||||||
}
|
}
|
||||||
if (rc > 0) return rc;
|
}
|
||||||
|
|
||||||
|
// Backspace
|
||||||
|
else if (ch == 8) {
|
||||||
|
if (buf->wp > buf->buf) {
|
||||||
|
buf->wp--;
|
||||||
|
rc = bputc(buf, ' ');
|
||||||
|
if (!rc) buf->wp--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEL character
|
||||||
|
else if (ch == 127) {
|
||||||
|
rc = bputc(buf, ' ');
|
||||||
|
if (!rc) buf->wp--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just a regular character
|
// Just a regular character
|
||||||
|
@ -118,7 +133,7 @@ error_t bputc(Buffer_t *buf, uchar ch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not line-buffering
|
// Not a terminal buffer
|
||||||
else {
|
else {
|
||||||
if (buf->wp == buf->buf + buf->size) {
|
if (buf->wp == buf->buf + buf->size) {
|
||||||
buf->flags |= BF_EOF;
|
buf->flags |= BF_EOF;
|
||||||
|
@ -127,11 +142,22 @@ error_t bputc(Buffer_t *buf, uchar ch)
|
||||||
|
|
||||||
*buf->wp++ = ch;
|
*buf->wp++ = ch;
|
||||||
|
|
||||||
if (buf->wp == buf->buf + buf->size && !(buf->flags&BF_FONCLOSE)) {
|
if (buf->wp == buf->buf + buf->size) {
|
||||||
buf->flusher(buf);
|
if (!(buf->flags & (BF_LINE|BF_FONCLOSE))) {
|
||||||
|
if (buf->flusher) buf->flusher(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line-buffering
|
||||||
|
if (ch == '\n' && buf->flags & BF_LINE) {
|
||||||
|
if (buf->flusher) buf->flusher(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return EOK;
|
if (rc != EOK) {
|
||||||
|
// buf->flags |= BF_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ error_t BScrollDownBuf(Buffer_t *buf)
|
||||||
assert(buf && buf->initDone == INITOK);
|
assert(buf && buf->initDone == INITOK);
|
||||||
|
|
||||||
if (!buf) return EINVAL;
|
if (!buf) return EINVAL;
|
||||||
|
if (!(buf->flags & BF_TERM)) return EBADF;
|
||||||
if (buf->flags & (BF_EOF|BF_ERR)) return EENDF;
|
if (buf->flags & (BF_EOF|BF_ERR)) return EENDF;
|
||||||
if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
|
if (buf->state != BS_RDWR && buf->state != BS_WRONLY) {
|
||||||
return EBADF;
|
return EBADF;
|
||||||
|
|
|
@ -26,13 +26,25 @@
|
||||||
#include <extras/locks.h>
|
#include <extras/locks.h>
|
||||||
#include <extras/malloc.h>
|
#include <extras/malloc.h>
|
||||||
|
|
||||||
Buffer_t *BStdOut, *BStdDbg;
|
#include <kernel/base.h>
|
||||||
|
|
||||||
|
Buffer_t *BStdIn, *BStdOut, *BStdDbg;
|
||||||
|
|
||||||
// Straightforward functions
|
// Straightforward functions
|
||||||
int BGetFlags(Buffer_t *buf) { return buf->flags; }
|
int BGetFlags(Buffer_t *buf) { return buf->flags; }
|
||||||
int BGetState(Buffer_t *buf) { return buf->state; }
|
int BGetState(Buffer_t *buf) { return buf->state; }
|
||||||
int BGetLineLen(Buffer_t *buf) { return buf->lineLen; }
|
|
||||||
void BSetLineLen(Buffer_t *buf, int len) { buf->lineLen = len; }
|
void BEnableLineBuffering(Buffer_t *buf)
|
||||||
|
{
|
||||||
|
assert(buf && !(buf->flags & BF_TERM));
|
||||||
|
buf->flags |= BF_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BDisaleLineBuffering(Buffer_t *buf)
|
||||||
|
{
|
||||||
|
assert(buf && !(buf->flags & BF_TERM));
|
||||||
|
buf->flags &= ~BF_LINE;
|
||||||
|
}
|
||||||
|
|
||||||
void BLockBuf(Buffer_t *buf)
|
void BLockBuf(Buffer_t *buf)
|
||||||
{
|
{
|
||||||
|
@ -43,8 +55,6 @@ void BLockBuf(Buffer_t *buf)
|
||||||
void BUnlockBuf(Buffer_t *buf) { ExReleaseLock(&buf->lock); }
|
void BUnlockBuf(Buffer_t *buf) { ExReleaseLock(&buf->lock); }
|
||||||
bool BTrylockBuf(Buffer_t *buf) { return ExAttemptLock(&buf->lock); }
|
bool BTrylockBuf(Buffer_t *buf) { return ExAttemptLock(&buf->lock); }
|
||||||
|
|
||||||
void BFlushOnClose(Buffer_t *buf) { buf->flags |= BF_FONCLOSE; }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Closes a buffer, not flushing unless the proper flag is set
|
// Closes a buffer, not flushing unless the proper flag is set
|
||||||
//
|
//
|
||||||
|
@ -129,16 +139,16 @@ error_t BOpenPureBufEx(Buffer_t **pbuf, char *source, int mode, size_t size,
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Creates a line buffer of (nLines + pbCount*nLines) lines each
|
// Creates a terminal buffer of (nLines + pbCount*nLines) lines each
|
||||||
// of lineLen length (pb = playback buffer, for scrolling up)
|
// of lineLen length (pb = playback buffer, for scrolling up)
|
||||||
//
|
//
|
||||||
error_t BOpenLineBuf(Buffer_t **pbuf, int mode,
|
error_t BOpenTermBuf(Buffer_t **pbuf, int mode,
|
||||||
int lineLen, int nLines, int pbCount)
|
int lineLen, int nLines, int pbCount)
|
||||||
{
|
{
|
||||||
return BOpenLineBufEx(pbuf, NULL, mode, lineLen, nLines, pbCount, NULL);
|
return BOpenTermBufEx(pbuf, NULL, mode, lineLen, nLines, pbCount, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
error_t BOpenLineBufEx(Buffer_t **pbuf, char *source, int mode,
|
error_t BOpenTermBufEx(Buffer_t **pbuf, char *source, int mode,
|
||||||
int lineLen, int nLines, int pbCount, BFlusher_t flusher)
|
int lineLen, int nLines, int pbCount, BFlusher_t flusher)
|
||||||
{
|
{
|
||||||
error_t rc;
|
error_t rc;
|
||||||
|
@ -152,7 +162,7 @@ error_t BOpenLineBufEx(Buffer_t **pbuf, char *source, int mode,
|
||||||
(*pbuf)->lastLF = 0;
|
(*pbuf)->lastLF = 0;
|
||||||
(*pbuf)->nLines = nLines;
|
(*pbuf)->nLines = nLines;
|
||||||
(*pbuf)->lineLen = lineLen;
|
(*pbuf)->lineLen = lineLen;
|
||||||
(*pbuf)->flags |= BF_LINE;
|
(*pbuf)->flags |= BF_TERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include <kalbase.h>
|
#include <kalbase.h>
|
||||||
#include <extras/malloc.h>
|
#include <extras/malloc.h>
|
||||||
|
|
||||||
|
#include<kernel/heap.h>
|
||||||
|
|
||||||
/* DO NOT compile with strict aliasing on */
|
/* DO NOT compile with strict aliasing on */
|
||||||
|
|
||||||
//------------------------------------------//
|
//------------------------------------------//
|
||||||
|
@ -178,7 +180,7 @@ void *memcpy(void *restrict dst, const void *restrict src, size_t bytes)
|
||||||
const ulong *usrc = (const ulong *)src;
|
const ulong *usrc = (const ulong *)src;
|
||||||
ulong *udst = (ulong *)dst;
|
ulong *udst = (ulong *)dst;
|
||||||
|
|
||||||
assert("Don't use this, use memmove()");
|
assert(!"Don't use this, use memmove()");
|
||||||
assert((dst + bytes < src || src + bytes < dst) && "memcpy() overlap; use memmove()");
|
assert((dst + bytes < src || src + bytes < dst) && "memcpy() overlap; use memmove()");
|
||||||
|
|
||||||
if unlikely (bytes == 0) return dst;
|
if unlikely (bytes == 0) return dst;
|
||||||
|
|
|
@ -22,11 +22,20 @@
|
||||||
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
||||||
//----------------------------------------------------------------------------//
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
//
|
#include <extras/buf.h>
|
||||||
// TODO integer modifiers
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <kalbase.h>
|
//
|
||||||
|
// XXX
|
||||||
|
// For now vsnprintf won't support n > 4096
|
||||||
|
// vsnprintf() is implemented using the libbuf, which
|
||||||
|
// does not support dynamically sized buffers (yet)
|
||||||
|
// (because we need realloc() for that, and we don't have it yet)
|
||||||
|
// So for now we have to create a buffer of size n which is allocated
|
||||||
|
// hard, with no paging etc.
|
||||||
|
// Once libbuf is supports dynamic buffers, the only changes necessary
|
||||||
|
// will be to change the value below to and add a line to vsnprintf()
|
||||||
|
//
|
||||||
|
#define VSNPRINTF_MAX 512
|
||||||
|
|
||||||
//
|
//
|
||||||
// Format str according to fmt using ellipsed arguments
|
// Format str according to fmt using ellipsed arguments
|
||||||
|
@ -36,8 +45,10 @@ size_t sprintf(char *str, const char *fmt, ...)
|
||||||
int ret;
|
int ret;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
|
assert(!"sprintf() is deprecated, used snprintf() for more safety");
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
ret = vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
ret = vsnprintf(str, VSNPRINTF_MAX, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -45,7 +56,7 @@ size_t sprintf(char *str, const char *fmt, ...)
|
||||||
|
|
||||||
size_t vsprintf(char *str, const char *fmt, va_list ap)
|
size_t vsprintf(char *str, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
return vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
return vsnprintf(str, VSNPRINTF_MAX, fmt, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -64,6 +75,57 @@ size_t snprintf(char *str, size_t n, const char *fmt, ...)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__GET_GETRIP();
|
||||||
|
size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
size_t ret;
|
||||||
|
error_t rc;
|
||||||
|
Buffer_t *buf;
|
||||||
|
|
||||||
|
assert(str && fmt);
|
||||||
|
|
||||||
|
if (n == 0) return 0;
|
||||||
|
if (n > VSNPRINTF_MAX) {
|
||||||
|
assert(!"Not yet...");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// n-1 to leave place for the '\0'
|
||||||
|
if (BOpenPureBuf(&buf, BS_WRONLY, n-1) != EOK) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
rc = vbprintf(buf, fmt, ap);
|
||||||
|
|
||||||
|
// We don't mind EOFs, just just return how much was successfully written
|
||||||
|
if (rc != EOK && !(rc == EENDF && !(buf->flags & BF_EOF))) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (size_t)buf->wp - (size_t)buf->buf;
|
||||||
|
|
||||||
|
if (ret > 0) {
|
||||||
|
// To be changed to memcpy()
|
||||||
|
memmove(str, (char *)buf->buf, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
str[ret++] = 0;
|
||||||
|
assert(ret <= n);
|
||||||
|
//109e38 101c63
|
||||||
|
|
||||||
|
BCloseBuf(buf);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
assert(!"vsnprintf() failure");
|
||||||
|
*str = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Old code
|
||||||
|
//
|
||||||
|
#if 0
|
||||||
|
|
||||||
// Size of the buffer is for convertions
|
// Size of the buffer is for convertions
|
||||||
#define CONVBUF 64
|
#define CONVBUF 64
|
||||||
|
|
||||||
|
@ -242,3 +304,5 @@ size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
return ret + 1;
|
return ret + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue