dlvhex  2.5.0
src/DLVProcess.cpp
Go to the documentation of this file.
00001 /* dlvhex -- Answer-Set Programming with external interfaces.
00002  * Copyright (C) 2005-2007 Roman Schindlauer
00003  * Copyright (C) 2006-2015 Thomas Krennwallner
00004  * Copyright (C) 2009-2016 Peter Schüller
00005  * Copyright (C) 2011-2016 Christoph Redl
00006  * Copyright (C) 2015-2016 Tobias Kaminski
00007  * Copyright (C) 2015-2016 Antonius Weinzierl
00008  *
00009  * This file is part of dlvhex.
00010  *
00011  * dlvhex is free software; you can redistribute it and/or modify it
00012  * under the terms of the GNU Lesser General Public License as
00013  * published by the Free Software Foundation; either version 2.1 of
00014  * the License, or (at your option) any later version.
00015  *
00016  * dlvhex is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with dlvhex; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00037 #ifdef HAVE_CONFIG_H
00038 #include "config.h"
00039 #endif                           // HAVE_CONFIG_H
00040 
00041 #include "dlvhex2/DLVProcess.h"
00042 #include "dlvhex2/Logger.h"
00043 
00044 #include <iostream>
00045 #include <boost/iostreams/tee.hpp>
00046 #include <boost/iostreams/filtering_stream.hpp>
00047 
00048 DLVHEX_NAMESPACE_BEGIN
00049 
00050 DLVProcess::DLVProcess()
00051 : proc(), ipipe(0), opipe(0), executable(), argv()
00052 { }
00053 
00054 DLVProcess::~DLVProcess()
00055 {
00056     proc.close();
00057     delete opipe;
00058     delete ipipe;
00059 }
00060 
00061 
00062 void
00063 DLVProcess::addOption(const std::string& option)
00064 {
00065     argv.push_back(option);
00066 }
00067 
00068 
00069 void
00070 DLVProcess::setPath(const std::string& path)
00071 {
00072     executable = path;
00073 }
00074 
00075 
00076 std::string
00077 DLVProcess::path() const
00078 {
00079     return executable;
00080 }
00081 
00082 
00083 std::vector<std::string>
00084 DLVProcess::commandline() const
00085 {
00086     std::vector<std::string> tmp;
00087 
00088     assert(!path().empty());
00089     tmp.push_back(path());
00090     tmp.insert(tmp.end(), argv.begin(), argv.end());
00091 
00092     return tmp;
00093 }
00094 
00095 
00096 void
00097 DLVProcess::setupStreams()
00098 {
00099     if (ipipe == 0 && opipe == 0) {
00100         #ifndef NDEBUG
00101         if( Logger::Instance().shallPrint(Logger::DBG) ) {
00102             // setup iostreams to copy to log stream
00103             DBGLOG(DBG,"Setting up DLVProcess opipe to be verbose");
00104 
00105             boost::iostreams::filtering_ostream* tmpopipe = new boost::iostreams::filtering_ostream;
00106 
00107             tmpopipe->push(boost::iostreams::tee_filter<std::streambuf>(proc));
00108             tmpopipe->push(Logger::Instance().stream());
00109 
00110             opipe = tmpopipe;
00111         }
00112         else
00113         #endif
00114         {
00115             opipe = new std::iostream(&proc);
00116         }
00117 
00118         ipipe = new std::iostream(&proc);
00119 
00120         // let ProcessBuf throw std::ios_base::failure
00121         opipe->exceptions(std::ios_base::badbit);
00122         ipipe->exceptions(std::ios_base::badbit);
00123     }
00124 }
00125 
00126 
00127 void
00128 DLVProcess::spawn()
00129 {
00130     setupStreams();
00131     proc.open(commandline());
00132 }
00133 
00134 
00135 void
00136 DLVProcess::spawn(const std::vector<std::string>& opt)
00137 {
00138     setupStreams();
00139     std::vector<std::string> tmp(opt);
00140     assert(!path().empty());
00141     tmp.insert(tmp.begin(), path());
00142     proc.open(tmp);
00143 }
00144 
00145 
00146 void
00147 DLVProcess::endoffile()
00148 {
00149     proc.endoffile();
00150 }
00151 
00152 
00153 int
00154 DLVProcess::close(bool kill)
00155 {
00156     assert(ipipe != 0 && opipe != 0);
00157 
00158     // first reset the state of the iostreams in order to re-use them
00159     opipe->clear();
00160     ipipe->clear();
00161     // exit code of process
00162     return proc.close(kill);
00163 }
00164 
00165 
00166 std::ostream&
00167 DLVProcess::getOutput()
00168 {
00169     assert(opipe != 0);
00170     return *opipe;
00171 }
00172 
00173 
00174 std::istream&
00175 DLVProcess::getInput()
00176 {
00177     assert(ipipe != 0);
00178     return *ipipe;
00179 }
00180 
00181 
00182 DLVHEX_NAMESPACE_END
00183 
00184 
00185 // vim:expandtab:ts=4:sw=4:
00186 // mode: C++
00187 // End: