b=404134. r=bsmedberg. a=dsicore. Allow XULRunner apps to override application.ini
authormark.finkle@gmail.com
Thu, 29 Nov 2007 09:20:54 -0800
changeset 8449 ef55cdf82bf120f67d7608ff2807a8e3fc695a63
parent 8448 6a83d3c3eee901e4547c67f58bc06dbf2ab2dd9f
child 8450 aca1cfe375b27b22fe94e40f5ec2aa22d9ef559f
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, dsicore
bugs404134
milestone1.9b2pre
b=404134. r=bsmedberg. a=dsicore. Allow XULRunner apps to override application.ini
xulrunner/app/nsXULRunnerApp.cpp
xulrunner/stub/nsXULStub.cpp
--- a/xulrunner/app/nsXULRunnerApp.cpp
+++ b/xulrunner/app/nsXULRunnerApp.cpp
@@ -73,17 +73,17 @@ static void Output(PRBool isError, const
 
 #if defined(XP_WIN) && !MOZ_WINCONSOLE
   char *msg = PR_vsmprintf(fmt, ap);
   if (msg)
   {
     UINT flags = MB_OK;
     if (isError)
       flags |= MB_ICONERROR;
-    else 
+    else
       flags |= MB_ICONINFORMATION;
     MessageBox(NULL, msg, "XULRunner", flags);
     PR_smprintf_free(msg);
   }
 #else
   vfprintf(stderr, fmt, ap);
 #endif
 
@@ -262,16 +262,21 @@ public:
     if (NS_FAILED(rv))
       mAppData = nsnull;
   }
   ~AutoAppData() {
     if (mAppData)
       XRE_FreeAppData(mAppData);
   }
 
+  nsresult
+  Override(nsILocalFile* aINIFile) {
+    return XRE_ParseAppData(aINIFile, mAppData);
+  }
+
   operator nsXREAppData*() const { return mAppData; }
   nsXREAppData* operator -> () const { return mAppData; }
 
 private:
   nsXREAppData* mAppData;
 };
 
 int main(int argc, char* argv[])
@@ -438,16 +443,40 @@ int main(int argc, char* argv[])
   }
 
   AutoAppData appData(appDataLF);
   if (!appData) {
     Output(PR_TRUE, "Error: couldn't parse application.ini.\n");
     return 2;
   }
 
+  if (argc > 1 && IsArg(argv[1], "override")) {
+    if (argc == 2) {
+      Usage(argv[0]);
+      return 1;
+    }
+    argv[1] = argv[0];
+    ++argv;
+    --argc;
+
+    const char *ovrDataFile = argv[1];
+    argv[1] = argv[0];
+    ++argv;
+    --argc;
+
+    nsCOMPtr<nsILocalFile> ovrDataLF;
+    nsresult rv = XRE_GetFileFromPath(ovrDataFile, getter_AddRefs(ovrDataLF));
+    if (NS_FAILED(rv)) {
+      Output(PR_TRUE, "Error: unrecognized override.ini path.\n");
+      return 2;
+    }
+
+    appData.Override(ovrDataLF);
+  }
+
   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 )
 {
--- a/xulrunner/stub/nsXULStub.cpp
+++ b/xulrunner/stub/nsXULStub.cpp
@@ -45,16 +45,17 @@
 
 #include <stdarg.h>
 
 #ifdef XP_WIN
 #include <windows.h>
 #include <io.h>
 #define snprintf _snprintf
 #define vsnprintf _vsnprintf
+#define strcasecmp stricmp
 #define PATH_SEPARATOR_CHAR '\\'
 #include "nsWindowsRestart.cpp"
 #define R_OK 04
 #elif defined(XP_MACOSX)
 #include <CFBundle.h>
 #define PATH_SEPARATOR_CHAR '/'
 #elif defined (XP_OS2)
 #define INCL_DOS
@@ -82,48 +83,71 @@ static void Output(PRBool isError, const
 #if defined(XP_WIN) && !MOZ_WINCONSOLE
   char msg[2048];
 
   vsnprintf(msg, sizeof(msg), fmt, ap);
 
   UINT flags = MB_OK;
   if (isError)
     flags |= MB_ICONERROR;
-  else 
+  else
     flags |= MB_ICONINFORMATION;
   MessageBox(NULL, msg, "XULRunner", flags);
 #else
   vfprintf(stderr, fmt, ap);
 #endif
 
   va_end(ap);
 }
 
+static PRBool IsArg(const char* arg, const char* s)
+{
+  if (*arg == '-')
+  {
+    if (*++arg == '-')
+      ++arg;
+    return !strcasecmp(arg, s);
+  }
+
+#if defined(XP_WIN) || defined(XP_OS2)
+  if (*arg == '/')
+    return !strcasecmp(++arg, s);
+#endif
+
+  return PR_FALSE;
+}
+
 class AutoAppData
 {
 public:
   AutoAppData(nsILocalFile* aINIFile) : mAppData(nsnull) {
     nsresult rv = XRE_CreateAppData(aINIFile, &mAppData);
     if (NS_FAILED(rv))
       mAppData = nsnull;
   }
   ~AutoAppData() {
     if (mAppData)
       XRE_FreeAppData(mAppData);
   }
 
+  nsresult
+  Override(nsILocalFile* aINIFile) {
+    return XRE_ParseAppData(aINIFile, mAppData);
+  }
+
   operator nsXREAppData*() const { return mAppData; }
   nsXREAppData* operator -> () const { return mAppData; }
 
 private:
   nsXREAppData* mAppData;
 };
 
 XRE_CreateAppDataType XRE_CreateAppData;
 XRE_FreeAppDataType XRE_FreeAppData;
+XRE_ParseAppDataType XRE_ParseAppData;
 XRE_mainType XRE_main;
 
 int
 main(int argc, char **argv)
 {
   nsresult rv;
   char *lastSlash;
 
@@ -169,17 +193,17 @@ main(int argc, char **argv)
 
 #ifdef XP_WIN
   if (!::GetModuleFileName(NULL, iniPath, sizeof(iniPath)))
     return 1;
 
 #elif defined(XP_OS2)
    PPIB ppib;
    PTIB ptib;
- 
+
    DosGetInfoBlocks(&ptib, &ppib);
    DosQueryModuleName(ppib->pib_hmte, sizeof(iniPath), iniPath);
 
 #else
   // on unix, there is no official way to get the path of the current binary.
   // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to
   // multiple applications, we will try a series of techniques:
   //
@@ -272,17 +296,17 @@ main(int argc, char **argv)
     rv = GRE_GetGREPathWithProperties(&range, 1,
                                       kProperties, NS_ARRAY_LENGTH(kProperties),
                                       greDir, sizeof(greDir));
     if (NS_FAILED(rv)) {
       // XXXbsmedberg: Do something much smarter here: notify the
       // user/offer to download/?
 
       Output(PR_FALSE,
-             "Could not find compatible GRE between version %s and %s.\n", 
+             "Could not find compatible GRE between version %s and %s.\n",
              range.lower, range.upper);
       return 1;
     }
   }
 #ifdef XP_OS2
   // On OS/2 we need to set BEGINLIBPATH to be able to find XULRunner DLLs
   strcpy(tmpPath, greDir);
   lastSlash = strrchr(tmpPath, PATH_SEPARATOR_CHAR);
@@ -296,16 +320,17 @@ main(int argc, char **argv)
   if (NS_FAILED(rv)) {
     Output(PR_TRUE, "Couldn't load XPCOM.\n");
     return 1;
   }
 
   static const nsDynamicFunctionLoad kXULFuncs[] = {
     { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData },
     { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData },
+    { "XRE_ParseAppData", (NSFuncPtr*) &XRE_ParseAppData },
     { "XRE_main", (NSFuncPtr*) &XRE_main },
     { nsnull, nsnull }
   };
 
   rv = XPCOMGlueLoadXULFunctions(kXULFuncs);
   if (NS_FAILED(rv)) {
     Output(PR_TRUE, "Couldn't load XRE functions.\n");
     return 1;
@@ -337,16 +362,35 @@ main(int argc, char **argv)
       lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR);
       if (lastSlash) {
         *lastSlash = '\0';
       }
       NS_NewNativeLocalFile(nsDependentCString(greDir), PR_FALSE,
                             &appData->xreDirectory);
     }
 
+    if (argc > 1 && IsArg(argv[1], "override")) {
+      if (argc == 2) {
+        Output(PR_TRUE, "Error: missing override.ini file.\n");
+        return 1;
+      }
+
+      const char *ovrDataFile = argv[2];
+
+      nsCOMPtr<nsILocalFile> ovrDataLF;
+      nsresult rv = NS_NewNativeLocalFile(nsDependentCString(ovrDataFile), PR_FALSE,
+                               getter_AddRefs(ovrDataLF));
+      if (NS_FAILED(rv)) {
+        Output(PR_TRUE, "Error: unrecognized override.ini path.\n");
+        return 1;
+      }
+
+      appData.Override(ovrDataLF);
+    }
+
     retval = XRE_main(argc, argv, appData);
   }
 
   NS_LogTerm();
 
   XPCOMGlueShutdown();
 
   return retval;