\r
INCFILES := stdio.h stdlib.h\r
\r
-OBJ = stub.o heap.o stdlib.o env.o fileIO.o string.o select.o rand.o\r
-OBJ += perror.o scanf.o signals.o\r
+OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o\r
+OBJ += perror.o scanf.o signals.o strtoi.o\r
OBJ += arch/$(ARCHDIR).ao\r
# signals.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
+++ /dev/null
-/*\r
- * AcessOS Basic C Library\r
- * stdio.c\r
- */\r
-#include "config.h"\r
-#include <acess/sys.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include "lib.h"\r
-#include "stdio_int.h"\r
-\r
-#define WRITE_STR(_fd, _str) write(_fd, _str, sizeof(_str))\r
-\r
-#define DEBUG_BUILD 0\r
-\r
-// === CONSTANTS ===\r
-#define _stdin 0\r
-#define _stdout 1\r
-\r
-// === PROTOTYPES ===\r
-EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned);\r
-struct sFILE *get_file_struct();\r
-\r
-// === GLOBALS ===\r
-struct sFILE _iob[STDIO_MAX_STREAMS]; // IO Buffer\r
-struct sFILE *stdin; // Standard Input\r
-struct sFILE *stdout; // Standard Output\r
-struct sFILE *stderr; // Standard Error\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
- \r
- // Sanity Check Arguments\r
- if(!fp || !file || !mode) return NULL;\r
- \r
- if(fp->FD != -1) {\r
- fflush(fp);\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(fp->Flags & FILE_FLAG_MODE_MASK)\r
- {\r
- // 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 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 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
- //Open File\r
- if(fp->FD != -1)\r
- fp->FD = reopen(fp->FD, file, openFlags);\r
- else\r
- fp->FD = open(file, openFlags);\r
- if(fp->FD == -1) {\r
- fp->Flags = 0;\r
- return NULL;\r
- }\r
- \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 fp;\r
-}\r
-/**\r
- \fn FILE *fopen(const char *file, const char *mode)\r
- \brief Opens a file and returns the pointer\r
- \param file String - Filename to open\r
- \param mode Mode to open in\r
-*/\r
-EXPORT FILE *fopen(const char *file, const char *mode)\r
-{\r
- FILE *retFile;\r
- \r
- // Sanity Check Arguments\r
- if(!file || !mode) return NULL;\r
- \r
- // Create Return Structure\r
- retFile = get_file_struct();\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
- 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
-\r
-EXPORT void fflush(FILE *fp)\r
-{\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 *fp)\r
-{\r
- if( !fp || fp->FD == -1 )\r
- return ;\r
- \r
- // TODO: Impliment clearerr()\r
-}\r
-\r
-EXPORT int feof(FILE *fp)\r
-{\r
- if( !fp || fp->FD == -1 )\r
- return 0;\r
- return !!(fp->Flags & FILE_FLAG_EOF);\r
-}\r
-\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
- return stream->FD;\r
-}\r
-\r
-EXPORT off_t ftell(FILE *fp)\r
-{\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 == -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
-/**\r
- * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
- * \brief Print to a file from a variable argument list\r
- */\r
-EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
-{\r
- va_list tmpList;\r
- int size;\r
-\r
- if(!fp || !format) return -1;\r
-\r
- va_copy(tmpList, args);\r
- \r
- size = vsnprintf(NULL, 0, (char*)format, tmpList);\r
- char buf[size+1];\r
- vsnprintf(buf, size+1, (char*)format, args);\r
- \r
- // Write to stream\r
- fwrite(buf, size, 1, fp);\r
- \r
- // Return written byte count\r
- return size;\r
-}\r
-\r
-/**\r
- * \fn int fprintf(FILE *fp, const char *format, ...)\r
- * \brief Print a formatted string to a stream\r
- */\r
-EXPORT int fprintf(FILE *fp, const char *format, ...)\r
-{\r
- va_list args;\r
- int ret;\r
- \r
- // Get Size\r
- va_start(args, format);\r
- ret = vfprintf(fp, (char*)format, args);\r
- va_end(args);\r
- \r
- return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
- * \brief Write to a stream\r
- */\r
-EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\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((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
-/**\r
- * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
- * \brief Read from a stream\r
- */\r
-EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\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
- * \fn EXPORT int fputc(int c, FILE *fp)\r
- * \brief Write a single character to the stream\r
- */\r
-EXPORT int fputc(int c, FILE *fp)\r
-{\r
- return fwrite(&c, 1, 1, fp);\r
-}\r
-\r
-EXPORT int putchar(int c)\r
-{\r
- c &= 0xFF;\r
- return write(_stdout, &c, 1);\r
-}\r
-\r
-/**\r
- * \fn EXPORT int fgetc(FILE *fp)\r
- * \brief Read a character from the stream\r
- */\r
-EXPORT int fgetc(FILE *fp)\r
-{\r
- char ret = 0;\r
- if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
- return -1;\r
- return ret;\r
-}\r
-\r
-EXPORT int getchar(void)\r
-{\r
- char ret = 0;\r
- if(read(_stdin, &ret, 1) != 1) return -1;\r
- return ret;\r
-}\r
-\r
-// --- INTERNAL ---\r
-/**\r
- * \fn FILE *get_file_struct()\r
- * \brief Returns a file descriptor structure\r
- */\r
-FILE *get_file_struct()\r
-{\r
- int i;\r
- for(i=0;i<STDIO_MAX_STREAMS;i++)\r
- {\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
-EXPORT int puts(const char *str)\r
-{\r
- int len;\r
- \r
- if(!str) return 0;\r
- len = strlen(str);\r
- \r
- len = write(_stdout, str, len);\r
- write(_stdout, "\n", 1);\r
- return len;\r
-}\r
-\r
-EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
-{\r
- return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
-}\r
-\r
-//sprintfv\r
-/**\r
- * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
- * \brief Prints a formatted string to a buffer\r
- * \param buf Pointer - Destination Buffer\r
- * \param format String - Format String\r
- * \param args VarArgs List - Arguments\r
- */\r
-EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
-{\r
- char tmp[65];\r
- int c, minSize, precision, len;\r
- size_t pos = 0;\r
- char *p;\r
- char pad;\r
- uint64_t arg;\r
- int bLongLong, bPadLeft;\r
-\r
- void _addchar(char ch)\r
- {\r
- if(buf && pos < __maxlen) buf[pos] = ch;\r
- pos ++;\r
- }\r
-\r
- tmp[32] = '\0';\r
- \r
- while((c = *format++) != 0)\r
- {\r
- // Non-control character\r
- if (c != '%') {\r
- _addchar(c);\r
- continue;\r
- }\r
- \r
- // Control Character\r
- c = *format++;\r
- if(c == '%') { // Literal %\r
- _addchar('%');\r
- continue;\r
- }\r
- \r
- bPadLeft = 0;\r
- bLongLong = 0;\r
- minSize = 0;\r
- precision = -1;\r
- pad = ' ';\r
- \r
- // Padding Character\r
- if(c == '0') {\r
- pad = '0';\r
- c = *format++;\r
- }\r
- // Padding length\r
- if( c == '*' ) {\r
- // Variable length\r
- minSize = va_arg(args, size_t);\r
- c = *format++;\r
- }\r
- else {\r
- if('1' <= c && c <= '9')\r
- {\r
- minSize = 0;\r
- while('0' <= c && c <= '9')\r
- {\r
- minSize *= 10;\r
- minSize += c - '0';\r
- c = *format++;\r
- }\r
- }\r
- }\r
-\r
- // Precision\r
- if(c == '.') {\r
- c = *format++;\r
- if(c == '*') {\r
- precision = va_arg(args, size_t);\r
- c = *format++;\r
- }\r
- else if('1' <= c && c <= '9')\r
- {\r
- precision = 0;\r
- while('0' <= c && c <= '9')\r
- {\r
- precision *= 10;\r
- precision += c - '0';\r
- c = *format++;\r
- }\r
- }\r
- }\r
- \r
- // Check for long long\r
- bLongLong = 0;\r
- if(c == 'l')\r
- {\r
- c = *format++;\r
- if(c == 'l') {\r
- bLongLong = 1;\r
- }\r
- }\r
- \r
- // Just help things along later\r
- p = tmp;\r
- \r
- // Get Type\r
- switch( c )\r
- {\r
- // Signed Integer\r
- case 'd': case 'i':\r
- // Get Argument\r
- if(bLongLong) arg = va_arg(args, int64_t);\r
- else arg = va_arg(args, int32_t);\r
- itoa(tmp, arg, 10, minSize, pad, 1);\r
- precision = -1;\r
- goto sprintf_puts;\r
- \r
- // Unsigned Integer\r
- case 'u':\r
- // Get Argument\r
- if(bLongLong) arg = va_arg(args, uint64_t);\r
- else arg = va_arg(args, uint32_t);\r
- itoa(tmp, arg, 10, minSize, pad, 0);\r
- precision = -1;\r
- goto sprintf_puts;\r
- \r
- // Pointer\r
- case 'p':\r
- _addchar('*');\r
- _addchar('0');\r
- _addchar('x');\r
- arg = va_arg(args, intptr_t);\r
- itoa(tmp, arg, 16, minSize, pad, 0);\r
- precision = -1;\r
- goto sprintf_puts;\r
- // Unsigned Hexadecimal\r
- case 'x':\r
- if(bLongLong) arg = va_arg(args, uint64_t);\r
- else arg = va_arg(args, uint32_t);\r
- itoa(tmp, arg, 16, minSize, pad, 0);\r
- precision = -1;\r
- goto sprintf_puts;\r
- \r
- // Unsigned Octal\r
- case 'o':\r
- if(bLongLong) arg = va_arg(args, uint64_t);\r
- else arg = va_arg(args, uint32_t);\r
- itoa(tmp, arg, 8, minSize, pad, 0);\r
- precision = -1;\r
- goto sprintf_puts;\r
- \r
- // Unsigned binary\r
- case 'b':\r
- if(bLongLong) arg = va_arg(args, uint64_t);\r
- else arg = va_arg(args, uint32_t);\r
- itoa(tmp, arg, 2, minSize, pad, 0);\r
- precision = -1;\r
- goto sprintf_puts;\r
-\r
- // String\r
- case 's':\r
- p = va_arg(args, char*);\r
- sprintf_puts:\r
- if(!p) p = "(null)";\r
- //_SysDebug("vsnprintf: p = '%s'", p);\r
- if(precision >= 0)\r
- len = strnlen(p, precision);\r
- else\r
- len = strlen(p);\r
- if(bPadLeft) while(minSize > len++) _addchar(pad);\r
- while( *p ) {\r
- if(precision >= 0 && precision -- == 0)\r
- break;\r
- _addchar(*p++);\r
- }\r
- if(!bPadLeft) while(minSize > len++) _addchar(pad);\r
- break;\r
-\r
- // Unknown, just treat it as a character\r
- default:\r
- arg = va_arg(args, uint32_t);\r
- _addchar(arg);\r
- break;\r
- }\r
- }\r
- _addchar('\0');\r
- pos --;\r
- \r
- //_SysDebug("vsnprintf: buf = '%s'", buf);\r
- \r
- return pos;\r
-}\r
-\r
-const char cUCDIGITS[] = "0123456789ABCDEF";\r
-/**\r
- * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
- * \brief Convert an integer into a character string\r
- * \param buf Destination Buffer\r
- * \param num Number to convert\r
- * \param base Base-n number output\r
- * \param minLength Minimum length of output\r
- * \param pad Padding used to ensure minLength\r
- * \param bSigned Signed number output?\r
- */\r
-EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)\r
-{\r
- char tmpBuf[64];\r
- int pos=0, i;\r
-\r
- if(!buf) return;\r
- if(base > 16 || base < 2) {\r
- buf[0] = 0;\r
- return;\r
- }\r
- \r
- if(bSigned && (int64_t)num < 0)\r
- {\r
- num = -num;\r
- bSigned = 1;\r
- } else\r
- bSigned = 0;\r
- \r
- // Encode into reversed string\r
- while(num > base-1) {\r
- tmpBuf[pos++] = cUCDIGITS[ num % base ];\r
- num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit\r
- }\r
-\r
- tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number}\r
- if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed\r
- \r
- i = 0;\r
- minLength -= pos;\r
- while(minLength-- > 0) buf[i++] = pad;\r
- while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters\r
- buf[i] = 0;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int printf(const char *format, ...)\r
- * \brief Print a string to stdout\r
- */\r
-EXPORT int printf(const char *format, ...)\r
-{\r
- int size;\r
- va_list args;\r
- \r
- // Get final size\r
- va_start(args, format);\r
- size = vsnprintf(NULL, 0, (char*)format, args);\r
- va_end(args);\r
- char buf[size+1];\r
- // Fill Buffer\r
- va_start(args, format);\r
- vsnprintf(buf, size+1, (char*)format, args);\r
- va_end(args);\r
- \r
- // Send to stdout\r
- write(_stdout, buf, size+1);\r
- \r
- // Free buffer\r
- free(buf);\r
- // Return\r
- return size;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int sprintf(const char *buf, char *format, ...)\r
- * \brief Print a formatted string to a buffer\r
- */\r
-EXPORT int sprintf(char *buf, const char *format, ...)\r
-{\r
- int ret;\r
- va_list args;\r
- va_start(args, format);\r
- ret = vsprintf((char*)buf, (char*)format, args);\r
- va_end(args);\r
- return ret;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...)\r
- * \brief Print a formatted string to a buffer\r
- */\r
-EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...)\r
-{\r
- int ret;\r
- va_list args;\r
- va_start(args, format);\r
- ret = vsnprintf((char*)buf, maxlen, (char*)format, args);\r
- va_end(args);\r
- return ret;\r
-}\r
--- /dev/null
+/*\r
+ * AcessOS Basic C Library\r
+ * stdio.c\r
+ */\r
+#include "config.h"\r
+#include <acess/sys.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "lib.h"\r
+#include "stdio_int.h"\r
+\r
+#define WRITE_STR(_fd, _str) write(_fd, _str, sizeof(_str))\r
+\r
+#define DEBUG_BUILD 0\r
+\r
+// === CONSTANTS ===\r
+#define _stdin 0\r
+#define _stdout 1\r
+\r
+// === PROTOTYPES ===\r
+EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned);\r
+struct sFILE *get_file_struct();\r
+\r
+// === GLOBALS ===\r
+struct sFILE _iob[STDIO_MAX_STREAMS]; // IO Buffer\r
+struct sFILE *stdin; // Standard Input\r
+struct sFILE *stdout; // Standard Output\r
+struct sFILE *stderr; // Standard Error\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
+ \r
+ // Sanity Check Arguments\r
+ if(!fp || !file || !mode) return NULL;\r
+ \r
+ if(fp->FD != -1) {\r
+ fflush(fp);\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(fp->Flags & FILE_FLAG_MODE_MASK)\r
+ {\r
+ // 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 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 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
+ //Open File\r
+ if(fp->FD != -1)\r
+ fp->FD = reopen(fp->FD, file, openFlags);\r
+ else\r
+ fp->FD = open(file, openFlags);\r
+ if(fp->FD == -1) {\r
+ fp->Flags = 0;\r
+ return NULL;\r
+ }\r
+ \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 fp;\r
+}\r
+/**\r
+ \fn FILE *fopen(const char *file, const char *mode)\r
+ \brief Opens a file and returns the pointer\r
+ \param file String - Filename to open\r
+ \param mode Mode to open in\r
+*/\r
+EXPORT FILE *fopen(const char *file, const char *mode)\r
+{\r
+ FILE *retFile;\r
+ \r
+ // Sanity Check Arguments\r
+ if(!file || !mode) return NULL;\r
+ \r
+ // Create Return Structure\r
+ retFile = get_file_struct();\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
+ 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
+\r
+EXPORT void fflush(FILE *fp)\r
+{\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 *fp)\r
+{\r
+ if( !fp || fp->FD == -1 )\r
+ return ;\r
+ \r
+ // TODO: Impliment clearerr()\r
+}\r
+\r
+EXPORT int feof(FILE *fp)\r
+{\r
+ if( !fp || fp->FD == -1 )\r
+ return 0;\r
+ return !!(fp->Flags & FILE_FLAG_EOF);\r
+}\r
+\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
+ return stream->FD;\r
+}\r
+\r
+EXPORT off_t ftell(FILE *fp)\r
+{\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 == -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
+/**\r
+ * \fn EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
+ * \brief Print to a file from a variable argument list\r
+ */\r
+EXPORT int vfprintf(FILE *fp, const char *format, va_list args)\r
+{\r
+ va_list tmpList;\r
+ int size;\r
+\r
+ if(!fp || !format) return -1;\r
+\r
+ va_copy(tmpList, args);\r
+ \r
+ size = vsnprintf(NULL, 0, (char*)format, tmpList);\r
+ char buf[size+1];\r
+ vsnprintf(buf, size+1, (char*)format, args);\r
+ \r
+ // Write to stream\r
+ fwrite(buf, size, 1, fp);\r
+ \r
+ // Return written byte count\r
+ return size;\r
+}\r
+\r
+/**\r
+ * \fn int fprintf(FILE *fp, const char *format, ...)\r
+ * \brief Print a formatted string to a stream\r
+ */\r
+EXPORT int fprintf(FILE *fp, const char *format, ...)\r
+{\r
+ va_list args;\r
+ int ret;\r
+ \r
+ // Get Size\r
+ va_start(args, format);\r
+ ret = vfprintf(fp, (char*)format, args);\r
+ va_end(args);\r
+ \r
+ return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
+ * \brief Write to a stream\r
+ */\r
+EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\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((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
+/**\r
+ * \fn EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\r
+ * \brief Read from a stream\r
+ */\r
+EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp)\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
+ * \fn EXPORT int fputc(int c, FILE *fp)\r
+ * \brief Write a single character to the stream\r
+ */\r
+EXPORT int fputc(int c, FILE *fp)\r
+{\r
+ return fwrite(&c, 1, 1, fp);\r
+}\r
+\r
+EXPORT int putchar(int c)\r
+{\r
+ c &= 0xFF;\r
+ return write(_stdout, &c, 1);\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int fgetc(FILE *fp)\r
+ * \brief Read a character from the stream\r
+ */\r
+EXPORT int fgetc(FILE *fp)\r
+{\r
+ char ret = 0;\r
+ if( fread(&ret, 1, 1, fp) == (size_t)-1 )\r
+ return -1;\r
+ return ret;\r
+}\r
+\r
+EXPORT int getchar(void)\r
+{\r
+ char ret = 0;\r
+ if(read(_stdin, &ret, 1) != 1) return -1;\r
+ return ret;\r
+}\r
+\r
+// --- INTERNAL ---\r
+/**\r
+ * \fn FILE *get_file_struct()\r
+ * \brief Returns a file descriptor structure\r
+ */\r
+FILE *get_file_struct()\r
+{\r
+ int i;\r
+ for(i=0;i<STDIO_MAX_STREAMS;i++)\r
+ {\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
+EXPORT int puts(const char *str)\r
+{\r
+ int len;\r
+ \r
+ if(!str) return 0;\r
+ len = strlen(str);\r
+ \r
+ len = write(_stdout, str, len);\r
+ write(_stdout, "\n", 1);\r
+ return len;\r
+}\r
+\r
+EXPORT int vsprintf(char * __s, const char *__format, va_list __args)\r
+{\r
+ return vsnprintf(__s, 0x7FFFFFFF, __format, __args);\r
+}\r
+\r
+//sprintfv\r
+/**\r
+ * \fn EXPORT void vsnprintf(char *buf, const char *format, va_list args)\r
+ * \brief Prints a formatted string to a buffer\r
+ * \param buf Pointer - Destination Buffer\r
+ * \param format String - Format String\r
+ * \param args VarArgs List - Arguments\r
+ */\r
+EXPORT int vsnprintf(char *buf, size_t __maxlen, const char *format, va_list args)\r
+{\r
+ char tmp[65];\r
+ int c, minSize, precision, len;\r
+ size_t pos = 0;\r
+ char *p;\r
+ char pad;\r
+ uint64_t arg;\r
+ int bLongLong, bPadLeft;\r
+\r
+ void _addchar(char ch)\r
+ {\r
+ if(buf && pos < __maxlen) buf[pos] = ch;\r
+ pos ++;\r
+ }\r
+\r
+ tmp[32] = '\0';\r
+ \r
+ while((c = *format++) != 0)\r
+ {\r
+ // Non-control character\r
+ if (c != '%') {\r
+ _addchar(c);\r
+ continue;\r
+ }\r
+ \r
+ // Control Character\r
+ c = *format++;\r
+ if(c == '%') { // Literal %\r
+ _addchar('%');\r
+ continue;\r
+ }\r
+ \r
+ bPadLeft = 0;\r
+ bLongLong = 0;\r
+ minSize = 0;\r
+ precision = -1;\r
+ pad = ' ';\r
+ \r
+ // Padding Character\r
+ if(c == '0') {\r
+ pad = '0';\r
+ c = *format++;\r
+ }\r
+ // Padding length\r
+ if( c == '*' ) {\r
+ // Variable length\r
+ minSize = va_arg(args, size_t);\r
+ c = *format++;\r
+ }\r
+ else {\r
+ if('1' <= c && c <= '9')\r
+ {\r
+ minSize = 0;\r
+ while('0' <= c && c <= '9')\r
+ {\r
+ minSize *= 10;\r
+ minSize += c - '0';\r
+ c = *format++;\r
+ }\r
+ }\r
+ }\r
+\r
+ // Precision\r
+ if(c == '.') {\r
+ c = *format++;\r
+ if(c == '*') {\r
+ precision = va_arg(args, size_t);\r
+ c = *format++;\r
+ }\r
+ else if('1' <= c && c <= '9')\r
+ {\r
+ precision = 0;\r
+ while('0' <= c && c <= '9')\r
+ {\r
+ precision *= 10;\r
+ precision += c - '0';\r
+ c = *format++;\r
+ }\r
+ }\r
+ }\r
+ \r
+ // Check for long long\r
+ bLongLong = 0;\r
+ if(c == 'l')\r
+ {\r
+ c = *format++;\r
+ if(c == 'l') {\r
+ bLongLong = 1;\r
+ }\r
+ }\r
+ \r
+ // Just help things along later\r
+ p = tmp;\r
+ \r
+ // Get Type\r
+ switch( c )\r
+ {\r
+ // Signed Integer\r
+ case 'd': case 'i':\r
+ // Get Argument\r
+ if(bLongLong) arg = va_arg(args, int64_t);\r
+ else arg = va_arg(args, int32_t);\r
+ itoa(tmp, arg, 10, minSize, pad, 1);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+ \r
+ // Unsigned Integer\r
+ case 'u':\r
+ // Get Argument\r
+ if(bLongLong) arg = va_arg(args, uint64_t);\r
+ else arg = va_arg(args, uint32_t);\r
+ itoa(tmp, arg, 10, minSize, pad, 0);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+ \r
+ // Pointer\r
+ case 'p':\r
+ _addchar('*');\r
+ _addchar('0');\r
+ _addchar('x');\r
+ arg = va_arg(args, intptr_t);\r
+ itoa(tmp, arg, 16, minSize, pad, 0);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+ // Unsigned Hexadecimal\r
+ case 'x':\r
+ if(bLongLong) arg = va_arg(args, uint64_t);\r
+ else arg = va_arg(args, uint32_t);\r
+ itoa(tmp, arg, 16, minSize, pad, 0);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+ \r
+ // Unsigned Octal\r
+ case 'o':\r
+ if(bLongLong) arg = va_arg(args, uint64_t);\r
+ else arg = va_arg(args, uint32_t);\r
+ itoa(tmp, arg, 8, minSize, pad, 0);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+ \r
+ // Unsigned binary\r
+ case 'b':\r
+ if(bLongLong) arg = va_arg(args, uint64_t);\r
+ else arg = va_arg(args, uint32_t);\r
+ itoa(tmp, arg, 2, minSize, pad, 0);\r
+ precision = -1;\r
+ goto sprintf_puts;\r
+\r
+ // String\r
+ case 's':\r
+ p = va_arg(args, char*);\r
+ sprintf_puts:\r
+ if(!p) p = "(null)";\r
+ //_SysDebug("vsnprintf: p = '%s'", p);\r
+ if(precision >= 0)\r
+ len = strnlen(p, precision);\r
+ else\r
+ len = strlen(p);\r
+ if(bPadLeft) while(minSize > len++) _addchar(pad);\r
+ while( *p ) {\r
+ if(precision >= 0 && precision -- == 0)\r
+ break;\r
+ _addchar(*p++);\r
+ }\r
+ if(!bPadLeft) while(minSize > len++) _addchar(pad);\r
+ break;\r
+\r
+ // Unknown, just treat it as a character\r
+ default:\r
+ arg = va_arg(args, uint32_t);\r
+ _addchar(arg);\r
+ break;\r
+ }\r
+ }\r
+ _addchar('\0');\r
+ pos --;\r
+ \r
+ //_SysDebug("vsnprintf: buf = '%s'", buf);\r
+ \r
+ return pos;\r
+}\r
+\r
+const char cUCDIGITS[] = "0123456789ABCDEF";\r
+/**\r
+ * \fn static void itoa(char *buf, uint64_t num, int base, int minLength, char pad, int bSigned)\r
+ * \brief Convert an integer into a character string\r
+ * \param buf Destination Buffer\r
+ * \param num Number to convert\r
+ * \param base Base-n number output\r
+ * \param minLength Minimum length of output\r
+ * \param pad Padding used to ensure minLength\r
+ * \param bSigned Signed number output?\r
+ */\r
+EXPORT void itoa(char *buf, uint64_t num, size_t base, int minLength, char pad, int bSigned)\r
+{\r
+ char tmpBuf[64];\r
+ int pos=0, i;\r
+\r
+ if(!buf) return;\r
+ if(base > 16 || base < 2) {\r
+ buf[0] = 0;\r
+ return;\r
+ }\r
+ \r
+ if(bSigned && (int64_t)num < 0)\r
+ {\r
+ num = -num;\r
+ bSigned = 1;\r
+ } else\r
+ bSigned = 0;\r
+ \r
+ // Encode into reversed string\r
+ while(num > base-1) {\r
+ tmpBuf[pos++] = cUCDIGITS[ num % base ];\r
+ num = (uint64_t) num / (uint64_t)base; // Shift {number} right 1 digit\r
+ }\r
+\r
+ tmpBuf[pos++] = cUCDIGITS[ num % base ]; // Last digit of {number}\r
+ if(bSigned) tmpBuf[pos++] = '-'; // Append sign symbol if needed\r
+ \r
+ i = 0;\r
+ minLength -= pos;\r
+ while(minLength-- > 0) buf[i++] = pad;\r
+ while(pos-- > 0) buf[i++] = tmpBuf[pos]; // Reverse the order of characters\r
+ buf[i] = 0;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int printf(const char *format, ...)\r
+ * \brief Print a string to stdout\r
+ */\r
+EXPORT int printf(const char *format, ...)\r
+{\r
+ int size;\r
+ va_list args;\r
+ \r
+ // Get final size\r
+ va_start(args, format);\r
+ size = vsnprintf(NULL, 0, (char*)format, args);\r
+ va_end(args);\r
+ char buf[size+1];\r
+ // Fill Buffer\r
+ va_start(args, format);\r
+ vsnprintf(buf, size+1, (char*)format, args);\r
+ va_end(args);\r
+ \r
+ // Send to stdout\r
+ write(_stdout, buf, size+1);\r
+ \r
+ // Free buffer\r
+ free(buf);\r
+ // Return\r
+ return size;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int sprintf(const char *buf, char *format, ...)\r
+ * \brief Print a formatted string to a buffer\r
+ */\r
+EXPORT int sprintf(char *buf, const char *format, ...)\r
+{\r
+ int ret;\r
+ va_list args;\r
+ va_start(args, format);\r
+ ret = vsprintf((char*)buf, (char*)format, args);\r
+ va_end(args);\r
+ return ret;\r
+}\r
+\r
+/**\r
+ * \fn EXPORT int snprintf(const char *buf, size_t maxlen, char *format, ...)\r
+ * \brief Print a formatted string to a buffer\r
+ */\r
+EXPORT int snprintf(char *buf, size_t maxlen, const char *format, ...)\r
+{\r
+ int ret;\r
+ va_list args;\r
+ va_start(args, format);\r
+ ret = vsnprintf((char*)buf, maxlen, (char*)format, args);\r
+ va_end(args);\r
+ return ret;\r
+}\r
#include <acess/sys.h>\r
#include <stdlib.h>\r
#include <stdio.h>\r
-#include <errno.h>\r
-#include <ctype.h>\r
-#include <limits.h>\r
#include "lib.h"\r
\r
-#define _stdout 1\r
-#define _stdin 0\r
-\r
extern void *_crt0_exit_handler;\r
\r
// === PROTOTYPES ===\r
}\r
}\r
\r
-EXPORT unsigned long long strtoull(const char *str, char **end, int base)\r
-{\r
- long long ret = 0;\r
- \r
- if( !str || base < 0 || base > 36 || base == 1 ) {\r
- if(end)\r
- *end = (char*)str;\r
- errno = EINVAL;\r
- return 0;\r
- }\r
-\r
- while( isspace(*str) )\r
- str++;\r
- \r
- if( base == 0 || base == 16 ) {\r
- if( *str == '0' && str[1] == 'x' ) {\r
- str += 2;\r
- base = 16;\r
- }\r
- }\r
- \r
- if( base == 0 && *str == '0' ) {\r
- str ++;\r
- base = 8;\r
- }\r
-\r
- if( base == 0 )\r
- base = 10;\r
-\r
- while( *str )\r
- {\r
- int next = -1;\r
- if( base <= 10 ) {\r
- if( '0' <= *str && *str <= '0'+base-1 )\r
- next = *str - '0';\r
- }\r
- else {\r
- if( '0' <= *str && *str <= '9' )\r
- next = *str - '0';\r
- if( 'A' <= *str && *str <= 'A'+base-10-1 )\r
- next = *str - 'A';\r
- if( 'a' <= *str && *str <= 'a'+base-10-1 )\r
- next = *str - 'a';\r
- }\r
- if( next < 0 )\r
- break;\r
- ret *= base;\r
- ret += next;\r
- str ++;\r
- }\r
-\r
- if(end)\r
- *end = (char*)str;\r
- return ret;\r
-}\r
-\r
-EXPORT unsigned long strtoul(const char *ptr, char **end, int base)\r
-{\r
- unsigned long long tmp = strtoull(ptr, end, base);\r
- \r
- if( tmp > ULONG_MAX ) {\r
- errno = ERANGE;\r
- return ULONG_MAX;\r
- }\r
- \r
- return tmp;\r
-}\r
-\r
-EXPORT long long strtoll(const char *str, char **end, int base)\r
-{\r
- int neg = 0;\r
- unsigned long long ret;\r
-\r
- if( !str ) {\r
- errno = EINVAL;\r
- return 0;\r
- }\r
- \r
- while( isspace(*str) )\r
- str++;\r
- \r
- // Check for negative (or positive) sign\r
- if(*str == '-' || *str == '+') {\r
- neg = (*str == '-');\r
- str++;\r
- }\r
-\r
- ret = strtoull(str, end, base); \r
-\r
- if( neg )\r
- return -ret;\r
- else\r
- return ret;\r
-}\r
-\r
-EXPORT long strtol(const char *str, char **end, int base)\r
-{\r
- long long tmp = strtoll(str, end, base);\r
- if( tmp > LONG_MAX || tmp < LONG_MIN ) {\r
- errno = ERANGE;\r
- return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN;\r
- }\r
- return tmp;\r
-}\r
-\r
-/**\r
- * \fn EXPORT int atoi(const char *str)\r
- * \brief Convert a string to an integer\r
- */\r
-EXPORT int atoi(const char *str)\r
-{\r
- long long tmp = strtoll(str, NULL, 0);\r
- if( tmp > INT_MAX || tmp < INT_MIN ) {\r
- errno = ERANGE;\r
- return (tmp > INT_MAX) ? INT_MAX : INT_MIN;\r
- }\r
- return tmp;\r
-}\r
\r
int abs(int j) { return j < 0 ? -j : j; }\r
long int labs(long int j) { return j < 0 ? -j : j; }\r
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * strtoi.c
+ * - strto[u][l]l/atoi implimentation
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#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;
+}
#include "stdio_int.h"\r
#include "lib.h"\r
#include <stdio.h>\r
-#include <sys/sys.h>\r
+#include <acess/sys.h>\r
\r
#define USE_CPUID 0\r
\r