Use new argument parser API

This commit is contained in:
Martchus 2016-06-14 00:47:07 +02:00
parent 53482bb114
commit 66fc779d33
2 changed files with 59 additions and 51 deletions

View File

@ -14,6 +14,10 @@ set(SRC_FILES
utils.cpp utils.cpp
) )
set(DOC_FILES
README.md
)
# meta data # meta data
set(META_PROJECT_NAME geocoordinatecalculator) set(META_PROJECT_NAME geocoordinatecalculator)
set(META_APP_NAME "Geo coordinate calculator") set(META_APP_NAME "Geo coordinate calculator")
@ -22,11 +26,11 @@ set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
set(META_APP_DESCRIPTION "Command line tool for basic calculations with geo coordinates such as format conversions and calculation of distance, bearing, mid point, destination and more.") set(META_APP_DESCRIPTION "Command line tool for basic calculations with geo coordinates such as format conversions and calculation of distance, bearing, mid point, destination and more.")
set(META_VERSION_MAJOR 1) set(META_VERSION_MAJOR 1)
set(META_VERSION_MINOR 1) set(META_VERSION_MINOR 1)
set(META_VERSION_PATCH 1) set(META_VERSION_PATCH 2)
set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}) set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH})
# find c++utilities # find c++utilities
find_package(c++utilities 3.3.0 REQUIRED) find_package(c++utilities 4.0.0 REQUIRED)
use_cpp_utilities() use_cpp_utilities()
# include modules to apply configuration # include modules to apply configuration

102
main.cpp
View File

@ -27,118 +27,122 @@ int main(int argc, char *argv[])
ArgumentParser argparser; ArgumentParser argparser;
Argument convert("convert", "c", "Converts the given coordinate or location to the specified output form."); Argument convert("convert", 'c', "Converts the given coordinate or location to the specified output form.");
convert.setRequiredValueCount(1); convert.setRequiredValueCount(1);
convert.appendValueName("coordinate/location"); convert.appendValueName("coordinate/location");
Argument distance("distance", "d", "Computes the approximate distance in meters between two locations."); Argument distance("distance", 'd', "Computes the approximate distance in meters between two locations.");
distance.setRequiredValueCount(2); distance.setRequiredValueCount(2);
distance.appendValueName("location 1"); distance.appendValueName("location 1");
distance.appendValueName("location 2"); distance.appendValueName("location 2");
Argument trackLength("track-length", "t", "Computes the approximate length in meters of a track given by a file containing trackpoints separated by new lines."); Argument trackLength("track-length", 't', "Computes the approximate length in meters of a track given by a file containing trackpoints separated by new lines.");
trackLength.setRequiredValueCount(1); Argument fileArg("file", 'f', "Specifies the file containing the track points");
trackLength.appendValueName("path"); fileArg.setRequiredValueCount(1);
Argument circle("circle", "", "If present the distance between the first and the last trackpoints will be added to the total track length."); fileArg.appendValueName("path");
trackLength.setSecondaryArguments({&circle}); fileArg.setRequired(true);
Argument circle("circle", '\0', "If present the distance between the first and the last trackpoints will be added to the total track length.");
trackLength.setSubArguments({&fileArg, &circle});
Argument bearing("bearing", "b", "Computes the approximate initial bearing East of true North when traveling along the shortest path between the given locations."); Argument bearing("bearing", 'b', "Computes the approximate initial bearing East of true North when traveling along the shortest path between the given locations.");
bearing.setRequiredValueCount(2); bearing.setRequiredValueCount(2);
bearing.appendValueName("location 1"); bearing.appendValueName("location 1");
bearing.appendValueName("location 2"); bearing.appendValueName("location 2");
Argument fbearing("final-bearing", string(), "Computes the approximate final bearing East of true North when traveling along the shortest path between the given locations."); Argument fbearing("final-bearing", '\0', "Computes the approximate final bearing East of true North when traveling along the shortest path between the given locations.");
fbearing.setRequiredValueCount(2); fbearing.setRequiredValueCount(2);
fbearing.appendValueName("location 1"); fbearing.appendValueName("location 1");
fbearing.appendValueName("location 2"); fbearing.appendValueName("location 2");
Argument midpoint("midpoint", "m", "Computes the approximate midpoint between the given locations."); Argument midpoint("midpoint", 'm', "Computes the approximate midpoint between the given locations.");
midpoint.setRequiredValueCount(2); midpoint.setRequiredValueCount(2);
midpoint.appendValueName("location 1"); midpoint.appendValueName("location 1");
midpoint.appendValueName("location 2"); midpoint.appendValueName("location 2");
Argument destination("destination", string(), "Calculates destination point given distance and bearing from start point."); Argument destination("destination", '\0', "Calculates destination point given distance and bearing from start point.");
destination.setRequiredValueCount(3); destination.setRequiredValueCount(3);
destination.appendValueName("start"); destination.appendValueName("start");
destination.appendValueName("distance"); destination.appendValueName("distance");
destination.appendValueName("bearing"); destination.appendValueName("bearing");
Argument gmapsLink("gmaps-link", "", "Generates a Google Maps link for all locations given by a file containing locations separated by new lines."); Argument gmapsLink("gmaps-link", '\0', "Generates a Google Maps link for all locations given by a file containing locations separated by new lines.");
gmapsLink.setRequiredValueCount(1); gmapsLink.setRequiredValueCount(1);
gmapsLink.appendValueName("path"); gmapsLink.appendValueName("path");
Argument inputAngularMeasureArg("input-angular-measure", "i", "Use this option to specify the angular measure you use to provide angles (degree or radian; default is degree)."); Argument inputAngularMeasureArg("input-angular-measure", 'i', "Use this option to specify the angular measure you use to provide angles (degree or radian; default is degree).");
inputAngularMeasureArg.setRequiredValueCount(1); inputAngularMeasureArg.setRequiredValueCount(1);
inputAngularMeasureArg.appendValueName("angular measure"); inputAngularMeasureArg.appendValueName("angular measure");
inputAngularMeasureArg.setCombinable(true); inputAngularMeasureArg.setCombinable(true);
Argument outputFormForAnglesArg("output-angle-form", "o", "Use this option to specify the output form for angles (degrees, minutes, seconds or radians; default is degrees)."); Argument outputFormForAnglesArg("output-angle-form", 'o', "Use this option to specify the output form for angles (degrees, minutes, seconds or radians; default is degrees).");
outputFormForAnglesArg.setRequiredValueCount(1); outputFormForAnglesArg.setRequiredValueCount(1);
outputFormForAnglesArg.appendValueName("form"); outputFormForAnglesArg.appendValueName("form");
outputFormForAnglesArg.setCombinable(true); outputFormForAnglesArg.setCombinable(true);
Argument inputSystemForLocationsArg("input-location-system", string(), "Use this option to specify the geographic system you use to provide locations (latitude&longitue or UTM-WGS84)."); Argument inputSystemForLocationsArg("input-location-system", '\0', "Use this option to specify the geographic system you use to provide locations (latitude&longitue or UTM-WGS84).");
inputSystemForLocationsArg.setRequiredValueCount(1); inputSystemForLocationsArg.setRequiredValueCount(1);
inputSystemForLocationsArg.appendValueName("system"); inputSystemForLocationsArg.appendValueName("system");
inputSystemForLocationsArg.setCombinable(true); inputSystemForLocationsArg.setCombinable(true);
Argument outputSystemForLocationsArg("output-location-system", string(), "Use this option to specify which geographic system is used to display locations (latitude&longitue or UTM-WGS84)."); Argument outputSystemForLocationsArg("output-location-system", '\0', "Use this option to specify which geographic system is used to display locations (latitude&longitue or UTM-WGS84).");
outputSystemForLocationsArg.setRequiredValueCount(1); outputSystemForLocationsArg.setRequiredValueCount(1);
outputSystemForLocationsArg.appendValueName("system"); outputSystemForLocationsArg.appendValueName("system");
outputSystemForLocationsArg.setCombinable(true); outputSystemForLocationsArg.setCombinable(true);
HelpArgument help(argparser); HelpArgument help(argparser);
Argument version("version", "v", "Shows the version of this application."); Argument version("version", 'v', "Shows the version of this application.");
argparser.setMainArguments({&help, &convert, &distance, &trackLength, &bearing, &fbearing, &midpoint, &destination, &gmapsLink, &inputAngularMeasureArg, &outputFormForAnglesArg, &inputSystemForLocationsArg, &outputSystemForLocationsArg, &version});
argparser.setMainArguments({&convert, &distance, &trackLength, &bearing, &fbearing, &midpoint, &destination, &gmapsLink, &help, &version, &inputAngularMeasureArg, &outputFormForAnglesArg, &inputSystemForLocationsArg, &outputSystemForLocationsArg});
argparser.parseArgs(argc, argv); argparser.parseArgs(argc, argv);
if(inputAngularMeasureArg.isPresent()) { if(inputAngularMeasureArg.isPresent()) {
if(inputAngularMeasureArg.value(0) == "radian") { const char *inputFormat = inputAngularMeasureArg.values().front();
if(!strcmp(inputFormat, "radian")) {
inputAngularMeasure = Angle::AngularMeasure::Radian; inputAngularMeasure = Angle::AngularMeasure::Radian;
} else if(inputAngularMeasureArg.value(0) == "degree") { } else if(!strcmp(inputFormat, "degree")) {
inputAngularMeasure = Angle::AngularMeasure::Degree; inputAngularMeasure = Angle::AngularMeasure::Degree;
} else { } else {
cout << "Invalid angular measure given, see --help." << endl; cerr << "Invalid angular measure given, see --help." << endl;
return 0; return 0;
} }
} }
if(outputFormForAnglesArg.isPresent()) { if(outputFormForAnglesArg.isPresent()) {
if(outputFormForAnglesArg.value(0) == "degrees") { const char *outputFormat = outputFormForAnglesArg.values().front();
if(!strcmp(outputFormat, "degrees")) {
outputFormForAngles = Angle::OutputForm::Degrees; outputFormForAngles = Angle::OutputForm::Degrees;
} else if(outputFormForAnglesArg.value(0) == "minutes") { } else if(!strcmp(outputFormat, "minutes")) {
outputFormForAngles = Angle::OutputForm::Minutes; outputFormForAngles = Angle::OutputForm::Minutes;
} else if(outputFormForAnglesArg.value(0) == "seconds") { } else if(!strcmp(outputFormat, "seconds")) {
outputFormForAngles = Angle::OutputForm::Seconds; outputFormForAngles = Angle::OutputForm::Seconds;
} else if(outputFormForAnglesArg.value(0) == "radians") { } else if(!strcmp(outputFormat, "radians")) {
outputFormForAngles = Angle::OutputForm::Radians; outputFormForAngles = Angle::OutputForm::Radians;
} else { } else {
cout << "Invalid output form for angles given, see --help." << endl; cerr << "Invalid output form for angles given, see --help." << endl;
return 0; return 0;
} }
} }
if(inputSystemForLocationsArg.isPresent()) { if(inputSystemForLocationsArg.isPresent()) {
if(inputSystemForLocationsArg.value(0) == "latitude&longitue") { const char *inputFormat = inputSystemForLocationsArg.values().front();
if(!strcmp(inputFormat, "latitude&longitue")) {
inputSystemForLocations = SystemForLocations::LatitudeLongitude; inputSystemForLocations = SystemForLocations::LatitudeLongitude;
} else if(inputSystemForLocationsArg.value(0) == "UTM-WGS84") { } else if(!strcmp(inputFormat, "UTM-WGS84")) {
inputSystemForLocations = SystemForLocations::UTMWGS84; inputSystemForLocations = SystemForLocations::UTMWGS84;
} else { } else {
cout << "Invalid geographic coordinate system given, see --help." << endl; cerr << "Invalid geographic coordinate system given, see --help." << endl;
return 0; return 0;
} }
} }
if(outputSystemForLocationsArg.isPresent()) { if(outputSystemForLocationsArg.isPresent()) {
if(outputSystemForLocationsArg.value(0) == "latitude&longitue") { const char *outputSystem = outputSystemForLocationsArg.values().front();
if(!strcmp(outputSystem, "latitude&longitue")) {
outputSystemForLocations = SystemForLocations::LatitudeLongitude; outputSystemForLocations = SystemForLocations::LatitudeLongitude;
} else if(outputSystemForLocationsArg.value(0) == "UTM-WGS84") { } else if(!strcmp(outputSystem, "UTM-WGS84")) {
outputSystemForLocations = SystemForLocations::UTMWGS84; outputSystemForLocations = SystemForLocations::UTMWGS84;
} else { } else {
cout << "Invalid geographic coordinate system given, see --help." << endl; cerr << "Invalid geographic coordinate system given, see --help." << endl;
return 0; return 0;
} }
} }
@ -150,31 +154,31 @@ int main(int argc, char *argv[])
} else if(version.isPresent()) { } else if(version.isPresent()) {
cout << APP_VERSION; cout << APP_VERSION;
} else if(convert.isPresent()) { } else if(convert.isPresent()) {
printConversion(convert.value(0)); printConversion(convert.values().front());
} else if(distance.isPresent()) { } else if(distance.isPresent()) {
printDistance(distance.value(0), distance.value(1)); printDistance(distance.values()[0], distance.values()[1]);
} else if(trackLength.isPresent()) { } else if(trackLength.isPresent()) {
printTrackLength(trackLength.value(0), circle.isPresent()); printTrackLength(fileArg.values().front(), circle.isPresent());
} else if(bearing.isPresent()) { } else if(bearing.isPresent()) {
printBearing(bearing.value(0), bearing.value(1)); printBearing(bearing.values()[0], bearing.values()[1]);
} else if(fbearing.isPresent()) { } else if(fbearing.isPresent()) {
printFinalBearing(fbearing.value(0), fbearing.value(1)); printFinalBearing(fbearing.values()[0], fbearing.values()[1]);
} else if(midpoint.isPresent()) { } else if(midpoint.isPresent()) {
printMidpoint(midpoint.value(0), midpoint.value(1)); printMidpoint(midpoint.values()[0], midpoint.values()[1]);
} else if(destination.isPresent()) { } else if(destination.isPresent()) {
printDestination(destination.value(0), destination.value(1), destination.value(2)); printDestination(destination.values()[0], destination.values()[1], destination.values()[2]);
} else if(gmapsLink.isPresent()) { } else if(gmapsLink.isPresent()) {
printMapsLink(gmapsLink.value(0)); printMapsLink(gmapsLink.values().front());
} else { } else {
cout << "No arguments given. See --help for available commands."; cerr << "No arguments given. See --help for available commands.";
} }
} catch(Failure &ex) { } catch(const Failure &ex) {
cout << "The provided locations/coordinates couldn't be parsed correctly. " << ex.what() << endl; cerr << "The provided locations/coordinates couldn't be parsed correctly. " << ex.what() << endl;
cout << endl; cerr << endl;
printAngleFormatInfo(cout); printAngleFormatInfo(cerr);
} }
} catch(Failure &ex) { } catch(const Failure &ex) {
cout << "Unable to parse arguments. " << ex.what() << endl << "See --help for available commands."; cerr << "Unable to parse arguments. " << ex.what() << endl << "See --help for available commands.";
} }
cout << endl; cout << endl;