RPM Package Manager, CVS Repository
/cvs/
____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson
Root: /v/rpm/cvs Email: jbj@rpm5.org
Module: rpm Date: 12-Sep-2010 17:23:06
Branch: HEAD Handle: 2010091215230600
Modified files:
rpm/js ngsr.c
Log:
- gpsee: WIP.
Summary:
Revision Changes Path
1.4 +68 -313 rpm/js/ngsr.c
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: rpm/js/ngsr.c
============================================================================
$ cvs diff -u -r1.3 -r1.4 ngsr.c
--- rpm/js/ngsr.c 12 Sep 2010 14:32:57 -0000 1.3
+++ rpm/js/ngsr.c 12 Sep 2010 15:23:06 -0000 1.4
@@ -37,7 +37,7 @@
* @file gsr.c GPSEE Script Runner ("scripting host")
* @author Wes Garland
* @date Aug 27 2007
- * @version $Id: ngsr.c,v 1.3 2010/09/12 14:32:57 jbj Exp $
+ * @version $Id: ngsr.c,v 1.4 2010/09/12 15:23:06 jbj Exp $
*
* This program is designed to interpret a JavaScript program as much like
* a shell script as possible.
@@ -55,7 +55,7 @@
*/
static __attribute__ ((unused))
-const char rcsid[] = "$Id: ngsr.c,v 1.3 2010/09/12 14:32:57 jbj Exp $";
+const char rcsid[] = "$Id: ngsr.c,v 1.4 2010/09/12 15:23:06 jbj Exp $";
#include "system.h"
@@ -104,6 +104,10 @@
RPMGSR_FLAGS_NONE = 0,
RPMGSR_FLAGS_NOEXEC = _DFB(0), /*!< -n */
RPMGSR_FLAGS_SKIPSHEBANG = _DFB(1), /*!< -F */
+ RPMGSR_FLAGS_LOADRC = _DFB(2), /*!< -R */
+ RPMGSR_FLAGS_NOUTF8 = _DFB(3), /*!< -U */
+ RPMGSR_FLAGS_NOCACHE = _DFB(4), /*!< -C */
+ RPMGSR_FLAGS_NOWARN = _DFB(5), /*!< -W */
};
/**
@@ -121,7 +125,7 @@
const char * code; /* String with JavaScript program in it */
const char * fn; /* Filename with JavaScript program in it */
- char *const *argv; /* Becomes arguments array in JS program */
+ ARGV_t argv; /* Becomes arguments array in JS program */
char *const *environ; /* Environment to pass to script */
int verbosity; /* 0 = no debug, bigger = more debug */
@@ -210,24 +214,38 @@
#endif
break;
case 'a':
+#if defined(GPSEE_DARWIN_SYSTEM)
+ gsr->environ = (char *const *) _NSGetEnviron();
+#else
+ gsr->environ = (char *const *) environ;
+#endif
break;
case 'C':
+ gsr->flags |= RPMGSR_FLAGS_NOCACHE;
break;
case 'd':
+ gsr->verbosity++;
break;
case 'e':
+ gsr->options &= ~JSOPTION_RELIMIT;
break;
case 'J':
+ gsr->options &= ~JSOPTION_JIT;
break;
case 'S':
+ gsr->options &= ~JSOPTION_STRICT;
break;
case 'R':
+ gsr->flags |= RPMGSR_FLAGS_LOADRC;
break;
case 'U':
+ gsr->flags |= RPMGSR_FLAGS_NOUTF8;
break;
case 'W':
+ gsr->flags |= RPMGSR_FLAGS_NOWARN;
break;
case 'x':
+ gsr->options |= JSOPTION_XML;
break;
case 'z':
gsr->gcZeal++;
@@ -328,102 +346,16 @@
#ifdef NOTYET
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
N_("Common options for all rpmio executables:"), NULL },
+#endif
POPT_AUTOALIAS
-#endif
POPT_AUTOHELP
-
- { NULL, -1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
- N_("\
-" PRODUCT_SHORTNAME " " PRODUCT_VERSION " - GPSEE Script Runner for GPSEE " GPSEE_CURRENT_VERSION_STRING "\n\
-Copyright (c) 2007-2009 PageMail, Inc. All Rights Reserved.\n\
-\n\
-As an interpreter: #! gsr {-/*flags*/}\n\
-As a command: gsr {-r file} [-D file] [-z #] [-n] <[-c code]|[-f filename]>\n\
- gsr {-/*flags*/} {[--] [arg...]}\n\
-Command Options:\n\
- -c code Specifies literal JavaScript code to execute\n\
- -f filename Specifies the filename containing code to run\n\
- -F filename Like -f, but skip shebang if present.\n\
- -h Display this help\n\
- -n Engine will load and parse, but not run, the script\n\
- -D file Specifies a debug output file\n\
- -r file Specifies alternate interpreter RC file\n\
- flags A series of one-character flags which can be used\n\
- in either file interpreter or command mode\n\
- -- Arguments after -- are passed to the script\n\
-\n\
-Valid Flags:\n\
- a - Allow (read-only) access to caller's environment\n\
- C - Disables compiler caching via JSScript XDR serialization\n\
- d - Increase verbosity\n\
- e - Do not limit regexps to n^3 levels of backtracking\n\
- J - Disable nanojit\n\
- S - Disable Strict mode\n\
- R - Load RC file for interpreter (" PRODUCT_SHORTNAME ") based on\n\
- script filename.\n\
- U - Disable UTF-8 C string processing\n\
- W - Do not report warnings\n\
- x - Parse <!-- comments --> as E4X tokens\n\
- z - Increase GC Zealousness\n\
-"), NULL },
-
POPT_TABLEEND
};
static struct poptOption *optionsTable = &_optionsTable[0];
/*==============================================================*/
-/** Help text for this program, which doubles as the "official"
- * documentation for the command-line parameters.
- *
- * @param argv_zero How this program was invoked.
- *
- * @note Exits with status 1
- */
-static void __attribute__ ((noreturn)) usage(const char *argv_zero)
-{
- char spaces[strlen(argv_zero) + 1];
-
- memset(spaces, (int) (' '), sizeof(spaces) - 1);
- spaces[sizeof(spaces) - 1] = '\0';
-
- printf("\n"
- PRODUCT_SHORTNAME " " PRODUCT_VERSION " - " PRODUCT_SUMMARY " "
- GPSEE_CURRENT_VERSION_STRING "\n"
- "Copyright (c) 2007-2010 PageMail, Inc. All Rights Reserved.\n"
- "\n" "As an interpreter: #! %s {-/*flags*/}\n"
- "As a command: %s "
- "[-z #] [-n] <[-c code] [-f filename]>\n"
- " %s {-/*flags*/} {[--] [arg...]}\n"
- "Command Options:\n"
- " -c code Specifies literal JavaScript code to execute (runs before -f)\n"
- " -f filename Specifies the filename containing code to run\n"
- " -F filename Like -f, but skip shebang if present.\n"
- " -h Display this help\n"
- " -H Display more help\n"
- " -n Engine will load and parse, but not run, the script\n"
- " flags A series of one-character flags which can be used\n"
- " in either file interpreter or command mode\n"
- " -- Arguments after -- are passed to the script\n"
- "\n"
- "Valid Flags:\n"
- " a - Allow (read-only) access to caller's environment\n"
- " C - Disables compiler caching via JSScript XDR serialization\n"
- " d - Increase verbosity\n"
- " e - Do not limit regexps to n^3 levels of backtracking\n"
- " J - Disable nanojit\n"
- " S - Disable Strict mode\n"
- " R - Load RC file for interpreter (" PRODUCT_SHORTNAME
- ") based on\n" " script filename.\n"
- " U - Disable UTF-8 C string processing\n"
- " W - Do not report warnings\n"
- " x - Parse <!-- comments --> as E4X tokens\n"
- " z - Increase GC Zealousness\n" "\n", argv_zero, argv_zero,
- spaces);
- exit(1);
-}
-
/** More help text for this program, which doubles as the "official"
* documentation for the more subtle behaviours of this embedding.
@@ -483,86 +415,7 @@
exit(1);
};
-/** Process the script interpreter flags.
- *
- * @param flags An array of flags, in no particular order.
- */
-static void processFlags(rpmgsr gsr, const char *flags,
- signed int *verbosity_p)
-{
- JSContext * cx = gsr->I->cx;
- int gcZeal = 0;
- int jsOptions;
- const char *f;
- gpsee_runtime_t *grt = JS_GetRuntimePrivate(JS_GetRuntime(cx));
-
- jsOptions =
- JS_GetOptions(cx) | JSOPTION_ANONFUNFIX | JSOPTION_STRICT |
- JSOPTION_RELIMIT | JSOPTION_JIT;
- *verbosity_p = 0;
-
- /* Iterate over each flag */
- for (f = flags; *f; f++) {
- switch (*f) {
- /* 'C' flag disables compiler cache */
- case 'C':
- grt->useCompilerCache = 0;
- break;
-
- case 'a': /* Handled in prmain() */
- case 'R': /* Handled in loadRuntimeConfig() */
- case 'U': /* Must be handled before 1st JS runtime */
- break;
-
- case 'x': /* Parse <!-- comments --> as E4X tokens */
- jsOptions |= JSOPTION_XML;
- break;
-
- case 'S': /* Disable Strict JS */
- jsOptions &= ~JSOPTION_STRICT;
- break;
-
- case 'W': /* Suppress JS Warnings */
- grt->errorReport |= er_noWarnings;
- break;
-
- case 'e': /* Allow regexps that are more than O(n^3) */
- jsOptions &= ~JSOPTION_RELIMIT;
- break;
-
- case 'J': /* Disable Nanojit */
- jsOptions &= ~JSOPTION_JIT;
- break;
-
- case 'z': /* GC Zeal */
- gcZeal++;
- break;
-
- case 'd': /* increase debug level */
- (*verbosity_p)++;;
- break;
-
- default:
- gpsee_log(cx, SLOG_WARNING,
- "Error: Unrecognized option flag %c!", *f);
- break;
- }
- }
-
-#ifdef JSFEATURE_GC_ZEAL
- if (JS_HasFeature(JSFEATURE_GC_ZEAL) == JS_TRUE)
- JS_SetGCZeal(cx, gcZeal);
-#else
-# ifdef JS_GC_ZEAL
- JS_SetGCZeal(cx, gcZeal);
-# else
-# warning JS_SetGCZeal not available when building with this version of SpiderMonkey (try a debug build?)
-# endif
-#endif
-
- JS_SetOptions(cx, jsOptions);
-}
-
+#ifdef NOTYET /* XXX FIXME */
static void processInlineFlags(rpmgsr gsr, FILE * fp, signed int *verbosity_p)
{
char buf[256];
@@ -599,6 +452,7 @@
fseeko(fp, offset, SEEK_SET);
}
+#endif
static FILE *openScriptFile(rpmgsr gsr)
{
@@ -633,54 +487,15 @@
return file;
}
-/**
- * Detect if we've been asked to run as a file interpreter.
- *
- * File interpreters always have the script filename within
- * the first two arguments. It is never "not found", except
- * due to an annoying OS race in exec(2), which is very hard
- * to exploit.
- *
- * @returns - 0 if we're not a file interpreter
- * - 1 if the script filename is on argv[1]
- * - 2 if the script filename is on argv[2]
- */
-PRIntn findFileToInterpret(PRIntn argc, char **argv)
-{
- if (argc == 1)
- return 0;
-
- if ((argv[1][0] == '-') && ((argv[1][1] == '-')
- || strchr(argv[1] + 1, 'c')
- || strchr(argv[1] + 1, 'f')
- || strchr(argv[1] + 1, 'F')
- || strchr(argv[1] + 1, 'h')
- || strchr(argv[1] + 1, 'n')
- )
- )
- return 0; /* -h, -c, -f, -F, -r will always be invalid flags & force command mode */
-
- if ((argc > 1) && argv[1][0] != '-')
- if (access(argv[1], F_OK) == 0)
- return 1;
-
- if ((argc > 2) && (argv[2][0] != '-'))
- if (access(argv[2], F_OK) == 0)
- return 2;
-
- return 0;
-}
-
/** Load RC file based on filename.
* Filename to use is script's filename, if -R option flag is thrown.
* Otherwise, file interpreter's filename (i.e. gsr) is used.
*/
-void loadRuntimeConfig(rpmgsr gsr, const char *flags,
- int argc, char *const *argv)
+static void loadRuntimeConfig(rpmgsr gsr, int argc, char *const *argv)
{
rcFILE *rc_file;
- if (strchr(flags, 'R')) {
+ if (F_ISSET(gsr, LOADRC)) {
char fake_argv_zero[FILENAME_MAX];
char *fake_argv[2];
char *s;
@@ -714,7 +529,7 @@
rc_close(rc_file);
}
-PRIntn prmain(PRIntn argc, char **argv)
+static PRIntn prmain(PRIntn argc, char **argv)
{
poptContext optCon;
rpmgsr gsr = &_gsr;
@@ -723,118 +538,40 @@
JSContext * cx; /* A context in realm */
void *stackBasePtr;
- char *flags; /* Flags found on command line */
+ int ac = 0;
int ec = 1;
#ifdef GPSEE_DEBUGGER
JSDContext *jsdc;
#endif
- flags = xmalloc(8);
- flags[0] = '\0';
-
gpsee_setVerbosity(isatty(STDERR_FILENO) ? GSR_PREPROGRAM_TTY_VERBOSITY
: GSR_PREPROGRAM_NOTTY_VERBOSITY);
gpsee_openlog(gpsee_basename(argv[0]));
optCon = rpmioInit(argc, argv, optionsTable);
- /* Print usage and exit if no arguments were given */
- if (argc < 2)
- usage(argv[0]);
-
- gsr->fiArg = findFileToInterpret(argc, argv);
-
- if (gsr->fiArg == 0) { /* Not a script file interpreter (shebang) */
- char *fe = flags;
- int c;
-
- while ((c = getopt(argc, argv, "v:c:hHnf:F:aCRxSUWdeJz")) != -1) {
- switch (c) {
-
- case 'a':
- case 'C':
- case 'd':
- case 'e':
- case 'J':
- case 'S':
- case 'R':
- case 'U':
- case 'W':
- case 'x':
- case 'z':
- {
- char *flags_storage =
- realloc(flags, (fe - flags) + 1 + 1);
-
- if (flags_storage != flags) {
- fe = (fe - flags) + flags_storage;
- flags = flags_storage;
- }
-
- *fe++ = c;
- *fe = '\0';
- }
- break;
-
- case '?':
- {
- char buf[32];
-
- snprintf(buf, sizeof(buf), "Invalid option: %c\n",
- optopt);
- fatal(buf);
- }
-
- case ':':
- {
- char buf[32];
- snprintf(buf, sizeof(buf),
- "Missing parameter to option '%c'\n", optopt);
- fatal(buf);
- }
-
- }
- } /* getopt wend */
-
- /* Create the script's argument vector with the script name as arguments[0] */
- {
- char **nc_script_argv =
- malloc(sizeof(argv[0]) * (2 + (argc - optind)));
- nc_script_argv[0] = (char *) gsr->fn;
- memcpy(nc_script_argv + 1, argv + optind,
- sizeof(argv[0]) * ((1 + argc) - optind));
- gsr->argv = nc_script_argv;
- }
-
- *fe = '\0';
- } else {
- gsr->fn = argv[gsr->fiArg];
-
- if (gsr->fiArg == 2) {
- if (argv[1][0] != '-')
- fatal
- ("Invalid syntax for file-interpreter flags! (Must begin with '-')");
-
- flags = realloc(flags, strlen(argv[1]) + 1);
- strcpy(flags, argv[1] + 1);
- }
-
- /* This is a file interpreter; script_argv is correct at offset fiArg. */
- gsr->argv = argv + gsr->fiArg;
+ /* Add files from CLI. */
+ { ARGV_t av = poptGetArgs(optCon);
+ int xx;
+ if (av != NULL)
+ xx = argvAppend((const char ***)&gsr->argv, av);
}
- if (strchr(flags, 'a')) {
-#if defined(GPSEE_DARWIN_SYSTEM)
- gsr->environ = (char *const *) _NSGetEnviron();
-#else
- extern char **environ;
- gsr->environ = (char *const *) environ;
-#endif
+ ac = argvCount((ARGV_t)gsr->argv);
+ switch (ac) {
+ case 0:
+ if (gsr->code || gsr->fn)
+ break;
+ /*@fallthrough@*/
+ default:
+ poptPrintUsage(optCon, stderr, 0);
+ goto exit;
+ /*@notreached@*/ break;
}
- loadRuntimeConfig(gsr, flags, argc, argv);
- if (strchr(flags, 'U')
+ loadRuntimeConfig(gsr, argc, argv);
+ if (F_ISSET(gsr, NOUTF8)
|| (rc_bool_value(rc, "gpsee_force_no_utf8_c_strings") == rc_true)
|| getenv("GPSEE_NO_UTF8_C_STRINGS"))
{
@@ -853,8 +590,24 @@
strtol(rc_default_value(rc, "gpsee_thread_stack_limit_bytes",
"0x80000"), NULL, 0));
- processFlags(gsr, flags, &gsr->verbosity);
- free(flags);
+ if (F_ISSET(gsr, NOWARN)) {
+ gpsee_runtime_t *grt = JS_GetRuntimePrivate(JS_GetRuntime(cx));
+ grt->errorReport |= er_noWarnings;
+ }
+
+#ifdef JSFEATURE_GC_ZEAL
+ if (JS_HasFeature(JSFEATURE_GC_ZEAL) == JS_TRUE)
+ JS_SetGCZeal(cx, gsr->gcZeal);
+#else
+# ifdef JS_GC_ZEAL
+ JS_SetGCZeal(cx, gsr->gcZeal);
+# else
+# warning JS_SetGCZeal not available when building with this version of SpiderMonkey (try a debug build?)
+# endif
+#endif
+
+ gsr->options |= JS_GetOptions(cx); /* XXX FIXME */
+ JS_SetOptions(cx, gsr->options);
if (gsr->verbosity < GSR_MIN_TTY_VERBOSITY && isatty(STDERR_FILENO))
gsr->verbosity = GSR_MIN_TTY_VERBOSITY;
@@ -933,7 +686,7 @@
gpsee_setVerbosity(gsr->verbosity);
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
- if (gsr->fiArg != 0)
+ if (ac != 0) /* XXX FIXME */
gsr->flags |= RPMGSR_FLAGS_SKIPSHEBANG;
if (gsr->fn == NULL) {
@@ -950,8 +703,10 @@
goto exit;
}
+#ifdef NOTYET /* XXX FIXME */
processInlineFlags(gsr, fp, &gsr->verbosity);
gpsee_setVerbosity(gsr->verbosity);
+#endif
/* Just compile and exit? */
if (F_ISSET(gsr, NOEXEC)) {
@@ -973,7 +728,7 @@
} else { /* noRunScript is false; run the program */
if (!gpsee_runProgramModule(cx, gsr->fn,
- NULL, fp, gsr->argv, gsr->environ))
+ NULL, fp, (char * const*)gsr->argv, gsr->environ))
{
int code = gpsee_getExceptionExitCode(cx);
if (code >= 0) {
@@ -997,7 +752,7 @@
exit:
gsr->code = _free(gsr->code);
gsr->fn = _free(gsr->fn);
- gsr->argv = NULL;
+ gsr->argv = argvFree(gsr->argv);
gsr->environ = NULL;
optCon = rpmioFini(optCon);
@@ .
Received on Sun Sep 12 17:23:07 2010