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 - 17:23:06 CEST
Message-Id: <20100912152307.023E7C10F8@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 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
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.