mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-09 04:39:03 +02:00
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
532 lines
13 KiB
C++
532 lines
13 KiB
C++
/* 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 "nsCommandLine.h"
|
|
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsICategoryManager.h"
|
|
#include "nsICommandLineHandler.h"
|
|
#include "nsICommandLineValidator.h"
|
|
#include "nsIConsoleService.h"
|
|
#include "nsIClassInfoImpl.h"
|
|
#include "nsIFile.h"
|
|
#include "nsISimpleEnumerator.h"
|
|
#include "mozilla/SimpleEnumerator.h"
|
|
|
|
#include "nsNativeCharsetUtils.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsIFileProtocolHandler.h"
|
|
#include "nsIURI.h"
|
|
#include "nsUnicharUtils.h"
|
|
#include "nsTextFormatter.h"
|
|
#include "nsXPCOMCID.h"
|
|
#include "plstr.h"
|
|
#include "mozilla/Attributes.h"
|
|
|
|
#ifdef MOZ_WIDGET_COCOA
|
|
# include <CoreFoundation/CoreFoundation.h>
|
|
# include "nsILocalFileMac.h"
|
|
#elif defined(XP_WIN)
|
|
# include <windows.h>
|
|
# include <shlobj.h>
|
|
#elif defined(XP_UNIX)
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
#ifdef DEBUG_bsmedberg
|
|
# define DEBUG_COMMANDLINE
|
|
#endif
|
|
|
|
#define NS_COMMANDLINE_CID \
|
|
{ \
|
|
0x23bcc750, 0xdc20, 0x460b, { \
|
|
0xb2, 0xd4, 0x74, 0xd8, 0xf5, 0x8d, 0x36, 0x15 \
|
|
} \
|
|
}
|
|
|
|
using mozilla::SimpleEnumerator;
|
|
|
|
nsCommandLine::nsCommandLine()
|
|
: mState(STATE_INITIAL_LAUNCH), mPreventDefault(false) {}
|
|
|
|
NS_IMPL_CLASSINFO(nsCommandLine, nullptr, 0, NS_COMMANDLINE_CID)
|
|
NS_IMPL_ISUPPORTS_CI(nsCommandLine, nsICommandLine, nsICommandLineRunner)
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetLength(int32_t* aResult) {
|
|
*aResult = int32_t(mArgs.Length());
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetArgument(int32_t aIndex, nsAString& aResult) {
|
|
NS_ENSURE_ARG_MIN(aIndex, 0);
|
|
NS_ENSURE_ARG_MAX(aIndex, int32_t(mArgs.Length() - 1));
|
|
|
|
aResult = mArgs[aIndex];
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::FindFlag(const nsAString& aFlag, bool aCaseSensitive,
|
|
int32_t* aResult) {
|
|
NS_ENSURE_ARG(!aFlag.IsEmpty());
|
|
|
|
nsDefaultStringComparator caseCmp;
|
|
nsCaseInsensitiveStringComparator caseICmp;
|
|
nsStringComparator& c = aCaseSensitive
|
|
? static_cast<nsStringComparator&>(caseCmp)
|
|
: static_cast<nsStringComparator&>(caseICmp);
|
|
|
|
for (uint32_t f = 0; f < mArgs.Length(); f++) {
|
|
const nsString& arg = mArgs[f];
|
|
|
|
if (arg.Length() >= 2 && arg.First() == char16_t('-')) {
|
|
if (aFlag.Equals(Substring(arg, 1), c)) {
|
|
*aResult = f;
|
|
return NS_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
*aResult = -1;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::RemoveArguments(int32_t aStart, int32_t aEnd) {
|
|
NS_ENSURE_ARG_MIN(aStart, 0);
|
|
NS_ENSURE_ARG_MAX(uint32_t(aEnd) + 1, mArgs.Length());
|
|
|
|
for (int32_t i = aEnd; i >= aStart; --i) {
|
|
mArgs.RemoveElementAt(i);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::HandleFlag(const nsAString& aFlag, bool aCaseSensitive,
|
|
bool* aResult) {
|
|
nsresult rv;
|
|
|
|
int32_t found;
|
|
rv = FindFlag(aFlag, aCaseSensitive, &found);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (found == -1) {
|
|
*aResult = false;
|
|
return NS_OK;
|
|
}
|
|
|
|
*aResult = true;
|
|
RemoveArguments(found, found);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::HandleFlagWithParam(const nsAString& aFlag, bool aCaseSensitive,
|
|
nsAString& aResult) {
|
|
nsresult rv;
|
|
|
|
int32_t found;
|
|
rv = FindFlag(aFlag, aCaseSensitive, &found);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (found == -1) {
|
|
aResult.SetIsVoid(true);
|
|
return NS_OK;
|
|
}
|
|
|
|
if (found == int32_t(mArgs.Length()) - 1) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
++found;
|
|
|
|
{ // scope for validity of |param|, which RemoveArguments call invalidates
|
|
const nsString& param = mArgs[found];
|
|
if (!param.IsEmpty() && param.First() == '-') {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
aResult = param;
|
|
}
|
|
|
|
RemoveArguments(found - 1, found);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetState(uint32_t* aResult) {
|
|
*aResult = mState;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetPreventDefault(bool* aResult) {
|
|
*aResult = mPreventDefault;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::SetPreventDefault(bool aValue) {
|
|
mPreventDefault = aValue;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetWorkingDirectory(nsIFile** aResult) {
|
|
NS_ENSURE_TRUE(mWorkingDir, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
NS_ADDREF(*aResult = mWorkingDir);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::ResolveFile(const nsAString& aArgument, nsIFile** aResult) {
|
|
NS_ENSURE_TRUE(mWorkingDir, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
// This is some seriously screwed-up code. nsIFile.appendRelativeNativePath
|
|
// explicitly does not accept .. or . path parts, but that is exactly what we
|
|
// need here. So we hack around it.
|
|
|
|
nsresult rv;
|
|
|
|
#if defined(MOZ_WIDGET_COCOA)
|
|
nsCOMPtr<nsILocalFileMac> lfm(do_QueryInterface(mWorkingDir));
|
|
NS_ENSURE_TRUE(lfm, NS_ERROR_NO_INTERFACE);
|
|
|
|
nsCOMPtr<nsILocalFileMac> newfile(
|
|
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
|
NS_ENSURE_TRUE(newfile, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
CFURLRef baseurl;
|
|
rv = lfm->GetCFURL(&baseurl);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsAutoCString path;
|
|
NS_CopyUnicodeToNative(aArgument, path);
|
|
|
|
CFURLRef newurl = CFURLCreateFromFileSystemRepresentationRelativeToBase(
|
|
nullptr, (const UInt8*)path.get(), path.Length(), true, baseurl);
|
|
|
|
CFRelease(baseurl);
|
|
|
|
rv = newfile->InitWithCFURL(newurl);
|
|
CFRelease(newurl);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
newfile.forget(aResult);
|
|
return NS_OK;
|
|
|
|
#elif defined(XP_UNIX)
|
|
nsCOMPtr<nsIFile> lf(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
|
NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
if (aArgument.First() == '/') {
|
|
// absolute path
|
|
rv = lf->InitWithPath(aArgument);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_ADDREF(*aResult = lf);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsAutoCString nativeArg;
|
|
NS_CopyUnicodeToNative(aArgument, nativeArg);
|
|
|
|
nsAutoCString newpath;
|
|
mWorkingDir->GetNativePath(newpath);
|
|
|
|
newpath.Append('/');
|
|
newpath.Append(nativeArg);
|
|
|
|
rv = lf->InitWithNativePath(newpath);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
rv = lf->Normalize();
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
lf.forget(aResult);
|
|
return NS_OK;
|
|
|
|
#elif defined(XP_WIN)
|
|
nsCOMPtr<nsIFile> lf(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
|
NS_ENSURE_TRUE(lf, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
rv = lf->InitWithPath(aArgument);
|
|
if (NS_FAILED(rv)) {
|
|
// If it's a relative path, the Init is *going* to fail. We use string magic
|
|
// and win32 _fullpath. Note that paths of the form "\Relative\To\CurDrive"
|
|
// are going to fail, and I haven't figured out a way to work around this
|
|
// without the PathCombine() function, which is not available in plain
|
|
// win95/nt4
|
|
|
|
nsAutoString fullPath;
|
|
mWorkingDir->GetPath(fullPath);
|
|
|
|
fullPath.Append('\\');
|
|
fullPath.Append(aArgument);
|
|
|
|
WCHAR pathBuf[MAX_PATH];
|
|
if (!_wfullpath(pathBuf, fullPath.get(), MAX_PATH)) return NS_ERROR_FAILURE;
|
|
|
|
rv = lf->InitWithPath(nsDependentString(pathBuf));
|
|
if (NS_FAILED(rv)) return rv;
|
|
}
|
|
lf.forget(aResult);
|
|
return NS_OK;
|
|
|
|
#else
|
|
# error Need platform-specific logic here.
|
|
#endif
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::ResolveURI(const nsAString& aArgument, nsIURI** aResult) {
|
|
nsresult rv;
|
|
|
|
// First, we try to init the argument as an absolute file path. If this
|
|
// doesn't work, it is an absolute or relative URI.
|
|
|
|
nsCOMPtr<nsIIOService> io = do_GetIOService();
|
|
NS_ENSURE_TRUE(io, NS_ERROR_OUT_OF_MEMORY);
|
|
|
|
nsCOMPtr<nsIURI> workingDirURI;
|
|
if (mWorkingDir) {
|
|
io->NewFileURI(mWorkingDir, getter_AddRefs(workingDirURI));
|
|
}
|
|
|
|
nsCOMPtr<nsIFile> lf(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
|
|
rv = lf->InitWithPath(aArgument);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
lf->Normalize();
|
|
nsAutoCString url;
|
|
// Try to resolve the url for .url files.
|
|
rv = resolveShortcutURL(lf, url);
|
|
if (NS_SUCCEEDED(rv) && !url.IsEmpty()) {
|
|
return io->NewURI(url, nullptr, workingDirURI, aResult);
|
|
}
|
|
|
|
return io->NewFileURI(lf, aResult);
|
|
}
|
|
|
|
return io->NewURI(NS_ConvertUTF16toUTF8(aArgument), nullptr, workingDirURI,
|
|
aResult);
|
|
}
|
|
|
|
void nsCommandLine::appendArg(const char* arg) {
|
|
#ifdef DEBUG_COMMANDLINE
|
|
printf("Adding XP arg: %s\n", arg);
|
|
#endif
|
|
|
|
nsAutoString warg;
|
|
#ifdef XP_WIN
|
|
CopyUTF8toUTF16(nsDependentCString(arg), warg);
|
|
#else
|
|
NS_CopyNativeToUnicode(nsDependentCString(arg), warg);
|
|
#endif
|
|
|
|
mArgs.AppendElement(warg);
|
|
}
|
|
|
|
nsresult nsCommandLine::resolveShortcutURL(nsIFile* aFile, nsACString& outURL) {
|
|
nsCOMPtr<nsIFileProtocolHandler> fph;
|
|
nsresult rv = NS_GetFileProtocolHandler(getter_AddRefs(fph));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
rv = fph->ReadURLFile(aFile, getter_AddRefs(uri));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
return uri->GetSpec(outURL);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::Init(int32_t argc, const char* const* argv, nsIFile* aWorkingDir,
|
|
uint32_t aState) {
|
|
NS_ENSURE_ARG_MAX(aState, 2);
|
|
|
|
int32_t i;
|
|
|
|
mWorkingDir = aWorkingDir;
|
|
|
|
// skip argv[0], we don't want it
|
|
for (i = 1; i < argc; ++i) {
|
|
const char* curarg = argv[i];
|
|
|
|
#ifdef DEBUG_COMMANDLINE
|
|
printf("Testing native arg %i: '%s'\n", i, curarg);
|
|
#endif
|
|
#if defined(XP_WIN)
|
|
if (*curarg == '/') {
|
|
char* dup = PL_strdup(curarg);
|
|
if (!dup) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
*dup = '-';
|
|
char* colon = PL_strchr(dup, ':');
|
|
if (colon) {
|
|
*colon = '\0';
|
|
appendArg(dup);
|
|
appendArg(colon + 1);
|
|
} else {
|
|
appendArg(dup);
|
|
}
|
|
PL_strfree(dup);
|
|
continue;
|
|
}
|
|
#endif
|
|
if (*curarg == '-') {
|
|
if (*(curarg + 1) == '-') ++curarg;
|
|
|
|
char* dup = PL_strdup(curarg);
|
|
if (!dup) return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
char* eq = PL_strchr(dup, '=');
|
|
if (eq) {
|
|
*eq = '\0';
|
|
appendArg(dup);
|
|
appendArg(eq + 1);
|
|
} else {
|
|
appendArg(dup);
|
|
}
|
|
PL_strfree(dup);
|
|
continue;
|
|
}
|
|
|
|
appendArg(curarg);
|
|
}
|
|
|
|
mState = aState;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
template <typename... T>
|
|
static void LogConsoleMessage(const char16_t* fmt, T... args) {
|
|
nsString msg;
|
|
nsTextFormatter::ssprintf(msg, fmt, args...);
|
|
|
|
nsCOMPtr<nsIConsoleService> cs =
|
|
do_GetService("@mozilla.org/consoleservice;1");
|
|
if (cs) cs->LogStringMessage(msg.get());
|
|
}
|
|
|
|
nsresult nsCommandLine::EnumerateHandlers(EnumerateHandlersCallback aCallback,
|
|
void* aClosure) {
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsICategoryManager> catman(
|
|
do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
|
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> entenum;
|
|
rv = catman->EnumerateCategory("command-line-handler",
|
|
getter_AddRefs(entenum));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
for (auto& categoryEntry : SimpleEnumerator<nsICategoryEntry>(entenum)) {
|
|
nsAutoCString contractID;
|
|
categoryEntry->GetValue(contractID);
|
|
|
|
nsCOMPtr<nsICommandLineHandler> clh(do_GetService(contractID.get()));
|
|
if (!clh) {
|
|
nsCString entry;
|
|
categoryEntry->GetEntry(entry);
|
|
|
|
LogConsoleMessage(
|
|
u"Contract ID '%s' was registered as a command line handler for "
|
|
u"entry '%s', but could not be created.",
|
|
contractID.get(), entry.get());
|
|
continue;
|
|
}
|
|
|
|
rv = (aCallback)(clh, this, aClosure);
|
|
if (rv == NS_ERROR_ABORT) break;
|
|
|
|
rv = NS_OK;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult nsCommandLine::EnumerateValidators(
|
|
EnumerateValidatorsCallback aCallback, void* aClosure) {
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsICategoryManager> catman(
|
|
do_GetService(NS_CATEGORYMANAGER_CONTRACTID));
|
|
NS_ENSURE_TRUE(catman, NS_ERROR_UNEXPECTED);
|
|
|
|
nsCOMPtr<nsISimpleEnumerator> entenum;
|
|
rv = catman->EnumerateCategory("command-line-validator",
|
|
getter_AddRefs(entenum));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
for (auto& categoryEntry : SimpleEnumerator<nsICategoryEntry>(entenum)) {
|
|
nsAutoCString contractID;
|
|
categoryEntry->GetValue(contractID);
|
|
|
|
nsCOMPtr<nsICommandLineValidator> clv(do_GetService(contractID.get()));
|
|
if (!clv) continue;
|
|
|
|
rv = (aCallback)(clv, this, aClosure);
|
|
if (rv == NS_ERROR_ABORT) break;
|
|
|
|
rv = NS_OK;
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
static nsresult EnumValidate(nsICommandLineValidator* aValidator,
|
|
nsICommandLine* aThis, void*) {
|
|
return aValidator->Validate(aThis);
|
|
}
|
|
|
|
static nsresult EnumRun(nsICommandLineHandler* aHandler, nsICommandLine* aThis,
|
|
void*) {
|
|
return aHandler->Handle(aThis);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::Run() {
|
|
nsresult rv;
|
|
|
|
rv = EnumerateValidators(EnumValidate, nullptr);
|
|
if (rv == NS_ERROR_ABORT) return rv;
|
|
|
|
rv = EnumerateHandlers(EnumRun, nullptr);
|
|
if (rv == NS_ERROR_ABORT) return rv;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
static nsresult EnumHelp(nsICommandLineHandler* aHandler, nsICommandLine* aThis,
|
|
void* aClosure) {
|
|
nsresult rv;
|
|
|
|
nsCString text;
|
|
rv = aHandler->GetHelpInfo(text);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
NS_ASSERTION(
|
|
text.Length() == 0 || text.Last() == '\n',
|
|
"Help text from command line handlers should end in a newline.");
|
|
|
|
nsACString* totalText = reinterpret_cast<nsACString*>(aClosure);
|
|
totalText->Append(text);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsCommandLine::GetHelpText(nsACString& aResult) {
|
|
EnumerateHandlers(EnumHelp, &aResult);
|
|
|
|
return NS_OK;
|
|
}
|