Kaynağa Gözat

fatfs and os tested on STM32

Lyon 2 yıl önce
ebeveyn
işleme
f4b4e77a8d

+ 39 - 0
package/pika_fatfs/pika_fatfs.c

@@ -184,4 +184,43 @@ char** pika_platform_listdir(const char* path, int* count) {
     return filelist;
 }
 
+int pika_platform_path_exists(const char *path){
+    FRESULT res;
+    FILINFO fno;
+    
+    res = f_stat(path, &fno);
+    if (res != FR_OK) {
+        return 0; // Path does not exist
+    }
+    return 1;
+}
+
+int pika_platform_path_isdir(const char *path){
+		int is_dir = 0;
+    FRESULT res;
+    FILINFO fno;
+
+    res = f_stat(path, &fno);
+    if (res == FR_OK) {
+        is_dir = (fno.fattrib & AM_DIR) ? 1 : 0;
+    }else{
+				return 0;
+		}
+    return is_dir;
+}
+
+int pika_platform_path_isfile(const char *path){
+    int is_file = 0;
+    FRESULT res;
+    FILINFO fno;
+
+    res = f_stat(path, &fno);
+    if (res == FR_OK) {
+        is_file = (fno.fattrib & AM_DIR) == 0 ? 1 : 0;
+    }else{
+				return 0;
+		}
+    return is_file;
+}
+
 #endif

+ 13 - 37
port/linux/package/pikascript/pikascript-lib/os/os_path.c

@@ -40,12 +40,12 @@ char* os_path_abspath(PikaObj* self, char* path) {
         return NULL;
     }
 #else
-    char* cwd = getcwd(NULL, 0);
+    char* cwd = pika_platform_getcwd(NULL, 0);
     if (cwd == NULL) {
         return NULL;
     }
 
-    abs_path = realpath(path, NULL);
+    abs_path = pika_platform_realpath(path, NULL);
     if (abs_path == NULL) {
         free(cwd);
         return NULL;
@@ -83,13 +83,15 @@ PIKA_BOOL os_path_exists(PikaObj* self, char* path) {
     }
 
     return PIKA_TRUE;
-#else
+#elif defined(__linux)
     struct stat statbuf;
     if (stat(path, &statbuf) == -1) {
         return PIKA_FALSE;
     }
 
     return PIKA_TRUE;
+#else
+		return pika_platform_path_exists(path);
 #endif
 }
 
@@ -115,38 +117,12 @@ PIKA_BOOL os_path_isabs(PikaObj* self, char* path) {
 
 // Returns true if the given path is a directory, false otherwise.
 PIKA_BOOL os_path_isdir(PikaObj* self, char* path) {
-    PIKA_BOOL is_dir = PIKA_FALSE;
-#ifdef _WIN32
-    DWORD attrs = GetFileAttributes((LPCWSTR)path);
-    if (attrs != INVALID_FILE_ATTRIBUTES) {
-        is_dir =
-            (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0 ? PIKA_TRUE : PIKA_FALSE;
-    }
-#else
-    struct stat st;
-    if (stat(path, &st) == 0) {
-        is_dir = S_ISDIR(st.st_mode) ? PIKA_TRUE : PIKA_FALSE;
-    }
-#endif
-    return is_dir;
+    return pika_platform_path_isdir(path);
 }
 
 // Returns true if the given path is a regular file, false otherwise.
 PIKA_BOOL os_path_isfile(PikaObj* self, char* path) {
-    PIKA_BOOL is_file = PIKA_FALSE;
-#ifdef _WIN32
-    DWORD attrs = GetFileAttributes(path);
-    if (attrs != INVALID_FILE_ATTRIBUTES) {
-        is_file =
-            (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0 ? PIKA_TRUE : PIKA_FALSE;
-    }
-#else
-    struct stat st;
-    if (stat(path, &st) == 0) {
-        is_file = S_ISREG(st.st_mode) ? PIKA_TRUE : PIKA_FALSE;
-    }
-#endif
-    return is_file;
+		return pika_platform_path_isfile(path);
 }
 
 char* os_path_join(PikaObj* self, PikaTuple* paths) {
@@ -226,7 +202,7 @@ int _os_path_split(char* path, char** folder, char** file) {
         }
         strncpy(*folder, path, idx + 1);
         (*folder)[idx] = '\0';
-        *file = strdup(p + 1);
+        *file = pika_platform_strdup(p + 1);
         if (*file == NULL) {
             pika_platform_free(*folder);
             *folder = NULL;
@@ -234,11 +210,11 @@ int _os_path_split(char* path, char** folder, char** file) {
         }
         return 0;
     } else {
-        *folder = strdup(path);
+        *folder = pika_platform_strdup(path);
         if (*folder == NULL) {
             return -1;
         }
-        *file = strdup("");
+        *file = pika_platform_strdup("");
         if (*file == NULL) {
             pika_platform_free(*folder);
             *folder = NULL;
@@ -258,7 +234,7 @@ int _os_path_splitext(char* path, char** file, char** ext) {
         }
         strncpy(*file, path, idx);
         (*file)[idx] = '\0';
-        *ext = strdup(p);
+        *ext = pika_platform_strdup(p);
         if (!(*ext)) {
             pika_platform_free(*file);
             *file = NULL;
@@ -266,11 +242,11 @@ int _os_path_splitext(char* path, char** file, char** ext) {
         }
         return 0;
     } else {
-        *file = strdup(path);
+        *file = pika_platform_strdup(path);
         if (!(*file)) {
             return -1;
         }
-        *ext = strdup("");
+        *ext = pika_platform_strdup("");
         if (!(*ext)) {
             free(*file);
             *file = NULL;

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

@@ -138,7 +138,7 @@ int os_mkdir_platform(int mode, char* path) {
 
 int os_chdir_platform(char* path) {
     int ret = 0;
-    ret = chdir(path);
+    ret = pika_platform_chdir(path);
     if (ret == 0)
         ret = PIKA_TRUE;
     else

+ 114 - 0
src/PikaPlatform.c

@@ -299,6 +299,120 @@ PIKA_WEAK int pika_platform_mkdir(const char* pathname, int mode) {
 #endif
 }
 
+PIKA_WEAK char *pika_platform_realpath(const char *path, char *resolved_path) {
+#if defined(_WIN32) || defined(__linux) || PIKA_LINUX_COMPATIBLE
+		return realpath(path, resolved_path);
+#else
+    if (!path || !resolved_path) return NULL;
+
+    char *output = resolved_path;
+    const char *segment_start = path;
+    const char *segment_end = path;
+
+    while (*segment_end) {
+        if (*segment_end == '/' || *(segment_end + 1) == '\0') {
+            size_t segment_len = segment_end - segment_start + (*segment_end != '/');
+
+            if (segment_len == 1 && segment_start[0] == '.') {
+                // Skip single-dot segment
+            } else if (segment_len == 2 && segment_start[0] == '.' && segment_start[1] == '.') {
+                // Handle double-dot segment by backtracking
+                if (output > resolved_path) {
+                    output--;  // Move back one char to overwrite the last slash
+                    while (output > resolved_path && *output != '/') {
+                        output--;
+                    }
+                }
+            } else {
+                // Copy the segment to the output
+                strncpy(output, segment_start, segment_len);
+                output += segment_len;
+                if (*segment_end) {
+                    *output = '/';
+                    output++;
+                }
+            }
+
+            segment_end++;  // Move past the slash
+            segment_start = segment_end;
+        } else {
+            segment_end++;
+        }
+    }
+    
+    if (output != resolved_path && *(output - 1) == '/') {
+        output--;  // Remove trailing slash, if any
+    }
+
+    *output = '\0';  // Null-terminate the resolved path
+
+    return resolved_path;
+#endif
+}
+
+PIKA_WEAK int pika_platform_path_exists(const char *path){
+#ifdef _WIN32
+    DWORD attr = GetFileAttributesA((LPCWSTR)path);
+    if (attr == INVALID_FILE_ATTRIBUTES) {
+        return 0;
+    }
+
+    return 1;
+#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
+    struct stat statbuf;
+    if (stat(path, &statbuf) == -1) {
+        return 0;
+    }
+
+    return 1;
+#else
+		WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
+}
+
+PIKA_WEAK int pika_platform_path_isdir(const char *path){
+#ifdef _WIN32
+    int is_dir = 0;
+    DWORD attrs = GetFileAttributes((LPCWSTR)path);
+    if (attrs != INVALID_FILE_ATTRIBUTES) {
+        is_dir =
+            (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0 ? 1 : 0;
+    }
+    return is_dir;
+#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
+    int is_dir = 0;
+    struct stat st;
+    if (stat(path, &st) == 0) {
+        is_dir = S_ISDIR(st.st_mode) ? PIKA_TRUE : PIKA_FALSE;
+    }
+    return is_dir;
+#else
+		WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
+}
+
+// Returns true if the given path is a regular file, false otherwise.
+PIKA_WEAK int pika_platform_path_isfile(const char* path) {
+#ifdef _WIN32
+    int is_file = 0;
+    DWORD attrs = GetFileAttributes(path);
+    if (attrs != INVALID_FILE_ATTRIBUTES) {
+        is_file =
+            (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0 ? PIKA_TRUE : PIKA_FALSE;
+    }
+    return is_file;
+#elif defined(__linux) || PIKA_LINUX_COMPATIBLE
+    int is_file = 0;
+    struct stat st;
+    if (stat(path, &st) == 0) {
+        is_file = S_ISREG(st.st_mode) ? PIKA_TRUE : PIKA_FALSE;
+    }
+    return is_file;
+#else
+    WEAK_FUNCTION_NEED_OVERRIDE_ERROR_LOWLEVEL(_);
+#endif
+}
+
 PIKA_WEAK int pika_platform_remove(const char* pathname) {
 #if defined(__linux) || defined(_WIN32)
     return remove(pathname);

+ 4 - 0
src/PikaPlatform.h

@@ -203,6 +203,10 @@ 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);
+char *pika_platform_realpath(const char *path, char *resolved_path);
+int pika_platform_path_exists(const char *path);
+int pika_platform_path_isdir(const char* path);
+int pika_platform_path_isfile(const char* path);
 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);