/*
* freescope - Free source browser
* Copyright (C) 2001 Olivier Deme
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
// FILE: trace.cpp
/************/
/* INCLUDES */
/************/
#ifndef NOT_BSD
#include <sys/time.h>
#endif // NOT_BSD
#include <stdio.h>
#include "trace.h"
/*******************/
/* INITIALIZATIONS */
/*******************/
Trace::Flags Trace::m_flags = Trace::FLAGS_TIME_LOCAL;
unsigned int Trace::m_locLine = 0;
char* Trace::m_locFile = "";
Trace::Module Trace::m_module = 0;
Trace::Level Trace::m_level = 0;
Trace* Trace::m_instance = 0;
const Trace::Module Trace::GLOBAL = 0;
/************************/
/* FUNCTION DEFINITIONS */
/************************/
/*
* FUNCTION: Trace::Trace
*
* DESCRIPTION: Constructor
*
* IN:
* IN-OUT:
* RETURN CODE:
*/
Trace::Trace () throw()
: HEADER_DELIMITER('-'),
LEVEL_ERROR(-1),
m_start(true),
m_streams(OSTREAM_STDOUT),
m_moduleMaxLength(0),
m_levelMaxLength(0)
{
for (unsigned int i = 0; i < sizeof(Module)*8; ++i)
{
m_modules[i].levels = 0;
m_modules[i].levDescrBits = 0;
m_modules[i].descriptionSet = false;
}
// Initialize a lookup table for level indexes
int powerOfTwo = 1;
for (unsigned int i = 0; i < sizeof(Level)*8; ++i)
{
m_lookupLevel[i] = powerOfTwo;
powerOfTwo *= 2;
}
m_modules[GLOBAL].descriptionSet = true;
m_modules[GLOBAL].description = "GLOBAL";
cout.setf(ios::uppercase);
cerr.setf(ios::uppercase);
}
/*
* FUNCTION: Trace::set_program_name
*
* DESCRIPTION: Set the program name
*
* IN: name The prohram name
* IN-OUT:
* RETURN CODE:
*/
void Trace::set_program_name ( const string& name)
throw ()
{
m_programName = name;
}
/*
* FUNCTION: Trace::add_to_mask
*
* DESCRIPTION: This function ORwises the bits passed as argument
* with the mask associated with the specified module.
*
* IN: module The module
* levels The level(s) to add to the mask(s)
* IN-OUT:
* RETURN CODE: The old mask value
*/
Trace::Level Trace::add_to_mask (const Module module,
const Level levels)
throw ()
{
// Check module has valid value
if ((size_t)module >= sizeof(Module)*8)
return LEVEL_ERROR;
Level old_mask = m_modules[module].levels;
m_modules[module].levels |= levels;
return old_mask;
}
/*
* FUNCTION: Trace::remove_from_mask
*
* DESCRIPTION: This function removes levels from the masks associated
* with the specified module.
*
* IN: module The module
* levels The level(s) to remove from the mask(s)
* IN-OUT:
* RETURN CODE:
*/
Trace::Level Trace::remove_from_mask (const Module module,
const Level levels)
throw ()
{
// Check module has valid value
if ((size_t)module >= sizeof(Module)*8)
return LEVEL_ERROR;
Level old_mask = m_modules[module].levels;
m_modules[module].levels &= ~levels;
return old_mask;
}
/*
* FUNCTION: Trace::set_mask
*
* DESCRIPTION: This function sets the mask for the specified module
*
* IN: module The module
* levels The new mask
* IN-OUT:
* RETURN CODE:
*/
Trace::Level Trace::set_mask (const Module module,
const Level levels)
throw ()
{
// Check module has valid value
if ((size_t)module >= sizeof(Module)*8)
return LEVEL_ERROR;
Level old_mask = m_modules[module].levels;
m_modules[module].levels = levels;
return old_mask;
}
/*
* FUNCTION: Trace::set_level_description
*
* DESCRIPTION: This function sets the description for one or more
* specified levels
*
* IN: module: The affected module
* levels: The affected levels
* description: The description string
* IN-OUT:
* RETURN CODE:
*/
void Trace::set_level_description (const Module module,
const Level levels,
const string& description)
throw()
{
// Check module has valid value
if ((size_t)module >= sizeof(Module)*8)
return;
Level level = 1;
// Find affected levels
for (unsigned int i = 0; i < sizeof(Level)*8; ++i)
{
if (levels & level)
{
// Set the description
if (description.size() != 0)
{
m_modules[module].levDescr[i] = description;
m_modules[module].levDescrBits |= 0x1 << i;
if (description.size() > m_levelMaxLength)
m_levelMaxLength = description.size();
}
else
{
// Unset description bit
m_modules[module].levDescrBits &= ~(0x1 << i);
m_levelMaxLength = 0;
set_level_max_length();
}
}
level <<= 1;
}
}
/*
* FUNCTION: Trace::set_module_description
*
* DESCRIPTION: This function sets the decription for a module
*
* IN: module The module
* description The description
* IN-OUT:
* RETURN CODE:
*/
void Trace::set_module_description (const Module module,
const string& description)
throw()
{
// Check module has valid value
if ((size_t)module >= sizeof(Module)*8)
return;
if (description.size() != 0)
{
m_modules[module].description = description;
m_modules[module].descriptionSet = true;
if (description.size() > m_moduleMaxLength)
m_moduleMaxLength = description.size();
}
else
{
m_modules[module].descriptionSet = false;
m_moduleMaxLength = 0;
set_module_max_length();
}
}
/*
* FUNCTION: Trace::enable
*
* DESCRIPTION: This function ORwises the specified options with the
* flags already set in the class
*
* IN: flags The flags
* IN-OUT:
* RETURN CODE: The old flags value
*/
Trace::Flags Trace::enable (const Flags flags)
throw ()
{
Flags old_flags = m_flags;
m_flags |= flags;
return old_flags;
}
/*
* FUNCTION: Trace::disable
*
* DESCRIPTION: This function disables the specified options from the class
* flags
*
* IN: flags The flags
* IN-OUT:
* RETURN CODE: The old flags value
*/
Trace::Flags Trace::disable (const Flags flags)
throw ()
{
Flags old_flags = m_flags;
m_flags &= ~flags;
return old_flags;
}
/*
* FUNCTION: Trace::set_flags
*
* DESCRIPTION: This function set the flags attribute.
*
* IN: flags The flags
* IN-OUT:
* RETURN CODE: The old flags value
*/
Trace::Flags Trace::set_flags (const Flags flags)
throw ()
{
Flags old_flags = m_flags;
m_flags = flags;
return old_flags;
}
/*
* FUNCTION: Trace::close
*
* DESCRIPTION: This function closes one or more streams
*
* IN: streams The streams to close
* IN-OUT:
* RETURN CODE: The resulting opened streams
*/
Trace::Stream Trace::close (Stream streams)
throw()
{
if ((m_streams & OSTREAM_FILE) && (streams & OSTREAM_FILE))
m_file.close();
m_streams &= ~streams;
return m_streams;
}
/*
* FUNCTION: Trace::open
*
* DESCRIPTION: Open a stream
*
* IN: streams The streams to open
* IN-OUT:
* RETURN CODE: The resulting opened streams
*/
Trace::Stream Trace::open (Stream streams)
throw ()
{
// Ignore file stream beacuse no file name specified
if (streams & OSTREAM_FILE)
streams &= ~OSTREAM_FILE;
m_streams |= streams;
return m_streams;
}
/*
* FUNCTION: Trace::open
*
* DESCRIPTION: Open a stream
*
* IN: streams The streams to open
* filename The name of a file to open
* IN-OUT:
* RETURN CODE: The resulting opened streams
*/
Trace::Stream Trace::open (const Stream streams,
const string& filename)
{
if ((streams & OSTREAM_FILE) &&
((m_streams & OSTREAM_FILE) == 0))
{
m_file.open(filename.c_str(), ios::app);
if (m_file == 0)
return m_streams;
}
m_file.setf(ios::uppercase);
m_streams |= streams;
return m_streams;
}
/*
* FUNCTION: Trace::create
*
* DESCRIPTION: This is the function that creates a Trace object
*
* IN:
* IN-OUT:
* RETURN CODE: true on success, false otherwise
*/
bool Trace::create ()
throw (bad_alloc)
{
assert(m_instance == 0); // An instance has already been created!
try
{
m_instance = new Trace();
}
catch (bad_alloc& ba)
{
// Propagate exception
throw;
return false;
}
return true;
}
/*
* FUNCTION: Trace::time_stamp()
*
* DESCRIPTION: This function gets the local time.
*
* IN:
* IN-OUT: buffer The buffer used to store the time stamp
* RETURN CODE: The number of characters written in the buffer
*/
int Trace::time_stamp (char* buffer)
throw ()
{
/*
* UNIX-LIKE PLATFORMS
*/
#if (!defined NO_GETTIMEOFDAY_AND_GETLOCALTIME && !defined HAVE_GETLOCALTIME)
struct timeval t1;
struct tm* t2;
gettimeofday(&t1, NULL);
if (m_flags & FLAGS_TIME_LOCAL)
t2 = localtime((time_t*)&t1.tv_sec);
else
t2 = gmtime((time_t*)&t1.tv_sec);
sprintf(buffer,
"%.2d:%.2d:%.2d.%.2d",
t2->tm_hour,
t2->tm_min,
t2->tm_sec,
(int)t1.tv_usec/10000);
return 11;
/*
* WINDOWS PLATOFORMS
*/
#elif (defined HAVE_GETLOCATIME)
/*
* OTHER PLATFORMS
*/
#else // HAVE_GETLOCALTIME
// Get the time with a resolution of a second
struct time_t t1;
struct tm* t2;
time(&t1);
if (m_flags & FLAGS_TIME_LOCAL)
t2 = localtime(&t1);
else
t2 = gmtime(&t1);
sprintf(buffer,
"%.2d:%.2d:%.2d",
t2->tm_hour,
t2->tm_min,
t2->tm_sec);
return 8;
#endif // !NO_GETTIMEOFDAY_AND_GETLOCALTIME && !HAVE_GETLOCALTIME
return 0;
}
/*
* FUNCTION: Trace::do_header
*
* DESCRIPTION: This function outputs to the opened streams all the
* header fields that have been enabled.
*
* IN:
* IN-OUT:
* RETURN CODE:
*/
void Trace::do_header ()
{
// Use character buffer for efficiency reasons
char header[80];
char* p = header;
header[0] = '\0';
if ((m_flags & FLAGS_PROGRAM_NAME) &&
(m_programName.size() != 0))
{
p += sprintf(p,
"%s %c ",
m_programName.c_str(),
HEADER_DELIMITER);
}
if (m_flags & FLAGS_TIMESTAMP)
{
p += time_stamp(p);
p += sprintf(p, " %c ", HEADER_DELIMITER);
}
if (m_flags & FLAGS_MODULE_DESCRIPTION)
{
if (m_modules[m_module].descriptionSet == true)
{
if (m_flags & FLAGS_ALIGNMENT)
{
p += sprintf(p,
"%-*s %c ",
m_moduleMaxLength,
m_modules[m_module].description.c_str(),
HEADER_DELIMITER);
}
else
{
p += sprintf(p,
"%s %c ",
m_modules[m_module].description.c_str(),
HEADER_DELIMITER);
}
}
}
if (m_flags & FLAGS_LEVEL_DESCRIPTION)
{
int indexLevel;
// Retrieve level index.
for (indexLevel = 0;
!(m_lookupLevel[indexLevel] & m_level);
++indexLevel);
if (m_modules[m_module].levDescrBits & (0x1 << indexLevel))
{
// A description has ben provided for this level
if (m_flags & FLAGS_ALIGNMENT)
{
p += sprintf(p,
"%-*s %c ",
m_levelMaxLength,
m_modules[m_module].levDescr[indexLevel].c_str(),
HEADER_DELIMITER);
}
else
{
p += sprintf(p,
"%s %c ",
m_modules[m_module].levDescr[indexLevel].c_str(),
HEADER_DELIMITER);
}
}
else
{
// No description has been provided for this level.
if (m_flags & FLAGS_ALIGNMENT)
{
p += sprintf(p,
"0x%-*X %c ",
m_levelMaxLength,
m_level,
HEADER_DELIMITER);
}
else
{
p += sprintf(p,
"0x%X %c ",
m_level,
HEADER_DELIMITER);
}
}
}
if (m_flags & FLAGS_CALLER)
{
p += sprintf(p,
"%s:%d %c ",
m_locFile,
m_locLine,
HEADER_DELIMITER);
}
// Send the header to the opened streams
if (m_streams & OSTREAM_STDOUT)
cout << header;
if (m_streams & OSTREAM_STDERR)
cerr << header;
if (m_streams & OSTREAM_FILE)
m_file << header;
// do not print the header until "endl" or "flush" manipulators
m_start = false;
}
/*
* FUNCTION: Trace::set_module_max_length
*
* DESCRIPTION: Retrieve and store the biggest length among all module
* descriptions.
*
* IN:
* IN-OUT:
* RETURN CODE:
*/
void Trace::set_module_max_length ()
throw ()
{
for (unsigned int i = 0; i < sizeof(Module)*8; ++i)
{
if ((m_modules[i].descriptionSet == true) &&
(m_modules[i].description.size() > m_moduleMaxLength))
{
m_moduleMaxLength = m_modules[i].description.size();
}
}
}
/*
* FUNCTION: Trace::set_level_max_length
*
* DESCRIPTION: Retrieve and store the biggest length among all level
* descriptions.
*
* IN:
* IN-OUT:
* RETURN CODE:
*/
void Trace::set_level_max_length ()
throw ()
{
for (unsigned int i = 0; i < sizeof(Module)*8; ++i)
{
Level level = 0x1;
// Iterate levels
for (unsigned int j = 0; j < sizeof(Level)*8; ++j)
{
if ((m_modules[i].levDescrBits & level) &&
(m_modules[i].levDescr[j].size() > m_levelMaxLength))
{
m_levelMaxLength = m_modules[i].levDescr[j].size();
}
level <<= 1;
}
}
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a character to the streams
*
*/
Trace& Trace::operator<< (char character)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << character;
if (m_streams & OSTREAM_STDERR)
cerr << character;
if (m_streams & OSTREAM_FILE)
m_file << character;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a character to the streams
*
*/
Trace& Trace::operator<< (unsigned char character)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << character;
if (m_streams & OSTREAM_STDERR)
cerr << character;
if (m_streams & OSTREAM_FILE)
m_file << character;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a string to the streams
*
*/
Trace& Trace::operator<< (char* str)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << str;
if (m_streams & OSTREAM_STDERR)
cerr << str;
if (m_streams & OSTREAM_FILE)
m_file << str;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a string to the streams
*
*/
Trace& Trace::operator<< (unsigned char* str)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << str;
if (m_streams & OSTREAM_STDERR)
cerr << str;
if (m_streams & OSTREAM_FILE)
m_file << str;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a string to the streams
*
*/
Trace& Trace::operator<< (const string& str)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << str.c_str();
if (m_streams & OSTREAM_STDERR)
cerr << str.c_str();
if (m_streams & OSTREAM_FILE)
m_file << str.c_str();
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send an int to the streams
*
*/
Trace& Trace::operator<< (int nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send an unsigned int to the streams
*
*/
Trace& Trace::operator<< (unsigned int nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a long to the streams
*
*/
Trace& Trace::operator<< (long nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send an unsigned long to the streams
*
*/
Trace& Trace::operator<< (unsigned long nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a short to the streams
*
*/
Trace& Trace::operator<< (short nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send an unsigned short to the streams
*
*/
Trace& Trace::operator<< (unsigned short nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a float short to the streams
*
*/
Trace& Trace::operator<< (float nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: Trace::operator<<
*
* DESCRIPTION: Send a double short to the streams
*
*/
Trace& Trace::operator<< (double nbr)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
if (m_start == true)
do_header();
if (m_streams & OSTREAM_STDOUT)
cout << nbr;
if (m_streams & OSTREAM_STDERR)
cerr << nbr;
if (m_streams & OSTREAM_FILE)
m_file << nbr;
return *this;
}
/*
* OPERATOR: operator<<
*
* DESCRIPTION: This operator is used for implementing the Hex effector.
*/
Trace& operator<< (Trace& trace, const Hex& h)
{
// Do nothing if module is invalid
if ((size_t)trace.m_module >= sizeof(Trace::Module)*8)
return trace;
if ((trace.m_modules[trace.m_module].levels & trace.m_level) == 0)
return trace;
if (trace.m_start == true)
trace.do_header();
if (trace.m_streams & Trace::OSTREAM_STDOUT)
{
cout.setf(ios::hex, ios::basefield);
cout << "0x" << h.m_nbr;
cout.setf(ios::dec, ios::basefield);
}
if (trace.m_streams & Trace::OSTREAM_STDERR)
{
cerr.setf(ios::hex, ios::basefield);
cerr << "0x" << h.m_nbr;
cerr.setf(ios::dec, ios::basefield);
}
if (trace.m_streams & Trace::OSTREAM_FILE)
{
trace.m_file.setf(ios::hex, ios::basefield);
trace.m_file << "0x" << h.m_nbr;
trace.m_file.setf(ios::dec, ios::basefield);
}
return trace;
}
Trace& Trace::operator<< (Trace_manip m)
{
// Do nothing if module is invalid
if ((size_t)m_module >= sizeof(Module)*8)
return *this;
if ((m_modules[m_module].levels & m_level) == 0)
return *this;
m(*this);
return *this;
}
Trace& operator<< (Trace& trace, const Width& w)
{
// Do nothing if module is invalid
if ((size_t)trace.m_module >= sizeof(Trace::Module)*8)
return trace;
if ((trace.m_modules[trace.m_module].levels & trace.m_level) == 0)
return trace;
int justify;
if (trace.m_start == true)
trace.do_header();
switch (w.m_fmt)
{
case Width::LEFT: justify = ios::left;
break;
case Width::RIGHT: justify = ios::right;
break;
default: return trace;
}
if (trace.m_streams & Trace::OSTREAM_STDOUT)
{
cout.width(w.m_width);
cout.fill(w.m_fill);
cout.setf(justify, ios::adjustfield);
}
if (trace.m_streams & Trace::OSTREAM_STDERR)
{
cerr.width(w.m_width);
cerr.fill(w.m_fill);
cerr.setf(justify, ios::adjustfield);
}
if (trace.m_streams & Trace::OSTREAM_FILE)
{
trace.m_file.width(w.m_width);
trace.m_file.fill(w.m_fill);
trace.m_file.setf(justify, ios::adjustfield);
}
return trace;
}
/*
* MANIPULATOR: endl
*
* DESCRIPTION: This manipulator adds a carriage return and flushes the
* opened streams.
*/
Trace& endl (Trace& trace)
{
// Do nothing if module is invalid
if ((size_t)trace.m_module >= sizeof(Trace::Module)*8)
return trace;
if ((trace.m_modules[trace.m_module].levels & trace.m_level) == 0)
return trace;
if (trace.m_start == true)
trace.do_header();
if (trace.m_streams & Trace::OSTREAM_STDOUT)
cout << endl;
if (trace.m_streams & Trace::OSTREAM_STDERR)
cerr << endl;
if (trace.m_streams & Trace::OSTREAM_FILE)
trace.m_file << endl;
trace.m_start = true;
return trace;
}
/*
* MANIPULATOR: flush
*
* DESCRIPTION: This manipulator flushes the opened streams
*/
Trace& flush (Trace& trace)
{
// Do nothing if module is invalid
if ((size_t)trace.m_module >= sizeof(Trace::Module)*8)
return trace;
if ((trace.m_modules[trace.m_module].levels & trace.m_level) == 0)
return trace;
if (trace.m_start == true)
trace.do_header();
if (trace.m_streams & Trace::OSTREAM_STDOUT)
cout << flush;
if (trace.m_streams & Trace::OSTREAM_STDERR)
cerr << flush;
if (trace.m_streams & Trace::OSTREAM_FILE)
trace.m_file << flush;
trace.m_start = true;
return trace;
}
/*
* FUNCTION: Width::Width
*
* DESCRIPTION: Effector constructor
*
* IN: justify The type of justification
* width The width of the next output
* fill The filling character
* IN-OUT:
* RETURN CODE:
*/
Width::Width (Format justify, unsigned int width, char fill)
: m_fmt(justify),
m_width(width),
m_fill(fill)
{
}
syntax highlighted by Code2HTML, v. 0.9.1