New class FLogger for logging

This commit is contained in:
Markus Gans 2020-05-13 23:47:14 +02:00
parent 4a8b863238
commit 923822ca25
55 changed files with 1538 additions and 210 deletions

1
.gitignore vendored
View File

@ -38,6 +38,7 @@ examples/.deps/
examples/.libs/
examples/calculator
examples/dialog
examples/event-log
examples/string-operations
examples/background-color
examples/opti-move

View File

@ -75,12 +75,12 @@ matrix:
- whoami
- echo -n | openssl s_client -CApath /etc/ssl/certs/ -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt
script:
- cat /home/travis/build/gansm/finalcut/cov-int/scm_log.txt
- cat /home/travis/build/gansm/finalcut/cov-int/scm_log.txt || echo
- autoreconf -v --install --force
- ./configure --prefix=/usr CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -DUNIT_TEST" --with-unit-test
- make V=1 -j10
- make check
- cat test/*.log
- cat test/*.log || echo
#
# Coveralls + Codecov

View File

@ -1,3 +1,8 @@
2020-05-13 Markus Gans <guru.mail@muenster.de>
* The new class FLogger for logging, which can be redirected
to different I/O channels
* Adding the event-log example to show the logging functionality
2020-05-02 Markus Gans <guru.mail@muenster.de>
* Transfer of all termcap functions into the FTermcap class

View File

@ -11,6 +11,7 @@ noinst_PROGRAMS = \
hello \
dialog \
input-dialog \
event-log \
fullwidth-character \
7segment \
choice \
@ -39,6 +40,7 @@ noinst_PROGRAMS = \
hello_SOURCES = hello.cpp
dialog_SOURCES = dialog.cpp
input_dialog_SOURCES = input-dialog.cpp
event_log_SOURCES = event-log.cpp
fullwidth_character_SOURCES = fullwidth-character.cpp
7segment_SOURCES = 7segment.cpp
choice_SOURCES = choice.cpp

View File

@ -211,7 +211,6 @@ void Background::cb_choice (const finalcut::FWidget*, const FDataPtr)
updateTerminal();
}
//----------------------------------------------------------------------
// main part
//----------------------------------------------------------------------
@ -226,6 +225,20 @@ int main (int argc, char* argv[])
Background dialog(&app);
finalcut::FWidget::setMainWidget(&dialog);
dialog.show();
//-------------------------------------------------
std::cout << "\r\n" << std::flush;
finalcut::FLog& log = *finalcut::FApplication::getLog();
//std::ofstream file_stream("test.log", std::ofstream::out | std::ofstream::app);
//log.setLineEnding (finalcut::FLog::LF);
//log.setOutputStream(file_stream);
log.info("test1");
log.warn("test2");
log << finalcut::FLog::Error << "streaming " << "test 1" << std::flush;
log.enableTimestamp();
log << finalcut::FLog::Debug << "streaming test 2";
//-------------------------------------------------
return app.exec();
}

353
examples/event-log.cpp Normal file
View File

@ -0,0 +1,353 @@
/***********************************************************************
* event-log.cpp - Logs events in a dialog box *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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 <fstream>
#include <sstream>
#include <tuple>
#include <utility>
#include <vector>
#include <final/final.h>
using finalcut::FPoint;
using finalcut::FRect;
using finalcut::FSize;
class EventLog; // class forward declaration
//----------------------------------------------------------------------
// class EventLog::EventLog
//----------------------------------------------------------------------
class EventDialog final : public finalcut::FDialog
{
public:
// Using-declaration
using FDialog::setGeometry;
// Constructor
explicit EventDialog (finalcut::FWidget* = nullptr);
// Disable copy constructor
EventDialog (const EventDialog&) = delete;
// Destructor
~EventDialog();
// Disable copy assignment operator (=)
EventDialog& operator = (const EventDialog&) = delete;
private:
// Methods
finalcut::FString getMouseButtonName (int);
void logMouseEvent (finalcut::FString, finalcut::FMouseEvent&);
// Event handlers
void onClose (finalcut::FCloseEvent*) override;
void onShow (finalcut::FShowEvent*) override;
void onTimer (finalcut::FTimerEvent*) override;
void onKeyPress (finalcut::FKeyEvent*) override;
void onMouseDown (finalcut::FMouseEvent*) override;
void onMouseMove (finalcut::FMouseEvent*) override;
void onMouseUp (finalcut::FMouseEvent*) override;
void onMouseDoubleClick (finalcut::FMouseEvent* ev) override;
void onWindowActive (finalcut::FEvent*) override;
void onWindowInactive (finalcut::FEvent*) override;
void onWindowRaised (finalcut::FEvent*) override;
void onWindowLowered (finalcut::FEvent*) override;
private:
// Data members
finalcut::FLog& log{*finalcut::FApplication::getLog()};
finalcut::FLabel label{this};
};
//----------------------------------------------------------------------
EventDialog::EventDialog (finalcut::FWidget* parent)
: FDialog(parent)
{
// Dialog settings
// Avoids calling a virtual function from the constructor
// (CERT, OOP50-CPP)
FDialog::setText ("Event dialog");
FDialog::setGeometry (FPoint{15, 2}, FSize{53, 12});
setShadow();
label.setText("\n\nUse the keyboard or mouse\n"
"in this dialog to create events");
label.setAlignment(finalcut::fc::alignCenter);
label.setGeometry (FPoint(1, 1), getClientSize(), false);
addTimer(60000); // Starts the timer every minute
}
//----------------------------------------------------------------------
EventDialog::~EventDialog() // destructor
{ }
//----------------------------------------------------------------------
finalcut::FString EventDialog::getMouseButtonName (int btn_state)
{
switch ( btn_state )
{
case finalcut::fc::LeftButton:
return "left";
case finalcut::fc::RightButton:
return "right";
case finalcut::fc::MiddleButton:
return "middle";
default:
return "unknown";
}
return "unknown";
}
//----------------------------------------------------------------------
void EventDialog::logMouseEvent ( finalcut::FString state
, finalcut::FMouseEvent& ev )
{
const int mouse_x = ev.getX();
const int mouse_y = ev.getY();
log << finalcut::FLog::Info
<< getMouseButtonName(ev.getButton())
<< " mouse button " << state << " at ("
<< mouse_x << ", " << mouse_y << ")" << std::flush;
}
//----------------------------------------------------------------------
void EventDialog::onClose (finalcut::FCloseEvent* ev)
{
log.info("The event dialog was closed");
ev->accept();
}
//----------------------------------------------------------------------
void EventDialog::onShow (finalcut::FShowEvent*)
{
log.info("The event dialog is now displayed");
}
//----------------------------------------------------------------------
void EventDialog::onTimer (finalcut::FTimerEvent*)
{
log.info("-- minute marker --");
}
//----------------------------------------------------------------------
void EventDialog::onKeyPress (finalcut::FKeyEvent* ev)
{
const FKey key_id = ev->key();
finalcut::FString key_name = getKeyName(key_id);
if ( key_name.isEmpty() )
key_name = wchar_t(key_id);
log << finalcut::FLog::Info
<< "Key " << key_name << " (id " << key_id << ")" << std::flush;
finalcut::FDialog::onKeyPress(ev);
}
//----------------------------------------------------------------------
void EventDialog::onMouseDown (finalcut::FMouseEvent* ev)
{
logMouseEvent("down", *ev);
finalcut::FDialog::onMouseDown(ev);
}
//----------------------------------------------------------------------
void EventDialog::onMouseMove (finalcut::FMouseEvent* ev)
{
logMouseEvent("move", *ev);
finalcut::FDialog::onMouseMove(ev);
}
//----------------------------------------------------------------------
void EventDialog::onMouseUp (finalcut::FMouseEvent* ev)
{
logMouseEvent("up", *ev);
finalcut::FDialog::onMouseUp(ev);
}
//----------------------------------------------------------------------
void EventDialog::onMouseDoubleClick (finalcut::FMouseEvent* ev)
{
logMouseEvent("double click", *ev);
finalcut::FDialog::onMouseDoubleClick(ev);
}
//----------------------------------------------------------------------
void EventDialog::onWindowActive (finalcut::FEvent* ev)
{
log.info("The Event dialog is now active");
finalcut::FDialog::onWindowActive(ev);
}
//----------------------------------------------------------------------
void EventDialog::onWindowInactive (finalcut::FEvent* ev)
{
log.info("The Event dialog is now inactive");
finalcut::FDialog::onWindowInactive(ev);
}
//----------------------------------------------------------------------
void EventDialog::onWindowRaised (finalcut::FEvent* ev)
{
log.info("The dialog was raised");
finalcut::FDialog::onWindowRaised(ev);
}
//----------------------------------------------------------------------
void EventDialog::onWindowLowered (finalcut::FEvent* ev)
{
log.info("The dialog was lowered");
finalcut::FDialog::onWindowLowered(ev);
}
//----------------------------------------------------------------------
// class EventLog
//----------------------------------------------------------------------
class EventLog final : public finalcut::FDialog, public std::ostringstream
{
public:
// Using-declaration
using FDialog::setGeometry;
// Constructor
explicit EventLog (finalcut::FWidget* = nullptr);
// Disable copy constructor
EventLog (const EventLog&) = delete;
// Destructor
~EventLog();
// Disable copy assignment operator (=)
EventLog& operator = (const EventLog&) = delete;
// Event handlers
void onTimer (finalcut::FTimerEvent*) override;
void onClose (finalcut::FCloseEvent*) override;
private:
// Method
void adjustSize() override;
// Data members
finalcut::FTextView scrollText{this};
EventDialog* event_dialog{new EventDialog(this)};
};
//----------------------------------------------------------------------
EventLog::EventLog (finalcut::FWidget* parent)
: FDialog(parent)
{
// Dialog settings
// Avoids calling a virtual function from the constructor
// (CERT, OOP50-CPP)
FDialog::setText ("Event log");
FDialog::setGeometry (FPoint{4, 16}, FSize{75, 8});
setMinimumSize (FSize{75, 5});
setResizeable();
setShadow();
scrollText.ignorePadding();
scrollText.setGeometry (FPoint{1, 2}, FSize{getWidth(), getHeight() - 1});
event_dialog->setFocus();
addTimer(250); // Starts the timer every 250 milliseconds
}
//----------------------------------------------------------------------
EventLog::~EventLog() // destructor
{ }
//----------------------------------------------------------------------
void EventLog::onTimer (finalcut::FTimerEvent*)
{
if ( ! str().empty() )
{
scrollText.append(str());
str("");
scrollText.scrollToEnd();
redraw();
updateTerminal();
}
}
//----------------------------------------------------------------------
void EventLog::onClose (finalcut::FCloseEvent* ev)
{
finalcut::FApplication::closeConfirmationDialog (this, ev);
}
//----------------------------------------------------------------------
void EventLog::adjustSize()
{
finalcut::FDialog::adjustSize();
scrollText.setGeometry (FPoint{1, 2}, FSize(getWidth(), getHeight() - 1));
}
//----------------------------------------------------------------------
// main part
//----------------------------------------------------------------------
int main (int argc, char* argv[])
{
finalcut::FApplication app(argc, argv);
EventLog dialog(&app);
// Get the global logger object
finalcut::FLog& log = *finalcut::FApplication::getLog();
// Set the line endings (default = CRLF)
log.setLineEnding (finalcut::FLog::LF);
// Write a timestamp before each output line
log.enableTimestamp();
// Set the dialog object as output stream
log.setOutputStream(dialog);
// ----------------------------------------------
// Remove the comment characters in the following
// two lines to log the output to a file.
// ----------------------------------------------
//std::ofstream file_stream("test.log", std::ofstream::out | std::ofstream::app);
//log.setOutputStream(file_stream);
// Sets the dialog as main widget
finalcut::FWidget::setMainWidget(&dialog);
// Show the dialog
dialog.show();
// Run the application
return app.exec();
}

View File

@ -226,15 +226,15 @@ void streamToInterger()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
}
@ -250,15 +250,15 @@ void streamToUnsignedInterger()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
}
@ -274,15 +274,15 @@ void streamToDouble()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
}
@ -298,15 +298,15 @@ void streamToFloat()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
}
@ -498,15 +498,15 @@ void convertToNumberExample()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
// Test: convert a string to a signed long interger
@ -517,15 +517,15 @@ void convertToNumberExample()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
// Test: convert a string to a double value
@ -542,15 +542,15 @@ void convertToNumberExample()
}
catch (const std::underflow_error& ex)
{
std::cerr << "underflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Underflow");
}
catch (const std::overflow_error& ex)
{
std::cerr << "overflow: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Overflow");
}
catch (const std::invalid_argument& ex)
{
std::cerr << "Arithmetic error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Arithmetic error");
}
}
@ -640,9 +640,9 @@ void insertExample()
std::cout << " insert: "
<< insert_str.insert("changed ", 7) << std::endl;
}
catch (const std::out_of_range& ex)
catch (const std::out_of_range&)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Out of Range");
}
}
@ -655,14 +655,14 @@ void indexExample()
try
{
index[0] = L'I'; // write a wide character at position 0
index[0] = L'I'; // Write a wide character at position 0
printf ( " index: [0] = %c ; [4] = %c\n"
, char(index[0])
, char(index[4]) );
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
finalcut::FApplication::getLog()->error("Out of Range");
}
}

View File

@ -981,7 +981,7 @@ void MyDialog::cb_view (const finalcut::FWidget*, FDataPtr data)
int(getRootWidget()->getHeight() / 6) }
, FSize{60, getRootWidget()->getHeight() * 3 / 4} );
view->setResizeable();
std::string line = "";
std::string line{""};
std::ifstream infile;
infile.open(file);
@ -1028,7 +1028,7 @@ int main (int argc, char* argv[])
//app.setEncoding(finalcut::fc::VT100);
// Sets the terminal size to 94×30
//app.setTermSize(94,30);
//finalcut::FTerm::setTermSize(FSize{94, 30});
// Enable the final cut graphical font
//app.setNewFont();

View File

@ -25,6 +25,8 @@ libfinal_la_SOURCES = \
flabel.cpp \
flistbox.cpp \
flistview.cpp \
flog.cpp \
flogger.cpp \
fmenu.cpp \
fmouse.cpp \
fsystem.cpp \
@ -98,6 +100,8 @@ finalcutinclude_HEADERS = \
include/final/flineedit.h \
include/final/flistbox.h \
include/final/flistview.h \
include/final/flog.h \
include/final/flogger.h \
include/final/fmenu.h \
include/final/fmouse.h \
include/final/fkeyboard.h \

View File

@ -25,6 +25,8 @@ INCLUDE_HEADERS = \
flineedit.h \
flistbox.h \
flistview.h \
flog.h \
flogger.h \
fmenu.h \
fdialoglistmenu.h \
fmenubar.h \
@ -98,6 +100,8 @@ OBJS = \
flabel.o \
flistbox.o \
flistview.o \
flog.o \
flogger.o \
fmenu.o \
fdialoglistmenu.o \
fmenubar.o \

View File

@ -25,6 +25,8 @@ INCLUDE_HEADERS = \
flineedit.h \
flistbox.h \
flistview.h \
flog.h \
flogger.h \
fmenu.h \
fdialoglistmenu.h \
fmenubar.h \
@ -98,6 +100,8 @@ OBJS = \
flabel.o \
flistbox.o \
flistview.o \
flog.o \
flogger.o \
fmenu.o \
fdialoglistmenu.o \
fmenubar.o \

View File

@ -25,6 +25,8 @@
#include "final/fapplication.h"
#include "final/fevent.h"
#include "final/flog.h"
#include "final/flogger.h"
#include "final/fmenu.h"
#include "final/fmenubar.h"
#include "final/fmessagebox.h"
@ -108,6 +110,20 @@ FApplication* FApplication::getApplicationObject()
return app_object;
}
//----------------------------------------------------------------------
std::shared_ptr<FLog>& FApplication::getLog()
{
// Global logger object
static std::shared_ptr<FLog> logger = std::make_shared<FLogger>();
return logger;
}
//----------------------------------------------------------------------
void FApplication::setLog (const std::shared_ptr<FLog>& logger)
{
getLog() = logger;
}
//----------------------------------------------------------------------
bool FApplication::isQuit()
{
@ -349,6 +365,9 @@ void FApplication::init (uInt64 key_time, uInt64 dblclick_time)
// Set the default double click interval
if ( mouse )
mouse->setDblclickInterval (dblclick_time);
// Initialize logging
getLog()->setLineEnding(FLog::CRLF);
}
//----------------------------------------------------------------------
@ -1094,6 +1113,17 @@ void FApplication::processCloseWidget()
setTerminalUpdates (FVTerm::start_terminal_updates);
}
//----------------------------------------------------------------------
void FApplication::processLogger()
{
// Synchronizing the stream buffer with the logging output
auto logger = getLog();
if ( ! logger->str().empty() )
logger->pubsync();
}
//----------------------------------------------------------------------
bool FApplication::processNextEvent()
{
@ -1104,6 +1134,7 @@ bool FApplication::processNextEvent()
processResizeEvent();
processTerminalUpdate();
processCloseWidget();
processLogger();
sendQueuedEvents();
num_events += processTimerEvent();

View File

@ -27,6 +27,7 @@
#include "final/flabel.h"
#include "final/flineedit.h"
#include "final/flistbox.h"
#include "final/flog.h"
#include "final/fmouse.h"
#include "final/fpoint.h"
#include "final/fsize.h"
@ -605,9 +606,9 @@ void FComboBox::passEventToListWindow (FMouseEvent* const& ev)
list_window.list.setFocus();
list_window.list.onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
@ -631,6 +632,7 @@ void FComboBox::cb_setInputField (const FWidget*, const FDataPtr)
input_field = list.getItem(index).getText();
input_field.redraw();
processChanged();
std::cout << "\r\n";
}
//----------------------------------------------------------------------
@ -692,9 +694,9 @@ void FComboBox::cb_inputFieldHandOver (const FWidget*, const FDataPtr)
list_window.list.setFocus();
list_window.list.onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}

View File

@ -824,9 +824,9 @@ void FDialog::initDialogMenu()
{
dialog_menu = new FMenu ("-", this);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMenu");
return;
}
@ -854,9 +854,9 @@ void FDialog::initMoveSizeMenuItem (FMenu* menu)
{
move_size_item = new FMenuItem (menu);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMenuItem");
return;
}
@ -877,9 +877,9 @@ void FDialog::initZoomMenuItem (FMenu* menu)
{
zoom_item = new FMenuItem (menu);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMenuItem");
return;
}
@ -900,9 +900,9 @@ void FDialog::initCloseMenuItem (FMenu* menu)
{
close_item = new FMenuItem ("&Close", menu);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMenuItem");
return;
}
@ -1358,9 +1358,9 @@ inline void FDialog::passEventToSubMenu ( const mouseStates& ms
setClickedWidget(dialog_menu);
dialog_menu->onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
return;
}
}
@ -1646,9 +1646,9 @@ void FDialog::cb_move (const FWidget*, const FDataPtr)
{
tooltip = new FToolTip(this);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FToolTip");
return;
}

View File

@ -27,6 +27,7 @@
#include "final/fcolorpair.h"
#include "final/fevent.h"
#include "final/flabel.h"
#include "final/flog.h"
#include "final/fstatusbar.h"
namespace finalcut
@ -173,9 +174,9 @@ void FLabel::onMouseDown (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
return;
}
}

View File

@ -25,6 +25,7 @@
#include "final/fapplication.h"
#include "final/fevent.h"
#include "final/flabel.h"
#include "final/flog.h"
#include "final/flineedit.h"
#include "final/fpoint.h"
#include "final/fsize.h"
@ -860,7 +861,8 @@ inline FLineEdit::offsetPair FLineEdit::endPosToOffset (std::size_t pos)
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
if ( input_width >= char_width )
@ -883,7 +885,8 @@ inline FLineEdit::offsetPair FLineEdit::endPosToOffset (std::size_t pos)
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
}
@ -918,7 +921,8 @@ std::size_t FLineEdit::clickPosToCursorPos (std::size_t pos)
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
idx++;
@ -951,7 +955,8 @@ void FLineEdit::adjustTextOffset()
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
}
@ -963,7 +968,8 @@ void FLineEdit::adjustTextOffset()
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
}

View File

@ -910,9 +910,9 @@ FObject::iterator FListView::insert ( const FStringList& cols
{
item = new FListViewItem (cols, d, getNullIterator());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FListViewItem");
return getNullIterator();
}

87
src/flog.cpp Normal file
View File

@ -0,0 +1,87 @@
/***********************************************************************
* flog.cpp - Interface of the FINAL CUT logger *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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 "final/flog.h"
namespace finalcut
{
//----------------------------------------------------------------------
// class FLog
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
FLog::FLog()
{ }
//----------------------------------------------------------------------
FLog::~FLog() // destructor
{
sync();
}
// public methods of FLog
//----------------------------------------------------------------------
FLog& FLog::operator << (LogLevel l)
{
sync();
switch ( l )
{
case Info:
current_log = std::bind(&FLog::info, this, _1);
break;
case Warn:
current_log = std::bind(&FLog::warn, this, _1);
break;
case Error:
current_log = std::bind(&FLog::error, this, _1);
break;
case Debug:
current_log = std::bind(&FLog::debug, this, _1);
break;
}
return *this;
}
// protected methods of FLog
//----------------------------------------------------------------------
int FLog::sync()
{
if ( ! str().empty() )
{
current_log (str());
str("");
}
return 0;
}
} // namespace finalcut

124
src/flogger.cpp Normal file
View File

@ -0,0 +1,124 @@
/***********************************************************************
* flogger.cpp - The FINAL CUT text logger *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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 "final/flogger.h"
namespace finalcut
{
//----------------------------------------------------------------------
// class FLogger
//----------------------------------------------------------------------
// constructors and destructor
//----------------------------------------------------------------------
FLogger::FLogger()
{ }
//----------------------------------------------------------------------
FLogger::~FLogger() // destructor
{ }
// private methods of FLogger
//----------------------------------------------------------------------
void FLogger::newlineReplace ( std::string& str
, const std::string& replace_str )
{
std::size_t pos{0};
std::size_t npos{std::string::npos};
while ( (pos = str.find("\n", pos)) != npos
&& pos + 1 < str.length() )
{
str.replace(pos, 1, replace_str);
pos += replace_str.length();
}
}
//----------------------------------------------------------------------
const std::string FLogger::getTimeString()
{
char str[100];
const auto& now = std::chrono::system_clock::now();
const auto& t = std::chrono::system_clock::to_time_t(now);
std::stringstream str_stream;
// Print RFC 2822 date
const auto& tm = std::localtime(&t);
std::strftime(str, sizeof(str), "%a, %d %b %Y %T %z", tm);
return std::string(str);
}
//----------------------------------------------------------------------
const std::string FLogger::getEOL()
{
if ( end_of_line == FLog::LF )
return "\n";
else if ( end_of_line == FLog::CR )
return "\r";
else if ( end_of_line == FLog::CRLF )
return "\r\n";
return "";
}
//----------------------------------------------------------------------
void FLogger::printLogLine (const std::string& msg)
{
const std::string& log_level = [this] ()
{
switch ( level )
{
case Info:
return "INFO";
case Warn:
return "WARNING";
case Error:
return "ERROR";
case Debug:
return "DEBUG";
}
return "";
}();
const std::string prefix = [this, &log_level] ()
{
if ( timestamp )
return getTimeString() + " [" + log_level + "] ";
else
return "[" + log_level + "] ";
}();
std::string message{msg};
const std::string& eol = getEOL();
const std::string replace_str = eol + prefix;
newlineReplace (message, replace_str);
output << prefix << message << eol;
}
} // namespace finalcut

View File

@ -28,6 +28,7 @@
#include "final/fcolorpair.h"
#include "final/fdialog.h"
#include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h"
#include "final/fmenubar.h"
#include "final/fmenuitem.h"
@ -941,9 +942,9 @@ void FMenu::passEventToSubMenu (FMouseEvent* const& ev)
setClickedWidget(opened_sub_menu);
opened_sub_menu->onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
@ -965,9 +966,9 @@ void FMenu::passEventToSuperMenu (FMouseEvent* const& ev)
setClickedWidget(smenu);
smenu->onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
@ -990,9 +991,9 @@ void FMenu::passEventToMenuBar (FMouseEvent* const& ev)
mbar.mouse_down = true;
mbar.onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}

View File

@ -25,6 +25,7 @@
#include "final/fapplication.h"
#include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h"
#include "final/fmenubar.h"
#include "final/fmenuitem.h"
@ -944,9 +945,9 @@ void FMenuBar::passEventToMenu (const FMouseEvent* const& ev)
setClickedWidget(menu);
menu->onMouseMove(_ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
}

View File

@ -25,6 +25,7 @@
#include "final/fapplication.h"
#include "final/fdialog.h"
#include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h"
#include "final/fmenubar.h"
#include "final/fmenulist.h"
@ -614,9 +615,9 @@ void FMenuItem::createDialogList (FMenu* winmenu)
// create a new dialog list item
win_item = new FMenuItem (name, winmenu);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMenuItem");
return;
}
@ -663,9 +664,9 @@ void FMenuItem::passMouseEvent ( T widget, const FMouseEvent* ev
{
_ev = std::make_shared<FMouseEvent>(ev_type, p2, t, b);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
return;
}

View File

@ -24,6 +24,7 @@
#include "final/fapplication.h"
#include "final/fbutton.h"
#include "final/flog.h"
#include "final/fmessagebox.h"
namespace finalcut
@ -256,9 +257,9 @@ inline void FMessageBox::allocation (int button0, int button1, int button2)
button[2]->setHeight(1, false);
}
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FButton");
return;
}
}

View File

@ -60,9 +60,9 @@ FObject::FObject (FObject* parent)
{
timer_list = new FTimerList;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTimerList");
return;
}
}

View File

@ -20,6 +20,8 @@
* <http://www.gnu.org/licenses/>. *
***********************************************************************/
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fstartoptions.h"
namespace finalcut
@ -65,9 +67,9 @@ FStartOptions& FStartOptions::getFStartOptions()
{
start_options = new FStartOptions;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FStartOptions");
std::abort();
}
}

View File

@ -25,6 +25,8 @@
#include <utility>
#include <vector>
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fstring.h"
namespace finalcut
@ -1232,9 +1234,9 @@ inline void FString::initLength (std::size_t len)
string = new wchar_t[bufsize]();
std::wmemset (string, L'\0', bufsize);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("wchar_t[bufsize]");
}
}
@ -1263,9 +1265,9 @@ void FString::_assign (const wchar_t s[])
{
string = new wchar_t[bufsize]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("wchar_t[bufsize]");
return;
}
}
@ -1291,9 +1293,9 @@ void FString::_insert (std::size_t len, const wchar_t s[])
{
string = new wchar_t[bufsize]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("wchar_t[bufsize]");
return;
}
@ -1338,9 +1340,9 @@ void FString::_insert ( std::size_t pos
{
sptr = new wchar_t[bufsize](); // generate new string
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("wchar_t[bufsize]");
return;
}
@ -1382,9 +1384,9 @@ void FString::_remove (std::size_t pos, std::size_t len)
{
sptr = new wchar_t[bufsize](); // generate new string
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("wchar_t[bufsize]");
return;
}
@ -1416,9 +1418,9 @@ inline char* FString::wc_to_c_str (const wchar_t s[]) const
// Generate a empty string ("")
c_string = new char[1]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("char[1]");
return nullptr;
}
@ -1441,9 +1443,9 @@ inline char* FString::wc_to_c_str (const wchar_t s[]) const
// pre-initialiaze the whole string with '\0'
std::memset (c_string, '\0', std::size_t(dest_size));
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("char[std::size_t(dest_size)]");
return nullptr;
}
@ -1473,9 +1475,9 @@ inline wchar_t* FString::c_to_wc_str (const char s[]) const
// Generate a empty wide string (L"")
return new wchar_t[1]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("wchar_t[1]");
return nullptr;
}
}
@ -1493,9 +1495,9 @@ inline wchar_t* FString::c_to_wc_str (const char s[]) const
// pre-initialiaze the whole string with '\0'
std::wmemset (dest, L'\0', std::size_t(size));
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << " " << ex.what() << std::endl;
badAllocOutput ("wchar_t[std::size_t(size)]");
return nullptr;
}

View File

@ -3,7 +3,7 @@
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2019 Markus Gans *
* Copyright 2019-2020 Markus Gans *
* *
* The Final Cut is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public License *
@ -42,6 +42,7 @@ FSystemImpl::FSystemImpl()
FSystemImpl::~FSystemImpl() // destructor
{ }
// public methods of FSystemImpl
//----------------------------------------------------------------------
int FSystemImpl::getpwuid_r ( uid_t uid, struct passwd* pwd
, char* buf, size_t buflen

View File

@ -31,6 +31,7 @@
#include "final/fcolorpalette.h"
#include "final/fkey_map.h"
#include "final/fkeyboard.h"
#include "final/flog.h"
#include "final/fmouse.h"
#include "final/foptiattr.h"
#include "final/foptimove.h"
@ -189,9 +190,9 @@ FTermData* FTerm::getFTermData()
{
data = new FTermData;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermData");
std::abort();
}
}
@ -208,9 +209,9 @@ FSystem* FTerm::getFSystem()
{
fsys = new FSystemImpl;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermData");
std::abort();
}
}
@ -227,9 +228,9 @@ FOptiMove* FTerm::getFOptiMove()
{
opti_move = new FOptiMove;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FOptiMove");
std::abort();
}
}
@ -246,9 +247,9 @@ FOptiAttr* FTerm::getFOptiAttr()
{
opti_attr = new FOptiAttr;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FOptiAttr");
std::abort();
}
}
@ -265,9 +266,9 @@ FTermDetection* FTerm::getFTermDetection()
{
term_detection = new FTermDetection;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermDetection");
std::abort();
}
}
@ -284,9 +285,9 @@ FTermXTerminal* FTerm::getFTermXTerminal()
{
xterm = new FTermXTerminal;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermXTerminal");
std::abort();
}
}
@ -303,9 +304,9 @@ FKeyboard* FTerm::getFKeyboard()
{
keyboard = new FKeyboard;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FKeyboard");
std::abort();
}
}
@ -322,9 +323,9 @@ FMouseControl* FTerm::getFMouseControl()
{
mouse = new FMouseControl;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseControl");
std::abort();
}
}
@ -342,9 +343,9 @@ FTermLinux* FTerm::getFTermLinux()
{
linux = new FTermLinux;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermLinux");
std::abort();
}
}
@ -362,9 +363,9 @@ FTermFreeBSD* FTerm::getFTermFreeBSD()
{
freebsd = new FTermFreeBSD;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermFreeBSD");
std::abort();
}
}
@ -382,9 +383,9 @@ FTermOpenBSD* FTerm::getFTermOpenBSD()
{
openbsd = new FTermOpenBSD;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermOpenBSD");
std::abort();
}
}
@ -403,9 +404,9 @@ FTermDebugData& FTerm::getFTermDebugData()
{
debug_data = new FTermDebugData;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermDebugData");
std::abort();
}
}
@ -624,7 +625,7 @@ void FTerm::redefineDefaultColors (bool enable)
if ( isNewFont() ) // NewFont need the reverse-video attribute
return;
xterm->redefineDefaultColors (enable);
getFTermXTerminal()->redefineDefaultColors (enable);
}
//----------------------------------------------------------------------
@ -665,7 +666,7 @@ bool FTerm::setVGAFont()
{
data->setVGAFont(true);
// Set font in xterm to vga
xterm->setFont("vga");
getFTermXTerminal()->setFont("vga");
data->setNewFont(false);
}
#if defined(__linux__)
@ -700,7 +701,7 @@ bool FTerm::setNewFont()
{
data->setNewFont(true);
// Set font in xterm to 8x16graph
xterm->setFont("8x16graph");
getFTermXTerminal()->setFont("8x16graph");
}
#if defined(__linux__)
else if ( isLinuxTerm() )
@ -739,12 +740,12 @@ bool FTerm::setOldFont()
if ( font.getLength() > 2 )
{
// restore saved xterm font
xterm->setFont(font);
getFTermXTerminal()->setFont(font);
}
else
{
// Set font in xterm to vga
xterm->setFont("vga");
getFTermXTerminal()->setFont("vga");
}
retval = true;
@ -914,7 +915,7 @@ void FTerm::setTermSize (const FSize& size)
{
// Set xterm size
xterm->setTermSize (size);
getFTermXTerminal()->setTermSize (size);
}
//----------------------------------------------------------------------
@ -922,7 +923,7 @@ void FTerm::setTermTitle (const FString& title)
{
// Set the xterm window title
xterm->setTitle (title);
getFTermXTerminal()->setTitle (title);
}
//----------------------------------------------------------------------
@ -1268,10 +1269,10 @@ void FTerm::initScreenSettings()
#endif
// set xterm underline cursor
xterm->setCursorStyle (fc::blinking_underline);
getFTermXTerminal()->setCursorStyle (fc::blinking_underline);
// set xterm color settings to defaults
xterm->setDefaults();
getFTermXTerminal()->setDefaults();
}
//----------------------------------------------------------------------
@ -1297,7 +1298,7 @@ void FTerm::exitWithMessage (const FString& message)
std::fflush (stdout);
if ( ! message.isEmpty() )
std::cerr << "Warning: " << message << std::endl;
FApplication::getLog()->warn(message.c_str());
std::exit (EXIT_FAILURE);
}
@ -1322,7 +1323,7 @@ void FTerm::init_global_values (bool disable_alt_screen)
data->useAlternateScreen(! disable_alt_screen);
// Initialize xterm object
xterm->init();
getFTermXTerminal()->init();
if ( ! getStartOptions().terminal_detection )
term_detection->setTerminalDetection (false);
@ -1845,9 +1846,9 @@ void FTerm::init_captureFontAndTitle()
if ( ! FStartOptions::getFStartOptions().terminal_data_request )
return;
xterm->captureFontAndTitle();
const auto& font = xterm->getFont();
const auto& title = xterm->getTitle();
getFTermXTerminal()->captureFontAndTitle();
const auto& font = getFTermXTerminal()->getFont();
const auto& title = getFTermXTerminal()->getTitle();
if ( ! font.isEmpty() )
data->setXtermFont(font);
@ -1899,14 +1900,14 @@ void FTerm::restoreColorPalette()
else // 8 colors
FColorPalette::reset8ColorPalette (FTerm::setPalette);
xterm->resetColorMap();
getFTermXTerminal()->resetColorMap();
resetColorMap();
}
//----------------------------------------------------------------------
void FTerm::setInsertCursorStyle()
{
xterm->setCursorStyle (fc::blinking_underline);
getFTermXTerminal()->setCursorStyle (fc::blinking_underline);
setKDECursor(fc::UnderlineCursor);
#if defined(__linux__)
@ -1916,13 +1917,13 @@ void FTerm::setInsertCursorStyle()
#endif
if ( isUrxvtTerminal() )
xterm->setCursorColor ("rgb:ffff/ffff/ffff");
getFTermXTerminal()->setCursorColor ("rgb:ffff/ffff/ffff");
}
//----------------------------------------------------------------------
void FTerm::setOverwriteCursorStyle()
{
xterm->setCursorStyle (fc::steady_block);
getFTermXTerminal()->setCursorStyle (fc::steady_block);
setKDECursor(fc::BlockCursor);
#if defined(__linux__)
@ -1932,7 +1933,7 @@ void FTerm::setOverwriteCursorStyle()
#endif
if ( isUrxvtTerminal() )
xterm->setCursorColor ("rgb:eeee/0000/0000");
getFTermXTerminal()->setCursorColor ("rgb:eeee/0000/0000");
}
//----------------------------------------------------------------------
@ -2250,7 +2251,7 @@ void FTerm::init (bool disable_alt_screen)
// Activate meta key sends escape
if ( isXTerminal() )
xterm->metaSendsESC(true);
getFTermXTerminal()->metaSendsESC(true);
// switch to application escape key mode
enableApplicationEscKey();
@ -2429,10 +2430,10 @@ void FTerm::finish()
}
// Reset xterm color settings to default values
xterm->resetDefaults();
getFTermXTerminal()->resetDefaults();
// Set xterm full block cursor
xterm->setCursorStyle (fc::steady_block);
getFTermXTerminal()->setCursorStyle (fc::steady_block);
// Restore the color palette
if ( getStartOptions().color_change )
@ -2454,7 +2455,7 @@ void FTerm::finish()
// Deactivate meta key sends escape
if ( isXTerminal() )
xterm->metaSendsESC(false);
getFTermXTerminal()->metaSendsESC(false);
// Switch to the normal screen
useNormalScreenBuffer();
@ -2471,7 +2472,7 @@ void FTerm::finish()
const auto& exit_message = data->getExitMessage();
if ( ! exit_message.isEmpty() )
std::cerr << exit_message << std::endl;
FApplication::getLog()->info(exit_message.c_str());
deallocationValues();
}
@ -2546,9 +2547,11 @@ void FTerm::signal_handler (int signum)
init_term_object->finish();
std::fflush (stderr);
std::fflush (stdout);
std::cerr << "\nProgram stopped: signal "
*FApplication::getLog() << FLog::Error
<< "\nProgram stopped: signal "
<< signum
<< " (" << strsignal(signum) << ")" << std::endl;
<< " (" << strsignal(signum) << ")"
<< std::endl;
std::terminate();
default:

View File

@ -27,7 +27,9 @@
#include <algorithm>
#include <numeric>
#include "final/fapplication.h"
#include "final/fcharmap.h"
#include "final/flog.h"
#include "final/fterm.h"
#include "final/ftermbuffer.h"
@ -451,7 +453,8 @@ std::size_t getColumnWidth (const FString& s, std::size_t pos)
}
catch (const std::out_of_range& ex)
{
std::cerr << "Out of Range error: " << ex.what() << std::endl;
*FApplication::getLog() << FLog::Error
<< "Out of Range error: " << ex.what() << std::endl;
}
}

View File

@ -83,7 +83,7 @@ void FTermcap::termcap()
std::vector<std::string> terminals{};
static constexpr int success = 1;
static constexpr int uninitialized = -2;
static char term_buffer[2048]{};
static char term_buffer[BUF_SIZE]{};
int status = uninitialized;
const bool color256 = term_detection->canDisplay256Colors();
@ -116,9 +116,6 @@ void FTermcap::termcap()
++iter;
}
if ( std::strncmp(termtype, "ansi", 4) == 0 )
term_detection->setAnsiTerminal (true);
termcapError (status);
termcapVariables();
}
@ -129,11 +126,13 @@ void FTermcap::termcapError (int status)
static constexpr int no_entry = 0;
static constexpr int db_not_found = -1;
static constexpr int uninitialized = -2;
finalcut::FLog& log = *FApplication::getLog();
if ( status == no_entry || status == uninitialized )
{
const char* termtype = fterm_data->getTermType();
std::cerr << "Unknown terminal: " << termtype << "\n"
log << FLog::Error
<< "Unknown terminal: " << termtype << "\n"
<< "Check the TERM environment variable\n"
<< "Also make sure that the terminal\n"
<< "is defined in the termcap/terminfo database.\n";
@ -141,7 +140,7 @@ void FTermcap::termcapError (int status)
}
else if ( status == db_not_found )
{
std::cerr << "The termcap/terminfo database could not be found.\n";
log << "The termcap/terminfo database could not be found.\n";
std::abort();
}
}

View File

@ -25,7 +25,9 @@
#endif
#include "final/emptyfstring.h"
#include "final/fapplication.h"
#include "final/fc.h"
#include "final/flog.h"
#include "final/fsystem.h"
#include "final/fterm.h"
#include "final/ftermdata.h"
@ -377,6 +379,8 @@ void FTermDetection::detectTerminal()
if ( ! new_termtype && std::strlen(termtype) == 5 )
new_termtype = "xterm-16color";
}
else if ( std::strncmp(termtype, "ansi", 4) == 0 ) // ANSI detection
terminal_type.ansi = true;
// set the new environment variable TERM
if ( new_termtype )
@ -587,9 +591,9 @@ const char* FTermDetection::parseAnswerbackMsg (const char current_termtype[])
{
answer_back = new FString(getAnswerbackMsg());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FString");
return nullptr;
}
@ -657,9 +661,9 @@ const char* FTermDetection::parseSecDA (const char current_termtype[])
// Secondary device attributes (SEC_DA) <- decTerminalID string
sec_da = new FString(getSecDA());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FString");
return current_termtype;
}

View File

@ -22,8 +22,10 @@
#include <vector>
#include "final/fapplication.h"
#include "final/fc.h"
#include "final/fcharmap.h"
#include "final/flog.h"
#include "final/fsystem.h"
#include "final/fterm.h"
#include "final/ftermcap.h"
@ -200,7 +202,7 @@ void FTermLinux::init()
}
else
{
std::cerr << "can not open the console.\n";
FApplication::getLog()->error("Can not open the console.");
std::abort();
}
}
@ -553,9 +555,9 @@ bool FTermLinux::getScreenFont()
static constexpr std::size_t data_size = 4 * 32 * 512;
font.data = new uChar[data_size]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FString");
return false;
}
@ -605,9 +607,9 @@ bool FTermLinux::getUnicodeMap()
{
screen_unicode_map.entries = new struct unipair[count]();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("unipair[count]");
return false;
}
@ -683,9 +685,9 @@ int FTermLinux::setScreenFont ( uChar fontdata[], uInt count
{
font.data = new uChar[data_size](); // Initialize with 0
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("uChar[data_size]");
return -1;
}

View File

@ -178,6 +178,18 @@ void FTextView::scrollTo (int x, int y)
updateTerminal();
}
//----------------------------------------------------------------------
void FTextView::scrollToBegin()
{
scrollToY (0);
}
//----------------------------------------------------------------------
void FTextView::scrollToEnd()
{
scrollToY (int(getRows() - getTextHeight()));
}
//----------------------------------------------------------------------
void FTextView::hide()
{
@ -363,9 +375,9 @@ void FTextView::onMouseDown (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
}
@ -392,9 +404,9 @@ void FTextView::onMouseUp (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseUp_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
}
@ -425,9 +437,9 @@ void FTextView::onMouseMove (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseMove_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get());
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FMouseEvent");
}
}
}
@ -577,8 +589,8 @@ inline void FTextView::mapKeyFunctions()
key_map[fc::Fkey_right] = [this] { scrollBy (1, 0); };
key_map[fc::Fkey_ppage] = [this] { scrollBy (0, -int(getTextHeight())); };
key_map[fc::Fkey_npage] = [this] { scrollBy (0, int(getTextHeight())); };
key_map[fc::Fkey_home] = [this] { scrollToY (0); };
key_map[fc::Fkey_end] = [this] { scrollToY (int(getRows() - getTextHeight())); };
key_map[fc::Fkey_home] = [this] { scrollToBegin(); };
key_map[fc::Fkey_end] = [this] { scrollToEnd(); };
}
//----------------------------------------------------------------------

View File

@ -29,6 +29,7 @@
#include "final/fcharmap.h"
#include "final/fcolorpair.h"
#include "final/fkeyboard.h"
#include "final/flog.h"
#include "final/foptiattr.h"
#include "final/foptimove.h"
#include "final/fstyle.h"
@ -690,9 +691,9 @@ void FVTerm::createArea ( const FRect& box
{
area = new FTermArea;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTermArea");
return;
}
@ -1383,9 +1384,9 @@ inline bool FVTerm::reallocateTextArea ( FTermArea* area
area->changes = new FLineChanges[height];
area->data = new FChar[size];
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocFunctionOutput ("FLineChanges[height] or FChar[size]");
return false;
}
@ -1404,9 +1405,9 @@ inline bool FVTerm::reallocateTextArea (FTermArea* area, std::size_t size)
{
area->data = new FChar[size];
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocFunctionOutput ("FChar[size]");
return false;
}
@ -1909,9 +1910,9 @@ void FVTerm::init (bool disable_alt_screen)
term_pos = new FPoint(-1, -1);
output_buffer = new std::queue<int>;
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FTerm, FPoint, or std::queue<int>");
std::abort();
}

View File

@ -24,6 +24,7 @@
#include "final/fapplication.h"
#include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenubar.h"
#include "final/fstatusbar.h"
#include "final/fstring.h"
@ -1689,9 +1690,9 @@ void FWidget::initRootWidget()
always_on_top_list = new FWidgetList();
close_widget = new FWidgetList();
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FWidgetList");
return;
}

View File

@ -27,6 +27,8 @@
#error "Only <final/final.h> can be included directly."
#endif
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fstring.h"
namespace finalcut
@ -51,6 +53,7 @@ public:
// Disable copy assignment operator (=)
emptyFString& operator = (const emptyFString&) = delete;
static const FString getClassName();
static bool isNull();
static const FString& get();
static void clear();
@ -61,6 +64,10 @@ private:
};
// emptyFString inline functions
//----------------------------------------------------------------------
inline const FString emptyFString::getClassName()
{ return "emptyFString"; }
//----------------------------------------------------------------------
inline bool emptyFString::isNull()
{
@ -76,9 +83,9 @@ inline const FString& emptyFString::get()
{
empty_string = new FString("");
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocOutput ("FString");
}
}

View File

@ -68,11 +68,12 @@ namespace finalcut
{
// class forward declaration
class FEvent;
class FAccelEvent;
class FCloseEvent;
class FEvent;
class FFocusEvent;
class FKeyEvent;
class FLog;
class FMouseEvent;
class FStartOptions;
class FTimerEvent;
@ -106,6 +107,10 @@ class FApplication : public FWidget
int getArgc() const;
char** getArgv() const;
static FApplication* getApplicationObject();
static std::shared_ptr<FLog>& getLog();
// Mutator
static void setLog (const std::shared_ptr<FLog>&);
// Inquiry
static bool isQuit();
@ -177,6 +182,7 @@ class FApplication : public FWidget
void processMouseEvent();
void processResizeEvent();
void processCloseWidget();
void processLogger();
bool processNextEvent();
void performTimerAction (FObject*, FEvent*) override;
static bool isEventProcessable (const FObject*, const FEvent*);

View File

@ -49,6 +49,8 @@
#include <final/flineedit.h>
#include <final/flistbox.h>
#include <final/flistview.h>
#include <final/flog.h>
#include <final/flogger.h>
#include <final/fmenubar.h>
#include <final/fmenu.h>
#include <final/fmenuitem.h>

129
src/include/final/flog.h Normal file
View File

@ -0,0 +1,129 @@
/***********************************************************************
* flog.h - Interface of the FINAL CUT logger *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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/>. *
***********************************************************************/
/* Standalone class
*
*
*
* FLog
*
*/
#ifndef FLOG_H
#define FLOG_H
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
#error "Only <final/final.h> can be included directly."
#endif
#include <functional>
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
#include <final/fstring.h>
namespace finalcut
{
using namespace std::placeholders;
//----------------------------------------------------------------------
// class FLog
//----------------------------------------------------------------------
class FLog : public std::stringbuf
{
public:
// Using-declaration
using FLogPrint = std::function<void(const std::string&)>;
// Enumerations
enum LogLevel
{
Info, Warn, Error, Debug
};
enum LineEnding
{
LF, CR, CRLF
};
// Constructor
FLog();
// Destructor
~FLog() override;
template <typename T>
FLog& operator << (const T& s);
FLog& operator << (std::ostream&(*)(std::ostream&));
FLog& operator << (LogLevel);
virtual const FString getClassName() const;
virtual void info (const std::string&) = 0;
virtual void warn (const std::string&) = 0;
virtual void error (const std::string&) = 0;
virtual void debug (const std::string&) = 0;
virtual void setOutputStream (const std::ostream&) = 0;
virtual void setLineEnding (LineEnding) = 0;
virtual void enableTimestamp() = 0;
virtual void disableTimestamp() = 0;
protected:
int sync() override;
// Data member
LogLevel level{Info};
LineEnding end_of_line{CRLF};
private:
// Data member
FLogPrint current_log{std::bind(&FLog::info, this, _1)};
std::ostream stream{this};
};
// FLog inline functions
//----------------------------------------------------------------------
template <typename T>
inline FLog& FLog::operator << (const T& s)
{
stream << s;
return *this;
}
//----------------------------------------------------------------------
inline FLog& FLog::operator << (std::ostream&(*pf)(std::ostream&))
{
pf(stream);
return *this;
}
//----------------------------------------------------------------------
inline const FString FLog::getClassName() const
{ return "FLog"; }
} // namespace finalcut
#endif // FLOG_H

138
src/include/final/flogger.h Normal file
View File

@ -0,0 +1,138 @@
/***********************************************************************
* flogger.h - The FINAL CUT text logger *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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/>. *
***********************************************************************/
/* Standalone class
*
*
*
* FLogger
*
*/
#ifndef FLOGGER_H
#define FLOGGER_H
#if !defined (USE_FINAL_H) && !defined (COMPILE_FINAL_CUT)
#error "Only <final/final.h> can be included directly."
#endif
#include <functional>
#include <iostream>
#include <sstream>
#include <string>
#include <chrono>
#include <iomanip>
#include "final/flog.h"
namespace finalcut
{
//----------------------------------------------------------------------
// class FLogger
//----------------------------------------------------------------------
class FLogger : public FLog
{
public:
// Constructor
FLogger();
// Destructor
~FLogger() override;
// Methods
const FString getClassName() const override;
void info (const std::string&) override;
void warn (const std::string&) override;
void error (const std::string&) override;
void debug (const std::string&) override;
void setOutputStream (const std::ostream&) override;
void setLineEnding (LineEnding) override;
void enableTimestamp() override;
void disableTimestamp() override;
private:
// Methods
void newlineReplace (std::string&, const std::string&);
const std::string getTimeString();
const std::string getEOL();
void printLogLine (const std::string&);
// Data member
bool timestamp{false};
std::ostream output{std::cerr.rdbuf()};
};
// FLogger inline functions
//----------------------------------------------------------------------
inline const FString FLogger::getClassName() const
{ return "FLogger"; }
//----------------------------------------------------------------------
inline void FLogger::info (const std::string& msg)
{
level = Info;
printLogLine (msg);
}
//----------------------------------------------------------------------
inline void FLogger::warn (const std::string& msg)
{
level = Warn;
printLogLine (msg);
}
//----------------------------------------------------------------------
inline void FLogger::error (const std::string& msg)
{
level = Error;
printLogLine (msg);
}
//----------------------------------------------------------------------
inline void FLogger::debug (const std::string& msg)
{
level = Debug;
printLogLine (msg);
}
//----------------------------------------------------------------------
inline void FLogger::setOutputStream (const std::ostream& os)
{ output.rdbuf(os.rdbuf()); }
//----------------------------------------------------------------------
inline void FLogger::setLineEnding (LineEnding eol)
{ end_of_line = eol; }
//----------------------------------------------------------------------
inline void FLogger::enableTimestamp()
{ timestamp = true; }
//----------------------------------------------------------------------
inline void FLogger::disableTimestamp()
{ timestamp = false; }
} // namespace finalcut
#endif // FLOGGER_H

View File

@ -169,8 +169,8 @@ inline const FString FMessageBox::getClassName() const
//----------------------------------------------------------------------
inline const FString FMessageBox::getTitlebarText() const
{
const FString& tb_text = FDialog::getText(); // initialize text
return tb_text;
const FString& title = FDialog::getText(); // initialize text
return title;
}
//----------------------------------------------------------------------

View File

@ -48,6 +48,8 @@
#include <memory>
#include <vector>
#include "final/fstring.h"
namespace finalcut
{

View File

@ -50,6 +50,8 @@
#include <functional>
#include <memory>
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fwidget.h"
namespace finalcut
@ -180,9 +182,9 @@ void initScrollbar ( FScrollbarPtr& bar
{
bar = std::make_shared<FScrollbar>(o, cb_instance);
}
catch (const std::bad_alloc& ex)
catch (const std::bad_alloc&)
{
std::cerr << bad_alloc_str << ex.what() << std::endl;
badAllocFunctionOutput ("FScrollbar");
return;
}

View File

@ -64,7 +64,7 @@ class FStartOptions final
FStartOptions& operator = (const FStartOptions&) = delete;
// Accessors
const FString getClassName();
static const FString getClassName();
static FStartOptions& getFStartOptions();
// Mutator

View File

@ -162,7 +162,7 @@ class FString
operator const char* () const { return c_str(); }
// Accessor
virtual const FString getClassName();
virtual const FString getClassName() const;
// inquiries
bool isNull() const;
@ -370,7 +370,7 @@ inline bool FString::operator > (const CharT& s) const
}
//----------------------------------------------------------------------
inline const FString FString::getClassName()
inline const FString FString::getClassName() const
{ return "FString"; }
//----------------------------------------------------------------------

View File

@ -78,5 +78,3 @@ class FSystem
} // namespace finalcut
#endif // FSYSTEM_H

View File

@ -173,7 +173,7 @@ class FTerm final
FTerm& operator = (const FTerm&) = delete;
// Accessors
const FString getClassName() const;
static const FString getClassName();
static std::size_t getLineNumber();
static std::size_t getColumnNumber();
static const FString getKeyName (FKey);
@ -405,7 +405,7 @@ std::size_t getColumnWidth (const FTermBuffer&);
// FTerm inline functions
//----------------------------------------------------------------------
inline const FString FTerm::getClassName() const
inline const FString FTerm::getClassName()
{ return "FTerm"; }
//----------------------------------------------------------------------

View File

@ -126,6 +126,9 @@ class FTermcap final
static tcap_map strings[];
private:
// Constant
static constexpr std::size_t BUF_SIZE{2048};
// Methods
static void termcap();
static void termcapError (int);
@ -140,7 +143,7 @@ class FTermcap final
static FSystem* fsystem;
static FTermData* fterm_data;
static FTermDetection* term_detection;
static char string_buf[2048];
static char string_buf[BUF_SIZE];
};
@ -153,35 +156,35 @@ inline const FString FTermcap::getClassName() const
template<typename CharT>
bool FTermcap::getFlag (const CharT& cap)
{
return tgetflag(C_STR(cap));
return ::tgetflag(C_STR(cap));
}
//----------------------------------------------------------------------
template<typename CharT>
int FTermcap::getNumber (const CharT& cap)
{
return tgetnum(C_STR(cap));
return ::tgetnum(C_STR(cap));
}
//----------------------------------------------------------------------
template<typename CharT>
char* FTermcap::getString (const CharT& cap)
{
return tgetstr(C_STR(cap), reinterpret_cast<char**>(&string_buf));
return ::tgetstr(C_STR(cap), reinterpret_cast<char**>(&string_buf));
}
//----------------------------------------------------------------------
template<typename CharT>
char* FTermcap::encodeMotionParameter (const CharT& cap, int col, int row)
{
return tgoto(C_STR(cap), col, row);
return ::tgoto(C_STR(cap), col, row);
}
//----------------------------------------------------------------------
template<typename CharT, typename... Args>
inline char* FTermcap::encodeParameter (const CharT& cap, Args&&... args)
{
return tparm (C_STR(cap), std::forward<Args>(args)...);
return ::tparm (C_STR(cap), std::forward<Args>(args)...);
}
//----------------------------------------------------------------------

View File

@ -373,5 +373,3 @@ inline void FTermData::setFramebufferBpp (int bpp)
} // namespace finalcut
#endif // FTERMDATA_H

View File

@ -91,7 +91,7 @@ class FTermDetection final
FTermDetection& operator = (const FTermDetection&) = delete;
// Accessor
const FString getClassName() const;
static const FString getClassName();
static const char* getTermType();
static int getGnomeTerminalID();
FTerminalType& getTermTypeStruct();
@ -240,7 +240,7 @@ struct FTermDetection::secondaryDA
// FTermDetection inline functions
//----------------------------------------------------------------------
inline const FString FTermDetection::getClassName() const
inline const FString FTermDetection::getClassName()
{ return "FTermDetection"; }
//----------------------------------------------------------------------

View File

@ -104,6 +104,8 @@ class FTextView : public FWidget
void scrollToY (int);
void scrollTo (const FPoint&);
void scrollTo (int, int);
void scrollToBegin();
void scrollToEnd();
void scrollBy (int, int);
// Methods

View File

@ -37,6 +37,23 @@
#define null nullptr
#define badAllocFunctionOutput(object_name) \
*FApplication::getLog() << FLog::Error \
<< "Not enough memory to alloc " \
<< (object_name) \
<< " in " \
<< __func__ << std::endl;
#define badAllocOutput(object_name) \
*FApplication::getLog() << FLog::Error \
<< "Not enough memory to alloc " \
<< (object_name) \
<< " in " \
<< getClassName() \
<< "::" \
<< __func__ << std::endl;
//F_METHOD_CALLBACK
namespace
{
@ -69,9 +86,6 @@ typedef void* FDataPtr;
namespace finalcut
{
const char* const bad_alloc_str = \
"not enough memory to alloc ";
template <typename T, bool is_signed>
struct is_negative
{

View File

@ -94,12 +94,12 @@
#include <utility>
#include <vector>
#include "final/fvterm.h"
#include "final/fobject.h"
#include "final/fpoint.h"
#include "final/frect.h"
#include "final/fsize.h"
#include "final/ftypes.h"
#include "final/fvterm.h"
// Callback macros
#define F_FUNCTION_CALLBACK(h) \

View File

@ -21,6 +21,7 @@ noinst_PROGRAMS = \
fcolorpair_test \
fstyle_test \
fstring_test \
flogger_test \
fsize_test \
fpoint_test \
frect_test
@ -39,6 +40,7 @@ foptiattr_test_SOURCES = foptiattr-test.cpp
fcolorpair_test_SOURCES = fcolorpair-test.cpp
fstyle_test_SOURCES = fstyle-test.cpp
fstring_test_SOURCES = fstring-test.cpp
flogger_test_SOURCES = flogger-test.cpp
fsize_test_SOURCES = fsize-test.cpp
fpoint_test_SOURCES = fpoint-test.cpp
frect_test_SOURCES = frect-test.cpp
@ -57,6 +59,7 @@ TESTS = fobject_test \
fcolorpair_test \
fstyle_test \
fstring_test \
flogger_test \
fsize_test \
fpoint_test \
frect_test

353
test/flogger-test.cpp Normal file
View File

@ -0,0 +1,353 @@
/***********************************************************************
* flogger-test.cpp - FLogger unit tests *
* *
* This file is part of the Final Cut widget toolkit *
* *
* Copyright 2020 Markus Gans *
* *
* The 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. *
* *
* The 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 <sstream>
#include <final/final.h>
//----------------------------------------------------------------------
// class FLoggerTest
//----------------------------------------------------------------------
class myLogger : public finalcut::FLog
{
public:
void info (const std::string& entry) override
{
output << " Info: " << entry << std::endl;
}
void warn (const std::string& entry) override
{
output << " Warn: " << entry << std::endl;
}
void error (const std::string& entry) override
{
output << "Error: " << entry << std::endl;
}
void debug (const std::string& entry) override
{
output << "Debug: " << entry << std::endl;
}
void setOutputStream (const std::ostream& os) override
{ output.rdbuf(os.rdbuf()); }
void setLineEnding (LineEnding) override
{ }
void enableTimestamp() override
{ }
void disableTimestamp() override
{ }
private:
// Data member
std::ostream output{std::cerr.rdbuf()};
};
//----------------------------------------------------------------------
// class FLoggerTest
//----------------------------------------------------------------------
class FLoggerTest : public CPPUNIT_NS::TestFixture
{
public:
FLoggerTest()
{ }
protected:
void classNameTest();
void defaultObjectTest();
void lineEndingTest();
void timestampTest();
void fileTest();
void applicationObjectTest();
private:
// Adds code needed to register the test suite
CPPUNIT_TEST_SUITE (FLoggerTest);
// Add a methods to the test suite
CPPUNIT_TEST (classNameTest);
CPPUNIT_TEST (defaultObjectTest);
CPPUNIT_TEST (lineEndingTest);
CPPUNIT_TEST (timestampTest);
CPPUNIT_TEST (fileTest);
CPPUNIT_TEST (applicationObjectTest);
// End of test suite definition
CPPUNIT_TEST_SUITE_END();
};
//----------------------------------------------------------------------
void FLoggerTest::classNameTest()
{
finalcut::FLogger log;
const finalcut::FString& classname = log.getClassName();
CPPUNIT_ASSERT ( classname == "FLogger" );
}
//----------------------------------------------------------------------
void FLoggerTest::defaultObjectTest()
{
finalcut::FLogger log{};
std::ostringstream buf{};
log.setOutputStream(buf);
log << "Hello, World!" << std::flush; // Default level is "Info"
CPPUNIT_ASSERT ( buf.str() == "[INFO] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << "Hel" << "lo," << " Wor" << "ld!" << std::flush; // Several parts
CPPUNIT_ASSERT ( buf.str() == "[INFO] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << "Hello, World!" << std::endl; // std::endl
CPPUNIT_ASSERT ( buf.str() == "[INFO] Hello, World!\n\r\n" );
buf.str(""); // Clear buffer
log << finalcut::FLog::Info << "Hello, World!" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[INFO] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << finalcut::FLog::Warn << "Hello, World!" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[WARNING] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << "Hello, World!" << std::flush; // Last level was "Warn"
CPPUNIT_ASSERT ( buf.str() == "[WARNING] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << finalcut::FLog::Error << "Hello, World!" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[ERROR] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << "Hello, World!" << std::flush; // Last level was "Error"
CPPUNIT_ASSERT ( buf.str() == "[ERROR] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << finalcut::FLog::Debug << "Hello, World!" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[DEBUG] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log << "Hello, World!" << std::flush; // Last level was "Debug"
CPPUNIT_ASSERT ( buf.str() == "[DEBUG] Hello, World!\r\n" );
buf.str(""); // Clear buffer
// Without stream
log.info("Hello, World!");
CPPUNIT_ASSERT ( buf.str() == "[INFO] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log.warn("Hello, World!");
CPPUNIT_ASSERT ( buf.str() == "[WARNING] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log.error("Hello, World!");
CPPUNIT_ASSERT ( buf.str() == "[ERROR] Hello, World!\r\n" );
buf.str(""); // Clear buffer
log.debug("Hello, World!");
CPPUNIT_ASSERT ( buf.str() == "[DEBUG] Hello, World!\r\n" );
buf.str(""); // Clear buffer
}
//----------------------------------------------------------------------
void FLoggerTest::lineEndingTest()
{
finalcut::FLogger log{};
std::ostringstream buf{};
log.setOutputStream(buf);
log.info("Line endings"); // Default = CRLF
CPPUNIT_ASSERT ( buf.str() == "[INFO] Line endings\r\n" );
buf.str(""); // Clear buffer
log.setLineEnding(finalcut::FLog::LF);
log.warn("Line endings");
CPPUNIT_ASSERT ( buf.str() == "[WARNING] Line endings\n" );
buf.str(""); // Clear buffer
log.setLineEnding(finalcut::FLog::CR);
log.error("Line endings");
CPPUNIT_ASSERT ( buf.str() == "[ERROR] Line endings\r" );
buf.str(""); // Clear buffer
log.setLineEnding(finalcut::FLog::CRLF);
log.debug("Line endings");
CPPUNIT_ASSERT ( buf.str() == "[DEBUG] Line endings\r\n" );
buf.str(""); // Clear buffer
}
//----------------------------------------------------------------------
void FLoggerTest::timestampTest()
{
finalcut::FLogger log{};
std::ostringstream buf{};
log.setOutputStream(buf);
log.info("Timestamp");
std::size_t length = buf.str().length();
CPPUNIT_ASSERT ( buf.str() == "[INFO] Timestamp\r\n" );
CPPUNIT_ASSERT ( length == 18 );
buf.str(""); // Clear buffer
log.enableTimestamp();
log.info("Timestamp");
length = buf.str().length();
CPPUNIT_ASSERT ( buf.str().substr(length - 18) == "[INFO] Timestamp\r\n" );
CPPUNIT_ASSERT ( length > 40 );
buf.str(""); // Clear buffer
log.disableTimestamp();
log.info("Timestamp");
length = buf.str().length();
CPPUNIT_ASSERT ( buf.str() == "[INFO] Timestamp\r\n" );
CPPUNIT_ASSERT ( length == 18 );
buf.str(""); // Clear buffer
}
//----------------------------------------------------------------------
void FLoggerTest::fileTest()
{
std::string filename = "test.log";
{
finalcut::FLogger log{};
std::ofstream file_stream(filename, std::ofstream::out);
log.setLineEnding (finalcut::FLog::LF);
log.setOutputStream(file_stream);
log.info("test1");
log.warn("test2");
log.error("test3");
log.debug("test4");
log << finalcut::FLog::Info << "streaming test1";
log << finalcut::FLog::Warn << "streaming test2";
log << finalcut::FLog::Error << "streaming test3";
log << finalcut::FLog::Debug << "streaming test4" << std::flush;
if ( file_stream.is_open() )
file_stream.close();
} // End of logging
std::string strings[] =
{
"[INFO] test1",
"[WARNING] test2",
"[ERROR] test3",
"[DEBUG] test4",
"[INFO] streaming test1",
"[WARNING] streaming test2",
"[ERROR] streaming test3",
"[DEBUG] streaming test4",
""
};
std::string line{};
std::ifstream file_stream{filename};
std::size_t i{0};
while ( ! file_stream.eof() && file_stream.good() )
{
getline(file_stream, line);
CPPUNIT_ASSERT ( line == strings[i] );
i++;
}
if ( file_stream.is_open() )
file_stream.close();
remove("test.log"); // Delete file
}
//----------------------------------------------------------------------
void FLoggerTest::applicationObjectTest()
{
std::shared_ptr<finalcut::FLog> log = finalcut::FApplication::getLog();
std::ostringstream buf{};
log->setOutputStream(buf);
log->info("test1");
CPPUNIT_ASSERT ( buf.str() == "[INFO] test1\r\n" );
buf.str(""); // Clear buffer
log->warn("test2");
CPPUNIT_ASSERT ( buf.str() == "[WARNING] test2\r\n" );
buf.str(""); // Clear buffer
log->error("test3");
CPPUNIT_ASSERT ( buf.str() == "[ERROR] test3\r\n" );
buf.str(""); // Clear buffer
log->debug("test4");
CPPUNIT_ASSERT ( buf.str() == "[DEBUG] test4\r\n" );
buf.str(""); // Clear buffer
*log << "test5" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[INFO] test5\r\n" );
buf.str(""); // Clear buffer
*log << finalcut::FLog::Error << "test6" << std::flush;
CPPUNIT_ASSERT ( buf.str() == "[ERROR] test6\r\n" );
buf.str(""); // Clear buffer
// Replace the logger with another one
finalcut::FApplication::setLog(std::make_shared<myLogger>());
log = finalcut::FApplication::getLog();
log->setOutputStream(buf);
log->info("myLogger 1");
CPPUNIT_ASSERT ( buf.str() == " Info: myLogger 1\n" );
buf.str(""); // Clear buffer
log->warn("myLogger 2");
CPPUNIT_ASSERT ( buf.str() == " Warn: myLogger 2\n" );
buf.str(""); // Clear buffer
log->error("myLogger 3");
CPPUNIT_ASSERT ( buf.str() == "Error: myLogger 3\n" );
buf.str(""); // Clear buffer
log->debug("myLogger 4");
CPPUNIT_ASSERT ( buf.str() == "Debug: myLogger 4\n" );
buf.str(""); // Clear buffer
}
// Put the test suite in the registry
CPPUNIT_TEST_SUITE_REGISTRATION (FLoggerTest);
// The general unit test main part
#include <main-test.inc>