Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * vitajsonlinker by xerpi
- * - ./vitajsonlinker db1.json [db2.json, ...]
- */
- #include <string>
- #include <list>
- #include <iostream>
- #include <jansson.h>
- typedef uint32_t vita_nid_t;
- struct vita_function_t {
- std::string name;
- vita_nid_t nid;
- };
- struct vita_variable_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;
- std::list<vita_variable_t> variables;
- };
- struct vita_module_t {
- std::string name;
- vita_nid_t nid;
- bool privilege;
- std::list<vita_library_t> libraries;
- };
- struct vita_exports_t {
- std::list<vita_module_t> modules;
- };
- void vita_exports_remove_empty(vita_exports_t &exports)
- {
- for (std::list<vita_module_t>::iterator mod = exports.modules.begin(); mod != exports.modules.end(); ) {
- for (std::list<vita_library_t>::iterator lib = mod->libraries.begin(); lib != mod->libraries.end(); ) {
- if (lib->functions.size() == 0 && lib->variables.size() == 0) {
- lib = mod->libraries.erase(lib);
- continue;
- }
- lib++;
- }
- if (mod->libraries.size() == 0) {
- mod = exports.modules.erase(mod);
- continue;
- }
- mod++;
- }
- }
- void vita_exports_sort(vita_exports_t &exports)
- {
- std::list<vita_module_t>::iterator mod_it;
- for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
- std::list<vita_library_t>::iterator lib_it;
- for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
- lib_it->functions.sort([](const vita_function_t &a, const vita_function_t &b) {
- return a.name < b.name;
- });
- lib_it->variables.sort([](const vita_variable_t &a, const vita_variable_t &b) {
- return a.name < b.name;
- });
- }
- mod_it->libraries.sort([](const vita_library_t &a, const vita_library_t &b) {
- return a.name < b.name;
- });
- }
- exports.modules.sort([](const vita_module_t &a, const vita_module_t &b) {
- return a.name < b.name;
- });
- }
- void vita_json_print(const vita_exports_t &exports)
- {
- std::cout << "{" << std::endl;
- std::list<vita_module_t>::const_iterator mod_it;
- for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
- std::cout << " \"" << mod_it->name << "\": {" << std::endl;
- std::cout << " \"" << "modules" << "\": {" << std::endl;
- std::list<vita_library_t>::const_iterator lib_it;
- for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
- std::cout << " \"" << lib_it->name << "\": {" << std::endl;
- std::cout << " \"" << "functions" << "\": {" << std::endl;
- std::list<vita_function_t>::const_iterator func_it;
- for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) {
- std::cout << " \"" << func_it->name << "\": " << func_it->nid;
- if (func_it != std::prev(lib_it->functions.end()))
- std::cout << ", ";
- std::cout << std::endl;
- }
- std::cout << " }," << std::endl;
- std::cout << " \"kernel\": " << (lib_it->visibility ? "true" : "false") << "," << std::endl;
- std::cout << " \"nid\": " << lib_it->nid << std::endl;
- std::cout << " }";
- if (lib_it != std::prev(mod_it->libraries.end()))
- std::cout << ",";
- std::cout << std::endl;
- }
- std::cout << " }" << "," << std::endl;
- std::cout << " \"nid\": " << mod_it->nid << std::endl;
- std::cout << " }";
- if (mod_it != std::prev(exports.modules.end()))
- std::cout << ",";
- std::cout << std::endl;
- }
- std::cout << "}" << std::endl;
- }
- bool vita_json_load(vita_exports_t &exports, FILE *file, int verbose)
- {
- json_t *libs, *lib_data;
- json_error_t error;
- const char *lib_name, *mod_name, *target_name;
- libs = json_loadf(file, 0, &error);
- if (libs == nullptr) {
- fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
- return false;
- }
- if (!json_is_object(libs)) {
- fprintf(stderr, "error: modules is not an object\n");
- json_decref(libs);
- return false;
- }
- int i, j, k;
- i = -1;
- json_object_foreach(libs, lib_name, lib_data) {
- json_t *nid, *modules, *mod_data;
- i++;
- if (!json_is_object(lib_data)) {
- fprintf(stderr, "error: library %s is not an object\n", lib_name);
- json_decref(libs);
- return false;
- }
- nid = json_object_get(lib_data, "nid");
- if (!json_is_integer(nid)) {
- fprintf(stderr, "error: library %s: nid is not an integer\n", lib_name);
- json_decref(libs);
- return false;
- }
- modules = json_object_get(lib_data, "modules");
- if (!json_is_object(modules)) {
- fprintf(stderr, "error: library %s: module is not an object\n", lib_name);
- json_decref(libs);
- return false;
- }
- std::string module_name = std::string(lib_name);
- vita_nid_t module_nid = json_integer_value(nid);
- std::list<vita_module_t>::iterator mod_it;
- for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
- if (mod_it->name.compare(module_name) == 0) {
- /*
- * If we have found the *real* NID, update
- * the fake one (nids from 0 to a few hundreds).
- */
- if (mod_it->nid < 500 && module_nid > 500)
- mod_it->nid = module_nid;
- break;
- }
- }
- if (mod_it == exports.modules.end()) {
- vita_module_t module;
- module.name = module_name;
- module.nid = module_nid;
- //module.visibility = ?;
- exports.modules.push_back(module);
- mod_it = std::prev(exports.modules.end());
- }
- if (verbose)
- printf("Lib: %s\n", lib_name);
- j = -1;
- json_object_foreach(modules, mod_name, mod_data) {
- json_t *nid, *kernel, *functions, *variables, *target_nid;
- bool has_variables = true;
- j++;
- if (!json_is_object(mod_data)) {
- fprintf(stderr, "error: module %s is not an object\n", mod_name);
- json_decref(libs);
- return false;
- }
- nid = json_object_get(mod_data, "nid");
- if (!json_is_integer(nid)) {
- fprintf(stderr, "error: module %s: nid is not an integer\n", mod_name);
- json_decref(libs);
- return false;
- }
- kernel = json_object_get(mod_data, "kernel");
- if (!json_is_boolean(kernel)) {
- fprintf(stderr, "error: module %s: kernel is not a boolean\n", mod_name);
- json_decref(libs);
- return false;
- }
- functions = json_object_get(mod_data, "functions");
- if (!json_is_object(functions)) {
- fprintf(stderr, "error: module %s: functions is not an array\n", mod_name);
- json_decref(libs);
- return false;
- }
- variables = json_object_get(mod_data, "variables");
- if (variables == nullptr) {
- has_variables = false;
- }
- if (has_variables && !json_is_object(variables)) {
- fprintf(stderr, "error: module %s: variables is not an array\n", mod_name);
- json_decref(libs);
- return false;
- }
- if (verbose)
- printf("\tModule: %s\n", mod_name);
- std::string library_name = std::string(mod_name);
- vita_nid_t library_nid = json_integer_value(nid);
- std::list<vita_library_t>::iterator lib_it;
- for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
- if (lib_it->name.compare(library_name) == 0)
- break;
- }
- if (lib_it == mod_it->libraries.end()) {
- vita_library_t library;
- library.name = library_name;
- library.nid = library_nid;
- library.visibility = json_boolean_value(kernel);
- mod_it->libraries.push_back(library);
- lib_it = std::prev(mod_it->libraries.end());
- }
- k = -1;
- json_object_foreach(functions, target_name, target_nid) {
- k++;
- if (!json_is_integer(target_nid)) {
- fprintf(stderr, "error: function %s: nid is not an integer\n", target_name);
- json_decref(libs);
- return false;
- }
- if (verbose)
- printf("\t\tFunction: %s\n", target_name);
- std::string function_name = std::string(target_name);
- vita_nid_t function_nid = json_integer_value(target_nid);
- std::list<vita_function_t>::iterator func_it;
- for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) {
- if (func_it->name.compare(function_name) == 0)
- break;
- }
- if (func_it == lib_it->functions.end()) {
- vita_function_t function;
- function.name = function_name;
- function.nid = function_nid;
- lib_it->functions.push_back(function);
- }
- }
- if (has_variables) {
- k = -1;
- json_object_foreach(variables, target_name, target_nid) {
- k++;
- if (!json_is_integer(target_nid)) {
- fprintf(stderr, "error: variable %s: nid is not an integer\n", target_name);
- json_decref(libs);
- return false;
- }
- if (verbose)
- printf("\t\tVariable: %s\n", target_name);
- std::string variable_name = std::string(target_name);
- vita_nid_t variable_nid = json_integer_value(target_nid);
- std::list<vita_variable_t>::iterator func_it;
- for (func_it = lib_it->variables.begin(); func_it != lib_it->variables.end(); func_it++) {
- if (func_it->name.compare(variable_name) == 0 && func_it->nid == variable_nid)
- break;
- }
- if (func_it == lib_it->variables.end()) {
- vita_variable_t variable;
- variable.name = variable_name;
- variable.nid = variable_nid;
- lib_it->variables.push_back(variable);
- }
- }
- }
- }
- }
- return true;
- }
- int main(int argc, char *argv[])
- {
- FILE *fp;
- vita_exports_t exports;
- if (argc < 2) {
- std::cerr << "Usage: vitajsonlinker db1.json [db2.json, ...]" << std::endl;
- return 1;
- }
- for (int i = 1; i < argc; i++) {
- fp = fopen(argv[i], "r");
- if (fp == nullptr) {
- std::cerr << "Error: could not open: " << argv[i] << std::endl;
- return 1;
- }
- vita_json_load(exports, fp, 0);
- fclose(fp);
- }
- //vita_exports_remove_empty(exports);
- //vita_exports_sort(exports);
- vita_json_print(exports);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement