1 /*
2 File autogenerated by gengetopt version 2.23
3 generated with the following command:
4 /usr/bin/gengetopt -i RNApdist.ggo --file-name=RNApdist_cmdl --include-getopt --default-optional --func-name=RNApdist_cmdline_parser --arg-struct-name=RNApdist_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 "RNApdist_cmdl.h"
26
27 const char *RNApdist_args_info_purpose = "Calculate distances between thermodynamic RNA secondary structures ensembles";
28
29 const char *RNApdist_args_info_usage = "Usage: RNApdist [OPTION]...";
30
31 const char *RNApdist_args_info_versiontext = "";
32
33 const char *RNApdist_args_info_description = "This program reads RNA sequences from stdin and calculates structure distances\nbetween the thermodynamic ensembles of their secondary structures.\n";
34
35 const char *RNApdist_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 " --noconv Do not automatically substitude nucleotide\n \"T\" with \"U\"\n\n (default=off)",
42 "\nAlgorithms:",
43 " -X, --compare=p|m|f|c Specify the comparison directive.\n (default=`p')",
44 " Possible arguments for this option are: -Xp compare the structures pairwise\n (p), i.e. first with 2nd, third with 4th etc.\n -Xm calculate the distance matrix between all structures. The output is\n formatted as a lower triangle matrix.\n -Xf compare each structure to the first one.\n -Xc compare continuously, that is i-th with (i+1)th structure.\n\n",
45 " -B, --backtrack[=<filename>] Print an \"alignment\" with gaps of the\n profiles. The aligned structures are written\n to <filename>, if specified.\n (default=`none')",
46 " Within the profile output, the following symbols will be used:\n\n () essentially upstream (downstream) paired bases\n\n {} weakly upstream (downstream) paired bases\n\n | strongly paired bases without preference\n\n , weakly paired bases without preference\n\n . essentially unpaired bases.\n\n If <filename> is not specified, the output is written to stdout, unless the\n \"-Xm\" option is set in which case \"backtrack.file\" is used.\n\n",
47 "\nModel Details:",
48 " -T, --temp=DOUBLE Rescale energy parameters to a temperature of\n temp C. Default is 37C.\n\n",
49 " -4, --noTetra Do not include special tabulated stabilizing\n energies for tri-, tetra- and hexaloop\n hairpins. Mostly for testing.\n\n (default=off)",
50 " -d, --dangles=INT set energy model for treatment of dangling\n bases\n\n (possible values=\"0\", \"2\" default=`2')",
51 " --noLP Produce structures without lonely pairs\n (helices of length 1).\n (default=off)",
52 " 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",
53 " --noGU Do not allow GU pairs\n\n (default=off)",
54 " --noClosingGU Do not allow GU pairs at the end of helices\n\n (default=off)",
55 " -P, --paramFile=paramfile Read energy parameters from paramfile, instead\n of using the default parameter set.\n",
56 " 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",
57 " --nsp=STRING Allow other pairs in addition to the usual\n AU,GC,and GU pairs.\n",
58 " 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",
59 " -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",
60 "\nIf in doubt our program is right, nature is at fault.\nComments should be sent to rna@tbi.univie.ac.at.\n\n",
61 0
62 };
63 static void
init_full_help_array(void)64 init_full_help_array(void)
65 {
66 RNApdist_args_info_full_help[0] = RNApdist_args_info_detailed_help[0];
67 RNApdist_args_info_full_help[1] = RNApdist_args_info_detailed_help[1];
68 RNApdist_args_info_full_help[2] = RNApdist_args_info_detailed_help[2];
69 RNApdist_args_info_full_help[3] = RNApdist_args_info_detailed_help[3];
70 RNApdist_args_info_full_help[4] = RNApdist_args_info_detailed_help[4];
71 RNApdist_args_info_full_help[5] = RNApdist_args_info_detailed_help[5];
72 RNApdist_args_info_full_help[6] = RNApdist_args_info_detailed_help[6];
73 RNApdist_args_info_full_help[7] = RNApdist_args_info_detailed_help[7];
74 RNApdist_args_info_full_help[8] = RNApdist_args_info_detailed_help[9];
75 RNApdist_args_info_full_help[9] = RNApdist_args_info_detailed_help[11];
76 RNApdist_args_info_full_help[10] = RNApdist_args_info_detailed_help[12];
77 RNApdist_args_info_full_help[11] = RNApdist_args_info_detailed_help[13];
78 RNApdist_args_info_full_help[12] = RNApdist_args_info_detailed_help[14];
79 RNApdist_args_info_full_help[13] = RNApdist_args_info_detailed_help[15];
80 RNApdist_args_info_full_help[14] = RNApdist_args_info_detailed_help[17];
81 RNApdist_args_info_full_help[15] = RNApdist_args_info_detailed_help[18];
82 RNApdist_args_info_full_help[16] = RNApdist_args_info_detailed_help[19];
83 RNApdist_args_info_full_help[17] = RNApdist_args_info_detailed_help[21];
84 RNApdist_args_info_full_help[18] = RNApdist_args_info_detailed_help[23];
85 RNApdist_args_info_full_help[19] = RNApdist_args_info_detailed_help[24];
86 RNApdist_args_info_full_help[20] = 0;
87
88 }
89
90 const char *RNApdist_args_info_full_help[21];
91
92 static void
init_help_array(void)93 init_help_array(void)
94 {
95 RNApdist_args_info_help[0] = RNApdist_args_info_detailed_help[0];
96 RNApdist_args_info_help[1] = RNApdist_args_info_detailed_help[1];
97 RNApdist_args_info_help[2] = RNApdist_args_info_detailed_help[2];
98 RNApdist_args_info_help[3] = RNApdist_args_info_detailed_help[3];
99 RNApdist_args_info_help[4] = RNApdist_args_info_detailed_help[4];
100 RNApdist_args_info_help[5] = RNApdist_args_info_detailed_help[5];
101 RNApdist_args_info_help[6] = RNApdist_args_info_detailed_help[6];
102 RNApdist_args_info_help[7] = RNApdist_args_info_detailed_help[7];
103 RNApdist_args_info_help[8] = RNApdist_args_info_detailed_help[9];
104 RNApdist_args_info_help[9] = RNApdist_args_info_detailed_help[11];
105 RNApdist_args_info_help[10] = RNApdist_args_info_detailed_help[12];
106 RNApdist_args_info_help[11] = RNApdist_args_info_detailed_help[13];
107 RNApdist_args_info_help[12] = RNApdist_args_info_detailed_help[14];
108 RNApdist_args_info_help[13] = RNApdist_args_info_detailed_help[15];
109 RNApdist_args_info_help[14] = RNApdist_args_info_detailed_help[17];
110 RNApdist_args_info_help[15] = RNApdist_args_info_detailed_help[18];
111 RNApdist_args_info_help[16] = RNApdist_args_info_detailed_help[19];
112 RNApdist_args_info_help[17] = RNApdist_args_info_detailed_help[24];
113 RNApdist_args_info_help[18] = 0;
114
115 }
116
117 const char *RNApdist_args_info_help[19];
118
119 typedef enum {ARG_NO
120 , ARG_FLAG
121 , ARG_STRING
122 , ARG_INT
123 , ARG_DOUBLE
124 } RNApdist_cmdline_parser_arg_type;
125
126 static
127 void clear_given (struct RNApdist_args_info *args_info);
128 static
129 void clear_args (struct RNApdist_args_info *args_info);
130
131 static int
132 RNApdist_cmdline_parser_internal (int argc, char **argv, struct RNApdist_args_info *args_info,
133 struct RNApdist_cmdline_parser_params *params, const char *additional_error);
134
135
136 const char *RNApdist_cmdline_parser_dangles_values[] = {"0", "2", 0}; /*< Possible values for dangles. */
137
138 static char *
139 gengetopt_strdup (const char *s);
140
141 static
clear_given(struct RNApdist_args_info * args_info)142 void clear_given (struct RNApdist_args_info *args_info)
143 {
144 args_info->help_given = 0 ;
145 args_info->detailed_help_given = 0 ;
146 args_info->full_help_given = 0 ;
147 args_info->version_given = 0 ;
148 args_info->noconv_given = 0 ;
149 args_info->compare_given = 0 ;
150 args_info->backtrack_given = 0 ;
151 args_info->temp_given = 0 ;
152 args_info->noTetra_given = 0 ;
153 args_info->dangles_given = 0 ;
154 args_info->noLP_given = 0 ;
155 args_info->noGU_given = 0 ;
156 args_info->noClosingGU_given = 0 ;
157 args_info->paramFile_given = 0 ;
158 args_info->nsp_given = 0 ;
159 args_info->energyModel_given = 0 ;
160 }
161
162 static
clear_args(struct RNApdist_args_info * args_info)163 void clear_args (struct RNApdist_args_info *args_info)
164 {
165 FIX_UNUSED (args_info);
166 args_info->noconv_flag = 0;
167 args_info->compare_arg = gengetopt_strdup ("p");
168 args_info->compare_orig = NULL;
169 args_info->backtrack_arg = gengetopt_strdup ("none");
170 args_info->backtrack_orig = NULL;
171 args_info->temp_orig = NULL;
172 args_info->noTetra_flag = 0;
173 args_info->dangles_arg = 2;
174 args_info->dangles_orig = NULL;
175 args_info->noLP_flag = 0;
176 args_info->noGU_flag = 0;
177 args_info->noClosingGU_flag = 0;
178 args_info->paramFile_arg = NULL;
179 args_info->paramFile_orig = NULL;
180 args_info->nsp_arg = NULL;
181 args_info->nsp_orig = NULL;
182 args_info->energyModel_orig = NULL;
183
184 }
185
186 static
init_args_info(struct RNApdist_args_info * args_info)187 void init_args_info(struct RNApdist_args_info *args_info)
188 {
189 init_full_help_array();
190 init_help_array();
191 args_info->help_help = RNApdist_args_info_detailed_help[0] ;
192 args_info->detailed_help_help = RNApdist_args_info_detailed_help[1] ;
193 args_info->full_help_help = RNApdist_args_info_detailed_help[2] ;
194 args_info->version_help = RNApdist_args_info_detailed_help[3] ;
195 args_info->noconv_help = RNApdist_args_info_detailed_help[5] ;
196 args_info->compare_help = RNApdist_args_info_detailed_help[7] ;
197 args_info->backtrack_help = RNApdist_args_info_detailed_help[9] ;
198 args_info->temp_help = RNApdist_args_info_detailed_help[12] ;
199 args_info->noTetra_help = RNApdist_args_info_detailed_help[13] ;
200 args_info->dangles_help = RNApdist_args_info_detailed_help[14] ;
201 args_info->noLP_help = RNApdist_args_info_detailed_help[15] ;
202 args_info->noGU_help = RNApdist_args_info_detailed_help[17] ;
203 args_info->noClosingGU_help = RNApdist_args_info_detailed_help[18] ;
204 args_info->paramFile_help = RNApdist_args_info_detailed_help[19] ;
205 args_info->nsp_help = RNApdist_args_info_detailed_help[21] ;
206 args_info->energyModel_help = RNApdist_args_info_detailed_help[23] ;
207
208 }
209
210 void
RNApdist_cmdline_parser_print_version(void)211 RNApdist_cmdline_parser_print_version (void)
212 {
213 printf ("%s %s\n",
214 (strlen(RNAPDIST_CMDLINE_PARSER_PACKAGE_NAME) ? RNAPDIST_CMDLINE_PARSER_PACKAGE_NAME : RNAPDIST_CMDLINE_PARSER_PACKAGE),
215 RNAPDIST_CMDLINE_PARSER_VERSION);
216
217 if (strlen(RNApdist_args_info_versiontext) > 0)
218 printf("\n%s\n", RNApdist_args_info_versiontext);
219 }
220
print_help_common(void)221 static void print_help_common(void)
222 {
223 size_t len_purpose = strlen(RNApdist_args_info_purpose);
224 size_t len_usage = strlen(RNApdist_args_info_usage);
225
226 if (len_usage > 0) {
227 printf("%s\n", RNApdist_args_info_usage);
228 }
229 if (len_purpose > 0) {
230 printf("%s\n", RNApdist_args_info_purpose);
231 }
232
233 if (len_usage || len_purpose) {
234 printf("\n");
235 }
236
237 if (strlen(RNApdist_args_info_description) > 0) {
238 printf("%s\n\n", RNApdist_args_info_description);
239 }
240 }
241
242 void
RNApdist_cmdline_parser_print_help(void)243 RNApdist_cmdline_parser_print_help (void)
244 {
245 int i = 0;
246 print_help_common();
247 while (RNApdist_args_info_help[i])
248 printf("%s\n", RNApdist_args_info_help[i++]);
249 }
250
251 void
RNApdist_cmdline_parser_print_full_help(void)252 RNApdist_cmdline_parser_print_full_help (void)
253 {
254 int i = 0;
255 print_help_common();
256 while (RNApdist_args_info_full_help[i])
257 printf("%s\n", RNApdist_args_info_full_help[i++]);
258 }
259
260 void
RNApdist_cmdline_parser_print_detailed_help(void)261 RNApdist_cmdline_parser_print_detailed_help (void)
262 {
263 int i = 0;
264 print_help_common();
265 while (RNApdist_args_info_detailed_help[i])
266 printf("%s\n", RNApdist_args_info_detailed_help[i++]);
267 }
268
269 void
RNApdist_cmdline_parser_init(struct RNApdist_args_info * args_info)270 RNApdist_cmdline_parser_init (struct RNApdist_args_info *args_info)
271 {
272 clear_given (args_info);
273 clear_args (args_info);
274 init_args_info (args_info);
275 }
276
277 void
RNApdist_cmdline_parser_params_init(struct RNApdist_cmdline_parser_params * params)278 RNApdist_cmdline_parser_params_init(struct RNApdist_cmdline_parser_params *params)
279 {
280 if (params)
281 {
282 params->override = 0;
283 params->initialize = 1;
284 params->check_required = 1;
285 params->check_ambiguity = 0;
286 params->print_errors = 1;
287 }
288 }
289
290 struct RNApdist_cmdline_parser_params *
RNApdist_cmdline_parser_params_create(void)291 RNApdist_cmdline_parser_params_create(void)
292 {
293 struct RNApdist_cmdline_parser_params *params =
294 (struct RNApdist_cmdline_parser_params *)malloc(sizeof(struct RNApdist_cmdline_parser_params));
295 RNApdist_cmdline_parser_params_init(params);
296 return params;
297 }
298
299 static void
free_string_field(char ** s)300 free_string_field (char **s)
301 {
302 if (*s)
303 {
304 free (*s);
305 *s = 0;
306 }
307 }
308
309
310 static void
RNApdist_cmdline_parser_release(struct RNApdist_args_info * args_info)311 RNApdist_cmdline_parser_release (struct RNApdist_args_info *args_info)
312 {
313
314 free_string_field (&(args_info->compare_arg));
315 free_string_field (&(args_info->compare_orig));
316 free_string_field (&(args_info->backtrack_arg));
317 free_string_field (&(args_info->backtrack_orig));
318 free_string_field (&(args_info->temp_orig));
319 free_string_field (&(args_info->dangles_orig));
320 free_string_field (&(args_info->paramFile_arg));
321 free_string_field (&(args_info->paramFile_orig));
322 free_string_field (&(args_info->nsp_arg));
323 free_string_field (&(args_info->nsp_orig));
324 free_string_field (&(args_info->energyModel_orig));
325
326
327
328 clear_given (args_info);
329 }
330
331 /**
332 * @param val the value to check
333 * @param values the possible values
334 * @return the index of the matched value:
335 * -1 if no value matched,
336 * -2 if more than one value has matched
337 */
338 static int
check_possible_values(const char * val,const char * values[])339 check_possible_values(const char *val, const char *values[])
340 {
341 int i, found, last;
342 size_t len;
343
344 if (!val) /* otherwise strlen() crashes below */
345 return -1; /* -1 means no argument for the option */
346
347 found = last = 0;
348
349 for (i = 0, len = strlen(val); values[i]; ++i)
350 {
351 if (strncmp(val, values[i], len) == 0)
352 {
353 ++found;
354 last = i;
355 if (strlen(values[i]) == len)
356 return i; /* exact macth no need to check more */
357 }
358 }
359
360 if (found == 1) /* one match: OK */
361 return last;
362
363 return (found ? -2 : -1); /* return many values or none matched */
364 }
365
366
367 static void
write_into_file(FILE * outfile,const char * opt,const char * arg,const char * values[])368 write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[])
369 {
370 int found = -1;
371 if (arg) {
372 if (values) {
373 found = check_possible_values(arg, values);
374 }
375 if (found >= 0)
376 fprintf(outfile, "%s=\"%s\" # %s\n", opt, arg, values[found]);
377 else
378 fprintf(outfile, "%s=\"%s\"\n", opt, arg);
379 } else {
380 fprintf(outfile, "%s\n", opt);
381 }
382 }
383
384
385 int
RNApdist_cmdline_parser_dump(FILE * outfile,struct RNApdist_args_info * args_info)386 RNApdist_cmdline_parser_dump(FILE *outfile, struct RNApdist_args_info *args_info)
387 {
388 int i = 0;
389
390 if (!outfile)
391 {
392 fprintf (stderr, "%s: cannot dump options to stream\n", RNAPDIST_CMDLINE_PARSER_PACKAGE);
393 return EXIT_FAILURE;
394 }
395
396 if (args_info->help_given)
397 write_into_file(outfile, "help", 0, 0 );
398 if (args_info->detailed_help_given)
399 write_into_file(outfile, "detailed-help", 0, 0 );
400 if (args_info->full_help_given)
401 write_into_file(outfile, "full-help", 0, 0 );
402 if (args_info->version_given)
403 write_into_file(outfile, "version", 0, 0 );
404 if (args_info->noconv_given)
405 write_into_file(outfile, "noconv", 0, 0 );
406 if (args_info->compare_given)
407 write_into_file(outfile, "compare", args_info->compare_orig, 0);
408 if (args_info->backtrack_given)
409 write_into_file(outfile, "backtrack", args_info->backtrack_orig, 0);
410 if (args_info->temp_given)
411 write_into_file(outfile, "temp", args_info->temp_orig, 0);
412 if (args_info->noTetra_given)
413 write_into_file(outfile, "noTetra", 0, 0 );
414 if (args_info->dangles_given)
415 write_into_file(outfile, "dangles", args_info->dangles_orig, RNApdist_cmdline_parser_dangles_values);
416 if (args_info->noLP_given)
417 write_into_file(outfile, "noLP", 0, 0 );
418 if (args_info->noGU_given)
419 write_into_file(outfile, "noGU", 0, 0 );
420 if (args_info->noClosingGU_given)
421 write_into_file(outfile, "noClosingGU", 0, 0 );
422 if (args_info->paramFile_given)
423 write_into_file(outfile, "paramFile", args_info->paramFile_orig, 0);
424 if (args_info->nsp_given)
425 write_into_file(outfile, "nsp", args_info->nsp_orig, 0);
426 if (args_info->energyModel_given)
427 write_into_file(outfile, "energyModel", args_info->energyModel_orig, 0);
428
429
430 i = EXIT_SUCCESS;
431 return i;
432 }
433
434 int
RNApdist_cmdline_parser_file_save(const char * filename,struct RNApdist_args_info * args_info)435 RNApdist_cmdline_parser_file_save(const char *filename, struct RNApdist_args_info *args_info)
436 {
437 FILE *outfile;
438 int i = 0;
439
440 outfile = fopen(filename, "w");
441
442 if (!outfile)
443 {
444 fprintf (stderr, "%s: cannot open file for writing: %s\n", RNAPDIST_CMDLINE_PARSER_PACKAGE, filename);
445 return EXIT_FAILURE;
446 }
447
448 i = RNApdist_cmdline_parser_dump(outfile, args_info);
449 fclose (outfile);
450
451 return i;
452 }
453
454 void
RNApdist_cmdline_parser_free(struct RNApdist_args_info * args_info)455 RNApdist_cmdline_parser_free (struct RNApdist_args_info *args_info)
456 {
457 RNApdist_cmdline_parser_release (args_info);
458 }
459
460 /** @brief replacement of strdup, which is not standard */
461 char *
gengetopt_strdup(const char * s)462 gengetopt_strdup (const char *s)
463 {
464 char *result = 0;
465 if (!s)
466 return result;
467
468 result = (char*)malloc(strlen(s) + 1);
469 if (result == (char*)0)
470 return (char*)0;
471 strcpy(result, s);
472 return result;
473 }
474
475 int
RNApdist_cmdline_parser(int argc,char ** argv,struct RNApdist_args_info * args_info)476 RNApdist_cmdline_parser (int argc, char **argv, struct RNApdist_args_info *args_info)
477 {
478 return RNApdist_cmdline_parser2 (argc, argv, args_info, 0, 1, 1);
479 }
480
481 int
RNApdist_cmdline_parser_ext(int argc,char ** argv,struct RNApdist_args_info * args_info,struct RNApdist_cmdline_parser_params * params)482 RNApdist_cmdline_parser_ext (int argc, char **argv, struct RNApdist_args_info *args_info,
483 struct RNApdist_cmdline_parser_params *params)
484 {
485 int result;
486 result = RNApdist_cmdline_parser_internal (argc, argv, args_info, params, 0);
487
488 if (result == EXIT_FAILURE)
489 {
490 RNApdist_cmdline_parser_free (args_info);
491 exit (EXIT_FAILURE);
492 }
493
494 return result;
495 }
496
497 int
RNApdist_cmdline_parser2(int argc,char ** argv,struct RNApdist_args_info * args_info,int override,int initialize,int check_required)498 RNApdist_cmdline_parser2 (int argc, char **argv, struct RNApdist_args_info *args_info, int override, int initialize, int check_required)
499 {
500 int result;
501 struct RNApdist_cmdline_parser_params params;
502
503 params.override = override;
504 params.initialize = initialize;
505 params.check_required = check_required;
506 params.check_ambiguity = 0;
507 params.print_errors = 1;
508
509 result = RNApdist_cmdline_parser_internal (argc, argv, args_info, ¶ms, 0);
510
511 if (result == EXIT_FAILURE)
512 {
513 RNApdist_cmdline_parser_free (args_info);
514 exit (EXIT_FAILURE);
515 }
516
517 return result;
518 }
519
520 int
RNApdist_cmdline_parser_required(struct RNApdist_args_info * args_info,const char * prog_name)521 RNApdist_cmdline_parser_required (struct RNApdist_args_info *args_info, const char *prog_name)
522 {
523 FIX_UNUSED (args_info);
524 FIX_UNUSED (prog_name);
525 return EXIT_SUCCESS;
526 }
527
528 /*
529 * Extracted from the glibc source tree, version 2.3.6
530 *
531 * Licensed under the GPL as per the whole glibc source tree.
532 *
533 * This file was modified so that getopt_long can be called
534 * many times without risking previous memory to be spoiled.
535 *
536 * Modified by Andre Noll and Lorenzo Bettini for use in
537 * GNU gengetopt generated files.
538 *
539 */
540
541 /*
542 * we must include anything we need since this file is not thought to be
543 * inserted in a file already using getopt.h
544 *
545 * Lorenzo
546 */
547
548 struct option
549 {
550 const char *name;
551 /* has_arg can't be an enum because some compilers complain about
552 type mismatches in all the code that assumes it is an int. */
553 int has_arg;
554 int *flag;
555 int val;
556 };
557
558 /* This version of `getopt' appears to the caller like standard Unix `getopt'
559 but it behaves differently for the user, since it allows the user
560 to intersperse the options with the other arguments.
561
562 As `getopt' works, it permutes the elements of ARGV so that,
563 when it is done, all the options precede everything else. Thus
564 all application programs are extended to handle flexible argument order.
565 */
566 /*
567 If the field `flag' is not NULL, it points to a variable that is set
568 to the value given in the field `val' when the option is found, but
569 left unchanged if the option is not found.
570
571 To have a long-named option do something other than set an `int' to
572 a compiled-in constant, such as set a value from `custom_optarg', set the
573 option's `flag' field to zero and its `val' field to a nonzero
574 value (the equivalent single-letter option character, if there is
575 one). For long options that have a zero `flag' field, `getopt'
576 returns the contents of the `val' field. */
577
578 /* Names for the values of the `has_arg' field of `struct option'. */
579 #ifndef no_argument
580 #define no_argument 0
581 #endif
582
583 #ifndef required_argument
584 #define required_argument 1
585 #endif
586
587 #ifndef optional_argument
588 #define optional_argument 2
589 #endif
590
591 struct custom_getopt_data {
592 /*
593 * These have exactly the same meaning as the corresponding global variables,
594 * except that they are used for the reentrant versions of getopt.
595 */
596 int custom_optind;
597 int custom_opterr;
598 int custom_optopt;
599 char *custom_optarg;
600
601 /* True if the internal members have been initialized. */
602 int initialized;
603
604 /*
605 * The next char to be scanned in the option-element in which the last option
606 * character we returned was found. This allows us to pick up the scan where
607 * we left off. If this is zero, or a null string, it means resume the scan by
608 * advancing to the next ARGV-element.
609 */
610 char *nextchar;
611
612 /*
613 * Describe the part of ARGV that contains non-options that have been skipped.
614 * `first_nonopt' is the index in ARGV of the first of them; `last_nonopt' is
615 * the index after the last of them.
616 */
617 int first_nonopt;
618 int last_nonopt;
619 };
620
621 /*
622 * the variables optarg, optind, opterr and optopt are renamed with
623 * the custom_ prefix so that they don't interfere with getopt ones.
624 *
625 * Moreover they're static so they are visible only from within the
626 * file where this very file will be included.
627 */
628
629 /*
630 * For communication from `custom_getopt' to the caller. When `custom_getopt' finds an
631 * option that takes an argument, the argument value is returned here.
632 */
633 static char *custom_optarg;
634
635 /*
636 * Index in ARGV of the next element to be scanned. This is used for
637 * communication to and from the caller and for communication between
638 * successive calls to `custom_getopt'.
639 *
640 * On entry to `custom_getopt', 1 means this is the first call; initialize.
641 *
642 * When `custom_getopt' returns -1, this is the index of the first of the non-option
643 * elements that the caller should itself scan.
644 *
645 * Otherwise, `custom_optind' communicates from one call to the next how much of ARGV
646 * has been scanned so far.
647 *
648 * 1003.2 says this must be 1 before any call.
649 */
650 static int custom_optind = 1;
651
652 /*
653 * Callers store zero here to inhibit the error message for unrecognized
654 * options.
655 */
656 static int custom_opterr = 1;
657
658 /*
659 * Set to an option character which was unrecognized. This must be initialized
660 * on some systems to avoid linking in the system's own getopt implementation.
661 */
662 static int custom_optopt = '?';
663
664 /*
665 * Exchange two adjacent subsequences of ARGV. One subsequence is elements
666 * [first_nonopt,last_nonopt) which contains all the non-options that have been
667 * skipped so far. The other is elements [last_nonopt,custom_optind), which contains
668 * all the options processed since those non-options were skipped.
669 * `first_nonopt' and `last_nonopt' are relocated so that they describe the new
670 * indices of the non-options in ARGV after they are moved.
671 */
exchange(char ** argv,struct custom_getopt_data * d)672 static void exchange(char **argv, struct custom_getopt_data *d)
673 {
674 int bottom = d->first_nonopt;
675 int middle = d->last_nonopt;
676 int top = d->custom_optind;
677 char *tem;
678
679 /*
680 * Exchange the shorter segment with the far end of the longer segment.
681 * That puts the shorter segment into the right place. It leaves the
682 * longer segment in the right place overall, but it consists of two
683 * parts that need to be swapped next.
684 */
685 while (top > middle && middle > bottom) {
686 if (top - middle > middle - bottom) {
687 /* Bottom segment is the short one. */
688 int len = middle - bottom;
689 int i;
690
691 /* Swap it with the top part of the top segment. */
692 for (i = 0; i < len; i++) {
693 tem = argv[bottom + i];
694 argv[bottom + i] =
695 argv[top - (middle - bottom) + i];
696 argv[top - (middle - bottom) + i] = tem;
697 }
698 /* Exclude the moved bottom segment from further swapping. */
699 top -= len;
700 } else {
701 /* Top segment is the short one. */
702 int len = top - middle;
703 int i;
704
705 /* Swap it with the bottom part of the bottom segment. */
706 for (i = 0; i < len; i++) {
707 tem = argv[bottom + i];
708 argv[bottom + i] = argv[middle + i];
709 argv[middle + i] = tem;
710 }
711 /* Exclude the moved top segment from further swapping. */
712 bottom += len;
713 }
714 }
715 /* Update records for the slots the non-options now occupy. */
716 d->first_nonopt += (d->custom_optind - d->last_nonopt);
717 d->last_nonopt = d->custom_optind;
718 }
719
720 /* Initialize the internal data when the first call is made. */
custom_getopt_initialize(struct custom_getopt_data * d)721 static void custom_getopt_initialize(struct custom_getopt_data *d)
722 {
723 /*
724 * Start processing options with ARGV-element 1 (since ARGV-element 0
725 * is the program name); the sequence of previously skipped non-option
726 * ARGV-elements is empty.
727 */
728 d->first_nonopt = d->last_nonopt = d->custom_optind;
729 d->nextchar = NULL;
730 d->initialized = 1;
731 }
732
733 #define NONOPTION_P (argv[d->custom_optind][0] != '-' || argv[d->custom_optind][1] == '\0')
734
735 /* 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)736 static int shuffle_argv(int argc, char *const *argv,const struct option *longopts,
737 struct custom_getopt_data *d)
738 {
739 /*
740 * Give FIRST_NONOPT & LAST_NONOPT rational values if CUSTOM_OPTIND has been
741 * moved back by the user (who may also have changed the arguments).
742 */
743 if (d->last_nonopt > d->custom_optind)
744 d->last_nonopt = d->custom_optind;
745 if (d->first_nonopt > d->custom_optind)
746 d->first_nonopt = d->custom_optind;
747 /*
748 * If we have just processed some options following some
749 * non-options, exchange them so that the options come first.
750 */
751 if (d->first_nonopt != d->last_nonopt &&
752 d->last_nonopt != d->custom_optind)
753 exchange((char **) argv, d);
754 else if (d->last_nonopt != d->custom_optind)
755 d->first_nonopt = d->custom_optind;
756 /*
757 * Skip any additional non-options and extend the range of
758 * non-options previously skipped.
759 */
760 while (d->custom_optind < argc && NONOPTION_P)
761 d->custom_optind++;
762 d->last_nonopt = d->custom_optind;
763 /*
764 * The special ARGV-element `--' means premature end of options. Skip
765 * it like a null option, then exchange with previous non-options as if
766 * it were an option, then skip everything else like a non-option.
767 */
768 if (d->custom_optind != argc && !strcmp(argv[d->custom_optind], "--")) {
769 d->custom_optind++;
770 if (d->first_nonopt != d->last_nonopt
771 && d->last_nonopt != d->custom_optind)
772 exchange((char **) argv, d);
773 else if (d->first_nonopt == d->last_nonopt)
774 d->first_nonopt = d->custom_optind;
775 d->last_nonopt = argc;
776 d->custom_optind = argc;
777 }
778 /*
779 * If we have done all the ARGV-elements, stop the scan and back over
780 * any non-options that we skipped and permuted.
781 */
782 if (d->custom_optind == argc) {
783 /*
784 * Set the next-arg-index to point at the non-options that we
785 * previously skipped, so the caller will digest them.
786 */
787 if (d->first_nonopt != d->last_nonopt)
788 d->custom_optind = d->first_nonopt;
789 return -1;
790 }
791 /*
792 * If we have come to a non-option and did not permute it, either stop
793 * the scan or describe it to the caller and pass it by.
794 */
795 if (NONOPTION_P) {
796 d->custom_optarg = argv[d->custom_optind++];
797 return 1;
798 }
799 /*
800 * We have found another option-ARGV-element. Skip the initial
801 * punctuation.
802 */
803 d->nextchar = (argv[d->custom_optind] + 1 + (longopts != NULL && argv[d->custom_optind][1] == '-'));
804 return 0;
805 }
806
807 /*
808 * Check whether the ARGV-element is a long option.
809 *
810 * If there's a long option "fubar" and the ARGV-element is "-fu", consider
811 * that an abbreviation of the long option, just like "--fu", and not "-f" with
812 * arg "u".
813 *
814 * This distinction seems to be the most useful approach.
815 *
816 */
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)817 static int check_long_opt(int argc, char *const *argv, const char *optstring,
818 const struct option *longopts, int *longind,
819 int print_errors, struct custom_getopt_data *d)
820 {
821 char *nameend;
822 const struct option *p;
823 const struct option *pfound = NULL;
824 int exact = 0;
825 int ambig = 0;
826 int indfound = -1;
827 int option_index;
828
829 for (nameend = d->nextchar; *nameend && *nameend != '='; nameend++)
830 /* Do nothing. */ ;
831
832 /* Test all long options for either exact match or abbreviated matches */
833 for (p = longopts, option_index = 0; p->name; p++, option_index++)
834 if (!strncmp(p->name, d->nextchar, nameend - d->nextchar)) {
835 if ((unsigned int) (nameend - d->nextchar)
836 == (unsigned int) strlen(p->name)) {
837 /* Exact match found. */
838 pfound = p;
839 indfound = option_index;
840 exact = 1;
841 break;
842 } else if (pfound == NULL) {
843 /* First nonexact match found. */
844 pfound = p;
845 indfound = option_index;
846 } else if (pfound->has_arg != p->has_arg
847 || pfound->flag != p->flag
848 || pfound->val != p->val)
849 /* Second or later nonexact match found. */
850 ambig = 1;
851 }
852 if (ambig && !exact) {
853 if (print_errors) {
854 fprintf(stderr,
855 "%s: option `%s' is ambiguous\n",
856 argv[0], argv[d->custom_optind]);
857 }
858 d->nextchar += strlen(d->nextchar);
859 d->custom_optind++;
860 d->custom_optopt = 0;
861 return '?';
862 }
863 if (pfound) {
864 option_index = indfound;
865 d->custom_optind++;
866 if (*nameend) {
867 if (pfound->has_arg != no_argument)
868 d->custom_optarg = nameend + 1;
869 else {
870 if (print_errors) {
871 if (argv[d->custom_optind - 1][1] == '-') {
872 /* --option */
873 fprintf(stderr, "%s: option `--%s' doesn't allow an argument\n",
874 argv[0], pfound->name);
875 } else {
876 /* +option or -option */
877 fprintf(stderr, "%s: option `%c%s' doesn't allow an argument\n",
878 argv[0], argv[d->custom_optind - 1][0], pfound->name);
879 }
880
881 }
882 d->nextchar += strlen(d->nextchar);
883 d->custom_optopt = pfound->val;
884 return '?';
885 }
886 } else if (pfound->has_arg == required_argument) {
887 if (d->custom_optind < argc)
888 d->custom_optarg = argv[d->custom_optind++];
889 else {
890 if (print_errors) {
891 fprintf(stderr,
892 "%s: option `%s' requires an argument\n",
893 argv[0],
894 argv[d->custom_optind - 1]);
895 }
896 d->nextchar += strlen(d->nextchar);
897 d->custom_optopt = pfound->val;
898 return optstring[0] == ':' ? ':' : '?';
899 }
900 }
901 d->nextchar += strlen(d->nextchar);
902 if (longind != NULL)
903 *longind = option_index;
904 if (pfound->flag) {
905 *(pfound->flag) = pfound->val;
906 return 0;
907 }
908 return pfound->val;
909 }
910 /*
911 * Can't find it as a long option. If this is not getopt_long_only, or
912 * the option starts with '--' or is not a valid short option, then
913 * it's an error. Otherwise interpret it as a short option.
914 */
915 if (print_errors) {
916 if (argv[d->custom_optind][1] == '-') {
917 /* --option */
918 fprintf(stderr,
919 "%s: unrecognized option `--%s'\n",
920 argv[0], d->nextchar);
921 } else {
922 /* +option or -option */
923 fprintf(stderr,
924 "%s: unrecognized option `%c%s'\n",
925 argv[0], argv[d->custom_optind][0],
926 d->nextchar);
927 }
928 }
929 d->nextchar = (char *) "";
930 d->custom_optind++;
931 d->custom_optopt = 0;
932 return '?';
933 }
934
check_short_opt(int argc,char * const * argv,const char * optstring,int print_errors,struct custom_getopt_data * d)935 static int check_short_opt(int argc, char *const *argv, const char *optstring,
936 int print_errors, struct custom_getopt_data *d)
937 {
938 char c = *d->nextchar++;
939 const char *temp = strchr(optstring, c);
940
941 /* Increment `custom_optind' when we start to process its last character. */
942 if (*d->nextchar == '\0')
943 ++d->custom_optind;
944 if (!temp || c == ':') {
945 if (print_errors)
946 fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
947
948 d->custom_optopt = c;
949 return '?';
950 }
951 if (temp[1] == ':') {
952 if (temp[2] == ':') {
953 /* This is an option that accepts an argument optionally. */
954 if (*d->nextchar != '\0') {
955 d->custom_optarg = d->nextchar;
956 d->custom_optind++;
957 } else
958 d->custom_optarg = NULL;
959 d->nextchar = NULL;
960 } else {
961 /* This is an option that requires an argument. */
962 if (*d->nextchar != '\0') {
963 d->custom_optarg = d->nextchar;
964 /*
965 * If we end this ARGV-element by taking the
966 * rest as an arg, we must advance to the next
967 * element now.
968 */
969 d->custom_optind++;
970 } else if (d->custom_optind == argc) {
971 if (print_errors) {
972 fprintf(stderr,
973 "%s: option requires an argument -- %c\n",
974 argv[0], c);
975 }
976 d->custom_optopt = c;
977 if (optstring[0] == ':')
978 c = ':';
979 else
980 c = '?';
981 } else
982 /*
983 * We already incremented `custom_optind' once;
984 * increment it again when taking next ARGV-elt
985 * as argument.
986 */
987 d->custom_optarg = argv[d->custom_optind++];
988 d->nextchar = NULL;
989 }
990 }
991 return c;
992 }
993
994 /*
995 * Scan elements of ARGV for option characters given in OPTSTRING.
996 *
997 * If an element of ARGV starts with '-', and is not exactly "-" or "--",
998 * then it is an option element. The characters of this element
999 * (aside from the initial '-') are option characters. If `getopt'
1000 * is called repeatedly, it returns successively each of the option characters
1001 * from each of the option elements.
1002 *
1003 * If `getopt' finds another option character, it returns that character,
1004 * updating `custom_optind' and `nextchar' so that the next call to `getopt' can
1005 * resume the scan with the following option character or ARGV-element.
1006 *
1007 * If there are no more option characters, `getopt' returns -1.
1008 * Then `custom_optind' is the index in ARGV of the first ARGV-element
1009 * that is not an option. (The ARGV-elements have been permuted
1010 * so that those that are not options now come last.)
1011 *
1012 * OPTSTRING is a string containing the legitimate option characters.
1013 * If an option character is seen that is not listed in OPTSTRING,
1014 * return '?' after printing an error message. If you set `custom_opterr' to
1015 * zero, the error message is suppressed but we still return '?'.
1016 *
1017 * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
1018 * so the following text in the same ARGV-element, or the text of the following
1019 * ARGV-element, is returned in `custom_optarg'. Two colons mean an option that
1020 * wants an optional arg; if there is text in the current ARGV-element,
1021 * it is returned in `custom_optarg', otherwise `custom_optarg' is set to zero.
1022 *
1023 * If OPTSTRING starts with `-' or `+', it requests different methods of
1024 * handling the non-option ARGV-elements.
1025 * See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
1026 *
1027 * Long-named options begin with `--' instead of `-'.
1028 * Their names may be abbreviated as long as the abbreviation is unique
1029 * or is an exact match for some defined option. If they have an
1030 * argument, it follows the option name in the same ARGV-element, separated
1031 * from the option name by a `=', or else the in next ARGV-element.
1032 * When `getopt' finds a long-named option, it returns 0 if that option's
1033 * `flag' field is nonzero, the value of the option's `val' field
1034 * if the `flag' field is zero.
1035 *
1036 * The elements of ARGV aren't really const, because we permute them.
1037 * But we pretend they're const in the prototype to be compatible
1038 * with other systems.
1039 *
1040 * LONGOPTS is a vector of `struct option' terminated by an
1041 * element containing a name which is zero.
1042 *
1043 * LONGIND returns the index in LONGOPT of the long-named option found.
1044 * It is only valid when a long-named option has been found by the most
1045 * recent call.
1046 *
1047 * Return the option character from OPTS just read. Return -1 when there are
1048 * no more options. For unrecognized options, or options missing arguments,
1049 * `custom_optopt' is set to the option letter, and '?' is returned.
1050 *
1051 * The OPTS string is a list of characters which are recognized option letters,
1052 * optionally followed by colons, specifying that that letter takes an
1053 * argument, to be placed in `custom_optarg'.
1054 *
1055 * If a letter in OPTS is followed by two colons, its argument is optional.
1056 * This behavior is specific to the GNU `getopt'.
1057 *
1058 * The argument `--' causes premature termination of argument scanning,
1059 * explicitly telling `getopt' that there are no more options. If OPTS begins
1060 * with `--', then non-option arguments are treated as arguments to the option
1061 * '\0'. This behavior is specific to the GNU `getopt'.
1062 */
1063
getopt_internal_r(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind,struct custom_getopt_data * d)1064 static int getopt_internal_r(int argc, char *const *argv, const char *optstring,
1065 const struct option *longopts, int *longind,
1066 struct custom_getopt_data *d)
1067 {
1068 int ret, print_errors = d->custom_opterr;
1069
1070 if (optstring[0] == ':')
1071 print_errors = 0;
1072 if (argc < 1)
1073 return -1;
1074 d->custom_optarg = NULL;
1075
1076 /*
1077 * This is a big difference with GNU getopt, since optind == 0
1078 * means initialization while here 1 means first call.
1079 */
1080 if (d->custom_optind == 0 || !d->initialized) {
1081 if (d->custom_optind == 0)
1082 d->custom_optind = 1; /* Don't scan ARGV[0], the program name. */
1083 custom_getopt_initialize(d);
1084 }
1085 if (d->nextchar == NULL || *d->nextchar == '\0') {
1086 ret = shuffle_argv(argc, argv, longopts, d);
1087 if (ret)
1088 return ret;
1089 }
1090 if (longopts && (argv[d->custom_optind][1] == '-' ))
1091 return check_long_opt(argc, argv, optstring, longopts,
1092 longind, print_errors, d);
1093 return check_short_opt(argc, argv, optstring, print_errors, d);
1094 }
1095
custom_getopt_internal(int argc,char * const * argv,const char * optstring,const struct option * longopts,int * longind)1096 static int custom_getopt_internal(int argc, char *const *argv, const char *optstring,
1097 const struct option *longopts, int *longind)
1098 {
1099 int result;
1100 /* Keep a global copy of all internal members of d */
1101 static struct custom_getopt_data d;
1102
1103 d.custom_optind = custom_optind;
1104 d.custom_opterr = custom_opterr;
1105 result = getopt_internal_r(argc, argv, optstring, longopts,
1106 longind, &d);
1107 custom_optind = d.custom_optind;
1108 custom_optarg = d.custom_optarg;
1109 custom_optopt = d.custom_optopt;
1110 return result;
1111 }
1112
custom_getopt_long(int argc,char * const * argv,const char * options,const struct option * long_options,int * opt_index)1113 static int custom_getopt_long (int argc, char *const *argv, const char *options,
1114 const struct option *long_options, int *opt_index)
1115 {
1116 return custom_getopt_internal(argc, argv, options, long_options,
1117 opt_index);
1118 }
1119
1120
1121 static char *package_name = 0;
1122
1123 /**
1124 * @brief updates an option
1125 * @param field the generic pointer to the field to update
1126 * @param orig_field the pointer to the orig field
1127 * @param field_given the pointer to the number of occurrence of this option
1128 * @param prev_given the pointer to the number of occurrence already seen
1129 * @param value the argument for this option (if null no arg was specified)
1130 * @param possible_values the possible values for this option (if specified)
1131 * @param default_value the default value (in case the option only accepts fixed values)
1132 * @param arg_type the type of this option
1133 * @param check_ambiguity @see RNApdist_cmdline_parser_params.check_ambiguity
1134 * @param override @see RNApdist_cmdline_parser_params.override
1135 * @param no_free whether to free a possible previous value
1136 * @param multiple_option whether this is a multiple option
1137 * @param long_opt the corresponding long option
1138 * @param short_opt the corresponding short option (or '-' if none)
1139 * @param additional_error possible further error specification
1140 */
1141 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,RNApdist_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)1142 int update_arg(void *field, char **orig_field,
1143 unsigned int *field_given, unsigned int *prev_given,
1144 char *value, const char *possible_values[],
1145 const char *default_value,
1146 RNApdist_cmdline_parser_arg_type arg_type,
1147 int check_ambiguity, int override,
1148 int no_free, int multiple_option,
1149 const char *long_opt, char short_opt,
1150 const char *additional_error)
1151 {
1152 char *stop_char = 0;
1153 const char *val = value;
1154 int found;
1155 char **string_field;
1156 FIX_UNUSED (field);
1157
1158 stop_char = 0;
1159 found = 0;
1160
1161 if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given)))
1162 {
1163 if (short_opt != '-')
1164 fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n",
1165 package_name, long_opt, short_opt,
1166 (additional_error ? additional_error : ""));
1167 else
1168 fprintf (stderr, "%s: `--%s' option given more than once%s\n",
1169 package_name, long_opt,
1170 (additional_error ? additional_error : ""));
1171 return 1; /* failure */
1172 }
1173
1174 if (possible_values && (found = check_possible_values((value ? value : default_value), possible_values)) < 0)
1175 {
1176 if (short_opt != '-')
1177 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s' (`-%c')%s\n",
1178 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt, short_opt,
1179 (additional_error ? additional_error : ""));
1180 else
1181 fprintf (stderr, "%s: %s argument, \"%s\", for option `--%s'%s\n",
1182 package_name, (found == -2) ? "ambiguous" : "invalid", value, long_opt,
1183 (additional_error ? additional_error : ""));
1184 return 1; /* failure */
1185 }
1186
1187 if (field_given && *field_given && ! override)
1188 return 0;
1189 if (prev_given)
1190 (*prev_given)++;
1191 if (field_given)
1192 (*field_given)++;
1193 if (possible_values)
1194 val = possible_values[found];
1195
1196 switch(arg_type) {
1197 case ARG_FLAG:
1198 *((int *)field) = !*((int *)field);
1199 break;
1200 case ARG_INT:
1201 if (val) *((int *)field) = strtol (val, &stop_char, 0);
1202 break;
1203 case ARG_DOUBLE:
1204 if (val) *((double *)field) = strtod (val, &stop_char);
1205 break;
1206 case ARG_STRING:
1207 if (val) {
1208 string_field = (char **)field;
1209 if (!no_free && *string_field)
1210 free (*string_field); /* free previous string */
1211 *string_field = gengetopt_strdup (val);
1212 }
1213 break;
1214 default:
1215 break;
1216 };
1217
1218 /* check numeric conversion */
1219 switch(arg_type) {
1220 case ARG_INT:
1221 case ARG_DOUBLE:
1222 if (val && !(stop_char && *stop_char == '\0')) {
1223 fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val);
1224 return 1; /* failure */
1225 }
1226 break;
1227 default:
1228 ;
1229 };
1230
1231 /* store the original value */
1232 switch(arg_type) {
1233 case ARG_NO:
1234 case ARG_FLAG:
1235 break;
1236 default:
1237 if (value && orig_field) {
1238 if (no_free) {
1239 *orig_field = value;
1240 } else {
1241 if (*orig_field)
1242 free (*orig_field); /* free previous string */
1243 *orig_field = gengetopt_strdup (value);
1244 }
1245 }
1246 };
1247
1248 return 0; /* OK */
1249 }
1250
1251
1252 int
RNApdist_cmdline_parser_internal(int argc,char ** argv,struct RNApdist_args_info * args_info,struct RNApdist_cmdline_parser_params * params,const char * additional_error)1253 RNApdist_cmdline_parser_internal (
1254 int argc, char **argv, struct RNApdist_args_info *args_info,
1255 struct RNApdist_cmdline_parser_params *params, const char *additional_error)
1256 {
1257 int c; /* Character of the parsed option. */
1258
1259 int error_occurred = 0;
1260 struct RNApdist_args_info local_args_info;
1261
1262 int override;
1263 int initialize;
1264 int check_required;
1265 int check_ambiguity;
1266
1267 char *optarg;
1268 int optind;
1269 int opterr;
1270 int optopt;
1271
1272 package_name = argv[0];
1273
1274 /* TODO: Why is this here? It is not used anywhere. */
1275 override = params->override;
1276 FIX_UNUSED(override);
1277
1278 initialize = params->initialize;
1279 check_required = params->check_required;
1280
1281 /* TODO: Why is this here? It is not used anywhere. */
1282 check_ambiguity = params->check_ambiguity;
1283 FIX_UNUSED(check_ambiguity);
1284
1285 if (initialize)
1286 RNApdist_cmdline_parser_init (args_info);
1287
1288 RNApdist_cmdline_parser_init (&local_args_info);
1289
1290 optarg = 0;
1291 optind = 0;
1292 opterr = params->print_errors;
1293 optopt = '?';
1294
1295 while (1)
1296 {
1297 int option_index = 0;
1298
1299 static struct option long_options[] = {
1300 { "help", 0, NULL, 'h' },
1301 { "detailed-help", 0, NULL, 0 },
1302 { "full-help", 0, NULL, 0 },
1303 { "version", 0, NULL, 'V' },
1304 { "noconv", 0, NULL, 0 },
1305 { "compare", 1, NULL, 'X' },
1306 { "backtrack", 2, NULL, 'B' },
1307 { "temp", 1, NULL, 'T' },
1308 { "noTetra", 0, NULL, '4' },
1309 { "dangles", 1, NULL, 'd' },
1310 { "noLP", 0, NULL, 0 },
1311 { "noGU", 0, NULL, 0 },
1312 { "noClosingGU", 0, NULL, 0 },
1313 { "paramFile", 1, NULL, 'P' },
1314 { "nsp", 1, NULL, 0 },
1315 { "energyModel", 1, NULL, 'e' },
1316 { 0, 0, 0, 0 }
1317 };
1318
1319 custom_optarg = optarg;
1320 custom_optind = optind;
1321 custom_opterr = opterr;
1322 custom_optopt = optopt;
1323
1324 c = custom_getopt_long (argc, argv, "hVX:B::T:4d:P:e:", long_options, &option_index);
1325
1326 optarg = custom_optarg;
1327 optind = custom_optind;
1328 opterr = custom_opterr;
1329 optopt = custom_optopt;
1330
1331 if (c == -1) break; /* Exit from `while (1)' loop. */
1332
1333 switch (c)
1334 {
1335 case 'h': /* Print help and exit. */
1336 RNApdist_cmdline_parser_print_help ();
1337 RNApdist_cmdline_parser_free (&local_args_info);
1338 exit (EXIT_SUCCESS);
1339
1340 case 'V': /* Print version and exit. */
1341 RNApdist_cmdline_parser_print_version ();
1342 RNApdist_cmdline_parser_free (&local_args_info);
1343 exit (EXIT_SUCCESS);
1344
1345 case 'X': /* Specify the comparison directive.
1346 . */
1347
1348
1349 if (update_arg( (void *)&(args_info->compare_arg),
1350 &(args_info->compare_orig), &(args_info->compare_given),
1351 &(local_args_info.compare_given), optarg, 0, "p", ARG_STRING,
1352 check_ambiguity, override, 0, 0,
1353 "compare", 'X',
1354 additional_error))
1355 goto failure;
1356
1357 break;
1358 case 'B': /* Print an \"alignment\" with gaps of the profiles. The aligned structures are written to <filename>, if specified.
1359 . */
1360
1361
1362 if (update_arg( (void *)&(args_info->backtrack_arg),
1363 &(args_info->backtrack_orig), &(args_info->backtrack_given),
1364 &(local_args_info.backtrack_given), optarg, 0, "none", ARG_STRING,
1365 check_ambiguity, override, 0, 0,
1366 "backtrack", 'B',
1367 additional_error))
1368 goto failure;
1369
1370 break;
1371 case 'T': /* Rescale energy parameters to a temperature of temp C. Default is 37C.
1372
1373 . */
1374
1375
1376 if (update_arg( (void *)&(args_info->temp_arg),
1377 &(args_info->temp_orig), &(args_info->temp_given),
1378 &(local_args_info.temp_given), optarg, 0, 0, ARG_DOUBLE,
1379 check_ambiguity, override, 0, 0,
1380 "temp", 'T',
1381 additional_error))
1382 goto failure;
1383
1384 break;
1385 case '4': /* Do not include special tabulated stabilizing energies for tri-, tetra- and hexaloop hairpins. Mostly for testing.
1386
1387 . */
1388
1389
1390 if (update_arg((void *)&(args_info->noTetra_flag), 0, &(args_info->noTetra_given),
1391 &(local_args_info.noTetra_given), optarg, 0, 0, ARG_FLAG,
1392 check_ambiguity, override, 1, 0, "noTetra", '4',
1393 additional_error))
1394 goto failure;
1395
1396 break;
1397 case 'd': /* set energy model for treatment of dangling bases
1398
1399 . */
1400
1401
1402 if (update_arg( (void *)&(args_info->dangles_arg),
1403 &(args_info->dangles_orig), &(args_info->dangles_given),
1404 &(local_args_info.dangles_given), optarg, RNApdist_cmdline_parser_dangles_values, "2", ARG_INT,
1405 check_ambiguity, override, 0, 0,
1406 "dangles", 'd',
1407 additional_error))
1408 goto failure;
1409
1410 break;
1411 case 'P': /* Read energy parameters from paramfile, instead of using the default parameter set.
1412 . */
1413
1414
1415 if (update_arg( (void *)&(args_info->paramFile_arg),
1416 &(args_info->paramFile_orig), &(args_info->paramFile_given),
1417 &(local_args_info.paramFile_given), optarg, 0, 0, ARG_STRING,
1418 check_ambiguity, override, 0, 0,
1419 "paramFile", 'P',
1420 additional_error))
1421 goto failure;
1422
1423 break;
1424 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.
1425
1426 . */
1427
1428
1429 if (update_arg( (void *)&(args_info->energyModel_arg),
1430 &(args_info->energyModel_orig), &(args_info->energyModel_given),
1431 &(local_args_info.energyModel_given), optarg, 0, 0, ARG_INT,
1432 check_ambiguity, override, 0, 0,
1433 "energyModel", 'e',
1434 additional_error))
1435 goto failure;
1436
1437 break;
1438
1439 case 0: /* Long option with no short option */
1440 if (strcmp (long_options[option_index].name, "detailed-help") == 0) {
1441 RNApdist_cmdline_parser_print_detailed_help ();
1442 RNApdist_cmdline_parser_free (&local_args_info);
1443 exit (EXIT_SUCCESS);
1444 }
1445
1446 if (strcmp (long_options[option_index].name, "full-help") == 0) {
1447 RNApdist_cmdline_parser_print_full_help ();
1448 RNApdist_cmdline_parser_free (&local_args_info);
1449 exit (EXIT_SUCCESS);
1450 }
1451
1452 /* Do not automatically substitude nucleotide \"T\" with \"U\"
1453
1454 . */
1455 if (strcmp (long_options[option_index].name, "noconv") == 0)
1456 {
1457
1458
1459 if (update_arg((void *)&(args_info->noconv_flag), 0, &(args_info->noconv_given),
1460 &(local_args_info.noconv_given), optarg, 0, 0, ARG_FLAG,
1461 check_ambiguity, override, 1, 0, "noconv", '-',
1462 additional_error))
1463 goto failure;
1464
1465 }
1466 /* Produce structures without lonely pairs (helices of length 1).
1467 . */
1468 else if (strcmp (long_options[option_index].name, "noLP") == 0)
1469 {
1470
1471
1472 if (update_arg((void *)&(args_info->noLP_flag), 0, &(args_info->noLP_given),
1473 &(local_args_info.noLP_given), optarg, 0, 0, ARG_FLAG,
1474 check_ambiguity, override, 1, 0, "noLP", '-',
1475 additional_error))
1476 goto failure;
1477
1478 }
1479 /* Do not allow GU pairs
1480
1481 . */
1482 else if (strcmp (long_options[option_index].name, "noGU") == 0)
1483 {
1484
1485
1486 if (update_arg((void *)&(args_info->noGU_flag), 0, &(args_info->noGU_given),
1487 &(local_args_info.noGU_given), optarg, 0, 0, ARG_FLAG,
1488 check_ambiguity, override, 1, 0, "noGU", '-',
1489 additional_error))
1490 goto failure;
1491
1492 }
1493 /* Do not allow GU pairs at the end of helices
1494
1495 . */
1496 else if (strcmp (long_options[option_index].name, "noClosingGU") == 0)
1497 {
1498
1499
1500 if (update_arg((void *)&(args_info->noClosingGU_flag), 0, &(args_info->noClosingGU_given),
1501 &(local_args_info.noClosingGU_given), optarg, 0, 0, ARG_FLAG,
1502 check_ambiguity, override, 1, 0, "noClosingGU", '-',
1503 additional_error))
1504 goto failure;
1505
1506 }
1507 /* Allow other pairs in addition to the usual AU,GC,and GU pairs.
1508 . */
1509 else if (strcmp (long_options[option_index].name, "nsp") == 0)
1510 {
1511
1512
1513 if (update_arg( (void *)&(args_info->nsp_arg),
1514 &(args_info->nsp_orig), &(args_info->nsp_given),
1515 &(local_args_info.nsp_given), optarg, 0, 0, ARG_STRING,
1516 check_ambiguity, override, 0, 0,
1517 "nsp", '-',
1518 additional_error))
1519 goto failure;
1520
1521 }
1522
1523 break;
1524 case '?': /* Invalid option. */
1525 /* `getopt_long' already printed an error message. */
1526 goto failure;
1527
1528 default: /* bug: option not considered. */
1529 fprintf (stderr, "%s: option unknown: %c%s\n", RNAPDIST_CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : ""));
1530 abort ();
1531 } /* switch */
1532 } /* while */
1533
1534
1535
1536 FIX_UNUSED(check_required);
1537
1538 RNApdist_cmdline_parser_release (&local_args_info);
1539
1540 if ( error_occurred )
1541 return (EXIT_FAILURE);
1542
1543 return 0;
1544
1545 failure:
1546
1547 RNApdist_cmdline_parser_release (&local_args_info);
1548 return (EXIT_FAILURE);
1549 }
1550 /* vim: set ft=c noet ts=8 sts=8 sw=8 tw=80 nojs spell : */
1551