diff --git a/include/lib/buf.h b/include/lib/buf.h index 72536b2..07311dc 100644 --- a/include/lib/buf.h +++ b/include/lib/buf.h @@ -138,18 +138,14 @@ int BGetState(Buffer_t *); error_t BFlushBuf(Buffer_t *); error_t BPutOnBuf(Buffer_t *, uchar); +error_t BWriteOnBuf(Buffer_t *, uchar *, size_t); +error_t BPrintOnBuf(Buffer_t *, const char *, ...); +error_t BPrintOnBufV(Buffer_t *, const char *, va_list); + error_t BGetFromBuf(Buffer_t *, uchar *); - -// The following functions return the number of bytes written to the buffer -size_t BWriteOnBuf(Buffer_t *, uchar *, size_t); -size_t BPrintOnBuf(Buffer_t *, const char *, ...); -size_t BPrintOnBufV(Buffer_t *, const char *, va_list); - -// The following functions return the number of elements from their -// va_list's their wrote too, e.g. successful bscanf("%d %d", &a, &b) == 2 -size_t BReadFromBuf(Buffer_t *, uchar *, size_t); -size_t BScanFromBuf(Buffer_t *, const char *, ...); -size_t BScanFromBufV(Buffer_t *, const char *, va_list); +error_t BReadBuf(Buffer_t *, uchar *, size_t); +error_t BScanBuf(Buffer_t *, const char *, ...); +error_t BScanBufV(Buffer_t *, const char *, va_list); void BLockBuf(Buffer_t *); void BUnlockBuf(Buffer_t *); @@ -161,14 +157,14 @@ bool BTrylockBuf(Buffer_t *); // error_t bputc(Buffer_t *, uchar); -size_t bwrite(Buffer_t *, uchar *, size_t); -size_t bprintf(Buffer_t *, const char *, ...); -size_t vbprintf(Buffer_t *, const char *, va_list); +error_t bwrite(Buffer_t *, uchar *, size_t); +error_t bprintf(Buffer_t *, const char *, ...); +error_t vbprintf(Buffer_t *, const char *, va_list); error_t bgetc(Buffer_t *, uchar *); -size_t bread(Buffer_t *, uchar *, size_t); -size_t bscanf(Buffer_t *, size_t *, const char *, ...); -size_t vbscanf(Buffer_t *, size_t *, const char *, va_list); +error_t bread(Buffer_t *, uchar *, size_t); +error_t bscanf(Buffer_t *, const char *, ...); +error_t vbscanf(Buffer_t *, const char *, va_list); error_t bemptybuf(Buffer_t *); error_t bscrolldown(Buffer_t *); diff --git a/include/libc.h b/include/libc.h index f35ae16..21a52e2 100644 --- a/include/libc.h +++ b/include/libc.h @@ -146,12 +146,8 @@ char *strrev(char *restrict, const char *restrict); char *strrev2(char *); size_t sprintf(char *, const char *, ...); -size_t vsprintf(char *, const char *, va_list); - -// These return the number of bytes **written** -// not the number of bytes which would have been -// written had the buffer been large enough size_t snprintf(char *, size_t, const char *, ...); +size_t vsprintf(char *, const char *, va_list); size_t vsnprintf(char *, size_t, const char *, va_list); //----------------------------------------------------------------------------// diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c index 0b95652..8f3bf8d 100644 --- a/kaleid/kernel/ke/panic.c +++ b/kaleid/kernel/ke/panic.c @@ -26,6 +26,7 @@ #include #include +error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap); extern bool KeIdtIsInitialized; // diff --git a/kaleid/libbuf/bgetc.c b/kaleid/libbuf/bgetc.c index ef53d4c..f0f6d0f 100644 --- a/kaleid/libbuf/bgetc.c +++ b/kaleid/libbuf/bgetc.c @@ -43,9 +43,6 @@ error_t BGetFromBuf(Buffer_t *buf, uchar *ch) ExReleaseLock(&buf->lock); return rc; } - -// Note: any change to this must be done while -// keeping in mind vbscanf()'s workaround for ungetc() error_t bgetc(Buffer_t *buf, uchar *ch) { error_t rc = EOK; @@ -73,9 +70,6 @@ error_t bgetc(Buffer_t *buf, uchar *ch) while (buf->rp >= buf->wp) { #ifdef _KALEID_KERNEL KeSleep(1); // XXX synchronization with keyboard driver -#else - buf->flags |= BF_EOF; - return EENDF; // Currently empty #endif } diff --git a/kaleid/libbuf/bprint.c b/kaleid/libbuf/bprint.c index c407cf4..48dbdeb 100644 --- a/kaleid/libbuf/bprint.c +++ b/kaleid/libbuf/bprint.c @@ -31,41 +31,73 @@ // // Prints formatted string on buf according to fmt // -size_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...) +error_t BPrintOnBuf(Buffer_t *buf, const char *fmt, ...) { - size_t sz; + error_t rc; va_list ap; va_start(ap, fmt); ExAcquireLock(&buf->lock); - sz = vbprintf(buf, fmt, ap); + rc = vbprintf(buf, fmt, ap); ExReleaseLock(&buf->lock); va_end(ap); - return sz; + return rc; } -size_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap) +error_t BPrintOnBufV(Buffer_t *buf, const char *fmt, va_list ap) { - size_t sz; + error_t rc; ExAcquireLock(&buf->lock); - sz = vbprintf(buf, fmt, ap); + rc = vbprintf(buf, fmt, ap); ExReleaseLock(&buf->lock); - return sz; + return rc; } -size_t bprintf(Buffer_t *buf, const char *fmt, ...) +error_t bprintf(Buffer_t *buf, const char *fmt, ...) { - size_t sz; + error_t rc; va_list ap; va_start(ap, fmt); - sz = vbprintf(buf, fmt, ap); + rc = vbprintf(buf, fmt, ap); va_end(ap); - return sz; + return rc; +} + +// +// Prints 0 for octal, 0x for hexadecimal, 0b for binary +// +static error_t bprinthash(Buffer_t *buf, int base, int cap) +{ + error_t rc; + + if (base != 2 && base != 8 && base != 16) { + return EOK; + } + + rc = bputc(buf, '0'); + + if (!rc && base != 8) { + rc = bputc(buf, (base == 2 ? 'b' : (cap ? 'X' : 'x'))); + } + + return rc; +} + +static error_t bdopadding(Buffer_t *buf, size_t width, size_t len, + char filler) +{ + error_t rc = EOK; + + for (; !rc && width > len ; width--) { + rc = bputc(buf, filler); + } + + return rc; } #define CONVBUFSIZE 100 @@ -74,10 +106,9 @@ size_t bprintf(Buffer_t *buf, const char *fmt, ...) // Actually does BPrintOnBuf's job; doesn't lock anything // Quite a long function // -size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) +error_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) { error_t rc = 0; - size_t written = 0; ssize_t width, prec, len; char type; @@ -103,11 +134,10 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // Base int base; - if (!buf || !fmt) { seterrno(EINVAL); return 0; } - if (buf->flags & (BF_EOF|BF_ERR)) { seterrno(EENDF); return 0; } + if (!buf || !fmt) return EINVAL; + if (buf->flags & (BF_EOF|BF_ERR)) return EENDF; if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { - seterrno(EBADF); - return 0; + return EBADF; } // Progress in format string @@ -116,14 +146,14 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // Deal with all non-'%' characters if (*fmt != '%') { rc = bputc(buf, *fmt); - written++; + fmt++; - continue; } // - // %[flags][width|*][.precision|*][length]type + // %[parameter][flags][width|*][.precision|*][length]type + // We aren't dealing with parameters and floating stuff just yet // // Skip the '%' @@ -132,9 +162,8 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // "%%" modifier if (*fmt == '%') { rc = bputc(buf, '%'); - written++; + fmt++; - continue; } @@ -224,7 +253,6 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) if (type == 'c') { uch = (uchar)va_arg(ap, int); rc = bputc(buf, uch); - written++; continue; } @@ -233,10 +261,8 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) if (type == 'C') { base = va_arg(ap, int); - if (!(base < 0 || base > VGA_COLOR_WHITE)) { + if (!(base < 0 || base > VGA_COLOR_WHITE)) rc = bputc(buf, RtlColorToChar(base)); - written++; - } assert(!rc && 1); @@ -255,7 +281,7 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // Zero/nonspecified precision means unlimited amount if (prec == 0) prec = INT_MAX; - for (; !rc && *s && prec-- ; s++) { + for (; *s && prec-- ; s++) { rc = bputc(buf, (uchar)*s); } @@ -266,7 +292,6 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // Make sure width and prec aren't too big // (We didn't do that earlier because %s uses width) if (width > CONVBUFSIZE || prec > CONVBUFSIZE) { - written++; // Work around "if (rc) return written - 1;" rc = EINVAL; break; } @@ -288,16 +313,16 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) // End of string too soon else if (type == '\0') { + bputc(buf, '%'); rc = EINVAL; - written++; // fool the line "if (rc) return written-1;" break; } // Unknown/unsupported modifier else { - rc = bputc(buf, '%'); - written++; - + bputc(buf, '%'); + bputc(buf, '?'); + rc = bputc(buf, type); continue; } @@ -357,63 +382,36 @@ size_t vbprintf(Buffer_t *buf, const char *fmt, va_list ap) } // When padding with spaces, we pad before +/-'s etc - if (!minus && !zero && width > len) { - for (; !rc && width > len ; width--) { - rc = bputc(buf, ' '); - written++; - } - } + if (!minus && !zero && width > len) + bdopadding(buf, width, len, ' '); // Deal with signs and the hash flag - if (*s == '-') { rc = bputc(buf, '-'); s++, len--; written++; } - else if (sgn && plus) { rc = bputc(buf, '+'); written++; } - else if (sgn && space) { rc = bputc(buf, ' '); written++; } - - // Print 0 for octal, 0x for hexadecimal, 0b for binary - else if (hash && (base == 2 || base == 8 || base == 16)) { - rc = bputc(buf, '0'); - written++; - - if (!rc && base != 8) { - rc = bputc(buf, (base == 2 ? 'b' : (cap ? 'X' : 'x'))); - written++; - } - } + if (*s == '-') { rc = bputc(buf, '-'); s++, len--; } + else if (sgn && plus) rc = bputc(buf, '+'); + else if (sgn && space) rc = bputc(buf, ' '); + else if (hash) bprinthash(buf, base, cap); // Deal with padding by zeroes // The 'minus' flag makes no sense with the 'zero' one - if (zero && width > len) { - for (; !rc && width > len ; width--) { - rc = bputc(buf, '0'); - written++; - } - } + if (zero && width > len) + bdopadding(buf, width, len, '0'); // Output the actual number for (; !rc && *s ; s++) { rc = bputc(buf, (uchar)*s); - written++; } // 'minus' padding, only with spaces - if (minus && !zero && width > len) { - for (; !rc && width > len ; width--) { - rc = bputc(buf, ' '); - written++; - } - } - + if (minus && !zero && width > len) + bdopadding(buf, width, base, ' '); + // Carry on to next modifier - } + } + + // For debugging purposes + if(rc)KeStartPanic("%s",strerror(rc)); + assert(!rc && "vbprintf() error"); - // For debugging purposes - assert(!rc && "vbprintf() error"); - seterrno(rc); - - if (rc) - return written - 1; // "- 1" because last bputc() must have failed - - else - return written; + return rc; } diff --git a/kaleid/libbuf/bscan.c b/kaleid/libbuf/bscan.c index cb31ee8..e6df43c 100644 --- a/kaleid/libbuf/bscan.c +++ b/kaleid/libbuf/bscan.c @@ -21,212 +21,6 @@ // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -#if 0 + #include - -// -// Builds string reading from buf according to fmt -// -size_t BScanFromBuf(Buffer_t *buf, const char *fmt, ...) -{ - size_t sz; - va_list ap; - - va_start(ap, fmt); - ExAcquireLock(&buf->lock); - sz = vbscanf(buf, fmt, ap); - ExReleaseLock(&buf->lock); - va_end(ap); - - return sz; -} - -size_t BScanFromBufV(Buffer_t *buf, const char *fmt, va_list ap) -{ - size_t rc; - - ExAcquireLock(&buf->lock); - sz = vbscanf(buf, fmt, ap); - ExReleaseLock(&buf->lock); - - return sz; -} - -size_t bscanf(Buffer_t *buf, const char *fmt, ...) -{ - size_t sz; - va_list ap; - - va_start(ap, fmt); - sz = vbscanf(buf, fmt, ap); - va_end(ap); - - return sz; -} - -size_t vbscanf(Buffer_t *buf, const char *fmt, va_list ap) -{ - error_t rc = EOK; - - size_t readcnt = 0; - uchar ch = 0; - - bool l, h; - - size_t width; - bool ignore; // '*' modifier, don't write to va_list for current mod - - if (!buf || !fmt) { seterrnp(EINVAL); return 0; } - if (buf->flags & (BF_EOF|BF_ERR)) { seterrno(EENDF); return 0; } - if (buf->state != BS_RDWR && buf->state != BS_WRONLY) { - seterrno(EBADF); - return 0; - } - - // Progress in format string - for (*fmt && !rc) { - - // Skip all kinds of whitespaces - if (isspace(*fmt)) { - - another_space: - rc = bgetc(buf, &ch); - - if (!rc) break; - - // Put back non-whitespaces and progress - if (!isspace(ch)) { - buf->rp--; - do { fmt++; } while (isspace(*fmt)); - continue; - } - - else goto another_space; - } - - // Deal with all non-'%' non-whitespace characters - if (*fmt != '%') { - rc = bgetc(buf, &ch); - - // Is it what we expected? - if (!rc && ch != *fmt) { - // No, so put it back - buf->rp--; - break; - } - - // We don't do anything with these characters - continue; - } - - // - // %[*][width][modifier]type - // - - // Skip the % - fmt++; - - // '%%' type - if (*fmt == '%') { - rc = bgetc(buf, &ch); - - if (!rc && ch != '%') { - buf->rp--; - break; - } - - continue; - } - - l = h = 0; - width = 0; - ignore = 0; - - // Don't write to variable - if (*fmt == '*') { - ignore = 1; - fmt++; - } - - // Extract width field - while (isdigit(*fmt)) { - width = 10 * width + (*fmt - '0'); - fmt++; - } - - assert(!(width < 0)); - - // - // Extract length field - // - - if (*fmt == 'l') { - l = 1; - fmt++; - } - - else if (*fmt == 'h') { - h = 1; - fmt++ - } - - // - // Types - // - - // Read character(s) - if (*fmt == 'c') { - if (width == 0) width = 1; - - // For >1 width, read that many characters - // then store them in successive argument pointers - for (; width; width--) { - rc = bgetc(buf, &ch); - if (!rc) break; - - char *chptr = va_arg(ap, char *); - *chptr = (char)ch; - readcnt++; - } - } - - // Decimal integer - else if (*fmt == 'd') { - - } - } - - // For debugging purposes - assert(!rc && "vbscanf() error"); - seterrno(rc); - - return readcnt; -} - - - -#endif - - - - - - - - - - - - - - - - - - - - - - - diff --git a/kaleid/libc/sprintf.c b/kaleid/libc/sprintf.c index bbee9b0..3e0f306 100644 --- a/kaleid/libc/sprintf.c +++ b/kaleid/libc/sprintf.c @@ -35,7 +35,7 @@ // 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 4096 +#define VSNPRINTF_MAX 512 // // Format str according to fmt using ellipsed arguments @@ -77,8 +77,8 @@ size_t snprintf(char *str, size_t n, const char *fmt, ...) size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap) { - error_t rc; - size_t ret, sz; + size_t ret; + error_t rc = EOK; Buffer_t *buf = NULL; assert(str && fmt); @@ -96,11 +96,16 @@ size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap) goto fail; } - sz = vbprintf(buf, fmt, ap); + rc = vbprintf(buf, fmt, ap); // We don't mind EOFs, just just return how much was successfully written - if (sz == 0) { - if (!(buf->flags & BF_EOF)) { + if (rc != EOK) { + if (rc == EENDF) { + if (!(buf->flags & BF_EOF)) { + goto fail; + } + } + else { goto fail; } } @@ -108,6 +113,7 @@ size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap) ret = (size_t)buf->wp - (size_t)buf->buf; if (ret > 0) { + // To be changed to memcpy() memmove(str, (char *)buf->buf, ret); }