update dev300-m58
[ooovba.git] / idlc / source / idlccompile.cxx
blob5b16a5f85120efadd43b37d709d32d9b39bf96ca
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: idlccompile.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_idlc.hxx"
33 #include <idlc/idlc.hxx>
34 #include <rtl/ustring.hxx>
35 #include <rtl/strbuf.hxx>
36 #include <osl/process.h>
37 #include <osl/diagnose.h>
38 #include <osl/thread.h>
39 #include <osl/file.hxx>
41 #if defined(SAL_W32) || defined(SAL_OS2)
42 #include <io.h>
43 #endif
45 #ifdef SAL_UNX
46 #include <unistd.h>
47 #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD)
48 #include <sys/wait.h>
49 #else
50 #include <wait.h>
51 #endif
52 #endif
54 #include <string.h>
56 using namespace ::rtl;
57 using namespace ::osl;
59 extern int yyparse();
60 extern FILE* yyin;
61 extern int yydebug;
63 sal_Int32 lineNumber = 1;
66 static OUString TMP(RTL_CONSTASCII_USTRINGPARAM("TMP"));
67 static OUString TEMP(RTL_CONSTASCII_USTRINGPARAM("TEMP"));
68 static sal_Char tmpFilePattern[512];
70 sal_Bool isFileUrl(const OString& fileName)
72 if (fileName.indexOf("file://") == 0 )
73 return sal_True;
74 return sal_False;
77 OString convertToAbsoluteSystemPath(const OString& fileName)
79 OUString uSysFileName;
80 OUString uFileName(fileName.getStr(), fileName.getLength(), osl_getThreadTextEncoding());
81 if ( isFileUrl(fileName) )
83 if (FileBase::getSystemPathFromFileURL(uFileName, uSysFileName)
84 != FileBase::E_None)
86 OSL_ASSERT(false);
88 } else
90 OUString uWorkingDir, uUrlFileName, uTmp;
91 if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None)
93 OSL_ASSERT(false);
95 if (FileBase::getFileURLFromSystemPath(uFileName, uTmp)
96 != FileBase::E_None)
98 OSL_ASSERT(false);
100 if (FileBase::getAbsoluteFileURL(uWorkingDir, uTmp, uUrlFileName)
101 != FileBase::E_None)
103 OSL_ASSERT(false);
105 if (FileBase::getSystemPathFromFileURL(uUrlFileName, uSysFileName)
106 != FileBase::E_None)
108 OSL_ASSERT(false);
112 return OUStringToOString(uSysFileName, osl_getThreadTextEncoding());
115 OString convertToFileUrl(const OString& fileName)
117 if ( !isFileUrl(fileName) )
119 OString tmp = convertToAbsoluteSystemPath(fileName);
120 OUString uFileName(tmp.getStr(), tmp.getLength(), osl_getThreadTextEncoding());
121 OUString uUrlFileName;
122 if (FileBase::getFileURLFromSystemPath(uFileName, uUrlFileName)
123 != FileBase::E_None)
125 OSL_ASSERT(false);
127 return OUStringToOString(uUrlFileName, osl_getThreadTextEncoding());
130 return fileName;
133 OString makeTempName(const OString& prefix)
135 OUString uTmpPath;
136 OString tmpPath;
138 if ( osl_getEnvironment(TMP.pData, &uTmpPath.pData) != osl_Process_E_None )
140 if ( osl_getEnvironment(TEMP.pData, &uTmpPath.pData) != osl_Process_E_None )
142 #if defined(SAL_W32)
143 tmpPath = OString("c:\\temp");
144 #else
145 tmpPath = OString("/tmp");
146 #endif
150 if ( uTmpPath.getLength() )
151 tmpPath = OUStringToOString(uTmpPath, RTL_TEXTENCODING_UTF8);
153 #if defined(SAL_W32) || defined(SAL_UNX) || defined(SAL_OS2)
155 OSL_ASSERT( sizeof(tmpFilePattern) > ( strlen(tmpPath)
156 + RTL_CONSTASCII_LENGTH(
157 PATH_SEPARATOR )
158 + prefix.getLength()
159 + RTL_CONSTASCII_LENGTH(
160 "XXXXXX") ) );
162 tmpFilePattern[ sizeof(tmpFilePattern)-1 ] = '\0';
163 strncpy(tmpFilePattern, tmpPath, sizeof(tmpFilePattern)-1);
164 strncat(tmpFilePattern, PATH_SEPARATOR, sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
165 strncat(tmpFilePattern, prefix.getStr(), sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
166 strncat(tmpFilePattern, "XXXXXX", sizeof(tmpFilePattern)-1-strlen(tmpFilePattern));
168 #ifdef SAL_UNX
169 int nDescriptor = mkstemp(tmpFilePattern);
170 if( -1 == nDescriptor )
172 fprintf( stderr,"idlc: couldn't create temporary file\n" );
173 exit( 1 );
175 // the file shall later be reopened by stdio functions
176 close( nDescriptor );
177 #else
178 (void) mktemp(tmpFilePattern);
179 #endif
180 #endif
182 return OString(tmpFilePattern);
185 sal_Bool copyFile(const OString* source, const OString& target)
187 sal_Bool bRet = sal_True;
189 FILE* pSource = source == 0 ? stdin : fopen(source->getStr(), "rb");
191 if ( !pSource )
192 return sal_False;
194 FILE* pTarget = fopen(target.getStr(), "wb");
196 if ( !pTarget )
198 fclose(pSource);
199 return sal_False;
202 size_t totalSize = 512;
203 size_t readSize = 0;
204 size_t writeSize = 0;
205 char pBuffer[513];
207 while ( !feof(pSource) )
209 if ( (readSize = fread(pBuffer, 1, totalSize, pSource)) > 0 && !ferror(pSource) )
211 if ( (writeSize = fwrite(pBuffer, 1, readSize, pTarget)) != readSize || ferror(pTarget) )
213 if (source != 0) {
214 fclose(pSource);
216 fclose(pTarget);
217 return sal_False;
222 if (source != 0) {
223 fclose(pSource);
225 if ( fflush(pTarget) )
226 bRet = sal_False;
227 fclose(pTarget);
229 return bRet;
232 sal_Int32 compileFile(const OString * pathname)
234 // preprocess input file
235 OString tmpFile = makeTempName(OString("idli_"));
236 OString preprocFile = makeTempName(OString("idlf_"));
238 OString fileName;
239 if (pathname == 0) {
240 fileName = "stdin";
241 } else {
242 fileName = *pathname;
245 if ( !copyFile(pathname, tmpFile) )
247 fprintf(stderr, "%s: could not copy %s%s to %s\n",
248 idlc()->getOptions()->getProgramName().getStr(),
249 pathname == 0 ? "" : "file ", fileName.getStr(),
250 tmpFile.getStr());
251 exit(99);
254 idlc()->setFileName(fileName);
255 idlc()->setMainFileName(fileName);
256 idlc()->setRealFileName(tmpFile);
258 OStringBuffer cppArgs(512);
259 cppArgs.append("-DIDL -Xi -Xc -+ -I.");
260 Options* pOptions = idlc()->getOptions();
262 OString filePath;
263 sal_Int32 index = fileName.lastIndexOf(SEPARATOR);
265 if ( index > 0)
267 filePath = fileName.copy(0, index);
269 if ( filePath.getLength() )
271 cppArgs.append(" -I\"");
272 cppArgs.append(filePath);
273 cppArgs.append("\"");
277 if ( pOptions->isValid("-D") )
279 cppArgs.append(" ");
280 cppArgs.append(pOptions->getOption("-D"));
282 if ( pOptions->isValid("-I") )
284 cppArgs.append(" ");
285 cppArgs.append(pOptions->getOption("-I"));
288 cppArgs.append(" \"");
289 cppArgs.append(tmpFile);
290 cppArgs.append("\" \"");
291 cppArgs.append(preprocFile);
292 cppArgs.append("\"");
294 OString cmdFileName = makeTempName(OString("idlc_"));
295 FILE* pCmdFile = fopen(cmdFileName, "w");
297 if ( !pCmdFile )
299 fprintf(stderr, "%s: couldn't open temporary file for preprocessor commands: %s\n",
300 idlc()->getOptions()->getProgramName().getStr(), cmdFileName.getStr());
301 exit(99);
303 #ifdef SAL_OS2_00
304 char* tok = strtok( (char*)cppArgs.getStr(), " \t\n\r");
305 while( tok) {
306 if (tok[strlen(tok)-1] == '\"')
307 tok[strlen(tok)-1] = '\0';
308 if (*tok == '\"')
309 memcpy( tok, tok+1, strlen(tok));
310 if (strlen(tok)>0) {
311 fputs(tok, pCmdFile);
312 fputc('\n', pCmdFile);
314 tok = strtok( NULL, " \t\n\r");
316 #else
317 fprintf(pCmdFile, "%s", cppArgs.getStr());
318 #endif
319 fclose(pCmdFile);
321 OUString cmdArg(RTL_CONSTASCII_USTRINGPARAM("@"));
322 cmdArg += OStringToOUString(cmdFileName, RTL_TEXTENCODING_UTF8);
324 OUString cpp;
325 OUString startDir;
326 if (osl_getExecutableFile(&cpp.pData) != osl_Process_E_None) {
327 OSL_ASSERT(false);
330 sal_Int32 idx= cpp.lastIndexOf(OUString( RTL_CONSTASCII_USTRINGPARAM("idlc")) );
331 cpp = cpp.copy(0, idx);
333 #if defined(SAL_W32) || defined(SAL_OS2)
334 cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("idlcpp.exe"));
335 #else
336 cpp += OUString( RTL_CONSTASCII_USTRINGPARAM("idlcpp"));
337 #endif
339 oslProcess hProcess = NULL;
340 oslProcessError procError = osl_Process_E_None;
342 procError = osl_executeProcess(cpp.pData, &cmdArg.pData, 1, osl_Process_WAIT,
343 0, startDir.pData, 0, 0, &hProcess);
345 oslProcessInfo hInfo;
346 hInfo.Size = (sal_uInt32)(sizeof(oslProcessInfo));
347 if (osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &hInfo)
348 != osl_Process_E_None)
350 OSL_ASSERT(false);
353 if ( procError || (hInfo.Code != 0) )
355 if ( procError != osl_Process_E_None )
356 fprintf(stderr, "%s: starting preprocessor failed\n", pOptions->getProgramName().getStr());
357 else
358 fprintf(stderr, "%s: preprocessing %s%s failed\n",
359 pOptions->getProgramName().getStr(),
360 pathname == 0 ? "" : "file ", fileName.getStr());
362 unlink(tmpFile.getStr());
363 unlink(preprocFile.getStr());
364 unlink(cmdFileName.getStr());
365 osl_freeProcessHandle(hProcess);
366 exit(hInfo.Code ? hInfo.Code : 99);
368 osl_freeProcessHandle(hProcess);
370 if (unlink(tmpFile.getStr()) != 0)
372 fprintf(stderr, "%s: Could not remove cpp input file %s\n",
373 pOptions->getProgramName().getStr(), tmpFile.getStr());
374 exit(99);
377 if (unlink(cmdFileName.getStr()) != 0)
379 fprintf(stderr, "%s: Could not remove unocpp command file %s\n",
380 pOptions->getProgramName().getStr(), cmdFileName.getStr());
382 exit(99);
385 if ( pOptions->isValid("-E") )
387 if (unlink(preprocFile) != 0)
389 fprintf(stderr, "%s: Could not remove parser input file %s\n",
390 pOptions->getProgramName().getStr(), preprocFile.getStr());
391 exit(99);
393 exit(0);
396 // parse file
397 yyin = fopen(preprocFile.getStr(), "r");
398 if (yyin == NULL)
400 fprintf(stderr, "%s: Could not open cpp output file %s\n",
401 pOptions->getProgramName().getStr(), preprocFile.getStr());
402 exit(99);
405 //yydebug = 0 no trace information
406 //yydebug = 1 parser produce trace information
407 yydebug = 0;
409 sal_Int32 nErrors = yyparse();
410 nErrors = idlc()->getErrorCount();
412 fclose(yyin);
413 if (unlink(preprocFile.getStr()) != 0)
415 fprintf(stderr, "%s: Could not remove parser input file %s\n",
416 pOptions->getProgramName().getStr(), preprocFile.getStr());
417 exit(99);
420 return nErrors;