mconfig-gen.cc 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include <iostream>
  2. #include <unordered_map>
  3. #include <string>
  4. // This program generates an mconfig.h file. It is used in the build process.
  5. // Map of variable name to value. Variables are passed via command line and stored
  6. // in this map.
  7. std::unordered_map<std::string, std::string> vars;
  8. char to_hex_digit(int i)
  9. {
  10. if (i < 10) return i + '0';
  11. return i - 10 + 'A';
  12. }
  13. // turn a string into a C++-source string, eg:
  14. // he said "hello"
  15. // becomes
  16. // "he said \"hello\""
  17. static std::string stringify(std::string a)
  18. {
  19. std::string out = "\"";
  20. for (std::string::size_type i = 0; i < a.length(); i++) {
  21. char c = a[i];
  22. if (c == '\n') out += "\\n";
  23. else if (c == '\t') out += "\\t";
  24. else if (c == '\"') out += "\\\"";
  25. else if (c < 0x20) {
  26. out += "\\x" ;
  27. out += to_hex_digit((c & 0xF0) >> 4);
  28. out += to_hex_digit((c & 0x0F));
  29. }
  30. else out += c;
  31. }
  32. out += "\"";
  33. return out;
  34. }
  35. // parse a NAME=VALUE argument and store in the variable map
  36. void parse_arg(std::string arg)
  37. {
  38. auto idx = arg.find("=", 0, 1);
  39. if (idx == std::string::npos) {
  40. throw std::string("Couldn't parse argument: ") + arg;
  41. }
  42. auto name = arg.substr(0, idx);
  43. auto value = arg.substr(idx + 1);
  44. vars.emplace(std::move(name), std::move(value));
  45. }
  46. int main(int argc, char **argv)
  47. {
  48. for (int i = 1; i < argc; i++) {
  49. parse_arg(argv[i]);
  50. }
  51. using namespace std;
  52. cout << "// This file is auto-generated by mconfig-gen.cc.\n\n";
  53. cout << "#ifndef DINIT_MCONFIG_H\n";
  54. cout << "#define DINIT_MCONFIG_H 1\n";
  55. cout << "\n// Defines\n\n";
  56. if (vars.find("USE_UTMPX") != vars.end()) {
  57. cout << "#define USE_UTMPX " << vars["USE_UTMPX"] << "\n";
  58. }
  59. if (vars.find("USE_INITGROUPS") != vars.end()) {
  60. cout << "#define USE_INITGROUPS " << vars["USE_INITGROUPS"] << "\n";
  61. }
  62. else {
  63. // Default to assuming initgroups(3) is available
  64. cout << "#define USE_INITGROUPS 1\n";
  65. }
  66. if (vars.find("SUPPORT_CGROUPS") != vars.end()) {
  67. cout << "#define SUPPORT_CGROUPS " << vars["SUPPORT_CGROUPS"] << "\n";
  68. }
  69. if (vars.find("DEFAULT_AUTO_RESTART") != vars.end()) {
  70. cout << "#define DEFAULT_AUTO_RESTART " << vars["DEFAULT_AUTO_RESTART"] << "\n";
  71. }
  72. if (vars.find("DEFAULT_START_TIMEOUT") != vars.end()) {
  73. cout << "#define DEFAULT_START_TIMEOUT " << vars["DEFAULT_START_TIMEOUT"] << "\n";
  74. }
  75. if (vars.find("DEFAULT_STOP_TIMEOUT") != vars.end()) {
  76. cout << "#define DEFAULT_STOP_TIMEOUT " << vars["DEFAULT_STOP_TIMEOUT"] << "\n";
  77. }
  78. cout << "\n// Constants\n";
  79. cout << "\nconstexpr static char DINIT_VERSION[] = " << stringify(vars["VERSION"]) << ";\n";
  80. cout << "constexpr static char SYSCONTROLSOCKET[] = " << stringify(vars["SYSCONTROLSOCKET"]) << ";\n";
  81. cout << "constexpr static char SBINDIR[] = " << stringify(vars["SBINDIR"]) << ";\n";
  82. cout << "constexpr static char SHUTDOWN_PREFIX[] = " << stringify(vars["SHUTDOWN_PREFIX"]) << ";\n";
  83. cout << "\n#endif // DINIT_MCONFIG_H\n";
  84. return 0;
  85. }