From d42ec42977d2bbf1da5040a1ae502b96f0dab1b6 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Thu, 24 Mar 2022 19:26:59 +0530 Subject: [PATCH 1/5] Implementation of file accessing using OS Module --- integration_tests/run_tests.py | 1 + integration_tests/test_os.py | 14 +++++++++ src/runtime/impure/lfortran_intrinsics.c | 36 ++++++++++++++++++++++++ src/runtime/impure/lfortran_intrinsics.h | 3 ++ src/runtime/os.py | 32 +++++++++++++++++++++ 5 files changed, 86 insertions(+) create mode 100644 integration_tests/test_os.py create mode 100644 src/runtime/os.py diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index 1359a79031..070132a72d 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -20,6 +20,7 @@ "test_numpy_01.py", "test_numpy_02.py", "test_random.py", + # "test_os.py", "test_builtin.py", "test_builtin_abs.py", "test_builtin_bool.py", diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py new file mode 100644 index 0000000000..8a093ef617 --- /dev/null +++ b/integration_tests/test_os.py @@ -0,0 +1,14 @@ +from ltypes import i64 +from os import (open, read, close) + +def test(): + path: str + path = "integration_tests/test_os.py" + fd: i64 + n: i64 + fd = open(path) + n = 100 + print(read(fd, n)) + close(fd) + +test() diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index aeb59f5ebd..0a080e3a4e 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include "lfortran_intrinsics.h" @@ -786,3 +788,37 @@ LFORTRAN_API void _lfortran_dp_rand_num(double *x) { srand(time(0)); *x = rand() / (double) RAND_MAX; } + +LFORTRAN_API int64_t _lpython_open(char *path) +{ + int64_t fd = open(path, O_RDONLY); + if (fd < 0) + { + printf("Error in opening the file!\n"); + perror(path); + exit(1); + } + return fd; +} + +LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n) +{ + char *c = (char *) calloc(n, sizeof(char)); + if (fd < 0) + { + printf("Error in reading the file!\n"); + exit(1); + } + int x = read(fd, c, n); + c[x] = '\0'; + return c; +} + +LFORTRAN_API void _lpython_close(int64_t fd) +{ + if (close(fd) < 0) + { + printf("Error in closing the file!\n"); + exit(1); + } +} diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index 2438eca410..359470f42f 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -160,6 +160,9 @@ LFORTRAN_API void _lfortran_i64sys_clock( uint64_t *count, int64_t *rate, int64_t *max); LFORTRAN_API void _lfortran_sp_rand_num(float *x); LFORTRAN_API void _lfortran_dp_rand_num(double *x); +LFORTRAN_API int64_t _lpython_open(char *path); +LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n); +LFORTRAN_API void _lpython_close(int64_t fd); #ifdef __cplusplus } diff --git a/src/runtime/os.py b/src/runtime/os.py new file mode 100644 index 0000000000..1b6c01c685 --- /dev/null +++ b/src/runtime/os.py @@ -0,0 +1,32 @@ +from ltypes import i64, ccall + +def open(path: str) -> i64: + """ + Returns the file descriptor for the newly opened file + """ + return _lpython_open(path) + +@ccall +def _lpython_open(path: str) -> i64: + pass + +def read(fd: i64, n: i64) -> str: + """ + Reads at most `n` bytes from file descriptor + """ + return _lpython_read(fd, n) + +@ccall +def _lpython_read(fd: i64, n: i64) -> str: + pass + +def close(fd: i64): + """ + Closes the file descriptor + """ + _lpython_close(fd) + return + +@ccall +def _lpython_close(fd: i64): + pass From 534377ffa5580fa6ce41c6140377ef2d360aab95 Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 25 Mar 2022 08:33:10 +0530 Subject: [PATCH 2/5] Include flags as an argument for open function --- integration_tests/run_tests.py | 2 +- integration_tests/test_os.py | 4 ++-- src/runtime/impure/lfortran_intrinsics.c | 4 ++-- src/runtime/impure/lfortran_intrinsics.h | 2 +- src/runtime/os.py | 14 ++++++++++---- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/integration_tests/run_tests.py b/integration_tests/run_tests.py index 070132a72d..f6bdc92ab8 100755 --- a/integration_tests/run_tests.py +++ b/integration_tests/run_tests.py @@ -20,7 +20,7 @@ "test_numpy_01.py", "test_numpy_02.py", "test_random.py", - # "test_os.py", + "test_os.py", "test_builtin.py", "test_builtin_abs.py", "test_builtin_bool.py", diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py index 8a093ef617..664d5fea0a 100644 --- a/integration_tests/test_os.py +++ b/integration_tests/test_os.py @@ -1,12 +1,12 @@ from ltypes import i64 -from os import (open, read, close) +from os import (open, read, close, O_RDONLY) def test(): path: str path = "integration_tests/test_os.py" fd: i64 n: i64 - fd = open(path) + fd = open(path, O_RDONLY) n = 100 print(read(fd, n)) close(fd) diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index 0a080e3a4e..0dafa7f0b9 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -789,9 +789,9 @@ LFORTRAN_API void _lfortran_dp_rand_num(double *x) { *x = rand() / (double) RAND_MAX; } -LFORTRAN_API int64_t _lpython_open(char *path) +LFORTRAN_API int64_t _lpython_open(char *path, int32_t flags) { - int64_t fd = open(path, O_RDONLY); + int64_t fd = open(path, flags); if (fd < 0) { printf("Error in opening the file!\n"); diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index 359470f42f..046d64d5d9 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -160,7 +160,7 @@ LFORTRAN_API void _lfortran_i64sys_clock( uint64_t *count, int64_t *rate, int64_t *max); LFORTRAN_API void _lfortran_sp_rand_num(float *x); LFORTRAN_API void _lfortran_dp_rand_num(double *x); -LFORTRAN_API int64_t _lpython_open(char *path); +LFORTRAN_API int64_t _lpython_open(char *path, int32_t flags); LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n); LFORTRAN_API void _lpython_close(int64_t fd); diff --git a/src/runtime/os.py b/src/runtime/os.py index 1b6c01c685..735a696951 100644 --- a/src/runtime/os.py +++ b/src/runtime/os.py @@ -1,13 +1,19 @@ -from ltypes import i64, ccall +from ltypes import i32, i64, ccall -def open(path: str) -> i64: +O_RDONLY: i32 # = 0 FIXME: Assign the value 0 to O_RDONLY +# O_WRONLY: i32 = 1 +# O_RDWR : i32 = 2 +# O_CREAT : i32 = 64 +# O_APPEND: i32 = 1024 + +def open(path: str, flag: i32) -> i64: """ Returns the file descriptor for the newly opened file """ - return _lpython_open(path) + return _lpython_open(path, flag) @ccall -def _lpython_open(path: str) -> i64: +def _lpython_open(path: str, flag: i32) -> i64: pass def read(fd: i64, n: i64) -> str: From eac54bb7cc5759d8b051afc7766d8222e540a29d Mon Sep 17 00:00:00 2001 From: Thirumalai-Shaktivel Date: Fri, 25 Mar 2022 20:19:42 +0530 Subject: [PATCH 3/5] Add _WIN32 preprocessor for unistd.h --- src/runtime/impure/lfortran_intrinsics.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index 0dafa7f0b9..15459a0f2d 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -9,7 +9,10 @@ #include #include #include + +#ifndef _WIN32 #include +#endif #include "lfortran_intrinsics.h" From 94b919647bf19cdc065b5088a56d910c4337ab13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 29 Mar 2022 09:34:24 -0600 Subject: [PATCH 4/5] Use standard C file IO --- src/runtime/impure/lfortran_intrinsics.c | 18 +++++++----------- src/runtime/impure/lfortran_intrinsics.h | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/runtime/impure/lfortran_intrinsics.c b/src/runtime/impure/lfortran_intrinsics.c index 15459a0f2d..9cedaa2a97 100644 --- a/src/runtime/impure/lfortran_intrinsics.c +++ b/src/runtime/impure/lfortran_intrinsics.c @@ -8,11 +8,6 @@ #include #include #include -#include - -#ifndef _WIN32 -#include -#endif #include "lfortran_intrinsics.h" @@ -792,16 +787,17 @@ LFORTRAN_API void _lfortran_dp_rand_num(double *x) { *x = rand() / (double) RAND_MAX; } -LFORTRAN_API int64_t _lpython_open(char *path, int32_t flags) +LFORTRAN_API int64_t _lpython_open(char *path, char *flags) { - int64_t fd = open(path, flags); - if (fd < 0) + FILE *fd; + fd = fopen(path, flags); + if (!fd) { printf("Error in opening the file!\n"); perror(path); exit(1); } - return fd; + return (int64_t)fd; } LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n) @@ -812,14 +808,14 @@ LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n) printf("Error in reading the file!\n"); exit(1); } - int x = read(fd, c, n); + int x = fread(c, 1, n, (FILE*)fd); c[x] = '\0'; return c; } LFORTRAN_API void _lpython_close(int64_t fd) { - if (close(fd) < 0) + if (fclose((FILE*)fd) != 0) { printf("Error in closing the file!\n"); exit(1); diff --git a/src/runtime/impure/lfortran_intrinsics.h b/src/runtime/impure/lfortran_intrinsics.h index 046d64d5d9..8492f3db60 100644 --- a/src/runtime/impure/lfortran_intrinsics.h +++ b/src/runtime/impure/lfortran_intrinsics.h @@ -160,7 +160,7 @@ LFORTRAN_API void _lfortran_i64sys_clock( uint64_t *count, int64_t *rate, int64_t *max); LFORTRAN_API void _lfortran_sp_rand_num(float *x); LFORTRAN_API void _lfortran_dp_rand_num(double *x); -LFORTRAN_API int64_t _lpython_open(char *path, int32_t flags); +LFORTRAN_API int64_t _lpython_open(char *path, char *flags); LFORTRAN_API char* _lpython_read(int64_t fd, int64_t n); LFORTRAN_API void _lpython_close(int64_t fd); From c5d5f679447c63eaebb2c6f286cbda5db7d376aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 29 Mar 2022 09:36:30 -0600 Subject: [PATCH 5/5] Update the code to use the new API --- integration_tests/test_os.py | 4 ++-- src/runtime/os.py | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/integration_tests/test_os.py b/integration_tests/test_os.py index 664d5fea0a..fea7230893 100644 --- a/integration_tests/test_os.py +++ b/integration_tests/test_os.py @@ -1,12 +1,12 @@ from ltypes import i64 -from os import (open, read, close, O_RDONLY) +from os import (open, read, close) def test(): path: str path = "integration_tests/test_os.py" fd: i64 n: i64 - fd = open(path, O_RDONLY) + fd = open(path, "r") n = 100 print(read(fd, n)) close(fd) diff --git a/src/runtime/os.py b/src/runtime/os.py index 735a696951..8d1050e3f9 100644 --- a/src/runtime/os.py +++ b/src/runtime/os.py @@ -1,19 +1,13 @@ from ltypes import i32, i64, ccall -O_RDONLY: i32 # = 0 FIXME: Assign the value 0 to O_RDONLY -# O_WRONLY: i32 = 1 -# O_RDWR : i32 = 2 -# O_CREAT : i32 = 64 -# O_APPEND: i32 = 1024 - -def open(path: str, flag: i32) -> i64: +def open(path: str, flag: str) -> i64: """ Returns the file descriptor for the newly opened file """ return _lpython_open(path, flag) @ccall -def _lpython_open(path: str, flag: i32) -> i64: +def _lpython_open(path: str, flag: str) -> i64: pass def read(fd: i64, n: i64) -> str: