]>
git.saurik.com Git - apt.git/blob - apt-pkg/contrib/cmndline.cc
6b36325c7c71949e0905abedb45aa85db031feb4
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: cmndline.cc,v 1.1 1998/09/22 05:30:26 jgg Exp $
4 /* ######################################################################
6 Command Line Class - Sophisticated command line parser
8 ##################################################################### */
10 // Include files /*{{{*/
12 #pragma implementation "apt-pkg/cmndline.h"
14 #include <apt-pkg/cmndline.h>
15 #include <apt-pkg/error.h>
19 // CommandLine::CommandLine - Constructor /*{{{*/
20 // ---------------------------------------------------------------------
22 CommandLine::CommandLine(Args
*AList
,Configuration
*Conf
) : ArgList(AList
),
23 Conf(Conf
), FileList(0)
27 // CommandLine::Parse - Main action member /*{{{*/
28 // ---------------------------------------------------------------------
30 bool CommandLine::Parse(int argc
,const char **argv
)
32 FileList
= new const char *[argc
];
33 const char **Files
= FileList
;
35 for (I
= 1; I
!= argc
; I
++)
37 const char *Opt
= argv
[I
];
39 // It is not an option
48 // Double dash signifies the end of option processing
49 if (*Opt
== '-' && Opt
[1] == 0)
52 // Single dash is a short option
55 // Iterate over each letter
58 // Search for the option
60 for (A
= ArgList
; A
->end() == false && A
->ShortOpt
!= *Opt
; A
++);
62 return _error
->Error("Command line option '%c' [from %s] is not known.",*Opt
,argv
[I
]);
64 if (HandleOpt(I
,argc
,argv
,Opt
,A
) == false)
74 // Match up to a = against the list
75 const char *OptEnd
= Opt
;
77 for (; *OptEnd
!= 0 && *OptEnd
!= '='; OptEnd
++);
78 for (A
= ArgList
; A
->end() == false &&
79 stringcasecmp(Opt
,OptEnd
,A
->LongOpt
) != 0; A
++);
81 // Failed, look for a word after the first - (no-foo)
84 for (; Opt
!= OptEnd
&& *Opt
!= '-'; Opt
++);
87 return _error
->Error("Command line option %s is not understood",argv
[I
]);
90 for (A
= ArgList
; A
->end() == false &&
91 stringcasecmp(Opt
,OptEnd
,A
->LongOpt
) != 0; A
++);
94 if (A
->end() == true && OptEnd
- Opt
!= 1)
95 return _error
->Error("Command line option %s is not understood",argv
[I
]);
97 // The option could be a single letter option prefixed by a no-..
98 for (A
= ArgList
; A
->end() == false && A
->ShortOpt
!= *Opt
; A
++);
100 if (A
->end() == true)
101 return _error
->Error("Command line option %s is not understood",argv
[I
]);
106 if (HandleOpt(I
,argc
,argv
,OptEnd
,A
) == false)
110 // Copy any remaining file names over
111 for (; I
!= argc
; I
++)
118 // CommandLine::HandleOpt - Handle a single option including all flags /*{{{*/
119 // ---------------------------------------------------------------------
120 /* This is a helper function for parser, it looks at a given argument
121 and looks for specific patterns in the string, it gets tokanized
122 -ruffly- like -*[yes|true|enable]-(o|longopt)[=][ ][argument] */
123 bool CommandLine::HandleOpt(int &I
,int argc
,const char *argv
[],
124 const char *&Opt
,Args
*A
)
126 const char *Argument
= 0;
127 bool CertainArg
= false;
130 /* Determine the possible location of an option or 0 if their is
132 if (Opt
[1] == 0 || (Opt
[1] == '=' && Opt
[2] == 0))
134 if (I
+ 1 < argc
&& argv
[I
+1][0] != '-')
135 Argument
= argv
[I
+1];
137 // Equals was specified but we fell off the end!
138 if (Opt
[1] == '=' && Argument
== 0)
139 return _error
->Error("Option %s requires an argument.",argv
[I
]);
156 // Option is an argument set
157 if ((A
->Flags
& HasArg
) == HasArg
)
160 return _error
->Error("Option %s requires an argument.",argv
[I
]);
164 // Parse a configuration file
165 if ((A
->Flags
& ConfigFile
) == ConfigFile
)
166 return ReadConfigFile(*Conf
,Argument
);
168 Conf
->Set(A
->ConfName
,Argument
);
172 // Option is an integer level
173 if ((A
->Flags
& IntLevel
) == IntLevel
)
175 // There might be an argument
179 unsigned long Value
= strtol(Argument
,&EndPtr
,10);
181 // Conversion failed and the argument was specified with an =s
182 if (EndPtr
== Argument
&& CertainArg
== true)
183 return _error
->Error("Option %s requires an integer argument, not '%s'",argv
[I
],Argument
);
185 // Conversion was ok, set the value and return
186 if (EndPtr
!= Argument
)
188 Conf
->Set(A
->ConfName
,Value
);
195 // Increase the level
196 Conf
->Set(A
->ConfName
,Conf
->FindI(A
->ConfName
)+1);
200 // Option is a boolean
201 int Sense
= -1; // -1 is unspecified, 0 is yes 1 is no
203 // Look for an argument.
206 // Look at preceeding text
210 if (strlen(argv
[I
]) >= sizeof(Buffer
))
211 return _error
->Error("Option '%s' is too long",argv
[I
]);
213 const char *J
= argv
[I
];
214 for (; *J
!= 0 && *J
== '-'; J
++);
215 const char *JEnd
= J
;
216 for (; *JEnd
!= 0 && *JEnd
!= '-'; JEnd
++);
219 strncpy(Buffer
,J
,JEnd
- J
);
220 Buffer
[JEnd
- J
] = 0;
228 // Check for positives
229 if (strcasecmp(Argument
,"yes") == 0 ||
230 strcasecmp(Argument
,"true") == 0 ||
231 strcasecmp(Argument
,"with") == 0 ||
232 strcasecmp(Argument
,"enable") == 0)
237 if (Argument
!= Buffer
)
245 // Check for negatives
246 if (strcasecmp(Argument
,"no") == 0 ||
247 strcasecmp(Argument
,"false") == 0 ||
248 strcasecmp(Argument
,"without") == 0 ||
249 strcasecmp(Argument
,"disable") == 0)
254 if (Argument
!= Buffer
)
262 if (CertainArg
== true)
263 return _error
->Error("Sense %s is not understood, try true or false.",Argument
);
268 // Indeterminate sense depends on the flag
271 if ((A
->Flags
& InvBoolean
) == InvBoolean
)
277 Conf
->Set(A
->ConfName
,Sense
);