1 /*
2   File autogenerated by gengetopt version 2.23
3   generated with the following command:
4   /usr/bin/gengetopt -i RNA2Dfold.ggo --file-name=RNA2Dfold_cmdl --include-getopt --default-optional --func-name=RNA2Dfold_cmdline_parser --arg-struct-name=RNA2Dfold_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 "RNA2Dfold_cmdl.h"
26 
27 const char *RNA2Dfold_args_info_purpose = "Compute MFE structure, partition function and representative sample structures\nof k,l neighborhoods";
28 
29 const char *RNA2Dfold_args_info_usage = "Usage: RNA2Dfold [OPTION]...";
30 
31 const char *RNA2Dfold_args_info_versiontext = "";
32 
33 const char *RNA2Dfold_args_info_description = "The program partitions the secondary structure space into (basepair)distance\nclasses according to two fixed reference structures. It expects a sequence and\ntwo secondary structures in dot-bracket notation as its inputs. For each\ndistance class, the MFE representative, Boltzmann probabilities and Gibbs free\nenergy is computed. Additionally, a stochastic backtracking routine allows one\nto produce samples of representative suboptimal secondary structures from each\npartition\n\n";
34 
35 const char *RNA2Dfold_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   "  -V, --version               Print version and exit",
39   "\nGeneral Options:",
40   "  Below are command line options which alter the general behavior of this\n  program\n\n",
41   "      --noconv                Do not automatically substitude nucleotide \"T\"\n                                with \"U\"\n\n                                  (default=off)",
42   "  -j, --numThreads=INT        Set the number of threads used for calculations\n                                (only available when compiled with OpenMP\n                                support)\n\n",
43   "\nAlgorithms:",
44   "  -p, --partfunc              calculate partition function and thus, Boltzmann\n                                probabilities and Gibbs free energy\n\n                                  (default=off)",
45   "      --stochBT=INT           backtrack a certain number of Boltzmann samples\n                                from the appropriate k,l neighborhood(s)\n\n",
46   "      --neighborhood=<k>:<l>  backtrack structures from certain\n                                k,l-neighborhood only, can be specified\n                                multiple times (<k>:<l>,<m>:<n>,...)\n\n",
47   "  -S, --pfScale=DOUBLE        scaling factor for pf to avoid overflows\n\n",
48   "      --noBT                  do not backtrack structures, calculate energy\n                                contributions only\n\n                                  (default=off)",
49   "  -c, --circ                  Assume a circular (instead of linear) RNA\n                                molecule.\n\n                                  (default=off)",
50   "\nModel Details:",
51   "  -T, --temp=DOUBLE           Rescale energy parameters to a temperature of\n                                temp C. Default is 37C.\n\n",
52   "  -K, --maxDist1=INT          maximum distance to first reference structure",
53   "  If this value is set all structures that exhibit a basepair distance greater\n  than maxDist1 will be thrown into a distance class denoted by K=L=-1\n\n",
54   "  -L, --maxDist2=INT          maximum distance to second reference structure",
55   "  If this value is set all structures that exhibit a basepair distance greater\n  than maxDist1 will be thrown into a distance class denoted by K=L=-1\n\n",
56   "  -4, --noTetra               Do not include special tabulated stabilizing\n                                energies for tri-, tetra- and hexaloop\n                                hairpins. Mostly for testing.\n\n                                  (default=off)",
57   "  -P, --paramFile=paramfile   Read energy parameters from paramfile, instead of\n                                using the default parameter set.\n",
58   "  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 an input file.\n\n",
59   "  -d, --dangles=INT           How to treat \"dangling end\" energies for bases\n                                adjacent to helices in free ends and\n                                multi-loops\n                                  (possible values=\"0\", \"2\" default=`2')",
60   "  \n  With -d2 dangling energies will be added for the bases adjacent to a helix on\n  both sides\n   in any case.\n  The option -d0 ignores dangling ends altogether (mostly for debugging).\n\n",
61   "      --noGU                  Do not allow GU pairs\n\n                                  (default=off)",
62   "      --noClosingGU           Do not allow GU pairs at the end of helices\n\n                                  (default=off)",
63   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n\n",
64     0
65 };
66 
67 static void
init_help_array(void)68 init_help_array(void)
69 {
70   RNA2Dfold_args_info_help[0] = RNA2Dfold_args_info_detailed_help[0];
71   RNA2Dfold_args_info_help[1] = RNA2Dfold_args_info_detailed_help[1];
72   RNA2Dfold_args_info_help[2] = RNA2Dfold_args_info_detailed_help[2];
73   RNA2Dfold_args_info_help[3] = RNA2Dfold_args_info_detailed_help[3];
74   RNA2Dfold_args_info_help[4] = RNA2Dfold_args_info_detailed_help[4];
75   RNA2Dfold_args_info_help[5] = RNA2Dfold_args_info_detailed_help[5];
76   RNA2Dfold_args_info_help[6] = RNA2Dfold_args_info_detailed_help[6];
77   RNA2Dfold_args_info_help[7] = RNA2Dfold_args_info_detailed_help[7];
78   RNA2Dfold_args_info_help[8] = RNA2Dfold_args_info_detailed_help[8];
79   RNA2Dfold_args_info_help[9] = RNA2Dfold_args_info_detailed_help[9];
80   RNA2Dfold_args_info_help[10] = RNA2Dfold_args_info_detailed_help[10];
81   RNA2Dfold_args_info_help[11] = RNA2Dfold_args_info_detailed_help[11];
82   RNA2Dfold_args_info_help[12] = RNA2Dfold_args_info_detailed_help[12];
83   RNA2Dfold_args_info_help[13] = RNA2Dfold_args_info_detailed_help[13];
84   RNA2Dfold_args_info_help[14] = RNA2Dfold_args_info_detailed_help[14];
85   RNA2Dfold_args_info_help[15] = RNA2Dfold_args_info_detailed_help[15];
86   RNA2Dfold_args_info_help[16] = RNA2Dfold_args_info_detailed_help[16];
87   RNA2Dfold_args_info_help[17] = RNA2Dfold_args_info_detailed_help[18];
88   RNA2Dfold_args_info_help[18] = RNA2Dfold_args_info_detailed_help[20];
89   RNA2Dfold_args_info_help[19] = RNA2Dfold_args_info_detailed_help[21];
90   RNA2Dfold_args_info_help[20] = RNA2Dfold_args_info_detailed_help[23];
91   RNA2Dfold_args_info_help[21] = RNA2Dfold_args_info_detailed_help[25];
92   RNA2Dfold_args_info_help[22] = RNA2Dfold_args_info_detailed_help[26];
93   RNA2Dfold_args_info_help[23] = RNA2Dfold_args_info_detailed_help[27];
94   RNA2Dfold_args_info_help[24] = 0;
95 
96 }
97 
98 const char *RNA2Dfold_args_info_help[25];
99 
100 typedef enum {ARG_NO
101   , ARG_FLAG
102   , ARG_STRING
103   , ARG_INT
104   , ARG_DOUBLE
105 } RNA2Dfold_cmdline_parser_arg_type;
106 
107 static
108 void clear_given (struct RNA2Dfold_args_info *args_info);
109 static
110 void clear_args (struct RNA2Dfold_args_info *args_info);
111 
112 static int
113 RNA2Dfold_cmdline_parser_internal (int argc, char **argv, struct RNA2Dfold_args_info *args_info,
114                         struct RNA2Dfold_cmdline_parser_params *params, const char *additional_error);
115 
116 static int
117 RNA2Dfold_cmdline_parser_required2 (struct RNA2Dfold_args_info *args_info, const char *prog_name, const char *additional_error);
118 
119 const char *RNA2Dfold_cmdline_parser_dangles_values[] = {"0", "2", 0}; /*< Possible values for dangles. */
120 
121 static char *
122 gengetopt_strdup (const char *s);
123 
124 static
clear_given(struct RNA2Dfold_args_info * args_info)125 void clear_given (struct RNA2Dfold_args_info *args_info)
126 {
127   args_info->help_given = 0 ;
128   args_info->detailed_help_given = 0 ;
129   args_info->version_given = 0 ;
130   args_info->noconv_given = 0 ;
131   args_info->numThreads_given = 0 ;
132   args_info->partfunc_given = 0 ;
133   args_info->stochBT_given = 0 ;
134   args_info->neighborhood_given = 0 ;
135   args_info->pfScale_given = 0 ;
136   args_info->noBT_given = 0 ;
137   args_info->circ_given = 0 ;
138   args_info->temp_given = 0 ;
139   args_info->maxDist1_given = 0 ;
140   args_info->maxDist2_given = 0 ;
141   args_info->noTetra_given = 0 ;
142   args_info->paramFile_given = 0 ;
143   args_info->dangles_given = 0 ;
144   args_info->noGU_given = 0 ;
145   args_info->noClosingGU_given = 0 ;
146 }
147 
148 static
clear_args(struct RNA2Dfold_args_info * args_info)149 void clear_args (struct RNA2Dfold_args_info *args_info)
150 {
151   FIX_UNUSED (args_info);
152   args_info->noconv_flag = 0;
153   args_info->numThreads_orig = NULL;
154   args_info->partfunc_flag = 0;
155   args_info->stochBT_orig = NULL;
156   args_info->neighborhood_arg = NULL;
157   args_info->neighborhood_orig = NULL;
158   args_info->pfScale_orig = NULL;
159   args_info->noBT_flag = 0;
160   args_info->circ_flag = 0;
161   args_info->temp_orig = NULL;
162   args_info->maxDist1_orig = NULL;
163   args_info->maxDist2_orig = NULL;
164   args_info->noTetra_flag = 0;
165   args_info->paramFile_arg = NULL;
166   args_info->paramFile_orig = NULL;
167   args_info->dangles_arg = 2;
168   args_info->dangles_orig = NULL;
169   args_info->noGU_flag = 0;
170   args_info->noClosingGU_flag = 0;
171 
172 }
173 
174 static
init_args_info(struct RNA2Dfold_args_info * args_info)175 void init_args_info(struct RNA2Dfold_args_info *args_info)
176 {
177 
178   init_help_array();
179   args_info->help_help = RNA2Dfold_args_info_detailed_help[0] ;
180   args_info->detailed_help_help = RNA2Dfold_args_info_detailed_help[1] ;
181   args_info->version_help = RNA2Dfold_args_info_detailed_help[2] ;
182   args_info->noconv_help = RNA2Dfold_args_info_detailed_help[5] ;
183   args_info->numThreads_help = RNA2Dfold_args_info_detailed_help[6] ;
184   args_info->partfunc_help = RNA2Dfold_args_info_detailed_help[8] ;
185   args_info->stochBT_help = RNA2Dfold_args_info_detailed_help[9] ;
186   args_info->neighborhood_help = RNA2Dfold_args_info_detailed_help[10] ;
187   args_info->neighborhood_min = 0;
188   args_info->neighborhood_max = 0;
189   args_info->pfScale_help = RNA2Dfold_args_info_detailed_help[11] ;
190   args_info->noBT_help = RNA2Dfold_args_info_detailed_help[12] ;
191   args_info->circ_help = RNA2Dfold_args_info_detailed_help[13] ;
192   args_info->temp_help = RNA2Dfold_args_info_detailed_help[15] ;
193   args_info->maxDist1_help = RNA2Dfold_args_info_detailed_help[16] ;
194   args_info->maxDist2_help = RNA2Dfold_args_info_detailed_help[18] ;
195   args_info->noTetra_help = RNA2Dfold_args_info_detailed_help[20] ;
196   args_info->paramFile_help = RNA2Dfold_args_info_detailed_help[21] ;
197   args_info->dangles_help = RNA2Dfold_args_info_detailed_help[23] ;
198   args_info->noGU_help = RNA2Dfold_args_info_detailed_help[25] ;
199   args_info->noClosingGU_help = RNA2Dfold_args_info_detailed_help[26] ;
200 
201 }
202 
203 void
RNA2Dfold_cmdline_parser_print_version(void)204 RNA2Dfold_cmdline_parser_print_version (void)
205 {
206   printf ("%s %s\n",
207      (strlen(RNA2DFOLD_CMDLINE_PARSER_PACKAGE_NAME) ? RNA2DFOLD_CMDLINE_PARSER_PACKAGE_NAME : RNA2DFOLD_CMDLINE_PARSER_PACKAGE),
208      RNA2DFOLD_CMDLINE_PARSER_VERSION);
209 
210   if (strlen(RNA2Dfold_args_info_versiontext) > 0)
211     printf("\n%s\n", RNA2Dfold_args_info_versiontext);
212 }
213 
print_help_common(void)214 static void print_help_common(void)
215 {
216 	size_t len_purpose = strlen(RNA2Dfold_args_info_purpose);
217 	size_t len_usage = strlen(RNA2Dfold_args_info_usage);
218 
219 	if (len_usage > 0) {
220 		printf("%s\n", RNA2Dfold_args_info_usage);
221 	}
222 	if (len_purpose > 0) {
223 		printf("%s\n", RNA2Dfold_args_info_purpose);
224 	}
225 
226 	if (len_usage || len_purpose) {
227 		printf("\n");
228 	}
229 
230 	if (strlen(RNA2Dfold_args_info_description) > 0) {
231 		printf("%s\n\n", RNA2Dfold_args_info_description);
232 	}
233 }
234 
235 void
RNA2Dfold_cmdline_parser_print_help(void)236 RNA2Dfold_cmdline_parser_print_help (void)
237 {
238   int i = 0;
239   print_help_common();
240   while (RNA2Dfold_args_info_help[i])
241     printf("%s\n", RNA2Dfold_args_info_help[i++]);
242 }
243 
244 void
RNA2Dfold_cmdline_parser_print_detailed_help(void)245 RNA2Dfold_cmdline_parser_print_detailed_help (void)
246 {
247   int i = 0;
248   print_help_common();
249   while (RNA2Dfold_args_info_detailed_help[i])
250     printf("%s\n", RNA2Dfold_args_info_detailed_help[i++]);
251 }
252 
253 void
RNA2Dfold_cmdline_parser_init(struct RNA2Dfold_args_info * args_info)254 RNA2Dfold_cmdline_parser_init (struct RNA2Dfold_args_info *args_info)
255 {
256   clear_given (args_info);
257   clear_args (args_info);
258   init_args_info (args_info);
259 }
260 
261 void
RNA2Dfold_cmdline_parser_params_init(struct RNA2Dfold_cmdline_parser_params * params)262 RNA2Dfold_cmdline_parser_params_init(struct RNA2Dfold_cmdline_parser_params *params)
263 {
264   if (params)
265     {
266       params->override = 0;
267       params->initialize = 1;
268       params->check_required = 1;
269       params->check_ambiguity = 0;
270       params->print_errors = 1;
271     }
272 }
273 
274 struct RNA2Dfold_cmdline_parser_params *
RNA2Dfold_cmdline_parser_params_create(void)275 RNA2Dfold_cmdline_parser_params_create(void)
276 {
277   struct RNA2Dfold_cmdline_parser_params *params =
278     (struct RNA2Dfold_cmdline_parser_params *)malloc(sizeof(struct RNA2Dfold_cmdline_parser_params));
279   RNA2Dfold_cmdline_parser_params_init(params);
280   return params;
281 }
282 
283 static void
free_string_field(char ** s)284 free_string_field (char **s)
285 {
286   if (*s)
287     {
288       free (*s);
289       *s = 0;
290     }
291 }
292 
293 /** @brief generic value variable */
294 union generic_value {
295     int int_arg;
296     double double_arg;
297     char *string_arg;
298     const char *default_string_arg;
299 };
300 
301 /** @brief holds temporary values for multiple options */
302 struct generic_list
303 {
304   union generic_value arg;
305   char *orig;
306   struct generic_list *next;
307 };
308 
309 /**
310  * @brief add a node at the head of the list
311  */
add_node(struct generic_list ** list)312 static void add_node(struct generic_list **list) {
313   struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
314   new_node->next = *list;
315   *list = new_node;
316   new_node->arg.string_arg = 0;
317   new_node->orig = 0;
318 }
319 
320 
321 static void
free_multiple_string_field(unsigned int len,char *** arg,char *** orig)322 free_multiple_string_field(unsigned int len, char ***arg, char ***orig)
323 {
324   unsigned int i;
325   if (*arg) {
326     for (i = 0; i < len; ++i)
327       {
328         free_string_field(&((*arg)[i]));
329         free_string_field(&((*orig)[i]));
330       }
331     free_string_field(&((*arg)[0])); /* free default string */
332 
333     free (*arg);
334     *arg = 0;
335     free (*orig);
336     *orig = 0;
337   }
338 }
339 
340 static void
RNA2Dfold_cmdline_parser_release(struct RNA2Dfold_args_info * args_info)341 RNA2Dfold_cmdline_parser_release (struct RNA2Dfold_args_info *args_info)
342 {
343 
344   free_string_field (&(args_info->numThreads_orig));
345   free_string_field (&(args_info->stochBT_orig));
346   free_multiple_string_field (args_info->neighborhood_given, &(args_info->neighborhood_arg), &(args_info->neighborhood_orig));
347   free_string_field (&(args_info->pfScale_orig));
348   free_string_field (&(args_info->temp_orig));
349   free_string_field (&(args_info->maxDist1_orig));
350   free_string_field (&(args_info->maxDist2_orig));
351   free_string_field (&(args_info->paramFile_arg));
352   free_string_field (&(args_info->paramFile_orig));
353   free_string_field (&(args_info->dangles_orig));
354 
355 
356 
357   clear_given (args_info);
358 }
359 
360 /**
361  * @param val the value to check
362  * @param values the possible values
363  * @return the index of the matched value:
364  * -1 if no value matched,
365  * -2 if more than one value has matched
366  */
367 static int
check_possible_values(const char * val,const char * values[])368 check_possible_values(const char *val, const char *values[])
369 {
370   int i, found, last;
371   size_t len;
372 
373   if (!val)   /* otherwise strlen() crashes below */
374     return -1; /* -1 means no argument for the option */
375 
376   found = last = 0;
377 
378   for (i = 0, len = strlen(val); values[i]; ++i)
379     {
380       if (strncmp(val, values[i], len) == 0)
381         {
382           ++found;
383           last = i;
384           if (strlen(values[i]) == len)
385             return i; /* exact macth no need to check more */
386         }
387     }
388 
389   if (found == 1) /* one match: OK */
390     return last;
391 
392   return (found ? -2 : -1); /* return many values or none matched */
393 }
394 
395 
396 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])397 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
398 {
399   int found = -1;
400   if (arg) {
401     if (values) {
402       found = check_possible_values(arg, values);
403     }
404     if (found >= 0)
405       fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]);
406     else
407       fprintf(outfile, "%s=\"%s\"\n", opt, arg);
408   } else {
409     fprintf(outfile, "%s\n", opt);
410   }
411 }
412 
413 static void
write_multiple_into_file(FILE * outfile,int len,const char * opt,char ** arg,const char * values[])414 write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])
415 {
416   int i;
417 
418   for (i = 0; i < len; ++i)
419     write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
420 }
421 
422 int
RNA2Dfold_cmdline_parser_dump(FILE * outfile,struct RNA2Dfold_args_info * args_info)423 RNA2Dfold_cmdline_parser_dump(FILE *outfile, struct RNA2Dfold_args_info *args_info)
424 {
425   int i = 0;
426 
427   if (!outfile)
428     {
429       fprintf (stderr, "%s: cannot dump options to stream\n", RNA2DFOLD_CMDLINE_PARSER_PACKAGE);
430       return EXIT_FAILURE;
431     }
432 
433   if (args_info->help_given)
434     write_into_file(outfile, "help", 0, 0 );
435   if (args_info->detailed_help_given)
436     write_into_file(outfile, "detailed-help", 0, 0 );
437   if (args_info->version_given)
438     write_into_file(outfile, "version", 0, 0 );
439   if (args_info->noconv_given)
440     write_into_file(outfile, "noconv", 0, 0 );
441   if (args_info->numThreads_given)
442     write_into_file(outfile, "numThreads", args_info->numThreads_orig, 0);
443   if (args_info->partfunc_given)
444     write_into_file(outfile, "partfunc", 0, 0 );
445   if (args_info->stochBT_given)
446     write_into_file(outfile, "stochBT", args_info->stochBT_orig, 0);
447   write_multiple_into_file(outfile, args_info->neighborhood_given, "neighborhood", args_info->neighborhood_orig, 0);
448   if (args_info->pfScale_given)
449     write_into_file(outfile, "pfScale", args_info->pfScale_orig, 0);
450   if (args_info->noBT_given)
451     write_into_file(outfile, "noBT", 0, 0 );
452   if (args_info->circ_given)
453     write_into_file(outfile, "circ", 0, 0 );
454   if (args_info->temp_given)
455     write_into_file(outfile, "temp", args_info->temp_orig, 0);
456   if (args_info->maxDist1_given)
457     write_into_file(outfile, "maxDist1", args_info->maxDist1_orig, 0);
458   if (args_info->maxDist2_given)
459     write_into_file(outfile, "maxDist2", args_info->maxDist2_orig, 0);
460   if (args_info->noTetra_given)
461     write_into_file(outfile, "noTetra", 0, 0 );
462   if (args_info->paramFile_given)
463     write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
464   if (args_info->dangles_given)
465     write_into_file(outfile, "dangles", args_info->dangles_orig, RNA2Dfold_cmdline_parser_dangles_values);
466   if (args_info->noGU_given)
467     write_into_file(outfile, "noGU", 0, 0 );
468   if (args_info->noClosingGU_given)
469     write_into_file(outfile, "noClosingGU", 0, 0 );
470 
471 
472   i = EXIT_SUCCESS;
473   return i;
474 }
475 
476 int
RNA2Dfold_cmdline_parser_file_save(const char * filename,struct RNA2Dfold_args_info * args_info)477 RNA2Dfold_cmdline_parser_file_save(const char *filename, struct RNA2Dfold_args_info *args_info)
478 {
479   FILE *outfile;
480   int i = 0;
481 
482   outfile = fopen(filename, "w");
483 
484   if (!outfile)
485     {
486       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNA2DFOLD_CMDLINE_PARSER_PACKAGE, filename);
487       return EXIT_FAILURE;
488     }
489 
490   i = RNA2Dfold_cmdline_parser_dump(outfile, args_info);
491   fclose (outfile);
492 
493   return i;
494 }
495 
496 void
RNA2Dfold_cmdline_parser_free(struct RNA2Dfold_args_info * args_info)497 RNA2Dfold_cmdline_parser_free (struct RNA2Dfold_args_info *args_info)
498 {
499   RNA2Dfold_cmdline_parser_release (args_info);
500 }
501 
502 /** @brief replacement of strdup, which is not standard */
503 char *
gengetopt_strdup(const char * s)504 gengetopt_strdup (const char *s)
505 {
506   char *result = 0;
507   if (!s)
508     return result;
509 
510   result = (char*)malloc(strlen(s) + 1);
511   if (result == (char*)0)
512     return (char*)0;
513   strcpy(result, s);
514   return result;
515 }
516 
517 static char *
get_multiple_arg_token(const char * arg)518 get_multiple_arg_token(const char *arg)
519 {
520   const char *tok;
521   char *ret;
522   size_t len, num_of_escape, i, j;
523 
524   if (!arg)
525     return 0;
526 
527   tok = strchr (arg, ',');
528   num_of_escape = 0;
529 
530   /* make sure it is not escaped */
531   while (tok)
532     {
533       if (*(tok-1) == '\\')
534         {
535           /* find the next one */
536           tok = strchr (tok+1, ',');
537           ++num_of_escape;
538         }
539       else
540         break;
541     }
542 
543   if (tok)
544     len = (size_t)(tok - arg + 1);
545   else
546     len = strlen (arg) + 1;
547 
548   len -= num_of_escape;
549 
550   ret = (char *) malloc (len);
551 
552   i = 0;
553   j = 0;
554   while (arg[i] && (j < len-1))
555     {
556       if (arg[i] == '\\' &&
557 	  arg[ i + 1 ] &&
558 	  arg[ i + 1 ] == ',')
559         ++i;
560 
561       ret[j++] = arg[i++];
562     }
563 
564   ret[len-1] = '\0';
565 
566   return ret;
567 }
568 
569 static const char *
get_multiple_arg_token_next(const char * arg)570 get_multiple_arg_token_next(const char *arg)
571 {
572   const char *tok;
573 
574   if (!arg)
575     return 0;
576 
577   tok = strchr (arg, ',');
578 
579   /* make sure it is not escaped */
580   while (tok)
581     {
582       if (*(tok-1) == '\\')
583         {
584           /* find the next one */
585           tok = strchr (tok+1, ',');
586         }
587       else
588         break;
589     }
590 
591   if (! tok || strlen(tok) == 1)
592     return 0;
593 
594   return tok+1;
595 }
596 
597 static int
598 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);
599 
600 int
check_multiple_option_occurrences(const char * prog_name,unsigned int option_given,unsigned int min,unsigned int max,const char * option_desc)601 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)
602 {
603   int error_occurred = 0;
604 
605   if (option_given && (min > 0 || max > 0))
606     {
607       if (min > 0 && max > 0)
608         {
609           if (min == max)
610             {
611               /* specific occurrences */
612               if (option_given != (unsigned int) min)
613                 {
614                   fprintf (stderr, "%s: %s option occurrences must be %d\n",
615                     prog_name, option_desc, min);
616                   error_occurred = 1;
617                 }
618             }
619           else if (option_given < (unsigned int) min
620                 || option_given > (unsigned int) max)
621             {
622               /* range occurrences */
623               fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
624                 prog_name, option_desc, min, max);
625               error_occurred = 1;
626             }
627         }
628       else if (min > 0)
629         {
630           /* at least check */
631           if (option_given < min)
632             {
633               fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
634                 prog_name, option_desc, min);
635               error_occurred = 1;
636             }
637         }
638       else if (max > 0)
639         {
640           /* at most check */
641           if (option_given > max)
642             {
643               fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
644                 prog_name, option_desc, max);
645               error_occurred = 1;
646             }
647         }
648     }
649 
650   return error_occurred;
651 }
652 int
RNA2Dfold_cmdline_parser(int argc,char ** argv,struct RNA2Dfold_args_info * args_info)653 RNA2Dfold_cmdline_parser (int argc, char **argv, struct RNA2Dfold_args_info *args_info)
654 {
655   return RNA2Dfold_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
656 }
657 
658 int
RNA2Dfold_cmdline_parser_ext(int argc,char ** argv,struct RNA2Dfold_args_info * args_info,struct RNA2Dfold_cmdline_parser_params * params)659 RNA2Dfold_cmdline_parser_ext (int argc, char **argv, struct RNA2Dfold_args_info *args_info,
660                    struct RNA2Dfold_cmdline_parser_params *params)
661 {
662   int result;
663   result = RNA2Dfold_cmdline_parser_internal (argc, argv, args_info, params, 0);
664 
665   if (result == EXIT_FAILURE)
666     {
667       RNA2Dfold_cmdline_parser_free (args_info);
668       exit (EXIT_FAILURE);
669     }
670 
671   return result;
672 }
673 
674 int
RNA2Dfold_cmdline_parser2(int argc,char ** argv,struct RNA2Dfold_args_info * args_info,int override,int initialize,int check_required)675 RNA2Dfold_cmdline_parser2 (int argc, char **argv, struct RNA2Dfold_args_info *args_info, int override, int initialize, int check_required)
676 {
677   int result;
678   struct RNA2Dfold_cmdline_parser_params params;
679 
680   params.override = override;
681   params.initialize = initialize;
682   params.check_required = check_required;
683   params.check_ambiguity = 0;
684   params.print_errors = 1;
685 
686   result = RNA2Dfold_cmdline_parser_internal (argc, argv, args_info, &params, 0);
687 
688   if (result == EXIT_FAILURE)
689     {
690       RNA2Dfold_cmdline_parser_free (args_info);
691       exit (EXIT_FAILURE);
692     }
693 
694   return result;
695 }
696 
697 int
RNA2Dfold_cmdline_parser_required(struct RNA2Dfold_args_info * args_info,const char * prog_name)698 RNA2Dfold_cmdline_parser_required (struct RNA2Dfold_args_info *args_info, const char *prog_name)
699 {
700   int result = EXIT_SUCCESS;
701 
702   if (RNA2Dfold_cmdline_parser_required2(args_info, prog_name, 0) > 0)
703     result = EXIT_FAILURE;
704 
705   if (result == EXIT_FAILURE)
706     {
707       RNA2Dfold_cmdline_parser_free (args_info);
708       exit (EXIT_FAILURE);
709     }
710 
711   return result;
712 }
713 
714 int
RNA2Dfold_cmdline_parser_required2(struct RNA2Dfold_args_info * args_info,const char * prog_name,const char * additional_error)715 RNA2Dfold_cmdline_parser_required2 (struct RNA2Dfold_args_info *args_info, const char *prog_name, const char *additional_error)
716 {
717   int error_occurred = 0;
718   FIX_UNUSED (additional_error);
719 
720   /* checks for required options */
721   if (check_multiple_option_occurrences(prog_name, args_info->neighborhood_given, args_info->neighborhood_min, args_info->neighborhood_max, "'--neighborhood'"))
722      error_occurred = 1;
723 
724 
725   /* checks for dependences among options */
726   if (args_info->neighborhood_given && ! args_info->stochBT_given)
727     {
728       fprintf (stderr, "%s: '--neighborhood' option depends on option 'stochBT'%s\n", prog_name, (additional_error ? additional_error : ""));
729       error_occurred = 1;
730     }
731 
732   return error_occurred;
733 }
734 
735 /*
736  * Extracted from the glibc source tree, version 2.3.6
737  *
738  * Licensed under the GPL as per the whole glibc source tree.
739  *
740  * This file was modified so that getopt_long can be called
741  * many times without risking previous memory to be spoiled.
742  *
743  * Modified by Andre Noll and Lorenzo Bettini for use in
744  * GNU gengetopt generated files.
745  *
746  */
747 
748 /*
749  * we must include anything we need since this file is not thought to be
750  * inserted in a file already using getopt.h
751  *
752  * Lorenzo
753  */
754 
755 struct option
756 {
757   const char *name;
758   /* has_arg can't be an enum because some compilers complain about
759      type mismatches in all the code that assumes it is an int.  */
760   int has_arg;
761   int *flag;
762   int val;
763 };
764 
765 /* This version of `getopt' appears to the caller like standard Unix `getopt'
766    but it behaves differently for the user, since it allows the user
767    to intersperse the options with the other arguments.
768 
769    As `getopt' works, it permutes the elements of ARGV so that,
770    when it is done, all the options precede everything else.  Thus
771    all application programs are extended to handle flexible argument order.
772 */
773 /*
774    If the field `flag' is not NULL, it points to a variable that is set
775    to the value given in the field `val' when the option is found, but
776    left unchanged if the option is not found.
777 
778    To have a long-named option do something other than set an `int' to
779    a compiled-in constant, such as set a value from `custom_optarg', set the
780    option's `flag' field to zero and its `val' field to a nonzero
781    value (the equivalent single-letter option character, if there is
782    one).  For long options that have a zero `flag' field, `getopt'
783    returns the contents of the `val' field.  */
784 
785 /* Names for the values of the `has_arg' field of `struct option'.  */
786 #ifndef no_argument
787 #define no_argument		0
788 #endif
789 
790 #ifndef required_argument
791 #define required_argument	1
792 #endif
793 
794 #ifndef optional_argument
795 #define optional_argument	2
796 #endif
797 
798 struct custom_getopt_data {
799 	/*
800 	 * These have exactly the same meaning as the corresponding global variables,
801 	 * except that they are used for the reentrant versions of getopt.
802 	 */
803 	int custom_optind;
804 	int custom_opterr;
805 	int custom_optopt;
806 	char *custom_optarg;
807 
808 	/* True if the internal members have been initialized.  */
809 	int initialized;
810 
811 	/*
812 	 * The next char to be scanned in the option-element in which the last option
813 	 * character we returned was found.  This allows us to pick up the scan where
814 	 * we left off.  If this is zero, or a null string, it means resume the scan by
815 	 * advancing to the next ARGV-element.
816 	 */
817 	char *nextchar;
818 
819 	/*
820 	 * Describe the part of ARGV that contains non-options that have been skipped.
821 	 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
822 	 * the index after the last of them.
823 	 */
824 	int first_nonopt;
825 	int last_nonopt;
826 };
827 
828 /*
829  * the variables optarg, optind, opterr and optopt are renamed with
830  * the custom_ prefix so that they don't interfere with getopt ones.
831  *
832  * Moreover they're static so they are visible only from within the
833  * file where this very file will be included.
834  */
835 
836 /*
837  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
838  * option that takes an argument, the argument value is returned here.
839  */
840 static char *custom_optarg;
841 
842 /*
843  * Index in ARGV of the next element to be scanned.  This is used for
844  * communication to and from the caller and for communication between
845  * successive calls to `custom_getopt'.
846  *
847  * On entry to `custom_getopt', 1 means this is the first call; initialize.
848  *
849  * When `custom_getopt' returns -1, this is the index of the first of the non-option
850  * elements that the caller should itself scan.
851  *
852  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
853  * has been scanned so far.
854  *
855  * 1003.2 says this must be 1 before any call.
856  */
857 static int custom_optind = 1;
858 
859 /*
860  * Callers store zero here to inhibit the error message for unrecognized
861  * options.
862  */
863 static int custom_opterr = 1;
864 
865 /*
866  * Set to an option character which was unrecognized.  This must be initialized
867  * on some systems to avoid linking in the system's own getopt implementation.
868  */
869 static int custom_optopt = '?';
870 
871 /*
872  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
873  * [first_nonopt,last_nonopt) which contains all the non-options that have been
874  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
875  * all the options processed since those non-options were skipped.
876  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
877  * indices of the non-options in ARGV after they are moved.
878  */
exchange(char ** argv,struct custom_getopt_data * d)879 static void exchange(char **argv, struct custom_getopt_data *d)
880 {
881 	int bottom = d->first_nonopt;
882 	int middle = d->last_nonopt;
883 	int top = d->custom_optind;
884 	char *tem;
885 
886 	/*
887 	 * Exchange the shorter segment with the far end of the longer segment.
888 	 * That puts the shorter segment into the right place.  It leaves the
889 	 * longer segment in the right place overall, but it consists of two
890 	 * parts that need to be swapped next.
891 	 */
892 	while (top > middle && middle > bottom) {
893 		if (top - middle > middle - bottom) {
894 			/* Bottom segment is the short one.  */
895 			int len = middle - bottom;
896 			int i;
897 
898 			/* Swap it with the top part of the top segment.  */
899 			for (i = 0; i < len; i++) {
900 				tem = argv[bottom + i];
901 				argv[bottom + i] =
902 					argv[top - (middle - bottom) + i];
903 				argv[top - (middle - bottom) + i] = tem;
904 			}
905 			/* Exclude the moved bottom segment from further swapping.  */
906 			top -= len;
907 		} else {
908 			/* Top segment is the short one.  */
909 			int len = top - middle;
910 			int i;
911 
912 			/* Swap it with the bottom part of the bottom segment.  */
913 			for (i = 0; i < len; i++) {
914 				tem = argv[bottom + i];
915 				argv[bottom + i] = argv[middle + i];
916 				argv[middle + i] = tem;
917 			}
918 			/* Exclude the moved top segment from further swapping.  */
919 			bottom += len;
920 		}
921 	}
922 	/* Update records for the slots the non-options now occupy.  */
923 	d->first_nonopt += (d->custom_optind - d->last_nonopt);
924 	d->last_nonopt = d->custom_optind;
925 }
926 
927 /* Initialize the internal data when the first call is made.  */
custom_getopt_initialize(struct custom_getopt_data * d)928 static void custom_getopt_initialize(struct custom_getopt_data *d)
929 {
930 	/*
931 	 * Start processing options with ARGV-element 1 (since ARGV-element 0
932 	 * is the program name); the sequence of previously skipped non-option
933 	 * ARGV-elements is empty.
934 	 */
935 	d->first_nonopt = d->last_nonopt = d->custom_optind;
936 	d->nextchar = NULL;
937 	d->initialized = 1;
938 }
939 
940 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
941 
942 /* 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)943 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
944 	struct custom_getopt_data *d)
945 {
946 	/*
947 	 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
948 	 * moved back by the user (who may also have changed the arguments).
949 	 */
950 	if (d->last_nonopt > d->custom_optind)
951 		d->last_nonopt = d->custom_optind;
952 	if (d->first_nonopt > d->custom_optind)
953 		d->first_nonopt = d->custom_optind;
954 	/*
955 	 * If we have just processed some options following some
956 	 * non-options, exchange them so that the options come first.
957 	 */
958 	if (d->first_nonopt != d->last_nonopt &&
959 			d->last_nonopt != d->custom_optind)
960 		exchange((char **) argv, d);
961 	else if (d->last_nonopt != d->custom_optind)
962 		d->first_nonopt = d->custom_optind;
963 	/*
964 	 * Skip any additional non-options and extend the range of
965 	 * non-options previously skipped.
966 	 */
967 	while (d->custom_optind < argc && NONOPTION_P)
968 		d->custom_optind++;
969 	d->last_nonopt = d->custom_optind;
970 	/*
971 	 * The special ARGV-element `--' means premature end of options.  Skip
972 	 * it like a null option, then exchange with previous non-options as if
973 	 * it were an option, then skip everything else like a non-option.
974 	 */
975 	if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
976 		d->custom_optind++;
977 		if (d->first_nonopt != d->last_nonopt
978 				&& d->last_nonopt != d->custom_optind)
979 			exchange((char **) argv, d);
980 		else if (d->first_nonopt == d->last_nonopt)
981 			d->first_nonopt = d->custom_optind;
982 		d->last_nonopt = argc;
983 		d->custom_optind = argc;
984 	}
985 	/*
986 	 * If we have done all the ARGV-elements, stop the scan and back over
987 	 * any non-options that we skipped and permuted.
988 	 */
989 	if (d->custom_optind == argc) {
990 		/*
991 		 * Set the next-arg-index to point at the non-options that we
992 		 * previously skipped, so the caller will digest them.
993 		 */
994 		if (d->first_nonopt != d->last_nonopt)
995 			d->custom_optind = d->first_nonopt;
996 		return -1;
997 	}
998 	/*
999 	 * If we have come to a non-option and did not permute it, either stop
1000 	 * the scan or describe it to the caller and pass it by.
1001 	 */
1002 	if (NONOPTION_P) {
1003 		d->custom_optarg = argv[d->custom_optind++];
1004 		return 1;
1005 	}
1006 	/*
1007 	 * We have found another option-ARGV-element. Skip the initial
1008 	 * punctuation.
1009 	 */
1010 	d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
1011 	return 0;
1012 }
1013 
1014 /*
1015  * Check whether the ARGV-element is a long option.
1016  *
1017  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
1018  * that an abbreviation of the long option, just like "--fu", and not "-f" with
1019  * arg "u".
1020  *
1021  * This distinction seems to be the most useful approach.
1022  *
1023  */
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)1024 static int check_long_opt(int argc, char *const *argv, const char *optstring,
1025 		const struct option *longopts, int *longind,
1026 		int print_errors, struct custom_getopt_data *d)
1027 {
1028 	char *nameend;
1029 	const struct option *p;
1030 	const struct option *pfound = NULL;
1031 	int exact = 0;
1032 	int ambig = 0;
1033 	int indfound = -1;
1034 	int option_index;
1035 
1036 	for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
1037 		/* Do nothing.  */ ;
1038 
1039 	/* Test all long options for either exact match or abbreviated matches */
1040 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
1041 		if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
1042 			if ((unsigned int) (nameend - d->nextchar)
1043 					== (unsigned int) strlen(p->name)) {
1044 				/* Exact match found.  */
1045 				pfound = p;
1046 				indfound = option_index;
1047 				exact = 1;
1048 				break;
1049 			} else if (pfound == NULL) {
1050 				/* First nonexact match found.  */
1051 				pfound = p;
1052 				indfound = option_index;
1053 			} else if (pfound->has_arg != p->has_arg
1054 					|| pfound->flag != p->flag
1055 					|| pfound->val != p->val)
1056 				/* Second or later nonexact match found.  */
1057 				ambig = 1;
1058 		}
1059 	if (ambig && !exact) {
1060 		if (print_errors) {
1061 			fprintf(stderr,
1062 				"%s: option `%s' is ambiguous\n",
1063 				argv[0], argv[d->custom_optind]);
1064 		}
1065 		d->nextchar += strlen(d->nextchar);
1066 		d->custom_optind++;
1067 		d->custom_optopt = 0;
1068 		return '?';
1069 	}
1070 	if (pfound) {
1071 		option_index = indfound;
1072 		d->custom_optind++;
1073 		if (*nameend) {
1074 			if (pfound->has_arg != no_argument)
1075 				d->custom_optarg = nameend + 1;
1076 			else {
1077 				if (print_errors) {
1078 					if (argv[d->custom_optind - 1][1] == '-') {
1079 						/* --option */
1080 						fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
1081 							argv[0], pfound->name);
1082 					} else {
1083 						/* +option or -option */
1084 						fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
1085 							argv[0], argv[d->custom_optind - 1][0], pfound->name);
1086 					}
1087 
1088 				}
1089 				d->nextchar += strlen(d->nextchar);
1090 				d->custom_optopt = pfound->val;
1091 				return '?';
1092 			}
1093 		} else if (pfound->has_arg == required_argument) {
1094 			if (d->custom_optind < argc)
1095 				d->custom_optarg = argv[d->custom_optind++];
1096 			else {
1097 				if (print_errors) {
1098 					fprintf(stderr,
1099 						"%s: option `%s' requires an argument\n",
1100 						argv[0],
1101 						argv[d->custom_optind - 1]);
1102 				}
1103 				d->nextchar += strlen(d->nextchar);
1104 				d->custom_optopt = pfound->val;
1105 				return optstring[0] == ':' ? ':' : '?';
1106 			}
1107 		}
1108 		d->nextchar += strlen(d->nextchar);
1109 		if (longind != NULL)
1110 			*longind = option_index;
1111 		if (pfound->flag) {
1112 			*(pfound->flag) = pfound->val;
1113 			return 0;
1114 		}
1115 		return pfound->val;
1116 	}
1117 	/*
1118 	 * Can't find it as a long option.  If this is not getopt_long_only, or
1119 	 * the option starts with '--' or is not a valid short option, then
1120 	 * it's an error.  Otherwise interpret it as a short option.
1121 	 */
1122 	if (print_errors) {
1123 		if (argv[d->custom_optind][1] == '-') {
1124 			/* --option */
1125 			fprintf(stderr,
1126 				"%s: unrecognized option `--%s'\n",
1127 				argv[0], d->nextchar);
1128 		} else {
1129 			/* +option or -option */
1130 			fprintf(stderr,
1131 				"%s: unrecognized option `%c%s'\n",
1132 				argv[0], argv[d->custom_optind][0],
1133 				d->nextchar);
1134 		}
1135 	}
1136 	d->nextchar = (char *) "";
1137 	d->custom_optind++;
1138 	d->custom_optopt = 0;
1139 	return '?';
1140 }
1141 
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)1142 static int check_short_opt(int argc, char *const *argv, const char *optstring,
1143 		int print_errors, struct custom_getopt_data *d)
1144 {
1145 	char c = *d->nextchar++;
1146 	const char *temp = strchr(optstring, c);
1147 
1148 	/* Increment `custom_optind' when we start to process its last character.  */
1149 	if (*d->nextchar == '\0')
1150 		++d->custom_optind;
1151 	if (!temp || c == ':') {
1152 		if (print_errors)
1153 			fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
1154 
1155 		d->custom_optopt = c;
1156 		return '?';
1157 	}
1158 	if (temp[1] == ':') {
1159 		if (temp[2] == ':') {
1160 			/* This is an option that accepts an argument optionally.  */
1161 			if (*d->nextchar != '\0') {
1162 				d->custom_optarg = d->nextchar;
1163 				d->custom_optind++;
1164 			} else
1165 				d->custom_optarg = NULL;
1166 			d->nextchar = NULL;
1167 		} else {
1168 			/* This is an option that requires an argument.  */
1169 			if (*d->nextchar != '\0') {
1170 				d->custom_optarg = d->nextchar;
1171 				/*
1172 				 * If we end this ARGV-element by taking the
1173 				 * rest as an arg, we must advance to the next
1174 				 * element now.
1175 				 */
1176 				d->custom_optind++;
1177 			} else if (d->custom_optind == argc) {
1178 				if (print_errors) {
1179 					fprintf(stderr,
1180 						"%s: option requires an argument -- %c\n",
1181 						argv[0], c);
1182 				}
1183 				d->custom_optopt = c;
1184 				if (optstring[0] == ':')
1185 					c = ':';
1186 				else
1187 					c = '?';
1188 			} else
1189 				/*
1190 				 * We already incremented `custom_optind' once;
1191 				 * increment it again when taking next ARGV-elt
1192 				 * as argument.
1193 				 */
1194 				d->custom_optarg = argv[d->custom_optind++];
1195 			d->nextchar = NULL;
1196 		}
1197 	}
1198 	return c;
1199 }
1200 
1201 /*
1202  * Scan elements of ARGV for option characters given in OPTSTRING.
1203  *
1204  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1205  * then it is an option element.  The characters of this element
1206  * (aside from the initial '-') are option characters.  If `getopt'
1207  * is called repeatedly, it returns successively each of the option characters
1208  * from each of the option elements.
1209  *
1210  * If `getopt' finds another option character, it returns that character,
1211  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1212  * resume the scan with the following option character or ARGV-element.
1213  *
1214  * If there are no more option characters, `getopt' returns -1.
1215  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1216  * that is not an option.  (The ARGV-elements have been permuted
1217  * so that those that are not options now come last.)
1218  *
1219  * OPTSTRING is a string containing the legitimate option characters.
1220  * If an option character is seen that is not listed in OPTSTRING,
1221  * return '?' after printing an error message.  If you set `custom_opterr' to
1222  * zero, the error message is suppressed but we still return '?'.
1223  *
1224  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1225  * so the following text in the same ARGV-element, or the text of the following
1226  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1227  * wants an optional arg; if there is text in the current ARGV-element,
1228  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1229  *
1230  * If OPTSTRING starts with `-' or `+', it requests different methods of
1231  * handling the non-option ARGV-elements.
1232  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1233  *
1234  * Long-named options begin with `--' instead of `-'.
1235  * Their names may be abbreviated as long as the abbreviation is unique
1236  * or is an exact match for some defined option.  If they have an
1237  * argument, it follows the option name in the same ARGV-element, separated
1238  * from the option name by a `=', or else the in next ARGV-element.
1239  * When `getopt' finds a long-named option, it returns 0 if that option's
1240  * `flag' field is nonzero, the value of the option's `val' field
1241  * if the `flag' field is zero.
1242  *
1243  * The elements of ARGV aren't really const, because we permute them.
1244  * But we pretend they're const in the prototype to be compatible
1245  * with other systems.
1246  *
1247  * LONGOPTS is a vector of `struct option' terminated by an
1248  * element containing a name which is zero.
1249  *
1250  * LONGIND returns the index in LONGOPT of the long-named option found.
1251  * It is only valid when a long-named option has been found by the most
1252  * recent call.
1253  *
1254  * Return the option character from OPTS just read.  Return -1 when there are
1255  * no more options.  For unrecognized options, or options missing arguments,
1256  * `custom_optopt' is set to the option letter, and '?' is returned.
1257  *
1258  * The OPTS string is a list of characters which are recognized option letters,
1259  * optionally followed by colons, specifying that that letter takes an
1260  * argument, to be placed in `custom_optarg'.
1261  *
1262  * If a letter in OPTS is followed by two colons, its argument is optional.
1263  * This behavior is specific to the GNU `getopt'.
1264  *
1265  * The argument `--' causes premature termination of argument scanning,
1266  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1267  * with `--', then non-option arguments are treated as arguments to the option
1268  * '\0'.  This behavior is specific to the GNU `getopt'.
1269  */
1270 
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1271 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1272 		const struct option *longopts, int *longind,
1273 		struct custom_getopt_data *d)
1274 {
1275 	int ret, print_errors = d->custom_opterr;
1276 
1277 	if (optstring[0] == ':')
1278 		print_errors = 0;
1279 	if (argc < 1)
1280 		return -1;
1281 	d->custom_optarg = NULL;
1282 
1283 	/*
1284 	 * This is a big difference with GNU getopt, since optind == 0
1285 	 * means initialization while here 1 means first call.
1286 	 */
1287 	if (d->custom_optind == 0 || !d->initialized) {
1288 		if (d->custom_optind == 0)
1289 			d->custom_optind = 1;	/* Don't scan ARGV[0], the program name.  */
1290 		custom_getopt_initialize(d);
1291 	}
1292 	if (d->nextchar == NULL || *d->nextchar == '\0') {
1293 		ret = shuffle_argv(argc, argv, longopts, d);
1294 		if (ret)
1295 			return ret;
1296 	}
1297 	if (longopts && (argv[d->custom_optind][1] == '-' ))
1298 		return check_long_opt(argc, argv, optstring, longopts,
1299 			longind, print_errors, d);
1300 	return check_short_opt(argc, argv, optstring, print_errors, d);
1301 }
1302 
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1303 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1304 	const struct option *longopts, int *longind)
1305 {
1306 	int result;
1307 	/* Keep a global copy of all internal members of d */
1308 	static struct custom_getopt_data d;
1309 
1310 	d.custom_optind = custom_optind;
1311 	d.custom_opterr = custom_opterr;
1312 	result = getopt_internal_r(argc, argv, optstring, longopts,
1313 		longind, &d);
1314 	custom_optind = d.custom_optind;
1315 	custom_optarg = d.custom_optarg;
1316 	custom_optopt = d.custom_optopt;
1317 	return result;
1318 }
1319 
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1320 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1321 	const struct option *long_options, int *opt_index)
1322 {
1323 	return custom_getopt_internal(argc, argv, options, long_options,
1324 		opt_index);
1325 }
1326 
1327 
1328 static char *package_name = 0;
1329 
1330 /**
1331  * @brief updates an option
1332  * @param field the generic pointer to the field to update
1333  * @param orig_field the pointer to the orig field
1334  * @param field_given the pointer to the number of occurrence of this option
1335  * @param prev_given the pointer to the number of occurrence already seen
1336  * @param value the argument for this option (if null no arg was specified)
1337  * @param possible_values the possible values for this option (if specified)
1338  * @param default_value the default value (in case the option only accepts fixed values)
1339  * @param arg_type the type of this option
1340  * @param check_ambiguity @see RNA2Dfold_cmdline_parser_params.check_ambiguity
1341  * @param override @see RNA2Dfold_cmdline_parser_params.override
1342  * @param no_free whether to free a possible previous value
1343  * @param multiple_option whether this is a multiple option
1344  * @param long_opt the corresponding long option
1345  * @param short_opt the corresponding short option (or '-' if none)
1346  * @param additional_error possible further error specification
1347  */
1348 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,RNA2Dfold_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)1349 int update_arg(void *field, char **orig_field,
1350                unsigned int *field_given, unsigned int *prev_given,
1351                char *value, const char *possible_values[],
1352                const char *default_value,
1353                RNA2Dfold_cmdline_parser_arg_type arg_type,
1354                int check_ambiguity, int override,
1355                int no_free, int multiple_option,
1356                const char *long_opt, char short_opt,
1357                const char *additional_error)
1358 {
1359   char *stop_char = 0;
1360   const char *val = value;
1361   int found;
1362   char **string_field;
1363   FIX_UNUSED (field);
1364 
1365   stop_char = 0;
1366   found = 0;
1367 
1368   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1369     {
1370       if (short_opt != '-')
1371         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1372                package_name, long_opt, short_opt,
1373                (additional_error ? additional_error : ""));
1374       else
1375         fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1376                package_name, long_opt,
1377                (additional_error ? additional_error : ""));
1378       return 1; /* failure */
1379     }
1380 
1381   if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)
1382     {
1383       if (short_opt != '-')
1384         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",
1385           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt,
1386           (additional_error ? additional_error : ""));
1387       else
1388         fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",
1389           package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt,
1390           (additional_error ? additional_error : ""));
1391       return 1; /* failure */
1392     }
1393 
1394   if (field_given && *field_given && ! override)
1395     return 0;
1396   if (prev_given)
1397     (*prev_given)++;
1398   if (field_given)
1399     (*field_given)++;
1400   if (possible_values)
1401     val = possible_values[found];
1402 
1403   switch(arg_type) {
1404   case ARG_FLAG:
1405     *((int *)field) = !*((int *)field);
1406     break;
1407   case ARG_INT:
1408     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1409     break;
1410   case ARG_DOUBLE:
1411     if (val) *((double *)field) = strtod (val, &stop_char);
1412     break;
1413   case ARG_STRING:
1414     if (val) {
1415       string_field = (char **)field;
1416       if (!no_free && *string_field)
1417         free (*string_field); /* free previous string */
1418       *string_field = gengetopt_strdup (val);
1419     }
1420     break;
1421   default:
1422     break;
1423   };
1424 
1425   /* check numeric conversion */
1426   switch(arg_type) {
1427   case ARG_INT:
1428   case ARG_DOUBLE:
1429     if (val && !(stop_char && *stop_char == '\0')) {
1430       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1431       return 1; /* failure */
1432     }
1433     break;
1434   default:
1435     ;
1436   };
1437 
1438   /* store the original value */
1439   switch(arg_type) {
1440   case ARG_NO:
1441   case ARG_FLAG:
1442     break;
1443   default:
1444     if (value && orig_field) {
1445       if (no_free) {
1446         *orig_field = value;
1447       } else {
1448         if (*orig_field)
1449           free (*orig_field); /* free previous string */
1450         *orig_field = gengetopt_strdup (value);
1451       }
1452     }
1453   };
1454 
1455   return 0; /* OK */
1456 }
1457 
1458 /**
1459  * @brief store information about a multiple option in a temporary list
1460  * @param list where to (temporarily) store multiple options
1461  */
1462 static
update_multiple_arg_temp(struct generic_list ** list,unsigned int * prev_given,const char * val,const char * possible_values[],const char * default_value,RNA2Dfold_cmdline_parser_arg_type arg_type,const char * long_opt,char short_opt,const char * additional_error)1463 int update_multiple_arg_temp(struct generic_list **list,
1464                unsigned int *prev_given, const char *val,
1465                const char *possible_values[], const char *default_value,
1466                RNA2Dfold_cmdline_parser_arg_type arg_type,
1467                const char *long_opt, char short_opt,
1468                const char *additional_error)
1469 {
1470   /* store single arguments */
1471   char *multi_token;
1472   const char *multi_next;
1473 
1474   if (arg_type == ARG_NO) {
1475     (*prev_given)++;
1476     return 0; /* OK */
1477   }
1478 
1479   multi_token = get_multiple_arg_token(val);
1480   multi_next = get_multiple_arg_token_next (val);
1481 
1482   while (1)
1483     {
1484       add_node (list);
1485       if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
1486           prev_given, multi_token, possible_values, default_value,
1487           arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
1488         if (multi_token) free(multi_token);
1489         return 1; /* failure */
1490       }
1491 
1492       if (multi_next)
1493         {
1494           multi_token = get_multiple_arg_token(multi_next);
1495           multi_next = get_multiple_arg_token_next (multi_next);
1496         }
1497       else
1498         break;
1499     }
1500 
1501   return 0; /* OK */
1502 }
1503 
1504 /**
1505  * @brief free the passed list (including possible string argument)
1506  */
1507 static
free_list(struct generic_list * list,short string_arg)1508 void free_list(struct generic_list *list, short string_arg)
1509 {
1510   if (list) {
1511     struct generic_list *tmp;
1512     while (list)
1513       {
1514         tmp = list;
1515         if (string_arg && list->arg.string_arg)
1516           free (list->arg.string_arg);
1517         if (list->orig)
1518           free (list->orig);
1519         list = list->next;
1520         free (tmp);
1521       }
1522   }
1523 }
1524 
1525 /**
1526  * @brief updates a multiple option starting from the passed list
1527  */
1528 static
update_multiple_arg(void * field,char *** orig_field,unsigned int field_given,unsigned int prev_given,union generic_value * default_value,RNA2Dfold_cmdline_parser_arg_type arg_type,struct generic_list * list)1529 void update_multiple_arg(void *field, char ***orig_field,
1530                unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
1531                RNA2Dfold_cmdline_parser_arg_type arg_type,
1532                struct generic_list *list)
1533 {
1534   int i;
1535   struct generic_list *tmp;
1536 
1537   if (prev_given && list) {
1538     *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
1539 
1540     switch(arg_type) {
1541     case ARG_INT:
1542       *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;
1543     case ARG_DOUBLE:
1544       *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;
1545     case ARG_STRING:
1546       *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
1547     default:
1548       break;
1549     };
1550 
1551     for (i = (prev_given - 1); i >= 0; --i)
1552       {
1553         tmp = list;
1554 
1555         switch(arg_type) {
1556         case ARG_INT:
1557           (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;
1558         case ARG_DOUBLE:
1559           (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;
1560         case ARG_STRING:
1561           (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
1562         default:
1563           break;
1564         }
1565         (*orig_field) [i + field_given] = list->orig;
1566         list = list->next;
1567         free (tmp);
1568       }
1569   } else { /* set the default value */
1570     if (default_value && ! field_given) {
1571       switch(arg_type) {
1572       case ARG_INT:
1573         if (! *((int **)field)) {
1574           *((int **)field) = (int *)malloc (sizeof (int));
1575           (*((int **)field))[0] = default_value->int_arg;
1576         }
1577         break;
1578       case ARG_DOUBLE:
1579         if (! *((double **)field)) {
1580           *((double **)field) = (double *)malloc (sizeof (double));
1581           (*((double **)field))[0] = default_value->double_arg;
1582         }
1583         break;
1584       case ARG_STRING:
1585         if (! *((char ***)field)) {
1586           *((char ***)field) = (char **)malloc (sizeof (char *));
1587           (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
1588         }
1589         break;
1590       default: break;
1591       }
1592       if (!(*orig_field)) {
1593         *orig_field = (char **) malloc (sizeof (char *));
1594         (*orig_field)[0] = 0;
1595       }
1596     }
1597   }
1598 }
1599 
1600 int
RNA2Dfold_cmdline_parser_internal(int argc,char ** argv,struct RNA2Dfold_args_info * args_info,struct RNA2Dfold_cmdline_parser_params * params,const char * additional_error)1601 RNA2Dfold_cmdline_parser_internal (
1602   int argc, char **argv, struct RNA2Dfold_args_info *args_info,
1603                         struct RNA2Dfold_cmdline_parser_params *params, const char *additional_error)
1604 {
1605   int c;	/* Character of the parsed option.  */
1606 
1607   struct generic_list * neighborhood_list = NULL;
1608   int error_occurred = 0;
1609   struct RNA2Dfold_args_info local_args_info;
1610 
1611   int override;
1612   int initialize;
1613   int check_required;
1614   int check_ambiguity;
1615 
1616   char *optarg;
1617   int optind;
1618   int opterr;
1619   int optopt;
1620 
1621   package_name = argv[0];
1622 
1623   /* TODO: Why is this here? It is not used anywhere. */
1624   override = params->override;
1625   FIX_UNUSED(override);
1626 
1627   initialize = params->initialize;
1628   check_required = params->check_required;
1629 
1630   /* TODO: Why is this here? It is not used anywhere. */
1631   check_ambiguity = params->check_ambiguity;
1632   FIX_UNUSED(check_ambiguity);
1633 
1634   if (initialize)
1635     RNA2Dfold_cmdline_parser_init (args_info);
1636 
1637   RNA2Dfold_cmdline_parser_init (&local_args_info);
1638 
1639   optarg = 0;
1640   optind = 0;
1641   opterr = params->print_errors;
1642   optopt = '?';
1643 
1644   while (1)
1645     {
1646       int option_index = 0;
1647 
1648       static struct option long_options[] = {
1649         { "help",	0, NULL, 'h' },
1650         { "detailed-help",	0, NULL, 0 },
1651         { "version",	0, NULL, 'V' },
1652         { "noconv",	0, NULL, 0 },
1653         { "numThreads",	1, NULL, 'j' },
1654         { "partfunc",	0, NULL, 'p' },
1655         { "stochBT",	1, NULL, 0 },
1656         { "neighborhood",	1, NULL, 0 },
1657         { "pfScale",	1, NULL, 'S' },
1658         { "noBT",	0, NULL, 0 },
1659         { "circ",	0, NULL, 'c' },
1660         { "temp",	1, NULL, 'T' },
1661         { "maxDist1",	1, NULL, 'K' },
1662         { "maxDist2",	1, NULL, 'L' },
1663         { "noTetra",	0, NULL, '4' },
1664         { "paramFile",	1, NULL, 'P' },
1665         { "dangles",	1, NULL, 'd' },
1666         { "noGU",	0, NULL, 0 },
1667         { "noClosingGU",	0, NULL, 0 },
1668         { 0,  0, 0, 0 }
1669       };
1670 
1671       custom_optarg = optarg;
1672       custom_optind = optind;
1673       custom_opterr = opterr;
1674       custom_optopt = optopt;
1675 
1676       c = custom_getopt_long (argc, argv, "hVj:pS:cT:K:L:4P:d:", long_options, &option_index);
1677 
1678       optarg = custom_optarg;
1679       optind = custom_optind;
1680       opterr = custom_opterr;
1681       optopt = custom_optopt;
1682 
1683       if (c == -1) break;	/* Exit from `while (1)' loop.  */
1684 
1685       switch (c)
1686         {
1687         case 'h':	/* Print help and exit.  */
1688           RNA2Dfold_cmdline_parser_print_help ();
1689           RNA2Dfold_cmdline_parser_free (&local_args_info);
1690           exit (EXIT_SUCCESS);
1691 
1692         case 'V':	/* Print version and exit.  */
1693           RNA2Dfold_cmdline_parser_print_version ();
1694           RNA2Dfold_cmdline_parser_free (&local_args_info);
1695           exit (EXIT_SUCCESS);
1696 
1697         case 'j':	/* Set the number of threads used for calculations (only available when compiled with OpenMP support)
1698 
1699 .  */
1700 
1701 
1702           if (update_arg( (void *)&(args_info->numThreads_arg),
1703                &(args_info->numThreads_orig), &(args_info->numThreads_given),
1704               &(local_args_info.numThreads_given), optarg, 0, 0, ARG_INT,
1705               check_ambiguity, override, 0, 0,
1706               "numThreads", 'j',
1707               additional_error))
1708             goto failure;
1709 
1710           break;
1711         case 'p':	/* calculate partition function and thus, Boltzmann probabilities and Gibbs free energy
1712 
1713 .  */
1714 
1715 
1716           if (update_arg((void *)&(args_info->partfunc_flag), 0, &(args_info->partfunc_given),
1717               &(local_args_info.partfunc_given), optarg, 0, 0, ARG_FLAG,
1718               check_ambiguity, override, 1, 0, "partfunc", 'p',
1719               additional_error))
1720             goto failure;
1721 
1722           break;
1723         case 'S':	/* scaling factor for pf to avoid overflows
1724 
1725 .  */
1726 
1727 
1728           if (update_arg( (void *)&(args_info->pfScale_arg),
1729                &(args_info->pfScale_orig), &(args_info->pfScale_given),
1730               &(local_args_info.pfScale_given), optarg, 0, 0, ARG_DOUBLE,
1731               check_ambiguity, override, 0, 0,
1732               "pfScale", 'S',
1733               additional_error))
1734             goto failure;
1735 
1736           break;
1737         case 'c':	/* Assume a circular (instead of linear) RNA molecule.
1738 
1739 .  */
1740 
1741 
1742           if (update_arg((void *)&(args_info->circ_flag), 0, &(args_info->circ_given),
1743               &(local_args_info.circ_given), optarg, 0, 0, ARG_FLAG,
1744               check_ambiguity, override, 1, 0, "circ", 'c',
1745               additional_error))
1746             goto failure;
1747 
1748           break;
1749         case 'T':	/* Rescale energy parameters to a temperature of temp C. Default is 37C.
1750 
1751 .  */
1752 
1753 
1754           if (update_arg( (void *)&(args_info->temp_arg),
1755                &(args_info->temp_orig), &(args_info->temp_given),
1756               &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
1757               check_ambiguity, override, 0, 0,
1758               "temp", 'T',
1759               additional_error))
1760             goto failure;
1761 
1762           break;
1763         case 'K':	/* maximum distance to first reference structure.  */
1764 
1765 
1766           if (update_arg( (void *)&(args_info->maxDist1_arg),
1767                &(args_info->maxDist1_orig), &(args_info->maxDist1_given),
1768               &(local_args_info.maxDist1_given), optarg, 0, 0, ARG_INT,
1769               check_ambiguity, override, 0, 0,
1770               "maxDist1", 'K',
1771               additional_error))
1772             goto failure;
1773 
1774           break;
1775         case 'L':	/* maximum distance to second reference structure.  */
1776 
1777 
1778           if (update_arg( (void *)&(args_info->maxDist2_arg),
1779                &(args_info->maxDist2_orig), &(args_info->maxDist2_given),
1780               &(local_args_info.maxDist2_given), optarg, 0, 0, ARG_INT,
1781               check_ambiguity, override, 0, 0,
1782               "maxDist2", 'L',
1783               additional_error))
1784             goto failure;
1785 
1786           break;
1787         case '4':	/* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins. Mostly for testing.
1788 
1789 .  */
1790 
1791 
1792           if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
1793               &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
1794               check_ambiguity, override, 1, 0, "noTetra", '4',
1795               additional_error))
1796             goto failure;
1797 
1798           break;
1799         case 'P':	/* Read energy parameters from paramfile, instead of using the default parameter set.
1800 .  */
1801 
1802 
1803           if (update_arg( (void *)&(args_info->paramFile_arg),
1804                &(args_info->paramFile_orig), &(args_info->paramFile_given),
1805               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1806               check_ambiguity, override, 0, 0,
1807               "paramFile", 'P',
1808               additional_error))
1809             goto failure;
1810 
1811           break;
1812         case 'd':	/* How to treat \"dangling end\" energies for bases adjacent to helices in free ends and multi-loops
1813 .  */
1814 
1815 
1816           if (update_arg( (void *)&(args_info->dangles_arg),
1817                &(args_info->dangles_orig), &(args_info->dangles_given),
1818               &(local_args_info.dangles_given), optarg, RNA2Dfold_cmdline_parser_dangles_values, "2", ARG_INT,
1819               check_ambiguity, override, 0, 0,
1820               "dangles", 'd',
1821               additional_error))
1822             goto failure;
1823 
1824           break;
1825 
1826         case 0:	/* Long option with no short option */
1827           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1828             RNA2Dfold_cmdline_parser_print_detailed_help ();
1829             RNA2Dfold_cmdline_parser_free (&local_args_info);
1830             exit (EXIT_SUCCESS);
1831           }
1832 
1833           /* Do not automatically substitude nucleotide \"T\" with \"U\"
1834 
1835 .  */
1836           if (strcmp (long_options[option_index].name, "noconv") == 0)
1837           {
1838 
1839 
1840             if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
1841                 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
1842                 check_ambiguity, override, 1, 0, "noconv", '-',
1843                 additional_error))
1844               goto failure;
1845 
1846           }
1847           /* backtrack a certain number of Boltzmann samples from the appropriate k,l neighborhood(s)
1848 
1849 .  */
1850           else if (strcmp (long_options[option_index].name, "stochBT") == 0)
1851           {
1852 
1853 
1854             if (update_arg( (void *)&(args_info->stochBT_arg),
1855                  &(args_info->stochBT_orig), &(args_info->stochBT_given),
1856                 &(local_args_info.stochBT_given), optarg, 0, 0, ARG_INT,
1857                 check_ambiguity, override, 0, 0,
1858                 "stochBT", '-',
1859                 additional_error))
1860               goto failure;
1861 
1862           }
1863           /* backtrack structures from certain k,l-neighborhood only, can be specified multiple times (<k>:<l>,<m>:<n>,...)
1864 
1865 .  */
1866           else if (strcmp (long_options[option_index].name, "neighborhood") == 0)
1867           {
1868 
1869             if (update_multiple_arg_temp(&neighborhood_list,
1870                 &(local_args_info.neighborhood_given), optarg, 0, 0, ARG_STRING,
1871                 "neighborhood", '-',
1872                 additional_error))
1873               goto failure;
1874 
1875           }
1876           /* do not backtrack structures, calculate energy contributions only
1877 
1878 .  */
1879           else if (strcmp (long_options[option_index].name, "noBT") == 0)
1880           {
1881 
1882 
1883             if (update_arg((void *)&(args_info->noBT_flag), 0, &(args_info->noBT_given),
1884                 &(local_args_info.noBT_given), optarg, 0, 0, ARG_FLAG,
1885                 check_ambiguity, override, 1, 0, "noBT", '-',
1886                 additional_error))
1887               goto failure;
1888 
1889           }
1890           /* Do not allow GU pairs
1891 
1892 .  */
1893           else if (strcmp (long_options[option_index].name, "noGU") == 0)
1894           {
1895 
1896 
1897             if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
1898                 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
1899                 check_ambiguity, override, 1, 0, "noGU", '-',
1900                 additional_error))
1901               goto failure;
1902 
1903           }
1904           /* Do not allow GU pairs at the end of helices
1905 
1906 .  */
1907           else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
1908           {
1909 
1910 
1911             if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
1912                 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
1913                 check_ambiguity, override, 1, 0, "noClosingGU", '-',
1914                 additional_error))
1915               goto failure;
1916 
1917           }
1918 
1919           break;
1920         case '?':	/* Invalid option.  */
1921           /* `getopt_long' already printed an error message.  */
1922           goto failure;
1923 
1924         default:	/* bug: option not considered.  */
1925           fprintf (stderr, "%s: option unknown: %c%s\n", RNA2DFOLD_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1926           abort ();
1927         } /* switch */
1928     } /* while */
1929 
1930 
1931   update_multiple_arg((void *)&(args_info->neighborhood_arg),
1932     &(args_info->neighborhood_orig), args_info->neighborhood_given,
1933     local_args_info.neighborhood_given, 0,
1934     ARG_STRING, neighborhood_list);
1935 
1936   args_info->neighborhood_given += local_args_info.neighborhood_given;
1937   local_args_info.neighborhood_given = 0;
1938 
1939   if (check_required)
1940     {
1941       error_occurred += RNA2Dfold_cmdline_parser_required2 (args_info, argv[0], additional_error);
1942     }
1943 
1944   RNA2Dfold_cmdline_parser_release (&local_args_info);
1945 
1946   if ( error_occurred )
1947     return (EXIT_FAILURE);
1948 
1949   return 0;
1950 
1951 failure:
1952   free_list (neighborhood_list, 1 );
1953 
1954   RNA2Dfold_cmdline_parser_release (&local_args_info);
1955   return (EXIT_FAILURE);
1956 }
1957 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
1958