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