options.cxx (2fe1ca3d) options.cxx (5979ef3c)
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 29 unchanged lines hidden (view full) ---

38
39#ifdef SAL_UNX
40#define SEPARATOR '/'
41#else
42#define SEPARATOR '\\'
43#endif
44
45Options::Options(char const * progname)
1/**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance

--- 29 unchanged lines hidden (view full) ---

38
39#ifdef SAL_UNX
40#define SEPARATOR '/'
41#else
42#define SEPARATOR '\\'
43#endif
44
45Options::Options(char const * progname)
46 : m_program(progname), m_stdin(false), m_verbose(false), m_quiet(false)
46 : m_program(progname), m_stdin(false), m_verbose(false), m_quiet(false)
47{
48}
49
50Options::~Options()
51{
52}
53
54// static
55bool Options::checkArgument (std::vector< std::string > & rArgs, char const * arg, size_t len)
56{
47{
48}
49
50Options::~Options()
51{
52}
53
54// static
55bool Options::checkArgument (std::vector< std::string > & rArgs, char const * arg, size_t len)
56{
57 bool result = ((arg != 0) && (len > 0));
58 OSL_PRECOND(result, "idlc::Options::checkArgument(): invalid arguments");
59 if (result)
60 {
61 switch(arg[0])
57 bool result = ((arg != 0) && (len > 0));
58 OSL_PRECOND(result, "idlc::Options::checkArgument(): invalid arguments");
59 if (result)
62 {
60 {
63 case '@':
64 if ((result = (len > 1)) == true)
65 {
66 // "@<cmdfile>"
67 result = Options::checkCommandFile (rArgs, &(arg[1]));
68 }
69 break;
70 case '-':
71 if ((result = (len > 1)) == true)
72 {
73 // "-<option>"
74 switch (arg[1])
61 switch(arg[0])
75 {
62 {
76 case 'O':
77 case 'I':
78 case 'D':
79 {
80 // "-<option>[<param>]
81 std::string option(&(arg[0]), 2);
82 rArgs.push_back(option);
83 if (len > 2)
63 case '@':
64 if ((result = (len > 1)) == true)
84 {
65 {
85 // "-<option><param>"
86 std::string param(&(arg[2]), len - 2);
87 rArgs.push_back(param);
66 // "@<cmdfile>"
67 result = Options::checkCommandFile (rArgs, &(arg[1]));
88 }
89 break;
68 }
69 break;
90 }
70 case '-':
71 if ((result = (len > 1)) == true)
72 {
73 // "-<option>"
74 switch (arg[1])
75 {
76 case 'O':
77 case 'I':
78 case 'D':
79 {
80 // "-<option>[<param>]
81 std::string option(&(arg[0]), 2);
82 rArgs.push_back(option);
83 if (len > 2)
84 {
85 // "-<option><param>"
86 std::string param(&(arg[2]), len - 2);
87 rArgs.push_back(param);
88 }
89 break;
90 }
91 default:
92 // "-<option>" ([long] option, w/o param)
93 rArgs.push_back(std::string(arg, len));
94 break;
95 }
96 }
97 break;
91 default:
98 default:
92 // "-<option>" ([long] option, w/o param)
93 rArgs.push_back(std::string(arg, len));
94 break;
99 // "<param>"
100 rArgs.push_back(std::string(arg, len));
101 break;
95 }
102 }
96 }
97 break;
98 default:
99 // "<param>"
100 rArgs.push_back(std::string(arg, len));
101 break;
102 }
103 }
103 }
104 return (result);
104 return (result);
105}
106
107// static
108bool Options::checkCommandFile (std::vector< std::string > & rArgs, char const * filename)
109{
110 FILE * fp = fopen(filename, "r");
111 if (fp == 0)
112 {
113 fprintf(stderr, "ERROR: can't open command file \"%s\"\n", filename);
114 return (false);
115 }
105}
106
107// static
108bool Options::checkCommandFile (std::vector< std::string > & rArgs, char const * filename)
109{
110 FILE * fp = fopen(filename, "r");
111 if (fp == 0)
112 {
113 fprintf(stderr, "ERROR: can't open command file \"%s\"\n", filename);
114 return (false);
115 }
116
116
117 std::string buffer;
118 buffer.reserve(256);
117 std::string buffer;
118 buffer.reserve(256);
119
119
120 bool quoted = false;
121 int c = EOF;
122 while ((c = fgetc(fp)) != EOF)
123 {
124 switch(c)
125 {
126 case '\"':
120 bool quoted = false;
121 int c = EOF;
122 while ((c = fgetc(fp)) != EOF)
123 {
124 switch(c)
125 {
126 case '\"':
127 quoted = !quoted;
128 break;
127 quoted = !quoted;
128 break;
129 case ' ':
130 case '\t':
131 case '\r':
132 case '\n':
129 case ' ':
130 case '\t':
131 case '\r':
132 case '\n':
133 if (!quoted)
134 {
135 if (!buffer.empty())
136 {
137 // append current argument.
138 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
139 {
140 (void) fclose(fp);
141 return (false);
142 }
143 buffer.clear();
144 }
145 break;
146 }
133 if (!quoted)
134 {
135 if (!buffer.empty())
136 {
137 // append current argument.
138 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
139 {
140 (void) fclose(fp);
141 return (false);
142 }
143 buffer.clear();
144 }
145 break;
146 }
147 default:
147 default:
148 // quoted white-space fall through
149 buffer.push_back(sal::static_int_cast<char>(c));
150 break;
148 // quoted white-space fall through
149 buffer.push_back(sal::static_int_cast<char>(c));
150 break;
151 }
152 }
153 if (!buffer.empty())
154 {
155 // append unterminated argument.
156 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
157 {
158 (void) fclose(fp);
159 return (false);
160 }
161 buffer.clear();
162 }
163 return (fclose(fp) == 0);
164}
165
166bool Options::badOption(char const * reason, std::string const & rArg) throw(IllegalArgument)
167{
151 }
152 }
153 if (!buffer.empty())
154 {
155 // append unterminated argument.
156 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
157 {
158 (void) fclose(fp);
159 return (false);
160 }
161 buffer.clear();
162 }
163 return (fclose(fp) == 0);
164}
165
166bool Options::badOption(char const * reason, std::string const & rArg) throw(IllegalArgument)
167{
168 OStringBuffer message;
169 if (reason != 0)
170 {
171 message.append(reason); message.append(" option '"); message.append(rArg.c_str()); message.append("'");
172 throw IllegalArgument(message.makeStringAndClear());
173 }
174 return false;
168 OStringBuffer message;
169 if (reason != 0)
170 {
171 message.append(reason); message.append(" option '"); message.append(rArg.c_str()); message.append("'");
172 throw IllegalArgument(message.makeStringAndClear());
173 }
174 return false;
175}
176
177bool Options::setOption(char const * option, std::string const & rArg)
178{
175}
176
177bool Options::setOption(char const * option, std::string const & rArg)
178{
179 bool result = (0 == strcmp(option, rArg.c_str()));
180 if (result)
181 m_options[rArg.c_str()] = OString(rArg.c_str(), rArg.size());
182 return (result);
179 bool result = (0 == strcmp(option, rArg.c_str()));
180 if (result)
181 m_options[rArg.c_str()] = OString(rArg.c_str(), rArg.size());
182 return (result);
183}
184
185bool Options::initOptions(std::vector< std::string > & rArgs) throw(IllegalArgument)
186{
183}
184
185bool Options::initOptions(std::vector< std::string > & rArgs) throw(IllegalArgument)
186{
187 std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
188 for (; first != last; ++first)
189 {
190 if ((*first)[0] != '-')
187 std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
188 for (; first != last; ++first)
191 {
189 {
192 OString filename((*first).c_str(), (*first).size());
193 OString tmp(filename.toAsciiLowerCase());
194 if (tmp.lastIndexOf(".idl") != (tmp.getLength() - 4))
195 {
196 throw IllegalArgument("'" + filename + "' is not a valid input file, only '*.idl' files will be accepted");
197 }
198 m_inputFiles.push_back(filename);
199 continue;
200 }
201
202 std::string const option(*first);
203 switch((*first)[1])
204 {
205 case 'O':
206 {
207 if (!((++first != last) && ((*first)[0] != '-')))
190 if ((*first)[0] != '-')
208 {
191 {
209 return badOption("invalid", option);
192 OString filename((*first).c_str(), (*first).size());
193 OString tmp(filename.toAsciiLowerCase());
194 if (tmp.lastIndexOf(".idl") != (tmp.getLength() - 4))
195 {
196 throw IllegalArgument("'" + filename + "' is not a valid input file, only '*.idl' files will be accepted");
197 }
198 m_inputFiles.push_back(filename);
199 continue;
210 }
200 }
211 OString param((*first).c_str(), (*first).size());
212 m_options["-O"] = param;
213 break;
214 }
215 case 'I':
216 {
217 if (!((++first != last) && ((*first)[0] != '-')))
201
202 std::string const option(*first);
203 switch((*first)[1])
218 {
204 {
219 return badOption("invalid", option);
220 }
221 OString param((*first).c_str(), (*first).size());
205 case 'O':
222 {
206 {
223 // quote param token(s).
224 OStringBuffer buffer;
225 sal_Int32 k = 0;
226 do
227 {
228 OStringBuffer token; token.append("-I\""); token.append(param.getToken(0, ';', k)); token.append("\"");
229 if (buffer.getLength() > 0)
230 buffer.append(' ');
231 buffer.append(token);
232 } while (k != -1);
233 param = buffer.makeStringAndClear();
207 if (!((++first != last) && ((*first)[0] != '-')))
208 {
209 return badOption("invalid", option);
210 }
211 OString param((*first).c_str(), (*first).size());
212 m_options["-O"] = param;
213 break;
234 }
214 }
235 if (m_options.count("-I") > 0)
215 case 'I':
236 {
216 {
237 // append param.
238 OStringBuffer buffer(m_options["-I"]);
239 buffer.append(' '); buffer.append(param);
240 param = buffer.makeStringAndClear();
217 if (!((++first != last) && ((*first)[0] != '-')))
218 {
219 return badOption("invalid", option);
220 }
221 OString param((*first).c_str(), (*first).size());
222 {
223 // quote param token(s).
224 OStringBuffer buffer;
225 sal_Int32 k = 0;
226 do
227 {
228 OStringBuffer token; token.append("-I"); token.append(param.getToken(0, ';', k));
229 if (buffer.getLength() > 0)
230 buffer.append(' ');
231 buffer.append(token);
232 } while (k != -1);
233 param = buffer.makeStringAndClear();
234 }
235 if (m_options.count("-I") > 0)
236 {
237 // append param.
238 OStringBuffer buffer(m_options["-I"]);
239 buffer.append(' '); buffer.append(param);
240 param = buffer.makeStringAndClear();
241 }
242 m_options["-I"] = param;
243 break;
241 }
244 }
242 m_options["-I"] = param;
243 break;
244 }
245 case 'D':
246 {
247 if (!((++first != last) && ((*first)[0] != '-')))
245 case 'D':
248 {
246 {
249 return badOption("invalid", option);
247 if (!((++first != last) && ((*first)[0] != '-')))
248 {
249 return badOption("invalid", option);
250 }
251 OString param("-D"); param += OString((*first).c_str(), (*first).size());
252 if (m_options.count("-D") > 0)
253 {
254 OStringBuffer buffer(m_options["-D"]);
255 buffer.append(' '); buffer.append(param);
256 param = buffer.makeStringAndClear();
257 }
258 m_options["-D"] = param;
259 break;
250 }
260 }
251 OString param("-D"); param += OString((*first).c_str(), (*first).size());
252 if (m_options.count("-D") > 0)
261 case 'C':
253 {
262 {
254 OStringBuffer buffer(m_options["-D"]);
255 buffer.append(' '); buffer.append(param);
256 param = buffer.makeStringAndClear();
263 if (!setOption("-C", option))
264 {
265 return badOption("invalid", option);
266 }
267 break;
257 }
268 }
258 m_options["-D"] = param;
259 break;
260 }
261 case 'C':
262 {
263 if (!setOption("-C", option))
269 case 'c':
264 {
270 {
265 return badOption("invalid", option);
271 if (!setOption("-cid", option))
272 {
273 return badOption("invalid", option);
274 }
275 break;
266 }
276 }
267 break;
268 }
269 case 'c':
270 {
271 if (!setOption("-cid", option))
277 case 'q':
272 {
278 {
273 return badOption("invalid", option);
279 if (!setOption("-quiet", option))
280 {
281 return badOption("invalid", option);
282 }
283 m_quiet = true;
284 break;
274 }
285 }
275 break;
276 }
277 case 'q':
278 {
279 if (!setOption("-quiet", option))
286 case 'v':
280 {
287 {
281 return badOption("invalid", option);
288 if (!setOption("-verbose", option))
289 {
290 return badOption("invalid", option);
291 }
292 m_verbose = true;
293 break;
282 }
294 }
283 m_quiet = true;
284 break;
285 }
286 case 'v':
287 {
288 if (!setOption("-verbose", option))
295 case 'w':
289 {
296 {
290 return badOption("invalid", option);
297 if (!(setOption("-w", option) || setOption("-we", option)))
298 {
299 return badOption("invalid", option);
300 }
301 break;
291 }
302 }
292 m_verbose = true;
293 break;
294 }
295 case 'w':
296 {
297 if (!(setOption("-w", option) || setOption("-we", option)))
303 case 'h':
304 case '?':
298 {
305 {
299 return badOption("invalid", option);
306 if (!(setOption("-h", option) || setOption("-?", option)))
307 {
308 return badOption("invalid", option);
309 }
310 {
311 (void) fprintf(stdout, "%s", prepareHelp().getStr());
312 return (false);
313 }
314 // break; // Unreachable
300 }
315 }
301 break;
302 }
303 case 'h':
304 case '?':
305 {
306 if (!(setOption("-h", option) || setOption("-?", option)))
316 case 's':
307 {
317 {
308 return badOption("invalid", option);
318 if (!setOption("-stdin", option))
319 {
320 return badOption("invalid", option);
321 }
322 m_stdin = true;
323 break;
309 }
324 }
310 {
311 (void) fprintf(stdout, "%s", prepareHelp().getStr());
312 return (false);
325 default:
326 return badOption("unknown", option);
313 }
327 }
314 // break; // Unreachable
315 }
316 case 's':
317 {
318 if (!setOption("-stdin", option))
319 {
320 return badOption("invalid", option);
321 }
322 m_stdin = true;
323 break;
324 }
325 default:
326 return badOption("unknown", option);
327 }
328 }
328 }
329 return (true);
329 return (true);
330}
331
332OString Options::prepareHelp()
333{
334 OString help("\nusing: ");
330}
331
332OString Options::prepareHelp()
333{
334 OString help("\nusing: ");
335 help += m_program
336 + " [-options] <file_1> ... <file_n> | @<filename> | -stdin\n";
335 help += m_program + " [-options] <file_1> ... <file_n> | @<filename> | -stdin\n";
337 help += " <file_n> = file_n specifies one or more idl files.\n";
338 help += " Only files with the extension '.idl' are valid.\n";
339 help += " @<filename> = filename specifies the name of a command file.\n";
340 help += " -stdin = read idl file from standard input.\n";
341 help += " Options:\n";
342 help += " -O<path> = path specifies the output directory.\n";
343 help += " The generated output is a registry file with\n";
344 help += " the same name as the idl input file (or 'stdin'\n";

--- 44 unchanged lines hidden ---
336 help += " <file_n> = file_n specifies one or more idl files.\n";
337 help += " Only files with the extension '.idl' are valid.\n";
338 help += " @<filename> = filename specifies the name of a command file.\n";
339 help += " -stdin = read idl file from standard input.\n";
340 help += " Options:\n";
341 help += " -O<path> = path specifies the output directory.\n";
342 help += " The generated output is a registry file with\n";
343 help += " the same name as the idl input file (or 'stdin'\n";

--- 44 unchanged lines hidden ---