update credits
[librepilot.git] / ground / uavobjgenerator / main.cpp
blob2cb2b8fbf349d68fbb0288c88bbed85ca78c9c00
1 /**
2 ******************************************************************************
4 * @file main.cpp
5 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2017.
6 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
7 * @brief UAVObjectGenerator main.
9 * @see The GNU Public License (GPL) Version 3
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include <QtCore/QCoreApplication>
28 #include <QFile>
29 #include <QString>
30 #include <QStringList>
31 #include <iostream>
33 #include "generators/java/uavobjectgeneratorjava.h"
34 #include "generators/flight/uavobjectgeneratorflight.h"
35 #include "generators/arduino/uavobjectgeneratorarduino.h"
36 #include "generators/gcs/uavobjectgeneratorgcs.h"
37 #include "generators/matlab/uavobjectgeneratormatlab.h"
38 #include "generators/python/uavobjectgeneratorpython.h"
39 #include "generators/wireshark/uavobjectgeneratorwireshark.h"
41 #define RETURN_ERR_USAGE 1
42 #define RETURN_ERR_XML 2
43 #define RETURN_OK 0
45 using namespace std;
47 /**
48 * print usage info
50 void usage()
52 cout << "Usage: uavobjectgenerator [language] [-v] xml_path template_base [UAVObj1] ... [UAVObjN]" << endl;
53 cout << "Languages: " << endl;
54 cout << "\t-gcs build groundstation code" << endl;
55 cout << "\t-flight build flight code" << endl;
56 cout << "\t-arduino build arduino code" << endl;
57 cout << "\t-java build java code" << endl;
58 cout << "\t-python build python code" << endl;
59 cout << "\t-matlab build matlab code" << endl;
60 cout << "\t-wireshark build wireshark plugin" << endl;
61 cout << "\tIf no language is specified none are built - just parse xmls." << endl;
62 cout << "Misc: " << endl;
63 cout << "\t-h or --help this help" << endl;
64 cout << "\t-v verbose" << endl;
65 cout << "\tinput_path path to UAVObject definition (.xml) files." << endl;
66 cout << "\ttemplate_path path to the root of the source tree." << endl;
67 cout << "\tUAVObjXY name of a specific UAVObject to be built." << endl;
68 cout << "\tIf any specific UAVObjects are given only these will be built." << endl;
69 cout << "\tIf no UAVObject is specified -> all are built." << endl;
72 /**
73 * inform user of invalid usage
75 int usage_err()
77 cout << "Invalid usage!" << endl;
78 usage();
79 return RETURN_ERR_USAGE;
82 /**
83 * entrance
85 int main(int argc, char *argv[])
87 QCoreApplication a(argc, argv);
89 cout << "- LibrePilot UAVObject Generator -" << endl;
91 QString inputpath;
92 QString templatepath;
93 QString outputpath;
94 QStringList arguments_stringlist;
95 QStringList objects_stringlist;
97 // process arguments
98 for (int argi = 1; argi < argc; argi++) {
99 arguments_stringlist << argv[argi];
102 if ((arguments_stringlist.removeAll("-h") > 0) || (arguments_stringlist.removeAll("--help") > 0)) {
103 usage();
104 return RETURN_OK;
107 bool verbose = (arguments_stringlist.removeAll("-v") > 0);
108 bool do_gcs = (arguments_stringlist.removeAll("-gcs") > 0);
109 bool do_flight = (arguments_stringlist.removeAll("-flight") > 0);
110 bool do_arduino = (arguments_stringlist.removeAll("-arduino") > 0);
111 bool do_java = (arguments_stringlist.removeAll("-java") > 0);
112 bool do_python = (arguments_stringlist.removeAll("-python") > 0);
113 bool do_matlab = (arguments_stringlist.removeAll("-matlab") > 0);
114 bool do_wireshark = (arguments_stringlist.removeAll("-wireshark") > 0);
116 bool do_allObjects = true;
118 if (arguments_stringlist.length() >= 2) {
119 inputpath = arguments_stringlist.at(0);
120 templatepath = arguments_stringlist.at(1);
121 } else {
122 // wrong number of arguments
123 return usage_err();
125 if (arguments_stringlist.length() > 2) {
126 do_allObjects = false;
127 for (int argi = 2; argi < arguments_stringlist.length(); argi++) {
128 objects_stringlist << (arguments_stringlist.at(argi).toLower() + ".xml");
132 if (!inputpath.endsWith("/")) {
133 inputpath.append("/"); // append a slash if it is not there
135 if (!templatepath.endsWith("/")) {
136 templatepath.append("/"); // append a slash if it is not there
138 // put all output files in the current directory
139 outputpath = QString("./");
141 QDir xmlPath = QDir(inputpath);
142 UAVObjectParser *parser = new UAVObjectParser();
144 QStringList filters = QStringList("*.xml");
146 xmlPath.setNameFilters(filters);
147 QFileInfoList xmlList = xmlPath.entryInfoList();
149 // Read in each XML file and parse object(s) in them
151 for (int n = 0; n < xmlList.length(); ++n) {
152 QFileInfo fileinfo = xmlList[n];
153 if (!do_allObjects) {
154 if (!objects_stringlist.removeAll(fileinfo.fileName().toLower())) {
155 if (verbose) {
156 cout << "Skipping XML file: " << fileinfo.fileName().toStdString() << endl;
158 continue;
161 if (verbose) {
162 cout << "Parsing XML file: " << fileinfo.fileName().toStdString() << endl;
164 QString filename = fileinfo.fileName();
165 QString xmlstr = readFile(fileinfo.absoluteFilePath());
167 QString res = parser->parseXML(xmlstr, filename);
169 if (!res.isNull()) {
170 if (!verbose) {
171 cout << "Error in XML file: " << fileinfo.fileName().toStdString() << endl;
173 cout << "Error parsing " << res.toStdString() << endl;
174 return RETURN_ERR_XML;
178 if (objects_stringlist.length() > 0) {
179 cout << "required UAVObject definitions not found! " << objects_stringlist.join(",").toStdString() << endl;
180 return RETURN_ERR_XML;
183 // check for duplicate object ID's
184 QList<quint32> objIDList;
185 int numBytesTotal = 0;
186 for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) {
187 quint32 id = parser->getObjectID(objidx);
188 numBytesTotal += parser->getNumBytes(objidx);
189 if (verbose) {
190 cout << "Checking object " << parser->getObjectName(objidx).toStdString() << " (" << parser->getNumBytes(objidx) << " bytes)" << endl;
192 if (objIDList.contains(id) || id == 0) {
193 cout << "Error: Object ID collision found in object " << parser->getObjectName(objidx).toStdString() << ", modify object name" << endl;
194 return RETURN_ERR_XML;
197 objIDList.append(id);
200 // done parsing and checking
201 cout << "Done: processed " << xmlList.length() << " XML files and generated "
202 << objIDList.length() << " objects with no ID collisions. Total size of the data fields is " << numBytesTotal << " bytes." << endl;
205 if (verbose) {
206 cout << "used units: " << parser->all_units.join(",").toStdString() << endl;
209 if (do_flight) {
210 // generate flight code if wanted
211 cout << "generating flight code" << endl;
212 UAVObjectGeneratorFlight flightgen;
213 flightgen.generate(parser, templatepath, outputpath);
214 } else if (do_arduino) {
215 // generate arduino code if wanted
216 cout << "generating arduino code" << endl;
217 UAVObjectGeneratorArduino arduinogen;
218 arduinogen.generate(parser, templatepath, outputpath);
219 } else if (do_gcs) {
220 // generate gcs code if wanted
221 cout << "generating gcs code" << endl;
222 UAVObjectGeneratorGCS gcsgen;
223 gcsgen.generate(parser, templatepath, outputpath);
224 } else if (do_java) {
225 // generate java code if wanted
226 cout << "generating java code" << endl;
227 UAVObjectGeneratorJava javagen;
228 javagen.generate(parser, templatepath, outputpath);
229 } else if (do_python) {
230 // generate python code if wanted
231 cout << "generating python code" << endl;
232 UAVObjectGeneratorPython pygen;
233 pygen.generate(parser, templatepath, outputpath);
234 } else if (do_matlab) {
235 // generate matlab code if wanted
236 cout << "generating matlab code" << endl;
237 UAVObjectGeneratorMatlab matlabgen;
238 matlabgen.generate(parser, templatepath, outputpath);
239 } else if (do_wireshark) {
240 // generate wireshark plugin if wanted
241 cout << "generating wireshark code" << endl;
242 UAVObjectGeneratorWireshark wiresharkgen;
243 wiresharkgen.generate(parser, templatepath, outputpath);
246 return RETURN_OK;