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 23908 917e4f318003d85195c1d6fa18793f461e678a2c
parent 23907 e9b3e83c66c3f49849ee861ec105d09c70f5c9c0
child 23909 c90cbbc0f90de95071fea4c778c80f866efbc1e9
push id980
push usertmielczarek@mozilla.com
push dateWed, 25 Mar 2009 17:09:45 +0000
reviewersted
bugs470971
milestone1.9.1b4pre
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
@@ -182,16 +182,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
@@ -7193,16 +7193,18 @@ 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
 
 if test -n "$MOZ_ENABLE_LIBXUL" -a -z "$MOZ_XUL_APP"; then
 	AC_MSG_ERROR([--enable-libxul is only compatible with toolkit XUL applications.])
 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)
 
 include $(topsrcdir)/config/rules.mk
 
 DEFINES		+= -DJS_THREADSAFE
 
 ifdef MOZ_SHARK
--- 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
@@ -85,16 +91,32 @@
 #if defined(XP_WIN) || defined(XP_OS2)
 #include <io.h>     /* for isatty() */
 #elif defined(XP_UNIX) || defined(XP_BEOS)
 #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)
@@ -916,17 +938,17 @@ Process(JSContext *cx, JSObject *obj, co
     if (file != stdin)
         fclose(file);
 }
 
 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)
 {
@@ -1544,19 +1566,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);
 
     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)
@@ -1712,14 +1764,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;
+}