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