Skip to content

Commit

Permalink
Merge pull request #27 from nikitalita/print-debug-line-numbers
Browse files Browse the repository at this point in the history
Print debug line numbers, print-info, print-compile-time
  • Loading branch information
Orvid authored Sep 30, 2023
2 parents d2a5345 + 5853ec1 commit 1a735b9
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 53 deletions.
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
cmake_policy(SET CMP0048 NEW) # VERSION variables
cmake_policy(SET CMP0091 NEW) # CMAKE_MSVC_RUNTIME_LIBRARY

# Get the version number from Decompiler/Version.hpp
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/Decompiler/Version.hpp" CHAMPOLLION_VERSION_FILE)
string(REGEX MATCH "define CHAMPOLLION_VERSION_MAJOR ([0-9]*)" _ ${CHAMPOLLION_VERSION_FILE})
math(EXPR CHAMPOLLION_VERSION_MAJOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "define CHAMPOLLION_VERSION_MINOR ([0-9]*)" _ ${CHAMPOLLION_VERSION_FILE})
math(EXPR CHAMPOLLION_VERSION_MINOR "${CMAKE_MATCH_1}")
string(REGEX MATCH "define CHAMPOLLION_VERSION_PATCH ([0-9]*)" _ ${CHAMPOLLION_VERSION_FILE})
math(EXPR CHAMPOLLION_VERSION_PATCH "${CMAKE_MATCH_1}")
#Get the Champollion version as a semver number literal, not as a string
set(CHAMPOLLION_VERSION ${CHAMPOLLION_VERSION_MAJOR}.${CHAMPOLLION_VERSION_MINOR}.${CHAMPOLLION_VERSION_PATCH})

message(STATUS "Champollion version: ${CHAMPOLLION_VERSION}")

# package information
set(PACKAGE_NAME "Champollion")
set(PACKAGE_VERSION "1.1.3")
set(PACKAGE_VERSION "${CHAMPOLLION_VERSION}")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/Orvid/champollion/issues")
Expand All @@ -13,7 +27,7 @@ if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
CACHE STRING "")
endif()

project(${PACKAGE_NAME} VERSION 1.1.3 LANGUAGES CXX)
project(${PACKAGE_NAME} VERSION ${PACKAGE_VERSION} LANGUAGES CXX)
include(GNUInstallDirs)


Expand Down
130 changes: 89 additions & 41 deletions Champollion/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace fs = std::filesystem;

#include <chrono>
#include <future>
#include <ctime>

#include "Pex/Binary.hpp"
#include "Pex/FileReader.hpp"
Expand All @@ -18,6 +19,7 @@ namespace fs = std::filesystem;
#include "Decompiler/PscCoder.hpp"

#include "Decompiler/StreamWriter.hpp"
#include "Decompiler/Version.hpp"
#include "glob.hpp"

struct Params
Expand All @@ -32,6 +34,9 @@ struct Params
bool decompileDebugFuncs;
bool recursive;
bool verbose;
bool printInfo;
bool printCompileTime;
bool debugLineComment;

fs::path assemblyDir;
fs::path papyrusDir;
Expand All @@ -58,10 +63,14 @@ OptionsResult getProgramOptions(int argc, char* argv[], Params& params)
params.recreateDirStructure = false;
params.decompileDebugFuncs = false;
params.verbose = false;
params.printInfo = false;
params.printCompileTime = false;
params.debugLineComment = true;

params.assemblyDir = fs::current_path();
params.papyrusDir = fs::current_path();

std::string version_string = "Champollion PEX decompiler v1.3.1";
std::string version_string = "Champollion PEX decompiler " + std::string(CHAMPOLLION_VERSION_STRING);
options::options_description desc(version_string);
desc.add_options()
("help,h", "Display the help message")
Expand All @@ -75,8 +84,11 @@ OptionsResult getProgramOptions(int argc, char* argv[], Params& params)
("trace,g", "Trace the decompilation and output results to rebuild log")
("no-dump-tree", "Do not dump tree for each node during decompilation tracing (requires --trace)")
("debug-funcs,d", "Decompile debug and compiler-generated functions (default false)")
("no-debug-line", "Do not comment with debug info line numbers on script lines (default false)")
("print-info,i", "Print header info from the specified PEX file(s) and exit")
("print-compile-time", "Print the compile time of the script in format of {filename}: {time_integer} and exit")
("verbose,v", "Verbose output")
("version", "Output version number")
("version,V", "Output version number")
;
options::options_description files;
files.add_options()
Expand Down Expand Up @@ -120,47 +132,41 @@ OptionsResult getProgramOptions(int argc, char* argv[], Params& params)
params.recursive = (args.count("recursive") != 0);
params.recreateDirStructure = (args.count("recreate-subdirs") != 0);
params.decompileDebugFuncs = (args.count("debug-funcs") != 0);
params.printInfo = (args.count("print-info") != 0);
params.printCompileTime = (args.count("print-compile-time") != 0);
params.debugLineComment = !(args.count("no-debug-line") != 0);
params.verbose = (args.count("verbose") != 0);
try
{
if (args.count("asm"))
{
params.outputAssembly = true;
auto dir = args["asm"].as<std::string>();
if (! dir.empty())
{
params.assemblyDir = fs::path(dir);
if (!fs::exists(params.assemblyDir))
{
fs::create_directories(params.assemblyDir);
}
else if (!fs::is_directory(params.assemblyDir))
{
std::cout << params.assemblyDir << " is not a directory" << std::endl;
return Invalid;
}
if (!params.printInfo) {
try {
if (args.count("asm")) {
params.outputAssembly = true;
auto dir = args["asm"].as<std::string>();
if (!dir.empty()) {
params.assemblyDir = fs::path(dir);
if (!fs::exists(params.assemblyDir)) {
fs::create_directories(params.assemblyDir);
} else if (!fs::is_directory(params.assemblyDir)) {
std::cout << params.assemblyDir << " is not a directory" << std::endl;
return Invalid;
}
}
}
if (args.count("psc"))
{
auto dir = args["psc"].as<std::string>();

params.papyrusDir = fs::path(dir);
if (!fs::exists(params.papyrusDir))
{
fs::create_directories(params.papyrusDir);
}
else if (!fs::is_directory(params.papyrusDir))
{
std::cout << params.papyrusDir << " is not a directory" << std::endl;
return Invalid;
}
if (args.count("psc")) {
auto dir = args["psc"].as<std::string>();

params.papyrusDir = fs::path(dir);
if (!fs::exists(params.papyrusDir)) {
fs::create_directories(params.papyrusDir);
} else if (!fs::is_directory(params.papyrusDir)) {
std::cout << params.papyrusDir << " is not a directory" << std::endl;
return Invalid;
}
}
}
catch(const std::exception& ex)
{
}
catch (const std::exception &ex) {
std::cout << ex.what();
return Invalid;
}
}

if(args.count("input"))
Expand Down Expand Up @@ -212,6 +218,48 @@ ProcessResults processFile(fs::path file, Params params)
return result;
}
pex.getGameType() == Pex::Binary::StarfieldScript ? result.isStarfield = true : result.isStarfield = false;
if (params.printInfo)
{
std::string gameType;
switch(pex.getGameType())
{
case Pex::Binary::SkyrimScript:
gameType = "Skyrim";
break;
case Pex::Binary::Fallout4Script:
gameType = "Fallout 4";
break;
case Pex::Binary::StarfieldScript:
gameType = "Starfield";
break;
default:
gameType = "Unknown";
break;
}

result.output.push_back(std::format("Script: {}", file.string() ));
// print out all the info contained in the header and exit
result.output.push_back(std::format(" Game: {}", gameType));
auto header = pex.getHeader();
result.output.push_back(std::format(" Game Version: {}.{}", header.getMajorVersion(), header.getMinorVersion()));
result.output.push_back(std::format(" GameID: {}", header.getGameID()));
auto time = header.getCompilationTime();
std::string hrtime = ctime(&time);
// trim trailing line break
hrtime.erase(hrtime.find_last_not_of("\n") + 1);
result.output.push_back(std::format(" Compilation Time: {} ({}) ", time, hrtime));
result.output.push_back(std::format(" Source File: {}", header.getSourceFileName()));
result.output.push_back(std::format(" User Name: {}", header.getUserName()));
result.output.push_back(std::format(" Computer Name: {}\n", header.getComputerName()));
return result;
}
if (params.printCompileTime)
{
auto header = pex.getHeader();
auto time = header.getCompilationTime();
result.output.push_back(std::format("{}: {}", file.string(), time));
return result;
}
if (params.outputAssembly)
{
fs::path asmFile = params.assemblyDir / file.filename().replace_extension(".pas");
Expand Down Expand Up @@ -257,7 +305,7 @@ ProcessResults processFile(fs::path file, Params params)
params.traceDecompilation,
params.dumpTree,
params.decompileDebugFuncs,
true,
params.debugLineComment,
params.papyrusDir.string()); // using string instead of path here for C++14 compatability for staticlib targets

pscCoder.code(pex);
Expand Down Expand Up @@ -288,7 +336,7 @@ void processResult(const ProcessResults &result, const Params& params)
{
std::cerr << line << '\n';
}
} else if (params.verbose) { // only output each individual successful result if `verbose` is on
} else if (params.verbose || params.printInfo || params.printCompileTime) { // only output each individual successful result if `verbose` is on
for (auto line : result.output)
{
std::cout << line << '\n';
Expand All @@ -305,7 +353,8 @@ int main(int argc, char* argv[])
if (result == Good)
{
auto start = std::chrono::steady_clock::now();
if(!args.parallel)
// ignore parallel if we are printing info
if(!args.parallel || args.printInfo || args.printCompileTime)
{
for (auto path : args.inputs)
{
Expand Down Expand Up @@ -378,7 +427,6 @@ int main(int argc, char* argv[])
{
auto pResult = result.get();
processResult(pResult, args);

}
countFiles = results.size();

Expand Down
18 changes: 10 additions & 8 deletions Decompiler/PscCoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <regex>

#include "PscDecompiler.hpp"

#include "Version.hpp"
#include "EventNames.hpp"

/**
Expand Down Expand Up @@ -139,7 +139,7 @@ void Decompiler::PscCoder::writeHeader(const Pex::Binary &pex)
{
auto& header = pex.getHeader();
auto& debug = pex.getDebugInfo();
write(";/ Decompiled by Champollion V1.1.3"); // TODO: Make this get the version number dynamically
write(";/ Decompiled by Champollion " + std::string(CHAMPOLLION_VERSION_STRING));
write(indent(0) << "PEX format v" << (int)header.getMajorVersion() << "." << (int)header.getMinorVersion() << " GameID: " << header.getGameID());
write(indent(0) << "Source : " << header.getSourceFileName());
if (debug.getModificationTime() != 0)
Expand Down Expand Up @@ -673,15 +673,17 @@ void Decompiler::PscCoder::writeFunction(int i, const Pex::Function &function, c
for (auto &line: decomp) {
auto & linemap = decomp.getLineMap();
if (m_PrintDebugLineNo){
line += " ; #DEBUG_LINE_NO:";
// get index of line
auto result = linemap[index];
for (auto i = 0; i < result.size(); ++i)
{
if (i > 0){
line += ",";
if (result.size() > 0){
line += " ; #DEBUG_LINE_NO:";
for (auto i = 0; i < result.size(); ++i)
{
if (i > 0){
line += ",";
}
line += std::to_string(result[i]);
}
line += std::to_string(result[i]);
}
}
write(indent(i+1) << line);
Expand Down
3 changes: 2 additions & 1 deletion Decompiler/PscDecompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,8 @@ void Decompiler::PscDecompiler::rebuildBooleanOperators(size_t startBlock, size_
{
if (*sourceLines.rbegin() != *nextLines.begin()){
if (*nextLines.begin() - *sourceLines.rbegin() == 1) {
// check if the next statement is an assign; if not, then this is probably not a boolean
// if the possible boolean is on the next line,
// check if the next statement is an assign; if so, then this is probably not a boolean
if (nextNode->is<Node::Assign>()){
maybeAnd = false;
maybeOr = false;
Expand Down
10 changes: 10 additions & 0 deletions Decompiler/Version.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#define CHAMPOLLION_VERSION_MAJOR 1
#define CHAMPOLLION_VERSION_MINOR 3
#define CHAMPOLLION_VERSION_PATCH 2

#define MAKE_STR_HELPER(a_str) #a_str
#define MAKE_STR(a_str) MAKE_STR_HELPER(a_str)

#define CHAMPOLLION_VERSION_STRING "v" MAKE_STR(CHAMPOLLION_VERSION_MAJOR) "." MAKE_STR(CHAMPOLLION_VERSION_MINOR) "." MAKE_STR(CHAMPOLLION_VERSION_PATCH)
2 changes: 1 addition & 1 deletion vcpkg.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/master/docs/vcpkg.schema.json",
"name": "champollion",
"version-semver": "1.1.3",
"version-semver": "1.3.2",
"port-version": 0,
"description": "Papyrus Script Decompiler.",
"homepage": "https://github.com/Orvid/Champollion",
Expand Down

0 comments on commit 1a735b9

Please sign in to comment.