[CRIU] [PATCH v2 10/13] protobuf: "pretty" engine
Kinsbursky Stanislav
skinsbursky at openvz.org
Mon Aug 6 12:11:47 EDT 2012
From: Stanislav Kinsbursky <skinsbursky at openvz.org>
v2:
1) parser updated to properly parse strings like this: "11:%x 1:%d"
Protobuf generic show function now accept a string with pretty specificators.
The string have to look like below (an example):
"0:%d 3:%u"
where numbers with colon specifies field number (the same number as in
proto-file) and "%[a-zA-Z]" specifies output format.
If pretty specificator for specified for a field, then it will be used for
output instead of generic hexidecimal view.
Signed-off-by: Stanislav Kinsbursky <skinsbursky at openvz.org>
---
include/protobuf.h | 6 +++---
protobuf.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 46 insertions(+), 6 deletions(-)
-------------- next part --------------
diff --git a/include/protobuf.h b/include/protobuf.h
index e13c3e4..2607c06 100644
--- a/include/protobuf.h
+++ b/include/protobuf.h
@@ -61,14 +61,14 @@ extern int pb_write_object_with_header(int fd, void *obj,
extern void do_pb_show_plain(int fd, const ProtobufCMessageDescriptor *d,
pb_unpack_t unpack, pb_free_t free, int single_entry,
void (*payload_hadler)(int fd, void *obj, int flags),
- int flags);
+ int flags, const char *pretty_fmt);
/* Don't have objects at hands to also do typechecking here */
#define pb_show_plain_payload(__fd, __proto_message_name, payload_hadler, flags) \
do_pb_show_plain(__fd, &__proto_message_name##__descriptor, \
(pb_unpack_t)__proto_message_name##__unpack, \
(pb_free_t)__proto_message_name##__free_unpacked, \
- 0, payload_hadler, flags)
+ 0, payload_hadler, flags, NULL)
#define pb_show_plain(__fd, __proto_message_name) \
pb_show_plain_payload(__fd, __proto_message_name, NULL, 0)
@@ -77,6 +77,6 @@ extern void do_pb_show_plain(int fd, const ProtobufCMessageDescriptor *d,
do_pb_show_plain(__fd, &__proto_message_name##__descriptor, \
(pb_unpack_t)__proto_message_name##__unpack, \
(pb_free_t)__proto_message_name##__free_unpacked, \
- 1, NULL, 0)
+ 1, NULL, 0, NULL)
#endif /* PROTOBUF_H__ */
diff --git a/protobuf.c b/protobuf.c
index 50ce9af..647786f 100644
--- a/protobuf.c
+++ b/protobuf.c
@@ -10,6 +10,7 @@
#include "types.h"
#include "log.h"
#include "util.h"
+#include "string.h"
#include "protobuf.h"
@@ -22,7 +23,9 @@
struct pb_pr_field_s {
void *data;
+ int number;
int depth;
+ char fmt[32];
};
typedef struct pb_pr_field_s pb_pr_field_t;
@@ -30,6 +33,7 @@ typedef struct pb_pr_field_s pb_pr_field_t;
struct pb_pr_ctrl_s {
void *arg;
int single_entry;
+ const char *pretty_fmt;
pb_pr_field_t cur;
};
@@ -150,6 +154,34 @@ static size_t pb_show_prepare_field_context(const ProtobufCFieldDescriptor *fd,
return fsize;
}
+static void pb_show_pretty(pb_pr_field_t *field)
+{
+ pr_msg(field->fmt, *(long *)field->data);
+}
+
+static int pb_field_show_pretty(pb_pr_ctl_t *ctl)
+{
+ pb_pr_field_t *field = &ctl->cur;
+ int found;
+ char cookie[32];
+ const char *ptr;
+
+ if (!ctl->pretty_fmt)
+ return 0;
+
+ sprintf(cookie, " %d:", field->number);
+ if (!strncmp(ctl->pretty_fmt, &cookie[1], strlen(&cookie[1])))
+ ptr = ctl->pretty_fmt;
+ else {
+ ptr = strstr(ctl->pretty_fmt, cookie);
+ if (!ptr)
+ return 0;
+ }
+ found = sscanf(ptr, "%*[ 1-9:]%s", field->fmt);
+ BUG_ON(found > 1);
+ return found;
+}
+
static pb_pr_show_t get_pb_show_function(int type)
{
switch (type) {
@@ -182,6 +214,13 @@ static pb_pr_show_t get_pb_show_function(int type)
return pb_msg_unk;
}
+static pb_pr_show_t get_show_function(int type, pb_pr_ctl_t *ctl)
+{
+ if (pb_field_show_pretty(ctl))
+ return pb_show_pretty;
+ return get_pb_show_function(type);
+}
+
static void do_show_field(pb_pr_ctl_t *ctl, int nr_fields, pb_pr_show_t show,
size_t fsize)
{
@@ -210,7 +249,7 @@ static void pb_show_field(const ProtobufCFieldDescriptor *fd,
print_tabs(ctl);
pr_msg("%s: ", fd->name);
- show = get_pb_show_function(fd->type);
+ show = get_show_function(fd->type, ctl);
do_show_field(ctl, nr_fields, show, pb_show_prepare_field_context(fd, ctl));
}
@@ -259,6 +298,7 @@ static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl)
}
ctl->cur.data = data;
+ ctl->cur.number = i + 1;
pb_show_field(&fd, nr_fields, ctl);
}
@@ -269,9 +309,9 @@ static inline void pb_no_payload(int fd, void *obj, int flags) { }
void do_pb_show_plain(int fd, const ProtobufCMessageDescriptor *md,
pb_unpack_t unpack, pb_free_t free, int single_entry,
void (*payload_hadler)(int fd, void *obj, int flags),
- int flags)
+ int flags, const char *pretty_fmt)
{
- pb_pr_ctl_t ctl = {NULL, single_entry};
+ pb_pr_ctl_t ctl = {NULL, single_entry, pretty_fmt};
void (*handle_payload)(int fd, void *obj, int flags);
handle_payload = (payload_hadler) ? : pb_no_payload;
More information about the CRIU
mailing list