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