[GRASS-SVN] r37934 - in grass/trunk: general/g.parser lib/python

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Jun 18 15:31:29 EDT 2009


Author: glynn
Date: 2009-06-18 15:31:29 -0400 (Thu, 18 Jun 2009)
New Revision: 37934

Modified:
   grass/trunk/general/g.parser/main.c
   grass/trunk/lib/python/core.py
Log:
Change Python/g.parser interface to avoid need to re-invoke script


Modified: grass/trunk/general/g.parser/main.c
===================================================================
--- grass/trunk/general/g.parser/main.c	2009-06-18 18:51:11 UTC (rev 37933)
+++ grass/trunk/general/g.parser/main.c	2009-06-18 19:31:29 UTC (rev 37934)
@@ -255,12 +255,98 @@
 	    cmd, ctx->line);
 }
 
+static int print_options(const struct context *ctx)
+{
+    struct Option *option;
+    struct Flag *flag;
+    const char *overwrite = getenv("GRASS_OVERWRITE");
+    const char *verbose = getenv("GRASS_VERBOSE");
+
+    printf("@ARGS_PARSED@\n");
+
+    if (overwrite)
+	printf("GRASS_OVERWRITE=%s\n", overwrite);
+
+    if (verbose)
+	printf("GRASS_VERBOSE=%s\n", verbose);
+
+    for (flag = ctx->first_flag; flag; flag = flag->next_flag)
+	printf("flag_%c=%d\n", flag->key, flag->answer ? 1 : 0);
+
+    for (option = ctx->first_option; option; option = option->next_opt)
+	printf("opt_%s=%s\n", option->key,
+	       option->answer ? option->answer : "");
+
+    return 0;
+}
+
+static int reinvoke_script(const struct context *ctx, const char *filename)
+{
+    struct Option *option;
+    struct Flag *flag;
+
+    /* Because shell from MINGW and CygWin converts all variables
+     * to uppercase it was necessary to use uppercase variables.
+     * Set both until all scripts are updated */
+    for (flag = ctx->first_flag; flag; flag = flag->next_flag) {
+	char buff[16];
+
+	sprintf(buff, "GIS_FLAG_%c=%d", flag->key, flag->answer ? 1 : 0);
+	putenv(G_store(buff));
+
+	sprintf(buff, "GIS_FLAG_%c=%d", toupper(flag->key),
+		flag->answer ? 1 : 0);
+
+	G_debug(2, "set %s", buff);
+	putenv(G_store(buff));
+    }
+
+    for (option = ctx->first_option; option; option = option->next_opt) {
+	char buff[4096], upper[4096];
+
+	sprintf(buff, "GIS_OPT_%s=%s", option->key,
+		option->answer ? option->answer : "");
+	putenv(G_store(buff));
+
+	strcpy(upper, option->key);
+	G_str_to_upper(upper);
+	sprintf(buff, "GIS_OPT_%s=%s", upper,
+		option->answer ? option->answer : "");
+
+	G_debug(2, "set %s", buff);
+	putenv(G_store(buff));
+    }
+
+#ifdef __MINGW32__
+    {
+	/* execlp() and _spawnlp ( _P_OVERLAY,..) do not work, they return 
+	 * immediately and that breaks scripts running GRASS scripts
+	 * because they dont wait until GRASS script finished */
+	/* execlp( "sh", "sh", filename, "@ARGS_PARSED@", NULL); */
+	/* _spawnlp ( _P_OVERLAY, filename, filename, "@ARGS_PARSED@", NULL ); */
+	int ret;
+
+	ret = _spawnlp(_P_WAIT, filename, filename, "@ARGS_PARSED@", NULL);
+	G_debug(1, "ret = %d", ret);
+	if (ret == -1) {
+	    perror("_spawnlp() failed");
+	    return 1;
+	}
+	return ret;
+    }
+#else
+    execl(filename, filename, "@ARGS_PARSED@", NULL);
+
+    perror("execl() failed");
+    return 1;
+#endif
+}
+
 int main(int argc, char *argv[])
 {
     struct context ctx;
-    struct Option *option;
-    struct Flag *flag;
     const char *filename;
+    int standard_output = 0;
 
     ctx.module = NULL;
     ctx.option = NULL;
@@ -274,18 +360,25 @@
     if (argc >= 2 && (strcmp(argv[1], "-t") == 0)) {
 	/* Turn on translation output */
 	translate_output = 1;
+	argv++, argc--;
     }
 
-    if ((argc < 2 + translate_output) || (argc >= 2 &&
-					  ((strcmp(argv[1], "help") == 0) ||
-					   (strcmp(argv[1], "-help") == 0) ||
-					   (strcmp(argv[1], "--help") == 0)))) {
+    if (argc >= 2 && (strcmp(argv[1], "-s") == 0)) {
+	/* write to stdout rather than re-invoking */
+	standard_output = 1;
+	argv++, argc--;
+    }
+
+    if ((argc < 2) || ((strcmp(argv[1], "help") == 0) ||
+		       (strcmp(argv[1], "-help") == 0) ||
+		       (strcmp(argv[1], "--help") == 0))) {
 	fprintf(stderr, "Usage: %s [-t] <filename> [<argument> ...]\n",
 		argv[0]);
 	return 1;
     }
 
-    filename = argv[1 + translate_output];
+    filename = argv[1];
+    argv++, argc--;
     G_debug(2, "filename = %s", filename);
 
     ctx.fp = fopen(filename, "r");
@@ -351,62 +444,12 @@
     if (translate_output)
 	return EXIT_SUCCESS;
 
-    if (G_parser(argc - 1, argv + 1))
+    if (G_parser(argc, argv))
 	return 1;
 
-    /* Because shell from MINGW and CygWin converts all variables
-     * to uppercase it was necessary to use uppercase variables.
-     * Set both until all scripts are updated */
-    for (flag = ctx.first_flag; flag; flag = flag->next_flag) {
-	char buff[16];
+    return standard_output
+	? print_options(&ctx)
+	: reinvoke_script(&ctx, filename);
 
-	sprintf(buff, "GIS_FLAG_%c=%d", flag->key, flag->answer ? 1 : 0);
-	putenv(G_store(buff));
-
-	sprintf(buff, "GIS_FLAG_%c=%d", toupper(flag->key),
-		flag->answer ? 1 : 0);
-
-	G_debug(2, "set %s", buff);
-	putenv(G_store(buff));
-    }
-
-    for (option = ctx.first_option; option; option = option->next_opt) {
-	char buff[4096], upper[4096];
-
-	sprintf(buff, "GIS_OPT_%s=%s", option->key,
-		option->answer ? option->answer : "");
-	putenv(G_store(buff));
-
-	strcpy(upper, option->key);
-	G_str_to_upper(upper);
-	sprintf(buff, "GIS_OPT_%s=%s", upper,
-		option->answer ? option->answer : "");
-
-	G_debug(2, "set %s", buff);
-	putenv(G_store(buff));
-    }
-
-#ifdef __MINGW32__
-    {
-	/* execlp() and _spawnlp ( _P_OVERLAY,..) do not work, they return 
-	 * immediately and that breaks scripts running GRASS scripts
-	 * because they dont wait until GRASS script finished */
-	/* execlp( "sh", "sh", filename, "@ARGS_PARSED@", NULL); */
-	/* _spawnlp ( _P_OVERLAY, filename, filename, "@ARGS_PARSED@", NULL ); */
-	int ret;
-
-	ret = _spawnlp(_P_WAIT, filename, filename, "@ARGS_PARSED@", NULL);
-	G_debug(1, "ret = %d", ret);
-	if (ret == -1) {
-	    perror("_spawnlp() failed");
-	    return 1;
-	}
-	return ret;
-    }
-#else
-    execl(filename, filename, "@ARGS_PARSED@", NULL);
-
-    perror("execl() failed");
-    return 1;
-#endif
+    return 0;
 }

Modified: grass/trunk/lib/python/core.py
===================================================================
--- grass/trunk/lib/python/core.py	2009-06-18 18:51:11 UTC (rev 37933)
+++ grass/trunk/lib/python/core.py	2009-06-18 19:31:29 UTC (rev 37934)
@@ -333,16 +333,27 @@
 
 # interface to g.parser
 
-def _parse_env():
+def _parse_opts(lines):
     options = {}
     flags = {}
-    for var, val in os.environ.iteritems():
-	if var.startswith("GIS_OPT_"):
-	    opt = var.replace("GIS_OPT_", "", 1).lower()
-	    options[opt] = val;
-	if var.startswith("GIS_FLAG_"):
-	    flg = var.replace("GIS_FLAG_", "", 1).lower()
-	    flags[flg] = bool(int(val));
+    for line in lines:
+	line = line.rstrip('\r\n')
+	if not line:
+	    break
+	try:
+	    [var, val] = line.split('=', 1)
+	except:
+	    raise SyntaxError("invalid output from g.parser: %s" % line)
+
+	if var.startswith('flag_'):
+	    flags[var[5:]] = bool(int(val))
+	elif var.startswith('opt_'):
+	    options[var[4:]] = val
+	elif var in ['GRASS_OVERWRITE', 'GRASS_VERBOSE']:
+	    os.environ[var] = val
+	else:
+	    raise SyntaxError("invalid output from g.parser: %s" % line)
+
     return (options, flags)
 
 def parser():
@@ -363,9 +374,6 @@
         print >> sys.stderr, "You must be in GRASS GIS to run this program."
         sys.exit(1)
 
-    if len(sys.argv) > 1 and sys.argv[1] == "@ARGS_PARSED@":
-	return _parse_env()
-
     cmdline = [basename(sys.argv[0])]
     cmdline += ['"' + arg + '"' for arg in sys.argv[1:]]
     os.environ['CMDLINE'] = ' '.join(cmdline)
@@ -378,12 +386,16 @@
 	else:
 	    argv[0] = os.path.join(sys.path[0], name)
 
-    if sys.platform == "win32":
-       os.execvp("g.parser.exe", [name] + argv)
-    else:
-       os.execvp("g.parser", [name] + argv)
-    raise OSError("error executing g.parser")
+    p = Popen(['g.parser', '-s'] + argv, stdout = PIPE)
+    s = p.communicate()[0]
+    lines = s.splitlines()
 
+    if not lines or lines[0].rstrip('\r\n') != "@ARGS_PARSED@":
+	sys.stdout.write(s)
+	sys.exit()
+
+    return _parse_opts(lines[1:])
+
 # interface to g.tempfile
 
 def tempfile():



More information about the grass-commit mailing list