/* UI_FILE - a generic STDIO like output stream.
   Copyright (C) 1999-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef UI_FILE_H
#define UI_FILE_H

#include <string>
#include "ui-style.h"

/* The abstract ui_file base class.  */

class ui_file
{
public:
  ui_file ();
  virtual ~ui_file () = 0;

  ui_file (ui_file &&other) = default;

  /* Public non-virtual API.  */

  void printf (const char *, ...) ATTRIBUTE_PRINTF (2, 3);

  /* Print a NUL-terminated string whose delimiter is QUOTER.  Note
     that these routines should only be called for printing things
     which are independent of the language of the program being
     debugged.

     This will normally escape backslashes and instances of QUOTER.
     If QUOTER is 0, it won't escape backslashes or any quoting
     character.  As a side effect, if you pass the backslash character
     as the QUOTER, this will escape backslashes as usual, but not any
     other quoting character.  */
  void putstr (const char *str, int quoter);

  /* Like putstr, but only print the first N characters of STR.  If
     ASYNC_SAFE is true, then the output is done via the
     write_async_safe method.  */
  void putstrn (const char *str, int n, int quoter, bool async_safe = false);

  void putc (int c);

  void vprintf (const char *, va_list) ATTRIBUTE_PRINTF (2, 0);

  /* Methods below are both public, and overridable by ui_file
     subclasses.  */

  virtual void write (const char *buf, long length_buf) = 0;

  /* This version of "write" is safe for use in signal handlers.  It's
     not guaranteed that all existing output will have been flushed
     first.  Implementations are also free to ignore some or all of
     the request.  puts_async is not provided as the async versions
     are rarely used, no point in having both for a rarely used
     interface.  */
  virtual void write_async_safe (const char *buf, long length_buf)
  { gdb_assert_not_reached ("write_async_safe"); }

  /* Some ui_files override this to provide a efficient implementation
     that avoids a strlen.  */
  virtual void puts (const char *str)
  { this->write (str, strlen (str)); }

  virtual long read (char *buf, long length_buf)
  { gdb_assert_not_reached ("can't read from this file type"); }

  virtual bool isatty ()
  { return false; }

  /* true indicates terminal output behavior such as cli_styling.
     This default implementation indicates to do terminal output
     behavior if the UI_FILE is a tty.  A derived class can override
     TERM_OUT to have cli_styling behavior without being a tty.  */
  virtual bool term_out ()
  { return isatty (); }

  /* true if ANSI escapes can be used on STREAM.  */
  virtual bool can_emit_style_escape ()
  { return false; }

  virtual void flush ()
  {}

  /* If this object has an underlying file descriptor, then return it.
     Otherwise, return -1.  */
  virtual int fd () const
  { return -1; }

  /* Indicate that if the next sequence of characters overflows the
     line, a newline should be inserted here rather than when it hits
     the end.  If INDENT is non-zero, it is a number of spaces to be
     printed to indent the wrapped part on the next line.

     If the line is already overfull, we immediately print a newline and
     the indentation, and disable further wrapping.

     If we don't know the width of lines, but we know the page height,
     we must not wrap words, but should still keep track of newlines
     that were explicitly printed.

     This routine is guaranteed to force out any output which has been
     squirreled away in the wrap_buffer, so wrap_here (0) can be
     used to force out output from the wrap_buffer.  */
  virtual void wrap_here (int indent)
  {
  }

  /* Emit an ANSI style escape for STYLE.  */
  virtual void emit_style_escape (const ui_file_style &style);

  /* Rest the current output style to the empty style.  */
  virtual void reset_style ();

  /* Print STR, bypassing any paging that might be done by this
     ui_file.  Note that nearly no code should call this -- it's
     intended for use by gdb_printf, but nothing else.  */
  virtual void puts_unfiltered (const char *str)
  {
    this->puts (str);
  }

protected:

  /* The currently applied style.  */
  ui_file_style m_applied_style;

private:

  /* Helper function for putstr and putstrn.  Print the character C on
     this stream as part of the contents of a literal string whose
     delimiter is QUOTER.  */
  void printchar (int c, int quoter, bool async_safe);
};

typedef std::unique_ptr<ui_file> ui_file_up;

/* A ui_file that writes to nowhere.  */

class null_file : public ui_file
{
public:
  void write (const char *buf, long length_buf) override;
  void write_async_safe (const char *buf, long sizeof_buf) override;
  void puts (const char *str) override;
};

/* A preallocated null_file stream.  */
extern null_file null_stream;

extern int gdb_console_fputs (const char *, FILE *);

/* A std::string-based ui_file.  Can be used as a scratch buffer for
   collecting output.  */

class string_file : public ui_file
{
public:
  /* Construct a string_file to collect 'raw' output, i.e. without
     'terminal' behavior such as cli_styling.  */
  string_file () : m_term_out (false) {};
  /* If TERM_OUT, construct a string_file with terminal output behavior
     such as cli_styling)
     else collect 'raw' output like the previous constructor.  */
  explicit string_file (bool term_out) : m_term_out (term_out) {};
  ~string_file () override;

  string_file (string_file &&other) = default;

  /* Override ui_file methods.  */

  void write (const char *buf, long length_buf) override;

  long read (char *buf, long length_buf) override
  { gdb_assert_not_reached ("a string_file is not readable"); }

  bool term_out () override;
  bool can_emit_style_escape () override;

  /* string_file-specific public API.  */

  /* Accesses the std::string containing the entire output collected
     so far.  */
  const std::string &string () { return m_string; }

  /* Return an std::string containing the entire output collected so far.

     The internal buffer is cleared, such that it's ready to build a new
     string.  */
  std::string release ()
  {
    std::string ret = std::move (m_string);
    m_string.clear ();
    return ret;
  }

  /* Set the internal buffer contents to STR.  Any existing contents are
     discarded.  */
  string_file &operator= (std::string &&str)
  {
    m_string = std::move (str);
    return *this;
  }

  /* Provide a few convenience methods with the same API as the
     underlying std::string.  */
  const char *data () const { return m_string.data (); }
  const char *c_str () const { return m_string.c_str (); }
  size_t size () const { return m_string.size (); }
  bool empty () const { return m_string.empty (); }
  void clear () { return m_string.clear (); }

private:
  /* The internal buffer.  */
  std::string m_string;

  bool m_term_out;
};

/* A ui_file implementation that maps directly onto <stdio.h>'s FILE.
   A stdio_file can either own its underlying file, or not.  If it
   owns the file, then destroying the stdio_file closes the underlying
   file, otherwise it is left open.  */

class stdio_file : public ui_file
{
public:
  /* Create a ui_file from a previously opened FILE.  CLOSE_P
     indicates whether the underlying file should be closed when the
     stdio_file is destroyed.  */
  explicit stdio_file (FILE *file, bool close_p = false);

  /* Create an stdio_file that is not managing any file yet.  Call
     open to actually open something.  */
  stdio_file ();

  ~stdio_file () override;

  /* Open NAME in mode MODE, and own the resulting file.  Returns true
     on success, false otherwise.  If the stdio_file previously owned
     a file, it is closed.  */
  bool open (const char *name, const char *mode);

  void flush () override;

  void write (const char *buf, long length_buf) override;

  void write_async_safe (const char *buf, long length_buf) override;

  void puts (const char *) override;

  long read (char *buf, long length_buf) override;

  bool isatty () override;

  bool can_emit_style_escape () override;

  /* Return the underlying file descriptor.  */
  int fd () const override
  { return m_fd; }

private:
  /* Sets the internal stream to FILE, and saves the FILE's file
     descriptor in M_FD.  */
  void set_stream (FILE *file);

  /* The file.  */
  FILE *m_file;

  /* The associated file descriptor is extracted ahead of time for
     stdio_file::write_async_safe's benefit, in case fileno isn't
     async-safe.  */
  int m_fd;

  /* If true, M_FILE is closed on destruction.  */
  bool m_close_p;
};

typedef std::unique_ptr<stdio_file> stdio_file_up;

/* Like stdio_file, but specifically for stderr.

   This exists because there is no real line-buffering on Windows, see
   <http://msdn.microsoft.com/en-us/library/86cebhfs%28v=vs.71%29.aspx>
   so the stdout is either fully-buffered or non-buffered.  We can't
   make stdout non-buffered, because of two concerns:

    1. Non-buffering hurts performance.
    2. Non-buffering may change GDB's behavior when it is interacting
       with a front-end, such as Emacs.

   We leave stdout as fully buffered, but flush it first when
   something is written to stderr.

   Note that the 'write_async_safe' method is not overridden, because
   there's no way to flush a stream in an async-safe manner.
   Fortunately, it doesn't really matter, because:

    1. That method is only used for printing internal debug output
       from signal handlers.

    2. Windows hosts don't have a concept of async-safeness.  Signal
       handlers run in a separate thread, so they can call the regular
       non-async-safe output routines freely.
*/
class stderr_file : public stdio_file
{
public:
  explicit stderr_file (FILE *stream);

  /* Override the output routines to flush gdb_stdout before deferring
     to stdio_file for the actual outputting.  */
  void write (const char *buf, long length_buf) override;
  void puts (const char *linebuffer) override;
};

/* A ui_file implementation that maps onto two ui-file objects.  */

class tee_file : public ui_file
{
public:
  /* Create a file which writes to both ONE and TWO.  Ownership of
     both files is up to the user.  */
  tee_file (ui_file *one, ui_file *two);
  ~tee_file () override;

  void write (const char *buf, long length_buf) override;
  void write_async_safe (const char *buf, long length_buf) override;
  void puts (const char *) override;

  bool isatty () override;
  bool term_out () override;
  bool can_emit_style_escape () override;
  void flush () override;

  void emit_style_escape (const ui_file_style &style) override
  {
    m_one->emit_style_escape (style);
    m_two->emit_style_escape (style);
  }

  void reset_style () override
  {
    m_one->reset_style ();
    m_two->reset_style ();
  }

  void puts_unfiltered (const char *str) override
  {
    m_one->puts_unfiltered (str);
    m_two->puts_unfiltered (str);
  }

private:
  /* The two underlying ui_files.  */
  ui_file *m_one;
  ui_file *m_two;
};

/* A ui_file implementation that filters out terminal escape
   sequences.  */

class no_terminal_escape_file : public stdio_file
{
public:
  no_terminal_escape_file ()
  {
  }

  /* Like the stdio_file methods, but these filter out terminal escape
     sequences.  */
  void write (const char *buf, long length_buf) override;
  void puts (const char *linebuffer) override;

  void emit_style_escape (const ui_file_style &style) override
  {
  }

  void reset_style () override
  {
  }
};

/* A base class for ui_file types that wrap another ui_file.  */

class wrapped_file : public ui_file
{
public:

  bool isatty () override
  { return m_stream->isatty (); }

  bool term_out () override
  { return m_stream->term_out (); }

  bool can_emit_style_escape () override
  { return m_stream->can_emit_style_escape (); }

  void flush () override
  { m_stream->flush (); }

  void wrap_here (int indent) override
  { m_stream->wrap_here (indent); }

  void emit_style_escape (const ui_file_style &style) override
  { m_stream->emit_style_escape (style); }

  /* Rest the current output style to the empty style.  */
  void reset_style () override
  { m_stream->reset_style (); }

  int fd () const override
  { return m_stream->fd (); }

  void puts_unfiltered (const char *str) override
  { m_stream->puts_unfiltered (str); }

  void write_async_safe (const char *buf, long length_buf) override
  { return m_stream->write_async_safe (buf, length_buf); }

protected:

  /* Note that this class does not assume ownership of the stream.
     However, a subclass may choose to, by adding a 'delete' to its
     destructor.  */
  explicit wrapped_file (ui_file *stream)
    : m_stream (stream)
  {
  }

  /* The underlying stream.  */
  ui_file *m_stream;
};

/* A ui_file that optionally puts a timestamp at the start of each
   line of output.  */

class timestamped_file : public wrapped_file
{
public:
  explicit timestamped_file (ui_file *stream)
    : wrapped_file (stream)
  {
  }

  DISABLE_COPY_AND_ASSIGN (timestamped_file);

  void write (const char *buf, long len) override;

private:

  /* True if the next output should be timestamped.  */
  bool m_needs_timestamp = true;
};

#endif
