X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2FfileIO.c;h=5fdac4cc220950f56f8ea34e592ea0461bd9288c;hb=5c46f86c5a8ceaa63a1a9919cf1f4d2889c6c233;hp=c1a47fff88c5ff1535af76a0f26835535bb988ed;hpb=91dd38c34820c03311738439125675d59bf9e3f1;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/fileIO.c b/Usermode/Libraries/libc.so_src/fileIO.c index c1a47fff..5fdac4cc 100644 --- a/Usermode/Libraries/libc.so_src/fileIO.c +++ b/Usermode/Libraries/libc.so_src/fileIO.c @@ -1,6 +1,7 @@ /* -AcessOS Basic C Library -*/ + * AcessOS Basic C Library + * stdio.c + */ #include "config.h" #include #include @@ -16,20 +17,21 @@ AcessOS Basic C Library #define _stdout 1 // === PROTOTYPES === -EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad); +EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned); struct sFILE *get_file_struct(); // === GLOBALS === struct sFILE _iob[STDIO_MAX_STREAMS]; // IO Buffer -struct sFILE *stdin = &_iob[0]; // Standard Input -struct sFILE *stdout = &_iob[1]; // Standard Output -struct sFILE *stderr = &_iob[2]; // Standard Error +struct sFILE *stdin; // Standard Input +struct sFILE *stdout; // Standard Output +struct sFILE *stderr; // Standard Error +///\note Initialised in SoMain // === CODE === /** - * \fn FILE *freopen(FILE *fp, char *file, char *mode) + * \fn FILE *freopen(char *file, char *mode, FILE *fp) */ -EXPORT FILE *freopen(FILE *fp, char *file, char *mode) +EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp) { int openFlags = 0; int i; @@ -39,8 +41,8 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) if(fp->Flags) { fflush(fp); - close(fp->FD); - } + } else + fp->FD = -1; // Get main mode switch(mode[0]) @@ -80,7 +82,10 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) } //Open File - fp->FD = reopen(fp->FD, file, openFlags); + 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; @@ -93,12 +98,12 @@ EXPORT FILE *freopen(FILE *fp, char *file, char *mode) return fp; } /** - \fn FILE *fopen(char *file, char *mode) + \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(char *file, char *mode) +EXPORT FILE *fopen(const char *file, const char *mode) { FILE *retFile; @@ -108,7 +113,7 @@ EXPORT FILE *fopen(char *file, char *mode) // Create Return Structure retFile = get_file_struct(); - return freopen(retFile, file, mode); + return freopen(file, mode, retFile); } EXPORT void fclose(FILE *fp) @@ -122,11 +127,26 @@ EXPORT void fflush(FILE *fp) ///\todo Implement } +EXPORT long int ftell(FILE *fp) +{ + if(!fp || !fp->FD) return -1; + + return tell(fp->FD); +} + +EXPORT int fseek(FILE *fp, long int amt, int whence) +{ + if(!fp || !fp->FD) return -1; + + return seek(fp->FD, amt, whence); +} + + /** - * \fn int fprintfv(FILE *fp, const char *format, va_list args) + * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args) * \brief Print to a file from a variable argument list */ -EXPORT int fprintfv(FILE *fp, const char *format, va_list args) +EXPORT int vfprintf(FILE *fp, const char *format, va_list args) { va_list tmpList = args; int size; @@ -134,13 +154,13 @@ EXPORT int fprintfv(FILE *fp, const char *format, va_list args) if(!fp || !format) return -1; - size = ssprintfv((char*)format, tmpList); + size = vsprintf(NULL, (char*)format, tmpList); buf = (char*)malloc(size+1); buf[size] = '\0'; // Print - sprintfv(buf, (char*)format, args); + vsprintf(buf, (char*)format, args); // Write to stream write(fp->FD, size+1, buf); @@ -163,13 +183,15 @@ EXPORT int fprintf(FILE *fp, const char *format, ...) // Get Size va_start(args, format); - ret = fprintfv(fp, (char*)format, args); + 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) { @@ -181,6 +203,20 @@ EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) 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) +{ + int ret; + if(!fp || !fp->FD) return -1; + + ret = read(fp->FD, size*num, ptr); + + return ret; +} + /** * \fn EXPORT int fputc(int c, FILE *fp) * \brief Write a single character to the stream @@ -237,33 +273,38 @@ EXPORT int puts(const char *str) //sprintfv /** - \fn EXPORT void sprintfv(char *buf, const char *format, va_list args) + \fn EXPORT void vsprintf(char *buf, const char *format, va_list args) \brief Prints a formatted string to a buffer \param buf Pointer - Destination Buffer \param format String - Format String \param args VarArgs List - Arguments */ -EXPORT void sprintfv(char *buf, const char *format, va_list args) +EXPORT int vsprintf(char *buf, const char *format, va_list args) { char tmp[33]; - int c, arg, minSize; + int c, minSize; int pos = 0; char *p; char pad; + uint64_t arg; + int bLongLong; tmp[32] = '\0'; while((c = *format++) != 0) { - //SysDebug("c = '%c'\n", c); + // Non-control character if (c != '%') { - buf[pos++] = c; + if(buf) buf[pos] = c; + pos ++; continue; } + // Control Character c = *format++; - if(c == '%') { - buf[pos++] = '%'; + if(c == '%') { // Literal % + if(buf) buf[pos] = '%'; + pos ++; continue; } @@ -284,150 +325,104 @@ EXPORT void sprintfv(char *buf, const char *format, va_list args) } } - p = tmp; - - // Get Argument - arg = va_arg(args, int); - // Get Type - switch (c) { - case 'd': - case 'i': - if(arg < 0) { - buf[pos++] = '-'; - arg = -arg; - } - itoa(tmp, arg, 10, minSize, pad); - goto sprintf_puts; - // break; - case 'u': - itoa(tmp, arg, 10, minSize, pad); - goto sprintf_puts; - // break; - case 'x': - itoa(tmp, arg, 16, minSize, pad); - goto sprintf_puts; - // break; - case 'o': - itoa(tmp, arg, 8, minSize, pad); - goto sprintf_puts; - // break; - case 'b': - itoa(tmp, arg, 2, minSize, pad); - goto sprintf_puts; - // break; - - case 's': - p = (void*)arg; - sprintf_puts: - if(!p) p = "(null)"; - while(*p) buf[pos++] = *p++; - break; - - default: - buf[pos++] = arg; - break; - } - } - buf[pos++] = '\0'; -} -/* -ssprintfv -- Size, Stream, Print Formated, Variable Argument List -*/ -/** - \fn EXPORT int ssprintfv(char *format, va_list args) - \brief Gets the total character count from a formatted string - \param format String - Format String - \param args VarArgs - Argument List -*/ -EXPORT int ssprintfv(char *format, va_list args) -{ - char tmp[33]; - int c, arg, minSize; - int len = 0; - char *p; - char pad; - - tmp[32] = '\0'; - - while((c = *format++) != 0) - { - if (c != '%') { - len++; - continue; - } - - c = *format++; - - // Literal '%' - if(c == '%') { - len++; - continue; - } - - // Padding - if(c == '0') { - pad = '0'; - c = *format++; - } else - pad = ' '; - minSize = 0; - if('1' <= c && c <= '9') + // Check for long long + bLongLong = 0; + if(c == 'l') { - while('0' <= c && c <= '9') - { - minSize *= 10; - minSize += c - '0'; - c = *format++; + c = *format++; + if(c == 'l') { + bLongLong = 1; } } - + p = tmp; - arg = va_arg(args, int); - switch (c) { - case 'd': - case 'i': - if(arg < 0) { - len ++; - arg = -arg; - } - itoa(tmp, arg, 10, minSize, pad); + + // Get Type + switch( c ) + { + // Signed Integer + case 'd': case 'i': + // Get Argument + if(bLongLong) arg = va_arg(args, int64_t); + else arg = va_arg(args, int32_t); + itoa(tmp, arg, 10, minSize, pad, 1); goto sprintf_puts; + + // Unsigned Integer case 'u': - itoa(tmp, arg, 10, minSize, pad); + // Get Argument + if(bLongLong) arg = va_arg(args, uint64_t); + else arg = va_arg(args, uint32_t); + itoa(tmp, arg, 10, minSize, pad, 0); goto sprintf_puts; + + // Pointer + case 'p': + if(buf) { + buf[pos] = '*'; + buf[pos+1] = '0'; + buf[pos+2] = 'x'; + } + pos += 3; + // Fall through to hex + // Unsigned Hexadecimal case 'x': - itoa(tmp, arg, 16, minSize, pad); + if(bLongLong) arg = va_arg(args, uint64_t); + else arg = va_arg(args, uint32_t); + itoa(tmp, arg, 16, minSize, pad, 0); goto sprintf_puts; + + // Unsigned Octal case 'o': - itoa(tmp, arg, 8, minSize, pad); - p = tmp; + if(bLongLong) arg = va_arg(args, uint64_t); + else arg = va_arg(args, uint32_t); + itoa(tmp, arg, 8, minSize, pad, 0); goto sprintf_puts; + + // Unsigned binary case 'b': - itoa(tmp, arg, 2, minSize, pad); + if(bLongLong) arg = va_arg(args, uint64_t); + else arg = va_arg(args, uint32_t); + itoa(tmp, arg, 2, minSize, pad, 0); goto sprintf_puts; + // String case 's': - p = (char*)arg; + arg = va_arg(args, uint32_t); + p = (void*)(intptr_t)arg; sprintf_puts: if(!p) p = "(null)"; - while(*p) len++, p++; + if(buf) { + while(*p) { + buf[pos++] = *p++; + } + } + else { + while(*p) { + pos++; p++; + } + } break; + // Unknown, just treat it as a character default: - len ++; + arg = va_arg(args, uint32_t); + if(buf) buf[pos] = arg; + pos ++; break; } } - return len; + if(buf) buf[pos] = '\0'; + + return pos; } const char cUCDIGITS[] = "0123456789ABCDEF"; /** - * \fn static void itoa(char *buf, unsigned long num, int base, int minLength, char pad) + * \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 */ -EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad) +EXPORT void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned) { char tmpBuf[32]; int pos=0, i; @@ -438,17 +433,25 @@ EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad return; } + if(bSigned && (int64_t)num < 0) + { + num = -num; + bSigned = 1; + } else + bSigned = 0; + while(num > base-1) { tmpBuf[pos] = cUCDIGITS[ num % base ]; - num = (long) num / base; //Shift {number} right 1 digit + num = (long) num / base; // Shift {number} right 1 digit pos++; } - tmpBuf[pos++] = cUCDIGITS[ num % base ]; //Last digit of {number} + 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 + while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters buf[i] = 0; } @@ -458,28 +461,34 @@ EXPORT void itoa(char *buf, unsigned long num, int base, int minLength, char pad */ EXPORT int printf(const char *format, ...) { - #if 0 + #if 1 int size; char *buf; va_list args; + // Get final size va_start(args, format); - size = ssprintfv((char*)format, args); + size = vsprintf(NULL, (char*)format, args); va_end(args); + // Allocate buffer buf = (char*)malloc(size+1); buf[size] = '\0'; + // Fill Buffer va_start(args, format); - sprintfv(buf, (char*)format, args); + vsprintf(buf, (char*)format, args); va_end(args); - + // Send to stdout write(_stdout, size+1, buf); + // Free buffer free(buf); + // Return return size; - #endif + + #else int ret; va_list args; @@ -487,6 +496,7 @@ EXPORT int printf(const char *format, ...) ret = fprintfv(stdout, (char*)format, args); va_end(args); return ret; + #endif } /** @@ -495,9 +505,10 @@ EXPORT int printf(const char *format, ...) */ EXPORT int sprintf(char *buf, const char *format, ...) { + int ret; va_list args; va_start(args, format); - sprintfv((char*)buf, (char*)format, args); + ret = vsprintf((char*)buf, (char*)format, args); va_end(args); - return 1; + return ret; }