diff --git a/examples/rotozoomer.cpp b/examples/rotozoomer.cpp index 3284abac..31d6d9c5 100644 --- a/examples/rotozoomer.cpp +++ b/examples/rotozoomer.cpp @@ -96,12 +96,14 @@ RotoZoomer::RotoZoomer (finalcut::FWidget* parent, bool b, int l) { for (std::size_t i{0}; i < 8; i++) { - data[h++] = L' '; + data[h] = L' '; + h++; } for (std::size_t i{0}; i < 8; i++) { - data[h++] = L'+'; + data[h] = L'+'; + h++; } } @@ -109,12 +111,14 @@ RotoZoomer::RotoZoomer (finalcut::FWidget* parent, bool b, int l) { for (std::size_t i{0}; i < 8; i++) { - data[h++] = L'x'; + data[h] = L'x'; + h++; } for (std::size_t i{0}; i < 8; i++) { - data[h++] = L' '; + data[h] = L' '; + h++; } } } diff --git a/src/fapplication.cpp b/src/fapplication.cpp index b4b77029..1c68fd9d 100644 --- a/src/fapplication.cpp +++ b/src/fapplication.cpp @@ -97,9 +97,9 @@ FApplication::FApplication (const int& _argc, char* _argv[]) if ( ! (_argc && _argv) ) { typedef char* CString; - static CString empty[1]{CString("")}; + static std::array empty{CString("")}; app_argc = 0; - app_argv = empty; + app_argv = empty.data(); } init(); diff --git a/src/ffiledialog.cpp b/src/ffiledialog.cpp index d36e80d0..5b456fae 100644 --- a/src/ffiledialog.cpp +++ b/src/ffiledialog.cpp @@ -25,6 +25,7 @@ #include // need for strcasecmp #endif +#include #include #include "final/fevent.h" @@ -427,7 +428,7 @@ inline bool FFileDialog::patternMatch ( const char* const pattern std::strncat(search.data(), pattern, search.size() - std::strlen(search.data()) - 1); } else - std::strncpy(search.data(), pattern, search.size()); + std::strncpy(search.data(), pattern, search.size() - 1); search[search.size() - 1] = '\0'; @@ -602,7 +603,7 @@ void FFileDialog::followSymLink (const char* const dir, FDirEntry& entry) const if ( ! fsystem ) fsystem = FTerm::getFSystem(); - std::strncpy (symLink.data(), dir, symLink.size()); + std::strncpy (symLink.data(), dir, symLink.size() - 1); symLink[symLink.size() - 1] = '\0'; std::strncat ( symLink.data() , entry.name.c_str() diff --git a/src/fterm_functions.cpp b/src/fterm_functions.cpp index 3dabd87b..e1e42515 100644 --- a/src/fterm_functions.cpp +++ b/src/fterm_functions.cpp @@ -545,39 +545,37 @@ FPoint readCursorPos() constexpr auto& DECXCPR{ESC "[6n"}; // Report Cursor Position (DECXCPR) - const ssize_t ret = write(stdout_no, DECXCPR, std::strlen(DECXCPR)); + if ( write(stdout_no, DECXCPR, std::strlen(DECXCPR)) < 1 ) + return FPoint{x, y}; - if ( ret > 0 ) + std::fflush(stdout); + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 100000; // 100 ms + + // Read the answer + if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) != 1 ) + return FPoint{x, y}; + + constexpr auto parse = "\033[%4d;%4dR"; + std::array temp{}; + std::size_t pos{0}; + + do { - std::fflush(stdout); - FD_ZERO(&ifds); - FD_SET(stdin_no, &ifds); - tv.tv_sec = 0; - tv.tv_usec = 100000; // 100 ms + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - // Read the answer - if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) == 1 ) - { - constexpr auto parse = "\033[%4d;%4dR"; - std::array temp{}; - std::size_t pos{0}; + if ( bytes <= 0 ) + break; - do - { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - - if ( bytes <= 0 ) - break; - - pos += std::size_t(bytes); - } - while ( pos < temp.size() && std::strchr(temp.data(), 'R') == nullptr ); - - if ( pos > 4 ) - std::sscanf(temp.data(), parse, &x, &y); - } + pos += std::size_t(bytes); } + while ( pos < temp.size() && std::strchr(temp.data(), 'R') == nullptr ); + + if ( pos > 4 ) + std::sscanf(temp.data(), parse, &x, &y); return FPoint{x, y}; } diff --git a/src/ftermdetection.cpp b/src/ftermdetection.cpp index 63fc2ac7..083d95c9 100644 --- a/src/ftermdetection.cpp +++ b/src/ftermdetection.cpp @@ -580,39 +580,38 @@ FString FTermDetection::getXTermColorName (FColor color) tv.tv_usec = 150000; // 150 ms // read the terminal answer - if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 ) + if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 ) + return color_str; + + constexpr auto parse = "\033]4;%10hu;%509[^\n]s"; + std::array temp{}; + std::size_t pos{0}; + + do { - constexpr auto parse = "\033]4;%10hu;%509[^\n]s"; - std::array temp{}; - std::size_t pos{0}; + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - do - { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); + if ( bytes <= 0 ) + break; - if ( bytes <= 0 ) - break; + pos += std::size_t(bytes); + } + while ( pos < temp.size() ); - pos += std::size_t(bytes); - } - while ( pos < temp.size() ); + if ( pos > 4 && std::sscanf(temp.data(), parse, &color, buf.data()) == 2 ) + { + std::size_t n = std::strlen(buf.data()); - if ( pos > 4 - && std::sscanf(temp.data(), parse, &color, buf.data()) == 2 ) - { - std::size_t n = std::strlen(buf.data()); + // BEL + '\0' = string terminator + if ( n >= 6 && buf[n - 1] == BEL[0] && buf[n] == '\0' ) + buf[n - 1] = '\0'; - // BEL + '\0' = string terminator - if ( n >= 6 && buf[n - 1] == BEL[0] && buf[n] == '\0' ) - buf[n - 1] = '\0'; + // Esc + \ = OSC string terminator (mintty) + if ( n >= 6 && buf[n - 2] == ESC[0] && buf[n - 1] == '\\' ) + buf[n - 2] = '\0'; - // Esc + \ = OSC string terminator (mintty) - if ( n >= 6 && buf[n - 2] == ESC[0] && buf[n - 1] == '\\' ) - buf[n - 2] = '\0'; - - color_str = buf.data(); - } + color_str = buf.data(); } return color_str; @@ -647,8 +646,8 @@ const char* FTermDetection::parseAnswerbackMsg (const char current_termtype[]) new_termtype = "putty"; } - // Some terminal like cygwin or the windows terminal - // needs to delete the '♣' char + // Some terminals like cygwin or the Windows terminal + // have to delete the printed character '♣' std::fprintf (stdout, "\r " BS); std::fflush (stdout); @@ -681,26 +680,26 @@ FString FTermDetection::getAnswerbackMsg() tv.tv_usec = 150000; // 150 ms // Read the answerback message - if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 ) + if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 ) + return answerback; + + std::array temp{}; + std::size_t pos{0}; + + do { - std::array temp{}; - std::size_t pos{0}; + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - do - { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); + if ( bytes <= 0 ) + break; - if ( bytes <= 0 ) - break; - - pos += std::size_t(bytes); - } - while ( pos < temp.size() ); - - if ( pos > 0 ) - answerback = temp.data(); + pos += std::size_t(bytes); } + while ( pos < temp.size() ); + + if ( pos > 0 ) + answerback = temp.data(); return answerback; } @@ -815,9 +814,7 @@ FString FTermDetection::getSecDA() constexpr auto& SECDA{ESC "[>c"}; // Get the secondary device attributes - const ssize_t ret = write(stdout_no, SECDA, std::strlen(SECDA)); - - if ( ret == -1 ) + if ( write(stdout_no, SECDA, std::strlen(SECDA)) == -1 ) return sec_da_str; std::fflush(stdout); @@ -827,28 +824,27 @@ FString FTermDetection::getSecDA() tv.tv_usec = 600000; // 600 ms // Read the answer - if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) == 1 ) + if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 ) + return sec_da_str; + + constexpr auto parse = "\033[>%10d;%10d;%10dc"; + std::array temp{}; + std::size_t pos{0}; + + do { - constexpr auto parse = "\033[>%10d;%10d;%10dc"; - std::array temp{}; - std::size_t pos{0}; + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - do - { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); + if ( bytes <= 0 ) + break; - if ( bytes <= 0 ) - break; - - pos += std::size_t(bytes); - } - while ( pos < temp.size() && std::strchr(temp.data(), 'c') == nullptr ); - - if ( pos > 3 - && std::sscanf(temp.data(), parse, &a, &b, &c) == 3 ) - sec_da_str.sprintf("\033[>%d;%d;%dc", a, b, c); + pos += std::size_t(bytes); } + while ( pos < temp.size() && std::strchr(temp.data(), 'c') == nullptr ); + + if ( pos > 3 && std::sscanf(temp.data(), parse, &a, &b, &c) == 3 ) + sec_da_str.sprintf("\033[>%d;%d;%dc", a, b, c); return sec_da_str; } diff --git a/src/ftermxterminal.cpp b/src/ftermxterminal.cpp index fdf0e6ba..ce079766 100644 --- a/src/ftermxterminal.cpp +++ b/src/ftermxterminal.cpp @@ -765,56 +765,58 @@ FString FTermXTerminal::captureXTermFont() const { initCheck(FString{}); - if ( term_detection->isXTerminal() - || term_detection->isScreenTerm() - || FTermcap::osc_support ) + if ( ! term_detection->isXTerminal() + && ! term_detection->isScreenTerm() + && ! FTermcap::osc_support ) { - fd_set ifds{}; - struct timeval tv{}; - const int stdin_no = FTermios::getStdIn(); + return FString{}; + } - // Querying the terminal font - oscPrefix(); - FTerm::putstring (OSC "50;?" BEL); - oscPostfix(); - std::fflush(stdout); - FD_ZERO(&ifds); - FD_SET(stdin_no, &ifds); - tv.tv_sec = 0; - tv.tv_usec = 150000; // 150 ms + fd_set ifds{}; + struct timeval tv{}; + const int stdin_no = FTermios::getStdIn(); - // Read the terminal answer - if ( select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 ) - { - std::array temp{}; - std::size_t pos{0}; + // Querying the terminal font + oscPrefix(); + FTerm::putstring (OSC "50;?" BEL); + oscPostfix(); + std::fflush(stdout); + FD_ZERO(&ifds); + FD_SET(stdin_no, &ifds); + tv.tv_sec = 0; + tv.tv_usec = 150000; // 150 ms - do - { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); + // Read the terminal answer + if ( select(stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 ) + return FString{}; - if ( bytes <= 0 ) - break; + std::array temp{}; + std::size_t pos{0}; - pos += std::size_t(bytes); - } - while ( pos < temp.size() && std::strchr(temp.data(), '\a') == nullptr ); + do + { + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - if ( pos > 5 && temp[0] == ESC[0] && temp[1] == ']' - && temp[2] == '5' && temp[3] == '0' && temp[4] == ';' ) - { - // Skip leading Esc ] 5 0 ; - char* str = &temp[5]; - const std::size_t n = std::strlen(str); + if ( bytes <= 0 ) + break; - // BEL + '\0' = string terminator - if ( n >= 5 && str[n - 1] == BEL[0] && str[n] == '\0' ) - str[n - 1] = '\0'; + pos += std::size_t(bytes); + } + while ( pos < temp.size() && std::strchr(temp.data(), '\a') == nullptr ); - return FString{str}; - } - } + if ( pos > 5 && temp[0] == ESC[0] && temp[1] == ']' && temp[2] == '5' + && temp[3] == '0' && temp[4] == ';' ) + { + // Skip leading Esc ] 5 0 ; + char* str = &temp[5]; + const std::size_t n = std::strlen(str); + + // BEL + '\0' = string terminator + if ( n >= 5 && str[n - 1] == BEL[0] && str[n] == '\0' ) + str[n - 1] = '\0'; + + return FString{str}; } return FString{}; @@ -841,38 +843,38 @@ FString FTermXTerminal::captureXTermTitle() const tv.tv_usec = 150000; // 150 ms // read the terminal answer - if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) > 0 ) + if ( select (stdin_no + 1, &ifds, nullptr, nullptr, &tv) < 1 ) + return FString{}; + + std::array temp{}; + std::size_t pos{0}; + + do { - std::array temp{}; - std::size_t pos{0}; + std::size_t bytes_free = temp.size() - pos - 1; + const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); - do + if ( bytes <= 0 ) + break; + + pos += std::size_t(bytes); + } + while ( pos < temp.size() && std::strstr(temp.data(), ESC "\\") == nullptr ); + + 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); + + // Esc + \ = OSC string terminator + if ( n >= 2 && str[n - 2] == ESC[0] && str[n - 1] == '\\' ) { - std::size_t bytes_free = temp.size() - pos - 1; - const ssize_t bytes = read(stdin_no, &temp[pos], bytes_free); + if ( n < 4 ) + return FString{}; - if ( bytes <= 0 ) - break; - - pos += std::size_t(bytes); - } - while ( pos < temp.size() && std::strstr(temp.data(), ESC "\\") == nullptr ); - - 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); - - // Esc + \ = OSC string terminator - if ( n >= 2 && str[n - 2] == ESC[0] && str[n - 1] == '\\' ) - { - if ( n < 4 ) - return FString{}; - - str[n - 2] = '\0'; - return FString{str}; - } + str[n - 2] = '\0'; + return FString{str}; } } diff --git a/src/include/final/fdata.h b/src/include/final/fdata.h index c691e6b5..9b47169d 100644 --- a/src/include/final/fdata.h +++ b/src/include/final/fdata.h @@ -153,6 +153,8 @@ template class FData : public FDataAccess { public: + typedef typename std::remove_cv::type T_nocv; + // Constructors explicit FData (T& v) // constructor : value_ref{v} @@ -244,8 +246,9 @@ class FData : public FDataAccess // Inquiries bool isInitializedCopy() const { - return bool( reinterpret_cast(&value) - == reinterpret_cast(&value_ref.get()) ); + const auto& v = reinterpret_cast(const_cast(&value)); + const auto& r = reinterpret_cast(const_cast(&value_ref.get())); + return bool( v == r ); } bool isInitializedReference() const