XRootD
Loading...
Searching...
No Matches
XrdOucArgs.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O u c A r g s . c c */
4/* */
5/* (c) 2009 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#include <cstdarg>
32#include <cstdlib>
33#include <cstdio>
34#include <strings.h>
35
36#include "XrdOuc/XrdOucArgs.hh"
37#include "XrdSys/XrdSysError.hh"
38
39/******************************************************************************/
40/* L o c a l C l a s s X r d O u c A r g s O p t */
41/******************************************************************************/
42
44{
45public:
46
47int operator==(char *optarg)
48 {int i = strlen(optarg);
49 return i <= Optmaxl && i >= Optminl &&
50 !strncmp((const char *)Optword, optarg, i);
51 }
52
53char *operator%(char *optarg)
54 {int i = strlen(optarg);
55 XrdOucArgsXO *p = this;
56 do if (i <= p->Optmaxl && i >= p->Optminl &&
57 !strncmp((const char *)p->Optword, optarg, i)) return p->Optvalu;
58 while((p = p->Optnext));
59 return 0;
60 }
61
62 XrdOucArgsXO(XrdOucArgsXO *nP,const char *optw,int minl,const char *optm)
63 {Optword = strdup(optw);
64 Optminl = minl; Optmaxl = strlen(optw);
65 Optvalu[0] = optm[0];
66 Optvalu[1] = (optm[0] ? optm[1] : '\0');
67 Optnext = nP;
68 }
69
71 {if (Optword) free(Optword);
72 if (Optnext) delete Optnext;
73 }
74private:
75XrdOucArgsXO *Optnext;
76char *Optword;
77int Optmaxl;
78int Optminl;
79char Optvalu[2];
80};
81
82/******************************************************************************/
83/* C o n s t r u c t o r & D e s t r u c t o r */
84/******************************************************************************/
85
87 const char *etxt,
88 const char *StdOpts,
89 const char *optw,
90 // int minl,
91 // const char *optm,
92 ...) : arg_stream(0)
93{
94 va_list ap;
95 const char *optm;
96 int minl;
97
98// Do the standard initialization
99//
100 inStream = Argc = Aloc = 0; vopts = curopt = 0; endopts = 1;
101 optp = 0; eDest = erp;
102 epfx = strdup(etxt ? etxt : "");
103
104// Process the valid opts
105//
106 if (StdOpts && *StdOpts == ':') {missarg = ':'; StdOpts++;}
107 else missarg = '?';
108 vopts = strdup(StdOpts ? StdOpts : "");
109
110// Handle list of extended options, if any
111//
112 if (optw)
113 {va_start(ap, optw);
114 while(optw)
115 {minl = va_arg(ap, int);
116 optm = va_arg(ap, const char *);
117 optp = new XrdOucArgsXO(optp, optw, minl, optm);
118 optw = va_arg(ap, const char *);
119 }
120 va_end(ap);
121 }
122}
123
124/******************************************************************************/
125
127 {if (vopts) free(vopts);
128 if (optp) delete optp;
129 free(epfx);
130 }
131
132/******************************************************************************/
133/* g e t a r g s */
134/******************************************************************************/
135
137{
138
139// Return argument from whatever source we have
140//
141 if (inStream) return arg_stream.GetToken();
142 if (Aloc >= Argc) return (char *)0;
143 argval = Argv[Aloc++];
144 return argval;
145}
146
147/******************************************************************************/
148/* g e t o p t */
149/******************************************************************************/
150
152{
153 char optbuff[3] = {'-', 'x', '\0'}, *optspec, *arglist, *optname = 0;
154
155// Check if we really have any more options
156//
157 if (endopts) return -1;
158
159// Get next option from whatever source we have
160//
161 if (curopt && *curopt) curopt++;
162 else if (inStream)
163 {if ((optname = curopt = arg_stream.GetToken(&arglist)))
164 {if (*curopt != '-') {arg_stream.RetToken(); curopt = 0;}
165 else curopt++;
166 }
167 }
168 else if (Aloc >= Argc || *Argv[Aloc] != '-') curopt = 0;
169 else optname = curopt = Argv[Aloc++]+1;
170
171// Check if we really have an option here
172//
173 if (!curopt) {endopts = 1; return -1;}
174 if (!*curopt)
175 {if (eDest) eDest->Say(epfx, "Option letter missing after '-'.");
176 endopts = 1;
177 return '?';
178 }
179
180// Check for extended options or single letter option
181//
182 if (*curopt == ':' || *curopt == '.') optspec = 0;
183 else {if (optp) {optspec = *optp%curopt; curopt = 0;}
184 else {optspec = index(vopts, int(*curopt));
185 optbuff[1] = *curopt; optname = optbuff; curopt++;
186 }
187 }
188 if (!optspec)
189 {char buff[500];
190 if (eDest)
191 {sprintf(buff, "Invalid option, '%s'.", optname);
192 eDest->Say(epfx, buff);
193 }
194 endopts = 1;
195 return '?';
196 }
197
198// Check if this option requires an argument
199//
200 if (optspec[1] != ':' && optspec[1] != '.') return *optspec;
201
202// Get the argument from whatever source we have
203//
204 if (inStream) argval = arg_stream.GetToken();
205 else argval = (Aloc < Argc ? Argv[Aloc++] : 0);
206
207// If we have a valid argument, then we are all done
208//
209 if (argval)
210 {if (!*argval) argval = 0;
211 else if (*argval != '-') return *optspec;
212 }
213
214// If argument is optional, let it go
215//
216 if (optspec[1] == '.')
217 {if (argval && *argval == '-')
218 {if (inStream) arg_stream.RetToken();
219 else Aloc--;
220 }
221 argval = 0;
222 return *optspec;
223 }
224
225// Complain about a missing argument
226//
227 if (eDest) eDest->Say(epfx, "Value not specified for '", optname, "'.");
228 endopts = 1;
229 return missarg;
230}
231
232/******************************************************************************/
233/* S e t */
234/******************************************************************************/
235
236void XrdOucArgs::Set(char *arglist)
237{
238 inStream = 1;
239 arg_stream.Attach(arglist);
240 curopt = 0;
241 endopts = !arg_stream.GetLine();
242}
243
244void XrdOucArgs::Set(int argc, char **argv)
245{
246 inStream = 0;
247 Argc = argc; Argv = argv; Aloc = 0;
248 curopt = 0; endopts = 0;
249 endopts = !argc;
250}
int operator==(char *optarg)
Definition XrdOucArgs.cc:47
char * operator%(char *optarg)
Definition XrdOucArgs.cc:53
XrdOucArgsXO(XrdOucArgsXO *nP, const char *optw, int minl, const char *optm)
Definition XrdOucArgs.cc:62
char getopt()
char * getarg()
XrdOucArgs(XrdSysError *erp, const char *etxt, const char *StdOpts, const char *optw=0,...)
Definition XrdOucArgs.cc:86
void Set(char *arglist)
char * argval