Implementation of an own padding print method for sending control codes to the terminal

This commit is contained in:
Markus Gans 2021-03-10 00:26:22 +01:00
parent f048d846da
commit 465fd9510a
40 changed files with 876 additions and 199 deletions

View File

@ -1,3 +1,7 @@
2021-02-09 Markus Gans <guru.mail@muenster.de>
* Implementation of an own padding print method for sending
control codes to the terminal
2021-02-28 Markus Gans <guru.mail@muenster.de>
* Removing the termcap library from the header files so
that FINAL CUT programs are not affected by the preprocessor

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 *
@ -1183,13 +1183,13 @@ void Calc::mapKeyFunctions()
//----------------------------------------------------------------------
inline bool operator < (const Calc::ButtonName& c, const int n) noexcept
{
return bool( int(c) < n );
return int(c) < n;
}
//----------------------------------------------------------------------
inline bool operator <= (const Calc::ButtonName& c, const int n) noexcept
{
return bool( int(c) <= n );
return int(c) <= n;
}
//----------------------------------------------------------------------

View File

@ -51,15 +51,16 @@ struct Data
const Termcap cap;
};
static std::array<TermcapString, 83> strings;
static std::array<TermcapString, 85> strings;
};
//----------------------------------------------------------------------
// struct data - string data array
//----------------------------------------------------------------------
std::array<Data::TermcapString, 83> Data::strings =
std::array<Data::TermcapString, 85> Data::strings =
{{
{ "t_bell", Termcap::t_bell },
{ "t_flash_screen", Termcap::t_flash_screen },
{ "t_erase_chars", Termcap::t_erase_chars },
{ "t_clear_screen", Termcap::t_clear_screen },
{ "t_clr_eos", Termcap::t_clr_eos },
@ -70,6 +71,7 @@ std::array<Data::TermcapString, 83> Data::strings =
{ "t_carriage_return", Termcap::t_carriage_return },
{ "t_tab", Termcap::t_tab },
{ "t_back_tab", Termcap::t_back_tab },
{ "t_pad_char", Termcap::t_pad_char },
{ "t_insert_padding", Termcap::t_insert_padding },
{ "t_insert_character", Termcap::t_insert_character },
{ "t_parm_ich", Termcap::t_parm_ich },
@ -266,6 +268,10 @@ void booleans()
, finalcut::FTermcap::osc_support );
tcapBoolean ( "no_utf8_acs_chars"
, finalcut::FTermcap::no_utf8_acs_chars );
tcapBoolean ( "no_padding_char"
, finalcut::FTermcap::no_padding_char );
tcapBoolean ( "xon_xoff_flow_control"
, finalcut::FTermcap::xon_xoff_flow_control );
}
//----------------------------------------------------------------------
@ -276,6 +282,8 @@ void numeric()
, finalcut::FTermcap::max_color);
tcapNumeric ("tabstop"
, finalcut::FTermcap::tabstop);
tcapNumeric ("padding_baudrate"
, finalcut::FTermcap::padding_baudrate);
tcapNumeric ("attr_without_color"
, finalcut::FTermcap::attr_without_color);
}

View File

@ -59,7 +59,7 @@ inline bool isLessThanInteger ( const finalcut::FString& lhs
{
const sInt64 l_number = stringToNumber(lhs);
const sInt64 r_number = stringToNumber(rhs);
return bool( l_number < r_number ); // lhs < rhs
return l_number < r_number; // lhs < rhs
}
//----------------------------------------------------------------------
@ -69,7 +69,7 @@ inline bool isLessThanDouble ( const finalcut::FString& lhs
std::setlocale(LC_NUMERIC, "C");
const double l_number = lhs.toDouble();
const double r_number = rhs.toDouble();
return bool( l_number < r_number ); // lhs < rhs
return l_number < r_number; // lhs < rhs
}
//----------------------------------------------------------------------
@ -78,7 +78,7 @@ inline bool isGreaterThanInteger ( const finalcut::FString& lhs
{
const sInt64 l_number = stringToNumber(lhs);
const sInt64 r_number = stringToNumber(rhs);
return bool( l_number > r_number ); // lhs > rhs
return l_number > r_number; // lhs > rhs
}
//----------------------------------------------------------------------
@ -88,7 +88,7 @@ inline bool isGreaterThanDouble ( const finalcut::FString& lhs
std::setlocale(LC_NUMERIC, "C");
const double l_number = lhs.toDouble();
const double r_number = rhs.toDouble();
return bool( l_number > r_number ); // lhs > rhs
return l_number > r_number; // lhs > rhs
}
//----------------------------------------------------------------------

View File

@ -4,7 +4,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2014-2020 Markus Gans *
* Copyright 2014-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 *
@ -386,7 +386,7 @@ bool FButtonGroup::isRadioButton (const FToggleButton* button) const
if ( ! button )
return false;
return bool( button->getClassName() == "FRadioButton" );
return button->getClassName() == "FRadioButton";
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2012-2020 Markus Gans *
* Copyright 2012-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 *
@ -112,7 +112,7 @@ bool FDialog::setModal (bool enable)
//----------------------------------------------------------------------
bool FDialog::setScrollable (bool enable)
{
return (setFlags().scrollable = enable);
return ( setFlags().scrollable = enable );
}
@ -134,7 +134,7 @@ bool FDialog::setBorder (bool enable)
setRightPadding(0);
}
return (setFlags().no_border = ! enable);
return ( setFlags().no_border = ! enable );
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2014-2020 Markus Gans *
* Copyright 2014-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 *
@ -184,13 +184,13 @@ FFocusEvent::FFocusEvent (Event ev_type) // constructor
//----------------------------------------------------------------------
bool FFocusEvent::gotFocus() const
{
return ( getType() == Event::FocusIn );
return getType() == Event::FocusIn;
}
//----------------------------------------------------------------------
bool FFocusEvent::lostFocus() const
{
return ( getType() == Event::FocusOut );
return getType() == Event::FocusOut;
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2014-2020 Markus Gans *
* Copyright 2014-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 *
@ -41,7 +41,7 @@ bool sortByName ( const FFileDialog::FDirEntry& lhs
, const FFileDialog::FDirEntry& rhs )
{
// lhs < rhs
return bool( strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0 );
return strcasecmp(lhs.name.c_str(), rhs.name.c_str()) < 0;
}
//----------------------------------------------------------------------
@ -131,9 +131,9 @@ FString FFileDialog::getSelectedFile() const
const auto n = uLong(filebrowser.currentItem() - 1);
if ( dir_entries[n].directory )
return FString{""};
return {""};
else
return FString{dir_entries[n].name};
return {dir_entries[n].name};
}
//----------------------------------------------------------------------
@ -695,9 +695,9 @@ FString FFileDialog::getHomeDir()
const uid_t euid = fsystem->geteuid();
if ( fsystem->getpwuid_r(euid, &pwd, buf.data(), buf.size(), &pwd_ptr) )
return FString{""};
return {""};
else
return FString{pwd.pw_dir};
return {pwd.pw_dir};
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2018-2020 Markus Gans *
* Copyright 2018-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 *
@ -91,17 +91,17 @@ FString FKeyboard::getKeyName (const FKey keynum) const
fc::fkeyname.cend(),
[&keynum] (const fc::FKeyName& kn)
{
return (kn.num != FKey::None && kn.num == keynum);
return ( kn.num != FKey::None && kn.num == keynum );
}
);
if ( found_key != fc::fkeyname.end() )
return FString{found_key->string};
return {found_key->string};
if ( keynum > 32 && keynum < 127 )
return FString{char(keynum)};
return {char(keynum)};
return FString{""};
return {""};
}
//----------------------------------------------------------------------

View File

@ -763,13 +763,13 @@ inline std::size_t FLineEdit::getCursorColumnPos() const
//----------------------------------------------------------------------
inline FString FLineEdit::getPasswordText() const
{
return FString{text.getLength(), UniChar::Bullet}; // •
return {text.getLength(), UniChar::Bullet}; // •
}
//----------------------------------------------------------------------
inline bool FLineEdit::isPasswordField() const
{
return bool( input_type == InputType::Password );
return input_type == InputType::Password;
}
//----------------------------------------------------------------------

View File

@ -122,7 +122,7 @@ bool sortAscendingByName (const FObject* lhs, const FObject* rhs)
const auto& r_string = r_item->getText(column);
// lhs < rhs
return bool( strcasecmp(l_string.c_str(), r_string.c_str()) < 0 );
return strcasecmp(l_string.c_str(), r_string.c_str()) < 0;
}
//----------------------------------------------------------------------
@ -135,7 +135,7 @@ bool sortDescendingByName (const FObject* lhs, const FObject* rhs)
const auto& r_string = r_item->getText(column);
// lhs > rhs
return bool( strcasecmp(l_string.c_str(), r_string.c_str()) > 0 );
return strcasecmp(l_string.c_str(), r_string.c_str()) > 0;
}
//----------------------------------------------------------------------
@ -148,7 +148,7 @@ bool sortAscendingByNumber (const FObject* lhs, const FObject* rhs)
const auto& r_number = firstNumberFromString(r_item->getText(column));
// lhs < rhs
return bool( l_number < r_number );
return l_number < r_number;
}
//----------------------------------------------------------------------
@ -161,7 +161,7 @@ bool sortDescendingByNumber (const FObject* lhs, const FObject* rhs)
const auto& r_number = firstNumberFromString(r_item->getText(column));
// lhs > rhs
return bool( l_number > r_number );
return l_number > r_number;
}

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2020 Markus Gans *
* Copyright 2020-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 *
@ -63,7 +63,7 @@ std::string FLogger::getTimeString() const
struct tm time{};
localtime_r (&t, &time);
std::strftime (str.data(), str.size(), "%a, %d %b %Y %T %z", &time);
return std::string(str.data());
return {str.data()};
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2015-2020 Markus Gans *
* Copyright 2015-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 *
@ -478,7 +478,7 @@ bool FMenuItem::isMenu (const FWidget* w) const
const bool m1 = w->isInstanceOf("FMenu");
const bool m2 = w->isInstanceOf("FDialogListMenu");
return bool( m1 || m2 );
return m1 || m2;
}

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2018-2020 Markus Gans *
* Copyright 2018-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 *
@ -62,81 +62,82 @@ const FPoint& FMouseData::getPos() const
{
return mouse;
}
//----------------------------------------------------------------------
bool FMouseData::isLeftButtonPressed() const
{
return bool(getButtonState().left_button == State::Pressed);
return getButtonState().left_button == State::Pressed;
}
//----------------------------------------------------------------------
bool FMouseData::isLeftButtonReleased() const
{
return bool(getButtonState().left_button == State::Released);
return getButtonState().left_button == State::Released;
}
//----------------------------------------------------------------------
bool FMouseData::isLeftButtonDoubleClick() const
{
return bool(getButtonState().left_button == State::DoubleClick);
return getButtonState().left_button == State::DoubleClick;
}
//----------------------------------------------------------------------
bool FMouseData::isRightButtonPressed() const
{
return bool(getButtonState().right_button == State::Pressed);
return getButtonState().right_button == State::Pressed;
}
//----------------------------------------------------------------------
bool FMouseData::isRightButtonReleased() const
{
return bool(getButtonState().right_button == State::Released);
return getButtonState().right_button == State::Released;
}
//----------------------------------------------------------------------
bool FMouseData::isMiddleButtonPressed() const
{
return bool(getButtonState().middle_button == State::Pressed);
return getButtonState().middle_button == State::Pressed;
}
//----------------------------------------------------------------------
bool FMouseData::isMiddleButtonReleased() const
{
return bool(getButtonState().middle_button == State::Released);
return getButtonState().middle_button == State::Released;
}
//----------------------------------------------------------------------
bool FMouseData::isShiftKeyPressed() const
{
return bool(getButtonState().shift_button);
return getButtonState().shift_button;
}
//----------------------------------------------------------------------
bool FMouseData::isControlKeyPressed() const
{
return bool(getButtonState().control_button);
return getButtonState().control_button;
}
//----------------------------------------------------------------------
bool FMouseData::isMetaKeyPressed() const
{
return bool(getButtonState().meta_button);
return getButtonState().meta_button;
}
//----------------------------------------------------------------------
bool FMouseData::isWheelUp() const
{
return bool(getButtonState().wheel_up);
return getButtonState().wheel_up;
}
//----------------------------------------------------------------------
bool FMouseData::isWheelDown() const
{
return bool(getButtonState().wheel_down);
return getButtonState().wheel_down;
}
//----------------------------------------------------------------------
bool FMouseData::isMoved() const
{
return bool(getButtonState().mouse_moved);
return getButtonState().mouse_moved;
}
//----------------------------------------------------------------------
@ -551,7 +552,7 @@ FString FMouseX11::getClassName() const
//----------------------------------------------------------------------
bool FMouseX11::hasData()
{
return bool(x11_mouse[0]);
return ( x11_mouse[0] );
}
//----------------------------------------------------------------------
@ -729,7 +730,7 @@ FString FMouseSGR::getClassName() const
//----------------------------------------------------------------------
bool FMouseSGR::hasData()
{
return bool(sgr_mouse[0]);
return ( sgr_mouse[0] );
}
//----------------------------------------------------------------------
@ -959,7 +960,7 @@ FString FMouseUrxvt::getClassName() const
//----------------------------------------------------------------------
bool FMouseUrxvt::hasData()
{
return bool(urxvt_mouse[0]);
return ( urxvt_mouse[0] );
}
//----------------------------------------------------------------------

View File

@ -1129,13 +1129,13 @@ bool FOptiAttr::hasNoAttribute (const FChar& attr)
inline bool FOptiAttr::hasColorChanged ( const FChar& term
, const FChar& next ) const
{
bool frev ( ( on.attr.bit.reverse
bool frev { ( on.attr.bit.reverse
|| on.attr.bit.standout
|| off.attr.bit.reverse
|| off.attr.bit.standout ) && fake_reverse );
return bool ( frev
|| term.fg_color != next.fg_color
|| term.bg_color != next.bg_color );
|| off.attr.bit.standout ) && fake_reverse };
return frev
|| term.fg_color != next.fg_color
|| term.bg_color != next.bg_color;
}
//----------------------------------------------------------------------

View File

@ -895,10 +895,9 @@ inline void FOptiMove::leftMove ( char hmove[], int& htime
inline bool FOptiMove::isWideMove ( int xold, int yold
, int xnew, int ynew ) const
{
return bool ( xnew > MOVE_LIMIT
&& xnew < int(screen_width) - 1 - MOVE_LIMIT
&& std::abs(xnew - xold) + std::abs(ynew - yold)
> MOVE_LIMIT );
return xnew > MOVE_LIMIT
&& xnew < int(screen_width) - 1 - MOVE_LIMIT
&& std::abs(xnew - xold) + std::abs(ynew - yold) > MOVE_LIMIT;
}
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2014-2020 Markus Gans *
* Copyright 2014-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 *

View File

@ -333,7 +333,7 @@ const FString& FString::operator >> (float& num) const
//----------------------------------------------------------------------
FString::operator bool () const
{
return bool(string);
return string;
}
//----------------------------------------------------------------------
@ -404,7 +404,7 @@ char* FString::c_str()
//----------------------------------------------------------------------
std::string FString::toString() const
{
return std::string(c_str(), length);
return {c_str(), length};
}
//----------------------------------------------------------------------
@ -442,7 +442,7 @@ sInt16 FString::toShort() const
if ( num < SHRT_MIN )
throw std::underflow_error ("underflow");
return sInt16(num);
return static_cast<sInt16>(num);
}
//----------------------------------------------------------------------
@ -453,7 +453,7 @@ uInt16 FString::toUShort() const
if ( num > USHRT_MAX )
throw std::overflow_error ("overflow");
return uInt16(num);
return static_cast<uInt16>(num);
}
//----------------------------------------------------------------------
@ -467,7 +467,7 @@ int FString::toInt() const
if ( num < INT_MIN )
throw std::underflow_error ("underflow");
return int(num);
return static_cast<int>(num);
}
//----------------------------------------------------------------------
@ -478,7 +478,7 @@ uInt FString::toUInt() const
if ( num > UINT_MAX )
throw std::overflow_error ("overflow");
return uInt(num);
return static_cast<uInt>(num);
}
//----------------------------------------------------------------------
@ -532,7 +532,7 @@ long FString::toLong() const
if ( neg )
num = (~num) + 1;
return num;
return static_cast<long>(num);
}
//----------------------------------------------------------------------
@ -576,7 +576,7 @@ uLong FString::toULong() const
if ( *p != L'\0' && ! std::iswdigit(std::wint_t(*p)) )
throw std::invalid_argument ("no valid number");
return num;
return static_cast<uLong>(num);
}
//----------------------------------------------------------------------
@ -590,7 +590,7 @@ float FString::toFloat() const
if ( std::fabs(num) < double(FLT_EPSILON) ) // num == 0.0f
throw std::underflow_error ("underflow");
return float(num);
return static_cast<float>(num);
}
//----------------------------------------------------------------------
@ -722,7 +722,7 @@ FString FString::mid (std::size_t pos, std::size_t len) const
len = length - pos + 1;
if ( pos > length || pos + len - 1 > length || len == 0 )
return FString{L""};
return {L""};
wchar_t* p = s.string;
wchar_t* first = p + pos - 1;
@ -907,7 +907,7 @@ bool FString::operator < (const FString& s) const
if ( ! (string || s.string) )
return false;
return ( std::wcscmp(string, s.string) < 0 );
return std::wcscmp(string, s.string) < 0;
}
//----------------------------------------------------------------------
@ -922,7 +922,7 @@ bool FString::operator <= (const FString& s) const
if ( ! string && s.string )
return true;
return ( std::wcscmp(string, s.string) <= 0 );
return std::wcscmp(string, s.string) <= 0;
}
//----------------------------------------------------------------------
@ -934,7 +934,7 @@ bool FString::operator == (const FString& s) const
if ( bool(string) != bool(s.string) || length != s.length )
return false;
return ( std::wcscmp(string, s.string) == 0 );
return std::wcscmp(string, s.string) == 0;
}
//----------------------------------------------------------------------
@ -955,7 +955,7 @@ bool FString::operator >= (const FString& s) const
if ( ! (string || s.string) )
return true;
return ( std::wcscmp(string, s.string) >= 0 );
return std::wcscmp(string, s.string) >= 0;
}
//----------------------------------------------------------------------
@ -970,7 +970,7 @@ bool FString::operator > (const FString& s) const
if ( ! string && s.string )
return false;
return ( std::wcscmp(string, s.string) > 0 );
return std::wcscmp(string, s.string) > 0;
}
//----------------------------------------------------------------------
@ -1189,7 +1189,7 @@ bool FString::includes (const FString& s) const
if ( ! (string && s.string) )
return false;
return ( std::wcsstr(string, s.string) != nullptr );
return std::wcsstr(string, s.string) != nullptr;
}

View File

@ -20,10 +20,10 @@
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <array>
#include <algorithm>
#include <unordered_map>
#include <array>
#include <string>
#include <unordered_map>
#include <vector>
#include "final/fapplication.h"
@ -974,10 +974,7 @@ void FTerm::resetBeep()
void FTerm::beep()
{
if ( TCAP(t_bell) )
{
putstring (TCAP(t_bell));
std::fflush(stdout);
}
}
//----------------------------------------------------------------------
@ -1054,7 +1051,7 @@ std::string FTerm::getEncodingString()
bool FTerm::charEncodable (wchar_t c)
{
const wchar_t ch = charEncode(c);
return bool(ch > 0 && ch != c);
return ch > 0 && ch != c;
}
//----------------------------------------------------------------------
@ -1558,7 +1555,7 @@ bool FTerm::init_font()
FApplication::exit(EXIT_FAILURE);
}
return ( ! FApplication::isQuit() );
return ! FApplication::isQuit();
}
//----------------------------------------------------------------------

View File

@ -276,7 +276,7 @@ bool hasFullWidthSupports()
has_fullwidth_support = FullWidthSupport::Yes;
}
return ( has_fullwidth_support == FullWidthSupport::Yes) ? true : false;
return ( has_fullwidth_support == FullWidthSupport::Yes ) ? true : false;
}
//----------------------------------------------------------------------
@ -385,7 +385,7 @@ FString getColumnSubString ( const FString& str
std::size_t num{0};
if ( col_len == 0 || s.isEmpty() )
return FString{L""};
return {L""};
if ( col_pos == 0 )
col_pos = 1;
@ -431,7 +431,7 @@ FString getColumnSubString ( const FString& str
}
if ( col_first < col_pos ) // String length < col_pos
return FString{L""};
return {L""};
return s.mid(first, num);
}
@ -590,7 +590,7 @@ int getCharLength (const FString& string, std::size_t pos)
}
while ( n < len && char_width == 0 && ! isWhitespace(string[n]) );
return int(n - pos);
return static_cast<int>(n - pos);
}
//----------------------------------------------------------------------
@ -684,7 +684,7 @@ FPoint readCursorPos()
// Report Cursor Position (DECXCPR)
if ( write(stdout_no, DECXCPR, std::strlen(DECXCPR)) < 1 )
return FPoint{x, y};
return {x, y};
std::fflush(stdout);
FD_ZERO(&ifds);
@ -696,7 +696,7 @@ FPoint readCursorPos()
// Read the answer
if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) != 1 )
return FPoint{x, y};
return {x, y};
do
{
@ -716,7 +716,7 @@ FPoint readCursorPos()
std::sscanf(temp.data(), parse, &y, &x );
}
return FPoint{x, y};
return {x, y};
}
} // namespace finalcut

View File

@ -42,6 +42,7 @@
#include <algorithm>
#include <string>
#include <thread>
#include <vector>
#include "final/emptyfstring.h"
@ -68,9 +69,14 @@ bool FTermcap::has_ansi_escape_sequences{false};
bool FTermcap::ansi_default_color {false};
bool FTermcap::osc_support {false};
bool FTermcap::no_utf8_acs_chars {false};
bool FTermcap::no_padding_char {false};
bool FTermcap::xon_xoff_flow_control {false};
int FTermcap::max_color {1};
int FTermcap::tabstop {8};
int FTermcap::padding_baudrate {0};
int FTermcap::attr_without_color {0};
int FTermcap::baudrate {9600};
char FTermcap::PC {'\0'};
char FTermcap::string_buf[2048] {};
//----------------------------------------------------------------------
@ -90,13 +96,14 @@ char FTermcap::string_buf[2048] {};
//----------------------------------------------------------------------
bool FTermcap::getFlag (const std::string& cap)
{
return ::tgetflag(C_STR(cap.data()));
return ::tgetflag(C_STR(cap.data())) == 1;
}
//----------------------------------------------------------------------
int FTermcap::getNumber (const std::string& cap)
{
return ::tgetnum(C_STR(cap.data()));
auto num = ::tgetnum(C_STR(cap.data()));
return ( num > 0) ? num : 0;
}
//----------------------------------------------------------------------
@ -112,6 +119,110 @@ std::string FTermcap::encodeMotionParameter (const std::string& cap, int col, in
return ( str ) ? str : std::string();
}
//----------------------------------------------------------------------
FTermcap::Status FTermcap::paddingPrint ( const std::string& string
, int affcnt
, const defaultPutChar& outc )
{
if ( string.empty() )
return Status::Error;
bool has_delay = (TCAP(t_bell) && string == std::string(TCAP(t_bell)))
|| (TCAP(t_flash_screen) && string == std::string(TCAP(t_flash_screen)))
|| ( ! xon_xoff_flow_control && padding_baudrate
&& (baudrate >= padding_baudrate) );
auto iter = string.begin();
while ( iter != string.end() )
{
if ( *iter != '$' )
outc(int(*iter));
else
{
++iter;
if ( *iter != '<' )
{
outc(int('$'));
if ( iter != string.end() )
outc(int(*iter));
}
else
{
++iter;
const auto first_digit = iter;
if ( (! std::isdigit(int(*iter)) && *iter != '.') )
{
outc(int('$'));
outc(int('<'));
continue;
}
int number = 0;
while ( std::isdigit(int(*iter)) && number < 1000 )
{
number = number * 10 + (*iter - '0');
++iter;
}
number *= 10;
if ( *iter == '.' )
{
++iter;
if ( std::isdigit(int(*iter)) )
{
number += (*iter - '0'); // Position after decimal point
++iter;
}
while ( std::isdigit(int(*iter)) )
++iter;
}
while ( *iter == '*' || *iter == '/' )
{
if ( *iter == '*' )
{
// Padding is proportional to the number of affected lines (suffix '*')
number *= affcnt;
++iter;
}
else
{
// Padding is mandatory (suffix '/')
has_delay = true;
++iter;
}
}
if ( *iter != '>' )
{
outc(int('$'));
outc(int('<'));
iter = first_digit;
continue;
}
else if ( has_delay && number > 0 )
{
delay_output(number / 10, outc);
}
} // end of else (*iter == '<')
} // end of else (*iter == '$')
if ( iter == string.end() )
break;
++iter;
}
return Status::OK;
}
//----------------------------------------------------------------------
void FTermcap::init()
{
@ -130,6 +241,7 @@ void FTermcap::termcap()
int status = uninitialized;
const auto& term_detection = FTerm::getFTermDetection();
const bool color256 = term_detection->canDisplay256Colors();
baudrate = int(FTerm::getFTermData()->getBaudrate());
// Open termcap file
const auto& termtype = fterm_data->getTermType();
@ -154,7 +266,6 @@ void FTermcap::termcap()
status = tgetent(term_buffer, termtype.data());
#endif
if ( status == success )
initialized = true;
@ -240,6 +351,12 @@ void FTermcap::termcapBoleans()
// U8 is nonzero for terminals with no VT100 line-drawing in UTF-8 mode
no_utf8_acs_chars = bool(getNumber("U8") != 0);
// No padding character available
no_padding_char = getFlag("NP");
// Terminal uses software flow control (XON/XOFF) with (Ctrl-Q/Ctrl-S)
xon_xoff_flow_control = getFlag("xo");
}
//----------------------------------------------------------------------
@ -263,6 +380,9 @@ void FTermcap::termcapNumerics()
// Get initial spacing for hardware tab stop
tabstop = getNumber("it");
// Get the smallest baud rate where padding is required
padding_baudrate = getNumber("pb");
// Get video attributes that cannot be used with colors
attr_without_color = getNumber("NC");
}
@ -279,8 +399,13 @@ void FTermcap::termcapStrings()
const auto& ho = TCAP(t_cursor_home);
if ( std::strncmp(ho, "\033[H", 3) == 0 )
if ( ho && std::strncmp(ho, "\033[H", 3) == 0 )
has_ansi_escape_sequences = true;
const auto& pc = TCAP(t_pad_char);
if ( pc )
PC = pc[0];
}
//----------------------------------------------------------------------
@ -311,14 +436,26 @@ std::string FTermcap::encodeParams ( const std::string& cap
}
//----------------------------------------------------------------------
int FTermcap::_tputs (const char* str, int affcnt, fn_putc putc)
void FTermcap::delay_output (int ms, const defaultPutChar& outc)
{
#if defined(__sun) && defined(__SVR4)
return ::tputs ( C_STR(str)
, affcnt, reinterpret_cast<int (*)(char)>(putc) );
#else
return ::tputs (str, affcnt, putc);
#endif
if ( no_padding_char )
{
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
else
{
static constexpr int baudbyte = 9; // = 7 bit + 1 parity + 1 stop
for ( int pad_char_count = (ms * baudrate) / (baudbyte * 1000);
pad_char_count > 0;
pad_char_count-- )
{
outc(int(PC));
}
std::fflush(stdout);
}
}
@ -331,6 +468,7 @@ FTermcap::TCapMapType FTermcap::strings =
// | | // variable name -> description
//------------------------------------------------------------------------------
{ nullptr, "bl" }, // bell -> audible signal (bell) (P)
{ nullptr, "vb" }, // flash_screen -> visible bell (may not move cursor)
{ nullptr, "ec" }, // erase_chars -> erase #1 characters (P)
{ nullptr, "cl" }, // clear_screen -> clear screen and home cursor (P*)
{ nullptr, "cd" }, // clr_eos -> clear to end of screen (P*)
@ -341,6 +479,7 @@ FTermcap::TCapMapType FTermcap::strings =
{ nullptr, "cr" }, // carriage_return -> carriage return (P*)
{ nullptr, "ta" }, // tab -> tab to next 8-space hardware tab stop
{ nullptr, "bt" }, // back_tab -> back tab (P)
{ nullptr, "pc" }, // pad_char -> padding char (instead of null)
{ nullptr, "ip" }, // insert_padding -> insert padding after inserted character
{ nullptr, "ic" }, // insert_character -> insert character (P)
{ nullptr, "IC" }, // parm_ich -> insert #1 characters (P*)

View File

@ -482,7 +482,7 @@ int FTermLinux::getFramebuffer_bpp() const
&& fsystem->ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix) == 0 )
{
fsystem->close(fd);
return int(fb_var.bits_per_pixel);
return static_cast<int>(fb_var.bits_per_pixel);
}
else
{
@ -1159,7 +1159,7 @@ sInt16 FTermLinux::getFontPos (wchar_t ucs) const
for (std::size_t n{0}; n < screen_unicode_map.entry_ct; n++)
{
if ( screen_unicode_map.entries[n].unicode == ucs )
return sInt16(screen_unicode_map.entries[n].fontpos);
return static_cast<sInt16>(screen_unicode_map.entries[n].fontpos);
}
return NOT_FOUND;

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2018-2020 Markus Gans *
* Copyright 2018-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 *
@ -741,7 +741,7 @@ FString FTermXTerminal::captureXTermFont() const
&& ! term_detection->isScreenTerm()
&& ! FTermcap::osc_support )
{
return FString{};
return {};
}
fd_set ifds{};
@ -760,7 +760,7 @@ FString FTermXTerminal::captureXTermFont() const
// Read the terminal answer
if ( select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 )
return FString{};
return {};
std::array<char, 150> temp{};
std::size_t pos{0};
@ -788,10 +788,10 @@ FString FTermXTerminal::captureXTermFont() const
if ( n >= 5 && str[n - 1] == BEL[0] && str[n] == '\0' )
str[n - 1] = '\0';
return FString{str};
return {str};
}
return FString{};
return {};
}
//----------------------------------------------------------------------
@ -800,7 +800,7 @@ FString FTermXTerminal::captureXTermTitle() const
const auto& term_detection = FTerm::getFTermDetection();
if ( term_detection->isKdeTerminal() )
return FString{};
return {};
fd_set ifds{};
struct timeval tv{};
@ -816,7 +816,7 @@ FString FTermXTerminal::captureXTermTitle() const
// read the terminal answer
if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 )
return FString{};
return {};
std::array<char, 512> temp{};
std::size_t pos{0};
@ -843,14 +843,14 @@ FString FTermXTerminal::captureXTermTitle() const
if ( n >= 2 && str[n - 2] == ESC[0] && str[n - 1] == '\\' )
{
if ( n < 4 )
return FString{};
return {};
str[n - 2] = '\0';
return FString{str};
return {str};
}
}
return FString{};
return {};
}
//----------------------------------------------------------------------

View File

@ -57,7 +57,7 @@ FTextView::~FTextView() noexcept = default; // destructor
FString FTextView::getText() const
{
if ( data.empty() )
return FString{""};
return {""};
std::size_t len{0};

View File

@ -581,7 +581,7 @@ void FVTerm::flush() const
{
const auto& first = output_buffer->front();
const auto& type = std::get<0>(first);
const auto& wstring = std::get<1>(first);
const auto& str = std::get<1>(first);
if ( type == OutputType::String )
{
@ -590,11 +590,11 @@ void FVTerm::flush() const
if ( ! FTermPutchar )
return;
for (auto&& ch : wstring)
for (auto&& ch : str.wstring)
FTermPutchar(int(ch));
}
else if ( type == OutputType::Control )
FTerm::putstring (std::string(wstring.begin(), wstring.end()));
FTerm::putstring (str.string);
output_buffer->pop();
}
@ -2625,7 +2625,7 @@ FVTerm::PrintState FVTerm::repeatCharacter (uInt& x, uInt xmax, uInt y) const
//----------------------------------------------------------------------
inline bool FVTerm::isFullWidthChar (const FChar& ch) const
{
return bool(ch.attr.bit.char_width == 2);
return ch.attr.bit.char_width == 2;
}
//----------------------------------------------------------------------
@ -3105,8 +3105,7 @@ inline bool FVTerm::isOutputBufferLimitReached() const
//----------------------------------------------------------------------
inline void FVTerm::appendOutputBuffer (const FTermControl& ctrl) const
{
const auto& wstring = std::wstring{ctrl.string.begin(), ctrl.string.end()};
output_buffer->emplace(std::make_tuple(OutputType::Control, wstring));
output_buffer->emplace(std::make_tuple(OutputType::Control, TermString(ctrl.string)));
if ( isOutputBufferLimitReached() )
flush();
@ -3129,7 +3128,7 @@ void FVTerm::appendOutputBuffer (const FTermString& str) const
auto& string_buf = std::get<1>(output_buffer->back());
std::transform ( str.string.begin()
, str.string.end()
, std::back_inserter(string_buf)
, std::back_inserter(string_buf.wstring)
, [] (wchar_t ch)
{
return ch;
@ -3137,7 +3136,7 @@ void FVTerm::appendOutputBuffer (const FTermString& str) const
);
}
else
output_buffer->emplace(std::make_tuple(OutputType::String, str.string));
output_buffer->emplace(std::make_tuple(OutputType::String, TermString(str.string)));
if ( isOutputBufferLimitReached() )
flush();

View File

@ -257,51 +257,51 @@ enum class UniChar : wchar_t
constexpr bool operator < (const UniChar& c1, const wchar_t c2) noexcept
{
return bool( wchar_t(c1) < c2 );
return wchar_t(c1) < c2;
}
constexpr bool operator > (const UniChar& c1, const wchar_t c2) noexcept
{
return bool( wchar_t(c1) > c2 );
return wchar_t(c1) > c2;
}
constexpr bool operator < (const wchar_t c1, const UniChar& c2) noexcept
{
return bool( c1 < wchar_t(c2) );
return c1 < wchar_t(c2);
}
constexpr bool operator > (const wchar_t c1, const UniChar& c2) noexcept
{
return bool( c1 > wchar_t(c2) );
return c1 > wchar_t(c2);
}
constexpr bool operator <= (const UniChar& c1, const wchar_t c2) noexcept
{
return bool( wchar_t(c1) <= c2 );
return wchar_t(c1) <= c2;
}
constexpr bool operator >= (const UniChar& c1, const wchar_t c2) noexcept
{
return bool( wchar_t(c1) >= c2 );
return wchar_t(c1) >= c2;
}
constexpr bool operator <= (const wchar_t c1, const UniChar& c2) noexcept
{
return bool( c1 <= wchar_t(c2) );
return c1 <= wchar_t(c2);
}
constexpr bool operator >= (const wchar_t c1, const UniChar& c2) noexcept
{
return bool( c1 >= wchar_t(c2) );
return c1 >= wchar_t(c2);
}
constexpr bool operator == (const wchar_t c1, const UniChar& c2) noexcept
{
return bool( c1 == wchar_t(c2) );
return c1 == wchar_t(c2);
}
constexpr bool operator == (const UniChar& c1, const wchar_t c2) noexcept
{
return bool( wchar_t(c1) == c2 );
return wchar_t(c1) == c2;
}
@ -819,22 +819,22 @@ constexpr FKey operator << (const FKey& k, const uInt32 n) noexcept
constexpr bool operator < (const FKey& k1, const uInt32 k2) noexcept
{
return bool( uInt32(k1) < k2 );
return uInt32(k1) < k2;
}
constexpr bool operator > (const FKey& k1, const uInt32 k2) noexcept
{
return bool( uInt32(k1) > k2 );
return uInt32(k1) > k2;
}
constexpr bool operator <= (const FKey& k1, const uInt32 k2) noexcept
{
return bool( uInt32(k1) <= k2 );
return uInt32(k1) <= k2;
}
constexpr bool operator >= (const FKey& k1, const uInt32 k2) noexcept
{
return bool( uInt32(k1) >= k2 );
return uInt32(k1) >= k2;
}
constexpr FKey operator | (const FKey& k1, const FKey& k2) noexcept
@ -1156,27 +1156,27 @@ constexpr FColor operator << (const FColor& c, const uInt16 n) noexcept
constexpr bool operator < (const FColor& c, const uInt16 n) noexcept
{
return bool( uInt16(c) < n );
return uInt16(c) < n;
}
constexpr bool operator > (const FColor& c, const uInt16 n) noexcept
{
return bool( uInt16(c) > n );
return uInt16(c) > n;
}
constexpr bool operator == (const FColor& c, const uInt16 n) noexcept
{
return bool( uInt16(c) == n );
return uInt16(c) == n;
}
constexpr bool operator <= (const FColor& c, const uInt16 n) noexcept
{
return bool( uInt16(c) <= n );
return uInt16(c) <= n;
}
constexpr bool operator >= (const FColor& c, const uInt16 n) noexcept
{
return bool( uInt16(c) >= n );
return uInt16(c) >= n;
}
constexpr FColor operator + (const FColor& c, const uInt16 n) noexcept
@ -1433,6 +1433,7 @@ enum class BracketType
enum class Termcap
{
t_bell,
t_flash_screen,
t_erase_chars,
t_clear_screen,
t_clr_eos,
@ -1443,6 +1444,7 @@ enum class Termcap
t_carriage_return,
t_tab,
t_back_tab,
t_pad_char,
t_insert_padding,
t_insert_character,
t_parm_ich,

View File

@ -122,7 +122,7 @@ inline FString FDropDownListBox::getClassName() const
//----------------------------------------------------------------------
inline bool FDropDownListBox::isEmpty() const
{ return bool( list.getCount() == 0 ); }
{ return list.getCount() == 0; }
//----------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 2020 Markus Gans *
* Copyright 2020-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 *
@ -247,7 +247,7 @@ class FData : public FDataAccess
{
const auto& v = reinterpret_cast<void*>(const_cast<T_nocv*>(&value));
const auto& r = reinterpret_cast<void*>(const_cast<T_nocv*>(&value_ref.get()));
return bool( v == r );
return v == r;
}
bool isInitializedReference() const

View File

@ -522,11 +522,11 @@ inline bool FListBox::isMultiSelection() const
//----------------------------------------------------------------------
inline bool FListBox::hasBrackets(std::size_t index) const
{ return bool(index2iterator(index - 1)->brackets != BracketType::None); }
{ return index2iterator(index - 1)->brackets != BracketType::None; }
//----------------------------------------------------------------------
inline bool FListBox::hasBrackets(FListBoxItems::iterator iter) const
{ return bool(iter->brackets != BracketType::None); }
{ return iter->brackets != BracketType::None; }
//----------------------------------------------------------------------
inline void FListBox::reserve (std::size_t new_cap)
@ -605,11 +605,11 @@ void FListBox::insert ( const ItemT& item
//----------------------------------------------------------------------
inline bool FListBox::isHorizontallyScrollable() const
{ return bool( max_line_width + 1 >= getClientWidth() ); }
{ return max_line_width + 1 >= getClientWidth(); }
//----------------------------------------------------------------------
inline bool FListBox::isVerticallyScrollable() const
{ return bool( getCount() > getClientHeight() ); }
{ return getCount() > getClientHeight(); }
//----------------------------------------------------------------------
inline FListBox::FListBoxItems::iterator \

View File

@ -170,7 +170,7 @@ inline FString FListViewItem::getClassName() const
//----------------------------------------------------------------------
inline uInt FListViewItem::getColumnCount() const
{ return uInt(column_list.size()); }
{ return static_cast<uInt>(column_list.size()); }
//----------------------------------------------------------------------
template <typename DT>
@ -718,11 +718,11 @@ inline const FListView::FListViewItems& FListView::getData() const
//----------------------------------------------------------------------
inline bool FListView::isHorizontallyScrollable() const
{ return bool( max_line_width > getClientWidth() ); }
{ return max_line_width > getClientWidth(); }
//----------------------------------------------------------------------
inline bool FListView::isVerticallyScrollable() const
{ return bool( getCount() > getClientHeight() ); }
{ return getCount() > getClientHeight(); }
//----------------------------------------------------------------------
inline void FListView::scrollTo (const FPoint& pos)

View File

@ -286,11 +286,11 @@ inline bool FMenuItem::isRadioButton() const
//----------------------------------------------------------------------
inline bool FMenuItem::hasHotkey() const
{ return bool(hotkey != FKey::None); }
{ return hotkey != FKey::None; }
//----------------------------------------------------------------------
inline bool FMenuItem::hasMenu() const
{ return bool(menu != nullptr); }
{ return menu != nullptr; }
//----------------------------------------------------------------------
inline FWidget* FMenuItem::getSuperMenu() const

View File

@ -248,11 +248,11 @@ inline bool FObject::hasParent() const
//----------------------------------------------------------------------
inline bool FObject::hasChildren() const
{ return bool( ! children_list.empty() ); }
{ return ! children_list.empty(); }
//----------------------------------------------------------------------
inline bool FObject::isDirectChild (const FObject* obj) const
{ return bool( obj->getParent() == this ); }
{ return obj->getParent() == this; }
//----------------------------------------------------------------------
inline bool FObject::isWidget() const
@ -260,7 +260,7 @@ inline bool FObject::isWidget() const
//----------------------------------------------------------------------
inline bool FObject::isInstanceOf (const FString& classname) const
{ return bool( classname == getClassName() ); }
{ return classname == getClassName(); }
//----------------------------------------------------------------------
inline bool FObject::isTimerInUpdating() const

View File

@ -227,83 +227,83 @@ inline FString FOptiMove::getClassName() const
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorHomeLength() const
{ return uInt(F_cursor_home.length); }
{ return static_cast<uInt>(F_cursor_home.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCarriageReturnLength() const
{ return uInt(F_carriage_return.length); }
{ return static_cast<uInt>(F_carriage_return.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorToLLLength() const
{ return uInt(F_cursor_to_ll.length); }
{ return static_cast<uInt>(F_cursor_to_ll.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getTabLength() const
{ return uInt(F_tab.length); }
{ return static_cast<uInt>(F_tab.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getBackTabLength() const
{ return uInt(F_back_tab.length); }
{ return static_cast<uInt>(F_back_tab.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorUpLength() const
{ return uInt(F_cursor_up.length); }
{ return static_cast<uInt>(F_cursor_up.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorDownLength() const
{ return uInt(F_cursor_down.length); }
{ return static_cast<uInt>(F_cursor_down.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorLeftLength() const
{ return uInt(F_cursor_left.length); }
{ return static_cast<uInt>(F_cursor_left.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorRightLength() const
{ return uInt(F_cursor_right.length); }
{ return static_cast<uInt>(F_cursor_right.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getCursorAddressLength() const
{ return uInt(F_cursor_address.length); }
{ return static_cast<uInt>(F_cursor_address.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getColumnAddressLength() const
{ return uInt(F_column_address.length); }
{ return static_cast<uInt>(F_column_address.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getRowAddressLength() const
{ return uInt(F_row_address.length); }
{ return static_cast<uInt>(F_row_address.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getParmUpCursorLength() const
{ return uInt(F_parm_up_cursor.length); }
{ return static_cast<uInt>(F_parm_up_cursor.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getParmDownCursorLength() const
{ return uInt(F_parm_down_cursor.length); }
{ return static_cast<uInt>(F_parm_down_cursor.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getParmLeftCursorLength() const
{ return uInt(F_parm_left_cursor.length); }
{ return static_cast<uInt>(F_parm_left_cursor.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getParmRightCursorLength() const
{ return uInt(F_parm_right_cursor.length); }
{ return static_cast<uInt>(F_parm_right_cursor.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getEraseCharsLength() const
{ return uInt(F_erase_chars.length); }
{ return static_cast<uInt>(F_erase_chars.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getRepeatCharLength() const
{ return uInt(F_repeat_char.length); }
{ return static_cast<uInt>(F_repeat_char.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getClrBolLength() const
{ return uInt(F_clr_bol.length); }
{ return static_cast<uInt>(F_clr_bol.length); }
//----------------------------------------------------------------------
inline uInt FOptiMove::getClrEolLength() const
{ return uInt(F_clr_eol.length); }
{ return static_cast<uInt>(F_clr_eol.length); }
//----------------------------------------------------------------------
inline void FOptiMove::set_auto_left_margin (bool bcap)

View File

@ -67,6 +67,7 @@
#include "final/fc.h"
#include "final/fsystem.h"
namespace finalcut
{

View File

@ -53,6 +53,13 @@ namespace finalcut
class FTermcap final
{
public:
// Enumeration
enum class Status
{
Error = -1,
OK = 0
};
struct TCapMap
{
const char* string;
@ -60,8 +67,8 @@ class FTermcap final
};
// Using-declaration
using fn_putc = int (*)(int);
using TCapMapType = std::array<TCapMap, 83>;
using TCapMapType = std::array<TCapMap, 85>;
using defaultPutChar = std::function<int(int)>;
// Constructors
FTermcap() = default;
@ -77,13 +84,18 @@ class FTermcap final
static std::string encodeMotionParameter (const std::string&, int, int);
template <typename... Args>
static std::string encodeParameter (const std::string&, Args&&...);
static int paddingPrint (const std::string&, int, fn_putc);
static Status paddingPrint ( const std::string&
, int
, const defaultPutChar&);
// Inquiry
static bool isInitialized();
// Mutator
static void setBaudrate (int);
// Methods
static void init();
static void init();
// Data members
static bool background_color_erase;
@ -95,8 +107,11 @@ class FTermcap final
static bool ansi_default_color;
static bool osc_support;
static bool no_utf8_acs_chars;
static bool no_padding_char;
static bool xon_xoff_flow_control;
static int max_color;
static int tabstop;
static int padding_baudrate;
static int attr_without_color;
static TCapMapType strings;
@ -114,11 +129,13 @@ class FTermcap final
static void termcapKeys();
static std::string encodeParams ( const std::string&
, const std::vector<int>& );
static int _tputs (const char*, int, fn_putc);
static void delay_output (int, const defaultPutChar&);
// Data member
static char string_buf[BUF_SIZE];
static bool initialized;
static int baudrate;
static char PC;
static char string_buf[BUF_SIZE];
};
// FTermcap inline functions
@ -133,18 +150,18 @@ std::string FTermcap::encodeParameter (const std::string& cap, Args&&... args)
return encodeParams(cap, {static_cast<int>(args)...});
}
//----------------------------------------------------------------------
inline int FTermcap::paddingPrint (const std::string& str, int affcnt, fn_putc putc)
{
return _tputs (C_STR(str.data()), affcnt, putc);
}
//----------------------------------------------------------------------
inline bool FTermcap::isInitialized()
{
return initialized;
}
//----------------------------------------------------------------------
inline void FTermcap::setBaudrate (int baud)
{
baudrate = baud;
}
} // namespace finalcut

View File

@ -205,11 +205,11 @@ inline FString FTermXTerminal::getHighlightBackground() const
//----------------------------------------------------------------------
inline bool FTermXTerminal::hasFont() const
{ return bool(xterm_font.getLength() > 2); }
{ return xterm_font.getLength() > 2; }
//----------------------------------------------------------------------
inline bool FTermXTerminal::hasTitle() const
{ return bool(xterm_title.getLength() > 0); }
{ return xterm_title.getLength() > 0; }
//----------------------------------------------------------------------
inline void FTermXTerminal::unsetMouseSupport()

View File

@ -260,11 +260,11 @@ inline void FTextView::deleteLine (int pos)
//----------------------------------------------------------------------
inline bool FTextView::isHorizontallyScrollable() const
{ return bool( max_line_width > getTextWidth() ); }
{ return max_line_width > getTextWidth(); }
//----------------------------------------------------------------------
inline bool FTextView::isVerticallyScrollable() const
{ return bool( getRows() > getTextHeight() ); }
{ return getRows() > getTextHeight(); }
} // namespace finalcut

View File

@ -324,8 +324,22 @@ class FVTerm
Control
};
struct TermString
{
TermString (const std::wstring& wstr)
: wstring{wstr}
{ }
TermString (const std::string& str)
: string{str}
{ }
std::wstring wstring{};
std::string string{};
};
// Using-declaration
using OutputData = std::tuple<OutputType, std::wstring>;
using OutputData = std::tuple<OutputType, TermString>;
using OutputBuffer = std::queue<OutputData>;
// Constants
@ -863,7 +877,7 @@ inline void FVTerm::setActiveArea (FTermArea* area) const
//----------------------------------------------------------------------
inline bool FVTerm::isActive (const FTermArea* area) const
{ return bool( area == active_area ); }
{ return area == active_area; }
//----------------------------------------------------------------------
inline bool FVTerm::hasPrintArea() const

View File

@ -13,6 +13,7 @@ noinst_PROGRAMS = \
fmouse_test \
fkeyboard_test \
fterm_functions_test \
ftermcap_test \
ftermdata_test \
ftermbuffer_test \
ftermdetection_test \
@ -37,6 +38,7 @@ fdata_test_SOURCES = fdata-test.cpp
fmouse_test_SOURCES = fmouse-test.cpp
fkeyboard_test_SOURCES = fkeyboard-test.cpp
fterm_functions_test_SOURCES = fterm_functions-test.cpp
ftermcap_test_SOURCES = ftermcap-test.cpp
ftermdata_test_SOURCES = ftermdata-test.cpp
ftermbuffer_test_SOURCES = ftermbuffer-test.cpp
ftermdetection_test_SOURCES = ftermdetection-test.cpp
@ -61,6 +63,7 @@ TESTS = fobject_test \
fmouse_test \
fkeyboard_test \
fterm_functions_test \
ftermcap_test \
ftermdata_test \
ftermbuffer_test \
ftermdetection_test \

493
test/ftermcap-test.cpp Normal file
View File

@ -0,0 +1,493 @@
/***********************************************************************
* ftermcap-test.cpp - FTermcap unit tests *
* *
* This file is part of the FINAL CUT widget toolkit *
* *
* Copyright 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 *
* published by the Free Software Foundation; either version 3 of *
* the License, or (at your option) any later version. *
* *
* FINAL CUT 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this program. If not, see *
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <chrono>
#include <string>
#include <final/final.h>
// FTermcap string macro
#ifdef TCAP
#undef TCAP
#endif
#define TCAP(...) finalcut::FTermcap::strings[int(finalcut::Termcap::__VA_ARGS__)].string
using std::chrono::duration_cast;
using std::chrono::milliseconds;
using std::chrono::high_resolution_clock;
#define CPPUNIT_ASSERT_CSTRING(expected, actual) \
check_c_string (expected, actual, CPPUNIT_SOURCELINE())
//----------------------------------------------------------------------
void check_c_string ( const char* s1
, const char* s2
, CppUnit::SourceLine sourceLine )
{
if ( s1 == 0 && s2 == 0 ) // Strings are equal
return;
if ( s1 && s2 && std::strcmp (s1, s2) == 0 ) // Strings are equal
return;
::CppUnit::Asserter::fail ("Strings are not equal", sourceLine);
}
//----------------------------------------------------------------------
// class FTermcapTest
//----------------------------------------------------------------------
class FTermcapTest : public CPPUNIT_NS::TestFixture
{
public:
FTermcapTest()
{ }
protected:
void classNameTest();
void initTest();
void getFlagTest();
void getNumberTest();
void getStringTest();
void encodeMotionParameterTest();
void encodeParameterTest();
void paddingPrintTest();
private:
static int putchar_test(int);
static void clear();
// Adds code needed to register the test suite
CPPUNIT_TEST_SUITE (FTermcapTest);
// Add a methods to the test suite
CPPUNIT_TEST (classNameTest);
CPPUNIT_TEST (initTest);
CPPUNIT_TEST (getFlagTest);
CPPUNIT_TEST (getNumberTest);
CPPUNIT_TEST (getStringTest);
CPPUNIT_TEST (encodeMotionParameterTest);
CPPUNIT_TEST (encodeParameterTest);
//CPPUNIT_TEST (paddingPrintTest);
// End of test suite definition
CPPUNIT_TEST_SUITE_END();
// Data member
static std::string output;
};
// static class attribute
std::string FTermcapTest::output{};
//----------------------------------------------------------------------
void FTermcapTest::classNameTest()
{
finalcut::FTermcap tcap;
const finalcut::FString& classname = tcap.getClassName();
CPPUNIT_ASSERT ( classname == "FTermcap" );
}
//----------------------------------------------------------------------
void FTermcapTest::initTest()
{
// Without a terminal type
const auto& fterm_data = finalcut::FTerm::getFTermData();
CPPUNIT_ASSERT ( fterm_data->getTermType().empty() );
finalcut::FTermcap tcap;
CPPUNIT_ASSERT ( ! tcap.isInitialized() );
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( ! fterm_data->getTermType().empty() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "xterm" );
// With terminal type ansi
fterm_data->setTermType("ansi");
tcap.init();
CPPUNIT_ASSERT ( fterm_data->getTermType() == "ansi" );
// With a non-existent terminal type
fterm_data->setTermType("bang!");
tcap.init();
CPPUNIT_ASSERT ( fterm_data->getTermType() == "xterm" );
setenv ("TERM", "xterm-256color", 1); // 256 color terminal
const auto& term_detection = finalcut::FTerm::getFTermDetection();
CPPUNIT_ASSERT ( ! term_detection->canDisplay256Colors() );
term_detection->detect();
CPPUNIT_ASSERT ( term_detection->canDisplay256Colors() );
fterm_data->setTermType("bang!");
tcap.init();
CPPUNIT_ASSERT ( fterm_data->getTermType() == "xterm-256color" );
fterm_data->setTermType("dumb");
tcap.init();
CPPUNIT_ASSERT ( fterm_data->getTermType() == "dumb" );
}
//----------------------------------------------------------------------
void FTermcapTest::getFlagTest()
{
const auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("ansi");
finalcut::FTermcap tcap;
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "ansi" );
CPPUNIT_ASSERT ( tcap.getFlag("am") ); // Automatic right margin
CPPUNIT_ASSERT ( ! tcap.getFlag("cc") ); // Can change color palette
CPPUNIT_ASSERT ( ! tcap.getFlag("xo") ); // Xon/Xoff flow control
}
//----------------------------------------------------------------------
void FTermcapTest::getNumberTest()
{
const auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("xterm");
finalcut::FTermcap tcap;
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "xterm" );
CPPUNIT_ASSERT ( tcap.getNumber("Co") == 8 ); // Colors
CPPUNIT_ASSERT ( tcap.getNumber("it") == 8 ); // Tab stop
CPPUNIT_ASSERT ( tcap.getNumber("NC") == 0 ); // Attr. without color
CPPUNIT_ASSERT ( tcap.getNumber("co") == 80 ); // Columns
CPPUNIT_ASSERT ( tcap.getNumber("li") == 24 ); // Lines
}
//----------------------------------------------------------------------
void FTermcapTest::getStringTest()
{
const auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("ansi");
finalcut::FTermcap tcap;
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "ansi" );
CPPUNIT_ASSERT_CSTRING ( tcap.getString("me"), CSI "0m" ); // Exit attribute mode
CPPUNIT_ASSERT_CSTRING ( tcap.getString("mr"), CSI "7m" ); // Enter reverse mode
CPPUNIT_ASSERT_CSTRING ( tcap.getString("us"), CSI "4m" ); // Enter underline mode
CPPUNIT_ASSERT_CSTRING ( tcap.getString("cd"), CSI "J" ); // Clear to end of screen
CPPUNIT_ASSERT_CSTRING ( tcap.getString("ce"), CSI "K" ); // Clear to end of line
CPPUNIT_ASSERT_CSTRING ( tcap.getString("cl"), CSI "H" CSI "J" ); // Clear screen
}
//----------------------------------------------------------------------
void FTermcapTest::encodeMotionParameterTest()
{
const auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("ansi");
finalcut::FTermcap tcap;
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "ansi" );
const auto& cursor_address = tcap.getString("cm");
CPPUNIT_ASSERT ( tcap.encodeMotionParameter(cursor_address, 10, 15) == CSI "16;11H" );
CPPUNIT_ASSERT ( tcap.encodeMotionParameter(cursor_address, 25, 1) == CSI "2;26H" );
CPPUNIT_ASSERT ( tcap.encodeMotionParameter(cursor_address, 0, 0) == CSI "1;1H" );
CPPUNIT_ASSERT ( tcap.encodeMotionParameter(cursor_address, 79, 23) == CSI "24;80H" );
}
//----------------------------------------------------------------------
void FTermcapTest::encodeParameterTest()
{
const auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("ansi");
finalcut::FTermcap tcap;
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( fterm_data->getTermType() == "ansi" );
const auto& parm_insert_line = tcap.getString("AL");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_insert_line, 7) == CSI "7L" );
const auto& parm_left_cursor = tcap.getString("LE");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_left_cursor, 3) == CSI "3D" );
const auto& parm_right_cursor = tcap.getString("RI");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_right_cursor, 4) == CSI "4C" );
const auto& parm_down_cursor = tcap.getString("DO");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_down_cursor, 12) == CSI "12B" );
const auto& parm_up_cursor = tcap.getString("UP");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_up_cursor, 5) == CSI "5A" );
const auto& parm_delete_line = tcap.getString("DL");
CPPUNIT_ASSERT ( tcap.encodeParameter(parm_delete_line, 9) == CSI "9M" );
}
//----------------------------------------------------------------------
void FTermcapTest::paddingPrintTest()
{
finalcut::FTermcap tcap;
setenv ("TERM", "xterm", 1); // xterm has no padding character
unsetenv("TERMCAP");
auto& fterm_data = finalcut::FTerm::getFTermData();
fterm_data->setTermType("xterm");
CPPUNIT_ASSERT ( ! tcap.xon_xoff_flow_control );
tcap.init();
CPPUNIT_ASSERT ( tcap.isInitialized() );
CPPUNIT_ASSERT ( tcap.no_padding_char );
// '$' without '<'
CPPUNIT_ASSERT ( output.empty() );
tcap.paddingPrint ("12$34567", 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "12$34567" );
// No closing '>'
output.clear();
tcap.paddingPrint ("12$3$<4567", 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "12$3$<4567" );
// With 2 ms print delay
output.clear();
auto start = high_resolution_clock::now();
tcap.paddingPrint ("1234$<2/>567", 1, FTermcapTest::putchar_test);
auto end = high_resolution_clock::now();
auto duration_ms = int(duration_cast<milliseconds>(end - start).count());
CPPUNIT_ASSERT ( duration_ms >= 2 );
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "1234567" );
// With 20 ms print delay
output.clear();
start = high_resolution_clock::now();
tcap.paddingPrint ("12$3$<45$<20/>67", 1, FTermcapTest::putchar_test);
end = high_resolution_clock::now();
duration_ms = int(duration_cast<milliseconds>(end - start).count());
CPPUNIT_ASSERT ( duration_ms >= 20 );
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "12$3$<4567" );
// With a high a delay (9.999 seconds)
output.clear();
start = high_resolution_clock::now();
tcap.paddingPrint ("1234$<9999/>567", 1, FTermcapTest::putchar_test);
end = high_resolution_clock::now();
duration_ms = int(duration_cast<milliseconds>(end - start).count());
CPPUNIT_ASSERT ( duration_ms >= 9999 );
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "1234567" );
// With too high a delay (delay > 9999 ms = 9.999 sec)
output.clear();
start = high_resolution_clock::now();
tcap.paddingPrint ("1234$<10000>567", 1, FTermcapTest::putchar_test);
end = high_resolution_clock::now();
duration_ms = int(duration_cast<milliseconds>(end - start).count());
CPPUNIT_ASSERT ( duration_ms < 20 );
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == "1234$<10000>567" );
// Beep has delayed output and flush
output.clear();
tcap.paddingPrint (TCAP(t_bell), 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == std::string(TCAP(t_bell)) );
// Flash screen has delayed output and flush
output.clear();
start = high_resolution_clock::now();
tcap.paddingPrint ("\033[?5h$<100/>\033[?5l", 1, FTermcapTest::putchar_test);
end = high_resolution_clock::now();
duration_ms = int(duration_cast<milliseconds>(end - start).count());
CPPUNIT_ASSERT ( duration_ms >= 100 );
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output == std::string("\033[?5h\033[?5l") );
// With 5 ms prints 21 padding chars ('\0')
setenv ("TERM", "ansi", 1); // ansi terminals used for delay padding character
fterm_data->setTermType("ansi");
tcap.init();
CPPUNIT_ASSERT ( ! tcap.no_padding_char );
CPPUNIT_ASSERT ( ! tcap.xon_xoff_flow_control );
output.clear();
tcap.setBaudrate (38400);
tcap.paddingPrint ("1234$<5*/>567", 1, FTermcapTest::putchar_test);
const auto& str1_with_0 = "1234" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "567";
std::string target_output(std::begin(str1_with_0), std::end(str1_with_0) - 1);
CPPUNIT_ASSERT ( ! output.empty() );
CPPUNIT_ASSERT ( output.length() == 28 );
CPPUNIT_ASSERT ( output == target_output );
// Wait 2 ms with padding characters and with 1 affected line
output.clear();
tcap.setBaudrate (9600);
tcap.padding_baudrate = 0; // no padding baudrate
tcap.paddingPrint ("abc$<2*>def", 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 6 );
CPPUNIT_ASSERT ( output == "abcdef" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 1, FTermcapTest::putchar_test); // with "*/"
const auto& str2_with_0 = "abc" "\0\0" "def";
target_output = std::string(std::begin(str2_with_0), std::end(str2_with_0) - 1);
CPPUNIT_ASSERT ( output.length() == 8 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/*>def", 1, FTermcapTest::putchar_test); // with "/*"
CPPUNIT_ASSERT ( output.length() == 8 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/x*>def", 1, FTermcapTest::putchar_test); // defekt
CPPUNIT_ASSERT ( output.length() == 13 );
CPPUNIT_ASSERT ( output == "abc$<2/x*>def" );
output.clear();
tcap.paddingPrint ("abc$<2/*x>def", 1, FTermcapTest::putchar_test); // defekt
CPPUNIT_ASSERT ( output.length() == 13 );
CPPUNIT_ASSERT ( output == "abc$<2/*x>def" );
output.clear();
tcap.padding_baudrate = 19200; // baudrate < padding baudrate
tcap.paddingPrint ("abc$<2*>def", 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 6 );
CPPUNIT_ASSERT ( output == "abcdef" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 1, FTermcapTest::putchar_test); // with "*/"
CPPUNIT_ASSERT ( output.length() == 8 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.padding_baudrate = 9600; // baudrate >= padding baudrate
tcap.paddingPrint ("abc$<2*>def", 1, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 8 );
CPPUNIT_ASSERT ( output == target_output );
// Wait 2 ms with padding characters and with 2 affected line
output.clear();
tcap.padding_baudrate = 0; // no padding baudrate
tcap.paddingPrint ("abc$<2*>>def", 2, FTermcapTest::putchar_test); // double >>
CPPUNIT_ASSERT ( output.length() == 7 );
CPPUNIT_ASSERT ( output == "abc>def" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 2, FTermcapTest::putchar_test); // with "*/"
const auto& str3_with_0 = "abc" "\0\0\0\0" "def";
target_output = std::string(std::begin(str3_with_0), std::end(str3_with_0) - 1);
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/*>def", 2, FTermcapTest::putchar_test); // with "/*"
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.padding_baudrate = 19200; // baudrate < padding baudrate
tcap.paddingPrint ("abc$<2*>def", 2, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 6 );
CPPUNIT_ASSERT ( output == "abcdef" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 2, FTermcapTest::putchar_test); // with "*/"
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/*>def", 2, FTermcapTest::putchar_test); // with "/*"
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.padding_baudrate = 9600; // baudrate >= padding baudrate
tcap.paddingPrint ("abc$<2*>def", 2, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
// Wait 2 ms with padding characters and with 3 affected line
output.clear();
tcap.padding_baudrate = 0; // no padding baudrate
tcap.paddingPrint ("abc$<2*>def", 3, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output == "abcdef" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 3, FTermcapTest::putchar_test); // with "*/"
const auto& str4_with_0 = "abc" "\0\0\0\0\0\0" "def";
target_output = std::string(std::begin(str4_with_0), std::end(str4_with_0) - 1);
CPPUNIT_ASSERT ( output.length() == 12 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/*>def", 3, FTermcapTest::putchar_test); // with "/*"
CPPUNIT_ASSERT ( output.length() == 12 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.padding_baudrate = 19200; // baudrate < padding baudrate
tcap.paddingPrint ("abc$<2*>def", 3, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 6 );
CPPUNIT_ASSERT ( output == "abcdef" );
output.clear();
tcap.paddingPrint ("abc$<2*/>def", 3, FTermcapTest::putchar_test); // with "*/"
CPPUNIT_ASSERT ( output.length() == 12 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2/*>def", 3, FTermcapTest::putchar_test); // with "/*"
CPPUNIT_ASSERT ( output.length() == 12 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.padding_baudrate = 9600; // baudrate >= padding baudrate
tcap.paddingPrint ("abc$<2*>def", 3, FTermcapTest::putchar_test);
CPPUNIT_ASSERT ( output.length() == 12 );
CPPUNIT_ASSERT ( output == target_output );
// With decimal point
output.clear();
tcap.setBaudrate(19200);
tcap.padding_baudrate = 19200; // baudrate == padding baudrate
tcap.paddingPrint ("abc$<2.>def", 1, FTermcapTest::putchar_test); // 2.
const auto& str5_with_0 = "abc" "\0\0\0\0" "def";
target_output = std::string(std::begin(str5_with_0), std::end(str5_with_0) - 1);
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2.0>def", 1, FTermcapTest::putchar_test); // 2.0
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2.7>def", 1, FTermcapTest::putchar_test); // 2.7
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
output.clear();
tcap.paddingPrint ("abc$<2.77>def", 1, FTermcapTest::putchar_test); // 2.77
CPPUNIT_ASSERT ( output.length() == 10 );
CPPUNIT_ASSERT ( output == target_output );
}
//----------------------------------------------------------------------
int FTermcapTest::putchar_test (int ch)
{
//std::cout << std::hex << "0x" << ch << "," << std::flush;
output.push_back(char(ch));
return ch;
}
//----------------------------------------------------------------------
void FTermcapTest::clear()
{
output.clear();
}
//----------------------------------------------------------------------
// Put the test suite in the registry
CPPUNIT_TEST_SUITE_REGISTRATION (FTermcapTest);
// The general unit test main part
#include <main-test.inc>