New Linux binaries for ViennaRNA
[jabaws.git] / binaries / src / ViennaRNA / Progs / RNAplex_cmdl.c
1 /*
2   File autogenerated by gengetopt version 2.22.5
3   generated with the following command:
4   gengetopt -i RNAplex.ggo --file-name=RNAplex_cmdl --include-getopt --default-optional --func-name=RNAplex_cmdline_parser --arg-struct-name=RNAplex_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 "RNAplex_cmdl.h"
26
27 const char *RNAplex_args_info_purpose = "Find targets of a query RNA";
28
29 const char *RNAplex_args_info_usage = "Usage: RNAplex [options]\n";
30
31 const char *RNAplex_args_info_description = "reads two RNA sequences from stdin or <filename> and computes optimal and \nsuboptimal secondary structures for their hybridization. The calculation is \nsimplified by allowing only inter-molecular base pairs. Accessibility effects \ncan be estimated by RNAplex if a RNAplfold accessibility profile is provided. \nThe computed optimal and suboptimal structure are written to stdout, one \nstructure per line. Each line consist of: The structure in dot bracket format \nwith a \"&\" separating the two strands. The range of the structure in the two \nsequences in the format  \"from,to : from,to\"; the energy of duplex structure \nin kcal/mol.\nThe format is especially useful for computing the hybrid structure between a \nsmall probe sequence and a long target sequence.\n";
32
33 const char *RNAplex_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   "      --version                 Print version and exit",
37   "\nInput Options:",
38   "  Below are command line options which alter the general input behavior of this \n  program\n",
39   "  -q, --query=STRING            File containing the query sequence.\n",
40   "  Input sequences can be given piped to RNAplex or given in a query file with \n  the -q option. Note that the -q option implies that the -t option is also \n  used\n\n",
41   "  -t, --target=STRING           File containing the target sequence.\n",
42   "  Input sequences can be given piped to RNAplex or given in a target file with \n  the -t option. Note that the -t option implies that the -q option is also \n  used\n\n",
43   "  -a, --accessibility-dir=STRING\n                                Location of the accessibility profiles.\n",
44   "  This option switches the accessibility modes on and indicates in which \n  directory accessibility profiles as generated by RNAplfold can be found\n\n",
45   "  -b, --binary                  Allow the reading and parsing of memory dumped \n                                  opening energy file\n                                    (default=off)",
46   "  The -b option allows to read and process opening energy files which are saved \n  in binary format\n   This can reduce by a factor of 500x-1000x the time needed to process those \n  files. RNAplex recognizes the corresponding opening energy files by looking \n  for files named after the sequence and containing the suffix _openen_bin. \n  Please look at the man page of RNAplfold if you need more information on how \n  to produce binary opening energy files.\n\n",
47   "  -P, --paramFile=paramfile     Read energy parameters from paramfile, instead \n                                  of using the default parameter set.\n",
48   "  A sample parameter file should accompany your distribution.\n  See the RNAlib documentation for details on the file format.\n\n",
49   "\nAlgorithms:",
50   "  Options which alter the computing behaviour of RNAplex.\n",
51   "  -T, --temp=DOUBLE             Rescale energy parameters to a temperature T. \n                                  Default is 37C.\n\n",
52   "  -l, --interaction-length=INT  Maximal length of an interaction\n                                    (default=`40')",
53   "  Maximal allowed length of an interaction\n\n",
54   "  -c, --extension-cost=INT      Cost to add to each nucleotide in a duplex\n                                    (default=`0')",
55   "  Cost of extending a duplex by one nucleotide. Allows to find compact \n  duplexes, having few/small bulges or interior loops Only useful when no \n  accessibility profiles are available. This option is disabled if \n  accessibility profiles are used (-a option)\n\n",
56   "  -p, --probe-mode              Compute Tm for probes  (default=off)",
57   "  Use this option if you want to compute the melting temperature of your probes\n\n",
58   "  -Q, --probe-concentration=DOUBLE\n                                Set the probe concentration for the Tm \n                                  computation\n\n                                    (default=`0.1')",
59   "  -N, --na-concentration=DOUBLE Set the Na+ concentration for the Tm \n                                  computation\n\n                                    (default=`1.0')",
60   "  -M, --mg-concentration=DOUBLE Set the Mg2+ concentration for the Tm \n                                  computation\n\n                                    (default=`1.0')",
61   "  -K, --k-concentration=DOUBLE  Set the K+ concentration for the Tm computation\n\n                                    (default=`1.0')",
62   "  -U, --tris-concentration=DOUBLE\n                                Set the tris+ concentration for the Tm \n                                  computation\n\n                                    (default=`1.0')",
63   "  -f, --fast-folding=INT        Speedup of the target search\n                                    (default=`0')",
64   "  This option allows to decide if the backtracking has to be done (-f 0, -f 2) \n  or not (-f 1). For -f 0 the structure is computed based on the standard \n  energy model. This is the slowest and most precise mode of RNAplex. With -f \n  2, the structure is computed based on the approximated plex model. If a lot \n  of targets are returned this is can greatly improve the runtime of RNAplex. \n  -f 1 is the fastest mode, as no structure are recomputed \n\n",
65   "  -V, --scale-accessibility=DOUBLE\n                                Rescale all opening energy by a factor V\n                                    (default=`1.0')",
66   "  Scale-factor for the accessibility. If V is set to 1 then the scaling has no \n  effect on the accessibility.\n\n",
67   "  -C, --constraint              Calculate structures subject to constraints.\n                                    (default=off)",
68   "  The program reads first the sequence, then a string containing constraints on \n  the structure for the query sequence encoded with the symbols:\n  . (no constraint for this base)\n  | (the corresponding base has to be paired)\n\n",
69   "  -A, --alignment-mode          Tells RNAplex to compute interactions based on \n                                  alignments\n                                    (default=off)",
70   "  If the A option is set RNAplex expects clustalw files as input for the -q and \n  -t option.\n\n",
71   "  -k, --convert-to-bin          If set, RNAplex will convert all opening energy \n                                  file in a directory set by the -a option into \n                                  binary opening energy files\n                                    (default=off)",
72   "  RNAplex can be used to convert existing text formatted opening energy files \n  into binary formatted files. In this mode RNAplex does not compute \n  interactions.\n\n",
73   "\nOutput:",
74   "  Options that modify the output\n",
75   "  -z, --duplex-distance=INT     Distance between target 3' ends of two \n                                  consecutive duplexes\n                                    (default=`0')",
76   "  Distance between the target 3'ends of two consecutive duplexes. Should be set \n  to the maximal length of interaction to get good results\n   Smaller z leads to larger overlaps between consecutive duplexes.\n\n",
77   "  -e, --energy-threshold=DOUBLE Minimal energy for a duplex to be returned\n                                    (default=`-100000')",
78   "  Energy threshold for a duplex to be returned. The threshold is set on the \n  total energy of interaction, i.e. the hybridization energy corrected for \n  opening energy if -a is set or the energy corrected by -c. If unset, only the \n  mfe will be returned\n\n",
79   "  -I, --produce-ps=STRING       Draw an alignment annotated interaction from \n                                  RNAplex\n",
80   "  This option allows to produce interaction figures in PS-format a la \n  RNAalifold, where base-pair conservation is represented in color-coded \n  format. In this mode no interaction are computed, but the -I option indicates \n  the location of the file containing interactions between two RNA \n  (alignments/sequence) from a previous run. If the -A option is not set a \n  structure figure a la RNAfold with color-coded annotation of the \n  accessibilities is returned\n\n",
81   "  -L, --WindowLength=INT        Tells how large the region around the target \n                                  site should be for redrawing the alignment \n                                  interaction\n                                    (default=`1')",
82   "  This option allow to specify how large the region surrounding the target site \n  should be set when generating the alignment figure of the interaction\n\n",
83   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n",
84     0
85 };
86
87 static void
88 init_help_array(void)
89 {
90   RNAplex_args_info_help[0] = RNAplex_args_info_detailed_help[0];
91   RNAplex_args_info_help[1] = RNAplex_args_info_detailed_help[1];
92   RNAplex_args_info_help[2] = RNAplex_args_info_detailed_help[2];
93   RNAplex_args_info_help[3] = RNAplex_args_info_detailed_help[3];
94   RNAplex_args_info_help[4] = RNAplex_args_info_detailed_help[4];
95   RNAplex_args_info_help[5] = RNAplex_args_info_detailed_help[5];
96   RNAplex_args_info_help[6] = RNAplex_args_info_detailed_help[7];
97   RNAplex_args_info_help[7] = RNAplex_args_info_detailed_help[9];
98   RNAplex_args_info_help[8] = RNAplex_args_info_detailed_help[11];
99   RNAplex_args_info_help[9] = RNAplex_args_info_detailed_help[13];
100   RNAplex_args_info_help[10] = RNAplex_args_info_detailed_help[15];
101   RNAplex_args_info_help[11] = RNAplex_args_info_detailed_help[16];
102   RNAplex_args_info_help[12] = RNAplex_args_info_detailed_help[17];
103   RNAplex_args_info_help[13] = RNAplex_args_info_detailed_help[18];
104   RNAplex_args_info_help[14] = RNAplex_args_info_detailed_help[20];
105   RNAplex_args_info_help[15] = RNAplex_args_info_detailed_help[22];
106   RNAplex_args_info_help[16] = RNAplex_args_info_detailed_help[24];
107   RNAplex_args_info_help[17] = RNAplex_args_info_detailed_help[25];
108   RNAplex_args_info_help[18] = RNAplex_args_info_detailed_help[26];
109   RNAplex_args_info_help[19] = RNAplex_args_info_detailed_help[27];
110   RNAplex_args_info_help[20] = RNAplex_args_info_detailed_help[28];
111   RNAplex_args_info_help[21] = RNAplex_args_info_detailed_help[29];
112   RNAplex_args_info_help[22] = RNAplex_args_info_detailed_help[31];
113   RNAplex_args_info_help[23] = RNAplex_args_info_detailed_help[33];
114   RNAplex_args_info_help[24] = RNAplex_args_info_detailed_help[35];
115   RNAplex_args_info_help[25] = RNAplex_args_info_detailed_help[37];
116   RNAplex_args_info_help[26] = RNAplex_args_info_detailed_help[39];
117   RNAplex_args_info_help[27] = RNAplex_args_info_detailed_help[40];
118   RNAplex_args_info_help[28] = RNAplex_args_info_detailed_help[41];
119   RNAplex_args_info_help[29] = RNAplex_args_info_detailed_help[43];
120   RNAplex_args_info_help[30] = RNAplex_args_info_detailed_help[45];
121   RNAplex_args_info_help[31] = RNAplex_args_info_detailed_help[47];
122   RNAplex_args_info_help[32] = RNAplex_args_info_detailed_help[49];
123   RNAplex_args_info_help[33] = 0; 
124   
125 }
126
127 const char *RNAplex_args_info_help[34];
128
129 typedef enum {ARG_NO
130   , ARG_FLAG
131   , ARG_STRING
132   , ARG_INT
133   , ARG_DOUBLE
134 } RNAplex_cmdline_parser_arg_type;
135
136 static
137 void clear_given (struct RNAplex_args_info *args_info);
138 static
139 void clear_args (struct RNAplex_args_info *args_info);
140
141 static int
142 RNAplex_cmdline_parser_internal (int argc, char **argv, struct RNAplex_args_info *args_info,
143                         struct RNAplex_cmdline_parser_params *params, const char *additional_error);
144
145
146 static char *
147 gengetopt_strdup (const char *s);
148
149 static
150 void clear_given (struct RNAplex_args_info *args_info)
151 {
152   args_info->help_given = 0 ;
153   args_info->detailed_help_given = 0 ;
154   args_info->version_given = 0 ;
155   args_info->query_given = 0 ;
156   args_info->target_given = 0 ;
157   args_info->accessibility_dir_given = 0 ;
158   args_info->binary_given = 0 ;
159   args_info->paramFile_given = 0 ;
160   args_info->temp_given = 0 ;
161   args_info->interaction_length_given = 0 ;
162   args_info->extension_cost_given = 0 ;
163   args_info->probe_mode_given = 0 ;
164   args_info->probe_concentration_given = 0 ;
165   args_info->na_concentration_given = 0 ;
166   args_info->mg_concentration_given = 0 ;
167   args_info->k_concentration_given = 0 ;
168   args_info->tris_concentration_given = 0 ;
169   args_info->fast_folding_given = 0 ;
170   args_info->scale_accessibility_given = 0 ;
171   args_info->constraint_given = 0 ;
172   args_info->alignment_mode_given = 0 ;
173   args_info->convert_to_bin_given = 0 ;
174   args_info->duplex_distance_given = 0 ;
175   args_info->energy_threshold_given = 0 ;
176   args_info->produce_ps_given = 0 ;
177   args_info->WindowLength_given = 0 ;
178 }
179
180 static
181 void clear_args (struct RNAplex_args_info *args_info)
182 {
183   FIX_UNUSED (args_info);
184   args_info->query_arg = NULL;
185   args_info->query_orig = NULL;
186   args_info->target_arg = NULL;
187   args_info->target_orig = NULL;
188   args_info->accessibility_dir_arg = NULL;
189   args_info->accessibility_dir_orig = NULL;
190   args_info->binary_flag = 0;
191   args_info->paramFile_arg = NULL;
192   args_info->paramFile_orig = NULL;
193   args_info->temp_orig = NULL;
194   args_info->interaction_length_arg = 40;
195   args_info->interaction_length_orig = NULL;
196   args_info->extension_cost_arg = 0;
197   args_info->extension_cost_orig = NULL;
198   args_info->probe_mode_flag = 0;
199   args_info->probe_concentration_arg = 0.1;
200   args_info->probe_concentration_orig = NULL;
201   args_info->na_concentration_arg = 1.0;
202   args_info->na_concentration_orig = NULL;
203   args_info->mg_concentration_arg = 1.0;
204   args_info->mg_concentration_orig = NULL;
205   args_info->k_concentration_arg = 1.0;
206   args_info->k_concentration_orig = NULL;
207   args_info->tris_concentration_arg = 1.0;
208   args_info->tris_concentration_orig = NULL;
209   args_info->fast_folding_arg = 0;
210   args_info->fast_folding_orig = NULL;
211   args_info->scale_accessibility_arg = 1.0;
212   args_info->scale_accessibility_orig = NULL;
213   args_info->constraint_flag = 0;
214   args_info->alignment_mode_flag = 0;
215   args_info->convert_to_bin_flag = 0;
216   args_info->duplex_distance_arg = 0;
217   args_info->duplex_distance_orig = NULL;
218   args_info->energy_threshold_arg = -100000;
219   args_info->energy_threshold_orig = NULL;
220   args_info->produce_ps_arg = NULL;
221   args_info->produce_ps_orig = NULL;
222   args_info->WindowLength_arg = 1;
223   args_info->WindowLength_orig = NULL;
224   
225 }
226
227 static
228 void init_args_info(struct RNAplex_args_info *args_info)
229 {
230
231   init_help_array(); 
232   args_info->help_help = RNAplex_args_info_detailed_help[0] ;
233   args_info->detailed_help_help = RNAplex_args_info_detailed_help[1] ;
234   args_info->version_help = RNAplex_args_info_detailed_help[2] ;
235   args_info->query_help = RNAplex_args_info_detailed_help[5] ;
236   args_info->target_help = RNAplex_args_info_detailed_help[7] ;
237   args_info->accessibility_dir_help = RNAplex_args_info_detailed_help[9] ;
238   args_info->binary_help = RNAplex_args_info_detailed_help[11] ;
239   args_info->paramFile_help = RNAplex_args_info_detailed_help[13] ;
240   args_info->temp_help = RNAplex_args_info_detailed_help[17] ;
241   args_info->interaction_length_help = RNAplex_args_info_detailed_help[18] ;
242   args_info->extension_cost_help = RNAplex_args_info_detailed_help[20] ;
243   args_info->probe_mode_help = RNAplex_args_info_detailed_help[22] ;
244   args_info->probe_concentration_help = RNAplex_args_info_detailed_help[24] ;
245   args_info->na_concentration_help = RNAplex_args_info_detailed_help[25] ;
246   args_info->mg_concentration_help = RNAplex_args_info_detailed_help[26] ;
247   args_info->k_concentration_help = RNAplex_args_info_detailed_help[27] ;
248   args_info->tris_concentration_help = RNAplex_args_info_detailed_help[28] ;
249   args_info->fast_folding_help = RNAplex_args_info_detailed_help[29] ;
250   args_info->scale_accessibility_help = RNAplex_args_info_detailed_help[31] ;
251   args_info->constraint_help = RNAplex_args_info_detailed_help[33] ;
252   args_info->alignment_mode_help = RNAplex_args_info_detailed_help[35] ;
253   args_info->convert_to_bin_help = RNAplex_args_info_detailed_help[37] ;
254   args_info->duplex_distance_help = RNAplex_args_info_detailed_help[41] ;
255   args_info->energy_threshold_help = RNAplex_args_info_detailed_help[43] ;
256   args_info->produce_ps_help = RNAplex_args_info_detailed_help[45] ;
257   args_info->WindowLength_help = RNAplex_args_info_detailed_help[47] ;
258   
259 }
260
261 void
262 RNAplex_cmdline_parser_print_version (void)
263 {
264   printf ("%s %s\n",
265      (strlen(RNAPLEX_CMDLINE_PARSER_PACKAGE_NAME) ? RNAPLEX_CMDLINE_PARSER_PACKAGE_NAME : RNAPLEX_CMDLINE_PARSER_PACKAGE),
266      RNAPLEX_CMDLINE_PARSER_VERSION);
267 }
268
269 static void print_help_common(void) {
270   RNAplex_cmdline_parser_print_version ();
271
272   if (strlen(RNAplex_args_info_purpose) > 0)
273     printf("\n%s\n", RNAplex_args_info_purpose);
274
275   if (strlen(RNAplex_args_info_usage) > 0)
276     printf("\n%s\n", RNAplex_args_info_usage);
277
278   printf("\n");
279
280   if (strlen(RNAplex_args_info_description) > 0)
281     printf("%s\n\n", RNAplex_args_info_description);
282 }
283
284 void
285 RNAplex_cmdline_parser_print_help (void)
286 {
287   int i = 0;
288   print_help_common();
289   while (RNAplex_args_info_help[i])
290     printf("%s\n", RNAplex_args_info_help[i++]);
291 }
292
293 void
294 RNAplex_cmdline_parser_print_detailed_help (void)
295 {
296   int i = 0;
297   print_help_common();
298   while (RNAplex_args_info_detailed_help[i])
299     printf("%s\n", RNAplex_args_info_detailed_help[i++]);
300 }
301
302 void
303 RNAplex_cmdline_parser_init (struct RNAplex_args_info *args_info)
304 {
305   clear_given (args_info);
306   clear_args (args_info);
307   init_args_info (args_info);
308 }
309
310 void
311 RNAplex_cmdline_parser_params_init(struct RNAplex_cmdline_parser_params *params)
312 {
313   if (params)
314     { 
315       params->override = 0;
316       params->initialize = 1;
317       params->check_required = 1;
318       params->check_ambiguity = 0;
319       params->print_errors = 1;
320     }
321 }
322
323 struct RNAplex_cmdline_parser_params *
324 RNAplex_cmdline_parser_params_create(void)
325 {
326   struct RNAplex_cmdline_parser_params *params = 
327     (struct RNAplex_cmdline_parser_params *)malloc(sizeof(struct RNAplex_cmdline_parser_params));
328   RNAplex_cmdline_parser_params_init(params);  
329   return params;
330 }
331
332 static void
333 free_string_field (char **s)
334 {
335   if (*s)
336     {
337       free (*s);
338       *s = 0;
339     }
340 }
341
342
343 static void
344 RNAplex_cmdline_parser_release (struct RNAplex_args_info *args_info)
345 {
346
347   free_string_field (&(args_info->query_arg));
348   free_string_field (&(args_info->query_orig));
349   free_string_field (&(args_info->target_arg));
350   free_string_field (&(args_info->target_orig));
351   free_string_field (&(args_info->accessibility_dir_arg));
352   free_string_field (&(args_info->accessibility_dir_orig));
353   free_string_field (&(args_info->paramFile_arg));
354   free_string_field (&(args_info->paramFile_orig));
355   free_string_field (&(args_info->temp_orig));
356   free_string_field (&(args_info->interaction_length_orig));
357   free_string_field (&(args_info->extension_cost_orig));
358   free_string_field (&(args_info->probe_concentration_orig));
359   free_string_field (&(args_info->na_concentration_orig));
360   free_string_field (&(args_info->mg_concentration_orig));
361   free_string_field (&(args_info->k_concentration_orig));
362   free_string_field (&(args_info->tris_concentration_orig));
363   free_string_field (&(args_info->fast_folding_orig));
364   free_string_field (&(args_info->scale_accessibility_orig));
365   free_string_field (&(args_info->duplex_distance_orig));
366   free_string_field (&(args_info->energy_threshold_orig));
367   free_string_field (&(args_info->produce_ps_arg));
368   free_string_field (&(args_info->produce_ps_orig));
369   free_string_field (&(args_info->WindowLength_orig));
370   
371   
372
373   clear_given (args_info);
374 }
375
376
377 static void
378 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
379 {
380   FIX_UNUSED (values);
381   if (arg) {
382     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
383   } else {
384     fprintf(outfile, "%s\n", opt);
385   }
386 }
387
388
389 int
390 RNAplex_cmdline_parser_dump(FILE *outfile, struct RNAplex_args_info *args_info)
391 {
392   int i = 0;
393
394   if (!outfile)
395     {
396       fprintf (stderr, "%s: cannot dump options to stream\n", RNAPLEX_CMDLINE_PARSER_PACKAGE);
397       return EXIT_FAILURE;
398     }
399
400   if (args_info->help_given)
401     write_into_file(outfile, "help", 0, 0 );
402   if (args_info->detailed_help_given)
403     write_into_file(outfile, "detailed-help", 0, 0 );
404   if (args_info->version_given)
405     write_into_file(outfile, "version", 0, 0 );
406   if (args_info->query_given)
407     write_into_file(outfile, "query", args_info->query_orig, 0);
408   if (args_info->target_given)
409     write_into_file(outfile, "target", args_info->target_orig, 0);
410   if (args_info->accessibility_dir_given)
411     write_into_file(outfile, "accessibility-dir", args_info->accessibility_dir_orig, 0);
412   if (args_info->binary_given)
413     write_into_file(outfile, "binary", 0, 0 );
414   if (args_info->paramFile_given)
415     write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
416   if (args_info->temp_given)
417     write_into_file(outfile, "temp", args_info->temp_orig, 0);
418   if (args_info->interaction_length_given)
419     write_into_file(outfile, "interaction-length", args_info->interaction_length_orig, 0);
420   if (args_info->extension_cost_given)
421     write_into_file(outfile, "extension-cost", args_info->extension_cost_orig, 0);
422   if (args_info->probe_mode_given)
423     write_into_file(outfile, "probe-mode", 0, 0 );
424   if (args_info->probe_concentration_given)
425     write_into_file(outfile, "probe-concentration", args_info->probe_concentration_orig, 0);
426   if (args_info->na_concentration_given)
427     write_into_file(outfile, "na-concentration", args_info->na_concentration_orig, 0);
428   if (args_info->mg_concentration_given)
429     write_into_file(outfile, "mg-concentration", args_info->mg_concentration_orig, 0);
430   if (args_info->k_concentration_given)
431     write_into_file(outfile, "k-concentration", args_info->k_concentration_orig, 0);
432   if (args_info->tris_concentration_given)
433     write_into_file(outfile, "tris-concentration", args_info->tris_concentration_orig, 0);
434   if (args_info->fast_folding_given)
435     write_into_file(outfile, "fast-folding", args_info->fast_folding_orig, 0);
436   if (args_info->scale_accessibility_given)
437     write_into_file(outfile, "scale-accessibility", args_info->scale_accessibility_orig, 0);
438   if (args_info->constraint_given)
439     write_into_file(outfile, "constraint", 0, 0 );
440   if (args_info->alignment_mode_given)
441     write_into_file(outfile, "alignment-mode", 0, 0 );
442   if (args_info->convert_to_bin_given)
443     write_into_file(outfile, "convert-to-bin", 0, 0 );
444   if (args_info->duplex_distance_given)
445     write_into_file(outfile, "duplex-distance", args_info->duplex_distance_orig, 0);
446   if (args_info->energy_threshold_given)
447     write_into_file(outfile, "energy-threshold", args_info->energy_threshold_orig, 0);
448   if (args_info->produce_ps_given)
449     write_into_file(outfile, "produce-ps", args_info->produce_ps_orig, 0);
450   if (args_info->WindowLength_given)
451     write_into_file(outfile, "WindowLength", args_info->WindowLength_orig, 0);
452   
453
454   i = EXIT_SUCCESS;
455   return i;
456 }
457
458 int
459 RNAplex_cmdline_parser_file_save(const char *filename, struct RNAplex_args_info *args_info)
460 {
461   FILE *outfile;
462   int i = 0;
463
464   outfile = fopen(filename, "w");
465
466   if (!outfile)
467     {
468       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNAPLEX_CMDLINE_PARSER_PACKAGE, filename);
469       return EXIT_FAILURE;
470     }
471
472   i = RNAplex_cmdline_parser_dump(outfile, args_info);
473   fclose (outfile);
474
475   return i;
476 }
477
478 void
479 RNAplex_cmdline_parser_free (struct RNAplex_args_info *args_info)
480 {
481   RNAplex_cmdline_parser_release (args_info);
482 }
483
484 /** @brief replacement of strdup, which is not standard */
485 char *
486 gengetopt_strdup (const char *s)
487 {
488   char *result = 0;
489   if (!s)
490     return result;
491
492   result = (char*)malloc(strlen(s) + 1);
493   if (result == (char*)0)
494     return (char*)0;
495   strcpy(result, s);
496   return result;
497 }
498
499 int
500 RNAplex_cmdline_parser (int argc, char **argv, struct RNAplex_args_info *args_info)
501 {
502   return RNAplex_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
503 }
504
505 int
506 RNAplex_cmdline_parser_ext (int argc, char **argv, struct RNAplex_args_info *args_info,
507                    struct RNAplex_cmdline_parser_params *params)
508 {
509   int result;
510   result = RNAplex_cmdline_parser_internal (argc, argv, args_info, params, 0);
511
512   if (result == EXIT_FAILURE)
513     {
514       RNAplex_cmdline_parser_free (args_info);
515       exit (EXIT_FAILURE);
516     }
517   
518   return result;
519 }
520
521 int
522 RNAplex_cmdline_parser2 (int argc, char **argv, struct RNAplex_args_info *args_info, int override, int initialize, int check_required)
523 {
524   int result;
525   struct RNAplex_cmdline_parser_params params;
526   
527   params.override = override;
528   params.initialize = initialize;
529   params.check_required = check_required;
530   params.check_ambiguity = 0;
531   params.print_errors = 1;
532
533   result = RNAplex_cmdline_parser_internal (argc, argv, args_info, &params, 0);
534
535   if (result == EXIT_FAILURE)
536     {
537       RNAplex_cmdline_parser_free (args_info);
538       exit (EXIT_FAILURE);
539     }
540   
541   return result;
542 }
543
544 int
545 RNAplex_cmdline_parser_required (struct RNAplex_args_info *args_info, const char *prog_name)
546 {
547   FIX_UNUSED (args_info);
548   FIX_UNUSED (prog_name);
549   return EXIT_SUCCESS;
550 }
551
552 /*
553  * Extracted from the glibc source tree, version 2.3.6
554  *
555  * Licensed under the GPL as per the whole glibc source tree.
556  *
557  * This file was modified so that getopt_long can be called
558  * many times without risking previous memory to be spoiled.
559  *
560  * Modified by Andre Noll and Lorenzo Bettini for use in
561  * GNU gengetopt generated files.
562  *
563  */
564
565 /* 
566  * we must include anything we need since this file is not thought to be
567  * inserted in a file already using getopt.h
568  *
569  * Lorenzo
570  */
571
572 struct option
573 {
574   const char *name;
575   /* has_arg can't be an enum because some compilers complain about
576      type mismatches in all the code that assumes it is an int.  */
577   int has_arg;
578   int *flag;
579   int val;
580 };
581
582 /* This version of `getopt' appears to the caller like standard Unix `getopt'
583    but it behaves differently for the user, since it allows the user
584    to intersperse the options with the other arguments.
585
586    As `getopt' works, it permutes the elements of ARGV so that,
587    when it is done, all the options precede everything else.  Thus
588    all application programs are extended to handle flexible argument order.
589 */
590 /*
591    If the field `flag' is not NULL, it points to a variable that is set
592    to the value given in the field `val' when the option is found, but
593    left unchanged if the option is not found.
594
595    To have a long-named option do something other than set an `int' to
596    a compiled-in constant, such as set a value from `custom_optarg', set the
597    option's `flag' field to zero and its `val' field to a nonzero
598    value (the equivalent single-letter option character, if there is
599    one).  For long options that have a zero `flag' field, `getopt'
600    returns the contents of the `val' field.  */
601
602 /* Names for the values of the `has_arg' field of `struct option'.  */
603 #ifndef no_argument
604 #define no_argument             0
605 #endif
606
607 #ifndef required_argument
608 #define required_argument       1
609 #endif
610
611 #ifndef optional_argument
612 #define optional_argument       2
613 #endif
614
615 struct custom_getopt_data {
616         /*
617          * These have exactly the same meaning as the corresponding global variables,
618          * except that they are used for the reentrant versions of getopt.
619          */
620         int custom_optind;
621         int custom_opterr;
622         int custom_optopt;
623         char *custom_optarg;
624
625         /* True if the internal members have been initialized.  */
626         int initialized;
627
628         /*
629          * The next char to be scanned in the option-element in which the last option
630          * character we returned was found.  This allows us to pick up the scan where
631          * we left off.  If this is zero, or a null string, it means resume the scan by
632          * advancing to the next ARGV-element.
633          */
634         char *nextchar;
635
636         /*
637          * Describe the part of ARGV that contains non-options that have been skipped.
638          * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
639          * the index after the last of them.
640          */
641         int first_nonopt;
642         int last_nonopt;
643 };
644
645 /*
646  * the variables optarg, optind, opterr and optopt are renamed with
647  * the custom_ prefix so that they don't interfere with getopt ones.
648  *
649  * Moreover they're static so they are visible only from within the
650  * file where this very file will be included.
651  */
652
653 /*
654  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
655  * option that takes an argument, the argument value is returned here.
656  */
657 static char *custom_optarg;
658
659 /*
660  * Index in ARGV of the next element to be scanned.  This is used for
661  * communication to and from the caller and for communication between
662  * successive calls to `custom_getopt'.
663  *
664  * On entry to `custom_getopt', 1 means this is the first call; initialize.
665  *
666  * When `custom_getopt' returns -1, this is the index of the first of the non-option
667  * elements that the caller should itself scan.
668  *
669  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
670  * has been scanned so far.
671  *
672  * 1003.2 says this must be 1 before any call.
673  */
674 static int custom_optind = 1;
675
676 /*
677  * Callers store zero here to inhibit the error message for unrecognized
678  * options.
679  */
680 static int custom_opterr = 1;
681
682 /*
683  * Set to an option character which was unrecognized.  This must be initialized
684  * on some systems to avoid linking in the system's own getopt implementation.
685  */
686 static int custom_optopt = '?';
687
688 /*
689  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
690  * [first_nonopt,last_nonopt) which contains all the non-options that have been
691  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
692  * all the options processed since those non-options were skipped.
693  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
694  * indices of the non-options in ARGV after they are moved.
695  */
696 static void exchange(char **argv, struct custom_getopt_data *d)
697 {
698         int bottom = d->first_nonopt;
699         int middle = d->last_nonopt;
700         int top = d->custom_optind;
701         char *tem;
702
703         /*
704          * Exchange the shorter segment with the far end of the longer segment.
705          * That puts the shorter segment into the right place.  It leaves the
706          * longer segment in the right place overall, but it consists of two
707          * parts that need to be swapped next.
708          */
709         while (top > middle && middle > bottom) {
710                 if (top - middle > middle - bottom) {
711                         /* Bottom segment is the short one.  */
712                         int len = middle - bottom;
713                         int i;
714
715                         /* Swap it with the top part of the top segment.  */
716                         for (i = 0; i < len; i++) {
717                                 tem = argv[bottom + i];
718                                 argv[bottom + i] =
719                                         argv[top - (middle - bottom) + i];
720                                 argv[top - (middle - bottom) + i] = tem;
721                         }
722                         /* Exclude the moved bottom segment from further swapping.  */
723                         top -= len;
724                 } else {
725                         /* Top segment is the short one.  */
726                         int len = top - middle;
727                         int i;
728
729                         /* Swap it with the bottom part of the bottom segment.  */
730                         for (i = 0; i < len; i++) {
731                                 tem = argv[bottom + i];
732                                 argv[bottom + i] = argv[middle + i];
733                                 argv[middle + i] = tem;
734                         }
735                         /* Exclude the moved top segment from further swapping.  */
736                         bottom += len;
737                 }
738         }
739         /* Update records for the slots the non-options now occupy.  */
740         d->first_nonopt += (d->custom_optind - d->last_nonopt);
741         d->last_nonopt = d->custom_optind;
742 }
743
744 /* Initialize the internal data when the first call is made.  */
745 static void custom_getopt_initialize(struct custom_getopt_data *d)
746 {
747         /*
748          * Start processing options with ARGV-element 1 (since ARGV-element 0
749          * is the program name); the sequence of previously skipped non-option
750          * ARGV-elements is empty.
751          */
752         d->first_nonopt = d->last_nonopt = d->custom_optind;
753         d->nextchar = NULL;
754         d->initialized = 1;
755 }
756
757 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
758
759 /* return: zero: continue, nonzero: return given value to user */
760 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
761         struct custom_getopt_data *d)
762 {
763         /*
764          * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
765          * moved back by the user (who may also have changed the arguments).
766          */
767         if (d->last_nonopt > d->custom_optind)
768                 d->last_nonopt = d->custom_optind;
769         if (d->first_nonopt > d->custom_optind)
770                 d->first_nonopt = d->custom_optind;
771         /*
772          * If we have just processed some options following some
773          * non-options, exchange them so that the options come first.
774          */
775         if (d->first_nonopt != d->last_nonopt &&
776                         d->last_nonopt != d->custom_optind)
777                 exchange((char **) argv, d);
778         else if (d->last_nonopt != d->custom_optind)
779                 d->first_nonopt = d->custom_optind;
780         /*
781          * Skip any additional non-options and extend the range of
782          * non-options previously skipped.
783          */
784         while (d->custom_optind < argc && NONOPTION_P)
785                 d->custom_optind++;
786         d->last_nonopt = d->custom_optind;
787         /*
788          * The special ARGV-element `--' means premature end of options.  Skip
789          * it like a null option, then exchange with previous non-options as if
790          * it were an option, then skip everything else like a non-option.
791          */
792         if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
793                 d->custom_optind++;
794                 if (d->first_nonopt != d->last_nonopt
795                                 && d->last_nonopt != d->custom_optind)
796                         exchange((char **) argv, d);
797                 else if (d->first_nonopt == d->last_nonopt)
798                         d->first_nonopt = d->custom_optind;
799                 d->last_nonopt = argc;
800                 d->custom_optind = argc;
801         }
802         /*
803          * If we have done all the ARGV-elements, stop the scan and back over
804          * any non-options that we skipped and permuted.
805          */
806         if (d->custom_optind == argc) {
807                 /*
808                  * Set the next-arg-index to point at the non-options that we
809                  * previously skipped, so the caller will digest them.
810                  */
811                 if (d->first_nonopt != d->last_nonopt)
812                         d->custom_optind = d->first_nonopt;
813                 return -1;
814         }
815         /*
816          * If we have come to a non-option and did not permute it, either stop
817          * the scan or describe it to the caller and pass it by.
818          */
819         if (NONOPTION_P) {
820                 d->custom_optarg = argv[d->custom_optind++];
821                 return 1;
822         }
823         /*
824          * We have found another option-ARGV-element. Skip the initial
825          * punctuation.
826          */
827         d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
828         return 0;
829 }
830
831 /*
832  * Check whether the ARGV-element is a long option.
833  *
834  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
835  * that an abbreviation of the long option, just like "--fu", and not "-f" with
836  * arg "u".
837  *
838  * This distinction seems to be the most useful approach.
839  *
840  */
841 static int check_long_opt(int argc, char *const *argv, const char *optstring,
842                 const struct option *longopts, int *longind,
843                 int print_errors, struct custom_getopt_data *d)
844 {
845         char *nameend;
846         const struct option *p;
847         const struct option *pfound = NULL;
848         int exact = 0;
849         int ambig = 0;
850         int indfound = -1;
851         int option_index;
852
853         for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
854                 /* Do nothing.  */ ;
855
856         /* Test all long options for either exact match or abbreviated matches */
857         for (p = longopts, option_index = 0; p->name; p++, option_index++)
858                 if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
859                         if ((unsigned int) (nameend - d->nextchar)
860                                         == (unsigned int) strlen(p->name)) {
861                                 /* Exact match found.  */
862                                 pfound = p;
863                                 indfound = option_index;
864                                 exact = 1;
865                                 break;
866                         } else if (pfound == NULL) {
867                                 /* First nonexact match found.  */
868                                 pfound = p;
869                                 indfound = option_index;
870                         } else if (pfound->has_arg != p->has_arg
871                                         || pfound->flag != p->flag
872                                         || pfound->val != p->val)
873                                 /* Second or later nonexact match found.  */
874                                 ambig = 1;
875                 }
876         if (ambig && !exact) {
877                 if (print_errors) {
878                         fprintf(stderr,
879                                 "%s: option `%s' is ambiguous\n",
880                                 argv[0], argv[d->custom_optind]);
881                 }
882                 d->nextchar += strlen(d->nextchar);
883                 d->custom_optind++;
884                 d->custom_optopt = 0;
885                 return '?';
886         }
887         if (pfound) {
888                 option_index = indfound;
889                 d->custom_optind++;
890                 if (*nameend) {
891                         if (pfound->has_arg != no_argument)
892                                 d->custom_optarg = nameend + 1;
893                         else {
894                                 if (print_errors) {
895                                         if (argv[d->custom_optind - 1][1] == '-') {
896                                                 /* --option */
897                                                 fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
898                                                         argv[0], pfound->name);
899                                         } else {
900                                                 /* +option or -option */
901                                                 fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
902                                                         argv[0], argv[d->custom_optind - 1][0], pfound->name);
903                                         }
904
905                                 }
906                                 d->nextchar += strlen(d->nextchar);
907                                 d->custom_optopt = pfound->val;
908                                 return '?';
909                         }
910                 } else if (pfound->has_arg == required_argument) {
911                         if (d->custom_optind < argc)
912                                 d->custom_optarg = argv[d->custom_optind++];
913                         else {
914                                 if (print_errors) {
915                                         fprintf(stderr,
916                                                 "%s: option `%s' requires an argument\n",
917                                                 argv[0],
918                                                 argv[d->custom_optind - 1]);
919                                 }
920                                 d->nextchar += strlen(d->nextchar);
921                                 d->custom_optopt = pfound->val;
922                                 return optstring[0] == ':' ? ':' : '?';
923                         }
924                 }
925                 d->nextchar += strlen(d->nextchar);
926                 if (longind != NULL)
927                         *longind = option_index;
928                 if (pfound->flag) {
929                         *(pfound->flag) = pfound->val;
930                         return 0;
931                 }
932                 return pfound->val;
933         }
934         /*
935          * Can't find it as a long option.  If this is not getopt_long_only, or
936          * the option starts with '--' or is not a valid short option, then
937          * it's an error.  Otherwise interpret it as a short option.
938          */
939         if (print_errors) {
940                 if (argv[d->custom_optind][1] == '-') {
941                         /* --option */
942                         fprintf(stderr,
943                                 "%s: unrecognized option `--%s'\n",
944                                 argv[0], d->nextchar);
945                 } else {
946                         /* +option or -option */
947                         fprintf(stderr,
948                                 "%s: unrecognized option `%c%s'\n",
949                                 argv[0], argv[d->custom_optind][0],
950                                 d->nextchar);
951                 }
952         }
953         d->nextchar = (char *) "";
954         d->custom_optind++;
955         d->custom_optopt = 0;
956         return '?';
957 }
958
959 static int check_short_opt(int argc, char *const *argv, const char *optstring,
960                 int print_errors, struct custom_getopt_data *d)
961 {
962         char c = *d->nextchar++;
963         const char *temp = strchr(optstring, c);
964
965         /* Increment `custom_optind' when we start to process its last character.  */
966         if (*d->nextchar == '\0')
967                 ++d->custom_optind;
968         if (!temp || c == ':') {
969                 if (print_errors)
970                         fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
971
972                 d->custom_optopt = c;
973                 return '?';
974         }
975         if (temp[1] == ':') {
976                 if (temp[2] == ':') {
977                         /* This is an option that accepts an argument optionally.  */
978                         if (*d->nextchar != '\0') {
979                                 d->custom_optarg = d->nextchar;
980                                 d->custom_optind++;
981                         } else
982                                 d->custom_optarg = NULL;
983                         d->nextchar = NULL;
984                 } else {
985                         /* This is an option that requires an argument.  */
986                         if (*d->nextchar != '\0') {
987                                 d->custom_optarg = d->nextchar;
988                                 /*
989                                  * If we end this ARGV-element by taking the
990                                  * rest as an arg, we must advance to the next
991                                  * element now.
992                                  */
993                                 d->custom_optind++;
994                         } else if (d->custom_optind == argc) {
995                                 if (print_errors) {
996                                         fprintf(stderr,
997                                                 "%s: option requires an argument -- %c\n",
998                                                 argv[0], c);
999                                 }
1000                                 d->custom_optopt = c;
1001                                 if (optstring[0] == ':')
1002                                         c = ':';
1003                                 else
1004                                         c = '?';
1005                         } else
1006                                 /*
1007                                  * We already incremented `custom_optind' once;
1008                                  * increment it again when taking next ARGV-elt
1009                                  * as argument.
1010                                  */
1011                                 d->custom_optarg = argv[d->custom_optind++];
1012                         d->nextchar = NULL;
1013                 }
1014         }
1015         return c;
1016 }
1017
1018 /*
1019  * Scan elements of ARGV for option characters given in OPTSTRING.
1020  *
1021  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1022  * then it is an option element.  The characters of this element
1023  * (aside from the initial '-') are option characters.  If `getopt'
1024  * is called repeatedly, it returns successively each of the option characters
1025  * from each of the option elements.
1026  *
1027  * If `getopt' finds another option character, it returns that character,
1028  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1029  * resume the scan with the following option character or ARGV-element.
1030  *
1031  * If there are no more option characters, `getopt' returns -1.
1032  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1033  * that is not an option.  (The ARGV-elements have been permuted
1034  * so that those that are not options now come last.)
1035  *
1036  * OPTSTRING is a string containing the legitimate option characters.
1037  * If an option character is seen that is not listed in OPTSTRING,
1038  * return '?' after printing an error message.  If you set `custom_opterr' to
1039  * zero, the error message is suppressed but we still return '?'.
1040  *
1041  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1042  * so the following text in the same ARGV-element, or the text of the following
1043  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1044  * wants an optional arg; if there is text in the current ARGV-element,
1045  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1046  *
1047  * If OPTSTRING starts with `-' or `+', it requests different methods of
1048  * handling the non-option ARGV-elements.
1049  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1050  *
1051  * Long-named options begin with `--' instead of `-'.
1052  * Their names may be abbreviated as long as the abbreviation is unique
1053  * or is an exact match for some defined option.  If they have an
1054  * argument, it follows the option name in the same ARGV-element, separated
1055  * from the option name by a `=', or else the in next ARGV-element.
1056  * When `getopt' finds a long-named option, it returns 0 if that option's
1057  * `flag' field is nonzero, the value of the option's `val' field
1058  * if the `flag' field is zero.
1059  *
1060  * The elements of ARGV aren't really const, because we permute them.
1061  * But we pretend they're const in the prototype to be compatible
1062  * with other systems.
1063  *
1064  * LONGOPTS is a vector of `struct option' terminated by an
1065  * element containing a name which is zero.
1066  *
1067  * LONGIND returns the index in LONGOPT of the long-named option found.
1068  * It is only valid when a long-named option has been found by the most
1069  * recent call.
1070  *
1071  * Return the option character from OPTS just read.  Return -1 when there are
1072  * no more options.  For unrecognized options, or options missing arguments,
1073  * `custom_optopt' is set to the option letter, and '?' is returned.
1074  *
1075  * The OPTS string is a list of characters which are recognized option letters,
1076  * optionally followed by colons, specifying that that letter takes an
1077  * argument, to be placed in `custom_optarg'.
1078  *
1079  * If a letter in OPTS is followed by two colons, its argument is optional.
1080  * This behavior is specific to the GNU `getopt'.
1081  *
1082  * The argument `--' causes premature termination of argument scanning,
1083  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1084  * with `--', then non-option arguments are treated as arguments to the option
1085  * '\0'.  This behavior is specific to the GNU `getopt'.
1086  */
1087
1088 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1089                 const struct option *longopts, int *longind,
1090                 struct custom_getopt_data *d)
1091 {
1092         int ret, print_errors = d->custom_opterr;
1093
1094         if (optstring[0] == ':')
1095                 print_errors = 0;
1096         if (argc < 1)
1097                 return -1;
1098         d->custom_optarg = NULL;
1099
1100         /* 
1101          * This is a big difference with GNU getopt, since optind == 0
1102          * means initialization while here 1 means first call.
1103          */
1104         if (d->custom_optind == 0 || !d->initialized) {
1105                 if (d->custom_optind == 0)
1106                         d->custom_optind = 1;   /* Don't scan ARGV[0], the program name.  */
1107                 custom_getopt_initialize(d);
1108         }
1109         if (d->nextchar == NULL || *d->nextchar == '\0') {
1110                 ret = shuffle_argv(argc, argv, longopts, d);
1111                 if (ret)
1112                         return ret;
1113         }
1114         if (longopts && (argv[d->custom_optind][1] == '-' ))
1115                 return check_long_opt(argc, argv, optstring, longopts,
1116                         longind, print_errors, d);
1117         return check_short_opt(argc, argv, optstring, print_errors, d);
1118 }
1119
1120 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1121         const struct option *longopts, int *longind)
1122 {
1123         int result;
1124         /* Keep a global copy of all internal members of d */
1125         static struct custom_getopt_data d;
1126
1127         d.custom_optind = custom_optind;
1128         d.custom_opterr = custom_opterr;
1129         result = getopt_internal_r(argc, argv, optstring, longopts,
1130                 longind, &d);
1131         custom_optind = d.custom_optind;
1132         custom_optarg = d.custom_optarg;
1133         custom_optopt = d.custom_optopt;
1134         return result;
1135 }
1136
1137 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1138         const struct option *long_options, int *opt_index)
1139 {
1140         return custom_getopt_internal(argc, argv, options, long_options,
1141                 opt_index);
1142 }
1143
1144
1145 static char *package_name = 0;
1146
1147 /**
1148  * @brief updates an option
1149  * @param field the generic pointer to the field to update
1150  * @param orig_field the pointer to the orig field
1151  * @param field_given the pointer to the number of occurrence of this option
1152  * @param prev_given the pointer to the number of occurrence already seen
1153  * @param value the argument for this option (if null no arg was specified)
1154  * @param possible_values the possible values for this option (if specified)
1155  * @param default_value the default value (in case the option only accepts fixed values)
1156  * @param arg_type the type of this option
1157  * @param check_ambiguity @see RNAplex_cmdline_parser_params.check_ambiguity
1158  * @param override @see RNAplex_cmdline_parser_params.override
1159  * @param no_free whether to free a possible previous value
1160  * @param multiple_option whether this is a multiple option
1161  * @param long_opt the corresponding long option
1162  * @param short_opt the corresponding short option (or '-' if none)
1163  * @param additional_error possible further error specification
1164  */
1165 static
1166 int update_arg(void *field, char **orig_field,
1167                unsigned int *field_given, unsigned int *prev_given, 
1168                char *value, const char *possible_values[],
1169                const char *default_value,
1170                RNAplex_cmdline_parser_arg_type arg_type,
1171                int check_ambiguity, int override,
1172                int no_free, int multiple_option,
1173                const char *long_opt, char short_opt,
1174                const char *additional_error)
1175 {
1176   char *stop_char = 0;
1177   const char *val = value;
1178   int found;
1179   char **string_field;
1180   FIX_UNUSED (field);
1181
1182   stop_char = 0;
1183   found = 0;
1184
1185   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1186     {
1187       if (short_opt != '-')
1188         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
1189                package_name, long_opt, short_opt,
1190                (additional_error ? additional_error : ""));
1191       else
1192         fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
1193                package_name, long_opt,
1194                (additional_error ? additional_error : ""));
1195       return 1; /* failure */
1196     }
1197
1198   FIX_UNUSED (default_value);
1199     
1200   if (field_given && *field_given && ! override)
1201     return 0;
1202   if (prev_given)
1203     (*prev_given)++;
1204   if (field_given)
1205     (*field_given)++;
1206   if (possible_values)
1207     val = possible_values[found];
1208
1209   switch(arg_type) {
1210   case ARG_FLAG:
1211     *((int *)field) = !*((int *)field);
1212     break;
1213   case ARG_INT:
1214     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1215     break;
1216   case ARG_DOUBLE:
1217     if (val) *((double *)field) = strtod (val, &stop_char);
1218     break;
1219   case ARG_STRING:
1220     if (val) {
1221       string_field = (char **)field;
1222       if (!no_free && *string_field)
1223         free (*string_field); /* free previous string */
1224       *string_field = gengetopt_strdup (val);
1225     }
1226     break;
1227   default:
1228     break;
1229   };
1230
1231   /* check numeric conversion */
1232   switch(arg_type) {
1233   case ARG_INT:
1234   case ARG_DOUBLE:
1235     if (val && !(stop_char && *stop_char == '\0')) {
1236       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1237       return 1; /* failure */
1238     }
1239     break;
1240   default:
1241     ;
1242   };
1243
1244   /* store the original value */
1245   switch(arg_type) {
1246   case ARG_NO:
1247   case ARG_FLAG:
1248     break;
1249   default:
1250     if (value && orig_field) {
1251       if (no_free) {
1252         *orig_field = value;
1253       } else {
1254         if (*orig_field)
1255           free (*orig_field); /* free previous string */
1256         *orig_field = gengetopt_strdup (value);
1257       }
1258     }
1259   };
1260
1261   return 0; /* OK */
1262 }
1263
1264
1265 int
1266 RNAplex_cmdline_parser_internal (
1267   int argc, char **argv, struct RNAplex_args_info *args_info,
1268                         struct RNAplex_cmdline_parser_params *params, const char *additional_error)
1269 {
1270   int c;        /* Character of the parsed option.  */
1271
1272   int error = 0;
1273   struct RNAplex_args_info local_args_info;
1274   
1275   int override;
1276   int initialize;
1277   int check_required;
1278   int check_ambiguity;
1279
1280   char *optarg;
1281   int optind;
1282   int opterr;
1283   int optopt;
1284   
1285   package_name = argv[0];
1286   
1287   override = params->override;
1288   initialize = params->initialize;
1289   check_required = params->check_required;
1290   check_ambiguity = params->check_ambiguity;
1291
1292   if (initialize)
1293     RNAplex_cmdline_parser_init (args_info);
1294
1295   RNAplex_cmdline_parser_init (&local_args_info);
1296
1297   optarg = 0;
1298   optind = 0;
1299   opterr = params->print_errors;
1300   optopt = '?';
1301
1302   while (1)
1303     {
1304       int option_index = 0;
1305
1306       static struct option long_options[] = {
1307         { "help",       0, NULL, 'h' },
1308         { "detailed-help",      0, NULL, 0 },
1309         { "version",    0, NULL, 0 },
1310         { "query",      1, NULL, 'q' },
1311         { "target",     1, NULL, 't' },
1312         { "accessibility-dir",  1, NULL, 'a' },
1313         { "binary",     0, NULL, 'b' },
1314         { "paramFile",  1, NULL, 'P' },
1315         { "temp",       1, NULL, 'T' },
1316         { "interaction-length", 1, NULL, 'l' },
1317         { "extension-cost",     1, NULL, 'c' },
1318         { "probe-mode", 0, NULL, 'p' },
1319         { "probe-concentration",        1, NULL, 'Q' },
1320         { "na-concentration",   1, NULL, 'N' },
1321         { "mg-concentration",   1, NULL, 'M' },
1322         { "k-concentration",    1, NULL, 'K' },
1323         { "tris-concentration", 1, NULL, 'U' },
1324         { "fast-folding",       1, NULL, 'f' },
1325         { "scale-accessibility",        1, NULL, 'V' },
1326         { "constraint", 0, NULL, 'C' },
1327         { "alignment-mode",     0, NULL, 'A' },
1328         { "convert-to-bin",     0, NULL, 'k' },
1329         { "duplex-distance",    1, NULL, 'z' },
1330         { "energy-threshold",   1, NULL, 'e' },
1331         { "produce-ps", 1, NULL, 'I' },
1332         { "WindowLength",       1, NULL, 'L' },
1333         { 0,  0, 0, 0 }
1334       };
1335
1336       custom_optarg = optarg;
1337       custom_optind = optind;
1338       custom_opterr = opterr;
1339       custom_optopt = optopt;
1340
1341       c = custom_getopt_long (argc, argv, "hq:t:a:bP:T:l:c:pQ:N:M:K:U:f:V:CAkz:e:I:L:", long_options, &option_index);
1342
1343       optarg = custom_optarg;
1344       optind = custom_optind;
1345       opterr = custom_opterr;
1346       optopt = custom_optopt;
1347
1348       if (c == -1) break;       /* Exit from `while (1)' loop.  */
1349
1350       switch (c)
1351         {
1352         case 'h':       /* Print help and exit.  */
1353           RNAplex_cmdline_parser_print_help ();
1354           RNAplex_cmdline_parser_free (&local_args_info);
1355           exit (EXIT_SUCCESS);
1356
1357         case 'q':       /* File containing the query sequence.
1358 .  */
1359         
1360         
1361           if (update_arg( (void *)&(args_info->query_arg), 
1362                &(args_info->query_orig), &(args_info->query_given),
1363               &(local_args_info.query_given), optarg, 0, 0, ARG_STRING,
1364               check_ambiguity, override, 0, 0,
1365               "query", 'q',
1366               additional_error))
1367             goto failure;
1368         
1369           break;
1370         case 't':       /* File containing the target sequence.
1371 .  */
1372         
1373         
1374           if (update_arg( (void *)&(args_info->target_arg), 
1375                &(args_info->target_orig), &(args_info->target_given),
1376               &(local_args_info.target_given), optarg, 0, 0, ARG_STRING,
1377               check_ambiguity, override, 0, 0,
1378               "target", 't',
1379               additional_error))
1380             goto failure;
1381         
1382           break;
1383         case 'a':       /* Location of the accessibility profiles.
1384 .  */
1385         
1386         
1387           if (update_arg( (void *)&(args_info->accessibility_dir_arg), 
1388                &(args_info->accessibility_dir_orig), &(args_info->accessibility_dir_given),
1389               &(local_args_info.accessibility_dir_given), optarg, 0, 0, ARG_STRING,
1390               check_ambiguity, override, 0, 0,
1391               "accessibility-dir", 'a',
1392               additional_error))
1393             goto failure;
1394         
1395           break;
1396         case 'b':       /* Allow the reading and parsing of memory dumped opening energy file
1397 .  */
1398         
1399         
1400           if (update_arg((void *)&(args_info->binary_flag), 0, &(args_info->binary_given),
1401               &(local_args_info.binary_given), optarg, 0, 0, ARG_FLAG,
1402               check_ambiguity, override, 1, 0, "binary", 'b',
1403               additional_error))
1404             goto failure;
1405         
1406           break;
1407         case 'P':       /* Read energy parameters from paramfile, instead of using the default parameter set.
1408 .  */
1409         
1410         
1411           if (update_arg( (void *)&(args_info->paramFile_arg), 
1412                &(args_info->paramFile_orig), &(args_info->paramFile_given),
1413               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1414               check_ambiguity, override, 0, 0,
1415               "paramFile", 'P',
1416               additional_error))
1417             goto failure;
1418         
1419           break;
1420         case 'T':       /* Rescale energy parameters to a temperature T. Default is 37C.
1421         
1422 .  */
1423         
1424         
1425           if (update_arg( (void *)&(args_info->temp_arg), 
1426                &(args_info->temp_orig), &(args_info->temp_given),
1427               &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
1428               check_ambiguity, override, 0, 0,
1429               "temp", 'T',
1430               additional_error))
1431             goto failure;
1432         
1433           break;
1434         case 'l':       /* Maximal length of an interaction
1435 .  */
1436         
1437         
1438           if (update_arg( (void *)&(args_info->interaction_length_arg), 
1439                &(args_info->interaction_length_orig), &(args_info->interaction_length_given),
1440               &(local_args_info.interaction_length_given), optarg, 0, "40", ARG_INT,
1441               check_ambiguity, override, 0, 0,
1442               "interaction-length", 'l',
1443               additional_error))
1444             goto failure;
1445         
1446           break;
1447         case 'c':       /* Cost to add to each nucleotide in a duplex
1448 .  */
1449         
1450         
1451           if (update_arg( (void *)&(args_info->extension_cost_arg), 
1452                &(args_info->extension_cost_orig), &(args_info->extension_cost_given),
1453               &(local_args_info.extension_cost_given), optarg, 0, "0", ARG_INT,
1454               check_ambiguity, override, 0, 0,
1455               "extension-cost", 'c',
1456               additional_error))
1457             goto failure;
1458         
1459           break;
1460         case 'p':       /* Compute Tm for probes.  */
1461         
1462         
1463           if (update_arg((void *)&(args_info->probe_mode_flag), 0, &(args_info->probe_mode_given),
1464               &(local_args_info.probe_mode_given), optarg, 0, 0, ARG_FLAG,
1465               check_ambiguity, override, 1, 0, "probe-mode", 'p',
1466               additional_error))
1467             goto failure;
1468         
1469           break;
1470         case 'Q':       /* Set the probe concentration for the Tm computation
1471         
1472 .  */
1473         
1474         
1475           if (update_arg( (void *)&(args_info->probe_concentration_arg), 
1476                &(args_info->probe_concentration_orig), &(args_info->probe_concentration_given),
1477               &(local_args_info.probe_concentration_given), optarg, 0, "0.1", ARG_DOUBLE,
1478               check_ambiguity, override, 0, 0,
1479               "probe-concentration", 'Q',
1480               additional_error))
1481             goto failure;
1482         
1483           break;
1484         case 'N':       /* Set the Na+ concentration for the Tm computation
1485         
1486 .  */
1487         
1488         
1489           if (update_arg( (void *)&(args_info->na_concentration_arg), 
1490                &(args_info->na_concentration_orig), &(args_info->na_concentration_given),
1491               &(local_args_info.na_concentration_given), optarg, 0, "1.0", ARG_DOUBLE,
1492               check_ambiguity, override, 0, 0,
1493               "na-concentration", 'N',
1494               additional_error))
1495             goto failure;
1496         
1497           break;
1498         case 'M':       /* Set the Mg2+ concentration for the Tm computation
1499         
1500 .  */
1501         
1502         
1503           if (update_arg( (void *)&(args_info->mg_concentration_arg), 
1504                &(args_info->mg_concentration_orig), &(args_info->mg_concentration_given),
1505               &(local_args_info.mg_concentration_given), optarg, 0, "1.0", ARG_DOUBLE,
1506               check_ambiguity, override, 0, 0,
1507               "mg-concentration", 'M',
1508               additional_error))
1509             goto failure;
1510         
1511           break;
1512         case 'K':       /* Set the K+ concentration for the Tm computation
1513         
1514 .  */
1515         
1516         
1517           if (update_arg( (void *)&(args_info->k_concentration_arg), 
1518                &(args_info->k_concentration_orig), &(args_info->k_concentration_given),
1519               &(local_args_info.k_concentration_given), optarg, 0, "1.0", ARG_DOUBLE,
1520               check_ambiguity, override, 0, 0,
1521               "k-concentration", 'K',
1522               additional_error))
1523             goto failure;
1524         
1525           break;
1526         case 'U':       /* Set the tris+ concentration for the Tm computation
1527         
1528 .  */
1529         
1530         
1531           if (update_arg( (void *)&(args_info->tris_concentration_arg), 
1532                &(args_info->tris_concentration_orig), &(args_info->tris_concentration_given),
1533               &(local_args_info.tris_concentration_given), optarg, 0, "1.0", ARG_DOUBLE,
1534               check_ambiguity, override, 0, 0,
1535               "tris-concentration", 'U',
1536               additional_error))
1537             goto failure;
1538         
1539           break;
1540         case 'f':       /* Speedup of the target search
1541 .  */
1542         
1543         
1544           if (update_arg( (void *)&(args_info->fast_folding_arg), 
1545                &(args_info->fast_folding_orig), &(args_info->fast_folding_given),
1546               &(local_args_info.fast_folding_given), optarg, 0, "0", ARG_INT,
1547               check_ambiguity, override, 0, 0,
1548               "fast-folding", 'f',
1549               additional_error))
1550             goto failure;
1551         
1552           break;
1553         case 'V':       /* Rescale all opening energy by a factor V
1554 .  */
1555         
1556         
1557           if (update_arg( (void *)&(args_info->scale_accessibility_arg), 
1558                &(args_info->scale_accessibility_orig), &(args_info->scale_accessibility_given),
1559               &(local_args_info.scale_accessibility_given), optarg, 0, "1.0", ARG_DOUBLE,
1560               check_ambiguity, override, 0, 0,
1561               "scale-accessibility", 'V',
1562               additional_error))
1563             goto failure;
1564         
1565           break;
1566         case 'C':       /* Calculate structures subject to constraints.
1567 .  */
1568         
1569         
1570           if (update_arg((void *)&(args_info->constraint_flag), 0, &(args_info->constraint_given),
1571               &(local_args_info.constraint_given), optarg, 0, 0, ARG_FLAG,
1572               check_ambiguity, override, 1, 0, "constraint", 'C',
1573               additional_error))
1574             goto failure;
1575         
1576           break;
1577         case 'A':       /* Tells RNAplex to compute interactions based on alignments
1578 .  */
1579         
1580         
1581           if (update_arg((void *)&(args_info->alignment_mode_flag), 0, &(args_info->alignment_mode_given),
1582               &(local_args_info.alignment_mode_given), optarg, 0, 0, ARG_FLAG,
1583               check_ambiguity, override, 1, 0, "alignment-mode", 'A',
1584               additional_error))
1585             goto failure;
1586         
1587           break;
1588         case 'k':       /* If set, RNAplex will convert all opening energy file in a directory set by the -a option into binary opening energy files
1589 .  */
1590         
1591         
1592           if (update_arg((void *)&(args_info->convert_to_bin_flag), 0, &(args_info->convert_to_bin_given),
1593               &(local_args_info.convert_to_bin_given), optarg, 0, 0, ARG_FLAG,
1594               check_ambiguity, override, 1, 0, "convert-to-bin", 'k',
1595               additional_error))
1596             goto failure;
1597         
1598           break;
1599         case 'z':       /* Distance between target 3' ends of two consecutive duplexes
1600 .  */
1601         
1602         
1603           if (update_arg( (void *)&(args_info->duplex_distance_arg), 
1604                &(args_info->duplex_distance_orig), &(args_info->duplex_distance_given),
1605               &(local_args_info.duplex_distance_given), optarg, 0, "0", ARG_INT,
1606               check_ambiguity, override, 0, 0,
1607               "duplex-distance", 'z',
1608               additional_error))
1609             goto failure;
1610         
1611           break;
1612         case 'e':       /* Minimal energy for a duplex to be returned
1613 .  */
1614         
1615         
1616           if (update_arg( (void *)&(args_info->energy_threshold_arg), 
1617                &(args_info->energy_threshold_orig), &(args_info->energy_threshold_given),
1618               &(local_args_info.energy_threshold_given), optarg, 0, "-100000", ARG_DOUBLE,
1619               check_ambiguity, override, 0, 0,
1620               "energy-threshold", 'e',
1621               additional_error))
1622             goto failure;
1623         
1624           break;
1625         case 'I':       /* Draw an alignment annotated interaction from RNAplex
1626 .  */
1627         
1628         
1629           if (update_arg( (void *)&(args_info->produce_ps_arg), 
1630                &(args_info->produce_ps_orig), &(args_info->produce_ps_given),
1631               &(local_args_info.produce_ps_given), optarg, 0, 0, ARG_STRING,
1632               check_ambiguity, override, 0, 0,
1633               "produce-ps", 'I',
1634               additional_error))
1635             goto failure;
1636         
1637           break;
1638         case 'L':       /* Tells how large the region around the target site should be for redrawing the alignment interaction
1639 .  */
1640         
1641         
1642           if (update_arg( (void *)&(args_info->WindowLength_arg), 
1643                &(args_info->WindowLength_orig), &(args_info->WindowLength_given),
1644               &(local_args_info.WindowLength_given), optarg, 0, "1", ARG_INT,
1645               check_ambiguity, override, 0, 0,
1646               "WindowLength", 'L',
1647               additional_error))
1648             goto failure;
1649         
1650           break;
1651
1652         case 0: /* Long option with no short option */
1653           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1654             RNAplex_cmdline_parser_print_detailed_help ();
1655             RNAplex_cmdline_parser_free (&local_args_info);
1656             exit (EXIT_SUCCESS);
1657           }
1658
1659           if (strcmp (long_options[option_index].name, "version") == 0) {
1660             RNAplex_cmdline_parser_print_version ();
1661             RNAplex_cmdline_parser_free (&local_args_info);
1662             exit (EXIT_SUCCESS);
1663           }
1664
1665         case '?':       /* Invalid option.  */
1666           /* `getopt_long' already printed an error message.  */
1667           goto failure;
1668
1669         default:        /* bug: option not considered.  */
1670           fprintf (stderr, "%s: option unknown: %c%s\n", RNAPLEX_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1671           abort ();
1672         } /* switch */
1673     } /* while */
1674
1675
1676
1677
1678   RNAplex_cmdline_parser_release (&local_args_info);
1679
1680   if ( error )
1681     return (EXIT_FAILURE);
1682
1683   return 0;
1684
1685 failure:
1686   
1687   RNAplex_cmdline_parser_release (&local_args_info);
1688   return (EXIT_FAILURE);
1689 }