1 /*
2   File autogenerated by gengetopt version 2.23
3   generated with the following command:
4   /usr/bin/gengetopt -i RNALalifold.ggo --file-name=RNALalifold_cmdl --include-getopt --default-optional --unamed-opts --func-name=RNALalifold_cmdline_parser --arg-struct-name=RNALalifold_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 "RNALalifold_cmdl.h"
26 
27 const char *RNALalifold_args_info_purpose = "calculate locally stable secondary structures for a set of aligned RNAs";
28 
29 const char *RNALalifold_args_info_usage = "Usage: RNALalifold [options] <file1.aln>";
30 
31 const char *RNALalifold_args_info_versiontext = "";
32 
33 const char *RNALalifold_args_info_description = "reads aligned RNA sequences from stdin or file.aln and calculates locally\nstable RNA secondary structure with a maximal base pair span. For a sequence of\nlength n and a base pair span of L the algorithm uses only O(n+L*L) memory and\nO(n*L*L) CPU time. Thus it is practical to \"scan\" very large genomes for\nshort RNA\n structures.\n";
34 
35 const char *RNALalifold_args_info_detailed_help[] = {
36   "  -h, --help                    Print help and exit",
37   "      --detailed-help           Print help, including all details and hidden\n                                  options, and exit",
38   "      --full-help               Print help, including hidden options, and exit",
39   "  -V, --version                 Print version and exit",
40   "\nGeneral Options:",
41   "  Command line options which alter the general behavior of this program\n\n",
42   "  -v, --verbose                 Be verbose.\n\n                                    (default=off)",
43   "  -q, --quiet                   Be quiet.\n                                    (default=off)",
44   "  This option can be used to minimize the output of additional information and\n  non-severe warnings which otherwise might spam stdout/stderr.\n\n",
45   "      --noconv                  Do not automatically substitute nucleotide\n                                  \"T\" with \"U\"\n\n                                    (default=off)",
46   "  -f, --input-format=C|S|F|M    File format of the input multiple sequence\n                                  alignment (MSA).\n",
47   "  If this parameter is set, the input is considered to be in a particular file\n  format. Otherwise, the program tries to determine the file format\n  automatically, if an input file was provided in the set of parameters. In\n  case the input MSA is provided in interactive mode, or from a terminal (TTY),\n  the programs default is to assume CLUSTALW format.\n  Currently, the following formats are available: ClustalW (C), Stockholm 1.0\n  (S), FASTA/Pearson (F), and MAF (M).\n\n",
48   "      --csv                     Create comma separated output (csv)\n\n                                    (default=off)",
49   "      --aln[=prefix]            Produce output alignments and secondary\n                                  structure plots for each hit found.\n",
50   "  This option tells the program to produce, for each hit, a colored and\n  structure annotated (sub)alignment and secondary structure plot in PostScript\n  format. It also adds the subalignment hit into a multi-Stockholm formatted\n  file \"RNALalifold_results.stk\". The postscript output file names are\n  \"aln_start_end.eps\" and \"ss_start_end.eps\". All files will be created in\n  the current directory. The optional argument string can be used to set a\n  specific prefix that is used to name the output files. The file names then\n  become \"prefix_aln_start_end.eps\", \"prefix_ss_start_end.eps\", and\n  \"prefix.stk\". Note: Any special characters in the prefix will be replaced\n  by the filename delimiter, hence there is no way to pass an entire directory\n  path through this option yet. (See also the \"--filename-delim\" parameter)\n\n",
51   "      --aln-EPS[=prefix]        Produce colored and structure annotated\n                                  subalignment for each hit\n",
52   "  The default file name used for the output is \"aln_start_end.eps\" where\n  \"start\" and \"end\" denote the first and last column of the subalignment\n  relative to the input (1-based). Users may change the filename to\n  \"prefix_aln_start_end.eps\" by specifying the prefix as optional argument.\n  Files will be create in the current directory. Note: Any special characters\n  in the prefix will be replaced by the filename delimiter, hence there is no\n  way to pass an entire directory path through this option yet. (See also the\n  \"--filename-delim\" parameter)\n\n",
53   "      --aln-EPS-cols=INT        Number of columns in colored EPS alignment\n                                  output.\n                                    (default=`60')",
54   "  A value less than 1 indicates that the output should not be wrapped at all.\n\n",
55   "      --aln-EPS-ss[=prefix]     Produce colored consensus secondary structure\n                                  plots in PostScript format\n",
56   "  The default file name used for the output is \"ss_start_end.eps\" where\n  \"start\" and \"end\" denote the first and last column of the subalignment\n  relative to the input (1-based). Users may change the filename to\n  \"prefix_ss_start_end.eps\" by specifying the prefix as optional argument.\n  Files will be create in the current directory. Note: Any special characters\n  in the prefix will be replaced by the filename delimiter, hence there is no\n  way to pass an entire directory path through this option yet. (See also the\n  \"--filename-delim\" parameter)\n\n",
57   "      --aln-stk[=prefix]        Add hits to a multi-Stockholm formatted output\n                                  file.\n                                    (default=`RNALalifold_results')",
58   "  The default file name used for the output is \"RNALalifold_results.stk\".\n  Users may change the filename to \"prefix.stk\" by specifying the prefix as\n  optional argument. The file will be create in the current directory if it\n  does not already exist. In case the file already exists, output will be\n  appended to it. Note: Any special characters in the prefix will be replaced\n  by the filename delimiter, hence there is no way to pass an entire directory\n  path through this option yet. (See also the \"--filename-delim\" parameter)\n\n",
59   "      --auto-id                 Automatically generate an ID for each\n                                  alignment.\n                                    (default=off)",
60   "  The default mode of RNALalifold is to automatically determine an ID from the\n  input alignment if the input file format allows to do that. Alignment IDs\n  are, for instance, usually given in Stockholm 1.0 formatted input. If this\n  flag is active, RNALalifold ignores any IDs retrieved from the input and\n  automatically generates an ID for each alignment.\n\n",
61   "      --id-prefix=prefix        Prefix for automatically generated IDs (as used\n                                  in output file names)\n\n                                    (default=`alignment')",
62   "  If this parameter is set, each alignment will be prefixed with the provided\n  string. Hence, the output files will obey the following naming scheme:\n  \"prefix_xxxx_ss.ps\" (secondary structure plot), \"prefix_xxxx_dp.ps\"\n  (dot-plot), \"prefix_xxxx_aln.ps\" (annotated alignment), etc. where xxxx is\n  the alignment number beginning with the second alignment in the input. Use\n  this setting in conjunction with the --continuous-ids flag to assign IDs\n  beginning with the first input alignment.\n\n",
63   "      --id-delim=delimiter      Change the delimiter between prefix and\n                                  increasing number for automatically generated\n                                  IDs (as used in output file names)\n\n                                    (default=`_')",
64   "  This parameter can be used to change the default delimiter \"_\" between\n   the prefix string and the increasing number for automatically generated ID.\n\n",
65   "      --id-digits=INT           Specify the number of digits of the counter in\n                                  automatically generated alignment IDs.\n                                    (default=`4')",
66   "  When alignments IDs are automatically generated, they receive an increasing\n  number, starting with 1. This number will always be left-padded by leading\n  zeros, such that the number takes up a certain width. Using this parameter,\n  the width can be specified to the users need. We allow numbers in the range\n  [1:18].\n\n",
67   "      --id-start=LONG           Specify the first number in automatically\n                                  generated alignment IDs.\n                                    (default=`1')",
68   "  When alignment IDs are automatically generated, they receive an increasing\n  number, usually starting with 1. Using this parameter, the first number can\n  be specified to the users requirements. Note: negative numbers are not\n  allowed.\n  Note: Setting this parameter implies continuous alignment IDs, i.e. it\n  activates the --continuous-ids flag.\n\n",
69   "      --filename-delim=delimiter\n                                Change the delimiting character that is used\n                                  for sanitized filenames\n\n                                    (default=`ID-delimiter')",
70   "  This parameter can be used to change the delimiting character used while\n  sanitizing filenames, i.e. replacing invalid characters. Note, that the\n  default delimiter ALWAYS is the first character of the \"ID delimiter\" as\n  supplied through the --id-delim option. If the delimiter is a whitespace\n  character or empty, invalid characters will be simply removed rather than\n  substituted. Currently, we regard the following characters as illegal for use\n  in filenames: backslash '\', slash '/', question mark '?', percent sign '%',\n  asterisk '*', colon ':', pipe symbol '|', double quote '\"', triangular\n  brackets '<' and '>'.\n\n",
71   "      --split-contributions     Split the free energy contributions into\n                                  separate parts\n                                    (default=off)",
72   "  By default, only the total energy contribution for each hit is returned.\n  Using this option, this contribution is split into individual parts, i.e. the\n  Nearest Neighbor model energy, the covariance pseudo energy, and if\n  applicable, a remaining pseudo energy derived from special constraints, such\n  as probing signals like SHAPE.\n\n",
73   "\nStructure Constraints:",
74   "  Command line options to interact with the structure constraints feature of\n  this program\n\n",
75   "      --shape=file1,file2       Use SHAPE reactivity data to guide structure\n                                  predictions\n",
76   "  Multiple shapefiles for the individual sequences in the alignment may be\n  specified  as a comma separated list. An optional association of particular\n  shape files to a specific  sequence in the alignment can be expressed by\n  prepending the sequence number to the filename,  e.g.\n  \"5=seq5.shape,3=seq3.shape\" will assign the reactivity values from file\n  seq5.shape to  the fifth sequence in the alignment, and the values from file\n  seq3.shape to sequence 3. If  no assignment is specified, the reactivity\n  values are assigned to corresponding sequences in  the order they are given.\n\n",
77   "      --shapeMethod=D[mX][bY]   Specify the method how to convert SHAPE\n                                  reactivity data to pseudo energy\n                                  contributions\n                                    (default=`D')",
78   "  Currently, the only data conversion method available is that of to Deigan et\n  al 2009.  This method is the default and is recognized by a capital 'D' in\n  the provided parameter, i.e.:  --shapeMethod=\"D\" is the default setting.\n  The slope 'm' and the intercept 'b' can be set to a  non-default value if\n  necessary. Otherwise m=1.8 and b=-0.6 as stated in the paper mentionen\n  before.  To alter these parameters, e.g. m=1.9 and b=-0.7, use a  parameter\n  string like this: --shapeMethod=\"Dm1.9b-0.7\". You may also provide only one\n  of the two  parameters like: --shapeMethod=\"Dm1.9\" or\n  --shapeMethod=\"Db-0.7\".\n\n",
79   "\nAlgorithms:",
80   "  Select additional algorithms which should be included in the calculations.\n  The Minimum free energy (MFE) and a structure representative are calculated\n  in any case.\n\n",
81   "  -L, --maxBPspan=INT           Set the maximum allowed separation of a base\n                                  pair to span. I.e. no pairs (i,j) with\n                                  j-i>span will be allowed.\n\n                                    (default=`70')",
82   "      --threshold=DOUBLE        Energy threshold in kcal/mol per nucleotide\n                                  above which secondary structure hits are\n                                  omitted in the output.\n\n                                    (default=`-0.1')",
83   "      --mis                     Output \"most informative sequence\" instead of\n                                  simple consensus: For each column of the\n                                  alignment output the set of nucleotides with\n                                  frequency greater than average in IUPAC\n                                  notation.\n\n                                    (default=off)",
84   "  -g, --gquad                   Incoorporate G-Quadruplex formation into the\n                                  structure prediction algorithm\n\n                                    (default=off)",
85   "\nModel Details:",
86   "  -T, --temp=DOUBLE             Rescale energy parameters to a temperature of\n                                  temp C. Default is 37C.\n\n",
87   "  -4, --noTetra                 Do not include special tabulated stabilizing\n                                  energies for tri-, tetra- and hexaloop\n                                  hairpins. Mostly for testing.\n\n                                    (default=off)",
88   "  -d, --dangles=INT             How to treat \"dangling end\" energies for\n                                  bases adjacent to helices in free ends and\n                                  multi-loops\n                                    (default=`2')",
89   "  \n  With -d1 only unpaired bases can participate in at most one dangling end.\n  With -d2 this check is ignored, dangling energies will be added for the bases\n  adjacent to a helix on both sides in any case; this is the default for mfe\n  and partition function folding (-p).\n  The option -d0 ignores dangling ends altogether (mostly for debugging).\n  With -d3 mfe folding will allow coaxial stacking of adjacent helices in\n  multi-loops. At the moment the implementation will not allow coaxial stacking\n  of the two interior pairs in a loop of degree 3 and works only for mfe\n  folding.\n\n  Note that with -d1 and -d3 only the MFE computations will be using this\n  setting while partition function uses -d2 setting, i.e. dangling ends will be\n  treated differently.\n\n",
90   "      --noLP                    Produce structures without lonely pairs\n                                  (helices of length 1).\n                                    (default=off)",
91   "  For partition function folding this only disallows pairs that can only occur\n  isolated. Other pairs may still occasionally occur as helices of length 1.\n\n",
92   "      --noGU                    Do not allow GU pairs\n\n                                    (default=off)",
93   "      --noClosingGU             Do not allow GU pairs at the end of helices\n\n                                    (default=off)",
94   "  -P, --paramFile=paramfile     Read energy parameters from paramfile, instead\n                                  of using the default parameter set.\n",
95   "  Different sets of energy parameters for RNA and DNA should accompany your\n  distribution.\n  See the RNAlib documentation for details on the file format. When passing the\n  placeholder file name \"DNA\", DNA parameters are loaded without the need to\n  actually specify any input file.\n\n",
96   "      --nsp=STRING              Allow other pairs in addition to the usual\n                                  AU,GC,and GU pairs.\n",
97   "  Its argument is a comma separated list of additionally allowed pairs. If the\n  first character is a \"-\" then AB will imply that AB and BA are allowed\n  pairs.\n  e.g. RNAfold -nsp -GA  will allow GA and AG pairs. Nonstandard pairs are\n  given 0 stacking energy.\n\n",
98   "  -e, --energyModel=INT         Rarely used option to fold sequences from the\n                                  artificial ABCD... alphabet, where A pairs B,\n                                  C-D etc.  Use the energy parameters for GC\n                                  (-e 1) or AU (-e 2) pairs.\n\n",
99   "      --cfactor=DOUBLE          Set the weight of the covariance term in the\n                                  energy function\n\n                                    (default=`1.0')",
100   "      --nfactor=DOUBLE          Set the penalty for non-compatible sequences in\n                                  the covariance term of the energy function\n\n                                    (default=`1.0')",
101   "  -R, --ribosum_file=ribosumfile\n                                use specified Ribosum Matrix instead of normal\n                                  energy model. Matrixes to use should be 6x6\n                                  matrices, the order of the terms is AU, CG,\n                                  GC, GU, UA, UG.\n\n",
102   "  -r, --ribosum_scoring         use ribosum scoring matrix. The matrix is\n                                  chosen according to the minimal and maximal\n                                  pairwise identities of the sequences in the\n                                  file.\n\n                                    (default=off)",
103   "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n\n",
104     0
105 };
106 static void
init_full_help_array(void)107 init_full_help_array(void)
108 {
109   RNALalifold_args_info_full_help[0] = RNALalifold_args_info_detailed_help[0];
110   RNALalifold_args_info_full_help[1] = RNALalifold_args_info_detailed_help[1];
111   RNALalifold_args_info_full_help[2] = RNALalifold_args_info_detailed_help[2];
112   RNALalifold_args_info_full_help[3] = RNALalifold_args_info_detailed_help[3];
113   RNALalifold_args_info_full_help[4] = RNALalifold_args_info_detailed_help[4];
114   RNALalifold_args_info_full_help[5] = RNALalifold_args_info_detailed_help[5];
115   RNALalifold_args_info_full_help[6] = RNALalifold_args_info_detailed_help[6];
116   RNALalifold_args_info_full_help[7] = RNALalifold_args_info_detailed_help[7];
117   RNALalifold_args_info_full_help[8] = RNALalifold_args_info_detailed_help[9];
118   RNALalifold_args_info_full_help[9] = RNALalifold_args_info_detailed_help[10];
119   RNALalifold_args_info_full_help[10] = RNALalifold_args_info_detailed_help[12];
120   RNALalifold_args_info_full_help[11] = RNALalifold_args_info_detailed_help[13];
121   RNALalifold_args_info_full_help[12] = RNALalifold_args_info_detailed_help[15];
122   RNALalifold_args_info_full_help[13] = RNALalifold_args_info_detailed_help[17];
123   RNALalifold_args_info_full_help[14] = RNALalifold_args_info_detailed_help[19];
124   RNALalifold_args_info_full_help[15] = RNALalifold_args_info_detailed_help[21];
125   RNALalifold_args_info_full_help[16] = RNALalifold_args_info_detailed_help[23];
126   RNALalifold_args_info_full_help[17] = RNALalifold_args_info_detailed_help[25];
127   RNALalifold_args_info_full_help[18] = RNALalifold_args_info_detailed_help[27];
128   RNALalifold_args_info_full_help[19] = RNALalifold_args_info_detailed_help[29];
129   RNALalifold_args_info_full_help[20] = RNALalifold_args_info_detailed_help[31];
130   RNALalifold_args_info_full_help[21] = RNALalifold_args_info_detailed_help[33];
131   RNALalifold_args_info_full_help[22] = RNALalifold_args_info_detailed_help[35];
132   RNALalifold_args_info_full_help[23] = RNALalifold_args_info_detailed_help[37];
133   RNALalifold_args_info_full_help[24] = RNALalifold_args_info_detailed_help[38];
134   RNALalifold_args_info_full_help[25] = RNALalifold_args_info_detailed_help[39];
135   RNALalifold_args_info_full_help[26] = RNALalifold_args_info_detailed_help[41];
136   RNALalifold_args_info_full_help[27] = RNALalifold_args_info_detailed_help[43];
137   RNALalifold_args_info_full_help[28] = RNALalifold_args_info_detailed_help[44];
138   RNALalifold_args_info_full_help[29] = RNALalifold_args_info_detailed_help[45];
139   RNALalifold_args_info_full_help[30] = RNALalifold_args_info_detailed_help[46];
140   RNALalifold_args_info_full_help[31] = RNALalifold_args_info_detailed_help[47];
141   RNALalifold_args_info_full_help[32] = RNALalifold_args_info_detailed_help[48];
142   RNALalifold_args_info_full_help[33] = RNALalifold_args_info_detailed_help[49];
143   RNALalifold_args_info_full_help[34] = RNALalifold_args_info_detailed_help[50];
144   RNALalifold_args_info_full_help[35] = RNALalifold_args_info_detailed_help[51];
145   RNALalifold_args_info_full_help[36] = RNALalifold_args_info_detailed_help[52];
146   RNALalifold_args_info_full_help[37] = RNALalifold_args_info_detailed_help[54];
147   RNALalifold_args_info_full_help[38] = RNALalifold_args_info_detailed_help[56];
148   RNALalifold_args_info_full_help[39] = RNALalifold_args_info_detailed_help[57];
149   RNALalifold_args_info_full_help[40] = RNALalifold_args_info_detailed_help[58];
150   RNALalifold_args_info_full_help[41] = RNALalifold_args_info_detailed_help[60];
151   RNALalifold_args_info_full_help[42] = RNALalifold_args_info_detailed_help[62];
152   RNALalifold_args_info_full_help[43] = RNALalifold_args_info_detailed_help[63];
153   RNALalifold_args_info_full_help[44] = RNALalifold_args_info_detailed_help[64];
154   RNALalifold_args_info_full_help[45] = RNALalifold_args_info_detailed_help[65];
155   RNALalifold_args_info_full_help[46] = RNALalifold_args_info_detailed_help[66];
156   RNALalifold_args_info_full_help[47] = RNALalifold_args_info_detailed_help[67];
157   RNALalifold_args_info_full_help[48] = 0;
158 
159 }
160 
161 const char *RNALalifold_args_info_full_help[49];
162 
163 static void
init_help_array(void)164 init_help_array(void)
165 {
166   RNALalifold_args_info_help[0] = RNALalifold_args_info_detailed_help[0];
167   RNALalifold_args_info_help[1] = RNALalifold_args_info_detailed_help[1];
168   RNALalifold_args_info_help[2] = RNALalifold_args_info_detailed_help[2];
169   RNALalifold_args_info_help[3] = RNALalifold_args_info_detailed_help[3];
170   RNALalifold_args_info_help[4] = RNALalifold_args_info_detailed_help[4];
171   RNALalifold_args_info_help[5] = RNALalifold_args_info_detailed_help[5];
172   RNALalifold_args_info_help[6] = RNALalifold_args_info_detailed_help[6];
173   RNALalifold_args_info_help[7] = RNALalifold_args_info_detailed_help[7];
174   RNALalifold_args_info_help[8] = RNALalifold_args_info_detailed_help[9];
175   RNALalifold_args_info_help[9] = RNALalifold_args_info_detailed_help[10];
176   RNALalifold_args_info_help[10] = RNALalifold_args_info_detailed_help[12];
177   RNALalifold_args_info_help[11] = RNALalifold_args_info_detailed_help[13];
178   RNALalifold_args_info_help[12] = RNALalifold_args_info_detailed_help[15];
179   RNALalifold_args_info_help[13] = RNALalifold_args_info_detailed_help[19];
180   RNALalifold_args_info_help[14] = RNALalifold_args_info_detailed_help[21];
181   RNALalifold_args_info_help[15] = RNALalifold_args_info_detailed_help[23];
182   RNALalifold_args_info_help[16] = RNALalifold_args_info_detailed_help[25];
183   RNALalifold_args_info_help[17] = RNALalifold_args_info_detailed_help[35];
184   RNALalifold_args_info_help[18] = RNALalifold_args_info_detailed_help[37];
185   RNALalifold_args_info_help[19] = RNALalifold_args_info_detailed_help[38];
186   RNALalifold_args_info_help[20] = RNALalifold_args_info_detailed_help[39];
187   RNALalifold_args_info_help[21] = RNALalifold_args_info_detailed_help[41];
188   RNALalifold_args_info_help[22] = RNALalifold_args_info_detailed_help[43];
189   RNALalifold_args_info_help[23] = RNALalifold_args_info_detailed_help[44];
190   RNALalifold_args_info_help[24] = RNALalifold_args_info_detailed_help[45];
191   RNALalifold_args_info_help[25] = RNALalifold_args_info_detailed_help[46];
192   RNALalifold_args_info_help[26] = RNALalifold_args_info_detailed_help[47];
193   RNALalifold_args_info_help[27] = RNALalifold_args_info_detailed_help[48];
194   RNALalifold_args_info_help[28] = RNALalifold_args_info_detailed_help[49];
195   RNALalifold_args_info_help[29] = RNALalifold_args_info_detailed_help[50];
196   RNALalifold_args_info_help[30] = RNALalifold_args_info_detailed_help[51];
197   RNALalifold_args_info_help[31] = RNALalifold_args_info_detailed_help[52];
198   RNALalifold_args_info_help[32] = RNALalifold_args_info_detailed_help[54];
199   RNALalifold_args_info_help[33] = RNALalifold_args_info_detailed_help[56];
200   RNALalifold_args_info_help[34] = RNALalifold_args_info_detailed_help[57];
201   RNALalifold_args_info_help[35] = RNALalifold_args_info_detailed_help[58];
202   RNALalifold_args_info_help[36] = RNALalifold_args_info_detailed_help[63];
203   RNALalifold_args_info_help[37] = RNALalifold_args_info_detailed_help[64];
204   RNALalifold_args_info_help[38] = RNALalifold_args_info_detailed_help[65];
205   RNALalifold_args_info_help[39] = RNALalifold_args_info_detailed_help[66];
206   RNALalifold_args_info_help[40] = RNALalifold_args_info_detailed_help[67];
207   RNALalifold_args_info_help[41] = 0;
208 
209 }
210 
211 const char *RNALalifold_args_info_help[42];
212 
213 typedef enum {ARG_NO
214   , ARG_FLAG
215   , ARG_STRING
216   , ARG_INT
217   , ARG_LONG
218   , ARG_DOUBLE
219 } RNALalifold_cmdline_parser_arg_type;
220 
221 static
222 void clear_given (struct RNALalifold_args_info *args_info);
223 static
224 void clear_args (struct RNALalifold_args_info *args_info);
225 
226 static int
227 RNALalifold_cmdline_parser_internal (int argc, char **argv, struct RNALalifold_args_info *args_info,
228                         struct RNALalifold_cmdline_parser_params *params, const char *additional_error);
229 
230 static int
231 RNALalifold_cmdline_parser_required2 (struct RNALalifold_args_info *args_info, const char *prog_name, const char *additional_error);
232 
233 static char *
234 gengetopt_strdup (const char *s);
235 
236 static
clear_given(struct RNALalifold_args_info * args_info)237 void clear_given (struct RNALalifold_args_info *args_info)
238 {
239   args_info->help_given = 0 ;
240   args_info->detailed_help_given = 0 ;
241   args_info->full_help_given = 0 ;
242   args_info->version_given = 0 ;
243   args_info->verbose_given = 0 ;
244   args_info->quiet_given = 0 ;
245   args_info->noconv_given = 0 ;
246   args_info->input_format_given = 0 ;
247   args_info->csv_given = 0 ;
248   args_info->aln_given = 0 ;
249   args_info->aln_EPS_given = 0 ;
250   args_info->aln_EPS_cols_given = 0 ;
251   args_info->aln_EPS_ss_given = 0 ;
252   args_info->aln_stk_given = 0 ;
253   args_info->auto_id_given = 0 ;
254   args_info->id_prefix_given = 0 ;
255   args_info->id_delim_given = 0 ;
256   args_info->id_digits_given = 0 ;
257   args_info->id_start_given = 0 ;
258   args_info->filename_delim_given = 0 ;
259   args_info->split_contributions_given = 0 ;
260   args_info->shape_given = 0 ;
261   args_info->shapeMethod_given = 0 ;
262   args_info->maxBPspan_given = 0 ;
263   args_info->threshold_given = 0 ;
264   args_info->mis_given = 0 ;
265   args_info->gquad_given = 0 ;
266   args_info->temp_given = 0 ;
267   args_info->noTetra_given = 0 ;
268   args_info->dangles_given = 0 ;
269   args_info->noLP_given = 0 ;
270   args_info->noGU_given = 0 ;
271   args_info->noClosingGU_given = 0 ;
272   args_info->paramFile_given = 0 ;
273   args_info->nsp_given = 0 ;
274   args_info->energyModel_given = 0 ;
275   args_info->cfactor_given = 0 ;
276   args_info->nfactor_given = 0 ;
277   args_info->ribosum_file_given = 0 ;
278   args_info->ribosum_scoring_given = 0 ;
279 }
280 
281 static
clear_args(struct RNALalifold_args_info * args_info)282 void clear_args (struct RNALalifold_args_info *args_info)
283 {
284   FIX_UNUSED (args_info);
285   args_info->verbose_flag = 0;
286   args_info->quiet_flag = 0;
287   args_info->noconv_flag = 0;
288   args_info->input_format_arg = NULL;
289   args_info->input_format_orig = NULL;
290   args_info->csv_flag = 0;
291   args_info->aln_arg = NULL;
292   args_info->aln_orig = NULL;
293   args_info->aln_EPS_arg = NULL;
294   args_info->aln_EPS_orig = NULL;
295   args_info->aln_EPS_cols_arg = 60;
296   args_info->aln_EPS_cols_orig = NULL;
297   args_info->aln_EPS_ss_arg = NULL;
298   args_info->aln_EPS_ss_orig = NULL;
299   args_info->aln_stk_arg = gengetopt_strdup ("RNALalifold_results");
300   args_info->aln_stk_orig = NULL;
301   args_info->auto_id_flag = 0;
302   args_info->id_prefix_arg = gengetopt_strdup ("alignment");
303   args_info->id_prefix_orig = NULL;
304   args_info->id_delim_arg = gengetopt_strdup ("_");
305   args_info->id_delim_orig = NULL;
306   args_info->id_digits_arg = 4;
307   args_info->id_digits_orig = NULL;
308   args_info->id_start_arg = 1;
309   args_info->id_start_orig = NULL;
310   args_info->filename_delim_arg = gengetopt_strdup ("ID-delimiter");
311   args_info->filename_delim_orig = NULL;
312   args_info->split_contributions_flag = 0;
313   args_info->shape_arg = NULL;
314   args_info->shape_orig = NULL;
315   args_info->shapeMethod_arg = gengetopt_strdup ("D");
316   args_info->shapeMethod_orig = NULL;
317   args_info->maxBPspan_arg = 70;
318   args_info->maxBPspan_orig = NULL;
319   args_info->threshold_arg = -0.1;
320   args_info->threshold_orig = NULL;
321   args_info->mis_flag = 0;
322   args_info->gquad_flag = 0;
323   args_info->temp_orig = NULL;
324   args_info->noTetra_flag = 0;
325   args_info->dangles_arg = 2;
326   args_info->dangles_orig = NULL;
327   args_info->noLP_flag = 0;
328   args_info->noGU_flag = 0;
329   args_info->noClosingGU_flag = 0;
330   args_info->paramFile_arg = NULL;
331   args_info->paramFile_orig = NULL;
332   args_info->nsp_arg = NULL;
333   args_info->nsp_orig = NULL;
334   args_info->energyModel_orig = NULL;
335   args_info->cfactor_arg = 1.0;
336   args_info->cfactor_orig = NULL;
337   args_info->nfactor_arg = 1.0;
338   args_info->nfactor_orig = NULL;
339   args_info->ribosum_file_arg = NULL;
340   args_info->ribosum_file_orig = NULL;
341   args_info->ribosum_scoring_flag = 0;
342 
343 }
344 
345 static
init_args_info(struct RNALalifold_args_info * args_info)346 void init_args_info(struct RNALalifold_args_info *args_info)
347 {
348   init_full_help_array();
349   init_help_array();
350   args_info->help_help = RNALalifold_args_info_detailed_help[0] ;
351   args_info->detailed_help_help = RNALalifold_args_info_detailed_help[1] ;
352   args_info->full_help_help = RNALalifold_args_info_detailed_help[2] ;
353   args_info->version_help = RNALalifold_args_info_detailed_help[3] ;
354   args_info->verbose_help = RNALalifold_args_info_detailed_help[6] ;
355   args_info->quiet_help = RNALalifold_args_info_detailed_help[7] ;
356   args_info->noconv_help = RNALalifold_args_info_detailed_help[9] ;
357   args_info->input_format_help = RNALalifold_args_info_detailed_help[10] ;
358   args_info->csv_help = RNALalifold_args_info_detailed_help[12] ;
359   args_info->aln_help = RNALalifold_args_info_detailed_help[13] ;
360   args_info->aln_EPS_help = RNALalifold_args_info_detailed_help[15] ;
361   args_info->aln_EPS_cols_help = RNALalifold_args_info_detailed_help[17] ;
362   args_info->aln_EPS_ss_help = RNALalifold_args_info_detailed_help[19] ;
363   args_info->aln_stk_help = RNALalifold_args_info_detailed_help[21] ;
364   args_info->auto_id_help = RNALalifold_args_info_detailed_help[23] ;
365   args_info->id_prefix_help = RNALalifold_args_info_detailed_help[25] ;
366   args_info->id_delim_help = RNALalifold_args_info_detailed_help[27] ;
367   args_info->id_digits_help = RNALalifold_args_info_detailed_help[29] ;
368   args_info->id_start_help = RNALalifold_args_info_detailed_help[31] ;
369   args_info->filename_delim_help = RNALalifold_args_info_detailed_help[33] ;
370   args_info->split_contributions_help = RNALalifold_args_info_detailed_help[35] ;
371   args_info->shape_help = RNALalifold_args_info_detailed_help[39] ;
372   args_info->shape_min = 1;
373   args_info->shape_max = 0;
374   args_info->shapeMethod_help = RNALalifold_args_info_detailed_help[41] ;
375   args_info->maxBPspan_help = RNALalifold_args_info_detailed_help[45] ;
376   args_info->threshold_help = RNALalifold_args_info_detailed_help[46] ;
377   args_info->mis_help = RNALalifold_args_info_detailed_help[47] ;
378   args_info->gquad_help = RNALalifold_args_info_detailed_help[48] ;
379   args_info->temp_help = RNALalifold_args_info_detailed_help[50] ;
380   args_info->noTetra_help = RNALalifold_args_info_detailed_help[51] ;
381   args_info->dangles_help = RNALalifold_args_info_detailed_help[52] ;
382   args_info->noLP_help = RNALalifold_args_info_detailed_help[54] ;
383   args_info->noGU_help = RNALalifold_args_info_detailed_help[56] ;
384   args_info->noClosingGU_help = RNALalifold_args_info_detailed_help[57] ;
385   args_info->paramFile_help = RNALalifold_args_info_detailed_help[58] ;
386   args_info->nsp_help = RNALalifold_args_info_detailed_help[60] ;
387   args_info->energyModel_help = RNALalifold_args_info_detailed_help[62] ;
388   args_info->cfactor_help = RNALalifold_args_info_detailed_help[63] ;
389   args_info->nfactor_help = RNALalifold_args_info_detailed_help[64] ;
390   args_info->ribosum_file_help = RNALalifold_args_info_detailed_help[65] ;
391   args_info->ribosum_scoring_help = RNALalifold_args_info_detailed_help[66] ;
392 
393 }
394 
395 void
RNALalifold_cmdline_parser_print_version(void)396 RNALalifold_cmdline_parser_print_version (void)
397 {
398   printf ("%s %s\n",
399      (strlen(RNALALIFOLD_CMDLINE_PARSER_PACKAGE_NAME) ? RNALALIFOLD_CMDLINE_PARSER_PACKAGE_NAME : RNALALIFOLD_CMDLINE_PARSER_PACKAGE),
400      RNALALIFOLD_CMDLINE_PARSER_VERSION);
401 
402   if (strlen(RNALalifold_args_info_versiontext) > 0)
403     printf("\n%s\n", RNALalifold_args_info_versiontext);
404 }
405 
print_help_common(void)406 static void print_help_common(void)
407 {
408 	size_t len_purpose = strlen(RNALalifold_args_info_purpose);
409 	size_t len_usage = strlen(RNALalifold_args_info_usage);
410 
411 	if (len_usage > 0) {
412 		printf("%s\n", RNALalifold_args_info_usage);
413 	}
414 	if (len_purpose > 0) {
415 		printf("%s\n", RNALalifold_args_info_purpose);
416 	}
417 
418 	if (len_usage || len_purpose) {
419 		printf("\n");
420 	}
421 
422 	if (strlen(RNALalifold_args_info_description) > 0) {
423 		printf("%s\n\n", RNALalifold_args_info_description);
424 	}
425 }
426 
427 void
RNALalifold_cmdline_parser_print_help(void)428 RNALalifold_cmdline_parser_print_help (void)
429 {
430   int i = 0;
431   print_help_common();
432   while (RNALalifold_args_info_help[i])
433     printf("%s\n", RNALalifold_args_info_help[i++]);
434 }
435 
436 void
RNALalifold_cmdline_parser_print_full_help(void)437 RNALalifold_cmdline_parser_print_full_help (void)
438 {
439   int i = 0;
440   print_help_common();
441   while (RNALalifold_args_info_full_help[i])
442     printf("%s\n", RNALalifold_args_info_full_help[i++]);
443 }
444 
445 void
RNALalifold_cmdline_parser_print_detailed_help(void)446 RNALalifold_cmdline_parser_print_detailed_help (void)
447 {
448   int i = 0;
449   print_help_common();
450   while (RNALalifold_args_info_detailed_help[i])
451     printf("%s\n", RNALalifold_args_info_detailed_help[i++]);
452 }
453 
454 void
RNALalifold_cmdline_parser_init(struct RNALalifold_args_info * args_info)455 RNALalifold_cmdline_parser_init (struct RNALalifold_args_info *args_info)
456 {
457   clear_given (args_info);
458   clear_args (args_info);
459   init_args_info (args_info);
460 
461   args_info->inputs = 0;
462   args_info->inputs_num = 0;
463 }
464 
465 void
RNALalifold_cmdline_parser_params_init(struct RNALalifold_cmdline_parser_params * params)466 RNALalifold_cmdline_parser_params_init(struct RNALalifold_cmdline_parser_params *params)
467 {
468   if (params)
469     {
470       params->override = 0;
471       params->initialize = 1;
472       params->check_required = 1;
473       params->check_ambiguity = 0;
474       params->print_errors = 1;
475     }
476 }
477 
478 struct RNALalifold_cmdline_parser_params *
RNALalifold_cmdline_parser_params_create(void)479 RNALalifold_cmdline_parser_params_create(void)
480 {
481   struct RNALalifold_cmdline_parser_params *params =
482     (struct RNALalifold_cmdline_parser_params *)malloc(sizeof(struct RNALalifold_cmdline_parser_params));
483   RNALalifold_cmdline_parser_params_init(params);
484   return params;
485 }
486 
487 static void
free_string_field(char ** s)488 free_string_field (char **s)
489 {
490   if (*s)
491     {
492       free (*s);
493       *s = 0;
494     }
495 }
496 
497 /** @brief generic value variable */
498 union generic_value {
499     int int_arg;
500     long long_arg;
501     double double_arg;
502     char *string_arg;
503     const char *default_string_arg;
504 };
505 
506 /** @brief holds temporary values for multiple options */
507 struct generic_list
508 {
509   union generic_value arg;
510   char *orig;
511   struct generic_list *next;
512 };
513 
514 /**
515  * @brief add a node at the head of the list
516  */
add_node(struct generic_list ** list)517 static void add_node(struct generic_list **list) {
518   struct generic_list *new_node = (struct generic_list *) malloc (sizeof (struct generic_list));
519   new_node->next = *list;
520   *list = new_node;
521   new_node->arg.string_arg = 0;
522   new_node->orig = 0;
523 }
524 
525 
526 static void
free_multiple_string_field(unsigned int len,char *** arg,char *** orig)527 free_multiple_string_field(unsigned int len, char ***arg, char ***orig)
528 {
529   unsigned int i;
530   if (*arg) {
531     for (i = 0; i < len; ++i)
532       {
533         free_string_field(&((*arg)[i]));
534         free_string_field(&((*orig)[i]));
535       }
536     free_string_field(&((*arg)[0])); /* free default string */
537 
538     free (*arg);
539     *arg = 0;
540     free (*orig);
541     *orig = 0;
542   }
543 }
544 
545 static void
RNALalifold_cmdline_parser_release(struct RNALalifold_args_info * args_info)546 RNALalifold_cmdline_parser_release (struct RNALalifold_args_info *args_info)
547 {
548   unsigned int i;
549   free_string_field (&(args_info->input_format_arg));
550   free_string_field (&(args_info->input_format_orig));
551   free_string_field (&(args_info->aln_arg));
552   free_string_field (&(args_info->aln_orig));
553   free_string_field (&(args_info->aln_EPS_arg));
554   free_string_field (&(args_info->aln_EPS_orig));
555   free_string_field (&(args_info->aln_EPS_cols_orig));
556   free_string_field (&(args_info->aln_EPS_ss_arg));
557   free_string_field (&(args_info->aln_EPS_ss_orig));
558   free_string_field (&(args_info->aln_stk_arg));
559   free_string_field (&(args_info->aln_stk_orig));
560   free_string_field (&(args_info->id_prefix_arg));
561   free_string_field (&(args_info->id_prefix_orig));
562   free_string_field (&(args_info->id_delim_arg));
563   free_string_field (&(args_info->id_delim_orig));
564   free_string_field (&(args_info->id_digits_orig));
565   free_string_field (&(args_info->id_start_orig));
566   free_string_field (&(args_info->filename_delim_arg));
567   free_string_field (&(args_info->filename_delim_orig));
568   free_multiple_string_field (args_info->shape_given, &(args_info->shape_arg), &(args_info->shape_orig));
569   free_string_field (&(args_info->shapeMethod_arg));
570   free_string_field (&(args_info->shapeMethod_orig));
571   free_string_field (&(args_info->maxBPspan_orig));
572   free_string_field (&(args_info->threshold_orig));
573   free_string_field (&(args_info->temp_orig));
574   free_string_field (&(args_info->dangles_orig));
575   free_string_field (&(args_info->paramFile_arg));
576   free_string_field (&(args_info->paramFile_orig));
577   free_string_field (&(args_info->nsp_arg));
578   free_string_field (&(args_info->nsp_orig));
579   free_string_field (&(args_info->energyModel_orig));
580   free_string_field (&(args_info->cfactor_orig));
581   free_string_field (&(args_info->nfactor_orig));
582   free_string_field (&(args_info->ribosum_file_arg));
583   free_string_field (&(args_info->ribosum_file_orig));
584 
585 
586   for (i = 0; i < args_info->inputs_num; ++i)
587     free (args_info->inputs [i]);
588 
589   if (args_info->inputs_num)
590     free (args_info->inputs);
591 
592   clear_given (args_info);
593 }
594 
595 
596 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])597 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
598 {
599   FIX_UNUSED (values);
600   if (arg) {
601     fprintf(outfile, "%s=\"%s\"\n", opt, arg);
602   } else {
603     fprintf(outfile, "%s\n", opt);
604   }
605 }
606 
607 static void
write_multiple_into_file(FILE * outfile,int len,const char * opt,char ** arg,const char * values[])608 write_multiple_into_file(FILE *outfile, int len, const char *opt, char **arg, const char *values[])
609 {
610   int i;
611 
612   for (i = 0; i < len; ++i)
613     write_into_file(outfile, opt, (arg ? arg[i] : 0), values);
614 }
615 
616 int
RNALalifold_cmdline_parser_dump(FILE * outfile,struct RNALalifold_args_info * args_info)617 RNALalifold_cmdline_parser_dump(FILE *outfile, struct RNALalifold_args_info *args_info)
618 {
619   int i = 0;
620 
621   if (!outfile)
622     {
623       fprintf (stderr, "%s: cannot dump options to stream\n", RNALALIFOLD_CMDLINE_PARSER_PACKAGE);
624       return EXIT_FAILURE;
625     }
626 
627   if (args_info->help_given)
628     write_into_file(outfile, "help", 0, 0 );
629   if (args_info->detailed_help_given)
630     write_into_file(outfile, "detailed-help", 0, 0 );
631   if (args_info->full_help_given)
632     write_into_file(outfile, "full-help", 0, 0 );
633   if (args_info->version_given)
634     write_into_file(outfile, "version", 0, 0 );
635   if (args_info->verbose_given)
636     write_into_file(outfile, "verbose", 0, 0 );
637   if (args_info->quiet_given)
638     write_into_file(outfile, "quiet", 0, 0 );
639   if (args_info->noconv_given)
640     write_into_file(outfile, "noconv", 0, 0 );
641   if (args_info->input_format_given)
642     write_into_file(outfile, "input-format", args_info->input_format_orig, 0);
643   if (args_info->csv_given)
644     write_into_file(outfile, "csv", 0, 0 );
645   if (args_info->aln_given)
646     write_into_file(outfile, "aln", args_info->aln_orig, 0);
647   if (args_info->aln_EPS_given)
648     write_into_file(outfile, "aln-EPS", args_info->aln_EPS_orig, 0);
649   if (args_info->aln_EPS_cols_given)
650     write_into_file(outfile, "aln-EPS-cols", args_info->aln_EPS_cols_orig, 0);
651   if (args_info->aln_EPS_ss_given)
652     write_into_file(outfile, "aln-EPS-ss", args_info->aln_EPS_ss_orig, 0);
653   if (args_info->aln_stk_given)
654     write_into_file(outfile, "aln-stk", args_info->aln_stk_orig, 0);
655   if (args_info->auto_id_given)
656     write_into_file(outfile, "auto-id", 0, 0 );
657   if (args_info->id_prefix_given)
658     write_into_file(outfile, "id-prefix", args_info->id_prefix_orig, 0);
659   if (args_info->id_delim_given)
660     write_into_file(outfile, "id-delim", args_info->id_delim_orig, 0);
661   if (args_info->id_digits_given)
662     write_into_file(outfile, "id-digits", args_info->id_digits_orig, 0);
663   if (args_info->id_start_given)
664     write_into_file(outfile, "id-start", args_info->id_start_orig, 0);
665   if (args_info->filename_delim_given)
666     write_into_file(outfile, "filename-delim", args_info->filename_delim_orig, 0);
667   if (args_info->split_contributions_given)
668     write_into_file(outfile, "split-contributions", 0, 0 );
669   write_multiple_into_file(outfile, args_info->shape_given, "shape", args_info->shape_orig, 0);
670   if (args_info->shapeMethod_given)
671     write_into_file(outfile, "shapeMethod", args_info->shapeMethod_orig, 0);
672   if (args_info->maxBPspan_given)
673     write_into_file(outfile, "maxBPspan", args_info->maxBPspan_orig, 0);
674   if (args_info->threshold_given)
675     write_into_file(outfile, "threshold", args_info->threshold_orig, 0);
676   if (args_info->mis_given)
677     write_into_file(outfile, "mis", 0, 0 );
678   if (args_info->gquad_given)
679     write_into_file(outfile, "gquad", 0, 0 );
680   if (args_info->temp_given)
681     write_into_file(outfile, "temp", args_info->temp_orig, 0);
682   if (args_info->noTetra_given)
683     write_into_file(outfile, "noTetra", 0, 0 );
684   if (args_info->dangles_given)
685     write_into_file(outfile, "dangles", args_info->dangles_orig, 0);
686   if (args_info->noLP_given)
687     write_into_file(outfile, "noLP", 0, 0 );
688   if (args_info->noGU_given)
689     write_into_file(outfile, "noGU", 0, 0 );
690   if (args_info->noClosingGU_given)
691     write_into_file(outfile, "noClosingGU", 0, 0 );
692   if (args_info->paramFile_given)
693     write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
694   if (args_info->nsp_given)
695     write_into_file(outfile, "nsp", args_info->nsp_orig, 0);
696   if (args_info->energyModel_given)
697     write_into_file(outfile, "energyModel", args_info->energyModel_orig, 0);
698   if (args_info->cfactor_given)
699     write_into_file(outfile, "cfactor", args_info->cfactor_orig, 0);
700   if (args_info->nfactor_given)
701     write_into_file(outfile, "nfactor", args_info->nfactor_orig, 0);
702   if (args_info->ribosum_file_given)
703     write_into_file(outfile, "ribosum_file", args_info->ribosum_file_orig, 0);
704   if (args_info->ribosum_scoring_given)
705     write_into_file(outfile, "ribosum_scoring", 0, 0 );
706 
707 
708   i = EXIT_SUCCESS;
709   return i;
710 }
711 
712 int
RNALalifold_cmdline_parser_file_save(const char * filename,struct RNALalifold_args_info * args_info)713 RNALalifold_cmdline_parser_file_save(const char *filename, struct RNALalifold_args_info *args_info)
714 {
715   FILE *outfile;
716   int i = 0;
717 
718   outfile = fopen(filename, "w");
719 
720   if (!outfile)
721     {
722       fprintf (stderr, "%s: cannot open file for writing: %s\n", RNALALIFOLD_CMDLINE_PARSER_PACKAGE, filename);
723       return EXIT_FAILURE;
724     }
725 
726   i = RNALalifold_cmdline_parser_dump(outfile, args_info);
727   fclose (outfile);
728 
729   return i;
730 }
731 
732 void
RNALalifold_cmdline_parser_free(struct RNALalifold_args_info * args_info)733 RNALalifold_cmdline_parser_free (struct RNALalifold_args_info *args_info)
734 {
735   RNALalifold_cmdline_parser_release (args_info);
736 }
737 
738 /** @brief replacement of strdup, which is not standard */
739 char *
gengetopt_strdup(const char * s)740 gengetopt_strdup (const char *s)
741 {
742   char *result = 0;
743   if (!s)
744     return result;
745 
746   result = (char*)malloc(strlen(s) + 1);
747   if (result == (char*)0)
748     return (char*)0;
749   strcpy(result, s);
750   return result;
751 }
752 
753 static char *
get_multiple_arg_token(const char * arg)754 get_multiple_arg_token(const char *arg)
755 {
756   const char *tok;
757   char *ret;
758   size_t len, num_of_escape, i, j;
759 
760   if (!arg)
761     return 0;
762 
763   tok = strchr (arg, ',');
764   num_of_escape = 0;
765 
766   /* make sure it is not escaped */
767   while (tok)
768     {
769       if (*(tok-1) == '\\')
770         {
771           /* find the next one */
772           tok = strchr (tok+1, ',');
773           ++num_of_escape;
774         }
775       else
776         break;
777     }
778 
779   if (tok)
780     len = (size_t)(tok - arg + 1);
781   else
782     len = strlen (arg) + 1;
783 
784   len -= num_of_escape;
785 
786   ret = (char *) malloc (len);
787 
788   i = 0;
789   j = 0;
790   while (arg[i] && (j < len-1))
791     {
792       if (arg[i] == '\\' &&
793 	  arg[ i + 1 ] &&
794 	  arg[ i + 1 ] == ',')
795         ++i;
796 
797       ret[j++] = arg[i++];
798     }
799 
800   ret[len-1] = '\0';
801 
802   return ret;
803 }
804 
805 static const char *
get_multiple_arg_token_next(const char * arg)806 get_multiple_arg_token_next(const char *arg)
807 {
808   const char *tok;
809 
810   if (!arg)
811     return 0;
812 
813   tok = strchr (arg, ',');
814 
815   /* make sure it is not escaped */
816   while (tok)
817     {
818       if (*(tok-1) == '\\')
819         {
820           /* find the next one */
821           tok = strchr (tok+1, ',');
822         }
823       else
824         break;
825     }
826 
827   if (! tok || strlen(tok) == 1)
828     return 0;
829 
830   return tok+1;
831 }
832 
833 static int
834 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc);
835 
836 int
check_multiple_option_occurrences(const char * prog_name,unsigned int option_given,unsigned int min,unsigned int max,const char * option_desc)837 check_multiple_option_occurrences(const char *prog_name, unsigned int option_given, unsigned int min, unsigned int max, const char *option_desc)
838 {
839   int error_occurred = 0;
840 
841   if (option_given && (min > 0 || max > 0))
842     {
843       if (min > 0 && max > 0)
844         {
845           if (min == max)
846             {
847               /* specific occurrences */
848               if (option_given != (unsigned int) min)
849                 {
850                   fprintf (stderr, "%s: %s option occurrences must be %d\n",
851                     prog_name, option_desc, min);
852                   error_occurred = 1;
853                 }
854             }
855           else if (option_given < (unsigned int) min
856                 || option_given > (unsigned int) max)
857             {
858               /* range occurrences */
859               fprintf (stderr, "%s: %s option occurrences must be between %d and %d\n",
860                 prog_name, option_desc, min, max);
861               error_occurred = 1;
862             }
863         }
864       else if (min > 0)
865         {
866           /* at least check */
867           if (option_given < min)
868             {
869               fprintf (stderr, "%s: %s option occurrences must be at least %d\n",
870                 prog_name, option_desc, min);
871               error_occurred = 1;
872             }
873         }
874       else if (max > 0)
875         {
876           /* at most check */
877           if (option_given > max)
878             {
879               fprintf (stderr, "%s: %s option occurrences must be at most %d\n",
880                 prog_name, option_desc, max);
881               error_occurred = 1;
882             }
883         }
884     }
885 
886   return error_occurred;
887 }
888 int
RNALalifold_cmdline_parser(int argc,char ** argv,struct RNALalifold_args_info * args_info)889 RNALalifold_cmdline_parser (int argc, char **argv, struct RNALalifold_args_info *args_info)
890 {
891   return RNALalifold_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
892 }
893 
894 int
RNALalifold_cmdline_parser_ext(int argc,char ** argv,struct RNALalifold_args_info * args_info,struct RNALalifold_cmdline_parser_params * params)895 RNALalifold_cmdline_parser_ext (int argc, char **argv, struct RNALalifold_args_info *args_info,
896                    struct RNALalifold_cmdline_parser_params *params)
897 {
898   int result;
899   result = RNALalifold_cmdline_parser_internal (argc, argv, args_info, params, 0);
900 
901   if (result == EXIT_FAILURE)
902     {
903       RNALalifold_cmdline_parser_free (args_info);
904       exit (EXIT_FAILURE);
905     }
906 
907   return result;
908 }
909 
910 int
RNALalifold_cmdline_parser2(int argc,char ** argv,struct RNALalifold_args_info * args_info,int override,int initialize,int check_required)911 RNALalifold_cmdline_parser2 (int argc, char **argv, struct RNALalifold_args_info *args_info, int override, int initialize, int check_required)
912 {
913   int result;
914   struct RNALalifold_cmdline_parser_params params;
915 
916   params.override = override;
917   params.initialize = initialize;
918   params.check_required = check_required;
919   params.check_ambiguity = 0;
920   params.print_errors = 1;
921 
922   result = RNALalifold_cmdline_parser_internal (argc, argv, args_info, &params, 0);
923 
924   if (result == EXIT_FAILURE)
925     {
926       RNALalifold_cmdline_parser_free (args_info);
927       exit (EXIT_FAILURE);
928     }
929 
930   return result;
931 }
932 
933 int
RNALalifold_cmdline_parser_required(struct RNALalifold_args_info * args_info,const char * prog_name)934 RNALalifold_cmdline_parser_required (struct RNALalifold_args_info *args_info, const char *prog_name)
935 {
936   int result = EXIT_SUCCESS;
937 
938   if (RNALalifold_cmdline_parser_required2(args_info, prog_name, 0) > 0)
939     result = EXIT_FAILURE;
940 
941   if (result == EXIT_FAILURE)
942     {
943       RNALalifold_cmdline_parser_free (args_info);
944       exit (EXIT_FAILURE);
945     }
946 
947   return result;
948 }
949 
950 int
RNALalifold_cmdline_parser_required2(struct RNALalifold_args_info * args_info,const char * prog_name,const char * additional_error)951 RNALalifold_cmdline_parser_required2 (struct RNALalifold_args_info *args_info, const char *prog_name, const char *additional_error)
952 {
953   int error_occurred = 0;
954   FIX_UNUSED (additional_error);
955 
956   /* checks for required options */
957   if (check_multiple_option_occurrences(prog_name, args_info->shape_given, args_info->shape_min, args_info->shape_max, "'--shape'"))
958      error_occurred = 1;
959 
960 
961   /* checks for dependences among options */
962   if (args_info->shapeMethod_given && ! args_info->shape_given)
963     {
964       fprintf (stderr, "%s: '--shapeMethod' option depends on option 'shape'%s\n", prog_name, (additional_error ? additional_error : ""));
965       error_occurred = 1;
966     }
967 
968   return error_occurred;
969 }
970 
971 /*
972  * Extracted from the glibc source tree, version 2.3.6
973  *
974  * Licensed under the GPL as per the whole glibc source tree.
975  *
976  * This file was modified so that getopt_long can be called
977  * many times without risking previous memory to be spoiled.
978  *
979  * Modified by Andre Noll and Lorenzo Bettini for use in
980  * GNU gengetopt generated files.
981  *
982  */
983 
984 /*
985  * we must include anything we need since this file is not thought to be
986  * inserted in a file already using getopt.h
987  *
988  * Lorenzo
989  */
990 
991 struct option
992 {
993   const char *name;
994   /* has_arg can't be an enum because some compilers complain about
995      type mismatches in all the code that assumes it is an int.  */
996   int has_arg;
997   int *flag;
998   int val;
999 };
1000 
1001 /* This version of `getopt' appears to the caller like standard Unix `getopt'
1002    but it behaves differently for the user, since it allows the user
1003    to intersperse the options with the other arguments.
1004 
1005    As `getopt' works, it permutes the elements of ARGV so that,
1006    when it is done, all the options precede everything else.  Thus
1007    all application programs are extended to handle flexible argument order.
1008 */
1009 /*
1010    If the field `flag' is not NULL, it points to a variable that is set
1011    to the value given in the field `val' when the option is found, but
1012    left unchanged if the option is not found.
1013 
1014    To have a long-named option do something other than set an `int' to
1015    a compiled-in constant, such as set a value from `custom_optarg', set the
1016    option's `flag' field to zero and its `val' field to a nonzero
1017    value (the equivalent single-letter option character, if there is
1018    one).  For long options that have a zero `flag' field, `getopt'
1019    returns the contents of the `val' field.  */
1020 
1021 /* Names for the values of the `has_arg' field of `struct option'.  */
1022 #ifndef no_argument
1023 #define no_argument		0
1024 #endif
1025 
1026 #ifndef required_argument
1027 #define required_argument	1
1028 #endif
1029 
1030 #ifndef optional_argument
1031 #define optional_argument	2
1032 #endif
1033 
1034 struct custom_getopt_data {
1035 	/*
1036 	 * These have exactly the same meaning as the corresponding global variables,
1037 	 * except that they are used for the reentrant versions of getopt.
1038 	 */
1039 	int custom_optind;
1040 	int custom_opterr;
1041 	int custom_optopt;
1042 	char *custom_optarg;
1043 
1044 	/* True if the internal members have been initialized.  */
1045 	int initialized;
1046 
1047 	/*
1048 	 * The next char to be scanned in the option-element in which the last option
1049 	 * character we returned was found.  This allows us to pick up the scan where
1050 	 * we left off.  If this is zero, or a null string, it means resume the scan by
1051 	 * advancing to the next ARGV-element.
1052 	 */
1053 	char *nextchar;
1054 
1055 	/*
1056 	 * Describe the part of ARGV that contains non-options that have been skipped.
1057 	 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
1058 	 * the index after the last of them.
1059 	 */
1060 	int first_nonopt;
1061 	int last_nonopt;
1062 };
1063 
1064 /*
1065  * the variables optarg, optind, opterr and optopt are renamed with
1066  * the custom_ prefix so that they don't interfere with getopt ones.
1067  *
1068  * Moreover they're static so they are visible only from within the
1069  * file where this very file will be included.
1070  */
1071 
1072 /*
1073  * For communication from `custom_getopt' to the caller.  When `custom_getopt' finds an
1074  * option that takes an argument, the argument value is returned here.
1075  */
1076 static char *custom_optarg;
1077 
1078 /*
1079  * Index in ARGV of the next element to be scanned.  This is used for
1080  * communication to and from the caller and for communication between
1081  * successive calls to `custom_getopt'.
1082  *
1083  * On entry to `custom_getopt', 1 means this is the first call; initialize.
1084  *
1085  * When `custom_getopt' returns -1, this is the index of the first of the non-option
1086  * elements that the caller should itself scan.
1087  *
1088  * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
1089  * has been scanned so far.
1090  *
1091  * 1003.2 says this must be 1 before any call.
1092  */
1093 static int custom_optind = 1;
1094 
1095 /*
1096  * Callers store zero here to inhibit the error message for unrecognized
1097  * options.
1098  */
1099 static int custom_opterr = 1;
1100 
1101 /*
1102  * Set to an option character which was unrecognized.  This must be initialized
1103  * on some systems to avoid linking in the system's own getopt implementation.
1104  */
1105 static int custom_optopt = '?';
1106 
1107 /*
1108  * Exchange two adjacent subsequences of ARGV.  One subsequence is elements
1109  * [first_nonopt,last_nonopt) which contains all the non-options that have been
1110  * skipped so far.  The other is elements [last_nonopt,custom_optind), which contains
1111  * all the options processed since those non-options were skipped.
1112  * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
1113  * indices of the non-options in ARGV after they are moved.
1114  */
exchange(char ** argv,struct custom_getopt_data * d)1115 static void exchange(char **argv, struct custom_getopt_data *d)
1116 {
1117 	int bottom = d->first_nonopt;
1118 	int middle = d->last_nonopt;
1119 	int top = d->custom_optind;
1120 	char *tem;
1121 
1122 	/*
1123 	 * Exchange the shorter segment with the far end of the longer segment.
1124 	 * That puts the shorter segment into the right place.  It leaves the
1125 	 * longer segment in the right place overall, but it consists of two
1126 	 * parts that need to be swapped next.
1127 	 */
1128 	while (top > middle && middle > bottom) {
1129 		if (top - middle > middle - bottom) {
1130 			/* Bottom segment is the short one.  */
1131 			int len = middle - bottom;
1132 			int i;
1133 
1134 			/* Swap it with the top part of the top segment.  */
1135 			for (i = 0; i < len; i++) {
1136 				tem = argv[bottom + i];
1137 				argv[bottom + i] =
1138 					argv[top - (middle - bottom) + i];
1139 				argv[top - (middle - bottom) + i] = tem;
1140 			}
1141 			/* Exclude the moved bottom segment from further swapping.  */
1142 			top -= len;
1143 		} else {
1144 			/* Top segment is the short one.  */
1145 			int len = top - middle;
1146 			int i;
1147 
1148 			/* Swap it with the bottom part of the bottom segment.  */
1149 			for (i = 0; i < len; i++) {
1150 				tem = argv[bottom + i];
1151 				argv[bottom + i] = argv[middle + i];
1152 				argv[middle + i] = tem;
1153 			}
1154 			/* Exclude the moved top segment from further swapping.  */
1155 			bottom += len;
1156 		}
1157 	}
1158 	/* Update records for the slots the non-options now occupy.  */
1159 	d->first_nonopt += (d->custom_optind - d->last_nonopt);
1160 	d->last_nonopt = d->custom_optind;
1161 }
1162 
1163 /* Initialize the internal data when the first call is made.  */
custom_getopt_initialize(struct custom_getopt_data * d)1164 static void custom_getopt_initialize(struct custom_getopt_data *d)
1165 {
1166 	/*
1167 	 * Start processing options with ARGV-element 1 (since ARGV-element 0
1168 	 * is the program name); the sequence of previously skipped non-option
1169 	 * ARGV-elements is empty.
1170 	 */
1171 	d->first_nonopt = d->last_nonopt = d->custom_optind;
1172 	d->nextchar = NULL;
1173 	d->initialized = 1;
1174 }
1175 
1176 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
1177 
1178 /* return: zero: continue, nonzero: return given value to user */
shuffle_argv(int argc,char * const * argv,const struct option * longopts,struct custom_getopt_data * d)1179 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
1180 	struct custom_getopt_data *d)
1181 {
1182 	/*
1183 	 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
1184 	 * moved back by the user (who may also have changed the arguments).
1185 	 */
1186 	if (d->last_nonopt > d->custom_optind)
1187 		d->last_nonopt = d->custom_optind;
1188 	if (d->first_nonopt > d->custom_optind)
1189 		d->first_nonopt = d->custom_optind;
1190 	/*
1191 	 * If we have just processed some options following some
1192 	 * non-options, exchange them so that the options come first.
1193 	 */
1194 	if (d->first_nonopt != d->last_nonopt &&
1195 			d->last_nonopt != d->custom_optind)
1196 		exchange((char **) argv, d);
1197 	else if (d->last_nonopt != d->custom_optind)
1198 		d->first_nonopt = d->custom_optind;
1199 	/*
1200 	 * Skip any additional non-options and extend the range of
1201 	 * non-options previously skipped.
1202 	 */
1203 	while (d->custom_optind < argc && NONOPTION_P)
1204 		d->custom_optind++;
1205 	d->last_nonopt = d->custom_optind;
1206 	/*
1207 	 * The special ARGV-element `--' means premature end of options.  Skip
1208 	 * it like a null option, then exchange with previous non-options as if
1209 	 * it were an option, then skip everything else like a non-option.
1210 	 */
1211 	if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
1212 		d->custom_optind++;
1213 		if (d->first_nonopt != d->last_nonopt
1214 				&& d->last_nonopt != d->custom_optind)
1215 			exchange((char **) argv, d);
1216 		else if (d->first_nonopt == d->last_nonopt)
1217 			d->first_nonopt = d->custom_optind;
1218 		d->last_nonopt = argc;
1219 		d->custom_optind = argc;
1220 	}
1221 	/*
1222 	 * If we have done all the ARGV-elements, stop the scan and back over
1223 	 * any non-options that we skipped and permuted.
1224 	 */
1225 	if (d->custom_optind == argc) {
1226 		/*
1227 		 * Set the next-arg-index to point at the non-options that we
1228 		 * previously skipped, so the caller will digest them.
1229 		 */
1230 		if (d->first_nonopt != d->last_nonopt)
1231 			d->custom_optind = d->first_nonopt;
1232 		return -1;
1233 	}
1234 	/*
1235 	 * If we have come to a non-option and did not permute it, either stop
1236 	 * the scan or describe it to the caller and pass it by.
1237 	 */
1238 	if (NONOPTION_P) {
1239 		d->custom_optarg = argv[d->custom_optind++];
1240 		return 1;
1241 	}
1242 	/*
1243 	 * We have found another option-ARGV-element. Skip the initial
1244 	 * punctuation.
1245 	 */
1246 	d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
1247 	return 0;
1248 }
1249 
1250 /*
1251  * Check whether the ARGV-element is a long option.
1252  *
1253  * If there's a long option "fubar" and the ARGV-element is "-fu", consider
1254  * that an abbreviation of the long option, just like "--fu", and not "-f" with
1255  * arg "u".
1256  *
1257  * This distinction seems to be the most useful approach.
1258  *
1259  */
check_long_opt(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,int print_errors,struct custom_getopt_data * d)1260 static int check_long_opt(int argc, char *const *argv, const char *optstring,
1261 		const struct option *longopts, int *longind,
1262 		int print_errors, struct custom_getopt_data *d)
1263 {
1264 	char *nameend;
1265 	const struct option *p;
1266 	const struct option *pfound = NULL;
1267 	int exact = 0;
1268 	int ambig = 0;
1269 	int indfound = -1;
1270 	int option_index;
1271 
1272 	for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
1273 		/* Do nothing.  */ ;
1274 
1275 	/* Test all long options for either exact match or abbreviated matches */
1276 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
1277 		if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
1278 			if ((unsigned int) (nameend - d->nextchar)
1279 					== (unsigned int) strlen(p->name)) {
1280 				/* Exact match found.  */
1281 				pfound = p;
1282 				indfound = option_index;
1283 				exact = 1;
1284 				break;
1285 			} else if (pfound == NULL) {
1286 				/* First nonexact match found.  */
1287 				pfound = p;
1288 				indfound = option_index;
1289 			} else if (pfound->has_arg != p->has_arg
1290 					|| pfound->flag != p->flag
1291 					|| pfound->val != p->val)
1292 				/* Second or later nonexact match found.  */
1293 				ambig = 1;
1294 		}
1295 	if (ambig && !exact) {
1296 		if (print_errors) {
1297 			fprintf(stderr,
1298 				"%s: option `%s' is ambiguous\n",
1299 				argv[0], argv[d->custom_optind]);
1300 		}
1301 		d->nextchar += strlen(d->nextchar);
1302 		d->custom_optind++;
1303 		d->custom_optopt = 0;
1304 		return '?';
1305 	}
1306 	if (pfound) {
1307 		option_index = indfound;
1308 		d->custom_optind++;
1309 		if (*nameend) {
1310 			if (pfound->has_arg != no_argument)
1311 				d->custom_optarg = nameend + 1;
1312 			else {
1313 				if (print_errors) {
1314 					if (argv[d->custom_optind - 1][1] == '-') {
1315 						/* --option */
1316 						fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
1317 							argv[0], pfound->name);
1318 					} else {
1319 						/* +option or -option */
1320 						fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
1321 							argv[0], argv[d->custom_optind - 1][0], pfound->name);
1322 					}
1323 
1324 				}
1325 				d->nextchar += strlen(d->nextchar);
1326 				d->custom_optopt = pfound->val;
1327 				return '?';
1328 			}
1329 		} else if (pfound->has_arg == required_argument) {
1330 			if (d->custom_optind < argc)
1331 				d->custom_optarg = argv[d->custom_optind++];
1332 			else {
1333 				if (print_errors) {
1334 					fprintf(stderr,
1335 						"%s: option `%s' requires an argument\n",
1336 						argv[0],
1337 						argv[d->custom_optind - 1]);
1338 				}
1339 				d->nextchar += strlen(d->nextchar);
1340 				d->custom_optopt = pfound->val;
1341 				return optstring[0] == ':' ? ':' : '?';
1342 			}
1343 		}
1344 		d->nextchar += strlen(d->nextchar);
1345 		if (longind != NULL)
1346 			*longind = option_index;
1347 		if (pfound->flag) {
1348 			*(pfound->flag) = pfound->val;
1349 			return 0;
1350 		}
1351 		return pfound->val;
1352 	}
1353 	/*
1354 	 * Can't find it as a long option.  If this is not getopt_long_only, or
1355 	 * the option starts with '--' or is not a valid short option, then
1356 	 * it's an error.  Otherwise interpret it as a short option.
1357 	 */
1358 	if (print_errors) {
1359 		if (argv[d->custom_optind][1] == '-') {
1360 			/* --option */
1361 			fprintf(stderr,
1362 				"%s: unrecognized option `--%s'\n",
1363 				argv[0], d->nextchar);
1364 		} else {
1365 			/* +option or -option */
1366 			fprintf(stderr,
1367 				"%s: unrecognized option `%c%s'\n",
1368 				argv[0], argv[d->custom_optind][0],
1369 				d->nextchar);
1370 		}
1371 	}
1372 	d->nextchar = (char *) "";
1373 	d->custom_optind++;
1374 	d->custom_optopt = 0;
1375 	return '?';
1376 }
1377 
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)1378 static int check_short_opt(int argc, char *const *argv, const char *optstring,
1379 		int print_errors, struct custom_getopt_data *d)
1380 {
1381 	char c = *d->nextchar++;
1382 	const char *temp = strchr(optstring, c);
1383 
1384 	/* Increment `custom_optind' when we start to process its last character.  */
1385 	if (*d->nextchar == '\0')
1386 		++d->custom_optind;
1387 	if (!temp || c == ':') {
1388 		if (print_errors)
1389 			fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
1390 
1391 		d->custom_optopt = c;
1392 		return '?';
1393 	}
1394 	if (temp[1] == ':') {
1395 		if (temp[2] == ':') {
1396 			/* This is an option that accepts an argument optionally.  */
1397 			if (*d->nextchar != '\0') {
1398 				d->custom_optarg = d->nextchar;
1399 				d->custom_optind++;
1400 			} else
1401 				d->custom_optarg = NULL;
1402 			d->nextchar = NULL;
1403 		} else {
1404 			/* This is an option that requires an argument.  */
1405 			if (*d->nextchar != '\0') {
1406 				d->custom_optarg = d->nextchar;
1407 				/*
1408 				 * If we end this ARGV-element by taking the
1409 				 * rest as an arg, we must advance to the next
1410 				 * element now.
1411 				 */
1412 				d->custom_optind++;
1413 			} else if (d->custom_optind == argc) {
1414 				if (print_errors) {
1415 					fprintf(stderr,
1416 						"%s: option requires an argument -- %c\n",
1417 						argv[0], c);
1418 				}
1419 				d->custom_optopt = c;
1420 				if (optstring[0] == ':')
1421 					c = ':';
1422 				else
1423 					c = '?';
1424 			} else
1425 				/*
1426 				 * We already incremented `custom_optind' once;
1427 				 * increment it again when taking next ARGV-elt
1428 				 * as argument.
1429 				 */
1430 				d->custom_optarg = argv[d->custom_optind++];
1431 			d->nextchar = NULL;
1432 		}
1433 	}
1434 	return c;
1435 }
1436 
1437 /*
1438  * Scan elements of ARGV for option characters given in OPTSTRING.
1439  *
1440  * If an element of ARGV starts with '-', and is not exactly "-" or "--",
1441  * then it is an option element.  The characters of this element
1442  * (aside from the initial '-') are option characters.  If `getopt'
1443  * is called repeatedly, it returns successively each of the option characters
1444  * from each of the option elements.
1445  *
1446  * If `getopt' finds another option character, it returns that character,
1447  * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1448  * resume the scan with the following option character or ARGV-element.
1449  *
1450  * If there are no more option characters, `getopt' returns -1.
1451  * Then `custom_optind' is the index in ARGV of the first ARGV-element
1452  * that is not an option.  (The ARGV-elements have been permuted
1453  * so that those that are not options now come last.)
1454  *
1455  * OPTSTRING is a string containing the legitimate option characters.
1456  * If an option character is seen that is not listed in OPTSTRING,
1457  * return '?' after printing an error message.  If you set `custom_opterr' to
1458  * zero, the error message is suppressed but we still return '?'.
1459  *
1460  * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1461  * so the following text in the same ARGV-element, or the text of the following
1462  * ARGV-element, is returned in `custom_optarg'.  Two colons mean an option that
1463  * wants an optional arg; if there is text in the current ARGV-element,
1464  * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1465  *
1466  * If OPTSTRING starts with `-' or `+', it requests different methods of
1467  * handling the non-option ARGV-elements.
1468  * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1469  *
1470  * Long-named options begin with `--' instead of `-'.
1471  * Their names may be abbreviated as long as the abbreviation is unique
1472  * or is an exact match for some defined option.  If they have an
1473  * argument, it follows the option name in the same ARGV-element, separated
1474  * from the option name by a `=', or else the in next ARGV-element.
1475  * When `getopt' finds a long-named option, it returns 0 if that option's
1476  * `flag' field is nonzero, the value of the option's `val' field
1477  * if the `flag' field is zero.
1478  *
1479  * The elements of ARGV aren't really const, because we permute them.
1480  * But we pretend they're const in the prototype to be compatible
1481  * with other systems.
1482  *
1483  * LONGOPTS is a vector of `struct option' terminated by an
1484  * element containing a name which is zero.
1485  *
1486  * LONGIND returns the index in LONGOPT of the long-named option found.
1487  * It is only valid when a long-named option has been found by the most
1488  * recent call.
1489  *
1490  * Return the option character from OPTS just read.  Return -1 when there are
1491  * no more options.  For unrecognized options, or options missing arguments,
1492  * `custom_optopt' is set to the option letter, and '?' is returned.
1493  *
1494  * The OPTS string is a list of characters which are recognized option letters,
1495  * optionally followed by colons, specifying that that letter takes an
1496  * argument, to be placed in `custom_optarg'.
1497  *
1498  * If a letter in OPTS is followed by two colons, its argument is optional.
1499  * This behavior is specific to the GNU `getopt'.
1500  *
1501  * The argument `--' causes premature termination of argument scanning,
1502  * explicitly telling `getopt' that there are no more options.  If OPTS begins
1503  * with `--', then non-option arguments are treated as arguments to the option
1504  * '\0'.  This behavior is specific to the GNU `getopt'.
1505  */
1506 
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1507 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1508 		const struct option *longopts, int *longind,
1509 		struct custom_getopt_data *d)
1510 {
1511 	int ret, print_errors = d->custom_opterr;
1512 
1513 	if (optstring[0] == ':')
1514 		print_errors = 0;
1515 	if (argc < 1)
1516 		return -1;
1517 	d->custom_optarg = NULL;
1518 
1519 	/*
1520 	 * This is a big difference with GNU getopt, since optind == 0
1521 	 * means initialization while here 1 means first call.
1522 	 */
1523 	if (d->custom_optind == 0 || !d->initialized) {
1524 		if (d->custom_optind == 0)
1525 			d->custom_optind = 1;	/* Don't scan ARGV[0], the program name.  */
1526 		custom_getopt_initialize(d);
1527 	}
1528 	if (d->nextchar == NULL || *d->nextchar == '\0') {
1529 		ret = shuffle_argv(argc, argv, longopts, d);
1530 		if (ret)
1531 			return ret;
1532 	}
1533 	if (longopts && (argv[d->custom_optind][1] == '-' ))
1534 		return check_long_opt(argc, argv, optstring, longopts,
1535 			longind, print_errors, d);
1536 	return check_short_opt(argc, argv, optstring, print_errors, d);
1537 }
1538 
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1539 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1540 	const struct option *longopts, int *longind)
1541 {
1542 	int result;
1543 	/* Keep a global copy of all internal members of d */
1544 	static struct custom_getopt_data d;
1545 
1546 	d.custom_optind = custom_optind;
1547 	d.custom_opterr = custom_opterr;
1548 	result = getopt_internal_r(argc, argv, optstring, longopts,
1549 		longind, &d);
1550 	custom_optind = d.custom_optind;
1551 	custom_optarg = d.custom_optarg;
1552 	custom_optopt = d.custom_optopt;
1553 	return result;
1554 }
1555 
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1556 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1557 	const struct option *long_options, int *opt_index)
1558 {
1559 	return custom_getopt_internal(argc, argv, options, long_options,
1560 		opt_index);
1561 }
1562 
1563 
1564 static char *package_name = 0;
1565 
1566 /**
1567  * @brief updates an option
1568  * @param field the generic pointer to the field to update
1569  * @param orig_field the pointer to the orig field
1570  * @param field_given the pointer to the number of occurrence of this option
1571  * @param prev_given the pointer to the number of occurrence already seen
1572  * @param value the argument for this option (if null no arg was specified)
1573  * @param possible_values the possible values for this option (if specified)
1574  * @param default_value the default value (in case the option only accepts fixed values)
1575  * @param arg_type the type of this option
1576  * @param check_ambiguity @see RNALalifold_cmdline_parser_params.check_ambiguity
1577  * @param override @see RNALalifold_cmdline_parser_params.override
1578  * @param no_free whether to free a possible previous value
1579  * @param multiple_option whether this is a multiple option
1580  * @param long_opt the corresponding long option
1581  * @param short_opt the corresponding short option (or '-' if none)
1582  * @param additional_error possible further error specification
1583  */
1584 static
update_arg(void * field,char ** orig_field,unsigned int * field_given,unsigned int * prev_given,char * value,const char * possible_values[],const char * default_value,RNALalifold_cmdline_parser_arg_type arg_type,int check_ambiguity,int override,int no_free,int multiple_option,const char * long_opt,char short_opt,const char * additional_error)1585 int update_arg(void *field, char **orig_field,
1586                unsigned int *field_given, unsigned int *prev_given,
1587                char *value, const char *possible_values[],
1588                const char *default_value,
1589                RNALalifold_cmdline_parser_arg_type arg_type,
1590                int check_ambiguity, int override,
1591                int no_free, int multiple_option,
1592                const char *long_opt, char short_opt,
1593                const char *additional_error)
1594 {
1595   char *stop_char = 0;
1596   const char *val = value;
1597   int found;
1598   char **string_field;
1599   FIX_UNUSED (field);
1600 
1601   stop_char = 0;
1602   found = 0;
1603 
1604   if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1605     {
1606       if (short_opt != '-')
1607         fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1608                package_name, long_opt, short_opt,
1609                (additional_error ? additional_error : ""));
1610       else
1611         fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1612                package_name, long_opt,
1613                (additional_error ? additional_error : ""));
1614       return 1; /* failure */
1615     }
1616 
1617   FIX_UNUSED (default_value);
1618 
1619   if (field_given && *field_given && ! override)
1620     return 0;
1621   if (prev_given)
1622     (*prev_given)++;
1623   if (field_given)
1624     (*field_given)++;
1625   if (possible_values)
1626     val = possible_values[found];
1627 
1628   switch(arg_type) {
1629   case ARG_FLAG:
1630     *((int *)field) = !*((int *)field);
1631     break;
1632   case ARG_INT:
1633     if (val) *((int *)field) = strtol (val, &stop_char, 0);
1634     break;
1635   case ARG_LONG:
1636     if (val) *((long *)field) = (long)strtol (val, &stop_char, 0);
1637     break;
1638   case ARG_DOUBLE:
1639     if (val) *((double *)field) = strtod (val, &stop_char);
1640     break;
1641   case ARG_STRING:
1642     if (val) {
1643       string_field = (char **)field;
1644       if (!no_free && *string_field)
1645         free (*string_field); /* free previous string */
1646       *string_field = gengetopt_strdup (val);
1647     }
1648     break;
1649   default:
1650     break;
1651   };
1652 
1653   /* check numeric conversion */
1654   switch(arg_type) {
1655   case ARG_INT:
1656   case ARG_LONG:
1657   case ARG_DOUBLE:
1658     if (val && !(stop_char && *stop_char == '\0')) {
1659       fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1660       return 1; /* failure */
1661     }
1662     break;
1663   default:
1664     ;
1665   };
1666 
1667   /* store the original value */
1668   switch(arg_type) {
1669   case ARG_NO:
1670   case ARG_FLAG:
1671     break;
1672   default:
1673     if (value && orig_field) {
1674       if (no_free) {
1675         *orig_field = value;
1676       } else {
1677         if (*orig_field)
1678           free (*orig_field); /* free previous string */
1679         *orig_field = gengetopt_strdup (value);
1680       }
1681     }
1682   };
1683 
1684   return 0; /* OK */
1685 }
1686 
1687 /**
1688  * @brief store information about a multiple option in a temporary list
1689  * @param list where to (temporarily) store multiple options
1690  */
1691 static
update_multiple_arg_temp(struct generic_list ** list,unsigned int * prev_given,const char * val,const char * possible_values[],const char * default_value,RNALalifold_cmdline_parser_arg_type arg_type,const char * long_opt,char short_opt,const char * additional_error)1692 int update_multiple_arg_temp(struct generic_list **list,
1693                unsigned int *prev_given, const char *val,
1694                const char *possible_values[], const char *default_value,
1695                RNALalifold_cmdline_parser_arg_type arg_type,
1696                const char *long_opt, char short_opt,
1697                const char *additional_error)
1698 {
1699   /* store single arguments */
1700   char *multi_token;
1701   const char *multi_next;
1702 
1703   if (arg_type == ARG_NO) {
1704     (*prev_given)++;
1705     return 0; /* OK */
1706   }
1707 
1708   multi_token = get_multiple_arg_token(val);
1709   multi_next = get_multiple_arg_token_next (val);
1710 
1711   while (1)
1712     {
1713       add_node (list);
1714       if (update_arg((void *)&((*list)->arg), &((*list)->orig), 0,
1715           prev_given, multi_token, possible_values, default_value,
1716           arg_type, 0, 1, 1, 1, long_opt, short_opt, additional_error)) {
1717         if (multi_token) free(multi_token);
1718         return 1; /* failure */
1719       }
1720 
1721       if (multi_next)
1722         {
1723           multi_token = get_multiple_arg_token(multi_next);
1724           multi_next = get_multiple_arg_token_next (multi_next);
1725         }
1726       else
1727         break;
1728     }
1729 
1730   return 0; /* OK */
1731 }
1732 
1733 /**
1734  * @brief free the passed list (including possible string argument)
1735  */
1736 static
free_list(struct generic_list * list,short string_arg)1737 void free_list(struct generic_list *list, short string_arg)
1738 {
1739   if (list) {
1740     struct generic_list *tmp;
1741     while (list)
1742       {
1743         tmp = list;
1744         if (string_arg && list->arg.string_arg)
1745           free (list->arg.string_arg);
1746         if (list->orig)
1747           free (list->orig);
1748         list = list->next;
1749         free (tmp);
1750       }
1751   }
1752 }
1753 
1754 /**
1755  * @brief updates a multiple option starting from the passed list
1756  */
1757 static
update_multiple_arg(void * field,char *** orig_field,unsigned int field_given,unsigned int prev_given,union generic_value * default_value,RNALalifold_cmdline_parser_arg_type arg_type,struct generic_list * list)1758 void update_multiple_arg(void *field, char ***orig_field,
1759                unsigned int field_given, unsigned int prev_given, union generic_value *default_value,
1760                RNALalifold_cmdline_parser_arg_type arg_type,
1761                struct generic_list *list)
1762 {
1763   int i;
1764   struct generic_list *tmp;
1765 
1766   if (prev_given && list) {
1767     *orig_field = (char **) realloc (*orig_field, (field_given + prev_given) * sizeof (char *));
1768 
1769     switch(arg_type) {
1770     case ARG_INT:
1771       *((int **)field) = (int *)realloc (*((int **)field), (field_given + prev_given) * sizeof (int)); break;
1772     case ARG_LONG:
1773       *((long **)field) = (long *)realloc (*((long **)field), (field_given + prev_given) * sizeof (long)); break;
1774     case ARG_DOUBLE:
1775       *((double **)field) = (double *)realloc (*((double **)field), (field_given + prev_given) * sizeof (double)); break;
1776     case ARG_STRING:
1777       *((char ***)field) = (char **)realloc (*((char ***)field), (field_given + prev_given) * sizeof (char *)); break;
1778     default:
1779       break;
1780     };
1781 
1782     for (i = (prev_given - 1); i >= 0; --i)
1783       {
1784         tmp = list;
1785 
1786         switch(arg_type) {
1787         case ARG_INT:
1788           (*((int **)field))[i + field_given] = tmp->arg.int_arg; break;
1789         case ARG_LONG:
1790           (*((long **)field))[i + field_given] = tmp->arg.long_arg; break;
1791         case ARG_DOUBLE:
1792           (*((double **)field))[i + field_given] = tmp->arg.double_arg; break;
1793         case ARG_STRING:
1794           (*((char ***)field))[i + field_given] = tmp->arg.string_arg; break;
1795         default:
1796           break;
1797         }
1798         (*orig_field) [i + field_given] = list->orig;
1799         list = list->next;
1800         free (tmp);
1801       }
1802   } else { /* set the default value */
1803     if (default_value && ! field_given) {
1804       switch(arg_type) {
1805       case ARG_INT:
1806         if (! *((int **)field)) {
1807           *((int **)field) = (int *)malloc (sizeof (int));
1808           (*((int **)field))[0] = default_value->int_arg;
1809         }
1810         break;
1811       case ARG_LONG:
1812         if (! *((long **)field)) {
1813           *((long **)field) = (long *)malloc (sizeof (long));
1814           (*((long **)field))[0] = default_value->long_arg;
1815         }
1816         break;
1817       case ARG_DOUBLE:
1818         if (! *((double **)field)) {
1819           *((double **)field) = (double *)malloc (sizeof (double));
1820           (*((double **)field))[0] = default_value->double_arg;
1821         }
1822         break;
1823       case ARG_STRING:
1824         if (! *((char ***)field)) {
1825           *((char ***)field) = (char **)malloc (sizeof (char *));
1826           (*((char ***)field))[0] = gengetopt_strdup(default_value->string_arg);
1827         }
1828         break;
1829       default: break;
1830       }
1831       if (!(*orig_field)) {
1832         *orig_field = (char **) malloc (sizeof (char *));
1833         (*orig_field)[0] = 0;
1834       }
1835     }
1836   }
1837 }
1838 
1839 int
RNALalifold_cmdline_parser_internal(int argc,char ** argv,struct RNALalifold_args_info * args_info,struct RNALalifold_cmdline_parser_params * params,const char * additional_error)1840 RNALalifold_cmdline_parser_internal (
1841   int argc, char **argv, struct RNALalifold_args_info *args_info,
1842                         struct RNALalifold_cmdline_parser_params *params, const char *additional_error)
1843 {
1844   int c;	/* Character of the parsed option.  */
1845 
1846   struct generic_list * shape_list = NULL;
1847   int error_occurred = 0;
1848   struct RNALalifold_args_info local_args_info;
1849 
1850   int override;
1851   int initialize;
1852   int check_required;
1853   int check_ambiguity;
1854 
1855   char *optarg;
1856   int optind;
1857   int opterr;
1858   int optopt;
1859 
1860   package_name = argv[0];
1861 
1862   /* TODO: Why is this here? It is not used anywhere. */
1863   override = params->override;
1864   FIX_UNUSED(override);
1865 
1866   initialize = params->initialize;
1867   check_required = params->check_required;
1868 
1869   /* TODO: Why is this here? It is not used anywhere. */
1870   check_ambiguity = params->check_ambiguity;
1871   FIX_UNUSED(check_ambiguity);
1872 
1873   if (initialize)
1874     RNALalifold_cmdline_parser_init (args_info);
1875 
1876   RNALalifold_cmdline_parser_init (&local_args_info);
1877 
1878   optarg = 0;
1879   optind = 0;
1880   opterr = params->print_errors;
1881   optopt = '?';
1882 
1883   while (1)
1884     {
1885       int option_index = 0;
1886 
1887       static struct option long_options[] = {
1888         { "help",	0, NULL, 'h' },
1889         { "detailed-help",	0, NULL, 0 },
1890         { "full-help",	0, NULL, 0 },
1891         { "version",	0, NULL, 'V' },
1892         { "verbose",	0, NULL, 'v' },
1893         { "quiet",	0, NULL, 'q' },
1894         { "noconv",	0, NULL, 0 },
1895         { "input-format",	1, NULL, 'f' },
1896         { "csv",	0, NULL, 0 },
1897         { "aln",	2, NULL, 0 },
1898         { "aln-EPS",	2, NULL, 0 },
1899         { "aln-EPS-cols",	1, NULL, 0 },
1900         { "aln-EPS-ss",	2, NULL, 0 },
1901         { "aln-stk",	2, NULL, 0 },
1902         { "auto-id",	0, NULL, 0 },
1903         { "id-prefix",	1, NULL, 0 },
1904         { "id-delim",	1, NULL, 0 },
1905         { "id-digits",	1, NULL, 0 },
1906         { "id-start",	1, NULL, 0 },
1907         { "filename-delim",	1, NULL, 0 },
1908         { "split-contributions",	0, NULL, 0 },
1909         { "shape",	1, NULL, 0 },
1910         { "shapeMethod",	1, NULL, 0 },
1911         { "maxBPspan",	1, NULL, 'L' },
1912         { "threshold",	1, NULL, 0 },
1913         { "mis",	0, NULL, 0 },
1914         { "gquad",	0, NULL, 'g' },
1915         { "temp",	1, NULL, 'T' },
1916         { "noTetra",	0, NULL, '4' },
1917         { "dangles",	1, NULL, 'd' },
1918         { "noLP",	0, NULL, 0 },
1919         { "noGU",	0, NULL, 0 },
1920         { "noClosingGU",	0, NULL, 0 },
1921         { "paramFile",	1, NULL, 'P' },
1922         { "nsp",	1, NULL, 0 },
1923         { "energyModel",	1, NULL, 'e' },
1924         { "cfactor",	1, NULL, 0 },
1925         { "nfactor",	1, NULL, 0 },
1926         { "ribosum_file",	1, NULL, 'R' },
1927         { "ribosum_scoring",	0, NULL, 'r' },
1928         { 0,  0, 0, 0 }
1929       };
1930 
1931       custom_optarg = optarg;
1932       custom_optind = optind;
1933       custom_opterr = opterr;
1934       custom_optopt = optopt;
1935 
1936       c = custom_getopt_long (argc, argv, "hVvqf:L:gT:4d:P:e:R:r", long_options, &option_index);
1937 
1938       optarg = custom_optarg;
1939       optind = custom_optind;
1940       opterr = custom_opterr;
1941       optopt = custom_optopt;
1942 
1943       if (c == -1) break;	/* Exit from `while (1)' loop.  */
1944 
1945       switch (c)
1946         {
1947         case 'h':	/* Print help and exit.  */
1948           RNALalifold_cmdline_parser_print_help ();
1949           RNALalifold_cmdline_parser_free (&local_args_info);
1950           exit (EXIT_SUCCESS);
1951 
1952         case 'V':	/* Print version and exit.  */
1953           RNALalifold_cmdline_parser_print_version ();
1954           RNALalifold_cmdline_parser_free (&local_args_info);
1955           exit (EXIT_SUCCESS);
1956 
1957         case 'v':	/* Be verbose.
1958 
1959 .  */
1960 
1961 
1962           if (update_arg((void *)&(args_info->verbose_flag), 0, &(args_info->verbose_given),
1963               &(local_args_info.verbose_given), optarg, 0, 0, ARG_FLAG,
1964               check_ambiguity, override, 1, 0, "verbose", 'v',
1965               additional_error))
1966             goto failure;
1967 
1968           break;
1969         case 'q':	/* Be quiet.
1970 .  */
1971 
1972 
1973           if (update_arg((void *)&(args_info->quiet_flag), 0, &(args_info->quiet_given),
1974               &(local_args_info.quiet_given), optarg, 0, 0, ARG_FLAG,
1975               check_ambiguity, override, 1, 0, "quiet", 'q',
1976               additional_error))
1977             goto failure;
1978 
1979           break;
1980         case 'f':	/* File format of the input multiple sequence alignment (MSA).
1981 .  */
1982 
1983 
1984           if (update_arg( (void *)&(args_info->input_format_arg),
1985                &(args_info->input_format_orig), &(args_info->input_format_given),
1986               &(local_args_info.input_format_given), optarg, 0, 0, ARG_STRING,
1987               check_ambiguity, override, 0, 0,
1988               "input-format", 'f',
1989               additional_error))
1990             goto failure;
1991 
1992           break;
1993         case 'L':	/* Set the maximum allowed separation of a base pair to span. I.e. no pairs (i,j) with j-i>span will be allowed.
1994 
1995 .  */
1996 
1997 
1998           if (update_arg( (void *)&(args_info->maxBPspan_arg),
1999                &(args_info->maxBPspan_orig), &(args_info->maxBPspan_given),
2000               &(local_args_info.maxBPspan_given), optarg, 0, "70", ARG_INT,
2001               check_ambiguity, override, 0, 0,
2002               "maxBPspan", 'L',
2003               additional_error))
2004             goto failure;
2005 
2006           break;
2007         case 'g':	/* Incoorporate G-Quadruplex formation into the structure prediction algorithm
2008 
2009 .  */
2010 
2011 
2012           if (update_arg((void *)&(args_info->gquad_flag), 0, &(args_info->gquad_given),
2013               &(local_args_info.gquad_given), optarg, 0, 0, ARG_FLAG,
2014               check_ambiguity, override, 1, 0, "gquad", 'g',
2015               additional_error))
2016             goto failure;
2017 
2018           break;
2019         case 'T':	/* Rescale energy parameters to a temperature of temp C. Default is 37C.
2020 
2021 .  */
2022 
2023 
2024           if (update_arg( (void *)&(args_info->temp_arg),
2025                &(args_info->temp_orig), &(args_info->temp_given),
2026               &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
2027               check_ambiguity, override, 0, 0,
2028               "temp", 'T',
2029               additional_error))
2030             goto failure;
2031 
2032           break;
2033         case '4':	/* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins. Mostly for testing.
2034 
2035 .  */
2036 
2037 
2038           if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
2039               &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
2040               check_ambiguity, override, 1, 0, "noTetra", '4',
2041               additional_error))
2042             goto failure;
2043 
2044           break;
2045         case 'd':	/* How to treat \"dangling end\" energies for bases adjacent to helices in free ends and multi-loops
2046 .  */
2047 
2048 
2049           if (update_arg( (void *)&(args_info->dangles_arg),
2050                &(args_info->dangles_orig), &(args_info->dangles_given),
2051               &(local_args_info.dangles_given), optarg, 0, "2", ARG_INT,
2052               check_ambiguity, override, 0, 0,
2053               "dangles", 'd',
2054               additional_error))
2055             goto failure;
2056 
2057           break;
2058         case 'P':	/* Read energy parameters from paramfile, instead of using the default parameter set.
2059 .  */
2060 
2061 
2062           if (update_arg( (void *)&(args_info->paramFile_arg),
2063                &(args_info->paramFile_orig), &(args_info->paramFile_given),
2064               &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
2065               check_ambiguity, override, 0, 0,
2066               "paramFile", 'P',
2067               additional_error))
2068             goto failure;
2069 
2070           break;
2071         case 'e':	/* Rarely used option to fold sequences from the artificial ABCD... alphabet, where A pairs B, C-D etc.  Use the energy parameters for GC (-e 1) or AU (-e 2) pairs.
2072 
2073 .  */
2074 
2075 
2076           if (update_arg( (void *)&(args_info->energyModel_arg),
2077                &(args_info->energyModel_orig), &(args_info->energyModel_given),
2078               &(local_args_info.energyModel_given), optarg, 0, 0, ARG_INT,
2079               check_ambiguity, override, 0, 0,
2080               "energyModel", 'e',
2081               additional_error))
2082             goto failure;
2083 
2084           break;
2085         case 'R':	/* use specified Ribosum Matrix instead of normal energy model. Matrixes to use should be 6x6 matrices, the order of the terms is AU, CG, GC, GU, UA, UG.
2086 
2087 .  */
2088 
2089 
2090           if (update_arg( (void *)&(args_info->ribosum_file_arg),
2091                &(args_info->ribosum_file_orig), &(args_info->ribosum_file_given),
2092               &(local_args_info.ribosum_file_given), optarg, 0, 0, ARG_STRING,
2093               check_ambiguity, override, 0, 0,
2094               "ribosum_file", 'R',
2095               additional_error))
2096             goto failure;
2097 
2098           break;
2099         case 'r':	/* use ribosum scoring matrix. The matrix is chosen according to the minimal and maximal pairwise identities of the sequences in the file.
2100 
2101 .  */
2102 
2103 
2104           if (update_arg((void *)&(args_info->ribosum_scoring_flag), 0, &(args_info->ribosum_scoring_given),
2105               &(local_args_info.ribosum_scoring_given), optarg, 0, 0, ARG_FLAG,
2106               check_ambiguity, override, 1, 0, "ribosum_scoring", 'r',
2107               additional_error))
2108             goto failure;
2109 
2110           break;
2111 
2112         case 0:	/* Long option with no short option */
2113           if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
2114             RNALalifold_cmdline_parser_print_detailed_help ();
2115             RNALalifold_cmdline_parser_free (&local_args_info);
2116             exit (EXIT_SUCCESS);
2117           }
2118 
2119           if (strcmp (long_options[option_index].name, "full-help") == 0) {
2120             RNALalifold_cmdline_parser_print_full_help ();
2121             RNALalifold_cmdline_parser_free (&local_args_info);
2122             exit (EXIT_SUCCESS);
2123           }
2124 
2125           /* Do not automatically substitute nucleotide \"T\" with \"U\"
2126 
2127 .  */
2128           if (strcmp (long_options[option_index].name, "noconv") == 0)
2129           {
2130 
2131 
2132             if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
2133                 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
2134                 check_ambiguity, override, 1, 0, "noconv", '-',
2135                 additional_error))
2136               goto failure;
2137 
2138           }
2139           /* Create comma separated output (csv)
2140 
2141 .  */
2142           else if (strcmp (long_options[option_index].name, "csv") == 0)
2143           {
2144 
2145 
2146             if (update_arg((void *)&(args_info->csv_flag), 0, &(args_info->csv_given),
2147                 &(local_args_info.csv_given), optarg, 0, 0, ARG_FLAG,
2148                 check_ambiguity, override, 1, 0, "csv", '-',
2149                 additional_error))
2150               goto failure;
2151 
2152           }
2153           /* Produce output alignments and secondary structure plots for each hit found.
2154 .  */
2155           else if (strcmp (long_options[option_index].name, "aln") == 0)
2156           {
2157 
2158 
2159             if (update_arg( (void *)&(args_info->aln_arg),
2160                  &(args_info->aln_orig), &(args_info->aln_given),
2161                 &(local_args_info.aln_given), optarg, 0, 0, ARG_STRING,
2162                 check_ambiguity, override, 0, 0,
2163                 "aln", '-',
2164                 additional_error))
2165               goto failure;
2166 
2167           }
2168           /* Produce colored and structure annotated subalignment for each hit
2169 .  */
2170           else if (strcmp (long_options[option_index].name, "aln-EPS") == 0)
2171           {
2172 
2173 
2174             if (update_arg( (void *)&(args_info->aln_EPS_arg),
2175                  &(args_info->aln_EPS_orig), &(args_info->aln_EPS_given),
2176                 &(local_args_info.aln_EPS_given), optarg, 0, 0, ARG_STRING,
2177                 check_ambiguity, override, 0, 0,
2178                 "aln-EPS", '-',
2179                 additional_error))
2180               goto failure;
2181 
2182           }
2183           /* Number of columns in colored EPS alignment output.
2184 .  */
2185           else if (strcmp (long_options[option_index].name, "aln-EPS-cols") == 0)
2186           {
2187 
2188 
2189             if (update_arg( (void *)&(args_info->aln_EPS_cols_arg),
2190                  &(args_info->aln_EPS_cols_orig), &(args_info->aln_EPS_cols_given),
2191                 &(local_args_info.aln_EPS_cols_given), optarg, 0, "60", ARG_INT,
2192                 check_ambiguity, override, 0, 0,
2193                 "aln-EPS-cols", '-',
2194                 additional_error))
2195               goto failure;
2196 
2197           }
2198           /* Produce colored consensus secondary structure plots in PostScript format
2199 .  */
2200           else if (strcmp (long_options[option_index].name, "aln-EPS-ss") == 0)
2201           {
2202 
2203 
2204             if (update_arg( (void *)&(args_info->aln_EPS_ss_arg),
2205                  &(args_info->aln_EPS_ss_orig), &(args_info->aln_EPS_ss_given),
2206                 &(local_args_info.aln_EPS_ss_given), optarg, 0, 0, ARG_STRING,
2207                 check_ambiguity, override, 0, 0,
2208                 "aln-EPS-ss", '-',
2209                 additional_error))
2210               goto failure;
2211 
2212           }
2213           /* Add hits to a multi-Stockholm formatted output file.
2214 .  */
2215           else if (strcmp (long_options[option_index].name, "aln-stk") == 0)
2216           {
2217 
2218 
2219             if (update_arg( (void *)&(args_info->aln_stk_arg),
2220                  &(args_info->aln_stk_orig), &(args_info->aln_stk_given),
2221                 &(local_args_info.aln_stk_given), optarg, 0, "RNALalifold_results", ARG_STRING,
2222                 check_ambiguity, override, 0, 0,
2223                 "aln-stk", '-',
2224                 additional_error))
2225               goto failure;
2226 
2227           }
2228           /* Automatically generate an ID for each alignment.
2229 .  */
2230           else if (strcmp (long_options[option_index].name, "auto-id") == 0)
2231           {
2232 
2233 
2234             if (update_arg((void *)&(args_info->auto_id_flag), 0, &(args_info->auto_id_given),
2235                 &(local_args_info.auto_id_given), optarg, 0, 0, ARG_FLAG,
2236                 check_ambiguity, override, 1, 0, "auto-id", '-',
2237                 additional_error))
2238               goto failure;
2239 
2240           }
2241           /* Prefix for automatically generated IDs (as used in output file names)
2242 
2243 .  */
2244           else if (strcmp (long_options[option_index].name, "id-prefix") == 0)
2245           {
2246 
2247 
2248             if (update_arg( (void *)&(args_info->id_prefix_arg),
2249                  &(args_info->id_prefix_orig), &(args_info->id_prefix_given),
2250                 &(local_args_info.id_prefix_given), optarg, 0, "alignment", ARG_STRING,
2251                 check_ambiguity, override, 0, 0,
2252                 "id-prefix", '-',
2253                 additional_error))
2254               goto failure;
2255 
2256           }
2257           /* Change the delimiter between prefix and increasing number for automatically generated IDs (as used in output file names)
2258 
2259 .  */
2260           else if (strcmp (long_options[option_index].name, "id-delim") == 0)
2261           {
2262 
2263 
2264             if (update_arg( (void *)&(args_info->id_delim_arg),
2265                  &(args_info->id_delim_orig), &(args_info->id_delim_given),
2266                 &(local_args_info.id_delim_given), optarg, 0, "_", ARG_STRING,
2267                 check_ambiguity, override, 0, 0,
2268                 "id-delim", '-',
2269                 additional_error))
2270               goto failure;
2271 
2272           }
2273           /* Specify the number of digits of the counter in automatically generated alignment IDs.
2274 .  */
2275           else if (strcmp (long_options[option_index].name, "id-digits") == 0)
2276           {
2277 
2278 
2279             if (update_arg( (void *)&(args_info->id_digits_arg),
2280                  &(args_info->id_digits_orig), &(args_info->id_digits_given),
2281                 &(local_args_info.id_digits_given), optarg, 0, "4", ARG_INT,
2282                 check_ambiguity, override, 0, 0,
2283                 "id-digits", '-',
2284                 additional_error))
2285               goto failure;
2286 
2287           }
2288           /* Specify the first number in automatically generated alignment IDs.
2289 .  */
2290           else if (strcmp (long_options[option_index].name, "id-start") == 0)
2291           {
2292 
2293 
2294             if (update_arg( (void *)&(args_info->id_start_arg),
2295                  &(args_info->id_start_orig), &(args_info->id_start_given),
2296                 &(local_args_info.id_start_given), optarg, 0, "1", ARG_LONG,
2297                 check_ambiguity, override, 0, 0,
2298                 "id-start", '-',
2299                 additional_error))
2300               goto failure;
2301 
2302           }
2303           /* Change the delimiting character that is used for sanitized filenames
2304 
2305 .  */
2306           else if (strcmp (long_options[option_index].name, "filename-delim") == 0)
2307           {
2308 
2309 
2310             if (update_arg( (void *)&(args_info->filename_delim_arg),
2311                  &(args_info->filename_delim_orig), &(args_info->filename_delim_given),
2312                 &(local_args_info.filename_delim_given), optarg, 0, "ID-delimiter", ARG_STRING,
2313                 check_ambiguity, override, 0, 0,
2314                 "filename-delim", '-',
2315                 additional_error))
2316               goto failure;
2317 
2318           }
2319           /* Split the free energy contributions into separate parts
2320 .  */
2321           else if (strcmp (long_options[option_index].name, "split-contributions") == 0)
2322           {
2323 
2324 
2325             if (update_arg((void *)&(args_info->split_contributions_flag), 0, &(args_info->split_contributions_given),
2326                 &(local_args_info.split_contributions_given), optarg, 0, 0, ARG_FLAG,
2327                 check_ambiguity, override, 1, 0, "split-contributions", '-',
2328                 additional_error))
2329               goto failure;
2330 
2331           }
2332           /* Use SHAPE reactivity data to guide structure predictions
2333 .  */
2334           else if (strcmp (long_options[option_index].name, "shape") == 0)
2335           {
2336 
2337             if (update_multiple_arg_temp(&shape_list,
2338                 &(local_args_info.shape_given), optarg, 0, 0, ARG_STRING,
2339                 "shape", '-',
2340                 additional_error))
2341               goto failure;
2342 
2343           }
2344           /* Specify the method how to convert SHAPE reactivity data to pseudo energy contributions
2345 .  */
2346           else if (strcmp (long_options[option_index].name, "shapeMethod") == 0)
2347           {
2348 
2349 
2350             if (update_arg( (void *)&(args_info->shapeMethod_arg),
2351                  &(args_info->shapeMethod_orig), &(args_info->shapeMethod_given),
2352                 &(local_args_info.shapeMethod_given), optarg, 0, "D", ARG_STRING,
2353                 check_ambiguity, override, 0, 0,
2354                 "shapeMethod", '-',
2355                 additional_error))
2356               goto failure;
2357 
2358           }
2359           /* Energy threshold in kcal/mol per nucleotide above which secondary structure hits are omitted in the output.
2360 
2361 .  */
2362           else if (strcmp (long_options[option_index].name, "threshold") == 0)
2363           {
2364 
2365 
2366             if (update_arg( (void *)&(args_info->threshold_arg),
2367                  &(args_info->threshold_orig), &(args_info->threshold_given),
2368                 &(local_args_info.threshold_given), optarg, 0, "-0.1", ARG_DOUBLE,
2369                 check_ambiguity, override, 0, 0,
2370                 "threshold", '-',
2371                 additional_error))
2372               goto failure;
2373 
2374           }
2375           /* Output \"most informative sequence\" instead of simple consensus: For each column of the alignment output the set of nucleotides with frequency greater than average in IUPAC notation.
2376 
2377 .  */
2378           else if (strcmp (long_options[option_index].name, "mis") == 0)
2379           {
2380 
2381 
2382             if (update_arg((void *)&(args_info->mis_flag), 0, &(args_info->mis_given),
2383                 &(local_args_info.mis_given), optarg, 0, 0, ARG_FLAG,
2384                 check_ambiguity, override, 1, 0, "mis", '-',
2385                 additional_error))
2386               goto failure;
2387 
2388           }
2389           /* Produce structures without lonely pairs (helices of length 1).
2390 .  */
2391           else if (strcmp (long_options[option_index].name, "noLP") == 0)
2392           {
2393 
2394 
2395             if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
2396                 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
2397                 check_ambiguity, override, 1, 0, "noLP", '-',
2398                 additional_error))
2399               goto failure;
2400 
2401           }
2402           /* Do not allow GU pairs
2403 
2404 .  */
2405           else if (strcmp (long_options[option_index].name, "noGU") == 0)
2406           {
2407 
2408 
2409             if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
2410                 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
2411                 check_ambiguity, override, 1, 0, "noGU", '-',
2412                 additional_error))
2413               goto failure;
2414 
2415           }
2416           /* Do not allow GU pairs at the end of helices
2417 
2418 .  */
2419           else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
2420           {
2421 
2422 
2423             if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
2424                 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
2425                 check_ambiguity, override, 1, 0, "noClosingGU", '-',
2426                 additional_error))
2427               goto failure;
2428 
2429           }
2430           /* Allow other pairs in addition to the usual AU,GC,and GU pairs.
2431 .  */
2432           else if (strcmp (long_options[option_index].name, "nsp") == 0)
2433           {
2434 
2435 
2436             if (update_arg( (void *)&(args_info->nsp_arg),
2437                  &(args_info->nsp_orig), &(args_info->nsp_given),
2438                 &(local_args_info.nsp_given), optarg, 0, 0, ARG_STRING,
2439                 check_ambiguity, override, 0, 0,
2440                 "nsp", '-',
2441                 additional_error))
2442               goto failure;
2443 
2444           }
2445           /* Set the weight of the covariance term in the energy function
2446 
2447 .  */
2448           else if (strcmp (long_options[option_index].name, "cfactor") == 0)
2449           {
2450 
2451 
2452             if (update_arg( (void *)&(args_info->cfactor_arg),
2453                  &(args_info->cfactor_orig), &(args_info->cfactor_given),
2454                 &(local_args_info.cfactor_given), optarg, 0, "1.0", ARG_DOUBLE,
2455                 check_ambiguity, override, 0, 0,
2456                 "cfactor", '-',
2457                 additional_error))
2458               goto failure;
2459 
2460           }
2461           /* Set the penalty for non-compatible sequences in the covariance term of the energy function
2462 
2463 .  */
2464           else if (strcmp (long_options[option_index].name, "nfactor") == 0)
2465           {
2466 
2467 
2468             if (update_arg( (void *)&(args_info->nfactor_arg),
2469                  &(args_info->nfactor_orig), &(args_info->nfactor_given),
2470                 &(local_args_info.nfactor_given), optarg, 0, "1.0", ARG_DOUBLE,
2471                 check_ambiguity, override, 0, 0,
2472                 "nfactor", '-',
2473                 additional_error))
2474               goto failure;
2475 
2476           }
2477 
2478           break;
2479         case '?':	/* Invalid option.  */
2480           /* `getopt_long' already printed an error message.  */
2481           goto failure;
2482 
2483         default:	/* bug: option not considered.  */
2484           fprintf (stderr, "%s: option unknown: %c%s\n", RNALALIFOLD_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
2485           abort ();
2486         } /* switch */
2487     } /* while */
2488 
2489 
2490   update_multiple_arg((void *)&(args_info->shape_arg),
2491     &(args_info->shape_orig), args_info->shape_given,
2492     local_args_info.shape_given, 0,
2493     ARG_STRING, shape_list);
2494 
2495   args_info->shape_given += local_args_info.shape_given;
2496   local_args_info.shape_given = 0;
2497 
2498   if (check_required)
2499     {
2500       error_occurred += RNALalifold_cmdline_parser_required2 (args_info, argv[0], additional_error);
2501     }
2502 
2503   RNALalifold_cmdline_parser_release (&local_args_info);
2504 
2505   if ( error_occurred )
2506     return (EXIT_FAILURE);
2507 
2508   if (optind < argc)
2509     {
2510       int i = 0 ;
2511       int found_prog_name = 0;
2512       /* whether program name, i.e., argv[0], is in the remaining args
2513          (this may happen with some implementations of getopt,
2514           but surely not with the one included by gengetopt) */
2515 
2516 
2517       args_info->inputs_num = argc - optind - found_prog_name;
2518       args_info->inputs =
2519         (char **)(malloc ((args_info->inputs_num)*sizeof(char *))) ;
2520       while (optind < argc)
2521         args_info->inputs[ i++ ] = gengetopt_strdup (argv[optind++]) ;
2522     }
2523 
2524   return 0;
2525 
2526 failure:
2527   free_list (shape_list, 1 );
2528 
2529   RNALalifold_cmdline_parser_release (&local_args_info);
2530   return (EXIT_FAILURE);
2531 }
2532 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
2533