Advertisement
xerpi

vitajsonlinker_crappy_format

Nov 12th, 2016
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.89 KB | None | 0 0
  1. /*
  2.  * vitajsonlinker by xerpi
  3.  *    - ./vitajsonlinker db1.json [db2.json, ...]
  4.  */
  5.  
  6. #include <string>
  7. #include <list>
  8. #include <iostream>
  9. #include <jansson.h>
  10.  
  11. typedef uint32_t vita_nid_t;
  12.  
  13. struct vita_function_t {
  14.     std::string name;
  15.     vita_nid_t nid;
  16. };
  17.  
  18. struct vita_variable_t {
  19.     std::string name;
  20.     vita_nid_t nid;
  21. };
  22.  
  23. struct vita_library_t {
  24.     std::string name;
  25.     vita_nid_t nid;
  26.     bool visibility;
  27.     std::list<vita_function_t> functions;
  28.     std::list<vita_variable_t> variables;
  29. };
  30.  
  31. struct vita_module_t {
  32.     std::string name;
  33.     vita_nid_t nid;
  34.     bool privilege;
  35.     std::list<vita_library_t> libraries;
  36. };
  37.  
  38. struct vita_exports_t {
  39.     std::list<vita_module_t> modules;
  40. };
  41.  
  42. void vita_exports_remove_empty(vita_exports_t &exports)
  43. {
  44.     for (std::list<vita_module_t>::iterator mod = exports.modules.begin(); mod != exports.modules.end(); ) {
  45.         for (std::list<vita_library_t>::iterator lib = mod->libraries.begin(); lib != mod->libraries.end(); ) {
  46.             if (lib->functions.size() == 0 && lib->variables.size() == 0) {
  47.                 lib = mod->libraries.erase(lib);
  48.                 continue;
  49.             }
  50.             lib++;
  51.         }
  52.  
  53.         if (mod->libraries.size() == 0) {
  54.             mod = exports.modules.erase(mod);
  55.             continue;
  56.         }
  57.         mod++;
  58.     }
  59. }
  60.  
  61. void vita_exports_sort(vita_exports_t &exports)
  62. {
  63.     std::list<vita_module_t>::iterator mod_it;
  64.     for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
  65.  
  66.         std::list<vita_library_t>::iterator lib_it;
  67.         for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
  68.  
  69.             lib_it->functions.sort([](const vita_function_t &a, const vita_function_t &b) {
  70.                 return a.name < b.name;
  71.             });
  72.  
  73.             lib_it->variables.sort([](const vita_variable_t &a, const vita_variable_t &b) {
  74.                 return a.name < b.name;
  75.             });
  76.         }
  77.  
  78.         mod_it->libraries.sort([](const vita_library_t &a, const vita_library_t &b) {
  79.             return a.name < b.name;
  80.         });
  81.     }
  82.  
  83.     exports.modules.sort([](const vita_module_t &a, const vita_module_t &b) {
  84.         return a.name < b.name;
  85.     });
  86. }
  87.  
  88. void vita_json_print(const vita_exports_t &exports)
  89. {
  90.     std::cout << "{" << std::endl;
  91.  
  92.     std::list<vita_module_t>::const_iterator mod_it;
  93.     for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
  94.  
  95.         std::cout << "    \"" << mod_it->name << "\": {" << std::endl;
  96.         std::cout << "        \"" << "modules" << "\": {" << std::endl;
  97.  
  98.         std::list<vita_library_t>::const_iterator lib_it;
  99.         for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
  100.             std::cout << "            \"" << lib_it->name << "\": {" << std::endl;
  101.             std::cout << "                \"" << "functions" << "\": {" << std::endl;
  102.  
  103.             std::list<vita_function_t>::const_iterator func_it;
  104.             for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) {
  105.                 std::cout << "                    \"" << func_it->name << "\": " << func_it->nid;
  106.  
  107.                 if (func_it != std::prev(lib_it->functions.end()))
  108.                     std::cout << ", ";
  109.                 std::cout << std::endl;
  110.             }
  111.  
  112.             std::cout << "                }," << std::endl;
  113.             std::cout << "                \"kernel\": " << (lib_it->visibility ? "true" : "false") << "," << std::endl;
  114.             std::cout << "                \"nid\": " << lib_it->nid << std::endl;
  115.             std::cout << "            }";
  116.  
  117.             if (lib_it != std::prev(mod_it->libraries.end()))
  118.                 std::cout << ",";
  119.             std::cout << std::endl;
  120.         }
  121.  
  122.         std::cout << "        }" << "," << std::endl;
  123.         std::cout << "        \"nid\": " << mod_it->nid << std::endl;
  124.  
  125.         std::cout << "    }";
  126.         if (mod_it != std::prev(exports.modules.end()))
  127.             std::cout << ",";
  128.         std::cout << std::endl;
  129.     }
  130.  
  131.     std::cout << "}" << std::endl;
  132. }
  133.  
  134. bool vita_json_load(vita_exports_t &exports, FILE *file, int verbose)
  135. {
  136.     json_t *libs, *lib_data;
  137.     json_error_t error;
  138.     const char *lib_name, *mod_name, *target_name;
  139.  
  140.     libs = json_loadf(file, 0, &error);
  141.     if (libs == nullptr) {
  142.         fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
  143.         return false;
  144.     }
  145.  
  146.     if (!json_is_object(libs)) {
  147.         fprintf(stderr, "error: modules is not an object\n");
  148.         json_decref(libs);
  149.         return false;
  150.     }
  151.  
  152.     int i, j, k;
  153.  
  154.     i = -1;
  155.     json_object_foreach(libs, lib_name, lib_data) {
  156.         json_t *nid, *modules, *mod_data;
  157.  
  158.         i++;
  159.  
  160.         if (!json_is_object(lib_data)) {
  161.             fprintf(stderr, "error: library %s is not an object\n", lib_name);
  162.             json_decref(libs);
  163.             return false;
  164.         }
  165.  
  166.         nid = json_object_get(lib_data, "nid");
  167.         if (!json_is_integer(nid)) {
  168.             fprintf(stderr, "error: library %s: nid is not an integer\n", lib_name);
  169.             json_decref(libs);
  170.             return false;
  171.         }
  172.  
  173.         modules = json_object_get(lib_data, "modules");
  174.         if (!json_is_object(modules)) {
  175.             fprintf(stderr, "error: library %s: module is not an object\n", lib_name);
  176.             json_decref(libs);
  177.             return false;
  178.         }
  179.  
  180.         std::string module_name = std::string(lib_name);
  181.         vita_nid_t module_nid = json_integer_value(nid);
  182.  
  183.         std::list<vita_module_t>::iterator mod_it;
  184.  
  185.         for (mod_it = exports.modules.begin(); mod_it != exports.modules.end(); mod_it++) {
  186.             if (mod_it->name.compare(module_name) == 0) {
  187.                 /*
  188.                  * If we have found the *real* NID, update
  189.                  * the fake one (nids from 0 to a few hundreds).
  190.                  */
  191.                 if (mod_it->nid < 500 && module_nid > 500)
  192.                     mod_it->nid = module_nid;
  193.                 break;
  194.             }
  195.         }
  196.  
  197.         if (mod_it == exports.modules.end()) {
  198.             vita_module_t module;
  199.             module.name = module_name;
  200.             module.nid = module_nid;
  201.             //module.visibility = ?;
  202.             exports.modules.push_back(module);
  203.             mod_it = std::prev(exports.modules.end());
  204.         }
  205.  
  206.         if (verbose)
  207.             printf("Lib: %s\n", lib_name);
  208.  
  209.         j = -1;
  210.         json_object_foreach(modules, mod_name, mod_data) {
  211.             json_t *nid, *kernel, *functions, *variables, *target_nid;
  212.             bool has_variables = true;
  213.  
  214.             j++;
  215.  
  216.             if (!json_is_object(mod_data)) {
  217.                 fprintf(stderr, "error: module %s is not an object\n", mod_name);
  218.                 json_decref(libs);
  219.                 return false;
  220.             }
  221.  
  222.             nid = json_object_get(mod_data, "nid");
  223.             if (!json_is_integer(nid)) {
  224.                 fprintf(stderr, "error: module %s: nid is not an integer\n", mod_name);
  225.                 json_decref(libs);
  226.                 return false;
  227.             }
  228.  
  229.             kernel = json_object_get(mod_data, "kernel");
  230.             if (!json_is_boolean(kernel)) {
  231.                 fprintf(stderr, "error: module %s: kernel is not a boolean\n", mod_name);
  232.                 json_decref(libs);
  233.                 return false;
  234.             }
  235.  
  236.             functions = json_object_get(mod_data, "functions");
  237.             if (!json_is_object(functions)) {
  238.                 fprintf(stderr, "error: module %s: functions is not an array\n", mod_name);
  239.                 json_decref(libs);
  240.                 return false;
  241.             }
  242.  
  243.             variables = json_object_get(mod_data, "variables");
  244.             if (variables == nullptr) {
  245.                 has_variables = false;
  246.             }
  247.  
  248.             if (has_variables && !json_is_object(variables)) {
  249.                 fprintf(stderr, "error: module %s: variables is not an array\n", mod_name);
  250.                 json_decref(libs);
  251.                 return false;
  252.             }
  253.  
  254.             if (verbose)
  255.                 printf("\tModule: %s\n", mod_name);
  256.  
  257.             std::string library_name = std::string(mod_name);
  258.             vita_nid_t library_nid = json_integer_value(nid);
  259.  
  260.             std::list<vita_library_t>::iterator lib_it;
  261.  
  262.             for (lib_it = mod_it->libraries.begin(); lib_it != mod_it->libraries.end(); lib_it++) {
  263.                 if (lib_it->name.compare(library_name) == 0)
  264.                     break;
  265.             }
  266.  
  267.             if (lib_it == mod_it->libraries.end()) {
  268.                 vita_library_t library;
  269.                 library.name = library_name;
  270.                 library.nid = library_nid;
  271.                 library.visibility = json_boolean_value(kernel);
  272.                 mod_it->libraries.push_back(library);
  273.                 lib_it = std::prev(mod_it->libraries.end());
  274.             }
  275.  
  276.             k = -1;
  277.             json_object_foreach(functions, target_name, target_nid) {
  278.                 k++;
  279.  
  280.                 if (!json_is_integer(target_nid)) {
  281.                     fprintf(stderr, "error: function %s: nid is not an integer\n", target_name);
  282.                     json_decref(libs);
  283.                     return false;
  284.                 }
  285.  
  286.                 if (verbose)
  287.                     printf("\t\tFunction: %s\n", target_name);
  288.  
  289.                 std::string function_name = std::string(target_name);
  290.                 vita_nid_t function_nid = json_integer_value(target_nid);
  291.  
  292.                 std::list<vita_function_t>::iterator func_it;
  293.  
  294.                 for (func_it = lib_it->functions.begin(); func_it != lib_it->functions.end(); func_it++) {
  295.                     if (func_it->name.compare(function_name) == 0)
  296.                         break;
  297.                 }
  298.  
  299.                 if (func_it == lib_it->functions.end()) {
  300.                     vita_function_t function;
  301.                     function.name = function_name;
  302.                     function.nid = function_nid;
  303.                     lib_it->functions.push_back(function);
  304.                 }
  305.             }
  306.  
  307.             if (has_variables) {
  308.                 k = -1;
  309.                 json_object_foreach(variables, target_name, target_nid) {
  310.                     k++;
  311.  
  312.                     if (!json_is_integer(target_nid)) {
  313.                         fprintf(stderr, "error: variable %s: nid is not an integer\n", target_name);
  314.                         json_decref(libs);
  315.                         return false;
  316.                     }
  317.  
  318.                     if (verbose)
  319.                         printf("\t\tVariable: %s\n", target_name);
  320.  
  321.                     std::string variable_name = std::string(target_name);
  322.                     vita_nid_t variable_nid = json_integer_value(target_nid);
  323.  
  324.                     std::list<vita_variable_t>::iterator func_it;
  325.  
  326.                     for (func_it = lib_it->variables.begin(); func_it != lib_it->variables.end(); func_it++) {
  327.                         if (func_it->name.compare(variable_name) == 0 && func_it->nid == variable_nid)
  328.                             break;
  329.                     }
  330.  
  331.                     if (func_it == lib_it->variables.end()) {
  332.                         vita_variable_t variable;
  333.                         variable.name = variable_name;
  334.                         variable.nid = variable_nid;
  335.                         lib_it->variables.push_back(variable);
  336.                     }
  337.                 }
  338.             }
  339.         }
  340.     }
  341.  
  342.     return true;
  343. }
  344.  
  345. int main(int argc, char *argv[])
  346. {
  347.     FILE *fp;
  348.     vita_exports_t exports;
  349.  
  350.     if (argc < 2) {
  351.         std::cerr << "Usage: vitajsonlinker db1.json [db2.json, ...]" << std::endl;
  352.         return 1;
  353.     }
  354.  
  355.     for (int i = 1; i < argc; i++) {
  356.         fp = fopen(argv[i], "r");
  357.         if (fp == nullptr) {
  358.             std::cerr << "Error: could not open: " << argv[i] << std::endl;
  359.             return 1;
  360.         }
  361.  
  362.         vita_json_load(exports, fp, 0);
  363.  
  364.         fclose(fp);
  365.     }
  366.  
  367.     //vita_exports_remove_empty(exports);
  368.     //vita_exports_sort(exports);
  369.     vita_json_print(exports);
  370.  
  371.     return 0;
  372. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement