Use C++ streams over C style IO

This commit is contained in:
Perceval Wajsbürt
2023-06-02 00:36:58 +02:00
committed by Perceval Wajsbürt
parent 409f175827
commit c4c35fc531
10 changed files with 488 additions and 460 deletions

View File

@@ -160,10 +160,10 @@ bool Pyc::IsCompareArg(int opcode)
return (opcode == Pyc::COMPARE_OP_A);
}
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote)
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote, std::ostream& pyc_output)
{
if (obj == NULL) {
fputs("<NULL>", pyc_output);
pyc_output << "<NULL>";
return;
}
@@ -190,112 +190,112 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
case PycObject::TYPE_TUPLE:
case PycObject::TYPE_SMALL_TUPLE:
{
fputs("(", pyc_output);
pyc_output << "(";
PycTuple::value_t values = obj.cast<PycTuple>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
if (values.size() == 1)
fputs(",)", pyc_output);
pyc_output << ",)";
else
fputs(")", pyc_output);
pyc_output << ")";
}
break;
case PycObject::TYPE_LIST:
{
fputs("[", pyc_output);
pyc_output << "[";
PycList::value_t values = obj.cast<PycList>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("]", pyc_output);
pyc_output << "]";
}
break;
case PycObject::TYPE_DICT:
{
fputs("{", pyc_output);
pyc_output << "{";
PycDict::key_t keys = obj.cast<PycDict>()->keys();
PycDict::value_t values = obj.cast<PycDict>()->values();
auto ki = keys.cbegin();
auto vi = values.cbegin();
if (ki != keys.cend()) {
print_const(*ki, mod);
fputs(": ", pyc_output);
print_const(*vi, mod);
print_const(*ki, mod, nullptr, pyc_output);
pyc_output << ": ";
print_const(*vi, mod, nullptr, pyc_output);
while (++ki != keys.cend()) {
++vi;
fputs(", ", pyc_output);
print_const(*ki, mod);
fputs(": ", pyc_output);
print_const(*vi, mod);
pyc_output << ", ";
print_const(*ki, mod, nullptr, pyc_output);
pyc_output << ": ";
print_const(*vi, mod, nullptr, pyc_output);
}
}
fputs("}", pyc_output);
pyc_output << "}";
}
break;
case PycObject::TYPE_SET:
{
fputs("{", pyc_output);
pyc_output << "{";
PycSet::value_t values = obj.cast<PycSet>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("}", pyc_output);
pyc_output << "}";
}
break;
case PycObject::TYPE_FROZENSET:
{
fputs("frozenset({", pyc_output);
pyc_output << "frozenset({";
PycSet::value_t values = obj.cast<PycSet>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("})", pyc_output);
pyc_output << "})";
}
break;
case PycObject::TYPE_NONE:
fputs("None", pyc_output);
pyc_output << "None";
break;
case PycObject::TYPE_TRUE:
fputs("True", pyc_output);
pyc_output << "True";
break;
case PycObject::TYPE_FALSE:
fputs("False", pyc_output);
pyc_output << "False";
break;
case PycObject::TYPE_ELLIPSIS:
fputs("...", pyc_output);
pyc_output << "...";
break;
case PycObject::TYPE_INT:
fprintf(pyc_output, "%d", obj.cast<PycInt>()->value());
formatted_print(pyc_output, "%d", obj.cast<PycInt>()->value());
break;
case PycObject::TYPE_LONG:
fprintf(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
formatted_print(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
break;
case PycObject::TYPE_FLOAT:
fprintf(pyc_output, "%s", obj.cast<PycFloat>()->value());
formatted_print(pyc_output, "%s", obj.cast<PycFloat>()->value());
break;
case PycObject::TYPE_COMPLEX:
fprintf(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
formatted_print(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
obj.cast<PycComplex>()->imag());
break;
case PycObject::TYPE_BINARY_FLOAT:
@@ -305,31 +305,31 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
bool is_negative = std::signbit(value);
if (std::isnan(value)) {
if (is_negative) {
fprintf(pyc_output, "float('-nan')");
pyc_output << "float('-nan')";
} else {
fprintf(pyc_output, "float('nan')");
pyc_output << "float('nan')";
}
} else if (std::isinf(value)) {
if (is_negative) {
fprintf(pyc_output, "float('-inf')");
pyc_output << "float('-inf')";
} else {
fprintf(pyc_output, "float('inf')");
pyc_output << "float('inf')";
}
} else {
fprintf(pyc_output, "%g", value);
formatted_print(pyc_output, "%g", value);
}
}
break;
case PycObject::TYPE_BINARY_COMPLEX:
fprintf(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
formatted_print(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
obj.cast<PycCComplex>()->imag());
break;
case PycObject::TYPE_CODE:
case PycObject::TYPE_CODE2:
fprintf(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
formatted_print(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
break;
default:
fprintf(pyc_output, "<TYPE: %d>\n", obj->type());
formatted_print(pyc_output, "<TYPE: %d>\n", obj->type());
}
}
@@ -363,7 +363,7 @@ void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int&
}
}
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags, std::ostream &pyc_output)
{
static const char *cmp_strings[] = {
"<", "<=", "==", "!=", ">", ">=", "in", "not in", "is", "is not",
@@ -388,78 +388,78 @@ void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
continue;
for (int i=0; i<indent; i++)
fputs(" ", pyc_output);
fprintf(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));
pyc_output << " ";
formatted_print(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));
if (opcode >= Pyc::PYC_HAVE_ARG) {
if (Pyc::IsConstArg(opcode)) {
try {
auto constParam = code->getConst(operand);
fprintf(pyc_output, "%d: ", operand);
print_const(constParam, mod);
formatted_print(pyc_output, "%d: ", operand);
print_const(constParam, mod, nullptr, pyc_output);
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (opcode == Pyc::LOAD_GLOBAL_A) {
// Special case for Python 3.11+
try {
if (operand & 1)
fprintf(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value());
formatted_print(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value());
else
fprintf(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsNameArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getName(operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsVarNameArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsCellArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsJumpOffsetArg(opcode)) {
int offs = operand;
if (mod->verCompare(3, 10) >= 0)
offs *= sizeof(uint16_t); // BPO-27129
fprintf(pyc_output, "%d (to %d)", operand, pos+offs);
formatted_print(pyc_output, "%d (to %d)", operand, pos+offs);
} else if (Pyc::IsJumpArg(opcode)) {
if (mod->verCompare(3, 10) >= 0) // BPO-27129
fprintf(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
formatted_print(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
else
fprintf(pyc_output, "%d", operand);
formatted_print(pyc_output, "%d", operand);
} else if (Pyc::IsCompareArg(opcode)) {
if (static_cast<size_t>(operand) < cmp_strings_len)
fprintf(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
formatted_print(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
else
fprintf(pyc_output, "%d (UNKNOWN)", operand);
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
} else if (opcode == Pyc::BINARY_OP_A) {
if (static_cast<size_t>(operand) < binop_strings_len)
fprintf(pyc_output, "%d (%s)", operand, binop_strings[operand]);
formatted_print(pyc_output, "%d (%s)", operand, binop_strings[operand]);
else
fprintf(pyc_output, "%d (UNKNOWN)", operand);
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
} else if (opcode == Pyc::IS_OP_A) {
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
: (operand == 1) ? "is not"
: "UNKNOWN");
} else if (opcode == Pyc::CONTAINS_OP_A) {
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
: (operand == 1) ? "not in"
: "UNKNOWN");
} else {
fprintf(pyc_output, "%d", operand);
formatted_print(pyc_output, "%d", operand);
}
}
fputs("\n", pyc_output);
pyc_output << "\n";
}
}