From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- idlc/source/idlcproduce.cxx | 242 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 idlc/source/idlcproduce.cxx (limited to 'idlc/source/idlcproduce.cxx') diff --git a/idlc/source/idlcproduce.cxx b/idlc/source/idlcproduce.cxx new file mode 100644 index 000000000..2592fe0de --- /dev/null +++ b/idlc/source/idlcproduce.cxx @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +#include +#include +#include +#endif + +#ifdef SAL_UNX +#include +#include +#include +#endif + +#include + +using namespace ::osl; + +static std::list< OString > gaCreatedDirectories; + +static bool checkOutputPath(const OString& completeName) +{ + OString sysPathName = convertToAbsoluteSystemPath(completeName); + OStringBuffer buffer(sysPathName.getLength()+16); + + if ( sysPathName.indexOf( SEPARATOR ) == -1 ) + return true; + + sal_Int32 nIndex = 0; + std::string_view token(o3tl::getToken(sysPathName, 0, SEPARATOR, nIndex)); + if (o3tl::starts_with(token, "..") + || (token.size() >= 2 && token[1] == ':') + || o3tl::starts_with(token, ".")) + { + buffer.append(token); + buffer.append(SEPARATOR); + } + else + nIndex = 0; + + do + { + buffer.append(o3tl::getToken(sysPathName, 0, SEPARATOR, nIndex)); + + if ( !buffer.isEmpty() && nIndex != -1 ) + { +#if defined(SAL_UNX) + if (mkdir(buffer.getStr(), 0777) == -1) +#else + if (mkdir(buffer.getStr()) == -1) +#endif + { + if (errno == ENOENT) + { + fprintf(stderr, "%s: cannot create directory '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), buffer.getStr()); + return false; + } + } + else + { + gaCreatedDirectories.push_front(buffer.getStr()); + } + } + buffer.append(SEPARATOR); + } while( nIndex != -1 ); + return true; +} + +static bool cleanPath() +{ + for (auto const& createdDirectory : gaCreatedDirectories) + { +//#ifdef SAL_UNX +// if (rmdir((char*)createdDirectory.getStr(), 0777) == -1) +//#else + if (rmdir(createdDirectory.getStr()) == -1) +//#endif + { + fprintf(stderr, "%s: cannot remove directory '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), createdDirectory.getStr()); + return false; + } + } + gaCreatedDirectories.clear(); + return true; +} + +void removeIfExists(std::string_view pathname) +{ + osl::File::remove(OStringToOUString(pathname, RTL_TEXTENCODING_UTF8)); +} + +sal_Int32 +produceFile(const OString& regFileName, sPair_t const*const pDepFile) +{ + Options* pOptions = idlc()->getOptions(); + + OString regTmpName = regFileName.replaceAt(regFileName.getLength() -3, 3, "_idlc_"); + + if ( !checkOutputPath(regFileName) ) + { + fprintf(stderr, "%s: could not create path of registry file '%s'.\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + return 1; + } + + OString depTmpName; + if (pDepFile) + { + depTmpName = pDepFile->first.replaceAt( + regFileName.getLength() -3, 3, "_idlc_"); + if ( !checkOutputPath(depTmpName) ) + { + fprintf(stderr, "%s: could not create path of dep file '%s'.\n", + pOptions->getProgramName().getStr(), pDepFile->first.getStr()); + return 1; + } + removeIfExists(depTmpName); + } + + removeIfExists(regTmpName); + OString urlRegTmpName = convertToFileUrl(regTmpName); + + Registry regFile; + if ( regFile.create(OStringToOUString(urlRegTmpName, RTL_TEXTENCODING_UTF8)) != RegError::NO_ERROR ) + { + fprintf(stderr, "%s: could not create registry file '%s'\n", + pOptions->getProgramName().getStr(), regTmpName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + RegistryKey rootKey; + if ( regFile.openRootKey(rootKey) != RegError::NO_ERROR ) + { + fprintf(stderr, "%s: could not open root of registry file '%s'\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + // produce registry file + if ( !idlc()->getRoot()->dump(rootKey) ) + { + rootKey.releaseKey(); + if (regFile.close() != RegError::NO_ERROR) + { + fprintf(stderr, "%s: could not close registry file '%s'\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + } + regFile.destroy(OStringToOUString(regFileName, RTL_TEXTENCODING_UTF8)); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + rootKey.releaseKey(); + if ( regFile.close() != RegError::NO_ERROR ) + { + fprintf(stderr, "%s: could not close registry file '%s'\n", + pOptions->getProgramName().getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + if (pDepFile && !idlc()->dumpDeps(depTmpName, pDepFile->second)) + { + fprintf(stderr, "%s: could not write dep file '%s'\n", + pOptions->getProgramName().getStr(), pDepFile->first.getStr()); + removeIfExists(depTmpName); + removeIfExists(pDepFile->first); + removeIfExists(regTmpName); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + + removeIfExists(regFileName); + + if ( File::move(OStringToOUString(regTmpName, osl_getThreadTextEncoding()), + OStringToOUString(regFileName, osl_getThreadTextEncoding())) != FileBase::E_None ) { + fprintf(stderr, "%s: cannot rename temporary registry '%s' to '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + regTmpName.getStr(), regFileName.getStr()); + removeIfExists(regTmpName); + cleanPath(); + return 1; + } + removeIfExists(regTmpName); + + if (pDepFile) + { + removeIfExists(pDepFile->first); + if ( File::move(OStringToOUString(depTmpName, osl_getThreadTextEncoding()), + OStringToOUString(pDepFile->first, osl_getThreadTextEncoding())) != FileBase::E_None ) { + fprintf(stderr, "%s: cannot rename dep file '%s' to '%s'\n", + idlc()->getOptions()->getProgramName().getStr(), + depTmpName.getStr(), pDepFile->first.getStr()); + removeIfExists(depTmpName); + removeIfExists(pDepFile->first); + removeIfExists(regFileName); + cleanPath(); + return 1; + } + removeIfExists(depTmpName); + } + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3