1// Aseprite Code Generator
2// Copyright (c) 2021 Igara Studio S.A.
3// Copyright (c) 2014-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#include "base/file_handle.h"
9#include "base/fs.h"
10#include "base/program_options.h"
11#include "base/string.h"
12#include "gen/check_strings.h"
13#include "gen/check_strings.h"
14#include "gen/pref_types.h"
15#include "gen/strings_class.h"
16#include "gen/theme_class.h"
17#include "gen/ui_class.h"
18#include "tinyxml.h"
19
20#include <iostream>
21#include <memory>
22
23typedef base::ProgramOptions PO;
24
25static void run(int argc, const char* argv[])
26{
27 PO po;
28 PO::Option& inputOpt = po.add("input").requiresValue("<filename>");
29 PO::Option& widgetId = po.add("widgetid").requiresValue("<id>");
30 PO::Option& prefH = po.add("pref-h");
31 PO::Option& prefCpp = po.add("pref-cpp");
32 PO::Option& theme = po.add("theme");
33 PO::Option& strings = po.add("strings");
34 PO::Option& commandIds = po.add("command-ids");
35 PO::Option& widgetsDir = po.add("widgets-dir").requiresValue("<dir>");
36 PO::Option& stringsDir = po.add("strings-dir").requiresValue("<dir>");
37 PO::Option& guiFile = po.add("gui-file").requiresValue("<filename>");
38 po.parse(argc, argv);
39
40 // Try to load the XML file
41 std::unique_ptr<TiXmlDocument> doc;
42
43 std::string inputFilename = po.value_of(inputOpt);
44 if (!inputFilename.empty() &&
45 base::get_file_extension(inputFilename) == "xml") {
46 base::FileHandle inputFile(base::open_file(inputFilename, "rb"));
47 doc.reset(new TiXmlDocument);
48 doc->SetValue(inputFilename.c_str());
49 if (!doc->LoadFile(inputFile.get())) {
50 std::cerr << doc->Value() << ":"
51 << doc->ErrorRow() << ":"
52 << doc->ErrorCol() << ": "
53 << "error " << doc->ErrorId() << ": "
54 << doc->ErrorDesc() << "\n";
55
56 throw std::runtime_error("invalid input file");
57 }
58 }
59
60 if (doc) {
61 // Generate widget class
62 if (po.enabled(widgetId))
63 gen_ui_class(doc.get(), inputFilename, po.value_of(widgetId));
64 // Generate preference header file
65 else if (po.enabled(prefH))
66 gen_pref_header(doc.get(), inputFilename);
67 // Generate preference c++ file
68 else if (po.enabled(prefCpp))
69 gen_pref_impl(doc.get(), inputFilename);
70 // Generate theme class
71 else if (po.enabled(theme))
72 gen_theme_class(doc.get(), inputFilename);
73 }
74 // Generate strings.ini.h file
75 else if (po.enabled(strings)) {
76 gen_strings_class(inputFilename);
77 }
78 // Generate command_ids.ini.h file
79 else if (po.enabled(commandIds)) {
80 gen_command_ids(inputFilename);
81 }
82 // Check all translation files (en.ini, es.ini, etc.)
83 else if (po.enabled(widgetsDir) &&
84 po.enabled(stringsDir)) {
85 check_strings(po.value_of(widgetsDir),
86 po.value_of(stringsDir),
87 po.value_of(guiFile));
88 }
89}
90
91int main(int argc, const char* argv[])
92{
93 try {
94 run(argc, argv);
95 return 0;
96 }
97 catch (const std::exception& e) {
98 std::cerr << e.what() << "\n";
99 return 1;
100 }
101}
102