From 47b3a24c29c91ede576168bec9d066238ad5808a Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Sat, 25 Jul 2009 00:02:31 +0000 Subject: [PATCH] Some more Py1k fixes, and added Py3k support --- bytecode.cpp | 39 +++++++++++++++++++++------------------ bytecode.h | 1 - object.cpp | 4 ++-- object.h | 1 - pycdas.cpp | 15 +++++++++++++++ string.cpp | 14 ++++++++++---- string.h | 10 ++++++++++ 7 files changed, 58 insertions(+), 26 deletions(-) diff --git a/bytecode.cpp b/bytecode.cpp index 6b32dea..df52e4a 100644 --- a/bytecode.cpp +++ b/bytecode.cpp @@ -171,11 +171,6 @@ bool Py1k::IsVarNameArg(int opcode) (opcode == Py1k::STORE_FAST); } -bool Py1k::IsCellArg(int opcode) -{ - return false; -} - bool Py2k::IsConstArg(int opcode) { return (opcode == Py2k::LOAD_CONST); @@ -231,7 +226,7 @@ bool Py3k::IsCellArg(int opcode) } -static void print_const(PycRef obj) +static void print_const(PycRef obj, PycModule* mod) { switch (obj->type()) { case PycObject::TYPE_STRING: @@ -241,16 +236,24 @@ static void print_const(PycRef obj) OutputString(obj.cast(), QS_Double); printf("\""); break; + case PycObject::TYPE_UNICODE: + if (mod->majorVer() == 3) + printf("\""); + else + printf("u\""); + OutputString(obj.cast(), QS_Double); + printf("\""); + break; case PycObject::TYPE_TUPLE: { printf("("); PycTuple::value_t values = obj.cast()->values(); PycTuple::value_t::iterator it = values.begin(); if (it != values.end()) { - print_const(*it); + print_const(*it, mod); while (++it != values.end()) { printf(", "); - print_const(*it); + print_const(*it, mod); } } printf(")"); @@ -262,10 +265,10 @@ static void print_const(PycRef obj) PycList::value_t values = obj.cast()->values(); PycList::value_t::iterator it = values.begin(); if (it != values.end()) { - print_const(*it); + print_const(*it, mod); while (++it != values.end()) { printf(", "); - print_const(*it); + print_const(*it, mod); } } printf("]"); @@ -279,15 +282,15 @@ static void print_const(PycRef obj) PycDict::key_t::iterator ki = keys.begin(); PycDict::value_t::iterator vi = values.begin(); if (ki != keys.end()) { - print_const(*ki); + print_const(*ki, mod); printf(": "); - print_const(*vi); + print_const(*vi, mod); while (++ki != keys.end()) { ++vi; printf(", "); - print_const(*ki); + print_const(*ki, mod); printf(": "); - print_const(*vi); + print_const(*vi, mod); } } printf("}"); @@ -353,8 +356,9 @@ void bc_disasm(PycRef code, PycModule* mod, int indent) (mod->majorVer() == 2 && Py2k::IsConstArg(opcode)) || (mod->majorVer() == 3 && Py3k::IsConstArg(opcode))) { printf("%d: ", operand); - print_const(code->getConst(operand)); + print_const(code->getConst(operand), mod); } else if ((mod->majorVer() == 1 && Py1k::IsNameArg(opcode)) || + (mod->majorVer() == 1 && mod->minorVer() < 4 && Py1k::IsVarNameArg(opcode)) || (mod->majorVer() == 2 && Py2k::IsNameArg(opcode)) || (mod->majorVer() == 3 && Py3k::IsNameArg(opcode))) { printf("%d: %s", operand, code->getName(operand)->value()); @@ -362,11 +366,10 @@ void bc_disasm(PycRef code, PycModule* mod, int indent) (mod->majorVer() == 2 && Py2k::IsVarNameArg(opcode)) || (mod->majorVer() == 3 && Py3k::IsVarNameArg(opcode))) { printf("%d: %s", operand, code->getVarName(operand)->value()); - } else if ((mod->majorVer() == 1 && Py1k::IsCellArg(opcode)) || - (mod->majorVer() == 2 && Py2k::IsCellArg(opcode)) || + } else if ((mod->majorVer() == 2 && Py2k::IsCellArg(opcode)) || (mod->majorVer() == 3 && Py3k::IsCellArg(opcode))) { printf("%d: ", operand); - print_const(code->getConst(operand)); + print_const(code->getConst(operand), mod); } else { printf("%d", operand); } diff --git a/bytecode.h b/bytecode.h index 43ac2d2..8319383 100644 --- a/bytecode.h +++ b/bytecode.h @@ -38,7 +38,6 @@ extern const char* OpcodeNames[256]; bool IsConstArg(int opcode); bool IsNameArg(int opcode); bool IsVarNameArg(int opcode); -bool IsCellArg(int opcode); } diff --git a/object.cpp b/object.cpp index 6e9627a..64b1734 100644 --- a/object.cpp +++ b/object.cpp @@ -57,8 +57,8 @@ PycRef CreateObject(int type) case PycObject::TYPE_CODE: case PycObject::TYPE_CODE2: return new PycCode(); - //case PycObject::TYPE_UNICODE: - // ... + case PycObject::TYPE_UNICODE: + return new PycUnicode(); //case PycObject::TYPE_SET: // ... //case PycObject::TYPE_FROZENSET: diff --git a/object.h b/object.h index b403758..d966ff4 100644 --- a/object.h +++ b/object.h @@ -1,7 +1,6 @@ #ifndef _PYC_OBJECT_H #define _PYC_OBJECT_H - template class PycRef { public: diff --git a/pycdas.cpp b/pycdas.cpp index 3d77c9b..3d0dbbc 100644 --- a/pycdas.cpp +++ b/pycdas.cpp @@ -74,6 +74,14 @@ void output_object(PycRef obj, PycModule* mod, int indent) OutputString(obj.cast(), QS_Double); printf("\"\n"); break; + case PycObject::TYPE_UNICODE: + if (mod->majorVer() == 3) + iprintf(indent, "\""); + else + iprintf(indent, "u\""); + OutputString(obj.cast(), QS_Double); + printf("\"\n"); + break; case PycObject::TYPE_TUPLE: { iprintf(indent, "(\n"); @@ -102,6 +110,7 @@ void output_object(PycRef obj, PycModule* mod, int indent) while (ki != keys.end()) { output_object(*ki, mod, indent + 1); output_object(*vi, mod, indent + 2); + ++ki, ++vi; } iprintf(indent, "}\n"); } @@ -109,6 +118,12 @@ void output_object(PycRef obj, PycModule* mod, int indent) case PycObject::TYPE_NONE: iprintf(indent, "None\n"); break; + case PycObject::TYPE_FALSE: + iprintf(indent, "False\n"); + break; + case PycObject::TYPE_TRUE: + iprintf(indent, "True\n"); + break; case PycObject::TYPE_INT: iprintf(indent, "%d\n", obj.cast()->value()); break; diff --git a/string.cpp b/string.cpp index f1a212a..351f14b 100644 --- a/string.cpp +++ b/string.cpp @@ -45,10 +45,11 @@ bool PycString::isEqual(PycRef obj) const void OutputString(PycRef str, QuoteStyle style, FILE* F) { const char* ch = str->value(); + int len = str->length(); if (ch == 0) return; - while (*ch != 0) { - if (*ch < 0x20) { + while (len--) { + if (*ch < 0x20 || *ch == 0x7F) { if (*ch == '\r') { fprintf(F, "\\r"); } else if (*ch == '\n') { @@ -61,8 +62,13 @@ void OutputString(PycRef str, QuoteStyle style, FILE* F) } else { fprintf(F, "\\x%x", *ch); } - } else if (*ch >= 0x7F) { - fprintf(F, "\\x%x", *ch); + } else if (*ch >= 0x80) { + if (str->type() == PycObject::TYPE_UNICODE) { + // Unicode stored as UTF-8... Let the stream interpret it + fputc(*ch, F); + } else { + fprintf(F, "\\x%x", *ch); + } } else { if (style == QS_Single && *ch == '\'') fprintf(F, "\\'"); diff --git a/string.h b/string.h index 9f9ee3a..3ee5297 100644 --- a/string.h +++ b/string.h @@ -33,6 +33,16 @@ private: int m_length; }; +class PycUnicode : public PycString { +public: + PycUnicode(int type = TYPE_UNICODE) : PycString(type) { } + + bool isType(int type) const + { + return (type == TYPE_UNICODE) || PycString::isType(type); + } +}; + void OutputString(PycRef str, QuoteStyle style, FILE* F = stdout); #endif