Using std::string for the attribute buffer

This commit is contained in:
Markus Gans 2021-05-24 21:13:10 +02:00
parent 920daaba1f
commit 95c0717589
17 changed files with 1053 additions and 1029 deletions

View File

@ -1,3 +1,6 @@
2021-05-24 Markus Gans <guru.mail@muenster.de>
* Using std::string for the attribute buffer
2021-05-22 Markus Gans <guru.mail@muenster.de>
* Convert FOptiMove from char[] to std::string

View File

@ -167,22 +167,21 @@ void tcapNumeric (const std::string& name, int cap_num)
}
//----------------------------------------------------------------------
void tcapString (const std::string& name, const char cap_str[])
void tcapString (const std::string& name, const char cap_string[])
{
std::string sequence{};
std::string cap_str{cap_string ? cap_string : std::string{}};
std::cout << name << ": ";
if ( cap_str == nullptr )
if ( cap_str.empty() )
{
std::cout << "\r\n";
return;
}
const auto len = uInt(std::strlen(cap_str));
for (uInt i{0}; i < len; i++)
for (auto&& ch : cap_str)
{
const auto c = uChar(cap_str[i]);
const auto c = uChar(ch);
if ( c > 127 )
{

View File

@ -372,18 +372,16 @@ void FFileDialog::initCallbacks()
inline bool FFileDialog::patternMatch ( const char* const pattern
, const char fname[] ) const
{
std::array<char, 128> search{};
std::string search{};
search.reserve(128);
if ( show_hidden && fname[0] == '.' && fname[1] != '\0' ) // hidden files
{
search[0] = '.';
search[1] = '\0';
std::strncat(search.data(), pattern, search.size() - std::strlen(search.data()) - 1);
search = ".";
search.append(pattern);
}
else
std::strncpy(search.data(), pattern, search.size() - 1);
search[search.size() - 1] = '\0';
search = pattern;
if ( fnmatch (search.data(), fname, FNM_PERIOD) == 0 )
return true;
@ -550,16 +548,11 @@ void FFileDialog::followSymLink (const char* const dir, FDirEntry& entry) const
return; // No symbolic link
std::array<char, MAXPATHLEN> resolved_path{};
std::array<char, MAXPATHLEN> symLink{};
std::string symLink{};
symLink.reserve(MAXPATHLEN);
struct stat sb{};
const auto& fsystem = FTerm::getFSystem();
std::strncpy (symLink.data(), dir, symLink.size() - 1);
symLink[symLink.size() - 1] = '\0';
std::strncat ( symLink.data()
, entry.name.c_str()
, symLink.size() - std::strlen(symLink.data()) - 1);
symLink[symLink.size() - 1] = '\0';
symLink = dir + entry.name;
if ( fsystem->realpath(symLink.data(), resolved_path.data()) == nullptr )
return; // Cannot follow the symlink

View File

@ -396,18 +396,18 @@ inline bool FKeyboard::isKeypressTimeout()
}
//----------------------------------------------------------------------
FKey FKeyboard::UTF8decode (const char utf8[]) const
FKey FKeyboard::UTF8decode (const std::string& utf8) const
{
using distance_type = std::iterator_traits<std::string::iterator>::difference_type;
FKey ucs{FKey::None}; // Universal coded character
constexpr std::size_t max = 4;
std::size_t len = std::strlen(utf8);
const auto len = utf8.length();
auto end = utf8.begin()
+ static_cast<distance_type>(std::min(len, max));
if ( len > max )
len = max;
for (std::size_t i{0}; i < len; ++i)
for (auto iter{utf8.begin()}; iter < end; ++iter)
{
const auto ch = uChar(utf8[i]);
const auto ch = uChar(*iter);
if ( (ch & 0xc0) == 0x80 )
{

View File

@ -39,6 +39,8 @@ namespace finalcut
//----------------------------------------------------------------------
FOptiAttr::FOptiAttr()
{
attr_buf.reserve(SGRoptimizer::ATTR_BUF_SIZE);
// Set bits that must not be reset
reset_byte_mask.attr.bit.transparent = true;
reset_byte_mask.attr.bit.color_overlay = true;
@ -543,11 +545,11 @@ FColor FOptiAttr::vga2ansi (FColor color)
}
//----------------------------------------------------------------------
const char* FOptiAttr::changeAttribute (FChar& term, FChar& next)
std::string FOptiAttr::changeAttribute (FChar& term, FChar& next)
{
const bool next_has_color = hasColor(next);
fake_reverse = false;
attr_buf[0] = '\0';
attr_buf.clear();
prevent_no_color_video_attributes (term, next_has_color);
prevent_no_color_video_attributes (next);
detectSwitchOn (term, next);
@ -559,7 +561,7 @@ const char* FOptiAttr::changeAttribute (FChar& term, FChar& next)
// Look for no changes
if ( ! (switchOn() || switchOff() || hasColorChanged(term, next)) )
return nullptr;
return {};
if ( hasNoAttribute(next) )
{
@ -578,7 +580,7 @@ const char* FOptiAttr::changeAttribute (FChar& term, FChar& next)
if ( FStartOptions::getFStartOptions().sgr_optimizer )
sgr_optimizer.optimize();
return attr_buf.data();
return attr_buf;
}
@ -1537,9 +1539,7 @@ inline bool FOptiAttr::append_sequence (const char seq[])
if ( ! seq )
return false;
char* attr_ptr{attr_buf.data()};
std::strncat (attr_ptr, seq, attr_buf.size() - std::strlen(attr_ptr));
attr_buf[attr_buf.size() - 1] = '\0';
attr_buf.append(seq);
return true;
}

View File

@ -428,9 +428,9 @@ bool FTerm::isInitialized()
//----------------------------------------------------------------------
bool FTerm::isCursorHideable()
{
const char* cursor_off_str = disableCursorString();
const auto& cursor_off_str = disableCursorString();
if ( cursor_off_str && std::strlen(cursor_off_str) > 0 )
if ( ! cursor_off_str.empty() )
return true;
return false;
@ -732,28 +732,28 @@ std::string FTerm::moveCursorString (int xold, int yold, int xnew, int ynew)
}
//----------------------------------------------------------------------
const char* FTerm::cursorsVisibilityString (bool enable)
std::string FTerm::cursorsVisibilityString (bool enable)
{
// Hides or shows the input cursor on the terminal
const char* visibility_str{nullptr};
std::string visibility_str{};
auto& data = FTerm::getFTermData();
if ( data.isCursorHidden() == enable )
return nullptr;
return {};
if ( enable )
{
visibility_str = disableCursorString();
if ( visibility_str )
if ( ! visibility_str.empty() )
data.setCursorHidden (true); // Global state
}
else
{
visibility_str = enableCursorString();
if ( visibility_str )
if ( ! visibility_str.empty() )
data.setCursorHidden (false); // Global state
}
@ -1157,7 +1157,7 @@ void FTerm::initScreenSettings()
}
//----------------------------------------------------------------------
const char* FTerm::changeAttribute (FChar& term_attr, FChar& next_attr)
std::string FTerm::changeAttribute (FChar& term_attr, FChar& next_attr)
{
auto& opti_attr = FTerm::getFOptiAttr();
return opti_attr.changeAttribute (term_attr, next_attr);
@ -1837,19 +1837,20 @@ void FTerm::setOverwriteCursorStyle()
}
//----------------------------------------------------------------------
const char* FTerm::enableCursorString()
std::string FTerm::enableCursorString()
{
// Returns the cursor enable string
static constexpr std::size_t SIZE = 32;
static std::array<char, SIZE> enable_str{};
static constexpr std::string::size_type SIZE{32u};
std::string enable_str{};
enable_str.reserve(SIZE);
const auto& vs = TCAP(t_cursor_visible);
const auto& ve = TCAP(t_cursor_normal);
if ( ve )
std::strncpy (enable_str.data(), ve, SIZE - 1);
enable_str = ve;
else if ( vs )
std::strncpy (enable_str.data(), vs, SIZE - 1);
enable_str = vs;
#if defined(__linux__)
if ( isLinuxTerm() )
@ -1857,13 +1858,10 @@ const char* FTerm::enableCursorString()
// Restore the last used Linux console cursor style
auto& linux_console = FTerm::getFTermLinux();
const char* cstyle = linux_console.getCursorStyleString();
std::size_t length = std::strlen(enable_str.data());
std::strncat (enable_str.data(), cstyle, SIZE - length - 1);
enable_str.append(cstyle);
}
#endif // defined(__linux__)
enable_str[SIZE - 1] = '\0';
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
if ( isFreeBSDTerm() )
{
@ -1873,11 +1871,11 @@ const char* FTerm::enableCursorString()
}
#endif // defined(__FreeBSD__) || defined(__DragonFly__) || defined(UNIT_TEST)
return enable_str.data();
return enable_str;
}
//----------------------------------------------------------------------
const char* FTerm::disableCursorString()
std::string FTerm::disableCursorString()
{
// Returns the cursor disable string
@ -1886,7 +1884,7 @@ const char* FTerm::disableCursorString()
if ( vi )
return vi;
return nullptr;
return {};
}
//----------------------------------------------------------------------

View File

@ -689,10 +689,10 @@ FPoint readCursorPos()
const int stdout_no{FTermios::getStdOut()};
fd_set ifds{};
struct timeval tv{};
constexpr auto& DECXCPR{ESC "[6n"};
const std::string DECXCPR{ESC "[6n"};
// Report Cursor Position (DECXCPR)
if ( write(stdout_no, DECXCPR, std::strlen(DECXCPR)) < 1 )
if ( write(stdout_no, DECXCPR.data(), DECXCPR.length()) < 1 )
return {x, y};
std::fflush(stdout);

View File

@ -330,9 +330,9 @@ void FTermDetection::termtypeAnalysis()
if ( std::strncmp(termtype, "screen", 6) == 0 )
{
terminal_type.screen = true;
const char* tmux = std::getenv("TMUX");
std::string tmux = std::getenv("TMUX");
if ( tmux && std::strlen(tmux) != 0 )
if ( tmux.length() != 0 )
terminal_type.tmux = true;
}
@ -813,10 +813,10 @@ FString FTermDetection::getSecDA()
const int stdout_no{FTermios::getStdOut()};
fd_set ifds{};
struct timeval tv{};
constexpr auto& SECDA{ESC "[>c"};
const std::string SECDA{ESC "[>c"};
// Get the secondary device attributes
if ( write(stdout_no, SECDA, std::strlen(SECDA)) == -1 )
if ( write(stdout_no, SECDA.data(), SECDA.length()) == -1 )
return sec_da_str;
std::fflush(stdout);

View File

@ -769,12 +769,12 @@ FString FTermXTerminal::captureXTermFont() const
&& temp[3] == '0' && temp[4] == ';' )
{
// Skip leading Esc ] 5 0 ;
char* str = &temp[5];
const std::size_t n = std::strlen(str);
std::string str = &temp[5];
const std::size_t n = str.length();
// BEL + '\0' = string terminator
if ( n >= 5 && str[n - 1] == BEL[0] && str[n] == '\0' )
str[n - 1] = '\0';
str.erase(n - 1);
return {str};
}
@ -822,8 +822,8 @@ FString FTermXTerminal::captureXTermTitle() const
if ( pos > 6 && temp[0] == ESC[0] && temp[1] == ']' && temp[2] == 'l' )
{
// Skip leading Esc + ] + l = OSC l
char* str = &temp[3];
const std::size_t n = std::strlen(str);
std::string str = &temp[3];
const std::size_t n = str.length();
// Esc + \ = OSC string terminator
if ( n >= 2 && str[n - 2] == ESC[0] && str[n - 1] == '\\' )
@ -831,7 +831,7 @@ FString FTermXTerminal::captureXTermTitle() const
if ( n < 4 )
return {};
str[n - 2] = '\0';
str.erase(n - 2);
return {str};
}
}

View File

@ -185,9 +185,9 @@ void FVTerm::hideCursor (bool enable) const
if ( ! cursor_hideable )
return;
const char* visibility_str = FTerm::cursorsVisibilityString (enable);
auto visibility_str = FTerm::cursorsVisibilityString (enable);
if ( ! visibility_str ) // Exit the function if the string is empty
if ( visibility_str.empty() ) // Exit the function if the string is empty
return;
appendOutputBuffer(FTermControl{visibility_str});
@ -1764,8 +1764,8 @@ FChar FVTerm::getCharacter ( CharacterType char_type
const int x = pos.getX();
const int y = pos.getY();
int xx = ( x > 0 ) ? x : 0;
int yy = ( y > 0 ) ? y : 0;
int xx = std::max(x, 0);
int yy = std::max(y, 0);
if ( xx >= vterm->width )
xx = vterm->width - 1;
@ -3080,7 +3080,7 @@ inline void FVTerm::appendAttributes (FChar& next_attr) const
// generate attribute string for the next character
const auto& attr_str = FTerm::changeAttribute (term_attribute, next_attr);
if ( attr_str )
if ( ! attr_str.empty() )
appendOutputBuffer (FTermControl{attr_str});
}

View File

@ -20,6 +20,7 @@
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <algorithm>
#include <vector>
#include "final/fapplication.h"
@ -405,7 +406,7 @@ void FWidget::setPos (const FPoint& p, bool adjust)
return;
}
if ( ! isWindowWidget() )
if ( ! isWindowWidget() ) // A widgets must be inside the client area
{
if ( pos.getX() < 1 )
pos.setX(1);
@ -430,7 +431,7 @@ void FWidget::setWidth (std::size_t width, bool adjust)
if ( getWidth() == width && wsize.getWidth() == width )
return;
if ( width < 1 )
if ( width < 1 ) // A width can never be narrower than 1 character
width = 1;
wsize.setWidth(width);
@ -452,7 +453,7 @@ void FWidget::setHeight (std::size_t height, bool adjust)
if ( getHeight() == height && wsize.getHeight() == height )
return;
if ( height < 1 )
if ( height < 1 ) // A height can never be narrower than 1 character
height = 1;
wsize.setHeight(height);
@ -479,10 +480,10 @@ void FWidget::setSize (const FSize& size, bool adjust)
&& getHeight() == height && wsize.getHeight() == height )
return;
if ( width < 1 )
if ( width < 1 ) // A width can never be narrower than 1 character
width = 1;
if ( height < 1 )
if ( height < 1 ) // A height can never be narrower than 1 character
height = 1;
wsize.setWidth(width);
@ -624,20 +625,19 @@ void FWidget::setGeometry (const FPoint& p, const FSize& s, bool adjust)
if ( getPos() == p && getWidth() == w && getHeight() == h )
return;
if ( ! isWindowWidget() )
{
( x < 1 ) ? wsize.setX(1) : wsize.setX(x);
( y < 1 ) ? wsize.setY(1) : wsize.setY(y);
}
else
if ( isWindowWidget() ) // A window widget can be outside
{
wsize.setX(x);
wsize.setY(y);
}
else // A normal widget must be inside the client area
{
wsize.setX(std::max(x, 1));
wsize.setY(std::max(y, 1));
}
( w < 1 ) ? wsize.setWidth(1) : wsize.setWidth(w);
( h < 1 ) ? wsize.setHeight(1) : wsize.setHeight(h);
wsize.setWidth(std::max(w, std::size_t(1u)));
wsize.setHeight(std::max(h, std::size_t(1u)));
adjust_wsize = wsize;
const int term_x = getTermX();
const int term_y = getTermY();

View File

@ -162,7 +162,7 @@ class FKeyboard final
static bool isIntervalTimeout();
// Methods
FKey UTF8decode (const char[]) const;
FKey UTF8decode (const std::string&) const;
ssize_t readKey();
void parseKeyBuffer();
FKey parseKeyString();

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2016-2020 Markus Gans *
* Copyright 2016-2021 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -156,7 +156,7 @@ class FOptiAttr final
// Methods
void initialize();
static FColor vga2ansi (FColor);
const char* changeAttribute (FChar&, FChar&);
std::string changeAttribute (FChar&, FChar&);
private:
struct Capability
@ -165,9 +165,6 @@ class FOptiAttr final
bool caused_reset;
};
// Using-declaration
using AttributeBuffer = SGRoptimizer::AttributeBuffer;
// Enumerations
enum init_reset_tests
{
@ -303,8 +300,8 @@ class FOptiAttr final
FChar off{};
FChar reset_byte_mask{};
std::string attr_buf{};
SGRoptimizer sgr_optimizer{attr_buf};
AttributeBuffer attr_buf{};
int max_color{1};
int attr_without_color{0};

View File

@ -268,7 +268,7 @@ class FTerm final
static int openConsole();
static int closeConsole();
static std::string moveCursorString (int, int, int, int);
static const char* cursorsVisibilityString (bool = true);
static std::string cursorsVisibilityString (bool = true);
static void detectTermSize();
static void setTermSize (const FSize&);
static void setTermTitle (const FString&);
@ -301,7 +301,7 @@ class FTerm final
void initTerminal();
static void initScreenSettings();
static const char* changeAttribute (FChar&, FChar&);
static std::string changeAttribute (FChar&, FChar&);
static void changeTermSizeFinished();
private:
@ -336,8 +336,8 @@ class FTerm final
static void restoreColorPalette();
static void setInsertCursorStyle();
static void setOverwriteCursorStyle();
static const char* enableCursorString();
static const char* disableCursorString();
static std::string enableCursorString();
static std::string disableCursorString();
static void enableMouse();
static void disableMouse();
static void enableApplicationEscKey();

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2019-2020 Markus Gans *
* Copyright 2019-2021 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -49,13 +49,10 @@ class SGRoptimizer final
{
public:
// Constants
static constexpr std::size_t ATTR_BUF_SIZE{8192};
// Using-declaration
using AttributeBuffer = std::array<char, ATTR_BUF_SIZE>;
static constexpr std::string::size_type ATTR_BUF_SIZE{8192u};
// Constructors
explicit SGRoptimizer (AttributeBuffer&);
explicit SGRoptimizer (std::string&);
// Disable copy constructor
SGRoptimizer (const SGRoptimizer&) = delete;
@ -78,7 +75,7 @@ class SGRoptimizer final
void combineParameter();
// Data member
AttributeBuffer& seq;
std::string& seq;
struct parameter
{

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2019-2020 Markus Gans *
* Copyright 2019-2021 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -19,7 +19,7 @@
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <iostream>
#include <cstring>
#include <vector>
@ -35,9 +35,11 @@ namespace finalcut
// constructors and destructor
//----------------------------------------------------------------------
SGRoptimizer::SGRoptimizer (AttributeBuffer& sequence)
SGRoptimizer::SGRoptimizer (std::string& sequence)
: seq{sequence}
{ }
{
seq.reserve(ATTR_BUF_SIZE);
}
// public methods of SGRoptimizer
@ -55,7 +57,7 @@ void SGRoptimizer::findParameter()
{
// Find ANSI X3.64 terminal SGR (Select Graphic Rendition) strings
const std::size_t len = std::strlen(seq.data());
const std::size_t len = seq.length();
csi_parameter.clear();
if ( len < 6 )
@ -105,6 +107,7 @@ void SGRoptimizer::combineParameter()
return;
const auto& first = csi_parameter.front();
const std::size_t len = seq.length();
std::size_t count = 1;
std::size_t read_pos{};
std::size_t write_pos = first.end;
@ -146,12 +149,14 @@ void SGRoptimizer::combineParameter()
}
}
while ( seq[write_pos] != '\0' )
while ( read_pos < len )
{
seq[write_pos] = seq[read_pos];
read_pos++;
write_pos++;
}
seq.erase(write_pos);
}
} // namespace finalcut

File diff suppressed because it is too large Load Diff