]> git.donarmstrong.com Git - lilypond.git/blob - flower/lib/lgetopt.cc
a56c64c6dbd40c98043f5e4474e2360f49a3508d
[lilypond.git] / flower / lib / lgetopt.cc
1 /*
2    process command line, GNU style.
3
4    this is (Copyleft) 1996, Han-Wen Nienhuys, <hanwen@stack.nl>
5  */
6 #include <stdio.h>
7 #include <iostream.h>
8 #include <assert.h>
9 #include "lgetopt.hh"
10
11 long
12 Getopt_long::intarg()
13 {
14     long l;
15     if (sscanf(optarg, "%ld", &l) != 1)
16         report(E_ILLEGALARG);
17     
18     return l;
19 }
20
21 Long_option_init *
22 Getopt_long::parselong()
23 {
24     const char *optnm = argv[optind] + 2 ;
25     assert(*optnm);
26     
27     char *endopt = strchr(optnm, '=');
28     int searchlen  = (endopt) ? endopt - optnm : strlen(optnm);
29     
30     beet=0;
31     for (int i=0; i< table_len; i++) {
32         const char *ln = the_opts[i].longname;
33
34         if (ln && !strncmp(ln, optnm, searchlen)) {
35             beet = the_opts+i;
36             break;
37         }
38     }   
39
40     if (!beet) {
41         report(E_UNKNOWNOPTION);
42         return 0;
43     }
44     optind++;
45     optindind = 0;
46
47     
48     if (beet->take_arg) {
49         if (endopt)
50             optarg = endopt +1; // a '='
51         else {
52             optarg = argv[optind];
53             optind++;
54         }
55         if (!optarg)
56             report(E_ARGEXPECT);
57
58     } else {
59         optarg = 0;
60         if (endopt)
61             report(E_NOARGEXPECT);
62     }
63     
64     return beet;
65 }
66
67
68 ostream &
69 Long_option_init::printon(ostream &errorout)
70 {
71     if (shortname)      
72         errorout <<"-" << shortname;
73     if (shortname && longname)
74         errorout << ", ";
75     if (longname)       
76         errorout << "`--" << longname << "'";
77     return errorout;
78 }
79
80 // report an error, GNU style.
81 void
82 Getopt_long::report(Errorcod c)
83 {
84     error = c;
85     if (!errorout)
86         return;
87
88     *errorout << argv[0] << ": ";
89     switch (c) {
90     case E_ARGEXPECT:
91         *errorout<< "option ";
92         beet->printon(*errorout);
93         *errorout << "requires an argument"<<endl;
94         break;
95     case  E_NOARGEXPECT:
96         *errorout << "option `--" <<
97             beet->longname << "' does not allow an argument"<<endl;
98         break;
99         
100     case E_UNKNOWNOPTION:
101         *errorout << "unrecognized option ";
102         if (optindind)
103             *errorout << "-" << argv[optind][optindind] << endl;
104         else
105             *errorout << argv[optind] << endl;
106
107         break;
108     case E_ILLEGALARG:
109         *errorout << "illegal argument `" << optarg << "\'to option ";
110         beet->printon(*errorout);
111         *errorout << '\n';
112     default:
113         assert(false);
114     }
115     exit(2); 
116 }
117     
118 Long_option_init *
119 Getopt_long::parseshort()
120 {
121     char c=argv[optind][optindind];
122     beet=0;
123     assert(c);
124     
125     for (int i=0; i < table_len; i++)
126         if (the_opts[i].shortname == c) {
127             beet  = the_opts+i;
128             break;
129         }
130
131     if (!beet){
132         report(E_UNKNOWNOPTION);
133         return 0;
134     }
135
136     optindind++;
137     if (!beet->take_arg){
138         optarg = 0;
139         return beet;
140     }
141     optarg = argv[optind] + optindind;
142
143     optind ++;
144     optindind = 0;
145     
146     if (!optarg[0]) {
147         optarg = argv[optind];
148         optind ++;
149     }
150     if (!optarg) {
151         report(E_ARGEXPECT);
152     }
153     
154     return beet;
155 }
156
157 Long_option_init *
158 Getopt_long::operator()() {
159     if (!next())
160         return 0;
161     
162     if (optindind)
163         return parseshort();
164     
165     if (argv[optind][0] != '-')
166         return 0;
167
168     if (argv[optind][1] == '-') {// what to do with "command  --  bla"
169         return parselong();
170     } else {
171         optindind = 1;
172         return parseshort();
173     }
174 }
175
176 Getopt_long::Getopt_long(int c, char **v, Long_option_init *lo)
177 {
178     the_opts = lo;
179     errorout = &cerr;
180     argv = v;
181     argc = c;
182     optind = 1;
183     optindind = 0;
184
185     //    reached end of option table?
186     int i;
187     for (i = 0;  the_opts[i].longname ||the_opts[i].shortname; i++)
188         ;
189     table_len = i;
190 }
191
192 bool
193 Getopt_long::next()
194 {
195
196     error = E_NOERROR;
197     while (optind < argc && !argv[optind][optindind]) {
198         optind++;
199         optindind = 0;
200     }
201     return (optind < argc);
202 }
203    
204 char *
205 Getopt_long::current_arg()
206 {
207     if (optind >= argc)
208         return 0;
209     char * a = argv[optind];
210     return a + optindind;
211 }
212
213 char *
214 Getopt_long::get_next_arg()
215 {
216     char * a = current_arg();
217     if ( a) {
218         optind ++;
219         optindind = 0;
220     }
221     return a;
222 }