From: John Hodge (sonata) Date: Wed, 28 Nov 2012 11:05:41 +0000 (+0800) Subject: Usermode/libc - Cleanup of source X-Git-Tag: rel0.15~640 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=166ddd4673dc43e28659516b3f521ba357b9ab27;p=tpg%2Facess2.git Usermode/libc - Cleanup of source --- diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index d2c3190a..b890d482 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -10,8 +10,8 @@ LDFLAGS += -soname libc.so -Map map.txt INCFILES := stdio.h stdlib.h -OBJ = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o -OBJ += perror.o scanf.o signals.o +OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o +OBJ += perror.o scanf.o signals.o strtoi.o OBJ += arch/$(ARCHDIR).ao # signals.o DEPFILES := $(OBJ:%.o=%.d) diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c deleted file mode 100644 index af8f0072..00000000 --- a/Usermode/Libraries/libc.so_src/fileIO.c +++ /dev/null @@ -1,718 +0,0 @@ -/* - * AcessOS Basic C Library - * stdio.c - */ -#include "config.h" -#include -#include -#include -#include -#include "lib.h" -#include "stdio_int.h" - -#define WRITE_STR(_fd, _str) write(_fd, _str, sizeof(_str)) - -#define DEBUG_BUILD 0 - -// === CONSTANTS === -#define _stdin 0 -#define _stdout 1 - -// === PROTOTYPES === -EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned); -struct sFILE *get_file_struct(); - -// === GLOBALS === -struct sFILE _iob[STDIO_MAX_STREAMS]; // IO Buffer -struct sFILE *stdin; // Standard Input -struct sFILE *stdout; // Standard Output -struct sFILE *stderr; // Standard Error -///\note Initialised in SoMain - -// === CODE === -int _fopen_modetoflags(const char *mode) -{ - int flags = 0; - - // Get main mode - switch(*mode) - { - case 'r': flags = FILE_FLAG_MODE_READ; break; - case 'w': flags = FILE_FLAG_MODE_WRITE; break; - case 'a': flags = FILE_FLAG_MODE_APPEND; break; - case 'x': flags = FILE_FLAG_MODE_EXEC; break; // Acess addon - default: - return -1; - } - mode ++; - - // Get Modifiers - for( ; *mode; mode ++ ) - { - switch(*mode) - { - case 'b': flags |= FILE_FLAG_M_BINARY; break; - case '+': flags |= FILE_FLAG_M_EXT; break; - default: - return -1; - } - } - - return flags; -} - -/** - * \fn FILE *freopen(char *file, char *mode, FILE *fp) - */ -EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) -{ - int openFlags = 0; - - // Sanity Check Arguments - if(!fp || !file || !mode) return NULL; - - if(fp->FD != -1) { - fflush(fp); - } - - // Get stdio flags - fp->Flags = _fopen_modetoflags(mode); - if(fp->Flags == -1) - return NULL; - - // Get Open Flags - switch(fp->Flags & FILE_FLAG_MODE_MASK) - { - // Read - case FILE_FLAG_MODE_READ: - openFlags = OPENFLAG_READ; - if(fp->Flags & FILE_FLAG_M_EXT) - openFlags |= OPENFLAG_WRITE; - break; - // Write - case FILE_FLAG_MODE_WRITE: - openFlags = OPENFLAG_WRITE; - if(fp->Flags & FILE_FLAG_M_EXT) - openFlags |= OPENFLAG_READ; - break; - // Execute - case FILE_FLAG_MODE_APPEND: - openFlags = OPENFLAG_APPEND; - if(fp->Flags & FILE_FLAG_M_EXT) - openFlags |= OPENFLAG_READ; - break; - // Execute - case FILE_FLAG_MODE_EXEC: - openFlags = OPENFLAG_EXEC; - break; - } - - //Open File - if(fp->FD != -1) - fp->FD = reopen(fp->FD, file, openFlags); - else - fp->FD = open(file, openFlags); - if(fp->FD == -1) { - fp->Flags = 0; - return NULL; - } - - if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) { - seek(fp->FD, 0, SEEK_END); //SEEK_END - } - - return fp; -} -/** - \fn FILE *fopen(const char *file, const char *mode) - \brief Opens a file and returns the pointer - \param file String - Filename to open - \param mode Mode to open in -*/ -EXPORT FILE *fopen(const char *file, const char *mode) -{ - FILE *retFile; - - // Sanity Check Arguments - if(!file || !mode) return NULL; - - // Create Return Structure - retFile = get_file_struct(); - - return freopen(file, mode, retFile); -} - -EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode) -{ - FILE *ret; - - if( !buffer || !mode ) return NULL; - - ret = get_file_struct(); - - ret->FD = -2; - ret->Flags = _fopen_modetoflags(mode); - if(ret->Flags == -1) { - ret->Flags = 0; - return NULL; - } - - ret->Buffer = buffer; - ret->BufferStart = 0; - ret->BufferSize = length; - - return ret; -} - -EXPORT int fclose(FILE *fp) -{ - fflush(fp); - if( fp->FD != -1 ) { - close(fp->FD); - } - fp->Flags = 0; - fp->FD = -1; - return 0; -} - -EXPORT void fflush(FILE *fp) -{ - if( !fp || fp->FD == -1 ) - return ; - - if( !(fp->Flags & FILE_FLAG_DIRTY) ) - return ; - - // Nothing to do for memory files - if( fp->FD == -2 ) - return ; -} - -EXPORT void clearerr(FILE *fp) -{ - if( !fp || fp->FD == -1 ) - return ; - - // TODO: Impliment clearerr() -} - -EXPORT int feof(FILE *fp) -{ - if( !fp || fp->FD == -1 ) - return 0; - return !!(fp->Flags & FILE_FLAG_EOF); -} - -EXPORT int ferror(FILE *fp) -{ - if( !fp || fp->FD == -1 ) - return 0; - return 0; -} -EXPORT int fileno(FILE *stream) -{ - return stream->FD; -} - -EXPORT off_t ftell(FILE *fp) -{ - if(!fp || fp->FD == -1) return -1; - - if( fp->FD == -2 ) - return fp->Pos; - else - return tell(fp->FD); -} - -EXPORT int fseek(FILE *fp, long int amt, int whence) -{ - if(!fp || fp->FD == -1) return -1; - - if( fp->FD == -2 ) { - switch(whence) - { - case SEEK_CUR: - fp->Pos += amt; - break; - case SEEK_SET: - fp->Pos = amt; - break; - case SEEK_END: - if( fp->BufferSize < (size_t)amt ) - fp->Pos = 0; - else - fp->Pos = fp->BufferSize - amt; - break; - } - if(fp->Pos > (off_t)fp->BufferSize) { - fp->Pos = fp->BufferSize; - fp->Flags |= FILE_FLAG_EOF; - } - return 0; - } - else - return seek(fp->FD, amt, whence); -} - - -/** - * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args) - * \brief Print to a file from a variable argument list - */ -EXPORT int vfprintf(FILE *fp, const char *format, va_list args) -{ - va_list tmpList; - int size; - - if(!fp || !format) return -1; - - va_copy(tmpList, args); - - size = vsnprintf(NULL, 0, (char*)format, tmpList); - char buf[size+1]; - vsnprintf(buf, size+1, (char*)format, args); - - // Write to stream - fwrite(buf, size, 1, fp); - - // Return written byte count - return size; -} - -/** - * \fn int fprintf(FILE *fp, const char *format, ...) - * \brief Print a formatted string to a stream - */ -EXPORT int fprintf(FILE *fp, const char *format, ...) -{ - va_list args; - int ret; - - // Get Size - va_start(args, format); - ret = vfprintf(fp, (char*)format, args); - va_end(args); - - return ret; -} - -/** - * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) - * \brief Write to a stream - */ -EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) -{ - size_t ret; - - if(!fp || fp->FD == -1) - return -1; - - if( fp->FD == -2 ) { - size_t avail = (fp->BufferSize - fp->Pos) / size; - if( avail == 0 ) - fp->Flags |= FILE_FLAG_EOF; - if( num > avail ) num = avail; - size_t bytes = num * size; - memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes); - fp->Pos += bytes; - ret = num; - } - else { - ret = write(fp->FD, ptr, size*num); - ret /= size; - } - - return ret; -} - -/** - * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) - * \brief Read from a stream - */ -EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) -{ - size_t ret; - - if(!fp || fp->FD == -1) - return -1; - - if( fp->FD == -2 ) { - size_t avail = (fp->BufferSize - fp->Pos) / size; - if( avail == 0 ) - fp->Flags |= FILE_FLAG_EOF; - if( num > avail ) num = avail; - size_t bytes = num * size; - memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes); - fp->Pos += bytes; - ret = num; - } - else { - ret = read(fp->FD, ptr, size*num); - ret /= size; - } - - return ret; -} - -/** - * \fn EXPORT int fputc(int c, FILE *fp) - * \brief Write a single character to the stream - */ -EXPORT int fputc(int c, FILE *fp) -{ - return fwrite(&c, 1, 1, fp); -} - -EXPORT int putchar(int c) -{ - c &= 0xFF; - return write(_stdout, &c, 1); -} - -/** - * \fn EXPORT int fgetc(FILE *fp) - * \brief Read a character from the stream - */ -EXPORT int fgetc(FILE *fp) -{ - char ret = 0; - if( fread(&ret, 1, 1, fp) == (size_t)-1 ) - return -1; - return ret; -} - -EXPORT int getchar(void) -{ - char ret = 0; - if(read(_stdin, &ret, 1) != 1) return -1; - return ret; -} - -// --- INTERNAL --- -/** - * \fn FILE *get_file_struct() - * \brief Returns a file descriptor structure - */ -FILE *get_file_struct() -{ - int i; - for(i=0;i= 0) - len = strnlen(p, precision); - else - len = strlen(p); - if(bPadLeft) while(minSize > len++) _addchar(pad); - while( *p ) { - if(precision >= 0 && precision -- == 0) - break; - _addchar(*p++); - } - if(!bPadLeft) while(minSize > len++) _addchar(pad); - break; - - // Unknown, just treat it as a character - default: - arg = va_arg(args, uint32_t); - _addchar(arg); - break; - } - } - _addchar('\0'); - pos --; - - //_SysDebug("vsnprintf: buf = '%s'", buf); - - return pos; -} - -const char cUCDIGITS[] = "0123456789ABCDEF"; -/** - * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned) - * \brief Convert an integer into a character string - * \param buf Destination Buffer - * \param num Number to convert - * \param base Base-n number output - * \param minLength Minimum length of output - * \param pad Padding used to ensure minLength - * \param bSigned Signed number output? - */ -EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned) -{ - char tmpBuf[64]; - int pos=0, i; - - if(!buf) return; - if(base > 16 || base < 2) { - buf[0] = 0; - return; - } - - if(bSigned && (int64_t)num < 0) - { - num = -num; - bSigned = 1; - } else - bSigned = 0; - - // Encode into reversed string - while(num > base-1) { - tmpBuf[pos++] = cUCDIGITS[ num % base ]; - num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit - } - - tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number} - if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed - - i = 0; - minLength -= pos; - while(minLength-- > 0) buf[i++] = pad; - while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters - buf[i] = 0; -} - -/** - * \fn EXPORT int printf(const char *format, ...) - * \brief Print a string to stdout - */ -EXPORT int printf(const char *format, ...) -{ - int size; - va_list args; - - // Get final size - va_start(args, format); - size = vsnprintf(NULL, 0, (char*)format, args); - va_end(args); - char buf[size+1]; - // Fill Buffer - va_start(args, format); - vsnprintf(buf, size+1, (char*)format, args); - va_end(args); - - // Send to stdout - write(_stdout, buf, size+1); - - // Free buffer - free(buf); - // Return - return size; -} - -/** - * \fn EXPORT int sprintf(const char *buf, char *format, ...) - * \brief Print a formatted string to a buffer - */ -EXPORT int sprintf(char *buf, const char *format, ...) -{ - int ret; - va_list args; - va_start(args, format); - ret = vsprintf((char*)buf, (char*)format, args); - va_end(args); - return ret; -} - -/** - * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...) - * \brief Print a formatted string to a buffer - */ -EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...) -{ - int ret; - va_list args; - va_start(args, format); - ret = vsnprintf((char*)buf, maxlen, (char*)format, args); - va_end(args); - return ret; -} diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c new file mode 100644 index 00000000..af8f0072 --- /dev/null +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -0,0 +1,718 @@ +/* + * AcessOS Basic C Library + * stdio.c + */ +#include "config.h" +#include +#include +#include +#include +#include "lib.h" +#include "stdio_int.h" + +#define WRITE_STR(_fd, _str) write(_fd, _str, sizeof(_str)) + +#define DEBUG_BUILD 0 + +// === CONSTANTS === +#define _stdin 0 +#define _stdout 1 + +// === PROTOTYPES === +EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned); +struct sFILE *get_file_struct(); + +// === GLOBALS === +struct sFILE _iob[STDIO_MAX_STREAMS]; // IO Buffer +struct sFILE *stdin; // Standard Input +struct sFILE *stdout; // Standard Output +struct sFILE *stderr; // Standard Error +///\note Initialised in SoMain + +// === CODE === +int _fopen_modetoflags(const char *mode) +{ + int flags = 0; + + // Get main mode + switch(*mode) + { + case 'r': flags = FILE_FLAG_MODE_READ; break; + case 'w': flags = FILE_FLAG_MODE_WRITE; break; + case 'a': flags = FILE_FLAG_MODE_APPEND; break; + case 'x': flags = FILE_FLAG_MODE_EXEC; break; // Acess addon + default: + return -1; + } + mode ++; + + // Get Modifiers + for( ; *mode; mode ++ ) + { + switch(*mode) + { + case 'b': flags |= FILE_FLAG_M_BINARY; break; + case '+': flags |= FILE_FLAG_M_EXT; break; + default: + return -1; + } + } + + return flags; +} + +/** + * \fn FILE *freopen(char *file, char *mode, FILE *fp) + */ +EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) +{ + int openFlags = 0; + + // Sanity Check Arguments + if(!fp || !file || !mode) return NULL; + + if(fp->FD != -1) { + fflush(fp); + } + + // Get stdio flags + fp->Flags = _fopen_modetoflags(mode); + if(fp->Flags == -1) + return NULL; + + // Get Open Flags + switch(fp->Flags & FILE_FLAG_MODE_MASK) + { + // Read + case FILE_FLAG_MODE_READ: + openFlags = OPENFLAG_READ; + if(fp->Flags & FILE_FLAG_M_EXT) + openFlags |= OPENFLAG_WRITE; + break; + // Write + case FILE_FLAG_MODE_WRITE: + openFlags = OPENFLAG_WRITE; + if(fp->Flags & FILE_FLAG_M_EXT) + openFlags |= OPENFLAG_READ; + break; + // Execute + case FILE_FLAG_MODE_APPEND: + openFlags = OPENFLAG_APPEND; + if(fp->Flags & FILE_FLAG_M_EXT) + openFlags |= OPENFLAG_READ; + break; + // Execute + case FILE_FLAG_MODE_EXEC: + openFlags = OPENFLAG_EXEC; + break; + } + + //Open File + if(fp->FD != -1) + fp->FD = reopen(fp->FD, file, openFlags); + else + fp->FD = open(file, openFlags); + if(fp->FD == -1) { + fp->Flags = 0; + return NULL; + } + + if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) { + seek(fp->FD, 0, SEEK_END); //SEEK_END + } + + return fp; +} +/** + \fn FILE *fopen(const char *file, const char *mode) + \brief Opens a file and returns the pointer + \param file String - Filename to open + \param mode Mode to open in +*/ +EXPORT FILE *fopen(const char *file, const char *mode) +{ + FILE *retFile; + + // Sanity Check Arguments + if(!file || !mode) return NULL; + + // Create Return Structure + retFile = get_file_struct(); + + return freopen(file, mode, retFile); +} + +EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode) +{ + FILE *ret; + + if( !buffer || !mode ) return NULL; + + ret = get_file_struct(); + + ret->FD = -2; + ret->Flags = _fopen_modetoflags(mode); + if(ret->Flags == -1) { + ret->Flags = 0; + return NULL; + } + + ret->Buffer = buffer; + ret->BufferStart = 0; + ret->BufferSize = length; + + return ret; +} + +EXPORT int fclose(FILE *fp) +{ + fflush(fp); + if( fp->FD != -1 ) { + close(fp->FD); + } + fp->Flags = 0; + fp->FD = -1; + return 0; +} + +EXPORT void fflush(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return ; + + if( !(fp->Flags & FILE_FLAG_DIRTY) ) + return ; + + // Nothing to do for memory files + if( fp->FD == -2 ) + return ; +} + +EXPORT void clearerr(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return ; + + // TODO: Impliment clearerr() +} + +EXPORT int feof(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return 0; + return !!(fp->Flags & FILE_FLAG_EOF); +} + +EXPORT int ferror(FILE *fp) +{ + if( !fp || fp->FD == -1 ) + return 0; + return 0; +} +EXPORT int fileno(FILE *stream) +{ + return stream->FD; +} + +EXPORT off_t ftell(FILE *fp) +{ + if(!fp || fp->FD == -1) return -1; + + if( fp->FD == -2 ) + return fp->Pos; + else + return tell(fp->FD); +} + +EXPORT int fseek(FILE *fp, long int amt, int whence) +{ + if(!fp || fp->FD == -1) return -1; + + if( fp->FD == -2 ) { + switch(whence) + { + case SEEK_CUR: + fp->Pos += amt; + break; + case SEEK_SET: + fp->Pos = amt; + break; + case SEEK_END: + if( fp->BufferSize < (size_t)amt ) + fp->Pos = 0; + else + fp->Pos = fp->BufferSize - amt; + break; + } + if(fp->Pos > (off_t)fp->BufferSize) { + fp->Pos = fp->BufferSize; + fp->Flags |= FILE_FLAG_EOF; + } + return 0; + } + else + return seek(fp->FD, amt, whence); +} + + +/** + * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args) + * \brief Print to a file from a variable argument list + */ +EXPORT int vfprintf(FILE *fp, const char *format, va_list args) +{ + va_list tmpList; + int size; + + if(!fp || !format) return -1; + + va_copy(tmpList, args); + + size = vsnprintf(NULL, 0, (char*)format, tmpList); + char buf[size+1]; + vsnprintf(buf, size+1, (char*)format, args); + + // Write to stream + fwrite(buf, size, 1, fp); + + // Return written byte count + return size; +} + +/** + * \fn int fprintf(FILE *fp, const char *format, ...) + * \brief Print a formatted string to a stream + */ +EXPORT int fprintf(FILE *fp, const char *format, ...) +{ + va_list args; + int ret; + + // Get Size + va_start(args, format); + ret = vfprintf(fp, (char*)format, args); + va_end(args); + + return ret; +} + +/** + * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) + * \brief Write to a stream + */ +EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) +{ + size_t ret; + + if(!fp || fp->FD == -1) + return -1; + + if( fp->FD == -2 ) { + size_t avail = (fp->BufferSize - fp->Pos) / size; + if( avail == 0 ) + fp->Flags |= FILE_FLAG_EOF; + if( num > avail ) num = avail; + size_t bytes = num * size; + memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes); + fp->Pos += bytes; + ret = num; + } + else { + ret = write(fp->FD, ptr, size*num); + ret /= size; + } + + return ret; +} + +/** + * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) + * \brief Read from a stream + */ +EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) +{ + size_t ret; + + if(!fp || fp->FD == -1) + return -1; + + if( fp->FD == -2 ) { + size_t avail = (fp->BufferSize - fp->Pos) / size; + if( avail == 0 ) + fp->Flags |= FILE_FLAG_EOF; + if( num > avail ) num = avail; + size_t bytes = num * size; + memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes); + fp->Pos += bytes; + ret = num; + } + else { + ret = read(fp->FD, ptr, size*num); + ret /= size; + } + + return ret; +} + +/** + * \fn EXPORT int fputc(int c, FILE *fp) + * \brief Write a single character to the stream + */ +EXPORT int fputc(int c, FILE *fp) +{ + return fwrite(&c, 1, 1, fp); +} + +EXPORT int putchar(int c) +{ + c &= 0xFF; + return write(_stdout, &c, 1); +} + +/** + * \fn EXPORT int fgetc(FILE *fp) + * \brief Read a character from the stream + */ +EXPORT int fgetc(FILE *fp) +{ + char ret = 0; + if( fread(&ret, 1, 1, fp) == (size_t)-1 ) + return -1; + return ret; +} + +EXPORT int getchar(void) +{ + char ret = 0; + if(read(_stdin, &ret, 1) != 1) return -1; + return ret; +} + +// --- INTERNAL --- +/** + * \fn FILE *get_file_struct() + * \brief Returns a file descriptor structure + */ +FILE *get_file_struct() +{ + int i; + for(i=0;i= 0) + len = strnlen(p, precision); + else + len = strlen(p); + if(bPadLeft) while(minSize > len++) _addchar(pad); + while( *p ) { + if(precision >= 0 && precision -- == 0) + break; + _addchar(*p++); + } + if(!bPadLeft) while(minSize > len++) _addchar(pad); + break; + + // Unknown, just treat it as a character + default: + arg = va_arg(args, uint32_t); + _addchar(arg); + break; + } + } + _addchar('\0'); + pos --; + + //_SysDebug("vsnprintf: buf = '%s'", buf); + + return pos; +} + +const char cUCDIGITS[] = "0123456789ABCDEF"; +/** + * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned) + * \brief Convert an integer into a character string + * \param buf Destination Buffer + * \param num Number to convert + * \param base Base-n number output + * \param minLength Minimum length of output + * \param pad Padding used to ensure minLength + * \param bSigned Signed number output? + */ +EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned) +{ + char tmpBuf[64]; + int pos=0, i; + + if(!buf) return; + if(base > 16 || base < 2) { + buf[0] = 0; + return; + } + + if(bSigned && (int64_t)num < 0) + { + num = -num; + bSigned = 1; + } else + bSigned = 0; + + // Encode into reversed string + while(num > base-1) { + tmpBuf[pos++] = cUCDIGITS[ num % base ]; + num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit + } + + tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number} + if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed + + i = 0; + minLength -= pos; + while(minLength-- > 0) buf[i++] = pad; + while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters + buf[i] = 0; +} + +/** + * \fn EXPORT int printf(const char *format, ...) + * \brief Print a string to stdout + */ +EXPORT int printf(const char *format, ...) +{ + int size; + va_list args; + + // Get final size + va_start(args, format); + size = vsnprintf(NULL, 0, (char*)format, args); + va_end(args); + char buf[size+1]; + // Fill Buffer + va_start(args, format); + vsnprintf(buf, size+1, (char*)format, args); + va_end(args); + + // Send to stdout + write(_stdout, buf, size+1); + + // Free buffer + free(buf); + // Return + return size; +} + +/** + * \fn EXPORT int sprintf(const char *buf, char *format, ...) + * \brief Print a formatted string to a buffer + */ +EXPORT int sprintf(char *buf, const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = vsprintf((char*)buf, (char*)format, args); + va_end(args); + return ret; +} + +/** + * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...) + * \brief Print a formatted string to a buffer + */ +EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = vsnprintf((char*)buf, maxlen, (char*)format, args); + va_end(args); + return ret; +} diff --git a/Usermode/Libraries/libc.so_src/stdlib.c b/Usermode/Libraries/libc.so_src/stdlib.c index e15f49b4..6e81c654 100644 --- a/Usermode/Libraries/libc.so_src/stdlib.c +++ b/Usermode/Libraries/libc.so_src/stdlib.c @@ -5,14 +5,8 @@ #include #include #include -#include -#include -#include #include "lib.h" -#define _stdout 1 -#define _stdin 0 - extern void *_crt0_exit_handler; // === PROTOTYPES === @@ -71,124 +65,6 @@ EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void } } -EXPORT unsigned long long strtoull(const char *str, char **end, int base) -{ - long long ret = 0; - - if( !str || base < 0 || base > 36 || base == 1 ) { - if(end) - *end = (char*)str; - errno = EINVAL; - return 0; - } - - while( isspace(*str) ) - str++; - - if( base == 0 || base == 16 ) { - if( *str == '0' && str[1] == 'x' ) { - str += 2; - base = 16; - } - } - - if( base == 0 && *str == '0' ) { - str ++; - base = 8; - } - - if( base == 0 ) - base = 10; - - while( *str ) - { - int next = -1; - if( base <= 10 ) { - if( '0' <= *str && *str <= '0'+base-1 ) - next = *str - '0'; - } - else { - if( '0' <= *str && *str <= '9' ) - next = *str - '0'; - if( 'A' <= *str && *str <= 'A'+base-10-1 ) - next = *str - 'A'; - if( 'a' <= *str && *str <= 'a'+base-10-1 ) - next = *str - 'a'; - } - if( next < 0 ) - break; - ret *= base; - ret += next; - str ++; - } - - if(end) - *end = (char*)str; - return ret; -} - -EXPORT unsigned long strtoul(const char *ptr, char **end, int base) -{ - unsigned long long tmp = strtoull(ptr, end, base); - - if( tmp > ULONG_MAX ) { - errno = ERANGE; - return ULONG_MAX; - } - - return tmp; -} - -EXPORT long long strtoll(const char *str, char **end, int base) -{ - int neg = 0; - unsigned long long ret; - - if( !str ) { - errno = EINVAL; - return 0; - } - - while( isspace(*str) ) - str++; - - // Check for negative (or positive) sign - if(*str == '-' || *str == '+') { - neg = (*str == '-'); - str++; - } - - ret = strtoull(str, end, base); - - if( neg ) - return -ret; - else - return ret; -} - -EXPORT long strtol(const char *str, char **end, int base) -{ - long long tmp = strtoll(str, end, base); - if( tmp > LONG_MAX || tmp < LONG_MIN ) { - errno = ERANGE; - return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN; - } - return tmp; -} - -/** - * \fn EXPORT int atoi(const char *str) - * \brief Convert a string to an integer - */ -EXPORT int atoi(const char *str) -{ - long long tmp = strtoll(str, NULL, 0); - if( tmp > INT_MAX || tmp < INT_MIN ) { - errno = ERANGE; - return (tmp > INT_MAX) ? INT_MAX : INT_MIN; - } - return tmp; -} int abs(int j) { return j < 0 ? -j : j; } long int labs(long int j) { return j < 0 ? -j : j; } diff --git a/Usermode/Libraries/libc.so_src/strtoi.c b/Usermode/Libraries/libc.so_src/strtoi.c new file mode 100644 index 00000000..53756dc8 --- /dev/null +++ b/Usermode/Libraries/libc.so_src/strtoi.c @@ -0,0 +1,135 @@ +/* + * Acess2 C Library + * - By John Hodge (thePowersGang) + * + * strtoi.c + * - strto[u][l]l/atoi implimentation + */ +#include +#include +#include +#include +#include "lib.h" + +EXPORT unsigned long long strtoull(const char *str, char **end, int base) +{ + long long ret = 0; + + if( !str || base < 0 || base > 36 || base == 1 ) { + if(end) + *end = (char*)str; + errno = EINVAL; + return 0; + } + + // Trim leading spaces + while( isspace(*str) ) + str++; + + // Handle base detection for hex + if( base == 0 || base == 16 ) { + if( *str == '0' && str[1] == 'x' ) { + str += 2; + base = 16; + } + } + + // Handle base detection for octal + if( base == 0 && *str == '0' ) { + str ++; + base = 8; + } + + // Fall back on decimal when unknown + if( base == 0 ) + base = 10; + + while( *str ) + { + int next = -1; + if( base <= 10 ) { + if( '0' <= *str && *str <= '0'+base-1 ) + next = *str - '0'; + } + else { + if( '0' <= *str && *str <= '9' ) + next = *str - '0'; + if( 'A' <= *str && *str <= 'A'+base-10-1 ) + next = *str - 'A'; + if( 'a' <= *str && *str <= 'a'+base-10-1 ) + next = *str - 'a'; + } + if( next < 0 ) + break; + ret *= base; + ret += next; + str ++; + } + + if(end) + *end = (char*)str; + return ret; +} + +EXPORT unsigned long strtoul(const char *ptr, char **end, int base) +{ + unsigned long long tmp = strtoull(ptr, end, base); + + if( tmp > ULONG_MAX ) { + errno = ERANGE; + return ULONG_MAX; + } + + return tmp; +} + +EXPORT long long strtoll(const char *str, char **end, int base) +{ + int neg = 0; + unsigned long long ret; + + if( !str ) { + errno = EINVAL; + return 0; + } + + while( isspace(*str) ) + str++; + + // Check for negative (or positive) sign + if(*str == '-' || *str == '+') { + neg = (*str == '-'); + str++; + } + + ret = strtoull(str, end, base); + + if( neg ) + return -ret; + else + return ret; +} + +EXPORT long strtol(const char *str, char **end, int base) +{ + long long tmp = strtoll(str, end, base); + if( tmp > LONG_MAX || tmp < LONG_MIN ) { + errno = ERANGE; + return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN; + } + return tmp; +} + +/** + * \fn EXPORT int atoi(const char *str) + * \brief Convert a string to an integer + */ +EXPORT int atoi(const char *str) +{ + long long tmp = strtoll(str, NULL, 0); + if( tmp > INT_MAX || tmp < INT_MIN ) { + errno = ERANGE; + return (tmp > INT_MAX) ? INT_MAX : INT_MIN; + } + return tmp; +} diff --git a/Usermode/Libraries/libc.so_src/stub.c b/Usermode/Libraries/libc.so_src/stub.c index 7cde4c1b..20e796ee 100644 --- a/Usermode/Libraries/libc.so_src/stub.c +++ b/Usermode/Libraries/libc.so_src/stub.c @@ -4,7 +4,7 @@ #include "stdio_int.h" #include "lib.h" #include -#include +#include #define USE_CPUID 0