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