]> git.donarmstrong.com Git - lilypond.git/blob - flower/lgetopt.cc
c2e5a3b7902ed9685eb6a2a927c4921eba291262
[lilypond.git] / flower / 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     char const *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         char const *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 {
160     if (!next())
161         return 0;
162     
163     if (optindind)
164         return parseshort();
165     
166     if (argv[optind][0] != '-')
167         return 0;
168
169     if (argv[optind][1] == '-') {// what to do with "command  --  bla"
170         return parselong();
171     } else {
172         optindind = 1;
173         return parseshort();
174     }
175 }
176
177 Getopt_long::Getopt_long(int c, char **v, Long_option_init *lo)
178 {
179     the_opts = lo;
180     errorout = &cerr;
181     argv = v;
182     argc = c;
183     optind = 1;
184     optindind = 0;
185
186     //    reached end of option table?
187     int i;
188     for (i = 0;  the_opts[i].longname ||the_opts[i].shortname; i++)
189         ;
190     table_len = i;
191 }
192
193 bool
194 Getopt_long::next()
195 {
196
197     error = E_NOERROR;
198     while (optind < argc && !argv[optind][optindind]) {
199         optind++;
200         optindind = 0;
201     }
202     return (optind < argc);
203 }
204    
205 char *
206 Getopt_long::current_arg()
207 {
208     if (optind >= argc)
209         return 0;
210     char * a = argv[optind];
211     return a + optindind;
212 }
213
214 char *
215 Getopt_long::get_next_arg()
216 {
217     char * a = current_arg();
218     if ( a) {
219         optind ++;
220         optindind = 0;
221     }
222     return a;
223 }