Added {,v}s{,n}printf(3).

This commit is contained in:
Jonas 'Sortie' Termansen 2012-01-09 00:31:42 +01:00
parent 91015a2ea7
commit 10a37e1f98
2 changed files with 62 additions and 4 deletions

View File

@ -100,8 +100,12 @@ extern int putc(int c, FILE* stream);
extern int putchar(int c);
extern int remove(const char* path);
extern void rewind(FILE* stream);
extern int snprintf(char* restrict s, size_t n, const char* restrict format, ...);
extern int sprintf(char* restrict s, const char* restrict format, ...);
extern int vfprintf(FILE* restrict stream, const char* restrict format, va_list ap);
extern int vprintf(const char* restrict format, va_list ap);
extern int vsnprintf(char* restrict, size_t, const char* restrict, va_list);
extern int vsprintf(char* restrict s, const char* restrict format, va_list ap);
/* TODO: These are not implemented in libmaxsi/sortix yet. */
#ifndef SORTIX_UNIMPLEMENTED
@ -128,15 +132,11 @@ extern int rename(const char* oldname, const char* newname);
extern int renameat(int oldfd, const char* oldname, int newfd, const char* newname);
extern int scanf(const char* restrict format, ...);
extern int setvbuf(FILE* restrict stream, char* restrict buf, int type, size_t size);
extern int snprintf(char* restrict s, size_t n, const char* restrict format, ...);
extern int sprintf(char* restrict s, const char* restrict format, ...);
extern int sscanf(const char* restrict s, const char* restrict format, ...);
extern int ungetc(int c, FILE* stream);
extern int vdprintf(int fildes, const char* restrict format, va_list ap);
extern int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);
extern int vscanf(const char* restrict format, va_list arg);
extern int vsnprintf(char* restrict, size_t, const char* restrict, va_list);
extern int vsprintf(char* restrict s, const char* restrict format, va_list ap);
extern int vsscanf(const char* restrict s, const char* restrict format, va_list arg);
extern ssize_t getdelim(char** restrict lineptr, size_t* restrict n, int delimiter, FILE* restrict stream);
extern ssize_t getline(char** restrict lineptr, size_t* restrict n, FILE* restrict stream);

View File

@ -27,6 +27,7 @@
#include "io.h"
#include "format.h"
#include "string.h"
#include "memory.h"
#include <sys/readdirents.h>
#include <unistd.h>
#include <errno.h>
@ -110,6 +111,63 @@ namespace Maxsi
return (int) result;
}
typedef struct vsnprintf_struct
{
char* str;
size_t size;
size_t produced;
size_t written;
} vsnprintf_t;
size_t StringPrintCallback(void* user, const char* string, size_t stringlen)
{
vsnprintf_t* info = (vsnprintf_t*) user;
if ( info->produced < info->size )
{
size_t available = info->size - info->produced;
size_t possible = (stringlen < available) ? stringlen : available;
Memory::Copy(info->str + info->produced, string, possible);
info->written += possible;
}
info->produced += stringlen;
return stringlen;
}
extern "C" int vsnprintf(char* restrict str, size_t size, const char* restrict format, va_list list)
{
vsnprintf_t info;
info.str = str;
info.size = (size) ? size-1 : 0;
info.produced = 0;
info.written = 0;
Maxsi::Format::Virtual(StringPrintCallback, &info, format, list);
if ( size ) { info.str[info.written] = '\0'; }
return (int) info.produced;
}
extern "C" int snprintf(char* restrict str, size_t size, const char* restrict format, ...)
{
va_list list;
va_start(list, format);
int result = vsnprintf(str, size, format, list);
va_end(list);
return result;
}
extern "C" int vsprintf(char* restrict str, const char* restrict format, va_list list)
{
return vsnprintf(str, SIZE_MAX, format, list);
}
extern "C" int sprintf(char* restrict str, const char* restrict format, ...)
{
va_list list;
va_start(list, format);
int result = vsprintf(str, format, list);
va_end(list);
return result;
}
extern "C" void error(int status, int errnum, const char *format, ...)
{
fprintf(stderr, "%s: ", program_invocation_name);