summaryrefslogtreecommitdiffstats
path: root/src/broadcom/cle/v3d_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/broadcom/cle/v3d_decoder.c')
-rw-r--r--src/broadcom/cle/v3d_decoder.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/broadcom/cle/v3d_decoder.c b/src/broadcom/cle/v3d_decoder.c
index ed9cb7dd438..d76c004730b 100644
--- a/src/broadcom/cle/v3d_decoder.c
+++ b/src/broadcom/cle/v3d_decoder.c
@@ -58,6 +58,7 @@ struct location {
struct parser_context {
XML_Parser parser;
+ const struct v3d_device_info *devinfo;
int foo;
struct location loc;
@@ -68,6 +69,9 @@ struct parser_context {
struct v3d_value *values[256];
struct v3d_spec *spec;
+
+ int parse_depth;
+ int parse_skip_depth;
};
const char *
@@ -414,6 +418,25 @@ set_group_opcode(struct v3d_group *group, const char **atts)
return;
}
+static bool
+ver_in_range(int ver, int min_ver, int max_ver)
+{
+ return ((min_ver == 0 || ver >= min_ver) &&
+ (max_ver == 0 || ver <= max_ver));
+}
+
+static bool
+skip_if_ver_mismatch(struct parser_context *ctx, int min_ver, int max_ver)
+{
+ if (!ctx->parse_skip_depth && !ver_in_range(ctx->devinfo->ver,
+ min_ver, max_ver)) {
+ assert(ctx->parse_depth != 0);
+ ctx->parse_skip_depth = ctx->parse_depth;
+ }
+
+ return ctx->parse_skip_depth;
+}
+
static void
start_element(void *data, const char *element_name, const char **atts)
{
@@ -421,6 +444,8 @@ start_element(void *data, const char *element_name, const char **atts)
int i;
const char *name = NULL;
const char *ver = NULL;
+ int min_ver = 0;
+ int max_ver = 0;
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
@@ -429,8 +454,15 @@ start_element(void *data, const char *element_name, const char **atts)
name = atts[i + 1];
else if (strcmp(atts[i], "gen") == 0)
ver = atts[i + 1];
+ else if (strcmp(atts[i], "min_ver") == 0)
+ min_ver = strtoul(atts[i + 1], NULL, 0);
+ else if (strcmp(atts[i], "max_ver") == 0)
+ max_ver = strtoul(atts[i + 1], NULL, 0);
}
+ if (skip_if_ver_mismatch(ctx, min_ver, max_ver))
+ goto skip;
+
if (strcmp(element_name, "vcxml") == 0) {
if (ver == NULL)
fail(&ctx->loc, "no ver given");
@@ -470,6 +502,8 @@ start_element(void *data, const char *element_name, const char **atts)
assert(ctx->nvalues < ARRAY_SIZE(ctx->values));
}
+skip:
+ ctx->parse_depth++;
}
static void
@@ -478,6 +512,14 @@ end_element(void *data, const char *name)
struct parser_context *ctx = data;
struct v3d_spec *spec = ctx->spec;
+ ctx->parse_depth--;
+
+ if (ctx->parse_skip_depth) {
+ if (ctx->parse_skip_depth == ctx->parse_depth)
+ ctx->parse_skip_depth = 0;
+ return;
+ }
+
if (strcmp(name, "packet") == 0 ||
strcmp(name, "struct") == 0 ||
strcmp(name, "register") == 0) {
@@ -603,6 +645,7 @@ v3d_spec_load(const struct v3d_device_info *devinfo)
memset(&ctx, 0, sizeof ctx);
ctx.parser = XML_ParserCreate(NULL);
+ ctx.devinfo = devinfo;
XML_SetUserData(ctx.parser, &ctx);
if (ctx.parser == NULL) {
fprintf(stderr, "failed to create parser\n");