summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/include/lib/kio.h17
-rw-r--r--kernel/include/lib/klib.h9
-rw-r--r--kernel/lib/kprintf.c70
-rw-r--r--kernel/lib/panic.c3
-rw-r--r--user/include/stdio.h101
-rw-r--r--user/lib/printf.c122
6 files changed, 231 insertions, 91 deletions
diff --git a/kernel/include/lib/kio.h b/kernel/include/lib/kio.h
index 652a85b..ef22f95 100644
--- a/kernel/include/lib/kio.h
+++ b/kernel/include/lib/kio.h
@@ -31,8 +31,9 @@ void kputs(const char *s);
*
* @param format - the format string
* @param ... - variable args for the format
+ * @returns number of bytes written
*/
-__attribute__((format(printf, 1, 2))) void kprintf(const char *format, ...);
+__attribute__((format(printf, 1, 2))) int kprintf(const char *format, ...);
/**
* prints out a formatted string to a buffer
@@ -42,7 +43,7 @@ __attribute__((format(printf, 1, 2))) void kprintf(const char *format, ...);
* @param ... - variable args for the format
* @returns number of bytes written
*/
-__attribute__((format(printf, 2, 3))) size_t ksprintf(char *restrict s,
+__attribute__((format(printf, 2, 3))) int ksprintf(char *restrict s,
const char *format, ...);
/**
@@ -53,8 +54,9 @@ __attribute__((format(printf, 2, 3))) size_t ksprintf(char *restrict s,
* @param format - the format string
* @param ... - variable args for the format
* @returns number of bytes written
+ * @returns number of bytes that would of been written (past maxlen)
*/
-__attribute__((format(printf, 3, 4))) size_t ksnprintf(char *restrict s,
+__attribute__((format(printf, 3, 4))) int ksnprintf(char *restrict s,
size_t maxlen,
const char *format, ...);
@@ -63,8 +65,9 @@ __attribute__((format(printf, 3, 4))) size_t ksnprintf(char *restrict s,
*
* @param format - the format string
* @param args - variable arg list for the format
+ * @returns number of bytes written
*/
-void kvprintf(const char *format, va_list args);
+int kvprintf(const char *format, va_list args);
/**
* prints out a formatted string to a buffer
@@ -74,7 +77,7 @@ void kvprintf(const char *format, va_list args);
* @param args - variable arg list for the format
* @returns number of bytes written
*/
-size_t kvsprintf(char *restrict s, const char *format, va_list args);
+int kvsprintf(char *restrict s, const char *format, va_list args);
/**
* prints out a formatted string to a buffer with a given max length
@@ -83,9 +86,9 @@ size_t kvsprintf(char *restrict s, const char *format, va_list args);
* @param maxlen - the max len of the buffer
* @param format - the format string
* @param args - variable arg list for the format
- * @returns number of bytes written
+ * @returns number of bytes that would of been written (past maxlen)
*/
-size_t kvsnprintf(char *restrict s, size_t maxlen, const char *format,
+int kvsnprintf(char *restrict s, size_t maxlen, const char *format,
va_list args);
#endif /* kio.h */
diff --git a/kernel/include/lib/klib.h b/kernel/include/lib/klib.h
index 3afe925..cb1de01 100644
--- a/kernel/include/lib/klib.h
+++ b/kernel/include/lib/klib.h
@@ -185,13 +185,20 @@ char *btoa(size_t bytes, char *buf);
*/
unsigned int bound(unsigned int min, unsigned int value, unsigned int max);
+#define __PANIC_STR(x) __PANIC_STR2(x)
+#define __PANIC_STR2(x) #x
+
+#define panic(...) __panic(__PANIC_STR(__LINE__), __FILE__, __VA_ARGS__)
+#define assert(val, ...) do { if (!(val)) { panic(__VA_ARGS__); } } while (0)
+
/**
* Abort the kernel with a given message.
*
* @param format - the format string
* @param ... - variable args for the format
*/
-__attribute__((noreturn)) void panic(const char *format, ...);
+__attribute__((noreturn, format(printf, 3, 4)))
+void __panic(const char *line, const char *file, const char *format, ...);
/**
* Fill dst with a stack trace consisting of return addresses in order
diff --git a/kernel/lib/kprintf.c b/kernel/lib/kprintf.c
index 552b923..aabefc4 100644
--- a/kernel/lib/kprintf.c
+++ b/kernel/lib/kprintf.c
@@ -71,6 +71,7 @@ typedef struct {
/* output */
size_t written_len;
+ size_t possible_written_len;
bool sprintf;
char *sprintf_buf;
@@ -80,6 +81,8 @@ typedef struct {
static void printf_putc(context_t *ctx, char c)
{
+ ctx->possible_written_len++;
+
// bounds check
if (ctx->has_max_len)
if (ctx->written_len >= ctx->max_len)
@@ -348,9 +351,11 @@ static void handle_string_specifier(context_t *ctx, options_t *opts,
data_t data)
{
char *str = data.str;
- int str_len = 0;
+ if (str == NULL)
+ str = "(null)";
// get length of string
+ int str_len = 0;
if (opts->precision_set)
str_len = opts->precision;
else
@@ -486,6 +491,13 @@ static void do_printf(context_t *ctx, va_list args)
case 's':
handle_string_specifier(ctx, &opts, data);
break;
+ // very terrible why in the love of FUCKING GOD would you do this
+ // but its in printf so im adding it for you fucks
+ case 'n': {
+ size_t *bad = va_arg(args, size_t *);
+ *bad = ctx->written_len;
+ break;
+ }
// unknown
default:
// print from % to current
@@ -494,73 +506,83 @@ static void do_printf(context_t *ctx, va_list args)
break;
}
}
+
+ // add \0 on sprintf
+ if (ctx->sprintf) {
+ int len, plen;
+ len = ctx->written_len;
+ plen = ctx->possible_written_len;
+ printf_putc(ctx, '\0');
+ ctx->written_len = len;
+ ctx->possible_written_len = plen;
+ }
}
-void kprintf(const char *format, ...)
+int kprintf(const char *format, ...)
{
va_list args;
+ int len;
+
va_start(args, format);
- kvprintf(format, args);
+ len = kvprintf(format, args);
va_end(args);
+ return len;
}
-size_t ksprintf(char *restrict s, const char *format, ...)
+int ksprintf(char *restrict s, const char *format, ...)
{
va_list args;
- size_t amt;
+ int len;
+
va_start(args, format);
- amt = kvsprintf(s, format, args);
+ len = kvsprintf(s, format, args);
va_end(args);
- return amt;
+ return len;
}
-size_t snprintf(char *restrict s, size_t maxlen, const char *format, ...)
+int snprintf(char *restrict s, size_t maxlen, const char *format, ...)
{
va_list args;
- size_t amt;
+ int len;
+
va_start(args, format);
- amt = kvsnprintf(s, maxlen, format, args);
+ len = kvsnprintf(s, maxlen, format, args);
va_end(args);
- return amt;
+ return len;
}
-void kvprintf(const char *format, va_list args)
+int kvprintf(const char *format, va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // print
+
do_printf(&ctx, args);
+ return ctx.written_len;
}
-size_t kvsprintf(char *restrict s, const char *format, va_list args)
+int kvsprintf(char *restrict s, const char *format, va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // sprintf buffer
ctx.sprintf_buf = s;
ctx.sprintf = 1;
- // print
+
do_printf(&ctx, args);
return ctx.written_len;
}
-size_t kvsnprintf(char *restrict s, size_t maxlen, const char *format,
+int kvsnprintf(char *restrict s, size_t maxlen, const char *format,
va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // sprintf buffer
ctx.sprintf_buf = s;
ctx.sprintf = 1;
- // sprintf max_len
ctx.has_max_len = 1;
ctx.max_len = maxlen;
- // print
+
do_printf(&ctx, args);
- return ctx.written_len;
+ return ctx.possible_written_len;
}
void kputc(char c)
diff --git a/kernel/lib/panic.c b/kernel/lib/panic.c
index d3db908..486f4b5 100644
--- a/kernel/lib/panic.c
+++ b/kernel/lib/panic.c
@@ -3,12 +3,13 @@
#include <stdarg.h>
#include <comus/asm.h>
-__attribute__((noreturn)) void panic(const char *format, ...)
+__attribute__((noreturn)) void __panic(const char *line, const char *file, const char *format, ...)
{
cli();
va_list list;
va_start(list, format);
kprintf("\n\n!!! PANIC !!!\n");
+ kprintf("In file %s at line %s:\n", file, line);
kvprintf(format, list);
kprintf("\n\n");
log_backtrace();
diff --git a/user/include/stdio.h b/user/include/stdio.h
index 9e60f55..0994589 100644
--- a/user/include/stdio.h
+++ b/user/include/stdio.h
@@ -12,6 +12,12 @@
#include <stdarg.h>
#include <stddef.h>
+#define EOF (-1)
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
// TODO: implement
typedef void FILE;
@@ -24,39 +30,53 @@ extern FILE *stdout;
* Prints out a char
*
* @param c - the char
+ * @returns the character written or EOF on failure
*/
-extern void putc(char c);
+extern int putchar(int c);
/**
- * Prints out a null terminated string
+ * Prints out a char to a stream
*
- * @param s - the string
+ * @param c - the char
+ * @param stream - the stream to print to
+ * @returns the character written or EOF on failure
*/
-extern void puts(const char *s);
+extern int putc(int c, FILE *stream);
/**
- * Prints out a char
+ * Prints out a char to a stream
*
- * @param stream - stream to write to
* @param c - the char
+ * @param stream - stream to write to
+ * @returns the character written or EOF on failure
+ */
+extern int fputc(int c, FILE *stream);
+
+/**
+ * Prints out a null terminated string with newline
+ *
+ * @param str - the string
+ * @returns nonnegative integer on success, EOF on error
*/
-extern void fputc(FILE *stream, char c);
+extern int puts(const char *str);
/**
* Prints out a null terminated string
*
+ * @param str - the string
* @param stream - stream to write to
- * @param s - the string
+ * @returns nonnegative integer on success, EOF on error
*/
-extern void fputs(FILE *stream, const char *s);
+extern int fputs(const char *str, FILE *stream);
/**
* prints out a formatted string
*
* @param format - the format string
* @param ... - variable args for the format
+ * @returns number of bytes written
*/
-__attribute__((format(printf, 1, 2))) extern void printf(const char *format,
+__attribute__((format(printf, 1, 2))) extern int printf(const char *format,
...);
/**
@@ -67,7 +87,7 @@ __attribute__((format(printf, 1, 2))) extern void printf(const char *format,
* @param ... - variable args for the format
* @returns number of bytes written
*/
-__attribute__((format(printf, 2, 3))) extern size_t
+__attribute__((format(printf, 2, 3))) extern int
sprintf(char *restrict s, const char *format, ...);
/**
@@ -77,9 +97,9 @@ sprintf(char *restrict s, const char *format, ...);
* @param maxlen - the max len of the buffer
* @param format - the format string
* @param ... - variable args for the format
- * @returns number of bytes written
+ * @returns number of bytes that would of been written (past maxlen)
*/
-__attribute__((format(printf, 3, 4))) extern size_t
+__attribute__((format(printf, 3, 4))) extern int
snprintf(char *restrict s, size_t maxlen, const char *format, ...);
/**
@@ -87,8 +107,9 @@ snprintf(char *restrict s, size_t maxlen, const char *format, ...);
*
* @param format - the format string
* @param args - variable arg list for the format
+ * @returns number of bytes written
*/
-extern void vprintf(const char *format, va_list args);
+extern int vprintf(const char *format, va_list args);
/**
* prints out a formatted string to a buffer
@@ -98,7 +119,7 @@ extern void vprintf(const char *format, va_list args);
* @param args - variable arg list for the format
* @returns number of bytes written
*/
-extern size_t vsprintf(char *restrict s, const char *format, va_list args);
+extern int vsprintf(char *restrict s, const char *format, va_list args);
/**
* prints out a formatted string to a buffer with a given max length
@@ -107,9 +128,9 @@ extern size_t vsprintf(char *restrict s, const char *format, va_list args);
* @param maxlen - the max len of the buffer
* @param format - the format string
* @param args - variable arg list for the format
- * @returns number of bytes written
+ * @returns number of bytes that would of been written (past maxlen)
*/
-extern size_t vsnprintf(char *restrict s, size_t maxlen, const char *format,
+extern int vsnprintf(char *restrict s, size_t maxlen, const char *format,
va_list args);
/**
@@ -135,9 +156,20 @@ extern void vfprintf(FILE *stream, const char *format, va_list args);
* opens a file with a given file name
*
* @param filename - the name of the file to open
+ * @param modes - the modes to open the file in
* @returns the file pointer of success, NULL on error
*/
-extern FILE *fopen(const char *filename);
+extern FILE *fopen(const char *restrict filename, const char *restrict modes);
+
+/**
+ * opens a file with a given file name, replacing en existing stream with it
+ *
+ * @param filename - the name of the file to open
+ * @param modes - the modes to open the file in
+ * @param stream - the stream to replace
+ * @returns the file pointer of success, NULL on error
+ */
+extern FILE *freopen(const char *restrict filename, const char *restrict modes, FILE *restrict stream);
/**
* closes a opened file
@@ -148,22 +180,49 @@ extern void fclose(FILE *stream);
/**
* reads data from a file into a pointer
+ *
* @param ptr - the buffer to write into
* @param size - the size of the block to read
* @param n - the count of blocks to read
* @param stream - the file stream to read from
* @returns the number of blocks read
*/
-extern size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
+extern size_t fread(void *restrict ptr, size_t size, size_t n, FILE *restrict stream);
/**
- * writes data from a pointer into a file
+ * writes data from a pointer into a filename
+ *
* @param ptr - the buffer to read from
* @param size - the size of the block to write
* @param n - the count of blocks to write
* @param stream - the file stream to write into
* @returns the number of blocks written
*/
-extern size_t fwrite(void *ptr, size_t size, size_t n, FILE *stream);
+extern size_t fwrite(const void *restrict ptr, size_t size, size_t n, FILE *restrict stream);
+
+/**
+ * seek to a certain position on stream
+ *
+ * @param stream - the stream to seek
+ * @param off - the offset from whence
+ * @param whence - where to seek from (SEEK_SET, SEEK_CUR, SEEK_END)
+ * @returns 0 on success, -1 on error setting errno
+ */
+extern int fseek(FILE *stream, long int off, int whence);
+
+/**
+ * return the current position of stream
+ *
+ * @param stream - the stream to tell
+ * @return the position on success, -1 on error setting errno
+ */
+extern long int ftell(FILE *stream);
+
+/**
+ * rewing to the begining of a stream
+ *
+ * @param stream - the stream to rewind
+ */
+extern void rewind(FILE *stream);
#endif /* stdio.h */
diff --git a/user/lib/printf.c b/user/lib/printf.c
index 53f98a6..3b5c65f 100644
--- a/user/lib/printf.c
+++ b/user/lib/printf.c
@@ -4,6 +4,7 @@
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
+#include <stdarg.h>
#define PRINTF_NUMERIC_BUF_LEN 50
@@ -74,6 +75,7 @@ typedef struct {
/* output */
size_t written_len;
+ size_t possible_written_len;
bool to_file;
union {
FILE *file;
@@ -86,6 +88,8 @@ typedef struct {
static void printf_putc(context_t *ctx, char c)
{
+ ctx->possible_written_len++;
+
// bounds check
if (ctx->has_max_len)
if (ctx->written_len >= ctx->max_len)
@@ -93,7 +97,7 @@ static void printf_putc(context_t *ctx, char c)
// write to correct
if (ctx->to_file)
- fputc(ctx->out.file, c);
+ fputc(c, ctx->out.file);
else
*(ctx->out.buf++) = c;
@@ -354,9 +358,11 @@ static void handle_string_specifier(context_t *ctx, options_t *opts,
data_t data)
{
char *str = data.str;
- int str_len = 0;
+ if (str == NULL)
+ str = "(null)";
// get length of string
+ int str_len = 0;
if (opts->precision_set)
str_len = opts->precision;
else
@@ -492,6 +498,13 @@ static void do_printf(context_t *ctx, va_list args)
case 's':
handle_string_specifier(ctx, &opts, data);
break;
+ // very terrible why in the love of FUCKING GOD would you do this
+ // but its in printf so im adding it for you fucks
+ case 'n': {
+ size_t *bad = va_arg(args, size_t *);
+ *bad = ctx->written_len;
+ break;
+ }
// unknown
default:
// print from % to current
@@ -500,103 +513,138 @@ static void do_printf(context_t *ctx, va_list args)
break;
}
}
+
+ // add \0 on sprintf
+ if (ctx->to_file == 0) {
+ int len, plen;
+ len = ctx->written_len;
+ plen = ctx->possible_written_len;
+ printf_putc(ctx, '\0');
+ ctx->written_len = len;
+ ctx->possible_written_len = plen;
+ }
}
-void printf(const char *format, ...)
+int printf(const char *format, ...)
{
va_list args;
+ int len;
+
va_start(args, format);
- vprintf(format, args);
+ len = vprintf(format, args);
va_end(args);
+ return len;
}
-size_t sprintf(char *restrict s, const char *format, ...)
+int sprintf(char *restrict s, const char *format, ...)
{
va_list args;
- size_t amt;
+ int len;
+
va_start(args, format);
- amt = vsprintf(s, format, args);
+ len = vsprintf(s, format, args);
va_end(args);
- return amt;
+ return len;
}
-size_t snprintf(char *restrict s, size_t maxlen, const char *format, ...)
+int snprintf(char *restrict s, size_t maxlen, const char *format, ...)
{
va_list args;
- size_t amt;
+ int len;
+
va_start(args, format);
- amt = vsnprintf(s, maxlen, format, args);
+ len = vsnprintf(s, maxlen, format, args);
va_end(args);
- return amt;
+ return len;
}
-void vprintf(const char *format, va_list args)
+int vprintf(const char *format, va_list args)
{
- vfprintf(stdout, format, args);
+ return vfprintf(stdout, format, args);
}
-size_t vsprintf(char *restrict s, const char *format, va_list args)
+int vsprintf(char *restrict s, const char *format, va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // sprintf buffer
ctx.out.buf = s;
ctx.to_file = 0;
- // print
+
do_printf(&ctx, args);
return ctx.written_len;
}
-size_t vsnprintf(char *restrict s, size_t maxlen, const char *format,
+int vsnprintf(char *restrict s, size_t maxlen, const char *format,
va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // sprintf buffer
ctx.out.buf = s;
ctx.to_file = 0;
- // sprintf max_len
ctx.has_max_len = 1;
ctx.max_len = maxlen;
- // print
+
do_printf(&ctx, args);
- return ctx.written_len;
+ return ctx.possible_written_len;
}
-void fprintf(FILE *stream, const char *format, ...)
+int fprintf(FILE *stream, const char *format, ...)
{
va_list args;
+ int len;
+
va_start(args, format);
- vfprintf(stream, format, args);
+ len = vfprintf(stream, format, args);
va_end(args);
+ return len;
}
-void vfprintf(FILE *stream, const char *format, va_list args)
+int vfprintf(FILE *stream, const char *format, va_list args)
{
- // create context
context_t ctx = { 0 };
ctx.format = format;
- // fprintf stream
ctx.out.file = stream;
ctx.to_file = 1;
- // print
+
do_printf(&ctx, args);
+ return ctx.written_len;
}
-void putc(char c)
+int putchar(int c)
{
- fputc(stdout, c);
+ return putc(c, stdout);
}
-void puts(const char *str)
+int putc(int c, FILE *stream)
{
- fputs(stdout, str);
+ return fputc(c, stream);
}
-void fputs(FILE *stream, const char *s)
+int fputc(int c, FILE *stream)
{
- while (*s)
- fputc(stream, *s++);
+ // TODO: a
+ return c;
+}
+
+int puts(const char *str)
+{
+ int res;
+ res = fputs(str, stdout);
+ if (res == EOF)
+ return res;
+ res = fputc('\n', stdout);
+ if (res == EOF)
+ return res;
+ return 0;
+}
+
+int fputs(const char *str, FILE *stream)
+{
+ int res;
+ while (*str) {
+ res = fputc(*str++, stream);
+ if (res == EOF)
+ return res;
+ }
+ return 0;
}