Add line-number styling

Message ID 20240916231324.3977190-1-tom@tromey.com
State New
Headers
Series Add line-number styling |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 fail Test failed
linaro-tcwg-bot/tcwg_gdb_check--master-arm fail Test failed

Commit Message

Tom Tromey Sept. 16, 2024, 11:13 p.m. UTC
  This patch adds separate styling for line numbers.  That is, whenever
gdb prints a source line number, it uses this style.
---
 gdb/NEWS                                 |  5 +++++
 gdb/breakpoint.c                         | 10 ++++++----
 gdb/cli-out.c                            |  5 +++--
 gdb/cli-out.h                            |  3 ++-
 gdb/cli/cli-cmds.c                       |  6 ++++--
 gdb/cli/cli-style.c                      | 12 ++++++++++++
 gdb/cli/cli-style.h                      |  3 +++
 gdb/doc/gdb.texinfo                      |  4 ++++
 gdb/infcmd.c                             |  4 +++-
 gdb/mi/mi-out.c                          | 13 +++++++------
 gdb/mi/mi-out.h                          |  3 ++-
 gdb/python/py-framefilter.c              |  2 +-
 gdb/python/py-mi.c                       |  3 ++-
 gdb/python/py-uiout.h                    |  3 ++-
 gdb/source.c                             | 24 +++++++++++++++---------
 gdb/stack.c                              |  2 +-
 gdb/symmisc.c                            |  3 ++-
 gdb/testsuite/gdb.base/style-logging.exp |  3 ++-
 gdb/testsuite/gdb.base/style.exp         | 13 +++++++------
 gdb/testsuite/lib/gdb-utils.exp          |  3 ++-
 gdb/testsuite/lib/gdb.exp                |  2 +-
 gdb/tracepoint.c                         | 12 +++++++-----
 gdb/tui/tui-source.c                     | 16 ++++++++++++++++
 gdb/tui/tui-source.h                     |  6 +++++-
 gdb/tui/tui-winsource.h                  |  8 +++++---
 gdb/ui-out.c                             |  8 +++++---
 gdb/ui-out.h                             |  6 ++++--
 27 files changed, 128 insertions(+), 54 deletions(-)
  

Comments

Eli Zaretskii Sept. 17, 2024, 2:29 a.m. UTC | #1
> From: Tom Tromey <tom@tromey.com>
> Cc: Tom Tromey <tom@tromey.com>
> Date: Mon, 16 Sep 2024 17:13:24 -0600
> 
> This patch adds separate styling for line numbers.  That is, whenever
> gdb prints a source line number, it uses this style.
> ---
>  gdb/NEWS                                 |  5 +++++
>  gdb/breakpoint.c                         | 10 ++++++----
>  gdb/cli-out.c                            |  5 +++--
>  gdb/cli-out.h                            |  3 ++-
>  gdb/cli/cli-cmds.c                       |  6 ++++--
>  gdb/cli/cli-style.c                      | 12 ++++++++++++
>  gdb/cli/cli-style.h                      |  3 +++
>  gdb/doc/gdb.texinfo                      |  4 ++++
>  gdb/infcmd.c                             |  4 +++-
>  gdb/mi/mi-out.c                          | 13 +++++++------
>  gdb/mi/mi-out.h                          |  3 ++-
>  gdb/python/py-framefilter.c              |  2 +-
>  gdb/python/py-mi.c                       |  3 ++-
>  gdb/python/py-uiout.h                    |  3 ++-
>  gdb/source.c                             | 24 +++++++++++++++---------
>  gdb/stack.c                              |  2 +-
>  gdb/symmisc.c                            |  3 ++-
>  gdb/testsuite/gdb.base/style-logging.exp |  3 ++-
>  gdb/testsuite/gdb.base/style.exp         | 13 +++++++------
>  gdb/testsuite/lib/gdb-utils.exp          |  3 ++-
>  gdb/testsuite/lib/gdb.exp                |  2 +-
>  gdb/tracepoint.c                         | 12 +++++++-----
>  gdb/tui/tui-source.c                     | 16 ++++++++++++++++
>  gdb/tui/tui-source.h                     |  6 +++++-
>  gdb/tui/tui-winsource.h                  |  8 +++++---
>  gdb/ui-out.c                             |  8 +++++---
>  gdb/ui-out.h                             |  6 ++++--
>  27 files changed, 128 insertions(+), 54 deletions(-)

Thanks, the documentation parts are okay.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
  
Keith Seitz Sept. 27, 2024, 6:44 p.m. UTC | #2
Hi, Tom,

On 9/16/24 4:13 PM, Tom Tromey wrote:
> This patch adds separate styling for line numbers.  That is, whenever
> gdb prints a source line number, it uses this style.

More styling! Me likey.

Just one problem I noticed while digging into this:

> diff --git a/gdb/infcmd.c b/gdb/infcmd.c
> index 5e9af413e33..74873b9f7c8 100644
> --- a/gdb/infcmd.c
> +++ b/gdb/infcmd.c
> @@ -1103,7 +1103,9 @@ jump_command (const char *arg, int from_tty)
>   					  find_pc_mapped_section (sal.pc));
>     if (fn != nullptr && sfn != fn)
>       {
> -      if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
> +      if (!query (_("Line %ps is not in `%s'.  Jump anyway? "),
> +		  styled_string (line_number_style.style (),
> +				 pulongest (sal.line)),
>   		  fn->print_name ()))
>   	{
>   	  error (_("Not confirmed."));

Something here is not right -- this is causing gdb.base/jump.exp and
gdb.base/jump-inline.exp to fail (similarly):

jump 29
Line 0x7ffd9e2e1fd0s is not in `function_inline'.  Jump anyway? (y or n) n
Not confirmed.
(gdb) FAIL: gdb.base/jump-inline.exp: aborted jump out of current 
function (got interactive prompt)

Keith
  
Tom Tromey Sept. 28, 2024, 9:10 p.m. UTC | #3
>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:

Keith> Something here is not right -- this is causing gdb.base/jump.exp and
Keith> gdb.base/jump-inline.exp to fail (similarly):

query uses string_printf, which doesn't understand %ps.
v2 will fix this.  Thanks for noticing this.

Probably all of gdb should use a single printf implementation so this
cannot ever happen.  Or, lol, it should use std::format.

Tom
  

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index cfc9cb05f77..4e2387263d1 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -53,6 +53,11 @@ 
 
 * New commands
 
+set style line-number foreground COLOR
+set style line-number background COLOR
+set style line-number intensity VALUE
+  Control the styling of line numbers printed by GDB.
+
 maintenance info inline-frames [ADDRESS]
   New command which displays GDB's inline-frame information for the
   current address, or for ADDRESS if specified.  The output identifies
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 7fd50ba63fc..bad6a54f1bc 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -6371,7 +6371,8 @@  print_breakpoint_location (const breakpoint *b, const bp_location *loc)
       if (uiout->is_mi_like_p ())
 	uiout->field_string ("fullname", symtab_to_fullname (loc->symtab));
       
-      uiout->field_signed ("line", loc->line_number);
+      uiout->field_signed ("line", loc->line_number,
+			   line_number_style.style ());
     }
   else if (loc)
     {
@@ -11799,10 +11800,11 @@  code_breakpoint::say_where () const
 	    {
 	      const char *filename
 		= symtab_to_filename_for_display (bl.symtab);
-	      gdb_printf (": file %ps, line %d.",
+	      gdb_printf (": file %ps, line %ps.",
 			  styled_string (file_name_style.style (),
 					 filename),
-			  bl.line_number);
+			  styled_string (line_number_style.style (),
+					 pulongest (bl.line_number)));
 	    }
 	  else
 	    /* This is not ideal, but each location may have a
@@ -12832,7 +12834,7 @@  update_static_tracepoint (tracepoint *tp, struct symtab_and_line sal)
 	      uiout->field_string ("fullname", fullname);
 	    }
 
-	  uiout->field_signed ("line", sal2.line);
+	  uiout->field_signed ("line", sal2.line, line_number_style.style ());
 	  uiout->text ("\n");
 
 	  tp->first_loc ().line_number = sal2.line;
diff --git a/gdb/cli-out.c b/gdb/cli-out.c
index 1c303f09662..d8a542d1b9b 100644
--- a/gdb/cli-out.c
+++ b/gdb/cli-out.c
@@ -94,13 +94,14 @@  cli_ui_out::do_end (ui_out_type type)
 
 void
 cli_ui_out::do_field_signed (int fldno, int width, ui_align alignment,
-			     const char *fldname, LONGEST value)
+			     const char *fldname, LONGEST value,
+			     const ui_file_style &style)
 {
   if (m_suppress_output)
     return;
 
   do_field_string (fldno, width, alignment, fldname, plongest (value),
-		   ui_file_style ());
+		   style);
 }
 
 /* output an unsigned field */
diff --git a/gdb/cli-out.h b/gdb/cli-out.h
index f17cb0c9856..f0654b2063e 100644
--- a/gdb/cli-out.h
+++ b/gdb/cli-out.h
@@ -52,7 +52,8 @@  class cli_ui_out : public ui_out
   virtual void do_begin (ui_out_type type, const char *id) override;
   virtual void do_end (ui_out_type type) override;
   virtual void do_field_signed (int fldno, int width, ui_align align,
-				const char *fldname, LONGEST value) override;
+				const char *fldname, LONGEST value,
+				const ui_file_style &style) override;
   virtual void do_field_unsigned (int fldno, int width, ui_align align,
 				  const char *fldname, ULONGEST value)
     override;
diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c
index fd8e27735f0..ca6336c7ed4 100644
--- a/gdb/cli/cli-cmds.c
+++ b/gdb/cli/cli-cmds.c
@@ -2122,9 +2122,11 @@  print_sal_location (const symtab_and_line &sal)
   const char *sym_name = NULL;
   if (sal.symbol != NULL)
     sym_name = sal.symbol->print_name ();
-  gdb_printf (_("file: \"%s\", line number: %d, symbol: \"%s\"\n"),
+  gdb_printf (_("file: \"%s\", line number: %ps, symbol: \"%s\"\n"),
 	      symtab_to_filename_for_display (sal.symtab),
-	      sal.line, sym_name != NULL ? sym_name : "???");
+	      styled_string (line_number_style.style (),
+			     pulongest (sal.line)),
+	      sym_name != NULL ? sym_name : "???");
 }
 
 /* Print a list of files and line numbers which a user may choose from
diff --git a/gdb/cli/cli-style.c b/gdb/cli/cli-style.c
index 5928998e9ca..36a8bd9c526 100644
--- a/gdb/cli/cli-style.c
+++ b/gdb/cli/cli-style.c
@@ -126,6 +126,10 @@  cli_style_option disasm_comment_style ("comment", ui_file_style::WHITE,
 
 /* See cli-style.h.  */
 
+cli_style_option line_number_style ("line-number", ui_file_style::DIM);
+
+/* See cli-style.h.  */
+
 cli_style_option::cli_style_option (const char *name,
 				    ui_file_style::basic_color fg,
 				    ui_file_style::intensity intensity)
@@ -529,6 +533,14 @@  then this style has no effect."),
 					     &style_disasm_show_list,
 					     false);
 
+  line_number_style.add_setshow_commands (no_class, _("\
+Line number display styling.\n\
+Configure colors and display intensity for line numbers\n\
+The \"line-number\" style is used when GDB displays line numbers\n\
+coming from your source code."),
+				       &style_set_list, &style_show_list,
+				       false);
+
   /* Setup 'disassembler address' style and 'disassembler symbol' style,
      these are aliases for 'address' and 'function' styles respectively.  */
   add_alias_cmd ("address", address_prefix_cmds.set, no_class, 0,
diff --git a/gdb/cli/cli-style.h b/gdb/cli/cli-style.h
index 1663b4ee53c..5052b867cfa 100644
--- a/gdb/cli/cli-style.h
+++ b/gdb/cli/cli-style.h
@@ -145,6 +145,9 @@  extern cli_style_option tui_active_border_style;
 /* The style to use for the GDB version string.  */
 extern cli_style_option version_style;
 
+/* The style for a line number.  */
+extern cli_style_option line_number_style;
+
 /* True if source styling is enabled.  */
 extern bool source_styling;
 
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 77a4021b36a..c6776dea687 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -27954,6 +27954,10 @@  if @value{GDBN} is using its builtin disassembler library for styling
 (@pxref{style_disassembler_enabled,,@kbd{set style disassembler
 enabled}}).
 
+@item line-number
+Control the styling of line numbers.  By default, this style's
+intensity is dim.
+
 @item variable
 Control the styling of variable names.  These are managed with the
 @code{set style variable} family of commands.  By default, this style's
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 5e9af413e33..74873b9f7c8 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1103,7 +1103,9 @@  jump_command (const char *arg, int from_tty)
 					  find_pc_mapped_section (sal.pc));
   if (fn != nullptr && sfn != fn)
     {
-      if (!query (_("Line %d is not in `%s'.  Jump anyway? "), sal.line,
+      if (!query (_("Line %ps is not in `%s'.  Jump anyway? "),
+		  styled_string (line_number_style.style (),
+				 pulongest (sal.line)),
 		  fn->print_name ()))
 	{
 	  error (_("Not confirmed."));
diff --git a/gdb/mi/mi-out.c b/gdb/mi/mi-out.c
index ff93d2cd448..9ad26e76a30 100644
--- a/gdb/mi/mi-out.c
+++ b/gdb/mi/mi-out.c
@@ -35,8 +35,8 @@  mi_ui_out::do_table_begin (int nr_cols, int nr_rows,
 			   const char *tblid)
 {
   open (tblid, ui_out_type_tuple);
-  do_field_signed (-1, -1, ui_left, "nr_rows", nr_rows);
-  do_field_signed (-1, -1, ui_left, "nr_cols", nr_cols);
+  do_field_signed (-1, -1, ui_left, "nr_rows", nr_rows, ui_file_style ());
+  do_field_signed (-1, -1, ui_left, "nr_cols", nr_cols, ui_file_style ());
   open ("hdr", ui_out_type_list);
 }
 
@@ -67,8 +67,8 @@  mi_ui_out::do_table_header (int width, ui_align alignment,
 			    const std::string &col_hdr)
 {
   open (NULL, ui_out_type_tuple);
-  do_field_signed (0, 0, ui_center, "width", width);
-  do_field_signed (0, 0, ui_center, "alignment", alignment);
+  do_field_signed (0, 0, ui_center, "width", width, ui_file_style ());
+  do_field_signed (0, 0, ui_center, "alignment", alignment, ui_file_style ());
   do_field_string (0, 0, ui_center, "col_name", col_name.c_str (),
 		   ui_file_style ());
   do_field_string (0, width, alignment, "colhdr", col_hdr.c_str (),
@@ -96,10 +96,11 @@  mi_ui_out::do_end (ui_out_type type)
 
 void
 mi_ui_out::do_field_signed (int fldno, int width, ui_align alignment,
-			    const char *fldname, LONGEST value)
+			    const char *fldname, LONGEST value,
+			    const ui_file_style &style)
 {
   do_field_string (fldno, width, alignment, fldname, plongest (value),
-		   ui_file_style ());
+		   style);
 }
 
 /* Output an unsigned field.  */
diff --git a/gdb/mi/mi-out.h b/gdb/mi/mi-out.h
index a21a34fb8c7..9ad419e5c05 100644
--- a/gdb/mi/mi-out.h
+++ b/gdb/mi/mi-out.h
@@ -62,7 +62,8 @@  class mi_ui_out : public ui_out
   virtual void do_begin (ui_out_type type, const char *id) override;
   virtual void do_end (ui_out_type type) override;
   virtual void do_field_signed (int fldno, int width, ui_align align,
-				const char *fldname, LONGEST value) override;
+				const char *fldname, LONGEST value,
+				const ui_file_style &style) override;
   virtual void do_field_unsigned (int fldno, int width, ui_align align,
 				  const char *fldname, ULONGEST value)
     override;
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 9f9032fbe17..daec6dd9151 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -1007,7 +1007,7 @@  py_print_frame (PyObject *filter, frame_filter_flags flags,
 
 	      out->text (":");
 	      annotate_frame_source_line ();
-	      out->field_signed ("line", line);
+	      out->field_signed ("line", line, line_number_style.style ());
 	    }
 	}
       if (out->is_mi_like_p ())
diff --git a/gdb/python/py-mi.c b/gdb/python/py-mi.c
index 0a636543f9a..a2c8178a411 100644
--- a/gdb/python/py-mi.c
+++ b/gdb/python/py-mi.c
@@ -86,7 +86,8 @@  py_ui_out::do_end (ui_out_type type)
 
 void
 py_ui_out::do_field_signed (int fldno, int width, ui_align align,
-			    const char *fldname, LONGEST value)
+			    const char *fldname, LONGEST value,
+			    const ui_file_style &style)
 {
   if (m_error.has_value ())
     return;
diff --git a/gdb/python/py-uiout.h b/gdb/python/py-uiout.h
index a2fc90e955b..5f8c53052cb 100644
--- a/gdb/python/py-uiout.h
+++ b/gdb/python/py-uiout.h
@@ -86,7 +86,8 @@  class py_ui_out : public ui_out
   void do_end (ui_out_type type) override;
 
   void do_field_signed (int fldno, int width, ui_align align,
-			const char *fldname, LONGEST value) override;
+			const char *fldname, LONGEST value,
+			const ui_file_style &style) override;
   void do_field_unsigned (int fldno, int width, ui_align align,
 			  const char *fldname, ULONGEST value) override;
 
diff --git a/gdb/source.c b/gdb/source.c
index b9122c421a0..61ed088ba69 100644
--- a/gdb/source.c
+++ b/gdb/source.c
@@ -1345,7 +1345,7 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 	     fields.  ui_source_list is set only for CLI, not for
 	     TUI.  */
 
-	  uiout->field_signed ("line", line);
+	  uiout->field_signed ("line", line, line_number_style.style ());
 	  uiout->text ("\tin ");
 
 	  uiout->field_string ("file", symtab_to_filename_for_display (s),
@@ -1389,8 +1389,10 @@  print_source_lines_base (struct symtab *s, int line, int stopline,
 	  uiout->text (symtab_to_filename_for_display (s));
 	  uiout->text (":");
 	}
-      xsnprintf (buf, sizeof (buf), "%d\t", new_lineno++);
-      uiout->text (buf);
+
+      uiout->message ("%ps\t", styled_string (line_number_style.style (),
+					      pulongest (new_lineno)));
+      ++new_lineno;
 
       while (*iter != '\0')
 	{
@@ -1551,8 +1553,9 @@  info_line_command (const char *arg, int from_tty)
 
 	  if (start_pc == end_pc)
 	    {
-	      gdb_printf ("Line %d of \"%s\"",
-			  sal.line,
+	      gdb_printf ("Line %ps of \"%s\"",
+			  styled_string (line_number_style.style (),
+					 pulongest (sal.line)),
 			  symtab_to_filename_for_display (sal.symtab));
 	      gdb_stdout->wrap_here (2);
 	      gdb_printf (" is at address ");
@@ -1562,8 +1565,9 @@  info_line_command (const char *arg, int from_tty)
 	    }
 	  else
 	    {
-	      gdb_printf ("Line %d of \"%s\"",
-			  sal.line,
+	      gdb_printf ("Line %ps of \"%s\"",
+			  styled_string (line_number_style.style (),
+					 pulongest (sal.line)),
 			  symtab_to_filename_for_display (sal.symtab));
 	      gdb_stdout->wrap_here (2);
 	      gdb_printf (" starts at address ");
@@ -1589,8 +1593,10 @@  info_line_command (const char *arg, int from_tty)
 	/* Is there any case in which we get here, and have an address
 	   which the user would want to see?  If we have debugging symbols
 	   and no line numbers?  */
-	gdb_printf (_("Line number %d is out of range for \"%s\".\n"),
-		    sal.line, symtab_to_filename_for_display (sal.symtab));
+	gdb_printf (_("Line number %ps is out of range for \"%s\".\n"),
+		    styled_string (line_number_style.style (),
+				   pulongest (sal.line)),
+		    symtab_to_filename_for_display (sal.symtab));
     }
 }
 
diff --git a/gdb/stack.c b/gdb/stack.c
index b7a102eb2c3..f29fad7f874 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1418,7 +1418,7 @@  print_frame (struct ui_out *uiout,
 	annotate_frame_source_file_end ();
 	uiout->text (":");
 	annotate_frame_source_line ();
-	uiout->field_signed ("line", sal.line);
+	uiout->field_signed ("line", sal.line, line_number_style.style ());
 	annotate_frame_source_end ();
       }
 
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 7f8141588b7..afd5875ee36 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -990,7 +990,8 @@  maintenance_print_one_line_table (struct symtab *symtab, void *data)
 	  ui_out_emit_tuple tuple_emitter (uiout, nullptr);
 	  uiout->field_signed ("index", i);
 	  if (item->line > 0)
-	    uiout->field_signed ("line", item->line);
+	    uiout->field_signed ("line", item->line,
+				 line_number_style.style ());
 	  else
 	    uiout->field_string ("line", _("END"));
 	  uiout->field_core_addr ("rel-address", objfile->arch (),
diff --git a/gdb/testsuite/gdb.base/style-logging.exp b/gdb/testsuite/gdb.base/style-logging.exp
index 882418b01fb..d866d36e02a 100644
--- a/gdb/testsuite/gdb.base/style-logging.exp
+++ b/gdb/testsuite/gdb.base/style-logging.exp
@@ -41,7 +41,8 @@  with_ansi_styling_terminal {
 
     set main_expr [style main function]
     set base_file_expr [style ".*style\\.c" file]
-    set file_expr "$base_file_expr:\[0-9\]"
+    set line_expr [style $decimal line-number]
+    set file_expr "$base_file_expr:$line_expr"
     set arg_expr [style "arg." variable]
     gdb_test "frame" \
 	"$main_expr.*$arg_expr.*$arg_expr.*$file_expr.*"
diff --git a/gdb/testsuite/gdb.base/style.exp b/gdb/testsuite/gdb.base/style.exp
index aff654537ac..d29b2381923 100644
--- a/gdb/testsuite/gdb.base/style.exp
+++ b/gdb/testsuite/gdb.base/style.exp
@@ -99,7 +99,8 @@  proc run_style_tests { } {
 
 	set main_expr [limited_style main function]
 	set base_file_expr [limited_style ".*style\\.c" file]
-	set file_expr "$base_file_expr:\[0-9\]+"
+	set line_expr [limited_style $decimal line-number]
+	set file_expr "$base_file_expr:$line_expr"
 	set arg_expr [limited_style "arg." variable]
 
 	# On some embedded targets that don't fully support argc/argv,
@@ -109,12 +110,12 @@  proc run_style_tests { } {
 	gdb_test "frame" \
 	    [multi_line \
 		 "#0\\s+$main_expr\\s+\\($arg_expr=$decimal,\\s+$arg_expr=$hex.*\\)\\s+at\\s+$file_expr" \
-		 "\[0-9\]+\\s+.*return.* break here .*"]
+		 "$line_expr\\s+.*return.* break here .*"]
 	gdb_test "info breakpoints" "$main_expr at $file_expr.*"
 
 	gdb_test_no_output "set style sources off"
 	gdb_test "frame" \
-	    "\r\n\[^\033\]*break here.*" \
+	    "\r\n$line_expr\[^\033\]*break here.*" \
 	    "frame without sources styling"
 	gdb_test_no_output "set style sources on"
 
@@ -139,18 +140,18 @@  proc run_style_tests { } {
 		[multi_line \
 		     "#0\\s+$main_expr\\s+\\($arg_expr=$decimal,\\s+$arg_expr=$hex\\)" \
 		     "\\s+at\\s+$file_expr" \
-		     "\[0-9\]+\\s+.*return.* break here .*"]
+		     "$line_expr\\s+.*return.* break here .*"]
 	    set re1_styled \
 		[multi_line \
 		     "#0\\s+$main_expr\\s+\\($arg_expr=$decimal,\\s+" \
 		     "\\s+$arg_expr=$hex.*\\)" \
 		     "\\s+at\\s+$file_expr" \
-		     "\[0-9\]+\\s+.*return.* break here .*"]
+		     "$line_expr\\s+.*return.* break here .*"]
 	    set re2_styled \
 		[multi_line \
 		     "#0\\s+$main_expr\\s+\\($arg_expr=.*" \
 		     "\\s+$arg_expr=$hex.*\\)\\s+at\\s+$file_expr" \
-		     "\[0-9\]+\\s+.*return.* break here .*"]
+		     "$line_expr\\s+.*return.* break here .*"]
 
 	    # The length of the line containing argv containing:
 	    # - 4 leading spaces
diff --git a/gdb/testsuite/lib/gdb-utils.exp b/gdb/testsuite/lib/gdb-utils.exp
index 41989da3ed2..a1fdf7381a1 100644
--- a/gdb/testsuite/lib/gdb-utils.exp
+++ b/gdb/testsuite/lib/gdb-utils.exp
@@ -64,7 +64,7 @@  proc string_list_to_regexp { args } {
 
 # STYLE can either be the payload part of an ANSI terminal sequence,
 # or a shorthand for one of the gdb standard styles: "file",
-# "function", "variable", or "address".
+# "function", "variable", "address", etc.
 
 proc style {str style} {
     switch -exact -- $style {
@@ -76,6 +76,7 @@  proc style {str style} {
 	address { set style 34 }
 	metadata { set style 2 }
 	version { set style "35;1" }
+	line-number { set style 2 }
 	none { return $str }
     }
     return "\033\\\[${style}m${str}\033\\\[m"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index c993f48fd34..b7be6168557 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -791,7 +791,7 @@  proc runto { linespec args } {
     # the "at foo.c:36" output we get with -g.
     # the "in func" output we get without -g.
     gdb_expect {
-	-re "(?:Break|Temporary break).* at .*:$decimal.*$gdb_prompt $" {
+	-re "(?:Break|Temporary break).* at .*:.*$decimal.*$gdb_prompt $" {
 	    if { $print_pass } {
 		pass $test_name
 	    }
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index a5a2e698a14..8cf96fd8618 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -2351,8 +2351,9 @@  tfind_line_command (const char *args, int from_tty)
     {
       if (start_pc == end_pc)
 	{
-	  gdb_printf ("Line %d of \"%s\"",
-		      sal.line,
+	  gdb_printf ("Line %ps of \"%s\"",
+		      styled_string (line_number_style.style (),
+				     pulongest (sal.line)),
 		      symtab_to_filename_for_display (sal.symtab));
 	  gdb_stdout->wrap_here (2);
 	  gdb_printf (" is at address ");
@@ -2363,8 +2364,9 @@  tfind_line_command (const char *args, int from_tty)
 	  if (sal.line > 0
 	      && find_line_pc_range (sal, &start_pc, &end_pc)
 	      && start_pc != end_pc)
-	    gdb_printf ("Attempting to find line %d instead.\n",
-			sal.line);
+	    gdb_printf ("Attempting to find line %ps instead.\n",
+			styled_string (line_number_style.style (),
+				       pulongest (sal.line)));
 	  else
 	    error (_("Cannot find a good line."));
 	}
@@ -3644,7 +3646,7 @@  print_one_static_tracepoint_marker (int count,
       else
 	uiout->field_skip ("fullname");
 
-      uiout->field_signed ("line", sal.line);
+      uiout->field_signed ("line", sal.line, line_number_style.style ());
     }
   else
     {
diff --git a/gdb/tui/tui-source.c b/gdb/tui/tui-source.c
index ee64e4172b5..503fb00902f 100644
--- a/gdb/tui/tui-source.c
+++ b/gdb/tui/tui-source.c
@@ -32,6 +32,20 @@ 
 #include "tui/tui-winsource.h"
 #include "tui/tui-source.h"
 #include "tui/tui-location.h"
+#include "tui/tui-io.h"
+#include "cli/cli-style.h"
+
+tui_source_window::tui_source_window ()
+{
+  line_number_style.changed.attach
+    (std::bind (&tui_source_window::style_changed, this),
+     m_src_observable, "tui-source");
+}
+
+tui_source_window::~tui_source_window ()
+{
+  line_number_style.changed.detach (m_src_observable);
+}
 
 /* Function to display source in the source window.  */
 bool
@@ -247,5 +261,7 @@  tui_source_window::show_line_number (int offset) const
 		 tui_left_margin_verbose ? "%0*d%c" : "%*d%c", m_digits - 1,
 		 lineno, space);
     }
+  tui_apply_style (handle.get (), line_number_style.style ());
   display_string (text);
+  tui_apply_style (handle.get (), ui_file_style ());
 }
diff --git a/gdb/tui/tui-source.h b/gdb/tui/tui-source.h
index f32167f4224..d8f7189ad73 100644
--- a/gdb/tui/tui-source.h
+++ b/gdb/tui/tui-source.h
@@ -30,7 +30,8 @@ 
 
 struct tui_source_window : public tui_source_window_base
 {
-  tui_source_window () = default;
+  tui_source_window ();
+  ~tui_source_window ();
 
   DISABLE_COPY_AND_ASSIGN (tui_source_window);
 
@@ -81,6 +82,9 @@  struct tui_source_window : public tui_source_window_base
 
   /* It is the resolved form as returned by symtab_to_fullname.  */
   gdb::unique_xmalloc_ptr<char> m_fullname;
+
+  /* A token used to register and unregister an observer.  */
+  gdb::observers::token m_src_observable;
 };
 
 /* Return the instance of the source window.  */
diff --git a/gdb/tui/tui-winsource.h b/gdb/tui/tui-winsource.h
index 29828c121bd..a262c635e5a 100644
--- a/gdb/tui/tui-winsource.h
+++ b/gdb/tui/tui-winsource.h
@@ -189,6 +189,11 @@  struct tui_source_window_base : public tui_win_info
      update_source_windows_with_addr.  */
   void update_source_window_with_addr (struct gdbarch *, CORE_ADDR);
 
+protected:
+
+  /* Called when a user style setting is changed.  */
+  void style_changed ();
+
 private:
 
   /* Used for horizontal scroll.  */
@@ -236,9 +241,6 @@  struct tui_source_window_base : public tui_win_info
      the initial escape that sets the color will still be applied.  */
   void puts_to_pad_with_skip (const char *string, int skip);
 
-  /* Called when the user "set style enabled" setting is changed.  */
-  void style_changed ();
-
   /* A token used to register and unregister an observer.  */
   gdb::observers::token m_observable;
 
diff --git a/gdb/ui-out.c b/gdb/ui-out.c
index 7e9f238fcf6..3330cc87ebb 100644
--- a/gdb/ui-out.c
+++ b/gdb/ui-out.c
@@ -433,7 +433,8 @@  ui_out::end (ui_out_type type)
 }
 
 void
-ui_out::field_signed (const char *fldname, LONGEST value)
+ui_out::field_signed (const char *fldname, LONGEST value,
+		      const ui_file_style &style)
 {
   int fldno;
   int width;
@@ -441,7 +442,7 @@  ui_out::field_signed (const char *fldname, LONGEST value)
 
   verify_field (&fldno, &width, &align);
 
-  do_field_signed (fldno, width, align, fldname, value);
+  do_field_signed (fldno, width, align, fldname, value, style);
 }
 
 void
@@ -454,7 +455,8 @@  ui_out::field_fmt_signed (int input_width, ui_align input_align,
 
   verify_field (&fldno, &width, &align);
 
-  do_field_signed (fldno, input_width, input_align, fldname, value);
+  do_field_signed (fldno, input_width, input_align, fldname, value,
+		   ui_file_style ());
 }
 
 /* See ui-out.h.  */
diff --git a/gdb/ui-out.h b/gdb/ui-out.h
index ef9ce4fad33..f9d96dea875 100644
--- a/gdb/ui-out.h
+++ b/gdb/ui-out.h
@@ -182,7 +182,8 @@  class ui_out
   void begin (ui_out_type type, const char *id);
   void end (ui_out_type type);
 
-  void field_signed (const char *fldname, LONGEST value);
+  void field_signed (const char *fldname, LONGEST value,
+		     const ui_file_style &style = ui_file_style ());
   void field_fmt_signed (int width, ui_align align, const char *fldname,
 			 LONGEST value);
   /* Like field_signed, but print an unsigned value.  */
@@ -346,7 +347,8 @@  class ui_out
   virtual void do_begin (ui_out_type type, const char *id) = 0;
   virtual void do_end (ui_out_type type) = 0;
   virtual void do_field_signed (int fldno, int width, ui_align align,
-				const char *fldname, LONGEST value) = 0;
+				const char *fldname, LONGEST value,
+				const ui_file_style &style) = 0;
   virtual void do_field_unsigned (int fldno, int width, ui_align align,
 				  const char *fldname, ULONGEST value) = 0;
   virtual void do_field_skip (int fldno, int width, ui_align align,