1 /*
2   File autogenerated by gengetopt version 2.23
3   generated with the following command:
4   /usr/bin/gengetopt -i RNApdist.ggo --file-name=RNApdist_cmdl --include-getopt --default-optional --func-name=RNApdist_cmdline_parser --arg-struct-name=RNApdist_args_info
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 "RNApdist_cmdl.h"
26 
27 const char *RNApdist_args_info_purpose = "Calculate distances between thermodynamic RNA secondary structures ensembles";
28 
29 const char *RNApdist_args_info_usage = "Usage: RNApdist [OPTION]...";
30 
31 const char *RNApdist_args_info_versiontext = "";
32 
33 const char *RNApdist_args_info_description = "This program reads RNA sequences from stdin and calculates structure distances\nbetween the thermodynamic ensembles of their secondary structures.\n";
34 
35 const char *RNApdist_args_info_detailed_help[] = {
36   "  -h, --help                    Print help and exit",
37   "      --detailed-help           Print help, including all details and hidden\n                                  options, and exit",
38   "      --full-help               Print help, including hidden options, and exit",
39   "  -V, --version                 Print version and exit",
40   "\nGeneral Options:",
41   "      --noconv                  Do not automatically substitude nucleotide\n                                  \"T\" with \"U\"\n\n                                    (default=off)",
42   "\nAlgorithms:",
43   "  -X, --compare=p|m|f|c         Specify the comparison directive.\n                                    (default=`p')",
44   "  Possible arguments for this option are: -Xp compare the structures pairwise\n  (p), i.e. first with 2nd, third with 4th etc.\n  -Xm calculate the distance matrix between all structures. The output is\n  formatted as a lower triangle matrix.\n  -Xf compare each structure to the first one.\n  -Xc compare continuously, that is i-th with (i+1)th structure.\n\n",
45   "  -B, --backtrack[=<filename>]  Print an \"alignment\" with gaps of the\n                                  profiles. The aligned structures are written\n                                  to <filename>, if specified.\n                                    (default=`none')",
46   "  Within the profile output, the following symbols will be used:\n\n   ()  essentially upstream (downstream) paired bases\n\n   {}  weakly upstream (downstream) paired bases\n\n   |    strongly paired bases without preference\n\n   ,    weakly paired bases without preference\n\n   .    essentially unpaired bases.\n\n   If <filename> is not specified, the output is written to stdout, unless the\n  \"-Xm\" option is set in which case \"backtrack.file\" is used.\n\n",
47   "\nModel Details:",
48   "  -T, --temp=DOUBLE             Rescale energy parameters to a temperature of\n                                  temp C. Default is 37C.\n\n",
49   "  -4, --noTetra                 Do not include special tabulated stabilizing\n                                  energies for tri-, tetra- and hexaloop\n                                  hairpins. Mostly for testing.\n\n                                    (default=off)",
50   "  -d, --dangles=INT             set energy model for treatment of dangling\n                                  bases\n\n                                    (possible values=\"0\", \"2\" default=`2')",
51   "      --noLP                    Produce structures without lonely pairs\n                                  (helices of length 1).\n                                    (default=off)",
52   "  For partition function folding this only disallows pairs that can only occur\n  isolated. Other pairs may still occasionally occur as helices of length 1.\n\n",
53   "      --noGU                    Do not allow GU pairs\n\n                                    (default=off)",
54   "      --noClosingGU             Do not allow GU pairs at the end of helices\n\n                                    (default=off)",
55   "  -P, --paramFile=paramfile     Read energy parameters from paramfile, instead\n                                  of using the default parameter set.\n",
56   "  Different sets of energy parameters for RNA and DNA should accompany your\n  distribution.\n  See the RNAlib documentation for details on the file format. When passing the\n  placeholder file name \"DNA\", DNA parameters are loaded without the need to\n  actually specify any input file.\n\n",
57   "      --nsp=STRING              Allow other pairs in addition to the usual\n                                  AU,GC,and GU pairs.\n",
58   "  Its argument is a comma separated list of additionally allowed pairs. If the\n  first character is a \"-\" then AB will imply that AB and BA are allowed\n  pairs.\n  e.g. RNAfold -nsp -GA  will allow GA and AG pairs. Nonstandard pairs are\n  given 0 stacking energy.\n\n",
59   "  -e, --energyModel=INT         Rarely used option to fold sequences from the\n                                  artificial ABCD... alphabet, where A pairs B,\n                                  C-D etc.  Use the energy parameters for GC\n                                  (-e 1) or AU (-e 2) pairs.\n\n",
60   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n\n",
61     0
62 };
63 static void
init_full_help_array(void)64 init_full_help_array(void)
65 {
66   RNApdist_args_info_full_help[0] = RNApdist_args_info_detailed_help[0];
67   RNApdist_args_info_full_help[1] = RNApdist_args_info_detailed_help[1];
68   RNApdist_args_info_full_help[2] = RNApdist_args_info_detailed_help[2];
69   RNApdist_args_info_full_help[3] = RNApdist_args_info_detailed_help[3];
70   RNApdist_args_info_full_help[4] = RNApdist_args_info_detailed_help[4];
71   RNApdist_args_info_full_help[5] = RNApdist_args_info_detailed_help[5];
72   RNApdist_args_info_full_help[6] = RNApdist_args_info_detailed_help[6];
73   RNApdist_args_info_full_help[7] = RNApdist_args_info_detailed_help[7];
74   RNApdist_args_info_full_help[8] = RNApdist_args_info_detailed_help[9];
75   RNApdist_args_info_full_help[9] = RNApdist_args_info_detailed_help[11];
76   RNApdist_args_info_full_help[10] = RNApdist_args_info_detailed_help[12];
77   RNApdist_args_info_full_help[11] = RNApdist_args_info_detailed_help[13];
78   RNApdist_args_info_full_help[12] = RNApdist_args_info_detailed_help[14];
79   RNApdist_args_info_full_help[13] = RNApdist_args_info_detailed_help[15];
80   RNApdist_args_info_full_help[14] = RNApdist_args_info_detailed_help[17];
81   RNApdist_args_info_full_help[15] = RNApdist_args_info_detailed_help[18];
82   RNApdist_args_info_full_help[16] = RNApdist_args_info_detailed_help[19];
83   RNApdist_args_info_full_help[17] = RNApdist_args_info_detailed_help[21];
84   RNApdist_args_info_full_help[18] = RNApdist_args_info_detailed_help[23];
85   RNApdist_args_info_full_help[19] = RNApdist_args_info_detailed_help[24];
86   RNApdist_args_info_full_help[20] = 0;
87 
88 }
89 
90 const char *RNApdist_args_info_full_help[21];
91 
92 static void
init_help_array(void)93 init_help_array(void)
94 {
95   RNApdist_args_info_help[0] = RNApdist_args_info_detailed_help[0];
96   RNApdist_args_info_help[1] = RNApdist_args_info_detailed_help[1];
97   RNApdist_args_info_help[2] = RNApdist_args_info_detailed_help[2];
98   RNApdist_args_info_help[3] = RNApdist_args_info_detailed_help[3];
99   RNApdist_args_info_help[4] = RNApdist_args_info_detailed_help[4];
100   RNApdist_args_info_help[5] = RNApdist_args_info_detailed_help[5];
101   RNApdist_args_info_help[6] = RNApdist_args_info_detailed_help[6];
102   RNApdist_args_info_help[7] = RNApdist_args_info_detailed_help[7];
103   RNApdist_args_info_help[8] = RNApdist_args_info_detailed_help[9];
104   RNApdist_args_info_help[9] = RNApdist_args_info_detailed_help[11];
105   RNApdist_args_info_help[10] = RNApdist_args_info_detailed_help[12];
106   RNApdist_args_info_help[11] = RNApdist_args_info_detailed_help[13];
107   RNApdist_args_info_help[12] = RNApdist_args_info_detailed_help[14];
108   RNApdist_args_info_help[13] = RNApdist_args_info_detailed_help[15];
109   RNApdist_args_info_help[14] = RNApdist_args_info_detailed_help[17];
110   RNApdist_args_info_help[15] = RNApdist_args_info_detailed_help[18];
111   RNApdist_args_info_help[16] = RNApdist_args_info_detailed_help[19];
112   RNApdist_args_info_help[17] = RNApdist_args_info_detailed_help[24];
113   RNApdist_args_info_help[18] = 0;
114 
115 }
116 
117 const char *RNApdist_args_info_help[19];
118 
119 typedef enum {ARG_NO
120   , ARG_FLAG
121   , ARG_STRING
122   , ARG_INT
123   , ARG_DOUBLE
124 } RNApdist_cmdline_parser_arg_type;
125 
126 static
127 void clear_given (struct RNApdist_args_info *args_info);
128 static
129 void clear_args (struct RNApdist_args_info *args_info);
130 
131 static int
132 RNApdist_cmdline_parser_internal (int argc, char **argv, struct RNApdist_args_info *args_info,
133                         struct RNApdist_cmdline_parser_params *params, const char *additional_error);
134 
135 
136 const char *RNApdist_cmdline_parser_dangles_values[] = {"0", "2", 0}; /*< Possible values for dangles. */
137 
138 static char *
139 gengetopt_strdup (const char *s);
140 
141 static
clear_given(struct RNApdist_args_info * args_info)142 void clear_given (struct RNApdist_args_info *args_info)
143 {
144   args_info->help_given = 0 ;
145   args_info->detailed_help_given = 0 ;
146   args_info->full_help_given = 0 ;
147   args_info->version_given = 0 ;
148   args_info->noconv_given = 0 ;
149   args_info->compare_given = 0 ;
150   args_info->backtrack_given = 0 ;
151   args_info->temp_given = 0 ;
152   args_info->noTetra_given = 0 ;
153   args_info->dangles_given = 0 ;
154   args_info->noLP_given = 0 ;
155   args_info->noGU_given = 0 ;
156   args_info->noClosingGU_given = 0 ;
157   args_info->paramFile_given = 0 ;
158   args_info->nsp_given = 0 ;
159   args_info->energyModel_given = 0 ;
160 }
161 
162 static
clear_args(struct RNApdist_args_info * args_info)163 void clear_args (struct RNApdist_args_info *args_info)
164 {
165   FIX_UNUSED (args_info);
166   args_info->noconv_flag = 0;
167   args_info->compare_arg = gengetopt_strdup ("p");
168   args_info->compare_orig = NULL;
169   args_info->backtrack_arg = gengetopt_strdup ("none");
170   args_info->backtrack_orig = NULL;
171   args_info->temp_orig = NULL;
172   args_info->noTetra_flag = 0;
173   args_info->dangles_arg = 2;
174   args_info->dangles_orig = NULL;
175   args_info->noLP_flag = 0;
176   args_info->noGU_flag = 0;
177   args_info->noClosingGU_flag = 0;
178   args_info->paramFile_arg = NULL;
179   args_info->paramFile_orig = NULL;
180   args_info->nsp_arg = NULL;
181   args_info->nsp_orig = NULL;
182   args_info->energyModel_orig = NULL;
183 
184 }
185 
186 static
init_args_info(struct RNApdist_args_info * args_info)187 void init_args_info(struct RNApdist_args_info *args_info)
188 {
189   init_full_help_array();
190   init_help_array();
191   args_info->help_help = RNApdist_args_info_detailed_help[0] ;
192   args_info->detailed_help_help = RNApdist_args_info_detailed_help[1] ;
193   args_info->full_help_help = RNApdist_args_info_detailed_help[2] ;
194   args_info->version_help = RNApdist_args_info_detailed_help[3] ;
195   args_info->noconv_help = RNApdist_args_info_detailed_help[5] ;
196   args_info->compare_help = RNApdist_args_info_detailed_help[7] ;
197   args_info->backtrack_help = RNApdist_args_info_detailed_help[9] ;
198   args_info->temp_help = RNApdist_args_info_detailed_help[12] ;
199   args_info->noTetra_help = RNApdist_args_info_detailed_help[13] ;
200   args_info->dangles_help = RNApdist_args_info_detailed_help[14] ;
201   args_info->noLP_help = RNApdist_args_info_detailed_help[15] ;
202   args_info->noGU_help = RNApdist_args_info_detailed_help[17] ;
203   args_info->noClosingGU_help = RNApdist_args_info_detailed_help[18] ;
204   args_info->paramFile_help = RNApdist_args_info_detailed_help[19] ;
205   args_info->nsp_help = RNApdist_args_info_detailed_help[21] ;
206   args_info->energyModel_help = RNApdist_args_info_detailed_help[23] ;
207 
208 }
209 
210 void
RNApdist_cmdline_parser_print_version(void)211 RNApdist_cmdline_parser_print_version (void)
212 {
213   printf ("%s %s\n",
214      (strlen(RNAPDIST_CMDLINE_PARSER_PACKAGE_NAME) ? RNAPDIST_CMDLINE_PARSER_PACKAGE_NAME : RNAPDIST_CMDLINE_PARSER_PACKAGE),
215      RNAPDIST_CMDLINE_PARSER_VERSION);
216 
217   if (strlen(RNApdist_args_info_versiontext) > 0)
218     printf("\n%s\n", RNApdist_args_info_versiontext);
219 }
220 
print_help_common(void)221 static void print_help_common(void)
222 {
223 	size_t len_purpose = strlen(RNApdist_args_info_purpose);
224 	size_t len_usage = strlen(RNApdist_args_info_usage);
225 
226 	if (len_usage > 0) {
227 		printf("%s\n", RNApdist_args_info_usage);
228 	}
229 	if (len_purpose > 0) {
230 		printf("%s\n", RNApdist_args_info_purpose);
231 	}
232 
233 	if (len_usage || len_purpose) {
234 		printf("\n");
235 	}
236 
237 	if (strlen(RNApdist_args_info_description) > 0) {
238 		printf("%s\n\n", RNApdist_args_info_description);
239 	}
240 }
241 
242 void
RNApdist_cmdline_parser_print_help(void)243 RNApdist_cmdline_parser_print_help (void)
244 {
245   int i = 0;
246   print_help_common();
247   while (RNApdist_args_info_help[i])
248     printf("%s\n", RNApdist_args_info_help[i++]);
249 }
250 
251 void
RNApdist_cmdline_parser_print_full_help(void)252 RNApdist_cmdline_parser_print_full_help (void)
253 {
254   int i = 0;
255   print_help_common();
256   while (RNApdist_args_info_full_help[i])
257     printf("%s\n", RNApdist_args_info_full_help[i++]);
258 }
259 
260 void
RNApdist_cmdline_parser_print_detailed_help(void)261 RNApdist_cmdline_parser_print_detailed_help (void)
262 {
263   int i = 0;
264   print_help_common();
265   while (RNApdist_args_info_detailed_help[i])
266     printf("%s\n", RNApdist_args_info_detailed_help[i++]);
267 }
268 
269 void
RNApdist_cmdline_parser_init(struct RNApdist_args_info * args_info)270 RNApdist_cmdline_parser_init (struct RNApdist_args_info *args_info)
271 {
272   clear_given (args_info);
273   clear_args (args_info);
274   init_args_info (args_info);
275 }
276 
277 void
RNApdist_cmdline_parser_params_init(struct RNApdist_cmdline_parser_params * params)278 RNApdist_cmdline_parser_params_init(struct RNApdist_cmdline_parser_params *params)
279 {
280   if (params)
281     {
282       params->override = 0;
283       params->initialize = 1;
284       params->check_required = 1;
285       params->check_ambiguity = 0;
286       params->print_errors = 1;
287     }
288 }
289 
290 struct RNApdist_cmdline_parser_params *
RNApdist_cmdline_parser_params_create(void)291 RNApdist_cmdline_parser_params_create(void)
292 {
293   struct RNApdist_cmdline_parser_params *params =
294     (struct RNApdist_cmdline_parser_params *)malloc(sizeof(struct RNApdist_cmdline_parser_params));
295   RNApdist_cmdline_parser_params_init(params);
296   return params;
297 }
298 
299 static void
free_string_field(char ** s)300 free_string_field (char **s)
301 {
302   if (*s)
303     {
304       free (*s);
305       *s = 0;
306     }
307 }
308 
309 
310 static void
RNApdist_cmdline_parser_release(struct RNApdist_args_info * args_info)311 RNApdist_cmdline_parser_release (struct RNApdist_args_info *args_info)
312 {
313 
314   free_string_field (&(args_info->compare_arg));
315   free_string_field (&(args_info->compare_orig));
316   free_string_field (&(args_info->backtrack_arg));
317   free_string_field (&(args_info->backtrack_orig));
318   free_string_field (&(args_info->temp_orig));
319   free_string_field (&(args_info->dangles_orig));
320   free_string_field (&(args_info->paramFile_arg));
321   free_string_field (&(args_info->paramFile_orig));
322   free_string_field (&(args_info->nsp_arg));
323   free_string_field (&(args_info->nsp_orig));
324   free_string_field (&(args_info->energyModel_orig));
325 
326 
327 
328   clear_given (args_info);
329 }
330 
331 /**
332  * @param val the value to check
333  * @param values the possible values
334  * @return the index of the matched value:
335  * -1 if no value matched,
336  * -2 if more than one value has matched
337  */
338 static int
check_possible_values(const char * val,const char * values[])339 check_possible_values(const char *val, const char *values[])
340 {
341   int i, found, last;
342   size_t len;
343 
344   if (!val)   /* otherwise strlen() crashes below */
345     return -1; /* -1 means no argument for the option */
346 
347   found = last = 0;
348 
349   for (i = 0, len = strlen(val); values[i]; ++i)
350     {
351       if (strncmp(val, values[i], len) == 0)
352         {
353           ++found;
354           last = i;
355           if (strlen(values[i]) == len)
356             return i; /* exact macth no need to check more */
357         }
358     }
359 
360   if (found == 1) /* one match: OK */
361     return last;
362 
363   return (found ? -2 : -1); /* return many values or none matched */
364 }
365 
366 
367 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])368 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
369 {
370   int found = -1;
371   if (arg) {
372     if (values) {
373       found = check_possible_values(arg, values);
374     }
375     if (found >= 0)
376       fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]);
377     else
378       fprintf(outfile, "%s=\"%s\"\n", opt, arg);
379   } else {
380     fprintf(outfile, "%s\n", opt);
381   }
382 }
383 
384 
385 int
RNApdist_cmdline_parser_dump(FILE * outfile,struct RNApdist_args_info * args_info)386 RNApdist_cmdline_parser_dump(FILE *outfile, struct RNApdist_args_info *args_info)
387 {
388   int i = 0;
389 
390   if (!outfile)
391     {
392       fprintf (stderr, "%s: cannot dump options to stream\n", RNAPDIST_CMDLINE_PARSER_PACKAGE);
393       return EXIT_FAILURE;
394     }
395 
396   if (args_info->help_given)
397     write_into_file(outfile, "help", 0, 0 );
398   if (args_info->detailed_help_given)
399     write_into_file(outfile, "detailed-help", 0, 0 );
400   if (args_info->full_help_given)
401     write_into_file(outfile, "full-help", 0, 0 );
402   if (args_info->version_given)
403     write_into_file(outfile, "version", 0, 0 );
404   if (args_info->noconv_given)
405     write_into_file(outfile, "noconv", 0, 0 );
406   if (args_info->compare_given)
407     write_into_file(outfile, "compare", args_info->compare_orig, 0);
408   if (args_info->backtrack_given)
409     write_into_file(outfile, "backtrack", args_info->backtrack_orig, 0);
410   if (args_info->temp_given)
411     write_into_file(outfile, "temp", args_info->temp_orig, 0);
412   if (args_info->noTetra_given)
413     write_into_file(outfile, "noTetra", 0, 0 );
414   if (args_info->dangles_given)
415     write_into_file(outfile, "dangles", args_info->dangles_orig, RNApdist_cmdline_parser_dangles_values);
416   if (args_info->noLP_given)
417     write_into_file(outfile, "noLP", 0, 0 );
418   if (args_info->noGU_given)
419     write_into_file(outfile, "noGU", 0, 0 );
420   if (args_info->noClosingGU_given)
421     write_into_file(outfile, "noClosingGU", 0, 0 );
422   if (args_info->paramFile_given)
423     write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
424   if (args_info->nsp_given)
425     write_into_file(outfile, "nsp", args_info->nsp_orig, 0);
426   if (args_info->energyModel_given)
427     write_into_file(outfile, "energyModel", args_info->energyModel_orig, 0);
428 
429 
430   i = EXIT_SUCCESS;
431   return i;
432 }
433 
434 int
RNApdist_cmdline_parser_file_save(const char * filename,struct RNApdist_args_info * args_info)435 RNApdist_cmdline_parser_file_save(const char *filename, struct RNApdist_args_info *args_info)
436 {
437   FILE *outfile;
438   int i = 0;
439 
440   outfile = fopen(filename, "w");
441 
442   if (!outfile)
443     {
444       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNAPDIST_CMDLINE_PARSER_PACKAGE, filename);
445       return EXIT_FAILURE;
446     }
447 
448   i = RNApdist_cmdline_parser_dump(outfile, args_info);
449   fclose (outfile);
450 
451   return i;
452 }
453 
454 void
RNApdist_cmdline_parser_free(struct RNApdist_args_info * args_info)455 RNApdist_cmdline_parser_free (struct RNApdist_args_info *args_info)
456 {
457   RNApdist_cmdline_parser_release (args_info);
458 }
459 
460 /** @brief replacement of strdup, which is not standard */
461 char *
gengetopt_strdup(const char * s)462 gengetopt_strdup (const char *s)
463 {
464   char *result = 0;
465   if (!s)
466     return result;
467 
468   result = (char*)malloc(strlen(s) + 1);
469   if (result == (char*)0)
470     return (char*)0;
471   strcpy(result, s);
472   return result;
473 }
474 
475 int
RNApdist_cmdline_parser(int argc,char ** argv,struct RNApdist_args_info * args_info)476 RNApdist_cmdline_parser (int argc, char **argv, struct RNApdist_args_info *args_info)
477 {
478   return RNApdist_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
479 }
480 
481 int
RNApdist_cmdline_parser_ext(int argc,char ** argv,struct RNApdist_args_info * args_info,struct RNApdist_cmdline_parser_params * params)482 RNApdist_cmdline_parser_ext (int argc, char **argv, struct RNApdist_args_info *args_info,
483                    struct RNApdist_cmdline_parser_params *params)
484 {
485   int result;
486   result = RNApdist_cmdline_parser_internal (argc, argv, args_info, params, 0);
487 
488   if (result == EXIT_FAILURE)
489     {
490       RNApdist_cmdline_parser_free (args_info);
491       exit (EXIT_FAILURE);
492     }
493 
494   return result;
495 }
496 
497 int
RNApdist_cmdline_parser2(int argc,char ** argv,struct RNApdist_args_info * args_info,int override,int initialize,int check_required)498 RNApdist_cmdline_parser2 (int argc, char **argv, struct RNApdist_args_info *args_info, int override, int initialize, int check_required)
499 {
500   int result;
501   struct RNApdist_cmdline_parser_params params;
502 
503   params.override = override;
504   params.initialize = initialize;
505   params.check_required = check_required;
506   params.check_ambiguity = 0;
507   params.print_errors = 1;
508 
509   result = RNApdist_cmdline_parser_internal (argc, argv, args_info, &params, 0);
510 
511   if (result == EXIT_FAILURE)
512     {
513       RNApdist_cmdline_parser_free (args_info);
514       exit (EXIT_FAILURE);
515     }
516 
517   return result;
518 }
519 
520 int
RNApdist_cmdline_parser_required(struct RNApdist_args_info * args_info,const char * prog_name)521 RNApdist_cmdline_parser_required (struct RNApdist_args_info *args_info, const char *prog_name)
522 {
523   FIX_UNUSED (args_info);
524   FIX_UNUSED (prog_name);
525   return EXIT_SUCCESS;
526 }
527 
528 /*
529  * Extracted from the glibc source tree, version 2.3.6
530  *
531  * Licensed under the GPL as per the whole glibc source tree.
532  *
533  * This file was modified so that getopt_long can be called
534  * many times without risking previous memory to be spoiled.
535  *
536  * Modified by Andre Noll and Lorenzo Bettini for use in
537  * GNU gengetopt generated files.
538  *
539  */
540 
541 /*
542  * we must include anything we need since this file is not thought to be
543  * inserted in a file already using getopt.h
544  *
545  * Lorenzo
546  */
547 
548 struct option
549 {
550   const char *name;
551   /* has_arg can't be an enum because some compilers complain about
552      type mismatches in all the code that assumes it is an int.  */
553   int has_arg;
554   int *flag;
555   int val;
556 };
557 
558 /* This version of `getopt' appears to the caller like standard Unix `getopt'
559    but it behaves differently for the user, since it allows the user
560    to intersperse the options with the other arguments.
561 
562    As `getopt' works, it permutes the elements of ARGV so that,
563    when it is done, all the options precede everything else.  Thus
564    all application programs are extended to handle flexible argument order.
565 */
566 /*
567    If the field `flag' is not NULL, it points to a variable that is set
568    to the value given in the field `val' when the option is found, but
569    left unchanged if the option is not found.
570 
571    To have a long-named option do something other than set an `int' to
572    a compiled-in constant, such as set a value from `custom_optarg', set the
573    option's `flag' field to zero and its `val' field to a nonzero
574    value (the equivalent single-letter option character, if there is
575    one).  For long options that have a zero `flag' field, `getopt'
576    returns the contents of the `val' field.  */
577 
578 /* Names for the values of the `has_arg' field of `struct option'.  */
579 #ifndef no_argument
580 #define no_argument		0
581 #endif
582 
583 #ifndef required_argument
584 #define required_argument	1
585 #endif
586 
587 #ifndef optional_argument
588 #define optional_argument	2
589 #endif
590 
591 struct custom_getopt_data {
592 	/*
593 	 * These have exactly the same meaning as the corresponding global variables,
594 	 * except that they are used for the reentrant versions of getopt.
595 	 */
596 	int custom_optind;
597 	int custom_opterr;
598 	int custom_optopt;
599 	char *custom_optarg;
600 
601 	/* True if the internal members have been initialized.  */
602 	int initialized;
603 
604 	/*
605 	 * The next char to be scanned in the option-element in which the last option
606 	 * character we returned was found.  This allows us to pick up the scan where
607 	 * we left off.  If this is zero, or a null string, it means resume the scan by
608 	 * advancing to the next ARGV-element.
609 	 */
610 	char *nextchar;
611 
612 	/*
613 	 * Describe the part of ARGV that contains non-options that have been skipped.
614 	 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
615 	 * the index after the last of them.
616 	 */
617 	int first_nonopt;
618 	int last_nonopt;
619 };
620 
621 /*
622  * the variables optarg, optind, opterr and optopt are renamed with
623  * the custom_ prefix so that they don't interfere with getopt ones.
624  *
625  * Moreover they're static so they are visible only from within the
626  * file where this very file will be included.
627  */
628 
629 /*
630  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
631  * option that takes an argument, the argument value is returned here.
632  */
633 static char *custom_optarg;
634 
635 /*
636  * Index in ARGV of the next element to be scanned.  This is used for
637  * communication to and from the caller and for communication between
638  * successive calls to `custom_getopt'.
639  *
640  * On entry to `custom_getopt', 1 means this is the first call; initialize.
641  *
642  * When `custom_getopt' returns -1, this is the index of the first of the non-option
643  * elements that the caller should itself scan.
644  *
645  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
646  * has been scanned so far.
647  *
648  * 1003.2 says this must be 1 before any call.
649  */
650 static int custom_optind = 1;
651 
652 /*
653  * Callers store zero here to inhibit the error message for unrecognized
654  * options.
655  */
656 static int custom_opterr = 1;
657 
658 /*
659  * Set to an option character which was unrecognized.  This must be initialized
660  * on some systems to avoid linking in the system's own getopt implementation.
661  */
662 static int custom_optopt = '?';
663 
664 /*
665  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
666  * [first_nonopt,last_nonopt) which contains all the non-options that have been
667  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
668  * all the options processed since those non-options were skipped.
669  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
670  * indices of the non-options in ARGV after they are moved.
671  */
exchange(char ** argv,struct custom_getopt_data * d)672 static void exchange(char **argv, struct custom_getopt_data *d)
673 {
674 	int bottom = d->first_nonopt;
675 	int middle = d->last_nonopt;
676 	int top = d->custom_optind;
677 	char *tem;
678 
679 	/*
680 	 * Exchange the shorter segment with the far end of the longer segment.
681 	 * That puts the shorter segment into the right place.  It leaves the
682 	 * longer segment in the right place overall, but it consists of two
683 	 * parts that need to be swapped next.
684 	 */
685 	while (top > middle && middle > bottom) {
686 		if (top - middle > middle - bottom) {
687 			/* Bottom segment is the short one.  */
688 			int len = middle - bottom;
689 			int i;
690 
691 			/* Swap it with the top part of the top segment.  */
692 			for (i = 0; i < len; i++) {
693 				tem = argv[bottom + i];
694 				argv[bottom + i] =
695 					argv[top - (middle - bottom) + i];
696 				argv[top - (middle - bottom) + i] = tem;
697 			}
698 			/* Exclude the moved bottom segment from further swapping.  */
699 			top -= len;
700 		} else {
701 			/* Top segment is the short one.  */
702 			int len = top - middle;
703 			int i;
704 
705 			/* Swap it with the bottom part of the bottom segment.  */
706 			for (i = 0; i < len; i++) {
707 				tem = argv[bottom + i];
708 				argv[bottom + i] = argv[middle + i];
709 				argv[middle + i] = tem;
710 			}
711 			/* Exclude the moved top segment from further swapping.  */
712 			bottom += len;
713 		}
714 	}
715 	/* Update records for the slots the non-options now occupy.  */
716 	d->first_nonopt += (d->custom_optind - d->last_nonopt);
717 	d->last_nonopt = d->custom_optind;
718 }
719 
720 /* Initialize the internal data when the first call is made.  */
custom_getopt_initialize(struct custom_getopt_data * d)721 static void custom_getopt_initialize(struct custom_getopt_data *d)
722 {
723 	/*
724 	 * Start processing options with ARGV-element 1 (since ARGV-element 0
725 	 * is the program name); the sequence of previously skipped non-option
726 	 * ARGV-elements is empty.
727 	 */
728 	d->first_nonopt = d->last_nonopt = d->custom_optind;
729 	d->nextchar = NULL;
730 	d->initialized = 1;
731 }
732 
733 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
734 
735 /* 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)736 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
737 	struct custom_getopt_data *d)
738 {
739 	/*
740 	 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
741 	 * moved back by the user (who may also have changed the arguments).
742 	 */
743 	if (d->last_nonopt > d->custom_optind)
744 		d->last_nonopt = d->custom_optind;
745 	if (d->first_nonopt > d->custom_optind)
746 		d->first_nonopt = d->custom_optind;
747 	/*
748 	 * If we have just processed some options following some
749 	 * non-options, exchange them so that the options come first.
750 	 */
751 	if (d->first_nonopt != d->last_nonopt &&
752 			d->last_nonopt != d->custom_optind)
753 		exchange((char **) argv, d);
754 	else if (d->last_nonopt != d->custom_optind)
755 		d->first_nonopt = d->custom_optind;
756 	/*
757 	 * Skip any additional non-options and extend the range of
758 	 * non-options previously skipped.
759 	 */
760 	while (d->custom_optind < argc && NONOPTION_P)
761 		d->custom_optind++;
762 	d->last_nonopt = d->custom_optind;
763 	/*
764 	 * The special ARGV-element `--' means premature end of options.  Skip
765 	 * it like a null option, then exchange with previous non-options as if
766 	 * it were an option, then skip everything else like a non-option.
767 	 */
768 	if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
769 		d->custom_optind++;
770 		if (d->first_nonopt != d->last_nonopt
771 				&& d->last_nonopt != d->custom_optind)
772 			exchange((char **) argv, d);
773 		else if (d->first_nonopt == d->last_nonopt)
774 			d->first_nonopt = d->custom_optind;
775 		d->last_nonopt = argc;
776 		d->custom_optind = argc;
777 	}
778 	/*
779 	 * If we have done all the ARGV-elements, stop the scan and back over
780 	 * any non-options that we skipped and permuted.
781 	 */
782 	if (d->custom_optind == argc) {
783 		/*
784 		 * Set the next-arg-index to point at the non-options that we
785 		 * previously skipped, so the caller will digest them.
786 		 */
787 		if (d->first_nonopt != d->last_nonopt)
788 			d->custom_optind = d->first_nonopt;
789 		return -1;
790 	}
791 	/*
792 	 * If we have come to a non-option and did not permute it, either stop
793 	 * the scan or describe it to the caller and pass it by.
794 	 */
795 	if (NONOPTION_P) {
796 		d->custom_optarg = argv[d->custom_optind++];
797 		return 1;
798 	}
799 	/*
800 	 * We have found another option-ARGV-element. Skip the initial
801 	 * punctuation.
802 	 */
803 	d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
804 	return 0;
805 }
806 
807 /*
808  * Check whether the ARGV-element is a long option.
809  *
810  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
811  * that an abbreviation of the long option, just like "--fu", and not "-f" with
812  * arg "u".
813  *
814  * This distinction seems to be the most useful approach.
815  *
816  */
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)817 static int check_long_opt(int argc, char *const *argv, const char *optstring,
818 		const struct option *longopts, int *longind,
819 		int print_errors, struct custom_getopt_data *d)
820 {
821 	char *nameend;
822 	const struct option *p;
823 	const struct option *pfound = NULL;
824 	int exact = 0;
825 	int ambig = 0;
826 	int indfound = -1;
827 	int option_index;
828 
829 	for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
830 		/* Do nothing.  */ ;
831 
832 	/* Test all long options for either exact match or abbreviated matches */
833 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
834 		if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
835 			if ((unsigned int) (nameend - d->nextchar)
836 					== (unsigned int) strlen(p->name)) {
837 				/* Exact match found.  */
838 				pfound = p;
839 				indfound = option_index;
840 				exact = 1;
841 				break;
842 			} else if (pfound == NULL) {
843 				/* First nonexact match found.  */
844 				pfound = p;
845 				indfound = option_index;
846 			} else if (pfound->has_arg != p->has_arg
847 					|| pfound->flag != p->flag
848 					|| pfound->val != p->val)
849 				/* Second or later nonexact match found.  */
850 				ambig = 1;
851 		}
852 	if (ambig && !exact) {
853 		if (print_errors) {
854 			fprintf(stderr,
855 				"%s: option `%s' is ambiguous\n",
856 				argv[0], argv[d->custom_optind]);
857 		}
858 		d->nextchar += strlen(d->nextchar);
859 		d->custom_optind++;
860 		d->custom_optopt = 0;
861 		return '?';
862 	}
863 	if (pfound) {
864 		option_index = indfound;
865 		d->custom_optind++;
866 		if (*nameend) {
867 			if (pfound->has_arg != no_argument)
868 				d->custom_optarg = nameend + 1;
869 			else {
870 				if (print_errors) {
871 					if (argv[d->custom_optind - 1][1] == '-') {
872 						/* --option */
873 						fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
874 							argv[0], pfound->name);
875 					} else {
876 						/* +option or -option */
877 						fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
878 							argv[0], argv[d->custom_optind - 1][0], pfound->name);
879 					}
880 
881 				}
882 				d->nextchar += strlen(d->nextchar);
883 				d->custom_optopt = pfound->val;
884 				return '?';
885 			}
886 		} else if (pfound->has_arg == required_argument) {
887 			if (d->custom_optind < argc)
888 				d->custom_optarg = argv[d->custom_optind++];
889 			else {
890 				if (print_errors) {
891 					fprintf(stderr,
892 						"%s: option `%s' requires an argument\n",
893 						argv[0],
894 						argv[d->custom_optind - 1]);
895 				}
896 				d->nextchar += strlen(d->nextchar);
897 				d->custom_optopt = pfound->val;
898 				return optstring[0] == ':' ? ':' : '?';
899 			}
900 		}
901 		d->nextchar += strlen(d->nextchar);
902 		if (longind != NULL)
903 			*longind = option_index;
904 		if (pfound->flag) {
905 			*(pfound->flag) = pfound->val;
906 			return 0;
907 		}
908 		return pfound->val;
909 	}
910 	/*
911 	 * Can't find it as a long option.  If this is not getopt_long_only, or
912 	 * the option starts with '--' or is not a valid short option, then
913 	 * it's an error.  Otherwise interpret it as a short option.
914 	 */
915 	if (print_errors) {
916 		if (argv[d->custom_optind][1] == '-') {
917 			/* --option */
918 			fprintf(stderr,
919 				"%s: unrecognized option `--%s'\n",
920 				argv[0], d->nextchar);
921 		} else {
922 			/* +option or -option */
923 			fprintf(stderr,
924 				"%s: unrecognized option `%c%s'\n",
925 				argv[0], argv[d->custom_optind][0],
926 				d->nextchar);
927 		}
928 	}
929 	d->nextchar = (char *) "";
930 	d->custom_optind++;
931 	d->custom_optopt = 0;
932 	return '?';
933 }
934 
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)935 static int check_short_opt(int argc, char *const *argv, const char *optstring,
936 		int print_errors, struct custom_getopt_data *d)
937 {
938 	char c = *d->nextchar++;
939 	const char *temp = strchr(optstring, c);
940 
941 	/* Increment `custom_optind' when we start to process its last character.  */
942 	if (*d->nextchar == '\0')
943 		++d->custom_optind;
944 	if (!temp || c == ':') {
945 		if (print_errors)
946 			fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
947 
948 		d->custom_optopt = c;
949 		return '?';
950 	}
951 	if (temp[1] == ':') {
952 		if (temp[2] == ':') {
953 			/* This is an option that accepts an argument optionally.  */
954 			if (*d->nextchar != '\0') {
955 				d->custom_optarg = d->nextchar;
956 				d->custom_optind++;
957 			} else
958 				d->custom_optarg = NULL;
959 			d->nextchar = NULL;
960 		} else {
961 			/* This is an option that requires an argument.  */
962 			if (*d->nextchar != '\0') {
963 				d->custom_optarg = d->nextchar;
964 				/*
965 				 * If we end this ARGV-element by taking the
966 				 * rest as an arg, we must advance to the next
967 				 * element now.
968 				 */
969 				d->custom_optind++;
970 			} else if (d->custom_optind == argc) {
971 				if (print_errors) {
972 					fprintf(stderr,
973 						"%s: option requires an argument -- %c\n",
974 						argv[0], c);
975 				}
976 				d->custom_optopt = c;
977 				if (optstring[0] == ':')
978 					c = ':';
979 				else
980 					c = '?';
981 			} else
982 				/*
983 				 * We already incremented `custom_optind' once;
984 				 * increment it again when taking next ARGV-elt
985 				 * as argument.
986 				 */
987 				d->custom_optarg = argv[d->custom_optind++];
988 			d->nextchar = NULL;
989 		}
990 	}
991 	return c;
992 }
993 
994 /*
995  * Scan elements of ARGV for option characters given in OPTSTRING.
996  *
997  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
998  * then it is an option element.  The characters of this element
999  * (aside from the initial '-') are option characters.  If `getopt'
1000  * is called repeatedly, it returns successively each of the option characters
1001  * from each of the option elements.
1002  *
1003  * If `getopt' finds another option character, it returns that character,
1004  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1005  * resume the scan with the following option character or ARGV-element.
1006  *
1007  * If there are no more option characters, `getopt' returns -1.
1008  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1009  * that is not an option.  (The ARGV-elements have been permuted
1010  * so that those that are not options now come last.)
1011  *
1012  * OPTSTRING is a string containing the legitimate option characters.
1013  * If an option character is seen that is not listed in OPTSTRING,
1014  * return '?' after printing an error message.  If you set `custom_opterr' to
1015  * zero, the error message is suppressed but we still return '?'.
1016  *
1017  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1018  * so the following text in the same ARGV-element, or the text of the following
1019  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1020  * wants an optional arg; if there is text in the current ARGV-element,
1021  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1022  *
1023  * If OPTSTRING starts with `-' or `+', it requests different methods of
1024  * handling the non-option ARGV-elements.
1025  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1026  *
1027  * Long-named options begin with `--' instead of `-'.
1028  * Their names may be abbreviated as long as the abbreviation is unique
1029  * or is an exact match for some defined option.  If they have an
1030  * argument, it follows the option name in the same ARGV-element, separated
1031  * from the option name by a `=', or else the in next ARGV-element.
1032  * When `getopt' finds a long-named option, it returns 0 if that option's
1033  * `flag' field is nonzero, the value of the option's `val' field
1034  * if the `flag' field is zero.
1035  *
1036  * The elements of ARGV aren't really const, because we permute them.
1037  * But we pretend they're const in the prototype to be compatible
1038  * with other systems.
1039  *
1040  * LONGOPTS is a vector of `struct option' terminated by an
1041  * element containing a name which is zero.
1042  *
1043  * LONGIND returns the index in LONGOPT of the long-named option found.
1044  * It is only valid when a long-named option has been found by the most
1045  * recent call.
1046  *
1047  * Return the option character from OPTS just read.  Return -1 when there are
1048  * no more options.  For unrecognized options, or options missing arguments,
1049  * `custom_optopt' is set to the option letter, and '?' is returned.
1050  *
1051  * The OPTS string is a list of characters which are recognized option letters,
1052  * optionally followed by colons, specifying that that letter takes an
1053  * argument, to be placed in `custom_optarg'.
1054  *
1055  * If a letter in OPTS is followed by two colons, its argument is optional.
1056  * This behavior is specific to the GNU `getopt'.
1057  *
1058  * The argument `--' causes premature termination of argument scanning,
1059  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1060  * with `--', then non-option arguments are treated as arguments to the option
1061  * '\0'.  This behavior is specific to the GNU `getopt'.
1062  */
1063 
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1064 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1065 		const struct option *longopts, int *longind,
1066 		struct custom_getopt_data *d)
1067 {
1068 	int ret, print_errors = d->custom_opterr;
1069 
1070 	if (optstring[0] == ':')
1071 		print_errors = 0;
1072 	if (argc < 1)
1073 		return -1;
1074 	d->custom_optarg = NULL;
1075 
1076 	/*
1077 	 * This is a big difference with GNU getopt, since optind == 0
1078 	 * means initialization while here 1 means first call.
1079 	 */
1080 	if (d->custom_optind == 0 || !d->initialized) {
1081 		if (d->custom_optind == 0)
1082 			d->custom_optind = 1;	/* Don't scan ARGV[0], the program name.  */
1083 		custom_getopt_initialize(d);
1084 	}
1085 	if (d->nextchar == NULL || *d->nextchar == '\0') {
1086 		ret = shuffle_argv(argc, argv, longopts, d);
1087 		if (ret)
1088 			return ret;
1089 	}
1090 	if (longopts && (argv[d->custom_optind][1] == '-' ))
1091 		return check_long_opt(argc, argv, optstring, longopts,
1092 			longind, print_errors, d);
1093 	return check_short_opt(argc, argv, optstring, print_errors, d);
1094 }
1095 
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1096 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1097 	const struct option *longopts, int *longind)
1098 {
1099 	int result;
1100 	/* Keep a global copy of all internal members of d */
1101 	static struct custom_getopt_data d;
1102 
1103 	d.custom_optind = custom_optind;
1104 	d.custom_opterr = custom_opterr;
1105 	result = getopt_internal_r(argc, argv, optstring, longopts,
1106 		longind, &d);
1107 	custom_optind = d.custom_optind;
1108 	custom_optarg = d.custom_optarg;
1109 	custom_optopt = d.custom_optopt;
1110 	return result;
1111 }
1112 
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1113 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1114 	const struct option *long_options, int *opt_index)
1115 {
1116 	return custom_getopt_internal(argc, argv, options, long_options,
1117 		opt_index);
1118 }
1119 
1120 
1121 static char *package_name = 0;
1122 
1123 /**
1124  * @brief updates an option
1125  * @param field the generic pointer to the field to update
1126  * @param orig_field the pointer to the orig field
1127  * @param field_given the pointer to the number of occurrence of this option
1128  * @param prev_given the pointer to the number of occurrence already seen
1129  * @param value the argument for this option (if null no arg was specified)
1130  * @param possible_values the possible values for this option (if specified)
1131  * @param default_value the default value (in case the option only accepts fixed values)
1132  * @param arg_type the type of this option
1133  * @param check_ambiguity @see RNApdist_cmdline_parser_params.check_ambiguity
1134  * @param override @see RNApdist_cmdline_parser_params.override
1135  * @param no_free whether to free a possible previous value
1136  * @param multiple_option whether this is a multiple option
1137  * @param long_opt the corresponding long option
1138  * @param short_opt the corresponding short option (or '-' if none)
1139  * @param additional_error possible further error specification
1140  */
1141 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,RNApdist_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)1142 int update_arg(void *field, char **orig_field,
1143                unsigned int *field_given, unsigned int *prev_given,
1144                char *value, const char *possible_values[],
1145                const char *default_value,
1146                RNApdist_cmdline_parser_arg_type arg_type,
1147                int check_ambiguity, int override,
1148                int no_free, int multiple_option,
1149                const char *long_opt, char short_opt,
1150                const char *additional_error)
1151 {
1152   char *stop_char = 0;
1153   const char *val = value;
1154   int found;
1155   char **string_field;
1156   FIX_UNUSED (field);
1157 
1158   stop_char = 0;
1159   found = 0;
1160 
1161   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1162     {
1163       if (short_opt != '-')
1164         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1165                package_name, long_opt, short_opt,
1166                (additional_error ? additional_error : ""));
1167       else
1168         fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1169                package_name, long_opt,
1170                (additional_error ? additional_error : ""));
1171       return 1; /* failure */
1172     }
1173 
1174   if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)
1175     {
1176       if (short_opt != '-')
1177         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",
1178           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt,
1179           (additional_error ? additional_error : ""));
1180       else
1181         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",
1182           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt,
1183           (additional_error ? additional_error : ""));
1184       return 1; /* failure */
1185     }
1186 
1187   if (field_given && *field_given && ! override)
1188     return 0;
1189   if (prev_given)
1190     (*prev_given)++;
1191   if (field_given)
1192     (*field_given)++;
1193   if (possible_values)
1194     val = possible_values[found];
1195 
1196   switch(arg_type) {
1197   case ARG_FLAG:
1198     *((int *)field) = !*((int *)field);
1199     break;
1200   case ARG_INT:
1201     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1202     break;
1203   case ARG_DOUBLE:
1204     if (val) *((double *)field) = strtod (val, &stop_char);
1205     break;
1206   case ARG_STRING:
1207     if (val) {
1208       string_field = (char **)field;
1209       if (!no_free && *string_field)
1210         free (*string_field); /* free previous string */
1211       *string_field = gengetopt_strdup (val);
1212     }
1213     break;
1214   default:
1215     break;
1216   };
1217 
1218   /* check numeric conversion */
1219   switch(arg_type) {
1220   case ARG_INT:
1221   case ARG_DOUBLE:
1222     if (val && !(stop_char && *stop_char == '\0')) {
1223       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1224       return 1; /* failure */
1225     }
1226     break;
1227   default:
1228     ;
1229   };
1230 
1231   /* store the original value */
1232   switch(arg_type) {
1233   case ARG_NO:
1234   case ARG_FLAG:
1235     break;
1236   default:
1237     if (value && orig_field) {
1238       if (no_free) {
1239         *orig_field = value;
1240       } else {
1241         if (*orig_field)
1242           free (*orig_field); /* free previous string */
1243         *orig_field = gengetopt_strdup (value);
1244       }
1245     }
1246   };
1247 
1248   return 0; /* OK */
1249 }
1250 
1251 
1252 int
RNApdist_cmdline_parser_internal(int argc,char ** argv,struct RNApdist_args_info * args_info,struct RNApdist_cmdline_parser_params * params,const char * additional_error)1253 RNApdist_cmdline_parser_internal (
1254   int argc, char **argv, struct RNApdist_args_info *args_info,
1255                         struct RNApdist_cmdline_parser_params *params, const char *additional_error)
1256 {
1257   int c;	/* Character of the parsed option.  */
1258 
1259   int error_occurred = 0;
1260   struct RNApdist_args_info local_args_info;
1261 
1262   int override;
1263   int initialize;
1264   int check_required;
1265   int check_ambiguity;
1266 
1267   char *optarg;
1268   int optind;
1269   int opterr;
1270   int optopt;
1271 
1272   package_name = argv[0];
1273 
1274   /* TODO: Why is this here? It is not used anywhere. */
1275   override = params->override;
1276   FIX_UNUSED(override);
1277 
1278   initialize = params->initialize;
1279   check_required = params->check_required;
1280 
1281   /* TODO: Why is this here? It is not used anywhere. */
1282   check_ambiguity = params->check_ambiguity;
1283   FIX_UNUSED(check_ambiguity);
1284 
1285   if (initialize)
1286     RNApdist_cmdline_parser_init (args_info);
1287 
1288   RNApdist_cmdline_parser_init (&local_args_info);
1289 
1290   optarg = 0;
1291   optind = 0;
1292   opterr = params->print_errors;
1293   optopt = '?';
1294 
1295   while (1)
1296     {
1297       int option_index = 0;
1298 
1299       static struct option long_options[] = {
1300         { "help",	0, NULL, 'h' },
1301         { "detailed-help",	0, NULL, 0 },
1302         { "full-help",	0, NULL, 0 },
1303         { "version",	0, NULL, 'V' },
1304         { "noconv",	0, NULL, 0 },
1305         { "compare",	1, NULL, 'X' },
1306         { "backtrack",	2, NULL, 'B' },
1307         { "temp",	1, NULL, 'T' },
1308         { "noTetra",	0, NULL, '4' },
1309         { "dangles",	1, NULL, 'd' },
1310         { "noLP",	0, NULL, 0 },
1311         { "noGU",	0, NULL, 0 },
1312         { "noClosingGU",	0, NULL, 0 },
1313         { "paramFile",	1, NULL, 'P' },
1314         { "nsp",	1, NULL, 0 },
1315         { "energyModel",	1, NULL, 'e' },
1316         { 0,  0, 0, 0 }
1317       };
1318 
1319       custom_optarg = optarg;
1320       custom_optind = optind;
1321       custom_opterr = opterr;
1322       custom_optopt = optopt;
1323 
1324       c = custom_getopt_long (argc, argv, "hVX:B::T:4d:P:e:", long_options, &option_index);
1325 
1326       optarg = custom_optarg;
1327       optind = custom_optind;
1328       opterr = custom_opterr;
1329       optopt = custom_optopt;
1330 
1331       if (c == -1) break;	/* Exit from `while (1)' loop.  */
1332 
1333       switch (c)
1334         {
1335         case 'h':	/* Print help and exit.  */
1336           RNApdist_cmdline_parser_print_help ();
1337           RNApdist_cmdline_parser_free (&local_args_info);
1338           exit (EXIT_SUCCESS);
1339 
1340         case 'V':	/* Print version and exit.  */
1341           RNApdist_cmdline_parser_print_version ();
1342           RNApdist_cmdline_parser_free (&local_args_info);
1343           exit (EXIT_SUCCESS);
1344 
1345         case 'X':	/* Specify the comparison directive.
1346 .  */
1347 
1348 
1349           if (update_arg( (void *)&(args_info->compare_arg),
1350                &(args_info->compare_orig), &(args_info->compare_given),
1351               &(local_args_info.compare_given), optarg, 0, "p", ARG_STRING,
1352               check_ambiguity, override, 0, 0,
1353               "compare", 'X',
1354               additional_error))
1355             goto failure;
1356 
1357           break;
1358         case 'B':	/* Print an \"alignment\" with gaps of the profiles. The aligned structures are written to <filename>, if specified.
1359 .  */
1360 
1361 
1362           if (update_arg( (void *)&(args_info->backtrack_arg),
1363                &(args_info->backtrack_orig), &(args_info->backtrack_given),
1364               &(local_args_info.backtrack_given), optarg, 0, "none", ARG_STRING,
1365               check_ambiguity, override, 0, 0,
1366               "backtrack", 'B',
1367               additional_error))
1368             goto failure;
1369 
1370           break;
1371         case 'T':	/* Rescale energy parameters to a temperature of temp C. Default is 37C.
1372 
1373 .  */
1374 
1375 
1376           if (update_arg( (void *)&(args_info->temp_arg),
1377                &(args_info->temp_orig), &(args_info->temp_given),
1378               &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
1379               check_ambiguity, override, 0, 0,
1380               "temp", 'T',
1381               additional_error))
1382             goto failure;
1383 
1384           break;
1385         case '4':	/* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins. Mostly for testing.
1386 
1387 .  */
1388 
1389 
1390           if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
1391               &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
1392               check_ambiguity, override, 1, 0, "noTetra", '4',
1393               additional_error))
1394             goto failure;
1395 
1396           break;
1397         case 'd':	/* set energy model for treatment of dangling bases
1398 
1399 .  */
1400 
1401 
1402           if (update_arg( (void *)&(args_info->dangles_arg),
1403                &(args_info->dangles_orig), &(args_info->dangles_given),
1404               &(local_args_info.dangles_given), optarg, RNApdist_cmdline_parser_dangles_values, "2", ARG_INT,
1405               check_ambiguity, override, 0, 0,
1406               "dangles", 'd',
1407               additional_error))
1408             goto failure;
1409 
1410           break;
1411         case 'P':	/* Read energy parameters from paramfile, instead of using the default parameter set.
1412 .  */
1413 
1414 
1415           if (update_arg( (void *)&(args_info->paramFile_arg),
1416                &(args_info->paramFile_orig), &(args_info->paramFile_given),
1417               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1418               check_ambiguity, override, 0, 0,
1419               "paramFile", 'P',
1420               additional_error))
1421             goto failure;
1422 
1423           break;
1424         case 'e':	/* Rarely used option to fold sequences from the artificial ABCD... alphabet, where A pairs B, C-D etc.  Use the energy parameters for GC (-e 1) or AU (-e 2) pairs.
1425 
1426 .  */
1427 
1428 
1429           if (update_arg( (void *)&(args_info->energyModel_arg),
1430                &(args_info->energyModel_orig), &(args_info->energyModel_given),
1431               &(local_args_info.energyModel_given), optarg, 0, 0, ARG_INT,
1432               check_ambiguity, override, 0, 0,
1433               "energyModel", 'e',
1434               additional_error))
1435             goto failure;
1436 
1437           break;
1438 
1439         case 0:	/* Long option with no short option */
1440           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1441             RNApdist_cmdline_parser_print_detailed_help ();
1442             RNApdist_cmdline_parser_free (&local_args_info);
1443             exit (EXIT_SUCCESS);
1444           }
1445 
1446           if (strcmp (long_options[option_index].name, "full-help") == 0) {
1447             RNApdist_cmdline_parser_print_full_help ();
1448             RNApdist_cmdline_parser_free (&local_args_info);
1449             exit (EXIT_SUCCESS);
1450           }
1451 
1452           /* Do not automatically substitude nucleotide \"T\" with \"U\"
1453 
1454 .  */
1455           if (strcmp (long_options[option_index].name, "noconv") == 0)
1456           {
1457 
1458 
1459             if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
1460                 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
1461                 check_ambiguity, override, 1, 0, "noconv", '-',
1462                 additional_error))
1463               goto failure;
1464 
1465           }
1466           /* Produce structures without lonely pairs (helices of length 1).
1467 .  */
1468           else if (strcmp (long_options[option_index].name, "noLP") == 0)
1469           {
1470 
1471 
1472             if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
1473                 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
1474                 check_ambiguity, override, 1, 0, "noLP", '-',
1475                 additional_error))
1476               goto failure;
1477 
1478           }
1479           /* Do not allow GU pairs
1480 
1481 .  */
1482           else if (strcmp (long_options[option_index].name, "noGU") == 0)
1483           {
1484 
1485 
1486             if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
1487                 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
1488                 check_ambiguity, override, 1, 0, "noGU", '-',
1489                 additional_error))
1490               goto failure;
1491 
1492           }
1493           /* Do not allow GU pairs at the end of helices
1494 
1495 .  */
1496           else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
1497           {
1498 
1499 
1500             if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
1501                 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
1502                 check_ambiguity, override, 1, 0, "noClosingGU", '-',
1503                 additional_error))
1504               goto failure;
1505 
1506           }
1507           /* Allow other pairs in addition to the usual AU,GC,and GU pairs.
1508 .  */
1509           else if (strcmp (long_options[option_index].name, "nsp") == 0)
1510           {
1511 
1512 
1513             if (update_arg( (void *)&(args_info->nsp_arg),
1514                  &(args_info->nsp_orig), &(args_info->nsp_given),
1515                 &(local_args_info.nsp_given), optarg, 0, 0, ARG_STRING,
1516                 check_ambiguity, override, 0, 0,
1517                 "nsp", '-',
1518                 additional_error))
1519               goto failure;
1520 
1521           }
1522 
1523           break;
1524         case '?':	/* Invalid option.  */
1525           /* `getopt_long' already printed an error message.  */
1526           goto failure;
1527 
1528         default:	/* bug: option not considered.  */
1529           fprintf (stderr, "%s: option unknown: %c%s\n", RNAPDIST_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1530           abort ();
1531         } /* switch */
1532     } /* while */
1533 
1534 
1535 
1536 	FIX_UNUSED(check_required);
1537 
1538   RNApdist_cmdline_parser_release (&local_args_info);
1539 
1540   if ( error_occurred )
1541     return (EXIT_FAILURE);
1542 
1543   return 0;
1544 
1545 failure:
1546 
1547   RNApdist_cmdline_parser_release (&local_args_info);
1548   return (EXIT_FAILURE);
1549 }
1550 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
1551