Commit 3904b402 authored by Stanislav Kinsbursky's avatar Stanislav Kinsbursky Committed by Pavel Emelyanov

protobuf: "pretty" engine

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: 's avatarStanislav Kinsbursky <skinsbursky@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 50ff74ff
...@@ -80,16 +80,16 @@ extern int pb_write_one(int fd, void *obj, int type); ...@@ -80,16 +80,16 @@ extern int pb_write_one(int fd, void *obj, int type);
extern void do_pb_show_plain(int fd, int type, int single_entry, extern void do_pb_show_plain(int fd, int type, int single_entry,
void (*payload_hadler)(int fd, void *obj, int flags), void (*payload_hadler)(int fd, void *obj, int flags),
int flags); int flags, const char *pretty_fmt);
#define pb_show_plain_payload(__fd, __type, payload_hadler, flags) \ #define pb_show_plain_payload(__fd, __type, payload_hadler, flags) \
do_pb_show_plain(__fd, __type, 0, payload_hadler, flags) do_pb_show_plain(__fd, __type, 0, payload_hadler, flags, NULL)
#define pb_show_plain(__fd, __type) \ #define pb_show_plain(__fd, __type) \
pb_show_plain_payload(__fd, __type, NULL, 0) pb_show_plain_payload(__fd, __type, NULL, 0)
#define pb_show_vertical(__fd, __type) \ #define pb_show_vertical(__fd, __type) \
do_pb_show_plain(__fd, __type, 1, NULL, 0) do_pb_show_plain(__fd, __type, 1, NULL, 0, NULL)
int collect_image(int fd_t, int obj_t, unsigned size, int collect_image(int fd_t, int obj_t, unsigned size,
int (*collect)(void *obj, ProtobufCMessage *msg)); int (*collect)(void *obj, ProtobufCMessage *msg));
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "types.h" #include "types.h"
#include "log.h" #include "log.h"
#include "util.h" #include "util.h"
#include "string.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/inventory.pb-c.h" #include "protobuf/inventory.pb-c.h"
...@@ -129,7 +130,10 @@ void cr_pb_init(void) ...@@ -129,7 +130,10 @@ void cr_pb_init(void)
struct pb_pr_field_s { struct pb_pr_field_s {
void *data; void *data;
int number;
int depth; int depth;
int count;
char fmt[32];
}; };
typedef struct pb_pr_field_s pb_pr_field_t; typedef struct pb_pr_field_s pb_pr_field_t;
...@@ -137,30 +141,35 @@ typedef struct pb_pr_field_s pb_pr_field_t; ...@@ -137,30 +141,35 @@ typedef struct pb_pr_field_s pb_pr_field_t;
struct pb_pr_ctrl_s { struct pb_pr_ctrl_s {
void *arg; void *arg;
int single_entry; int single_entry;
const char *pretty_fmt;
pb_pr_field_t cur; pb_pr_field_t cur;
}; };
typedef struct pb_pr_ctrl_s pb_pr_ctl_t; typedef struct pb_pr_ctrl_s pb_pr_ctl_t;
typedef void (*pb_pr_show_t)(pb_pr_field_t *field); typedef int (*pb_pr_show_t)(pb_pr_field_t *field);
static void pb_msg_int32x(pb_pr_field_t *field) static int pb_msg_int32x(pb_pr_field_t *field)
{ {
pr_msg("%#x", *(int *)field->data); pr_msg("%#x", *(int *)field->data);
return 0;
} }
static void pb_msg_int64x(pb_pr_field_t *field) static int pb_msg_int64x(pb_pr_field_t *field)
{ {
pr_msg("%#016lx", *(long *)field->data); pr_msg("%#016lx", *(long *)field->data);
return 0;
} }
static void pb_msg_string(pb_pr_field_t *field) static int pb_msg_string(pb_pr_field_t *field)
{ {
pr_msg("\"%s\"", *(char **)field->data); pr_msg("\"%s\"", *(char **)field->data);
return 0;
} }
static void pb_msg_unk(pb_pr_field_t *field) static int pb_msg_unk(pb_pr_field_t *field)
{ {
pr_msg("unknown object %p", field->data); pr_msg("unknown object %p", field->data);
return 0;
} }
static inline void print_tabs(pb_pr_ctl_t *ctl) static inline void print_tabs(pb_pr_ctl_t *ctl)
...@@ -183,7 +192,7 @@ static void print_nested_message_braces(pb_pr_ctl_t *ctl, int right_brace) ...@@ -183,7 +192,7 @@ static void print_nested_message_braces(pb_pr_ctl_t *ctl, int right_brace)
static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl); static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl);
static void show_nested_message(pb_pr_field_t *field) static int show_nested_message(pb_pr_field_t *field)
{ {
pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur); pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur);
...@@ -192,9 +201,10 @@ static void show_nested_message(pb_pr_field_t *field) ...@@ -192,9 +201,10 @@ static void show_nested_message(pb_pr_field_t *field)
pb_show_msg(field->data, ctl); pb_show_msg(field->data, ctl);
field->depth--; field->depth--;
print_nested_message_braces(ctl, 1); print_nested_message_braces(ctl, 1);
return 0;
} }
static void show_enum(pb_pr_field_t *field) static int show_enum(pb_pr_field_t *field)
{ {
pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur); pb_pr_ctl_t *ctl = container_of(field, pb_pr_ctl_t, cur);
ProtobufCEnumDescriptor *d = ctl->arg; ProtobufCEnumDescriptor *d = ctl->arg;
...@@ -212,9 +222,10 @@ static void show_enum(pb_pr_field_t *field) ...@@ -212,9 +222,10 @@ static void show_enum(pb_pr_field_t *field)
pr_msg("%s", val_name); pr_msg("%s", val_name);
else else
pr_msg("%d", val); pr_msg("%d", val);
return 0;
} }
static void show_bool(pb_pr_field_t *field) static int show_bool(pb_pr_field_t *field)
{ {
protobuf_c_boolean val = *(protobuf_c_boolean *)field->data; protobuf_c_boolean val = *(protobuf_c_boolean *)field->data;
...@@ -222,6 +233,7 @@ static void show_bool(pb_pr_field_t *field) ...@@ -222,6 +233,7 @@ static void show_bool(pb_pr_field_t *field)
pr_msg("True"); pr_msg("True");
else else
pr_msg("False"); pr_msg("False");
return 0;
} }
static size_t pb_show_prepare_field_context(const ProtobufCFieldDescriptor *fd, static size_t pb_show_prepare_field_context(const ProtobufCFieldDescriptor *fd,
...@@ -267,6 +279,35 @@ static size_t pb_show_prepare_field_context(const ProtobufCFieldDescriptor *fd, ...@@ -267,6 +279,35 @@ static size_t pb_show_prepare_field_context(const ProtobufCFieldDescriptor *fd,
return fsize; return fsize;
} }
static int pb_show_pretty(pb_pr_field_t *field)
{
pr_msg(field->fmt, *(long *)field->data);
return 0;
}
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) static pb_pr_show_t get_pb_show_function(int type)
{ {
switch (type) { switch (type) {
...@@ -299,13 +340,25 @@ static pb_pr_show_t get_pb_show_function(int type) ...@@ -299,13 +340,25 @@ static pb_pr_show_t get_pb_show_function(int type)
return pb_msg_unk; 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 pb_show_repeated(pb_pr_ctl_t *ctl, int nr_fields, pb_pr_show_t show, static void pb_show_repeated(pb_pr_ctl_t *ctl, int nr_fields, pb_pr_show_t show,
size_t fsize) size_t fsize)
{ {
pb_pr_field_t *field = &ctl->cur; pb_pr_field_t *field = &ctl->cur;
unsigned long counter; unsigned long counter;
int done;
field->count = nr_fields;
done = show(field);
if (done)
return;
show(field);
field->data += fsize; field->data += fsize;
for (counter = 0; counter < nr_fields - 1; counter++, field->data += fsize) { for (counter = 0; counter < nr_fields - 1; counter++, field->data += fsize) {
...@@ -322,7 +375,7 @@ static void pb_show_field(const ProtobufCFieldDescriptor *fd, ...@@ -322,7 +375,7 @@ static void pb_show_field(const ProtobufCFieldDescriptor *fd,
print_tabs(ctl); print_tabs(ctl);
pr_msg("%s: ", fd->name); pr_msg("%s: ", fd->name);
show = get_pb_show_function(fd->type); show = get_show_function(fd->type, ctl);
pb_show_repeated(ctl, nr_fields, show, pb_show_prepare_field_context(fd, ctl)); pb_show_repeated(ctl, nr_fields, show, pb_show_prepare_field_context(fd, ctl));
...@@ -376,6 +429,7 @@ static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl) ...@@ -376,6 +429,7 @@ static void pb_show_msg(const void *msg, pb_pr_ctl_t *ctl)
} }
ctl->cur.data = data; ctl->cur.data = data;
ctl->cur.number = i + 1;
pb_show_field(&fd, nr_fields, ctl); pb_show_field(&fd, nr_fields, ctl);
} }
...@@ -385,9 +439,9 @@ static inline void pb_no_payload(int fd, void *obj, int flags) { } ...@@ -385,9 +439,9 @@ static inline void pb_no_payload(int fd, void *obj, int flags) { }
void do_pb_show_plain(int fd, int type, int single_entry, void do_pb_show_plain(int fd, int type, int single_entry,
void (*payload_hadler)(int fd, void *obj, int flags), 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); void (*handle_payload)(int fd, void *obj, int flags);
if (!cr_pb_descs[type].pb_desc) { if (!cr_pb_descs[type].pb_desc) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment