Skip to content

Commit

Permalink
Added error handling for lexical_cast<int>
Browse files Browse the repository at this point in the history
  • Loading branch information
ttadano committed Feb 22, 2016
1 parent 8449c9b commit 517d8db
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 44 deletions.
78 changes: 51 additions & 27 deletions alm/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ void Input::parce_input(int narg, char **arg)
}
parse_general_vars();


if (!locate_tag("&cell")) {
error->exit("parse_input", "&cell entry not found in the input file");
}
Expand Down Expand Up @@ -130,20 +129,19 @@ void Input::parse_general_vars()
error->exit("parse_general_vars", "Invalid MODE variable");
}

nat = boost::lexical_cast<int>(general_var_dict["NAT"]);
nkd = boost::lexical_cast<int>(general_var_dict["NKD"]);

assign_val(nat, "NAT", general_var_dict);
assign_val(nkd, "NKD", general_var_dict);

if (general_var_dict["NSYM"].empty()) {
nsym = 0;
} else {
nsym= boost::lexical_cast<int>(general_var_dict["NSYM"]);
assign_val(nsym, "NSYM", general_var_dict);
}

if (general_var_dict["PRINTSYM"].empty()) {
is_printsymmetry = 0;
} else {
is_printsymmetry = boost::lexical_cast<int>(general_var_dict["PRINTSYM"]);
assign_val(is_printsymmetry, "PRINTSYM", general_var_dict);
}

split_str_by_space(general_var_dict["KD"], kdname_v);
Expand All @@ -165,7 +163,12 @@ void Input::parse_general_vars()
}
} else if (periodic_v.size() == 3) {
for (i = 0; i < 3; ++i) {
is_periodic[i] = boost::lexical_cast<int>(periodic_v[i]);
try{
is_periodic[i] = boost::lexical_cast<int>(periodic_v[i]);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
error->exit("parse_general_vars", "The PERIODIC tag must be a set of integers.");
}
}
} else {
error->exit("parse_general_vars", "Invalid number of entries for PERIODIC");
Expand All @@ -174,7 +177,7 @@ void Input::parse_general_vars()
if (general_var_dict["TOLERANCE"].empty()) {
tolerance = 1.0e-8;
} else {
tolerance = boost::lexical_cast<double>(general_var_dict["TOLERANCE"]);
assign_val(tolerance, "TOLERANCE", general_var_dict);
}

// Convert MAGMOM input to array
Expand All @@ -190,12 +193,12 @@ void Input::parse_general_vars()
if (general_var_dict["NONCOLLINEAR"].empty()) {
noncollinear = 0;
} else {
noncollinear = boost::lexical_cast<int>(general_var_dict["NONCOLLINEAR"]);
assign_val(noncollinear, "NONCOLLINEAR", general_var_dict);
}
if (general_var_dict["TREVSYM"].empty()) {
trevsym = 1;
} else {
trevsym = boost::lexical_cast<int>(general_var_dict["TREVSYM"]);
assign_val(trevsym, "TREVSYM", general_var_dict);
}

if (!general_var_dict["MAGMOM"].empty()) {
Expand Down Expand Up @@ -275,7 +278,7 @@ void Input::parse_general_vars()
if (general_var_dict["TRIMEVEN"].empty()) {
trim_dispsign_for_evenfunc = true;
} else {
trim_dispsign_for_evenfunc = boost::lexical_cast<bool>(general_var_dict["TRIMEVEN"]);
assign_val(trim_dispsign_for_evenfunc, "TRIMEVEN", general_var_dict);
}

}
Expand Down Expand Up @@ -441,12 +444,7 @@ void Input::parse_interaction_vars()
}
}

try {
maxorder = boost::lexical_cast<int>(interaction_var_dict["NORDER"]);
} catch (std::exception &e) {
std::cerr << "Detect exception: " << e.what() << std::endl;
error->exit("parse_interaction_vars", "Invalid value for NORDER");
}
assign_val(maxorder, "NORDER", interaction_var_dict);
if (maxorder < 1) error->exit("parse_interaction_vars", "maxorder has to be a positive integer");

memory->allocate(nbody_include, maxorder);
Expand All @@ -459,7 +457,12 @@ void Input::parse_interaction_vars()
}
} else if (nbody_v.size() == maxorder) {
for (i = 0; i < maxorder; ++i) {
nbody_include[i] = boost::lexical_cast<int>(nbody_v[i]);
try {
nbody_include[i] = boost::lexical_cast<int>(nbody_v[i]);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
error->exit("parse_interaction_vars", "NBODY must be an integer.");
}
}
} else {
error->exit("parse_interaction_vars", "The number of entry of NBODY has to be equal to NORDER");
Expand Down Expand Up @@ -696,37 +699,36 @@ void Input::parse_fitting_vars()
}
}

ndata = boost::lexical_cast<int>(fitting_var_dict["NDATA"]);
assign_val(ndata, "NDATA", fitting_var_dict);

if (fitting_var_dict["NSTART"].empty()) {
nstart = 1;
} else {
nstart= boost::lexical_cast<int>(fitting_var_dict["NSTART"]);
assign_val(nstart, "NSTART", fitting_var_dict);
}
if (fitting_var_dict["NEND"].empty()) {
nend = ndata;
} else {
nend = boost::lexical_cast<int>(fitting_var_dict["NEND"]);
assign_val(nend, "NEND", fitting_var_dict);
}
if (fitting_var_dict["NSKIP"].empty()) {
nskip = 0;
} else {
nskip = boost::lexical_cast<int>(fitting_var_dict["NSKIP"]);
assign_val(nskip, "NSKIP", fitting_var_dict);
}

if (ndata <= 0 || nstart <= 0 || nend <= 0
|| nstart > ndata || nend > ndata || nstart > nend) {
error->exit("parce_fitting_vars", "ndata, nstart, nend are not consistent with each other");
}


if (nskip < -1) error->exit("parce_fitting_vars", "nskip has to be larger than -2.");
if (nskip == -1) {

if (fitting_var_dict["NBOOT"].empty()) {
error->exit("parse_fitting_vars", "NBOOT has to be given when NSKIP=-1");
} else {
nboot = boost::lexical_cast<int>(fitting_var_dict["NBOOT"]);
assign_val(nboot, "NBOOT", fitting_var_dict);
}

if (nboot <= 0) error->exit("parce_input", "nboot has to be a positive integer");
Expand All @@ -741,13 +743,13 @@ void Input::parse_fitting_vars()
if (fitting_var_dict["MULTDAT"].empty()) {
multiply_data = 1;
} else {
multiply_data = boost::lexical_cast<int>(fitting_var_dict["MULTDAT"]);
assign_val(multiply_data, "MULTDAT", fitting_var_dict);
}

if (fitting_var_dict["ICONST"].empty()) {
constraint_flag = 1;
} else {
constraint_flag = boost::lexical_cast<int>(fitting_var_dict["ICONST"]);
assign_val(constraint_flag, "ICONST", fitting_var_dict);
}

fc2_file = fitting_var_dict["FC2XML"];
Expand Down Expand Up @@ -865,7 +867,12 @@ void Input::parse_atomic_positions()
split_str_by_space(str_v[i], pos_line);

if (pos_line.size() == 4) {
kd[i] = boost::lexical_cast<int>(pos_line[0]);
try {
kd[i] = boost::lexical_cast<int>(pos_line[0]);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
error->exit("parse_atomic_positions", "Invalid entry for the &position field at line ", i + 1);
}

for (j = 0; j < 3; ++j) {
xeq[i][j] = boost::lexical_cast<double>(pos_line[j + 1]);
Expand Down Expand Up @@ -1091,3 +1098,20 @@ void Input::split_str_by_space(const std::string str, std::vector<std::string> &
}
str_tmp.clear();
}

template<typename T> void Input::assign_val(T &val, const std::string key, std::map<std::string, std::string> dict)
{
// Assign a value to the variable "key" using the boost::lexica_cast.

if (!dict[key].empty()) {
try {
val = boost::lexical_cast<T>(dict[key]);
} catch (std::exception &e) {
std::string str_tmp;
std::cout << e.what() << std::endl;
str_tmp = "Invalid entry for the " + key + " tag.\n";
str_tmp += " Please check the input value.";
error->exit("assign_val", str_tmp.c_str());
}
}
}
4 changes: 3 additions & 1 deletion alm/input.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
input.h
Copyright (c) 2014 Terumasa Tadano
Copyright (c) 2014, 2015, 2016 Terumasa Tadano
This file is distributed under the terms of the MIT license.
Please see the file 'LICENCE.txt' in the root directory
Expand Down Expand Up @@ -37,5 +37,7 @@ namespace ALM_NS {
void parse_atomic_positions();
bool is_endof_entry(std::string);
void get_var_dict(const std::string, std::map<std::string, std::string>&);

template<typename T> void assign_val(T&, const std::string, std::map<std::string, std::string>);
};
}
46 changes: 30 additions & 16 deletions anphon/parsephon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,8 @@ void Input::parse_general_vars()

file_result = prefix + ".result";

#ifdef _USE_BOOST
boost::to_upper(mode);
nsym = boost::lexical_cast<int>(general_var_dict["NSYM"]);
#else
std::transform (mode.begin(), mode.end(), mode.begin(), toupper);
nsym = my_cast<int>(general_var_dict["NSYM"]);
#endif
assign_val(nsym, "NSYM", general_var_dict);

fcsinfo = general_var_dict["FCSXML"];
assign_val(nkd, "NKD", general_var_dict);
Expand Down Expand Up @@ -306,6 +301,7 @@ void Input::parse_analysis_vars(const bool use_default_values)
int quartic_mode;
int include_isotope;
int scattering_phase_space;
unsigned int cellsize[3];

double delta_a;
double *isotope_factor;
Expand Down Expand Up @@ -402,10 +398,17 @@ void Input::parse_analysis_vars(const bool use_default_values)
if (anime_cellsize.size() != 3) {
error->exit("parse_analysis_vars", "The number of entries for ANIME_CELLSIZE should be 3.");
}
if (my_cast<int>(anime_cellsize[0]) < 1 ||
my_cast<int>(anime_cellsize[1]) < 1 ||
my_cast<int>(anime_cellsize[2]) < 1) {

for (i = 0; i < 3; ++i) {
try {
cellsize[i] = boost::lexical_cast<unsigned int>(anime_cellsize[i]);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
error->exit("parse_analysis_vars", "ANIME_CELLSIZE must be a set of positive integers.");
}
if (cellsize[i] < 1) {
error->exit("parse_analysis_vars", "Please give positive integers in ANIME_CELLSIZE.");
}
}

assign_val(anime_format, "ANIME_FORMAT", analysis_var_dict);
Expand All @@ -429,7 +432,7 @@ void Input::parse_analysis_vars(const bool use_default_values)
if (print_anime) {
for (i = 0; i < 3; ++i) {
writes->anime_kpoint[i] = my_cast<double>(anime_kpoint[i]);
writes->anime_cellsize[i] = my_cast<unsigned int>(anime_cellsize[i]);
writes->anime_cellsize[i] = cellsize[i];
}
writes->anime_format = anime_format;
}
Expand Down Expand Up @@ -619,7 +622,12 @@ void Input::parse_kpoints()
if (i == 0) {
// kpmode
if (kpelem.size() == 1) {
kpmode = boost::lexical_cast<int>(kpelem[0]);
try {
kpmode = boost::lexical_cast<int>(kpelem[0]);
} catch (std::exception &e) {
std::cout << e.what() << std::endl;
error->exit("parse_kpoints", "KPMODE must be an integer. [0, 1, or 2]");
}

if (!(kpmode >= 0 && kpmode <= 3)) {
error->exit("parse_kpoints", "KPMODE must be 0, 1, or 2.");
Expand Down Expand Up @@ -910,16 +918,22 @@ void Input::split_str_by_space(const std::string str, std::vector<std::string> &

template<typename T> void Input::assign_val(T &val, const std::string key, std::map<std::string, std::string> dict)
{
// Assign a value to the variable "key" using the boost::lexica_cast.

if (!dict[key].empty()) {
#ifdef _USE_BOOST
val = boost::lexical_cast<T>(dict[key]);
#else
val = my_cast<T>(dict[key]);
#endif
try {
val = boost::lexical_cast<T>(dict[key]);
} catch (std::exception &e) {
std::string str_tmp;
std::cout << e.what() << std::endl;
str_tmp = "Invalid entry for the " + key + " tag.\n";
str_tmp += " Please check the input value.";
error->exit("assign_val", str_tmp.c_str());
}
}
}


template<typename T_to, typename T_from> T_to Input::my_cast(T_from const &x)
{
std::stringstream ss;
Expand Down

0 comments on commit 517d8db

Please sign in to comment.