add lseek() function

support readline(), readlines(), writelines() for FILEIO
This commit is contained in:
pikastech 2022-07-18 13:53:39 +08:00
parent d9349b7812
commit 15c0985d2e
8 changed files with 203 additions and 1 deletions

View File

@ -0,0 +1,9 @@
f = open('test/python/main.py', 'r')
s = f.readline()
print(s)
lines = f.readlines()
print(lines)
f.close()

View File

@ -0,0 +1,4 @@
f = open('test/out/file3.txt', 'w')
seq = ['This is the first line.\n', 'This is the second line.\n', 'This is the third line.\n']
f.writelines(seq)
f.close()

View File

@ -101,6 +101,9 @@ class FILEIO:
def close(self): ...
def seek(self, offset: int, *fromwhere) -> int: ...
def tell(self) -> int: ...
def readline(self) -> str: ...
def readlines(self) -> List: ...
def writelines(self, lines: List): ...
class Utils:

View File

@ -1,5 +1,6 @@
#include "PikaStdData_FILEIO.h"
#include <stdio.h>
#include "PikaStdData_List.h"
void PikaStdData_FILEIO_init(PikaObj* self, char* mode, char* path) {
if (obj_isArgExist(self, "_f")) {
@ -100,3 +101,76 @@ int PikaStdData_FILEIO_tell(PikaObj* self) {
}
return __platform_ftell(f);
}
char* PikaStdData_FILEIO_readline(PikaObj* self) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't read line from file\n");
return NULL;
}
obj_setBytes(self, "_line_buff", NULL, PIKA_LINE_BUFF_SIZE);
char* line_buff = (char*)obj_getBytes(self, "_line_buff");
while (1) {
char char_buff[2] = {0};
int n = __platform_fread(char_buff, 1, 1, f);
if (n == 0) {
/* EOF */
return NULL;
}
if (char_buff[0] == '\n') {
/* end of line */
strAppend(line_buff, char_buff);
return line_buff;
}
if (strGetSize(line_buff) >= PIKA_LINE_BUFF_SIZE) {
/* line too long */
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: line too long\n");
return NULL;
}
strAppend(line_buff, char_buff);
}
}
PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't read lines from file\n");
return NULL;
}
PikaObj* line_list = newNormalObj(New_PikaStdData_List);
PikaStdData_List___init__(line_list);
while (1) {
char* line = PikaStdData_FILEIO_readline(self);
if (line == NULL) {
break;
}
Arg* arg_str = arg_setStr(NULL, "", line);
PikaStdData_List_append(line_list, arg_str);
arg_deinit(arg_str);
}
return line_list;
}
void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't write lines to file\n");
return -1;
}
PikaList* list = obj_getPtr(lines, "list");
if (list == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't write lines to file\n");
return -1;
}
int i;
for (i = 0; i < list_getSize(list); i++) {
PikaObj* line = list_getStr(list, i);
PikaStdData_FILEIO_write(self, line);
}
return 0;
}

View File

@ -101,6 +101,9 @@ class FILEIO:
def close(self): ...
def seek(self, offset: int, *fromwhere) -> int: ...
def tell(self) -> int: ...
def readline(self) -> str: ...
def readlines(self) -> List: ...
def writelines(self, lines: List): ...
class Utils:

View File

@ -1,5 +1,6 @@
#include "PikaStdData_FILEIO.h"
#include <stdio.h>
#include "PikaStdData_List.h"
void PikaStdData_FILEIO_init(PikaObj* self, char* mode, char* path) {
if (obj_isArgExist(self, "_f")) {
@ -100,3 +101,77 @@ int PikaStdData_FILEIO_tell(PikaObj* self) {
}
return __platform_ftell(f);
}
char* PikaStdData_FILEIO_readline(PikaObj* self) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't read line from file\n");
return NULL;
}
obj_setBytes(self, "_line_buff", NULL, PIKA_LINE_BUFF_SIZE);
char* line_buff = (char*)obj_getBytes(self, "_line_buff");
while (1) {
char char_buff[2] = {0};
int n = __platform_fread(char_buff, 1, 1, f);
if (n == 0) {
/* EOF */
return NULL;
}
if (char_buff[0] == '\n') {
/* end of line */
strAppend(line_buff, char_buff);
return line_buff;
}
if (strGetSize(line_buff) >= PIKA_LINE_BUFF_SIZE) {
/* line too long */
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: line too long\n");
return NULL;
}
strAppend(line_buff, char_buff);
}
}
PikaObj* PikaStdData_FILEIO_readlines(PikaObj* self) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't read lines from file\n");
return NULL;
}
PikaObj* line_list = newNormalObj(New_PikaStdData_List);
PikaStdData_List___init__(line_list);
while (1) {
char* line = PikaStdData_FILEIO_readline(self);
if (line == NULL) {
break;
}
Arg* arg_str = arg_setStr(NULL, "", line);
PikaStdData_List_append(line_list, arg_str);
arg_deinit(arg_str);
}
return line_list;
}
void PikaStdData_FILEIO_writelines(PikaObj* self, PikaObj* lines) {
FILE* f = obj_getPtr(self, "_f");
if (f == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't write lines to file\n");
return;
}
PikaList* list = obj_getPtr(lines, "list");
if (list == NULL) {
obj_setErrorCode(self, PIKA_RES_ERR_IO);
__platform_printf("Error: can't write lines to file\n");
return;
}
for (size_t i = 0; i < list_getSize(list); i++) {
char* line = list_getStr(list, i);
Arg* arg_str = arg_setStr(NULL, "", line);
PikaStdData_FILEIO_write(self, arg_str);
arg_deinit(arg_str);
}
return;
}

View File

@ -53,3 +53,37 @@ TEST(builtin, seek) {
EXPECT_EQ(pikaMemNow(), 0);
}
#endif
#if PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MAXIMAL
TEST(builtin, file2) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
/* run */
__platform_printf("BEGIN\r\n");
pikaVM_runSingleFile(pikaMain, "../../examples/BuiltIn/file2.py");
/* collect */
char* s = obj_getStr(pikaMain, "s");
/* assert */
EXPECT_STREQ(s, "import PikaStdLib\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif
#if PIKA_SYNTAX_LEVEL == PIKA_SYNTAX_LEVEL_MAXIMAL
TEST(builtin, file3) {
/* init */
pikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
/* run */
__platform_printf("BEGIN\r\n");
pikaVM_runSingleFile(pikaMain, "../../examples/BuiltIn/file3.py");
/* collect */
/* assert */
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif

View File

@ -153,9 +153,9 @@ int __platform_fclose(FILE* stream);
size_t __platform_fwrite(const void* ptr, size_t size, size_t n, FILE* stream);
size_t __platform_fread(void* ptr, size_t size, size_t n, FILE* stream);
int __platform_fseek(FILE* stream, long offset, int whence);
long __platform_ftell(FILE* stream);
/* error */
void __platform_error_handle(void);
long __platform_ftell(FILE* stream);
#endif