static int ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) { const char rcfilename[] = "xpcshell.js"; FILE *rcfile; int i, j, length; JSObject *argsObj; char *filename = NULL; JSBool isInteractive = JS_TRUE; JSBool forceTTY = JS_FALSE; rcfile = fopen(rcfilename, "r"); if (rcfile) { printf("[loading '%s'...]\n", rcfilename); ProcessFile(cx, obj, rcfilename, rcfile, JS_FALSE); } /* * 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], JS_FALSE); /* * 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 'i': isInteractive = forceTTY = JS_TRUE; 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; #ifdef MOZ_SHARK case 'k': JS_ConnectShark(); break; #endif default: return usage(); } } if (filename || isInteractive) Process(cx, obj, filename, forceTTY); return gExitCode; }
static int ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) { int i, j, length; JSObject *argsObj; char *filename = NULL; JSBool isInteractive = JS_TRUE; JSBool forceTTY = JS_FALSE; /* * 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 'b': case 'c': case 'f': case 'e': case 'v': case 'S': ++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_TRUE; break; case 'W': reportWarnings = JS_FALSE; break; case 's': JS_ToggleOptions(cx, JSOPTION_STRICT); break; case 'E': JS_ToggleOptions(cx, JSOPTION_RELIMIT); break; case 'x': JS_ToggleOptions(cx, JSOPTION_XML); break; case 'o': if (++i == argc) return usage(); for (j = 0; js_options[j].name; ++j) { if (strcmp(js_options[j].name, argv[i]) == 0) { JS_ToggleOptions(cx, js_options[j].flag); break; } } break; case 'c': /* set stack chunk size */ gStackChunkSize = atoi(argv[++i]); break; case 'f': if (++i == argc) return usage(); Process(cx, obj, argv[i], JS_FALSE); /* * XXX: js -f foo.js should interpret foo.js and then * drop into interactive mode, but that breaks the test * harness. Just execute foo.js for now. */ isInteractive = JS_FALSE; break; case 'e': { jsval rval; if (++i == argc) return usage(); /* Pass a filename of -e to imitate PERL */ JS_EvaluateScript(cx, obj, argv[i], SG_STRLEN(argv[i]), "-e", 1, &rval); isInteractive = JS_FALSE; break; } case 'C': compileOnly = JS_TRUE; isInteractive = JS_FALSE; break; case 'i': isInteractive = forceTTY = JS_TRUE; break; case 'S': if (++i == argc) return usage(); /* Set maximum stack size. */ gMaxStackSize = atoi(argv[i]); break; #ifdef MOZ_SHARK case 'k': JS_ConnectShark(); break; #endif default: return usage(); } } if (filename || isInteractive) Process(cx, obj, filename, forceTTY); return gExitCode; }