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