RPM Community Forums

Mailing List Message of <rpm-cvs>

[CVS] RPM: rpm/js/ ngsr.c

From: Jeff Johnson <jbj@rpm5.org>
Date: Sun 12 Sep 2010 - 16:32:57 CEST
Message-Id: <20100912143257.8AEAEC1838@rpm5.org>
  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 16:32:57
  Branch: HEAD                             Handle: 2010091214325700

  Modified files:
    rpm/js                  ngsr.c

  Log:
    - gpsee: WIP.

  Summary:
    Revision    Changes     Path
    1.3         +385 -203   rpm/js/ngsr.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/js/ngsr.c
  ============================================================================
  $ cvs diff -u -r1.2 -r1.3 ngsr.c
  --- rpm/js/ngsr.c	12 Sep 2010 05:59:33 -0000	1.2
  +++ rpm/js/ngsr.c	12 Sep 2010 14:32:57 -0000	1.3
  @@ -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.2 2010/09/12 05:59:33 jbj Exp $
  + * @version	$Id: ngsr.c,v 1.3 2010/09/12 14:32:57 jbj Exp $
    *
    * This program is designed to interpret a JavaScript program as much like
    * a shell script as possible.
  @@ -55,7 +55,13 @@
    */
   
   static __attribute__ ((unused))
  -const char rcsid[] = "$Id: ngsr.c,v 1.2 2010/09/12 05:59:33 jbj Exp $";
  +const char rcsid[] = "$Id: ngsr.c,v 1.3 2010/09/12 14:32:57 jbj Exp $";
  +
  +#include "system.h"
  +
  +#include <rpmiotypes.h>
  +#include <rpmio.h>
  +#include <poptIO.h>
   
   #define PRODUCT_VERSION		"1.0-pre3"
   
  @@ -77,23 +83,60 @@
   #include <crt_externs.h>
   #endif
   
  -#if defined(__SURELYNX__)
  -# define NO_APR_SURELYNX_NAMESPACE_POISONING
  -# define NO_SURELYNX_INT_TYPEDEFS	/* conflicts with mozilla's NSPR protypes.h */
  -#endif
  +#define xstr(s) str(s)
  +#define str(s) #s
   
  -#if defined(__SURELYNX__)
  -static apr_pool_t *permanent_pool;
  -#endif
  +#include "debug.h"
   
  -#if defined(__SURELYNX__)
  -# define whenSureLynx(a,b)	a
  -#else
  -# define whenSureLynx(a,b)	b
  -#endif
  +/*==============================================================*/
   
  -#define xstr(s) str(s)
  -#define str(s) #s
  +static int _rpmgsr_debug = 0;
  +
  +#define _KFB(n) (1U << (n))
  +#define _DFB(n) (_KFB(n) | 0x40000000)
  +
  +#define F_ISSET(_gsr, _FLAG) ((_gsr)->flags & ((RPMGSR_FLAGS_##_FLAG) & ~0x40000000))
  +
  +/**
  + * Bit field enum for CLI options.
  + */
  +enum gsrFlags_e {
  +    RPMGSR_FLAGS_NONE		= 0,
  +    RPMGSR_FLAGS_NOEXEC		= _DFB(0),	/*!< -n */
  +    RPMGSR_FLAGS_SKIPSHEBANG	= _DFB(1),	/*!< -F */
  +};
  +
  +/**
  + */
  +typedef struct rpmgsr_s *rpmgsr;
  +
  +/**
  + */
  +struct rpmgsr_s {
  +    enum gsrFlags_e flags;	/*!< control bits. */
  +    int options;
  +    int gcZeal;
  +
  +    gpsee_interpreter_t * I;	/* Handle describing JS interpreter */
  +
  +    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 */
  +    char *const *environ;	/* Environment to pass to script */
  +
  +    int verbosity;		/* 0 = no debug, bigger = more debug */
  +    int fiArg;
  +};
  +
  +/**
  + */
  +static struct rpmgsr_s _gsr = {
  +    .flags = RPMGSR_FLAGS_NONE,
  +    .options =
  +      JSOPTION_ANONFUNFIX | JSOPTION_STRICT | JSOPTION_RELIMIT | JSOPTION_JIT,
  +};
  +
  +/*==============================================================*/
   
   extern rc_list rc;
   
  @@ -139,6 +182,198 @@
       fatal(message);
   }
   
  +/*==============================================================*/
  +/**
  + */
  +static void rpmgsrArgCallback(poptContext con,
  +                /*@unused@*/ enum poptCallbackReason reason,
  +                const struct poptOption * opt, /*@unused@*/ const char * arg,
  +                /*@unused@*/ void * data)
  +	/*@globals fileSystem @*/
  +	/*@modifies fileSystem @*/
  +{
  +    rpmgsr gsr = &_gsr;
  +
  +    /* XXX avoid accidental collisions with POPT_BIT_SET for flags */
  +    if (opt->arg == NULL)
  +    switch (opt->val) {
  +    case 'F':
  +	gsr->flags |= RPMGSR_FLAGS_SKIPSHEBANG;
  +	gsr->fn = xstrdup(arg);
  +	break;
  +    case 'h':
  +	poptPrintHelp(con, stderr, 0);
  +#ifdef	NOTYET
  +/*@-exitarg@*/
  +	exit(0);
  +/*@=exitarg@*/
  +#endif
  +	break;
  +    case 'a':
  +	break;
  +    case 'C':
  +	break;
  +    case 'd':
  +	break;
  +    case 'e':
  +	break;
  +    case 'J':
  +	break;
  +    case 'S':
  +	break;
  +    case 'R':
  +	break;
  +    case 'U':
  +	break;
  +    case 'W':
  +	break;
  +    case 'x':
  +	break;
  +    case 'z':
  +	gsr->gcZeal++;
  +	break;
  +    default:
  +	fprintf(stderr, _("%s: Unknown option -%c\n"), __progname, opt->val);
  +	poptPrintUsage(con, stderr, 0);
  +/*@-exitarg@*/
  +	exit(2);
  +/*@=exitarg@*/
  +	/*@notreached@*/ break;
  +    }
  +}
  +
  +static struct poptOption _gsrOptionsTable[] = {
  +/*@-type@*/ /* FIX: cast? */
  + { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
  +        rpmgsrArgCallback, 0, NULL, NULL },
  +/*@=type@*/
  +
  +  { NULL, 'c', POPT_ARG_STRING,      &_gsr.code, 0,
  +        N_("Specifies literal JavaScript code to execute"), N_("code") },
  +  { NULL, 'f', POPT_ARG_STRING,      &_gsr.fn, 0,
  +        N_("Specifies the filename containing code to run"), N_("filename") },
  +  { NULL, 'F', POPT_ARG_STRING,      NULL, 'F',
  +        N_("Like -f, but skip shebang if present."), N_("filename") },
  +  { NULL, 'h', POPT_ARG_NONE,      NULL, 'h',
  +        N_("Display this help"), NULL },
  +  { NULL, 'n', POPT_BIT_SET,		&_gsr.flags, RPMGSR_FLAGS_NOEXEC,
  +	N_("Engine will load and parse, but not run, the script"), NULL },
  +#if defined(__SURELYNX__)
  +  { NULL, 'D', POPT_ARG_STRING,      NULL, 'D',
  +        N_("Specifies a debug output file"), N_("file") },
  +#ifdef	NOTYET	/* -r file appears defunct */
  +  { NULL, 'r', POPT_ARG_STRING,      NULL, 'r',
  +        N_("Specifies alternate interpreter RC file"), N_("file") },
  +#endif
  +#endif
  +
  +  POPT_TABLEEND
  +};
  +
  +static struct poptOption _jsOptionsTable[] = {
  +/*@-type@*/ /* FIX: cast? */
  + { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
  +        rpmgsrArgCallback, 0, NULL, NULL },
  +/*@=type@*/
  +
  +  { NULL, 'a', POPT_ARG_NONE,      NULL, 'a',
  +        N_("Allow (read-only) access to caller's environmen"), NULL },
  +  { NULL, 'C', POPT_ARG_NONE,      NULL, 'C',
  +        N_("Disables compiler caching via JSScript XDR serialization"), NULL },
  +  { NULL, 'd', POPT_ARG_NONE,      NULL, 'd',
  +        N_("Increase verbosity"), NULL },
  +  { NULL, 'e', POPT_ARG_NONE,      NULL, 'e',
  +        N_("Do not limit regexps to n^3 levels of backtracking"), NULL },
  +  { NULL, 'J', POPT_ARG_NONE,      NULL, 'J',
  +        N_("Disable nanojit"), NULL },
  +  { NULL, 'S', POPT_ARG_NONE,      NULL, 'S',
  +        N_("Disable Strict mode"), NULL },
  +  { NULL, 'R', POPT_ARG_NONE,      NULL, 'R',
  +        N_("Load RC file for interpreter (" PRODUCT_SHORTNAME ") based on script filename."), NULL },
  +  { NULL, 'U', POPT_ARG_NONE,      NULL, 'U',
  +        N_("Disable UTF-8 C string processing"), NULL },
  +  { NULL, 'W', POPT_ARG_NONE,      NULL, 'W',
  +        N_("Do not report warnings"), NULL },
  +  { NULL, 'x', POPT_ARG_NONE,      NULL, 'x',
  +        N_("Parse <!-- comments --> as E4X tokens"), NULL },
  +  { NULL, 'z', POPT_ARG_NONE,      NULL, 'z',
  +        N_("Increase GC Zealousness"), NULL },
  +
  +  POPT_TABLEEND
  +};
  +
  +static struct poptOption _optionsTable[] = {
  +/*@-type@*/ /* FIX: cast? */
  + { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
  +        rpmgsrArgCallback, 0, NULL, NULL },
  +/*@=type@*/
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, _gsrOptionsTable, 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\
  +\n\
  +Command Options:\
  +"), NULL },
  +
  +  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, _jsOptionsTable, 0,
  +        N_("\
  +Valid Flags:\
  +"), NULL },
  +
  +#ifdef	NOTYET
  + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmioAllPoptTable, 0,
  +	N_("Common options for all rpmio executables:"), NULL },
  +
  +  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.
    *
  @@ -151,20 +386,14 @@
       char spaces[strlen(argv_zero) + 1];
   
       memset(spaces, (int) (' '), sizeof(spaces) - 1);
  -    spaces[sizeof(spaces) - 1] = (char) 0;
  +    spaces[sizeof(spaces) - 1] = '\0';
   
       printf("\n"
  -#if defined(__SURELYNX__)
  -	   "SureLynx "
  -#endif
   	   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 "
  -#if defined(__SURELYNX__)
  -	   "{-r file} [-D file] "
  -#endif
   	   "[-z #] [-n] <[-c code] [-f filename]>\n"
   	   "                   %s {-/*flags*/} {[--] [arg...]}\n"
   	   "Command Options:\n"
  @@ -174,10 +403,6 @@
   	   "    -h          Display this help\n"
   	   "    -H          Display more help\n"
   	   "    -n          Engine will load and parse, but not run, the script\n"
  -#if defined(__SURELYNX__)
  -	   "    -D file     Specifies a debug output file\n"
  -	   "    -r file     Specifies alternate interpreter RC file\n"
  -#endif
   	   "    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"
  @@ -212,12 +437,9 @@
       char spaces[strlen(argv_zero) + 1];
   
       memset(spaces, (int) (' '), sizeof(spaces) - 1);
  -    spaces[sizeof(spaces) - 1] = (char) 0;
  +    spaces[sizeof(spaces) - 1] = '\0';
   
       printf("\n"
  -#if defined(__SURELYNX__)
  -	   "SureLynx "
  -#endif
   	   PRODUCT_SHORTNAME " " PRODUCT_VERSION " - " PRODUCT_SUMMARY " "
   	   GPSEE_CURRENT_VERSION_STRING "\n"
   	   "Copyright (c) 2007-2010 PageMail, Inc. All Rights Reserved.\n"
  @@ -265,9 +487,10 @@
    *
    *  @param	flags	An array of flags, in no particular order.
    */
  -static void processFlags(JSContext * cx, const char *flags,
  +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;
  @@ -340,15 +563,14 @@
       JS_SetOptions(cx, jsOptions);
   }
   
  -static void processInlineFlags(JSContext * cx, FILE * scriptFile,
  -			       signed int *verbosity_p)
  +static void processInlineFlags(rpmgsr gsr, FILE * fp, signed int *verbosity_p)
   {
       char buf[256];
       off_t offset;
   
  -    offset = ftello(scriptFile);
  +    offset = ftello(fp);
   
  -    while (fgets(buf, sizeof(buf), scriptFile)) {
  +    while (fgets(buf, sizeof(buf), fp)) {
   	char *s, *e;
   
   	if ((buf[0] != '/') || (buf[1] != '/'))
  @@ -366,22 +588,22 @@
   	    case '\n':
   	    case '\t':
   	    case ' ':
  -		*e = (char) 0;
  +		*e = '\0';
   		break;
   	    }
   	}
   
   	if (s[0])
  -	    processFlags(cx, s, verbosity_p);
  +	    processFlags(gsr, s, verbosity_p);
       }
   
  -    fseeko(scriptFile, offset, SEEK_SET);
  +    fseeko(fp, offset, SEEK_SET);
   }
   
  -static FILE *openScriptFile(JSContext * cx, const char *scriptFilename,
  -			    int skipSheBang)
  +static FILE *openScriptFile(rpmgsr gsr)
   {
  -    FILE *file = fopen(scriptFilename, "r");
  +    JSContext * cx = gsr->I->cx;
  +    FILE *file = fopen(gsr->fn, "r");
       char line[64];		/* #! args can be longer than 64 on some unices, but no matter */
   
       if (!file)
  @@ -389,7 +611,7 @@
   
       gpsee_flock(fileno(file), GPSEE_LOCK_SH);
   
  -    if (!skipSheBang)
  +    if (!F_ISSET(gsr, SKIPSHEBANG))
   	return file;
   
       if (fgets(line, sizeof(line), file)) {
  @@ -434,10 +656,6 @@
   				|| strchr(argv[1] + 1, 'F')
   				|| strchr(argv[1] + 1, 'h')
   				|| strchr(argv[1] + 1, 'n')
  -#if defined(__SURELYNX__)
  -				|| strchr(argv[1], 'r')
  -				|| strchr(argv[1], 'D')
  -#endif
   	)
   	)
   	return 0;		/* -h, -c, -f, -F, -r will always be invalid flags & force command mode */
  @@ -457,7 +675,7 @@
    *  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(const char *scriptFilename, const char *flags,
  +void loadRuntimeConfig(rpmgsr gsr, const char *flags,
   		       int argc, char *const *argv)
   {
       rcFILE *rc_file;
  @@ -467,23 +685,22 @@
   	char *fake_argv[2];
   	char *s;
   
  -	if (!scriptFilename)
  +	if (gsr->fn == NULL)
   	    fatal
   		("Cannot use script-filename RC file when script-filename is unknown!");
   
   	fake_argv[0] = fake_argv_zero;
   
  -	gpsee_cpystrn(fake_argv_zero, scriptFilename,
  -		      sizeof(fake_argv_zero));
  +	gpsee_cpystrn(fake_argv_zero, gsr->fn, sizeof(fake_argv_zero));
   
  -	if ((s = strstr(fake_argv_zero, ".js")) && (s[3] == (char) 0))
  -	    *s = (char) 0;
  +	if ((s = strstr(fake_argv_zero, ".js")) && s[3] == '\0')
  +	    *s = '\0';
   
  -	if ((s = strstr(fake_argv_zero, ".es3")) && (s[4] == (char) 0))
  -	    *s = (char) 0;
  +	if ((s = strstr(fake_argv_zero, ".es3")) && s[4] == '\0')
  +	    *s = '\0';
   
  -	if ((s = strstr(fake_argv_zero, ".e4x")) && (s[4] == (char) 0))
  -	    *s = (char) 0;
  +	if ((s = strstr(fake_argv_zero, ".e4x")) && s[4] == '\0')
  +	    *s = '\0';
   
   	rc_file = rc_openfile(1, fake_argv);
       } else {
  @@ -499,78 +716,40 @@
   
   PRIntn prmain(PRIntn argc, char **argv)
   {
  +    poptContext optCon;
  +    rpmgsr gsr = &_gsr;
  +    gpsee_interpreter_t * I = NULL;
  +    gpsee_realm_t * realm;	/* Interpreter's primordial realm */
  +    JSContext * cx;		/* A context in realm */
  +
       void *stackBasePtr;
  -    gpsee_interpreter_t *jsi;	/* Handle describing a GPSEE/JavaScript Interpreter */
  -    gpsee_realm_t *realm;	/* Interpreter's primordial realm */
  -    JSContext *cx;		/* A context in realm */
  -    const char *scriptCode = NULL;	/* String with JavaScript program in it */
  -    const char *scriptFilename = NULL;	/* Filename with JavaScript program in it */
  -    char *const *script_argv;	/* Becomes arguments array in JS program */
  -    char *const *script_environ = NULL;	/* Environment to pass to script */
  -    char *flags = malloc(8);	/* Flags found on command line */
  -    int noRunScript = 0;	/* !0 = compile but do not run */
  -
  -    int fiArg = 0;
  -    int skipSheBang = 0;
  -    int exitCode = 1;
  -    int verbosity;		/* Verbosity to use before flags are processed */
  +    char *flags;		/* Flags found on command line */
  +    int ec = 1;
   #ifdef GPSEE_DEBUGGER
       JSDContext *jsdc;
   #endif
   
  -#if defined(__SURELYNX__)
  -    permanent_pool = apr_initRuntime();
  -#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]);
   
  -    flags[0] = (char) 0;
  +    gsr->fiArg = findFileToInterpret(argc, argv);
   
  -    fiArg = findFileToInterpret(argc, argv);
  -
  -    if (fiArg == 0) {		/* Not a script file interpreter (shebang) */
  +    if (gsr->fiArg == 0) {		/* Not a script file interpreter (shebang) */
  +	char *fe = flags;
   	int c;
  -	char *flag_p = flags;
   
  -	while ((c =
  -		getopt(argc, argv,
  -		       whenSureLynx("D:r:",
  -				    "") "v:c:hHnf:F:aCRxSUWdeJz")) != -1) {
  +	while ((c = getopt(argc, argv, "v:c:hHnf:F:aCRxSUWdeJz")) != -1) {
   	    switch (c) {
  -#if defined(__SURELYNX__)
  -	    case 'D':
  -		redirect_output(permanent_pool, optarg);
  -		break;
  -	    case 'r':		/* handled by rc_openfile() */
  -		break;
  -#endif
  -
  -	    case 'c':
  -		scriptCode = optarg;
  -		break;
  -
  -	    case 'h':
  -		usage(argv[0]);
  -		break;
  -
  -	    case 'H':
  -		moreHelp(argv[0]);
  -		break;
  -
  -	    case 'n':
  -		noRunScript = 1;
  -		break;
  -
  -	    case 'F':
  -		skipSheBang = 1;
  -	    case 'f':
  -		scriptFilename = optarg;
  -		break;
   
   	    case 'a':
   	    case 'C':
  @@ -585,15 +764,15 @@
   	    case 'z':
   		{
   		    char *flags_storage =
  -			realloc(flags, (flag_p - flags) + 1 + 1);
  +			realloc(flags, (fe - flags) + 1 + 1);
   
   		    if (flags_storage != flags) {
  -			flag_p = (flag_p - flags) + flags_storage;
  +			fe = (fe - flags) + flags_storage;
   			flags = flags_storage;
   		    }
   
  -		    *flag_p++ = c;
  -		    *flag_p = '\0';
  +		    *fe++ = c;
  +		    *fe = '\0';
   		}
   		break;
   
  @@ -622,17 +801,17 @@
   	{
   	    char **nc_script_argv =
   		malloc(sizeof(argv[0]) * (2 + (argc - optind)));
  -	    nc_script_argv[0] = (char *) scriptFilename;
  +	    nc_script_argv[0] = (char *) gsr->fn;
   	    memcpy(nc_script_argv + 1, argv + optind,
   		   sizeof(argv[0]) * ((1 + argc) - optind));
  -	    script_argv = nc_script_argv;
  +	    gsr->argv = nc_script_argv;
   	}
   
  -	*flag_p = (char) 0;
  +	*fe = '\0';
       } else {
  -	scriptFilename = argv[fiArg];
  +	gsr->fn = argv[gsr->fiArg];
   
  -	if (fiArg == 2) {
  +	if (gsr->fiArg == 2) {
   	    if (argv[1][0] != '-')
   		fatal
   		    ("Invalid syntax for file-interpreter flags! (Must begin with '-')");
  @@ -642,67 +821,64 @@
   	}
   
   	/* This is a file interpreter; script_argv is correct at offset fiArg. */
  -	script_argv = argv + fiArg;
  +	gsr->argv = argv + gsr->fiArg;
       }
   
       if (strchr(flags, 'a')) {
   #if defined(GPSEE_DARWIN_SYSTEM)
  -	script_environ = (char *const *) _NSGetEnviron();
  +	gsr->environ = (char *const *) _NSGetEnviron();
   #else
   	extern char **environ;
  -	script_environ = (char *const *) environ;
  +	gsr->environ = (char *const *) environ;
   #endif
       }
   
  -    loadRuntimeConfig(scriptFilename, flags, argc, argv);
  +    loadRuntimeConfig(gsr, flags, argc, argv);
       if (strchr(flags, 'U')
  -	|| (rc_bool_value(rc, "gpsee_force_no_utf8_c_strings") == rc_true)
  -	|| getenv("GPSEE_NO_UTF8_C_STRINGS")) {
  +     || (rc_bool_value(rc, "gpsee_force_no_utf8_c_strings") == rc_true)
  +     || getenv("GPSEE_NO_UTF8_C_STRINGS"))
  +    {
   	JS_DestroyRuntime(JS_NewRuntime(1024));
   	putenv((char *) "GPSEE_NO_UTF8_C_STRINGS=1");
       }
   
  -    jsi = gpsee_createInterpreter();
  -    realm = jsi->realm;
  -    cx = jsi->cx;
  +    gsr->I = I = gpsee_createInterpreter();
  +    realm = I->realm;
  +    cx = I->cx;
   #if defined(GPSEE_DEBUGGER)
       jsdc = gpsee_initDebugger(cx, realm, DEBUGGER_JS);
   #endif
   
       gpsee_setThreadStackLimit(cx, &stackBasePtr,
  -			      strtol(rc_default_value
  -				     (rc, "gpsee_thread_stack_limit_bytes",
  -				      "0x80000"), NULL, 0));
  +		strtol(rc_default_value(rc, "gpsee_thread_stack_limit_bytes",
  +			      "0x80000"), NULL, 0));
   
  -    processFlags(cx, flags, &verbosity);
  +    processFlags(gsr, flags, &gsr->verbosity);
       free(flags);
   
  -#if defined(__SURELYNX__)
  -    sl_set_debugLevel(gpsee_verbosity(0));
  -    enableTerminalLogs(permanent_pool, gpsee_verbosity(0) > 0, NULL);
  -#else
  -    if (verbosity < GSR_MIN_TTY_VERBOSITY && isatty(STDERR_FILENO))
  -	verbosity = GSR_MIN_TTY_VERBOSITY;
  -#endif
  +    if (gsr->verbosity < GSR_MIN_TTY_VERBOSITY && isatty(STDERR_FILENO))
  +	gsr->verbosity = GSR_MIN_TTY_VERBOSITY;
   
  -    if (gpsee_verbosity(0) < verbosity)
  -	gpsee_setVerbosity(verbosity);
  +    if (gpsee_verbosity(0) < gsr->verbosity)
  +	gpsee_setVerbosity(gsr->verbosity);
   
       /* Run JavaScript specified with -c */
  -    if (scriptCode) {
  +    if (gsr->code) {
   	jsval v;
   
  -	if (JS_EvaluateScript
  -	    (cx, realm->globalObject, scriptCode, strlen(scriptCode),
  -	     "command_line", 1, &v) == JS_FALSE) {
  +	if (JS_EvaluateScript(cx, realm->globalObject,
  +		gsr->code, strlen(gsr->code),
  +		"command_line", 1, &v) == JS_FALSE)
  +	{
   	    v = JSVAL_NULL;
  -	    goto out;
  +	    goto exit;
   	}
   	v = JSVAL_NULL;
       }
   
  -    if ((argv[0][0] == '/') && (strcmp(argv[0], SYSTEM_GSR) != 0)
  -	&& rc_bool_value(rc, "no_gsr_preload_script") != rc_true) {
  +    if (argv[0][0] == '/' && strcmp(argv[0], SYSTEM_GSR)
  +     && rc_bool_value(rc, "no_gsr_preload_script") != rc_true)
  +    {
   	char preloadScriptFilename[FILENAME_MAX];
   	char mydir[FILENAME_MAX];
   	int i;
  @@ -711,7 +887,7 @@
   		     "%s/.%s_preload", gpsee_dirname(argv[0], mydir,
   						     sizeof(mydir)),
   		     gpsee_basename(argv[0]));
  -	if ((i == 0) || (i == (sizeof(preloadScriptFilename) - 1)))
  +	if (i == 0 || i == (sizeof(preloadScriptFilename) - 1))
   	    gpsee_log(cx, SLOG_EMERG,
   		      PRODUCT_SHORTNAME
   		      ": Unable to create preload script filename!");
  @@ -723,25 +899,25 @@
   	    JSScript *script;
   	    JSObject *scrobj;
   
  -	    if (!gpsee_compileScript
  -		(cx, preloadScriptFilename, NULL, NULL, &script,
  -		 realm->globalObject, &scrobj)) {
  +	    if (!gpsee_compileScript(cx, preloadScriptFilename,
  +			NULL, NULL, &script, realm->globalObject, &scrobj))
  +	    {
   		gpsee_log(cx, SLOG_EMERG,
   			  PRODUCT_SHORTNAME
   			  ": Unable to compile preload script '%s'",
   			  preloadScriptFilename);
  -		goto out;
  +		goto exit;
   	    }
   
   	    if (!script || !scrobj)
  -		goto out;
  +		goto exit;
   
  -	    if (!noRunScript) {
  +	    if (!F_ISSET(gsr, NOEXEC)) {
   		JS_AddNamedObjectRoot(cx, &scrobj, "preload_scrobj");
  -		if (JS_ExecuteScript(cx, realm->globalObject, script, &v)
  -		    == JS_FALSE) {
  +		if (JS_ExecuteScript(cx, realm->globalObject, script, &v) == JS_FALSE)
  +		{
   		    if (JS_IsExceptionPending(cx))
  -			jsi->grt->exitType = et_exception;
  +			I->grt->exitType = et_exception;
   		    JS_ReportPendingException(cx);
   		}
   		JS_RemoveObjectRoot(cx, &scrobj);
  @@ -749,87 +925,93 @@
   	    }
   	}
   
  -	if (jsi->grt->exitType & et_exception)
  -	    goto out;
  +	if (I->grt->exitType & et_exception)
  +	    goto exit;
       }
   
       /* Setup for main-script running -- cancel preprogram verbosity and use our own error reporting system in gsr that does not use error reporter */
  -    gpsee_setVerbosity(verbosity);
  +    gpsee_setVerbosity(gsr->verbosity);
       JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
   
  -    if (!scriptFilename) {
  -	exitCode = scriptCode ? 0 : 1;
  +    if (gsr->fiArg != 0)
  +	gsr->flags |= RPMGSR_FLAGS_SKIPSHEBANG;
  +
  +    if (gsr->fn == NULL) {
  +	ec = gsr->code ? 0 : 1;
       } else {
  -	FILE *scriptFile = openScriptFile(cx, scriptFilename, skipSheBang
  -					  || (fiArg != 0));
  +	FILE *fp = openScriptFile(gsr);
   
  -	if (!scriptFile) {
  +	if (fp == NULL) {
   	    gpsee_log(cx, SLOG_NOTICE,
   		      PRODUCT_SHORTNAME
   		      ": Unable to open' script '%s'! (%m)",
  -		      scriptFilename);
  -	    exitCode = 1;
  -	    goto out;
  +		      gsr->fn);
  +	    ec = 1;
  +	    goto exit;
   	}
   
  -	processInlineFlags(cx, scriptFile, &verbosity);
  -	gpsee_setVerbosity(verbosity);
  +	processInlineFlags(gsr, fp, &gsr->verbosity);
  +	gpsee_setVerbosity(gsr->verbosity);
   
   	/* Just compile and exit? */
  -	if (noRunScript) {
  +	if (F_ISSET(gsr, NOEXEC)) {
   	    JSScript *script;
   	    JSObject *scrobj;
   
  -	    if (!gpsee_compileScript
  -		(cx, scriptFilename, scriptFile, NULL, &script,
  -		 realm->globalObject, &scrobj)) {
  +	    if (!gpsee_compileScript(cx, gsr->fn,
  +			fp, NULL, &script, realm->globalObject, &scrobj))
  +	    {
   		gpsee_reportUncaughtException(cx, JSVAL_NULL,
  -					      (gpsee_verbosity(0) >=
  -					       GSR_FORCE_STACK_DUMP_VERBOSITY)
  -					      ||
  -					      ((gpsee_verbosity(0) >=
  -						GPSEE_ERROR_OUTPUT_VERBOSITY)
  -					       && isatty(STDERR_FILENO)));
  -		exitCode = 1;
  +			(gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY)
  +			||
  +			((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY)
  +				&& isatty(STDERR_FILENO)));
  +		ec = 1;
   	    } else {
  -		exitCode = 0;
  +		ec = 0;
   	    }
   	} else {		/* noRunScript is false; run the program */
   
  -	    if (!gpsee_runProgramModule
  -		(cx, scriptFilename, NULL, scriptFile, script_argv,
  -		 script_environ)) {
  +	    if (!gpsee_runProgramModule(cx, gsr->fn,
  +			NULL, fp, gsr->argv, gsr->environ))
  +	    {
   		int code = gpsee_getExceptionExitCode(cx);
   		if (code >= 0) {
  -		    exitCode = code;
  +		    ec = code;
   		} else {
   		    gpsee_reportUncaughtException(cx, JSVAL_NULL,
  -						  (gpsee_verbosity(0) >=
  -						   GSR_FORCE_STACK_DUMP_VERBOSITY)
  -						  ||
  -						  ((gpsee_verbosity(0) >=
  -						    GPSEE_ERROR_OUTPUT_VERBOSITY)
  -						   &&
  -						   isatty(STDERR_FILENO)));
  -		    exitCode = 1;
  +			(gpsee_verbosity(0) >= GSR_FORCE_STACK_DUMP_VERBOSITY)
  +			||
  +			((gpsee_verbosity(0) >= GPSEE_ERROR_OUTPUT_VERBOSITY)
  +				&& isatty(STDERR_FILENO)));
  +		    ec = 1;
   		}
   	    } else {
  -		exitCode = 0;
  +		ec = 0;
   	    }
   	}
  -	fclose(scriptFile);
  -	goto out;
  +	fclose(fp);
  +	goto exit;
       }
   
  -  out:
  +exit:
  +    gsr->code = _free(gsr->code);
  +    gsr->fn = _free(gsr->fn);
  +    gsr->argv = NULL;
  +    gsr->environ = NULL;
  +
  +    optCon = rpmioFini(optCon);
  +
   #ifdef GPSEE_DEBUGGER
       gpsee_finiDebugger(jsdc);
   #endif
   
  -    gpsee_destroyInterpreter(jsi);
  +    gpsee_destroyInterpreter(gsr->I);
  +    gsr->I = I = NULL;
  +
       JS_ShutDown();
   
  -    return exitCode;
  +    return ec;
   }
   
   int main(int argc, char *argv[])
  @@ .
Received on Sun Sep 12 16:32:57 2010
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.