Explorar o código

Extend g.parser to support dependency rules

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@61994 15284696-431f-4ddb-bdfa-cd5b030d7da7
Glynn Clements %!s(int64=10) %!d(string=hai) anos
pai
achega
e3d0133982

+ 2 - 1
general/g.parser/global.h

@@ -6,7 +6,8 @@ enum state
     S_TOPLEVEL,
     S_MODULE,
     S_FLAG,
-    S_OPTION
+    S_OPTION,
+    S_RULES
 };
 
 struct context

+ 3 - 0
general/g.parser/main.c

@@ -129,6 +129,9 @@ int main(int argc, char *argv[])
 	case S_OPTION:
 	    parse_option(&ctx, cmd, arg);
 	    break;
+	case S_RULES:
+	    parse_rule(&ctx, cmd, arg);
+	    break;
 	}
     }
 

+ 5 - 0
general/g.parser/parse.c

@@ -62,6 +62,11 @@ void parse_toplevel(struct context *ctx, const char *cmd)
 	return;
     }
 
+    if (G_strcasecmp(cmd, "rules") == 0) {
+	ctx->state = S_RULES;
+	return;
+    }
+
     fprintf(stderr, _("Unknown command \"%s\" at line %d\n"), cmd, ctx->line);
 }
 

+ 3 - 0
general/g.parser/proto.h

@@ -17,3 +17,6 @@ struct Option *define_standard_option(const char *);
 
 /* translate.c */
 char *translate(const char *);
+
+/* rules.c */
+void parse_rule(struct context *, const char *, const char *);

+ 92 - 0
general/g.parser/rules.c

@@ -0,0 +1,92 @@
+#include <string.h>
+#include "proto.h"
+
+#include <grass/glocale.h>
+
+static void *find_flag(const struct context *ctx, int key)
+{
+    struct Flag *flag;
+
+    for (flag = ctx->first_flag; flag; flag = flag->next_flag)
+	if (flag->key == key)
+	    return flag;
+
+    fprintf(stderr, _("Unknown flag \"-%c\" in rule\n"), key);
+    return NULL;
+}
+
+static void *find_option(const struct context *ctx, const char *key)
+{
+    struct Option *option;
+
+    for (option = ctx->first_option; option; option = option->next_opt)
+	if (G_strcasecmp(option->key, key) == 0)
+	    return option;
+
+    fprintf(stderr, _("Unknown option \"%s\" in rule\n"), key);
+    return NULL;
+}
+
+static void add_rule(struct context *ctx, int type, const char *data)
+{
+    char **tokens;
+    int ntokens;
+    void **opts;
+    int i;
+
+    tokens = G_tokenize(data, ",");
+    ntokens = G_number_of_tokens(tokens);
+    opts = G_malloc(ntokens * sizeof(void *));
+
+    for (i = 0; i < ntokens; i++) {
+	char buf[256];
+	char *name;
+
+	strcpy(buf, tokens[i]);
+	name = G_chop(buf);
+	opts[i] = (name[0] == '-')
+	    ? find_flag(ctx, name[1])
+	    : find_option(ctx, name);
+    }
+
+    G_free_tokens(tokens);
+
+    G__option_rule(type, ntokens, opts);
+}
+
+void parse_rule(struct context *ctx, const char *cmd, const char *arg)
+{
+    if (G_strcasecmp(cmd, "exclusive") == 0) {
+	add_rule(ctx, RULE_EXCLUSIVE, arg);
+	return;
+    }
+
+    if (G_strcasecmp(cmd, "requires") == 0) {
+	add_rule(ctx, RULE_REQUIRES, arg);
+	return;
+    }
+
+    if (G_strcasecmp(cmd, "requires_all") == 0) {
+	add_rule(ctx, RULE_REQUIRES_ALL, arg);
+	return;
+    }
+
+    if (G_strcasecmp(cmd, "excludes") == 0) {
+	add_rule(ctx, RULE_EXCLUDES, arg);
+	return;
+    }
+
+    if (G_strcasecmp(cmd, "collective") == 0) {
+	add_rule(ctx, RULE_COLLECTIVE, arg);
+	return;
+    }
+
+    if (G_strcasecmp(cmd, "end") == 0) {
+	ctx->state = S_TOPLEVEL;
+	return;
+    }
+
+    fprintf(stderr, _("Unknown rule type \"%s\" at line %d\n"),
+	    cmd, ctx->line);
+}
+

+ 6 - 5
include/defs/gis.h

@@ -516,11 +516,12 @@ FILE *G_open_option_file(const struct Option *);
 void G_close_option_file(FILE *);
 
 /* parser_dependencies.c */
-void G_option_exclusive(void *first, ...);
-void G_option_required(void *first, ...);
-void G_option_requires(void *first, ...);
-void G_option_requires_all(void *first, ...);
-void G_option_collective(void *first, ...);
+void G__option_rule(int, int, void **);
+void G_option_exclusive(void *, ...);
+void G_option_required(void *, ...);
+void G_option_requires(void *, ...);
+void G_option_requires_all(void *, ...);
+void G_option_collective(void *, ...);
 
 /* paths.c */
 int G_mkdir(const char *);

+ 10 - 0
include/gis.h

@@ -305,6 +305,16 @@ typedef enum
     G_FLG_V_TOPO,               /*!< do not build topology */
 } STD_FLG;
 
+/* Parser rules for G__option_rule() */
+enum rule_type {
+    RULE_EXCLUSIVE,
+    RULE_REQUIRED,
+    RULE_REQUIRES,
+    RULE_REQUIRES_ALL,
+    RULE_EXCLUDES,
+    RULE_COLLECTIVE
+};
+
 /* Message format */
 #define G_INFO_FORMAT_STANDARD 0	/* GRASS_MESSAGE_FORMAT=standard or not defined */
 #define G_INFO_FORMAT_GUI      1	/* GRASS_MESSAGE_FORMAT=gui */

+ 12 - 15
lib/gis/parser_dependencies.c

@@ -20,15 +20,6 @@
 
 #include "parser_local_proto.h"
 
-enum rule_type {
-    RULE_EXCLUSIVE,
-    RULE_REQUIRED,
-    RULE_REQUIRES,
-    RULE_REQUIRES_ALL,
-    RULE_EXCLUDES,
-    RULE_COLLECTIVE
-};
-
 struct vector {
     size_t elsize;
     size_t increment;
@@ -68,11 +59,21 @@ struct rule {
 
 static struct vector rules = {sizeof(struct rule), 50};
 
+void G__option_rule(int type, int nopts, void **opts)
+{
+    struct rule rule;
+
+    rule.type = type;
+    rule.count = nopts;
+    rule.opts = opts;
+
+    vector_append(&rules, &rule);
+}
+
 static void make_rule(int type, void *first, va_list ap)
 {
     struct vector opts;
     void *opt;
-    struct rule rule;
 
     vector_new(&opts, sizeof(void *), 10);
 
@@ -85,11 +86,7 @@ static void make_rule(int type, void *first, va_list ap)
 	vector_append(&opts, &opt);
     }
 
-    rule.type = type;
-    rule.count = opts.count;
-    rule.opts = (void**) opts.data;
-
-    vector_append(&rules, &rule);
+    G__option_rule(type, opts.count, (void**) opts.data);
 }
 
 static int is_flag(const void *p)