-include ../Makefile.cfg\r
\r
CPPFLAGS += \r
-CFLAGS += \r
+CFLAGS += -Werror -Wextra\r
ASFLAGS +=\r
LDFLAGS += -soname libc.so -Map map.txt -lgcc\r
\r
///\note Initialised in SoMain\r
\r
// === CODE ===\r
+int _fopen_modetoflags(const char *mode)\r
+{\r
+ int flags = 0;\r
+ \r
+ // Get main mode\r
+ switch(*mode)\r
+ {\r
+ case 'r': flags = FILE_FLAG_MODE_READ; break;\r
+ case 'w': flags = FILE_FLAG_MODE_WRITE; break;\r
+ case 'a': flags = FILE_FLAG_MODE_APPEND; break;\r
+ case 'x': flags = FILE_FLAG_MODE_EXEC; break; // Acess addon\r
+ default:\r
+ return -1;\r
+ }\r
+ mode ++;\r
+\r
+ // Get Modifiers\r
+ for( ; *mode; mode ++ )\r
+ {\r
+ switch(*mode)\r
+ {\r
+ case 'b': flags |= FILE_FLAG_M_BINARY; break;\r
+ case '+': flags |= FILE_FLAG_M_EXT; break;\r
+ default:\r
+ return -1;\r
+ }\r
+ }\r
+ \r
+ return flags;\r
+}\r
+\r
/**\r
* \fn FILE *freopen(char *file, char *mode, FILE *fp)\r
*/\r
EXPORT FILE *freopen(const char *file, const char *mode, FILE *fp)\r
{\r
int openFlags = 0;\r
- int i;\r
\r
// Sanity Check Arguments\r
if(!fp || !file || !mode) return NULL;\r
\r
- if(fp->Flags) {\r
+ if(fp->FD != -1) {\r
fflush(fp);\r
- } else\r
- fp->FD = -1;\r
- \r
- // Get main mode\r
- switch(mode[0])\r
- {\r
- case 'r': fp->Flags = FILE_FLAG_MODE_READ; break;\r
- case 'w': fp->Flags = FILE_FLAG_MODE_WRITE; break;\r
- case 'a': fp->Flags = FILE_FLAG_MODE_APPEND; break;\r
- case 'x': fp->Flags = FILE_FLAG_MODE_EXEC; break;\r
- default:\r
- return NULL;\r
- }\r
- // Get Modifiers\r
- for(i=1;mode[i];i++)\r
- {\r
- switch(mode[i])\r
- {\r
- case '+': fp->Flags |= FILE_FLAG_M_EXT;\r
- }\r
}\r
+\r
+ // Get stdio flags\r
+ fp->Flags = _fopen_modetoflags(mode);\r
+ if(fp->Flags == -1)\r
+ return NULL;\r
\r
// Get Open Flags\r
- switch(mode[0])\r
+ switch(fp->Flags & FILE_FLAG_MODE_MASK)\r
{\r
// Read\r
- case 'r': openFlags = OPENFLAG_READ;\r
+ case FILE_FLAG_MODE_READ:\r
+ openFlags = OPENFLAG_READ;\r
if(fp->Flags & FILE_FLAG_M_EXT)\r
openFlags |= OPENFLAG_WRITE;\r
break;\r
// Write\r
- case 'w': openFlags = OPENFLAG_WRITE;\r
+ case FILE_FLAG_MODE_WRITE:\r
+ openFlags = OPENFLAG_WRITE;\r
if(fp->Flags & FILE_FLAG_M_EXT)\r
openFlags |= OPENFLAG_READ;\r
break;\r
// Execute\r
- case 'x': openFlags = OPENFLAG_EXEC;\r
+ case FILE_FLAG_MODE_APPEND:\r
+ openFlags = OPENFLAG_APPEND;\r
+ if(fp->Flags & FILE_FLAG_M_EXT)\r
+ openFlags |= OPENFLAG_READ;\r
+ break;\r
+ // Execute\r
+ case FILE_FLAG_MODE_EXEC:\r
+ openFlags = OPENFLAG_EXEC;\r
break;\r
}\r
\r
return NULL;\r
}\r
\r
- if(mode[0] == 'a') {\r
+ if( (fp->Flags & FILE_FLAG_MODE_MASK) == FILE_FLAG_MODE_APPEND ) {\r
seek(fp->FD, 0, SEEK_END); //SEEK_END\r
}\r
\r
return freopen(file, mode, retFile);\r
}\r
\r
+EXPORT FILE *fmemopen(void *buffer, size_t length, const char *mode)\r
+{\r
+ FILE *ret;\r
+ \r
+ if( !buffer || !mode ) return NULL;\r
+ \r
+ ret = get_file_struct();\r
+ \r
+ ret->FD = -2;\r
+ ret->Flags = _fopen_modetoflags(mode);\r
+ if(ret->Flags == -1) {\r
+ ret->Flags = 0;\r
+ return NULL;\r
+ }\r
+ \r
+ ret->Buffer = buffer;\r
+ ret->BufferStart = 0;\r
+ ret->BufferSize = length;\r
+ \r
+ return ret;\r
+}\r
+\r
EXPORT int fclose(FILE *fp)\r
{\r
- close(fp->FD);\r
+ fflush(fp);\r
+ if( fp->FD != -1 ) {\r
+ close(fp->FD);\r
+ }\r
fp->Flags = 0;\r
fp->FD = -1;\r
return 0;\r
\r
EXPORT void fflush(FILE *fp)\r
{\r
- ///\todo Implement\r
+ if( !fp || fp->FD == -1 )\r
+ return ;\r
+ \r
+ if( !(fp->Flags & FILE_FLAG_DIRTY) )\r
+ return ;\r
+ \r
+ // Nothing to do for memory files\r
+ if( fp->FD == -2 )\r
+ return ;\r
}\r
\r
-EXPORT void clearerr(FILE *stream)\r
+EXPORT void clearerr(FILE *fp)\r
{\r
- /// \todo Impliment\r
+ if( !fp || fp->FD == -1 )\r
+ return ;\r
+ \r
+ // TODO: Impliment clearerr()\r
}\r
\r
-EXPORT int feof(FILE *stream)\r
+EXPORT int feof(FILE *fp)\r
{\r
- return 0; //stream->; // ?\r
+ if( !fp || fp->FD == -1 )\r
+ return 0;\r
+ return !!(fp->Flags & FILE_FLAG_EOF);\r
}\r
\r
-EXPORT int ferror(FILE *stream)\r
+EXPORT int ferror(FILE *fp)\r
{\r
+ if( !fp || fp->FD == -1 )\r
+ return 0;\r
return 0;\r
}\r
EXPORT int fileno(FILE *stream)\r
\r
EXPORT off_t ftell(FILE *fp)\r
{\r
- if(!fp || !fp->FD) return -1;\r
- \r
- return tell(fp->FD);\r
+ if(!fp || fp->FD == -1) return -1;\r
+\r
+ if( fp->FD == -2 )\r
+ return fp->Pos; \r
+ else\r
+ return tell(fp->FD);\r
}\r
\r
EXPORT int fseek(FILE *fp, long int amt, int whence)\r
{\r
- if(!fp || !fp->FD) return -1;\r
- \r
- return seek(fp->FD, amt, whence);\r
+ if(!fp || fp->FD == -1) return -1;\r
+\r
+ if( fp->FD == -2 ) {\r
+ switch(whence)\r
+ {\r
+ case SEEK_CUR:\r
+ fp->Pos += amt;\r
+ break;\r
+ case SEEK_SET:\r
+ fp->Pos = amt;\r
+ break;\r
+ case SEEK_END:\r
+ if( fp->BufferSize < (size_t)amt )\r
+ fp->Pos = 0;\r
+ else\r
+ fp->Pos = fp->BufferSize - amt;\r
+ break;\r
+ }\r
+ if(fp->Pos > (off_t)fp->BufferSize) {\r
+ fp->Pos = fp->BufferSize;\r
+ fp->Flags |= FILE_FLAG_EOF;\r
+ }\r
+ return 0;\r
+ }\r
+ else\r
+ return seek(fp->FD, amt, whence);\r
}\r
\r
\r
vsnprintf(buf, size+1, (char*)format, args);\r
\r
// Write to stream\r
- write(fp->FD, buf, size);\r
- \r
- // Free buffer\r
- free(buf);\r
+ fwrite(buf, size, 1, fp);\r
\r
// Return written byte count\r
return size;\r
*/\r
EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
{\r
- int ret;\r
- if(!fp || !fp->FD) return -1;\r
- \r
- ret = write(fp->FD, ptr, size*num);\r
+ size_t ret;\r
+ \r
+ if(!fp || fp->FD == -1)\r
+ return -1;\r
+\r
+ if( fp->FD == -2 ) {\r
+ size_t avail = (fp->BufferSize - fp->Pos) / size;\r
+ if( avail == 0 )\r
+ fp->Flags |= FILE_FLAG_EOF;\r
+ if( num > avail ) num = avail;\r
+ size_t bytes = num * size;\r
+ memcpy((char*)fp->Buffer + fp->Pos, ptr, bytes);\r
+ fp->Pos += bytes;\r
+ ret = num;\r
+ }\r
+ else { \r
+ ret = write(fp->FD, ptr, size*num);\r
+ ret /= size;\r
+ }\r
\r
return ret;\r
}\r
*/\r
EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
{\r
- int ret;\r
- if(!fp || !fp->FD) return -1;\r
-\r
- // TODO: Fit the spec better with the return value \r
- ret = read(fp->FD, ptr, size*num);\r
- \r
+ size_t ret;\r
+ \r
+ if(!fp || fp->FD == -1)\r
+ return -1;\r
+\r
+ if( fp->FD == -2 ) {\r
+ size_t avail = (fp->BufferSize - fp->Pos) / size;\r
+ if( avail == 0 )\r
+ fp->Flags |= FILE_FLAG_EOF;\r
+ if( num > avail ) num = avail;\r
+ size_t bytes = num * size;\r
+ memcpy(ptr, (char*)fp->Buffer + fp->Pos, bytes);\r
+ fp->Pos += bytes;\r
+ ret = num;\r
+ }\r
+ else {\r
+ ret = read(fp->FD, ptr, size*num);\r
+ ret /= size;\r
+ }\r
+ \r
return ret;\r
}\r
\r
*/\r
EXPORT int fputc(int c, FILE *fp)\r
{\r
- if(!fp || !fp->FD) return -1;\r
- return write(fp->FD, &c, 1);\r
+ return fwrite(&c, 1, 1, fp);\r
}\r
\r
EXPORT int putchar(int c)\r
EXPORT int fgetc(FILE *fp)\r
{\r
char ret = 0;\r
- if(!fp) return -1;\r
- if(read(fp->FD, &ret, 1) == -1) return -1;\r
+ if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
+ return -1;\r
return ret;\r
}\r
\r
int i;\r
for(i=0;i<STDIO_MAX_STREAMS;i++)\r
{\r
- if(_iob[i].Flags == 0) return &_iob[i];\r
+ if(_iob[i].Flags & FILE_FLAG_ALLOC)\r
+ continue ;\r
+ _iob[i].Flags |= FILE_FLAG_ALLOC;\r
+ _iob[i].FD = -1;\r
+ _iob[i].Pos = 0;\r
+ return &_iob[i];\r
}\r
return NULL;\r
}\r
{\r
char tmp[65];\r
int c, minSize, precision, len;\r
- int pos = 0;\r
+ size_t pos = 0;\r
char *p;\r
char pad;\r
uint64_t arg;\r
*/\r
EXPORT int printf(const char *format, ...)\r
{\r
- #if 1\r
int size;\r
va_list args;\r
\r
free(buf);\r
// Return\r
return size;\r
- \r
- #else\r
- \r
- int ret;\r
- va_list args;\r
- va_start(args, format);\r
- ret = fprintfv(stdout, (char*)format, args);\r
- va_end(args);\r
- return ret;\r
- #endif\r
}\r
\r
/**\r
DEBUGS("free(%p) : 0x%x bytes", mem, head->size);\r
\r
//Unify Right\r
- if((intptr_t)head + head->size < (intptr_t)_heap_end)\r
+ if((uintptr_t)head + head->size < (uintptr_t)_heap_end)\r
{\r
heap_head *nextHead = (heap_head*)((intptr_t)head + head->size);\r
if(nextHead->magic == MAGIC_FREE) { //Is the next block free\r
}\r
}\r
//Unify Left\r
- if((intptr_t)head - sizeof(heap_foot) > (intptr_t)_heap_start)\r
+ if((uintptr_t)head - sizeof(heap_foot) > (uintptr_t)_heap_start)\r
{\r
heap_head *prevHead;\r
heap_foot *prevFoot = (heap_foot *)((intptr_t)head - sizeof(heap_foot));\r
if(ch == '\n') return 1;
return 0;
}
+// C99
+static inline int isblank(int ch) {
+ if(ch == ' ') return 1;
+ if(ch == '\t') return 1;
+ return 0;
+}
#endif
#define LOCAL\r
#endif\r
\r
+#define UNUSED(type, param) __attribute__((unused)) type UNUSED__##param\r
+\r
extern void *memcpy(void *dest, const void *src, size_t n);\r
\r
typedef struct sCPUID tCPUID;\r
*/
#include <stdio.h>
#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+
+extern void _SysDebug(const char *format, ...);
+
+enum e_vcscanf_types
+{
+ _VCSCANF_NOTYPE,
+ _VCSCANF_INT,
+ _VCSCANF_REAL,
+};
+
+enum e_vcscanf_sizes
+{
+ _VCSCANF_UNDEF,
+ _VCSCANF_CHAR,
+ _VCSCANF_SHORT,
+ _VCSCANF_LONG,
+ _VCSCANF_LONGLONG,
+ _VCSCANF_INTMAX,
+ _VCSCANF_SIZET,
+ _VCSCANF_PTRDIFF,
+ _VCSCANF_LONGDOUBLE
+};
// === CODE ===
-int _vcscanf(int (*__getc)(void *), void *h, const char *format, va_list ap)
+int _vcscanf_int(int (*__getc)(void *), void (*__rewind)(void*), void *h, int base, int maxlen, long long *outval)
{
- // TODO: Impliment
- return 0;
+ char ich;
+ int sgn = 1;
+ long long int ret = 0;
+ int n_read = 0;
+
+ // Initialise output to something sane
+ *outval = 0;
+
+ // First character
+ // - maxlen == 0 means no limit
+ ich = __getc(h);
+ n_read ++;
+
+ // Sign?
+ if( ich == '-' || ich == '+' ) {
+ sgn = (ich == '-' ? -1 : 1);
+ if( n_read == maxlen )
+ return n_read;
+ ich = __getc(h);
+ n_read ++;
+ }
+
+ // Determine base
+ if( base == 0 ) {
+ if( ich != '0' ) {
+ base = 10;
+ }
+ else {
+ if( n_read == maxlen )
+ return n_read;
+ ich = __getc(h);
+ n_read ++;
+ if( ich != 'x' ) {
+ base = 8;
+ }
+ else {
+ base = 16;
+ if( n_read == maxlen )
+ return n_read;
+ ich = __getc(h);
+ n_read ++;
+ }
+ }
+ }
+
+ if( ich == 0 ) {
+ // Oops?
+ return n_read;
+ }
+
+ while( ich )
+ {
+ int next = -1;
+
+ // Get the digit value
+ if( base <= 10 ) {
+ if( '0' <= ich && ich <= '0'+base-1 )
+ next = ich - '0';
+ }
+ else {
+ if( '0' <= ich && ich <= '9' )
+ next = ich - '0';
+ if( 'A' <= ich && ich <= 'A'+base-10-1 )
+ next = ich - 'A' + 10;
+ if( 'a' <= ich && ich <= 'a'+base-10-1 )
+ next = ich - 'a' + 10;
+ }
+ // if it's not a digit, rewind and break
+ if( next < 0 ) {
+ __rewind(h);
+ n_read --;
+ break;
+ }
+
+ // Add to the result
+ ret *= base;
+ ret += next;
+ //_SysDebug("- %i/%i read, 0x%x val", n_read, maxlen, ret);
+
+ // Check if we've reached the limit
+ if( n_read == maxlen )
+ break ;
+
+ // Next character
+ ich = __getc(h);
+ n_read ++;
+ }
+
+ // Apply sign
+ if( sgn == -1 )
+ ret = -ret;
+
+ *outval = ret;
+ return n_read;
+}
+
+int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char *format, va_list ap)
+{
+ char fch, ich;
+ int ret = 0, nch = 0;
+
+ while( (fch = *format++) )
+ {
+ union {
+ void *_void;
+ char *_char;
+ short *_short;
+ int *_int;
+ long *_long;
+ long long *_longlong;
+ } ptr;
+ long long ival;
+ //long double rval;
+ int maxlen = 0, offset = -1;
+ enum e_vcscanf_sizes size = _VCSCANF_UNDEF;
+ enum e_vcscanf_types valtype;
+
+ const char *set_start;
+ int set_len;
+
+ // Whitespace matches any ammount of whitespace (including none)
+ if( isspace(fch) )
+ {
+ while( (ich = __getc(h)) && isspace(ich) )
+ nch ++;
+ continue ;
+ }
+
+ // Any non-whitespace and non-% characters must match exactly
+ if( fch != '%' )
+ {
+ if( __getc(h) != fch )
+ break;
+ nch ++;
+ continue ;
+ }
+
+ // Format specifier
+ fch = *format++;
+ if(!fch) break;
+
+ // Catch '%%' early
+ if( fch == '%' ) {
+ if( __getc(h) != '%' )
+ break;
+ nch ++;
+ continue ;
+ }
+
+ // %n$ - Direct offset selection, shouldn't be mixed with just %
+ for( ; isdigit(fch); fch = *format++ )
+ maxlen = maxlen * 10 + (fch - '0');
+ if( fch == '$' ) {
+ offset = maxlen;
+ maxlen = 0;
+ }
+
+ // Supress assignemnt?
+ if( fch == '*' )
+ {
+ fch = *format++;
+ ptr._void = NULL;
+ ret --;
+ }
+ else
+ ptr._void = va_arg(ap, void*);
+
+ // Max field length
+ while( isdigit(fch) )
+ {
+ maxlen = maxlen * 10 + fch - '0';
+ fch = *format++;
+ }
+
+ // Length modifier
+ switch( fch )
+ {
+ case 'h':
+ // 'short'
+ size = _VCSCANF_SHORT;
+ fch = *format++;
+ if( fch == 'h' ) {
+ // 'char'
+ size = _VCSCANF_CHAR;
+ fch = *format++;
+ }
+ break;
+ case 'l':
+ // 'long'
+ size = _VCSCANF_LONG;
+ fch = *format++;
+ if( fch == 'l' ) {
+ // 'long long'
+ size = _VCSCANF_LONGLONG;
+ fch = *format++;
+ }
+ break;
+ case 'j':
+ // '(u)intmax_t'
+ size = _VCSCANF_INTMAX;
+ fch = *format++;
+ break;
+ case 'z':
+ // 'size_t'
+ size = _VCSCANF_SIZET;
+ fch = *format++;
+ break;
+ case 't':
+ // 'ptrdiff_t'
+ size = _VCSCANF_PTRDIFF;
+ fch = *format++;
+ break;
+ case 'L':
+ // 'long double' (a, A, e, E, f, F, g, G)
+ size = _VCSCANF_LONGDOUBLE;
+ fch = *format++;
+ break;
+ }
+
+ // Format specifiers
+ switch( fch )
+ {
+ // Decimal integer
+ case 'd':
+ nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival);
+ valtype = _VCSCANF_INT;
+ break;
+ // variable-base integer
+ case 'i':
+ nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival);
+ valtype = _VCSCANF_INT;
+ break;
+ // Octal integer
+ case 'o':
+ nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival);
+ valtype = _VCSCANF_INT;
+ break;
+ // Hexadecimal integer
+ case 'x': case 'X':
+ nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival);
+ valtype = _VCSCANF_INT;
+ break;
+ // strtod format float
+ case 'a': case 'A':
+ case 'e': case 'E':
+ case 'f': case 'F':
+ case 'g': case 'G':
+ valtype = _VCSCANF_REAL;
+ break;
+ // `maxlen` or 1 characters
+ case 'c':
+ if( maxlen == 0 )
+ maxlen = 1;
+ while( maxlen -- && (ich = __getc(h)) )
+ {
+ if(ptr._char) *ptr._char++ = ich;
+ nch ++;
+ }
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ // sequence of non-whitespace characters
+ case 's':
+ if( maxlen == 0 )
+ maxlen = -1;
+
+ ich = 0;
+ while( maxlen -- && (ich = __getc(h)) && !isblank(ich) )
+ {
+ if(ptr._char) *ptr._char++ = ich;
+ nch ++;
+ }
+ if( maxlen >= 0 && ich )
+ __rewind(h);
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ // match a set of characters
+ case '[':
+ fch = *format++;
+ if( fch == '^' ) {
+ // Invert
+ fch = *format;
+ }
+ set_start = format;
+ set_len = 0;
+ // if the first character is ']' it's part of the set
+ do {
+ // permissable character
+ set_len ++;
+ fch = *format++;
+ } while( fch && fch != ']' );
+
+ ich = 0;
+ while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) )
+ {
+ if(ptr._char) *ptr._char++ = ich;
+ nch ++;
+ }
+ if( maxlen >= 0 && ich )
+ __rewind(h);
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ case 'p': // read back printf("%p")
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ case 'n': // number of read characters to this point
+ if(ptr._int) {
+ *ptr._int = nch;
+ ret --; // negates the ret ++ at the end
+ }
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ default:
+ // Implimentation defined
+ valtype = _VCSCANF_NOTYPE;
+ break;
+ }
+
+ switch(valtype)
+ {
+ case _VCSCANF_NOTYPE:
+ // Used when assignment is done above
+ break;
+ case _VCSCANF_INT:
+ switch(size)
+ {
+ case _VCSCANF_UNDEF: *ptr._int = ival; break;
+ case _VCSCANF_CHAR: *ptr._char = ival; break;
+ case _VCSCANF_SHORT: *ptr._short = ival; break;
+ case _VCSCANF_LONG: *ptr._long = ival; break;
+ case _VCSCANF_LONGLONG: *ptr._longlong = ival; break;
+ default: // ???
+ break;
+ }
+ break;
+ case _VCSCANF_REAL:
+ break;
+ }
+
+ ret ++;
+ }
+
+ return ret;
}
int _vsscanf_getc(void *h)
{
const char **ibuf = h;
- return *(*ibuf)++; // Dereference, read, increment
+ return *(*ibuf)++; // Dereference, read for return, increment
+}
+
+void _vsscanf_rewind(void *h)
+{
+ const char **ibuf = h;
+ (*ibuf) --; // NOTE: Breaks if there's a rewind before a getc, but that shouldn't happen
}
int vscanf(const char *format, va_list ap)
int vsscanf(const char *str, const char *format, va_list ap)
{
- return _vcscanf(_vsscanf_getc, &str, format, ap);
+ return _vcscanf(_vsscanf_getc, _vsscanf_rewind, &str, format, ap);
}
int _vfscanf_getc(void *h)
{
return fgetc(h); // TODO: Handle -1 -> 0
}
+void _vfscanf_rewind(void *h)
+{
+ fseek(h, -1, SEEK_CUR);
+}
int vfscanf(FILE *stream, const char *format, va_list ap)
{
- return _vcscanf(_vfscanf_getc, stream, format, ap);
+ return _vcscanf(_vfscanf_getc, _vfscanf_rewind, stream, format, ap);
}
int scanf(const char *format, ...)
* Configuration Options
*/
#ifndef _STDIO_INT_H
-# define _STDIO_INT_H
+#define _STDIO_INT_H
+
+#include <sys/types.h>
+#include <stddef.h>
// === CONSTANTS ===
-#define FILE_FLAG_MODE_MASK 0x07
-#define FILE_FLAG_MODE_READ 0x01
-#define FILE_FLAG_MODE_WRITE 0x02
-#define FILE_FLAG_MODE_EXEC 0x03
-#define FILE_FLAG_MODE_APPEND 0x04
-#define FILE_FLAG_M_EXT 0x10
+#define FILE_FLAG_MODE_MASK 0x0007
+#define FILE_FLAG_MODE_READ 0x0001
+#define FILE_FLAG_MODE_WRITE 0x0002
+#define FILE_FLAG_MODE_EXEC 0x0003
+#define FILE_FLAG_MODE_APPEND 0x0004
+#define FILE_FLAG_M_EXT 0x0010
+#define FILE_FLAG_M_BINARY 0x0020
+#define FILE_FLAG_EOF 0x0100
+#define FILE_FLAG_DIRTY 0x0200
+#define FILE_FLAG_ALLOC 0x1000
// === TYPES ===
struct sFILE {
- int FD;
int Flags;
+ int FD;
+ off_t Pos;
+
#if DEBUG_BUILD
- char *FileName;
- #endif
- #if STDIO_LOCAL_BUFFER
- char *Buffer;
- Uint64 BufferStart;
- int BufferSize;
+ char *FileName; // heap
#endif
+ void *Buffer;
+ off_t BufferStart;
+ size_t BufferSize;
};
#endif
*/\r
EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *))\r
{\r
- int i, j, min;\r
+ size_t i, j, min;\r
// With 0 items, there's nothing to do and with 1 its already sorted\r
if(nmemb == 0 || nmemb == 1) return;\r
\r
char *sp = (char *)src;
char *dp = (char *)dest;
// Check if the areas overlap
- if( (intptr_t)src < (intptr_t)dest && (intptr_t)dest < (intptr_t)src+count )
+ if( (uintptr_t)src < (uintptr_t)dest && (uintptr_t)dest < (uintptr_t)src+count )
for(;count--;)
dp[count] = sp[count];
else
* \param argv Unused - Arguments (NULL for current version of ld-acess)\r
* \param envp Environment Pointer\r
*/\r
-int SoMain(unsigned int BaseAddress, int argc, char **argv, char **envp)\r
+int SoMain(UNUSED(uintptr_t, BaseAddress), UNUSED(int, argc), UNUSED(char **, argv), char **envp)\r
{\r
// Init for env.c\r
_envp = envp;\r