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