Bump version to 4.3-4
[LibreOffice.git] / idlc / source / options.cxx
blobc04603d118b7d3cfa49f29438bdcd1e3647c4f3b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "idlc/options.hxx"
23 #include <osl/diagnose.h>
24 #include <rtl/string.hxx>
25 #include <rtl/strbuf.hxx>
27 #include <stdio.h>
28 #include <string.h>
31 Options::Options(char const * progname)
32 : m_program(progname), m_stdin(false), m_verbose(false), m_quiet(false)
36 Options::~Options()
40 // static
41 bool Options::checkArgument (std::vector< std::string > & rArgs, char const * arg, size_t len)
43 bool result = ((arg != 0) && (len > 0));
44 OSL_PRECOND(result, "idlc::Options::checkArgument(): invalid arguments");
45 if (result)
47 switch(arg[0])
49 case '@':
50 if ((result = (len > 1)) == true)
52 // "@<cmdfile>"
53 result = Options::checkCommandFile (rArgs, &(arg[1]));
55 break;
56 case '-':
57 if ((result = (len > 1)) == true)
59 // "-<option>"
60 switch (arg[1])
62 case 'O':
63 case 'M':
64 case 'I':
65 case 'D':
67 // "-<option>[<param>]
68 std::string option(&(arg[0]), 2);
69 rArgs.push_back(option);
70 if (len > 2)
72 // "-<option><param>"
73 std::string param(&(arg[2]), len - 2);
74 rArgs.push_back(param);
76 break;
78 default:
79 // "-<option>" ([long] option, w/o param)
80 rArgs.push_back(std::string(arg, len));
81 break;
84 break;
85 default:
86 // "<param>"
87 rArgs.push_back(std::string(arg, len));
88 break;
91 return (result);
94 // static
95 bool Options::checkCommandFile (std::vector< std::string > & rArgs, char const * filename)
97 FILE * fp = fopen(filename, "r");
98 if (fp == 0)
100 fprintf(stderr, "ERROR: can't open command file \"%s\"\n", filename);
101 return (false);
104 std::string buffer;
105 buffer.reserve(256);
107 bool quoted = false;
108 int c = EOF;
109 while ((c = fgetc(fp)) != EOF)
111 switch(c)
113 case '\"':
114 quoted = !quoted;
115 break;
116 case ' ':
117 case '\t':
118 case '\r':
119 case '\n':
120 if (!quoted)
122 if (!buffer.empty())
124 // append current argument.
125 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
127 (void) fclose(fp);
128 return (false);
130 buffer.clear();
132 break;
134 default:
135 // quoted white-space fall through
136 buffer.push_back(sal::static_int_cast<char>(c));
137 break;
140 if (!buffer.empty())
142 // append unterminated argument.
143 if (!Options::checkArgument(rArgs, buffer.c_str(), buffer.size()))
145 (void) fclose(fp);
146 return (false);
148 buffer.clear();
150 return (fclose(fp) == 0);
153 bool Options::badOption(char const * reason, std::string const & rArg) throw(IllegalArgument)
155 OStringBuffer message;
156 if (reason != 0)
158 message.append(reason); message.append(" option '"); message.append(rArg.c_str()); message.append("'");
159 throw IllegalArgument(message.makeStringAndClear());
161 return false;
164 bool Options::setOption(char const * option, std::string const & rArg)
166 bool result = (0 == strcmp(option, rArg.c_str()));
167 if (result)
168 m_options[rArg.c_str()] = OString(rArg.c_str(), rArg.size());
169 return (result);
172 bool Options::initOptions(std::vector< std::string > & rArgs) throw(IllegalArgument)
174 std::vector< std::string >::const_iterator first = rArgs.begin(), last = rArgs.end();
175 for (; first != last; ++first)
177 if ((*first)[0] != '-')
179 OString filename((*first).c_str(), (*first).size());
180 OString tmp(filename.toAsciiLowerCase());
181 if (tmp.lastIndexOf(".idl") != (tmp.getLength() - 4))
183 throw IllegalArgument("'" + filename + "' is not a valid input file, only '*.idl' files will be accepted");
185 m_inputFiles.push_back(filename);
186 continue;
189 std::string const option(*first);
190 switch((*first)[1])
192 case 'O':
194 if (!((++first != last) && ((*first)[0] != '-')))
196 return badOption("invalid", option);
198 OString param((*first).c_str(), (*first).size());
199 m_options["-O"] = param;
200 break;
202 case 'M':
204 if (!((++first != last) && ((*first)[0] != '-')))
206 return badOption("invalid", option);
208 OString param((*first).c_str(), (*first).size());
209 m_options["-M"] = param;
210 break;
212 case 'I':
214 if (!((++first != last) && ((*first)[0] != '-')))
216 return badOption("invalid", option);
218 OString param((*first).c_str(), (*first).size());
220 // quote param token(s).
221 OStringBuffer buffer;
222 sal_Int32 k = 0;
225 if (!buffer.isEmpty())
226 buffer.append(' ');
227 // buffer.append("-I\"");
228 buffer.append(param.getToken(0, ';', k));
229 // buffer.append("\"");
230 } while (k != -1);
231 param = buffer.makeStringAndClear();
233 if (m_options.count("-I") > 0)
235 // append param.
236 OStringBuffer buffer(m_options["-I"]);
237 buffer.append(' '); buffer.append(param);
238 param = buffer.makeStringAndClear();
240 m_options["-I"] = param;
241 break;
243 case 'D':
245 if (!((++first != last) && ((*first)[0] != '-')))
247 return badOption("invalid", option);
249 OString param("-D"); param += OString((*first).c_str(), (*first).size());
250 if (m_options.count("-D") > 0)
252 OStringBuffer buffer(m_options["-D"]);
253 buffer.append(' '); buffer.append(param);
254 param = buffer.makeStringAndClear();
256 m_options["-D"] = param;
257 break;
259 case 'C':
261 if (!setOption("-C", option))
263 return badOption("invalid", option);
265 break;
267 case 'c':
269 if (!setOption("-cid", option))
271 return badOption("invalid", option);
273 break;
275 case 'q':
277 if (!setOption("-quiet", option))
279 return badOption("invalid", option);
281 m_quiet = true;
282 break;
284 case 'v':
286 if (!setOption("-verbose", option))
288 return badOption("invalid", option);
290 m_verbose = true;
291 break;
293 case 'w':
295 if (!(setOption("-w", option) || setOption("-we", option)))
297 return badOption("invalid", option);
299 break;
301 case 'h':
302 case '?':
304 if (!(setOption("-h", option) || setOption("-?", option)))
306 return badOption("invalid", option);
309 (void) fprintf(stdout, "%s", prepareHelp().getStr());
310 return (false);
312 // break; // Unreachable
314 case 's':
316 if (!setOption("-stdin", option))
318 return badOption("invalid", option);
320 m_stdin = true;
321 break;
323 default:
324 return badOption("unknown", option);
327 return (true);
330 OString Options::prepareHelp()
332 OString help("\nusing: ");
333 help += m_program + " [-options] <file_1> ... <file_n> | @<filename> | -stdin\n";
334 help += " <file_n> = file_n specifies one or more idl files.\n";
335 help += " Only files with the extension '.idl' are valid.\n";
336 help += " @<filename> = filename specifies the name of a command file.\n";
337 help += " -stdin = read idl file from standard input.\n";
338 help += " Options:\n";
339 help += " -O<path> = path specifies the output directory.\n";
340 help += " The generated output is a registry file with\n";
341 help += " the same name as the idl input file (or 'stdin'\n";
342 help += " for -stdin).\n";
343 help += " -M<path> = path specifies the output directory for deps.\n";
344 help += " Generate GNU make dependency files with the\n";
345 help += " same name as the idl input file.\n";
346 help += " -I<path> = path specifies a directory where include\n";
347 help += " files will be searched by the preprocessor.\n";
348 help += " Multiple directories can be combined with ';'.\n";
349 help += " -D<name> = name defines a macro for the preprocessor.\n";
350 help += " -C = generate complete type information, including\n";
351 help += " documentation.\n";
352 help += " -cid = check if identifiers fulfill the UNO naming\n";
353 help += " requirements.\n";
354 help += " -quiet = no output.\n";
355 help += " -verbose = verbose output.\n";
356 help += " -w = display warning messages.\n";
357 help += " -we = treat warnings as errors.\n";
358 help += " -h|-? = print this help message and exit.\n\n";
359 help += prepareVersion();
361 return help;
364 OString Options::prepareVersion()
366 OString version(m_program);
367 version += " Version 1.1\n\n";
368 return version;
371 const OString& Options::getProgramName() const
373 return m_program;
376 bool Options::isValid(const OString& option)
378 return (m_options.count(option) > 0);
381 const OString& Options::getOption(const OString& option)
382 throw( IllegalArgument )
384 if (!isValid(option))
386 throw IllegalArgument("Option is not valid or currently not set.");
388 return m_options[option];
391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */