Bug 470971 - Add ability to pass the GRE dir to xpcshell, r=ted - fixed patch: XRE_GetBinaryPath gets the file of the executable: we want to pass the parent directory to XPCOM.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Tue, 20 Jan 2009 14:56:44 -0500
changeset 24548 9a28db57d6a95203fd99907ac834d799b3309fe7
parent 24547 b6dece3b80537536435b78402e0f14cb331b2e0b
child 24549 6f89dd8e23af5bd2d932751468ffecdfbe649b2c
push id5111
push userbsmedberg@mozilla.com
push dateTue, 03 Feb 2009 14:15:55 +0000
treeherdermozilla-central@9a28db57d6a9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersted
bugs470971
milestone1.9.2a1pre
Bug 470971 - Add ability to pass the GRE dir to xpcshell, r=ted - fixed patch: XRE_GetBinaryPath gets the file of the executable: we want to pass the parent directory to XPCOM.
config/autoconf.mk.in
configure.in
js/src/xpconnect/shell/Makefile.in
js/src/xpconnect/shell/xpcshell.cpp
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -181,16 +181,17 @@ MOZ_UI_LOCALE = @MOZ_UI_LOCALE@
 
 MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS = @MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS@
 MOZ_COMPONENT_NSPR_LIBS=@MOZ_COMPONENT_NSPR_LIBS@
 
 MOZ_FIX_LINK_PATHS=@MOZ_FIX_LINK_PATHS@
 
 XPCOM_FROZEN_LDOPTS=@XPCOM_FROZEN_LDOPTS@
 XPCOM_LIBS=@XPCOM_LIBS@
+LIBXUL_LIBS=@LIBXUL_LIBS@
 MOZ_TIMELINE=@MOZ_TIMELINE@
 
 ENABLE_STRIP	= @ENABLE_STRIP@
 PKG_SKIP_STRIP	= @PKG_SKIP_STRIP@
 
 ClientWallet=1
 CookieManagement=1
 SingleSignon=1
--- a/configure.in
+++ b/configure.in
@@ -7249,16 +7249,18 @@ MOZ_ARG_ENABLE_BOOL(libxul,
 if test -n "$MOZ_STATIC_BUILD_UNSUPPORTED" -a -n "$BUILD_STATIC_LIBS"; then
 	AC_MSG_ERROR([--enable-static is not supported for building $MOZ_APP_NAME. You probably want --enable-libxul.])
 fi
 
 if test -n "$MOZ_ENABLE_LIBXUL" -a -n "$BUILD_STATIC_LIBS"; then
 	AC_MSG_ERROR([--enable-libxul is not compatible with --enable-static])
 fi
 
+AC_SUBST(LIBXUL_LIBS)
+
 if test -n "$MOZ_ENABLE_LIBXUL"; then
     XPCOM_LIBS="$LIBXUL_LIBS"
     AC_DEFINE(MOZ_ENABLE_LIBXUL)
 else
     if test -n "$BUILD_STATIC_LIBS"; then
         AC_DEFINE(MOZ_STATIC_BUILD)
     fi
     XPCOM_LIBS="$DYNAMIC_XPCOM_LIBS"
--- a/js/src/xpconnect/shell/Makefile.in
+++ b/js/src/xpconnect/shell/Makefile.in
@@ -45,28 +45,29 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= xpcshell
 PROGRAM		= xpcshell$(BIN_SUFFIX)
 
 REQUIRES	= xpconnect \
 		  xpcom \
 		  js \
 		  caps \
+		  xulapp \
 		  $(NULL)
 
 CPPSRCS		= xpcshell.cpp
 
 ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
 CMMSRCS += xpcshellMacUtils.mm
 endif
 
 LIBS		= \
 		$(DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) \
+		$(LIBXUL_LIBS) \
 		$(MOZ_JS_LIBS) \
-		$(XPCOM_LIBS) \
 		$(NSPR_LIBS) \
 		$(NULL)
 
 NSDISTMODE = copy
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DJS_THREADSAFE
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -40,34 +40,40 @@
  * 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 ***** */
 
 /* XPConnect JavaScript interactive shell. */
 
 #include <stdio.h>
+#include "nsXULAppAPI.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
+#include "nsStringAPI.h"
 #include "nsIXPConnect.h"
 #include "nsIXPCScriptable.h"
 #include "nsIInterfaceInfo.h"
 #include "nsIInterfaceInfoManager.h"
 #include "nsIXPCScriptable.h"
 #include "nsIServiceManager.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsILocalFile.h"
 #include "nsStringAPI.h"
+#include "nsIDirectoryService.h"
+#include "nsILocalFile.h"
+#include "nsDirectoryServiceDefs.h"
 #include "jsapi.h"
 #include "jsdbgapi.h"
 #include "jsprf.h"
 #include "nscore.h"
 #include "nsMemory.h"
 #include "nsIGenericFactory.h"
+#include "nsISupportsImpl.h"
 #include "nsIJSRuntimeService.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIXPCSecurityManager.h"
 #ifdef XP_MACOSX
 #include "xpcshellMacUtils.h"
 #endif
 #ifdef XP_WIN
@@ -86,16 +92,32 @@
 #include <io.h>     /* for isatty() */
 #endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>     /* for isatty() */
 #endif
 
 #include "nsIJSContextStack.h"
 
+class XPCShellDirProvider : public nsIDirectoryServiceProvider
+{
+public:
+    NS_DECL_ISUPPORTS_INHERITED
+    NS_DECL_NSIDIRECTORYSERVICEPROVIDER
+
+    XPCShellDirProvider() { }
+    ~XPCShellDirProvider() { }
+
+    PRBool SetGREDir(const char *dir);
+    void ClearGREDir() { mGREDir = nsnull; }
+
+private:
+    nsCOMPtr<nsILocalFile> mGREDir;
+};
+
 /***************************************************************************/
 
 #ifdef JS_THREADSAFE
 #define DoBeginRequest(cx) JS_BeginRequest((cx))
 #define DoEndRequest(cx)   JS_EndRequest((cx))
 #else
 #define DoBeginRequest(cx) ((void)0)
 #define DoEndRequest(cx)   ((void)0)
@@ -914,17 +936,17 @@ Process(JSContext *cx, JSObject *obj, co
 
     ProcessFile(cx, obj, filename, file, forceTTY);
 }
 
 static int
 usage(void)
 {
     fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
-    fprintf(gErrFile, "usage: xpcshell [-PswWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
+    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-PswWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
     return 2;
 }
 
 extern JSClass global_class;
 
 static int
 ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
 {
@@ -1543,19 +1565,49 @@ main(int argc, char **argv, char **envp)
     // unbuffer stdout so that output is in the correct order; note that stderr
     // is unbuffered by default
     setbuf(stdout, 0);
 #endif
 
     gErrFile = stderr;
     gOutFile = stdout;
     gInFile = stdin;
+
+    NS_LogInit();
+
+    nsCOMPtr<nsILocalFile> appFile;
+    rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(appFile));
+    if (NS_FAILED(rv)) {
+        printf("Couldn't figure application file.\n");
+        return 1;
+    }
+    nsCOMPtr<nsIFile> appDir;
+    rv = appFile->GetParent(getter_AddRefs(appDir));
+    if (NS_FAILED(rv)) {
+        printf("Couldn't get application directory.\n");
+        return 1;
+    }
+
+    XPCShellDirProvider dirprovider;
+
+    if (argc > 1 && !strcmp(argv[1], "-g")) {
+        if (argc < 3)
+            return usage();
+
+        if (!dirprovider.SetGREDir(argv[2])) {
+            printf("SetGREDir failed.\n");
+            return 1;
+        }
+        argc -= 2;
+        argv += 2;
+    }
+
     {
         nsCOMPtr<nsIServiceManager> servMan;
-        rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+        rv = NS_InitXPCOM2(getter_AddRefs(servMan), appDir, &dirprovider);
         if (NS_FAILED(rv)) {
             printf("NS_InitXPCOM failed!\n");
             return 1;
         }
         {
             nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
             NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
             if (registrar)
@@ -1711,14 +1763,54 @@ main(int argc, char **argv, char **envp)
 
 #ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
     // test of late call and release (see above)
     JSContext* bogusCX;
     bogus->Peek(&bogusCX);
     bogus = nsnull;
 #endif
 
+    appDir = nsnull;
+    appFile = nsnull;
+    dirprovider.ClearGREDir();
+
+    NS_LogTerm();
+
 #ifdef XP_MACOSX
     FinishAutoreleasePool();
 #endif
 
     return result;
 }
+
+PRBool
+XPCShellDirProvider::SetGREDir(const char *dir)
+{
+    nsresult rv = XRE_GetFileFromPath(dir, getter_AddRefs(mGREDir));
+    return NS_SUCCEEDED(rv);
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+XPCShellDirProvider::AddRef()
+{
+    return 2;
+}
+
+NS_IMETHODIMP_(nsrefcnt)
+XPCShellDirProvider::Release()
+{
+    return 1;
+}
+
+NS_IMPL_QUERY_INTERFACE1(XPCShellDirProvider, nsIDirectoryServiceProvider)
+
+NS_IMETHODIMP
+XPCShellDirProvider::GetFile(const char *prop, PRBool *persistent,
+                             nsIFile* *result)
+{
+    if (mGREDir && !strcmp(prop, NS_GRE_DIR)) {
+        *persistent = PR_TRUE;
+        NS_ADDREF(*result = mGREDir);
+        return NS_OK;
+    }
+
+    return NS_ERROR_FAILURE;
+}