[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