Mozilla/mozilla/xpfe/apprunner/src/nsAppRunner.cpp
sudu%netscape.com d3239a027a OJI MozClassic to raptor merge
git-svn-id: svn://10.0.0.236/trunk@18465 18797224-902f-48f8-a5cc-f745e15eee43
1999-01-25 08:05:00 +00:00

391 lines
12 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (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/NPL/
*
* 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 Communicator client code.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1998
* Netscape Communications Corporation. All Rights Reserved.
*/
#include <stdio.h>
#include <stdarg.h>
#include "nsAppRunner.h"
#include "nsIAppShellService.h"
#include "nsRepository.h"
#include "nsIServiceManager.h"
#include "xp_core.h"
#include "xp_mcom.h"
#include "xp_str.h"
// Define Class IDs.
static NS_DEFINE_IID(kAppRunnerCID, NS_APPRUNNER_CID);
// Define Interface IDs.
static NS_DEFINE_IID(kIAppRunnerIID, NS_IAPPRUNNER_IID);
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
// Generate implementation of nsISupports stuff.
NS_IMPL_ISUPPORTS(nsAppRunner, kIAppRunnerIID);
// ctor
nsAppRunner::nsAppRunner()
: mArgc( 0 ), mArg( 0 ) {
NS_INIT_REFCNT();
}
// dtor
nsAppRunner::~nsAppRunner() {
delete [] mArg;
}
/*---------------------------- nsAppRunner::main -------------------------------
| Initialize, then load and run the app shell. All work is farmed out to |
| virtual functions to enable customization. | |
------------------------------------------------------------------------------*/
NS_IMETHODIMP
nsAppRunner::main( int argc, char *argv[] ) {
#if 0
fprintf( stdout, "nsAppRunner::main entered\n" );
for ( int i = 0; i < argc; i++ ) {
fprintf( stdout, "\targv[%d] = %s\n", i, argv[i] );
}
return NS_OK;
#else
nsresult rv = Initialize();
if ( rv == NS_OK ) {
// Load app shell.
rv = LoadAppShell();
if ( rv == NS_OK ) {
// Execute the shell.
rv = AppShell()->Initialize();
if ( rv == NS_OK ) {
// Run the shell.
rv = AppShell()->Run();
// Shut it down.
AppShell()->Shutdown();
if ( rv != NS_OK ) {
DisplayMsg( "nsAppRunner error", "app shell failed to run, rv=0x%lX", rv );
}
} else {
DisplayMsg( "nsAppRunner error", "app shell initialization failed, rv=0x%lX", rv );
}
} else {
char *cid = AppShellCID().ToString();
DisplayMsg( "nsAppRunner error", "Unable to load app shell (CID=%s), rv=0x%lX", cid, rv );
delete [] cid;
}
} else {
DisplayMsg( "nsAppRunner error", "Initialize failed, rv=0x%lX", rv );
}
return rv;
#endif
}
/*---------------------- NSAppRunner::ParseCommandLine -------------------------
| Store the command line arguments in data members with minor twiddling to |
| simplify lookup. |
------------------------------------------------------------------------------*/
PRBool nsAppRunner::ParseCommandLine( int argc, char *argv[] ) {
mArgc = argc;
// Allocate array of arg info structures.
mArg = new Arg[ mArgc ];
// Fill in structures.
for( int i = 0; i < mArgc; i++ ) {
char *p = argv[i];
// "Key" is always the beginning
mArg[i].key = p;
// Bump pointer till we get to null or double quote.
while ( *p && *p != '"' ) {
p++;
}
// If not null, get value.
if ( *p ) {
*p++ = 0; // Terminate key and advance pointer.
// Value starts here.
mArg[i].value = p;
// Strip trailing '"'.
if ( p[ XP_STRLEN(p) ] == '"' ) {
p[ XP_STRLEN(p) ] = 0;
}
} else {
// Have value point to this null string.
mArg[i].value = p;
}
}
return PR_TRUE;
}
/*------------------------- nsAppRunner::IndexOfArg ----------------------------
| Return index of specified argument "key." -1 if not found. |
------------------------------------------------------------------------------*/
int nsAppRunner::IndexOfArg( const char *key, PRBool ignoreCase ) {
int result = -1;
for( int i = 0; result == -1 && i < mArgc; i++ ) {
if ( ( ignoreCase && XP_STRCASECMP( key, mArg[i].key ) == 0 )
||
( !ignoreCase && XP_STRCMP( key, mArg[i].key ) == 0 ) ) {
result = i;
}
}
return result;
}
/*---------------------- nsAppRunner::IsOptionSpecified ------------------------
| Search for key via IndexOfArg and return true iff it is found. |
------------------------------------------------------------------------------*/
PRBool nsAppRunner::IsOptionSpecified( const char *key, PRBool ignoreCase ) {
int index = this->IndexOfArg( key, ignoreCase );
return index != -1;
}
/*----------------------- nsAppRunner::*ValueForOption -------------------------
| Search for key via IndexOfArg and return corresponding value if it is found, |
| 0 otherwise. |
------------------------------------------------------------------------------*/
const char *nsAppRunner::ValueForOption( const char *key, PRBool ignoreCase ) {
const char *result = 0;
int index = this->IndexOfArg( key, ignoreCase );
if ( index != -1 ) {
result = mArg[ index ].value;
}
return result;
}
/*------------------------- nsAppRunner::Initialize ----------------------------
| Default simply returns NS_OK. |
------------------------------------------------------------------------------*/
nsresult nsAppRunner::Initialize() {
return NS_OK;
}
/*--------------------------- nsAppRunner::OnExit ------------------------------
| Default simply returns the input application return value unmodified. |
------------------------------------------------------------------------------*/
nsresult nsAppRunner::OnExit( nsresult rvIn ) {
return rvIn;
}
/*------------------------- nsAppRunner::AppShellCID ---------------------------
| Return the CID for nsAppShell. Long term, get this ID dynamically? |
------------------------------------------------------------------------------*/
nsCID nsAppRunner::AppShellCID() const {
nsCID appShellCID = NS_APPSHELL_SERVICE_CID;
return appShellCID;
}
/*------------------------ nsAppRunner::LoadAppShell ---------------------------
| Create an instance of the app shell (object of class represented by |
| the CID returned by AppShellCID). |
------------------------------------------------------------------------------*/
nsresult nsAppRunner::LoadAppShell() {
nsIAppShellService *appShell = 0;
nsIID kIAppShellServiceIID = NS_IAPPSHELL_SERVICE_IID;
nsresult rv = nsServiceManager::GetService( this->AppShellCID(),
kIAppShellServiceIID,
(nsISupports**)&appShell );
if ( rv == NS_OK ) {
this->SetAppShell( appShell );
NS_IF_RELEASE( appShell );
}
return rv;
}
/*-------------------------- nsAppRunner::RunShell -----------------------------
| Run the app shell. |
------------------------------------------------------------------------------*/
nsresult nsAppRunner::RunShell() {
nsresult result = this->mAppShell->Run();
return result;
}
/*-------------------------- nsAppRunner::*AppShell ----------------------------
| Return the app shell associated with this app runner. |
------------------------------------------------------------------------------*/
nsIAppShellService *nsAppRunner::AppShell() const {
return mAppShell;
}
/*------------------------- nsAppRunner::DisplayMsg ----------------------------
| Write out the title and text to stderr. |
------------------------------------------------------------------------------*/
void nsAppRunner::DisplayMsg( const char *title, const char *text ) {
fprintf( stderr, "%s\n", title );
fprintf( stderr, "%s\n", text );
return;
}
/*------------------------- nsAppRunner::DisplayMsg ----------------------------
| Use svprintf to expand the text+args then display the complete text using |
| the overloaded version of nsAppRunner::DisplayMsg(). |
------------------------------------------------------------------------------*/
static void displayMsg( nsAppRunner &obj, const char *title, const char *text, va_list args ) {
// Fix this later.
obj.DisplayMsg( title, text );
return;
}
/*------------------------- nsAppRunner::DisplayMsg ----------------------------
| Convert the extra arguments to a vargs list and invoke the static function |
| that takes one of those. |
------------------------------------------------------------------------------*/
void nsAppRunner::DisplayMsg( const char *title, const char *text, ... ) {
va_list args;
va_start( text, args );
this->DisplayMsg( title, text, args );
va_end( args );
return;
}
/*------------------------ nsAppRunner::&SetAppShell ---------------------------
| Simply do as directed, return *this. |
------------------------------------------------------------------------------*/
nsAppRunner &nsAppRunner::SetAppShell( nsIAppShellService *newAppShell ) {
// Bump refcount for new shell.
newAppShell->AddRef();
// Release current app shell.
NS_IF_RELEASE(this->mAppShell);
// Attach new one.
this->mAppShell = newAppShell;
return *this;
}
#if 0
// nsAppRunnerFactory
//
// Means by which instances are created via nsRepository.
// This code is somewhat temporary as the CreateInstance should really
// go in platform-specific code in order to create an instance specific
// to the platform on which we're running.
class nsAppRunnerFactory : public nsIFactory {
public:
NS_DECL_ISUPPORTS
nsAppRunnerFactory();
// nsIFactory methods
NS_IMETHOD CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult);
NS_IMETHOD LockFactory(PRBool aLock);
protected:
virtual ~nsAppRunnerFactory();
};
nsAppRunnerFactory::nsAppRunnerFactory() {
NS_INIT_REFCNT();
}
nsAppRunnerFactory::~nsAppRunnerFactory() {
NS_ASSERTION(mRefCnt == 0, "non-zero refcnt at destruction");
}
NS_IMPL_ISUPPORTS(nsAppRunnerFactory, kIFactoryIID);
NS_IMETHODIMP
nsAppRunnerFactory::CreateInstance(nsISupports *aOuter,
const nsIID &aIID,
void **aResult) {
nsresult rv = NS_OK;
nsAppRunner* newAppRunner;
if (aResult == NULL) {
return NS_ERROR_NULL_POINTER;
} else {
*aResult = NULL;
}
if (0 != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
NS_NEWXPCOM(newAppRunner, nsAppRunner);
if (newAppRunner == NULL) {
return NS_ERROR_OUT_OF_MEMORY;
}
NS_ADDREF(newAppRunner);
rv = newAppRunner->QueryInterface(aIID, aResult);
NS_RELEASE(newAppRunner);
return rv;
}
nsresult
nsAppRunnerFactory::LockFactory(PRBool aLock)
{
// Not implemented in simplest case.
return NS_OK;
}
extern "C" NS_EXPORT nsresult
NSGetFactory(const nsCID &cid, nsISupports* servMgr, nsIFactory** aFactory ) {
nsresult rv = NS_OK;
if ( aFactory == 0 ) {
return NS_ERROR_NULL_POINTER;
} else {
*aFactory = 0;
}
nsIFactory* inst = new nsAppRunnerFactory();
if (0 == inst) {
rv = NS_ERROR_OUT_OF_MEMORY;
} else {
NS_ADDREF(inst);
*aFactory = inst;
}
return rv;
}
#endif