// Locale
const char* locale;
+
+ // Check Only?
+ unsigned int check;
} td_client_ctx;
enum {
OPT_UNTIL = 5,
OPT_OMIT_TITLE = 6,
OPT_LOCALE = 7,
+ OPT_CHECK = 8,
};
static struct argp_option options[] = {
+ { "check", OPT_CHECK, NULL, 0, "Don't render, only check if it can be rendered", 0 },
+
{ "format", OPT_FORMAT, "FORMAT", 0, "Output Format", 0 },
{ "height", OPT_HEIGHT, "PIXELS", 0, "Height of the output image", 1 },
{ "width", OPT_WIDTH, "PIXELS", 0, "Width of the output image", 1 },
ctx->locale = arg;
break;
+ case OPT_CHECK:
+ ctx->check = 1;
+ break;
+
// Called for each argument
case ARGP_KEY_ARG:
// Take the graph name as first argument
goto ERROR;
}
+ // Check Only?
+ if (ctx->check) {
+ r = sd_bus_message_append(m, "{sv}", "check", "b", 1);
+ if (r < 0)
+ goto ERROR;
+ }
+
// Close the array
r = sd_bus_message_close_container(m);
if (r < 0)
goto ERROR;
}
- // Render the graph
+ // Render
r = render(&ctx);
ERROR:
# #
#############################################################################*/
+#include <stdbool.h>
#include <stdlib.h>
#include <systemd/sd-bus.h>
// Flags
int omit_title = 0;
+ int check = 0;
// Open the options array
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
r = sd_bus_message_read(m, "v", "s", &options.locale);
if (r < 0)
goto ERROR;
+
+ } else if (td_string_equals(key, "check")) {
+ r = sd_bus_message_read(m, "v", "b", &check);
+ if (r < 0)
+ goto ERROR;
+
+ if (check)
+ options.flags |= TD_GRAPH_CHECK;
}
// Leave the container
goto ERROR;
}
- // Render the graph
- r = td_graph_render(graph, object, &options, &buffer, &length);
- if (r < 0)
- goto ERROR;
-
// Make the reply message
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
goto ERROR;
+ // Check Only?
+ if (options.flags & TD_GRAPH_CHECK) {
+ r = td_graph_can_render(graph, object, &options);
+ switch (r) {
+ // Can Render
+ case 0:
+ break;
+
+ // Cannot Render
+ case 1:
+ break;
+
+ // Raise any errors
+ default:
+ goto ERROR;
+ }
+ if (r < 0)
+ goto ERROR;
+
+ // Render the graph
+ } else {
+ r = td_graph_render(graph, object, &options, &buffer, &length);
+ if (r < 0)
+ goto ERROR;
+ }
+
// Append the graph
r = sd_bus_message_append_array(reply, 'y', buffer, length);
if (r < 0)
SD_BUS_VTABLE_START(0),
// Operations
- SD_BUS_METHOD_WITH_ARGS("Render", SD_BUS_ARGS("a{sv}", options), SD_BUS_RESULT("ay", graph),
+ SD_BUS_METHOD_WITH_ARGS("Render", SD_BUS_ARGS("a{sv}", options), SD_BUS_RESULT("a{sv}", graph),
td_graph_bus_render, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
return 0;
}
+int td_graph_can_render(td_graph* self, const char* object,
+ const td_graph_render_options* options) {
+ // If we don't have a check function, we just assume that we can render
+ if (!self->impl->can_render)
+ return 1;
+
+ // Check if this can be rendered
+ return self->impl->can_render(self->ctx, self, options, object);
+}
+
int td_graph_render(td_graph* self, const char* object,
const td_graph_render_options* options, char** buffer, size_t* length) {
td_args* args = NULL;
return -ENOTSUP;
// Check if this can be rendered
- if (self->impl->can_render) {
- r = self->impl->can_render(self->ctx, self, options, object);
- if (r < 0)
+ r = td_graph_can_render(self, object, options);
+ switch (r) {
+ // Cannot render
+ case 0:
+ r = -ENODATA;
+ break;
+
+ // Can render
+ case 1:
+ break;
+
+ // Raise any errors
+ default:
goto ERROR;
}
// Flags
enum {
- TD_GRAPH_OMIT_TITLE = (1 << 0),
+ TD_GRAPH_CHECK = (1 << 0),
+ TD_GRAPH_OMIT_TITLE = (1 << 1),
} flags;
} td_graph_render_options;
int td_graph_load_sources(td_graph* self,
td_args* args, const char* name, const char** objects);
+int td_graph_can_render(td_graph* self, const char* object,
+ const td_graph_render_options* options);
int td_graph_render(td_graph* self, const char* object,
const td_graph_render_options* options, char** buffer, size_t* length);