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 <qprocess.h>
#include <qwaitcondition.h>
#include <qapplication.h>
#include <qstringlist.h>
#include "fileexportertoolchain.h"
namespace BibTeX
{
FileExporterToolchain::FileExporterToolchain()
: FileExporter(), m_errorLog( NULL )
{
m_waitCond = new QWaitCondition();
workingDir = createTempDir();
}
FileExporterToolchain::~FileExporterToolchain()
{
delete m_waitCond;
deleteTempDir( workingDir );
}
bool FileExporterToolchain::runProcesses( const QStringList &progs, QStringList *errorLog )
{
bool result = TRUE;
int i = 0;
emit progress( 0, progs.size() );
for ( QStringList::ConstIterator it = progs.begin(); result && it != progs.end(); it++ )
{
qApp->processEvents();
QStringList args = QStringList::split( ' ', *it );
result &= runProcess( args, errorLog );
emit progress( i++, progs.size() );
}
qApp->processEvents();
return result;
}
bool FileExporterToolchain::runProcess( const QStringList &args, QStringList *errorLog )
{
bool result = FALSE;
QApplication::setOverrideCursor( Qt::waitCursor );
m_process = new QProcess( 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;
qApp->processEvents();
while ( m_process->isRunning() )
{
m_waitCond->wait( 250 );
qApp->processEvents();
counter++;
if ( counter > 400 )
m_process->tryTerminate();
}
result = m_process->normalExit() && counter < 400;
if ( !result )
errorLog->append( QString( "Process '%1' failed." ).arg( args.join( " " ) ) );
}
else
errorLog->append( QString( "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;
QApplication::restoreOverrideCursor();
return result;
}
bool FileExporterToolchain::writeFileToIODevice( const QString &filename, QIODevice *device )
{
QFile file( filename );
if ( file.open( IO_ReadOnly ) )
{
bool result = TRUE;
Q_ULONG buffersize = 0x10000;
Q_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;
}
QString FileExporterToolchain::createTempDir()
{
QString result = QString::null;
QFile *devrandom = new QFile( "/dev/random" );
if ( devrandom->open( IO_ReadOnly ) )
{
Q_UINT32 randomNumber;
if ( devrandom->readBlock(( char* ) & randomNumber, sizeof( randomNumber ) ) > 0 )
{
randomNumber |= 0x10000000;
result = QString( "/tmp/bibtex-%1" ).arg( randomNumber, sizeof( randomNumber ) * 2, 16 );
if ( !QDir().mkdir( result ) )
result = QString::null;
}
devrandom->close();
}
delete devrandom;
return result;
}
void FileExporterToolchain::deleteTempDir( const QString& directory )
{
QDir dir = QDir( directory );
QStringList subDirs = dir.entryList( QDir::Dirs );
for ( QStringList::Iterator it = subDirs.begin(); it != subDirs.end(); it++ )
{
if (( QString::compare( *it, "." ) != 0 ) && ( QString::compare( *it, ".." ) != 0 ) )
deleteTempDir( *it );
}
QStringList allEntries = dir.entryList( QDir::All );
for ( QStringList::Iterator it = allEntries.begin(); it != allEntries.end(); it++ )
dir.remove( *it );
QDir().rmdir( directory );
}
void FileExporterToolchain::slotProcessExited()
{
m_waitCond->wakeAll();
}
void FileExporterToolchain::cancel()
{
if ( m_process != NULL )
{
qDebug( "Canceling process" );
m_process->tryTerminate();
m_process->kill();
m_waitCond->wakeAll();
}
}
void FileExporterToolchain::slotReadProcessOutput()
{
if ( m_process )
{
while ( m_process->canReadLineStdout() )
{
QString line = m_process->readLineStdout();
if ( m_errorLog != NULL )
m_errorLog->append( line );
}
while ( m_process->canReadLineStderr() )
{
QString line = m_process->readLineStderr();
if ( m_errorLog != NULL )
m_errorLog->append( line );
}
}
}
bool FileExporterToolchain::kpsewhich( const QString& filename )
{
bool result = FALSE;
int counter = 0;
QWaitCondition waitCond;
QProcess kpsewhich;
kpsewhich.addArgument( "kpsewhich" );
kpsewhich.addArgument( filename );
if ( kpsewhich.start() )
{
qApp->processEvents();
while ( kpsewhich.isRunning() )
{
waitCond.wait( 250 );
qApp->processEvents();
counter++;
if ( counter > 50 )
kpsewhich.tryTerminate();
}
result = kpsewhich.exitStatus() == 0 && counter < 50;
}
return result;
}
}
#include "fileexportertoolchain.moc"