Mercurial > repos > clustalomega > clustalomega
comparison clustalomega/clustal-omega-0.2.0/src/squid/getopt.c @ 0:ff1768533a07
Migrated tool version 0.2 from old tool shed archive to new tool shed repository
author | clustalomega |
---|---|
date | Tue, 07 Jun 2011 17:04:25 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:ff1768533a07 |
---|---|
1 /***************************************************************** | |
2 * SQUID - a library of functions for biological sequence analysis | |
3 * Copyright (C) 1992-2002 Washington University School of Medicine | |
4 * | |
5 * This source code is freely distributed under the terms of the | |
6 * GNU General Public License. See the files COPYRIGHT and LICENSE | |
7 * for details. | |
8 *****************************************************************/ | |
9 | |
10 /* RCS $Id: getopt.c 217 2011-03-19 10:27:10Z andreas $ (Original squid RCS Id: getopt.c,v 1.7 2001/02/21 21:09:10 eddy Exp) | |
11 */ | |
12 | |
13 #include <stdio.h> | |
14 #include <string.h> | |
15 #include <stdlib.h> | |
16 | |
17 #include "squid.h" | |
18 | |
19 /* Function: Getopt() | |
20 * | |
21 * Purpose: Portable command line option parsing with abbreviated | |
22 * option switches. Replaces UNIX getopt(). Using UNIX getopt() | |
23 * hinders portability to non-UNIX platforms, and getopt() | |
24 * is also limited to single letter options. | |
25 * | |
26 * Getopt() implements a superset of UNIX getopt(). | |
27 * All of getopt()'s single-character switch behavior | |
28 * is emulated, and "--" by itself terminates the options. | |
29 * Additionally, Getopt() provides extended switches | |
30 * like "--youroptionhere", and Getopt() type checks | |
31 * arguments. | |
32 * | |
33 * Extended options must start with "--", as in "--option1". | |
34 * Normal options must start with "-", as in "-o". | |
35 * Normal options may be concatenated, as in "-a -b" == "-ab". | |
36 * | |
37 * See bottom of this .c file after #fdef GETOPT_TESTDRIVER | |
38 * for an example of calling Getopt(). | |
39 * | |
40 * Args: argc - from main(). number of elems in argv. | |
41 * argv - from main(). argv[0] is the name of the command. | |
42 * opt - array of opt_s structures, defining option switches | |
43 * nopts - number of switches in opt | |
44 * usage - a (possibly long) string to print if usage error. | |
45 * ret_optind - RETURN: the index in argv[] of the next | |
46 * valid command-line token. | |
47 * ret_optname- RETURN: ptr to the name of option switch | |
48 * seen, or NULL if no option was seen. | |
49 * ret_optarg - RETURN: ptr to the optional argument, if any; | |
50 * NULL if option takes no argument. | |
51 * | |
52 * Return: 1 if a valid option was parsed. | |
53 * 0 if no option was found, and command-line parsing is complete. | |
54 * Die()'s here if an error is detected. | |
55 */ | |
56 int | |
57 Getopt(int argc, char **argv, struct opt_s *opt, int nopts, char *usage, | |
58 int *ret_optind, char **ret_optname, char **ret_optarg) | |
59 { | |
60 int i; | |
61 int arglen; | |
62 int nmatch; | |
63 static int optind = 1; /* init to 1 on first call */ | |
64 static char *optptr = NULL; /* ptr to next valid switch */ | |
65 int opti = 0; /* init only to silence gcc uninit warnings */ | |
66 | |
67 /* Check to see if we've run out of options. | |
68 * A '-' by itself is an argument (e.g. "read from stdin") | |
69 * not an option. | |
70 */ | |
71 if (optind >= argc || argv[optind][0] != '-' || strcmp(argv[optind], "-") == 0) | |
72 { | |
73 *ret_optind = optind; | |
74 *ret_optarg = NULL; | |
75 *ret_optname = NULL; | |
76 return 0; | |
77 } | |
78 | |
79 /* Check to see if we're being told that this is the end | |
80 * of the options with the special "--" flag. | |
81 */ | |
82 if (strcmp(argv[optind], "--") == 0) | |
83 { | |
84 optind++; | |
85 *ret_optind = optind; | |
86 *ret_optname = NULL; | |
87 *ret_optarg = NULL; | |
88 return 0; | |
89 } | |
90 | |
91 /* We have a real option. Find which one it is. | |
92 * We handle single letter switches "-o" separately | |
93 * from full switches "--option", based on the "-" vs. "--" | |
94 * prefix -- single letter switches can be concatenated | |
95 * as long as they don't have arguments. | |
96 */ | |
97 /* full option */ | |
98 if (optptr == NULL && strncmp(argv[optind], "--", 2) == 0) | |
99 { | |
100 /* Use optptr to parse argument in options of form "--foo=666" | |
101 */ | |
102 if ((optptr = strchr(argv[optind], '=')) != NULL) | |
103 { *optptr = '\0'; optptr++; } | |
104 | |
105 arglen = strlen(argv[optind]); | |
106 nmatch = 0; | |
107 for (i = 0; i < nopts; i++) | |
108 if (opt[i].single == FALSE && | |
109 strncmp(opt[i].name, argv[optind], arglen) == 0) | |
110 { | |
111 nmatch++; | |
112 opti = i; | |
113 if (arglen == strlen(opt[i].name)) break; /* exact match, stop now */ | |
114 } | |
115 if (nmatch > 1 && arglen != strlen(opt[i].name)) | |
116 Die("Option \"%s\" is ambiguous; please be more specific.\n%s", | |
117 argv[optind], usage); | |
118 if (nmatch == 0) | |
119 Die("No such option \"%s\".\n%s", argv[optind], usage); | |
120 | |
121 *ret_optname = opt[opti].name; | |
122 | |
123 /* Set the argument, if there is one | |
124 */ | |
125 if (opt[opti].argtype != sqdARG_NONE) | |
126 { | |
127 if (optptr != NULL) | |
128 { /* --foo=666 style */ | |
129 *ret_optarg = optptr; | |
130 optptr = NULL; | |
131 optind++; | |
132 } | |
133 else if (optind+1 >= argc) | |
134 Die("Option %s requires an argument\n%s", opt[opti].name, usage); | |
135 else /* "--foo 666" style */ | |
136 { | |
137 *ret_optarg = argv[optind+1]; | |
138 optind+=2; | |
139 } | |
140 } | |
141 else /* sqdARG_NONE */ | |
142 { | |
143 if (optptr != NULL) | |
144 Die("Option %s does not take an argument\n%s", opt[opti].name, usage); | |
145 *ret_optarg = NULL; | |
146 optind++; | |
147 } | |
148 } | |
149 else /* else, a single letter option "-o" */ | |
150 { | |
151 /* find the option */ | |
152 if (optptr == NULL) | |
153 optptr = argv[optind]+1; | |
154 for (opti = -1, i = 0; i < nopts; i++) | |
155 if (opt[i].single == TRUE && *optptr == opt[i].name[1]) | |
156 { opti = i; break; } | |
157 if (opti == -1) | |
158 Die("No such option \"%c\".\n%s", *optptr, usage); | |
159 *ret_optname = opt[opti].name; | |
160 | |
161 /* set the argument, if there is one */ | |
162 if (opt[opti].argtype != sqdARG_NONE) | |
163 { | |
164 if (*(optptr+1) != '\0') /* attached argument */ | |
165 { | |
166 *ret_optarg = optptr+1; | |
167 optind++; | |
168 } | |
169 else if (optind+1 < argc) /* unattached argument */ | |
170 { | |
171 *ret_optarg = argv[optind+1]; | |
172 optind+=2; | |
173 } | |
174 else Die("Option %s requires an argument\n%s", opt[opti].name, usage); | |
175 | |
176 optptr = NULL; /* can't concatenate after an argument */ | |
177 } | |
178 else /* sqdARG_NONE */ | |
179 { | |
180 *ret_optarg = NULL; | |
181 if (*(optptr+1) != '\0') /* concatenation */ | |
182 optptr++; | |
183 else | |
184 { | |
185 optind++; /* move to next field */ | |
186 optptr = NULL; | |
187 } | |
188 } | |
189 | |
190 } | |
191 | |
192 /* Type check the argument, if there is one | |
193 */ | |
194 if (opt[opti].argtype != sqdARG_NONE) | |
195 { | |
196 if (opt[opti].argtype == sqdARG_INT && ! IsInt(*ret_optarg)) | |
197 Die("Option %s requires an integer argument\n%s", | |
198 opt[opti].name, usage); | |
199 else if (opt[opti].argtype == sqdARG_FLOAT && ! IsReal(*ret_optarg)) | |
200 Die("Option %s requires a numerical argument\n%s", | |
201 opt[opti].name, usage); | |
202 else if (opt[opti].argtype == sqdARG_CHAR && strlen(*ret_optarg) != 1) | |
203 Die("Option %s requires a single-character argument\n%s", | |
204 opt[opti].name, usage); | |
205 /* sqdARG_STRING is always ok, no type check necessary */ | |
206 } | |
207 | |
208 *ret_optind = optind; | |
209 return 1; | |
210 } | |
211 | |
212 | |
213 | |
214 #ifdef GETOPT_TESTDRIVER | |
215 /* cc -DGETOPT_TESTDRIVER -L ~/lib/squid.linux/ getopt.c -lsquid | |
216 */ | |
217 struct opt_s OPTIONS[] = { | |
218 { "--test1", FALSE, sqdARG_INT }, | |
219 { "--test2", FALSE, sqdARG_FLOAT }, | |
220 { "--test3", FALSE, sqdARG_STRING }, | |
221 { "--test4", FALSE, sqdARG_CHAR }, | |
222 { "-a", TRUE, sqdARG_NONE }, | |
223 { "-b", TRUE, sqdARG_INT }, | |
224 }; | |
225 #define NOPTIONS (sizeof(OPTIONS) / sizeof(struct opt_s)) | |
226 | |
227 int | |
228 main(int argc, char **argv) | |
229 { | |
230 int optind; | |
231 char *optarg; | |
232 char *optname; | |
233 | |
234 while (Getopt(argc, argv, OPTIONS, NOPTIONS, "Usage/help here", | |
235 &optind, &optname, &optarg)) | |
236 { | |
237 printf("Option: index: %d name: %s argument: %s\n", | |
238 optind, optname, optarg); | |
239 } | |
240 while (optind < argc) | |
241 { | |
242 printf("Argument: index: %d name: %s\n", optind, argv[optind]); | |
243 optind++; | |
244 } | |
245 | |
246 | |
247 } | |
248 | |
249 | |
250 #endif /*GETOPT_TESTDRIVER*/ |