00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 const char *XrdOucArgsCVSID = "$Id: XrdOucArgs.cc 29874 2009-08-21 16:56:04Z ganis $";
00014
00015 #include <stdarg.h>
00016 #include <stdlib.h>
00017 #include <stdio.h>
00018 #include <strings.h>
00019
00020 #include "XrdOuc/XrdOucArgs.hh"
00021 #include "XrdSys/XrdSysError.hh"
00022
00023
00024
00025
00026
00027 class XrdOucArgsXO
00028 {
00029 public:
00030
00031 int operator==(char *optarg)
00032 {int i = strlen(optarg);
00033 return i <= Optmaxl && i >= Optminl &&
00034 !strncmp((const char *)Optword, optarg, i);
00035 }
00036
00037 char *operator%(char *optarg)
00038 {int i = strlen(optarg);
00039 XrdOucArgsXO *p = this;
00040 do if (i <= p->Optmaxl && i >= p->Optminl &&
00041 !strncmp((const char *)p->Optword, optarg, i)) return p->Optvalu;
00042 while((p = p->Optnext));
00043 return 0;
00044 }
00045
00046 XrdOucArgsXO(XrdOucArgsXO *nP,const char *optw,int minl,const char *optm)
00047 {Optword = strdup(optw);
00048 Optminl = minl; Optmaxl = strlen(optw);
00049 Optvalu[0] = optm[0];
00050 Optvalu[1] = (optm[0] ? optm[1] : '\0');
00051 Optnext = nP;
00052 }
00053
00054 ~XrdOucArgsXO()
00055 {if (Optword) free(Optword);
00056 if (Optnext) delete Optnext;
00057 }
00058 private:
00059 XrdOucArgsXO *Optnext;
00060 char *Optword;
00061 int Optmaxl;
00062 int Optminl;
00063 char Optvalu[2];
00064 };
00065
00066
00067
00068
00069
00070 XrdOucArgs::XrdOucArgs(XrdSysError *erp,
00071 const char *etxt,
00072 const char *StdOpts,
00073 const char *optw,
00074
00075
00076 ...) : arg_stream(0)
00077 {
00078 va_list ap;
00079 const char *optm;
00080 int minl;
00081
00082
00083
00084 inStream = Argc = Aloc = 0; vopts = curopt = 0; endopts = 1;
00085 optp = 0; eDest = erp;
00086 epfx = strdup(etxt ? etxt : "");
00087
00088
00089
00090 if (StdOpts && *StdOpts == ':') {missarg = ':'; StdOpts++;}
00091 else missarg = '?';
00092 vopts = strdup(StdOpts ? StdOpts : "");
00093
00094
00095
00096 if (optw)
00097 {va_start(ap, optw);
00098 while(optw)
00099 {minl = va_arg(ap, int);
00100 optm = va_arg(ap, const char *);
00101 optp = new XrdOucArgsXO(optp, optw, minl, optm);
00102 optw = va_arg(ap, const char *);
00103 }
00104 va_end(ap);
00105 }
00106 }
00107
00108
00109
00110 XrdOucArgs::~XrdOucArgs()
00111 {if (vopts) free(vopts);
00112 if (optp) delete optp;
00113 free(epfx);
00114 }
00115
00116
00117
00118
00119
00120 char *XrdOucArgs::getarg()
00121 {
00122
00123
00124
00125 if (inStream) return arg_stream.GetToken();
00126 if (Aloc >= Argc) return (char *)0;
00127 argval = Argv[Aloc++];
00128 return argval;
00129 }
00130
00131
00132
00133
00134
00135 char XrdOucArgs::getopt()
00136 {
00137 char optbuff[3] = {'-', 'x', '\0'}, *optspec, *arglist, *optname = 0;
00138
00139
00140
00141 if (endopts) return -1;
00142
00143
00144
00145 if (curopt && *curopt) curopt++;
00146 else if (inStream)
00147 {if ((optname = curopt = arg_stream.GetToken(&arglist)))
00148 {if (*curopt != '-') {arg_stream.RetToken(); curopt = 0;}
00149 else curopt++;
00150 }
00151 }
00152 else if (Aloc >= Argc || *Argv[Aloc] != '-') curopt = 0;
00153 else optname = curopt = Argv[Aloc++]+1;
00154
00155
00156
00157 if (!curopt) {endopts = 1; return -1;}
00158 if (!*curopt)
00159 {if (eDest) eDest->Say(epfx, "Option letter missing after '-'.");
00160 endopts = 1;
00161 return '?';
00162 }
00163
00164
00165
00166 if (*curopt == ':' || *curopt == '.') optspec = 0;
00167 else {if (optp) {optspec = *optp%curopt; curopt = 0;}
00168 else {optspec = index(vopts, int(*curopt));
00169 optbuff[1] = *curopt; optname = optbuff; curopt++;
00170 }
00171 }
00172 if (!optspec)
00173 {char buff[500];
00174 if (eDest)
00175 {sprintf(buff, "Invalid option, '%s'.", optname);
00176 eDest->Say(epfx, buff);
00177 }
00178 endopts = 1;
00179 return '?';
00180 }
00181
00182
00183
00184 if (optspec[1] != ':' && optspec[1] != '.') return *optspec;
00185
00186
00187
00188 if (inStream) argval = arg_stream.GetToken();
00189 else argval = (Aloc < Argc ? Argv[Aloc++] : 0);
00190
00191
00192
00193 if (argval)
00194 {if (!*argval) argval = 0;
00195 else if (*argval != '-') return *optspec;
00196 }
00197
00198
00199
00200 if (optspec[1] == '.')
00201 {if (argval && *argval == '-')
00202 {if (inStream) arg_stream.RetToken();
00203 else Aloc--;
00204 }
00205 argval = 0;
00206 return *optspec;
00207 }
00208
00209
00210
00211 if (eDest) eDest->Say(epfx, "Value not specified for '", optname, "'.");
00212 endopts = 1;
00213 return missarg;
00214 }
00215
00216
00217
00218
00219
00220 void XrdOucArgs::Set(char *arglist)
00221 {
00222 inStream = 1;
00223 arg_stream.Attach(arglist);
00224 curopt = 0;
00225 endopts = !arg_stream.GetLine();
00226 }
00227
00228 void XrdOucArgs::Set(int argc, char **argv)
00229 {
00230 inStream = 0;
00231 Argc = argc; Argv = argv; Aloc = 0;
00232 curopt = 0; endopts = 0;
00233 endopts = !argc;
00234 }