Skip to content

Commit

Permalink
Allow repetition of simulation flags. (#7784)
Browse files Browse the repository at this point in the history
- There are 4 policies for handling repeated flags.
    - `FLAG_REPEAT_POLICY_FORBID`
    - `FLAG_REPEAT_POLICY_IGNORE`
    - `FLAG_REPEAT_POLICY_REPLACE`
    - `FLAG_REPEAT_POLICY_COMBINE`

    The first three are implemented. Combining flags (`FLAG_REPEAT_POLICY_COMBINE)`
    is not yet implemented. Will be added later.

    _Maybe we need to add `FLAG_REPEAT_POLICY_IGNORE_SILENT` for flags
    like `-help`_.

  - If an `Option` (with value) is specified multiple times:
    Forbid: Prints an error and terminates flag/option processing.
    Ignore: Prints a warning and ignores the new value.
    Replace: Prints a warning and uses the new value.
    Combine: Prints a warning and combines all values (NOT YET IMPLEMENTED).

  - If a `flag` is specified multiple times:
    Forbid: Prints an error and terminates flag/option processing.
    Ignore: Prints a warning and ignores the repeated flags.
    Replace: Invalid for `flags`. Print error and terminate.
    Combine: Invalid for `flags`. Print error and terminate.

  - All flags/options are now set to `FLAG_REPEAT_POLICY_FORBID` except for
    `-help` and `-lv` which are both set to `FLAG_REPEAT_POLICY_REPLACE`
    for now.

    Please feel free to update the policies for the flags if you know what
    should be the best way to handle them each.
  • Loading branch information
mahge committed Aug 19, 2021
1 parent 78435df commit ec5d971
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 16 deletions.
122 changes: 106 additions & 16 deletions OMCompiler/SimulationRuntime/c/simulation/options.c
Expand Up @@ -40,6 +40,9 @@ static int optionSet(const char *option, int argc, char** argv); /* -f=value
static const char* getOption(const char*, int, char **); /* -f=value; returns NULL if not found */
static const char* getFlagValue(const char *, int , char **); /* -f value; returns NULL if not found */

static int handle_repeated_option(int flag_index, char **argv_loc, int is_sticky);
static int handle_repeated_flag(int flag_index);

int omc_flag[FLAG_MAX];
const char *omc_flagValue[FLAG_MAX];

Expand Down Expand Up @@ -104,13 +107,17 @@ int checkCommandLineArguments(int argc, char **argv)
{
if((FLAG_TYPE[j] == FLAG_TYPE_FLAG) && flagSet(FLAG_NAME[j], 1, argv+i))
{
if(omc_flag[j])
{
errorStreamPrint(LOG_STDOUT, 0, "each command line option can only be used once: %s", argv[i]);
// Flag is not yet set.
if(!omc_flag[j]) {
omc_flag[j] = 1;
}
// Flag is already specified earlier. Check repetition policy.
else if(!handle_repeated_flag(j)) {
// repetition is invlaid for this Flag
return 1;
}

omc_flag[j] = 1;
// All good.
found=1;

#ifdef USE_DEBUG_OUTPUT
Expand All @@ -121,16 +128,20 @@ int checkCommandLineArguments(int argc, char **argv)
}
else if((FLAG_TYPE[j] == FLAG_TYPE_OPTION) && flagSet(FLAG_NAME[j], 1, argv+i) && (i+1 < argc))
{
if(omc_flag[j])
{
errorStreamPrint(LOG_STDOUT, 0, "each command line option can only be used once: %s", argv[i]);
// Option is not yet set.
if(!omc_flag[j]) {
omc_flag[j] = 1;
omc_flagValue[j] = (char*)getFlagValue(FLAG_NAME[j], 1, argv+i);
}
// Option is already specified earlier. Check repetition policy.
else if(!handle_repeated_option(j, argv+i, 0 /*Not sticky*/)) {
// repetition is invlaid for this option
return 1;
}

omc_flag[j] = 1;
omc_flagValue[j] = (char*)getFlagValue(FLAG_NAME[j], 1, argv+i);
// All good.
found = 1;
i++;
found=1;

#ifdef USE_DEBUG_OUTPUT
debugStreamPrint(LOG_STDOUT, 0, "-%s %s", FLAG_NAME[j], omc_flagValue[j]);
Expand All @@ -140,15 +151,20 @@ int checkCommandLineArguments(int argc, char **argv)
}
else if((FLAG_TYPE[j] == FLAG_TYPE_OPTION) && optionSet(FLAG_NAME[j], 1, argv+i))
{
if(omc_flag[j])
{
errorStreamPrint(LOG_STDOUT, 0, "each command line option can only be used once: %s", argv[i]);

// Option is not yet set.
if (!omc_flag[j]) {
omc_flag[j] = 1;
omc_flagValue[j] = (char*)getOption(FLAG_NAME[j], 1, argv+i);
}
// Option is already specified earlier. Check repetition policy.
else if (!handle_repeated_option(j, argv+i, 1 /*Sticky*/)) {
// repetition is invlaid for this option
return 1;
}

omc_flag[j] = 1;
omc_flagValue[j] = (char*)getOption(FLAG_NAME[j], 1, argv+i);
found=1;
// All good.
found = 1;

#ifdef USE_DEBUG_OUTPUT
debugStreamPrint(LOG_STDOUT, 0, "-%s=%s", FLAG_NAME[j], omc_flagValue[j]);
Expand All @@ -174,6 +190,80 @@ int checkCommandLineArguments(int argc, char **argv)
return 0;
}

static int handle_repeated_flag(int flag_index) {

const char* flag_name = FLAG_NAME[flag_index];
flag_repeat_policy repeat_policy = FLAG_REPEAT_POLICIES[flag_index];

if(repeat_policy == FLAG_REPEAT_POLICY_IGNORE) {
warningStreamPrint(LOG_STDOUT, 0, "Command line flag '%s' specified again. Ignoring."
, flag_name);
return 1;
}

if(repeat_policy == FLAG_REPEAT_POLICY_FORBID) {
errorStreamPrint(LOG_STDOUT, 0, "Command line flag '%s' can be specified only once.", flag_name);
return 0;
}


if(repeat_policy == FLAG_REPEAT_POLICY_REPLACE) {
errorStreamPrint(LOG_STDOUT, 0, "Command line flag %s is supposed to be replaced on repetition. This option does not apply for flags. Fix the repetition policy for the flag.", flag_name);
return 0;
}

if(repeat_policy == FLAG_REPEAT_POLICY_COMBINE) {
errorStreamPrint(LOG_STDOUT, 0, "Command line flag %s is supposed to be combined on repetition. This option does not apply for flags. Fix the repetition policy for the flag.", flag_name);
return 0;
}

errorStreamPrint(LOG_STDOUT, 0, "Error: Unknow repetition policy for command line flag %s.", flag_name);
return 0;
}

static int handle_repeated_option(int flag_index, char **argv_loc, int is_sticky) {

const char* flag_name = FLAG_NAME[flag_index];
flag_repeat_policy repeat_policy = FLAG_REPEAT_POLICIES[flag_index];

const char* old_value = omc_flagValue[flag_index];

if(repeat_policy == FLAG_REPEAT_POLICY_IGNORE) {
warningStreamPrint(LOG_STDOUT, 0, "Command line option '%s' specified again. Keeping the first value '%s' and ignoring the rest."
, flag_name, old_value);
return 1;
}

if(repeat_policy == FLAG_REPEAT_POLICY_FORBID) {
errorStreamPrint(LOG_STDOUT, 0, "Command line option '%s' can be specified only once.", flag_name);
return 0;
}


const char* new_value;

if(is_sticky) // lv=LOG_STATS
new_value = (char*)getOption(flag_name, 1, argv_loc);
else // lv LOG_STATS
new_value = (char*)getFlagValue(flag_name, 1, argv_loc);

if(repeat_policy == FLAG_REPEAT_POLICY_REPLACE) {
omc_flagValue[flag_index] = new_value;
warningStreamPrint(LOG_STDOUT, 0, "Command line option '%s' specified again. Value has been overriden from '%s' to '%s'."
, flag_name, old_value, new_value);
return 1;
}

if(repeat_policy == FLAG_REPEAT_POLICY_COMBINE) {
errorStreamPrint(LOG_STDOUT, 0, "Command line option %s is supposed to be combined on repetition. This has not bee implemented yet", flag_name);
return 0;
}

errorStreamPrint(LOG_STDOUT, 0, "Error: Unknow repetition policy for command line option %s.", flag_name);
return 0;

}

static int flagSet(const char *option, int argc, char** argv)
{
int i;
Expand Down
119 changes: 119 additions & 0 deletions OMCompiler/SimulationRuntime/c/util/simulation_options.c
Expand Up @@ -568,6 +568,125 @@ const char *FLAG_DETAILED_DESC[FLAG_MAX+1] = {
"FLAG_MAX"
};

const flag_repeat_policy FLAG_REPEAT_POLICIES[FLAG_MAX] = {
FLAG_REPEAT_POLICY_FORBID,

/* FLAG_ABORT_SLOW */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_ALARM */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_CLOCK */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_CPU */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_CSV_OSTEP */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_CVODE_ITER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_CVODE_LMM */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DATA_RECONCILE_Cx */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DAE_MODE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DELTA_X_LINEARIZE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DELTA_X_SOLVER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_EMBEDDED_SERVER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_EMBEDDED_SERVER_PORT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MAT_SYNC */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_EMIT_PROTECTED */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DATA_RECONCILE_Eps */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_F */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HELP */ FLAG_REPEAT_POLICY_REPLACE,
/* FLAG_HOMOTOPY_ADAPT_BEND */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_BACKTRACE_STRATEGY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_H_EPS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_MAX_LAMBDA_STEPS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_MAX_NEWTON_STEPS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_MAX_TRIES */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_NEG_START_DIR */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_ON_FIRST_TRY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NO_HOMOTOPY_ON_FIRST_TRY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_DEC_FACTOR */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_DEC_FACTOR_PRED */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_INC_FACTOR */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_INC_THRESHOLD */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_MAX */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_MIN */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_HOMOTOPY_TAU_START */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_MAXERRORTESTFAIL */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_MAXNONLINITERS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_MAXCONVFAILS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_NONLINCONVCOEF */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_LS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDA_SCALING */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IDAS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IGNORE_HIDERESULT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IIF */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IIM */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IIT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_ILS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IMPRK_ORDER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IMPRK_LS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_INITIAL_STEP_SIZE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_INPUT_CSV */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_INPUT_FILE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_INPUT_FILE_STATES */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_INPUT_PATH */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IPOPT_HESSE*/ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IPOPT_INIT*/ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IPOPT_JAC*/ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IPOPT_MAX_ITER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_IPOPT_WARM_START */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_JACOBIAN */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_JACOBIAN_THREADS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_L */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_L_DATA_RECOVERY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LOG_FORMAT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LS_IPOPT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LSS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LSS_MAX_DENSITY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LSS_MIN_SIZE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_LV */ FLAG_REPEAT_POLICY_REPLACE,
/* FLAG_LV_TIME */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MAX_BISECTION_ITERATIONS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MAX_EVENT_ITERATIONS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MAX_ORDER */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MAX_STEP_SIZE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_MEASURETIMEPLOTFORMAT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NEWTON_FTOL */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NEWTON_MAX_STEP_FACTOR */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NEWTON_XTOL */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NEWTON_STRATEGY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NLS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NLS_INFO */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NLS_LS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NLS_MAX_DENSITY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NLS_MIN_SIZE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NOEMIT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NOEQUIDISTANT_GRID */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NOEQUIDISTANT_OUT_FREQ*/ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NOEQUIDISTANT_OUT_TIME*/ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NOEVENTEMIT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NO_RESTART */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NO_ROOTFINDING */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NO_SCALING */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_NO_SUPPRESS_ALG */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OPTDEBUGEJAC */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OPTIMIZER_NP */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OPTIMIZER_TGRID */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OUTPUT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OUTPUT_PATH */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OVERRIDE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_OVERRIDE_FILE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_PORT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_R */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DATA_RECONCILE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DATA_RECONCILE_BOUNDARY */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_RT */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_S */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_SINGLE_PRECISION */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_SOLVER_STEPS */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_STEADY_STATE */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_STEADY_STATE_TOL */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_DATA_RECONCILE_Sx */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_UP_HESSIAN */ FLAG_REPEAT_POLICY_FORBID,
/* FLAG_W */ FLAG_REPEAT_POLICY_FORBID,
};


const int FLAG_TYPE[FLAG_MAX] = {
FLAG_TYPE_UNKNOWN,

Expand Down
8 changes: 8 additions & 0 deletions OMCompiler/SimulationRuntime/c/util/simulation_options.h
Expand Up @@ -174,9 +174,17 @@ enum _FLAG_TYPE
FLAG_TYPE_MAX
};

typedef enum {
FLAG_REPEAT_POLICY_FORBID = 0,
FLAG_REPEAT_POLICY_IGNORE,
FLAG_REPEAT_POLICY_REPLACE,
FLAG_REPEAT_POLICY_COMBINE
} flag_repeat_policy;

extern const char *FLAG_NAME[FLAG_MAX+1];
extern const char *FLAG_DESC[FLAG_MAX+1];
extern const char *FLAG_DETAILED_DESC[FLAG_MAX+1];
extern const flag_repeat_policy FLAG_REPEAT_POLICIES[FLAG_MAX];
extern const int FLAG_TYPE[FLAG_MAX];

enum SOLVER_METHOD
Expand Down

0 comments on commit ec5d971

Please sign in to comment.