@@ -223,128 +223,126 @@ pub type Result = result::Result<Matches, Fail_>;
223223 * Use <fail_str> to get an error message.
224224 */
225225pub fn getopts( args : & [ ~str ] , opts : & [ Opt ] ) -> Result {
226- unsafe {
227- let n_opts = opts. len ( ) ;
228- fn f ( _x : uint ) -> ~[ Optval ] { return ~[ ] ; }
229- let mut vals = vec:: from_fn ( n_opts, f) ;
230- let mut free: ~[ ~str ] = ~[ ] ;
231- let l = args. len ( ) ;
232- let mut i = 0 ;
233- while i < l {
234- let cur = args[ i] ;
235- let curlen = cur. len ( ) ;
236- if !is_arg ( cur) {
237- free. push ( cur) ;
238- } else if cur == ~"--" {
239- let mut j = i + 1;
240- while j < l { free.push(args[j]); j += 1; }
241- break;
242- } else {
243- let mut names;
244- let mut i_arg = None;
245- if cur[1] == '-' as u8 {
246- let tail = str::slice(cur, 2, curlen).to_owned();
247- let mut tail_eq = ~[];
248- for str::each_splitn_char(tail, '=', 1) |s| { tail_eq.push(s.to_owned()) }
249- if tail_eq.len() <= 1 {
250- names = ~[Long(tail)];
251- } else {
252- names =
253- ~[Long(tail_eq[0])];
254- i_arg = Some(tail_eq[1]);
255- }
226+ let n_opts = opts. len ( ) ;
227+ fn f ( _x : uint ) -> ~[ Optval ] { return ~[ ] ; }
228+ let mut vals = vec:: from_fn ( n_opts, f) ;
229+ let mut free: ~[ ~str ] = ~[ ] ;
230+ let l = args. len ( ) ;
231+ let mut i = 0 ;
232+ while i < l {
233+ let cur = args[ i] ;
234+ let curlen = cur. len ( ) ;
235+ if !is_arg ( cur) {
236+ free. push ( cur) ;
237+ } else if cur == ~"--" {
238+ let mut j = i + 1;
239+ while j < l { free.push(args[j]); j += 1; }
240+ break;
241+ } else {
242+ let mut names;
243+ let mut i_arg = None;
244+ if cur[1] == '-' as u8 {
245+ let tail = str::slice(cur, 2, curlen).to_owned();
246+ let mut tail_eq = ~[];
247+ for str::each_splitn_char(tail, '=', 1) |s| { tail_eq.push(s.to_owned()) }
248+ if tail_eq.len() <= 1 {
249+ names = ~[Long(tail)];
256250 } else {
257- let mut j = 1;
258- let mut last_valid_opt_id = None;
259- names = ~[];
260- while j < curlen {
261- let range = str::char_range_at(cur, j);
262- let opt = Short(range.ch);
263-
264- /* In a series of potential options (eg. -aheJ), if we
265- see one which takes an argument, we assume all
266- subsequent characters make up the argument. This
267- allows options such as -L/usr/local/lib/foo to be
268- interpreted correctly
269- */
270-
271- match find_opt(opts, opt) {
272- Some(id) => last_valid_opt_id = Some(id),
273- None => {
274- let arg_follows =
275- last_valid_opt_id.is_some() &&
276- match opts[last_valid_opt_id.get()]
277- .hasarg {
278-
279- Yes | Maybe => true,
280- No => false
281- };
282- if arg_follows && j < curlen {
283- i_arg = Some(cur.slice(j, curlen).to_owned());
284- break;
285- } else {
286- last_valid_opt_id = None;
287- }
288- }
289- }
290- names.push(opt);
291- j = range.next;
292- }
251+ names =
252+ ~[Long(tail_eq[0])];
253+ i_arg = Some(tail_eq[1]);
293254 }
294- let mut name_pos = 0;
295- for names.each() |nm| {
296- name_pos += 1;
297- let optid = match find_opt(opts, *nm) {
298- Some(id) => id,
299- None => return Err(UnrecognizedOption(name_str(nm)))
300- };
301- match opts[optid].hasarg {
302- No => {
303- if !i_arg.is_none() {
304- return Err(UnexpectedArgument(name_str(nm)));
255+ } else {
256+ let mut j = 1;
257+ let mut last_valid_opt_id = None;
258+ names = ~[];
259+ while j < curlen {
260+ let range = str::char_range_at(cur, j);
261+ let opt = Short(range.ch);
262+
263+ /* In a series of potential options (eg. -aheJ), if we
264+ see one which takes an argument, we assume all
265+ subsequent characters make up the argument. This
266+ allows options such as -L/usr/local/lib/foo to be
267+ interpreted correctly
268+ */
269+
270+ match find_opt(opts, opt) {
271+ Some(id) => last_valid_opt_id = Some(id),
272+ None => {
273+ let arg_follows =
274+ last_valid_opt_id.is_some() &&
275+ match opts[last_valid_opt_id.get()]
276+ .hasarg {
277+
278+ Yes | Maybe => true,
279+ No => false
280+ };
281+ if arg_follows && j < curlen {
282+ i_arg = Some(cur.slice(j, curlen).to_owned());
283+ break;
284+ } else {
285+ last_valid_opt_id = None;
305286 }
306- vals[optid].push(Given);
307- }
308- Maybe => {
309- if !i_arg.is_none() {
310- vals[optid].push(Val(i_arg.get()));
311- } else if name_pos < names.len() ||
312- i + 1 == l || is_arg(args[i + 1]) {
313- vals[optid].push(Given);
314- } else { i += 1; vals[optid].push(Val(args[i])); }
315- }
316- Yes => {
317- if !i_arg.is_none() {
318- vals[optid].push(Val(i_arg.get()));
319- } else if i + 1 == l {
320- return Err(ArgumentMissing(name_str(nm)));
321- } else { i += 1; vals[optid].push(Val(args[i])); }
322287 }
323288 }
289+ names.push(opt);
290+ j = range.next;
324291 }
325292 }
326- i += 1;
327- }
328- i = 0u;
329- while i < n_opts {
330- let n = vals[i].len();
331- let occ = opts[i].occur;
332- if occ == Req {
333- if n == 0 {
334- return Err(OptionMissing(name_str(&(opts[i].name))));
293+ let mut name_pos = 0;
294+ for names.each() |nm| {
295+ name_pos += 1;
296+ let optid = match find_opt(opts, *nm) {
297+ Some(id) => id,
298+ None => return Err(UnrecognizedOption(name_str(nm)))
299+ };
300+ match opts[optid].hasarg {
301+ No => {
302+ if !i_arg.is_none() {
303+ return Err(UnexpectedArgument(name_str(nm)));
304+ }
305+ vals[optid].push(Given);
306+ }
307+ Maybe => {
308+ if !i_arg.is_none() {
309+ vals[optid].push(Val(i_arg.get()));
310+ } else if name_pos < names.len() ||
311+ i + 1 == l || is_arg(args[i + 1]) {
312+ vals[optid].push(Given);
313+ } else { i += 1; vals[optid].push(Val(args[i])); }
314+ }
315+ Yes => {
316+ if !i_arg.is_none() {
317+ vals[optid].push(Val(i_arg.get()));
318+ } else if i + 1 == l {
319+ return Err(ArgumentMissing(name_str(nm)));
320+ } else { i += 1; vals[optid].push(Val(args[i])); }
321+ }
335322 }
336323 }
337- if occ != Multi {
338- if n > 1 {
339- return Err(OptionDuplicated(name_str(&(opts[i].name))));
340- }
324+ }
325+ i += 1;
326+ }
327+ i = 0u;
328+ while i < n_opts {
329+ let n = vals[i].len();
330+ let occ = opts[i].occur;
331+ if occ == Req {
332+ if n == 0 {
333+ return Err(OptionMissing(name_str(&(opts[i].name))));
334+ }
335+ }
336+ if occ != Multi {
337+ if n > 1 {
338+ return Err(OptionDuplicated(name_str(&(opts[i].name))));
341339 }
342- i += 1;
343340 }
344- return Ok(Matches {opts: vec::from_slice(opts),
345- vals: vals,
346- free: free});
341+ i += 1;
347342 }
343+ return Ok(Matches {opts: vec::from_slice(opts),
344+ vals: vals,
345+ free: free});
348346}
349347
350348fn opt_vals(mm: &Matches, nm: &str) -> ~[Optval] {
0 commit comments