From ab0720a5ef25c6a024d5cedf2dd12429dd508f3b Mon Sep 17 00:00:00 2001 From: Add00 Date: Mon, 14 Aug 2023 22:02:33 -0400 Subject: [PATCH] memory leak and several bugs fixed --- repl/lib_fileio.c | 43 +++++++------ test/scripts/lib/fileio.toy | 119 +++++++++++++++++++++++++----------- 2 files changed, 106 insertions(+), 56 deletions(-) diff --git a/repl/lib_fileio.c b/repl/lib_fileio.c index 01ed59d..8cfcfc4 100644 --- a/repl/lib_fileio.c +++ b/repl/lib_fileio.c @@ -196,18 +196,18 @@ static int nativeRead(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) switch (valueLiteral.as.type.typeOf) { - case TOY_LITERAL_BOOLEAN: - { - char value[TOY_MAX_STRING_LENGTH] = {0}; - fgets(value, sizeof(value) - 1, file->fp); - value[TOY_MAX_STRING_LENGTH] = '\0'; + // case TOY_LITERAL_BOOLEAN: + // { + // char value[TOY_MAX_STRING_LENGTH] = {0}; + // fgets(value, sizeof(value) - 1, file->fp); + // value[TOY_MAX_STRING_LENGTH] = '\0'; - Toy_Literal stringLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(value)); - resultLiteral = TOY_TO_BOOLEAN_LITERAL(TOY_IS_TRUTHY(stringLiteral)); - Toy_freeLiteral(stringLiteral); + // Toy_Literal stringLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(value)); + // resultLiteral = TOY_TO_BOOLEAN_LITERAL(TOY_IS_TRUTHY(stringLiteral)); + // Toy_freeLiteral(stringLiteral); - break; - } + // break; + // } case TOY_LITERAL_INTEGER: { @@ -232,7 +232,7 @@ static int nativeRead(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) case TOY_LITERAL_STRING: { char value[TOY_MAX_STRING_LENGTH] = {0}; - fgets(value, sizeof(value) - 1, file->fp); + fread(value, sizeof(char), sizeof(value) - 1, file->fp); value[TOY_MAX_STRING_LENGTH] = '\0'; resultLiteral = TOY_TO_STRING_LITERAL(Toy_createRefString(value)); @@ -372,8 +372,10 @@ static int nativeRename(Toy_Interpreter* interpreter, Toy_LiteralArray* argument return -1; } + Toy_Literal filePathLiteral = Toy_getDrivePathLiteral(interpreter, &valueLiteral); + Toy_File* file = (Toy_File*)TOY_AS_OPAQUE(selfLiteral); - const char* newName = Toy_toCString(TOY_AS_STRING(valueLiteral)); + const char* newName = Toy_toCString(TOY_AS_STRING(filePathLiteral)); // close the file if (file->fp != NULL) { @@ -384,18 +386,20 @@ static int nativeRename(Toy_Interpreter* interpreter, Toy_LiteralArray* argument // rename the file int result = rename(Toy_toCString(file->name), newName); - // attempt to open file + // open file again file->fp = fopen(newName, Toy_toCString(file->mode)); + // update the file object's name Toy_deleteRefString(file->name); file->name = Toy_createRefString(newName); // return result - Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result != 0); + Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result == 0); Toy_pushLiteralArray(&interpreter->stack, resultLiteral); // cleanup Toy_freeLiteral(resultLiteral); + Toy_freeLiteral(filePathLiteral); Toy_freeLiteral(valueLiteral); Toy_freeLiteral(selfLiteral); @@ -462,11 +466,10 @@ static int nativeSeek(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_File* file = (Toy_File*)TOY_AS_OPAQUE(selfLiteral); int offset = TOY_AS_INTEGER(offsetLiteral); - Toy_RefString* orginString = TOY_AS_STRING(originLiteral); + Toy_RefString* orginString = Toy_copyRefString(TOY_AS_STRING(originLiteral)); int origin = 0; - - if (Toy_equalsRefStringCString(orginString, "set")) { + if (Toy_equalsRefStringCString(orginString, "bgn")) { origin = SEEK_SET; } else if (Toy_equalsRefStringCString(orginString, "cur")) { @@ -476,13 +479,13 @@ static int nativeSeek(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) origin = SEEK_END; } - int result = fseek(file->fp, offset, origin); + int result = origin >= SEEK_SET && origin <= SEEK_END? + fseek(file->fp, offset, origin) : -1; Toy_Literal resultLiteral = TOY_TO_BOOLEAN_LITERAL(result == 0); Toy_pushLiteralArray(&interpreter->stack, resultLiteral); // cleanup - Toy_deleteRefString(orginString); Toy_freeLiteral(resultLiteral); Toy_freeLiteral(offsetLiteral); Toy_freeLiteral(selfLiteral); @@ -674,7 +677,7 @@ static int nativeMode(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) Toy_File* file = (Toy_File*)TOY_AS_OPAQUE(selfLiteral); // return the result - Toy_Literal resultLiteral = TOY_TO_STRING_LITERAL(file->mode); + Toy_Literal resultLiteral = TOY_TO_STRING_LITERAL(Toy_copyRefString(file->mode)); Toy_pushLiteralArray(&interpreter->stack, resultLiteral); // cleanup diff --git a/test/scripts/lib/fileio.toy b/test/scripts/lib/fileio.toy index 061bb4d..33ed34c 100644 --- a/test/scripts/lib/fileio.toy +++ b/test/scripts/lib/fileio.toy @@ -2,6 +2,14 @@ import fileio; var PATH: string const = "scripts:/lib/file/fileio.txt"; +// reset file to orginal state +fn reset() { + var writer = open(PATH, "w"); + writer.write("Hello, World!\n"); + + writer.close(); +} + // test global constants { assert MAX_FILENAME_SIZE > 0, "MAX_FILENAME_SIZE failed"; @@ -9,28 +17,89 @@ var PATH: string const = "scripts:/lib/file/fileio.txt"; assert END_OF_FILE == -1, "END_OF_FILE failed"; } +// test read +{ + // // enter test + // assert input.read(string) == "test\n", "read string failed"; + + // // enter 8 + // assert input.read(int) == 8, "read int failed"; + + // // enter 12.5 + // assert input.read(float) == 12.5, "read float failed"; + + // // invaild types + // assert input.read(type) == null, "read type failed"; + // assert input.read(any) == null, "read any failed"; +} + +// test write +{ + assert output.write(8) == true, "write int failed"; + assert output.write("\n") == true, "write string failed"; + assert output.write(12.5) == true, "write float failed"; +} + + // test open and close { var reader = open(PATH, "r"); - assert reader != null, "open failed on existing file"; + assert reader != null, "open failed in reading mode"; + + assert reader.close() == true, "close failed"; var file = open("scripts:/doesNotExist", "r"); assert file == null, "open failed on nonexisting file"; - - assert reader.close() == true, "close failed"; +} + +// test write +{ + var writer = open(PATH, "w"); + assert writer != null, "open failed in writing mode"; + + assert writer.read(string) != null, "read in writing mode failed"; + assert writer.write("writen text") == true, "write in writing mode failed"; + + writer.close(); + reset(); } // test append { var appender = open(PATH, "a"); + assert appender != null, "open failed on appending file"; + assert appender.write("appended text") == true, "append failed"; appender.close(); + reset(); +} - var writer = open(PATH, "w"); - writer.write("Hello, World!\n"); +// test read extended +{ + var reader = open(PATH, "r+"); + assert reader != null, "open failed on read extended mode"; + + assert reader.write("writen text") == true, "write in read extended failed"; + assert reader.read(string) == "d!\n", "read in read extended failed"; + + reader.close(); + reset(); +} + +// test write extended +{ + var writer = open(PATH, "w+"); + assert writer != null, "open failed on write extended mode"; + + assert writer.write("writen text") == true, "write in write extended failed"; + + writer.seek("bgn", 0); + + assert writer.read(string) == "writen text", "read in write extended failed"; writer.close(); + reset(); } // test rename @@ -38,16 +107,17 @@ var PATH: string const = "scripts:/lib/file/fileio.txt"; var reader = open(PATH, "r"); assert reader.rename("scripts:/lib/file/newName.txt") == true, "rename failed"; + reader.rename(PATH); reader.close(); } // test seek { var reader = open(PATH, "r"); - assert reader.seek("set", 6) == true, "seek failed"; + assert reader.seek("bgn", 6) == true, "seek operation failed"; var contents = reader.read(string); - assert contents == " World!\n", "seek failed to move"; + assert contents == " World!\n", "seek failed to move file position"; reader.close(); } @@ -64,36 +134,13 @@ var PATH: string const = "scripts:/lib/file/fileio.txt"; reader.read(string); - // assert reader.error() == false, "error failed"; - // assert reader.completed() == true, "completed failed"; // Leaks for some reason? - // assert reader.position() == 14, "position failed"; - // assert reader.size() == 13, "size failed"; - // assert reader.mode() == "r", "mode failed"; + assert reader.error() == false, "error failed"; + assert reader.completed() == true, "completed after read failed"; + assert reader.position() == 14, "position failed"; + assert reader.size() == 14, "size failed"; + assert reader.mode() == "r", "mode failed"; reader.close(); } -// test write -{ - assert output.write(8), "write int failed"; - assert output.write("\n"), "write string failed"; - assert output.write(12.5), "write float failed"; -} - -// test read -{ - output.write("\n"); - - // enter 8 - assert input.read(int) == 8, "read int failed"; - - // enter 12.5 - assert input.read(float) == 12.5, "read float failed"; - - // enter test - assert input.read(string) == "test\n", "read string failed"; - - // invaild types - assert input.read(type) == null, "type failed"; - assert input.read(any) == null, "any failed"; -} +print "All good"; \ No newline at end of file