Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Enumerations | Functions | Variables
xpcshell.cpp File Reference
#include <stdio.h>
#include "nsIXPConnect.h"
#include "nsIXPCScriptable.h"
#include "nsIInterfaceInfo.h"
#include "nsIInterfaceInfoManager.h"
#include "nsIServiceManager.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "jsapi.h"
#include "jsprf.h"
#include "nscore.h"
#include "nsMemory.h"
#include "nsIGenericFactory.h"
#include "nsIJSRuntimeService.h"
#include "nsCOMPtr.h"
#include "nsIXPCSecurityManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIPrincipal.h"
#include <stdlib.h>
#include <errno.h>
#include "nsIJSContextStack.h"
#include "jscntxt.h"
#include "jsshell.msg"

Go to the source code of this file.

Classes

class  FullTrustSecMan

Defines

#define DoBeginRequest(cx)   ((void)0)
#define DoEndRequest(cx)   ((void)0)
#define EXITCODE_RUNTIME_ERROR   3
#define EXITCODE_FILE_NOT_FOUND   4
#define MSG_DEF(name, number, count, exception, format)   name = number,
#define MSG_DEF(name, number, count, exception, format)   { NULL, count } ,

Typedefs

typedef enum JSShellErrNum JSShellErrNum

Enumerations

enum  JSShellErrNum { JSShellErr_Limit, JSShellErr_Limit }

Functions

 my_ErrorReporter (JSContext *cx, const char *message, JSErrorReport *report)
 Print (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Dump (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Load (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Version (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 BuildDate (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Quit (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 DumpXPC (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 GC (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 Clear (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
static JSBool env_setProperty (JSContext *cx, JSObject *obj, jsval id, jsval *vp)
static JSBool env_enumerate (JSContext *cx, JSObject *obj)
static JSBool env_resolve (JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)
 my_GetErrorMessage (void *userRef, const char *locale, const uintN errorNumber)
static JSBool GetLine (JSContext *cx, char *bufp, FILE *file, const char *prompt)
static void ProcessFile (JSContext *cx, JSObject *obj, const char *filename, FILE *file)
static void Process (JSContext *cx, JSObject *obj, const char *filename)
static int usage (void)
static int ProcessArgs (JSContext *cx, JSObject *obj, char **argv, int argc)
int main (int argc, char **argv, char **envp)

Variables

FILEgOutFile = NULL
FILEgErrFile = NULL
int gExitCode = 0
JSBool gQuitting = JS_FALSE
static JSBool reportWarnings = JS_TRUE
static JSBool compileOnly = JS_FALSE
JSPrincipalsgJSPrincipals = nsnull
static JSFunctionSpec glob_functions []
JSClass global_class
static JSClass env_class
JSErrorFormatString jsShell_ErrorFormatString [JSErr_Limit]

Define Documentation

#define DoBeginRequest (   cx)    ((void)0)

Definition at line 86 of file xpcshell.cpp.

#define DoEndRequest (   cx)    ((void)0)

Definition at line 87 of file xpcshell.cpp.

Definition at line 93 of file xpcshell.cpp.

Definition at line 92 of file xpcshell.cpp.

#define MSG_DEF (   name,
  number,
  count,
  exception,
  format 
)    name = number,

Definition at line 487 of file xpcshell.cpp.

#define MSG_DEF (   name,
  number,
  count,
  exception,
  format 
)    { NULL, count } ,

Definition at line 487 of file xpcshell.cpp.


Typedef Documentation


Enumeration Type Documentation

Enumerator:
JSShellErr_Limit 
JSShellErr_Limit 

Definition at line 486 of file xpcshell.cpp.

                           {
#define MSG_DEF(name, number, count, exception, format) \
    name = number,
#include "jsshell.msg"
#undef MSG_DEF
    JSShellErr_Limit
#undef MSGDEF
} JSShellErrNum;

Function Documentation

BuildDate ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 254 of file xpcshell.cpp.

{
    fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__);
    return JS_TRUE;
}

Here is the call graph for this function:

Clear ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 340 of file xpcshell.cpp.

{
    if (argc > 0 && !JSVAL_IS_PRIMITIVE(argv[0])) {
        JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
    } else {
        JS_ReportError(cx, "'clear' requires an object");
        return JS_FALSE;
    }    
    return JS_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Dump ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 191 of file xpcshell.cpp.

{
    JSString *str;
    if (!argc)
        return JS_TRUE;
    
    str = JS_ValueToString(cx, argv[0]);
    if (!str)
        return JS_FALSE;

    char *bytes = JS_GetStringBytes(str);
    bytes = strdup(bytes);

    fputs(bytes, gOutFile);
    free(bytes);
    return JS_TRUE;
}

Here is the call graph for this function:

DumpXPC ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 276 of file xpcshell.cpp.

{
    int32 depth = 2;

    if (argc > 0) {
        if (!JS_ValueToInt32(cx, argv[0], &depth))
            return JS_FALSE;
    }

    nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
    if(xpc)
        xpc->DebugDump((int16)depth);
    return JS_TRUE;
}

Here is the call graph for this function:

static JSBool env_enumerate ( JSContext cx,
JSObject obj 
) [static]

Definition at line 417 of file xpcshell.cpp.

{
    static JSBool reflected;
    char **evp, *name, *value;
    JSString *valstr;
    JSBool ok;

    if (reflected)
        return JS_TRUE;

    for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) {
        value = strchr(name, '=');
        if (!value)
            continue;
        *value++ = '\0';
        valstr = JS_NewStringCopyZ(cx, value);
        if (!valstr) {
            ok = JS_FALSE;
        } else {
            ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
                                   NULL, NULL, JSPROP_ENUMERATE);
        }
        value[-1] = '=';
        if (!ok)
            return JS_FALSE;
    }

    reflected = JS_TRUE;
    return JS_TRUE;
}

Here is the call graph for this function:

static JSBool env_resolve ( JSContext cx,
JSObject obj,
jsval  id,
uintN  flags,
JSObject **  objp 
) [static]

Definition at line 449 of file xpcshell.cpp.

{
    JSString *idstr, *valstr;
    const char *name, *value;

    if (flags & JSRESOLVE_ASSIGNING)
        return JS_TRUE;

    idstr = JS_ValueToString(cx, id);
    if (!idstr)
        return JS_FALSE;
    name = JS_GetStringBytes(idstr);
    value = getenv(name);
    if (value) {
        valstr = JS_NewStringCopyZ(cx, value);
        if (!valstr)
            return JS_FALSE;
        if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr),
                               NULL, NULL, JSPROP_ENUMERATE)) {
            return JS_FALSE;
        }
        *objp = obj;
    }
    return JS_TRUE;
}

Here is the call graph for this function:

static JSBool env_setProperty ( JSContext cx,
JSObject obj,
jsval  id,
jsval vp 
) [static]

Definition at line 371 of file xpcshell.cpp.

{
/* XXX porting may be easy, but these don't seem to supply setenv by default */
#if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS
    JSString *idstr, *valstr;
    const char *name, *value;
    int rv;

    idstr = JS_ValueToString(cx, id);
    valstr = JS_ValueToString(cx, *vp);
    if (!idstr || !valstr)
        return JS_FALSE;
    name = JS_GetStringBytes(idstr);
    value = JS_GetStringBytes(valstr);
#if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX
    {
        char *waste = JS_smprintf("%s=%s", name, value);
        if (!waste) {
            JS_ReportOutOfMemory(cx);
            return JS_FALSE;
        }
        rv = putenv(waste);
#ifdef XP_WIN
        /*
         * HPUX9 at least still has the bad old non-copying putenv.
         *
         * Per mail from <s.shanmuganathan@digital.com>, OSF1 also has a putenv
         * that will crash if you pass it an auto char array (so it must place
         * its argument directly in the char *environ[] array).
         */
        free(waste);
#endif
    }
#else
    rv = setenv(name, value, 1);
#endif
    if (rv < 0) {
        JS_ReportError(cx, "can't set envariable %s to %s", name, value);
        return JS_FALSE;
    }
    *vp = STRING_TO_JSVAL(valstr);
#endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */
    return JS_TRUE;
}

Here is the call graph for this function:

GC ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 299 of file xpcshell.cpp.

{
    JSRuntime *rt;
    uint32 preBytes;

    rt = cx->runtime;
    preBytes = rt->gcBytes;
#ifdef GC_MARK_DEBUG
    if (argc && JSVAL_IS_STRING(argv[0])) {
        char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
        FILE *file = fopen(name, "w");
        if (!file) {
            fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno));
            return JS_FALSE;
        }
        js_DumpGCHeap = file;
    } else {
        js_DumpGCHeap = stdout;
    }
#endif
    JS_GC(cx);
#ifdef GC_MARK_DEBUG
    if (js_DumpGCHeap != stdout)
        fclose(js_DumpGCHeap);
    js_DumpGCHeap = NULL;
#endif
    fprintf(gOutFile, "before %lu, after %lu, break %08lx\n",
           (unsigned long)preBytes, (unsigned long)rt->gcBytes,
#ifdef XP_UNIX
           (unsigned long)sbrk(0)
#else
           0
#endif
           );
#ifdef JS_GCMETER
    js_DumpGCStats(rt, stdout);
#endif
    return JS_TRUE;
}

Here is the call graph for this function:

static JSBool GetLine ( JSContext cx,
char *  bufp,
FILE file,
const char *  prompt 
) [static]

Definition at line 524 of file xpcshell.cpp.

                                                                   {
#ifdef EDITLINE
    /*
     * Use readline only if file is stdin, because there's no way to specify
     * another handle.  Are other filehandles interactive?
     */
    if (file == stdin) {
        char *linep = readline(prompt);
        if (!linep)
            return JS_FALSE;
        if (*linep)
            add_history(linep);
        strcpy(bufp, linep);
        JS_free(cx, linep);
        bufp += strlen(bufp);
        *bufp++ = '\n';
        *bufp = '\0';
    } else
#endif
    {
        char line[256];
        fprintf(gOutFile, prompt);
        fflush(gOutFile);
        if (!fgets(line, sizeof line, file))
            return JS_FALSE;
        strcpy(bufp, line);
    }
    return JS_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Load ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 210 of file xpcshell.cpp.

{
    uintN i;
    JSString *str;
    const char *filename;
    JSScript *script;
    JSBool ok;
    jsval result;
    FILE *file;

    for (i = 0; i < argc; i++) {
        str = JS_ValueToString(cx, argv[i]);
        if (!str)
            return JS_FALSE;
        argv[i] = STRING_TO_JSVAL(str);
        filename = JS_GetStringBytes(str);
        file = fopen(filename, "r");
        script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
                                                   gJSPrincipals);
        if (!script)
            ok = JS_FALSE;
        else {
            ok = !compileOnly
                 ? JS_ExecuteScript(cx, obj, script, &result)
                 : JS_TRUE;
            JS_DestroyScript(cx, script);
        }
        if (!ok)
            return JS_FALSE;
    }
    return JS_TRUE;
}

Here is the call graph for this function:

int main ( int  argc,
char **  argv,
char **  envp 
)

Definition at line 963 of file xpcshell.cpp.

{
    JSRuntime *rt;
    JSContext *cx;
    JSObject *glob, *envobj;
    int result;
    nsresult rv;

    gErrFile = stderr;
    gOutFile = stdout;
    {
        nsCOMPtr<nsIServiceManager> servMan;
        rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
        if (NS_FAILED(rv)) {
            printf("NS_InitXPCOM failed!\n");
            return 1;
        }
        {
            nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
            NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
            if (registrar)
                registrar->AutoRegister(nsnull);
        }

        nsCOMPtr<nsIJSRuntimeService> rtsvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
        // get the JSRuntime from the runtime svc
        if (!rtsvc) {
            printf("failed to get nsJSRuntimeService!\n");
            return 1;
        }
    
        if (NS_FAILED(rtsvc->GetRuntime(&rt)) || !rt) {
            printf("failed to get JSRuntime from nsJSRuntimeService!\n");
            return 1;
        }

        cx = JS_NewContext(rt, 8192);
        if (!cx) {
            printf("JS_NewContext failed!\n");
            return 1;
        }

        JS_SetErrorReporter(cx, my_ErrorReporter);

        nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
        if (!xpc) {
            printf("failed to get nsXPConnect service!\n");
            return 1;
        }

        // Since the caps security system might set a default security manager
        // we will be sure that the secman on this context gives full trust.
        // That way we can avoid getting principals from the caps security manager
        // just to shut it up. Also, note that even though our secman will allow
        // anything, we set the flags to '0' so it ought never get called anyway.
        nsCOMPtr<nsIXPCSecurityManager> secman =
            NS_STATIC_CAST(nsIXPCSecurityManager*, new FullTrustSecMan());
        xpc->SetSecurityManagerForJSContext(cx, secman, 0);

        //    xpc->SetCollectGarbageOnMainThreadOnly(PR_TRUE);
        //    xpc->SetDeferReleasesUntilAfterGarbageCollection(PR_TRUE);

#ifndef XPCONNECT_STANDALONE
        // Fetch the system principal and store it away in a global, to use for
        // script compilation in Load() and ProcessFile() (including interactive
        // eval loop)
        {
            nsCOMPtr<nsIPrincipal> princ;

            nsCOMPtr<nsIScriptSecurityManager> securityManager =
                do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
            if (NS_SUCCEEDED(rv) && securityManager) {
                rv = securityManager->GetSystemPrincipal(getter_AddRefs(princ));
                if (NS_FAILED(rv)) {
                    fprintf(gErrFile, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n");
                } else {
                    // fetch the JS principals and stick in a global
                    rv = princ->GetJSPrincipals(cx, &gJSPrincipals);
                    if (NS_FAILED(rv)) {
                        fprintf(gErrFile, "+++ Failed to obtain JS principals from SystemPrincipal.\n");
                    }
                }
            } else {
                fprintf(gErrFile, "+++ Failed to get ScriptSecurityManager service, running without principals");
            }
        }
#endif

#ifdef TEST_TranslateThis
        nsCOMPtr<nsIXPCFunctionThisTranslator>
            translator(new nsXPCFunctionThisTranslator);
        xpc->SetFunctionThisTranslator(NS_GET_IID(nsITestXPCFunctionCallback), translator, nsnull);
#endif
    
        nsCOMPtr<nsIJSContextStack> cxstack = do_GetService("@mozilla.org/js/xpc/ContextStack;1");
        if (!cxstack) {
            printf("failed to get the nsThreadJSContextStack service!\n");
            return 1;
        }

        if(NS_FAILED(cxstack->Push(cx))) {
            printf("failed to push the current JSContext on the nsThreadJSContextStack!\n");
            return 1;
        }

        nsCOMPtr<nsIXPCScriptable> backstagePass;
        nsresult rv = rtsvc->GetBackstagePass(getter_AddRefs(backstagePass));
        if (NS_FAILED(rv)) {
            fprintf(gErrFile, "+++ Failed to get backstage pass from rtsvc: %8x\n",
                    rv);
            return 1;
        }

        nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
        rv = xpc->InitClassesWithNewWrappedGlobal(cx, backstagePass,
                                                  NS_GET_IID(nsISupports),
                                                  nsIXPConnect::
                                                      FLAG_SYSTEM_GLOBAL_OBJECT,
                                                  getter_AddRefs(holder));
        if (NS_FAILED(rv))
            return 1;
        
        rv = holder->GetJSObject(&glob);
        if (NS_FAILED(rv)) {
            NS_ASSERTION(glob == nsnull, "bad GetJSObject?");
            return 1;
        }
        if (!JS_DefineFunctions(cx, glob, glob_functions))
            return 1;

        envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0);
        if (!envobj || !JS_SetPrivate(cx, envobj, envp))
            return 1;

        argc--;
        argv++;

        result = ProcessArgs(cx, glob, argv, argc);


//#define TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN 1

#ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
        // test of late call and release (see below)
        nsCOMPtr<nsIJSContextStack> bogus;
        xpc->WrapJS(cx, glob, NS_GET_IID(nsIJSContextStack),
                    (void**) getter_AddRefs(bogus));
#endif

        JS_ClearScope(cx, glob);
        JS_GC(cx);
        JSContext *oldcx;
        cxstack->Pop(&oldcx);
        NS_ASSERTION(oldcx == cx, "JS thread context push/pop mismatch");
        cxstack = nsnull;
        JS_GC(cx);
        JS_DestroyContext(cx);
        xpc->SyncJSContexts();
    } // this scopes the nsCOMPtrs
    // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
    rv = NS_ShutdownXPCOM( NULL );
    NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");

#ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
    // test of late call and release (see above)
    JSContext* bogusCX;
    bogus->Peek(&bogusCX);
    bogus = nsnull;
#endif

    return result;
}

Here is the call graph for this function:

my_ErrorReporter ( JSContext cx,
const char *  message,
JSErrorReport report 
)

Definition at line 106 of file xpcshell.cpp.

{
    int i, j, k, n;
    char *prefix = NULL, *tmp;
    const char *ctmp;

    if (!report) {
        fprintf(gErrFile, "%s\n", message);
        return;
    }

    /* Conditionally ignore reported warnings. */
    if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings)
        return;

    if (report->filename)
        prefix = JS_smprintf("%s:", report->filename);
    if (report->lineno) {
        tmp = prefix;
        prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
        JS_free(cx, tmp);
    }
    if (JSREPORT_IS_WARNING(report->flags)) {
        tmp = prefix;
        prefix = JS_smprintf("%s%swarning: ",
                             tmp ? tmp : "",
                             JSREPORT_IS_STRICT(report->flags) ? "strict " : "");
        JS_free(cx, tmp);
    }

    /* embedded newlines -- argh! */
    while ((ctmp = strchr(message, '\n')) != 0) {
        ctmp++;
        if (prefix) fputs(prefix, gErrFile);
        fwrite(message, 1, ctmp - message, gErrFile);
        message = ctmp;
    }
    /* If there were no filename or lineno, the prefix might be empty */
    if (prefix)
        fputs(prefix, gErrFile);
    fputs(message, gErrFile);

    if (!report->linebuf) {
        fputc('\n', gErrFile);
        goto out;
    }

    fprintf(gErrFile, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
    n = report->tokenptr - report->linebuf;
    for (i = j = 0; i < n; i++) {
        if (report->linebuf[i] == '\t') {
            for (k = (j + 8) & ~7; j < k; j++) {
                fputc('.', gErrFile);
            }
            continue;
        }
        fputc('.', gErrFile);
        j++;
    }
    fputs("^\n", gErrFile);
 out:
    if (!JSREPORT_IS_WARNING(report->flags))
        gExitCode = EXITCODE_RUNTIME_ERROR;
    JS_free(cx, prefix);
}

Here is the call graph for this function:

my_GetErrorMessage ( void userRef,
const char *  locale,
const uintN  errorNumber 
)

Definition at line 508 of file xpcshell.cpp.

Here is the caller graph for this function:

Print ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 173 of file xpcshell.cpp.

{
    uintN i, n;
    JSString *str;

    for (i = n = 0; i < argc; i++) {
        str = JS_ValueToString(cx, argv[i]);
        if (!str)
            return JS_FALSE;
        fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str));
    }
    n++;
    if (n)
        fputc('\n', gOutFile);
    return JS_TRUE;
}

Here is the call graph for this function:

static void Process ( JSContext cx,
JSObject obj,
const char *  filename 
) [static]

Definition at line 664 of file xpcshell.cpp.

{
    FILE *file;

    if (!filename || strcmp(filename, "-") == 0) {
        file = stdin;
    } else {
        file = fopen(filename, "r");
        if (!file) {
            JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
                                 JSSMSG_CANT_OPEN,
                                 filename, strerror(errno));
            gExitCode = EXITCODE_FILE_NOT_FOUND;
            return;
        }
    }

    ProcessFile(cx, obj, filename, file);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int ProcessArgs ( JSContext cx,
JSObject obj,
char **  argv,
int  argc 
) [static]

Definition at line 695 of file xpcshell.cpp.

{
    const char rcfilename[] = "xpcshell.js";
    FILE *rcfile;
    int i, j, length;
    JSObject *argsObj;
    char *filename = NULL;
    JSBool isInteractive = JS_TRUE;

    rcfile = fopen(rcfilename, "r");
    if (rcfile) {
        printf("[loading '%s'...]\n", rcfilename);
        ProcessFile(cx, obj, rcfilename, rcfile);
    }

    /*
     * Scan past all optional arguments so we can create the arguments object
     * before processing any -f options, which must interleave properly with
     * -v and -w options.  This requires two passes, and without getopt, we'll
     * have to keep the option logic here and in the second for loop in sync.
     */
    for (i = 0; i < argc; i++) {
        if (argv[i][0] != '-' || argv[i][1] == '\0') {
            ++i;
            break;
        }
        switch (argv[i][1]) {
          case 'v':
          case 'f':
          case 'e':
            ++i;
            break;
          default:;
        }
    }

    /*
     * Create arguments early and define it to root it, so it's safe from any
     * GC calls nested below, and so it is available to -f <file> arguments.
     */
    argsObj = JS_NewArrayObject(cx, 0, NULL);
    if (!argsObj)
        return 1;
    if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj),
                           NULL, NULL, 0)) {
        return 1;
    }

    length = argc - i;
    for (j = 0; j < length; j++) {
        JSString *str = JS_NewStringCopyZ(cx, argv[i++]);
        if (!str)
            return 1;
        if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str),
                              NULL, NULL, JSPROP_ENUMERATE)) {
            return 1;
        }
    }

    for (i = 0; i < argc; i++) {
        if (argv[i][0] != '-' || argv[i][1] == '\0') {
            filename = argv[i++];
            isInteractive = JS_FALSE;
            break;
        }
        switch (argv[i][1]) {
        case 'v':
            if (++i == argc) {
                return usage();
            }
            JS_SetVersion(cx, JSVersion(atoi(argv[i])));
            break;
        case 'W':
            reportWarnings = JS_FALSE;
            break;
        case 'w':
            reportWarnings = JS_TRUE;
            break;
        case 's':
            JS_ToggleOptions(cx, JSOPTION_STRICT);
            break;
        case 'x':
            JS_ToggleOptions(cx, JSOPTION_XML);
            break;
        case 'P':
            if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
                JSObject *gobj;

                if (!JS_SealObject(cx, obj, JS_TRUE))
                    return JS_FALSE;
                gobj = JS_NewObject(cx, &global_class, NULL, NULL);
                if (!gobj)
                    return JS_FALSE;
                if (!JS_SetPrototype(cx, gobj, obj))
                    return JS_FALSE;
                JS_SetParent(cx, gobj, NULL);
                JS_SetGlobalObject(cx, gobj);
                obj = gobj;
            }
            break;
        case 'f':
            if (++i == argc) {
                return usage();
            }
            Process(cx, obj, argv[i]);
            /*
             * XXX: js -f foo.js should interpret foo.js and then
             * drop into interactive mode, but that breaks test
             * harness. Just execute foo.js for now.
             */
            isInteractive = JS_FALSE;
            break;

        case 'e':
        {
            jsval rval;

            if (++i == argc) {
                return usage();
            }

            JS_EvaluateScript(cx, obj, argv[i], strlen(argv[i]), 
                              "-e", 1, &rval);

            isInteractive = JS_FALSE;
            break;
        }
        case 'C':
            compileOnly = JS_TRUE;
            isInteractive = JS_FALSE;
            break;

        default:
            return usage();
        }
    }

    if (filename || isInteractive)
        Process(cx, obj, filename);
    return gExitCode;
}

Here is the call graph for this function:

static void ProcessFile ( JSContext cx,
JSObject obj,
const char *  filename,
FILE file 
) [static]

Definition at line 555 of file xpcshell.cpp.

{
    JSScript *script;
    jsval result;
    int lineno, startline;
    JSBool ok, hitEOF;
    char *bufp, buffer[4096];
    JSString *str;

    if (!isatty(fileno(file))) {
        /*
         * It's not interactive - just execute it.
         *
         * Support the UNIX #! shell hack; gobble the first line if it starts
         * with '#'.  TODO - this isn't quite compatible with sharp variables,
         * as a legal js program (using sharp variables) might start with '#'.
         * But that would require multi-character lookahead.
         */
        int ch = fgetc(file);
        if (ch == '#') {
            while((ch = fgetc(file)) != EOF) {
                if(ch == '\n' || ch == '\r')
                    break;
            }
        }
        ungetc(ch, file);
        DoBeginRequest(cx);

        script = JS_CompileFileHandleForPrincipals(cx, obj, filename, file,
                                                   gJSPrincipals);

        if (script) {
            if (!compileOnly)
                (void)JS_ExecuteScript(cx, obj, script, &result);
            JS_DestroyScript(cx, script);
        }
        DoEndRequest(cx);
        return;
    }

    /* It's an interactive filehandle; drop into read-eval-print loop. */
    lineno = 1;
    hitEOF = JS_FALSE;
    do {
        bufp = buffer;
        *bufp = '\0';

        /*
         * Accumulate lines until we get a 'compilable unit' - one that either
         * generates an error (before running out of source) or that compiles
         * cleanly.  This should be whenever we get a complete statement that
         * coincides with the end of a line.
         */
        startline = lineno;
        do {
            if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) {
                hitEOF = JS_TRUE;
                break;
            }
            bufp += strlen(bufp);
            lineno++;
        } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer)));
        
        DoBeginRequest(cx);
        /* Clear any pending exception from previous failed compiles.  */
        JS_ClearPendingException(cx);
        script = JS_CompileScriptForPrincipals(cx, obj, gJSPrincipals, buffer,
                                               strlen(buffer), "typein", startline);
        if (script) {
            JSErrorReporter older;

            if (!compileOnly) {
                ok = JS_ExecuteScript(cx, obj, script, &result);
                if (ok && result != JSVAL_VOID) {
                    /* Suppress error reports from JS_ValueToString(). */
                    older = JS_SetErrorReporter(cx, NULL);
                    str = JS_ValueToString(cx, result);
                    JS_SetErrorReporter(cx, older);
    
                    if (str)
                        fprintf(gOutFile, "%s\n", JS_GetStringBytes(str));
                    else
                        ok = JS_FALSE;
                }
#if 0
#if JS_HAS_ERROR_EXCEPTIONS
                /*
                 * Require that any time we return failure, an exception has
                 * been set.
                 */
                JS_ASSERT(ok || JS_IsExceptionPending(cx));
    
                /*
                 * Also that any time an exception has been set, we've
                 * returned failure.
                 */
                JS_ASSERT(!JS_IsExceptionPending(cx) || !ok);
#endif /* JS_HAS_ERROR_EXCEPTIONS */
#endif
            }
            JS_DestroyScript(cx, script);
        }
        DoEndRequest(cx);
    } while (!hitEOF && !gQuitting);
    fprintf(gOutFile, "\n");
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Quit ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 261 of file xpcshell.cpp.

{
#ifdef LIVECONNECT
    JSJ_SimpleShutdown();
#endif

    gExitCode = 0;
    JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode);

    gQuitting = JS_TRUE;
//    exit(0);
    return JS_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int usage ( void  ) [static]

Definition at line 685 of file xpcshell.cpp.

{
    fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
    fprintf(gErrFile, "usage: xpcshell [-PswWxC] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
    return 2;
}

Here is the call graph for this function:

Version ( JSContext cx,
JSObject obj,
uintN  argc,
jsval argv,
jsval rval 
)

Definition at line 244 of file xpcshell.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 101 of file xpcshell.cpp.

JSClass env_class [static]

Definition at line 96 of file xpcshell.cpp.

Definition at line 98 of file xpcshell.cpp.

Definition at line 103 of file xpcshell.cpp.

Initial value:
 {
    {"print",           Print,          0},
    {"load",            Load,           1},
    {"quit",            Quit,           0},
    {"version",         Version,        1},
    {"build",           BuildDate,      0},
    {"dumpXPC",         DumpXPC,        1},
    {"dump",            Dump,           1},
    {"gc",              GC,             0},
    {"clear",           Clear,          1},
    {0}
}

Definition at line 351 of file xpcshell.cpp.

Definition at line 95 of file xpcshell.cpp.

Definition at line 99 of file xpcshell.cpp.

Initial value:
 {




#define MSG_DEF(name, number, count, exception, format) 















}

Definition at line 495 of file xpcshell.cpp.

Definition at line 100 of file xpcshell.cpp.