1 /*
2   File autogenerated by gengetopt version 2.23
3   generated with the following command:
4   /usr/bin/gengetopt -i RNAup.ggo --file-name=RNAup_cmdl --include-getopt --default-optional --func-name=RNAup_cmdline_parser --arg-struct-name=RNAup_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 "RNAup_cmdl.h"
26 
27 const char *RNAup_args_info_purpose = "Calculate the thermodynamics of RNA-RNA interactions";
28 
29 const char *RNAup_args_info_usage = "Usage: RNAup [OPTION]...";
30 
31 const char *RNAup_args_info_versiontext = "";
32 
33 const char *RNAup_args_info_description = "RNAup calculates the thermodynamics of RNA-RNA interactions, by decomposing the\nbinding into two stages. (1) First the probability that a potential binding\nsites remains unpaired (equivalent to the free energy needed to open the site)\nis computed. (2) Then this accessibility is combined with the interaction\nenergy to obtain the total binding energy. All calculations are done by\ncomputing partition functions over all possible conformations.\n";
34 
35 const char *RNAup_args_info_detailed_help[] = {
36   "  -h, --help                  Print help and exit",
37   "      --detailed-help         Print help, including all details and hidden\n                                options, and exit",
38   "      --full-help             Print help, including hidden options, and exit",
39   "  -V, --version               Print version and exit",
40   "\nGeneral Options:",
41   "  Below are command line options which alter the general behavior of this\n  program\n",
42   "  -C, --constraint            Apply structural constraint(s) during prediction.\n                                (default=off)",
43   "  The program first reads the sequence(s), then a dot-bracket like string\n  containing constraints on the structure. The following symbols are\n  recognized:\n   '.' ... no constraint for this base\n\n   'x' ... the base is unpaired\n\n   '<' ... the base pairs downstream, i.e. i is paired with j > i\n\n   '>' ... the base pairs upstream, i.e. i is paired with j < i\n\n   '()' ... base i pairs with base j\n\n   '|' ... the corresponding base has to be paired intermolecularily (only for\n  interaction mode)\n",
44   "  -o, --no_output_file        Do not produce an output file.  (default=off)",
45   "      --no_header             Do not produce a header with the command line\n                                parameters used in the outputfile.\n                                (default=off)",
46   "      --noconv                Do not automatically substitude nucleotide \"T\"\n                                with \"U\".  (default=off)",
47   "\nCalculations of opening energies:",
48   "  -u, --ulength=length        Specify the length of the unstructured region in\n                                the output.  (default=`4')",
49   "  The probability of being unpaired is plotted on the right border of the\n  unpaired region. You can specify up to 20 different length values: use \"-\"\n  to specify a range of continuous values (e.g. -u 4-8) or specify a list of\n  comma separated values (e.g. -u 4,8,15).\n",
50   "  -c, --contributions=SHIME   Specify the contributions listed in the output.\n                                (default=`S')",
51   "  By default only the full probability of being unpaired is plotted. The -c\n  option allows one to get the different contributions (c) to the probability\n  of being unpaired: The full probability of being unpaired (\"S\" is the sum\n  of the probability of being unpaired in the exterior loop (\"E\"), within a\n  hairpin loop (\"H\"), within an interior loop (\"I\") and within a multiloop\n  (\"M\"). Any combination of these letters may be given.\n",
52   "\nCalculations of RNA-RNA interactions:",
53   "  -w, --window=INT            Set the maximal length of the region of\n                                interaction.  (default=`25')",
54   "  -b, --include_both          Include the probability of unpaired regions in\n                                both (b) RNAs.  (default=off)",
55   "  By default only the probability of being unpaired in the longer RNA (target)\n  is used.\n",
56   "  -5, --extend5=INT           Extend the region of interaction in the target to\n                                some residues on the 5' side.",
57   "  The underlying assumption is that it is favorable for an interaction if not\n  only the direct region of contact is unpaired but also a few residues 5'\n",
58   "  -3, --extend3=INT           Extend the region of interaction in the target to\n                                some residues on the 3' side.",
59   "  The underlying assumption is that it is favorable for an interaction if not\n  only the direct region of contact is unpaired but also a few residues 3'\n",
60   "      --interaction_pairwise  Activate pairwise interaction mode.\n                                (default=off)",
61   "  The first sequence interacts with the 2nd, the third with the 4th etc. If\n  activated, two interacting sequences may be given in a single line separated\n  by \"&\" or each sequence may be given on an extra line.\n",
62   "      --interaction_first     Activate interaction mode using first sequence\n                                only.  (default=off)",
63   "  The interaction of each sequence with the first one is calculated (e.g.\n  interaction of one mRNA with many small RNAs). Each sequence has to be given\n  on an extra line\n",
64   "\nModel Details:",
65   "  -S, --pfScale=DOUBLE        Set scaling factor for Boltzmann factors to\n                                prevent under/overflows.",
66   "  In the calculation of the pf use scale*mfe as an estimate for the ensemble\n  free energy (used to avoid overflows). The default is 1.07, useful values are\n  1.0 to 1.2. Occasionally needed for long sequences.\n  You can also recompile the program to use double precision (see the README\n  file).\n",
67   "  -T, --temp=DOUBLE           Rescale energy parameters to a temperature in\n                                degrees centigrade.  (default=`37.0')",
68   "  -4, --noTetra               Do not include special tabulated stabilizing\n                                energies for tri-, tetra- and hexaloop\n                                hairpins.  (default=off)",
69   "  Mostly for testing.\n",
70   "  -d, --dangles=INT           Specify \"dangling end\" model for bases adjacent\n                                to helices in free ends and multi-loops.\n                                (default=`2')",
71   "  \n  With -d2 dangling energies will be added for the bases adjacent to a helix on\n  both sides in any case.\n   The option -d0 ignores dangling ends altogether (mostly for debugging).\n",
72   "      --noLP                  Produce structures without lonely pairs (helices\n                                of length 1).  (default=off)",
73   "  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",
74   "      --noGU                  Do not allow GU pairs.  (default=off)",
75   "      --noClosingGU           Do not allow GU pairs at the end of helices.\n                                (default=off)",
76   "  -P, --paramFile=paramfile   Read energy parameters from paramfile, instead of\n                                using the default parameter set.",
77   "  Different sets of energy parameters for RNA and DNA should accompany your\n  distribution.\n  See the RNAlib documentation for details on the file format. When passing the\n  placeholder file name \"DNA\", DNA parameters are loaded without the need to\n  actually specify any input file.\n",
78   "      --nsp=STRING            Allow other pairs in addition to the usual\n                                AU,GC,and GU pairs.",
79   "  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",
80   "  -e, --energyModel=INT       Set energy model.",
81   "  Rarely used option to fold sequences from the artificial ABCD... alphabet,\n  where A pairs B, C-D etc.  Use the energy parameters for GC (-e 1) or AU (-e\n  2) pairs.\n",
82   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n\n",
83     0
84 };
85 static void
init_full_help_array(void)86 init_full_help_array(void)
87 {
88   RNAup_args_info_full_help[0] = RNAup_args_info_detailed_help[0];
89   RNAup_args_info_full_help[1] = RNAup_args_info_detailed_help[1];
90   RNAup_args_info_full_help[2] = RNAup_args_info_detailed_help[2];
91   RNAup_args_info_full_help[3] = RNAup_args_info_detailed_help[3];
92   RNAup_args_info_full_help[4] = RNAup_args_info_detailed_help[4];
93   RNAup_args_info_full_help[5] = RNAup_args_info_detailed_help[5];
94   RNAup_args_info_full_help[6] = RNAup_args_info_detailed_help[6];
95   RNAup_args_info_full_help[7] = RNAup_args_info_detailed_help[8];
96   RNAup_args_info_full_help[8] = RNAup_args_info_detailed_help[9];
97   RNAup_args_info_full_help[9] = RNAup_args_info_detailed_help[10];
98   RNAup_args_info_full_help[10] = RNAup_args_info_detailed_help[11];
99   RNAup_args_info_full_help[11] = RNAup_args_info_detailed_help[12];
100   RNAup_args_info_full_help[12] = RNAup_args_info_detailed_help[14];
101   RNAup_args_info_full_help[13] = RNAup_args_info_detailed_help[16];
102   RNAup_args_info_full_help[14] = RNAup_args_info_detailed_help[17];
103   RNAup_args_info_full_help[15] = RNAup_args_info_detailed_help[18];
104   RNAup_args_info_full_help[16] = RNAup_args_info_detailed_help[20];
105   RNAup_args_info_full_help[17] = RNAup_args_info_detailed_help[22];
106   RNAup_args_info_full_help[18] = RNAup_args_info_detailed_help[24];
107   RNAup_args_info_full_help[19] = RNAup_args_info_detailed_help[26];
108   RNAup_args_info_full_help[20] = RNAup_args_info_detailed_help[28];
109   RNAup_args_info_full_help[21] = RNAup_args_info_detailed_help[29];
110   RNAup_args_info_full_help[22] = RNAup_args_info_detailed_help[31];
111   RNAup_args_info_full_help[23] = RNAup_args_info_detailed_help[32];
112   RNAup_args_info_full_help[24] = RNAup_args_info_detailed_help[34];
113   RNAup_args_info_full_help[25] = RNAup_args_info_detailed_help[36];
114   RNAup_args_info_full_help[26] = RNAup_args_info_detailed_help[38];
115   RNAup_args_info_full_help[27] = RNAup_args_info_detailed_help[39];
116   RNAup_args_info_full_help[28] = RNAup_args_info_detailed_help[40];
117   RNAup_args_info_full_help[29] = RNAup_args_info_detailed_help[42];
118   RNAup_args_info_full_help[30] = RNAup_args_info_detailed_help[44];
119   RNAup_args_info_full_help[31] = RNAup_args_info_detailed_help[46];
120   RNAup_args_info_full_help[32] = 0;
121 
122 }
123 
124 const char *RNAup_args_info_full_help[33];
125 
126 static void
init_help_array(void)127 init_help_array(void)
128 {
129   RNAup_args_info_help[0] = RNAup_args_info_detailed_help[0];
130   RNAup_args_info_help[1] = RNAup_args_info_detailed_help[1];
131   RNAup_args_info_help[2] = RNAup_args_info_detailed_help[2];
132   RNAup_args_info_help[3] = RNAup_args_info_detailed_help[3];
133   RNAup_args_info_help[4] = RNAup_args_info_detailed_help[4];
134   RNAup_args_info_help[5] = RNAup_args_info_detailed_help[5];
135   RNAup_args_info_help[6] = RNAup_args_info_detailed_help[6];
136   RNAup_args_info_help[7] = RNAup_args_info_detailed_help[8];
137   RNAup_args_info_help[8] = RNAup_args_info_detailed_help[9];
138   RNAup_args_info_help[9] = RNAup_args_info_detailed_help[10];
139   RNAup_args_info_help[10] = RNAup_args_info_detailed_help[11];
140   RNAup_args_info_help[11] = RNAup_args_info_detailed_help[12];
141   RNAup_args_info_help[12] = RNAup_args_info_detailed_help[14];
142   RNAup_args_info_help[13] = RNAup_args_info_detailed_help[16];
143   RNAup_args_info_help[14] = RNAup_args_info_detailed_help[17];
144   RNAup_args_info_help[15] = RNAup_args_info_detailed_help[18];
145   RNAup_args_info_help[16] = RNAup_args_info_detailed_help[20];
146   RNAup_args_info_help[17] = RNAup_args_info_detailed_help[22];
147   RNAup_args_info_help[18] = RNAup_args_info_detailed_help[24];
148   RNAup_args_info_help[19] = RNAup_args_info_detailed_help[26];
149   RNAup_args_info_help[20] = RNAup_args_info_detailed_help[28];
150   RNAup_args_info_help[21] = RNAup_args_info_detailed_help[31];
151   RNAup_args_info_help[22] = RNAup_args_info_detailed_help[32];
152   RNAup_args_info_help[23] = RNAup_args_info_detailed_help[34];
153   RNAup_args_info_help[24] = RNAup_args_info_detailed_help[36];
154   RNAup_args_info_help[25] = RNAup_args_info_detailed_help[38];
155   RNAup_args_info_help[26] = RNAup_args_info_detailed_help[39];
156   RNAup_args_info_help[27] = RNAup_args_info_detailed_help[40];
157   RNAup_args_info_help[28] = RNAup_args_info_detailed_help[46];
158   RNAup_args_info_help[29] = 0;
159 
160 }
161 
162 const char *RNAup_args_info_help[30];
163 
164 typedef enum {ARG_NO
165   , ARG_FLAG
166   , ARG_STRING
167   , ARG_INT
168   , ARG_DOUBLE
169 } RNAup_cmdline_parser_arg_type;
170 
171 static
172 void clear_given (struct RNAup_args_info *args_info);
173 static
174 void clear_args (struct RNAup_args_info *args_info);
175 
176 static int
177 RNAup_cmdline_parser_internal (int argc, char **argv, struct RNAup_args_info *args_info,
178                         struct RNAup_cmdline_parser_params *params, const char *additional_error);
179 
180 static int
181 RNAup_cmdline_parser_required2 (struct RNAup_args_info *args_info, const char *prog_name, const char *additional_error);
182 
183 static char *
184 gengetopt_strdup (const char *s);
185 
186 static
clear_given(struct RNAup_args_info * args_info)187 void clear_given (struct RNAup_args_info *args_info)
188 {
189   args_info->help_given = 0 ;
190   args_info->detailed_help_given = 0 ;
191   args_info->full_help_given = 0 ;
192   args_info->version_given = 0 ;
193   args_info->constraint_given = 0 ;
194   args_info->no_output_file_given = 0 ;
195   args_info->no_header_given = 0 ;
196   args_info->noconv_given = 0 ;
197   args_info->ulength_given = 0 ;
198   args_info->contributions_given = 0 ;
199   args_info->window_given = 0 ;
200   args_info->include_both_given = 0 ;
201   args_info->extend5_given = 0 ;
202   args_info->extend3_given = 0 ;
203   args_info->interaction_pairwise_given = 0 ;
204   args_info->interaction_first_given = 0 ;
205   args_info->pfScale_given = 0 ;
206   args_info->temp_given = 0 ;
207   args_info->noTetra_given = 0 ;
208   args_info->dangles_given = 0 ;
209   args_info->noLP_given = 0 ;
210   args_info->noGU_given = 0 ;
211   args_info->noClosingGU_given = 0 ;
212   args_info->paramFile_given = 0 ;
213   args_info->nsp_given = 0 ;
214   args_info->energyModel_given = 0 ;
215 }
216 
217 static
clear_args(struct RNAup_args_info * args_info)218 void clear_args (struct RNAup_args_info *args_info)
219 {
220   FIX_UNUSED (args_info);
221   args_info->constraint_flag = 0;
222   args_info->no_output_file_flag = 0;
223   args_info->no_header_flag = 0;
224   args_info->noconv_flag = 0;
225   args_info->ulength_arg = NULL;
226   args_info->ulength_orig = NULL;
227   args_info->contributions_arg = gengetopt_strdup ("S");
228   args_info->contributions_orig = NULL;
229   args_info->window_arg = 25;
230   args_info->window_orig = NULL;
231   args_info->include_both_flag = 0;
232   args_info->extend5_orig = NULL;
233   args_info->extend3_orig = NULL;
234   args_info->interaction_pairwise_flag = 0;
235   args_info->interaction_first_flag = 0;
236   args_info->pfScale_orig = NULL;
237   args_info->temp_arg = 37.0;
238   args_info->temp_orig = NULL;
239   args_info->noTetra_flag = 0;
240   args_info->dangles_arg = 2;
241   args_info->dangles_orig = NULL;
242   args_info->noLP_flag = 0;
243   args_info->noGU_flag = 0;
244   args_info->noClosingGU_flag = 0;
245   args_info->paramFile_arg = NULL;
246   args_info->paramFile_orig = NULL;
247   args_info->nsp_arg = NULL;
248   args_info->nsp_orig = NULL;
249   args_info->energyModel_orig = NULL;
250 
251 }
252 
253 static
init_args_info(struct RNAup_args_info * args_info)254 void init_args_info(struct RNAup_args_info *args_info)
255 {
256   init_full_help_array();
257   init_help_array();
258   args_info->help_help = RNAup_args_info_detailed_help[0] ;
259   args_info->detailed_help_help = RNAup_args_info_detailed_help[1] ;
260   args_info->full_help_help = RNAup_args_info_detailed_help[2] ;
261   args_info->version_help = RNAup_args_info_detailed_help[3] ;
262   args_info->constraint_help = RNAup_args_info_detailed_help[6] ;
263   args_info->no_output_file_help = RNAup_args_info_detailed_help[8] ;
264   args_info->no_header_help = RNAup_args_info_detailed_help[9] ;
265   args_info->noconv_help = RNAup_args_info_detailed_help[10] ;
266   args_info->ulength_help = RNAup_args_info_detailed_help[12] ;
267   args_info->ulength_min = 0;
268   args_info->ulength_max = 0;
269   args_info->contributions_help = RNAup_args_info_detailed_help[14] ;
270   args_info->window_help = RNAup_args_info_detailed_help[17] ;
271   args_info->include_both_help = RNAup_args_info_detailed_help[18] ;
272   args_info->extend5_help = RNAup_args_info_detailed_help[20] ;
273   args_info->extend3_help = RNAup_args_info_detailed_help[22] ;
274   args_info->interaction_pairwise_help = RNAup_args_info_detailed_help[24] ;
275   args_info->interaction_first_help = RNAup_args_info_detailed_help[26] ;
276   args_info->pfScale_help = RNAup_args_info_detailed_help[29] ;
277   args_info->temp_help = RNAup_args_info_detailed_help[31] ;
278   args_info->noTetra_help = RNAup_args_info_detailed_help[32] ;
279   args_info->dangles_help = RNAup_args_info_detailed_help[34] ;
280   args_info->noLP_help = RNAup_args_info_detailed_help[36] ;
281   args_info->noGU_help = RNAup_args_info_detailed_help[38] ;
282   args_info->noClosingGU_help = RNAup_args_info_detailed_help[39] ;
283   args_info->paramFile_help = RNAup_args_info_detailed_help[40] ;
284   args_info->nsp_help = RNAup_args_info_detailed_help[42] ;
285   args_info->energyModel_help = RNAup_args_info_detailed_help[44] ;
286 
287 }
288 
289 void
RNAup_cmdline_parser_print_version(void)290 RNAup_cmdline_parser_print_version (void)
291 {
292   printf ("%s %s\n",
293      (strlen(RNAUP_CMDLINE_PARSER_PACKAGE_NAME) ? RNAUP_CMDLINE_PARSER_PACKAGE_NAME : RNAUP_CMDLINE_PARSER_PACKAGE),
294      RNAUP_CMDLINE_PARSER_VERSION);
295 
296   if (strlen(RNAup_args_info_versiontext) > 0)
297     printf("\n%s\n", RNAup_args_info_versiontext);
298 }
299 
print_help_common(void)300 static void print_help_common(void)
301 {
302 	size_t len_purpose = strlen(RNAup_args_info_purpose);
303 	size_t len_usage = strlen(RNAup_args_info_usage);
304 
305 	if (len_usage > 0) {
306 		printf("%s\n", RNAup_args_info_usage);
307 	}
308 	if (len_purpose > 0) {
309 		printf("%s\n", RNAup_args_info_purpose);
310 	}
311 
312 	if (len_usage || len_purpose) {
313 		printf("\n");
314 	}
315 
316 	if (strlen(RNAup_args_info_description) > 0) {
317 		printf("%s\n\n", RNAup_args_info_description);
318 	}
319 }
320 
321 void
RNAup_cmdline_parser_print_help(void)322 RNAup_cmdline_parser_print_help (void)
323 {
324   int i = 0;
325   print_help_common();
326   while (RNAup_args_info_help[i])
327     printf("%s\n", RNAup_args_info_help[i++]);
328 }
329 
330 void
RNAup_cmdline_parser_print_full_help(void)331 RNAup_cmdline_parser_print_full_help (void)
332 {
333   int i = 0;
334   print_help_common();
335   while (RNAup_args_info_full_help[i])
336     printf("%s\n", RNAup_args_info_full_help[i++]);
337 }
338 
339 void
RNAup_cmdline_parser_print_detailed_help(void)340 RNAup_cmdline_parser_print_detailed_help (void)
341 {
342   int i = 0;
343   print_help_common();
344   while (RNAup_args_info_detailed_help[i])
345     printf("%s\n", RNAup_args_info_detailed_help[i++]);
346 }
347 
348 void
RNAup_cmdline_parser_init(struct RNAup_args_info * args_info)349 RNAup_cmdline_parser_init (struct RNAup_args_info *args_info)
350 {
351   clear_given (args_info);
352   clear_args (args_info);
353   init_args_info (args_info);
354 }
355 
356 void
RNAup_cmdline_parser_params_init(struct RNAup_cmdline_parser_params * params)357 RNAup_cmdline_parser_params_init(struct RNAup_cmdline_parser_params *params)
358 {
359   if (params)
360     {
361       params->override = 0;
362       params->initialize = 1;
363       params->check_required = 1;
364       params->check_ambiguity = 0;
365       params->print_errors = 1;
366     }
367 }
368 
369 struct RNAup_cmdline_parser_params *
RNAup_cmdline_parser_params_create(void)370 RNAup_cmdline_parser_params_create(void)
371 {
372   struct RNAup_cmdline_parser_params *params =
373     (struct RNAup_cmdline_parser_params *)malloc(sizeof(struct RNAup_cmdline_parser_params));
374   RNAup_cmdline_parser_params_init(params);
375   return params;
376 }
377 
378 static void
free_string_field(char ** s)379 free_string_field (char **s)
380 {
381   if (*s)
382     {
383       free (*s);
384       *s = 0;
385     }
386 }
387 
388 /** @brief generic value variable */
389 union generic_value {
390     int int_arg;
391     double double_arg;
392     char *string_arg;
393     const char *default_string_arg;
394 };
395 
396 /** @brief holds temporary values for multiple options */
397 struct generic_list
398 {
399   union generic_value arg;
400   char *orig;
401   struct generic_list *next;
402 };
403 
404 /**
405  * @brief add a node at the head of the list
406  */
add_node(struct generic_list ** list)407 static void add_node(struct generic_list **list) {
408   struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
409   new_node->next = *list;
410   *list = new_node;
411   new_node->arg.string_arg = 0;
412   new_node->orig = 0;
413 }
414 
415 
416 static void
free_multiple_string_field(unsigned int len,char *** arg,char *** orig)417 free_multiple_string_field(unsigned int len, char ***arg, char ***orig)
418 {
419   unsigned int i;
420   if (*arg) {
421     for (i = 0; i < len; ++i)
422       {
423         free_string_field(&((*arg)[i]));
424         free_string_field(&((*orig)[i]));
425       }
426     free_string_field(&((*arg)[0])); /* free default string */
427 
428     free (*arg);
429     *arg = 0;
430     free (*orig);
431     *orig = 0;
432   }
433 }
434 
435 static void
RNAup_cmdline_parser_release(struct RNAup_args_info * args_info)436 RNAup_cmdline_parser_release (struct RNAup_args_info *args_info)
437 {
438 
439   free_multiple_string_field (args_info->ulength_given, &(args_info->ulength_arg), &(args_info->ulength_orig));
440   free_string_field (&(args_info->contributions_arg));
441   free_string_field (&(args_info->contributions_orig));
442   free_string_field (&(args_info->window_orig));
443   free_string_field (&(args_info->extend5_orig));
444   free_string_field (&(args_info->extend3_orig));
445   free_string_field (&(args_info->pfScale_orig));
446   free_string_field (&(args_info->temp_orig));
447   free_string_field (&(args_info->dangles_orig));
448   free_string_field (&(args_info->paramFile_arg));
449   free_string_field (&(args_info->paramFile_orig));
450   free_string_field (&(args_info->nsp_arg));
451   free_string_field (&(args_info->nsp_orig));
452   free_string_field (&(args_info->energyModel_orig));
453 
454 
455 
456   clear_given (args_info);
457 }
458 
459 
460 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])461 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
462 {
463   FIX_UNUSED (values);
464   if (arg) {
465     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
466   } else {
467     fprintf(outfile, "%s\n", opt);
468   }
469 }
470 
471 static void
write_multiple_into_file(FILE * outfile,int len,const char * opt,char ** arg,const char * values[])472 write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])
473 {
474   int i;
475 
476   for (i = 0; i < len; ++i)
477     write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
478 }
479 
480 int
RNAup_cmdline_parser_dump(FILE * outfile,struct RNAup_args_info * args_info)481 RNAup_cmdline_parser_dump(FILE *outfile, struct RNAup_args_info *args_info)
482 {
483   int i = 0;
484 
485   if (!outfile)
486     {
487       fprintf (stderr, "%s: cannot dump options to stream\n", RNAUP_CMDLINE_PARSER_PACKAGE);
488       return EXIT_FAILURE;
489     }
490 
491   if (args_info->help_given)
492     write_into_file(outfile, "help", 0, 0 );
493   if (args_info->detailed_help_given)
494     write_into_file(outfile, "detailed-help", 0, 0 );
495   if (args_info->full_help_given)
496     write_into_file(outfile, "full-help", 0, 0 );
497   if (args_info->version_given)
498     write_into_file(outfile, "version", 0, 0 );
499   if (args_info->constraint_given)
500     write_into_file(outfile, "constraint", 0, 0 );
501   if (args_info->no_output_file_given)
502     write_into_file(outfile, "no_output_file", 0, 0 );
503   if (args_info->no_header_given)
504     write_into_file(outfile, "no_header", 0, 0 );
505   if (args_info->noconv_given)
506     write_into_file(outfile, "noconv", 0, 0 );
507   write_multiple_into_file(outfile, args_info->ulength_given, "ulength", args_info->ulength_orig, 0);
508   if (args_info->contributions_given)
509     write_into_file(outfile, "contributions", args_info->contributions_orig, 0);
510   if (args_info->window_given)
511     write_into_file(outfile, "window", args_info->window_orig, 0);
512   if (args_info->include_both_given)
513     write_into_file(outfile, "include_both", 0, 0 );
514   if (args_info->extend5_given)
515     write_into_file(outfile, "extend5", args_info->extend5_orig, 0);
516   if (args_info->extend3_given)
517     write_into_file(outfile, "extend3", args_info->extend3_orig, 0);
518   if (args_info->interaction_pairwise_given)
519     write_into_file(outfile, "interaction_pairwise", 0, 0 );
520   if (args_info->interaction_first_given)
521     write_into_file(outfile, "interaction_first", 0, 0 );
522   if (args_info->pfScale_given)
523     write_into_file(outfile, "pfScale", args_info->pfScale_orig, 0);
524   if (args_info->temp_given)
525     write_into_file(outfile, "temp", args_info->temp_orig, 0);
526   if (args_info->noTetra_given)
527     write_into_file(outfile, "noTetra", 0, 0 );
528   if (args_info->dangles_given)
529     write_into_file(outfile, "dangles", args_info->dangles_orig, 0);
530   if (args_info->noLP_given)
531     write_into_file(outfile, "noLP", 0, 0 );
532   if (args_info->noGU_given)
533     write_into_file(outfile, "noGU", 0, 0 );
534   if (args_info->noClosingGU_given)
535     write_into_file(outfile, "noClosingGU", 0, 0 );
536   if (args_info->paramFile_given)
537     write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
538   if (args_info->nsp_given)
539     write_into_file(outfile, "nsp", args_info->nsp_orig, 0);
540   if (args_info->energyModel_given)
541     write_into_file(outfile, "energyModel", args_info->energyModel_orig, 0);
542 
543 
544   i = EXIT_SUCCESS;
545   return i;
546 }
547 
548 int
RNAup_cmdline_parser_file_save(const char * filename,struct RNAup_args_info * args_info)549 RNAup_cmdline_parser_file_save(const char *filename, struct RNAup_args_info *args_info)
550 {
551   FILE *outfile;
552   int i = 0;
553 
554   outfile = fopen(filename, "w");
555 
556   if (!outfile)
557     {
558       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNAUP_CMDLINE_PARSER_PACKAGE, filename);
559       return EXIT_FAILURE;
560     }
561 
562   i = RNAup_cmdline_parser_dump(outfile, args_info);
563   fclose (outfile);
564 
565   return i;
566 }
567 
568 void
RNAup_cmdline_parser_free(struct RNAup_args_info * args_info)569 RNAup_cmdline_parser_free (struct RNAup_args_info *args_info)
570 {
571   RNAup_cmdline_parser_release (args_info);
572 }
573 
574 /** @brief replacement of strdup, which is not standard */
575 char *
gengetopt_strdup(const char * s)576 gengetopt_strdup (const char *s)
577 {
578   char *result = 0;
579   if (!s)
580     return result;
581 
582   result = (char*)malloc(strlen(s) + 1);
583   if (result == (char*)0)
584     return (char*)0;
585   strcpy(result, s);
586   return result;
587 }
588 
589 static char *
get_multiple_arg_token(const char * arg)590 get_multiple_arg_token(const char *arg)
591 {
592   const char *tok;
593   char *ret;
594   size_t len, num_of_escape, i, j;
595 
596   if (!arg)
597     return 0;
598 
599   tok = strchr (arg, ',');
600   num_of_escape = 0;
601 
602   /* make sure it is not escaped */
603   while (tok)
604     {
605       if (*(tok-1) == '\\')
606         {
607           /* find the next one */
608           tok = strchr (tok+1, ',');
609           ++num_of_escape;
610         }
611       else
612         break;
613     }
614 
615   if (tok)
616     len = (size_t)(tok - arg + 1);
617   else
618     len = strlen (arg) + 1;
619 
620   len -= num_of_escape;
621 
622   ret = (char *) malloc (len);
623 
624   i = 0;
625   j = 0;
626   while (arg[i] && (j < len-1))
627     {
628       if (arg[i] == '\\' &&
629 	  arg[ i + 1 ] &&
630 	  arg[ i + 1 ] == ',')
631         ++i;
632 
633       ret[j++] = arg[i++];
634     }
635 
636   ret[len-1] = '\0';
637 
638   return ret;
639 }
640 
641 static const char *
get_multiple_arg_token_next(const char * arg)642 get_multiple_arg_token_next(const char *arg)
643 {
644   const char *tok;
645 
646   if (!arg)
647     return 0;
648 
649   tok = strchr (arg, ',');
650 
651   /* make sure it is not escaped */
652   while (tok)
653     {
654       if (*(tok-1) == '\\')
655         {
656           /* find the next one */
657           tok = strchr (tok+1, ',');
658         }
659       else
660         break;
661     }
662 
663   if (! tok || strlen(tok) == 1)
664     return 0;
665 
666   return tok+1;
667 }
668 
669 static int
670 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);
671 
672 int
check_multiple_option_occurrences(const char * prog_name,unsigned int option_given,unsigned int min,unsigned int max,const char * option_desc)673 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)
674 {
675   int error_occurred = 0;
676 
677   if (option_given && (min > 0 || max > 0))
678     {
679       if (min > 0 && max > 0)
680         {
681           if (min == max)
682             {
683               /* specific occurrences */
684               if (option_given != (unsigned int) min)
685                 {
686                   fprintf (stderr, "%s: %s option occurrences must be %d\n",
687                     prog_name, option_desc, min);
688                   error_occurred = 1;
689                 }
690             }
691           else if (option_given < (unsigned int) min
692                 || option_given > (unsigned int) max)
693             {
694               /* range occurrences */
695               fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
696                 prog_name, option_desc, min, max);
697               error_occurred = 1;
698             }
699         }
700       else if (min > 0)
701         {
702           /* at least check */
703           if (option_given < min)
704             {
705               fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
706                 prog_name, option_desc, min);
707               error_occurred = 1;
708             }
709         }
710       else if (max > 0)
711         {
712           /* at most check */
713           if (option_given > max)
714             {
715               fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
716                 prog_name, option_desc, max);
717               error_occurred = 1;
718             }
719         }
720     }
721 
722   return error_occurred;
723 }
724 int
RNAup_cmdline_parser(int argc,char ** argv,struct RNAup_args_info * args_info)725 RNAup_cmdline_parser (int argc, char **argv, struct RNAup_args_info *args_info)
726 {
727   return RNAup_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
728 }
729 
730 int
RNAup_cmdline_parser_ext(int argc,char ** argv,struct RNAup_args_info * args_info,struct RNAup_cmdline_parser_params * params)731 RNAup_cmdline_parser_ext (int argc, char **argv, struct RNAup_args_info *args_info,
732                    struct RNAup_cmdline_parser_params *params)
733 {
734   int result;
735   result = RNAup_cmdline_parser_internal (argc, argv, args_info, params, 0);
736 
737   if (result == EXIT_FAILURE)
738     {
739       RNAup_cmdline_parser_free (args_info);
740       exit (EXIT_FAILURE);
741     }
742 
743   return result;
744 }
745 
746 int
RNAup_cmdline_parser2(int argc,char ** argv,struct RNAup_args_info * args_info,int override,int initialize,int check_required)747 RNAup_cmdline_parser2 (int argc, char **argv, struct RNAup_args_info *args_info, int override, int initialize, int check_required)
748 {
749   int result;
750   struct RNAup_cmdline_parser_params params;
751 
752   params.override = override;
753   params.initialize = initialize;
754   params.check_required = check_required;
755   params.check_ambiguity = 0;
756   params.print_errors = 1;
757 
758   result = RNAup_cmdline_parser_internal (argc, argv, args_info, &params, 0);
759 
760   if (result == EXIT_FAILURE)
761     {
762       RNAup_cmdline_parser_free (args_info);
763       exit (EXIT_FAILURE);
764     }
765 
766   return result;
767 }
768 
769 int
RNAup_cmdline_parser_required(struct RNAup_args_info * args_info,const char * prog_name)770 RNAup_cmdline_parser_required (struct RNAup_args_info *args_info, const char *prog_name)
771 {
772   int result = EXIT_SUCCESS;
773 
774   if (RNAup_cmdline_parser_required2(args_info, prog_name, 0) > 0)
775     result = EXIT_FAILURE;
776 
777   if (result == EXIT_FAILURE)
778     {
779       RNAup_cmdline_parser_free (args_info);
780       exit (EXIT_FAILURE);
781     }
782 
783   return result;
784 }
785 
786 int
RNAup_cmdline_parser_required2(struct RNAup_args_info * args_info,const char * prog_name,const char * additional_error)787 RNAup_cmdline_parser_required2 (struct RNAup_args_info *args_info, const char *prog_name, const char *additional_error)
788 {
789   int error_occurred = 0;
790   FIX_UNUSED (additional_error);
791 
792   /* checks for required options */
793   if (check_multiple_option_occurrences(prog_name, args_info->ulength_given, args_info->ulength_min, args_info->ulength_max, "'--ulength' ('-u')"))
794      error_occurred = 1;
795 
796 
797   /* checks for dependences among options */
798 
799   return error_occurred;
800 }
801 
802 /*
803  * Extracted from the glibc source tree, version 2.3.6
804  *
805  * Licensed under the GPL as per the whole glibc source tree.
806  *
807  * This file was modified so that getopt_long can be called
808  * many times without risking previous memory to be spoiled.
809  *
810  * Modified by Andre Noll and Lorenzo Bettini for use in
811  * GNU gengetopt generated files.
812  *
813  */
814 
815 /*
816  * we must include anything we need since this file is not thought to be
817  * inserted in a file already using getopt.h
818  *
819  * Lorenzo
820  */
821 
822 struct option
823 {
824   const char *name;
825   /* has_arg can't be an enum because some compilers complain about
826      type mismatches in all the code that assumes it is an int.  */
827   int has_arg;
828   int *flag;
829   int val;
830 };
831 
832 /* This version of `getopt' appears to the caller like standard Unix `getopt'
833    but it behaves differently for the user, since it allows the user
834    to intersperse the options with the other arguments.
835 
836    As `getopt' works, it permutes the elements of ARGV so that,
837    when it is done, all the options precede everything else.  Thus
838    all application programs are extended to handle flexible argument order.
839 */
840 /*
841    If the field `flag' is not NULL, it points to a variable that is set
842    to the value given in the field `val' when the option is found, but
843    left unchanged if the option is not found.
844 
845    To have a long-named option do something other than set an `int' to
846    a compiled-in constant, such as set a value from `custom_optarg', set the
847    option's `flag' field to zero and its `val' field to a nonzero
848    value (the equivalent single-letter option character, if there is
849    one).  For long options that have a zero `flag' field, `getopt'
850    returns the contents of the `val' field.  */
851 
852 /* Names for the values of the `has_arg' field of `struct option'.  */
853 #ifndef no_argument
854 #define no_argument		0
855 #endif
856 
857 #ifndef required_argument
858 #define required_argument	1
859 #endif
860 
861 #ifndef optional_argument
862 #define optional_argument	2
863 #endif
864 
865 struct custom_getopt_data {
866 	/*
867 	 * These have exactly the same meaning as the corresponding global variables,
868 	 * except that they are used for the reentrant versions of getopt.
869 	 */
870 	int custom_optind;
871 	int custom_opterr;
872 	int custom_optopt;
873 	char *custom_optarg;
874 
875 	/* True if the internal members have been initialized.  */
876 	int initialized;
877 
878 	/*
879 	 * The next char to be scanned in the option-element in which the last option
880 	 * character we returned was found.  This allows us to pick up the scan where
881 	 * we left off.  If this is zero, or a null string, it means resume the scan by
882 	 * advancing to the next ARGV-element.
883 	 */
884 	char *nextchar;
885 
886 	/*
887 	 * Describe the part of ARGV that contains non-options that have been skipped.
888 	 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
889 	 * the index after the last of them.
890 	 */
891 	int first_nonopt;
892 	int last_nonopt;
893 };
894 
895 /*
896  * the variables optarg, optind, opterr and optopt are renamed with
897  * the custom_ prefix so that they don't interfere with getopt ones.
898  *
899  * Moreover they're static so they are visible only from within the
900  * file where this very file will be included.
901  */
902 
903 /*
904  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
905  * option that takes an argument, the argument value is returned here.
906  */
907 static char *custom_optarg;
908 
909 /*
910  * Index in ARGV of the next element to be scanned.  This is used for
911  * communication to and from the caller and for communication between
912  * successive calls to `custom_getopt'.
913  *
914  * On entry to `custom_getopt', 1 means this is the first call; initialize.
915  *
916  * When `custom_getopt' returns -1, this is the index of the first of the non-option
917  * elements that the caller should itself scan.
918  *
919  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
920  * has been scanned so far.
921  *
922  * 1003.2 says this must be 1 before any call.
923  */
924 static int custom_optind = 1;
925 
926 /*
927  * Callers store zero here to inhibit the error message for unrecognized
928  * options.
929  */
930 static int custom_opterr = 1;
931 
932 /*
933  * Set to an option character which was unrecognized.  This must be initialized
934  * on some systems to avoid linking in the system's own getopt implementation.
935  */
936 static int custom_optopt = '?';
937 
938 /*
939  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
940  * [first_nonopt,last_nonopt) which contains all the non-options that have been
941  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
942  * all the options processed since those non-options were skipped.
943  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
944  * indices of the non-options in ARGV after they are moved.
945  */
exchange(char ** argv,struct custom_getopt_data * d)946 static void exchange(char **argv, struct custom_getopt_data *d)
947 {
948 	int bottom = d->first_nonopt;
949 	int middle = d->last_nonopt;
950 	int top = d->custom_optind;
951 	char *tem;
952 
953 	/*
954 	 * Exchange the shorter segment with the far end of the longer segment.
955 	 * That puts the shorter segment into the right place.  It leaves the
956 	 * longer segment in the right place overall, but it consists of two
957 	 * parts that need to be swapped next.
958 	 */
959 	while (top > middle && middle > bottom) {
960 		if (top - middle > middle - bottom) {
961 			/* Bottom segment is the short one.  */
962 			int len = middle - bottom;
963 			int i;
964 
965 			/* Swap it with the top part of the top segment.  */
966 			for (i = 0; i < len; i++) {
967 				tem = argv[bottom + i];
968 				argv[bottom + i] =
969 					argv[top - (middle - bottom) + i];
970 				argv[top - (middle - bottom) + i] = tem;
971 			}
972 			/* Exclude the moved bottom segment from further swapping.  */
973 			top -= len;
974 		} else {
975 			/* Top segment is the short one.  */
976 			int len = top - middle;
977 			int i;
978 
979 			/* Swap it with the bottom part of the bottom segment.  */
980 			for (i = 0; i < len; i++) {
981 				tem = argv[bottom + i];
982 				argv[bottom + i] = argv[middle + i];
983 				argv[middle + i] = tem;
984 			}
985 			/* Exclude the moved top segment from further swapping.  */
986 			bottom += len;
987 		}
988 	}
989 	/* Update records for the slots the non-options now occupy.  */
990 	d->first_nonopt += (d->custom_optind - d->last_nonopt);
991 	d->last_nonopt = d->custom_optind;
992 }
993 
994 /* Initialize the internal data when the first call is made.  */
custom_getopt_initialize(struct custom_getopt_data * d)995 static void custom_getopt_initialize(struct custom_getopt_data *d)
996 {
997 	/*
998 	 * Start processing options with ARGV-element 1 (since ARGV-element 0
999 	 * is the program name); the sequence of previously skipped non-option
1000 	 * ARGV-elements is empty.
1001 	 */
1002 	d->first_nonopt = d->last_nonopt = d->custom_optind;
1003 	d->nextchar = NULL;
1004 	d->initialized = 1;
1005 }
1006 
1007 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
1008 
1009 /* return: zero: continue, nonzero: return given value to user */
shuffle_argv(int argc,char * const * argv,const struct option * longopts,struct custom_getopt_data * d)1010 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
1011 	struct custom_getopt_data *d)
1012 {
1013 	/*
1014 	 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
1015 	 * moved back by the user (who may also have changed the arguments).
1016 	 */
1017 	if (d->last_nonopt > d->custom_optind)
1018 		d->last_nonopt = d->custom_optind;
1019 	if (d->first_nonopt > d->custom_optind)
1020 		d->first_nonopt = d->custom_optind;
1021 	/*
1022 	 * If we have just processed some options following some
1023 	 * non-options, exchange them so that the options come first.
1024 	 */
1025 	if (d->first_nonopt != d->last_nonopt &&
1026 			d->last_nonopt != d->custom_optind)
1027 		exchange((char **) argv, d);
1028 	else if (d->last_nonopt != d->custom_optind)
1029 		d->first_nonopt = d->custom_optind;
1030 	/*
1031 	 * Skip any additional non-options and extend the range of
1032 	 * non-options previously skipped.
1033 	 */
1034 	while (d->custom_optind < argc && NONOPTION_P)
1035 		d->custom_optind++;
1036 	d->last_nonopt = d->custom_optind;
1037 	/*
1038 	 * The special ARGV-element `--' means premature end of options.  Skip
1039 	 * it like a null option, then exchange with previous non-options as if
1040 	 * it were an option, then skip everything else like a non-option.
1041 	 */
1042 	if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
1043 		d->custom_optind++;
1044 		if (d->first_nonopt != d->last_nonopt
1045 				&& d->last_nonopt != d->custom_optind)
1046 			exchange((char **) argv, d);
1047 		else if (d->first_nonopt == d->last_nonopt)
1048 			d->first_nonopt = d->custom_optind;
1049 		d->last_nonopt = argc;
1050 		d->custom_optind = argc;
1051 	}
1052 	/*
1053 	 * If we have done all the ARGV-elements, stop the scan and back over
1054 	 * any non-options that we skipped and permuted.
1055 	 */
1056 	if (d->custom_optind == argc) {
1057 		/*
1058 		 * Set the next-arg-index to point at the non-options that we
1059 		 * previously skipped, so the caller will digest them.
1060 		 */
1061 		if (d->first_nonopt != d->last_nonopt)
1062 			d->custom_optind = d->first_nonopt;
1063 		return -1;
1064 	}
1065 	/*
1066 	 * If we have come to a non-option and did not permute it, either stop
1067 	 * the scan or describe it to the caller and pass it by.
1068 	 */
1069 	if (NONOPTION_P) {
1070 		d->custom_optarg = argv[d->custom_optind++];
1071 		return 1;
1072 	}
1073 	/*
1074 	 * We have found another option-ARGV-element. Skip the initial
1075 	 * punctuation.
1076 	 */
1077 	d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
1078 	return 0;
1079 }
1080 
1081 /*
1082  * Check whether the ARGV-element is a long option.
1083  *
1084  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
1085  * that an abbreviation of the long option, just like "--fu", and not "-f" with
1086  * arg "u".
1087  *
1088  * This distinction seems to be the most useful approach.
1089  *
1090  */
check_long_opt(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int print_errors,struct custom_getopt_data * d)1091 static int check_long_opt(int argc, char *const *argv, const char *optstring,
1092 		const struct option *longopts, int *longind,
1093 		int print_errors, struct custom_getopt_data *d)
1094 {
1095 	char *nameend;
1096 	const struct option *p;
1097 	const struct option *pfound = NULL;
1098 	int exact = 0;
1099 	int ambig = 0;
1100 	int indfound = -1;
1101 	int option_index;
1102 
1103 	for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
1104 		/* Do nothing.  */ ;
1105 
1106 	/* Test all long options for either exact match or abbreviated matches */
1107 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
1108 		if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
1109 			if ((unsigned int) (nameend - d->nextchar)
1110 					== (unsigned int) strlen(p->name)) {
1111 				/* Exact match found.  */
1112 				pfound = p;
1113 				indfound = option_index;
1114 				exact = 1;
1115 				break;
1116 			} else if (pfound == NULL) {
1117 				/* First nonexact match found.  */
1118 				pfound = p;
1119 				indfound = option_index;
1120 			} else if (pfound->has_arg != p->has_arg
1121 					|| pfound->flag != p->flag
1122 					|| pfound->val != p->val)
1123 				/* Second or later nonexact match found.  */
1124 				ambig = 1;
1125 		}
1126 	if (ambig && !exact) {
1127 		if (print_errors) {
1128 			fprintf(stderr,
1129 				"%s: option `%s' is ambiguous\n",
1130 				argv[0], argv[d->custom_optind]);
1131 		}
1132 		d->nextchar += strlen(d->nextchar);
1133 		d->custom_optind++;
1134 		d->custom_optopt = 0;
1135 		return '?';
1136 	}
1137 	if (pfound) {
1138 		option_index = indfound;
1139 		d->custom_optind++;
1140 		if (*nameend) {
1141 			if (pfound->has_arg != no_argument)
1142 				d->custom_optarg = nameend + 1;
1143 			else {
1144 				if (print_errors) {
1145 					if (argv[d->custom_optind - 1][1] == '-') {
1146 						/* --option */
1147 						fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
1148 							argv[0], pfound->name);
1149 					} else {
1150 						/* +option or -option */
1151 						fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
1152 							argv[0], argv[d->custom_optind - 1][0], pfound->name);
1153 					}
1154 
1155 				}
1156 				d->nextchar += strlen(d->nextchar);
1157 				d->custom_optopt = pfound->val;
1158 				return '?';
1159 			}
1160 		} else if (pfound->has_arg == required_argument) {
1161 			if (d->custom_optind < argc)
1162 				d->custom_optarg = argv[d->custom_optind++];
1163 			else {
1164 				if (print_errors) {
1165 					fprintf(stderr,
1166 						"%s: option `%s' requires an argument\n",
1167 						argv[0],
1168 						argv[d->custom_optind - 1]);
1169 				}
1170 				d->nextchar += strlen(d->nextchar);
1171 				d->custom_optopt = pfound->val;
1172 				return optstring[0] == ':' ? ':' : '?';
1173 			}
1174 		}
1175 		d->nextchar += strlen(d->nextchar);
1176 		if (longind != NULL)
1177 			*longind = option_index;
1178 		if (pfound->flag) {
1179 			*(pfound->flag) = pfound->val;
1180 			return 0;
1181 		}
1182 		return pfound->val;
1183 	}
1184 	/*
1185 	 * Can't find it as a long option.  If this is not getopt_long_only, or
1186 	 * the option starts with '--' or is not a valid short option, then
1187 	 * it's an error.  Otherwise interpret it as a short option.
1188 	 */
1189 	if (print_errors) {
1190 		if (argv[d->custom_optind][1] == '-') {
1191 			/* --option */
1192 			fprintf(stderr,
1193 				"%s: unrecognized option `--%s'\n",
1194 				argv[0], d->nextchar);
1195 		} else {
1196 			/* +option or -option */
1197 			fprintf(stderr,
1198 				"%s: unrecognized option `%c%s'\n",
1199 				argv[0], argv[d->custom_optind][0],
1200 				d->nextchar);
1201 		}
1202 	}
1203 	d->nextchar = (char *) "";
1204 	d->custom_optind++;
1205 	d->custom_optopt = 0;
1206 	return '?';
1207 }
1208 
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)1209 static int check_short_opt(int argc, char *const *argv, const char *optstring,
1210 		int print_errors, struct custom_getopt_data *d)
1211 {
1212 	char c = *d->nextchar++;
1213 	const char *temp = strchr(optstring, c);
1214 
1215 	/* Increment `custom_optind' when we start to process its last character.  */
1216 	if (*d->nextchar == '\0')
1217 		++d->custom_optind;
1218 	if (!temp || c == ':') {
1219 		if (print_errors)
1220 			fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
1221 
1222 		d->custom_optopt = c;
1223 		return '?';
1224 	}
1225 	if (temp[1] == ':') {
1226 		if (temp[2] == ':') {
1227 			/* This is an option that accepts an argument optionally.  */
1228 			if (*d->nextchar != '\0') {
1229 				d->custom_optarg = d->nextchar;
1230 				d->custom_optind++;
1231 			} else
1232 				d->custom_optarg = NULL;
1233 			d->nextchar = NULL;
1234 		} else {
1235 			/* This is an option that requires an argument.  */
1236 			if (*d->nextchar != '\0') {
1237 				d->custom_optarg = d->nextchar;
1238 				/*
1239 				 * If we end this ARGV-element by taking the
1240 				 * rest as an arg, we must advance to the next
1241 				 * element now.
1242 				 */
1243 				d->custom_optind++;
1244 			} else if (d->custom_optind == argc) {
1245 				if (print_errors) {
1246 					fprintf(stderr,
1247 						"%s: option requires an argument -- %c\n",
1248 						argv[0], c);
1249 				}
1250 				d->custom_optopt = c;
1251 				if (optstring[0] == ':')
1252 					c = ':';
1253 				else
1254 					c = '?';
1255 			} else
1256 				/*
1257 				 * We already incremented `custom_optind' once;
1258 				 * increment it again when taking next ARGV-elt
1259 				 * as argument.
1260 				 */
1261 				d->custom_optarg = argv[d->custom_optind++];
1262 			d->nextchar = NULL;
1263 		}
1264 	}
1265 	return c;
1266 }
1267 
1268 /*
1269  * Scan elements of ARGV for option characters given in OPTSTRING.
1270  *
1271  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1272  * then it is an option element.  The characters of this element
1273  * (aside from the initial '-') are option characters.  If `getopt'
1274  * is called repeatedly, it returns successively each of the option characters
1275  * from each of the option elements.
1276  *
1277  * If `getopt' finds another option character, it returns that character,
1278  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1279  * resume the scan with the following option character or ARGV-element.
1280  *
1281  * If there are no more option characters, `getopt' returns -1.
1282  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1283  * that is not an option.  (The ARGV-elements have been permuted
1284  * so that those that are not options now come last.)
1285  *
1286  * OPTSTRING is a string containing the legitimate option characters.
1287  * If an option character is seen that is not listed in OPTSTRING,
1288  * return '?' after printing an error message.  If you set `custom_opterr' to
1289  * zero, the error message is suppressed but we still return '?'.
1290  *
1291  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1292  * so the following text in the same ARGV-element, or the text of the following
1293  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1294  * wants an optional arg; if there is text in the current ARGV-element,
1295  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1296  *
1297  * If OPTSTRING starts with `-' or `+', it requests different methods of
1298  * handling the non-option ARGV-elements.
1299  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1300  *
1301  * Long-named options begin with `--' instead of `-'.
1302  * Their names may be abbreviated as long as the abbreviation is unique
1303  * or is an exact match for some defined option.  If they have an
1304  * argument, it follows the option name in the same ARGV-element, separated
1305  * from the option name by a `=', or else the in next ARGV-element.
1306  * When `getopt' finds a long-named option, it returns 0 if that option's
1307  * `flag' field is nonzero, the value of the option's `val' field
1308  * if the `flag' field is zero.
1309  *
1310  * The elements of ARGV aren't really const, because we permute them.
1311  * But we pretend they're const in the prototype to be compatible
1312  * with other systems.
1313  *
1314  * LONGOPTS is a vector of `struct option' terminated by an
1315  * element containing a name which is zero.
1316  *
1317  * LONGIND returns the index in LONGOPT of the long-named option found.
1318  * It is only valid when a long-named option has been found by the most
1319  * recent call.
1320  *
1321  * Return the option character from OPTS just read.  Return -1 when there are
1322  * no more options.  For unrecognized options, or options missing arguments,
1323  * `custom_optopt' is set to the option letter, and '?' is returned.
1324  *
1325  * The OPTS string is a list of characters which are recognized option letters,
1326  * optionally followed by colons, specifying that that letter takes an
1327  * argument, to be placed in `custom_optarg'.
1328  *
1329  * If a letter in OPTS is followed by two colons, its argument is optional.
1330  * This behavior is specific to the GNU `getopt'.
1331  *
1332  * The argument `--' causes premature termination of argument scanning,
1333  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1334  * with `--', then non-option arguments are treated as arguments to the option
1335  * '\0'.  This behavior is specific to the GNU `getopt'.
1336  */
1337 
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1338 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1339 		const struct option *longopts, int *longind,
1340 		struct custom_getopt_data *d)
1341 {
1342 	int ret, print_errors = d->custom_opterr;
1343 
1344 	if (optstring[0] == ':')
1345 		print_errors = 0;
1346 	if (argc < 1)
1347 		return -1;
1348 	d->custom_optarg = NULL;
1349 
1350 	/*
1351 	 * This is a big difference with GNU getopt, since optind == 0
1352 	 * means initialization while here 1 means first call.
1353 	 */
1354 	if (d->custom_optind == 0 || !d->initialized) {
1355 		if (d->custom_optind == 0)
1356 			d->custom_optind = 1;	/* Don't scan ARGV[0], the program name.  */
1357 		custom_getopt_initialize(d);
1358 	}
1359 	if (d->nextchar == NULL || *d->nextchar == '\0') {
1360 		ret = shuffle_argv(argc, argv, longopts, d);
1361 		if (ret)
1362 			return ret;
1363 	}
1364 	if (longopts && (argv[d->custom_optind][1] == '-' ))
1365 		return check_long_opt(argc, argv, optstring, longopts,
1366 			longind, print_errors, d);
1367 	return check_short_opt(argc, argv, optstring, print_errors, d);
1368 }
1369 
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1370 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1371 	const struct option *longopts, int *longind)
1372 {
1373 	int result;
1374 	/* Keep a global copy of all internal members of d */
1375 	static struct custom_getopt_data d;
1376 
1377 	d.custom_optind = custom_optind;
1378 	d.custom_opterr = custom_opterr;
1379 	result = getopt_internal_r(argc, argv, optstring, longopts,
1380 		longind, &d);
1381 	custom_optind = d.custom_optind;
1382 	custom_optarg = d.custom_optarg;
1383 	custom_optopt = d.custom_optopt;
1384 	return result;
1385 }
1386 
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1387 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1388 	const struct option *long_options, int *opt_index)
1389 {
1390 	return custom_getopt_internal(argc, argv, options, long_options,
1391 		opt_index);
1392 }
1393 
1394 
1395 static char *package_name = 0;
1396 
1397 /**
1398  * @brief updates an option
1399  * @param field the generic pointer to the field to update
1400  * @param orig_field the pointer to the orig field
1401  * @param field_given the pointer to the number of occurrence of this option
1402  * @param prev_given the pointer to the number of occurrence already seen
1403  * @param value the argument for this option (if null no arg was specified)
1404  * @param possible_values the possible values for this option (if specified)
1405  * @param default_value the default value (in case the option only accepts fixed values)
1406  * @param arg_type the type of this option
1407  * @param check_ambiguity @see RNAup_cmdline_parser_params.check_ambiguity
1408  * @param override @see RNAup_cmdline_parser_params.override
1409  * @param no_free whether to free a possible previous value
1410  * @param multiple_option whether this is a multiple option
1411  * @param long_opt the corresponding long option
1412  * @param short_opt the corresponding short option (or '-' if none)
1413  * @param additional_error possible further error specification
1414  */
1415 static
update_arg(void * field,char ** orig_field,unsigned int * field_given,unsigned int * prev_given,char * value,const char * possible_values[],const char * default_value,RNAup_cmdline_parser_arg_type arg_type,int check_ambiguity,int override,int no_free,int multiple_option,const char * long_opt,char short_opt,const char * additional_error)1416 int update_arg(void *field, char **orig_field,
1417                unsigned int *field_given, unsigned int *prev_given,
1418                char *value, const char *possible_values[],
1419                const char *default_value,
1420                RNAup_cmdline_parser_arg_type arg_type,
1421                int check_ambiguity, int override,
1422                int no_free, int multiple_option,
1423                const char *long_opt, char short_opt,
1424                const char *additional_error)
1425 {
1426   char *stop_char = 0;
1427   const char *val = value;
1428   int found;
1429   char **string_field;
1430   FIX_UNUSED (field);
1431 
1432   stop_char = 0;
1433   found = 0;
1434 
1435   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1436     {
1437       if (short_opt != '-')
1438         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1439                package_name, long_opt, short_opt,
1440                (additional_error ? additional_error : ""));
1441       else
1442         fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1443                package_name, long_opt,
1444                (additional_error ? additional_error : ""));
1445       return 1; /* failure */
1446     }
1447 
1448   FIX_UNUSED (default_value);
1449 
1450   if (field_given && *field_given && ! override)
1451     return 0;
1452   if (prev_given)
1453     (*prev_given)++;
1454   if (field_given)
1455     (*field_given)++;
1456   if (possible_values)
1457     val = possible_values[found];
1458 
1459   switch(arg_type) {
1460   case ARG_FLAG:
1461     *((int *)field) = !*((int *)field);
1462     break;
1463   case ARG_INT:
1464     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1465     break;
1466   case ARG_DOUBLE:
1467     if (val) *((double *)field) = strtod (val, &stop_char);
1468     break;
1469   case ARG_STRING:
1470     if (val) {
1471       string_field = (char **)field;
1472       if (!no_free && *string_field)
1473         free (*string_field); /* free previous string */
1474       *string_field = gengetopt_strdup (val);
1475     }
1476     break;
1477   default:
1478     break;
1479   };
1480 
1481   /* check numeric conversion */
1482   switch(arg_type) {
1483   case ARG_INT:
1484   case ARG_DOUBLE:
1485     if (val && !(stop_char && *stop_char == '\0')) {
1486       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1487       return 1; /* failure */
1488     }
1489     break;
1490   default:
1491     ;
1492   };
1493 
1494   /* store the original value */
1495   switch(arg_type) {
1496   case ARG_NO:
1497   case ARG_FLAG:
1498     break;
1499   default:
1500     if (value && orig_field) {
1501       if (no_free) {
1502         *orig_field = value;
1503       } else {
1504         if (*orig_field)
1505           free (*orig_field); /* free previous string */
1506         *orig_field = gengetopt_strdup (value);
1507       }
1508     }
1509   };
1510 
1511   return 0; /* OK */
1512 }
1513 
1514 /**
1515  * @brief store information about a multiple option in a temporary list
1516  * @param list where to (temporarily) store multiple options
1517  */
1518 static
update_multiple_arg_temp(struct generic_list ** list,unsigned int * prev_given,const char * val,const char * possible_values[],const char * default_value,RNAup_cmdline_parser_arg_type arg_type,const char * long_opt,char short_opt,const char * additional_error)1519 int update_multiple_arg_temp(struct generic_list **list,
1520                unsigned int *prev_given, const char *val,
1521                const char *possible_values[], const char *default_value,
1522                RNAup_cmdline_parser_arg_type arg_type,
1523                const char *long_opt, char short_opt,
1524                const char *additional_error)
1525 {
1526   /* store single arguments */
1527   char *multi_token;
1528   const char *multi_next;
1529 
1530   if (arg_type == ARG_NO) {
1531     (*prev_given)++;
1532     return 0; /* OK */
1533   }
1534 
1535   multi_token = get_multiple_arg_token(val);
1536   multi_next = get_multiple_arg_token_next (val);
1537 
1538   while (1)
1539     {
1540       add_node (list);
1541       if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
1542           prev_given, multi_token, possible_values, default_value,
1543           arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
1544         if (multi_token) free(multi_token);
1545         return 1; /* failure */
1546       }
1547 
1548       if (multi_next)
1549         {
1550           multi_token = get_multiple_arg_token(multi_next);
1551           multi_next = get_multiple_arg_token_next (multi_next);
1552         }
1553       else
1554         break;
1555     }
1556 
1557   return 0; /* OK */
1558 }
1559 
1560 /**
1561  * @brief free the passed list (including possible string argument)
1562  */
1563 static
free_list(struct generic_list * list,short string_arg)1564 void free_list(struct generic_list *list, short string_arg)
1565 {
1566   if (list) {
1567     struct generic_list *tmp;
1568     while (list)
1569       {
1570         tmp = list;
1571         if (string_arg && list->arg.string_arg)
1572           free (list->arg.string_arg);
1573         if (list->orig)
1574           free (list->orig);
1575         list = list->next;
1576         free (tmp);
1577       }
1578   }
1579 }
1580 
1581 /**
1582  * @brief updates a multiple option starting from the passed list
1583  */
1584 static
update_multiple_arg(void * field,char *** orig_field,unsigned int field_given,unsigned int prev_given,union generic_value * default_value,RNAup_cmdline_parser_arg_type arg_type,struct generic_list * list)1585 void update_multiple_arg(void *field, char ***orig_field,
1586                unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
1587                RNAup_cmdline_parser_arg_type arg_type,
1588                struct generic_list *list)
1589 {
1590   int i;
1591   struct generic_list *tmp;
1592 
1593   if (prev_given && list) {
1594     *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
1595 
1596     switch(arg_type) {
1597     case ARG_INT:
1598       *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;
1599     case ARG_DOUBLE:
1600       *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;
1601     case ARG_STRING:
1602       *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
1603     default:
1604       break;
1605     };
1606 
1607     for (i = (prev_given - 1); i >= 0; --i)
1608       {
1609         tmp = list;
1610 
1611         switch(arg_type) {
1612         case ARG_INT:
1613           (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;
1614         case ARG_DOUBLE:
1615           (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;
1616         case ARG_STRING:
1617           (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
1618         default:
1619           break;
1620         }
1621         (*orig_field) [i + field_given] = list->orig;
1622         list = list->next;
1623         free (tmp);
1624       }
1625   } else { /* set the default value */
1626     if (default_value && ! field_given) {
1627       switch(arg_type) {
1628       case ARG_INT:
1629         if (! *((int **)field)) {
1630           *((int **)field) = (int *)malloc (sizeof (int));
1631           (*((int **)field))[0] = default_value->int_arg;
1632         }
1633         break;
1634       case ARG_DOUBLE:
1635         if (! *((double **)field)) {
1636           *((double **)field) = (double *)malloc (sizeof (double));
1637           (*((double **)field))[0] = default_value->double_arg;
1638         }
1639         break;
1640       case ARG_STRING:
1641         if (! *((char ***)field)) {
1642           *((char ***)field) = (char **)malloc (sizeof (char *));
1643           (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
1644         }
1645         break;
1646       default: break;
1647       }
1648       if (!(*orig_field)) {
1649         *orig_field = (char **) malloc (sizeof (char *));
1650         (*orig_field)[0] = 0;
1651       }
1652     }
1653   }
1654 }
1655 
1656 int
RNAup_cmdline_parser_internal(int argc,char ** argv,struct RNAup_args_info * args_info,struct RNAup_cmdline_parser_params * params,const char * additional_error)1657 RNAup_cmdline_parser_internal (
1658   int argc, char **argv, struct RNAup_args_info *args_info,
1659                         struct RNAup_cmdline_parser_params *params, const char *additional_error)
1660 {
1661   int c;	/* Character of the parsed option.  */
1662   union generic_value multiple_default_value;
1663 
1664   struct generic_list * ulength_list = NULL;
1665   int error_occurred = 0;
1666   struct RNAup_args_info local_args_info;
1667 
1668   int override;
1669   int initialize;
1670   int check_required;
1671   int check_ambiguity;
1672 
1673   char *optarg;
1674   int optind;
1675   int opterr;
1676   int optopt;
1677 
1678   package_name = argv[0];
1679 
1680   /* TODO: Why is this here? It is not used anywhere. */
1681   override = params->override;
1682   FIX_UNUSED(override);
1683 
1684   initialize = params->initialize;
1685   check_required = params->check_required;
1686 
1687   /* TODO: Why is this here? It is not used anywhere. */
1688   check_ambiguity = params->check_ambiguity;
1689   FIX_UNUSED(check_ambiguity);
1690 
1691   if (initialize)
1692     RNAup_cmdline_parser_init (args_info);
1693 
1694   RNAup_cmdline_parser_init (&local_args_info);
1695 
1696   optarg = 0;
1697   optind = 0;
1698   opterr = params->print_errors;
1699   optopt = '?';
1700 
1701   while (1)
1702     {
1703       int option_index = 0;
1704 
1705       static struct option long_options[] = {
1706         { "help",	0, NULL, 'h' },
1707         { "detailed-help",	0, NULL, 0 },
1708         { "full-help",	0, NULL, 0 },
1709         { "version",	0, NULL, 'V' },
1710         { "constraint",	0, NULL, 'C' },
1711         { "no_output_file",	0, NULL, 'o' },
1712         { "no_header",	0, NULL, 0 },
1713         { "noconv",	0, NULL, 0 },
1714         { "ulength",	1, NULL, 'u' },
1715         { "contributions",	1, NULL, 'c' },
1716         { "window",	1, NULL, 'w' },
1717         { "include_both",	0, NULL, 'b' },
1718         { "extend5",	1, NULL, '5' },
1719         { "extend3",	1, NULL, '3' },
1720         { "interaction_pairwise",	0, NULL, 0 },
1721         { "interaction_first",	0, NULL, 0 },
1722         { "pfScale",	1, NULL, 'S' },
1723         { "temp",	1, NULL, 'T' },
1724         { "noTetra",	0, NULL, '4' },
1725         { "dangles",	1, NULL, 'd' },
1726         { "noLP",	0, NULL, 0 },
1727         { "noGU",	0, NULL, 0 },
1728         { "noClosingGU",	0, NULL, 0 },
1729         { "paramFile",	1, NULL, 'P' },
1730         { "nsp",	1, NULL, 0 },
1731         { "energyModel",	1, NULL, 'e' },
1732         { 0,  0, 0, 0 }
1733       };
1734 
1735       custom_optarg = optarg;
1736       custom_optind = optind;
1737       custom_opterr = opterr;
1738       custom_optopt = optopt;
1739 
1740       c = custom_getopt_long (argc, argv, "hVCou:c:w:b5:3:S:T:4d:P:e:", long_options, &option_index);
1741 
1742       optarg = custom_optarg;
1743       optind = custom_optind;
1744       opterr = custom_opterr;
1745       optopt = custom_optopt;
1746 
1747       if (c == -1) break;	/* Exit from `while (1)' loop.  */
1748 
1749       switch (c)
1750         {
1751         case 'h':	/* Print help and exit.  */
1752           RNAup_cmdline_parser_print_help ();
1753           RNAup_cmdline_parser_free (&local_args_info);
1754           exit (EXIT_SUCCESS);
1755 
1756         case 'V':	/* Print version and exit.  */
1757           RNAup_cmdline_parser_print_version ();
1758           RNAup_cmdline_parser_free (&local_args_info);
1759           exit (EXIT_SUCCESS);
1760 
1761         case 'C':	/* Apply structural constraint(s) during prediction..  */
1762 
1763 
1764           if (update_arg((void *)&(args_info->constraint_flag), 0, &(args_info->constraint_given),
1765               &(local_args_info.constraint_given), optarg, 0, 0, ARG_FLAG,
1766               check_ambiguity, override, 1, 0, "constraint", 'C',
1767               additional_error))
1768             goto failure;
1769 
1770           break;
1771         case 'o':	/* Do not produce an output file..  */
1772 
1773 
1774           if (update_arg((void *)&(args_info->no_output_file_flag), 0, &(args_info->no_output_file_given),
1775               &(local_args_info.no_output_file_given), optarg, 0, 0, ARG_FLAG,
1776               check_ambiguity, override, 1, 0, "no_output_file", 'o',
1777               additional_error))
1778             goto failure;
1779 
1780           break;
1781         case 'u':	/* Specify the length of the unstructured region in the output..  */
1782 
1783           if (update_multiple_arg_temp(&ulength_list,
1784               &(local_args_info.ulength_given), optarg, 0, "4", ARG_STRING,
1785               "ulength", 'u',
1786               additional_error))
1787             goto failure;
1788 
1789           break;
1790         case 'c':	/* Specify the contributions listed in the output..  */
1791 
1792 
1793           if (update_arg( (void *)&(args_info->contributions_arg),
1794                &(args_info->contributions_orig), &(args_info->contributions_given),
1795               &(local_args_info.contributions_given), optarg, 0, "S", ARG_STRING,
1796               check_ambiguity, override, 0, 0,
1797               "contributions", 'c',
1798               additional_error))
1799             goto failure;
1800 
1801           break;
1802         case 'w':	/* Set the maximal length of the region of interaction..  */
1803 
1804 
1805           if (update_arg( (void *)&(args_info->window_arg),
1806                &(args_info->window_orig), &(args_info->window_given),
1807               &(local_args_info.window_given), optarg, 0, "25", ARG_INT,
1808               check_ambiguity, override, 0, 0,
1809               "window", 'w',
1810               additional_error))
1811             goto failure;
1812 
1813           break;
1814         case 'b':	/* Include the probability of unpaired regions in both (b) RNAs..  */
1815 
1816 
1817           if (update_arg((void *)&(args_info->include_both_flag), 0, &(args_info->include_both_given),
1818               &(local_args_info.include_both_given), optarg, 0, 0, ARG_FLAG,
1819               check_ambiguity, override, 1, 0, "include_both", 'b',
1820               additional_error))
1821             goto failure;
1822 
1823           break;
1824         case '5':	/* Extend the region of interaction in the target to some residues on the 5' side..  */
1825 
1826 
1827           if (update_arg( (void *)&(args_info->extend5_arg),
1828                &(args_info->extend5_orig), &(args_info->extend5_given),
1829               &(local_args_info.extend5_given), optarg, 0, 0, ARG_INT,
1830               check_ambiguity, override, 0, 0,
1831               "extend5", '5',
1832               additional_error))
1833             goto failure;
1834 
1835           break;
1836         case '3':	/* Extend the region of interaction in the target to some residues on the 3' side..  */
1837 
1838 
1839           if (update_arg( (void *)&(args_info->extend3_arg),
1840                &(args_info->extend3_orig), &(args_info->extend3_given),
1841               &(local_args_info.extend3_given), optarg, 0, 0, ARG_INT,
1842               check_ambiguity, override, 0, 0,
1843               "extend3", '3',
1844               additional_error))
1845             goto failure;
1846 
1847           break;
1848         case 'S':	/* Set scaling factor for Boltzmann factors to prevent under/overflows..  */
1849 
1850 
1851           if (update_arg( (void *)&(args_info->pfScale_arg),
1852                &(args_info->pfScale_orig), &(args_info->pfScale_given),
1853               &(local_args_info.pfScale_given), optarg, 0, 0, ARG_DOUBLE,
1854               check_ambiguity, override, 0, 0,
1855               "pfScale", 'S',
1856               additional_error))
1857             goto failure;
1858 
1859           break;
1860         case 'T':	/* Rescale energy parameters to a temperature in degrees centigrade..  */
1861 
1862 
1863           if (update_arg( (void *)&(args_info->temp_arg),
1864                &(args_info->temp_orig), &(args_info->temp_given),
1865               &(local_args_info.temp_given), optarg, 0, "37.0", ARG_DOUBLE,
1866               check_ambiguity, override, 0, 0,
1867               "temp", 'T',
1868               additional_error))
1869             goto failure;
1870 
1871           break;
1872         case '4':	/* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins..  */
1873 
1874 
1875           if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
1876               &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
1877               check_ambiguity, override, 1, 0, "noTetra", '4',
1878               additional_error))
1879             goto failure;
1880 
1881           break;
1882         case 'd':	/* Specify \"dangling end\" model for bases adjacent to helices in free ends and multi-loops..  */
1883 
1884 
1885           if (update_arg( (void *)&(args_info->dangles_arg),
1886                &(args_info->dangles_orig), &(args_info->dangles_given),
1887               &(local_args_info.dangles_given), optarg, 0, "2", ARG_INT,
1888               check_ambiguity, override, 0, 0,
1889               "dangles", 'd',
1890               additional_error))
1891             goto failure;
1892 
1893           break;
1894         case 'P':	/* Read energy parameters from paramfile, instead of using the default parameter set..  */
1895 
1896 
1897           if (update_arg( (void *)&(args_info->paramFile_arg),
1898                &(args_info->paramFile_orig), &(args_info->paramFile_given),
1899               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1900               check_ambiguity, override, 0, 0,
1901               "paramFile", 'P',
1902               additional_error))
1903             goto failure;
1904 
1905           break;
1906         case 'e':	/* Set energy model..  */
1907 
1908 
1909           if (update_arg( (void *)&(args_info->energyModel_arg),
1910                &(args_info->energyModel_orig), &(args_info->energyModel_given),
1911               &(local_args_info.energyModel_given), optarg, 0, 0, ARG_INT,
1912               check_ambiguity, override, 0, 0,
1913               "energyModel", 'e',
1914               additional_error))
1915             goto failure;
1916 
1917           break;
1918 
1919         case 0:	/* Long option with no short option */
1920           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1921             RNAup_cmdline_parser_print_detailed_help ();
1922             RNAup_cmdline_parser_free (&local_args_info);
1923             exit (EXIT_SUCCESS);
1924           }
1925 
1926           if (strcmp (long_options[option_index].name, "full-help") == 0) {
1927             RNAup_cmdline_parser_print_full_help ();
1928             RNAup_cmdline_parser_free (&local_args_info);
1929             exit (EXIT_SUCCESS);
1930           }
1931 
1932           /* Do not produce a header with the command line parameters used in the outputfile..  */
1933           if (strcmp (long_options[option_index].name, "no_header") == 0)
1934           {
1935 
1936 
1937             if (update_arg((void *)&(args_info->no_header_flag), 0, &(args_info->no_header_given),
1938                 &(local_args_info.no_header_given), optarg, 0, 0, ARG_FLAG,
1939                 check_ambiguity, override, 1, 0, "no_header", '-',
1940                 additional_error))
1941               goto failure;
1942 
1943           }
1944           /* Do not automatically substitude nucleotide \"T\" with \"U\"..  */
1945           else if (strcmp (long_options[option_index].name, "noconv") == 0)
1946           {
1947 
1948 
1949             if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
1950                 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
1951                 check_ambiguity, override, 1, 0, "noconv", '-',
1952                 additional_error))
1953               goto failure;
1954 
1955           }
1956           /* Activate pairwise interaction mode..  */
1957           else if (strcmp (long_options[option_index].name, "interaction_pairwise") == 0)
1958           {
1959 
1960 
1961             if (update_arg((void *)&(args_info->interaction_pairwise_flag), 0, &(args_info->interaction_pairwise_given),
1962                 &(local_args_info.interaction_pairwise_given), optarg, 0, 0, ARG_FLAG,
1963                 check_ambiguity, override, 1, 0, "interaction_pairwise", '-',
1964                 additional_error))
1965               goto failure;
1966 
1967           }
1968           /* Activate interaction mode using first sequence only..  */
1969           else if (strcmp (long_options[option_index].name, "interaction_first") == 0)
1970           {
1971 
1972 
1973             if (update_arg((void *)&(args_info->interaction_first_flag), 0, &(args_info->interaction_first_given),
1974                 &(local_args_info.interaction_first_given), optarg, 0, 0, ARG_FLAG,
1975                 check_ambiguity, override, 1, 0, "interaction_first", '-',
1976                 additional_error))
1977               goto failure;
1978 
1979           }
1980           /* Produce structures without lonely pairs (helices of length 1)..  */
1981           else if (strcmp (long_options[option_index].name, "noLP") == 0)
1982           {
1983 
1984 
1985             if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
1986                 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
1987                 check_ambiguity, override, 1, 0, "noLP", '-',
1988                 additional_error))
1989               goto failure;
1990 
1991           }
1992           /* Do not allow GU pairs..  */
1993           else if (strcmp (long_options[option_index].name, "noGU") == 0)
1994           {
1995 
1996 
1997             if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
1998                 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
1999                 check_ambiguity, override, 1, 0, "noGU", '-',
2000                 additional_error))
2001               goto failure;
2002 
2003           }
2004           /* Do not allow GU pairs at the end of helices..  */
2005           else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
2006           {
2007 
2008 
2009             if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
2010                 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
2011                 check_ambiguity, override, 1, 0, "noClosingGU", '-',
2012                 additional_error))
2013               goto failure;
2014 
2015           }
2016           /* Allow other pairs in addition to the usual AU,GC,and GU pairs..  */
2017           else if (strcmp (long_options[option_index].name, "nsp") == 0)
2018           {
2019 
2020 
2021             if (update_arg( (void *)&(args_info->nsp_arg),
2022                  &(args_info->nsp_orig), &(args_info->nsp_given),
2023                 &(local_args_info.nsp_given), optarg, 0, 0, ARG_STRING,
2024                 check_ambiguity, override, 0, 0,
2025                 "nsp", '-',
2026                 additional_error))
2027               goto failure;
2028 
2029           }
2030 
2031           break;
2032         case '?':	/* Invalid option.  */
2033           /* `getopt_long' already printed an error message.  */
2034           goto failure;
2035 
2036         default:	/* bug: option not considered.  */
2037           fprintf (stderr, "%s: option unknown: %c%s\n", RNAUP_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
2038           abort ();
2039         } /* switch */
2040     } /* while */
2041 
2042 
2043   multiple_default_value.default_string_arg = "4";
2044   update_multiple_arg((void *)&(args_info->ulength_arg),
2045     &(args_info->ulength_orig), args_info->ulength_given,
2046     local_args_info.ulength_given, &multiple_default_value,
2047     ARG_STRING, ulength_list);
2048 
2049   args_info->ulength_given += local_args_info.ulength_given;
2050   local_args_info.ulength_given = 0;
2051 
2052   if (check_required)
2053     {
2054       error_occurred += RNAup_cmdline_parser_required2 (args_info, argv[0], additional_error);
2055     }
2056 
2057   RNAup_cmdline_parser_release (&local_args_info);
2058 
2059   if ( error_occurred )
2060     return (EXIT_FAILURE);
2061 
2062   return 0;
2063 
2064 failure:
2065   free_list (ulength_list, 1 );
2066 
2067   RNAup_cmdline_parser_release (&local_args_info);
2068   return (EXIT_FAILURE);
2069 }
2070 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
2071