mirror of
https://github.com/kenshineto/kern.git
synced 2025-04-16 23:47:25 +00:00
make lib betterer
This commit is contained in:
parent
f3b610289f
commit
c5cbf5d747
6 changed files with 249 additions and 109 deletions
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
size_t 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 kvsprintf(char *restrict s, const char *format, va_list args)
|
||||
{
|
||||
context_t ctx = { 0 };
|
||||
ctx.format = format;
|
||||
ctx.sprintf_buf = s;
|
||||
ctx.sprintf = 1;
|
||||
|
||||
do_printf(&ctx, args);
|
||||
return ctx.written_len;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
extern void puts(const char *s);
|
||||
|
||||
/**
|
||||
* Prints out a char
|
||||
*
|
||||
* @param stream - stream to write to
|
||||
* @param c - the char
|
||||
* @param stream - the stream to print to
|
||||
* @returns the character written or EOF on failure
|
||||
*/
|
||||
extern void fputc(FILE *stream, char c);
|
||||
extern int putc(int c, FILE *stream);
|
||||
|
||||
/**
|
||||
* Prints out a char to a stream
|
||||
*
|
||||
* @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 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 */
|
||||
|
|
|
@ -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.possible_written_len;
|
||||
}
|
||||
|
||||
int fprintf(FILE *stream, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
va_start(args, format);
|
||||
len = vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
return len;
|
||||
}
|
||||
|
||||
int vfprintf(FILE *stream, const char *format, va_list args)
|
||||
{
|
||||
context_t ctx = { 0 };
|
||||
ctx.format = format;
|
||||
ctx.out.file = stream;
|
||||
ctx.to_file = 1;
|
||||
|
||||
do_printf(&ctx, args);
|
||||
return ctx.written_len;
|
||||
}
|
||||
|
||||
void fprintf(FILE *stream, const char *format, ...)
|
||||
int putchar(int c)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
return putc(c, stdout);
|
||||
}
|
||||
|
||||
void vfprintf(FILE *stream, const char *format, va_list args)
|
||||
int putc(int c, FILE *stream)
|
||||
{
|
||||
// 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 fputc(c, stream);
|
||||
}
|
||||
|
||||
void putc(char c)
|
||||
int fputc(int c, FILE *stream)
|
||||
{
|
||||
fputc(stdout, c);
|
||||
// TODO: a
|
||||
return c;
|
||||
}
|
||||
|
||||
void puts(const char *str)
|
||||
int puts(const char *str)
|
||||
{
|
||||
fputs(stdout, str);
|
||||
int res;
|
||||
res = fputs(str, stdout);
|
||||
if (res == EOF)
|
||||
return res;
|
||||
res = fputc('\n', stdout);
|
||||
if (res == EOF)
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fputs(FILE *stream, const char *s)
|
||||
int fputs(const char *str, FILE *stream)
|
||||
{
|
||||
while (*s)
|
||||
fputc(stream, *s++);
|
||||
int res;
|
||||
while (*str) {
|
||||
res = fputc(*str++, stream);
|
||||
if (res == EOF)
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue