diff --git a/src/libc/fclose.c b/src/libc/fclose.c index d35a2e328..34d2768dd 100644 --- a/src/libc/fclose.c +++ b/src/libc/fclose.c @@ -19,5 +19,6 @@ int __attribute__((weak)) fclose(FILE *stream) _file_streams[slot - 1].slot = 0; - return ti_Close(slot); + int status = ti_Close(slot); + return (status == 0) ? EOF : 0; } diff --git a/src/libc/getc.src b/src/libc/getc.src new file mode 100644 index 000000000..a0ff98322 --- /dev/null +++ b/src/libc/getc.src @@ -0,0 +1,9 @@ + assume adl=1 + + section .text + + public _getc + +_getc := _fgetc + + extern _fgetc diff --git a/src/libc/include/stdio.h b/src/libc/include/stdio.h index 36e74ae7d..b902f0435 100644 --- a/src/libc/include/stdio.h +++ b/src/libc/include/stdio.h @@ -6,7 +6,7 @@ #ifdef HAS_CUSTOM_FILE #include CUSTOM_FILE_FILE -#else +#else /* HAS_CUSTOM_FILE*/ typedef struct { unsigned char slot; @@ -17,7 +17,7 @@ typedef struct #define stdin ((FILE*)1) #define stdout ((FILE*)2) #define stderr ((FILE*)2) -#endif +#endif /* HAS_CUSTOM_FILE */ #ifndef EOF #define EOF (-1) @@ -36,12 +36,14 @@ typedef struct __BEGIN_DECLS /* weak user-defined functions */ + int inchar(void); void outchar(char character); -FILE *fopen(const char *__restrict filename, - const char *__restrict mode); +FILE *fopen(const char *__restrict filename, const char *__restrict mode); + +FILE *freopen(const char *__restrict filename, const char *__restrict mode, FILE *__restrict stream); int fclose(FILE *stream); @@ -53,36 +55,42 @@ int feof(FILE *stream); void clearerr(FILE *stream); -int fputs(const char *__restrict str, FILE *__restrict stream); - -size_t fread(void *ptr, size_t size, size_t count, FILE *__restrict stream); +size_t fread(void *__restrict ptr, size_t size, size_t count, FILE *__restrict stream); -size_t fwrite(const void *__restrict ptr, size_t size, size_t count, - FILE *__restrict stream); +size_t fwrite(const void *__restrict ptr, size_t size, size_t count, FILE *__restrict stream); long int ftell(FILE *stream) __attribute__((__warn_unused_result__)); int fseek(FILE *stream, long int offset, int origin); +void rewind(FILE *stream); + int fgetc(FILE *stream); -#define getc(...) fgetc(__VA_ARGS__) + +char *fgets(char *__restrict str, int num, FILE *__restrict stream); + +int ungetc(int ch, FILE *stream); int fputc(int c, FILE *stream); -#define putc(...) fputc(__VA_ARGS__) -char *fgets(char *__restrict str, int num, FILE *__restrict stream); +int fputs(const char *__restrict str, FILE *__restrict stream); int remove(const char *filename); -void rewind(FILE *stream); +int rename(const char *old_filename, const char *new_filename); /* standard impls */ + int getchar(void); int putchar(int character); int puts(const char *str); +int getc(FILE *stream); + +int putc(int c, FILE *stream); + int printf(const char *__restrict format, ...) __attribute__((format(__printf__, 1, 2))); @@ -90,7 +98,7 @@ int vprintf(const char *__restrict format, va_list va) __attribute__((format(__printf__, 1, 0))); int sprintf(char *__restrict buffer, const char *__restrict format, ...) - __attribute__((format (__printf__, 2, 3))); + __attribute__((format(__printf__, 2, 3))); int vsprintf(char *__restrict buffer, const char *__restrict format, va_list va) __attribute__((format(__printf__, 2, 0))); @@ -108,7 +116,7 @@ int vfprintf(FILE *__restrict stream, const char *__restrict format, va_list va) __attribute__((format(__printf__, 2, 0))); int asprintf(char **__restrict p_buffer, const char *__restrict format, ...) - __attribute__((format (__printf__, 2, 3))) __attribute__((nonnull(1))); + __attribute__((format(__printf__, 2, 3))) __attribute__((nonnull(1))); int vasprintf(char **__restrict p_buffer, const char *__restrict format, va_list va) __attribute__((format(__printf__, 2, 0))) __attribute__((nonnull(1))); @@ -119,39 +127,44 @@ __END_DECLS #ifdef __cplusplus namespace std { - using ::size_t; - using ::FILE; - - using ::fopen; - using ::fclose; - using ::fflush; - using ::ferror; - using ::feof; - using ::clearerr; - using ::fputs; - using ::fread; - using ::fwrite; - using ::ftell; - using ::fseek; - using ::fgetc; - using ::fputc; - using ::fgets; - using ::remove; - using ::rewind; - using ::getchar; - using ::putchar; - using ::puts; - using ::printf; - using ::vprintf; - using ::sprintf; - using ::vsprintf; - using ::snprintf; - using ::vsnprintf; - using ::fprintf; - using ::vfprintf; - using ::asprintf; - using ::vasprintf; - using ::perror; +using ::size_t; +using ::FILE; + +using ::fopen; +using ::freopen; +using ::fclose; +using ::fflush; +using ::ferror; +using ::feof; +using ::clearerr; +using ::fread; +using ::fwrite; +using ::ftell; +using ::fseek; +using ::rewind; +using ::fgetc; +using ::fgets; +using ::ungetc; +using ::fputc; +using ::fputs; +using ::remove; +using ::rename; +using ::getchar; +using ::putchar; +using ::puts; +using ::getc; +using ::putc; +using ::printf; +using ::vprintf; +using ::sprintf; +using ::vsprintf; +using ::snprintf; +using ::vsnprintf; +using ::fprintf; +using ::vfprintf; +using ::asprintf; +using ::vasprintf; +using ::perror; } /* namespace std */ #endif /* __cplusplus */ diff --git a/src/libc/putc.src b/src/libc/putc.src new file mode 100644 index 000000000..4ce8a9816 --- /dev/null +++ b/src/libc/putc.src @@ -0,0 +1,9 @@ + assume adl=1 + + section .text + + public _putc + +_putc := _fputc + + extern _fputc diff --git a/src/libc/rename.c b/src/libc/rename.c new file mode 100644 index 000000000..67fc9e2ec --- /dev/null +++ b/src/libc/rename.c @@ -0,0 +1,7 @@ +#include +#include + +__attribute__((__weak__)) +int rename(const char *old_filename, const char *new_filename) { + return (int)ti_Rename(old_filename, new_filename); +} diff --git a/test/fileioc/rename/autotest.json b/test/fileioc/rename/autotest.json new file mode 100644 index 000000000..9257ebf8f --- /dev/null +++ b/test/fileioc/rename/autotest.json @@ -0,0 +1,37 @@ +{ + "transfer_files": + [ + "bin/DEMO.8xp" + ], + "target": + { + "name": "DEMO", + "isASM": true + }, + "sequence": + [ + "action|launch", + "delay|500", + "hashWait|1", + "key|enter", + "delay|300", + "hashWait|2" + ], + "hashes": + { + "1": + { + "description": "All tests passed", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ "38E2AD5A" ] + }, + "2": + { + "description": "Test homescreen cleared", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ] + } + } +} diff --git a/test/fileioc/rename/makefile b/test/fileioc/rename/makefile new file mode 100644 index 000000000..d4d6f51d3 --- /dev/null +++ b/test/fileioc/rename/makefile @@ -0,0 +1,16 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = DEMO +ICON = icon.png +DESCRIPTION = "CE C Toolchain Demo" +COMPRESSED = NO +ARCHIVED = NO + +CFLAGS = -Wall -Wextra -Oz +CXXFLAGS = -Wall -Wextra -Oz + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/test/fileioc/rename/src/main.c b/test/fileioc/rename/src/main.c new file mode 100644 index 000000000..552b02867 --- /dev/null +++ b/test/fileioc/rename/src/main.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define C(expr) if (!(expr)) { return __LINE__; } +#define TEST(test) { ret = test; if (ret != 0) { return ret; }} + +static const char *name0 = "foo1"; +static const char *name1 = "bar2"; +static const char *name2 = "foobar3"; + +int test_fileioc_rename(void) { + uint8_t test_fileioc; + uint8_t other_fileioc; + + test_fileioc = ti_Open(name0, "w"); + other_fileioc = ti_Open(name2, "w"); + + C(test_fileioc != 0); + C(other_fileioc != 0); + + // close out of order + + C(ti_Close(other_fileioc) != 0); + C(ti_Close(test_fileioc) != 0); + + // test renames + + // old name doesn't exist + C(ti_Rename(name1, name0) != 0); + + // new name already exists + C(ti_Rename(name0, name2) != 0); + + // valid rename + C(ti_Rename(name0, name1) == 0); + + // delete a file that doesn't exist + C(ti_Delete(name0) == 0); + + // delete a valid file + C(ti_Delete(name1) != 0); + + // delete the same file again + C(ti_Delete(name1) == 0); + + // delete a valid file + C(ti_Delete(name2) != 0); + + return 0; +} + +int test_stdio_rename(void) { + FILE *test_stdio; + FILE *other_stdio; + + test_stdio = fopen(name0, "w"); + other_stdio = fopen(name2, "w"); + + C(test_stdio != NULL); + C(other_stdio != NULL); + + C(fclose(other_stdio) == 0); + C(fclose(test_stdio) == 0); + + // old name doesn't exist + C(rename(name1, name0) != 0); + + // new name already exists + C(rename(name0, name2) != 0); + + // valid rename + C(rename(name0, name1) == 0); + + // delete a file that doesn't exist + C(remove(name0) != 0); + + // delete a valid file + C(remove(name1) == 0); + + // delete the same file again + C(remove(name1) != 0); + + // delete a valid file + C(remove(name2) == 0); + + return 0; +} + +int run_tests(void) { + int ret = 0; + + TEST(test_fileioc_rename()); + TEST(test_stdio_rename()); + + return ret; +} + +int main(void) { + os_ClrHome(); + errno = 0; + int failed_test = run_tests(); + if (errno != 0) { + perror(NULL); + } + if (failed_test != 0) { + char buf[sizeof("Failed test L-8388608\n")]; + boot_sprintf(buf, "Failed test L%d\n", failed_test); + fputs(buf, stdout); + } else { + fputs("All tests passed", stdout); + } + + while (!os_GetCSC()); + + return 0; +}