Browse Source

update & fix: 调整文件寻找策略

文件需找默认从env下寻找
涉及修改:file, clib, import/include
修改import在比较字符串后缀的时候使用eqWide比较char *的错误
修改eqWide, 去掉强制类型转换

link #20
SongZihuan 4 years ago
parent
commit
50743bf0f6

+ 12 - 0
vmcore/file/file.c

@@ -46,3 +46,15 @@ char *splitDir(char * dir){
             *tmp = '_';
     return return_char;
 }
+
+
+char *findPath(char **path, char *env, bool need_free) {  // env 必须以 SEP 结尾
+#ifdef __linux
+    if (**path == SEP_CH) {
+#else
+    if (!(isupper(**path) && *path[1] == ':')) {
+#endif
+        *path = memStrcat(env, *path, false, need_free);  // 调整为相对路径模式
+    }
+    return *path;
+}

+ 2 - 1
vmcore/include/file.h

@@ -2,6 +2,7 @@
 #define VIRTUALMATH_FILE_H
 
 int checkFileReadable(char *dir);
-char *splitDir(char * dir);
+char *findPath(char **path, char *env, bool need_free);
+char *splitDir(char *dir);
 
 #endif //VIRTUALMATH_FILE_H

+ 1 - 1
vmcore/include/mem.h

@@ -25,7 +25,7 @@ wchar_t *memStrToWcs(char *str, bool free_old);
 
 #define memFree(p) ((p) = ((p) != NULL ? (free((p)), NULL) : NULL))
 #define eqString(str1, str2) (!strcmp((str1), (str2)))
-#define eqWide(wid1, wid2) (!wcscmp((wchar_t *)(wid1), (wchar_t *)(wid2)))
+#define eqWide(wid1, wid2) (!wcscmp((wid1), (wid2)))
 #define memString(size) (char *)memCalloc((size) + 1, sizeof(char))
 #define memWide(size) (wchar_t *)memCalloc((size) + 1, sizeof(wchar_t))
 #define memStrlen(p) (((p) == NULL) ? 0 : strlen((p)))

+ 7 - 2
vmcore/ofunc/src/vmobj/file_.c

@@ -37,6 +37,7 @@ static ResultType file_init(O_FUNC){
     LinkValue *file;
     char *path;
     char *mode;
+    FILE *f;
     setResultCore(result);
     parserArgumentUnion(ap, arg, CNEXT_NT);
     if (!CHECK_RESULT(result))
@@ -62,8 +63,12 @@ static ResultType file_init(O_FUNC){
     else
         mode = memStrcpy("rt");  // 默认模式是rt
 
-    if (checkFileReadable(path) != 1) {
-        setResultError(E_TypeException, L"file is not readable", LINEFILE, true, CNEXT_NT);
+    findPath(&path, inter->data.env, true);  // 更新env
+    f = fopen(path, mode);
+    if (f == NULL) {
+        wchar_t *message = memStrToWcs(memStrcat("file is not readable : ", strerror(errno), false, false), true);
+        setResultError(E_TypeException, message, LINEFILE, true, CNEXT_NT);
+        memFree(message);
         return R_error;
     }
     file->value->data.file.path = path;

+ 1 - 4
vmcore/ofunc/src/vmobj/lib_.c

@@ -42,11 +42,8 @@ static ResultType lib_init(O_FUNC){
         return R_error;
     }
     path = memWcsToStr(ap[1].value->value->data.str.str, false);
+    findPath(&path, inter->data.env, true);
     handle = dlopen(path, RTLD_NOW);
-    if (handle == NULL) {
-        path = memStrcat(inter->data.env, path, false, true);  // 检查env地址下是否存在这个包
-        handle = dlopen(path, RTLD_NOW);
-    }
     if (handle == NULL) {
         wchar_t *tmp = memWidecat(L"load lib error: ", memStrToWcs(dlerror(), false), false, true);
         setResultError(E_ImportException, tmp, LINEFILE, true, CNEXT_NT);

+ 4 - 22
vmcore/src/runfile.c

@@ -42,7 +42,7 @@ static bool isExist(char **path, bool is_ab, char *file) {  // is_ab 参数参
             return isExist(path, false, NULL);
         } else
             return true;
-    } else if (checkFileReadable(backup = memStrcat(backup, ".vm", true, false)) == 1) {
+    } else if (checkFileReadable(backup = memStrcat(backup, ".vm", true, false)) == 1) {  // 添加.vm检查文件是否存在
         memFree(*path);  // 若文件存在则替换文件路径
         *path = backup;
         return true;
@@ -54,7 +54,7 @@ static bool isExist(char **path, bool is_ab, char *file) {  // is_ab 参数参
 #define GOTO_RETURN(num) do{return_num = num; goto return_;}while(0)
 #define CHECK_TYPE(file) do { /* 判断文件类型 */ \
     void *dl; \
-    if (eqWide((file) + memStrlen(file) - 3, ".vm")) { \
+    if (eqString((file) + memStrlen(file) - 3, ".vm")) { \
         GOTO_RETURN(1);  /* return 2 表示clib模式 */ \
     } else if (CHECK_CLIB(file, dl)) { \
         GOTO_RETURN(2);  /* return 1 表示.vm模式 */ \
@@ -66,7 +66,7 @@ static bool isExist(char **path, bool is_ab, char *file) {  // is_ab 参数参
 
 int checkFileDir(char **file_dir, FUNC) {
     int return_num;
-    bool diff = false;
+    bool diff = false;  // diff为true的时候表示lib_file和file_dir不同(避免重复检查)
     char *lib_file = strncmp(*file_dir, "lib", 3) == 0 ? memStrcpy(*file_dir) : (diff = true, memStrcat("libvm", *file_dir, false, false));  // 自动增加libvm前缀
     if (strstr(lib_file, SHARED_MARK) == NULL) {
         lib_file = memStrcat(lib_file, SHARED_MARK, true, false);
@@ -87,28 +87,10 @@ int checkFileDir(char **file_dir, FUNC) {
             break;
     }
 
+    findPath(file_dir, inter->data.env, true);  // 调整地址
     if (isExist(file_dir, false, "__init__.vm"))
         CHECK_TYPE(*file_dir);
 
-    {
-        char *p_cwd = memStrcatIter(inter->data.env, false, SEP, *file_dir, NULL);  // 以NULL结尾表示结束
-        if (isExist(&p_cwd, false, "__init__.vm")) {
-            memFree(*file_dir);
-            *file_dir = p_cwd;  // p_cwd 不需要释放
-            CHECK_TYPE(*file_dir);
-        } else if (diff) {  // 检查是否为动态库, 若 lib_file 和 file_dir 一致则不检查
-            void *tmp_dl;
-            memFree(p_cwd);
-            p_cwd = memStrcatIter(inter->data.env, false, SEP, lib_file, NULL);  // 以NULL结尾表示结束
-            if (CHECK_CLIB(p_cwd, tmp_dl)) {
-                memFree(*file_dir);
-                *file_dir = p_cwd;  // p_cwd 不需要释放
-                GOTO_RETURN(2);
-            }
-        }
-        memFree(p_cwd);
-    }
-
     path: {
         char *path = memStrcpy(getenv("VIRTUALMATHPATH"));  // 因为 strtok 需要修改path, 所以path不能重复使用
         for (char *tmp = strtok(path, ";"), *new_dir; tmp != NULL; tmp = strtok(NULL, ";")) {