ProcessResults processFile(fs::path file, Params& params) { ProcessResults result; Pex::Binary pex; try { Pex::FileReader reader(file.string()); reader.read(pex); } catch(std::exception& ex) { result.push_back(boost::str(boost::format("ERROR: %1% : %2%") % file.string() % ex.what())); return result; } if (params.outputAssembly) { fs::path asmFile = params.assemblyDir / file.filename().replace_extension(".pas"); try { std::ofstream asmStream(asmFile.string()); Decompiler::AsmCoder asmCoder(new Decompiler::StreamWriter(asmStream)); asmCoder.code(pex); result.push_back(boost::str(boost::format("%1% dissassembled to %2%") % file.string() % asmFile.string())); } catch(std::exception& ex) { result.push_back(boost::str(boost::format("ERROR: %1% : %2%") % file.string() % ex.what())); fs::remove(asmFile); } } fs::path pscFile = params.papyrusDir / file.filename().replace_extension(".psc"); try { std::ofstream pscStream(pscFile.string()); Decompiler::PscCoder pscCoder(new Decompiler::StreamWriter(pscStream)); pscCoder.outputAsmComment(params.outputComment).code(pex); result.push_back(boost::str(boost::format("%1% decompiled to %2%") % file.string() % pscFile.string())); } catch(std::exception& ex) { result.push_back(boost::str(boost::format("ERROR: %1% : %2%") % file.string() % ex.what())); fs::remove(pscFile); } return result; }
void paraFlow(char *fileName, int pfArgc, char **pfArgv) /* parse and dump. */ { struct pfCompile *pfc; struct pfParse *program, *module; char baseDir[256], baseName[128], baseSuffix[64]; char defFile[PATH_LEN]; char *parseFile = "out.parse"; char *typeFile = "out.typed"; char *boundFile = "out.bound"; char *scopeFile = "out.scope"; char *foldedFile = "out.folded"; char *cFile = "out.c"; FILE *parseF = mustOpen(parseFile, "w"); FILE *typeF = mustOpen(typeFile, "w"); FILE *scopeF = mustOpen(scopeFile, "w"); FILE *boundF = mustOpen(boundFile, "w"); FILE *foldedF = mustOpen(foldedFile, "w"); if (endPhase < 0) return; verbose(2, "Phase 0 - initialization\n"); pfc = pfCompileNew(); getPaths(pfc); splitPath(fileName, baseDir, baseName, baseSuffix); pfc->baseDir = cloneString(baseDir); safef(defFile, sizeof(defFile), "%s%s.pfh", baseDir, baseName); if (endPhase < 1) return ; verbose(2, "Phase 1 - tokenizing\n"); pfTokenizeInto(pfc, baseDir, baseName); if (endPhase < 2) return; verbose(2, "Phase 2 - parsing\n"); program = pfParseInto(pfc); dumpParseTree(pfc, program, parseF); carefulClose(&parseF); if (endPhase < 3) return; verbose(2, "Phase 3 - binding names\n"); pfBindVars(pfc, program); dumpParseTree(pfc, program, boundF); carefulClose(&boundF); if (endPhase < 4) return; verbose(2, "Phase 4 - type checking\n"); pfTypeCheck(pfc, &program); dumpParseTree(pfc, program, typeF); carefulClose(&typeF); if (endPhase < 5) return; verbose(2, "Phase 5 - polymorphic, para, and flow checks\n"); checkPolymorphic(pfc, pfc->scopeRefList); checkParaFlow(pfc, program); printScopeInfo(scopeF, 0, program); carefulClose(&scopeF); if (endPhase < 6) return; verbose(2, "Phase 6 - constant folding\n"); pfConstFold(pfc, program); dumpParseTree(pfc, program, foldedF); if (optionExists("asm")) { struct dyString *gccFiles; if (endPhase < 7) return; verbose(2, "Phase 7 - nothing\n"); if (endPhase < 8) return; verbose(2, "Phase 8 - Code generation\n"); pfc->backEnd = backEndFind("mac-pentium"); gccFiles = asmCoder(pfc, program, baseDir, baseName); if (endPhase < 9) return; verbose(2, "Phase 9 - Assembling pentium code\n"); { char *libName = hashMustFindVal(pfc->cfgHash,"runAsmLib"); struct dyString *dy = dyStringNew(0); int err; dyStringPrintf(dy, "gcc "); dyStringPrintf(dy, "-I %s ", pfc->cIncludeDir); dyStringPrintf(dy, "-o %s%s ", baseDir, baseName); dyStringAppend(dy, gccFiles->string); dyStringPrintf(dy, "%s ", libName); dyStringPrintf(dy, " %s ", pfc->runtimeLib); dyStringPrintf(dy, "%s ", pfc->jkwebLib); verbose(2, "%s\n", dy->string); err = system(dy->string); if (err != 0) errAbort("Couldn't assemble: %s", dy->string); dyStringFree(&dy); } dyStringFree(&gccFiles); } else { verbose(2, "Phase 7 - nothing\n"); if (endPhase < 8) return; verbose(2, "Phase 8 - C code generation\n"); pfCodeC(pfc, program, baseDir, cFile); verbose(2, "%d modules, %d tokens, %d parseNodes\n", pfc->moduleHash->elCount, pfc->tkz->tokenCount, pfParseCount(program)); if (endPhase < 9) return; verbose(2, "Phase 9 - compiling C code\n"); /* Now run gcc on it. */ { struct dyString *dy = dyStringNew(0); int err; for (module = program->children; module != NULL; module = module->next) { if (module->name[0] != '<' && module->type != pptModuleRef) { struct pfModule *mod = hashMustFindVal(pfc->moduleHash, module->name); char *cName = replaceSuffix(mod->fileName, ".pf", ".c"); char *oName = replaceSuffix(mod->fileName, ".pf", ".o"); dyStringClear(dy); dyStringAppend(dy, "gcc "); dyStringAppend(dy, "-O "); dyStringPrintf(dy, "-I %s ", pfc->cIncludeDir); dyStringAppend(dy, "-c "); dyStringAppend(dy, "-o "); dyStringPrintf(dy, "%s ", oName); dyStringPrintf(dy, "%s ", cName); verbose(2, "%s\n", dy->string); err = system(dy->string); if (err != 0) errAbort("Couldn't compile %s.c", module->name); freeMem(oName); freeMem(cName); } } dyStringClear(dy); dyStringAppend(dy, "gcc "); dyStringAppend(dy, "-O "); dyStringPrintf(dy, "-I %s ", pfc->cIncludeDir); dyStringPrintf(dy, "-o %s%s ", baseDir, baseName); dyStringPrintf(dy, "%s ", cFile); for (module = program->children; module != NULL; module = module->next) { if (module->name[0] != '<') { struct pfModule *mod = hashMustFindVal(pfc->moduleHash, module->name); char *suffix = (module->type == pptModuleRef ? ".pfh" : ".pf"); char *oName = replaceSuffix(mod->fileName, suffix, ".o"); dyStringPrintf(dy, "%s ", oName); freeMem(oName); } } dyStringPrintf(dy, " %s ", pfc->runtimeLib); dyStringPrintf(dy, "%s ", pfc->jkwebLib); dyStringAppend(dy, "-lpthread -lm"); verbose(2, "%s\n", dy->string); err = system(dy->string); if (err != 0) errnoAbort("problem compiling:\n", dy->string); dyStringFree(&dy); } } if (endPhase < 10) return; verbose(2, "Phase 10 - execution\n"); /* Now go run program itself. */ { struct dyString *dy = dyStringNew(0); int err; int i; if (baseDir[0] == 0) dyStringPrintf(dy, "./%s", baseName); else dyStringPrintf(dy, "%s%s", baseDir, baseName); for (i=0; i<pfArgc; ++i) { dyStringAppendC(dy, ' '); dyStringAppend(dy, pfArgv[i]); } err = system(dy->string); if (err != 0) errAbort("problem running %s", baseName); dyStringFree(&dy); } }