--- a/chrome/src/Makefile.in
+++ b/chrome/src/Makefile.in
@@ -38,26 +38,22 @@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = chrome
-LIBRARY_NAME = chrome
-EXPORT_LIBRARY = 1
-IS_COMPONENT = 1
-MODULE_NAME = nsChromeModule
-GRE_MODULE = 1
+LIBRARY_NAME = chrome_s
LIBXUL_LIBRARY = 1
+FORCE_STATIC_LIB = 1
CPPSRCS = \
- nsChromeFactory.cpp \
nsChromeRegistry.cpp \
nsChromeProtocolHandler.cpp \
$(NULL)
EXTRA_DSO_LDOPTS = \
$(MOZ_UNICHARUTIL_LIBS) \
$(MOZ_COMPONENT_LIBS) \
$(NULL)
@@ -71,8 +67,12 @@ EXTRA_DSO_LDOPTS += $(TK_LIBS)
endif
include $(topsrcdir)/config/rules.mk
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
endif
+LOCAL_INCLUDES += \
+ -I$(topsrcdir)/xpcom/components \
+ -I$(DEPTH)/xpcom \
+ $(NULL)
deleted file mode 100644
--- a/chrome/src/nsChromeFactory.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (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.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#include "nsCOMPtr.h"
-#include "mozilla/ModuleUtils.h"
-
-#include "nsIServiceManager.h"
-#include "nsIComponentManager.h"
-#include "nsIChromeRegistry.h"
-#include "nscore.h"
-#include "nsChromeProtocolHandler.h"
-#include "nsChromeRegistry.h"
-
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
-
-NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
-NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
-
-static const mozilla::Module::CIDEntry kChromeCIDs[] = {
- { &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
- { &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
- { NULL }
-};
-
-static const mozilla::Module::ContractIDEntry kChromeContracts[] = {
- { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
- { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
- { NULL }
-};
-
-static const mozilla::Module kChromeModule = {
- mozilla::Module::kVersion,
- kChromeCIDs,
- kChromeContracts
-};
-
-NSMODULE_DEFN(nsChromeModule) = &kChromeModule;
-
--- a/chrome/src/nsChromeRegistry.cpp
+++ b/chrome/src/nsChromeRegistry.cpp
@@ -50,16 +50,17 @@
#elif defined(XP_MACOSX)
#include <CoreServices/CoreServices.h>
#elif defined(MOZ_WIDGET_GTK2)
#include <gtk/gtk.h>
#endif
#include "nsAppDirectoryServiceDefs.h"
#include "nsArrayEnumerator.h"
+#include "nsComponentManager.h"
#include "nsStringEnumerator.h"
#include "nsEnumeratorUtils.h"
#include "nsCOMPtr.h"
#include "nsDOMError.h"
#include "nsEscape.h"
#include "nsInt64.h"
#include "nsLayoutCID.h"
#include "nsNetCID.h"
@@ -457,27 +458,18 @@ nsresult
nsChromeRegistry::Init()
{
nsresult rv;
// Check to see if necko and the JAR protocol handler are registered yet
// if not, somebody is doing work during XPCOM registration that they
// shouldn't be doing. See bug 292549, where JS components are trying
// to call Components.utils.import("chrome:///") early in registration
-
- nsCOMPtr<nsIIOService> io (do_GetIOService());
- if (!io) return NS_ERROR_FAILURE;
-
- nsCOMPtr<nsIProtocolHandler> ph;
- rv = io->GetProtocolHandler("jar", getter_AddRefs(ph));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIJARProtocolHandler> jph = do_QueryInterface(ph);
- if (!jph)
- return NS_ERROR_NOT_INITIALIZED;
+ NS_ASSERTION(nsCOMPtr<nsIIOService>(mozilla::services::GetIOService()),
+ "I/O service not registered or available early enough?");
if (!PL_DHashTableInit(&mPackagesHash, &kTableOps,
nsnull, sizeof(PackageEntry), 16))
return NS_ERROR_FAILURE;
if (!mOverlayHash.Init() ||
!mStyleHash.Init() ||
!mOverrideTable.Init())
@@ -526,18 +518,16 @@ nsChromeRegistry::Init()
nsCOMPtr<nsIObserverService> obsService =
mozilla::services::GetObserverService();
if (obsService) {
obsService->AddObserver(this, "command-line-startup", PR_TRUE);
obsService->AddObserver(this, "profile-initial-state", PR_TRUE);
}
- CheckForNewChrome();
-
mInitialized = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::CheckForOSAccessibility()
{
@@ -1142,111 +1132,22 @@ static PLDHashOperator
RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, PRUint32 number, void *arg)
{
return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
}
NS_IMETHODIMP
nsChromeRegistry::CheckForNewChrome()
{
- nsresult rv;
-
PL_DHashTableEnumerate(&mPackagesHash, RemoveAll, nsnull);
mOverlayHash.Clear();
mStyleHash.Clear();
mOverrideTable.Clear();
- nsCOMPtr<nsIProperties> dirSvc (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
- NS_ENSURE_TRUE(dirSvc, NS_ERROR_FAILURE);
-
- // check the extra chrome directories
- nsCOMPtr<nsISimpleEnumerator> chromeML;
- rv = dirSvc->Get(NS_CHROME_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
- getter_AddRefs(chromeML));
- if (NS_FAILED(rv)) {
- // ok, then simply load all .manifest files in the app chrome dir.
- nsCOMPtr<nsIFile> chromeDir;
- rv = dirSvc->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsIFile),
- getter_AddRefs(chromeDir));
- if (NS_FAILED(rv))
- return rv;
- rv = NS_NewSingletonEnumerator(getter_AddRefs(chromeML), chromeDir);
- if (NS_FAILED(rv))
- return rv;
- }
-
- PRBool exists;
- nsCOMPtr<nsISupports> next;
- while (NS_SUCCEEDED(chromeML->HasMoreElements(&exists)) && exists) {
- chromeML->GetNext(getter_AddRefs(next));
- nsCOMPtr<nsILocalFile> lmanifest = do_QueryInterface(next);
- if (!lmanifest) {
- NS_ERROR("Directory enumerator returned a non-nsILocalFile");
- continue;
- }
-
- PRBool isDir;
- if (NS_SUCCEEDED(lmanifest->IsDirectory(&isDir)) && isDir) {
- nsCOMPtr<nsISimpleEnumerator> entries;
- rv = lmanifest->GetDirectoryEntries(getter_AddRefs(entries));
- if (NS_FAILED(rv))
- continue;
-
- while (NS_SUCCEEDED(entries->HasMoreElements(&exists)) && exists) {
- entries->GetNext(getter_AddRefs(next));
- lmanifest = do_QueryInterface(next);
- if (lmanifest) {
- nsCAutoString leafName;
- lmanifest->GetNativeLeafName(leafName);
- if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".manifest"))) {
- rv = ProcessManifest(lmanifest, PR_FALSE);
- if (NS_FAILED(rv)) {
- nsCAutoString path;
- lmanifest->GetNativePath(path);
- LogMessage("Failed to process chrome manifest '%s'.",
- path.get());
-
- }
- }
- }
- }
- }
- else {
- rv = ProcessManifest(lmanifest, PR_FALSE);
- if (NS_FAILED(rv)) {
- nsCAutoString path;
- lmanifest->GetNativePath(path);
- LogMessage("Failed to process chrome manifest: '%s'.",
- path.get());
- }
- }
- }
-
- rv = dirSvc->Get(NS_SKIN_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
- getter_AddRefs(chromeML));
- if (NS_FAILED(rv))
- return NS_OK;
-
- while (NS_SUCCEEDED(chromeML->HasMoreElements(&exists)) && exists) {
- chromeML->GetNext(getter_AddRefs(next));
- nsCOMPtr<nsILocalFile> lmanifest = do_QueryInterface(next);
- if (!lmanifest) {
- NS_ERROR("Directory enumerator returned a non-nsILocalFile");
- continue;
- }
-
- rv = ProcessManifest(lmanifest, PR_TRUE);
- if (NS_FAILED(rv)) {
- nsCAutoString path;
- lmanifest->GetNativePath(path);
- LogMessage("Failed to process chrome manifest: '%s'.",
- path.get());
- }
- }
-
+ nsComponentManagerImpl::gComponentManager->RereadChromeManifests();
return NS_OK;
}
NS_IMETHODIMP_(PRBool)
nsChromeRegistry::WrappersEnabled(nsIURI *aURI)
{
nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aURI));
if (!chromeURL)
@@ -1346,822 +1247,288 @@ NS_IMETHODIMP nsChromeRegistry::Observe(
}
else {
NS_ERROR("Unexpected observer topic!");
}
return rv;
}
-nsresult
-nsChromeRegistry::ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly)
+nsIURI*
+nsChromeRegistry::ManifestProcessingContext::GetManifestURI()
{
- nsresult rv;
-
- PRFileDesc* fd;
- rv = aManifest->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
- NS_ENSURE_SUCCESS(rv, rv);
-
- PRInt32 n, size;
- char *buf;
-
- size = PR_Available(fd);
- if (size == -1) {
- rv = NS_ERROR_UNEXPECTED;
- goto mend;
- }
-
- buf = (char *) malloc(size + 1);
- if (!buf) {
- rv = NS_ERROR_OUT_OF_MEMORY;
- goto mend;
- }
-
- n = PR_Read(fd, buf, size);
- if (n > 0) {
- buf[size] = '\0';
- rv = ProcessManifestBuffer(buf, size, aManifest, aSkinOnly);
- }
- free(buf);
-
-mend:
- PR_Close(fd);
- return rv;
-}
-
-static const char kWhitespace[] = "\t ";
-static const char kNewlines[] = "\r\n";
+ if (!mManifestURI) {
+ nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
+ if (!io) {
+ NS_WARNING("No IO service trying to process chrome manifests");
+ return NULL;
+ }
-/**
- * Check for a modifier flag of the following forms:
- * "flag" (same as "true")
- * "flag=yes|true|1"
- * "flag="no|false|0"
- * @param aFlag The flag to compare.
- * @param aData The tokenized data to check; this is lowercased
- * before being passed in.
- * @param aResult If the flag is found, the value is assigned here.
- * @return Whether the flag was handled.
- */
-static PRBool
-CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, PRBool& aResult)
-{
- if (!StringBeginsWith(aData, aFlag))
- return PR_FALSE;
-
- if (aFlag.Length() == aData.Length()) {
- // the data is simply "flag", which is the same as "flag=yes"
- aResult = PR_TRUE;
- return PR_TRUE;
+ io->NewFileURI(mFile, getter_AddRefs(mManifestURI));
}
-
- if (aData.CharAt(aFlag.Length()) != '=') {
- // the data is "flag2=", which is not anything we care about
- return PR_FALSE;
- }
-
- if (aData.Length() == aFlag.Length() + 1) {
- aResult = PR_FALSE;
- return PR_TRUE;
- }
-
- switch (aData.CharAt(aFlag.Length() + 1)) {
- case '1':
- case 't': //true
- case 'y': //yes
- aResult = PR_TRUE;
- return PR_TRUE;
-
- case '0':
- case 'f': //false
- case 'n': //no
- aResult = PR_FALSE;
- return PR_TRUE;
- }
-
- return PR_FALSE;
+ return mManifestURI;
}
-enum TriState {
- eUnspecified,
- eBad,
- eOK
-};
-
-/**
- * Check for a modifier flag of the following form:
- * "flag=string"
- * "flag!=string"
- * @param aFlag The flag to compare.
- * @param aData The tokenized data to check; this is lowercased
- * before being passed in.
- * @param aValue The value that is expected.
- * @param aResult If this is "ok" when passed in, this is left alone.
- * Otherwise if the flag is found it is set to eBad or eOK.
- * @return Whether the flag was handled.
- */
-static PRBool
-CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
- const nsSubstring& aValue, TriState& aResult)
+nsIXPConnect*
+nsChromeRegistry::ManifestProcessingContext::GetXPConnect()
{
- if (aData.Length() < aFlag.Length() + 1)
- return PR_FALSE;
-
- if (!StringBeginsWith(aData, aFlag))
- return PR_FALSE;
+ if (!mXPConnect)
+ mXPConnect = do_GetService("@mozilla.org/js/xpc/XPConnect;1");
- PRBool comparison = PR_TRUE;
- if (aData[aFlag.Length()] != '=') {
- if (aData[aFlag.Length()] == '!' &&
- aData.Length() >= aFlag.Length() + 2 &&
- aData[aFlag.Length() + 1] == '=')
- comparison = PR_FALSE;
- else
- return PR_FALSE;
- }
-
- if (aResult != eOK) {
- nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2));
- if (testdata.Equals(aValue))
- aResult = comparison ? eOK : eBad;
- else
- aResult = comparison ? eBad : eOK;
- }
-
- return PR_TRUE;
+ return mXPConnect;
}
-/**
- * Check for a modifier flag of the following form:
- * "flag=version"
- * "flag<=version"
- * "flag<version"
- * "flag>=version"
- * "flag>version"
- * @param aFlag The flag to compare.
- * @param aData The tokenized data to check; this is lowercased
- * before being passed in.
- * @param aValue The value that is expected. If this is empty then no
- * comparison will match.
- * @param aChecker the version checker to use. If null, aResult will always
- * be eBad.
- * @param aResult If this is eOK when passed in, this is left alone.
- * Otherwise if the flag is found it is set to eBad or eOK.
- * @return Whether the flag was handled.
- */
-
-#define COMPARE_EQ 1 << 0
-#define COMPARE_LT 1 << 1
-#define COMPARE_GT 1 << 2
-
-static PRBool
-CheckVersionFlag(const nsSubstring& aFlag, const nsSubstring& aData,
- const nsSubstring& aValue, nsIVersionComparator* aChecker,
- TriState& aResult)
+already_AddRefed<nsIURI>
+nsChromeRegistry::ManifestProcessingContext::ResolveURI(const char* uri)
{
- if (aData.Length() < aFlag.Length() + 2)
- return PR_FALSE;
-
- if (!StringBeginsWith(aData, aFlag))
- return PR_FALSE;
-
- if (aValue.Length() == 0) {
- if (aResult != eOK)
- aResult = eBad;
- return PR_TRUE;
- }
-
- PRUint32 comparison;
- nsAutoString testdata;
-
- switch (aData[aFlag.Length()]) {
- case '=':
- comparison = COMPARE_EQ;
- testdata = Substring(aData, aFlag.Length() + 1);
- break;
+ nsIURI* baseuri = GetManifestURI();
+ if (!baseuri)
+ return NULL;
- case '<':
- if (aData[aFlag.Length() + 1] == '=') {
- comparison = COMPARE_EQ | COMPARE_LT;
- testdata = Substring(aData, aFlag.Length() + 2);
- }
- else {
- comparison = COMPARE_LT;
- testdata = Substring(aData, aFlag.Length() + 1);
- }
- break;
-
- case '>':
- if (aData[aFlag.Length() + 1] == '=') {
- comparison = COMPARE_EQ | COMPARE_GT;
- testdata = Substring(aData, aFlag.Length() + 2);
- }
- else {
- comparison = COMPARE_GT;
- testdata = Substring(aData, aFlag.Length() + 1);
- }
- break;
-
- default:
- return PR_FALSE;
- }
+ nsCOMPtr<nsIURI> resolved;
+ nsresult rv = NS_NewURI(getter_AddRefs(resolved), uri, baseuri);
+ if (NS_FAILED(rv))
+ return NULL;
- if (testdata.Length() == 0)
- return PR_FALSE;
-
- if (aResult != eOK) {
- if (!aChecker) {
- aResult = eBad;
- }
- else {
- PRInt32 c;
- nsresult rv = aChecker->Compare(NS_ConvertUTF16toUTF8(aValue),
- NS_ConvertUTF16toUTF8(testdata), &c);
- if (NS_FAILED(rv)) {
- aResult = eBad;
- }
- else {
- if ((c == 0 && comparison & COMPARE_EQ) ||
- (c < 0 && comparison & COMPARE_LT) ||
- (c > 0 && comparison & COMPARE_GT))
- aResult = eOK;
- else
- aResult = eBad;
- }
- }
- }
-
- return PR_TRUE;
+ return resolved.forget();
}
static void
EnsureLowerCase(char *aBuf)
{
for (; *aBuf; ++aBuf) {
char ch = *aBuf;
if (ch >= 'A' && ch <= 'Z')
*aBuf = ch + 'a' - 'A';
}
}
-nsresult
-nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
- nsILocalFile* aManifest,
- PRBool aSkinOnly)
+void
+nsChromeRegistry::ManifestContent(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
{
- nsresult rv;
+ char* package = argv[0];
+ char* uri = argv[1];
+
+ EnsureLowerCase(package);
+
+ nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+ if (!resolved) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI '%s'.", uri);
+ return;
+ }
+
+ if (!CanLoadResource(resolved)) {
+ LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+ "During chrome registration, cannot register non-local URI '%s' as content.",
+ uri);
+ return;
+ }
+
+ PackageEntry* entry =
+ static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+ & (const nsACString&) nsDependentCString(package),
+ PL_DHASH_ADD));
+ if (!entry)
+ return;
+
+ entry->baseURI = resolved;
+
+ if (platform)
+ entry->flags |= PackageEntry::PLATFORM_PACKAGE;
+ if (contentaccessible)
+ entry->flags |= PackageEntry::CONTENT_ACCESSIBLE;
+ if (cx.GetXPConnect()) {
+ nsCAutoString urlp("chrome://");
+ urlp.Append(package);
+ urlp.Append('/');
+
+ cx.GetXPConnect()->FlagSystemFilenamePrefix(urlp.get(), true);
+ }
+}
+
+void
+nsChromeRegistry::ManifestLocale(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* package = argv[0];
+ char* provider = argv[1];
+ char* uri = argv[2];
+
+ EnsureLowerCase(package);
+
+ nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+ if (!resolved) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI '%s'.", uri);
+ return;
+ }
+
+ if (!CanLoadResource(resolved)) {
+ LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+ "During chrome registration, cannot register non-local URI '%s' as content.",
+ uri);
+ return;
+ }
+
+ PackageEntry* entry =
+ static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+ & (const nsACString&) nsDependentCString(package),
+ PL_DHASH_ADD));
+ if (!entry)
+ return;
+
+ entry->locales.SetBase(nsDependentCString(provider), resolved);
+}
+
+void
+nsChromeRegistry::ManifestSkin(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* package = argv[0];
+ char* provider = argv[1];
+ char* uri = argv[2];
+
+ EnsureLowerCase(package);
+
+ nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+ if (!resolved) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI '%s'.", uri);
+ return;
+ }
- NS_NAMED_LITERAL_STRING(kPlatform, "platform");
- NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
- NS_NAMED_LITERAL_STRING(kApplication, "application");
- NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
- NS_NAMED_LITERAL_STRING(kOs, "os");
- NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
+ if (!CanLoadResource(resolved)) {
+ LogMessageWithContext(resolved, lineno, nsIScriptError::warningFlag,
+ "During chrome registration, cannot register non-local URI '%s' as content.",
+ uri);
+ return;
+ }
+
+ PackageEntry* entry =
+ static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
+ & (const nsACString&) nsDependentCString(package),
+ PL_DHASH_ADD));
+ if (!entry)
+ return;
+
+ entry->skins.SetBase(nsDependentCString(provider), resolved);
+}
+
+void
+nsChromeRegistry::ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* base = argv[0];
+ char* overlay = argv[1];
+
+ nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
+ nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
+ if (!baseuri || !overlayuri) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI.");
+ return;
+ }
+
+ if (!CanLoadResource(overlayuri)) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "Cannot register non-local URI '%s' as an overlay.", overlay);
+ return;
+ }
+
+ mOverlayHash.Add(baseuri, overlayuri);
+}
+
+void
+nsChromeRegistry::ManifestStyle(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* base = argv[0];
+ char* overlay = argv[1];
- nsCOMPtr<nsIIOService> io (do_GetIOService());
- if (!io) return NS_ERROR_FAILURE;
+ nsCOMPtr<nsIURI> baseuri = cx.ResolveURI(base);
+ nsCOMPtr<nsIURI> overlayuri = cx.ResolveURI(overlay);
+ if (!baseuri || !overlayuri) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI.");
+ return;
+ }
+
+ if (!CanLoadResource(overlayuri)) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "Cannot register non-local URI '%s' as a style overlay.", overlay);
+ return;
+ }
+
+ mStyleHash.Add(baseuri, overlayuri);
+}
+
+void
+nsChromeRegistry::ManifestOverride(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* chrome = argv[0];
+ char* resolved = argv[1];
+
+ nsCOMPtr<nsIURI> chromeuri = cx.ResolveURI(chrome);
+ nsCOMPtr<nsIURI> resolveduri = cx.ResolveURI(resolved);
+ if (!chromeuri || !resolveduri) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI.");
+ return;
+ }
+
+ if (!CanLoadResource(resolveduri)) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "Cannot register non-local URI '%s' for an override.", resolved);
+ return;
+ }
+ mOverrideTable.Put(chromeuri, resolveduri);
+}
+
+void
+nsChromeRegistry::ManifestResource(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible)
+{
+ char* package = argv[0];
+ char* uri = argv[1];
+
+ EnsureLowerCase(package);
+ nsDependentCString host(package);
+
+ nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
+ if (!io) {
+ NS_WARNING("No IO service trying to process chrome manifests");
+ return;
+ }
nsCOMPtr<nsIProtocolHandler> ph;
- rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIResProtocolHandler> rph (do_QueryInterface(ph));
- if (!rph) return NS_ERROR_FAILURE;
-
- nsCOMPtr<nsIURI> manifestURI;
- rv = io->NewFileURI(aManifest, getter_AddRefs(manifestURI));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIXPConnect> xpc (do_GetService("@mozilla.org/js/xpc/XPConnect;1"));
- nsCOMPtr<nsIVersionComparator> vc (do_GetService("@mozilla.org/xpcom/version-comparator;1"));
-
- nsAutoString appID;
- nsAutoString appVersion;
- nsAutoString osTarget;
- nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
- if (xapp) {
- nsCAutoString s;
- rv = xapp->GetID(s);
- if (NS_SUCCEEDED(rv))
- CopyUTF8toUTF16(s, appID);
-
- rv = xapp->GetVersion(s);
- if (NS_SUCCEEDED(rv))
- CopyUTF8toUTF16(s, appVersion);
-
- nsCOMPtr<nsIXULRuntime> xruntime (do_QueryInterface(xapp));
- if (xruntime) {
- rv = xruntime->GetOS(s);
- if (NS_SUCCEEDED(rv)) {
- CopyUTF8toUTF16(s, osTarget);
- ToLowerCase(osTarget);
- }
- }
- }
+ nsresult rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
+ if (NS_FAILED(rv))
+ return;
- nsAutoString osVersion;
-#if defined(XP_WIN)
- OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
- if (GetVersionEx(&info)) {
- nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
- info.dwMajorVersion,
- info.dwMinorVersion);
- }
-#elif defined(XP_MACOSX)
- SInt32 majorVersion, minorVersion;
- if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
- (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
- nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
- majorVersion,
- minorVersion);
- }
-#elif defined(MOZ_WIDGET_GTK2)
- nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
- gtk_major_version,
- gtk_minor_version);
-#endif
-
- char *token;
- char *newline = buf;
- PRUint32 line = 0;
-
- // outer loop tokenizes by newline
- while (nsnull != (token = nsCRT::strtok(newline, kNewlines, &newline))) {
- ++line;
-
- if (*token == '#') // ignore lines that begin with # as comments
- continue;
-
- char *whitespace = token;
- token = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!token) continue;
-
- if (!strcmp(token, "content")) {
- if (aSkinOnly) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring content registration in skin-only manifest.");
- continue;
- }
- char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!package || !uri) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Malformed content registration.");
- continue;
- }
-
- EnsureLowerCase(package);
-
- // NOTE: We check for platform modifiers on content packages, but they
- // are *applied* to content|skin|locale.
-
- PRBool platform = PR_FALSE;
- PRBool contentAccessible = PR_FALSE;
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOsVersion = eUnspecified;
- TriState stOs = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckFlag(kPlatform, wtoken, platform) ||
- CheckFlag(kContentAccessible, wtoken, contentAccessible) ||
- CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsCOMPtr<nsIURI> resolved;
- rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
- getter_AddRefs(resolved));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as content.",
- uri);
- continue;
- }
-
- PackageEntry* entry =
- static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
- & (const nsACString&) nsDependentCString(package),
- PL_DHASH_ADD));
- if (!entry)
- return NS_ERROR_OUT_OF_MEMORY;
-
- entry->baseURI = resolved;
-
- if (platform)
- entry->flags |= PackageEntry::PLATFORM_PACKAGE;
- if (contentAccessible)
- entry->flags |= PackageEntry::CONTENT_ACCESSIBLE;
- if (xpc) {
- nsCAutoString urlp("chrome://");
- urlp.Append(package);
- urlp.Append('/');
-
- rv = xpc->FlagSystemFilenamePrefix(urlp.get(), true);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- }
- else if (!strcmp(token, "locale")) {
- if (aSkinOnly) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring locale registration in skin-only manifest.");
- continue;
- }
- char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *provider = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!package || !provider || !uri) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Malformed locale registration.");
- continue;
- }
-
- EnsureLowerCase(package);
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOs = eUnspecified;
- TriState stOsVersion = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsCOMPtr<nsIURI> resolved;
- rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
- getter_AddRefs(resolved));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as a locale.",
- uri);
- continue;
- }
-
- PackageEntry* entry =
- static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
- & (const nsACString&) nsDependentCString(package),
- PL_DHASH_ADD));
- if (!entry)
- return NS_ERROR_OUT_OF_MEMORY;
-
- entry->locales.SetBase(nsDependentCString(provider), resolved);
- }
- else if (!strcmp(token, "skin")) {
- char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *provider = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!package || !provider || !uri) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Malformed skin registration.");
- continue;
- }
-
- EnsureLowerCase(package);
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOs = eUnspecified;
- TriState stOsVersion = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
+ nsCOMPtr<nsIResProtocolHandler> rph = do_QueryInterface(ph);
- nsCOMPtr<nsIURI> resolved;
- rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
- getter_AddRefs(resolved));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as a skin.",
- uri);
- continue;
- }
-
- PackageEntry* entry =
- static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
- & (const nsACString&) nsDependentCString(package),
- PL_DHASH_ADD));
- if (!entry)
- return NS_ERROR_OUT_OF_MEMORY;
-
- entry->skins.SetBase(nsDependentCString(provider), resolved);
- }
- else if (!strcmp(token, "overlay")) {
- if (aSkinOnly) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring overlay registration in skin-only manifest.");
- continue;
- }
- char *base = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *overlay = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!base || !overlay) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: malformed chrome overlay instruction.");
- continue;
- }
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOs = eUnspecified;
- TriState stOsVersion = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsCOMPtr<nsIURI> baseuri, overlayuri;
- rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
- getter_AddRefs(baseuri));
- rv |= io->NewURI(nsDependentCString(overlay), nsnull, nsnull,
- getter_AddRefs(overlayuri));
- if (NS_FAILED(rv)) {
- NS_WARNING("Could not make URIs for overlay directive. Ignoring.");
- continue;
- }
-
- if (!CanLoadResource(overlayuri)) {
- LogMessageWithContext(overlayuri, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as an overlay.",
- overlay);
- continue;
- }
-
- mOverlayHash.Add(baseuri, overlayuri);
- }
- else if (!strcmp(token, "style")) {
- char *base = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *overlay = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!base || !overlay) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: malformed chrome style instruction.");
- continue;
- }
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOs = eUnspecified;
- TriState stOsVersion = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsCOMPtr<nsIURI> baseuri, overlayuri;
- rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
- getter_AddRefs(baseuri));
- rv |= io->NewURI(nsDependentCString(overlay), nsnull, nsnull,
- getter_AddRefs(overlayuri));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(overlayuri)) {
- LogMessageWithContext(overlayuri, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as a style overlay.",
- overlay);
- continue;
- }
-
- mStyleHash.Add(baseuri, overlayuri);
- }
- else if (!strcmp(token, "override")) {
- if (aSkinOnly) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring override registration in skin-only manifest.");
- continue;
- }
-
- char *chrome = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *resolved = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!chrome || !resolved) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: malformed chrome override instruction.");
- continue;
- }
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOs = eUnspecified;
- TriState stOsVersion = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsCOMPtr<nsIURI> chromeuri, resolveduri;
- rv = io->NewURI(nsDependentCString(chrome), nsnull, nsnull,
- getter_AddRefs(chromeuri));
- rv |= io->NewURI(nsDependentCString(resolved), nsnull, manifestURI,
- getter_AddRefs(resolveduri));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(resolveduri)) {
- LogMessageWithContext(resolveduri, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as an override.",
- resolved);
- continue;
- }
-
- mOverrideTable.Put(chromeuri, resolveduri);
- }
- else if (!strcmp(token, "resource")) {
- if (aSkinOnly) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring resource registration in skin-only manifest.");
- continue;
- }
-
- char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
- if (!package || !uri) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Malformed resource registration.");
- continue;
- }
-
- EnsureLowerCase(package);
-
- TriState stAppVersion = eUnspecified;
- TriState stApp = eUnspecified;
- TriState stOsVersion = eUnspecified;
- TriState stOs = eUnspecified;
-
- PRBool badFlag = PR_FALSE;
-
- while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
- !badFlag) {
- NS_ConvertASCIItoUTF16 wtoken(token);
- ToLowerCase(wtoken);
-
- if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
- CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
- CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
- CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
- continue;
-
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Unrecognized chrome registration modifier '%s'.",
- token);
- badFlag = PR_TRUE;
- }
-
- if (badFlag || stApp == eBad || stAppVersion == eBad ||
- stOs == eBad || stOsVersion == eBad)
- continue;
-
- nsDependentCString host(package);
-
- PRBool exists;
- rv = rph->HasSubstitution(host, &exists);
- NS_ENSURE_SUCCESS(rv, rv);
- if (exists) {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Duplicate resource declaration for '%s' ignored.",
- package);
- continue;
- }
-
- nsCOMPtr<nsIURI> resolved;
- rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
- getter_AddRefs(resolved));
- if (NS_FAILED(rv))
- continue;
-
- if (!CanLoadResource(resolved)) {
- LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
- "Warning: cannot register non-local URI '%s' as a resource.",
- uri);
- continue;
- }
-
- rv = rph->SetSubstitution(host, resolved);
- NS_ENSURE_SUCCESS(rv, rv);
- }
- else {
- LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
- "Warning: Ignoring unrecognized chrome manifest instruction.");
- }
+ PRBool exists = PR_FALSE;
+ rv = rph->HasSubstitution(host, &exists);
+ if (exists) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "Duplicate resource declaration for '%s' ignored.", package);
+ return;
}
- return NS_OK;
+ nsCOMPtr<nsIURI> resolved = cx.ResolveURI(uri);
+ if (!resolved) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "During chrome registration, unable to create URI '%s'.", uri);
+ return;
+ }
+
+ if (!CanLoadResource(resolved)) {
+ LogMessageWithContext(cx.GetManifestURI(), lineno, nsIScriptError::warningFlag,
+ "Warning: cannot register non-local URI '%s' as a resource.",
+ uri);
+ return;
+ }
+
+ rph->SetSubstitution(host, resolved);
}
--- a/chrome/src/nsChromeRegistry.h
+++ b/chrome/src/nsChromeRegistry.h
@@ -50,16 +50,19 @@
#include "nsCOMArray.h"
#include "nsString.h"
#include "nsTHashtable.h"
#include "nsURIHashKey.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
#include "nsInterfaceHashtable.h"
+#include "nsXULAppAPI.h"
+#include "nsIResProtocolHandler.h"
+#include "nsIXPConnect.h"
struct PRFileDesc;
class nsIAtom;
class nsIDOMWindowInternal;
class nsILocalFile;
class nsIPrefBranch;
class nsIRDFDataSource;
class nsIRDFResource;
@@ -116,29 +119,51 @@ protected:
private:
nsresult SelectLocaleFromPref(nsIPrefBranch* prefs);
static nsresult RefreshWindow(nsIDOMWindowInternal* aWindow);
static nsresult GetProviderAndPath(nsIURL* aChromeURL,
nsACString& aProvider, nsACString& aPath);
-#ifdef MOZ_XUL
- NS_HIDDEN_(void) ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
- nsIRDFDataSource* ds, nsIRDFResource* aRoot,
- PRBool aIsLocale, const nsACString& aBaseURL);
- NS_HIDDEN_(void) ProcessOverlays(PRFileDesc *fd, nsIRDFDataSource* ds,
- nsIRDFResource* aRoot,
- const nsCSubstring& aType);
-#endif
+public:
+ struct ManifestProcessingContext
+ {
+ ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
+ : mType(aType)
+ , mFile(aFile)
+ { }
+ ~ManifestProcessingContext()
+ { }
+
+ nsIURI* GetManifestURI();
+ nsIXPConnect* GetXPConnect();
+
+ already_AddRefed<nsIURI> ResolveURI(const char* uri);
- NS_HIDDEN_(nsresult) ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly);
- NS_HIDDEN_(nsresult) ProcessManifestBuffer(char *aBuffer, PRInt32 aLength, nsILocalFile* aManifest, PRBool aSkinOnly);
- NS_HIDDEN_(nsresult) ProcessNewChromeFile(nsILocalFile *aListFile, nsIURI* aManifest);
- NS_HIDDEN_(nsresult) ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength, nsIURI* aManifest);
+ NSLocationType mType;
+ nsCOMPtr<nsILocalFile> mFile;
+ nsCOMPtr<nsIURI> mManifestURI;
+ nsCOMPtr<nsIXPConnect> mXPConnect;
+ };
+
+ void ManifestContent(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestLocale(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestSkin(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestOverlay(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestStyle(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestOverride(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
+ void ManifestResource(ManifestProcessingContext& cx, int lineno,
+ char *const * argv, bool platform, bool contentaccessible);
public:
struct ProviderEntry
{
ProviderEntry(const nsACString& aProvider, nsIURI* aBase) :
provider(aProvider),
baseURI(aBase) { }
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -750,57 +750,55 @@ mozJSComponentLoader::LoadModule(nsILoca
rv = file_holder->GetJSObject(&file_jsobj);
if (NS_FAILED(rv)) {
return NULL;
}
JSCLAutoErrorReporterSetter aers(cx, mozJSLoaderErrorReporter);
- jsval argv[2], retval, NSGetFactory_val;
+ jsval NSGetFactory_val;
if (!JS_GetProperty(cx, entry->global, "NSGetFactory", &NSGetFactory_val) ||
JSVAL_IS_VOID(NSGetFactory_val)) {
return NULL;
}
if (JS_TypeOfValue(cx, NSGetFactory_val) != JSTYPE_FUNCTION) {
nsCAutoString path;
aComponentFile->GetNativePath(path);
JS_ReportError(cx, "%s has NSGetFactory property that is not a function",
path.get());
return NULL;
}
JSObject *jsGetFactoryObj;
- if (!JS_ValueToObject(cx, retval, &jsGetFactoryObj) ||
+ if (!JS_ValueToObject(cx, NSGetFactory_val, &jsGetFactoryObj) ||
!jsGetFactoryObj) {
/* XXX report error properly */
return NULL;
}
rv = xpc->WrapJS(cx, jsGetFactoryObj,
- NS_GET_IID(xpcIJSGetFactory), getter_AddRefs(entry->getfactory));
+ NS_GET_IID(xpcIJSGetFactory), getter_AddRefs(entry->getfactoryobj));
if (NS_FAILED(rv)) {
/* XXX report error properly */
#ifdef DEBUG
fprintf(stderr, "mJCL: couldn't get nsIModule from jsval\n");
#endif
return NULL;
}
// Cache this module for later
if (!mModules.Put(lfhash, entry))
return NULL;
// The hash owns the ModuleEntry now, forget about it
- entry.forget();
-
- return entry;
+ return entry.forget();
}
// Some stack based classes for cleaning up on early return
#ifdef HAVE_PR_MEMMAP
class FileAutoCloser
{
public:
explicit FileAutoCloser(PRFileDesc *file) : mFile(file) {}
@@ -1372,24 +1370,32 @@ mozJSComponentLoader::GlobalForLocation(
*aGlobal = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
JS_AddNamedRoot(cx, aGlobal, *aLocation);
return NS_OK;
}
+/* static */ PLDHashOperator
+mozJSComponentLoader::ClearModules(nsIHashable* key, ModuleEntry*& entry, void* cx)
+{
+ entry->Clear();
+ return PL_DHASH_REMOVE;
+}
+
void
mozJSComponentLoader::UnloadModules()
{
mInitialized = PR_FALSE;
mInProgressImports.Clear();
mImports.Clear();
- mModules.Clear();
+
+ mModules.Enumerate(ClearModules, NULL);
// Destroying our context will force a GC.
JS_DestroyContext(mContext);
mContext = nsnull;
mRuntimeService = nsnull;
mContextStack = nsnull;
#ifdef DEBUG_shaver_off
@@ -1655,16 +1661,31 @@ mozJSComponentLoader::Observe(nsISupport
}
else {
NS_ERROR("Unexpected observer topic.");
}
return NS_OK;
}
+/* static */ already_AddRefed<nsIFactory>
+mozJSComponentLoader::ModuleEntry::GetFactory(const mozilla::Module& module,
+ const mozilla::Module::CIDEntry& entry)
+{
+ const ModuleEntry& self = static_cast<const ModuleEntry&>(module);
+ NS_ASSERTION(self.getfactoryobj, "Handing out an uninitialized module?");
+
+ nsCOMPtr<nsIFactory> f;
+ nsresult rv = self.getfactoryobj->Get(*entry.cid, getter_AddRefs(f));
+ if (NS_FAILED(rv))
+ return NULL;
+
+ return f.forget();
+}
+
//----------------------------------------------------------------------
JSCLContextHelper::JSCLContextHelper(mozJSComponentLoader *loader)
: mContext(loader->mContext), mContextThread(0),
mContextStack(loader->mContextStack)
{
mContextStack->Push(mContext);
mContextThread = JS_GetContextThread(mContext);
--- a/js/src/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.h
@@ -137,42 +137,59 @@ class mozJSComponentLoader : public mozi
#endif
JSRuntime *mRuntime;
JSContext *mContext;
class ModuleEntry : public mozilla::Module
{
public:
ModuleEntry() : mozilla::Module() {
-
+ mVersion = mozilla::Module::kVersion;
+ mCIDs = NULL;
+ mContractIDs = NULL;
+ mCategoryEntries = NULL;
+ getfactory = GetFactory;
+ loaded = NULL;
+ unloaded = NULL;
+
global = nsnull;
location = nsnull;
}
~ModuleEntry() {
- getfactory = NULL;
+ Clear();
+ }
+
+ void Clear() {
+ getfactoryobj = NULL;
if (global) {
JSAutoRequest ar(sSelf->mContext);
JS_ClearScope(sSelf->mContext, global);
JS_RemoveRoot(sSelf->mContext, &global);
}
if (location)
NS_Free(location);
+
+ global = NULL;
+ location = NULL;
}
static already_AddRefed<nsIFactory> GetFactory(const mozilla::Module& module,
const mozilla::Module::CIDEntry& entry);
- nsCOMPtr<xpcIJSGetFactory> getfactory;
+ nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
JSObject *global;
char *location;
};
friend class ModuleEntry;
- nsClassHashtable<nsHashableHashKey, ModuleEntry> mModules;
+ // Modules are intentionally leaked, but still cleared.
+ static PLDHashOperator ClearModules(nsIHashable* key, ModuleEntry*& entry, void* cx);
+ nsDataHashtable<nsHashableHashKey, ModuleEntry*> mModules;
+
nsClassHashtable<nsHashableHashKey, ModuleEntry> mImports;
nsDataHashtable<nsHashableHashKey, ModuleEntry*> mInProgressImports;
PRBool mInitialized;
};
--- a/toolkit/library/libxul-config.mk
+++ b/toolkit/library/libxul-config.mk
@@ -139,17 +139,16 @@ COMPONENT_LIBS += \
htmlpars \
imglib2 \
gklayout \
docshell \
embedcomponents \
webbrwsr \
nsappshell \
txmgr \
- chrome \
commandlines \
extensions \
toolkitcomps \
pipboot \
pipnss \
appcomps \
$(NULL)
--- a/toolkit/library/nsStaticXULComponents.cpp
+++ b/toolkit/library/nsStaticXULComponents.cpp
@@ -247,17 +247,16 @@
MODULE(nsLayoutModule) \
MODULE(docshell_provider) \
MODULE(embedcomponents) \
MODULE(Browser_Embedding_Module) \
ACCESS_MODULES \
MODULE(appshell) \
MODULE(nsTransactionManagerModule) \
COMPOSER_MODULE \
- MODULE(nsChromeModule) \
MODULE(application) \
MODULE(Apprunner) \
MODULE(CommandLineModule) \
FILEVIEW_MODULE \
STORAGE_MODULE \
PLACES_MODULES \
XULENABLED_MODULES \
MODULE(AddonsModule) \
--- a/toolkit/toolkit-tiers.mk
+++ b/toolkit/toolkit-tiers.mk
@@ -195,17 +195,17 @@ endif
ifdef ACCESSIBILITY
tier_platform_dirs += accessible
endif
#
# "toolkit" - xpfe & toolkit
#
-tier_platform_dirs += chrome profile
+tier_platform_dirs += profile
# This must preceed xpfe
ifdef MOZ_JPROF
tier_platform_dirs += tools/jprof
endif
tier_platform_dirs += xpfe/components
--- a/xpcom/Makefile.in
+++ b/xpcom/Makefile.in
@@ -52,16 +52,17 @@ DIRS = \
base \
ds \
io \
components \
threads \
reflect \
proxy \
system \
+ ../chrome \
build \
$(NULL)
ifndef MOZ_ENABLE_LIBXUL
DIRS += stub
endif
ifeq ($(OS_ARCH),WINNT)
--- a/xpcom/build/Makefile.in
+++ b/xpcom/build/Makefile.in
@@ -77,16 +77,17 @@ CPPSRCS += dlldeps.cpp
endif
endif
ifdef MOZ_OMNIJAR
CPPSRCS += Omnijar.cpp
endif
SHARED_LIBRARY_LIBS = \
+ $(DEPTH)/chrome/src/chrome_s.$(LIB_SUFFIX) \
../ds/$(LIB_PREFIX)xpcomds_s.$(LIB_SUFFIX) \
../io/$(LIB_PREFIX)xpcomio_s.$(LIB_SUFFIX) \
../components/$(LIB_PREFIX)xpcomcomponents_s.$(LIB_SUFFIX) \
../threads/$(LIB_PREFIX)xpcomthreads_s.$(LIB_SUFFIX) \
../proxy/src/$(LIB_PREFIX)xpcomproxy_s.$(LIB_SUFFIX) \
../base/$(LIB_PREFIX)xpcombase_s.$(LIB_SUFFIX) \
../reflect/xptcall/src/$(LIB_PREFIX)xptcall.$(LIB_SUFFIX) \
../reflect/xptcall/src/$(LIB_PREFIX)xptcmd.$(LIB_SUFFIX) \
@@ -108,16 +109,17 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../base \
-I$(srcdir)/../ds \
-I$(srcdir)/../io \
-I$(srcdir)/../components \
-I$(srcdir)/../threads \
-I$(srcdir)/../threads/_xpidlgen \
-I$(srcdir)/../proxy/src \
-I$(srcdir)/../reflect/xptinfo/src \
+ -I$(topsrcdir)/chrome/src \
$(NULL)
EXPORTS_NAMESPACES = mozilla
SDK_HEADERS = \
nsXPCOM.h \
nsXPCOMCID.h \
$(NULL)
--- a/xpcom/build/dlldeps.cpp
+++ b/xpcom/build/dlldeps.cpp
@@ -301,10 +301,10 @@ void XXXNeverCalled()
TimeStamp theTimeStamp = TimeStamp::Now();
TimeDuration theTimeDuration = TimeDuration::FromMilliseconds(0);
NS_WildCardValid((const char *)nsnull);
NS_WildCardValid((const PRUnichar *)nsnull);
NS_WildCardMatch((const char *)nsnull, (const char *)nsnull, PR_FALSE);
NS_WildCardMatch((const PRUnichar *)nsnull, (const PRUnichar *)nsnull, PR_FALSE);
XRE_AddStaticComponent(NULL);
- XRE_AddComponentLocation(NULL);
+ XRE_AddComponentLocation(NS_COMPONENT_LOCATION, NULL);
}
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -138,16 +138,19 @@ extern nsresult nsStringInputStreamConst
#include "nsSystemInfo.h"
#include "nsMemoryReporterManager.h"
#include <locale.h>
#include "mozilla/Services.h"
#include "mozilla/FunctionTimer.h"
+#include "nsChromeRegistry.h"
+#include "nsChromeProtocolHandler.h"
+
#ifdef MOZ_IPC
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "mozilla/ipc/BrowserProcessSubThread.h"
using base::AtExitManager;
@@ -259,16 +262,22 @@ nsXPTIInterfaceInfoManagerGetSingleton(n
nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL;
PRBool gXPCOMShuttingDown = PR_FALSE;
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kINIParserFactoryCID, NS_INIPARSERFACTORY_CID);
static NS_DEFINE_CID(kSimpleUnicharStreamFactoryCID, NS_SIMPLE_UNICHAR_STREAM_FACTORY_CID);
+NS_DEFINE_NAMED_CID(NS_CHROMEREGISTRY_CID);
+NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
+
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsChromeRegistry, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
+
#define NS_PERSISTENTPROPERTIES_CID NS_IPERSISTENTPROPERTIES_CID /* sigh */
#define NS_XPCOMPROXY_CID NS_PROXYEVENT_MANAGER_CID
static already_AddRefed<nsIFactory>
CreateINIParserFactory(const mozilla::Module& module,
const mozilla::Module::CIDEntry& entry)
{
nsIFactory* f = new nsINIParserFactory();
@@ -288,23 +297,27 @@ CreateUnicharStreamFactory(const mozilla
#undef COMPONENT
#define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, NULL, Ctor },
const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
{ &kComponentManagerCID, true, NULL, nsComponentManagerImpl::Create },
{ &kINIParserFactoryCID, false, CreateINIParserFactory },
{ &kSimpleUnicharStreamFactoryCID, false, CreateUnicharStreamFactory },
#include "XPCOMModule.inc"
+ { &kNS_CHROMEREGISTRY_CID, false, NULL, nsChromeRegistryConstructor },
+ { &kNS_CHROMEPROTOCOLHANDLER_CID, false, NULL, nsChromeProtocolHandlerConstructor },
{ NULL }
};
#undef COMPONENT
#define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
#include "XPCOMModule.inc"
+ { NS_CHROMEREGISTRY_CONTRACTID, &kNS_CHROMEREGISTRY_CID },
+ { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
{ NULL }
};
#undef COMPONENT
const mozilla::Module kXPCOMModule = { mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts };
// gDebug will be freed during shutdown.
static nsIDebug* gDebug = nsnull;
@@ -468,35 +481,28 @@ NS_InitXPCOM2(nsIServiceManager* *result
}
#endif
NS_ASSERTION(nsComponentManagerImpl::gComponentManager == NULL, "CompMgr not null at init");
NS_TIME_FUNCTION_MARK("Next: component manager init");
// Create the Component/Service Manager
- nsComponentManagerImpl *compMgr = new nsComponentManagerImpl();
- if (compMgr == NULL)
- return NS_ERROR_OUT_OF_MEMORY;
- NS_ADDREF(compMgr);
+ nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
+ NS_ADDREF(nsComponentManagerImpl::gComponentManager);
- rv = compMgr->Init();
+ rv = nsComponentManagerImpl::gComponentManager->Init();
if (NS_FAILED(rv))
{
- NS_RELEASE(compMgr);
+ NS_RELEASE(nsComponentManagerImpl::gComponentManager);
return rv;
}
- nsComponentManagerImpl::gComponentManager = compMgr;
-
if (result) {
- nsIServiceManager *serviceManager =
- static_cast<nsIServiceManager*>(compMgr);
-
- NS_ADDREF(*result = serviceManager);
+ NS_ADDREF(*result = nsComponentManagerImpl::gComponentManager);
}
NS_TIME_FUNCTION_MARK("Next: cycle collector startup");
rv = nsCycleCollector_startup();
if (NS_FAILED(rv)) return rv;
NS_TIME_FUNCTION_MARK("Next: interface info manager init");
--- a/xpcom/build/nsXULAppAPI.h
+++ b/xpcom/build/nsXULAppAPI.h
@@ -348,27 +348,41 @@ XRE_API(nsresult,
/**
* Register static XPCOM component information.
* This method may be called at any time before or after XRE_main or
* XRE_InitEmbedding.
*/
XRE_API(nsresult,
XRE_AddStaticComponent, (const mozilla::Module* aComponent))
+
/**
* Register XPCOM components found in an array of files/directories.
* This method may be called at any time before or after XRE_main or
* XRE_InitEmbedding.
*
* @param aFiles An array of files or directories.
* @param aFileCount the number of items in the aFiles array.
* @note appdir/components is registered automatically.
+ *
+ * NS_COMPONENT_LOCATION specifies a location to search for binary XPCOM
+ * components as well as component/chrome manifest files.
+ *
+ * NS_SKIN_LOCATION specifies a location to search for chrome manifest files
+ * which are only allowed to register only skin packages and style overlays.
*/
+enum NSLocationType
+{
+ NS_COMPONENT_LOCATION,
+ NS_SKIN_LOCATION
+};
+
XRE_API(nsresult,
- XRE_AddComponentLocation, (nsILocalFile* aLocation))
+ XRE_AddComponentLocation, (NSLocationType aType,
+ nsILocalFile* aLocation))
/**
* Fire notifications to inform the toolkit about a new profile. This
* method should be called after XRE_InitEmbedding if the embedder
* wishes to run with a profile. Normally the embedder should call
* XRE_LockProfileDirectory to lock the directory before calling this
* method.
*
--- a/xpcom/components/Makefile.in
+++ b/xpcom/components/Makefile.in
@@ -41,16 +41,17 @@ srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = xpcom
XPIDL_MODULE = xpcom_components
LIBRARY_NAME = xpcomcomponents_s
GRE_MODULE = 1
+LIBXUL_LIBRARY = 1
MOZILLA_INTERNAL_API = 1
EXPORTS_NAMESPACES = mozilla
EXPORTS = \
nsCategoryManagerUtils.h \
$(NULL)
@@ -59,16 +60,17 @@ EXPORTS_mozilla = \
Module.h \
ModuleLoader.h \
ModuleUtils.h \
$(NULL)
CPPSRCS = \
nsCategoryManager.cpp \
nsComponentManager.cpp \
+ ManifestParser.cpp \
nsNativeComponentLoader.cpp \
GenericFactory.cpp \
$(NULL)
SDK_XPIDLSRCS = \
nsIClassInfo.idl \
nsIComponentRegistrar.idl \
nsIFactory.idl \
@@ -79,16 +81,17 @@ SDK_XPIDLSRCS = \
LOCAL_INCLUDES = \
-I$(srcdir)/../reflect/xptinfo/src \
-I$(srcdir)/../base \
-I$(srcdir)/../thread \
-I$(srcdir)/../ds \
-I$(srcdir)/../build \
-I.. \
+ -I$(topsrcdir)/chrome/src \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
# Force use of PIC
FORCE_USE_PIC = 1
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/xpcom/components/ManifestParser.cpp
@@ -0,0 +1,472 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Firefox
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "ManifestParser.h"
+
+#include <string.h>
+
+#include "prio.h"
+#include "prprf.h"
+#if defined(XP_WIN)
+#include <windows.h>
+#elif defined(XP_MACOSX)
+#include <CoreServices/CoreServices.h>
+#elif defined(MOZ_WIDGET_GTK2)
+#include <gtk/gtk.h>
+#endif
+
+#include "nsTextFormatter.h"
+#include "nsUnicharUtils.h"
+#include "nsVersionComparator.h"
+#include "nsXPCOMCIDInternal.h"
+
+#include "nsIConsoleService.h"
+#include "nsIScriptError.h"
+#include "nsIXULAppInfo.h"
+#include "nsIXULRuntime.h"
+
+struct ManifestDirective
+{
+ const char* directive;
+ int argc;
+
+ // Some directives should only be delivered for NS_COMPONENT_LOCATION
+ // manifests.
+ bool componentonly;
+
+ bool ischrome;
+
+ // The platform/contentaccessible flags only apply to content directives.
+ bool contentflags;
+
+ // Function to handle this directive. This isn't a union because C++ still
+ // hasn't learned how to initialize unions in a sane way.
+ void (nsComponentManagerImpl::*mgrfunc)
+ (nsComponentManagerImpl::ManifestProcessingContext& cx,
+ int lineno, char *const * argv);
+ void (nsChromeRegistry::*regfunc)
+ (nsChromeRegistry::ManifestProcessingContext& cx,
+ int lineno, char *const *argv,
+ bool platform, bool contentaccessible);
+};
+static const ManifestDirective kParsingTable[] = {
+ { "binary-component", 1, true, false, false,
+ &nsComponentManagerImpl::ManifestBinaryComponent, NULL },
+ { "component", 2, true, false, false,
+ &nsComponentManagerImpl::ManifestComponent, NULL },
+ { "contract", 2, true, false, false,
+ &nsComponentManagerImpl::ManifestContract, NULL },
+ { "category", 3, true, false, false,
+ &nsComponentManagerImpl::ManifestCategory, NULL },
+ { "content", 2, true, true, true,
+ NULL, &nsChromeRegistry::ManifestContent },
+ { "locale", 3, true, true, false,
+ NULL, &nsChromeRegistry::ManifestLocale },
+ { "skin", 3, false, true, false,
+ NULL, &nsChromeRegistry::ManifestSkin },
+ { "overlay", 2, true, true, false,
+ NULL, &nsChromeRegistry::ManifestOverlay },
+ { "style", 2, false, true, false,
+ NULL, &nsChromeRegistry::ManifestStyle },
+ { "override", 2, true, true, false,
+ NULL, &nsChromeRegistry::ManifestOverride },
+ { "resource", 2, true, true, false,
+ NULL, &nsChromeRegistry::ManifestResource }
+};
+
+static const char kWhitespace[] = "\t ";
+static const char kNewlines[] = "\r\n";
+
+static void LogMessageWithContext(nsILocalFile* aFile, PRUint32 aLineNumber, const char* aMsg, ...)
+{
+ nsCOMPtr<nsIConsoleService> console =
+ do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ nsCOMPtr<nsIScriptError> error =
+ do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
+ if (!console || !error)
+ return;
+
+ va_list args;
+ va_start(args, aMsg);
+ char* formatted = PR_vsmprintf(aMsg, args);
+ va_end(args);
+ if (!formatted)
+ return;
+
+ nsString file;
+ aFile->GetPath(file);
+
+ nsresult rv = error->Init(NS_ConvertUTF8toUTF16(formatted).get(),
+ file.get(), NULL,
+ aLineNumber, 0, nsIScriptError::warningFlag,
+ "chrome registration");
+ PR_smprintf_free(formatted);
+ if (NS_FAILED(rv))
+ return;
+
+ console->LogMessage(error);
+}
+
+/**
+ * Check for a modifier flag of the following forms:
+ * "flag" (same as "true")
+ * "flag=yes|true|1"
+ * "flag="no|false|0"
+ * @param aFlag The flag to compare.
+ * @param aData The tokenized data to check; this is lowercased
+ * before being passed in.
+ * @param aResult If the flag is found, the value is assigned here.
+ * @return Whether the flag was handled.
+ */
+static bool
+CheckFlag(const nsSubstring& aFlag, const nsSubstring& aData, bool& aResult)
+{
+ if (!StringBeginsWith(aData, aFlag))
+ return false;
+
+ if (aFlag.Length() == aData.Length()) {
+ // the data is simply "flag", which is the same as "flag=yes"
+ aResult = true;
+ return true;
+ }
+
+ if (aData.CharAt(aFlag.Length()) != '=') {
+ // the data is "flag2=", which is not anything we care about
+ return false;
+ }
+
+ if (aData.Length() == aFlag.Length() + 1) {
+ aResult = false;
+ return true;
+ }
+
+ switch (aData.CharAt(aFlag.Length() + 1)) {
+ case '1':
+ case 't': //true
+ case 'y': //yes
+ aResult = true;
+ return true;
+
+ case '0':
+ case 'f': //false
+ case 'n': //no
+ aResult = false;
+ return true;
+ }
+
+ return false;
+}
+
+enum TriState {
+ eUnspecified,
+ eBad,
+ eOK
+};
+
+/**
+ * Check for a modifier flag of the following form:
+ * "flag=string"
+ * "flag!=string"
+ * @param aFlag The flag to compare.
+ * @param aData The tokenized data to check; this is lowercased
+ * before being passed in.
+ * @param aValue The value that is expected.
+ * @param aResult If this is "ok" when passed in, this is left alone.
+ * Otherwise if the flag is found it is set to eBad or eOK.
+ * @return Whether the flag was handled.
+ */
+static bool
+CheckStringFlag(const nsSubstring& aFlag, const nsSubstring& aData,
+ const nsSubstring& aValue, TriState& aResult)
+{
+ if (aData.Length() < aFlag.Length() + 1)
+ return false;
+
+ if (!StringBeginsWith(aData, aFlag))
+ return false;
+
+ bool comparison = true;
+ if (aData[aFlag.Length()] != '=') {
+ if (aData[aFlag.Length()] == '!' &&
+ aData.Length() >= aFlag.Length() + 2 &&
+ aData[aFlag.Length() + 1] == '=')
+ comparison = false;
+ else
+ return false;
+ }
+
+ if (aResult != eOK) {
+ nsDependentSubstring testdata = Substring(aData, aFlag.Length() + (comparison ? 1 : 2));
+ if (testdata.Equals(aValue))
+ aResult = comparison ? eOK : eBad;
+ else
+ aResult = comparison ? eBad : eOK;
+ }
+
+ return true;
+}
+
+/**
+ * Check for a modifier flag of the following form:
+ * "flag=version"
+ * "flag<=version"
+ * "flag<version"
+ * "flag>=version"
+ * "flag>version"
+ * @param aFlag The flag to compare.
+ * @param aData The tokenized data to check; this is lowercased
+ * before being passed in.
+ * @param aValue The value that is expected. If this is empty then no
+ * comparison will match.
+ * @param aResult If this is eOK when passed in, this is left alone.
+ * Otherwise if the flag is found it is set to eBad or eOK.
+ * @return Whether the flag was handled.
+ */
+
+#define COMPARE_EQ 1 << 0
+#define COMPARE_LT 1 << 1
+#define COMPARE_GT 1 << 2
+
+static bool
+CheckVersionFlag(const nsString& aFlag, const nsString& aData,
+ const nsString& aValue, TriState& aResult)
+{
+ if (aData.Length() < aFlag.Length() + 2)
+ return false;
+
+ if (!StringBeginsWith(aData, aFlag))
+ return false;
+
+ if (aValue.Length() == 0) {
+ if (aResult != eOK)
+ aResult = eBad;
+ return true;
+ }
+
+ PRUint32 comparison;
+ nsAutoString testdata;
+
+ switch (aData[aFlag.Length()]) {
+ case '=':
+ comparison = COMPARE_EQ;
+ testdata = Substring(aData, aFlag.Length() + 1);
+ break;
+
+ case '<':
+ if (aData[aFlag.Length() + 1] == '=') {
+ comparison = COMPARE_EQ | COMPARE_LT;
+ testdata = Substring(aData, aFlag.Length() + 2);
+ }
+ else {
+ comparison = COMPARE_LT;
+ testdata = Substring(aData, aFlag.Length() + 1);
+ }
+ break;
+
+ case '>':
+ if (aData[aFlag.Length() + 1] == '=') {
+ comparison = COMPARE_EQ | COMPARE_GT;
+ testdata = Substring(aData, aFlag.Length() + 2);
+ }
+ else {
+ comparison = COMPARE_GT;
+ testdata = Substring(aData, aFlag.Length() + 1);
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ if (testdata.Length() == 0)
+ return false;
+
+ if (aResult != eOK) {
+ PRInt32 c = NS_CompareVersions(aValue.get(), testdata.get());
+ if ((c == 0 && comparison & COMPARE_EQ) ||
+ (c < 0 && comparison & COMPARE_LT) ||
+ (c > 0 && comparison & COMPARE_GT))
+ aResult = eOK;
+ else
+ aResult = eBad;
+ }
+
+ return true;
+}
+
+void
+ParseManifest(NSLocationType aType, nsILocalFile* aFile, char* buf)
+{
+ nsresult rv;
+
+ nsComponentManagerImpl::ManifestProcessingContext mgrcx(aType, aFile);
+ nsChromeRegistry::ManifestProcessingContext chromecx(aType, aFile);
+
+ NS_NAMED_LITERAL_STRING(kPlatform, "platform");
+ NS_NAMED_LITERAL_STRING(kContentAccessible, "contentaccessible");
+ NS_NAMED_LITERAL_STRING(kApplication, "application");
+ NS_NAMED_LITERAL_STRING(kAppVersion, "appversion");
+ NS_NAMED_LITERAL_STRING(kOs, "os");
+ NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
+
+ nsAutoString appID;
+ nsAutoString appVersion;
+ nsAutoString osTarget;
+ nsCOMPtr<nsIXULAppInfo> xapp (do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
+ if (xapp) {
+ nsCAutoString s;
+ rv = xapp->GetID(s);
+ if (NS_SUCCEEDED(rv))
+ CopyUTF8toUTF16(s, appID);
+
+ rv = xapp->GetVersion(s);
+ if (NS_SUCCEEDED(rv))
+ CopyUTF8toUTF16(s, appVersion);
+
+ nsCOMPtr<nsIXULRuntime> xruntime (do_QueryInterface(xapp));
+ if (xruntime) {
+ rv = xruntime->GetOS(s);
+ if (NS_SUCCEEDED(rv)) {
+ CopyUTF8toUTF16(s, osTarget);
+ ToLowerCase(osTarget);
+ }
+ }
+ }
+
+ nsAutoString osVersion;
+#if defined(XP_WIN)
+ OSVERSIONINFO info = { sizeof(OSVERSIONINFO) };
+ if (GetVersionEx(&info)) {
+ nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+ info.dwMajorVersion,
+ info.dwMinorVersion);
+ }
+#elif defined(XP_MACOSX)
+ SInt32 majorVersion, minorVersion;
+ if ((Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) &&
+ (Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) {
+ nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+ majorVersion,
+ minorVersion);
+ }
+#elif defined(MOZ_WIDGET_GTK2)
+ nsTextFormatter::ssprintf(osVersion, NS_LITERAL_STRING("%ld.%ld").get(),
+ gtk_major_version,
+ gtk_minor_version);
+#endif
+
+ char *token;
+ char *newline = buf;
+ PRUint32 line = 0;
+
+ // outer loop tokenizes by newline
+ while (nsnull != (token = nsCRT::strtok(newline, kNewlines, &newline))) {
+ ++line;
+
+ if (*token == '#') // ignore lines that begin with # as comments
+ continue;
+
+ char *whitespace = token;
+ token = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
+ if (!token) continue;
+
+ const ManifestDirective* directive = NULL;
+ for (const ManifestDirective* d = kParsingTable;
+ d < kParsingTable + NS_ARRAY_LENGTH(kParsingTable);
+ ++d) {
+ if (!strcmp(d->directive, token)) {
+ directive = d;
+ break;
+ }
+ }
+ if (!directive) {
+ LogMessageWithContext(aFile, line, "Ignoring unrecognized chrome manifest directive '%s'.", token);
+ continue;
+ }
+ if (directive->componentonly && NS_COMPONENT_LOCATION != aType) {
+ LogMessageWithContext(aFile, line, "Skin manifest not allowed to use '%s' directive.", token);
+ continue;
+ }
+
+ NS_ASSERTION(directive->argc < 4, "Need to reset argv array length");
+ char* argv[4];
+ for (int i = 0; i < directive->argc; ++i)
+ argv[i] = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
+
+ if (!argv[directive->argc - 1]) {
+ LogMessageWithContext(aFile, line, "Not enough arguments for chrome manifest directive '%s', expected %i.", token, directive->argc);
+ continue;
+ }
+
+ bool ok = true;
+ TriState stAppVersion = eUnspecified;
+ TriState stApp = eUnspecified;
+ TriState stOsVersion = eUnspecified;
+ TriState stOs = eUnspecified;
+ bool platform = false;
+ bool contentAccessible = false;
+
+ while (NULL != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && ok) {
+ NS_ConvertASCIItoUTF16 wtoken(token);
+ ToLowerCase(wtoken);
+
+ if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
+ CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
+ CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) ||
+ CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion))
+ continue;
+
+ if (directive->contentflags &&
+ (CheckFlag(kPlatform, wtoken, platform) ||
+ CheckFlag(kContentAccessible, wtoken, contentAccessible)))
+ continue;
+
+ LogMessageWithContext(aFile, line, "Unrecognized chrome manifest modifier '%s'.", token);
+ ok = false;
+ }
+
+ if (!ok || stApp == eBad || stAppVersion == eBad || stOs == eBad || stOsVersion == eBad)
+ continue;
+
+ if (directive->ischrome)
+ (nsChromeRegistry::gChromeRegistry->*(directive->regfunc))
+ (chromecx, line, argv, platform, contentAccessible);
+ else
+ (nsComponentManagerImpl::gComponentManager->*(directive->mgrfunc))
+ (mgrcx, line, argv);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/xpcom/components/ManifestParser.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (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.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Firefox
+ *
+ * The Initial Developer of the Original Code is
+ * the Mozilla Foundation <http://www.mozilla.org/>.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef ManifestParser_h
+#define ManifestParser_h
+
+#include "nsComponentManager.h"
+#include "nsChromeRegistry.h"
+
+class nsILocalFile;
+
+void ParseManifest(NSLocationType type, nsILocalFile* file, char* buf);
+
+#endif // ManifestParser_h
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -84,16 +84,17 @@
#include "prcmon.h"
#include "xptinfo.h" // this after nsISupports, to pick up IID so that xpt stuff doesn't try to define it itself...
#include "nsThreadUtils.h"
#include "prthread.h"
#include "private/pprthred.h"
#include "nsTArray.h"
#include "prio.h"
#include "mozilla/FunctionTimer.h"
+#include "ManifestParser.h"
#include "nsInt64.h"
#include "nsManifestLineReader.h"
#include "mozilla/GenericFactory.h"
#include "nsSupportsPrimitives.h"
#include "nsArrayEnumerator.h"
#include "nsStringEnumerator.h"
@@ -308,25 +309,26 @@ nsComponentManagerImpl::InitializeStatic
return;
sStaticModules = new nsTArray<const mozilla::Module*>;
for (const mozilla::Module *const *staticModules = kPStaticModules;
*staticModules; ++staticModules)
sStaticModules->AppendElement(*staticModules);
}
-nsCOMArray<nsILocalFile>* nsComponentManagerImpl::sModuleLocations;
+nsTArray<nsComponentManagerImpl::ComponentLocation>*
+nsComponentManagerImpl::sModuleLocations;
/* static */ void
nsComponentManagerImpl::InitializeModuleLocations()
{
if (sModuleLocations)
return;
- sModuleLocations = new nsCOMArray<nsILocalFile>;
+ sModuleLocations = new nsTArray<ComponentLocation>;
}
nsresult nsComponentManagerImpl::Init()
{
NS_TIME_FUNCTION;
PR_ASSERT(NOT_INITIALIZED == mStatus);
@@ -336,70 +338,85 @@ nsresult nsComponentManagerImpl::Init()
}
// Initialize our arena
NS_TIME_FUNCTION_MARK("Next: init component manager arena");
PL_INIT_ARENA_POOL(&mArena, "ComponentManagerArena", NS_CM_BLOCK_SIZE);
mFactories.Init(CONTRACTID_HASHTABLE_INITIAL_SIZE);
mContractIDs.Init(CONTRACTID_HASHTABLE_INITIAL_SIZE);
+ mLoaderMap.Init();
+ mKnownFileModules.Init();
mMon = nsAutoMonitor::NewMonitor("nsComponentManagerImpl");
if (mMon == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
static const char *const kComponents[] = { "components", NULL };
nsCOMPtr<nsILocalFile> greComponents =
GetLocationFromDirectoryService(NS_GRE_DIR, kComponents);
nsCOMPtr<nsILocalFile> appComponents =
GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR, kComponents);
InitializeStaticModules();
InitializeModuleLocations();
+ ComponentLocation* l = sModuleLocations->InsertElementAt(0);
+ l->type = NS_COMPONENT_LOCATION;
+ l->location = appComponents;
+
PRBool equals = PR_FALSE;
appComponents->Equals(greComponents, &equals);
- if (!equals)
- sModuleLocations->InsertObjectAt(greComponents, 0);
- sModuleLocations->InsertObjectAt(appComponents, 0);
+ if (!equals) {
+ l = sModuleLocations->InsertElementAt(0);
+ l->type = NS_COMPONENT_LOCATION;
+ l->location = greComponents;
+ }
PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG,
("nsComponentManager: Initialized."));
NS_TIME_FUNCTION_MARK("Next: init native module loader");
nsresult rv = mNativeModuleLoader.Init();
if (NS_FAILED(rv))
return rv;
nsCategoryManager::GetSingleton()->SuppressNotifications(true);
RegisterModule(&kXPCOMModule, NULL);
for (PRUint32 i = 0; i < sStaticModules->Length(); ++i)
RegisterModule((*sStaticModules)[i], NULL);
- for (PRInt32 i = 0; i < sModuleLocations->Count(); ++i)
- RegisterLocation((*sModuleLocations)[i]);
+ for (PRUint32 i = 0; i < sModuleLocations->Length(); ++i) {
+ ComponentLocation& l = sModuleLocations->ElementAt(i);
+ RegisterLocation(l.type, l.location);
+ }
nsCategoryManager::GetSingleton()->SuppressNotifications(false);
mStatus = NORMAL;
return NS_OK;
}
void
nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
nsILocalFile* aFile)
{
nsAutoMonitor mon(mMon);
KnownModule* m = new KnownModule(aModule, aFile);
- mKnownModules.AppendElement(m);
+ if (aFile) {
+ nsCOMPtr<nsIHashable> h = do_QueryInterface(aFile);
+ mKnownFileModules.Put(h, m);
+ }
+ else
+ mKnownStaticModules.AppendElement(m);
if (aModule->mCIDs) {
const mozilla::Module::CIDEntry* entry;
for (entry = aModule->mCIDs; entry->cid; ++entry)
RegisterCIDEntry(entry, m);
}
if (aModule->mContractIDs) {
@@ -447,81 +464,278 @@ nsComponentManagerImpl::RegisterContract
// XXX REPORT ERROR, CID isn't registered
return;
}
mContractIDs.Put(nsDependentCString(aEntry->contractid), f);
}
void
-nsComponentManagerImpl::RegisterLocation(nsILocalFile* aLocation)
+nsComponentManagerImpl::RegisterLocation(NSLocationType aType,
+ nsILocalFile* aLocation)
{
+ nsCOMArray<nsILocalFile> manifests;
+
PRBool directory = PR_FALSE;
aLocation->IsDirectory(&directory);
if (directory)
- RegisterDirectory(aLocation);
+ RegisterDirectory(aType, aLocation, manifests);
else
- RegisterFile(aLocation);
+ RegisterFile(aType, aLocation, manifests);
+
+ for (PRInt32 i = 0; i < manifests.Count(); ++i)
+ RegisterManifestFile(aType, manifests[i]);
}
void
-nsComponentManagerImpl::RegisterDirectory(nsILocalFile* aDirectory)
+nsComponentManagerImpl::RegisterDirectory(NSLocationType aType,
+ nsILocalFile* aDirectory,
+ nsCOMArray<nsILocalFile>& aManifests)
{
nsCOMPtr<nsISimpleEnumerator> entries;
aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
if (!entries)
return;
PRBool more;
while (NS_SUCCEEDED(entries->HasMoreElements(&more)) && more) {
nsCOMPtr<nsISupports> supp;
entries->GetNext(getter_AddRefs(supp));
nsCOMPtr<nsILocalFile> f = do_QueryInterface(supp);
if (!f)
continue;
- RegisterFile(f);
+ RegisterFile(aType, f, aManifests);
}
}
-void
-nsComponentManagerImpl::RegisterFile(nsILocalFile* aFile)
+static void
+GetExtension(nsILocalFile* file, nsCString& extension)
{
- nsCString extension;
- aFile->GetNativePath(extension);
+ file->GetNativePath(extension);
PRInt32 dotPos = extension.RFindChar('.');
if (kNotFound == dotPos)
+ extension.Truncate();
+ else
+ extension.Cut(0, dotPos + 1);
+}
+
+void
+nsComponentManagerImpl::RegisterFile(NSLocationType aType,
+ nsILocalFile* aFile,
+ nsCOMArray<nsILocalFile>& aManifests)
+{
+ nsCString extension;
+ GetExtension(aFile, extension);
+
+ if (NS_COMPONENT_LOCATION == aType) {
+ if (extension.EqualsLiteral("xpt")) {
+ xptiInterfaceInfoManager::GetSingleton()
+ ->RegisterFile(aFile,
+ xptiInterfaceInfoManager::XPT);
+ }
+ else if (extension.EqualsLiteral("jar")) {
+ xptiInterfaceInfoManager::GetSingleton()
+ ->RegisterFile(aFile,
+ xptiInterfaceInfoManager::ZIP);
+ }
+ }
+
+ if (extension.LowerCaseEqualsLiteral("manifest"))
+ aManifests.AppendObject(aFile);
+}
+
+namespace {
+struct AutoCloseFD
+{
+ AutoCloseFD()
+ : mFD(NULL)
+ { }
+ ~AutoCloseFD() {
+ if (mFD)
+ PR_Close(mFD);
+ }
+ operator PRFileDesc*() {
+ return mFD;
+ }
+
+ PRFileDesc** operator&() {
+ NS_ASSERTION(!mFD, "Re-opening a file");
+ return &mFD;
+ }
+
+ PRFileDesc* mFD;
+};
+
+} // anonymous namespace
+
+void
+nsComponentManagerImpl::RegisterManifestFile(NSLocationType aType,
+ nsILocalFile* aFile)
+{
+ nsresult rv;
+
+ AutoCloseFD fd;
+ rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &fd);
+ if (NS_FAILED(rv))
+ return;
+
+ PRFileInfo64 fileInfo;
+ if (PR_SUCCESS != PR_GetOpenFileInfo64(fd, &fileInfo))
+ return;
+
+ if (fileInfo.size > PRInt64(PR_INT32_MAX))
return;
- extension.Cut(0, dotPos + 1);
- if (extension.LowerCaseEqualsLiteral(NAKED_DLL_SUFFIX)) {
- const mozilla::Module* m = mNativeModuleLoader.LoadModule(aFile);
- if (!m)
+ nsAutoArrayPtr<char> data(new char[PRInt32(fileInfo.size + 1)]);
+
+ for (PRInt32 totalRead = 0; totalRead < fileInfo.size; ) {
+ PRInt32 read = PR_Read(fd, data + totalRead, PRInt32(fileInfo.size));
+ if (read < 0)
return;
- RegisterModule(m, aFile);
+ totalRead += read;
+ }
+
+ data[fileInfo.size] = '\0';
+ ParseManifest(aType, aFile, data);
+}
+
+void
+nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
+{
+ char* file = argv[0];
+
+ nsCOMPtr<nsIFile> cfile;
+ cx.mFile->GetParent(getter_AddRefs(cfile));
+ nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
+
+ nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Couldn't append relative path?");
+ return;
+ }
+
+ const mozilla::Module* m = mNativeModuleLoader.LoadModule(clfile);
+ if (!m) {
+ // XXX report load error
+ return;
+ }
+ RegisterModule(m, clfile);
+}
+
+void
+nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv)
+{
+ char* id = argv[0];
+ char* file = argv[1];
+
+ nsID cid;
+ if (!cid.Parse(id)) {
+ // XXX report parse error
+ return;
+ }
+
+ nsAutoMonitor mon(mMon);
+ nsFactoryEntry* f = mFactories.Get(cid);
+ if (f) {
+ // XXX report double-register error
+ return;
+ }
+
+ nsCOMPtr<nsIFile> cfile;
+ cx.mFile->GetParent(getter_AddRefs(cfile));
+ nsCOMPtr<nsILocalFile> clfile = do_QueryInterface(cfile);
+
+ nsresult rv = clfile->AppendRelativeNativePath(nsDependentCString(file));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Couldn't append relative path?");
+ return;
}
- else if (extension.EqualsLiteral("xpt")) {
- xptiInterfaceInfoManager::GetSingleton()
- ->RegisterFile(aFile,
- xptiInterfaceInfoManager::XPT);
+
+ nsCOMPtr<nsIHashable> h = do_QueryInterface(clfile);
+ KnownModule* km = mKnownFileModules.Get(h);
+ if (!km) {
+ km = new KnownModule(clfile);
+ mKnownFileModules.Put(h, km);
+ }
+
+ void* place;
+
+ PL_ARENA_ALLOCATE(place, &mArena, sizeof(nsCID));
+ nsID* permanentCID = static_cast<nsID*>(place);
+ *permanentCID = cid;
+
+ PL_ARENA_ALLOCATE(place, &mArena, sizeof(mozilla::Module::CIDEntry));
+ mozilla::Module::CIDEntry* e = new (place) mozilla::Module::CIDEntry();
+ e->cid = permanentCID;
+
+ f = new nsFactoryEntry(e, km);
+ mFactories.Put(cid, f);
+}
+
+void
+nsComponentManagerImpl::ManifestContract(ManifestProcessingContext& cx, int lineno, char *const * argv)
+{
+ char* contract = argv[0];
+ char* id = argv[1];
+
+ nsID cid;
+ if (!cid.Parse(id)) {
+ // XXX report parse error
+ return;
}
- else if (extension.EqualsLiteral("jar")) {
- xptiInterfaceInfoManager::GetSingleton()
- ->RegisterFile(aFile,
- xptiInterfaceInfoManager::ZIP);
+
+ nsAutoMonitor mon(mMon);
+ nsFactoryEntry* f = mFactories.Get(cid);
+ if (!f) {
+ // XXX report unregistered CID
+ return;
}
+
+ mContractIDs.Put(nsDependentCString(contract), f);
+}
+
+void
+nsComponentManagerImpl::ManifestCategory(ManifestProcessingContext& cx, int lineno, char *const * argv)
+{
+ char* category = argv[0];
+ char* key = argv[1];
+ char* value = argv[2];
+
+ nsCategoryManager::GetSingleton()->
+ AddCategoryEntry(category, key, value);
+}
+
+void
+nsComponentManagerImpl::RereadChromeManifests()
+{
+ NS_ERROR("XXX Not done!");
+}
+
+bool
+nsComponentManagerImpl::KnownModule::EnsureLoader()
+{
+ if (!mLoader) {
+ nsCString extension;
+ GetExtension(mFile, extension);
+
+ mLoader = nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
+ }
+ return !!mLoader;
}
bool
nsComponentManagerImpl::KnownModule::Load()
{
if (mFailed)
return false;
if (!mModule) {
+ if (!EnsureLoader())
+ return false;
mModule = mLoader->LoadModule(mFile);
if (!mModule) {
mFailed = true;
return false;
}
}
if (!mLoaded) {
if (mModule->loaded) {
@@ -545,16 +759,18 @@ nsresult nsComponentManagerImpl::Shutdow
mStatus = SHUTDOWN_IN_PROGRESS;
// Shutdown the component manager
PR_LOG(nsComponentManagerLog, PR_LOG_DEBUG, ("nsComponentManager: Beginning Shutdown."));
// Release all cached factories
mContractIDs.Clear();
mFactories.Clear(); // XXX release the objects, don't just clear
+ mLoaderMap.Clear();
+ mKnownFileModules.Clear();
mLoaderData.Clear();
// Unload libraries
mNativeModuleLoader.UnloadLibraries();
// delete arena for strings and small objects
PL_FinishArenaPool(&mArena);
@@ -1239,26 +1455,16 @@ nsComponentManagerImpl::LoaderForExtensi
return NULL;
mLoaderMap.Put(aExt, loader);
}
return loader.forget();
}
-static void
-ReportLoadFailure(nsIFile* aFile, nsIConsoleService* aCS)
-{
- nsAutoString message;
- aFile->GetPath(message);
- message.Insert(NS_LITERAL_STRING("Failed to load XPCOM component: "), 0);
-
- aCS->LogStringMessage(message.get());
-}
-
NS_IMETHODIMP
nsComponentManagerImpl::RegisterFactory(const nsCID& aClass,
const char* aName,
const char* aContractID,
nsIFactory* aFactory)
{
nsAutoPtr<nsFactoryEntry> f = new nsFactoryEntry(aFactory);
@@ -1413,17 +1619,17 @@ nsFactoryEntry::GetFactory()
if (!mModule->Load())
return NULL;
if (mModule->Module()->getfactory) {
mFactory = mModule->Module()->getfactory(*mModule->Module(),
*mCIDEntry);
}
- if (mCIDEntry->getfactory) {
+ else if (mCIDEntry->getfactory) {
mFactory = mCIDEntry->getfactory(*mModule->Module(), *mCIDEntry);
}
else {
NS_ASSERTION(mCIDEntry->constructor, "no getfactory or constructor");
mFactory = new mozilla::GenericFactory(mCIDEntry->constructor);
}
if (!mFactory)
return NULL;
@@ -1476,19 +1682,22 @@ XRE_AddStaticComponent(const mozilla::Mo
if (nsComponentManagerImpl::gComponentManager &&
nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
nsComponentManagerImpl::gComponentManager->RegisterModule(aComponent, NULL);
return NS_OK;
}
EXPORT_XPCOM_API(nsresult)
-XRE_AddComponentLocation(nsILocalFile* aLocation)
+XRE_AddComponentLocation(NSLocationType aType, nsILocalFile* aLocation)
{
nsComponentManagerImpl::InitializeModuleLocations();
- nsComponentManagerImpl::sModuleLocations->AppendObject(aLocation);
+ nsComponentManagerImpl::ComponentLocation* c =
+ nsComponentManagerImpl::sModuleLocations->AppendElement();
+ c->type = aType;
+ c->location = aLocation;
if (nsComponentManagerImpl::gComponentManager &&
nsComponentManagerImpl::NORMAL == nsComponentManagerImpl::gComponentManager->mStatus)
- nsComponentManagerImpl::gComponentManager->RegisterLocation(aLocation);
+ nsComponentManagerImpl::gComponentManager->RegisterLocation(aType, aLocation);
return NS_OK;
}
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -42,31 +42,33 @@
#include "xpcom-private.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIServiceManager.h"
#include "nsILocalFile.h"
#include "mozilla/Module.h"
#include "mozilla/ModuleLoader.h"
+#include "nsXULAppAPI.h"
#include "nsNativeComponentLoader.h"
#include "nsIFactory.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "pldhash.h"
#include "prtime.h"
#include "prmon.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsWeakReference.h"
#include "nsIFile.h"
#include "plarena.h"
#include "nsCOMArray.h"
#include "nsDataHashtable.h"
#include "nsInterfaceHashtable.h"
+#include "nsClassHashtable.h"
#include "nsTArray.h"
struct nsFactoryEntry;
class nsIServiceManager;
struct PRThread;
#define NS_COMPONENTMANAGER_CID \
{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
@@ -152,74 +154,111 @@ public:
nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories;
nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
PRMonitor* mMon;
static void InitializeStaticModules();
static void InitializeModuleLocations();
+ struct ComponentLocation
+ {
+ NSLocationType type;
+ nsCOMPtr<nsILocalFile> location;
+ };
+
static nsTArray<const mozilla::Module*>* sStaticModules;
- static nsCOMArray<nsILocalFile>* sModuleLocations;
+ static nsTArray<ComponentLocation>* sModuleLocations;
nsNativeModuleLoader mNativeModuleLoader;
class KnownModule
{
public:
/**
* Static or binary module.
*/
KnownModule(const mozilla::Module* aModule, nsILocalFile* aFile)
: mModule(aModule)
, mFile(aFile)
, mLoaded(false)
, mFailed(false)
{ }
- KnownModule(nsILocalFile* aFile, mozilla::ModuleLoader* aLoader)
+ KnownModule(nsILocalFile* aFile)
: mModule(NULL)
, mFile(aFile)
- , mLoader(aLoader)
+ , mLoader(NULL)
, mLoaded(false)
, mFailed(false)
{ }
~KnownModule()
{
if (mLoaded && mModule->unloaded)
mModule->unloaded();
}
+ bool EnsureLoader();
bool Load();
const mozilla::Module* Module() const
{
return mModule;
}
private:
const mozilla::Module* mModule;
nsCOMPtr<nsILocalFile> mFile;
nsCOMPtr<mozilla::ModuleLoader> mLoader;
bool mLoaded;
bool mFailed;
};
- nsTArray< nsAutoPtr<KnownModule> > mKnownModules;
+ // The KnownModule is kept alive by these members, it is referenced by pointer
+ // from the factory entries.
+ nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
+ nsClassHashtable<nsHashableHashKey, KnownModule> mKnownFileModules;
void RegisterModule(const mozilla::Module* aModule,
nsILocalFile* aFile);
void RegisterCIDEntry(const mozilla::Module::CIDEntry* aEntry,
KnownModule* aModule);
void RegisterContractID(const mozilla::Module::ContractIDEntry* aEntry);
- void RegisterLocation(nsILocalFile* aLocation);
- void RegisterDirectory(nsILocalFile* aDirectory);
- void RegisterFile(nsILocalFile* aFile);
+ void RegisterLocation(NSLocationType aType, nsILocalFile* aLocation);
+
+ // Register XPT/XPTJAR files, and fills aManifests with .manifest
+ // files, which must be registered after all DLLs so that networking is
+ // registered.
+ void RegisterDirectory(NSLocationType aType, nsILocalFile* aDirectory,
+ nsCOMArray<nsILocalFile>& aManifests);
+ void RegisterFile(NSLocationType aType, nsILocalFile* aFile,
+ nsCOMArray<nsILocalFile>& aManifests);
+
+ void RegisterManifestFile(NSLocationType aType, nsILocalFile* aFile);
+
+ struct ManifestProcessingContext
+ {
+ ManifestProcessingContext(NSLocationType aType, nsILocalFile* aFile)
+ : mType(aType)
+ , mFile(aFile)
+ { }
+ ~ManifestProcessingContext() { }
+
+ NSLocationType mType;
+ nsCOMPtr<nsILocalFile> mFile;
+ };
+
+ void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
+ void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
+ void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv);
+ void ManifestCategory(ManifestProcessingContext& cx, int lineno, char* const * argv);
+
+ void RereadChromeManifests();
// Shutdown
enum {
NOT_INITIALIZED,
NORMAL,
SHUTDOWN_IN_PROGRESS,
SHUTDOWN_COMPLETE
} mStatus;
--- a/xpcom/glue/nsClassHashtable.h
+++ b/xpcom/glue/nsClassHashtable.h
@@ -58,16 +58,22 @@ public:
typedef typename KeyClass::KeyType KeyType;
typedef T* UserDataType;
/**
* @copydoc nsBaseHashtable::Get
* @param pData if the key doesn't exist, pData will be set to nsnull.
*/
PRBool Get(KeyType aKey, UserDataType* pData) const;
+
+ /**
+ * @copydoc nsBaseHashtable::Get
+ * @returns NULL if the key is not present.
+ */
+ UserDataType Get(KeyType aKey) const;
};
/**
* Thread-safe version of nsClassHashtable
* @param KeyClass a wrapper-class for the hashtable key, see nsHashKeys.h
* for a complete specification.
* @param Class the class-type being wrapped
@@ -109,16 +115,29 @@ nsClassHashtable<KeyClass,T>::Get(KeyTyp
}
if (retVal)
*retVal = nsnull;
return PR_FALSE;
}
+template<class KeyClass,class T>
+T*
+nsClassHashtable<KeyClass,T>::Get(KeyType aKey) const
+{
+ typename nsBaseHashtable<KeyClass,nsAutoPtr<T>,T*>::EntryType* ent =
+ GetEntry(aKey);
+
+ if (!ent)
+ return NULL;
+
+ return ent->mData;
+}
+
//
// nsClassHashtableMT definitions
//
template<class KeyClass,class T>
PRBool
nsClassHashtableMT<KeyClass,T>::Get(KeyType aKey, T** retVal) const
--- a/xpcom/sample/Makefile.in
+++ b/xpcom/sample/Makefile.in
@@ -104,8 +104,13 @@ endif
include $(topsrcdir)/config/rules.mk
libs:: $(TARGETS)
$(INSTALL) $(srcdir)/xpconnect-sample.html $(DIST)/bin/res/samples
install:: $(TARGETS)
$(SYSINSTALL) $(IFLAGS1) $(srcdir)/xpconnect-sample.html $(DESTDIR)$(mozappdir)/res/samples
+# XXX TEMPORARY DEMONSTRATION HACK
+libs::
+ $(PYTHON) $(topsrcdir)/config/Preprocessor.py -Fsubstitution $(DEFINES) $(srcdir)/nsSample.manifest > $(DIST)/bin/components/nsSample.manifest
+
+DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY)
--- a/xpcom/sample/nsSample.js
+++ b/xpcom/sample/nsSample.js
@@ -35,95 +35,35 @@ mySample.prototype = {
if (iid.equals(Components.interfaces.nsISample) ||
iid.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
val: "<default value>"
-}
-
-var myModule = {
- firstTime: true,
-
- /*
- * RegisterSelf is called at registration time (component installation
- * or the only-until-release startup autoregistration) and is responsible
- * for notifying the component manager of all components implemented in
- * this module. The fileSpec, location and type parameters are mostly
- * opaque, and should be passed on to the registerComponent call
- * unmolested.
- */
- registerSelf: function (compMgr, fileSpec, location, type) {
- if (this.firstTime) {
- debug("*** Deferring registration of sample JS components\n");
- this.firstTime = false;
- throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
- }
- debug("*** Registering sample JS components\n");
- compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
- compMgr.registerFactoryLocation(this.myCID,
- "Sample JS Component",
- this.myProgID,
- fileSpec,
- location,
- type);
- },
-
- /*
- * The GetClassObject method is responsible for producing Factory objects
- */
- getClassObject: function (compMgr, cid, iid) {
- if (!cid.equals(this.myCID))
- throw Components.results.NS_ERROR_NO_INTERFACE;
-
- if (!iid.equals(Components.interfaces.nsIFactory))
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
-
- return this.myFactory;
- },
-
- /* CID for this class */
- myCID: Components.ID("{dea98e50-1dd1-11b2-9344-8902b4805a2e}"),
-
- /* ProgID for this class */
- myProgID: "@mozilla.org/jssample;1",
-
- /* factory object */
- myFactory: {
- /*
- * Construct an instance of the interface specified by iid, possibly
- * aggregating it with the provided outer. (If you don't know what
- * aggregation is all about, you don't need to. It reduces even the
- * mightiest of XPCOM warriors to snivelling cowards.)
- */
- createInstance: function (outer, iid) {
- debug("CI: " + iid + "\n");
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
-
- return (new mySample()).QueryInterface(iid);
- }
- },
-
- /*
- * The canUnload method signals that the component is about to be unloaded.
- * C++ components can return false to indicate that they don't wish to be
- * unloaded, but the return value from JS components' canUnload is ignored:
- * mark-and-sweep will keep everything around until it's no longer in use,
- * making unconditional ``unload'' safe.
- *
- * You still need to provide a (likely useless) canUnload method, though:
- * it's part of the nsIModule interface contract, and the JS loader _will_
- * call it.
- */
- canUnload: function(compMgr) {
- debug("*** Unloading sample JS components\n");
- return true;
- }
};
-function NSGetModule(compMgr, fileSpec) {
- return myModule;
+const kMyCID = Components.ID("{dea98e50-1dd1-11b2-9344-8902b4805a2e}");
+
+const kMyFactory = {
+ /*
+ * Construct an instance of the interface specified by iid, possibly
+ * aggregating it with the provided outer. (If you don't know what
+ * aggregation is all about, you don't need to. It reduces even the
+ * mightiest of XPCOM warriors to snivelling cowards.)
+ */
+ createInstance: function (outer, iid) {
+ debug("CI: " + iid + "\n");
+ if (outer != null)
+ throw Components.results.NS_ERROR_NO_AGGREGATION;
+
+ return (new mySample()).QueryInterface(iid);
+ }
+};
+
+function NSGetFactory(cid)
+{
+ if (cid.equals(kMyCID))
+ return kMyFactory;
+
+ throw Components.results.NS_ERROR_FACTORY_NOT_REGISTERED;
}
-
-
new file mode 100644
--- /dev/null
+++ b/xpcom/sample/nsSample.manifest
@@ -0,0 +1,3 @@
+component dea98e50-1dd1-11b2-9344-8902b4805a2e nsSample.js
+contract @mozilla.org/jssample;1 dea98e50-1dd1-11b2-9344-8902b4805a2e
+binary-component @SHARED_LIBRARY@
--- a/xpcom/tests/TestRegistrationOrder.cpp
+++ b/xpcom/tests/TestRegistrationOrder.cpp
@@ -156,18 +156,20 @@ int main(int argc, char** argv)
if (argc < 2)
{
fprintf(stderr, "not enough arguments -- need registration dir path\n");
return 1;
}
const char *regPath = argv[1];
- XRE_AddComponentLocation(nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "core")));
- XRE_AddComponentLocation(nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "extension")));
+ XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
+ nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "core")));
+ XRE_AddComponentLocation(NS_COMPONENT_LOCATION,
+ nsCOMPtr<nsILocalFile>(GetRegDirectory(regPath, "extension")));
ScopedXPCOM xpcom("RegistrationOrder");
if (xpcom.failed())
return 1;
int rv = 0;
if (NS_FAILED(TestRegular()))
rv = 1;
if (NS_FAILED(TestDeferred()))