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