You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kbibtex/src/fileexportertoolchain.cpp

233 lines
7.8 KiB

/***************************************************************************
* Copyright (C) 2004-2009 by Thomas Fischer *
* fischer@unix-ag.uni-kl.de *
* *
* 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. *
***************************************************************************/
#include <ntqprocess.h>
#include <ntqwaitcondition.h>
#include <ntqapplication.h>
#include <ntqstringlist.h>
#include "fileexportertoolchain.h"
namespace BibTeX
{
FileExporterToolchain::FileExporterToolchain()
: FileExporter(), m_errorLog( NULL )
{
m_waitCond = new TQWaitCondition();
workingDir = createTempDir();
}
FileExporterToolchain::~FileExporterToolchain()
{
delete m_waitCond;
deleteTempDir( workingDir );
}
bool FileExporterToolchain::runProcesses( const TQStringList &progs, TQStringList *errorLog )
{
bool result = TRUE;
int i = 0;
emit progress( 0, progs.size() );
for ( TQStringList::ConstIterator it = progs.begin(); result && it != progs.end(); it++ )
{
tqApp->processEvents();
TQStringList args = TQStringList::split( ' ', *it );
result &= runProcess( args, errorLog );
emit progress( i++, progs.size() );
}
tqApp->processEvents();
return result;
}
bool FileExporterToolchain::runProcess( const TQStringList &args, TQStringList *errorLog )
{
bool result = FALSE;
TQApplication::setOverrideCursor( TQt::waitCursor );
m_process = new TQProcess( args );
m_process->setWorkingDirectory( workingDir );
connect( m_process, SIGNAL( processExited() ), this, SLOT( slotProcessExited() ) );
connect( m_process, SIGNAL( readyReadStdout() ), this, SLOT( slotReadProcessOutput() ) );
connect( m_process, SIGNAL( readyReadStderr() ), this, SLOT( slotReadProcessOutput() ) );
if ( m_process->start() )
{
m_errorLog = errorLog;
int counter = 0;
tqApp->processEvents();
while ( m_process->isRunning() )
{
m_waitCond->wait( 250 );
tqApp->processEvents();
counter++;
if ( counter > 400 )
m_process->tryTerminate();
}
result = m_process->normalExit() && counter < 400;
if ( !result )
errorLog->append( TQString( "Process '%1' failed." ).arg( args.join( " " ) ) );
}
else
errorLog->append( TQString( "Process '%1' was not started." ).arg( args.join( " " ) ) );
disconnect( m_process, SIGNAL( readyReadStdout() ), this, SLOT( slotReadProcessOutput() ) );
disconnect( m_process, SIGNAL( readyReadStderr() ), this, SLOT( slotReadProcessOutput() ) );
disconnect( m_process, SIGNAL( processExited() ), this, SLOT( slotProcessExited() ) );
delete( m_process );
m_process = NULL;
TQApplication::restoreOverrideCursor();
return result;
}
bool FileExporterToolchain::writeFileToIODevice( const TQString &filename, TQIODevice *device )
{
TQFile file( filename );
if ( file.open( IO_ReadOnly ) )
{
bool result = TRUE;
TQ_ULONG buffersize = 0x10000;
TQ_LONG amount = 0;
char* buffer = new char[ buffersize ];
do
{
result = (( amount = file.readBlock( buffer, buffersize ) ) > -1 ) && ( device->writeBlock( buffer, amount ) > -1 );
}
while ( result && amount > 0 );
file.close();
delete[] buffer;
return result;
}
else
return FALSE;
}
TQString FileExporterToolchain::createTempDir()
{
TQString result = TQString::null;
TQFile *devrandom = new TQFile( "/dev/random" );
if ( devrandom->open( IO_ReadOnly ) )
{
TQ_UINT32 randomNumber;
if ( devrandom->readBlock(( char* ) & randomNumber, sizeof( randomNumber ) ) > 0 )
{
randomNumber |= 0x10000000;
result = TQString( "/tmp/bibtex-%1" ).arg( randomNumber, sizeof( randomNumber ) * 2, 16 );
if ( !TQDir().mkdir( result ) )
result = TQString::null;
}
devrandom->close();
}
delete devrandom;
return result;
}
void FileExporterToolchain::deleteTempDir( const TQString& directory )
{
TQDir dir = TQDir( directory );
TQStringList subDirs = dir.entryList( TQDir::Dirs );
for ( TQStringList::Iterator it = subDirs.begin(); it != subDirs.end(); it++ )
{
if (( TQString::compare( *it, "." ) != 0 ) && ( TQString::compare( *it, ".." ) != 0 ) )
deleteTempDir( *it );
}
TQStringList allEntries = dir.entryList( TQDir::All );
for ( TQStringList::Iterator it = allEntries.begin(); it != allEntries.end(); it++ )
dir.remove( *it );
TQDir().rmdir( directory );
}
void FileExporterToolchain::slotProcessExited()
{
m_waitCond->wakeAll();
}
void FileExporterToolchain::cancel()
{
if ( m_process != NULL )
{
tqDebug( "Canceling process" );
m_process->tryTerminate();
m_process->kill();
m_waitCond->wakeAll();
}
}
void FileExporterToolchain::slotReadProcessOutput()
{
if ( m_process )
{
while ( m_process->canReadLineStdout() )
{
TQString line = m_process->readLineStdout();
if ( m_errorLog != NULL )
m_errorLog->append( line );
}
while ( m_process->canReadLineStderr() )
{
TQString line = m_process->readLineStderr();
if ( m_errorLog != NULL )
m_errorLog->append( line );
}
}
}
bool FileExporterToolchain::kpsewhich( const TQString& filename )
{
bool result = FALSE;
int counter = 0;
TQWaitCondition waitCond;
TQProcess kpsewhich;
kpsewhich.addArgument( "kpsewhich" );
kpsewhich.addArgument( filename );
if ( kpsewhich.start() )
{
tqApp->processEvents();
while ( kpsewhich.isRunning() )
{
waitCond.wait( 250 );
tqApp->processEvents();
counter++;
if ( counter > 50 )
kpsewhich.tryTerminate();
}
result = kpsewhich.exitStatus() == 0 && counter < 50;
}
return result;
}
}
#include "fileexportertoolchain.moc"