Explorar o código

fix str(None) return other string

lyon %!s(int64=3) %!d(string=hai) anos
pai
achega
1bd3b367f4

+ 10 - 3
package/PikaStdLib/PikaStdLib_SysObj.c

@@ -64,6 +64,9 @@ Arg* PikaStdLib_SysObj_type(PikaObj* self, Arg* arg) {
     if (ARG_TYPE_METHOD_STATIC == type) {
         return arg_setStr(NULL, "", "<class 'function'>");
     }
+    if (ARG_TYPE_NONE == type) {
+        return arg_setStr(NULL, "", "<class 'NoneType'>");
+    }
     return arg_setNull(NULL);
 }
 
@@ -107,6 +110,7 @@ int PikaStdLib_SysObj_int(PikaObj* self, Arg* arg) {
 }
 
 char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg) {
+    obj_removeArg(self, "__buf");
     ArgType type = arg_getType(arg);
     Args buffs = {0};
     char* res = NULL;
@@ -127,6 +131,9 @@ char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg) {
     if (ARG_TYPE_STRING == type) {
         res = arg_getStr(arg);
     }
+    if (ARG_TYPE_NONE == type) {
+        res = "None";
+    }
     if (argType_isObject(type)) {
         res = obj_toStr(arg_getPtr(arg));
         if (NULL != res) {
@@ -528,7 +535,7 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) {
 }
 
 char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) {
-		#if PIKA_SYNTEX_FORMAT_ENABLE
+#if PIKA_SYNTEX_FORMAT_ENABLE
     Args buffs = {0};
     pikaMemMaxReset();
     char* res = strsFormatList(&buffs, fmt, &var->super);
@@ -536,11 +543,11 @@ char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) {
     res = obj_getStr(self, "_buf");
     strsDeinit(&buffs);
     return res;
-		#else
+#else
     obj_setErrorCode(self, 1);
     __platform_printf("[Error] PIKA_SYNTEX_FORMAT_ENABLE is not enabled.\r\n");
     return NULL;
-		#endif
+#endif
 }
 
 int PikaStdLib_SysObj_id(PikaObj* self, Arg* obj) {

+ 1 - 1
port/linux/.vscode/launch.json

@@ -11,7 +11,7 @@
             "program": "${workspaceFolder}/build/test/pikascript_test",
             // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
             "args": [
-                // "--gtest_filter=pikaMain.num_issue1"
+                // "--gtest_filter=string.str_issue1"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 10 - 3
port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c

@@ -64,6 +64,9 @@ Arg* PikaStdLib_SysObj_type(PikaObj* self, Arg* arg) {
     if (ARG_TYPE_METHOD_STATIC == type) {
         return arg_setStr(NULL, "", "<class 'function'>");
     }
+    if (ARG_TYPE_NONE == type) {
+        return arg_setStr(NULL, "", "<class 'NoneType'>");
+    }
     return arg_setNull(NULL);
 }
 
@@ -107,6 +110,7 @@ int PikaStdLib_SysObj_int(PikaObj* self, Arg* arg) {
 }
 
 char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg) {
+    obj_removeArg(self, "__buf");
     ArgType type = arg_getType(arg);
     Args buffs = {0};
     char* res = NULL;
@@ -127,6 +131,9 @@ char* PikaStdLib_SysObj_str(PikaObj* self, Arg* arg) {
     if (ARG_TYPE_STRING == type) {
         res = arg_getStr(arg);
     }
+    if (ARG_TYPE_NONE == type) {
+        res = "None";
+    }
     if (argType_isObject(type)) {
         res = obj_toStr(arg_getPtr(arg));
         if (NULL != res) {
@@ -528,7 +535,7 @@ void PikaStdLib_SysObj_printNoEnd(PikaObj* self, Arg* val) {
 }
 
 char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) {
-		#if PIKA_SYNTEX_FORMAT_ENABLE
+#if PIKA_SYNTEX_FORMAT_ENABLE
     Args buffs = {0};
     pikaMemMaxReset();
     char* res = strsFormatList(&buffs, fmt, &var->super);
@@ -536,11 +543,11 @@ char* PikaStdLib_SysObj_cformat(PikaObj* self, char* fmt, PikaTuple* var) {
     res = obj_getStr(self, "_buf");
     strsDeinit(&buffs);
     return res;
-		#else
+#else
     obj_setErrorCode(self, 1);
     __platform_printf("[Error] PIKA_SYNTEX_FORMAT_ENABLE is not enabled.\r\n");
     return NULL;
-		#endif
+#endif
 }
 
 int PikaStdLib_SysObj_id(PikaObj* self, Arg* obj) {

+ 47 - 0
port/linux/test/parse-test.cpp

@@ -3400,6 +3400,53 @@ TEST(parser, function_chain) {
     EXPECT_EQ(pikaMemNow(), 0);
 }
 
+TEST(parser, str_issue1) {
+    char* lines =
+        "if str(type(data)) == \"<class 'str'>\" and str(type(included_data)) "
+        "== \"<class 'str'>\":\n"
+        "\n";
+    pikaMemInfo.heapUsedMax = 0;
+    Args* buffs = New_strBuff();
+    __platform_printf("%s\n", lines);
+    char* pikaAsm = Parser_multiLineToAsm(buffs, lines);
+    __platform_printf("%s", pikaAsm);
+    EXPECT_STREQ(pikaAsm,
+                 "B0\n"
+                 "4 REF data\n"
+                 "3 RUN type\n"
+                 "2 RUN str\n"
+                 "2 STR <class 'str'>\n"
+                 "1 OPT ==\n"
+                 "4 REF included_data\n"
+                 "3 RUN type\n"
+                 "2 RUN str\n"
+                 "2 STR <class 'str'>\n"
+                 "1 OPT ==\n"
+                 "0 OPT  and \n"
+                 "0 JEZ 1\n"
+                 "B0\n");
+    args_deinit(buffs);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
+TEST(parser, str_issue2) {
+    char* lines = "print('ret = %s' % str(ret))\n";
+    pikaMemInfo.heapUsedMax = 0;
+    Args* buffs = New_strBuff();
+    __platform_printf("%s\n", lines);
+    char* pikaAsm = Parser_multiLineToAsm(buffs, lines);
+    __platform_printf("%s", pikaAsm);
+    EXPECT_STREQ(pikaAsm,
+                 "B0\n"
+                 "2 STR ret = %s\n"
+                 "3 REF ret\n"
+                 "2 RUN str\n"
+                 "1 RUN cformat\n"
+                 "0 RUN print\n");
+    args_deinit(buffs);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
 TEST(parser, num_issue) {
     pikaMemInfo.heapUsedMax = 0;
     Args* buffs = New_strBuff();

+ 33 - 0
port/linux/test/python/str_issue1.py

@@ -0,0 +1,33 @@
+def is_include(included_data, data):     #判断一个字符串是否存在于另外一个字符串中
+    if str(type(data)) == "<class 'str'>" and str(type(included_data)) == "<class 'str'>":
+        print('type assert passed')
+        data_length = len(data)
+        included_data_length = len(included_data)
+        if data_length == included_data_length:
+            print('length assert passed')
+            if data == included_data:
+                print('data equal assert passed 1')
+                return True
+            else:
+                print('data not equal 1')
+                return None
+        elif data_length > included_data_length:
+            max_count = data_length - included_data_length
+            for i in range(0, max_count):
+                if data[i:i+included_data_length] == included_data:
+                    print('data equal assert passed 2')
+                    return True
+            print('data not equal 2')
+            return None
+        else:
+            print('data not equal 3')
+            return None
+    else:
+        print('type assert failed')
+        return 'TypeError'
+
+a = '34'
+b = '35'
+ret = (is_include(a, b))
+ret_str = str(ret)
+print('ret = %s' % ret_str)

+ 24 - 6
port/linux/test/string-test.cpp

@@ -170,12 +170,11 @@ TEST(string, replace_chain) {
     pikaMemInfo.heapUsedMax = 0;
     PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
     /* run */
-    obj_run(
-        pikaMain,
-        "from PikaStdData import String as S\n"
-        "res = PikaStdData.String('  a,b,c, d  ').replace('a', 'A')\n"
-        "res2 = S(S('[test]').replace('[','')).replace(']','')\n"
-        "\n");
+    obj_run(pikaMain,
+            "from PikaStdData import String as S\n"
+            "res = PikaStdData.String('  a,b,c, d  ').replace('a', 'A')\n"
+            "res2 = S(S('[test]').replace('[','')).replace(']','')\n"
+            "\n");
     /* collect */
     char* res = obj_getStr(pikaMain, "res");
     char* res2 = obj_getStr(pikaMain, "res2");
@@ -223,3 +222,22 @@ TEST(string, str_chain) {
     obj_deinit(pikaMain);
     EXPECT_EQ(pikaMemNow(), 0);
 }
+
+#if PIKA_SYNTEX_FORMAT_ENABLE
+TEST(string, str_issue1) {
+    /* init */
+    pikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    pikaVM_runSingleFile(pikaMain, "test/python/str_issue1.py");
+    /* collect */
+    char* ret_str = obj_getStr(pikaMain, "ret_str");
+    /* assert */
+    EXPECT_STREQ(ret_str, "None");
+    /* deinit */
+    obj_deinit(pikaMain);
+
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+#endif

+ 1 - 1
src/PikaVersion.h

@@ -2,4 +2,4 @@
 #define PIKA_VERSION_MINOR       9
 #define PIKA_VERSION_MICRO       0
 
-#define PIKA_EDIT_TIME      "2022/07/06 11:03:07"
+#define PIKA_EDIT_TIME      "2022/07/06 15:13:21"

+ 12 - 2
src/dataArgs.c

@@ -79,7 +79,7 @@ PIKA_RES args_setStr(Args* self, char* name, char* strIn) {
     PIKA_RES errCode = PIKA_RES_OK;
     Arg* argNew = New_arg(NULL);
     argNew = arg_setStr(argNew, name, strIn);
-    if(NULL == argNew){
+    if (NULL == argNew) {
         return PIKA_RES_ERR_INVALID_PTR;
     }
     args_setArg(self, argNew);
@@ -587,8 +587,14 @@ char* strsFormatArg(Args* out_buffs, char* fmt, Arg* arg) {
         res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, val);
         goto exit;
     }
+    if (ARG_TYPE_NONE == type) {
+        res = strsFormat(&buffs, PIKA_SPRINTF_BUFF_SIZE, fmt, "None");
+        goto exit;
+    }
 exit:
-    res = strsCopy(out_buffs, res);
+    if (NULL != res) {
+        res = strsCopy(out_buffs, res);
+    }
     strsDeinit(&buffs);
     return res;
 }
@@ -606,6 +612,10 @@ char* strsFormatList(Args* out_buffs, char* fmt, PikaList* list) {
         char* fmt_item = strsPopToken(&buffs_item, fmt_buff, '%');
         fmt_item = strsAppend(&buffs_item, "%", fmt_item);
         char* str_format = strsFormatArg(&buffs_item, fmt_item, arg);
+        if (NULL == str_format) {
+            strsDeinit(&buffs_item);
+            goto exit;
+        }
         res_buff = arg_strAppend(res_buff, str_format);
         strsDeinit(&buffs_item);
     }