comparison lib/argp-help.c @ 6484:0346b7d45837

(fill_in_uparams): Check if the constructed struct uparams is valid. Fall back to the default values if it is not.
author Sergey Poznyakoff <gray@gnu.org.ua>
date Sat, 10 Dec 2005 21:37:29 +0000
parents 39f26cf09cc9
children d41048afd9bb
comparison
equal deleted inserted replaced
6483:d39421bbc830 6484:0346b7d45837
88 /* This is true if when DUP_ARGS is false, and some duplicate arguments have 88 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
89 been suppressed, an explanatory message should be printed. */ 89 been suppressed, an explanatory message should be printed. */
90 int dup_args_note; 90 int dup_args_note;
91 91
92 /* Various output columns. */ 92 /* Various output columns. */
93 int short_opt_col; 93 int short_opt_col; /* column in which short options start */
94 int long_opt_col; 94 int long_opt_col; /* column in which long options start */
95 int doc_opt_col; 95 int doc_opt_col; /* column in which doc options start */
96 int opt_doc_col; 96 int opt_doc_col; /* column in which option text starts */
97 int header_col; 97 int header_col; /* column in which group headers are printed */
98 int usage_indent; 98 int usage_indent; /* indentation of wrapped usage lines */
99 int rmargin; 99 int rmargin; /* right margin used for wrapping */
100 100
101 int valid; /* True when the values in here are valid. */ 101 int valid; /* True when the values in here are valid. */
102 }; 102 };
103 103
104 /* This is a global variable, as user options are only ever read once. */ 104 /* This is a global variable, as user options are only ever read once. */
105 static struct uparams uparams = { 105 static struct uparams uparams = {
106 DUP_ARGS, DUP_ARGS_NOTE, 106 DUP_ARGS, DUP_ARGS_NOTE,
130 { "usage-indent", 0, offsetof (struct uparams, usage_indent) }, 130 { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
131 { "rmargin", 0, offsetof (struct uparams, rmargin) }, 131 { "rmargin", 0, offsetof (struct uparams, rmargin) },
132 { 0 } 132 { 0 }
133 }; 133 };
134 134
135 /* Read user options from the environment, and fill in UPARAMS appropiately. */ 135 static void
136 validate_uparams (const struct argp_state *state, struct uparams *upptr)
137 {
138 const struct uparam_name *up;
139
140 for (up = uparam_names; up->name; up++)
141 {
142 if (up->is_bool
143 || up->uparams_offs == offsetof (struct uparams, rmargin))
144 continue;
145 if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
146 {
147 __argp_failure (state, 0, 0,
148 dgettext (state->root_argp->argp_domain,
149 "\
150 ARGP_HELP_FMT: %s value is less then or equal to %s"),
151 "rmargin", up->name);
152 return;
153 }
154 }
155 uparams = *upptr;
156 uparams.valid = 1;
157 }
158
159 /* Read user options from the environment, and fill in UPARAMS appropiately. */
136 static void 160 static void
137 fill_in_uparams (const struct argp_state *state) 161 fill_in_uparams (const struct argp_state *state)
138 { 162 {
139 const char *var = getenv ("ARGP_HELP_FMT"); 163 const char *var = getenv ("ARGP_HELP_FMT");
140 164 struct uparams new_params = uparams;
165
141 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0); 166 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
142 167
143 if (var) 168 if (var)
144 /* Parse var. */ 169 {
145 while (*var) 170 /* Parse var. */
146 { 171 while (*var)
147 SKIPWS (var); 172 {
148 173 SKIPWS (var);
149 if (isalpha (*var)) 174
150 { 175 if (isalpha (*var))
151 size_t var_len; 176 {
152 const struct uparam_name *un; 177 size_t var_len;
153 int unspec = 0, val = 0; 178 const struct uparam_name *un;
154 const char *arg = var; 179 int unspec = 0, val = 0;
155 180 const char *arg = var;
156 while (isalnum (*arg) || *arg == '-' || *arg == '_') 181
157 arg++; 182 while (isalnum (*arg) || *arg == '-' || *arg == '_')
158 var_len = arg - var;
159
160 SKIPWS (arg);
161
162 if (*arg == '\0' || *arg == ',')
163 unspec = 1;
164 else if (*arg == '=')
165 {
166 arg++; 183 arg++;
167 SKIPWS (arg); 184 var_len = arg - var;
168 } 185
169 186 SKIPWS (arg);
170 if (unspec) 187
171 { 188 if (*arg == '\0' || *arg == ',')
172 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-') 189 unspec = 1;
190 else if (*arg == '=')
191 {
192 arg++;
193 SKIPWS (arg);
194 }
195
196 if (unspec)
197 {
198 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
199 {
200 val = 0;
201 var += 3;
202 var_len -= 3;
203 }
204 else
205 val = 1;
206 }
207 else if (isdigit (*arg))
208 {
209 val = atoi (arg);
210 while (isdigit (*arg))
211 arg++;
212 SKIPWS (arg);
213 }
214
215 for (un = uparam_names; un->name; un++)
216 if (strlen (un->name) == var_len
217 && strncmp (var, un->name, var_len) == 0)
173 { 218 {
174 val = 0; 219 if (unspec && !un->is_bool)
175 var += 3; 220 __argp_failure (state, 0, 0,
176 var_len -= 3; 221 dgettext (state->root_argp->argp_domain,
222 "\
223 %.*s: ARGP_HELP_FMT parameter requires a value"),
224 (int) var_len, var);
225 else if (val < 0)
226 __argp_failure (state, 0, 0,
227 dgettext (state->root_argp->argp_domain,
228 "\
229 %.*s: ARGP_HELP_FMT parameter must be positive"),
230 (int) var_len, var);
231 else
232 *(int *)((char *)&new_params + un->uparams_offs) = val;
233 break;
177 } 234 }
178 else 235 if (! un->name)
179 val = 1; 236 __argp_failure (state, 0, 0,
180 } 237 dgettext (state->root_argp->argp_domain, "\
181 else if (isdigit (*arg)) 238 %.*s: Unknown ARGP_HELP_FMT parameter"),
182 { 239 (int) var_len, var);
183 val = atoi (arg); 240
184 while (isdigit (*arg)) 241 var = arg;
185 arg++; 242 if (*var == ',')
186 SKIPWS (arg); 243 var++;
187 } 244 }
188 245 else if (*var)
189 for (un = uparam_names; un->name; un++) 246 {
190 if (strlen (un->name) == var_len
191 && strncmp (var, un->name, var_len) == 0)
192 {
193 if (unspec && !un->is_bool)
194 __argp_failure (state, 0, 0,
195 dgettext (state->root_argp->argp_domain, "\
196 %.*s: ARGP_HELP_FMT parameter requires a value"),
197 (int) var_len, var);
198 else
199 *(int *)((char *)&uparams + un->uparams_offs) = val;
200 break;
201 }
202 if (! un->name)
203 __argp_failure (state, 0, 0, 247 __argp_failure (state, 0, 0,
204 dgettext (state->root_argp->argp_domain, "\ 248 dgettext (state->root_argp->argp_domain,
205 %.*s: Unknown ARGP_HELP_FMT parameter"), 249 "Garbage in ARGP_HELP_FMT: %s"), var);
206 (int) var_len, var); 250 break;
207 251 }
208 var = arg; 252 }
209 if (*var == ',') 253 validate_uparams (state, &new_params);
210 var++; 254 }
211 }
212 else if (*var)
213 {
214 __argp_failure (state, 0, 0,
215 dgettext (state->root_argp->argp_domain,
216 "Garbage in ARGP_HELP_FMT: %s"), var);
217 break;
218 }
219 }
220 } 255 }
221 256
222 /* Returns true if OPT hasn't been marked invisible. Visibility only affects 257 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
223 whether OPT is displayed or used in sorting, not option shadowing. */ 258 whether OPT is displayed or used in sorting, not option shadowing. */
224 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN)) 259 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))