From 293ec4a8813e6d7d68dc147dff102d3a61396515 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 21 May 2010 16:38:55 +0200 Subject: Add --print-dot option to print topology as a dot graph Signed-off-by: Laurent Pinchart --- main.c | 4 ++-- media.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- media.h | 2 +- options.c | 8 +++++++ options.h | 1 + 5 files changed, 92 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index fad538d..164d4e5 100644 --- a/main.c +++ b/main.c @@ -363,8 +363,8 @@ int main(int argc, char **argv) printf("Entity '%s' not found\n", media_opts.entity); } - if (media_opts.print) { - media_print_topology(media); + if (media_opts.print || media_opts.print_dot) { + media_print_topology(media, media_opts.print_dot); printf("\n"); } diff --git a/media.c b/media.c index 81c730c..b2d0ec1 100644 --- a/media.c +++ b/media.c @@ -201,7 +201,78 @@ int media_reset_links(struct media_device *media) return 0; } -void media_print_topology(struct media_device *media) +static void media_print_topology_dot(struct media_device *media) +{ + unsigned int i, j; + + printf("digraph board {\n"); + printf("\trankdir=TB\n"); + + for (i = 0; i < media->entities_count; ++i) { + struct media_entity *entity = &media->entities[i]; + unsigned int npads; + + switch (entity->info.type) { + case MEDIA_ENTITY_TYPE_NODE: + printf("\tn%08x [label=\"%s\", shape=box, style=filled, " + "fillcolor=yellow]\n", + entity->info.id, entity->info.name); + break; + + case MEDIA_ENTITY_TYPE_SUBDEV: + printf("\tn%08x [label=\"{{", entity->info.id); + + for (j = 0, npads = 0; j < entity->info.pads; ++j) { + if (entity->pads[j].type != MEDIA_PAD_TYPE_INPUT) + continue; + + printf("%s %u", npads ? " | " : "", j, j); + npads++; + } + + printf("} | %s | {", entity->info.name); + + for (j = 0, npads = 0; j < entity->info.pads; ++j) { + if (entity->pads[j].type != MEDIA_PAD_TYPE_OUTPUT) + continue; + + printf("%s %u", npads ? " | " : "", j, j); + npads++; + } + + printf("}}\", shape=Mrecord, style=filled, fillcolor=green]\n"); + break; + + default: + continue; + } + + for (j = 0; j < entity->info.links; j++) { + struct media_entity_link *link = &entity->links[j]; + + if (link->source->entity != entity) + continue; + + printf("\tn%08x", link->source->entity->info.id); + if (link->source->entity->info.type == MEDIA_ENTITY_TYPE_SUBDEV) + printf(":port%u", link->source->index); + printf(" -> "); + printf("n%08x", link->sink->entity->info.id); + if (link->sink->entity->info.type == MEDIA_ENTITY_TYPE_SUBDEV) + printf(":port%u", link->sink->index); + + if (link->flags & MEDIA_LINK_FLAG_IMMUTABLE) + printf(" [style=bold]"); + else if (!(link->flags & MEDIA_LINK_FLAG_ACTIVE)) + printf(" [style=dashed]"); + printf("\n"); + } + } + + printf("}\n"); +} + +static void media_print_topology_text(struct media_device *media) { unsigned int i, j, k; unsigned int padding; @@ -244,6 +315,14 @@ void media_print_topology(struct media_device *media) } } +void media_print_topology(struct media_device *media, int dot) +{ + if (dot) + media_print_topology_dot(media); + else + media_print_topology_text(media); +} + static int media_enum_links(struct media_device *media) { __u32 id; diff --git a/media.h b/media.h index 7217403..7dbcc1c 100644 --- a/media.h +++ b/media.h @@ -56,7 +56,7 @@ struct media_entity_pad *media_entity_remote_pad(struct media_entity_pad *pad); struct media_entity *media_get_entity_by_name(struct media_device *media, const char *name, size_t length); -void media_print_topology(struct media_device *media); +void media_print_topology(struct media_device *media, int dot); int media_setup_link(struct media_device *media, struct media_entity_pad *source, struct media_entity_pad *sink, __u32 flags); diff --git a/options.c b/options.c index c607dee..5cc13f2 100644 --- a/options.c +++ b/options.c @@ -40,10 +40,13 @@ static void usage(const char *argv0) printf("-i, --interactive Modify links interactively\n"); printf("-l, --links Comma-separated list of links descriptors to setup\n"); printf("-p, --print-topology Print the device topology (implies -v)\n"); + printf(" --print-dot Print the device topology as a dot graph (implies -v)\n"); printf("-r, --reset Reset all links to inactive\n"); printf("-v, --verbose Be verbose\n"); } +#define OPT_PRINT_DOT 256 + static struct option opts[] = { {"device", 1, 0, 'd'}, {"entity", 1, 0, 'e'}, @@ -51,6 +54,7 @@ static struct option opts[] = { {"help", 0, 0, 'h'}, {"interactive", 0, 0, 'i'}, {"links", 1, 0, 'l'}, + {"print-dot", 0, 0, OPT_PRINT_DOT}, {"print-topology", 0, 0, 'p'}, {"reset", 0, 0, 'r'}, {"verbose", 0, 0, 'v'}, @@ -105,6 +109,10 @@ int parse_cmdline(int argc, char **argv) media_opts.verbose = 1; break; + case OPT_PRINT_DOT: + media_opts.print_dot = 1; + break; + default: printf("Invalid option -%c\n", opt); printf("Run %s -h for help.\n", argv[0]); diff --git a/options.h b/options.h index a490a65..81c9736 100644 --- a/options.h +++ b/options.h @@ -25,6 +25,7 @@ struct media_options const char *devname; unsigned int interactive:1, print:1, + print_dot:1, reset:1, verbose:1; const char *entity; -- cgit v1.2.3