xref: /AOO41X/main/idlc/source/idlcproduce.cxx (revision 2fe1ca3d80babb7c0b18eb5dd968c2181ca17fa3)
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