Bläddra i källkod

more fs API support for pikaPlatform.h

lyon 2 år sedan
förälder
incheckning
5293ca54d5

+ 1 - 0
examples/os/os_test1.py

@@ -21,4 +21,5 @@ print(os.read(f, 100))
 os.close(f)
 os.chdir("..")
 os.chdir(origin)
+os.listdir('.')
 print("PASS")

+ 12 - 8
package/os/os.c

@@ -7,6 +7,10 @@
 #include "os_fileStat.h"
 #include "os_platform.h"
 
+#if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 12, 7)
+#error "This library requires PikaScript version 1.12.7 or higher"
+#endif
+
 void os___init__(PikaObj* self) {
     // obj_newDirectObj(self,"os",New_TinyObj);
 
@@ -44,8 +48,8 @@ char* os_read(PikaObj* self, PikaObj* fd, int len) {
 int os_write(PikaObj* self, PikaObj* fd, Arg* buf) {
     if (arg_getType(buf) != ARG_TYPE_BYTES) {
         obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
-        pika_platform_printf(
-            "TypeError: a bytes-like object is required, not 'str'\r\n");
+        obj_setSysOut(self,
+                      "TypeError: a bytes-like object is required, not 'str'");
         return -1;
     }
     return os_write_platform(arg_getBytes(buf), arg_getBytesSize(buf), fd);
@@ -58,7 +62,7 @@ int os_lseek(PikaObj* self, PikaObj* fd, int how, int pos) {
 void os_close(PikaObj* self, PikaObj* fd) {
     if (os_close_platform(fd) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("close file error\r\n");
+        obj_setSysOut(self, "close file error");
     }
 }
 
@@ -79,34 +83,34 @@ void os_mkdir(PikaObj* self, char* path, PikaTuple* mode) {
     }
     if (os_mkdir_platform(iMode, path) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("mkdir error\r\n");
+        obj_setSysOut(self, "mkdir error");
     }
 }
 
 void os_chdir(PikaObj* self, char* path) {
     if (os_chdir_platform(path) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("chdir error\r\n");
+        obj_setSysOut(self, "chdir error");
     }
 }
 
 void os_rmdir(PikaObj* self, char* path) {
     if (os_rmdir_platform(path) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("rmdir error\r\n");
+        obj_setSysOut(self, "rmdir error");
     }
 }
 
 void os_remove(PikaObj* self, char* filename) {
     if (os_remove_platform(filename) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("remove error\r\n");
+        obj_setSysOut(self, "remove error");
     }
 }
 
 void os_rename(PikaObj* self, char* old, char* new) {
     if (os_rename_platform(old, new) < 0) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
-        pika_platform_printf("rename error\r\n");
+        obj_setSysOut(self, "rename error");
     }
 }

+ 31 - 74
package/os/os_platform.c

@@ -3,9 +3,9 @@
 int os_getFileSize(PikaObj* fd) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fseek(fp, 0, SEEK_END);
+        int ret = pika_platform_fseek(fp, 0, SEEK_END);
         if (ret == 0) {
-            ret = ftell(fp);
+            ret = pika_platform_ftell(fp);
             return ret;
         }
     }
@@ -16,7 +16,7 @@ PikaObj* os_open_platform(char* filename, int flags) {
     char file_flag[4] = {0};
     int index = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    pika_platform_memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
 
     if (FILE_RDONLY == (flags & FILE_RDONLY)) {
         file_flag[0] = 'r';
@@ -26,9 +26,9 @@ PikaObj* os_open_platform(char* filename, int flags) {
     }
 
     if (FILE_RDWR == (flags & FILE_RDWR)) {
-        memcpy(file_flag, "r+", 2);
+        pika_platform_memcpy(file_flag, "r+", 2);
         if (FILE_CREAT == (flags & FILE_CREAT)) {
-            memcpy(file_flag, "w+", 2);
+            pika_platform_memcpy(file_flag, "w+", 2);
         }
     }
 
@@ -38,7 +38,7 @@ PikaObj* os_open_platform(char* filename, int flags) {
     if (FILE_APPEND == (flags & FILE_APPEND))
         memcpy(file_flag, "a+", 2);
 
-    FILE* fp = fopen(dirpath, file_flag);
+    FILE* fp = pika_platform_fopen(dirpath, file_flag);
     if (fp != NULL) {
         PikaObj* file_obj = newNormalObj(New_TinyObj);
         obj_setPtr(file_obj, "fd", fp);
@@ -53,16 +53,16 @@ char* os_read_platform(PikaObj* self, PikaObj* fd, int len) {
     int size = 0;
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        buf = malloc(len);
-        memset(buf, 0x00, len);
-        size = fread(buf, 1, len, fp);
+        buf = pika_platform_malloc(len);
+        pika_platform_memset(buf, 0x00, len);
+        size = pika_platform_fread(buf, 1, len, fp);
 
         if (size > 0) {
             obj_setStr(self, "os_file_read", buf);
-            free(buf);
+            pika_platform_free(buf);
             return obj_getStr(self, "os_file_read");
         }
-        free(buf);
+        pika_platform_free(buf);
     }
 
     return "";
@@ -72,7 +72,7 @@ int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
     int size = 0;
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        size = fwrite(buf, 1, len, fp);
+        size = pika_platform_fwrite(buf, 1, len, fp);
         return size;
     }
     return 0;
@@ -81,7 +81,7 @@ int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
 int os_lseek_platform(PikaObj* fd, int how, int pos) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fseek(fp, pos, how);
+        int ret = pika_platform_fseek(fp, pos, how);
         return ret;
 
     } else
@@ -91,7 +91,7 @@ int os_lseek_platform(PikaObj* fd, int how, int pos) {
 int os_close_platform(PikaObj* fd) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fclose(fp);
+        int ret = pika_platform_fclose(fp);
         return ret;
 
     } else
@@ -100,7 +100,7 @@ int os_close_platform(PikaObj* fd) {
 
 char* os_getcwd_platform(PikaObj* self) {
     char dirpath[256] = {0};
-    if (getcwd(dirpath, sizeof(dirpath)) == NULL) {
+    if (pika_platform_getcwd(dirpath, sizeof(dirpath)) == NULL) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
         obj_setStr(self, "os_current_path", "");
         return NULL;
@@ -110,71 +110,29 @@ char* os_getcwd_platform(PikaObj* self) {
 }
 
 PikaObj* os_listdir_platform(char* path) {
-#ifdef _WIN32
-    struct _finddata_t fb;
-    long handle = 0;
-    char dirpath[256] = {0};
-    char* currentPath = getcwd(dirpath, 256);
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
-    strcat(dirpath, "/*");
-
-    PikaObj* list = newNormalObj(New_PikaStdData_List);
-    PikaStdData_List___init__(list);
-
-    handle = _findfirst(dirpath, &fb);
-    if (handle != -1L) {
-        if (memcmp(fb.name, ".", 1) != 0) {
-            Arg* arg = arg_setStr(NULL, "", fb.name);
-
-            PikaStdData_List_append(list, arg);
-
-            arg_deinit(arg);
-        }
-
-        while (0 == _findnext(handle, &fb)) {
-            if (memcmp(fb.name, "..", 2) != 0) {
-                Arg* arg = arg_setStr(NULL, "", fb.name);
-                PikaStdData_List_append(list, arg);
-                arg_deinit(arg);
-            }
-        }
-        _findclose(handle);
-    }
-
-    return list;
-#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
-    struct dirent* dp;
-    DIR* dir = opendir(path);
+    int count = 0;
+    char** filenames = NULL;
 
+    filenames = pika_platform_listdir(path, &count);
     PikaObj* list = newNormalObj(New_PikaStdData_List);
     PikaStdData_List___init__(list);
 
-    if (dir != NULL) {
-        while ((dp = readdir(dir)) != NULL) {
-            if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
-                Arg* arg = arg_setStr(NULL, "", dp->d_name);
-                PikaStdData_List_append(list, arg);
-                arg_deinit(arg);
-            }
-        }
-
-        closedir(dir);
+    for (int i = 0; i < count; i++) {
+        Arg* arg = arg_setStr(NULL, "", filenames[i]);
+        PikaStdData_List_append(list, arg);
+        arg_deinit(arg);
+        pika_platform_free(filenames[i]);
     }
+    pika_platform_free(filenames);
 
     return list;
-#endif
 }
 
 int os_mkdir_platform(int mode, char* path) {
     char dirpath[256] = {0};
     int ret = 0;
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
-#ifdef _WIN32
-    (void)(mode);
-    ret = mkdir(dirpath);
-#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
-    ret = mkdir(dirpath, mode);
-#endif
+    pika_platform_memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    ret = pika_platform_mkdir(dirpath, mode);
     return ret;
 }
 
@@ -185,24 +143,23 @@ int os_chdir_platform(char* path) {
         ret = PIKA_TRUE;
     else
         ret = PIKA_FALSE;
-
     return ret;
 }
 
 int os_rmdir_platform(char* path) {
     int ret = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    pika_platform_memcpy(dirpath + strlen(dirpath), path, strlen(path));
 
-    ret = rmdir(dirpath);
+    ret = pika_platform_rmdir(dirpath);
     return ret;
 }
 
 int os_remove_platform(char* filename) {
     int ret = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
-    ret = remove(dirpath);
+    pika_platform_memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    ret = pika_platform_remove(dirpath);
     return ret;
 }
 
@@ -210,7 +167,7 @@ int os_rename_platform(char* old, char* new) {
     if (NULL == old || NULL == new) {
         return -1;
     }
-    if (0 != rename(old, new)) {
+    if (0 != pika_platform_rename(old, new)) {
         return -1;
     }
     return 0;

+ 137 - 40
package/pika_fatfs/pika_fatfs.c

@@ -7,37 +7,10 @@ typedef FIL _INNER_FILE;
 int __fmodeflags(const char* mode);
 
 /* public prototypes */
-FILE* fatfs_fopen(const char* filename, const char* modes);
-size_t fatfs_fwrite(const void* ptr, size_t size, size_t n, FILE* stream);
-size_t fatfs_fread(void* ptr, size_t size, size_t n, FILE* stream);
-int fatfs_fclose(FILE* stream);
-int fatfs_fseek(FILE* stream, long offset, int whence);
-long fatfs_ftell(FILE* stream);
-
 #ifndef PIKA_FATFS_ENABLE
 #define PIKA_FATFS_ENABLE 1
 #endif
 
-#if PIKA_FATFS_ENABLE
-FILE* __platform_fopen(const char* filename, const char* modes) {
-    return fatfs_fopen(filename, modes);
-}
-int __platform_fclose(FILE* stream) {
-    return fatfs_fclose(stream);
-}
-size_t __platform_fwrite(const void* ptr, size_t size, size_t n, FILE* stream) {
-    return fatfs_fwrite(ptr, size, n, stream);
-}
-size_t __platform_fread(void* ptr, size_t size, size_t n, FILE* stream) {
-    return fatfs_fread(ptr, size, n, stream);
-}
-int __platform_fseek(FILE* stream, long offset, int whence) {
-    return fatfs_fseek(stream, offset, whence);
-}
-long __platform_ftell(FILE* stream) {
-    return fatfs_ftell(stream);
-}
-#endif
 
 FILE* fatfs_fopen(const char* filename, const char* modes) {
     FRESULT res;
@@ -87,8 +60,25 @@ int fatfs_fclose(FILE* stream) {
 
 int fatfs_fseek(FILE* stream, long offset, int whence) {
     _INNER_FILE* _f = (_INNER_FILE*)stream;
-    f_lseek(_f, offset);
-    return f_tell(_f);
+    DWORD fatfs_offset;
+    switch (whence) {
+        case SEEK_SET:
+            fatfs_offset = offset;
+            break;
+        case SEEK_CUR:
+            fatfs_offset = f_tell(_f) + offset;
+            break;
+        case SEEK_END:
+            fatfs_offset = f_size(_f) + offset;
+            break;
+        default:
+            return -1; // Invalid argument
+    }
+    if (f_lseek(_f, fatfs_offset) == FR_OK) {
+        return 0;
+    } else {
+        return -1;
+    }
 }
 
 long fatfs_ftell(FILE* stream) {
@@ -97,16 +87,123 @@ long fatfs_ftell(FILE* stream) {
 }
 
 int __fmodeflags(const char* mode) {
-    int flags;
-    if (strchr(mode, '+'))
-        flags = FA_WRITE | FA_READ;
-    else if (*mode == 'r')
-        flags = FA_READ;
-    else
-        flags = FA_CREATE_ALWAYS;
-    if (*mode == 'w')
-        flags |= FA_CREATE_ALWAYS;
-    if (*mode == 'a')
-        flags |= FA_OPEN_APPEND;
+    int flags = 0; 
+
+    if (strchr(mode, '+')) {
+        flags = FA_WRITE | FA_READ; 
+    }
+
+    if (*mode == 'r') {
+        if (!(flags & FA_WRITE)) { 
+            flags |= FA_READ;
+        }
+    } else if (*mode == 'w') {
+        flags |= FA_CREATE_ALWAYS | FA_WRITE; 
+    } else if (*mode == 'a') {
+        flags |= FA_OPEN_APPEND | FA_WRITE; 
+    }
+
     return flags;
 }
+
+char* fatfs_getcwd(char* buf, size_t size) {
+    // FatFS doesn't directly provide a getcwd function. You might need 
+    // to manage the current directory yourself or return a default if it's 
+    // not crucial for your application.
+    strncpy(buf, "/", size);
+    return buf;
+}
+
+int fatfs_chdir(const char* path) {
+    // FatFS doesn't directly provide a chdir function. You might need 
+    // to manage the current directory yourself.
+    return -1; // Not implemented
+}
+
+int fatfs_rmdir(const char* pathname) {
+    return f_unlink(pathname);
+}
+
+int fatfs_mkdir(const char* pathname, int mode) {
+    return f_mkdir(pathname);
+}
+
+int fatfs_remove(const char* pathname) {
+    return f_unlink(pathname);
+}
+
+int fatfs_rename(const char* oldpath, const char* newpath) {
+    return f_rename(oldpath, newpath);
+}
+
+char** fatfs_listdir(const char* path, int* count) {
+    DIR dir;
+    static FILINFO fno;
+    FRESULT res;
+    char **filelist = NULL;
+    int idx = 0, capacity = 10; // start with a capacity of 10, then grow if necessary
+
+    res = f_opendir(&dir, path); // Open the directory
+    if (res == FR_OK) {
+        filelist = pika_platform_malloc(capacity * sizeof(char*));
+        if(!filelist) return NULL; // Failed to allocate memory
+
+        for (;;) {
+            res = f_readdir(&dir, &fno); // Read a directory item
+            if (res != FR_OK || fno.fname[0] == 0) break; // Break on error or end of dir
+
+            if (idx == capacity) { // Grow the list if necessary
+                capacity *= 2;
+                char **newlist = pika_platform_realloc(filelist, capacity * sizeof(char*));
+                if(!newlist) {
+                    // Free any previously allocated memory
+                    for(int i = 0; i < idx; i++)
+                        pika_platform_free(filelist[i]);
+                    pika_platform_free(filelist);
+                    *count = 0;
+                    return NULL; // Failed to allocate more memory
+                }
+                filelist = newlist;
+            }
+
+            filelist[idx] = strdup(fno.fname);
+            if(!filelist[idx]) {
+                // Free any previously allocated memory
+                for(int i = 0; i < idx; i++)
+                    pika_platform_free(filelist[i]);
+                pika_platform_free(filelist);
+                *count = 0;
+                return NULL; // Failed to allocate memory for filename
+            }
+            idx++;
+        }
+        f_closedir(&dir);
+    }
+
+    *count = idx;
+    return filelist;
+}
+
+#if PIKA_FATFS_ENABLE
+char* pika_platform_getcwd(char* buf, size_t size) {
+    return fatfs_getcwd(buf, size);
+}
+int pika_platform_chdir(const char* path) {
+    return fatfs_chdir(path);
+}
+int pika_platform_rmdir(const char* pathname) {
+    return fatfs_rmdir(pathname);
+}
+int pika_platform_mkdir(const char* pathname, int mode) {
+    return fatfs_mkdir(pathname, mode);
+}
+int pika_platform_remove(const char* pathname) {
+    return fatfs_remove(pathname);
+}
+int pika_platform_rename(const char* oldpath, const char* newpath) {
+    return fatfs_rename(oldpath, newpath);
+}
+char** pika_platform_listdir(const char* path, int* count) {
+    return fatfs_listdir(path, count);
+}
+#endif

+ 81 - 1
package/pika_littlefs/pika_littlefs.c

@@ -9,6 +9,7 @@
 #include "lfs.h"
 
 PIKA_WEAK lfs_t pika_lfs_handle = {0};
+static char current_path[256] = "/";
 
 static int __lfs_fmodeflags(const char* mode) {
     int flag = 0;
@@ -62,12 +63,91 @@ size_t pika_platform_fread(void* ptr, size_t size, size_t n, FILE* stream) {
 }
 
 int pika_platform_fseek(FILE* stream, long offset, int whence) {
+    int lfs_whence;
+
+    switch (whence) {
+        case SEEK_SET:
+            lfs_whence = LFS_SEEK_SET;
+            break;
+        case SEEK_CUR:
+            lfs_whence = LFS_SEEK_CUR;
+            break;
+        case SEEK_END:
+            lfs_whence = LFS_SEEK_END;
+            break;
+        default:
+            return -1;
+    }
+
     return (int)lfs_file_seek(&pika_lfs_handle, (lfs_file_t*)stream,
-                              (lfs_soff_t)offset, whence);
+                              (lfs_soff_t)offset, lfs_whence);
 }
 
 long pika_platform_ftell(FILE* stream) {
     return (long)lfs_file_tell(&pika_lfs_handle, (lfs_file_t*)stream);
 }
 
+char* pika_platform_getcwd(char* buf, size_t size) {
+    strncpy(buf, current_path, size);
+    return buf;
+}
+
+int pika_platform_chdir(const char* path) {
+    // In a real environment, you'd want to check if the directory exists first
+    strncpy(current_path, path, sizeof(current_path));
+    return 0;
+}
+
+int pika_platform_rmdir(const char* pathname) {
+    return lfs_remove(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_mkdir(const char* pathname, int mode) {
+    // mode is not used in LittleFS
+    return lfs_mkdir(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_remove(const char* pathname) {
+    return lfs_remove(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_rename(const char* oldpath, const char* newpath) {
+    return lfs_rename(&pika_lfs_handle, oldpath, newpath);
+}
+
+char** pika_platform_listdir(const char* path, int* count) {
+    // LittleFS doesn't have a direct listdir function, so we'll need to
+    // implement this.
+    lfs_dir_t dir;
+    lfs_info_t info;
+
+    char** filenames = NULL;
+    int index = 0;
+    *count = 0;
+
+    if (lfs_opendir(&pika_lfs_handle, &dir, path) == LFS_ERR_OK) {
+        while (lfs_readdir(&pika_lfs_handle, &dir, &info) == LFS_ERR_OK) {
+            if (info.name[0] != 0) {
+                (*count)++;
+            }
+        }
+        lfs_closedir(&pika_lfs_handle, &dir);
+
+        // Allocate space for filenames
+        filenames = (char**)pika_platform_malloc(sizeof(char*) * (*count));
+
+        // Read filenames
+        lfs_opendir(&pika_lfs_handle, &dir, path);
+        while (lfs_readdir(&pika_lfs_handle, &dir, &info) == LFS_ERR_OK) {
+            if (info.name[0] != 0) {
+                filenames[index] = pika_platform_strdup(info.name);
+                index++;
+            }
+        }
+        lfs_closedir(&pika_lfs_handle, &dir);
+    }
+
+    return filenames;
+}
+
 #endif

+ 4 - 0
port/linux/package/pikascript/pikascript-lib/os/os.c

@@ -7,6 +7,10 @@
 #include "os_fileStat.h"
 #include "os_platform.h"
 
+#if !PIKASCRIPT_VERSION_REQUIRE_MINIMUN(1, 12, 7)
+#error "This library requires PikaScript version 1.12.7 or higher"
+#endif
+
 void os___init__(PikaObj* self) {
     // obj_newDirectObj(self,"os",New_TinyObj);
 

+ 31 - 74
port/linux/package/pikascript/pikascript-lib/os/os_platform.c

@@ -3,9 +3,9 @@
 int os_getFileSize(PikaObj* fd) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fseek(fp, 0, SEEK_END);
+        int ret = pika_platform_fseek(fp, 0, SEEK_END);
         if (ret == 0) {
-            ret = ftell(fp);
+            ret = pika_platform_ftell(fp);
             return ret;
         }
     }
@@ -16,7 +16,7 @@ PikaObj* os_open_platform(char* filename, int flags) {
     char file_flag[4] = {0};
     int index = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    pika_platform_memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
 
     if (FILE_RDONLY == (flags & FILE_RDONLY)) {
         file_flag[0] = 'r';
@@ -26,9 +26,9 @@ PikaObj* os_open_platform(char* filename, int flags) {
     }
 
     if (FILE_RDWR == (flags & FILE_RDWR)) {
-        memcpy(file_flag, "r+", 2);
+        pika_platform_memcpy(file_flag, "r+", 2);
         if (FILE_CREAT == (flags & FILE_CREAT)) {
-            memcpy(file_flag, "w+", 2);
+            pika_platform_memcpy(file_flag, "w+", 2);
         }
     }
 
@@ -38,7 +38,7 @@ PikaObj* os_open_platform(char* filename, int flags) {
     if (FILE_APPEND == (flags & FILE_APPEND))
         memcpy(file_flag, "a+", 2);
 
-    FILE* fp = fopen(dirpath, file_flag);
+    FILE* fp = pika_platform_fopen(dirpath, file_flag);
     if (fp != NULL) {
         PikaObj* file_obj = newNormalObj(New_TinyObj);
         obj_setPtr(file_obj, "fd", fp);
@@ -53,16 +53,16 @@ char* os_read_platform(PikaObj* self, PikaObj* fd, int len) {
     int size = 0;
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        buf = malloc(len);
-        memset(buf, 0x00, len);
-        size = fread(buf, 1, len, fp);
+        buf = pika_platform_malloc(len);
+        pika_platform_memset(buf, 0x00, len);
+        size = pika_platform_fread(buf, 1, len, fp);
 
         if (size > 0) {
             obj_setStr(self, "os_file_read", buf);
-            free(buf);
+            pika_platform_free(buf);
             return obj_getStr(self, "os_file_read");
         }
-        free(buf);
+        pika_platform_free(buf);
     }
 
     return "";
@@ -72,7 +72,7 @@ int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
     int size = 0;
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        size = fwrite(buf, 1, len, fp);
+        size = pika_platform_fwrite(buf, 1, len, fp);
         return size;
     }
     return 0;
@@ -81,7 +81,7 @@ int os_write_platform(uint8_t* buf, size_t len, PikaObj* fd) {
 int os_lseek_platform(PikaObj* fd, int how, int pos) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fseek(fp, pos, how);
+        int ret = pika_platform_fseek(fp, pos, how);
         return ret;
 
     } else
@@ -91,7 +91,7 @@ int os_lseek_platform(PikaObj* fd, int how, int pos) {
 int os_close_platform(PikaObj* fd) {
     FILE* fp = obj_getPtr(fd, "fd");
     if (fp != NULL) {
-        int ret = fclose(fp);
+        int ret = pika_platform_fclose(fp);
         return ret;
 
     } else
@@ -100,7 +100,7 @@ int os_close_platform(PikaObj* fd) {
 
 char* os_getcwd_platform(PikaObj* self) {
     char dirpath[256] = {0};
-    if (getcwd(dirpath, sizeof(dirpath)) == NULL) {
+    if (pika_platform_getcwd(dirpath, sizeof(dirpath)) == NULL) {
         obj_setErrorCode(self, PIKA_RES_ERR_IO_ERROR);
         obj_setStr(self, "os_current_path", "");
         return NULL;
@@ -110,71 +110,29 @@ char* os_getcwd_platform(PikaObj* self) {
 }
 
 PikaObj* os_listdir_platform(char* path) {
-#ifdef _WIN32
-    struct _finddata_t fb;
-    long handle = 0;
-    char dirpath[256] = {0};
-    char* currentPath = getcwd(dirpath, 256);
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
-    strcat(dirpath, "/*");
-
-    PikaObj* list = newNormalObj(New_PikaStdData_List);
-    PikaStdData_List___init__(list);
-
-    handle = _findfirst(dirpath, &fb);
-    if (handle != -1L) {
-        if (memcmp(fb.name, ".", 1) != 0) {
-            Arg* arg = arg_setStr(NULL, "", fb.name);
-
-            PikaStdData_List_append(list, arg);
-
-            arg_deinit(arg);
-        }
-
-        while (0 == _findnext(handle, &fb)) {
-            if (memcmp(fb.name, "..", 2) != 0) {
-                Arg* arg = arg_setStr(NULL, "", fb.name);
-                PikaStdData_List_append(list, arg);
-                arg_deinit(arg);
-            }
-        }
-        _findclose(handle);
-    }
-
-    return list;
-#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
-    struct dirent* dp;
-    DIR* dir = opendir(path);
+    int count = 0;
+    char** filenames = NULL;
 
+    filenames = pika_platform_listdir(path, &count);
     PikaObj* list = newNormalObj(New_PikaStdData_List);
     PikaStdData_List___init__(list);
 
-    if (dir != NULL) {
-        while ((dp = readdir(dir)) != NULL) {
-            if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
-                Arg* arg = arg_setStr(NULL, "", dp->d_name);
-                PikaStdData_List_append(list, arg);
-                arg_deinit(arg);
-            }
-        }
-
-        closedir(dir);
+    for (int i = 0; i < count; i++) {
+        Arg* arg = arg_setStr(NULL, "", filenames[i]);
+        PikaStdData_List_append(list, arg);
+        arg_deinit(arg);
+        pika_platform_free(filenames[i]);
     }
+    pika_platform_free(filenames);
 
     return list;
-#endif
 }
 
 int os_mkdir_platform(int mode, char* path) {
     char dirpath[256] = {0};
     int ret = 0;
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
-#ifdef _WIN32
-    (void)(mode);
-    ret = mkdir(dirpath);
-#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
-    ret = mkdir(dirpath, mode);
-#endif
+    pika_platform_memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    ret = pika_platform_mkdir(dirpath, mode);
     return ret;
 }
 
@@ -185,24 +143,23 @@ int os_chdir_platform(char* path) {
         ret = PIKA_TRUE;
     else
         ret = PIKA_FALSE;
-
     return ret;
 }
 
 int os_rmdir_platform(char* path) {
     int ret = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), path, strlen(path));
+    pika_platform_memcpy(dirpath + strlen(dirpath), path, strlen(path));
 
-    ret = rmdir(dirpath);
+    ret = pika_platform_rmdir(dirpath);
     return ret;
 }
 
 int os_remove_platform(char* filename) {
     int ret = 0;
     char dirpath[256] = {0};
-    memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
-    ret = remove(dirpath);
+    pika_platform_memcpy(dirpath + strlen(dirpath), filename, strlen(filename));
+    ret = pika_platform_remove(dirpath);
     return ret;
 }
 
@@ -210,7 +167,7 @@ int os_rename_platform(char* old, char* new) {
     if (NULL == old || NULL == new) {
         return -1;
     }
-    if (0 != rename(old, new)) {
+    if (0 != pika_platform_rename(old, new)) {
         return -1;
     }
     return 0;

+ 81 - 1
port/linux/package/pikascript/pikascript-lib/pika_littlefs/pika_littlefs.c

@@ -9,6 +9,7 @@
 #include "lfs.h"
 
 PIKA_WEAK lfs_t pika_lfs_handle = {0};
+static char current_path[256] = "/";
 
 static int __lfs_fmodeflags(const char* mode) {
     int flag = 0;
@@ -62,12 +63,91 @@ size_t pika_platform_fread(void* ptr, size_t size, size_t n, FILE* stream) {
 }
 
 int pika_platform_fseek(FILE* stream, long offset, int whence) {
+    int lfs_whence;
+
+    switch (whence) {
+        case SEEK_SET:
+            lfs_whence = LFS_SEEK_SET;
+            break;
+        case SEEK_CUR:
+            lfs_whence = LFS_SEEK_CUR;
+            break;
+        case SEEK_END:
+            lfs_whence = LFS_SEEK_END;
+            break;
+        default:
+            return -1;
+    }
+
     return (int)lfs_file_seek(&pika_lfs_handle, (lfs_file_t*)stream,
-                              (lfs_soff_t)offset, whence);
+                              (lfs_soff_t)offset, lfs_whence);
 }
 
 long pika_platform_ftell(FILE* stream) {
     return (long)lfs_file_tell(&pika_lfs_handle, (lfs_file_t*)stream);
 }
 
+char* pika_platform_getcwd(char* buf, size_t size) {
+    strncpy(buf, current_path, size);
+    return buf;
+}
+
+int pika_platform_chdir(const char* path) {
+    // In a real environment, you'd want to check if the directory exists first
+    strncpy(current_path, path, sizeof(current_path));
+    return 0;
+}
+
+int pika_platform_rmdir(const char* pathname) {
+    return lfs_remove(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_mkdir(const char* pathname, int mode) {
+    // mode is not used in LittleFS
+    return lfs_mkdir(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_remove(const char* pathname) {
+    return lfs_remove(&pika_lfs_handle, pathname);
+}
+
+int pika_platform_rename(const char* oldpath, const char* newpath) {
+    return lfs_rename(&pika_lfs_handle, oldpath, newpath);
+}
+
+char** pika_platform_listdir(const char* path, int* count) {
+    // LittleFS doesn't have a direct listdir function, so we'll need to
+    // implement this.
+    lfs_dir_t dir;
+    lfs_info_t info;
+
+    char** filenames = NULL;
+    int index = 0;
+    *count = 0;
+
+    if (lfs_opendir(&pika_lfs_handle, &dir, path) == LFS_ERR_OK) {
+        while (lfs_readdir(&pika_lfs_handle, &dir, &info) == LFS_ERR_OK) {
+            if (info.name[0] != 0) {
+                (*count)++;
+            }
+        }
+        lfs_closedir(&pika_lfs_handle, &dir);
+
+        // Allocate space for filenames
+        filenames = (char**)pika_platform_malloc(sizeof(char*) * (*count));
+
+        // Read filenames
+        lfs_opendir(&pika_lfs_handle, &dir, path);
+        while (lfs_readdir(&pika_lfs_handle, &dir, &info) == LFS_ERR_OK) {
+            if (info.name[0] != 0) {
+                filenames[index] = pika_platform_strdup(info.name);
+                index++;
+            }
+        }
+        lfs_closedir(&pika_lfs_handle, &dir);
+    }
+
+    return filenames;
+}
+
 #endif

+ 1 - 1
port/linux/test/os-test.cpp

@@ -12,7 +12,7 @@ TEST(os, test1) {
     pikaVM_runSingleFile(pikaMain, "test/python/os/os_test1.py");
     /* assert */
     EXPECT_STREQ(log_buff[0], "PASS\r\n");
-    EXPECT_STREQ(log_buff[1], "Hello World!\r\n");
+    EXPECT_STREQ(log_buff[2], "Hello World!\r\n");
     /* deinit */
     obj_deinit(pikaMain);
     EXPECT_EQ(pikaMemNow(), 0);

+ 1 - 0
port/linux/test/python/os/os_test1.py

@@ -21,4 +21,5 @@ print(os.read(f, 100))
 os.close(f)
 os.chdir("..")
 os.chdir(origin)
+os.listdir('.')
 print("PASS")

+ 1 - 1
port/linux/version_config.py

@@ -1,3 +1,3 @@
 MajorVersion  =   "1"
 MinorVersion  =   "12"
-MicroVersion  =   "6"
+MicroVersion  =   "7"

+ 137 - 0
src/PikaObj.c

@@ -3904,6 +3904,143 @@ Arg* builtins_min(PikaObj* self, PikaTuple* val) {
     return _max_min(self, val, (uint8_t*)bc_min);
 }
 
+static PIKA_BOOL _check_no_buff_format(char* format) {
+    while (*format) {
+        if (*format == '%') {
+            ++format;
+            if (*format != 's' && *format != '%') {
+                return PIKA_FALSE;
+            }
+        }
+        ++format;
+    }
+    return PIKA_TRUE;
+}
+
+int pika_pvsprintf(char** buff, const char* fmt, va_list args) {
+    int required_size;
+    int current_size = PIKA_SPRINTF_BUFF_SIZE;
+    *buff = (char*)pika_platform_malloc(current_size * sizeof(char));
+
+    if (*buff == NULL) {
+        return -1;  // Memory allocation failed
+    }
+
+    va_list args_copy;
+    va_copy(args_copy, args);
+
+    required_size =
+        pika_platform_vsnprintf(*buff, current_size, fmt, args_copy);
+    va_end(args_copy);
+
+    while (required_size >= current_size) {
+        current_size *= 2;
+        char* new_buff =
+            (char*)pika_platform_realloc(*buff, current_size * sizeof(char));
+
+        if (new_buff == NULL) {
+            pika_platform_free(*buff);
+            *buff = NULL;
+            return -1;  // Memory allocation failed
+        } else {
+            *buff = new_buff;
+        }
+
+        va_copy(args_copy, args);
+        required_size =
+            pika_platform_vsnprintf(*buff, current_size, fmt, args_copy);
+        va_end(args_copy);
+    }
+
+    return required_size;
+}
+
+static int _no_buff_vprintf(char* fmt, va_list args) {
+    int written = 0;
+    while (*fmt) {
+        if (*fmt == '%') {
+            ++fmt;
+            if (*fmt == 's') {
+                char* str = va_arg(args, char*);
+                if (str == NULL) {
+                    str = "(null)";
+                }
+                int len = strlen(str);
+                written += len;
+                for (int i = 0; i < len; i++) {
+                    pika_putchar(str[i]);
+                }
+            } else if (*fmt == '%') {
+                pika_putchar('%');
+                ++written;
+            }
+        } else {
+            pika_putchar(*fmt);
+            ++written;
+        }
+        ++fmt;
+    }
+    return written;
+}
+
+int pika_vprintf(char* fmt, va_list args) {
+    int ret = 0;
+    if (_check_no_buff_format(fmt)) {
+        _no_buff_vprintf(fmt, args);
+        return 0;
+    }
+
+    char* buff = NULL;
+    int required_size = pika_pvsprintf(&buff, fmt, args);
+
+    if (required_size < 0) {
+        ret = -1;  // Memory allocation or other error occurred
+        goto __exit;
+    }
+
+    // putchar
+    for (int i = 0; i < strlen(buff); i++) {
+        pika_putchar(buff[i]);
+    }
+
+__exit:
+    if (NULL != buff) {
+        pika_platform_free(buff);
+    }
+    return ret;
+}
+
+int pika_sprintf(char* buff, char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int res = pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args);
+    va_end(args);
+    if (res >= PIKA_SPRINTF_BUFF_SIZE) {
+        pika_platform_printf(
+            "OverflowError: sprintf buff size overflow, please use bigger "
+            "PIKA_SPRINTF_BUFF_SIZE\r\n");
+        pika_platform_printf("Info: buff size request: %d\r\n", res);
+        pika_platform_printf("Info: buff size now: %d\r\n",
+                             PIKA_SPRINTF_BUFF_SIZE);
+        while (1)
+            ;
+    }
+    return res;
+}
+
+int pika_vsprintf(char* buff, char* fmt, va_list args) {
+    /* vsnprintf */
+    return pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args);
+}
+
+int pika_snprintf(char* buff, size_t size, const char* fmt, ...) {
+    va_list args;
+    va_start(args, fmt);
+    int ret = pika_platform_vsnprintf(buff, size, fmt, args);
+    va_end(args);
+    return ret;
+}
+
 void _do_vsysOut(char* fmt, va_list args) {
     char* fmt_buff = pikaMalloc(strGetSize(fmt) + 2);
     pika_platform_memcpy(fmt_buff, fmt, strGetSize(fmt));

+ 155 - 181
src/PikaPlatform.c

@@ -30,23 +30,22 @@
 #include <stdlib.h>
 #if defined(_WIN32) && !defined(CROSS_BUILD)
 #include <Windows.h>
+#include <io.h>
+#include <direct.h>
+#endif
+
+#if defined(__linux) || PIKA_LINUX_COMPATIBLE
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "unistd.h"
 #endif
 
 void pikaFree(void* mem, uint32_t size);
 void* pikaMalloc(uint32_t size);
+int pika_pvsprintf(char** buff, const char* fmt, va_list args);
 
-#if PIKA_FREERTOS_ENABLE
-static uint32_t platform_uptime_ms(void) {
-#if (configTICK_RATE_HZ == 1000)
-    return (uint32_t)xTaskGetTickCount();
-#else
-    TickType_t tick = 0u;
-
-    tick = xTaskGetTickCount() * 1000;
-    return (uint32_t)((tick + configTICK_RATE_HZ - 1) / configTICK_RATE_HZ);
-#endif
-}
-#endif
+/* stdio platform */
 
 int pika_putchar(char ch) {
     int ret = pika_platform_putchar(ch);
@@ -56,141 +55,8 @@ int pika_putchar(char ch) {
     return ret;
 }
 
-int pika_pvsprintf(char** buff, const char* fmt, va_list args) {
-    int required_size;
-    int current_size = PIKA_SPRINTF_BUFF_SIZE;
-    *buff = (char*)pika_platform_malloc(current_size * sizeof(char));
-
-    if (*buff == NULL) {
-        return -1;  // Memory allocation failed
-    }
-
-    va_list args_copy;
-    va_copy(args_copy, args);
-
-    required_size =
-        pika_platform_vsnprintf(*buff, current_size, fmt, args_copy);
-    va_end(args_copy);
-
-    while (required_size >= current_size) {
-        current_size *= 2;
-        char* new_buff =
-            (char*)pika_platform_realloc(*buff, current_size * sizeof(char));
-
-        if (new_buff == NULL) {
-            pika_platform_free(*buff);
-            *buff = NULL;
-            return -1;  // Memory allocation failed
-        } else {
-            *buff = new_buff;
-        }
-
-        va_copy(args_copy, args);
-        required_size =
-            pika_platform_vsnprintf(*buff, current_size, fmt, args_copy);
-        va_end(args_copy);
-    }
-
-    return required_size;
-}
-
-static PIKA_BOOL _check_no_buff_format(char* format) {
-    while (*format) {
-        if (*format == '%') {
-            ++format;
-            if (*format != 's' && *format != '%') {
-                return PIKA_FALSE;
-            }
-        }
-        ++format;
-    }
-    return PIKA_TRUE;
-}
-
-static int _no_buff_vprintf(char* fmt, va_list args) {
-    int written = 0;
-    while (*fmt) {
-        if (*fmt == '%') {
-            ++fmt;
-            if (*fmt == 's') {
-                char* str = va_arg(args, char*);
-                if (str == NULL) {
-                    str = "(null)";
-                }
-                int len = strlen(str);
-                written += len;
-                for (int i = 0; i < len; i++) {
-                    pika_putchar(str[i]);
-                }
-            } else if (*fmt == '%') {
-                pika_putchar('%');
-                ++written;
-            }
-        } else {
-            pika_putchar(*fmt);
-            ++written;
-        }
-        ++fmt;
-    }
-    return written;
-}
-
-int pika_vprintf(char* fmt, va_list args) {
-    int ret = 0;
-    if (_check_no_buff_format(fmt)) {
-        _no_buff_vprintf(fmt, args);
-        return 0;
-    }
-
-    char* buff = NULL;
-    int required_size = pika_pvsprintf(&buff, fmt, args);
-
-    if (required_size < 0) {
-        ret = -1;  // Memory allocation or other error occurred
-        goto __exit;
-    }
-
-    // putchar
-    for (int i = 0; i < strlen(buff); i++) {
-        pika_putchar(buff[i]);
-    }
-
-__exit:
-    if (NULL != buff) {
-        pika_platform_free(buff);
-    }
-    return ret;
-}
-
-int pika_sprintf(char* buff, char* fmt, ...) {
-    va_list args;
-    va_start(args, fmt);
-    int res = pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args);
-    va_end(args);
-    if (res >= PIKA_SPRINTF_BUFF_SIZE) {
-        pika_platform_printf(
-            "OverflowError: sprintf buff size overflow, please use bigger "
-            "PIKA_SPRINTF_BUFF_SIZE\r\n");
-        pika_platform_printf("Info: buff size request: %d\r\n", res);
-        pika_platform_printf("Info: buff size now: %d\r\n",
-                             PIKA_SPRINTF_BUFF_SIZE);
-        while (1)
-            ;
-    }
-    return res;
-}
-
-int pika_vsprintf(char* buff, char* fmt, va_list args) {
-    /* vsnprintf */
-    return pika_platform_vsnprintf(buff, PIKA_SPRINTF_BUFF_SIZE, fmt, args);
-}
-
-int pika_snprintf(char* buff, size_t size, const char* fmt, ...) {
-    va_list args;
-    va_start(args, fmt);
-    int ret = pika_platform_vsnprintf(buff, size, fmt, args);
-    va_end(args);
-    return ret;
+PIKA_WEAK void pika_platform_clear(void) {
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
 }
 
 #if !PIKA_PLATFORM_NO_WEAK
@@ -203,6 +69,7 @@ PIKA_WEAK void pika_platform_enable_irq_handle(void) {
     /* disable irq to support thread */
 }
 
+/* memory support */
 PIKA_WEAK void* pika_platform_malloc(size_t size) {
     return malloc(size);
 }
@@ -227,17 +94,34 @@ PIKA_WEAK void pika_user_free(void* ptr, size_t size) {
     pika_platform_free(ptr);
 }
 
-PIKA_WEAK void pika_platform_error_handle() {
-    return;
+PIKA_WEAK uint8_t pika_is_locked_pikaMemory(void) {
+    return 0;
 }
 
-PIKA_WEAK void pika_platform_panic_handle() {
-    while (1) {
-    };
+/* time support */
+#if PIKA_FREERTOS_ENABLE
+static uint32_t platform_uptime_ms(void) {
+#if (configTICK_RATE_HZ == 1000)
+    return (uint32_t)xTaskGetTickCount();
+#else
+    TickType_t tick = 0u;
+
+    tick = xTaskGetTickCount() * 1000;
+    return (uint32_t)((tick + configTICK_RATE_HZ - 1) / configTICK_RATE_HZ);
+#endif
 }
+#endif
 
-PIKA_WEAK uint8_t pika_is_locked_pikaMemory(void) {
-    return 0;
+PIKA_WEAK void pika_platform_sleep_ms(uint32_t ms) {
+#if defined(__linux)
+    usleep(ms * 1000);
+#elif defined(_WIN32) && !defined(CROSS_BUILD)
+    Sleep(ms);
+#elif PIKA_RTTHREAD_ENABLE
+    rt_thread_mdelay(ms);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
 }
 
 PIKA_WEAK int64_t pika_platform_get_tick(void) {
@@ -324,7 +208,7 @@ PIKA_WEAK char pika_platform_getchar(void) {
 #endif
 }
 
-/* fopen */
+/* file system support */
 PIKA_WEAK FILE* pika_platform_fopen(const char* filename, const char* modes) {
 #if defined(__linux) || defined(_WIN32)
     return fopen(filename, modes);
@@ -333,7 +217,6 @@ PIKA_WEAK FILE* pika_platform_fopen(const char* filename, const char* modes) {
 #endif
 }
 
-/* fclose */
 PIKA_WEAK int pika_platform_fclose(FILE* stream) {
 #if defined(__linux) || defined(_WIN32)
     return fclose(stream);
@@ -342,7 +225,6 @@ PIKA_WEAK int pika_platform_fclose(FILE* stream) {
 #endif
 }
 
-/* fwrite */
 PIKA_WEAK size_t pika_platform_fwrite(const void* ptr,
                                       size_t size,
                                       size_t n,
@@ -355,7 +237,6 @@ PIKA_WEAK size_t pika_platform_fwrite(const void* ptr,
 #endif
 }
 
-/* fread */
 PIKA_WEAK size_t pika_platform_fread(void* ptr,
                                      size_t size,
                                      size_t n,
@@ -367,7 +248,6 @@ PIKA_WEAK size_t pika_platform_fread(void* ptr,
 #endif
 }
 
-/* fseek */
 PIKA_WEAK int pika_platform_fseek(FILE* stream, long offset, int whence) {
 #if defined(__linux) || defined(_WIN32)
     return fseek(stream, offset, whence);
@@ -376,7 +256,6 @@ PIKA_WEAK int pika_platform_fseek(FILE* stream, long offset, int whence) {
 #endif
 }
 
-/* ftell */
 PIKA_WEAK long pika_platform_ftell(FILE* stream) {
 #if defined(__linux) || defined(_WIN32)
     return ftell(stream);
@@ -385,18 +264,105 @@ PIKA_WEAK long pika_platform_ftell(FILE* stream) {
 #endif
 }
 
-PIKA_WEAK void pika_hook_instruct(void) {
-    return;
+PIKA_WEAK char* pika_platform_getcwd(char* buf, size_t size) {
+#if defined(__linux) || defined(_WIN32)
+    return getcwd(buf, size);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
 }
 
-PIKA_WEAK PIKA_BOOL pika_hook_arg_cache_filter(void* self) {
-    return PIKA_TRUE;
+PIKA_WEAK int pika_platform_chdir(const char* path) {
+#if defined(__linux) || defined(_WIN32)
+    return chdir(path);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
 }
 
-PIKA_WEAK void pika_thread_idle_hook(void) {
-    return;
+PIKA_WEAK int pika_platform_rmdir(const char* pathname) {
+#if defined(__linux) || defined(_WIN32)
+    return rmdir(pathname);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
+}
+
+PIKA_WEAK int pika_platform_mkdir(const char* pathname, int mode) {
+#ifdef _WIN32
+    (void)(mode);
+    return mkdir(dirpath);
+#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
+    return mkdir(pathname, mode);
+#endif
+}
+
+PIKA_WEAK int pika_platform_remove(const char* pathname) {
+#if defined(__linux) || defined(_WIN32)
+    return remove(pathname);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL();
+#endif
+}
+
+PIKA_WEAK int pika_platform_rename(const char* oldpath, const char* newpath) {
+#if defined(__linux) || defined(_WIN32)
+    return rename(oldpath, newpath);
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL();
+#endif
+}
+
+PIKA_WEAK char** pika_platform_listdir(const char* path, int* count) {
+#if defined(__linux)
+    struct dirent* dp;
+    DIR* dir = opendir(path);
+
+    char** filenames = NULL;
+    *count = 0;
+
+    if (dir != NULL) {
+        while ((dp = readdir(dir)) != NULL) {
+            if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
+                filenames = (char**)pika_platform_realloc(
+                    filenames, (*count + 1) * sizeof(char*));
+                filenames[*count] = pika_platform_strdup(dp->d_name);
+                (*count)++;
+            }
+        }
+        closedir(dir);
+    }
+    return filenames;
+#elif defined(_WIN32) && !defined(CROSS_BUILD)
+    struct _finddata_t fb;
+    intptr_t handle = 0;
+    char dirpath[256] = {0};
+    char* currentPath = _getcwd(dirpath, 256);
+    strcat(dirpath, path);
+    strcat(dirpath, "\\*");
+
+    char** filenames = NULL;
+    *count = 0;
+
+    handle = _findfirst(dirpath, &fb);
+    if (handle != -1L) {
+        do {
+            if (strcmp(fb.name, ".") != 0 && strcmp(fb.name, "..") != 0) {
+                filenames = (char**)pika_platform_realloc(
+                    filenames, (*count + 1) * sizeof(char*));
+                filenames[*count] = pika_platform_strdup(fb.name);
+                (*count)++;
+            }
+        } while (_findnext(handle, &fb) == 0);
+        _findclose(handle);
+    }
+    return filenames;
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL();
+#endif
 }
 
+/* thread support */
 PIKA_WEAK void pika_platform_thread_yield(void) {
     pika_thread_idle_hook();
 #if PIKA_FREERTOS_ENABLE
@@ -410,19 +376,6 @@ PIKA_WEAK void pika_platform_thread_yield(void) {
 #endif
 }
 
-PIKA_WEAK void pika_platform_sleep_ms(uint32_t ms) {
-#if defined(__linux)
-    usleep(ms * 1000);
-#elif defined(_WIN32) && !defined(CROSS_BUILD)
-    Sleep(ms);
-#elif PIKA_RTTHREAD_ENABLE
-    rt_thread_mdelay(ms);
-#else
-    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
-#endif
-}
-
-/* Thread Support */
 PIKA_WEAK pika_platform_thread_t* pika_platform_thread_init(
     const char* name,
     void (*entry)(void*),
@@ -790,6 +743,8 @@ PIKA_WEAK void pika_platform_thread_timer_usleep(unsigned long usec) {
 #endif
 }
 
+/* system support */
+
 PIKA_WEAK void pika_platform_reboot(void) {
 #if __linux
     pika_platform_printf("reboot\n");
@@ -798,11 +753,30 @@ PIKA_WEAK void pika_platform_reboot(void) {
 #endif
 }
 
-PIKA_WEAK void pika_platform_clear(void) {
-    WEAK_FUNCTION_NEED_OVERRIDE_ERROR();
+/* hook */
+PIKA_WEAK void pika_platform_error_handle() {
+    return;
+}
+
+PIKA_WEAK void pika_platform_panic_handle() {
+    while (1) {
+    };
+}
+
+PIKA_WEAK void pika_hook_instruct(void) {
+    return;
+}
+
+PIKA_WEAK PIKA_BOOL pika_hook_arg_cache_filter(void* self) {
+    return PIKA_TRUE;
 }
 
 PIKA_WEAK void pika_platform_abort_handler(void) {
     return;
 }
+
+PIKA_WEAK void pika_thread_idle_hook(void) {
+    return;
+}
+
 #endif

+ 8 - 1
src/PikaPlatform.h

@@ -199,7 +199,13 @@ size_t pika_platform_fwrite(const void* ptr,
 size_t pika_platform_fread(void* ptr, size_t size, size_t n, FILE* stream);
 int pika_platform_fseek(FILE* stream, long offset, int whence);
 long pika_platform_ftell(FILE* stream);
-
+char* pika_platform_getcwd(char* buf, size_t size);
+int pika_platform_chdir(const char* path);
+int pika_platform_rmdir(const char* pathname);
+int pika_platform_mkdir(const char* pathname, int mode);
+int pika_platform_remove(const char* pathname);
+int pika_platform_rename(const char* oldpath, const char* newpath);
+char** pika_platform_listdir(const char* path, int* count);
 /* error */
 void pika_platform_error_handle(void);
 
@@ -211,6 +217,7 @@ int64_t pika_platform_get_tick(void);
 void pika_platform_sleep_ms(uint32_t ms);
 
 void pika_hook_instruct(void);
+void pika_thread_idle_hook(void);
 PIKA_BOOL pika_hook_arg_cache_filter(void* self);
 void* pika_user_malloc(size_t size);
 void pika_user_free(void* ptr, size_t size);

+ 2 - 2
src/PikaVersion.h

@@ -1,5 +1,5 @@
 #define PIKA_VERSION_MAJOR 1
 #define PIKA_VERSION_MINOR 12
-#define PIKA_VERSION_MICRO 6
+#define PIKA_VERSION_MICRO 7
 
-#define PIKA_EDIT_TIME "2023/10/15 18:12:31"
+#define PIKA_EDIT_TIME "2023/10/22 12:57:51"