Add missing binaty and statis library
[jabaws.git] / binaries / src / ViennaRNA / Progs / RNAdistance_cmdl.c
1 /*
2   File autogenerated by gengetopt version 2.22.5
3   generated with the following command:
4   gengetopt -i RNAdistance.ggo --file-name=RNAdistance_cmdl --include-getopt --default-optional --func-name=RNAdistance_cmdline_parser --arg-struct-name=RNAdistance_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 "RNAdistance_cmdl.h"
26
27 const char *RNAdistance_args_info_purpose = "Calculate distances between RNA secondary structures";
28
29 const char *RNAdistance_args_info_usage = "Usage: RNAdistance [OPTIONS]...";
30
31 const char *RNAdistance_args_info_description = "This program reads RNA secondary structures from stdin and calculates one or \nmore measures for their dissimilarity, based on tree or string editing \n(alignment). In addition it calculates a \"base pair distance\" given by the \nnumber of base pairs present in one structure, but not the other. For \nstructures of different length base pair distance is not recommended.\n";
32
33 const char *RNAdistance_args_info_detailed_help[] = {
34   "  -h, --help                    Print help and exit",
35   "      --detailed-help           Print help, including all details and hidden \n                                  options, and exit",
36   "  -V, --version                 Print version and exit",
37   "  -D, --distance=fhwcFHWCP      Specify the distance representation to be used \n                                  in calculations.\n                                    (default=`f')",
38   "  Use the full, HIT, weighted coarse, or coarse representation to calculate the \n  distance. Capital letters indicate string alignment otherwise tree editing is \n  used.\n  Any combination of distances can bespecified.\n\n",
39   "  -X, --compare=p|m|f|c         Specify the comparison directive.\n                                    (default=`p')",
40   "  Possible arguments for this option are: -Xp compare the structures pairwise \n  (p), i.e. first with 2nd, third with 4th etc.\n  -Xm calculate the distance matrix between all structures. The output is \n  formatted as a lower triangle matrix.\n  -Xf compare each structure to the first one.\n  -Xc compare continuously, that is i-th with (i+1)th structure.\n\n",
41   "  -S, --shapiro                 Use the Bruce Shapiro's cost matrix for \n                                  comparing coarse structures.\n\n                                    (default=off)",
42   "  -B, --backtrack[=<filename>]  Print an \"alignment\" with gaps of the \n                                  structures, to show matching substructures. \n                                  The aligned structures are written to \n                                  <filename>, if specified.\n                                    (default=`none')",
43   "  If <filename> is not specified, the output is written to stdout, unless the \n  -Xm option is set in which case \"backtrack.file\" is used.\n\n",
44   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n",
45     0
46 };
47
48 static void
49 init_help_array(void)
50 {
51   RNAdistance_args_info_help[0] = RNAdistance_args_info_detailed_help[0];
52   RNAdistance_args_info_help[1] = RNAdistance_args_info_detailed_help[1];
53   RNAdistance_args_info_help[2] = RNAdistance_args_info_detailed_help[2];
54   RNAdistance_args_info_help[3] = RNAdistance_args_info_detailed_help[3];
55   RNAdistance_args_info_help[4] = RNAdistance_args_info_detailed_help[5];
56   RNAdistance_args_info_help[5] = RNAdistance_args_info_detailed_help[7];
57   RNAdistance_args_info_help[6] = RNAdistance_args_info_detailed_help[8];
58   RNAdistance_args_info_help[7] = RNAdistance_args_info_detailed_help[10];
59   RNAdistance_args_info_help[8] = 0; 
60   
61 }
62
63 const char *RNAdistance_args_info_help[9];
64
65 typedef enum {ARG_NO
66   , ARG_FLAG
67   , ARG_STRING
68 } RNAdistance_cmdline_parser_arg_type;
69
70 static
71 void clear_given (struct RNAdistance_args_info *args_info);
72 static
73 void clear_args (struct RNAdistance_args_info *args_info);
74
75 static int
76 RNAdistance_cmdline_parser_internal (int argc, char **argv, struct RNAdistance_args_info *args_info,
77                         struct RNAdistance_cmdline_parser_params *params, const char *additional_error);
78
79
80 static char *
81 gengetopt_strdup (const char *s);
82
83 static
84 void clear_given (struct RNAdistance_args_info *args_info)
85 {
86   args_info->help_given = 0 ;
87   args_info->detailed_help_given = 0 ;
88   args_info->version_given = 0 ;
89   args_info->distance_given = 0 ;
90   args_info->compare_given = 0 ;
91   args_info->shapiro_given = 0 ;
92   args_info->backtrack_given = 0 ;
93 }
94
95 static
96 void clear_args (struct RNAdistance_args_info *args_info)
97 {
98   FIX_UNUSED (args_info);
99   args_info->distance_arg = gengetopt_strdup ("f");
100   args_info->distance_orig = NULL;
101   args_info->compare_arg = gengetopt_strdup ("p");
102   args_info->compare_orig = NULL;
103   args_info->shapiro_flag = 0;
104   args_info->backtrack_arg = gengetopt_strdup ("none");
105   args_info->backtrack_orig = NULL;
106   
107 }
108
109 static
110 void init_args_info(struct RNAdistance_args_info *args_info)
111 {
112
113   init_help_array(); 
114   args_info->help_help = RNAdistance_args_info_detailed_help[0] ;
115   args_info->detailed_help_help = RNAdistance_args_info_detailed_help[1] ;
116   args_info->version_help = RNAdistance_args_info_detailed_help[2] ;
117   args_info->distance_help = RNAdistance_args_info_detailed_help[3] ;
118   args_info->compare_help = RNAdistance_args_info_detailed_help[5] ;
119   args_info->shapiro_help = RNAdistance_args_info_detailed_help[7] ;
120   args_info->backtrack_help = RNAdistance_args_info_detailed_help[8] ;
121   
122 }
123
124 void
125 RNAdistance_cmdline_parser_print_version (void)
126 {
127   printf ("%s %s\n",
128      (strlen(RNADISTANCE_CMDLINE_PARSER_PACKAGE_NAME) ? RNADISTANCE_CMDLINE_PARSER_PACKAGE_NAME : RNADISTANCE_CMDLINE_PARSER_PACKAGE),
129      RNADISTANCE_CMDLINE_PARSER_VERSION);
130 }
131
132 static void print_help_common(void) {
133   RNAdistance_cmdline_parser_print_version ();
134
135   if (strlen(RNAdistance_args_info_purpose) > 0)
136     printf("\n%s\n", RNAdistance_args_info_purpose);
137
138   if (strlen(RNAdistance_args_info_usage) > 0)
139     printf("\n%s\n", RNAdistance_args_info_usage);
140
141   printf("\n");
142
143   if (strlen(RNAdistance_args_info_description) > 0)
144     printf("%s\n\n", RNAdistance_args_info_description);
145 }
146
147 void
148 RNAdistance_cmdline_parser_print_help (void)
149 {
150   int i = 0;
151   print_help_common();
152   while (RNAdistance_args_info_help[i])
153     printf("%s\n", RNAdistance_args_info_help[i++]);
154 }
155
156 void
157 RNAdistance_cmdline_parser_print_detailed_help (void)
158 {
159   int i = 0;
160   print_help_common();
161   while (RNAdistance_args_info_detailed_help[i])
162     printf("%s\n", RNAdistance_args_info_detailed_help[i++]);
163 }
164
165 void
166 RNAdistance_cmdline_parser_init (struct RNAdistance_args_info *args_info)
167 {
168   clear_given (args_info);
169   clear_args (args_info);
170   init_args_info (args_info);
171 }
172
173 void
174 RNAdistance_cmdline_parser_params_init(struct RNAdistance_cmdline_parser_params *params)
175 {
176   if (params)
177     { 
178       params->override = 0;
179       params->initialize = 1;
180       params->check_required = 1;
181       params->check_ambiguity = 0;
182       params->print_errors = 1;
183     }
184 }
185
186 struct RNAdistance_cmdline_parser_params *
187 RNAdistance_cmdline_parser_params_create(void)
188 {
189   struct RNAdistance_cmdline_parser_params *params = 
190     (struct RNAdistance_cmdline_parser_params *)malloc(sizeof(struct RNAdistance_cmdline_parser_params));
191   RNAdistance_cmdline_parser_params_init(params);  
192   return params;
193 }
194
195 static void
196 free_string_field (char **s)
197 {
198   if (*s)
199     {
200       free (*s);
201       *s = 0;
202     }
203 }
204
205
206 static void
207 RNAdistance_cmdline_parser_release (struct RNAdistance_args_info *args_info)
208 {
209
210   free_string_field (&(args_info->distance_arg));
211   free_string_field (&(args_info->distance_orig));
212   free_string_field (&(args_info->compare_arg));
213   free_string_field (&(args_info->compare_orig));
214   free_string_field (&(args_info->backtrack_arg));
215   free_string_field (&(args_info->backtrack_orig));
216   
217   
218
219   clear_given (args_info);
220 }
221
222
223 static void
224 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
225 {
226   FIX_UNUSED (values);
227   if (arg) {
228     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
229   } else {
230     fprintf(outfile, "%s\n", opt);
231   }
232 }
233
234
235 int
236 RNAdistance_cmdline_parser_dump(FILE *outfile, struct RNAdistance_args_info *args_info)
237 {
238   int i = 0;
239
240   if (!outfile)
241     {
242       fprintf (stderr, "%s: cannot dump options to stream\n", RNADISTANCE_CMDLINE_PARSER_PACKAGE);
243       return EXIT_FAILURE;
244     }
245
246   if (args_info->help_given)
247     write_into_file(outfile, "help", 0, 0 );
248   if (args_info->detailed_help_given)
249     write_into_file(outfile, "detailed-help", 0, 0 );
250   if (args_info->version_given)
251     write_into_file(outfile, "version", 0, 0 );
252   if (args_info->distance_given)
253     write_into_file(outfile, "distance", args_info->distance_orig, 0);
254   if (args_info->compare_given)
255     write_into_file(outfile, "compare", args_info->compare_orig, 0);
256   if (args_info->shapiro_given)
257     write_into_file(outfile, "shapiro", 0, 0 );
258   if (args_info->backtrack_given)
259     write_into_file(outfile, "backtrack", args_info->backtrack_orig, 0);
260   
261
262   i = EXIT_SUCCESS;
263   return i;
264 }
265
266 int
267 RNAdistance_cmdline_parser_file_save(const char *filename, struct RNAdistance_args_info *args_info)
268 {
269   FILE *outfile;
270   int i = 0;
271
272   outfile = fopen(filename, "w");
273
274   if (!outfile)
275     {
276       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNADISTANCE_CMDLINE_PARSER_PACKAGE, filename);
277       return EXIT_FAILURE;
278     }
279
280   i = RNAdistance_cmdline_parser_dump(outfile, args_info);
281   fclose (outfile);
282
283   return i;
284 }
285
286 void
287 RNAdistance_cmdline_parser_free (struct RNAdistance_args_info *args_info)
288 {
289   RNAdistance_cmdline_parser_release (args_info);
290 }
291
292 /** @brief replacement of strdup, which is not standard */
293 char *
294 gengetopt_strdup (const char *s)
295 {
296   char *result = 0;
297   if (!s)
298     return result;
299
300   result = (char*)malloc(strlen(s) + 1);
301   if (result == (char*)0)
302     return (char*)0;
303   strcpy(result, s);
304   return result;
305 }
306
307 int
308 RNAdistance_cmdline_parser (int argc, char **argv, struct RNAdistance_args_info *args_info)
309 {
310   return RNAdistance_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
311 }
312
313 int
314 RNAdistance_cmdline_parser_ext (int argc, char **argv, struct RNAdistance_args_info *args_info,
315                    struct RNAdistance_cmdline_parser_params *params)
316 {
317   int result;
318   result = RNAdistance_cmdline_parser_internal (argc, argv, args_info, params, 0);
319
320   if (result == EXIT_FAILURE)
321     {
322       RNAdistance_cmdline_parser_free (args_info);
323       exit (EXIT_FAILURE);
324     }
325   
326   return result;
327 }
328
329 int
330 RNAdistance_cmdline_parser2 (int argc, char **argv, struct RNAdistance_args_info *args_info, int override, int initialize, int check_required)
331 {
332   int result;
333   struct RNAdistance_cmdline_parser_params params;
334   
335   params.override = override;
336   params.initialize = initialize;
337   params.check_required = check_required;
338   params.check_ambiguity = 0;
339   params.print_errors = 1;
340
341   result = RNAdistance_cmdline_parser_internal (argc, argv, args_info, &params, 0);
342
343   if (result == EXIT_FAILURE)
344     {
345       RNAdistance_cmdline_parser_free (args_info);
346       exit (EXIT_FAILURE);
347     }
348   
349   return result;
350 }
351
352 int
353 RNAdistance_cmdline_parser_required (struct RNAdistance_args_info *args_info, const char *prog_name)
354 {
355   FIX_UNUSED (args_info);
356   FIX_UNUSED (prog_name);
357   return EXIT_SUCCESS;
358 }
359
360 /*
361  * Extracted from the glibc source tree, version 2.3.6
362  *
363  * Licensed under the GPL as per the whole glibc source tree.
364  *
365  * This file was modified so that getopt_long can be called
366  * many times without risking previous memory to be spoiled.
367  *
368  * Modified by Andre Noll and Lorenzo Bettini for use in
369  * GNU gengetopt generated files.
370  *
371  */
372
373 /* 
374  * we must include anything we need since this file is not thought to be
375  * inserted in a file already using getopt.h
376  *
377  * Lorenzo
378  */
379
380 struct option
381 {
382   const char *name;
383   /* has_arg can't be an enum because some compilers complain about
384      type mismatches in all the code that assumes it is an int.  */
385   int has_arg;
386   int *flag;
387   int val;
388 };
389
390 /* This version of `getopt' appears to the caller like standard Unix `getopt'
391    but it behaves differently for the user, since it allows the user
392    to intersperse the options with the other arguments.
393
394    As `getopt' works, it permutes the elements of ARGV so that,
395    when it is done, all the options precede everything else.  Thus
396    all application programs are extended to handle flexible argument order.
397 */
398 /*
399    If the field `flag' is not NULL, it points to a variable that is set
400    to the value given in the field `val' when the option is found, but
401    left unchanged if the option is not found.
402
403    To have a long-named option do something other than set an `int' to
404    a compiled-in constant, such as set a value from `custom_optarg', set the
405    option's `flag' field to zero and its `val' field to a nonzero
406    value (the equivalent single-letter option character, if there is
407    one).  For long options that have a zero `flag' field, `getopt'
408    returns the contents of the `val' field.  */
409
410 /* Names for the values of the `has_arg' field of `struct option'.  */
411 #ifndef no_argument
412 #define no_argument             0
413 #endif
414
415 #ifndef required_argument
416 #define required_argument       1
417 #endif
418
419 #ifndef optional_argument
420 #define optional_argument       2
421 #endif
422
423 struct custom_getopt_data {
424         /*
425          * These have exactly the same meaning as the corresponding global variables,
426          * except that they are used for the reentrant versions of getopt.
427          */
428         int custom_optind;
429         int custom_opterr;
430         int custom_optopt;
431         char *custom_optarg;
432
433         /* True if the internal members have been initialized.  */
434         int initialized;
435
436         /*
437          * The next char to be scanned in the option-element in which the last option
438          * character we returned was found.  This allows us to pick up the scan where
439          * we left off.  If this is zero, or a null string, it means resume the scan by
440          * advancing to the next ARGV-element.
441          */
442         char *nextchar;
443
444         /*
445          * Describe the part of ARGV that contains non-options that have been skipped.
446          * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
447          * the index after the last of them.
448          */
449         int first_nonopt;
450         int last_nonopt;
451 };
452
453 /*
454  * the variables optarg, optind, opterr and optopt are renamed with
455  * the custom_ prefix so that they don't interfere with getopt ones.
456  *
457  * Moreover they're static so they are visible only from within the
458  * file where this very file will be included.
459  */
460
461 /*
462  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
463  * option that takes an argument, the argument value is returned here.
464  */
465 static char *custom_optarg;
466
467 /*
468  * Index in ARGV of the next element to be scanned.  This is used for
469  * communication to and from the caller and for communication between
470  * successive calls to `custom_getopt'.
471  *
472  * On entry to `custom_getopt', 1 means this is the first call; initialize.
473  *
474  * When `custom_getopt' returns -1, this is the index of the first of the non-option
475  * elements that the caller should itself scan.
476  *
477  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
478  * has been scanned so far.
479  *
480  * 1003.2 says this must be 1 before any call.
481  */
482 static int custom_optind = 1;
483
484 /*
485  * Callers store zero here to inhibit the error message for unrecognized
486  * options.
487  */
488 static int custom_opterr = 1;
489
490 /*
491  * Set to an option character which was unrecognized.  This must be initialized
492  * on some systems to avoid linking in the system's own getopt implementation.
493  */
494 static int custom_optopt = '?';
495
496 /*
497  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
498  * [first_nonopt,last_nonopt) which contains all the non-options that have been
499  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
500  * all the options processed since those non-options were skipped.
501  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
502  * indices of the non-options in ARGV after they are moved.
503  */
504 static void exchange(char **argv, struct custom_getopt_data *d)
505 {
506         int bottom = d->first_nonopt;
507         int middle = d->last_nonopt;
508         int top = d->custom_optind;
509         char *tem;
510
511         /*
512          * Exchange the shorter segment with the far end of the longer segment.
513          * That puts the shorter segment into the right place.  It leaves the
514          * longer segment in the right place overall, but it consists of two
515          * parts that need to be swapped next.
516          */
517         while (top > middle && middle > bottom) {
518                 if (top - middle > middle - bottom) {
519                         /* Bottom segment is the short one.  */
520                         int len = middle - bottom;
521                         int i;
522
523                         /* Swap it with the top part of the top segment.  */
524                         for (i = 0; i < len; i++) {
525                                 tem = argv[bottom + i];
526                                 argv[bottom + i] =
527                                         argv[top - (middle - bottom) + i];
528                                 argv[top - (middle - bottom) + i] = tem;
529                         }
530                         /* Exclude the moved bottom segment from further swapping.  */
531                         top -= len;
532                 } else {
533                         /* Top segment is the short one.  */
534                         int len = top - middle;
535                         int i;
536
537                         /* Swap it with the bottom part of the bottom segment.  */
538                         for (i = 0; i < len; i++) {
539                                 tem = argv[bottom + i];
540                                 argv[bottom + i] = argv[middle + i];
541                                 argv[middle + i] = tem;
542                         }
543                         /* Exclude the moved top segment from further swapping.  */
544                         bottom += len;
545                 }
546         }
547         /* Update records for the slots the non-options now occupy.  */
548         d->first_nonopt += (d->custom_optind - d->last_nonopt);
549         d->last_nonopt = d->custom_optind;
550 }
551
552 /* Initialize the internal data when the first call is made.  */
553 static void custom_getopt_initialize(struct custom_getopt_data *d)
554 {
555         /*
556          * Start processing options with ARGV-element 1 (since ARGV-element 0
557          * is the program name); the sequence of previously skipped non-option
558          * ARGV-elements is empty.
559          */
560         d->first_nonopt = d->last_nonopt = d->custom_optind;
561         d->nextchar = NULL;
562         d->initialized = 1;
563 }
564
565 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
566
567 /* return: zero: continue, nonzero: return given value to user */
568 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
569         struct custom_getopt_data *d)
570 {
571         /*
572          * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
573          * moved back by the user (who may also have changed the arguments).
574          */
575         if (d->last_nonopt > d->custom_optind)
576                 d->last_nonopt = d->custom_optind;
577         if (d->first_nonopt > d->custom_optind)
578                 d->first_nonopt = d->custom_optind;
579         /*
580          * If we have just processed some options following some
581          * non-options, exchange them so that the options come first.
582          */
583         if (d->first_nonopt != d->last_nonopt &&
584                         d->last_nonopt != d->custom_optind)
585                 exchange((char **) argv, d);
586         else if (d->last_nonopt != d->custom_optind)
587                 d->first_nonopt = d->custom_optind;
588         /*
589          * Skip any additional non-options and extend the range of
590          * non-options previously skipped.
591          */
592         while (d->custom_optind < argc && NONOPTION_P)
593                 d->custom_optind++;
594         d->last_nonopt = d->custom_optind;
595         /*
596          * The special ARGV-element `--' means premature end of options.  Skip
597          * it like a null option, then exchange with previous non-options as if
598          * it were an option, then skip everything else like a non-option.
599          */
600         if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
601                 d->custom_optind++;
602                 if (d->first_nonopt != d->last_nonopt
603                                 && d->last_nonopt != d->custom_optind)
604                         exchange((char **) argv, d);
605                 else if (d->first_nonopt == d->last_nonopt)
606                         d->first_nonopt = d->custom_optind;
607                 d->last_nonopt = argc;
608                 d->custom_optind = argc;
609         }
610         /*
611          * If we have done all the ARGV-elements, stop the scan and back over
612          * any non-options that we skipped and permuted.
613          */
614         if (d->custom_optind == argc) {
615                 /*
616                  * Set the next-arg-index to point at the non-options that we
617                  * previously skipped, so the caller will digest them.
618                  */
619                 if (d->first_nonopt != d->last_nonopt)
620                         d->custom_optind = d->first_nonopt;
621                 return -1;
622         }
623         /*
624          * If we have come to a non-option and did not permute it, either stop
625          * the scan or describe it to the caller and pass it by.
626          */
627         if (NONOPTION_P) {
628                 d->custom_optarg = argv[d->custom_optind++];
629                 return 1;
630         }
631         /*
632          * We have found another option-ARGV-element. Skip the initial
633          * punctuation.
634          */
635         d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
636         return 0;
637 }
638
639 /*
640  * Check whether the ARGV-element is a long option.
641  *
642  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
643  * that an abbreviation of the long option, just like "--fu", and not "-f" with
644  * arg "u".
645  *
646  * This distinction seems to be the most useful approach.
647  *
648  */
649 static int check_long_opt(int argc, char *const *argv, const char *optstring,
650                 const struct option *longopts, int *longind,
651                 int print_errors, struct custom_getopt_data *d)
652 {
653         char *nameend;
654         const struct option *p;
655         const struct option *pfound = NULL;
656         int exact = 0;
657         int ambig = 0;
658         int indfound = -1;
659         int option_index;
660
661         for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
662                 /* Do nothing.  */ ;
663
664         /* Test all long options for either exact match or abbreviated matches */
665         for (p = longopts, option_index = 0; p->name; p++, option_index++)
666                 if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
667                         if ((unsigned int) (nameend - d->nextchar)
668                                         == (unsigned int) strlen(p->name)) {
669                                 /* Exact match found.  */
670                                 pfound = p;
671                                 indfound = option_index;
672                                 exact = 1;
673                                 break;
674                         } else if (pfound == NULL) {
675                                 /* First nonexact match found.  */
676                                 pfound = p;
677                                 indfound = option_index;
678                         } else if (pfound->has_arg != p->has_arg
679                                         || pfound->flag != p->flag
680                                         || pfound->val != p->val)
681                                 /* Second or later nonexact match found.  */
682                                 ambig = 1;
683                 }
684         if (ambig && !exact) {
685                 if (print_errors) {
686                         fprintf(stderr,
687                                 "%s: option `%s' is ambiguous\n",
688                                 argv[0], argv[d->custom_optind]);
689                 }
690                 d->nextchar += strlen(d->nextchar);
691                 d->custom_optind++;
692                 d->custom_optopt = 0;
693                 return '?';
694         }
695         if (pfound) {
696                 option_index = indfound;
697                 d->custom_optind++;
698                 if (*nameend) {
699                         if (pfound->has_arg != no_argument)
700                                 d->custom_optarg = nameend + 1;
701                         else {
702                                 if (print_errors) {
703                                         if (argv[d->custom_optind - 1][1] == '-') {
704                                                 /* --option */
705                                                 fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
706                                                         argv[0], pfound->name);
707                                         } else {
708                                                 /* +option or -option */
709                                                 fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
710                                                         argv[0], argv[d->custom_optind - 1][0], pfound->name);
711                                         }
712
713                                 }
714                                 d->nextchar += strlen(d->nextchar);
715                                 d->custom_optopt = pfound->val;
716                                 return '?';
717                         }
718                 } else if (pfound->has_arg == required_argument) {
719                         if (d->custom_optind < argc)
720                                 d->custom_optarg = argv[d->custom_optind++];
721                         else {
722                                 if (print_errors) {
723                                         fprintf(stderr,
724                                                 "%s: option `%s' requires an argument\n",
725                                                 argv[0],
726                                                 argv[d->custom_optind - 1]);
727                                 }
728                                 d->nextchar += strlen(d->nextchar);
729                                 d->custom_optopt = pfound->val;
730                                 return optstring[0] == ':' ? ':' : '?';
731                         }
732                 }
733                 d->nextchar += strlen(d->nextchar);
734                 if (longind != NULL)
735                         *longind = option_index;
736                 if (pfound->flag) {
737                         *(pfound->flag) = pfound->val;
738                         return 0;
739                 }
740                 return pfound->val;
741         }
742         /*
743          * Can't find it as a long option.  If this is not getopt_long_only, or
744          * the option starts with '--' or is not a valid short option, then
745          * it's an error.  Otherwise interpret it as a short option.
746          */
747         if (print_errors) {
748                 if (argv[d->custom_optind][1] == '-') {
749                         /* --option */
750                         fprintf(stderr,
751                                 "%s: unrecognized option `--%s'\n",
752                                 argv[0], d->nextchar);
753                 } else {
754                         /* +option or -option */
755                         fprintf(stderr,
756                                 "%s: unrecognized option `%c%s'\n",
757                                 argv[0], argv[d->custom_optind][0],
758                                 d->nextchar);
759                 }
760         }
761         d->nextchar = (char *) "";
762         d->custom_optind++;
763         d->custom_optopt = 0;
764         return '?';
765 }
766
767 static int check_short_opt(int argc, char *const *argv, const char *optstring,
768                 int print_errors, struct custom_getopt_data *d)
769 {
770         char c = *d->nextchar++;
771         const char *temp = strchr(optstring, c);
772
773         /* Increment `custom_optind' when we start to process its last character.  */
774         if (*d->nextchar == '\0')
775                 ++d->custom_optind;
776         if (!temp || c == ':') {
777                 if (print_errors)
778                         fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
779
780                 d->custom_optopt = c;
781                 return '?';
782         }
783         if (temp[1] == ':') {
784                 if (temp[2] == ':') {
785                         /* This is an option that accepts an argument optionally.  */
786                         if (*d->nextchar != '\0') {
787                                 d->custom_optarg = d->nextchar;
788                                 d->custom_optind++;
789                         } else
790                                 d->custom_optarg = NULL;
791                         d->nextchar = NULL;
792                 } else {
793                         /* This is an option that requires an argument.  */
794                         if (*d->nextchar != '\0') {
795                                 d->custom_optarg = d->nextchar;
796                                 /*
797                                  * If we end this ARGV-element by taking the
798                                  * rest as an arg, we must advance to the next
799                                  * element now.
800                                  */
801                                 d->custom_optind++;
802                         } else if (d->custom_optind == argc) {
803                                 if (print_errors) {
804                                         fprintf(stderr,
805                                                 "%s: option requires an argument -- %c\n",
806                                                 argv[0], c);
807                                 }
808                                 d->custom_optopt = c;
809                                 if (optstring[0] == ':')
810                                         c = ':';
811                                 else
812                                         c = '?';
813                         } else
814                                 /*
815                                  * We already incremented `custom_optind' once;
816                                  * increment it again when taking next ARGV-elt
817                                  * as argument.
818                                  */
819                                 d->custom_optarg = argv[d->custom_optind++];
820                         d->nextchar = NULL;
821                 }
822         }
823         return c;
824 }
825
826 /*
827  * Scan elements of ARGV for option characters given in OPTSTRING.
828  *
829  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
830  * then it is an option element.  The characters of this element
831  * (aside from the initial '-') are option characters.  If `getopt'
832  * is called repeatedly, it returns successively each of the option characters
833  * from each of the option elements.
834  *
835  * If `getopt' finds another option character, it returns that character,
836  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
837  * resume the scan with the following option character or ARGV-element.
838  *
839  * If there are no more option characters, `getopt' returns -1.
840  * Then `custom_optind' is the index in ARGV of the first ARGV-element
841  * that is not an option.  (The ARGV-elements have been permuted
842  * so that those that are not options now come last.)
843  *
844  * OPTSTRING is a string containing the legitimate option characters.
845  * If an option character is seen that is not listed in OPTSTRING,
846  * return '?' after printing an error message.  If you set `custom_opterr' to
847  * zero, the error message is suppressed but we still return '?'.
848  *
849  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
850  * so the following text in the same ARGV-element, or the text of the following
851  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
852  * wants an optional arg; if there is text in the current ARGV-element,
853  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
854  *
855  * If OPTSTRING starts with `-' or `+', it requests different methods of
856  * handling the non-option ARGV-elements.
857  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
858  *
859  * Long-named options begin with `--' instead of `-'.
860  * Their names may be abbreviated as long as the abbreviation is unique
861  * or is an exact match for some defined option.  If they have an
862  * argument, it follows the option name in the same ARGV-element, separated
863  * from the option name by a `=', or else the in next ARGV-element.
864  * When `getopt' finds a long-named option, it returns 0 if that option's
865  * `flag' field is nonzero, the value of the option's `val' field
866  * if the `flag' field is zero.
867  *
868  * The elements of ARGV aren't really const, because we permute them.
869  * But we pretend they're const in the prototype to be compatible
870  * with other systems.
871  *
872  * LONGOPTS is a vector of `struct option' terminated by an
873  * element containing a name which is zero.
874  *
875  * LONGIND returns the index in LONGOPT of the long-named option found.
876  * It is only valid when a long-named option has been found by the most
877  * recent call.
878  *
879  * Return the option character from OPTS just read.  Return -1 when there are
880  * no more options.  For unrecognized options, or options missing arguments,
881  * `custom_optopt' is set to the option letter, and '?' is returned.
882  *
883  * The OPTS string is a list of characters which are recognized option letters,
884  * optionally followed by colons, specifying that that letter takes an
885  * argument, to be placed in `custom_optarg'.
886  *
887  * If a letter in OPTS is followed by two colons, its argument is optional.
888  * This behavior is specific to the GNU `getopt'.
889  *
890  * The argument `--' causes premature termination of argument scanning,
891  * explicitly telling `getopt' that there are no more options.  If OPTS begins
892  * with `--', then non-option arguments are treated as arguments to the option
893  * '\0'.  This behavior is specific to the GNU `getopt'.
894  */
895
896 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
897                 const struct option *longopts, int *longind,
898                 struct custom_getopt_data *d)
899 {
900         int ret, print_errors = d->custom_opterr;
901
902         if (optstring[0] == ':')
903                 print_errors = 0;
904         if (argc < 1)
905                 return -1;
906         d->custom_optarg = NULL;
907
908         /* 
909          * This is a big difference with GNU getopt, since optind == 0
910          * means initialization while here 1 means first call.
911          */
912         if (d->custom_optind == 0 || !d->initialized) {
913                 if (d->custom_optind == 0)
914                         d->custom_optind = 1;   /* Don't scan ARGV[0], the program name.  */
915                 custom_getopt_initialize(d);
916         }
917         if (d->nextchar == NULL || *d->nextchar == '\0') {
918                 ret = shuffle_argv(argc, argv, longopts, d);
919                 if (ret)
920                         return ret;
921         }
922         if (longopts && (argv[d->custom_optind][1] == '-' ))
923                 return check_long_opt(argc, argv, optstring, longopts,
924                         longind, print_errors, d);
925         return check_short_opt(argc, argv, optstring, print_errors, d);
926 }
927
928 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
929         const struct option *longopts, int *longind)
930 {
931         int result;
932         /* Keep a global copy of all internal members of d */
933         static struct custom_getopt_data d;
934
935         d.custom_optind = custom_optind;
936         d.custom_opterr = custom_opterr;
937         result = getopt_internal_r(argc, argv, optstring, longopts,
938                 longind, &d);
939         custom_optind = d.custom_optind;
940         custom_optarg = d.custom_optarg;
941         custom_optopt = d.custom_optopt;
942         return result;
943 }
944
945 static int custom_getopt_long (int argc, char *const *argv, const char *options,
946         const struct option *long_options, int *opt_index)
947 {
948         return custom_getopt_internal(argc, argv, options, long_options,
949                 opt_index);
950 }
951
952
953 static char *package_name = 0;
954
955 /**
956  * @brief updates an option
957  * @param field the generic pointer to the field to update
958  * @param orig_field the pointer to the orig field
959  * @param field_given the pointer to the number of occurrence of this option
960  * @param prev_given the pointer to the number of occurrence already seen
961  * @param value the argument for this option (if null no arg was specified)
962  * @param possible_values the possible values for this option (if specified)
963  * @param default_value the default value (in case the option only accepts fixed values)
964  * @param arg_type the type of this option
965  * @param check_ambiguity @see RNAdistance_cmdline_parser_params.check_ambiguity
966  * @param override @see RNAdistance_cmdline_parser_params.override
967  * @param no_free whether to free a possible previous value
968  * @param multiple_option whether this is a multiple option
969  * @param long_opt the corresponding long option
970  * @param short_opt the corresponding short option (or '-' if none)
971  * @param additional_error possible further error specification
972  */
973 static
974 int update_arg(void *field, char **orig_field,
975                unsigned int *field_given, unsigned int *prev_given, 
976                char *value, const char *possible_values[],
977                const char *default_value,
978                RNAdistance_cmdline_parser_arg_type arg_type,
979                int check_ambiguity, int override,
980                int no_free, int multiple_option,
981                const char *long_opt, char short_opt,
982                const char *additional_error)
983 {
984   char *stop_char = 0;
985   const char *val = value;
986   int found;
987   char **string_field;
988   FIX_UNUSED (field);
989
990   stop_char = 0;
991   found = 0;
992
993   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
994     {
995       if (short_opt != '-')
996         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", 
997                package_name, long_opt, short_opt,
998                (additional_error ? additional_error : ""));
999       else
1000         fprintf (stderr, "%s: `--%s' option given more than once%s\n", 
1001                package_name, long_opt,
1002                (additional_error ? additional_error : ""));
1003       return 1; /* failure */
1004     }
1005
1006   FIX_UNUSED (default_value);
1007     
1008   if (field_given && *field_given && ! override)
1009     return 0;
1010   if (prev_given)
1011     (*prev_given)++;
1012   if (field_given)
1013     (*field_given)++;
1014   if (possible_values)
1015     val = possible_values[found];
1016
1017   switch(arg_type) {
1018   case ARG_FLAG:
1019     *((int *)field) = !*((int *)field);
1020     break;
1021   case ARG_STRING:
1022     if (val) {
1023       string_field = (char **)field;
1024       if (!no_free && *string_field)
1025         free (*string_field); /* free previous string */
1026       *string_field = gengetopt_strdup (val);
1027     }
1028     break;
1029   default:
1030     break;
1031   };
1032
1033
1034   /* store the original value */
1035   switch(arg_type) {
1036   case ARG_NO:
1037   case ARG_FLAG:
1038     break;
1039   default:
1040     if (value && orig_field) {
1041       if (no_free) {
1042         *orig_field = value;
1043       } else {
1044         if (*orig_field)
1045           free (*orig_field); /* free previous string */
1046         *orig_field = gengetopt_strdup (value);
1047       }
1048     }
1049   };
1050
1051   return 0; /* OK */
1052 }
1053
1054
1055 int
1056 RNAdistance_cmdline_parser_internal (
1057   int argc, char **argv, struct RNAdistance_args_info *args_info,
1058                         struct RNAdistance_cmdline_parser_params *params, const char *additional_error)
1059 {
1060   int c;        /* Character of the parsed option.  */
1061
1062   int error = 0;
1063   struct RNAdistance_args_info local_args_info;
1064   
1065   int override;
1066   int initialize;
1067   int check_required;
1068   int check_ambiguity;
1069
1070   char *optarg;
1071   int optind;
1072   int opterr;
1073   int optopt;
1074   
1075   package_name = argv[0];
1076   
1077   override = params->override;
1078   initialize = params->initialize;
1079   check_required = params->check_required;
1080   check_ambiguity = params->check_ambiguity;
1081
1082   if (initialize)
1083     RNAdistance_cmdline_parser_init (args_info);
1084
1085   RNAdistance_cmdline_parser_init (&local_args_info);
1086
1087   optarg = 0;
1088   optind = 0;
1089   opterr = params->print_errors;
1090   optopt = '?';
1091
1092   while (1)
1093     {
1094       int option_index = 0;
1095
1096       static struct option long_options[] = {
1097         { "help",       0, NULL, 'h' },
1098         { "detailed-help",      0, NULL, 0 },
1099         { "version",    0, NULL, 'V' },
1100         { "distance",   1, NULL, 'D' },
1101         { "compare",    1, NULL, 'X' },
1102         { "shapiro",    0, NULL, 'S' },
1103         { "backtrack",  2, NULL, 'B' },
1104         { 0,  0, 0, 0 }
1105       };
1106
1107       custom_optarg = optarg;
1108       custom_optind = optind;
1109       custom_opterr = opterr;
1110       custom_optopt = optopt;
1111
1112       c = custom_getopt_long (argc, argv, "hVD:X:SB::", long_options, &option_index);
1113
1114       optarg = custom_optarg;
1115       optind = custom_optind;
1116       opterr = custom_opterr;
1117       optopt = custom_optopt;
1118
1119       if (c == -1) break;       /* Exit from `while (1)' loop.  */
1120
1121       switch (c)
1122         {
1123         case 'h':       /* Print help and exit.  */
1124           RNAdistance_cmdline_parser_print_help ();
1125           RNAdistance_cmdline_parser_free (&local_args_info);
1126           exit (EXIT_SUCCESS);
1127
1128         case 'V':       /* Print version and exit.  */
1129           RNAdistance_cmdline_parser_print_version ();
1130           RNAdistance_cmdline_parser_free (&local_args_info);
1131           exit (EXIT_SUCCESS);
1132
1133         case 'D':       /* Specify the distance representation to be used in calculations.
1134 .  */
1135         
1136         
1137           if (update_arg( (void *)&(args_info->distance_arg), 
1138                &(args_info->distance_orig), &(args_info->distance_given),
1139               &(local_args_info.distance_given), optarg, 0, "f", ARG_STRING,
1140               check_ambiguity, override, 0, 0,
1141               "distance", 'D',
1142               additional_error))
1143             goto failure;
1144         
1145           break;
1146         case 'X':       /* Specify the comparison directive.
1147 .  */
1148         
1149         
1150           if (update_arg( (void *)&(args_info->compare_arg), 
1151                &(args_info->compare_orig), &(args_info->compare_given),
1152               &(local_args_info.compare_given), optarg, 0, "p", ARG_STRING,
1153               check_ambiguity, override, 0, 0,
1154               "compare", 'X',
1155               additional_error))
1156             goto failure;
1157         
1158           break;
1159         case 'S':       /* Use the Bruce Shapiro's cost matrix for comparing coarse structures.
1160         
1161 .  */
1162         
1163         
1164           if (update_arg((void *)&(args_info->shapiro_flag), 0, &(args_info->shapiro_given),
1165               &(local_args_info.shapiro_given), optarg, 0, 0, ARG_FLAG,
1166               check_ambiguity, override, 1, 0, "shapiro", 'S',
1167               additional_error))
1168             goto failure;
1169         
1170           break;
1171         case 'B':       /* Print an \"alignment\" with gaps of the structures, to show matching substructures. The aligned structures are written to <filename>, if specified.
1172 .  */
1173         
1174         
1175           if (update_arg( (void *)&(args_info->backtrack_arg), 
1176                &(args_info->backtrack_orig), &(args_info->backtrack_given),
1177               &(local_args_info.backtrack_given), optarg, 0, "none", ARG_STRING,
1178               check_ambiguity, override, 0, 0,
1179               "backtrack", 'B',
1180               additional_error))
1181             goto failure;
1182         
1183           break;
1184
1185         case 0: /* Long option with no short option */
1186           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1187             RNAdistance_cmdline_parser_print_detailed_help ();
1188             RNAdistance_cmdline_parser_free (&local_args_info);
1189             exit (EXIT_SUCCESS);
1190           }
1191
1192         case '?':       /* Invalid option.  */
1193           /* `getopt_long' already printed an error message.  */
1194           goto failure;
1195
1196         default:        /* bug: option not considered.  */
1197           fprintf (stderr, "%s: option unknown: %c%s\n", RNADISTANCE_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1198           abort ();
1199         } /* switch */
1200     } /* while */
1201
1202
1203
1204
1205   RNAdistance_cmdline_parser_release (&local_args_info);
1206
1207   if ( error )
1208     return (EXIT_FAILURE);
1209
1210   return 0;
1211
1212 failure:
1213   
1214   RNAdistance_cmdline_parser_release (&local_args_info);
1215   return (EXIT_FAILURE);
1216 }