Fix mconfig.h generation.
authorDavin McCall <davmac@davmac.org>
Thu, 7 Jun 2018 20:21:47 +0000 (21:21 +0100)
committerDavin McCall <davmac@davmac.org>
Thu, 7 Jun 2018 20:22:31 +0000 (21:22 +0100)
Re-work mconfig-gen so that it takes the variables at run-time on the
command line, rather than receiving them as macros at compile time. The
latter makes it impossible to use some values.

src/Makefile
src/mconfig-gen.cc

index 701afb92004a85041edac0d495341edb8e76df9b..2e5abcef058d7c41db97e60cf4ada2f9fd9660af 100644 (file)
@@ -12,11 +12,10 @@ objects = $(dinit_objects) dinitctl.o shutdown.o
 all: dinit dinitctl $(SHUTDOWN)
 
 mconfig.h: mconfig-gen
-       ./mconfig-gen > mconfig.h
+       ./mconfig-gen SBINDIR=$(SBINDIR) SYSCONTROLSOCKET=$(SYSCONTROLSOCKET) > mconfig.h
 
 mconfig-gen: mconfig-gen.cc ../mconfig
-       $(CXX) $(CXXOPTS) -o mconfig-gen mconfig-gen.cc $(LDFLAGS) -DSBINDIR=$(SBINDIR) \
-               -DSYSCONTROLSOCKET=$(SYSCONTROLSOCKET)
+       $(CXX) $(CXXOPTS) -o mconfig-gen mconfig-gen.cc $(LDFLAGS)
 
 dinit: mconfig.h $(dinit_objects)
        $(CXX) -o dinit $(dinit_objects) $(LDFLAGS)
index 0da3d842814f0341cdb22d89c84bc29bc1abf7c3..74b3a112b22d7784002b02c7afe5f61c77a14e64 100644 (file)
@@ -1,18 +1,66 @@
 #include <iostream>
+#include <unordered_map>
+#include <string>
 
-#define STR2(arg) #arg
-#define STR(arg)  STR2(arg)
+// This program generates an mconfig.h file. It is used in the build process.
 
+// Map of variable name to value. Variables are passed via command line and stored
+// in this map.
+std::unordered_map<std::string, std::string> vars;
+
+char to_hex_digit(int i)
+{
+    if (i < 10) return i + '0';
+    return i - 10 + 'A';
+}
+
+// turn a string into a C++-source string, eg:
+//     he said "hello"
+//  becomes
+//    "he said \"hello\""
 static std::string stringify(std::string a)
 {
-    return std::string("\"") + a + "\"";
+    std::string out = "\"";
+
+    for (std::string::size_type i = 0; i < a.length(); i++) {
+        char c = a[i];
+        if (c == '\n') out += "\\n";
+        else if (c == '\t') out += "\\t";
+        else if (c == '\"') out += "\\\"";
+        else if (c < 0x20) {
+            out += "\\x" ;
+            out += to_hex_digit((c & 0xF0) >> 4);
+            out += to_hex_digit((c & 0x0F));
+        }
+        else out += c;
+    }
+
+    out += "\"";
+    return out;
+}
+
+// parse a NAME=VALUE argument and store in the variable map
+void parse_arg(std::string arg)
+{
+    auto idx = arg.find("=", 0, 1);
+    if (idx == std::string::npos) {
+        throw std::string("Couldn't parse argument: ") + arg;
+    }
+
+    auto name = arg.substr(0, idx);
+    auto value = arg.substr(idx + 1);
+    vars.emplace(std::move(name), std::move(value));
 }
 
 int main(int argc, char **argv)
 {
+    for (int i = 1; i < argc; i++) {
+        parse_arg(argv[i]);
+    }
+
     using namespace std;
     cout << "// This file is auto-generated by mconfig-gen.cc." << endl;
-    cout << "const static char SYSCONTROLSOCKET[] =" << stringify(STR(SYSCONTROLSOCKET)) << ";" << endl;
-    cout << "const static char SBINDIR[] = " << stringify(STR(SBINDIR)) << ";" << endl;
+    cout << "const static char SYSCONTROLSOCKET[] = " << stringify(vars["SYSCONTROLSOCKET"]) << ";" << endl;
+    cout << "const static char SBINDIR[] = " << stringify(vars["SBINDIR"]) << ";" << endl;
     return 0;
 }