codegen/codegen.cpp

changeset 861
83426c5fa732
parent 848
68410477c8bb
child 968
4b93b7963456
equal deleted inserted replaced
860:a496e72af069 861:83426c5fa732
31 using std::strncmp; 31 using std::strncmp;
32 using std::getline; 32 using std::getline;
33 using std::cout; 33 using std::cout;
34 using std::endl; 34 using std::endl;
35 35
36 struct entry_type 36 struct EntryType
37 { 37 {
38 string name; 38 string name;
39 string type; 39 string type;
40 string defvalue; 40 string defvalue;
41 41
42 inline bool operator< (entry_type const& other) const 42 inline bool operator< (EntryType const& other) const
43 { 43 {
44 return name < other.name; 44 return name < other.name;
45 } 45 }
46 46
47 inline bool operator== (entry_type const& other) const 47 inline bool operator== (EntryType const& other) const
48 { 48 {
49 return name == other.name and type == other.type; 49 return name == other.name and type == other.type;
50 } 50 }
51 51
52 inline bool operator!= (entry_type const& other) const 52 inline bool operator!= (EntryType const& other) const
53 { 53 {
54 return not operator== (other); 54 return not operator== (other);
55 } 55 }
56 }; 56 };
57 57
58 char advance_pointer (char const*& ptr) 58 char AdvancePointer (char const*& ptr)
59 { 59 {
60 char a = *ptr++; 60 char a = *ptr++;
61
61 if (*ptr == '\0') 62 if (*ptr == '\0')
62 throw false; 63 throw false;
63 64
64 return a; 65 return a;
65 } 66 }
66 67
67 void read_cfgentries (string const& filename, vector<entry_type>& entries, const char* macroname) 68 void ReadConfigEntries (string const& filename, vector<EntryType>& entries, const char* macroname)
68 { 69 {
69 ifstream is (filename.c_str()); 70 ifstream is (filename.c_str());
70 string line; 71 string line;
71 size_t const macrolen = strlen (macroname); 72 size_t const macrolen = strlen (macroname);
72 73
76 { 77 {
77 if (strncmp (line.c_str(), macroname, macrolen) != 0) 78 if (strncmp (line.c_str(), macroname, macrolen) != 0)
78 continue; 79 continue;
79 80
80 char const* ptr = &line[macrolen]; 81 char const* ptr = &line[macrolen];
81 entry_type entry; 82 EntryType entry;
82 83
83 // Skip to paren 84 // Skip to paren
84 while (*ptr != '(') 85 while (*ptr != '(')
85 advance_pointer (ptr); 86 AdvancePointer (ptr);
86 87
87 // Skip whitespace 88 // Skip whitespace
88 while (isspace (*ptr)) 89 while (isspace (*ptr))
89 advance_pointer (ptr); 90 AdvancePointer (ptr);
90 91
91 // Skip paren 92 // Skip paren
92 advance_pointer (ptr); 93 AdvancePointer (ptr);
93 94
94 // Read type 95 // Read type
95 while (*ptr != ',') 96 while (*ptr != ',')
96 entry.type += advance_pointer (ptr); 97 entry.type += AdvancePointer (ptr);
97 98
98 // Skip comma and whitespace 99 // Skip comma and whitespace
99 for (advance_pointer (ptr); isspace (*ptr); advance_pointer (ptr)) 100 for (AdvancePointer (ptr); isspace (*ptr); AdvancePointer (ptr))
100 ; 101 ;
101 102
102 // Read name 103 // Read name
103 while (*ptr != ',') 104 while (*ptr != ',')
104 entry.name += advance_pointer (ptr); 105 entry.name += AdvancePointer (ptr);
105 106
106 // Skip comma and whitespace 107 // Skip comma and whitespace
107 for (advance_pointer (ptr); isspace (*ptr); advance_pointer (ptr)) 108 for (AdvancePointer (ptr); isspace (*ptr); AdvancePointer (ptr))
108 ; 109 ;
109 110
110 // Read default 111 // Read default
111 while (*ptr != ')') 112 while (*ptr != ')')
112 entry.defvalue += advance_pointer (ptr); 113 entry.defvalue += AdvancePointer (ptr);
113 114
114 entries.push_back (entry); 115 entries.push_back (entry);
115 } 116 }
116 catch (bool) {} 117 catch (bool) {}
117 } 118 }
118 } 119 }
119 120
120 bool check_equality (vector<entry_type> a, vector<entry_type> b) 121 bool CheckEquality (vector<EntryType> a, vector<EntryType> b)
121 { 122 {
122 if (a.size() != b.size()) 123 if (a.size() != b.size())
123 return false; 124 return false;
124 125
125 std::sort (a.begin(), a.end()); 126 std::sort (a.begin(), a.end());
134 return true; 135 return true;
135 } 136 }
136 137
137 int main (int argc, char* argv[]) 138 int main (int argc, char* argv[])
138 { 139 {
139 vector<entry_type> entries; 140 vector<EntryType> entries;
140 vector<entry_type> oldentries; 141 vector<EntryType> oldentries;
141 read_cfgentries (argv[argc - 1], oldentries, "CODEGEN_CACHE"); 142 ReadConfigEntries (argv[argc - 1], oldentries, "CODEGEN_CACHE");
142 143
143 for (int arg = 1; arg < argc - 1; ++arg) 144 for (int arg = 1; arg < argc - 1; ++arg)
144 read_cfgentries (argv[arg], entries, "CFGENTRY"); 145 ReadConfigEntries (argv[arg], entries, "CFGENTRY");
145 146
146 if (check_equality (entries, oldentries)) 147 if (CheckEquality (entries, oldentries))
147 { 148 {
148 cout << "Configuration options unchanged" << endl; 149 cout << "Configuration options unchanged" << endl;
149 } 150 return 0;
150 else
151 {
152 std::ofstream os (argv[argc - 1]);
153 os << "#pragma once" << endl;
154 os << "#define CODEGEN_CACHE(A,B,C)" << endl;
155
156 for (vector<entry_type>::const_iterator it = entries.begin(); it != entries.end(); ++it)
157 os << "CODEGEN_CACHE (" << it->type << ", " << it->name << ", " << it->defvalue << ")" << endl;
158
159 os << endl;
160 for (vector<entry_type>::const_iterator it = entries.begin(); it != entries.end(); ++it)
161 os << "EXTERN_CFGENTRY (" << it->type << ", " << it->name << ")" << endl;
162
163 os << endl;
164 os << "static void InitConfigurationEntry (AbstractConfigEntry* entry);" << endl;
165 os << "static void SetupConfigurationLists()" << endl;
166 os << "{" << endl;
167
168 for (vector<entry_type>::const_iterator it = entries.begin(); it != entries.end(); ++it)
169 {
170 os << "\tInitConfigurationEntry (new " << it->type << "ConfigEntry (&cfg::" <<
171 it->name << ", \"" << it->name << "\", " << it->defvalue << "));" << endl;
172 }
173
174 os << "}" << endl;
175
176 cout << "Wrote configuration options list to " << argv[argc - 1] << "." << endl;
177 } 151 }
178 152
153 std::ofstream os (argv[argc - 1]);
154 os << "#pragma once" << endl;
155 os << "#define CODEGEN_CACHE(A,B,C)" << endl;
156
157 for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it)
158 {
159 os << "CODEGEN_CACHE (" << it->type << ", " << it->name << ", " <<
160 it->defvalue << ")" << endl;
161 }
162
163 os << endl;
164 for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it)
165 os << "EXTERN_CFGENTRY (" << it->type << ", " << it->name << ")" << endl;
166
167 os << endl;
168 os << "static void InitConfigurationEntry (AbstractConfigEntry* entry);" << endl;
169 os << "static void SetupConfigurationLists()" << endl;
170 os << "{" << endl;
171
172 for (vector<EntryType>::const_iterator it = entries.begin(); it != entries.end(); ++it)
173 {
174 os << "\tInitConfigurationEntry (new " << it->type << "ConfigEntry (&cfg::" <<
175 it->name << ", \"" << it->name << "\", " << it->defvalue << "));" << endl;
176 }
177
178 os << "}" << endl;
179 cout << "Wrote configuration options list to " << argv[argc - 1] << "." << endl;
179 return 0; 180 return 0;
180 } 181 }

mercurial