aboutsummaryrefslogtreecommitdiff
path: root/reference_model/src/func_config.cc
diff options
context:
space:
mode:
Diffstat (limited to 'reference_model/src/func_config.cc')
-rw-r--r--reference_model/src/func_config.cc663
1 files changed, 66 insertions, 597 deletions
diff --git a/reference_model/src/func_config.cc b/reference_model/src/func_config.cc
index a17fdef..6bd809e 100644
--- a/reference_model/src/func_config.cc
+++ b/reference_model/src/func_config.cc
@@ -13,6 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cxxopts.hpp>
#include <ctype.h>
#include <signal.h>
#include <stdarg.h>
@@ -25,615 +26,83 @@
#include "func_config.h"
#include "func_debug.h"
-#define MAX_NAME_LEN 128
-#define MAX_DESC_LEN 128
-
-#ifndef ARG_ERROR
-#define ARG_ERROR(...) \
- fprintf(stderr, "ERROR: "); \
- fprintf(stderr, __VA_ARGS__); \
- fprintf(stderr, "\n"); \
- return 1;
-#endif
-
-// Parameter base name string table
-const char* config_base_name_table[] = {
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) #NAME,
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) #NAME,
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) #NAME,
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) #NAME,
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-#undef DEF_UNIT_OPTION
-};
-
-// Parameter description table
-const char* config_param_desc_table[] = {
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) #DESC,
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) #DESC,
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) #DESC,
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) #DESC,
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-};
-
-// String table and enum for the option hierarchy level/sub-levels
-// (no leaf options). Attribute at the top level have "BASE" as their
-// enum value and an empty string for the value.
-const char* config_hier_str_table[] = {
- "",
-#define DEF_UNIT_START(UNIT) #UNIT,
-#define DEF_UNIT_END(UNIT) /**/
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) /**/
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) /**/
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) /**/
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) /**/
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-};
-
-typedef enum config_hier_enum_t
-{
- BASE,
-#define DEF_UNIT_START(UNIT) CURRENT_UNIT,
-#define DEF_UNIT_END(UNIT) /**/
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) /**/
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) /**/
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) /**/
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) /**/
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-
- MAX_CONFIG_HIER
-} config_hier_enum_t;
-
-// Mapping from a leaf parameter index to the
-// position in the hierarchy.
-config_hier_enum_t config_hierarchy_map[] = {
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) BASE,
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) BASE,
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) CURRENT_UNIT,
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) CURRENT_UNIT,
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-};
-
-#define CONFIG_PARAMETER_COUNT (sizeof(config_hierarchy_map) / sizeof(config_hier_enum_t))
-
-// Dynamically generated at initialization
-char** config_param_str_table = nullptr;
-
-// Initialize the configuration data structures
-int func_model_init_config()
+// Read the command line arguments
+int func_model_parse_cmd_line(
+ func_config_t& func_config, func_debug_t& func_debug, int argc, char** argv, const char* version)
{
- // Initialize string table (builds the hierarchical names)
- config_param_str_table = (char**)calloc(CONFIG_PARAMETER_COUNT, sizeof(char*));
- ASSERT_MEM(config_param_str_table);
-
- for (uint32_t i = 0; i < CONFIG_PARAMETER_COUNT; i++)
+ try
{
- size_t len = strlen(config_base_name_table[i]) + 1;
- if (config_hierarchy_map[i] != BASE)
- {
- ASSERT_MSG(config_hierarchy_map[i] <= MAX_CONFIG_HIER,
- "Configuration parameter\'s hierarchy is out of bounds");
- len += strlen(config_hier_str_table[config_hierarchy_map[i]]) + 1;
+ cxxopts::Options options("tosa_reference_model", "The TOSA reference model");
+
+ // clang-format off
+ options.add_options()
+ ("operator_fbs", "Flat buffer schema file", cxxopts::value<std::string>(func_config.operator_fbs), "<schema>")
+ ("test_desc", "Json test descriptor", cxxopts::value<std::string>(func_config.test_desc), "<descriptor>")
+ ("flatbuffer_dir", "Flatbuffer directory to load. If not specified, it will be overwritten by dirname(test_desc)",
+ cxxopts::value<std::string>(func_config.flatbuffer_dir))
+ ("output_dir", "Output directory to write. If not specified, it will be overwritten by dirname(test_desc)",
+ cxxopts::value<std::string>(func_config.output_dir))
+ ("tosa_file", "Flatbuffer file. Support .json or .tosa. Specifying this will overwrite the one initialized by --test_desc.",
+ cxxopts::value<std::string>(func_config.tosa_file))
+ ("ifm_name", "Input tensor name. Comma(,) separated. Specifying this will overwrite the one initialized by --test_desc.",
+ cxxopts::value<std::string>(func_config.ifm_name))
+ ("ifm_file", "Input tensor numpy Comma(,) separated. file to initialize with placeholder. Specifying this will overwrite the one initialized by --test_desc.",
+ cxxopts::value<std::string>(func_config.ifm_file))
+ ("ofm_name", "Output tensor name. Comma(,) seperated. Specifying this will overwrite the one initialized by --test_desc.",
+ cxxopts::value<std::string>(func_config.ofm_name))
+ ("ofm_file", "Output tensor numpy file to be generated. Comma(,) seperated. Specifying this will overwrite the one initialized by --test_desc.",
+ cxxopts::value<std::string>(func_config.ofm_file))
+ ("eval", "Evaluate the network (0/1)", cxxopts::value<uint32_t>(func_config.eval))
+ ("fp_format", "Floating-point number dump format string (printf-style format, e.g. 0.5)",
+ cxxopts::value<std::string>(func_config.fp_format))
+ ("validate_only", "Validate the network, but do not read inputs or evaluate (0/1)",
+ cxxopts::value<uint32_t>(func_config.validate_only))
+ ("output_tensors", "Output tensors to a file (0/1)", cxxopts::value<uint32_t>(func_config.output_tensors))
+ ("tosa_profile", "Set TOSA profile (0 = Base Inference, 1 = Main Inference, 2 = Main Training)",
+ cxxopts::value<uint32_t>(func_config.tosa_profile))
+ ("dump_intermediates", "Dump intermediate tensors (0/1)", cxxopts::value<uint32_t>(func_config.dump_intermediates))
+ ("v,version", "print model version")
+ ("i,input_tensor_file", "specify input tensor files", cxxopts::value<std::vector<std::string>>())
+ ("l,loglevel", func_debug.get_debug_verbosity_help_string(), cxxopts::value<std::string>())
+ ("o,logfile", "output log file", cxxopts::value<std::string>())
+ ("d,debugmask", func_debug.get_debug_mask_help_string(), cxxopts::value<std::vector<std::string>>())
+ ("h,help", "print help");
+ // clang-format on
+
+ auto result = options.parse(argc, argv);
+ if (result.count("help")) {
+ std::cout << options.help() << std::endl;
+ return 1;
}
- config_param_str_table[i] = (char*)calloc(len, 1);
- ASSERT_MEM(config_param_str_table[i]);
- ASSERT_MSG(len < MAX_NAME_LEN, "option expanded name is too long: %s", config_base_name_table[i]);
-
- if (config_hierarchy_map[i] != BASE)
- {
- snprintf(config_param_str_table[i], len, "%s.%s", config_hier_str_table[config_hierarchy_map[i]],
- config_base_name_table[i]);
+ if (result.count("debugmask")) {
+ auto& v = result["debugmask"].as<std::vector<std::string>>();
+ for (const std::string& s : v)
+ func_debug.set_mask(s);
}
- else
- {
- snprintf(config_param_str_table[i], len, "%s", config_base_name_table[i]);
+ if (result.count("loglevel")) {
+ const std::string& levelstr = result["loglevel"].as<std::string>();
+ func_debug.set_verbosity(levelstr);
}
- }
-
- return 0;
-}
-
-int func_model_set_default_config(func_config_t* func_config)
-{
- // Set default values in the global configuration data structure
- bzero(func_config, sizeof(*func_config));
-
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) func_config->NAME = (DEFAULT);
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) strncpy(func_config->NAME, (DEFAULT), (LEN)-1);
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) func_config->UNIT.NAME = (DEFAULT);
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) strncpy(func_config->UNIT.NAME, (DEFAULT), (LEN)-1);
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-
- return 0;
-}
-
-int func_model_config_cleanup()
-{
- uint32_t i;
-
- if (!config_param_str_table)
- return 1;
-
- for (i = 0; i < CONFIG_PARAMETER_COUNT; i++)
- {
- free(config_param_str_table[i]);
- }
-
- free(config_param_str_table);
- config_param_str_table = nullptr;
-
- return 0;
-}
-
-int func_model_config_set_option(func_config_t* func_config, const char* name, const char* value)
-{
- // Increment an index variable on each parameter position
- // so that we can index both the position struct through the macro and the
- // array of parameter names through a simple array of strings.
- int param_idx = 0;
- char* endptr;
-
- // TODO: does not handle strings yet. Can set magic values on FMT to
- // choose a string copy vs strtoull
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- func_config->NAME = (uint64_t)strtoll(value, &endptr, 0); \
- if (endptr == value) \
- { \
- ARG_ERROR("Cannot parse option: %s = %s", name, value); \
- } \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- if (strlen(value) >= LEN) \
- { \
- ARG_ERROR("Option value is too long: %s = %s", name, value); \
- } \
- strncpy(func_config->NAME, value, (LEN)-1); \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- func_config->UNIT.NAME = (uint64_t)strtoll(value, &endptr, 0); \
- if (endptr == value) \
- { \
- ARG_ERROR("Cannot parse option: %s = %s", name, value); \
- } \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- if (strlen(value) >= LEN) \
- { \
- ARG_ERROR("Option value is too long: %s = %s", name, value); \
- } \
- strncpy(func_config->UNIT.NAME, value, (LEN)-1); \
- return 0; \
- } \
- param_idx++;
-
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-
- // No match!
- ARG_ERROR("Cannot find option: %s", name);
-
- return 1;
-}
-
-int func_model_config_get_option_by_name(func_config_t* func_config, const char* name, uint64_t* val)
-{
- // Increment an index variable on each parameter position
- // so that we can index both the position struct through the macro and the
- // array of parameter names through a simple array of strings.
- int param_idx = 0;
-
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) param_idx++;
-
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, FMT, DEFAULT) param_idx++;
-
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- *val = func_config->NAME; \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- *val = func_config->UNIT.NAME; \
- return 0; \
- } \
- param_idx++;
-
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
- // No match!
- return 1;
-}
-int func_model_config_get_str_option_by_name(func_config_t* func_config,
- const char* name,
- char* value,
- const uint32_t len)
-{
- // Increment an index variable on each parameter position
- // so that we can index both the position struct through the macro and the
- // array of parameter names through a simple array of strings.
- int param_idx = 0;
-
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- strncpy(value, func_config->NAME, len - 1); \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) \
- if (!strcmp(config_param_str_table[param_idx], name)) \
- { \
- strncpy(value, func_config->UNIT.NAME, len - 1); \
- return 0; \
- } \
- param_idx++;
-
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) param_idx++;
-
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) param_idx++;
-
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
- // No match!
- return 1;
-}
-
-int func_config_print_config_help(FILE* out)
-{
- fprintf(out, "%-40s %s\n", "Option", "Description");
- fprintf(out, "%-40s %s\n", "------", "-----------");
-
- for (uint32_t i = 0; i < CONFIG_PARAMETER_COUNT; i++)
- {
- fprintf(out, "-C%-40s %s\n", config_param_str_table[i], config_param_desc_table[i]);
- }
-
- fprintf(out, "\n");
-
- return 0;
-}
-
-int func_model_print_config(func_config_t* func_config, FILE* out)
-{
-#define DEF_UNIT_START(UNIT)
-#define DEF_UNIT_END(UNIT)
-#define DEF_OPTION(NAME, DESC, TYPE, FMT, DEFAULT) fprintf(out, "%-40s = " FMT "\n", #NAME, func_config->NAME);
-#define DEF_UNIT_OPTION(UNIT, NAME, DESC, TYPE, FMT, DEFAULT) \
- fprintf(out, "%-40s = " FMT "\n", #UNIT "." #NAME, func_config->UNIT.NAME);
-#define DEF_OPTION_STR(NAME, DESC, LEN, DEFAULT) fprintf(out, "%-40s = %s\n", #NAME, func_config->NAME);
-#define DEF_UNIT_OPTION_STR(UNIT, NAME, DESC, LEN, DEFAULT) \
- fprintf(out, "%-40s = %s\n", #UNIT "." #NAME, func_config->UNIT.NAME);
-
-#define FOF_HEX "0x%llx"
-#define FOF_DEC "%" PRIu32
-#define FOF_DECU64 "%" PRIu64
-
-#include "func_config.def"
-#undef DEF_UNIT_START
-#undef DEF_UNIT_END
-#undef DEF_OPTION
-#undef DEF_UNIT_OPTION
-#undef DEF_OPTION_STR
-#undef DEF_UNIT_OPTION_STR
-
- return 0;
-}
-
-static const char* programname;
-
-void func_model_print_debug_masks(FILE* out)
-{
- fprintf(out, "\t List of components:\n");
-#define DEBUG_MODE(string, value) fprintf(out, "\t\t" #string "\n");
-#include "debug_modes.def"
-#undef DEBUG_MODE
-}
-
-int func_model_print_help(FILE* out)
-{
- fprintf(out, "TOSA Reference Model help\n\n");
-
- fprintf(out,
- "Usage: %s [-c] [-C <name=value>] [-d <Debug Mask>] [-h] [-l <verbosity>] [-F "
- "<flatconfig>]\n",
- programname);
- fprintf(out, "\t-c - Print list of config options\n");
- fprintf(out, "\t-C <name=value> - modify config option <name> to <value>\n");
- fprintf(out, "\t-d <Debug Mask - set component debug mask\n");
- func_model_print_debug_masks(out);
- fprintf(out, "\t-F <flatconfig> - parse <flatconfig> as file of config options\n");
- fprintf(out, "\t-v - Print refererence model version\n");
- fprintf(out, "\t-h - show this help message and exit\n");
- fprintf(
- out,
- "\t-i <input_tensor_name>,<filename> - set input tensor <input_tensor_name> to the values from <filename>\n");
- fprintf(out, "\t-l <verbosity> - set log verbosity\n");
- fprintf(out, "\t-o <debuglog> - set debug log file\n");
- fprintf(out, "\n");
-
- func_config_print_config_help(stdout);
-
- return 0;
-}
-
-static const char* get_arg_text(int& index, const int argc, const char** argv)
-{
- if (strlen(argv[index]) > 2)
- {
- return argv[index] + 2;
- }
-
- if ((index + 1 == argc) || (argv[index + 1][0] == '-'))
- {
- fprintf(stderr, "No option value found for option %s\n", argv[index]);
- return "";
- }
-
- index++;
- return argv[index];
-}
-
-// Read the command line arguments
-int func_model_parse_cmd_line(
- func_config_t* func_config, func_debug_t* func_debug, const int argc, const char** argv, const char* version)
-{
- int i;
- programname = argv[0];
- for (i = 1; i < argc; i++)
- {
- // All command line arguments must begin with -X where X is a recognized character
- if (strlen(argv[i]) < 2 || argv[i][0] != '-')
- {
- func_model_print_help(stderr);
- ARG_ERROR("Command line argument at position %d not valid: %s", i, argv[i]);
+ if (result.count("logfile")) {
+ func_debug.set_file(result["logfile"].as<std::string>());
}
-
- switch (argv[i][1])
- {
- // Model parameters may be overridden with the -Cname=value switch
- case 'c':
- func_config_print_config_help(stderr);
- return 1;
-
- case 'C':
- {
- const char *name = nullptr, *value = nullptr;
-
- // Break the string into name and value parts
- name = get_arg_text(i, argc, argv);
- value = strchr(name, '=');
-
- if (value == nullptr)
- {
- func_model_print_help(stderr);
- ARG_ERROR("Cannot parse -C argument at position %d: %s", i, argv[i]);
- }
-
- *const_cast<char*>(value) = 0;
-
- if (func_model_config_set_option(func_config, name, value + 1))
- {
- func_model_print_help(stderr);
- ARG_ERROR("Cannot parse -C argument at position %d: %s", i, argv[i]);
- }
- break;
- }
-
- case 'd':
- case 'D':
- {
- func_debug_set_mask(func_debug, get_arg_text(i, argc, argv));
- break;
- }
- case 'F':
- {
- // Read a flat configuration file
- if (func_model_parse_flat_config_file(func_config, get_arg_text(i, argc, argv)))
- return 1;
-
- break;
- }
- case 'h':
- func_model_print_help(stderr);
- return 1;
-
- case 'i':
- {
- // shortcut for '-Cinput_tensor='
- if (func_model_config_set_option(func_config, "input_tensor", get_arg_text(i, argc, argv)))
- {
- func_model_print_help(stderr);
- ARG_ERROR("Cannot set input tensor config value");
- }
- break;
- }
- case 'l':
- {
- // Debug verbosity/logging level
- func_debug_set_verbosity(func_debug, get_arg_text(i, argc, argv));
- break;
- }
- case 'o':
- {
- func_debug_set_file(func_debug, get_arg_text(i, argc, argv));
- break;
- }
- case 'v':
- {
- fprintf(stdout, "Model Version %s\n", version);
- return 1;
- }
- default:
- func_model_print_help(stderr);
- ARG_ERROR("Unrecognized argument at position %d: %s", i, argv[i]);
+ if (result.count("input_tensor_file")) {
+ func_config.ifm_name = result["input_tensor_file"].as<std::string>();
}
+ if (result.count("version")) {
+ std::cout << "Model version " << version << std::endl;
+ }
+ }
+ catch(const std::exception& e)
+ {
+ std::cerr << e.what() << '\n';
+ return 1;
}
return 0;
}
-int func_model_parse_flat_config_file(func_config_t* func_config, const char* filename)
+void func_model_print_help()
{
- const int MAX_LINE_LEN = 1024;
-
- FILE* infile = nullptr;
- char line_buf[MAX_LINE_LEN];
- int line = 1;
-
- infile = fopen(filename, "r");
-
- if (infile == nullptr)
- {
- ARG_ERROR("Cannot open config file: %s\n", filename);
- }
-
- while (fgets(line_buf, MAX_LINE_LEN - 1, infile) != nullptr)
- {
- char *name = line_buf, *value = nullptr, *comment = nullptr, *ptr = nullptr;
-
- // Remove comments
- comment = strchr(line_buf, '#');
-
- if (comment)
- *comment = 0;
- // Break the string into name and value parts
- name = line_buf;
-
- // Remove leading whitespace
- while (*name && isspace(*name))
- name++;
-
- // Empty line?
- if (*name == 0)
- {
- line++;
- continue;
- }
-
- value = strchr(name, '=');
-
- // Missing value
- if (value == nullptr)
- {
- ARG_ERROR("Cannot parse parameter in %s at line %d: %s", filename, line, line_buf);
- }
-
- // Remove the =
- *value = 0;
- value++;
-
- // Trim off any whitespace at the end of the value
- ptr = value;
- while (*ptr != 0 && !isspace(*ptr))
- ptr++;
- *ptr = 0;
-
- // Include a nested file
- if (!strcmp(name, "include"))
- {
- if (func_model_parse_flat_config_file(func_config, value))
- return 1;
- line++;
- continue;
- }
-
- if (func_model_config_set_option(func_config, name, value))
- {
- func_model_print_help(stderr);
- ARG_ERROR("Cannot set parameter in %s at line %d: %s", filename, line, line_buf)
- }
-
- line++;
- }
-
- fclose(infile);
-
- return 0;
}