Initial commit.
[jagi.git] / src / jagi / PosixArgs.java
1 package jagi;
2
3 import java.util.*;
4
5 public class PosixArgs {
6     private List<Arg> parsed;
7     public String[] rest;
8     public String arg = null;
9     
10     private static class Arg {
11         private char ch;
12         private String arg;
13         
14         private Arg(char ch, String arg) {
15             this.ch = ch;
16             this.arg = arg;
17         }
18     }
19     
20     private PosixArgs() {
21         parsed = new ArrayList<Arg>();
22     }
23
24     public static PosixArgs getopt(String[] argv, int start, String desc) {
25         PosixArgs ret = new PosixArgs();
26         List<Character> fl = new ArrayList<Character>(), fla = new ArrayList<Character>();
27         List<String> rest = new ArrayList<String>();
28         for(int i = 0; i < desc.length();) {
29             char ch = desc.charAt(i++);
30             if((i < desc.length()) && (desc.charAt(i) == ':')) {
31                 i++;
32                 fla.add(ch);
33             } else {
34                 fl.add(ch);
35             }
36         }
37         boolean acc = true;
38         for(int i = start; i < argv.length;) {
39             String arg = argv[i++];
40             if(acc && arg.equals("--")) {
41                 acc = false;
42             } else if(acc && (arg.charAt(0) == '-') && (arg.length() > 1)) {
43                 for(int o = 1; o < arg.length();) {
44                     char ch = arg.charAt(o++);
45                     if(fl.contains(ch)) {
46                         ret.parsed.add(new Arg(ch, null));
47                     } else if(fla.contains(ch)) {
48                         if(o < arg.length()) {
49                             ret.parsed.add(new Arg(ch, arg.substring(o)));
50                             break;
51                         } else if(i < argv.length) {
52                             ret.parsed.add(new Arg(ch, argv[i++]));
53                             break;
54                         } else {
55                             System.err.println("option requires an argument -- '" + ch + "'");
56                             return(null);
57                         }
58                     } else {
59                         System.err.println("invalid option -- '" + ch + "'");
60                         return(null);
61                     }
62                 }
63             } else {
64                 rest.add(arg);
65             }
66         }
67         ret.rest = rest.toArray(new String[0]);
68         return(ret);
69     }
70     
71     public static PosixArgs getopt(String[] argv, String desc) {
72         return(getopt(argv, 0, desc));
73     }
74     
75     public Iterable<Character> parsed() {
76         return(new Iterable<Character>() {
77                 public Iterator<Character> iterator() {
78                     return(new Iterator<Character>() {
79                             private int i = 0;
80                             
81                             public boolean hasNext() {
82                                 return(i < parsed.size());
83                             }
84                             
85                             public Character next() {
86                                 if(i >= parsed.size())
87                                     throw(new NoSuchElementException());
88                                 Arg a = parsed.get(i++);
89                                 arg = a.arg;
90                                 return(a.ch);
91                             }
92                             
93                             public void remove() {
94                                 throw(new UnsupportedOperationException());
95                             }
96                         });
97                 }
98             });
99     }
100 }