Last active
November 11, 2016 18:37
-
-
Save xerpi/ba032cf937f54d4254716e7d78a9b88c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* wikinidparser by xerpi | |
* Usage: | |
* - hxpipe SceFoo > SceFoo_piped | |
* - ./wikinidparser SceFoo_piped | |
*/ | |
#include <stdlib.h> | |
#include <fstream> | |
#include <sstream> | |
#include <iostream> | |
#include <string> | |
#include <algorithm> | |
#include <cstdint> | |
#include <list> | |
typedef uint32_t vita_nid_t; | |
struct vita_function_t { | |
std::string name; | |
vita_nid_t nid; | |
}; | |
struct vita_library_t { | |
std::string name; | |
vita_nid_t nid; | |
bool visibility; | |
std::list<vita_function_t> functions; | |
}; | |
struct vita_module_t { | |
std::string name; | |
vita_nid_t nid; | |
bool privilege; | |
std::list<vita_library_t> libraries; | |
}; | |
static std::string rtrim(std::string s) | |
{ | |
s.erase(std::find_if(s.rbegin(), s.rend(), | |
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); | |
return s; | |
} | |
static void skip_lines(std::istringstream &is, int n) | |
{ | |
std::string line; | |
for (int i = 1; i < n; i++) { | |
std::getline(is, line); | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
vita_module_t module; | |
if (argc < 2) { | |
std::cout << "Usage: wikinidparser <html filename>.\n"; | |
exit(EXIT_FAILURE); | |
} | |
std::ifstream in(argv[1], std::ios::in | std::ios::binary); | |
if (!in) { | |
std::cout << "File " << argv[1] << " not found!\n"; | |
exit(EXIT_FAILURE); | |
} | |
std::string contents; | |
in.seekg(0, std::ios::end); | |
contents.resize(in.tellg()); | |
in.seekg(0, std::ios::beg); | |
in.read(&contents[0], contents.size()); | |
in.close(); | |
std::istringstream is(contents); | |
bool found_module = false; | |
bool found_libs = false; | |
std::string line; | |
std::string tmp; | |
while (std::getline(is, line)) { | |
/* Module */ | |
if (line.compare("Aid CDATA Known_NIDs") == 0 && !found_module) { | |
std::string module_name; | |
bool kernel; | |
uint32_t nid; | |
skip_lines(is, 35); | |
std::getline(is, tmp); | |
module_name = rtrim(tmp.substr(tmp.find("Sce"))); | |
skip_lines(is, 8); | |
std::getline(is, tmp); | |
kernel = tmp.find("Kernel") != std::string::npos; | |
skip_lines(is, 4); | |
std::getline(is, tmp); | |
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16); | |
module.name = module_name; | |
module.nid = nid; | |
module.privilege = kernel; | |
found_module = true; | |
} else if (line.compare("Aid CDATA Known_NIDs_2") == 0 && !found_libs) { /* Lib */ | |
skip_lines(is, 37); | |
while (true) { | |
std::string lib_name; | |
bool kernel; | |
uint32_t nid; | |
std::size_t found; | |
std::getline(is, line); | |
if (line.find("Atitle CDATA") == std::string::npos) | |
break; | |
skip_lines(is, 2); | |
std::getline(is, tmp); | |
found = tmp.find("Sce"); | |
if (found == std::string::npos) | |
break; | |
lib_name = rtrim(tmp.substr(found)); | |
skip_lines(is, 10); | |
std::getline(is, tmp); | |
kernel = tmp.find("Kernel") != std::string::npos; | |
skip_lines(is, 4); | |
std::getline(is, tmp); | |
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16); | |
vita_library_t library; | |
library.name = lib_name; | |
library.nid = nid; | |
library.visibility = kernel; | |
module.libraries.push_back(library); | |
skip_lines(is, 11); | |
} | |
found_libs = true; | |
} | |
/* Functions */ | |
if (line.find("Aid CDATA Sce") != std::string::npos && found_module && found_libs) { | |
std::string library; | |
size_t found; | |
library = rtrim(line.substr(line.find("Sce"))); | |
skip_lines(is, 11); | |
while (1) { | |
std::string func_name; | |
uint32_t nid; | |
std::getline(is, tmp); | |
found = tmp.find("sce"); | |
if (found == std::string::npos) | |
break; | |
func_name = rtrim(tmp.substr(found)); | |
skip_lines(is, 23); | |
std::getline(is, tmp); | |
nid = std::stoul(tmp.substr(tmp.find("0x")), nullptr, 16); | |
vita_function_t function; | |
function.name = func_name; | |
function.nid = nid; | |
std::list<vita_library_t>::iterator lib_it; | |
for (lib_it = module.libraries.begin(); lib_it != module.libraries.end(); lib_it++) { | |
if (lib_it->name.compare(library) == 0) | |
break; | |
} | |
if (lib_it != module.libraries.end()) | |
lib_it->functions.push_back(function); | |
skip_lines(is, 7); | |
} | |
} | |
} | |
std::cout << "{" << std::endl; | |
std::cout << "\t\"" << module.name << "\": {" << std::endl; | |
std::cout << "\t\t\"" << "modules" << "\": {" << std::endl; | |
std::list<vita_library_t>::iterator lib_it; | |
for (lib_it = module.libraries.begin(); lib_it != module.libraries.end(); lib_it++) { | |
std::cout << "\t\t\t\"" << lib_it->name << "\": {" << std::endl; | |
std::cout << "\t\t\t\t\"" << "functions" << "\": {" << std::endl; | |
std::list<vita_function_t>::iterator func_it; | |
for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) { | |
std::cout << "\t\t\t\t\t\"" << func_it->name << "\": " << func_it->nid; | |
if (func_it != std::prev(lib_it->functions.end())) | |
std::cout << ","; | |
std::cout << std::endl; | |
} | |
std::cout << "\t\t\t\t}," << std::endl; | |
std::cout << "\t\t\t\t\"kernel\": " << (lib_it->visibility ? "true" : "false") << "," << std::endl; | |
std::cout << "\t\t\t\t\"nid\": " << lib_it->nid << std::endl; | |
std::cout << "\t\t\t}"; | |
if (lib_it != std::prev(module.libraries.end())) | |
std::cout << ","; | |
std::cout << std::endl; | |
} | |
std::cout << "\t\t}," << std::endl; | |
std::cout << "\t\t\"nid\": " << module.nid << std::endl; | |
std::cout << "\t}" << std::endl; | |
std::cout << "}" << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment