diff options
-rw-r--r-- | lib9p/9p.generated.c | 66 | ||||
-rw-r--r-- | lib9p/protogen/c_format.py | 37 | ||||
-rw-r--r-- | lib9p/tests/testclient-p9p.explog | 14 |
3 files changed, 95 insertions, 22 deletions
diff --git a/lib9p/9p.generated.c b/lib9p/9p.generated.c index ec8b066..284a0a6 100644 --- a/lib9p/9p.generated.c +++ b/lib9p/9p.generated.c @@ -4665,7 +4665,6 @@ static void lib9p_fid_format(lib9p_fid_t *self, struct fmt_state *state) { } static void lib9p_s_format(struct lib9p_s *self, struct fmt_state *state) { - /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat" #pragma GCC diagnostic ignored "-Wformat-extra-args" @@ -5273,7 +5272,18 @@ static void lib9p_msg_Rread_format(struct lib9p_msg_Rread *self, struct fmt_stat lib9p_tag_format(&self->tag, state); fmt_state_puts(state, " count="); fmt_state_printf(state, "%"PRIu32, self->count); - fmt_state_puts(state, " data=<bytedata>"); + if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_state_printf(state, " data=%.*q%s", + (int)(self->count < 50 ? self->count : 50), + (char *)self->data, + self->count < 50 ? "" : "..."); +#pragma GCC diagnostic pop + } else { + fmt_state_puts(state, " data=<bytedata>"); + } fmt_state_puts(state, " }"); } @@ -5287,7 +5297,18 @@ static void lib9p_msg_Twrite_format(struct lib9p_msg_Twrite *self, struct fmt_st fmt_state_printf(state, "%"PRIu64, self->offset); fmt_state_puts(state, " count="); fmt_state_printf(state, "%"PRIu32, self->count); - fmt_state_puts(state, " data=<bytedata>"); + if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_state_printf(state, " data=%.*q%s", + (int)(self->count < 50 ? self->count : 50), + (char *)self->data, + self->count < 50 ? "" : "..."); +#pragma GCC diagnostic pop + } else { + fmt_state_puts(state, " data=<bytedata>"); + } fmt_state_puts(state, " }"); } @@ -7086,7 +7107,18 @@ static void lib9p_msg_Rreaddir_format(struct lib9p_msg_Rreaddir *self, struct fm lib9p_tag_format(&self->tag, state); fmt_state_puts(state, " count="); fmt_state_printf(state, "%"PRIu32, self->count); - fmt_state_puts(state, " data=<bytedata>"); + if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_state_printf(state, " data=%.*q%s", + (int)(self->count < 50 ? self->count : 50), + (char *)self->data, + self->count < 50 ? "" : "..."); +#pragma GCC diagnostic pop + } else { + fmt_state_puts(state, " data=<bytedata>"); + } fmt_state_puts(state, " }"); } @@ -7302,7 +7334,18 @@ static void lib9p_msg_Rsread_format(struct lib9p_msg_Rsread *self, struct fmt_st lib9p_tag_format(&self->tag, state); fmt_state_puts(state, " count="); fmt_state_printf(state, "%"PRIu32, self->count); - fmt_state_puts(state, " data=<bytedata>"); + if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_state_printf(state, " data=%.*q%s", + (int)(self->count < 50 ? self->count : 50), + (char *)self->data, + self->count < 50 ? "" : "..."); +#pragma GCC diagnostic pop + } else { + fmt_state_puts(state, " data=<bytedata>"); + } fmt_state_puts(state, " }"); } @@ -7323,7 +7366,18 @@ static void lib9p_msg_Tswrite_format(struct lib9p_msg_Tswrite *self, struct fmt_ fmt_state_puts(state, " ]"); fmt_state_puts(state, " count="); fmt_state_printf(state, "%"PRIu32, self->count); - fmt_state_puts(state, " data=<bytedata>"); + if (is_valid_utf8_without_nul((uint8_t *)self->data, (size_t)self->count)) { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wformat-extra-args" + fmt_state_printf(state, " data=%.*q%s", + (int)(self->count < 50 ? self->count : 50), + (char *)self->data, + self->count < 50 ? "" : "..."); +#pragma GCC diagnostic pop + } else { + fmt_state_puts(state, " data=<bytedata>"); + } fmt_state_puts(state, " }"); } diff --git a/lib9p/protogen/c_format.py b/lib9p/protogen/c_format.py index a1bcbf3..4a809d1 100644 --- a/lib9p/protogen/c_format.py +++ b/lib9p/protogen/c_format.py @@ -21,6 +21,19 @@ def bf_numname(typ: idl.Bitfield, num: idl.BitNum, base: str) -> str: return c9util.Ident(c9util.add_prefix(prefix, base)) +def ext_printf(line: str) -> str: + assert line.startswith("\t") + assert line.endswith("\n") + # It sucks that %v trips -Wformat and -Wformat-extra-args + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 + ret = "#pragma GCC diagnostic push\n" + ret += '#pragma GCC diagnostic ignored "-Wformat"\n' + ret += '#pragma GCC diagnostic ignored "-Wformat-extra-args"\n' + ret += line + ret += "#pragma GCC diagnostic pop\n" + return ret + + def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str: ret = """ /* *_format *******************************************************************/ @@ -93,12 +106,9 @@ def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str: ret += "\t\tfmt_state_putchar(state, '0');\n" ret += "\tfmt_state_putchar(state, ')');\n" case idl.Struct(typname="s"): # SPECIAL(string) - ret += "\t/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47781 */\n" - ret += "#pragma GCC diagnostic push\n" - ret += '#pragma GCC diagnostic ignored "-Wformat"\n' - ret += '#pragma GCC diagnostic ignored "-Wformat-extra-args"\n' - ret += '\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n' - ret += "#pragma GCC diagnostic pop\n" + ret += ext_printf( + '\tfmt_state_printf(state, "%.*q", self->len, self->utf8);\n' + ) case idl.Struct(): # and idl.Message(): if isinstance(typ, idl.Message): ret += f'\tfmt_state_puts(state, "{typ.typname} {{");\n' @@ -109,15 +119,24 @@ def gen_c_format(versions: set[str], typs: list[idl.UserType]) -> str: continue ret += cutil.ifdef_push(2, c9util.ver_ifdef(member.in_versions)) if member.cnt: - if member.typ.static_size == 1: # SPECIAL (data) - ret += f'\tfmt_state_puts(state, " {member.membname}=<bytedata>");\n' - continue if isinstance(member.cnt, int): cnt_str = str(member.cnt) cnt_typ = "size_t" else: cnt_str = f"self->{member.cnt.membname}" cnt_typ = c9util.typename(member.cnt.typ) + if member.typ.static_size == 1: # SPECIAL (data) + ret += f"\tif (is_valid_utf8_without_nul((uint8_t *)self->{member.membname}, (size_t){cnt_str})) {{\n" + ret += ext_printf( + f'\t\tfmt_state_printf(state, " {member.membname}=%.*q%s",\n' + f"\t\t\t(int)({cnt_str} < 50 ? {cnt_str} : 50),\n" + f"\t\t\t(char *)self->{member.membname},\n" + f'\t\t\t{cnt_str} < 50 ? "" : "...");\n' + ) + ret += "\t} else {\n" + ret += f'\t\tfmt_state_puts(state, " {member.membname}=<bytedata>");\n' + ret += "\t}\n" + continue ret += f'\tfmt_state_puts(state, " {member.membname}=[");\n' ret += f"\tfor ({cnt_typ} i = 0; i < {cnt_str}; i++) {{\n" ret += "\t\tif (i)\n" diff --git a/lib9p/tests/testclient-p9p.explog b/lib9p/tests/testclient-p9p.explog index f3ff1ce..c9c3f55 100644 --- a/lib9p/tests/testclient-p9p.explog +++ b/lib9p/tests/testclient-p9p.explog @@ -21,7 +21,7 @@ > Tread { tag=0 fid=1 offset=0 count=4096 } < Rread { tag=0 count=213 data=<bytedata> } > Tread { tag=0 fid=1 offset=213 count=4096 } -< Rread { tag=0 count=0 data=<bytedata> } +< Rread { tag=0 count=0 data="" } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } > Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } @@ -43,7 +43,7 @@ > Tread { tag=0 fid=1 offset=0 count=4096 } < Rread { tag=0 count=62 data=<bytedata> } > Tread { tag=0 fid=1 offset=62 count=4096 } -< Rread { tag=0 count=0 data=<bytedata> } +< Rread { tag=0 count=0 data="" } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } > Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } @@ -57,9 +57,9 @@ > Topen { tag=0 fid=1 mode=(MODE_READ) } < Ropen { tag=0 qid={ type=(0) vers=1 path=3 } iounit=0 } > Tread { tag=0 fid=1 offset=0 count=4096 } -< Rread { tag=0 count=166 data=<bytedata> } +< Rread { tag=0 count=166 data="<!--\n README.md - test static file\n\n Copyright ("... } > Tread { tag=0 fid=1 offset=166 count=4096 } -< Rread { tag=0 count=0 data=<bytedata> } +< Rread { tag=0 count=0 data="" } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } > Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } @@ -73,9 +73,9 @@ > Topen { tag=0 fid=1 mode=(MODE_READ) } < Ropen { tag=0 qid={ type=(0) vers=1 path=1 } iounit=0 } > Tread { tag=0 fid=1 offset=0 count=4096 } -< Rread { tag=0 count=166 data=<bytedata> } +< Rread { tag=0 count=166 data="<!--\n Documentation/x.txt - test static file\n\n C"... } > Tread { tag=0 fid=1 offset=166 count=4096 } -< Rread { tag=0 count=0 data=<bytedata> } +< Rread { tag=0 count=0 data="" } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } > Tversion { tag=NOTAG max_msg_size=8192 version="9P2000" } @@ -100,7 +100,7 @@ < Rwalk { tag=0 nwqid=1 wqid=[{ type=(0) vers=1 path=4 } ] } > Topen { tag=0 fid=1 mode=(TRUNC|MODE_WRITE) } < Ropen { tag=0 qid={ type=(0) vers=1 path=4 } iounit=0 } -> Twrite { tag=0 fid=1 offset=0 count=2 data=<bytedata> } +> Twrite { tag=0 fid=1 offset=0 count=2 data="1\n" } < Rwrite { tag=0 count=2 } > Tclunk { tag=0 fid=1 } < Rclunk { tag=0 } |