Bug 388833 - Give the Firefox binary the ability to kinda-sorta launch XR apps (mainly meant for webrunner experimentation right now), r=luser
authorbenjamin@smedbergs.us
Wed, 25 Jul 2007 13:24:37 -0700
changeset 3970 ea67dba653c5c1bbd38b49d68526fdbf09705fae
parent 3969 e0dbe121fa09879df2c9e3cc1cf295f19e1c3b46
child 3971 adcc7a17b262f8133fc7d52c9a8ccb7ca89105aa
push idunknown
push userunknown
push dateunknown
reviewersluser
bugs388833
milestone1.9a7pre
Bug 388833 - Give the Firefox binary the ability to kinda-sorta launch XR apps (mainly meant for webrunner experimentation right now), r=luser
browser/app/nsBrowserApp.cpp
toolkit/xre/nsAppData.cpp
xulrunner/app/nsXULRunnerApp.cpp
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -40,16 +40,20 @@
 #ifdef XP_WIN
 #include <windows.h>
 #include <stdlib.h>
 #endif
 
 #include <stdio.h>
 #include <stdarg.h>
 
+#include "plstr.h"
+#include "prprf.h"
+#include "prenv.h"
+
 #include "nsCOMPtr.h"
 #include "nsILocalFile.h"
 #include "nsStringGlue.h"
 
 static void Output(const char *fmt, ... )
 {
   va_list ap;
   va_start(ap, fmt);
@@ -62,35 +66,99 @@ static void Output(const char *fmt, ... 
   MessageBox(NULL, msg, "XULRunner", MB_OK | MB_ICONERROR);
 #else
   vfprintf(stderr, fmt, ap);
 #endif
 
   va_end(ap);
 }
 
+/**
+ * Return true if |arg| matches the given argument name.
+ */
+static PRBool IsArg(const char* arg, const char* s)
+{
+  if (*arg == '-')
+  {
+    if (*++arg == '-')
+      ++arg;
+    return !PL_strcasecmp(arg, s);
+  }
+
+#if defined(XP_WIN) || defined(XP_OS2)
+  if (*arg == '/')
+    return !PL_strcasecmp(++arg, s);
+#endif
+
+  return PR_FALSE;
+}
+
+/**
+ * A helper class which calls NS_LogTerm/NS_LogTerm in its scope.
+ */
+class ScopedLogging
+{
+public:
+  ScopedLogging() { NS_LogInit(); }
+  ~ScopedLogging() { NS_LogTerm(); }
+};
+
 int main(int argc, char* argv[])
 {
+  ScopedLogging log;
+
   nsCOMPtr<nsILocalFile> appini;
   nsresult rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(appini));
   if (NS_FAILED(rv)) {
     Output("Couldn't calculate the application directory.");
     return 255;
   }
   appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini"));
 
+  // Allow firefox.exe to launch XULRunner apps via -app <application.ini>
+  // Note that -app must be the *first* argument.
+  char *appEnv = nsnull;
+  const char *appDataFile = PR_GetEnv("XUL_APP_FILE");
+  if (appDataFile && *appDataFile) {
+    rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini));
+    if (NS_FAILED(rv)) {
+      Output("Invalid path found: '%s'", appDataFile);
+      return 255;
+    }
+  }
+  else if (argc > 1 && IsArg(argv[1], "app")) {
+    if (argc == 2) {
+      Output("Incorrect number of arguments passed to -app");
+      return 255;
+    }
+
+    rv = XRE_GetFileFromPath(argv[2], getter_AddRefs(appini));
+    if (NS_FAILED(rv)) {
+      Output("application.ini path not recognized: '%s'", argv[2]);
+      return 255;
+    }
+
+    appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]);
+    PR_SetEnv(appEnv);
+    argv[2] = argv[0];
+    argv += 2;
+    argc -= 2;
+  }
+
   nsXREAppData *appData;
   rv = XRE_CreateAppData(appini, &appData);
   if (NS_FAILED(rv)) {
     Output("Couldn't read application.ini");
     return 255;
   }
 
   int result = XRE_main(argc, argv, appData);
   XRE_FreeAppData(appData);
+  if (appEnv)
+    PR_smprintf_free(appEnv);
   return result;
 }
 
 #if defined( XP_WIN ) && defined( WIN32 ) && !defined(__GNUC__)
 // We need WinMain in order to not be a console app.  This function is
 // unused if we are a console application.
 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR args, int )
 {
--- a/toolkit/xre/nsAppData.cpp
+++ b/toolkit/xre/nsAppData.cpp
@@ -35,16 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsXULAppAPI.h"
 #include "nsINIParser.h"
 #include "nsILocalFile.h"
 #include "nsAppRunner.h"
 #include "nsCRTGlue.h"
+#include "nsAutoPtr.h"
 
 void
 SetAllocatedString(const char *&str, const char *newvalue)
 {
   NS_Free(const_cast<char*>(str));
   if (newvalue) {
     str = NS_strdup(newvalue);
   }
@@ -109,29 +110,37 @@ ScopedAppData::~ScopedAppData()
   SetAllocatedString(this->crashReporterURL, nsnull);
 }
 
 nsresult
 XRE_CreateAppData(nsILocalFile* aINIFile, nsXREAppData **aAppData)
 {
   NS_ENSURE_ARG(aINIFile && aAppData);
 
-  nsXREAppData *data = new ScopedAppData();
+  nsAutoPtr<nsXREAppData> data = new ScopedAppData();
   if (!data)
     return NS_ERROR_OUT_OF_MEMORY;
 
   nsresult rv = XRE_ParseAppData(aINIFile, data);
-  if (NS_FAILED(rv)) {
-    delete data;
-  }
-  else {
-    *aAppData = data;
+  if (NS_FAILED(rv))
+    return rv;
+
+  if (!data->directory) {
+    nsCOMPtr<nsIFile> appDir;
+    rv = aINIFile->GetParent(getter_AddRefs(appDir));
+    if (NS_FAILED(rv))
+      return rv;
+
+    rv = CallQueryInterface(appDir, &data->directory);
+    if (NS_FAILED(rv))
+      return rv;
   }
 
-  return rv;
+  *aAppData = data.forget();
+  return NS_OK;
 }
 
 struct ReadString {
   const char *section;
   const char *key;
   const char **buffer;
 };
 
--- a/xulrunner/app/nsXULRunnerApp.cpp
+++ b/xulrunner/app/nsXULRunnerApp.cpp
@@ -438,27 +438,16 @@ int main(int argc, char* argv[])
   }
 
   AutoAppData appData(appDataLF);
   if (!appData) {
     Output(PR_TRUE, "Error: couldn't parse application.ini.\n");
     return 2;
   }
 
-  if (!appData->directory) {
-    nsCOMPtr<nsIFile> appDir;
-    rv = appDataLF->GetParent(getter_AddRefs(appDir));
-    if (NS_FAILED(rv)) {
-      Output(PR_TRUE, "Error: could not get application directory.\n");
-      return 2;
-    }
-
-    CallQueryInterface(appDir, &appData->directory);
-  }
-
   return XRE_main(argc, argv, appData);
 }
 
 #if defined( XP_WIN ) && defined( WIN32 ) && !defined(__GNUC__)
 // We need WinMain in order to not be a console app.  This function is
 // unused if we are a console application.
 int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR args, int )
 {