diff -r 11587d419d2f -r fec7023e91a7 codegen/codegen.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/codegen/codegen.cpp Wed Jul 16 18:57:48 2014 +0300
@@ -0,0 +1,176 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2013, 2014 Teemu Piippo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using std::string;
+using std::vector;
+using std::ifstream;
+using std::size_t;
+using std::strncmp;
+using std::getline;
+using std::cout;
+using std::endl;
+
+struct entry_type
+{
+ string name;
+ string type;
+ string defvalue;
+
+ inline bool operator< (entry_type const& other) const
+ {
+ return name < other.name;
+ }
+
+ inline bool operator== (entry_type const& other) const
+ {
+ return name == other.name and type == other.type;
+ }
+
+ inline bool operator!= (entry_type const& other) const
+ {
+ return not operator== (other);
+ }
+};
+
+char advance_pointer (char const*& ptr)
+{
+ char a = *ptr++;
+ if (*ptr == '\0')
+ throw false;
+
+ return a;
+}
+
+void read_cfgentries (string const& filename, vector& entries, const char* macroname)
+{
+ ifstream is (filename.c_str());
+ string line;
+ size_t const macrolen = strlen (macroname);
+
+ while (getline (is, line))
+ {
+ try
+ {
+ if (strncmp (line.c_str(), macroname, macrolen) != 0)
+ continue;
+
+ char const* ptr = &line[macrolen];
+ entry_type entry;
+
+ // Skip to paren
+ while (*ptr != '(')
+ advance_pointer (ptr);
+
+ // Skip whitespace
+ while (isspace (*ptr))
+ advance_pointer (ptr);
+
+ // Skip paren
+ advance_pointer (ptr);
+
+ // Read type
+ while (*ptr != ',')
+ entry.type += advance_pointer (ptr);
+
+ // Skip comma and whitespace
+ for (advance_pointer (ptr); isspace (*ptr); advance_pointer (ptr))
+ ;
+
+ // Read name
+ while (*ptr != ',')
+ entry.name += advance_pointer (ptr);
+
+ // Skip comma and whitespace
+ for (advance_pointer (ptr); isspace (*ptr); advance_pointer (ptr))
+ ;
+
+ // Read default
+ while (*ptr != ')')
+ entry.defvalue += advance_pointer (ptr);
+
+ entries.push_back (entry);
+ }
+ catch (bool) {}
+ }
+}
+
+bool check_equality (vector a, vector b)
+{
+ if (a.size() != b.size())
+ return false;
+
+ std::sort (a.begin(), a.end());
+ std::sort (b.begin(), b.end());
+
+ for (size_t i = 0; i < a.size(); ++i)
+ {
+ if (a[i] != b[i])
+ return false;
+ }
+
+ return true;
+}
+
+int main (int argc, char* argv[])
+{
+ vector entries;
+ vector oldentries;
+ read_cfgentries (argv[argc - 1], oldentries, "CODEGEN_CACHE");
+
+ for (int arg = 1; arg < argc - 1; ++arg)
+ read_cfgentries (argv[arg], entries, "CFGENTRY");
+
+ if (check_equality (entries, oldentries))
+ {
+ cout << "Configuration options unchanged" << endl;
+ }
+ else
+ {
+ std::ofstream os (argv[argc - 1]);
+ os << "#pragma once" << endl;
+ os << "#define CODEGEN_CACHE(A,B,C)" << endl;
+
+ for (vector::const_iterator it = entries.begin(); it != entries.end(); ++it)
+ os << "CODEGEN_CACHE (" << it->type << ", " << it->name << ", " << it->defvalue << ")" << endl;
+
+ os << endl;
+ for (vector::const_iterator it = entries.begin(); it != entries.end(); ++it)
+ os << "EXTERN_CFGENTRY (" << it->type << ", " << it->name << ")" << endl;
+
+ os << endl;
+ os << "static void initConfigurationEntry (ConfigEntry* entry);" << endl;
+ os << "static void setupConfigurationLists()" << endl;
+ os << "{" << endl;
+
+ for (vector::const_iterator it = entries.begin(); it != entries.end(); ++it)
+ os << "\tinitConfigurationEntry (new " << it->type << "ConfigEntry (&cfg::" << it->name << ", \"" << it->name << "\", " << it->defvalue << "));" << endl;
+ os << "}" << endl;
+
+ cout << "Wrote configuration options list to " << argv[argc - 1] << "." << endl;
+ }
+
+ return 0;
+}