Răsfoiți Sursa

fix json parse issue on jsmn and fix compiler

lyon 2 ani în urmă
părinte
comite
e32ba87dff

+ 10 - 0
examples/json/json_issue1.py

@@ -0,0 +1,10 @@
+import json
+data = '{"code": 0,"path": "act_mode_config", "act_mode": [["ACTUATOR_NAME","ACTUATOR_ID","ACTUATOR_MODE_NAME","ACTUATOR_MODE_ID","ACT_MODE_TYPE","ACT_VALUE_TIME_s"],["电机1","actuator123","开闭循环1","mode2345","loop","{\\"AC_VALUE\\":1,\\"ACT_TIME_s\\":300}"],["电机1","actuator123","常开","mode2346","always","{\\"AC_VALUE\\":1,\\"ACT_TIME_s\\"}:0"]],"ext": "data"}'
+
+print(data)
+json_data = json.loads(data)
+ACT_VALUE_TIMS_S = json_data['act_mode'][1][5]
+print(ACT_VALUE_TIMS_S)
+act_value_tims_json = json.loads(ACT_VALUE_TIMS_S)
+print(act_value_tims_json['ACT_TIME_s'])
+act_time_s = act_value_tims_json['ACT_TIME_s']

+ 43 - 27
package/json/_json.c

@@ -73,10 +73,21 @@ Arg* json_to_arg_recursive(jsmntok_t* t,
             }
             break;
         }
-        case JSMN_STRING:
+        case JSMN_STRING: {
             val = arg_newStrN(json_str + t[*index].start,
                               t[*index].end - t[*index].start);
+            char* raw = arg_getStr(val);
+            if (strIsContain(arg_getStr(val), '\\')) {
+                Args buffs = {0};
+                size_t i = 0;
+                char* transfered_str = strsTransfer(&buffs, raw, &i);
+                Arg* val_transfered = arg_newStr(transfered_str);
+                arg_deinit(val);
+                val = val_transfered;
+                strsDeinit(&buffs);
+            }
             break;
+        }
         case JSMN_OBJECT: {
             PikaObj* ret = obj_newDict(NULL);
             int num_keys = t[*index].size;
@@ -164,32 +175,37 @@ int32_t jsonDictEachHandle(PikaObj* self,
 
 cJSON* _cjson_decode(Arg* d) {
     ArgType type = arg_getType(d);
-    if (type == ARG_TYPE_NONE) {
-        return cJSON_CreateNull();
-    } else if (type == ARG_TYPE_INT) {
-        return cJSON_CreateNumber(arg_getInt(d));
-    } else if (type == ARG_TYPE_FLOAT) {
-        return cJSON_CreateNumber(arg_getFloat(d));
-    } else if (type == ARG_TYPE_BOOL) {
-        if (arg_getBool(d)) {
-            return cJSON_CreateTrue();
-        } else {
-            return cJSON_CreateFalse();
-        }
-    } else if (type == ARG_TYPE_STRING) {
-        return cJSON_CreateString(arg_getStr(d));
-    } else if (arg_isList(d)) {
-        JsonListContext context;
-        context.jsonArray = cJSON_CreateArray();
-        objList_forEach(arg_getObj(d), jsonListEachHandle, &context);
-        return context.jsonArray;
-    } else if (arg_isDict(d)) {
-        JsonDictContext context;
-        context.jsonObject = cJSON_CreateObject();
-        objDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
-        return context.jsonObject;
-    } else {
-        return cJSON_CreateNull();
+    switch (type) {
+        case ARG_TYPE_NONE:
+            return cJSON_CreateNull();
+
+        case ARG_TYPE_INT:
+            return cJSON_CreateNumber(arg_getInt(d));
+
+        case ARG_TYPE_FLOAT:
+            return cJSON_CreateNumber(arg_getFloat(d));
+
+        case ARG_TYPE_BOOL:
+            return arg_getBool(d) ? cJSON_CreateTrue() : cJSON_CreateFalse();
+
+        case ARG_TYPE_STRING:
+            return cJSON_CreateString(arg_getStr(d));
+
+        default:
+            if (arg_isList(d)) {
+                JsonListContext context;
+                context.jsonArray = cJSON_CreateArray();
+                objList_forEach(arg_getObj(d), jsonListEachHandle, &context);
+                return context.jsonArray;
+            }
+
+            if (arg_isDict(d)) {
+                JsonDictContext context;
+                context.jsonObject = cJSON_CreateObject();
+                objDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
+                return context.jsonObject;
+            }
+            return cJSON_CreateNull();
     }
 }
 

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

@@ -30,7 +30,8 @@
                 // "--gtest_filter=eventloop.*"
                 // "--gtest_filter=event.event_thread"
                 // "--gtest_filter=_json.loads"
-                "--gtest_filter=json.speed"
+                // "--gtest_filter=json.speed"
+                "--gtest_filter=json.json_issue1"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 43 - 27
port/linux/package/pikascript/pikascript-lib/json/_json.c

@@ -73,10 +73,21 @@ Arg* json_to_arg_recursive(jsmntok_t* t,
             }
             break;
         }
-        case JSMN_STRING:
+        case JSMN_STRING: {
             val = arg_newStrN(json_str + t[*index].start,
                               t[*index].end - t[*index].start);
+            char* raw = arg_getStr(val);
+            if (strIsContain(arg_getStr(val), '\\')) {
+                Args buffs = {0};
+                size_t i = 0;
+                char* transfered_str = strsTransfer(&buffs, raw, &i);
+                Arg* val_transfered = arg_newStr(transfered_str);
+                arg_deinit(val);
+                val = val_transfered;
+                strsDeinit(&buffs);
+            }
             break;
+        }
         case JSMN_OBJECT: {
             PikaObj* ret = obj_newDict(NULL);
             int num_keys = t[*index].size;
@@ -164,32 +175,37 @@ int32_t jsonDictEachHandle(PikaObj* self,
 
 cJSON* _cjson_decode(Arg* d) {
     ArgType type = arg_getType(d);
-    if (type == ARG_TYPE_NONE) {
-        return cJSON_CreateNull();
-    } else if (type == ARG_TYPE_INT) {
-        return cJSON_CreateNumber(arg_getInt(d));
-    } else if (type == ARG_TYPE_FLOAT) {
-        return cJSON_CreateNumber(arg_getFloat(d));
-    } else if (type == ARG_TYPE_BOOL) {
-        if (arg_getBool(d)) {
-            return cJSON_CreateTrue();
-        } else {
-            return cJSON_CreateFalse();
-        }
-    } else if (type == ARG_TYPE_STRING) {
-        return cJSON_CreateString(arg_getStr(d));
-    } else if (arg_isList(d)) {
-        JsonListContext context;
-        context.jsonArray = cJSON_CreateArray();
-        objList_forEach(arg_getObj(d), jsonListEachHandle, &context);
-        return context.jsonArray;
-    } else if (arg_isDict(d)) {
-        JsonDictContext context;
-        context.jsonObject = cJSON_CreateObject();
-        objDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
-        return context.jsonObject;
-    } else {
-        return cJSON_CreateNull();
+    switch (type) {
+        case ARG_TYPE_NONE:
+            return cJSON_CreateNull();
+
+        case ARG_TYPE_INT:
+            return cJSON_CreateNumber(arg_getInt(d));
+
+        case ARG_TYPE_FLOAT:
+            return cJSON_CreateNumber(arg_getFloat(d));
+
+        case ARG_TYPE_BOOL:
+            return arg_getBool(d) ? cJSON_CreateTrue() : cJSON_CreateFalse();
+
+        case ARG_TYPE_STRING:
+            return cJSON_CreateString(arg_getStr(d));
+
+        default:
+            if (arg_isList(d)) {
+                JsonListContext context;
+                context.jsonArray = cJSON_CreateArray();
+                objList_forEach(arg_getObj(d), jsonListEachHandle, &context);
+                return context.jsonArray;
+            }
+
+            if (arg_isDict(d)) {
+                JsonDictContext context;
+                context.jsonObject = cJSON_CreateObject();
+                objDict_forEach(arg_getObj(d), jsonDictEachHandle, &context);
+                return context.jsonObject;
+            }
+            return cJSON_CreateNull();
     }
 }
 

+ 9 - 2
src/PikaParser.c

@@ -1889,13 +1889,20 @@ AST* AST_parseStmt(AST* ast, char* stmt) {
     if (STMT_string == stmtType) {
         str = strsCopy(&buffs, right);
         /* remove the first char */
+        char firstChar = str[0];
         str = str + 1;
         /* remove the last char */
         str[strGetSize(str) - 1] = '\0';
         /* replace */
         if (strIsContain(str, '\\')) {
-            str = strsReplace(&buffs, str, "\\\"", "\"");
-            str = strsReplace(&buffs, str, "\\'", "'");
+            switch (firstChar) {
+                case '\'':
+                    str = strsReplace(&buffs, str, "\\\'", "\'");
+                    break;
+                case '\"':
+                    str = strsReplace(&buffs, str, "\\\"", "\"");
+                    break;
+            }
         }
         AST_setNodeAttr(ast, (char*)"string", str);
         goto __exit;

+ 2 - 57
src/PikaVM.c

@@ -2133,61 +2133,6 @@ __exit:
     return aReturn;
 }
 
-static char* __get_transferd_str(Args* buffs, char* str, size_t* iout_p) {
-    char* transfered_str = args_getBuff(buffs, strGetSize(str));
-    size_t i_out = 0;
-    size_t len = strGetSize(str);
-    for (size_t i = 0; i < len; i++) {
-        /* eg. replace '\x33' to '3' */
-        if ((str[i] == '\\') && (str[i + 1] == 'x')) {
-            char hex_str[] = "0x00";
-            hex_str[2] = str[i + 2];
-            hex_str[3] = str[i + 3];
-            char hex = (char)strtoll(hex_str, NULL, 0);
-            transfered_str[i_out++] = hex;
-            i += 3;
-            continue;
-        }
-        if (str[i] == '\\') {
-            switch (str[i + 1]) {
-                case 'r':
-                    transfered_str[i_out++] = '\r';
-                    break;
-                case 'n':
-                    transfered_str[i_out++] = '\n';
-                    break;
-                case 't':
-                    transfered_str[i_out++] = '\t';
-                    break;
-                case 'b':
-                    transfered_str[i_out++] = '\b';
-                    break;
-                case '\\':
-                    transfered_str[i_out++] = '\\';
-                    break;
-                case '\'':
-                    transfered_str[i_out++] = '\'';
-                    break;
-                case '\"':
-                    transfered_str[i_out++] = '\"';
-                    break;
-                case '?':
-                    transfered_str[i_out++] = '\?';
-                    break;
-                default:
-                    transfered_str[i_out++] = str[i];
-                    break;
-            }
-            i += 1;
-            continue;
-        }
-        /* normal char */
-        transfered_str[i_out++] = str[i];
-    }
-    *iout_p = i_out;
-    return transfered_str;
-}
-
 static Arg* VM_instruction_handler_STR(PikaObj* self,
                                        VMState* vm,
                                        char* data,
@@ -2195,7 +2140,7 @@ static Arg* VM_instruction_handler_STR(PikaObj* self,
     if (strIsContain(data, '\\')) {
         Args buffs = {0};
         size_t i_out = 0;
-        char* transfered_str = __get_transferd_str(&buffs, data, &i_out);
+        char* transfered_str = strsTransfer(&buffs, data, &i_out);
         Arg* return_arg = arg_ret_reg;
         return_arg = arg_setStr(return_arg, "", transfered_str);
         strsDeinit(&buffs);
@@ -2211,7 +2156,7 @@ static Arg* VM_instruction_handler_BYT(PikaObj* self,
     if (strIsContain(data, '\\')) {
         Args buffs = {0};
         size_t i_out = 0;
-        char* transfered_str = __get_transferd_str(&buffs, data, &i_out);
+        char* transfered_str = strsTransfer(&buffs, data, &i_out);
         Arg* return_arg = New_arg(NULL);
         return_arg =
             arg_setBytes(return_arg, "", (uint8_t*)transfered_str, i_out);

+ 55 - 0
src/dataStrs.c

@@ -228,3 +228,58 @@ char* strsPathGetFileName(Args* buffs_p, char* input) {
     strPathGetFileName(input, buff);
     return buff;
 }
+
+char* strsTransfer(Args* buffs, char* str, size_t* iout_p) {
+    char* transfered_str = args_getBuff(buffs, strGetSize(str));
+    size_t i_out = 0;
+    size_t len = strGetSize(str);
+    for (size_t i = 0; i < len; i++) {
+        /* eg. replace '\x33' to '3' */
+        if ((str[i] == '\\') && (str[i + 1] == 'x')) {
+            char hex_str[] = "0x00";
+            hex_str[2] = str[i + 2];
+            hex_str[3] = str[i + 3];
+            char hex = (char)strtoll(hex_str, NULL, 0);
+            transfered_str[i_out++] = hex;
+            i += 3;
+            continue;
+        }
+        if (str[i] == '\\') {
+            switch (str[i + 1]) {
+                case 'r':
+                    transfered_str[i_out++] = '\r';
+                    break;
+                case 'n':
+                    transfered_str[i_out++] = '\n';
+                    break;
+                case 't':
+                    transfered_str[i_out++] = '\t';
+                    break;
+                case 'b':
+                    transfered_str[i_out++] = '\b';
+                    break;
+                case '\\':
+                    transfered_str[i_out++] = '\\';
+                    break;
+                case '\'':
+                    transfered_str[i_out++] = '\'';
+                    break;
+                case '\"':
+                    transfered_str[i_out++] = '\"';
+                    break;
+                case '?':
+                    transfered_str[i_out++] = '\?';
+                    break;
+                default:
+                    transfered_str[i_out++] = str[i];
+                    break;
+            }
+            i += 1;
+            continue;
+        }
+        /* normal char */
+        transfered_str[i_out++] = str[i];
+    }
+    *iout_p = i_out;
+    return transfered_str;
+}

+ 1 - 0
src/dataStrs.h

@@ -52,6 +52,7 @@ char* strsPathGetFileName(Args* buffs_p, char* input);
 char* strsPathGetFolder(Args* buffs_p, char* input);
 char* strsPathJoin(Args* buffs_p, char* input1, char* input2);
 char* strsPathFormat(Args* buffs_p, char* input);
+char* strsTransfer(Args* buffs, char* str, size_t* iout_p);
 
 #endif
 #ifdef __cplusplus

+ 16 - 0
test/json-test.cpp

@@ -56,6 +56,22 @@ TEST(json, speed_diff) {
     EXPECT_EQ(pikaMemNow(), 0);
 }
 
+TEST(json, json_issue1) {
+    g_PikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    extern unsigned char pikaModules_py_a[];
+    obj_linkLibrary(pikaMain, pikaModules_py_a);
+    /* run */
+    __platform_printf("BEGIN\r\n");
+    pikaVM_runSingleFile(pikaMain, "test/python/json/json_issue1.py");
+    /* assert */
+    int act_time_s = obj_getInt(pikaMain, "act_time_s");
+    ASSERT_EQ(act_time_s, 300);
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
 #endif
 #endif
 

+ 10 - 0
test/python/json/json_issue1.py

@@ -0,0 +1,10 @@
+import json
+data = '{"code": 0,"path": "act_mode_config", "act_mode": [["ACTUATOR_NAME","ACTUATOR_ID","ACTUATOR_MODE_NAME","ACTUATOR_MODE_ID","ACT_MODE_TYPE","ACT_VALUE_TIME_s"],["电机1","actuator123","开闭循环1","mode2345","loop","{\\"AC_VALUE\\":1,\\"ACT_TIME_s\\":300}"],["电机1","actuator123","常开","mode2346","always","{\\"AC_VALUE\\":1,\\"ACT_TIME_s\\"}:0"]],"ext": "data"}'
+
+print(data)
+json_data = json.loads(data)
+ACT_VALUE_TIMS_S = json_data['act_mode'][1][5]
+print(ACT_VALUE_TIMS_S)
+act_value_tims_json = json.loads(ACT_VALUE_TIMS_S)
+print(act_value_tims_json['ACT_TIME_s'])
+act_time_s = act_value_tims_json['ACT_TIME_s']

+ 91 - 91
test/test_common.h

@@ -11,6 +11,7 @@
 #include "dataStrs.h"
 
 extern "C" {
+#include <stdio.h>
 #include "PikaMain.h"
 #include "PikaMath_Operator.h"
 #include "PikaStdLib_MemChecker.h"
@@ -18,109 +19,108 @@ extern "C" {
 #include "pikaScript.h"
 #include "pika_config_gtest.h"
 #include "pika_hal.h"
-#include <stdio.h>
-char *PikaStdData_Dict___str__(PikaObj *self);
-char *PikaStdData_List___str__(PikaObj *self);
+char* PikaStdData_Dict___str__(PikaObj* self);
+char* PikaStdData_List___str__(PikaObj* self);
 
 extern PikaMemInfo g_PikaMemInfo;
 /* the log_buff of printf */
 extern char log_buff[LOG_BUFF_MAX][LOG_SIZE];
 }
 
-#define TEST_RUN_SINGLE_FILE(_test_suite_, _test_name_, _file_name_)           \
-  TEST(_test_suite_, _test_name_) {                                            \
-    g_PikaMemInfo.heapUsedMax = 0;                                             \
-    PikaObj *pikaMain = newRootObj("pikaMain", New_PikaMain);                  \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(pikaMain, pikaModules_py_a);                               \
-    /* run */                                                                  \
-    __platform_printf("BEGIN\r\n");                                            \
-    pikaVM_runSingleFile(pikaMain, _file_name_);                               \
-    /* assert */                                                               \
-    /* deinit */                                                               \
-    obj_deinit(pikaMain);                                                      \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_SINGLE_FILE(_test_suite_, _test_name_, _file_name_) \
+    TEST(_test_suite_, _test_name_) {                                \
+        g_PikaMemInfo.heapUsedMax = 0;                               \
+        PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);    \
+        extern unsigned char pikaModules_py_a[];                     \
+        obj_linkLibrary(pikaMain, pikaModules_py_a);                 \
+        /* run */                                                    \
+        __platform_printf("BEGIN\r\n");                              \
+        pikaVM_runSingleFile(pikaMain, _file_name_);                 \
+        /* assert */                                                 \
+        /* deinit */                                                 \
+        obj_deinit(pikaMain);                                        \
+        EXPECT_EQ(pikaMemNow(), 0);                                  \
+    }
 
-#define TEST_RUN_SINGLE_FILE_PASS(_test_suite_, _test_name_, _file_name_)      \
-  TEST(_test_suite_, _test_name_) {                                            \
-    g_PikaMemInfo.heapUsedMax = 0;                                             \
-    PikaObj *pikaMain = newRootObj("pikaMain", New_PikaMain);                  \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(pikaMain, pikaModules_py_a);                               \
-    /* run */                                                                  \
-    __platform_printf("BEGIN\r\n");                                            \
-    pikaVM_runSingleFile(pikaMain, _file_name_);                               \
-    /* assert */                                                               \
-    EXPECT_STREQ(log_buff[0], "PASS\r\n");                                     \
-    EXPECT_STREQ(log_buff[1], "BEGIN\r\n");                                    \
-    /* deinit */                                                               \
-    obj_deinit(pikaMain);                                                      \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_SINGLE_FILE_PASS(_test_suite_, _test_name_, _file_name_) \
+    TEST(_test_suite_, _test_name_) {                                     \
+        g_PikaMemInfo.heapUsedMax = 0;                                    \
+        PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);         \
+        extern unsigned char pikaModules_py_a[];                          \
+        obj_linkLibrary(pikaMain, pikaModules_py_a);                      \
+        /* run */                                                         \
+        __platform_printf("BEGIN\r\n");                                   \
+        pikaVM_runSingleFile(pikaMain, _file_name_);                      \
+        /* assert */                                                      \
+        EXPECT_STREQ(log_buff[0], "PASS\r\n");                            \
+        EXPECT_STREQ(log_buff[1], "BEGIN\r\n");                           \
+        /* deinit */                                                      \
+        obj_deinit(pikaMain);                                             \
+        EXPECT_EQ(pikaMemNow(), 0);                                       \
+    }
 
-#define TEST_RUN_SINGLE_FILE_EXCEPT_OUTPUT(_test_suite_, _test_name_,          \
-                                           _file_name_, _except_output_)       \
-  TEST(_test_suite_, _test_name_) {                                            \
-    g_PikaMemInfo.heapUsedMax = 0;                                             \
-    PikaObj *pikaMain = newRootObj("pikaMain", New_PikaMain);                  \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(pikaMain, pikaModules_py_a);                               \
-    /* run */                                                                  \
-    __platform_printf("BEGIN\r\n");                                            \
-    pikaVM_runSingleFile(pikaMain, _file_name_);                               \
-    /* assert */                                                               \
-    EXPECT_STREQ(log_buff[0], (_except_output_));                              \
-    EXPECT_STREQ(log_buff[1], "BEGIN\r\n");                                    \
-    /* deinit */                                                               \
-    obj_deinit(pikaMain);                                                      \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_SINGLE_FILE_EXCEPT_OUTPUT(_test_suite_, _test_name_,    \
+                                           _file_name_, _except_output_) \
+    TEST(_test_suite_, _test_name_) {                                    \
+        g_PikaMemInfo.heapUsedMax = 0;                                   \
+        PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);        \
+        extern unsigned char pikaModules_py_a[];                         \
+        obj_linkLibrary(pikaMain, pikaModules_py_a);                     \
+        /* run */                                                        \
+        __platform_printf("BEGIN\r\n");                                  \
+        pikaVM_runSingleFile(pikaMain, _file_name_);                     \
+        /* assert */                                                     \
+        EXPECT_STREQ(log_buff[0], (_except_output_));                    \
+        EXPECT_STREQ(log_buff[1], "BEGIN\r\n");                          \
+        /* deinit */                                                     \
+        obj_deinit(pikaMain);                                            \
+        EXPECT_EQ(pikaMemNow(), 0);                                      \
+    }
 
-#define TEST_RUN_LINES(_test_suite_, _test_name_, _lines_)                     \
-  TEST(_test_suite_, _test_name_) {                                            \
-    PikaObj *self = newRootObj("root", New_PikaMain);                          \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(self, pikaModules_py_a);                                   \
-    obj_run(self, (_lines_)); /* collect */ /* assert */                       \
-    obj_deinit(self);                                                          \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_LINES(_test_suite_, _test_name_, _lines_)   \
+    TEST(_test_suite_, _test_name_) {                        \
+        PikaObj* self = newRootObj("root", New_PikaMain);    \
+        extern unsigned char pikaModules_py_a[];             \
+        obj_linkLibrary(self, pikaModules_py_a);             \
+        obj_run(self, (_lines_)); /* collect */ /* assert */ \
+        obj_deinit(self);                                    \
+        EXPECT_EQ(pikaMemNow(), 0);                          \
+    }
 
-#define TEST_RUN_LINES_NO_OUTPUT(_test_suite_, _test_name_, _lines_)           \
-  TEST(_test_suite_, _test_name_) {                                            \
-    PikaObj *self = newRootObj("root", New_PikaMain);                          \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(self, pikaModules_py_a);                                   \
-    pika_platform_printf("BEGIN\r\n");                                         \
-    obj_run(self, (_lines_)); /* collect */ /* assert */                       \
-    EXPECT_STREQ(log_buff[0], "BEGIN\r\n");                                    \
-    obj_deinit(self);                                                          \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_LINES_NO_OUTPUT(_test_suite_, _test_name_, _lines_) \
+    TEST(_test_suite_, _test_name_) {                                \
+        PikaObj* self = newRootObj("root", New_PikaMain);            \
+        extern unsigned char pikaModules_py_a[];                     \
+        obj_linkLibrary(self, pikaModules_py_a);                     \
+        pika_platform_printf("BEGIN\r\n");                           \
+        obj_run(self, (_lines_)); /* collect */ /* assert */         \
+        EXPECT_STREQ(log_buff[0], "BEGIN\r\n");                      \
+        obj_deinit(self);                                            \
+        EXPECT_EQ(pikaMemNow(), 0);                                  \
+    }
 
-#define TEST_RUN_LINES_PASS(_test_suite_, _test_name_, _lines_)                \
-  TEST(_test_suite_, _test_name_) {                                            \
-    PikaObj *self = newRootObj("root", New_PikaMain);                          \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(self, pikaModules_py_a);                                   \
-    obj_run(self, (_lines_)); /* collect */ /* assert */                       \
-    EXPECT_STREQ(log_buff[0], "PASS\r\n");                                     \
-    obj_deinit(self);                                                          \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_LINES_PASS(_test_suite_, _test_name_, _lines_) \
+    TEST(_test_suite_, _test_name_) {                           \
+        PikaObj* self = newRootObj("root", New_PikaMain);       \
+        extern unsigned char pikaModules_py_a[];                \
+        obj_linkLibrary(self, pikaModules_py_a);                \
+        obj_run(self, (_lines_)); /* collect */ /* assert */    \
+        EXPECT_STREQ(log_buff[0], "PASS\r\n");                  \
+        obj_deinit(self);                                       \
+        EXPECT_EQ(pikaMemNow(), 0);                             \
+    }
 
-#define TEST_RUN_LINES_EXCEPT_OUTPUT(_test_suite_, _test_name_, _lines_,       \
-                                     _except_output_)                          \
-  TEST(_test_suite_, _test_name_) {                                            \
-    PikaObj *self = newRootObj("root", New_PikaMain);                          \
-    extern unsigned char pikaModules_py_a[];                                   \
-    obj_linkLibrary(self, pikaModules_py_a);                                   \
-    obj_run(self, (_lines_)); /* collect */ /* assert */                       \
-    EXPECT_STREQ(log_buff[0], (_except_output_));                              \
-    obj_deinit(self);                                                          \
-    EXPECT_EQ(pikaMemNow(), 0);                                                \
-  }
+#define TEST_RUN_LINES_EXCEPT_OUTPUT(_test_suite_, _test_name_, _lines_, \
+                                     _except_output_)                    \
+    TEST(_test_suite_, _test_name_) {                                    \
+        PikaObj* self = newRootObj("root", New_PikaMain);                \
+        extern unsigned char pikaModules_py_a[];                         \
+        obj_linkLibrary(self, pikaModules_py_a);                         \
+        obj_run(self, (_lines_)); /* collect */ /* assert */             \
+        EXPECT_STREQ(log_buff[0], (_except_output_));                    \
+        obj_deinit(self);                                                \
+        EXPECT_EQ(pikaMemNow(), 0);                                      \
+    }
 
 #if USE_GOOGLE_TEST
 #include "gtest/gtest.h"