diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index cc2b1840c661..f5411b1ede0d 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -1603,7 +1603,7 @@ diagnostic_context::report_diagnostic (diagnostic_info *diagnostic)
 
   pp_format (this->printer, &diagnostic->message, m_urlifier);
   m_output_format->on_begin_diagnostic (*diagnostic);
-  pp_output_formatted_text (this->printer);
+  pp_output_formatted_text (this->printer, m_urlifier);
   if (m_show_cwe)
     print_any_cwe (*diagnostic);
   if (m_show_rules)
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 859ae2a273db..de454ab7a401 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
+#define INCLUDE_VECTOR
 #include "system.h"
 #include "coretypes.h"
 #include "intl.h"
@@ -1031,7 +1032,16 @@ obstack_append_string (obstack *ostack, const char *str)
   obstack_grow (ostack, str, strlen (str));
 }
 
-/* Given quoted text starting at QUOTED_TEXT_START_IDX within PP's buffer,
+/* Append STR to OSTACK, without a null-terminator.  */
+
+static void
+obstack_append_string (obstack *ostack, const char *str, size_t len)
+{
+  obstack_grow (ostack, str, len);
+}
+
+/* Given quoted text within the buffer OBSTACK
+   at the half-open interval [QUOTED_TEXT_START_IDX, QUOTED_TEXT_END_IDX),
    potentially use URLIFIER (if non-null) to see if there's a URL for the
    quoted text.
 
@@ -1039,47 +1049,45 @@ obstack_append_string (obstack *ostack, const char *str)
    version of the text, using PP's settings.
 
    For example, given this is the buffer:
-     "this is a test `hello world"
+     "this is a test `hello worldTRAILING-CONTENT"
      .................^~~~~~~~~~~
    with the quoted text starting at the 'h' of "hello world", the buffer
    becomes:
-     "this is a test `BEGIN_URL(URL)hello worldEND(URL)"
+     "this is a test `BEGIN_URL(URL)hello worldEND(URL)TRAILING-CONTENT"
      .................^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      .................-----------replacement-----------
-*/
 
-static void
+   Return the new offset into the buffer of the quoted text endpoint i.e.
+   the offset of "TRAILING-CONTENT" in the above.  */
+
+static size_t
 urlify_quoted_string (pretty_printer *pp,
+		      obstack *obstack,
 		      const urlifier *urlifier,
-		      size_t quoted_text_start_idx)
+		      size_t quoted_text_start_idx,
+		      size_t quoted_text_end_idx)
 {
   if (pp->url_format == URL_FORMAT_NONE)
-    return;
+    return quoted_text_end_idx;
   if (!urlifier)
-    return;
+    return quoted_text_end_idx;
 
-  output_buffer * const buffer = pp_buffer (pp);
-
-  /* Get end of quoted string.  */
-  const size_t close_quote_idx
-    = obstack_object_size (&buffer->chunk_obstack);
-  gcc_assert (close_quote_idx >= quoted_text_start_idx);
-  if (close_quote_idx == quoted_text_start_idx)
+  const size_t quoted_len = quoted_text_end_idx - quoted_text_start_idx;
+  if (quoted_len == 0)
     /* Empty quoted string; do nothing.  */
-    return;
-  const size_t len = close_quote_idx - quoted_text_start_idx;
-  const char *start = (buffer->chunk_obstack.object_base
-		       + quoted_text_start_idx);
-  char *url = urlifier->get_url_for_quoted_text (start, len);
+    return quoted_text_end_idx;
+  const char *start = (obstack->object_base + quoted_text_start_idx);
+  char *url = urlifier->get_url_for_quoted_text (start, quoted_len);
   if (!url)
     /* No URL for this quoted text; do nothing.  */
-    return;
+    return quoted_text_end_idx;
 
-  /* Stash a copy of the quoted text.  */
-  char *text = xstrndup (start, len);
+  /* Stash a copy of the remainder of the chunk.  */
+  char *text = xstrndup (start,
+			 obstack_object_size (obstack) - quoted_text_start_idx);
 
   /* Replace quoted text...  */
-  buffer->chunk_obstack.next_free -= len;
+  obstack->next_free = obstack->object_base + quoted_text_start_idx;
 
   /*  ...with URLified version of the text.  */
   /* Begin URL.  */
@@ -1089,27 +1097,136 @@ urlify_quoted_string (pretty_printer *pp,
     case URL_FORMAT_NONE:
       gcc_unreachable ();
     case URL_FORMAT_ST:
-      obstack_append_string (&buffer->chunk_obstack,
-			     "\33]8;;");
-      obstack_append_string (&buffer->chunk_obstack, url);
-      obstack_append_string (&buffer->chunk_obstack,
-			     "\33\\");
+      obstack_append_string (obstack, "\33]8;;");
+      obstack_append_string (obstack, url);
+      obstack_append_string (obstack, "\33\\");
       break;
     case URL_FORMAT_BEL:
-      obstack_append_string (&buffer->chunk_obstack,
-			     "\33]8;;");
-      obstack_append_string (&buffer->chunk_obstack, url);
-      obstack_append_string (&buffer->chunk_obstack,
-			     "\a");
+      obstack_append_string (obstack, "\33]8;;");
+      obstack_append_string (obstack, url);
+      obstack_append_string (obstack, "\a");
       break;
     }
-  /* Add the text back.  */
-  obstack_append_string (&buffer->chunk_obstack, text);
+  /* Add back the quoted part of the text.  */
+  obstack_append_string (obstack, text, quoted_len);
   /* End URL.  */
-  obstack_append_string (&buffer->chunk_obstack,
+  obstack_append_string (obstack,
 			 get_end_url_string (pp));
+
+  size_t new_end_idx = obstack_object_size (obstack);
+
+  /* Add back the remainder of the text after the quoted part.  */
+  obstack_append_string (obstack, text + quoted_len);
   free (text);
   free (url);
+  return new_end_idx;
+}
+
+/* A class for tracking quoted text within a buffer for
+   use by a urlifier.  */
+
+class quoting_info
+{
+public:
+  /* Called when quoted text is begun in phase 1 or 2.  */
+  void on_begin_quote (const output_buffer &buf,
+		       unsigned chunk_idx)
+  {
+    /* Stash location of start of quoted string.  */
+    size_t byte_offset = obstack_object_size (&buf.chunk_obstack);
+    m_loc_last_open_quote = location (chunk_idx, byte_offset);
+  }
+
+  /* Called when quoted text is ended in phase 1 or 2.  */
+  void on_end_quote (pretty_printer *pp,
+		     output_buffer &buf,
+		     unsigned chunk_idx,
+		     const urlifier &urlifier)
+  {
+    /* If possible, do urlification now.  */
+    if (chunk_idx == m_loc_last_open_quote.m_chunk_idx)
+      {
+	urlify_quoted_string (pp,
+			      &buf.chunk_obstack,
+			      &urlifier,
+			      m_loc_last_open_quote.m_byte_offset,
+			      obstack_object_size (&buf.chunk_obstack));
+	m_loc_last_open_quote = location ();
+	return;
+      }
+    /* Otherwise the quoted text straddles multiple chunks.
+       Stash the location of end of quoted string for use in phase 3.  */
+    size_t byte_offset = obstack_object_size (&buf.chunk_obstack);
+    m_phase_3_quotes.push_back (run (m_loc_last_open_quote,
+				     location (chunk_idx, byte_offset)));
+    m_loc_last_open_quote = location ();
+  }
+
+  bool has_phase_3_quotes_p () const
+  {
+    return m_phase_3_quotes.size () > 0;
+  }
+  void handle_phase_3 (pretty_printer *pp,
+		       const urlifier &urlifier);
+
+private:
+  struct location
+  {
+    location ()
+    : m_chunk_idx (UINT_MAX),
+      m_byte_offset (SIZE_MAX)
+    {
+    }
+
+    location (unsigned chunk_idx,
+	      size_t byte_offset)
+    : m_chunk_idx (chunk_idx),
+      m_byte_offset (byte_offset)
+    {
+    }
+
+    unsigned m_chunk_idx;
+    size_t m_byte_offset;
+  };
+
+  struct run
+  {
+    run (location start, location end)
+    : m_start (start), m_end (end)
+    {
+    }
+
+    location m_start;
+    location m_end;
+  };
+
+  location m_loc_last_open_quote;
+  std::vector<run> m_phase_3_quotes;
+};
+
+static void
+on_begin_quote (const output_buffer &buf,
+		unsigned chunk_idx,
+		const urlifier *urlifier)
+{
+  if (!urlifier)
+    return;
+  if (!buf.cur_chunk_array->m_quotes)
+    buf.cur_chunk_array->m_quotes = new quoting_info ();
+  buf.cur_chunk_array->m_quotes->on_begin_quote (buf, chunk_idx);
+}
+
+static void
+on_end_quote (pretty_printer *pp,
+	      output_buffer &buf,
+	      unsigned chunk_idx,
+	      const urlifier *urlifier)
+{
+  if (!urlifier)
+    return;
+  if (!buf.cur_chunk_array->m_quotes)
+    buf.cur_chunk_array->m_quotes = new quoting_info ();
+  buf.cur_chunk_array->m_quotes->on_end_quote (pp, buf, chunk_idx, *urlifier);
 }
 
 /* The following format specifiers are recognized as being client independent:
@@ -1161,11 +1278,12 @@ urlify_quoted_string (pretty_printer *pp,
      "before %<quoted%> after"
    with a URLIFIER that has a URL for "quoted" might be emitted as:
      "before `BEGIN_URL(http://example.com)quotedEND_URL' after"
-   This only works for message fragments that are:
+   This is handled here for message fragments that are:
    - quoted entirely in phase 1 (e.g. "%<this is quoted%>"), or
    - quoted entirely in phase 2 (e.g. "%qs"),
-   but *not* in strings that use a mixture of both phases
-   (e.g. "%<this is a mixture: %s %>").   */
+   Quoted fragments that use a mixture of both phases
+   (e.g. "%<this is a mixture: %s %>")
+   are stashed into the output_buffer's m_quotes for use in phase 3.  */
 
 void
 pp_format (pretty_printer *pp,
@@ -1182,12 +1300,11 @@ pp_format (pretty_printer *pp,
   bool any_unnumbered = false, any_numbered = false;
   const char **formatters[PP_NL_ARGMAX];
 
-  /* Keep track of location of last "%", if any.  */
-  size_t quoted_text_start_idx = 0;
-
   /* Allocate a new chunk structure.  */
   new_chunk_array = XOBNEW (&buffer->chunk_obstack, struct chunk_info);
+
   new_chunk_array->prev = buffer->cur_chunk_array;
+  new_chunk_array->m_quotes = nullptr;
   buffer->cur_chunk_array = new_chunk_array;
   args = new_chunk_array->args;
 
@@ -1229,20 +1346,14 @@ pp_format (pretty_printer *pp,
 	    obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
 	    p++;
 
-	    /* Stash offset of start of quoted string.  */
-	    quoted_text_start_idx
-	      = obstack_object_size (&buffer->chunk_obstack);
-
+	    on_begin_quote (*buffer, chunk, urlifier);
 	    continue;
 	  }
 
 	case '>':
 	  {
-	    if (quoted_text_start_idx)
-	      {
-		urlify_quoted_string (pp, urlifier, quoted_text_start_idx);
-		quoted_text_start_idx = 0;
-	      }
+	    on_end_quote (pp, *buffer, chunk, urlifier);
+
 	    const char *colorstr = colorize_stop (pp_show_color (pp));
 	    obstack_grow (&buffer->chunk_obstack, colorstr, strlen (colorstr));
 	  }
@@ -1282,14 +1393,7 @@ pp_format (pretty_printer *pp,
 	default:
 	  /* Handled in phase 2.  Terminate the plain chunk here.  */
 	  obstack_1grow (&buffer->chunk_obstack, '\0');
-	  gcc_assert (chunk < PP_NL_ARGMAX * 2);
 	  args[chunk++] = XOBFINISH (&buffer->chunk_obstack, const char *);
-	  /* We can't yet handle urlifying quoted strings that use
-	     a combination of phase 1 and phase 2 e.g.
-	     "did you mean %<-%s%>".
-	     Stop any phase 1 quoted text if there are going to be any
-	     phase 2 quoted chunks.  */
-	  quoted_text_start_idx = 0;
 	  break;
 	}
 
@@ -1392,7 +1496,6 @@ pp_format (pretty_printer *pp,
       bool plus = false;
       bool hash = false;
       bool quote = false;
-      quoted_text_start_idx = 0;
 
       /* We do not attempt to enforce any ordering on the modifier
 	 characters.  */
@@ -1435,8 +1538,7 @@ pp_format (pretty_printer *pp,
       if (quote)
 	{
 	  pp_begin_quote (pp, pp_show_color (pp));
-	  quoted_text_start_idx
-	    = obstack_object_size (&buffer->chunk_obstack);
+	  on_begin_quote (*buffer, chunk, urlifier);
 	}
 
       switch (*p)
@@ -1608,11 +1710,7 @@ pp_format (pretty_printer *pp,
 
       if (quote)
 	{
-	  if (quoted_text_start_idx)
-	    {
-	      urlify_quoted_string (pp, urlifier, quoted_text_start_idx);
-	      quoted_text_start_idx = 0;
-	    }
+	  on_end_quote (pp, *buffer, chunk, urlifier);
 	  pp_end_quote (pp, pp_show_color (pp));
 	}
 
@@ -1636,9 +1734,136 @@ pp_format (pretty_printer *pp,
   pp_clear_state (pp);
 }
 
-/* Format of a message pointed to by TEXT.  */
+struct auto_obstack
+{
+  auto_obstack ()
+  {
+    obstack_init (&m_obstack);
+  }
+
+  ~auto_obstack ()
+  {
+    obstack_free (&m_obstack, NULL);
+  }
+
+  void grow (const void *src, size_t length)
+  {
+    obstack_grow (&m_obstack, src, length);
+  }
+
+  void *object_base () const
+  {
+    return m_obstack.object_base;
+  }
+
+  size_t object_size () const
+  {
+    return obstack_object_size (&m_obstack);
+  }
+
+  obstack m_obstack;
+};
+
+/* Subroutine of pp_output_formatted_text for the awkward case where
+   quoted text straddles multiple chunks.
+
+   Flush PP's buffer's chunks to PP's output buffer, whilst inserting
+   URLs for any quoted text that should be URLified.
+
+   For example, given:
+   |  pp_format (pp,
+   |            "unrecognized option %qs; did you mean %<-%s%>",
+   |            "foo", "foption");
+   we would have these chunks:
+   |  chunk 0: "unrecognized option "
+   |  chunk 1: "`foo'" (already checked for urlification)
+   |  chunk 2: "; did you mean `-"
+   |                           ^*
+   |  chunk 3: "foption"
+   |            *******
+   |  chunk 4: "'"
+   |            ^
+   and this quoting_info would have recorded the open quote near the end
+   of chunk 2 and close quote at the start of chunk 4; this function would
+   check the combination of the end of chunk 2 and all of chunk 3 ("-foption")
+   for urlification.  */
+
+void
+quoting_info::handle_phase_3 (pretty_printer *pp,
+			      const urlifier &urlifier)
+{
+  unsigned int chunk;
+  output_buffer * const buffer = pp_buffer (pp);
+  struct chunk_info *chunk_array = buffer->cur_chunk_array;
+  const char **args = chunk_array->args;
+
+  /* We need to construct the string into an intermediate buffer
+     for this case, since using pp_string can introduce prefixes
+     and line-wrapping, and omit whitespace at the start of lines.  */
+  auto_obstack combined_buf;
+
+  /* Iterate simultaneously through both
+     - the chunks and
+     - the runs of quoted characters
+     Accumulate text from the chunks into combined_buf, and handle
+     runs of quoted characters when handling the chunks they
+     correspond to.  */
+  size_t start_of_run_byte_offset = 0;
+  std::vector<quoting_info::run>::const_iterator iter_run
+    = buffer->cur_chunk_array->m_quotes->m_phase_3_quotes.begin ();
+  std::vector<quoting_info::run>::const_iterator end_runs
+    = buffer->cur_chunk_array->m_quotes->m_phase_3_quotes.end ();
+  for (chunk = 0; args[chunk]; chunk++)
+    {
+      size_t start_of_chunk_idx = combined_buf.object_size ();
+
+      combined_buf.grow (args[chunk], strlen (args[chunk]));
+
+      if (iter_run != end_runs
+	  && chunk == iter_run->m_end.m_chunk_idx)
+	{
+	  /* A run is ending; consider for it urlification.  */
+	  const size_t end_of_run_byte_offset
+	    = start_of_chunk_idx + iter_run->m_end.m_byte_offset;
+	  const size_t end_offset
+	    = urlify_quoted_string (pp,
+				    &combined_buf.m_obstack,
+				    &urlifier,
+				    start_of_run_byte_offset,
+				    end_of_run_byte_offset);
+
+	  /* If URLification occurred it will have grown the buffer.
+	     We need to update start_of_chunk_idx so that offsets
+	     relative to it are still correct, for the case where
+	     we have a chunk that both ends a quoted run and starts
+	     another quoted run.  */
+	  gcc_assert (end_offset >= end_of_run_byte_offset);
+	  start_of_chunk_idx += end_offset - end_of_run_byte_offset;
+
+	  iter_run++;
+	}
+      if (iter_run != end_runs
+	  && chunk == iter_run->m_start.m_chunk_idx)
+	{
+	  /* Note where the run starts w.r.t. the composed buffer.  */
+	  start_of_run_byte_offset
+	    = start_of_chunk_idx + iter_run->m_start.m_byte_offset;
+	}
+    }
+
+  /* Now print to PP.  */
+  const char *start
+    = static_cast <const char *> (combined_buf.object_base ());
+  pp_maybe_wrap_text (pp, start, start + combined_buf.object_size ());
+}
+
+/* Format of a message pointed to by TEXT.
+   If URLIFIER is non-null then use it on any quoted text that was not
+   handled in phases 1 or 2 to potentially add URLs.  */
+
 void
-pp_output_formatted_text (pretty_printer *pp)
+pp_output_formatted_text (pretty_printer *pp,
+			  const urlifier *urlifier)
 {
   unsigned int chunk;
   output_buffer * const buffer = pp_buffer (pp);
@@ -1649,11 +1874,20 @@ pp_output_formatted_text (pretty_printer *pp)
 
   /* This is a third phase, first 2 phases done in pp_format_args.
      Now we actually print it.  */
-  for (chunk = 0; args[chunk]; chunk++)
-    pp_string (pp, args[chunk]);
+
+  /* If we have any deferred urlification, handle it now.  */
+  if (urlifier
+      && pp->url_format != URL_FORMAT_NONE
+      && buffer->cur_chunk_array->m_quotes
+      && buffer->cur_chunk_array->m_quotes->has_phase_3_quotes_p ())
+    buffer->cur_chunk_array->m_quotes->handle_phase_3 (pp, *urlifier);
+  else
+    for (chunk = 0; args[chunk]; chunk++)
+      pp_string (pp, args[chunk]);
 
   /* Deallocate the chunk structure and everything after it (i.e. the
      associated series of formatted strings).  */
+  delete buffer->cur_chunk_array->m_quotes;
   buffer->cur_chunk_array = chunk_array->prev;
   obstack_free (&buffer->chunk_obstack, chunk_array);
 }
@@ -2800,7 +3034,7 @@ pp_printf_with_urlifier (pretty_printer *pp,
   va_start (ap, msg);
   text_info text (msg, &ap, errno);
   pp_format (pp, &text, urlifier);
-  pp_output_formatted_text (pp);
+  pp_output_formatted_text (pp, urlifier);
   va_end (ap);
 }
 
@@ -2876,9 +3110,71 @@ test_urlification ()
     pp_printf_with_urlifier (&pp, &urlifier,
 			     "foo %<-f%s%> bar",
 			     "option");
-    /* We don't support this, but make sure we don't crash.  */
     ASSERT_STREQ
-      ("foo `-foption' bar",
+      ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar",
+       pp_formatted_text (&pp));
+  }
+
+  /* Likewise, where there is trailing phase 1 content within the
+     quoted region.  */
+  {
+    pretty_printer pp;
+    pp.url_format = URL_FORMAT_ST;
+    pp_printf_with_urlifier (&pp, &urlifier,
+			     "foo %<-f%sion%> bar %<-f%sion%> baz",
+			     "opt", "opt");
+    ASSERT_STREQ
+      ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' baz",
+       pp_formatted_text (&pp));
+  }
+
+  /* Likewise.  */
+  {
+    pretty_printer pp;
+    pp.url_format = URL_FORMAT_ST;
+    pp_printf_with_urlifier (&pp, &urlifier,
+			     "foo %<%sption%> bar %<-f%sion%> baz",
+			     "-fo", "opt");
+    ASSERT_STREQ
+      ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' baz",
+       pp_formatted_text (&pp));
+  }
+
+  /* Another mixed usage of %< and %s, where the quoted string is built
+     between a mixture of phase 1 and multiple phase 2.  */
+  {
+    pretty_printer pp;
+    pp.url_format = URL_FORMAT_ST;
+    pp_printf_with_urlifier (&pp, &urlifier,
+			     "foo %<-f%s%s%> bar",
+			     "opt", "ion");
+    ASSERT_STREQ
+      ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar",
+       pp_formatted_text (&pp));
+  }
+
+  /* Mixed usage of %< and %s with a prefix.  */
+  {
+    pretty_printer pp;
+    pp.url_format = URL_FORMAT_ST;
+    pp_set_prefix (&pp, xstrdup ("PREFIX"));
+    pp_printf_with_urlifier (&pp, &urlifier,
+			     "foo %<-f%s%> bar",
+			     "option");
+    ASSERT_STREQ
+      ("PREFIXfoo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar",
+       pp_formatted_text (&pp));
+  }
+
+  /* Example of mixed %< and %s with numbered args.  */
+  {
+    pretty_printer pp;
+    pp.url_format = URL_FORMAT_ST;
+    pp_printf_with_urlifier (&pp, &urlifier,
+			     "foo %<-f%2$st%1$sn%> bar",
+			     "io", "op");
+    ASSERT_STREQ
+      ("foo `\33]8;;http://example.com\33\\-foption\33]8;;\33\\' bar",
        pp_formatted_text (&pp));
   }
 }
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 4548c25a42de..14a225eefe06 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -69,6 +69,8 @@ enum diagnostic_prefixing_rule_t
   DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2
 };
 
+class quoting_info;
+
 /* The chunk_info data structure forms a stack of the results from the
    first phase of formatting (pp_format) which have not yet been
    output (pp_output_formatted_text).  A stack is necessary because
@@ -86,6 +88,10 @@ struct chunk_info
      text, and the third phase simply emits all the chunks in sequence
      with appropriate line-wrapping.  */
   const char *args[PP_NL_ARGMAX * 2];
+
+  /* If non-null, information on quoted text runs within the chunks
+     for use by a urlifier.  */
+  quoting_info *m_quotes;
 };
 
 /* The output buffer datatype.  This is best seen as an abstract datatype
@@ -409,7 +415,8 @@ extern void pp_flush (pretty_printer *);
 extern void pp_really_flush (pretty_printer *);
 extern void pp_format (pretty_printer *, text_info *,
 		       const urlifier * = nullptr);
-extern void pp_output_formatted_text (pretty_printer *);
+extern void pp_output_formatted_text (pretty_printer *,
+				      const urlifier * = nullptr);
 extern void pp_format_verbatim (pretty_printer *, text_info *);
 
 extern void pp_indent (pretty_printer *);
