diff options
author | Gard Spreemann <gard.spreemann@epfl.ch> | 2018-10-24 13:07:52 +0200 |
---|---|---|
committer | Gard Spreemann <gard.spreemann@epfl.ch> | 2018-10-24 13:07:52 +0200 |
commit | 3ae1f6c19533f24964166ec373e739c82919ae75 (patch) | |
tree | ef1c23301612a01e449f7db29b571b666b58141f | |
parent | 864389f80dc5e7bdfa936c73c5f792b993a2b971 (diff) |
Proper option parsing.
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/main.cpp | 24 | ||||
-rw-r--r-- | src/options.cpp | 97 | ||||
-rw-r--r-- | src/options.hpp | 17 |
4 files changed, 132 insertions, 8 deletions
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 <slepceps.h> #include <petscmat.h> +#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 <string> +#include <iostream> + +#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 <string> + +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]"); |