xref: /aoo41x/main/idlc/source/idlcproduce.cxx (revision 2fe1ca3d)
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
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_idlc.hxx"
26 #include <idlc/idlc.hxx>
27 #include <idlc/astmodule.hxx>
28 #include <rtl/strbuf.hxx>
29 #include <osl/file.hxx>
30 #include <osl/thread.h>
31 
32 #if defined(SAL_W32) || defined(SAL_OS2)
33 #include <io.h>
34 #include <direct.h>
35 #include <errno.h>
36 #endif
37 
38 #ifdef SAL_UNX
39 #include <unistd.h>
40 #include <sys/stat.h>
41 #include <errno.h>
42 #endif
43 
44 #include <string.h>
45 
46 using namespace ::rtl;
47 using namespace ::osl;
48 
49 StringList* pCreatedDirectories = NULL;
50 
checkOutputPath(const OString & completeName)51 static sal_Bool checkOutputPath(const OString& completeName)
52 {
53     OString sysPathName = convertToAbsoluteSystemPath(completeName);
54 	OStringBuffer buffer(sysPathName.getLength());
55 
56 	if ( sysPathName.indexOf( SEPARATOR ) == -1 )
57 		return sal_True;
58 
59     sal_Int32 nIndex = 0;
60 	OString token(sysPathName.getToken(0, SEPARATOR, nIndex));
61 	const sal_Char* p = token.getStr();
62 	if (strcmp(p, "..") == 0
63         || *(p+1) == ':'
64         || strcmp(p, ".") == 0)
65 	{
66 		buffer.append(token);
67 		buffer.append(SEPARATOR);
68 	}
69     else
70         nIndex = 0;
71 
72     do
73 	{
74 		buffer.append(sysPathName.getToken(0, SEPARATOR, nIndex));
75 
76 		if ( buffer.getLength() > 0 && nIndex != -1 )
77 		{
78 #if defined(SAL_UNX) || defined(SAL_OS2)
79 			if (mkdir((char*)buffer.getStr(), 0777) == -1)
80 #else
81 			if (mkdir((char*)buffer.getStr()) == -1)
82 #endif
83 			{
84 				if (errno == ENOENT)
85 				{
86 					fprintf(stderr, "%s: cannot create directory '%s'\n",
87 							idlc()->getOptions()->getProgramName().getStr(), buffer.getStr());
88 					return sal_False;
89 				}
90 	        } else
91 			{
92 				if ( !pCreatedDirectories )
93 					pCreatedDirectories = new StringList();
94 				pCreatedDirectories->push_front(buffer.getStr());
95 			}
96 		}
97         buffer.append(SEPARATOR);
98 	} while( nIndex != -1 );
99 	return sal_True;
100 }
101 
cleanPath()102 static sal_Bool cleanPath()
103 {
104 	if ( pCreatedDirectories )
105 	{
106 		StringList::iterator iter = pCreatedDirectories->begin();
107 		StringList::iterator end = pCreatedDirectories->end();
108 		while ( iter != end )
109 		{
110 //#ifdef SAL_UNX
111 //			if (rmdir((char*)(*iter).getStr(), 0777) == -1)
112 //#else
113 			if (rmdir((char*)(*iter).getStr()) == -1)
114 //#endif
115 			{
116 				fprintf(stderr, "%s: cannot remove directory '%s'\n",
117 						idlc()->getOptions()->getProgramName().getStr(), (*iter).getStr());
118 				return sal_False;
119 			}
120 			++iter;
121 		}
122 		delete pCreatedDirectories;
123 	}
124 	return sal_True;
125 }
126 
removeIfExists(const OString & pathname)127 void removeIfExists(const OString& pathname)
128 {
129     unlink(pathname.getStr());
130 }
131 
produceFile(const OString & regFileName)132 sal_Int32 SAL_CALL produceFile(const OString& regFileName)
133 {
134 	Options* pOptions = idlc()->getOptions();
135 
136     OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_");
137 
138 	if ( !checkOutputPath(regFileName) )
139 	{
140 		fprintf(stderr, "%s: could not create path of registry file '%s'.\n",
141 				pOptions->getProgramName().getStr(), regFileName.getStr());
142 		return 1;
143 	}
144 
145 	removeIfExists(regTmpName);
146     OString urlRegTmpName = convertToFileUrl(regTmpName);
147 
148 	Registry regFile;
149 	if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != REG_NO_ERROR )
150 	{
151 		fprintf(stderr, "%s: could not create registry file '%s'\n",
152 				pOptions->getProgramName().getStr(), regTmpName.getStr());
153 		removeIfExists(regTmpName);
154 		removeIfExists(regFileName);
155 		cleanPath();
156 		return 1;
157 	}
158 
159 	RegistryKey rootKey;
160 	if ( regFile.openRootKey(rootKey) != REG_NO_ERROR )
161 	{
162 		fprintf(stderr, "%s: could not open root of registry file '%s'\n",
163 				pOptions->getProgramName().getStr(), regFileName.getStr());
164 		removeIfExists(regTmpName);
165 		removeIfExists(regFileName);
166 		cleanPath();
167 		return 1;
168 	}
169 
170 	// produce registry file
171 	if ( !idlc()->getRoot()->dump(rootKey) )
172 	{
173 		rootKey.releaseKey();
174 		regFile.close();
175 		regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8));
176 		removeIfExists(regFileName);
177 		cleanPath();
178 		return 1;
179 	}
180 
181 	rootKey.releaseKey();
182 	if ( regFile.close() != REG_NO_ERROR )
183 	{
184 		fprintf(stderr, "%s: could not close registry file '%s'\n",
185 				pOptions->getProgramName().getStr(), regFileName.getStr());
186 		removeIfExists(regTmpName);
187 		removeIfExists(regFileName);
188 		cleanPath();
189 		return 1;
190 	}
191 
192 	removeIfExists(regFileName);
193 
194     if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()),
195                     OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) {
196 		fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n",
197 				idlc()->getOptions()->getProgramName().getStr(),
198 				regTmpName.getStr(), regFileName.getStr());
199 		removeIfExists(regTmpName);
200 		cleanPath();
201 		return 1;
202     }
203 	removeIfExists(regTmpName);
204 
205 	return 0;
206 }
207