fish-shell/src/output.h
Aaron Gyes 14d2a6d8ff IWYU-guided #include rejiggering.
Let's hope this doesn't causes build failures for e.g. musl: I just
know it's good on macOS and our Linux CI.

It's been a long time.

One fix this brings, is I discovered we #include assert.h or cassert
in a lot of places. If those ever happen to be in a file that doesn't
include common.h, or we are before common.h gets included, we're
unawaringly working with the system 'assert' macro again, which
may get disabled for debug builds or at least has different
behavior on crash. We undef 'assert' and redefine it in common.h.

Those were all eliminated, except in one catch-22 spot for
maybe.h: it can't include common.h. A fix might be to
make a fish_assert.h that *usually* common.h exports.
2022-08-20 23:55:18 -07:00

138 lines
4.2 KiB
C++

// Generic output functions.
//
// Constants for various character classifications. Each character of a command string can be
// classified as one of the following types.
#ifndef FISH_OUTPUT_H
#define FISH_OUTPUT_H
#include <cstdint>
#include <cstring>
#include <cwchar>
#include <string>
#include <vector>
#include "color.h"
#include "common.h"
#include "fallback.h" // IWYU pragma: keep
class env_var_t;
class outputter_t {
/// Storage for buffered contents.
std::string contents_;
/// Count of how many outstanding begin_buffering() calls there are.
uint32_t buffer_count_{0};
/// fd to output to.
int fd_{-1};
rgb_color_t last_color = rgb_color_t::normal();
rgb_color_t last_color2 = rgb_color_t::normal();
bool was_bold = false;
bool was_underline = false;
bool was_italics = false;
bool was_dim = false;
bool was_reverse = false;
void reset_modes() {
was_bold = false;
was_underline = false;
was_italics = false;
was_dim = false;
was_reverse = false;
}
/// Construct an outputter which outputs to a given fd.
explicit outputter_t(int fd) : fd_(fd) {}
/// Flush output, if we have a set fd and our buffering count is 0.
void maybe_flush() {
if (fd_ >= 0 && buffer_count_ == 0) flush_to(fd_);
}
public:
/// Construct an outputter which outputs to its string.
outputter_t() = default;
/// Unconditionally write the color string to the output.
bool write_color(rgb_color_t color, bool is_fg);
/// Set the foreground and background color.
void set_color(rgb_color_t fg, rgb_color_t bg);
/// Write a wide character to the receiver.
void writech(wchar_t ch) { writestr(&ch, 1); }
/// Write a NUL-terminated wide character string to the receiver.
void writestr(const wchar_t *str) { writestr(str, wcslen(str)); }
/// Write a wide character string to the receiver.
void writestr(const wcstring &str) { writestr(str.data(), str.size()); }
/// Write the given terminfo string to the receiver, like tputs().
int term_puts(const char *str, int affcnt);
/// Write a wide string of the given length.
void writestr(const wchar_t *str, size_t len);
/// Write a narrow string of the given length.
void writestr(const char *str, size_t len) {
contents_.append(str, len);
maybe_flush();
}
/// Write a narrow NUL-terminated string.
void writestr(const char *str) { writestr(str, std::strlen(str)); }
/// Write a narrow character.
void push_back(char c) {
contents_.push_back(c);
maybe_flush();
}
/// \return the "output" contents.
const std::string &contents() const { return contents_; }
/// Output any buffered data to the given \p fd.
void flush_to(int fd);
/// Begins buffering. Output will not be automatically flushed until a corresponding
/// end_buffering() call.
void begin_buffering() {
buffer_count_++;
assert(buffer_count_ > 0 && "bufferCount_ overflow");
}
/// Balance a begin_buffering() call.
void end_buffering() {
assert(buffer_count_ > 0 && "bufferCount_ underflow");
buffer_count_--;
maybe_flush();
}
/// Accesses the singleton stdout outputter.
/// This can only be used from the main thread.
/// This outputter flushes its buffer after every write operation.
static outputter_t &stdoutput();
};
void writembs_check(outputter_t &outp, const char *mbs, const char *mbs_name, bool critical,
const char *file, long line);
#define writembs(outp, mbs) writembs_check((outp), (mbs), #mbs, true, __FILE__, __LINE__)
#define writembs_nofail(outp, mbs) writembs_check((outp), (mbs), #mbs, false, __FILE__, __LINE__)
rgb_color_t parse_color(const env_var_t &var, bool is_background);
/// Sets what colors are supported.
enum { color_support_term256 = 1 << 0, color_support_term24bit = 1 << 1 };
using color_support_t = unsigned int;
color_support_t output_get_color_support();
void output_set_color_support(color_support_t val);
rgb_color_t best_color(const std::vector<rgb_color_t> &candidates, color_support_t support);
unsigned char index_for_color(rgb_color_t c);
#endif