blueloveTH 3 лет назад
Родитель
Сommit
53b33eb2f2
2 измененных файлов с 30 добавлено и 4 удалено
  1. 2 4
      src/pocketpy.h
  2. 28 0
      src/str.h

+ 2 - 4
src/pocketpy.h

@@ -301,14 +301,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
 
     _vm->bindMethod("str", "__repr__", [](VM* vm, PyVarList args) {
         const _Str& _self = vm->PyStr_AS_C(args[0]);
-        // we just do a simple repr here, no escaping
-        return vm->PyStr("'" + _self.str() + "'");
+        return vm->PyStr("'" + _self.__escape(true).str() + "'");
     });
 
     _vm->bindMethod("str", "__json__", [](VM* vm, PyVarList args) {
         const _Str& _self = vm->PyStr_AS_C(args[0]);
-        // we just do a simple repr here, no escaping
-        return vm->PyStr('"' + _self.str() + '"');
+        return vm->PyStr("\"" + _self.__escape(false) + "\"");
     });
 
     _vm->bindMethod("str", "__eq__", [](VM* vm, PyVarList args) {

+ 28 - 0
src/str.h

@@ -135,6 +135,34 @@ public:
         }));
         return _Str(copy);
     }
+
+    _Str __escape(bool single_quote) const {
+        _StrStream ss;
+        for (auto c = _s.cbegin(); c != _s.cend(); c++) {
+            switch (*c) {
+                case '"':
+                    if(!single_quote) ss << '\\';
+                    ss << '"';
+                    break;
+                case '\'':
+                    if(single_quote) ss << '\\';
+                    ss << '\'';
+                    break;
+                case '\\': ss << '\\' << '\\'; break;
+                case '\n': ss << "\\n"; break;
+                case '\r': ss << "\\r"; break;
+                case '\t': ss << "\\t"; break;
+                default:
+                    if ('\x00' <= *c && *c <= '\x1f') {
+                        ss << "\\u"
+                        << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(*c);
+                    } else {
+                        ss << *c;
+                    }
+            }
+        }
+        return ss.str();
+    }
 };