gecko-dev/xpcom/io/nsLocalFileCommon.cpp
Gabriele Svelto 5dc21d568c Bug 1600545 - Remove useless inclusions of header files generated from IDL files in modules/, netwerk/, parser/, security/, startupcache/, storage/, toolkit/, tools/, uriloader/, widget/, xpcom/ and xpfe/ r=Ehsan
The inclusions were removed with the following very crude script and the
resulting breakage was fixed up by hand. The manual fixups did either
revert the changes done by the script, replace a generic header with a more
specific one or replace a header with a forward declaration.

find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do
    interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2)
    if [ -n "$interfaces" ]; then
        if [[ "$interfaces" == *$'\n'* ]]; then
          regexp="\("
          for i in $interfaces; do regexp="$regexp$i\|"; done
          regexp="${regexp%%\\\|}\)"
        else
          regexp="$interfaces"
        fi
        interface=$(basename "$path")
        rg -l "#include.*${interface%%.idl}.h" . | while read path2; do
            hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" )
            if [ $hits -eq 0 ]; then
                echo "Removing ${interface} from ${path2}"
                grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp
                mv -f "$path2".tmp "$path2"
            fi
        done
    fi
done

Differential Revision: https://phabricator.services.mozilla.com/D55444

--HG--
extra : moz-landing-system : lando
2019-12-06 09:17:57 +00:00

415 lines
10 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "nsLocalFile.h" // includes platform-specific headers
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsReadableUtils.h"
#include "nsPrintfCString.h"
#include "nsCRT.h"
#include "nsNativeCharsetUtils.h"
#include "nsUTF8Utils.h"
#include "nsArray.h"
#include "nsLocalFileCommon.h"
#ifdef XP_WIN
# include <string.h>
#endif
// Extensions that should be considered 'executable', ie will not allow users
// to open immediately without first saving to disk, and potentially provoke
// other warnings. PLEASE read the longer comment in
// toolkit/components/reputationservice/ApplicationReputation.h
// before modifying this list!
/* static */
const char* const sExecutableExts[] = {
// clang-format off
".ad",
".ade", // access project extension
".adp",
".air", // Adobe AIR installer
".app", // executable application
".application", // from bug 348763
".asp",
".bas",
".bat",
".chm",
".cmd",
".com",
".cpl",
".crt",
".exe",
".fxp", // FoxPro compiled app
".hlp",
".hta",
".inf",
".ins",
".isp",
".jar", // java application bundle
".jnlp",
".js",
".jse",
".lnk",
".mad", // Access Module Shortcut
".maf", // Access
".mag", // Access Diagram Shortcut
".mam", // Access Macro Shortcut
".maq", // Access Query Shortcut
".mar", // Access Report Shortcut
".mas", // Access Stored Procedure
".mat", // Access Table Shortcut
".mau", // Media Attachment Unit
".mav", // Access View Shortcut
".maw", // Access Data Access Page
".mda", // Access Add-in, MDA Access 2 Workgroup
".mdb",
".mde",
".mdt", // Access Add-in Data
".mdw", // Access Workgroup Information
".mdz", // Access Wizard Template
".msc",
".msh", // Microsoft Shell
".msh1", // Microsoft Shell
".msh1xml", // Microsoft Shell
".msh2", // Microsoft Shell
".msh2xml", // Microsoft Shell
".mshxml", // Microsoft Shell
".msi",
".msp",
".mst",
".ops", // Office Profile Settings
".pcd",
".pif",
".plg", // Developer Studio Build Log
".prf", // windows system file
".prg",
".pst",
".reg",
".scf", // Windows explorer command
".scr",
".sct",
".settingcontent-ms",
".shb",
".shs",
".url",
".vb",
".vbe",
".vbs",
".vdx",
".vsd",
".vsdm",
".vsdx",
".vsmacros", // Visual Studio .NET Binary-based Macro Project
".vss",
".vssm",
".vssx",
".vst",
".vstm",
".vstx",
".vsw",
".vsx",
".vtx",
".ws",
".wsc",
".wsf",
".wsh"
// clang-format on
};
#if !defined(MOZ_WIDGET_COCOA) && !defined(XP_WIN)
NS_IMETHODIMP
nsLocalFile::InitWithFile(nsIFile* aFile) {
if (NS_WARN_IF(!aFile)) {
return NS_ERROR_INVALID_ARG;
}
nsAutoCString path;
aFile->GetNativePath(path);
if (path.IsEmpty()) {
return NS_ERROR_INVALID_ARG;
}
return InitWithNativePath(path);
}
#endif
#define kMaxFilenameLength 255
#define kMaxExtensionLength 100
#define kMaxSequenceNumberLength 5 // "-9999"
// requirement: kMaxExtensionLength <
// kMaxFilenameLength - kMaxSequenceNumberLength
NS_IMETHODIMP
nsLocalFile::CreateUnique(uint32_t aType, uint32_t aAttributes) {
nsresult rv;
bool longName;
#ifdef XP_WIN
nsAutoString pathName, leafName, rootName, suffix;
rv = GetPath(pathName);
#else
nsAutoCString pathName, leafName, rootName, suffix;
rv = GetNativePath(pathName);
#endif
if (NS_FAILED(rv)) {
return rv;
}
auto FailedBecauseExists = [&](nsresult aRv) {
if (aRv == NS_ERROR_FILE_ACCESS_DENIED) {
bool exists;
return NS_SUCCEEDED(Exists(&exists)) && exists;
}
return aRv == NS_ERROR_FILE_ALREADY_EXISTS;
};
longName =
(pathName.Length() + kMaxSequenceNumberLength > kMaxFilenameLength);
if (!longName) {
rv = Create(aType, aAttributes);
if (!FailedBecauseExists(rv)) {
return rv;
}
}
#ifdef XP_WIN
rv = GetLeafName(leafName);
if (NS_FAILED(rv)) {
return rv;
}
const int32_t lastDot = leafName.RFindChar(char16_t('.'));
#else
rv = GetNativeLeafName(leafName);
if (NS_FAILED(rv)) {
return rv;
}
const int32_t lastDot = leafName.RFindChar('.');
#endif
if (lastDot == kNotFound) {
rootName = leafName;
} else {
suffix = Substring(leafName, lastDot); // include '.'
rootName = Substring(leafName, 0, lastDot); // strip suffix and dot
}
if (longName) {
int32_t maxRootLength =
(kMaxFilenameLength - (pathName.Length() - leafName.Length()) -
suffix.Length() - kMaxSequenceNumberLength);
// We cannot create an item inside a directory whose name is too long.
// Also, ensure that at least one character remains after we truncate
// the root name, as we don't want to end up with an empty leaf name.
if (maxRootLength < 2) {
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
#ifdef XP_WIN
// ensure that we don't cut the name in mid-UTF16-character
rootName.SetLength(NS_IS_LOW_SURROGATE(rootName[maxRootLength])
? maxRootLength - 1
: maxRootLength);
SetLeafName(rootName + suffix);
#else
if (NS_IsNativeUTF8()) {
// ensure that we don't cut the name in mid-UTF8-character
// (assume the name is valid UTF8 to begin with)
while (UTF8traits::isInSeq(rootName[maxRootLength])) {
--maxRootLength;
}
// Another check to avoid ending up with an empty leaf name.
if (maxRootLength == 0 && suffix.IsEmpty()) {
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
}
rootName.SetLength(maxRootLength);
SetNativeLeafName(rootName + suffix);
#endif
nsresult rvCreate = Create(aType, aAttributes);
if (!FailedBecauseExists(rvCreate)) {
return rvCreate;
}
}
for (int indx = 1; indx < 10000; ++indx) {
// start with "Picture-1.jpg" after "Picture.jpg" exists
#ifdef XP_WIN
SetLeafName(rootName +
NS_ConvertASCIItoUTF16(nsPrintfCString("-%d", indx)) + suffix);
#else
SetNativeLeafName(rootName + nsPrintfCString("-%d", indx) + suffix);
#endif
rv = Create(aType, aAttributes);
if (NS_SUCCEEDED(rv) || !FailedBecauseExists(rv)) {
return rv;
}
}
// The disk is full, sort of
return NS_ERROR_FILE_TOO_BIG;
}
#if defined(XP_WIN)
static const char16_t kPathSeparatorChar = '\\';
#elif defined(XP_UNIX)
static const char16_t kPathSeparatorChar = '/';
#else
# error Need to define file path separator for your platform
#endif
static void SplitPath(char16_t* aPath, nsTArray<char16_t*>& aNodeArray) {
if (*aPath == 0) {
return;
}
if (*aPath == kPathSeparatorChar) {
aPath++;
}
aNodeArray.AppendElement(aPath);
for (char16_t* cp = aPath; *cp != 0; ++cp) {
if (*cp == kPathSeparatorChar) {
*cp++ = 0;
if (*cp == 0) {
break;
}
aNodeArray.AppendElement(cp);
}
}
}
NS_IMETHODIMP
nsLocalFile::GetRelativeDescriptor(nsIFile* aFromFile, nsACString& aResult) {
if (NS_WARN_IF(!aFromFile)) {
return NS_ERROR_INVALID_ARG;
}
//
// aResult will be UTF-8 encoded
//
nsresult rv;
aResult.Truncate(0);
nsAutoString thisPath, fromPath;
AutoTArray<char16_t*, 32> thisNodes;
AutoTArray<char16_t*, 32> fromNodes;
rv = GetPath(thisPath);
if (NS_FAILED(rv)) {
return rv;
}
rv = aFromFile->GetPath(fromPath);
if (NS_FAILED(rv)) {
return rv;
}
// get raw pointer to mutable string buffer
char16_t* thisPathPtr = thisPath.BeginWriting();
char16_t* fromPathPtr = fromPath.BeginWriting();
SplitPath(thisPathPtr, thisNodes);
SplitPath(fromPathPtr, fromNodes);
size_t nodeIndex;
for (nodeIndex = 0;
nodeIndex < thisNodes.Length() && nodeIndex < fromNodes.Length();
++nodeIndex) {
#ifdef XP_WIN
if (_wcsicmp(char16ptr_t(thisNodes[nodeIndex]),
char16ptr_t(fromNodes[nodeIndex]))) {
break;
}
#else
if (nsCRT::strcmp(thisNodes[nodeIndex], fromNodes[nodeIndex])) {
break;
}
#endif
}
size_t branchIndex = nodeIndex;
for (nodeIndex = branchIndex; nodeIndex < fromNodes.Length(); ++nodeIndex) {
aResult.AppendLiteral("../");
}
for (nodeIndex = branchIndex; nodeIndex < thisNodes.Length(); ++nodeIndex) {
NS_ConvertUTF16toUTF8 nodeStr(thisNodes[nodeIndex]);
aResult.Append(nodeStr);
if (nodeIndex + 1 < thisNodes.Length()) {
aResult.Append('/');
}
}
return NS_OK;
}
NS_IMETHODIMP
nsLocalFile::SetRelativeDescriptor(nsIFile* aFromFile,
const nsACString& aRelativeDesc) {
NS_NAMED_LITERAL_CSTRING(kParentDirStr, "../");
nsCOMPtr<nsIFile> targetFile;
nsresult rv = aFromFile->Clone(getter_AddRefs(targetFile));
if (NS_FAILED(rv)) {
return rv;
}
//
// aRelativeDesc is UTF-8 encoded
//
nsCString::const_iterator strBegin, strEnd;
aRelativeDesc.BeginReading(strBegin);
aRelativeDesc.EndReading(strEnd);
nsCString::const_iterator nodeBegin(strBegin), nodeEnd(strEnd);
nsCString::const_iterator pos(strBegin);
nsCOMPtr<nsIFile> parentDir;
while (FindInReadable(kParentDirStr, nodeBegin, nodeEnd)) {
rv = targetFile->GetParent(getter_AddRefs(parentDir));
if (NS_FAILED(rv)) {
return rv;
}
if (!parentDir) {
return NS_ERROR_FILE_UNRECOGNIZED_PATH;
}
targetFile = parentDir;
nodeBegin = nodeEnd;
pos = nodeEnd;
nodeEnd = strEnd;
}
nodeBegin = nodeEnd = pos;
while (nodeEnd != strEnd) {
FindCharInReadable('/', nodeEnd, strEnd);
targetFile->Append(NS_ConvertUTF8toUTF16(Substring(nodeBegin, nodeEnd)));
if (nodeEnd != strEnd) { // If there's more left in the string, inc over
// the '/' nodeEnd is on.
++nodeEnd;
}
nodeBegin = nodeEnd;
}
return InitWithFile(targetFile);
}
NS_IMETHODIMP
nsLocalFile::GetRelativePath(nsIFile* aFromFile, nsACString& aResult) {
return GetRelativeDescriptor(aFromFile, aResult);
}
NS_IMETHODIMP
nsLocalFile::SetRelativePath(nsIFile* aFromFile,
const nsACString& aRelativePath) {
return SetRelativeDescriptor(aFromFile, aRelativePath);
}