From 3ae1f6c19533f24964166ec373e739c82919ae75 Mon Sep 17 00:00:00 2001 From: Gard Spreemann Date: Wed, 24 Oct 2018 13:07:52 +0200 Subject: Proper option parsing. --- src/CMakeLists.txt | 2 +- src/main.cpp | 24 ++++++++++---- src/options.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/options.hpp | 17 ++++++++++ 4 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 src/options.cpp create mode 100644 src/options.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ecff6e3..f6002e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,2 +1,2 @@ -add_executable(lapdog main.cpp) +add_executable(lapdog main.cpp options.cpp) target_link_libraries(lapdog ${MPI_LIBRARIES} ${PETSC_LIBRARIES} ${SLEPC_LIBRARIES}) diff --git a/src/main.cpp b/src/main.cpp index 8d09427..d1dc8b1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,13 +5,22 @@ #include #include +#include "options.hpp" + int main(int argc, char ** argv) { SlepcInitialize(&argc, &argv, NULL, NULL); - std::string infile(argv[1]); - std::string outfile_vals(argv[2]); - std::string outfile_vecs(argv[3]); + Options opts; + int optresult = parse_opts(argc, argv, opts); + if (optresult) + { + SlepcFinalize(); + if (optresult == 2) + exit(0); + else + exit(1); + } PetscMPIInt mpi_rank; PetscMPIInt mpi_size; @@ -19,15 +28,16 @@ int main(int argc, char ** argv) MPI_Comm_size(PETSC_COMM_WORLD, &mpi_size); PetscErrorCode err; + Mat L; err = MatCreate(PETSC_COMM_WORLD, &L); CHKERRQ(err); err = MatSetFromOptions(L); CHKERRQ(err); PetscViewer viewer; - err = PetscViewerBinaryOpen(PETSC_COMM_WORLD, infile.c_str(), FILE_MODE_READ, &viewer); CHKERRQ(err); + err = PetscViewerBinaryOpen(PETSC_COMM_WORLD, opts.infile.c_str(), FILE_MODE_READ, &viewer); CHKERRQ(err); err = MatLoad(L, viewer); CHKERRQ(err); err = MatAssemblyBegin(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err); - err = MatAssemblyEnd(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err); + err = MatAssemblyEnd(L, MAT_FINAL_ASSEMBLY); CHKERRQ(err); PetscInt m; PetscInt n; @@ -86,8 +96,8 @@ int main(int argc, char ** argv) std::ofstream ofs_vecs; if (mpi_rank == 0) { - ofs_vals.open(outfile_vals, std::ios::out); - ofs_vecs.open(outfile_vecs, std::ios::out); + ofs_vals.open(opts.outfile_vals, std::ios::out); + ofs_vecs.open(opts.outfile_vecs, std::ios::out); } for (PetscInt i = 0; i < num_ev; i++) diff --git a/src/options.cpp b/src/options.cpp new file mode 100644 index 0000000..a52a0bc --- /dev/null +++ b/src/options.cpp @@ -0,0 +1,97 @@ +#include +#include + +#include "options.hpp" + +void print_usage(const std::string & invocation) +{ + std::cerr << "Usage:" << std::endl; + std::cerr << invocation << " " << usage_args << std::endl; +} + +void print_help(const std::string & invocation) +{ + print_usage(invocation); + std::cerr << "FIXME: Write help." << std::endl; +} + +int parse_opts(int argc, char ** argv, Options & opts) +{ + std::string invocation(argv[0]); + + for (int i = 1; i < argc; ++i) + { + std::string arg(argv[i]); + + if (arg == std::string("-h") || arg == std::string("--help")) + { + print_help(invocation); + return 2; + } + + else if (arg == std::string("-l") || arg == std::string("--laplacian")) + { + if (i+1 < argc && argv[i+1][0] != '-') + opts.infile = std::string(argv[++i]); + else + { + std::cerr << "Missing argument to --laplacian." << std::endl; + print_usage(invocation); + return 1; + } + } + + else if (arg == std::string("--vals")) + { + if (i+1 < argc && argv[i+1][0] != '-') + opts.outfile_vals = std::string(argv[++i]); + else + { + std::cerr << "Missing argument to --vals." << std::endl; + print_usage(invocation); + return 1; + } + } + + else if (arg == std::string("--vecs")) + { + if (i+1 < argc && argv[i+1][0] != '-') + opts.outfile_vecs = std::string(argv[++i]); + else + { + std::cerr << "Missing argument to --vecs." << std::endl; + print_usage(invocation); + return 1; + } + } + + else + { + std::cout << "The argument \"" << arg << "\" will be dealt with by PETSc/SLEPc if they understand it. Otherwise it will be silently ignored." << std::endl; + } + } + + // Begin options validation. + if (opts.infile.empty()) + { + std::cerr << "Missing Laplacian file." << std::endl; + print_usage(invocation); + return 1; + } + + if (opts.outfile_vecs.empty()) + { + std::cerr << "Missing output eigenvectors file." << std::endl; + print_usage(invocation); + return 1; + } + if (opts.outfile_vals.empty()) + { + std::cerr << "Missing output eigenvalues file." << std::endl; + print_usage(invocation); + return 1; + } + // End validation. + + return 0; +} diff --git a/src/options.hpp b/src/options.hpp new file mode 100644 index 0000000..05a6ee5 --- /dev/null +++ b/src/options.hpp @@ -0,0 +1,17 @@ +#pragma once + +#include + +typedef struct Options +{ + std::string infile; + std::string outfile_vals; + std::string outfile_vecs; +} Options; + +int parse_opts(int argc, char ** argv, Options & opts); + +void print_usage(const std::string & invocation); +void print_help(const std::string & invocation); + +static const std::string usage_args("--laplacian|-l file --vals file --vecs file [-h|--help] [PETSc/SLEPc options]"); -- cgit v1.2.3