Skip to content

Commit d9c436d

Browse files
committed
Use C++ streams over C style IO
1 parent 72c5f87 commit d9c436d

File tree

10 files changed

+486
-460
lines changed

10 files changed

+486
-460
lines changed

ASTree.cpp

Lines changed: 263 additions & 263 deletions
Large diffs are not rendered by default.

ASTree.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#include "ASTNode.h"
55

66
PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod);
7-
void print_src(PycRef<ASTNode> node, PycModule* mod);
7+
void print_src(PycRef<ASTNode> node, PycModule* mod, std::ostream& pyc_output);
88

9-
void decompyle(PycRef<PycCode> code, PycModule* mod);
9+
void decompyle(PycRef<PycCode> code, PycModule* mod, std::ostream& pyc_output);
1010

1111
#endif

bytecode.cpp

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ bool Pyc::IsCompareArg(int opcode)
160160
return (opcode == Pyc::COMPARE_OP_A);
161161
}
162162

163-
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote)
163+
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote, std::ostream& pyc_output)
164164
{
165165
if (obj == NULL) {
166-
fputs("<NULL>", pyc_output);
166+
pyc_output << "<NULL>";
167167
return;
168168
}
169169

@@ -190,112 +190,112 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
190190
case PycObject::TYPE_TUPLE:
191191
case PycObject::TYPE_SMALL_TUPLE:
192192
{
193-
fputs("(", pyc_output);
193+
pyc_output << "(";
194194
PycTuple::value_t values = obj.cast<PycTuple>()->values();
195195
auto it = values.cbegin();
196196
if (it != values.cend()) {
197-
print_const(*it, mod);
197+
print_const(*it, mod, nullptr, pyc_output);
198198
while (++it != values.cend()) {
199-
fputs(", ", pyc_output);
200-
print_const(*it, mod);
199+
pyc_output << ", ";
200+
print_const(*it, mod, nullptr, pyc_output);
201201
}
202202
}
203203
if (values.size() == 1)
204-
fputs(",)", pyc_output);
204+
pyc_output << ",)";
205205
else
206-
fputs(")", pyc_output);
206+
pyc_output << ")";
207207
}
208208
break;
209209
case PycObject::TYPE_LIST:
210210
{
211-
fputs("[", pyc_output);
211+
pyc_output << "[";
212212
PycList::value_t values = obj.cast<PycList>()->values();
213213
auto it = values.cbegin();
214214
if (it != values.cend()) {
215-
print_const(*it, mod);
215+
print_const(*it, mod, nullptr, pyc_output);
216216
while (++it != values.cend()) {
217-
fputs(", ", pyc_output);
218-
print_const(*it, mod);
217+
pyc_output << ", ";
218+
print_const(*it, mod, nullptr, pyc_output);
219219
}
220220
}
221-
fputs("]", pyc_output);
221+
pyc_output << "]";
222222
}
223223
break;
224224
case PycObject::TYPE_DICT:
225225
{
226-
fputs("{", pyc_output);
226+
pyc_output << "{";
227227
PycDict::key_t keys = obj.cast<PycDict>()->keys();
228228
PycDict::value_t values = obj.cast<PycDict>()->values();
229229
auto ki = keys.cbegin();
230230
auto vi = values.cbegin();
231231
if (ki != keys.cend()) {
232-
print_const(*ki, mod);
233-
fputs(": ", pyc_output);
234-
print_const(*vi, mod);
232+
print_const(*ki, mod, nullptr, pyc_output);
233+
pyc_output << ": ";
234+
print_const(*vi, mod, nullptr, pyc_output);
235235
while (++ki != keys.cend()) {
236236
++vi;
237-
fputs(", ", pyc_output);
238-
print_const(*ki, mod);
239-
fputs(": ", pyc_output);
240-
print_const(*vi, mod);
237+
pyc_output << ", ";
238+
print_const(*ki, mod, nullptr, pyc_output);
239+
pyc_output << ": ";
240+
print_const(*vi, mod, nullptr, pyc_output);
241241
}
242242
}
243-
fputs("}", pyc_output);
243+
pyc_output << "}";
244244
}
245245
break;
246246
case PycObject::TYPE_SET:
247247
{
248-
fputs("{", pyc_output);
248+
pyc_output << "{";
249249
PycSet::value_t values = obj.cast<PycSet>()->values();
250250
auto it = values.cbegin();
251251
if (it != values.cend()) {
252-
print_const(*it, mod);
252+
print_const(*it, mod, nullptr, pyc_output);
253253
while (++it != values.cend()) {
254-
fputs(", ", pyc_output);
255-
print_const(*it, mod);
254+
pyc_output << ", ";
255+
print_const(*it, mod, nullptr, pyc_output);
256256
}
257257
}
258-
fputs("}", pyc_output);
258+
pyc_output << "}";
259259
}
260260
break;
261261
case PycObject::TYPE_FROZENSET:
262262
{
263-
fputs("frozenset({", pyc_output);
263+
pyc_output << "frozenset({";
264264
PycSet::value_t values = obj.cast<PycSet>()->values();
265265
auto it = values.cbegin();
266266
if (it != values.cend()) {
267-
print_const(*it, mod);
267+
print_const(*it, mod, nullptr, pyc_output);
268268
while (++it != values.cend()) {
269-
fputs(", ", pyc_output);
270-
print_const(*it, mod);
269+
pyc_output << ", ";
270+
print_const(*it, mod, nullptr, pyc_output);
271271
}
272272
}
273-
fputs("})", pyc_output);
273+
pyc_output << "})";
274274
}
275275
break;
276276
case PycObject::TYPE_NONE:
277-
fputs("None", pyc_output);
277+
pyc_output << "None";
278278
break;
279279
case PycObject::TYPE_TRUE:
280-
fputs("True", pyc_output);
280+
pyc_output << "True";
281281
break;
282282
case PycObject::TYPE_FALSE:
283-
fputs("False", pyc_output);
283+
pyc_output << "False";
284284
break;
285285
case PycObject::TYPE_ELLIPSIS:
286-
fputs("...", pyc_output);
286+
pyc_output << "...";
287287
break;
288288
case PycObject::TYPE_INT:
289-
fprintf(pyc_output, "%d", obj.cast<PycInt>()->value());
289+
formatted_print(pyc_output, "%d", obj.cast<PycInt>()->value());
290290
break;
291291
case PycObject::TYPE_LONG:
292-
fprintf(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
292+
formatted_print(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
293293
break;
294294
case PycObject::TYPE_FLOAT:
295-
fprintf(pyc_output, "%s", obj.cast<PycFloat>()->value());
295+
formatted_print(pyc_output, "%s", obj.cast<PycFloat>()->value());
296296
break;
297297
case PycObject::TYPE_COMPLEX:
298-
fprintf(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
298+
formatted_print(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
299299
obj.cast<PycComplex>()->imag());
300300
break;
301301
case PycObject::TYPE_BINARY_FLOAT:
@@ -305,31 +305,31 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
305305
bool is_negative = std::signbit(value);
306306
if (std::isnan(value)) {
307307
if (is_negative) {
308-
fprintf(pyc_output, "float('-nan')");
308+
pyc_output << "float('-nan')";
309309
} else {
310-
fprintf(pyc_output, "float('nan')");
310+
pyc_output << "float('nan')";
311311
}
312312
} else if (std::isinf(value)) {
313313
if (is_negative) {
314-
fprintf(pyc_output, "float('-inf')");
314+
pyc_output << "float('-inf')";
315315
} else {
316-
fprintf(pyc_output, "float('inf')");
316+
pyc_output << "float('inf')";
317317
}
318318
} else {
319-
fprintf(pyc_output, "%g", value);
319+
formatted_print(pyc_output, "%g", value);
320320
}
321321
}
322322
break;
323323
case PycObject::TYPE_BINARY_COMPLEX:
324-
fprintf(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
324+
formatted_print(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
325325
obj.cast<PycCComplex>()->imag());
326326
break;
327327
case PycObject::TYPE_CODE:
328328
case PycObject::TYPE_CODE2:
329-
fprintf(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
329+
formatted_print(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
330330
break;
331331
default:
332-
fprintf(pyc_output, "<TYPE: %d>\n", obj->type());
332+
formatted_print(pyc_output, "<TYPE: %d>\n", obj->type());
333333
}
334334
}
335335

@@ -363,7 +363,7 @@ void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int&
363363
}
364364
}
365365

366-
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
366+
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags, std::ostream &pyc_output)
367367
{
368368
static const char *cmp_strings[] = {
369369
"<", "<=", "==", "!=", ">", ">=", "in", "not in", "is", "is not",
@@ -388,78 +388,78 @@ void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
388388
continue;
389389

390390
for (int i=0; i<indent; i++)
391-
fputs(" ", pyc_output);
392-
fprintf(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));
391+
pyc_output << " ";
392+
formatted_print(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));
393393

394394
if (opcode >= Pyc::PYC_HAVE_ARG) {
395395
if (Pyc::IsConstArg(opcode)) {
396396
try {
397397
auto constParam = code->getConst(operand);
398-
fprintf(pyc_output, "%d: ", operand);
399-
print_const(constParam, mod);
398+
formatted_print(pyc_output, "%d: ", operand);
399+
print_const(constParam, mod, nullptr, pyc_output);
400400
} catch (const std::out_of_range &) {
401-
fprintf(pyc_output, "%d <INVALID>", operand);
401+
formatted_print(pyc_output, "%d <INVALID>", operand);
402402
}
403403
} else if (opcode == Pyc::LOAD_GLOBAL_A) {
404404
// Special case for Python 3.11+
405405
try {
406406
if (operand & 1)
407-
fprintf(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value());
407+
formatted_print(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value());
408408
else
409-
fprintf(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
409+
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
410410
} catch (const std::out_of_range &) {
411-
fprintf(pyc_output, "%d <INVALID>", operand);
411+
formatted_print(pyc_output, "%d <INVALID>", operand);
412412
}
413413
} else if (Pyc::IsNameArg(opcode)) {
414414
try {
415-
fprintf(pyc_output, "%d: %s", operand, code->getName(operand)->value());
415+
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand)->value());
416416
} catch (const std::out_of_range &) {
417-
fprintf(pyc_output, "%d <INVALID>", operand);
417+
formatted_print(pyc_output, "%d <INVALID>", operand);
418418
}
419419
} else if (Pyc::IsVarNameArg(opcode)) {
420420
try {
421-
fprintf(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
421+
formatted_print(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
422422
} catch (const std::out_of_range &) {
423-
fprintf(pyc_output, "%d <INVALID>", operand);
423+
formatted_print(pyc_output, "%d <INVALID>", operand);
424424
}
425425
} else if (Pyc::IsCellArg(opcode)) {
426426
try {
427-
fprintf(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
427+
formatted_print(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
428428
} catch (const std::out_of_range &) {
429-
fprintf(pyc_output, "%d <INVALID>", operand);
429+
formatted_print(pyc_output, "%d <INVALID>", operand);
430430
}
431431
} else if (Pyc::IsJumpOffsetArg(opcode)) {
432432
int offs = operand;
433433
if (mod->verCompare(3, 10) >= 0)
434434
offs *= sizeof(uint16_t); // BPO-27129
435-
fprintf(pyc_output, "%d (to %d)", operand, pos+offs);
435+
formatted_print(pyc_output, "%d (to %d)", operand, pos+offs);
436436
} else if (Pyc::IsJumpArg(opcode)) {
437437
if (mod->verCompare(3, 10) >= 0) // BPO-27129
438-
fprintf(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
438+
formatted_print(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
439439
else
440-
fprintf(pyc_output, "%d", operand);
440+
formatted_print(pyc_output, "%d", operand);
441441
} else if (Pyc::IsCompareArg(opcode)) {
442442
if (static_cast<size_t>(operand) < cmp_strings_len)
443-
fprintf(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
443+
formatted_print(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
444444
else
445-
fprintf(pyc_output, "%d (UNKNOWN)", operand);
445+
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
446446
} else if (opcode == Pyc::BINARY_OP_A) {
447447
if (static_cast<size_t>(operand) < binop_strings_len)
448-
fprintf(pyc_output, "%d (%s)", operand, binop_strings[operand]);
448+
formatted_print(pyc_output, "%d (%s)", operand, binop_strings[operand]);
449449
else
450-
fprintf(pyc_output, "%d (UNKNOWN)", operand);
450+
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
451451
} else if (opcode == Pyc::IS_OP_A) {
452-
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
452+
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
453453
: (operand == 1) ? "is not"
454454
: "UNKNOWN");
455455
} else if (opcode == Pyc::CONTAINS_OP_A) {
456-
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
456+
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
457457
: (operand == 1) ? "not in"
458458
: "UNKNOWN");
459459
} else {
460-
fprintf(pyc_output, "%d", operand);
460+
formatted_print(pyc_output, "%d", operand);
461461
}
462462
}
463-
fputs("\n", pyc_output);
463+
pyc_output << "\n";
464464
}
465465
}

bytecode.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ bool IsCompareArg(int opcode);
3535

3636
}
3737

38-
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote = nullptr);
38+
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote, std::ostream& pyc_output);
3939
void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int& pos);
40-
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags);
40+
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags, std::ostream& pyc_output);

data.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include "data.h"
22
#include <cstring>
3-
4-
FILE* pyc_output = stdout;
3+
#include <cstdarg>
4+
#include <ostream>
5+
#include <vector>
56

67
/* PycData */
78
int PycData::get16()
@@ -82,3 +83,18 @@ int PycBuffer::getBuffer(int bytes, void* buffer)
8283
memcpy(buffer, (m_buffer + m_pos), bytes);
8384
return bytes;
8485
}
86+
87+
88+
89+
int formatted_print(std::ostream& stream, const char* format, ...) {
90+
va_list args;
91+
va_start(args, format);
92+
size_t len = std::vsnprintf(NULL, 0, format, args);
93+
va_end(args);
94+
std::vector<char> vec(len + 1);
95+
va_start(args, format);
96+
std::vsnprintf(&vec[0], len + 1, format, args);
97+
va_end(args);
98+
stream << &vec[0];
99+
return 0;
100+
}

data.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define _PYC_FILE_H
33

44
#include <cstdio>
5+
#include <ostream>
56

67
#ifdef WIN32
78
typedef __int64 Pyc_INT64;
@@ -56,6 +57,6 @@ class PycBuffer : public PycData {
5657
int m_size, m_pos;
5758
};
5859

59-
extern FILE* pyc_output;
60+
int formatted_print(std::ostream& stream, const char* fmt, ...);
6061

6162
#endif

0 commit comments

Comments
 (0)