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/.libs/
examples/calculator examples/calculator
examples/dialog examples/dialog
examples/event-log
examples/string-operations examples/string-operations
examples/background-color examples/background-color
examples/opti-move examples/opti-move

View File

@ -75,12 +75,12 @@ matrix:
- whoami - 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 - 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: 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 - autoreconf -v --install --force
- ./configure --prefix=/usr CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -DUNIT_TEST" --with-unit-test - ./configure --prefix=/usr CPPFLAGS="-DDEBUG" CXXFLAGS="-g -O0 -DDEBUG -DUNIT_TEST" --with-unit-test
- make V=1 -j10 - make V=1 -j10
- make check - make check
- cat test/*.log - cat test/*.log || echo
# #
# Coveralls + Codecov # 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> 2020-05-02 Markus Gans <guru.mail@muenster.de>
* Transfer of all termcap functions into the FTermcap class * Transfer of all termcap functions into the FTermcap class

View File

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

View File

@ -211,7 +211,6 @@ void Background::cb_choice (const finalcut::FWidget*, const FDataPtr)
updateTerminal(); updateTerminal();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// main part // main part
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -226,6 +225,20 @@ int main (int argc, char* argv[])
Background dialog(&app); Background dialog(&app);
finalcut::FWidget::setMainWidget(&dialog); finalcut::FWidget::setMainWidget(&dialog);
dialog.show(); 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(); 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) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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 // Test: convert a string to a signed long interger
@ -517,15 +517,15 @@ void convertToNumberExample()
} }
catch (const std::underflow_error& ex) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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 // Test: convert a string to a double value
@ -542,15 +542,15 @@ void convertToNumberExample()
} }
catch (const std::underflow_error& ex) catch (const std::underflow_error& ex)
{ {
std::cerr << "underflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Underflow");
} }
catch (const std::overflow_error& ex) catch (const std::overflow_error& ex)
{ {
std::cerr << "overflow: " << ex.what() << std::endl; finalcut::FApplication::getLog()->error("Overflow");
} }
catch (const std::invalid_argument& ex) 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: " std::cout << " insert: "
<< insert_str.insert("changed ", 7) << std::endl; << 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 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" printf ( " index: [0] = %c ; [4] = %c\n"
, char(index[0]) , char(index[0])
, char(index[4]) ); , char(index[4]) );
} }
catch (const std::out_of_range& ex) 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) } int(getRootWidget()->getHeight() / 6) }
, FSize{60, getRootWidget()->getHeight() * 3 / 4} ); , FSize{60, getRootWidget()->getHeight() * 3 / 4} );
view->setResizeable(); view->setResizeable();
std::string line = ""; std::string line{""};
std::ifstream infile; std::ifstream infile;
infile.open(file); infile.open(file);
@ -1028,7 +1028,7 @@ int main (int argc, char* argv[])
//app.setEncoding(finalcut::fc::VT100); //app.setEncoding(finalcut::fc::VT100);
// Sets the terminal size to 94×30 // Sets the terminal size to 94×30
//app.setTermSize(94,30); //finalcut::FTerm::setTermSize(FSize{94, 30});
// Enable the final cut graphical font // Enable the final cut graphical font
//app.setNewFont(); //app.setNewFont();

View File

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

View File

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

View File

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

View File

@ -25,6 +25,8 @@
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flog.h"
#include "final/flogger.h"
#include "final/fmenu.h" #include "final/fmenu.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fmessagebox.h" #include "final/fmessagebox.h"
@ -108,6 +110,20 @@ FApplication* FApplication::getApplicationObject()
return app_object; 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() bool FApplication::isQuit()
{ {
@ -349,6 +365,9 @@ void FApplication::init (uInt64 key_time, uInt64 dblclick_time)
// Set the default double click interval // Set the default double click interval
if ( mouse ) if ( mouse )
mouse->setDblclickInterval (dblclick_time); mouse->setDblclickInterval (dblclick_time);
// Initialize logging
getLog()->setLineEnding(FLog::CRLF);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -1094,6 +1113,17 @@ void FApplication::processCloseWidget()
setTerminalUpdates (FVTerm::start_terminal_updates); 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() bool FApplication::processNextEvent()
{ {
@ -1104,6 +1134,7 @@ bool FApplication::processNextEvent()
processResizeEvent(); processResizeEvent();
processTerminalUpdate(); processTerminalUpdate();
processCloseWidget(); processCloseWidget();
processLogger();
sendQueuedEvents(); sendQueuedEvents();
num_events += processTimerEvent(); num_events += processTimerEvent();

View File

@ -27,6 +27,7 @@
#include "final/flabel.h" #include "final/flabel.h"
#include "final/flineedit.h" #include "final/flineedit.h"
#include "final/flistbox.h" #include "final/flistbox.h"
#include "final/flog.h"
#include "final/fmouse.h" #include "final/fmouse.h"
#include "final/fpoint.h" #include "final/fpoint.h"
#include "final/fsize.h" #include "final/fsize.h"
@ -605,9 +606,9 @@ void FComboBox::passEventToListWindow (FMouseEvent* const& ev)
list_window.list.setFocus(); list_window.list.setFocus();
list_window.list.onMouseMove(_ev.get()); 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 = list.getItem(index).getText();
input_field.redraw(); input_field.redraw();
processChanged(); processChanged();
std::cout << "\r\n";
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -692,9 +694,9 @@ void FComboBox::cb_inputFieldHandOver (const FWidget*, const FDataPtr)
list_window.list.setFocus(); list_window.list.setFocus();
list_window.list.onMouseMove(_ev.get()); 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); 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; return;
} }
@ -854,9 +854,9 @@ void FDialog::initMoveSizeMenuItem (FMenu* menu)
{ {
move_size_item = new FMenuItem (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; return;
} }
@ -877,9 +877,9 @@ void FDialog::initZoomMenuItem (FMenu* menu)
{ {
zoom_item = new FMenuItem (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; return;
} }
@ -900,9 +900,9 @@ void FDialog::initCloseMenuItem (FMenu* menu)
{ {
close_item = new FMenuItem ("&Close", 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; return;
} }
@ -1358,9 +1358,9 @@ inline void FDialog::passEventToSubMenu ( const mouseStates& ms
setClickedWidget(dialog_menu); setClickedWidget(dialog_menu);
dialog_menu->onMouseMove(_ev.get()); 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; return;
} }
} }
@ -1646,9 +1646,9 @@ void FDialog::cb_move (const FWidget*, const FDataPtr)
{ {
tooltip = new FToolTip(this); 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; return;
} }

View File

@ -27,6 +27,7 @@
#include "final/fcolorpair.h" #include "final/fcolorpair.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flabel.h" #include "final/flabel.h"
#include "final/flog.h"
#include "final/fstatusbar.h" #include "final/fstatusbar.h"
namespace finalcut namespace finalcut
@ -173,9 +174,9 @@ void FLabel::onMouseDown (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b); std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get()); 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; return;
} }
} }

View File

@ -25,6 +25,7 @@
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flabel.h" #include "final/flabel.h"
#include "final/flog.h"
#include "final/flineedit.h" #include "final/flineedit.h"
#include "final/fpoint.h" #include "final/fpoint.h"
#include "final/fsize.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) 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 ) 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) 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) 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++; idx++;
@ -951,7 +955,8 @@ void FLineEdit::adjustTextOffset()
} }
catch (const std::out_of_range& ex) 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) 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()); 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(); 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/fcolorpair.h"
#include "final/fdialog.h" #include "final/fdialog.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h" #include "final/fmenu.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fmenuitem.h" #include "final/fmenuitem.h"
@ -941,9 +942,9 @@ void FMenu::passEventToSubMenu (FMouseEvent* const& ev)
setClickedWidget(opened_sub_menu); setClickedWidget(opened_sub_menu);
opened_sub_menu->onMouseMove(_ev.get()); 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); setClickedWidget(smenu);
smenu->onMouseMove(_ev.get()); 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.mouse_down = true;
mbar.onMouseMove(_ev.get()); 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/fapplication.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h" #include "final/fmenu.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fmenuitem.h" #include "final/fmenuitem.h"
@ -944,9 +945,9 @@ void FMenuBar::passEventToMenu (const FMouseEvent* const& ev)
setClickedWidget(menu); setClickedWidget(menu);
menu->onMouseMove(_ev.get()); 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/fapplication.h"
#include "final/fdialog.h" #include "final/fdialog.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenu.h" #include "final/fmenu.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fmenulist.h" #include "final/fmenulist.h"
@ -614,9 +615,9 @@ void FMenuItem::createDialogList (FMenu* winmenu)
// create a new dialog list item // create a new dialog list item
win_item = new FMenuItem (name, winmenu); 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; return;
} }
@ -663,9 +664,9 @@ void FMenuItem::passMouseEvent ( T widget, const FMouseEvent* ev
{ {
_ev = std::make_shared<FMouseEvent>(ev_type, p2, t, b); _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; return;
} }

View File

@ -24,6 +24,7 @@
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fbutton.h" #include "final/fbutton.h"
#include "final/flog.h"
#include "final/fmessagebox.h" #include "final/fmessagebox.h"
namespace finalcut namespace finalcut
@ -256,9 +257,9 @@ inline void FMessageBox::allocation (int button0, int button1, int button2)
button[2]->setHeight(1, false); 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; return;
} }
} }

View File

@ -60,9 +60,9 @@ FObject::FObject (FObject* parent)
{ {
timer_list = new FTimerList; 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; return;
} }
} }

View File

@ -20,6 +20,8 @@
* <http://www.gnu.org/licenses/>. * * <http://www.gnu.org/licenses/>. *
***********************************************************************/ ***********************************************************************/
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fstartoptions.h" #include "final/fstartoptions.h"
namespace finalcut namespace finalcut
@ -65,9 +67,9 @@ FStartOptions& FStartOptions::getFStartOptions()
{ {
start_options = new FStartOptions; 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(); std::abort();
} }
} }

View File

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

View File

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

View File

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

View File

@ -27,7 +27,9 @@
#include <algorithm> #include <algorithm>
#include <numeric> #include <numeric>
#include "final/fapplication.h"
#include "final/fcharmap.h" #include "final/fcharmap.h"
#include "final/flog.h"
#include "final/fterm.h" #include "final/fterm.h"
#include "final/ftermbuffer.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) 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{}; std::vector<std::string> terminals{};
static constexpr int success = 1; static constexpr int success = 1;
static constexpr int uninitialized = -2; static constexpr int uninitialized = -2;
static char term_buffer[2048]{}; static char term_buffer[BUF_SIZE]{};
int status = uninitialized; int status = uninitialized;
const bool color256 = term_detection->canDisplay256Colors(); const bool color256 = term_detection->canDisplay256Colors();
@ -116,9 +116,6 @@ void FTermcap::termcap()
++iter; ++iter;
} }
if ( std::strncmp(termtype, "ansi", 4) == 0 )
term_detection->setAnsiTerminal (true);
termcapError (status); termcapError (status);
termcapVariables(); termcapVariables();
} }
@ -129,19 +126,21 @@ void FTermcap::termcapError (int status)
static constexpr int no_entry = 0; static constexpr int no_entry = 0;
static constexpr int db_not_found = -1; static constexpr int db_not_found = -1;
static constexpr int uninitialized = -2; static constexpr int uninitialized = -2;
finalcut::FLog& log = *FApplication::getLog();
if ( status == no_entry || status == uninitialized ) if ( status == no_entry || status == uninitialized )
{ {
const char* termtype = fterm_data->getTermType(); const char* termtype = fterm_data->getTermType();
std::cerr << "Unknown terminal: " << termtype << "\n" log << FLog::Error
<< "Check the TERM environment variable\n" << "Unknown terminal: " << termtype << "\n"
<< "Also make sure that the terminal\n" << "Check the TERM environment variable\n"
<< "is defined in the termcap/terminfo database.\n"; << "Also make sure that the terminal\n"
<< "is defined in the termcap/terminfo database.\n";
std::abort(); std::abort();
} }
else if ( status == db_not_found ) 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(); std::abort();
} }
} }

View File

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

View File

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

View File

@ -178,6 +178,18 @@ void FTextView::scrollTo (int x, int y)
updateTerminal(); updateTerminal();
} }
//----------------------------------------------------------------------
void FTextView::scrollToBegin()
{
scrollToY (0);
}
//----------------------------------------------------------------------
void FTextView::scrollToEnd()
{
scrollToY (int(getRows() - getTextHeight()));
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
void FTextView::hide() void FTextView::hide()
{ {
@ -363,9 +375,9 @@ void FTextView::onMouseDown (FMouseEvent* ev)
std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b); std::make_shared<FMouseEvent>(fc::MouseDown_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get()); 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); std::make_shared<FMouseEvent>(fc::MouseUp_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get()); 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); std::make_shared<FMouseEvent>(fc::MouseMove_Event, p, tp, b);
FApplication::sendEvent (parent, _ev.get()); 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_right] = [this] { scrollBy (1, 0); };
key_map[fc::Fkey_ppage] = [this] { scrollBy (0, -int(getTextHeight())); }; key_map[fc::Fkey_ppage] = [this] { scrollBy (0, -int(getTextHeight())); };
key_map[fc::Fkey_npage] = [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_home] = [this] { scrollToBegin(); };
key_map[fc::Fkey_end] = [this] { scrollToY (int(getRows() - getTextHeight())); }; key_map[fc::Fkey_end] = [this] { scrollToEnd(); };
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

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

View File

@ -24,6 +24,7 @@
#include "final/fapplication.h" #include "final/fapplication.h"
#include "final/fevent.h" #include "final/fevent.h"
#include "final/flog.h"
#include "final/fmenubar.h" #include "final/fmenubar.h"
#include "final/fstatusbar.h" #include "final/fstatusbar.h"
#include "final/fstring.h" #include "final/fstring.h"
@ -1689,9 +1690,9 @@ void FWidget::initRootWidget()
always_on_top_list = new FWidgetList(); always_on_top_list = new FWidgetList();
close_widget = 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; return;
} }

View File

@ -27,6 +27,8 @@
#error "Only <final/final.h> can be included directly." #error "Only <final/final.h> can be included directly."
#endif #endif
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fstring.h" #include "final/fstring.h"
namespace finalcut namespace finalcut
@ -51,6 +53,7 @@ public:
// Disable copy assignment operator (=) // Disable copy assignment operator (=)
emptyFString& operator = (const emptyFString&) = delete; emptyFString& operator = (const emptyFString&) = delete;
static const FString getClassName();
static bool isNull(); static bool isNull();
static const FString& get(); static const FString& get();
static void clear(); static void clear();
@ -61,6 +64,10 @@ private:
}; };
// emptyFString inline functions // emptyFString inline functions
//----------------------------------------------------------------------
inline const FString emptyFString::getClassName()
{ return "emptyFString"; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline bool emptyFString::isNull() inline bool emptyFString::isNull()
{ {
@ -76,9 +83,9 @@ inline const FString& emptyFString::get()
{ {
empty_string = new FString(""); 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 forward declaration
class FEvent;
class FAccelEvent; class FAccelEvent;
class FCloseEvent; class FCloseEvent;
class FEvent;
class FFocusEvent; class FFocusEvent;
class FKeyEvent; class FKeyEvent;
class FLog;
class FMouseEvent; class FMouseEvent;
class FStartOptions; class FStartOptions;
class FTimerEvent; class FTimerEvent;
@ -106,6 +107,10 @@ class FApplication : public FWidget
int getArgc() const; int getArgc() const;
char** getArgv() const; char** getArgv() const;
static FApplication* getApplicationObject(); static FApplication* getApplicationObject();
static std::shared_ptr<FLog>& getLog();
// Mutator
static void setLog (const std::shared_ptr<FLog>&);
// Inquiry // Inquiry
static bool isQuit(); static bool isQuit();
@ -177,6 +182,7 @@ class FApplication : public FWidget
void processMouseEvent(); void processMouseEvent();
void processResizeEvent(); void processResizeEvent();
void processCloseWidget(); void processCloseWidget();
void processLogger();
bool processNextEvent(); bool processNextEvent();
void performTimerAction (FObject*, FEvent*) override; void performTimerAction (FObject*, FEvent*) override;
static bool isEventProcessable (const FObject*, const FEvent*); static bool isEventProcessable (const FObject*, const FEvent*);

View File

@ -49,6 +49,8 @@
#include <final/flineedit.h> #include <final/flineedit.h>
#include <final/flistbox.h> #include <final/flistbox.h>
#include <final/flistview.h> #include <final/flistview.h>
#include <final/flog.h>
#include <final/flogger.h>
#include <final/fmenubar.h> #include <final/fmenubar.h>
#include <final/fmenu.h> #include <final/fmenu.h>
#include <final/fmenuitem.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 inline const FString FMessageBox::getTitlebarText() const
{ {
const FString& tb_text = FDialog::getText(); // initialize text const FString& title = FDialog::getText(); // initialize text
return tb_text; return title;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

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

View File

@ -50,6 +50,8 @@
#include <functional> #include <functional>
#include <memory> #include <memory>
#include "final/fapplication.h"
#include "final/flog.h"
#include "final/fwidget.h" #include "final/fwidget.h"
namespace finalcut namespace finalcut
@ -180,9 +182,9 @@ void initScrollbar ( FScrollbarPtr& bar
{ {
bar = std::make_shared<FScrollbar>(o, cb_instance); 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; return;
} }

View File

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

View File

@ -162,7 +162,7 @@ class FString
operator const char* () const { return c_str(); } operator const char* () const { return c_str(); }
// Accessor // Accessor
virtual const FString getClassName(); virtual const FString getClassName() const;
// inquiries // inquiries
bool isNull() const; 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"; } { return "FString"; }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

View File

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

View File

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

View File

@ -126,6 +126,9 @@ class FTermcap final
static tcap_map strings[]; static tcap_map strings[];
private: private:
// Constant
static constexpr std::size_t BUF_SIZE{2048};
// Methods // Methods
static void termcap(); static void termcap();
static void termcapError (int); static void termcapError (int);
@ -140,7 +143,7 @@ class FTermcap final
static FSystem* fsystem; static FSystem* fsystem;
static FTermData* fterm_data; static FTermData* fterm_data;
static FTermDetection* term_detection; 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> template<typename CharT>
bool FTermcap::getFlag (const CharT& cap) bool FTermcap::getFlag (const CharT& cap)
{ {
return tgetflag(C_STR(cap)); return ::tgetflag(C_STR(cap));
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
template<typename CharT> template<typename CharT>
int FTermcap::getNumber (const CharT& cap) int FTermcap::getNumber (const CharT& cap)
{ {
return tgetnum(C_STR(cap)); return ::tgetnum(C_STR(cap));
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
template<typename CharT> template<typename CharT>
char* FTermcap::getString (const CharT& cap) 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> template<typename CharT>
char* FTermcap::encodeMotionParameter (const CharT& cap, int col, int row) 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> template<typename CharT, typename... Args>
inline char* FTermcap::encodeParameter (const CharT& cap, Args&&... 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 } // namespace finalcut
#endif // FTERMDATA_H #endif // FTERMDATA_H

View File

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

View File

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

View File

@ -37,6 +37,23 @@
#define null nullptr #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 namespace
{ {
@ -69,9 +86,6 @@ typedef void* FDataPtr;
namespace finalcut namespace finalcut
{ {
const char* const bad_alloc_str = \
"not enough memory to alloc ";
template <typename T, bool is_signed> template <typename T, bool is_signed>
struct is_negative struct is_negative
{ {

View File

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

View File

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