From patchwork Mon Jul 1 13:17:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pedro Alves X-Patchwork-Id: 33498 Received: (qmail 3722 invoked by alias); 1 Jul 2019 13:17:58 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 3708 invoked by uid 89); 1 Jul 2019 13:17:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 spammy=desire X-HELO: mail-wr1-f65.google.com Received: from mail-wr1-f65.google.com (HELO mail-wr1-f65.google.com) (209.85.221.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 01 Jul 2019 13:17:56 +0000 Received: by mail-wr1-f65.google.com with SMTP id c27so6136054wrb.2 for ; Mon, 01 Jul 2019 06:17:56 -0700 (PDT) Return-Path: Received: from ?IPv6:2001:8a0:f913:f700:4c97:6d52:2cea:997b? ([2001:8a0:f913:f700:4c97:6d52:2cea:997b]) by smtp.gmail.com with ESMTPSA id x20sm9605337wmc.1.2019.07.01.06.17.53 (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Mon, 01 Jul 2019 06:17:53 -0700 (PDT) Subject: Re: ui_out format strings for fields and styles (Re: [PATCH] Style "pwd" output) To: Tom Tromey References: <20190605020116.1550-1-tom@tromey.com> <1ee4bd6b-4cdf-f3a9-74af-0843bf123a8b@redhat.com> <87lfygi1x0.fsf@tromey.com> <32872d6a-15d6-9718-59ae-957694e114c9@redhat.com> <87imtjhj6b.fsf@tromey.com> <625cd0ba-058d-d4bf-8ba3-8676f335b0f3@redhat.com> <87blzbep47.fsf@tromey.com> <2180f72f-da10-5333-90a1-666ba3bd145e@redhat.com> <87imtjbrmx.fsf@tromey.com> <871s056yjw.fsf@tromey.com> <87wohx5hir.fsf@tromey.com> <4e543ef2-eec3-b82c-a84a-a107e1ef2bc2@redhat.com> Cc: gdb-patches@sourceware.org From: Pedro Alves Message-ID: <3ff7dd5c-334b-3bcc-e43e-a350b3008304@redhat.com> Date: Mon, 1 Jul 2019 14:17:52 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 In-Reply-To: <4e543ef2-eec3-b82c-a84a-a107e1ef2bc2@redhat.com> On 7/1/19 1:55 PM, Pedro Alves wrote: > There are two other things that I wanted to experiment/try first. > > - See if we could get rid of the need for the ".ptr ()" calls. > > - See about implementing support for some ui field type other than > integers, to make sure that we're not missing something. Here's a patch for thing #2. It adds a string_field type. It applies on top of the other patch that gets rid of .ptr(), but it's super easy to make string_field a ctor, that was not the point here. I looked for a few things here and there to convert, one thing was interesting, the field_fmt() calls. If we wanted to add some fmt_field type for that, one which saves a copy of the va_list as a field, to avoid formatting into a temporary string, then the "get rid of .ptr()" patch conflicts with that desire, as that relies on a default argument to int_field/string_field etc, which doesn't work when you also want a "..." parameter, like: static inline string_field_s * fmt_field (const char *name, const char *str, fmt_s &&tmp = {}, ...) { tmp.vargs = va_copy ....; ... } I'm not sure whether we could portably save the varargs like above, though. So that might be moot. The patch replaces the format_fmt calls with string_printf + string_field. From ebcc5fb83fb0c6e98db2501c5868ba8cee6dd1f8 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Fri, 7 Jun 2019 22:45:09 +0100 Subject: [PATCH] string_field --- gdb/breakpoint.c | 14 ++++++-------- gdb/infrun.c | 19 +++++++------------ gdb/ui-out.c | 18 ++++++++++++++++-- gdb/ui-out.h | 37 ++++++++++++++++++++++++++++++++++++- 4 files changed, 65 insertions(+), 23 deletions(-) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 77f416eb9ca..e2adb18a9fa 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -6193,10 +6193,9 @@ print_one_breakpoint_location (struct breakpoint *b, && breakpoint_condition_evaluation_mode () == condition_evaluation_target) { - uiout->text (" ("); - uiout->field_string ("evaluated-by", - bp_condition_evaluator (b)); - uiout->text (" evals)"); + uiout->message (" (%pF evals)", + string_field ("evaluated-by", + bp_condition_evaluator (b))); } uiout->text ("\n"); } @@ -12752,10 +12751,9 @@ tracepoint_print_one_detail (const struct breakpoint *self, { gdb_assert (self->type == bp_static_tracepoint); - uiout->text ("\tmarker id is "); - uiout->field_string ("static-tracepoint-marker-string-id", - tp->static_trace_marker_id); - uiout->text ("\n"); + uiout->message ("\tmarker id is %pF\n", + string_field ("static-tracepoint-marker-string-id", + tp->static_trace_marker_id)); } } diff --git a/gdb/infrun.c b/gdb/infrun.c index 4fd92f1bac2..604015e1ef8 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -7641,24 +7641,19 @@ print_exited_reason (struct ui_out *uiout, int exitstatus) { if (uiout->is_mi_like_p ()) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED)); - uiout->text ("[Inferior "); - uiout->text (plongest (inf->num)); - uiout->text (" ("); - uiout->text (pidstr.c_str ()); - uiout->text (") exited with code "); - uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus); - uiout->text ("]\n"); + std::string exit_code_str + = string_printf ("0%o", (unsigned int) exitstatus); + uiout->message ("[Inferior %s (%s) exited with code %pF]\n", + plongest (inf->num), pidstr.c_str (), + string_field ("exit-code", exit_code_str.c_str ())); } else { if (uiout->is_mi_like_p ()) uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY)); - uiout->text ("[Inferior "); - uiout->text (plongest (inf->num)); - uiout->text (" ("); - uiout->text (pidstr.c_str ()); - uiout->text (") exited normally]\n"); + uiout->message ("[Inferior %s (%s) exited normally]\n", + plongest (inf->num), pidstr.c_str ()); } } diff --git a/gdb/ui-out.c b/gdb/ui-out.c index 92e461f850e..86bb2f5289a 100644 --- a/gdb/ui-out.c +++ b/gdb/ui-out.c @@ -607,8 +607,22 @@ ui_out::vmessage (const char *format, va_list args) { case 'F': { - int_field_s *field = va_arg (args, int_field_s *); - field_int (field->name, field->val); + base_field_s *bf = va_arg (args, base_field_s *); + switch (bf->kind) + { + case field_kind::INT: + { + auto *f = (int_field_s *) bf; + field_int (f->name, f->val); + } + break; + case field_kind::STRING: + { + auto *f = (string_field_s *) bf; + field_string (f->name, f->str); + } + break; + } } break; case 's': diff --git a/gdb/ui-out.h b/gdb/ui-out.h index fbf9c9bd326..e682d44383e 100644 --- a/gdb/ui-out.h +++ b/gdb/ui-out.h @@ -68,11 +68,24 @@ enum ui_out_type ui_out_type_list }; +enum class field_kind + { + INT, + STRING, + }; + /* An int field, to be passed to %pF in format strings. */ -struct int_field_s +struct base_field_s { const char *name; + field_kind kind; +}; + +/* An int field, to be passed to %pF in format strings. */ + +struct int_field_s : base_field_s +{ int val; }; @@ -85,10 +98,32 @@ int_field (const char *name, int val, int_field_s &&tmp = {}) { tmp.name = name; + tmp.kind = field_kind::INT; tmp.val = val; return &tmp; } +/* A string field, to be passed to %pF in format strings. */ + +struct string_field_s : base_field_s +{ + const char *str; +}; + +/* Construct a temporary string_field_s on the caller's stack and + return a pointer to the constructed object. We use this because + it's not possible to pass a reference via va_args. */ + +static inline string_field_s * +string_field (const char *name, const char *str, + string_field_s &&tmp = {}) +{ + tmp.name = name; + tmp.kind = field_kind::STRING; + tmp.str = str; + return &tmp; +} + /* A styled string. */ struct styled_string_s