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