/** ****************************************************************************** * * @file main.cpp * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2017. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief UAVObjectGenerator main. * * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "generators/java/uavobjectgeneratorjava.h" #include "generators/flight/uavobjectgeneratorflight.h" #include "generators/arduino/uavobjectgeneratorarduino.h" #include "generators/gcs/uavobjectgeneratorgcs.h" #include "generators/matlab/uavobjectgeneratormatlab.h" #include "generators/python/uavobjectgeneratorpython.h" #include "generators/wireshark/uavobjectgeneratorwireshark.h" #define RETURN_ERR_USAGE 1 #define RETURN_ERR_XML 2 #define RETURN_OK 0 using namespace std; /** * print usage info */ void usage() { cout << "Usage: uavobjectgenerator [language] [-v] xml_path template_base [UAVObj1] ... [UAVObjN]" << endl; cout << "Languages: " << endl; cout << "\t-gcs build groundstation code" << endl; cout << "\t-flight build flight code" << endl; cout << "\t-arduino build arduino code" << endl; cout << "\t-java build java code" << endl; cout << "\t-python build python code" << endl; cout << "\t-matlab build matlab code" << endl; cout << "\t-wireshark build wireshark plugin" << endl; cout << "\tIf no language is specified none are built - just parse xmls." << endl; cout << "Misc: " << endl; cout << "\t-h or --help this help" << endl; cout << "\t-v verbose" << endl; cout << "\tinput_path path to UAVObject definition (.xml) files." << endl; cout << "\ttemplate_path path to the root of the source tree." << endl; cout << "\tUAVObjXY name of a specific UAVObject to be built." << endl; cout << "\tIf any specific UAVObjects are given only these will be built." << endl; cout << "\tIf no UAVObject is specified -> all are built." << endl; } /** * inform user of invalid usage */ int usage_err() { cout << "Invalid usage!" << endl; usage(); return RETURN_ERR_USAGE; } /** * entrance */ int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); cout << "- LibrePilot UAVObject Generator -" << endl; QString inputpath; QString templatepath; QString outputpath; QStringList arguments_stringlist; QStringList objects_stringlist; // process arguments for (int argi = 1; argi < argc; argi++) { arguments_stringlist << argv[argi]; } if ((arguments_stringlist.removeAll("-h") > 0) || (arguments_stringlist.removeAll("--help") > 0)) { usage(); return RETURN_OK; } bool verbose = (arguments_stringlist.removeAll("-v") > 0); bool do_gcs = (arguments_stringlist.removeAll("-gcs") > 0); bool do_flight = (arguments_stringlist.removeAll("-flight") > 0); bool do_arduino = (arguments_stringlist.removeAll("-arduino") > 0); bool do_java = (arguments_stringlist.removeAll("-java") > 0); bool do_python = (arguments_stringlist.removeAll("-python") > 0); bool do_matlab = (arguments_stringlist.removeAll("-matlab") > 0); bool do_wireshark = (arguments_stringlist.removeAll("-wireshark") > 0); bool do_allObjects = true; if (arguments_stringlist.length() >= 2) { inputpath = arguments_stringlist.at(0); templatepath = arguments_stringlist.at(1); } else { // wrong number of arguments return usage_err(); } if (arguments_stringlist.length() > 2) { do_allObjects = false; for (int argi = 2; argi < arguments_stringlist.length(); argi++) { objects_stringlist << (arguments_stringlist.at(argi).toLower() + ".xml"); } } if (!inputpath.endsWith("/")) { inputpath.append("/"); // append a slash if it is not there } if (!templatepath.endsWith("/")) { templatepath.append("/"); // append a slash if it is not there } // put all output files in the current directory outputpath = QString("./"); QDir xmlPath = QDir(inputpath); UAVObjectParser *parser = new UAVObjectParser(); QStringList filters = QStringList("*.xml"); xmlPath.setNameFilters(filters); QFileInfoList xmlList = xmlPath.entryInfoList(); // Read in each XML file and parse object(s) in them for (int n = 0; n < xmlList.length(); ++n) { QFileInfo fileinfo = xmlList[n]; if (!do_allObjects) { if (!objects_stringlist.removeAll(fileinfo.fileName().toLower())) { if (verbose) { cout << "Skipping XML file: " << fileinfo.fileName().toStdString() << endl; } continue; } } if (verbose) { cout << "Parsing XML file: " << fileinfo.fileName().toStdString() << endl; } QString filename = fileinfo.fileName(); QString xmlstr = readFile(fileinfo.absoluteFilePath()); QString res = parser->parseXML(xmlstr, filename); if (!res.isNull()) { if (!verbose) { cout << "Error in XML file: " << fileinfo.fileName().toStdString() << endl; } cout << "Error parsing " << res.toStdString() << endl; return RETURN_ERR_XML; } } if (objects_stringlist.length() > 0) { cout << "required UAVObject definitions not found! " << objects_stringlist.join(",").toStdString() << endl; return RETURN_ERR_XML; } // check for duplicate object ID's QList objIDList; int numBytesTotal = 0; for (int objidx = 0; objidx < parser->getNumObjects(); ++objidx) { quint32 id = parser->getObjectID(objidx); numBytesTotal += parser->getNumBytes(objidx); if (verbose) { cout << "Checking object " << parser->getObjectName(objidx).toStdString() << " (" << parser->getNumBytes(objidx) << " bytes)" << endl; } if (objIDList.contains(id) || id == 0) { cout << "Error: Object ID collision found in object " << parser->getObjectName(objidx).toStdString() << ", modify object name" << endl; return RETURN_ERR_XML; } objIDList.append(id); } // done parsing and checking cout << "Done: processed " << xmlList.length() << " XML files and generated " << objIDList.length() << " objects with no ID collisions. Total size of the data fields is " << numBytesTotal << " bytes." << endl; if (verbose) { cout << "used units: " << parser->all_units.join(",").toStdString() << endl; } if (do_flight) { // generate flight code if wanted cout << "generating flight code" << endl; UAVObjectGeneratorFlight flightgen; flightgen.generate(parser, templatepath, outputpath); } else if (do_arduino) { // generate arduino code if wanted cout << "generating arduino code" << endl; UAVObjectGeneratorArduino arduinogen; arduinogen.generate(parser, templatepath, outputpath); } else if (do_gcs) { // generate gcs code if wanted cout << "generating gcs code" << endl; UAVObjectGeneratorGCS gcsgen; gcsgen.generate(parser, templatepath, outputpath); } else if (do_java) { // generate java code if wanted cout << "generating java code" << endl; UAVObjectGeneratorJava javagen; javagen.generate(parser, templatepath, outputpath); } else if (do_python) { // generate python code if wanted cout << "generating python code" << endl; UAVObjectGeneratorPython pygen; pygen.generate(parser, templatepath, outputpath); } else if (do_matlab) { // generate matlab code if wanted cout << "generating matlab code" << endl; UAVObjectGeneratorMatlab matlabgen; matlabgen.generate(parser, templatepath, outputpath); } else if (do_wireshark) { // generate wireshark plugin if wanted cout << "generating wireshark code" << endl; UAVObjectGeneratorWireshark wiresharkgen; wiresharkgen.generate(parser, templatepath, outputpath); } return RETURN_OK; }