WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / Progs / RNApaln_cmdl.c
1 /*
2   File autogenerated by gengetopt version 2.22.5
3   generated with the following command:
4   gengetopt -i RNApaln.ggo --file-name=RNApaln_cmdl --include-getopt --default-optional --func-name=RNApaln_cmdline_parser --arg-struct-name=RNApaln_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 "RNApaln_cmdl.h"
26
27 const char *RNApaln_args_info_purpose = "RNA alignment based on sequence base pairing propensities";
28
29 const char *RNApaln_args_info_usage = "Usage: RNApaln [OPTIONS]...";
30
31 const char *RNApaln_args_info_description = "Uses string-alignment techniques to perform fast pairwise structural alignments \nof RNAs. Similar to RNApdist secondary structure is incorporated in an \napproximate manner by computing base pair probabilities, which are then reduced \nto a vector holding the probability that a base is paired upstream, downstream, \nor remains unpaired. Such pair propsensity vectors can then be compared using \nstandard alignment algorithms. In contrast to RNApdist, RNApaln performs \nsimilarity (instead of distance) alignments, considers both sequence and \nstructure information, and uses affine (rather than linear) gap costs. RNApaln \ncan perform semi-local alignments by using free end gaps, a true local \nalignment mode is planned.\n\nThe same approach has since been used in the StraL program from Gerhard \nSteeger's group. Since StraL has optimized parameters and a multiple alignment \nmode, it be be currently the better option.\n";
32
33 const char *RNApaln_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   "  Below are command line options which alter the general behavior of this \n  program\n",
40   "  -B, --printAlignment[=filename]\n                                Print an \"alignment\" with gaps of the \n                                  profiles\n                                  The aligned structures are written to \n                                  filename, if specified\n                                  Otherwise output is written to stdout, unless \n                                  the -Xm option is set in which case \n                                  \"backtrack.file\" is used.\n                                    (default=`stdout')",
41   "  The following symbols are used:\n   (  )  essentially upstream (downstream) paired bases\n\n   {  }  weakly upstream (downstream) paired bases\n   |    strongly paired bases without preference\n\n   ,    weakly paired bases without preference\n   .    essentially unpaired bases.\n\n",
42   "      --noconv                  Do not automatically substitude nucleotide \n                                  \"T\" with \"U\"\n\n                                    (default=off)",
43   "\nAlgorithms:",
44   "  Select additional algorithms which should be included in the calculations.\n",
45   "  -X, --mode=pmfc               Set the alignment mode to be used\n",
46   "  The alignment mode is passed as a single character value. The following \n  options are available:\n  'p' - Compare the structures pairwise, that is first with 2nd, third with 4th \n  etc. This is the default.\n\n   'm'  - Calculate the distance matrix between all structures. The output is \n  formatted as a lower triangle matrix.\n\n   'f' - Compare each structure to the first one.\n\n   'c' - Compare continuously, that is i-th with (i+1)th structure.\n\n",
47   "\nModel Details:",
48   "      --gapo=open               Set the gap open penalty\n\n",
49   "      --gape=ext                Set the gap extension penalty\n\n",
50   "      --seqw=w                  Set the weight of sequence (compared to \n                                  structure) in the scoring function.\n\n",
51   "      --endgaps                 Use free end-gaps\n\n                                    (default=off)",
52   "  -T, --temp=DOUBLE             Rescale energy parameters to a temperature of \n                                  temp C. Default is 37C.\n\n",
53   "  -4, --noTetra                 Do not include special tabulated stabilizing \n                                  energies for tri-, tetra- and hexaloop \n                                  hairpins. Mostly for testing.\n\n                                    (default=off)",
54   "  -d, --dangles=INT             How to treat \"dangling end\" energies for \n                                  bases adjacent to helices in free ends and \n                                  multi-loops\n                                    (default=`2')",
55   "  \n  With -d1 only unpaired bases can participate in at most one dangling end, \n  this is the default for mfe folding but unsupported for the partition \n  function folding.\n\n  With -d2 this check is ignored, dangling energies will be added for the bases \n  adjacent to a helix on both sides in any case; this is the default for \n  partition function folding (-p).\n  The option -d0 ignores dangling ends altogether (mostly for debugging).\n  With -d3 mfe folding will allow coaxial stacking of adjacent helices in \n  multi-loops. At the moment the implementation will not allow coaxial stacking \n  of the two interior pairs in a loop of degree 3 and works only for mfe \n  folding.\n\n  Note that by default (as well as with -d1 and -d3) pf and mfe folding treat \n  dangling ends differently. Use -d2 in addition to -p to ensure that both \n  algorithms use the same energy model.\n\n",
56   "      --noLP                    Produce structures without lonely pairs \n                                  (helices of length 1).\n                                    (default=off)",
57   "  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",
58   "      --noGU                    Do not allow GU pairs\n\n                                    (default=off)",
59   "      --noClosingGU             Do not allow GU pairs at the end of helices\n\n                                    (default=off)",
60   "  -P, --paramFile=paramfile     Read energy parameters from paramfile, instead \n                                  of using the default parameter set.\n",
61   "  A sample parameter file should accompany your distribution.\n  See the RNAlib documentation for details on the file format.\n\n",
62   "      --nsp=STRING              Allow other pairs in addition to the usual \n                                  AU,GC,and GU pairs.\n",
63   "  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",
64   "  -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",
65   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n",
66     0
67 };
68 static void
69 init_full_help_array(void)
70 {
71   RNApaln_args_info_full_help[0] = RNApaln_args_info_detailed_help[0];
72   RNApaln_args_info_full_help[1] = RNApaln_args_info_detailed_help[1];
73   RNApaln_args_info_full_help[2] = RNApaln_args_info_detailed_help[2];
74   RNApaln_args_info_full_help[3] = RNApaln_args_info_detailed_help[3];
75   RNApaln_args_info_full_help[4] = RNApaln_args_info_detailed_help[4];
76   RNApaln_args_info_full_help[5] = RNApaln_args_info_detailed_help[5];
77   RNApaln_args_info_full_help[6] = RNApaln_args_info_detailed_help[6];
78   RNApaln_args_info_full_help[7] = RNApaln_args_info_detailed_help[8];
79   RNApaln_args_info_full_help[8] = RNApaln_args_info_detailed_help[9];
80   RNApaln_args_info_full_help[9] = RNApaln_args_info_detailed_help[10];
81   RNApaln_args_info_full_help[10] = RNApaln_args_info_detailed_help[11];
82   RNApaln_args_info_full_help[11] = RNApaln_args_info_detailed_help[13];
83   RNApaln_args_info_full_help[12] = RNApaln_args_info_detailed_help[14];
84   RNApaln_args_info_full_help[13] = RNApaln_args_info_detailed_help[15];
85   RNApaln_args_info_full_help[14] = RNApaln_args_info_detailed_help[16];
86   RNApaln_args_info_full_help[15] = RNApaln_args_info_detailed_help[17];
87   RNApaln_args_info_full_help[16] = RNApaln_args_info_detailed_help[18];
88   RNApaln_args_info_full_help[17] = RNApaln_args_info_detailed_help[19];
89   RNApaln_args_info_full_help[18] = RNApaln_args_info_detailed_help[20];
90   RNApaln_args_info_full_help[19] = RNApaln_args_info_detailed_help[22];
91   RNApaln_args_info_full_help[20] = RNApaln_args_info_detailed_help[24];
92   RNApaln_args_info_full_help[21] = RNApaln_args_info_detailed_help[25];
93   RNApaln_args_info_full_help[22] = RNApaln_args_info_detailed_help[26];
94   RNApaln_args_info_full_help[23] = RNApaln_args_info_detailed_help[28];
95   RNApaln_args_info_full_help[24] = RNApaln_args_info_detailed_help[30];
96   RNApaln_args_info_full_help[25] = RNApaln_args_info_detailed_help[31];
97   RNApaln_args_info_full_help[26] = 0; 
98   
99 }
100
101 const char *RNApaln_args_info_full_help[27];
102
103 static void
104 init_help_array(void)
105 {
106   RNApaln_args_info_help[0] = RNApaln_args_info_detailed_help[0];
107   RNApaln_args_info_help[1] = RNApaln_args_info_detailed_help[1];
108   RNApaln_args_info_help[2] = RNApaln_args_info_detailed_help[2];
109   RNApaln_args_info_help[3] = RNApaln_args_info_detailed_help[3];
110   RNApaln_args_info_help[4] = RNApaln_args_info_detailed_help[4];
111   RNApaln_args_info_help[5] = RNApaln_args_info_detailed_help[5];
112   RNApaln_args_info_help[6] = RNApaln_args_info_detailed_help[6];
113   RNApaln_args_info_help[7] = RNApaln_args_info_detailed_help[8];
114   RNApaln_args_info_help[8] = RNApaln_args_info_detailed_help[9];
115   RNApaln_args_info_help[9] = RNApaln_args_info_detailed_help[10];
116   RNApaln_args_info_help[10] = RNApaln_args_info_detailed_help[11];
117   RNApaln_args_info_help[11] = RNApaln_args_info_detailed_help[13];
118   RNApaln_args_info_help[12] = RNApaln_args_info_detailed_help[14];
119   RNApaln_args_info_help[13] = RNApaln_args_info_detailed_help[15];
120   RNApaln_args_info_help[14] = RNApaln_args_info_detailed_help[16];
121   RNApaln_args_info_help[15] = RNApaln_args_info_detailed_help[17];
122   RNApaln_args_info_help[16] = RNApaln_args_info_detailed_help[18];
123   RNApaln_args_info_help[17] = RNApaln_args_info_detailed_help[19];
124   RNApaln_args_info_help[18] = RNApaln_args_info_detailed_help[20];
125   RNApaln_args_info_help[19] = RNApaln_args_info_detailed_help[22];
126   RNApaln_args_info_help[20] = RNApaln_args_info_detailed_help[24];
127   RNApaln_args_info_help[21] = RNApaln_args_info_detailed_help[25];
128   RNApaln_args_info_help[22] = RNApaln_args_info_detailed_help[26];
129   RNApaln_args_info_help[23] = RNApaln_args_info_detailed_help[31];
130   RNApaln_args_info_help[24] = 0; 
131   
132 }
133
134 const char *RNApaln_args_info_help[25];
135
136 typedef enum {ARG_NO
137   , ARG_FLAG
138   , ARG_STRING
139   , ARG_INT
140   , ARG_FLOAT
141   , ARG_DOUBLE
142 } RNApaln_cmdline_parser_arg_type;
143
144 static
145 void clear_given (struct RNApaln_args_info *args_info);
146 static
147 void clear_args (struct RNApaln_args_info *args_info);
148
149 static int
150 RNApaln_cmdline_parser_internal (int argc, char **argv, struct RNApaln_args_info *args_info,
151                         struct RNApaln_cmdline_parser_params *params, const char *additional_error);
152
153
154 static char *
155 gengetopt_strdup (const char *s);
156
157 static
158 void clear_given (struct RNApaln_args_info *args_info)
159 {
160   args_info->help_given = 0 ;
161   args_info->detailed_help_given = 0 ;
162   args_info->full_help_given = 0 ;
163   args_info->version_given = 0 ;
164   args_info->printAlignment_given = 0 ;
165   args_info->noconv_given = 0 ;
166   args_info->mode_given = 0 ;
167   args_info->gapo_given = 0 ;
168   args_info->gape_given = 0 ;
169   args_info->seqw_given = 0 ;
170   args_info->endgaps_given = 0 ;
171   args_info->temp_given = 0 ;
172   args_info->noTetra_given = 0 ;
173   args_info->dangles_given = 0 ;
174   args_info->noLP_given = 0 ;
175   args_info->noGU_given = 0 ;
176   args_info->noClosingGU_given = 0 ;
177   args_info->paramFile_given = 0 ;
178   args_info->nsp_given = 0 ;
179   args_info->energyModel_given = 0 ;
180 }
181
182 static
183 void clear_args (struct RNApaln_args_info *args_info)
184 {
185   FIX_UNUSED (args_info);
186   args_info->printAlignment_arg = gengetopt_strdup ("stdout");
187   args_info->printAlignment_orig = NULL;
188   args_info->noconv_flag = 0;
189   args_info->mode_arg = NULL;
190   args_info->mode_orig = NULL;
191   args_info->gapo_orig = NULL;
192   args_info->gape_orig = NULL;
193   args_info->seqw_orig = NULL;
194   args_info->endgaps_flag = 0;
195   args_info->temp_orig = NULL;
196   args_info->noTetra_flag = 0;
197   args_info->dangles_arg = 2;
198   args_info->dangles_orig = NULL;
199   args_info->noLP_flag = 0;
200   args_info->noGU_flag = 0;
201   args_info->noClosingGU_flag = 0;
202   args_info->paramFile_arg = NULL;
203   args_info->paramFile_orig = NULL;
204   args_info->nsp_arg = NULL;
205   args_info->nsp_orig = NULL;
206   args_info->energyModel_orig = NULL;
207   
208 }
209
210 static
211 void init_args_info(struct RNApaln_args_info *args_info)
212 {
213   init_full_help_array(); 
214   init_help_array(); 
215   args_info->help_help = RNApaln_args_info_detailed_help[0] ;
216   args_info->detailed_help_help = RNApaln_args_info_detailed_help[1] ;
217   args_info->full_help_help = RNApaln_args_info_detailed_help[2] ;
218   args_info->version_help = RNApaln_args_info_detailed_help[3] ;
219   args_info->printAlignment_help = RNApaln_args_info_detailed_help[6] ;
220   args_info->noconv_help = RNApaln_args_info_detailed_help[8] ;
221   args_info->mode_help = RNApaln_args_info_detailed_help[11] ;
222   args_info->gapo_help = RNApaln_args_info_detailed_help[14] ;
223   args_info->gape_help = RNApaln_args_info_detailed_help[15] ;
224   args_info->seqw_help = RNApaln_args_info_detailed_help[16] ;
225   args_info->endgaps_help = RNApaln_args_info_detailed_help[17] ;
226   args_info->temp_help = RNApaln_args_info_detailed_help[18] ;
227   args_info->noTetra_help = RNApaln_args_info_detailed_help[19] ;
228   args_info->dangles_help = RNApaln_args_info_detailed_help[20] ;
229   args_info->noLP_help = RNApaln_args_info_detailed_help[22] ;
230   args_info->noGU_help = RNApaln_args_info_detailed_help[24] ;
231   args_info->noClosingGU_help = RNApaln_args_info_detailed_help[25] ;
232   args_info->paramFile_help = RNApaln_args_info_detailed_help[26] ;
233   args_info->nsp_help = RNApaln_args_info_detailed_help[28] ;
234   args_info->energyModel_help = RNApaln_args_info_detailed_help[30] ;
235   
236 }
237
238 void
239 RNApaln_cmdline_parser_print_version (void)
240 {
241   printf ("%s %s\n",
242      (strlen(RNAPALN_CMDLINE_PARSER_PACKAGE_NAME) ? RNAPALN_CMDLINE_PARSER_PACKAGE_NAME : RNAPALN_CMDLINE_PARSER_PACKAGE),
243      RNAPALN_CMDLINE_PARSER_VERSION);
244 }
245
246 static void print_help_common(void) {
247   RNApaln_cmdline_parser_print_version ();
248
249   if (strlen(RNApaln_args_info_purpose) > 0)
250     printf("\n%s\n", RNApaln_args_info_purpose);
251
252   if (strlen(RNApaln_args_info_usage) > 0)
253     printf("\n%s\n", RNApaln_args_info_usage);
254
255   printf("\n");
256
257   if (strlen(RNApaln_args_info_description) > 0)
258     printf("%s\n\n", RNApaln_args_info_description);
259 }
260
261 void
262 RNApaln_cmdline_parser_print_help (void)
263 {
264   int i = 0;
265   print_help_common();
266   while (RNApaln_args_info_help[i])
267     printf("%s\n", RNApaln_args_info_help[i++]);
268 }
269
270 void
271 RNApaln_cmdline_parser_print_full_help (void)
272 {
273   int i = 0;
274   print_help_common();
275   while (RNApaln_args_info_full_help[i])
276     printf("%s\n", RNApaln_args_info_full_help[i++]);
277 }
278
279 void
280 RNApaln_cmdline_parser_print_detailed_help (void)
281 {
282   int i = 0;
283   print_help_common();
284   while (RNApaln_args_info_detailed_help[i])
285     printf("%s\n", RNApaln_args_info_detailed_help[i++]);
286 }
287
288 void
289 RNApaln_cmdline_parser_init (struct RNApaln_args_info *args_info)
290 {
291   clear_given (args_info);
292   clear_args (args_info);
293   init_args_info (args_info);
294 }
295
296 void
297 RNApaln_cmdline_parser_params_init(struct RNApaln_cmdline_parser_params *params)
298 {
299   if (params)
300     { 
301       params->override = 0;
302       params->initialize = 1;
303       params->check_required = 1;
304       params->check_ambiguity = 0;
305       params->print_errors = 1;
306     }
307 }
308
309 struct RNApaln_cmdline_parser_params *
310 RNApaln_cmdline_parser_params_create(void)
311 {
312   struct RNApaln_cmdline_parser_params *params = 
313     (struct RNApaln_cmdline_parser_params *)malloc(sizeof(struct RNApaln_cmdline_parser_params));
314   RNApaln_cmdline_parser_params_init(params);  
315   return params;
316 }
317
318 static void
319 free_string_field (char **s)
320 {
321   if (*s)
322     {
323       free (*s);
324       *s = 0;
325     }
326 }
327
328
329 static void
330 RNApaln_cmdline_parser_release (struct RNApaln_args_info *args_info)
331 {
332
333   free_string_field (&(args_info->printAlignment_arg));
334   free_string_field (&(args_info->printAlignment_orig));
335   free_string_field (&(args_info->mode_arg));
336   free_string_field (&(args_info->mode_orig));
337   free_string_field (&(args_info->gapo_orig));
338   free_string_field (&(args_info->gape_orig));
339   free_string_field (&(args_info->seqw_orig));
340   free_string_field (&(args_info->temp_orig));
341   free_string_field (&(args_info->dangles_orig));
342   free_string_field (&(args_info->paramFile_arg));
343   free_string_field (&(args_info->paramFile_orig));
344   free_string_field (&(args_info->nsp_arg));
345   free_string_field (&(args_info->nsp_orig));
346   free_string_field (&(args_info->energyModel_orig));
347   
348   
349
350   clear_given (args_info);
351 }
352
353
354 static void
355 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
356 {
357   FIX_UNUSED (values);
358   if (arg) {
359     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
360   } else {
361     fprintf(outfile, "%s\n", opt);
362   }
363 }
364
365
366 int
367 RNApaln_cmdline_parser_dump(FILE *outfile, struct RNApaln_args_info *args_info)
368 {
369   int i = 0;
370
371   if (!outfile)
372     {
373       fprintf (stderr, "%s: cannot dump options to stream\n", RNAPALN_CMDLINE_PARSER_PACKAGE);
374       return EXIT_FAILURE;
375     }
376
377   if (args_info->help_given)
378     write_into_file(outfile, "help", 0, 0 );
379   if (args_info->detailed_help_given)
380     write_into_file(outfile, "detailed-help", 0, 0 );
381   if (args_info->full_help_given)
382     write_into_file(outfile, "full-help", 0, 0 );
383   if (args_info->version_given)
384     write_into_file(outfile, "version", 0, 0 );
385   if (args_info->printAlignment_given)
386     write_into_file(outfile, "printAlignment", args_info->printAlignment_orig, 0);
387   if (args_info->noconv_given)
388     write_into_file(outfile, "noconv", 0, 0 );
389   if (args_info->mode_given)
390     write_into_file(outfile, "mode", args_info->mode_orig, 0);
391   if (args_info->gapo_given)
392     write_into_file(outfile, "gapo", args_info->gapo_orig, 0);
393   if (args_info->gape_given)
394     write_into_file(outfile, "gape", args_info->gape_orig, 0);
395   if (args_info->seqw_given)
396     write_into_file(outfile, "seqw", args_info->seqw_orig, 0);
397   if (args_info->endgaps_given)
398     write_into_file(outfile, "endgaps", 0, 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, 0);
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 RNApaln_cmdline_parser_file_save(const char *filename, struct RNApaln_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", RNAPALN_CMDLINE_PARSER_PACKAGE, filename);
434       return EXIT_FAILURE;
435     }
436
437   i = RNApaln_cmdline_parser_dump(outfile, args_info);
438   fclose (outfile);
439
440   return i;
441 }
442
443 void
444 RNApaln_cmdline_parser_free (struct RNApaln_args_info *args_info)
445 {
446   RNApaln_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 RNApaln_cmdline_parser (int argc, char **argv, struct RNApaln_args_info *args_info)
466 {
467   return RNApaln_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
468 }
469
470 int
471 RNApaln_cmdline_parser_ext (int argc, char **argv, struct RNApaln_args_info *args_info,
472                    struct RNApaln_cmdline_parser_params *params)
473 {
474   int result;
475   result = RNApaln_cmdline_parser_internal (argc, argv, args_info, params, 0);
476
477   if (result == EXIT_FAILURE)
478     {
479       RNApaln_cmdline_parser_free (args_info);
480       exit (EXIT_FAILURE);
481     }
482   
483   return result;
484 }
485
486 int
487 RNApaln_cmdline_parser2 (int argc, char **argv, struct RNApaln_args_info *args_info, int override, int initialize, int check_required)
488 {
489   int result;
490   struct RNApaln_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 = RNApaln_cmdline_parser_internal (argc, argv, args_info, &params, 0);
499
500   if (result == EXIT_FAILURE)
501     {
502       RNApaln_cmdline_parser_free (args_info);
503       exit (EXIT_FAILURE);
504     }
505   
506   return result;
507 }
508
509 int
510 RNApaln_cmdline_parser_required (struct RNApaln_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 RNApaln_cmdline_parser_params.check_ambiguity
1123  * @param override @see RNApaln_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                RNApaln_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   FIX_UNUSED (default_value);
1164     
1165   if (field_given && *field_given && ! override)
1166     return 0;
1167   if (prev_given)
1168     (*prev_given)++;
1169   if (field_given)
1170     (*field_given)++;
1171   if (possible_values)
1172     val = possible_values[found];
1173
1174   switch(arg_type) {
1175   case ARG_FLAG:
1176     *((int *)field) = !*((int *)field);
1177     break;
1178   case ARG_INT:
1179     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1180     break;
1181   case ARG_FLOAT:
1182     if (val) *((float *)field) = (float)strtod (val, &stop_char);
1183     break;
1184   case ARG_DOUBLE:
1185     if (val) *((double *)field) = strtod (val, &stop_char);
1186     break;
1187   case ARG_STRING:
1188     if (val) {
1189       string_field = (char **)field;
1190       if (!no_free && *string_field)
1191         free (*string_field); /* free previous string */
1192       *string_field = gengetopt_strdup (val);
1193     }
1194     break;
1195   default:
1196     break;
1197   };
1198
1199   /* check numeric conversion */
1200   switch(arg_type) {
1201   case ARG_INT:
1202   case ARG_FLOAT:
1203   case ARG_DOUBLE:
1204     if (val && !(stop_char && *stop_char == '\0')) {
1205       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1206       return 1; /* failure */
1207     }
1208     break;
1209   default:
1210     ;
1211   };
1212
1213   /* store the original value */
1214   switch(arg_type) {
1215   case ARG_NO:
1216   case ARG_FLAG:
1217     break;
1218   default:
1219     if (value && orig_field) {
1220       if (no_free) {
1221         *orig_field = value;
1222       } else {
1223         if (*orig_field)
1224           free (*orig_field); /* free previous string */
1225         *orig_field = gengetopt_strdup (value);
1226       }
1227     }
1228   };
1229
1230   return 0; /* OK */
1231 }
1232
1233
1234 int
1235 RNApaln_cmdline_parser_internal (
1236   int argc, char **argv, struct RNApaln_args_info *args_info,
1237                         struct RNApaln_cmdline_parser_params *params, const char *additional_error)
1238 {
1239   int c;        /* Character of the parsed option.  */
1240
1241   int error = 0;
1242   struct RNApaln_args_info local_args_info;
1243   
1244   int override;
1245   int initialize;
1246   int check_required;
1247   int check_ambiguity;
1248
1249   char *optarg;
1250   int optind;
1251   int opterr;
1252   int optopt;
1253   
1254   package_name = argv[0];
1255   
1256   override = params->override;
1257   initialize = params->initialize;
1258   check_required = params->check_required;
1259   check_ambiguity = params->check_ambiguity;
1260
1261   if (initialize)
1262     RNApaln_cmdline_parser_init (args_info);
1263
1264   RNApaln_cmdline_parser_init (&local_args_info);
1265
1266   optarg = 0;
1267   optind = 0;
1268   opterr = params->print_errors;
1269   optopt = '?';
1270
1271   while (1)
1272     {
1273       int option_index = 0;
1274
1275       static struct option long_options[] = {
1276         { "help",       0, NULL, 'h' },
1277         { "detailed-help",      0, NULL, 0 },
1278         { "full-help",  0, NULL, 0 },
1279         { "version",    0, NULL, 'V' },
1280         { "printAlignment",     2, NULL, 'B' },
1281         { "noconv",     0, NULL, 0 },
1282         { "mode",       1, NULL, 'X' },
1283         { "gapo",       1, NULL, 0 },
1284         { "gape",       1, NULL, 0 },
1285         { "seqw",       1, NULL, 0 },
1286         { "endgaps",    0, NULL, 0 },
1287         { "temp",       1, NULL, 'T' },
1288         { "noTetra",    0, NULL, '4' },
1289         { "dangles",    1, NULL, 'd' },
1290         { "noLP",       0, NULL, 0 },
1291         { "noGU",       0, NULL, 0 },
1292         { "noClosingGU",        0, NULL, 0 },
1293         { "paramFile",  1, NULL, 'P' },
1294         { "nsp",        1, NULL, 0 },
1295         { "energyModel",        1, NULL, 'e' },
1296         { 0,  0, 0, 0 }
1297       };
1298
1299       custom_optarg = optarg;
1300       custom_optind = optind;
1301       custom_opterr = opterr;
1302       custom_optopt = optopt;
1303
1304       c = custom_getopt_long (argc, argv, "hVB::X:T:4d:P:e:", long_options, &option_index);
1305
1306       optarg = custom_optarg;
1307       optind = custom_optind;
1308       opterr = custom_opterr;
1309       optopt = custom_optopt;
1310
1311       if (c == -1) break;       /* Exit from `while (1)' loop.  */
1312
1313       switch (c)
1314         {
1315         case 'h':       /* Print help and exit.  */
1316           RNApaln_cmdline_parser_print_help ();
1317           RNApaln_cmdline_parser_free (&local_args_info);
1318           exit (EXIT_SUCCESS);
1319
1320         case 'V':       /* Print version and exit.  */
1321           RNApaln_cmdline_parser_print_version ();
1322           RNApaln_cmdline_parser_free (&local_args_info);
1323           exit (EXIT_SUCCESS);
1324
1325         case 'B':       /* Print an \"alignment\" with gaps of the profiles
1326         The aligned structures are written to filename, if specified
1327         Otherwise output is written to stdout, unless the -Xm option is set in which case \"backtrack.file\" is used.
1328 .  */
1329         
1330         
1331           if (update_arg( (void *)&(args_info->printAlignment_arg), 
1332                &(args_info->printAlignment_orig), &(args_info->printAlignment_given),
1333               &(local_args_info.printAlignment_given), optarg, 0, "stdout", ARG_STRING,
1334               check_ambiguity, override, 0, 0,
1335               "printAlignment", 'B',
1336               additional_error))
1337             goto failure;
1338         
1339           break;
1340         case 'X':       /* Set the alignment mode to be used
1341 .  */
1342         
1343         
1344           if (update_arg( (void *)&(args_info->mode_arg), 
1345                &(args_info->mode_orig), &(args_info->mode_given),
1346               &(local_args_info.mode_given), optarg, 0, 0, ARG_STRING,
1347               check_ambiguity, override, 0, 0,
1348               "mode", 'X',
1349               additional_error))
1350             goto failure;
1351         
1352           break;
1353         case 'T':       /* Rescale energy parameters to a temperature of temp C. Default is 37C.
1354         
1355 .  */
1356         
1357         
1358           if (update_arg( (void *)&(args_info->temp_arg), 
1359                &(args_info->temp_orig), &(args_info->temp_given),
1360               &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
1361               check_ambiguity, override, 0, 0,
1362               "temp", 'T',
1363               additional_error))
1364             goto failure;
1365         
1366           break;
1367         case '4':       /* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins. Mostly for testing.
1368         
1369 .  */
1370         
1371         
1372           if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
1373               &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
1374               check_ambiguity, override, 1, 0, "noTetra", '4',
1375               additional_error))
1376             goto failure;
1377         
1378           break;
1379         case 'd':       /* How to treat \"dangling end\" energies for bases adjacent to helices in free ends and multi-loops
1380 .  */
1381         
1382         
1383           if (update_arg( (void *)&(args_info->dangles_arg), 
1384                &(args_info->dangles_orig), &(args_info->dangles_given),
1385               &(local_args_info.dangles_given), optarg, 0, "2", ARG_INT,
1386               check_ambiguity, override, 0, 0,
1387               "dangles", 'd',
1388               additional_error))
1389             goto failure;
1390         
1391           break;
1392         case 'P':       /* Read energy parameters from paramfile, instead of using the default parameter set.
1393 .  */
1394         
1395         
1396           if (update_arg( (void *)&(args_info->paramFile_arg), 
1397                &(args_info->paramFile_orig), &(args_info->paramFile_given),
1398               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1399               check_ambiguity, override, 0, 0,
1400               "paramFile", 'P',
1401               additional_error))
1402             goto failure;
1403         
1404           break;
1405         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.
1406         
1407 .  */
1408         
1409         
1410           if (update_arg( (void *)&(args_info->energyModel_arg), 
1411                &(args_info->energyModel_orig), &(args_info->energyModel_given),
1412               &(local_args_info.energyModel_given), optarg, 0, 0, ARG_INT,
1413               check_ambiguity, override, 0, 0,
1414               "energyModel", 'e',
1415               additional_error))
1416             goto failure;
1417         
1418           break;
1419
1420         case 0: /* Long option with no short option */
1421           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1422             RNApaln_cmdline_parser_print_detailed_help ();
1423             RNApaln_cmdline_parser_free (&local_args_info);
1424             exit (EXIT_SUCCESS);
1425           }
1426
1427           if (strcmp (long_options[option_index].name, "full-help") == 0) {
1428             RNApaln_cmdline_parser_print_full_help ();
1429             RNApaln_cmdline_parser_free (&local_args_info);
1430             exit (EXIT_SUCCESS);
1431           }
1432
1433           /* Do not automatically substitude nucleotide \"T\" with \"U\"
1434           
1435 .  */
1436           if (strcmp (long_options[option_index].name, "noconv") == 0)
1437           {
1438           
1439           
1440             if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
1441                 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
1442                 check_ambiguity, override, 1, 0, "noconv", '-',
1443                 additional_error))
1444               goto failure;
1445           
1446           }
1447           /* Set the gap open penalty
1448           
1449 .  */
1450           else if (strcmp (long_options[option_index].name, "gapo") == 0)
1451           {
1452           
1453           
1454             if (update_arg( (void *)&(args_info->gapo_arg), 
1455                  &(args_info->gapo_orig), &(args_info->gapo_given),
1456                 &(local_args_info.gapo_given), optarg, 0, 0, ARG_FLOAT,
1457                 check_ambiguity, override, 0, 0,
1458                 "gapo", '-',
1459                 additional_error))
1460               goto failure;
1461           
1462           }
1463           /* Set the gap extension penalty
1464           
1465 .  */
1466           else if (strcmp (long_options[option_index].name, "gape") == 0)
1467           {
1468           
1469           
1470             if (update_arg( (void *)&(args_info->gape_arg), 
1471                  &(args_info->gape_orig), &(args_info->gape_given),
1472                 &(local_args_info.gape_given), optarg, 0, 0, ARG_FLOAT,
1473                 check_ambiguity, override, 0, 0,
1474                 "gape", '-',
1475                 additional_error))
1476               goto failure;
1477           
1478           }
1479           /* Set the weight of sequence (compared to structure) in the scoring function.
1480           
1481 .  */
1482           else if (strcmp (long_options[option_index].name, "seqw") == 0)
1483           {
1484           
1485           
1486             if (update_arg( (void *)&(args_info->seqw_arg), 
1487                  &(args_info->seqw_orig), &(args_info->seqw_given),
1488                 &(local_args_info.seqw_given), optarg, 0, 0, ARG_FLOAT,
1489                 check_ambiguity, override, 0, 0,
1490                 "seqw", '-',
1491                 additional_error))
1492               goto failure;
1493           
1494           }
1495           /* Use free end-gaps
1496           
1497 .  */
1498           else if (strcmp (long_options[option_index].name, "endgaps") == 0)
1499           {
1500           
1501           
1502             if (update_arg((void *)&(args_info->endgaps_flag), 0, &(args_info->endgaps_given),
1503                 &(local_args_info.endgaps_given), optarg, 0, 0, ARG_FLAG,
1504                 check_ambiguity, override, 1, 0, "endgaps", '-',
1505                 additional_error))
1506               goto failure;
1507           
1508           }
1509           /* Produce structures without lonely pairs (helices of length 1).
1510 .  */
1511           else if (strcmp (long_options[option_index].name, "noLP") == 0)
1512           {
1513           
1514           
1515             if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
1516                 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
1517                 check_ambiguity, override, 1, 0, "noLP", '-',
1518                 additional_error))
1519               goto failure;
1520           
1521           }
1522           /* Do not allow GU pairs
1523           
1524 .  */
1525           else if (strcmp (long_options[option_index].name, "noGU") == 0)
1526           {
1527           
1528           
1529             if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
1530                 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
1531                 check_ambiguity, override, 1, 0, "noGU", '-',
1532                 additional_error))
1533               goto failure;
1534           
1535           }
1536           /* Do not allow GU pairs at the end of helices
1537           
1538 .  */
1539           else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
1540           {
1541           
1542           
1543             if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
1544                 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
1545                 check_ambiguity, override, 1, 0, "noClosingGU", '-',
1546                 additional_error))
1547               goto failure;
1548           
1549           }
1550           /* Allow other pairs in addition to the usual AU,GC,and GU pairs.
1551 .  */
1552           else if (strcmp (long_options[option_index].name, "nsp") == 0)
1553           {
1554           
1555           
1556             if (update_arg( (void *)&(args_info->nsp_arg), 
1557                  &(args_info->nsp_orig), &(args_info->nsp_given),
1558                 &(local_args_info.nsp_given), optarg, 0, 0, ARG_STRING,
1559                 check_ambiguity, override, 0, 0,
1560                 "nsp", '-',
1561                 additional_error))
1562               goto failure;
1563           
1564           }
1565           
1566           break;
1567         case '?':       /* Invalid option.  */
1568           /* `getopt_long' already printed an error message.  */
1569           goto failure;
1570
1571         default:        /* bug: option not considered.  */
1572           fprintf (stderr, "%s: option unknown: %c%s\n", RNAPALN_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1573           abort ();
1574         } /* switch */
1575     } /* while */
1576
1577
1578
1579
1580   RNApaln_cmdline_parser_release (&local_args_info);
1581
1582   if ( error )
1583     return (EXIT_FAILURE);
1584
1585   return 0;
1586
1587 failure:
1588   
1589   RNApaln_cmdline_parser_release (&local_args_info);
1590   return (EXIT_FAILURE);
1591 }