Age Owner Branch data TLA Line data Source code
1 : : /*-------------------------------------------------------------------------
2 : : *
3 : : * Command line option processing facilities for frontend code
4 : : *
5 : : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
6 : : * Portions Copyright (c) 1994, Regents of the University of California
7 : : *
8 : : * src/fe_utils/option_utils.c
9 : : *
10 : : *-------------------------------------------------------------------------
11 : : */
12 : :
13 : : #include "postgres_fe.h"
14 : :
15 : : #include "common/logging.h"
16 : : #include "common/string.h"
17 : : #include "fe_utils/option_utils.h"
18 : :
19 : : /*
20 : : * Provide strictly harmonized handling of --help and --version
21 : : * options.
22 : : */
23 : : void
1864 rhaas@postgresql.org 24 :CBC 347 : handle_help_version_opts(int argc, char *argv[],
25 : : const char *fixed_progname, help_handler hlp)
26 : : {
27 [ + + ]: 347 : if (argc > 1)
28 : : {
29 [ + + - + ]: 343 : if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
30 : : {
31 : 11 : hlp(get_progname(argv[0]));
32 : 11 : exit(0);
33 : : }
34 [ + + + + ]: 332 : if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
35 : : {
36 : 29 : printf("%s (PostgreSQL) " PG_VERSION "\n", fixed_progname);
37 : 29 : exit(0);
38 : : }
39 : : }
40 : 307 : }
41 : :
42 : : /*
43 : : * option_parse_int
44 : : *
45 : : * Parse integer value for an option. If the parsing is successful, returns
46 : : * true and stores the result in *result if that's given; if parsing fails,
47 : : * returns false.
48 : : */
49 : : bool
1695 michael@paquier.xyz 50 : 249 : option_parse_int(const char *optarg, const char *optname,
51 : : int min_range, int max_range,
52 : : int *result)
53 : : {
54 : : char *endptr;
55 : : int val;
56 : :
57 : 249 : errno = 0;
58 : 249 : val = strtoint(optarg, &endptr, 10);
59 : :
60 : : /*
61 : : * Skip any trailing whitespace; if anything but whitespace remains before
62 : : * the terminating character, fail.
63 : : */
1692 64 [ + + + + ]: 250 : while (*endptr != '\0' && isspace((unsigned char) *endptr))
65 : 1 : endptr++;
66 : :
67 [ + + ]: 249 : if (*endptr != '\0')
68 : : {
1695 69 : 6 : pg_log_error("invalid value \"%s\" for option %s",
70 : : optarg, optname);
71 : 6 : return false;
72 : : }
73 : :
74 [ + - + + : 243 : if (errno == ERANGE || val < min_range || val > max_range)
- + ]
75 : : {
76 : 11 : pg_log_error("%s must be in range %d..%d",
77 : : optname, min_range, max_range);
78 : 11 : return false;
79 : : }
80 : :
81 [ + + ]: 232 : if (result)
82 : 226 : *result = val;
83 : 232 : return true;
84 : : }
85 : :
86 : : /*
87 : : * Provide strictly harmonized handling of the --sync-method option.
88 : : */
89 : : bool
921 nathan@postgresql.or 90 : 1 : parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
91 : : {
92 [ - + ]: 1 : if (strcmp(optarg, "fsync") == 0)
921 nathan@postgresql.or 93 :UBC 0 : *sync_method = DATA_DIR_SYNC_METHOD_FSYNC;
921 nathan@postgresql.or 94 [ + - ]:CBC 1 : else if (strcmp(optarg, "syncfs") == 0)
95 : : {
96 : : #ifdef HAVE_SYNCFS
97 : 1 : *sync_method = DATA_DIR_SYNC_METHOD_SYNCFS;
98 : : #else
99 : : pg_log_error("this build does not support sync method \"%s\"",
100 : : "syncfs");
101 : : return false;
102 : : #endif
103 : : }
104 : : else
105 : : {
921 nathan@postgresql.or 106 :UBC 0 : pg_log_error("unrecognized sync method: %s", optarg);
107 : 0 : return false;
108 : : }
109 : :
921 nathan@postgresql.or 110 :CBC 1 : return true;
111 : : }
112 : :
113 : : /*
114 : : * Fail with appropriate error if 2 or more of the specified options are set.
115 : : * The first parameter is the number of arguments. Following that is an
116 : : * arbitrary number of bool/string pairs. The bool indicates whether the
117 : : * option is set, and the string is used for the error message. Note that only
118 : : * the first pair of enabled options we find are reported.
119 : : *
120 : : * Don't call this directly. Use the check_mut_excl_opts() macro in
121 : : * option_utils.h, which is the exact same except it doesn't take the first
122 : : * parameter (it discovers the number of arguments automagically).
123 : : */
124 : : void
9 nathan@postgresql.or 125 :GNC 4067 : check_mut_excl_opts_internal(int n,...)
126 : : {
127 : 4067 : char *first = NULL;
128 : : va_list args;
129 : :
130 [ - + ]: 4067 : Assert(n % 2 == 0);
131 : :
132 : 4067 : va_start(args, n);
133 [ + + ]: 13749 : for (int i = 0; i < n; i += 2)
134 : : {
135 : 9715 : bool set = va_arg(args, int);
136 : 9715 : char *opt = va_arg(args, char *);
137 : :
138 [ + + + + ]: 9715 : if (set && first)
139 : 33 : pg_fatal("options %s and %s cannot be used together",
140 : : first, opt);
141 : :
142 [ + + ]: 9682 : if (set)
143 : 774 : first = opt;
144 : : }
145 : 4034 : va_end(args);
146 : 4034 : }
|