/* UI_FILE - a generic STDIO like output stream.
   Copyright (C) 1999-2025 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 GDB_UI_FILE_H
#define GDB_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 /* GDB_UI_FILE_H */
