Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include "parser.hpp"
10 :
11 : #include <algorithm>
12 : #include <fstream>
13 : #include <iostream>
14 :
15 : #ifndef _WIN32
16 : #include <errno.h>
17 : #include <fcntl.h>
18 : #include <stdio.h>
19 : #include <string.h>
20 : #include <sys/stat.h>
21 : #include <sys/types.h>
22 : #include <unistd.h>
23 : #endif
24 :
25 : using namespace std;
26 :
27 0 : static ostream & printKDBErrors (ostream & os, parse_t & p)
28 : {
29 0 : os << "/*This is an auto-generated file generated by exporterrors. Do not modify it.*/" << endl
30 0 : << endl
31 0 : << "#ifndef KDBERRORS_H" << endl
32 0 : << "#define KDBERRORS_H" << endl
33 0 : << endl
34 0 : << "#include <kdb.h>" << endl
35 0 : << "#include <kdbhelper.h>" << endl
36 0 : << "#include <kdblogger.h>" << endl
37 0 : << "#include <kdbmacros.h>" << endl
38 0 : << "#include <string.h>" << endl
39 0 : << endl
40 0 : << "#ifdef __cplusplus" << endl
41 0 : << "using namespace ckdb;" << endl
42 0 : << "#endif" << endl;
43 0 : os << endl << endl;
44 :
45 0 : for (size_t i = 1; i < p.size (); ++i)
46 : {
47 0 : os << "#define ELEKTRA_SET_" << p[i]["macro"] << "_ERROR(key, text) \\" << endl
48 0 : << "\tdo { ELEKTRA_LOG (\"Add Error " << p[i]["number"] << ": %s\", text); elektraSetError" << p[i]["number"]
49 0 : << "(key, text, __FILE__, ELEKTRA_STRINGIFY(__LINE__), ELEKTRA_STRINGIFY(ELEKTRA_MODULE_NAME)); } while (0)" << endl;
50 0 : os << "#define ELEKTRA_SET_" << p[i]["macro"] << "_ERRORF(key, text, ...) \\" << endl
51 0 : << "\tdo { ELEKTRA_LOG (\"Add Error " << p[i]["number"] << ": \" text, __VA_ARGS__); elektraSetErrorf" << p[i]["number"]
52 0 : << "(key, text, __FILE__, ELEKTRA_STRINGIFY(__LINE__), ELEKTRA_STRINGIFY(ELEKTRA_MODULE_NAME), __VA_ARGS__); } while (0)"
53 0 : << endl;
54 :
55 0 : os << "#define ELEKTRA_ADD_" << p[i]["macro"] << "_WARNING(key, text) \\" << endl
56 0 : << "\tdo { ELEKTRA_LOG (\"Add Warning " << p[i]["number"] << ": %s\", text); elektraAddWarning" << p[i]["number"]
57 0 : << "(key, text, __FILE__, ELEKTRA_STRINGIFY(__LINE__), ELEKTRA_STRINGIFY(ELEKTRA_MODULE_NAME)); } while (0)" << endl;
58 0 : os << "#define ELEKTRA_ADD_" << p[i]["macro"] << "_WARNINGF(key, text, ...) \\" << endl
59 0 : << "\tdo { ELEKTRA_LOG (\"Add Warning " << p[i]["number"] << ": \" text, __VA_ARGS__); elektraAddWarningf"
60 0 : << p[i]["number"]
61 0 : << "(key, text, __FILE__, ELEKTRA_STRINGIFY(__LINE__), ELEKTRA_STRINGIFY(ELEKTRA_MODULE_NAME), __VA_ARGS__); } while (0)"
62 0 : << endl;
63 :
64 0 : os << endl;
65 : }
66 0 : os << endl;
67 :
68 0 : for (size_t i = 1; i < p.size (); ++i)
69 : {
70 0 : if (p[i]["unused"] == "yes")
71 : {
72 : continue;
73 : }
74 :
75 0 : if (p[i]["macro"].empty ())
76 : {
77 0 : throw invalid_argument ("Error with number " + p[i]["number"] + " does not have a mandatory macro.");
78 : }
79 :
80 0 : os << "#define ELEKTRA_WARNING_" << p[i]["macro"] << " \"" << p[i]["number"] << "\"" << endl;
81 0 : os << "#define ELEKTRA_ERROR_" << p[i]["macro"] << " \"" << p[i]["number"] << "\"" << endl;
82 : }
83 :
84 0 : os << endl << endl;
85 :
86 0 : for (size_t i = 1; i < p.size (); ++i)
87 : {
88 :
89 0 : for (int f = 0; f < 2; ++f)
90 : {
91 0 : if (f == 0)
92 : {
93 0 : os << "static inline void elektraAddWarningf" << p[i]["number"] << "(Key *warningKey, const char *reason,"
94 0 : << endl
95 : << " const char *file, const char *line, const char *module, ...) __attribute__ ((format (printf, 2, "
96 0 : "6)));"
97 0 : << endl;
98 0 : os << "static inline void elektraAddWarningf" << p[i]["number"] << "(Key *warningKey, const char *reason,"
99 0 : << endl
100 0 : << " const char *file, const char *line, const char *module, ...)" << endl;
101 : }
102 : else
103 : {
104 0 : os << "static inline void elektraAddWarning" << p[i]["number"] << "(Key *warningKey, const char *reason,"
105 0 : << endl
106 0 : << " const char *file, const char *line, const char *module)" << endl;
107 : }
108 0 : os << "{" << endl
109 0 : << " if (!warningKey) return;" << endl
110 0 : << "" << endl
111 0 : << " char buffer[25] = \"warnings/#00\";buffer[12] = '\\0';" << endl
112 0 : << " const Key *meta = keyGetMeta(warningKey, \"warnings\");" << endl
113 0 : << " if (meta)" << endl
114 0 : << " {" << endl
115 0 : << " buffer[10] = keyString(meta)[0];" << endl
116 0 : << " buffer[11] = keyString(meta)[1];" << endl
117 0 : << " buffer[11]++;" << endl
118 0 : << " if (buffer[11] > '9')" << endl
119 0 : << " {" << endl
120 0 : << " buffer[11] = '0';" << endl
121 0 : << " buffer[10]++;" << endl
122 0 : << " if (buffer[10] > '9') buffer[10] = '0';" << endl
123 0 : << " }" << endl
124 0 : << " keySetMeta(warningKey, \"warnings\", &buffer[10]);" << endl
125 0 : << " } else keySetMeta(warningKey, \"warnings\", \"00\");" << endl
126 0 : << "" << endl
127 0 : << " keySetMeta(warningKey, buffer, \"number description module file line function reason\");" << endl
128 0 : << " strcat(buffer, \"/number\" );" << endl
129 0 : << " keySetMeta(warningKey, buffer, \"" << p[i]["number"] << "\");" << endl
130 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/description\");" << endl
131 0 : << " keySetMeta(warningKey, buffer, \"" << p[i]["description"] << "\");" << endl
132 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/module\");"
133 0 : << endl
134 : // TODO: Not the best implementation, fix if better way is found
135 0 : << " if (strcmp(module, \"ELEKTRA_MODULE_NAME\") == 0) module = \"kdb\";" << endl
136 0 : << " keySetMeta(warningKey, buffer, module);" << endl
137 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/file\");" << endl // should be called sourcefile
138 0 : << " keySetMeta(warningKey, buffer, file);" << endl
139 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/line\");" << endl
140 0 : << " keySetMeta(warningKey, buffer, line);" << endl
141 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/mountpoint\");" << endl
142 0 : << " keySetMeta(warningKey, buffer, keyName(warningKey));" << endl
143 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/configfile\");" << endl
144 0 : << " keySetMeta(warningKey, buffer, keyString(warningKey));" << endl
145 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/reason\");" << endl;
146 0 : if (f == 0)
147 : {
148 0 : os << " va_list arg;" << endl
149 0 : << " va_start(arg, module);" << endl
150 0 : << " char * r = elektraVFormat(reason, arg);" << endl
151 0 : << " keySetMeta(warningKey, buffer, r);" << endl
152 0 : << " elektraFree(r);" << endl
153 0 : << " va_end(arg);" << endl;
154 : }
155 : else
156 : {
157 0 : os << " keySetMeta(warningKey, buffer, reason);" << endl;
158 : }
159 0 : os << "}" << endl << endl;
160 : }
161 :
162 0 : for (int f = 0; f < 2; ++f)
163 : {
164 0 : if (f == 0)
165 : {
166 0 : os << "static inline void elektraSetErrorf" << p[i]["number"] << "(Key *errorKey, const char *reason,"
167 0 : << endl
168 : << " const char *file, const char *line, const char *module, ...) __attribute__ ((format (printf, 2, "
169 0 : "6)));"
170 0 : << endl
171 0 : << "static inline void elektraSetErrorf" << p[i]["number"] << "(Key *errorKey, const char *reason,"
172 0 : << endl
173 0 : << " const char *file, const char *line, const char *module, ...)" << endl;
174 : }
175 : else
176 : {
177 0 : os << "static inline void elektraSetError" << p[i]["number"] << "(Key *errorKey, const char *reason,"
178 0 : << endl
179 0 : << " const char *file, const char *line, const char *module)" << endl;
180 : }
181 0 : os << "{" << endl
182 0 : << " if (!errorKey) return;" << endl
183 0 : << " char buffer[25] = \"warnings/#00\";" << endl
184 0 : << " const Key *meta = keyGetMeta(errorKey, \"error\");" << endl
185 0 : << " if (meta)" << endl
186 0 : << " {" << endl
187 0 : << " const Key *warningMeta = keyGetMeta(errorKey, \"warnings\");" << endl
188 0 : << " if (warningMeta)" << endl
189 0 : << " {" << endl
190 0 : << " buffer[10] = keyString(warningMeta)[0];" << endl
191 0 : << " buffer[11] = keyString(warningMeta)[1];" << endl
192 0 : << " buffer[11]++;" << endl
193 0 : << " if (buffer[11] > '9')" << endl
194 0 : << " {" << endl
195 0 : << " buffer[11] = '0';" << endl
196 0 : << " buffer[10]++;" << endl
197 0 : << " if (buffer[10] > '9') buffer[10] = '0';" << endl
198 0 : << " }" << endl
199 0 : << " keySetMeta(errorKey, \"warnings\", &buffer[10]);" << endl
200 0 : << " } else keySetMeta(errorKey, \"warnings\", \"00\");" << endl
201 : << " keySetMeta(errorKey, buffer, \"number description module file line function "
202 0 : "reason\");"
203 0 : << endl
204 0 : << " strcat(buffer, \"/number\" );" << endl
205 0 : << " keySetMeta(errorKey, buffer, \"" << p[i]["number"] << "\");" << endl
206 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/description\");" << endl
207 0 : << " keySetMeta(errorKey, buffer, \"" << p[i]["description"] << "\");" << endl
208 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/module\");"
209 0 : << endl
210 : // TODO: Not the best implementation, fix if better way is found
211 0 : << " if (strcmp(module, \"ELEKTRA_MODULE_NAME\") == 0) module = \"kdb\";" << endl
212 0 : << " keySetMeta(errorKey, buffer, module);" << endl
213 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/file\");" << endl // should be called sourcefile
214 0 : << " keySetMeta(errorKey, buffer, file);" << endl
215 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/line\");" << endl
216 0 : << " keySetMeta(errorKey, buffer, line);" << endl
217 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/mountpoint\");" << endl
218 0 : << " keySetMeta(errorKey, buffer, keyName(errorKey));" << endl
219 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/configfile\");" << endl
220 0 : << " keySetMeta(errorKey, buffer, keyString(errorKey));" << endl
221 0 : << " buffer[12] = '\\0'; strcat(buffer, \"/reason\");" << endl
222 0 : << " }" << endl
223 0 : << " else" << endl
224 0 : << " {" << endl
225 : << " keySetMeta(errorKey, \"error\", \""
226 : << "number description module file line function reason"
227 0 : << "\");" << endl
228 0 : << " keySetMeta(errorKey, \"error/number\", \"" << p[i]["number"] << "\");" << endl
229 0 : << " keySetMeta(errorKey, \"error/description\", \"" << p[i]["description"] << "\");"
230 0 : << endl
231 : // TODO: Not the best implementation, fix if better way is found
232 0 : << " if (strcmp(module, \"ELEKTRA_MODULE_NAME\") == 0) module = \"kdb\";" << endl
233 0 : << " keySetMeta(errorKey, \"error/module\", module);" << endl
234 : << " keySetMeta(errorKey, \"error/file\", "
235 : << "file"
236 0 : << ");" << endl
237 : << " keySetMeta(errorKey, \"error/line\", "
238 : << "line"
239 0 : << ");" << endl
240 : << " keySetMeta(errorKey, \"error/mountpoint\", "
241 : << "keyName(errorKey)"
242 0 : << ");" << endl
243 : << " keySetMeta(errorKey, \"error/configfile\", "
244 : << "keyString(errorKey)"
245 0 : << ");" << endl
246 0 : << " }" << endl;
247 0 : if (f == 0)
248 : {
249 0 : os << " va_list arg;" << endl
250 0 : << " va_start(arg, module);" << endl
251 0 : << " char * r = elektraVFormat(reason, arg);" << endl
252 0 : << " if (meta)" << endl
253 0 : << " keySetMeta(errorKey, buffer, r);" << endl
254 0 : << " else" << endl
255 : << " keySetMeta(errorKey, \"error/reason\", "
256 : << "r"
257 0 : << ");" << endl
258 0 : << " elektraFree(r);" << endl
259 0 : << " va_end(arg);" << endl;
260 : }
261 : else
262 : {
263 0 : os << " if (meta)" << endl
264 0 : << " keySetMeta(errorKey, buffer, reason);" << endl
265 0 : << " else" << endl
266 0 : << " keySetMeta(errorKey, \"error/reason\", reason);" << endl;
267 : }
268 0 : os << "}" << endl << endl;
269 : }
270 : }
271 :
272 0 : os << "static inline KeySet *elektraErrorSpecification (void)" << endl
273 0 : << "{" << endl
274 0 : << " return ksNew (30," << endl
275 0 : << " keyNew (\"system/elektra/modules/error/specification\"," << endl
276 0 : << " KEY_VALUE, \"the specification of all error codes\", KEY_END)," << endl;
277 0 : for (size_t i = 1; i < p.size (); ++i)
278 : {
279 0 : os << " keyNew (\"system/elektra/modules/error/specification/" << p[i]["number"] << "\"," << endl
280 0 : << " KEY_END)," << endl
281 0 : << " keyNew (\"system/elektra/modules/error/specification/" << p[i]["number"] << "/description\"," << endl
282 0 : << " KEY_VALUE, \"" << p[i]["description"] << "\", KEY_END)," << endl;
283 : // << " keyNew (\"system/elektra/modules/error/specification/" << p[i]["number"] << "/severity\","
284 : //<<
285 : // endl
286 : // << " KEY_VALUE, \"" << p[i]["severity"] << "\", KEY_END)," << endl
287 : // << " keyNew (\"system/elektra/modules/error/specification/" << p[i]["number"] << "/module\"," <<
288 : // endl
289 : // << " KEY_VALUE, \"" << p[i]["module"] << "\", KEY_END)," << endl;
290 : }
291 0 : os << " KS_END);" << endl << "}" << endl;
292 :
293 0 : os << "static inline void elektraTriggerWarnings (const char *nr, Key *parentKey, const char *message)" << endl << "{" << endl;
294 0 : for (size_t i = 1; i < p.size (); ++i)
295 : {
296 0 : os << " if (strcmp(nr, \"" << p[i]["number"] << "\") == 0)" << endl << " {" << endl;
297 0 : os << " ELEKTRA_ADD_" << p[i]["macro"] << "_WARNING (parentKey, message);" << endl
298 0 : << " return;" << endl
299 0 : << " }" << endl;
300 : }
301 0 : os << " ELEKTRA_ADD_INTERNAL_WARNINGF (parentKey, \"Unkown warning code %s\", nr);" << endl << "}" << endl << "" << endl;
302 0 : os << "static inline void elektraTriggerError (const char *nr, Key *parentKey, const char *message)" << endl << "{" << endl;
303 0 : for (size_t i = 1; i < p.size (); ++i)
304 : {
305 0 : os << " if (strcmp(nr, \"" << p[i]["number"] << "\") == 0)" << endl << " {" << endl;
306 0 : os << " ELEKTRA_SET_" << p[i]["macro"] << "_ERROR (parentKey, message);" << endl
307 0 : << " return;" << endl
308 0 : << " }" << endl;
309 : }
310 0 : os << " ELEKTRA_SET_INTERNAL_ERRORF (parentKey, \"Unkown error code %s\", nr);" << endl << "}" << endl;
311 :
312 0 : os << "#endif" << endl;
313 0 : return os;
314 : }
315 :
316 0 : static string macroCaseToPascalCase (const string & s)
317 : {
318 0 : std::string result;
319 0 : result.resize (s.size ());
320 0 : auto upcase = true;
321 0 : std::transform (s.begin (), s.end (), result.begin (), [&upcase](char c) {
322 0 : int x = upcase ? toupper (c) : tolower (c);
323 0 : upcase = c == '_';
324 0 : return x;
325 0 : });
326 0 : result.erase (std::remove (result.begin (), result.end (), '_'), result.end ());
327 0 : return result;
328 : }
329 :
330 0 : static ostream & printHighlevelErrorsHeader (ostream & os, parse_t & p)
331 : {
332 0 : os << "/*This is an auto-generated file generated by exporterrors highlevel. Do not modify it.*/" << endl
333 0 : << endl
334 0 : << "#ifndef ELEKTRA_ERRORS_H" << endl
335 0 : << "#define ELEKTRA_ERRORS_H" << endl
336 0 : << endl
337 0 : << "#include <elektra/error.h>" << endl
338 0 : << "#include <elektra/types.h>" << endl
339 0 : << endl
340 0 : << "#ifdef __cplusplus" << endl
341 0 : << "extern \"C\" {" << endl
342 0 : << "#endif" << endl;
343 :
344 0 : for (size_t i = 1; i < p.size (); ++i)
345 : {
346 0 : const auto & macroName = p[i]["macro"];
347 : os << "#define ELEKTRA_ERROR_" << macroName << "_ERROR(description, ...) elektraError" << macroName
348 0 : << "Error (\"TODO\", __FILE__, __LINE__)" << endl;
349 : os << "#define ELEKTRA_ERROR_ADD_" << macroName << "_WARNING(error, description, ...) elektraErrorAdd" << macroName
350 0 : << "Warning (error, \"TODO\", __FILE__, __LINE__)" << endl;
351 :
352 0 : os << "ElektraError * elektraError" << macroCaseToPascalCase (macroName)
353 0 : << "Error (const char * module, const char * file, kdb_long_t line, const char * description, ...);" << endl;
354 0 : os << "void elektraErrorAdd" << macroCaseToPascalCase (macroName)
355 : << "Warning (ElektraError * error, const char * module, const char * file, kdb_long_t line, const char * description, "
356 0 : "...);"
357 0 : << endl;
358 :
359 0 : os << endl;
360 : }
361 :
362 0 : os << "#ifdef __cplusplus" << endl << "}" << endl << "#endif" << endl;
363 :
364 0 : os << "#endif // ELEKTRA_ERRORS_PRIVATE_H" << endl;
365 0 : os << endl;
366 0 : return os;
367 : }
368 :
369 0 : static ostream & printHighlevelErrorsSource (ostream & os, parse_t & p, const std::string & header)
370 : {
371 0 : os << "/*This is an auto-generated file generated by exporterrors_highlevel. Do not modify it.*/" << endl
372 0 : << endl
373 0 : << "#include <" << header << ">" << endl
374 0 : << "#include <kdbprivate.h>" << endl
375 0 : << "#include <kdbhelper.h>" << endl
376 0 : << "#include <kdberrors.h>" << endl
377 0 : << endl;
378 :
379 : // work-around not needed after new error concept
380 0 : os << "#if defined(__GNUC__)" << endl
381 0 : << "#pragma GCC diagnostic push" << endl
382 0 : << "#pragma GCC diagnostic ignored \"-Wformat\"" << endl
383 0 : << "#endif" << endl
384 0 : << endl;
385 :
386 0 : for (size_t i = 1; i < p.size (); ++i)
387 : {
388 0 : const auto & macroName = p[i]["macro"];
389 :
390 0 : os << "ElektraError * elektraError" << macroCaseToPascalCase (macroName)
391 0 : << "Error (const char * module, const char * file, kdb_long_t line, const char * description, ...) {" << endl
392 0 : << "\tva_list arg;" << endl
393 0 : << "\tva_start (arg, description);" << endl
394 0 : << "\tchar * descriptionText = elektraVFormat (description, arg);" << endl
395 0 : << "\tElektraError * error = elektraErrorCreate (ELEKTRA_ERROR_" << p[i]["macro"]
396 0 : << ", descriptionText, module, file, line);" << endl
397 0 : << "\telektraFree (descriptionText);" << endl
398 0 : << "\tva_end (arg);" << endl
399 0 : << "\treturn error;" << endl
400 0 : << "}" << endl
401 0 : << endl;
402 :
403 0 : os << "void elektraErrorAdd" << macroCaseToPascalCase (macroName)
404 : << "Warning (ElektraError * error, const char * module, const char * file, kdb_long_t line, const char * description, "
405 0 : "...) {"
406 0 : << endl
407 0 : << "\tva_list arg;" << endl
408 0 : << "\tva_start (arg, description);" << endl
409 0 : << "\tchar * descriptionText = elektraVFormat (description, arg);" << endl
410 0 : << "\tElektraError * warning = elektraErrorCreate (ELEKTRA_ERROR_" << p[i]["macro"]
411 0 : << ", descriptionText, module, file, line);" << endl
412 0 : << "\telektraFree (descriptionText);" << endl
413 0 : << "\tva_end (arg);" << endl
414 0 : << "\telektraErrorAddWarning (error, warning);" << endl
415 0 : << "}" << endl
416 0 : << endl;
417 : }
418 :
419 0 : os << "#if defined(__GNUC__)" << endl << "#pragma GCC diagnostic pop" << endl << "#endif" << endl << endl;
420 :
421 0 : return os;
422 : }
423 :
424 : template <typename Func>
425 0 : static int writeFile (parse_t & data, const char * filename, Func printFn)
426 : {
427 0 : std::string tmpfile = filename;
428 : #ifndef _WIN32
429 0 : tmpfile += ".tmp";
430 0 : tmpfile += to_string (getpid ());
431 : #endif
432 : {
433 0 : ofstream fout (tmpfile);
434 0 : if (!fout.is_open ())
435 : {
436 0 : cerr << "Could not open output file " << filename << endl;
437 0 : return 1;
438 : }
439 0 : printFn (fout, data);
440 : }
441 :
442 : #ifndef _WIN32
443 0 : int fd = open (tmpfile.c_str (), O_RDWR);
444 0 : if (fd == -1)
445 : {
446 0 : cerr << "Could not reopen file " << filename << endl;
447 : return 2;
448 : }
449 0 : if (fsync (fd) == -1)
450 : {
451 0 : cerr << "Could not fsync config file " << filename << " because ", strerror (errno);
452 0 : close (fd);
453 : return 3;
454 : }
455 0 : close (fd);
456 :
457 0 : if (rename (tmpfile.c_str (), filename) == -1)
458 : {
459 0 : cerr << "Could not rename file " << tmpfile << " to " << filename << endl;
460 : return 4;
461 : }
462 : #endif
463 : return 0;
464 : }
465 :
466 0 : static void printUsage (const std::string & name)
467 : {
468 : cerr << "Usage " << name << "MODE infile [options]"
469 0 : << "\tMODES:" << endl
470 0 : << "\t\tkdb\t\t options: outfile" << endl
471 0 : << "\t\thighlevel\t\t options: outcodes outpublic outprivate outsource includepublic includeprivate" << endl
472 0 : << "\t\t\t outcodes: outfile for error codes enum" << endl
473 0 : << "\t\t\t outpublic: outfile for public header" << endl
474 0 : << "\t\t\t outprivate: outfile for private header" << endl
475 0 : << "\t\t\t outsource: outfile for source code" << endl
476 0 : << "\t\t\t includepublic: include path (including file name) for public header" << endl
477 0 : << "\t\t\t includeprivate: include path (including file name) for private header" << endl
478 0 : << endl;
479 0 : }
480 :
481 0 : int main (int argc, char ** argv) try
482 : {
483 0 : if (argc < 2)
484 : {
485 0 : printUsage (argv[0]);
486 0 : return 1;
487 : }
488 :
489 0 : std::string mode = argv[1];
490 :
491 0 : if (mode == "kdb")
492 : {
493 0 : switch (argc)
494 : {
495 : case 3:
496 : {
497 0 : string infile = argv[2];
498 0 : parse_t data = parse (infile);
499 0 : printKDBErrors (cout, data);
500 : break;
501 : }
502 : case 4:
503 : {
504 0 : string infile = argv[2];
505 0 : parse_t data = parse (infile);
506 0 : writeFile (data, argv[3], printKDBErrors);
507 : break;
508 : }
509 : default:
510 0 : printUsage (argv[0]);
511 0 : return 1;
512 : }
513 : }
514 0 : else if (mode == "highlevel")
515 : {
516 0 : switch (argc)
517 : {
518 : case 3:
519 : {
520 0 : string infile = argv[2];
521 0 : parse_t data = parse (infile);
522 0 : printHighlevelErrorsHeader (cout, data);
523 0 : cout << endl << endl;
524 0 : printHighlevelErrorsSource (cout, data, "");
525 : break;
526 : }
527 : case 6:
528 : {
529 0 : string infile = argv[2];
530 0 : parse_t data = parse (infile);
531 0 : writeFile (data, argv[3], printHighlevelErrorsHeader);
532 :
533 0 : auto func = [&](ostream & os, parse_t & p) { printHighlevelErrorsSource (os, p, argv[5]); };
534 :
535 0 : writeFile (data, argv[4], func);
536 : break;
537 : }
538 : default:
539 0 : printUsage (argv[0]);
540 :
541 0 : return 1;
542 : }
543 : }
544 : else
545 : {
546 0 : cerr << "Unknown mode" << endl;
547 0 : printUsage (argv[0]);
548 0 : return 1;
549 : }
550 :
551 :
552 : return 0;
553 : }
554 0 : catch (parse_error const & e)
555 : {
556 0 : cerr << "The line " << e.linenr << " caused following parse error: " << e.info << endl;
557 : return 2;
558 0 : }
|