blob: ce0b715a2a6208488791371f41ed275bd88750b0 [file] [log] [blame]
//#####################################################################
// Copyright 2004, Eran Guendelman, Geoffrey Irving, Andrew Selle.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
// Class PARSE_ARGS
//#####################################################################
#include <string>
#include "PARSE_ARGS.h"
using namespace PhysBAM;
using namespace std;
//#####################################################################
// Function Use_Help_Option
//#####################################################################
void PARSE_ARGS::Use_Help_Option (bool use_it)
{
use_help_option = use_it;
}
//#####################################################################
// Function Add_Option_Argument
//#####################################################################
void PARSE_ARGS::
Add_Option_Argument (const std::string& arg_str, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, desc));
}
//#####################################################################
// Function Add_Integer_Argument
//#####################################################################
void PARSE_ARGS::
Add_Integer_Argument (const std::string& arg_str, int default_value, const std::string& val_name, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, val_name, desc, default_value));
}
//#####################################################################
// Function Add_Double_Argument
//#####################################################################
void PARSE_ARGS::
Add_Double_Argument (const std::string& arg_str, double default_value, const std::string& val_name, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, val_name, desc, default_value));
}
//#####################################################################
// Function Add_Vector2_Argument
//#####################################################################
void PARSE_ARGS::
Add_Vector2_Argument (const std::string& arg_str, double default_value[2], const std::string& val_name, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, val_name, desc, default_value, 2));
}
//#####################################################################
// Function Add_Vector3_Argument
//#####################################################################
void PARSE_ARGS::
Add_Vector3_Argument (const std::string& arg_str, double default_value[3], const std::string& val_name, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, val_name, desc, default_value, 3));
}
//#####################################################################
// Function Add_String_Argument
//#####################################################################
void PARSE_ARGS::
Add_String_Argument (const std::string& arg_str, const std::string& default_value, const std::string& val_name, const std::string& desc)
{
arg_data_list.Append_Element (ARG_DATA (arg_str, val_name, desc, default_value));
}
//#####################################################################
// Function Add_Vector_2D_Argument
//#####################################################################
void PARSE_ARGS::
Add_Vector_2D_Argument (const std::string& arg_str, const VECTOR_2D<double> &default_value, const std::string& val_name, const std::string& desc)
{
double vec[2] = {default_value.x, default_value.y};
Add_Vector2_Argument (arg_str, vec, val_name, desc);
}
//#####################################################################
// Function Add_Vector_3D_Argument
//#####################################################################
void PARSE_ARGS::
Add_Vector_3D_Argument (const std::string& arg_str, const VECTOR_3D<double> &default_value, const std::string& val_name, const std::string& desc)
{
double vec[3] = {default_value.x, default_value.y, default_value.z};
Add_Vector3_Argument (arg_str, vec, val_name, desc);
}
//#####################################################################
// Function Set_Extra_Arguments
//#####################################################################
void PARSE_ARGS::
Set_Extra_Arguments (int num, const std::string& synopsis, const std::string& desc) // num=-1 for arbitrary extra rguments
{
num_expected_extra_args = num;
if (synopsis.length()) extra_args_synopsis = synopsis;
if (desc.length()) extra_args_desc = desc;
}
//#####################################################################
// Function Set_Extra_Usage_Callback
//#####################################################################
void PARSE_ARGS::
Set_Extra_Usage_Callback (void (*extra_usage_callback_input) ())
{
extra_usage_callback = extra_usage_callback_input;
}
//#####################################################################
// Function Parse
//#####################################################################
int PARSE_ARGS::
Parse (int argc, char* argv[])
{
program_name = argv[0];
int current_arg = 1;
while (current_arg < argc)
{
if (use_help_option && !strcmp (argv[current_arg], "--help")) Print_Usage (true); // print help
int match = Find_Match (argv[current_arg]);
if (match < 0)
{
if (argv[current_arg][0] == '-') Print_Usage (true);
else break;
}
if (!arg_data_list (match).Parse_Value (argc, argv, current_arg)) Print_Usage (true);
else arg_data_list (match).value_set = true;
}
int num_remaining_args = argc - current_arg;
if (num_expected_extra_args != -1 && num_remaining_args != num_expected_extra_args) Print_Usage (true); // didn't get the expected number of extra args
extra_arg_list.Remove_All_Entries();
for (int i = current_arg; i < argc; i++) extra_arg_list.Append_Element (argv[i]);
return current_arg;
}
//#####################################################################
// Function Parse
//#####################################################################
int PARSE_ARGS::
Parse (int argc, const char* argv[])
{
return Parse (argc, (char**) argv);
}
//#####################################################################
// Function Get_Option_Value
//#####################################################################
bool PARSE_ARGS::
Get_Option_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::OPTION);
return arg_data_list (match).boolean_value;
}
//#####################################################################
// Function Get_Integer_Value
//#####################################################################
int PARSE_ARGS::
Get_Integer_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::INTEGER);
return arg_data_list (match).integer_value;
}
//#####################################################################
// Function Get_Double_Value
//#####################################################################
double PARSE_ARGS::
Get_Double_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::DOUBLE);
return arg_data_list (match).double_value;
}
//#####################################################################
// Function Get_Vector2_Value
//#####################################################################
const double* PARSE_ARGS::
Get_Vector2_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::VECTOR2);
return arg_data_list (match).vector_value;
}
//#####################################################################
// Function Get_Vector2_Value
//#####################################################################
void PARSE_ARGS::
Get_Vector2_Value (const std::string& arg_str, double* value) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::VECTOR2);
memcpy (value, arg_data_list (match).vector_value, 2 * sizeof (double));
}
//#####################################################################
// Function Get_Vector_2D_Value
//#####################################################################
VECTOR_2D<double> PARSE_ARGS::
Get_Vector_2D_Value (const std::string& arg_str) const
{
const double* vec = Get_Vector2_Value (arg_str);
VECTOR_2D<double> vector (vec[0], vec[1]);
return vector;
}
//#####################################################################
// Function Get_Vector3_Value
//#####################################################################
const double* PARSE_ARGS::
Get_Vector3_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::VECTOR3);
return arg_data_list (match).vector_value;
}
//#####################################################################
// Function Get_Vector_3D_Value
//#####################################################################
VECTOR_3D<double> PARSE_ARGS::
Get_Vector_3D_Value (const std::string& arg_str) const
{
const double* vec = Get_Vector3_Value (arg_str);
VECTOR_3D<double> vector (vec[0], vec[1], vec[2]);
return vector;
}
//#####################################################################
// Function Get_Vector3_Value
//#####################################################################
void PARSE_ARGS::
Get_Vector3_Value (const std::string& arg_str, double* value) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::VECTOR3);
memcpy (value, arg_data_list (match).vector_value, 3 * sizeof (double));
}
//#####################################################################
// Function Get_String_Value
//#####################################################################
const std::string& PARSE_ARGS::
Get_String_Value (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
assert (arg_data_list (match).type == ARG_DATA::STRING);
return arg_data_list (match).string_value;
}
//#####################################################################
// Function Is_Value_Set
//#####################################################################
bool PARSE_ARGS::
Is_Value_Set (const std::string& arg_str) const
{
int match = Find_Match (arg_str);
assert (match >= 0);
return arg_data_list (match).value_set;
}
//#####################################################################
// Function Find_Match
//#####################################################################
int PARSE_ARGS::
Find_Match (const std::string& str) const
{
for (int i = 1; i <= arg_data_list.m; i++) if (arg_data_list (i).str == str) return i;
return -1;
}
//#####################################################################
// Function Num_Extra_Args
//#####################################################################
int PARSE_ARGS::
Num_Extra_Args() const
{
return extra_arg_list.m;
}
//#####################################################################
// Function Extra_Arg
//#####################################################################
const std::string& PARSE_ARGS::
Extra_Arg (int i) const
{
return extra_arg_list (i);
}
//#####################################################################
// Function Get_Program_Name
//#####################################################################
const std::string& PARSE_ARGS::
Get_Program_Name() const
{
return program_name;
}
//#####################################################################
// Function Print_Usage
//#####################################################################
void PARSE_ARGS::
Print_Usage (bool do_exit) const
{
int i;
cerr << "Usage: " << program_name << " ";
for (i = 1; i <= arg_data_list.m; i++)
{
arg_data_list (i).Print_Synopsis (cerr);
cerr << " ";
}
cerr << extra_args_synopsis << std::endl;
int width = 0;
for (i = 1; i <= arg_data_list.m; i++)
{
int len = (int) arg_data_list (i).str.length();
if (len > width) width = len;
}
for (i = 1; i <= arg_data_list.m; i++)
{
arg_data_list (i).Print_Description (cerr, width + 2);
cerr << endl;
}
cerr << extra_args_desc << endl;
if (extra_usage_callback) extra_usage_callback();
if (do_exit) exit (-1);
}
//#####################################################################
// Function Find_And_Remove
//#####################################################################
bool PARSE_ARGS::
Find_And_Remove (const char *str, int& argc, char** argv)
{
int i;
for (i = 0; i < argc; i++) if (!strcmp (str, argv[i])) break;
if (i < argc)
{
for (; i < argc - 1; i++) argv[i] = argv[i + 1];
argc--;
return true;
}
return false;
}
//#####################################################################