mconfig-gen.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. cout << "\n// Constants\n";
  73. cout << "\nconstexpr static char DINIT_VERSION[] = " << stringify(vars["VERSION"]) << ";\n";
  74. cout << "constexpr static char SYSCONTROLSOCKET[] = " << stringify(vars["SYSCONTROLSOCKET"]) << ";\n";
  75. cout << "constexpr static char SBINDIR[] = " << stringify(vars["SBINDIR"]) << ";\n";
  76. cout << "constexpr static char SHUTDOWN_PREFIX[] = " << stringify(vars["SHUTDOWN_PREFIX"]) << ";\n";
  77. if (vars.find("DEFAULT_START_TIMEOUT") != vars.end()) {
  78. cout << "constexpr static unsigned DEFAULT_START_TIMEOUT = " << vars["DEFAULT_START_TIMEOUT"] << ";\n";
  79. }
  80. else {
  81. cout << "constexpr static unsigned DEFAULT_START_TIMEOUT = 60;\n";
  82. }
  83. if (vars.find("DEFAULT_STOP_TIMEOUT") != vars.end()) {
  84. cout << "constexpr static unsigned DEFAULT_STOP_TIMEOUT = " << vars["DEFAULT_STOP_TIMEOUT"] << ";\n";
  85. }
  86. else {
  87. cout << "constexpr static unsigned DEFAULT_STOP_TIMEOUT = 10;\n";
  88. }
  89. cout << "\n#endif // DINIT_MCONFIG_H\n";
  90. return 0;
  91. }