#include "QFramework/TQLibrary.h"
#include "TTree.h"
#include "QFramework/TQStringUtils.h"
#include "QFramework/TQFolder.h"
#include "definitions.h"
#include "locals.h"
#include <iostream>
#include <stdlib.h>
#include "stdio.h"
#include "unistd.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fstream>
#include <string>
#include <iostream>
#include <sys/ioctl.h>
#include <algorithm>
#include "TROOT.h"
#include "TInterpreter.h"

#include "QFramework/TQUtils.h"
#include "QFramework/TQIterator.h"
#include "QFramework/TQPathManager.h"

////////////////////////////////////////////////////////////////////////////////////////////////
//
// TQLibrary
//
// The TQLibrary is a global/static class of which there should only be one instance at a time.
// It is not intended to be instantiated by the user -- instead, an instance of it is created
// automatically at runtime as a global static member variable TQLibrary::gQFramework.
//
// It facilitates a set of OS and/or root-version specific 'hacks' to help the user
// in keeping his or her own code clean of such workarounds.
//
// It also provides functions to access version numbers of the compiler and root itself.
//
////////////////////////////////////////////////////////////////////////////////////////////////

int TQLibrary::stdoutfd(dup(fileno(stdout)));
int TQLibrary::stderrfd(dup(fileno(stderr)));
bool TQLibrary::stdoutfd_isRedirected(false);
bool TQLibrary::stderrfd_isRedirected(false);
bool TQLibrary::stdoutfd_allowRedirection(true);
bool TQLibrary::stderrfd_allowRedirection(true);
bool TQLibrary::stdoutstr_isCaptured(false);
bool TQLibrary::stderrstr_isCaptured(false);
bool TQLibrary::stdouterrstr_areCaptured(false);
bool TQLibrary::stdoutstr_allowCapturing(true);
bool TQLibrary::stderrstr_allowCapturing(true);
std::streambuf* TQLibrary::defaultStdoutStreamBuf(NULL);
std::streambuf* TQLibrary::defaultStderrStreamBuf(NULL);
std::stringstream* TQLibrary::capturingStdoutStream(NULL);
std::stringstream* TQLibrary::capturingStderrStream(NULL);
std::stringstream* TQLibrary::capturingStdoutStderrStream(NULL);

TQMessageStream TQLibrary::msgStream(std::cout);


TQLibrary* TQLibrary::getQLibrary(){
  // return a pointer to gQFramework
  if(TQLibrary::isInitialized)
    return &TQLibrary::gQFramework;
  return NULL;
}

TQLibrary TQLibrary::gQFramework;
bool TQLibrary::isInitialized(false);

TQLibrary::TQLibrary() :
#ifdef VC_VERSION
  libversion(VC_VERSION),
#else
  libversion("UNKNOWN"),
#endif
#ifdef ROOTVERSION
  rootversion(ROOTVERSION),
#else
  rootversion("UNKNOWN"),
#endif
#ifdef GCCVERSION
  gccversion(GCCVERSION),
#else
  gccversion("UNKNOWN"),
#endif
#ifdef TQPATH
  tqpath(TQPATH),
#else
  tqpath(""),
#endif
  eosmgmurl("root://eosuser.cern.ch"),
  eoscmd("xrdfs eosatlas.cern.ch"),
#ifdef LOCALGROUPDISK
  localGroupDiskIdentifier(LOCALGROUPDISK),
#else
  localGroupDiskIdentifier(""),
#endif
#ifdef DQ2PATHHEAD
  dq2PathHead(DQ2PATHHEAD),
#else
  dq2PathHead(""),
#endif
#ifdef DCACHEPATHHEAD
  dCachePathHead(DCACHEPATHHEAD),
#else
  dCachePathHead(""),
#endif
  dq2cmd("dq2"),
  website("http://atlas-caf.web.cern.ch/"),
  appName("My CAFCore App"),
  procStatPath("/proc/self/stat"),
#ifdef PDFFONTEMBEDCMD
  pdfFontEmbedCommand(PDFFONTEMBEDCMD),
#else
  pdfFontEmbedCommand("mv $(filename) $(filename).bak && ( gs -q -dNOPAUSE -dBATCH -dPDFSETTINGS=/prepress -sDEVICE=pdfwrite -sOutputFile=$(filename) $(filename).bak && rm $(filename).bak ) || mv $(filename).bak $(filename)"),
#endif
  pdfFontEmbedEnabled(false),
#ifdef EXIFTOOLPATH
  exiftoolPath(EXIFTOOLPATH),
#else
  exiftoolPath(""),
#endif
  exiftoolEnabled(false),
#ifdef LIBXMLPATH
  libXMLpath(LIBXMLPATH)
#else
  libXMLpath(TQLibrary::findLibrary("libxml2*.so*"))
#endif
{
  this->timeOfConstruction = TQUtils::getCurrentTime();

  TTree::SetMaxTreeSize(1e15);

  char cCurrentPath[FILENAME_MAX];

  if (getcwd(cCurrentPath, sizeof(cCurrentPath)))
    this->workingDirectory = TString(cCurrentPath);

  if (this == &TQLibrary::gQFramework){
    DEBUG("The static member gQFramework is being created.");
    TQLibrary::isInitialized = true;
  }
  else{
    DEBUG("An instance of TQLibrary that is not the static member gQFramework is being created.");
  }

#ifdef PACKAGES
  for(auto pkg:PACKAGES){
		packages.push_back(pkg);
  }
#endif

#ifdef CONSOLEWIDTH
  this->setConsoleWidth(CONSOLEWIDTH);
#else
  this->findConsoleWidth();
#endif
}

TQLibrary::~TQLibrary(){
  // If snowflakeMode, check the number of printed messages. If they exceed
  // a threshold, break. A threshold can be set for warnings. The threshold
  // value for everything worse than that is 0.
  if (this->snowflakeMode){
    for (auto type = TQMessageStream::messageTypesAlert.begin(); type != TQMessageStream::messageTypesAlert.end(); type++){
      unsigned int messageCount = TQMessageStream::getGlobMessageCount(*type);
      if ((*type == TQMessageStream::WARNING) && (messageCount <= this->maxWarningsAllowed))
        continue;
      if (messageCount > 0){
        // Make sure that files are written before crashing
        if (TQPathManager::getPathManager())
          TQPathManager::getPathManager()->~TQPathManager();
        printGlobAlertMessageCount();
        BREAK("You are running in snowflake mode and the allowed number of alert messages was exceeded (have %d alert messages; allowed are %d alert messages).", messageCount, this->maxWarningsAllowed);
      }
    }
  }
  if (this == &TQLibrary::gQFramework){
    DEBUGclass("The static member gQFramework is being destroyed.");
    TQLibrary::isInitialized = false;
  }
  else{
    DEBUGclass("An instance of TQLibrary that is not the static member gQFramework is being destroyed.");
  }

}


const TString& TQLibrary::getLocalGroupDisk(){
  // retrieve the string identifying the local group disk
  // this is the local group disk identifier, i.e. something like
  // UNI-FREIBURG_LOCALGROUPDISK
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.localGroupDiskIdentifier;
}
void TQLibrary::setLocalGroupDisk(const TString& lcgid){
  // set the string identifying the local group disk
  // this is the local group disk identifier, i.e. something like
  // UNI-FREIBURG_LOCALGROUPDISK
  this->localGroupDiskIdentifier = lcgid;
}

const TString& TQLibrary::getDQ2PathHead(){
  // retrieve the DQ2 path head for the local storage
  // this is something like
  // srm://se.bfg.uni-freiburg.de
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.dq2PathHead;
}
void TQLibrary::setDQ2PathHead(const TString& dq2ph){
  // set the DQ2 path head for the local storage
  // this is something like
  // srm://se.bfg.uni-freiburg.de
  this->dq2PathHead = dq2ph;
}

const TString& TQLibrary::getdCachePathHead(){
  // retrieve the dCache path head for the local storage
  // this is something like
  // dcap://se.bfg.uni-freiburg.de:22125
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.dCachePathHead;
}
void TQLibrary::setdCachePathHead(const TString& dCache2ph){
  // set the dCache path head for the local storage
  // this is something like
  // dcap://se.bfg.uni-freiburg.de:22125
  this->dCachePathHead = dCache2ph;
}

const TString& TQLibrary::getDQ2cmd(){
  // retrieve the local DQ2 command
  // this usually either "dq2" or "rucio"
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.dq2cmd;
}
void TQLibrary::setDQ2cmd(const TString& dq2command){
  // set the local DQ2 command
  // this usually either "dq2" or "rucio"
  this->dq2cmd = dq2command;
}

TString TQLibrary::getEOScmd(){
  // retrieve the eos activation command
  // on CERN AFS and for the ATLAS EOS, this is
  // export EOS_MGM_URL=root://eosatlas.cern.ch; /afs/cern.ch/project/eos/installation/atlas/bin/eos
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return "export EOS_MGM_URL="+TQLibrary::gQFramework.eosmgmurl + "; " + TQLibrary::gQFramework.eoscmd;
}

void TQLibrary::setEOScmd(TString neweoscmd){
  // set the path to the eos binary
  // on CERN AFS, this is
  // /afs/cern.ch/project/eos/installation/atlas/bin/eos
  this->eoscmd = neweoscmd;
}

void TQLibrary::setEOSurl(TString neweosurl){
  // set the eos url, for example
  // root://eosuser.cern.ch for USER EOS
  // root://eosatlas.cern.ch for ATLAS EOS
  this->eosmgmurl = neweosurl;
}

void TQLibrary::printMessage(){
  // print an informational message
  // containing all important version numbers
  std::cout << "This is libQFramework rev. " << TQLibrary::getVersion() << ", compiled with root " << TQLibrary::getROOTVersion() << " and g++ " << TQLibrary::getGCCVersion() << std::endl;
  std::cout << "for bug reports, feature requests and general questions, please contact cburgard@cern.ch" << std::endl;
}

const TString& TQLibrary::getVersion(){
  // return the svn revision of the libQFramework
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.libversion;
}

const TString& TQLibrary::getROOTVersion(){
  // return the root version
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.rootversion;
}

const TString& TQLibrary::getGCCVersion(){
  // return the compiler version
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.gccversion;
}

int TQLibrary::getVersionNumber(){
  // return the svn revision of the libQFramework (numeric value);
  if (!TQLibrary::isInitialized) return 0;
  return atoi(TQLibrary::gQFramework.libversion);
}

float TQLibrary::getROOTVersionNumber(){
  // return the root version (numeric value)
  if (!TQLibrary::isInitialized) return 0;
  return atoi(TQLibrary::gQFramework.rootversion);
}

float TQLibrary::getGCCVersionNumber(){
  // return the compiler version (numeric value)
  if (!TQLibrary::isInitialized) return 0;
  return atoi(TQLibrary::gQFramework.gccversion);
}


int TQLibrary::redirect_stdout(const TString& fname, bool append){
  // redirect stdout to the file of the given name
  // if the file exists, it will be overwritten
  // if the file does not exist, it will be created
  if(!TQLibrary::stdoutfd_allowRedirection) return -1;
  if(TQLibrary::stdoutfd_isRedirected) return -2;
  if(TQLibrary::stdoutstr_isCaptured) return -3;
  fflush(stdout);
  int newstdout = append ? open(fname.Data(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) : open(fname.Data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  dup2(newstdout, fileno(stdout));
  close(newstdout);
  TQLibrary::stdoutfd_isRedirected = true;
  return fileno(stdout);
}

int TQLibrary::restore_stdout(){
  // if TQLibrary::redirect_stdout or TQLibrary::capture_stdout
  // was called previously this function will restore the
  // original output stream
  if (TQLibrary::stdoutfd_isRedirected){
    fflush(stdout);
    dup2(TQLibrary::stdoutfd, fileno(stdout));
    TQLibrary::stdoutfd_isRedirected = false;
    return TQLibrary::stdoutfd;
  }
  else if (TQLibrary::stdoutstr_isCaptured){
    if (TQLibrary::stdouterrstr_areCaptured){
      VERBOSE("Call TQLibrary::restore() to end capturing of stdout and stderr. Not restoring stdout.");
      return -2;
    }
    std::cout.rdbuf(TQLibrary::defaultStdoutStreamBuf);
    delete TQLibrary::capturingStdoutStream;
    TQLibrary::capturingStdoutStream = NULL;
    TQLibrary::stdoutstr_isCaptured = false;
    return 0;
  }
  return -1;
}

TString TQLibrary::readCapturedStdout(){
  if (!TQLibrary::stdoutstr_isCaptured) return "";
  return TQLibrary::capturingStdoutStream->str();
}

int TQLibrary::resetCapturedStdout(){
  if (!TQLibrary::stdoutstr_isCaptured) return -3;
  TQLibrary::capturingStdoutStream->str("");
  TQLibrary::capturingStdoutStream->clear();
  return 0;
}

TString TQLibrary::readAndResetCapturedStdout(){
  TString str = TQLibrary::readCapturedStdout();
  TQLibrary::resetCapturedStdout();
  return str;
}

TString TQLibrary::readCapturedStderr(){
  if (!TQLibrary::stderrstr_isCaptured) return "";
  return TQLibrary::capturingStderrStream->str();
}

int TQLibrary::resetCapturedStderr(){
  if (!TQLibrary::stderrstr_isCaptured) return -3;
  TQLibrary::capturingStderrStream->str("");
  TQLibrary::capturingStderrStream->clear();
  return 0;
}

TString TQLibrary::readAndResetCapturedStderr(){
  TString str = TQLibrary::readCapturedStderr();
  TQLibrary::resetCapturedStderr();
  return str;
}

TString TQLibrary::readCapturedStdoutStderr(){
  if (!TQLibrary::stdouterrstr_areCaptured) return "";
  return TQLibrary::capturingStdoutStderrStream->str();
}

int TQLibrary::resetCapturedStdoutStderr(){
  if (!TQLibrary::stdouterrstr_areCaptured) return -3;
  TQLibrary::capturingStdoutStderrStream->str("");
  TQLibrary::capturingStdoutStderrStream->clear();
  return 0;
}

TString TQLibrary::readAndResetCapturedStdoutStderr(){
  TString str = TQLibrary::readCapturedStdoutStderr();
  TQLibrary::resetCapturedStdoutStderr();
  return str;
}


int TQLibrary::redirect_stderr(const TString& fname, bool append){
  // redirect stderr to the file of the given name
  // if the file exists, it will be overwritten
  // if the file does not exist, it will be created
  if(!TQLibrary::stderrfd_allowRedirection) return -1;
  if(TQLibrary::stderrfd_isRedirected) return -2;
  if(TQLibrary::stderrstr_isCaptured) return -3;
  fflush(stderr);
  int newstderr = append ? open(fname.Data(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) : open(fname.Data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  dup2(newstderr, fileno(stderr));
  close(newstderr);
  TQLibrary::stderrfd_isRedirected = true;
  return newstderr;
}

int TQLibrary::restore_stderr(){
  // if TQLibrary::redirect_stderr or TQLibrary::capture_stderr
  // was called previously this function will restore the
  // original output stream
  if(TQLibrary::stderrfd_isRedirected){
    fflush(stderr);
    dup2(TQLibrary::stderrfd, fileno(stderr));
    TQLibrary::stderrfd_isRedirected = false;
    return TQLibrary::stderrfd;
  }
  else if (TQLibrary::stderrstr_isCaptured){
    if (TQLibrary::stdouterrstr_areCaptured){
      VERBOSE("Call TQLibrary::restore() to end capturing of stdout and stderr. Not restoring stderr.");
      return -2;
    }
    std::cerr.rdbuf(TQLibrary::defaultStderrStreamBuf);
    delete TQLibrary::capturingStderrStream;
    TQLibrary::capturingStderrStream = NULL;
    TQLibrary::stderrstr_isCaptured = false;
    return 0;
  }
  return -1;
}

int TQLibrary::captureStdout(){
  // Don't print stdout, but instead store it in
  // TQLibrary::capturingStdoutStream. The stored string
  // can be read using TQLibrary::readCapturedStdout().
  // Use TQLibrary::restore_stdout() to stop capturing.
  if(!TQLibrary::stdoutstr_allowCapturing) return -1;
  if(TQLibrary::stdoutfd_isRedirected) return -2;
  if(TQLibrary::stdoutstr_isCaptured) return -3;
  TQLibrary::capturingStdoutStream = new std::stringstream();
  std::cout.flush();
  TQLibrary::defaultStdoutStreamBuf = std::cout.rdbuf();
  std::cout.rdbuf(TQLibrary::capturingStdoutStream->rdbuf());
  TQLibrary::stdoutstr_isCaptured = true;
  return 0;
}

int TQLibrary::captureStderr(){
  // Don't print stderr, but instead store it in
  // TQLibrary::capturingStderrStream. The stored string
  // can be read using TQLibrary::readCapturedStderr().
  // Use TQLibrary::restore_stderr() to stop capturing.
  if(!TQLibrary::stderrstr_allowCapturing) return -1;
  if(TQLibrary::stderrfd_isRedirected) return -2;
  if(TQLibrary::stderrstr_isCaptured) return -3;
  TQLibrary::capturingStderrStream = new std::stringstream();
  std::cerr.flush();
  TQLibrary::defaultStderrStreamBuf = std::cerr.rdbuf();
  std::cerr.rdbuf(TQLibrary::capturingStderrStream->rdbuf());
  TQLibrary::stderrstr_isCaptured = true;
  return 0;
}

int TQLibrary::captureStdoutStderr(){
  // Captures both stdout and stderr and writes them to the same
  // stream.

  if ((!TQLibrary::stdoutstr_allowCapturing) or
      (!TQLibrary::stderrstr_allowCapturing))
    return -1;
  if ((TQLibrary::stdoutfd_isRedirected) or
      (TQLibrary::stderrfd_isRedirected))
    return -2;
  if ((TQLibrary::stdoutstr_isCaptured) or
      (TQLibrary::stderrstr_isCaptured))
    return -3;
  TQLibrary::capturingStdoutStderrStream = new std::stringstream();
  std::cout.flush();
  std::cerr.flush();
  TQLibrary::defaultStdoutStreamBuf = std::cout.rdbuf();
  TQLibrary::defaultStderrStreamBuf = std::cerr.rdbuf();
  std::cout.rdbuf(TQLibrary::capturingStdoutStderrStream->rdbuf());
  std::cerr.rdbuf(TQLibrary::capturingStdoutStderrStream->rdbuf());
  TQLibrary::stdoutstr_isCaptured = true;
  TQLibrary::stderrstr_isCaptured = true;
  TQLibrary::stdouterrstr_areCaptured = true;
  return 0;
}

void TQLibrary::allowRedirection_stdout(bool allow){
  if (TQLibrary::stdouterrstr_areCaptured)
    TQLibrary::restore();
  else
    TQLibrary::restore_stdout();
  TQLibrary::stdoutfd_allowRedirection = allow;
}
void TQLibrary::allowRedirection_stderr(bool allow){
  if (TQLibrary::stdouterrstr_areCaptured)
    TQLibrary::restore();
  else
    TQLibrary::restore_stderr();
  TQLibrary::stderrfd_allowRedirection = allow;
}
void TQLibrary::allowRedirection(bool allow){
  TQLibrary::restore();
  TQLibrary::stdoutfd_allowRedirection = allow;
  TQLibrary::stderrfd_allowRedirection = allow;
}

void TQLibrary::allowCapturing_stdout(bool allow){
  if (TQLibrary::stdouterrstr_areCaptured)
    TQLibrary::restore();
  else
    TQLibrary::restore_stdout();
  TQLibrary::stdoutstr_allowCapturing = allow;
}
void TQLibrary::allowCapturing_stderr(bool allow){
  if (TQLibrary::stdouterrstr_areCaptured)
    TQLibrary::restore();
  else
    TQLibrary::restore_stderr();
  TQLibrary::stderrstr_allowCapturing = allow;
}
void TQLibrary::allowCapturing(bool allow){
  TQLibrary::restore();
  TQLibrary::stdoutstr_allowCapturing = allow;
  TQLibrary::stderrstr_allowCapturing = allow;
}

int TQLibrary::redirect(const TString& fname, bool append){
  // redirect stdout and stderr to the file of the given name
  // if the file exists, it will be overwritten
  // if the file does not exist, it will be created
  if(!TQLibrary::stdoutfd_allowRedirection || !TQLibrary::stderrfd_allowRedirection) return -1;
  if(TQLibrary::stdoutfd_isRedirected || TQLibrary::stderrfd_isRedirected) return -2;
  fflush(stdout);
  fflush(stderr);
  int newstdeo = append ? open(fname.Data(), O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) : open(fname.Data(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
  dup2(newstdeo, fileno(stdout));
  dup2(newstdeo, fileno(stderr));
  close(newstdeo);
  TQLibrary::stdoutfd_isRedirected = true;
  TQLibrary::stderrfd_isRedirected = true;
  return newstdeo;
}

bool TQLibrary::restore(){
  // if TQLibrary::redirect_stdout was called previously
  // this function will restore the original output stream
  if (!TQLibrary::stdouterrstr_areCaptured){
    TQLibrary::restore_stderr();
    TQLibrary::restore_stdout();
  }
  else{
    std::cout.rdbuf(TQLibrary::defaultStdoutStreamBuf);
    std::cerr.rdbuf(TQLibrary::defaultStderrStreamBuf);
    delete TQLibrary::capturingStdoutStderrStream;
    TQLibrary::capturingStdoutStderrStream = NULL;
    TQLibrary::stdoutstr_isCaptured = false;
    TQLibrary::stderrstr_isCaptured = false;
    TQLibrary::stdouterrstr_areCaptured = false;
  }
  return true;
}

Long64_t TQLibrary::getVirtualMemory(){
	try {
		std::string line;
		std::ifstream myfile (TQLibrary::getProcStatPath().Data());
		if (myfile.is_open()){
			std::string pid, comm, state, ppid, pgrp, session, tty_nr;
			std::string tpgid, flags, minflt, cminflt, majflt, cmajflt;
			std::string utime, stime, cutime, cstime, priority, nice;
			std::string O, itrealvalue, starttime;
			Long64_t vsize;
			Long64_t rss;
			if( myfile.good() ){
				myfile >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
							 >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
							 >> utime >> stime >> cutime >> cstime >> priority >> nice
							 >> O >> itrealvalue >> starttime >> vsize >> rss;
			}
			myfile.close();
			return vsize;
		}
	} catch (const std::bad_alloc& oom){
		// do nothing
	}
	return -1;
}

void TQLibrary::printMemory(){
  // print the current memory usage of the code
	Long64_t vsize = getVirtualMemory();
	if(vsize>0){
		std::cout << TQLibrary::getApplicationName() <<": virtual memory used = " << TQStringUtils::fixedWidth(TQStringUtils::getThousandsSeparators(vsize,"'"),20) << std::endl;
	} else {
		std::cout << "Unable to open file" << std::endl;
	}
}

void TQLibrary::recordMemory(short color) {
  if (!TQLibrary::isInitialized) return;
  try {
    TQLibrary::gQFramework.rssUsageTimestamps.push_back(TQUtils::getCurrentTime());
    TQLibrary::gQFramework.rssUsageMemory.push_back(TQUtils::getCurrentRSS());
    TQLibrary::gQFramework.rssUsageColors.push_back(color);
  } catch (const std::bad_alloc& oom){
    // do nothing
  }
  return;
}

TMultiGraph* TQLibrary::getMemoryGraph(bool differential) {
  // returns a TGraph recording the memory usage over time
  if (!TQLibrary::isInitialized) return NULL;

  std::vector<double>timestamps(TQLibrary::gQFramework.rssUsageTimestamps.begin(),TQLibrary::gQFramework.rssUsageTimestamps.end());
  std::vector<double>memory(TQLibrary::gQFramework.rssUsageMemory.begin(),TQLibrary::gQFramework.rssUsageMemory.end());


  //if (dTimestamps.size() != dMemory.size() || dMemory.size()==0) return nullptr;
  if (differential) {
    std::vector<double> deltaMemory;
    deltaMemory.reserve(memory.size());
    for (size_t i=0; i<memory.size(); ++i) {
      if (i==0) {
        deltaMemory.push_back(0.);
      } else {
        deltaMemory.push_back(memory[i]-memory[i-1]);
      }
    }
    return TQHistogramUtils::makeMultiColorGraph(timestamps, deltaMemory, TQLibrary::gQFramework.rssUsageColors);
  }

  return TQHistogramUtils::makeMultiColorGraph(timestamps, memory, TQLibrary::gQFramework.rssUsageColors);

  //new TGraph(dTimestamps.size(),&dTimestamps[0],&dMemory[0]);
}

const TString& TQLibrary::getProcStatPath(){
  // retrieve the path to the file/device providing process information
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.procStatPath;
}

void TQLibrary::setProcStatPath(TString newpath){
  // set the path to the file/device providing process information
  this->procStatPath = newpath;
}

const TString& TQLibrary::getEXIFtoolPath(){
  // retrieve the path of the EXIFtool binary
  // which allows modifying PDF meta-information
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.exiftoolPath;
}

void TQLibrary::setEXIFtoolPath(TString newpath){
  // set the path of the EXIFtool binary
  // which allows modifying PDF meta-information
  this->exiftoolPath = newpath;
}

bool TQLibrary::hasEXIFsupport(){
  // return true if TQLibrary is configured for EXIF support
  // return false otherwise
  return TQLibrary::isInitialized &&gQFramework.exiftoolEnabled && !(gQFramework.exiftoolPath.IsNull());
}

bool TQLibrary::enableEXIFsupport(bool val){
  // enable support of EXIFtool
  // this requires a valid EXIFtool path to be set
  if (!TQLibrary::isInitialized) return false;
  if(TQLibrary::gQFramework.exiftoolPath.IsNull()) return false;
  TQLibrary::gQFramework.exiftoolEnabled = val;
  return true;
}

bool TQLibrary::setEXIF(const TString& fname, const TString& title, const TString& keywords){
  // use the EXIFtool to set the title and keywords metainformation on some PDF
  if(title.IsNull() || keywords.IsNull()) return false;
  if(!TQLibrary::hasEXIFsupport()) return false;
  system(TQLibrary::getEXIFtoolPath() + " -Author=\"$(whoami)\" -Title=\""+title+"\" -Keywords=\""+keywords+"\" -Creator\"="+TQLibrary::getApplicationName()+" with libQFramework rev. "+TQLibrary::getVersion()+" (ROOT "+TQLibrary::getROOTVersion() + ", g++ " + TQLibrary::getGCCVersion() + ")\" " + fname);
  return true;
}


const TString& TQLibrary::getPDFfontEmbedCommand(){
  // retrieve the command used to embed fonts in PDF files
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.pdfFontEmbedCommand;
}

void TQLibrary::setPDFfontEmbedCommand(TString cmd){
  // set the command used to embed fonts in PDF files
  this->pdfFontEmbedCommand = cmd;
}

bool TQLibrary::hasPDFfontEmbedding(){
  // return true if TQLibrary is configured to perfrom font embedding in PDFs
  // return false otherwise
  return TQLibrary::isInitialized && gQFramework.pdfFontEmbedEnabled && !(gQFramework.pdfFontEmbedCommand.IsNull());
}

bool TQLibrary::enablePDFfontEmbedding(bool val){
  // enable font embedding in PDFs
  // this requires pdfFonntEmbedCommand to be set
  if (!TQLibrary::isInitialized) return false;
  if(TQLibrary::gQFramework.pdfFontEmbedCommand.IsNull()) return false;
  TQLibrary::gQFramework.pdfFontEmbedEnabled = val;
  return true;
}

bool TQLibrary::embedFonts(const TString& filename, bool verbose){
  // embed fonts in some PDF file
  // if verbose, print the command output
  if(!TQLibrary::hasPDFfontEmbedding()) return false;
  TString cmd(TQLibrary::getPDFfontEmbedCommand());
  cmd.ReplaceAll("$(filename)",filename);
  TList* result = TQUtils::execute(cmd);
  if(!result) return false;
  if(verbose && (result->GetEntries() > 0)){
    msgStream.sendFunctionMessage(TQMessageStream::VERBOSE,__FUNCTION__,"embedding fonts for file %s",filename.Data());
    TQIterator itr(result);
    while(itr.hasNext()){
      TObject* obj = itr.readNext();
      msgStream.sendFunctionMessage(TQMessageStream::VERBOSE,__FUNCTION__,obj->GetName());
    }
  }
  delete result;
  return true;
}

const TString& TQLibrary::getApplicationName(){
  // get the name of this application
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.appName;
}

void TQLibrary::setApplicationName(TString newname){
  // set the name of this application
  this->appName = newname;
}

TString TQLibrary::getAbsolutePath(const TString& path){
  // retrieve the absolute path to some local path inside the working directory
  if(path.IsNull()) return TQLibrary::getWorkingDirectory();
  if(path[0]=='/') return path;
  return TQFolder::concatPaths(TQLibrary::getWorkingDirectory(),path);
}
const TString& TQLibrary::getWorkingDirectory(){
  // retrieve the current working directory
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.workingDirectory;
}
void TQLibrary::setWorkingDirectory(TString newpath){
  // set the current working directory
  this->workingDirectory = newpath;
}
const TString& TQLibrary::pwd(){
  // retrieve the current working directory
  // same as getWorkingDirectory
  return TQLibrary::getWorkingDirectory();
}
void TQLibrary::cd(TString newpath){
  // change the current working directory
  // same as setWorkingDirectory
  this->workingDirectory = newpath;
}

const TString& TQLibrary::getTQPATH(){
  // get the TQPATH
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.tqpath;
}
void TQLibrary::setTQPATH(TString newpath){
  // set the TQPATH
  this->tqpath = newpath;
}

const TString& TQLibrary::getlibXMLpath(){
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.libXMLpath;
}

const TString& TQLibrary::getWebsite(){
  // retrieve the URL of the documentation website
  if (!TQLibrary::isInitialized) return TQStringUtils::emptyString;
  return TQLibrary::gQFramework.website;
}


void TQLibrary::setMessageStream(std::ostream& os, bool allowColors){
  // set the message output stream
  TQLibrary::msgStream.absorb(TQMessageStream(os,false,allowColors));
}

void TQLibrary::setMessageStream(std::ostream* os, bool allowColors){
  // set the message output stream
  TQLibrary::msgStream.absorb(TQMessageStream(os,false,allowColors));
}

bool TQLibrary::openLogFile(const TString& fname, bool allowColors){
  // open a log file at the given location
  INFOfunc(TQUtils::getTimeStamp()+ " - attempting to use log file '%s'",fname.Data());
  TQLibrary::msgStream.absorb(TQMessageStream(fname,allowColors));
  if(msgStream.isGood()){
    INFOfunc(TQUtils::getTimeStamp()+ " - successfully opened log file for writing");
  } else {
    ERRORfunc(TQUtils::getTimeStamp()+ " - failed to open log file for writing");
  }
  return true;
}

bool TQLibrary::closeLogFile(){
  // close the currently opened log file and redirect logging to std::cout
  // the same effect can be accomplished by calling TQLibrary::setMessageStream(std::cout)
  INFOfunc(TQUtils::getTimeStamp()+ " - closing log");
  TQLibrary::setMessageStream(std::cout,true);
  INFOfunc(TQUtils::getTimeStamp()+ " - closed log file");
  return true;
}

int TQLibrary::getConsoleWidth(){
  // get the currently set console width
  return TQLibrary::gQFramework.consoleWidth;
}

void TQLibrary::setConsoleWidth(int width){
  // set the global console width
  TQLibrary::gQFramework.consoleWidth = width;
}

void TQLibrary::findConsoleWidth(){
  // recalculate the console width from the kernel
  struct winsize w;
  ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
  this->consoleWidth = std::max(std::min((int)(w.ws_col),(int)300),40);
}


TString TQLibrary::findLibrary(const TString& filename){
  // find the path of some library
  TString retval = "";
  TList* paths = TQUtils::execute("find $(g++ --print-search-dirs | grep libraries | sed -e 's/^[ ]*libraries:[ ]*=//' -e 's/:/ /g') -name '"+filename+".*so' 2>/dev/null -print -quit",255);
  paths->SetOwner(true);
  if(!paths) return retval;
  if(paths->GetEntries() > 0){
    retval = paths->First()->GetName();
  }
  delete paths;
  return retval;
}

bool TQLibrary::hasPackage(const char* pkgname){
	// check if a given package was known at build time
	for(const auto& pkg:TQLibrary::getQLibrary()->packages){
		if(TQStringUtils::equal(pkgname,pkg)) return true;
	}
	return false;
}

std::vector<std::string> TQLibrary::getListOfPackages() {
  std::vector<std::string> pks;
  for (std::string p : TQLibrary::getQLibrary()->packages) {
    pks.push_back(p);
  }
  return pks;
}

void TQLibrary::printGlobMessageCount(){
  TQMessageStream::printGlobMessageCount();
}

void TQLibrary::printGlobAlertMessageCount(){
  TQMessageStream::printGlobAlertMessageCount();
}

void TQLibrary::setSnowflakeMode(bool snowflakeMode, unsigned int maxWarningsAllowed){
  this->snowflakeMode = snowflakeMode;
  this->maxWarningsAllowed = maxWarningsAllowed;
}

bool TQLibrary::getSnowflakeMode(){
  return this->snowflakeMode;
}

unsigned long TQLibrary::getTimeOfConstruction(){
  return this->timeOfConstruction;
}

unsigned long TQLibrary::getTimeSinceConstruction(){
  return TQUtils::getCurrentTime() - this->timeOfConstruction;
}
 TQLibrary.cxx:1
 TQLibrary.cxx:2
 TQLibrary.cxx:3
 TQLibrary.cxx:4
 TQLibrary.cxx:5
 TQLibrary.cxx:6
 TQLibrary.cxx:7
 TQLibrary.cxx:8
 TQLibrary.cxx:9
 TQLibrary.cxx:10
 TQLibrary.cxx:11
 TQLibrary.cxx:12
 TQLibrary.cxx:13
 TQLibrary.cxx:14
 TQLibrary.cxx:15
 TQLibrary.cxx:16
 TQLibrary.cxx:17
 TQLibrary.cxx:18
 TQLibrary.cxx:19
 TQLibrary.cxx:20
 TQLibrary.cxx:21
 TQLibrary.cxx:22
 TQLibrary.cxx:23
 TQLibrary.cxx:24
 TQLibrary.cxx:25
 TQLibrary.cxx:26
 TQLibrary.cxx:27
 TQLibrary.cxx:28
 TQLibrary.cxx:29
 TQLibrary.cxx:30
 TQLibrary.cxx:31
 TQLibrary.cxx:32
 TQLibrary.cxx:33
 TQLibrary.cxx:34
 TQLibrary.cxx:35
 TQLibrary.cxx:36
 TQLibrary.cxx:37
 TQLibrary.cxx:38
 TQLibrary.cxx:39
 TQLibrary.cxx:40
 TQLibrary.cxx:41
 TQLibrary.cxx:42
 TQLibrary.cxx:43
 TQLibrary.cxx:44
 TQLibrary.cxx:45
 TQLibrary.cxx:46
 TQLibrary.cxx:47
 TQLibrary.cxx:48
 TQLibrary.cxx:49
 TQLibrary.cxx:50
 TQLibrary.cxx:51
 TQLibrary.cxx:52
 TQLibrary.cxx:53
 TQLibrary.cxx:54
 TQLibrary.cxx:55
 TQLibrary.cxx:56
 TQLibrary.cxx:57
 TQLibrary.cxx:58
 TQLibrary.cxx:59
 TQLibrary.cxx:60
 TQLibrary.cxx:61
 TQLibrary.cxx:62
 TQLibrary.cxx:63
 TQLibrary.cxx:64
 TQLibrary.cxx:65
 TQLibrary.cxx:66
 TQLibrary.cxx:67
 TQLibrary.cxx:68
 TQLibrary.cxx:69
 TQLibrary.cxx:70
 TQLibrary.cxx:71
 TQLibrary.cxx:72
 TQLibrary.cxx:73
 TQLibrary.cxx:74
 TQLibrary.cxx:75
 TQLibrary.cxx:76
 TQLibrary.cxx:77
 TQLibrary.cxx:78
 TQLibrary.cxx:79
 TQLibrary.cxx:80
 TQLibrary.cxx:81
 TQLibrary.cxx:82
 TQLibrary.cxx:83
 TQLibrary.cxx:84
 TQLibrary.cxx:85
 TQLibrary.cxx:86
 TQLibrary.cxx:87
 TQLibrary.cxx:88
 TQLibrary.cxx:89
 TQLibrary.cxx:90
 TQLibrary.cxx:91
 TQLibrary.cxx:92
 TQLibrary.cxx:93
 TQLibrary.cxx:94
 TQLibrary.cxx:95
 TQLibrary.cxx:96
 TQLibrary.cxx:97
 TQLibrary.cxx:98
 TQLibrary.cxx:99
 TQLibrary.cxx:100
 TQLibrary.cxx:101
 TQLibrary.cxx:102
 TQLibrary.cxx:103
 TQLibrary.cxx:104
 TQLibrary.cxx:105
 TQLibrary.cxx:106
 TQLibrary.cxx:107
 TQLibrary.cxx:108
 TQLibrary.cxx:109
 TQLibrary.cxx:110
 TQLibrary.cxx:111
 TQLibrary.cxx:112
 TQLibrary.cxx:113
 TQLibrary.cxx:114
 TQLibrary.cxx:115
 TQLibrary.cxx:116
 TQLibrary.cxx:117
 TQLibrary.cxx:118
 TQLibrary.cxx:119
 TQLibrary.cxx:120
 TQLibrary.cxx:121
 TQLibrary.cxx:122
 TQLibrary.cxx:123
 TQLibrary.cxx:124
 TQLibrary.cxx:125
 TQLibrary.cxx:126
 TQLibrary.cxx:127
 TQLibrary.cxx:128
 TQLibrary.cxx:129
 TQLibrary.cxx:130
 TQLibrary.cxx:131
 TQLibrary.cxx:132
 TQLibrary.cxx:133
 TQLibrary.cxx:134
 TQLibrary.cxx:135
 TQLibrary.cxx:136
 TQLibrary.cxx:137
 TQLibrary.cxx:138
 TQLibrary.cxx:139
 TQLibrary.cxx:140
 TQLibrary.cxx:141
 TQLibrary.cxx:142
 TQLibrary.cxx:143
 TQLibrary.cxx:144
 TQLibrary.cxx:145
 TQLibrary.cxx:146
 TQLibrary.cxx:147
 TQLibrary.cxx:148
 TQLibrary.cxx:149
 TQLibrary.cxx:150
 TQLibrary.cxx:151
 TQLibrary.cxx:152
 TQLibrary.cxx:153
 TQLibrary.cxx:154
 TQLibrary.cxx:155
 TQLibrary.cxx:156
 TQLibrary.cxx:157
 TQLibrary.cxx:158
 TQLibrary.cxx:159
 TQLibrary.cxx:160
 TQLibrary.cxx:161
 TQLibrary.cxx:162
 TQLibrary.cxx:163
 TQLibrary.cxx:164
 TQLibrary.cxx:165
 TQLibrary.cxx:166
 TQLibrary.cxx:167
 TQLibrary.cxx:168
 TQLibrary.cxx:169
 TQLibrary.cxx:170
 TQLibrary.cxx:171
 TQLibrary.cxx:172
 TQLibrary.cxx:173
 TQLibrary.cxx:174
 TQLibrary.cxx:175
 TQLibrary.cxx:176
 TQLibrary.cxx:177
 TQLibrary.cxx:178
 TQLibrary.cxx:179
 TQLibrary.cxx:180
 TQLibrary.cxx:181
 TQLibrary.cxx:182
 TQLibrary.cxx:183
 TQLibrary.cxx:184
 TQLibrary.cxx:185
 TQLibrary.cxx:186
 TQLibrary.cxx:187
 TQLibrary.cxx:188
 TQLibrary.cxx:189
 TQLibrary.cxx:190
 TQLibrary.cxx:191
 TQLibrary.cxx:192
 TQLibrary.cxx:193
 TQLibrary.cxx:194
 TQLibrary.cxx:195
 TQLibrary.cxx:196
 TQLibrary.cxx:197
 TQLibrary.cxx:198
 TQLibrary.cxx:199
 TQLibrary.cxx:200
 TQLibrary.cxx:201
 TQLibrary.cxx:202
 TQLibrary.cxx:203
 TQLibrary.cxx:204
 TQLibrary.cxx:205
 TQLibrary.cxx:206
 TQLibrary.cxx:207
 TQLibrary.cxx:208
 TQLibrary.cxx:209
 TQLibrary.cxx:210
 TQLibrary.cxx:211
 TQLibrary.cxx:212
 TQLibrary.cxx:213
 TQLibrary.cxx:214
 TQLibrary.cxx:215
 TQLibrary.cxx:216
 TQLibrary.cxx:217
 TQLibrary.cxx:218
 TQLibrary.cxx:219
 TQLibrary.cxx:220
 TQLibrary.cxx:221
 TQLibrary.cxx:222
 TQLibrary.cxx:223
 TQLibrary.cxx:224
 TQLibrary.cxx:225
 TQLibrary.cxx:226
 TQLibrary.cxx:227
 TQLibrary.cxx:228
 TQLibrary.cxx:229
 TQLibrary.cxx:230
 TQLibrary.cxx:231
 TQLibrary.cxx:232
 TQLibrary.cxx:233
 TQLibrary.cxx:234
 TQLibrary.cxx:235
 TQLibrary.cxx:236
 TQLibrary.cxx:237
 TQLibrary.cxx:238
 TQLibrary.cxx:239
 TQLibrary.cxx:240
 TQLibrary.cxx:241
 TQLibrary.cxx:242
 TQLibrary.cxx:243
 TQLibrary.cxx:244
 TQLibrary.cxx:245
 TQLibrary.cxx:246
 TQLibrary.cxx:247
 TQLibrary.cxx:248
 TQLibrary.cxx:249
 TQLibrary.cxx:250
 TQLibrary.cxx:251
 TQLibrary.cxx:252
 TQLibrary.cxx:253
 TQLibrary.cxx:254
 TQLibrary.cxx:255
 TQLibrary.cxx:256
 TQLibrary.cxx:257
 TQLibrary.cxx:258
 TQLibrary.cxx:259
 TQLibrary.cxx:260
 TQLibrary.cxx:261
 TQLibrary.cxx:262
 TQLibrary.cxx:263
 TQLibrary.cxx:264
 TQLibrary.cxx:265
 TQLibrary.cxx:266
 TQLibrary.cxx:267
 TQLibrary.cxx:268
 TQLibrary.cxx:269
 TQLibrary.cxx:270
 TQLibrary.cxx:271
 TQLibrary.cxx:272
 TQLibrary.cxx:273
 TQLibrary.cxx:274
 TQLibrary.cxx:275
 TQLibrary.cxx:276
 TQLibrary.cxx:277
 TQLibrary.cxx:278
 TQLibrary.cxx:279
 TQLibrary.cxx:280
 TQLibrary.cxx:281
 TQLibrary.cxx:282
 TQLibrary.cxx:283
 TQLibrary.cxx:284
 TQLibrary.cxx:285
 TQLibrary.cxx:286
 TQLibrary.cxx:287
 TQLibrary.cxx:288
 TQLibrary.cxx:289
 TQLibrary.cxx:290
 TQLibrary.cxx:291
 TQLibrary.cxx:292
 TQLibrary.cxx:293
 TQLibrary.cxx:294
 TQLibrary.cxx:295
 TQLibrary.cxx:296
 TQLibrary.cxx:297
 TQLibrary.cxx:298
 TQLibrary.cxx:299
 TQLibrary.cxx:300
 TQLibrary.cxx:301
 TQLibrary.cxx:302
 TQLibrary.cxx:303
 TQLibrary.cxx:304
 TQLibrary.cxx:305
 TQLibrary.cxx:306
 TQLibrary.cxx:307
 TQLibrary.cxx:308
 TQLibrary.cxx:309
 TQLibrary.cxx:310
 TQLibrary.cxx:311
 TQLibrary.cxx:312
 TQLibrary.cxx:313
 TQLibrary.cxx:314
 TQLibrary.cxx:315
 TQLibrary.cxx:316
 TQLibrary.cxx:317
 TQLibrary.cxx:318
 TQLibrary.cxx:319
 TQLibrary.cxx:320
 TQLibrary.cxx:321
 TQLibrary.cxx:322
 TQLibrary.cxx:323
 TQLibrary.cxx:324
 TQLibrary.cxx:325
 TQLibrary.cxx:326
 TQLibrary.cxx:327
 TQLibrary.cxx:328
 TQLibrary.cxx:329
 TQLibrary.cxx:330
 TQLibrary.cxx:331
 TQLibrary.cxx:332
 TQLibrary.cxx:333
 TQLibrary.cxx:334
 TQLibrary.cxx:335
 TQLibrary.cxx:336
 TQLibrary.cxx:337
 TQLibrary.cxx:338
 TQLibrary.cxx:339
 TQLibrary.cxx:340
 TQLibrary.cxx:341
 TQLibrary.cxx:342
 TQLibrary.cxx:343
 TQLibrary.cxx:344
 TQLibrary.cxx:345
 TQLibrary.cxx:346
 TQLibrary.cxx:347
 TQLibrary.cxx:348
 TQLibrary.cxx:349
 TQLibrary.cxx:350
 TQLibrary.cxx:351
 TQLibrary.cxx:352
 TQLibrary.cxx:353
 TQLibrary.cxx:354
 TQLibrary.cxx:355
 TQLibrary.cxx:356
 TQLibrary.cxx:357
 TQLibrary.cxx:358
 TQLibrary.cxx:359
 TQLibrary.cxx:360
 TQLibrary.cxx:361
 TQLibrary.cxx:362
 TQLibrary.cxx:363
 TQLibrary.cxx:364
 TQLibrary.cxx:365
 TQLibrary.cxx:366
 TQLibrary.cxx:367
 TQLibrary.cxx:368
 TQLibrary.cxx:369
 TQLibrary.cxx:370
 TQLibrary.cxx:371
 TQLibrary.cxx:372
 TQLibrary.cxx:373
 TQLibrary.cxx:374
 TQLibrary.cxx:375
 TQLibrary.cxx:376
 TQLibrary.cxx:377
 TQLibrary.cxx:378
 TQLibrary.cxx:379
 TQLibrary.cxx:380
 TQLibrary.cxx:381
 TQLibrary.cxx:382
 TQLibrary.cxx:383
 TQLibrary.cxx:384
 TQLibrary.cxx:385
 TQLibrary.cxx:386
 TQLibrary.cxx:387
 TQLibrary.cxx:388
 TQLibrary.cxx:389
 TQLibrary.cxx:390
 TQLibrary.cxx:391
 TQLibrary.cxx:392
 TQLibrary.cxx:393
 TQLibrary.cxx:394
 TQLibrary.cxx:395
 TQLibrary.cxx:396
 TQLibrary.cxx:397
 TQLibrary.cxx:398
 TQLibrary.cxx:399
 TQLibrary.cxx:400
 TQLibrary.cxx:401
 TQLibrary.cxx:402
 TQLibrary.cxx:403
 TQLibrary.cxx:404
 TQLibrary.cxx:405
 TQLibrary.cxx:406
 TQLibrary.cxx:407
 TQLibrary.cxx:408
 TQLibrary.cxx:409
 TQLibrary.cxx:410
 TQLibrary.cxx:411
 TQLibrary.cxx:412
 TQLibrary.cxx:413
 TQLibrary.cxx:414
 TQLibrary.cxx:415
 TQLibrary.cxx:416
 TQLibrary.cxx:417
 TQLibrary.cxx:418
 TQLibrary.cxx:419
 TQLibrary.cxx:420
 TQLibrary.cxx:421
 TQLibrary.cxx:422
 TQLibrary.cxx:423
 TQLibrary.cxx:424
 TQLibrary.cxx:425
 TQLibrary.cxx:426
 TQLibrary.cxx:427
 TQLibrary.cxx:428
 TQLibrary.cxx:429
 TQLibrary.cxx:430
 TQLibrary.cxx:431
 TQLibrary.cxx:432
 TQLibrary.cxx:433
 TQLibrary.cxx:434
 TQLibrary.cxx:435
 TQLibrary.cxx:436
 TQLibrary.cxx:437
 TQLibrary.cxx:438
 TQLibrary.cxx:439
 TQLibrary.cxx:440
 TQLibrary.cxx:441
 TQLibrary.cxx:442
 TQLibrary.cxx:443
 TQLibrary.cxx:444
 TQLibrary.cxx:445
 TQLibrary.cxx:446
 TQLibrary.cxx:447
 TQLibrary.cxx:448
 TQLibrary.cxx:449
 TQLibrary.cxx:450
 TQLibrary.cxx:451
 TQLibrary.cxx:452
 TQLibrary.cxx:453
 TQLibrary.cxx:454
 TQLibrary.cxx:455
 TQLibrary.cxx:456
 TQLibrary.cxx:457
 TQLibrary.cxx:458
 TQLibrary.cxx:459
 TQLibrary.cxx:460
 TQLibrary.cxx:461
 TQLibrary.cxx:462
 TQLibrary.cxx:463
 TQLibrary.cxx:464
 TQLibrary.cxx:465
 TQLibrary.cxx:466
 TQLibrary.cxx:467
 TQLibrary.cxx:468
 TQLibrary.cxx:469
 TQLibrary.cxx:470
 TQLibrary.cxx:471
 TQLibrary.cxx:472
 TQLibrary.cxx:473
 TQLibrary.cxx:474
 TQLibrary.cxx:475
 TQLibrary.cxx:476
 TQLibrary.cxx:477
 TQLibrary.cxx:478
 TQLibrary.cxx:479
 TQLibrary.cxx:480
 TQLibrary.cxx:481
 TQLibrary.cxx:482
 TQLibrary.cxx:483
 TQLibrary.cxx:484
 TQLibrary.cxx:485
 TQLibrary.cxx:486
 TQLibrary.cxx:487
 TQLibrary.cxx:488
 TQLibrary.cxx:489
 TQLibrary.cxx:490
 TQLibrary.cxx:491
 TQLibrary.cxx:492
 TQLibrary.cxx:493
 TQLibrary.cxx:494
 TQLibrary.cxx:495
 TQLibrary.cxx:496
 TQLibrary.cxx:497
 TQLibrary.cxx:498
 TQLibrary.cxx:499
 TQLibrary.cxx:500
 TQLibrary.cxx:501
 TQLibrary.cxx:502
 TQLibrary.cxx:503
 TQLibrary.cxx:504
 TQLibrary.cxx:505
 TQLibrary.cxx:506
 TQLibrary.cxx:507
 TQLibrary.cxx:508
 TQLibrary.cxx:509
 TQLibrary.cxx:510
 TQLibrary.cxx:511
 TQLibrary.cxx:512
 TQLibrary.cxx:513
 TQLibrary.cxx:514
 TQLibrary.cxx:515
 TQLibrary.cxx:516
 TQLibrary.cxx:517
 TQLibrary.cxx:518
 TQLibrary.cxx:519
 TQLibrary.cxx:520
 TQLibrary.cxx:521
 TQLibrary.cxx:522
 TQLibrary.cxx:523
 TQLibrary.cxx:524
 TQLibrary.cxx:525
 TQLibrary.cxx:526
 TQLibrary.cxx:527
 TQLibrary.cxx:528
 TQLibrary.cxx:529
 TQLibrary.cxx:530
 TQLibrary.cxx:531
 TQLibrary.cxx:532
 TQLibrary.cxx:533
 TQLibrary.cxx:534
 TQLibrary.cxx:535
 TQLibrary.cxx:536
 TQLibrary.cxx:537
 TQLibrary.cxx:538
 TQLibrary.cxx:539
 TQLibrary.cxx:540
 TQLibrary.cxx:541
 TQLibrary.cxx:542
 TQLibrary.cxx:543
 TQLibrary.cxx:544
 TQLibrary.cxx:545
 TQLibrary.cxx:546
 TQLibrary.cxx:547
 TQLibrary.cxx:548
 TQLibrary.cxx:549
 TQLibrary.cxx:550
 TQLibrary.cxx:551
 TQLibrary.cxx:552
 TQLibrary.cxx:553
 TQLibrary.cxx:554
 TQLibrary.cxx:555
 TQLibrary.cxx:556
 TQLibrary.cxx:557
 TQLibrary.cxx:558
 TQLibrary.cxx:559
 TQLibrary.cxx:560
 TQLibrary.cxx:561
 TQLibrary.cxx:562
 TQLibrary.cxx:563
 TQLibrary.cxx:564
 TQLibrary.cxx:565
 TQLibrary.cxx:566
 TQLibrary.cxx:567
 TQLibrary.cxx:568
 TQLibrary.cxx:569
 TQLibrary.cxx:570
 TQLibrary.cxx:571
 TQLibrary.cxx:572
 TQLibrary.cxx:573
 TQLibrary.cxx:574
 TQLibrary.cxx:575
 TQLibrary.cxx:576
 TQLibrary.cxx:577
 TQLibrary.cxx:578
 TQLibrary.cxx:579
 TQLibrary.cxx:580
 TQLibrary.cxx:581
 TQLibrary.cxx:582
 TQLibrary.cxx:583
 TQLibrary.cxx:584
 TQLibrary.cxx:585
 TQLibrary.cxx:586
 TQLibrary.cxx:587
 TQLibrary.cxx:588
 TQLibrary.cxx:589
 TQLibrary.cxx:590
 TQLibrary.cxx:591
 TQLibrary.cxx:592
 TQLibrary.cxx:593
 TQLibrary.cxx:594
 TQLibrary.cxx:595
 TQLibrary.cxx:596
 TQLibrary.cxx:597
 TQLibrary.cxx:598
 TQLibrary.cxx:599
 TQLibrary.cxx:600
 TQLibrary.cxx:601
 TQLibrary.cxx:602
 TQLibrary.cxx:603
 TQLibrary.cxx:604
 TQLibrary.cxx:605
 TQLibrary.cxx:606
 TQLibrary.cxx:607
 TQLibrary.cxx:608
 TQLibrary.cxx:609
 TQLibrary.cxx:610
 TQLibrary.cxx:611
 TQLibrary.cxx:612
 TQLibrary.cxx:613
 TQLibrary.cxx:614
 TQLibrary.cxx:615
 TQLibrary.cxx:616
 TQLibrary.cxx:617
 TQLibrary.cxx:618
 TQLibrary.cxx:619
 TQLibrary.cxx:620
 TQLibrary.cxx:621
 TQLibrary.cxx:622
 TQLibrary.cxx:623
 TQLibrary.cxx:624
 TQLibrary.cxx:625
 TQLibrary.cxx:626
 TQLibrary.cxx:627
 TQLibrary.cxx:628
 TQLibrary.cxx:629
 TQLibrary.cxx:630
 TQLibrary.cxx:631
 TQLibrary.cxx:632
 TQLibrary.cxx:633
 TQLibrary.cxx:634
 TQLibrary.cxx:635
 TQLibrary.cxx:636
 TQLibrary.cxx:637
 TQLibrary.cxx:638
 TQLibrary.cxx:639
 TQLibrary.cxx:640
 TQLibrary.cxx:641
 TQLibrary.cxx:642
 TQLibrary.cxx:643
 TQLibrary.cxx:644
 TQLibrary.cxx:645
 TQLibrary.cxx:646
 TQLibrary.cxx:647
 TQLibrary.cxx:648
 TQLibrary.cxx:649
 TQLibrary.cxx:650
 TQLibrary.cxx:651
 TQLibrary.cxx:652
 TQLibrary.cxx:653
 TQLibrary.cxx:654
 TQLibrary.cxx:655
 TQLibrary.cxx:656
 TQLibrary.cxx:657
 TQLibrary.cxx:658
 TQLibrary.cxx:659
 TQLibrary.cxx:660
 TQLibrary.cxx:661
 TQLibrary.cxx:662
 TQLibrary.cxx:663
 TQLibrary.cxx:664
 TQLibrary.cxx:665
 TQLibrary.cxx:666
 TQLibrary.cxx:667
 TQLibrary.cxx:668
 TQLibrary.cxx:669
 TQLibrary.cxx:670
 TQLibrary.cxx:671
 TQLibrary.cxx:672
 TQLibrary.cxx:673
 TQLibrary.cxx:674
 TQLibrary.cxx:675
 TQLibrary.cxx:676
 TQLibrary.cxx:677
 TQLibrary.cxx:678
 TQLibrary.cxx:679
 TQLibrary.cxx:680
 TQLibrary.cxx:681
 TQLibrary.cxx:682
 TQLibrary.cxx:683
 TQLibrary.cxx:684
 TQLibrary.cxx:685
 TQLibrary.cxx:686
 TQLibrary.cxx:687
 TQLibrary.cxx:688
 TQLibrary.cxx:689
 TQLibrary.cxx:690
 TQLibrary.cxx:691
 TQLibrary.cxx:692
 TQLibrary.cxx:693
 TQLibrary.cxx:694
 TQLibrary.cxx:695
 TQLibrary.cxx:696
 TQLibrary.cxx:697
 TQLibrary.cxx:698
 TQLibrary.cxx:699
 TQLibrary.cxx:700
 TQLibrary.cxx:701
 TQLibrary.cxx:702
 TQLibrary.cxx:703
 TQLibrary.cxx:704
 TQLibrary.cxx:705
 TQLibrary.cxx:706
 TQLibrary.cxx:707
 TQLibrary.cxx:708
 TQLibrary.cxx:709
 TQLibrary.cxx:710
 TQLibrary.cxx:711
 TQLibrary.cxx:712
 TQLibrary.cxx:713
 TQLibrary.cxx:714
 TQLibrary.cxx:715
 TQLibrary.cxx:716
 TQLibrary.cxx:717
 TQLibrary.cxx:718
 TQLibrary.cxx:719
 TQLibrary.cxx:720
 TQLibrary.cxx:721
 TQLibrary.cxx:722
 TQLibrary.cxx:723
 TQLibrary.cxx:724
 TQLibrary.cxx:725
 TQLibrary.cxx:726
 TQLibrary.cxx:727
 TQLibrary.cxx:728
 TQLibrary.cxx:729
 TQLibrary.cxx:730
 TQLibrary.cxx:731
 TQLibrary.cxx:732
 TQLibrary.cxx:733
 TQLibrary.cxx:734
 TQLibrary.cxx:735
 TQLibrary.cxx:736
 TQLibrary.cxx:737
 TQLibrary.cxx:738
 TQLibrary.cxx:739
 TQLibrary.cxx:740
 TQLibrary.cxx:741
 TQLibrary.cxx:742
 TQLibrary.cxx:743
 TQLibrary.cxx:744
 TQLibrary.cxx:745
 TQLibrary.cxx:746
 TQLibrary.cxx:747
 TQLibrary.cxx:748
 TQLibrary.cxx:749
 TQLibrary.cxx:750
 TQLibrary.cxx:751
 TQLibrary.cxx:752
 TQLibrary.cxx:753
 TQLibrary.cxx:754
 TQLibrary.cxx:755
 TQLibrary.cxx:756
 TQLibrary.cxx:757
 TQLibrary.cxx:758
 TQLibrary.cxx:759
 TQLibrary.cxx:760
 TQLibrary.cxx:761
 TQLibrary.cxx:762
 TQLibrary.cxx:763
 TQLibrary.cxx:764
 TQLibrary.cxx:765
 TQLibrary.cxx:766
 TQLibrary.cxx:767
 TQLibrary.cxx:768
 TQLibrary.cxx:769
 TQLibrary.cxx:770
 TQLibrary.cxx:771
 TQLibrary.cxx:772
 TQLibrary.cxx:773
 TQLibrary.cxx:774
 TQLibrary.cxx:775
 TQLibrary.cxx:776
 TQLibrary.cxx:777
 TQLibrary.cxx:778
 TQLibrary.cxx:779
 TQLibrary.cxx:780
 TQLibrary.cxx:781
 TQLibrary.cxx:782
 TQLibrary.cxx:783
 TQLibrary.cxx:784
 TQLibrary.cxx:785
 TQLibrary.cxx:786
 TQLibrary.cxx:787
 TQLibrary.cxx:788
 TQLibrary.cxx:789
 TQLibrary.cxx:790
 TQLibrary.cxx:791
 TQLibrary.cxx:792
 TQLibrary.cxx:793
 TQLibrary.cxx:794
 TQLibrary.cxx:795
 TQLibrary.cxx:796
 TQLibrary.cxx:797
 TQLibrary.cxx:798
 TQLibrary.cxx:799
 TQLibrary.cxx:800
 TQLibrary.cxx:801
 TQLibrary.cxx:802
 TQLibrary.cxx:803
 TQLibrary.cxx:804
 TQLibrary.cxx:805
 TQLibrary.cxx:806
 TQLibrary.cxx:807
 TQLibrary.cxx:808
 TQLibrary.cxx:809
 TQLibrary.cxx:810
 TQLibrary.cxx:811
 TQLibrary.cxx:812
 TQLibrary.cxx:813
 TQLibrary.cxx:814
 TQLibrary.cxx:815
 TQLibrary.cxx:816
 TQLibrary.cxx:817
 TQLibrary.cxx:818
 TQLibrary.cxx:819
 TQLibrary.cxx:820
 TQLibrary.cxx:821
 TQLibrary.cxx:822
 TQLibrary.cxx:823
 TQLibrary.cxx:824
 TQLibrary.cxx:825
 TQLibrary.cxx:826
 TQLibrary.cxx:827
 TQLibrary.cxx:828
 TQLibrary.cxx:829
 TQLibrary.cxx:830
 TQLibrary.cxx:831
 TQLibrary.cxx:832
 TQLibrary.cxx:833
 TQLibrary.cxx:834
 TQLibrary.cxx:835
 TQLibrary.cxx:836
 TQLibrary.cxx:837
 TQLibrary.cxx:838
 TQLibrary.cxx:839
 TQLibrary.cxx:840
 TQLibrary.cxx:841
 TQLibrary.cxx:842
 TQLibrary.cxx:843
 TQLibrary.cxx:844
 TQLibrary.cxx:845
 TQLibrary.cxx:846
 TQLibrary.cxx:847
 TQLibrary.cxx:848
 TQLibrary.cxx:849
 TQLibrary.cxx:850
 TQLibrary.cxx:851
 TQLibrary.cxx:852
 TQLibrary.cxx:853
 TQLibrary.cxx:854
 TQLibrary.cxx:855
 TQLibrary.cxx:856
 TQLibrary.cxx:857
 TQLibrary.cxx:858
 TQLibrary.cxx:859
 TQLibrary.cxx:860
 TQLibrary.cxx:861
 TQLibrary.cxx:862
 TQLibrary.cxx:863
 TQLibrary.cxx:864
 TQLibrary.cxx:865
 TQLibrary.cxx:866
 TQLibrary.cxx:867
 TQLibrary.cxx:868
 TQLibrary.cxx:869
 TQLibrary.cxx:870
 TQLibrary.cxx:871
 TQLibrary.cxx:872
 TQLibrary.cxx:873
 TQLibrary.cxx:874
 TQLibrary.cxx:875
 TQLibrary.cxx:876
 TQLibrary.cxx:877
 TQLibrary.cxx:878
 TQLibrary.cxx:879
 TQLibrary.cxx:880
 TQLibrary.cxx:881
 TQLibrary.cxx:882
 TQLibrary.cxx:883
 TQLibrary.cxx:884
 TQLibrary.cxx:885
 TQLibrary.cxx:886
 TQLibrary.cxx:887
 TQLibrary.cxx:888
 TQLibrary.cxx:889
 TQLibrary.cxx:890
 TQLibrary.cxx:891
 TQLibrary.cxx:892
 TQLibrary.cxx:893
 TQLibrary.cxx:894
 TQLibrary.cxx:895
 TQLibrary.cxx:896
 TQLibrary.cxx:897
 TQLibrary.cxx:898
 TQLibrary.cxx:899
 TQLibrary.cxx:900
 TQLibrary.cxx:901
 TQLibrary.cxx:902
 TQLibrary.cxx:903
 TQLibrary.cxx:904
 TQLibrary.cxx:905
 TQLibrary.cxx:906