1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_codemaker.hxx"
30 #include <stdio.h>
31 #include <string.h>
32 
33 #include "cppuoptions.hxx"
34 #include "osl/thread.h"
35 #include "osl/process.h"
36 
37 #ifdef SAL_UNX
38 #define SEPARATOR '/'
39 #else
40 #define SEPARATOR '\\'
41 #endif
42 
43 using namespace rtl;
44 
45 sal_Bool CppuOptions::initOptions(int ac, char* av[], sal_Bool bCmdFile)
46 	throw( IllegalArgument )
47 {
48 	sal_Bool 	ret = sal_True;
49 	sal_uInt16	i=0;
50 
51 	if (!bCmdFile)
52 	{
53 		bCmdFile = sal_True;
54 
55 		OString name(av[0]);
56 		sal_Int32 index = name.lastIndexOf(SEPARATOR);
57 		m_program = name.copy((index > 0 ? index+1 : 0));
58 
59 		if (ac < 2)
60 		{
61 			fprintf(stderr, "%s", prepareHelp().getStr());
62 			ret = sal_False;
63 		}
64 
65 		i = 1;
66 	} else
67 	{
68 		i = 0;
69 	}
70 
71 	char	*s=NULL;
72 	for( ; i < ac; i++)
73 	{
74 		if (av[i][0] == '-')
75 		{
76 			switch (av[i][1])
77 			{
78 				case 'O':
79 					if (av[i][2] == '\0')
80 					{
81 						if (i < ac - 1 && av[i+1][0] != '-')
82 						{
83 							i++;
84 							s = av[i];
85 						} else
86 						{
87 							OString tmp("'-O', please check");
88 							if (i <= ac - 1)
89 							{
90 								tmp += " your input '" + OString(av[i+1]) + "'";
91 							}
92 
93 							throw IllegalArgument(tmp);
94 						}
95 					} else
96 					{
97 						s = av[i] + 2;
98 					}
99 
100 					m_options["-O"] = OString(s);
101 					break;
102 				case 'B':
103 					if (av[i][2] == '\0')
104 					{
105 						if (i < ac - 1 && av[i+1][0] != '-')
106 						{
107 							i++;
108 							s = av[i];
109 						} else
110 						{
111 							OString tmp("'-B', please check");
112 							if (i <= ac - 1)
113 							{
114 								tmp += " your input '" + OString(av[i+1]) + "'";
115 							}
116 
117 							throw IllegalArgument(tmp);
118 						}
119 					} else
120 					{
121 						s = av[i] + 2;
122 					}
123 
124 					m_options["-B"] = OString(s);
125 					break;
126 				case 'T':
127 					if (av[i][2] == '\0')
128 					{
129 						if (i < ac - 1 && av[i+1][0] != '-')
130 						{
131 							i++;
132 							s = av[i];
133 						} else
134 						{
135 							OString tmp("'-T', please check");
136 							if (i <= ac - 1)
137 							{
138 								tmp += " your input '" + OString(av[i+1]) + "'";
139 							}
140 
141 							throw IllegalArgument(tmp);
142 						}
143 					} else
144 					{
145 						s = av[i] + 2;
146 					}
147 
148 					if (m_options.count("-T") > 0)
149 					{
150 						OString tmp(m_options["-T"]);
151 						tmp = tmp + ";" + s;
152 						m_options["-T"] = tmp;
153 					} else
154 					{
155 						m_options["-T"] = OString(s);
156 					}
157 					break;
158 				case 'L':
159 					if (av[i][2] != '\0')
160 					{
161 						OString tmp("'-L', please check");
162 						if (i <= ac - 1)
163 						{
164 							tmp += " your input '" + OString(av[i]) + "'";
165 						}
166 
167 						throw IllegalArgument(tmp);
168 					}
169 
170 					if (isValid("-C") || isValid("-CS"))
171 					{
172 						OString tmp("'-L' could not be combined with '-C' or '-CS' option");
173 						throw IllegalArgument(tmp);
174 					}
175 					m_options["-L"] = OString("");
176 					break;
177 				case 'C':
178 					if (av[i][2] == 'S')
179 					{
180 						if (av[i][3] != '\0')
181 						{
182 							OString tmp("'-CS', please check");
183 							if (i <= ac - 1)
184 							{
185 								tmp += " your input '" + OString(av[i]) + "'";
186 							}
187 
188 							throw IllegalArgument(tmp);
189 						}
190 
191 						if (isValid("-L") || isValid("-C"))
192 						{
193 							OString tmp("'-CS' could not be combined with '-L' or '-C' option");
194 							throw IllegalArgument(tmp);
195 						}
196 						m_options["-CS"] = OString("");
197 						break;
198 					} else
199 					if (av[i][2] != '\0')
200 					{
201 						OString tmp("'-C', please check");
202 						if (i <= ac - 1)
203 						{
204 							tmp += " your input '" + OString(av[i]) + "'";
205 						}
206 
207 						throw IllegalArgument(tmp);
208 					}
209 
210 					if (isValid("-L") || isValid("-CS"))
211 					{
212 						OString tmp("'-C' could not be combined with '-L' or '-CS' option");
213 						throw IllegalArgument(tmp);
214 					}
215 					m_options["-C"] = OString("");
216 					break;
217 				case 'G':
218 					if (av[i][2] == 'c')
219 					{
220 						if (av[i][3] != '\0')
221 						{
222 							OString tmp("'-Gc', please check");
223 							if (i <= ac - 1)
224 							{
225 								tmp += " your input '" + OString(av[i]) + "'";
226 							}
227 
228 							throw IllegalArgument(tmp);
229 						}
230 
231 						m_options["-Gc"] = OString("");
232 						break;
233 					} else
234 					if (av[i][2] != '\0')
235 					{
236 						OString tmp("'-G', please check");
237 						if (i <= ac - 1)
238 						{
239 							tmp += " your input '" + OString(av[i]) + "'";
240 						}
241 
242 						throw IllegalArgument(tmp);
243 					}
244 
245 					m_options["-G"] = OString("");
246 					break;
247 				case 'X': // support for eXtra type rdbs
248                 {
249 					if (av[i][2] == '\0')
250 					{
251 						if (i < ac - 1 && av[i+1][0] != '-')
252 						{
253 							i++;
254 							s = av[i];
255 						} else
256 						{
257 							OString tmp("'-X', please check");
258 							if (i <= ac - 1)
259 							{
260 								tmp += " your input '" + OString(av[i+1]) + "'";
261 							}
262 
263 							throw IllegalArgument(tmp);
264 						}
265 					} else
266 					{
267 						s = av[i] + 2;
268 					}
269 
270                     m_extra_input_files.push_back( s );
271 					break;
272                 }
273 
274 				default:
275 					throw IllegalArgument("the option is unknown" + OString(av[i]));
276 			}
277 		} else
278 		{
279 			if (av[i][0] == '@')
280 			{
281 				FILE* cmdFile = fopen(av[i]+1, "r");
282 		  		if( cmdFile == NULL )
283       			{
284 					fprintf(stderr, "%s", prepareHelp().getStr());
285 					ret = sal_False;
286 				} else
287 				{
288 					int rargc=0;
289 					char* rargv[512];
290 					char  buffer[512];
291 
292 					while ( fscanf(cmdFile, "%s", buffer) != EOF )
293 					{
294 						rargv[rargc]= strdup(buffer);
295 						rargc++;
296 					}
297 					fclose(cmdFile);
298 
299 					ret = initOptions(rargc, rargv, bCmdFile);
300 
301 					for (long j=0; j < rargc; j++)
302 					{
303 						free(rargv[j]);
304 					}
305 				}
306 			} else
307 			{
308                 if (bCmdFile)
309                 {
310                     m_inputFiles.push_back(av[i]);
311                 } else
312                 {
313                     OUString system_filepath;
314                     if (osl_getCommandArg( i-1, &system_filepath.pData )
315                         != osl_Process_E_None)
316                     {
317                         OSL_ASSERT(false);
318                     }
319                     m_inputFiles.push_back(OUStringToOString(system_filepath, osl_getThreadTextEncoding()));
320                 }
321 			}
322 		}
323 	}
324 
325 	return ret;
326 }
327 
328 OString	CppuOptions::prepareHelp()
329 {
330 	OString help("\nusing: ");
331 	help += m_program + " [-options] file_1 ... file_n\nOptions:\n";
332 	help += "    -O<path>   = path describes the root directory for the generated output.\n";
333 	help += "                 The output directory tree is generated under this directory.\n";
334 	help += "    -T<name>   = name specifies a type or a list of types. The output for this\n";
335 	help += "      [t1;...]   type is generated. If no '-T' option is specified,\n";
336 	help += "                 then output for all types is generated.\n";
337 	help += "                 Example: 'com.sun.star.uno.XInterface' is a valid type.\n";
338 	help += "    -B<name>   = name specifies the base node. All types are searched under this\n";
339 	help += "                 node. Default is the root '/' of the registry files.\n";
340 	help += "    -L         = UNO type functions are generated lightweight, that means only\n";
341 	help += "                 the name and typeclass are given and everything else is retrieved\n";
342 	help += "                 from the type library dynamically. The default is that UNO type\n";
343 	help += "                 functions provides enough type information for boostrapping C++.\n";
344 	help += "                 '-L' should be the default for external components.\n";
345 	help += "    -C         = UNO type functions are generated comprehensive that means all\n";
346 	help += "                 necessary information is available for bridging the type in UNO.\n";
347 	help += "    -G         = generate only target files which does not exists.\n";
348 	help += "    -Gc        = generate only target files which content will be changed.\n";
349 	help += "    -X<file>   = extra types which will not be taken into account for generation.\n\n";
350 	help += prepareVersion();
351 
352 	return help;
353 }
354 
355 OString	CppuOptions::prepareVersion()
356 {
357 	OString version(m_program);
358 	version += " Version 2.0\n\n";
359 	return version;
360 }
361 
362 
363