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