1 /*
2   File autogenerated by gengetopt version 2.23
3   generated with the following command:
4   gengetopt -i kinfold.ggo --default-optional --include-getopt
5 
6   The developers of gengetopt consider the fixed text that goes in all
7   gengetopt output files to be in the public domain:
8   we make no copyright claims on it.
9 */
10 
11 /* If we use autoconf.  */
12 #ifdef HAVE_CONFIG_H
13 #include "config.h"
14 #endif
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #ifndef FIX_UNUSED
21 #define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */
22 #endif
23 
24 
25 #include "cmdline.h"
26 
27 const char *gengetopt_args_info_purpose = "Stochastic Folding Simulations of Single-Stranded Nucleic Acids";
28 
29 const char *gengetopt_args_info_usage = "Usage: Kinfold [OPTION]...";
30 
31 const char *gengetopt_args_info_versiontext = "";
32 
33 const char *gengetopt_args_info_description = "";
34 
35 const char *gengetopt_args_info_full_help[] = {
36   "  -h, --help            Print help and exit",
37   "      --full-help       Print help, including hidden options, and exit",
38   "  -V, --version         Print version and exit",
39   "\nEnergy Model:",
40   "  -d, --dangle=INT      <0|1|2> set dangling end model to (none|normal|double)\n                          (possible values=\"0\", \"1\", \"2\" default=`2')",
41   "  -T, --Temp=FLOAT      simulation temperature  (default=`37')",
42   "  -P, --Par=filename    read energy-parameter-file",
43   "      --logML           use logarithmic multiloop energies instead of linear\n                          (default=on)",
44   "\nMoveSet:",
45   "      --noShift         turn off shift-moves  (default=off)",
46   "      --noLP            forbid structures with isolated base-pairs\n                          (default=off)",
47   "\nSimulation:",
48   "      --seed=STRING     set random number seed specify 3 integers as\n                          int=int=int  (default=`clock')",
49   "      --time=FLOAT      set maxtime of simulation  (default=`500')",
50   "      --num=INT         set number of trajectories  (default=`1')",
51   "      --start           read start structure from stdin (otherwise use open\n                          chain)  (default=off)",
52   "      --stop            read stop structure(s) from stdin (otherwise use MFE)\n                          (default=off)",
53   "      --met             use Metropolis rule for rates (not Kawasaki rule)\n                          (default=off)",
54   "      --fpt             compute first passage time (stop when a stop-structure\n                          is reached)  (default=on)",
55   "      --rect            compute recurrence time (of a start structure which is\n                          contained in stop structures)  (default=off)",
56   "      --grow=FLOAT      grow chain every <float> time units  (default=`0')",
57   "      --glen=INT        initial size of growing chain  (default=`15')",
58   "      --phi=DOUBLE      set phi value",
59   "      --pbounds=STRING  specify 3 floats for phi_min, phi_inc, phi_max in the\n                          form <d1=d2=d3>",
60   "\nOutput:",
61   "      --log=filename    set basename of log-file  (default=`kinout')",
62   "  -q, --silent          no output to stdout  (default=off)",
63   "  -v, --verbose         more information to stdout  (default=off)",
64   "      --lmin            output only local minima to stdout  (default=off)",
65   "      --cut=FLOAT       only print structures with E <= MFE + <float> to stdout\n                          (default=`20')",
66   "Input File Format:\n  1st line sequence\n  2nd line start structure (if option --start is used)\n  following lines are stop structures (if option --stop is used)",
67     0
68 };
69 
70 static void
init_help_array(void)71 init_help_array(void)
72 {
73   gengetopt_args_info_help[0] = gengetopt_args_info_full_help[0];
74   gengetopt_args_info_help[1] = gengetopt_args_info_full_help[1];
75   gengetopt_args_info_help[2] = gengetopt_args_info_full_help[2];
76   gengetopt_args_info_help[3] = gengetopt_args_info_full_help[3];
77   gengetopt_args_info_help[4] = gengetopt_args_info_full_help[4];
78   gengetopt_args_info_help[5] = gengetopt_args_info_full_help[5];
79   gengetopt_args_info_help[6] = gengetopt_args_info_full_help[6];
80   gengetopt_args_info_help[7] = gengetopt_args_info_full_help[7];
81   gengetopt_args_info_help[8] = gengetopt_args_info_full_help[8];
82   gengetopt_args_info_help[9] = gengetopt_args_info_full_help[9];
83   gengetopt_args_info_help[10] = gengetopt_args_info_full_help[10];
84   gengetopt_args_info_help[11] = gengetopt_args_info_full_help[11];
85   gengetopt_args_info_help[12] = gengetopt_args_info_full_help[12];
86   gengetopt_args_info_help[13] = gengetopt_args_info_full_help[13];
87   gengetopt_args_info_help[14] = gengetopt_args_info_full_help[14];
88   gengetopt_args_info_help[15] = gengetopt_args_info_full_help[15];
89   gengetopt_args_info_help[16] = gengetopt_args_info_full_help[16];
90   gengetopt_args_info_help[17] = gengetopt_args_info_full_help[17];
91   gengetopt_args_info_help[18] = gengetopt_args_info_full_help[18];
92   gengetopt_args_info_help[19] = gengetopt_args_info_full_help[19];
93   gengetopt_args_info_help[20] = gengetopt_args_info_full_help[20];
94   gengetopt_args_info_help[21] = gengetopt_args_info_full_help[21];
95   gengetopt_args_info_help[22] = gengetopt_args_info_full_help[24];
96   gengetopt_args_info_help[23] = gengetopt_args_info_full_help[25];
97   gengetopt_args_info_help[24] = gengetopt_args_info_full_help[26];
98   gengetopt_args_info_help[25] = gengetopt_args_info_full_help[27];
99   gengetopt_args_info_help[26] = gengetopt_args_info_full_help[28];
100   gengetopt_args_info_help[27] = gengetopt_args_info_full_help[29];
101   gengetopt_args_info_help[28] = gengetopt_args_info_full_help[30];
102   gengetopt_args_info_help[29] = 0;
103 
104 }
105 
106 const char *gengetopt_args_info_help[30];
107 
108 typedef enum {ARG_NO
109   , ARG_FLAG
110   , ARG_STRING
111   , ARG_INT
112   , ARG_FLOAT
113   , ARG_DOUBLE
114 } cmdline_parser_arg_type;
115 
116 static
117 void clear_given (struct gengetopt_args_info *args_info);
118 static
119 void clear_args (struct gengetopt_args_info *args_info);
120 
121 static int
122 cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info,
123                         struct cmdline_parser_params *params, const char *additional_error);
124 
125 
126 const char *cmdline_parser_dangle_values[] = {"0", "1", "2", 0}; /*< Possible values for dangle. */
127 
128 static char *
129 gengetopt_strdup (const char *s);
130 
131 static
clear_given(struct gengetopt_args_info * args_info)132 void clear_given (struct gengetopt_args_info *args_info)
133 {
134   args_info->help_given = 0 ;
135   args_info->full_help_given = 0 ;
136   args_info->version_given = 0 ;
137   args_info->dangle_given = 0 ;
138   args_info->Temp_given = 0 ;
139   args_info->Par_given = 0 ;
140   args_info->logML_given = 0 ;
141   args_info->noShift_given = 0 ;
142   args_info->noLP_given = 0 ;
143   args_info->seed_given = 0 ;
144   args_info->time_given = 0 ;
145   args_info->num_given = 0 ;
146   args_info->start_given = 0 ;
147   args_info->stop_given = 0 ;
148   args_info->met_given = 0 ;
149   args_info->fpt_given = 0 ;
150   args_info->rect_given = 0 ;
151   args_info->grow_given = 0 ;
152   args_info->glen_given = 0 ;
153   args_info->phi_given = 0 ;
154   args_info->pbounds_given = 0 ;
155   args_info->log_given = 0 ;
156   args_info->silent_given = 0 ;
157   args_info->verbose_given = 0 ;
158   args_info->lmin_given = 0 ;
159   args_info->cut_given = 0 ;
160 }
161 
162 static
clear_args(struct gengetopt_args_info * args_info)163 void clear_args (struct gengetopt_args_info *args_info)
164 {
165   FIX_UNUSED (args_info);
166   args_info->dangle_arg = 2;
167   args_info->dangle_orig = NULL;
168   args_info->Temp_arg = 37;
169   args_info->Temp_orig = NULL;
170   args_info->Par_arg = NULL;
171   args_info->Par_orig = NULL;
172   args_info->logML_flag = 1;
173   args_info->noShift_flag = 0;
174   args_info->noLP_flag = 0;
175   args_info->seed_arg = gengetopt_strdup ("clock");
176   args_info->seed_orig = NULL;
177   args_info->time_arg = 500;
178   args_info->time_orig = NULL;
179   args_info->num_arg = 1;
180   args_info->num_orig = NULL;
181   args_info->start_flag = 0;
182   args_info->stop_flag = 0;
183   args_info->met_flag = 0;
184   args_info->fpt_flag = 1;
185   args_info->rect_flag = 0;
186   args_info->grow_arg = 0;
187   args_info->grow_orig = NULL;
188   args_info->glen_arg = 15;
189   args_info->glen_orig = NULL;
190   args_info->phi_orig = NULL;
191   args_info->pbounds_arg = NULL;
192   args_info->pbounds_orig = NULL;
193   args_info->log_arg = gengetopt_strdup ("kinout");
194   args_info->log_orig = NULL;
195   args_info->silent_flag = 0;
196   args_info->verbose_flag = 0;
197   args_info->lmin_flag = 0;
198   args_info->cut_arg = 20;
199   args_info->cut_orig = NULL;
200 
201 }
202 
203 static
init_args_info(struct gengetopt_args_info * args_info)204 void init_args_info(struct gengetopt_args_info *args_info)
205 {
206 
207   init_help_array();
208   args_info->help_help = gengetopt_args_info_full_help[0] ;
209   args_info->full_help_help = gengetopt_args_info_full_help[1] ;
210   args_info->version_help = gengetopt_args_info_full_help[2] ;
211   args_info->dangle_help = gengetopt_args_info_full_help[4] ;
212   args_info->Temp_help = gengetopt_args_info_full_help[5] ;
213   args_info->Par_help = gengetopt_args_info_full_help[6] ;
214   args_info->logML_help = gengetopt_args_info_full_help[7] ;
215   args_info->noShift_help = gengetopt_args_info_full_help[9] ;
216   args_info->noLP_help = gengetopt_args_info_full_help[10] ;
217   args_info->seed_help = gengetopt_args_info_full_help[12] ;
218   args_info->time_help = gengetopt_args_info_full_help[13] ;
219   args_info->num_help = gengetopt_args_info_full_help[14] ;
220   args_info->start_help = gengetopt_args_info_full_help[15] ;
221   args_info->stop_help = gengetopt_args_info_full_help[16] ;
222   args_info->met_help = gengetopt_args_info_full_help[17] ;
223   args_info->fpt_help = gengetopt_args_info_full_help[18] ;
224   args_info->rect_help = gengetopt_args_info_full_help[19] ;
225   args_info->grow_help = gengetopt_args_info_full_help[20] ;
226   args_info->glen_help = gengetopt_args_info_full_help[21] ;
227   args_info->phi_help = gengetopt_args_info_full_help[22] ;
228   args_info->pbounds_help = gengetopt_args_info_full_help[23] ;
229   args_info->log_help = gengetopt_args_info_full_help[25] ;
230   args_info->silent_help = gengetopt_args_info_full_help[26] ;
231   args_info->verbose_help = gengetopt_args_info_full_help[27] ;
232   args_info->lmin_help = gengetopt_args_info_full_help[28] ;
233   args_info->cut_help = gengetopt_args_info_full_help[29] ;
234 
235 }
236 
237 void
cmdline_parser_print_version(void)238 cmdline_parser_print_version (void)
239 {
240   printf ("%s %s\n",
241      (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE),
242      CMDLINE_PARSER_VERSION);
243 
244   if (strlen(gengetopt_args_info_versiontext) > 0)
245     printf("\n%s\n", gengetopt_args_info_versiontext);
246 }
247 
print_help_common(void)248 static void print_help_common(void)
249 {
250 	size_t len_purpose = strlen(gengetopt_args_info_purpose);
251 	size_t len_usage = strlen(gengetopt_args_info_usage);
252 
253 	if (len_usage > 0) {
254 		printf("%s\n", gengetopt_args_info_usage);
255 	}
256 	if (len_purpose > 0) {
257 		printf("%s\n", gengetopt_args_info_purpose);
258 	}
259 
260 	if (len_usage || len_purpose) {
261 		printf("\n");
262 	}
263 
264 	if (strlen(gengetopt_args_info_description) > 0) {
265 		printf("%s\n\n", gengetopt_args_info_description);
266 	}
267 }
268 
269 void
cmdline_parser_print_help(void)270 cmdline_parser_print_help (void)
271 {
272   int i = 0;
273   print_help_common();
274   while (gengetopt_args_info_help[i])
275     printf("%s\n", gengetopt_args_info_help[i++]);
276 }
277 
278 void
cmdline_parser_print_full_help(void)279 cmdline_parser_print_full_help (void)
280 {
281   int i = 0;
282   print_help_common();
283   while (gengetopt_args_info_full_help[i])
284     printf("%s\n", gengetopt_args_info_full_help[i++]);
285 }
286 
287 void
cmdline_parser_init(struct gengetopt_args_info * args_info)288 cmdline_parser_init (struct gengetopt_args_info *args_info)
289 {
290   clear_given (args_info);
291   clear_args (args_info);
292   init_args_info (args_info);
293 }
294 
295 void
cmdline_parser_params_init(struct cmdline_parser_params * params)296 cmdline_parser_params_init(struct cmdline_parser_params *params)
297 {
298   if (params)
299     {
300       params->override = 0;
301       params->initialize = 1;
302       params->check_required = 1;
303       params->check_ambiguity = 0;
304       params->print_errors = 1;
305     }
306 }
307 
308 struct cmdline_parser_params *
cmdline_parser_params_create(void)309 cmdline_parser_params_create(void)
310 {
311   struct cmdline_parser_params *params =
312     (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params));
313   cmdline_parser_params_init(params);
314   return params;
315 }
316 
317 static void
free_string_field(char ** s)318 free_string_field (char **s)
319 {
320   if (*s)
321     {
322       free (*s);
323       *s = 0;
324     }
325 }
326 
327 
328 static void
cmdline_parser_release(struct gengetopt_args_info * args_info)329 cmdline_parser_release (struct gengetopt_args_info *args_info)
330 {
331 
332   free_string_field (&(args_info->dangle_orig));
333   free_string_field (&(args_info->Temp_orig));
334   free_string_field (&(args_info->Par_arg));
335   free_string_field (&(args_info->Par_orig));
336   free_string_field (&(args_info->seed_arg));
337   free_string_field (&(args_info->seed_orig));
338   free_string_field (&(args_info->time_orig));
339   free_string_field (&(args_info->num_orig));
340   free_string_field (&(args_info->grow_orig));
341   free_string_field (&(args_info->glen_orig));
342   free_string_field (&(args_info->phi_orig));
343   free_string_field (&(args_info->pbounds_arg));
344   free_string_field (&(args_info->pbounds_orig));
345   free_string_field (&(args_info->log_arg));
346   free_string_field (&(args_info->log_orig));
347   free_string_field (&(args_info->cut_orig));
348 
349 
350 
351   clear_given (args_info);
352 }
353 
354 /**
355  * @param val the value to check
356  * @param values the possible values
357  * @return the index of the matched value:
358  * -1 if no value matched,
359  * -2 if more than one value has matched
360  */
361 static int
check_possible_values(const char * val,const char * values[])362 check_possible_values(const char *val, const char *values[])
363 {
364   int i, found, last;
365   size_t len;
366 
367   if (!val)   /* otherwise strlen() crashes below */
368     return -1; /* -1 means no argument for the option */
369 
370   found = last = 0;
371 
372   for (i = 0, len = strlen(val); values[i]; ++i)
373     {
374       if (strncmp(val, values[i], len) == 0)
375         {
376           ++found;
377           last = i;
378           if (strlen(values[i]) == len)
379             return i; /* exact macth no need to check more */
380         }
381     }
382 
383   if (found == 1) /* one match: OK */
384     return last;
385 
386   return (found ? -2 : -1); /* return many values or none matched */
387 }
388 
389 
390 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])391 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
392 {
393   int found = -1;
394   if (arg) {
395     if (values) {
396       found = check_possible_values(arg, values);
397     }
398     if (found >= 0)
399       fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]);
400     else
401       fprintf(outfile, "%s=\"%s\"\n", opt, arg);
402   } else {
403     fprintf(outfile, "%s\n", opt);
404   }
405 }
406 
407 
408 int
cmdline_parser_dump(FILE * outfile,struct gengetopt_args_info * args_info)409 cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
410 {
411   int i = 0;
412 
413   if (!outfile)
414     {
415       fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE);
416       return EXIT_FAILURE;
417     }
418 
419   if (args_info->help_given)
420     write_into_file(outfile, "help", 0, 0 );
421   if (args_info->full_help_given)
422     write_into_file(outfile, "full-help", 0, 0 );
423   if (args_info->version_given)
424     write_into_file(outfile, "version", 0, 0 );
425   if (args_info->dangle_given)
426     write_into_file(outfile, "dangle", args_info->dangle_orig, cmdline_parser_dangle_values);
427   if (args_info->Temp_given)
428     write_into_file(outfile, "Temp", args_info->Temp_orig, 0);
429   if (args_info->Par_given)
430     write_into_file(outfile, "Par", args_info->Par_orig, 0);
431   if (args_info->logML_given)
432     write_into_file(outfile, "logML", 0, 0 );
433   if (args_info->noShift_given)
434     write_into_file(outfile, "noShift", 0, 0 );
435   if (args_info->noLP_given)
436     write_into_file(outfile, "noLP", 0, 0 );
437   if (args_info->seed_given)
438     write_into_file(outfile, "seed", args_info->seed_orig, 0);
439   if (args_info->time_given)
440     write_into_file(outfile, "time", args_info->time_orig, 0);
441   if (args_info->num_given)
442     write_into_file(outfile, "num", args_info->num_orig, 0);
443   if (args_info->start_given)
444     write_into_file(outfile, "start", 0, 0 );
445   if (args_info->stop_given)
446     write_into_file(outfile, "stop", 0, 0 );
447   if (args_info->met_given)
448     write_into_file(outfile, "met", 0, 0 );
449   if (args_info->fpt_given)
450     write_into_file(outfile, "fpt", 0, 0 );
451   if (args_info->rect_given)
452     write_into_file(outfile, "rect", 0, 0 );
453   if (args_info->grow_given)
454     write_into_file(outfile, "grow", args_info->grow_orig, 0);
455   if (args_info->glen_given)
456     write_into_file(outfile, "glen", args_info->glen_orig, 0);
457   if (args_info->phi_given)
458     write_into_file(outfile, "phi", args_info->phi_orig, 0);
459   if (args_info->pbounds_given)
460     write_into_file(outfile, "pbounds", args_info->pbounds_orig, 0);
461   if (args_info->log_given)
462     write_into_file(outfile, "log", args_info->log_orig, 0);
463   if (args_info->silent_given)
464     write_into_file(outfile, "silent", 0, 0 );
465   if (args_info->verbose_given)
466     write_into_file(outfile, "verbose", 0, 0 );
467   if (args_info->lmin_given)
468     write_into_file(outfile, "lmin", 0, 0 );
469   if (args_info->cut_given)
470     write_into_file(outfile, "cut", args_info->cut_orig, 0);
471 
472 
473   i = EXIT_SUCCESS;
474   return i;
475 }
476 
477 int
cmdline_parser_file_save(const char * filename,struct gengetopt_args_info * args_info)478 cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info)
479 {
480   FILE *outfile;
481   int i = 0;
482 
483   outfile = fopen(filename, "w");
484 
485   if (!outfile)
486     {
487       fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename);
488       return EXIT_FAILURE;
489     }
490 
491   i = cmdline_parser_dump(outfile, args_info);
492   fclose (outfile);
493 
494   return i;
495 }
496 
497 void
cmdline_parser_free(struct gengetopt_args_info * args_info)498 cmdline_parser_free (struct gengetopt_args_info *args_info)
499 {
500   cmdline_parser_release (args_info);
501 }
502 
503 /** @brief replacement of strdup, which is not standard */
504 char *
gengetopt_strdup(const char * s)505 gengetopt_strdup (const char *s)
506 {
507   char *result = 0;
508   if (!s)
509     return result;
510 
511   result = (char*)malloc(strlen(s) + 1);
512   if (result == (char*)0)
513     return (char*)0;
514   strcpy(result, s);
515   return result;
516 }
517 
518 int
cmdline_parser(int argc,char ** argv,struct gengetopt_args_info * args_info)519 cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info)
520 {
521   return cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
522 }
523 
524 int
cmdline_parser_ext(int argc,char ** argv,struct gengetopt_args_info * args_info,struct cmdline_parser_params * params)525 cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info,
526                    struct cmdline_parser_params *params)
527 {
528   int result;
529   result = cmdline_parser_internal (argc, argv, args_info, params, 0);
530 
531   if (result == EXIT_FAILURE)
532     {
533       cmdline_parser_free (args_info);
534       exit (EXIT_FAILURE);
535     }
536 
537   return result;
538 }
539 
540 int
cmdline_parser2(int argc,char ** argv,struct gengetopt_args_info * args_info,int override,int initialize,int check_required)541 cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required)
542 {
543   int result;
544   struct cmdline_parser_params params;
545 
546   params.override = override;
547   params.initialize = initialize;
548   params.check_required = check_required;
549   params.check_ambiguity = 0;
550   params.print_errors = 1;
551 
552   result = cmdline_parser_internal (argc, argv, args_info, &params, 0);
553 
554   if (result == EXIT_FAILURE)
555     {
556       cmdline_parser_free (args_info);
557       exit (EXIT_FAILURE);
558     }
559 
560   return result;
561 }
562 
563 int
cmdline_parser_required(struct gengetopt_args_info * args_info,const char * prog_name)564 cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name)
565 {
566   FIX_UNUSED (args_info);
567   FIX_UNUSED (prog_name);
568   return EXIT_SUCCESS;
569 }
570 
571 /*
572  * Extracted from the glibc source tree, version 2.3.6
573  *
574  * Licensed under the GPL as per the whole glibc source tree.
575  *
576  * This file was modified so that getopt_long can be called
577  * many times without risking previous memory to be spoiled.
578  *
579  * Modified by Andre Noll and Lorenzo Bettini for use in
580  * GNU gengetopt generated files.
581  *
582  */
583 
584 /*
585  * we must include anything we need since this file is not thought to be
586  * inserted in a file already using getopt.h
587  *
588  * Lorenzo
589  */
590 
591 struct option
592 {
593   const char *name;
594   /* has_arg can't be an enum because some compilers complain about
595      type mismatches in all the code that assumes it is an int.  */
596   int has_arg;
597   int *flag;
598   int val;
599 };
600 
601 /* This version of `getopt' appears to the caller like standard Unix `getopt'
602    but it behaves differently for the user, since it allows the user
603    to intersperse the options with the other arguments.
604 
605    As `getopt' works, it permutes the elements of ARGV so that,
606    when it is done, all the options precede everything else.  Thus
607    all application programs are extended to handle flexible argument order.
608 */
609 /*
610    If the field `flag' is not NULL, it points to a variable that is set
611    to the value given in the field `val' when the option is found, but
612    left unchanged if the option is not found.
613 
614    To have a long-named option do something other than set an `int' to
615    a compiled-in constant, such as set a value from `custom_optarg', set the
616    option's `flag' field to zero and its `val' field to a nonzero
617    value (the equivalent single-letter option character, if there is
618    one).  For long options that have a zero `flag' field, `getopt'
619    returns the contents of the `val' field.  */
620 
621 /* Names for the values of the `has_arg' field of `struct option'.  */
622 #ifndef no_argument
623 #define no_argument		0
624 #endif
625 
626 #ifndef required_argument
627 #define required_argument	1
628 #endif
629 
630 #ifndef optional_argument
631 #define optional_argument	2
632 #endif
633 
634 struct custom_getopt_data {
635 	/*
636 	 * These have exactly the same meaning as the corresponding global variables,
637 	 * except that they are used for the reentrant versions of getopt.
638 	 */
639 	int custom_optind;
640 	int custom_opterr;
641 	int custom_optopt;
642 	char *custom_optarg;
643 
644 	/* True if the internal members have been initialized.  */
645 	int initialized;
646 
647 	/*
648 	 * The next char to be scanned in the option-element in which the last option
649 	 * character we returned was found.  This allows us to pick up the scan where
650 	 * we left off.  If this is zero, or a null string, it means resume the scan by
651 	 * advancing to the next ARGV-element.
652 	 */
653 	char *nextchar;
654 
655 	/*
656 	 * Describe the part of ARGV that contains non-options that have been skipped.
657 	 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
658 	 * the index after the last of them.
659 	 */
660 	int first_nonopt;
661 	int last_nonopt;
662 };
663 
664 /*
665  * the variables optarg, optind, opterr and optopt are renamed with
666  * the custom_ prefix so that they don't interfere with getopt ones.
667  *
668  * Moreover they're static so they are visible only from within the
669  * file where this very file will be included.
670  */
671 
672 /*
673  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
674  * option that takes an argument, the argument value is returned here.
675  */
676 static char *custom_optarg;
677 
678 /*
679  * Index in ARGV of the next element to be scanned.  This is used for
680  * communication to and from the caller and for communication between
681  * successive calls to `custom_getopt'.
682  *
683  * On entry to `custom_getopt', 1 means this is the first call; initialize.
684  *
685  * When `custom_getopt' returns -1, this is the index of the first of the non-option
686  * elements that the caller should itself scan.
687  *
688  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
689  * has been scanned so far.
690  *
691  * 1003.2 says this must be 1 before any call.
692  */
693 static int custom_optind = 1;
694 
695 /*
696  * Callers store zero here to inhibit the error message for unrecognized
697  * options.
698  */
699 static int custom_opterr = 1;
700 
701 /*
702  * Set to an option character which was unrecognized.  This must be initialized
703  * on some systems to avoid linking in the system's own getopt implementation.
704  */
705 static int custom_optopt = '?';
706 
707 /*
708  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
709  * [first_nonopt,last_nonopt) which contains all the non-options that have been
710  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
711  * all the options processed since those non-options were skipped.
712  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
713  * indices of the non-options in ARGV after they are moved.
714  */
exchange(char ** argv,struct custom_getopt_data * d)715 static void exchange(char **argv, struct custom_getopt_data *d)
716 {
717 	int bottom = d->first_nonopt;
718 	int middle = d->last_nonopt;
719 	int top = d->custom_optind;
720 	char *tem;
721 
722 	/*
723 	 * Exchange the shorter segment with the far end of the longer segment.
724 	 * That puts the shorter segment into the right place.  It leaves the
725 	 * longer segment in the right place overall, but it consists of two
726 	 * parts that need to be swapped next.
727 	 */
728 	while (top > middle && middle > bottom) {
729 		if (top - middle > middle - bottom) {
730 			/* Bottom segment is the short one.  */
731 			int len = middle - bottom;
732 			int i;
733 
734 			/* Swap it with the top part of the top segment.  */
735 			for (i = 0; i < len; i++) {
736 				tem = argv[bottom + i];
737 				argv[bottom + i] =
738 					argv[top - (middle - bottom) + i];
739 				argv[top - (middle - bottom) + i] = tem;
740 			}
741 			/* Exclude the moved bottom segment from further swapping.  */
742 			top -= len;
743 		} else {
744 			/* Top segment is the short one.  */
745 			int len = top - middle;
746 			int i;
747 
748 			/* Swap it with the bottom part of the bottom segment.  */
749 			for (i = 0; i < len; i++) {
750 				tem = argv[bottom + i];
751 				argv[bottom + i] = argv[middle + i];
752 				argv[middle + i] = tem;
753 			}
754 			/* Exclude the moved top segment from further swapping.  */
755 			bottom += len;
756 		}
757 	}
758 	/* Update records for the slots the non-options now occupy.  */
759 	d->first_nonopt += (d->custom_optind - d->last_nonopt);
760 	d->last_nonopt = d->custom_optind;
761 }
762 
763 /* Initialize the internal data when the first call is made.  */
custom_getopt_initialize(struct custom_getopt_data * d)764 static void custom_getopt_initialize(struct custom_getopt_data *d)
765 {
766 	/*
767 	 * Start processing options with ARGV-element 1 (since ARGV-element 0
768 	 * is the program name); the sequence of previously skipped non-option
769 	 * ARGV-elements is empty.
770 	 */
771 	d->first_nonopt = d->last_nonopt = d->custom_optind;
772 	d->nextchar = NULL;
773 	d->initialized = 1;
774 }
775 
776 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
777 
778 /* return: zero: continue, nonzero: return given value to user */
shuffle_argv(int argc,char * const * argv,const struct option * longopts,struct custom_getopt_data * d)779 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
780 	struct custom_getopt_data *d)
781 {
782 	/*
783 	 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
784 	 * moved back by the user (who may also have changed the arguments).
785 	 */
786 	if (d->last_nonopt > d->custom_optind)
787 		d->last_nonopt = d->custom_optind;
788 	if (d->first_nonopt > d->custom_optind)
789 		d->first_nonopt = d->custom_optind;
790 	/*
791 	 * If we have just processed some options following some
792 	 * non-options, exchange them so that the options come first.
793 	 */
794 	if (d->first_nonopt != d->last_nonopt &&
795 			d->last_nonopt != d->custom_optind)
796 		exchange((char **) argv, d);
797 	else if (d->last_nonopt != d->custom_optind)
798 		d->first_nonopt = d->custom_optind;
799 	/*
800 	 * Skip any additional non-options and extend the range of
801 	 * non-options previously skipped.
802 	 */
803 	while (d->custom_optind < argc && NONOPTION_P)
804 		d->custom_optind++;
805 	d->last_nonopt = d->custom_optind;
806 	/*
807 	 * The special ARGV-element `--' means premature end of options.  Skip
808 	 * it like a null option, then exchange with previous non-options as if
809 	 * it were an option, then skip everything else like a non-option.
810 	 */
811 	if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
812 		d->custom_optind++;
813 		if (d->first_nonopt != d->last_nonopt
814 				&& d->last_nonopt != d->custom_optind)
815 			exchange((char **) argv, d);
816 		else if (d->first_nonopt == d->last_nonopt)
817 			d->first_nonopt = d->custom_optind;
818 		d->last_nonopt = argc;
819 		d->custom_optind = argc;
820 	}
821 	/*
822 	 * If we have done all the ARGV-elements, stop the scan and back over
823 	 * any non-options that we skipped and permuted.
824 	 */
825 	if (d->custom_optind == argc) {
826 		/*
827 		 * Set the next-arg-index to point at the non-options that we
828 		 * previously skipped, so the caller will digest them.
829 		 */
830 		if (d->first_nonopt != d->last_nonopt)
831 			d->custom_optind = d->first_nonopt;
832 		return -1;
833 	}
834 	/*
835 	 * If we have come to a non-option and did not permute it, either stop
836 	 * the scan or describe it to the caller and pass it by.
837 	 */
838 	if (NONOPTION_P) {
839 		d->custom_optarg = argv[d->custom_optind++];
840 		return 1;
841 	}
842 	/*
843 	 * We have found another option-ARGV-element. Skip the initial
844 	 * punctuation.
845 	 */
846 	d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
847 	return 0;
848 }
849 
850 /*
851  * Check whether the ARGV-element is a long option.
852  *
853  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
854  * that an abbreviation of the long option, just like "--fu", and not "-f" with
855  * arg "u".
856  *
857  * This distinction seems to be the most useful approach.
858  *
859  */
check_long_opt(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int print_errors,struct custom_getopt_data * d)860 static int check_long_opt(int argc, char *const *argv, const char *optstring,
861 		const struct option *longopts, int *longind,
862 		int print_errors, struct custom_getopt_data *d)
863 {
864 	char *nameend;
865 	const struct option *p;
866 	const struct option *pfound = NULL;
867 	int exact = 0;
868 	int ambig = 0;
869 	int indfound = -1;
870 	int option_index;
871 
872 	for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
873 		/* Do nothing.  */ ;
874 
875 	/* Test all long options for either exact match or abbreviated matches */
876 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
877 		if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
878 			if ((unsigned int) (nameend - d->nextchar)
879 					== (unsigned int) strlen(p->name)) {
880 				/* Exact match found.  */
881 				pfound = p;
882 				indfound = option_index;
883 				exact = 1;
884 				break;
885 			} else if (pfound == NULL) {
886 				/* First nonexact match found.  */
887 				pfound = p;
888 				indfound = option_index;
889 			} else if (pfound->has_arg != p->has_arg
890 					|| pfound->flag != p->flag
891 					|| pfound->val != p->val)
892 				/* Second or later nonexact match found.  */
893 				ambig = 1;
894 		}
895 	if (ambig && !exact) {
896 		if (print_errors) {
897 			fprintf(stderr,
898 				"%s: option `%s' is ambiguous\n",
899 				argv[0], argv[d->custom_optind]);
900 		}
901 		d->nextchar += strlen(d->nextchar);
902 		d->custom_optind++;
903 		d->custom_optopt = 0;
904 		return '?';
905 	}
906 	if (pfound) {
907 		option_index = indfound;
908 		d->custom_optind++;
909 		if (*nameend) {
910 			if (pfound->has_arg != no_argument)
911 				d->custom_optarg = nameend + 1;
912 			else {
913 				if (print_errors) {
914 					if (argv[d->custom_optind - 1][1] == '-') {
915 						/* --option */
916 						fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
917 							argv[0], pfound->name);
918 					} else {
919 						/* +option or -option */
920 						fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
921 							argv[0], argv[d->custom_optind - 1][0], pfound->name);
922 					}
923 
924 				}
925 				d->nextchar += strlen(d->nextchar);
926 				d->custom_optopt = pfound->val;
927 				return '?';
928 			}
929 		} else if (pfound->has_arg == required_argument) {
930 			if (d->custom_optind < argc)
931 				d->custom_optarg = argv[d->custom_optind++];
932 			else {
933 				if (print_errors) {
934 					fprintf(stderr,
935 						"%s: option `%s' requires an argument\n",
936 						argv[0],
937 						argv[d->custom_optind - 1]);
938 				}
939 				d->nextchar += strlen(d->nextchar);
940 				d->custom_optopt = pfound->val;
941 				return optstring[0] == ':' ? ':' : '?';
942 			}
943 		}
944 		d->nextchar += strlen(d->nextchar);
945 		if (longind != NULL)
946 			*longind = option_index;
947 		if (pfound->flag) {
948 			*(pfound->flag) = pfound->val;
949 			return 0;
950 		}
951 		return pfound->val;
952 	}
953 	/*
954 	 * Can't find it as a long option.  If this is not getopt_long_only, or
955 	 * the option starts with '--' or is not a valid short option, then
956 	 * it's an error.  Otherwise interpret it as a short option.
957 	 */
958 	if (print_errors) {
959 		if (argv[d->custom_optind][1] == '-') {
960 			/* --option */
961 			fprintf(stderr,
962 				"%s: unrecognized option `--%s'\n",
963 				argv[0], d->nextchar);
964 		} else {
965 			/* +option or -option */
966 			fprintf(stderr,
967 				"%s: unrecognized option `%c%s'\n",
968 				argv[0], argv[d->custom_optind][0],
969 				d->nextchar);
970 		}
971 	}
972 	d->nextchar = (char *) "";
973 	d->custom_optind++;
974 	d->custom_optopt = 0;
975 	return '?';
976 }
977 
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)978 static int check_short_opt(int argc, char *const *argv, const char *optstring,
979 		int print_errors, struct custom_getopt_data *d)
980 {
981 	char c = *d->nextchar++;
982 	const char *temp = strchr(optstring, c);
983 
984 	/* Increment `custom_optind' when we start to process its last character.  */
985 	if (*d->nextchar == '\0')
986 		++d->custom_optind;
987 	if (!temp || c == ':') {
988 		if (print_errors)
989 			fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
990 
991 		d->custom_optopt = c;
992 		return '?';
993 	}
994 	if (temp[1] == ':') {
995 		if (temp[2] == ':') {
996 			/* This is an option that accepts an argument optionally.  */
997 			if (*d->nextchar != '\0') {
998 				d->custom_optarg = d->nextchar;
999 				d->custom_optind++;
1000 			} else
1001 				d->custom_optarg = NULL;
1002 			d->nextchar = NULL;
1003 		} else {
1004 			/* This is an option that requires an argument.  */
1005 			if (*d->nextchar != '\0') {
1006 				d->custom_optarg = d->nextchar;
1007 				/*
1008 				 * If we end this ARGV-element by taking the
1009 				 * rest as an arg, we must advance to the next
1010 				 * element now.
1011 				 */
1012 				d->custom_optind++;
1013 			} else if (d->custom_optind == argc) {
1014 				if (print_errors) {
1015 					fprintf(stderr,
1016 						"%s: option requires an argument -- %c\n",
1017 						argv[0], c);
1018 				}
1019 				d->custom_optopt = c;
1020 				if (optstring[0] == ':')
1021 					c = ':';
1022 				else
1023 					c = '?';
1024 			} else
1025 				/*
1026 				 * We already incremented `custom_optind' once;
1027 				 * increment it again when taking next ARGV-elt
1028 				 * as argument.
1029 				 */
1030 				d->custom_optarg = argv[d->custom_optind++];
1031 			d->nextchar = NULL;
1032 		}
1033 	}
1034 	return c;
1035 }
1036 
1037 /*
1038  * Scan elements of ARGV for option characters given in OPTSTRING.
1039  *
1040  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1041  * then it is an option element.  The characters of this element
1042  * (aside from the initial '-') are option characters.  If `getopt'
1043  * is called repeatedly, it returns successively each of the option characters
1044  * from each of the option elements.
1045  *
1046  * If `getopt' finds another option character, it returns that character,
1047  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1048  * resume the scan with the following option character or ARGV-element.
1049  *
1050  * If there are no more option characters, `getopt' returns -1.
1051  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1052  * that is not an option.  (The ARGV-elements have been permuted
1053  * so that those that are not options now come last.)
1054  *
1055  * OPTSTRING is a string containing the legitimate option characters.
1056  * If an option character is seen that is not listed in OPTSTRING,
1057  * return '?' after printing an error message.  If you set `custom_opterr' to
1058  * zero, the error message is suppressed but we still return '?'.
1059  *
1060  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1061  * so the following text in the same ARGV-element, or the text of the following
1062  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1063  * wants an optional arg; if there is text in the current ARGV-element,
1064  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1065  *
1066  * If OPTSTRING starts with `-' or `+', it requests different methods of
1067  * handling the non-option ARGV-elements.
1068  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1069  *
1070  * Long-named options begin with `--' instead of `-'.
1071  * Their names may be abbreviated as long as the abbreviation is unique
1072  * or is an exact match for some defined option.  If they have an
1073  * argument, it follows the option name in the same ARGV-element, separated
1074  * from the option name by a `=', or else the in next ARGV-element.
1075  * When `getopt' finds a long-named option, it returns 0 if that option's
1076  * `flag' field is nonzero, the value of the option's `val' field
1077  * if the `flag' field is zero.
1078  *
1079  * The elements of ARGV aren't really const, because we permute them.
1080  * But we pretend they're const in the prototype to be compatible
1081  * with other systems.
1082  *
1083  * LONGOPTS is a vector of `struct option' terminated by an
1084  * element containing a name which is zero.
1085  *
1086  * LONGIND returns the index in LONGOPT of the long-named option found.
1087  * It is only valid when a long-named option has been found by the most
1088  * recent call.
1089  *
1090  * Return the option character from OPTS just read.  Return -1 when there are
1091  * no more options.  For unrecognized options, or options missing arguments,
1092  * `custom_optopt' is set to the option letter, and '?' is returned.
1093  *
1094  * The OPTS string is a list of characters which are recognized option letters,
1095  * optionally followed by colons, specifying that that letter takes an
1096  * argument, to be placed in `custom_optarg'.
1097  *
1098  * If a letter in OPTS is followed by two colons, its argument is optional.
1099  * This behavior is specific to the GNU `getopt'.
1100  *
1101  * The argument `--' causes premature termination of argument scanning,
1102  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1103  * with `--', then non-option arguments are treated as arguments to the option
1104  * '\0'.  This behavior is specific to the GNU `getopt'.
1105  */
1106 
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1107 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1108 		const struct option *longopts, int *longind,
1109 		struct custom_getopt_data *d)
1110 {
1111 	int ret, print_errors = d->custom_opterr;
1112 
1113 	if (optstring[0] == ':')
1114 		print_errors = 0;
1115 	if (argc < 1)
1116 		return -1;
1117 	d->custom_optarg = NULL;
1118 
1119 	/*
1120 	 * This is a big difference with GNU getopt, since optind == 0
1121 	 * means initialization while here 1 means first call.
1122 	 */
1123 	if (d->custom_optind == 0 || !d->initialized) {
1124 		if (d->custom_optind == 0)
1125 			d->custom_optind = 1;	/* Don't scan ARGV[0], the program name.  */
1126 		custom_getopt_initialize(d);
1127 	}
1128 	if (d->nextchar == NULL || *d->nextchar == '\0') {
1129 		ret = shuffle_argv(argc, argv, longopts, d);
1130 		if (ret)
1131 			return ret;
1132 	}
1133 	if (longopts && (argv[d->custom_optind][1] == '-' ))
1134 		return check_long_opt(argc, argv, optstring, longopts,
1135 			longind, print_errors, d);
1136 	return check_short_opt(argc, argv, optstring, print_errors, d);
1137 }
1138 
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1139 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1140 	const struct option *longopts, int *longind)
1141 {
1142 	int result;
1143 	/* Keep a global copy of all internal members of d */
1144 	static struct custom_getopt_data d;
1145 
1146 	d.custom_optind = custom_optind;
1147 	d.custom_opterr = custom_opterr;
1148 	result = getopt_internal_r(argc, argv, optstring, longopts,
1149 		longind, &d);
1150 	custom_optind = d.custom_optind;
1151 	custom_optarg = d.custom_optarg;
1152 	custom_optopt = d.custom_optopt;
1153 	return result;
1154 }
1155 
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1156 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1157 	const struct option *long_options, int *opt_index)
1158 {
1159 	return custom_getopt_internal(argc, argv, options, long_options,
1160 		opt_index);
1161 }
1162 
1163 
1164 static char *package_name = 0;
1165 
1166 /**
1167  * @brief updates an option
1168  * @param field the generic pointer to the field to update
1169  * @param orig_field the pointer to the orig field
1170  * @param field_given the pointer to the number of occurrence of this option
1171  * @param prev_given the pointer to the number of occurrence already seen
1172  * @param value the argument for this option (if null no arg was specified)
1173  * @param possible_values the possible values for this option (if specified)
1174  * @param default_value the default value (in case the option only accepts fixed values)
1175  * @param arg_type the type of this option
1176  * @param check_ambiguity @see cmdline_parser_params.check_ambiguity
1177  * @param override @see cmdline_parser_params.override
1178  * @param no_free whether to free a possible previous value
1179  * @param multiple_option whether this is a multiple option
1180  * @param long_opt the corresponding long option
1181  * @param short_opt the corresponding short option (or '-' if none)
1182  * @param additional_error possible further error specification
1183  */
1184 static
update_arg(void * field,char ** orig_field,unsigned int * field_given,unsigned int * prev_given,char * value,const char * possible_values[],const char * default_value,cmdline_parser_arg_type arg_type,int check_ambiguity,int override,int no_free,int multiple_option,const char * long_opt,char short_opt,const char * additional_error)1185 int update_arg(void *field, char **orig_field,
1186                unsigned int *field_given, unsigned int *prev_given,
1187                char *value, const char *possible_values[],
1188                const char *default_value,
1189                cmdline_parser_arg_type arg_type,
1190                int check_ambiguity, int override,
1191                int no_free, int multiple_option,
1192                const char *long_opt, char short_opt,
1193                const char *additional_error)
1194 {
1195   char *stop_char = 0;
1196   const char *val = value;
1197   int found;
1198   char **string_field;
1199   FIX_UNUSED (field);
1200 
1201   stop_char = 0;
1202   found = 0;
1203 
1204   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1205     {
1206       if (short_opt != '-')
1207         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1208                package_name, long_opt, short_opt,
1209                (additional_error ? additional_error : ""));
1210       else
1211         fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1212                package_name, long_opt,
1213                (additional_error ? additional_error : ""));
1214       return 1; /* failure */
1215     }
1216 
1217   if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)
1218     {
1219       if (short_opt != '-')
1220         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",
1221           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt,
1222           (additional_error ? additional_error : ""));
1223       else
1224         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",
1225           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt,
1226           (additional_error ? additional_error : ""));
1227       return 1; /* failure */
1228     }
1229 
1230   if (field_given && *field_given && ! override)
1231     return 0;
1232   if (prev_given)
1233     (*prev_given)++;
1234   if (field_given)
1235     (*field_given)++;
1236   if (possible_values)
1237     val = possible_values[found];
1238 
1239   switch(arg_type) {
1240   case ARG_FLAG:
1241     *((int *)field) = !*((int *)field);
1242     break;
1243   case ARG_INT:
1244     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1245     break;
1246   case ARG_FLOAT:
1247     if (val) *((float *)field) = (float)strtod (val, &stop_char);
1248     break;
1249   case ARG_DOUBLE:
1250     if (val) *((double *)field) = strtod (val, &stop_char);
1251     break;
1252   case ARG_STRING:
1253     if (val) {
1254       string_field = (char **)field;
1255       if (!no_free && *string_field)
1256         free (*string_field); /* free previous string */
1257       *string_field = gengetopt_strdup (val);
1258     }
1259     break;
1260   default:
1261     break;
1262   };
1263 
1264   /* check numeric conversion */
1265   switch(arg_type) {
1266   case ARG_INT:
1267   case ARG_FLOAT:
1268   case ARG_DOUBLE:
1269     if (val && !(stop_char && *stop_char == '\0')) {
1270       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1271       return 1; /* failure */
1272     }
1273     break;
1274   default:
1275     ;
1276   };
1277 
1278   /* store the original value */
1279   switch(arg_type) {
1280   case ARG_NO:
1281   case ARG_FLAG:
1282     break;
1283   default:
1284     if (value && orig_field) {
1285       if (no_free) {
1286         *orig_field = value;
1287       } else {
1288         if (*orig_field)
1289           free (*orig_field); /* free previous string */
1290         *orig_field = gengetopt_strdup (value);
1291       }
1292     }
1293   };
1294 
1295   return 0; /* OK */
1296 }
1297 
1298 
1299 int
cmdline_parser_internal(int argc,char ** argv,struct gengetopt_args_info * args_info,struct cmdline_parser_params * params,const char * additional_error)1300 cmdline_parser_internal (
1301   int argc, char **argv, struct gengetopt_args_info *args_info,
1302                         struct cmdline_parser_params *params, const char *additional_error)
1303 {
1304   int c;	/* Character of the parsed option.  */
1305 
1306   int error_occurred = 0;
1307   struct gengetopt_args_info local_args_info;
1308 
1309   int override;
1310   int initialize;
1311   int check_required;
1312   int check_ambiguity;
1313 
1314   char *optarg;
1315   int optind;
1316   int opterr;
1317   int optopt;
1318 
1319   package_name = argv[0];
1320 
1321   /* TODO: Why is this here? It is not used anywhere. */
1322   override = params->override;
1323   FIX_UNUSED(override);
1324 
1325   initialize = params->initialize;
1326   check_required = params->check_required;
1327 
1328   /* TODO: Why is this here? It is not used anywhere. */
1329   check_ambiguity = params->check_ambiguity;
1330   FIX_UNUSED(check_ambiguity);
1331 
1332   if (initialize)
1333     cmdline_parser_init (args_info);
1334 
1335   cmdline_parser_init (&local_args_info);
1336 
1337   optarg = 0;
1338   optind = 0;
1339   opterr = params->print_errors;
1340   optopt = '?';
1341 
1342   while (1)
1343     {
1344       int option_index = 0;
1345 
1346       static struct option long_options[] = {
1347         { "help",	0, NULL, 'h' },
1348         { "full-help",	0, NULL, 0 },
1349         { "version",	0, NULL, 'V' },
1350         { "dangle",	1, NULL, 'd' },
1351         { "Temp",	1, NULL, 'T' },
1352         { "Par",	1, NULL, 'P' },
1353         { "logML",	0, NULL, 0 },
1354         { "noShift",	0, NULL, 0 },
1355         { "noLP",	0, NULL, 0 },
1356         { "seed",	1, NULL, 0 },
1357         { "time",	1, NULL, 0 },
1358         { "num",	1, NULL, 0 },
1359         { "start",	0, NULL, 0 },
1360         { "stop",	0, NULL, 0 },
1361         { "met",	0, NULL, 0 },
1362         { "fpt",	0, NULL, 0 },
1363         { "rect",	0, NULL, 0 },
1364         { "grow",	1, NULL, 0 },
1365         { "glen",	1, NULL, 0 },
1366         { "phi",	1, NULL, 0 },
1367         { "pbounds",	1, NULL, 0 },
1368         { "log",	1, NULL, 0 },
1369         { "silent",	0, NULL, 'q' },
1370         { "verbose",	0, NULL, 'v' },
1371         { "lmin",	0, NULL, 0 },
1372         { "cut",	1, NULL, 0 },
1373         { 0,  0, 0, 0 }
1374       };
1375 
1376       custom_optarg = optarg;
1377       custom_optind = optind;
1378       custom_opterr = opterr;
1379       custom_optopt = optopt;
1380 
1381       c = custom_getopt_long (argc, argv, "hVd:T:P:qv", long_options, &option_index);
1382 
1383       optarg = custom_optarg;
1384       optind = custom_optind;
1385       opterr = custom_opterr;
1386       optopt = custom_optopt;
1387 
1388       if (c == -1) break;	/* Exit from `while (1)' loop.  */
1389 
1390       switch (c)
1391         {
1392         case 'h':	/* Print help and exit.  */
1393           cmdline_parser_print_help ();
1394           cmdline_parser_free (&local_args_info);
1395           exit (EXIT_SUCCESS);
1396 
1397         case 'V':	/* Print version and exit.  */
1398           cmdline_parser_print_version ();
1399           cmdline_parser_free (&local_args_info);
1400           exit (EXIT_SUCCESS);
1401 
1402         case 'd':	/* <0|1|2> set dangling end model to (none|normal|double).  */
1403 
1404 
1405           if (update_arg( (void *)&(args_info->dangle_arg),
1406                &(args_info->dangle_orig), &(args_info->dangle_given),
1407               &(local_args_info.dangle_given), optarg, cmdline_parser_dangle_values, "2", ARG_INT,
1408               check_ambiguity, override, 0, 0,
1409               "dangle", 'd',
1410               additional_error))
1411             goto failure;
1412 
1413           break;
1414         case 'T':	/* simulation temperature.  */
1415 
1416 
1417           if (update_arg( (void *)&(args_info->Temp_arg),
1418                &(args_info->Temp_orig), &(args_info->Temp_given),
1419               &(local_args_info.Temp_given), optarg, 0, "37", ARG_FLOAT,
1420               check_ambiguity, override, 0, 0,
1421               "Temp", 'T',
1422               additional_error))
1423             goto failure;
1424 
1425           break;
1426         case 'P':	/* read energy-parameter-file.  */
1427 
1428 
1429           if (update_arg( (void *)&(args_info->Par_arg),
1430                &(args_info->Par_orig), &(args_info->Par_given),
1431               &(local_args_info.Par_given), optarg, 0, 0, ARG_STRING,
1432               check_ambiguity, override, 0, 0,
1433               "Par", 'P',
1434               additional_error))
1435             goto failure;
1436 
1437           break;
1438         case 'q':	/* no output to stdout.  */
1439 
1440 
1441           if (update_arg((void *)&(args_info->silent_flag), 0, &(args_info->silent_given),
1442               &(local_args_info.silent_given), optarg, 0, 0, ARG_FLAG,
1443               check_ambiguity, override, 1, 0, "silent", 'q',
1444               additional_error))
1445             goto failure;
1446 
1447           break;
1448         case 'v':	/* more information to stdout.  */
1449 
1450 
1451           if (update_arg((void *)&(args_info->verbose_flag), 0, &(args_info->verbose_given),
1452               &(local_args_info.verbose_given), optarg, 0, 0, ARG_FLAG,
1453               check_ambiguity, override, 1, 0, "verbose", 'v',
1454               additional_error))
1455             goto failure;
1456 
1457           break;
1458 
1459         case 0:	/* Long option with no short option */
1460           if (strcmp (long_options[option_index].name, "full-help") == 0) {
1461             cmdline_parser_print_full_help ();
1462             cmdline_parser_free (&local_args_info);
1463             exit (EXIT_SUCCESS);
1464           }
1465 
1466           /* use logarithmic multiloop energies instead of linear.  */
1467           if (strcmp (long_options[option_index].name, "logML") == 0)
1468           {
1469 
1470 
1471             if (update_arg((void *)&(args_info->logML_flag), 0, &(args_info->logML_given),
1472                 &(local_args_info.logML_given), optarg, 0, 0, ARG_FLAG,
1473                 check_ambiguity, override, 1, 0, "logML", '-',
1474                 additional_error))
1475               goto failure;
1476 
1477           }
1478           /* turn off shift-moves.  */
1479           else if (strcmp (long_options[option_index].name, "noShift") == 0)
1480           {
1481 
1482 
1483             if (update_arg((void *)&(args_info->noShift_flag), 0, &(args_info->noShift_given),
1484                 &(local_args_info.noShift_given), optarg, 0, 0, ARG_FLAG,
1485                 check_ambiguity, override, 1, 0, "noShift", '-',
1486                 additional_error))
1487               goto failure;
1488 
1489           }
1490           /* forbid structures with isolated base-pairs.  */
1491           else if (strcmp (long_options[option_index].name, "noLP") == 0)
1492           {
1493 
1494 
1495             if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
1496                 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
1497                 check_ambiguity, override, 1, 0, "noLP", '-',
1498                 additional_error))
1499               goto failure;
1500 
1501           }
1502           /* set random number seed specify 3 integers as int=int=int.  */
1503           else if (strcmp (long_options[option_index].name, "seed") == 0)
1504           {
1505 
1506 
1507             if (update_arg( (void *)&(args_info->seed_arg),
1508                  &(args_info->seed_orig), &(args_info->seed_given),
1509                 &(local_args_info.seed_given), optarg, 0, "clock", ARG_STRING,
1510                 check_ambiguity, override, 0, 0,
1511                 "seed", '-',
1512                 additional_error))
1513               goto failure;
1514 
1515           }
1516           /* set maxtime of simulation.  */
1517           else if (strcmp (long_options[option_index].name, "time") == 0)
1518           {
1519 
1520 
1521             if (update_arg( (void *)&(args_info->time_arg),
1522                  &(args_info->time_orig), &(args_info->time_given),
1523                 &(local_args_info.time_given), optarg, 0, "500", ARG_FLOAT,
1524                 check_ambiguity, override, 0, 0,
1525                 "time", '-',
1526                 additional_error))
1527               goto failure;
1528 
1529           }
1530           /* set number of trajectories.  */
1531           else if (strcmp (long_options[option_index].name, "num") == 0)
1532           {
1533 
1534 
1535             if (update_arg( (void *)&(args_info->num_arg),
1536                  &(args_info->num_orig), &(args_info->num_given),
1537                 &(local_args_info.num_given), optarg, 0, "1", ARG_INT,
1538                 check_ambiguity, override, 0, 0,
1539                 "num", '-',
1540                 additional_error))
1541               goto failure;
1542 
1543           }
1544           /* read start structure from stdin (otherwise use open chain).  */
1545           else if (strcmp (long_options[option_index].name, "start") == 0)
1546           {
1547 
1548 
1549             if (update_arg((void *)&(args_info->start_flag), 0, &(args_info->start_given),
1550                 &(local_args_info.start_given), optarg, 0, 0, ARG_FLAG,
1551                 check_ambiguity, override, 1, 0, "start", '-',
1552                 additional_error))
1553               goto failure;
1554 
1555           }
1556           /* read stop structure(s) from stdin (otherwise use MFE).  */
1557           else if (strcmp (long_options[option_index].name, "stop") == 0)
1558           {
1559 
1560 
1561             if (update_arg((void *)&(args_info->stop_flag), 0, &(args_info->stop_given),
1562                 &(local_args_info.stop_given), optarg, 0, 0, ARG_FLAG,
1563                 check_ambiguity, override, 1, 0, "stop", '-',
1564                 additional_error))
1565               goto failure;
1566 
1567           }
1568           /* use Metropolis rule for rates (not Kawasaki rule).  */
1569           else if (strcmp (long_options[option_index].name, "met") == 0)
1570           {
1571 
1572 
1573             if (update_arg((void *)&(args_info->met_flag), 0, &(args_info->met_given),
1574                 &(local_args_info.met_given), optarg, 0, 0, ARG_FLAG,
1575                 check_ambiguity, override, 1, 0, "met", '-',
1576                 additional_error))
1577               goto failure;
1578 
1579           }
1580           /* compute first passage time (stop when a stop-structure is reached).  */
1581           else if (strcmp (long_options[option_index].name, "fpt") == 0)
1582           {
1583 
1584 
1585             if (update_arg((void *)&(args_info->fpt_flag), 0, &(args_info->fpt_given),
1586                 &(local_args_info.fpt_given), optarg, 0, 0, ARG_FLAG,
1587                 check_ambiguity, override, 1, 0, "fpt", '-',
1588                 additional_error))
1589               goto failure;
1590 
1591           }
1592           /* compute recurrence time (of a start structure which is contained in stop structures).  */
1593           else if (strcmp (long_options[option_index].name, "rect") == 0)
1594           {
1595 
1596 
1597             if (update_arg((void *)&(args_info->rect_flag), 0, &(args_info->rect_given),
1598                 &(local_args_info.rect_given), optarg, 0, 0, ARG_FLAG,
1599                 check_ambiguity, override, 1, 0, "rect", '-',
1600                 additional_error))
1601               goto failure;
1602 
1603           }
1604           /* grow chain every <float> time units.  */
1605           else if (strcmp (long_options[option_index].name, "grow") == 0)
1606           {
1607 
1608 
1609             if (update_arg( (void *)&(args_info->grow_arg),
1610                  &(args_info->grow_orig), &(args_info->grow_given),
1611                 &(local_args_info.grow_given), optarg, 0, "0", ARG_FLOAT,
1612                 check_ambiguity, override, 0, 0,
1613                 "grow", '-',
1614                 additional_error))
1615               goto failure;
1616 
1617           }
1618           /* initial size of growing chain.  */
1619           else if (strcmp (long_options[option_index].name, "glen") == 0)
1620           {
1621 
1622 
1623             if (update_arg( (void *)&(args_info->glen_arg),
1624                  &(args_info->glen_orig), &(args_info->glen_given),
1625                 &(local_args_info.glen_given), optarg, 0, "15", ARG_INT,
1626                 check_ambiguity, override, 0, 0,
1627                 "glen", '-',
1628                 additional_error))
1629               goto failure;
1630 
1631           }
1632           /* set phi value.  */
1633           else if (strcmp (long_options[option_index].name, "phi") == 0)
1634           {
1635 
1636 
1637             if (update_arg( (void *)&(args_info->phi_arg),
1638                  &(args_info->phi_orig), &(args_info->phi_given),
1639                 &(local_args_info.phi_given), optarg, 0, 0, ARG_DOUBLE,
1640                 check_ambiguity, override, 0, 0,
1641                 "phi", '-',
1642                 additional_error))
1643               goto failure;
1644 
1645           }
1646           /* specify 3 floats for phi_min, phi_inc, phi_max in the form <d1=d2=d3>.  */
1647           else if (strcmp (long_options[option_index].name, "pbounds") == 0)
1648           {
1649 
1650 
1651             if (update_arg( (void *)&(args_info->pbounds_arg),
1652                  &(args_info->pbounds_orig), &(args_info->pbounds_given),
1653                 &(local_args_info.pbounds_given), optarg, 0, 0, ARG_STRING,
1654                 check_ambiguity, override, 0, 0,
1655                 "pbounds", '-',
1656                 additional_error))
1657               goto failure;
1658 
1659           }
1660           /* set basename of log-file.  */
1661           else if (strcmp (long_options[option_index].name, "log") == 0)
1662           {
1663 
1664 
1665             if (update_arg( (void *)&(args_info->log_arg),
1666                  &(args_info->log_orig), &(args_info->log_given),
1667                 &(local_args_info.log_given), optarg, 0, "kinout", ARG_STRING,
1668                 check_ambiguity, override, 0, 0,
1669                 "log", '-',
1670                 additional_error))
1671               goto failure;
1672 
1673           }
1674           /* output only local minima to stdout.  */
1675           else if (strcmp (long_options[option_index].name, "lmin") == 0)
1676           {
1677 
1678 
1679             if (update_arg((void *)&(args_info->lmin_flag), 0, &(args_info->lmin_given),
1680                 &(local_args_info.lmin_given), optarg, 0, 0, ARG_FLAG,
1681                 check_ambiguity, override, 1, 0, "lmin", '-',
1682                 additional_error))
1683               goto failure;
1684 
1685           }
1686           /* only print structures with E <= MFE + <float> to stdout.  */
1687           else if (strcmp (long_options[option_index].name, "cut") == 0)
1688           {
1689 
1690 
1691             if (update_arg( (void *)&(args_info->cut_arg),
1692                  &(args_info->cut_orig), &(args_info->cut_given),
1693                 &(local_args_info.cut_given), optarg, 0, "20", ARG_FLOAT,
1694                 check_ambiguity, override, 0, 0,
1695                 "cut", '-',
1696                 additional_error))
1697               goto failure;
1698 
1699           }
1700 
1701           break;
1702         case '?':	/* Invalid option.  */
1703           /* `getopt_long' already printed an error message.  */
1704           goto failure;
1705 
1706         default:	/* bug: option not considered.  */
1707           fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1708           abort ();
1709         } /* switch */
1710     } /* while */
1711 
1712 
1713 
1714 	FIX_UNUSED(check_required);
1715 
1716   cmdline_parser_release (&local_args_info);
1717 
1718   if ( error_occurred )
1719     return (EXIT_FAILURE);
1720 
1721   return 0;
1722 
1723 failure:
1724 
1725   cmdline_parser_release (&local_args_info);
1726   return (EXIT_FAILURE);
1727 }
1728 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
1729