📄 params.c
字号:
/* * params.c: Parameter file and command line parsing * * Written by: Stefan Frank * Ullrich Hafner * * This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) * Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> *//* * $Date: 2000/07/15 17:24:21 $ * $Author: hafner $ * $Revision: 5.2 $ * $State: Exp $ */#define _BSD_SOURCE 1 /* Make sure strdup() is in string.h */#define _XOPEN_SOURCE 500 /* Make sure strdup() is in string.h */#include "config.h"#include <stdio.h>#include <ctype.h>#include <math.h> /* strtod() on SUN sparc */#include <stdlib.h>#include <string.h> #include <getopt.h> /* system or ../lib */#include "nstring.h"#include "types.h"#include "macros.h"#include "bit-io.h"#include "misc.h"#include "fiasco.h"#include "binerror.h"#include "params.h"/***************************************************************************** prototypes *****************************************************************************/static voidread_parameter_file (param_t *params, FILE *file);static intget_parameter_index (const param_t *params, const char *search_string);static voidset_parameter (param_t *parameter, const char *value);static void usage (const param_t *params, const char *progname, const char *synopsis, const char *comment, const char *non_opt_string, bool_t show_all_options, const char *sys_file_name, const char *usr_file_name);/***************************************************************************** public code *****************************************************************************/intparseargs (param_t *usr_params, int argc, char **argv, const char *synopsis, const char *comment, const char *non_opt_string, const char *path, const char *sys_file_name, const char *usr_file_name)/* * Perform the command line parsing. * List of allowed parameters is given by 'usr_params'. * Command line and number of parameters are given by 'argv' and 'argc'. * 'synopsis' contains a brief description of the program and * 'comment' may contain some additional advice. * Initialization order of parameters: * 1.) Default values given by the param_t struct * 2.) System parameter-file ('path'/'sys_file_name') * 3.) User parameter-file ($HOME/'usr_file_name') * 4.) Command line parameters * 5.) Parameter-file forced by option -f (--config-file) * * Return value: * index in ARGV of the first ARGV-element that is not an option. * * Side effects: * the elements of ARGV are permuted * usr_params [].value is modified */{ extern int optind; /* index in ARGV of the 1st element that is not an option */ bool_t detailed_help = NO; /* NO if all parameters can be modified with short options too */ unsigned n1; /* number of user parameters */ unsigned n2; /* number of system parameters */ bool_t read_config_file = NO; /* will override command line */ param_t *params; /* array of user and system params */ param_t *sys_params; /* array of system parameters */ param_t detailed_sys_params [] = /* detailed system parameters */ { {"version", NULL, 'v', PFLAG, {0}, NULL, "Print program version number, then exit."}, {"verbose", "NUM", 'V', PINT, {0}, "1", "Set level of verbosity to `%s'."}, {"config", "FILE", 'f', PSTR, {0}, NULL, "Load `%s' to initialize parameters."}, {"info", NULL, 'h', PFLAG, {0}, NULL, "Print brief help, then exit."}, {"help", NULL, 'H', PFLAG, {0}, NULL, "Print detailed help, then exit."}, {NULL, NULL, 0, PSTR, {0}, NULL, NULL } }; param_t short_sys_params [] = /* short system parameters */ { {"version", NULL, 'v', PFLAG, {0}, NULL, "Print program version number, then exit."}, {"verbose", "NUM", 'V', PINT, {0}, "1", "Set level of verbosity to `%s'."}, {"config", "FILE", 'f', PSTR, {0}, NULL, "Load `%s' to initialize parameters."}, {"help", NULL, 'h', PFLAG, {0}, NULL, "Print this help, then exit."}, {NULL, NULL, 0, PSTR, {0}, NULL, NULL } }; char *sys_path; /* path to system config file */ sys_path = calloc (strlen (path) + strlen (sys_file_name) + 2, sizeof (char)); if (!sys_path) error ("Out of memory."); sprintf (sys_path, "%s/%s", path, sys_file_name); /* * Set parameters defaults */ { param_t *p; for (p = usr_params; p->name != NULL; p++) { set_parameter (p, p->default_value); if (p->optchar == '\0') detailed_help = YES; } sys_params = detailed_help ? detailed_sys_params : short_sys_params; for (p = sys_params; p->name != NULL; p++) set_parameter (p, p->default_value); } /* * Append system command line option to user parameters */ for (n1 = 0; usr_params [n1].name != NULL; n1++) ; for (n2 = 0; sys_params [n2].name != NULL; n2++) ; params = calloc (n1 + n2 + 1, sizeof (param_t)); if (!params) error ("Out of memory."); memcpy (params, usr_params, n1 * sizeof (param_t)); memcpy (params + n1, sys_params, (n2 + 1) * sizeof (param_t)); /* * Try to open the system resource file 'path'/'sys_file_name' */ { FILE *parameter_file = open_file (sys_path, NULL, READ_ACCESS); if (parameter_file == NULL)/* warning ("No system resource file found.");*/ {} else { read_parameter_file (params, parameter_file); fclose (parameter_file); } } /* * Try to read user resource file $HOME/'usr_file_name' */ { FILE *parameter_file = open_file (usr_file_name, "HOME", READ_ACCESS); if (parameter_file != NULL) { read_parameter_file (params, parameter_file); fclose (parameter_file); } } /* * Parse command line options */ { extern char *optarg; /* argument of current option */ struct option *long_options; /* array of long options */ int option_index = 0; char optstr [MAXSTRLEN]; /* string containing the legitimate option characters */ int optchar; /* found option character */ /* * Build short option string for getopt_long (). */ { param_t *p; /* counter */ char *ptr_optstr; /* pointer to position in string */ ptr_optstr = optstr; for (p = params; p->name != NULL; p++) if (p->optchar != '\0') { *ptr_optstr++ = p->optchar; if (p->type == POSTR) { *ptr_optstr++ = ':'; *ptr_optstr++ = ':'; } else if (p->type != PFLAG) *ptr_optstr++ = ':'; } *ptr_optstr = '\0'; } /* * Build long option string for getopt_long (). */ { int i; long_options = calloc (n1 + n2 + 1, sizeof (struct option)); if (!long_options) error ("Out of memory."); for (i = 0; params [i].name != NULL; i++) { long_options [i].name = params [i].name; switch (params [i].type) { case PFLAG: long_options [i].has_arg = 0; break; case POSTR: long_options [i].has_arg = 2; break; case PINT: case PSTR: case PFLOAT: default: long_options [i].has_arg = 1; break; } long_options [i].has_arg = params [i].type != PFLAG; long_options [i].flag = NULL; long_options [i].val = 0; } } /* * Parse comand line */ while ((optchar = getopt_long (argc, argv, optstr, long_options, &option_index)) != EOF) { int param_index = -1; switch (optchar) { case 0: param_index = option_index; break; case ':': if (detailed_help) fprintf (stderr, "Try `%s -h' or `%s --help' for " "more information.\n", argv [0], argv [0]); else fprintf (stderr, "Try `%s --help' for more information.\n", argv [0]); exit (2); break; case '?': if (detailed_help) fprintf (stderr, "Try `%s -h' or `%s --help' " "for more information.\n", argv [0], argv [0]); else fprintf (stderr, "Try `%s --help' for more information.\n", argv [0]); exit (2); break; default: { int i; for (i = 0; params [i].name != NULL; i++) if (params [i].optchar == optchar) { param_index = i; break; } } } /* * Check for system options */ if (param_index >= 0) { set_parameter (params + param_index, optarg ? optarg : ""); if (streq (params [param_index].name, "help")) usage (params, argv [0], synopsis, comment, non_opt_string, YES, sys_path, usr_file_name); else if (streq (params [param_index].name, "info")) usage (params, argv [0], synopsis, comment, non_opt_string, NO, sys_path, usr_file_name); else if (streq (params [param_index].name, "version")) { fprintf (stderr, "%s " VERSION "\n", argv [0]); exit (2); } else if (streq (params [param_index].name, "verbose")) fiasco_set_verbosity ( * (fiasco_verbosity_e *) parameter_value (params, "verbose")); else if (streq (params [param_index].name, "config")) read_config_file = YES; param_index = -1; /* clear index flag */ } } free (long_options); } /* * Read config-file if specified by option -f */ if (read_config_file) { char *filename; if ((filename = (char *) parameter_value (params, "config")) != NULL) { FILE *parameter_file; /* input file */ warning ("Options set in file `%s' will override" " command line options.", filename); parameter_file = open_file (filename, NULL, READ_ACCESS); if (parameter_file != NULL) { read_parameter_file (params, parameter_file); fclose (parameter_file); } else file_error (filename); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -