Home | History | Annotate | Line # | Download | only in gdb
ui-file.h revision 1.10
      1   1.1  christos /* UI_FILE - a generic STDIO like output stream.
      2  1.10  christos    Copyright (C) 1999-2023 Free Software Foundation, Inc.
      3   1.1  christos 
      4   1.1  christos    This file is part of GDB.
      5   1.1  christos 
      6   1.1  christos    This program is free software; you can redistribute it and/or modify
      7   1.1  christos    it under the terms of the GNU General Public License as published by
      8   1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9   1.1  christos    (at your option) any later version.
     10   1.1  christos 
     11   1.1  christos    This program is distributed in the hope that it will be useful,
     12   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  christos    GNU General Public License for more details.
     15   1.1  christos 
     16   1.1  christos    You should have received a copy of the GNU General Public License
     17   1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18   1.1  christos 
     19   1.1  christos #ifndef UI_FILE_H
     20   1.1  christos #define UI_FILE_H
     21   1.1  christos 
     22   1.7  christos #include <string>
     23   1.8  christos #include "ui-style.h"
     24   1.1  christos 
     25   1.7  christos /* The abstract ui_file base class.  */
     26   1.1  christos 
     27   1.7  christos class ui_file
     28   1.7  christos {
     29   1.7  christos public:
     30   1.7  christos   ui_file ();
     31   1.7  christos   virtual ~ui_file () = 0;
     32   1.1  christos 
     33   1.7  christos   /* Public non-virtual API.  */
     34   1.1  christos 
     35   1.7  christos   void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);
     36   1.1  christos 
     37  1.10  christos   /* Print a NUL-terminated string whose delimiter is QUOTER.  Note
     38  1.10  christos      that these routines should only be called for printing things
     39  1.10  christos      which are independent of the language of the program being
     40  1.10  christos      debugged.
     41  1.10  christos 
     42  1.10  christos      This will normally escape backslashes and instances of QUOTER.
     43  1.10  christos      If QUOTER is 0, it won't escape backslashes or any quoting
     44  1.10  christos      character.  As a side effect, if you pass the backslash character
     45  1.10  christos      as the QUOTER, this will escape backslashes as usual, but not any
     46  1.10  christos      other quoting character.  */
     47   1.7  christos   void putstr (const char *str, int quoter);
     48   1.1  christos 
     49  1.10  christos   /* Like putstr, but only print the first N characters of STR.  If
     50  1.10  christos      ASYNC_SAFE is true, then the output is done via the
     51  1.10  christos      write_async_safe method.  */
     52  1.10  christos   void putstrn (const char *str, int n, int quoter, bool async_safe = false);
     53   1.1  christos 
     54  1.10  christos   void putc (int c);
     55   1.1  christos 
     56   1.7  christos   void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);
     57   1.1  christos 
     58   1.7  christos   /* Methods below are both public, and overridable by ui_file
     59   1.7  christos      subclasses.  */
     60   1.7  christos 
     61   1.7  christos   virtual void write (const char *buf, long length_buf) = 0;
     62   1.7  christos 
     63   1.7  christos   /* This version of "write" is safe for use in signal handlers.  It's
     64   1.7  christos      not guaranteed that all existing output will have been flushed
     65   1.7  christos      first.  Implementations are also free to ignore some or all of
     66   1.7  christos      the request.  puts_async is not provided as the async versions
     67   1.7  christos      are rarely used, no point in having both for a rarely used
     68   1.7  christos      interface.  */
     69   1.7  christos   virtual void write_async_safe (const char *buf, long length_buf)
     70   1.7  christos   { gdb_assert_not_reached ("write_async_safe"); }
     71   1.7  christos 
     72   1.7  christos   /* Some ui_files override this to provide a efficient implementation
     73   1.7  christos      that avoids a strlen.  */
     74   1.7  christos   virtual void puts (const char *str)
     75   1.7  christos   { this->write (str, strlen (str)); }
     76   1.1  christos 
     77   1.7  christos   virtual long read (char *buf, long length_buf)
     78   1.7  christos   { gdb_assert_not_reached ("can't read from this file type"); }
     79   1.1  christos 
     80   1.7  christos   virtual bool isatty ()
     81   1.7  christos   { return false; }
     82   1.3  christos 
     83   1.9  christos   /* true indicates terminal output behaviour such as cli_styling.
     84   1.9  christos      This default implementation indicates to do terminal output
     85   1.9  christos      behaviour if the UI_FILE is a tty.  A derived class can override
     86   1.9  christos      TERM_OUT to have cli_styling behaviour without being a tty.  */
     87   1.9  christos   virtual bool term_out ()
     88   1.9  christos   { return isatty (); }
     89   1.9  christos 
     90   1.9  christos   /* true if ANSI escapes can be used on STREAM.  */
     91   1.9  christos   virtual bool can_emit_style_escape ()
     92   1.9  christos   { return false; }
     93   1.9  christos 
     94   1.7  christos   virtual void flush ()
     95   1.7  christos   {}
     96  1.10  christos 
     97  1.10  christos   /* If this object has an underlying file descriptor, then return it.
     98  1.10  christos      Otherwise, return -1.  */
     99  1.10  christos   virtual int fd () const
    100  1.10  christos   { return -1; }
    101  1.10  christos 
    102  1.10  christos   /* Indicate that if the next sequence of characters overflows the
    103  1.10  christos      line, a newline should be inserted here rather than when it hits
    104  1.10  christos      the end.  If INDENT is non-zero, it is a number of spaces to be
    105  1.10  christos      printed to indent the wrapped part on the next line.
    106  1.10  christos 
    107  1.10  christos      If the line is already overfull, we immediately print a newline and
    108  1.10  christos      the indentation, and disable further wrapping.
    109  1.10  christos 
    110  1.10  christos      If we don't know the width of lines, but we know the page height,
    111  1.10  christos      we must not wrap words, but should still keep track of newlines
    112  1.10  christos      that were explicitly printed.
    113  1.10  christos 
    114  1.10  christos      This routine is guaranteed to force out any output which has been
    115  1.10  christos      squirreled away in the wrap_buffer, so wrap_here (0) can be
    116  1.10  christos      used to force out output from the wrap_buffer.  */
    117  1.10  christos   virtual void wrap_here (int indent)
    118  1.10  christos   {
    119  1.10  christos   }
    120  1.10  christos 
    121  1.10  christos   /* Emit an ANSI style escape for STYLE.  */
    122  1.10  christos   virtual void emit_style_escape (const ui_file_style &style);
    123  1.10  christos 
    124  1.10  christos   /* Rest the current output style to the empty style.  */
    125  1.10  christos   virtual void reset_style ();
    126  1.10  christos 
    127  1.10  christos   /* Print STR, bypassing any paging that might be done by this
    128  1.10  christos      ui_file.  Note that nearly no code should call this -- it's
    129  1.10  christos      intended for use by gdb_printf, but nothing else.  */
    130  1.10  christos   virtual void puts_unfiltered (const char *str)
    131  1.10  christos   {
    132  1.10  christos     this->puts (str);
    133  1.10  christos   }
    134  1.10  christos 
    135  1.10  christos protected:
    136  1.10  christos 
    137  1.10  christos   /* The currently applied style.  */
    138  1.10  christos   ui_file_style m_applied_style;
    139  1.10  christos 
    140  1.10  christos private:
    141  1.10  christos 
    142  1.10  christos   /* Helper function for putstr and putstrn.  Print the character C on
    143  1.10  christos      this stream as part of the contents of a literal string whose
    144  1.10  christos      delimiter is QUOTER.  */
    145  1.10  christos   void printchar (int c, int quoter, bool async_safe);
    146   1.7  christos };
    147   1.3  christos 
    148   1.7  christos typedef std::unique_ptr<ui_file> ui_file_up;
    149   1.1  christos 
    150   1.7  christos /* A ui_file that writes to nowhere.  */
    151   1.1  christos 
    152   1.7  christos class null_file : public ui_file
    153   1.7  christos {
    154   1.7  christos public:
    155   1.7  christos   void write (const char *buf, long length_buf) override;
    156   1.7  christos   void write_async_safe (const char *buf, long sizeof_buf) override;
    157   1.7  christos   void puts (const char *str) override;
    158   1.7  christos };
    159   1.1  christos 
    160   1.7  christos /* A preallocated null_file stream.  */
    161   1.7  christos extern null_file null_stream;
    162   1.1  christos 
    163   1.8  christos extern int gdb_console_fputs (const char *, FILE *);
    164   1.8  christos 
    165   1.7  christos /* A std::string-based ui_file.  Can be used as a scratch buffer for
    166   1.7  christos    collecting output.  */
    167   1.1  christos 
    168   1.7  christos class string_file : public ui_file
    169   1.7  christos {
    170   1.7  christos public:
    171   1.9  christos   /* Construct a string_file to collect 'raw' output, i.e. without
    172   1.9  christos      'terminal' behaviour such as cli_styling.  */
    173   1.9  christos   string_file () : m_term_out (false) {};
    174   1.9  christos   /* If TERM_OUT, construct a string_file with terminal output behaviour
    175   1.9  christos      such as cli_styling)
    176   1.9  christos      else collect 'raw' output like the previous constructor.  */
    177   1.9  christos   explicit string_file (bool term_out) : m_term_out (term_out) {};
    178   1.7  christos   ~string_file () override;
    179   1.7  christos 
    180   1.7  christos   /* Override ui_file methods.  */
    181   1.7  christos 
    182   1.7  christos   void write (const char *buf, long length_buf) override;
    183   1.7  christos 
    184   1.7  christos   long read (char *buf, long length_buf) override
    185   1.7  christos   { gdb_assert_not_reached ("a string_file is not readable"); }
    186   1.7  christos 
    187   1.9  christos   bool term_out () override;
    188   1.9  christos   bool can_emit_style_escape () override;
    189   1.9  christos 
    190   1.7  christos   /* string_file-specific public API.  */
    191   1.7  christos 
    192   1.7  christos   /* Accesses the std::string containing the entire output collected
    193  1.10  christos      so far.  */
    194  1.10  christos   const std::string &string () { return m_string; }
    195   1.7  christos 
    196  1.10  christos   /* Return an std::string containing the entire output collected so far.
    197   1.7  christos 
    198  1.10  christos      The internal buffer is cleared, such that it's ready to build a new
    199  1.10  christos      string.  */
    200  1.10  christos   std::string release ()
    201  1.10  christos   {
    202  1.10  christos     std::string ret = std::move (m_string);
    203  1.10  christos     m_string.clear ();
    204  1.10  christos     return ret;
    205  1.10  christos   }
    206  1.10  christos 
    207  1.10  christos   /* Set the internal buffer contents to STR.  Any existing contents are
    208  1.10  christos      discarded.  */
    209  1.10  christos   string_file &operator= (std::string &&str)
    210  1.10  christos   {
    211  1.10  christos     m_string = std::move (str);
    212  1.10  christos     return *this;
    213  1.10  christos   }
    214   1.7  christos 
    215   1.7  christos   /* Provide a few convenience methods with the same API as the
    216   1.7  christos      underlying std::string.  */
    217   1.7  christos   const char *data () const { return m_string.data (); }
    218   1.7  christos   const char *c_str () const { return m_string.c_str (); }
    219   1.7  christos   size_t size () const { return m_string.size (); }
    220   1.7  christos   bool empty () const { return m_string.empty (); }
    221   1.7  christos   void clear () { return m_string.clear (); }
    222   1.7  christos 
    223   1.7  christos private:
    224   1.7  christos   /* The internal buffer.  */
    225   1.7  christos   std::string m_string;
    226   1.9  christos 
    227   1.9  christos   bool m_term_out;
    228   1.7  christos };
    229   1.7  christos 
    230   1.7  christos /* A ui_file implementation that maps directly onto <stdio.h>'s FILE.
    231   1.7  christos    A stdio_file can either own its underlying file, or not.  If it
    232   1.7  christos    owns the file, then destroying the stdio_file closes the underlying
    233   1.7  christos    file, otherwise it is left open.  */
    234   1.7  christos 
    235   1.7  christos class stdio_file : public ui_file
    236   1.7  christos {
    237   1.7  christos public:
    238   1.7  christos   /* Create a ui_file from a previously opened FILE.  CLOSE_P
    239   1.7  christos      indicates whether the underlying file should be closed when the
    240   1.7  christos      stdio_file is destroyed.  */
    241   1.7  christos   explicit stdio_file (FILE *file, bool close_p = false);
    242   1.7  christos 
    243   1.7  christos   /* Create an stdio_file that is not managing any file yet.  Call
    244   1.7  christos      open to actually open something.  */
    245   1.7  christos   stdio_file ();
    246   1.7  christos 
    247   1.7  christos   ~stdio_file () override;
    248   1.7  christos 
    249   1.7  christos   /* Open NAME in mode MODE, and own the resulting file.  Returns true
    250   1.7  christos      on success, false otherwise.  If the stdio_file previously owned
    251   1.7  christos      a file, it is closed.  */
    252   1.7  christos   bool open (const char *name, const char *mode);
    253   1.7  christos 
    254   1.7  christos   void flush () override;
    255   1.7  christos 
    256   1.7  christos   void write (const char *buf, long length_buf) override;
    257   1.7  christos 
    258   1.7  christos   void write_async_safe (const char *buf, long length_buf) override;
    259   1.7  christos 
    260   1.7  christos   void puts (const char *) override;
    261   1.7  christos 
    262   1.7  christos   long read (char *buf, long length_buf) override;
    263   1.7  christos 
    264   1.7  christos   bool isatty () override;
    265   1.7  christos 
    266   1.9  christos   bool can_emit_style_escape () override;
    267   1.9  christos 
    268  1.10  christos   /* Return the underlying file descriptor.  */
    269  1.10  christos   int fd () const override
    270  1.10  christos   { return m_fd; }
    271  1.10  christos 
    272   1.7  christos private:
    273   1.7  christos   /* Sets the internal stream to FILE, and saves the FILE's file
    274   1.7  christos      descriptor in M_FD.  */
    275   1.7  christos   void set_stream (FILE *file);
    276   1.7  christos 
    277   1.7  christos   /* The file.  */
    278   1.7  christos   FILE *m_file;
    279   1.7  christos 
    280   1.7  christos   /* The associated file descriptor is extracted ahead of time for
    281   1.7  christos      stdio_file::write_async_safe's benefit, in case fileno isn't
    282   1.7  christos      async-safe.  */
    283   1.7  christos   int m_fd;
    284   1.7  christos 
    285   1.7  christos   /* If true, M_FILE is closed on destruction.  */
    286   1.7  christos   bool m_close_p;
    287   1.7  christos };
    288   1.7  christos 
    289   1.7  christos typedef std::unique_ptr<stdio_file> stdio_file_up;
    290   1.7  christos 
    291   1.7  christos /* Like stdio_file, but specifically for stderr.
    292   1.7  christos 
    293   1.7  christos    This exists because there is no real line-buffering on Windows, see
    294   1.7  christos    <http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx>
    295   1.7  christos    so the stdout is either fully-buffered or non-buffered.  We can't
    296   1.7  christos    make stdout non-buffered, because of two concerns:
    297   1.7  christos 
    298   1.7  christos     1. Non-buffering hurts performance.
    299   1.7  christos     2. Non-buffering may change GDB's behavior when it is interacting
    300   1.7  christos        with a front-end, such as Emacs.
    301   1.7  christos 
    302   1.7  christos    We leave stdout as fully buffered, but flush it first when
    303   1.7  christos    something is written to stderr.
    304   1.7  christos 
    305   1.7  christos    Note that the 'write_async_safe' method is not overridden, because
    306   1.7  christos    there's no way to flush a stream in an async-safe manner.
    307   1.7  christos    Fortunately, it doesn't really matter, because:
    308   1.7  christos 
    309   1.7  christos     1. That method is only used for printing internal debug output
    310   1.7  christos        from signal handlers.
    311   1.7  christos 
    312   1.7  christos     2. Windows hosts don't have a concept of async-safeness.  Signal
    313   1.7  christos        handlers run in a separate thread, so they can call the regular
    314   1.7  christos        non-async-safe output routines freely.
    315   1.7  christos */
    316   1.7  christos class stderr_file : public stdio_file
    317   1.7  christos {
    318   1.7  christos public:
    319   1.7  christos   explicit stderr_file (FILE *stream);
    320   1.7  christos 
    321   1.7  christos   /* Override the output routines to flush gdb_stdout before deferring
    322   1.7  christos      to stdio_file for the actual outputting.  */
    323   1.7  christos   void write (const char *buf, long length_buf) override;
    324   1.7  christos   void puts (const char *linebuffer) override;
    325   1.7  christos };
    326   1.7  christos 
    327   1.7  christos /* A ui_file implementation that maps onto two ui-file objects.  */
    328   1.7  christos 
    329   1.7  christos class tee_file : public ui_file
    330   1.7  christos {
    331   1.7  christos public:
    332  1.10  christos   /* Create a file which writes to both ONE and TWO.  Ownership of
    333  1.10  christos      both files is up to the user.  */
    334  1.10  christos   tee_file (ui_file *one, ui_file *two);
    335   1.7  christos   ~tee_file () override;
    336   1.7  christos 
    337   1.7  christos   void write (const char *buf, long length_buf) override;
    338   1.7  christos   void write_async_safe (const char *buf, long length_buf) override;
    339   1.7  christos   void puts (const char *) override;
    340   1.7  christos 
    341   1.7  christos   bool isatty () override;
    342   1.9  christos   bool term_out () override;
    343   1.9  christos   bool can_emit_style_escape () override;
    344   1.7  christos   void flush () override;
    345   1.7  christos 
    346  1.10  christos   void emit_style_escape (const ui_file_style &style) override
    347  1.10  christos   {
    348  1.10  christos     m_one->emit_style_escape (style);
    349  1.10  christos     m_two->emit_style_escape (style);
    350  1.10  christos   }
    351  1.10  christos 
    352  1.10  christos   void reset_style () override
    353  1.10  christos   {
    354  1.10  christos     m_one->reset_style ();
    355  1.10  christos     m_two->reset_style ();
    356  1.10  christos   }
    357  1.10  christos 
    358  1.10  christos   void puts_unfiltered (const char *str) override
    359  1.10  christos   {
    360  1.10  christos     m_one->puts_unfiltered (str);
    361  1.10  christos     m_two->puts_unfiltered (str);
    362  1.10  christos   }
    363  1.10  christos 
    364   1.7  christos private:
    365   1.9  christos   /* The two underlying ui_files.  */
    366   1.9  christos   ui_file *m_one;
    367  1.10  christos   ui_file *m_two;
    368   1.9  christos };
    369   1.9  christos 
    370   1.9  christos /* A ui_file implementation that filters out terminal escape
    371   1.9  christos    sequences.  */
    372   1.9  christos 
    373   1.9  christos class no_terminal_escape_file : public stdio_file
    374   1.9  christos {
    375   1.9  christos public:
    376   1.9  christos   no_terminal_escape_file ()
    377   1.9  christos   {
    378   1.9  christos   }
    379   1.9  christos 
    380   1.9  christos   /* Like the stdio_file methods, but these filter out terminal escape
    381   1.9  christos      sequences.  */
    382   1.9  christos   void write (const char *buf, long length_buf) override;
    383   1.9  christos   void puts (const char *linebuffer) override;
    384  1.10  christos 
    385  1.10  christos   void emit_style_escape (const ui_file_style &style) override
    386  1.10  christos   {
    387  1.10  christos   }
    388  1.10  christos 
    389  1.10  christos   void reset_style () override
    390  1.10  christos   {
    391  1.10  christos   }
    392  1.10  christos };
    393  1.10  christos 
    394  1.10  christos /* A base class for ui_file types that wrap another ui_file.  */
    395  1.10  christos 
    396  1.10  christos class wrapped_file : public ui_file
    397  1.10  christos {
    398  1.10  christos public:
    399  1.10  christos 
    400  1.10  christos   bool isatty () override
    401  1.10  christos   { return m_stream->isatty (); }
    402  1.10  christos 
    403  1.10  christos   bool term_out () override
    404  1.10  christos   { return m_stream->term_out (); }
    405  1.10  christos 
    406  1.10  christos   bool can_emit_style_escape () override
    407  1.10  christos   { return m_stream->can_emit_style_escape (); }
    408  1.10  christos 
    409  1.10  christos   void flush () override
    410  1.10  christos   { m_stream->flush (); }
    411  1.10  christos 
    412  1.10  christos   void wrap_here (int indent) override
    413  1.10  christos   { m_stream->wrap_here (indent); }
    414  1.10  christos 
    415  1.10  christos   void emit_style_escape (const ui_file_style &style) override
    416  1.10  christos   { m_stream->emit_style_escape (style); }
    417  1.10  christos 
    418  1.10  christos   /* Rest the current output style to the empty style.  */
    419  1.10  christos   void reset_style () override
    420  1.10  christos   { m_stream->reset_style (); }
    421  1.10  christos 
    422  1.10  christos   int fd () const override
    423  1.10  christos   { return m_stream->fd (); }
    424  1.10  christos 
    425  1.10  christos   void puts_unfiltered (const char *str) override
    426  1.10  christos   { m_stream->puts_unfiltered (str); }
    427  1.10  christos 
    428  1.10  christos   void write_async_safe (const char *buf, long length_buf) override
    429  1.10  christos   { return m_stream->write_async_safe (buf, length_buf); }
    430  1.10  christos 
    431  1.10  christos protected:
    432  1.10  christos 
    433  1.10  christos   /* Note that this class does not assume ownership of the stream.
    434  1.10  christos      However, a subclass may choose to, by adding a 'delete' to its
    435  1.10  christos      destructor.  */
    436  1.10  christos   explicit wrapped_file (ui_file *stream)
    437  1.10  christos     : m_stream (stream)
    438  1.10  christos   {
    439  1.10  christos   }
    440  1.10  christos 
    441  1.10  christos   /* The underlying stream.  */
    442  1.10  christos   ui_file *m_stream;
    443  1.10  christos };
    444  1.10  christos 
    445  1.10  christos /* A ui_file that optionally puts a timestamp at the start of each
    446  1.10  christos    line of output.  */
    447  1.10  christos 
    448  1.10  christos class timestamped_file : public wrapped_file
    449  1.10  christos {
    450  1.10  christos public:
    451  1.10  christos   explicit timestamped_file (ui_file *stream)
    452  1.10  christos     : wrapped_file (stream)
    453  1.10  christos   {
    454  1.10  christos   }
    455  1.10  christos 
    456  1.10  christos   DISABLE_COPY_AND_ASSIGN (timestamped_file);
    457  1.10  christos 
    458  1.10  christos   void write (const char *buf, long len) override;
    459  1.10  christos 
    460  1.10  christos private:
    461  1.10  christos 
    462  1.10  christos   /* True if the next output should be timestamped.  */
    463  1.10  christos   bool m_needs_timestamp = true;
    464   1.7  christos };
    465   1.1  christos 
    466   1.1  christos #endif
    467