diff --git a/examples/main.c b/examples/main.c index 631117148addd3ab7ad49ed2760855b793757870..f4425cb797f86b6886e9f1de30ff910576f2cb5d 100644 --- a/examples/main.c +++ b/examples/main.c @@ -87,6 +87,8 @@ void print_help_message() { printf(" %2s %8s %s\n", "-n", "{int}", "Execute a fixed number of time steps. When unset use the time_end " "parameter to stop."); + printf(" %2s %8s %s\n", "-P", "{sec:par:val}", + "Set parameter value, can be used more than once."); printf(" %2s %8s %s\n", "-s", "", "Run with hydrodynamics."); printf(" %2s %8s %s\n", "-S", "", "Run with stars."); printf(" %2s %8s %s\n", "-t", "{int}", @@ -170,12 +172,14 @@ int main(int argc, char *argv[]) { int verbose = 0; int nr_threads = 1; int with_verbose_timers = 0; + int nparams = 0; + char *cmdparams[PARSER_MAX_NO_OF_PARAMS]; char paramFileName[200] = ""; unsigned long long cpufreq = 0; /* Parse the parameters */ int c; - while ((c = getopt(argc, argv, "acCdDef:FgGhMn:sSt:Tv:y:")) != -1) + while ((c = getopt(argc, argv, "acCdDef:FgGhMn:P:sSt:Tv:y:")) != -1) switch (c) { case 'a': with_aff = 1; @@ -224,6 +228,10 @@ int main(int argc, char *argv[]) { return 1; } break; + case 'P': + cmdparams[nparams] = optarg; + nparams++; + break; case 's': with_hydro = 1; break; @@ -351,6 +359,13 @@ int main(int argc, char *argv[]) { if (myrank == 0) { message("Reading runtime parameters from file '%s'", paramFileName); parser_read_file(paramFileName, params); + + /* Handle any command-line overrides. */ + if (nparams > 0) + for (int k = 0; k < nparams; k++) + parser_set_param(params, cmdparams[k]); + + /* And dump the parameters as used. */ // parser_print_params(¶ms); parser_write_params_to_file(params, "used_parameters.yml"); } diff --git a/src/parser.c b/src/parser.c index 41a3e8637630eceb3beb9383acb3344028d38659..0ff388d43912725d91d0971ade8cc0e653f45e8e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2016 James Willis (james.s.willis@durham.ac.uk) + * 2017 Peter W. Draper (p.w.draper@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -89,6 +90,60 @@ void parser_read_file(const char *file_name, struct swift_params *params) { fclose(file); } +/** + * @brief Set or update a parameter using a compressed format. + * + * The compressed format allows a value to be given as a single + * string and has the format "section:parameter:value", with all + * names as would be given in the parameter file. + * + * @param params Structure that holds the parameters. + * @param namevalue the parameter name and value as described. + */ +void parser_set_param(struct swift_params *params, const char *namevalue) { + + /* Get the various parts. */ + char name[PARSER_MAX_LINE_SIZE]; + char value[PARSER_MAX_LINE_SIZE]; + name[0] = '\0'; + value[0] = '\0'; + + /* Name is part until second colon. */ + char *p1 = strchr(namevalue, ':'); + if (p1 != NULL) { + char *p2 = strchr(p1+1, ':'); + if (p2 != NULL) { + memcpy(name, namevalue, p2-namevalue); + name[p2-namevalue] = '\0'; + + /* Value is rest after second colon. */ + p2++; + strcpy(value, p2); + } + } + + /* Sanity check. */ + if (strlen(name) == 0 || strlen(value) == 0 || strchr(value, ':') != NULL) + error("Cannot parse compressed parameter string: '%s', check syntax " + "should be section:parameter:value", namevalue); + + /* And update or set. */ + int updated = 0; + for (int i = 0; i < params->paramCount; i++) { + if (strcmp(name, params->data[i].name) == 0) { + strcpy(params->data[i].value, value); + updated = 1; + } + } + if (!updated) { + strcpy(params->data[params->paramCount].name, name); + strcpy(params->data[params->paramCount].value, value); + params->paramCount++; + if (params->paramCount == PARSER_MAX_NO_OF_PARAMS) + error("Too many parameters, current maximum is %d.", params->paramCount); + } +} + /** * @brief Counts the number of times a specific character appears in a string. * @@ -238,7 +293,7 @@ static void parse_value(char *line, struct swift_params *params) { /* Check for more than one value on the same line. */ if (count_char(line, PARSER_VALUE_CHAR) > 1) { - error("Inavlid line:%d '%s', only one value allowed per line.", lineNumber, + error("Invalid line:%d '%s', only one value allowed per line.", lineNumber, line); } @@ -718,6 +773,7 @@ void parser_write_params_to_file(const struct swift_params *params, fclose(file); } + #if defined(HAVE_HDF5) void parser_write_params_to_hdf5(const struct swift_params *params, hid_t grp) { diff --git a/src/parser.h b/src/parser.h index b78e21194d256ed7b50b8a09718c9725d52a1e0b..bab6d8b25f5334546ac2aaf39a3f25ef7fb6ff57 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. * Copyright (c) 2016 James Willis (james.s.willis@durham.ac.uk) + * 2017 Peter W. Draper (p.w.draper@durham.ac.uk) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -55,6 +56,7 @@ void parser_read_file(const char *file_name, struct swift_params *params); void parser_print_params(const struct swift_params *params); void parser_write_params_to_file(const struct swift_params *params, const char *file_name); +void parser_set_param(struct swift_params *params, const char *desc); char parser_get_param_char(const struct swift_params *params, const char *name); int parser_get_param_int(const struct swift_params *params, const char *name);