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