XRootD
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 {
45 public:
46 
47 int operator==(char *optarg)
48  {int i = strlen(optarg);
49  return i <= Optmaxl && i >= Optminl &&
50  !strncmp((const char *)Optword, optarg, i);
51  }
52 
53 char *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  }
74 private:
75 XrdOucArgsXO *Optnext;
76 char *Optword;
77 int Optmaxl;
78 int Optminl;
79 char 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 
236 void XrdOucArgs::Set(char *arglist)
237 {
238  inStream = 1;
239  arg_stream.Attach(arglist);
240  curopt = 0;
241  endopts = !arg_stream.GetLine();
242 }
243 
244 void 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
XrdOucArgsXO(XrdOucArgsXO *nP, const char *optw, int minl, const char *optm)
Definition: XrdOucArgs.cc:62
char * operator%(char *optarg)
Definition: XrdOucArgs.cc:53
char getopt()
Definition: XrdOucArgs.cc:151
char * getarg()
Definition: XrdOucArgs.cc:136
XrdOucArgs(XrdSysError *erp, const char *etxt, const char *StdOpts, const char *optw=0,...)
Definition: XrdOucArgs.cc:86
void Set(char *arglist)
Definition: XrdOucArgs.cc:236
char * argval
Definition: XrdOucArgs.hh:102
char * GetToken(char **rest=0, int lowcase=0)
void Attach(char *bp)
void Say(const char *text1, const char *text2=0, const char *txt3=0, const char *text4=0, const char *text5=0, const char *txt6=0)
Definition: XrdSysError.cc:141