OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
argpar-help.c
Go to the documentation of this file.
1 #include "argpar.h"
2 
3 #include <ctype.h>
4 #include <errno.h>
5 #include <limits.h>
6 #include <stdbool.h>
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #define OPT_COL 2 /* column in which long options start */
11 #define DOC_OPT_COL 2 /* column in which doc options start */
12 #define OPT_DOC_COL 29 /* column in which option text starts */
13 #define DOC_COL 2 /* column in which group documents are printed */
14 #define ENUM_COL 8 /* column in which enum documents are printed */
15 #define ALIAS_COL 4 /* column in which alias documents are printed */
16 #define HEADER_COL 1 /* column in which group headers are printed */
17 #define WRAP_INDENT 12 /* indentation of wrapped lines */
18 #define RMARGIN 79 /* right margin used for wrapping */
19 
20 static int print_wrapped(argpar* p, const char *doc, size_t *current_column, int indent, int filter_key) {
21  char *text;
22  if (filter_key && p->help_filter) {
23  text = p->help_filter(filter_key, doc, NULL);
24  if (text == doc) {
25  text = strdup(doc);
26  if (text == NULL) {
27  return ENOMEM;
28  }
29  }
30  } else if (doc) {
31  text = strdup(doc);
32  if (text == NULL) {
33  return ENOMEM;
34  }
35  } else {
36  return -1;
37  }
38  if (text) {
39  char *d = text;
40  size_t doc_length = strlen(d);
41  switch (filter_key) {
43  doc_length++;
44  fprintf(argpar_ostream, " ");
45  break;
48  fprintf(argpar_ostream, "\n");
49  if (current_column) {
50  *current_column = 0;
51  }
52  break;
53  }
54  size_t desired_length = RMARGIN;
55  if (current_column) {
56  desired_length -= *current_column;
57  }
58  while (doc_length && doc_length > desired_length) {
59  char *doc_end = d;
60  size_t length_to_print = 0;
61 
62  while (length_to_print <= desired_length && *doc_end != '\n') {
63  length_to_print++;
64  doc_end++;
65  }
66 
67  char tmp_char = 0;
68  if (!isspace(*doc_end)) {
69  while (!isspace(*doc_end) && length_to_print) {
70  doc_end--;
71  length_to_print--;
72  }
73  if (length_to_print == 0) {
74  length_to_print = desired_length;
75  }
76  }
77 
78  tmp_char = d[length_to_print];
79  d[length_to_print] = '\0';
80 
81  fprintf(argpar_ostream, "%s\n", d);
82  fprintf(argpar_ostream, "%*s", indent, "");
83 
84  if (tmp_char == '\n') {
85  fprintf(argpar_ostream, "\n");
86  }
87 
88  if (tmp_char) {
89  d[length_to_print] = tmp_char;
90  tmp_char = 0;
91  }
92  d += length_to_print;
93  while (isspace(*d)) {
94  d++;
95  }
96  doc_length = strlen(d);
97  desired_length = RMARGIN;
98  }
99  fprintf(argpar_ostream, "%s", d);
100  if (current_column) {
101  *current_column = strlen(d);
102  }
103  switch (filter_key) {
106  fprintf(argpar_ostream, "\n");
107  if (current_column) {
108  *current_column = 0;
109  }
110  break;
111  }
112  if (text != doc) {
113  free(text);
114  }
115  }
116  return 0;
117 }
118 
119 static const char *get_arg_text(const argpar_option *o) {
120  const char *arg;
121  if (o->arg) {
122  arg = o->arg;
123  } else if (o->flags & OPTION_DBL) {
124  arg = "DBL";
125  } else if (o->flags & OPTION_INT) {
126  arg = "INT";
127  } else {
128  arg = "ARG";
129  }
130  return arg;
131 }
132 
133 typedef enum {
134  HEADER = 1, OPTION = 2, DOC = 3
135 } option_type;
136 typedef enum {
138 } child_type;
139 typedef struct item_counts {
140  unsigned header;
141  unsigned option;
142  unsigned doc;
143 } item_counts;
144 
145 // all the group/option stuff should probably be pre-processed, like in argp (see clusters), but it works fine
146 static int print_all_options(const argpar_child *c, bool is_parent); // should prototype all group ones so this looks less weird
147 
148 static int _print_group(const argpar_child *c, bool is_parent, option_type type, int group, child_type merged, item_counts *counts) {
149 // printf("%s %p, group %d, type %d, not merged %d\n", c->header ? "child" : "parent", c->argpar, group, type, merged);
150  argpar *p = c->argpar;
151  bool printed = false;
152  if ((merged == NOT_MERGED && c->header && group == c->group) || (merged == MERGED && !c->header)) {
153  printed = true;
154  if (c->header) {
155 // if (counts->doc || counts->option || counts->header){
156 // fprintf(argpar_ostream, "\n");
157 // }
158  if (strlen(c->header)) {
159  fprintf(argpar_ostream, "\n%*s", HEADER_COL, "");
160  size_t cur_column = HEADER_COL;
161  if (print_wrapped(p, c->header, &cur_column, HEADER_COL, ARGPAR_KEY_HELP_HEADER)) {
162  return 1;
163  }
164 // fprintf(argpar_ostream, "\n");
165  counts->header += 1;
166  }
167  argpar_child merged_child = { c->argpar, c->flags, NULL, 0 };
168  print_all_options(&merged_child, false);
169  } else {
170  const argpar_option *o = p->options;
171  int i = -1, cur_group = 0;
172  const argpar_option *base_option = NULL;
173  while (o[++i].name || o[i].doc) {
174  int is_doc = o[i].flags & OPTION_DOC;
175  if (!group && (o[i].group || (!o[i].name && !is_doc))) {
176  break;
177  } else if (o[i].group) {
178  cur_group = o[i].group;
179  } else if (!o[i].name && !is_doc) {
180  if (cur_group < 0) {
181  cur_group--;
182  } else {
183  cur_group++;
184  }
185  }
186 
187  if (cur_group == group && !(o[i].flags & OPTION_HIDDEN) && !((o[i].flags & OPTION_PARENT) && !is_parent) && !((o[i].flags & OPTION_CHILD) && is_parent)) {
188  switch (type) {
189  case HEADER:
190  if (!o[i].name && !(o[i].flags & OPTION_DOC)) {
191  fprintf(argpar_ostream, "\n%*s", HEADER_COL, "");
192  size_t cur_column = HEADER_COL;
193  if (print_wrapped(p, o[i].doc, &cur_column, HEADER_COL, ARGPAR_KEY_HELP_HEADER)) {
194  return 1;
195  }
196  fprintf(argpar_ostream, "\n");
197  counts->header += 1;
198  }
199  break;
200  case OPTION:
201  if (o[i].name) {
202  if (!(counts->doc || counts->option || counts->header)) {
203  fprintf(argpar_ostream, "\n");
204  }
205  if (!(o[i].flags & (OPTION_DOC | OPTION_ALIAS))){
206  base_option = &o[i];
207  }
208  size_t cur_column = 0;
209  if ((o[i].flags & OPTION_ENUM) == OPTION_ENUM) {
210  fprintf(argpar_ostream, "%*s%s", ENUM_COL, "", o[i].name);
211  cur_column = ENUM_COL + strlen(o[i].name);
212  } else if ((o[i].flags & OPTION_ALIAS) == OPTION_ALIAS) {
213  fprintf(argpar_ostream, "%*s%s", ALIAS_COL, "", o[i].name);
214  cur_column = ALIAS_COL + strlen(o[i].name);
215  } else if (o[i].flags & OPTION_DOC) {
216  fprintf(argpar_ostream, "%*s%s", DOC_OPT_COL, "", o[i].name);
217  cur_column = DOC_OPT_COL + strlen(o[i].name);
218  } else {
219  fprintf(argpar_ostream, "%*s", OPT_COL, "");
220  const char *arg = get_arg_text(&o[i]);
221  fprintf(argpar_ostream, "%s=%s", o[i].name, arg);
222  cur_column = OPT_COL + strlen(o[i].name) + 1 + strlen(arg); // equals sign = 1
223  }
224 
225  if (o[i].doc) {
226  if ((cur_column + 1) > OPT_DOC_COL) { // +1 to ensure a space between opt and doc
227  fprintf(argpar_ostream, "\n%*s", (int) (cur_column = WRAP_INDENT), "");
228  } else {
229  fprintf(argpar_ostream, "%*s", (int) (OPT_DOC_COL - cur_column), "");
230  cur_column = OPT_DOC_COL;
231  }
232  if (print_wrapped(p, o[i].doc, &cur_column, WRAP_INDENT, o[i].key)) {
233  return 1;
234  }
235  } else if ((o[i].flags & OPTION_ALIAS) == OPTION_ALIAS){
236  if ((cur_column + 1) > OPT_DOC_COL) { // +1 to ensure a space between opt and doc
237  fprintf(argpar_ostream, "\n%*s", (int) (cur_column = WRAP_INDENT), "");
238  } else {
239  fprintf(argpar_ostream, "%*s", (int) (OPT_DOC_COL - cur_column), "");
240  cur_column = OPT_DOC_COL;
241  }
242  char new_doc[12 + strlen(base_option->name)];
243  sprintf(new_doc, "Alias for '%s'", base_option->name);
244  if (print_wrapped(p, new_doc, &cur_column, WRAP_INDENT, o[i].key)) {
245  return 1;
246  }
247  }
248  fprintf(argpar_ostream, "\n");
249  counts->option += 1;
250  }
251  break;
252  case DOC:
253  if (!o[i].name && (o[i].flags & OPTION_DOC)) {
254 // if (counts->doc || counts->option || counts->header){
255  fprintf(argpar_ostream, "\n");
256 // }
257  fprintf(argpar_ostream, "%*s", DOC_COL, "");
258  size_t cur_column = DOC_COL;
259  if (print_wrapped(p, o[i].doc, &cur_column, DOC_COL, ARGPAR_KEY_HELP_OPTION_DOC)) {
260  return 1;
261  }
262  if (!(o[i].flags & OPTION_DOC_NO_BREAK)) {
263  fprintf(argpar_ostream, "\n");
264  }
265  counts->doc += 1;
266  }
267  break;
268  }
269  }
270  }
271  }
272  }
273 
274  if (p->children && (printed || merged == NOT_MERGED)) {
275  const argpar_child *c;
276  for (c = p->children; c->argpar; c++) {
277  if (_print_group(c, false, type, group, merged, counts)) {
278  return 1;
279  }
280  }
281  }
282 
283  return 0;
284 }
285 
286 static int print_group(const argpar_child *c, bool is_parent, int group, child_type merged, item_counts *counts) {
288  if (merged == MERGED) {
289  for (type = HEADER; type <= DOC; type++) {
290  if (_print_group(c, is_parent, type, group, merged, counts)) {
291  return 1;
292  }
293  }
294  } else {
295  if (_print_group(c, is_parent, HEADER, group, merged, counts)) {
296  return 1;
297  }
298  }
299  return 0;
300 }
301 
302 static int print_args(const argpar_child *c, size_t *cur_column) {
303  argpar *p = c->argpar;
304  if (p) {
305  if (p->args_doc) {
306  print_wrapped(p, p->args_doc, cur_column, WRAP_INDENT, ARGPAR_KEY_HELP_ARGS_DOC);
307  }
308 // if (p->options){
309 // const argpar_option *o = p->options;
310 // int i = -1;
311 // while (o[++i].name || o[i].doc){
312 // if (!o[i].name || (o[i].flags & OPTION_HIDDEN) || (o[i].flags & OPTION_NO_USAGE) || (o[i].flags & OPTION_DOC)){
313 // continue;
314 // } else if ((o[i].flags & OPTION_ARG_OPTIONAL) == 0){ // required option
315 // const char *arg = get_arg_text(o);
316 // int adding_cols = strlen(o[i].name) + strlen(arg) + 1;
317 // if ((*cur_column + adding_cols) > RMARGIN){
318 // fprintf(argpar_ostream, "\n%*s", WRAP_INDENT, "");
319 // *cur_column = WRAP_INDENT;
320 // }
321 // fprintf(argpar_ostream, "%s=%s ", o[i].name, arg);
322 // *cur_column += adding_cols;
323 // }
324 // }
325 // }
326  if (p->children) {
327  const argpar_child *c;
328  for (c = p->children; c->argpar; c++) {
329  if (print_args(c, cur_column)) {
330  return 1;
331  }
332  }
333  }
334  }
335  return 0;
336 }
337 
338 typedef struct group_limits {
339  int max, min;
340 } group_limits;
341 
342 static int find_group_limits(const argpar_child *c, group_limits *l) {
343  argpar *p = c->argpar;
344  if (p && p->options) {
345  if (c->group > l->max) {
346  l->max = c->group;
347  }
348  if (c->group < l->min) {
349  l->min = c->group;
350  }
351  if (!c->header) {
352  const argpar_option *o = p->options;
353  int i = -1, cur_group = 0;
354  while (o[++i].name || o[i].doc) {
355  if (o[i].group) {
356  cur_group = o[i].group;
357  } else if (!o[i].name && !(o[i].flags & OPTION_DOC)) {
358  if (cur_group < 0) {
359  cur_group--;
360  } else {
361  cur_group++;
362  }
363  }
364  if (cur_group > l->max) {
365  l->max = cur_group;
366  }
367  if (cur_group < l->min) {
368  l->min = cur_group;
369  }
370  }
371  if (p->children) {
372  const argpar_child *c;
373  for (c = p->children; c->argpar; c++) {
374  if (find_group_limits(c, l)) {
375  return 1;
376  }
377  }
378  }
379  }
380  }
381  return 0;
382 }
383 
384 static int print_all_options(const argpar_child *c, bool is_parent) {
385  group_limits g_lims = { .min = INT_MAX, .max = INT_MIN };
386  find_group_limits(c, &g_lims);
387 
388  int group_i; // really need to get rid of the following copy pasta
389  for (group_i = 0; group_i <= g_lims.max; group_i++) {
390  item_counts counts = { 0, 0, 0 };
391  if (print_group(c, is_parent, group_i, MERGED, &counts)) {
392  return 1;
393  }
394  if (print_group(c, is_parent, group_i, NOT_MERGED, &counts)) {
395  return 1;
396  }
397  }
398  for (group_i = g_lims.min; group_i < 0; group_i++) {
399  item_counts counts = { 0, 0, 0 };
400  if (print_group(c, is_parent, group_i, MERGED, &counts)) {
401  return 1;
402  }
403  if (print_group(c, is_parent, group_i, NOT_MERGED, &counts)) {
404  return 1;
405  }
406  }
407  return 0;
408 }
409 
410 static int print_ending_doc(const argpar_child *c) {
411  argpar *p = c->argpar;
412  if (p->doc) {
413  char *ending_doc = strchr(p->doc, '\v');
414  if (ending_doc) {
415  int printed = print_wrapped(p, ending_doc + 1, 0, 0, ARGPAR_KEY_HELP_POST_DOC);
416  if (printed > 0) {
417  return 1;
418  } else if (printed) {
419  fprintf(argpar_ostream, "\n");
420  }
421  }
422  }
423 
424  if (p->children) {
425  const argpar_child *c;
426  for (c = p->children; c->argpar; c++) {
427  if (print_ending_doc(c)) {
428  return 1;
429  }
430  }
431  }
432  return 0;
433 }
434 
435 #if HAVE_DECL_PROGRAM_INVOCATION_NAME
436 // stolen directly from argp
437 static char *nondestructive_basename(char *name) {
438  char *short_name = strrchr (name, '/');
439  return short_name ? short_name + 1 : name;
440 }
441 #endif
442 
443 // mostly stolen from argp
444 static char *program_name() {
445 #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
446  return program_invocation_short_name;
447 #elif HAVE_DECL_PROGRAM_INVOCATION_NAME
448  return nondestructive_basename(program_invocation_name);
449 #else
450  return (argpar_program_name ? (char*) argpar_program_name : "<cmd>");
451 #endif
452 }
453 
454 static int _argpar_print_usage(argpar *p, unsigned flags) {
455  const argpar_child base_argpar = { p, flags, NULL, 0 };
456  if (!argpar_ostream) {
458  }
459  char *progname = program_name();
460  fprintf(argpar_ostream, "Usage: %s", progname);
461 
462  size_t cur_column = 8 + strlen(progname); // "Usage: " + space padding after program name
463 
464  print_args(&base_argpar, &cur_column);
465  fprintf(argpar_ostream, "\n");
466 
467  if (p->doc) {
468  char *ending_doc = strchr(p->doc, '\v');
469  if (ending_doc) {
470  size_t new_doc_length = strlen(p->doc) - strlen(ending_doc);
471  char new_doc[new_doc_length + 1];
472  strncpy(new_doc, p->doc, new_doc_length);
473  new_doc[new_doc_length] = '\0';
474  if (print_wrapped(p, new_doc, 0, 0, ARGPAR_KEY_HELP_PRE_DOC)) {
475  return 1;
476  }
477  } else {
478  if (print_wrapped(p, p->doc, 0, 0, ARGPAR_KEY_HELP_PRE_DOC)) {
479  return 1;
480  }
481  }
482  fprintf(argpar_ostream, "\n");
483  }
484 // fprintf(argpar_ostream, "\n");
485 
486  if (print_all_options(&base_argpar, true)) {
487  return 1;
488  }
489 
490  if (p->children) {
491  print_ending_doc(&base_argpar);
492  }
493 
494  print_wrapped(p, NULL, 0, 0, ARGPAR_KEY_HELP_EXTRA);
495  if (p->children) {
496  const argpar_child *c;
497  for (c = p->children; c->argpar; c++) {
498  if (print_wrapped(c->argpar, NULL, 0, 0, ARGPAR_KEY_HELP_EXTRA)) {
499  return 1;
500  }
501  }
502  }
503  return 0;
504 }
505 
507  return _argpar_print_usage(state->argpar, state->flags);
508 }
510  return _argpar_print_usage(argpar, 0);
511 }
512 int argpar_help(argpar *argpar, FILE *stream, unsigned flags, char *name) {
513  argpar_ostream = stream;
514  if (name != NULL) {
516  }
517  return _argpar_print_usage(argpar, flags);
518 }
Master structure containing options, document strings, child parsers, and text filters....
Definition: argpar.h:398
unsigned doc
Definition: argpar-help.c:142
option_type
Definition: argpar-help.c:133
#define ARGPAR_KEY_HELP_PRE_DOC
Passed as the key to each help filter when printing the doc string before options are listed....
Definition: argpar.h:315
@ DOC
Definition: argpar-help.c:134
#define DOC_COL
Definition: argpar-help.c:13
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
#define OPTION_DOC_NO_BREAK
Do not add an extra newline after this documentation string. Useful for lists and manual formatting.
Definition: argpar.h:171
FILE * argpar_ostream
Definition: argpar-help.c:5
#define NULL
Definition: decode_rs.h:63
unsigned header
Definition: argpar-help.c:140
#define OPTION_INT
Cast this option as a long. The value and any error will be reflected in the argpar_state struct duri...
Definition: argpar.h:160
#define ALIAS_COL
Definition: argpar-help.c:15
uint8 * counts
Definition: l1_czcs_hdf.c:30
child_type
Definition: argpar-help.c:136
Child parser for nesting argpars.
Definition: argpar.h:377
#define RMARGIN
Definition: argpar-help.c:18
unsigned option
Definition: argpar-help.c:141
#define ARGPAR_KEY_HELP_POST_DOC
Passed as the key to each help filter when printing the doc string after all options are listed,...
Definition: argpar.h:320
int argpar_help(argpar *argpar, FILE *stream, unsigned flags, char *name)
Print the default usage summary with all available sections.
Definition: argpar-help.c:512
int state(double tjdTDB, JPLIntUtilType *util, double posvel[13][6], double *pnut)
#define OPTION_ENUM
This option serves to document a valid value for an option. This is not enforced by argpar.
Definition: argpar.h:179
#define ARGPAR_KEY_HELP_OPTION_DOC
Passed as the key to each help filter when printing a group's trailing documentation.
Definition: argpar.h:326
int flags
Modify the behavior of the argument by OR'ing one or more OPTION_ macros.
Definition: argpar.h:100
char * strdup(const char *)
#define HEADER_COL
Definition: argpar-help.c:16
#define OPTION_HIDDEN
Do not display this option anywhere in the usage summary.
Definition: argpar.h:149
#define ARGPAR_KEY_HELP_HEADER
Passed as the key to each help filter when printing a group header.
Definition: argpar.h:323
int argpar_usage(argpar_state *state)
Print usage summary, called within a argpar_parser.
Definition: argpar-help.c:506
#define OPT_COL
Definition: argpar-help.c:10
@ MERGED
Definition: argpar-help.c:137
#define ARGPAR_KEY_HELP_EXTRA
Passed as the key to each help filter after all other documentation is printed, to return extra infor...
Definition: argpar.h:330
#define ENUM_COL
Definition: argpar-help.c:14
#define isspace(c)
@ NOT_MERGED
Definition: argpar-help.c:137
@ OPTION
Definition: argpar-help.c:134
#define OPTION_ALIAS
Do not add an extra newline after this documentation string. Useful for lists and manual formatting.
Definition: argpar.h:175
flags
Definition: DDAlgorithm.h:22
#define OPTION_DOC
This option isn't actually an option, merely text for the usage summary.
Definition: argpar.h:152
State variable to be filled before each call to the parser callback.
Definition: argpar.h:196
#define OPT_DOC_COL
Definition: argpar-help.c:12
int argpar_usage_default(argpar *argpar)
Print the default usage summary with all available sections.
Definition: argpar-help.c:509
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
const char * argpar_program_name
Definition: argpar-help.c:6
#define ARGPAR_KEY_HELP_ARGS_DOC
Passed as the key to each help filter when printing the args_doc.
Definition: argpar.h:310
Library for reading command-line arguments in the form of key=value.
#define OPTION_CHILD
This option only applies if this parser is not the top-most parser.
Definition: argpar.h:167
const char * name
The key to search for.
Definition: argpar.h:89
@ HEADER
Definition: argpar-help.c:134
#define WRAP_INDENT
Definition: argpar-help.c:17
#define DOC_OPT_COL
Definition: argpar-help.c:11
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
int i
Definition: decode_rs.h:71
#define OPTION_PARENT
This option only applies if this parser is the top-most parser. Useful for return value documentation...
Definition: argpar.h:164
const char * arg
What to display as the right side of the argument in the usage statement.
Definition: argpar.h:98
Stores the configuration for a par argument.
Definition: argpar.h:87
#define OPTION_DBL
Cast this option as a double. The value and any error will be reflected in the argpar_state struct du...
Definition: argpar.h:156
float p[MODELMAX]
Definition: atrem_corl1.h:131
int group
The group associated with this option. If 0 and a documentation option, it is auto-incremented.
Definition: argpar.h:111