Merge branch 'corvuscorax/OP-1456_struct_to_array_improvement' into next
[librepilot.git] / ground / uavobjgenerator / main.cpp
blob55de04f3dac1da3a61429806f5ae0dac912e258e
1 /**
2 ******************************************************************************
4 * @file main.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
6 * @brief UAVObjectGenerator main.
8 * @see The GNU Public License (GPL) Version 3
10 *****************************************************************************/
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <QtCore/QCoreApplication>
27 #include <QFile>
28 #include <QString>
29 #include <QStringList>
30 #include <iostream>
32 #include "generators/java/uavobjectgeneratorjava.h"
33 #include "generators/flight/uavobjectgeneratorflight.h"
34 #include "generators/gcs/uavobjectgeneratorgcs.h"
35 #include "generators/matlab/uavobjectgeneratormatlab.h"
36 #include "generators/python/uavobjectgeneratorpython.h"
37 #include "generators/wireshark/uavobjectgeneratorwireshark.h"
39 #define RETURN_ERR_USAGE 1
40 #define RETURN_ERR_XML 2
41 #define RETURN_OK 0
43 using namespace std;
45 /**
46 * print usage info
48 void usage()
50 cout << "Usage: uavobjectgenerator [-gcs] [-flight] [-java] [-python] [-matlab] [-wireshark] [-none] [-v] xml_path template_base [UAVObj1] ... [UAVObjN]" << endl;
51 cout << "Languages: " << endl;
52 cout << "\t-gcs build groundstation code" << endl;
53 cout << "\t-flight build flight code" << endl;
54 cout << "\t-java build java code" << endl;
55 cout << "\t-python build python code" << endl;
56 cout << "\t-matlab build matlab code" << endl;
57 cout << "\t-wireshark build wireshark plugin" << endl;
58 cout << "\tIf no language is specified ( and not -none ) -> all are built." << endl;
59 cout << "Misc: " << endl;
60 cout << "\t-none build no language - just parse xml's" << endl;
61 cout << "\t-h this help" << endl;
62 cout << "\t-v verbose" << endl;
63 cout << "\tinput_path path to UAVObject definition (.xml) files." << endl;
64 cout << "\ttemplate_path path to the root of the OpenPilot source tree." << endl;
65 cout << "\tUAVObjXY name of a specific UAVObject to be built." << endl;
66 cout << "\tIf any specific UAVObjects are given only these will be built." << endl;
67 cout << "\tIf no UAVObject is specified -> all are built." << endl;
70 /**
71 * inform user of invalid usage
73 int usage_err()
75 cout << "Invalid usage!" << endl;
76 usage();
77 return RETURN_ERR_USAGE;
80 /**
81 * entrance
83 int main(int argc, char *argv[])
85 QCoreApplication a(argc, argv);
87 cout << "- OpenPilot UAVObject Generator -" << endl;
89 QString inputpath;
90 QString templatepath;
91 QString outputpath;
92 QStringList arguments_stringlist;
93 QStringList objects_stringlist;
95 // process arguments
96 for (int argi = 1; argi < argc; argi++) {
97 arguments_stringlist << argv[argi];
100 if ((arguments_stringlist.removeAll("-h") > 0) || (arguments_stringlist.removeAll("-h") > 0)) {
101 usage();
102 return RETURN_OK;
105 bool verbose = (arguments_stringlist.removeAll("-v") > 0);
106 bool do_gcs = (arguments_stringlist.removeAll("-gcs") > 0);
107 bool do_flight = (arguments_stringlist.removeAll("-flight") > 0);
108 bool do_java = (arguments_stringlist.removeAll("-java") > 0);
109 bool do_python = (arguments_stringlist.removeAll("-python") > 0);
110 bool do_matlab = (arguments_stringlist.removeAll("-matlab") > 0);
111 bool do_wireshark = (arguments_stringlist.removeAll("-wireshark") > 0);
112 bool do_none = (arguments_stringlist.removeAll("-none") > 0); //
114 bool do_all = ((do_gcs || do_flight || do_java || do_python || do_matlab) == false);
115 bool do_allObjects = true;
117 if (arguments_stringlist.length() >= 2) {
118 inputpath = arguments_stringlist.at(0);
119 templatepath = arguments_stringlist.at(1);
120 } else {
121 // wrong number of arguments
122 return usage_err();
124 if (arguments_stringlist.length() > 2) {
125 do_allObjects = false;
126 for (int argi = 2; argi < arguments_stringlist.length(); argi++) {
127 objects_stringlist << (arguments_stringlist.at(argi).toLower() + ".xml");
131 if (!inputpath.endsWith("/")) {
132 inputpath.append("/"); // append a slash if it is not there
134 if (!templatepath.endsWith("/")) {
135 templatepath.append("/"); // append a slash if it is not there
137 // put all output files in the current directory
138 outputpath = QString("./");
140 QDir xmlPath = QDir(inputpath);
141 UAVObjectParser *parser = new UAVObjectParser();
143 QStringList filters = QStringList("*.xml");
145 xmlPath.setNameFilters(filters);
146 QFileInfoList xmlList = xmlPath.entryInfoList();
148 // Read in each XML file and parse object(s) in them
150 for (int n = 0; n < xmlList.length(); ++n) {
151 QFileInfo fileinfo = xmlList[n];
152 if (!do_allObjects) {
153 if (!objects_stringlist.removeAll(fileinfo.fileName().toLower())) {
154 if (verbose) {
155 cout << "Skipping XML file: " << fileinfo.fileName().toStdString() << endl;
157 continue;
160 if (verbose) {
161 cout << "Parsing XML file: " << fileinfo.fileName().toStdString() << endl;
163 QString filename = fileinfo.fileName();
164 QString xmlstr = readFile(fileinfo.absoluteFilePath());
166 QString res = parser->parseXML(xmlstr, filename);
168 if (!res.isNull()) {
169 if (!verbose) {
170 cout << "Error in XML file: " << fileinfo.fileName().toStdString() << endl;
172 cout << "Error parsing " << res.toStdString() << endl;
173 return RETURN_ERR_XML;
177 if (objects_stringlist.length() > 0) {
178 cout << "required UAVObject definitions not found! " << objects_stringlist.join(",").toStdString() << endl;
179 return RETURN_ERR_XML;
182 // check for duplicate object ID's
183 QList<quint32> objIDList;
184 int numBytesTotal = 0;
185 for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) {
186 quint32 id = parser->getObjectID(objidx);
187 numBytesTotal += parser->getNumBytes(objidx);
188 if (verbose) {
189 cout << "Checking object " << parser->getObjectName(objidx).toStdString() << " (" << parser->getNumBytes(objidx) << " bytes)" << endl;
191 if (objIDList.contains(id) || id == 0) {
192 cout << "Error: Object ID collision found in object " << parser->getObjectName(objidx).toStdString() << ", modify object name" << endl;
193 return RETURN_ERR_XML;
196 objIDList.append(id);
199 // done parsing and checking
200 cout << "Done: processed " << xmlList.length() << " XML files and generated "
201 << objIDList.length() << " objects with no ID collisions. Total size of the data fields is " << numBytesTotal << " bytes." << endl;
204 if (verbose) {
205 cout << "used units: " << parser->all_units.join(",").toStdString() << endl;
208 if (do_none) {
209 return RETURN_OK;
212 // generate flight code if wanted
213 if (do_flight | do_all) {
214 cout << "generating flight code" << endl;
215 UAVObjectGeneratorFlight flightgen;
216 flightgen.generate(parser, templatepath, outputpath);
219 // generate gcs code if wanted
220 if (do_gcs | do_all) {
221 cout << "generating gcs code" << endl;
222 UAVObjectGeneratorGCS gcsgen;
223 gcsgen.generate(parser, templatepath, outputpath);
226 // generate java code if wanted
227 if (do_java | do_all) {
228 cout << "generating java code" << endl;
229 UAVObjectGeneratorJava javagen;
230 javagen.generate(parser, templatepath, outputpath);
233 // generate python code if wanted
234 if (do_python | do_all) {
235 cout << "generating python code" << endl;
236 UAVObjectGeneratorPython pygen;
237 pygen.generate(parser, templatepath, outputpath);
240 // generate matlab code if wanted
241 if (do_matlab | do_all) {
242 cout << "generating matlab code" << endl;
243 UAVObjectGeneratorMatlab matlabgen;
244 matlabgen.generate(parser, templatepath, outputpath);
247 // generate wireshark plugin if wanted
248 if (do_wireshark | do_all) {
249 cout << "generating wireshark code" << endl;
250 UAVObjectGeneratorWireshark wiresharkgen;
251 wiresharkgen.generate(parser, templatepath, outputpath);
254 return RETURN_OK;